Limitaciones del control de flujo

Las instrucciones de control de flujo del sombreador de píxeles tienen límites que afectan al número de niveles de anidamiento que se pueden incluir en las instrucciones. Además, hay algunas limitaciones para implementar el control de flujo por píxel con instrucciones de degradado.

Nota

Cuando usas los perfiles de sombreador *_4_0_level_9_x HLSL, usas implícitamente los perfiles del modelo de sombreador 2.x para admitir hardware compatible con Direct3D 9. Los perfiles del modelo de sombreador 2.x admiten un comportamiento de control de flujo más limitado que el modelo de sombreador 4.x y los perfiles posteriores.

 

Recuentos de profundidad de instrucción del sombreador de píxeles

ps_2_0 no admite el control de flujo. A continuación se enumeran las limitaciones de las otras versiones del sombreador de píxeles.

Recuento de profundidad de instrucciones para ps_2_x

Cada instrucción cuenta con uno o varios límites de profundidad de anidamiento. En la tabla siguiente se muestra el recuento de profundidad que cada instrucción agrega o resta de la profundidad existente.

Instrucción Anidamiento estático Anidamiento dinámico anidamiento de bucle/rep anidamiento de llamadas
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(si está pred - ps o 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

 

Profundidad de anidamiento

La profundidad de anidamiento define el número de instrucciones que se pueden llamar entre sí. Cada tipo de instrucción tiene uno o más límites de anidamiento, como se indica en la tabla siguiente.

Tipo de instrucción Máximo
Anidamiento estático 24 si (D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); 0 de lo contrario
Anidamiento dinámico De 0 a 24, consulte D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth
anidamiento de rep De 0 a 4, consulte D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth
anidamiento de llamadas De 0 a 4, consulte D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (independiente del límite de rep)

 

Recuento de profundidad de instrucciones para ps_2_sw

Cada instrucción cuenta con uno o varios límites de profundidad de anidamiento. En esta tabla se muestra el recuento de profundidad que cada instrucción agrega o resta de la profundidad existente.

Instrucción Anidamiento estático Anidamiento dinámico anidamiento de bucle/rep anidamiento de llamadas
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(si está pred - ps o 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

 

Profundidad de anidamiento

La profundidad de anidamiento define el número de instrucciones a las que se puede llamar entre sí. Cada tipo de instrucción tiene uno o varios límites de anidamiento, como se indica en la tabla siguiente.

Tipo de instrucción Máximo
Anidamiento estático 24
Anidamiento dinámico 24
anidamiento de repetición 4
anidamiento de llamadas 4

 

Recuento de profundidad de instrucciones para ps_3_0

Cada instrucción cuenta con uno o varios límites de profundidad de anidamiento. En esta tabla se muestra el recuento de profundidad que cada instrucción agrega o resta de la profundidad existente.

Instrucción Anidamiento estático Anidamiento dinámico anidamiento de bucles o rep anidamiento de llamadas
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(si está pred - ps o 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

 

Profundidad de anidamiento

La profundidad de anidamiento define el número de instrucciones a las que se puede llamar entre sí. Cada tipo de instrucción tiene uno o varios límites de anidamiento, como se indica en la tabla siguiente.

Tipo de instrucción Máximo
Anidamiento estático 24
Anidamiento dinámico 24
anidamiento de bucles o rep 4
anidamiento de llamadas 4

 

Recuento de profundidad de instrucciones para ps_3_sw

Cada instrucción cuenta con uno o varios límites de profundidad de anidamiento. En esta tabla se muestra el recuento de profundidad que cada instrucción agrega o resta de la profundidad existente.

Instrucción Anidamiento estático Anidamiento dinámico anidamiento de bucles o rep anidamiento de llamadas
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(si está pred - ps o 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

 

Profundidad de anidamiento

La profundidad de anidamiento define el número de instrucciones que se pueden llamar entre sí. Cada tipo de instrucción tiene uno o más límites de anidamiento, como se indica en la tabla siguiente.

Tipo de instrucción Máximo
Anidamiento estático 24
Anidamiento dinámico 24
anidamiento de bucle/rep 4
anidamiento de llamadas 4

 

Interacción del control de flujo de Per-Pixel con degradados de pantalla

El conjunto de instrucciones del sombreador de píxeles incluye varias instrucciones que producen o usan degradados de cantidades con respecto al espacio de pantalla x e y. El uso más común para los degradados es calcular cálculos de nivel de detalle para el muestreo de texturas y, en el caso del filtrado anisotrópico, seleccionando muestras a lo largo del eje de anisotropía. Normalmente, las implementaciones de hardware ejecutan el sombreador de píxeles en varios píxeles simultáneamente (como una cuadrícula de 2x2), de modo que los degradados de las cantidades calculadas en el sombreador se puedan aproximar razonablemente como deltas de los valores en el mismo punto de ejecución en píxeles adyacentes.

Cuando el control de flujo está presente en un sombreador, el resultado de un cálculo de degradado solicitado dentro de una ruta de acceso de rama determinada es ambiguo cuando los píxeles adyacentes pueden ejecutar rutas de control de flujo independientes. Por lo tanto, se considera ilegal usar cualquier operación de sombreador de píxeles que solicite que se produzca un cálculo de degradado en una ubicación dentro de una construcción de control de flujo que podría variar en píxeles para un primitivo determinado que se rasteriza.

Todas las instrucciones del sombreador de píxeles se dividen en las operaciones permitidas y en las que no están permitidas dentro del control de flujo:

  • Escenario A: Operaciones que no están permitidas dentro del control de flujo que podrían variar entre los píxeles de un primitivo. Entre ellas se incluyen las operaciones enumeradas en la tabla siguiente.

    Instrucción Se permite en el control de flujo cuando:
    texld : ps_2_0 y arriba, texldb - ps y texldp - ps Se usa un registro temporal para la coordenada de textura.
    dsx - ps y dsy - ps Se usa un registro temporal para el operando.

     

  • Escenario B: Operaciones permitidas en cualquier lugar. Entre ellas se incluyen las operaciones enumeradas en la tabla siguiente.

    Instrucción Se permite en cualquier lugar cuando:
    texld : ps_2_0 y arriba, texldb - ps y texldp - ps Se usa una cantidad de solo lectura para la coordenada de textura (puede variar por píxel, como las coordenadas de textura interpoladas).
    dsx - ps y dsy - ps Se usa una cantidad de solo lectura para el operando de entrada (puede variar por píxel, como las coordenadas de textura interpoladas).
    texldl - ps El usuario proporciona el nivel de detalle como argumento, por lo que no hay degradados y, por tanto, no hay ningún problema con el control de flujo.
    texldd - ps El usuario proporciona degradados como argumentos de entrada, por lo que no hay ningún problema con el control de flujo.

     

Estas restricciones se aplican estrictamente en la validación del sombreador. Los escenarios que tienen una condición de rama similar a la que se bifurcaría de forma coherente en un primitivo, aunque un operando de la expresión de condición es una cantidad calculada por sombreador de píxeles, sin embargo, todavía se encuentra en el escenario A y no se permite. Del mismo modo, los escenarios en los que se solicitan degradados en alguna cantidad calculada por sombreador x desde el control de flujo dinámico, pero donde parece que x no se modifica en ninguna de las ramas, sin embargo, todavía se encuentran en el escenario A y no se permiten.

El predicado se incluye en estas restricciones sobre el control de flujo, por lo que las implementaciones siguen siendo libres de intercambiar trivialmente la implementación de instrucciones de rama con instrucciones predeterificadas.

El usuario puede usar instrucciones de los escenarios A y B juntos. Por ejemplo, supongamos que el usuario necesita una muestra de textura anisotrópica dada una coordenada de textura calculada del sombreador; sin embargo, la carga de textura solo es necesaria para píxeles que satisfacen alguna condición por píxel. Para cumplir estos requisitos, el usuario puede calcular la coordenada de textura para todos los píxeles, fuera del control de flujo variable por píxel, calculando inmediatamente los degradados mediante las instrucciones dsx - ps y dsy - ps . A continuación, dentro de un bloque bool - psendif - ps/, el usuario puede usar texldd - ps (carga de textura con degradados proporcionados por el usuario), pasando los degradados precalculados. Otra manera de describir este patrón de uso es que, mientras que todos los píxeles del primitivo tenían que calcular las coordenadas de textura y estar implicados en el cálculo de degradado, solo los píxeles necesarios para muestrear una textura realmente lo hicieron.

Independientemente de estas reglas, la carga sigue en el usuario para asegurarse de que antes de calcular cualquier degradado (o realizar una muestra de textura que calcula implícitamente un degradado), el registro que contiene los datos de origen debe haberse inicializado para todas las rutas de acceso de ejecución de antemano. La inicialización de registros temporales no se valida ni se aplica en general.

Instrucciones del sombreador de píxeles