[PATCH 4/5] wined3d: Introduce shader_run_compute operation for the spirv backend.

Jan Sikorski jsikorski at codeweavers.com
Tue Aug 10 03:34:29 CDT 2021


Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
 dlls/wined3d/shader_spirv.c    | 112 +++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |   2 +
 2 files changed, 114 insertions(+)

diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c
index fb9f9dc4ff1..7ede7551049 100644
--- a/dlls/wined3d/shader_spirv.c
+++ b/dlls/wined3d/shader_spirv.c
@@ -1128,6 +1128,117 @@ static BOOL shader_spirv_has_ffp_proj_control(void *shader_priv)
     return priv->ffp_proj_control;
 }
 
+static void wined3d_spirv_run_compute(unsigned groups_x, unsigned groups_y, unsigned groups_z,
+        struct wined3d_context *context, struct wined3d_shader *shader, ...)
+{
+    struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
+    struct shader_spirv_priv *priv = context->shader_backend_data;
+    const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+    struct shader_spirv_resource_bindings spirv_bindings = {0};
+    struct wined3d_shader_resource_bindings bindings = {0};
+    struct shader_spirv_compute_program_vk *program;
+    VkWriteDescriptorSet write_set = {0};
+    struct wined3d_device_vk *device_vk;
+    VkDescriptorSet vk_descriptor_set;
+    VkCommandBuffer vk_command_buffer;
+    unsigned int i;
+    va_list list;
+    VkResult vr;
+
+    if (!shader_spirv_resource_bindings_add_shader(&spirv_bindings, &bindings, shader, WINED3D_SHADER_TYPE_COMPUTE))
+    {
+        ERR("Failed to initialize bindings.\n");
+        return;
+    }
+
+    program = shader_spirv_find_compute_program_vk(priv, context_vk, shader, &spirv_bindings);
+
+    vr = wined3d_context_vk_create_vk_descriptor_set(context_vk, program->vk_set_layout, &vk_descriptor_set);
+    if (vr != VK_SUCCESS)
+    {
+        ERR("Failed to create descriptor set, vr %s.\n", wined3d_debug_vkresult(vr));
+        return;
+    }
+
+    device_vk = wined3d_device_vk(context_vk->c.device);
+    if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
+    {
+        ERR("Failed to get command buffer.\n");
+        return;
+    }
+    wined3d_context_vk_end_current_render_pass(context_vk);
+
+    write_set.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    write_set.pNext = NULL;
+    write_set.dstArrayElement = 0;
+    write_set.descriptorCount = 1;
+    write_set.dstSet = vk_descriptor_set;
+
+    va_start(list, shader);
+    for (i = 0; i < bindings.count; ++i)
+    {
+        struct wined3d_shader_resource_binding *b = bindings.bindings + i;
+        VkDescriptorBufferInfo buffer_info;
+
+        write_set.dstBinding = b->binding_idx;
+
+        switch (b->shader_descriptor_type)
+        {
+            case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV:
+            {
+                struct wined3d_bo_vk *bo = va_arg(list, struct wined3d_bo_vk *);
+
+                wined3d_context_vk_reference_bo(context_vk, bo);
+
+                buffer_info.buffer = bo->vk_buffer;
+                buffer_info.offset = bo->buffer_offset;
+                buffer_info.range  = bo->size;
+
+                write_set.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+                write_set.pBufferInfo = &buffer_info;
+                break;
+            }
+            case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV:
+            {
+                struct wined3d_unordered_access_view_vk *uav = va_arg(list, struct wined3d_unordered_access_view_vk *);
+                struct wined3d_texture_vk *texture_vk;
+                wined3d_context_vk_reference_unordered_access_view(context_vk, uav);
+
+                if (uav->v.resource->type == WINED3D_RTYPE_BUFFER)
+                {
+                    write_set.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+                    write_set.pTexelBufferView = &uav->view_vk.u.vk_buffer_view;
+                }
+                else
+                {
+                    write_set.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+                    write_set.pImageInfo = &uav->view_vk.u.vk_image_info;
+                    if (!write_set.pImageInfo->imageView)
+                    {
+                        texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(uav->v.resource));
+                        write_set.pImageInfo = wined3d_texture_vk_get_default_image_info(texture_vk, context_vk);
+                    }
+                }
+
+                break;
+            }
+            default:
+            {
+                ERR("Unhandled type %#x.\n", b->shader_descriptor_type);
+                break;
+            }
+        }
+
+        VK_CALL(vkUpdateDescriptorSets(device_vk->vk_device, 1, &write_set, 0, NULL));
+    }
+    va_end(list);
+
+    VK_CALL(vkCmdBindPipeline(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, program->vk_pipeline));
+    VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, program->vk_pipeline_layout,
+            0, 1, &vk_descriptor_set, 0, NULL));
+    VK_CALL(vkCmdDispatch(vk_command_buffer, groups_x, groups_y, groups_z));
+}
+
 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk =
 {
     .shader_handle_instruction = shader_spirv_handle_instruction,
@@ -1147,6 +1258,7 @@ static const struct wined3d_shader_backend_ops spirv_shader_backend_vk =
     .shader_get_caps = shader_spirv_get_caps,
     .shader_color_fixup_supported = shader_spirv_color_fixup_supported,
     .shader_has_ffp_proj_control = shader_spirv_has_ffp_proj_control,
+    .shader_run_compute = wined3d_spirv_run_compute,
 };
 
 const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(void)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 87757e504a2..5ffcaa1f8db 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1511,6 +1511,8 @@ struct wined3d_shader_backend_ops
     void (*shader_get_caps)(const struct wined3d_adapter *adapter, struct shader_caps *caps);
     BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup);
     BOOL (*shader_has_ffp_proj_control)(void *shader_priv);
+    void (*shader_run_compute)(unsigned groups_x, unsigned groups_y, unsigned groups_z,
+            struct wined3d_context *context, struct wined3d_shader *shader, ...);
 };
 
 extern const struct wined3d_shader_backend_ops glsl_shader_backend DECLSPEC_HIDDEN;
-- 
2.30.2




More information about the wine-devel mailing list