[PATCH 7/7] wined3d: Implement indexed Vulkan draws.

Henri Verbeet hverbeet at codeweavers.com
Mon May 18 10:52:51 CDT 2020


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 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;
-- 
2.20.1




More information about the wine-devel mailing list