[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