ws2_32: Add support for hints in GetAddrInfoExW.
[wine.git] / dlls / wined3d / shader_spirv.c
blob7617ee9d6ef9dcd0b7fdb6cb89ce53a786e91643
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 "config.h"
21 #include "wine/port.h"
23 #include "wined3d_private.h"
25 WINE_DECLARE_DEBUG_CHANNEL(winediag);
27 #ifdef SONAME_LIBVKD3D_SHADER
29 #define VKD3D_SHADER_NO_PROTOTYPES
30 #include <vkd3d_shader.h>
32 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
34 static PFN_vkd3d_shader_compile vkd3d_shader_compile;
35 static PFN_vkd3d_shader_free_messages vkd3d_shader_free_messages;
36 static PFN_vkd3d_shader_free_scan_descriptor_info vkd3d_shader_free_scan_descriptor_info;
37 static PFN_vkd3d_shader_free_shader_code vkd3d_shader_free_shader_code;
38 static PFN_vkd3d_shader_get_version vkd3d_shader_get_version;
39 static PFN_vkd3d_shader_scan vkd3d_shader_scan;
41 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk;
43 static void *vkd3d_shader_handle;
45 struct shader_spirv_resource_bindings
47 struct vkd3d_shader_resource_binding *bindings;
48 SIZE_T bindings_size, binding_count;
50 struct vkd3d_shader_uav_counter_binding uav_counters[MAX_UNORDERED_ACCESS_VIEWS];
51 SIZE_T uav_counter_count;
53 VkDescriptorSetLayoutBinding *vk_bindings;
54 SIZE_T vk_bindings_size, vk_binding_count;
56 size_t binding_base[WINED3D_SHADER_TYPE_COUNT];
57 enum wined3d_shader_type so_stage;
60 struct shader_spirv_priv
62 const struct wined3d_vertex_pipe_ops *vertex_pipe;
63 const struct wined3d_fragment_pipe_ops *fragment_pipe;
64 bool ffp_proj_control;
66 struct shader_spirv_resource_bindings bindings;
69 struct shader_spirv_compile_arguments
71 union
73 struct
75 uint32_t alpha_swizzle;
76 unsigned int sample_count;
77 } fs;
78 } u;
81 struct shader_spirv_graphics_program_variant_vk
83 struct shader_spirv_compile_arguments compile_args;
84 const struct wined3d_stream_output_desc *so_desc;
85 size_t binding_base;
87 VkShaderModule vk_module;
90 struct shader_spirv_graphics_program_vk
92 struct shader_spirv_graphics_program_variant_vk *variants;
93 SIZE_T variants_size, variant_count;
95 struct vkd3d_shader_scan_descriptor_info descriptor_info;
98 struct shader_spirv_compute_program_vk
100 VkShaderModule vk_module;
101 VkPipeline vk_pipeline;
102 VkPipelineLayout vk_pipeline_layout;
103 VkDescriptorSetLayout vk_set_layout;
105 struct vkd3d_shader_scan_descriptor_info descriptor_info;
108 struct wined3d_shader_spirv_compile_args
110 struct vkd3d_shader_spirv_target_info spirv_target;
111 struct vkd3d_shader_parameter sample_count;
112 unsigned int ps_alpha_swizzle[WINED3D_MAX_RENDER_TARGETS];
115 struct wined3d_shader_spirv_shader_interface
117 struct vkd3d_shader_interface_info vkd3d_interface;
118 struct vkd3d_shader_transform_feedback_info xfb_info;
121 static bool wined3d_load_vkd3d_shader_functions(void *vkd3d_shader_handle)
123 #define LOAD_FUNCPTR(f) if (!(f = dlsym(vkd3d_shader_handle, #f))) return false;
124 LOAD_FUNCPTR(vkd3d_shader_compile)
125 LOAD_FUNCPTR(vkd3d_shader_free_messages)
126 LOAD_FUNCPTR(vkd3d_shader_free_scan_descriptor_info)
127 LOAD_FUNCPTR(vkd3d_shader_free_shader_code)
128 LOAD_FUNCPTR(vkd3d_shader_get_version)
129 LOAD_FUNCPTR(vkd3d_shader_scan)
130 #undef LOAD_FUNCPTR
132 return true;
135 static void wined3d_unload_vkd3d_shader(void)
137 if (vkd3d_shader_handle)
139 dlclose(vkd3d_shader_handle);
140 vkd3d_shader_handle = NULL;
144 static BOOL WINAPI wined3d_init_vkd3d_once(INIT_ONCE *once, void *param, void **context)
146 TRACE("Loading vkd3d-shader %s.\n", SONAME_LIBVKD3D_SHADER);
148 if ((vkd3d_shader_handle = dlopen(SONAME_LIBVKD3D_SHADER, RTLD_NOW)))
150 if (!wined3d_load_vkd3d_shader_functions(vkd3d_shader_handle))
152 ERR_(winediag)("Failed to load libvkd3d-shader functions.\n");
153 wined3d_unload_vkd3d_shader();
155 TRACE("Using %s.\n", vkd3d_shader_get_version(NULL, NULL));
157 else
159 ERR_(winediag)("Failed to load libvkd3d-shader.\n");
162 return TRUE;
165 static bool wined3d_init_vkd3d(void)
167 static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
168 InitOnceExecuteOnce(&init_once, wined3d_init_vkd3d_once, NULL, NULL);
169 return !!vkd3d_shader_handle;
172 static enum vkd3d_shader_visibility vkd3d_shader_visibility_from_wined3d(enum wined3d_shader_type shader_type)
174 switch (shader_type)
176 case WINED3D_SHADER_TYPE_VERTEX:
177 return VKD3D_SHADER_VISIBILITY_VERTEX;
178 case WINED3D_SHADER_TYPE_HULL:
179 return VKD3D_SHADER_VISIBILITY_HULL;
180 case WINED3D_SHADER_TYPE_DOMAIN:
181 return VKD3D_SHADER_VISIBILITY_DOMAIN;
182 case WINED3D_SHADER_TYPE_GEOMETRY:
183 return VKD3D_SHADER_VISIBILITY_GEOMETRY;
184 case WINED3D_SHADER_TYPE_PIXEL:
185 return VKD3D_SHADER_VISIBILITY_PIXEL;
186 case WINED3D_SHADER_TYPE_COMPUTE:
187 return VKD3D_SHADER_VISIBILITY_COMPUTE;
188 default:
189 ERR("Invalid shader type %s.\n", debug_shader_type(shader_type));
190 return VKD3D_SHADER_VISIBILITY_ALL;
194 static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction *ins)
198 static void shader_spirv_compile_arguments_init(struct shader_spirv_compile_arguments *args,
199 const struct wined3d_context *context, const struct wined3d_shader *shader,
200 const struct wined3d_state *state, unsigned int sample_count)
202 struct wined3d_rendertarget_view *rtv;
203 unsigned int i;
205 memset(args, 0, sizeof(*args));
207 switch (shader->reg_maps.shader_version.type)
209 case WINED3D_SHADER_TYPE_PIXEL:
210 for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
212 if (!(rtv = state->fb.render_targets[i]) || rtv->format->id == WINED3DFMT_NULL)
213 continue;
214 if (rtv->format->id == WINED3DFMT_A8_UNORM && !is_identity_fixup(rtv->format->color_fixup))
215 args->u.fs.alpha_swizzle |= 1u << i;
217 args->u.fs.sample_count = sample_count;
218 break;
220 default:
221 break;
225 static void shader_spirv_init_compile_args(struct wined3d_shader_spirv_compile_args *args,
226 struct vkd3d_shader_interface_info *vkd3d_interface, enum vkd3d_shader_spirv_environment environment,
227 enum wined3d_shader_type shader_type, const struct shader_spirv_compile_arguments *compile_args)
229 unsigned int i;
231 memset(args, 0, sizeof(*args));
232 args->spirv_target.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO;
233 args->spirv_target.next = vkd3d_interface;
234 args->spirv_target.entry_point = "main";
235 args->spirv_target.environment = environment;
237 if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
239 unsigned int rt_alpha_swizzle = compile_args->u.fs.alpha_swizzle;
240 struct vkd3d_shader_parameter *shader_parameter;
242 shader_parameter = &args->sample_count;
243 shader_parameter->name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT;
244 shader_parameter->type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
245 shader_parameter->data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
246 shader_parameter->u.immediate_constant.u.u32 = compile_args->u.fs.sample_count;
248 args->spirv_target.parameter_count = 1;
249 args->spirv_target.parameters = shader_parameter;
251 for (i = 0; i < ARRAY_SIZE(args->ps_alpha_swizzle); ++i)
253 if (rt_alpha_swizzle && (1u << i))
254 args->ps_alpha_swizzle[i] = VKD3D_SHADER_SWIZZLE(W, X, Y, Z);
255 else
256 args->ps_alpha_swizzle[i] = VKD3D_SHADER_NO_SWIZZLE;
259 args->spirv_target.output_swizzles = args->ps_alpha_swizzle;
260 args->spirv_target.output_swizzle_count = ARRAY_SIZE(args->ps_alpha_swizzle);
264 static const char *get_line(const char **ptr)
266 const char *p, *q;
268 p = *ptr;
269 if (!(q = strstr(p, "\n")))
271 if (!*p) return NULL;
272 *ptr += strlen(p);
273 return p;
275 *ptr = q + 1;
277 return p;
280 static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_shader_interface *iface,
281 struct wined3d_shader *shader, const struct shader_spirv_resource_bindings *b,
282 const struct wined3d_stream_output_desc *so_desc)
284 memset(iface, 0, sizeof(*iface));
285 iface->vkd3d_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
287 if (so_desc)
289 iface->xfb_info.type = VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO;
290 iface->xfb_info.next = NULL;
292 iface->xfb_info.elements = (const struct vkd3d_shader_transform_feedback_element *)so_desc->elements;
293 iface->xfb_info.element_count = so_desc->element_count;
294 iface->xfb_info.buffer_strides = so_desc->buffer_strides;
295 iface->xfb_info.buffer_stride_count = so_desc->buffer_stride_count;
297 iface->vkd3d_interface.next = &iface->xfb_info;
300 iface->vkd3d_interface.bindings = b->bindings;
301 iface->vkd3d_interface.binding_count = b->binding_count;
303 iface->vkd3d_interface.uav_counters = b->uav_counters;
304 iface->vkd3d_interface.uav_counter_count = b->uav_counter_count;
307 static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk,
308 struct wined3d_shader *shader, const struct shader_spirv_compile_arguments *args,
309 const struct shader_spirv_resource_bindings *bindings, const struct wined3d_stream_output_desc *so_desc)
311 struct wined3d_shader_spirv_compile_args compile_args;
312 struct wined3d_shader_spirv_shader_interface iface;
313 struct vkd3d_shader_compile_info info;
314 const struct wined3d_vk_info *vk_info;
315 enum wined3d_shader_type shader_type;
316 VkShaderModuleCreateInfo shader_desc;
317 struct wined3d_device_vk *device_vk;
318 struct vkd3d_shader_code spirv;
319 VkShaderModule module;
320 char *messages;
321 VkResult vr;
322 int ret;
324 shader_spirv_init_shader_interface_vk(&iface, shader, bindings, so_desc);
325 shader_type = shader->reg_maps.shader_version.type;
326 shader_spirv_init_compile_args(&compile_args, &iface.vkd3d_interface,
327 VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, shader_type, args);
329 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
330 info.next = &compile_args.spirv_target;
331 info.source.code = shader->byte_code;
332 info.source.size = shader->byte_code_size;
333 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
334 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
335 info.options = NULL;
336 info.option_count = 0;
337 info.log_level = VKD3D_SHADER_LOG_WARNING;
338 info.source_name = NULL;
340 ret = vkd3d_shader_compile(&info, &spirv, &messages);
341 if (messages && *messages && FIXME_ON(d3d_shader))
343 const char *ptr = messages;
344 const char *line;
346 FIXME("Shader log:\n");
347 while ((line = get_line(&ptr)))
349 FIXME(" %.*s", (int)(ptr - line), line);
351 FIXME("\n");
353 vkd3d_shader_free_messages(messages);
355 if (ret < 0)
357 ERR("Failed to compile DXBC, ret %d.\n", ret);
358 return VK_NULL_HANDLE;
361 device_vk = wined3d_device_vk(context_vk->c.device);
362 vk_info = &device_vk->vk_info;
364 shader_desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
365 shader_desc.pNext = NULL;
366 shader_desc.flags = 0;
367 shader_desc.codeSize = spirv.size;
368 shader_desc.pCode = spirv.code;
369 if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_desc, NULL, &module))) < 0)
371 vkd3d_shader_free_shader_code(&spirv);
372 WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr));
373 return VK_NULL_HANDLE;
376 vkd3d_shader_free_shader_code(&spirv);
378 return module;
381 static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphics_program_variant_vk(
382 struct shader_spirv_priv *priv, struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
383 const struct wined3d_state *state, const struct shader_spirv_resource_bindings *bindings)
385 enum wined3d_shader_type shader_type = shader->reg_maps.shader_version.type;
386 struct shader_spirv_graphics_program_variant_vk *variant_vk;
387 size_t binding_base = bindings->binding_base[shader_type];
388 const struct wined3d_stream_output_desc *so_desc = NULL;
389 struct shader_spirv_graphics_program_vk *program_vk;
390 struct shader_spirv_compile_arguments args;
391 size_t variant_count, i;
393 shader_spirv_compile_arguments_init(&args, &context_vk->c, shader, state, context_vk->sample_count);
394 if (bindings->so_stage == shader_type)
395 so_desc = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->u.gs.so_desc;
397 if (!(program_vk = shader->backend_data))
398 return NULL;
400 variant_count = program_vk->variant_count;
401 for (i = 0; i < variant_count; ++i)
403 variant_vk = &program_vk->variants[i];
404 if (variant_vk->so_desc == so_desc && variant_vk->binding_base == binding_base
405 && !memcmp(&variant_vk->compile_args, &args, sizeof(args)))
406 return variant_vk;
409 if (!wined3d_array_reserve((void **)&program_vk->variants, &program_vk->variants_size,
410 variant_count + 1, sizeof(*program_vk->variants)))
411 return NULL;
413 variant_vk = &program_vk->variants[variant_count];
414 variant_vk->compile_args = args;
415 variant_vk->binding_base = binding_base;
416 if (!(variant_vk->vk_module = shader_spirv_compile(context_vk, shader, &args, bindings, so_desc)))
417 return NULL;
418 ++program_vk->variant_count;
420 return variant_vk;
423 static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program_vk(struct shader_spirv_priv *priv,
424 struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
425 const struct shader_spirv_resource_bindings *bindings)
427 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
428 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
429 struct shader_spirv_compute_program_vk *program;
430 struct wined3d_pipeline_layout_vk *layout;
431 VkComputePipelineCreateInfo pipeline_info;
432 VkResult vr;
434 if (!(program = shader->backend_data))
435 return NULL;
437 if (program->vk_module)
438 return program;
440 if (!(program->vk_module = shader_spirv_compile(context_vk, shader, NULL, bindings, NULL)))
441 return NULL;
443 if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk,
444 bindings->vk_bindings, bindings->vk_binding_count)))
446 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
447 program->vk_module = VK_NULL_HANDLE;
448 return NULL;
450 program->vk_set_layout = layout->vk_set_layout;
451 program->vk_pipeline_layout = layout->vk_pipeline_layout;
453 pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
454 pipeline_info.pNext = NULL;
455 pipeline_info.flags = 0;
456 pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
457 pipeline_info.stage.pNext = NULL;
458 pipeline_info.stage.flags = 0;
459 pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
460 pipeline_info.stage.pName = "main";
461 pipeline_info.stage.pSpecializationInfo = NULL;
462 pipeline_info.stage.module = program->vk_module;
463 pipeline_info.layout = program->vk_pipeline_layout;
464 pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
465 pipeline_info.basePipelineIndex = -1;
466 if ((vr = VK_CALL(vkCreateComputePipelines(device_vk->vk_device,
467 VK_NULL_HANDLE, 1, &pipeline_info, NULL, &program->vk_pipeline))) < 0)
469 ERR("Failed to create Vulkan compute pipeline, vr %s.\n", wined3d_debug_vkresult(vr));
470 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
471 program->vk_module = VK_NULL_HANDLE;
472 return NULL;
475 return program;
478 static void shader_spirv_resource_bindings_cleanup(struct shader_spirv_resource_bindings *bindings)
480 heap_free(bindings->vk_bindings);
481 heap_free(bindings->bindings);
484 static bool shader_spirv_resource_bindings_add_vk_binding(struct shader_spirv_resource_bindings *bindings,
485 VkDescriptorType vk_type, VkShaderStageFlagBits vk_stage, size_t *binding_idx)
487 SIZE_T binding_count = bindings->vk_binding_count;
488 VkDescriptorSetLayoutBinding *binding;
490 if (!wined3d_array_reserve((void **)&bindings->vk_bindings, &bindings->vk_bindings_size,
491 binding_count + 1, sizeof(*bindings->vk_bindings)))
492 return false;
494 *binding_idx = binding_count;
495 binding = &bindings->vk_bindings[binding_count];
496 binding->binding = binding_count;
497 binding->descriptorType = vk_type;
498 binding->descriptorCount = 1;
499 binding->stageFlags = vk_stage;
500 binding->pImmutableSamplers = NULL;
501 ++bindings->vk_binding_count;
503 return true;
506 static bool shader_spirv_resource_bindings_add_binding(struct shader_spirv_resource_bindings *bindings,
507 enum vkd3d_shader_descriptor_type vkd3d_type, VkDescriptorType vk_type, size_t register_idx,
508 enum vkd3d_shader_visibility vkd3d_visibility, VkShaderStageFlagBits vk_stage,
509 uint32_t flags, size_t *binding_idx)
511 SIZE_T binding_count = bindings->binding_count;
512 struct vkd3d_shader_resource_binding *binding;
514 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->bindings_size,
515 binding_count + 1, sizeof(*bindings->bindings)))
516 return false;
518 if (!shader_spirv_resource_bindings_add_vk_binding(bindings, vk_type, vk_stage, binding_idx))
519 return false;
521 binding = &bindings->bindings[binding_count];
522 binding->type = vkd3d_type;
523 binding->register_space = 0;
524 binding->register_index = register_idx;
525 binding->shader_visibility = vkd3d_visibility;
526 binding->flags = flags;
527 binding->binding.set = 0;
528 binding->binding.binding = *binding_idx;
529 binding->binding.count = 1;
530 ++bindings->binding_count;
532 return true;
535 static bool shader_spirv_resource_bindings_add_uav_counter_binding(struct shader_spirv_resource_bindings *bindings,
536 size_t register_idx, enum vkd3d_shader_visibility vkd3d_visibility,
537 VkShaderStageFlagBits vk_stage, size_t *binding_idx)
539 SIZE_T uav_counter_count = bindings->uav_counter_count;
540 struct vkd3d_shader_uav_counter_binding *counter;
542 if (uav_counter_count >= ARRAY_SIZE(bindings->uav_counters))
543 return false;
545 if (!shader_spirv_resource_bindings_add_vk_binding(bindings,
546 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, vk_stage, binding_idx))
547 return false;
549 counter = &bindings->uav_counters[uav_counter_count];
550 counter->register_space = 0;
551 counter->register_index = register_idx;
552 counter->shader_visibility = vkd3d_visibility;
553 counter->binding.set = 0;
554 counter->binding.binding = *binding_idx;
555 counter->binding.count = 1;
556 counter->offset = 0;
557 ++bindings->uav_counter_count;
559 return true;
562 static bool wined3d_shader_resource_bindings_add_binding(struct wined3d_shader_resource_bindings *bindings,
563 enum wined3d_shader_type shader_type, enum wined3d_shader_descriptor_type shader_descriptor_type,
564 size_t resource_idx, enum wined3d_shader_resource_type resource_type,
565 enum wined3d_data_type resource_data_type, size_t binding_idx)
567 struct wined3d_shader_resource_binding *binding;
568 SIZE_T binding_count = bindings->count;
570 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->size,
571 binding_count + 1, sizeof(*bindings->bindings)))
572 return false;
574 binding = &bindings->bindings[binding_count];
575 binding->shader_type = shader_type;
576 binding->shader_descriptor_type = shader_descriptor_type;
577 binding->resource_idx = resource_idx;
578 binding->resource_type = resource_type;
579 binding->resource_data_type = resource_data_type;
580 binding->binding_idx = binding_idx;
581 ++bindings->count;
583 return true;
586 static VkDescriptorType vk_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type,
587 enum vkd3d_shader_resource_type resource_type)
589 switch (type)
591 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
592 return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
594 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
595 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
596 return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
597 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
599 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
600 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
601 return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
602 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
604 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
605 return VK_DESCRIPTOR_TYPE_SAMPLER;
607 default:
608 FIXME("Unhandled descriptor type %#x.\n", type);
609 return ~0u;
613 static enum wined3d_shader_descriptor_type wined3d_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type)
615 switch (type)
617 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
618 return WINED3D_SHADER_DESCRIPTOR_TYPE_CBV;
620 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
621 return WINED3D_SHADER_DESCRIPTOR_TYPE_SRV;
623 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
624 return WINED3D_SHADER_DESCRIPTOR_TYPE_UAV;
626 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
627 return WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
629 default:
630 FIXME("Unhandled descriptor type %#x.\n", type);
631 return ~0u;
635 static enum wined3d_shader_resource_type wined3d_shader_resource_type_from_vkd3d(enum vkd3d_shader_resource_type t)
637 return (enum wined3d_shader_resource_type)t;
640 static enum wined3d_data_type wined3d_data_type_from_vkd3d(enum vkd3d_shader_resource_data_type t)
642 switch (t)
644 case VKD3D_SHADER_RESOURCE_DATA_UNORM:
645 return WINED3D_DATA_UNORM;
646 case VKD3D_SHADER_RESOURCE_DATA_SNORM:
647 return WINED3D_DATA_SNORM;
648 case VKD3D_SHADER_RESOURCE_DATA_INT:
649 return WINED3D_DATA_INT;
650 case VKD3D_SHADER_RESOURCE_DATA_UINT:
651 return WINED3D_DATA_UINT;
652 case VKD3D_SHADER_RESOURCE_DATA_FLOAT:
653 return WINED3D_DATA_FLOAT;
654 default:
655 FIXME("Unhandled resource data type %#x.\n", t);
656 return WINED3D_DATA_FLOAT;
660 static bool shader_spirv_resource_bindings_init(struct shader_spirv_resource_bindings *bindings,
661 struct wined3d_shader_resource_bindings *wined3d_bindings,
662 const struct wined3d_state *state, uint32_t shader_mask)
664 struct vkd3d_shader_scan_descriptor_info *descriptor_info;
665 enum wined3d_shader_descriptor_type wined3d_type;
666 enum vkd3d_shader_visibility shader_visibility;
667 enum wined3d_shader_type shader_type;
668 VkDescriptorType vk_descriptor_type;
669 VkShaderStageFlagBits vk_stage;
670 struct wined3d_shader *shader;
671 size_t binding_idx;
672 unsigned int i;
674 bindings->binding_count = 0;
675 bindings->uav_counter_count = 0;
676 bindings->vk_binding_count = 0;
677 bindings->so_stage = WINED3D_SHADER_TYPE_GEOMETRY;
678 wined3d_bindings->count = 0;
680 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_COUNT; ++shader_type)
682 bindings->binding_base[shader_type] = bindings->vk_binding_count;
684 if (!(shader_mask & (1u << shader_type)) || !(shader = state->shader[shader_type]))
685 continue;
687 if (shader_type == WINED3D_SHADER_TYPE_COMPUTE)
689 descriptor_info = &((struct shader_spirv_compute_program_vk *)shader->backend_data)->descriptor_info;
691 else
693 descriptor_info = &((struct shader_spirv_graphics_program_vk *)shader->backend_data)->descriptor_info;
694 if (shader_type == WINED3D_SHADER_TYPE_GEOMETRY && !shader->function)
695 bindings->so_stage = WINED3D_SHADER_TYPE_VERTEX;
698 vk_stage = vk_shader_stage_from_wined3d(shader_type);
699 shader_visibility = vkd3d_shader_visibility_from_wined3d(shader_type);
701 for (i = 0; i < descriptor_info->descriptor_count; ++i)
703 struct vkd3d_shader_descriptor_info *d = &descriptor_info->descriptors[i];
704 uint32_t flags;
706 if (d->register_space)
708 WARN("Unsupported register space %u.\n", d->register_space);
709 return false;
712 if (d->resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
713 flags = VKD3D_SHADER_BINDING_FLAG_BUFFER;
714 else
715 flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
717 vk_descriptor_type = vk_descriptor_type_from_vkd3d(d->type, d->resource_type);
718 if (!shader_spirv_resource_bindings_add_binding(bindings, d->type, vk_descriptor_type,
719 d->register_index, shader_visibility, vk_stage, flags, &binding_idx))
720 return false;
722 wined3d_type = wined3d_descriptor_type_from_vkd3d(d->type);
723 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings, shader_type,
724 wined3d_type, d->register_index, wined3d_shader_resource_type_from_vkd3d(d->resource_type),
725 wined3d_data_type_from_vkd3d(d->resource_data_type), binding_idx))
726 return false;
728 if (d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
729 && (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER))
731 if (!shader_spirv_resource_bindings_add_uav_counter_binding(bindings,
732 d->register_index, shader_visibility, vk_stage, &binding_idx))
733 return false;
734 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings,
735 shader_type, WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER, d->register_index,
736 WINED3D_SHADER_RESOURCE_BUFFER, WINED3D_DATA_UINT, binding_idx))
737 return false;
742 return true;
745 static void shader_spirv_scan_shader(struct wined3d_shader *shader,
746 struct vkd3d_shader_scan_descriptor_info *descriptor_info)
748 struct vkd3d_shader_compile_info info;
749 char *messages;
750 int ret;
752 memset(descriptor_info, 0, sizeof(*descriptor_info));
753 descriptor_info->type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
755 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
756 info.next = descriptor_info;
757 info.source.code = shader->byte_code;
758 info.source.size = shader->byte_code_size;
759 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
760 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
761 info.options = NULL;
762 info.option_count = 0;
763 info.log_level = VKD3D_SHADER_LOG_WARNING;
764 info.source_name = NULL;
766 if ((ret = vkd3d_shader_scan(&info, &messages)) < 0)
767 ERR("Failed to scan shader, ret %d.\n", ret);
768 if (messages && *messages && FIXME_ON(d3d_shader))
770 const char *ptr = messages;
771 const char *line;
773 FIXME("Shader log:\n");
774 while ((line = get_line(&ptr)))
776 FIXME(" %.*s", (int)(ptr - line), line);
778 FIXME("\n");
780 vkd3d_shader_free_messages(messages);
783 static void shader_spirv_precompile_compute(struct wined3d_shader *shader)
785 struct shader_spirv_compute_program_vk *program_vk;
787 if (!(program_vk = shader->backend_data))
789 if (!(program_vk = heap_alloc_zero(sizeof(*program_vk))))
790 ERR("Failed to allocate program.\n");
791 shader->backend_data = program_vk;
794 shader_spirv_scan_shader(shader, &program_vk->descriptor_info);
797 static void shader_spirv_precompile(void *shader_priv, struct wined3d_shader *shader)
799 struct shader_spirv_graphics_program_vk *program_vk;
801 TRACE("shader_priv %p, shader %p.\n", shader_priv, shader);
803 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
805 shader_spirv_precompile_compute(shader);
806 return;
809 if (!(program_vk = shader->backend_data))
811 if (!(program_vk = heap_alloc_zero(sizeof(*program_vk))))
812 ERR("Failed to allocate program.\n");
813 shader->backend_data = program_vk;
816 shader_spirv_scan_shader(shader, &program_vk->descriptor_info);
819 static void shader_spirv_select(void *shader_priv, struct wined3d_context *context,
820 const struct wined3d_state *state)
822 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
823 struct shader_spirv_graphics_program_variant_vk *variant_vk;
824 struct shader_spirv_resource_bindings *bindings;
825 size_t binding_base[WINED3D_SHADER_TYPE_COUNT];
826 struct wined3d_pipeline_layout_vk *layout_vk;
827 struct shader_spirv_priv *priv = shader_priv;
828 enum wined3d_shader_type shader_type;
829 struct wined3d_shader *shader;
831 priv->vertex_pipe->vp_enable(context, !use_vs(state));
832 priv->fragment_pipe->fp_enable(context, !use_ps(state));
834 bindings = &priv->bindings;
835 memcpy(binding_base, bindings->binding_base, sizeof(bindings->binding_base));
836 if (!shader_spirv_resource_bindings_init(bindings, &context_vk->graphics.bindings,
837 state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)))
839 ERR("Failed to initialise shader resource bindings.\n");
840 goto fail;
842 if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY))
843 context->shader_update_mask |= 1u << bindings->so_stage;
845 layout_vk = wined3d_context_vk_get_pipeline_layout(context_vk, bindings->vk_bindings, bindings->vk_binding_count);
846 context_vk->graphics.vk_set_layout = layout_vk->vk_set_layout;
847 context_vk->graphics.vk_pipeline_layout = layout_vk->vk_pipeline_layout;
849 for (shader_type = 0; shader_type < ARRAY_SIZE(context_vk->graphics.vk_modules); ++shader_type)
851 if (!(context->shader_update_mask & (1u << shader_type)) && (!context_vk->graphics.vk_modules[shader_type]
852 || binding_base[shader_type] == bindings->binding_base[shader_type]))
853 continue;
855 if (!(shader = state->shader[shader_type]) || !shader->function)
857 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
858 continue;
861 if (!(variant_vk = shader_spirv_find_graphics_program_variant_vk(priv, context_vk, shader, state, bindings)))
862 goto fail;
863 context_vk->graphics.vk_modules[shader_type] = variant_vk->vk_module;
866 return;
868 fail:
869 context_vk->graphics.vk_set_layout = VK_NULL_HANDLE;
870 context_vk->graphics.vk_pipeline_layout = VK_NULL_HANDLE;
873 static void shader_spirv_select_compute(void *shader_priv,
874 struct wined3d_context *context, const struct wined3d_state *state)
876 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
877 struct shader_spirv_compute_program_vk *program;
878 struct shader_spirv_priv *priv = shader_priv;
879 struct wined3d_shader *shader;
881 if (!shader_spirv_resource_bindings_init(&priv->bindings,
882 &context_vk->compute.bindings, state, 1u << WINED3D_SHADER_TYPE_COMPUTE))
883 ERR("Failed to initialise shader resource bindings.\n");
885 if ((shader = state->shader[WINED3D_SHADER_TYPE_COMPUTE]))
886 program = shader_spirv_find_compute_program_vk(priv, context_vk, shader, &priv->bindings);
887 else
888 program = NULL;
890 if (program)
892 context_vk->compute.vk_pipeline = program->vk_pipeline;
893 context_vk->compute.vk_set_layout = program->vk_set_layout;
894 context_vk->compute.vk_pipeline_layout = program->vk_pipeline_layout;
896 else
898 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
899 context_vk->compute.vk_set_layout = VK_NULL_HANDLE;
900 context_vk->compute.vk_pipeline_layout = VK_NULL_HANDLE;
904 static void shader_spirv_disable(void *shader_priv, struct wined3d_context *context)
906 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
907 struct shader_spirv_priv *priv = shader_priv;
909 priv->vertex_pipe->vp_enable(context, false);
910 priv->fragment_pipe->fp_enable(context, false);
912 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
913 context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
914 | (1u << WINED3D_SHADER_TYPE_VERTEX)
915 | (1u << WINED3D_SHADER_TYPE_GEOMETRY)
916 | (1u << WINED3D_SHADER_TYPE_HULL)
917 | (1u << WINED3D_SHADER_TYPE_DOMAIN)
918 | (1u << WINED3D_SHADER_TYPE_COMPUTE);
921 static void shader_spirv_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
923 WARN("Not implemented.\n");
926 static void shader_spirv_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
928 WARN("Not implemented.\n");
931 static void shader_spirv_load_constants(void *shader_priv, struct wined3d_context *context,
932 const struct wined3d_state *state)
934 WARN("Not implemented.\n");
937 static void shader_spirv_invalidate_compute_program(struct wined3d_context_vk *context_vk,
938 const struct shader_spirv_compute_program_vk *program)
940 if (context_vk->compute.vk_pipeline == program->vk_pipeline)
942 context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE);
943 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
947 static void shader_spirv_invalidate_contexts_compute_program(struct wined3d_device *device,
948 const struct shader_spirv_compute_program_vk *program)
950 unsigned int i;
952 for (i = 0; i < device->context_count; ++i)
954 shader_spirv_invalidate_compute_program(wined3d_context_vk(device->contexts[i]), program);
958 static void shader_spirv_invalidate_graphics_program_variant(struct wined3d_context_vk *context_vk,
959 const struct shader_spirv_graphics_program_variant_vk *variant)
961 enum wined3d_shader_type shader_type;
963 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++shader_type)
965 if (context_vk->graphics.vk_modules[shader_type] != variant->vk_module)
966 continue;
968 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
969 context_vk->c.shader_update_mask |= (1u << shader_type);
973 static void shader_spirv_invalidate_contexts_graphics_program_variant(struct wined3d_device *device,
974 const struct shader_spirv_graphics_program_variant_vk *variant)
976 unsigned int i;
978 for (i = 0; i < device->context_count; ++i)
980 shader_spirv_invalidate_graphics_program_variant(wined3d_context_vk(device->contexts[i]), variant);
984 static void shader_spirv_destroy_compute_vk(struct wined3d_shader *shader)
986 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
987 struct shader_spirv_compute_program_vk *program = shader->backend_data;
988 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
990 shader_spirv_invalidate_contexts_compute_program(&device_vk->d, program);
991 VK_CALL(vkDestroyPipeline(device_vk->vk_device, program->vk_pipeline, NULL));
992 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
993 vkd3d_shader_free_scan_descriptor_info(&program->descriptor_info);
994 shader->backend_data = NULL;
995 heap_free(program);
998 static void shader_spirv_destroy(struct wined3d_shader *shader)
1000 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
1001 struct shader_spirv_graphics_program_variant_vk *variant_vk;
1002 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
1003 struct shader_spirv_graphics_program_vk *program_vk;
1004 size_t i;
1006 if (!shader->backend_data)
1007 return;
1009 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
1011 shader_spirv_destroy_compute_vk(shader);
1012 return;
1015 program_vk = shader->backend_data;
1016 for (i = 0; i < program_vk->variant_count; ++i)
1018 variant_vk = &program_vk->variants[i];
1019 shader_spirv_invalidate_contexts_graphics_program_variant(&device_vk->d, variant_vk);
1020 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, variant_vk->vk_module, NULL));
1022 heap_free(program_vk->variants);
1023 vkd3d_shader_free_scan_descriptor_info(&program_vk->descriptor_info);
1025 shader->backend_data = NULL;
1026 heap_free(program_vk);
1029 static HRESULT shader_spirv_alloc(struct wined3d_device *device,
1030 const struct wined3d_vertex_pipe_ops *vertex_pipe, const struct wined3d_fragment_pipe_ops *fragment_pipe)
1032 struct fragment_caps fragment_caps;
1033 void *vertex_priv, *fragment_priv;
1034 struct shader_spirv_priv *priv;
1036 if (!(priv = heap_alloc(sizeof(*priv))))
1037 return E_OUTOFMEMORY;
1039 if (!(vertex_priv = vertex_pipe->vp_alloc(&spirv_shader_backend_vk, priv)))
1041 ERR("Failed to initialise vertex pipe.\n");
1042 heap_free(priv);
1043 return E_FAIL;
1046 if (!(fragment_priv = fragment_pipe->alloc_private(&spirv_shader_backend_vk, priv)))
1048 ERR("Failed to initialise fragment pipe.\n");
1049 vertex_pipe->vp_free(device, NULL);
1050 heap_free(priv);
1051 return E_FAIL;
1054 priv->vertex_pipe = vertex_pipe;
1055 priv->fragment_pipe = fragment_pipe;
1056 fragment_pipe->get_caps(device->adapter, &fragment_caps);
1057 priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
1058 memset(&priv->bindings, 0, sizeof(priv->bindings));
1060 device->vertex_priv = vertex_priv;
1061 device->fragment_priv = fragment_priv;
1062 device->shader_priv = priv;
1064 return WINED3D_OK;
1067 static void shader_spirv_free(struct wined3d_device *device, struct wined3d_context *context)
1069 struct shader_spirv_priv *priv = device->shader_priv;
1071 shader_spirv_resource_bindings_cleanup(&priv->bindings);
1072 priv->fragment_pipe->free_private(device, context);
1073 priv->vertex_pipe->vp_free(device, context);
1074 heap_free(priv);
1077 static BOOL shader_spirv_allocate_context_data(struct wined3d_context *context)
1079 return TRUE;
1082 static void shader_spirv_free_context_data(struct wined3d_context *context)
1086 static void shader_spirv_init_context_state(struct wined3d_context *context)
1090 static void shader_spirv_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps)
1092 caps->vs_version = min(wined3d_settings.max_sm_vs, 5);
1093 caps->hs_version = min(wined3d_settings.max_sm_hs, 5);
1094 caps->ds_version = min(wined3d_settings.max_sm_ds, 5);
1095 caps->gs_version = min(wined3d_settings.max_sm_gs, 5);
1096 caps->ps_version = min(wined3d_settings.max_sm_ps, 5);
1097 caps->cs_version = min(wined3d_settings.max_sm_cs, 5);
1099 caps->vs_uniform_count = WINED3D_MAX_VS_CONSTS_F;
1100 caps->ps_uniform_count = WINED3D_MAX_PS_CONSTS_F;
1101 caps->ps_1x_max_value = FLT_MAX;
1102 caps->varying_count = 0;
1103 caps->wined3d_caps = WINED3D_SHADER_CAP_VS_CLIPPING
1104 | WINED3D_SHADER_CAP_SRGB_WRITE
1105 | WINED3D_SHADER_CAP_FULL_FFP_VARYINGS;
1108 static BOOL shader_spirv_color_fixup_supported(struct color_fixup_desc fixup)
1110 return is_identity_fixup(fixup);
1113 static BOOL shader_spirv_has_ffp_proj_control(void *shader_priv)
1115 struct shader_spirv_priv *priv = shader_priv;
1117 return priv->ffp_proj_control;
1120 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk =
1122 .shader_handle_instruction = shader_spirv_handle_instruction,
1123 .shader_precompile = shader_spirv_precompile,
1124 .shader_select = shader_spirv_select,
1125 .shader_select_compute = shader_spirv_select_compute,
1126 .shader_disable = shader_spirv_disable,
1127 .shader_update_float_vertex_constants = shader_spirv_update_float_vertex_constants,
1128 .shader_update_float_pixel_constants = shader_spirv_update_float_pixel_constants,
1129 .shader_load_constants = shader_spirv_load_constants,
1130 .shader_destroy = shader_spirv_destroy,
1131 .shader_alloc_private = shader_spirv_alloc,
1132 .shader_free_private = shader_spirv_free,
1133 .shader_allocate_context_data = shader_spirv_allocate_context_data,
1134 .shader_free_context_data = shader_spirv_free_context_data,
1135 .shader_init_context_state = shader_spirv_init_context_state,
1136 .shader_get_caps = shader_spirv_get_caps,
1137 .shader_color_fixup_supported = shader_spirv_color_fixup_supported,
1138 .shader_has_ffp_proj_control = shader_spirv_has_ffp_proj_control,
1141 const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(void)
1143 if (!wined3d_init_vkd3d())
1144 return NULL;
1146 return &spirv_shader_backend_vk;
1149 void wined3d_spirv_shader_backend_cleanup(void)
1151 wined3d_unload_vkd3d_shader();
1154 static void spirv_vertex_pipe_vk_vp_enable(const struct wined3d_context *context, BOOL enable)
1156 /* Nothing to do. */
1159 static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps)
1161 memset(caps, 0, sizeof(*caps));
1164 static uint32_t spirv_vertex_pipe_vk_vp_get_emul_mask(const struct wined3d_gl_info *gl_info)
1166 return 0;
1169 static void *spirv_vertex_pipe_vk_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1171 if (shader_backend != &spirv_shader_backend_vk)
1173 FIXME("SPIR-V vertex pipe without SPIR-V shader backend not implemented.\n");
1174 return NULL;
1177 return shader_priv;
1180 static void spirv_vertex_pipe_vk_vp_free(struct wined3d_device *device, struct wined3d_context *context)
1182 /* Nothing to do. */
1185 static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states[] =
1187 {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), state_nop}},
1188 {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_nop}},
1189 {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_RENDER(WINED3D_RS_LIGHTING), state_nop}},
1190 {STATE_RENDER(WINED3D_RS_AMBIENT), {STATE_RENDER(WINED3D_RS_AMBIENT), state_nop}},
1191 {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_RENDER(WINED3D_RS_COLORVERTEX), state_nop}},
1192 {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_nop}},
1193 {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_nop}},
1194 {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), state_nop}},
1195 {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), state_nop}},
1196 {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), state_nop}},
1197 {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), state_nop}},
1198 {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_nop}},
1199 {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), state_nop}},
1200 {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSIZE), state_nop}},
1201 {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_nop}},
1202 {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_nop}},
1203 {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALE_A), state_nop}},
1204 {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALE_B), state_nop}},
1205 {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALE_C), state_nop}},
1206 {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), state_nop}},
1207 {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), state_nop}},
1208 {STATE_RENDER(WINED3D_RS_TWEENFACTOR), {STATE_RENDER(WINED3D_RS_TWEENFACTOR), state_nop}},
1209 {STATE_MATERIAL, {STATE_MATERIAL, state_nop}},
1210 {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), state_nop}},
1211 {STATE_LIGHT_TYPE, {STATE_LIGHT_TYPE, state_nop}},
1212 {0}, /* Terminate */
1215 static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk =
1217 .vp_enable = spirv_vertex_pipe_vk_vp_enable,
1218 .vp_get_caps = spirv_vertex_pipe_vk_vp_get_caps,
1219 .vp_get_emul_mask = spirv_vertex_pipe_vk_vp_get_emul_mask,
1220 .vp_alloc = spirv_vertex_pipe_vk_vp_alloc,
1221 .vp_free = spirv_vertex_pipe_vk_vp_free,
1222 .vp_states = spirv_vertex_pipe_vk_vp_states,
1225 const struct wined3d_vertex_pipe_ops *wined3d_spirv_vertex_pipe_init_vk(void)
1227 return &spirv_vertex_pipe_vk;
1230 static void spirv_fragment_pipe_vk_fp_enable(const struct wined3d_context *context, BOOL enable)
1232 /* Nothing to do. */
1235 static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps)
1237 memset(caps, 0, sizeof(*caps));
1240 static uint32_t spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_gl_info *gl_info)
1242 return 0;
1245 static void *spirv_fragment_pipe_vk_fp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1247 if (shader_backend != &spirv_shader_backend_vk)
1249 FIXME("SPIR-V fragment pipe without SPIR-V shader backend not implemented.\n");
1250 return NULL;
1253 return shader_priv;
1256 static void spirv_fragment_pipe_vk_fp_free(struct wined3d_device *device, struct wined3d_context *context)
1258 /* Nothing to do. */
1261 static BOOL spirv_fragment_pipe_vk_fp_alloc_context_data(struct wined3d_context *context)
1263 return TRUE;
1266 static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context *context)
1268 /* Nothing to do. */
1271 static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states[] =
1273 {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_nop}},
1274 {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_nop}},
1275 {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHAREF), state_nop}},
1276 {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), state_nop}},
1277 {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}},
1278 {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_nop}},
1279 {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_nop}},
1280 {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), state_nop}},
1281 {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_nop}},
1282 {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGEND), state_nop}},
1283 {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_nop}},
1284 {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop}},
1285 {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_nop}},
1286 {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}},
1287 {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}},
1288 {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}},
1289 {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, state_nop}},
1290 {STATE_COLOR_KEY, {STATE_COLOR_KEY, state_nop}},
1291 {0}, /* Terminate */
1294 static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk =
1296 .fp_enable = spirv_fragment_pipe_vk_fp_enable,
1297 .get_caps = spirv_fragment_pipe_vk_fp_get_caps,
1298 .get_emul_mask = spirv_fragment_pipe_vk_fp_get_emul_mask,
1299 .alloc_private = spirv_fragment_pipe_vk_fp_alloc,
1300 .free_private = spirv_fragment_pipe_vk_fp_free,
1301 .allocate_context_data = spirv_fragment_pipe_vk_fp_alloc_context_data,
1302 .free_context_data = spirv_fragment_pipe_vk_fp_free_context_data,
1303 .color_fixup_supported = shader_spirv_color_fixup_supported,
1304 .states = spirv_fragment_pipe_vk_fp_states,
1307 const struct wined3d_fragment_pipe_ops *wined3d_spirv_fragment_pipe_init_vk(void)
1309 return &spirv_fragment_pipe_vk;
1312 #else
1314 const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(void)
1316 ERR_(winediag)("Wine was built without libvkd3d-shader support.\n");
1317 return NULL;
1320 void wined3d_spirv_shader_backend_cleanup(void)
1324 const struct wined3d_vertex_pipe_ops *wined3d_spirv_vertex_pipe_init_vk(void)
1326 return &none_vertex_pipe;
1329 const struct wined3d_fragment_pipe_ops *wined3d_spirv_fragment_pipe_init_vk(void)
1331 return &none_fragment_pipe;
1334 #endif /* defined(SONAME_LIBVKD3D_SHADER) */