Effects ctor error

Started by
5 comments, last by Clutchplate 10 years, 4 months ago

Hi there,

I am getting an E_FAIL error from the ctor of the Effects class. This is the code:


string compileErrors;
var effectBytes = ShaderBytecode.CompileFromFile(filename, "fx_4_0", ShaderFlags.None, EffectFlags.None,null,null, out compileErrors);
this.effect = new Effect(Renderer.RenderDevice, effectBytes);

This code throws an exception with absolutely no detail in it. The filename shader file contains some structs, pixelshaders, vertexshaders and a technique. It's an ANSI file (not UTF-8). I can get specific shaders out of the file just fine with code like this:


using (var bytecode = ShaderBytecode.CompileFromFile(filename, "PCPShader", "ps_5_0", ShaderFlags.None, EffectFlags.None))
{
  pixelShader = new PixelShader(direct3DDevice, bytecode);
}
 

Any ideas what could be going on here? Any ideas how to further analyze what the problem might be? Are there restrictions as to what can be in the shader file for it to be loaded like this? I'm hoping to load the shader file and then use the Effects class to get at the individual shaders and techniques.

- Lutz

Advertisement

After reading some more, I think this is not the right way to go about it. fx_5_0 is legacy and deprecated.

So is there no way to read an entire .fx file and get at the individual shaders and techniques inside it?

- Lutz

You could try running the .fx file through fxc, rather than compiling the effect in code. At least if fxc encounters an error with the shader it will report something.

I wouldn't worry too much about fx_5_0 being deprecated. SlimDX requires the old June 2010 SDK D3DX libraries for parts of it to work, and DirectX has now been folded into the Windows 8 and 8.1 SDKs, so technically the old standalone DirectX SDK is deprecated as well, although by and large people still use it.

Eric Richards

SlimDX tutorials - http://www.richardssoftware.net/

Twitter - @EricRichards22

A look at your shader code might reveal something, especially how you set up your techniques. I noticed you use SM 5 shaders, but fx_4_0 effects (which are actually SM 4). That's probably the mismatch and yes IIRC you don't get any useful feedback.

Thanks for the hint. That was in fact the problem. I have it loading fine now, however, I have now hit another issue :-).

I get a E_INVALIDARG in the last line of this code:


Effect effect = new Effect(Renderer.RenderDevice, shaderbytecode);
EffectTechnique tech = mat.Effect.GetTechniqueByName("RenderInstanced");
EffectPass pass = tech.GetPassByIndex(0);
InputSignature = pass.Description.Signature;
inputLayout = new InputLayout(Renderer.RenderDevice, InputSignature, DiffuseColorInstancedVertex.GetInputLayout());

The technique looks like this:


technique11 RenderInstanced
{
  pass P0
  {
    SetVertexShader( CompileShader( vs_5_0, DiffInstVertShader() ) );
    SetGeometryShader( NULL );
    SetPixelShader( CompileShader( ps_5_0, DiffInstPixShader() ) );
    SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF);
    SetDepthStencilState( EnableDepthTestWrite, 0 );
  }
}
?
?

The vertex shader looks like this:


struct VS_OUTPUT_INST
{
   float4 Pos : SV_POSITION;
   float3 Normal : NORMAL;
   float4 Color : COLOR;
   row_major float4x4 mtxTransform : mtxTransform;
   float4 Tint : Tint;
};
?
 
VS_OUTPUT_INST DiffInstVertShader(VS_OUTPUT_INST vsIn)
{
  VS_OUTPUT_INST outp = (VS_OUTPUT_INST)0;
  [snip]
  return outp;
} 

The pixelshader:


float4 DiffInstPixShader(VS_OUTPUT_INST inpt) : SV_Target
{
  return inpt.Color * inpt.Tint;
}

And the inputlayout for DiffuseColorInstancedVertex is this:


new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0, InputClassification.PerVertexData, 0),
new InputElement("NORMAL", 0, Format.R32G32B32_Float, 16, 0, InputClassification.PerVertexData, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 32, 0, InputClassification.PerVertexData, 0),
new InputElement("mtxTransform",0,Format.R32G32B32A32_Float,0,1,InputClassification.PerInstanceData,1),
new InputElement("mtxTransform",1,Format.R32G32B32A32_Float,16,1,InputClassification.PerInstanceData,1),
new InputElement("mtxTransform",2,Format.R32G32B32A32_Float,32,1,InputClassification.PerInstanceData,1),
new InputElement("mtxTransform",3,Format.R32G32B32A32_Float,48,1,InputClassification.PerInstanceData,1),
new InputElement("Tint", 0, Format.R32G32B32A32_Float, 64, 1, InputClassification.PerInstanceData, 1),

And the struct is defined like this:


[StructLayout(LayoutKind.Sequential)]
public struct DiffuseColorInstancedVertex
{
 
  private Vector4 position; 
  private Vector3 normal;
  private readonly float reserved2;
  private Vector4 color;
  private Matrix transform;
  private Vector4 tint;
  ....
}

Not sure what is going on here, the error message is not very helpful.

Thanks for any pointers.

- Lutz

I think your offsets are wrong for the vertex shader input structure. You are saying that the offset into the COLOR element of the struct should be 32 bytes, but the way your shader structure is written, I think that that should be 28 instead, since you don't have the extra float padding defined in the HLSL.

I would try either using InputElement.AppendAligned instead of explicit offsets, or adding in a junk float to your hlsl structure definition, along with a corresponding dummy R32_Float element in the InputElement array.

Using AppendAligned would look like this, since you need to give a 0 offset for the first element of each slot, I believe.


new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0, InputClassification.PerVertexData, 0),
new InputElement("NORMAL", 0, Format.R32G32B32_Float, InputElement.AppendAligned, 0, InputClassification.PerVertexData, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, InputElement.AppendAligned, 0, InputClassification.PerVertexData, 0),
new InputElement("mtxTransform",0,Format.R32G32B32A32_Float,0,1,InputClassification.PerInstanceData,1),
new InputElement("mtxTransform",1,Format.R32G32B32A32_Float,InputElement.AppendAligned,1,InputClassification.PerInstanceData,1),
new InputElement("mtxTransform",2,Format.R32G32B32A32_Float,InputElement.AppendAligned,1,InputClassification.PerInstanceData,1),
new InputElement("mtxTransform",3,Format.R32G32B32A32_Float,InputElement.AppendAligned,1,InputClassification.PerInstanceData,1),
new InputElement("Tint", 0, Format.R32G32B32A32_Float, InputElement.AppendAligned, 1, InputClassification.PerInstanceData, 1),

Eric Richards

SlimDX tutorials - http://www.richardssoftware.net/

Twitter - @EricRichards22

I tried all of those, but nothing worked:

I added an extra float like this in the shader code:


struct VS_OUTPUT_INST
{ 
  float4 Pos : SV_POSITION;
  float3 Normal : NORMAL;
  float reserved : Reserved;
  float4 Color : COLOR;
  row_major float4x4 mtxTransform : mtxTransform;
  float4 Tint : Tint;
};

I left the InputLayput as I had it and it didn't work.

I then changed the InputLayout, inserting the dummy float with an offset of 28. Also did not work.

Then I removed that float in the InputLayout and added the AppendAligned flags as you posted. That also did not work.

Got the same E_INVALIDARG error in all cases....

This topic is closed to new replies.

Advertisement