Optix 7 - Shader binding table

선비Sunbei·2023년 8월 28일
0

OptiX

목록 보기
8/25
https://raytracing-docs.nvidia.com/optix7/guide/index.html#shader_binding_table#shader-binding-table

shader binding table(SBT)는 program 및 해당 파라미터의 위치에 대한 정보를 포함하는 배열이다. SBT는 device memoryㅇ네 있으며 Application에서 관리한다.

7.1 Records

record는 헤더와 데이터 블록으로 구성된 SBT의 배열 요소이다.
header의 contents는 Application에서 opaque하며, program을 식별하고 호출하기 위해 traversal 실행에 의해 액세스되는 정보를 포함한다. 데이터 블록은 OptiX에서 사용되지 않으며 program에서 액세스할 수 있는 임의의 program별 Application 정보를 보유한다. 헤더 크기는 OPTIX_SBT_RECORD_HEADER_SIZE 매크로에 의해 정의된다. (현재 32byte)

API 함수 optixSbtRecordPackHeader와 지정된 OptixProgramGroup 객체는 SBT record의 헤더를 채우는데 사용된다. SBT record는 OptiX를 실행하기 전에 device에 업로드 해야 된다. SBT header 내용은 opaque하지만, 복사하거나 이동할 수 있다. 동일한 program group이 두 개 이상의 SBT record에 사용되는 경우 일반 device 측 메모리 복사본을 사용하여 SBT 헤더를 복사할 수 있다.

Module과 program group 간에 컴파일 옵션이 일치하는 한 SBT header는 pipeline 간에 재사용할 수 있다. SBT record의 데이터 section은 optixGetDataPointer device function을 사용하여 device에서 액세스할 수 있다.

7.2 Layout

SBT은 5개의 section으로 나뉘며, 각 section은 고유한 program group 유형을 나타낸다.

SBT section에 대한 포인터는 OptiX launch로 전달된다.

device의 모든 SBT record는 OPTIX_SBT_RECORD_ALGNMENT (현재 16byte)에 의해 정의된 최소 메모리 정렬을 가져야 한다. 따라서 record 사이의 간격도 OPTIX_SBT_RECORD_ALIGNMENT의 배수여야 한다. SBT의 각 section은 독립적인 메모리 범위이며 연속적으로 할당될 필요는 없다.

SBT record의 선택은 program type에 따라 다르며 해당 base pointer를 사용한다. ray-generation, exception program 모두에 대해 한 번만 호출할 수 있으므로 이 두 program group type에는 stride가 필요하지 않으며 전달된 pointer는 원하는 SBT record를 가리킨다.

다른 type의 경우, group-type의 program group에 대한 sbt-index의 record는 다음 공식으로 찾을 수 있다.

예를들어 miss group의 3번째 record(index 2)는 다음과 같다.

SBT의 record에 대한 index는 miss, hit, collables groups에 따라 다른 방식으로 사용된다.

  • Miss
    miss program은 missSBTIndex 매개 변수를 사용하여 모든 optixTrace 호출에 대해 선택된다.
  • Callables
    Callable은 index를 매개변수로 사용하여 optixDirectCall을 호출할 때는 직접 direct-callable을, optixContinuationCall을 호출할 대는 continuation-callable을 호출한다.
  • Any-hit, closest-hit, intersection
    hit group(intersection, any-hit, closest-hit)에 대한 index 계산은 traverse 중에 수행된다.

7.3 Acceleration Structures

instance에 대한 SBT hit group record의 선택은 다양한 ray type과 같은 여러 사용 사례를 허용하기 위해 약간 더 복잡하다. SBT record index sbtIndex는 traverse 중에 다음 index 계산에 의해 결정된다.

index 계산은 SBT index와 offset에 따라 달라진다.

7.3.1 SBT instance offset

instance acceleration structure(type OptixInstance)는 traverse 중에 적용되는 SBT offset을 저장한다. 값을 보유할 해당 instance AS가 없기 때문에 단일 GAS traversable의 경우 이 값은 0이다. 이 값은 28bit로 제한된다.(OptixInstance::sbtOffset의 선언 참조)

7.3.2 SBT geometry-AS index

각 GAS build input은 적어도 하나의 SBT record를 참조한다. 각 GAS build input에 대한 첫 번째 SBT GAS index는 SBT 레코드 수의 접두사 합이다. 따라서 계산된 SBT GAS index는 build input 순서에 따라 달라진다.

