d3d12: Implement pipe_video_codec.create_dpb_buffer for AOT resources

Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30908>
This commit is contained in:
Sil Vilerino
2024-08-28 09:54:29 -04:00
committed by Marge Bot
parent f8145fe691
commit 4070d02524
4 changed files with 64 additions and 2 deletions

View File

@@ -262,6 +262,14 @@ init_texture(struct d3d12_screen *screen,
*/
}
if (templ->bind & PIPE_BIND_VIDEO_DECODE_DPB)
desc.Flags |= (D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY |
D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE);
if (templ->bind & PIPE_BIND_VIDEO_ENCODE_DPB)
desc.Flags |= (D3D12_RESOURCE_FLAG_VIDEO_ENCODE_REFERENCE_ONLY |
D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE);
const DXGI_FORMAT *format_cast_list = NULL;
uint32_t num_castable_formats = 0;
@@ -681,6 +689,10 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
res->base.b.bind |= PIPE_BIND_SHADER_IMAGE;
if ((incoming_res_desc.Flags & D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE) == D3D12_RESOURCE_FLAG_NONE)
res->base.b.bind |= PIPE_BIND_SAMPLER_VIEW;
if (incoming_res_desc.Flags & D3D12_RESOURCE_FLAG_VIDEO_DECODE_REFERENCE_ONLY)
res->base.b.bind |= PIPE_BIND_VIDEO_DECODE_DPB;
if (incoming_res_desc.Flags & D3D12_RESOURCE_FLAG_VIDEO_ENCODE_REFERENCE_ONLY)
res->base.b.bind |= PIPE_BIND_VIDEO_ENCODE_DPB;
if (templ) {
if (res->base.b.target == PIPE_TEXTURE_2D_ARRAY &&

View File

@@ -22,6 +22,7 @@
*/
#include "d3d12_video_buffer.h"
#include "d3d12_video_enc.h"
#include "d3d12_resource.h"
#include "d3d12_video_dec.h"
#include "d3d12_residency.h"
@@ -63,10 +64,13 @@ d3d12_video_buffer_create_impl(struct pipe_context *pipe,
pD3D12VideoBuffer->base.contiguous_planes = true;
pD3D12VideoBuffer->base.associated_data = nullptr;
pD3D12VideoBuffer->base.bind = PIPE_BIND_CUSTOM;
// Used to signal the rest of the d3d12 driver this is a video (dpb or not) texture
pD3D12VideoBuffer->base.bind |= PIPE_BIND_CUSTOM;
#ifdef HAVE_GALLIUM_D3D12_GRAPHICS
struct d3d12_screen *dscreen = (struct d3d12_screen*) pipe->screen;
if (dscreen->max_feature_level >= D3D_FEATURE_LEVEL_11_0)
if ((dscreen->max_feature_level >= D3D_FEATURE_LEVEL_11_0) &&
((pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_DECODE_DPB) == 0) &&
((pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_ENCODE_DPB) == 0))
pD3D12VideoBuffer->base.bind |= (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW);
#endif // HAVE_GALLIUM_D3D12_GRAPHICS
@@ -239,6 +243,11 @@ d3d12_video_buffer_get_surfaces(struct pipe_video_buffer *buffer)
struct pipe_context * pipe = pD3D12VideoBuffer->base.context;
struct pipe_surface surface_template = {};
// DPB buffers don't support views
if ((pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_DECODE_DPB) ||
(pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_ENCODE_DPB))
return nullptr;
if (!pipe->create_surface)
return nullptr;
@@ -316,6 +325,11 @@ d3d12_video_buffer_get_sampler_view_planes(struct pipe_video_buffer *buffer)
struct pipe_context * pipe = pD3D12VideoBuffer->base.context;
struct pipe_sampler_view samplerViewTemplate;
// DPB buffers don't support views
if ((pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_DECODE_DPB) ||
(pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_ENCODE_DPB))
return nullptr;
// Some video frameworks iterate over [0..VL_MAX_SURFACES) and ignore the nullptr entries
// So we have to null initialize the other surfaces not used from [num_planes..VL_MAX_SURFACES)
// Like in src/gallium/frontends/vdpau/surface.c
@@ -367,6 +381,11 @@ d3d12_video_buffer_get_sampler_view_components(struct pipe_video_buffer *buffer)
struct pipe_context * pipe = pD3D12VideoBuffer->base.context;
struct pipe_sampler_view samplerViewTemplate;
// DPB buffers don't support views
if ((pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_DECODE_DPB) ||
(pD3D12VideoBuffer->base.bind & PIPE_BIND_VIDEO_ENCODE_DPB))
return nullptr;
// pCurPlaneResource refers to the planar resource, not the overall resource.
// in d3d12_resource this is handled by having a linked list of planes with
// d3dRes->base.next ptr to next plane resource
@@ -416,3 +435,24 @@ error:
return nullptr;
}
struct pipe_video_buffer*
d3d12_video_create_dpb_buffer(struct pipe_video_codec *codec,
struct pipe_picture_desc *picture,
const struct pipe_video_buffer *templat)
{
struct d3d12_video_encoder *pD3D12Enc = (struct d3d12_video_encoder *) codec;
assert(pD3D12Enc);
bool bSupportsAOT = ((pD3D12Enc->m_currentEncodeCapabilities.m_SupportFlags &
D3D12_VIDEO_ENCODER_SUPPORT_FLAG_RECONSTRUCTED_FRAMES_REQUIRE_TEXTURE_ARRAYS) == 0);
assert(bSupportsAOT); // Do not support texture array (for now)
// Indicate to the d3d12 resource creation path this needs decode/encode reference only resource flags
pipe_video_buffer tmpl = *templat;
if (codec->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
tmpl.bind |= PIPE_BIND_VIDEO_DECODE_DPB;
else if (codec->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE)
tmpl.bind |= PIPE_BIND_VIDEO_ENCODE_DPB;
return d3d12_video_buffer_create_impl(codec->context, &tmpl, NULL, 0);
}

View File

@@ -102,4 +102,13 @@ struct d3d12_video_buffer
/// Pipe video buffer interface ends
///
/**
* creates a video dpb buffer
*/
struct pipe_video_buffer*
d3d12_video_create_dpb_buffer(struct pipe_video_codec *codec,
struct pipe_picture_desc *picture,
const struct pipe_video_buffer *templat);
#endif

View File

@@ -1597,6 +1597,7 @@ d3d12_video_encoder_create_encoder(struct pipe_context *context, const struct pi
pD3D12Enc->base.flush = d3d12_video_encoder_flush;
pD3D12Enc->base.get_encode_headers = d3d12_video_encoder_get_encode_headers;
pD3D12Enc->base.get_feedback = d3d12_video_encoder_get_feedback;
pD3D12Enc->base.create_dpb_buffer = d3d12_video_create_dpb_buffer;
struct d3d12_context *pD3D12Ctx = (struct d3d12_context *) context;
pD3D12Enc->m_pD3D12Screen = d3d12_screen(pD3D12Ctx->base.screen);