Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Porting shaders from FXC to DXC

Tex Riddell edited this pageJan 30, 2021 ·5 revisions

Porting shaders from FXC to DXC

Introduction

This topic should be used as a reference point when porting your existing high-level shader language (HLSL) shaders over from D3DCompiler (FXC) to DXCompiler (DXC). Specifically, this topic provides details about the following:

  1. Enable some of the old FXC compilation behaviors that are disabled by default on DXC. This is supported on DXC through the following compiler flags:

    • -Gec: Enable Direct3D 9 backward compatibility (for example, enable support forCOLOR semantic that's supported only until Direct3D 9).

    • -HV: Enable FXC backward compatibility by setting the language version to 2016 (that is,-HV 2016). This enables a certain legacy language semantic that's available on FXC.

    • -flegacy-macro-expansion: Expand the operands before performing token-pasting operation (FXC behavior).

    • -flegacy-resource-reservation: Reserve unused explicit register assignments for compatibility with shader model 5.0 and earlier.

  2. Provide information about the old deprecated HLSL syntaxes that were supported on FXC but are no longer supported on DXC.

Compiler .dll interface changes

We recommend using the newIDxcCompiler3::Compile function for compiling DXC shaders. For more information about helper routines that will make porting existing code to the new interface easier, along with sample code, seeUsing DXC.

Backward compatibility with FXC behaviors

Multiplication-only pattern for the intrinsic functionpow

By default, DXC always useslog-mul-exp pattern (explained as follows) to implement thepow function. In contrast, FXC also uses themul-only pattern instead to implement thepow function in some scenarios. For example, for smaller constant values ofy (such aspow(x, 3)), FXC uses themul-only pattern. This could lead to thepow function producing different results when compiled by using FXC and DXC in some cases. For example, for a runtime value ofx=0,pow(x,3) evaluates toNaN and0 on DXC and FXC, respectively. To achieve the FXC behavior with respect to thepow function on DXC, set the language version to 2016 (by using the flag-HV 2016) during compilation.

Example of pow implementation by using the log-mul-exp pattern

pow(x,y) = e^(log(x) * y)

Example of pow implementation by using the mul-only pattern

pow(x,3) = (x * x) * x

Out-of-bound array accesses

By default, DXC errors out when finding constant index references to an array, which is out of bound. For example, the following HLSL shader fails to compile with an error message:error: array index 3 is out of bounds. You could turn this error into a warning by setting the language version to 2016 (that is, by using the-HV 2016 flag) only when the out-of-bound access happens in the unused or dead code.

voidmain(){  uint x[2];  x[3]=1.f;// Out-of-bound access.}

Warn when unroll attribute can't be honored

When theunroll attribute is applied on a loop and if the loop-trip–count can't be ascertained at compile-time or if it's above a certain threshold, then by default, DXC fails to compile shaders such as the following. To turn this failure into a warning, set the language version to 2016. When the following shader is compiled on DXC with the-HV 2016 flag, it compiles successfully without unrolling the loop and generates a warning message:warning: Could not unroll the loop.

uintmain(uint x : IN) : OUT{   uint r =0;   [unroll]for(uint i=0; i<x; i++)    r+=i;return r;}

COLOR semantic

The semantic COLOR isn't supported on DXC by default. When writing new HLSL shaders targeting DXC, you should instead useSV_Target. However, DXC also provides an option to compile shaders referencing the COLOR semantic by passing it the-Gec flag. For example, the following HLSL code should compile successfully on DXC when the-Gec flag is used.

floatmain() : COLOR{return1.f;}

Length property on constant arrays

TheLength property on constant arrays is supported on DXC under the-Gec flag as shown in the following example.

uintmain() : OUT{int x[5];return x.Length;}

Writing to globals

Global variables are treated as constants in HLSL, but just like FXC, DXC also enables support for writing to globals with the-Gec flag as shown in the following example.

float gvar;// Write enabled with "-Gec"float4main(uint a : A) : SV_Target{  gvar = a *2.0f;return (float4) gvar;}

Legacy resource reservation by using the-flegacy-resource-reservation flag

For shader model 5.0 or earlier, FXC would factor in the register allocation of unused resources when doing register allocation for used ones. For example, when compiling the following shader on FXC with SM5.0 and 5.1,Tex1[1] is bound tot4 andt0, respectively.When using DXC, to achieve the FXC resource allocation behavior with SM5.0 or earlier, use the-flegacy-resource-reservation flag.

Texture2D Tex0[2] :register(t1);Texture2D Tex1[2];float4main() : SV_Target{return Tex1[1].Load((uint3)0);}

Resource binding on FXC with SM5.0

// Resource bindings://// Name                                 Type  Format         Dim      HLSL Bind  Count// ------------------------------ ---------- ------- ----------- -------------- ------// Tex1[1]                           texture  float4          2d             t4      1

Resource binding on FXC with SM5.1

// Resource bindings://// Name                                 Type  Format         Dim      ID      HLSL Bind  Count// ------------------------------ ---------- ------- ----------- ------- -------------- ------// Tex1                              texture  float4          2d      T0             t0      2

Resource binding on DXC with SM6.0 without the-flegacy-resource-reservation flag

// Resource bindings://// Name                                 Type  Format         Dim      ID      HLSL Bind  Count// ------------------------------ ---------- ------- ----------- ------- -------------- ------// Tex1                              texture     f32          2d      T0             t0     2

Resource binding on DXC with SM6.0 with the-flegacy-resource-reservation flag

// Resource bindings://// Name                                 Type  Format         Dim      ID      HLSL Bind  Count// ------------------------------ ---------- ------- ----------- ------- -------------- ------// Tex1                              texture     f32          2d      T0             t3     2

Legacy macro expansion by using the-flegacy-macro-expansion flag

The following HLSL shader compiles successfully on FXC, but errors out on DXC asb##slot is replaced withbSLOT_VAL instead ofb3, thus causing compilation failure. To achieve the FXC token replacement behavior on DXC, compile with the additional flag "-flegacy-macro-expansion".

#defineSLOT_VAL3#defineCBUFFER_ALIGNED( name, slot) cbuffer name :register( b##slot )CBUFFER_ALIGNED( MyCBuffer, SLOT_VAL ){       float4        val;};

You can avoid the usage of the -flegacy-macro-expansion flag in this case by following standard preprocessor rules.

#defineSLOT_VAL3#definePASTE1(a, b) a##b#definePASTE(a, b) PASTE1(a, b)#defineCBUFFER_ALIGNED( name, slot) cbuffer name :register( PASTE(b, slot) )CBUFFER_ALIGNED( MyCBuffer, SLOT_VAL ){       float4        val;};

-flegacy-macro-expansion doesn't help for cases where the tokens are not macro arguments, though fxc still expands these. The following will result in an error even if -flegacy-macro-expansion is used.

#defineC4#defineA4 float4#defineTYPE A##C#defineFUNC(ty) tymain() : OUT {return0; }FUNC(TYPE)

The following change will bring the HLSL into compatibility with standard preprocessor rules, no longer requiring the -flegacy-macro-expansion option.

#defineC4#defineA4 float4#definePASTE1(a, b) a##b#definePASTE(a, b) PASTE1(a, b)#defineTYPEPASTE(A, C)#defineFUNC(ty) tymain() : OUT {return0; }FUNC(TYPE)

Unsupported FXC behaviors

Effect framework

Features related to the effects framework are no longer supported.

Uniform parameters on entry functions

Uniform parameters on entry functions are no longer supported.

There is a rewriter utility that may help port shaders that use this feature to DXC. The command line tool is called dxr.exe, and the API is indxctools.h.

The option to use is-extract-entry-uniforms, along with the entry name, and any other options necessary to parse the shader, such as-I include and-D define options. Seedxr.exe -? for a full option list. For the API, use the IDxcRewriter2::RewriteWithOptions method.

Rewritten HLSL will have the uniform resource and values extracted into the global scope for a single entry point. Name collisions are possible if parameter names collide with global names. It's meant to be used on one entry for one compilation, not on all entries in one file, otherwise name collisions will likely occur. Additionally, resources will only be extracted if identified with theuniform keyword at this time.

Uniform values extracted into global space will be placed in a constant buffer named_Params, since the equivalent in FXC would have been to put them in a constant buffer named$Params.

Example:

float4main(float4 color : INPUT,    uniformfloat scale,    uniform SamplerState sam,    uniform Texture2D<float2> tex,    uniform RWStructuredBuffer<float2> buf :register(u1)    ) : SV_TARGET{  buf[int(color.x)] = tex.SampleLevel(sam, color.xy * scale,0).xy;return color;}

Use the rewriter tool:

dxr.exe example.hlsl -extract-entry-uniforms -E main -Fo output.hlsl

To produce something like this inoutput.hlsl:

uniform SamplerState sam;uniform Texture2D<float2> tex;uniform RWStructuredBuffer<float2> buf :register(u1);cbuffer _Params {uniformfloat scale;}float4main(float4 color : INPUT) : SV_TARGET {  buf[int(color.x)] = tex.SampleLevel(sam, color.xy * scale,0).xy;return color;}

Interfaces

Interfaces are no longer supported.

Dimension-specific texture sample functions no longer supported

Support fortex1D,tex2D, and similar functions for sampling are now deprecated. To learn how to port to supported sampling functions, see the following example.

Example using the old syntax for sampling, which is no longer supported

sampler FontTextureSampler :register(s0);structVS_OUT{   float2 TexCoord0 : TEXCOORD0;};float4PSMain_Unsupported( VS_OUT In ) : SV_Target{returntex2D( FontTextureSampler, In.TexCoord0 ).zyxw;// tex2D is unsupported.}

Example showing supported syntax for sampling

SamplerState FontTextureSampler :register(s0);Texture2D FontTexture2D :register( t0 );// Step 1. Declare texture.structVS_OUT{   float2 TexCoord0 : TEXCOORD0;};float4PSMain( VS_OUT In ) : SV_Target{// Step 2. Use "Sample" method of the texture declared in the previous step.return FontTexture2D.Sample( FontTextureSampler, In.TexCoord0 ).zyxw;}

Semantic overlap not supported

DXC disallows the use of duplicate semantics. For example, the following shader will fail compilation on DXC.

uintmain(uint a : SV_VertexID, uint b : SV_VertexID) : OUT{return a + b;}

"ConstantBuffer" as constant buffer name not supported

Starting with SM5.1, HLSL supportsindexable constant buffers by using theConstantBuffer template construct. Therefore,ConstantBuffer is a reserved keywordand DXC disallows using it as a buffer name.

cbuffer ConstantBuffer :register(b0)// ConstantBuffer as buffer name not allowed.{ float2 field1;float field2;}
Clone this wiki locally

[8]ページ先頭

©2009-2025 Movatter.jp