From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/context_vk.c | 4 +- dlls/wined3d/decoder.c | 84 +++++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_vk.h | 7 +++- 3 files changed, 92 insertions(+), 3 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index f0a9b454f39..42c54faeb8b 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -381,7 +381,7 @@ VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_cont return vk_memory; }
-static struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct wined3d_context_vk *context_vk, +struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct wined3d_context_vk *context_vk, unsigned int memory_type, VkDeviceSize size, VkDeviceMemory *vk_memory) { struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); @@ -410,7 +410,7 @@ static struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct return block; }
-static void wined3d_context_vk_free_memory(struct wined3d_context_vk *context_vk, struct wined3d_allocator_block *block) +void wined3d_context_vk_free_memory(struct wined3d_context_vk *context_vk, struct wined3d_allocator_block *block) { struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
diff --git a/dlls/wined3d/decoder.c b/dlls/wined3d/decoder.c index bb43d61067b..db6883fe619 100644 --- a/dlls/wined3d/decoder.c +++ b/dlls/wined3d/decoder.c @@ -97,6 +97,8 @@ struct wined3d_decoder_vk struct wined3d_decoder d; VkVideoSessionKHR vk_session; uint64_t command_buffer_id; + struct wined3d_allocator_block *session_memory; + VkDeviceMemory vk_session_memory; };
static struct wined3d_decoder_vk *wined3d_decoder_vk(struct wined3d_decoder *decoder) @@ -198,12 +200,19 @@ static void wined3d_decoder_vk_get_profiles(struct wined3d_adapter *adapter, uns static void wined3d_decoder_vk_destroy_object(void *object) { struct wined3d_decoder_vk *decoder_vk = object; + struct wined3d_device_vk *device_vk = wined3d_device_vk(decoder_vk->d.device); + struct wined3d_vk_info *vk_info = &device_vk->vk_info; struct wined3d_context_vk *context_vk;
TRACE("decoder_vk %p.\n", decoder_vk);
context_vk = wined3d_context_vk(context_acquire(decoder_vk->d.device, NULL, 0));
+ if (decoder_vk->session_memory) + wined3d_context_vk_free_memory(context_vk, decoder_vk->session_memory); + else + VK_CALL(vkFreeMemory(device_vk->vk_device, decoder_vk->vk_session_memory, NULL)); + wined3d_context_vk_destroy_vk_video_session(context_vk, decoder_vk->vk_session, decoder_vk->command_buffer_id);
free(decoder_vk); @@ -216,6 +225,79 @@ static void wined3d_decoder_vk_destroy(struct wined3d_decoder *decoder) wined3d_cs_destroy_object(decoder->device->cs, wined3d_decoder_vk_destroy_object, decoder_vk); }
+static void bind_video_session_memory(struct wined3d_decoder_vk *decoder_vk) +{ + struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(decoder_vk->d.device->adapter); + struct wined3d_device_vk *device_vk = wined3d_device_vk(decoder_vk->d.device); + const struct wined3d_vk_info *vk_info = &device_vk->vk_info; + VkVideoSessionMemoryRequirementsKHR *requirements; + VkBindVideoSessionMemoryInfoKHR *memory; + struct wined3d_context_vk *context_vk; + uint32_t count; + VkResult vr; + + context_vk = wined3d_context_vk(context_acquire(&device_vk->d, NULL, 0)); + + VK_CALL(vkGetVideoSessionMemoryRequirementsKHR(device_vk->vk_device, decoder_vk->vk_session, &count, NULL)); + + if (!(requirements = calloc(count, sizeof(*requirements)))) + { + context_release(&context_vk->c); + return; + } + + for (uint32_t i = 0; i < count; ++i) + requirements[i].sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_MEMORY_REQUIREMENTS_KHR; + + VK_CALL(vkGetVideoSessionMemoryRequirementsKHR(device_vk->vk_device, decoder_vk->vk_session, &count, requirements)); + + if (!(memory = calloc(count, sizeof(*memory)))) + { + free(requirements); + context_release(&context_vk->c); + return; + } + + for (uint32_t i = 0; i < count; ++i) + { + unsigned int memory_type_idx; + + /* It's not at all clear what memory properties we should be passing + * here. The spec doesn't say, and it doesn't give a hint as to what's + * most performant either. + * + * Of course, this is a terrible, terrible API generally speaking, and + * there is no reason for it to exist. */ + memory_type_idx = wined3d_adapter_vk_get_memory_type_index(adapter_vk, + requirements[i].memoryRequirements.memoryTypeBits, 0); + if (memory_type_idx == ~0u) + { + ERR("Failed to find suitable memory type.\n"); + goto out; + } + if (requirements[i].memoryRequirements.alignment > WINED3D_ALLOCATOR_MIN_BLOCK_SIZE) + ERR("Required alignment is %I64u, but we only support %u.\n", + requirements[i].memoryRequirements.alignment, WINED3D_ALLOCATOR_MIN_BLOCK_SIZE); + decoder_vk->session_memory = wined3d_context_vk_allocate_memory(context_vk, + memory_type_idx, requirements[i].memoryRequirements.size, &decoder_vk->vk_session_memory); + + memory[i].sType = VK_STRUCTURE_TYPE_BIND_VIDEO_SESSION_MEMORY_INFO_KHR; + memory[i].memoryBindIndex = requirements[i].memoryBindIndex; + memory[i].memory = decoder_vk->vk_session_memory; + memory[i].memoryOffset = decoder_vk->session_memory ? decoder_vk->session_memory->offset : 0; + memory[i].memorySize = requirements[i].memoryRequirements.size; + } + + if ((vr = VK_CALL(vkBindVideoSessionMemoryKHR(device_vk->vk_device, + decoder_vk->vk_session, count, memory))) != VK_SUCCESS) + ERR("Failed to bind memory, vr %s.\n", wined3d_debug_vkresult(vr)); + +out: + free(requirements); + free(memory); + context_release(&context_vk->c); +} + static void wined3d_decoder_vk_cs_init(void *object) { VkVideoDecodeH264CapabilitiesKHR h264_caps = {.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR}; @@ -270,6 +352,8 @@ static void wined3d_decoder_vk_cs_init(void *object) }
TRACE("Created video session 0x%s.\n", wine_dbgstr_longlong(decoder_vk->vk_session)); + + bind_video_session_memory(decoder_vk); }
static HRESULT wined3d_decoder_vk_create(struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d_vk.h b/dlls/wined3d/wined3d_vk.h index add8ec3cb3b..208431a15e8 100644 --- a/dlls/wined3d/wined3d_vk.h +++ b/dlls/wined3d/wined3d_vk.h @@ -216,8 +216,10 @@ struct wined3d_device_vk; VK_DEVICE_PFN(vkGetSwapchainImagesKHR) \ VK_DEVICE_PFN(vkQueuePresentKHR) \ /* VK_KHR_video_queue */ \ + VK_DEVICE_EXT_PFN(vkBindVideoSessionMemoryKHR) \ VK_DEVICE_EXT_PFN(vkCreateVideoSessionKHR) \ - VK_DEVICE_EXT_PFN(vkDestroyVideoSessionKHR) + VK_DEVICE_EXT_PFN(vkDestroyVideoSessionKHR) \ + VK_DEVICE_EXT_PFN(vkGetVideoSessionMemoryRequirementsKHR)
#define DECLARE_VK_PFN(name) PFN_##name name;
@@ -674,6 +676,8 @@ static inline struct wined3d_context_vk *wined3d_context_vk(struct wined3d_conte return CONTAINING_RECORD(context, struct wined3d_context_vk, c); }
+struct wined3d_allocator_block *wined3d_context_vk_allocate_memory(struct wined3d_context_vk *context_vk, + unsigned int memory_type, VkDeviceSize size, VkDeviceMemory *vk_memory); bool wined3d_context_vk_allocate_query(struct wined3d_context_vk *context_vk, enum wined3d_query_type type, struct wined3d_query_pool_idx_vk *pool_idx); VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_context_vk *context_vk, @@ -714,6 +718,7 @@ void wined3d_context_vk_destroy_vk_pipeline(struct wined3d_context_vk *context_v void wined3d_context_vk_destroy_vk_video_session(struct wined3d_context_vk *context_vk, VkPipeline vk_video_session, uint64_t command_buffer_id); void wined3d_context_vk_end_current_render_pass(struct wined3d_context_vk *context_vk); +void wined3d_context_vk_free_memory(struct wined3d_context_vk *context_vk, struct wined3d_allocator_block *block); VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk); struct wined3d_pipeline_layout_vk *wined3d_context_vk_get_pipeline_layout(struct wined3d_context_vk *context_vk, VkDescriptorSetLayoutBinding *bindings, SIZE_T binding_count);