DirectX11 Shader Compiling

Started by
4 comments, last by Assassin 15 years, 4 months ago
I'm running into a strange error. I am using the method 'D3DX11CompileFromMemory' to compile HLSL code into byte code, then creating a shader using 'CreatePixelShader/CreateVertexShader'. I am getting S_OK for the compile, and E_INVALIDARG from the Create*Shader. Debug info reports:

D3D11: ERROR: ID3D11Device::CreateVertexShader: Encoded Vertex Shader size doesn't match specified size. [ STATE_CREATION ERROR #166: CREATEVERTEXSHADER_INVALIDSHADERBYTECODE ]
'D3DX11CompileFromMemory' uses the 'ID3D10Blob' interface, and I am feeding Create*Shader ID3D10Blob::GetBufferPointer() and ID3D10Blob::GetBufferSize() so I am not sure where the error is occuring. I noticed that the D3D11 examples are not using these methods for shader creation, they are using the 'D3DCompile' method which seems to be undocumented. Anyone have thoughts?
Advertisement
Could you please post some snippets of relevant code (the Compile and Create calls, most importantly) and the shader? I'll see if we can reproduce the problem here.
Assassin, aka RedBeard. andyc.org
Sure thing:
   static String sHLSLStr( "hlsl" );   if (filePath.getExtension().equal(sHLSLStr, String::NoCase))      {      FrameAllocatorMarker fam;      char *buffer = NULL;      // Set this so that the D3DXInclude::Open will have this information for      // relative paths.      smD3D10Include->_pShaderFile = filePath;      FileStream* s = new FileStream();      if(!s->open( filePath, Torque::FS::File::Read ))      {         AssertISV(false, avar("GFXD3D11Shader::initShader - failed to open shader '%s'.", filePath.getFullPath().c_str()));         Con::errorf("GFXD3D11Shader::initShader - failed to open shader '%s'.", filePath.getFullPath().c_str());         return;      }      if( s != NULL )      {         U32 bufSize = s->getStreamSize();         buffer = (char *)fam.alloc( bufSize );         s->read( bufSize, buffer );         res = D3DX11CompileFromMemory(buffer, bufSize, filePath.getFullPath(),             defines, smD3D10Include, "main", target, flags, 0, NULL, &code,            &errorBuff, NULL);         s->close();      }      else      {         res = D3DX11CompileFromFile(filePath.getFullPath().utf16(), defines,            smD3D10Include, "main", target, flags, 0, NULL, &code,            &errorBuff, NULL);      }      SAFE_DELETE( s );    }// -- SNIP -- (here lies code for handling errors)   // Create the proper shader if we have code   if( code != NULL )   {      const void *blobPtr = code->GetBufferPointer();      SIZE_T blobSize = code->GetBufferSize();      if (target.compare("ps_", 3) == 0)               res = mD3D11Device->CreatePixelShader( blobPtr, blobSize, NULL, NULL/*&mPixShader*/ );      else         res = mD3D11Device->CreateVertexShader( blobPtr, blobSize, NULL, NULL/*&mVertShader */);      if (SUCCEEDED(res))      {         _getShaderConstants(bufferLayoutF, bufferLayoutI);      }      // Ok, we've got a valid shader and constants, let's write them all out.      if (!_saveCompiledOutput(filePath, code, bufferLayoutF, bufferLayoutI))         Con::errorf("Unable to save shader compile output for: %s", filePath);   }   SAFE_RELEASE( code );   SAFE_RELEASE( errorBuff );

The shader is compiled using "vs_2_0" target. I can post it, as well, but it's not doing anything fancy. I changed the shader itself to use the system value semantics instead of VS/PS 2/3 semantics (Like POSITION), but that made no difference.

Edit: Sorry, here's the shader:
//*****************************************************************************// Glow shader//*****************************************************************************//-----------------------------------------------------------------------------// Structures                                                                  //-----------------------------------------------------------------------------struct VertData{   float2 texCoord        : TEXCOORD0;   float4 position        : POSITION;};struct ConnectData{   float4 hpos            : POSITION;   float2 tex0            : TEXCOORD0;   float2 tex1            : TEXCOORD1;   float2 tex2            : TEXCOORD2;   float2 tex3            : TEXCOORD3;};//-----------------------------------------------------------------------------// Main                                                                        //-----------------------------------------------------------------------------ConnectData main( VertData IN,                  uniform float4x4 modelview       : register(C0),                  uniform float2   offset0         : register(C4),                  uniform float2   offset1         : register(C5),                  uniform float2   offset2         : register(C6),                  uniform float2   offset3         : register(C7)){   ConnectData OUT;   OUT.hpos = mul(modelview, IN.position);      OUT.tex0 = IN.texCoord + offset0;   OUT.tex1 = IN.texCoord + offset1;   OUT.tex2 = IN.texCoord + offset2;   OUT.tex3 = IN.texCoord + offset3;   return OUT;}
Quote:Original post by patw

The shader is compiled using "vs_2_0" target. I can post it, as well, but it's not doing anything fancy. I changed the shader itself to use the system value semantics instead of VS/PS 2/3 semantics (Like POSITION), but that made no difference.


Thanks for your response. I think that the D3D11 runtime expects to receive shaders that are compiled with at least vs_4_0 target, although the compiler can output shaders to any known D3D target. Unfortunately, it looks like the runtime interprets the vs_2_0 blob as corrupt rather than seeing that it's simply compiled with an inappropriate target.

Depending on which feature level you're targeting, you have a choice of shader targets: vs_4_0, vs_4_0_level_9_1, vs_4_0_level_9_3, vs_5_0
Assassin, aka RedBeard. andyc.org
Ahh fantastic, thanks for the quick reply. I am coming at DX11 from DX9/360 and not a DX10 background so I'm stumbling along.

Here's a question. We've also found, with the new shader compiler in the Nov2k8 SDK (under DX9 proper vista/XP), that it is incorrectly optimizing some shaders, resulting in samplers actually getting optimized out. (In one case, it's optimizing out a light-map, and stuffing a different texture. The 'change around code order and hope for the best' doesn't seem to be working this time. Where is a good place to report these issues?
Quote:Original post by patw
Ahh fantastic, thanks for the quick reply. I am coming at DX11 from DX9/360 and not a DX10 background so I'm stumbling along.


The debug layer feedback is usually quite useful in D3D10 & 11, unfortunately it seems a bit lacking in this particular case.

Quote:Here's a question. We've also found, with the new shader compiler in the Nov2k8 SDK (under DX9 proper vista/XP), that it is incorrectly optimizing some shaders, resulting in samplers actually getting optimized out. (In one case, it's optimizing out a light-map, and stuffing a different texture. The 'change around code order and hope for the best' doesn't seem to be working this time. Where is a good place to report these issues?


I believe we have a public forum or email alias, but I can't seem to locate it at the moment. In this case, if you'd like to send your shader, along with the options & method you use to compile it, to my email address (removed), I'll send it along to the shader compiler team.

I believe the forum here is monitored by other developers on the runtime & compiler teams: http://forums.xna.com/forums/27.aspx

[Edited by - Assassin on December 9, 2008 4:40:15 PM]
Assassin, aka RedBeard. andyc.org

This topic is closed to new replies.

Advertisement