D3D11 - Effects 11 - Backward Compatibility

Started by
8 comments, last by Xsy 14 years, 5 months ago
Good Evening. I recently discovered D3D11 removed support for Effect Pools replacing them with Effect Groups. Now given there isn't much documentation on the issue , I didn't really understand how groups can retain effect pool functionality. The functionality I'm actually referring to is the easy setting of constant buffers that are the same on multiple effect files. What I have done before is to create one Effect pool from one Effect file that had a constant buffer containing the LightDirection , View / Projection matrices , basicly stuff that are set once regardless. Than I would just include this effect in effects needing that data and creating them as child effects. That allowed me to use the pool to set the data once before going into multiple effects and setting their individual variables. Now I'm not sure how am I suppose to use groups to do the same thing. Maybe I'm missing or misunderstanding something , I'll be glad if you can assist me with this :> [SOLVED] * New question in a new reply below. [Edited by - Xsy on November 8, 2009 12:16:33 PM]
Advertisement
[SOLVED]
D3D11 is starting to get on my nerves :|
When creating a compiled effect that was compiled on the fx_5_0 platform , I get this crap :
 D3D11: ERROR: ID3D11Device::CreateVertexShader: The pClassLinkage parameter must be NULL, unless GetFeatureLevel returns D3D_FEATURE_LEVEL_11_0 or greater. [ STATE_CREATION ERROR #2097154: CREATEVERTEXSHADER_INVALIDCLASSLINKAGE ]D3D11: ERROR: ID3D11Device::CreatePixelShader: The pClassLinkage parameter must be NULL, unless GetFeatureLevel returns D3D_FEATURE_LEVEL_11_0 or greater. [ STATE_CREATION ERROR #2097160: CREATEPIXELSHADER_INVALIDCLASSLINKAGE ]


I perfectly understand what the error means , that thing is I cant find any control over this. There is no flag or parameter or something that I should pass during compilation or creation. Of course when I try to compile it to fx_4_0 and create with D3DX11CreateEffectFromMemory() I get: "Effects11: Effect version is unrecognized. This runtime supports fx_5_0 to fx_5_0".

So does this mean that I cant use the Effects11 framework on a machine with no dx11 hardware? Because that would be kind of stupid I guess i'm doing something wrong. I'd be happy to know what :>

[EDIT] Further searching revealed that it's a bug , the framework keeps passing a classlinkage class to the creation function , changing the source code helps.

[Edited by - Xsy on November 8, 2009 12:01:17 PM]
Using the new features around Runtime-Shader-Linkage is only supported on 11 class hardware. You can't select an implementation for a class at runtime on older hardware. As such, you can't pass anything to the pClassLinkage parameter (since that would set implementations at runtime).

You should be able to hard-code implementations in your shader code, and it should compile and run correctly.

As for the lost effect pool funcionality, while I don't have any specific answers about new functionality to replace it, it doesn't sound like a huge loss. IIRC, there were several issues with Effect Pools, and implementing similar functionality (using a shader constant buffer) shouldn't be all that difficult. Have you considered just using one constant buffer for all the shared stuff?

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
Quote:Original post by sirob
Using the new features around Runtime-Shader-Linkage is only supported on 11 class hardware. You can't select an implementation for a class at runtime on older hardware. As such, you can't pass anything to the pClassLinkage parameter (since that would set implementations at runtime).

You should be able to hard-code implementations in your shader code, and it should compile and run correctly.

As for the lost effect pool funcionality, while I don't have any specific answers about new functionality to replace it, it doesn't sound like a huge loss. IIRC, there were several issues with Effect Pools, and implementing similar functionality (using a shader constant buffer) shouldn't be all that difficult. Have you considered just using one constant buffer for all the shared stuff?

Hope this helps.


I am using one constant buffer for the shared stuff. Maybe I'm misunderstanding constant buffers , but isn't the buffer set per effect? In other words this would mean that I will need to update the view / proj variables per effect. My goal is to update it just once per frame , with no regard to the number of effects.

The contents of the constant buffer would only have to be set once per frame (assuming they are the same for all draw calls).
You'll still need to set the constant buffer once per effect, but that setting should remain between frames, so you'd only need to set it once when you create a new effect. After that, you never touch it, only update the contents of the constant buffer.
Sirob Yes.» - status: Work-O-Rama.
Oh , I guess I just misunderstood how constant buffers work. Thank's for the enlightenment :)

By the way , if anyone wants a solution for the pClassLinkage thing.
Just recompile the D3DX11Effects.lib with a small change to code in EffectNonRuntime.cpp , line 1270. Replace the original code with:

// This is a regular shaderD3D_FEATURE_LEVEL fLevel = m_pDevice->GetFeatureLevel();if( pShader->pReflectionData->RasterizedStream == D3D11_SO_NO_RASTERIZED_STREAM ){   pShader->IsValid = FALSE;}else if( fLevel == D3D_FEATURE_LEVEL_11_0 ){   if( FAILED( (m_pDevice->*(pShader->pVT->pCreateShader))( (UINT *) pShader->pReflectionData->pBytecode, pShader->pReflectionData->BytecodeLength, m_pClassLinkage, &pShader->pD3DObject) ) )                    pShader->IsValid = FALSE;}else{   if( FAILED( (m_pDevice->*(pShader->pVT->pCreateShader))( (UINT *) pShader->pReflectionData->pBytecode, pShader->pReflectionData->BytecodeLength, 0, &pShader->pD3DObject) ) )                    pShader->IsValid = FALSE;}


Basically if you don't have a feature level of 11 , the pClassLinkage is not passed.

[Edited by - Xsy on November 7, 2009 2:36:16 PM]
This is a known bug in the Effects11 system.
I got a new question :) I am wondering if the Effects11 framework has support for feature level 9_3 shaders? If there is support , I would love to know how exactly can I use effects11 interfaces with SM3 effects. At the moment I tried several methodes:

1. Write an effect exactly like it's written to the D3D9 platform , compile to fx_5_0 with a SHADER_DEBUG flag for backwards compatibility. The compile works but when I use D3DX11LoadFromMemory and try to get a handle to the technique using GetTechniqueByIndex I get an error : " Invalid technique index (0) ".

2. Write an effect with a technique11 and just compile to vs_3_0 , ps_3_0 , I get a compile error saying that I can't compile SM3 shaders to a D3D10 target. Using technique ( and not technique11 ) results the same error I mentioned in #1.

Basically , if D3D11 is designed so it could work on DX9 Hardware , I guess there should be a way to initiate a ID3DX11Effect interface with a SM3 effect , I just wonder if it's even supported yet , before I venture into the source code :)
You'll have to compile using the down level targets, [vs,ps]_4_0_level_9_[0,3], if you want this to work. These are new targets were added just for this. They get the compiler to dump out code compatible with the DX10+ system while using 9.X shader code.
Oh that's awesome , I wonder how I missed that , thank's alot man :)
Too bad its quiet slow comparing to regular D3D9 shaders and interface , but I guess it'll get optimized later.

This topic is closed to new replies.

Advertisement