Signed-off-by: Jan Sikorski jsikorski@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;