Export (0) Print
Expand All

Offline Compiling

The effect-compiler tool (fxc.exe) is designed for offline compilation of HLSL shaders and effects. The tool is located at:

(SDK root)\Utilities\Bin\x86\

Differences between Direct3D 9 and Direct3D 10:

Beginning with the December 2006 SDK, the DirectX 10 HLSL compiler (Effect-Compiler Tool) (which includes many improvements in code generation) is the default compiler. For applications that want to continue to compile against the DirectX 9 compiler rules (fxc.exe), you may use fxc.exe with the /LD switch (this requires the D3DX9_31.DLL).

The DirectX 10 HLSL compiler does not have direct support for ps_1_x shaders. To use fxc on ps_1_x shaders requires the /Gec switch to enable backwards compatibility. Effects that specify ps_1_x targets will instead compile to ps_2_0 targets because this is the minimum shader version supported by the DirectX 10 HLSL compiler.

 

Compiling with the Current Compiler

The shader models supported by the current compiler are shown in Profiles. This example compiles an effect from the BasicHLSL10.fx file (see BasicHLSL10 Sample) for the shader model 4 target.



// For a release build
fxc /T fx_4_0 /Fo BasicHLSL10.fxo BasicHLSL10.fx
      

In this example:

  • fx_4_0 is the target profile.
  • BasicHLSL10.fxo is the output-object file containing the compiled effect.
  • BasicHLSL10.fx is the input effect file.


// For a debug build
fxc /Od /Zi /T fx_4_0 /Fo BasicHLSL10.fxo BasicHLSL10.fx
      

The debug options include additional options to disable compiler optimizations and enable debug information like line numbers and symbols. The binary representation of the shader is written to a file called BasicHLSL10.fxo, which is an arbitrary abbreviation for the fxc output file.

For a full listing of the command-line options, see the syntax page.

Effects can be compiled into object files using the fxc.exe tool with a target of fx_2_0 or fx_4_0. The object file can then be used to create an effect directly using D3DXCreateEffect(Direct3D 9) or D3D10CreateEffectFromMemory (Direct3D 10).

Compiling with the Legacy Compiler

Beginning with Direct3D 10, some shader models are no longer supported. These include pixel shader models: ps_1_1, ps_1_2, ps_1_3, and ps_1_4 which support very limited resources and are dependent on hardware. The compiler has been redesigned with shader model 2 (or greater) which allows for greater efficiencies with compilation. This of course will require that you are running on hardware that supports shader models 2 and greater.

If you still want to compile shaders using the legacy compiler, use the /LD switch. This supports shader models 1, 2 and 3 and does not contain the improvements and bug fixes found in the current compiler.

Also note that you should consult the SDK release notes associated with your version of the Effect-Compiler Tool for behavior affected by the /Gec switch.

Compiling Shader Model 1 with the Current Compiler

The legacy compiler is not recommended for compiling new shader code due to the limitations caused by pixel shaders in shader model 1 (see Compiling with the Legacy Compiler). However, there are libraries of existing shaders that were created for ps_1_x.

To use the current compiler to build shader model 1 pixel shaders and effects, use the /Gec switch. This causes the effect-compiler tool to compile all ps_1_x targets to ps_2_0 targets. This can be done without changing any existing shader or effect code.

Using the Effect-Compiler tool in a Subprocess

If fxc.exe is spawned as a subprocess by an application it is important to ensure that the application checks for and reads any data in output or error pipes passed to the CreateProcess function. If the application only waits for the subprocess to finish and one of the pipes becomes full the subprocess will never finish.

The following example code illustrates waiting on a subprocess and reading the output and error pipes attached to the subprocess. The contents of the WaitHandles array correspond to handles for the subprocess, the pipe for stdout and the pipe for stderr.




  HANDLE WaitHandles[] = {
    piProcInfo.hProcess, hReadOutPipe, hReadErrorPipe
  };

  const DWORD BUFSIZE = 4096;
  BYTE buff[BUFSIZE];

  while (1)
  {
    DWORD dwBytesRead, dwBytesAvailable;

    dwWaitResult = WaitForMultipleObjects(3, WaitHandles, FALSE, 60000L);

    // Read from the pipes...
    while( PeekNamedPipe(hReadOutPipe, NULL, 0, NULL, &dwBytesAvailable, NULL) && dwBytesAvailable )
    {
      ReadFile(hReadOutPipe, buff, BUFSIZE-1, &dwBytesRead, 0);
      streamOut << std::string((char*)buff, (size_t)dwBytesRead);
    }
    while( PeekNamedPipe(hReadErrorPipe, NULL, 0, NULL, &dwBytesAvailable, NULL) && dwBytesAvailable )
    {
      ReadFile(hReadErrorPipe, buff, BUFSIZE-1, &dwBytesRead, 0);
      streamError << std::string((char*)buff, (size_t)dwBytesRead);
    }

    // Process is done, or we timed out:
    if(dwWaitResult == WAIT_OBJECT_0 || dwWaitResult == WAIT_TIMEOUT)
    break;
  }        


For additional information on spawning a process see the reference page for CreateProcess.

Related topics

Effect-Compiler Tool

 

 

Community Additions

ADD
Show:
© 2014 Microsoft