From: Elizabeth Figura zfigura@codeweavers.com
This patch contains all the boilerplate for splitting purposes; the actual implementation is deferred to a following patch. --- dlls/d3d11/device.c | 30 +++++++++++++++++++-- dlls/wined3d/cs.c | 48 ++++++++++++++++++++++++++++++++++ dlls/wined3d/decoder.c | 23 ++++++++++++++++ dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 5 ++++ include/wine/wined3d.h | 2 ++ 6 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index 64baad68859..cf62e5151ef 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -3232,8 +3232,34 @@ static HRESULT STDMETHODCALLTYPE d3d11_video_context_DecoderEndFrame( static HRESULT STDMETHODCALLTYPE d3d11_video_context_SubmitDecoderBuffers(ID3D11VideoContext *iface, ID3D11VideoDecoder *decoder, UINT count, const D3D11_VIDEO_DECODER_BUFFER_DESC *buffers) { - FIXME("iface %p, decoder %p, count %u, buffers %p, stub!\n", iface, decoder, count, buffers); - return E_NOTIMPL; + struct d3d_video_decoder *decoder_impl = unsafe_impl_from_ID3D11VideoDecoder(decoder); + unsigned int bitstream_size = 0, slice_control_size = 0; + + TRACE("iface %p, decoder %p, count %u, buffers %p.\n", iface, decoder, count, buffers); + + for (unsigned int i = 0; i < count; ++i) + { + const D3D11_VIDEO_DECODER_BUFFER_DESC *buffer = &buffers[i]; + + TRACE(" [%u] type %#x, size %u, first MB %u, MB count %u.\n", + i, buffer->BufferType, buffer->DataSize, buffer->FirstMBaddress, buffer->NumMBsInBuffer); + + switch (buffer->BufferType) + { + case D3D11_VIDEO_DECODER_BUFFER_BITSTREAM: + bitstream_size = buffer->DataSize; + break; + + case D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL: + slice_control_size = buffer->DataSize; + break; + + default: + break; + } + } + + return wined3d_decoder_decode(decoder_impl->wined3d_decoder, bitstream_size, slice_control_size); }
static HRESULT STDMETHODCALLTYPE d3d11_video_context_DecoderExtension(ID3D11VideoContext *iface, diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 9bac7afdba2..1c5685220b1 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -140,6 +140,7 @@ enum wined3d_cs_op WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW, WINED3D_CS_OP_COPY_UAV_COUNTER, WINED3D_CS_OP_GENERATE_MIPMAPS, + WINED3D_CS_OP_DECODE, WINED3D_CS_OP_EXECUTE_COMMAND_LIST, WINED3D_CS_OP_STOP, }; @@ -532,6 +533,14 @@ struct wined3d_cs_generate_mipmaps struct wined3d_shader_resource_view *view; };
+struct wined3d_cs_decode +{ + enum wined3d_cs_op opcode; + struct wined3d_decoder *decoder; + struct wined3d_decoder_output_view *output_view; + unsigned int bitstream_size, slice_control_size; +}; + struct wined3d_cs_execute_command_list { enum wined3d_cs_op opcode; @@ -626,6 +635,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op) WINED3D_TO_STR(WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW); WINED3D_TO_STR(WINED3D_CS_OP_COPY_UAV_COUNTER); WINED3D_TO_STR(WINED3D_CS_OP_GENERATE_MIPMAPS); + WINED3D_TO_STR(WINED3D_CS_OP_DECODE); WINED3D_TO_STR(WINED3D_CS_OP_EXECUTE_COMMAND_LIST); WINED3D_TO_STR(WINED3D_CS_OP_STOP); #undef WINED3D_TO_STR @@ -2940,6 +2950,43 @@ void wined3d_device_context_emit_generate_mipmaps(struct wined3d_device_context wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
+static void wined3d_cs_exec_decode(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_decode *op = data; + struct wined3d_context *context; + + context = context_acquire(cs->c.device, NULL, 0); + cs->c.device->adapter->decoder_ops->decode(context, op->decoder, + op->output_view, op->bitstream_size, op->slice_control_size); + context_release(context); +} + +void wined3d_cs_emit_decode(struct wined3d_decoder *decoder, struct wined3d_decoder_output_view *output_view, + unsigned int bitstream_size, unsigned int slice_control_size) +{ + struct wined3d_device_context *context = &output_view->texture->resource.device->cs->c; + struct wined3d_cs_decode *op; + + op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_DECODE; + op->decoder = decoder; + op->output_view = output_view; + op->bitstream_size = bitstream_size; + op->slice_control_size = slice_control_size; + + wined3d_device_context_reference_resource(context, &output_view->texture->resource); + wined3d_device_context_reference_resource(context, + wined3d_decoder_get_buffer(decoder, WINED3D_DECODER_BUFFER_BITSTREAM)); + wined3d_device_context_reference_resource(context, + wined3d_decoder_get_buffer(decoder, WINED3D_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX)); + wined3d_device_context_reference_resource(context, + wined3d_decoder_get_buffer(decoder, WINED3D_DECODER_BUFFER_PICTURE_PARAMETERS)); + wined3d_device_context_reference_resource(context, + wined3d_decoder_get_buffer(decoder, WINED3D_DECODER_BUFFER_SLICE_CONTROL)); + + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); +} + static void wined3d_cs_emit_stop(struct wined3d_cs *cs) { struct wined3d_cs_stop *op; @@ -3009,6 +3056,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view, /* WINED3D_CS_OP_COPY_UAV_COUNTER */ wined3d_cs_exec_copy_uav_counter, /* WINED3D_CS_OP_GENERATE_MIPMAPS */ wined3d_cs_exec_generate_mipmaps, + /* WINED3D_CS_OP_DECODE */ wined3d_cs_exec_decode, /* WINED3D_CS_OP_EXECUTE_COMMAND_LIST */ wined3d_cs_exec_execute_command_list, };
diff --git a/dlls/wined3d/decoder.c b/dlls/wined3d/decoder.c index 1a33f759174..578b00d1f6b 100644 --- a/dlls/wined3d/decoder.c +++ b/dlls/wined3d/decoder.c @@ -440,11 +440,19 @@ static HRESULT wined3d_decoder_vk_create(struct wined3d_device *device, return WINED3D_OK; }
+static void wined3d_decoder_vk_decode(struct wined3d_context *context, struct wined3d_decoder *decoder, + struct wined3d_decoder_output_view *output_view, + unsigned int bitstream_size, unsigned int slice_control_size) +{ + FIXME("Not implemented.\n"); +} + const struct wined3d_decoder_ops wined3d_decoder_vk_ops = { .get_profiles = wined3d_decoder_vk_get_profiles, .create = wined3d_decoder_vk_create, .destroy = wined3d_decoder_vk_destroy, + .decode = wined3d_decoder_vk_decode, };
struct wined3d_resource * CDECL wined3d_decoder_get_buffer( @@ -501,3 +509,18 @@ HRESULT CDECL wined3d_decoder_end_frame(struct wined3d_decoder *decoder)
return S_OK; } + +HRESULT CDECL wined3d_decoder_decode(struct wined3d_decoder *decoder, + unsigned int bitstream_size, unsigned int slice_control_size) +{ + TRACE("decoder %p, bitstream_size %u, slice_control_size %u.\n", decoder, bitstream_size, slice_control_size); + + if (!decoder->output_view) + { + ERR("Not in frame.\n"); + return E_INVALIDARG; + } + + wined3d_cs_emit_decode(decoder, decoder->output_view, bitstream_size, slice_control_size); + return S_OK; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index e9125e52cf6..dba67917004 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -43,6 +43,7 @@ @ cdecl wined3d_decoder_begin_frame(ptr ptr) @ cdecl wined3d_decoder_create(ptr ptr ptr) @ cdecl wined3d_decoder_decref(ptr) +@ cdecl wined3d_decoder_decode(ptr long long) @ cdecl wined3d_decoder_end_frame(ptr) @ cdecl wined3d_decoder_get_buffer(ptr long)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e73ba018929..936bd46c15f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3701,6 +3701,8 @@ void wined3d_cs_emit_add_dirty_texture_region(struct wined3d_cs *cs, struct wined3d_texture *texture, unsigned int layer); void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *rects, uint32_t flags, const struct wined3d_color *color, float depth, DWORD stencil); +void wined3d_cs_emit_decode(struct wined3d_decoder *decoder, struct wined3d_decoder_output_view *output_view, + unsigned int bitstream_size, unsigned int slice_control_size); void wined3d_device_context_emit_clear_uav(struct wined3d_device_context *context, struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value, bool fp); void wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource); @@ -4486,6 +4488,9 @@ struct wined3d_decoder_ops HRESULT (*create)(struct wined3d_device *device, const struct wined3d_decoder_desc *desc, struct wined3d_decoder **decoder); void (*destroy)(struct wined3d_decoder *decoder); + void (*decode)(struct wined3d_context *context, struct wined3d_decoder *decoder, + struct wined3d_decoder_output_view *output_view, + unsigned int bitstream_size, unsigned int slice_control_size); };
extern const struct wined3d_decoder_ops wined3d_decoder_vk_ops; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 7a0434925c0..11aa2499c05 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2382,6 +2382,8 @@ HRESULT __cdecl wined3d_decoder_begin_frame(struct wined3d_decoder *decoder, struct wined3d_decoder_output_view *view); HRESULT __cdecl wined3d_decoder_create(struct wined3d_device *device, const struct wined3d_decoder_desc *desc, struct wined3d_decoder **decoder); +HRESULT __cdecl wined3d_decoder_decode(struct wined3d_decoder *decoder, + unsigned int bitstream_size, unsigned int slice_control_size); ULONG __cdecl wined3d_decoder_decref(struct wined3d_decoder *decoder); HRESULT __cdecl wined3d_decoder_end_frame(struct wined3d_decoder *decoder); struct wined3d_resource * __cdecl wined3d_decoder_get_buffer(