mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-10-25 10:20:52 +00:00
Fix various D3D12 video decode state issues (#4038)
* Fix D3D12 video decode reference resource states Transition both NV12 planes of active DPB references to VIDEO_DECODE_READ before DecodeFrame and restore their states afterward. Exclude unused reference slots while preserving DXVA picture indices and use the actual DPB slot count. * Fix D3D12 scratch descriptor heap lifetime during growth Defer replaced heap destruction until the command-list fence completes. Allow the deferred-release queue to retain IUnknown objects so descriptor heaps can use the same retirement mechanism as resources. Fixes OBJECT_DELETED_WHILE_STILL_IN_USE (#921) when draw-load growth replaces a heap referenced by pending native video conversion commands.
This commit is contained in:
@@ -4739,7 +4739,12 @@ namespace bgfx { namespace d3d12
|
||||
, (void**)&heap
|
||||
) );
|
||||
|
||||
DX_RELEASE(m_heap, 0);
|
||||
if (NULL != m_heap)
|
||||
{
|
||||
BX_TRACE("D3D12 scratch heap grow: retired=%p size=%u replacement=%p size=%u queue=%u"
|
||||
, m_heap, m_size, heap, _num, s_renderD3D12->m_cmd.m_control.m_current);
|
||||
s_renderD3D12->m_cmd.release(m_heap);
|
||||
}
|
||||
m_heap = heap;
|
||||
m_size = _num;
|
||||
m_cpuHandleStart = getCPUHandleHeapStart(m_heap);
|
||||
@@ -5564,7 +5569,7 @@ namespace bgfx { namespace d3d12
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandQueueD3D12::release(ID3D12Resource* _ptr)
|
||||
void CommandQueueD3D12::release(IUnknown* _ptr)
|
||||
{
|
||||
m_release[m_control.m_current].push_back(_ptr);
|
||||
}
|
||||
|
||||
@@ -593,7 +593,7 @@ namespace bgfx { namespace d3d12
|
||||
uint64_t kick();
|
||||
void finish(uint64_t _waitFence = UINT64_MAX, bool _finishAll = false);
|
||||
bool tryFinish(uint64_t _waitFence);
|
||||
void release(ID3D12Resource* _ptr);
|
||||
void release(IUnknown* _ptr);
|
||||
bool consume(uint32_t _ms = UINT32_MAX);
|
||||
|
||||
void addExternal(TextureHandle _handle);
|
||||
@@ -649,7 +649,7 @@ namespace bgfx { namespace d3d12
|
||||
uint64_t m_completedFence;
|
||||
ID3D12Fence* m_fence;
|
||||
CommandList m_commandList[kMaxCommandLists];
|
||||
typedef stl::vector<ID3D12Resource*> ResourceArray;
|
||||
typedef stl::vector<IUnknown*> ResourceArray;
|
||||
ResourceArray m_release[kMaxCommandLists];
|
||||
typedef stl::vector<TextureHandle> ExternalTextureArray;
|
||||
ExternalTextureArray m_external;
|
||||
|
||||
@@ -956,10 +956,30 @@ namespace bgfx { namespace d3d12
|
||||
|
||||
ID3D12Resource* refFrames[kNumDpbSlots] = {};
|
||||
UINT refSubresources[kNumDpbSlots] = {};
|
||||
for (uint32_t ii = 0; ii < m_numDpbSlots; ++ii)
|
||||
refFrames[m_currentSlot] = m_dpb;
|
||||
refSubresources[m_currentSlot] = UINT(m_currentSlot);
|
||||
D3D12_RESOURCE_BARRIER referenceBarriers[2 * kNumDpbSlots];
|
||||
uint32_t numReferenceBarriers = 0;
|
||||
for (uint32_t ii = 0; ii < m_numActiveRefs; ++ii)
|
||||
{
|
||||
refFrames[ii] = m_dpb;
|
||||
refSubresources[ii] = UINT(ii);
|
||||
const uint32_t refSlot = m_referenceUsage[ii];
|
||||
refFrames[refSlot] = m_dpb;
|
||||
refSubresources[refSlot] = UINT(refSlot);
|
||||
for (uint32_t plane = 0; plane < 2; ++plane)
|
||||
{
|
||||
referenceBarriers[numReferenceBarriers++] =
|
||||
{
|
||||
.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
|
||||
.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
|
||||
.Transition =
|
||||
{
|
||||
.pResource = m_dpb,
|
||||
.Subresource = plane * m_numDpbSlots + refSlot,
|
||||
.StateBefore = m_dpbState[refSlot].state,
|
||||
.StateAfter = D3D12_RESOURCE_STATE_VIDEO_DECODE_READ,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
D3D12_VIDEO_DECODE_INPUT_STREAM_ARGUMENTS input
|
||||
@@ -973,7 +993,7 @@ namespace bgfx { namespace d3d12
|
||||
},
|
||||
.ReferenceFrames =
|
||||
{
|
||||
.NumTexture2Ds = kNumDpbSlots,
|
||||
.NumTexture2Ds = m_numDpbSlots,
|
||||
.ppTexture2Ds = refFrames,
|
||||
.pSubresources = refSubresources,
|
||||
.ppHeaps = NULL,
|
||||
@@ -1009,7 +1029,21 @@ namespace bgfx { namespace d3d12
|
||||
}
|
||||
;
|
||||
|
||||
if (numReferenceBarriers > 0)
|
||||
{
|
||||
m_videoCmd->ResourceBarrier(numReferenceBarriers, referenceBarriers);
|
||||
}
|
||||
m_videoCmd->DecodeFrame(m_decoder, &output, &input);
|
||||
if (numReferenceBarriers > 0)
|
||||
{
|
||||
for (uint32_t ii = 0; ii < numReferenceBarriers; ++ii)
|
||||
{
|
||||
const D3D12_RESOURCE_STATES previousState = referenceBarriers[ii].Transition.StateBefore;
|
||||
referenceBarriers[ii].Transition.StateBefore = referenceBarriers[ii].Transition.StateAfter;
|
||||
referenceBarriers[ii].Transition.StateAfter = previousState;
|
||||
}
|
||||
m_videoCmd->ResourceBarrier(numReferenceBarriers, referenceBarriers);
|
||||
}
|
||||
|
||||
if (m_referenceOnly)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user