diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 4552eed4b79..ade56c74077 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -1521,6 +1521,7 @@ static void adapter_vk_flush_context(struct wined3d_context *context) static void adapter_vk_draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, const struct wined3d_draw_parameters *parameters) { + struct wined3d_buffer_vk *indirect_vk = NULL; const struct wined3d_vk_info *vk_info; struct wined3d_context_vk *context_vk; VkCommandBuffer vk_command_buffer; @@ -1531,14 +1532,32 @@ static void adapter_vk_draw_primitive(struct wined3d_device *device, context_vk = wined3d_context_vk(context_acquire(device, NULL, 0)); vk_info = context_vk->vk_info; - if (!(vk_command_buffer = wined3d_context_vk_apply_draw_state(context_vk, state))) + 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))) { ERR("Failed to apply draw state.\n"); context_release(&context_vk->c); return; } - if (!parameters->indirect && !parameters->indexed) + if (parameters->indirect) + { + 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; + + 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) { instance_count = parameters->u.direct.instance_count; if (context_vk->c.instance_count) diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index 8bb2457e1ad..20f4c0f8b34 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -1887,7 +1887,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) + const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) { 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 +1950,9 @@ 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 (indirect_vk) + wined3d_buffer_load(&indirect_vk->b, &context_vk->c, state); + if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk))) { ERR("Failed to get command buffer.\n"); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 903057fb0ef..1f2efd1f785 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) DECLSPEC_HIDDEN; + const struct wined3d_state *state, struct wined3d_buffer_vk *indirect_vk) 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;