Udostępnij przez


Ograniczenia sterowania przepływem

Instrukcje sterowania przepływem cieniowania pikseli mają limity wpływające na liczbę poziomów zagnieżdżania w instrukcjach. Ponadto istnieją pewne ograniczenia dotyczące implementowania sterowania przepływem na piksel z instrukcjami gradientu.

Nuta

Jeśli używasz profilów cieniowania *_4_0_level_9_x HLSL, niejawnie używasz profilów Shader Model 2.x do obsługi sprzętu obsługującego usługę Direct3D 9. Profile Shader Model 2.x obsługują bardziej ograniczone zachowanie sterowania przepływem niż profile Shader Model 4.x i nowsze.

 

Liczba głębokości instrukcji cieniowania pikseli

ps_2_0 nie obsługuje sterowania przepływem. Poniżej wymieniono ograniczenia dotyczące innych wersji cieniowania pikseli.

Liczba głębokości instrukcji dla ps_2_x

Każda instrukcja jest liczone względem co najmniej jednego limitu głębokości zagnieżdżania. W poniższej tabeli wymieniono liczbę głębokości, którą każda instrukcja dodaje lub odejmuje z istniejącej głębokości.

Polecenie Zagnieżdżanie statyczne Dynamiczne zagnieżdżanie zagnieżdżanie pętli/powtórzeń zagnieżdżanie wywołań
jeśli bool - ps 1 0 0 0
if_comp — ps 0 1 0 0
wstępnie — ps 0 1 0 0
else — ps 0 0 0 0
endif — ps -1(if bool - ps) -1(, jeśli pred - ps lub if_comp - ps) 0 0
rep — ps 0 0 1 0
endrep — ps 0 0 -1 0
przerwa — ps 0 0 0 0
break_comp — ps 0 1, -1 0 0
breakp — ps 0 0 0 0
połączenie — 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

 

Głębokość zagnieżdżania

Głębokość zagnieżdżania definiuje liczbę instrukcji, które można wywołać od wewnątrz siebie. Każdy typ instrukcji ma co najmniej jeden limit zagnieżdżania, jak wskazano w poniższej tabeli.

Typ instrukcji Maksimum
Zagnieżdżanie statyczne 24 jeżeli (D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth > 0); 0 w przeciwnym razie
Dynamiczne zagnieżdżanie Od 0 do 24, zobacz D3DCAPS9. D3DPSHADERCAPS2_0.DynamicFlowControlDepth
zagnieżdżanie repozytorium Od 0 do 4, zobacz D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth
zagnieżdżanie wywołań Od 0 do 4, zobacz D3DCAPS9. D3DPSHADERCAPS2_0.StaticFlowControlDepth (niezależnie od limitu repozytorium)

 

Liczba głębokości instrukcji dla ps_2_sw

Każda instrukcja jest liczone względem co najmniej jednego limitu głębokości zagnieżdżania. W tej tabeli przedstawiono liczbę głębokości, którą każda instrukcja dodaje lub odejmuje z istniejącej głębokości.

Polecenie Zagnieżdżanie statyczne Dynamiczne zagnieżdżanie zagnieżdżanie pętli/powtórzeń zagnieżdżanie wywołań
jeśli bool - ps 1 0 0 0
wstępnie — 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(, jeśli pred - ps lub if_comp - ps) 0 0
rep — ps 0 0 1 0
endrep — ps 0 0 -1 0
pętla — ps N/a N/a N/a N/a
endloop — ps N/a N/a N/a N/a
przerwa — ps 0 0 0 0
break_comp — ps 0 1, -1 0 0
breakp — ps 0 0 0 0
połączenie — 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

 

Głębokość zagnieżdżania

Głębokość zagnieżdżania definiuje liczbę instrukcji, które mogą być wywoływane ze sobą. Każdy typ instrukcji ma co najmniej jeden limit zagnieżdżania, jak wskazano w poniższej tabeli.

Typ instrukcji Maksimum
Zagnieżdżanie statyczne 24
Dynamiczne zagnieżdżanie 24
zagnieżdżanie repozytorium 4
zagnieżdżanie wywołań 4

 

Liczba głębokości instrukcji dla ps_3_0

