d3d12: Use EnqueueMakeResident with GPU Wait for video permanent residency promotions
Reviewed-by: Pohsiang (John) Hsu <pohhsu@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38057>
This commit is contained in:
committed by
Marge Bot
parent
ca3ba3f924
commit
7e1982a7eb
@@ -281,8 +281,26 @@ d3d12_deinit_residency(struct d3d12_screen *screen)
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_resource** resources, unsigned count)
|
||||
d3d12_promote_to_permanent_residency(
|
||||
struct d3d12_screen *screen,
|
||||
struct d3d12_resource** resources,
|
||||
unsigned count,
|
||||
ID3D12Fence* pResidencyFence, /* NULL implies usage of synchronous MakeResident */
|
||||
uint64_t *pResidencyFenceValue /* Out: value to wait on for residency for this call */
|
||||
)
|
||||
{
|
||||
#if MESA_DEBUG
|
||||
if (pResidencyFence && !pResidencyFenceValue)
|
||||
{
|
||||
debug_printf("D3D12: d3d12_promote_to_permanent_residency called with a fence but no fence value out parameter!\n");
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (pResidencyFence && pResidencyFenceValue) {
|
||||
debug_printf("D3D12: promote_to_permanent_residency called with %u resources, current fence value: %" PRIu64 "\n", count, *pResidencyFenceValue);
|
||||
}
|
||||
#endif // MESA_DEBUG
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
@@ -291,11 +309,29 @@ d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_r
|
||||
ID3D12Pageable *pageables_to_make_resident[residency_batch_size];
|
||||
unsigned num_to_make_resident = 0;
|
||||
|
||||
auto flush_batch = [](struct d3d12_screen *screen, ID3D12Pageable **pageables, unsigned count) {
|
||||
auto flush_batch = [](struct d3d12_screen *screen, ID3D12Pageable **pageables, unsigned count, ID3D12Fence* pResidencyFence, uint64_t *pResidencyFenceValue) {
|
||||
if (count > 0) {
|
||||
ASSERTED HRESULT hr = screen->dev->MakeResident(count, pageables);
|
||||
ASSERTED HRESULT hr = S_OK;
|
||||
|
||||
if (!pResidencyFence)
|
||||
{
|
||||
hr = screen->dev->MakeResident(count, pageables);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
debug_printf("D3D12: Promoted %u resources to permanent residency (synchronous)\n", count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = screen->dev->EnqueueMakeResident(D3D12_RESIDENCY_FLAG_NONE, count, pageables,
|
||||
pResidencyFence, (*pResidencyFenceValue) + 1);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
(*pResidencyFenceValue)++;
|
||||
debug_printf("D3D12: Promoted %u resources to permanent residency (asynchronous) with fence object %p and fence value %" PRIu64 " and hr %x\n", count, pResidencyFence, *pResidencyFenceValue, (unsigned)hr);
|
||||
}
|
||||
}
|
||||
assert(SUCCEEDED(hr));
|
||||
debug_printf("D3D12: Promoted %u resources to permanent residency\n", count);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -311,19 +347,24 @@ d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_r
|
||||
assert(num_to_make_resident < residency_batch_size);
|
||||
pageables_to_make_resident[num_to_make_resident++] = base_bo->res;
|
||||
if (num_to_make_resident == residency_batch_size) {
|
||||
flush_batch(screen, pageables_to_make_resident, num_to_make_resident);
|
||||
flush_batch(screen, pageables_to_make_resident, num_to_make_resident, pResidencyFence, pResidencyFenceValue);
|
||||
num_to_make_resident = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flush_batch(screen, pageables_to_make_resident, num_to_make_resident);
|
||||
flush_batch(screen, pageables_to_make_resident, num_to_make_resident, pResidencyFence, pResidencyFenceValue);
|
||||
mtx_unlock(&screen->submit_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_resource* resource)
|
||||
d3d12_promote_to_permanent_residency(
|
||||
struct d3d12_screen *screen,
|
||||
struct d3d12_resource* resource,
|
||||
ID3D12Fence* pResidencyFence, /* NULL implies usage of synchronous MakeResident */
|
||||
uint64_t *pResidencyFenceValue /* Out: value to wait on for residency for this call */
|
||||
)
|
||||
{
|
||||
// Early out for null resource or if the bo is already permanently resident
|
||||
if (!resource)
|
||||
@@ -336,5 +377,5 @@ d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_r
|
||||
return;
|
||||
}
|
||||
|
||||
d3d12_promote_to_permanent_residency(screen, &resource, 1);
|
||||
d3d12_promote_to_permanent_residency(screen, &resource, 1, pResidencyFence, pResidencyFenceValue);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,18 @@ void
|
||||
d3d12_deinit_residency(struct d3d12_screen *screen);
|
||||
|
||||
void
|
||||
d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_resource** resources, unsigned count);
|
||||
d3d12_promote_to_permanent_residency(
|
||||
struct d3d12_screen *screen,
|
||||
struct d3d12_resource** resources,
|
||||
unsigned count,
|
||||
ID3D12Fence* pResidencyFence = NULL,
|
||||
uint64_t *pResidencyFenceValue = NULL
|
||||
);
|
||||
|
||||
void
|
||||
d3d12_promote_to_permanent_residency(struct d3d12_screen *screen, struct d3d12_resource* resource);
|
||||
d3d12_promote_to_permanent_residency(
|
||||
struct d3d12_screen *screen,
|
||||
struct d3d12_resource* resource,
|
||||
ID3D12Fence* pResidencyFence = NULL,
|
||||
uint64_t *pResidencyFenceValue = NULL
|
||||
);
|
||||
|
||||
@@ -123,6 +123,9 @@ d3d12_video_encoder_flush(struct pipe_video_codec *codec)
|
||||
pD3D12Enc->m_spEncodeCommandQueue->Wait(casted_completion_fence->cmdqueue_fence, casted_completion_fence->value);
|
||||
pD3D12Enc->m_pD3D12Screen->base.fence_reference(&pD3D12Enc->m_pD3D12Screen->base, &completion_fence, NULL);
|
||||
|
||||
// Wait on residency fence for this frame to ensure all resources used in encoding are resident
|
||||
pD3D12Enc->m_spEncodeCommandQueue->Wait(pD3D12Enc->m_spResidencyFence.Get(), pD3D12Enc->m_ResidencyFenceValue);
|
||||
|
||||
struct d3d12_fence *input_surface_fence = pD3D12Enc->m_inflightResourcesPool[current_pool_idx].m_InputSurfaceFence;
|
||||
if (input_surface_fence)
|
||||
d3d12_fence_wait_impl(input_surface_fence, pD3D12Enc->m_spEncodeCommandQueue.Get(),
|
||||
@@ -2378,6 +2381,14 @@ d3d12_video_encoder_create_command_objects(struct d3d12_video_encoder *pD3D12Enc
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = pD3D12Enc->m_pD3D12Screen->dev->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&pD3D12Enc->m_spResidencyFence));
|
||||
if (FAILED(hr)) {
|
||||
debug_printf(
|
||||
"[d3d12_video_encoder] d3d12_video_encoder_create_command_objects - Call to CreateFence failed with HR %x\n",
|
||||
(unsigned)hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
hr = pD3D12Enc->m_pD3D12Screen->dev->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&pD3D12Enc->m_spLastSliceFence));
|
||||
if (FAILED(hr)) {
|
||||
debug_printf(
|
||||
@@ -3293,12 +3304,10 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
||||
}
|
||||
|
||||
// Make permanently resident for video use - batch promote all slice buffers
|
||||
if (num_slice_objects > 0) {
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_pOutputBitstreamBuffers.data(), num_slice_objects);
|
||||
}
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_pOutputBitstreamBuffers.data(), num_slice_objects, pD3D12Enc->m_spResidencyFence.Get(), &pD3D12Enc->m_ResidencyFenceValue);
|
||||
|
||||
// Make permanently resident for video use
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pInputVideoBuffer->texture);
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, &pInputVideoBuffer->texture, 1, pD3D12Enc->m_spResidencyFence.Get(), &pD3D12Enc->m_ResidencyFenceValue);
|
||||
|
||||
size_t current_metadata_slot = d3d12_video_encoder_metadata_current_index(pD3D12Enc);
|
||||
|
||||
@@ -3801,7 +3810,8 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
||||
D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAGS optionalMetadataFlags = D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_NONE;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource) {
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_QP_MAP;
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource);
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, &pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource,
|
||||
1, pD3D12Enc->m_spResidencyFence.Get(), &pD3D12Enc->m_ResidencyFenceValue);
|
||||
d3d12_transition_resource_state(d3d12_context(pD3D12Enc->base.context),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPUQPStatsResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
@@ -3813,7 +3823,8 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
||||
ID3D12Resource* d12_gpu_stats_satd_map = NULL;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource) {
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_SATD_MAP;
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource);
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, &pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource,
|
||||
1, pD3D12Enc->m_spResidencyFence.Get(), &pD3D12Enc->m_ResidencyFenceValue);
|
||||
d3d12_transition_resource_state(d3d12_context(pD3D12Enc->base.context),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPUSATDStatsResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
@@ -3825,7 +3836,8 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
||||
ID3D12Resource* d12_gpu_stats_rc_bitallocation_map = NULL;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource) {
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_RC_BIT_ALLOCATION_MAP;
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource);
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, &pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource,
|
||||
1, pD3D12Enc->m_spResidencyFence.Get(), &pD3D12Enc->m_ResidencyFenceValue);
|
||||
d3d12_transition_resource_state(d3d12_context(pD3D12Enc->base.context),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPURCBitAllocationStatsResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
@@ -3837,7 +3849,8 @@ d3d12_video_encoder_encode_bitstream_impl(struct pipe_video_codec *codec,
|
||||
ID3D12Resource* d12_gpu_stats_psnr = NULL;
|
||||
if (pD3D12Enc->m_currentEncodeConfig.m_GPUPSNRAllocationStatsResource) {
|
||||
optionalMetadataFlags |= D3D12_VIDEO_ENCODER_OPTIONAL_METADATA_ENABLE_FLAG_FRAME_PSNR;
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, pD3D12Enc->m_currentEncodeConfig.m_GPUPSNRAllocationStatsResource);
|
||||
d3d12_promote_to_permanent_residency(pD3D12Enc->m_pD3D12Screen, &pD3D12Enc->m_currentEncodeConfig.m_GPUPSNRAllocationStatsResource,
|
||||
1, pD3D12Enc->m_spResidencyFence.Get(), &pD3D12Enc->m_ResidencyFenceValue);
|
||||
d3d12_transition_resource_state(d3d12_context(pD3D12Enc->base.context),
|
||||
pD3D12Enc->m_currentEncodeConfig.m_GPUPSNRAllocationStatsResource,
|
||||
D3D12_RESOURCE_STATE_COMMON,
|
||||
|
||||
@@ -581,9 +581,11 @@ struct d3d12_video_encoder
|
||||
size_t m_MaxMetadataBuffersCount = 0;
|
||||
|
||||
ComPtr<ID3D12Fence> m_spFence;
|
||||
ComPtr<ID3D12Fence> m_spResidencyFence;
|
||||
ComPtr<ID3D12Fence> m_spLastSliceFence;
|
||||
uint64_t m_fenceValue = 1u;
|
||||
uint64_t m_LastSliceFenceValue = 1u;
|
||||
uint64_t m_ResidencyFenceValue = 0u;
|
||||
bool m_bPendingWorkNotFlushed = false;
|
||||
|
||||
ComPtr<ID3D12VideoDevice3> m_spD3D12VideoDevice;
|
||||
|
||||
Reference in New Issue
Block a user