include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / wined3d / shader_spirv.c
bloba4b311ae8d2a54e63cdfef48e1b1cf3511ae2304
1 /*
2 * Copyright 2018 Henri Verbeet for CodeWeavers
3 * Copyright 2019 Józef Kucia for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wined3d_private.h"
21 #include "wined3d_vk.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
25 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk;
27 static const struct vkd3d_shader_compile_option spirv_compile_options[] =
29 {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_7},
30 {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0},
33 struct shader_spirv_resource_bindings
35 struct vkd3d_shader_resource_binding *bindings;
36 SIZE_T bindings_size, binding_count;
38 struct vkd3d_shader_uav_counter_binding uav_counters[MAX_UNORDERED_ACCESS_VIEWS];
39 SIZE_T uav_counter_count;
41 VkDescriptorSetLayoutBinding *vk_bindings;
42 SIZE_T vk_bindings_size, vk_binding_count;
44 size_t binding_base[WINED3D_SHADER_TYPE_COUNT];
45 enum wined3d_shader_type so_stage;
48 struct shader_spirv_priv
50 const struct wined3d_vertex_pipe_ops *vertex_pipe;
51 const struct wined3d_fragment_pipe_ops *fragment_pipe;
53 struct shader_spirv_resource_bindings bindings;
56 #define MAX_SM1_INTER_STAGE_VARYINGS 12
58 struct shader_spirv_compile_arguments
60 union
62 struct
64 struct vkd3d_shader_varying_map varying_map[MAX_SM1_INTER_STAGE_VARYINGS];
65 unsigned int varying_count;
66 } vs;
67 struct
69 uint32_t alpha_swizzle;
70 unsigned int sample_count;
71 bool dual_source_blending;
72 } fs;
73 } u;
76 struct shader_spirv_graphics_program_variant_vk
78 struct shader_spirv_compile_arguments compile_args;
79 const struct wined3d_stream_output_desc *so_desc;
80 size_t binding_base;
82 VkShaderModule vk_module;
85 struct shader_spirv_graphics_program_vk
87 struct shader_spirv_graphics_program_variant_vk *variants;
88 SIZE_T variants_size, variant_count;
90 struct vkd3d_shader_scan_descriptor_info descriptor_info;
91 struct vkd3d_shader_scan_signature_info signature_info;
94 struct shader_spirv_compute_program_vk
96 VkShaderModule vk_module;
97 VkPipeline vk_pipeline;
98 VkPipelineLayout vk_pipeline_layout;
99 VkDescriptorSetLayout vk_set_layout;
101 struct vkd3d_shader_scan_descriptor_info descriptor_info;
104 struct wined3d_shader_spirv_compile_args
106 struct vkd3d_shader_varying_map_info varying_map;
107 struct vkd3d_shader_spirv_target_info spirv_target;
108 enum vkd3d_shader_spirv_extension extensions[1];
109 struct vkd3d_shader_parameter sample_count;
110 unsigned int ps_alpha_swizzle[WINED3D_MAX_RENDER_TARGETS];
113 struct wined3d_shader_spirv_shader_interface
115 struct vkd3d_shader_interface_info vkd3d_interface;
116 struct vkd3d_shader_transform_feedback_info xfb_info;
119 static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction *ins)
123 static void shader_spirv_compile_arguments_init(struct shader_spirv_compile_arguments *args,
124 const struct wined3d_context *context, const struct wined3d_shader *shader,
125 const struct wined3d_state *state, unsigned int sample_count)
127 struct wined3d_rendertarget_view *rtv;
128 unsigned int i;
130 memset(args, 0, sizeof(*args));
132 switch (shader->reg_maps.shader_version.type)
134 case WINED3D_SHADER_TYPE_PIXEL:
135 for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
137 if (!(rtv = state->fb.render_targets[i]) || rtv->format->id == WINED3DFMT_NULL)
138 continue;
139 if (rtv->format->id == WINED3DFMT_A8_UNORM && !is_identity_fixup(rtv->format->color_fixup))
140 args->u.fs.alpha_swizzle |= 1u << i;
142 args->u.fs.sample_count = sample_count;
143 args->u.fs.dual_source_blending = state->blend_state && state->blend_state->dual_source;
144 break;
146 case WINED3D_SHADER_TYPE_VERTEX:
148 struct wined3d_shader *ps = state->shader[WINED3D_SHADER_TYPE_PIXEL];
150 if (shader->reg_maps.shader_version.major < 4 && ps)
152 struct shader_spirv_graphics_program_vk *vs_program = shader->backend_data;
153 struct shader_spirv_graphics_program_vk *ps_program = ps->backend_data;
155 if (ps_program->signature_info.input.element_count > ARRAY_SIZE(args->u.vs.varying_map))
156 ERR("Unexpected inter-stage varying count %u.\n", ps_program->signature_info.input.element_count);
157 vkd3d_shader_build_varying_map(&vs_program->signature_info.output,
158 &ps_program->signature_info.input, &args->u.vs.varying_count, args->u.vs.varying_map);
160 break;
163 default:
164 break;
168 static void shader_spirv_init_compile_args(const struct wined3d_vk_info *vk_info,
169 struct wined3d_shader_spirv_compile_args *args,
170 struct vkd3d_shader_interface_info *vkd3d_interface, enum vkd3d_shader_spirv_environment environment,
171 enum wined3d_shader_type shader_type, enum vkd3d_shader_source_type source_type,
172 const struct shader_spirv_compile_arguments *compile_args)
174 unsigned int i;
176 memset(args, 0, sizeof(*args));
177 args->spirv_target.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO;
178 args->spirv_target.next = vkd3d_interface;
179 args->spirv_target.entry_point = "main";
180 args->spirv_target.environment = environment;
182 args->spirv_target.extensions = args->extensions;
184 if (vk_info->supported[WINED3D_VK_EXT_SHADER_STENCIL_EXPORT])
185 args->extensions[args->spirv_target.extension_count++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT;
186 assert(args->spirv_target.extension_count <= ARRAY_SIZE(args->extensions));
188 if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
190 unsigned int rt_alpha_swizzle = compile_args->u.fs.alpha_swizzle;
191 struct vkd3d_shader_parameter *shader_parameter;
193 shader_parameter = &args->sample_count;
194 shader_parameter->name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT;
195 shader_parameter->type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
196 shader_parameter->data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
197 shader_parameter->u.immediate_constant.u.u32 = compile_args->u.fs.sample_count;
199 args->spirv_target.dual_source_blending = compile_args->u.fs.dual_source_blending;
201 args->spirv_target.parameter_count = 1;
202 args->spirv_target.parameters = shader_parameter;
204 for (i = 0; i < ARRAY_SIZE(args->ps_alpha_swizzle); ++i)
206 if (rt_alpha_swizzle && (1u << i))
207 args->ps_alpha_swizzle[i] = VKD3D_SHADER_SWIZZLE(W, X, Y, Z);
208 else
209 args->ps_alpha_swizzle[i] = VKD3D_SHADER_NO_SWIZZLE;
212 args->spirv_target.output_swizzles = args->ps_alpha_swizzle;
213 args->spirv_target.output_swizzle_count = ARRAY_SIZE(args->ps_alpha_swizzle);
215 else if (shader_type == WINED3D_SHADER_TYPE_VERTEX)
217 if (source_type == VKD3D_SHADER_SOURCE_D3D_BYTECODE)
219 args->spirv_target.next = &args->varying_map;
221 args->varying_map.type = VKD3D_SHADER_STRUCTURE_TYPE_VARYING_MAP_INFO;
222 args->varying_map.next = vkd3d_interface;
223 args->varying_map.varying_map = compile_args->u.vs.varying_map;
224 args->varying_map.varying_count = compile_args->u.vs.varying_count;
229 static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_shader_interface *iface,
230 const struct shader_spirv_resource_bindings *b, const struct wined3d_stream_output_desc *so_desc)
232 memset(iface, 0, sizeof(*iface));
233 iface->vkd3d_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
235 if (so_desc)
237 iface->xfb_info.type = VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO;
238 iface->xfb_info.next = NULL;
240 iface->xfb_info.elements = (const struct vkd3d_shader_transform_feedback_element *)so_desc->elements;
241 iface->xfb_info.element_count = so_desc->element_count;
242 iface->xfb_info.buffer_strides = so_desc->buffer_strides;
243 iface->xfb_info.buffer_stride_count = so_desc->buffer_stride_count;
245 iface->vkd3d_interface.next = &iface->xfb_info;
248 iface->vkd3d_interface.bindings = b->bindings;
249 iface->vkd3d_interface.binding_count = b->binding_count;
251 iface->vkd3d_interface.uav_counters = b->uav_counters;
252 iface->vkd3d_interface.uav_counter_count = b->uav_counter_count;
255 static VkShaderModule shader_spirv_compile_shader(struct wined3d_context_vk *context_vk,
256 const struct wined3d_shader_desc *shader_desc, enum vkd3d_shader_source_type source_type,
257 enum wined3d_shader_type shader_type, const struct shader_spirv_compile_arguments *args,
258 const struct shader_spirv_resource_bindings *bindings, const struct wined3d_stream_output_desc *so_desc)
260 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
261 const struct wined3d_vk_info *vk_info = &device_vk->vk_info;
262 struct wined3d_shader_spirv_compile_args compile_args;
263 struct wined3d_shader_spirv_shader_interface iface;
264 VkShaderModuleCreateInfo shader_create_info;
265 struct vkd3d_shader_compile_info info;
266 struct vkd3d_shader_code spirv;
267 VkShaderModule module;
268 char *messages;
269 VkResult vr;
270 int ret;
272 shader_spirv_init_shader_interface_vk(&iface, bindings, so_desc);
273 shader_spirv_init_compile_args(vk_info, &compile_args, &iface.vkd3d_interface,
274 VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, shader_type, source_type, args);
276 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
277 info.next = &compile_args.spirv_target;
278 info.source.code = shader_desc->byte_code;
279 info.source.size = shader_desc->byte_code_size;
280 info.source_type = source_type;
281 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
282 info.options = spirv_compile_options;
283 info.option_count = ARRAY_SIZE(spirv_compile_options);
284 info.log_level = VKD3D_SHADER_LOG_WARNING;
285 info.source_name = NULL;
287 ret = vkd3d_shader_compile(&info, &spirv, &messages);
288 if (messages && *messages && FIXME_ON(d3d_shader))
290 const char *ptr, *end, *line;
292 FIXME("Shader log:\n");
293 ptr = messages;
294 end = ptr + strlen(ptr);
295 while ((line = wined3d_get_line(&ptr, end)))
297 FIXME(" %.*s", (int)(ptr - line), line);
299 FIXME("\n");
301 vkd3d_shader_free_messages(messages);
303 if (ret < 0)
305 ERR("Failed to compile shader, ret %d.\n", ret);
306 return VK_NULL_HANDLE;
309 shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
310 shader_create_info.pNext = NULL;
311 shader_create_info.flags = 0;
312 shader_create_info.codeSize = spirv.size;
313 shader_create_info.pCode = spirv.code;
314 if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_create_info, NULL, &module))) < 0)
316 vkd3d_shader_free_shader_code(&spirv);
317 WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr));
318 return VK_NULL_HANDLE;
321 vkd3d_shader_free_shader_code(&spirv);
323 return module;
326 static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphics_program_variant_vk(
327 struct shader_spirv_priv *priv, struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
328 const struct wined3d_state *state, const struct shader_spirv_resource_bindings *bindings)
330 enum wined3d_shader_type shader_type = shader->reg_maps.shader_version.type;
331 struct shader_spirv_graphics_program_variant_vk *variant_vk;
332 size_t binding_base = bindings->binding_base[shader_type];
333 const struct wined3d_stream_output_desc *so_desc = NULL;
334 struct shader_spirv_graphics_program_vk *program_vk;
335 struct shader_spirv_compile_arguments args;
336 struct wined3d_shader_desc shader_desc;
337 size_t variant_count, i;
339 shader_spirv_compile_arguments_init(&args, &context_vk->c, shader, state, context_vk->sample_count);
340 if (bindings->so_stage == shader_type)
341 so_desc = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->u.gs.so_desc;
343 if (!(program_vk = shader->backend_data))
344 return NULL;
346 variant_count = program_vk->variant_count;
347 for (i = 0; i < variant_count; ++i)
349 variant_vk = &program_vk->variants[i];
350 if (variant_vk->so_desc == so_desc && variant_vk->binding_base == binding_base
351 && !memcmp(&variant_vk->compile_args, &args, sizeof(args)))
352 return variant_vk;
355 if (!wined3d_array_reserve((void **)&program_vk->variants, &program_vk->variants_size,
356 variant_count + 1, sizeof(*program_vk->variants)))
357 return NULL;
359 variant_vk = &program_vk->variants[variant_count];
360 variant_vk->compile_args = args;
361 variant_vk->binding_base = binding_base;
363 if (shader->source_type == VKD3D_SHADER_SOURCE_D3D_BYTECODE)
365 shader_desc.byte_code = shader->function;
366 shader_desc.byte_code_size = shader->functionLength;
368 else
370 shader_desc.byte_code = shader->byte_code;
371 shader_desc.byte_code_size = shader->byte_code_size;
374 if (!(variant_vk->vk_module = shader_spirv_compile_shader(context_vk, &shader_desc,
375 shader->source_type, shader_type, &args, bindings, so_desc)))
376 return NULL;
377 ++program_vk->variant_count;
379 return variant_vk;
382 static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program_vk(struct shader_spirv_priv *priv,
383 struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
384 const struct shader_spirv_resource_bindings *bindings)
386 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
387 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
388 struct shader_spirv_compute_program_vk *program;
389 struct wined3d_pipeline_layout_vk *layout;
390 VkComputePipelineCreateInfo pipeline_info;
391 struct wined3d_shader_desc shader_desc;
392 VkResult vr;
394 if (!(program = shader->backend_data))
395 return NULL;
397 if (program->vk_module)
398 return program;
400 shader_desc.byte_code = shader->byte_code;
401 shader_desc.byte_code_size = shader->byte_code_size;
403 if (!(program->vk_module = shader_spirv_compile_shader(context_vk, &shader_desc,
404 shader->source_type, WINED3D_SHADER_TYPE_COMPUTE, NULL, bindings, NULL)))
405 return NULL;
407 if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk,
408 bindings->vk_bindings, bindings->vk_binding_count)))
410 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
411 program->vk_module = VK_NULL_HANDLE;
412 return NULL;
414 program->vk_set_layout = layout->vk_set_layout;
415 program->vk_pipeline_layout = layout->vk_pipeline_layout;
417 pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
418 pipeline_info.pNext = NULL;
419 pipeline_info.flags = 0;
420 pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
421 pipeline_info.stage.pNext = NULL;
422 pipeline_info.stage.flags = 0;
423 pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
424 pipeline_info.stage.pName = "main";
425 pipeline_info.stage.pSpecializationInfo = NULL;
426 pipeline_info.stage.module = program->vk_module;
427 pipeline_info.layout = program->vk_pipeline_layout;
428 pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
429 pipeline_info.basePipelineIndex = -1;
430 if ((vr = VK_CALL(vkCreateComputePipelines(device_vk->vk_device,
431 VK_NULL_HANDLE, 1, &pipeline_info, NULL, &program->vk_pipeline))) < 0)
433 ERR("Failed to create Vulkan compute pipeline, vr %s.\n", wined3d_debug_vkresult(vr));
434 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
435 program->vk_module = VK_NULL_HANDLE;
436 return NULL;
439 return program;
442 static void shader_spirv_resource_bindings_cleanup(struct shader_spirv_resource_bindings *bindings)
444 free(bindings->vk_bindings);
445 free(bindings->bindings);
448 static bool shader_spirv_resource_bindings_add_vk_binding(struct shader_spirv_resource_bindings *bindings,
449 VkDescriptorType vk_type, VkShaderStageFlagBits vk_stage, size_t *binding_idx)
451 SIZE_T binding_count = bindings->vk_binding_count;
452 VkDescriptorSetLayoutBinding *binding;
454 if (!wined3d_array_reserve((void **)&bindings->vk_bindings, &bindings->vk_bindings_size,
455 binding_count + 1, sizeof(*bindings->vk_bindings)))
456 return false;
458 *binding_idx = binding_count;
459 binding = &bindings->vk_bindings[binding_count];
460 binding->binding = binding_count;
461 binding->descriptorType = vk_type;
462 binding->descriptorCount = 1;
463 binding->stageFlags = vk_stage;
464 binding->pImmutableSamplers = NULL;
465 ++bindings->vk_binding_count;
467 return true;
470 static bool shader_spirv_resource_bindings_add_binding(struct shader_spirv_resource_bindings *bindings,
471 enum vkd3d_shader_descriptor_type vkd3d_type, VkDescriptorType vk_type, size_t register_idx,
472 enum vkd3d_shader_visibility vkd3d_visibility, VkShaderStageFlagBits vk_stage,
473 uint32_t flags, size_t *binding_idx)
475 SIZE_T binding_count = bindings->binding_count;
476 struct vkd3d_shader_resource_binding *binding;
478 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->bindings_size,
479 binding_count + 1, sizeof(*bindings->bindings)))
480 return false;
482 if (!shader_spirv_resource_bindings_add_vk_binding(bindings, vk_type, vk_stage, binding_idx))
483 return false;
485 binding = &bindings->bindings[binding_count];
486 binding->type = vkd3d_type;
487 binding->register_space = 0;
488 binding->register_index = register_idx;
489 binding->shader_visibility = vkd3d_visibility;
490 binding->flags = flags;
491 binding->binding.set = 0;
492 binding->binding.binding = *binding_idx;
493 binding->binding.count = 1;
494 ++bindings->binding_count;
496 return true;
499 static bool shader_spirv_resource_bindings_add_uav_counter_binding(struct shader_spirv_resource_bindings *bindings,
500 size_t register_idx, enum vkd3d_shader_visibility vkd3d_visibility,
501 VkShaderStageFlagBits vk_stage, size_t *binding_idx)
503 SIZE_T uav_counter_count = bindings->uav_counter_count;
504 struct vkd3d_shader_uav_counter_binding *counter;
506 if (uav_counter_count >= ARRAY_SIZE(bindings->uav_counters))
507 return false;
509 if (!shader_spirv_resource_bindings_add_vk_binding(bindings,
510 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, vk_stage, binding_idx))
511 return false;
513 counter = &bindings->uav_counters[uav_counter_count];
514 counter->register_space = 0;
515 counter->register_index = register_idx;
516 counter->shader_visibility = vkd3d_visibility;
517 counter->binding.set = 0;
518 counter->binding.binding = *binding_idx;
519 counter->binding.count = 1;
520 counter->offset = 0;
521 ++bindings->uav_counter_count;
523 return true;
526 static bool wined3d_shader_resource_bindings_add_binding(struct wined3d_shader_resource_bindings *bindings,
527 enum wined3d_shader_type shader_type, enum wined3d_shader_descriptor_type shader_descriptor_type,
528 size_t resource_idx, enum wined3d_shader_resource_type resource_type,
529 enum wined3d_data_type resource_data_type, size_t binding_idx)
531 struct wined3d_shader_resource_binding *binding;
532 SIZE_T binding_count = bindings->count;
534 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->size,
535 binding_count + 1, sizeof(*bindings->bindings)))
536 return false;
538 binding = &bindings->bindings[binding_count];
539 binding->shader_type = shader_type;
540 binding->shader_descriptor_type = shader_descriptor_type;
541 binding->resource_idx = resource_idx;
542 binding->resource_type = resource_type;
543 binding->resource_data_type = resource_data_type;
544 binding->binding_idx = binding_idx;
545 ++bindings->count;
547 return true;
550 static VkDescriptorType vk_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type,
551 enum vkd3d_shader_resource_type resource_type)
553 switch (type)
555 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
556 return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
558 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
559 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
560 return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
561 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
563 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
564 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
565 return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
566 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
568 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
569 return VK_DESCRIPTOR_TYPE_SAMPLER;
571 default:
572 FIXME("Unhandled descriptor type %#x.\n", type);
573 return ~0u;
577 static enum wined3d_shader_descriptor_type wined3d_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type)
579 switch (type)
581 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
582 return WINED3D_SHADER_DESCRIPTOR_TYPE_CBV;
584 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
585 return WINED3D_SHADER_DESCRIPTOR_TYPE_SRV;
587 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
588 return WINED3D_SHADER_DESCRIPTOR_TYPE_UAV;
590 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
591 return WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
593 default:
594 FIXME("Unhandled descriptor type %#x.\n", type);
595 return ~0u;
599 static enum wined3d_shader_resource_type wined3d_shader_resource_type_from_vkd3d(enum vkd3d_shader_resource_type t)
601 return (enum wined3d_shader_resource_type)t;
604 static enum wined3d_data_type wined3d_data_type_from_vkd3d(enum vkd3d_shader_resource_data_type t)
606 switch (t)
608 case VKD3D_SHADER_RESOURCE_DATA_UNORM:
609 return WINED3D_DATA_UNORM;
610 case VKD3D_SHADER_RESOURCE_DATA_SNORM:
611 return WINED3D_DATA_SNORM;
612 case VKD3D_SHADER_RESOURCE_DATA_INT:
613 return WINED3D_DATA_INT;
614 case VKD3D_SHADER_RESOURCE_DATA_UINT:
615 return WINED3D_DATA_UINT;
616 case VKD3D_SHADER_RESOURCE_DATA_FLOAT:
617 return WINED3D_DATA_FLOAT;
618 case VKD3D_SHADER_RESOURCE_DATA_MIXED:
619 return WINED3D_DATA_UINT;
620 default:
621 FIXME("Unhandled resource data type %#x.\n", t);
622 return WINED3D_DATA_FLOAT;
626 static bool shader_spirv_resource_bindings_init(struct shader_spirv_resource_bindings *bindings,
627 struct wined3d_shader_resource_bindings *wined3d_bindings,
628 const struct wined3d_state *state, uint32_t shader_mask)
630 const struct vkd3d_shader_scan_descriptor_info *descriptor_info;
631 enum wined3d_shader_descriptor_type wined3d_type;
632 enum vkd3d_shader_visibility shader_visibility;
633 enum wined3d_shader_type shader_type;
634 VkDescriptorType vk_descriptor_type;
635 VkShaderStageFlagBits vk_stage;
636 struct wined3d_shader *shader;
637 size_t binding_idx;
638 unsigned int i;
640 bindings->binding_count = 0;
641 bindings->uav_counter_count = 0;
642 bindings->vk_binding_count = 0;
643 bindings->so_stage = WINED3D_SHADER_TYPE_GEOMETRY;
644 wined3d_bindings->count = 0;
646 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_COUNT; ++shader_type)
648 bindings->binding_base[shader_type] = bindings->vk_binding_count;
650 if (!(shader_mask & (1u << shader_type)) || !(shader = state->shader[shader_type]))
651 continue;
653 if (shader_type == WINED3D_SHADER_TYPE_COMPUTE)
655 descriptor_info = &((struct shader_spirv_compute_program_vk *)shader->backend_data)->descriptor_info;
657 else
659 descriptor_info = &((struct shader_spirv_graphics_program_vk *)shader->backend_data)->descriptor_info;
660 if (shader_type == WINED3D_SHADER_TYPE_GEOMETRY && !shader->function)
661 bindings->so_stage = WINED3D_SHADER_TYPE_VERTEX;
664 vk_stage = vk_shader_stage_from_wined3d(shader_type);
665 shader_visibility = vkd3d_shader_visibility_from_wined3d(shader_type);
667 for (i = 0; i < descriptor_info->descriptor_count; ++i)
669 const struct vkd3d_shader_descriptor_info *d = &descriptor_info->descriptors[i];
670 uint32_t flags;
672 if (d->register_space)
674 WARN("Unsupported register space %u.\n", d->register_space);
675 return false;
678 if (d->resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
679 flags = VKD3D_SHADER_BINDING_FLAG_BUFFER;
680 else
681 flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
683 vk_descriptor_type = vk_descriptor_type_from_vkd3d(d->type, d->resource_type);
684 if (!shader_spirv_resource_bindings_add_binding(bindings, d->type, vk_descriptor_type,
685 d->register_index, shader_visibility, vk_stage, flags, &binding_idx))
686 return false;
688 wined3d_type = wined3d_descriptor_type_from_vkd3d(d->type);
689 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings, shader_type,
690 wined3d_type, d->register_index, wined3d_shader_resource_type_from_vkd3d(d->resource_type),
691 wined3d_data_type_from_vkd3d(d->resource_data_type), binding_idx))
692 return false;
694 if (d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
695 && (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER))
697 if (!shader_spirv_resource_bindings_add_uav_counter_binding(bindings,
698 d->register_index, shader_visibility, vk_stage, &binding_idx))
699 return false;
700 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings,
701 shader_type, WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER, d->register_index,
702 WINED3D_SHADER_RESOURCE_BUFFER, WINED3D_DATA_UINT, binding_idx))
703 return false;
708 return true;
711 static void shader_spirv_scan_shader(struct wined3d_shader *shader,
712 struct vkd3d_shader_scan_descriptor_info *descriptor_info,
713 struct vkd3d_shader_scan_signature_info *signature_info)
715 struct vkd3d_shader_compile_info info;
716 char *messages;
717 int ret;
719 memset(descriptor_info, 0, sizeof(*descriptor_info));
720 descriptor_info->type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
722 if (signature_info)
724 memset(signature_info, 0, sizeof(*signature_info));
725 signature_info->type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO;
726 descriptor_info->next = signature_info;
729 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
730 info.next = descriptor_info;
731 if (shader->source_type == VKD3D_SHADER_SOURCE_D3D_BYTECODE)
733 info.source.code = shader->function;
734 info.source.size = shader->functionLength;
736 else
738 info.source.code = shader->byte_code;
739 info.source.size = shader->byte_code_size;
741 info.source_type = shader->source_type;
742 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
743 info.options = spirv_compile_options;
744 info.option_count = ARRAY_SIZE(spirv_compile_options);
745 info.log_level = VKD3D_SHADER_LOG_WARNING;
746 info.source_name = NULL;
748 if ((ret = vkd3d_shader_scan(&info, &messages)) < 0)
749 ERR("Failed to scan shader, ret %d.\n", ret);
750 if (messages && *messages && FIXME_ON(d3d_shader))
752 const char *ptr, *end, *line;
754 FIXME("Shader log:\n");
755 ptr = messages;
756 end = ptr + strlen(ptr);
757 while ((line = wined3d_get_line(&ptr, end)))
759 FIXME(" %.*s", (int)(ptr - line), line);
761 FIXME("\n");
763 vkd3d_shader_free_messages(messages);
766 static void shader_spirv_precompile_compute(struct wined3d_shader *shader)
768 struct shader_spirv_compute_program_vk *program_vk;
770 if (!(program_vk = shader->backend_data))
772 if (!(program_vk = calloc(1, sizeof(*program_vk))))
773 ERR("Failed to allocate program.\n");
774 shader->backend_data = program_vk;
777 shader_spirv_scan_shader(shader, &program_vk->descriptor_info, NULL);
780 static void shader_spirv_precompile(void *shader_priv, struct wined3d_shader *shader)
782 struct shader_spirv_graphics_program_vk *program_vk;
784 TRACE("shader_priv %p, shader %p.\n", shader_priv, shader);
786 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
788 shader_spirv_precompile_compute(shader);
789 return;
792 if (!(program_vk = shader->backend_data))
794 if (!(program_vk = calloc(1, sizeof(*program_vk))))
795 ERR("Failed to allocate program.\n");
796 shader->backend_data = program_vk;
799 shader_spirv_scan_shader(shader, &program_vk->descriptor_info, &program_vk->signature_info);
802 static void shader_spirv_apply_draw_state(void *shader_priv, struct wined3d_context *context,
803 const struct wined3d_state *state)
805 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
806 struct shader_spirv_graphics_program_variant_vk *variant_vk;
807 struct shader_spirv_resource_bindings *bindings;
808 size_t binding_base[WINED3D_SHADER_TYPE_COUNT];
809 struct wined3d_pipeline_layout_vk *layout_vk;
810 struct shader_spirv_priv *priv = shader_priv;
811 enum wined3d_shader_type shader_type;
812 struct wined3d_shader *shader;
814 priv->vertex_pipe->vp_apply_draw_state(context, state);
815 priv->fragment_pipe->fp_apply_draw_state(context, state);
817 bindings = &priv->bindings;
818 memcpy(binding_base, bindings->binding_base, sizeof(bindings->binding_base));
819 if (!shader_spirv_resource_bindings_init(bindings, &context_vk->graphics.bindings,
820 state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)))
822 ERR("Failed to initialise shader resource bindings.\n");
823 goto fail;
825 if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY))
826 context->shader_update_mask |= 1u << bindings->so_stage;
828 layout_vk = wined3d_context_vk_get_pipeline_layout(context_vk, bindings->vk_bindings, bindings->vk_binding_count);
829 context_vk->graphics.vk_set_layout = layout_vk->vk_set_layout;
830 context_vk->graphics.vk_pipeline_layout = layout_vk->vk_pipeline_layout;
832 for (shader_type = 0; shader_type < ARRAY_SIZE(context_vk->graphics.vk_modules); ++shader_type)
834 if (!(context->shader_update_mask & (1u << shader_type)) && (!context_vk->graphics.vk_modules[shader_type]
835 || binding_base[shader_type] == bindings->binding_base[shader_type]))
836 continue;
838 if (!(shader = state->shader[shader_type]) || !shader->function)
840 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
841 continue;
844 if (!(variant_vk = shader_spirv_find_graphics_program_variant_vk(priv, context_vk, shader, state, bindings)))
845 goto fail;
846 context_vk->graphics.vk_modules[shader_type] = variant_vk->vk_module;
849 return;
851 fail:
852 context_vk->graphics.vk_set_layout = VK_NULL_HANDLE;
853 context_vk->graphics.vk_pipeline_layout = VK_NULL_HANDLE;
856 static void shader_spirv_apply_compute_state(void *shader_priv,
857 struct wined3d_context *context, const struct wined3d_state *state)
859 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
860 struct shader_spirv_compute_program_vk *program;
861 struct shader_spirv_priv *priv = shader_priv;
862 struct wined3d_shader *shader;
864 if (!shader_spirv_resource_bindings_init(&priv->bindings,
865 &context_vk->compute.bindings, state, 1u << WINED3D_SHADER_TYPE_COMPUTE))
866 ERR("Failed to initialise shader resource bindings.\n");
868 if ((shader = state->shader[WINED3D_SHADER_TYPE_COMPUTE]))
869 program = shader_spirv_find_compute_program_vk(priv, context_vk, shader, &priv->bindings);
870 else
871 program = NULL;
873 if (program)
875 context_vk->compute.vk_pipeline = program->vk_pipeline;
876 context_vk->compute.vk_set_layout = program->vk_set_layout;
877 context_vk->compute.vk_pipeline_layout = program->vk_pipeline_layout;
879 else
881 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
882 context_vk->compute.vk_set_layout = VK_NULL_HANDLE;
883 context_vk->compute.vk_pipeline_layout = VK_NULL_HANDLE;
887 static void shader_spirv_disable(void *shader_priv, struct wined3d_context *context)
889 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
890 struct shader_spirv_priv *priv = shader_priv;
892 priv->vertex_pipe->vp_disable(context);
893 priv->fragment_pipe->fp_disable(context);
895 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
896 context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
897 | (1u << WINED3D_SHADER_TYPE_VERTEX)
898 | (1u << WINED3D_SHADER_TYPE_GEOMETRY)
899 | (1u << WINED3D_SHADER_TYPE_HULL)
900 | (1u << WINED3D_SHADER_TYPE_DOMAIN)
901 | (1u << WINED3D_SHADER_TYPE_COMPUTE);
904 static void shader_spirv_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
906 WARN("Not implemented.\n");
909 static void shader_spirv_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
911 WARN("Not implemented.\n");
914 static void shader_spirv_invalidate_compute_program(struct wined3d_context_vk *context_vk,
915 const struct shader_spirv_compute_program_vk *program)
917 if (context_vk->compute.vk_pipeline == program->vk_pipeline)
919 context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE);
920 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
924 static void shader_spirv_invalidate_contexts_compute_program(struct wined3d_device *device,
925 const struct shader_spirv_compute_program_vk *program)
927 unsigned int i;
929 for (i = 0; i < device->context_count; ++i)
931 shader_spirv_invalidate_compute_program(wined3d_context_vk(device->contexts[i]), program);
935 static void shader_spirv_invalidate_graphics_program_variant(struct wined3d_context_vk *context_vk,
936 const struct shader_spirv_graphics_program_variant_vk *variant)
938 enum wined3d_shader_type shader_type;
940 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++shader_type)
942 if (context_vk->graphics.vk_modules[shader_type] != variant->vk_module)
943 continue;
945 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
946 context_vk->c.shader_update_mask |= (1u << shader_type);
950 static void shader_spirv_invalidate_contexts_graphics_program_variant(struct wined3d_device *device,
951 const struct shader_spirv_graphics_program_variant_vk *variant)
953 unsigned int i;
955 for (i = 0; i < device->context_count; ++i)
957 shader_spirv_invalidate_graphics_program_variant(wined3d_context_vk(device->contexts[i]), variant);
961 static void shader_spirv_destroy_compute_vk(struct wined3d_shader *shader)
963 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
964 struct shader_spirv_compute_program_vk *program = shader->backend_data;
965 struct wined3d_context_vk *context_vk = &device_vk->context_vk;
966 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
968 shader_spirv_invalidate_contexts_compute_program(&device_vk->d, program);
969 wined3d_context_vk_destroy_vk_pipeline(context_vk, program->vk_pipeline, context_vk->current_command_buffer.id);
970 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
971 vkd3d_shader_free_scan_descriptor_info(&program->descriptor_info);
972 shader->backend_data = NULL;
973 free(program);
976 static void shader_spirv_destroy(struct wined3d_shader *shader)
978 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
979 struct shader_spirv_graphics_program_variant_vk *variant_vk;
980 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
981 struct shader_spirv_graphics_program_vk *program_vk;
982 size_t i;
984 if (!shader->backend_data)
985 return;
987 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
989 shader_spirv_destroy_compute_vk(shader);
990 return;
993 program_vk = shader->backend_data;
994 for (i = 0; i < program_vk->variant_count; ++i)
996 variant_vk = &program_vk->variants[i];
997 shader_spirv_invalidate_contexts_graphics_program_variant(&device_vk->d, variant_vk);
998 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, variant_vk->vk_module, NULL));
1000 free(program_vk->variants);
1001 vkd3d_shader_free_scan_descriptor_info(&program_vk->descriptor_info);
1002 vkd3d_shader_free_scan_signature_info(&program_vk->signature_info);
1004 shader->backend_data = NULL;
1005 free(program_vk);
1008 static HRESULT shader_spirv_alloc(struct wined3d_device *device,
1009 const struct wined3d_vertex_pipe_ops *vertex_pipe, const struct wined3d_fragment_pipe_ops *fragment_pipe)
1011 void *vertex_priv, *fragment_priv;
1012 struct shader_spirv_priv *priv;
1014 if (!(priv = malloc(sizeof(*priv))))
1015 return E_OUTOFMEMORY;
1017 if (!(vertex_priv = vertex_pipe->vp_alloc(&spirv_shader_backend_vk, priv)))
1019 ERR("Failed to initialise vertex pipe.\n");
1020 free(priv);
1021 return E_FAIL;
1024 if (!(fragment_priv = fragment_pipe->alloc_private(&spirv_shader_backend_vk, priv)))
1026 ERR("Failed to initialise fragment pipe.\n");
1027 vertex_pipe->vp_free(device, NULL);
1028 free(priv);
1029 return E_FAIL;
1032 priv->vertex_pipe = vertex_pipe;
1033 priv->fragment_pipe = fragment_pipe;
1034 memset(&priv->bindings, 0, sizeof(priv->bindings));
1036 device->vertex_priv = vertex_priv;
1037 device->fragment_priv = fragment_priv;
1038 device->shader_priv = priv;
1040 return WINED3D_OK;
1043 static void shader_spirv_free(struct wined3d_device *device, struct wined3d_context *context)
1045 struct shader_spirv_priv *priv = device->shader_priv;
1047 shader_spirv_resource_bindings_cleanup(&priv->bindings);
1048 priv->fragment_pipe->free_private(device, context);
1049 priv->vertex_pipe->vp_free(device, context);
1050 free(priv);
1053 static BOOL shader_spirv_allocate_context_data(struct wined3d_context *context)
1055 return TRUE;
1058 static void shader_spirv_free_context_data(struct wined3d_context *context)
1062 static void shader_spirv_init_context_state(struct wined3d_context *context)
1066 static void shader_spirv_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps)
1068 caps->vs_version = min(wined3d_settings.max_sm_vs, 5);
1069 caps->hs_version = min(wined3d_settings.max_sm_hs, 5);
1070 caps->ds_version = min(wined3d_settings.max_sm_ds, 5);
1071 caps->gs_version = min(wined3d_settings.max_sm_gs, 5);
1072 caps->ps_version = min(wined3d_settings.max_sm_ps, 5);
1073 caps->cs_version = min(wined3d_settings.max_sm_cs, 5);
1075 caps->vs_uniform_count = WINED3D_MAX_VS_CONSTS_F;
1076 caps->ps_uniform_count = WINED3D_MAX_PS_CONSTS_F;
1077 caps->ps_1x_max_value = FLT_MAX;
1078 caps->varying_count = 0;
1079 caps->wined3d_caps = WINED3D_SHADER_CAP_FULL_FFP_VARYINGS;
1082 static BOOL shader_spirv_color_fixup_supported(struct color_fixup_desc fixup)
1084 return is_identity_fixup(fixup);
1087 static uint64_t shader_spirv_compile(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc,
1088 enum wined3d_shader_type shader_type)
1090 struct shader_spirv_resource_bindings bindings = {0};
1091 return (uint64_t)shader_spirv_compile_shader(wined3d_context_vk(context), shader_desc,
1092 VKD3D_SHADER_SOURCE_DXBC_TPF, shader_type, NULL, &bindings, NULL);
1095 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk =
1097 .shader_handle_instruction = shader_spirv_handle_instruction,
1098 .shader_precompile = shader_spirv_precompile,
1099 .shader_apply_draw_state = shader_spirv_apply_draw_state,
1100 .shader_apply_compute_state = shader_spirv_apply_compute_state,
1101 .shader_disable = shader_spirv_disable,
1102 .shader_update_float_vertex_constants = shader_spirv_update_float_vertex_constants,
1103 .shader_update_float_pixel_constants = shader_spirv_update_float_pixel_constants,
1104 .shader_destroy = shader_spirv_destroy,
1105 .shader_alloc_private = shader_spirv_alloc,
1106 .shader_free_private = shader_spirv_free,
1107 .shader_allocate_context_data = shader_spirv_allocate_context_data,
1108 .shader_free_context_data = shader_spirv_free_context_data,
1109 .shader_init_context_state = shader_spirv_init_context_state,
1110 .shader_get_caps = shader_spirv_get_caps,
1111 .shader_color_fixup_supported = shader_spirv_color_fixup_supported,
1112 .shader_compile = shader_spirv_compile,
1115 const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(void)
1117 TRACE("Using %s.\n", vkd3d_shader_get_version(NULL, NULL));
1119 return &spirv_shader_backend_vk;
1122 static void spirv_vertex_pipe_vk_vp_apply_draw_state(struct wined3d_context *context, const struct wined3d_state *state)
1124 /* Nothing to do. */
1127 static void spirv_vertex_pipe_vk_vp_disable(const struct wined3d_context *context)
1129 /* Nothing to do. */
1132 static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps)
1134 memset(caps, 0, sizeof(*caps));
1137 static unsigned int spirv_vertex_pipe_vk_vp_get_emul_mask(const struct wined3d_adapter *adapter)
1139 return 0;
1142 static void *spirv_vertex_pipe_vk_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1144 if (shader_backend != &spirv_shader_backend_vk)
1146 FIXME("SPIR-V vertex pipe without SPIR-V shader backend not implemented.\n");
1147 return NULL;
1150 return shader_priv;
1153 static void spirv_vertex_pipe_vk_vp_free(struct wined3d_device *device, struct wined3d_context *context)
1155 /* Nothing to do. */
1158 static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states[] =
1160 {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), state_nop}},
1161 {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_nop}},
1162 {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_RENDER(WINED3D_RS_LIGHTING), state_nop}},
1163 {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_RENDER(WINED3D_RS_COLORVERTEX), state_nop}},
1164 {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_nop}},
1165 {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_nop}},
1166 {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), state_nop}},
1167 {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), state_nop}},
1168 {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), state_nop}},
1169 {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), state_nop}},
1170 {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_nop}},
1171 {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), state_nop}},
1172 {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSIZE), state_nop}},
1173 {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_nop}},
1174 {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_nop}},
1175 {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALE_A), state_nop}},
1176 {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALE_B), state_nop}},
1177 {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALE_C), state_nop}},
1178 {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), state_nop}},
1179 {STATE_MATERIAL, {STATE_MATERIAL, state_nop}},
1180 {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), state_nop}},
1181 {STATE_LIGHT_TYPE, {STATE_LIGHT_TYPE, state_nop}},
1182 {0}, /* Terminate */
1185 static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk =
1187 .vp_apply_draw_state = spirv_vertex_pipe_vk_vp_apply_draw_state,
1188 .vp_disable = spirv_vertex_pipe_vk_vp_disable,
1189 .vp_get_caps = spirv_vertex_pipe_vk_vp_get_caps,
1190 .vp_get_emul_mask = spirv_vertex_pipe_vk_vp_get_emul_mask,
1191 .vp_alloc = spirv_vertex_pipe_vk_vp_alloc,
1192 .vp_free = spirv_vertex_pipe_vk_vp_free,
1193 .vp_states = spirv_vertex_pipe_vk_vp_states,
1196 const struct wined3d_vertex_pipe_ops *wined3d_spirv_vertex_pipe_init_vk(void)
1198 return &spirv_vertex_pipe_vk;
1201 static void spirv_fragment_pipe_vk_fp_apply_draw_state(
1202 struct wined3d_context *context, const struct wined3d_state *state)
1204 /* Nothing to do. */
1207 static void spirv_fragment_pipe_vk_fp_disable(const struct wined3d_context *context)
1209 /* Nothing to do. */
1212 static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps)
1214 memset(caps, 0, sizeof(*caps));
1217 static unsigned int spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_adapter *adapter)
1219 return 0;
1222 static void *spirv_fragment_pipe_vk_fp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1224 if (shader_backend != &spirv_shader_backend_vk)
1226 FIXME("SPIR-V fragment pipe without SPIR-V shader backend not implemented.\n");
1227 return NULL;
1230 return shader_priv;
1233 static void spirv_fragment_pipe_vk_fp_free(struct wined3d_device *device, struct wined3d_context *context)
1235 /* Nothing to do. */
1238 static BOOL spirv_fragment_pipe_vk_fp_alloc_context_data(struct wined3d_context *context)
1240 return TRUE;
1243 static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context *context)
1245 /* Nothing to do. */
1248 static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states[] =
1250 {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_nop}},
1251 {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_nop}},
1252 {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHAREF), state_nop}},
1253 {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), state_nop}},
1254 {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}},
1255 {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_nop}},
1256 {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), state_nop}},
1257 {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_nop}},
1258 {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGEND), state_nop}},
1259 {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_nop}},
1260 {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop}},
1261 {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}},
1262 {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}},
1263 {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}},
1264 {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, state_nop}},
1265 {0}, /* Terminate */
1268 static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk =
1270 .fp_apply_draw_state = spirv_fragment_pipe_vk_fp_apply_draw_state,
1271 .fp_disable = spirv_fragment_pipe_vk_fp_disable,
1272 .get_caps = spirv_fragment_pipe_vk_fp_get_caps,
1273 .get_emul_mask = spirv_fragment_pipe_vk_fp_get_emul_mask,
1274 .alloc_private = spirv_fragment_pipe_vk_fp_alloc,
1275 .free_private = spirv_fragment_pipe_vk_fp_free,
1276 .allocate_context_data = spirv_fragment_pipe_vk_fp_alloc_context_data,
1277 .free_context_data = spirv_fragment_pipe_vk_fp_free_context_data,
1278 .color_fixup_supported = shader_spirv_color_fixup_supported,
1279 .states = spirv_fragment_pipe_vk_fp_states,
1282 const struct wined3d_fragment_pipe_ops *wined3d_spirv_fragment_pipe_init_vk(void)
1284 return &spirv_fragment_pipe_vk;