Effects for Direct3D 11 Update


The Effects 11 library (FX11) was made available as shared-source in the DirectX SDK. Previous versions of the Effects library were part of D3DX (FX9) or built into the OS (FX10). With the DirectX SDK now legacy (see Where is the DirectX SDK? and Where is the DirectX SDK (2013 Edition)?), there are still a number of people looking for the latest version since it is not included in the Windows 8.0 SDK. This post provides an updated version of the Effects 11 (FX11) library. The primary purpose of this release is to remove the dependencies on the legacy DirectX SDK for the D3DX11 headers, but it also includes some code tidying and a few customer requests.

If you still need Visual Studio 2008 support, you should keep using the legacy DirectX SDK (June 2010) version.

Disclaimer

Effects 11 is primarily being provided as a porting aid for older code that make use of the Effects 10 (FX10) API or Effects 9 (FX9) API in the deprecated D3DX9 library. See MSDN for a list of differences compared to the Effects 10 (FX10) library.

  • The Effects 11 library is for use in Win32 desktop applications. FX11 requires the D3DCompiler API be available at runtime to provide shader reflection functionality, and this API is not deployable for Windows Store apps on Windows 8 or Windows RT.
  • The fx_5_0 profile support in the HLSL compiler is deprecated, and does not fully support DirectX 11.1 HLSL features such as minimum precision types.  It is supported in the Windows 8.0 SDK version of the HLSL compiler (FXC.EXE) and D3DCompile API (#46), but could be removed in a future update.
  • The Visual Studio 2012 graphics diagnostics feature has had some problems when trying to debug fx_5_0 profile shaders. You may want to try the latest VS 2012 Update.

Porting Notes

Here’s a handy table of equivalents related to Effects (see Living without D3DX for a complete listing):

D3DXCreateEffect
D3DXCreateEffectEx
D3DXCreateEffectFromResource
D3DXCreateEffectFromResourceEx
D3D10CompileEffectFromMemory

D3DX11CompileEffectFromMemory

D3DXCreateEffectFromFile
D3DXCreateEffectFromFileEx

D3DX11CompileEffectFromFile

D3D10CreateEffectFromMemory

D3DX11CreateEffectFromMemory

D3DXCreateEffectPool
D3D10CreateEffectPoolFromMemory

Effects 11 does not support ‘effect pools’
or D3DCOMPILE_EFFECT_CHILD_EFFECT. Effect groups provide a more efficient solution for common scenarios previously addressed with ‘effect pools’

D3DXDisassembleEffect
D3D10DisassembleEffect

D3DDisassemble
D3DDisassemble10Effect in D3DCompile

Version History

October 24, 2012 (11.03)

  • Removed the dependency on the D3DX11 headers, so FX11 no longer requires the legacy DirectX SDK to build. It does require the d3dcompiler.h header from either the Windows 8.0 SDK or from the legacy DirectX SDK
  • Removed references to D3D10 constants and interfaces
  • Deleted the d3dx11dbg.cpp and d3dx11dbg.h files
  • Deleted the D3DX11_EFFECT_PASS flags which were never implemented
  • General C++ code cleanups (nullptr, C++ style casting, stdint.h types, Safer CRT, etc.) which are compatible with Visual C++ 2010 and 2012
  • SAL2 annotation and /analyze cleanup
  • Added population of Direct3D debug names for object naming support in PIX and the SDK debug layer; added additional optional parameter to D3DX11CreateEffectFromMemory to provide a debug name
  • Added D3DX11CreateEffectFromFile, D3DX11CompileEffectFromMemory, and D3DX11CompileEffectFromFile

June 2010 (11.02)

  • The DirectX SDK (June 2010) included an update with some minor additional bug fixes. This also included the Effects 11-based sample DynamicShaderLinkageFX11. This is the last version to support Visual Studio 2008. The source code is located in Samples\C++\Effects11.

February 2010 (11.01)

  • An update was shipped with the DirectX SDK (February 2010). This fixed a problem with the library which prevented it from working correctly on 9.x and 10.x feature levels. This is the last version to support Visual Studio 2005. The source code is located in Samples\C++\Effects11.

August 2009 (11.00)

  • The initial release of Effects 11 (FX11) was in DirectX SDK (August 2009). The source code is located in Utilities\Source\Effects11. This is essentially the Effects 10 (FX10) system ported to Direct3D 11.0 with support for effects pools removed and support for groups added.

Update: Effects 11 is now hosted on CodePlex and GitHub. The latest version of the library, documentation, release history, and other information is now available there.

Samples: Effects 11 Win32 Samples

Related: DirectXTex and Effects 11 Update

Comments (30)

  1. I like it! What will you be working on next?

  2. Please do not kill Effects API. It is great framework which saves a lot of developer work.

  3. I am very confused at the moment, I have switched to visual studio 2012. I am using speed tree 5.0, which relies on the effect library. I am using D3D10.

    I can successfully compily the FX using D3DCompile() and the "fx_4_0" profile.

    However, now D3D10CreateEffectFromMemory() doesn't like the compiled effect anymore, and return E_FAIL. I have no other information but this error code.

    I had a look at the Effects11 library, but it requires a ID3D11Device.

    Any idea ?

  4. Gregory – Please try to send me directly a minimal repro of your problem, particularly the shader file(s) in question and instructions for compiling them using FXC.EXE.

    Did it work with DirectX SDK (June 2010) release?

  5. > I can successfully compily the FX using D3DCompile() and the "fx_4_0" profile.

    Gregory, you should use fx_5_0 profile only for effect compilation. fx_4_0 is incompatible with Effects11.

  6. I think Gregory is trying to use the latest HLSL complier (D3DCompile #46) to generate shaders for the FX10 system which is why he's using fx_4_0.

  7. Doug says:

    Is it advisable to not use the Effects framework for shader development, due to its uncertain longevity? In other words, how likely is it that the Effects framework will not be supported in future DX versions?

  8. New development should probably consider alternatives to the FX solution. That said, HLSL remains an important language for Direct3D programming.

  9. devast says:

    Hi, I'm completely confused about what I should use for shader processing! I have Windows 7 and Visual Studio 2010, what is adviceable way to do it right? (that is whithout using deprecated stuff and using proper file formats). I understand I should use FXC.exe from the Windows 8 Sdk to compile the *.hlsl file manually and then.. what should I use then?

  10. If you are not using the legacy "fx" profiles, then all you need to do is get the resulting binary blob from the shader compiler and set it using the appropriate Direct3D call (such as VSSetShader). You can load the resulting compiled shader from FXC (made with the /Fo command) as a binary file using any standard file I/O operation that doesn't do any ASCII text mode changes. Alternatively, you can use FXC to create a header file with the compiled shader in it to include directly into your C++ code (via the /Fh command). If you are writing a Win32 desktop app, you can of course also do runtime compilation via the D3DCompile API and pass the resulting binary blob to Direct3D.

    See Windows Store app Direct3D samples for an example of using binary loading of a .cso file created from the /Fo option.

    See DirectXTK for an example of using the /Fh option.

    See the Win32 desktop version of the Direct3D 11 tutorials for an example of using D3DCompile API.

    See HLSL, FXC, and D3DCompile

  11. Nasir says:

    I have made an application on directx 11 with DXUT . What happened to me is its all fine as long as i am running it from code but once I make a setup of it. It fails and shows some problem of memory in the effect file where dynamic memory is been allocated. I dont know how to get rid of it. Moreover in the application the device is twice created which also at time creates a problem while allocating the memory.

  12. Rob Withey says:

    Why does GetBool et al take a bool pointer and then ultimately write an int into it in CopyScalarValue?  4 into 1 doesn't seem to go…!

  13. @Rob – In the original code it was "BOOL" which is actually 4 bytes. I changed it to 'bool' for a more modern type usage, but that's probably what gave rise to your bug. Do have a file name and line number to check?

  14. Rob Withey says:

    Attempt #2 to post.

    Sure, though not sure about it being "my" bug.  😉

    EffectVariable.inl, around line 1624 (But there are lots of methods getting bools, and they are all broken afaics).

    template<typename IBaseInterface, bool IsAnnotation>

    _Use_decl_annotations_

    HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)

    {

       return CopyScalarValue<ETVT_Float, ETVT_Bool, float, true>(*Data.pNumericFloat, pValue, "ID3DX11EffectScalarVariable::GetBool");

    }

    EffectVariable, around line 630:

    // Note that the branches in this code is based on template parameters and will be compiled out

    template<ETemplateVarType SourceType, ETemplateVarType DestType, typename SRC_TYPE, bool ValidatePtr>

    __forceinline HRESULT CopyScalarValue(_In_ SRC_TYPE SrcValue, _Out_writes_bytes_(4) void *pDest, _In_z_ const char *pFuncName)

    {

       HRESULT hr = S_OK;

    #ifdef _DEBUG

       if (ValidatePtr)

           VERIFYPARAMETER(pDest);

    #else

       UNREFERENCED_PARAMETER(pFuncName);

    #endif

       switch (SourceType)

       {

       case ETVT_Float:

           switch (DestType)

           {

           case ETVT_Bool:

               *(int*)pDest = (SrcValue != 0.0f) ? -1 : 0;                // <—– This writes int size to a bool.  Same for other source types.

               break;

           case ETVT_Int:

               *(int*)pDest = (int) (SrcValue);

               break;

           case ETVT_Float:

               *(float*)pDest = (float) SrcValue;

               break;

           default:

               assert(0);

           }

           break;

       default:

           assert(0);

       }

    lExit:

       return hr;

    }

    sizeof(bool) == 1, sizeof(int) == 4.  Therefore this writes 4 bytes to a 1 byte storage.  It also writes -1 as true.  Which is a bit odd for a bool.

    I think the problem is much worse when getting arrays of bools, since it writes an array of ints to an array of bools, and the memory trampling is much worse.

    So I think in summary the following API methods in EffectVariable.inl will write more memory than they should:

    1626 : HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)

    1644 : HRESULT TFloatScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)

    1760 : HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)

    1778 : HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)

    1894 : HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetBool(bool *pValue)

    1912 : HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)

    2178 : HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetBoolVector(bool *pData)

    2322 : HRESULT TVectorVariable<IBaseInterface, IsAnnotation, BaseType>::GetBoolVectorArray(bool *pData, uint32_t Offset, uint32_t Count)

    Hope that helps, best regards.

    Rob

  15. @Rob – Thanks. The simplest thing is probably to change those back to using "BOOL".

  16. Mauricio Vives - Autodesk says:

    Chuck, I just hit the same issue as Rob.  I modified the source in a few places to use bool instead of int, and it seems to be OK now.  I would rather not use BOOL to avoid copying between bool and BOOL arrays.  This should be easy to fix in the next drop.  Thanks.

  17. @Mauricio – Can you send me the source changes you made? I wonder if I really need to support both "BOOL" and "bool".

  18. Mauricio Vives - Autodesk says:

    Chuck, I missed your earlier reply here.  This actually turns out to be more complicated, because you can't pack an *array* of bools (single byte) into a constant buffer and have it work properly.  So the system must convert the input bools into int / BOOL for storage.  I previously had it working for single elements, but not arrays, so I am working on that now.  If you are still interested, I can send the modifications after I have them tested.

  19. @Mauricio – Thanks, that would be helpful…

  20. Mauricio Vives - Autodesk says:

    Due to some template limitations, I decided to go for the brute force fix: the exposed (API) functions continue to accept bool but I changed the internal storage (pNumericBool) to BOOL.  This means converting between them in the GetBool / SetBool / GetBoolArray / SetBoolArray functions, but that is basically the same as what we did with the old Effects11, except now the conversion is hidden inside Effects11.  Here is what GetBoolArray() looks like as an example:

    template<typename IBaseInterface, bool IsAnnotation>

    _Use_decl_annotations_

    HRESULT TBoolScalarVariable<IBaseInterface, IsAnnotation>::GetBoolArray(bool *pData, uint32_t Offset, uint32_t Count)

    {

       // Create a temporary BOOL array.

       BOOL* pValues = new BOOL[Count];

       HRESULT hr = GetScalarArray<ETVT_Bool, ETVT_Bool, BOOL, BOOL>(Data.pNumericBool, pValues, Offset, Count,

           pType, GetTotalUnpackedSize(), "ID3DX11EffectScalarVariable::GetBoolArray");

       if (FAILED(hr)) { delete [] pValues; return hr; }

       // Copy the temporary BOOL array to the output bool array.

       for (uint32_t i = 0; i < Count; i++) { pData[i] = pValues[i] != 0; }

       delete [] pValues;

       return hr;

    }

  21. JACK says:

    win7 + d2d1.1 + effect ,don't run !

  22. Effects11 works with Direct3D 11, and is not directly related to Direct2D. Can you clarify what exactly your scenario and symptoms are?

  23. Hello. I've got big problem with d3dcompiler_46.dll. When I use 43th version (I need to make some changes in EffectApi.cpp to do that) then my effects creates just fine and everything is working. But after moving to 46th version I get "Effects11: Internal loading error: cannot create shader reflection object." error message. I even tried to load DynamicShaderLinkageFX11.fx file from DirectX SDK june 2010 and I got the same error. Did I missed some changes in fx_5_0 profile or the problem lies somewhere else? Thanks in advance for any response.

  24. @Chazar: I have been able to use the DynamicShaderLinkageFX11 sample with the #46 compiler and the latest Effects 11 without any such problems. The most likely problem is that you are attempting to use a binary blob built with #43 and use the #46 D3DReflect API to read it or vice-versa. Also, remember that the .fx file is the HLSL source file and must be used with D3DX11CompileEffect, not D3DX11CreateEffect which expects a binary shader blob.

  25. Thank you Chuck for fast response. It helped me a lot because i knew then that the problem lied on my side.

    I'm forced to use d3dx9 library for older part of our code so my library directories in VS showed both Win8 SDK and DX SDK. It turned out that libraries like dxguid.lib were taken from DX SDK. Once I removed all libraries beside d3dx9.lib (which I need) it started working with version #46. Thanks again.

    Cheers

  26. You should look at the instructions on MSDN for the best way to mix the use of the Windows 8.0 SDK that comes with VS 2012 and the legacy DirectX SDK to avoid getting the 'wrong' libraries

  27. Wolk says:

    I'm pretty sure i got it wrong, is it still using the D3DX naming? However, when i use the D3DX naming it gives me unresolved external symbol error

  28. Effects uses the D3DX11 naming. You may want to take this issue to the CodePlex discussion area…