From 9b9bde8d8240b080ad1cecf1bea6f61c8c6f9c1b Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Wed, 13 May 2020 01:12:59 +0430 Subject: [PATCH] wined3d: Implement Vulkan constant buffer descriptors. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/adapter_vk.c | 8 ++ dlls/wined3d/buffer.c | 17 +++ dlls/wined3d/context_vk.c | 238 +++++++++++++++++++++++++++++++-- dlls/wined3d/shader_spirv.c | 54 +++----- dlls/wined3d/wined3d_private.h | 39 +++++- 5 files changed, 305 insertions(+), 51 deletions(-) diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index a9d3e5eb255..f3404c5e657 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -810,6 +810,7 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context, { struct wined3d_context_vk *context_vk = wined3d_context_vk(context); const struct wined3d_vk_info *vk_info; + struct wined3d_bo_user_vk *bo_user_vk; struct wined3d_device_vk *device_vk; VkCommandBuffer vk_command_buffer; VkBufferMemoryBarrier vk_barrier; @@ -830,8 +831,15 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context, { if (wined3d_context_vk_create_bo(context_vk, bo->size, bo->usage, bo->memory_type, &tmp)) { + list_move_head(&tmp.users, &bo->users); wined3d_context_vk_destroy_bo(context_vk, bo); *bo = tmp; + list_init(&bo->users); + list_move_head(&bo->users, &tmp.users); + LIST_FOR_EACH_ENTRY(bo_user_vk, &bo->users, struct wined3d_bo_user_vk, entry) + { + bo_user_vk->valid = false; + } goto map; } diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c index 4d1db98b884..b32d0160cc1 100644 --- a/dlls/wined3d/buffer.c +++ b/dlls/wined3d/buffer.c @@ -1593,12 +1593,27 @@ static BOOL wined3d_buffer_vk_create_buffer_object(struct wined3d_buffer_vk *buf return FALSE; } + list_init(&buffer_vk->bo_user.entry); + list_add_head(&buffer_vk->bo.users, &buffer_vk->bo_user.entry); buffer_vk->b.buffer_object = (uintptr_t)&buffer_vk->bo; buffer_invalidate_bo_range(&buffer_vk->b, 0, 0); return TRUE; } +const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk) +{ + if (buffer_vk->bo_user.valid) + return &buffer_vk->buffer_info; + + buffer_vk->buffer_info.buffer = buffer_vk->bo.vk_buffer; + buffer_vk->buffer_info.offset = buffer_vk->bo.buffer_offset; + buffer_vk->buffer_info.range = buffer_vk->b.resource.size; + buffer_vk->bo_user.valid = true; + + return &buffer_vk->buffer_info; +} + static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer, struct wined3d_context *context, unsigned int location) { @@ -1630,6 +1645,8 @@ static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer, switch (location) { case WINED3D_LOCATION_BUFFER: + buffer_vk->bo_user.valid = false; + list_remove(&buffer_vk->bo_user.entry); wined3d_context_vk_destroy_bo(context_vk, &buffer_vk->bo); buffer_vk->bo.vk_buffer = VK_NULL_HANDLE; buffer_vk->bo.memory = NULL; diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index b623b7db847..4c12cff7d11 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -243,6 +243,7 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context bo->buffer_offset = idx * object_size; bo->memory_offset = slab->bo.memory_offset + bo->buffer_offset; bo->size = size; + list_init(&bo->users); bo->command_buffer_id = 0; TRACE("Using buffer 0x%s, memory 0x%s, offset 0x%s for bo %p.\n", @@ -319,6 +320,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic bo->size = size; bo->usage = usage; bo->memory_type = adapter_vk->memory_properties.memoryTypes[memory_type_idx].propertyFlags; + list_init(&bo->users); bo->command_buffer_id = 0; bo->slab = NULL; @@ -770,6 +772,23 @@ static void wined3d_context_vk_destroy_bo_slab(struct wine_rb_entry *entry, void } } +static void wined3d_context_vk_destroy_pipeline_layout(struct wine_rb_entry *entry, void *ctx) +{ + struct wined3d_pipeline_layout_vk *layout = WINE_RB_ENTRY_VALUE(entry, + struct wined3d_pipeline_layout_vk, entry); + struct wined3d_context_vk *context_vk = ctx; + const struct wined3d_vk_info *vk_info; + struct wined3d_device_vk *device_vk; + + vk_info = context_vk->vk_info; + device_vk = wined3d_device_vk(context_vk->c.device); + + VK_CALL(vkDestroyPipelineLayout(device_vk->vk_device, layout->vk_pipeline_layout, NULL)); + VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, layout->vk_set_layout, NULL)); + heap_free(layout->key.bindings); + heap_free(layout); +} + static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *key, const struct wined3d_fb_state *fb, unsigned int rt_count, bool depth_stencil, uint32_t clear_flags) { @@ -966,6 +985,11 @@ static void wined3d_context_vk_destroy_render_pass(struct wine_rb_entry *entry, heap_free(pass); } +static void wined3d_shader_descriptor_writes_vk_cleanup(struct wined3d_shader_descriptor_writes_vk *writes) +{ + heap_free(writes->writes); +} + void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) { struct wined3d_command_buffer_vk *buffer = &context_vk->current_command_buffer; @@ -983,11 +1007,6 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) wined3d_context_vk_wait_command_buffer(context_vk, buffer->id - 1); context_vk->completed_command_buffer_id = buffer->id; - if (context_vk->vk_pipeline_layout) - { - VK_CALL(vkDestroyPipelineLayout(device_vk->vk_device, context_vk->vk_pipeline_layout, NULL)); - VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, context_vk->vk_set_layout, NULL)); - } heap_free(context_vk->compute.bindings.bindings); if (context_vk->vk_descriptor_pool) VK_CALL(vkDestroyDescriptorPool(device_vk->vk_device, context_vk->vk_descriptor_pool, NULL)); @@ -996,6 +1015,8 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) heap_free(context_vk->submitted.buffers); heap_free(context_vk->retired.objects); + wined3d_shader_descriptor_writes_vk_cleanup(&context_vk->descriptor_writes); + wine_rb_destroy(&context_vk->pipeline_layouts, wined3d_context_vk_destroy_pipeline_layout, context_vk); wine_rb_destroy(&context_vk->render_passes, wined3d_context_vk_destroy_render_pass, context_vk); wined3d_context_cleanup(&context_vk->c); @@ -1175,6 +1196,17 @@ static int wined3d_render_pass_vk_compare(const void *key, const struct wine_rb_ return memcmp(k, &pass->key, sizeof(*k)); } +static int wined3d_pipeline_layout_vk_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct wined3d_pipeline_layout_key_vk *a = key; + const struct wined3d_pipeline_layout_key_vk *b = &WINE_RB_ENTRY_VALUE(entry, + const struct wined3d_pipeline_layout_vk, entry)->key; + + if (a->binding_count != b->binding_count) + return a->binding_count - b->binding_count; + return memcmp(a->bindings, b->bindings, a->binding_count * sizeof(*a->bindings)); +} + static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entry *entry) { const struct wined3d_bo_slab_vk *slab = WINE_RB_ENTRY_VALUE(entry, const struct wined3d_bo_slab_vk, entry); @@ -1260,36 +1292,211 @@ static VkResult wined3d_context_vk_create_descriptor_set(struct wined3d_context_ return vr; } -static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *context_vk, - VkCommandBuffer vk_command_buffer) +static bool wined3d_shader_descriptor_writes_vk_add_write(struct wined3d_shader_descriptor_writes_vk *writes, + VkDescriptorSet vk_descriptor_set, size_t binding_idx, VkDescriptorType type, + const VkDescriptorBufferInfo *buffer_info, const VkDescriptorImageInfo *image_info, + const VkBufferView *buffer_view) { + SIZE_T write_count = writes->count; + VkWriteDescriptorSet *write; + + if (!wined3d_array_reserve((void **)&writes->writes, &writes->size, + write_count + 1, sizeof(*writes->writes))) + return false; + + write = &writes->writes[write_count]; + write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + write->pNext = NULL; + write->dstSet = vk_descriptor_set; + write->dstBinding = binding_idx; + write->dstArrayElement = 0; + write->descriptorCount = 1; + write->descriptorType = type; + write->pImageInfo = image_info; + write->pBufferInfo = buffer_info; + write->pTexelBufferView = buffer_view; + + ++writes->count; + + return true; +} + +static bool wined3d_context_vk_update_descriptors(struct wined3d_context_vk *context_vk, + VkCommandBuffer vk_command_buffer, const struct wined3d_state *state) +{ + struct wined3d_shader_descriptor_writes_vk *writes = &context_vk->descriptor_writes; + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); const struct wined3d_vk_info *vk_info = context_vk->vk_info; const struct wined3d_shader_resource_binding *binding; struct wined3d_shader_resource_bindings *bindings; + const VkDescriptorBufferInfo *buffer_info; VkDescriptorSet vk_descriptor_set; + struct wined3d_buffer *buffer; VkResult vr; + size_t i; bindings = &context_vk->compute.bindings; if ((vr = wined3d_context_vk_create_descriptor_set(context_vk, - context_vk->vk_set_layout, &vk_descriptor_set))) + context_vk->compute.vk_set_layout, &vk_descriptor_set))) { WARN("Failed to create descriptor set, vr %s.\n", wined3d_debug_vkresult(vr)); return false; } - if (bindings->count) + writes->count = 0; + for (i = 0; i < bindings->count; ++i) { - binding = bindings->bindings; - FIXME("Unhandled descriptor type %#x.\n", binding->shader_descriptor_type); - return false; + binding = &bindings->bindings[i]; + + switch (binding->shader_descriptor_type) + { + case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV: + if (!(buffer = state->cb[binding->shader_type][binding->resource_idx])) + { + FIXME("NULL constant buffer views not implemented.\n"); + return false; + } + buffer_info = wined3d_buffer_vk_get_buffer_info(wined3d_buffer_vk(buffer)); + if (!wined3d_shader_descriptor_writes_vk_add_write(writes, vk_descriptor_set, + binding->binding_idx, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, buffer_info, NULL, NULL)) + return false; + break; + + default: + FIXME("Unhandled descriptor type %#x.\n", binding->shader_descriptor_type); + return false; + } } + VK_CALL(vkUpdateDescriptorSets(device_vk->vk_device, writes->count, writes->writes, 0, NULL)); VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, - context_vk->vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, NULL)); + context_vk->compute.vk_pipeline_layout, 0, 1, &vk_descriptor_set, 0, NULL)); return true; } +static VkResult wined3d_context_vk_create_descriptor_set_layout(struct wined3d_device_vk *device_vk, + const struct wined3d_vk_info *vk_info, const struct wined3d_pipeline_layout_key_vk *key, + VkDescriptorSetLayout *vk_set_layout) +{ + VkDescriptorSetLayoutCreateInfo layout_desc; + VkResult vr; + + layout_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layout_desc.pNext = NULL; + layout_desc.flags = 0; + layout_desc.bindingCount = key->binding_count; + layout_desc.pBindings = key->bindings; + + if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device_vk->vk_device, &layout_desc, NULL, vk_set_layout))) < 0) + WARN("Failed to create Vulkan descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr)); + + return vr; +} + +struct wined3d_pipeline_layout_vk *wined3d_context_vk_get_pipeline_layout( + struct wined3d_context_vk *context_vk, VkDescriptorSetLayoutBinding *bindings, SIZE_T binding_count) +{ + struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); + const struct wined3d_vk_info *vk_info = context_vk->vk_info; + struct wined3d_pipeline_layout_key_vk key; + struct wined3d_pipeline_layout_vk *layout; + VkPipelineLayoutCreateInfo layout_desc; + struct wine_rb_entry *entry; + VkResult vr; + + key.bindings = bindings; + key.binding_count = binding_count; + if ((entry = wine_rb_get(&context_vk->pipeline_layouts, &key))) + return WINE_RB_ENTRY_VALUE(entry, struct wined3d_pipeline_layout_vk, entry); + + if (!(layout = heap_alloc(sizeof(*layout)))) + return NULL; + + if (!(layout->key.bindings = heap_alloc(sizeof(*layout->key.bindings) * key.binding_count))) + { + heap_free(layout); + return NULL; + } + memcpy(layout->key.bindings, key.bindings, sizeof(*layout->key.bindings) * key.binding_count); + layout->key.binding_count = key.binding_count; + + if ((vr = wined3d_context_vk_create_descriptor_set_layout(device_vk, vk_info, &key, &layout->vk_set_layout))) + { + WARN("Failed to create descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr)); + goto fail; + } + + layout_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + layout_desc.pNext = NULL; + layout_desc.flags = 0; + layout_desc.setLayoutCount = 1; + layout_desc.pSetLayouts = &layout->vk_set_layout; + layout_desc.pushConstantRangeCount = 0; + layout_desc.pPushConstantRanges = NULL; + + if ((vr = VK_CALL(vkCreatePipelineLayout(device_vk->vk_device, + &layout_desc, NULL, &layout->vk_pipeline_layout))) < 0) + { + WARN("Failed to create Vulkan pipeline layout, vr %s.\n", wined3d_debug_vkresult(vr)); + VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, layout->vk_set_layout, NULL)); + goto fail; + } + + if (wine_rb_put(&context_vk->pipeline_layouts, &layout->key, &layout->entry) == -1) + { + ERR("Failed to insert pipeline layout.\n"); + VK_CALL(vkDestroyPipelineLayout(device_vk->vk_device, layout->vk_pipeline_layout, NULL)); + VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, layout->vk_set_layout, NULL)); + goto fail; + } + + return layout; + +fail: + heap_free(layout->key.bindings); + heap_free(layout); + return NULL; +} + +static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk *context_vk, + const struct wined3d_state *state) +{ + const struct wined3d_shader_resource_bindings *bindings = &context_vk->compute.bindings; + struct wined3d_shader_descriptor_writes_vk *writes = &context_vk->descriptor_writes; + const struct wined3d_shader_resource_binding *binding; + struct wined3d_buffer_vk *buffer_vk; + struct wined3d_buffer *buffer; + size_t i; + + writes->count = 0; + for (i = 0; i < bindings->count; ++i) + { + binding = &bindings->bindings[i]; + + switch (binding->shader_descriptor_type) + { + case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV: + if (!(buffer = state->cb[binding->shader_type][binding->resource_idx])) + break; + + buffer_vk = wined3d_buffer_vk(buffer); + wined3d_buffer_load(buffer, &context_vk->c, state); + if (!buffer_vk->bo_user.valid) + context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_CONSTANT_BUFFER); + wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo); + break; + + case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER: + break; + + default: + FIXME("Unhandled descriptor type %#x.\n", binding->shader_descriptor_type); + break; + } + } +} + VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk, const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) { @@ -1314,6 +1521,8 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk context_vk->update_compute_pipeline = 1; } + wined3d_context_vk_load_shader_resources(context_vk, state); + if (indirect_vk) wined3d_buffer_load_location(&indirect_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER); @@ -1339,7 +1548,7 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk if (context_vk->c.update_compute_shader_resource_bindings || context_vk->c.update_compute_unordered_access_view_bindings) { - if (!wined3d_context_vk_update_descriptors(context_vk, vk_command_buffer)) + if (!wined3d_context_vk_update_descriptors(context_vk, vk_command_buffer, state)) { ERR("Failed to update shader descriptors.\n"); return VK_NULL_HANDLE; @@ -1383,6 +1592,7 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi context_vk->current_command_buffer.id = 1; wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare); + wine_rb_init(&context_vk->pipeline_layouts, wined3d_pipeline_layout_vk_compare); wine_rb_init(&context_vk->bo_slab_available, wined3d_bo_slab_vk_compare); return WINED3D_OK; diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 4b6c8886907..28add47c7e5 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -44,6 +44,8 @@ struct shader_spirv_compute_program_vk { VkShaderModule vk_module; VkPipeline vk_pipeline; + VkPipelineLayout vk_pipeline_layout; + VkDescriptorSetLayout vk_set_layout; }; static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction *ins) @@ -65,8 +67,7 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); const struct wined3d_vk_info *vk_info = context_vk->vk_info; struct shader_spirv_compute_program_vk *program; - VkDescriptorSetLayoutCreateInfo set_layout_desc; - VkPipelineLayoutCreateInfo pipeline_layout_desc; + struct wined3d_pipeline_layout_vk *layout; VkComputePipelineCreateInfo pipeline_info; VkResult vr; @@ -82,40 +83,15 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program return NULL; } - if (!context_vk->vk_pipeline_layout) + if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk, + bindings->vk_bindings, bindings->vk_binding_count))) { - set_layout_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - set_layout_desc.pNext = NULL; - set_layout_desc.flags = 0; - set_layout_desc.bindingCount = 0; - set_layout_desc.pBindings = NULL; - if ((vr = VK_CALL(vkCreateDescriptorSetLayout(device_vk->vk_device, - &set_layout_desc, NULL, &context_vk->vk_set_layout))) < 0) - { - WARN("Failed to create Vulkan descriptor set layout, vr %s.\n", wined3d_debug_vkresult(vr)); - VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL)); - heap_free(program); - return NULL; - } - - pipeline_layout_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - pipeline_layout_desc.pNext = NULL; - pipeline_layout_desc.flags = 0; - pipeline_layout_desc.setLayoutCount = 1; - pipeline_layout_desc.pSetLayouts = &context_vk->vk_set_layout; - pipeline_layout_desc.pushConstantRangeCount = 0; - pipeline_layout_desc.pPushConstantRanges = NULL; - - if ((vr = VK_CALL(vkCreatePipelineLayout(device_vk->vk_device, - &pipeline_layout_desc, NULL, &context_vk->vk_pipeline_layout))) < 0) - { - WARN("Failed to create Vulkan pipeline layout, vr %s.\n", wined3d_debug_vkresult(vr)); - VK_CALL(vkDestroyDescriptorSetLayout(device_vk->vk_device, context_vk->vk_set_layout, NULL)); - VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL)); - heap_free(program); - return NULL; - } + VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL)); + heap_free(program); + return NULL; } + program->vk_set_layout = layout->vk_set_layout; + program->vk_pipeline_layout = layout->vk_pipeline_layout; pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; pipeline_info.pNext = NULL; @@ -127,7 +103,7 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program pipeline_info.stage.pName = "main"; pipeline_info.stage.pSpecializationInfo = NULL; pipeline_info.stage.module = program->vk_module; - pipeline_info.layout = context_vk->vk_pipeline_layout; + pipeline_info.layout = program->vk_pipeline_layout; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; pipeline_info.basePipelineIndex = -1; if ((vr = VK_CALL(vkCreateComputePipelines(device_vk->vk_device, @@ -342,9 +318,17 @@ static void shader_spirv_select_compute(void *shader_priv, program = NULL; if (program) + { context_vk->compute.vk_pipeline = program->vk_pipeline; + context_vk->compute.vk_set_layout = program->vk_set_layout; + context_vk->compute.vk_pipeline_layout = program->vk_pipeline_layout; + } else + { context_vk->compute.vk_pipeline = VK_NULL_HANDLE; + context_vk->compute.vk_set_layout = VK_NULL_HANDLE; + context_vk->compute.vk_pipeline_layout = VK_NULL_HANDLE; + } } static void shader_spirv_disable(void *shader_priv, struct wined3d_context *context) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c8dc1b9dcbb..321d58b0bf9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1540,6 +1540,12 @@ static inline GLuint wined3d_bo_gl_id(uintptr_t bo) return bo ? ((struct wined3d_bo_gl *)bo)->id : 0; } +struct wined3d_bo_user_vk +{ + struct list entry; + bool valid; +}; + struct wined3d_bo_vk { VkBuffer vk_buffer; @@ -1554,6 +1560,7 @@ struct wined3d_bo_vk VkBufferUsageFlags usage; VkMemoryPropertyFlags memory_type; + struct list users; uint64_t command_buffer_id; }; @@ -2299,6 +2306,20 @@ struct wined3d_render_pass_vk VkRenderPass vk_render_pass; }; +struct wined3d_pipeline_layout_key_vk +{ + VkDescriptorSetLayoutBinding *bindings; + SIZE_T binding_count; +}; + +struct wined3d_pipeline_layout_vk +{ + struct wine_rb_entry entry; + struct wined3d_pipeline_layout_key_vk key; + VkPipelineLayout vk_pipeline_layout; + VkDescriptorSetLayout vk_set_layout; +}; + enum wined3d_shader_descriptor_type { WINED3D_SHADER_DESCRIPTOR_TYPE_CBV, @@ -2324,6 +2345,12 @@ struct wined3d_shader_resource_bindings SIZE_T size, count; }; +struct wined3d_shader_descriptor_writes_vk +{ + VkWriteDescriptorSet *writes; + SIZE_T size, count; +}; + struct wined3d_context_vk { struct wined3d_context c; @@ -2336,6 +2363,8 @@ struct wined3d_context_vk struct { VkPipeline vk_pipeline; + VkPipelineLayout vk_pipeline_layout; + VkDescriptorSetLayout vk_set_layout; struct wined3d_shader_resource_bindings bindings; } compute; @@ -2350,12 +2379,13 @@ struct wined3d_context_vk SIZE_T buffer_count; } submitted; + struct wined3d_shader_descriptor_writes_vk descriptor_writes; + VkDescriptorPool vk_descriptor_pool; - VkPipelineLayout vk_pipeline_layout; - VkDescriptorSetLayout vk_set_layout; struct wined3d_retired_objects_vk retired; struct wine_rb_tree render_passes; + struct wine_rb_tree pipeline_layouts; struct wine_rb_tree bo_slab_available; }; @@ -2390,6 +2420,8 @@ void wined3d_context_vk_destroy_memory(struct wined3d_context_vk *context_vk, void wined3d_context_vk_destroy_sampler(struct wined3d_context_vk *context_vk, VkSampler vk_sampler, uint64_t command_buffer_id) DECLSPEC_HIDDEN; VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; +struct wined3d_pipeline_layout_vk *wined3d_context_vk_get_pipeline_layout(struct wined3d_context_vk *context_vk, + VkDescriptorSetLayoutBinding *bindings, SIZE_T binding_count) DECLSPEC_HIDDEN; VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *context_vk, const struct wined3d_fb_state *fb, unsigned int rt_count, bool depth_stencil, uint32_t clear_flags) DECLSPEC_HIDDEN; @@ -4547,6 +4579,8 @@ struct wined3d_buffer_vk struct wined3d_buffer b; struct wined3d_bo_vk bo; + struct wined3d_bo_user_vk bo_user; + VkDescriptorBufferInfo buffer_info; }; static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer *buffer) @@ -4554,6 +4588,7 @@ static inline struct wined3d_buffer_vk *wined3d_buffer_vk(struct wined3d_buffer return CONTAINING_RECORD(buffer, struct wined3d_buffer_vk, b); } +const VkDescriptorBufferInfo *wined3d_buffer_vk_get_buffer_info(struct wined3d_buffer_vk *buffer_vk) DECLSPEC_HIDDEN; HRESULT wined3d_buffer_vk_init(struct wined3d_buffer_vk *buffer_vk, struct wined3d_device *device, const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;