[SlimDX / D3D11] - Loading effects

Started by
16 comments, last by Mike.Popoloski 14 years ago
Today has been a painful introduction to Direct3D 11 for me. I have successfully got a device initiated and displaying a blank screen (no geometry). I'm now trying to load and apply an effect to get some geometry showing. Unfortunately, the loading and usage of an effect is tripping me up. I think the problem is down to the fact that I'm targetting 'FeatureLevel.Level_9_1' but I'm not sure. Here is my fx file, as simple as can be:

struct VS_IN
{
	float4 pos : POSITION;
};

struct PS_IN
{
	float4 pos : SV_POSITION;
};

PS_IN vs_main(VS_IN input)
{
	PS_IN output = (PS_IN)0;
	output.pos = input.pos;
	return output;
}

float4 ps_main(PS_IN input) : SV_Target
{
	return float4(1, 0, 0, 1);
}

technique Render
{
	pass P0
	{
		SetVertexShader(CompileShader(vs_2_0, vs_main()));
		SetPixelShader (CompileShader(ps_2_0, ps_main()));
	}
}


Note that it's simple vertex / pixel shader. And this is me trying to load the effect:

ShaderBytecode effectByteCode = ShaderBytecode.CompileFromFile("Default.fx", "Render", "fx_5_0", /*"vs_4_0_level_9_1", */ShaderFlags.EnableStrictness, EffectFlags.None);
Effect effect = new Effect(this.device, this.effectByteCode, EffectFlags.None);


The loads succeeds (although I'm unsure if it's 'safe' to use the "fx_5_0" profile when targetting Direct3D 9, and vertex / pixel shaders 2.0)? The 'vs_4_0_level_9_1' comment was an alternative profile that I tried, with no success. The problem occurs when I try to use the effect:
EffectTechnique tech = effect.GetTechniqueByIndex(0);
                    EffectPass pass = tech.GetPassByIndex(0);

                    InputLayout input = new InputLayout(this.device, pass.Description.Signature, new InputElement[]
                    {
                        new InputElement("POSITION0", 0, Format.R32G32B32_Float, 0, 0)
                    });


GetTechniqueByIndex fails with 'ID3DX11Effect::GetTechniqueByIndex: Invalid technique index (0)', which doesn't cause SlimDX to except until the InputLayout instance is created. I've tried the same with the following:

EffectTechnique tech = effect.GetTechniqueByName("Render");
                    EffectPass pass = tech.GetPassByIndex(0);

                    InputLayout input = new InputLayout(this.device, pass.Description.Signature, new InputElement[]
                    {
                        new InputElement("POSITION0", 0, Format.R32G32B32_Float, 0, 0)
                    });


But then the GetTechniqueByName method excepts with 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.' I'm not sure where I'm going wrong - if my shader code is wrong, if it's compiled incorrectly for Direct3D 9, etc. Hopefully someone can help me? Thanks.
Using Visual C++ 7.0
Advertisement
I don't think you can use the 4.0 and up profiles without using technique10 or technique11. I also don't think you can use them in the 9 feature level.
I tried 'fx_2_0', and got the exception '[7860] Effects11: Effect version is unrecognized. This runtime supports fx_5_0 to fx_5_0.'. It may just be a weird error message, but that suggests to me that ONLY the fx_5_0 is supported.

I also tried 'vs_4_0_level_9_1', but I get the exception 'error X3501: 'Render': entrypoint not found'. I'm not sure what an entry point in terms of an effect file, but I assumed 'Render' would be it..!

Using Visual C++ 7.0
Leave the entry point null or blank (I forget which is valid). Use technique10.
As far as I can tell, neither is valid - if it's null I get the exception:

"String reference not set to an instance of a String.
Parameter name: s"

If set it to be empty string, I get another exception

"Index was outside the bounds of the array."

I thought I couldn't use 'technique10' when using the 'FeatureLevel.Level_9_1' feature level?

Thanks for your help so far.
Using Visual C++ 7.0
Dunno. I'm just guessing. I hadn't ever been able to get effects in D3D11 working properly, although I didn't try very hard. It's the main reason we don't have D3D11 samples in SlimDX yet.
I did wonder why there weren't any. I also wondered why Effect.FromFile was missing - is the effects framework unfinished in SlimDX perhaps?

In fact, should I even be loading effect files with ShaderBytecode.CompileFromFile I wonder? It looks to me like a shader compilation function, and not an effects one...
Using Visual C++ 7.0
Effects11 (the underlying native library) is rather different than the previous versions of the effect framework. You're supposed to compile the effect to bytecode and load that, there isn't a 'from file' method any longer.
I got a bit further! Not necessarily in the right direction. I made file a plain vertex shader (no techniques, passes, etc).
struct VS_IN{	float4 pos : POSITION;};struct PS_IN{	float4 pos : SV_POSITION;};PS_IN vs_main(VS_IN input){	PS_IN output = (PS_IN)0;	output.pos = input.pos;	return output;}


And tried to load and it as follows:

effectByteCode = ShaderBytecode.CompileFromFile("Default2.fx", "vs_main", "vs_4_0_level_9_1", ShaderFlags.None, EffectFlags.None);vertexShader = new VertexShader(this.device, effectByteCode);[...]InputLayout input = new InputLayout(this.device, ShaderSignature.GetInputSignature(this.effectByteCode), new InputElement[]    {         new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0)    });context.VertexShader.Set(this.vertexShader);


The shader appears to be loaded, but falls on creating the InputLayout with this error:

'[7560] D3D11: ERROR: ID3D11Device::CreateInputLayout: Input Signature in bytecode could not be parsed. Data may be corrupt or in an unrecognizable format. [ STATE_CREATION ERROR #161: CREATEINPUTLAYOUT_UNPARSEABLEINPUTSIGNATURE ]'
Using Visual C++ 7.0
You have to use technique11, the others will not work when using Effects11 API.

You have to compile with "fx_5_0", nothing else will work when using Effects11 API.

In your effect file, you have to compile for your target: which is 9_1, not 2_0 when using feature levels.


SetVertexShader(CompileShader(vs_4_0_level_9_1, vs_main()));

This topic is closed to new replies.

Advertisement