Limitações de controle de fluxo

As instruções de controle de fluxo do sombreador de pixel têm limites que afetam quantos níveis de aninhamento podem ser incluídos nas instruções. Além disso, há algumas limitações para implementar o controle de fluxo por pixel com instruções de gradiente.

Observação

Ao usar os perfis de sombreador *_4_0_level_9_x HLSL, você usa implicitamente os perfis do Modelo de Sombreador 2.x para dar suporte ao hardware compatível com Direct3D 9. Os perfis do Modelo de Sombreador 2.x dão suporte a um comportamento de controle de fluxo mais limitado do que o Modelo de Sombreador 4.x e perfis posteriores.

 

Contagens de profundidade de instrução do sombreador de pixel

ps_2_0 não dá suporte ao controle de fluxo. As limitações para as outras versões do sombreador de pixel são listadas abaixo.

Contagem de profundidade de instrução para ps_2_x

Cada instrução conta com um ou mais limites de profundidade de aninhamento. A tabela a seguir lista a contagem de profundidade que cada instrução adiciona ou subtrai da profundidade existente.

Instrução Aninhamento estático Aninhamento dinâmico aninhamento de loop/rep aninhamento de chamadas
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(se for anterior - ps ou 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

 

Profundidade de aninhamento

A profundidade de aninhamento define o número de instruções que podem ser chamadas de dentro umas das outras. Cada tipo de instrução tem um ou mais limites de aninhamento, conforme indicado na tabela a seguir.

Tipo de instrução Máximo
Aninhamento estático 24 se (D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); Caso contrário, 0
Aninhamento dinâmico 0 a 24, consulte D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth
aninhamento de rep 0 a 4, consulte D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth
aninhamento de chamadas 0 a 4, consulte D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (independente do limite de representantes)

 

Contagem de profundidade de instrução para ps_2_sw

Cada instrução conta com um ou mais limites de profundidade de aninhamento. Esta tabela mostra a contagem de profundidade que cada instrução adiciona ou subtrai da profundidade existente.

Instrução Aninhamento estático Aninhamento dinâmico aninhamento de loop/rep aninhamento de chamadas
se 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 or if_comp - ps) 0 0
rep – ps 0 0 1 0
endrep - ps 0 0 -1 0
loop – ps n/d n/d n/d n/d
endloop - ps n/d n/d n/d n/d
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

 

Profundidade de aninhamento

A profundidade de aninhamento define o número de instruções que podem ser chamadas de dentro umas das outras. Cada tipo de instrução tem um ou mais limites de aninhamento, conforme indicado na tabela a seguir.

Tipo de instrução Máximo
Aninhamento estático 24
Aninhamento dinâmico 24
aninhamento de rep 4
aninhamento de chamadas 4

 

Contagem de profundidade de instrução para ps_3_0

Cada instrução conta com um ou mais limites de profundidade de aninhamento. Esta tabela mostra a contagem de profundidade que cada instrução adiciona ou subtrai da profundidade existente.

Instrução Aninhamento estático Aninhamento dinâmico aninhamento de loop/rep aninhamento de chamadas
se 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 or 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

 

Profundidade de aninhamento

A profundidade de aninhamento define o número de instruções que podem ser chamadas de dentro umas das outras. Cada tipo de instrução tem um ou mais limites de aninhamento, conforme indicado na tabela a seguir.

Tipo de instrução Máximo
Aninhamento estático 24
Aninhamento dinâmico 24
aninhamento de loop/rep 4
aninhamento de chamadas 4

 

Contagem de profundidade de instrução para ps_3_sw

Cada instrução conta com um ou mais limites de profundidade de aninhamento. Esta tabela mostra a contagem de profundidade que cada instrução adiciona ou subtrai da profundidade existente.

Instrução Aninhamento estático Aninhamento dinâmico aninhamento de loop/rep aninhamento de chamadas
se 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 or 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

 

Profundidade de aninhamento

A profundidade de aninhamento define o número de instruções que podem ser chamadas de dentro umas das outras. Cada tipo de instrução tem um ou mais limites de aninhamento, conforme indicado na tabela a seguir.

Tipo de instrução Máximo
Aninhamento estático 24
Aninhamento dinâmico 24
aninhamento de loop/rep 4
aninhamento de chamadas 4

 

Interação do controle de fluxo de Per-Pixel com gradientes de tela

