Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm following these instructions on TheCodeProject for rendering from DirectX to WPF using D3DImage.

The trouble is that now that I have no swap chain to call Present() on -- which according to the article shouldn't be a problem, but it definitely wasn't copying my back buffer.

An additional step that I have to take before I can copy the texture to WPF is to share it with a second D3D9Ex device, since D3DImage only works with DX9 (which is understandable, as WPF is built on DX9). To that end, I've modified some SlimDX code to work with DirectX 11.

I tried calling DeviceContext.Flush() (the Immediate one) at the end of each render cycle, which kind of works -- most of the time it'll show my renderings, but maybe for maybe 3 or 4 out of 60 frames each second, it'll draw my clear color instead. This makes sense -- Flush() is non-blocking; it doesn't wait for the GPU to do its thing the way SwapChain.Present does.

Any idea what the proper solution is?

I have a feeling it has something to do with my texture parameters for the back buffer, but I don't know.

share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted
First:
// Create a Query to be able to wait for the completion of the drawing:
D3D11_QUERY_DESC qd;
ZeroMemory(&qd, sizeof(qd));
qd.Query = D3D11_QUERY_EVENT;
hr = m_U->m_pd3dDevice->CreateQuery(&qd, &m_U->m_pEventQuery);
if( FAILED( hr ) )
    return hr;

After the flush put the query in the queue (there is no call like begin in this case):
// Draw!
m_U->m_pImmediateContext->DrawInstanced( 3* numTrianglesPerInstance, numInstances, 0, 0);
m_U->m_pImmediateContext->Flush();
m_U->m_pImmediateContext->End(m_U->m_pEventQuery);

Wait for the paint/flush/query to end:
// wait for drawing to come to an end:
while (S_FALSE == m_U->m_pImmediateContext->GetData(m_U->m_pEventQuery, NULL /*&GPUfinished*/, 0 /*sizeof(GPUfinished)*/, 0));

Tidy up later:
if( m_U->m_pEventQuery) m_U->m_pEventQuery->Release();
share|improve this answer
    
Works, danke schoen! –  Rei Miyasaka Sep 18 '12 at 17:47
    
You're suggesting a busy wait Greg. One should never busy wait! –  Zbyl Dec 30 '12 at 20:13
add comment

I think the proper way of syncronising the surfaces is using "Direct3D9Ex and DXGI Shared Surface Queue":

More info:

share|improve this answer
    
Thanks, this looks promising too. All the better without a spinlock. –  Rei Miyasaka Dec 30 '12 at 21:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.