D3D12Texture Sample - flickering texture

MachTwo
Posts: 59
Joined: Fri Oct 04, 2013 8:21 am

D3D12Texture Sample - flickering texture

Postby MachTwo » Mon May 11, 2020 1:04 pm

Hello,

If you follow the D3D12Texture SDK example, and place the CursorTexture over the Mooney MFD (as per the example instructions) - the entire VC texture object area flickers.

You can easily reproduce this issue by running the above example whilst stressing the CPU/GPU using HeavyLoad:

https://www.jam-software.com/heavyload

We would really like to see this issue resolved for v5 - as it essentially breaks any DX12 RTT implementations.
Regards,

Andrew
Andrew Wilson
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

MachTwo
Posts: 59
Joined: Fri Oct 04, 2013 8:21 am

Re: D3D12Texture Sample - flickering texture

Postby MachTwo » Sat May 16, 2020 6:28 am

Hi Rob / Beau -

Did you have any luck reproducing this?

If it helps - you can have any number of RTT’s; they will all flicker at the same time.
Andrew Wilson
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

User avatar
lkalam
Posts: 232
Joined: Wed Dec 07, 2011 10:23 am

Re: D3D12Texture Sample - flickering texture

Postby lkalam » Fri May 29, 2020 10:18 am

Hello guys,

would it be at all possible to have a look at this? It is very easy to reproduce given the steps above... If this is not fixed in HF2, a lot of functionality will be lost.

Thank you,
Lefteris Kalamaras
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

MachTwo
Posts: 59
Joined: Fri Oct 04, 2013 8:21 am

Re: D3D12Texture Sample - flickering texture

Postby MachTwo » Fri Jun 19, 2020 7:25 pm

I've read here that the HF2 release is imminent and yet there has been no word from anyone at LM on this issue.

It will be disappointing to see this issue remain in HF2 having provided very simple steps to reproduce.
Andrew Wilson
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

User avatar
Beau Hollis
Lockheed Martin
Posts: 2167
Joined: Wed Oct 06, 2010 3:25 pm

Re: D3D12Texture Sample - flickering texture

Postby Beau Hollis » Tue Aug 18, 2020 5:15 pm

Sorry we missed this post. Is this still happening in HF2? It may be that we resolved issues with our internal texture plugin based features (radar, AR pass-though cameras, etc) and the change to the dx12 rendering utilities didn't get merged over to the sample. We do have some 3rd parties using texture plugins without flashing issues, so hopefully it's an issue with the sample itself and not the core engine.
Beau Hollis
Prepar3D Software Architect

MachTwo
Posts: 59
Joined: Fri Oct 04, 2013 8:21 am

Re: D3D12Texture Sample - flickering texture

Postby MachTwo » Wed Aug 19, 2020 5:32 am

Hi Beau,

Thanks for your reply.

Yes, we’re still seeing this in HF2. The issue is prominent when VC Mipmaps are selected to OFF, Enhanced Atmosphere selected OFF and the D3D sample is used under load (easy to reproduce whilst stressing the CPU/GPU with HeavyLoad as described above).

If there are updates to be made to the sample, would it be possible to make those available to us so that we can test here with HF2?
Andrew Wilson
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

User avatar
Beau Hollis
Lockheed Martin
Posts: 2167
Joined: Wed Oct 06, 2010 3:25 pm

Re: D3D12Texture Sample - flickering texture

Postby Beau Hollis » Tue Sep 01, 2020 5:39 pm

If we can reproduce the issue and fix it in the sample, I'll post the code changes here on this thread.
Beau Hollis
Prepar3D Software Architect

User avatar
Beau Hollis
Lockheed Martin
Posts: 2167
Joined: Wed Oct 06, 2010 3:25 pm

Re: D3D12Texture Sample - flickering texture

Postby Beau Hollis » Tue Sep 01, 2020 7:46 pm

I looked back over the sample code, and I see the issue. I'll write a ticket to improve the sample, but I can't say for sure when we'll get around to it.

