wined3d: Handle VKD3D_SHADER_RESOURCE_DATA_MIXED in wined3d_data_type_from_vkd3d().
[wine.git] / dlls / wined3d / shader_spirv.c
blobfe1cc03e9f4c428b1d43251b4e9b5033714bf722
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 #define LIBVKD3D_SHADER_SOURCE
22 #include <vkd3d_shader.h>
24 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
26 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk;
28 static const struct vkd3d_shader_compile_option spirv_compile_options[] =
30 {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_3},
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;
52 bool ffp_proj_control;
54 struct shader_spirv_resource_bindings bindings;
57 struct shader_spirv_compile_arguments
59 union
61 struct
63 uint32_t alpha_swizzle;
64 unsigned int sample_count;
65 bool dual_source_blending;
66 } fs;
67 } u;
70 struct shader_spirv_graphics_program_variant_vk
72 struct shader_spirv_compile_arguments compile_args;
73 const struct wined3d_stream_output_desc *so_desc;
74 size_t binding_base;
76 VkShaderModule vk_module;
79 struct shader_spirv_graphics_program_vk
81 struct shader_spirv_graphics_program_variant_vk *variants;
82 SIZE_T variants_size, variant_count;
84 struct vkd3d_shader_scan_descriptor_info descriptor_info;
87 struct shader_spirv_compute_program_vk
89 VkShaderModule vk_module;
90 VkPipeline vk_pipeline;
91 VkPipelineLayout vk_pipeline_layout;
92 VkDescriptorSetLayout vk_set_layout;
94 struct vkd3d_shader_scan_descriptor_info descriptor_info;
97 struct wined3d_shader_spirv_compile_args
99 struct vkd3d_shader_spirv_target_info spirv_target;
100 struct vkd3d_shader_parameter sample_count;
101 unsigned int ps_alpha_swizzle[WINED3D_MAX_RENDER_TARGETS];
104 struct wined3d_shader_spirv_shader_interface
106 struct vkd3d_shader_interface_info vkd3d_interface;
107 struct vkd3d_shader_transform_feedback_info xfb_info;
110 static enum vkd3d_shader_visibility vkd3d_shader_visibility_from_wined3d(enum wined3d_shader_type shader_type)
112 switch (shader_type)
114 case WINED3D_SHADER_TYPE_VERTEX:
115 return VKD3D_SHADER_VISIBILITY_VERTEX;
116 case WINED3D_SHADER_TYPE_HULL:
117 return VKD3D_SHADER_VISIBILITY_HULL;
118 case WINED3D_SHADER_TYPE_DOMAIN:
119 return VKD3D_SHADER_VISIBILITY_DOMAIN;
120 case WINED3D_SHADER_TYPE_GEOMETRY:
121 return VKD3D_SHADER_VISIBILITY_GEOMETRY;
122 case WINED3D_SHADER_TYPE_PIXEL:
123 return VKD3D_SHADER_VISIBILITY_PIXEL;
124 case WINED3D_SHADER_TYPE_COMPUTE:
125 return VKD3D_SHADER_VISIBILITY_COMPUTE;
126 default:
127 ERR("Invalid shader type %s.\n", debug_shader_type(shader_type));
128 return VKD3D_SHADER_VISIBILITY_ALL;
132 static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction *ins)
136 static void shader_spirv_compile_arguments_init(struct shader_spirv_compile_arguments *args,
137 const struct wined3d_context *context, const struct wined3d_shader *shader,
138 const struct wined3d_state *state, unsigned int sample_count)
140 struct wined3d_rendertarget_view *rtv;
141 unsigned int i;
143 memset(args, 0, sizeof(*args));
145 switch (shader->reg_maps.shader_version.type)
147 case WINED3D_SHADER_TYPE_PIXEL:
148 for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
150 if (!(rtv = state->fb.render_targets[i]) || rtv->format->id == WINED3DFMT_NULL)
151 continue;
152 if (rtv->format->id == WINED3DFMT_A8_UNORM && !is_identity_fixup(rtv->format->color_fixup))
153 args->u.fs.alpha_swizzle |= 1u << i;
155 args->u.fs.sample_count = sample_count;
156 args->u.fs.dual_source_blending = state->blend_state && state->blend_state->dual_source;
157 break;
159 default:
160 break;
164 static void shader_spirv_init_compile_args(struct wined3d_shader_spirv_compile_args *args,
165 struct vkd3d_shader_interface_info *vkd3d_interface, enum vkd3d_shader_spirv_environment environment,
166 enum wined3d_shader_type shader_type, const struct shader_spirv_compile_arguments *compile_args)
168 unsigned int i;
170 memset(args, 0, sizeof(*args));
171 args->spirv_target.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO;
172 args->spirv_target.next = vkd3d_interface;
173 args->spirv_target.entry_point = "main";
174 args->spirv_target.environment = environment;
176 if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
178 unsigned int rt_alpha_swizzle = compile_args->u.fs.alpha_swizzle;
179 struct vkd3d_shader_parameter *shader_parameter;
181 shader_parameter = &args->sample_count;
182 shader_parameter->name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT;
183 shader_parameter->type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
184 shader_parameter->data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
185 shader_parameter->u.immediate_constant.u.u32 = compile_args->u.fs.sample_count;
187 args->spirv_target.dual_source_blending = compile_args->u.fs.dual_source_blending;
189 args->spirv_target.parameter_count = 1;
190 args->spirv_target.parameters = shader_parameter;
192 for (i = 0; i < ARRAY_SIZE(args->ps_alpha_swizzle); ++i)
194 if (rt_alpha_swizzle && (1u << i))
195 args->ps_alpha_swizzle[i] = VKD3D_SHADER_SWIZZLE(W, X, Y, Z);
196 else
197 args->ps_alpha_swizzle[i] = VKD3D_SHADER_NO_SWIZZLE;
200 args->spirv_target.output_swizzles = args->ps_alpha_swizzle;
201 args->spirv_target.output_swizzle_count = ARRAY_SIZE(args->ps_alpha_swizzle);
205 static const char *get_line(const char **ptr)
207 const char *p, *q;
209 p = *ptr;
210 if (!(q = strstr(p, "\n")))
212 if (!*p) return NULL;
213 *ptr += strlen(p);
214 return p;
216 *ptr = q + 1;
218 return p;
221 static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_shader_interface *iface,
222 const struct shader_spirv_resource_bindings *b, const struct wined3d_stream_output_desc *so_desc)
224 memset(iface, 0, sizeof(*iface));
225 iface->vkd3d_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
227 if (so_desc)
229 iface->xfb_info.type = VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO;
230 iface->xfb_info.next = NULL;
232 iface->xfb_info.elements = (const struct vkd3d_shader_transform_feedback_element *)so_desc->elements;
233 iface->xfb_info.element_count = so_desc->element_count;
234 iface->xfb_info.buffer_strides = so_desc->buffer_strides;
235 iface->xfb_info.buffer_stride_count = so_desc->buffer_stride_count;
237 iface->vkd3d_interface.next = &iface->xfb_info;
240 iface->vkd3d_interface.bindings = b->bindings;
241 iface->vkd3d_interface.binding_count = b->binding_count;
243 iface->vkd3d_interface.uav_counters = b->uav_counters;
244 iface->vkd3d_interface.uav_counter_count = b->uav_counter_count;
247 static VkShaderModule shader_spirv_compile_shader(struct wined3d_context_vk *context_vk,
248 const struct wined3d_shader_desc *shader_desc, enum wined3d_shader_type shader_type,
249 const struct shader_spirv_compile_arguments *args, const struct shader_spirv_resource_bindings *bindings,
250 const struct wined3d_stream_output_desc *so_desc)
252 struct wined3d_shader_spirv_compile_args compile_args;
253 struct wined3d_shader_spirv_shader_interface iface;
254 VkShaderModuleCreateInfo shader_create_info;
255 struct vkd3d_shader_compile_info info;
256 const struct wined3d_vk_info *vk_info;
257 struct wined3d_device_vk *device_vk;
258 struct vkd3d_shader_code spirv;
259 VkShaderModule module;
260 char *messages;
261 VkResult vr;
262 int ret;
264 shader_spirv_init_shader_interface_vk(&iface, bindings, so_desc);
265 shader_spirv_init_compile_args(&compile_args, &iface.vkd3d_interface,
266 VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, shader_type, args);
268 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
269 info.next = &compile_args.spirv_target;
270 info.source.code = shader_desc->byte_code;
271 info.source.size = shader_desc->byte_code_size;
272 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
273 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
274 info.options = spirv_compile_options;
275 info.option_count = ARRAY_SIZE(spirv_compile_options);
276 info.log_level = VKD3D_SHADER_LOG_WARNING;
277 info.source_name = NULL;
279 ret = vkd3d_shader_compile(&info, &spirv, &messages);
280 if (messages && *messages && FIXME_ON(d3d_shader))
282 const char *ptr = messages;
283 const char *line;
285 FIXME("Shader log:\n");
286 while ((line = get_line(&ptr)))
288 FIXME(" %.*s", (int)(ptr - line), line);
290 FIXME("\n");
292 vkd3d_shader_free_messages(messages);
294 if (ret < 0)
296 ERR("Failed to compile DXBC, ret %d.\n", ret);
297 return VK_NULL_HANDLE;
300 device_vk = wined3d_device_vk(context_vk->c.device);
301 vk_info = &device_vk->vk_info;
303 shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
304 shader_create_info.pNext = NULL;
305 shader_create_info.flags = 0;
306 shader_create_info.codeSize = spirv.size;
307 shader_create_info.pCode = spirv.code;
308 if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_create_info, NULL, &module))) < 0)
310 vkd3d_shader_free_shader_code(&spirv);
311 WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr));
312 return VK_NULL_HANDLE;
315 vkd3d_shader_free_shader_code(&spirv);
317 return module;
320 static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphics_program_variant_vk(
321 struct shader_spirv_priv *priv, struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
322 const struct wined3d_state *state, const struct shader_spirv_resource_bindings *bindings)
324 enum wined3d_shader_type shader_type = shader->reg_maps.shader_version.type;
325 struct shader_spirv_graphics_program_variant_vk *variant_vk;
326 size_t binding_base = bindings->binding_base[shader_type];
327 const struct wined3d_stream_output_desc *so_desc = NULL;
328 struct shader_spirv_graphics_program_vk *program_vk;
329 struct shader_spirv_compile_arguments args;
330 struct wined3d_shader_desc shader_desc;
331 size_t variant_count, i;
333 shader_spirv_compile_arguments_init(&args, &context_vk->c, shader, state, context_vk->sample_count);
334 if (bindings->so_stage == shader_type)
335 so_desc = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->u.gs.so_desc;
337 if (!(program_vk = shader->backend_data))
338 return NULL;
340 variant_count = program_vk->variant_count;
341 for (i = 0; i < variant_count; ++i)
343 variant_vk = &program_vk->variants[i];
344 if (variant_vk->so_desc == so_desc && variant_vk->binding_base == binding_base
345 && !memcmp(&variant_vk->compile_args, &args, sizeof(args)))
346 return variant_vk;
349 if (!wined3d_array_reserve((void **)&program_vk->variants, &program_vk->variants_size,
350 variant_count + 1, sizeof(*program_vk->variants)))
351 return NULL;
353 variant_vk = &program_vk->variants[variant_count];
354 variant_vk->compile_args = args;
355 variant_vk->binding_base = binding_base;
357 shader_desc.byte_code = shader->byte_code;
358 shader_desc.byte_code_size = shader->byte_code_size;
360 if (!(variant_vk->vk_module = shader_spirv_compile_shader(context_vk, &shader_desc, shader_type, &args,
361 bindings, so_desc)))
362 return NULL;
363 ++program_vk->variant_count;
365 return variant_vk;
368 static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program_vk(struct shader_spirv_priv *priv,
369 struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
370 const struct shader_spirv_resource_bindings *bindings)
372 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
373 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
374 struct shader_spirv_compute_program_vk *program;
375 struct wined3d_pipeline_layout_vk *layout;
376 VkComputePipelineCreateInfo pipeline_info;
377 struct wined3d_shader_desc shader_desc;
378 VkResult vr;
380 if (!(program = shader->backend_data))
381 return NULL;
383 if (program->vk_module)
384 return program;
386 shader_desc.byte_code = shader->byte_code;
387 shader_desc.byte_code_size = shader->byte_code_size;
389 if (!(program->vk_module = shader_spirv_compile_shader(context_vk, &shader_desc, WINED3D_SHADER_TYPE_COMPUTE,
390 NULL, bindings, NULL)))
391 return NULL;
393 if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk,
394 bindings->vk_bindings, bindings->vk_binding_count)))
396 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
397 program->vk_module = VK_NULL_HANDLE;
398 return NULL;
400 program->vk_set_layout = layout->vk_set_layout;
401 program->vk_pipeline_layout = layout->vk_pipeline_layout;
403 pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
404 pipeline_info.pNext = NULL;
405 pipeline_info.flags = 0;
406 pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
407 pipeline_info.stage.pNext = NULL;
408 pipeline_info.stage.flags = 0;
409 pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
410 pipeline_info.stage.pName = "main";
411 pipeline_info.stage.pSpecializationInfo = NULL;
412 pipeline_info.stage.module = program->vk_module;
413 pipeline_info.layout = program->vk_pipeline_layout;
414 pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
415 pipeline_info.basePipelineIndex = -1;
416 if ((vr = VK_CALL(vkCreateComputePipelines(device_vk->vk_device,
417 VK_NULL_HANDLE, 1, &pipeline_info, NULL, &program->vk_pipeline))) < 0)
419 ERR("Failed to create Vulkan compute pipeline, vr %s.\n", wined3d_debug_vkresult(vr));
420 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
421 program->vk_module = VK_NULL_HANDLE;
422 return NULL;
425 return program;
428 static void shader_spirv_resource_bindings_cleanup(struct shader_spirv_resource_bindings *bindings)
430 heap_free(bindings->vk_bindings);
431 heap_free(bindings->bindings);
434 static bool shader_spirv_resource_bindings_add_vk_binding(struct shader_spirv_resource_bindings *bindings,
435 VkDescriptorType vk_type, VkShaderStageFlagBits vk_stage, size_t *binding_idx)
437 SIZE_T binding_count = bindings->vk_binding_count;
438 VkDescriptorSetLayoutBinding *binding;
440 if (!wined3d_array_reserve((void **)&bindings->vk_bindings, &bindings->vk_bindings_size,
441 binding_count + 1, sizeof(*bindings->vk_bindings)))
442 return false;
444 *binding_idx = binding_count;
445 binding = &bindings->vk_bindings[binding_count];
446 binding->binding = binding_count;
447 binding->descriptorType = vk_type;
448 binding->descriptorCount = 1;
449 binding->stageFlags = vk_stage;
450 binding->pImmutableSamplers = NULL;
451 ++bindings->vk_binding_count;
453 return true;
456 static bool shader_spirv_resource_bindings_add_binding(struct shader_spirv_resource_bindings *bindings,
457 enum vkd3d_shader_descriptor_type vkd3d_type, VkDescriptorType vk_type, size_t register_idx,
458 enum vkd3d_shader_visibility vkd3d_visibility, VkShaderStageFlagBits vk_stage,
459 uint32_t flags, size_t *binding_idx)
461 SIZE_T binding_count = bindings->binding_count;
462 struct vkd3d_shader_resource_binding *binding;
464 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->bindings_size,
465 binding_count + 1, sizeof(*bindings->bindings)))
466 return false;
468 if (!shader_spirv_resource_bindings_add_vk_binding(bindings, vk_type, vk_stage, binding_idx))
469 return false;
471 binding = &bindings->bindings[binding_count];
472 binding->type = vkd3d_type;
473 binding->register_space = 0;
474 binding->register_index = register_idx;
475 binding->shader_visibility = vkd3d_visibility;
476 binding->flags = flags;
477 binding->binding.set = 0;
478 binding->binding.binding = *binding_idx;
479 binding->binding.count = 1;
480 ++bindings->binding_count;
482 return true;
485 static bool shader_spirv_resource_bindings_add_uav_counter_binding(struct shader_spirv_resource_bindings *bindings,
486 size_t register_idx, enum vkd3d_shader_visibility vkd3d_visibility,
487 VkShaderStageFlagBits vk_stage, size_t *binding_idx)
489 SIZE_T uav_counter_count = bindings->uav_counter_count;
490 struct vkd3d_shader_uav_counter_binding *counter;
492 if (uav_counter_count >= ARRAY_SIZE(bindings->uav_counters))
493 return false;
495 if (!shader_spirv_resource_bindings_add_vk_binding(bindings,
496 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, vk_stage, binding_idx))
497 return false;
499 counter = &bindings->uav_counters[uav_counter_count];
500 counter->register_space = 0;
501 counter->register_index = register_idx;
502 counter->shader_visibility = vkd3d_visibility;
503 counter->binding.set = 0;
504 counter->binding.binding = *binding_idx;
505 counter->binding.count = 1;
506 counter->offset = 0;
507 ++bindings->uav_counter_count;
509 return true;
512 static bool wined3d_shader_resource_bindings_add_binding(struct wined3d_shader_resource_bindings *bindings,
513 enum wined3d_shader_type shader_type, enum wined3d_shader_descriptor_type shader_descriptor_type,
514 size_t resource_idx, enum wined3d_shader_resource_type resource_type,
515 enum wined3d_data_type resource_data_type, size_t binding_idx)
517 struct wined3d_shader_resource_binding *binding;
518 SIZE_T binding_count = bindings->count;
520 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->size,
521 binding_count + 1, sizeof(*bindings->bindings)))
522 return false;
524 binding = &bindings->bindings[binding_count];
525 binding->shader_type = shader_type;
526 binding->shader_descriptor_type = shader_descriptor_type;
527 binding->resource_idx = resource_idx;
528 binding->resource_type = resource_type;
529 binding->resource_data_type = resource_data_type;
530 binding->binding_idx = binding_idx;
531 ++bindings->count;
533 return true;
536 static VkDescriptorType vk_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type,
537 enum vkd3d_shader_resource_type resource_type)
539 switch (type)
541 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
542 return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
544 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
545 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
546 return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
547 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
549 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
550 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
551 return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
552 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
554 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
555 return VK_DESCRIPTOR_TYPE_SAMPLER;
557 default:
558 FIXME("Unhandled descriptor type %#x.\n", type);
559 return ~0u;
563 static enum wined3d_shader_descriptor_type wined3d_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type)
565 switch (type)
567 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
568 return WINED3D_SHADER_DESCRIPTOR_TYPE_CBV;
570 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
571 return WINED3D_SHADER_DESCRIPTOR_TYPE_SRV;
573 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
574 return WINED3D_SHADER_DESCRIPTOR_TYPE_UAV;
576 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
577 return WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
579 default:
580 FIXME("Unhandled descriptor type %#x.\n", type);
581 return ~0u;
585 static enum wined3d_shader_resource_type wined3d_shader_resource_type_from_vkd3d(enum vkd3d_shader_resource_type t)
587 return (enum wined3d_shader_resource_type)t;
590 static enum wined3d_data_type wined3d_data_type_from_vkd3d(enum vkd3d_shader_resource_data_type t)
592 switch (t)
594 case VKD3D_SHADER_RESOURCE_DATA_UNORM:
595 return WINED3D_DATA_UNORM;
596 case VKD3D_SHADER_RESOURCE_DATA_SNORM:
597 return WINED3D_DATA_SNORM;
598 case VKD3D_SHADER_RESOURCE_DATA_INT:
599 return WINED3D_DATA_INT;
600 case VKD3D_SHADER_RESOURCE_DATA_UINT:
601 return WINED3D_DATA_UINT;
602 case VKD3D_SHADER_RESOURCE_DATA_FLOAT:
603 return WINED3D_DATA_FLOAT;
604 case VKD3D_SHADER_RESOURCE_DATA_MIXED:
605 return WINED3D_DATA_UINT;
606 default:
607 FIXME("Unhandled resource data type %#x.\n", t);
608 return WINED3D_DATA_FLOAT;
612 static bool shader_spirv_resource_bindings_init(struct shader_spirv_resource_bindings *bindings,
613 struct wined3d_shader_resource_bindings *wined3d_bindings,
614 const struct wined3d_state *state, uint32_t shader_mask)
616 struct vkd3d_shader_scan_descriptor_info *descriptor_info;
617 enum wined3d_shader_descriptor_type wined3d_type;
618 enum vkd3d_shader_visibility shader_visibility;
619 enum wined3d_shader_type shader_type;
620 VkDescriptorType vk_descriptor_type;
621 VkShaderStageFlagBits vk_stage;
622 struct wined3d_shader *shader;
623 size_t binding_idx;
624 unsigned int i;
626 bindings->binding_count = 0;
627 bindings->uav_counter_count = 0;
628 bindings->vk_binding_count = 0;
629 bindings->so_stage = WINED3D_SHADER_TYPE_GEOMETRY;
630 wined3d_bindings->count = 0;
632 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_COUNT; ++shader_type)
634 bindings->binding_base[shader_type] = bindings->vk_binding_count;
636 if (!(shader_mask & (1u << shader_type)) || !(shader = state->shader[shader_type]))
637 continue;
639 if (shader_type == WINED3D_SHADER_TYPE_COMPUTE)
641 descriptor_info = &((struct shader_spirv_compute_program_vk *)shader->backend_data)->descriptor_info;
643 else
645 descriptor_info = &((struct shader_spirv_graphics_program_vk *)shader->backend_data)->descriptor_info;
646 if (shader_type == WINED3D_SHADER_TYPE_GEOMETRY && !shader->function)
647 bindings->so_stage = WINED3D_SHADER_TYPE_VERTEX;
650 vk_stage = vk_shader_stage_from_wined3d(shader_type);
651 shader_visibility = vkd3d_shader_visibility_from_wined3d(shader_type);
653 for (i = 0; i < descriptor_info->descriptor_count; ++i)
655 struct vkd3d_shader_descriptor_info *d = &descriptor_info->descriptors[i];
656 uint32_t flags;
658 if (d->register_space)
660 WARN("Unsupported register space %u.\n", d->register_space);
661 return false;
664 if (d->resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
665 flags = VKD3D_SHADER_BINDING_FLAG_BUFFER;
666 else
667 flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
669 vk_descriptor_type = vk_descriptor_type_from_vkd3d(d->type, d->resource_type);
670 if (!shader_spirv_resource_bindings_add_binding(bindings, d->type, vk_descriptor_type,
671 d->register_index, shader_visibility, vk_stage, flags, &binding_idx))
672 return false;
674 wined3d_type = wined3d_descriptor_type_from_vkd3d(d->type);
675 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings, shader_type,
676 wined3d_type, d->register_index, wined3d_shader_resource_type_from_vkd3d(d->resource_type),
677 wined3d_data_type_from_vkd3d(d->resource_data_type), binding_idx))
678 return false;
680 if (d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
681 && (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER))
683 if (!shader_spirv_resource_bindings_add_uav_counter_binding(bindings,
684 d->register_index, shader_visibility, vk_stage, &binding_idx))
685 return false;
686 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings,
687 shader_type, WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER, d->register_index,
688 WINED3D_SHADER_RESOURCE_BUFFER, WINED3D_DATA_UINT, binding_idx))
689 return false;
694 return true;
697 static void shader_spirv_scan_shader(struct wined3d_shader *shader,
698 struct vkd3d_shader_scan_descriptor_info *descriptor_info)
700 struct vkd3d_shader_compile_info info;
701 char *messages;
702 int ret;
704 memset(descriptor_info, 0, sizeof(*descriptor_info));
705 descriptor_info->type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
707 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
708 info.next = descriptor_info;
709 info.source.code = shader->byte_code;
710 info.source.size = shader->byte_code_size;
711 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
712 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
713 info.options = spirv_compile_options;
714 info.option_count = ARRAY_SIZE(spirv_compile_options);
715 info.log_level = VKD3D_SHADER_LOG_WARNING;
716 info.source_name = NULL;
718 if ((ret = vkd3d_shader_scan(&info, &messages)) < 0)
719 ERR("Failed to scan shader, ret %d.\n", ret);
720 if (messages && *messages && FIXME_ON(d3d_shader))
722 const char *ptr = messages;
723 const char *line;
725 FIXME("Shader log:\n");
726 while ((line = get_line(&ptr)))
728 FIXME(" %.*s", (int)(ptr - line), line);
730 FIXME("\n");
732 vkd3d_shader_free_messages(messages);
735 static void shader_spirv_precompile_compute(struct wined3d_shader *shader)
737 struct shader_spirv_compute_program_vk *program_vk;
739 if (!(program_vk = shader->backend_data))
741 if (!(program_vk = heap_alloc_zero(sizeof(*program_vk))))
742 ERR("Failed to allocate program.\n");
743 shader->backend_data = program_vk;
746 shader_spirv_scan_shader(shader, &program_vk->descriptor_info);
749 static void shader_spirv_precompile(void *shader_priv, struct wined3d_shader *shader)
751 struct shader_spirv_graphics_program_vk *program_vk;
753 TRACE("shader_priv %p, shader %p.\n", shader_priv, shader);
755 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
757 shader_spirv_precompile_compute(shader);
758 return;
761 if (!(program_vk = shader->backend_data))
763 if (!(program_vk = heap_alloc_zero(sizeof(*program_vk))))
764 ERR("Failed to allocate program.\n");
765 shader->backend_data = program_vk;
768 shader_spirv_scan_shader(shader, &program_vk->descriptor_info);
771 static void shader_spirv_select(void *shader_priv, struct wined3d_context *context,
772 const struct wined3d_state *state)
774 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
775 struct shader_spirv_graphics_program_variant_vk *variant_vk;
776 struct shader_spirv_resource_bindings *bindings;
777 size_t binding_base[WINED3D_SHADER_TYPE_COUNT];
778 struct wined3d_pipeline_layout_vk *layout_vk;
779 struct shader_spirv_priv *priv = shader_priv;
780 enum wined3d_shader_type shader_type;
781 struct wined3d_shader *shader;
783 priv->vertex_pipe->vp_enable(context, !use_vs(state));
784 priv->fragment_pipe->fp_enable(context, !use_ps(state));
786 bindings = &priv->bindings;
787 memcpy(binding_base, bindings->binding_base, sizeof(bindings->binding_base));
788 if (!shader_spirv_resource_bindings_init(bindings, &context_vk->graphics.bindings,
789 state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)))
791 ERR("Failed to initialise shader resource bindings.\n");
792 goto fail;
794 if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY))
795 context->shader_update_mask |= 1u << bindings->so_stage;
797 layout_vk = wined3d_context_vk_get_pipeline_layout(context_vk, bindings->vk_bindings, bindings->vk_binding_count);
798 context_vk->graphics.vk_set_layout = layout_vk->vk_set_layout;
799 context_vk->graphics.vk_pipeline_layout = layout_vk->vk_pipeline_layout;
801 for (shader_type = 0; shader_type < ARRAY_SIZE(context_vk->graphics.vk_modules); ++shader_type)
803 if (!(context->shader_update_mask & (1u << shader_type)) && (!context_vk->graphics.vk_modules[shader_type]
804 || binding_base[shader_type] == bindings->binding_base[shader_type]))
805 continue;
807 if (!(shader = state->shader[shader_type]) || !shader->function)
809 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
810 continue;
813 if (!(variant_vk = shader_spirv_find_graphics_program_variant_vk(priv, context_vk, shader, state, bindings)))
814 goto fail;
815 context_vk->graphics.vk_modules[shader_type] = variant_vk->vk_module;
818 return;
820 fail:
821 context_vk->graphics.vk_set_layout = VK_NULL_HANDLE;
822 context_vk->graphics.vk_pipeline_layout = VK_NULL_HANDLE;
825 static void shader_spirv_select_compute(void *shader_priv,
826 struct wined3d_context *context, const struct wined3d_state *state)
828 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
829 struct shader_spirv_compute_program_vk *program;
830 struct shader_spirv_priv *priv = shader_priv;
831 struct wined3d_shader *shader;
833 if (!shader_spirv_resource_bindings_init(&priv->bindings,
834 &context_vk->compute.bindings, state, 1u << WINED3D_SHADER_TYPE_COMPUTE))
835 ERR("Failed to initialise shader resource bindings.\n");
837 if ((shader = state->shader[WINED3D_SHADER_TYPE_COMPUTE]))
838 program = shader_spirv_find_compute_program_vk(priv, context_vk, shader, &priv->bindings);
839 else
840 program = NULL;
842 if (program)
844 context_vk->compute.vk_pipeline = program->vk_pipeline;
845 context_vk->compute.vk_set_layout = program->vk_set_layout;
846 context_vk->compute.vk_pipeline_layout = program->vk_pipeline_layout;
848 else
850 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
851 context_vk->compute.vk_set_layout = VK_NULL_HANDLE;
852 context_vk->compute.vk_pipeline_layout = VK_NULL_HANDLE;
856 static void shader_spirv_disable(void *shader_priv, struct wined3d_context *context)
858 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
859 struct shader_spirv_priv *priv = shader_priv;
861 priv->vertex_pipe->vp_enable(context, false);
862 priv->fragment_pipe->fp_enable(context, false);
864 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
865 context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
866 | (1u << WINED3D_SHADER_TYPE_VERTEX)
867 | (1u << WINED3D_SHADER_TYPE_GEOMETRY)
868 | (1u << WINED3D_SHADER_TYPE_HULL)
869 | (1u << WINED3D_SHADER_TYPE_DOMAIN)
870 | (1u << WINED3D_SHADER_TYPE_COMPUTE);
873 static void shader_spirv_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
875 WARN("Not implemented.\n");
878 static void shader_spirv_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
880 WARN("Not implemented.\n");
883 static void shader_spirv_load_constants(void *shader_priv, struct wined3d_context *context,
884 const struct wined3d_state *state)
886 WARN("Not implemented.\n");
889 static void shader_spirv_invalidate_compute_program(struct wined3d_context_vk *context_vk,
890 const struct shader_spirv_compute_program_vk *program)
892 if (context_vk->compute.vk_pipeline == program->vk_pipeline)
894 context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE);
895 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
899 static void shader_spirv_invalidate_contexts_compute_program(struct wined3d_device *device,
900 const struct shader_spirv_compute_program_vk *program)
902 unsigned int i;
904 for (i = 0; i < device->context_count; ++i)
906 shader_spirv_invalidate_compute_program(wined3d_context_vk(device->contexts[i]), program);
910 static void shader_spirv_invalidate_graphics_program_variant(struct wined3d_context_vk *context_vk,
911 const struct shader_spirv_graphics_program_variant_vk *variant)
913 enum wined3d_shader_type shader_type;
915 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++shader_type)
917 if (context_vk->graphics.vk_modules[shader_type] != variant->vk_module)
918 continue;
920 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
921 context_vk->c.shader_update_mask |= (1u << shader_type);
925 static void shader_spirv_invalidate_contexts_graphics_program_variant(struct wined3d_device *device,
926 const struct shader_spirv_graphics_program_variant_vk *variant)
928 unsigned int i;
930 for (i = 0; i < device->context_count; ++i)
932 shader_spirv_invalidate_graphics_program_variant(wined3d_context_vk(device->contexts[i]), variant);
936 static void shader_spirv_destroy_compute_vk(struct wined3d_shader *shader)
938 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
939 struct shader_spirv_compute_program_vk *program = shader->backend_data;
940 struct wined3d_context_vk *context_vk = &device_vk->context_vk;
941 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
943 shader_spirv_invalidate_contexts_compute_program(&device_vk->d, program);
944 wined3d_context_vk_destroy_vk_pipeline(context_vk, program->vk_pipeline, context_vk->current_command_buffer.id);
945 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
946 vkd3d_shader_free_scan_descriptor_info(&program->descriptor_info);
947 shader->backend_data = NULL;
948 heap_free(program);
951 static void shader_spirv_destroy(struct wined3d_shader *shader)
953 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
954 struct shader_spirv_graphics_program_variant_vk *variant_vk;
955 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
956 struct shader_spirv_graphics_program_vk *program_vk;
957 size_t i;
959 if (!shader->backend_data)
960 return;
962 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
964 shader_spirv_destroy_compute_vk(shader);
965 return;
968 program_vk = shader->backend_data;
969 for (i = 0; i < program_vk->variant_count; ++i)
971 variant_vk = &program_vk->variants[i];
972 shader_spirv_invalidate_contexts_graphics_program_variant(&device_vk->d, variant_vk);
973 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, variant_vk->vk_module, NULL));
975 heap_free(program_vk->variants);
976 vkd3d_shader_free_scan_descriptor_info(&program_vk->descriptor_info);
978 shader->backend_data = NULL;
979 heap_free(program_vk);
982 static HRESULT shader_spirv_alloc(struct wined3d_device *device,
983 const struct wined3d_vertex_pipe_ops *vertex_pipe, const struct wined3d_fragment_pipe_ops *fragment_pipe)
985 struct fragment_caps fragment_caps;
986 void *vertex_priv, *fragment_priv;
987 struct shader_spirv_priv *priv;
989 if (!(priv = heap_alloc(sizeof(*priv))))
990 return E_OUTOFMEMORY;
992 if (!(vertex_priv = vertex_pipe->vp_alloc(&spirv_shader_backend_vk, priv)))
994 ERR("Failed to initialise vertex pipe.\n");
995 heap_free(priv);
996 return E_FAIL;
999 if (!(fragment_priv = fragment_pipe->alloc_private(&spirv_shader_backend_vk, priv)))
1001 ERR("Failed to initialise fragment pipe.\n");
1002 vertex_pipe->vp_free(device, NULL);
1003 heap_free(priv);
1004 return E_FAIL;
1007 priv->vertex_pipe = vertex_pipe;
1008 priv->fragment_pipe = fragment_pipe;
1009 fragment_pipe->get_caps(device->adapter, &fragment_caps);
1010 priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
1011 memset(&priv->bindings, 0, sizeof(priv->bindings));
1013 device->vertex_priv = vertex_priv;
1014 device->fragment_priv = fragment_priv;
1015 device->shader_priv = priv;
1017 return WINED3D_OK;
1020 static void shader_spirv_free(struct wined3d_device *device, struct wined3d_context *context)
1022 struct shader_spirv_priv *priv = device->shader_priv;
1024 shader_spirv_resource_bindings_cleanup(&priv->bindings);
1025 priv->fragment_pipe->free_private(device, context);
1026 priv->vertex_pipe->vp_free(device, context);
1027 heap_free(priv);
1030 static BOOL shader_spirv_allocate_context_data(struct wined3d_context *context)
1032 return TRUE;
1035 static void shader_spirv_free_context_data(struct wined3d_context *context)
1039 static void shader_spirv_init_context_state(struct wined3d_context *context)
1043 static void shader_spirv_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps)
1045 caps->vs_version = min(wined3d_settings.max_sm_vs, 5);
1046 caps->hs_version = min(wined3d_settings.max_sm_hs, 5);
1047 caps->ds_version = min(wined3d_settings.max_sm_ds, 5);
1048 caps->gs_version = min(wined3d_settings.max_sm_gs, 5);
1049 caps->ps_version = min(wined3d_settings.max_sm_ps, 5);
1050 caps->cs_version = min(wined3d_settings.max_sm_cs, 5);
1052 caps->vs_uniform_count = WINED3D_MAX_VS_CONSTS_F;
1053 caps->ps_uniform_count = WINED3D_MAX_PS_CONSTS_F;
1054 caps->ps_1x_max_value = FLT_MAX;
1055 caps->varying_count = 0;
1056 caps->wined3d_caps = WINED3D_SHADER_CAP_VS_CLIPPING
1057 | WINED3D_SHADER_CAP_SRGB_WRITE
1058 | WINED3D_SHADER_CAP_FULL_FFP_VARYINGS;
1061 static BOOL shader_spirv_color_fixup_supported(struct color_fixup_desc fixup)
1063 return is_identity_fixup(fixup);
1066 static BOOL shader_spirv_has_ffp_proj_control(void *shader_priv)
1068 struct shader_spirv_priv *priv = shader_priv;
1070 return priv->ffp_proj_control;
1073 static uint64_t shader_spirv_compile(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc,
1074 enum wined3d_shader_type shader_type)
1076 struct shader_spirv_resource_bindings bindings = {0};
1077 return (uint64_t)shader_spirv_compile_shader(wined3d_context_vk(context), shader_desc, shader_type, NULL, &bindings, NULL);
1080 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk =
1082 .shader_handle_instruction = shader_spirv_handle_instruction,
1083 .shader_precompile = shader_spirv_precompile,
1084 .shader_select = shader_spirv_select,
1085 .shader_select_compute = shader_spirv_select_compute,
1086 .shader_disable = shader_spirv_disable,
1087 .shader_update_float_vertex_constants = shader_spirv_update_float_vertex_constants,
1088 .shader_update_float_pixel_constants = shader_spirv_update_float_pixel_constants,
1089 .shader_load_constants = shader_spirv_load_constants,
1090 .shader_destroy = shader_spirv_destroy,
1091 .shader_alloc_private = shader_spirv_alloc,
1092 .shader_free_private = shader_spirv_free,
1093 .shader_allocate_context_data = shader_spirv_allocate_context_data,
1094 .shader_free_context_data = shader_spirv_free_context_data,
1095 .shader_init_context_state = shader_spirv_init_context_state,
1096 .shader_get_caps = shader_spirv_get_caps,
1097 .shader_color_fixup_supported = shader_spirv_color_fixup_supported,
1098 .shader_has_ffp_proj_control = shader_spirv_has_ffp_proj_control,
1099 .shader_compile = shader_spirv_compile,
1102 const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(void)
1104 TRACE("Using %s.\n", vkd3d_shader_get_version(NULL, NULL));
1106 return &spirv_shader_backend_vk;
1109 static void spirv_vertex_pipe_vk_vp_enable(const struct wined3d_context *context, BOOL enable)
1111 /* Nothing to do. */
1114 static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps)
1116 memset(caps, 0, sizeof(*caps));
1117 caps->xyzrhw = TRUE;
1118 caps->ffp_generic_attributes = TRUE;
1121 static uint32_t spirv_vertex_pipe_vk_vp_get_emul_mask(const struct wined3d_gl_info *gl_info)
1123 return 0;
1126 static void *spirv_vertex_pipe_vk_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1128 if (shader_backend != &spirv_shader_backend_vk)
1130 FIXME("SPIR-V vertex pipe without SPIR-V shader backend not implemented.\n");
1131 return NULL;
1134 return shader_priv;
1137 static void spirv_vertex_pipe_vk_vp_free(struct wined3d_device *device, struct wined3d_context *context)
1139 /* Nothing to do. */
1142 static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states[] =
1144 {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), state_nop}},
1145 {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_nop}},
1146 {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_RENDER(WINED3D_RS_LIGHTING), state_nop}},
1147 {STATE_RENDER(WINED3D_RS_AMBIENT), {STATE_RENDER(WINED3D_RS_AMBIENT), state_nop}},
1148 {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_RENDER(WINED3D_RS_COLORVERTEX), state_nop}},
1149 {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_nop}},
1150 {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_nop}},
1151 {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), state_nop}},
1152 {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), state_nop}},
1153 {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), state_nop}},
1154 {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), state_nop}},
1155 {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_nop}},
1156 {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), state_nop}},
1157 {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSIZE), state_nop}},
1158 {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_nop}},
1159 {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_nop}},
1160 {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALE_A), state_nop}},
1161 {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALE_B), state_nop}},
1162 {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALE_C), state_nop}},
1163 {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), state_nop}},
1164 {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), state_nop}},
1165 {STATE_RENDER(WINED3D_RS_TWEENFACTOR), {STATE_RENDER(WINED3D_RS_TWEENFACTOR), state_nop}},
1166 {STATE_MATERIAL, {STATE_MATERIAL, state_nop}},
1167 {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), state_nop}},
1168 {STATE_LIGHT_TYPE, {STATE_LIGHT_TYPE, state_nop}},
1169 {0}, /* Terminate */
1172 static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk =
1174 .vp_enable = spirv_vertex_pipe_vk_vp_enable,
1175 .vp_get_caps = spirv_vertex_pipe_vk_vp_get_caps,
1176 .vp_get_emul_mask = spirv_vertex_pipe_vk_vp_get_emul_mask,
1177 .vp_alloc = spirv_vertex_pipe_vk_vp_alloc,
1178 .vp_free = spirv_vertex_pipe_vk_vp_free,
1179 .vp_states = spirv_vertex_pipe_vk_vp_states,
1182 const struct wined3d_vertex_pipe_ops *wined3d_spirv_vertex_pipe_init_vk(void)
1184 return &spirv_vertex_pipe_vk;
1187 static void spirv_fragment_pipe_vk_fp_enable(const struct wined3d_context *context, BOOL enable)
1189 /* Nothing to do. */
1192 static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps)
1194 memset(caps, 0, sizeof(*caps));
1197 static uint32_t spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_gl_info *gl_info)
1199 return 0;
1202 static void *spirv_fragment_pipe_vk_fp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1204 if (shader_backend != &spirv_shader_backend_vk)
1206 FIXME("SPIR-V fragment pipe without SPIR-V shader backend not implemented.\n");
1207 return NULL;
1210 return shader_priv;
1213 static void spirv_fragment_pipe_vk_fp_free(struct wined3d_device *device, struct wined3d_context *context)
1215 /* Nothing to do. */
1218 static BOOL spirv_fragment_pipe_vk_fp_alloc_context_data(struct wined3d_context *context)
1220 return TRUE;
1223 static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context *context)
1225 /* Nothing to do. */
1228 static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states[] =
1230 {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_nop}},
1231 {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_nop}},
1232 {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHAREF), state_nop}},
1233 {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), state_nop}},
1234 {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}},
1235 {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_nop}},
1236 {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_nop}},
1237 {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), state_nop}},
1238 {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_nop}},
1239 {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGEND), state_nop}},
1240 {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_nop}},
1241 {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop}},
1242 {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_nop}},
1243 {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}},
1244 {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}},
1245 {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}},
1246 {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, state_nop}},
1247 {STATE_COLOR_KEY, {STATE_COLOR_KEY, state_nop}},
1248 {0}, /* Terminate */
1251 static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk =
1253 .fp_enable = spirv_fragment_pipe_vk_fp_enable,
1254 .get_caps = spirv_fragment_pipe_vk_fp_get_caps,
1255 .get_emul_mask = spirv_fragment_pipe_vk_fp_get_emul_mask,
1256 .alloc_private = spirv_fragment_pipe_vk_fp_alloc,
1257 .free_private = spirv_fragment_pipe_vk_fp_free,
1258 .allocate_context_data = spirv_fragment_pipe_vk_fp_alloc_context_data,
1259 .free_context_data = spirv_fragment_pipe_vk_fp_free_context_data,
1260 .color_fixup_supported = shader_spirv_color_fixup_supported,
1261 .states = spirv_fragment_pipe_vk_fp_states,
1264 const struct wined3d_fragment_pipe_ops *wined3d_spirv_fragment_pipe_init_vk(void)
1266 return &spirv_fragment_pipe_vk;