Graphics
Intel® graphics drivers and software, compatibility, troubleshooting, performance, and optimization
22666 Discussions

DX12: ExecuteIndirect and multiple pipeline states

masv
Débutant
3 368 Visites

CPU: i5-6300HQ
GPU: Intel HD Graphics 530
Driver: Have tried latest stable and latest beta
OS: Windows 10 64-bit
API: DirectX 12

Not sure if driver bug or just me using it wrong.

I've encountered a problem with using ExecuteIndirect and multiple pipeline states. It seems like previous ExecuteIndirect commands are not issued when changing the pipeline state and calling ExecuteIndirect again. So the only ExecuteIndirect commands that are issued are the ones after the last pipeline state change. I've tried visualize the problem in the code below:

m_commandList->SetPipelineState( m_pipelineState0 );
m_commandList->ExecuteIndirect( ... ); // NOT drawn

m_commandList->SetPipelineState( m_pipelineState1 );
m_commandList->ExecuteIndirect( ... ); // NOT drawn
m_commandList->ExecuteIndirect( ... ); // NOT drawn

m_commandList->SetPipelineState( m_pipelineState2 );
m_commandList->ExecuteIndirect( ... ); // Drawn
m_commandList->ExecuteIndirect( ... ); // Drawn
m_commandList->ExecuteIndirect( ... ); // Drawn

The problem can be reproduced by downloading the Execute Indirect Sample (https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12ExecuteIndirect), duplicating the pipeline state and splitting the ExecuteIndirect commands into two commands. Something like this:

// NOT drawn
m_commandList->SetPipelineState( m_pipelineState0 );
m_commandList->ExecuteIndirect(
				m_commandSignature.Get(),
				TriangleCount / 2,
				m_commandBuffer.Get(),
				CommandBufferSizePerFrame * m_frameIndex,
				nullptr,
				0);

// Drawn
m_commandList->SetPipelineState( m_pipelineState1 );
m_commandList->ExecuteIndirect(
				m_commandSignature.Get(),
				TriangleCount / 2,
				m_commandBuffer.Get(),
				CommandBufferSizePerFrame * m_frameIndex + ( TriangleCount / 2 ) * sizeof( IndirectCommand ),
				nullptr,
				0);

Thanks,
Marcus

0 Compliments
5 Réponses
Michael_C_Intel2
Employé
3 369 Visites

Hi Masv,

I have submitted an ticket and will work with the driver to team to investigate.  I think I have all the information I need, but may need some additional details. I will update when I know something. 

-Michael 

0 Compliments
Michael_C_Intel2
Employé
3 369 Visites

Hi Marcus,

We are unable to reproduce this issue. For your reference we tried the latest beta driver (4404) on a desktop system and a MSI notebook with an i7-6700HQ (which has HD 530 graphics). Are there any system setup or configurations you use on your development system? Any other items that may help us reproduce the issue? 

Thanks,

-Michael 

0 Compliments
masv
Débutant
3 369 Visites

Hi Michael!

Not any I'm aware of. I'm running the application on a Acer Aspire Nitro VN7-592G and, as I've stated, I've tested both the latest beta (4404) and the latest stable (4380).

Here's the exact code I'm using in the D3D12ExecuteIndirect sample:
D3D12ExecuteIndirect.h: http://pastebin.com/w1iCGaiD
D3D12ExecuteIndirect.cpp: http://pastebin.com/aZv54ug4

I've split up the rendering into two ExecuteIndirect-calls with separate pipeline states. The first ExecuteIndirect renders all but four triangles and the second one renders the remaining four. Here's how that looks:

// No triangles drawn
m_commandList->SetPipelineState( m_pipelineState0.Get() );
m_commandList->ExecuteIndirect(
    m_commandSignature.Get(),
    TriangleCount - 4,
    m_commandBuffer.Get(),
    CommandBufferSizePerFrame * m_frameIndex,
    nullptr,
    0 );

// 4 triangles drawn
m_commandList->SetPipelineState( m_pipelineState1.Get() );
m_commandList->ExecuteIndirect(
    m_commandSignature.Get(),
    4,
    m_commandBuffer.Get(),
    CommandBufferSizePerFrame * m_frameIndex + ( TriangleCount - 4 ) * sizeof( IndirectCommand ),
    nullptr,
    0 );

The dedicated GPU renders all 1024 triangles, while Intel HD Graphics 530 only renders the four in the last ExecuteIndirect. However, if I remove the last pipeline state change so it looks like this:

// All triangles drawn
m_commandList->SetPipelineState( m_pipelineState0.Get() );
m_commandList->ExecuteIndirect(
    m_commandSignature.Get(),
    TriangleCount - 4,
    m_commandBuffer.Get(),
    CommandBufferSizePerFrame * m_frameIndex,
    nullptr,
    0 );
m_commandList->ExecuteIndirect(
    m_commandSignature.Get(),
    4,
    m_commandBuffer.Get(),
    CommandBufferSizePerFrame * m_frameIndex + ( TriangleCount - 4 ) * sizeof( IndirectCommand ),
    nullptr,
    0 );

Then all triangles are rendered on Intel HD Graphics 530 aswell.

I'm currently also having a bit of problem with the timeout detection recovery (TDR) sometimes kicking in when using ExecuteIndirect on Intel HD Graphics 530. Could that be a contributing factor and do you have any suggestions on how to avoid it?

Kind regards,
Marcus

0 Compliments
Michael_C_Intel2
Employé
3 369 Visites

Thanks Marcus we will see if this helps us reproduce the issue. 

Also you can increased the TDR delay and see if the helps. Here is a MSDN page the goeas over the regkey changes needed:

https://msdn.microsoft.com/en-us/library/windows/hardware/ff569918(v=vs.85).aspx

-Michael

0 Compliments
masv
Débutant
3 369 Visites

Thanks for the link Michael! It unfortunately didn't help with the problem I've reported here.

If there is any more information I can give you, just let me know. I'm currently working on a bigger project where I encountered the problem in the first place. I could send it to you, but I doubt it would make any difference.

0 Compliments
Répondre