1. 소개
이 섹션은 규범적이지 않습니다.
그래픽 처리 장치(GPU)는 개인 컴퓨팅에서 풍부한 렌더링 및 연산 응용 프로그램을 가능하게 하는 데 필수적이었습니다. WebGPU는 웹에서 GPU 하드웨어의 기능을 노출하는 API입니다. 이 API는 (2014년 이후) 네이티브 GPU API에 효율적으로 매핑되도록 처음부터 설계되었습니다. WebGPU는 WebGL과 관련이 없으며 OpenGL ES를 명시적으로 대상으로 하지 않습니다.
WebGPU는 물리적 GPU 하드웨어를 GPUAdapter
로
봅니다.
어댑터와의 연결은 GPUDevice
를 통해
제공되며,
이는 리소스를 관리하고 디바이스의 GPUQueue
에서 명령을
실행합니다.
GPUDevice
는 자체
메모리를 가지고 있을 수 있으며, 처리 장치에 고속으로 접근할 수 있습니다.
GPUBuffer
와
GPUTexture
는
GPU 메모리에 의해 지원되는 물리적
리소스입니다.
GPUCommandBuffer
와
GPURenderBundle
는
사용자 기록 명령을 담는 컨테이너입니다.
GPUShaderModule
에는
셰이더 코드가 들어 있습니다. 그 외의 리소스들(예: GPUSampler
또는
GPUBindGroup
)은
GPU에서 물리적 리소스가 사용되는
방식을 구성합니다.
GPU는 GPUCommandBuffer
에
인코딩된 명령을 실행하며,
데이터를 파이프라인을 통해 처리합니다. 파이프라인은 고정 기능 및
프로그래머블 단계가 혼합된 구조입니다. 프로그래머블 단계는
셰이더를 실행하는데, 셰이더는 GPU 하드웨어에서
실행되도록 설계된 특별한 프로그램입니다.
파이프라인의 대부분 상태는
GPURenderPipeline
또는
GPUComputePipeline
객체로 정의됩니다. 이 파이프라인 객체에 포함되지 않은 상태는
beginRenderPass()
나
setBlendConstant()
와
같은 명령 인코딩 시에 설정됩니다.
2. 악의적 사용 고려사항
이 섹션은 규범적이지 않습니다. 이 섹션은 이 API를 웹에 노출할 때 발생할 수 있는 위험을 설명합니다.
2.1. 보안 고려사항
WebGPU의 보안 요구 사항은 웹의 기존 보안 요구와 동일하며, 협상 대상이 아닙니다. 일반적인 접근 방식은 모든 명령을 GPU에 전달하기 전에 엄격하게 검증하여 페이지가 자신의 데이터만 다룰 수 있도록 하는 것입니다.
2.1.1. CPU 기반 정의되지 않은 동작
WebGPU 구현은 사용자가 발행한 작업을 대상 플랫폼에 특화된 API 명령으로 변환합니다. 네이티브 API는 명령의 올바른 사용법을 지정하며 (예: vkCreateDescriptorSetLayout) 유효한 사용 규칙을 따르지 않으면 어떤 결과도 보장하지 않습니다. 이를 "정의되지 않은 동작"이라 하며, 공격자가 이를 악용하여 자신이 소유하지 않은 메모리에 접근하거나 드라이버가 임의의 코드를 실행하도록 할 수 있습니다.
안전하지 않은 사용을 막기 위해, 허용되는 WebGPU 동작의 범위는 모든 입력에 대해 정의됩니다.
구현체는 사용자의 모든 입력을 검증하고, 유효한 작업만 드라이버로 전달해야 합니다. 이 문서에서는 모든 오류 조건과 처리 의미론을 명시합니다.
예를 들어, copyBufferToBuffer()의 "source"와 "destination"에 겹치는
범위로 동일 버퍼를 지정하면
GPUCommandEncoder
가
오류를 발생시키고 다른 작업은 수행되지 않습니다.
오류 처리에 대한 자세한 내용은 § 22 오류 및 디버깅을 참고하세요.
2.1.2. GPU 기반 정의되지 않은 동작
WebGPU 셰이더는 GPU 하드웨어 내의 연산 장치에서 실행됩니다. 네이티브
API에서는
일부 셰이더 명령이 GPU에서 정의되지 않은 동작을 일으킬 수 있습니다.
이를 해결하기 위해, 셰이더 명령 집합과 그 동작은 WebGPU에서 엄격하게 정의됩니다. 셰이더가 createShaderModule()
에
제공될 때,
WebGPU 구현체는 번역(플랫폼별 셰이더로)이나 변환 패스 전에 셰이더를 검증해야 합니다.
2.1.3. 초기화되지 않은 데이터
일반적으로, 새 메모리를 할당하면 시스템에서 실행 중인 다른 응용 프로그램의 남은 데이터가 노출될 수 있습니다. 이를 해결하기 위해, WebGPU는 모든 리소스를 개념적으로 0으로 초기화합니다. 하지만 실제로는 개발자가 내용을 직접 초기화하는 경우 이 단계를 생략할 수 있습니다. 여기에는 셰이더 내 변수 및 공유 워크그룹 메모리도 포함됩니다.
워크그룹 메모리 초기화 메커니즘은 플랫폼마다 다를 수 있습니다. 네이티브 API에 이를 초기화하는 기능이 없다면, WebGPU 구현체는 연산 셰이더를 변환하여 모든 호출에서 먼저 초기화, 동기화 후 개발자 코드를 실행하게 합니다.
GPULoadOp
"load"
대신 "clear"
를
사용하는 등).
결과적으로, 모든 구현체는 비록 실제 페널티가 없더라도 이러한 잠재적 성능 저하에 대해 개발자 콘솔 경고를 권장합니다.
2.1.4. 셰이더에서의 범위 초과 접근
셰이더는 물리적 리소스에 직접 접근하거나
("uniform"
GPUBufferBinding
등),
또는 텍스처 유닛을 통해 접근할 수 있습니다.
텍스처 유닛은 텍스처 좌표 변환을 처리하는 고정 기능 하드웨어 블록입니다.
WebGPU API의 검증은 셰이더에 전달되는 모든 입력 값이 제공되고 올바른 사용법과 타입임을 보장할 수 있습니다.
하지만 텍스처 유닛이 관여하지 않는 한, 데이터가 범위 내에서 접근되는 것은 API가 보장할 수 없습니다.
셰이더가 애플리케이션이 소유하지 않은 GPU 메모리에 접근하는 것을 막기 위해, WebGPU 구현체는 드라이버에서 "견고한 버퍼 접근(robust buffer access)" 모드를 활성화하여 접근이 버퍼의 경계 내로 제한되도록 할 수 있습니다.
또는, 구현체가 셰이더 코드를 변환하여 수동 경계 검사를 삽입할 수도 있습니다.
이 방식에서는 범위 초과 검사가 배열 인덱싱에만 적용됩니다. 호스트 측의 minBindingSize
검증 덕분에
셰이더 구조체의 단순 필드 접근에는 필요하지 않습니다.
셰이더가 물리적 리소스 경계 밖의 데이터를 읽으려 할 경우, 구현체는 다음 중 하나를 허용합니다:
-
리소스 경계 내의 다른 위치의 값을 반환
-
"(0, 0, 0, X)" 형식의 값 벡터 반환(X는 임의값)
-
드로우 또는 디스패치 호출을 부분적으로 폐기
셰이더가 물리적 리소스 경계 밖에 데이터를 쓰려 할 경우, 구현체는 다음 중 하나를 허용합니다:
-
리소스 경계 내의 다른 위치에 값을 씀
-
쓰기 작업 폐기
-
드로우 또는 디스패치 호출을 부분적으로 폐기
2.1.5. 잘못된 데이터
CPU에서 GPU로 부동소수점 데이터를 업로드하거나 GPU에서 생성할 때, 값이 무한대나 NaN(Not-a-Number)와 같은 유효하지 않은 숫자 이진 표현이 될 수 있습니다. 이 경우 GPU의 동작은 IEEE-754 표준의 구현 정확도에 달려 있습니다. WebGPU는 잘못된 부동소수점을 도입해도 산술 계산 결과에만 영향을 주며, 다른 부작용은 없음을 보장합니다.
2.1.6. 드라이버 버그
GPU 드라이버도 다른 소프트웨어처럼 버그가 있을 수 있습니다. 버그가 발생할 경우, 공격자가 드라이버의 잘못된 동작을 악용하여 권한 없는 데이터에 접근할 수 있습니다. 위험을 줄이기 위해 WebGPU 워킹 그룹은 GPU 벤더와 협력하여 WebGPU 적합성 테스트 스위트(CTS)를 드라이버 테스트 프로세스에 통합할 예정입니다(WebGL처럼). WebGPU 구현체는 발견된 일부 버그에 대해 우회 방법을 갖추고, 우회할 수 없는 알려진 버그가 있는 드라이버에서는 WebGPU를 비활성화하는 것이 기대됩니다.
2.1.7. 타이밍 공격
2.1.7.1. 콘텐츠-타임라인 타이밍
WebGPU는 JavaScript에 콘텐츠
타임라인과 같은 새로운 상태를 노출하지 않습니다.
이러한 상태는 에이전트 간에
에이전트 클러스터 내에서 공유됩니다.
콘텐츠 타임라인 상태([[mapping]]
등)는
명시적 콘텐츠 타임라인 작업(일반
JavaScript처럼)에서만 변경됩니다.
2.1.7.2. 디바이스/큐-타임라인 타이밍
쓰기 가능한 저장 버퍼 및 기타 교차 호출 통신은 큐 타임라인에서 고정밀 타이머를 구성하는 데 사용될 수 있습니다.
선택적 "timestamp-query"
기능 역시 GPU 작업의 고정밀 타이밍을 제공합니다.
보안 및 프라이버시 문제를 완화하기 위해, 타이밍 쿼리 값은 더 낮은 정밀도로 맞춰집니다: current queue timestamp 참고. 특히:
-
디바이스 타임라인은 대개 여러 오리진이 공유하는 프로세스에서 실행되므로, COOP/COEP로 제공되는 교차 오리진 격리도 디바이스/큐-타임라인 타이머를 격리하지 못합니다.
-
큐 타임라인 작업은 디바이스 타임라인에서 발행되며, GPU 하드웨어에서 실행될 수 있습니다. 이 하드웨어는 CPU 프로세스(예: Meltdown 완화책)에서 기대하는 격리를 보장하지 않을 수 있습니다.
-
GPU 하드웨어는 일반적으로 Spectre 스타일 공격에 취약하지 않지만(하지만), WebGPU가 소프트웨어로 구현될 경우, 해당 소프트웨어가 공유 프로세스에서 실행될 수 있어 격리 기반 완화가 불가능할 수 있습니다.
2.1.8. Row hammer 공격
Row hammer는 DRAM 셀 상태 누출을 악용하는 공격의 한 종류입니다. GPU에서도 사용될 수 있습니다. WebGPU는 이에 대한 특정 대응책을 갖추고 있지 않으며, 메모리 리프레시 주기 단축 등 플랫폼 수준의 솔루션에 의존합니다.
2.1.9. 서비스 거부
WebGPU 응용 프로그램은 GPU 메모리 및 연산 장치에 접근할 수 있습니다. WebGPU 구현체는 다른 응용 프로그램의 응답성을 보장하기 위해 애플리케이션이 사용할 수 있는 GPU 메모리를 제한할 수 있습니다. GPU 처리 시간에 대해서는, WebGPU 구현체가 "감시견(watchdog)" 타이머를 설정하여 애플리케이션이 GPU를 몇 초 이상 응답하지 않게 하는 것을 방지할 수 있습니다. 이러한 조치는 WebGL에서 사용되는 것과 유사합니다.
2.1.10. 작업 부하 식별
WebGPU는 동일한 머신에서 실행되는 여러 프로그램(웹 페이지 포함)이 공유하는 제한된 글로벌 리소스에 접근합니다. 애플리케이션은 이러한 공유 리소스 사용 패턴을 기반으로 다른 열린 웹 페이지가 수행하는 작업 부하를 간접적으로 탐지하려고 시도할 수 있습니다. 이러한 문제는 Javascript의 시스템 메모리와 CPU 실행 처리량과 유사합니다. WebGPU는 이와 관련하여 추가적인 대응책을 제공하지 않습니다.
2.1.11. 메모리 자원
WebGPU는 VRAM과 같은 머신 전역 메모리 힙에서 실패할 수 있는 할당을 노출합니다. 이를 통해 할당을 시도하고 실패를 감지함으로써(힙 유형별로) 시스템의 남은 사용 가능 메모리 크기를 추론할 수 있습니다.
GPU는 내부적으로 하나 또는 여러 개(대개 두 개)의 메모리 힙을 모든 실행 중인 응용 프로그램이 공유합니다. 힙이 소진되면 WebGPU는 리소스 생성에 실패합니다. 이는 관찰 가능하므로, 악의적인 애플리케이션이 다른 애플리케이션이 어떤 힙을 사용하고 얼마를 할당하는지 추측할 수 있습니다.
2.1.12. 연산 자원
한 사이트가 다른 사이트와 동시에 WebGPU를 사용할 경우, 작업 처리 시간이 증가하는 현상을 관찰할 수 있습니다. 예를 들어, 한 사이트가 연산 작업을 지속적으로 제출하고 큐에서 작업 완료를 추적하면, GPU를 다른 곳에서 사용하기 시작했음을 감지할 수 있습니다.
GPU에는 산술 장치, 텍스처 샘플링 장치, 원자적 장치 등 독립적으로 테스트할 수 있는 여러 부분이 있습니다. 악의적인 애플리케이션은 이들 장치가 과부하되는 시점을 감지하여 다른 애플리케이션의 작업 부하를 추론할 수 있습니다. 이는 JavaScript의 CPU 실행 현실과 유사합니다.
2.1.13. 기능 오용
악의적인 사이트는 WebGPU가 제공하는 기능을 남용하여 사용자에게 도움이 되지 않는 계산(예: 숨겨진 암호화폐 채굴, 비밀번호 크래킹, 레인보우 테이블 연산 등)을 수행할 수 있습니다.
브라우저가 유효한 작업과 악용 작업을 구별할 수 없으므로, 이러한 형태의 API 오용을 방지할 방법은 없습니다. 이는 JavaScript, WebAssembly, WebGL 등 웹의 모든 범용 연산 기능에 공통적인 문제입니다. WebGPU는 일부 작업을 구현하기 쉬워지고, WebGL보다 약간 더 효율적으로 수행할 수 있을 뿐입니다.
이러한 오용을 완화하기 위해, 브라우저는 백그라운드 탭의 작업을 제한하거나, 탭이 많은 리소스를 사용하고 있음을 경고하거나, WebGPU 사용을 허용할 수 있는 컨텍스트를 제한할 수 있습니다.
사용자 에이전트는 잠재적으로 악의적인 사용으로 인한 높은 전력 사용에 대해 휴리스틱 기반 경고를 사용자에게 알릴 수 있습니다. 만약 사용자 에이전트가 이러한 경고를 구현한다면, WebGPU 사용도 JavaScript, WebAssembly, WebGL 등과 함께 휴리스틱에 포함해야 합니다.
2.2. 프라이버시 고려사항
WebGPU의 프라이버시 고려사항은 WebGL과 유사합니다. GPU API는 복잡하며, 개발자가 해당 기능을 효과적으로 활용할 수 있도록 기기 기능의 다양한 측면을 반드시 노출해야 합니다. 일반적인 완화 방법은 잠재적으로 식별 가능한 정보를 정규화하거나 구획화하고, 가능한 한 균일한 동작을 강제하는 것입니다.
사용자 에이전트는 32개를 초과하는 구분 가능한 구성 또는 버킷을 공개해서는 안 됩니다.
2.2.1. 기기별 기능 및 한계
WebGPU는 기반이 되는 GPU 아키텍처와 기기 구조에 대한 많은 세부사항을 노출할 수 있습니다. 여기에는 사용 가능한 물리적 어댑터, GPU 및 CPU 리소스에 대한 다양한 한계(예: 최대 텍스처 크기), 그리고 사용 가능한 하드웨어별 선택적 기능 등이 포함됩니다.
사용자 에이전트는 실제 하드웨어 한계를 반드시 노출할 필요가 없으며, 기기별 정보를 얼마나 노출할지 완전히 제어할 수 있습니다. 지문 채취를 줄이는 한 가지 전략은 모든 대상 플랫폼을 소수의 구획으로 묶는 것입니다. 일반적으로 하드웨어 한계 노출의 프라이버시 영향은 WebGL과 일치합니다.
기본 한계는 대부분의 애플리케이션이 더 높은 한계를 요청하지 않아도 작동할 수 있도록 의도적으로 충분히 높게 설정되어 있습니다. API 사용은 요청된 한계에 따라 검증되기 때문에, 실제 하드웨어 기능이 실수로 사용자에게 노출되는 일은 없습니다.
2.2.2. 기기별 아티팩트
WebGL에서와 마찬가지로 기기별 래스터화/정밀도 아티팩트와 성능 차이를 관찰할 수 있습니다. 이는 래스터화 커버리지 및 패턴, 셰이더 단계 간 보간 정밀도, 연산 장치 스케줄링 등 실행의 여러 측면에 해당됩니다.
일반적으로, 래스터화 및 정밀도 지문은 각 벤더의 대부분 또는 모든 기기에서 동일합니다. 성능 차이는 상대적으로 판별이 어렵지만 신호가 약합니다(JS 실행 성능과 유사).
프라이버시가 중요한 애플리케이션 및 사용자 에이전트는 이러한 아티팩트를 제거하기 위해 소프트웨어 구현을 활용해야 합니다.
2.2.3. 기기별 성능
사용자를 구분하는 또 다른 요인은 GPU에서 특정 작업의 성능을 측정하는 것입니다. 낮은 정밀도의 타이밍만으로도, 반복적으로 작업을 실행하면 사용자의 기기가 특정 작업에 빠른지 확인할 수 있습니다. 이는 WebGL과 Javascript 모두에서 흔히 볼 수 있는 벡터이지만, 신호가 약하고 실제로 정규화하기 어렵습니다.
WebGPU 연산 파이프라인은 고정 기능 하드웨어에 의해 방해받지 않는 GPU 접근을 제공합니다. 이는 고유한 기기 지문 채취 위험을 추가로 유발할 수 있습니다. 사용자 에이전트는 논리적 GPU 호출을 실제 연산 장치와 분리하여 이러한 위험을 줄일 수 있습니다.
2.2.4. User Agent 상태
이 명세는 오리진에 대한 추가적인 사용자 에이전트 상태를 정의하지 않습니다.
하지만 사용자 에이전트는 GPUShaderModule
,
GPURenderPipeline
및 GPUComputePipeline
과
같이 비용이 많이 드는 컴파일 결과에 대한 캐시를 보유할 것으로 예상됩니다.
이러한 캐시는 WebGPU 애플리케이션을 처음 방문한 이후 로딩 시간을 개선하는 데 중요합니다.
이 명세에서는 이러한 캐시가 매우 빠른 컴파일과 구분되지 않지만,
애플리케이션에서는 createComputePipelineAsync()
가
해결되는 데 걸리는 시간을 쉽게 측정할 수 있습니다. 이는 오리진 간 정보(예: "사용자가 이 특정 셰이더를 사용하는 사이트에 접속했는가")를 누출할 수 있으므로, 사용자 에이전트는 스토리지 파티셔닝의 모범 사례를 따라야 합니다.
시스템의 GPU 드라이버 역시 자체적으로 컴파일된 셰이더 및 파이프라인 캐시를 보유할 수 있습니다. 사용자 에이전트는 가능하다면 이를 비활성화하거나, 셰이더에 파티션별 데이터를 추가하여 GPU 드라이버가 서로 다르게 인식하도록 할 수 있습니다.
2.2.5. 드라이버 버그
보안 고려사항에서 설명한 우려사항에 더해, 드라이버 버그는 사용자를 구분할 수 있는 동작 차이를 유발할 수 있습니다. 보안 고려사항에서 언급된 완화책(예: GPU 벤더와의 협력 및 사용자 에이전트의 알려진 문제 우회 구현)이 여기에도 적용됩니다.
2.2.6. 어댑터 식별자
WebGL의 과거 경험에 따르면, 개발자는 코드가 실행되는 GPU를 식별할 수 있어야 강건한 GPU 기반 콘텐츠를 만들고 유지할 수 있습니다. 예를 들어, 알려진 드라이버 버그가 있는 어댑터를 식별하여 이를 우회하거나, 특정 하드웨어에서 기대보다 성능이 낮은 기능을 피할 수 있습니다.
하지만 어댑터 식별자를 노출하면 지문 채취 정보가 자연스럽게 늘어나므로, 어댑터 식별의 정밀도를 제한하고자 하는 요구가 있습니다.
강건한 콘텐츠 구현과 프라이버시 보호의 균형을 맞추기 위해 여러 완화책을 적용할 수 있습니다. 우선, 사용자 에이전트는 알려진 드라이버 이슈를 식별하고 우회함으로써(브라우저가 GPU를 사용하기 시작한 이후로 해오던 것처럼) 개발자의 부담을 줄일 수 있습니다.
어댑터 식별자를 기본적으로 노출할 때는, 실제 사용 중인 어댑터를 식별하지 않으면서도 유용할 수 있도록 최대한 넓게(예: 어댑터의 벤더 및 일반 아키텍처) 식별해야 합니다. 때로는 실제 어댑터의 합리적인 대리로 간주되는 어댑터 식별자를 보고할 수도 있습니다.
어댑터에 대한 전체 상세 정보가 유용한 경우(예: 버그 리포트 제출 시)에는, 사용자가 자신의 하드웨어 정보를 페이지에 추가로 공개하도록 동의할 수 있습니다.
마지막으로, 사용자 에이전트는 필요하다고 판단될 경우(예: 강화된 프라이버시 모드) 어댑터 식별자를 전혀 보고하지 않을 수 있습니다.
3. 기초
3.1. 관례
3.1.1. 구문 단축
이 명세에서는 다음과 같은 구문 단축 표현을 사용합니다:
.
("점") 구문, 프로그래밍 언어에서 일반적임.-
"
Foo.Bar
"는 "값(또는 인터페이스)Foo
의Bar
멤버"를 의미합니다.Foo
가 ordered map이며Bar
가 존재하지 않을 때는undefined
를 반환합니다. ?.
("옵셔널 체이닝") 구문, JavaScript에서 차용.-
"
Foo?.Bar
"는 "Foo
가null
또는undefined
이거나Bar
가 존재하지 않을 때undefined
; 그렇지 않으면Foo.Bar
"를 의미합니다.예를 들어
buffer
가GPUBuffer
일 때,buffer?.\[[device]].\[[adapter]]
는 "buffer
가null
또는undefined
면undefined
; 그렇지 않으면,buffer
의\[[device]]
내부 슬롯의\[[adapter]]
내부 슬롯"을 의미. ??
("널 병합") 구문, JavaScript에서 차용.-
"
x
??y
"는 "x
가 null 또는 undefined가 아니면x
, 그렇지 않으면y
"입니다. - 슬롯 기반 속성
-
동일한 이름의 내부 슬롯에 의해 지원되는 WebIDL 속성입니다. 변경 가능할 수도, 불가능할 수도 있습니다.
3.1.2. WebGPU 객체
WebGPU 객체는 WebGPU 인터페이스와 내부 객체로 이루어집니다.
WebGPU 인터페이스는 WebGPU 객체의 공개 인터페이스와 상태를 정의합니다. 이는 객체가 생성된 콘텐츠 타임라인(JavaScript에서 노출되는 WebIDL 인터페이스)에서 사용할 수 있습니다.
GPUObjectBase
를 포함하는 모든 인터페이스는 WebGPU 인터페이스입니다.
내부 객체는 WebGPU 객체의 상태를 디바이스 타임라인에서 추적합니다. 내부 객체의 변경 가능한 상태에 대한 모든 읽기/쓰기는 하나의 잘 정렬된 디바이스 타임라인에서 실행되는 단계에서만 발생합니다.
다음과 같은 특별한 속성 유형이 WebGPU 객체에 정의될 수 있습니다:
- 불변 속성
-
객체 초기화 시 설정되는 읽기 전용 슬롯입니다. 모든 타임라인에서 접근할 수 있습니다.
참고: 슬롯이 불변이므로 구현체는 필요에 따라 여러 타임라인에 복사본을 둘 수 있습니다. 불변 속성은 이 명세에서 여러 복사본을 설명하지 않기 위해 이렇게 정의됩니다.
[[대괄호]]
로 명명되면 내부 슬롯입니다.
대괄호없이
로 명명되면 슬롯 기반 속성의 WebGPU 인터페이스입니다. - 콘텐츠 타임라인 속성
-
객체가 생성된 콘텐츠 타임라인에서만 접근할 수 있는 속성입니다.
[[대괄호]]
로 명명되면 내부 슬롯입니다.
대괄호없이
로 명명되면 슬롯 기반 속성의 WebGPU 인터페이스입니다. - 디바이스 타임라인 속성
-
내부 객체의 상태를 추적하는 속성이며, 객체가 생성된 디바이스 타임라인에서만 접근할 수 있습니다. 디바이스 타임라인 속성은 변경 가능할 수 있습니다.
디바이스 타임라인 속성은
[[대괄호]]
로 명명되며, 내부 슬롯입니다. - 큐 타임라인 속성
-
내부 객체의 상태를 추적하며, 객체가 생성된 큐 타임라인에서만 접근할 수 있습니다. 큐 타임라인 속성은 변경 가능할 수 있습니다.
큐 타임라인 속성은
[[대괄호]]
로 명명되며, 내부 슬롯입니다.
interface mixin GPUObjectBase {attribute USVString label ; };
GPUObjectBase
parent,
인터페이스 T, GPUObjectDescriptorBase
descriptor)
(T는 GPUObjectBase
를
확장함),
다음 콘텐츠 타임라인 단계 실행:
-
device를 parent.
[[device]]
로 둡니다. -
object를 T의 새 인스턴스로 둡니다.
-
object.
[[device]]
에 device를 설정합니다. -
object를 반환합니다.
GPUObjectBase
에는 다음 불변 속성이 있습니다:
GPUObjectBase
에는 다음 콘텐츠
타임라인 속성이 있습니다:
label
, 타입 USVString-
개발자가 제공하는 레이블로, 구현체 정의 방식으로 사용됩니다. 브라우저, OS 또는 기타 도구에서 개발자가 해당 내부 객체를 식별하는 데 사용할 수 있습니다. 예를 들어
GPUError
메시지, 콘솔 경고, 브라우저 개발자 도구, 플랫폼 디버깅 유틸리티 등에 레이블을 표시할 수 있습니다.참고:구현체는 WebGPU 객체 식별을 위해 오류 메시지에 레이블을 활용하는 것이 권장됩니다.그러나 객체 식별 방식이 반드시 레이블만을 의미하지는 않습니다: 구현체는 레이블이 없는 경우에도 사용 가능한 다른 정보를 활용해야 합니다. 예시:
-
GPUTexture
의 부모 레이블을GPUTextureView
출력 시 사용. -
GPUCommandEncoder
의 부모 레이블을GPURenderPassEncoder
또는GPUComputePassEncoder
출력 시 사용. -
GPUCommandEncoder
의 소스 레이블을GPUCommandBuffer
출력 시 사용. -
GPURenderBundleEncoder
의 소스 레이블을GPURenderBundle
출력 시 사용.
참고:label
은GPUObjectBase
의 속성입니다. 두GPUObjectBase
"래퍼" 객체는 같은 기반 객체를 참조하더라도 완전히 별도의 레이블 상태를 가집니다 (예:getBindGroupLayout()
반환 객체).label
속성은 JavaScript에서 설정되는 경우를 제외하고는 변경되지 않습니다.즉, 하나의 기반 객체에 여러 개의 레이블이 연결될 수 있습니다. 이 명세는 레이블이 디바이스 타임라인에 어떻게 전달되는지 정의하지 않습니다. 레이블 사용 방식은 완전히 구현체 정의입니다: 오류 메시지에 가장 최근 레이블, 모든 레이블, 또는 레이블을 전혀 표시하지 않을 수 있습니다.
타입을
USVString
으로 정의한 이유는, 일부 사용자 에이전트가 이를 기반 네이티브 API의 디버그 기능에 제공할 수 있기 때문입니다. -
GPUObjectBase
에는 다음 디바이스
타임라인 속성이 있습니다:
[[valid]]
, 타입boolean
, 초기값true
.-
true
면 내부 객체가 사용 가능함을 의미합니다.
[[device]]
)의
가비지 컬렉션을 방해하지 않아야 합니다. 하지만 일부 구현체에서는 부모 객체에 강한 참조를 유지해야 할 수 있어 이를 보장할 수 없습니다.
따라서 개발자는 WebGPU 인터페이스의 모든 자식 객체가 가비지 컬렉션될 때까지 해당 인터페이스가 수거되지 않을 수 있음을 염두에 두어야 합니다. 이는 일부 리소스가 예상보다 오래 할당된 상태로 남아 있을 수 있음을 의미합니다.
할당된 리소스를 예측 가능하게 해제하려면, destroy
메서드(WebGPU 인터페이스의 예: GPUDevice
.destroy()
또는 GPUBuffer
.destroy()
)를
가비지 컬렉션에 의존하기보다 적극적으로 호출하는 것이 좋습니다.
3.1.3. 객체 디스크립터
객체 디스크립터는 객체를 생성하는 데
필요한 정보를 담고 있으며,
일반적으로 create*
메서드(예: GPUDevice
의
메서드)를 통해 생성됩니다.
dictionary {
GPUObjectDescriptorBase USVString label = ""; };
GPUObjectDescriptorBase
에는 다음 멤버가 있습니다:
label
, 타입 USVString, 기본값""
-
GPUObjectBase.label
의 초기값입니다.
3.2. 비동기성
3.2.1. 잘못된 내부 객체 및 전염성 무효화
WebGPU의 객체 생성 작업은 프라미스를 반환하지 않지만, 내부적으로는 비동기적으로 동작합니다. 반환된 객체는 내부 객체를 참조하며, 디바이스 타임라인에서 조작됩니다. 예외나 거부로 실패하는 대신, 대부분의 디바이스 타임라인에서 발생하는 오류는
해당 디바이스에서 생성된 GPUError
를 통해
전달됩니다.
내부 객체는 유효하거나 무효입니다. 무효 객체는 이후에 유효 상태가 될 수 없지만, 유효 객체는 무효화될 수 있습니다.
객체는 생성 시 무효일 수 있으며,
예를 들어 객체 디스크립터가 유효한 객체를
나타내지 않거나, 리소스 할당에 필요한 메모리가 부족할 때 발생할 수 있습니다.
또한, 다른 무효 객체로부터 객체를 생성할 때도 발생하는데
(예: 무효 GPUTexture
에
대해 createView()
를
호출하는 경우),
이를 전염성 무효화라고
합니다.
내부 객체는
대부분의 타입에서 생성 후 무효가 될 수 없지만, 소유 디바이스가 손실되거나,
destroyed
상태,
혹은 버퍼 상태가 "destroyed" 등 특수 내부 상태일 때 사용 불가능해질 수 있습니다.
일부 타입의 내부 객체는 생성 후에도 무효가
될 수 있는데, 대표적으로
디바이스, 어댑터, GPUCommandBuffer
,
그리고 커맨드/패스/번들 인코더 등이 해당됩니다.
GPUObjectBase
object가 targetObject와 함께 사용에 유효하려면 아래 디바이스 타임라인 요구사항을 모두 충족해야 합니다:
-
object.
[[valid]]
값이true
여야 합니다. -
object.
[[device]]
.[[valid]]
값이true
여야 합니다. -
object.
[[device]]
값이 targetObject.[[device]]
와 같아야 합니다.
3.2.2. 프라미스 순서
WebGPU의 여러 작업은 프라미스를 반환합니다.
WebGPU는 이 프라미스들이 해결(성공 또는 실패)되는 순서에 대해 다음의 경우를 제외하고 어떠한 보장도 하지 않습니다:
-
어떤
GPUQueue
q에 대해, p1 = q.onSubmittedWorkDone()
호출이 p2 = q.onSubmittedWorkDone()
호출보다 먼저라면, p1이 p2보다 먼저 해결되어야 합니다. -
같은
GPUQueue
q 및GPUBuffer
b가 같은GPUDevice
에 있을 때, p1 = b.mapAsync()
호출이 p2 = q.onSubmittedWorkDone()
호출보다 먼저라면, p1이 p2보다 먼저 해결되어야 합니다.
애플리케이션은 그 외의 프라미스 해결 순서에 의존해서는 안 됩니다.
3.3. 좌표계
렌더링 작업에서는 다음과 같은 좌표계를 사용합니다:
-
정규화된 디바이스 좌표(또는 NDC)은 3차원 좌표계로,
-
-1.0 ≤ x ≤ 1.0
-
-1.0 ≤ y ≤ 1.0
-
0.0 ≤ z ≤ 1.0
-
좌하단 꼭짓점은 (-1.0, -1.0, z)입니다.
정규화된 디바이스 좌표. 참고:
z = 0
또는z = 1
이 근접 평면으로 처리되는지는 애플리케이션에 따라 다릅니다. 위 그림은z = 0
을 근접 평면으로 표현하지만, 실제 동작은 셰이더에서 사용하는 투영 행렬,depthClearValue
,depthCompare
함수 등 여러 요소의 조합에 따라 결정됩니다. -
-
클립 공간 좌표는 4차원: (x, y, z, w)
-
클립 공간 좌표는 버텍스의 클립 위치(즉, 버텍스 셰이더의 position 출력)와 클립 볼륨에 사용됩니다.
-
정규화된 디바이스 좌표와 클립 공간 좌표의 관계: 점 p = (p.x, p.y, p.z, p.w)가 클립 볼륨 내에 있으면, 정규화된 디바이스 좌표는 (p.x ÷ p.w, p.y ÷ p.w, p.z ÷ p.w)입니다.
-
-
프레임버퍼 좌표는 프레임버퍼의 픽셀을 주소 지정합니다.
-
2차원 좌표입니다.
-
각 픽셀은 x, y 방향으로 1 단위씩 확장됩니다.
-
좌상단 꼭짓점은 (0.0, 0.0)입니다.
-
x는 오른쪽으로 증가합니다.
-
y는 아래로 증가합니다.
-
§ 17 렌더 패스 및 § 23.2.5 래스터화 참고.
프레임버퍼 좌표. -
-
뷰포트 좌표는 x, y 방향의 프레임버퍼 좌표와 깊이(z)를 결합합니다.
-
일반적으로 0.0 ≤ z ≤ 1.0이지만,
[[viewport]]
.minDepth
및maxDepth
를setViewport()
로 설정하여 변경할 수 있습니다.
-
-
프래그먼트 좌표는 뷰포트 좌표와 일치합니다.
-
텍스처 좌표는 2D에서 "UV 좌표"라고도 하며, 텍스처 샘플링에 사용되며
텍스처 차원
에 따라 구성 요소의 수가 결정됩니다.-
0 ≤ u ≤ 1.0
-
0 ≤ v ≤ 1.0
-
0 ≤ w ≤ 1.0
-
(0.0, 0.0, 0.0)은 텍스처 메모리 주소 순서 기준 첫 번째 텍셀에 해당합니다.
-
(1.0, 1.0, 1.0)은 텍스처 메모리 주소 순서 기준 마지막 텍셀에 해당합니다.
2D 텍스처 좌표. -
-
윈도우 좌표 또는 프레젠트 좌표는 프레임버퍼 좌표와 일치하며, 외부 디스플레이 또는 이와 유사한 인터페이스와 상호작용 시 사용됩니다.
참고: WebGPU의 좌표계는 그래픽 파이프라인에서 DirectX의 좌표계와 일치합니다.
3.4. 프로그래밍 모델
3.4.1. 타임라인
WebGPU의 동작은 "타임라인"으로 설명됩니다. 각 작업(알고리즘으로 정의됨)은 타임라인에서 발생합니다. 타임라인은 작업의 순서뿐만 아니라 어떤 상태가 어떤 작업에 사용 가능한지도 명확히 정의합니다.
참고: 이 "타임라인" 모델은 브라우저 엔진의 멀티 프로세스 모델(일반적으로 "콘텐츠 프로세스"와 "GPU 프로세스")의 제약을 기술하며, 많은 구현에서 GPU 자체도 별도의 실행 단위로 작동합니다. WebGPU 구현은 타임라인이 병렬 실행되어야 할 필요가 없으므로, 복수 프로세스나 복수 스레드가 필요하지 않습니다. (단, get a copy of the image contents of a context와 같이 다른 타임라인이 완료될 때까지 동기적으로 대기해야 하는 경우에는 동시성이 필요합니다.)
- 콘텐츠 타임라인
-
웹 스크립트 실행과 연관되어 있습니다. 본 명세에서 기술한 모든 메서드 호출이 이에 포함됩니다.
GPUDevice
device
에서 작업을 콘텐츠 타임라인에 전달하려면, 해당 단계로 queue a global task for GPUDevicedevice
를 실행합니다. - 디바이스 타임라인
-
사용자 에이전트가 발행하는 GPU 디바이스 작업과 연관되어 있습니다. 어댑터, 디바이스, GPU 리소스 및 상태 객체의 생성이 포함되며, 이는 사용자 에이전트가 GPU를 제어하는 관점에서 일반적으로 동기적으로 동작하지만, 별도의 OS 프로세스에서 실행될 수 있습니다.
- 큐 타임라인
-
GPU의 연산 장치에서 작업이 실제로 실행되는 것과 연관되어 있습니다. 실제 드로우, 복사, 연산 작업이 GPU에서 실행됩니다.
- 타임라인 비특정
-
위의 어느 타임라인과도 연관될 수 있습니다.
단계가 불변 속성이나 호출 단계에서 전달된 인자만 다룬다면 어떤 타임라인에서도 실행될 수 있습니다.
- 불변 값 예시 용어 정의
-
모든 타임라인에서 사용될 수 있습니다.
- 콘텐츠 타임라인 예시 용어 정의
-
오직 콘텐츠 타임라인에서만 사용될 수 있습니다.
- 디바이스 타임라인 예시 용어 정의
-
오직 디바이스 타임라인에서만 사용될 수 있습니다.
- 큐 타임라인 예시 용어 정의
-
오직 큐 타임라인에서만 사용될 수 있습니다.
불변 값 예시 용어 사용.
불변 값 예시 용어 사용. 콘텐츠 타임라인 예시 용어 사용.
불변 값 예시 용어 사용. 디바이스 타임라인 예시 용어 사용.
불변 값 예시 용어 사용. 큐 타임라인 예시 용어 사용.
본 명세에서 비동기 작업은 반환값이 콘텐츠 타임라인 이외의 타임라인에서 발생하는 작업에 따라 결정될 때 사용됩니다. 비동기 작업은 API에서 프라미스와 이벤트로 표시됩니다.
GPUComputePassEncoder.dispatchWorkgroups()
:
-
사용자가
dispatchWorkgroups
명령을GPUComputePassEncoder
의 메서드로 호출하여, 콘텐츠 타임라인에서 실행합니다. -
사용자가
GPUQueue.submit()
를 호출하여GPUCommandBuffer
를 사용자 에이전트에 전달하면, 에이전트가 OS 드라이버에 저수준 제출을 요청하여 디바이스 타임라인에서 처리합니다. -
제출된 작업은 GPU 호출 스케줄러가 실제 연산 장치에 분배하여 실행하며, 이는 큐 타임라인에서 발생합니다.
GPUDevice.createBuffer()
:
-
사용자가
GPUBufferDescriptor
를 작성하고, 이를 이용해GPUBuffer
를 생성하는데, 이는 콘텐츠 타임라인에서 실행됩니다. -
사용자 에이전트가 디바이스 타임라인에서 저수준 버퍼를 생성합니다.
3.4.2. 메모리 모델
이 섹션은 규범적이지 않습니다.
애플리케이션 초기화 루틴에서 GPUDevice
를 얻은
후,
WebGPU 플랫폼은 다음과 같은
계층으로 구성되어 있다고 볼 수 있습니다:
-
명세를 구현하는 사용자 에이전트.
-
이 장치용 저수준 네이티브 API 드라이버가 있는 운영체제.
-
실제 CPU 및 GPU 하드웨어.
각 WebGPU 플랫폼 계층은 명세를 구현할 때 사용자 에이전트가 고려해야 할 다양한 메모리 유형을 가질 수 있습니다:
-
스크립트가 소유한 메모리(예: 스크립트에서 생성한
ArrayBuffer
)는 일반적으로 GPU 드라이버에서 접근할 수 없습니다. -
사용자 에이전트는 콘텐츠 실행과 GPU 드라이버와의 통신을 담당하는 서로 다른 프로세스를 가질 수 있습니다. 이 경우, 데이터 전송을 위해 프로세스 간 공유 메모리를 사용합니다.
-
전용 GPU는 고대역폭 전용 메모리를 가지고, 통합 GPU는 일반적으로 시스템과 메모리를 공유합니다.
대부분의 물리적 리소스는 GPU가 계산이나 렌더링에 효율적인 타입의 메모리에 할당됩니다. 사용자가 GPU로 새로운 데이터를 제공해야 할 때, 데이터는 먼저 프로세스 경계를 넘어 GPU 드라이버와 통신하는 사용자 에이전트 부분에 도달해야 할 수 있습니다. 이후 드라이버가 데이터를 볼 수 있도록 만들어야 하는데, 때로는 드라이버가 할당한 스테이징 메모리로 복사해야 합니다. 마지막으로, 전용 GPU 메모리로 데이터를 전송해야 할 수 있으며, 내부 레이아웃도 GPU가 효율적으로 처리할 수 있도록 변경될 수 있습니다.
이러한 모든 전환은 사용자 에이전트의 WebGPU 구현이 처리합니다.
참고: 이 예시는 최악의 경우를 설명합니다. 실제로는 프로세스 경계를 넘지 않아도 되거나,
사용자에게 ArrayBuffer
뒤에 드라이버가 관리하는 메모리를 직접 노출하여 데이터 복사를 피할 수 있는 경우도 있습니다.
3.4.3. 자원 사용
물리적 리소스는 내부 사용 형태로 GPU 명령에서 사용할 수 있습니다:
- 입력
-
드로우 또는 디스패치 호출에 대한 입력 데이터를 가진 버퍼. 내용 보존. buffer
INDEX
, bufferVERTEX
, 또는 bufferINDIRECT
에 의해 허용됨. - 상수
-
셰이더 관점에서 상수로 간주되는 리소스 바인딩. 내용 보존. buffer
UNIFORM
또는 textureTEXTURE_BINDING
에 의해 허용됨. - 저장소
-
읽기/쓰기 저장 리소스 바인딩. buffer
STORAGE
또는 textureSTORAGE_BINDING
에 의해 허용됨. - 저장소-읽기
-
읽기 전용 저장 리소스 바인딩. 내용 보존. buffer
STORAGE
또는 textureSTORAGE_BINDING
에 의해 허용됨. - 어태치먼트
-
렌더 패스에서 읽기/쓰기 출력 어태치먼트 또는 쓰기 전용 리졸브 타깃으로 사용되는 텍스처. texture
RENDER_ATTACHMENT
에 의해 허용됨. - 어태치먼트-읽기
-
렌더 패스에서 읽기 전용 어태치먼트로 사용되는 텍스처. 내용 보존. texture
RENDER_ATTACHMENT
에 의해 허용됨.
서브리소스는 전체 버퍼 또는 텍스처 서브리소스를 의미합니다.
-
U의 각 사용이 저장소일 때.
여러 개의 쓰기 가능한 사용도 허용됩니다. 이것이 사용 범위 저장소 예외입니다.
-
U의 각 사용이 어태치먼트일 때.
여러 개의 쓰기 가능한 사용도 허용됩니다. 이것이 사용 범위 어태치먼트 예외입니다.
사용을 호환 사용 리스트로만 결합하도록 강제하면, 메모리 작업에서 데이터 경쟁(race)이 발생할 수 있는 시점을 API가 제한할 수 있습니다. 이 특성은 WebGPU 기반 애플리케이션이 다른 플랫폼에서 수정 없이 잘 동작할 가능성을 높여줍니다.
-
모든 aspect가 읽기 전용으로 표시된 깊이/스텐실 어태치먼트로서 (
depthReadOnly
및/또는stencilReadOnly
사용). -
드로우 호출에 텍스처 바인딩으로서.
-
버퍼 또는 텍스처를 렌더 패스에서 두 개의 다른 드로우 호출에 저장소로 바인딩할 수 있습니다.
-
하나의 버퍼의 분리된 범위를 두 개의 바인딩 포인트에 저장소로 바인딩할 수 있습니다.
겹치는 범위는 하나의 디스패치/드로우 호출에는 바인딩할 수 없습니다; 이는 "Encoder bind groups alias a writable resource"에서 검사합니다.
한 슬라이스를 두 개의 다른 어태치먼트에 바인딩하는 것은 허용되지 않습니다;
이는 beginRenderPass()
에서
검사합니다.
3.4.4. 동기화
사용 범위는 map 형식으로, 서브리소스에서 list<내부 사용>>로 연결됩니다. 각 사용 범위는 서로 동시 실행될 수 있는 작업의 범위를 포함하며, 따라서 서브리소스는 범위 내에서 호환 사용 리스트로만 사용할 수 있습니다.
사용 범위는 인코딩 과정에서 생성 및 검증됩니다:
사용 범위는 다음과 같습니다:
-
컴퓨트 패스에서는 각각의 디스패치 명령(
dispatchWorkgroups()
또는dispatchWorkgroupsIndirect()
) 가 하나의 사용 범위입니다.서브리소스가 해당 사용 범위에서 사용된다고 간주하려면, 디스패치 호출에 의해 접근 가능할 경우 포함됩니다:
-
현재
GPUComputePipeline
의[[layout]]
에서 사용된 슬롯의 바인드 그룹이 참조하는 모든 서브리소스 -
디스패치 호출에 직접 사용된 버퍼(예: 인디렉트 버퍼)
참고: setBindGroup() 같은 상태 설정 컴퓨트 패스 명령은 바인딩된 리소스를 사용 범위에 직접 추가하지 않습니다. 디스패치 호출에서 상태를 확인할 때만 포함됩니다.
-
-
하나의 렌더 패스가 하나의 사용 범위입니다.
서브리소스가 해당 사용 범위에서 사용된다고 간주하려면, 어떤 명령(상태 설정 명령 포함)에서라도 참조될 경우 포함됩니다:
-
setVertexBuffer()
로 설정된 버퍼 -
setIndexBuffer()
로 설정된 버퍼 -
setBindGroup()으로 설정된 바인드 그룹이 참조하는 모든 서브리소스
-
드로우 호출에 직접 사용되는 버퍼(예: 인디렉트 버퍼)
-
참고: 복사 명령은 독립 실행 작업이므로 검증에 사용 범위를 사용하지 않습니다. 자체적으로 self-race를 방지하는 검증을 구현합니다.
-
렌더 패스에서 setBindGroup() 호출에 사용된 서브리소스는, 현재 바인딩된 파이프라인의 셰이더나 레이아웃이 해당 바인딩을 실제로 필요로 하거나, 바인드 그룹이 또 다른 set 호출에 의해 가려졌는지와 관계없이 사용 범위에 포함됩니다.
-
setVertexBuffer() 호출에 사용된 버퍼는, 어떤 드로우 호출이 해당 버퍼를 사용하는지, 또는 또 다른 set 호출에 의해 가려졌는지와 관계없이 사용 범위에 포함됩니다.
-
setIndexBuffer() 호출에 사용된 버퍼는, 어떤 드로우 호출이 해당 버퍼를 사용하는지, 또는 또 다른 set 호출에 의해 가려졌는지와 관계없이 사용 범위에 포함됩니다.
-
색상 어태치먼트, 리졸브 어태치먼트, 깊이/스텐실 어태치먼트로 사용되는 텍스처 서브리소스는 beginRenderPass()에서 셰이더가 실제로 해당 어태치먼트를 필요로 하는지와 관계없이 사용 범위에 포함됩니다.
-
visibility가 0인 바인드 그룹 엔트리에 사용된 리소스나, 컴퓨트 스테이지에만 visible하지만 렌더 패스에서 사용되는 리소스(혹은 그 반대)도 사용 범위에 포함됩니다.
3.5. 핵심 내부 객체
3.5.1. 어댑터
어댑터는 시스템에서 WebGPU 구현을 식별합니다: 브라우저 기반 플랫폼의 연산/렌더링 기능 인스턴스와, 그 기능 위에 구현된 브라우저의 WebGPU 인스턴스 모두를 포함합니다.
어댑터는 GPUAdapter
를
통해 노출됩니다.
어댑터는 기반 구현을 고유하게 대표하지 않습니다:
requestAdapter()
를
여러 번 호출하면 매번 다른 어댑터 객체가 반환됩니다.
각 어댑터 객체는 오직 하나의 디바이스만 생성할 수 있습니다:
requestDevice()
가
성공적으로 호출되면 어댑터의 [[state]]
가
"consumed"
로
변경됩니다.
추가로 어댑터 객체는 언제든지 만료될 수
있습니다.
참고:
이는 디바이스 생성 시 어댑터 선택에서 최신 시스템 상태를 사용할 수 있도록 보장합니다.
또한 첫 초기화, 어댑터 분리로 인한 재초기화, 테스트용 GPUDevice.destroy()
호출 등 여러 시나리오를 일관되게 처리할 수 있게 해줍니다.
어댑터는 성능에 중대한 제한이 있지만, 더 넓은 호환성, 예측 가능한 동작, 또는 향상된 프라이버시와 같은 조합을 위해 폴백 어댑터로 간주될 수 있습니다. 모든 시스템에서 폴백 어댑터가 반드시 제공될 필요는 없습니다.
[[features]]
, 타입 ordered set<GPUFeatureName
>, 읽기 전용-
이 어댑터에서 디바이스를 생성할 때 사용할 수 있는 기능들입니다.
[[limits]]
, 타입 지원 한계, 읽기 전용-
이 어댑터에서 디바이스를 생성할 때 사용할 수 있는 최상 한계입니다.
[[fallback]]
, 타입boolean
, 읽기 전용-
true
일 때 어댑터가 폴백 어댑터임을 나타냅니다. [[xrCompatible]]
, 타입 boolean-
true
일 때, 어댑터가 WebXR 세션과 호환되도록 요청되었음을 나타냅니다.
어댑터는 다음 디바이스 타임라인 속성을 가집니다:
[[state]]
, 초기값"valid"
-
"valid"
-
어댑터를 사용해 디바이스를 생성할 수 있습니다.
"consumed"
-
어댑터가 이미 디바이스 생성에 사용되었으므로 다시 사용할 수 없습니다.
"expired"
-
어댑터가 다른 이유로 만료되었습니다.
3.5.2. 디바이스
디바이스는 어댑터의 논리적 인스턴스화로, 내부 객체가 이 디바이스를 통해 생성됩니다.
디바이스는 자신으로부터 생성된 모든 내부 객체의 독점 소유자입니다:
디바이스가 무효가 될 때
(손실되거나 destroyed
일
때),
해당 디바이스 및 그 위에서 생성된 모든 객체(직접적으로 예:
createTexture()
,
간접적으로 예: createView()
)
는 암묵적으로 사용 불가 상태가 됩니다.
[[adapter]]
, 타입 어댑터, 읽기 전용-
이 디바이스가 생성된 어댑터입니다.
[[features]]
, 타입 ordered set<GPUFeatureName
>, 읽기 전용-
이 디바이스에서 사용할 수 있는 기능이며, 생성 시에 결정됩니다. 기반 어댑터가 더 많은 기능을 지원하더라도, 추가 기능을 사용할 수 없습니다.
[[limits]]
, 타입 지원 한계, 읽기 전용-
이 디바이스에서 사용할 수 있는 한계이며, 생성 시에 결정됩니다. 기반 어댑터가 더 나은 한계를 지원하더라도, 더 나은 한계를 사용할 수 없습니다.
디바이스는 다음 콘텐츠 타임라인 속성을 가집니다:
GPUDeviceDescriptor
descriptor로 새
디바이스를 생성하려면, 다음 디바이스 타임라인 단계 실행:
-
features에 descriptor.
requiredFeatures
의 값을 set으로 둡니다. -
features에
"texture-formats-tier2"
가 포함되어 있다면:-
Append
"texture-formats-tier1"
를 features에 추가
-
-
features에
"texture-formats-tier1"
가 포함되어 있다면:-
Append
"rg11b10ufloat-renderable"
를 features에 추가
-
-
Append
"core-features-and-limits"
를 features에 추가. -
limits에 모든 값을 기본값으로 둔 지원 한계 객체를 둡니다.
-
descriptor.
requiredLimits
의 각 (key, value)에 대해:-
value가
undefined
가 아니고, value가 limits[key]보다 더 나으면:-
limits[key]를 value로 설정
-
-
-
device에 디바이스 객체를 둡니다.
-
device.
[[adapter]]
를 adapter로 설정. -
device.
[[features]]
를 features로 설정. -
device.
[[limits]]
를 limits로 설정. -
device를 반환.
사용자 에이전트가 디바이스 접근을 취소해야 할 때마다,
디바이스
손실(device
, "unknown"
)
을 해당 디바이스의 디바이스 타임라인에서
호출합니다.
이는 해당 타임라인에 대기 중이던 다른 작업보다 먼저 발생할 수 있습니다.
작업 실패로 인해 디바이스의 객체 상태가 관찰될 만큼 변하거나 내부 구현/드라이버 상태가 손상될 위험이 있다면, 이런 변화가 관찰되지 않도록 디바이스를 손실해야 합니다.
참고:
앱이 직접 destroy()
로
디바이스 손실을 유발하지 않은 모든 경우에,
사용자 에이전트는 lost
프라미스를 핸들링하더라도 무조건 개발자 가시 경고를 고려해야 합니다.
이런 시나리오는 드물어야 하며, 신호는 중요합니다. 왜냐하면 WebGPU API 대부분은 앱의 런타임 흐름을 방해하지 않기 위해 문제가 없는 것처럼 동작하기 때문입니다:
검증 오류가 발생하지 않고, 대부분의 프라미스가 정상적으로 resolve되는 등.
-
무효화 device.
-
device.
[[content device]]
의 콘텐츠 타임라인에서 다음 단계 실행: -
device가 손실 상태가 됨을 기다리는 모든 대기 단계 완료.
참고: 손실된 디바이스에서는 오류가 발생하지 않습니다. § 22 오류 및 디버깅 참고.
-
디바이스 타임라인이 event의 완료를 통보받았거나,
-
device가 이미 손실 상태이거나, 손실 상태가 되었을 때:
그때 timeline에서 steps를 실행합니다.
3.6. 선택적 기능
WebGPU 어댑터와 디바이스에는 기능(capabilities)이 있으며, 이는 WebGPU 기능이 구현마다 다르게 동작하는 부분을 설명합니다. 주로 하드웨어 또는 시스템 소프트웨어의 제약 때문입니다. 기능은 기능(feature) 또는 한계(limit)입니다.
사용자 에이전트는 32개를 초과하는 구분 가능한 구성이나 버킷을 공개해서는 안 됩니다.
어댑터의 기능은 반드시 § 4.2.1 어댑터 기능 보장을 따라야 합니다.
requestDevice()
에서
지원되는 기능만 요청할 수 있습니다;
지원되지 않는 기능을 요청하면 실패합니다.
디바이스의 기능은 "새 디바이스"에서 어댑터의
기본값(기능 없음 및 지원 한계의
기본값)에서 시작해,
requestDevice()
에서
요청한 기능을 추가하여 결정됩니다.
이러한 기능은 어댑터의 기능과 관계없이 적용됩니다.
프라이버시 관련 내용은 § 2.2.1 기기별 기능 및 한계를 참고하세요.
3.6.1. 기능
기능(feature)은 모든 구현에서 지원되지 않는 WebGPU의 선택적 기능 집합입니다. 일반적으로 하드웨어 또는 시스템 소프트웨어의 제약 때문입니다.
모든 기능은 선택적이지만, 어댑터는 그 가용성을 보장합니다 (§ 4.2.1 어댑터 기능 보장 참조).
디바이스는 생성 시 결정된 정확한 기능 집합만 지원합니다(§ 3.6 선택적 기능 참조). API 호출은 이 디바이스의 기능에 따라 검증을 수행합니다(어댑터의 기능이 아님):
-
기존 API를 새로운 방식으로 사용하는 경우 일반적으로 검증 오류가 발생합니다.
-
여러 유형의 선택적 API 표면이 있습니다:
-
새로운 메서드나 enum 값을 사용하면 항상
TypeError
가 발생합니다. -
새로운 딕셔너리 멤버를 올바른 타입의 기본값이 아닌 값으로 사용하면 일반적으로 검증 오류가 발생합니다.
-
새로운 WGSL
enable
지시문을 사용하면 항상createShaderModule()
에서 검증 오류가 발생합니다.
-
GPUFeatureName
feature가 GPUObjectBase
object에 활성화됨이란,
object.[[device]]
.[[features]]
에
포함될 때만 해당 feature가 활성화됩니다.
각 기능이 어떤 역할을 하는지에 대한 설명은 기능 색인을 참고하세요.
참고: 기능을 활성화하는 것이 항상 바람직한 것은 아니며, 성능에 영향을 줄 수 있습니다. 이를 감안해, 그리고 다양한 디바이스 및 구현에서 이식성을 높이기 위해, 실제로 필요한 기능만 요청하는 것이 좋습니다.
3.6.2. 한계
한계(limit)는 디바이스에서 WebGPU 사용에 대한 수치적 한계입니다.
참고: "더 나은" 한계를 설정하는 것이 항상 바람직한 것은 아니며, 성능에 영향을 줄 수 있습니다. 이를 감안해, 그리고 다양한 디바이스 및 구현에서 이식성을 높이기 위해, 실제로 필요한 경우에만 기본값보다 더 나은 한계를 요청하는 것이 좋습니다.
각 한계에는 기본값이 있습니다.
어댑터는 항상 기본값 또는 더 나은 값을 지원합니다 (§ 4.2.1 어댑터 기능 보장 참고).
디바이스는 생성 시 결정된 정확한 한계 집합만 지원합니다(§ 3.6 선택적 기능 참조). API 호출은 이 디바이스의 한계에 따라 검증을 수행합니다(어댑터의 한계가 아님), 더 나은 값도, 더 낮은 값도 사용할 수 없습니다.
각 한계에 대해 어떤 값이 더 나은 값인지 정의됩니다. 더 나은 한계 값은 항상 검증을 완화하여, 더 많은 프로그램이 유효해집니다. 각 한계 클래스마다 "더 나은"의 정의가 다릅니다.
한계마다 서로 다른 한계 클래스가 있습니다:
- 최대값
-
해당 한계는 API에 전달되는 어떤 값의 최대값을 제한합니다.
더 높은 값이 더 나은 값입니다.
기본값 이상(≥)만 설정할 수 있습니다. 더 낮은 값은 기본값으로 강제됩니다.
- 정렬값
-
해당 한계는 API에 전달되는 어떤 값의 최소 정렬값을 제한합니다. 즉, 값은 해당 한계의 배수여야 합니다.
더 낮은 값이 더 나은 값입니다.
기본값 이하(≤)의 2의 거듭제곱만 설정할 수 있습니다. 2의 거듭제곱이 아닌 값은 유효하지 않습니다. 더 높은 거듭제곱은 기본값으로 강제됩니다.
지원 한계 객체는 WebGPU에서 정의된 모든 한계에 대한 값을 가집니다:
한계 이름 | 타입 | 한계 클래스 | 기본값 |
---|---|---|---|
maxTextureDimension1D
| GPUSize32
| 최대값 | 8192 |
size .width
값의 최대 허용치 (1D 텍스처에서 dimension
"1d"
사용).
| |||
maxTextureDimension2D
| GPUSize32
| 최대값 | 8192 |
size .width 및
size .height
값의 최대 허용치 (2D 텍스처에서 dimension
"2d"
사용).
| |||
maxTextureDimension3D
| GPUSize32
| 최대값 | 2048 |
size .width,
size .height
및 size .depthOrArrayLayers
값의 최대 허용치 (3D 텍스처에서 dimension
"3d"
사용).
| |||
maxTextureArrayLayers
| GPUSize32
| 최대값 | 256 |
size .depthOrArrayLayers
값의 최대 허용치 (2D 텍스처에서 dimension
"2d"
사용).
| |||
maxBindGroups
| GPUSize32
| 최대값 | 4 |
GPUBindGroupLayouts
최대 갯수 (bindGroupLayouts
사용 시 GPUPipelineLayout
생성).
| |||
maxBindGroupsPlusVertexBuffers
| GPUSize32
| 최대값 | 24 |
동시에 사용되는 바인드 그룹 및 버텍스 버퍼 슬롯의 최대 갯수 (빈 슬롯 포함).
createRenderPipeline()
및 드로우 호출에서 검증.
| |||
maxBindingsPerBindGroup
| GPUSize32
| 최대값 | 1000 |
GPUBindGroupLayout
생성 시 사용 가능한 binding 인덱스 최대 갯수.
참고: 이 한계는 규범적이지만 임의적입니다.
기본 binding slot limits에서는 하나의 바인드 그룹에
1000개 바인딩을 사용하는 것은 불가능하지만,
| |||
maxDynamicUniformBuffersPerPipelineLayout
| GPUSize32
| 최대값 | 8 |
GPUBindGroupLayoutEntry
중 동적 오프셋이 있는 uniform buffer의 최대 갯수 (GPUPipelineLayout
기준).
binding slot 한계 초과 참고.
| |||
maxDynamicStorageBuffersPerPipelineLayout
| GPUSize32
| 최대값 | 4 |
GPUBindGroupLayoutEntry
중 동적 오프셋이 있는 storage buffer의 최대 갯수 (GPUPipelineLayout
기준).
binding slot 한계 초과 참고.
| |||
maxSampledTexturesPerShaderStage
| GPUSize32
| 최대값 | 16 |
각 GPUShaderStage
stage 별
GPUBindGroupLayoutEntry
중 샘플링 텍스처의 최대 갯수 (GPUPipelineLayout
기준).
binding slot 한계 초과 참고.
| |||
maxSamplersPerShaderStage
| GPUSize32
| 최대값 | 16 |
각 GPUShaderStage
stage 별
GPUBindGroupLayoutEntry
중 샘플러의 최대 갯수 (GPUPipelineLayout
기준).
binding slot 한계 초과 참고.
| |||
maxStorageBuffersPerShaderStage
| GPUSize32
| 최대값 | 8 |
각 GPUShaderStage
stage 별
GPUBindGroupLayoutEntry
중 storage buffer의 최대 갯수 (GPUPipelineLayout
기준).
binding slot 한계 초과 참고.
| |||
maxStorageTexturesPerShaderStage
| GPUSize32
| 최대값 | 4 |
각 GPUShaderStage
stage 별
GPUBindGroupLayoutEntry
중 storage texture의 최대 갯수 (GPUPipelineLayout
기준).
binding slot 한계 초과 참고.
| |||
maxUniformBuffersPerShaderStage
| GPUSize32
| 최대값 | 12 |
각 GPUShaderStage
stage 별
GPUBindGroupLayoutEntry
중 uniform buffer의 최대 갯수 (GPUPipelineLayout
기준).
binding slot 한계 초과 참고.
| |||
maxUniformBufferBindingSize
| GPUSize64
| 최대값 | 65536 bytes |
GPUBufferBinding .size
값의 최대치 (바인딩 타입이 "uniform" 일
때).
| |||
maxStorageBufferBindingSize
| GPUSize64
| 최대값 | 134217728 bytes (128 MiB) |
GPUBufferBinding .size
값의 최대치 (바인딩 타입이 "storage"
또는 "read-only-storage" 일
때).
| |||
minUniformBufferOffsetAlignment
| GPUSize32
| 정렬값 | 256 bytes |
GPUBufferBinding .offset
및 setBindGroup()에서 제공되는 동적 오프셋의 정렬값 (GPUBindGroupLayoutEntry
타입이 "uniform" 일
때).
| |||
minStorageBufferOffsetAlignment
| GPUSize32
| 정렬값 | 256 bytes |
GPUBufferBinding .offset
및 setBindGroup()에서 제공되는 동적 오프셋의 정렬값 (GPUBindGroupLayoutEntry
타입이 "storage"
또는 "read-only-storage" 일
때).
| |||
maxVertexBuffers
| GPUSize32
| 최대값 | 8 |
buffers
최대 갯수 (GPURenderPipeline
생성 시).
| |||
maxBufferSize
| GPUSize64
| 최대값 | 268435456 bytes (256 MiB) |
size
최대값 (GPUBuffer
생성 시).
| |||
maxVertexAttributes
| GPUSize32
| 최대값 | 16 |
attributes
최대 갯수 (buffers
전체 합계, GPURenderPipeline
생성 시).
| |||
maxVertexBufferArrayStride
| GPUSize32
| 최대값 | 2048 bytes |
arrayStride
최대 허용값 (GPURenderPipeline
생성 시).
| |||
maxInterStageShaderVariables
| GPUSize32
| 최대값 | 16 |
입력/출력 변수의 최대 허용 갯수 (버텍스 출력, 프래그먼트 입력 등 스테이지 간 통신). | |||
maxColorAttachments
| GPUSize32
| 최대값 | 8 |
GPURenderPipelineDescriptor .fragment .targets ,
GPURenderPassDescriptor .colorAttachments ,
GPURenderPassLayout .colorFormats
값의 최대 갯수.
| |||
maxColorAttachmentBytesPerSample
| GPUSize32
| 최대값 | 32 |
모든 컬러 어태치먼트에서 렌더 파이프라인 출력 데이터의 한 샘플(픽셀 또는 서브픽셀)을 저장하는 데 필요한 최대 바이트 수. | |||
maxComputeWorkgroupStorageSize
| GPUSize32
| 최대값 | 16384 bytes |
컴퓨트 스테이지 GPUShaderModule
엔트리 포인트에서 사용되는 workgroup 스토리지의 최대 바이트 수.
| |||
maxComputeInvocationsPerWorkgroup
| GPUSize32
| 최대값 | 256 |
컴퓨트 스테이지 GPUShaderModule
엔트리 포인트의 workgroup_size 차원의 곱의 최대값.
| |||
maxComputeWorkgroupSizeX
| GPUSize32
| 최대값 | 256 |
컴퓨트 스테이지 GPUShaderModule
엔트리 포인트의 workgroup_size X 차원의 최대값.
| |||
maxComputeWorkgroupSizeY
| GPUSize32
| 최대값 | 256 |
컴퓨트 스테이지 GPUShaderModule
엔트리 포인트의 workgroup_size Y 차원의 최대값.
| |||
maxComputeWorkgroupSizeZ
| GPUSize32
| 최대값 | 64 |
컴퓨트 스테이지 GPUShaderModule
엔트리 포인트의 workgroup_size Z 차원의 최대값.
| |||
maxComputeWorkgroupsPerDimension
| GPUSize32
| 최대값 | 65535 |
dispatchWorkgroups(workgroupCountX, workgroupCountY, workgroupCountZ)
인자별 최대값.
|
3.6.2.1. GPUSupportedLimits
GPUSupportedLimits
는 어댑터 또는 디바이스의 지원 한계를
노출합니다.
GPUAdapter.limits
와 GPUDevice.limits
참고.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUSupportedLimits {readonly attribute unsigned long ;
maxTextureDimension1D readonly attribute unsigned long ;
maxTextureDimension2D readonly attribute unsigned long ;
maxTextureDimension3D readonly attribute unsigned long ;
maxTextureArrayLayers readonly attribute unsigned long ;
maxBindGroups readonly attribute unsigned long ;
maxBindGroupsPlusVertexBuffers readonly attribute unsigned long ;
maxBindingsPerBindGroup readonly attribute unsigned long ;
maxDynamicUniformBuffersPerPipelineLayout readonly attribute unsigned long ;
maxDynamicStorageBuffersPerPipelineLayout readonly attribute unsigned long ;
maxSampledTexturesPerShaderStage readonly attribute unsigned long ;
maxSamplersPerShaderStage readonly attribute unsigned long ;
maxStorageBuffersPerShaderStage readonly attribute unsigned long ;
maxStorageTexturesPerShaderStage readonly attribute unsigned long ;
maxUniformBuffersPerShaderStage readonly attribute unsigned long long ;
maxUniformBufferBindingSize readonly attribute unsigned long long ;
maxStorageBufferBindingSize readonly attribute unsigned long ;
minUniformBufferOffsetAlignment readonly attribute unsigned long ;
minStorageBufferOffsetAlignment readonly attribute unsigned long ;
maxVertexBuffers readonly attribute unsigned long long ;
maxBufferSize readonly attribute unsigned long ;
maxVertexAttributes readonly attribute unsigned long ;
maxVertexBufferArrayStride readonly attribute unsigned long ;
maxInterStageShaderVariables readonly attribute unsigned long ;
maxColorAttachments readonly attribute unsigned long ;
maxColorAttachmentBytesPerSample readonly attribute unsigned long ;
maxComputeWorkgroupStorageSize readonly attribute unsigned long ;
maxComputeInvocationsPerWorkgroup readonly attribute unsigned long ;
maxComputeWorkgroupSizeX readonly attribute unsigned long ;
maxComputeWorkgroupSizeY readonly attribute unsigned long ;
maxComputeWorkgroupSizeZ readonly attribute unsigned long ; };
maxComputeWorkgroupsPerDimension
3.6.2.2. GPUSupportedFeatures
GPUSupportedFeatures
는 setlike 인터페이스입니다. set entries는
어댑터 또는 디바이스가 지원하는 GPUFeatureName
값(기능)입니다. 반드시 GPUFeatureName
enum의 문자열만 포함해야 합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUSupportedFeatures {readonly setlike <DOMString >; };
GPUSupportedFeatures
set entries의 타입은 DOMString
입니다.
이렇게 하면 사용자 에이전트가 명세의 후속 버전에 추가된 새로운 GPUFeatureName
을
인식하지 못해도 원활하게 처리할 수 있습니다.
만약 set entries의 타입이
GPUFeatureName
이라면,
아래 코드에서 false
를 반환하는 대신 TypeError
가
발생합니다:
3.6.2.3. WGSLLanguageFeatures
WGSLLanguageFeatures
는
navigator.gpu.
의
setlike 인터페이스입니다.
set entries는 해당 구현이 지원하는 WGSL 언어
확장의 문자열 이름입니다(어댑터, 디바이스와 관계없이).
wgslLanguageFeatures
[Exposed =(Window ,Worker ),SecureContext ]interface WGSLLanguageFeatures {readonly setlike <DOMString >; };
3.6.2.4. GPUAdapterInfo
GPUAdapterInfo
는 어댑터에 대한 다양한 식별 정보를 노출합니다.
GPUAdapterInfo
의 멤버들은 특정 값이 반드시 채워진다는 보장이 없습니다.
값이 제공되지 않으면 속성은 빈 문자열 ""
을 반환합니다. 어떤 값을 노출할지 결정하는 것은 사용자 에이전트의 재량이며,
일부 디바이스에서는 값이 전혀 채워지지 않을 수 있습니다. 따라서 애플리케이션은 모든 GPUAdapterInfo
값(값 없음 포함)을 처리할 수 있어야 합니다.
어댑터의 GPUAdapterInfo
는 GPUAdapter.info
및 GPUDevice.adapterInfo
를
통해 노출됩니다.
이 정보는 불변(immutable)입니다:
동일 어댑터에 대해 각 GPUAdapterInfo
속성은 접근할 때마다 같은 값을 반환합니다.
참고:
GPUAdapterInfo
속성은 한 번 접근하면 불변이지만, 각 속성에 대해 노출할 값을 언제 결정할지 구현체가 지연할 수 있습니다.
참고:
동일한 물리 어댑터를 나타내더라도 다른 GPUAdapter
인스턴스는 GPUAdapterInfo
에서
다른 값을 노출할 수 있습니다.
그래도 특별한 이벤트로 페이지의 식별 정보 접근 권한이 늘어난 경우가 아니라면(이 명세에서는 그런 이벤트 정의 없음) 동일한 값을 노출해야 합니다.
프라이버시 관련 내용은 § 2.2.6 어댑터 식별자를 참고하세요.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUAdapterInfo {readonly attribute DOMString vendor ;readonly attribute DOMString architecture ;readonly attribute DOMString device ;readonly attribute DOMString description ;readonly attribute unsigned long subgroupMinSize ;readonly attribute unsigned long subgroupMaxSize ;readonly attribute boolean isFallbackAdapter ; };
GPUAdapterInfo
는 다음 속성을 가집니다:
vendor
, 타입 DOMString, 읽기 전용-
어댑터의 벤더 이름(가능한 경우). 없으면 빈 문자열.
architecture
, 타입 DOMString, 읽기 전용-
어댑터가 속한 GPU 계열/클래스 이름(가능한 경우). 없으면 빈 문자열.
device
, 타입 DOMString, 읽기 전용-
어댑터에 대한 벤더별 식별자(가능한 경우). 없으면 빈 문자열.
참고: 해당 어댑터의 종류를 나타내는 값입니다. 예를 들어 PCI device ID일 수 있습니다. 특정 하드웨어(시리얼번호 등)를 고유하게 식별하지 않습니다.
description
, 타입 DOMString, 읽기 전용-
드라이버가 보고한 어댑터 설명(가능한 경우, 사람이 읽을 수 있는 문자열). 없으면 빈 문자열.
참고:
description
에는 별도의 포맷이 적용되지 않으므로 파싱 권장하지 않습니다. 드라이버 이슈 등으로 동작을 달리하는 앱은 가능하면 다른 필드를 활용해야 합니다. subgroupMinSize
, 타입 unsigned long, 읽기 전용-
"subgroups"
기능이 지원된다면, subgroup size의 최소값(해당 어댑터 기준). subgroupMaxSize
, 타입 unsigned long, 읽기 전용-
"subgroups"
기능이 지원된다면, subgroup size의 최대값(해당 어댑터 기준). isFallbackAdapter
, 타입 boolean, 읽기 전용
-
adapterInfo에
GPUAdapterInfo
새 인스턴스 할당. -
벤더가 알려져 있으면 adapterInfo.
vendor
에 adapter 벤더 이름(정규화 식별자 문자열)을 설정. 프라이버시 보호를 위해 빈 문자열 또는 유사 벤더명을 사용할 수 있음. -
아키텍처가 알려져 있으면 adapterInfo.
architecture
에 adapter가 속한 계열/클래스(정규화 식별자 문자열)를 설정. 프라이버시 보호를 위해 빈 문자열 또는 유사 아키텍처명을 사용할 수 있음. -
디바이스가 알려져 있으면 adapterInfo.
device
에 adapter 벤더별 식별자(정규화 식별자 문자열)를 설정. 프라이버시 보호를 위해 빈 문자열 또는 유사 식별자를 사용할 수 있음. -
설명이 알려져 있으면 adapterInfo.
description
에 드라이버가 보고한 설명을 설정. 프라이버시 보호를 위해 빈 문자열 또는 유사 설명을 사용할 수 있음. -
"subgroups"
기능이 지원되면subgroupMinSize
에 지원하는 최소 subgroup size를 설정. 아니면 4로 설정.참고: 프라이버시 보호를 위해 일부 기능 미지원 또는 식별 불가능한 값을 사용할 수 있음(예: 모든 디바이스에 4 사용).
-
"subgroups"
기능이 지원되면subgroupMaxSize
에 지원하는 최대 subgroup size를 설정. 아니면 128로 설정.참고: 프라이버시 보호를 위해 일부 기능 미지원 또는 식별 불가능한 값을 사용할 수 있음(예: 모든 디바이스에 128 사용).
-
adapterInfo.
isFallbackAdapter
값을 adapter.[[fallback]]
로 설정. -
adapterInfo 반환.
[a-z0-9]+(-[a-z0-9]+)*
3.7. 확장 문서
"확장 문서"는 새로운 기능을 설명하는 추가 문서로, 이는 비규범적이며 WebGPU/WGSL 명세의 일부가 아닙니다.
이러한 문서는 현행 표준을 기반으로 새로운 기능을 설명하며, 종종 하나 이상의 새로운 API 기능 플래그 및/또는 WGSL
enable
지시문, 또는 다른 웹 초안 명세와의 상호작용을 포함합니다.
WebGPU 구현체는 확장 기능을 노출해서는 안 됩니다; 그렇게 하면 명세 위반입니다. 새로운 기능은 WebGPU 표준(이 문서) 및/또는 WGSL 명세에 통합될 때까지 WebGPU 표준의 일부가 아닙니다.
3.8. 오리진 제한
WebGPU는 이미지, 비디오, 캔버스에 저장된 이미지 데이터를 접근할 수 있도록 허용합니다. 셰이더를 통해 GPU에 업로드된 텍스처의 내용을 간접적으로 추론할 수 있기 때문에, 교차 도메인 미디어 사용에는 제한이 있습니다.
WebGPU는 이미지 소스가 오리진-클린하지 않은 경우 업로드를 허용하지 않습니다.
이로 인해 WebGPU로 렌더링된 캔버스의 origin-clean 플래그는 결코 false
로 설정되지 않습니다.
이미지 및 비디오 요소에 대해 CORS 요청 발행에 대한 자세한 내용은 다음을 참고하세요:
3.9. 태스크 소스
3.9.1. WebGPU 태스크 소스
WebGPU는 태스크 소스라는 새로운 WebGPU 태스크 소스를 정의합니다.
이는 uncapturederror
이벤트 및 GPUDevice
.lost
에
사용됩니다.
GPUDevice
device에 대해, 콘텐츠
타임라인에서 일련의 단계 steps를
글로벌 태스크로 큐잉 하려면:
-
글로벌 태스크 큐잉을 WebGPU 태스크 소스에 대해, device를 생성한 글로벌 객체와 steps를 전달해 실행합니다.
3.9.2. 자동 만료 태스크 소스
WebGPU는 태스크 소스라는 새로운 자동 만료 태스크 소스를 정의합니다. 특정 객체의 자동, 시간 기반 만료(파괴)에 사용됩니다:
-
GPUTexture
가getCurrentTexture()
로 반환된 경우 -
GPUExternalTexture
가HTMLVideoElement
에서 생성된 경우
GPUDevice
device와 콘텐츠
타임라인의 단계 steps를
자동 만료 태스크로 큐잉 하려면:
-
글로벌 태스크 큐잉을 자동 만료 태스크 소스에 대해, device를 생성한 글로벌 객체와 steps를 전달해 실행합니다.
자동 만료 태스크 소스의 태스크는 높은 우선순위로 처리되어야 하며, 큐잉 후에는 사용자 정의(JavaScript) 태스크보다 먼저 실행되어야 합니다.
구현 참고: 높은 우선순위 만료 "태스크"는 실제 태스크를 실행하는 대신 이벤트 루프 처리 모델의 고정 지점에 추가 단계 삽입으로 구현해도 무방합니다.
3.10. 색 공간 및 인코딩
WebGPU는 색상 관리(color management)를 제공하지 않습니다. WebGPU 내부의 모든 값(예: 텍스처 요소)은 색상 관리가 적용된 값이 아니라, 순수 숫자 값입니다.
WebGPU는 색상 관리가 적용된 출력(GPUCanvasConfiguration
)
및 입력
(copyExternalImageToTexture()
및 importExternalTexture()
)과
인터페이스합니다.
따라서 WebGPU의 숫자 값과 외부 색상 값 사이에는 색상 변환이 필요합니다.
이러한 인터페이스 지점마다 인코딩(색 공간, 전송 함수, 알파 프리멀티플리케이션)이 개별적으로 정의되어 WebGPU의 숫자 값이 해석됩니다.
WebGPU는 PredefinedColorSpace
enum의 모든 색 공간을 허용합니다.
각 색 공간은 참조된 CSS 정의에 따라 확장 범위로 정의되므로, 색 공간 밖의 색상 값(색도 및 휘도 모두)을 표현할 수 있습니다.
가뮤트 초과
프리멀티플라이드 RGBA 값은 R/G/B 채널 값 중 하나라도 알파 채널 값을 초과하는 경우입니다. 예를 들어 프리멀티플라이드 sRGB RGBA 값 [1.0, 0, 0,
0.5]는 (비프리멀티플라이드) 색상 [2, 0, 0]에 50% 알파를 적용한 것으로, CSS에서는 rgb(srgb 2 0 0 / 50%)
로 표현됩니다.
sRGB 색 공간을 벗어난 색상 값과 마찬가지로, 이는 확장된 색 공간 내에서 잘 정의된 점입니다(알파가 0이면 색상 없음).
하지만 이러한 값이 눈에 보이는 캔버스에 출력될 경우 결과는 정의되지 않습니다
(GPUCanvasAlphaMode
"premultiplied"
참고).
3.10.1. 색 공간 변환
색상은 한 공간에서 다른 공간으로 변환할 때 위 정의에 따라 표현을 변환합니다.
소스 값에 RGBA 채널이 4개 미만일 경우, 부족한 green/blue/alpha 채널을 각각 0, 0, 1
로 설정한 뒤 색 공간/인코딩 및 알파 프리멀티플라이드 변환을
수행합니다.
변환 후 목적지에서 채널이 4개 미만일 경우, 추가 채널은 무시됩니다.
참고:
그레이스케일 이미지는 일반적으로 RGB 값 (V, V, V)
또는 RGBA 값 (V, V, V, A)
로 색 공간 내에서 표현됩니다.
색상 변환 과정에서 값이 소실(clamp)되지 않습니다: 한 색 공간에서 다른 색 공간으로 변환할 때, 소스 색 값이 목적지 색 공간의 가뮤트 범위를 벗어나면 [0, 1] 범위를 벗어난 값이 나올 수 있습니다. 예를 들어, sRGB 목적지의 경우 소스가 rgba16float이거나 더 넓은 색 공간(Display-P3 등)이거나, 프리멀티플라이드 값이 가뮤트 초과 값을 포함하는 경우 발생할 수 있습니다.
마찬가지로 소스 값이 고비트뎁스(PNG 16비트 등) 또는 확장 범위(canvas의 float16
저장 등)일 경우, 색 공간 변환을 통해 이러한 색상 값이 보존되며, 중간
계산은 소스와 동일한 정밀도를 가져야 합니다.
3.10.2. 색 공간 변환 생략
색 공간/인코딩 변환의 소스와 목적지가 동일하면 변환이 필요하지 않습니다. 일반적으로 변환 단계 중 어떤 단계가 항등 함수(no-op)라면, 구현체는 성능을 위해 이를 생략해야 합니다.
최적의 성능을 위해, 앱은 전체 과정에서 필요한 변환 횟수를 최소화할 수 있도록 색 공간 및 인코딩 옵션을 설정하는 것이 권장됩니다.
다양한 이미지 소스(GPUCopyExternalImageSourceInfo
)의
경우:
-
-
프리멀티플라이드 알파는
premultiplyAlpha
로 제어. -
색 공간은
colorSpaceConversion
으로 제어.
-
-
2d 캔버스:
-
색 공간은
colorSpace
컨텍스트 생성 속성으로 제어.
-
WebGL 캔버스:
-
프리멀티플라이드 알파는
premultipliedAlpha
옵션(WebGLContextAttributes
)으로 제어. -
색 공간은
WebGLRenderingContextBase
의drawingBufferColorSpace
상태로 제어.
-
참고: 이러한 기능에 의존하기 전에 브라우저 구현 지원 여부를 확인하세요.
3.11. JavaScript에서 WGSL로의 숫자 변환
WebGPU API의 여러 부분(pipeline-overridable constants
및
렌더 패스 clear 값)은 WebIDL(double
또는 float
)
타입의 숫자 값을 받아
WGSL 값(bool
, i32
, u32
, f32
,
f16
)으로 변환합니다.
double
또는 float
일
때,
WGSL
타입 T로 변환하려면,
TypeError
가
발생할 수 있으며,
아래 디바이스 타임라인 단계를 실행합니다:
참고: 이 TypeError
는 디바이스 타임라인에서 생성되며,
JavaScript에는 전달되지 않습니다.
-
assert idlValue가 유한한 값인지 확인합니다. 이는
unrestricted double
또는unrestricted float
가 아니기 때문입니다. -
v는 ! idlValue를 ECMAScript 값으로 변환한 결과의 ECMAScript Number입니다.
-
- 만약 T가
bool
이면 -
! v를 타입
boolean
의 IDL 값으로 변환한 결과에 해당하는 WGSLbool
값을 반환합니다.참고: 이 알고리즘은 ECMAScript 값을 IDL
double
또는float
로 변환한 뒤 호출됩니다. 만약 원래 ECMAScript 값이 숫자나 불리언이 아닌[]
또는{}
였다면, WGSLbool
결과는 ECMAScript 값을 직접 boolean으로 변환한 결과와 다를 수 있습니다. - 만약 T가
i32
이면 -
? v를 [
EnforceRange
]long
타입의 IDL 값으로 변환한 결과에 해당하는 WGSLi32
값을 반환합니다. - 만약 T가
u32
이면 -
? v를 [
EnforceRange
]unsigned long
타입의 IDL 값으로 변환한 결과에 해당하는 WGSLu32
값을 반환합니다. - 만약 T가
f32
이면 - 만약 T가
f16
이면 -
-
wgslF32를 ? v를
float
타입의 IDL 값으로 변환한 결과에 해당하는 WGSLf32
값으로 둡니다. -
f16(wgslF32)
를 반환합니다. 이는 WGSLf32
값을f16
으로 변환하는 규칙(WGSL 부동소수점 변환)을 따릅니다.
참고: 값이
f32
범위 내라면 오류가 발생하지 않으며,f16
범위를 벗어나도 오류 없이 변환됩니다. -
- 만약 T가
GPUColor
타입의 color를 텍스처 포맷의 텍셀 값 format으로 변환하려면,
TypeError
가
발생할 수 있으며,
아래 디바이스 타임라인 단계를 실행합니다:
참고: 이 TypeError
는 디바이스 타임라인에서 생성되며,
JavaScript에는 전달되지 않습니다.
-
format의 컴포넌트 타입이(assert로 모두 같은 타입임을 보장):
- 부동소수점 또는 정규화 타입
-
T를
f32
로 둡니다. - 부호 있는 정수 타입
-
T를
i32
로 둡니다. - 부호 없는 정수 타입
-
T를
u32
로 둡니다.
-
wgslColor를 타입
vec4<T>
의 WGSL 값으로, RGBA 채널 각각을 ? 변환(WGSL 타입 T 변환)한 값으로 설정합니다. -
wgslColor를 format에 맞게 § 23.2.7 출력 머지(Output Merging) 단계와 동일한 변환 규칙을 적용해 변환 후 반환합니다.
참고: 정수 타입이 아니라면, 구체적인 값 선택은 구현체 정의입니다. 정규화 타입의 경우 값은 타입의 범위로 강제(clamp)됩니다.
참고:
즉, 작성되는 값은 WGSL 셰이더가 vec4
의 f32
, i32
, u32
로 출력한 것과
동일하게 동작합니다.
4. 초기화
4.1. navigator.gpu
GPU
객체는 Window
및 WorkerGlobalScope
컨텍스트에서
Navigator
및 WorkerNavigator
인터페이스를 통해 노출되며 navigator.gpu
로 접근할 수 있습니다:
interface mixin { [
NavigatorGPU SameObject ,SecureContext ]readonly attribute GPU gpu ; };Navigator includes NavigatorGPU ;WorkerNavigator includes NavigatorGPU ;
NavigatorGPU
는 다음 속성을 가집니다:
gpu
, 타입 GPU, 읽기 전용-
글로벌 싱글톤 객체로,
requestAdapter()
등 최상위 진입점을 제공합니다.
4.2. GPU
GPU
는
WebGPU의 진입점입니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPU {Promise <GPUAdapter ?>requestAdapter (optional GPURequestAdapterOptions options = {});GPUTextureFormat getPreferredCanvasFormat (); [SameObject ]readonly attribute WGSLLanguageFeatures wgslLanguageFeatures ; };
GPU
는 다음 메서드를 가집니다:
requestAdapter(options)
-
사용자 에이전트에서 어댑터를 요청합니다. 사용자 에이전트는 어댑터를 반환할지, 반환한다면 옵션에 따라 선택합니다.
호출 대상:GPU
this.인자:
GPU.requestAdapter(options) 메서드 인자. 파라미터 타입 Nullable Optional 설명 options
GPURequestAdapterOptions
✘ ✔ 어댑터 선택 기준. 반환값:
Promise
<GPUAdapter
?>콘텐츠 타임라인 단계:
디바이스 타임라인 initialization steps:-
아래 단계의 모든 요구사항을 반드시 만족해야 합니다.
-
options.
featureLevel
반드시 feature level string이어야 합니다.
만족하고 사용자 에이전트가 어댑터를 반환하기로 결정한 경우:
-
adapter를 어댑터로 설정하며, § 4.2.2 어댑터 선택 규칙과 options 기준에 따라 선택. § 4.2.1 어댑터 기능 보장 준수. adapter의 속성은 정의에 따라 초기화:
-
adapter.
[[limits]]
및 adapter.[[features]]
를 해당 어댑터의 지원 기능으로 설정. adapter.[[features]]
는"core-features-and-limits"
를 포함해야 함. -
adapter가 폴백 어댑터 기준을 만족하면 adapter.
[[fallback]]
을true
로, 아니면false
로 설정. -
adapter.
[[xrCompatible]]
값을 options.xrCompatible
로 설정.
-
그렇지 않으면:
-
adapter를
null
로 둡니다.
-
-
이후 단계는 contentTimeline에서 실행.
콘텐츠 타임라인 단계:-
adapter가
null
이 아니면:-
resolve promise를
GPUAdapter
새 객체(내부적으로 adapter 캡슐화)로 설정.
-
-
그렇지 않으면 resolve promise를
null
로 설정.
-
getPreferredCanvasFormat()
-
이 시스템에서 8비트 깊이, 표준 다이나믹 레인지 콘텐츠를 표시하기에 최적의
GPUTextureFormat
을 반환합니다. 반드시"rgba8unorm"
또는"bgra8unorm"
만 반환해야 합니다.반환된 값은
format
으로configure()
호출 시 전달하여, 연관된GPUCanvasContext
캔버스가 효율적으로 내용을 표시할 수 있도록 할 수 있습니다.참고: 화면에 표시되지 않는 캔버스는 이 포맷을 사용해도 이점이 없을 수 있습니다.
호출 대상:GPU
this.반환값:
GPUTextureFormat
콘텐츠 타임라인 단계:
-
WebGPU 캔버스 표시에 최적인 포맷을 선택하여
"rgba8unorm"
또는"bgra8unorm"
반환.
-
GPU
는 다음 속성을 가집니다:
wgslLanguageFeatures
, 타입 WGSLLanguageFeatures, 읽기 전용-
지원되는 WGSL 언어 확장 이름. 지원되는 언어 확장은 자동으로 활성화됩니다.
어댑터는 언제든지 만료될 수
있습니다. 시스템 상태가 변경되어 requestAdapter()
호출 결과에 영향을 줄 수 있을 때, 사용자 에이전트는 이전에 반환된 어댑터를 만료해야 합니다. 예:
-
물리 어댑터가 추가/제거됨(플러그/언플러그, 드라이버 업데이트, 행 복구 등)
-
시스템 전원 구성 변경(노트북 분리, 전원 설정 변경 등)
참고:
사용자 에이전트는 시스템 상태가 변경되지 않아도 어댑터를 자주 만료할 수 있습니다(예: 생성 후 몇 초 또는 몇 분 후).
이는 실제 시스템 상태 변화를 감추고, requestAdapter()
를 다시 호출하는 것이 항상 필요하다는 점을 개발자에게 더 잘 인식시키는 데 도움이 됩니다.
만약 애플리케이션에서 이런 상황을 만나면, 표준 디바이스 손실 복구 처리를 통해 회복할 수 있습니다.
4.2.1. 어댑터 기능 보장
GPUAdapter
객체가 requestAdapter()
로 반환될 때는 아래 보장을 제공해야 합니다:
-
다음 중 하나 이상이 반드시 참이어야 합니다:
-
"texture-compression-bc"
기능을 지원함. -
"texture-compression-etc2"
및"texture-compression-astc"
기능 모두 지원함.
-
-
"texture-compression-bc-sliced-3d"
를 지원하는 경우,"texture-compression-bc"
도 지원해야 합니다. -
"texture-compression-astc-sliced-3d"
를 지원하는 경우,"texture-compression-astc"
도 지원해야 합니다. -
모든 정렬 클래스 한계값은 2의 거듭제곱이어야 합니다.
-
maxBindingsPerBindGroup
값은 반드시 (max bindings per shader stage × 파이프라인당 최대 셰이더 스테이지 수) 이상이어야 하며, 여기서:-
max bindings per shader stage는 (
maxSampledTexturesPerShaderStage
+maxSamplersPerShaderStage
+maxStorageBuffersPerShaderStage
+maxStorageTexturesPerShaderStage
+maxUniformBuffersPerShaderStage
) 의 합입니다. -
파이프라인당 최대 셰이더 스테이지 수는
2
입니다.GPURenderPipeline
은 버텍스/프래그먼트 셰이더 모두 지원하므로.
참고:
maxBindingsPerBindGroup
값은 근본적인 한계를 반영하는 것이 아니므로, 구현체는 이 요구사항을 만족하기 위해 해당 값을 올려야 하며, 다른 한계값을 낮추는 방식은 허용되지 않습니다. -
-
maxBindGroups
값은maxBindGroupsPlusVertexBuffers
이하이어야 합니다. -
maxVertexBuffers
값은maxBindGroupsPlusVertexBuffers
이하이어야 합니다. -
minUniformBufferOffsetAlignment
와minStorageBufferOffsetAlignment
값은 모두 32바이트 이상이어야 합니다.참고: 32바이트는
vec4<f64>
의 정렬값입니다. WebGPU Shading Language § 14.4.1 정렬 및 크기 참고. -
maxUniformBufferBindingSize
값은maxBufferSize
이하이어야 합니다. -
maxStorageBufferBindingSize
값은maxBufferSize
이하이어야 합니다. -
maxStorageBufferBindingSize
값은 4바이트의 배수여야 합니다. -
maxVertexBufferArrayStride
값은 4바이트의 배수여야 합니다. -
maxComputeWorkgroupSizeX
값은maxComputeInvocationsPerWorkgroup
이하이어야 합니다. -
maxComputeWorkgroupSizeY
값은maxComputeInvocationsPerWorkgroup
이하이어야 합니다. -
maxComputeWorkgroupSizeZ
값은maxComputeInvocationsPerWorkgroup
이하이어야 합니다. -
maxComputeInvocationsPerWorkgroup
값은maxComputeWorkgroupSizeX
×maxComputeWorkgroupSizeY
×maxComputeWorkgroupSizeZ
이하이어야 합니다.
4.2.2. 어댑터 선택
GPURequestAdapterOptions
는 사용자 에이전트에게 앱에 적합한 구성을 힌트로 제공합니다.
dictionary GPURequestAdapterOptions {DOMString featureLevel = "core";GPUPowerPreference powerPreference ;boolean forceFallbackAdapter =false ;boolean xrCompatible =false ; };
enum {
GPUPowerPreference "low-power" ,"high-performance" , };
GPURequestAdapterOptions
는 아래 멤버를 가집니다:
featureLevel
, 타입 DOMString, 기본값"core"
-
어댑터 요청의 "feature level"입니다.
허용되는 feature level string 값:
- "core"
-
영향 없음.
- "compatibility"
-
영향 없음.
참고: 이 값은 향후 추가 검증 제한을 선택적으로 적용하기 위한 예약 값입니다. 현재는 사용하지 않아야 합니다.
powerPreference
, 타입 GPUPowerPreference-
시스템의 사용 가능한 어댑터 중 어떤 클래스가 선택되어야 하는지 힌트를 제공합니다.
이 힌트 값은 어떤 어댑터가 선택되는지에 영향을 줄 수 있지만, 어댑터가 반환되는지 여부에는 영향을 주지 않습니다.
참고: 이 힌트의 주요 용도는 멀티 GPU 시스템에서 어떤 GPU를 사용할지 결정하는 것입니다. 예를 들어, 일부 노트북에는 저전력 내장 GPU와 고성능 외장 GPU가 있습니다. 이 힌트는 선택된 GPU의 전원 구성에도 영향을 줄 수 있습니다.
참고: 배터리 상태, 연결된 디스플레이, 착탈식 GPU 등 하드웨어 구성에 따라 동일한 powerPreference여도 다른 어댑터가 선택될 수 있습니다. 일반적으로 동일한 하드웨어 구성 및 상태,
powerPreference
라면 동일 어댑터가 선택될 가능성이 높습니다.다음 값 중 하나여야 합니다:
undefined
(또는 미지정)-
사용자 에이전트에 힌트를 제공하지 않습니다.
"low-power"
-
성능보다 전력 절약을 우선하도록 요청합니다.
참고: 일반적으로 초당 1프레임만 렌더링하거나, 단순한 지오메트리/셰이더만 사용하는 콘텐츠, 작은 HTML 캔버스 등을 사용할 경우 이에 적합합니다. 가능하면 이 값을 사용하면 휴대기기의 배터리 수명에 큰 도움이 될 수 있습니다.
"high-performance"
-
전력 소모보다 성능을 우선하도록 요청합니다.
참고: 이 값을 선택하면, 해당 어댑터에서 생성한 디바이스가 전력 절약을 위해 저전력 어댑터로 전환되면서 강제로 디바이스 손실(device loss)이 발생할 수 있습니다. 정말 필요하다고 판단될 때만 이 값을 지정해야 하며, 휴대기기에서 배터리 수명이 크게 감소할 수 있습니다.
forceFallbackAdapter
, 타입 boolean, 기본값false
-
true
이면 폴백 어댑터만 반환될 수 있습니다. 사용자 에이전트가 폴백 어댑터를 지원하지 않으면requestAdapter()
는null
로 resolve됩니다.참고:
requestAdapter()
는forceFallbackAdapter
가false
일 때도, 적합한 어댑터가 없거나 사용자 에이전트가 폴백 어댑터 반환을 선택하면 폴백 어댑터를 반환할 수 있습니다. 폴백 어댑터에서 실행을 막으려면info
.isFallbackAdapter
속성을 확인한 후GPUDevice
를 요청해야 합니다. xrCompatible
, 타입 boolean, 기본값false
-
true
로 설정하면 WebXR 세션 렌더링에 가장 적합한 어댑터를 반환해야 함을 의미합니다. 사용자 에이전트나 시스템이 WebXR 세션을 지원하지 않는 경우, 어댑터 선택 시 이 값을 무시할 수 있습니다.참고: 어댑터를 요청할 때
xrCompatible
가true
로 설정되지 않으면, 해당 어댑터에서 생성한GPUDevice
는 WebXR 세션 렌더링에 사용할 수 없습니다.
"high-performance"
GPUAdapter
를
요청하는 예시:
const gpuAdapter= await navigator. gpu. requestAdapter({ powerPreference: 'high-performance' });
4.3. GPUAdapter
GPUAdapter
는 어댑터를 캡슐화하며,
해당 기능 및 한계 등 기능을 설명합니다.
GPUAdapter
를 얻으려면 requestAdapter()
를 사용하세요.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUAdapter { [SameObject ]readonly attribute GPUSupportedFeatures features ; [SameObject ]readonly attribute GPUSupportedLimits limits ; [SameObject ]readonly attribute GPUAdapterInfo info ;Promise <GPUDevice >requestDevice (optional GPUDeviceDescriptor descriptor = {}); };
GPUAdapter
는 다음 불변 속성을 가집니다.
features
, 타입 GPUSupportedFeatures, 읽기 전용-
this
.[[adapter]]
.[[features]]
값의 집합입니다. limits
, 타입 GPUSupportedLimits, 읽기 전용-
this
.[[adapter]]
.[[limits]]
값입니다. info
, 타입 GPUAdapterInfo, 읽기 전용-
이
GPUAdapter
가 참조하는 물리적 어댑터 정보입니다.동일한
GPUAdapter
에 대해GPUAdapterInfo
값은 시간이 지나도 변하지 않습니다.항상 동일 객체를 반환합니다. 처음 객체를 만들 때:
호출 대상:GPUAdapter
this.반환값:
GPUAdapterInfo
콘텐츠 타임라인 단계:
-
this.
[[adapter]]
에 대해 새 adapter info를 반환합니다.
-
[[adapter]]
, 타입 adapter, 읽기 전용-
이
GPUAdapter
가 참조하는 어댑터입니다.
GPUAdapter
는 다음 메서드를 가집니다:
requestDevice(descriptor)
-
이 작업은 1회성입니다: 디바이스가 성공적으로 반환되면 어댑터는
"consumed"
상태가 됩니다.호출 대상:GPUAdapter
this.인자:
GPUAdapter.requestDevice(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUDeviceDescriptor
✘ ✔ 요청할 GPUDevice
의 설명.콘텐츠 타임라인 단계:
-
contentTimeline을 현재 콘텐츠 타임라인으로 둡니다.
-
promise를 새 promise로 둡니다.
-
adapter를 this.
[[adapter]]
로 둡니다. -
initialization steps를 this의 디바이스 타임라인에서 실행합니다.
-
promise를 반환합니다.
디바이스 타임라인 initialization steps:-
아래 요구사항 중 하나라도 만족하지 않으면:
-
descriptor.
requiredFeatures
의 값 집합이 adapter.[[features]]
의 부분집합이어야 합니다.
만족하지 않으면 contentTimeline에서 아래 단계 실행 후 반환:
참고: 브라우저에서 해당 기능명을 전혀 모를 때도 동일 오류가 발생합니다(
GPUFeatureName
정의에 없음). 브라우저가 기능을 지원하지 않는 경우와 특정 어댑터가 지원하지 않는 경우의 동작을 일치시킵니다. -
-
아래 단계 요구사항을 반드시 만족해야 합니다.
-
adapter.
[[state]]
값이"consumed"
가 아니어야 합니다. -
descriptor.
requiredLimits
의 각 [key, value] 쌍에서 value가undefined
가 아닌 경우:-
key는 지원 한계의 멤버 이름이어야 합니다.
-
value는 adapter.
[[limits]]
[key]보다 더 나은 값이 아니어야 합니다.
참고: key가 인식되지 않더라도 value가
undefined
면 개발자 가시 경고를 주는 것이 좋습니다. -
만족하지 않으면 contentTimeline에서 아래 단계 실행 후 반환:
콘텐츠 타임라인 단계:-
promise를
OperationError
로 reject.
-
-
adapter.
[[state]]
값이"expired"
이거나 사용자 에이전트가 요청을 처리할 수 없는 경우:-
새 디바이스를 device로 둡니다.
-
디바이스 손실 처리(device,
"unknown"
). -
assert adapter.
[[state]]
값이"expired"
임을 확인.참고: 이런 경우 개발자 가시 경고를 대부분(또는 모든 경우) 주는 것이 좋습니다. 앱은
requestAdapter()
로부터 재초기화 로직을 수행해야 합니다.
그렇지 않으면:
-
-
이후 단계는 contentTimeline에서 실행.
콘텐츠 타임라인 단계:-
새
GPUDevice
인스턴스를 gpuDevice로 둡니다. -
gpuDevice.
[[device]]
값을 device로 설정. -
device.
[[content device]]
값을 gpuDevice로 설정. -
resolve promise를 gpuDevice로 설정.
참고: 어댑터가 요청을 처리할 수 없어 이미 디바이스가 손실된 경우, device.
lost
는 promise가 resolve되기 전에 이미 resolve됩니다.
-
GPUDevice
요청
예시:
const gpuAdapter= await navigator. gpu. requestAdapter(); const gpuDevice= await gpuAdapter. requestDevice();
4.3.1. GPUDeviceDescriptor
GPUDeviceDescriptor
는 디바이스 요청을 기술합니다.
dictionary GPUDeviceDescriptor :GPUObjectDescriptorBase {sequence <GPUFeatureName >requiredFeatures = [];record <DOMString , (GPUSize64 or undefined )>requiredLimits = {};GPUQueueDescriptor defaultQueue = {}; };
GPUDeviceDescriptor
는 다음 멤버를 가집니다:
requiredFeatures
, 타입 sequence<GPUFeatureName>, 기본값[]
-
디바이스 요청에 반드시 필요한 기능을 지정합니다. 어댑터가 해당 기능을 제공할 수 없으면 요청은 실패합니다.
API 호출 검증 시 결과 디바이스에 대해 정확히 명시된 기능 집합만 허용되며, 그 외는 허용되지 않습니다.
requiredLimits
, 타입record<DOMString, (GPUSize64 or undefined)>
, 기본값{}
-
디바이스 요청에 반드시 필요한 한계를 지정합니다. 어댑터가 해당 한계를 제공할 수 없으면 요청은 실패합니다.
값이
undefined
가 아닌 각 키는 지원 한계의 멤버 이름이어야 합니다.결과 디바이스에서의 API 호출은 어댑터가 아니라 디바이스의 정확한 한계에 따라 검증됩니다(§ 3.6.2 한계 참고).
defaultQueue
, 타입 GPUQueueDescriptor, 기본값{}
-
기본
GPUQueue
의 디스크립터.
"texture-compression-astc"
기능을 지원하는 경우, 해당 기능을 포함해 GPUDevice
를
요청하는 예시:
const gpuAdapter= await navigator. gpu. requestAdapter(); const requiredFeatures= []; if ( gpuAdapter. features. has( 'texture-compression-astc' )) { requiredFeatures. push( 'texture-compression-astc' ) } const gpuDevice= await gpuAdapter. requestDevice({ requiredFeatures});
maxColorAttachmentBytesPerSample
한계를 지정해 GPUDevice
를
요청하는 예시:
const gpuAdapter= await navigator. gpu. requestAdapter(); if ( gpuAdapter. limits. maxColorAttachmentBytesPerSample< 64 ) { // 원하는 한계가 지원되지 않을 경우, 더 높은 한계를 요구하지 않는 코드 경로로 대체하거나 // 최소 요구사항에 미달하는 디바이스임을 사용자에게 안내하는 등의 처리를 할 수 있습니다. } // max color attachments bytes per sample 한계 상향 요청. const gpuDevice= await gpuAdapter. requestDevice({ requiredLimits: { maxColorAttachmentBytesPerSample: 64 }, });
4.3.1.1. GPUFeatureName
각 GPUFeatureName
은 특정 기능 집합을 식별하며,
해당 기능이 지원될 경우 기존 WebGPU에서 불가능한 추가 사용이 가능합니다.
enum GPUFeatureName {"core-features-and-limits" ,"depth-clip-control" ,"depth32float-stencil8" ,"texture-compression-bc" ,"texture-compression-bc-sliced-3d" ,"texture-compression-etc2" ,"texture-compression-astc" ,"texture-compression-astc-sliced-3d" ,"timestamp-query" ,"indirect-first-instance" ,"shader-f16" ,"rg11b10ufloat-renderable" ,"bgra8unorm-storage" ,"float32-filterable" ,"float32-blendable" ,"clip-distances" ,"dual-source-blending" ,"subgroups" ,"texture-formats-tier1" ,"texture-formats-tier2" ,"primitive-index" , };
4.4. GPUDevice
GPUDevice
는 디바이스를 캡슐화하며,
해당 디바이스의 기능을 노출합니다.
GPUDevice
는
WebGPU 인터페이스가 생성되는 최상위
인터페이스입니다.
GPUDevice
를
얻으려면
requestDevice()
를 사용하세요.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUDevice :EventTarget { [SameObject ]readonly attribute GPUSupportedFeatures features ; [SameObject ]readonly attribute GPUSupportedLimits limits ; [SameObject ]readonly attribute GPUAdapterInfo adapterInfo ; [SameObject ]readonly attribute GPUQueue queue ;undefined destroy ();GPUBuffer createBuffer (GPUBufferDescriptor descriptor );GPUTexture createTexture (GPUTextureDescriptor descriptor );GPUSampler createSampler (optional GPUSamplerDescriptor descriptor = {});GPUExternalTexture importExternalTexture (GPUExternalTextureDescriptor descriptor );GPUBindGroupLayout createBindGroupLayout (GPUBindGroupLayoutDescriptor descriptor );GPUPipelineLayout createPipelineLayout (GPUPipelineLayoutDescriptor descriptor );GPUBindGroup createBindGroup (GPUBindGroupDescriptor descriptor );GPUShaderModule createShaderModule (GPUShaderModuleDescriptor descriptor );GPUComputePipeline createComputePipeline (GPUComputePipelineDescriptor descriptor );GPURenderPipeline createRenderPipeline (GPURenderPipelineDescriptor descriptor );Promise <GPUComputePipeline >createComputePipelineAsync (GPUComputePipelineDescriptor descriptor );Promise <GPURenderPipeline >createRenderPipelineAsync (GPURenderPipelineDescriptor descriptor );GPUCommandEncoder createCommandEncoder (optional GPUCommandEncoderDescriptor descriptor = {});GPURenderBundleEncoder createRenderBundleEncoder (GPURenderBundleEncoderDescriptor descriptor );GPUQuerySet createQuerySet (GPUQuerySetDescriptor descriptor ); };GPUDevice includes GPUObjectBase ;
features
, 타입 GPUSupportedFeatures, 읽기 전용-
이 디바이스가 지원하는
GPUFeatureName
값의 집합 ([[device]]
.[[features]]
). limits
, 타입 GPUSupportedLimits, 읽기 전용-
이 디바이스가 지원하는 한계 (
[[device]]
.[[limits]]
). queue
, 타입 GPUQueue, 읽기 전용-
이 디바이스의 기본
GPUQueue
입니다. adapterInfo
, 타입 GPUAdapterInfo, 읽기 전용-
이
GPUDevice
가 참조하는 디바이스를 생성한 물리 어댑터 정보입니다.동일
GPUDevice
에 대해,GPUAdapterInfo
값은 시간이 지나도 변하지 않습니다.항상 동일 객체를 반환합니다. 처음 객체를 만들 때:
호출 대상:GPUDevice
this.반환값:
GPUAdapterInfo
콘텐츠 타임라인 단계:
-
this.
[[device]]
.[[adapter]]
에 대해 새 adapter info를 반환합니다.
-
[[device]]
는
GPUDevice
가
참조하는 디바이스입니다.
GPUDevice
는 다음
메서드를 가집니다:
destroy()
-
이 디바이스를 파괴하여 더 이상 작업할 수 없게 합니다. 남아있는 비동기 작업은 모두 실패합니다.
참고: 디바이스를 여러 번 파괴해도 문제가 없습니다.
-
디바이스 손실 처리(this.
[[device]]
,"destroyed"
).
참고: 더 이상 작업을 큐잉할 수 없으므로, 구현체는 남아있는 비동기 작업을 즉시 중단하고, 매핑 해제된 메모리를 포함하여 자원을 해제할 수 있습니다.
-
GPUDevice
의
허용된 버퍼 용도는 아래와
같습니다:
GPUDevice
의
허용된 텍스처 용도는 아래와
같습니다:
-
항상 허용됨:
COPY_SRC
,COPY_DST
,TEXTURE_BINDING
,STORAGE_BINDING
,RENDER_ATTACHMENT
4.5. 예시
GPUAdapter
및
GPUDevice
요청의 좀 더 견고한 예시:
let gpuDevice= null ; async function initializeWebGPU() { // 사용자 에이전트가 WebGPU를 지원하는지 확인. if ( ! ( 'gpu' in navigator)) { console. error( "사용자 에이전트가 WebGPU를 지원하지 않습니다." ); return false ; } // 어댑터 요청. const gpuAdapter= await navigator. gpu. requestAdapter(); // requestAdapter는 적합한 어댑터가 없으면 null로 resolve될 수 있음. if ( ! gpuAdapter) { console. error( 'WebGPU 어댑터를 찾을 수 없습니다.' ); return false ; } // 디바이스 요청. // 옵션 딕셔너리에 잘못된 값이 들어가면 promise가 reject될 수 있음. // 항상 어댑터의 feature와 limit을 확인한 후 requestDevice()를 호출하면 reject를 피할 수 있음. gpuDevice= await gpuAdapter. requestDevice(); // requestDevice는 절대 null을 반환하지 않지만, 유효한 디바이스 요청을 충족할 수 없으면 이미 손실된 디바이스가 반환될 수 있음. // 또한 디바이스는 생성 후 여러 이유(브라우저 리소스 관리, 드라이버 업데이트 등)로 언제든 손실될 수 있으므로 // 디바이스 손실을 항상 우아하게 처리하는 것이 좋음. gpuDevice. lost. then(( info) => { console. error( `WebGPU 디바이스가 손실됨: ${ info. message} ` ); gpuDevice= null ; // 디바이스 손실의 많은 원인은 일시적이므로, 앱은 이전 디바이스가 손실되면 새 디바이스를 다시 요청해야 함. // 단, 손실 이유가 앱에서 디바이스를 직접 destroy한 경우는 제외. 이전 디바이스로 생성한 모든 WebGPU 리소스(버퍼, 텍스처 등)는 // 새 디바이스로 재생성해야 함. if ( info. reason!= 'destroyed' ) { initializeWebGPU(); } }); onWebGPUInitialized(); return true ; } function onWebGPUInitialized() { // 여기서 WebGPU 리소스 생성 시작... } initializeWebGPU();
5. 버퍼
5.1. GPUBuffer
GPUBuffer
는 GPU 연산에 사용할 수 있는 메모리 블록을 나타냅니다.
데이터는 선형 레이아웃으로 저장되며, 할당된 각 바이트는 GPUBuffer
의 시작
오프셋 기준으로 접근할 수 있습니다.
연산에 따라 정렬 제한이 있을 수 있습니다. 일부 GPUBuffers
는
매핑되어 해당 메모리 블록을 ArrayBuffer
(매핑)로 접근할 수 있습니다.
GPUBuffer
는
createBuffer()
로 생성합니다.
버퍼는 mappedAtCreation
으로 생성할 수 있습니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUBuffer {readonly attribute GPUSize64Out size ;readonly attribute GPUFlagsConstant usage ;readonly attribute GPUBufferMapState mapState ;Promise <undefined >mapAsync (GPUMapModeFlags mode ,optional GPUSize64 offset = 0,optional GPUSize64 size );ArrayBuffer getMappedRange (optional GPUSize64 offset = 0,optional GPUSize64 size );undefined unmap ();undefined destroy (); };GPUBuffer includes GPUObjectBase ;enum GPUBufferMapState {"unmapped" ,"pending" ,"mapped" , };
size
, 타입 GPUSize64Out, 읽기 전용-
GPUBuffer
에 할당된 바이트 단위 길이입니다. usage
, 타입 GPUFlagsConstant, 읽기 전용-
이
GPUBuffer
에서 허용된 용도.
GPUBuffer
는 다음
콘텐츠 타임라인
속성을 가집니다:
mapState
, 타입 GPUBufferMapState, 읽기 전용-
버퍼의 현재
GPUBufferMapState
상태:"unmapped"
-
버퍼가
this
.getMappedRange()
로 매핑되어 있지 않음. "pending"
-
버퍼 매핑이 요청되었으나 대기 중.
mapAsync()
에서 검증에 성공하거나 실패할 수 있음. "mapped"
-
버퍼가 매핑되어
this
.getMappedRange()
를 사용할 수 있음.
getter 단계는 아래와 같습니다:
콘텐츠 타임라인 단계:-
this.
[[mapping]]
이null
이 아니면"mapped"
반환. -
this.
[[pending_map]]
이null
이 아니면"pending"
반환. -
"unmapped"
반환.
[[pending_map]]
, 타입Promise
<void> 또는null
, 초기값null
-
현재 대기 중인
Promise
,mapAsync()
의 반환값.항상 pending map은 하나만 있을 수 있습니다. 이미 요청이 진행 중이면
mapAsync()
는 즉시 거부됩니다. [[mapping]]
, 타입 active buffer mapping 또는null
, 초기값null
-
버퍼가
getMappedRange()
로 매핑되어 있을 때만 설정됨. 그렇지 않으면null
([[pending_map]]
가 있어도).active buffer mapping은 다음 필드가 있는 구조체입니다:
- data, 타입 Data Block
-
이
GPUBuffer
의 매핑 데이터.ArrayBuffer
뷰로 접근하며,getMappedRange()
로 반환되고, views에 저장됩니다. - mode, 타입
GPUMapModeFlags
-
매핑 모드(
GPUMapModeFlags
),mapAsync()
또는createBuffer()
호출 시 지정. - range, 타입 튜플 [
unsigned long long
,unsigned long long
] -
매핑된
GPUBuffer
범위. - views, 타입 list<
ArrayBuffer
> -
API에서
ArrayBuffer
로 반환된 매핑 데이터.getMappedRange()
로 반환됨.unmap()
호출 시 분리(detach)됨.
active buffer mapping 초기화를 mode mode와 range range로 하려면, 아래 콘텐츠 타임라인 단계 실행:-
size를 range[1] - range[0]로 둡니다.
-
data를 ? CreateByteDataBlock(size)로 둡니다.
참고:이 할당은RangeError
를 발생시킬 수 있습니다. 일관성/예측성을 위해:-
어떤 size에서
new ArrayBuffer()
가 성공한다면, 이 할당도 그때 성공해야 합니다. -
어떤 size에서
new ArrayBuffer()
가RangeError
를 결정적으로 던지면, 이 할당도 동일하게 던져야 합니다.
-
-
아래 값으로 active buffer mapping 반환:
GPUBuffer
는 다음
디바이스 타임라인
속성을 가집니다:
[[internal state]]
-
버퍼의 현재 내부 상태:
5.1.1. GPUBufferDescriptor
dictionary GPUBufferDescriptor :GPUObjectDescriptorBase {required GPUSize64 size ;required GPUBufferUsageFlags usage ;boolean mappedAtCreation =false ; };
GPUBufferDescriptor
는 다음 멤버를 가집니다:
size
, 타입 GPUSize64-
버퍼의 크기(바이트 단위).
usage
, 타입 GPUBufferUsageFlags-
버퍼의 허용된 용도.
mappedAtCreation
, 타입 boolean, 기본값false
-
true
로 설정하면 버퍼가 생성 즉시 매핑된 상태로 생성되어,getMappedRange()
를 바로 호출할 수 있습니다.usage
에MAP_READ
또는MAP_WRITE
가 없어도mappedAtCreation
을true
로 설정할 수 있습니다. 이는 버퍼의 초기 데이터를 설정할 때 사용할 수 있습니다.버퍼 생성이 결국 실패하더라도, unmapped될 때까지는 매핑된 범위에 읽기/쓰기가 가능한 것처럼 동작함을 보장합니다.
5.1.2. 버퍼 용도
typedef [EnforceRange ]unsigned long ; [
GPUBufferUsageFlags Exposed =(Window ,Worker ),SecureContext ]namespace {
GPUBufferUsage const GPUFlagsConstant MAP_READ = 0x0001;const GPUFlagsConstant MAP_WRITE = 0x0002;const GPUFlagsConstant COPY_SRC = 0x0004;const GPUFlagsConstant COPY_DST = 0x0008;const GPUFlagsConstant INDEX = 0x0010;const GPUFlagsConstant VERTEX = 0x0020;const GPUFlagsConstant UNIFORM = 0x0040;const GPUFlagsConstant STORAGE = 0x0080;const GPUFlagsConstant INDIRECT = 0x0100;const GPUFlagsConstant QUERY_RESOLVE = 0x0200; };
GPUBufferUsage
플래그는 GPUBuffer
가 생성
후 어떻게 사용될 수 있는지 결정합니다:
MAP_READ
-
버퍼를 읽기용으로 매핑할 수 있음. (예:
mapAsync()
를GPUMapMode.READ
와 함께 호출)COPY_DST
와만 결합 가능. MAP_WRITE
-
버퍼를 쓰기용으로 매핑할 수 있음. (예:
mapAsync()
를GPUMapMode.WRITE
와 함께 호출)COPY_SRC
와만 결합 가능. COPY_SRC
-
버퍼를 복사 연산의 소스로 사용 가능. (예: copyBufferToBuffer()나
copyBufferToTexture()
호출 시 source로 사용) COPY_DST
-
버퍼를 복사/쓰기 연산의 대상으로 사용 가능. (예: copyBufferToBuffer()나
copyTextureToBuffer()
호출 시 destination으로 사용, 또는writeBuffer()
의 대상 등) INDEX
-
버퍼를 인덱스 버퍼로 사용 가능. (예:
setIndexBuffer()
에 전달) VERTEX
-
버퍼를 버텍스 버퍼로 사용 가능. (예:
setVertexBuffer()
에 전달) UNIFORM
-
버퍼를 유니폼 버퍼로 사용 가능. (예:
GPUBufferBindingLayout
의buffer
.type
값이"uniform"
인 경우 등) STORAGE
-
버퍼를 스토리지 버퍼로 사용 가능. (예:
GPUBufferBindingLayout
의buffer
.type
값이"storage"
또는"read-only-storage"
인 경우 등) INDIRECT
-
버퍼를 간접 명령 인자 저장 용도로 사용 가능. (예:
indirectBuffer
인자로drawIndirect()
나dispatchWorkgroupsIndirect()
에 전달) QUERY_RESOLVE
-
버퍼를 쿼리 결과 캡처 용도로 사용 가능. (예:
destination
인자로resolveQuerySet()
에 전달)
5.1.3. 버퍼 생성
createBuffer(descriptor)
-
GPUBuffer
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createBuffer(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUBufferDescriptor
✘ ✘ 생성할 GPUBuffer
의 설명.반환값:
GPUBuffer
콘텐츠 타임라인 단계:
-
b를 ! 새 WebGPU 객체 생성(this,
GPUBuffer
, descriptor)로 둡니다. -
만약 descriptor.
mappedAtCreation
이true
라면:-
descriptor.
size
가 4의 배수가 아니면RangeError
를 throw. -
b.
[[mapping]]
값을 ? active buffer mapping 초기화(modeWRITE
, range[0, descriptor.
)로 설정.size
]
-
-
initialization steps를 this의 디바이스 타임라인에서 실행.
-
b를 반환.
디바이스 타임라인 initialization steps:-
아래 요구사항 중 하나라도 만족하지 않으면, 검증 오류 생성, b를 무효화하고 반환.
-
this가 손실(lost) 상태가 아니어야 함.
-
descriptor.
usage
값이 0이 아니어야 함. -
descriptor.
size
값이 this.[[device]]
.[[limits]]
.maxBufferSize
이하이어야 함.
-
참고: 버퍼 생성이 실패하고 descriptor.
mappedAtCreation
값이false
인 경우,mapAsync()
호출은 거부됩니다. 매핑을 위한 리소스는 할당 취소 또는 재활용될 수 있습니다.-
descriptor.
mappedAtCreation
값이true
면:-
b.
[[internal state]]
값을 "unavailable"로 설정.
그 외에는:
-
b.
[[internal state]]
값을 "available"로 설정.
-
-
b에 대해 각 바이트가 0인 디바이스 할당 생성.
할당이 부작용 없이 실패하면, out-of-memory 오류 생성, b를 무효화하고 반환.
-
const buffer= gpuDevice. createBuffer({ size: 128 , usage: GPUBufferUsage. UNIFORM| GPUBufferUsage. COPY_DST});
5.1.4. 버퍼 파괴
앱에서 GPUBuffer
가 더
이상 필요하지 않을 때,
destroy()
를
호출해
가비지 컬렉션 전에 접근 권한을 잃게 할 수 있습니다. 버퍼를 파괴하면 매핑도 해제되어 할당된 매핑 메모리가 해제됩니다.
참고: 이렇게 하면 사용자 에이전트가 해당 GPUBuffer
와 연결된
GPU 메모리를
해당 버퍼를 사용하는 모든 제출된 작업이 완료된 뒤 회수할 수 있습니다.
GPUBuffer
는 다음
메서드를 가집니다:
destroy()
-
GPUBuffer
를 파괴합니다.참고: 버퍼를 여러 번 파괴해도 문제가 없습니다.
호출 대상:GPUBuffer
this.반환값:
undefined
콘텐츠 타임라인 단계:
-
this.
unmap()
호출. -
이후 단계는 this.
[[device]]
의 디바이스 타임라인에서 실행.
디바이스 타임라인 단계:-
this.
[[internal state]]
값을 "destroyed"로 설정.
참고: 이 버퍼로 더 이상 작업을 큐잉할 수 없으므로, 구현체는 매핑 해제된 메모리를 포함한 자원 할당을 해제할 수 있습니다.
-
5.2. 버퍼 매핑
애플리케이션은 GPUBuffer
를
매핑(map) 요청하여
ArrayBuffer
로
해당 버퍼의 일부 할당 영역에 접근할 수 있습니다.
GPUBuffer
매핑은
mapAsync()
로
비동기 요청하며,
사용자 에이전트가 GPU가 해당 버퍼를 사용 중임을 확인한 뒤 애플리케이션이 내용을 접근할 수 있게 합니다.
매핑된 GPUBuffer
는
GPU가 사용할 수 없으며,
unmap()
을
통해
unmap한 뒤에야 Queue 타임라인에서 해당
버퍼를 사용하는 작업을 제출할 수 있습니다.
GPUBuffer
가
매핑된 뒤에는,
getMappedRange()
로
동기적으로 해당 콘텐츠의 범위에 접근할 수 있습니다.
반환되는 ArrayBuffer
는
오직 unmap()
(직접 호출하거나 GPUBuffer
.destroy()
,
GPUDevice
.destroy()
로
간접 호출)로만 detach될 수 있습니다.
transferred될 수 없으며,
다른 연산에서 시도하면 TypeError
가
발생합니다.
typedef [EnforceRange ]unsigned long ; [
GPUMapModeFlags Exposed =(Window ,Worker ),SecureContext ]namespace {
GPUMapMode const GPUFlagsConstant READ = 0x0001;const GPUFlagsConstant WRITE = 0x0002; };
GPUMapMode
플래그는 GPUBuffer
를
mapAsync()
로
호출할 때
어떻게 매핑할지 결정합니다:
READ
-
MAP_READ
용도로 생성한 버퍼에서만 유효합니다.버퍼가 매핑되면
getMappedRange()
호출 시 버퍼의 현재 값이 들어있는ArrayBuffer
를 반환합니다. 반환된ArrayBuffer
의 변경 내용은unmap()
호출 후 버려집니다. WRITE
-
MAP_WRITE
용도로 생성한 버퍼에서만 유효합니다.버퍼가 매핑되면
getMappedRange()
호출 시 버퍼의 현재 값이 들어있는ArrayBuffer
를 반환합니다. 반환된ArrayBuffer
의 변경 내용은GPUBuffer
에unmap()
호출 후 저장됩니다.참고:
MAP_WRITE
용도 버퍼는COPY_SRC
와만 결합할 수 있으므로, 쓰기 매핑 시 GPU에서 생성된 값을 반환할 수 없고, 반환된ArrayBuffer
는 항상 기본 초기화 데이터(0)나 이전 매핑에서 웹페이지가 기록한 데이터만 포함합니다.
GPUBuffer
는 다음
메서드를 가집니다:
mapAsync(mode, offset, size)
-
지정한
GPUBuffer
의 범위를 매핑(map)하며, 반환된Promise
는GPUBuffer
의 내용을getMappedRange()
로 접근할 준비가 완료되면 resolve됩니다.반환된
Promise
의 resolve는 오직 버퍼가 매핑됐음을 나타냅니다. 콘텐츠 타임라인에서 볼 수 있는 다른 작업의 완료를 보장하지 않으며, 특히 다른Promise
(onSubmittedWorkDone()
나mapAsync()
가 다른GPUBuffer
에 대해 반환한 Promise)들의 완료도 의미하지 않습니다.onSubmittedWorkDone()
로 반환된Promise
의 resolve는 해당 호출 전에 큐에서 독점적으로 사용된GPUBuffer
에 대해mapAsync()
가 완료됨을 의미합니다.호출 대상:GPUBuffer
this.인자:
GPUBuffer.mapAsync(mode, offset, size) 메서드 인자. 파라미터 타입 Nullable Optional 설명 mode
GPUMapModeFlags
✘ ✘ 버퍼를 읽기/쓰기로 매핑할지 여부. offset
GPUSize64
✘ ✔ 매핑 시작 위치(바이트 단위). size
GPUSize64
✘ ✔ 매핑 범위 크기(바이트 단위). 콘텐츠 타임라인 단계:
-
contentTimeline을 현재 콘텐츠 타임라인으로 둡니다.
-
만약 this.
mapState
가"unmapped"
가 아니면:-
this.
[[device]]
의 디바이스 타임라인에서 early-reject steps를 실행합니다. -
OperationError로 reject된 promise를 반환합니다.
-
-
p를 새로운
Promise
로 둡니다. -
this.
[[pending_map]]
에 p를 설정합니다. -
this.
[[device]]
의 디바이스 타임라인에서 validation steps를 실행합니다. -
p를 반환합니다.
디바이스 타임라인 early-reject steps:-
반환.
디바이스 타임라인 validation steps:-
size가
undefined
이면:-
rangeSize를 max(0, this.
size
- offset)로 둔다.
그 외에는:
-
rangeSize를 size로 둔다.
-
-
아래 조건 중 하나라도 만족하지 않으면:
-
this는 유효(valid)해야 한다.
-
deviceLost를
true
로 둔다. -
map failure steps를 contentTimeline에서 실행한다.
-
반환.
-
-
아래 조건 중 하나라도 만족하지 않으면:
그 후:
-
deviceLost를
false
로 둔다. -
map failure steps를 contentTimeline에서 실행한다.
-
반환.
-
-
this.
[[internal state]]
값을 "unavailable"로 설정한다.참고: 버퍼가 매핑된 상태라 이 단계와
unmap()
사이에는 내용이 변경될 수 없다. -
아래 이벤트 중 하나라도 발생하면(혹은 이미 발생한 경우):
-
디바이스 타임라인이 특정 큐 타임라인의 완료를 알게 됨:
-
현재 큐잉된 작업 중 this를 사용하는 작업 완료 후
-
this를 사용하든 안 하든 모든 현재 큐잉된 작업 완료 후
-
-
this.
[[device]]
가 손실됨(becomes lost).
이후 단계는 this.
[[device]]
의 디바이스 타임라인에서 실행한다. -
디바이스 타임라인 단계:-
this.
[[device]]
가 손실(lost)이면 deviceLost를true
로, 아니면false
로 둔다.참고: 디바이스가 바로 앞 단계와 이 단계 사이에 손실될 수 있음.
-
deviceLost가
true
라면:-
map failure steps를 contentTimeline에서 실행한다.
그 외에는:
-
internalStateAtCompletion을 this.
[[internal state]]
로 둔다.참고: 이 시점에
unmap()
호출로 버퍼가 다시 "available" 상태가 되었다면[[pending_map]]
!= 아래의 p이므로 아래 단계에서 매핑 성공할 수 없음. -
dataForMappedRegion을 this의 offset부터 rangeSize 바이트만큼의 내용으로 둔다.
-
map success steps를 contentTimeline에서 실행한다.
-
콘텐츠 타임라인 매핑 성공 단계:-
만약 this.
[[pending_map]]
이 p와 다르다면:참고:
unmap()
에 의해 매핑이 취소됨.-
Assert p는 reject 상태여야 한다.
-
반환.
-
-
Assert p는 pending 상태여야 한다.
-
Assert internalStateAtCompletion이 "unavailable"이다.
-
mapping을 active buffer mapping 초기화(mode mode, range
[offset, offset + rangeSize]
)로 둔다.이 할당이 실패하면:
-
this.
[[pending_map]]
을null
로 설정하고, RangeError로 p를 reject 한다. -
반환.
-
-
mapping.data의 내용을 dataForMappedRegion으로 설정.
-
this.
[[mapping]]
을 mapping으로 설정. -
this.
[[pending_map]]
을null
로 설정하고, resolve p.
콘텐츠 타임라인 매핑 실패 단계:-
만약 this.
[[pending_map]]
이 p와 다르다면:참고:
unmap()
에 의해 매핑이 취소됨.-
Assert p는 이미 reject 상태여야 한다.
-
반환.
-
-
Assert p는 아직 pending 상태여야 한다.
-
this.
[[pending_map]]
을null
로 설정. -
deviceLost가 true라면:
-
AbortError로 p를 reject 한다.
참고:
unmap()
으로 매핑을 취소할 때 발생하는 오류와 동일한 타입.
그 외에는:
-
OperationError로 p를 reject 한다.
-
-
getMappedRange(offset, size)
-
지정된 매핑 범위의
ArrayBuffer
를 반환합니다. 반환된GPUBuffer
의 내용을 포함합니다.호출 대상:GPUBuffer
this.인자:
GPUBuffer.getMappedRange(offset, size) 메서드 인자. 파라미터 타입 Nullable Optional 설명 offset
GPUSize64
✘ ✔ 버퍼에서 반환할 내용의 바이트 단위 오프셋. size
GPUSize64
✘ ✔ 반환할 ArrayBuffer
의 크기(바이트 단위).반환값:
ArrayBuffer
콘텐츠 타임라인 단계:
-
size가 없으면:
-
rangeSize를 max(0, this.
size
- offset)로 둔다.
그 외에는 rangeSize를 size로 둔다.
-
-
아래 조건 중 하나라도 만족하지 않으면
OperationError
를 throw하고 반환한다.-
this.
[[mapping]]
값이null
이 아님. -
offset이 8의 배수임.
-
rangeSize가 4의 배수임.
-
offset ≥ this.
[[mapping]]
.range[0]. -
offset + rangeSize ≤ this.
[[mapping]]
.range[1]. -
[offset, offset + rangeSize)가 this.
[[mapping]]
.views의 다른 범위와 겹치지 않음.
참고:
GPUBuffer
가mappedAtCreation
으로 생성된 경우, invalid 상태여도 항상 매핑 범위를 가져올 수 있음. 이는 콘텐츠 타임라인이 invalid 상태를 모를 수 있기 때문임. -
-
data를 this.
[[mapping]]
.data로 둔다. -
view를 ! ArrayBuffer 생성(크기 rangeSize)로 둔다. 단, 포인터는 data의 (offset -
[[mapping]]
.range[0]) 오프셋부터의 내용에 mutably reference함.참고:
RangeError
는 발생하지 않음. data는 이미mapAsync()
또는createBuffer()
에서 할당됨. -
view.
[[ArrayBufferDetachKey]]
를 "WebGPUBufferMapping"으로 설정함.참고:
TypeError
는unmap()
이외의 방법으로 DetachArrayBuffer를 시도할 때 발생함. -
Append view를 this.
[[mapping]]
.views에 추가한다. -
view를 반환한다.
참고:
getMappedRange()
가 매핑 상태를 확인하지 않고 성공한 경우,mapAsync()
성공,mapState
가"mapped"
인지 확인, 또는onSubmittedWorkDone()
성공 등 상태 확인에 대한 경고를 개발자에게 표시할 수 있음. -
unmap()
-
매핑된
GPUBuffer
범위를 해제(unmap)하여 GPU가 다시 해당 내용을 사용할 수 있도록 합니다.호출 대상:GPUBuffer
this.반환값:
undefined
콘텐츠 타임라인 단계:
-
this.
[[pending_map]]
이null
이 아니면:-
Reject this.
[[pending_map]]
에AbortError
로 reject한다. -
this.
[[pending_map]]
를null
로 설정한다.
-
-
this.
[[mapping]]
이null
이면:-
반환.
-
-
this.
ArrayBuffer
ab를 this.[[mapping]]
.views에서 각각에 대해:-
DetachArrayBuffer(ab, "WebGPUBufferMapping")를 실행한다.
-
-
bufferUpdate를
null
로 둔다. -
this.
[[mapping]]
.mode가WRITE
를 포함하면:-
bufferUpdate를 {
data
: this.[[mapping]]
.data,offset
: this.[[mapping]]
.range[0] }로 둔다.
참고:
WRITE
모드 없이 매핑된 버퍼는 unmap시 애플리케이션이 매핑 범위에 로컬에서 수정한 내용이 모두 폐기되며 이후 매핑에 영향을 주지 않는다. -
-
this.
[[mapping]]
을null
로 둔다. -
이후 단계는 this.
[[device]]
의 디바이스 타임라인에서 실행한다.
디바이스 타임라인 단계:-
아래 조건 중 하나라도 만족하지 않으면 반환한다.
-
this는 유효하게 사용할 수 있어야 함 this.
[[device]]
와 함께.
-
-
Assert this.
[[internal state]]
값이 "unavailable"임을 확인. -
bufferUpdate가
null
이 아니면:-
this.
[[device]]
.queue
의 큐 타임라인 단계로 이동:큐 타임라인 단계:-
this의 bufferUpdate.
offset
에서 bufferUpdate.data
의 내용으로 버퍼 내용을 갱신함.
-
-
-
this.
[[internal state]]
을 "available"로 둔다.
-
6. 텍스처와 텍스처 뷰
6.1. GPUTexture
텍스처는 1d
,
2d
,
또는 3d
데이터 배열로 구성되며, 각 요소에는 여러 값을 포함할 수 있어 색상과 같은 정보를 표현합니다. 텍스처는 생성 시 지정된 GPUTextureUsage
에
따라 다양한 방법으로 읽고 쓸 수 있습니다. 예를 들어, 텍스처는 렌더 및 컴퓨트 파이프라인 셰이더에서 샘플링, 읽기, 쓰기할 수 있고, 렌더 패스 출력으로 쓰기도 가능합니다.
내부적으로 텍스처는 GPU 메모리에 다차원 접근에 최적화된 레이아웃으로 저장되는 경우가 많습니다(선형 접근이 아닌).
하나의 텍스처는 하나 이상의 텍스처 서브리소스로 구성되며,
각각은 mipmap 레벨과
2d
텍스처의 경우 array layer 및 aspect로 고유하게 식별됩니다.
텍스처 서브리소스는 서브리소스로, 각각은 하나의 사용 범위 내에서 서로 다른 내부 용도로 사용될 수 있습니다.
mipmap 레벨의 각 서브리소스는 공간
차원마다 바로 이전 레벨의 리소스 크기보다 약 절반 크기입니다
(자세한 내용은 논리적 miplevel별 텍스처 크기 참고).
레벨 0의 서브리소스는 텍스처 자체의 크기를 가집니다.
작은 레벨은 일반적으로 동일 이미지의 저해상도 버전을 저장하는 데 사용됩니다.
GPUSampler
와
WGSL은 상세도 레벨 선택 및 보간을 명시적
또는 자동으로 지원합니다.
"2d"
텍스처는 array layer 배열일 수
있습니다.
각 array layer의 서브리소스는 다른 layer의 동일한 리소스와 크기가 같습니다.
2d가 아닌 텍스처는 모든 서브리소스의 array layer 인덱스가 0입니다.
각 서브리소스에는 aspect가 있습니다.
컬러 텍스처는 하나의 aspect(color)만 가집니다.
깊이 또는 스텐실
포맷 텍스처는 여러 aspect를 가질 수 있습니다:
깊이
aspect,
스텐실 aspect, 또는 둘 다 가질 수 있으며, depthStencilAttachment
및 "depth"
바인딩 등 특수 용도로 사용될 수 있습니다.
"3d"
텍스처는 여러 slice를 가질 수 있으며, 각
slice는 텍스처의 특정 z
값에 해당하는 2차원 이미지입니다.
slice는 별도의 서브리소스가 아닙니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUTexture {GPUTextureView createView (optional GPUTextureViewDescriptor descriptor = {});undefined destroy ();readonly attribute GPUIntegerCoordinateOut width ;readonly attribute GPUIntegerCoordinateOut height ;readonly attribute GPUIntegerCoordinateOut depthOrArrayLayers ;readonly attribute GPUIntegerCoordinateOut mipLevelCount ;readonly attribute GPUSize32Out sampleCount ;readonly attribute GPUTextureDimension dimension ;readonly attribute GPUTextureFormat format ;readonly attribute GPUFlagsConstant usage ; };GPUTexture includes GPUObjectBase ;
GPUTexture
는 다음 불변 속성을 가집니다:
width
, 타입 GPUIntegerCoordinateOut, 읽기 전용-
이
GPUTexture
의 너비입니다. height
, 타입 GPUIntegerCoordinateOut, 읽기 전용-
이
GPUTexture
의 높이입니다. depthOrArrayLayers
, 타입 GPUIntegerCoordinateOut, 읽기 전용-
이
GPUTexture
의 깊이 또는 레이어 개수입니다. mipLevelCount
, 타입 GPUIntegerCoordinateOut, 읽기 전용-
이
GPUTexture
의 mip 레벨 개수입니다. sampleCount
, 타입 GPUSize32Out, 읽기 전용-
이
GPUTexture
의 샘플 개수입니다. dimension
, 타입 GPUTextureDimension, 읽기 전용-
각
GPUTexture
의 서브리소스별 텍셀 집합의 차원입니다. format
, 타입 GPUTextureFormat, 읽기 전용-
이
GPUTexture
의 포맷입니다. usage
, 타입 GPUFlagsConstant, 읽기 전용-
이
GPUTexture
의 허용된 용도입니다. [[viewFormats]]
, 타입 sequence<GPUTextureFormat
>-
이
GPUTexture
에 대한 뷰 생성 시GPUTextureViewDescriptor
.format
으로 사용할 수 있는GPUTextureFormat
들의 집합입니다.
GPUTexture
는 다음 디바이스
타임라인 속성을 가집니다:
[[destroyed]]
, 타입boolean
, 초기값false
-
텍스처가 destroy되면, 어떤 작업에도 더 이상 사용할 수 없으며, 하부 메모리가 해제될 수 있습니다.
인자:
-
GPUExtent3D
baseSize -
GPUSize32
mipLevel
반환값: GPUExtent3DDict
디바이스 타임라인 단계:
-
extent를 새로운
GPUExtent3DDict
객체로 둔다. -
extent.
depthOrArrayLayers
를 1로 설정한다. -
extent를 반환한다.
논리적 miplevel별 텍스처 크기는 특정 miplevel에서 텍스처의 텍셀 단위 크기입니다. 다음 절차로 계산됩니다:
인자:
-
GPUTextureDescriptor
descriptor -
GPUSize32
mipLevel
반환값: GPUExtent3DDict
-
extent를 새로운
GPUExtent3DDict
객체로 둔다. -
descriptor.
dimension
값이 다음 중 하나일 때:"1d"
-
-
extent.
width
를 max(1, descriptor.size
.width ≫ mipLevel)로 설정. -
extent.
height
를 1로 설정. -
extent.
depthOrArrayLayers
를 1로 설정.
-
"2d"
-
-
extent.
width
를 max(1, descriptor.size
.width ≫ mipLevel)로 설정. -
extent.
height
를 max(1, descriptor.size
.height ≫ mipLevel)로 설정. -
extent.
depthOrArrayLayers
를 descriptor.size
.depthOrArrayLayers로 설정.
-
"3d"
-
-
extent.
width
를 max(1, descriptor.size
.width ≫ mipLevel)로 설정. -
extent.
height
를 max(1, descriptor.size
.height ≫ mipLevel)로 설정. -
extent.
depthOrArrayLayers
를 max(1, descriptor.size
.depthOrArrayLayers ≫ mipLevel)로 설정.
-
-
extent를 반환한다.
물리적 miplevel별 텍스처 크기는 특정 miplevel에서 텍스처의 텍셀 단위 크기로, 텍셀 블록을 완성하기 위한 추가 패딩이 포함될 수 있습니다. 다음 절차로 계산됩니다:
인자:
-
GPUTextureDescriptor
descriptor -
GPUSize32
mipLevel
반환값: GPUExtent3DDict
-
extent를 새로운
GPUExtent3DDict
객체로 둔다. -
logicalExtent를 논리적 miplevel별 텍스처 크기(descriptor, mipLevel)로 둔다.
-
descriptor.
dimension
값이 다음 중 하나일 때:"1d"
-
-
extent.
width
를 logicalExtent.width를 descriptor의 텍셀 블록 너비의 배수로 올림한 값으로 설정. -
extent.
height
를 1로 설정. -
extent.
depthOrArrayLayers
를 1로 설정.
-
"2d"
-
-
extent.
width
를 logicalExtent.width를 descriptor의 텍셀 블록 너비의 배수로 올림한 값으로 설정. -
extent.
height
를 logicalExtent.height를 descriptor의 텍셀 블록 높이의 배수로 올림한 값으로 설정. -
extent.
depthOrArrayLayers
를 logicalExtent.depthOrArrayLayers로 설정.
-
"3d"
-
-
extent.
width
를 logicalExtent.width를 descriptor의 텍셀 블록 너비의 배수로 올림한 값으로 설정. -
extent.
height
를 logicalExtent.height를 descriptor의 텍셀 블록 높이의 배수로 올림한 값으로 설정. -
extent.
depthOrArrayLayers
를 logicalExtent.depthOrArrayLayers로 설정.
-
-
extent를 반환한다.
6.1.1. GPUTextureDescriptor
dictionary GPUTextureDescriptor :GPUObjectDescriptorBase {required GPUExtent3D size ;GPUIntegerCoordinate mipLevelCount = 1;GPUSize32 sampleCount = 1;GPUTextureDimension dimension = "2d";required GPUTextureFormat format ;required GPUTextureUsageFlags usage ;sequence <GPUTextureFormat >viewFormats = []; };
GPUTextureDescriptor
는 다음 멤버를 가집니다:
size
, 타입 GPUExtent3D-
텍스처의 너비, 높이, 깊이 또는 레이어 개수입니다.
mipLevelCount
, 타입 GPUIntegerCoordinate, 기본값1
-
텍스처가 포함할 mip 레벨 개수입니다.
sampleCount
, 타입 GPUSize32, 기본값1
-
텍스처의 샘플 개수입니다.
sampleCount
>1
이면 다중 샘플 텍스처임을 나타냅니다. dimension
, 타입 GPUTextureDimension, 기본값"2d"
-
텍스처가 1차원, 2차원 레이어 배열, 또는 3차원인지 여부입니다.
format
, 타입 GPUTextureFormat-
텍스처의 포맷입니다.
usage
, 타입 GPUTextureUsageFlags-
텍스처의 허용되는 용도입니다.
viewFormats
, 타입 sequence<GPUTextureFormat>, 기본값[]
-
이 텍스처에 대해
format
값을 사용하여createView()
를 호출할 때 허용되는 뷰 포맷을 지정합니다(텍스처의 실제format
포함).참고:이 목록에 포맷을 추가하면 성능에 큰 영향을 줄 수 있으므로 불필요하게 포맷을 추가하지 않는 것이 좋습니다.실제 성능 영향은 대상 시스템에 따라 매우 다르므로 개발자는 다양한 시스템에서 테스트하여 애플리케이션에 대한 영향을 확인해야 합니다. 예를 들어, 일부 시스템에서는
format
또는viewFormats
항목에"rgba8unorm-srgb"
가 포함된 경우,"rgba8unorm"
만 사용하는 텍스처보다 성능이 저하될 수 있습니다. 비슷한 주의사항이 다른 포맷, 포맷 쌍에도 적용됩니다.이 목록의 포맷들은 텍스처 포맷과 텍스처 뷰 포맷 호환이어야 합니다.
두GPUTextureFormat
format과 viewFormat이 텍스처 뷰 포맷 호환이 되려면:-
format이 viewFormat과 같거나,
-
format과 viewFormat이
srgb
포맷(-srgb 접미사 유무)만 다르면
-
enum {
GPUTextureDimension "1d" ,"2d" ,"3d" , };
"1d"
-
너비만 있는 1차원 텍스처를 지정합니다.
"1d"
텍스처는 mipmap을 가질 수 없으며, 다중 샘플, 압축 또는 깊이/스텐실 포맷을 사용할 수 없고, 렌더 타겟으로도 사용할 수 없습니다. "2d"
-
너비와 높이가 있으며, 레이어를 가질 수 있는 텍스처를 지정합니다.
"3d"
-
너비, 높이, 깊이를 가지는 텍스처를 지정합니다.
"3d"
텍스처는 다중 샘플을 지원하지 않으며, 해당 포맷이 3d 텍스처를 지원해야 합니다 (모든 일반 컬러 포맷과 일부 packed/압축 포맷).
6.1.2. 텍스처 용도
typedef [EnforceRange ]unsigned long ; [
GPUTextureUsageFlags Exposed =(Window ,Worker ),SecureContext ]namespace {
GPUTextureUsage const GPUFlagsConstant COPY_SRC = 0x01;const GPUFlagsConstant COPY_DST = 0x02;const GPUFlagsConstant TEXTURE_BINDING = 0x04;const GPUFlagsConstant STORAGE_BINDING = 0x08;const GPUFlagsConstant RENDER_ATTACHMENT = 0x10; };
GPUTextureUsage
플래그는 GPUTexture
생성 후 어떻게 사용할 수 있는지 결정합니다:
COPY_SRC
-
텍스처를 복사 작업의 소스로 사용할 수 있습니다. (예:
source
인자로copyTextureToTexture()
또는copyTextureToBuffer()
호출 시.) COPY_DST
-
텍스처를 복사 또는 쓰기 작업의 대상으로 사용할 수 있습니다. (예:
destination
인자로copyTextureToTexture()
또는copyBufferToTexture()
호출 시, 혹은writeTexture()
호출의 대상.) TEXTURE_BINDING
-
텍스처를 셰이더에서 샘플링 텍스처로 바인딩할 수 있습니다(예:
GPUTextureBindingLayout
의 바인드 그룹 항목). STORAGE_BINDING
-
텍스처를 셰이더에서 storage 텍스처로 바인딩할 수 있습니다(예:
GPUStorageTextureBindingLayout
의 바인드 그룹 항목). RENDER_ATTACHMENT
-
텍스처를 렌더 패스에서 컬러 또는 깊이/스텐실 attachment로 사용할 수 있습니다. (예:
GPURenderPassColorAttachment
.view
또는GPURenderPassDepthStencilAttachment
.view
로 사용.)
인자:
-
GPUTextureDimension
dimension -
GPUTextureDimension
size
6.1.3. 텍스처 생성
createTexture(descriptor)
-
GPUTexture
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createTexture(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUTextureDescriptor
✘ ✘ 생성할 GPUTexture
의 설명.반환값:
GPUTexture
콘텐츠 타임라인 단계:
-
? GPUExtent3D 형태 검증(descriptor.
size
). -
? 텍스처 포맷 필수 기능 검증(descriptor.
format
, this.[[device]]
). -
? 텍스처 포맷 필수 기능 검증을 descriptor.
viewFormats
의 각각의 요소와 this.[[device]]
에 대해 수행한다. -
t를 ! 새 WebGPU 객체 생성(this,
GPUTexture
, descriptor)로 둔다. -
t.
depthOrArrayLayers
를 descriptor.size
.depthOrArrayLayers로 설정. -
t.
mipLevelCount
를 descriptor.mipLevelCount
로 설정. -
t.
sampleCount
를 descriptor.sampleCount
로 설정. -
this의 디바이스 타임라인에서 초기화 단계를 실행합니다.
-
t를 반환합니다.
디바이스 타임라인 초기화 단계:-
아래 조건 중 하나라도 만족하지 않으면 검증 오류를 생성하고, t를 무효화하고 반환합니다.
-
GPUTextureDescriptor 유효성 검증(this, descriptor) 결과가
true
여야 합니다.
-
-
t.
[[viewFormats]]
를 descriptor.viewFormats
로 설정. -
t에 대해 각 블록이 0비트 표현의 블록과 동등 텍셀 표현을 가지도록 디바이스 할당을 생성합니다.
할당이 부작용 없이 실패하면, 메모리 부족 오류 생성, t를 무효화하고 반환합니다.
-
인자:
-
GPUDevice
this -
GPUTextureDescriptor
descriptor
디바이스 타임라인 단계:
-
limits를 this.
[[limits]]
로 둔다. -
아래 요구사항을 모두 만족하면
true
반환, 아니면false
반환:-
this는 손실(lost) 상태가 아니어야 합니다.
-
descriptor.
usage
는 0이 아니어야 합니다. -
descriptor.
usage
는 this의 허용된 텍스처 용도 비트만 포함해야 합니다. -
descriptor.
size
.width, descriptor.size
.height, descriptor.size
.depthOrArrayLayers는 0보다 커야 합니다. -
descriptor.
mipLevelCount
는 0보다 커야 합니다. -
descriptor.
sampleCount
는 1 또는 4이어야 합니다. -
descriptor.
dimension
값이 다음 중 하나일 때:"1d"
-
-
descriptor.
size
.width는 limits.maxTextureDimension1D
이하이어야 합니다. -
descriptor.
size
.depthOrArrayLayers 는 1이어야 합니다. -
descriptor.
sampleCount
는 1이어야 합니다.
-
"2d"
-
-
descriptor.
size
.width는 limits.maxTextureDimension2D
이하이어야 합니다. -
descriptor.
size
.height는 limits.maxTextureDimension2D
이하이어야 합니다. -
descriptor.
size
.depthOrArrayLayers 는 limits.maxTextureArrayLayers
이하이어야 합니다.
-
"3d"
-
-
descriptor.
size
.width는 limits.maxTextureDimension3D
이하이어야 합니다. -
descriptor.
size
.height는 limits.maxTextureDimension3D
이하이어야 합니다. -
descriptor.
size
.depthOrArrayLayers 는 limits.maxTextureDimension3D
이하이어야 합니다. -
descriptor.
sampleCount
는 1이어야 합니다. -
descriptor.
format
는"3d"
텍스처를 지원해야 합니다. (§ 26.1 텍스처 포맷 지원 참조)
-
-
descriptor.
sampleCount
> 1일 때:-
descriptor.
mipLevelCount
는 1이어야 합니다. -
descriptor.
size
.depthOrArrayLayers 는 1이어야 합니다. -
descriptor.
usage
는STORAGE_BINDING
비트를 포함하면 안 됩니다. -
descriptor.
usage
는RENDER_ATTACHMENT
비트를 포함해야 합니다. -
descriptor.
format
는 다중 샘플링을 지원해야 합니다(§ 26.1 텍스처 포맷 지원 참조).
-
-
descriptor.
mipLevelCount
는 최대 mipLevel 개수(descriptor.dimension
, descriptor.size
) 이하이어야 합니다. -
descriptor.
usage
에RENDER_ATTACHMENT
비트가 포함된 경우:-
descriptor.
format
는 렌더링 가능한 포맷이어야 합니다.
-
-
descriptor.
usage
에STORAGE_BINDING
비트가 포함된 경우:-
descriptor.
format
는 § 26.1.1 일반 컬러 포맷 테이블에STORAGE_BINDING
능력이 최소 한 access mode에서 있어야 합니다.
-
-
각 viewFormat에 대해 descriptor.
viewFormats
의 descriptor.format
과 viewFormat은 텍스처 뷰 포맷 호환이어야 합니다.참고:구현체는 viewFormat이 지정된usage
비트와 호환되지 않을 때 개발자에게 경고를 표시할 수 있습니다. 해당 viewFormat은 사용할 수 없기 때문입니다.
-
const texture= gpuDevice. createTexture({ size: { width: 16 , height: 16 }, format: 'rgba8unorm' , usage: GPUTextureUsage. TEXTURE_BINDING, });
6.1.4. 텍스처 소멸
애플리케이션에서 더 이상 GPUTexture
가
필요하지 않은 경우,
가비지 컬렉션 전에 destroy()
를
호출하여 접근 권한을 미리 잃도록 선택할 수 있습니다.
참고: 이렇게 하면 사용자 에이전트가 GPUTexture
와
관련된 GPU 메모리를
해당 텍스처를 사용하는 모든 이전 제출 작업이 완료된 후 회수할 수 있습니다.
GPUTexture
는 다음 메서드를 가집니다:
destroy()
-
GPUTexture
를 소멸시킵니다.디바이스 타임라인 단계:-
this.
[[destroyed]]
를 true로 설정합니다.
-
6.2. GPUTextureView
GPUTextureView
는
특정 GPUTexture
에
대해
텍스처 서브리소스의 일부
집합을 참조하는 뷰입니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUTextureView { };GPUTextureView includes GPUObjectBase ;
GPUTextureView
는 다음 불변 속성을 가집니다:
[[texture]]
, 읽기 전용-
이 뷰가 참조하는
GPUTexture
입니다. [[descriptor]]
, 읽기 전용-
이 텍스처 뷰를 설명하는
GPUTextureViewDescriptor
입니다.모든 선택적
GPUTextureViewDescriptor
필드는 정의되어 있습니다. [[renderExtent]]
, 읽기 전용-
렌더링 가능한 뷰일 경우, 렌더링에 사용되는 실질적인
GPUExtent3DDict
입니다.참고: 이 크기는
baseMipLevel
에 따라 달라집니다.
[[descriptor]]
desc를 기준으로,
view.[[texture]]
의
서브리소스 중
각각의 서브리소스 s가 아래 조건을 만족하는 부분집합입니다:
-
s의 mipmap 레벨이 desc.
baseMipLevel
이상이고, desc.baseMipLevel
+ desc.mipLevelCount
미만입니다. -
s의 array layer가 desc.
baseArrayLayer
이상이고, desc.baseArrayLayer
+ desc.arrayLayerCount
미만입니다.
두 GPUTextureView
객체는
서브리소스 집합이 겹칠 때에만 텍스처 뷰 aliasing 관계입니다.
6.2.1. 텍스처 뷰 생성
dictionary :
GPUTextureViewDescriptor GPUObjectDescriptorBase {GPUTextureFormat format ;GPUTextureViewDimension dimension ;GPUTextureUsageFlags usage = 0;GPUTextureAspect aspect = "all";GPUIntegerCoordinate baseMipLevel = 0;GPUIntegerCoordinate mipLevelCount ;GPUIntegerCoordinate baseArrayLayer = 0;GPUIntegerCoordinate arrayLayerCount ; };
GPUTextureViewDescriptor
는 다음 멤버를 가집니다:
format
, 타입 GPUTextureFormat-
텍스처 뷰의 포맷입니다. 반드시 해당 텍스처의
format
또는 생성 시 지정된viewFormats
중 하나여야 합니다. dimension
, 타입 GPUTextureViewDimension-
텍스처를 어떤 차원으로 볼지 지정합니다.
usage
, 타입 GPUTextureUsageFlags, 기본값0
-
텍스처 뷰의 허용된
usage
입니다. 반드시 텍스처의usage
플래그의 부분집합이어야 합니다. 0일 경우, 기본값은 텍스처의 모든usage
플래그입니다.참고: 뷰의
format
이 텍스처의 모든usage
를 지원하지 않으면, 기본값이 실패하며 뷰의usage
를 명시적으로 지정해야 합니다. aspect
, 타입 GPUTextureAspect, 기본값"all"
-
텍스처의 어느
aspect
가 텍스처 뷰에서 접근 가능한지 지정합니다. baseMipLevel
, 타입 GPUIntegerCoordinate, 기본값0
-
텍스처 뷰에서 접근 가능한 첫 번째(가장 상세한) mipmap 레벨입니다.
mipLevelCount
, 타입 GPUIntegerCoordinate-
baseMipLevel
부터 몇 개의 mipmap 레벨이 텍스처 뷰에서 접근 가능한지 지정합니다. baseArrayLayer
, 타입 GPUIntegerCoordinate, 기본값0
-
텍스처 뷰에서 접근 가능한 첫 번째 배열 레이어의 인덱스입니다.
arrayLayerCount
, 타입 GPUIntegerCoordinate-
baseArrayLayer
부터 몇 개의 배열 레이어가 텍스처 뷰에서 접근 가능한지 지정합니다.
enum {
GPUTextureViewDimension "1d" ,"2d" ,"2d-array" ,"cube" ,"cube-array" ,"3d" , };
"1d"
-
텍스처를 1차원 이미지로 봅니다.
해당 WGSL 타입:
-
texture_1d
-
texture_storage_1d
-
"2d"
-
텍스처를 단일 2차원 이미지로 봅니다.
해당 WGSL 타입:
-
texture_2d
-
texture_storage_2d
-
texture_multisampled_2d
-
texture_depth_2d
-
texture_depth_multisampled_2d
-
"2d-array"
-
텍스처 뷰를 2차원 이미지 배열로 봅니다.
해당 WGSL 타입:
-
texture_2d_array
-
texture_storage_2d_array
-
texture_depth_2d_array
-
"cube"
-
텍스처를 큐브맵으로 봅니다.
뷰에는 6개의 배열 레이어가 있으며, 각각은 큐브의 면에 해당합니다. 순서는
[+X, -X, +Y, -Y, +Z, -Z]
이고 방향은 다음과 같습니다:큐브맵 면들. +U/+V 축은 각 면의 텍스처 좌표를 나타내며, 각 면의 texel copy 메모리 레이아웃도 의미합니다. 참고: 내부에서 보면 오른손 좌표계가 아닌 왼손 좌표계가 되며, +X는 오른쪽, +Y는 위, +Z는 앞쪽이 됩니다.
샘플링은 큐브맵의 모든 면에 걸쳐 매끄럽게 처리됩니다.
해당 WGSL 타입:
-
texture_cube
-
texture_depth_cube
-
"cube-array"
-
텍스처를 n개의 큐브맵 묶음 배열로 봅니다. 각각은 6개의 배열 레이어로 하나의
"cube"
뷰처럼 동작하며, 전체 배열 레이어 수는 6n입니다.해당 WGSL 타입:
-
texture_cube_array
-
texture_depth_cube_array
-
"3d"
-
텍스처를 3차원 이미지로 봅니다.
해당 WGSL 타입:
-
texture_3d
-
texture_storage_3d
-
각 GPUTextureAspect
값은 aspect 집합에 대응합니다.
아래 각 값에 대한 aspect 집합은 다음과 같이 정의됩니다.
enum GPUTextureAspect {"all" ,"stencil-only" ,"depth-only" , };
"all"
-
텍스처 포맷의 모든 사용 가능한 aspect가 텍스처 뷰에서 접근 가능합니다. 컬러 포맷의 경우 color aspect가 접근 가능하며, depth-stencil 결합 포맷은 depth와 stencil aspect 모두 접근 가능합니다. depth 또는 stencil 포맷 중 aspect가 하나뿐인 경우 해당 aspect만 접근 가능합니다.
"stencil-only"
-
depth 또는 stencil 포맷에서 stencil aspect만 텍스처 뷰에서 접근 가능합니다.
"depth-only"
-
depth 또는 stencil 포맷에서 depth aspect만 텍스처 뷰에서 접근 가능합니다.
createView(descriptor)
-
GPUTextureView
를 생성합니다.참고:기본적으로createView()
는 텍스처 전체를 표현할 수 있는 차원의 뷰를 생성합니다. 예를 들어,createView()
호출 시dimension
을 지정하지 않고 여러 레이어가 있는"2d"
텍스처에 대해 호출하면,"2d-array"
GPUTextureView
가 생성됩니다.arrayLayerCount
가 1이어도 마찬가지입니다.레이어 개수를 개발 시점에 알 수 없는 소스로 생성된 텍스처의 경우 셰이더 호환성을 위해
createView()
호출에 명시적으로dimension
을 지정하는 것이 권장됩니다.호출 대상:GPUTexture
this.인자:
GPUTexture.createView(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUTextureViewDescriptor
✘ ✔ 생성할 GPUTextureView
의 설명.반환값: view, 타입
GPUTextureView
.콘텐츠 타임라인 단계:
-
? 텍스처 포맷 필수 기능 검증(descriptor.
format
, this.[[device]]
). -
view를 ! 새 WebGPU 객체 생성(this,
GPUTextureView
, descriptor)로 둔다. -
this의 디바이스 타임라인에서 초기화 단계를 실행합니다.
-
view를 반환합니다.
디바이스 타임라인 초기화 단계:-
descriptor를 GPUTextureViewDescriptor 기본값 해석의 결과로 설정합니다 (this와 descriptor 사용).
-
아래 조건 중 하나라도 만족하지 않으면 검증 오류를 생성, view를 무효화하고 반환합니다.
-
this는 해당 디바이스와 사용 가능(valid to use with)해야 합니다. this.
[[device]]
. -
descriptor.
aspect
값이"all"
인 경우:-
descriptor.
format
값은 this.format
또는 this.[[viewFormats]]
중 하나여야 합니다.
그 외에는:
-
descriptor.
format
값은 GPUTextureAspect 해석의 결과와 같아야 합니다 (this.format
, descriptor.aspect
).
-
-
descriptor.
usage
값에RENDER_ATTACHMENT
비트가 포함된 경우:-
descriptor.
format
값은 렌더링 가능한 포맷이어야 합니다.
-
-
descriptor.
usage
값에STORAGE_BINDING
비트가 포함된 경우:-
descriptor.
format
값은 § 26.1.1 일반 컬러 포맷 테이블에STORAGE_BINDING
능력이 최소 한 access mode에서 있어야 합니다.
-
-
descriptor.
mipLevelCount
값은 0보다 커야 합니다. -
descriptor.
baseMipLevel
+ descriptor.mipLevelCount
값은 this.mipLevelCount
이하이어야 합니다. -
descriptor.
arrayLayerCount
값은 0보다 커야 합니다. -
descriptor.
baseArrayLayer
+ descriptor.arrayLayerCount
값은 array layer count 이하이어야 합니다 (this 기준). -
this.
sampleCount
값이 1보다 크면, descriptor.dimension
값은"2d"
여야 합니다. -
descriptor.
dimension
값이 다음 중 하나일 때:"1d"
-
-
descriptor.
arrayLayerCount
값은1
이어야 합니다.
"2d"
-
-
descriptor.
arrayLayerCount
값은1
이어야 합니다.
"2d-array"
"cube"
-
-
descriptor.
arrayLayerCount
값은6
이어야 합니다.
"cube-array"
-
-
descriptor.
arrayLayerCount
값은6
의 배수여야 합니다.
"3d"
-
-
descriptor.
arrayLayerCount
값은1
이어야 합니다.
-
-
view를 새로운
GPUTextureView
객체로 둔다. -
view.
[[texture]]
값을 this로 설정. -
view.
[[descriptor]]
값을 descriptor로 설정. -
descriptor.
usage
에RENDER_ATTACHMENT
가 포함된 경우:-
renderExtent를 compute render extent([this.
width
, this.height
, this.depthOrArrayLayers
], descriptor.baseMipLevel
)로 둔다. -
view.
[[renderExtent]]
값을 renderExtent로 설정.
-
-
GPUTextureView
texture와 GPUTextureViewDescriptor
descriptor를 대상으로 할 때, 아래 디바이스 타임라인 단계들을 실행한다:
-
resolved를 descriptor의 복사본으로 둔다.
-
resolved.
format
값이 제공되지 않은 경우: -
resolved.
mipLevelCount
값이 제공되지 않은 경우: resolved.mipLevelCount
를 texture.mipLevelCount
− resolved.baseMipLevel
로 설정. -
resolved.
dimension
값이 제공되지 않은 경우이고, texture.dimension
이 다음 중 하나일 때: -
resolved.
arrayLayerCount
값이 제공되지 않은 경우이고, resolved.dimension
값이 다음 중 하나일 때:"1d"
,"2d"
, 또는"3d"
-
resolved.
arrayLayerCount
를1
로 설정. "cube"
-
resolved.
arrayLayerCount
를6
으로 설정. "2d-array"
또는"cube-array"
-
resolved.
arrayLayerCount
를 texture의 array layer count − resolved.baseArrayLayer
로 설정.
-
resolved를 반환.
GPUTexture
texture의 array layer count를 결정하려면
아래 단계를 수행합니다:
-
texture.
dimension
값이 다음 중 하나일 때:"1d"
또는"3d"
-
1
반환. "2d"
-
texture.
depthOrArrayLayers
반환.
6.3. 텍스처 포맷
포맷의 이름은 컴포넌트의 순서, 컴포넌트당 비트 수, 그리고 컴포넌트의 데이터 타입을 지정합니다.
-
r
,g
,b
,a
= 빨강, 녹색, 파랑, 알파 -
unorm
= 부호 없는 정규화 -
snorm
= 부호 있는 정규화 -
uint
= 부호 없는 정수 -
sint
= 부호 있는 정수 -
float
= 부동 소수점
포맷에 -srgb
접미사가 있으면, 셰이더에서 색상 값을 읽고 쓸 때 sRGB 변환(감마와 선형 변환)이 적용됩니다. 압축 텍스처 포맷은 기능으로 제공됩니다. 명명 규칙은 여기의 관례를 따라야 하며, 텍스처
이름을 접두사로 사용합니다. 예시:
etc2-rgba8unorm
.
텍셀 블록은 픽셀 기반 GPUTextureFormat
텍스처의 단일 주소 지정 가능한 요소이자,
블록 기반 압축 GPUTextureFormat
텍스처의 단일 압축 블록입니다.
텍셀 블록 너비와 텍셀 블록 높이는 하나의 텍셀 블록의 가로, 세로 차원을 지정합니다.
-
픽셀 기반
GPUTextureFormat
의 경우, 텍셀 블록 너비와 텍셀 블록 높이는 항상 1입니다. -
블록 기반 압축
GPUTextureFormat
의 경우, 텍셀 블록 너비는 하나의 텍셀 블록의 각 행에 있는 텍셀 수이고, 텍셀 블록 높이는 하나의 텍셀 블록의 행 수입니다. 각 텍스처 포맷별 값은 § 26.1 텍스처 포맷 지원에서 확인하세요.
텍셀 블록 복사
풋프린트는 aspect별
GPUTextureFormat
에 대해, 텍셀 복사 시 하나의 텍셀 블록이 차지하는 바이트
수입니다(해당 시).
참고:
텍셀 블록 메모리 비용은
GPUTextureFormat
별로 하나의 텍셀 블록을 저장하는 데 필요한 바이트 수입니다.
모든 포맷에 대해 완전히 정의된 값은 아닙니다.
이 값은 안내용이며, 표준적인 값이 아닙니다.
enum { // 8비트 포맷
GPUTextureFormat ,
"r8unorm" ,
"r8snorm" ,
"r8uint" , // 16비트 포맷
"r8sint" ,
"r16unorm" ,
"r16snorm" ,
"r16uint" ,
"r16sint" ,
"r16float" ,
"rg8unorm" ,
"rg8snorm" ,
"rg8uint" , // 32비트 포맷
"rg8sint" ,
"r32uint" ,
"r32sint" ,
"r32float" ,
"rg16unorm" ,
"rg16snorm" ,
"rg16uint" ,
"rg16sint" ,
"rg16float" ,
"rgba8unorm" ,
"rgba8unorm-srgb" ,
"rgba8snorm" ,
"rgba8uint" ,
"rgba8sint" ,
"bgra8unorm" , // Packed 32비트 포맷
"bgra8unorm-srgb" ,
"rgb9e5ufloat" ,
"rgb10a2uint" ,
"rgb10a2unorm" , // 64비트 포맷
"rg11b10ufloat" ,
"rg32uint" ,
"rg32sint" ,
"rg32float" ,
"rgba16unorm" ,
"rgba16snorm" ,
"rgba16uint" ,
"rgba16sint" , // 128비트 포맷
"rgba16float" ,
"rgba32uint" ,
"rgba32sint" , // 깊이/스텐실 포맷
"rgba32float" ,
"stencil8" ,
"depth16unorm" ,
"depth24plus" ,
"depth24plus-stencil8" , // "depth32float-stencil8" 기능
"depth32float" , // 디바이스/사용자 에이전트가 "texture-compression-bc"를 지원 & requestDevice에서 활성화된 경우 사용 가능한 BC 압축 포맷
"depth32float-stencil8" ,
"bc1-rgba-unorm" ,
"bc1-rgba-unorm-srgb" ,
"bc2-rgba-unorm" ,
"bc2-rgba-unorm-srgb" ,
"bc3-rgba-unorm" ,
"bc3-rgba-unorm-srgb" ,
"bc4-r-unorm" ,
"bc4-r-snorm" ,
"bc5-rg-unorm" ,
"bc5-rg-snorm" ,
"bc6h-rgb-ufloat" ,
"bc6h-rgb-float" ,
"bc7-rgba-unorm" , // 디바이스/사용자 에이전트가 "texture-compression-etc2"를 지원 & requestDevice에서 활성화된 경우 사용 가능한 ETC2 압축 포맷
"bc7-rgba-unorm-srgb" ,
"etc2-rgb8unorm" ,
"etc2-rgb8unorm-srgb" ,
"etc2-rgb8a1unorm" ,
"etc2-rgb8a1unorm-srgb" ,
"etc2-rgba8unorm" ,
"etc2-rgba8unorm-srgb" ,
"eac-r11unorm" ,
"eac-r11snorm" ,
"eac-rg11unorm" , // 디바이스/사용자 에이전트가 "texture-compression-astc"를 지원 & requestDevice에서 활성화된 경우 사용 가능한 ASTC 압축 포맷
"eac-rg11snorm" ,
"astc-4x4-unorm" ,
"astc-4x4-unorm-srgb" ,
"astc-5x4-unorm" ,
"astc-5x4-unorm-srgb" ,
"astc-5x5-unorm" ,
"astc-5x5-unorm-srgb" ,
"astc-6x5-unorm" ,
"astc-6x5-unorm-srgb" ,
"astc-6x6-unorm" ,
"astc-6x6-unorm-srgb" ,
"astc-8x5-unorm" ,
"astc-8x5-unorm-srgb" ,
"astc-8x6-unorm" ,
"astc-8x6-unorm-srgb" ,
"astc-8x8-unorm" ,
"astc-8x8-unorm-srgb" ,
"astc-10x5-unorm" ,
"astc-10x5-unorm-srgb" ,
"astc-10x6-unorm" ,
"astc-10x6-unorm-srgb" ,
"astc-10x8-unorm" ,
"astc-10x8-unorm-srgb" ,
"astc-10x10-unorm" ,
"astc-10x10-unorm-srgb" ,
"astc-12x10-unorm" ,
"astc-12x10-unorm-srgb" ,
"astc-12x12-unorm" , };
"astc-12x12-unorm-srgb"
"depth24plus"
및 "depth24plus-stencil8"
포맷의 깊이 컴포넌트는 24비트 깊이 값 또는 "depth32float"
값으로 구현될 수 있습니다.
stencil8
포맷은 실제 "stencil8" 또는 "depth24stencil8"로 구현될 수 있으며, 이 경우 깊이 aspect는 숨겨지고 접근할 수 없습니다.
-
24비트 깊이의 경우, 1 ULP는 항상 1 / (224 − 1)입니다.
-
depth32float의 경우, 1 ULP는 변동값이며 최대 1 / (224)를 초과하지 않습니다.
포맷이 렌더링 가능하려면 컬러 렌더링 포맷이거나 깊이/스텐실 포맷이어야 합니다.
만약 해당 포맷이 § 26.1.1 일반 컬러 포맷에 RENDER_ATTACHMENT
기능으로 나열되어 있다면, 컬러 렌더링 포맷입니다. 그렇지 않은 포맷은 컬러 렌더링 포맷이 아닙니다.
모든 깊이/스텐실
포맷은 렌더링 가능합니다.
렌더링 가능 포맷은 블렌딩 가능 포맷이기도 하며, 렌더 파이프라인 블렌딩에 사용할 수 있습니다. 자세한 내용은 § 26.1 텍스처 포맷 지원을 참고하세요.
포맷이 필터링 가능하려면,
GPUTextureSampleType
"float"
(단순 "unfilterable-float"
만이
아니라)
를 지원해야 하며,
"filtering"
GPUSampler
에
사용할 수 있어야 합니다.
자세한 내용은 § 26.1 텍스처 포맷 지원을 참고하세요.
인자:
-
GPUTextureFormat
format -
GPUTextureAspect
aspect
반환값: GPUTextureFormat
또는 null
-
aspect가 다음 중 하나일 때:
"all"
-
format 반환.
"depth-only"
"stencil-only"
-
format이 깊이-스텐실 포맷이면: aspect별 포맷을 § 26.1.2 깊이-스텐실 포맷에 따라 반환하거나, 해당 aspect가 format에 없으면
null
반환.
-
null
반환.
일부 텍스처 포맷을 사용하려면 GPUDevice
에서 기능을 활성화해야 합니다.
새로운 포맷이 명세에 추가될 수 있으므로, 해당 enum 값이 구현체에 알려지지 않을 수 있습니다.
모든 구현에서 동작을 일관성 있게 만들기 위해, 기능이 필요한 포맷을 기능을 활성화하지 않은 디바이스에서 사용하려 하면 예외가 발생합니다.
이는 포맷이 구현체에 알려지지 않았을 때와 같은 동작을 보장합니다.
어떤 GPUTextureFormat
이
기능을 필요로 하는지는 § 26.1 텍스처 포맷 지원을 참고하세요.
GPUTextureFormat
format,논리적 device device):
-
format이 기능을 필요로 하는데 device.
[[features]]
에 해당 기능이 포함되지 않은 경우:-
TypeError
를 throw합니다.
-
6.4. GPUExternalTexture
GPUExternalTexture
는 외부 비디오 프레임을 래핑한 샘플링 가능한 2D 텍스처입니다.
이는 불변 스냅샷으로, WebGPU 내부에서(샘플링만 가능)든 외부에서(예: 비디오 프레임 진행 등)든 시간이 지나도 내용이 변하지 않습니다.
GPUExternalTexture
는
externalTexture
바인드 그룹 레이아웃 엔트리 멤버를 통해 바인드 그룹에 바인딩할 수 있습니다.
해당 멤버는 여러 바인딩 슬롯을 사용하니 주의하세요.
GPUExternalTexture
는 임포트된 소스의 복사본을 생성하지 않고도 구현될 수 있지만,
이는 구현의 정의에 따라 달라집니다.
내부 표현의 소유권은 단독일 수도 있고(예: 비디오 디코더 등) 다른 소유자와 공유될 수도 있지만, 애플리케이션에서는 볼 수 없습니다.
외부 텍스처의 내부 표현은(정밀 샘플링 동작을 제외하면) 관측할 수 없으나, 일반적으로 다음을 포함할 수 있습니다:
-
최대 3개의 2D 데이터 평면(RGBA, Y+UV, Y+U+V 등)
-
해당 평면을 읽기 전에 좌표 변환(크롭, 회전 등)을 위한 메타데이터
-
지정된 출력 색공간으로 값을 변환하기 위한 메타데이터(행렬, 감마, 3D LUT)
구현체 내부의 구성 방식은 시간, 시스템, 사용자 에이전트, 미디어 소스, 심지어 단일 비디오 소스의 각 프레임마다 일관되지 않을 수 있습니다. 다양한 표현에 대응하기 위해, 각 외부 텍스처마다 아래와 같이 보수적으로 바인딩합니다:
-
최대 3개의 평면 샘플링 텍스처 바인딩
-
3D LUT용 샘플링 텍스처 바인딩 1개
-
3D LUT 샘플링용 샘플러 바인딩 1개
-
메타데이터용 uniform buffer 바인딩 1개
[Exposed =(Window ,Worker ),SecureContext ]interface GPUExternalTexture { };GPUExternalTexture includes GPUObjectBase ;
GPUExternalTexture
는 다음 불변 속성을 가집니다:
[[descriptor]]
, 타입GPUExternalTextureDescriptor
, 읽기 전용-
텍스처 생성에 사용된 descriptor입니다.
GPUExternalTexture
는 다음 불변 속성을 가집니다:
[[expired]]
, 타입boolean
, 초기값false
-
객체가 만료되어 더 이상 사용할 수 없는지 여부를 나타냅니다.
참고:
[[destroyed]]
슬롯과 유사하지만, 이 값은true
에서false
로 다시 바뀔 수 있습니다.
6.4.1. 외부 텍스처 가져오기
외부 텍스처는 외부 비디오 객체에서 importExternalTexture()
를
사용해 생성됩니다.
HTMLVideoElement
에서
생성된 외부 텍스처는
가져온 후 작업에서 자동으로 만료(소멸)되며, 다른 리소스처럼 수동이나 가비지 컬렉션 시 소멸되지 않습니다.
외부 텍스처가 만료되면 [[expired]]
슬롯이 true
로 바뀝니다.
VideoFrame
에서
생성된 외부 텍스처는,
소스 VideoFrame
이
닫혔을 때(명시적으로 close()
로,
또는 다른 방법으로)만 만료(소멸)됩니다.
참고: decode()
에
설명된 대로,
작성자는 디코더 정지를 피하기 위해 출력 VideoFrame
에
대해 반드시
close()
를
호출해야 합니다.
가져온 VideoFrame
이
닫히지 않고 버려지면,
가져온 GPUExternalTexture
객체가 VideoFrame을 살아있게 유지합니다.
두 객체 모두 버려질 때까지 VideoFrame
은
가비지 컬렉션되지 않습니다.
가비지 컬렉션은 예측 불가능하므로, 이것이 비디오 디코더를 지연시킬 수 있습니다.
GPUExternalTexture
가 만료되면 importExternalTexture()
를
다시 호출해야 합니다.
하지만 사용자 에이전트가 만료 상태를 해제하고 새로운 객체를 만들지 않고 같은 GPUExternalTexture
를
다시 반환할 수 있습니다.
이는 일반적으로 애플리케이션 실행이 비디오 프레임률과 맞춰 스케줄되지 않는 경우(예: requestVideoFrameCallback()
사용 등)에 발생합니다.
같은 객체가 다시 반환되면 이전 객체와 동등 비교가 가능하며, GPUBindGroup
,
GPURenderBundle
등에서 이전 객체를 계속 사용할 수 있습니다.
dictionary :
GPUExternalTextureDescriptor GPUObjectDescriptorBase {required (HTMLVideoElement or VideoFrame )source ;PredefinedColorSpace colorSpace = "srgb"; };
GPUExternalTextureDescriptor
딕셔너리는 다음 멤버를 가집니다:
source
, 타입(HTMLVideoElement or VideoFrame)
-
외부 텍스처를 가져올 비디오 소스입니다. 소스 크기는 외부 소스 크기 표에 따라 결정됩니다.
colorSpace
, 타입 PredefinedColorSpace, 기본값"srgb"
-
source
의 이미지 내용을 읽을 때 변환할 색 공간입니다.
importExternalTexture(descriptor)
-
제공된 이미지 소스를 래핑하는
GPUExternalTexture
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.importExternalTexture(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUExternalTextureDescriptor
✘ ✘ 외부 이미지 소스 객체(및 생성 옵션)를 제공합니다. 반환값:
GPUExternalTexture
콘텐츠 타임라인 단계:
-
source를 descriptor.
source
로 둔다. -
현재 source의 이미지 내용이 같은 descriptor(
label
제외)로 가장 최근에importExternalTexture()
를 호출한 결과와 동일하고, 사용자 에이전트가 재사용을 선택한 경우:-
previousResult를 이전에 반환된
GPUExternalTexture
로 둔다. -
previousResult.
[[expired]]
를false
로 설정하여, 하부 리소스 소유권을 갱신한다. -
result를 previousResult로 둔다.
참고: 이는 애플리케이션이 중복 import를 감지하고 종속 객체(
GPUBindGroup
등)를 다시 생성하지 않을 수 있게 해줍니다. 구현은 동일 프레임이 여러GPUExternalTexture
로 래핑되는 경우도 처리해야 하며, import 메타데이터(colorSpace
등)는 동일 프레임에도 달라질 수 있습니다.그 외에는:
-
source가 origin-clean하지 않으면,
SecurityError
를 throw하고 반환. -
usability를 ? 이미지 인자 사용 가능 여부 확인(source)로 둔다.
-
usability가
good
이 아니면:-
무효화된
GPUExternalTexture
를 반환.
-
data를 source의 현재 이미지 내용을 descriptor.
colorSpace
색 공간으로, unpremultiplied alpha로 변환한 결과로 둔다.이는 범위 [0, 1]을 벗어날 수 있습니다. 클램핑이 필요하다면 샘플링 후 별도로 수행할 수 있습니다.
참고: 복사처럼 서술되었지만, 읽기 전용 하부 데이터 참조와 변환용 메타데이터로 구현될 수도 있습니다.
-
result를 data를 래핑하는 새로운
GPUExternalTexture
객체로 둔다.
-
-
source가
HTMLVideoElement
이면, 자동 만료 작업 큐잉(디바이스 this 및 다음 단계 포함):-
result.
[[expired]]
를true
로 설정하여 하부 리소스 소유권 해제.
참고:
HTMLVideoElement
는 텍스처 샘플링과 같은 작업 내에서 import되어야 하며 (일반적으로requestVideoFrameCallback
또는 애플리케이션에 따라requestAnimationFrame()
사용), 그렇지 않으면 텍스처가 애플리케이션에서 사용되기 전에 소멸될 수 있습니다. -
-
source가
VideoFrame
이면, source가 닫힐 때 다음 단계를 실행:-
result.
[[expired]]
를true
로 설정.
-
-
result를 반환.
-
const videoElement= document. createElement( 'video' ); // ... videoElement를 설정하고, 준비될 때까지 대기 ... function frame() { requestAnimationFrame( frame); // 매 애니메이션 프레임마다 항상 비디오를 다시 import해야 함(import가 만료되었을 수 있음) // 브라우저가 이전 프레임을 캐시 및 재사용할 수 있고, 이 경우 동일한 GPUExternalTexture 객체를 다시 반환할 수 있음 // 이 경우 기존 바인드 그룹도 여전히 유효함 const externalTexture= gpuDevice. importExternalTexture({ source: videoElement}); // ... externalTexture를 사용해 렌더링 ... } requestAnimationFrame( frame);
requestVideoFrameCallback
이 사용 가능하면 비디오 프레임 속도에 맞춰 비디오 요소 외부 텍스처로 렌더링:
const videoElement= document. createElement( 'video' ); // ... videoElement 설정 ... function frame() { videoElement. requestVideoFrameCallback( frame); // 프레임이 진행된 것을 알기 때문에 항상 재-import const externalTexture= gpuDevice. importExternalTexture({ source: videoElement}); // ... externalTexture를 사용해 렌더링 ... } videoElement. requestVideoFrameCallback( frame);
6.5. 외부 텍스처 바인딩 샘플링
externalTexture
바인딩 포인트는 GPUExternalTexture
객체(비디오 등 동적 이미지 소스)를 바인딩할 수 있습니다. 또한 GPUTexture
및
GPUTextureView
도
지원합니다.
참고:
GPUTexture
또는 GPUTextureView
를
externalTexture
바인딩에 바인딩하면,
crop/회전/색상 변환 없이 단일 RGBA 평면을 가진 GPUExternalTexture
처럼
동작합니다.
외부 텍스처는 WGSL에서 texture_external
로 표현되며, textureLoad
와
textureSampleBaseClampToEdge
로 읽을 수 있습니다.
textureSampleBaseClampToEdge
에 제공된 sampler
는 하부 텍스처 샘플링에 사용됩니다.
바인딩 리소스 타입이
GPUExternalTexture
일
경우,
결과는 colorSpace
로
설정된 색 공간에 있습니다.
샘플러(및 필터링)가 하부 값에서 지정된 색 공간으로 변환되기 전 또는 후에 적용되는지는 구현에 따라 다릅니다.
참고: 내부 표현이 RGBA 평면이면 샘플링은 일반 2D 텍스처처럼 동작합니다. 여러 하부 평면(Y+UV 등)이 있으면, 샘플러가 각 하부 텍스처를 개별적으로 샘플링한 뒤 YUV→색 공간 변환이 진행됩니다.
7. 샘플러
7.1. GPUSampler
GPUSampler
는 셰이더에서 텍스처 리소스 데이터를 해석하는 데 사용할 변환 및 필터링 정보를 인코딩합니다.
GPUSampler
는
createSampler()
로
생성합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUSampler { };GPUSampler includes GPUObjectBase ;
GPUSampler
는 다음 불변 속성을 가집니다:
[[descriptor]]
, 타입GPUSamplerDescriptor
, 읽기 전용-
GPUSamplerDescriptor
로GPUSampler
를 생성했습니다. [[isComparison]]
, 타입boolean
, 읽기 전용-
GPUSampler
가 비교 샘플러로 사용되는지 여부입니다. [[isFiltering]]
, 타입boolean
, 읽기 전용-
GPUSampler
가 텍스처의 여러 샘플에 가중치를 두는지 여부입니다.
7.1.1. GPUSamplerDescriptor
GPUSamplerDescriptor
는 GPUSampler
생성 시 사용할 옵션을 지정합니다.
dictionary :
GPUSamplerDescriptor GPUObjectDescriptorBase {GPUAddressMode addressModeU = "clamp-to-edge";GPUAddressMode addressModeV = "clamp-to-edge";GPUAddressMode addressModeW = "clamp-to-edge";GPUFilterMode magFilter = "nearest";GPUFilterMode minFilter = "nearest";GPUMipmapFilterMode mipmapFilter = "nearest";float lodMinClamp = 0;float lodMaxClamp = 32;GPUCompareFunction compare ; [Clamp ]unsigned short maxAnisotropy = 1; };
addressModeU
, 타입 GPUAddressMode, 기본값"clamp-to-edge"
addressModeV
, 타입 GPUAddressMode, 기본값"clamp-to-edge"
addressModeW
, 타입 GPUAddressMode, 기본값"clamp-to-edge"
-
텍스처의 너비, 높이, 깊이 좌표 각각에 대한
address mode
를 지정합니다. magFilter
, 타입 GPUFilterMode, 기본값"nearest"
-
샘플링 영역이 텍셀 하나보다 작거나 같을 때의 샘플링 동작을 지정합니다.
minFilter
, 타입 GPUFilterMode, 기본값"nearest"
-
샘플링 영역이 텍셀 하나보다 클 때의 샘플링 동작을 지정합니다.
mipmapFilter
, 타입 GPUMipmapFilterMode, 기본값"nearest"
-
mipmap 레벨 간 샘플링 동작을 지정합니다.
lodMinClamp
, 타입 float, 기본값0
lodMaxClamp
, 타입 float, 기본값32
-
텍스처 샘플링 시 내부적으로 사용되는 상세 레벨(LOD)의 최소/최대값을 지정합니다.
compare
, 타입 GPUCompareFunction-
지정 시 해당
GPUCompareFunction
을 사용하는 비교 샘플러가 됩니다.참고: 비교 샘플러도 필터링을 사용할 수 있지만, 샘플링 결과는 구현에 따라 달라지며 일반 필터링 규칙과 다를 수 있습니다.
maxAnisotropy
, 타입 unsigned short, 기본값1
-
샘플러에서 사용할 최대 이방성값 클램프를 지정합니다.
maxAnisotropy
가 1보다 크고 구현이 지원하는 경우 이방성 필터링이 활성화됩니다.이방성 필터링은 비스듬히 보는 텍스처의 이미지 품질을 향상시킵니다.
maxAnisotropy
가 클수록 필터링 시 지원되는 최대 이방성 비율을 의미합니다.참고:대부분의 구현은maxAnisotropy
값으로 1~16 범위를 지원합니다. 실제로 사용되는maxAnisotropy
값은 플랫폼이 지원하는 최대값으로 클램프됩니다.정확한 필터링 동작은 구현에 따라 다릅니다.
상세 레벨(Level of detail, LOD)은 텍스처 샘플링 시 어떤 mip 레벨을 선택하는지 나타내며, 셰이더의 textureSampleLevel 등으로 명시하거나 텍스처 좌표 미분값으로 암시적으로 결정될 수 있습니다.
참고: 암시적 LOD 계산 예시는 Vulkan 1.3: Scale Factor Operation, LOD Operation and Image Level Selection을 참고하세요.
GPUAddressMode
는 샘플링한 텍셀이 텍스처 경계를 벗어났을 때의 샘플러 동작을 지정합니다.
enum {
GPUAddressMode "clamp-to-edge" ,"repeat" ,"mirror-repeat" , };
"clamp-to-edge"
-
텍스처 좌표를 0.0~1.0 사이로 클램프합니다.
"repeat"
-
텍스처 좌표가 텍스처 반대편으로 래핑됩니다.
"mirror-repeat"
-
텍스처 좌표가 텍스처 반대편으로 래핑되지만, 좌표의 정수 부분이 홀수일 때 텍스처가 뒤집힙니다.
GPUFilterMode
와 GPUMipmapFilterMode
는 샘플링 영역이 정확히 한 텍셀만을 포함하지 않을 때의 동작을 지정합니다.
참고: 각 필터링 모드에서 어떤 텍셀이 샘플링되는지에 대한 예시는 Vulkan 1.3: Texel Filtering을 참고하세요.
enum {
GPUFilterMode "nearest" ,"linear" , };enum {
GPUMipmapFilterMode ,
"nearest" , };
"linear"
"nearest"
-
텍스처 좌표에 가장 가까운 텍셀의 값을 반환합니다.
"linear"
-
각 차원마다 두 텍셀을 선택하고 값의 선형 보간을 반환합니다.
GPUCompareFunction
은 비교 샘플러의 동작을 지정합니다. 셰이더에서 비교 샘플러를 사용하면 depth_ref
가 가져온 텍셀 값과 비교되어, 비교 결과(1.0f
는 통과,
0.0f
는 실패)가 생성됩니다.
비교 후 텍스처 필터링이 활성화된 경우, 필터링 단계에서 비교 결과가 혼합되어 [0, 1]
범위의 값이 생성됩니다. 필터링은 일반적으로 평소와
동일하게 동작하지만, 구현에 따라 정밀도가 낮거나 아예 혼합이 없을 수도 있습니다.
enum {
GPUCompareFunction "never" ,"less" ,"equal" ,"less-equal" ,"greater" ,"not-equal" ,"greater-equal" ,"always" , };
"never"
-
비교 테스트가 절대 통과하지 않습니다.
"less"
-
제공된 값이 샘플링된 값보다 작으면 비교 테스트를 통과합니다.
"equal"
-
제공된 값이 샘플링된 값과 같으면 비교 테스트를 통과합니다.
"less-equal"
-
제공된 값이 샘플링된 값 이하이면 비교 테스트를 통과합니다.
"greater"
-
제공된 값이 샘플링된 값보다 크면 비교 테스트를 통과합니다.
"not-equal"
-
제공된 값이 샘플링된 값과 다르면 비교 테스트를 통과합니다.
"greater-equal"
-
제공된 값이 샘플링된 값 이상이면 비교 테스트를 통과합니다.
"always"
-
비교 테스트가 항상 통과합니다.
7.1.2. 샘플러 생성
createSampler(descriptor)
-
GPUSampler
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createSampler(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUSamplerDescriptor
✘ ✔ 생성할 GPUSampler
의 설명.반환값:
GPUSampler
콘텐츠 타임라인 단계:
-
s를 ! 새 WebGPU 객체 생성(this,
GPUSampler
, descriptor)로 둔다. -
this의 디바이스 타임라인에서 초기화 단계를 실행합니다.
-
s를 반환합니다.
디바이스 타임라인 초기화 단계:-
다음 조건 중 하나라도 만족하지 않으면 검증 오류 생성, s를 무효화하고 반환합니다.
-
this는 손실(lost) 상태가 아니어야 합니다.
-
descriptor.
lodMinClamp
≥ 0이어야 합니다. -
descriptor.
lodMaxClamp
≥ descriptor.lodMinClamp
이어야 합니다. -
descriptor.
maxAnisotropy
≥ 1이어야 합니다.참고: 대부분의 구현은
maxAnisotropy
값으로 1~16 범위를 지원합니다. 지정값은 플랫폼이 지원하는 최대값으로 클램프됩니다. -
descriptor.
maxAnisotropy
> 1일 때:-
descriptor.
magFilter
, descriptor.minFilter
, descriptor.mipmapFilter
모두"linear"
여야 합니다.
-
-
-
s.
[[descriptor]]
를 descriptor로 설정합니다. -
s.
[[isComparison]]
는 s.[[descriptor]]
의compare
속성이null
또는 undefined이면false
, 아니면true
로 설정합니다. -
s.
[[isFiltering]]
는minFilter
,magFilter
,mipmapFilter
중 어느 것도"linear"
값이 없으면false
로, 있으면true
로 설정합니다.
-
GPUSampler
생성 예시:
const sampler= gpuDevice. createSampler({ addressModeU: 'repeat' , addressModeV: 'repeat' , magFilter: 'linear' , minFilter: 'linear' , mipmapFilter: 'linear' , });
8. 리소스 바인딩
8.1. GPUBindGroupLayout
GPUBindGroupLayout
은 GPUBindGroup
에
바인딩되는 리소스 집합과 셰이더 단계에서의 접근성 사이의 인터페이스를 정의합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUBindGroupLayout { };GPUBindGroupLayout includes GPUObjectBase ;
GPUBindGroupLayout
은 다음 불변 속성을 가집니다:
[[descriptor]]
, 타입GPUBindGroupLayoutDescriptor
, 읽기 전용
8.1.1. 바인드 그룹 레이아웃 생성
GPUBindGroupLayout
은 GPUDevice.createBindGroupLayout()
로
생성됩니다.
dictionary :
GPUBindGroupLayoutDescriptor GPUObjectDescriptorBase {required sequence <GPUBindGroupLayoutEntry >entries ; };
GPUBindGroupLayoutDescriptor
딕셔너리는 다음 멤버를 가집니다:
entries
, 타입 sequence<GPUBindGroupLayoutEntry>-
바인드 그룹의 셰이더 리소스 바인딩을 기술하는 엔트리 목록입니다.
GPUBindGroupLayoutEntry
는 GPUBindGroupLayout
에
포함되는 단일 셰이더 리소스 바인딩을 설명합니다.
dictionary {
GPUBindGroupLayoutEntry required GPUIndex32 binding ;required GPUShaderStageFlags visibility ;GPUBufferBindingLayout buffer ;GPUSamplerBindingLayout sampler ;GPUTextureBindingLayout texture ;GPUStorageTextureBindingLayout storageTexture ;GPUExternalTextureBindingLayout externalTexture ; };
GPUBindGroupLayoutEntry
딕셔너리는 다음 멤버를 가집니다:
binding
, 타입 GPUIndex32-
해당
GPUBindGroupLayout
내 리소스 바인딩의 고유 식별자이며,GPUBindGroupEntry.binding
및 @binding 속성과 대응됩니다. visibility
, 타입 GPUShaderStageFlags-
GPUShaderStage
멤버들의 비트셋입니다. 각 설정된 비트는GPUBindGroupLayoutEntry
의 리소스가 해당 셰이더 단계에서 접근 가능함을 나타냅니다. buffer
, 타입 GPUBufferBindingLayoutsampler
, 타입 GPUSamplerBindingLayouttexture
, 타입 GPUTextureBindingLayoutstorageTexture
, 타입 GPUStorageTextureBindingLayoutexternalTexture
, 타입 GPUExternalTextureBindingLayout-
이 멤버 중 반드시 하나만 설정해야 하며, 바인딩 타입을 나타냅니다. 해당 멤버의 내용은 타입별 옵션을 지정합니다.
createBindGroup()
의 해당 리소스는 이 바인딩에 대해 바인딩 리소스 타입을 가져야 합니다.
typedef [EnforceRange ]unsigned long ; [
GPUShaderStageFlags Exposed =(Window ,Worker ),SecureContext ]namespace {
GPUShaderStage const GPUFlagsConstant VERTEX = 0x1;const GPUFlagsConstant FRAGMENT = 0x2;const GPUFlagsConstant COMPUTE = 0x4; };
GPUShaderStage
에는 해당 GPUBindGroupEntry
가
이 GPUBindGroupLayoutEntry
에
대해 어느 셰이더 단계에서 보이는지 설명하는 다음 플래그가 포함되어 있습니다:
VERTEX
-
바인드 그룹 엔트리가 버텍스 셰이더에서 접근할 수 있습니다.
FRAGMENT
-
바인드 그룹 엔트리가 프래그먼트 셰이더에서 접근할 수 있습니다.
COMPUTE
-
바인드 그룹 엔트리가 컴퓨트 셰이더에서 접근할 수 있습니다.
GPUBindGroupLayoutEntry
의
binding member는
GPUBindGroupLayoutEntry
의
어떤 멤버가 정의되었는지에 따라 결정됩니다:
buffer
,
sampler
,
texture
,
storageTexture
,
또는
externalTexture
.
하나의 GPUBindGroupLayoutEntry
에는
반드시 하나만 정의될 수 있습니다.
각 멤버는 관련 GPUBindingResource
타입을 가지며, 각 binding type은
관련 internal usage를 가지며, 아래
표에 정리되어 있습니다:
GPUBindGroupLayoutEntry
값 entries가
바인딩 슬롯 한도 초과한 경우는
지원 한도
limits에서 해당 한도를 초과하여 슬롯이 사용된 경우입니다.
각 entry는 여러 한도에 대해 여러 슬롯을 사용할 수 있습니다.
디바이스 타임라인 단계:
-
entries의 각 entry에 대해, 만약:
- entry.
buffer
?.type
값이"uniform"
이고, entry.buffer
?.hasDynamicOffset
값이true
이면 -
1개의
maxDynamicUniformBuffersPerPipelineLayout
슬롯을 사용한 것으로 간주. - entry.
buffer
?.type
값이"storage"
이고, entry.buffer
?.hasDynamicOffset
값이true
이면 -
1개의
maxDynamicStorageBuffersPerPipelineLayout
슬롯을 사용한 것으로 간주.
- entry.
-
각 셰이더 단계 stage in «
VERTEX
,FRAGMENT
,COMPUTE
»:-
entries의 각 entry 중 entry.
visibility
값에 stage가 포함된 경우, 만약:- entry.
buffer
?.type
값이"uniform"
이면 -
1개의
maxUniformBuffersPerShaderStage
슬롯을 사용한 것으로 간주. - entry.
buffer
?.type
값이"storage"
또는"read-only-storage"
이면 -
1개의
maxStorageBuffersPerShaderStage
슬롯을 사용한 것으로 간주. - entry.
sampler
값이 제공됨이면 -
1개의
maxSamplersPerShaderStage
슬롯을 사용한 것으로 간주. - entry.
texture
값이 제공됨이면 -
1개의
maxSampledTexturesPerShaderStage
슬롯을 사용한 것으로 간주. - entry.
storageTexture
값이 제공됨이면 -
1개의
maxStorageTexturesPerShaderStage
슬롯을 사용한 것으로 간주. - entry.
externalTexture
값이 제공됨이면 -
4개의
maxSampledTexturesPerShaderStage
슬롯, 1개의maxSamplersPerShaderStage
슬롯, 1개의maxUniformBuffersPerShaderStage
슬롯을 사용한 것으로 간주.참고: 이 동작의 설명은
GPUExternalTexture
를 참고.
- entry.
-
enum {
GPUBufferBindingType ,
"uniform" ,
"storage" , };
"read-only-storage" dictionary {
GPUBufferBindingLayout GPUBufferBindingType type = "uniform";boolean hasDynamicOffset =false ;GPUSize64 minBindingSize = 0; };
GPUBufferBindingLayout
딕셔너리는 다음 멤버를 가집니다:
type
, 타입 GPUBufferBindingType, 기본값"uniform"
-
이 바인딩에 연결되는 버퍼가 요구하는 타입을 나타냅니다.
hasDynamicOffset
, 타입 boolean, 기본값false
-
이 바인딩이 동적 오프셋을 요구하는지 여부를 나타냅니다.
minBindingSize
, 타입 GPUSize64, 기본값0
-
이 바인딩 포인트에서 사용되는 버퍼 바인딩의 최소
size
를 나타냅니다.바인딩은
createBindGroup()
에서 항상 이 크기에 대해 검증됩니다.이 값이 0이 아니면 파이프라인 생성 시 추가로 검증되며, 해당 값이 변수의 최소 버퍼 바인딩 크기 이상이어야 합니다.
이 값이 0이면 파이프라인 생성에서는 무시되고, draw/dispatch 명령에서 바인드 그룹 검증 시 각 바인딩이 변수의 최소 버퍼 바인딩 크기를 만족하는지 확인합니다.
참고: 실행 시점 검증은 이른 검증이 요구되는 다른 바인딩 관련 필드(예:
sampleType
및format
)에도 이론적으로 적용 가능하지만, 현재는 파이프라인 생성에서만 검증됩니다. 이러한 실행 시점 검증은 비용이 크거나 불필요하게 복잡할 수 있으므로, 가장 실용적 영향이 큰minBindingSize
에만 적용됩니다.
enum {
GPUSamplerBindingType ,
"filtering" ,
"non-filtering" , };
"comparison" dictionary {
GPUSamplerBindingLayout GPUSamplerBindingType type = "filtering"; };
GPUSamplerBindingLayout
딕셔너리는 다음 멤버를 가집니다:
type
, 타입 GPUSamplerBindingType, 기본값"filtering"
-
이 바인딩에 연결되는 샘플러가 요구하는 타입을 나타냅니다.
enum {
GPUTextureSampleType ,
"float" ,
"unfilterable-float" ,
"depth" ,
"sint" , };
"uint" dictionary {
GPUTextureBindingLayout GPUTextureSampleType sampleType = "float";GPUTextureViewDimension viewDimension = "2d";boolean multisampled =false ; };
GPUTextureBindingLayout
딕셔너리는 다음 멤버를 가집니다:
sampleType
, 타입 GPUTextureSampleType, 기본값"float"
-
이 바인딩에 연결되는 텍스처 뷰가 요구하는 타입을 나타냅니다.
viewDimension
, 타입 GPUTextureViewDimension, 기본값"2d"
-
이 바인딩에 연결되는 텍스처 뷰가 요구하는
dimension
을 나타냅니다. multisampled
, 타입 boolean, 기본값false
-
이 바인딩에 연결되는 텍스처 뷰가 멀티샘플링이어야 하는지 여부를 나타냅니다.
enum {
GPUStorageTextureAccess ,
"write-only" ,
"read-only" , };
"read-write" dictionary {
GPUStorageTextureBindingLayout GPUStorageTextureAccess access = "write-only";required GPUTextureFormat format ;GPUTextureViewDimension viewDimension = "2d"; };
GPUStorageTextureBindingLayout
딕셔너리는 다음 멤버를 가집니다:
access
, 타입 GPUStorageTextureAccess, 기본값"write-only"
-
이 바인딩의 접근 모드(읽기, 쓰기 가능 여부 등)를 나타냅니다.
format
, 타입 GPUTextureFormat-
이 바인딩에 연결되는 텍스처 뷰가 요구하는
format
을 나타냅니다. viewDimension
, 타입 GPUTextureViewDimension, 기본값"2d"
-
이 바인딩에 연결되는 텍스처 뷰가 요구하는
dimension
을 나타냅니다.
dictionary { };
GPUExternalTextureBindingLayout
GPUBindGroupLayout
객체는 다음 디바이스
타임라인 속성을 가집니다:
[[entryMap]]
, 타입 ordered map<GPUSize32
,GPUBindGroupLayoutEntry
>, 읽기 전용-
이
GPUBindGroupLayout
이 설명하는GPUBindGroupLayoutEntry
들을 가리키는 바인딩 인덱스 맵입니다. [[dynamicOffsetCount]]
, 타입GPUSize32
, 읽기 전용-
이
GPUBindGroupLayout
내 동적 오프셋을 가진 버퍼 바인딩 수입니다. [[exclusivePipeline]]
, 타입GPUPipelineBase
?, 읽기 전용-
이
GPUBindGroupLayout
가 기본 파이프라인 레이아웃의 일부로 생성된 경우 생성한 파이프라인입니다.null
이 아니면 이GPUBindGroup
로 생성한 바인드 그룹은 해당GPUPipelineBase
에서만 사용할 수 있습니다.
createBindGroupLayout(descriptor)
-
GPUBindGroupLayout
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createBindGroupLayout(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUBindGroupLayoutDescriptor
✘ ✘ 생성할 GPUBindGroupLayout
의 설명.반환값:
GPUBindGroupLayout
콘텐츠 타임라인 단계:
-
descriptor.
entries
의 각GPUBindGroupLayoutEntry
entry에 대해:-
entry.
storageTexture
값이 제공됨이라면:-
? 텍스처 포맷 필수 기능 검증을 entry.
storageTexture
.format
및 this.[[device]]
에 대해 수행.
-
-
-
layout을 ! 새 WebGPU 객체 생성(this,
GPUBindGroupLayout
, descriptor)로 둔다. -
this의 디바이스 타임라인에서 초기화 단계를 실행합니다.
-
layout을 반환합니다.
디바이스 타임라인 초기화 단계:-
아래 조건 중 하나라도 만족하지 않으면 검증 오류 생성, layout을 무효화하고 반환.
-
this는 손실(lost) 상태가 아니어야 합니다.
-
limits를 this.
[[device]]
.[[limits]]
로 둔다. -
descriptor의 각 entry의
binding
값은 고유해야 합니다. -
descriptor의 각 entry의
binding
값은 limits.maxBindingsPerBindGroup
미만이어야 합니다. -
descriptor.
entries
값은 바인딩 슬롯 한도 초과하지 않아야 합니다. -
descriptor.
entries
의 각GPUBindGroupLayoutEntry
entry에 대해:-
entry.
buffer
, entry.sampler
, entry.texture
, entry.storageTexture
, entry.externalTexture
중 반드시 하나만 제공됨이어야 합니다. -
entry.
visibility
값은GPUShaderStage
에 정의된 비트만 포함해야 합니다. -
entry.
visibility
값에VERTEX
가 포함될 경우:-
entry.
buffer
값이 제공됨이면, entry.buffer
.type
값은"uniform"
또는"read-only-storage"
이어야 합니다. -
entry.
storageTexture
값이 제공됨이면, entry.storageTexture
.access
값은"read-only"
이어야 합니다.
-
-
entry.
texture
?.multisampled
값이true
이면:-
entry.
texture
.viewDimension
값은"2d"
여야 합니다. -
entry.
texture
.sampleType
값은"float"
가 아니어야 합니다.
-
-
entry.
storageTexture
값이 제공됨이면:-
entry.
storageTexture
.viewDimension
값은"cube"
또는"cube-array"
가 아니어야 합니다. -
entry.
storageTexture
.format
값은 entry.storageTexture
.access
에 대해 § 26.1.1 일반 컬러 포맷 표에서 저장 용도를 지원하는 포맷이어야 합니다.
-
-
-
-
layout.
[[descriptor]]
값을 descriptor로 설정합니다. -
layout.
[[dynamicOffsetCount]]
값을 descriptor에서buffer
가 제공됨이고,buffer
.hasDynamicOffset
값이true
인 entry 수로 설정합니다. -
layout.
[[exclusivePipeline]]
값을null
로 설정합니다. -
descriptor.
entries
의 각GPUBindGroupLayoutEntry
entry에 대해:-
entry를 layout.
[[entryMap]]
에 entry.binding
키로 삽입합니다.
-
-
8.1.2. 호환성
GPUBindGroupLayout
객체 a와 b는 아래 모든 조건을 만족할 때 그룹 등가(group-equivalent)로 간주합니다.
-
a.
[[exclusivePipeline]]
== b.[[exclusivePipeline]]
이어야 합니다. -
모든 바인딩 번호 binding에 대해 아래 조건 중 하나를 만족해야 합니다:
-
a.
[[entryMap]]
과 b.[[entryMap]]
모두에 존재하지 않음 -
a.
[[entryMap]]
[binding] == b.[[entryMap]]
[binding]임
-
바인드 그룹 레이아웃이 그룹 등가(group-equivalent)이면 모든 컨텐츠에서 서로 대체하여 사용할 수 있습니다.
8.2. GPUBindGroup
GPUBindGroup
는 리소스 집합을 하나의 그룹으로 묶어서 바인딩하고, 셰이더 단계에서 리소스가 어떻게 사용되는지 정의합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUBindGroup { };GPUBindGroup includes GPUObjectBase ;
GPUBindGroup
는 다음 디바이스
타임라인 속성을 가집니다:
[[layout]]
, 타입GPUBindGroupLayout
, 읽기 전용-
이
GPUBindGroup
와 연결된GPUBindGroupLayout
입니다. [[entries]]
, 타입 sequence<GPUBindGroupEntry
>, 읽기 전용-
이
GPUBindGroup
가 기술하는GPUBindGroupEntry
의 집합입니다. [[usedResources]]
, 타입 사용 범위(usage scope), 읽기 전용-
이 바인드 그룹이 사용하는 버퍼 및 텍스처 서브리소스(subresource)의 집합이며, 각 내부 용도(internal usage) 플래그 리스트와 연결되어 있습니다.
GPUBindGroup
bindGroup의 바인드된 버퍼 범위(bound buffer ranges)는
list<GPUBufferDynamicOffset> dynamicOffsets가 주어졌을 때 다음과 같이 계산합니다:
-
result를 새로운 set<(
GPUBindGroupLayoutEntry
,GPUBufferBinding
)>로 둔다. -
dynamicOffsetIndex를 0으로 둔다.
-
bindGroup.
[[entries]]
에 있는 각GPUBindGroupEntry
bindGroupEntry를 bindGroupEntry.binding
순으로 정렬하여 반복:-
bindGroupLayoutEntry를 bindGroup.
[[layout]]
.[[entryMap]]
[bindGroupEntry.binding
]로 둔다. -
bound를 버퍼 바인딩으로 변환(get as buffer binding)(bindGroupEntry.
resource
)로 둔다. -
bindGroupLayoutEntry.
buffer
.hasDynamicOffset
값이true
이면:-
bound.
offset
값을 dynamicOffsets[dynamicOffsetIndex]만큼 증가시킨다. -
dynamicOffsetIndex를 1 증가시킨다.
-
-
추가 (bindGroupLayoutEntry, bound)를 result에 수행한다.
-
-
result를 반환한다.
8.2.1. 바인드 그룹 생성
GPUBindGroup
는 GPUDevice.createBindGroup()
로
생성합니다.
dictionary :
GPUBindGroupDescriptor GPUObjectDescriptorBase {required GPUBindGroupLayout layout ;required sequence <GPUBindGroupEntry >entries ; };
GPUBindGroupDescriptor
딕셔너리는 다음 멤버를 가집니다:
layout
, 타입 GPUBindGroupLayout-
이 바인드 그룹의 엔트리가 따를
GPUBindGroupLayout
입니다. entries
, 타입 sequence<GPUBindGroupEntry>-
각
layout
로 기술된 바인딩에 대해 셰이더에 노출할 리소스를 기술하는 엔트리 목록입니다.
typedef (GPUSampler or GPUTexture or GPUTextureView or GPUBuffer or GPUBufferBinding or GPUExternalTexture );
GPUBindingResource dictionary {
GPUBindGroupEntry required GPUIndex32 binding ;required GPUBindingResource resource ; };
GPUBindGroupEntry
는 GPUBindGroup
에
바인딩될 단일 리소스를 기술하며, 다음 멤버를 가집니다:
binding
, 타입 GPUIndex32-
해당
GPUBindGroup
내 리소스 바인딩의 고유 식별자이며,GPUBindGroupLayoutEntry.binding
및 @binding 속성과 대응됩니다. resource
, 타입 GPUBindingResource-
바인딩할 리소스이며,
GPUSampler
,GPUTexture
,GPUTextureView
,GPUBuffer
,GPUBufferBinding
, 또는GPUExternalTexture
일 수 있습니다.
GPUBindGroupEntry
는 다음 디바이스
타임라인 속성을 가집니다:
[[prevalidatedSize]]
, 타입boolean
-
이 바인딩 엔트리가 생성 시점에 버퍼 크기 검증을 거쳤는지 여부입니다.
dictionary {
GPUBufferBinding required GPUBuffer buffer ;GPUSize64 offset = 0;GPUSize64 size ; };
GPUBufferBinding
은 바인드할 버퍼 및 선택적 범위를 기술하는 리소스이며, 다음 멤버를 가집니다:
buffer
, 타입 GPUBuffer-
바인드할
GPUBuffer
입니다. offset
, 타입 GPUSize64, 기본값0
-
buffer
시작점에서부터 바인딩되는 범위의 시작까지의 오프셋(바이트 단위)입니다. size
, 타입 GPUSize64-
버퍼 바인딩의 크기(바이트 단위)입니다. 제공되지 않을 경우,
offset
에서buffer
끝까지의 범위를 지정합니다.
createBindGroup(descriptor)
-
GPUBindGroup
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createBindGroup(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUBindGroupDescriptor
✘ ✘ 생성할 GPUBindGroup
의 설명.반환값:
GPUBindGroup
콘텐츠 타임라인 단계:
-
bindGroup을 ! 새 WebGPU 객체 생성(this,
GPUBindGroup
, descriptor)로 둔다. -
this의 디바이스 타임라인에서 초기화 단계를 실행합니다.
-
bindGroup을 반환합니다.
디바이스 타임라인 초기화 단계:-
limits를 this.
[[device]]
.[[limits]]
로 둔다. -
아래 조건 중 하나라도 만족하지 않으면 검증 오류 생성, bindGroup을 무효화하고 반환.
-
descriptor.
layout
값이 this와 유효하게 사용 가능(valid to use with)해야 합니다. -
descriptor.
entries
의 개수가 descriptor.layout
의 엔트리 개수와 정확히 일치해야 합니다.
descriptor.
entries
의 각GPUBindGroupEntry
bindingDescriptor에 대해:-
resource를 bindingDescriptor.
resource
로 둔다. -
descriptor.
layout
.entries
에, bindingDescriptor.binding
과 일치하는GPUBindGroupLayoutEntry
layoutBinding이 정확히 하나 존재해야 합니다. -
정의된 binding member가:
sampler
-
-
resource는
GPUSampler
여야 합니다. -
resource는 this와 유효하게 사용 가능(valid to use with)해야 합니다.
-
layoutBinding.
sampler
.type
값이:"filtering"
-
resource.
[[isComparison]]
값이false
여야 합니다. "non-filtering"
-
resource.
[[isFiltering]]
값이false
이고, resource.[[isComparison]]
값도false
여야 합니다. "comparison"
-
resource.
[[isComparison]]
값이true
여야 합니다.
-
texture
-
-
resource는
GPUTexture
또는GPUTextureView
여야 합니다. -
resource는 this와 유효하게 사용 가능(valid to use with)해야 합니다.
-
textureView를 get as texture view(resource)로 둔다.
-
texture를 textureView.
[[texture]]
로 둔다. -
layoutBinding.
texture
.viewDimension
값이 textureView의dimension
과 같아야 합니다. -
layoutBinding.
texture
.sampleType
값이 textureView의format
과 호환되어야 합니다. -
textureView.
[[descriptor]]
.usage
값에TEXTURE_BINDING
이 포함되어야 합니다. -
layoutBinding.
texture
.multisampled
값이true
라면, texture의sampleCount
>1
이어야 하고, 아니라면1
이어야 합니다.
-
storageTexture
-
-
resource는
GPUTexture
또는GPUTextureView
여야 합니다. -
resource는 this와 유효하게 사용 가능(valid to use with)해야 합니다.
-
storageTextureView를 get as texture view(resource)로 둔다.
-
texture를 storageTextureView.
[[texture]]
로 둔다. -
layoutBinding.
storageTexture
.viewDimension
값이 storageTextureView의dimension
과 같아야 합니다. -
layoutBinding.
storageTexture
.format
값이 storageTextureView.[[descriptor]]
.format
과 같아야 합니다. -
storageTextureView.
[[descriptor]]
.usage
값에STORAGE_BINDING
이 포함되어야 합니다. -
storageTextureView.
[[descriptor]]
.mipLevelCount
값이 1이어야 합니다.
-
buffer
-
-
resource는
GPUBuffer
또는GPUBufferBinding
여야 합니다. -
bufferBinding을 get as buffer binding(resource)로 둔다.
-
bufferBinding.
buffer
값은 this와 유효하게 사용 가능(valid to use with)해야 합니다. -
bufferBinding.
offset
, bufferBinding.size
로 지정된 바인딩 범위가 버퍼 내부에 있고, 크기가 0이 아니어야 합니다. -
effective buffer binding size(bufferBinding) ≥ layoutBinding.
buffer
.minBindingSize
이어야 합니다. -
"uniform"
-
-
effective buffer binding size(bufferBinding) 값이 limits.
maxUniformBufferBindingSize
이하이어야 합니다. -
bufferBinding.
offset
값이 limits.minUniformBufferOffsetAlignment
의 배수여야 합니다.
"storage"
또는"read-only-storage"
-
-
effective buffer binding size(bufferBinding) 값이 limits.
maxStorageBufferBindingSize
이하이어야 합니다. -
effective buffer binding size(bufferBinding) 값이 4의 배수여야 합니다.
-
bufferBinding.
offset
값이 limits.minStorageBufferOffsetAlignment
의 배수여야 합니다.
-
externalTexture
-
-
resource는
GPUExternalTexture
,GPUTexture
, 또는GPUTextureView
여야 합니다. -
resource는 this와 유효하게 사용 가능(valid to use with)해야 합니다.
-
resource가:
GPUTexture
또는GPUTextureView
-
-
view를 get as texture view(resource)로 둔다.
-
view.
[[descriptor]]
.usage
값에TEXTURE_BINDING
이 반드시 포함되어야 합니다. -
view.
[[descriptor]]
.dimension
값이"2d"
여야 합니다. -
view.
[[descriptor]]
.mipLevelCount
값이 1이어야 합니다. -
view.
[[descriptor]]
.format
값이"rgba8unorm"
,"bgra8unorm"
, 또는"rgba16float"
여야 합니다. -
view.
[[texture]]
.sampleCount
값이 1이어야 합니다.
-
-
-
-
bindGroup.
[[layout]]
= descriptor.layout
로 설정합니다. -
bindGroup.
[[entries]]
= descriptor.entries
로 설정합니다. -
bindGroup.
[[usedResources]]
= {}로 설정합니다. -
descriptor.
entries
의 각GPUBindGroupEntry
bindingDescriptor에 대해:-
internalUsage를 layoutBinding에 대한 binding usage로 둡니다.
-
resource가 참조하는 모든 subresource를
[[usedResources]]
에 internalUsage로 추가합니다. -
bindingDescriptor.
[[prevalidatedSize]]
값을, layoutBinding에 대해 정의된 binding member가buffer
이고, layoutBinding.buffer
.minBindingSize
값이0
이면false
, 아니면true
로 설정합니다.
-
-
인자:
-
GPUBindingResource
resource
반환값: GPUTextureView
-
Assert resource는
GPUTexture
또는GPUTextureView
여야 합니다. -
resource가 아래 중 하나라면:
GPUTexture
-
-
resource.
createView()
를 반환합니다.
-
GPUTextureView
-
-
resource를 반환합니다.
-
인자:
-
GPUBindingResource
resource
반환값: GPUBufferBinding
-
Assert resource는
GPUBuffer
또는GPUBufferBinding
여야 합니다. -
resource가 아래 중 하나라면:
GPUBuffer
-
-
bufferBinding을 새로운
GPUBufferBinding
으로 둔다. -
bufferBinding.
buffer
값을 resource로 설정합니다. -
bufferBinding을 반환합니다.
-
GPUBufferBinding
-
-
resource를 반환합니다.
-
GPUBufferBinding
객체 a와 b가 버퍼 바인딩 메모리 중복(buffer-binding-aliasing)으로 간주되는 경우는 아래 모두가 true일 때입니다:
-
a.
offset
및 a.size
로 구성된 범위가 b.offset
및 b.size
로 구성된 범위와 교차합니다. 만약size
가 명시되지 않았다면, 해당 범위는 버퍼 끝까지로 간주합니다.
참고: 이 계산을 할 때, 모든 동적 오프셋은 이미 범위에 적용된 상태입니다.
8.3. GPUPipelineLayout
GPUPipelineLayout
는 setBindGroup()을 통해 커맨드 인코딩 시 설정된 모든 GPUBindGroup
객체의 리소스와,
GPURenderCommandsMixin.setPipeline
또는 GPUComputePassEncoder.setPipeline
으로
설정된 파이프라인의 셰이더 사이의 매핑을 정의합니다.
리소스의 전체 바인딩 주소는 다음 세 가지로 구성됩니다:
-
해당 리소스가 보이는 셰이더 단계 마스크
-
바인드 그룹 인덱스
-
바인딩 번호
이 주소의 구성 요소는 파이프라인의 바인딩 공간으로도 볼 수 있습니다. GPUBindGroup
(해당 GPUBindGroupLayout
포함)
는 고정된 바인드 그룹 인덱스에 대한 공간을 담당합니다. 포함된 바인딩은 해당 인덱스에서 셰이더가 사용하는 리소스의 상위 집합이어야 합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface GPUPipelineLayout { };GPUPipelineLayout includes GPUObjectBase ;
GPUPipelineLayout
는 다음 디바이스
타임라인 속성을 가집니다:
[[bindGroupLayouts]]
, 타입 list<GPUBindGroupLayout
>, 읽기 전용-
생성 시
GPUPipelineLayoutDescriptor.bindGroupLayouts
에 지정된GPUBindGroupLayout
객체들입니다.
참고: 동일한 GPUPipelineLayout
을
여러 GPURenderPipeline
또는 GPUComputePipeline
파이프라인에 사용하면,
이들 사이를 전환할 때 UA가 내부적으로 리소스를 재바인딩할 필요가 없음을 보장합니다.
GPUComputePipeline
객체 X는 GPUPipelineLayout.bindGroupLayouts
A, B, C로 생성되었습니다.
GPUComputePipeline
객체 Y는 GPUPipelineLayout.bindGroupLayouts
A, D, C로 생성되었습니다. 커맨드 인코딩 시퀀스에 두 번의 dispatch가 있다고 가정할 때:
-
setBindGroup(0, ...)
-
setBindGroup(1, ...)
-
setBindGroup(2, ...)
-
setPipeline
(X) -
setBindGroup(1, ...)
-
setPipeline
(Y)
이 상황에서 두 번째 dispatch를 위해 그룹 슬롯 2를 UA가 다시 바인딩해야 합니다. 이는 GPUPipelineLayout.bindGroupLayouts
의
2번 인덱스의 GPUBindGroupLayout
또는 슬롯 2의 GPUBindGroup
이
변경되지 않더라도 발생합니다.
참고: GPUPipelineLayout
의
권장 사용법은 가장 일반적이고 변경 빈도가 낮은 바인드 그룹을 레이아웃의 "하단"(즉 인덱스 0이나 1)에 배치하는 것입니다. 반대로 바인드 그룹이 draw 호출 사이에 자주 변경될수록 인덱스를
높게 두는 것이 좋습니다. 이 가이드라인은 UA가 draw 호출 사이의 상태 변경을 최소화하여 CPU 오버헤드를 낮출 수 있도록 돕습니다.
8.3.1. 파이프라인 레이아웃 생성
GPUPipelineLayout
는 GPUDevice.createPipelineLayout()
로
생성됩니다.
dictionary :
GPUPipelineLayoutDescriptor GPUObjectDescriptorBase {required sequence <GPUBindGroupLayout ?>bindGroupLayouts ; };
GPUPipelineLayoutDescriptor
딕셔너리는 파이프라인에서 사용되는 모든 GPUBindGroupLayout
을
정의하며,
다음 멤버를 가집니다:
bindGroupLayouts
, 타입sequence<GPUBindGroupLayout?>
-
파이프라인에서 사용할 수 있는
GPUBindGroupLayout
의 옵션 목록입니다. 각 요소는GPUShaderModule
내 @group 어트리뷰트에 대응하며, N번째 요소는@group(N)
에 대응합니다.
createPipelineLayout(descriptor)
-
GPUPipelineLayout
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createPipelineLayout(descriptor) 메서드 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUPipelineLayoutDescriptor
✘ ✘ 생성할 GPUPipelineLayout
의 설명.반환값:
GPUPipelineLayout
콘텐츠 타임라인 단계:
-
pl을 ! 새 WebGPU 객체 생성(this,
GPUPipelineLayout
, descriptor)로 둔다. -
this의 디바이스 타임라인에서 초기화 단계를 실행합니다.
-
pl을 반환합니다.
디바이스 타임라인 초기화 단계:-
limits를 this.
[[device]]
.[[limits]]
로 둔다. -
bindGroupLayouts를 list of
null
GPUBindGroupLayout
로, size가 limits.maxBindGroups
와 같은 새 리스트로 둔다. -
각 bindGroupLayout을 descriptor.
bindGroupLayouts
의 인덱스 i에 대해:-
bindGroupLayout이
null
이 아니고, bindGroupLayout.[[descriptor]]
.entries
값이 비어 있지 않으면:-
bindGroupLayouts[i]에 bindGroupLayout을 설정합니다.
-
-
-
allEntries를 bindGroupLayouts의 각
null
이 아닌 bgl에 대해 bgl.[[descriptor]]
.entries
를 연결한 결과로 둔다. -
아래 조건 중 하나라도 만족하지 않으면 검증 오류 생성, pl을 무효화하고 반환.
-
bindGroupLayouts의
null
이 아닌 모든GPUBindGroupLayout
에 대해 반드시 this와 유효하게 사용 가능(valid to use with)이어야 하고,[[exclusivePipeline]]
값이null
이어야 합니다. -
descriptor.
bindGroupLayouts
의 size가 limits.maxBindGroups
이하이어야 합니다. -
allEntries 값이 바인딩 슬롯 한도 초과하지 않아야 합니다.
-
-
pl.
[[bindGroupLayouts]]
값을 bindGroupLayouts로 설정합니다.
-
참고: 두 GPUPipelineLayout
객체는 내부 [[bindGroupLayouts]]
시퀀스가
group-equivalent인 GPUBindGroupLayout
객체를 포함하면
모든 용도에서 등가로 간주됩니다.
8.4. 예시
GPUBindGroupLayout
을 생성합니다.
그리고 GPUBindGroup
및 GPUPipelineLayout
을 GPUBindGroupLayout
을
활용해 생성합니다.
const bindGroupLayout= gpuDevice. createBindGroupLayout({ entries: [{ binding: 0 , visibility: GPUShaderStage. VERTEX| GPUShaderStage. FRAGMENT, buffer: {} }, { binding: 1 , visibility: GPUShaderStage. FRAGMENT, texture: {} }, { binding: 2 , visibility: GPUShaderStage. FRAGMENT, sampler: {} }] }); const bindGroup= gpuDevice. createBindGroup({ layout: bindGroupLayout, entries: [{ binding: 0 , resource: { buffer: buffer}, }, { binding: 1 , resource: texture}, { binding: 2 , resource: sampler}] }); const pipelineLayout= gpuDevice. createPipelineLayout({ bindGroupLayouts: [ bindGroupLayout] });
9. 셰이더 모듈
9.1. GPUShaderModule
[Exposed =(Window ,Worker ),SecureContext ]interface GPUShaderModule {Promise <GPUCompilationInfo >getCompilationInfo (); };GPUShaderModule includes GPUObjectBase ;
GPUShaderModule
은 내부 셰이더 모듈 객체에 대한 참조입니다.
9.1.1. 셰이더 모듈 생성
dictionary :
GPUShaderModuleDescriptor GPUObjectDescriptorBase {required USVString code ;sequence <GPUShaderModuleCompilationHint >compilationHints = []; };
code
, of type USVString-
WGSL 셰이더 모듈을 위한 소스 코드입니다.
compilationHints
, of type sequence<GPUShaderModuleCompilationHint>, defaulting to[]
-
GPUShaderModuleCompilationHint
들의 목록입니다.애플리케이션에서 제공하는 모든 힌트는 파이프라인의 엔트리 포인트 하나에 관한 정보를 포함해야 합니다. 이 파이프라인은 결국 해당 엔트리 포인트로부터 생성됩니다.
구현체는
GPUShaderModuleCompilationHint
에 포함된 정보를 최대한 활용하여createShaderModule()
내에서 컴파일을 최대한 많이 수행해야 합니다.타입 검사 외에는 이러한 힌트가 어떤 방식으로든 검증되지 않습니다.
NOTE:compilationHints
에 정보를 제공해도 성능을 제외한 관찰 가능한 효과는 없습니다. 생성되지 않는 파이프라인에 대한 힌트를 제공하면 성능에 악영향을 줄 수 있습니다.하나의 셰이더 모듈은 여러 엔트리 포인트를 가질 수 있으며, 여러 파이프라인이 하나의 셰이더 모듈로부터 생성될 수 있기 때문에, 구현체가
createShaderModule()
에서 한 번에 가능한 많은 컴파일을 수행하는 것이createComputePipeline()
또는createRenderPipeline()
을 여러 번 호출하는 것보다 더 성능이 좋을 수 있습니다.힌트는 명시적으로 이름이 지정된 엔트리 포인트에만 적용됩니다.
GPUProgrammableStage.entryPoint
와는 다르게, 모듈에 엔트리 포인트가 하나만 있더라도 기본값이 없습니다.Note: 힌트는 관찰 가능한 방식으로 검증되지 않지만, 사용자 에이전트는 식별 가능한 오류(예: 알 수 없는 엔트리 포인트 이름이나 호환되지 않는 파이프라인 레이아웃 등)를 개발자에게 노출할 수 있습니다. 예를 들어 브라우저 개발자 콘솔에서 표시될 수 있습니다.
createShaderModule(descriptor)
-
GPUShaderModule
을 생성합니다.호출 대상:GPUDevice
this.인수:
GPUDevice.createShaderModule(descriptor) 메서드의 인수. 파라미터 타입 Nullable Optional 설명 descriptor
GPUShaderModuleDescriptor
✘ ✘ 생성할 GPUShaderModule
에 대한 설명입니다.반환값:
GPUShaderModule
콘텐츠 타임라인 단계:
-
sm을 ! 새로운 WebGPU 객체 생성(this,
GPUShaderModule
, descriptor)로 설정합니다. -
this의 디바이스 타임라인에서 초기화 단계를 수행합니다.
-
sm을 반환합니다.
디바이스 타임라인 초기화 단계:-
error를 WGSL 소스 descriptor.
code
로 셰이더 모듈 생성에서 발생한 오류로 설정하거나, 오류가 없으면null
로 설정합니다. -
다음 요구사항 중 하나라도 만족하지 않으면, 유효성 검사 오류 생성, 무효화 sm, 그리고 반환합니다.
-
this가 lost 상태가 아니어야 합니다.
-
descriptor.
code
내의 각enable
확장에 대해, 해당하는GPUFeatureName
이 활성화되어 있어야 합니다 (Feature Index 참고).
Note: 분류되지 않은 오류는 셰이더 모듈 생성에서 발생할 수 없습니다. 구현체가 셰이더 모듈 생성 중에 이러한 오류를 감지하면, 셰이더 모듈이 유효한 것처럼 동작해야 하며 오류는 파이프라인 생성 시까지 지연되어야 합니다.
-
NOTE:사용자 에이전트는 여기서 발생한 유효성 검사 오류의message
텍스트에 상세 컴파일러 오류 메시지나 셰이더 텍스트를 포함하지 않아야 합니다: 이러한 정보는getCompilationInfo()
를 통해 접근할 수 있습니다. 사용자 에이전트는 개발자가 더 쉽게 디버깅할 수 있도록 사람이 읽을 수 있는 형식의 오류 세부 정보를 제공해야 하며 (예: 브라우저 개발자 콘솔의 경고로, 전체 셰이더 소스를 펼쳐볼 수 있도록 표시).셰이더 컴파일 오류는 현행 표준 애플리케이션에서는 드물어야 하므로, 사용자 에이전트는 오류 처리(GPU error scope나
uncapturederror
이벤트 핸들러)에 관계없이 개발자에게 오류를 표시할 수 있습니다. 그렇지 않다면, 사람이 읽을 수 있는 오류 세부 정보를 액세스할 수 있는 별도의 방법을 제공하고 문서화해야 하며, 예를 들어 오류를 무조건적으로 표시하는 체크박스를 추가하거나,GPUCompilationInfo
객체를 콘솔에 로깅할 때 사람이 읽을 수 있는 세부 정보를 표시해야 합니다. -
GPUShaderModule
을
생성:
// 뷰포트 전체를 빨간색으로 채우는 간단한 버텍스 및 프래그먼트 셰이더 쌍 예시입니다. const shaderSource= ` var<private> pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>( vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); @vertex fn vertexMain(@builtin(vertex_index) vertexIndex : u32) -> @builtin(position) vec4<f32> { return vec4(pos[vertexIndex], 1.0, 1.0); } @fragment fn fragmentMain() -> @location(0) vec4<f32> { return vec4(1.0, 0.0, 0.0, 1.0); } ` ; const shaderModule= gpuDevice. createShaderModule({ code: shaderSource, });
9.1.1.1. 셰이더 모듈 컴파일 힌트
셰이더 모듈 컴파일 힌트는 선택적으로 제공하는 추가 정보로서, 특정 GPUShaderModule
엔트리 포인트가
향후 어떻게 사용될지에 대한 의도를 나타냅니다. 일부 구현체에서는 이 정보가 셰이더 모듈을 더 빨리 컴파일하는 데 도움이 되어, 성능이 향상될 수 있습니다.
dictionary {
GPUShaderModuleCompilationHint required USVString ; (
entryPoint GPUPipelineLayout or GPUAutoLayoutMode )layout ; };
layout
, 타입(GPUPipelineLayout or GPUAutoLayoutMode)
-
GPUPipelineLayout
은GPUShaderModule
이 이후createComputePipeline()
또는createRenderPipeline()
호출에서 사용될 수 있는 파이프라인 레이아웃입니다."auto"
로 설정되면, 해당 힌트와 연관된 엔트리 포인트에 대해 기본 파이프라인 레이아웃이 사용됩니다.
createShaderModule()
와
createComputePipeline()
/
createRenderPipeline()
에
동일한 정보를 제공하는 것이 좋습니다.
애플리케이션이 createShaderModule()
호출 시 힌트 정보를 제공할 수 없다면,
호출을 지연시키기보다는 compilationHints
시퀀스 또는
GPUShaderModuleCompilationHint
의
멤버에서
알 수 없는 정보를 생략하는 것이 일반적으로 더 바람직합니다.
해당 정보를 생략하면 컴파일이 createComputePipeline()
/
createRenderPipeline()
까지
지연될 수 있습니다.
작성자가 createShaderModule()
에
전달한 힌트 정보가
이후 createComputePipeline()
/
createRenderPipeline()
에
동일 모듈로 전달될 정보와
일치하지 않을 가능성이 있다면, 그 정보를 createShaderModule()
에
전달하지 않는 것이 좋습니다.
일치하지 않는 정보를 전달하면 불필요한 컴파일이 발생할 수 있습니다.
9.1.2. 셰이더 모듈 컴파일 정보
enum {
GPUCompilationMessageType ,
"error" ,
"warning" , }; [
"info" Exposed =(Window ,Worker ),Serializable ,SecureContext ]interface {
GPUCompilationMessage readonly attribute DOMString message ;readonly attribute GPUCompilationMessageType type ;readonly attribute unsigned long long lineNum ;readonly attribute unsigned long long linePos ;readonly attribute unsigned long long offset ;readonly attribute unsigned long long length ; }; [Exposed =(Window ,Worker ),Serializable ,SecureContext ]interface {
GPUCompilationInfo readonly attribute FrozenArray <GPUCompilationMessage >; };
messages
GPUCompilationMessage
는
GPUShaderModule
컴파일러에서
생성한 정보성, 경고 또는 오류 메시지입니다. 메시지는 개발자가 셰이더 code
문제를 진단하는 데 도움이 되도록 사람이 읽을 수 있도록 작성됩니다.
각 메시지는 셰이더 코드 내의 한 지점, 코드의 부분 문자열, 또는 코드의 특정 지점과 연관되지 않을 수도 있습니다.
GPUCompilationMessage
는
다음과 같은 속성을 가집니다:
message
, 타입 DOMString, 읽기 전용-
이 컴파일 메시지에 대한 사람이 읽을 수 있고 지역화 가능한 텍스트입니다.
Note:
message
는 언어 및 방향 정보에 대한 모범 사례를 따라야 합니다. 이는 향후 표준이 등장할 경우 해당 문자열의 언어 및 방향 메타데이터 보고 방식도 포함됩니다.Editorial note: 현재로서는 레거시 API와 호환성 및 일관성을 제공하는 언어/방향 권고가 없으나, 향후 제공될 경우 공식적으로 도입하세요.
type
, 타입 GPUCompilationMessageType, 읽기 전용-
메시지의 심각도 수준입니다.
lineNum
, 타입 unsigned long long, 읽기 전용-
메시지가 대응하는 셰이더
code
의 줄 번호입니다. 1부터 시작하며,1
이면 셰이더code
의 첫 번째 줄을 의미합니다. 줄은 줄 바꿈으로 구분됩니다.메시지가 부분 문자열에 대응하는 경우, 해당 부분 문자열이 시작되는 줄을 나타냅니다. 메시지가 셰이더
code
의 특정 지점을 참조하지 않으면0
이 됩니다. linePos
, 타입 unsigned long long, 읽기 전용-
셰이더
lineNum
줄의 시작부터 메시지가 대응하는 지점 또는 부분 문자열까지의 UTF-16 코드 유닛 오프셋입니다. 1부터 시작하며,linePos
가1
이면 해당 줄의 첫 번째 코드 유닛을 의미합니다.메시지가 부분 문자열에 대응하는 경우, 그 부분 문자열의 첫 번째 UTF-16 코드 유닛을 나타냅니다. 메시지가 셰이더
code
의 특정 지점을 참조하지 않으면0
이 됩니다. offset
, 타입 unsigned long long, 읽기 전용-
셰이더
code
의 시작부터 메시지가 대응하는 지점 또는 부분 문자열까지의 UTF-16 코드 유닛 오프셋입니다.lineNum
및linePos
와 동일한 위치를 참조해야 합니다. 메시지가 셰이더code
의 특정 지점을 참조하지 않으면0
이 됩니다. length
, 타입 unsigned long long, 읽기 전용-
메시지가 대응하는 부분 문자열의 UTF-16 코드 유닛 개수입니다. 메시지가 부분 문자열과 연관되지 않으면
length
는 0이어야 합니다.
Note: GPUCompilationMessage
.lineNum
및
GPUCompilationMessage
.linePos
는
대부분의 경우 사람이 읽을 수 있는 메시지를 출력하여 많은 텍스트 에디터에서 표시되는 줄 및 열 번호와 일치시키는 용도로 사용되므로 1부터 시작합니다.
Note: GPUCompilationMessage
.offset
및
GPUCompilationMessage
.length
는
셰이더 code
의
부분 문자열을
substr()
로 추출할 때 적합합니다. 메시지가 대응하는 부분 문자열을 얻을 수 있습니다.
getCompilationInfo()
-
GPUShaderModule
의 컴파일 중에 생성된 모든 메시지를 반환합니다.메시지의 위치, 순서 및 내용은 구현 정의입니다. 특히, 메시지는
lineNum
기준으로 정렬되어 있지 않을 수 있습니다.호출 대상:GPUShaderModule
this반환값:
Promise
<GPUCompilationInfo
>콘텐츠 타임라인 단계:
-
contentTimeline을 현재 콘텐츠 타임라인으로 설정합니다.
-
promise를 새로운 promise로 설정합니다.
-
this의 디바이스 타임라인에서 동기화 단계를 수행합니다.
-
promise를 반환합니다.
디바이스 타임라인 동기화 단계:-
event를 this에 대한 셰이더 모듈 생성의 성공 또는 실패 시 발생하도록 설정합니다.
-
타임라인 이벤트 수신 event 를 this.
[[device]]
에서 수행하며, 이후 단계는 contentTimeline에서 처리합니다.
콘텐츠 타임라인 단계:-
info를 새로운
GPUCompilationInfo
로 설정합니다. -
messages를 this의 셰이더 모듈 생성 중에 생성된 오류, 경고 또는 정보 메시지의 목록으로 설정하거나, 디바이스가 손실된 경우 빈 목록
[]
로 설정합니다. -
messages의 각 message에 대해:
-
m을 새로운
GPUCompilationMessage
로 설정합니다. -
m.
message
에 message의 텍스트를 설정합니다. -
- 만약 message가 셰이더
code
의 특정 부분 문자열이나 위치와 연관되어 있다면: - 그 외의 경우:
- 만약 message가 셰이더
-
-
promise를 info로 resolve합니다.
-
10. 파이프라인
파이프라인은 GPUComputePipeline
또는 GPURenderPipeline
이
될 수 있으며,
바인딩과 버텍스 버퍼 형태의 입력 데이터를 처리하여 출력 렌더 타깃의 색상 등과 같은 출력을 생성하는 GPU 하드웨어, 드라이버, 그리고 사용자 에이전트가 결합된 전체 기능을 나타냅니다.
구조적으로 파이프라인은 프로그래머블 스테이지(셰이더)와 블렌딩 모드 등과 같은 고정 기능 상태의 시퀀스로 구성됩니다.
Note: 내부적으로, 타깃 플랫폼에 따라 드라이버가 일부 고정 기능 상태를 셰이더 코드로 변환하여 사용자가 제공한 셰이더와 함께 연결할 수 있습니다. 이 연결이 객체가 전체로 생성되는 이유 중 하나입니다.
이 결합 상태는 하나의 객체로 생성됩니다
(GPUComputePipeline
또는 GPURenderPipeline
)
그리고 하나의 명령으로 전환됩니다
(GPUComputePassEncoder
.setPipeline()
또는
GPURenderCommandsMixin
.setPipeline()
각각).
파이프라인을 생성하는 방법은 두 가지가 있습니다:
- 즉시 파이프라인 생성
-
createComputePipeline()
및createRenderPipeline()
은 바로 패스 인코더에서 사용할 수 있는 파이프라인 객체를 반환합니다.이 과정이 실패하면 파이프라인 객체는 무효화되고 호출은 유효성 검사 오류 또는 내부 오류를 생성합니다.
Note: 핸들 객체가 즉시 반환되지만 실제 파이프라인 생성은 동기적이지 않습니다. 파이프라인 생성이 오래 걸릴 경우, 디바이스 타임라인에서 생성 호출과 최초
setPipeline()
실행 사이, 해당GPUCommandEncoder
또는GPURenderBundleEncoder
의finish()
시점, 그리고 해당GPUCommandBuffer
의submit()
호출 시점 중 하나에서 스톨이 발생할 수 있습니다. 이 지점은 명시되지 않지만, 가장 가능성 높은 시점입니다. - 비동기 파이프라인 생성
-
createComputePipelineAsync()
및createRenderPipelineAsync()
는 파이프라인 생성이 완료되면 파이프라인 객체로 resolve되는Promise
를 반환합니다.실패 시
Promise
는GPUPipelineError
로 reject됩니다.
GPUPipelineError
는 파이프라인 생성 실패를 설명합니다.
[Exposed =(Window ,Worker ),SecureContext ,Serializable ]interface GPUPipelineError :DOMException {constructor (optional DOMString message = "",GPUPipelineErrorInit options );readonly attribute GPUPipelineErrorReason reason ; };dictionary {
GPUPipelineErrorInit required GPUPipelineErrorReason ; };
reason enum GPUPipelineErrorReason {"validation" ,"internal" , };
GPUPipelineError
생성자:
constructor()
-
인수:
GPUPipelineError.constructor() 메서드의 인수. 파라미터 타입 Nullable Optional 설명 message
DOMString
✘ ✔ 기본 DOMException
의 오류 메시지입니다.options
GPUPipelineErrorInit
✘ ✘ GPUPipelineError
에 특화된 옵션입니다.콘텐츠 타임라인 단계:
GPUPipelineError
는 다음과 같은 속성을 가집니다:
reason
, 타입 GPUPipelineErrorReason, 읽기 전용-
파이프라인 생성 중 발생한 오류의 종류를 슬롯 기반 attribute로 노출하는 읽기 전용 속성입니다.
GPUPipelineErrorReason
:
GPUPipelineError
객체는 직렬화 가능한
객체입니다.
-
DOMException
의 직렬화 단계를 value와 serialized를 인수로 실행합니다.
-
DOMException
의 역직렬화 단계를 value와 serialized를 인수로 실행합니다.
10.1. 기본 파이프라인
enum {
GPUAutoLayoutMode , };
"auto" dictionary :
GPUPipelineDescriptorBase GPUObjectDescriptorBase {required (GPUPipelineLayout or GPUAutoLayoutMode )layout ; };
layout
, 타입(GPUPipelineLayout or GPUAutoLayoutMode)
-
이 파이프라인의
GPUPipelineLayout
또는 파이프라인 레이아웃을 자동으로 생성하려면"auto"
를 사용합니다.Note:
"auto"
가 사용되면 해당 파이프라인은 다른 파이프라인과GPUBindGroup
을 공유할 수 없습니다.
interface mixin { [
GPUPipelineBase NewObject ]GPUBindGroupLayout getBindGroupLayout (unsigned long index ); };
GPUPipelineBase
는 다음 디바이스
타임라인 속성을 가집니다:
[[layout]]
, 타입GPUPipelineLayout
-
this
와 함께 사용할 수 있는 리소스의 레이아웃 정의입니다.
GPUPipelineBase
는 다음과 같은 메서드를 가집니다:
getBindGroupLayout(index)
-
index
에 있는GPUPipelineBase
의GPUBindGroupLayout
에 호환되는GPUBindGroupLayout
을 반환합니다.호출 대상:GPUPipelineBase
this인수:
GPUPipelineBase.getBindGroupLayout(index) 메서드의 인수. 파라미터 타입 Nullable Optional 설명 index
unsigned long
✘ ✘ 파이프라인 레이아웃의 [[bindGroupLayouts]]
시퀀스의 인덱스입니다.반환값:
GPUBindGroupLayout
콘텐츠 타임라인 단계:
-
layout을 새로운
GPUBindGroupLayout
객체로 설정합니다. -
this의 디바이스 타임라인에서 초기화 단계를 수행합니다.
-
layout을 반환합니다.
디바이스 타임라인 초기화 단계:-
limits를 this.
[[device]]
.[[limits]]
로 설정합니다. -
다음 조건 중 하나라도 만족하지 않으면 유효성 검사 오류 생성, 무효화 layout 그리고 반환합니다.
-
this가 유효해야 합니다.
-
index < limits.
maxBindGroups
.
-
-
layout을 this.
[[layout]]
.[[bindGroupLayouts]]
[index]의 복사본으로 초기화합니다.Note:
GPUBindGroupLayout
은 항상 값으로만 사용되며, 참조로 사용되지 않으므로 이는 같은 내부 객체를 새로운 WebGPU 인터페이스로 반환하는 것과 동일합니다. 새로운GPUBindGroupLayout
WebGPU 인터페이스가 매번 반환되며, 이는 콘텐츠 타임라인과 디바이스 타임라인 간의 왕복을 피하기 위함입니다.
-
10.1.1. 기본 파이프라인 레이아웃
GPUPipelineBase
객체가 layout
을
"auto"
로
설정하여 생성된 경우,
기본 레이아웃이 생성되어 대신 사용됩니다.
Note: 기본 레이아웃은 단순한 파이프라인에 편의를 위해 제공되지만, 대부분의 경우 명시적 레이아웃 사용을 권장합니다. 기본 레이아웃에서 생성된 바인드 그룹은 다른 파이프라인과 함께 사용할 수 없으며, 셰이더를 변경하면 기본 레이아웃의 구조가 바뀌어 바인드 그룹 생성 오류가 발생할 수 있습니다.
GPUPipelineBase
pipeline을 위한 기본 파이프라인 레이아웃을 생성하려면,
다음 디바이스 타임라인 단계를
실행하세요:
-
groupCount를 0으로 설정합니다.
-
groupDescs를 device.
[[limits]]
.maxBindGroups
개의 새로운GPUBindGroupLayoutDescriptor
객체 시퀀스로 설정합니다. -
groupDescs의 각 groupDesc에 대해:
-
pipeline을 생성할 때 사용된 descriptor의 각
GPUProgrammableStage
stageDesc에 대해:-
shaderStage를 pipeline에서 stageDesc가 사용되는 셰이더 스테이지의
GPUShaderStageFlags
로 설정합니다. -
entryPoint를 get the entry point(shaderStage, stageDesc)로 설정합니다. Assert entryPoint가
null
이 아님을 확인합니다. -
entryPoint가 정적으로 사용하는 각 리소스 resource에 대해:
-
group를 resource의 "group" decoration으로 설정합니다.
-
binding을 resource의 "binding" decoration으로 설정합니다.
-
entry를 새로운
GPUBindGroupLayoutEntry
로 설정합니다. -
entry.
binding
을 binding으로 설정합니다. -
entry.
visibility
를 shaderStage로 설정합니다. -
resource가 샘플러 바인딩이면:
-
samplerLayout을 새로운
GPUSamplerBindingLayout
로 설정합니다. -
entry.
sampler
를 samplerLayout으로 설정합니다.
-
-
resource가 비교 샘플러 바인딩이면:
-
samplerLayout을 새로운
GPUSamplerBindingLayout
로 설정합니다. -
samplerLayout.
type
을"comparison"
으로 설정합니다. -
entry.
sampler
를 samplerLayout으로 설정합니다.
-
-
resource가 버퍼 바인딩이면:
-
bufferLayout을 새로운
GPUBufferBindingLayout
로 설정합니다. -
bufferLayout.
minBindingSize
를 resource의 최소 버퍼 바인딩 크기로 설정합니다. -
resource가 read-only storage buffer이면:
-
bufferLayout.
type
을"read-only-storage"
로 설정합니다.
-
-
resource가 storage buffer이면:
-
entry.
buffer
를 bufferLayout으로 설정합니다.
-
-
resource가 샘플링된 텍스처 바인딩이면:
-
textureLayout을 새로운
GPUTextureBindingLayout
로 설정합니다. -
resource가 깊이 텍스처 바인딩이면:
-
textureLayout.
sampleType
을"depth"
로 설정합니다.
그 외 resource의 샘플 타입이 다음과 같으면:
f32
및 stageDesc에서 샘플러를 함께 사용하는 texture builtin 함수 호출에 resource가 정적으로 사용되면-
textureLayout.
sampleType
을"float"
로 설정합니다. f32
그 외-
textureLayout.
sampleType
을"unfilterable-float"
로 설정합니다. i32
-
textureLayout.
sampleType
을"sint"
로 설정합니다. u32
-
textureLayout.
sampleType
을"uint"
로 설정합니다.
-
-
textureLayout.
viewDimension
을 resource의 dimension으로 설정합니다. -
resource가 멀티샘플 텍스처면:
-
textureLayout.
multisampled
를true
로 설정합니다.
-
-
entry.
texture
를 textureLayout으로 설정합니다.
-
-
resource가 storage texture 바인딩이면:
-
storageTextureLayout을 새로운
GPUStorageTextureBindingLayout
로 설정합니다. -
storageTextureLayout.
format
을 resource의 format으로 설정합니다. -
storageTextureLayout.
viewDimension
을 resource의 dimension으로 설정합니다. -
access 모드가 다음과 같으면:
read
-
textureLayout.
access
를"read-only"
로 설정합니다. write
-
textureLayout.
access
를"write-only"
로 설정합니다. read_write
-
textureLayout.
access
를"read-write"
로 설정합니다.
-
entry.
storageTexture
를 storageTextureLayout으로 설정합니다.
-
-
groupCount를 max(groupCount, group + 1)로 설정합니다.
-
groupDescs[group]에
binding
값이 binding인 previousEntry가 있으면:-
entry가 previousEntry와
visibility
가 다르면:-
entry.
visibility
에 설정된 비트를 previousEntry.visibility
에 추가합니다.
-
-
resource가 버퍼 바인딩이고 entry가 previousEntry보다 더 큰
buffer
.minBindingSize
값을 가지면:-
previousEntry.
buffer
.minBindingSize
를 entry.buffer
.minBindingSize
로 설정합니다.
-
-
resource가 샘플링된 텍스처 바인딩이고 entry의
texture
.sampleType
이 previousEntry와 다르며, 두 entry와 previousEntry 모두texture
.sampleType
이"float"
또는"unfilterable-float"
이면:-
previousEntry.
texture
.sampleType
을"float"
로 설정합니다.
-
-
그 외 entry와 previousEntry간에 다른 속성이 있으면:
-
null
을 반환합니다 (파이프라인 생성이 실패하게 됨).
-
-
resource가 storage texture 바인딩이고, entry.storageTexture.
access
가"read-write"
이고, previousEntry.storageTexture.access
가"write-only"
이며, previousEntry.storageTexture.format
이STORAGE_BINDING
및"read-write"
와 호환된다면:-
previousEntry.storageTexture.
access
을"read-write"
로 설정합니다.
-
-
-
그 외의 경우
-
entry를 groupDescs[group]에 추가합니다.
-
-
-
-
groupLayouts를 새로운 리스트로 설정합니다.
-
0부터 groupCount - 1까지의 각 i에 대해:
-
groupDesc를 groupDescs[i]로 설정합니다.
-
bindGroupLayout를 device.
createBindGroupLayout()
(groupDesc) 호출 결과로 설정합니다. -
bindGroupLayout.
[[exclusivePipeline]]
를 pipeline으로 설정합니다. -
bindGroupLayout을 groupLayouts에 추가합니다.
-
-
desc를 새로운
GPUPipelineLayoutDescriptor
로 설정합니다. -
desc.
bindGroupLayouts
를 groupLayouts로 설정합니다. -
device.
createPipelineLayout()
(desc)를 반환합니다.
10.1.2. GPUProgrammableStage
GPUProgrammableStage
는
사용자가 제공한 GPUShaderModule
에서
파이프라인의 프로그래머블 스테이지 중 하나를 제어하는 진입점을
설명합니다.
엔트리 포인트 이름은 WGSL 식별자 비교 규칙을 따릅니다.
dictionary GPUProgrammableStage {required GPUShaderModule module ;USVString entryPoint ;record <USVString ,GPUPipelineConstantValue >constants = {}; };typedef double GPUPipelineConstantValue ; // WGSL의 bool, f32, i32, u32, 그리고 f16(활성화된 경우)을 나타낼 수 있음.
GPUProgrammableStage
는
다음 멤버를 가집니다:
module
, 타입 GPUShaderModule-
이 프로그래머블 스테이지가 실행할 코드를 포함하는
GPUShaderModule
입니다. entryPoint
, 타입 USVString-
이 스테이지가 작업을 수행할 때 사용할
module
내 함수의 이름입니다.NOTE:
entryPoint
딕셔너리 멤버는 필수가 아니기 때문에,GPUProgrammableStage
를 사용하는 메서드는 어떤 엔트리 포인트를 참조하는지 결정하기 위해 "get the entry point" 알고리즘을 사용해야 합니다. constants
, 타입 record<USVString, GPUPipelineConstantValue>, 기본값은{}
-
셰이더 모듈
module
에 있는 파이프라인 오버라이드 가능 상수들의 값을 지정합니다.각 파이프라인 오버라이드 가능 상수는 하나의 파이프라인 오버라이드 상수 식별자 문자열로 고유하게 식별되며, 선언 시 파이프라인 상수 ID를 명시했다면 그 값, 그렇지 않으면 상수의 식별자 이름을 사용합니다.
각 키-값 쌍의 키는 해당 상수의 식별자 문자열과 같아야 하며, 비교는 WGSL 식별자 비교 규칙에 따라 수행합니다. 파이프라인이 실행될 때 그 상수는 지정한 값을 갖게 됩니다.
값은
GPUPipelineConstantValue
로 지정하며,double
입니다. 파이프라인 오버라이드 가능 상수의 WGSL 타입(bool
/i32
/u32
/f32
/f16
)로 변환됩니다. 변환에 실패하면 유효성 검사 오류가 발생합니다.WGSL에서 정의된 파이프라인 오버라이드 가능 상수 예시:@id ( 0 ) override has_point_light : bool= true ; // 알고리즘 제어. @id ( 1200 ) override specular_param : f32= 2.3 ; // 숫자 제어. @id ( 1300 ) override gain : f32; // 반드시 오버라이드 필요. override width : f32= 0.0 ; // API 레벨에서 지정 // 이름 "width" 사용. override depth : f32; // API 레벨에서 지정 // 이름 "depth" 사용. // 반드시 오버라이드 필요. override height = 2 * depth ; // 기본값은 // (API에서 지정하지 않으면), // 다른 오버라이드 가능 상수에 따라 결정됨. 기본값이 없는 오버라이드 필수 상수만 제공한 JS 코드 예시:
{ // ... constants: { 1300 : 2.0 , // "gain" depth: - 1 , // "depth" } } 모든 상수 오버라이드 JS 코드 예시:
{ // ... constants: { 0 : false , // "has_point_light" 1200 : 3.0 , // "specular_param" 1300 : 2.0 , // "gain" width: 20 , // "width" depth: - 1 , // "depth" height: 15 , // "height" } }
GPUShaderStage
stage,
GPUProgrammableStage
descriptor에 대해
엔트리
포인트 가져오기를 실행하려면,
다음 디바이스 타임라인 단계를 수행하세요:
-
만약 descriptor.
entryPoint
가 제공된 경우:-
descriptor.
module
에 descriptor.entryPoint
와 이름이 같고, 셰이더 스테이지가 stage와 같은 엔트리 포인트가 있으면 그 엔트리 포인트를 반환합니다.그렇지 않으면
null
을 반환합니다.
그 외의 경우:
-
descriptor.
module
에 셰이더 스테이지가 stage인 엔트리 포인트가 정확히 하나만 있으면 그 엔트리 포인트를 반환합니다.그렇지 않으면
null
을 반환합니다.
-
인수:
-
GPUShaderStage
stage -
GPUProgrammableStage
descriptor -
GPUPipelineLayout
layout -
GPUDevice
device
아래 단계의 모든 요구사항을 반드시 만족해야 합니다.
하나라도 만족하지 않으면 false
를 반환하고, 모두 만족하면 true
를 반환합니다.
-
descriptor.
module
은 device와 사용 가능(valid to use with) 상태여야 합니다. -
entryPoint를 엔트리 포인트 가져오기(stage, descriptor)로 설정합니다.
-
entryPoint는
null
이 아니어야 합니다. -
entryPoint가 정적으로 사용하는 각 binding에 대해:
-
셰이더 바인딩 유효성 검사(binding, layout)는 반드시
true
를 반환해야 합니다.
-
-
루트 entryPoint에 있는 셰이더 스테이지 내 함수들의 모든 texture 내장 함수 호출에 대해, 샘플링된 텍스처(sampled texture) 또는 depth texture 타입의 textureBinding과,
sampler
타입(단,sampler_comparison
제외)의 samplerBinding을 함께 사용할 때:-
texture를 textureBinding에 해당하는
GPUBindGroupLayoutEntry
로 설정합니다. -
sampler를 samplerBinding에 해당하는
GPUBindGroupLayoutEntry
로 설정합니다. -
sampler.
type
이"filtering"
인 경우, texture.sampleType
은 반드시"float"
여야 합니다.
Note:
"comparison"
샘플러는"depth"
텍스처와만 사용할 수 있습니다. WGSLtexture_depth_*
바인딩에 연결할 수 있는 유일한 텍스처 타입입니다. -
-
descriptor.
constants
의 각 key → value에 대해:-
key는 반드시 셰이더 모듈 descriptor.
module
에 정의된 파이프라인 오버라이드 가능 상수 중 하나의 식별자 문자열과 같아야 하며, 비교는 WGSL 식별자 비교 규칙을 따릅니다. 파이프라인 오버라이드 가능 상수는 entryPoint에 정적으로 사용될 필요는 없습니다. 그 상수의 타입을 T라 합니다.
-
-
entryPoint에 파이프라인 오버라이드 상수 식별자 문자열 key가 정적으로 사용되는 모든 경우:
인수:
-
셰이더 바인딩 선언 variable (셰이더 모듈에서 반영된 모듈 범위의 변수 선언)
-
GPUPipelineLayout
layout
bindGroup을 바인드 그룹 인덱스로, bindIndex를 바인딩 인덱스로, 셰이더 바인딩 선언 variable에서 얻어옵니다.
아래 조건을 모두 만족하면 true
를 반환합니다:
-
layout.
[[bindGroupLayouts]]
[bindGroup] 에 bindIndex와 같은GPUBindGroupLayoutEntry
entry가 포함되어 있습니다. -
entry의 binding member가 다음과 같으면:
buffer
-
"uniform"
-
variable이
uniform
주소 공간으로 선언되어 있습니다. "storage"
-
variable이
storage
주소 공간과read_write
접근 모드로 선언되어 있습니다. "read-only-storage"
-
variable이
storage
주소 공간과read
접근 모드로 선언되어 있습니다.
entry.
buffer
.minBindingSize
가0
이 아니면, 반드시 셰이더의 해당 버퍼 바인딩 변수의 최소 버퍼 바인딩 크기 이상이어야 합니다. sampler
-
entry.
sampler
.type
이 다음 타입일 때:"filtering"
또는"non-filtering"
-
variable은
sampler
타입입니다. "comparison"
-
variable은
sampler_comparison
타입입니다.
texture
-
오직 다음의 경우에만, entry.
texture
.multisampled
가true
이면, variable은texture_multisampled_2d<T>
또는texture_depth_multisampled_2d<T>
타입입니다.entry.
texture
.sampleType
이 다음 타입일 때:"float"
,"unfilterable-float"
,"sint"
또는"uint"
-
variable은 다음 타입 중 하나입니다:
-
texture_1d<T>
-
texture_2d<T>
-
texture_2d_array<T>
-
texture_cube<T>
-
texture_cube_array<T>
-
texture_3d<T>
-
texture_multisampled_2d<T>
entry.
texture
.sampleType
이 다음 타입일 때:"float"
또는"unfilterable-float"
-
샘플 타입
T
는f32
입니다. "sint"
-
샘플 타입
T
는i32
입니다. "uint"
-
샘플 타입
T
는u32
입니다.
-
"depth"
-
variable은 다음 타입 중 하나입니다:
-
texture_2d<T>
-
texture_2d_array<T>
-
texture_cube<T>
-
texture_cube_array<T>
-
texture_multisampled_2d<T>
-
texture_depth_2d
-
texture_depth_2d_array
-
texture_depth_cube
-
texture_depth_cube_array
-
texture_depth_multisampled_2d
여기서 샘플 타입
T
는f32
입니다. -
entry.
texture
.viewDimension
이 다음일 때:"1d"
-
variable은
texture_1d<T>
타입입니다. "2d"
-
variable은
texture_2d<T>
또는texture_multisampled_2d<T>
타입입니다. "2d-array"
-
variable은
texture_2d_array<T>
타입입니다. "cube"
-
variable은
texture_cube<T>
타입입니다. "cube-array"
-
variable은
texture_cube_array<T>
타입입니다. "3d"
-
variable은
texture_3d<T>
타입입니다.
storageTexture
-
entry.
storageTexture
.viewDimension
이 다음일 때:"1d"
-
variable은
texture_storage_1d<T, A>
타입입니다. "2d"
-
variable은
texture_storage_2d<T, A>
타입입니다. "2d-array"
-
variable은
texture_storage_2d_array<T, A>
타입입니다. "3d"
-
variable은
texture_storage_3d<T, A>
타입입니다.
entry.
storageTexture
.access
이 다음일 때:"write-only"
-
접근 모드
A
는write
입니다. "read-only"
-
접근 모드
A
는read
입니다. "read-write"
-
접근 모드
A
는read_write
또는write
입니다.
텍셀 포맷
T
는 entry.storageTexture
.format
과 같습니다.
-
T를 저장 타입으로 설정합니다.
-
T가 런타임 크기 배열이거나, 런타임 크기 배열을 포함하고 있다면, 해당
array<E>
를array<E, 1>
로 대체합니다.Note: 이렇게 하면 항상 한 개의 요소를 위한 메모리가 확보되어, 배열 인덱스를 배열 길이에 맞게 클램프하여 인-메모리 접근이 가능하게 됩니다.
-
SizeOf(T)를 반환합니다.
Note: 이 하한을 강제하면 버퍼 변수로 읽고 쓸 때 항상 버퍼의 경계 내 메모리 위치만 접근하도록 보장합니다.
10.2. GPUComputePipeline
GPUComputePipeline
은
파이프라인의 한 종류로서,
컴퓨트 셰이더 스테이지를 제어하며,
GPUComputePassEncoder
에서
사용할 수 있습니다.
컴퓨트 입력과 출력은 모두 지정된 GPUPipelineLayout
에
따라 바인딩에 포함됩니다.
출력은 buffer
바인딩(타입 "storage"
),
storageTexture
바인딩(타입
"write-only"
또는
"read-write"
)에
해당합니다.
컴퓨트 파이프라인의 스테이지:
-
컴퓨트 셰이더
[Exposed =(Window ,Worker ),SecureContext ]interface GPUComputePipeline { };GPUComputePipeline includes GPUObjectBase ;GPUComputePipeline includes GPUPipelineBase ;
10.2.1. 컴퓨트 파이프라인 생성
GPUComputePipelineDescriptor
는
컴퓨트 파이프라인을 설명합니다. 자세한 내용은 § 23.1 컴퓨팅을 참고하세요.
dictionary :
GPUComputePipelineDescriptor GPUPipelineDescriptorBase {required GPUProgrammableStage compute ; };
GPUComputePipelineDescriptor
는
다음 멤버를 가집니다:
compute
, 타입 GPUProgrammableStage-
파이프라인의 컴퓨트 셰이더 엔트리 포인트를 설명합니다.
createComputePipeline(descriptor)
-
즉시 파이프라인 생성을 통해
GPUComputePipeline
을 생성합니다.호출 대상:GPUDevice
this.인수:
GPUDevice.createComputePipeline(descriptor) 메서드의 인수. 파라미터 타입 Nullable Optional 설명 descriptor
GPUComputePipelineDescriptor
✘ ✘ 생성할 GPUComputePipeline
에 대한 설명.반환값:
GPUComputePipeline
콘텐츠 타임라인 단계:
-
pipeline을 ! 새로운 WebGPU 객체 생성(this,
GPUComputePipeline
, descriptor)로 설정합니다. -
this의 디바이스 타임라인에서 초기화 단계를 수행합니다.
-
pipeline을 반환합니다.
디바이스 타임라인 초기화 단계:-
layout을 pipeline에 대해 기본 파이프라인 레이아웃으로 설정합니다. 단, descriptor.
layout
이"auto"
인 경우에만, 그렇지 않으면 descriptor.layout
을 사용합니다. -
아래 단계의 모든 요구사항을 반드시 만족해야 합니다. 하나라도 만족하지 않으면 유효성 검사 오류 생성, 무효화 pipeline 그리고 반환합니다.
-
layout은 this와 사용 가능(valid to use with) 상태여야 합니다.
-
GPUProgrammableStage 유효성 검사(
COMPUTE
, descriptor.compute
, layout, this)가 반드시 성공해야 합니다. -
entryPoint를 엔트리 포인트 가져오기(
COMPUTE
, descriptor.compute
)로 설정합니다.Assert entryPoint가
null
이 아님을 확인합니다. -
workgroupStorageUsed를 루트 entryPoint가 workgroup 주소 공간을 가진 정적으로 사용되는 모든 변수의 타입 T에 대해 roundUp(16, SizeOf(T))의 합으로 설정합니다.
workgroupStorageUsed는 반드시 device.limits.
maxComputeWorkgroupStorageSize
이하여야 합니다. -
entryPoint는 반드시 device.limits.
maxComputeInvocationsPerWorkgroup
이하의 workgroup 내 invocations만 사용해야 합니다. -
entryPoint의
workgroup_size
속성의 각 컴포넌트는 반드시 아래와 같은 대응하는 컴포넌트 값 이하여야 합니다: [device.limits.maxComputeWorkgroupSizeX
, device.limits.maxComputeWorkgroupSizeY
, device.limits.maxComputeWorkgroupSizeZ
].
-
-
파이프라인 생성 구현에서 파이프라인 생성 분류되지 않은 오류가 발생하면, 내부 오류 생성, 무효화 pipeline 그리고 반환합니다.
Note: 구현에서 셰이더 모듈 생성 시 분류되지 않은 오류를 감지했다면, 해당 오류는 이 단계에서 표면화됩니다.
-
pipeline.
[[layout]]
을 layout으로 설정합니다.
-
createComputePipelineAsync(descriptor)
-
비동기 파이프라인 생성을 통해
GPUComputePipeline
을 생성합니다. 반환된Promise
는 생성된 파이프라인이 추가 지연 없이 사용 가능해질 때 resolve됩니다.파이프라인 생성이 실패하면 반환된
Promise
는GPUPipelineError
로 reject됩니다. (GPUError
는 디바이스로 dispatch되지 않습니다.)Note: 가능한 경우 이 메서드 사용을 권장합니다. 파이프라인 컴파일로 큐 타임라인 작업이 블록되는 것을 방지할 수 있습니다.
호출 대상:GPUDevice
this.인수:
GPUDevice.createComputePipelineAsync(descriptor) 메서드의 인수. 파라미터 타입 Nullable Optional 설명 descriptor
GPUComputePipelineDescriptor
✘ ✘ 생성할 GPUComputePipeline
에 대한 설명.반환값:
Promise
<GPUComputePipeline
>콘텐츠 타임라인 단계:
-
contentTimeline을 현재 콘텐츠 타임라인으로 설정합니다.
-
promise를 새로운 promise로 설정합니다.
-
this의 디바이스 타임라인에서 초기화 단계를 수행합니다.
-
promise를 반환합니다.
디바이스 타임라인 초기화 단계:-
pipeline을 this.
createComputePipeline()
을 descriptor로 호출한 것처럼 생성하되, 오류는 디바이스로 디스패치하지 않고 error로 캡처합니다. -
pipeline에 대한 파이프라인 생성이 성공 또는 실패할 때 event가 발생하도록 설정합니다.
-
타임라인 이벤트 수신 event 를 this.
[[device]]
에서 수행하며, 이후 단계는 디바이스 타임라인에서 처리합니다.
디바이스 타임라인 단계:-
pipeline이 유효하거나 this가 lost 상태면:
-
아래 단계를 contentTimeline에서 실행합니다:
-
반환합니다.
Note: lost된 디바이스에서는 오류가 생성되지 않습니다. § 22 오류 및 디버깅 참고.
-
-
pipeline이 무효이고 error가 내부 오류일 경우, 아래 단계를 contentTimeline에서 실행하고 반환합니다.
콘텐츠 타임라인 단계:-
promise를
GPUPipelineError
와 함께 reject합니다.reason
값은"internal"
입니다.
-
-
pipeline이 무효이고 error가 유효성 검사 오류일 경우, 아래 단계를 contentTimeline에서 실행하고 반환합니다.
콘텐츠 타임라인 단계:-
promise를
GPUPipelineError
와 함께 reject합니다.reason
값은"validation"
입니다.
-
-
GPUComputePipeline
생성 예시:
const computePipeline= gpuDevice. createComputePipeline({ layout: pipelineLayout, compute: { module: computeShaderModule, entryPoint: 'computeMain' , } });
10.3. GPURenderPipeline
GPURenderPipeline
은
파이프라인의 한 종류로서,
버텍스 및 프래그먼트 셰이더 스테이지를 제어하며,
GPURenderPassEncoder
와 GPURenderBundleEncoder
에서
사용할 수 있습니다.
렌더 파이프라인의 입력값:
-
주어진
GPUPipelineLayout
에 따른 바인딩 -
GPUVertexState
로 기술된 버텍스 및 인덱스 버퍼 -
GPUColorTargetState
로 기술된 컬러 어태치먼트 -
선택적으로,
GPUDepthStencilState
로 기술된 깊이-스텐실 어태치먼트
렌더 파이프라인의 출력값:
-
storageTexture
바인딩 (access
이"write-only"
또는"read-write"
) -
GPUColorTargetState
로 기술된 컬러 어태치먼트 -
선택적으로,
GPUDepthStencilState
로 기술된 깊이-스텐실 어태치먼트
렌더 파이프라인은 다음 렌더 스테이지들로 구성됩니다:
-
버텍스 fetch (
GPUVertexState.buffers
로 제어) -
버텍스 셰이더 (
GPUVertexState
로 제어) -
도형 조립 (
GPUPrimitiveState
로 제어) -
래스터화 (
GPUPrimitiveState
,GPUDepthStencilState
,GPUMultisampleState
로 제어) -
프래그먼트 셰이더 (
GPUFragmentState
로 제어) -
스텐실 테스트 및 연산 (
GPUDepthStencilState
로 제어) -
깊이 테스트 및 쓰기 (
GPUDepthStencilState
로 제어) -
출력 머징 (
GPUFragmentState.targets
로 제어)
[Exposed =(Window ,Worker ),SecureContext ]interface GPURenderPipeline { };GPURenderPipeline includes GPUObjectBase ;GPURenderPipeline includes GPUPipelineBase ;
GPURenderPipeline
는
다음 디바이스
타임라인 속성을 가집니다:
[[descriptor]]
, 타입GPURenderPipelineDescriptor
, 읽기 전용-
이 파이프라인을 기술하는
GPURenderPipelineDescriptor
입니다.모든 선택적 필드는
GPURenderPipelineDescriptor
에서 정의됩니다. [[writesDepth]]
, 타입boolean
, 읽기 전용-
파이프라인이 깊이/스텐실 어태치먼트의 깊이 컴포넌트에 쓰는 경우 true
[[writesStencil]]
, 타입boolean
, 읽기 전용-
파이프라인이 깊이/스텐실 어태치먼트의 스텐실 컴포넌트에 쓰는 경우 true
10.3.1. 렌더 파이프라인 생성
GPURenderPipelineDescriptor
는
각 렌더 스테이지를 구성하여 렌더 파이프라인을 설명합니다. 자세한 내용은 § 23.2 렌더링을 참고하세요.
dictionary :
GPURenderPipelineDescriptor GPUPipelineDescriptorBase {required GPUVertexState vertex ;GPUPrimitiveState primitive = {};GPUDepthStencilState depthStencil ;GPUMultisampleState multisample = {};GPUFragmentState fragment ; };
GPURenderPipelineDescriptor
는
다음 멤버를 가집니다:
vertex
, 타입 GPUVertexState-
파이프라인의 버텍스 셰이더 엔트리 포인트와 입력 버퍼 레이아웃을 설명합니다.
primitive
, 타입 GPUPrimitiveState, 기본값{}
-
파이프라인의 도형 관련 속성을 설명합니다.
depthStencil
, 타입 GPUDepthStencilState-
테스트, 연산, 바이어스 등 선택적 깊이-스텐실 속성을 설명합니다.
multisample
, 타입 GPUMultisampleState, 기본값{}
-
파이프라인의 멀티샘플링 속성을 설명합니다.
fragment
, 타입 GPUFragmentState-
파이프라인의 프래그먼트 셰이더 엔트리 포인트와 출력 색상을 설명합니다. 제공되지 않은 경우 § 23.2.8 컬러 출력 없음 모드가 활성화됩니다.
createRenderPipeline(descriptor)
-
즉시 파이프라인 생성으로
GPURenderPipeline
을 생성합니다.호출 대상:GPUDevice
this.인수:
GPUDevice.createRenderPipeline(descriptor) 메서드의 인수. 파라미터 타입 Nullable Optional 설명 descriptor
GPURenderPipelineDescriptor
✘ ✘ 생성할 GPURenderPipeline
에 대한 설명.반환값:
GPURenderPipeline
콘텐츠 타임라인 단계:
-
-
모든 non-
null
colorState에 대해 descriptor.fragment
.targets
:-
? 텍스처 포맷 요구 기능 유효성 검사를 colorState.
format
및 this.[[device]]
으로 수행합니다.
-
-
-
descriptor.
depthStencil
가 제공된 경우:-
? 텍스처 포맷 요구 기능 유효성 검사를 descriptor.
depthStencil
.format
및 this.[[device]]
으로 수행합니다.
-
-
pipeline을 ! 새로운 WebGPU 객체 생성(this,
GPURenderPipeline
, descriptor)로 설정합니다. -
this의 디바이스 타임라인에서 초기화 단계를 수행합니다.
-
pipeline을 반환합니다.
디바이스 타임라인 초기화 단계:-
layout을 pipeline에 대해 기본 파이프라인 레이아웃으로 설정합니다. 단, descriptor.
layout
이"auto"
인 경우에만, 그렇지 않으면 descriptor.layout
을 사용합니다. -
아래 단계의 모든 요구사항을 반드시 만족해야 합니다. 하나라도 만족하지 않으면 유효성 검사 오류 생성, 무효화 pipeline 그리고 반환합니다.
-
layout은 this와 사용 가능(valid to use with) 상태여야 합니다.
-
GPURenderPipelineDescriptor 유효성 검사(descriptor, layout, this)가 반드시 성공해야 합니다.
-
vertexBufferCount를 descriptor.
vertex
.buffers
에서 마지막 non-null 항목의 인덱스 + 1로 설정하고, 항목이 없다면 0으로 설정합니다. -
layout.
[[bindGroupLayouts]]
.size + vertexBufferCount는 this.[[device]]
.[[limits]]
.maxBindGroupsPlusVertexBuffers
이하여야 합니다.
-
-
파이프라인 생성 구현에서 파이프라인 생성 분류되지 않은 오류가 발생하면, 내부 오류 생성, 무효화 pipeline 그리고 반환합니다.
Note: 구현에서 셰이더 모듈 생성 시 분류되지 않은 오류를 감지했다면, 해당 오류는 이 단계에서 표면화됩니다.
-
pipeline.
[[descriptor]]
을 descriptor로 설정합니다. -
pipeline.
[[writesDepth]]
를 false로 설정합니다. -
pipeline.
[[writesStencil]]
를 false로 설정합니다. -
depthStencil를 descriptor.
depthStencil
로 설정합니다. -
depthStencil가 null이 아니면:
-
depthStencil.
depthWriteEnabled
가 제공된 경우:-
pipeline.
[[writesDepth]]
를 depthStencil.depthWriteEnabled
값으로 설정합니다.
-
-
depthStencil.
stencilWriteMask
가 0이 아니면:-
stencilFront를 depthStencil.
stencilFront
로 설정합니다. -
stencilBack를 depthStencil.
stencilBack
로 설정합니다. -
cullMode가
"front"
가 아니고, stencilFront.passOp
, stencilFront.depthFailOp
, 또는 stencilFront.failOp
중 하나라도"keep"
가 아니라면:-
pipeline.
[[writesStencil]]
을 true로 설정한다.
-
-
cullMode가
"back"
가 아니고, stencilBack.passOp
, stencilBack.depthFailOp
, 또는 stencilBack.failOp
중 하나라도"keep"
가 아니라면:-
pipeline.
[[writesStencil]]
을 true로 설정한다.
-
-
-
-
pipeline.
[[layout]]
을 layout으로 설정한다.
-
createRenderPipelineAsync(descriptor)
-
GPURenderPipeline
을 비동기 파이프라인 생성을 사용하여 생성한다. 반환되는Promise
는 생성된 파이프라인이 추가적인 지연 없이 사용할 준비가 되었을 때 resolve된다.파이프라인 생성에 실패하면, 반환된
Promise
는GPUPipelineError
로 reject된다. (GPUError
는 디바이스에 디스패치되지 않는다.)참고: 가능한 경우 이 메서드의 사용이 권장된다. 파이프라인 컴파일 시 큐 타임라인 작업이 막히는 것을 방지하기 때문이다.
호출 대상:GPUDevice
this.인자:
GPUDevice.createRenderPipelineAsync(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPURenderPipelineDescriptor
✘ ✘ 생성할 GPURenderPipeline
의 설명.반환값:
Promise
<GPURenderPipeline
>콘텐츠 타임라인 단계:
-
현재 콘텐츠 타임라인을 contentTimeline으로 한다.
-
promise를 새로운 Promise로 한다.
-
this의 디바이스 타임라인에서 초기화 단계를 수행한다.
-
promise를 반환한다.
디바이스 타임라인 초기화 단계:-
pipeline을
GPURenderPipeline
의 새 인스턴스로 생성한다. 이 때 this.createRenderPipeline()
를 descriptor로 호출한 것처럼 처리하되, 오류는 디바이스에 디스패치하지 않고 error로 캡처한다. -
pipeline의 파이프라인 생성이 완료(성공 또는 실패)될 때 event가 발생한다.
-
타임라인 이벤트 수신 event를 this.
[[device]]
에서 수신하고, 이후 단계는 this의 디바이스 타임라인에서 처리한다.
디바이스 타임라인 단계:-
pipeline이 유효하거나, this가 lost 상태라면:
-
contentTimeline에서 다음 단계를 수행한다:
-
Return.
참고: lost 상태의 디바이스에서는 오류가 발생하지 않는다. § 22 오류 및 디버깅 참고.
-
-
pipeline이 무효이고, error가 내부 오류라면, contentTimeline에서 다음 단계를 수행하고 return한다.
콘텐츠 타임라인 단계:-
reject promise에
GPUPipelineError
와reason
"internal"
을 전달한다.
-
-
pipeline이 무효이고, error가 검증 오류라면, contentTimeline에서 다음 단계를 수행하고 return한다.
콘텐츠 타임라인 단계:-
reject promise에
GPUPipelineError
와reason
"validation"
을 전달한다.
-
-
인자:
-
GPURenderPipelineDescriptor
descriptor -
GPUPipelineLayout
layout -
GPUDevice
device
디바이스 타임라인 단계:
-
다음 조건이 모두 만족되면
true
를 반환한다:-
GPUVertexState 유효성 검사(device, descriptor.
vertex
, layout)가 성공한다. -
-
GPUFragmentState 유효성 검사(device, descriptor.
fragment
, layout)가 성공한다. -
sample_mask 내장값이 셰이더 스테이지 출력이라면 descriptor.
fragment
의 경우:-
descriptor.
multisample
.alphaToCoverageEnabled
값이false
여야 한다.
-
-
frag_depth 내장값이 셰이더 스테이지 출력이라면 descriptor.
fragment
의 경우:-
descriptor.
depthStencil
이 제공되어야 하며, descriptor.depthStencil
.format
은 깊이 aspect를 가져야 한다.
-
-
-
GPUPrimitiveState 유효성 검사(descriptor.
primitive
, device)가 성공한다. -
descriptor.
depthStencil
이 제공된 경우:-
GPUDepthStencilState 유효성 검사(descriptor.
depthStencil
, descriptor.primitive
.topology
) 가 성공한다.
-
-
GPUMultisampleState 유효성 검사(descriptor.
multisample
) 가 성공한다. -
descriptor.
multisample
.alphaToCoverageEnabled
값이 true인 경우: -
적어도 하나의 attachment가 존재해야 한다. 다음 중 하나:
-
descriptor.
depthStencil
-
인터스테이지 인터페이스 유효성 검사(device, descriptor)가
true
를 반환한다.
-
인자:
-
GPUDevice
device -
GPURenderPipelineDescriptor
descriptor
반환값: boolean
디바이스 타임라인 단계:
-
maxVertexShaderOutputVariables를 device.limits.
maxInterStageShaderVariables
로 한다. -
maxVertexShaderOutputLocation을 device.limits.
maxInterStageShaderVariables
- 1로 한다. -
descriptor.
primitive
.topology
가"point-list"
인 경우:-
maxVertexShaderOutputVariables를 1 감소시킨다.
-
-
clip_distances가 descriptor.
vertex
출력에 선언된 경우:-
clipDistancesSize를 clip_distances 배열 크기로 한다.
-
maxVertexShaderOutputVariables를 ceil(clipDistancesSize / 4)만큼 감소시킨다.
-
maxVertexShaderOutputLocation을 ceil(clipDistancesSize / 4)만큼 감소시킨다.
-
-
다음 요구사항을 하나라도 만족하지 못하면
false
를 반환한다: -
-
maxFragmentShaderInputVariables를 device.limits.
maxInterStageShaderVariables
로 한다. -
front_facing
,sample_index
,sample_mask
내장값 중 하나라도 descriptor.fragment
입력이면:-
maxFragmentShaderInputVariables를 1 감소시킨다.
-
-
다음 요구사항을 하나라도 만족하지 못하면
false
를 반환한다: -
Assert: descriptor.
fragment
의 각 사용자 정의 입력의 location 값이 device.limits.maxInterStageShaderVariables
보다 작아야 한다. (위 규칙에서 따라옴)
-
-
true
를 반환한다.
GPURenderPipeline
생성 예시:
const renderPipeline= gpuDevice. createRenderPipeline({ layout: pipelineLayout, vertex: { module: shaderModule, entryPoint: 'vertexMain' }, fragment: { module: shaderModule, entryPoint: 'fragmentMain' , targets: [{ format: 'bgra8unorm' , }], } });
10.3.2. 프리미티브 상태
dictionary {
GPUPrimitiveState GPUPrimitiveTopology topology = "triangle-list";GPUIndexFormat stripIndexFormat ;GPUFrontFace frontFace = "ccw";GPUCullMode cullMode = "none"; // "depth-clip-control" 기능 필요.boolean unclippedDepth =false ; };
GPUPrimitiveState
는
다음 멤버를 가지며, GPURenderPipeline
이
버텍스 입력을 기반으로 프리미티브를 구성하고 래스터화하는 방식을 설명합니다:
topology
, 타입 GPUPrimitiveTopology, 기본값"triangle-list"
-
버텍스 입력으로부터 생성할 프리미티브의 유형입니다.
stripIndexFormat
, 타입 GPUIndexFormat-
스트립 토폴로지(
"line-strip"
또는"triangle-strip"
) 파이프라인에서 인덱스 버퍼 포맷 및 프리미티브 리스타트 값을 결정합니다("uint16"
/0xFFFF
또는"uint32"
/0xFFFFFFFF
). 비스트립 토폴로지 파이프라인에서는 사용할 수 없습니다.참고: 일부 구현은 파이프라인 상태 객체 컴파일 시 프리미티브 리스타트 값 정보를 필요로 합니다.
스트립 토폴로지 파이프라인에서 인덱스드 드로우 호출(
drawIndexed()
또는drawIndexedIndirect()
)을 사용할 때 반드시 설정해야 하며, 드로우 호출에서 사용하는 인덱스 버퍼 포맷(setIndexBuffer()
에서 설정)을 일치시켜야 합니다.자세한 내용은 § 23.2.3 프리미티브 조립을 참고하세요.
frontFace
, 타입 GPUFrontFace, 기본값"ccw"
-
어떤 폴리곤을 앞면으로 간주할지 정의합니다.
cullMode
, 타입 GPUCullMode, 기본값"none"
-
어떤 폴리곤 방향을 컬링(제거)할지 정의합니다.
unclippedDepth
, 타입 boolean, 기본값false
-
true인 경우 깊이 클리핑이 비활성화됨을 나타냅니다.
"depth-clip-control"
기능이 활성화되어 있어야 합니다.
-
GPUPrimitiveState
descriptor -
GPUDevice
device
디바이스 타임라인 단계:
-
다음 조건을 모두 만족하면
true
를 반환한다:-
descriptor.
topology
가"line-strip"
또는"triangle-strip"
가 아닌 경우:-
descriptor.
stripIndexFormat
이 제공되어 있으면 안 됨.
-
-
descriptor.
unclippedDepth
가true
인 경우:-
"depth-clip-control"
기능이 device에 대해 활성화되어 있어야 한다.
-
-
enum {
GPUPrimitiveTopology "point-list" ,"line-list" ,"line-strip" ,"triangle-list" ,"triangle-strip" , };
GPUPrimitiveTopology
는
GPURenderPipeline
으로
드로우 호출 시 사용할 프리미티브 타입을 정의합니다. 자세한 내용은 § 23.2.5 래스터화를 참고하세요:
"point-list"
-
각 버텍스가 하나의 포인트 프리미티브를 정의합니다.
"line-list"
-
연속된 두 버텍스가 하나의 라인 프리미티브를 정의합니다.
"line-strip"
-
첫 번째 이후 각 버텍스가 이전 버텍스와 함께 하나의 라인 프리미티브를 정의합니다.
"triangle-list"
-
연속된 세 버텍스가 하나의 삼각형 프리미티브를 정의합니다.
"triangle-strip"
-
첫 두 버텍스 이후 각 버텍스가 앞의 두 버텍스와 함께 하나의 삼각형 프리미티브를 정의합니다.
enum {
GPUFrontFace "ccw" ,"cw" , };
GPUFrontFace
는
GPURenderPipeline
이
폴리곤을 앞면으로 간주하는 방식을 정의합니다. 자세한
내용은 § 23.2.5.4 폴리곤 래스터화를 참고하세요:
enum {
GPUCullMode "none" ,"front" ,"back" , };
GPUPrimitiveTopology
는
GPURenderPipeline
으로
드로우 호출 시 컬링될 폴리곤을 정의합니다. 자세한 내용은 § 23.2.5.4 폴리곤 래스터화를 참고하세요:
참고: GPUFrontFace
와
GPUCullMode
는
"point-list"
,
"line-list"
,
"line-strip"
토폴로지에서는 효과가 없습니다.
10.3.3. 멀티샘플 상태
dictionary {
GPUMultisampleState GPUSize32 count = 1;GPUSampleMask mask = 0xFFFFFFFF;boolean alphaToCoverageEnabled =false ; };
GPUMultisampleState
는 GPURenderPipeline
이
렌더 패스의 멀티샘플링된 attachment와 상호작용하는 방식을 설명하는 다음 멤버들을 갖습니다.
count
, 타입 GPUSize32, 기본값1
-
픽셀 당 샘플 개수. 이
GPURenderPipeline
은colorAttachments
및depthStencilAttachment
와 같이sampleCount
가 동일한 attachment 텍스처와만 호환됩니다. mask
, 타입 GPUSampleMask, 기본값0xFFFFFFFF
-
샘플 중 어떤 샘플에 쓸지 결정하는 마스크입니다.
alphaToCoverageEnabled
, 타입 boolean, 기본값false
-
true
인 경우, 프래그먼트의 알파 채널을 샘플 커버리지 마스크 생성에 사용함을 의미합니다.
-
GPUMultisampleState
descriptor
디바이스 타임라인 단계:
-
다음 조건을 모두 만족하면
true
를 반환한다:-
descriptor.
count
값은 1 또는 4이어야 한다. -
descriptor.
alphaToCoverageEnabled
가true
인 경우:-
descriptor.
count
값이 1보다 커야 한다.
-
-
10.3.4. 프래그먼트 상태
dictionary :
GPUFragmentState GPUProgrammableStage {required sequence <GPUColorTargetState ?>targets ; };
targets
, 타입sequence<GPUColorTargetState?>
-
이 파이프라인이 기록하는 컬러 타겟의 포맷과 동작을 정의하는
GPUColorTargetState
리스트입니다.
인자:
-
GPUDevice
device -
GPUFragmentState
descriptor -
GPUPipelineLayout
layout
디바이스 타임라인 단계:
-
다음 요구사항을 모두 만족하면
true
를 반환한다:-
GPUProgrammableStage 유효성 검사(
FRAGMENT
, descriptor, layout, device)가 성공한다. -
descriptor.
targets
.size가 device.[[limits]]
.maxColorAttachments
이하이어야 한다. -
entryPoint을 get the entry point(
FRAGMENT
, descriptor)로 한다. -
usesDualSourceBlending을
false
로 한다. -
각 index에 대해, descriptor.
targets
의 non-null
값 colorState:-
colorState.
format
은 § 26.1.1 일반 컬러 포맷에RENDER_ATTACHMENT
기능으로 나열되어 있어야 한다. -
colorState.
writeMask
값은 16 미만이어야 한다. -
-
colorState.
blend
.color
값은 유효한 GPUBlendComponent이어야 한다. -
colorState.
blend
.alpha
값은 유효한 GPUBlendComponent이어야 한다. -
colorState.
blend
.color
.srcFactor
또는 colorState.blend
.color
.dstFactor
또는 colorState.blend
.alpha
.srcFactor
또는 colorState.blend
.alpha
.dstFactor
값이 해당 블렌딩 유닛의 두 번째 입력을 사용하는 경우(즉,"src1"
,"one-minus-src1"
,"src1-alpha"
,"one-minus-src1-alpha"
중 하나라면):-
usesDualSourceBlending을
true
로 설정한다.
-
-
셰이더 스테이지 출력값 output 중 location 속성이 index인 것에 대해:
-
colorState.
format
의 각 컴포넌트에 해당하는 output의 컴포넌트가 존재해야 한다. (즉, RGBA는 vec4, RGB는 vec3 또는 vec4, RG는 vec2 또는 vec3 또는 vec4 필요) -
GPUTextureSampleType
이 colorState.format
에 대해(자세한 내용은 § 26.1 텍스처 포맷 기능 참조):"float"
및/또는"unfilterable-float"
-
output은 부동소수점 스칼라 타입이어야 한다.
"sint"
-
output은 signed 정수 스칼라 타입이어야 한다.
"uint"
-
output은 unsigned 정수 스칼라 타입이어야 한다.
-
colorState.
blend
값이 제공되고, colorState.blend
.color
.srcFactor
또는 .dstFactor
값이 source alpha를 사용하는 경우("src-alpha"
,"one-minus-src-alpha"
,"src-alpha-saturated"
,"src1-alpha"
또는"one-minus-src1-alpha"
중 하나라면):-
output은 알파 채널(vec4)을 가져야 한다.
-
-
-
colorState.
writeMask
값이 0이 아닌 경우:-
entryPoint는 셰이더 스테이지 출력 중 location이 index인 것이 존재해야 하며, blend_src가 생략되었거나 0이어야 한다.
-
-
-
usesDualSourceBlending이
true
인 경우:-
셰이더 스테이지 출력 중 location이 있는 모든 값이 한 struct에 있어야 하며, dual source blending을 사용해야 한다.
-
GPUFragmentState의 컬러 attachment 바이트/샘플 유효성 검사(device, descriptor.
targets
) 가 성공한다.
-
인자:
-
GPUDevice
device -
sequence<
GPUColorTargetState
?> targets
디바이스 타임라인 단계:
-
formats를 list<
GPUTextureFormat
?>의 빈 리스트로 한다. -
targets의 각 target에 대해:
-
컬러 attachment 바이트/샘플 계산(formats) 값이 device.
[[limits]]
.maxColorAttachmentBytesPerSample
이하이어야 한다.
참고: 프래그먼트 셰이더는 파이프라인에서 사용하는 것보다 더 많은 값을 출력할 수 있습니다. 이 경우 해당 값은 무시됩니다.
10.3.5. 컬러 타겟 상태
dictionary {
GPUColorTargetState required GPUTextureFormat format ;GPUBlendState blend ;GPUColorWriteFlags writeMask = 0xF; // GPUColorWrite.ALL };
format
, 타입 GPUTextureFormat-
이 컬러 타겟의
GPUTextureFormat
입니다. 파이프라인은GPURenderPassEncoder
가 해당 색상 attachment에 이 포맷의GPUTextureView
를 사용할 때만 호환됩니다. blend
, 타입 GPUBlendState-
이 컬러 타겟의 블렌딩 동작입니다. 지정하지 않으면 블렌딩이 비활성화됩니다.
writeMask
, 타입 GPUColorWriteFlags, 기본값0xF
-
이 컬러 타겟에 드로잉할 때 어떤 채널에 쓸지 제어하는 비트마스크입니다.
dictionary {
GPUBlendState required GPUBlendComponent color ;required GPUBlendComponent alpha ; };
color
, 타입 GPUBlendComponent-
해당 렌더 타겟의 컬러 채널의 블렌딩 동작을 정의합니다.
alpha
, 타입 GPUBlendComponent-
해당 렌더 타겟의 알파 채널의 블렌딩 동작을 정의합니다.
typedef [EnforceRange ]unsigned long ; [
GPUColorWriteFlags Exposed =(Window ,Worker ),SecureContext ]namespace {
GPUColorWrite const GPUFlagsConstant = 0x1;
RED const GPUFlagsConstant = 0x2;
GREEN const GPUFlagsConstant = 0x4;
BLUE const GPUFlagsConstant = 0x8;
ALPHA const GPUFlagsConstant = 0xF; };
ALL
10.3.5.1. 블렌드 상태
dictionary {
GPUBlendComponent GPUBlendOperation operation = "add";GPUBlendFactor srcFactor = "one";GPUBlendFactor dstFactor = "zero"; };
GPUBlendComponent
는 프래그먼트의 컬러 또는 알파 컴포넌트가 어떻게 블렌딩되는지 설명하는 다음 멤버들을 갖습니다:
operation
, 타입 GPUBlendOperation, 기본값"add"
-
타겟 attachment 컴포넌트에 기록되는 값을 계산하는 데 사용하는
GPUBlendOperation
을 정의합니다. srcFactor
, 타입 GPUBlendFactor, 기본값"one"
-
프래그먼트 셰이더에서 나온 값에 대해 수행할
GPUBlendFactor
연산을 정의합니다. dstFactor
, 타입 GPUBlendFactor, 기본값"zero"
-
타겟 attachment에서 나온 값에 대해 수행할
GPUBlendFactor
연산을 정의합니다.
다음 표들은 주어진 프래그먼트 위치에 대해 컬러 컴포넌트를 설명할 때 이 기호를 사용합니다:
RGBAsrc
| 컬러 attachment에 대해 프래그먼트 셰이더가 출력한 컬러. 셰이더가 알파 채널을 반환하지 않으면 src-alpha 블렌드 팩터는 사용할 수 없습니다. |
RGBAsrc1
| "@blend_src" 속성
이 1 인 컬러 attachment에 대해 프래그먼트 셰이더가 출력한 컬러.
셰이더가 알파 채널을 반환하지 않으면 src1-alpha 블렌드 팩터는 사용할 수 없습니다.
|
RGBAdst
| 컬러 attachment에 현재 있는 컬러.
green/blue/alpha 채널이 없으면 각각 0, 0, 1 로 기본값이 설정됩니다.
|
RGBAconst
| 현재 [[blendConstant]] .
|
RGBAsrcFactor
| srcFactor 에
의해 정의된 소스 블렌드 팩터 컴포넌트.
|
RGBAdstFactor
| dstFactor 에
의해 정의된 대상 블렌드 팩터 컴포넌트.
|
enum {
GPUBlendFactor "zero" ,"one" ,"src" ,"one-minus-src" ,"src-alpha" ,"one-minus-src-alpha" ,"dst" ,"one-minus-dst" ,"dst-alpha" ,"one-minus-dst-alpha" ,"src-alpha-saturated" ,"constant" ,"one-minus-constant" ,"src1" ,"one-minus-src1" ,"src1-alpha" ,"one-minus-src1-alpha" , };
GPUBlendFactor
는 소스 또는 대상 블렌드 팩터가 어떻게 계산되는지 정의합니다:
GPUBlendFactor | 블렌드 팩터 RGBA 컴포넌트 | 기능 |
---|---|---|
"zero"
| (0, 0, 0, 0)
| |
"one"
| (1, 1, 1, 1)
| |
"src"
| (Rsrc, Gsrc, Bsrc, Asrc)
| |
"one-minus-src"
| (1 - Rsrc, 1 - Gsrc, 1 - Bsrc, 1 - Asrc)
| |
"src-alpha"
| (Asrc, Asrc, Asrc, Asrc)
| |
"one-minus-src-alpha"
| (1 - Asrc, 1 - Asrc, 1 - Asrc, 1 - Asrc)
| |
"dst"
| (Rdst, Gdst, Bdst, Adst)
| |
"one-minus-dst"
| (1 - Rdst, 1 - Gdst, 1 - Bdst, 1 - Adst)
| |
"dst-alpha"
| (Adst, Adst, Adst, Adst)
| |
"one-minus-dst-alpha"
| (1 - Adst, 1 - Adst, 1 - Adst, 1 - Adst)
| |
"src-alpha-saturated"
| (min(Asrc, 1 - Adst), min(Asrc, 1 - Adst), min(Asrc, 1 - Adst), 1)
| |
"constant"
| (Rconst, Gconst, Bconst, Aconst)
| |
"one-minus-constant"
| (1 - Rconst, 1 - Gconst, 1 - Bconst, 1 - Aconst)
| |
"src1"
| (Rsrc1, Gsrc1, Bsrc1, Asrc1)
| dual-source-blending
|
"one-minus-src1"
| (1 - Rsrc1, 1 - Gsrc1, 1 - Bsrc1, 1 - Asrc1)
| |
"src1-alpha"
| (Asrc1, Asrc1, Asrc1, Asrc1)
| |
"one-minus-src1-alpha"
| (1 - Asrc1, 1 - Asrc1, 1 - Asrc1, 1 - Asrc1)
|
enum {
GPUBlendOperation "add" ,"subtract" ,"reverse-subtract" ,"min" ,"max" , };
GPUBlendOperation
은 소스와 대상 블렌드 팩터를 결합하는 알고리즘을 정의합니다:
GPUBlendOperation | RGBA 컴포넌트 |
---|---|
"add"
| RGBAsrc × RGBAsrcFactor + RGBAdst × RGBAdstFactor
|
"subtract"
| RGBAsrc × RGBAsrcFactor - RGBAdst × RGBAdstFactor
|
"reverse-subtract"
| RGBAdst × RGBAdstFactor - RGBAsrc × RGBAsrcFactor
|
"min"
| min(RGBAsrc, RGBAdst)
|
"max"
| max(RGBAsrc, RGBAdst)
|
10.3.6. 깊이/스텐실 상태
dictionary {
GPUDepthStencilState required GPUTextureFormat format ;boolean depthWriteEnabled ;GPUCompareFunction depthCompare ;GPUStencilFaceState stencilFront = {};GPUStencilFaceState stencilBack = {};GPUStencilValue stencilReadMask = 0xFFFFFFFF;GPUStencilValue stencilWriteMask = 0xFFFFFFFF;GPUDepthBias depthBias = 0;float depthBiasSlopeScale = 0;float depthBiasClamp = 0; };
GPUDepthStencilState
는 GPURenderPipeline
이 렌더 패스의 depthStencilAttachment
에
어떤 영향을 미치는지 설명하는 다음 멤버들을 갖습니다:
format
, 타입 GPUTextureFormat-
이
GPURenderPipeline
이 호환되는depthStencilAttachment
의format
입니다. depthWriteEnabled
, 타입 boolean-
이
GPURenderPipeline
이depthStencilAttachment
의 깊이 값을 변경할 수 있는지 나타냅니다. depthCompare
, 타입 GPUCompareFunction-
프래그먼트의 깊이 값과
depthStencilAttachment
깊이 값을 비교하는 데 사용되는 연산입니다. stencilFront
, 타입 GPUStencilFaceState, 기본값{}
-
앞면 프리미티브에 대해 스텐실 비교 및 연산이 어떻게 수행되는지 정의합니다.
stencilBack
, 타입 GPUStencilFaceState, 기본값{}
-
뒷면 프리미티브에 대해 스텐실 비교 및 연산이 어떻게 수행되는지 정의합니다.
stencilReadMask
, 타입 GPUStencilValue, 기본값0xFFFFFFFF
-
스텐실 비교 테스트를 수행할 때
depthStencilAttachment
스텐실 값 비트 중 어느 비트를 읽을지 제어하는 비트마스크입니다. stencilWriteMask
, 타입 GPUStencilValue, 기본값0xFFFFFFFF
-
스텐실 연산을 수행할 때
depthStencilAttachment
스텐실 값 비트 중 어느 비트를 쓸지 제어하는 비트마스크입니다. depthBias
, 타입 GPUDepthBias, 기본값0
-
각 삼각형 프래그먼트에 더해지는 상수 깊이 바이어스입니다. 자세한 내용은 바이어스된 프래그먼트 깊이를 참고하세요.
depthBiasSlopeScale
, 타입 float, 기본값0
-
삼각형 프래그먼트의 기울기에 따라 스케일되는 깊이 바이어스입니다. 자세한 내용은 바이어스된 프래그먼트 깊이를 참고하세요.
depthBiasClamp
, 타입 float, 기본값0
-
삼각형 프래그먼트의 최대 깊이 바이어스입니다. 자세한 내용은 바이어스된 프래그먼트 깊이를 참고하세요.
참고: depthBias
,
depthBiasSlopeScale
,
그리고
depthBiasClamp
는 "point-list"
,
"line-list"
,
그리고 "line-strip"
프리미티브에는 영향을 주지 않으며, 0이어야 합니다.
depthStencilAttachment
attachment에 기록되는 프래그먼트에 대해
GPUDepthStencilState
state를 사용할 때 다음 큐
타임라인 단계를 따라 계산됩니다:
-
r을 format에서 32비트 float로 변환한 0보다 큰 최소 양의 표현값으로 한다.
-
maxDepthSlope을 프래그먼트의 깊이 값의 수평 및 수직 기울기 중 최대값으로 한다.
-
format이 unorm 포맷인 경우:
-
bias를
(float)state.
로 한다.depthBias
* r + state.depthBiasSlopeScale
* maxDepthSlope
-
-
그 외에 format이 float 포맷인 경우:
-
bias를
(float)state.
로 한다.depthBias
* 2^(exp(max depth in primitive) - r) + state.depthBiasSlopeScale
* maxDepthSlope
-
-
state.
depthBiasClamp
>0
인 경우:-
bias를
min(state.
로 설정한다.depthBiasClamp
, bias)
-
-
그 외에 state.
depthBiasClamp
<0
인 경우:-
bias를
max(state.
로 설정한다.depthBiasClamp
, bias)
-
-
state.
depthBias
≠0
또는 state.depthBiasSlopeScale
≠0
인 경우:-
프래그먼트의 깊이 값을
fragment depth value + bias
로 설정한다.
-
인자:
-
GPUDepthStencilState
descriptor -
GPUPrimitiveTopology
topology
디바이스 타임라인 단계:
-
다음 조건을 모두 만족할 때만
true
를 반환한다:-
descriptor.
format
값이 깊이 또는 스텐실 포맷이어야 한다. -
descriptor.
depthWriteEnabled
값이true
이거나 descriptor.depthCompare
값이 제공되고"always"
가 아닌 경우:-
descriptor.
format
은 depth 컴포넌트를 가져야 한다.
-
-
descriptor.
stencilFront
또는 descriptor.stencilBack
값이 기본값이 아닌 경우:-
descriptor.
format
은 스텐실 컴포넌트를 가져야 한다.
-
-
descriptor.
format
이 depth 컴포넌트를 가져야 하는 경우:-
descriptor.
depthWriteEnabled
값이 제공되어야 합니다. -
descriptor.
depthCompare
값은 다음의 경우 제공되어야 합니다:-
descriptor.
depthWriteEnabled
값이true
이거나 -
descriptor.
stencilFront
.depthFailOp
값이"keep"
가 아니거나 -
descriptor.
stencilBack
.depthFailOp
값이"keep"
가 아닌 경우.
-
-
-
topology가
"point-list"
,"line-list"
, 또는"line-strip"
인 경우:-
descriptor.
depthBias
값이 0이어야 한다. -
descriptor.
depthBiasSlopeScale
값이 0이어야 한다. -
descriptor.
depthBiasClamp
값이 0이어야 한다.
-
-
dictionary {
GPUStencilFaceState GPUCompareFunction compare = "always";GPUStencilOperation failOp = "keep";GPUStencilOperation depthFailOp = "keep";GPUStencilOperation passOp = "keep"; };
GPUStencilFaceState
는 스텐실 비교 및 연산이 어떻게 수행되는지 설명하는 다음 멤버들을 갖습니다:
compare
, 타입 GPUCompareFunction, 기본값"always"
-
프래그먼트의
[[stencilReference]]
값을depthStencilAttachment
스텐실 값과 비교할 때 사용하는GPUCompareFunction
입니다. failOp
, 타입 GPUStencilOperation, 기본값"keep"
-
compare
비교 테스트가 실패할 때 수행되는GPUStencilOperation
입니다. depthFailOp
, 타입 GPUStencilOperation, 기본값"keep"
-
프래그먼트의 깊이 비교(
depthCompare
)가 실패할 때 수행되는GPUStencilOperation
입니다. passOp
, 타입 GPUStencilOperation, 기본값"keep"
-
compare
비교 테스트가 성공할 때 수행되는GPUStencilOperation
입니다.
enum {
GPUStencilOperation "keep" ,"zero" ,"replace" ,"invert" ,"increment-clamp" ,"decrement-clamp" ,"increment-wrap" ,"decrement-wrap" , };
GPUStencilOperation
은 다음 연산을 정의합니다:
"keep"
-
현재 스텐실 값을 유지합니다.
"zero"
-
스텐실 값을
0
으로 설정합니다. "replace"
-
스텐실 값을
[[stencilReference]]
로 설정합니다. "invert"
-
현재 스텐실 값을 비트 반전합니다.
"increment-clamp"
-
현재 스텐실 값을 증가시키되,
depthStencilAttachment
의 스텐실 aspect의 최댓값을 넘지 않도록 클램프합니다. "decrement-clamp"
-
현재 스텐실 값을 감소시키되,
0
보다 작아지지 않도록 클램프합니다. "increment-wrap"
-
현재 스텐실 값을 증가시키되, 값이
depthStencilAttachment
의 스텐실 aspect 최댓값을 넘으면 0으로 래핑합니다. "decrement-wrap"
-
현재 스텐실 값을 감소시키되, 값이
0
보다 작아지면depthStencilAttachment
의 스텐실 aspect 최댓값으로 래핑합니다.
10.3.7. 버텍스 상태
enum {
GPUIndexFormat "uint16" ,"uint32" , };
인덱스 포맷은 버퍼 내 인덱스 값의 데이터 타입을 결정하며, 스트립 프리미티브 토폴로지("line-strip"
또는
"triangle-strip"
)
사용 시 프리미티브 리스타트 값도 지정합니다.
프리미티브 리스타트 값은
인덱스 값 중 새 프리미티브를 시작해야 하는 값이며,
이전 인덱스 버텍스들과 계속 스트립을 구성하는 대신, 새 프리미티브가 시작됨을 의미합니다.
GPUPrimitiveState
에서
스트립 프리미티브 토폴로지를 지정할 경우 인덱스드 드로우에 사용되는 경우
stripIndexFormat
을 반드시 명시해야 하며,
프리미티브 리스타트
값이 파이프라인 생성 시점에 확정되어야 합니다.
GPUPrimitiveState
가
리스트 프리미티브 토폴로지를 지정할 경우
인덱스드 렌더링 시 setIndexBuffer()
에
전달된 인덱스 포맷을 사용합니다.
인덱스 포맷 | 바이트 크기 | 프리미티브 리스타트 값 |
---|---|---|
"uint16"
| 2 | 0xFFFF |
"uint32"
| 4 | 0xFFFFFFFF |
10.3.7.1. 버텍스 포맷
GPUVertexFormat
은 버텍스 속성이 버텍스 버퍼에서 어떻게 해석되고 셰이더에 노출되는지 나타냅니다. 포맷 이름은 컴포넌트의 순서, 컴포넌트 당 비트 수, 그리고 각 컴포넌트의 버텍스 데이터 타입을 지정합니다.
각 버텍스 데이터 타입은 동일한 기본 타입의 WGSL 스칼라 타입과 비트 수에 관계없이 매핑될 수 있습니다:
버텍스 포맷 접두사 | 버텍스 데이터 타입 | 호환 WGSL 타입 |
---|---|---|
uint
| 부호 없는 정수 | u32
|
sint
| 부호 있는 정수 | i32
|
unorm
| 부호 없는 정규화 | f16 , f32
|
snorm
| 부호 있는 정규화 | |
float
| 부동소수점 |
다중 컴포넌트 포맷은 "x" 뒤의 숫자로 컴포넌트 수를 지정합니다. 버텍스 포맷과 셰이더 타입 간 컴포넌트 수가 불일치할 수 있으며, 부족한 컴포넌트는 기본값으로 채워지고, 초과하는 컴포넌트는 버려질 수 있습니다.
"unorm8x2"
포맷의 버텍스 속성에서
바이트 값 [0x7F, 0xFF]
를 사용할 때
셰이더에서 다음 타입으로 접근할 수 있습니다:
셰이더 타입 | 셰이더 값 |
---|---|
f16
| 0.5h
|
f32
| 0.5f
|
vec2<f16>
| vec2(0.5h, 1.0h)
|
vec2<f32>
| vec2(0.5f, 1.0f)
|
vec3<f16>
| vec2(0.5h, 1.0h, 0.0h)
|
vec3<f32>
| vec2(0.5f, 1.0f, 0.0f)
|
vec4<f16>
| vec2(0.5h, 1.0h, 0.0h, 1.0h)
|
vec4<f32>
| vec2(0.5f, 1.0f, 0.0f, 1.0f)
|
버텍스 포맷이 셰이더에 어떻게 노출되는지 더 자세한 내용은 § 23.2.2 버텍스 처리를 참고하세요.
enum {
GPUVertexFormat "uint8" ,"uint8x2" ,"uint8x4" ,"sint8" ,"sint8x2" ,"sint8x4" ,"unorm8" ,"unorm8x2" ,"unorm8x4" ,"snorm8" ,"snorm8x2" ,"snorm8x4" ,"uint16" ,"uint16x2" ,"uint16x4" ,"sint16" ,"sint16x2" ,"sint16x4" ,"unorm16" ,"unorm16x2" ,"unorm16x4" ,"snorm16" ,"snorm16x2" ,"snorm16x4" ,"float16" ,"float16x2" ,"float16x4" ,"float32" ,"float32x2" ,"float32x3" ,"float32x4" ,"uint32" ,"uint32x2" ,"uint32x3" ,"uint32x4" ,"sint32" ,"sint32x2" ,"sint32x3" ,"sint32x4" ,"unorm10-10-10-2" ,"unorm8x4-bgra" , };
버텍스 포맷 | 데이터 타입 | 컴포넌트 수 | 바이트 크기 | 예시 WGSL 타입 |
---|---|---|---|---|
"uint8"
| 부호 없는 정수 | 1 | 1 | u32
|
"uint8x2"
| 부호 없는 정수 | 2 | 2 | vec2<u32>
|
"uint8x4"
| 부호 없는 정수 | 4 | 4 | vec4<u32>
|
"sint8"
| 부호 있는 정수 | 1 | 1 | i32
|
"sint8x2"
| 부호 있는 정수 | 2 | 2 | vec2<i32>
|
"sint8x4"
| 부호 있는 정수 | 4 | 4 | vec4<i32>
|
"unorm8"
| 부호 없는 정규화 | 1 | 1 | f32
|
"unorm8x2"
| 부호 없는 정규화 | 2 | 2 | vec2<f32>
|
"unorm8x4"
| 부호 없는 정규화 | 4 | 4 | vec4<f32>
|
"snorm8"
| 부호 있는 정규화 | 1 | 1 | f32
|
"snorm8x2"
| 부호 있는 정규화 | 2 | 2 | vec2<f32>
|
"snorm8x4"
| 부호 있는 정규화 | 4 | 4 | vec4<f32>
|
"uint16"
| 부호 없는 정수 | 1 | 2 | u32
|
"uint16x2"
| 부호 없는 정수 | 2 | 4 | vec2<u32>
|
"uint16x4"
| 부호 없는 정수 | 4 | 8 | vec4<u32>
|
"sint16"
| 부호 있는 정수 | 1 | 2 | i32
|
"sint16x2"
| 부호 있는 정수 | 2 | 4 | vec2<i32>
|
"sint16x4"
| 부호 있는 정수 | 4 | 8 | vec4<i32>
|
"unorm16"
| 부호 없는 정규화 | 1 | 2 | f32
|
"unorm16x2"
| 부호 없는 정규화 | 2 | 4 | vec2<f32>
|
"unorm16x4"
| 부호 없는 정규화 | 4 | 8 | vec4<f32>
|
"snorm16"
| 부호 있는 정규화 | 1 | 2 | f32
|
"snorm16x2"
| 부호 있는 정규화 | 2 | 4 | vec2<f32>
|
"snorm16x4"
| 부호 있는 정규화 | 4 | 8 | vec4<f32>
|
"float16"
| 부동소수점 | 1 | 2 | f32
|
"float16x2"
| 부동소수점 | 2 | 4 | vec2<f16>
|
"float16x4"
| 부동소수점 | 4 | 8 | vec4<f16>
|
"float32"
| 부동소수점 | 1 | 4 | f32
|
"float32x2"
| 부동소수점 | 2 | 8 | vec2<f32>
|
"float32x3"
| 부동소수점 | 3 | 12 | vec3<f32>
|
"float32x4"
| 부동소수점 | 4 | 16 | vec4<f32>
|
"uint32"
| 부호 없는 정수 | 1 | 4 | u32
|
"uint32x2"
| 부호 없는 정수 | 2 | 8 | vec2<u32>
|
"uint32x3"
| 부호 없는 정수 | 3 | 12 | vec3<u32>
|
"uint32x4"
| 부호 없는 정수 | 4 | 16 | vec4<u32>
|
"sint32"
| 부호 있는 정수 | 1 | 4 | i32
|
"sint32x2"
| 부호 있는 정수 | 2 | 8 | vec2<i32>
|
"sint32x3"
| 부호 있는 정수 | 3 | 12 | vec3<i32>
|
"sint32x4"
| 부호 있는 정수 | 4 | 16 | vec4<i32>
|
"unorm10-10-10-2"
| 부호 없는 정규화 | 4 | 4 | vec4<f32>
|
"unorm8x4-bgra"
| 부호 없는 정규화 | 4 | 4 | vec4<f32>
|
enum {
GPUVertexStepMode "vertex" ,"instance" , };
단계 모드는 현재 버텍스 또는 인스턴스 인덱스를 기준으로 버텍스 버퍼 데이터의 주소가 어떻게 계산되는지 설정합니다:
"vertex"
-
각 버텍스마다
arrayStride
만큼 주소가 증가하며, 인스턴스마다 초기화됩니다. "instance"
-
각 인스턴스마다
arrayStride
만큼 주소가 증가합니다.
dictionary :
GPUVertexState GPUProgrammableStage {sequence <GPUVertexBufferLayout ?>buffers = []; };
buffers
, 타입sequence<GPUVertexBufferLayout?>
, 기본값[]
-
이 파이프라인에서 사용하는 각 버텍스 버퍼의 버텍스 속성 데이터 레이아웃을 정의하는
GPUVertexBufferLayout
리스트입니다.
버텍스 버퍼는 개념적으로 구조체
배열로서의 버퍼 메모리 뷰입니다.
arrayStride
는 해당 배열의 요소 간의 바이트 단위 간격입니다.
버텍스 버퍼의 각 요소는 구조체와 유사하며,
attributes
에
정의된 메모리 레이아웃을 따릅니다.
멤버는 구조체 내 속성에 해당합니다.
각 GPUVertexAttribute
는 자신의
format
과 구조체 내에서의
offset
(바이트 단위)를 정의합니다.
각 속성은 버텍스 셰이더에서 개별 입력으로 나타나며, 각 입력은 숫자 location에 바인딩됩니다.
이 위치는 shaderLocation
로
지정합니다.
GPUVertexState
내 모든 location은 고유해야 합니다.
dictionary {
GPUVertexBufferLayout required GPUSize64 arrayStride ;GPUVertexStepMode stepMode = "vertex";required sequence <GPUVertexAttribute >attributes ; };
arrayStride
, 타입 GPUSize64-
이 배열의 요소 간 바이트 간격입니다.
stepMode
, 타입 GPUVertexStepMode, 기본값"vertex"
-
배열의 각 요소가 버텍스 데이터인지 인스턴스 데이터인지 여부입니다.
attributes
, 타입 sequence<GPUVertexAttribute>-
각 요소 내 버텍스 속성의 레이아웃을 정의하는 배열입니다.
dictionary {
GPUVertexAttribute required GPUVertexFormat format ;required GPUSize64 offset ;required GPUIndex32 shaderLocation ; };
format
, 타입 GPUVertexFormat-
속성의
GPUVertexFormat
입니다. offset
, 타입 GPUSize64-
속성 데이터가 요소 시작점에서 몇 바이트 떨어져 있는지 나타내는 오프셋입니다.
shaderLocation
, 타입 GPUIndex32-
이 속성과 연관된 숫자 위치로, "@location" 속성 으로 셰이더에서 선언합니다.
vertex
.module
에 해당합니다.
인자:
-
GPUDevice
device -
GPUVertexBufferLayout
descriptor
디바이스 타임라인 단계:
-
다음 조건을 모두 만족할 때만
true
를 반환한다:-
descriptor.
arrayStride
값이 device.[[device]]
.[[limits]]
.maxVertexBufferArrayStride
이하이어야 함. -
descriptor.
arrayStride
값이 4의 배수여야 함. -
descriptor.
attributes
리스트의 각 속성 attrib에 대하여:-
descriptor.
arrayStride
값이 0인 경우:-
attrib.
offset
+ byteSize(attrib.format
) 값이 device.[[device]]
.[[limits]]
.maxVertexBufferArrayStride
이하이어야 함.
그 외의 경우:
-
attrib.
offset
+ byteSize(attrib.format
) 값이 descriptor.arrayStride
이하이어야 함.
-
-
attrib.
shaderLocation
값이 device.[[device]]
.[[limits]]
.maxVertexAttributes
미만이어야 함.
-
-
인자:
-
GPUDevice
device -
GPUVertexState
descriptor -
GPUPipelineLayout
layout
디바이스 타임라인 단계:
-
entryPoint을 get the entry point(
VERTEX
, descriptor)로 한다. -
Assert entryPoint이
null
이 아니어야 함. -
다음 단계에서 모든 요구사항이 충족되어야 합니다.
-
GPUProgrammableStage 유효성 검사(
VERTEX
, descriptor, layout, device) 성공해야 함. -
descriptor.
buffers
.size 값이 device.[[device]]
.[[limits]]
.maxVertexBuffers
이하이어야 함. -
리스트 descriptor.
buffers
의 각 vertexBuffer 레이아웃 디스크립터가 GPUVertexBufferLayout 유효성 검사(device, vertexBuffer)를 통과해야 함. -
모든 vertexBuffer.
attributes
.size의 합이 descriptor.buffers
의 모든 vertexBuffer에 대해, device.[[device]]
.[[limits]]
.maxVertexAttributes
이하이어야 함. -
entryPoint에서 정적으로 사용되는(타입 T의 location location에서 선언된) 모든 버텍스 속성 선언에 대해, 반드시 descriptor.
buffers
[i]?.attributes
[j].shaderLocation
== location인 쌍이 정확히 하나 존재해야 함.이때 attrib는 해당
GPUVertexAttribute
입니다. -
T는 attrib.
format
의 버텍스 데이터 타입과 호환되어야 함:- "unorm", "snorm", 또는 "float"
-
T는
f32
또는vecN<f32>
여야 함. - "uint"
-
T는
u32
또는vecN<u32>
여야 함. - "sint"
-
T는
i32
또는vecN<i32>
여야 함.
-
11. 복사
11.1. 버퍼 복사
버퍼 복사 연산은 원시 바이트 단위로 동작합니다.
WebGPU는 "버퍼링된" GPUCommandEncoder
명령을 제공합니다:
그리고 "즉시" GPUQueue
연산:
-
writeBuffer()
,ArrayBuffer
에서GPUBuffer
로 쓰기
11.2. 텍셀 복사
텍셀 복사 연산은 바이트가 아닌 텍스처/"이미지" 데이터에 대해 동작합니다.
WebGPU는 "버퍼링된" GPUCommandEncoder
명령을 제공합니다:
그리고 "즉시" GPUQueue
연산:
-
writeTexture()
,ArrayBuffer
에서GPUTexture
로 쓰기 -
copyExternalImageToTexture()
, Web 플랫폼 이미지 소스에서 텍스처로 복사
텍셀 복사 중에는 동등한 텍셀 표현으로 복사됩니다. 텍셀 복사는 소스의 유효한 정상 숫자 값이 목적지에 동일한 숫자 값으로 보장될 뿐, 아래 값들의 비트 표현을 반드시 보존하지는 않습니다:
-
snorm 값은 -1.0을 -127 또는 -128로 표현할 수 있습니다.
-
0 값의 부호가 보존되지 않을 수 있습니다.
-
서브노멀 부동소수점 값은 -0.0 또는 +0.0으로 대체될 수 있습니다.
-
NaN 또는 Infinity는 유효하지 않은 값이며 불확정 값으로 대체될 수 있습니다.
참고: 복사는 WGSL 셰이더로 수행될 수 있으므로, WGSL 부동소수점 동작이 관찰될 수 있습니다.
다음 정의들은 이 메서드들에서 사용됩니다:
11.2.1. GPUTexelCopyBufferLayout
"GPUTexelCopyBufferLayout
"
은 바이트 버퍼(GPUBuffer
또는 AllowSharedBufferSource
)에서
"텍셀"의 "레이아웃"을 "텍셀 복사" 연산에서 설명합니다.
dictionary GPUTexelCopyBufferLayout {GPUSize64 offset = 0;GPUSize32 bytesPerRow ;GPUSize32 rowsPerImage ; };
텍셀 이미지는 하나 이상의 텍셀 블록 행으로 구성됩니다(여기서는 텍셀 블록 행이라 함).
텍셀 이미지의 각 텍셀 블록 행에는 같은 수의 텍셀 블록이 있어야 하며,
하나의 텍셀 이미지 내 모든 텍셀 블록은 같은 GPUTextureFormat
입니다.
GPUTexelCopyBufferLayout
은 선형 메모리 내 텍셀 이미지의 레이아웃입니다.
텍스처와 GPUBuffer
간에
데이터를 복사하거나,
GPUQueue
에서
텍스처로 쓰기를 예약할 때 사용됩니다.
바이트 배열과 텍스처 간 복사 연산은 항상 전체 텍셀 블록 단위로 동작합니다. 텍셀 블록의 일부만 업데이트하는 것은 불가능합니다.
텍셀 블록은 텍셀 복사의 선형 메모리 레이아웃에서 각 텍셀 블록 행 내에 꽉 채워져 있으며, 각 텍셀 블록은 바로 앞 텍셀 블록 다음에 바로 이어집니다. 패딩은 없습니다. 복사를 포함하여 깊이·스텐실 포맷 텍스처의 특정 aspect에 대해: 스텐실 값은 바이트 배열에 꽉 채워지고, 깊이 값은 해당 타입("depth16unorm" 또는 "depth32float") 배열에 꽉 채워집니다.
offset
, 타입 GPUSize64, 기본값0
-
텍셀 데이터 소스(
GPUTexelCopyBufferInfo.buffer
등)의 시작점부터 해당 소스 내 텍셀 데이터의 시작까지 바이트 단위 오프셋입니다. bytesPerRow
, 타입 GPUSize32-
각 텍셀 블록 행의 시작점과 그 다음 텍셀 블록 행의 시작점 사이의 바이트 단위 간격입니다.
복사 높이/깊이가 블록 1개를 초과하여 여러 텍셀 블록 행이 있는 경우 필수입니다.
rowsPerImage
, 타입 GPUSize32-
해당 텍스처의 단일 텍셀 이미지당 텍셀 블록 행의 개수.
rowsPerImage
×bytesPerRow
는 데이터의 각 텍셀 이미지 시작점 간 바이트 단위 간격입니다.복사 깊이가 블록 1개를 초과하여 여러 텍셀 이미지가 있는 경우 필수입니다.
11.2.2. GPUTexelCopyBufferInfo
"GPUTexelCopyBufferInfo
"
는 "버퍼" 소스 또는 목적지에 대한 "정보"(GPUBuffer
와
GPUTexelCopyBufferLayout
)
를 "텍셀 복사" 연산에서
설명합니다.
copySize
와 함께 GPUBuffer
내 텍셀
영역의 footprint를 설명합니다.
dictionary GPUTexelCopyBufferInfo :GPUTexelCopyBufferLayout {required GPUBuffer buffer ; };
buffer
, 타입 GPUBuffer-
복사되는 텍셀 데이터를 포함하거나 복사된 텍셀 데이터를 저장할 버퍼(사용되는 메서드에 따라 다름)입니다.
인자:
-
GPUTexelCopyBufferInfo
imageCopyBuffer
반환값: boolean
디바이스 타임라인 단계:
-
다음 조건을 모두 만족할 때만
true
를 반환한다:-
imageCopyBuffer.
bytesPerRow
값이 256의 배수여야 함.
11.2.3. GPUTexelCopyTextureInfo
"GPUTexelCopyTextureInfo
"
는 "텍스처" 복사 연산의 "정보"(GPUTexture
등)를 설명합니다.
copySize
와 함께, 텍스처의 서브영역(동일한 mip-map 레벨 내에서 하나 이상의 연속 텍스처 서브리소스를 포함)을 설명합니다.
dictionary GPUTexelCopyTextureInfo {required GPUTexture texture ;GPUIntegerCoordinate mipLevel = 0;GPUOrigin3D origin = {};GPUTextureAspect aspect = "all"; };
texture
, 타입 GPUTexture-
복사할 텍스처입니다.
mipLevel
, 타입 GPUIntegerCoordinate, 기본값0
-
복사할
texture
의 mip-map 레벨입니다. origin
, 타입 GPUOrigin3D, 기본값{}
-
복사할 서브영역의 원점(최소 좌표)입니다.
copySize
와 함께, 전체 복사 서브영역을 정의합니다. aspect
, 타입 GPUTextureAspect, 기본값"all"
-
복사할
texture
의 aspect를 지정합니다.
GPUTexelCopyTextureInfo
copyTexture의 depth slice 또는 array layer index에 대해 다음 절차로 결정됩니다:
GPUTexelCopyBufferLayout
bufferLayout에서 텍셀 블록
x, y, depth slice 또는 array layer z에 해당하는 GPUTexture
texture 데이터에 대해 다음 절차로 결정됩니다:
-
blockBytes를 texture.
format
의 텍셀 블록 복사 footprint로 한다. -
imageOffset을 (z × bufferLayout.
rowsPerImage
× bufferLayout.bytesPerRow
) + bufferLayout.offset
로 한다. -
rowOffset을 (y × bufferLayout.
bytesPerRow
) + imageOffset로 한다. -
blockOffset을 (x × blockBytes) + rowOffset로 한다.
-
blockOffset을 반환한다.
인자:
-
GPUTexelCopyTextureInfo
texelCopyTextureInfo -
GPUExtent3D
copySize
반환값: boolean
디바이스 타임라인 단계:
-
blockWidth를 texelCopyTextureInfo.
texture
.format
의 텍셀 블록 너비로 한다. -
blockHeight를 texelCopyTextureInfo.
texture
.format
의 텍셀 블록 높이로 한다. -
다음 조건을 모두 만족할 때만
true
를 반환한다:-
텍스처 복사 범위 유효성 검사(texelCopyTextureInfo, copySize)가
true
를 반환함. -
texelCopyTextureInfo.
texture
는 유효한GPUTexture
여야 함. -
texelCopyTextureInfo.
mipLevel
값이 texelCopyTextureInfo.texture
.mipLevelCount
미만이어야 함. -
GPUTexelCopyTextureInfo 실제 서브리소스 크기가 아래 조건 중 하나라도 참이면 copySize와 같아야 함:
-
texelCopyTextureInfo.
texture
.sampleCount
> 1임.
-
인자:
-
GPUTexelCopyTextureInfo
texelCopyTextureInfo -
GPUTexelCopyBufferLayout
bufferLayout -
GPUSize64Out
dataLength -
GPUExtent3D
copySize -
GPUTextureUsage
textureUsage -
boolean
aligned
반환값: boolean
디바이스 타임라인 단계:
-
texture을 texelCopyTextureInfo.
texture
로 한다 -
aspectSpecificFormat = texture.
format
로 한다. -
offsetAlignment = texture.
format
의 텍셀 블록 복사 footprint로 한다. -
다음 조건을 모두 만족할 때만
true
를 반환한다:-
GPUTexelCopyTextureInfo 유효성 검사(texelCopyTextureInfo, copySize)가
true
를 반환함. -
texture.
sampleCount
값이 1임. -
texture.
usage
값에 textureUsage가 포함되어 있음. -
texture.
format
값이 깊이·스텐실 포맷인 경우:-
texelCopyTextureInfo.
aspect
값이 texture.format
의 단일 aspect를 참조해야 함. -
textureUsage가 다음 중 하나인 경우:
COPY_SRC
-
그 aspect는 텍셀 복사 소스여야 하며, § 26.1.2 깊이-스텐실 포맷에 따름.
COPY_DST
-
그 aspect는 텍셀 복사 목적지여야 하며, § 26.1.2 깊이-스텐실 포맷에 따름.
-
aspectSpecificFormat을 측면별 포맷으로 설정하며, § 26.1.2 깊이-스텐실 포맷에 따름.
-
offsetAlignment을 4로 설정함.
-
-
aligned이
true
인 경우:-
bufferLayout.
offset
값이 offsetAlignment의 배수여야 함.
-
-
직렬 텍스처 데이터 유효성 검사(bufferLayout, dataLength, aspectSpecificFormat, copySize)가 성공해야 함.
-
11.2.4.
GPUCopyExternalImageDestInfo
WebGPU 텍스처는 색상에 대한 의미론적 메타데이터 없이 원시 숫자 데이터를 저장합니다.
그러나 copyExternalImageToTexture()
는 색상을 설명하는 소스에서 복사합니다.
"GPUCopyExternalImageDestInfo
"
는 "copyExternalImageToTexture()" 연산의 "목적지"에 대한 "정보"를
설명합니다.
이것은 GPUTexelCopyTextureInfo
이며,
여기에 색상 공간/인코딩 및 알파 프리멀티플리케이션 메타데이터가 추가로 태그되어 있으므로,
복사 시 의미론적 색상 데이터가 보존될 수 있습니다.
이 메타데이터는 복사 연산의 의미에만 영향을 주며,
목적지 텍스처 객체의 상태나 의미에는 영향을 주지 않습니다.
dictionary GPUCopyExternalImageDestInfo :GPUTexelCopyTextureInfo {PredefinedColorSpace colorSpace = "srgb";boolean premultipliedAlpha =false ; };
colorSpace
, 타입 PredefinedColorSpace, 기본값"srgb"
-
목적지 텍스처에 데이터를 인코딩할 때 사용하는 색상 공간 및 인코딩을 설명합니다.
이 변환 결과는 대상 텍스처 포맷이 표현 가능하다면 [0, 1] 범위를 벗어난 값이 기록될 수 있습니다. 그렇지 않으면 결과가 대상 텍스처 포맷의 범위로 클램프됩니다.
참고:
colorSpace
가 소스 이미지와 일치하면, 변환이 필요하지 않을 수 있습니다. § 3.10.2 색상 공간 변환 생략을 참고하세요. premultipliedAlpha
, 타입 boolean, 기본값false
-
텍스처에 기록되는 데이터의 RGB 채널을 알파 채널로 프리멀티플리케이션할지 여부를 설명합니다.
이 옵션이
true
이고source
도 프리멀티플라이된 경우, 소스의 RGB 값은 해당 알파 값을 초과하더라도 그대로 보존되어야 합니다.참고:
premultipliedAlpha
가 소스 이미지와 일치하면, 변환이 필요하지 않을 수 있습니다. § 3.10.2 색상 공간 변환 생략을 참고하세요.
11.2.5.
GPUCopyExternalImageSourceInfo
"GPUCopyExternalImageSourceInfo
"
는 "copyExternalImageToTexture()" 연산의 "소스"에 대한 "정보"를
설명합니다.
typedef (ImageBitmap or ImageData or HTMLImageElement or HTMLVideoElement or VideoFrame or HTMLCanvasElement or OffscreenCanvas );
GPUCopyExternalImageSource dictionary GPUCopyExternalImageSourceInfo {required GPUCopyExternalImageSource source ;GPUOrigin2D origin = {};boolean flipY =false ; };
GPUCopyExternalImageSourceInfo
는 다음 멤버들을 갖습니다:
source
, 타입 GPUCopyExternalImageSource-
텍셀 복사의 소스입니다. 복사 소스 데이터는
copyExternalImageToTexture()
호출 시점에 캡처됩니다. 소스 크기는 외부 소스 크기 표에 따라 결정됩니다. origin
, 타입 GPUOrigin2D, 기본값{}
-
복사할 서브영역의 원점(최소, 좌상단)입니다.
copySize
와 함께 전체 복사 서브영역을 정의합니다. flipY
, 타입 boolean, 기본값false
-
소스 이미지가 수직으로 뒤집혀 있는지 여부를 설명합니다.
이 옵션이
true
면, 복사가 수직으로 반전되어 진행됩니다: 소스 영역의 맨 아래 행이 목적지 영역의 첫 행에 복사되고, 그 다음이 이어집니다.origin
옵션은 여전히 소스 이미지의 좌상단 기준이며, 아래로 증가합니다.
외부 소스를 텍스처 생성 또는 복사에 사용할 때, 외부 소스 크기 는 소스 타입에 따라 다음 표와 같이 정의됩니다:
11.2.6. 서브루틴
인자:
-
GPUTexelCopyTextureInfo
texelCopyTextureInfo
반환값: GPUExtent3D
texelCopyTextureInfo의 GPUTexelCopyTextureInfo 실제 서브리소스 크기는 다음과 같이 계산됩니다:
그 width, height, depthOrArrayLayers는 각각
texelCopyTextureInfo.texture
subresource의 물리적 mip레벨별 텍스처 크기에서
mipmap level
texelCopyTextureInfo.mipLevel
의
width, height, depth 입니다.
인자:
GPUTexelCopyBufferLayout
layout-
직렬 텍스처 데이터의 레이아웃입니다.
GPUSize64
byteSize-
직렬 데이터의 총 바이트 크기입니다.
GPUTextureFormat
format-
텍스처의 포맷입니다.
GPUExtent3D
copyExtent-
복사할 텍스처 범위(크기)입니다.
디바이스 타임라인 단계:
-
Let:
-
다음 입력 검증 요구사항을 만족하지 않으면 실패:
-
heightInBlocks > 1인 경우, layout.
bytesPerRow
값이 지정되어야 함. -
copyExtent.depthOrArrayLayers > 1인 경우, layout.
bytesPerRow
및 layout.rowsPerImage
값이 지정되어야 함. -
지정된 경우, layout.
bytesPerRow
값이 bytesInLastRow 이상이어야 함. -
지정된 경우, layout.
rowsPerImage
값이 heightInBlocks 이상이어야 함.
-
-
Let:
-
bytesPerRow = layout.
bytesPerRow
?? 0. -
rowsPerImage = layout.
rowsPerImage
?? 0.
참고: 이 기본값들은 항상 0과 곱해지기 때문에 영향이 없습니다.
-
-
requiredBytesInCopy를 0으로 한다.
-
copyExtent.depthOrArrayLayers > 0인 경우:
-
requiredBytesInCopy += bytesPerRow × rowsPerImage × (copyExtent.depthOrArrayLayers − 1)
-
heightInBlocks > 0인 경우:
-
requiredBytesInCopy += bytesPerRow × (heightInBlocks − 1) + bytesInLastRow
-
-
-
다음 조건을 만족하지 않으면 실패:
-
레이아웃이 직렬 데이터 내에 들어가야 함: layout.
offset
+ requiredBytesInCopy ≤ byteSize.
-
인자:
GPUTexelCopyTextureInfo
texelCopyTextureInfo-
복사 대상 텍스처 서브리소스와 복사 원점입니다.
GPUExtent3D
copySize-
텍스처의 크기입니다.
디바이스 타임라인 단계:
-
blockHeight = texelCopyTextureInfo.
texture
.format
의 텍셀 블록 높이. -
subresourceSize = texelCopyTextureInfo의 GPUTexelCopyTextureInfo 실제 서브리소스 크기입니다.
-
다음 조건들을 모두 만족하는지 반환:
-
(texelCopyTextureInfo.
origin
.x + copySize.width) ≤ subresourceSize.width -
(texelCopyTextureInfo.
origin
.y + copySize.height) ≤ subresourceSize.height -
(texelCopyTextureInfo.
origin
.z + copySize.depthOrArrayLayers) ≤ subresourceSize.depthOrArrayLayers -
copySize.width가 blockWidth의 배수여야 함.
-
copySize.height가 blockHeight의 배수여야 함.
참고: 텍스처 복사 범위는 물리적(올림 처리된) 크기에 대해 검증되므로, 압축 포맷의 경우 텍스처 내부에 완전히 포함되지 않는 텍스처 블록을 접근할 수 있습니다.
-
GPUTextureFormat
format1, format2가 복사 호환(copy-compatible)이려면:
-
format1이 format2와 같거나,
-
format1과 format2가
srgb
포맷 여부(즉-srgb
접미사 포함 여부)만 다를 때.
texture
에 대해, 각 서브리소스 s가 다음을 만족하는 서브리소스의 부분집합입니다:
-
s의 mipmap level이 texelCopyTextureInfo.
mipLevel
과 같음. -
s의 aspect가 texelCopyTextureInfo.
aspect
의 set of aspects에 포함됨. -
-
s의 array layer가 texelCopyTextureInfo.
origin
.z 이상이고, texelCopyTextureInfo.origin
.z + copySize.depthOrArrayLayers 미만임.
-
12. 커맨드 버퍼
커맨드 버퍼는 GPU 명령(큐 타임라인
단계 블록)의 사전 기록된 목록으로, GPUQueue
에 제출하여
실행할 수 있습니다.
각 GPU 명령
은 상태 설정, 드로우, 리소스 복사 등 큐
타임라인에서 수행할 작업을 나타냅니다.
GPUCommandBuffer
는 한 번만 제출할 수 있으며, 제출 이후에는 무효화됩니다.
여러 번 제출해 렌더링 명령을 재사용하려면 GPURenderBundle
을
사용하세요.
12.1. GPUCommandBuffer
[Exposed =(Window ,Worker ),SecureContext ]interface GPUCommandBuffer { };GPUCommandBuffer includes GPUObjectBase ;
GPUCommandBuffer
는 다음 디바이스
타임라인 속성을 갖습니다:
[[command_list]]
, 타입은 list<GPU 명령>, 읽기 전용[[renderState]]
, 타입은 RenderState, 초기값은null
-
실행 중인 렌더 패스 명령에 사용되는 현재 상태입니다.
12.1.1. 커맨드 버퍼 생성
dictionary :
GPUCommandBufferDescriptor GPUObjectDescriptorBase { };
13. 커맨드 인코딩
13.1. GPUCommandsMixin
GPUCommandsMixin
은 모든 커맨드 인코딩 인터페이스에 공통적인 상태를 정의합니다.
메서드는 없습니다.
interface mixin GPUCommandsMixin { };
GPUCommandsMixin
은 다음 디바이스
타임라인 속성을 갖습니다:
[[state]]
, 타입 인코더 상태, 초기값 "open"-
인코더의 현재 상태입니다.
[[commands]]
, 타입 list<GPU 명령>, 초기값[]
-
이 커맨드를 포함하는
GPUCommandBuffer
가 제출될 때 list로 GPU 명령이 큐 타임라인에서 실행됩니다.
인코더 상태는 다음 중 하나일 수 있습니다:
- "open"
-
인코더가 새로운 커맨드 인코딩에 사용 가능합니다.
- "locked"
-
인코더가 자식 인코더에 의해 잠겼기 때문에 사용할 수 없습니다. 즉,
GPUCommandEncoder
이고,GPURenderPassEncoder
또는GPUComputePassEncoder
가 활성화된 상태입니다. 패스가 종료되면 인코더는 다시 "open" 상태가 됩니다.이 상태에서 커맨드를 발행하면 인코더가 무효화됩니다.
- "ended"
-
인코더가 종료되어 새로운 커맨드를 인코딩할 수 없습니다.
이 상태에서 커맨드를 발행하면 유효성 오류가 생성됩니다.
GPUCommandsMixin
encoder
에서 GPU 명령 command의 단계를
발행하려면, 다음 디바이스 타임라인 단계를
수행합니다:
-
Append command를 encoder.
[[commands]]
에 추가합니다. -
command가
GPUCommandBuffer
에서 실행될 때:-
command의 단계를 실행합니다.
-
13.2. GPUCommandEncoder
[Exposed =(Window ,Worker ),SecureContext ]interface GPUCommandEncoder {GPURenderPassEncoder beginRenderPass (GPURenderPassDescriptor descriptor );GPUComputePassEncoder beginComputePass (optional GPUComputePassDescriptor descriptor = {});undefined copyBufferToBuffer (GPUBuffer ,
source GPUBuffer ,
destination optional GPUSize64 );
size undefined copyBufferToBuffer (GPUBuffer source ,GPUSize64 sourceOffset ,GPUBuffer destination ,GPUSize64 destinationOffset ,optional GPUSize64 size );undefined copyBufferToTexture (GPUTexelCopyBufferInfo source ,GPUTexelCopyTextureInfo destination ,GPUExtent3D copySize );undefined copyTextureToBuffer (GPUTexelCopyTextureInfo source ,GPUTexelCopyBufferInfo destination ,GPUExtent3D copySize );undefined copyTextureToTexture (GPUTexelCopyTextureInfo source ,GPUTexelCopyTextureInfo destination ,GPUExtent3D copySize );undefined clearBuffer (GPUBuffer buffer ,optional GPUSize64 offset = 0,optional GPUSize64 size );undefined resolveQuerySet (GPUQuerySet querySet ,GPUSize32 firstQuery ,GPUSize32 queryCount ,GPUBuffer destination ,GPUSize64 destinationOffset );GPUCommandBuffer finish (optional GPUCommandBufferDescriptor descriptor = {}); };GPUCommandEncoder includes GPUObjectBase ;GPUCommandEncoder includes GPUCommandsMixin ;GPUCommandEncoder includes GPUDebugCommandsMixin ;
13.2.1. 커맨드 인코더 생성
dictionary :
GPUCommandEncoderDescriptor GPUObjectDescriptorBase { };
createCommandEncoder(descriptor)
-
GPUCommandEncoder
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createCommandEncoder(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUCommandEncoderDescriptor
✘ ✔ 생성할 GPUCommandEncoder
의 설명.반환값:
GPUCommandEncoder
컨텐트 타임라인 단계:
-
e를 ! create a new WebGPU object(this,
GPUCommandEncoder
, descriptor)로 한다. -
this의 디바이스 타임라인에서 초기화 단계를 실행한다.
-
e를 반환한다.
-
GPUCommandEncoder
를
생성하고,
버퍼를 삭제(clear)하는 커맨드를 인코딩한 뒤,
인코더를 마쳐 GPUCommandBuffer
를
얻고,
GPUQueue
에
제출합니다.
const commandEncoder= gpuDevice. createCommandEncoder(); commandEncoder. clearBuffer( buffer); const commandBuffer= commandEncoder. finish(); gpuDevice. queue. submit([ commandBuffer]);
13.3. 패스 인코딩
beginRenderPass(descriptor)
-
descriptor로 설명된 렌더 패스 인코딩을 시작합니다.
호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.beginRenderPass(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPURenderPassDescriptor
✘ ✘ 생성할 GPURenderPassEncoder
의 설명.반환값:
GPURenderPassEncoder
컨텐트 타임라인 단계:
-
descriptor.
colorAttachments
의 각null
이 아닌 colorAttachment에 대해:-
colorAttachment.
clearValue
가 제공된 경우:-
? GPUColor 모양 유효성 검증(colorAttachment.
clearValue
).
-
-
-
pass를 새
GPURenderPassEncoder
객체로 한다. -
this의 디바이스 타임라인에서 초기화 단계를 실행한다.
-
pass를 반환한다.
디바이스 타임라인 초기화 단계:-
attachmentRegions를 list([texture subresource,
depthSlice
?] 쌍)로 초기화한다. 각 쌍은 렌더링되는 텍스처 영역을 설명하며, "3d" 텍스처는 단일 depth slice를 포함한다. -
descriptor.
colorAttachments
의 각null
이 아닌 colorAttachment에 대해:-
[colorAttachment.
view
, colorAttachment.depthSlice
??null
]을 attachmentRegions에 추가. -
colorAttachment.
resolveTarget
이null
이 아니면:-
[colorAttachment.
resolveTarget
,undefined
]을 attachmentRegions에 추가.
-
-
-
아래 조건 중 하나라도 충족하지 않으면, pass를 무효화하고 반환.
-
descriptor는 Valid Usage 규칙을 this.
[[device]]
에서 충족해야 함. -
attachmentRegions에 있는 텍스처 영역 집합은 쌍별로 겹치지 않아야 함. 즉, 두 텍스처 영역이 겹치면 안 됨.
-
-
attachment 사용으로 attachmentRegions의 각 texture subresource를 pass.
[[usage scope]]
에 추가. -
depthStencilAttachment를 descriptor.
depthStencilAttachment
로 한다. -
depthStencilAttachment가
null
이 아니면:-
depthStencilView를 depthStencilAttachment.
view
로 한다. -
depthReadOnly가 true면 attachment-read 사용으로, 아니면 attachment 사용으로 depthStencilView의 depth subresource를 pass.
[[usage scope]]
에 추가. -
stencilReadOnly가 true면 attachment-read 사용으로, 아니면 attachment 사용으로 depthStencilView의 stencil subresource를 pass.
[[usage scope]]
에 추가. -
pass.
[[depthReadOnly]]
값을 depthStencilAttachment.depthReadOnly
로 설정. -
pass.
[[stencilReadOnly]]
값을 depthStencilAttachment.stencilReadOnly
로 설정.
-
-
pass.
[[layout]]
값을 derive render targets layout from pass(descriptor)로 설정. -
descriptor.
timestampWrites
가 제공된 경우:-
timestampWrites를 descriptor.
timestampWrites
로 한다. -
timestampWrites.
beginningOfPassWriteIndex
가 제공된 경우, append GPU 명령을 this.[[commands]]
에 추가하며, 아래 단계를 실행:-
패스 커맨드 실행 전, 현재 큐 타임스탬프를 timestampWrites.
beginningOfPassWriteIndex
인덱스에 timestampWrites.querySet
에 기록.
-
-
timestampWrites.
endOfPassWriteIndex
가 제공된 경우, pass.[[endTimestampWrite]]
에 아래 GPU 명령 단계를 설정:-
패스 커맨드 실행 후, 현재 큐 타임스탬프를 timestampWrites.
endOfPassWriteIndex
인덱스에 timestampWrites.querySet
에 기록.
-
-
-
pass.
[[drawCount]]
값을 0으로 설정. -
pass.
[[maxDrawCount]]
값을 descriptor.maxDrawCount
로 설정. -
pass.
[[maxDrawCount]]
값을 descriptor.maxDrawCount
로 설정. -
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
현재 실행 중인
GPUCommandBuffer
의[[renderState]]
를 새 RenderState로 한다. -
[[renderState]]
.[[colorAttachments]]
값을 descriptor.colorAttachments
로 설정. -
[[renderState]]
.[[depthStencilAttachment]]
값을 descriptor.depthStencilAttachment
로 설정. -
descriptor.
colorAttachments
의 각null
이 아닌 colorAttachment에 대해:-
colorView를 colorAttachment.
view
로 한다. -
colorView.
[[descriptor]]
.dimension
값에 따라:"3d"
-
colorSubregion을 colorAttachment.
depthSlice
로 한다. - 그 외
-
colorSubregion을 colorView로 한다.
-
colorAttachment.
loadOp
값에 따라:
-
-
depthStencilAttachment가
null
이 아니면:-
depthStencilAttachment.
depthLoadOp
값에 따라:- 제공되지 않은 경우
-
Assert depthStencilAttachment.
depthReadOnly
가true
임을 보장하고, depthStencilView의 depth subresource를 프레임버퍼 메모리에 로드함. "load"
-
depthStencilView의 depth subresource를 프레임버퍼 메모리에 로드함.
"clear"
-
depthStencilView의 depth subresource에 연결된 프레임버퍼 메모리의 모든 텍셀을 depthStencilAttachment.
depthClearValue
로 설정.
-
depthStencilAttachment.
stencilLoadOp
값에 따라:- 제공되지 않은 경우
-
Assert depthStencilAttachment.
stencilReadOnly
가true
임을 보장하고, depthStencilView의 stencil subresource를 프레임버퍼 메모리에 로드함. "load"
-
depthStencilView의 stencil subresource를 프레임버퍼 메모리에 로드함.
"clear"
-
depthStencilView의 stencil subresource에 연결된 프레임버퍼 메모리의 모든 텍셀을 depthStencilAttachment.
stencilClearValue
로 설정.
-
참고: 읽기 전용 depth-stencil 어태치먼트는 암묵적으로
"load"
연산을 수행한 것으로 처리됩니다. 읽기 전용 어태치먼트에서 load op를 명시하지 않아야 한다는 유효성 검증은 GPURenderPassDepthStencilAttachment Valid Usage에서 수행됩니다. -
beginComputePass(descriptor)
-
descriptor로 설명된 컴퓨트 패스 인코딩을 시작합니다.
호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.beginComputePass(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUComputePassDescriptor
✘ ✔ 컨텐트 타임라인 단계:
-
pass를 새
GPUComputePassEncoder
객체로 한다. -
this의 디바이스 타임라인에서 초기화 단계를 실행한다.
-
pass를 반환한다.
디바이스 타임라인 초기화 단계:-
아래 조건 중 하나라도 충족하지 않으면, pass를 무효화하고 반환.
-
descriptor.
timestampWrites
가 제공된 경우:-
timestampWrites 유효성 검증(this.
[[device]]
, descriptor.timestampWrites
) 는 true를 반환해야 함.
-
-
-
descriptor.
timestampWrites
가 제공된 경우:-
timestampWrites를 descriptor.
timestampWrites
로 한다. -
timestampWrites.
beginningOfPassWriteIndex
가 제공된 경우, append GPU 명령을 this.[[commands]]
에 추가하며, 아래 단계를 실행:-
패스 커맨드 실행 전, 현재 큐 타임스탬프를 timestampWrites.
beginningOfPassWriteIndex
인덱스에 timestampWrites.querySet
에 기록.
-
-
timestampWrites.
endOfPassWriteIndex
가 제공된 경우, pass.[[endTimestampWrite]]
에 아래 GPU 명령 단계를 설정:-
패스 커맨드 실행 후, 현재 큐 타임스탬프를 timestampWrites.
endOfPassWriteIndex
인덱스에 timestampWrites.querySet
에 기록.
-
-
-
13.4. 버퍼 복사 커맨드
copyBufferToBuffer()는 두 가지 오버로드를 지원합니다:
copyBufferToBuffer(source, destination, size)
-
간략 표기,
copyBufferToBuffer(source, 0, destination, 0, size)
와 동일합니다. copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size)
-
GPUCommandEncoder
에 한GPUBuffer
의 서브영역에서 다른GPUBuffer
의 서브영역으로 데이터를 복사하는 커맨드를 인코드합니다.호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 source
GPUBuffer
✘ ✘ 복사할 GPUBuffer
.sourceOffset
GPUSize64
✘ ✘ source에서 복사를 시작할 바이트 오프셋. destination
GPUBuffer
✘ ✘ 복사 대상 GPUBuffer
.destinationOffset
GPUSize64
✘ ✘ destination에 복사 데이터가 저장될 바이트 오프셋. size
GPUSize64
✘ ✔ 복사할 바이트 수. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행한다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
size가
undefined
이면, size를 source.size
− sourceOffset으로 설정. -
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
source가 this와 함께 사용 가능한 상태여야 함.
-
destination가 this와 함께 사용 가능한 상태여야 함.
-
size가 4의 배수여야 함.
-
sourceOffset가 4의 배수여야 함.
-
destinationOffset가 4의 배수여야 함.
-
source.
size
≥ (sourceOffset + size)여야 함. -
destination.
size
≥ (destinationOffset + size)여야 함. -
source와 destination이 동일
GPUBuffer
가 아니어야 함.
-
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
sourceOffset에서 시작하여 source의 size 바이트를 destinationOffset에서 시작하여 destination에 복사합니다.
-
clearBuffer(buffer, offset, size)
-
GPUCommandEncoder
에GPUBuffer
의 일부 영역을 0으로 채우는 커맨드를 인코드합니다.호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.clearBuffer(buffer, offset, size) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 buffer
GPUBuffer
✘ ✘ 초기화할 GPUBuffer
.offset
GPUSize64
✘ ✔ buffer에서 영역을 초기화할 바이트 오프셋. size
GPUSize64
✘ ✔ 초기화할 영역의 바이트 크기. 기본값은 버퍼 크기에서 offset만큼 뺀 값. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
size가 지정되지 않은 경우, size를
max(0, buffer.
로 설정.size
- offset) -
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
buffer가 this와 함께 사용 가능한 상태여야 함.
-
size가 4의 배수여야 함.
-
offset가 4의 배수여야 함.
-
buffer.
size
≥ (offset + size)여야 함.
-
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
offset에서 시작하여 buffer의 size 바이트를
0
으로 설정합니다.
-
13.5. 텍셀 복사 커맨드
copyBufferToTexture(source, destination, copySize)
-
GPUCommandEncoder
에GPUBuffer
의 일부 영역에서 하나 이상의 연속 텍스처 서브리소스의 일부 영역으로 데이터를 복사하는 커맨드를 인코드합니다.호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.copyBufferToTexture(source, destination, copySize) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 source
GPUTexelCopyBufferInfo
✘ ✘ copySize와 함께, 소스 버퍼 영역을 정의함. destination
GPUTexelCopyTextureInfo
✘ ✘ copySize와 함께, 목적지 텍스처 서브리소스 영역을 정의함. copySize
GPUExtent3D
✘ ✘ 반환값:
undefined
컨텐트 타임라인 단계:
-
GPUOrigin3D 형태 유효성 검증(destination.
origin
). -
GPUExtent3D 형태 유효성 검증(copySize).
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
aligned을
true
로 한다. -
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
validating GPUTexelCopyBufferInfo(source)가
true
를 반환해야 함. -
validating texture buffer copy(destination, source, dataLength, copySize,
COPY_DST
, aligned)가true
를 반환해야 함.
-
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
dstOrigin을 destination.
origin
로 한다. -
dstBlockOriginX를 (dstOrigin.x ÷ blockWidth)로 한다.
-
dstBlockOriginY를 (dstOrigin.y ÷ blockHeight)로 한다.
-
blockColumns를 (copySize.width ÷ blockWidth)로 한다.
-
blockRows를 (copySize.height ÷ blockHeight)로 한다.
-
Assert dstBlockOriginX, dstBlockOriginY, blockColumns, blockRows가 정수임을 보장한다.
-
각 z in [0, copySize.depthOrArrayLayers − 1]에 대해:
-
dstSubregion을 texture copy sub-region(z + dstOrigin.z) of destination로 한다.
-
각 y in [0, blockRows − 1]에 대해:
-
각 x in [0, blockColumns − 1]에 대해:
-
blockOffset을 texel block byte offset of source for (x, y, z) of destination.
texture
로 한다. -
dstSubregion의 (dstBlockOriginX + x, dstBlockOriginY + y) 텍셀 블록을 source.
buffer
의 blockOffset 위치의 동등 텍셀 표현으로 설정합니다.
-
-
-
-
copyTextureToBuffer(source, destination, copySize)
-
GPUCommandEncoder
에 하나 이상의 연속 텍스처 서브리소스의 일부 영역에서GPUBuffer
의 일부 영역으로 데이터를 복사하는 커맨드를 인코드합니다.호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.copyTextureToBuffer(source, destination, copySize) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 source
GPUTexelCopyTextureInfo
✘ ✘ copySize와 함께, 소스 텍스처 서브리소스 영역을 정의함. destination
GPUTexelCopyBufferInfo
✘ ✘ copySize와 함께, 목적지 버퍼 영역을 정의함. copySize
GPUExtent3D
✘ ✘ 반환값:
undefined
컨텐트 타임라인 단계:
-
GPUOrigin3D 형태 유효성 검증(source.
origin
). -
GPUExtent3D 형태 유효성 검증(copySize).
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
aligned을
true
로 한다. -
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
validating GPUTexelCopyBufferInfo(destination)가
true
를 반환해야 함. -
validating texture buffer copy(source, destination, dataLength, copySize,
COPY_SRC
, aligned)가true
를 반환해야 함.
-
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
srcOrigin을 source.
origin
로 한다. -
srcBlockOriginX를 (srcOrigin.x ÷ blockWidth)로 한다.
-
srcBlockOriginY를 (srcOrigin.y ÷ blockHeight)로 한다.
-
blockColumns를 (copySize.width ÷ blockWidth)로 한다.
-
blockRows를 (copySize.height ÷ blockHeight)로 한다.
-
Assert srcBlockOriginX, srcBlockOriginY, blockColumns, blockRows가 정수임을 보장한다.
-
각 z in [0, copySize.depthOrArrayLayers − 1]에 대해:
-
srcSubregion을 texture copy sub-region(z + srcOrigin.z) of source로 한다.
-
각 y in [0, blockRows − 1]에 대해:
-
각 x in [0, blockColumns − 1]에 대해:
-
blockOffset을 texel block byte offset of destination for (x, y, z) of source.
texture
로 한다. -
destination.
buffer
의 blockOffset 위치에 동등 텍셀 표현의 텍셀 블록 (srcBlockOriginX + x, srcBlockOriginY + y) of srcSubregion을 설정한다.
-
-
-
-
copyTextureToTexture(source, destination, copySize)
-
GPUCommandEncoder
에 하나 이상의 연속 텍스처 서브리소스의 일부 영역에서 다른 하나 이상의 연속 텍스처 서브리소스의 일부 영역으로 데이터를 복사하는 커맨드를 인코드합니다.호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.copyTextureToTexture(source, destination, copySize) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 source
GPUTexelCopyTextureInfo
✘ ✘ copySize와 함께, 소스 텍스처 서브리소스 영역을 정의함. destination
GPUTexelCopyTextureInfo
✘ ✘ copySize와 함께, 목적지 텍스처 서브리소스 영역을 정의함. copySize
GPUExtent3D
✘ ✘ 반환값:
undefined
컨텐트 타임라인 단계:
-
GPUOrigin3D 형태 유효성 검증(source.
origin
). -
GPUOrigin3D 형태 유효성 검증(destination.
origin
). -
GPUExtent3D 형태 유효성 검증(copySize).
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
srcTexture를 source.
texture
로 한다. -
dstTexture를 destination.
texture
로 한다. -
validating GPUTexelCopyTextureInfo(source, copySize) 가
true
를 반환해야 함. -
validating GPUTexelCopyTextureInfo(destination, copySize)가
true
를 반환해야 함. -
srcTexture.
sampleCount
값이 dstTexture.sampleCount
와 같아야 함. -
srcTexture.
format
값이 깊이-스텐실 포맷인 경우: -
텍스처 복사를 위한 서브리소스 집합(source, copySize)와 텍스처 복사를 위한 서브리소스 집합(destination, copySize)이 겹치지 않아야 함.
-
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
srcOrigin을 source.
origin
로 한다. -
srcBlockOriginX를 (srcOrigin.x ÷ blockWidth)로 한다.
-
srcBlockOriginY를 (srcOrigin.y ÷ blockHeight)로 한다.
-
dstOrigin을 destination.
origin
로 한다. -
dstBlockOriginX를 (dstOrigin.x ÷ blockWidth)로 한다.
-
dstBlockOriginY를 (dstOrigin.y ÷ blockHeight)로 한다.
-
blockColumns를 (copySize.width ÷ blockWidth)로 한다.
-
blockRows를 (copySize.height ÷ blockHeight)로 한다.
-
Assert srcBlockOriginX, srcBlockOriginY, dstBlockOriginX, dstBlockOriginY, blockColumns, blockRows가 정수임을 보장한다.
-
각 z in [0, copySize.depthOrArrayLayers − 1]에 대해:
-
srcSubregion을 texture copy sub-region(z + srcOrigin.z) of source로 한다.
-
dstSubregion을 texture copy sub-region(z + dstOrigin.z) of destination로 한다.
-
각 y in [0, blockRows − 1]에 대해:
-
-
13.6. 쿼리
resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset)
-
GPUQuerySet
의 쿼리 결과를GPUBuffer
의 범위로 내보내는 커맨드를 인코드합니다.호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 querySet
GPUQuerySet
✘ ✘ firstQuery
GPUSize32
✘ ✘ queryCount
GPUSize32
✘ ✘ destination
GPUBuffer
✘ ✘ destinationOffset
GPUSize64
✘ ✘ 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
querySet가 this와 함께 사용 가능한 상태여야 함.
-
destination가 this와 함께 사용 가능한 상태여야 함.
-
destination.
usage
에QUERY_RESOLVE
가 포함되어야 함. -
firstQuery가 querySet의 쿼리 개수보다 작아야 함.
-
(firstQuery + queryCount) ≤ querySet의 쿼리 개수이어야 함.
-
destinationOffset가 256의 배수여야 함.
-
destinationOffset + 8 × queryCount ≤ destination.
size
이어야 함.
-
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
queryIndex를 firstQuery로 한다.
-
offset을 destinationOffset로 한다.
-
queryIndex < firstQuery + queryCount인 동안:
-
destination의 offset 위치의 8 바이트를 querySet의 queryIndex 값으로 설정한다.
-
queryIndex를 queryIndex + 1로 설정.
-
offset을 offset + 8로 설정.
-
-
13.7. 최종화
GPUCommandBuffer
에 GPUCommandEncoder
로
기록된 커맨드들을 담아,
finish()
를
호출하여 생성할 수 있습니다.
한번 finish()
가
호출되면,
해당 커맨드 인코더는 더 이상 사용할 수 없습니다.
finish(descriptor)
-
커맨드 시퀀스 기록을 완료하고, 이에 해당하는
GPUCommandBuffer
를 반환합니다.호출 대상:GPUCommandEncoder
this.인자:
GPUCommandEncoder.finish(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUCommandBufferDescriptor
✘ ✔ 반환값:
GPUCommandBuffer
컨텐트 타임라인 단계:
-
commandBuffer를 새
GPUCommandBuffer
로 한다. -
this.
[[device]]
의 디바이스 타임라인에서 finish steps를 실행한다. -
commandBuffer를 반환한다.
디바이스 타임라인 finish steps:-
아래 모든 요구사항을 만족하면 validationSucceeded를
true
로, 아니면false
로 한다.-
this는 valid 상태여야 함.
-
this.
[[debug_group_stack]]
이 비어 있어야 함.
-
-
validationSucceeded가
false
면:-
무효화된
GPUCommandBuffer
를 반환.
-
commandBuffer.
[[command_list]]
값을 this.[[commands]]
로 설정.
-
14. 프로그래머블 패스
interface mixin {
GPUBindingCommandsMixin undefined setBindGroup (GPUIndex32 index ,GPUBindGroup ?bindGroup ,optional sequence <GPUBufferDynamicOffset >dynamicOffsets = []);undefined setBindGroup (GPUIndex32 index ,GPUBindGroup ?bindGroup , [AllowShared ]Uint32Array dynamicOffsetsData ,GPUSize64 dynamicOffsetsDataStart ,GPUSize32 dynamicOffsetsDataLength ); };
GPUBindingCommandsMixin
은
GPUObjectBase
와 GPUCommandsMixin
멤버가 동일 객체에 존재함을 가정합니다.
반드시 해당 믹스인들을 포함하는 인터페이스에서만 포함되어야 합니다.
GPUBindingCommandsMixin
은 다음 디바이스
타임라인 속성을 갖습니다:
[[bind_groups]]
, 타입 ordered map<GPUIndex32
,GPUBindGroup
>, 초기값은 empty-
각 인덱스의 현재
GPUBindGroup
값입니다. [[dynamic_offsets]]
, 타입 ordered map<GPUIndex32
, list<GPUBufferDynamicOffset
>>, 초기값은 empty-
각
[[bind_groups]]
항목의 현재 dynamic offset 값입니다.
14.1. 바인드 그룹
setBindGroup()는 두 가지 오버로드가 있습니다:
setBindGroup(index, bindGroup, dynamicOffsets)
-
주어진 인덱스에 대해 현재
GPUBindGroup
을 설정합니다.호출 대상:GPUBindingCommandsMixin
this.인자:
index
, 타입GPUIndex32
, non-nullable, 필수-
바인드 그룹을 설정할 인덱스입니다.
bindGroup
, 타입GPUBindGroup
, nullable, 필수-
이후 렌더/컴퓨트 커맨드에 사용할 바인드 그룹입니다.
dynamicOffsets
, 타입 sequence<GPUBufferDynamicOffset
>, non-nullable, 기본값[]
-
bindGroup에서
buffer
.hasDynamicOffset
로 표시된 각 항목에 대해 바이트 단위 버퍼 오프셋을 담은 배열이며,GPUBindGroupLayoutEntry
.binding
순서대로 정렬되어 있습니다. 추가적인 상세는 노트 참고.
반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
bindGroup
이null
이면 dynamicOffsetCount를 0으로, 아니면 bindGroup.[[layout]]
.[[dynamicOffsetCount]]
로 한다. -
아래 요구사항 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
index가 this.
[[device]]
.[[limits]]
.maxBindGroups
미만이어야 함. -
dynamicOffsets.size가 dynamicOffsetCount와 같아야 함.
-
-
bindGroup이
null
인 경우:-
Remove this.
[[bind_groups]]
[index]. -
Remove this.
[[dynamic_offsets]]
[index].
그 외의 경우:
-
아래 요구사항 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
bindGroup이 this와 함께 사용 가능한 상태여야 함.
-
각 dynamic binding 순회 (bufferBinding, bufferLayout, dynamicOffsetIndex) in bindGroup:
-
bufferBinding.
offset
+ dynamicOffsets[dynamicOffsetIndex] + bufferLayout.minBindingSize
값이 bufferBinding.buffer
.size
이하이어야 함. -
bufferLayout.
type
값이"uniform"
인 경우:-
dynamicOffset가
minUniformBufferOffsetAlignment
의 배수여야 함.
-
-
bufferLayout.
type
값이"storage"
또는"read-only-storage"
인 경우:-
dynamicOffset가
minStorageBufferOffsetAlignment
의 배수여야 함.
-
-
-
-
this.
[[bind_groups]]
[index] 값을 bindGroup으로 설정. -
this.
[[dynamic_offsets]]
[index] 값을 dynamicOffsets의 복사본으로 설정. -
this가
GPURenderCommandsMixin
인 경우:-
this.
[[bind_groups]]
의 각 bindGroup에 대해, merge bindGroup.[[usedResources]]
를 this.[[usage scope]]
에 병합.
-
-
setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength)
-
주어진 인덱스에 대해 현재
GPUBindGroup
을 설정하며, dynamic offsets를Uint32Array
의 일부로 지정합니다.호출 대상:GPUBindingCommandsMixin
this.인자:
GPUBindingCommandsMixin.setBindGroup(index, bindGroup, dynamicOffsetsData, dynamicOffsetsDataStart, dynamicOffsetsDataLength) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 index
GPUIndex32
✘ ✘ 바인드 그룹을 설정할 인덱스. bindGroup
GPUBindGroup?
✔ ✘ 이후 렌더/컴퓨트 커맨드에 사용할 바인드 그룹. dynamicOffsetsData
Uint32Array
✘ ✘ bindGroup에서 buffer
.hasDynamicOffset
로 표시된 각 항목에 대해 바이트 단위 버퍼 오프셋을 담은 배열이며,GPUBindGroupLayoutEntry
.binding
순서대로 정렬되어 있습니다. 추가적인 상세는 노트 참고.dynamicOffsetsDataStart
GPUSize64
✘ ✘ dynamicOffsetsData에서 버퍼 오프셋 데이터가 시작하는 요소 오프셋. dynamicOffsetsDataLength
GPUSize32
✘ ✘ dynamicOffsetsData에서 읽을 버퍼 오프셋 수. 반환값:
undefined
컨텐트 타임라인 단계:
-
아래 요구사항 중 하나라도 만족하지 않으면
RangeError
를 throw하고 반환.-
dynamicOffsetsDataStart가 0 이상이어야 함.
-
dynamicOffsetsDataStart + dynamicOffsetsDataLength 값이 dynamicOffsetsData.
length
이하이어야 함.
-
-
dynamicOffsets를 list로 생성하며, dynamicOffsetsDataStart 인덱스에서 시작하여 dynamicOffsetsDataLength 개의 요소를 버퍼 소스 복사본에서 복사.
-
this.
setBindGroup
(index, bindGroup, dynamicOffsets)을 호출.
-
GPUBindGroupLayoutEntry
.binding
순서대로 적용됩니다.
즉, dynamic bindings
가 GPUBindGroupLayoutEntry
중 GPUBindGroupLayout
에서
buffer
?.hasDynamicOffset
이 true
로 설정된 항목을 GPUBindGroupLayoutEntry
.binding
기준으로 정렬한 리스트라면,
setBindGroup()에 전달된
dynamic offset[i]
는
dynamic bindings[i]
에 대응합니다.
GPUBindGroupLayout
의
예시:
// bindings 배열 순서는 무관하지만 binding 인덱스 기준으로 정렬됩니다. // 순서가 바뀌어도 상관없습니다. let layout= gpuDevice. createBindGroupLayout({ entries: [{ binding: 1 , buffer: {}, }, { binding: 2 , buffer: { dynamicOffset: true }, }, { binding: 0 , buffer: { dynamicOffset: true }, }] });
다음 호출로 생성된 GPUBindGroup
에서
사용:
// 위와 마찬가지로 배열 순서는 상관없습니다. // layout에서 사용한 순서와 일치할 필요도 없습니다. let bindGroup= gpuDevice. createBindGroup({ layout: layout, entries: [{ binding: 1 , resource: { buffer: bufferA, offset: 256 }, }, { binding: 2 , resource: { buffer: bufferB, offset: 512 }, }, { binding: 0 , resource: { buffer: bufferC}, }] });
그리고 다음 호출로 바인딩:
pass. setBindGroup( 0 , bindGroup, [ 1024 , 2048 ]);
적용되는 버퍼 오프셋은 다음과 같습니다:
바인딩 | 버퍼 | 오프셋 |
---|---|---|
0 | bufferC | 1024 (Dynamic) |
1 | bufferA | 256 (Static) |
2 | bufferB | 2560 (Static + Dynamic) |
GPUBindGroup
bindGroup에 대해 steps 리스트 단계를 각 dynamic offset에 실행하려면, 다음 디바이스 타임라인 단계를 수행합니다:
-
dynamicOffsetIndex를
0
으로 한다. -
layout을 bindGroup.
[[layout]]
로 한다. -
bindGroup.
[[entries]]
에서 각GPUBindGroupEntry
entry를 entry.binding
값을 오름차순으로 정렬하여 순회:-
bindingDescriptor를 layout.
[[entryMap]]
[entry.binding
]로 한다. -
bindingDescriptor.
buffer
?.hasDynamicOffset
이true
인 경우:-
bufferBinding을 get as buffer binding(entry.
resource
)로 한다. -
bufferLayout을 bindingDescriptor.
buffer
로 한다. -
steps에 bufferBinding, bufferLayout, dynamicOffsetIndex를 전달해서 호출.
-
dynamicOffsetIndex를 dynamicOffsetIndex +
1
로 한다.
-
-
인자:
GPUBindingCommandsMixin
encoder-
바인드 그룹을 검증할 인코더.
GPUPipelineBase
pipeline-
인코더의 바인드 그룹과 호환되는지 검증할 파이프라인.
디바이스 타임라인 단계:
-
아래 조건 중 하나라도 만족하지 않으면
false
반환:-
pipeline이
null
이 아니어야 함. -
파이프라인에서 사용하는 모든 바인드 그룹이 설정되어 있고, 파이프라인 레이아웃과 호환되어야 함: (
GPUIndex32
index,GPUBindGroupLayout
bindGroupLayout) 쌍마다 pipeline.[[layout]]
.[[bindGroupLayouts]]
에서 반복:-
bindGroupLayout이
null
이면, continue. -
bindGroup을 encoder.
[[bind_groups]]
[index]로 한다. -
dynamicOffsets를 encoder.
[[dynamic_offsets]]
[index]로 한다. -
bindGroup이
null
이 아니어야 함. -
bindGroup.
[[layout]]
가 group-equivalent이어야 함. bindGroupLayout과 호환되어야 함. -
dynamicOffsetIndex를 0으로 한다.
-
bindGroup.
[[entries]]
의 각GPUBindGroupEntry
bindGroupEntry를 bindGroupEntry.binding
값을 기준으로 정렬하여 반복:-
bindGroupLayoutEntry를 bindGroup.
[[layout]]
.[[entryMap]]
[bindGroupEntry.binding
]로 한다. -
bindGroupLayoutEntry.
buffer
가 제공되지 않은 경우, continue. -
bound을 get as buffer binding(bindGroupEntry.
resource
)로 한다. -
bindGroupLayoutEntry.
buffer
.hasDynamicOffset
인 경우:-
bound.
offset
값에 dynamicOffsets[dynamicOffsetIndex]을 더함. -
dynamicOffsetIndex를 1 증가.
-
-
bindGroupEntry.
[[prevalidatedSize]]
가false
인 경우:-
effective buffer binding size(bound) 값이 최소 버퍼 바인딩 크기 보다 커야 함. 해당 bindGroupEntry에 대응하는 파이프라인의 셰이더 바인딩 변수 기준.
-
-
-
-
인코더 바인드 그룹이 쓰기 가능한 리소스와 겹치는지 검사(encoder, pipeline) 값이
false
여야 함.
-
그 외에는 true
반환.
GPUTextureView
객체의 텍스처 서브리소스와
겹칠 경우 참입니다.
참고: 이 알고리즘은 usage scope storage 예외 사용을 제한합니다.
인자:
GPUBindingCommandsMixin
encoder-
바인드 그룹을 검증할 인코더.
GPUPipelineBase
pipeline-
인코더의 바인드 그룹과 호환되는지 검증할 파이프라인.
디바이스 타임라인 단계:
-
각 stage in [
VERTEX
,FRAGMENT
,COMPUTE
]에 대해:-
bufferBindings를 (
GPUBufferBinding
,boolean
) 쌍의 list로 한다. 두 번째 값은 리소스가 쓰기 용도로 사용되었는지 여부. -
textureViews를 (
GPUTextureView
,boolean
) 쌍의 list로 한다. 두 번째 값은 리소스가 쓰기 용도로 사용되었는지 여부. -
각 (
GPUIndex32
bindGroupIndex,GPUBindGroupLayout
bindGroupLayout) 쌍에 대해 pipeline.[[layout]]
.[[bindGroupLayouts]]
에서 반복:-
bindGroup을 encoder.
[[bind_groups]]
[bindGroupIndex]로 한다. -
bindGroupLayoutEntries를 bindGroupLayout.
[[descriptor]]
.entries
로 한다. -
bufferRanges를 bindGroup의 바인딩된 버퍼 범위로 한다. dynamic offset은 encoder.
[[dynamic_offsets]]
[bindGroupIndex] 사용 -
bindGroupLayoutEntries와 bufferRanges에서, bindGroupLayoutEntry.
visibility
값이 stage를 포함하는 각 (GPUBindGroupLayoutEntry
bindGroupLayoutEntry,GPUBufferBinding
resource)에 대해:-
resourceWritable를 (bindGroupLayoutEntry.
buffer
.type
=="storage"
)로 한다. -
각 (
GPUBufferBinding
pastResource,boolean
pastResourceWritable) in bufferBindings에 대해:-
(resourceWritable 또는 pastResourceWritable)가 true이고, pastResource와 resource가 buffer-binding-aliasing이면
true
반환.
-
-
Append (resource, resourceWritable)를 bufferBindings에 추가.
-
-
bindGroupLayoutEntries와 bindGroup의 텍스처에 대해, bindGroupLayoutEntry.
visibility
값이 stage를 포함하는 각 (GPUBindGroupLayoutEntry
bindGroupLayoutEntry,GPUTextureView
resource)에 대해:-
bindGroupLayoutEntry.
storageTexture
값이 제공되지 않은 경우, continue. -
resourceWritable를 bindGroupLayoutEntry.
storageTexture
.access
값이 쓰기 모드인 경우로 한다. -
각 (
GPUTextureView
pastResource,boolean
pastResourceWritable) in textureViews에 대해,-
(resourceWritable 또는 pastResourceWritable)가 true이고, pastResource와 resource가 texture-view-aliasing이면
true
반환.
-
-
Append (resource, resourceWritable)를 textureViews에 추가.
-
-
-
-
false
반환.
참고: 구현체는 이 알고리즘을 최대한 최적화하는 것이 권장됩니다.
15. 디버그 마커
GPUDebugCommandsMixin
은 커맨드 그룹에 디버그 라벨을 적용하거나 커맨드 시퀀스에 단일
라벨을 삽입하는 메서드를 제공합니다.
디버그 그룹은 중첩하여 라벨 계층 구조를 만들 수 있으며, 반드시 균형 잡힌 구조여야 합니다.
객체 라벨
과
마찬가지로,
이러한 라벨은 필수 동작을 요구하지 않지만, 오류 메시지, 브라우저 개발자 도구, 네이티브 API 백엔드에 표시될 수 있습니다.
interface mixin GPUDebugCommandsMixin {undefined pushDebugGroup (USVString groupLabel );undefined popDebugGroup ();undefined insertDebugMarker (USVString markerLabel ); };
GPUDebugCommandsMixin
은
GPUObjectBase
와 GPUCommandsMixin
멤버가 동일 객체에 존재함을 가정합니다.
반드시 해당 믹스인들을 포함하는 인터페이스에서만 포함되어야 합니다.
GPUDebugCommandsMixin
은 다음 디바이스
타임라인 속성을 갖습니다:
[[debug_group_stack]]
, 타입 stack<USVString
>-
활성화된 디버그 그룹 라벨의 스택입니다.
GPUDebugCommandsMixin
은 다음 메서드를 제공합니다:
pushDebugGroup(groupLabel)
-
이후 커맨드를 포함하는 라벨이 지정된 디버그 그룹을 시작합니다.
호출 대상:GPUDebugCommandsMixin
this.인자:
GPUDebugCommandsMixin.pushDebugGroup(groupLabel) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 groupLabel
USVString
✘ ✘ 커맨드 그룹의 라벨. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
Push groupLabel을 this.
[[debug_group_stack]]
에 추가.
-
popDebugGroup()
-
가장 최근에 시작된 디버그 그룹(
pushDebugGroup()
)을 종료합니다.호출 대상:GPUDebugCommandsMixin
this.반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면 this를 무효화하고 반환.
-
this.
[[debug_group_stack]]
값이 비어 있지 않아야 함.
-
-
Pop을 this.
[[debug_group_stack]]
에 대해 실행.
-
insertDebugMarker(markerLabel)
-
커맨드 스트림의 한 지점에 라벨을 삽입합니다.
호출 대상:GPUDebugCommandsMixin
this.인자:
GPUDebugCommandsMixin.insertDebugMarker(markerLabel) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 markerLabel
USVString
✘ ✘ 삽입할 라벨. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
-
16. 컴퓨트 패스
16.1. GPUComputePassEncoder
[Exposed =(Window ,Worker ),SecureContext ]interface GPUComputePassEncoder {undefined setPipeline (GPUComputePipeline pipeline );undefined dispatchWorkgroups (GPUSize32 workgroupCountX ,optional GPUSize32 workgroupCountY = 1,optional GPUSize32 workgroupCountZ = 1);undefined dispatchWorkgroupsIndirect (GPUBuffer indirectBuffer ,GPUSize64 indirectOffset );undefined end (); };GPUComputePassEncoder includes GPUObjectBase ;GPUComputePassEncoder includes GPUCommandsMixin ;GPUComputePassEncoder includes GPUDebugCommandsMixin ;GPUComputePassEncoder includes GPUBindingCommandsMixin ;
GPUComputePassEncoder
는 다음 디바이스
타임라인 속성을 가집니다:
[[command_encoder]]
, 타입GPUCommandEncoder
, 읽기 전용-
이 컴퓨트 패스 인코더를 생성한
GPUCommandEncoder
입니다. [[endTimestampWrite]]
, 타입 GPU command?, 읽기 전용, 기본값null
-
패스가 끝날 때 타임스탬프를 기록하는 GPU command가 있을 경우 해당 명령입니다.
[[pipeline]]
, 타입GPUComputePipeline
, 초기값null
-
현재
GPUComputePipeline
입니다.
16.1.1. 컴퓨트 패스 인코더 생성
dictionary {
GPUComputePassTimestampWrites required GPUQuerySet querySet ;GPUSize32 beginningOfPassWriteIndex ;GPUSize32 endOfPassWriteIndex ; };
querySet
, 타입 GPUQuerySet-
GPUQuerySet
의 쿼리 결과가 기록될"timestamp"
타입 객체입니다. beginningOfPassWriteIndex
, 타입 GPUSize32-
정의된 경우, compute 패스 시작 시 타임스탬프가 기록될
querySet
의 쿼리 인덱스를 의미합니다. endOfPassWriteIndex
, 타입 GPUSize32-
정의된 경우, compute 패스 종료 시 타임스탬프가 기록될
querySet
의 쿼리 인덱스를 의미합니다.
참고: 타임스탬프 쿼리 값은 나노초 단위로 기록되지만, 값이 어떻게 결정되는지는 구현 정의이며 반드시 단조 증가하지 않을 수 있습니다. 자세한 내용은 § 20.4 타임스탬프 쿼리 참고.
dictionary :
GPUComputePassDescriptor GPUObjectDescriptorBase {GPUComputePassTimestampWrites timestampWrites ; };
timestampWrites
, 타입 GPUComputePassTimestampWrites-
이 패스에서 어떤 타임스탬프 값을 어디에 기록할지 정의합니다.
16.1.2. 디스패치
setPipeline(pipeline)
-
현재
GPUComputePipeline
을 설정합니다.호출 대상:GPUComputePassEncoder
this.인자:
GPUComputePassEncoder.setPipeline(pipeline) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 pipeline
GPUComputePipeline
✘ ✘ 이후 디스패치 명령에 사용할 컴퓨트 파이프라인. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
pipeline이 this와 함께 사용 가능한 상태여야 함.
-
-
this.
[[pipeline]]
값을 pipeline으로 설정.
-
dispatchWorkgroups(workgroupCountX, workgroupCountY, workgroupCountZ)
-
현재
GPUComputePipeline
을 사용해 작업을 디스패치합니다. 상세 명세는 § 23.1 컴퓨팅 참고.호출 대상:GPUComputePassEncoder
this.인자:
GPUComputePassEncoder.dispatchWorkgroups(workgroupCountX, workgroupCountY, workgroupCountZ) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 workgroupCountX
GPUSize32
✘ ✘ 디스패치할 workgroup의 X 차원 크기. workgroupCountY
GPUSize32
✘ ✔ 디스패치할 workgroup의 Y 차원 크기. workgroupCountZ
GPUSize32
✘ ✔ 디스패치할 workgroup의 Z 차원 크기. 참고:x
,y
,z
값은dispatchWorkgroups()
및dispatchWorkgroupsIndirect()
에 전달될 때 각 차원의 workgroup 개수이지, 각 차원에 걸쳐 실행될 셰이더 호출 개수가 아닙니다. 이는 현행 GPU API 동작과 일치하지만 OpenCL과는 다릅니다.예를 들어
GPUShaderModule
의 entry point가@workgroup_size(4, 4)
으로 정의되어 있고,computePass.dispatchWorkgroups(8, 8);
로 디스패치하면, entry point는 총 1024번 호출됩니다: 4x4 workgroup을 X, Y축 각각 8번 디스패치해서4*4*8*8=1024
번 실행됩니다.반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
usageScope를 비어 있는 usage scope로 한다.
-
this.
[[bind_groups]]
의 각 bindGroup에 대해, merge bindGroup.[[usedResources]]
를 this.[[usage scope]]
에 병합합니다. -
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
usageScope가 usage scope 유효성 검증을 통과해야 함.
-
인코더 바인드 그룹 유효성 검증(this, this.
[[pipeline]]
) 값이true
여야 함. -
workgroupCountX, workgroupCountY, workgroupCountZ가 모두 this.device.limits.
maxComputeWorkgroupsPerDimension
이하이어야 함.
-
-
bindingState를 this의 현재 상태 스냅샷으로 한다.
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
[workgroupCountX, workgroupCountY, workgroupCountZ] 크기의 workgroup 그리드를 bindingState.
[[pipeline]]
로 실행하며, bindingState.[[bind_groups]]
를 사용합니다.
-
dispatchWorkgroupsIndirect(indirectBuffer, indirectOffset)
-
현재
GPUComputePipeline
을 사용해GPUBuffer
에서 읽은 파라미터로 작업을 디스패치합니다. 상세 명세는 § 23.1 컴퓨팅 참고.버퍼에 인코딩되는 indirect dispatch parameters는 세 개의 32비트 unsigned 정수 값(총 12 바이트)을 동일한 순서로 연속 저장해야 합니다.
dispatchWorkgroups()
인자 순서와 동일합니다. 예시:let dispatchIndirectParameters= new Uint32Array( 3 ); dispatchIndirectParameters[ 0 ] = workgroupCountX; dispatchIndirectParameters[ 1 ] = workgroupCountY; dispatchIndirectParameters[ 2 ] = workgroupCountZ; 호출 대상:GPUComputePassEncoder
this.인자:
GPUComputePassEncoder.dispatchWorkgroupsIndirect(indirectBuffer, indirectOffset) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 indirectBuffer
GPUBuffer
✘ ✘ indirect dispatch parameters가 저장된 버퍼. indirectOffset
GPUSize64
✘ ✘ indirectBuffer에서 디스패치 데이터가 시작하는 바이트 오프셋. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. false면 반환.
-
usageScope를 비어 있는 usage scope로 한다.
-
this.
[[bind_groups]]
의 각 bindGroup에 대해, merge bindGroup.[[usedResources]]
를 this.[[usage scope]]
에 병합합니다. -
아래 조건 중 하나라도 충족하지 않으면, this를 무효화하고 반환.
-
usageScope가 usage scope 유효성 검증을 통과해야 함.
-
인코더 바인드 그룹 유효성 검증(this, this.
[[pipeline]]
) 값이true
여야 함. -
indirectBuffer가 this와 함께 사용 가능한 상태여야 함.
-
indirectOffset + sizeof(indirect dispatch parameters)가 indirectBuffer.
size
이하이어야 함. -
indirectOffset가 4의 배수여야 함.
-
-
bindingState를 this의 현재 상태 스냅샷으로 한다.
-
Enqueue a command를 this에 실행하여, 실행 시 큐 타임라인에서 이후 단계를 실행.
큐 타임라인 단계:-
workgroupCountX를 indirectBuffer에서 indirectOffset 바이트 위치에서 읽은 unsigned 32비트 정수로 설정.
-
workgroupCountY를 indirectBuffer에서 (indirectOffset + 4) 바이트 위치에서 읽은 unsigned 32비트 정수로 설정.
-
workgroupCountZ를 indirectBuffer에서 (indirectOffset + 8) 바이트 위치에서 읽은 unsigned 32비트 정수로 설정.
-
workgroupCountX, workgroupCountY, workgroupCountZ 중 하나라도 this.device.limits.
maxComputeWorkgroupsPerDimension
보다 크면 반환. -
[workgroupCountX, workgroupCountY, workgroupCountZ] 크기의 workgroup 그리드를 bindingState.
[[pipeline]]
로 실행하며, bindingState.[[bind_groups]]
를 사용합니다.
-
16.1.3. 최종화
사용자가 패스에 대한 커맨드 기록을 끝낸 뒤 end()
를
호출함으로써 컴퓨트 패스 인코더를 종료할 수 있습니다.
end()
가
호출된 후에는 해당 컴퓨트 패스 인코더를 더 이상 사용할 수 없습니다.
end()
-
컴퓨트 패스 커맨드 시퀀스 기록을 완료합니다.
호출 대상:GPUComputePassEncoder
this.반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
parentEncoder를 this.
[[command_encoder]]
로 설정. -
아래 요구사항 중 하나라도 만족하지 않으면, 유효성 오류 생성 후 반환.
-
아래 요구사항 중 하나라도 만족하지 않으면, parentEncoder를 무효화하고 반환.
-
this가 valid 상태여야 함.
-
this.
[[debug_group_stack]]
값이 비어 있어야 함.
-
-
Extend parentEncoder.
[[commands]]
값에 this.[[commands]]
를 확장. -
this.
[[endTimestampWrite]]
값이null
이 아니면:-
Extend parentEncoder.
[[commands]]
값에 this.[[endTimestampWrite]]
를 확장.
-
-
17. 렌더 패스
17.1. GPURenderPassEncoder
[Exposed =(Window ,Worker ),SecureContext ]interface GPURenderPassEncoder {undefined setViewport (float x ,float y ,float width ,float height ,float minDepth ,float maxDepth );undefined setScissorRect (GPUIntegerCoordinate x ,GPUIntegerCoordinate y ,GPUIntegerCoordinate width ,GPUIntegerCoordinate height );undefined setBlendConstant (GPUColor color );undefined setStencilReference (GPUStencilValue reference );undefined beginOcclusionQuery (GPUSize32 queryIndex );undefined endOcclusionQuery ();undefined executeBundles (sequence <GPURenderBundle >bundles );undefined end (); };GPURenderPassEncoder includes GPUObjectBase ;GPURenderPassEncoder includes GPUCommandsMixin ;GPURenderPassEncoder includes GPUDebugCommandsMixin ;GPURenderPassEncoder includes GPUBindingCommandsMixin ;GPURenderPassEncoder includes GPURenderCommandsMixin ;
GPURenderPassEncoder
는 다음 디바이스
타임라인 속성을 가집니다:
[[command_encoder]]
, 타입GPUCommandEncoder
, 읽기 전용-
이 렌더 패스 인코더를 생성한
GPUCommandEncoder
입니다. [[attachment_size]]
, 읽기 전용-
다음 크기로 설정됩니다:
-
width, height
= 패스의 렌더 어태치먼트의 크기
-
[[occlusion_query_set]]
, 타입GPUQuerySet
, 읽기 전용-
패스의 오클루전 쿼리 결과를 저장할
GPUQuerySet
이며, 패스 생성 시GPURenderPassDescriptor
.occlusionQuerySet
으로 초기화됩니다. [[endTimestampWrite]]
, 타입 GPU command?, 읽기 전용, 기본값null
-
패스 종료 시 타임스탬프를 기록하는 GPU command가 있을 경우 해당 명령입니다.
[[maxDrawCount]]
타입GPUSize64
, 읽기 전용-
이 패스에서 허용되는 최대 draw 수입니다.
[[occlusion_query_active]]
, 타입boolean
-
패스의
[[occlusion_query_set]]
이 기록 중인지 여부.
렌더 패스 커맨드가 GPUCommandBuffer
의
일부로 실행될 때,
내부 RenderState 객체가 렌더링에
필요한 현재 상태를 추적합니다.
RenderState는 다음 큐 타임라인 속성을 가집니다:
[[occlusionQueryIndex]]
, 타입GPUSize32
-
오클루전 쿼리 결과를 저장할
[[occlusion_query_set]]
의 인덱스입니다. [[viewport]]
-
현재 뷰포트 사각형 및 깊이 범위. 초기값은 다음과 같습니다:
-
x, y
=0.0, 0.0
-
width, height
= 패스의 렌더 타겟 크기 -
minDepth, maxDepth
=0.0, 1.0
-
[[scissorRect]]
-
현재 시저(Scissor) 사각형. 초기값은 다음과 같습니다:
-
x, y
=0, 0
-
width, height
= 패스의 렌더 타겟 크기
-
[[blendConstant]]
, 타입GPUColor
-
현재 블렌드 상수값. 초기값은
[0, 0, 0, 0]
입니다. [[stencilReference]]
, 타입GPUStencilValue
-
현재 스텐실 참조값. 초기값은
0
입니다. [[colorAttachments]]
, 타입 sequence<GPURenderPassColorAttachment
?>-
이 렌더 패스의 컬러 어태치먼트와 상태입니다.
[[depthStencilAttachment]]
, 타입GPURenderPassDepthStencilAttachment
?-
이 렌더 패스의 깊이/스텐실 어태치먼트와 상태입니다.
렌더 패스에는 프레임버퍼 메모리도 있는데, 이는 draw 커맨드로 기록되고 블렌딩 및 깊이/스텐실 테스트에 읽히는 각 어태치먼트에 매핑된 텍셀 데이터를 포함합니다.
참고: GPU 하드웨어에 따라 프레임버퍼 메모리가 어태치먼트 텍스처에서 직접 할당된 메모리일 수도 있고, 타일 기반 등 아키텍처에서는 텍스처 데이터가 복사되는 별도의 메모리 영역일 수도 있습니다.
17.1.1. 렌더 패스 인코더 생성
dictionary {
GPURenderPassTimestampWrites required GPUQuerySet querySet ;GPUSize32 beginningOfPassWriteIndex ;GPUSize32 endOfPassWriteIndex ; };
querySet
, 타입 GPUQuerySet-
GPUQuerySet
의 쿼리 결과가 기록될"timestamp"
타입 객체입니다. beginningOfPassWriteIndex
, 타입 GPUSize32-
정의된 경우, 렌더 패스 시작 시 타임스탬프가 기록될
querySet
의 쿼리 인덱스를 의미합니다. endOfPassWriteIndex
, 타입 GPUSize32-
정의된 경우, 렌더 패스 종료 시 타임스탬프가 기록될
querySet
의 쿼리 인덱스를 의미합니다.
참고: 타임스탬프 쿼리 값은 나노초 단위로 기록되지만, 값이 어떻게 결정되는지는 구현 정의이며 반드시 단조 증가하지 않을 수 있습니다. 자세한 내용은 § 20.4 타임스탬프 쿼리 참고.
dictionary :
GPURenderPassDescriptor GPUObjectDescriptorBase {required sequence <GPURenderPassColorAttachment ?>colorAttachments ;GPURenderPassDepthStencilAttachment depthStencilAttachment ;GPUQuerySet occlusionQuerySet ;GPURenderPassTimestampWrites timestampWrites ;GPUSize64 maxDrawCount = 50000000; };
colorAttachments
, 타입sequence<GPURenderPassColorAttachment?>
-
이 시퀀스에 포함된
GPURenderPassColorAttachment
값들은 렌더 패스 실행 시 출력할 컬러 어태치먼트를 정의합니다.사용 호환성에 따라, 어느 컬러 어태치먼트도 다른 어태치먼트나 렌더 패스 내 사용되는 리소스와 겹칠 수 없습니다.
depthStencilAttachment
, 타입 GPURenderPassDepthStencilAttachment-
실행 시 출력 및 테스트에 사용할
GPURenderPassDepthStencilAttachment
값입니다.사용 호환성에 따라, 쓰기 가능한 깊이/스텐실 어태치먼트는 다른 어태치먼트나 패스 내 사용된 리소스와 겹칠 수 없습니다.
occlusionQuerySet
, 타입 GPUQuerySet-
이 패스의 오클루전 쿼리 결과를 저장할
GPUQuerySet
값입니다. timestampWrites
, 타입 GPURenderPassTimestampWrites-
이 패스에서 어떤 타임스탬프 값을 어디에 기록할지 정의합니다.
maxDrawCount
, 타입 GPUSize64, 기본값50000000
-
렌더 패스에서 수행될 최대 draw 호출 수입니다. 일부 구현체는 렌더 패스 전에 작업 크기 결정에 사용합니다. 더 많은 draw가 필요하지 않다면 기본값을 유지하는 것이 좋습니다.
GPUDevice
device와 GPURenderPassDescriptor
this가 주어진 경우, 다음과 같은 검증 규칙이 적용됩니다:
-
this.
colorAttachments
.size가 device.[[limits]]
.maxColorAttachments
이하이어야 합니다. -
this.
colorAttachments
의 각 non-null
colorAttachment에 대해:-
colorAttachment.
view
는 device와 함께 사용 가능한 상태여야 합니다. -
colorAttachment.
resolveTarget
값이 제공된 경우:-
colorAttachment.
resolveTarget
역시 device와 함께 사용 가능한 상태여야 합니다.
-
-
colorAttachment는 GPURenderPassColorAttachment 유효한 사용 규칙을 만족해야 합니다.
-
-
this.
depthStencilAttachment
값이 제공된 경우:-
this.
depthStencilAttachment
.view
는 device와 함께 사용 가능한 상태여야 합니다. -
this.
depthStencilAttachment
는 GPURenderPassDepthStencilAttachment 유효한 사용 규칙을 만족해야 합니다.
-
-
최소 하나의 어태치먼트가 존재해야 합니다. 즉 다음 중 하나:
-
this.
colorAttachments
중 non-null
값, 또는
-
-
GPURenderPassDescriptor의 color attachment bytes per sample 유효성 검증(device, this.
colorAttachments
) 가 성공해야 합니다. -
non-
null
this.colorAttachments
멤버의 모든view
와, this.depthStencilAttachment
.view
(존재시)의sampleCount
가 모두 같아야 합니다. -
non-
null
this.colorAttachments
멤버의 모든view
와, this.depthStencilAttachment
.view
(존재시)의[[renderExtent]]
가 일치해야 합니다. -
this.
occlusionQuerySet
값이 제공된 경우:-
this.
occlusionQuerySet
값은 device와 함께 사용 가능한 상태여야 합니다. -
this.
occlusionQuerySet
.type
값이occlusion
이어야 합니다.
-
-
this.
timestampWrites
값이 제공된 경우:-
timestampWrites 검증(device, this.
timestampWrites
) 결과가 true여야 합니다.
-
인자:
-
GPUDevice
device -
sequence<
GPURenderPassColorAttachment
?> colorAttachments
디바이스 타임라인 단계:
-
formats를 빈 list<
GPUTextureFormat
?>로 초기화합니다. -
colorAttachments의 각 colorAttachment에 대해:
-
colorAttachment가
undefined
인 경우 continue. -
Append colorAttachment.
view
.[[descriptor]]
.format
를 formats에 추가합니다.
-
-
color attachment bytes per sample 계산(formats)이 device.
[[limits]]
.maxColorAttachmentBytesPerSample
이하이어야 합니다.
17.1.1.1. 컬러 어태치먼트
dictionary {
GPURenderPassColorAttachment required (GPUTexture or GPUTextureView )view ;GPUIntegerCoordinate depthSlice ; (GPUTexture or GPUTextureView )resolveTarget ;GPUColor clearValue ;required GPULoadOp loadOp ;required GPUStoreOp storeOp ; };
view
, 타입(GPUTexture 또는 GPUTextureView)
-
이 컬러 어태치먼트에서 출력될 텍스처 서브리소스를 설명합니다. 서브리소스는 get as texture view(
view
) 호출로 결정됩니다. depthSlice
, 타입 GPUIntegerCoordinateresolveTarget
, 타입(GPUTexture 또는 GPUTextureView)
-
이 컬러 어태치먼트에서
view
값이 멀티샘플링일 경우, 해상된 출력이 기록될 텍스처 서브리소스를 설명합니다. 서브리소스는 get as texture view(resolveTarget
) 호출로 결정됩니다. clearValue
, 타입 GPUColor-
렌더 패스를 실행하기 전에
view
값을 초기화할 값입니다. 제공되지 않으면 기본값{r: 0, g: 0, b: 0, a: 0}
입니다.loadOp
값이"clear"
가 아니면 무시됩니다.clearValue
각 구성 요소는 모두 double 값입니다. 렌더 어태치먼트에 맞는 텍스처 포맷 텍셀 값 변환 시도에 실패하면 유효성 오류가 발생합니다. loadOp
, 타입 GPULoadOp-
렌더 패스를 실행하기 전에
view
에 수행할 load 연산을 지정합니다.참고: 초기화(clear)를 우선 추천합니다. 자세한 내용은
"clear"
참고. storeOp
, 타입 GPUStoreOp-
렌더 패스 실행 후
view
에 수행할 store 연산을 지정합니다.
GPURenderPassColorAttachment
this가 주어진 경우:
-
renderViewDescriptor를 this.
view
.[[descriptor]]
로 설정. -
renderTexture를 this.
view
.[[texture]]
로 설정. -
아래 모든 요구사항을 만족해야 합니다.
-
this.
view
값이 렌더링 가능한 텍스처 뷰여야 합니다. -
renderViewDescriptor.
dimension
값이"3d"
인 경우:-
this.
depthSlice
값이 제공되어야 하며 또한 renderTexture 서브리소스의 depthOrArrayLayers 보다 작아야 합니다. (해당 논리적 mip레벨 특정 텍스처 크기 기준, renderViewDescriptor.baseMipLevel
에서)
그 외의 경우:
-
this.
depthSlice
값이 제공되어서는 안 됩니다.
-
-
-
IDL 값 this.
clearValue
를 renderViewDescriptor.format
에 맞는 텍셀 값 변환 시TypeError
가 발생하면 안 됩니다.참고: 값이 포맷 범위 밖이더라도 WGSL 프리미티브 타입(
f32
,i32
,u32
) 범위 내라면 오류가 발생하지 않습니다.
-
-
this.
resolveTarget
값이 제공된 경우:-
resolveViewDescriptor를 this.
resolveTarget
.[[descriptor]]
로 설정. -
resolveTexture를 this.
resolveTarget
.[[texture]]
로 설정. -
renderTexture.
sampleCount
값이 반드시 1보다 커야 합니다. -
resolveTexture.
sampleCount
값이 반드시 1이어야 합니다. -
this.
resolveTarget
값이 3d가 아닌 렌더링 가능한 텍스처 뷰여야 합니다. -
this.
resolveTarget
.[[renderExtent]]
값과 this.view
.[[renderExtent]]
값이 반드시 일치해야 합니다. -
resolveViewDescriptor.
format
값이 반드시 renderViewDescriptor.format
값과 같아야 합니다. -
resolveTexture.
format
값이 반드시 renderTexture.format
값과 같아야 합니다. -
resolveViewDescriptor.
format
값이 § 26.1.1 일반 컬러 포맷에 따라 resolve를 지원해야 합니다.
-
GPUTextureView
view가 렌더링 가능한 텍스처 뷰이려면, 아래 디바이스 타임라인 단계 요구사항을 모두 만족해야 합니다:
-
descriptor를 view.
[[descriptor]]
로 설정합니다. -
descriptor.
usage
값에RENDER_ATTACHMENT
가 포함되어야 합니다. -
descriptor.
dimension
값이"2d"
또는"2d-array"
또는"3d"
이어야 합니다. -
descriptor.
mipLevelCount
값이 1이어야 합니다. -
descriptor.
arrayLayerCount
값이 1이어야 합니다. -
descriptor.
aspect
값이 view.[[texture]]
의 모든 aspect을 참조해야 합니다.
인자:
-
sequence<
GPUTextureFormat
?> formats
반환값: GPUSize32
-
total을 0으로 설정합니다.
-
formats의 각 non-null format에 대해
-
renderTargetPixelByteCost를 format의 렌더 타겟 픽셀 바이트 비용으로 설정합니다.
-
renderTargetComponentAlignment를 format의 렌더 타겟 컴포넌트 정렬로 설정합니다.
-
total을 renderTargetComponentAlignment의 배수 중 total 이상 중 가장 작은 값으로 올림합니다.
-
renderTargetPixelByteCost를 total에 더합니다.
-
total을 반환합니다.
17.1.1.2. 깊이/스텐실 어태치먼트
dictionary {
GPURenderPassDepthStencilAttachment required (GPUTexture or GPUTextureView )view ;float depthClearValue ;GPULoadOp depthLoadOp ;GPUStoreOp depthStoreOp ;boolean depthReadOnly =false ;GPUStencilValue stencilClearValue = 0;GPULoadOp stencilLoadOp ;GPUStoreOp stencilStoreOp ;boolean stencilReadOnly =false ; };
view
, 타입(GPUTexture 또는 GPUTextureView)
-
이 깊이/스텐실 어태치먼트에서 출력 및 읽기할 텍스처 서브리소스를 설명합니다. 서브리소스는 get as texture view(
view
) 호출로 결정됩니다. depthClearValue
, 타입 float-
렌더 패스를 실행하기 전에
view
의 depth 컴포넌트 값을 초기화할 값입니다.depthLoadOp
값이"clear"
가 아니면 무시됩니다. 반드시 0.0 이상 1.0 이하이어야 합니다. depthLoadOp
, 타입 GPULoadOp-
렌더 패스를 실행하기 전에
view
의 depth 컴포넌트에 수행할 load 연산을 지정합니다.참고: 초기화(clear)를 우선 추천합니다. 자세한 내용은
"clear"
참고. depthStoreOp
, 타입 GPUStoreOp-
렌더 패스 실행 후
view
의 depth 컴포넌트에 수행할 store 연산을 지정합니다. depthReadOnly
, 타입 boolean, 기본값false
-
view
의 depth 컴포넌트가 읽기 전용임을 나타냅니다. stencilClearValue
, 타입 GPUStencilValue, 기본값0
-
렌더 패스를 실행하기 전에
view
의 stencil 컴포넌트 값을 초기화할 값입니다.stencilLoadOp
값이"clear"
가 아니면 무시됩니다.값은 view의 stencil aspect 타입에 맞게 변환되며, view의 텍셀의 stencil aspect 비트 수만큼 LSB를 사용합니다.
stencilLoadOp
, 타입 GPULoadOp-
렌더 패스를 실행하기 전에
view
의 stencil 컴포넌트에 수행할 load 연산을 지정합니다.참고: 초기화(clear)를 우선 추천합니다. 자세한 내용은
"clear"
참고. stencilStoreOp
, 타입 GPUStoreOp-
렌더 패스 실행 후
view
의 stencil 컴포넌트에 수행할 store 연산을 지정합니다. stencilReadOnly
, 타입 boolean, 기본값false
-
view
의 stencil 컴포넌트가 읽기 전용임을 나타냅니다.
GPURenderPassDepthStencilAttachment
this가 주어진 경우, 다음과 같은 검증 규칙이 적용됩니다:
-
this.
view
값이 depth-or-stencil 포맷이어야 합니다. -
this.
view
값이 렌더링 가능한 텍스처 뷰여야 합니다. -
format을 this.
view
.[[descriptor]]
.format
으로 설정합니다. -
depthLoadOp
값이"clear"
인 경우,depthClearValue
값이 제공되어야 하며 0.0~1.0 범위 내여야 합니다. -
format에 depth aspect가 있고
depthReadOnly
값이false
인 경우:-
depthLoadOp
값이 제공되어야 함. -
depthStoreOp
값이 제공되어야 함.
그 외의 경우:
-
-
format에 stencil aspect가 있고
stencilReadOnly
값이false
인 경우:-
stencilLoadOp
값이 제공되어야 함.
그 외의 경우:
-
17.1.1.3. 로드 & 스토어 연산
enum {
GPULoadOp "load" ,"clear" , };
"load"
-
이 어태치먼트의 기존 값을 렌더 패스로 불러옵니다.
"clear"
-
이 어태치먼트의 초기화(clear) 값을 렌더 패스로 불러옵니다.
참고: 일부 GPU 하드웨어(주로 모바일)에서는
"clear"
가 훨씬 더 저렴합니다. 주 메모리에서 타일-로컬 메모리로 데이터를 불러오는 과정을 건너뛰기 때문입니다. 다른 GPU 하드웨어에서는 큰 차이가 없습니다. 따라서 초기 값이 중요하지 않을 때(예: 렌더 타겟이 스카이박스로 초기화될 경우)"clear"
를"load"
대신 사용하는 것이 권장됩니다.
enum {
GPUStoreOp "store" ,"discard" , };
"store"
-
렌더 패스의 결과값을 어태치먼트에 저장합니다.
"discard"
-
렌더 패스의 결과값을 어태치먼트에서 폐기(discard)합니다.
참고: 폐기된 어태치먼트는 0으로 초기화된 것처럼 동작하지만, 구현체는 패스 끝에 명시적 초기화를 수행할 필요가 없습니다. 패스 끝에 명시적으로 clear하지 않는 구현체는 해당 어태치먼트 내용을 읽기(샘플링, 복사, 이후 렌더 패스에서
"load"
로 attach, 캔버스 디스플레이/리드백(get a copy of the image contents of a context 등) 하기 전에 지연(lazy) 초기화를 해야 합니다.
17.1.1.4. 렌더 패스 레이아웃
GPURenderPassLayout
는 GPURenderBundle
의
렌더 타겟 레이아웃을 선언합니다.
내부적으로 GPURenderPassEncoder
레이아웃 및
GPURenderPipeline
레이아웃에도 사용됩니다.
렌더 패스, 렌더 번들, 렌더 파이프라인 간 호환성을 결정합니다.
dictionary :
GPURenderPassLayout GPUObjectDescriptorBase {required sequence <GPUTextureFormat ?>colorFormats ;GPUTextureFormat depthStencilFormat ;GPUSize32 sampleCount = 1; };
colorFormats
, 타입sequence<GPUTextureFormat?>
-
이 패스 또는 번들의 컬러 어태치먼트
GPUTextureFormat
리스트입니다. depthStencilFormat
, 타입 GPUTextureFormat-
이 패스 또는 번들의 깊이/스텐실 어태치먼트
GPUTextureFormat
입니다. sampleCount
, 타입 GPUSize32, 기본값1
-
이 패스 또는 번들 어태치먼트의 픽셀당 샘플 수입니다.
GPURenderPassLayout
값이 동등(equal)하려면:
-
depthStencilFormat
과sampleCount
값이 같아야 하며, -
colorFormats
값이 뒤쪽의null
은 무시하고 비교했을 때 같아야 합니다.
인자:
-
GPURenderPassDescriptor
descriptor
반환값: GPURenderPassLayout
디바이스 타임라인 단계:
-
layout을 새
GPURenderPassLayout
객체로 한다. -
descriptor.
colorAttachments
의 각 colorAttachment에 대해:-
colorAttachment가
null
이 아니면:-
layout.
sampleCount
값을 colorAttachment.view
.[[texture]]
.sampleCount
로 설정. -
colorAttachment.
view
.[[descriptor]]
.format
을 layout.colorFormats
에 추가.
-
-
그 외의 경우:
-
null
을 layout.colorFormats
에 추가.
-
-
-
depthStencilAttachment를 descriptor.
depthStencilAttachment
로 한다. -
depthStencilAttachment가
null
이 아니면:-
view를 depthStencilAttachment.
view
로 한다. -
layout.
sampleCount
값을 view.[[texture]]
.sampleCount
로 설정. -
layout.
depthStencilFormat
값을 view.[[descriptor]]
.format
으로 설정.
-
-
layout을 반환합니다.
인자:
-
GPURenderPipelineDescriptor
descriptor
반환값: GPURenderPassLayout
디바이스 타임라인 단계:
-
layout을 새
GPURenderPassLayout
객체로 설정합니다. -
layout.
sampleCount
값을 descriptor.multisample
.count
으로 설정합니다. -
descriptor.
depthStencil
값이 제공된 경우:-
layout.
depthStencilFormat
값을 descriptor.depthStencil
.format
으로 설정합니다.
-
-
descriptor.
fragment
값이 제공된 경우:-
descriptor.
fragment
.targets
의 각 colorTarget에 대해:-
colorTarget이
null
이 아니면 colorTarget.format
값을 layout.colorFormats
에 추가하고,null
이면null
을 추가합니다.
-
-
-
layout을 반환합니다.
17.1.2. 최종화
사용자가 해당 패스에 대한 커맨드 기록을 마친 뒤 end()
를
호출하여 렌더 패스 인코더를 종료할 수 있습니다.
end()
가
호출된 후에는 해당 렌더 패스 인코더를 더 이상 사용할 수 없습니다.
end()
-
렌더 패스 커맨드 시퀀스 기록을 완료합니다.
호출 대상:GPURenderPassEncoder
this.반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
parentEncoder를 this.
[[command_encoder]]
로 설정. -
아래 요구사항 중 하나라도 만족하지 않으면, 유효성 오류 생성 후 반환.
-
아래 요구사항 중 하나라도 만족하지 않으면, parentEncoder를 무효화하고 반환.
-
this가 valid 상태여야 함.
-
this.
[[usage scope]]
값이 usage scope 유효성 검증을 만족해야 함. -
this.
[[debug_group_stack]]
값이 비어 있어야 함. -
this.
[[occlusion_query_active]]
값이false
여야 함. -
this.
[[drawCount]]
값이 this.[[maxDrawCount]]
이하이어야 함.
-
-
Extend parentEncoder.
[[commands]]
값에 this.[[commands]]
를 확장. -
this.
[[endTimestampWrite]]
값이null
이 아니면:-
Extend parentEncoder.
[[commands]]
값에 this.[[endTimestampWrite]]
를 확장.
-
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
non-
null
renderState.[[colorAttachments]]
멤버의 각 colorAttachment에 대해:-
colorView를 colorAttachment.
view
로 한다. -
colorView.
[[descriptor]]
.dimension
값에 따라:"3d"
-
colorSubregion을 colorAttachment.
depthSlice
of colorView로 한다. - 그 외의 경우
-
colorSubregion을 colorView로 한다.
-
colorAttachment.
resolveTarget
값이null
이 아니면:-
모든 텍셀의 멀티 샘플을 resolve하여 colorSubregion의 단일 샘플로 만들고, colorAttachment.
resolveTarget
에 복사합니다.
-
-
colorAttachment.
storeOp
값에 따라:
-
-
depthStencilAttachment를 renderState.
[[depthStencilAttachment]]
로 한다. -
depthStencilAttachment가
null
이 아니면:-
depthStencilAttachment.
depthStoreOp
값에 따라: -
depthStencilAttachment.
stencilStoreOp
값에 따라:
-
-
renderState를
null
로 설정합니다.
참고: 폐기(discard)된 어태치먼트는 0으로 초기화된 것처럼 동작하지만, 구현체는 패스 끝에 명시적 초기화를 할 필요는 없습니다. 추가 내용은
"discard"
참고.참고: 읽기 전용 depth-stencil 어태치먼트는 암묵적으로
"store"
연산을 사용하는 것으로 간주할 수 있지만, 패스 실행 중 내용이 변경되지 않으므로 구현체는 업데이트할 필요가 없습니다. 읽기 전용 어태치먼트에 store op가 제공되면 안 된다는 검증은 GPURenderPassDepthStencilAttachment 유효한 사용에서 수행합니다. -
17.2. GPURenderCommandsMixin
GPURenderCommandsMixin
은 GPURenderPassEncoder
와 GPURenderBundleEncoder
에 공통인 렌더링 명령을 정의합니다.
interface mixin GPURenderCommandsMixin {undefined setPipeline (GPURenderPipeline pipeline );undefined setIndexBuffer (GPUBuffer buffer ,GPUIndexFormat indexFormat ,optional GPUSize64 offset = 0,optional GPUSize64 size );undefined setVertexBuffer (GPUIndex32 slot ,GPUBuffer ?buffer ,optional GPUSize64 offset = 0,optional GPUSize64 size );undefined draw (GPUSize32 vertexCount ,optional GPUSize32 instanceCount = 1,optional GPUSize32 firstVertex = 0,optional GPUSize32 firstInstance = 0);undefined drawIndexed (GPUSize32 indexCount ,optional GPUSize32 instanceCount = 1,optional GPUSize32 firstIndex = 0,optional GPUSignedOffset32 baseVertex = 0,optional GPUSize32 firstInstance = 0);undefined drawIndirect (GPUBuffer indirectBuffer ,GPUSize64 indirectOffset );undefined drawIndexedIndirect (GPUBuffer indirectBuffer ,GPUSize64 indirectOffset ); };
GPURenderCommandsMixin
은 동일 객체에
GPUObjectBase
,
GPUCommandsMixin
,
GPUBindingCommandsMixin
멤버가 존재함을 전제로 합니다.
반드시 위 믹스인을 포함한 인터페이스에서만 사용되어야 합니다.
GPURenderCommandsMixin
는 다음 디바이스
타임라인 속성을 가집니다:
[[layout]]
, 타입GPURenderPassLayout
, 읽기 전용-
렌더 패스의 레이아웃입니다.
[[depthReadOnly]]
, 타입boolean
, 읽기 전용-
true
면 depth 컴포넌트가 변경되지 않음을 나타냅니다. [[stencilReadOnly]]
, 타입boolean
, 읽기 전용-
true
면 stencil 컴포넌트가 변경되지 않음을 나타냅니다. [[usage scope]]
, 타입 usage scope, 초기값은 비어 있음-
이 렌더 패스 또는 번들의 usage scope입니다.
[[pipeline]]
, 타입GPURenderPipeline
, 초기값null
-
현재
GPURenderPipeline
입니다. [[index_buffer]]
, 타입GPUBuffer
, 초기값null
-
현재 인덱스 데이터를 읽는 버퍼입니다.
[[index_format]]
, 타입GPUIndexFormat
-
현재
[[index_buffer]]
의 인덱스 데이터 포맷입니다. [[index_buffer_offset]]
, 타입GPUSize64
-
현재 설정된
[[index_buffer]]
의 바이트 오프셋입니다. [[index_buffer_size]]
, 타입GPUSize64
-
현재 설정된
[[index_buffer]]
의 바이트 크기, 초기값은0
입니다. [[vertex_buffers]]
, 타입 ordered map<slot,GPUBuffer
>, 초기값은 비어 있음-
각 슬롯별로 현재 설정된 버텍스 데이터 읽기용
GPUBuffer
들입니다. [[vertex_buffer_sizes]]
, 타입 ordered map<slot,GPUSize64
>, 초기값은 비어 있음-
각 슬롯별로 현재 설정된
GPUBuffer
의 바이트 크기입니다. [[drawCount]]
, 타입GPUSize64
-
이 인코더에 기록된 draw 명령 개수입니다.
GPURenderCommandsMixin
encoder에 실행하여
GPU Command
command를 RenderState
renderState와 함께 실행할 때, 다음 디바이스 타임라인 단계를 수행합니다:
-
Append command를 encoder.
[[commands]]
에 추가합니다. -
command가
GPUCommandBuffer
commandBuffer의 일부로 실행되는 경우:-
commandBuffer.
[[renderState]]
를 renderState로 하여 command 단계를 실행합니다.
-
17.2.1. 드로잉
setPipeline(pipeline)
-
현재
GPURenderPipeline
을 설정합니다.호출 대상:GPURenderCommandsMixin
this.인자:
GPURenderCommandsMixin.setPipeline(pipeline) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 pipeline
GPURenderPipeline
✘ ✘ 이후 드로잉 명령에 사용할 렌더 파이프라인. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
pipelineTargetsLayout을 파이프라인에서 렌더 타겟 레이아웃 도출(pipeline.
[[descriptor]]
)로 설정. -
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
pipeline이 this와 함께 사용 가능한 상태여야 함.
-
this.
[[layout]]
값이 pipelineTargetsLayout과 동등해야 함. -
pipeline.
[[writesDepth]]
가 true인 경우, this.[[depthReadOnly]]
값이 false여야 함. -
pipeline.
[[writesStencil]]
가 true인 경우, this.[[stencilReadOnly]]
값이 false여야 함.
-
-
this.
[[pipeline]]
값을 pipeline으로 설정.
-
setIndexBuffer(buffer, indexFormat, offset, size)
-
현재 인덱스 버퍼를 설정합니다.
호출 대상:GPURenderCommandsMixin
this.인자:
GPURenderCommandsMixin.setIndexBuffer(buffer, indexFormat, offset, size) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 buffer
GPUBuffer
✘ ✘ 이후 드로잉 명령에서 사용할 인덱스 데이터가 들어있는 버퍼. indexFormat
GPUIndexFormat
✘ ✘ buffer 내부 인덱스 데이터의 포맷. offset
GPUSize64
✘ ✔ buffer에서 인덱스 데이터가 시작하는 바이트 오프셋. 기본값은 0
.size
GPUSize64
✘ ✔ buffer 내부 인덱스 데이터의 바이트 크기. 기본값은 버퍼 크기에서 오프셋을 뺀 값. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
size가 누락된 경우, size를 max(0, buffer.
size
- offset)으로 설정. -
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
buffer가 this와 함께 사용 가능한 상태여야 함.
-
offset이 indexFormat의 바이트 크기 배수여야 함.
-
offset + size ≤ buffer.
size
여야 함.
-
-
Add buffer를
[[usage scope]]
에 input 용도로 추가. -
this.
[[index_buffer]]
값을 buffer로 설정. -
this.
[[index_format]]
값을 indexFormat으로 설정. -
this.
[[index_buffer_offset]]
값을 offset으로 설정. -
this.
[[index_buffer_size]]
값을 size로 설정.
-
setVertexBuffer(slot, buffer, offset, size)
-
지정한 슬롯에 현재 버텍스 버퍼를 설정합니다.
호출 대상:GPURenderCommandsMixin
this.인자:
GPURenderCommandsMixin.setVertexBuffer(slot, buffer, offset, size) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 slot
GPUIndex32
✘ ✘ 버텍스 버퍼를 설정할 버텍스 버퍼 슬롯. buffer
GPUBuffer?
✔ ✘ 이후 드로잉 명령에 사용할 버텍스 데이터가 들어 있는 버퍼. offset
GPUSize64
✘ ✔ buffer에서 버텍스 데이터가 시작하는 바이트 오프셋. 기본값 0
.size
GPUSize64
✘ ✔ buffer에서 버텍스 데이터의 바이트 크기. 기본값은 버퍼 크기에서 오프셋을 뺀 값. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인 단계에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
bufferSize를 buffer가
null
이면 0, 아니면 buffer.size
로 설정. -
size가 누락된 경우, size를 max(0, bufferSize - offset)으로 설정.
-
아래 요구사항 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
slot 값이 this.
[[device]]
.[[limits]]
.maxVertexBuffers
미만이어야 함. -
offset 값이 4의 배수이어야 함.
-
offset + size 값이 bufferSize 이하이어야 함.
-
-
buffer가
null
인 경우:-
Remove this.
[[vertex_buffers]]
[slot]. -
Remove this.
[[vertex_buffer_sizes]]
[slot].
그 외의 경우:
-
아래 요구사항 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
buffer가 this와 함께 사용 가능한 상태여야 함.
-
-
Add buffer 를
[[usage scope]]
에 input 용도로 추가합니다. -
this.
[[vertex_buffers]]
[slot] 값을 buffer로 설정합니다. -
this.
[[vertex_buffer_sizes]]
[slot] 값을 size로 설정합니다.
-
-
draw(vertexCount, instanceCount, firstVertex, firstInstance)
-
프리미티브를 드로우합니다. 자세한 명세는 § 23.2 렌더링을 참고하세요.
호출 대상:GPURenderCommandsMixin
this.인자:
GPURenderCommandsMixin.draw(vertexCount, instanceCount, firstVertex, firstInstance) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 vertexCount
GPUSize32
✘ ✘ 드로우할 버텍스 개수. instanceCount
GPUSize32
✘ ✔ 드로우할 인스턴스 개수. firstVertex
GPUSize32
✘ ✔ 버텍스 버퍼에서 시작할 오프셋(버텍스 단위). firstInstance
GPUSize32
✘ ✔ 드로우할 첫 번째 인스턴스. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인 단계에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 단계의 모든 요구사항을 만족해야 합니다. 하나라도 만족하지 않으면 this를 무효화하고 반환.
-
현재 valid to draw 상태여야 합니다.
-
buffers를 this.
[[pipeline]]
.[[descriptor]]
.vertex
.buffers
로 설정. -
각
GPUIndex32
slot에 대해 0부터 buffers.size (불포함)까지:-
buffers[slot] 값이
null
이면 continue. -
bufferSize를 this.
[[vertex_buffer_sizes]]
[slot]로 설정. -
stride를 buffers[slot].
arrayStride
로 설정. -
attributes를 buffers[slot].
attributes
로 설정. -
lastStride를 attributes 각 attribute에 대해 (attribute.
offset
+ byteSize(attribute.format
))의 최댓값으로, attributes가 비어 있으면 0으로 설정. -
strideCount를 buffers[slot].
stepMode
에 따라 계산:"vertex"
-
firstVertex + vertexCount
"instance"
-
firstInstance + instanceCount
-
strideCount ≠
0
이면:-
(strideCount −
1
) × stride + lastStride 값이 bufferSize 이하이어야 함.
-
-
-
-
this.
[[drawCount]]
값을 1 증가시킵니다. -
bindingState를 this의 현재 상태 스냅샷으로 설정합니다.
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
프리미티브를 vertexCount개의 버텍스(firstVertex부터 시작), instanceCount개의 인스턴스(firstInstance부터 시작)로 드로우하고, bindingState 및 renderState의 상태를 사용합니다.
-
drawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance)
-
인덱스드 프리미티브를 드로우합니다. 자세한 명세는 § 23.2 렌더링을 참고하세요.
호출 대상:GPURenderCommandsMixin
this.인자:
GPURenderCommandsMixin.drawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 indexCount
GPUSize32
✘ ✘ 드로우할 인덱스 개수. instanceCount
GPUSize32
✘ ✔ 드로우할 인스턴스 개수. firstIndex
GPUSize32
✘ ✔ 인덱스 버퍼에서 시작할 오프셋(인덱스 단위). baseVertex
GPUSignedOffset32
✘ ✔ 각 인덱스 값에 더하여 버텍스 버퍼에 접근. firstInstance
GPUSize32
✘ ✔ 드로우할 첫 번째 인스턴스. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인 단계에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
valid to draw indexed 상태여야 함.
-
firstIndex + indexCount 값이 this.
[[index_buffer_size]]
÷ this.[[index_format]]
의 바이트 크기 이하이어야 함; -
buffers를 this.
[[pipeline]]
.[[descriptor]]
.vertex
.buffers
로 설정. -
각
GPUIndex32
slot에 대해 0부터 buffers.size (불포함)까지:-
buffers[slot]이
null
이면 continue. -
bufferSize를 this.
[[vertex_buffer_sizes]]
[slot]로 설정. -
stride를 buffers[slot].
arrayStride
로 설정. -
lastStride를 buffers[slot].
attributes
각 attribute에 대해 (attribute.offset
+ byteSize(attribute.format
))의 최댓값으로 설정. -
strideCount를 firstInstance + instanceCount로 설정.
-
buffers[slot].
stepMode
값이"instance"
이고 strideCount ≠0
이면:-
(strideCount −
1
) × stride + lastStride 값이 bufferSize 이하이어야 함.
-
-
-
-
this.
[[drawCount]]
값을 1 증가시킵니다. -
bindingState를 this의 현재 상태 스냅샷으로 설정합니다.
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
프리미티브를 indexCount개의 인덱스드 버텍스(firstIndex부터 시작, baseVertex를 기준), instanceCount개의 인스턴스(firstInstance부터 시작)로 드로우하고, bindingState 및 renderState의 상태를 사용합니다.
참고: WebGPU 애플리케이션은 항상
GPUVertexStepMode
"vertex"
를 가진 바운드 버텍스 버퍼의 범위를 벗어난 인덱스 데이터를 사용해서는 안 됩니다. WebGPU 구현체마다 처리 방식이 다르므로 다양한 동작이 허용됩니다. 전체 드로우 콜이 무시(discard)되거나, 범위를 벗어난 속성 접근은 WGSL의 invalid memory reference로 처리됩니다. -
drawIndirect(indirectBuffer, indirectOffset)
-
GPUBuffer
에서 읽어온 파라미터로 프리미티브를 드로우합니다. 자세한 명세는 § 23.2 렌더링을 참고하세요.버퍼에 인코딩된 간접 드로우 파라미터는 32비트 부호없는 정수 4개(총 16바이트)를 순서대로 꽉 채워야 하며,
draw()
의 인자와 같은 순서로 배치되어야 합니다. 예시:let drawIndirectParameters= new Uint32Array( 4 ); drawIndirectParameters[ 0 ] = vertexCount; drawIndirectParameters[ 1 ] = instanceCount; drawIndirectParameters[ 2 ] = firstVertex; drawIndirectParameters[ 3 ] = firstInstance; firstInstance
에 해당하는 값은"indirect-first-instance"
feature가 활성화되어 있지 않으면 반드시 0이어야 합니다. 만약"indirect-first-instance"
feature가 활성화되어 있지 않고firstInstance
가 0이 아니라면,drawIndirect()
호출은 아무 동작도 하지 않습니다(no-op).호출 대상:GPURenderCommandsMixin
this.인자:
GPURenderCommandsMixin.drawIndirect(indirectBuffer, indirectOffset) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 indirectBuffer
GPUBuffer
✘ ✘ 간접 드로우 파라미터가 들어있는 버퍼. indirectOffset
GPUSize64
✘ ✘ indirectBuffer에서 드로잉 데이터가 시작하는 바이트 오프셋. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
현재 valid to draw 상태여야 함.
-
indirectBuffer가 this와 함께 사용 가능한 상태여야 함.
-
indirectOffset + sizeof(간접 드로우 파라미터) 값이 indirectBuffer.
size
이하이어야 함. -
indirectOffset 값이 4의 배수여야 함.
-
-
Add indirectBuffer 를
[[usage scope]]
에 input 용도로 추가합니다. -
this.
[[drawCount]]
값을 1 증가시킵니다. -
bindingState를 this의 현재 상태 스냅샷으로 설정합니다.
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
vertexCount를 indirectBuffer에서 indirectOffset 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
instanceCount를 indirectBuffer에서 (indirectOffset + 4) 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
firstVertex를 indirectBuffer에서 (indirectOffset + 8) 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
firstInstance를 indirectBuffer에서 (indirectOffset + 12) 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
프리미티브를 vertexCount개의 버텍스(firstVertex부터 시작), instanceCount개의 인스턴스(firstInstance부터 시작)로 드로우하고, bindingState 및 renderState의 상태를 사용합니다.
-
drawIndexedIndirect(indirectBuffer, indirectOffset)
-
GPUBuffer
에서 읽어온 파라미터로 인덱스드 프리미티브를 드로우합니다. 자세한 명세는 § 23.2 렌더링을 참고하세요.버퍼에 인코딩된 간접 drawIndexed 파라미터는 5개의 32비트 값(총 20바이트)을 순서대로 꽉 채워야 하며,
drawIndexed()
의 인자와 같은 순서로 배치되어야 합니다.baseVertex
에 해당하는 값만 32비트 부호있는 정수이며, 나머지는 모두 부호없는 32비트 정수입니다. 예시:let drawIndexedIndirectParameters= new Uint32Array( 5 ); let drawIndexedIndirectParametersSigned= new Int32Array( drawIndexedIndirectParameters. buffer); drawIndexedIndirectParameters[ 0 ] = indexCount; drawIndexedIndirectParameters[ 1 ] = instanceCount; drawIndexedIndirectParameters[ 2 ] = firstIndex; // baseVertex는 signed 값입니다. drawIndexedIndirectParametersSigned[ 3 ] = baseVertex; drawIndexedIndirectParameters[ 4 ] = firstInstance; firstInstance
에 해당하는 값은"indirect-first-instance"
feature가 활성화되어 있지 않으면 반드시 0이어야 합니다. 만약"indirect-first-instance"
feature가 활성화되어 있지 않고firstInstance
가 0이 아니라면,drawIndexedIndirect()
호출은 아무 동작도 하지 않습니다(no-op).호출 대상:GPURenderCommandsMixin
this.인자:
GPURenderCommandsMixin.drawIndexedIndirect(indirectBuffer, indirectOffset) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 indirectBuffer
GPUBuffer
✘ ✘ 간접 drawIndexed 파라미터가 들어있는 버퍼. indirectOffset
GPUSize64
✘ ✘ indirectBuffer에서 드로잉 데이터가 시작하는 바이트 오프셋. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
현재 valid to draw indexed 상태여야 함.
-
indirectBuffer가 this와 함께 사용 가능한 상태여야 함.
-
indirectOffset + sizeof(간접 drawIndexed 파라미터) 값이 indirectBuffer.
size
이하이어야 함. -
indirectOffset 값이 4의 배수여야 함.
-
-
Add indirectBuffer 를
[[usage scope]]
에 input 용도로 추가합니다. -
this.
[[drawCount]]
값을 1 증가시킵니다. -
bindingState를 this의 현재 상태 스냅샷으로 설정합니다.
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
indexCount를 indirectBuffer에서 indirectOffset 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
instanceCount를 indirectBuffer에서 (indirectOffset + 4) 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
firstIndex를 indirectBuffer에서 (indirectOffset + 8) 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
baseVertex를 indirectBuffer에서 (indirectOffset + 12) 바이트 위치에서 부호있는 32비트 정수로 읽어옴.
-
firstInstance를 indirectBuffer에서 (indirectOffset + 16) 바이트 위치에서 부호없는 32비트 정수로 읽어옴.
-
프리미티브를 indexCount개의 인덱스드 버텍스(firstIndex부터 시작, baseVertex 기준), instanceCount개의 인스턴스(firstInstance부터 시작)로 드로우하고, bindingState 및 renderState의 상태를 사용합니다.
-
GPURenderCommandsMixin
encoder로 드로우가 유효한지(valid to draw) 판단하려면,
다음 디바이스 타임라인 단계를 실행합니다:
-
아래 조건 중 하나라도 만족하지 않으면
false
를 반환합니다:-
Validate encoder bind groups(encoder, encoder.
[[pipeline]]
) 값이true
여야 합니다. -
pipelineDescriptor를 encoder.
[[pipeline]]
.[[descriptor]]
로 설정합니다. -
각
GPUIndex32
slot에 대해 0부터 pipelineDescriptor.vertex
.buffers
.size까지:-
pipelineDescriptor.
vertex
.buffers
[slot] 값이null
이 아니면, encoder.[[vertex_buffers]]
에 slot이 존재해야 합니다.
-
-
maxBindGroupsPlusVertexBuffers
검증:-
bindGroupSpaceUsed를 (encoder.
[[bind_groups]]
의 최대 key) + 1로 설정. -
vertexBufferSpaceUsed를 (encoder.
[[vertex_buffers]]
의 최대 key) + 1로 설정. -
bindGroupSpaceUsed + vertexBufferSpaceUsed 값이 encoder.
[[device]]
.[[limits]]
.maxBindGroupsPlusVertexBuffers
이하이어야 함.
-
-
-
그 외의 경우
true
를 반환합니다.
GPURenderCommandsMixin
encoder로 인덱스드 드로우가 유효한지(valid to draw indexed) 판단하려면,
다음 디바이스 타임라인 단계를 실행합니다:
-
아래 조건 중 하나라도 만족하지 않으면
false
를 반환합니다:-
valid to draw 상태여야 합니다.
-
encoder.
[[index_buffer]]
값이null
이 아니어야 합니다. -
topology를 encoder.
[[pipeline]]
.[[descriptor]]
.primitive
.topology
로 설정합니다. -
topology 값이
"line-strip"
또는"triangle-strip"
이면:-
encoder.
[[index_format]]
값이 encoder.[[pipeline]]
.[[descriptor]]
.primitive
.stripIndexFormat
과 같아야 함.
-
-
-
그 외의 경우
true
를 반환합니다.
17.2.2. 래스터화 상태
GPURenderPassEncoder
에는
이 인코더에서 사용되는 어태치먼트에 드로우 명령이 어떻게 래스터화(rasterize)되는지에 영향을 주는 여러 메서드가 있습니다.
setViewport(x, y, width, height, minDepth, maxDepth)
-
래스터화 단계에서 정규화된 장치 좌표에서 뷰포트 좌표로 선형 변환하는 데 사용되는 뷰포트를 설정합니다.
호출 대상:GPURenderPassEncoder
this.인자:
GPURenderPassEncoder.setViewport(x, y, width, height, minDepth, maxDepth) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 x
float
✘ ✘ 뷰포트의 최소 X값(픽셀 단위). y
float
✘ ✘ 뷰포트의 최소 Y값(픽셀 단위). width
float
✘ ✘ 뷰포트의 너비(픽셀 단위). height
float
✘ ✘ 뷰포트의 높이(픽셀 단위). minDepth
float
✘ ✘ 뷰포트의 최소 깊이값. maxDepth
float
✘ ✘ 뷰포트의 최대 깊이값. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
maxViewportRange를 this.
limits
.maxTextureDimension2D
×2
로 설정. -
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
x ≥ -maxViewportRange
-
y ≥ -maxViewportRange
-
0
≤ width ≤ this.limits
.maxTextureDimension2D
-
0
≤ height ≤ this.limits
.maxTextureDimension2D
-
x + width ≤ maxViewportRange −
1
-
y + height ≤ maxViewportRange −
1
-
0.0
≤ minDepth ≤1.0
-
0.0
≤ maxDepth ≤1.0
-
minDepth ≤ maxDepth
-
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
x, y, width, height 값을 정수 반올림 이상의 정밀도로 일관되게 반올림합니다.
-
renderState.
[[viewport]]
값을 x, y, width, height, minDepth, maxDepth 범위로 설정합니다.
-
setScissorRect(x, y, width, height)
-
래스터화 단계에서 사용할 시저(rect) 사각형을 설정합니다. 뷰포트 좌표로 변환된 후, 시저 사각형 밖에 위치한 프래그먼트는 폐기됩니다.
호출 대상:GPURenderPassEncoder
this.인자:
GPURenderPassEncoder.setScissorRect(x, y, width, height) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 x
GPUIntegerCoordinate
✘ ✘ 시저 사각형의 최소 X값(픽셀 단위). y
GPUIntegerCoordinate
✘ ✘ 시저 사각형의 최소 Y값(픽셀 단위). width
GPUIntegerCoordinate
✘ ✘ 시저 사각형의 너비(픽셀 단위). height
GPUIntegerCoordinate
✘ ✘ 시저 사각형의 높이(픽셀 단위). 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
x+width 값이 this.
[[attachment_size]]
.width 이하이어야 함. -
y+height 값이 this.
[[attachment_size]]
.height 이하이어야 함.
-
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
renderState.
[[scissorRect]]
값을 x, y, width, height 범위로 설정합니다.
-
setBlendConstant(color)
-
"constant"
및"one-minus-constant"
GPUBlendFactor
에서 사용할 블렌드 상수 색상 및 알파 값을 설정합니다.호출 대상:GPURenderPassEncoder
this.인자:
GPURenderPassEncoder.setBlendConstant(color) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 color
GPUColor
✘ ✘ 블렌딩에 사용할 색상 값. 반환값:
undefined
컨텐트 타임라인 단계:
-
? GPUColor shape 검증(color).
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
renderState.
[[blendConstant]]
값을 color로 설정합니다.
-
setStencilReference(reference)
-
[[stencilReference]]
값을"replace"
GPUStencilOperation
과 함께 사용하는 스텐실 테스트에 사용할 값을 설정합니다.호출 대상:GPURenderPassEncoder
this.인자:
GPURenderPassEncoder.setStencilReference(reference) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 reference
GPUStencilValue
✘ ✘ 새로운 스텐실 참조값. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
renderState.
[[stencilReference]]
값을 reference로 설정합니다.
-
17.2.3. 쿼리
beginOcclusionQuery(queryIndex)
-
호출 대상:
GPURenderPassEncoder
this.인자:
GPURenderPassEncoder.beginOcclusionQuery(queryIndex) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 queryIndex
GPUSize32
✘ ✘ 쿼리 세트 내 쿼리의 인덱스. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
this.
[[occlusion_query_set]]
값이null
이 아니어야 함. -
queryIndex 값이 this.
[[occlusion_query_set]]
.count
미만이어야 함. -
같은 queryIndex에 대해 이번 패스에서 이미 기록된 적이 없어야 함.
-
this.
[[occlusion_query_active]]
값이false
여야 함.
-
-
this.
[[occlusion_query_active]]
값을true
로 설정. -
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
renderState.
[[occlusionQueryIndex]]
값을 queryIndex로 설정합니다.
-
endOcclusionQuery()
-
호출 대상:
GPURenderPassEncoder
this.반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
this.
[[occlusion_query_active]]
값이true
여야 함.
-
-
this.
[[occlusion_query_active]]
값을false
로 설정. -
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 이후 단계를 실행.
큐 타임라인 단계:-
passingFragments를 해당
beginOcclusionQuery()
명령 실행 이후 모든 프래그먼트 샘플이 per-fragment 테스트를 통과했다면 0이 아닌 값으로, 그렇지 않으면 0으로 설정합니다.참고: 드로우 호출이 없으면 passingFragments 값은 0입니다.
-
passingFragments를 this.
[[occlusion_query_set]]
의 renderState.[[occlusionQueryIndex]]
인덱스에 기록합니다.
-
17.2.4. 번들
executeBundles(bundles)
-
해당
GPURenderBundle
에 미리 기록된 명령들을 이 렌더 패스의 일부로 실행합니다.GPURenderBundle
이 실행될 때, 렌더 패스의 파이프라인, 바인드 그룹, 버텍스/인덱스 버퍼 상태를 상속하지 않습니다.GPURenderBundle
실행 후 렌더 패스의 파이프라인, 바인드 그룹, 버텍스/인덱스 버퍼 상태는 (초기 빈 값으로) 클리어됩니다.참고: 상태는 이전 상태로 복원되지 않고 클리어됩니다. 0개의
GPURenderBundles
를 실행해도 클리어가 발생합니다.호출 대상:GPURenderPassEncoder
this.인자:
GPURenderPassEncoder.executeBundles(bundles) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 bundles
sequence<GPURenderBundle>
✘ ✘ 실행할 렌더 번들 리스트. 반환값:
undefined
컨텐트 타임라인 단계:
-
this.
[[device]]
의 디바이스 타임라인에서 이후 단계를 실행합니다.
디바이스 타임라인 단계:-
인코더 상태 검증을 this에 대해 실행. 결과가 false면 반환.
-
아래 조건 중 하나라도 만족하지 않으면, this를 무효화하고 반환.
-
각 bundle에 대해:
-
bundle이 this와 함께 사용 가능한 상태여야 함.
-
this.
[[layout]]
값이 bundle.[[layout]]
과 같아야 함. -
this.
[[depthReadOnly]]
값이 true이면 bundle.[[depthReadOnly]]
값도 true이어야 함. -
this.
[[stencilReadOnly]]
값이 true이면 bundle.[[stencilReadOnly]]
값도 true이어야 함.
-
-
-
각 bundle에 대해:
-
this.
[[drawCount]]
값을 bundle.[[drawCount]]
만큼 증가시킵니다. -
Merge bundle.
[[usage scope]]
를 this.[[usage scope]]
에 병합합니다. -
렌더 커맨드 enqueue를 this에 실행하여, 실행 시 큐 타임라인에서 renderState를 사용해 다음 단계를 실행:
큐 타임라인 단계:-
bundle.
[[command_list]]
의 각 명령을 renderState와 함께 실행합니다.참고: renderState는 번들을 실행해도 변경되지 않습니다. 바인딩 상태는 번들 인코딩 시 캡처됐으므로 번들 실행 시 사용되지 않습니다.
-
-
-
렌더 패스 바인딩 상태 초기화를 this에 실행합니다.
-
GPURenderPassEncoder
encoder에 실행하려면
다음 디바이스 타임라인 단계를 실행합니다:
-
Clear encoder.
[[bind_groups]]
. -
encoder.
[[pipeline]]
값을null
로 설정합니다. -
encoder.
[[index_buffer]]
값을null
로 설정합니다. -
Clear encoder.
[[vertex_buffers]]
.
18. 번들
번들은 한 번 인코딩된 후 여러 번 실행할 수 있는 부분적이고 제한적인 패스로, 일반적인 커맨드 버퍼처럼 사용 후 만료되지 않습니다. 반복적으로 변경 없이 발행되는 명령의 인코딩 및 제출 오버헤드를 줄일 수 있습니다.
18.1. GPURenderBundle
[Exposed =(Window ,Worker ),SecureContext ]interface GPURenderBundle { };GPURenderBundle includes GPUObjectBase ;
[[command_list]]
, of type list<GPU command>-
GPURenderBundle
가 실행될 때GPURenderPassEncoder
에 제출되는 GPU 명령 리스트입니다. [[usage scope]]
, of type usage scope, initially empty-
해당 렌더 번들의 usage scope로, 나중에
executeBundles()
에서GPURenderPassEncoder
의[[usage scope]]
에 병합할 때 사용됩니다. [[layout]]
, of typeGPURenderPassLayout
-
렌더 번들의 레이아웃입니다.
[[depthReadOnly]]
, of typeboolean
-
true
면 이 렌더 번들 실행 시 depth 컴포넌트가 변경되지 않음을 의미합니다. [[stencilReadOnly]]
, of typeboolean
-
true
면 이 렌더 번들 실행 시 stencil 컴포넌트가 변경되지 않음을 의미합니다. [[drawCount]]
, of typeGPUSize64
-
이
GPURenderBundle
의 드로우 명령 개수입니다.
18.1.1. 렌더 번들 생성
dictionary :
GPURenderBundleDescriptor GPUObjectDescriptorBase { };
[Exposed =(Window ,Worker ),SecureContext ]interface {
GPURenderBundleEncoder GPURenderBundle finish (optional GPURenderBundleDescriptor descriptor = {}); };GPURenderBundleEncoder includes GPUObjectBase ;GPURenderBundleEncoder includes GPUCommandsMixin ;GPURenderBundleEncoder includes GPUDebugCommandsMixin ;GPURenderBundleEncoder includes GPUBindingCommandsMixin ;GPURenderBundleEncoder includes GPURenderCommandsMixin ;
createRenderBundleEncoder(descriptor)
-
GPURenderBundleEncoder
를 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createRenderBundleEncoder(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPURenderBundleEncoderDescriptor
✘ ✘ 생성할 GPURenderBundleEncoder
설명.컨텐트 타임라인 단계:
-
? 텍스처 포맷 필수 기능 검증을 descriptor.
colorFormats
의 각 non-null
요소에 대해 this.[[device]]
와 함께 실행. -
descriptor.
depthStencilFormat
값이 제공된 경우:-
? 텍스처 포맷 필수 기능 검증을 descriptor.
depthStencilFormat
에 대해 this.[[device]]
와 함께 실행.
-
-
e를 ! 새 WebGPU 객체 생성(this,
GPURenderBundleEncoder
, descriptor)로 설정. -
this의 디바이스 타임라인에서 initialization steps 실행.
-
e 반환.
디바이스 타임라인 initialization steps:-
아래 조건 중 하나라도 만족하지 않으면 유효성 오류 생성, e를 무효화하고 반환.
-
this는 lost 상태가 아니어야 함.
-
descriptor.
colorFormats
.size 값이 this.[[limits]]
.maxColorAttachments
이하이어야 함. -
각 non-
null
colorFormat에 대해 descriptor.colorFormats
:-
colorFormat 값이 color renderable format이어야 함.
-
-
색상 어태치먼트 샘플당 바이트 계산(descriptor.
colorFormats
) 값이 this.[[limits]]
.maxColorAttachmentBytesPerSample
이하이어야 함. -
descriptor.
depthStencilFormat
값이 제공된 경우:-
descriptor.
depthStencilFormat
값이 depth-or-stencil format이어야 함.
-
-
어태치먼트가 최소 1개 존재해야 하며, 다음 중 하나여야 함:
-
descriptor.
colorFormats
에 non-null
값이 존재하거나 -
descriptor.
depthStencilFormat
이 존재하거나.
-
-
-
e.
[[layout]]
값을 descriptor에 포함된GPURenderPassLayout
인터페이스의 복사본으로 설정. -
e.
[[depthReadOnly]]
값을 descriptor.depthReadOnly
로 설정. -
e.
[[stencilReadOnly]]
값을 descriptor.stencilReadOnly
로 설정. -
e.
[[drawCount]]
값을 0으로 설정.
-
18.1.2. 인코딩
dictionary :
GPURenderBundleEncoderDescriptor GPURenderPassLayout {boolean depthReadOnly =false ;boolean stencilReadOnly =false ; };
depthReadOnly
, 타입 boolean, 기본값false
-
true
면 렌더 번들이 실행되는 어떤 렌더 패스의GPURenderPassDepthStencilAttachment
의 depth 컴포넌트를 수정하지 않음을 의미합니다. stencilReadOnly
, 타입 boolean, 기본값false
-
true
면 렌더 번들이 실행되는 어떤 렌더 패스의GPURenderPassDepthStencilAttachment
의 stencil 컴포넌트를 수정하지 않음을 의미합니다.
18.1.3. 최종화
finish(descriptor)
-
렌더 번들 커맨드 시퀀스 기록을 완료합니다.
호출 대상:GPURenderBundleEncoder
this.인자:
GPURenderBundleEncoder.finish(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPURenderBundleDescriptor
✘ ✔ 반환값:
GPURenderBundle
컨텐트 타임라인 단계:
-
renderBundle을 새로운
GPURenderBundle
로 설정. -
this.
[[device]]
의 디바이스 타임라인에서 finish steps 실행. -
renderBundle 반환.
디바이스 타임라인 finish steps:-
아래 요구사항을 모두 만족하면 validationSucceeded를
true
로, 아니면false
로 설정.-
this가 valid 상태여야 함.
-
this.
[[usage scope]]
가 usage scope validation을 만족해야 함. -
this.
[[debug_group_stack]]
값이 비어 있어야 함.
-
-
validationSucceeded가
false
면: -
renderBundle.
[[command_list]]
값을 this.[[commands]]
로 설정. -
renderBundle.
[[usage scope]]
값을 this.[[usage scope]]
로 설정. -
renderBundle.
[[drawCount]]
값을 this.[[drawCount]]
로 설정.
-
19. 큐(Queues)
19.1. GPUQueueDescriptor
GPUQueueDescriptor
는 큐 요청을 설명합니다.
dictionary GPUQueueDescriptor :GPUObjectDescriptorBase { };
19.2. GPUQueue
[Exposed =(Window ,Worker ),SecureContext ]interface GPUQueue {undefined submit (sequence <GPUCommandBuffer >commandBuffers );Promise <undefined >onSubmittedWorkDone ();undefined writeBuffer (GPUBuffer buffer ,GPUSize64 bufferOffset ,AllowSharedBufferSource data ,optional GPUSize64 dataOffset = 0,optional GPUSize64 size );undefined writeTexture (GPUTexelCopyTextureInfo destination ,AllowSharedBufferSource data ,GPUTexelCopyBufferLayout dataLayout ,GPUExtent3D size );undefined copyExternalImageToTexture (GPUCopyExternalImageSourceInfo source ,GPUCopyExternalImageDestInfo destination ,GPUExtent3D copySize ); };GPUQueue includes GPUObjectBase ;
GPUQueue
에는 다음과
같은 메서드가 있습니다:
writeBuffer(buffer, bufferOffset, data, dataOffset, size)
-
제공된 데이터를
GPUBuffer
에 기록합니다.호출 대상:GPUQueue
this.인자:
GPUQueue.writeBuffer(buffer, bufferOffset, data, dataOffset, size) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 buffer
GPUBuffer
✘ ✘ 기록 대상 버퍼. bufferOffset
GPUSize64
✘ ✘ buffer에서 기록을 시작할 바이트 오프셋. data
AllowSharedBufferSource
✘ ✘ buffer에 기록할 데이터. dataOffset
GPUSize64
✘ ✔ data에서 기록을 시작할 오프셋. data가 TypedArray
면 요소 단위, 그렇지 않으면 바이트 단위.size
GPUSize64
✘ ✔ data에서 buffer로 기록할 내용의 크기. data가 TypedArray
면 요소 단위, 그렇지 않으면 바이트 단위.반환값:
undefined
컨텐트 타임라인 단계:
-
data가
ArrayBuffer
또는DataView
면, element type을 "byte"로 설정. 그렇지 않으면 data는 TypedArray이며, element type은 TypedArray의 타입. -
dataSize를 data의 크기(요소 단위)로 설정.
-
size가 없으면, contentsSize를 dataSize − dataOffset으로, 아니면 contentsSize를 size로 설정.
-
아래 조건 중 하나라도 만족하지 않으면,
OperationError
를 throw하고 반환.-
contentsSize ≥ 0.
-
dataOffset + contentsSize ≤ dataSize.
-
contentsSize를 바이트로 변환했을 때 4바이트 배수여야 함.
-
-
dataContents를 data의 버퍼 소스에서 복사한 바이트로 설정.
-
contents를 dataContents의 dataOffset 위치에서 contentsSize만큼의 요소로 설정.
-
이후 단계는 this의 디바이스 타임라인에서 실행.
디바이스 타임라인 단계:-
아래 조건 중 하나라도 만족하지 않으면, 유효성 오류 생성 후 반환.
-
buffer가 this와 함께 사용 가능한 상태여야 함.
-
buffer.
[[internal state]]
값이 "available"이어야 함. -
bufferOffset를 바이트로 변환했을 때 4바이트 배수여야 함.
-
bufferOffset + contentsSize를 바이트로 변환한 값이 buffer.
size
바이트 이하이어야 함.
-
-
이후 단계는 this의 큐 타임라인에서 실행.
큐 타임라인 단계:-
contents를 buffer의 bufferOffset 위치부터 기록합니다.
-
writeTexture(destination, data, dataLayout, size)
-
제공된 데이터를
GPUTexture
에 기록합니다.호출 대상:GPUQueue
this.인자:
GPUQueue.writeTexture(destination, data, dataLayout, size) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 destination
GPUTexelCopyTextureInfo
✘ ✘ 기록 대상 텍스처 서브리소스와 시작 위치. data
AllowSharedBufferSource
✘ ✘ destination에 기록할 데이터. dataLayout
GPUTexelCopyBufferLayout
✘ ✘ data의 레이아웃. size
GPUExtent3D
✘ ✘ data에서 destination으로 기록할 컨텐츠의 크기. 반환값:
undefined
컨텐트 타임라인 단계:
-
? GPUOrigin3D shape 검증(destination.
origin
). -
? GPUExtent3D shape 검증(size).
-
dataBytes를 data의 버퍼 소스에서 복사한 바이트 시퀀스로 설정.
참고: 명세상 data 전체를 디바이스 타임라인으로 복사한다고 되어 있지만, 실제로는 필요한 바이트만 복사하는 것이 최적화됩니다.
-
이후 단계는 this의 디바이스 타임라인에서 실행.
디바이스 타임라인 단계:-
aligned를
false
로 설정. -
dataLength를 dataBytes의 길이로 설정.
-
아래 조건 중 하나라도 만족하지 않으면, 유효성 오류 생성 후 반환.
-
destination.
texture
.[[destroyed]]
값이false
여야 함. -
텍스처 버퍼 복사 검증(destination, dataLayout, dataLength, size,
COPY_DST
, aligned) 값이true
여야 함.
참고:
GPUCommandEncoder
.copyBufferToTexture()
와 달리 dataLayout.bytesPerRow
나 dataLayout.offset
에 대한 정렬 요구는 없음. -
-
이후 단계는 this의 큐 타임라인에서 실행.
큐 타임라인 단계:-
blockWidth를 destination.
texture
의 텍셀 블록 너비로 설정. -
blockHeight를 destination.
texture
의 텍셀 블록 높이로 설정. -
dstOrigin을 destination.
origin
로 설정; -
dstBlockOriginX를 (dstOrigin.x ÷ blockWidth)로 설정.
-
dstBlockOriginY를 (dstOrigin.y ÷ blockHeight)로 설정.
-
blockColumns를 (copySize.width ÷ blockWidth)로 설정.
-
blockRows를 (copySize.height ÷ blockHeight)로 설정.
-
Assert로 dstBlockOriginX, dstBlockOriginY, blockColumns, blockRows가 정수임을 확인.
-
각 z에 대해 [0, copySize.depthOrArrayLayers − 1] 범위:
-
dstSubregion을 texture copy sub-region (z + dstOrigin.z)로 설정.
-
각 y에 대해 [0, blockRows − 1] 범위:
-
각 x에 대해 [0, blockColumns − 1] 범위:
-
blockOffset를 texel block byte offset (x, y, z)로 설정.
-
dstSubregion의 (dstBlockOriginX + x, dstBlockOriginY + y) 텍셀 블록을 dataBytes의 blockOffset 위치에서 동등한 텍셀 표현으로 설정.
-
-
-
-
copyExternalImageToTexture(source, destination, copySize)
-
플랫폼 이미지/캔버스의 내용을 대상 텍스처에 복사합니다.
이 작업은
GPUCopyExternalImageDestInfo
파라미터에 따라 대상 인코딩으로 컬러 인코딩을 수행합니다.-srgb
텍스처에 복사할 경우, 동일한 디코드 값이 아닌 동일한 텍스처 바이트가 복사됩니다. 따라서 복사 후 대상 텍스처를 샘플링하면 포맷이-srgb
인지에 따라 결과가 달라집니다.참고:"webgl"
/"webgl2"
컨텍스트 캔버스에서 복사할 때, WebGL Drawing Buffer는 프레임 표시 사이클 중 특정 시점에 존재하지 않을 수 있습니다(이미지가 디스플레이를 위해 컴포지터로 이동된 후). 이를 피하려면 다음 중 하나를 수행하세요:-
WebGL 렌더링 작업과 동일 task에서
copyExternalImageToTexture()
를 호출해 복사가 WebGL 캔버스 표시 전에 이루어지도록 하세요. -
불가능하다면
preserveDrawingBuffer
옵션을WebGLContextAttributes
에true
로 설정해, 프레임 표시 후에도 드로잉 버퍼가 프레임 내용을 복사본으로 유지하도록 하세요. 단, 추가 복사로 인해 성능 저하가 있을 수 있습니다.
호출 대상:GPUQueue
this.인자:
GPUQueue.copyExternalImageToTexture(source, destination, copySize) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 source
GPUCopyExternalImageSourceInfo
✘ ✘ 복사할 destination에 대한 소스 이미지와 원점. destination
GPUCopyExternalImageDestInfo
✘ ✘ 기록할 텍스처 서브리소스 및 원점, 그리고 인코딩 메타데이터. copySize
GPUExtent3D
✘ ✘ source에서 destination으로 기록할 콘텐츠의 범위. 반환값:
undefined
컨텐트 타임라인 단계:
-
? GPUOrigin2D shape 검증(source.
origin
). -
? GPUOrigin3D shape 검증(destination.
origin
). -
? GPUExtent3D shape 검증(copySize).
-
sourceImage를 source.
source
로 설정. -
sourceImage가 origin-clean 상태가 아니면,
SecurityError
를 throw하고 반환. -
아래 요구사항 중 하나라도 만족하지 않으면
OperationError
를 throw하고 반환.-
source.origin.x + copySize.width 값이 sourceImage의 너비 이하이어야 함.
-
source.origin.y + copySize.height 값이 sourceImage의 높이 이하이어야 함.
-
copySize.depthOrArrayLayers 값이 1 이하이어야 함.
-
-
usability를 ? 이미지 인자 사용성 체크(source)로 설정.
-
이후 단계를 this의 디바이스 타임라인에서 실행.
디바이스 타임라인 단계:-
texture를 destination.
texture
로 설정. -
아래 요구사항 중 하나라도 만족하지 않으면 유효성 오류 생성하고 반환.
-
usability 값이
good
이어야 함. -
texture.
[[destroyed]]
값이false
이어야 함. -
texture이 this와 함께 사용 가능한 상태여야 함.
-
validating GPUTexelCopyTextureInfo(destination, copySize) 값이
true
여야 함. -
texture.
usage
값에RENDER_ATTACHMENT
및COPY_DST
가 모두 포함되어야 함. -
texture.
sampleCount
값이 1이어야 함. -
texture.
format
값이 다음 포맷 중 하나이어야 함(RENDER_ATTACHMENT
사용을 지원):
-
-
copySize.depthOrArrayLayers 값이 0보다 크면, 이후 단계를 this의 큐 타임라인에서 실행.
큐 타임라인 단계:-
Assert destination.
texture
의 texel block width가 1, texel block height가 1, copySize.depthOrArrayLayers가 1임을 확인. -
srcOrigin을 source.
origin
으로 설정. -
dstOrigin을 destination.
origin
으로 설정. -
dstSubregion을 texture copy sub-region (dstOrigin.z) of destination으로 설정.
-
각 y에 대해 [0, copySize.height − 1] 범위에서:
-
srcY를 source.
flipY
값이false
이면 y로, 아니면 (copySize.height − 1 − y)로 설정. -
각 x에 대해 [0, copySize.width − 1] 범위에서:
-
texel block (dstOrigin.x + x, dstOrigin.y + y) of dstSubregion을 (srcOrigin.x + x, srcOrigin.y + srcY) 위치의 source.
source
픽셀의 동등 texel 표현으로 설정. destination.colorSpace
및 destination.premultipliedAlpha
에 필요한 컬러스페이스 변환 적용 후.
-
-
-
submit(commandBuffers)
-
이 큐에서 GPU가 커맨드 버퍼를 실행하도록 예약합니다.
제출된 커맨드 버퍼는 다시 사용할 수 없습니다.
호출 대상:GPUQueue
this.인자:
GPUQueue.submit(commandBuffers) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 commandBuffers
sequence<GPUCommandBuffer>
✘ ✘ 반환값:
undefined
컨텐트 타임라인 단계:
-
이후 단계를 this의 디바이스 타임라인에서 실행:
디바이스 타임라인 단계:-
다음 요구사항 중 하나라도 충족되지 않으면, 유효성 검사 오류를 발생시키고, invalidate를 commandBuffers의 각
GPUCommandBuffer
에 수행한 뒤 반환합니다.-
commandBuffers의 모든
GPUCommandBuffer
가 this와 함께 사용 가능한 상태여야 함. -
commandBuffers의 모든
GPUCommandBuffer
가 유일해야 함. -
다음 자원 타입이 commandBuffers 내 모든 커맨드에서 사용된 경우:
GPUBuffer
b-
b.
[[internal state]]
값이 "available"이어야 함. GPUTexture
t-
t.
[[destroyed]]
값이false
이어야 함. GPUExternalTexture
et-
et.
[[expired]]
값이false
이어야 함. GPUQuerySet
qs-
qs.
[[destroyed]]
값이false
이어야 함.
참고: Occlusion 쿼리의 경우,
occlusionQuerySet
은beginRenderPass()
에서 사용되어도beginOcclusionQuery()
에서 사용하지 않으면 "사용됨"으로 간주되지 않습니다.
-
-
각 commandBuffer에 대해:
-
이후 단계를 this의 큐 타임라인에서 실행:
큐 타임라인 단계:-
각 commandBuffer에 대해:
-
commandBuffer.
[[command_list]]
의 각 명령을 실행합니다.
-
-
onSubmittedWorkDone()
-
이 큐가 지금까지 제출된 모든 작업을 처리하면 resolve되는
Promise
를 반환합니다.이
Promise
가 resolve되면, 해당 호출 전에mapAsync()
가 실행된GPUBuffer
들에 대해, 마지막으로 해당 큐에서만 사용된 버퍼의 작업이 완료됨을 의미합니다.호출 대상:GPUQueue
this.컨텐트 타임라인 단계:
-
contentTimeline을 현재 컨텐트 타임라인으로 설정.
-
promise를 새로운 promise로 설정.
-
this의 디바이스 타임라인에서 synchronization steps 실행.
-
promise 반환.
디바이스 타임라인 synchronization steps:-
현재 큐에 등록된 모든 작업이 완료되면 event가 발생하도록 설정.
-
event를 타임라인 이벤트로 수신 하여, this.
[[device]]
에서 contentTimeline에서 후속 단계 처리.
컨텐트 타임라인 단계: -
20. 쿼리(Queries)
20.1. GPUQuerySet
[Exposed =(Window ,Worker ),SecureContext ]interface GPUQuerySet {undefined destroy ();readonly attribute GPUQueryType type ;readonly attribute GPUSize32Out count ; };GPUQuerySet includes GPUObjectBase ;
GPUQuerySet
객체에는 다음 불변 속성이
있습니다:
type
, 타입 GPUQueryType, 읽기전용-
이
GPUQuerySet
이 관리하는 쿼리 타입입니다. count
, 타입 GPUSize32Out, 읽기전용-
이
GPUQuerySet
이 관리하는 쿼리 개수입니다.
GPUQuerySet
객체에는 다음 디바이스 타임라인 속성이 있습니다:
[[destroyed]]
, 타입boolean
, 초기값false
-
쿼리셋이 destroy되면 더 이상 작업에 사용할 수 없으며, 메모리도 해제될 수 있습니다.
20.1.1. 쿼리셋 생성(QuerySet Creation)
GPUQuerySetDescriptor
는 GPUQuerySet
생성 시 사용할 옵션을 지정합니다.
dictionary :
GPUQuerySetDescriptor GPUObjectDescriptorBase {required GPUQueryType type ;required GPUSize32 count ; };
type
, 타입 GPUQueryType-
GPUQuerySet
이 관리하는 쿼리 타입입니다. count
, 타입 GPUSize32-
GPUQuerySet
이 관리하는 쿼리 개수입니다.
createQuerySet(descriptor)
-
GPUQuerySet
을 생성합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.createQuerySet(descriptor) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 descriptor
GPUQuerySetDescriptor
✘ ✘ 생성할 GPUQuerySet
설명.반환값:
GPUQuerySet
컨텐트 타임라인 단계:
-
descriptor.
type
값이"timestamp"
이지만,"timestamp-query"
가 this에 enabled for 상태가 아니라면:-
TypeError
를 throw합니다.
-
-
q를 ! 새 WebGPU 객체 생성(this,
GPUQuerySet
, descriptor)로 설정. -
this의 디바이스 타임라인에서 initialization steps 실행.
-
q 반환.
-
GPUQuerySet
생성 예시.
const querySet= gpuDevice. createQuerySet({ type: 'occlusion' , count: 32 });
20.1.2. 쿼리셋 소멸(Query Set Destruction)
더 이상 GPUQuerySet
이 필요하지 않은 애플리케이션은 destroy()
를
호출하여
가비지 컬렉션 이전에 접근을 잃을 수 있습니다.
GPUQuerySet
객체에는 다음과 같은 메서드가 있습니다:
destroy()
-
GPUQuerySet
을 소멸시킵니다.디바이스 타임라인 단계:-
this.
[[destroyed]]
값을true
로 설정합니다.
-
20.2. QueryType
enum {
GPUQueryType ,
"occlusion" , };
"timestamp"
20.3. Occlusion Query
Occlusion 쿼리는 렌더 패스에서만 사용할 수 있으며, 드로우 명령 집합에 대해 스크리서, 샘플 마스크, 알파 투 커버리지, 스텐실, 깊이 테스트 등 모든 프래그먼트 테스트를 통과한 프래그먼트 샘플의 개수를 쿼리합니다. 쿼리 결과가 0이 아닌 값이면 하나 이상의 샘플이 테스트를 통과해 렌더 파이프라인의 출력 머지 단계에 도달했다는 의미이고, 0이면 어떤 샘플도 테스트를 통과하지 않았다는 뜻입니다.
렌더 패스를 시작할 때 GPURenderPassDescriptor
.occlusionQuerySet
을 지정해야 패스에서 occlusion 쿼리를 사용할 수 있습니다. 쿼리는 beginOcclusionQuery()
와
endOcclusionQuery()
를 반드시 쌍으로 호출해야 하며 중첩될 수 없고, GPUBuffer
로 64비트 부호 없는 정수 형태로 GPUCommandEncoder
.resolveQuerySet()
로
결과를 저장합니다.
20.4. Timestamp Query
Timestamp 쿼리를 사용하면 애플리케이션이 다음을 통해 GPUQuerySet
에
타임스탬프를 기록할 수 있습니다:
그리고 타임스탬프 값을(나노초 단위의 64비트 부호 없는 정수 형태) GPUBuffer
에
GPUCommandEncoder
.resolveQuerySet()
를
통해 저장할 수 있습니다.
Timestamp 값은 구현 종속적이며 반드시 단조 증가하지 않을 수 있습니다. 물리 디바이스가 타임스탬프 카운터를 가끔 리셋할 수 있어 논리적으로 증가해야 할 타임스탬프 사이가 음수 등 예기치 않은 값이 나올 수 있습니다. 이런 경우는 드물며 무시해도 안전합니다. 애플리케이션이 예기치 않은 타임스탬프 때문에 실패하지 않도록 작성되어야 합니다.
Timestamp 쿼리는 고해상도 타이머(참고 § 2.1.7.2 디바이스/큐 타임라인 타이밍)로 구현됩니다. 보안 및 프라이버시 문제를 완화하기 위해 정밀도가 감소되어야 합니다:
-
fineTimestamp를 현재 큐 타임라인의 타임스탬프 값으로, 나노초 단위, 구현 종속적 과거의 한 시점 기준으로 설정.
-
fineTimestamp에 대해 coarsen time을 호출하여,
crossOriginIsolatedCapability
를false
로 설정 후 결과를 반환.
참고: cross-origin 격리가 디바이스 타임라인이나
큐 타임라인에 적용되지 않을 수 있으므로,
crossOriginIsolatedCapability
는 항상 false
로 설정됩니다.
인자:
-
GPUDevice
device -
(
timestampWritesGPUComputePassTimestampWrites
또는GPURenderPassTimestampWrites
)
디바이스 타임라인 단계:
-
아래 요구사항을 모두 만족하면
true
, 아니면false
를 반환:-
"timestamp-query"
가 device에 enabled for 상태여야 함. -
timestampWrites.
querySet
이 device와 함께 사용 가능한 상태여야 함. -
timestampWrites.
querySet
.type
값이"timestamp"
이어야 함. -
timestampWrites의 write index 멤버들 (
beginningOfPassWriteIndex
,endOfPassWriteIndex
)에 대해:
-
21. 캔버스 렌더링
21.1. HTMLCanvasElement.getContext()
GPUCanvasContext
객체는 getContext()
메서드를 통해 HTMLCanvasElement
인스턴스에서 문자열 리터럴 'webgpu'
를 contextType
인자로 넘기면 생성됩니다.
HTMLCanvasElement
에서
GPUCanvasContext
얻기:
const canvas= document. createElement( 'canvas' ); const context= canvas. getContext( 'webgpu' );
WebGL이나 2D 컨텍스트 생성과 달리,
HTMLCanvasElement.getContext()
또는
OffscreenCanvas.getContext()
의
두 번째 인자인
컨텍스트 생성 속성 딕셔너리 options
는 무시됩니다.
대신, 캔버스를 교체하지 않고 캔버스 구성 변경이 가능한 GPUCanvasContext.configure()
를
사용하세요.
HTMLCanvasElement
또는 OffscreenCanvas
)
canvas에 대해, 다음
컨텐트 타임라인
단계를 실행합니다:
-
context를 새로운
GPUCanvasContext
로 설정합니다. -
context.
canvas
값을 canvas로 설정합니다. -
drawing buffer 교체를 context에 대해 실행합니다.
-
context를 반환합니다.
참고: getContext()
로 WebGPU 캔버스 컨텍스트를 얻을 때
무시되는 options
인자가 제공되면
사용자 에이전트는 개발자에게 경고를 표시해야 합니다.
21.2. GPUCanvasContext
[Exposed =(Window ,Worker ),SecureContext ]interface {
GPUCanvasContext readonly attribute (HTMLCanvasElement or OffscreenCanvas )canvas ;undefined configure (GPUCanvasConfiguration configuration );undefined unconfigure ();GPUCanvasConfiguration ?getConfiguration ();GPUTexture getCurrentTexture (); };
GPUCanvasContext
객체에는 다음 컨텐트 타임라인 속성이 있습니다:
canvas
, 타입(HTMLCanvasElement or OffscreenCanvas)
, 읽기전용-
이 컨텍스트가 생성된 캔버스입니다.
[[configuration]]
, 타입GPUCanvasConfiguration
?, 초기값null
-
현재 이 컨텍스트가 구성된 옵션입니다.
아직 구성되지 않았거나
unconfigure
된 경우null
입니다. [[textureDescriptor]]
, 타입GPUTextureDescriptor
?, 초기값null
-
현재 구성된 텍스처 디스크립터로,
[[configuration]]
및 캔버스에서 유도됩니다.아직 구성되지 않았거나
unconfigure
된 경우null
입니다. [[drawingBuffer]]
, 이미지, 초기값은 캔버스와 동일한 크기의 투명 검정 이미지-
드로잉 버퍼는 캔버스의 작업용 이미지 데이터입니다.
[[currentTexture]]
(즉,getCurrentTexture()
로 반환)에서 쓰기 가능하게 노출됩니다.드로잉 버퍼는 컨텍스트의 이미지 내용 복사에 사용되며, 캔버스 표시 또는 읽기 시 동작합니다.
[[configuration]]
.alphaMode
값이"opaque"
여도 투명할 수 있습니다.alphaMode
는 "컨텍스트의 이미지 내용 복사" 알고리즘의 결과에만 영향을 줍니다.드로잉 버퍼는
[[currentTexture]]
보다 오래 존재하며, 캔버스가 표시된 후에도 이전 렌더링 내용이 남아 있습니다. drawing buffer 교체에서만 초기화됩니다.드로잉 버퍼를 읽을 때마다 구현체는 이전에 제출된 모든 작업(예: 큐 제출)이
[[currentTexture]]
를 통해 모두 기록을 완료했는지 보장해야 합니다. [[currentTexture]]
, 타입GPUTexture
?, 초기값null
-
현재 프레임에 그리기 위한
GPUTexture
입니다. 이는[[drawingBuffer]]
에 대한 쓰기 가능한 뷰를 제공합니다.getCurrentTexture()
가 이 슬롯이null
이면 할당 후 반환합니다.표시 상태의 캔버스에서는 currentTexture로 드로잉 버퍼에 변경된 내용이 WebGPU 캔버스 렌더링 갱신 시점에 표시됩니다. 그 시점이나 그 이전에 텍스처가 destroy되고,
[[currentTexture]]
값은null
로 바뀌어 다음getCurrentTexture()
호출에서 새로 생성됨을 신호합니다.currentTexture destroy
는 드로잉 버퍼 내용에는 영향을 주지 않으며, 단지 드로잉 버퍼의 쓰기 접근을 즉시 중단시킵니다. 같은 프레임 내에서는getCurrentTexture()
가 계속해서 동일한 destroy된 텍스처를 반환할 수 있습니다.currentTexture 만료는 currentTexture를
null
로 설정합니다. 이는configure()
, 캔버스 크기 변경, 프레젠테이션,transferToImageBitmap()
등에서 호출됩니다. [[lastPresentedImage]]
, 타입(readonly image)?
, 초기값null
-
이 캔버스에서 "WebGPU 캔버스 렌더링 갱신" 시 가장 최근에 표시된 이미지입니다. 디바이스가 lost 또는 destroy된 경우, 캔버스가 빈 상태가 되지 않도록 "컨텍스트의 이미지 내용 복사"에서 fallback으로 사용할 수 있습니다.
참고: 이 속성은 fallback 구현하는 경우에만 필요하며 선택 사항입니다.
GPUCanvasContext
객체에는 다음과 같은 메서드가 있습니다:
configure(configuration)
-
이 캔버스의 컨텍스트를 구성합니다. drawing buffer를 투명 검정색으로 초기화합니다(drawing buffer 교체).
호출 대상:GPUCanvasContext
this.인자:
GPUCanvasContext.configure(configuration) 메서드의 인자. 파라미터 타입 Nullable Optional 설명 configuration
GPUCanvasConfiguration
✘ ✘ 컨텍스트에 원하는 구성. 반환값: undefined
컨텐트 타임라인 단계:
-
device를 configuration.
device
로 설정합니다. -
? 텍스처 포맷 필수 기능 검증을 configuration.
format
에 대해 device.[[device]]
와 함께 실행. -
? 텍스처 포맷 필수 기능 검증을 configuration.
viewFormats
의 각 요소에 대해 device.[[device]]
와 함께 실행. -
지원하는 컨텍스트 포맷이 configuration.
format
을 포함하지 않으면,TypeError
를 throw합니다. -
descriptor를 캔버스와 configuration용 GPUTextureDescriptor(this.
canvas
, configuration)로 설정. -
this.
[[configuration]]
값을 configuration로 설정합니다.참고:이 명세는toneMapping
옵션을 통해 HDR 지원을 요구합니다. 사용자가toneMapping: "standard"
만 지원하는 경우,toneMapping
멤버가GPUCanvasConfiguration
에 존재하지 않아야 하며,getConfiguration()
결과에도 존재하지 않고,configure()
에서도 접근되지 않아야 합니다. 이렇게 하면 웹사이트에서 기능 지원 여부를 감지할 수 있습니다. -
this.
[[textureDescriptor]]
값을 descriptor로 설정합니다. -
drawing buffer 교체를 this에 대해 실행합니다.
-
이후 단계를 device의 디바이스 타임라인에서 실행합니다.
디바이스 타임라인 단계:-
아래 요구사항 중 하나라도 만족하지 않으면 유효성 오류 생성 후 반환.
-
validating GPUTextureDescriptor(device, descriptor) 값이 true여야 함.
참고: 이 초기 검증은 다음
configure()
호출까지 유효합니다. 단,size
에 대한 검증은 캔버스 크기가 변경될 때만 예외입니다. -
-
unconfigure()
-
컨텍스트 구성을 제거합니다. 구성 중 생성된 텍스처는 모두 destroy됩니다.
호출 대상:GPUCanvasContext
this.반환값: undefined
컨텐트 타임라인 단계:
-
this.
[[configuration]]
값을null
로 설정합니다. -
this.
[[textureDescriptor]]
값을null
로 설정합니다. -
drawing buffer 교체를 this에 대해 실행합니다.
-
getConfiguration()
-
컨텍스트 구성을 반환합니다.
호출 대상:GPUCanvasContext
this.반환값:
GPUCanvasConfiguration
또는null
컨텐트 타임라인 단계:
-
configuration을 this.
[[configuration]]
의 복사본으로 설정합니다. -
configuration을 반환합니다.
참고:getConfiguration()
가toneMapping
이 구현되어 있고 dynamic-range 미디어 쿼리가 HDR 지원을 나타내면, WebGPU 캔버스는 반드시 HDR 디스플레이의 SDR 범위로 값을 클램핑하지 않고 전체 HDR 범위로 렌더링해야 합니다. -
getCurrentTexture()
-
다음에
GPUCanvasContext
가 문서에 합성할GPUTexture
를 반환합니다.참고:애플리케이션은 캔버스 텍스처에 렌더링하는 작업과 같은 태스크 내에서getCurrentTexture()
를 호출해야 합니다. 그렇지 않으면 아래 단계들에 의해 애플리케이션이 텍스처 렌더링을 완료하기 전에 텍스처가 소멸될 수 있습니다.만료 태스크(아래 정의)는 구현 시 선택 사항입니다. 구현된 경우에도 태스크 소스 우선순위는 표준적으로 정의되지 않으므로 다음 태스크에서 일어날 수도, 모든 다른 태스크 소스가 비었을 때 일어날 수도 있습니다 (automatic expiry task source 참고). 만료는 가시 캔버스가 표시될 때만 보장됩니다 (WebGPU 캔버스 렌더링 업데이트), 그리고 "현재 텍스처 만료"를 호출하는 다른 곳에서도 발생할 수 있습니다.
호출 대상:GPUCanvasContext
this.반환값:
GPUTexture
컨텐트 타임라인 단계:
-
this.
[[configuration]]
값이null
이면,InvalidStateError
를 throw하고 반환합니다. -
this.
[[textureDescriptor]]
값이null
이 아님을 확인(assert)합니다. -
device를 this.
[[configuration]]
.device
로 설정합니다. -
this.
[[currentTexture]]
값이null
이면:-
그리기 버퍼 교체를 this에 대해 실행합니다.
-
this.
[[currentTexture]]
값을 device.createTexture()
를 호출하여 this.[[textureDescriptor]]
로 생성하되,GPUTexture
의 내부 스토리지가 this.[[drawingBuffer]]
를 가리키도록 설정합니다.참고: 텍스처 생성에 실패(예: 유효성 검사 실패 또는 메모리 부족)하면 에러가 발생하고 무효화된
GPUTexture
가 반환됩니다. 일부 유효성 검사는configure()
에서 이미 수행됩니다. 구현체는 이러한 중복 검증을 절대 생략하면 안 됩니다.
-
-
선택적으로, 자동 만료 태스크 등록을 device와 함께 다음 단계로 실행할 수 있습니다:
-
현재 텍스처 만료를 this에 대해 실행합니다.
참고: 만약 WebGPU 캔버스 렌더링 업데이트에서 이미 수행됐다면, 효과가 없습니다.
-
-
this.
[[currentTexture]]
를 반환합니다.
참고: "현재 텍스처 만료"가 실행되기 전까지는,
GPUTexture
가 소멸되거나 유효성 검사에 실패하거나 할당 실패해도getCurrentTexture()
를 호출할 때마다 같은GPUTexture
객체가 반환됩니다. -
인자:
-
context:
GPUCanvasContext
반환값: 이미지 콘텐츠
컨텐트 타임라인 단계:
-
snapshot을 context.
canvas
와 같은 크기의 투명한 검정 이미지로 설정합니다. -
configuration을 context.
[[configuration]]
로 설정합니다. -
configuration이
null
이면:-
snapshot을 반환합니다.
참고: 컨텍스트가 구성되지 않았거나
unconfigure
된 경우 configuration은null
입니다. 이는 캔버스에 컨텍스트가 없는 경우와 동일한 동작입니다. -
-
제출된 모든 작업 항목(예: 큐 제출)이 이미지(context.
[[currentTexture]]
를 통해)에 기록을 완료했는지 확인합니다. -
configuration.
device
가 유효한 상태라면:-
snapshot을 context.
[[drawingBuffer]]
의 복사본으로 설정합니다.
그렇지 않고 context.
[[lastPresentedImage]]
값이null
이 아니면:-
선택적으로, snapshot을 context.
[[lastPresentedImage]]
의 복사본으로 설정합니다.참고: 이는 선택 사항이며,
[[lastPresentedImage]]
가 더 이상 존재하지 않을 수 있고, 디바이스 손실 원인에 따라 구현체는 해당 이미지를 사용할 수 있어도 건너뛸 수 있습니다.
-
-
alphaMode를 configuration.
alphaMode
로 설정합니다. -
- alphaMode가
"opaque"
인 경우: -
-
snapshot의 알파 채널을 1.0으로 클리어합니다.
-
snapshot을 불투명으로 태깅합니다.
참고:
[[currentTexture]]
가 소멸된 경우(예: "현재 텍스처 만료") 알파 채널은 관찰할 수 없으므로 구현체는 알파 채널을 인플레이스로 클리어해도 됩니다. -
- 그 외의 경우:
-
snapshot에 alphaMode를 태깅합니다.
- alphaMode가
-
snapshot에
colorSpace
와toneMapping
을 태깅합니다. -
snapshot을 반환합니다.
GPUCanvasContext
context에 대해 실행하려면 다음 컨텐트 타임라인 단계를 따릅니다:
-
현재 텍스처 만료를 context에 대해 실행합니다.
-
configuration을 context.
[[configuration]]
로 설정합니다. -
context.
[[drawingBuffer]]
를 context.canvas
와 같은 크기의 투명한 검정 이미지로 설정합니다.-
configuration이 null이면, drawing buffer에
"srgb"
컬러스페이스 태그를 부여합니다. 이 경우 drawing buffer는 컨텍스트가 구성될 때까지 빈 상태로 유지됩니다. -
그 외의 경우 drawing buffer는 지정된 configuration.
format
을 가지며, configuration.colorSpace
와 configuration.toneMapping
태그가 부여됩니다.
참고: configuration.
alphaMode
값은 "컨텍스트 이미지 콘텐츠 복사본 얻기" 전까지는 무시됩니다.참고:새로 교체된 drawing buffer 이미지는 투명한 검정으로 클리어된 것처럼 동작하지만,"discard"
이후처럼, 구현체는 필요 시에만 lazy하게 클리어할 수 있습니다.참고: drawing buffer가 이미 클리어되어 있고, 올바른 구성이라면 이 작업은 대부분 no-op입니다.
-
GPUCanvasContext
context에 대해 실행하려면 다음 컨텐트 타임라인 단계를 따릅니다:
-
context.
[[currentTexture]]
값이null
이 아니면:-
context.
[[currentTexture]]
.destroy()
를 호출하여(context.[[drawingBuffer]]
는 삭제하지 않음) 이미지에 대한 쓰기 접근을 종료합니다. -
context.
[[currentTexture]]
를null
로 설정합니다.
-
21.3. HTML 명세 후크
아래 알고리즘들은 HTML 명세의 알고리즘에 "hook"되어 지정된 지점에서 실행되어야 합니다.
HTMLCanvasElement
또는 OffscreenCanvas
에서 GPUCanvasContext
context의 "bitmap"을 읽을 때, 아래 컨텐트 타임라인 단계를 실행합니다:
-
context의 이미지 콘텐츠 복사본을 반환합니다.
-
HTMLCanvasElement
의 렌더링이 갱신될 때.-
캔버스가 OffscreenCanvas 플레이스홀더 캔버스 요소일 때도 포함.
-
-
transferToImageBitmap()
가 비트맵에서ImageBitmap
을 생성할 때. (WebGPU에서 transferToImageBitmap 참고.) -
WebGPU 캔버스 콘텐츠를
drawImage()
,texImage2D()
,texSubImage2D()
,toDataURL()
,toBlob()
등 다른 Web API로 읽을 때도 발생.
alphaMode
가 "opaque"
면,
알파 채널을 클리어합니다. 구현체가 알파 채널을 무시하거나 읽지 않고 이미지를 표시할 수 있으면 이 단계를 생략할 수 있습니다.
애플리케이션에서 캔버스를 단순 연동용(프레젠테이션 목적 아님)으로만 사용할 경우, 필요 없으면 "opaque"
를
피하세요.
HTMLCanvasElement
또는 OffscreenCanvas
와 플레이스홀더 캔버스 요소가 있는 경우)
GPUCanvasContext
context에 대해, 캔버스 이미지 콘텐츠를 얻기 전 아래 이벤트 루프 처리 모델의 하위 단계에서 실행합니다:
-
"해당
Document
의 렌더링 또는 사용자 인터페이스 업데이트" -
"해당 전용 worker의 렌더링 업데이트"
참고:
서비스 및 공유 워커는 "렌더링 업데이트" 단계가 없습니다. 사용자에게 보이는 캔버스에 렌더링할 수 없기 때문입니다.
requestAnimationFrame()
은
ServiceWorkerGlobalScope
와 SharedWorkerGlobalScope
에
노출되지 않으며,
OffscreenCanvas
는
transferControlToOffscreen()
를 통해 이런 워커로 전달할 수 없습니다.
아래 컨텐트 타임라인 단계를 실행합니다:
-
context에 대해 현재 텍스처 만료를 실행합니다.
참고: 만약
getCurrentTexture()
에서 큐된 태스크에서 이미 실행된 경우 아무 효과가 없습니다. -
context.
[[lastPresentedImage]]
를 context.[[drawingBuffer]]
로 설정합니다.참고: 이는 복사본이 아니라 참조입니다. current texture가 만료된 후 drawing buffer의 콘텐츠는 인플레이스 변경되지 않습니다.
참고:
단독 OffscreenCanvas
(new OffscreenCanvas()
로 생성)에는 적용되지 않습니다.
캔버스에서 transferToImageBitmap()
가
호출되고,
GPUCanvasContext
context가 있다면, 캔버스 비트맵에서 ImageBitmap
을
생성한 후,
아래 컨텐트 타임라인 단계를
실행합니다:
-
context에 대해 그리기 버퍼 교체를 실행합니다.
참고: 이로 인해 transferToImageBitmap()
이 이미지 콘텐츠를 ImageBitmap으로 "이동"(그리고 필요 시 알파 클리어)하는 것과 동등해집니다. 복사본이 아닙니다.
-
캔버스 크기 업데이트 알고리즘.
21.4. GPUCanvasConfiguration
지원되는 컨텍스트 포맷은
집합에
해당하는 GPUTextureFormat
들입니다:
«"bgra8unorm"
,
"rgba8unorm"
,
"rgba16float"
».
이 포맷들은 GPUCanvasConfiguration
.format
으로 지정할 때 반드시 지원되어야 하며,
GPUCanvasConfiguration
.device
값과 관계없이 적용됩니다.
참고: 캔버스 구성에서는 srgb
포맷("bgra8unorm-srgb"
등)을 사용할 수 없습니다.
대신 비-srgb
대응 포맷("bgra8unorm"
)을
사용하고,
srgb
포맷은 viewFormats
에
지정한 뒤,
createView()
로
srgb
포맷의 뷰를 생성합니다.
enum GPUCanvasAlphaMode {"opaque" ,"premultiplied" , };enum GPUCanvasToneMappingMode {"standard" ,"extended" , };dictionary {
GPUCanvasToneMapping GPUCanvasToneMappingMode = "standard"; };
mode dictionary {
GPUCanvasConfiguration required GPUDevice device ;required GPUTextureFormat format ;GPUTextureUsageFlags usage = 0x10; // GPUTextureUsage.RENDER_ATTACHMENTsequence <GPUTextureFormat >viewFormats = [];PredefinedColorSpace colorSpace = "srgb";GPUCanvasToneMapping toneMapping = {};GPUCanvasAlphaMode alphaMode = "opaque"; };
GPUCanvasConfiguration
객체의 멤버는 다음과 같습니다:
device
, 타입 GPUDevice-
GPUDevice
는getCurrentTexture()
로 반환되는 텍스처들이 호환되는 디바이스입니다. format
, 타입 GPUTextureFormat-
getCurrentTexture()
로 반환되는 텍스처의 포맷입니다. 반드시 지원되는 컨텍스트 포맷 중 하나여야 합니다. usage
, 타입 GPUTextureUsageFlags, 기본값0x10
-
getCurrentTexture()
로 반환되는 텍스처의 usage입니다.RENDER_ATTACHMENT
가 기본값이지만, usage를 명시적으로 설정할 경우 자동으로 포함되지 않습니다.RENDER_ATTACHMENT
용도로getCurrentTexture()
의 텍스처를 렌더 패스의 색상 타겟으로 사용할 경우 반드시 포함하세요. viewFormats
, 타입 sequence<GPUTextureFormat>, 기본값[]
-
getCurrentTexture()
로 반환되는 텍스처에서 생성되는 뷰가 사용할 수 있는 포맷 목록입니다. colorSpace
, 타입 PredefinedColorSpace, 기본값"srgb"
-
getCurrentTexture()
로 반환되는 텍스처에 기록된 값이 표시될 때 사용할 컬러스페이스입니다. toneMapping
, 타입 GPUCanvasToneMapping, 기본값{}
-
톤 매핑은
getCurrentTexture()
로 반환된 텍스처의 콘텐츠가 어떻게 표시될지 결정합니다.참고: HDR WebGPU 캔버스를 지원하지 않는 경우, 이 멤버를 노출하지 않아 기능 감지가 가능하도록 해야 합니다.
getConfiguration()
참고. alphaMode
, 타입 GPUCanvasAlphaMode, 기본값"opaque"
-
getCurrentTexture()
로 반환된 텍스처를 읽거나 표시하거나 이미지 소스로 사용할 때 알파 값의 효과를 결정합니다.
GPUDevice
와 함께
사용할 GPUCanvasContext
를
구성하고,
이 컨텍스트에 권장 포맷을 사용하는 예시:
const canvas= document. createElement( 'canvas' ); const context= canvas. getContext( 'webgpu' ); context. configure({ device: gpuDevice, format: navigator. gpu. getPreferredCanvasFormat(), });
HTMLCanvasElement
또는 OffscreenCanvas
)
canvas,
GPUCanvasConfiguration
configuration)
은 다음 멤버를 가지는 GPUTextureDescriptor
입니다:
-
size
: [canvas.width, canvas.height, 1]. -
viewFormats
: configuration.viewFormats
.
그 외 멤버는 모두 기본값으로 설정됩니다.
canvas.width는 HTMLCanvasElement
.width
또는 OffscreenCanvas
.width
값을 의미합니다.
canvas.height는 HTMLCanvasElement
.height
또는 OffscreenCanvas
.height
값을 의미합니다.
21.4.1. 캔버스 컬러스페이스(Canvas Color Space)
프레젠테이션 시, 캔버스의 색상 값은 화면의 컬러스페이스로 변환됩니다.
toneMapping
은
화면 컬러스페이스에서 [0, 1]
구간 외 값의 처리를 결정합니다.
21.4.2. 캔버스 컨텍스트 크기(Canvas Context sizing)
모든 캔버스 구성은 configure()
에서
설정되며,
해상도는 캔버스의 width
및 height
로 설정됩니다.
참고: WebGL 및 2d 캔버스와 마찬가지로, WebGPU 캔버스 크기를 변경하면 drawing buffer의 현재 내용이 손실됩니다. WebGPU에서는 drawing buffer 교체로 처리됩니다.
HTMLCanvasElement
또는 OffscreenCanvas
canvas가
GPUCanvasContext
context와 함께 width
나 height
속성이 설정되면,
캔버스 크기 업데이트 알고리즘은 다음 컨텐트 타임라인 단계를 실행합니다:
-
context에 대해 drawing buffer 교체를 실행합니다.
-
configuration을 context.
[[configuration]]
로 설정합니다. -
configuration이
null
이 아니면:-
context.
[[textureDescriptor]]
를 캔버스 및 구성의 GPUTextureDescriptor(canvas, configuration)로 설정합니다.
-
참고: 이 과정에서
GPUTextureDescriptor
가
디바이스의 maxTextureDimension2D
를
초과할 수 있습니다. 이 경우,
getCurrentTexture()
에서
유효성 검사가 실패합니다.
참고: 이 알고리즘은 canvas의 width
또는
height
속성이 설정될 때마다 실행되며,
값이 실제로 변경되지 않아도 실행됩니다.
21.5. GPUCanvasToneMappingMode
이 enum은 색상 값이 화면에 어떻게 표시될지 지정합니다.
"standard"
-
화면의 표준 다이내믹 레인지 내 색상 값은 변경되지 않고, 나머지 색상 값은 화면의 표준 다이내믹 레인지로 투영(projected)됩니다.
참고: 이 투영은 종종 화면 컬러스페이스에서 색상 값을
[0, 1]
구간으로 클램핑(clamping)하는 방식으로 처리됩니다. "extended"
-
화면의 확장 다이내믹 레인지 내 색상 값은 변경되지 않고, 나머지 색상 값은 화면의 확장 다이내믹 레인지로 투영됩니다.
참고: 이 투영은 종종 화면 컬러스페이스에서 색상 값을 해당 화면이 표시할 수 있는 값의 구간(1보다 큰 값 포함 가능)으로 클램핑하는 방식으로 처리됩니다.
예를 들어,(2.5, -0.15, -0.15)
값을'srgb'
캔버스에 기록한다고 가정합니다.sRGB 화면이 sRGB 공간에서
[0, 4]
구간 값을 표시할 수 있다면, sRGB로 변환(캔버스가 sRGB이므로 변환 없음) 후 디스플레이 공간으로 투영됩니다. 컴포넌트별 클램핑을 사용하면 sRGB 값(2.5, 0.0, 0.0)
이 됩니다.Display P3 화면이 Display P3 공간에서
[0, 2]
구간 값을 표시할 수 있다면, Display P3 컬러스페이스 값(2.3, 0.545, 0.386)
으로 변환 후 디스플레이 공간으로 투영됩니다. 컴포넌트별 클램핑을 사용하면 Display P3 값(2.0, 0.545, 0.386)
이 됩니다.
21.6. GPUCanvasAlphaMode
이 enum은 캔버스의 콘텐츠를 읽거나, 화면에 표시하거나 이미지 소스로 사용할 때 (drawImage, toDataURL 등에서) 어떻게 해석할지 선택합니다.
아래에서 src
는 캔버스 텍스처의 값이고, dst
는 캔버스가 합성되는 이미지(예: HTML 페이지 렌더링, 2D 캔버스 등)입니다.
"opaque"
-
RGB를 불투명(opaque)으로 읽고 알파 값을 무시합니다. 콘텐츠가 이미 불투명하지 않으면, "컨텍스트 이미지 콘텐츠 복사본 얻기"에서 알파 채널이 1.0으로 클리어됩니다.
"premultiplied"
-
RGBA를 프리멀티플라이드로 읽습니다: 색상 값이 자신의 알파 값으로 곱해집니다. 100% 빨강에 50% 알파면
[0.5, 0, 0, 0.5]
입니다.캔버스 텍스처에 가무트 초과 프리멀티플라이드 RGBA 값이 존재할 때, 캔버스 콘텐츠를 읽을 때의 동작은 캔버스 사용 맥락에 따라 다릅니다:
- 이미지 소스로 사용
-
값이 보존되며, 컬러스페이스 변환에서 설명한 대로 동작합니다.
- 화면에 표시
-
합성 결과는 정의되지 않습니다.
참고: 컬러스페이스 변환으로 합성 전에 가무트 내 값이 되어도, 합성 중간 포맷이 명세되지 않았으므로 결과는 여전히 정의되지 않습니다.
22. 오류 및 디버깅
WebGPU의 정상적인 동작 과정에서, 오류는 에러 디스패치로 발생합니다.
디바이스가 손실된 이후에는, 가능한 경우 더 이상 오류가 노출되지 않습니다. 이 시점 이후로, 구현체는 유효성 검사나 오류 추적을 수행할 필요가 없습니다:
-
디바이스 내 객체의 유효성은 관찰할 수 없게 됩니다.
-
popErrorScope()
와uncapturederror
는 오류 보고를 중단합니다. (디바이스 손실 자체로 인한 오류는 생성되지 않습니다. 대신,GPUDevice
.lost
프라미스가 디바이스 손실을 알리며 resolve됩니다.) -
컨텐트 타임라인에 메시지를 보내는 모든 연산은 기존 단계를 건너뜁니다. 대부분은 성공한 것처럼 보이지만,
mapAsync()
는 디바이스 손실 후 올바른 매핑 데이터를 제공할 수 없어 오류를 생성합니다.메시지를 돌려주지 않는 다른 타입의 연산(실제로 실행되었는지)은 관찰할 수 없습니다.
22.1. 치명적 오류
enum {
GPUDeviceLostReason ,
"unknown" , }; [
"destroyed" Exposed =(Window ,Worker ),SecureContext ]interface {
GPUDeviceLostInfo readonly attribute GPUDeviceLostReason ;
reason readonly attribute DOMString ; };
message partial interface GPUDevice {readonly attribute Promise <GPUDeviceLostInfo >lost ; };
GPUDevice
는
다음과 같은 추가 속성을 가집니다:
lost
, 타입 Promise<GPUDeviceLostInfo>, 읽기 전용-
디바이스 생성 시 생성되며, 디바이스의 생명주기 동안 pending 상태로 유지되고, 디바이스가 손실되면 resolve되는 프라미스를 가지는 슬롯 기반 속성입니다.
초기화 시 새로운 프라미스로 설정됩니다.
22.2. GPUError
[Exposed =(Window ,Worker ),SecureContext ]interface GPUError {readonly attribute DOMString message ; };
GPUError
는
popErrorScope()
및 uncapturederror
이벤트에서 발생하는 모든 오류의 기본 인터페이스입니다.
오류는 각 알고리즘에서 명시적으로 오류가 발생하는 조건과 생성될 오류의 하위 타입을 명시한 경우에만 생성되어야 합니다.
손실된 디바이스에서는 오류가 생성되지 않습니다. § 22 오류 및 디버깅 참고.
참고: GPUError
는 향후 현행
표준에서 새로운 하위 타입을 가질 수 있습니다. 애플리케이션은 이 가능성에 대비해, 가능한 경우 에러의 message
만
사용하고,
특수화가 필요할 때는 instanceof
를 사용해야 합니다. 에러를 직렬화(예: JSON이나 디버그 리포트)에 사용할 경우
error.constructor.name
를 쓰세요.
message
, 타입 DOMString, 읽기 전용-
오류에 대한 정보를 제공하는 사람이 읽을 수 있는 지역화 가능한 텍스트 메시지입니다.
참고: 이 메시지는 일반적으로 애플리케이션 개발자가 디버깅 및 디버그 리포트용 정보를 수집하는 용도이며, 최종 사용자에게 노출하는 용도가 아닙니다.
참고: 유저 에이전트는 이 메시지에 시스템의 사용 가능한 메모리 등 기계가 파싱 가능한 세부 정보를 포함해서는 안 됩니다(
"out-of-memory"
등에서 메모리가 고갈된 조건 등).참고:
message
는 언어 및 방향 정보에 대한 권장사항을 따라야 합니다. 이는 향후 관련 표준이 등장할 경우 공식적으로 채택할 수 있습니다.편집자 노트: 현재 시점에서는 레거시 API와 호환성과 일관성을 제공하는 언어/방향 권장사항이 없으나, 향후 표준화될 경우 공식적으로 채택하세요.
[Exposed =(Window ,Worker ),SecureContext ]interface :
GPUValidationError GPUError {(
constructor DOMString ); };
message
GPUValidationError
는 GPUError
의 하위
타입으로,
연산이 모든 유효성 검사 요구사항을 만족하지 못한 경우를 나타냅니다. 유효성 검사 오류는 항상 애플리케이션 오류를 의미하며,
동일한 [[features]]
및 [[limits]]
를
사용하는 경우 모든 디바이스에서 동일하게 실패해야 합니다.
GPUDevice
device에 대해 수행하려면 다음 단계를 실행합니다:
디바이스 타임라인 단계:
-
error를 적절한 오류 메시지와 함께 새
GPUValidationError
로 생성합니다. -
에러 디스패치로 error를 device에 전달합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface :
GPUOutOfMemoryError GPUError {(
constructor DOMString ); };
message
GPUOutOfMemoryError
는 GPUError
의 하위
타입으로,
요청된 연산을 완료하기에 충분한 자유 메모리가 없음을 나타냅니다. 더 작은 텍스처 크기 등 적은 메모리 요구로 다시 시도하거나, 다른 리소스가 사용하는 메모리를 먼저 해제하면 성공할 수도
있습니다.
GPUDevice
device에 대해 수행하려면 다음 단계를 실행합니다:
디바이스 타임라인 단계:
-
error를 적절한 오류 메시지와 함께 새
GPUOutOfMemoryError
로 생성합니다. -
에러 디스패치로 error를 device에 전달합니다.
[Exposed =(Window ,Worker ),SecureContext ]interface :
GPUInternalError GPUError {(
constructor DOMString ); };
message
GPUInternalError
는 GPUError
의 하위
타입으로,
모든 유효성 검사 요구사항을 만족했음에도 시스템 또는 구현체 고유의 사유로 연산이 실패한 경우를 나타냅니다.
예를 들어, 구현체의 기능을 지원 한계로
쉽게 포착하기 어려운 방식으로 초과한 경우 등입니다.
동일 연산이 다른 디바이스나 상황에서는 성공할 수도 있습니다.
GPUDevice
device에 대해 수행하려면 다음 단계를 실행합니다:
디바이스 타임라인 단계:
-
error를 적절한 오류 메시지와 함께 새
GPUInternalError
로 생성합니다. -
에러 디스패치로 error를 device에 전달합니다.
22.3. 에러 스코프(Error Scopes)
GPU 에러 스코프는
GPUError
가
현재 GPU 에러 스코프일 때 생성된 오류들을
캡처합니다.
에러 스코프는 WebGPU 호출 집합 내에서 발생한 오류를 분리하여 디버깅이나 연산의 내결함성을 높이기 위해 사용됩니다.
GPU 에러 스코프는 다음 디바이스 타임라인 속성을 가집니다:
[[errors]]
, 타입 list<GPUError
>, 기본값 []-
GPU 에러 스코프가 현재일 때 관찰된
GPUError
목록입니다. [[filter]]
, 타입GPUErrorFilter
-
이 GPU 에러 스코프가 관찰하는
GPUError
타입을 결정합니다.
enum {
GPUErrorFilter "validation" ,"out-of-memory" ,"internal" , };partial interface GPUDevice {undefined pushErrorScope (GPUErrorFilter filter );Promise <GPUError ?>popErrorScope (); };
GPUErrorFilter
는
pushErrorScope()
호출시 어떤 타입의 오류를 포착할지 정의합니다:
"validation"
-
에러 스코프가
GPUValidationError
를 포착함을 나타냅니다. "out-of-memory"
-
에러 스코프가
GPUOutOfMemoryError
를 포착함을 나타냅니다. "internal"
-
에러 스코프가
GPUInternalError
를 포착함을 나타냅니다.
GPUDevice
는 다음
디바이스 타임라인
속성을 가집니다:
[[errorScopeStack]]
, 타입 stack<GPU 에러 스코프>-
GPUDevice
에 푸시된 GPU 에러 스코프의 스택입니다.
GPUError
error와
GPUDevice
device에 대해 디바이스
타임라인에 다음 단계를 발행하여 결정합니다:
디바이스 타임라인 단계:
-
만약 error가 다음 인스턴스면:
GPUValidationError
-
type을 "validation"으로 설정.
GPUOutOfMemoryError
-
type을 "out-of-memory"로 설정.
GPUInternalError
-
type을 "internal"로 설정.
-
scope를 device.
[[errorScopeStack]]
의 마지막 항목으로 설정. -
scope가
undefined
가 아닐 때까지:-
scope.
[[filter]]
가 type이면 scope 반환. -
scope를 device.
[[errorScopeStack]]
의 이전 항목으로 설정.
-
-
undefined
반환.
GPUError
error를
GPUDevice
device에서 실행하려면 다음 디바이스 타임라인 단계를 실행합니다:
참고: 손실된 디바이스에서는 오류가 생성되지 않습니다. 이 알고리즘이 device가 손실 상태에서 호출될 경우, 애플리케이션에서 관찰할 수 없습니다. § 22 오류 및 디버깅 참고.
-
scope를 현재 에러 스코프(error, device)로 설정.
-
scope가
undefined
가 아니면:-
추가(append) error를 scope.
[[errors]]
에. -
반환.
-
-
그렇지 않으면 컨텐트 타임라인에 다음 단계를 실행:
-
유저 에이전트가 선택하면,
GPUUncapturedErrorEvent
이벤트를 "uncapturederror
" 이름으로 device에 발생시키고,error
를 error로 설정합니다.
참고: 이벤트 디스패치 후, 유저 에이전트는 uncaptured 오류를 개발자에게
노출해야 하며(예: 브라우저 개발자 콘솔의 경고),
단, 이벤트의 defaultPrevented
값이 true라면 콘솔 경고를 표시하지 않습니다. 즉 preventDefault()
를
호출하면 콘솔 경고가 사라집니다.
참고: 유저 에이전트는 GPUUncapturedErrorEvent
가
GPUDevice
에서
과도하게 발생하지 않도록 제한하거나 throttle 할 수 있습니다.
과도한 오류 처리/로깅이 성능에 영향을 미치는 것을 방지하기 위함입니다.
pushErrorScope(filter)
-
this의
[[errorScopeStack]]
에 새 GPU 에러 스코프를 푸시합니다.호출 대상:GPUDevice
this.인자:
GPUDevice.pushErrorScope(filter) 메서드의 인자. Parameter Type Nullable Optional Description filter
GPUErrorFilter
✘ ✘ 이 에러 스코프가 관찰할 오류 클래스. 반환값:
undefined
컨텐트 타임라인 단계:
-
이후 단계는 this의 디바이스 타임라인에서 실행.
디바이스 타임라인 단계:-
scope를 새 GPU 에러 스코프로 생성.
-
scope.
[[filter]]
를 filter로 설정. -
푸시(push) scope를 this.
[[errorScopeStack]]
에.
-
popErrorScope()
-
this의
[[errorScopeStack]]
에서 GPU 에러 스코프를 pop하고, 해당 스코프에서 관찰된 아무GPUError
또는 없으면null
로 resolve됩니다.프라미스 resolve 순서는 보장되지 않습니다.
디바이스 타임라인 check steps:-
this가 손실 상태면:
-
contentTimeline에 다음 단계 실행:
-
반환.
참고: 손실된 디바이스에서는 오류가 생성되지 않습니다. § 22 오류 및 디버깅 참고.
-
-
다음 요구사항 중 하나라도 충족하지 않으면:
-
this.
[[errorScopeStack]]
.size가 0보다 커야 함.
그렇다면 contentTimeline에 다음 단계 실행 후 반환:
컨텐트 타임라인 단계:-
reject promise를
OperationError
로.
-
-
this.
[[errorScopeStack]]
에서 항목을 pop하여 scope로 설정합니다. -
scope.
[[errors]]
의 항목 중 아무거나 하나를 error로 설정하거나, 없으면null
로 설정합니다.리스트 내 오류 E1, E2에 대해 만약 E2가 E1에 의해 발생했다면, E2는 선택하면 안 됩니다.
참고: 예시: E1이
t
=createTexture()
에서 발생하고, E2가t
.createView()
에서t
가 잘못됨 상태로 인해 발생했다면, E1을 선택하는 것이 개발자가 문제를 더 잘 이해할 수 있습니다. 두 오류 모두GPUValidationError
이며, 차이는message
필드뿐인데, 이는 사람이 읽기 위한 정보입니다. -
지금 혹은 미래의 불특정 시점에, 이후 단계를 contentTimeline에서 수행합니다.
참고:
popErrorScope()
호출이 어느 순서로든, scope에서 관찰된 어떤 오류로든 resolve될 수 있게 허용함으로써, 이 명세는 유효성 검사가 순서와 무관하게 완료될 수 있도록 합니다. 상태 관찰만 명세 준수 시점에 맞게 이루어지면 됩니다. 예를 들어, 셰이더 컴파일은 비상태 입력에만 의존하므로, 다른 디바이스 타임라인 작업과 병렬로 백그라운드 스레드에서 완료되어 이후 오류를 보고할 수도 있습니다.
-
GPUDevice
연산에서 발생할 수 있는 유효성 검사 오류를 error scope로 캡처하는 예시:
gpuDevice. pushErrorScope( 'validation' ); let sampler= gpuDevice. createSampler({ maxAnisotropy: 0 , // 잘못됨, maxAnisotropy는 최소 1이어야 함. }); gpuDevice. popErrorScope(). then(( error) => { if ( error) { // 샘플러 생성 중 오류가 있었으므로 버린다. sampler= null ; console. error( `샘플러 생성 중 오류 발생: ${ error. message} ` ); } });
예시: 텍스처나 버퍼 등 단일 리소스 생성만을 포함하는 error scope는 out-of-memory 등 실패를 감지하는 데 사용할 수 있으며, 이 경우 애플리케이션은 리소스를 해제한 후 다시 할당 시도할 수 있습니다.
Error scope는 실패한 명령이 무엇인지 식별하지 못합니다. 예를 들어, 모델 로딩 중 실행된 모든 명령을 하나의 error scope로 감싸면, 해당 scope의 실패가 메모리 제약 때문인지 파악하기 어렵습니다. 따라서 리소스 해제는 비생산적일 수 있습니다. 더 적절한 대응은 다른 모델로 폴백하거나 경고를 출력하는 것입니다. 메모리 제약에 대응하고 싶다면, 메모리 할당 작업만을 더 작은 nested error scope로 감쌀 수 있습니다.
22.4. 텔레메트리
GPUError
가 생성되었지만 어떤 GPU error
scope에서도 관찰되지 않은 경우, 사용자 에이전트는 선택적으로 이벤트를 발생시킬 수
있습니다. 이벤트 이름은 uncapturederror
이고, GPUDevice
객체에서 GPUUncapturedErrorEvent
를
사용하여 발생시킵니다.
참고: uncapturederror
이벤트는 텔레메트리 및 예기치 않은 오류 보고 용도로 사용됩니다.
모든 uncaptured 오류에 대해 반드시 디스패치되는 것은 아니며(예: 노출되는 오류 수에 제한이 있을 수 있음), 애플리케이션의 정상 동작 중 발생 가능한 알려진 오류 처리에는 사용하면 안
됩니다.
그런 경우에는 pushErrorScope()
와
popErrorScope()
를 사용하는 것이 좋습니다.
[Exposed =(Window ,Worker ),SecureContext ]interface :
GPUUncapturedErrorEvent Event {(
constructor DOMString ,
type GPUUncapturedErrorEventInit ); [
gpuUncapturedErrorEventInitDict SameObject ]readonly attribute GPUError error ; };dictionary :
GPUUncapturedErrorEventInit EventInit {required GPUError ; };
error
GPUUncapturedErrorEvent
는 다음 속성을 가집니다:
error
, 타입 GPUError, 읽기 전용-
uncaptured 오류를 나타내는 객체를 가진 슬롯 기반 속성입니다.
popErrorScope()
로 반환되는 오류 타입과 동일합니다.
partial interface GPUDevice {attribute EventHandler onuncapturederror ; };
GPUDevice
는 다음
컨텐트 타임라인
속성을 가집니다:
onuncapturederror
, 타입 EventHandler-
uncapturederror
이벤트 타입에 대한 이벤트 핸들러 IDL 속성입니다.
GPUDevice
에서
uncaptured 오류를 감지하는 예시:
gpuDevice. addEventListener( 'uncapturederror' , ( event) => { // 이벤트 리스너 추가 시 콘솔 로그가 사라질 수 있으므로 오류를 재노출함. console. error( 'WebGPU uncaptured 오류 발생:' , event. error); myEngineDebugReport. uncapturedErrors. push({ type: event. error. constructor . name, message: event. error. message, }); });
23. 상세 연산
이 섹션은 다양한 GPU 연산의 세부 사항을 설명합니다.
23.1. 컴퓨팅
컴퓨팅 연산은 GPU의 프로그래머블 하드웨어에 직접 접근할 수 있게 해줍니다.
Compute 셰이더는 셰이더 스테이지 입력이나 출력을 갖지 않으며, 결과는
GPUBufferBindingLayout
에서 GPUBufferBindingType
의 "storage"
또는 GPUStorageTextureBindingLayout
등 스토리지 바인딩에 데이터를 기록하는 부작용(side effect)으로 나타납니다.
이러한 연산은 GPUComputePassEncoder
내에 아래와 같이 인코딩됩니다:
주요 컴퓨트 알고리즘:
인자:
-
descriptor: 현재
GPUComputePipeline
의 설명. -
dispatchCall: 디스패치 호출 파라미터. 함수 인자 또는
INDIRECT
버퍼에서 올 수 있음.
-
computeStage를 descriptor.
compute
로 설정합니다. -
workgroupSize를 computeStage.
entryPoint
에 computeStage.constants
를 적용한 후, computeStage.module
로부터 계산된 workgroup 크기로 설정합니다. -
workgroupX를
[0, dispatchCall.
범위에서 반복:workgroupCountX
]-
workgroupY를
[0, dispatchCall.
범위에서 반복:workgroupCountY
]-
workgroupZ를
[0, dispatchCall.
범위에서 반복:workgroupCountZ
]-
localX를
[0, workgroupSize.
범위에서 반복:x
]-
localY를
[0, workgroupSize.
범위에서 반복:y
]-
localZ를
[0, workgroupSize.
범위에서 반복:y
]-
invocation을
{ computeStage, workgroupX, workgroupY, workgroupZ, localX, localY, localZ }
로 설정합니다. -
append invocation을 computeInvocations에 추가합니다.
-
-
-
-
-
-
-
computeInvocations의 각 invocation에 대해, 디바이스가 선택한 임의의 순서(병렬 포함)로:
-
셰이더 내장값(builtins)을 설정:
-
num_workgroups 내장값이 있다면
(
으로 설정합니다.
dispatchCall.workgroupCountX
,
dispatchCall.workgroupCountY
,
dispatchCall.workgroupCountZ
) -
workgroup_id 내장값이 있다면
(
으로 설정합니다.
invocation.workgroupX,
invocation.workgroupY,
invocation.workgroupZ
) -
local_invocation_id 내장값이 있다면
(
으로 설정합니다.
invocation.localX,
invocation.localY,
invocation.localZ
) -
global_invocation_id 내장값이 있다면
(
으로 설정합니다.
invocation.workgroupX * workgroupSize.x
+ invocation.localX,
invocation.workgroupY * workgroupSize.y
+ invocation.localY,
invocation.workgroupZ * workgroupSize.z
+ invocation.localZ
) -
local_invocation_index 내장값이 있다면
invocation.localX + (invocation.localY * workgroupSize.
로 설정합니다.x
) + (invocation.localZ * workgroupSize.x
* workgroupSize.y
)
-
-
invocation.computeStage에 해당하는 컴퓨트 셰이더 entry point를 실행합니다.
-
참고: 셰이더 호출 순서는 보장되지 않으며, 디바이스 성능에 따라 주로 병렬로 실행됩니다. 개발자는 특정 호출이나 워크그룹이 다른 것보다 먼저 완료된다고 가정해서는 안 됩니다. 일부 디바이스는 일관된 순서로 실행되는 것처럼 보일 수 있지만, 이는 모든 디바이스에서 동일하지 않으므로 신뢰해서는 안 됩니다. 호출 간 동기화가 필요한 셰이더는 동기화 내장 함수를 사용하세요.
디바이스는 손실될 수 있습니다.
셰이더 실행이 종료되지 않을 경우,
사용자 에이전트가 판단한 합리적인 시간 내에 실행이 끝나지 않으면 디바이스가 손실될 수 있습니다.
23.2. 렌더링
렌더링은 GPURenderPassEncoder
내에서 실행되는 일련의 GPU 연산에 의해 수행되며,
렌더 패스 어태치먼트가 참조하는 텍스처 데이터가 수정되는 결과를 만듭니다.
이러한 연산은 아래와 같이 인코딩됩니다:
참고: 렌더링은 GPU의 전통적인 용도이며, 하드웨어 내 여러 고정 기능 블록에서 지원됩니다.
주요 렌더링 알고리즘:
인자:
-
pipeline: 현재
GPURenderPipeline
입니다. -
drawCall: draw 호출 파라미터. 함수 인자 또는
INDIRECT
버퍼에서 올 수 있습니다. -
state: draw 호출이 발생한
GPURenderCommandsMixin
의 RenderState입니다.
-
descriptor를 pipeline.
[[descriptor]]
로 설정합니다. -
인덱스 해석. § 23.2.1 인덱스 해석 참고.
vertexList를 resolve indices(drawCall, state)의 결과로 설정합니다.
-
버텍스 처리. § 23.2.2 버텍스 처리 참고.
process vertices(vertexList, drawCall, descriptor.
vertex
, state)를 실행합니다. -
프리미티브 조립. § 23.2.3 프리미티브 조립 참고.
assemble primitives(vertexList, drawCall, descriptor.
primitive
)를 실행합니다. -
프리미티브 클리핑. § 23.2.4 프리미티브 클리핑 참고.
이 단계의 결과로 primitiveList를 얻습니다.
-
래스터화. § 23.2.5 래스터화 참고.
rasterizationList를 rasterize(primitiveList, state)의 결과로 설정합니다.
-
프래그먼트 처리. § 23.2.6 프래그먼트 처리 참고.
rasterizationList의 각 rasterPoint에 대해 process fragment(rasterPoint, descriptor, state) 를 실행하여 fragments 리스트를 얻습니다.
-
픽셀 기록. § 23.2.7 출력 병합 참고.
fragments의 각 non-null fragment에 대해:
-
process depth stencil(fragment, pipeline, state)를 실행합니다.
-
process color attachments(fragment, pipeline, state)를 실행합니다.
-
23.2.1. 인덱스 해석
렌더링의 첫 단계에서 파이프라인은 각 인스턴스에 대해 처리할 버텍스 리스트를 만듭니다.
인자:
-
drawCall: draw 호출 파라미터. 함수 인자 또는
INDIRECT
버퍼에서 올 수 있습니다. -
state: draw 호출 시점의
GPURenderCommandsMixin
의 상태 스냅샷입니다.
반환값: 정수 인덱스 리스트.
-
vertexIndexList를 비어 있는 인덱스 리스트로 설정합니다.
-
drawCall이 인덱스 기반 draw 호출이면:
-
vertexIndexList를 drawCall.indexCount 개의 정수로 초기화합니다.
-
i를 0 .. drawCall.indexCount(미포함) 범위에서 반복:
-
relativeVertexIndex를 fetch index(i + drawCall.
firstIndex
, state.[[index_buffer]]
)의 결과로 설정합니다. -
relativeVertexIndex가 특수 값
"out of bounds"
라면, 빈 리스트를 반환합니다.참고: 구현체는 이 상황이 발생할 때(특히 감지하기 쉬운 경우, 예: 비-indirect 인덱스 draw 호출) 경고를 띄울 수 있습니다.
-
drawCall.
baseVertex
+ relativeVertexIndex를 vertexIndexList에 추가합니다.
-
-
-
그 외의 경우:
-
vertexIndexList를 drawCall.vertexCount 개의 정수로 초기화합니다.
-
각 vertexIndexList의 항목 i를 drawCall.firstVertex + i로 설정합니다.
-
-
vertexIndexList를 반환합니다.
참고: indirect draw 호출의 경우,
indexCount
, vertexCount
등 drawCall의 속성들은 draw 명령이 아니라 indirect 버퍼에서
읽습니다.
인자:
-
i: 가져올 버텍스 인덱스의 인덱스.
-
state: draw 호출 시점의
GPURenderCommandsMixin
상태 스냅샷.
반환값: unsigned integer 또는 "out of bounds"
-
indexSize를 state.
[[index_format]]
에 따라 정의: -
state.
[[index_buffer_offset]]
+ |i + 1| × indexSize > state.[[index_buffer_size]]
라면, 특수 값"out of bounds"
를 반환합니다. -
state.
[[index_buffer]]
의 데이터를, 오프셋 state.[[index_buffer_offset]]
+ i × indexSize 위치에서, indexSize 바이트 크기만큼 unsigned integer로 해석하여 반환합니다.
23.2.2. 버텍스 처리
버텍스 처리 단계는 렌더 파이프라인의 프로그래머블 단계로, 버텍스 속성 데이터를 처리하여 § 23.2.4 프리미티브 클리핑에 필요한 clip space 좌표와 § 23.2.6 프래그먼트 처리에 필요한 기타 데이터를 생성합니다.
인자:
-
vertexIndexList: 처리할 버텍스 인덱스 리스트(참조로 전달, 변경 가능).
-
drawCall: draw 호출 파라미터. 함수 인자 또는
INDIRECT
버퍼에서 올 수 있음. -
desc:
GPUVertexState
타입의 디스크립터. -
state: draw 호출 시점의
GPURenderCommandsMixin
상태 스냅샷.
각 vertexIndex는 vertexIndexList 내에서, 각 rawInstanceIndex 인스턴스마다 개별적으로
처리됩니다.
rawInstanceIndex는 0부터 drawCall.instanceCount - 1까지 포함합니다.
이 처리는 병렬로 이루어지며, GPUBufferBindingType
"storage"
바인딩 등에 대한 기록 같은 부작용(side effect)은 임의의 순서로 발생할 수 있습니다.
-
instanceIndex를 rawInstanceIndex + drawCall.firstInstance로 설정.
-
desc.
buffers
리스트의 각 non-null
vertexBufferLayout에 대해:-
해당 리스트의 버퍼 레이아웃 인덱스를 i로 설정.
-
슬롯 i의 state.
[[vertex_buffers]]
에서 vertexBuffer, vertexBufferOffset, vertexBufferBindingSize를 가져옴. -
vertexElementIndex는 vertexBufferLayout.
stepMode
에 따라 달라집니다:"vertex"
-
vertexIndex
"instance"
-
instanceIndex
-
drawCallOutOfBounds를
false
로 설정. -
vertexBufferLayout.
attributes
의 각 attributeDesc에 대해:-
attributeOffset를 vertexBufferOffset + vertexElementIndex * vertexBufferLayout.
arrayStride
+ attributeDesc.offset
로 설정. -
attributeOffset + byteSize(attributeDesc.
format
) > vertexBufferOffset + vertexBufferBindingSize이면:-
drawCallOutOfBounds를
true
로 설정. -
선택적으로 (구현체 정의), vertexIndexList를 비움 및 반환, draw 호출 취소.
참고: 이렇게 하면 구현체가 draw 호출 전에 인덱스 버퍼에서 범위 초과 값을 감지할 수 있습니다. 잘못된 메모리 참조 동작 대신.
-
-
-
vertexBufferLayout.
attributes
의 각 attributeDesc에 대해:-
drawCallOutOfBounds가
true
면:-
WGSL의 잘못된 메모리 참조 동작에 따라 vertexBuffer에서 attribute data를 로드.
참고: 잘못된 메모리 참조는 범위 내 attribute의 "정상" 결과를 실제로 로드하는 등 여러 동작을 허용합니다. draw-call-wide drawCallOutOfBounds가
true
여도.
그 외의 경우:
-
attributeOffset를 vertexBufferOffset + vertexElementIndex * vertexBufferLayout.
arrayStride
+ attributeDesc.offset
로 설정. -
vertexBuffer에서 attributeOffset 위치부터 attributeDesc.
format
형식의 attribute data를 로드. 컴포넌트는 버퍼 메모리에서x
,y
,z
,w
순으로 로드됨.
-
-
채널 포맷 규칙에 따라 data를 셰이더에서 읽을 수 있는 포맷으로 변환.
-
셰이더 타입에 따라 data 크기 조정:
-
둘 다 스칼라인 경우, 또는 둘 다 같은 차원의 벡터인 경우 조정 불필요.
-
data가 벡터이고 셰이더 타입이 스칼라인 경우, 첫 번째 컴포넌트만 추출.
-
둘 다 벡터이고 data의 차원이 더 높으면, 초과 컴포넌트는 버림.
타입"float32x3"
의 attribute, 값vec3<f32>(1.0, 2.0, 3.0)
는 셰이더에서 2-컴포넌트 벡터가 필요하면vec2<f32>(1.0, 2.0)
로 노출됨. -
셰이더 타입이 더 높은 차원의 벡터이거나 data가 스칼라인 경우, 누락된 컴포넌트는
vec4<*>(0, 0, 0, 1)
값으로 채움.
-
-
data를 버텍스 셰이더 입력 위치 attributeDesc.
shaderLocation
에 바인딩.
-
-
-
state.
[[bind_groups]]
의 각GPUBindGroup
group(index)에 대해:-
바인드 그룹의 각
GPUBindingResource
리소스에 대해:-
해당 리소스에 해당하는
GPUBindGroupLayoutEntry
를 entry로 설정. -
entry.
visibility
가VERTEX
를 포함하면:-
리소스를 셰이더의 group index 및 바인딩
GPUBindGroupLayoutEntry.binding
에 바인딩.
-
-
-
-
셰이더 내장값 설정:
-
vertex_index
내장값이 있다면 vertexIndex로 설정. -
instance_index
내장값이 있다면 instanceIndex로 설정.
-
-
desc에 기술된 버텍스 셰이더 entry point를 호출.
참고: 타겟 플랫폼은 버텍스 셰이더 호출 결과를 캐싱합니다. vertexIndex가 두 번 이상 반복되어도 반드시 여러 번 호출된다는 보장은 없습니다. 마찬가지로, 하나의 vertexIndex가 한 번만 처리된다는 보장도 없습니다.
디바이스는 손실될 수 있습니다.
셰이더 실행이 종료되지 않을 경우, 사용자 에이전트가 판단한 합리적인 시간 내에 실행이 끝나지 않으면 디바이스가 손실될 수 있습니다.
23.2.3. 프리미티브 조립
프리미티브는 GPU의 고정 기능 단계에서 조립됩니다.
인자:
-
vertexIndexList: 처리할 버텍스 인덱스 리스트입니다.
-
drawCall: draw 호출 파라미터. 함수 인자 또는
INDIRECT
버퍼에서 올 수 있습니다. -
desc:
GPUPrimitiveState
타입의 디스크립터입니다.
각 인스턴스마다, vertexIndexList를 기반으로 셰이더에서 처리한 버텍스들로 프리미티브가 조립됩니다.
-
먼저, 프리미티브 토폴로지가 스트립인 경우(desc.
stripIndexFormat
이 undefined가 아니고) drawCall이 인덱스 기반 호출이면, vertexIndexList는 desc.stripIndexFormat
최대값을 구분자로 사용하여 여러 서브 리스트로 분할됩니다.예시:
"uint16"
타입의 vertexIndexList 값이[1, 2, 65535, 4, 5, 6]
이면, 서브 리스트[1, 2]
와[4, 5, 6]
로 분할됩니다. -
각 서브 리스트 vl에 대해, 프리미티브 생성은 desc.
topology
에 따라 수행됩니다:"line-list"
-
라인 프리미티브는 (vl.0, vl.1), 그 다음 (vl.2, vl.3), 그 다음 (vl.4, vl.5) ... 식으로 구성됩니다. 각 프리미티브는 2개의 버텍스를 사용합니다.
"line-strip"
-
라인 프리미티브는 (vl.0, vl.1), 그 다음 (vl.1, vl.2), 그 다음 (vl.2, vl.3) ... 식으로 구성됩니다. 각 프리미티브는 1개의 버텍스를 추가로 사용합니다.
"triangle-list"
-
삼각형 프리미티브는 (vl.0, vl.1, vl.2), 그 다음 (vl.3, vl.4, vl.5), 그 다음 (vl.6, vl.7, vl.8) ... 식으로 구성됩니다. 각 프리미티브는 3개의 버텍스를 사용합니다.
"triangle-strip"
-
삼각형 프리미티브는 (vl.0, vl.1, vl.2), 그 다음 (vl.2, vl.1, vl.3), 그 다음 (vl.2, vl.3, vl.4), 그 다음 (vl.4, vl.3, vl.5) ... 식으로 구성됩니다. 각 프리미티브는 1개의 버텍스를 추가로 사용합니다.
프리미티브가 불완전한 경우(버텍스가 부족한 경우)는 해당 프리미티브는 버려집니다.
23.2.4. 프리미티브 클리핑
버텍스 셰이더는 position(타입 vec4<f32>
)이라는 내장값을 생성해야 하며,
이는 버텍스의 클립 공간
좌표 내 클립 위치를
나타냅니다.
프리미티브는 클립 볼륨에 맞게 클리핑됩니다. 프리미티브 내 임의의 클립 위치 p에 대해, 클립 볼륨은 다음 부등식으로 정의됩니다:
-
−p.w ≤ p.x ≤ p.w
-
−p.w ≤ p.y ≤ p.w
-
0 ≤ p.z ≤ p.w (깊이 클리핑)
"clip-distances"
기능이 활성화된 경우, 클립 볼륨은
버텍스 셰이더 출력에 clip_distances를 선언하여, 사용자 정의 반공간으로 더욱 제한될 수 있습니다. clip_distances 배열의 각 값은 프리미티브 전체에 선형 보간되며, 보간 결과가 0 미만인
부분은 클리핑됩니다.
descriptor.primitive
.unclippedDepth
가 true
이면,
깊이 클리핑은 적용되지 않으며, 클립 볼륨의 z축 제한이 사라집니다.
프리미티브의 모든 엣지가 클립 볼륨 내부에 완전히 포함되면,
해당 프리미티브는 변경 없이 이 단계를 통과합니다.
프리미티브의 엣지가 클립 볼륨의 경계를 교차하면, 교차하는
엣지는 클립 볼륨의 경계선을 따라 새로운 엣지로 다시
연결됩니다.
삼각형 프리미티브(descriptor.primitive
.topology
가
"triangle-list"
또는 "triangle-strip"
인
경우),
내부적으로 다각형에 새로운 버텍스가 추가될 수 있습니다.
프리미티브가 클립 볼륨 경계를 교차하면, 클리핑된 다각형에는 반드시 경계 위의 점이 포함되어야 합니다.
버텍스 셰이더가 "perspective" 보간으로 지정된 다른 부동소수점 값(스칼라 및 벡터)을 출력하면, 이 값들도 클리핑됩니다. 클립 볼륨 내에 있는 버텍스에 연관된 출력값은 클리핑되지 않습니다. 하지만 프리미티브가 클리핑되어 새 버텍스가 생성된 경우, 해당 버텍스에 할당된 출력값도 클리핑됩니다.
버텍스 a와 b 사이 엣지가 클리핑되어 새 버텍스 c가 만들어진 경우, t를 엣지 버텍스 간 비율로 정의합니다: c.p = t × a.p + (1 − t) × b.p, 여기서 x.p는 버텍스 x의 클립 위치입니다.
각 버텍스 출력값 "v"가 해당 프래그먼트 입력을 갖는 경우, a.v와 b.v는 각각 a와 b 버텍스의 출력값입니다. 클리핑된 셰이더 출력 c.v는 다음 보간 방식에 따라 생성됩니다:
- flat
-
flat 보간은 영향을 받지 않으며, provoking vertex에 기반합니다. 이는 셰이더에 선언된 보간 샘플링 모드에 의해 결정됩니다. 출력값은 프리미티브 전체에 동일하며, provoking vertex의 버텍스 출력과 일치합니다.
- linear
-
보간 비율은 클립 위치의 투영 좌표에 따라 조정되어, 화면 공간에서 선형적인 보간 결과가 됩니다.
- perspective
-
값은 클립 공간에서 선형적으로 보간되어, 퍼스펙티브 보정된 값을 생성합니다.
프리미티브 클리핑 결과는 클립 볼륨 내에 포함된 새로운 프리미티브 집합입니다.
23.2.5. 래스터화
래스터화는 하드웨어 처리 단계로, 생성된 프리미티브를 프레임버퍼의 2차원 렌더링 영역(현재 GPURenderPassEncoder
의
렌더 어태치먼트 집합)에 매핑합니다.
이 렌더링 영역은 픽셀의 균등한 격자로 나뉩니다.
프레임버퍼 좌표는 렌더 타겟의 좌상단에서 시작합니다. 각 단위는 정확히 한 픽셀에 해당합니다. 자세한 내용은 § 3.3 좌표계를 참고하세요.
래스터화는 프리미티브에 영향을 받는 픽셀 집합을 결정합니다. 멀티샘플링의 경우, 각 픽셀은
descriptor.multisample
.count
개의 샘플로 추가 분할됩니다.
표준 샘플 패턴은 다음과
같으며,
픽셀의 좌상단 기준 프레임버퍼 좌표에서 위치가 주어집니다(픽셀 범위가 (0,0)~(1,1)):
multisample .count
| 샘플 위치 |
---|---|
1 | 샘플 0: (0.5, 0.5) |
4 |
샘플 0: (0.375, 0.125) 샘플 1: (0.875, 0.375) 샘플 2: (0.125, 0.625) 샘플 3: (0.625, 0.875) |
구현체는 래스터화 수행 시 해당 표준 샘플 패턴을 반드시 사용해야 합니다.
multisample
.count
에
맞게 적용됩니다.
FragmentDestination을 다음과 같이 정의합니다:
- position
-
프레임버퍼 좌표를 사용하는 2D 픽셀 위치
- sampleIndex
-
§ 23.2.10 샘플별 셰이딩이 활성화된 경우 정수, 그렇지 않으면
null
정규화 디바이스 좌표(NDC) 개념도 사용합니다. 이 좌표계에서 viewport 경계는 X, Y가 -1~1, Z가 0~1 범위입니다.
래스터화는 다음 데이터를 포함하는 RasterizationPoint 리스트를 생성합니다:
- destination
- coverageMask
-
멀티샘플 커버리지 마스크 참조 (§ 23.2.11 샘플 마스킹 참고)
- frontFacing
-
프리미티브의 전면(face) 포인트라면 true
- perspectiveDivisor
-
프리미티브 전역에서 보간된 1.0 ÷ W 값 참조
- depth
-
뷰포트 좌표 내 깊이 참조, 즉
[[viewport]]
minDepth
~maxDepth
범위 - primitiveVertices
-
프리미티브를 구성하는 버텍스 출력값 리스트 참조
- barycentricCoordinates
인자:
-
primitiveList: 래스터화할 프리미티브 리스트.
-
state: 활성 RenderState.
반환값: RasterizationPoint 리스트.
primitiveList 내 각 프리미티브는 개별적으로 처리됩니다. 단, 프리미티브의 순서는 이후 단계(깊이/스텐실 연산, 픽셀 기록)에 영향을 줍니다.
-
먼저, 클리핑된 버텍스들은 NDC(정규화 디바이스 좌표)로 변환됩니다. 출력 위치 p를 주면, NDC 위치 및 퍼스펙티브 디바이저는 다음과 같습니다:
ndc(p) = 벡터(p.x ÷ p.w, p.y ÷ p.w, p.z ÷ p.w)
divisor(p) = 1.0 ÷ p.w
-
vp를 state.
[[viewport]]
로 설정합니다. NDC 위치 n을 뷰포트 좌표로 매핑:-
렌더 타겟 오프셋 및 크기로 프레임버퍼 좌표 계산:
framebufferCoords(n) = 벡터(vp.
x
+ 0.5 × (n.x + 1) × vp.width
, vp.y
+ 0.5 × (−n.y + 1) × vp.height
) -
[0,1]을 뷰포트 깊이 범위에 선형 매핑하여 깊이 계산:
depth(n) = vp.
minDepth
+ n.z
× ( vp.maxDepth
- vp.minDepth
)
-
-
rasterizationPoints를, 프리미티브 내 위치에 따라(
divisor(p)
,framebufferCoords(n)
,depth(n)
등), § 23.2.4 프리미티브 클리핑과 동일한 보간 방식으로 보간된 속성을 가진 포인트 리스트로 설정합니다. 속성이 사용자 정의(내장 출력값이 아닌)라면, WGSL @interpolate 속성에 지정된 보간 타입을 사용합니다. -
아래 프리미티브 토폴로지에 따라 특정 래스터화 알고리즘 진행:
primitive
.topology
:"point-list"
-
포인트가 § 23.2.4 프리미티브 클리핑에서 필터링되지 않았다면 § 23.2.5.1 포인트 래스터화로 전달.
"line-list"
또는"line-strip"
-
라인이 § 23.2.4 프리미티브 클리핑에서 잘린 경우 § 23.2.5.2 라인 래스터화로 전달.
"triangle-list"
또는"triangle-strip"
-
§ 23.2.4 프리미티브 클리핑에서 생성된 폴리곤은 § 23.2.5.4 폴리곤 래스터화로 전달.
-
rasterizationPoints에서 rp 중 rp.destination.position 이 state.
[[scissorRect]]
밖인 것은 제거합니다. -
rasterizationPoints를 반환합니다.
23.2.5.1. 포인트 래스터화
포인트의 프레임버퍼 좌표가 포함된 픽셀 내에서 하나의 FragmentDestination이 선택됩니다.
커버리지 마스크는 멀티샘플링 모드에 따라 달라집니다:
- 샘플-주파수
-
coverageMask = 1 ≪
sampleIndex
- 픽셀-주파수 멀티샘플링
-
coverageMask = 1 ≪ descriptor.
multisample
.count
− 1 - 멀티샘플링 없음
-
coverageMask = 1
23.2.5.2. 라인 래스터화
라인 래스터화에 사용되는 정확한 알고리즘은 정의되지 않았으며, 구현체마다 다를 수 있습니다. 예를 들어, 라인 세그먼트 주변 1px 너비의 사각형을 § 23.2.5.4 폴리곤 래스터화로 그릴 수도 있고, Bresenham 라인 알고리즘을 사용해 FragmentDestination을 선택할 수도 있습니다.
참고: 자세한 라인 래스터화 알고리즘 구현 방법은 기본 라인 세그먼트 래스터화 및 Bresenham 라인 세그먼트 래스터화를 Vulkan 1.3 명세에서 참고할 수 있습니다.
23.2.5.3. 바리센트릭 좌표
바리센트릭 좌표란 n개의 숫자 bi의 리스트로, 프레임버퍼 공간 내 n개의 버텍스 vi를 가진 볼록 다각형 내부의 점 p에 대해 정의됩니다. 각 bi는 0~1 범위를 가지며, 해당 버텍스 vi와의 근접도를 나타냅니다. 이들의 합은 항상 일정합니다:
∑ (bi) = 1
이 좌표들은 다각형 내부(혹은 경계 위)의 임의의 점 p를 다음과 같이 유일하게 지정합니다:
p = ∑ (bi × pi)
버텍스가 3개인 삼각형의 경우, 임의의 점 p에 대한 바리센트릭 좌표는 다음과 같이 계산 가능합니다:
Apolygon = A(v1, v2, v3) b1 = A(p, b2, b3) ÷ Apolygon b2 = A(b1, p, b3) ÷ Apolygon b3 = A(b1, b2, p) ÷ Apolygon
여기서 A(점 리스트)는 주어진 버텍스 집합으로 이루어진 다각형의 면적입니다.
3개 초과 버텍스의 다각형은 정확한 알고리즘이 구현체마다 다릅니다. 하나의 가능한 구현 방법은 다각형을 삼각형들로 쪼개고, 점이 속하는 삼각형을 기준으로 바리센트릭 좌표를 계산하는 것입니다.
23.2.5.4. 폴리곤 래스터화
폴리곤이 투영 방향을 바라보고 있으면 전면입니다. 그렇지 않으면 후면입니다.
인자:
반환값: RasterizationPoint 리스트.
-
rasterizationPoints를 비어 있는 리스트로 설정.
-
클리핑된 버텍스 번호 i(1부터 시작)의 프레임버퍼 좌표를 v(i)로 설정. 다각형의 버텍스 개수는 n입니다.
참고: 이 섹션에서는 "triangle" 대신 "polygon" 용어를 사용하는데, § 23.2.4 프리미티브 클리핑 단계에서 추가 버텍스가 생길 수 있기 때문입니다. 이는 애플리케이션에서 관찰할 수 없습니다.
-
폴리곤이 전면인지 판단하려면, 프레임버퍼 좌표에서 폴리곤이 차지하는 area의 부호에 따라 결정합니다:
area = 0.5 × ((v1.x × vn.y − vn.x × v1.y) + ∑ (vi+1.x × vi.y − vi.x × vi+1.y))
-
폴리곤 내부 fragments 집합을 프레임버퍼 공간에서 결정합니다 - 이 위치들은 프래그먼트별 연산 대상입니다. 이 연산은 "포인트 샘플링"이라 불립니다. 로직은 descriptor.
multisample
에 따라 다릅니다:- 비활성화
-
Fragment는 픽셀 중앙에 연결됩니다. 즉, 프레임버퍼 공간에서 좌표 C의 fract(C) = vector2(0.5, 0.5)인 점들이 폴리곤 내부에 있으면 포함됩니다. 픽셀 중앙이 폴리곤 경계에 있으면 포함 여부는 정의되어 있지 않습니다.
참고: 이는 래스터라이저의 정밀도에 따라 달라집니다.
- 활성화
-
각 픽셀은 descriptor.
multisample
.count
개의 위치에 연결되며, 이 위치들은 구현체 정의입니다. 위치들은 정렬되어 있으며, 프레임버퍼의 각 픽셀에 대해 동일한 리스트입니다. 각 위치는 멀티샘플 프레임버퍼 내 하나의 프래그먼트에 대응합니다.래스터라이저는 각 픽셀 내에서 내부에 포함된 위치의 마스크를 만들고, 이를 프래그먼트 셰이더의 "sample-mask" 내장값으로 제공합니다.
-
생성된 각 FragmentDestination 타입 프래그먼트에 대해:
-
rp를 새 RasterizationPoint 객체로 설정
-
그 프래그먼트의 § 23.2.5.3 바리센트릭 좌표를 리스트 b로 계산. rp.barycentricCoordinates에 b를 설정.
-
di를 vi의 깊이 값으로 설정.
-
rp.depth를 ∑ (bi × di)로 설정
-
rp를 rasterizationPoints에 추가.
-
-
rasterizationPoints를 반환.
23.2.6. 프래그먼트 처리
프래그먼트 처리 단계는 렌더 파이프라인의 프로그래머블 단계로, 렌더 타겟에 기록될 프래그먼트 데이터(주로 색상 등)를 계산합니다.
이 단계는 각 RasterizationPoint에 대해 Fragment를 생성합니다:
-
destination: FragmentDestination 참조.
-
frontFacing: 프리미티브의 전면 프래그먼트일 경우 true.
-
coverageMask: 멀티샘플 커버리지 마스크(§ 23.2.11 샘플 마스킹 참고) 참조.
-
depth: 뷰포트 좌표 내 깊이 참조, 즉
[[viewport]]
minDepth
~maxDepth
범위. -
colors:
colorAttachments
의 각 타겟에 대해 하나씩 색상값 리스트. -
depthPassed : 해당 프래그먼트가
depthCompare
연산을 통과하면true
. -
stencilPassed : 해당 프래그먼트가
compare
스텐실 연산을 통과하면true
.
인자:
-
rp: RasterizationPoint (§ 23.2.5 래스터화에서 생성).
-
descriptor:
GPURenderPipelineDescriptor
타입의 디스크립터. -
state: 활성 RenderState.
반환값: Fragment 또는
null
.
-
fragmentDesc를 descriptor.
fragment
로 설정. -
depthStencilDesc를 descriptor.
depthStencil
로 설정. -
fragment를 새 Fragment 객체로 생성.
-
fragment.destination에 rp.destination을 설정.
-
fragment.frontFacing에 rp.frontFacing을 설정.
-
fragment.coverageMask에 rp.coverageMask를 설정.
-
셰이더에서
frag_depth
내장값을 생성하지 않은 경우:-
fragment.depthPassed를 compare fragment(fragment.destination, fragment.depth, "depth", state.
[[depthStencilAttachment]]
, depthStencilDesc?.depthCompare
)의 결과로 설정.
-
-
stencilState를 depthStencilDesc?.
stencilFront
(만약 rp.frontFacing이true
면), 그 외에는 depthStencilDesc?.stencilBack
로 설정. -
fragment.stencilPassed를 compare fragment(fragment.destination, state.
[[stencilReference]]
, "stencil", state.[[depthStencilAttachment]]
, stencilState?.compare
)의 결과로 설정. -
fragmentDesc가
null
이 아니라면:-
fragment.depthPassed가
false
이고, 셰이더 entry point가frag_depth
내장값을 생성하지 않았으며, 셰이더 entry point가 스토리지 바인딩에 기록하지 않았다면, 이후 단계는 생략할 수 있습니다. -
셰이더 입력 내장값 설정. 각 entry point의 비복합 인자 중 내장값으로 어노테이션된 것은 해당 어노테이션에 따라 값 설정:
position
-
vec4<f32>
(rp.destination.position, rp.depth, rp.perspectiveDivisor) front_facing
-
rp.frontFacing
sample_index
sample_mask
-
rp.coverageMask
-
프래그먼트 단계의 각 사용자 지정 셰이더 입력에 대해:
-
value를, rp.barycentricCoordinates, rp.primitiveVertices, 입력의 보간 지정자에 따라 보간된 프래그먼트 입력값으로 설정.
-
해당 프래그먼트 셰이더 location 입력값에 value를 설정.
-
-
fragmentDesc에 기술된 프래그먼트 셰이더 entry point를 호출.
디바이스는 손실될 수 있습니다.
셰이더 실행이 종료되지 않을 경우, 사용자 에이전트가 판단한 합리적인 시간 내에 실행이 끝나지 않으면 디바이스가 손실될 수 있습니다. -
프래그먼트에서
discard
를 호출하면null
을 반환. -
셰이더 출력 내장값에 대해:
-
frag_depth
내장값이 셰이더에서 value로 생성된 경우:-
vp를 state.
[[viewport]]
로 설정. -
fragment.depth를 clamp(value, vp.
minDepth
, vp.maxDepth
)로 설정. -
fragment.depthPassed를 compare fragment(fragment.destination, fragment.depth, "depth", state.
[[depthStencilAttachment]]
, depthStencilDesc?.depthCompare
)로 설정.
-
-
-
sample_mask
내장값이 셰이더에서 value로 생성된 경우:-
fragment.coverageMask를 fragment.coverageMask ∧ value로 설정.
-
그 외인 경우 § 23.2.8 색상 출력 없음 모드이며, fragment.colors는 비어 있음.
-
-
fragment를 반환.
인자:
-
destination: FragmentDestination.
-
value: 비교할 값.
-
aspect: attachment에서 샘플링할 aspect.
-
attachment: 비교 대상 어태치먼트.
-
compareFunc: 사용할
GPUCompareFunction
또는undefined
.
반환값: 비교가 통과하면 true
, 그렇지 않으면 false
-
attachment가
undefined
이거나 aspect를 가지지 않으면true
반환. -
compareFunc가
undefined
이거나"always"
이면true
반환. -
attachmentValue를 destination 위치의 attachment의 aspect 값으로 설정.
-
value와 attachmentValue를 compareFunc로 비교해 통과하면
true
, 아니면false
반환.
프래그먼트 처리는 병렬로 이루어지며, GPUBufferBindingType
"storage"
바인딩 등에 대한 기록 같은 부작용은 임의의 순서로 발생할 수 있습니다.
23.2.7. 출력 병합
출력 병합은 렌더 파이프라인의 고정 기능 단계로, 프래그먼트의 색상, 깊이, 스텐실 데이터를 렌더 패스 어태치먼트에 기록합니다.
인자:
-
fragment: Fragment (§ 23.2.6 프래그먼트 처리에서 생성).
-
pipeline: 현재
GPURenderPipeline
. -
state: 활성 RenderState.
-
depthStencilDesc를 pipeline.
[[descriptor]]
.depthStencil
로 설정. -
pipeline.
[[writesDepth]]
가true
이고 fragment.depthPassed가true
이면:-
state.
[[depthStencilAttachment]]
의 depth aspect 값을 fragment.destination 위치에 fragment.depth로 설정.
-
-
pipeline.
[[writesStencil]]
이 true이면:-
stencilState를 depthStencilDesc.
stencilFront
(fragment.frontFacing이true
일 때), 아니면 depthStencilDesc.stencilBack
로 설정. -
fragment.stencilPassed가
false
이면:-
stencilOp를 stencilState.
failOp
로 설정.
그 외 fragment.depthPassed가
false
이면:-
stencilOp를 stencilState.
depthFailOp
로 설정.
그 외의 경우:
-
stencilOp를 stencilState.
passOp
로 설정.
-
-
state.
[[depthStencilAttachment]]
의 stencil aspect 값을 fragment.destination 위치에 stencilOp에 따라 갱신.
-
이 단계의 깊이 입력값(있는 경우)은 현재 [[viewport]]
깊이 범위로 clamp됩니다(프래그먼트 셰이더 단계에서 frag_depth
내장값을 기록하는지 여부와 관계없이).
인자:
-
fragment: Fragment (§ 23.2.6 프래그먼트 처리에서 생성).
-
pipeline: 현재
GPURenderPipeline
. -
state: 활성 RenderState.
-
fragment.depthPassed가
false
거나 fragment.stencilPassed가false
면 return. -
targets를 pipeline.
[[descriptor]]
.fragment
.targets
로 설정. -
state.
[[colorAttachments]]
의 각 attachment에 대해:-
color를 fragment.colors에서 attachment에 해당하는 값으로 설정.
-
targetDesc를 targets에서 attachment에 해당하는 엔트리로 설정.
-
fragment.destination 위치의 attachment 값을 color로 설정.
-
23.2.8. 색상 출력 없음
색상 출력 없음 모드에서는 파이프라인이 색상 어태치먼트 출력을 생성하지 않습니다.
파이프라인은 래스터화 및 버텍스 위치 출력에 기반한 깊이 값을 계속 생성합니다. 깊이 테스트와 스텐실 연산 역시 사용할 수 있습니다.
23.2.9. 알파 투 커버리지
알파 투 커버리지 모드에서는, 프래그먼트 셰이더 출력 @location(0)
의 alpha 컴포넌트를 기반으로,
MSAA 샘플들의 추가 alpha-to-coverage 마스크가 생성됩니다.
이 추가 마스크 생성 알고리즘은 플랫폼에 따라 다르며, 픽셀마다 달라질 수 있습니다. 다음을 보장합니다:
-
alpha ≤ 0.0이면 결과는 0x0
-
alpha ≥ 1.0이면 결과는 0xFFFFFFFF
-
중간 alpha 값은 마스크 내 1로 설정된 비트 수가 비례하도록 결과를 만듭니다. 일부 플랫폼에서는, 마스크 내 1 비트 수가 픽셀마다 alpha가 증가할 때 단조 증가한다는 것이 보장되지 않을 수 있습니다.
23.2.10. 샘플별 셰이딩
멀티샘플 렌더 어태치먼트에 렌더링할 때, 프래그먼트 셰이더는 픽셀당 한 번 또는 샘플당 한 번 실행될 수 있습니다.
sample_index
내장값이나
sample
보간 샘플링이 셰이더 출력에 기여하면 프래그먼트 셰이더는 반드시 샘플별로 한 번씩 실행되어야 합니다. 그렇지
않으면 프래그먼트 셰이더는 픽셀당 한 번만 실행되어도 되고, 결과는 최종 샘플 마스크에 포함된 모든 샘플에 브로드캐스트됩니다.
샘플별 셰이딩을 사용할 때, 샘플 N에 대한 색상 출력은 프래그먼트 셰이더가 현재 픽셀에서 sample_index
== N로 실행된
결과입니다.
23.2.11. 샘플 마스킹
픽셀의 최종 샘플 마스크는 다음과 같이
계산됩니다:
래스터화 마스크
& mask
& 셰이더 출력 마스크.
마스크의 하위 count
비트만 고려됩니다.
최종 샘플 마스크의 위치 N의 최하위 비트가 "0"이면, 해당 샘플의 색상 출력(샘플 N에 해당)은 프래그먼트 셰이더의 모든 어태치먼트에서 폐기됩니다. 또한, depth-stencil 어태치먼트의 해당 샘플에서는 깊이 테스트나 스텐실 연산이 실행되지 않습니다.
래스터화 마스크는 래스터화 단계에서 생성되며, 래스터화된 폴리곤의 모양에 따라 결정됩니다. 도형에 포함된 샘플은 마스크의 해당 비트가 1이 됩니다.
셰이더 출력 마스크는 프래그먼트
셰이더의 "sample_mask" 내장값 출력값을 취합니다.
프래그먼트 셰이더에서 내장값을 출력하지 않고, alphaToCoverageEnabled
가 활성화된 경우, 셰이더 출력
마스크는 alpha-to-coverage 마스크가 됩니다.
그 외에는 0xFFFFFFFF가 기본값입니다.
24. 타입 정의
typedef [EnforceRange ]unsigned long ;
GPUBufferDynamicOffset typedef [EnforceRange ]unsigned long ;
GPUStencilValue typedef [EnforceRange ]unsigned long ;
GPUSampleMask typedef [EnforceRange ]long ;
GPUDepthBias typedef [EnforceRange ]unsigned long long ;
GPUSize64 typedef [EnforceRange ]unsigned long ;
GPUIntegerCoordinate typedef [EnforceRange ]unsigned long ;
GPUIndex32 typedef [EnforceRange ]unsigned long ;
GPUSize32 typedef [EnforceRange ]long ;
GPUSignedOffset32 typedef unsigned long long ;
GPUSize64Out typedef unsigned long ;
GPUIntegerCoordinateOut typedef unsigned long ;
GPUSize32Out typedef unsigned long ;
GPUFlagsConstant
24.1. 색상 및 벡터
dictionary {
GPUColorDict required double r ;required double g ;required double b ;required double a ; };typedef (sequence <double >or GPUColorDict );
GPUColor
참고: double
은 32비트 부호/무부호 정수와 단정밀도(float) 값을
정확하게 표현할 수 있을 만큼 충분히 큽니다.
r
, 타입 double-
빨간색 채널 값입니다.
g
, 타입 double-
초록색 채널 값입니다.
b
, 타입 double-
파란색 채널 값입니다.
a
, 타입 double-
알파(투명도) 채널 값입니다.
GPUColor
값 color의 타입에 따라 다음 문법을 사용합니다:
-
color.r은
GPUColorDict
.r
또는 시퀀스의 첫 번째 항목(해당 항목이 있다는 assert 기준)입니다. -
color.g은
GPUColorDict
.g
또는 시퀀스의 두 번째 항목(해당 항목이 있다는 assert 기준)입니다. -
color.b은
GPUColorDict
.b
또는 시퀀스의 세 번째 항목(해당 항목이 있다는 assert 기준)입니다. -
color.a은
GPUColorDict
.a
또는 시퀀스의 네 번째 항목(해당 항목이 있다는 assert 기준)입니다.
dictionary {
GPUOrigin2DDict GPUIntegerCoordinate = 0;
x GPUIntegerCoordinate = 0; };
y typedef (sequence <GPUIntegerCoordinate >or GPUOrigin2DDict );
GPUOrigin2D
GPUOrigin2D
값 origin의 타입에 따라 다음 문법을 사용합니다:
-
origin.x은
GPUOrigin2DDict
.x
또는 시퀀스의 첫 번째 항목(없으면 0)입니다. -
origin.y은
GPUOrigin2DDict
.y
또는 시퀀스의 두 번째 항목(없으면 0)입니다.
dictionary {
GPUOrigin3DDict GPUIntegerCoordinate = 0;
x GPUIntegerCoordinate = 0;
y GPUIntegerCoordinate = 0; };
z typedef (sequence <GPUIntegerCoordinate >or GPUOrigin3DDict );
GPUOrigin3D
GPUOrigin3D
값 origin의 타입에 따라 다음 문법을 사용합니다:
-
origin.x은
GPUOrigin3DDict
.x
또는 시퀀스의 첫 번째 항목(없으면 0)입니다. -
origin.y은
GPUOrigin3DDict
.y
또는 시퀀스의 두 번째 항목(없으면 0)입니다. -
origin.z은
GPUOrigin3DDict
.z
또는 시퀀스의 세 번째 항목(없으면 0)입니다.
인자:
-
origin: 검증할
GPUOrigin3D
입니다.
반환값: undefined
컨텐트 타임라인 단계:
-
다음 경우
TypeError
를 발생시킵니다:
dictionary {
GPUExtent3DDict required GPUIntegerCoordinate width ;GPUIntegerCoordinate height = 1;GPUIntegerCoordinate depthOrArrayLayers = 1; };typedef (sequence <GPUIntegerCoordinate >or GPUExtent3DDict );
GPUExtent3D
width
, 타입 GPUIntegerCoordinate-
extent의 너비입니다.
height
, 타입 GPUIntegerCoordinate, 기본값1
-
extent의 높이입니다.
depthOrArrayLayers
, 타입 GPUIntegerCoordinate, 기본값1
-
extent의 깊이 또는 포함된 배열 레이어 수입니다.
GPUTexture
가GPUTextureDimension
의"3d"
와 함께 사용되면 텍스처의 깊이를 정의합니다.GPUTexture
가GPUTextureDimension
의"2d"
와 함께 사용되면 텍스처의 배열 레이어 수를 정의합니다.
GPUExtent3D
값 extent의 타입에 따라 다음 문법을 사용합니다:
-
extent.width은
GPUExtent3DDict
.width
또는 시퀀스의 첫 번째 항목(해당 항목이 있다는 assert 기준)입니다. -
extent.height은
GPUExtent3DDict
.height
또는 시퀀스의 두 번째 항목(없으면 1)입니다. -
extent.depthOrArrayLayers은
GPUExtent3DDict
.depthOrArrayLayers
또는 시퀀스의 세 번째 항목(없으면 1)입니다.
인자:
-
extent: 검증할
GPUExtent3D
입니다.
반환값: undefined
컨텐트 타임라인 단계:
-
다음 경우
TypeError
를 발생시킵니다:
25. 기능 색인
25.1. "core-features-and-limits"
모든 핵심 WebGPU 기능과 제한을 사용할 수 있게 해줍니다.
참고: 현재 모든 어댑터에서 이용 가능하며, 요청하지 않아도 모든 디바이스에 자동으로 활성화됩니다.
25.2. "depth-clip-control"
깊이 클리핑을 비활성화할 수 있습니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운
GPUPrimitiveState
딕셔너리 멤버:
25.3. "depth32float-stencil8"
"depth32float-stencil8"
포맷의 텍스처를 명시적으로 생성할 수 있습니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운
GPUTextureFormat
열거형 값:
25.4. "texture-compression-bc"
BC 압축 포맷의 텍스처를 명시적으로 생성할 수 있습니다. 여기에는 "S3TC", "RGTC", "BPTC" 포맷이 포함됩니다. 2D 텍스처만 지원합니다.
참고: "texture-compression-bc"
를 지원하는 어댑터가 항상 "texture-compression-bc-sliced-3d"
를 지원하는 것은 아닙니다.
"texture-compression-bc-sliced-3d"
를 사용하려면,
"texture-compression-bc"
를 명시적으로 활성화해야 하며, 이 기능 자체로는 BC 포맷이 활성화되지 않습니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운
GPUTextureFormat
열거형 값:
25.5. "texture-compression-bc-sliced-3d"
BC 압축 포맷 텍스처에 대해 3d
차원을 사용할 수 있습니다.
참고: "texture-compression-bc"
를 지원하는 어댑터가 항상 "texture-compression-bc-sliced-3d"
를 지원하는 것은 아닙니다.
"texture-compression-bc-sliced-3d"
를 사용하려면,
"texture-compression-bc"
를 명시적으로 활성화해야 하며, 이 기능 자체로는 BC 포맷이 활성화되지 않습니다.
이 기능은 선택적 API 표면을 추가하지 않습니다.
25.6. "texture-compression-etc2"
ETC2 압축 포맷의 텍스처를 명시적으로 생성할 수 있습니다. 2D 텍스처만 지원합니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운
GPUTextureFormat
열거형 값:
25.7. "texture-compression-astc"
ASTC 압축 포맷의 텍스처를 명시적으로 생성할 수 있습니다. 2D 텍스처만 지원합니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운
GPUTextureFormat
열거형 값:
25.8. "texture-compression-astc-sliced-3d"
ASTC 압축 포맷 텍스처에 대해 3d
차원을 사용할 수 있습니다.
참고: "texture-compression-astc"
를 지원하는 어댑터가 항상 "texture-compression-astc-sliced-3d"
를 지원하는 것은 아닙니다.
"texture-compression-astc-sliced-3d"
를 사용하려면,
"texture-compression-astc"
를 명시적으로 활성화해야 하며, 이 기능 자체로는 ASTC 포맷이 활성화되지 않습니다.
이 기능은 선택적 API 표면을 추가하지 않습니다.
25.9. "timestamp-query"
GPU 커맨드 버퍼에서 타임스탬프를 쿼리할 수 있는 기능을 추가합니다. § 20.4 타임스탬프 쿼리 참고.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운
GPUQueryType
값: -
새로운
GPUComputePassDescriptor
멤버: -
새로운
GPURenderPassDescriptor
멤버:
25.10. "indirect-first-instance"
indirect draw
parameters 및
indirect drawIndexed parameters에서 0이 아닌
firstInstance
값을 사용할 수 있습니다.
이 기능은 선택적 API 표면을 추가하지 않습니다.
25.11.
"shader-f16"
WGSL에서 반정밀도 부동소수점 타입 f16을 사용할 수 있습니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운 WGSL 확장:
25.12. "rg11b10ufloat-renderable"
RENDER_ATTACHMENT
용도로 "rg11b10ufloat"
포맷의 텍스처를 사용할 수 있으며, 해당 포맷의 텍스처에 블렌딩, 멀티샘플링, 리졸브도 가능합니다.
이 기능은 선택적 API 표면을 추가하지 않습니다.
"texture-formats-tier1"
를 디바이스 생성 시 활성화하면
"rg11b10ufloat-renderable"
도 활성화됩니다.
25.13. "bgra8unorm-storage"
STORAGE_BINDING
용도로 "bgra8unorm"
포맷의 텍스처를 사용할 수 있습니다.
이 기능은 선택적 API 표면을 추가하지 않습니다.
25.14. "float32-filterable"
"r32float"
,
"rg32float"
,
"rgba32float"
포맷의 텍스처를 필터링 가능하게 만듭니다.
25.15. "float32-blendable"
"r32float"
,
"rg32float"
,
"rgba32float"
포맷의 텍스처를 블렌딩 가능하게 만듭니다.
25.16. "clip-distances"
WGSL에서 clip_distances를 사용할 수 있습니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운 WGSL 확장:
25.17. "dual-source-blending"
WGSL에서 blend_src를 사용할 수 있으며, 동시에 두 개의 픽셀 셰이더
출력(@blend_src(0)
와 @blend_src(1)
)을 색상 어태치먼트 0에 대한 블렌딩 연산의 입력으로 사용할 수 있습니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
아래
GPUBlendFactor
를 사용할 수 있습니다: -
새로운 WGSL 확장:
25.18.
"subgroups"
WGSL에서 subgroup 및 quad 연산을 사용할 수 있습니다.
이 기능은 선택적 API
표면을 추가하지 않지만, 어댑터에서 이 기능을 사용할 수 있을 때 아래 GPUAdapterInfo
엔트리들이 실제 값을 노출합니다:
-
새로운 WGSL 확장:
25.19. "texture-formats-tier1"
아래 새로운 GPUTextureFormat
을
RENDER_ATTACHMENT
,
블렌딩 가능, 멀티샘플링
기능과 STORAGE_BINDING
기능을 "read-only"
및 "write-only"
GPUStorageTextureAccess
로
지원합니다:
아래 GPUTextureFormat
에
RENDER_ATTACHMENT
,
블렌딩 가능, 멀티샘플링
,
리졸브
기능을 지원합니다:
아래 GPUTextureFormat
에
대해 "read-only"
또는 "write-only"
GPUStorageTextureAccess
를
지원합니다:
디바이스 생성 시 "texture-formats-tier2"
를
활성화하면
"texture-formats-tier1"
도
활성화됩니다.
디바이스 생성 시 "texture-formats-tier1"
를
활성화하면
"rg11b10ufloat-renderable"
도
활성화됩니다.
25.20. "texture-formats-tier2"
아래 GPUTextureFormat
에
대해 "read-write"
GPUStorageTextureAccess
를
지원합니다:
디바이스 생성 시 "texture-formats-tier2"
를
활성화하면
"texture-formats-tier1"
도
활성화됩니다.
25.21. "primitive-index"
WGSL에서 primitive_index를 사용할 수 있습니다.
이 기능은 다음 선택적 API 표면을 추가합니다:
-
새로운 WGSL 확장:
26. 부록
26.1. 텍스처 포맷 기능
26.1.1. 일반 색상 포맷
모든 지원되는 일반 색상 포맷은
COPY_SRC
,
COPY_DST
,
TEXTURE_BINDING
사용과, "3d"
차원을 지원합니다.
RENDER_ATTACHMENT
및 STORAGE_BINDING
열은 각각 GPUTextureUsage.RENDER_ATTACHMENT
및 GPUTextureUsage.STORAGE_BINDING
사용 지원 여부를 나타냅니다.
렌더 타겟 픽셀 바이트
비용과
렌더 타겟 컴포넌트
정렬은
maxColorAttachmentBytesPerSample
제한을 검증하는 데 사용됩니다.
참고: 각 포맷의 텍셀 블록 메모리 비용은 텍셀 블록 복사 풋프린트와 동일합니다.
26.1.2. 깊이-스텐실 포맷
깊이 또는 스텐실 포맷은 깊이와/또는 스텐실 aspect가 있는 모든 포맷입니다. 복합 깊이-스텐실 포맷은 깊이 또는 스텐실 포맷 중 깊이와 스텐실 aspect가 모두 있는 포맷을 말합니다.
모든 깊이 또는 스텐실
포맷은 COPY_SRC
,
COPY_DST
,
TEXTURE_BINDING
,
RENDER_ATTACHMENT
사용을 지원합니다.
이들 포맷은 모두 멀티샘플링을 지원합니다.
단, 특정 복사 작업은 소스와 대상 포맷에 제한이 있고, 이들 포맷은 "3d"
차원의 텍스처를 지원하지 않습니다.
깊이 텍스처는 "filtering"
샘플러와 함께 사용할 수 없지만,
"comparison"
샘플러(필터링을 사용하는 경우에도)와는 항상 사용할 수 있습니다.
포맷 |
참고:
텍셀
블록 메모리 비용 (바이트)
| Aspect | GPUTextureSampleType
| 유효한 텍셀 복사 소스 | 유효한 텍셀 복사 대상 | 텍셀 블록 복사 풋프린트 (바이트) | Aspect별 포맷 |
---|---|---|---|---|---|---|---|
stencil8
| 1 − 4 | 스텐실 | "uint"
| ✓ | 1 | stencil8
| |
depth16unorm
| 2 | 깊이(depth) | "depth" ,
"unfilterable-float"
| ✓ | 2 | depth16unorm
| |
depth24plus
| 4 | 깊이(depth) | "depth" ,
"unfilterable-float"
| ✗ | – | depth24plus
| |
depth24plus-stencil8
| 4 − 8 | 깊이(depth) | "depth" ,
"unfilterable-float"
| ✗ | – | depth24plus
| |
스텐실 | "uint"
| ✓ | 1 | stencil8
| |||
depth32float
| 4 | 깊이(depth) | "depth" ,
"unfilterable-float"
| ✓ | ✗ | 4 | depth32float
|
depth32float-stencil8
| 5 − 8 | 깊이(depth) | "depth" ,
"unfilterable-float"
| ✓ | ✗ | 4 | depth32float
|
스텐실 | "uint"
| ✓ | 1 | stencil8
|
24비트 깊이란 0.0~1.0 범위의 24비트 부호 없는 정규화된 깊이 포맷을 의미하며, 노출될 경우 "depth24unorm"으로 표기됩니다.
26.1.2.1. 깊이/스텐실 텍스처 읽기 및 샘플링
가능한 것은, depth aspect의 GPUTextureView
를
texture_depth_*
바인딩이나, 다른 depth가 아닌 2d/cube 텍스처 타입 바인딩에 연결하는 것입니다.
스텐실 aspect의 GPUTextureView
는
반드시 일반 텍스처 바인딩 타입에 연결해야 합니다.
sampleType
은
GPUBindGroupLayout
에서
"uint"
이어야
합니다.
텍스처의 깊이 또는 스텐실 aspect를 읽거나 샘플링하면, 해당 텍스처는 (V, X, X, X)
형식의 값을 가진 것으로 동작합니다. 여기서 V는 실제 깊이 또는 스텐실
값이고, 각 X는 구현 정의의 미정 값입니다.
depth aspect 바인딩의 경우, 미정 값은 texture_depth_*
타입 바인딩에서는 보이지 않습니다.
tex
에 texture_2d<f32>
타입으로 바인딩되어 있다면:
-
textureSample(tex, ...)
은vec4<f32>(D, X, X, X)
를 반환합니다. -
textureGather(0, tex, ...)
은vec4<f32>(D1, D2, D3, D4)
를 반환합니다. -
textureGather(2, tex, ...)
은vec4<f32>(X1, X2, X3, X4)
를 반환합니다 (완전히 미정 값).
참고:
depth와 같이 더 제한적인 스텐실 샘플러 타입을 추가하지 않는 이상, 구현에서 depth/stencil 읽기를 드라이버 차이를 효율적으로 감추기는 불가능합니다.
WebGL에서는 이식성 문제점이 없었으므로, WebGPU에서도 문제가 될 것으로 예상되지 않습니다.
실제로는, 하드웨어에 따라 (V, V, V, V)
또는 (V, 0, 0, 1)
(여기서 V
는 깊이 또는 스텐실 값) 중 하나가
될 수 있습니다.
26.1.2.2. 깊이/스텐실 텍스처 복사
depth32float 포맷의 깊이 aspect
("depth32float"
및 "depth32float-stencil8"
)는 범위가 제한되어 있습니다.
따라서 이런 텍스처로의 복사는 동일한 포맷의 다른 텍스처에서만 유효합니다.
depth24plus 포맷의 깊이 aspect
("depth24plus"
및 "depth24plus-stencil8"
)
는 불투명하게 표현됩니다(내부적으로 24비트 깊이 또는
"depth32float"
로
구현됨).
따라서 depth aspect의 텍셀 복사는 이 포맷에서는
허용되지 않습니다.
-
이 포맷들은 모두 프래그먼트 셰이더에서
frag_depth
출력으로 깊이 값을 출력하는 렌더 패스에서 기록할 수 있습니다. -
"depth24plus" 포맷의 텍스처는 셰이더 텍스처로 읽고, 렌더 패스 어태치먼트로 텍스처에 기록하거나, 컴퓨트 셰이더의 storage buffer 바인딩을 통해 버퍼에 기록할 수 있습니다.
26.1.3. 패킹 포맷
모든 패킹 텍스처 포맷은 COPY_SRC
,
COPY_DST
,
TEXTURE_BINDING
사용을 지원합니다.
이들 포맷은 모두 필터링 가능합니다.
이들 포맷은 렌더링 가능하지 않으며 멀티샘플링도 지원하지
않습니다.
압축 포맷은 블록 크기가 1×1보다 큰 모든 포맷입니다.
참고: 각 포맷의 텍셀 블록 메모리 비용은 텍셀 블록 복사 풋프린트와 동일합니다.