Każda instrukcja jest liczone względem co najmniej jednego limitu głębokości zagnieżdżania. W tej tabeli przedstawiono liczbę głębokości, którą każda instrukcja dodaje lub odejmuje z istniejącej głębokości.

Polecenie Zagnieżdżanie statyczne Dynamiczne zagnieżdżanie zagnieżdżanie pętli/powtórzeń zagnieżdżanie wywołań
jeśli bool - ps 1 0 0 0
wstępnie — 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(, jeśli pred - ps lub if_comp - ps) 0 0
rep — ps 0 0 1 0
endrep — ps 0 0 -1 0
pętla — ps 0 0 1 0
endloop — ps 0 0 -1 0
przerwa — ps 0 0 0 0
break_comp — ps 0 1, -1 0 0
breakp — ps 0 0 0 0
połączenie — 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

 

Głębokość zagnieżdżania

Głębokość zagnieżdżania definiuje liczbę instrukcji, które mogą być wywoływane ze sobą. Każdy typ instrukcji ma co najmniej jeden limit zagnieżdżania, jak wskazano w poniższej tabeli.

Typ instrukcji Maksimum
Zagnieżdżanie statyczne 24
Dynamiczne zagnieżdżanie 24
zagnieżdżanie pętli/powtórzeń 4
zagnieżdżanie wywołań 4

 

Liczba głębokości instrukcji dla ps_3_sw

Każda instrukcja jest liczone względem co najmniej jednego limitu głębokości zagnieżdżania. W tej tabeli przedstawiono liczbę głębokości, którą każda instrukcja dodaje lub odejmuje z istniejącej głębokości.

Polecenie Zagnieżdżanie statyczne Dynamiczne zagnieżdżanie zagnieżdżanie pętli/powtórzeń zagnieżdżanie wywołań
jeśli bool - ps 1 0 0 0
wstępnie — 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(, jeśli pred - ps lub if_comp - ps) 0 0
rep — ps 0 0 1 0
endrep — ps 0 0 -1 0
pętla — ps 0 0 1 0
endloop — ps 0 0 -1 0
przerwa — ps 0 0 0 0
break_comp — ps 0 1, -1 0 0
breakp — ps 0 0 0 0
połączenie — 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

 

Głębokość zagnieżdżania

Głębokość zagnieżdżania definiuje liczbę instrukcji, które mogą być wywoływane ze sobą. Każdy typ instrukcji ma co najmniej jeden limit zagnieżdżania, jak wskazano w poniższej tabeli.

Typ instrukcji Maksimum
Zagnieżdżanie statyczne 24
Dynamiczne zagnieżdżanie 24
zagnieżdżanie pętli/powtórzeń 4
zagnieżdżanie wywołań 4

 

Interakcja kontrolki przepływu Per-Pixel z gradientami ekranu

Zestaw instrukcji cieniowania pikseli zawiera kilka instrukcji, które tworzą lub używają gradientów ilości w odniesieniu do miejsca na ekranie x i y. Najczęstszym zastosowaniem gradientów jest obliczanie obliczeń na poziomie szczegółów na potrzeby próbkowania tekstur, a w przypadku filtrowania anisotropowego wybór próbek wzdłuż osi anizotropii. Zazwyczaj implementacje sprzętowe uruchamiają cieniowanie pikseli na wielu pikselach jednocześnie (na przykład siatce 2x2), dzięki czemu gradienty ilości obliczonych w cieniatorze mogą być dość przybliżone jako różnice wartości w tym samym punkcie wykonywania w sąsiednich pikselach.

Gdy kontrolka przepływu jest obecna w cieniatorze, wynik obliczenia gradientu żądanego wewnątrz danej ścieżki gałęzi jest niejednoznaczny, gdy sąsiadujące piksele mogą wykonywać oddzielne ścieżki sterowania przepływu. W związku z tym uznaje się, że jest to nielegalne, aby użyć dowolnej operacji cieniowania pikseli, która żąda obliczenia gradientu w lokalizacji, która znajduje się wewnątrz konstrukcji sterowania przepływem, która może się różnić w pikselach dla danego pierwotnego rasteryzowanego.