다음 예제는 세 개의 build input이 있는 GAS를 보여준다.
각 build input은 numSBTRrecords=1을 지정하여 하나의 SBT 레코드를 참조한다. trace time에 geometry를 교차할 때 hit group record를 선택하기 위해 sbtIndex를 계산하는 데 사용되는 SBT GAS index는 다음과 같이 구성된다.

이 간단한 예제에서 build input에 대한 index는 SBT GAS index와 같다. 따라서 build input[1]의 primitive가 교차할 때 SBT GAS index는 1이 된다.

geometry당 여러 material을 지원하기 위해 단일 build input이 여러 SBT record를 참조하는 경우, mapping은 참조된 SBT record 수에 대한 접두사 합계에 해당한다.

예를 들어, 첫 번째 build input이 4개의 SBT record를 참조하고, 두 번째 입력이 1개의 SBT record를 참조하고, 마지막 입력이 2개의 SBT record를 참조하는 세 개의 build input을 생각해보자.

이 세가지 build input은 해당 GAS input과 교차할 때 다음과 같은 가능한 SBT GAS index를 생성한다.

  • Build input[0]의 primitive가 교차하는 경우 [0,3] 범위의 index 1개
  • Build input[1]의 primitive가 교차하는 경우 4의 인덱스 1개
  • Build input[2]의 primitive가 교차하는 경우 [5,6] 범위의 인덱스 1개

primitive 별 SBT index offset은 sbtIndexOffsetBuffer를 사용하여 지정한 대로 build input에 local이다.(?) 따라서 build input 0의 경우 [0,3] 범위의 primitive별 offset과 마지막 build input의 경우 [0,1] 범위의 offset은 다음과 같이 SBT GAS index에 매핑된다.

build input 1은 단일 SBT 레코드를 참조하므로 GAS build에 sbtIndexOffsetBuffer를 지정할 필요가 없다.

7.3.3 SBT trace offset

optixTrace 함수는 매개변수 SBToffset을 받아 이 특정 ray에 대한 SBT acces shift를 허용한다. 다양한 ray 유형을 구현하는데 필요하다.

7.3.4 SBT trace stride

index offset으로 정의된 매개변수 SBTstride에 optixTrace와 SBT GAS index가 곱해진다. 다양한 ray 유형을 구현하는데 필요하다.

7.3.5 Example SBT for a scene

이 예제에서는 SBT이 하나의 IAS와 동일한 GAS의 instance 두 개를 포함하는 간단한 씬에 대한 program을 선택을 구현하며, GAS에는 두 개의 build input이 있다.

첫 번째 build input은 단일 SBT record를 참조하고, 두 번째 input은 두 개의 SBT record를 참조한다. ray type에는 순방향 경로 추적용 광선과 shadow ray(다음 이벤트 추정)용 ray 두 가지가 있다. GAS의 두 instance는 동일한 GAS의 각 instance에서 material 변동을 허용하기 위해 서로 다른 Transform과 SBT offset을 갖는다. 따라서 SBT는 2개의 miss record와 12개의 hit group record(GAS의 경우 3, ray type은 IAS의 두 인스턴스에 대해 3개)를 보유해야 한다.

type 0의 ray 추적을 하려면(예> 경로 추적)

shadow ray는 조정된 sbtOffset과 missSBTIndex를 전달해야 한다.

예시와 같이 서로 다른 유형(ray-gen, miss, intersection 등)의 program group이 서로 인접할 필요는 없다. 앞서 설명한대로 각 program group의 첫 번째 record에 대한 포인터가 optixLaunch로 전달되므로 서로 다른 program group type의 record 사이에 SBT에서 임의의 간격을 둘 수 있다.

7.4 SBT record access on device

현재 실행 중인 program의 SBT data section에 액세스하려면 API 함수를 사용하여 해당 포인터를 요청한다.

일반적으로 이 포인터는 data section의 레이아웃을 나타내는 포인터로 캐스팅된다. 예를 들어, closest hit program의 경우 Application은 해당 closest hit program을 호출하는 데 사용된 SBT record와 연결된 데이터에 액세스할 수 있다.

program은 이 데이터를 효율적으로 읽기 위해 SBT data section의 정렬 제약 조건에 의존하는 것이 좋다.

0개의 댓글