흐름 제어 제한

픽셀 셰이더 흐름 제어 명령에는 명령에 포함될 수 있는 중첩 수준 수에 영향을 미치는 제한이 있습니다. 또한 그라데이션 명령으로 픽셀당 흐름 제어를 구현하는 데는 몇 가지 제한 사항이 있습니다.

참고

*_4_0_level_9_x HLSL 셰이더 프로필을 사용하는 경우 셰이더 모델 2.x 프로필을 암시적으로 사용하여 Direct3D 9 가능 하드웨어를 지원합니다. 셰이더 모델 2.x 프로필은 셰이더 모델 4.x 이상 프로필보다 더 제한된 흐름 제어 동작을 지원합니다.

 

픽셀 셰이더 명령 깊이 개수

ps_2_0은 흐름 제어를 지원하지 않습니다. 다른 픽셀 셰이더 버전에 대한 제한 사항은 다음과 같습니다.

ps_2_x에 대한 명령 깊이 개수

각 명령은 하나 이상의 중첩 깊이 제한에 대해 계산됩니다. 다음 표는 각 명령이 기존 깊이에서 더하거나 빼는 깊이 수를 보여줍니다.

명령 정적 중첩 동적 중첩 루프/반복 중첩 호출 중첩
if bool - ps 1 0 0 0
if_comp - ps 0 1 0 0
if pred - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(if pred - ps 또는 if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
call - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

중첩 깊이

중첩 깊이는 서로 내부에서 호출할 수 있는 명령 수를 정의합니다. 각 명령 유형에는 다음 표에 표시된 대로 하나 이상의 중첩 제한이 있습니다.

명령 형식 최대
정적 중첩 24 if(D3DCAPS9.D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); 0 otherwise
동적 중첩 0~24, see D3DCAPS9.D3DPSHADERCAPS2_0.DynamicFlowControlDepth
rep 중첩 0~4, see D3DCAPS9.D3DPSHADERCAPS2_0.StaticFlowControlDepth
호출 중첩 0~4, see D3DCAPS9.D3DPSHADERCAPS2_0.StaticFlowControlDepth(rep 제한과 무관)

 

ps_2_sw에 대한 명령 깊이 개수

각 명령은 하나 이상의 중첩 깊이 제한에 대해 계산됩니다. 이 표는 각 명령이 기존 깊이에서 더하거나 빼는 깊이 수를 보여 줍니다.

명령 정적 중첩 동적 중첩 루프/반복 중첩 호출 중첩
if bool - ps 1 0 0 0
if pred - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(if pred - ps 또는 if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
loop - ps 해당 없음 해당 없음 해당 없음 해당 없음
endloop - ps 해당 없음 해당 없음 해당 없음 해당 없음
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
call - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

중첩 깊이

중첩 깊이는 서로 내부에서 호출할 수 있는 명령 수를 정의합니다. 각 명령 유형에는 다음 표에 표시된 대로 하나 이상의 중첩 제한이 있습니다.

명령 형식 최대
정적 중첩 24
동적 중첩 24
rep 중첩 4
호출 중첩 4

 

ps_3_0에 대한 명령 깊이 개수

각 명령은 하나 이상의 중첩 깊이 제한에 대해 계산됩니다. 이 표는 각 명령이 기존 깊이에서 더하거나 빼는 깊이 수를 보여 줍니다.

명령 정적 중첩 동적 중첩 루프/반복 중첩 호출 중첩
if bool - ps 1 0 0 0
if pred - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(if pred - ps 또는 if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
loop - ps 0 0 1 0
endloop - ps 0 0 -1 0
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
call - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

중첩 깊이

중첩 깊이는 서로 내부에서 호출할 수 있는 명령 수를 정의합니다. 각 명령 유형에는 다음 표에 표시된 대로 하나 이상의 중첩 제한이 있습니다.

명령 형식 최대
정적 중첩 24
동적 중첩 24
루프/반복 중첩 4
호출 중첩 4

 

ps_3_sw에 대한 명령 깊이 개수

각 명령은 하나 이상의 중첩 깊이 제한에 대해 계산됩니다. 이 표는 각 명령이 기존 깊이에서 더하거나 빼는 깊이 수를 보여 줍니다.

명령 정적 중첩 동적 중첩 루프/반복 중첩 호출 중첩
if bool - ps 1 0 0 0
if pred - ps 0 1 0 0
if_comp - ps 0 1 0 0
else - ps 0 0 0 0
endif - ps -1(if bool - ps) -1(if pred - ps 또는 if_comp - ps) 0 0
rep - ps 0 0 1 0
endrep - ps 0 0 -1 0
loop - ps 0 0 1 0
endloop - ps 0 0 -1 0
break - ps 0 0 0 0
break_comp - ps 0 1, -1 0 0
breakp - ps 0 0 0 0
call - ps 0 0 0 1
callnz bool - ps 0 0 0 1
callnz pred - ps 0 1 0 1
ret - ps 0 -1(callnz pred - ps) 0 -1
setp_comp - ps 0 0 0 0

 

중첩 깊이

중첩 깊이는 서로 내부에서 호출할 수 있는 명령 수를 정의합니다. 각 명령 유형에는 다음 표에 표시된 대로 하나 이상의 중첩 제한이 있습니다.

명령 형식 최대
정적 중첩 24
동적 중첩 24
루프/반복 중첩 4
호출 중첩 4

 

픽셀당 흐름 제어와 스크린 그라데이션의 상호 작용

픽셀 셰이더 명령 집합에는 화면 공간 x 및 y에 대한 양의 그라데이션을 생성하거나 사용하는 여러 명령이 포함되어 있습니다. 그라데이션 항목의 가장 흔한 용도는 텍스처 샘플링을 위한 LOD(level-of-detail) 계산을 하고, 이방성 필터링의 경우에는 이방성 축을 따라 샘플을 선택하는 것입니다. 일반적으로 하드웨어 구현은 여러 픽셀(예: 2x2 그리드)에서 동시에 하나의 픽셀 셰이더를 실행하므로 픽셀 셰이더에서 계산되는 수량 그라데이션 항목은 인접 픽셀의 동일한 실행 지점에서 값의 델타로 합리적으로 어림잡을 수 있습니다.

셰이더에 흐름 제어가 있는 경우 인접한 픽셀이 별도의 흐름 제어 경로를 실행할 수 있는 경우 지정된 분기 경로 내에서 요청된 그라데이션 계산 결과가 모호합니다. 따라서 래스터화되는 지정된 기본 형식에 대해 픽셀 간에 다를 수 있는 흐름 제어 구문 내부의 위치에서 발생하도록 그라데이션 계산을 요청하는 픽셀 셰이더 작업을 사용하는 것은 불법으로 간주됩니다.

모든 픽셀 셰이더 명령은 흐름 제어 내에서 허용되는 작업과 허용되지 않는 작업으로 분할됩니다.

  • 시나리오 A: 기본 형식의 픽셀에 따라 다를 수 있는 흐름 제어 내부에서 허용되지 않는 작업. 다음 표에 나열된 작업이 여기에 포함되어 있습니다.

    명령 다음과 같은 경우 흐름 제어에서 허용됩니다.
    texld - ps_2_0 and up, texldb - ps, texldp - ps 텍스처 좌표에는 임시 레지스터가 사용됩니다.
    dsx - ps, dsy - ps 피연산자에는 임시 레지스터가 사용됩니다.

     

  • 시나리오 B: 어디에서나 허용되는 작업입니다. 다음 표에 나열된 작업이 여기에 포함되어 있습니다.

    명령 다음과 같은 경우 어디에서나 허용됩니다.
    texld - ps_2_0 and up, texldb - ps, texldp - ps 읽기 전용 수량은 텍스처 좌표에 사용됩니다(보간된 텍스처 좌표와 같이 픽셀별로 다를 수 있음).
    dsx - ps, dsy - ps 읽기 전용 수량은 입력 피연산자에 사용됩니다(보간된 텍스처 좌표와 같이 픽셀별로 다를 수 있음).
    texldl - ps 사용자가 세부 수준을 인수로 제공하여 그라데이션이 없으므로 흐름 제어에 문제가 없습니다.
    texldd - ps 사용자가 그라데이션을 입력 인수로 제공하므로 흐름 제어에 문제가 없습니다.

     

이러한 제한 사항은 셰이더 유효성 검사에서 엄격하게 적용됩니다. 조건 표현식의 피연산자가 픽셀 셰이더 계산 수량임에도 불구하고 여전히 기본 형식에 걸쳐 일관되게 분기하는 것처럼 보이는 분기 조건이 있는 시나리오는 여전히 시나리오 A에 속하며 허용되지 않습니다. 마찬가지로, 동적 흐름 제어 내부에서 일부 셰이더 계산 수량 x에 대한 그라데이션이 요청되는데, x는 어떤 분기에서도 수정되지 않은 것으로 보이지만 그럼에도 불구하고 여전히 시나리오 A에 속하며 허용되지 않는 시나리오입니다.

술어는 흐름 제어에 대한 이러한 제한 사항에 포함되어 있으므로 구현에서 술어가 있는 명령으로 분기 명령의 구현을 사소하게 교환할 수 있습니다.

사용자는 시나리오 A와 B의 명령을 함께 사용할 수 있습니다. 예를 들어 셰이더가 계산한 텍스처 좌표가 지정된 이방성 텍스처 샘플이 사용자에게 필요하다고 가정합니다. 그러나 텍스처 로드는 일부 픽셀당 조건을 만족하는 픽셀에만 필요합니다. 이러한 요구 사항을 충족하기 위해 사용자는 dsx - psdsy - ps 명령을 사용하여 즉시 그라데이션을 계산하고 픽셀당 가변 흐름 제어 외부의 모든 픽셀에 대한 텍스처 좌표를 계산할 수 있습니다. 그런 다음 픽셀당 if bool - ps/endif - ps 블록 내에서 사용자는 texldd - ps를 사용하여(사용자가 제공한 그라데이션으로 텍스처 로드), 미리 계산된 그라데이션을 전달할 수 있습니다. 이 사용 패턴을 설명하는 또 한 가지 방법은 기본 형식의 모든 픽셀이 텍스처 좌표를 계산하고 그라데이션 계산에 참여해야 했지만 실제로는 텍스처를 샘플링하는 데 필요한 픽셀만 그렇게 했다는 것입니다.

이러한 규칙에 관계없이 사용자는 그라데이션을 계산하기 전에(또는 암시적으로 그라데이션을 계산하는 텍스처 샘플을 수행하기 전에) 소스 데이터를 포함하는 레지스터가 모든 실행 경로에 대해 미리 초기화되었는지 확인해야 합니다. 임시 레지스터의 초기화는 일반적으로 유효성이 검사되거나 적용되지 않습니다.

픽셀 셰이더 명령