In the meantime, we have a couple of other samples that are more robust and use the PipelineState helper class we use for internal plugins like the VR and the air to ground radar. The OpenGLTexture and OpenCVStereoCamera, both contain a util folder with helpful dx12 utility classes including RenderHelper.h which contains the PipelineState class. This class handles the logic for waiting on your command allocator to be done working on the GPU before reusing it on the CPU. The two functions of interest here are Execute and Reset. Execute signals a fence after the command list is executed and reset, waits for that fence before resetting.

These should work without flicker, but may not perform as well under high load as some of our internal use add-ons. The version of RenderUtil we use internally has been updated to use a pool allocators so that you don't get CPU stalls waiting for the GPU while under heavy load. Below is the newer version of this utility used by our VR add-on. It includes a basic CommandAllocatorQueue that is essentially just a small tripple-buffered ring buffer. Double buffering would be enough in general, but if you plan to execute/reset more than once per frame, you may need to increase the size of the queue to prevent stalls.

Code: Select all

//========================================================================================================== struct TrackedAllocator { CComPtr<ID3D12CommandAllocator> m_spCommandAllocator = nullptr; UINT m_uFenceValue = 0; }; #define ALLOCATOR_COUNT 3 struct CommandAllocatorQueue { CommandAllocatorQueue() : m_uCurrent(0) {} TrackedAllocator& GetCurrent() { return m_aAllocators[m_uCurrent]; } TrackedAllocator& GetNext() { m_uCurrent = (m_uCurrent + 1) % ALLOCATOR_COUNT; return m_aAllocators[m_uCurrent]; } TrackedAllocator m_aAllocators[ALLOCATOR_COUNT]; UINT m_uCurrent = 0; }; class PipelineState { public: PipelineState() noexcept; HRESULT Initialize(ID3D12Device* pDevice, ID3D12CommandQueue* pQueue); HRESULT DeInitialize(); HRESULT Apply(bool bClearRTV = true); HRESULT Clear(); HRESULT Execute(); HRESULT Reset(); void CopySubresourceRegion(P3D::IRenderDataResourceV500* pDestination, UINT DstX, UINT DstY, UINT DstZ, P3D::IRenderDataResourceV500* pSource, const D3D12_BOX* pSourceBox); void CopyResource(P3D::IRenderDataResourceV500* pDestination, P3D::IRenderDataResourceV500* pSource); static const unsigned int MAX_RESOURCES = 4; CComPtr<P3D::IRenderDataResourceV500> m_spResources[MAX_RESOURCES]; CComPtr<P3D::IRenderDataResourceV500> m_spRenderTarget; CComPtr<P3D::IRenderDataResourceV500> m_spDepthStencil; CComPtr<P3D::IRenderDataResourceV500> m_spVertexBuffer; D3D12_VERTEX_BUFFER_VIEW m_sVertexBufferView; CComPtr<P3D::IRenderDataResourceV500> m_spConstantBuffer; CComPtr<ID3D12Device> m_spDevice; CComPtr<ID3D12GraphicsCommandList> m_spCommandList; CComPtr<ID3D12CommandQueue> m_spCommandQueue; CComPtr<ID3D12PipelineState> m_spPipelineState; CComPtr<ID3D12RootSignature> m_spRootSignature; CComPtr<ID3D12DescriptorHeap> m_spDescriptorHeapSRV; CComPtr<ID3D12DescriptorHeap> m_spDescriptorHeapRTV; CComPtr<ID3D12DescriptorHeap> m_spDescriptorHeapDSV; CComPtr<ID3D12Fence> m_spFence; D3D_PRIMITIVE_TOPOLOGY m_ePrimitiveTopology; D3D12_VIEWPORT m_ViewPort; HANDLE m_hFenceEvent; UINT m_uDepthStencilRef; UINT m_uSRVIncrement; UINT m_uRTVIncrement; UINT m_uDSVIncrement; CommandAllocatorQueue m_AllocatorQueue; UINT m_uFenceValue = 0; }; //========================================================================================================== PipelineState::PipelineState() noexcept :m_ViewPort() { m_ePrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; m_uDepthStencilRef = 0; } HRESULT PipelineState::Initialize(ID3D12Device* pDevice, ID3D12CommandQueue* pQueue) { HRESULT hr = S_OK; if (m_spDevice != pDevice || m_spCommandQueue != pQueue) { m_spDevice = pDevice; m_spCommandQueue = pQueue; for (int i = 0; i < ALLOCATOR_COUNT; i++) { hr = m_spDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_AllocatorQueue.m_aAllocators[i].m_spCommandAllocator)); if (FAILED(hr)) { return hr; } } hr = m_spDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_AllocatorQueue.m_aAllocators[0].m_spCommandAllocator, nullptr, IID_PPV_ARGS(&m_spCommandList)); if (FAILED(hr)) { return hr; } //Create Fence and Event m_uFenceValue = 0; hr = pDevice->CreateFence(m_uFenceValue, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_spFence)); if (FAILED(hr)) { return hr; } m_hFenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); } return hr; } HRESULT PipelineState::DeInitialize() { for (unsigned int i = 0; i < MAX_RESOURCES; i++) { m_spResources[i] = nullptr; } ZeroMemory(&m_sVertexBufferView, sizeof(m_sVertexBufferView)); ZeroMemory(&m_ViewPort, sizeof(m_ViewPort)); m_ePrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; m_spRenderTarget = nullptr; m_spDepthStencil = nullptr; m_spVertexBuffer = nullptr; m_spConstantBuffer = nullptr; m_spDevice = nullptr; m_spCommandList = nullptr; m_spCommandQueue = nullptr; m_spPipelineState = nullptr; m_spRootSignature = nullptr; m_spDescriptorHeapSRV = nullptr; m_spDescriptorHeapRTV = nullptr; m_spDescriptorHeapDSV = nullptr; m_spFence = nullptr; m_hFenceEvent = nullptr; m_uDepthStencilRef = 0; m_uSRVIncrement = 0; m_uRTVIncrement = 0; m_uDSVIncrement = 0; m_uFenceValue = 0; for (int i = 0; i < ALLOCATOR_COUNT; i++) { m_AllocatorQueue.m_aAllocators[i].m_spCommandAllocator = nullptr; } return S_OK; } //========================================================================================================== HRESULT PipelineState::Apply(bool bClearRTV) { static float ClearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; // red,green,blue,alpha ID3D12DescriptorHeap* ppHeaps[] = { m_spDescriptorHeapSRV }; m_spCommandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); m_spCommandList->SetGraphicsRootSignature(m_spRootSignature); if (bClearRTV && m_spRenderTarget != nullptr) { D3D12_CPU_DESCRIPTOR_HANDLE hRenderTargetHandle = m_spDescriptorHeapRTV->GetCPUDescriptorHandleForHeapStart(); m_spCommandList->ClearRenderTargetView(hRenderTargetHandle, ClearColor, 0, nullptr); } if (m_spDepthStencil != nullptr && m_spRenderTarget != nullptr) { D3D12_CPU_DESCRIPTOR_HANDLE hDepthStencilHandle = m_spDescriptorHeapDSV->GetCPUDescriptorHandleForHeapStart(); D3D12_CPU_DESCRIPTOR_HANDLE hRenderTargetHandle = m_spDescriptorHeapRTV->GetCPUDescriptorHandleForHeapStart(); m_spCommandList->OMSetStencilRef(m_uDepthStencilRef); m_spCommandList->OMSetRenderTargets(1, &hRenderTargetHandle, FALSE, &hDepthStencilHandle); } else if(m_spRenderTarget) { D3D12_CPU_DESCRIPTOR_HANDLE hRenderTargetHandle = m_spDescriptorHeapRTV->GetCPUDescriptorHandleForHeapStart(); m_spCommandList->OMSetRenderTargets(1, &hRenderTargetHandle, FALSE, nullptr); } else { D3D12_CPU_DESCRIPTOR_HANDLE hDepthStencilHandle = m_spDescriptorHeapDSV->GetCPUDescriptorHandleForHeapStart(); m_spCommandList->OMSetStencilRef(m_uDepthStencilRef); m_spCommandList->OMSetRenderTargets(0, nullptr, FALSE, &hDepthStencilHandle); } m_spCommandList->SetPipelineState(m_spPipelineState); D3D12_RECT sScissorRectFull; sScissorRectFull.left = 0; sScissorRectFull.top = 0; sScissorRectFull.right = static_cast<LONG>(m_ViewPort.Width); sScissorRectFull.bottom = static_cast<LONG>(m_ViewPort.Height); //Setup the viewport. m_spCommandList->RSSetViewports(1, &m_ViewPort); m_spCommandList->RSSetScissorRects(1, &sScissorRectFull); if (m_spConstantBuffer) { m_spCommandList->SetGraphicsRootConstantBufferView(0, m_spConstantBuffer->GetD3D12Resource()->GetGPUVirtualAddress()); } m_spCommandList->IASetPrimitiveTopology(m_ePrimitiveTopology); m_spCommandList->IASetVertexBuffers(0, 1, &m_sVertexBufferView); for (int i = 0; i < MAX_RESOURCES; i++) { if (m_spResources[i] != nullptr) { D3D12_GPU_DESCRIPTOR_HANDLE hGpuHandle = m_spDescriptorHeapSRV->GetGPUDescriptorHandleForHeapStart(); hGpuHandle.ptr += m_uSRVIncrement * i; m_spCommandList->SetGraphicsRootDescriptorTable(i + 1, hGpuHandle); } } return S_OK; } //========================================================================================================== HRESULT PipelineState::Clear() { m_spCommandList->ClearState(m_spPipelineState); m_spCommandList->OMSetRenderTargets(0, nullptr, false, nullptr); return S_OK; } //========================================================================================================== HRESULT PipelineState::Execute() { HRESULT hr = S_OK; hr = m_spCommandList->Close(); if (FAILED(hr)) { return hr; } ID3D12CommandList* ppCommandLists[] = { m_spCommandList }; m_spCommandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); hr = m_spCommandQueue->Signal(m_spFence, m_uFenceValue); if (FAILED(hr)) { return hr; } return hr; } //========================================================================================================== HRESULT PipelineState::Reset() { HRESULT hr = S_OK; TrackedAllocator& alloc = m_AllocatorQueue.GetNext(); if (m_spFence->GetCompletedValue() < (alloc.m_uFenceValue)) { hr = m_spFence->SetEventOnCompletion(alloc.m_uFenceValue, m_hFenceEvent); if (FAILED(hr)) { return hr; } WaitForSingleObjectEx(m_hFenceEvent, INFINITE, FALSE); } m_uFenceValue++; alloc.m_uFenceValue = m_uFenceValue; hr = alloc.m_spCommandAllocator->Reset(); if (FAILED(hr)) { return hr; } hr = m_spCommandList->Reset(alloc.m_spCommandAllocator, nullptr); return hr; } void PipelineState::CopySubresourceRegion(P3D::IRenderDataResourceV500* pDestination, UINT DstX, UINT DstY, UINT DstZ, P3D::IRenderDataResourceV500* pSource, const D3D12_BOX* pSourceBox) { if (pDestination == nullptr || pSource == nullptr || m_spCommandList == nullptr) return; D3D12_RESOURCE_STATES destState = pDestination->GetResourceState(); D3D12_RESOURCE_STATES srcState = pSource->GetResourceState(); D3D12_RESOURCE_BARRIER sBarriersBefore[2]; sBarriersBefore[0] = CD3DX12_RESOURCE_BARRIER::Transition(pDestination->GetD3D12Resource(), destState, D3D12_RESOURCE_STATE_COPY_DEST); sBarriersBefore[1] = CD3DX12_RESOURCE_BARRIER::Transition(pSource->GetD3D12Resource(), srcState, D3D12_RESOURCE_STATE_COPY_SOURCE); pDestination->SetResourceState(D3D12_RESOURCE_STATE_COPY_DEST); pSource->SetResourceState(D3D12_RESOURCE_STATE_COPY_SOURCE); m_spCommandList->ResourceBarrier(2, sBarriersBefore); if (pDestination->GetD3D12Resource()->GetDesc().Format == D3D12_RESOURCE_DIMENSION_BUFFER) { D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint; m_spDevice->GetCopyableFootprints(&pDestination->GetD3D12Resource()->GetDesc(), 0, 1, 0, &PlacedFootprint, nullptr, nullptr, nullptr); m_spCommandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(pDestination->GetD3D12Resource(), PlacedFootprint), DstX, DstY, DstZ, &CD3DX12_TEXTURE_COPY_LOCATION(pSource->GetD3D12Resource()), pSourceBox); } else { m_spCommandList->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(pDestination->GetD3D12Resource()), DstX, DstY, DstZ, &CD3DX12_TEXTURE_COPY_LOCATION(pSource->GetD3D12Resource()), pSourceBox); } D3D12_RESOURCE_BARRIER sBarriersAfter[2]; sBarriersAfter[0] = CD3DX12_RESOURCE_BARRIER::Transition(pDestination->GetD3D12Resource(), D3D12_RESOURCE_STATE_COPY_DEST, destState); sBarriersAfter[1] = CD3DX12_RESOURCE_BARRIER::Transition(pSource->GetD3D12Resource(), D3D12_RESOURCE_STATE_COPY_SOURCE, srcState); pDestination->SetResourceState(destState); pSource->SetResourceState(srcState); m_spCommandList->ResourceBarrier(2, sBarriersAfter); } void PipelineState::CopyResource(P3D::IRenderDataResourceV500* pDestination, P3D::IRenderDataResourceV500* pSource) { if (pDestination == nullptr || pSource == nullptr || m_spCommandList == nullptr) return; D3D12_RESOURCE_STATES destState = pDestination->GetResourceState(); D3D12_RESOURCE_STATES srcState = pSource->GetResourceState(); D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint; m_spDevice->GetCopyableFootprints(&pDestination->GetD3D12Resource()->GetDesc(), 0, 1, 0, &PlacedFootprint, nullptr, nullptr, nullptr); D3D12_RESOURCE_BARRIER sBarriersBefore[2]; sBarriersBefore[0] = CD3DX12_RESOURCE_BARRIER::Transition(pDestination->GetD3D12Resource(), destState, D3D12_RESOURCE_STATE_COPY_DEST); sBarriersBefore[1] = CD3DX12_RESOURCE_BARRIER::Transition(pSource->GetD3D12Resource(), srcState, D3D12_RESOURCE_STATE_COPY_SOURCE); pDestination->SetResourceState(D3D12_RESOURCE_STATE_COPY_DEST); pSource->SetResourceState(D3D12_RESOURCE_STATE_COPY_SOURCE); m_spCommandList->ResourceBarrier(2, sBarriersBefore); m_spCommandList->CopyResource(pDestination->GetD3D12Resource(), pSource->GetD3D12Resource()); D3D12_RESOURCE_BARRIER sBarriersAfter[2]; sBarriersAfter[0] = CD3DX12_RESOURCE_BARRIER::Transition(pDestination->GetD3D12Resource(), D3D12_RESOURCE_STATE_COPY_DEST, destState); sBarriersAfter[1] = CD3DX12_RESOURCE_BARRIER::Transition(pSource->GetD3D12Resource(), D3D12_RESOURCE_STATE_COPY_SOURCE, srcState); pDestination->SetResourceState(destState); pSource->SetResourceState(srcState); m_spCommandList->ResourceBarrier(2, sBarriersAfter); }
Beau Hollis
Prepar3D Software Architect