Wszystkie instrukcje cieniowania pikseli są podzielone na te operacje, które są dozwolone i do tych, które nie są dozwolone wewnątrz sterowania przepływem:

  • Scenariusz 1: Operacje, które nie są dozwolone wewnątrz kontrolki przepływu, które mogą się różnić w pikselach w elementach pierwotnych. Obejmują one operacje wymienione w poniższej tabeli.

    Polecenie Jest dozwolone w kontrolce przepływu, gdy:
    texld — ps_2_0 i w górę, texldb — ps i texldp — ps Rejestr tymczasowy jest używany na potrzeby współrzędnych tekstury.
    dsx — ps i dsy — ps Rejestr tymczasowy jest używany dla operandu.

     

  • Scenariusz B: operacje dozwolone w dowolnym miejscu. Obejmują one operacje wymienione w poniższej tabeli.

    Polecenie Jest dozwolone w dowolnym miejscu, gdy:
    texld — ps_2_0 i w górę, texldb — ps i texldp — ps Ilość tylko do odczytu jest używana dla współrzędnych tekstury (może się różnić w pikselach, takich jak współrzędne tekstury interpolowanej).
    dsx — ps i dsy — ps Ilość tylko do odczytu jest używana dla operandu wejściowego (może się różnić w pikselach, takich jak współrzędne tekstury interpolowanej).
    texldl — ps Użytkownik udostępnia poziom szczegółowości jako argument, więc nie ma gradientów, a tym samym nie ma problemu z sterowaniem przepływem.
    texldd — ps Użytkownik udostępnia gradienty jako argumenty wejściowe, więc nie ma problemu z sterowaniem przepływem.

     

Te ograniczenia są ściśle wymuszane w weryfikacji cieniowania. Scenariusze, w których warunek gałęzi wygląda na to, że będzie stale rozgałęziany w obrębie elementu pierwotnego, mimo że operand w wyrażeniu warunku jest ilością obliczaną przez cieniowanie pikseli, mimo to nadal należy do scenariusza A i nie są dozwolone. Podobnie scenariusze, w których gradienty są żądane dla pewnej ilości obliczonej cieniowania x z wewnątrz dynamicznej kontrolki przepływu, ale gdzie wydaje się, że x nie jest modyfikowane w żadnej z gałęzi, mimo to nadal należy do scenariusza A i nie są dozwolone.

Predykacja jest uwzględniana w tych ograniczeniach dotyczących sterowania przepływem, dzięki czemu implementacje pozostają swobodne, aby trywialnie wymieniać implementację instrukcji gałęzi z wstępnie określonymi instrukcjami.

Użytkownik może używać instrukcji ze scenariuszy A i B razem. Załóżmy na przykład, że użytkownik potrzebuje próbki tekstury anisotropowej, biorąc pod uwagę współrzędną tekstury obliczanej za pomocą cieniowania; jednak obciążenie tekstury jest wymagane tylko w przypadku pikseli satysfakcjonujących niektóre warunki na piksel. Aby spełnić te wymagania, użytkownik może obliczyć współrzędną tekstury dla wszystkich pikseli, poza zmienną kontrolką przepływu, natychmiast obliczając gradienty przy użyciu dsx — ps i dsy — ps instrukcje. Następnie w na piksel, jeśli wartość logiczna - ps/endif - ps bloku, użytkownik może użyć texldd - ps (obciążenie tekstury z gradientami dostarczonymi przez użytkownika), przekazując wstępnie obliczone gradienty. Innym sposobem opisania tego wzorca użycia jest to, że podczas gdy wszystkie piksele w typie pierwotnym musiały obliczyć współrzędne tekstury i być zaangażowane w obliczenie gradientu, tylko piksele potrzebne do próbkowania tekstury rzeczywiście to zrobił.

Niezależnie od tych reguł obciążenie jest nadal związane z użytkownikiem, aby upewnić się, że przed obliczeniem dowolnego gradientu (lub wykonania próbki tekstury, która niejawnie oblicza gradient), rejestr zawierający dane źródłowe musi zostać zainicjowany dla wszystkich ścieżek wykonywania wcześniej. Inicjowanie rejestrów tymczasowych nie jest ogólnie weryfikowane ani wymuszane.

instrukcje cieniowania pikseli