Ограничения управления потоком

Инструкции по управлению потоком шейдера пикселей имеют ограничения, влияющие на количество уровней вложения, которые могут быть включены в инструкции. Кроме того, существуют некоторые ограничения для реализации управления потоком для каждого пикселя с помощью инструкций градиента.

Примечание

При использовании профилей шейдеров *_4_0_level_9_x HLSL вы неявно используете профили модели шейдера 2.x для поддержки оборудования с поддержкой Direct3D 9. Профили модели шейдера 2.x поддерживают более ограниченное поведение управления потоком, чем профили модели шейдера 4.x и более поздних версий.

 

Счетчики глубины инструкций шейдера пикселей

ps_2_0 не поддерживает управление потоком. Ниже перечислены ограничения для других версий пиксельного шейдера.

Число глубин инструкций для ps_2_x

Каждая инструкция учитывается в одном или нескольких ограничениях глубины вложенной вложения. В следующей таблице перечислены значения глубины, которые каждая инструкция добавляет или вычитает из существующей глубины.

Инструкция Статическая вложенная Динамическое вложение Вложенное вложение loop/rep вложение вызовов
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(если bool - ps) -1(если 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 в противном случае
Динамическое вложение От 0 до 24 см. раздел D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth
вложение rep От 0 до 4 см. раздел D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth
вложение вызовов От 0 до 4 см. раздел D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (независимо от ограничения rep)

 

Глубина инструкций для ps_2_sw

Каждая инструкция учитывается в соответствии с одним или несколькими ограничениями глубины вложенной вложения. В этой таблице показано количество глубин, которое каждая инструкция добавляет или вычитает из существующей глубины.

Инструкция Статическая вложенная Динамическое вложение Вложение loop/rep вложение вызовов
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(если bool - ps) -1(если 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

Каждая инструкция учитывается в соответствии с одним или несколькими ограничениями глубины вложенной вложения. В этой таблице показано количество глубин, которое каждая инструкция добавляет или вычитает из существующей глубины.

Инструкция Статическая вложенная Динамическое вложение Вложение loop/rep вложение вызовов
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(если bool - ps) -1(если 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
Вложенное вложение loop/rep 4
вложение вызовов 4

 

Число глубин инструкций для ps_3_sw

Каждая инструкция учитывается в одном или нескольких ограничениях глубины вложенной вложения. В этой таблице показано количество глубин, которое каждая инструкция добавляет или вычитает из существующей глубины.

Инструкция Статическая вложенная Динамическое вложение Вложенное вложение loop/rep вложение вызовов
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(если bool - ps) -1(если 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
Вложение loop/rep 4
вложение вызовов 4

 

Взаимодействие управления потоком Per-Pixel с градиентами экрана

Набор инструкций по пиксельным шейдерам включает несколько инструкций, которые создают или используют градиенты величин относительно экранного пространства x и y. Градиенты чаще всего используются для вычисления вычислений уровня детализации для выборки текстуры, а в случае анизотропной фильтрации — выборки по оси анизотропии. Как правило, аппаратные реализации запускают пиксельный шейдер одновременно на нескольких пикселях (например, в сетке 2x2), чтобы градиенты количества, вычисляемые в шейдере, можно было разумно приблизить как разностные значения в той же точке выполнения в смежных пикселях.

Если управление потоком присутствует в шейдере, результат вычисления градиента, запрошенного внутри заданного пути ветви, является неоднозначным, когда смежные пиксели могут выполнять отдельные пути управления потоком. Поэтому использование любой операции шейдера пикселей, которая запрашивает вычисление градиента в расположении, которое находится внутри конструкции управления потоком, которое может различаться в пикселях для данного примитивного растеризации.

Все инструкции шейдера пикселей секционируются на операции, которые разрешены, и на операции, которые не разрешены внутри управления потоком:

  • Сценарий A. Операции, которые не разрешены внутри элемента управления потоком, могут различаться в пикселях в примитиве. К ним относятся операции, перечисленные в следующей таблице.

    Инструкция Разрешено в управлении потоком в случаях, когда:
    texld - ps_2_0 и up, texldb - ps и texldp - ps Для координаты текстуры используется временный регистр.
    dsx - ps и dsy - ps Для операнда используется временный регистр.

     

  • Сценарий Б. Операции, разрешенные в любом месте. К ним относятся операции, перечисленные в следующей таблице.

    Инструкция Разрешено в любом месте, если:
    texld - ps_2_0 и up, texldb - ps и texldp - ps Количество, доступное только для чтения, используется для координат текстуры (может отличаться для каждого пикселя, например интерполированные координаты текстуры).
    dsx - ps и dsy - ps Количество, доступное только для чтения, используется для входного операнда (может отличаться в пикселях, например интерполированные координаты текстуры).
    texldl — ps Пользователь предоставляет уровень детализации в качестве аргумента, поэтому нет градиентов и, следовательно, нет проблем с управлением потоком.
    texldd — ps Пользователь предоставляет градиенты в качестве входных аргументов, поэтому нет проблем с управлением потоком.

     

Эти ограничения строго применяются при проверке шейдера. Сценарии с условием ветви, которое выглядит так, будто оно будет последовательно ветвиться в примитиве, даже если операнд в выражении условия является количеством, вычисленным пиксельным шейдером, тем не менее по-прежнему попадают в сценарий A и не допускаются. Аналогичным образом, сценарии, в которых градиенты запрашиваются для некоторого количества x, вычисленного шейдером, из элемента управления динамическим потоком, но когда кажется, что x не изменяется ни в одной из ветвей, тем не менее по-прежнему попадают в сценарий A и не допускаются.

Предикат включается в эти ограничения на управление потоком, поэтому реализации остаются свободными для тривиального обмена реализацией инструкций ветви с предикатными инструкциями.

Пользователь может использовать инструкции из сценариев A и B вместе. Например, предположим, что пользователю нужен образец анизотропной текстуры с учетом вычисленной координаты текстуры шейдера; однако нагрузка текстуры требуется только для пикселей, удовлетворяющих некоторым условиям каждого пикселя. Чтобы удовлетворить эти требования, пользователь может вычислить координату текстуры для всех пикселей за пределами управления потоком для каждого пикселя, немедленно вычисляя градиенты с помощью инструкций dsx - ps и dsy - ps . Затем в пределах пикселя, если bool - ps/endif - ps блок ps , пользователь может использовать texldd - ps (загрузка текстуры с предоставленными пользователем градиентами), передав предварительно вычисленные градиенты. Другой способ описать этот шаблон использования заключается в том, что, хотя все пиксели в примитиве должны были вычислять координаты текстуры и участвовать в вычислении градиента, только пиксели, необходимые для выборки текстуры, на самом деле сделали это.

Независимо от этих правил, пользователь по-прежнему должен убедиться, что перед вычислением любого градиента (или выполнением образца текстуры, который неявно вычисляет градиент) регистр, содержащий исходные данные, должен быть инициализирован для всех путей выполнения заранее. Инициализация временных регистров не проверяется и не применяется в целом.

Инструкции по шейдеру пикселей