User avatar
lkalam
Posts: 232
Joined: Wed Dec 07, 2011 10:23 am

Re: D3D12Texture Sample - flickering texture

Postby lkalam » Mon Sep 28, 2020 10:45 am

Hi Beau,

we have included your updated code into the OpenGLTexture sample and unfortunately, the result is that the code freezes.Here is the OpenGLTexture sample, updated with the RenderHelper code that includes your new PipelineState, so you can test on your end, but we've tried it on different machines and the result is the same.

https://we.tl/t-UsG0Dk6VFo

Would appreciate updated code, possibly on the D3D12Texture sample as that's simpler.

Regards
Lefteris Kalamaras
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

User avatar
Beau Hollis
Lockheed Martin
Posts: 2167
Joined: Wed Oct 06, 2010 3:25 pm

Re: D3D12Texture Sample - flickering texture

Postby Beau Hollis » Tue Sep 29, 2020 12:18 pm

Thanks. We're in the process or updating our d3d12 util classes and making a shared utility project that all 3 dx projects can share. We'll be testing that out soon. The plan is to update the d3d12Texture project as well.
Beau Hollis
Prepar3D Software Architect

User avatar
lkalam
Posts: 232
Joined: Wed Dec 07, 2011 10:23 am

Re: D3D12Texture Sample - flickering texture

