From 7d9c1db2abdc74dc903b9b8946aefc1adf947645 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 18 May 2020 20:22:51 +0430 Subject: [PATCH] wined3d: Implement indexed Vulkan draws. Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/adapter_vk.c | 28 ++++++++++++++++++++-------- dlls/wined3d/context_vk.c | 24 +++++++++++++++++++++++- dlls/wined3d/wined3d_private.h | 2 +- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index ade56c74077..7d152d70b06 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -1535,7 +1535,8 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device, if (parameters->indirect) indirect_vk = wined3d_buffer_vk(parameters->u.indirect.buffer); - if (!(vk_command_buffer = wined3d_context_vk_apply_draw_state(context_vk, state, indirect_vk))) + if (!(vk_command_buffer = wined3d_context_vk_apply_draw_state(context_vk, + state, indirect_vk, parameters->indexed))) { ERR("Failed to apply draw state.\n"); context_release(&context_vk->c); @@ -1547,17 +1548,23 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device, struct wined3d_bo_vk *bo = &indirect_vk->bo; uint32_t stride, size; - if (!parameters->indexed) - { - wined3d_context_vk_reference_bo(context_vk, bo); - size = indirect_vk->b.resource.size - parameters->u.indirect.offset; + wined3d_context_vk_reference_bo(context_vk, bo); + size = indirect_vk->b.resource.size - parameters->u.indirect.offset; + if (parameters->indexed) + { + stride = sizeof(VkDrawIndexedIndirectCommand); + VK_CALL(vkCmdDrawIndexedIndirect(vk_command_buffer, bo->vk_buffer, + bo->buffer_offset + parameters->u.indirect.offset, size / stride, stride)); + } + else + { stride = sizeof(VkDrawIndirectCommand); VK_CALL(vkCmdDrawIndirect(vk_command_buffer, bo->vk_buffer, bo->buffer_offset + parameters->u.indirect.offset, size / stride, stride)); } } - else if (!parameters->indexed) + else { instance_count = parameters->u.direct.instance_count; if (context_vk->c.instance_count) @@ -1565,8 +1572,13 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device, if (!instance_count) instance_count = 1; - VK_CALL(vkCmdDraw(vk_command_buffer, parameters->u.direct.index_count, instance_count, - parameters->u.direct.start_idx, parameters->u.direct.start_instance)); + if (parameters->indexed) + VK_CALL(vkCmdDrawIndexed(vk_command_buffer, parameters->u.direct.index_count, + instance_count, parameters->u.direct.start_idx, parameters->u.direct.base_vertex_idx, + parameters->u.direct.start_instance)); + else + VK_CALL(vkCmdDraw(vk_command_buffer, parameters->u.direct.index_count, instance_count, + parameters->u.direct.start_idx, parameters->u.direct.start_instance)); } context_release(&context_vk->c); diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 20f4c0f8b34..f5902bbd65a 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1126,6 +1126,7 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context context_vk->c.update_compute_shader_resource_bindings = 1; context_vk->c.update_unordered_access_view_bindings = 1; context_vk->c.update_compute_unordered_access_view_bindings = 1; + context_invalidate_state(&context_vk->c, STATE_INDEXBUFFER); VK_CALL(vkEndCommandBuffer(buffer->vk_command_buffer)); @@ -1887,7 +1888,7 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk * } VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *context_vk, - const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) + const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk, bool indexed) { struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); const struct wined3d_vk_info *vk_info = context_vk->vk_info; @@ -1950,6 +1951,13 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c wined3d_context_vk_load_shader_resources(context_vk, state, WINED3D_PIPELINE_GRAPHICS); + if (indexed) + { + wined3d_buffer_load(state->index_buffer, &context_vk->c, state); + if (!wined3d_buffer_vk(state->index_buffer)->bo_user.valid) + context_invalidate_state(&context_vk->c, STATE_INDEXBUFFER); + } + if (indirect_vk) wined3d_buffer_load(&indirect_vk->b, &context_vk->c, state); @@ -1974,6 +1982,20 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c } VK_CALL(vkCmdBindPipeline(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, context_vk->graphics.vk_pipeline)); + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_INDEXBUFFER) && state->index_buffer) + { + struct wined3d_bo_vk *bo = &wined3d_buffer_vk(state->index_buffer)->bo; + VkIndexType idx_type; + + if (state->index_format == WINED3DFMT_R16_UINT) + idx_type = VK_INDEX_TYPE_UINT16; + else + idx_type = VK_INDEX_TYPE_UINT32; + wined3d_context_vk_reference_bo(context_vk, bo); + VK_CALL(vkCmdBindIndexBuffer(vk_command_buffer, bo->vk_buffer, + bo->buffer_offset + state->index_offset, idx_type)); + } + if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL)) || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX)) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 1f2efd1f785..ef82fd7b0c1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2412,7 +2412,7 @@ VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_cont VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk *context_vk, const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) DECLSPEC_HIDDEN; VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *context_vk, - const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) DECLSPEC_HIDDEN; + const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk, bool indexed) DECLSPEC_HIDDEN; void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN; BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;