locked
Can't use 'SV_InstanceID' in a vertex shader

    Question

  • I am trying to do instancing in my pixel shader in my metro style app, but when I add SV_InstanceID - the compiler complains about it not being supported by VS 4.0 level 9.3. Is VS forcing the use of an older shader model? Do I need to call fxc manually to get it to work or am I doing something wrong?

    This is the error I am getting:

    Error 5 error X4502: invalid vs_4_0_level_9_3 input semantic 'SV_InstanceID' MyVertexShader.hlsl 27 22 D3DRenderer

    My vertex shader:

    struct PerInstanceData
    {
        matrix model;
        float4 opacity;
    };
    
    cbuffer MyConstantBuffer : register(b0)
    {
        matrix view;
        matrix projection;
        float3 highlight;
        float3 shadow;
        float textureTransitionAmount;
    //};
    //
    //cbuffer InstanceDataConstantBuffer
    //{
        PerInstanceData g_instances[150];
        uint g_numOfInstances;
    }
    
    struct VertexShaderInput
    {
        float3 pos : POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
        uint instanceId : SV_InstanceID;
    };
    
    struct PixelShaderInput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
        //uint instanceID : INSTANCEID;
        float2 opacity : TEXCOORD1;
    };
    
    PixelShaderInput main(VertexShaderInput input)
    {
        PixelShaderInput vertexShaderOutput;
        float4 pos = float4(input.pos, 1.0f);
    
        // Transform the vertex position into projection space.
        pos = mul(pos, g_instances[input.instanceId].model);
        pos = mul(pos, view);
        pos = mul(pos, projection);
        vertexShaderOutput.pos = pos;
    
        // Pass through the texture coordinate without modification.
        vertexShaderOutput.tex = input.tex;
    
        vertexShaderOutput.opacity = g_instances[input.instanceId].opacity;
        return vertexShaderOutput;
    }

    Somehow the code does not want to format correctly - let's try a screenshot...


    Monday, June 11, 2012 6:09 PM

Answers

  • Actually DirectX 11 supports hardware instancing with Feature Level 9.3, but you don't get the system generated InstanceID value as you would with Feature Level 10.0 or later hardware.

    When you call D3D11CreateDevice you can give a set of feature levels you support. You are free to require something other than the default (which is FL 9.1, 9.2, 9.3, 10.0, 10.1, or 11.0), so you might for example require FL 9.3 or FL 10.0 for your application. Note you don't have to have multiple feature levels. If you want your app can always require Feature Level 10.0 and that will also work on FL 10.1, 11.0, or 11.1 devices as well.

    Fallback back to WARP is an option, but that's not a good performance fallback. It's better if you just do a bunch of drawing on Feature Level 9.1 or 9.2 rather than try to use 'hardware' instancing. You can check out the legacy DirectX SDK'a Direct3D 9 and Direct3D10 instancing samples for some ideas on different choices for handling this scenario--be sure to see <http://blogs.msdn.com/b/chuckw/archive/2012/03/22/where-is-the-directx-sdk.aspx>




    Monday, June 11, 2012 11:48 PM

All replies

  • Nevermind, I think I have found out where to switch to a different shader model. The option does not show by default in the properties pane when you select the hlsl file in the solution explorer, but when you right click the file and select properties - a property pages window opens where you can change the shader model.

    Now - what happens if my app runs on a device that does not support Shader Model 4.0? Does it automatically fall back to WARP or do I need to write some custom code to do a manual fallback?


    Filip Skakun

    Monday, June 11, 2012 9:14 PM
  • The shader profiles are 'forward' compatible, not backwards. So you can apply a 4_0_level_9_3 profile to a Feature Level 9.3, 10.0, 10.1, 11.0, or 11.1 device, but it will fail the Set*Shader call if you try to apply it to a Feature Level 9.1 device.

    Generally speaking you should use the 'lowest' shader profile that meets your minimum required Feature Level, and then create more advanced shaders that you only use with higher Feature Level devices.

    The "4_0_level_9_x" profiles are a little strange. Essentially they compile the shader twice internally: once for a Shader Model 2.0 profile and again for a Shader Model 4.0 profile. This means that you have to write the shader to fit the constraints of Shader Model 2.0 (specifically the 2.0 profile for FL 9.1 and FL 9.2, the 2.0a profile for Vertex Shaders with FL9.3, and the 2.0b profile for Pixel Shaders with FL 9.3) and it has to compile succesfuly for both profiles.

    Monday, June 11, 2012 9:31 PM
  • Thanks for your response, Chuck!

    So if my shader uses instancing and as sych requires Feature level D3D_FEATURE_LEVEL_10_0 and my D3D11CreateDevice calls returns something lower - I will need to either write a separate renderer that works without instancing or use WARP, right? Is WARP supported in WinRT?


    Filip Skakun

    Monday, June 11, 2012 9:43 PM
  • Actually DirectX 11 supports hardware instancing with Feature Level 9.3, but you don't get the system generated InstanceID value as you would with Feature Level 10.0 or later hardware.

    When you call D3D11CreateDevice you can give a set of feature levels you support. You are free to require something other than the default (which is FL 9.1, 9.2, 9.3, 10.0, 10.1, or 11.0), so you might for example require FL 9.3 or FL 10.0 for your application. Note you don't have to have multiple feature levels. If you want your app can always require Feature Level 10.0 and that will also work on FL 10.1, 11.0, or 11.1 devices as well.

    Fallback back to WARP is an option, but that's not a good performance fallback. It's better if you just do a bunch of drawing on Feature Level 9.1 or 9.2 rather than try to use 'hardware' instancing. You can check out the legacy DirectX SDK'a Direct3D 9 and Direct3D10 instancing samples for some ideas on different choices for handling this scenario--be sure to see <http://blogs.msdn.com/b/chuckw/archive/2012/03/22/where-is-the-directx-sdk.aspx>




    Monday, June 11, 2012 11:48 PM