Postby lkalam » Wed Sep 30, 2020 7:05 am

Hi Beau,

thanks for the reply - any hints as to how we can get your sample code to work rather than to freeze? It's imperative to get our RTT implementation going.
Lefteris Kalamaras
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

User avatar
lkalam
Posts: 232
Joined: Wed Dec 07, 2011 10:23 am

Re: D3D12Texture Sample - flickering texture

Postby lkalam » Sat Oct 17, 2020 7:45 am

Hello,

just wanted to bring this back to your attention as we've not heard from you still and we are very concerned that the flickering issue is not resolved.

Can you please share your revised sample code if you have it, so we can test and let you know if it's fixed?

Our upcoming products require that we use D3D12 Textures and we need to ensure that they will work without this happening.

Thank you,
Lefteris Kalamaras
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com

User avatar
Beau Hollis
Lockheed Martin
Posts: 2167
Joined: Wed Oct 06, 2010 3:25 pm

Re: D3D12Texture Sample - flickering texture

Postby Beau Hollis » Mon Oct 19, 2020 12:59 pm

We've updated the dx12 and opengl samples and are testing them in beta. The freeze in the OpenGL sample, is because it made assumptions about how the pipeline wrappers fence was being used. In the updated sample I've added an additional fence specifically for tracking the shared resource.
Beau Hollis
Prepar3D Software Architect

User avatar
Beau Hollis
Lockheed Martin
Posts: 2167
Joined: Wed Oct 06, 2010 3:25 pm

Re: D3D12Texture Sample - flickering texture

Postby Beau Hollis » Wed Oct 28, 2020 7:45 pm

Updated samples are included with 5.1. Also with 5.1 we found and fixed a core issue that caused black flickering with texture elements like this, especially if mipmap vc panels was disabled.

Thanks
Beau Hollis
Prepar3D Software Architect

User avatar
lkalam
Posts: 232
Joined: Wed Dec 07, 2011 10:23 am

Re: D3D12Texture Sample - flickering texture

Postby lkalam » Wed Oct 28, 2020 8:55 pm

Thank you Beau,

we appreciate it. The Mipmap VC panels "off" was mentioned back in August, I guess that was the issue after all.
Lefteris Kalamaras
Flight Sim Labs, Ltd.
---------------------------
www.flightsimlabs.com


Return to “Software Development Kit (SDK) Questions”

Who is online

Users browsing this forum: No registered users and 11 guests