Sign in to follow this  
ErnieDingo

DirectX 11 Sharpdx - Instancing - ATI Vs Nvidia

Recommended Posts

Hi guys,

 

Working through a problem at the moment with myself and my team member around an issue with development.

 

So, here goes.

 

My PC currently has a ATI R290 card , his a GTX 960 card. (this may or may not be relevant based on some testing).

 

Currently I have instancing working with my game so basically I have 2 buffers being loaded into the GPU with instance and vertex data.  This works perfectly well on my R290 and my test machine (sans dev environment) with a ATI 7800. The buffer is a row_major matrix that Im loading for each instance.

 

On my team members PC, he has a GTX 960.  The issue is, and I have walked him through it is that the Instance buffer isn't loading in.  Now, I think I have coded in a way to be an issue.  

 

In the input assembler stage, I am loading the instance buffer in before loading the vertex buffer, in 2 separate calls.  I am also setting some other variables in the input assembler along the way.  Now they aren't being set in the same spot at the same time, but very close, only a few lines of code difference (But instance is being loaded ahead of vertex data).  This shouldn't really be an issue, and its not on my ATI cards. 

 

But my colleague has mentioned that the input assembler stage can be a little tempramental depending on the card being used.  SO.

 

I've rewritten the code to load the buffers at the same time.  2 different versons of the calls, 1 call using the Sharpdx buffer binding (setvertexbuffers call), and the other by passing the input array in including strides etc (different version sharpdx setvertexbuffers call).  

 

He is to test these, but I am wondering if there is anything else I may need to consider.

 

We narrowed it down to the instance buffer matrix not being passed by passing matrix via constant buffer instead and testing the code worked (rendered all objects in same spot, but it worked).  When it didn't work, it was rendering black triangles into the first half of the top right quartile of the screen (I had this also while developing instancing and it is consistent).

 

Sorry for the long post, I'm endeavouring to work through this one.  Will let you know my results, just any other suggestions?  At the least I've rewritten the code to test other vectors of attack, I hope he will be coming back with answers stating it works.  Otherwise, where to from here?

Share this post


Link to post
Share on other sites

the input assembler stage can be a little tempramental depending on the card being used
If you're using the API correctly (no warnings/errors being emitted by the debug layer), then the behaviour should be the same on every card. 

 

Enable the D3D debug layer by passing D3D11_CREATE_DEVICE_DEBUG when you create the device, and then check in the Visual Studio 'output' window for debug layer messages when you run your game.

 

You'll have to translate this from C++ to SharpDX, but this code tells D3D to throw an exception when you trigger a warning/error, which makes them impossible to miss:

ID3D11Device* m_device = ...;
ID3D11InfoQueue* m_debugInfoQueue = nullptr;
m_device->QueryInterface(IID_ID3D11InfoQueue, (void**)&m_debugInfoQueue);
m_debugInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_ERROR, TRUE );
m_debugInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_WARNING, TRUE );

Share this post


Link to post
Share on other sites

 

the input assembler stage can be a little tempramental depending on the card being used
If you're using the API correctly (no warnings/errors being emitted by the debug layer), then the behaviour should be the same on every card. 

 

Enable the D3D debug layer by passing D3D11_CREATE_DEVICE_DEBUG when you create the device, and then check in the Visual Studio 'output' window for debug layer messages when you run your game.

 

You'll have to translate this from C++ to SharpDX, but this code tells D3D to throw an exception when you trigger a warning/error, which makes them impossible to miss:

ID3D11Device* m_device = ...;
ID3D11InfoQueue* m_debugInfoQueue = nullptr;
m_device->QueryInterface(IID_ID3D11InfoQueue, (void**)&m_debugInfoQueue);
m_debugInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_ERROR, TRUE );
m_debugInfoQueue->SetBreakOnSeverity( D3D11_MESSAGE_SEVERITY_WARNING, TRUE );

Cheers, will give it a spin.  I'm getting no errors at the moment from current debug mode, but I will continue my investigation.

 

Appreciate it.

Share this post


Link to post
Share on other sites

Thanks bud, I have uncovered a raft of small issues that didnt seem to bother the ATI Driver but were showing up.  The worst being a data alignment issue on the Matrix instance buffer.  This wasn't an issue in one SetVertexBuffer call because I was setting the alignment correctly, BUT if I used the other call, the creation of the binding was incorrectly offset.  This was causing an issue.  

 

I've attached the code for Sharpdx for everyone's reference in future.

    D3D11.InfoQueue m_infoQueue = m_parentDevice.QueryInterface<D3D11.InfoQueue>();

    try
    {
        Context.DrawInstanced(vb.m_bufferRun, a_renderCount, vb.m_startingIndex, 0);
    }
    catch
    {               
        for (int j = 0; j < m_infoQueue.NumStoredMessages; j++)
        {
            D3D11.Message a = m_infoQueue.GetMessage(j);

            Console.WriteLine(a.Description);
        }
    }

On another note, I was not setting the backbuffer resolution to the correct resolution and leaving it to be set by the window handle, this also caused an exception in relation to setting the stencil buffer in SetRenderTargets.  This also was fixed.  Thanks for your help!


Added note: still have to wait on my colleague to test the changes :)  But I feel these issues were at the core of it.  Also, Sharpdx AppendAligned doesn't seem to work and was causing an issue!

Share this post


Link to post
Share on other sites

Thanks bud, I have uncovered a raft of small issues that didnt seem to bother the ATI Driver but were showing up.  The worst being a data alignment issue on the Matrix instance buffer.  This wasn't an issue in one SetVertexBuffer call because I was setting the alignment correctly, BUT if I used the other call, the creation of the binding was incorrectly offset.  This was causing an issue.  

 

I've attached the code for Sharpdx for everyone's reference in future.

    D3D11.InfoQueue m_infoQueue = m_parentDevice.QueryInterface<D3D11.InfoQueue>();

    try
    {
        Context.DrawInstanced(vb.m_bufferRun, a_renderCount, vb.m_startingIndex, 0);
    }
    catch
    {               
        for (int j = 0; j < m_infoQueue.NumStoredMessages; j++)
        {
            D3D11.Message a = m_infoQueue.GetMessage(j);

            Console.WriteLine(a.Description);
        }
    }

On another note, I was not setting the backbuffer resolution to the correct resolution and leaving it to be set by the window handle, this also caused an exception in relation to setting the stencil buffer in SetRenderTargets.  This also was fixed.  Thanks for your help!


Added note: still have to wait on my colleague to test the changes :)  But I feel these issues were at the core of it.  Also, Sharpdx AppendAligned doesn't seem to work and was causing an issue!

YEah NVIdia can be a bit finicky when you dont set the backbuffers to the exact client rect size, I saw extreme slowdowns in those cases (a 970M ran at the same speeds of a 4600HD).

Share this post


Link to post
Share on other sites
Just to report in that my colleague has tested the fixes i made and it works. Thanks for the info on testing the api calls.

At least i know now that ati drivers seen a little more tolerant but that isn't always a good thing.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this