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
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
75 uint32_t alpha_swizzle
;
76 unsigned int sample_count
;
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
;
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
)
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
));
159 ERR_(winediag
)("Failed to load libvkd3d-shader.\n");
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
)
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
;
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
;
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
)
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
;
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
)
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
);
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
)
269 if (!(q
= strstr(p
, "\n")))
271 if (!*p
) return NULL
;
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
;
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
;
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
;
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
;
346 FIXME("Shader log:\n");
347 while ((line
= get_line(&ptr
)))
349 FIXME(" %.*s", (int)(ptr
- line
), line
);
353 vkd3d_shader_free_messages(messages
);
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
);
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
))
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
)))
409 if (!wined3d_array_reserve((void **)&program_vk
->variants
, &program_vk
->variants_size
,
410 variant_count
+ 1, sizeof(*program_vk
->variants
)))
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
)))
418 ++program_vk
->variant_count
;
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
;
434 if (!(program
= shader
->backend_data
))
437 if (program
->vk_module
)
440 if (!(program
->vk_module
= shader_spirv_compile(context_vk
, shader
, NULL
, bindings
, 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
;
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
;
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
)))
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
;
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
)))
518 if (!shader_spirv_resource_bindings_add_vk_binding(bindings
, vk_type
, vk_stage
, binding_idx
))
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
;
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
))
545 if (!shader_spirv_resource_bindings_add_vk_binding(bindings
,
546 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
, vk_stage
, binding_idx
))
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;
557 ++bindings
->uav_counter_count
;
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
)))
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
;
586 static VkDescriptorType
vk_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type
,
587 enum vkd3d_shader_resource_type resource_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
;
608 FIXME("Unhandled descriptor type %#x.\n", type
);
613 static enum wined3d_shader_descriptor_type
wined3d_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type 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
;
630 FIXME("Unhandled descriptor type %#x.\n", type
);
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
)
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
;
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
;
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
]))
687 if (shader_type
== WINED3D_SHADER_TYPE_COMPUTE
)
689 descriptor_info
= &((struct shader_spirv_compute_program_vk
*)shader
->backend_data
)->descriptor_info
;
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
];
706 if (d
->register_space
)
708 WARN("Unsupported register space %u.\n", d
->register_space
);
712 if (d
->resource_type
== VKD3D_SHADER_RESOURCE_BUFFER
)
713 flags
= VKD3D_SHADER_BINDING_FLAG_BUFFER
;
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
))
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
))
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
))
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
))
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
;
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
;
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
;
773 FIXME("Shader log:\n");
774 while ((line
= get_line(&ptr
)))
776 FIXME(" %.*s", (int)(ptr
- line
), line
);
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
);
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");
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
]))
855 if (!(shader
= state
->shader
[shader_type
]) || !shader
->function
)
857 context_vk
->graphics
.vk_modules
[shader_type
] = VK_NULL_HANDLE
;
861 if (!(variant_vk
= shader_spirv_find_graphics_program_variant_vk(priv
, context_vk
, shader
, state
, bindings
)))
863 context_vk
->graphics
.vk_modules
[shader_type
] = variant_vk
->vk_module
;
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
);
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
;
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
)
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
)
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
)
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
;
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
;
1006 if (!shader
->backend_data
)
1009 if (shader
->reg_maps
.shader_version
.type
== WINED3D_SHADER_TYPE_COMPUTE
)
1011 shader_spirv_destroy_compute_vk(shader
);
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 vkd3d_shader_free_scan_descriptor_info(&program_vk
->descriptor_info
);
1024 shader
->backend_data
= NULL
;
1025 heap_free(program_vk
);
1028 static HRESULT
shader_spirv_alloc(struct wined3d_device
*device
,
1029 const struct wined3d_vertex_pipe_ops
*vertex_pipe
, const struct wined3d_fragment_pipe_ops
*fragment_pipe
)
1031 struct fragment_caps fragment_caps
;
1032 void *vertex_priv
, *fragment_priv
;
1033 struct shader_spirv_priv
*priv
;
1035 if (!(priv
= heap_alloc(sizeof(*priv
))))
1036 return E_OUTOFMEMORY
;
1038 if (!(vertex_priv
= vertex_pipe
->vp_alloc(&spirv_shader_backend_vk
, priv
)))
1040 ERR("Failed to initialise vertex pipe.\n");
1045 if (!(fragment_priv
= fragment_pipe
->alloc_private(&spirv_shader_backend_vk
, priv
)))
1047 ERR("Failed to initialise fragment pipe.\n");
1048 vertex_pipe
->vp_free(device
, NULL
);
1053 priv
->vertex_pipe
= vertex_pipe
;
1054 priv
->fragment_pipe
= fragment_pipe
;
1055 fragment_pipe
->get_caps(device
->adapter
, &fragment_caps
);
1056 priv
->ffp_proj_control
= fragment_caps
.wined3d_caps
& WINED3D_FRAGMENT_CAP_PROJ_CONTROL
;
1057 memset(&priv
->bindings
, 0, sizeof(priv
->bindings
));
1059 device
->vertex_priv
= vertex_priv
;
1060 device
->fragment_priv
= fragment_priv
;
1061 device
->shader_priv
= priv
;
1066 static void shader_spirv_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1068 struct shader_spirv_priv
*priv
= device
->shader_priv
;
1070 shader_spirv_resource_bindings_cleanup(&priv
->bindings
);
1071 priv
->fragment_pipe
->free_private(device
, context
);
1072 priv
->vertex_pipe
->vp_free(device
, context
);
1076 static BOOL
shader_spirv_allocate_context_data(struct wined3d_context
*context
)
1081 static void shader_spirv_free_context_data(struct wined3d_context
*context
)
1085 static void shader_spirv_init_context_state(struct wined3d_context
*context
)
1089 static void shader_spirv_get_caps(const struct wined3d_adapter
*adapter
, struct shader_caps
*caps
)
1091 caps
->vs_version
= min(wined3d_settings
.max_sm_vs
, 5);
1092 caps
->hs_version
= min(wined3d_settings
.max_sm_hs
, 5);
1093 caps
->ds_version
= min(wined3d_settings
.max_sm_ds
, 5);
1094 caps
->gs_version
= min(wined3d_settings
.max_sm_gs
, 5);
1095 caps
->ps_version
= min(wined3d_settings
.max_sm_ps
, 5);
1096 caps
->cs_version
= min(wined3d_settings
.max_sm_cs
, 5);
1098 caps
->vs_uniform_count
= WINED3D_MAX_VS_CONSTS_F
;
1099 caps
->ps_uniform_count
= WINED3D_MAX_PS_CONSTS_F
;
1100 caps
->ps_1x_max_value
= FLT_MAX
;
1101 caps
->varying_count
= 0;
1102 caps
->wined3d_caps
= WINED3D_SHADER_CAP_VS_CLIPPING
1103 | WINED3D_SHADER_CAP_SRGB_WRITE
1104 | WINED3D_SHADER_CAP_FULL_FFP_VARYINGS
;
1107 static BOOL
shader_spirv_color_fixup_supported(struct color_fixup_desc fixup
)
1109 return is_identity_fixup(fixup
);
1112 static BOOL
shader_spirv_has_ffp_proj_control(void *shader_priv
)
1114 struct shader_spirv_priv
*priv
= shader_priv
;
1116 return priv
->ffp_proj_control
;
1119 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk
=
1121 .shader_handle_instruction
= shader_spirv_handle_instruction
,
1122 .shader_precompile
= shader_spirv_precompile
,
1123 .shader_select
= shader_spirv_select
,
1124 .shader_select_compute
= shader_spirv_select_compute
,
1125 .shader_disable
= shader_spirv_disable
,
1126 .shader_update_float_vertex_constants
= shader_spirv_update_float_vertex_constants
,
1127 .shader_update_float_pixel_constants
= shader_spirv_update_float_pixel_constants
,
1128 .shader_load_constants
= shader_spirv_load_constants
,
1129 .shader_destroy
= shader_spirv_destroy
,
1130 .shader_alloc_private
= shader_spirv_alloc
,
1131 .shader_free_private
= shader_spirv_free
,
1132 .shader_allocate_context_data
= shader_spirv_allocate_context_data
,
1133 .shader_free_context_data
= shader_spirv_free_context_data
,
1134 .shader_init_context_state
= shader_spirv_init_context_state
,
1135 .shader_get_caps
= shader_spirv_get_caps
,
1136 .shader_color_fixup_supported
= shader_spirv_color_fixup_supported
,
1137 .shader_has_ffp_proj_control
= shader_spirv_has_ffp_proj_control
,
1140 const struct wined3d_shader_backend_ops
*wined3d_spirv_shader_backend_init_vk(void)
1142 if (!wined3d_init_vkd3d())
1145 return &spirv_shader_backend_vk
;
1148 void wined3d_spirv_shader_backend_cleanup(void)
1150 wined3d_unload_vkd3d_shader();
1153 static void spirv_vertex_pipe_vk_vp_enable(const struct wined3d_context
*context
, BOOL enable
)
1155 /* Nothing to do. */
1158 static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter
*adapter
, struct wined3d_vertex_caps
*caps
)
1160 memset(caps
, 0, sizeof(*caps
));
1163 static uint32_t spirv_vertex_pipe_vk_vp_get_emul_mask(const struct wined3d_gl_info
*gl_info
)
1168 static void *spirv_vertex_pipe_vk_vp_alloc(const struct wined3d_shader_backend_ops
*shader_backend
, void *shader_priv
)
1170 if (shader_backend
!= &spirv_shader_backend_vk
)
1172 FIXME("SPIR-V vertex pipe without SPIR-V shader backend not implemented.\n");
1179 static void spirv_vertex_pipe_vk_vp_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1181 /* Nothing to do. */
1184 static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states
[] =
1186 {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE
), {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE
), state_nop
}},
1187 {STATE_RENDER(WINED3D_RS_CLIPPING
), {STATE_RENDER(WINED3D_RS_CLIPPING
), state_nop
}},
1188 {STATE_RENDER(WINED3D_RS_LIGHTING
), {STATE_RENDER(WINED3D_RS_LIGHTING
), state_nop
}},
1189 {STATE_RENDER(WINED3D_RS_AMBIENT
), {STATE_RENDER(WINED3D_RS_AMBIENT
), state_nop
}},
1190 {STATE_RENDER(WINED3D_RS_COLORVERTEX
), {STATE_RENDER(WINED3D_RS_COLORVERTEX
), state_nop
}},
1191 {STATE_RENDER(WINED3D_RS_LOCALVIEWER
), {STATE_RENDER(WINED3D_RS_LOCALVIEWER
), state_nop
}},
1192 {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS
), {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS
), state_nop
}},
1193 {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE
), state_nop
}},
1194 {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE
), state_nop
}},
1195 {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE
), state_nop
}},
1196 {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE
), state_nop
}},
1197 {STATE_RENDER(WINED3D_RS_VERTEXBLEND
), {STATE_RENDER(WINED3D_RS_VERTEXBLEND
), state_nop
}},
1198 {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE
), {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE
), state_nop
}},
1199 {STATE_RENDER(WINED3D_RS_POINTSIZE
), {STATE_RENDER(WINED3D_RS_POINTSIZE
), state_nop
}},
1200 {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN
), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN
), state_nop
}},
1201 {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE
), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE
), state_nop
}},
1202 {STATE_RENDER(WINED3D_RS_POINTSCALE_A
), {STATE_RENDER(WINED3D_RS_POINTSCALE_A
), state_nop
}},
1203 {STATE_RENDER(WINED3D_RS_POINTSCALE_B
), {STATE_RENDER(WINED3D_RS_POINTSCALE_B
), state_nop
}},
1204 {STATE_RENDER(WINED3D_RS_POINTSCALE_C
), {STATE_RENDER(WINED3D_RS_POINTSCALE_C
), state_nop
}},
1205 {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX
), {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX
), state_nop
}},
1206 {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE
), {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE
), state_nop
}},
1207 {STATE_RENDER(WINED3D_RS_TWEENFACTOR
), {STATE_RENDER(WINED3D_RS_TWEENFACTOR
), state_nop
}},
1208 {STATE_MATERIAL
, {STATE_MATERIAL
, state_nop
}},
1209 {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
), state_nop
}},
1210 {STATE_LIGHT_TYPE
, {STATE_LIGHT_TYPE
, state_nop
}},
1211 {0}, /* Terminate */
1214 static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk
=
1216 .vp_enable
= spirv_vertex_pipe_vk_vp_enable
,
1217 .vp_get_caps
= spirv_vertex_pipe_vk_vp_get_caps
,
1218 .vp_get_emul_mask
= spirv_vertex_pipe_vk_vp_get_emul_mask
,
1219 .vp_alloc
= spirv_vertex_pipe_vk_vp_alloc
,
1220 .vp_free
= spirv_vertex_pipe_vk_vp_free
,
1221 .vp_states
= spirv_vertex_pipe_vk_vp_states
,
1224 const struct wined3d_vertex_pipe_ops
*wined3d_spirv_vertex_pipe_init_vk(void)
1226 return &spirv_vertex_pipe_vk
;
1229 static void spirv_fragment_pipe_vk_fp_enable(const struct wined3d_context
*context
, BOOL enable
)
1231 /* Nothing to do. */
1234 static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter
*adapter
, struct fragment_caps
*caps
)
1236 memset(caps
, 0, sizeof(*caps
));
1239 static uint32_t spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_gl_info
*gl_info
)
1244 static void *spirv_fragment_pipe_vk_fp_alloc(const struct wined3d_shader_backend_ops
*shader_backend
, void *shader_priv
)
1246 if (shader_backend
!= &spirv_shader_backend_vk
)
1248 FIXME("SPIR-V fragment pipe without SPIR-V shader backend not implemented.\n");
1255 static void spirv_fragment_pipe_vk_fp_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1257 /* Nothing to do. */
1260 static BOOL
spirv_fragment_pipe_vk_fp_alloc_context_data(struct wined3d_context
*context
)
1265 static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context
*context
)
1267 /* Nothing to do. */
1270 static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states
[] =
1272 {STATE_RENDER(WINED3D_RS_SHADEMODE
), {STATE_RENDER(WINED3D_RS_SHADEMODE
), state_nop
}},
1273 {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE
), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE
), state_nop
}},
1274 {STATE_RENDER(WINED3D_RS_ALPHAREF
), {STATE_RENDER(WINED3D_RS_ALPHAREF
), state_nop
}},
1275 {STATE_RENDER(WINED3D_RS_ALPHAFUNC
), {STATE_RENDER(WINED3D_RS_ALPHAFUNC
), state_nop
}},
1276 {STATE_RENDER(WINED3D_RS_FOGENABLE
), {STATE_RENDER(WINED3D_RS_FOGENABLE
), state_nop
}},
1277 {STATE_RENDER(WINED3D_RS_SPECULARENABLE
), {STATE_RENDER(WINED3D_RS_SPECULARENABLE
), state_nop
}},
1278 {STATE_RENDER(WINED3D_RS_FOGCOLOR
), {STATE_RENDER(WINED3D_RS_FOGCOLOR
), state_nop
}},
1279 {STATE_RENDER(WINED3D_RS_FOGTABLEMODE
), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE
), state_nop
}},
1280 {STATE_RENDER(WINED3D_RS_FOGSTART
), {STATE_RENDER(WINED3D_RS_FOGSTART
), state_nop
}},
1281 {STATE_RENDER(WINED3D_RS_FOGEND
), {STATE_RENDER(WINED3D_RS_FOGEND
), state_nop
}},
1282 {STATE_RENDER(WINED3D_RS_FOGDENSITY
), {STATE_RENDER(WINED3D_RS_FOGDENSITY
), state_nop
}},
1283 {STATE_RENDER(WINED3D_RS_COLORKEYENABLE
), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE
), state_nop
}},
1284 {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR
), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR
), state_nop
}},
1285 {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE
), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE
), state_nop
}},
1286 {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE
), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE
), state_nop
}},
1287 {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE
), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE
), state_nop
}},
1288 {STATE_POINT_ENABLE
, {STATE_POINT_ENABLE
, state_nop
}},
1289 {STATE_COLOR_KEY
, {STATE_COLOR_KEY
, state_nop
}},
1290 {0}, /* Terminate */
1293 static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk
=
1295 .fp_enable
= spirv_fragment_pipe_vk_fp_enable
,
1296 .get_caps
= spirv_fragment_pipe_vk_fp_get_caps
,
1297 .get_emul_mask
= spirv_fragment_pipe_vk_fp_get_emul_mask
,
1298 .alloc_private
= spirv_fragment_pipe_vk_fp_alloc
,
1299 .free_private
= spirv_fragment_pipe_vk_fp_free
,
1300 .allocate_context_data
= spirv_fragment_pipe_vk_fp_alloc_context_data
,
1301 .free_context_data
= spirv_fragment_pipe_vk_fp_free_context_data
,
1302 .color_fixup_supported
= shader_spirv_color_fixup_supported
,
1303 .states
= spirv_fragment_pipe_vk_fp_states
,
1306 const struct wined3d_fragment_pipe_ops
*wined3d_spirv_fragment_pipe_init_vk(void)
1308 return &spirv_fragment_pipe_vk
;
1313 const struct wined3d_shader_backend_ops
*wined3d_spirv_shader_backend_init_vk(void)
1315 ERR_(winediag
)("Wine was built without libvkd3d-shader support.\n");
1319 void wined3d_spirv_shader_backend_cleanup(void)
1323 const struct wined3d_vertex_pipe_ops
*wined3d_spirv_vertex_pipe_init_vk(void)
1325 return &none_vertex_pipe
;
1328 const struct wined3d_fragment_pipe_ops
*wined3d_spirv_fragment_pipe_init_vk(void)
1330 return &none_fragment_pipe
;
1333 #endif /* defined(SONAME_LIBVKD3D_SHADER) */