mf/tests: Test input type for WMA decoder DMO.
[wine.git] / dlls / wined3d / shader_spirv.c
blobad0a8f1b3e8f71c6945e4023f50f2c0737b2f5c2
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"
22 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
24 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk;
26 static const struct vkd3d_shader_compile_option spirv_compile_options[] =
28 {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_7},
29 {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0},
32 struct shader_spirv_resource_bindings
34 struct vkd3d_shader_resource_binding *bindings;
35 SIZE_T bindings_size, binding_count;
37 struct vkd3d_shader_uav_counter_binding uav_counters[MAX_UNORDERED_ACCESS_VIEWS];
38 SIZE_T uav_counter_count;
40 VkDescriptorSetLayoutBinding *vk_bindings;
41 SIZE_T vk_bindings_size, vk_binding_count;
43 size_t binding_base[WINED3D_SHADER_TYPE_COUNT];
44 enum wined3d_shader_type so_stage;
47 struct shader_spirv_priv
49 const struct wined3d_vertex_pipe_ops *vertex_pipe;
50 const struct wined3d_fragment_pipe_ops *fragment_pipe;
51 bool ffp_proj_control;
53 struct shader_spirv_resource_bindings bindings;
56 struct shader_spirv_compile_arguments
58 union
60 struct
62 uint32_t alpha_swizzle;
63 unsigned int sample_count;
64 bool dual_source_blending;
65 } fs;
66 } u;
69 struct shader_spirv_graphics_program_variant_vk
71 struct shader_spirv_compile_arguments compile_args;
72 const struct wined3d_stream_output_desc *so_desc;
73 size_t binding_base;
75 VkShaderModule vk_module;
78 struct shader_spirv_graphics_program_vk
80 struct shader_spirv_graphics_program_variant_vk *variants;
81 SIZE_T variants_size, variant_count;
83 struct vkd3d_shader_scan_descriptor_info descriptor_info;
86 struct shader_spirv_compute_program_vk
88 VkShaderModule vk_module;
89 VkPipeline vk_pipeline;
90 VkPipelineLayout vk_pipeline_layout;
91 VkDescriptorSetLayout vk_set_layout;
93 struct vkd3d_shader_scan_descriptor_info descriptor_info;
96 struct wined3d_shader_spirv_compile_args
98 struct vkd3d_shader_spirv_target_info spirv_target;
99 struct vkd3d_shader_parameter sample_count;
100 unsigned int ps_alpha_swizzle[WINED3D_MAX_RENDER_TARGETS];
103 struct wined3d_shader_spirv_shader_interface
105 struct vkd3d_shader_interface_info vkd3d_interface;
106 struct vkd3d_shader_transform_feedback_info xfb_info;
109 static enum vkd3d_shader_visibility vkd3d_shader_visibility_from_wined3d(enum wined3d_shader_type shader_type)
111 switch (shader_type)
113 case WINED3D_SHADER_TYPE_VERTEX:
114 return VKD3D_SHADER_VISIBILITY_VERTEX;
115 case WINED3D_SHADER_TYPE_HULL:
116 return VKD3D_SHADER_VISIBILITY_HULL;
117 case WINED3D_SHADER_TYPE_DOMAIN:
118 return VKD3D_SHADER_VISIBILITY_DOMAIN;
119 case WINED3D_SHADER_TYPE_GEOMETRY:
120 return VKD3D_SHADER_VISIBILITY_GEOMETRY;
121 case WINED3D_SHADER_TYPE_PIXEL:
122 return VKD3D_SHADER_VISIBILITY_PIXEL;
123 case WINED3D_SHADER_TYPE_COMPUTE:
124 return VKD3D_SHADER_VISIBILITY_COMPUTE;
125 default:
126 ERR("Invalid shader type %s.\n", debug_shader_type(shader_type));
127 return VKD3D_SHADER_VISIBILITY_ALL;
131 static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction *ins)
135 static void shader_spirv_compile_arguments_init(struct shader_spirv_compile_arguments *args,
136 const struct wined3d_context *context, const struct wined3d_shader *shader,
137 const struct wined3d_state *state, unsigned int sample_count)
139 struct wined3d_rendertarget_view *rtv;
140 unsigned int i;
142 memset(args, 0, sizeof(*args));
144 switch (shader->reg_maps.shader_version.type)
146 case WINED3D_SHADER_TYPE_PIXEL:
147 for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
149 if (!(rtv = state->fb.render_targets[i]) || rtv->format->id == WINED3DFMT_NULL)
150 continue;
151 if (rtv->format->id == WINED3DFMT_A8_UNORM && !is_identity_fixup(rtv->format->color_fixup))
152 args->u.fs.alpha_swizzle |= 1u << i;
154 args->u.fs.sample_count = sample_count;
155 args->u.fs.dual_source_blending = state->blend_state && state->blend_state->dual_source;
156 break;
158 default:
159 break;
163 static void shader_spirv_init_compile_args(struct wined3d_shader_spirv_compile_args *args,
164 struct vkd3d_shader_interface_info *vkd3d_interface, enum vkd3d_shader_spirv_environment environment,
165 enum wined3d_shader_type shader_type, const struct shader_spirv_compile_arguments *compile_args)
167 unsigned int i;
169 memset(args, 0, sizeof(*args));
170 args->spirv_target.type = VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO;
171 args->spirv_target.next = vkd3d_interface;
172 args->spirv_target.entry_point = "main";
173 args->spirv_target.environment = environment;
175 if (shader_type == WINED3D_SHADER_TYPE_PIXEL)
177 unsigned int rt_alpha_swizzle = compile_args->u.fs.alpha_swizzle;
178 struct vkd3d_shader_parameter *shader_parameter;
180 shader_parameter = &args->sample_count;
181 shader_parameter->name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT;
182 shader_parameter->type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
183 shader_parameter->data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
184 shader_parameter->u.immediate_constant.u.u32 = compile_args->u.fs.sample_count;
186 args->spirv_target.dual_source_blending = compile_args->u.fs.dual_source_blending;
188 args->spirv_target.parameter_count = 1;
189 args->spirv_target.parameters = shader_parameter;
191 for (i = 0; i < ARRAY_SIZE(args->ps_alpha_swizzle); ++i)
193 if (rt_alpha_swizzle && (1u << i))
194 args->ps_alpha_swizzle[i] = VKD3D_SHADER_SWIZZLE(W, X, Y, Z);
195 else
196 args->ps_alpha_swizzle[i] = VKD3D_SHADER_NO_SWIZZLE;
199 args->spirv_target.output_swizzles = args->ps_alpha_swizzle;
200 args->spirv_target.output_swizzle_count = ARRAY_SIZE(args->ps_alpha_swizzle);
204 static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_shader_interface *iface,
205 const struct shader_spirv_resource_bindings *b, const struct wined3d_stream_output_desc *so_desc)
207 memset(iface, 0, sizeof(*iface));
208 iface->vkd3d_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO;
210 if (so_desc)
212 iface->xfb_info.type = VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO;
213 iface->xfb_info.next = NULL;
215 iface->xfb_info.elements = (const struct vkd3d_shader_transform_feedback_element *)so_desc->elements;
216 iface->xfb_info.element_count = so_desc->element_count;
217 iface->xfb_info.buffer_strides = so_desc->buffer_strides;
218 iface->xfb_info.buffer_stride_count = so_desc->buffer_stride_count;
220 iface->vkd3d_interface.next = &iface->xfb_info;
223 iface->vkd3d_interface.bindings = b->bindings;
224 iface->vkd3d_interface.binding_count = b->binding_count;
226 iface->vkd3d_interface.uav_counters = b->uav_counters;
227 iface->vkd3d_interface.uav_counter_count = b->uav_counter_count;
230 static VkShaderModule shader_spirv_compile_shader(struct wined3d_context_vk *context_vk,
231 const struct wined3d_shader_desc *shader_desc, enum wined3d_shader_type shader_type,
232 const struct shader_spirv_compile_arguments *args, const struct shader_spirv_resource_bindings *bindings,
233 const struct wined3d_stream_output_desc *so_desc)
235 struct wined3d_shader_spirv_compile_args compile_args;
236 struct wined3d_shader_spirv_shader_interface iface;
237 VkShaderModuleCreateInfo shader_create_info;
238 struct vkd3d_shader_compile_info info;
239 const struct wined3d_vk_info *vk_info;
240 struct wined3d_device_vk *device_vk;
241 struct vkd3d_shader_code spirv;
242 VkShaderModule module;
243 char *messages;
244 VkResult vr;
245 int ret;
247 shader_spirv_init_shader_interface_vk(&iface, bindings, so_desc);
248 shader_spirv_init_compile_args(&compile_args, &iface.vkd3d_interface,
249 VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, shader_type, args);
251 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
252 info.next = &compile_args.spirv_target;
253 info.source.code = shader_desc->byte_code;
254 info.source.size = shader_desc->byte_code_size;
255 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
256 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
257 info.options = spirv_compile_options;
258 info.option_count = ARRAY_SIZE(spirv_compile_options);
259 info.log_level = VKD3D_SHADER_LOG_WARNING;
260 info.source_name = NULL;
262 ret = vkd3d_shader_compile(&info, &spirv, &messages);
263 if (messages && *messages && FIXME_ON(d3d_shader))
265 const char *ptr, *end, *line;
267 FIXME("Shader log:\n");
268 ptr = messages;
269 end = ptr + strlen(ptr);
270 while ((line = wined3d_get_line(&ptr, end)))
272 FIXME(" %.*s", (int)(ptr - line), line);
274 FIXME("\n");
276 vkd3d_shader_free_messages(messages);
278 if (ret < 0)
280 ERR("Failed to compile DXBC, ret %d.\n", ret);
281 return VK_NULL_HANDLE;
284 device_vk = wined3d_device_vk(context_vk->c.device);
285 vk_info = &device_vk->vk_info;
287 shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
288 shader_create_info.pNext = NULL;
289 shader_create_info.flags = 0;
290 shader_create_info.codeSize = spirv.size;
291 shader_create_info.pCode = spirv.code;
292 if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_create_info, NULL, &module))) < 0)
294 vkd3d_shader_free_shader_code(&spirv);
295 WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr));
296 return VK_NULL_HANDLE;
299 vkd3d_shader_free_shader_code(&spirv);
301 return module;
304 static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphics_program_variant_vk(
305 struct shader_spirv_priv *priv, struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
306 const struct wined3d_state *state, const struct shader_spirv_resource_bindings *bindings)
308 enum wined3d_shader_type shader_type = shader->reg_maps.shader_version.type;
309 struct shader_spirv_graphics_program_variant_vk *variant_vk;
310 size_t binding_base = bindings->binding_base[shader_type];
311 const struct wined3d_stream_output_desc *so_desc = NULL;
312 struct shader_spirv_graphics_program_vk *program_vk;
313 struct shader_spirv_compile_arguments args;
314 struct wined3d_shader_desc shader_desc;
315 size_t variant_count, i;
317 shader_spirv_compile_arguments_init(&args, &context_vk->c, shader, state, context_vk->sample_count);
318 if (bindings->so_stage == shader_type)
319 so_desc = state->shader[WINED3D_SHADER_TYPE_GEOMETRY]->u.gs.so_desc;
321 if (!(program_vk = shader->backend_data))
322 return NULL;
324 variant_count = program_vk->variant_count;
325 for (i = 0; i < variant_count; ++i)
327 variant_vk = &program_vk->variants[i];
328 if (variant_vk->so_desc == so_desc && variant_vk->binding_base == binding_base
329 && !memcmp(&variant_vk->compile_args, &args, sizeof(args)))
330 return variant_vk;
333 if (!wined3d_array_reserve((void **)&program_vk->variants, &program_vk->variants_size,
334 variant_count + 1, sizeof(*program_vk->variants)))
335 return NULL;
337 variant_vk = &program_vk->variants[variant_count];
338 variant_vk->compile_args = args;
339 variant_vk->binding_base = binding_base;
341 shader_desc.byte_code = shader->byte_code;
342 shader_desc.byte_code_size = shader->byte_code_size;
344 if (!(variant_vk->vk_module = shader_spirv_compile_shader(context_vk, &shader_desc, shader_type, &args,
345 bindings, so_desc)))
346 return NULL;
347 ++program_vk->variant_count;
349 return variant_vk;
352 static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program_vk(struct shader_spirv_priv *priv,
353 struct wined3d_context_vk *context_vk, struct wined3d_shader *shader,
354 const struct shader_spirv_resource_bindings *bindings)
356 struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
357 const struct wined3d_vk_info *vk_info = context_vk->vk_info;
358 struct shader_spirv_compute_program_vk *program;
359 struct wined3d_pipeline_layout_vk *layout;
360 VkComputePipelineCreateInfo pipeline_info;
361 struct wined3d_shader_desc shader_desc;
362 VkResult vr;
364 if (!(program = shader->backend_data))
365 return NULL;
367 if (program->vk_module)
368 return program;
370 shader_desc.byte_code = shader->byte_code;
371 shader_desc.byte_code_size = shader->byte_code_size;
373 if (!(program->vk_module = shader_spirv_compile_shader(context_vk, &shader_desc, WINED3D_SHADER_TYPE_COMPUTE,
374 NULL, bindings, NULL)))
375 return NULL;
377 if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk,
378 bindings->vk_bindings, bindings->vk_binding_count)))
380 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
381 program->vk_module = VK_NULL_HANDLE;
382 return NULL;
384 program->vk_set_layout = layout->vk_set_layout;
385 program->vk_pipeline_layout = layout->vk_pipeline_layout;
387 pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
388 pipeline_info.pNext = NULL;
389 pipeline_info.flags = 0;
390 pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
391 pipeline_info.stage.pNext = NULL;
392 pipeline_info.stage.flags = 0;
393 pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
394 pipeline_info.stage.pName = "main";
395 pipeline_info.stage.pSpecializationInfo = NULL;
396 pipeline_info.stage.module = program->vk_module;
397 pipeline_info.layout = program->vk_pipeline_layout;
398 pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
399 pipeline_info.basePipelineIndex = -1;
400 if ((vr = VK_CALL(vkCreateComputePipelines(device_vk->vk_device,
401 VK_NULL_HANDLE, 1, &pipeline_info, NULL, &program->vk_pipeline))) < 0)
403 ERR("Failed to create Vulkan compute pipeline, vr %s.\n", wined3d_debug_vkresult(vr));
404 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
405 program->vk_module = VK_NULL_HANDLE;
406 return NULL;
409 return program;
412 static void shader_spirv_resource_bindings_cleanup(struct shader_spirv_resource_bindings *bindings)
414 heap_free(bindings->vk_bindings);
415 heap_free(bindings->bindings);
418 static bool shader_spirv_resource_bindings_add_vk_binding(struct shader_spirv_resource_bindings *bindings,
419 VkDescriptorType vk_type, VkShaderStageFlagBits vk_stage, size_t *binding_idx)
421 SIZE_T binding_count = bindings->vk_binding_count;
422 VkDescriptorSetLayoutBinding *binding;
424 if (!wined3d_array_reserve((void **)&bindings->vk_bindings, &bindings->vk_bindings_size,
425 binding_count + 1, sizeof(*bindings->vk_bindings)))
426 return false;
428 *binding_idx = binding_count;
429 binding = &bindings->vk_bindings[binding_count];
430 binding->binding = binding_count;
431 binding->descriptorType = vk_type;
432 binding->descriptorCount = 1;
433 binding->stageFlags = vk_stage;
434 binding->pImmutableSamplers = NULL;
435 ++bindings->vk_binding_count;
437 return true;
440 static bool shader_spirv_resource_bindings_add_binding(struct shader_spirv_resource_bindings *bindings,
441 enum vkd3d_shader_descriptor_type vkd3d_type, VkDescriptorType vk_type, size_t register_idx,
442 enum vkd3d_shader_visibility vkd3d_visibility, VkShaderStageFlagBits vk_stage,
443 uint32_t flags, size_t *binding_idx)
445 SIZE_T binding_count = bindings->binding_count;
446 struct vkd3d_shader_resource_binding *binding;
448 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->bindings_size,
449 binding_count + 1, sizeof(*bindings->bindings)))
450 return false;
452 if (!shader_spirv_resource_bindings_add_vk_binding(bindings, vk_type, vk_stage, binding_idx))
453 return false;
455 binding = &bindings->bindings[binding_count];
456 binding->type = vkd3d_type;
457 binding->register_space = 0;
458 binding->register_index = register_idx;
459 binding->shader_visibility = vkd3d_visibility;
460 binding->flags = flags;
461 binding->binding.set = 0;
462 binding->binding.binding = *binding_idx;
463 binding->binding.count = 1;
464 ++bindings->binding_count;
466 return true;
469 static bool shader_spirv_resource_bindings_add_uav_counter_binding(struct shader_spirv_resource_bindings *bindings,
470 size_t register_idx, enum vkd3d_shader_visibility vkd3d_visibility,
471 VkShaderStageFlagBits vk_stage, size_t *binding_idx)
473 SIZE_T uav_counter_count = bindings->uav_counter_count;
474 struct vkd3d_shader_uav_counter_binding *counter;
476 if (uav_counter_count >= ARRAY_SIZE(bindings->uav_counters))
477 return false;
479 if (!shader_spirv_resource_bindings_add_vk_binding(bindings,
480 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, vk_stage, binding_idx))
481 return false;
483 counter = &bindings->uav_counters[uav_counter_count];
484 counter->register_space = 0;
485 counter->register_index = register_idx;
486 counter->shader_visibility = vkd3d_visibility;
487 counter->binding.set = 0;
488 counter->binding.binding = *binding_idx;
489 counter->binding.count = 1;
490 counter->offset = 0;
491 ++bindings->uav_counter_count;
493 return true;
496 static bool wined3d_shader_resource_bindings_add_binding(struct wined3d_shader_resource_bindings *bindings,
497 enum wined3d_shader_type shader_type, enum wined3d_shader_descriptor_type shader_descriptor_type,
498 size_t resource_idx, enum wined3d_shader_resource_type resource_type,
499 enum wined3d_data_type resource_data_type, size_t binding_idx)
501 struct wined3d_shader_resource_binding *binding;
502 SIZE_T binding_count = bindings->count;
504 if (!wined3d_array_reserve((void **)&bindings->bindings, &bindings->size,
505 binding_count + 1, sizeof(*bindings->bindings)))
506 return false;
508 binding = &bindings->bindings[binding_count];
509 binding->shader_type = shader_type;
510 binding->shader_descriptor_type = shader_descriptor_type;
511 binding->resource_idx = resource_idx;
512 binding->resource_type = resource_type;
513 binding->resource_data_type = resource_data_type;
514 binding->binding_idx = binding_idx;
515 ++bindings->count;
517 return true;
520 static VkDescriptorType vk_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type,
521 enum vkd3d_shader_resource_type resource_type)
523 switch (type)
525 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
526 return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
528 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
529 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
530 return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
531 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
533 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
534 if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
535 return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
536 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
538 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
539 return VK_DESCRIPTOR_TYPE_SAMPLER;
541 default:
542 FIXME("Unhandled descriptor type %#x.\n", type);
543 return ~0u;
547 static enum wined3d_shader_descriptor_type wined3d_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type)
549 switch (type)
551 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
552 return WINED3D_SHADER_DESCRIPTOR_TYPE_CBV;
554 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
555 return WINED3D_SHADER_DESCRIPTOR_TYPE_SRV;
557 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
558 return WINED3D_SHADER_DESCRIPTOR_TYPE_UAV;
560 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
561 return WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
563 default:
564 FIXME("Unhandled descriptor type %#x.\n", type);
565 return ~0u;
569 static enum wined3d_shader_resource_type wined3d_shader_resource_type_from_vkd3d(enum vkd3d_shader_resource_type t)
571 return (enum wined3d_shader_resource_type)t;
574 static enum wined3d_data_type wined3d_data_type_from_vkd3d(enum vkd3d_shader_resource_data_type t)
576 switch (t)
578 case VKD3D_SHADER_RESOURCE_DATA_UNORM:
579 return WINED3D_DATA_UNORM;
580 case VKD3D_SHADER_RESOURCE_DATA_SNORM:
581 return WINED3D_DATA_SNORM;
582 case VKD3D_SHADER_RESOURCE_DATA_INT:
583 return WINED3D_DATA_INT;
584 case VKD3D_SHADER_RESOURCE_DATA_UINT:
585 return WINED3D_DATA_UINT;
586 case VKD3D_SHADER_RESOURCE_DATA_FLOAT:
587 return WINED3D_DATA_FLOAT;
588 case VKD3D_SHADER_RESOURCE_DATA_MIXED:
589 return WINED3D_DATA_UINT;
590 default:
591 FIXME("Unhandled resource data type %#x.\n", t);
592 return WINED3D_DATA_FLOAT;
596 static bool shader_spirv_resource_bindings_init(struct shader_spirv_resource_bindings *bindings,
597 struct wined3d_shader_resource_bindings *wined3d_bindings,
598 const struct wined3d_state *state, uint32_t shader_mask)
600 const struct vkd3d_shader_scan_descriptor_info *descriptor_info;
601 enum wined3d_shader_descriptor_type wined3d_type;
602 enum vkd3d_shader_visibility shader_visibility;
603 enum wined3d_shader_type shader_type;
604 VkDescriptorType vk_descriptor_type;
605 VkShaderStageFlagBits vk_stage;
606 struct wined3d_shader *shader;
607 size_t binding_idx;
608 unsigned int i;
610 bindings->binding_count = 0;
611 bindings->uav_counter_count = 0;
612 bindings->vk_binding_count = 0;
613 bindings->so_stage = WINED3D_SHADER_TYPE_GEOMETRY;
614 wined3d_bindings->count = 0;
616 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_COUNT; ++shader_type)
618 bindings->binding_base[shader_type] = bindings->vk_binding_count;
620 if (!(shader_mask & (1u << shader_type)) || !(shader = state->shader[shader_type]))
621 continue;
623 if (shader_type == WINED3D_SHADER_TYPE_COMPUTE)
625 descriptor_info = &((struct shader_spirv_compute_program_vk *)shader->backend_data)->descriptor_info;
627 else
629 descriptor_info = &((struct shader_spirv_graphics_program_vk *)shader->backend_data)->descriptor_info;
630 if (shader_type == WINED3D_SHADER_TYPE_GEOMETRY && !shader->function)
631 bindings->so_stage = WINED3D_SHADER_TYPE_VERTEX;
634 vk_stage = vk_shader_stage_from_wined3d(shader_type);
635 shader_visibility = vkd3d_shader_visibility_from_wined3d(shader_type);
637 for (i = 0; i < descriptor_info->descriptor_count; ++i)
639 const struct vkd3d_shader_descriptor_info *d = &descriptor_info->descriptors[i];
640 uint32_t flags;
642 if (d->register_space)
644 WARN("Unsupported register space %u.\n", d->register_space);
645 return false;
648 if (d->resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
649 flags = VKD3D_SHADER_BINDING_FLAG_BUFFER;
650 else
651 flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
653 vk_descriptor_type = vk_descriptor_type_from_vkd3d(d->type, d->resource_type);
654 if (!shader_spirv_resource_bindings_add_binding(bindings, d->type, vk_descriptor_type,
655 d->register_index, shader_visibility, vk_stage, flags, &binding_idx))
656 return false;
658 wined3d_type = wined3d_descriptor_type_from_vkd3d(d->type);
659 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings, shader_type,
660 wined3d_type, d->register_index, wined3d_shader_resource_type_from_vkd3d(d->resource_type),
661 wined3d_data_type_from_vkd3d(d->resource_data_type), binding_idx))
662 return false;
664 if (d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
665 && (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER))
667 if (!shader_spirv_resource_bindings_add_uav_counter_binding(bindings,
668 d->register_index, shader_visibility, vk_stage, &binding_idx))
669 return false;
670 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings,
671 shader_type, WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER, d->register_index,
672 WINED3D_SHADER_RESOURCE_BUFFER, WINED3D_DATA_UINT, binding_idx))
673 return false;
678 return true;
681 static void shader_spirv_scan_shader(struct wined3d_shader *shader,
682 struct vkd3d_shader_scan_descriptor_info *descriptor_info)
684 struct vkd3d_shader_compile_info info;
685 char *messages;
686 int ret;
688 memset(descriptor_info, 0, sizeof(*descriptor_info));
689 descriptor_info->type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO;
691 info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO;
692 info.next = descriptor_info;
693 info.source.code = shader->byte_code;
694 info.source.size = shader->byte_code_size;
695 info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
696 info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY;
697 info.options = spirv_compile_options;
698 info.option_count = ARRAY_SIZE(spirv_compile_options);
699 info.log_level = VKD3D_SHADER_LOG_WARNING;
700 info.source_name = NULL;
702 if ((ret = vkd3d_shader_scan(&info, &messages)) < 0)
703 ERR("Failed to scan shader, ret %d.\n", ret);
704 if (messages && *messages && FIXME_ON(d3d_shader))
706 const char *ptr, *end, *line;
708 FIXME("Shader log:\n");
709 ptr = messages;
710 end = ptr + strlen(ptr);
711 while ((line = wined3d_get_line(&ptr, end)))
713 FIXME(" %.*s", (int)(ptr - line), line);
715 FIXME("\n");
717 vkd3d_shader_free_messages(messages);
720 static void shader_spirv_precompile_compute(struct wined3d_shader *shader)
722 struct shader_spirv_compute_program_vk *program_vk;
724 if (!(program_vk = shader->backend_data))
726 if (!(program_vk = heap_alloc_zero(sizeof(*program_vk))))
727 ERR("Failed to allocate program.\n");
728 shader->backend_data = program_vk;
731 shader_spirv_scan_shader(shader, &program_vk->descriptor_info);
734 static void shader_spirv_precompile(void *shader_priv, struct wined3d_shader *shader)
736 struct shader_spirv_graphics_program_vk *program_vk;
738 TRACE("shader_priv %p, shader %p.\n", shader_priv, shader);
740 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
742 shader_spirv_precompile_compute(shader);
743 return;
746 if (!(program_vk = shader->backend_data))
748 if (!(program_vk = heap_alloc_zero(sizeof(*program_vk))))
749 ERR("Failed to allocate program.\n");
750 shader->backend_data = program_vk;
753 shader_spirv_scan_shader(shader, &program_vk->descriptor_info);
756 static void shader_spirv_select(void *shader_priv, struct wined3d_context *context,
757 const struct wined3d_state *state)
759 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
760 struct shader_spirv_graphics_program_variant_vk *variant_vk;
761 struct shader_spirv_resource_bindings *bindings;
762 size_t binding_base[WINED3D_SHADER_TYPE_COUNT];
763 struct wined3d_pipeline_layout_vk *layout_vk;
764 struct shader_spirv_priv *priv = shader_priv;
765 enum wined3d_shader_type shader_type;
766 struct wined3d_shader *shader;
768 priv->vertex_pipe->vp_enable(context, !use_vs(state));
769 priv->fragment_pipe->fp_enable(context, !use_ps(state));
771 bindings = &priv->bindings;
772 memcpy(binding_base, bindings->binding_base, sizeof(bindings->binding_base));
773 if (!shader_spirv_resource_bindings_init(bindings, &context_vk->graphics.bindings,
774 state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE)))
776 ERR("Failed to initialise shader resource bindings.\n");
777 goto fail;
779 if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_GEOMETRY))
780 context->shader_update_mask |= 1u << bindings->so_stage;
782 layout_vk = wined3d_context_vk_get_pipeline_layout(context_vk, bindings->vk_bindings, bindings->vk_binding_count);
783 context_vk->graphics.vk_set_layout = layout_vk->vk_set_layout;
784 context_vk->graphics.vk_pipeline_layout = layout_vk->vk_pipeline_layout;
786 for (shader_type = 0; shader_type < ARRAY_SIZE(context_vk->graphics.vk_modules); ++shader_type)
788 if (!(context->shader_update_mask & (1u << shader_type)) && (!context_vk->graphics.vk_modules[shader_type]
789 || binding_base[shader_type] == bindings->binding_base[shader_type]))
790 continue;
792 if (!(shader = state->shader[shader_type]) || !shader->function)
794 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
795 continue;
798 if (!(variant_vk = shader_spirv_find_graphics_program_variant_vk(priv, context_vk, shader, state, bindings)))
799 goto fail;
800 context_vk->graphics.vk_modules[shader_type] = variant_vk->vk_module;
803 return;
805 fail:
806 context_vk->graphics.vk_set_layout = VK_NULL_HANDLE;
807 context_vk->graphics.vk_pipeline_layout = VK_NULL_HANDLE;
810 static void shader_spirv_select_compute(void *shader_priv,
811 struct wined3d_context *context, const struct wined3d_state *state)
813 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
814 struct shader_spirv_compute_program_vk *program;
815 struct shader_spirv_priv *priv = shader_priv;
816 struct wined3d_shader *shader;
818 if (!shader_spirv_resource_bindings_init(&priv->bindings,
819 &context_vk->compute.bindings, state, 1u << WINED3D_SHADER_TYPE_COMPUTE))
820 ERR("Failed to initialise shader resource bindings.\n");
822 if ((shader = state->shader[WINED3D_SHADER_TYPE_COMPUTE]))
823 program = shader_spirv_find_compute_program_vk(priv, context_vk, shader, &priv->bindings);
824 else
825 program = NULL;
827 if (program)
829 context_vk->compute.vk_pipeline = program->vk_pipeline;
830 context_vk->compute.vk_set_layout = program->vk_set_layout;
831 context_vk->compute.vk_pipeline_layout = program->vk_pipeline_layout;
833 else
835 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
836 context_vk->compute.vk_set_layout = VK_NULL_HANDLE;
837 context_vk->compute.vk_pipeline_layout = VK_NULL_HANDLE;
841 static void shader_spirv_disable(void *shader_priv, struct wined3d_context *context)
843 struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
844 struct shader_spirv_priv *priv = shader_priv;
846 priv->vertex_pipe->vp_enable(context, false);
847 priv->fragment_pipe->fp_enable(context, false);
849 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
850 context->shader_update_mask = (1u << WINED3D_SHADER_TYPE_PIXEL)
851 | (1u << WINED3D_SHADER_TYPE_VERTEX)
852 | (1u << WINED3D_SHADER_TYPE_GEOMETRY)
853 | (1u << WINED3D_SHADER_TYPE_HULL)
854 | (1u << WINED3D_SHADER_TYPE_DOMAIN)
855 | (1u << WINED3D_SHADER_TYPE_COMPUTE);
858 static void shader_spirv_update_float_vertex_constants(struct wined3d_device *device, UINT start, UINT count)
860 WARN("Not implemented.\n");
863 static void shader_spirv_update_float_pixel_constants(struct wined3d_device *device, UINT start, UINT count)
865 WARN("Not implemented.\n");
868 static void shader_spirv_load_constants(void *shader_priv, struct wined3d_context *context,
869 const struct wined3d_state *state)
871 WARN("Not implemented.\n");
874 static void shader_spirv_invalidate_compute_program(struct wined3d_context_vk *context_vk,
875 const struct shader_spirv_compute_program_vk *program)
877 if (context_vk->compute.vk_pipeline == program->vk_pipeline)
879 context_vk->c.shader_update_mask |= (1u << WINED3D_SHADER_TYPE_COMPUTE);
880 context_vk->compute.vk_pipeline = VK_NULL_HANDLE;
884 static void shader_spirv_invalidate_contexts_compute_program(struct wined3d_device *device,
885 const struct shader_spirv_compute_program_vk *program)
887 unsigned int i;
889 for (i = 0; i < device->context_count; ++i)
891 shader_spirv_invalidate_compute_program(wined3d_context_vk(device->contexts[i]), program);
895 static void shader_spirv_invalidate_graphics_program_variant(struct wined3d_context_vk *context_vk,
896 const struct shader_spirv_graphics_program_variant_vk *variant)
898 enum wined3d_shader_type shader_type;
900 for (shader_type = 0; shader_type < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++shader_type)
902 if (context_vk->graphics.vk_modules[shader_type] != variant->vk_module)
903 continue;
905 context_vk->graphics.vk_modules[shader_type] = VK_NULL_HANDLE;
906 context_vk->c.shader_update_mask |= (1u << shader_type);
910 static void shader_spirv_invalidate_contexts_graphics_program_variant(struct wined3d_device *device,
911 const struct shader_spirv_graphics_program_variant_vk *variant)
913 unsigned int i;
915 for (i = 0; i < device->context_count; ++i)
917 shader_spirv_invalidate_graphics_program_variant(wined3d_context_vk(device->contexts[i]), variant);
921 static void shader_spirv_destroy_compute_vk(struct wined3d_shader *shader)
923 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
924 struct shader_spirv_compute_program_vk *program = shader->backend_data;
925 struct wined3d_context_vk *context_vk = &device_vk->context_vk;
926 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
928 shader_spirv_invalidate_contexts_compute_program(&device_vk->d, program);
929 wined3d_context_vk_destroy_vk_pipeline(context_vk, program->vk_pipeline, context_vk->current_command_buffer.id);
930 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, program->vk_module, NULL));
931 vkd3d_shader_free_scan_descriptor_info(&program->descriptor_info);
932 shader->backend_data = NULL;
933 heap_free(program);
936 static void shader_spirv_destroy(struct wined3d_shader *shader)
938 struct wined3d_device_vk *device_vk = wined3d_device_vk(shader->device);
939 struct shader_spirv_graphics_program_variant_vk *variant_vk;
940 struct wined3d_vk_info *vk_info = &device_vk->vk_info;
941 struct shader_spirv_graphics_program_vk *program_vk;
942 size_t i;
944 if (!shader->backend_data)
945 return;
947 if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_COMPUTE)
949 shader_spirv_destroy_compute_vk(shader);
950 return;
953 program_vk = shader->backend_data;
954 for (i = 0; i < program_vk->variant_count; ++i)
956 variant_vk = &program_vk->variants[i];
957 shader_spirv_invalidate_contexts_graphics_program_variant(&device_vk->d, variant_vk);
958 VK_CALL(vkDestroyShaderModule(device_vk->vk_device, variant_vk->vk_module, NULL));
960 heap_free(program_vk->variants);
961 vkd3d_shader_free_scan_descriptor_info(&program_vk->descriptor_info);
963 shader->backend_data = NULL;
964 heap_free(program_vk);
967 static HRESULT shader_spirv_alloc(struct wined3d_device *device,
968 const struct wined3d_vertex_pipe_ops *vertex_pipe, const struct wined3d_fragment_pipe_ops *fragment_pipe)
970 struct fragment_caps fragment_caps;
971 void *vertex_priv, *fragment_priv;
972 struct shader_spirv_priv *priv;
974 if (!(priv = heap_alloc(sizeof(*priv))))
975 return E_OUTOFMEMORY;
977 if (!(vertex_priv = vertex_pipe->vp_alloc(&spirv_shader_backend_vk, priv)))
979 ERR("Failed to initialise vertex pipe.\n");
980 heap_free(priv);
981 return E_FAIL;
984 if (!(fragment_priv = fragment_pipe->alloc_private(&spirv_shader_backend_vk, priv)))
986 ERR("Failed to initialise fragment pipe.\n");
987 vertex_pipe->vp_free(device, NULL);
988 heap_free(priv);
989 return E_FAIL;
992 priv->vertex_pipe = vertex_pipe;
993 priv->fragment_pipe = fragment_pipe;
994 fragment_pipe->get_caps(device->adapter, &fragment_caps);
995 priv->ffp_proj_control = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_PROJ_CONTROL;
996 memset(&priv->bindings, 0, sizeof(priv->bindings));
998 device->vertex_priv = vertex_priv;
999 device->fragment_priv = fragment_priv;
1000 device->shader_priv = priv;
1002 return WINED3D_OK;
1005 static void shader_spirv_free(struct wined3d_device *device, struct wined3d_context *context)
1007 struct shader_spirv_priv *priv = device->shader_priv;
1009 shader_spirv_resource_bindings_cleanup(&priv->bindings);
1010 priv->fragment_pipe->free_private(device, context);
1011 priv->vertex_pipe->vp_free(device, context);
1012 heap_free(priv);
1015 static BOOL shader_spirv_allocate_context_data(struct wined3d_context *context)
1017 return TRUE;
1020 static void shader_spirv_free_context_data(struct wined3d_context *context)
1024 static void shader_spirv_init_context_state(struct wined3d_context *context)
1028 static void shader_spirv_get_caps(const struct wined3d_adapter *adapter, struct shader_caps *caps)
1030 caps->vs_version = min(wined3d_settings.max_sm_vs, 5);
1031 caps->hs_version = min(wined3d_settings.max_sm_hs, 5);
1032 caps->ds_version = min(wined3d_settings.max_sm_ds, 5);
1033 caps->gs_version = min(wined3d_settings.max_sm_gs, 5);
1034 caps->ps_version = min(wined3d_settings.max_sm_ps, 5);
1035 caps->cs_version = min(wined3d_settings.max_sm_cs, 5);
1037 caps->vs_uniform_count = WINED3D_MAX_VS_CONSTS_F;
1038 caps->ps_uniform_count = WINED3D_MAX_PS_CONSTS_F;
1039 caps->ps_1x_max_value = FLT_MAX;
1040 caps->varying_count = 0;
1041 caps->wined3d_caps = WINED3D_SHADER_CAP_VS_CLIPPING
1042 | WINED3D_SHADER_CAP_SRGB_WRITE
1043 | WINED3D_SHADER_CAP_FULL_FFP_VARYINGS;
1046 static BOOL shader_spirv_color_fixup_supported(struct color_fixup_desc fixup)
1048 return is_identity_fixup(fixup);
1051 static BOOL shader_spirv_has_ffp_proj_control(void *shader_priv)
1053 struct shader_spirv_priv *priv = shader_priv;
1055 return priv->ffp_proj_control;
1058 static uint64_t shader_spirv_compile(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc,
1059 enum wined3d_shader_type shader_type)
1061 struct shader_spirv_resource_bindings bindings = {0};
1062 return (uint64_t)shader_spirv_compile_shader(wined3d_context_vk(context), shader_desc, shader_type, NULL, &bindings, NULL);
1065 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk =
1067 .shader_handle_instruction = shader_spirv_handle_instruction,
1068 .shader_precompile = shader_spirv_precompile,
1069 .shader_select = shader_spirv_select,
1070 .shader_select_compute = shader_spirv_select_compute,
1071 .shader_disable = shader_spirv_disable,
1072 .shader_update_float_vertex_constants = shader_spirv_update_float_vertex_constants,
1073 .shader_update_float_pixel_constants = shader_spirv_update_float_pixel_constants,
1074 .shader_load_constants = shader_spirv_load_constants,
1075 .shader_destroy = shader_spirv_destroy,
1076 .shader_alloc_private = shader_spirv_alloc,
1077 .shader_free_private = shader_spirv_free,
1078 .shader_allocate_context_data = shader_spirv_allocate_context_data,
1079 .shader_free_context_data = shader_spirv_free_context_data,
1080 .shader_init_context_state = shader_spirv_init_context_state,
1081 .shader_get_caps = shader_spirv_get_caps,
1082 .shader_color_fixup_supported = shader_spirv_color_fixup_supported,
1083 .shader_has_ffp_proj_control = shader_spirv_has_ffp_proj_control,
1084 .shader_compile = shader_spirv_compile,
1087 const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(void)
1089 TRACE("Using %s.\n", vkd3d_shader_get_version(NULL, NULL));
1091 return &spirv_shader_backend_vk;
1094 static void spirv_vertex_pipe_vk_vp_enable(const struct wined3d_context *context, BOOL enable)
1096 /* Nothing to do. */
1099 static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter *adapter, struct wined3d_vertex_caps *caps)
1101 memset(caps, 0, sizeof(*caps));
1102 caps->xyzrhw = TRUE;
1103 caps->ffp_generic_attributes = TRUE;
1106 static unsigned int spirv_vertex_pipe_vk_vp_get_emul_mask(const struct wined3d_gl_info *gl_info)
1108 return 0;
1111 static void *spirv_vertex_pipe_vk_vp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1113 if (shader_backend != &spirv_shader_backend_vk)
1115 FIXME("SPIR-V vertex pipe without SPIR-V shader backend not implemented.\n");
1116 return NULL;
1119 return shader_priv;
1122 static void spirv_vertex_pipe_vk_vp_free(struct wined3d_device *device, struct wined3d_context *context)
1124 /* Nothing to do. */
1127 static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states[] =
1129 {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), state_nop}},
1130 {STATE_RENDER(WINED3D_RS_CLIPPING), {STATE_RENDER(WINED3D_RS_CLIPPING), state_nop}},
1131 {STATE_RENDER(WINED3D_RS_LIGHTING), {STATE_RENDER(WINED3D_RS_LIGHTING), state_nop}},
1132 {STATE_RENDER(WINED3D_RS_AMBIENT), {STATE_RENDER(WINED3D_RS_AMBIENT), state_nop}},
1133 {STATE_RENDER(WINED3D_RS_COLORVERTEX), {STATE_RENDER(WINED3D_RS_COLORVERTEX), state_nop}},
1134 {STATE_RENDER(WINED3D_RS_LOCALVIEWER), {STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_nop}},
1135 {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_nop}},
1136 {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), state_nop}},
1137 {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), state_nop}},
1138 {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), state_nop}},
1139 {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), state_nop}},
1140 {STATE_RENDER(WINED3D_RS_VERTEXBLEND), {STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_nop}},
1141 {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), state_nop}},
1142 {STATE_RENDER(WINED3D_RS_POINTSIZE), {STATE_RENDER(WINED3D_RS_POINTSIZE), state_nop}},
1143 {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_nop}},
1144 {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_nop}},
1145 {STATE_RENDER(WINED3D_RS_POINTSCALE_A), {STATE_RENDER(WINED3D_RS_POINTSCALE_A), state_nop}},
1146 {STATE_RENDER(WINED3D_RS_POINTSCALE_B), {STATE_RENDER(WINED3D_RS_POINTSCALE_B), state_nop}},
1147 {STATE_RENDER(WINED3D_RS_POINTSCALE_C), {STATE_RENDER(WINED3D_RS_POINTSCALE_C), state_nop}},
1148 {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), state_nop}},
1149 {STATE_MATERIAL, {STATE_MATERIAL, state_nop}},
1150 {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), state_nop}},
1151 {STATE_LIGHT_TYPE, {STATE_LIGHT_TYPE, state_nop}},
1152 {0}, /* Terminate */
1155 static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk =
1157 .vp_enable = spirv_vertex_pipe_vk_vp_enable,
1158 .vp_get_caps = spirv_vertex_pipe_vk_vp_get_caps,
1159 .vp_get_emul_mask = spirv_vertex_pipe_vk_vp_get_emul_mask,
1160 .vp_alloc = spirv_vertex_pipe_vk_vp_alloc,
1161 .vp_free = spirv_vertex_pipe_vk_vp_free,
1162 .vp_states = spirv_vertex_pipe_vk_vp_states,
1165 const struct wined3d_vertex_pipe_ops *wined3d_spirv_vertex_pipe_init_vk(void)
1167 return &spirv_vertex_pipe_vk;
1170 static void spirv_fragment_pipe_vk_fp_enable(const struct wined3d_context *context, BOOL enable)
1172 /* Nothing to do. */
1175 static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter *adapter, struct fragment_caps *caps)
1177 memset(caps, 0, sizeof(*caps));
1180 static unsigned int spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_gl_info *gl_info)
1182 return 0;
1185 static void *spirv_fragment_pipe_vk_fp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
1187 if (shader_backend != &spirv_shader_backend_vk)
1189 FIXME("SPIR-V fragment pipe without SPIR-V shader backend not implemented.\n");
1190 return NULL;
1193 return shader_priv;
1196 static void spirv_fragment_pipe_vk_fp_free(struct wined3d_device *device, struct wined3d_context *context)
1198 /* Nothing to do. */
1201 static BOOL spirv_fragment_pipe_vk_fp_alloc_context_data(struct wined3d_context *context)
1203 return TRUE;
1206 static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context *context)
1208 /* Nothing to do. */
1211 static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states[] =
1213 {STATE_RENDER(WINED3D_RS_SHADEMODE), {STATE_RENDER(WINED3D_RS_SHADEMODE), state_nop}},
1214 {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_nop}},
1215 {STATE_RENDER(WINED3D_RS_ALPHAREF), {STATE_RENDER(WINED3D_RS_ALPHAREF), state_nop}},
1216 {STATE_RENDER(WINED3D_RS_ALPHAFUNC), {STATE_RENDER(WINED3D_RS_ALPHAFUNC), state_nop}},
1217 {STATE_RENDER(WINED3D_RS_FOGENABLE), {STATE_RENDER(WINED3D_RS_FOGENABLE), state_nop}},
1218 {STATE_RENDER(WINED3D_RS_SPECULARENABLE), {STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_nop}},
1219 {STATE_RENDER(WINED3D_RS_FOGCOLOR), {STATE_RENDER(WINED3D_RS_FOGCOLOR), state_nop}},
1220 {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE), state_nop}},
1221 {STATE_RENDER(WINED3D_RS_FOGSTART), {STATE_RENDER(WINED3D_RS_FOGSTART), state_nop}},
1222 {STATE_RENDER(WINED3D_RS_FOGEND), {STATE_RENDER(WINED3D_RS_FOGEND), state_nop}},
1223 {STATE_RENDER(WINED3D_RS_FOGDENSITY), {STATE_RENDER(WINED3D_RS_FOGDENSITY), state_nop}},
1224 {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE), state_nop}},
1225 {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_nop}},
1226 {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), state_nop}},
1227 {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_nop}},
1228 {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), state_nop}},
1229 {STATE_POINT_ENABLE, {STATE_POINT_ENABLE, state_nop}},
1230 {STATE_COLOR_KEY, {STATE_COLOR_KEY, state_nop}},
1231 {0}, /* Terminate */
1234 static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk =
1236 .fp_enable = spirv_fragment_pipe_vk_fp_enable,
1237 .get_caps = spirv_fragment_pipe_vk_fp_get_caps,
1238 .get_emul_mask = spirv_fragment_pipe_vk_fp_get_emul_mask,
1239 .alloc_private = spirv_fragment_pipe_vk_fp_alloc,
1240 .free_private = spirv_fragment_pipe_vk_fp_free,
1241 .allocate_context_data = spirv_fragment_pipe_vk_fp_alloc_context_data,
1242 .free_context_data = spirv_fragment_pipe_vk_fp_free_context_data,
1243 .color_fixup_supported = shader_spirv_color_fixup_supported,
1244 .states = spirv_fragment_pipe_vk_fp_states,
1247 const struct wined3d_fragment_pipe_ops *wined3d_spirv_fragment_pipe_init_vk(void)
1249 return &spirv_fragment_pipe_vk;