Jump to content
  • Advertisement
Sign in to follow this  
dwatt

Deferred Context Usage

This topic is 767 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am adding multithread rendering to my d3d11 engine. I am encountering an issue where it is getting an out of memory error after a minute or so. Basically I have a class called renderer which is an encapsulation of a context. I create a context in the constructor and do commands on it then call finish on it to get the list then pass it to a class which encapsulates the immediate context and call execute on the list. Is there a cleanup step I am missing? I have tried using new contexts each time and that doesn't help either. For now I have one thread which builds the contexts and another which renders the contexts.

 

D3D11Renderer::D3D11Renderer(void)

{

    if (FAILED(g_Device->CreateDeferredContext(0, m_Context)))

    {

        _ASSERT(false);

    }

}

 

 

void D3D11Renderer::End(bool bPresent)

{

    m_List = nullptr;

     

    if(FAILED(m_Context->FinishCommandList(false, &m_List)))

    {

        _ASSERT(false);

    }

}

 

void D3D11RenderQueue::Execute(std::list<IRendererPointer>& List)

{

    for each(IRendererPointer Render in List)

    {

        if (Render.Cast<D3D11Renderer>()->m_List)

        {

            g_Immediate->ExecuteCommandList(Render.Cast<D3D11Renderer>()->m_List, false);

        }

    }

}

 

 

Share this post


Link to post
Share on other sites
Advertisement

Unless "m_List" is a ComPtr or some other 'smart' type that calls ->Release for you when you assign it to a new value, then you're probably leaking command lists. Are you calling Release on your ID3D11CommandLists?

Share this post


Link to post
Share on other sites
What is it that you are doing on those contexts?
Things like map/discard and the like can cause a lot of memory to be consumed; for example, iirc if you 'map' on a deferred context the driver basically creates you a whole new copy/version of what you have just mapped and ties it to the that context; when you factor in that the driver will buffer a few frames ahead memory can be eaten very quickly.

(Also, as a side note, DX11 really doesn't scale well with threading - you'll probably want to profile but outside of a few outlier cases, such as Civ5, most people didn't see an increase. Also, last I checked, AMD's drivers didn't expose the 'we can do this properly' property so you are relying on the runtime so even less chance of a speed up. NV were/are better about this, they put a huge chunk of time in to it and their DX11 driver is simply Better, but even in that case CPU gains tended to be in the 5% range at best. In short... meh.)

Share this post


Link to post
Share on other sites

calling release on the list fixed it . It had been a smart pointer but that was crashing, so I thought it must not be that type of object and changed it.

 

Thank you.

Share this post


Link to post
Share on other sites
In my current game, I had a weird performance issue where if I called release immediately after execute, sometimes release would take ~10ms to return. I "fixed" this weird issue by dumping my command lists into a queue after executing them, and releasing objects in the queue two frames after they entered it :o

I've never seen this mentioned anywhere else as a performance pitfall, so it might just be a driver edge-case that my game's uncovered, but keep an eye out anyway.

Share this post


Link to post
Share on other sites

Yeah I'm going to piggy-back on what phantom said, and advise you to steer clear of deferred contexts in D3D11. Unfortunately the way that the D3D11 API is setup just doesn't work for multithreading, and so deferred contexts were never able to live up to their promise. The biggest problem comes from the fact that the driver often needs the full pipeline state at draw or dispatch time in order patch shaders and set low-level GPU state. With deferred contexts some of the state might be inherited from a previous context, and so the driver ends up having to serialize at submission time in order to figure out the full set of state bits for a draw. The lack of lower-level memory access is also an issue, since it makes the semantics of thinks like Map/Discard more complicated.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!