O conjunto de instruções do sombreador de pixels inclui várias instruções que produzem ou usam gradientes de quantidades em relação ao espaço de tela x e y. O uso mais comum para gradientes é calcular cálculos de nível de detalhes para amostragem de textura e, no caso da filtragem anisotrópica, selecionando exemplos ao longo do eixo da anisotropia. Normalmente, as implementações de hardware executam o sombreador de pixels em vários pixels simultaneamente (como uma grade 2x2), de modo que os gradientes de quantidades computadas no sombreador possam ser razoavelmente aproximados como deltas dos valores no mesmo ponto de execução em pixels adjacentes.

Quando o controle de fluxo está presente em um sombreador, o resultado de um cálculo de gradiente solicitado dentro de um determinado caminho de ramificação é ambíguo quando pixels adjacentes podem executar caminhos de controle de fluxo separados. Portanto, é considerado ilegal usar qualquer operação de sombreador de pixel que solicite que um cálculo de gradiente ocorra em um local que esteja dentro de um constructo de controle de fluxo que possa variar entre pixels para um determinado primitivo sendo rasterizado.

Todas as instruções de sombreador de pixel são particionadas para as operações permitidas e para aquelas que não são permitidas dentro do controle de fluxo:

  • Cenário A: operações que não são permitidas dentro do controle de fluxo que podem variar entre os pixels em um primitivo. Elas incluem as operações listadas na tabela a seguir.

    Instrução É permitido no controle de fluxo quando:
    texld - ps_2_0 e para cima, texldb - ps e texldp - ps Um registro temporário é usado para a coordenada de textura.
    dsx - ps e dsy - ps Um registro temporário é usado para o operando.

     

  • Cenário B: operações permitidas em qualquer lugar. Elas incluem as operações listadas na tabela a seguir.

    Instrução É permitido em qualquer lugar quando:
    texld - ps_2_0 e para cima, texldb - ps e texldp - ps Uma quantidade somente leitura é usada para a coordenada de textura (pode variar por pixel, como coordenadas de textura interpolada).
    dsx - ps e dsy - ps Uma quantidade somente leitura é usada para o operando de entrada (pode variar por pixel, como coordenadas de textura interpoladas).
    texldl - ps O usuário fornece nível de detalhes como um argumento, portanto, não há gradientes e, portanto, nenhum problema com o controle de fluxo.
    texldd - ps O usuário fornece gradientes como argumentos de entrada, portanto, não há nenhum problema com o controle de fluxo.

     

Essas restrições são estritamente impostas na validação do sombreador. Cenários com uma condição de ramificação que parece que ele se ramificaria consistentemente em um primitivo, mesmo que um operando na expressão de condição seja uma quantidade computada por sombreador de pixels, no entanto, ainda se enquadra no cenário A e não é permitido. Da mesma forma, cenários em que os gradientes são solicitados em alguma quantidade computada por sombreador x de dentro do controle de fluxo dinâmico, mas onde parece que x não é modificado em nenhum dos branches, no entanto, ainda se enquadram no cenário A e não são permitidos.

A pré-indicação está incluída nessas restrições no controle de fluxo, de modo que as implementações permaneçam livres para alternar trivialmente a implementação de instruções de branch com instruções predefinidas.

O usuário pode usar instruções dos cenários A e B juntos. Por exemplo, suponha que o usuário precise de uma amostra de textura anisotrópica dada uma coordenada de textura computada do sombreador; no entanto, a carga de textura só é necessária para pixels que satisfazem alguma condição por pixel. Para atender a esses requisitos, o usuário pode calcular a coordenada de textura para todos os pixels, fora do controle de fluxo variável por pixel, computando imediatamente gradientes usando dsx - ps e dsy - instruções ps . Em seguida, dentro de um bloco se bool - ps/endif - ps block, o usuário pode usar texldd - ps (carga de textura com gradientes fornecidos pelo usuário), passando os gradientes pré-calculados. Outra maneira de descrever esse padrão de uso é que, embora todos os pixels no primitivo tivessem que calcular as coordenadas de textura e estar envolvidos com o cálculo do gradiente, apenas os pixels necessários para amostrar uma textura realmente o fizeram.

Independentemente dessas regras, a carga ainda está sobre o usuário para garantir que antes de calcular qualquer gradiente (ou executar um exemplo de textura que compute implicitamente um gradiente), o registro que contém os dados de origem deve ter sido inicializado para todos os caminhos de execução de antemão. A inicialização de registros temporários não é validada ou imposta em geral.

Instruções de sombreador de pixel