Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/shader_spirv.c | 84 +++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 22 deletions(-)
diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 185c5f78556..c09eb724c2c 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -78,6 +78,18 @@ struct shader_spirv_compile_arguments } u; };
+struct shader_spirv_interface +{ + const struct vkd3d_shader_resource_binding *bindings; + SIZE_T binding_count; + + const struct vkd3d_shader_uav_counter_binding *uav_counters; + SIZE_T uav_counter_count; + + const struct vkd3d_shader_push_constant_buffer *push_constants; + SIZE_T push_constant_count; +}; + struct shader_spirv_graphics_program_variant_vk { struct shader_spirv_compile_arguments compile_args; @@ -278,8 +290,7 @@ static const char *get_line(const char **ptr) }
static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_shader_interface *iface, - struct wined3d_shader *shader, const struct shader_spirv_resource_bindings *b, - const struct wined3d_stream_output_desc *so_desc) + const struct shader_spirv_interface *i, const struct wined3d_stream_output_desc *so_desc) { memset(iface, 0, sizeof(*iface)); iface->vkd3d_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO; @@ -297,23 +308,26 @@ static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_sh iface->vkd3d_interface.next = &iface->xfb_info; }
- iface->vkd3d_interface.bindings = b->bindings; - iface->vkd3d_interface.binding_count = b->binding_count; + iface->vkd3d_interface.bindings = i->bindings; + iface->vkd3d_interface.binding_count = i->binding_count;
- iface->vkd3d_interface.uav_counters = b->uav_counters; - iface->vkd3d_interface.uav_counter_count = b->uav_counter_count; + iface->vkd3d_interface.uav_counters = i->uav_counters; + iface->vkd3d_interface.uav_counter_count = i->uav_counter_count; + + iface->vkd3d_interface.push_constant_buffers = i->push_constants; + iface->vkd3d_interface.push_constant_buffer_count = i->push_constant_count; }
static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk, - struct wined3d_shader *shader, const struct shader_spirv_compile_arguments *args, - const struct shader_spirv_resource_bindings *bindings, const struct wined3d_stream_output_desc *so_desc) + struct wined3d_shader_desc *shader_desc, enum wined3d_shader_type shader_type, + const struct shader_spirv_compile_arguments *args, const struct shader_spirv_interface *shader_interface, + const struct wined3d_stream_output_desc *so_desc) { struct wined3d_shader_spirv_compile_args compile_args; struct wined3d_shader_spirv_shader_interface iface; + VkShaderModuleCreateInfo shader_create_info; struct vkd3d_shader_compile_info info; const struct wined3d_vk_info *vk_info; - enum wined3d_shader_type shader_type; - VkShaderModuleCreateInfo shader_desc; struct wined3d_device_vk *device_vk; struct vkd3d_shader_code spirv; VkShaderModule module; @@ -321,15 +335,14 @@ static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk VkResult vr; int ret;
- shader_spirv_init_shader_interface_vk(&iface, shader, bindings, so_desc); - shader_type = shader->reg_maps.shader_version.type; + shader_spirv_init_shader_interface_vk(&iface, shader_interface, so_desc); shader_spirv_init_compile_args(&compile_args, &iface.vkd3d_interface, VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, shader_type, args);
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; info.next = &compile_args.spirv_target; - info.source.code = shader->byte_code; - info.source.size = shader->byte_code_size; + info.source.code = shader_desc->byte_code; + info.source.size = shader_desc->byte_code_size; info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY; info.options = NULL; @@ -361,12 +374,12 @@ static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk device_vk = wined3d_device_vk(context_vk->c.device); vk_info = &device_vk->vk_info;
- shader_desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shader_desc.pNext = NULL; - shader_desc.flags = 0; - shader_desc.codeSize = spirv.size; - shader_desc.pCode = spirv.code; - if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_desc, NULL, &module))) < 0) + shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_create_info.pNext = NULL; + shader_create_info.flags = 0; + shader_create_info.codeSize = spirv.size; + shader_create_info.pCode = spirv.code; + if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_create_info, NULL, &module))) < 0) { vkd3d_shader_free_shader_code(&spirv); WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr)); @@ -387,7 +400,9 @@ static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphi size_t binding_base = bindings->binding_base[shader_type]; const struct wined3d_stream_output_desc *so_desc = NULL; struct shader_spirv_graphics_program_vk *program_vk; + struct shader_spirv_interface shader_interface; struct shader_spirv_compile_arguments args; + struct wined3d_shader_desc shader_desc; size_t variant_count, i;
shader_spirv_compile_arguments_init(&args, &context_vk->c, shader, state, context_vk->sample_count); @@ -413,7 +428,19 @@ static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphi variant_vk = &program_vk->variants[variant_count]; variant_vk->compile_args = args; variant_vk->binding_base = binding_base; - if (!(variant_vk->vk_module = shader_spirv_compile(context_vk, shader, &args, bindings, so_desc))) + + shader_interface.bindings = bindings->bindings; + shader_interface.binding_count = bindings->binding_count; + shader_interface.uav_counters = bindings->uav_counters; + shader_interface.uav_counter_count = bindings->uav_counter_count; + shader_interface.push_constant_count = 0; + shader_interface.push_constants = NULL; + + shader_desc.byte_code = shader->byte_code; + shader_desc.byte_code_size = shader->byte_code_size; + + if (!(variant_vk->vk_module = shader_spirv_compile(context_vk, &shader_desc, shader_type, &args, + &shader_interface, so_desc))) return NULL; ++program_vk->variant_count;
@@ -427,8 +454,10 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); const struct wined3d_vk_info *vk_info = context_vk->vk_info; struct shader_spirv_compute_program_vk *program; + struct shader_spirv_interface shader_interface; struct wined3d_pipeline_layout_vk *layout; VkComputePipelineCreateInfo pipeline_info; + struct wined3d_shader_desc shader_desc; VkResult vr;
if (!(program = shader->backend_data)) @@ -437,7 +466,18 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program if (program->vk_module) return program;
- if (!(program->vk_module = shader_spirv_compile(context_vk, shader, NULL, bindings, NULL))) + shader_interface.bindings = bindings->bindings; + shader_interface.binding_count = bindings->binding_count; + shader_interface.uav_counters = bindings->uav_counters; + shader_interface.uav_counter_count = bindings->uav_counter_count; + shader_interface.push_constant_count = 0; + shader_interface.push_constants = NULL; + + shader_desc.byte_code = shader->byte_code; + shader_desc.byte_code_size = shader->byte_code_size; + + if (!(program->vk_module = shader_spirv_compile(context_vk, &shader_desc, WINED3D_SHADER_TYPE_COMPUTE, + NULL, &shader_interface, NULL))) return NULL;
if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk,