[HLSL/DX] Compilation fail

Hi there,

I’m currently learning HLSL and it’s fun. My research engine is currently running the OpenGL port of MonoGame but when I try to use DirectX it’s not working. An exception is thrown and I think that my shader code is not valid for DirectX.

This is my shader

I tried to debug the code myself and saw that GetInputLayout method in GraphicsDevice.DirectX throws a SharpDX.SharpDXException.
There are two screenshots of my debug session, here. This code is called by my MeshRenderer which has a Material object (where is loaded the effect)

An issue on my github repo has been opened about that.

It seems that the outputs of my VertexShaderFunction do not match with the inputs of the PixelShaderFunction. But I not sure to understand where is the problem.

Is anyone can help me to correct my code please ?


Worth checking this http://www.monogame.net/documentation/?page=Custom_Effects
Could be the SV_POSITION register that you need instead of POSITION?

@procd is correct here. Usually when GetInputLayout throws an exception it is because your vertex shader inputs don’t match your VertexBuffer format.

Hi guys,

A big thank you for your reply, it’s almost working now !

Almost because I need to use a shader profile 9_3 instead of 9_1 for my DiffuseSpecularEffect, If I don’t use this profile, I’ve this error in the Pipeline tool

D:\\Projets\\Sources\\C3DE\\C3DE.Content\\FX\\DiffuseSpecularTextureEffect.fx(140,5): error X5608: Compiled shader code uses too many arithmetic instruction slots (92). Max. allowed by the target (ps_2_0) is 64.
(1,1): error X5609: Compiled shader code uses too many instruction slots (97). Max. allowed by the target (ps_2_0) is 96.

As I already said, I just begin my journey in shaders world with MonoGame and HLSL, my code is probably bad. It seems that there are too many operations done at the same time ?

return saturate(textureColor * input.Color * shadowTerm + AmbientColor * AmbientIntensity + specular + EmissiveColor);

I tried to compute each calculs in a separate variable and use the result in the saturate function but it hasn’t changed anything. My other shaders are working as expected with profile 9_1.

I read on the docs page that it can be less compatible with some devices ? What type or devices are concerned ? Is it for ARM device only or Desktop device too ?

A finale question: Can I use SV_Position with OpenGL target or must I write a conditional comment ?

#if SM4
	float4 Position : SV_Position;
	float4 Position : POSITION0;

Thanks again, now that DirectX port works, I can start to code an editor !

A last thing: I’m writting a blog post (in French, see Home - Demonixis Games) about the new pipeline tool and a guide about Shader porting :wink:


It has nothing to do with “same time”. It is too many instructions as a whole… as in the length of the shader program is too long. You just have to do less work in your shader.

If you look here…

Specifying Compiler Targets - Win32 apps | Microsoft Learn

… you’ll see that there is a limit of 64 arithmetic and 32 texture instructions for the ps_4_0_level_9_1 profile. Moving up to ps_4_0_level_9_3 gives you up to 512 instructions, but won’t run on some hardware.

Can I use SV_Position with OpenGL target or must I write a conditional comment ?

You need to use a conditional.

Thanks for the clarification and for this usefull link !

Is it possible to use a profile greater than level 9_3 with MonoGame ? I have not the level for now but it can be interesting for the future.

Is it possible to detect the capabilities of the hardware to load a fallback shader if it’s not compatible ?
What are the limitations with OpenGL ? I use a SM/PS_3 profile and it’s works for now, but I need to be careful right ?

It’s really very interesting and it take a lot of my time :slight_smile: Thanks again for your replies.


Sure… MonoGame fully supports higher shader models. The limit is only what DirectX and/or OpenGL supports.

Well if you try to load a shader that is incompatible with the hardware it will throw and exception. You are free to catch it and try to load another.

Ideally you could detect this ahead of time, but we don’t have anything beyond the “HiDef” or “Reach” profile. That is something we’ve discussed a bunch in the past, but we don’t have a clear solution yet.

I’m not as experienced with that, but until we move to OpenGL 4.0 I don’t think you can go above SM 3.0.

Thanks again for these clarfications :wink: