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
22 #include "wined3d_private.h"
24 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
26 #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 const struct shader_spirv_resource_bindings
*b
, const struct wined3d_stream_output_desc
*so_desc
)
283 memset(iface
, 0, sizeof(*iface
));
284 iface
->vkd3d_interface
.type
= VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO
;
288 iface
->xfb_info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO
;
289 iface
->xfb_info
.next
= NULL
;
291 iface
->xfb_info
.elements
= (const struct vkd3d_shader_transform_feedback_element
*)so_desc
->elements
;
292 iface
->xfb_info
.element_count
= so_desc
->element_count
;
293 iface
->xfb_info
.buffer_strides
= so_desc
->buffer_strides
;
294 iface
->xfb_info
.buffer_stride_count
= so_desc
->buffer_stride_count
;
296 iface
->vkd3d_interface
.next
= &iface
->xfb_info
;
299 iface
->vkd3d_interface
.bindings
= b
->bindings
;
300 iface
->vkd3d_interface
.binding_count
= b
->binding_count
;
302 iface
->vkd3d_interface
.uav_counters
= b
->uav_counters
;
303 iface
->vkd3d_interface
.uav_counter_count
= b
->uav_counter_count
;
306 static VkShaderModule
shader_spirv_compile_shader(struct wined3d_context_vk
*context_vk
,
307 const struct wined3d_shader_desc
*shader_desc
, enum wined3d_shader_type shader_type
,
308 const struct shader_spirv_compile_arguments
*args
, const struct shader_spirv_resource_bindings
*bindings
,
309 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 VkShaderModuleCreateInfo shader_create_info
;
314 struct vkd3d_shader_compile_info info
;
315 const struct wined3d_vk_info
*vk_info
;
316 struct wined3d_device_vk
*device_vk
;
317 struct vkd3d_shader_code spirv
;
318 VkShaderModule module
;
323 shader_spirv_init_shader_interface_vk(&iface
, bindings
, so_desc
);
324 shader_spirv_init_compile_args(&compile_args
, &iface
.vkd3d_interface
,
325 VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0
, shader_type
, args
);
327 info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO
;
328 info
.next
= &compile_args
.spirv_target
;
329 info
.source
.code
= shader_desc
->byte_code
;
330 info
.source
.size
= shader_desc
->byte_code_size
;
331 info
.source_type
= VKD3D_SHADER_SOURCE_DXBC_TPF
;
332 info
.target_type
= VKD3D_SHADER_TARGET_SPIRV_BINARY
;
334 info
.option_count
= 0;
335 info
.log_level
= VKD3D_SHADER_LOG_WARNING
;
336 info
.source_name
= NULL
;
338 ret
= vkd3d_shader_compile(&info
, &spirv
, &messages
);
339 if (messages
&& *messages
&& FIXME_ON(d3d_shader
))
341 const char *ptr
= messages
;
344 FIXME("Shader log:\n");
345 while ((line
= get_line(&ptr
)))
347 FIXME(" %.*s", (int)(ptr
- line
), line
);
351 vkd3d_shader_free_messages(messages
);
355 ERR("Failed to compile DXBC, ret %d.\n", ret
);
356 return VK_NULL_HANDLE
;
359 device_vk
= wined3d_device_vk(context_vk
->c
.device
);
360 vk_info
= &device_vk
->vk_info
;
362 shader_create_info
.sType
= VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
;
363 shader_create_info
.pNext
= NULL
;
364 shader_create_info
.flags
= 0;
365 shader_create_info
.codeSize
= spirv
.size
;
366 shader_create_info
.pCode
= spirv
.code
;
367 if ((vr
= VK_CALL(vkCreateShaderModule(device_vk
->vk_device
, &shader_create_info
, NULL
, &module
))) < 0)
369 vkd3d_shader_free_shader_code(&spirv
);
370 WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr
));
371 return VK_NULL_HANDLE
;
374 vkd3d_shader_free_shader_code(&spirv
);
379 static struct shader_spirv_graphics_program_variant_vk
*shader_spirv_find_graphics_program_variant_vk(
380 struct shader_spirv_priv
*priv
, struct wined3d_context_vk
*context_vk
, struct wined3d_shader
*shader
,
381 const struct wined3d_state
*state
, const struct shader_spirv_resource_bindings
*bindings
)
383 enum wined3d_shader_type shader_type
= shader
->reg_maps
.shader_version
.type
;
384 struct shader_spirv_graphics_program_variant_vk
*variant_vk
;
385 size_t binding_base
= bindings
->binding_base
[shader_type
];
386 const struct wined3d_stream_output_desc
*so_desc
= NULL
;
387 struct shader_spirv_graphics_program_vk
*program_vk
;
388 struct shader_spirv_compile_arguments args
;
389 struct wined3d_shader_desc shader_desc
;
390 size_t variant_count
, i
;
392 shader_spirv_compile_arguments_init(&args
, &context_vk
->c
, shader
, state
, context_vk
->sample_count
);
393 if (bindings
->so_stage
== shader_type
)
394 so_desc
= state
->shader
[WINED3D_SHADER_TYPE_GEOMETRY
]->u
.gs
.so_desc
;
396 if (!(program_vk
= shader
->backend_data
))
399 variant_count
= program_vk
->variant_count
;
400 for (i
= 0; i
< variant_count
; ++i
)
402 variant_vk
= &program_vk
->variants
[i
];
403 if (variant_vk
->so_desc
== so_desc
&& variant_vk
->binding_base
== binding_base
404 && !memcmp(&variant_vk
->compile_args
, &args
, sizeof(args
)))
408 if (!wined3d_array_reserve((void **)&program_vk
->variants
, &program_vk
->variants_size
,
409 variant_count
+ 1, sizeof(*program_vk
->variants
)))
412 variant_vk
= &program_vk
->variants
[variant_count
];
413 variant_vk
->compile_args
= args
;
414 variant_vk
->binding_base
= binding_base
;
416 shader_desc
.byte_code
= shader
->byte_code
;
417 shader_desc
.byte_code_size
= shader
->byte_code_size
;
419 if (!(variant_vk
->vk_module
= shader_spirv_compile_shader(context_vk
, &shader_desc
, shader_type
, &args
,
422 ++program_vk
->variant_count
;
427 static struct shader_spirv_compute_program_vk
*shader_spirv_find_compute_program_vk(struct shader_spirv_priv
*priv
,
428 struct wined3d_context_vk
*context_vk
, struct wined3d_shader
*shader
,
429 const struct shader_spirv_resource_bindings
*bindings
)
431 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
432 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
433 struct shader_spirv_compute_program_vk
*program
;
434 struct wined3d_pipeline_layout_vk
*layout
;
435 VkComputePipelineCreateInfo pipeline_info
;
436 struct wined3d_shader_desc shader_desc
;
439 if (!(program
= shader
->backend_data
))
442 if (program
->vk_module
)
445 shader_desc
.byte_code
= shader
->byte_code
;
446 shader_desc
.byte_code_size
= shader
->byte_code_size
;
448 if (!(program
->vk_module
= shader_spirv_compile_shader(context_vk
, &shader_desc
, WINED3D_SHADER_TYPE_COMPUTE
,
449 NULL
, bindings
, NULL
)))
452 if (!(layout
= wined3d_context_vk_get_pipeline_layout(context_vk
,
453 bindings
->vk_bindings
, bindings
->vk_binding_count
)))
455 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, program
->vk_module
, NULL
));
456 program
->vk_module
= VK_NULL_HANDLE
;
459 program
->vk_set_layout
= layout
->vk_set_layout
;
460 program
->vk_pipeline_layout
= layout
->vk_pipeline_layout
;
462 pipeline_info
.sType
= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
;
463 pipeline_info
.pNext
= NULL
;
464 pipeline_info
.flags
= 0;
465 pipeline_info
.stage
.sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
;
466 pipeline_info
.stage
.pNext
= NULL
;
467 pipeline_info
.stage
.flags
= 0;
468 pipeline_info
.stage
.stage
= VK_SHADER_STAGE_COMPUTE_BIT
;
469 pipeline_info
.stage
.pName
= "main";
470 pipeline_info
.stage
.pSpecializationInfo
= NULL
;
471 pipeline_info
.stage
.module
= program
->vk_module
;
472 pipeline_info
.layout
= program
->vk_pipeline_layout
;
473 pipeline_info
.basePipelineHandle
= VK_NULL_HANDLE
;
474 pipeline_info
.basePipelineIndex
= -1;
475 if ((vr
= VK_CALL(vkCreateComputePipelines(device_vk
->vk_device
,
476 VK_NULL_HANDLE
, 1, &pipeline_info
, NULL
, &program
->vk_pipeline
))) < 0)
478 ERR("Failed to create Vulkan compute pipeline, vr %s.\n", wined3d_debug_vkresult(vr
));
479 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, program
->vk_module
, NULL
));
480 program
->vk_module
= VK_NULL_HANDLE
;
487 static void shader_spirv_resource_bindings_cleanup(struct shader_spirv_resource_bindings
*bindings
)
489 heap_free(bindings
->vk_bindings
);
490 heap_free(bindings
->bindings
);
493 static bool shader_spirv_resource_bindings_add_vk_binding(struct shader_spirv_resource_bindings
*bindings
,
494 VkDescriptorType vk_type
, VkShaderStageFlagBits vk_stage
, size_t *binding_idx
)
496 SIZE_T binding_count
= bindings
->vk_binding_count
;
497 VkDescriptorSetLayoutBinding
*binding
;
499 if (!wined3d_array_reserve((void **)&bindings
->vk_bindings
, &bindings
->vk_bindings_size
,
500 binding_count
+ 1, sizeof(*bindings
->vk_bindings
)))
503 *binding_idx
= binding_count
;
504 binding
= &bindings
->vk_bindings
[binding_count
];
505 binding
->binding
= binding_count
;
506 binding
->descriptorType
= vk_type
;
507 binding
->descriptorCount
= 1;
508 binding
->stageFlags
= vk_stage
;
509 binding
->pImmutableSamplers
= NULL
;
510 ++bindings
->vk_binding_count
;
515 static bool shader_spirv_resource_bindings_add_binding(struct shader_spirv_resource_bindings
*bindings
,
516 enum vkd3d_shader_descriptor_type vkd3d_type
, VkDescriptorType vk_type
, size_t register_idx
,
517 enum vkd3d_shader_visibility vkd3d_visibility
, VkShaderStageFlagBits vk_stage
,
518 uint32_t flags
, size_t *binding_idx
)
520 SIZE_T binding_count
= bindings
->binding_count
;
521 struct vkd3d_shader_resource_binding
*binding
;
523 if (!wined3d_array_reserve((void **)&bindings
->bindings
, &bindings
->bindings_size
,
524 binding_count
+ 1, sizeof(*bindings
->bindings
)))
527 if (!shader_spirv_resource_bindings_add_vk_binding(bindings
, vk_type
, vk_stage
, binding_idx
))
530 binding
= &bindings
->bindings
[binding_count
];
531 binding
->type
= vkd3d_type
;
532 binding
->register_space
= 0;
533 binding
->register_index
= register_idx
;
534 binding
->shader_visibility
= vkd3d_visibility
;
535 binding
->flags
= flags
;
536 binding
->binding
.set
= 0;
537 binding
->binding
.binding
= *binding_idx
;
538 binding
->binding
.count
= 1;
539 ++bindings
->binding_count
;
544 static bool shader_spirv_resource_bindings_add_uav_counter_binding(struct shader_spirv_resource_bindings
*bindings
,
545 size_t register_idx
, enum vkd3d_shader_visibility vkd3d_visibility
,
546 VkShaderStageFlagBits vk_stage
, size_t *binding_idx
)
548 SIZE_T uav_counter_count
= bindings
->uav_counter_count
;
549 struct vkd3d_shader_uav_counter_binding
*counter
;
551 if (uav_counter_count
>= ARRAY_SIZE(bindings
->uav_counters
))
554 if (!shader_spirv_resource_bindings_add_vk_binding(bindings
,
555 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
, vk_stage
, binding_idx
))
558 counter
= &bindings
->uav_counters
[uav_counter_count
];
559 counter
->register_space
= 0;
560 counter
->register_index
= register_idx
;
561 counter
->shader_visibility
= vkd3d_visibility
;
562 counter
->binding
.set
= 0;
563 counter
->binding
.binding
= *binding_idx
;
564 counter
->binding
.count
= 1;
566 ++bindings
->uav_counter_count
;
571 static bool wined3d_shader_resource_bindings_add_binding(struct wined3d_shader_resource_bindings
*bindings
,
572 enum wined3d_shader_type shader_type
, enum wined3d_shader_descriptor_type shader_descriptor_type
,
573 size_t resource_idx
, enum wined3d_shader_resource_type resource_type
,
574 enum wined3d_data_type resource_data_type
, size_t binding_idx
)
576 struct wined3d_shader_resource_binding
*binding
;
577 SIZE_T binding_count
= bindings
->count
;
579 if (!wined3d_array_reserve((void **)&bindings
->bindings
, &bindings
->size
,
580 binding_count
+ 1, sizeof(*bindings
->bindings
)))
583 binding
= &bindings
->bindings
[binding_count
];
584 binding
->shader_type
= shader_type
;
585 binding
->shader_descriptor_type
= shader_descriptor_type
;
586 binding
->resource_idx
= resource_idx
;
587 binding
->resource_type
= resource_type
;
588 binding
->resource_data_type
= resource_data_type
;
589 binding
->binding_idx
= binding_idx
;
595 static VkDescriptorType
vk_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type
,
596 enum vkd3d_shader_resource_type resource_type
)
600 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
:
601 return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
;
603 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
:
604 if (resource_type
== VKD3D_SHADER_RESOURCE_BUFFER
)
605 return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
;
606 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
;
608 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
:
609 if (resource_type
== VKD3D_SHADER_RESOURCE_BUFFER
)
610 return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
;
611 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
;
613 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
:
614 return VK_DESCRIPTOR_TYPE_SAMPLER
;
617 FIXME("Unhandled descriptor type %#x.\n", type
);
622 static enum wined3d_shader_descriptor_type
wined3d_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type
)
626 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
:
627 return WINED3D_SHADER_DESCRIPTOR_TYPE_CBV
;
629 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
:
630 return WINED3D_SHADER_DESCRIPTOR_TYPE_SRV
;
632 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
:
633 return WINED3D_SHADER_DESCRIPTOR_TYPE_UAV
;
635 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
:
636 return WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
;
639 FIXME("Unhandled descriptor type %#x.\n", type
);
644 static enum wined3d_shader_resource_type
wined3d_shader_resource_type_from_vkd3d(enum vkd3d_shader_resource_type t
)
646 return (enum wined3d_shader_resource_type
)t
;
649 static enum wined3d_data_type
wined3d_data_type_from_vkd3d(enum vkd3d_shader_resource_data_type t
)
653 case VKD3D_SHADER_RESOURCE_DATA_UNORM
:
654 return WINED3D_DATA_UNORM
;
655 case VKD3D_SHADER_RESOURCE_DATA_SNORM
:
656 return WINED3D_DATA_SNORM
;
657 case VKD3D_SHADER_RESOURCE_DATA_INT
:
658 return WINED3D_DATA_INT
;
659 case VKD3D_SHADER_RESOURCE_DATA_UINT
:
660 return WINED3D_DATA_UINT
;
661 case VKD3D_SHADER_RESOURCE_DATA_FLOAT
:
662 return WINED3D_DATA_FLOAT
;
664 FIXME("Unhandled resource data type %#x.\n", t
);
665 return WINED3D_DATA_FLOAT
;
669 static bool shader_spirv_resource_bindings_init(struct shader_spirv_resource_bindings
*bindings
,
670 struct wined3d_shader_resource_bindings
*wined3d_bindings
,
671 const struct wined3d_state
*state
, uint32_t shader_mask
)
673 struct vkd3d_shader_scan_descriptor_info
*descriptor_info
;
674 enum wined3d_shader_descriptor_type wined3d_type
;
675 enum vkd3d_shader_visibility shader_visibility
;
676 enum wined3d_shader_type shader_type
;
677 VkDescriptorType vk_descriptor_type
;
678 VkShaderStageFlagBits vk_stage
;
679 struct wined3d_shader
*shader
;
683 bindings
->binding_count
= 0;
684 bindings
->uav_counter_count
= 0;
685 bindings
->vk_binding_count
= 0;
686 bindings
->so_stage
= WINED3D_SHADER_TYPE_GEOMETRY
;
687 wined3d_bindings
->count
= 0;
689 for (shader_type
= 0; shader_type
< WINED3D_SHADER_TYPE_COUNT
; ++shader_type
)
691 bindings
->binding_base
[shader_type
] = bindings
->vk_binding_count
;
693 if (!(shader_mask
& (1u << shader_type
)) || !(shader
= state
->shader
[shader_type
]))
696 if (shader_type
== WINED3D_SHADER_TYPE_COMPUTE
)
698 descriptor_info
= &((struct shader_spirv_compute_program_vk
*)shader
->backend_data
)->descriptor_info
;
702 descriptor_info
= &((struct shader_spirv_graphics_program_vk
*)shader
->backend_data
)->descriptor_info
;
703 if (shader_type
== WINED3D_SHADER_TYPE_GEOMETRY
&& !shader
->function
)
704 bindings
->so_stage
= WINED3D_SHADER_TYPE_VERTEX
;
707 vk_stage
= vk_shader_stage_from_wined3d(shader_type
);
708 shader_visibility
= vkd3d_shader_visibility_from_wined3d(shader_type
);
710 for (i
= 0; i
< descriptor_info
->descriptor_count
; ++i
)
712 struct vkd3d_shader_descriptor_info
*d
= &descriptor_info
->descriptors
[i
];
715 if (d
->register_space
)
717 WARN("Unsupported register space %u.\n", d
->register_space
);
721 if (d
->resource_type
== VKD3D_SHADER_RESOURCE_BUFFER
)
722 flags
= VKD3D_SHADER_BINDING_FLAG_BUFFER
;
724 flags
= VKD3D_SHADER_BINDING_FLAG_IMAGE
;
726 vk_descriptor_type
= vk_descriptor_type_from_vkd3d(d
->type
, d
->resource_type
);
727 if (!shader_spirv_resource_bindings_add_binding(bindings
, d
->type
, vk_descriptor_type
,
728 d
->register_index
, shader_visibility
, vk_stage
, flags
, &binding_idx
))
731 wined3d_type
= wined3d_descriptor_type_from_vkd3d(d
->type
);
732 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings
, shader_type
,
733 wined3d_type
, d
->register_index
, wined3d_shader_resource_type_from_vkd3d(d
->resource_type
),
734 wined3d_data_type_from_vkd3d(d
->resource_data_type
), binding_idx
))
737 if (d
->type
== VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
738 && (d
->flags
& VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER
))
740 if (!shader_spirv_resource_bindings_add_uav_counter_binding(bindings
,
741 d
->register_index
, shader_visibility
, vk_stage
, &binding_idx
))
743 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings
,
744 shader_type
, WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER
, d
->register_index
,
745 WINED3D_SHADER_RESOURCE_BUFFER
, WINED3D_DATA_UINT
, binding_idx
))
754 static void shader_spirv_scan_shader(struct wined3d_shader
*shader
,
755 struct vkd3d_shader_scan_descriptor_info
*descriptor_info
)
757 struct vkd3d_shader_compile_info info
;
761 memset(descriptor_info
, 0, sizeof(*descriptor_info
));
762 descriptor_info
->type
= VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO
;
764 info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO
;
765 info
.next
= descriptor_info
;
766 info
.source
.code
= shader
->byte_code
;
767 info
.source
.size
= shader
->byte_code_size
;
768 info
.source_type
= VKD3D_SHADER_SOURCE_DXBC_TPF
;
769 info
.target_type
= VKD3D_SHADER_TARGET_SPIRV_BINARY
;
771 info
.option_count
= 0;
772 info
.log_level
= VKD3D_SHADER_LOG_WARNING
;
773 info
.source_name
= NULL
;
775 if ((ret
= vkd3d_shader_scan(&info
, &messages
)) < 0)
776 ERR("Failed to scan shader, ret %d.\n", ret
);
777 if (messages
&& *messages
&& FIXME_ON(d3d_shader
))
779 const char *ptr
= messages
;
782 FIXME("Shader log:\n");
783 while ((line
= get_line(&ptr
)))
785 FIXME(" %.*s", (int)(ptr
- line
), line
);
789 vkd3d_shader_free_messages(messages
);
792 static void shader_spirv_precompile_compute(struct wined3d_shader
*shader
)
794 struct shader_spirv_compute_program_vk
*program_vk
;
796 if (!(program_vk
= shader
->backend_data
))
798 if (!(program_vk
= heap_alloc_zero(sizeof(*program_vk
))))
799 ERR("Failed to allocate program.\n");
800 shader
->backend_data
= program_vk
;
803 shader_spirv_scan_shader(shader
, &program_vk
->descriptor_info
);
806 static void shader_spirv_precompile(void *shader_priv
, struct wined3d_shader
*shader
)
808 struct shader_spirv_graphics_program_vk
*program_vk
;
810 TRACE("shader_priv %p, shader %p.\n", shader_priv
, shader
);
812 if (shader
->reg_maps
.shader_version
.type
== WINED3D_SHADER_TYPE_COMPUTE
)
814 shader_spirv_precompile_compute(shader
);
818 if (!(program_vk
= shader
->backend_data
))
820 if (!(program_vk
= heap_alloc_zero(sizeof(*program_vk
))))
821 ERR("Failed to allocate program.\n");
822 shader
->backend_data
= program_vk
;
825 shader_spirv_scan_shader(shader
, &program_vk
->descriptor_info
);
828 static void shader_spirv_select(void *shader_priv
, struct wined3d_context
*context
,
829 const struct wined3d_state
*state
)
831 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
832 struct shader_spirv_graphics_program_variant_vk
*variant_vk
;
833 struct shader_spirv_resource_bindings
*bindings
;
834 size_t binding_base
[WINED3D_SHADER_TYPE_COUNT
];
835 struct wined3d_pipeline_layout_vk
*layout_vk
;
836 struct shader_spirv_priv
*priv
= shader_priv
;
837 enum wined3d_shader_type shader_type
;
838 struct wined3d_shader
*shader
;
840 priv
->vertex_pipe
->vp_enable(context
, !use_vs(state
));
841 priv
->fragment_pipe
->fp_enable(context
, !use_ps(state
));
843 bindings
= &priv
->bindings
;
844 memcpy(binding_base
, bindings
->binding_base
, sizeof(bindings
->binding_base
));
845 if (!shader_spirv_resource_bindings_init(bindings
, &context_vk
->graphics
.bindings
,
846 state
, ~(1u << WINED3D_SHADER_TYPE_COMPUTE
)))
848 ERR("Failed to initialise shader resource bindings.\n");
851 if (context
->shader_update_mask
& (1u << WINED3D_SHADER_TYPE_GEOMETRY
))
852 context
->shader_update_mask
|= 1u << bindings
->so_stage
;
854 layout_vk
= wined3d_context_vk_get_pipeline_layout(context_vk
, bindings
->vk_bindings
, bindings
->vk_binding_count
);
855 context_vk
->graphics
.vk_set_layout
= layout_vk
->vk_set_layout
;
856 context_vk
->graphics
.vk_pipeline_layout
= layout_vk
->vk_pipeline_layout
;
858 for (shader_type
= 0; shader_type
< ARRAY_SIZE(context_vk
->graphics
.vk_modules
); ++shader_type
)
860 if (!(context
->shader_update_mask
& (1u << shader_type
)) && (!context_vk
->graphics
.vk_modules
[shader_type
]
861 || binding_base
[shader_type
] == bindings
->binding_base
[shader_type
]))
864 if (!(shader
= state
->shader
[shader_type
]) || !shader
->function
)
866 context_vk
->graphics
.vk_modules
[shader_type
] = VK_NULL_HANDLE
;
870 if (!(variant_vk
= shader_spirv_find_graphics_program_variant_vk(priv
, context_vk
, shader
, state
, bindings
)))
872 context_vk
->graphics
.vk_modules
[shader_type
] = variant_vk
->vk_module
;
878 context_vk
->graphics
.vk_set_layout
= VK_NULL_HANDLE
;
879 context_vk
->graphics
.vk_pipeline_layout
= VK_NULL_HANDLE
;
882 static void shader_spirv_select_compute(void *shader_priv
,
883 struct wined3d_context
*context
, const struct wined3d_state
*state
)
885 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
886 struct shader_spirv_compute_program_vk
*program
;
887 struct shader_spirv_priv
*priv
= shader_priv
;
888 struct wined3d_shader
*shader
;
890 if (!shader_spirv_resource_bindings_init(&priv
->bindings
,
891 &context_vk
->compute
.bindings
, state
, 1u << WINED3D_SHADER_TYPE_COMPUTE
))
892 ERR("Failed to initialise shader resource bindings.\n");
894 if ((shader
= state
->shader
[WINED3D_SHADER_TYPE_COMPUTE
]))
895 program
= shader_spirv_find_compute_program_vk(priv
, context_vk
, shader
, &priv
->bindings
);
901 context_vk
->compute
.vk_pipeline
= program
->vk_pipeline
;
902 context_vk
->compute
.vk_set_layout
= program
->vk_set_layout
;
903 context_vk
->compute
.vk_pipeline_layout
= program
->vk_pipeline_layout
;
907 context_vk
->compute
.vk_pipeline
= VK_NULL_HANDLE
;
908 context_vk
->compute
.vk_set_layout
= VK_NULL_HANDLE
;
909 context_vk
->compute
.vk_pipeline_layout
= VK_NULL_HANDLE
;
913 static void shader_spirv_disable(void *shader_priv
, struct wined3d_context
*context
)
915 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
916 struct shader_spirv_priv
*priv
= shader_priv
;
918 priv
->vertex_pipe
->vp_enable(context
, false);
919 priv
->fragment_pipe
->fp_enable(context
, false);
921 context_vk
->compute
.vk_pipeline
= VK_NULL_HANDLE
;
922 context
->shader_update_mask
= (1u << WINED3D_SHADER_TYPE_PIXEL
)
923 | (1u << WINED3D_SHADER_TYPE_VERTEX
)
924 | (1u << WINED3D_SHADER_TYPE_GEOMETRY
)
925 | (1u << WINED3D_SHADER_TYPE_HULL
)
926 | (1u << WINED3D_SHADER_TYPE_DOMAIN
)
927 | (1u << WINED3D_SHADER_TYPE_COMPUTE
);
930 static void shader_spirv_update_float_vertex_constants(struct wined3d_device
*device
, UINT start
, UINT count
)
932 WARN("Not implemented.\n");
935 static void shader_spirv_update_float_pixel_constants(struct wined3d_device
*device
, UINT start
, UINT count
)
937 WARN("Not implemented.\n");
940 static void shader_spirv_load_constants(void *shader_priv
, struct wined3d_context
*context
,
941 const struct wined3d_state
*state
)
943 WARN("Not implemented.\n");
946 static void shader_spirv_invalidate_compute_program(struct wined3d_context_vk
*context_vk
,
947 const struct shader_spirv_compute_program_vk
*program
)
949 if (context_vk
->compute
.vk_pipeline
== program
->vk_pipeline
)
951 context_vk
->c
.shader_update_mask
|= (1u << WINED3D_SHADER_TYPE_COMPUTE
);
952 context_vk
->compute
.vk_pipeline
= VK_NULL_HANDLE
;
956 static void shader_spirv_invalidate_contexts_compute_program(struct wined3d_device
*device
,
957 const struct shader_spirv_compute_program_vk
*program
)
961 for (i
= 0; i
< device
->context_count
; ++i
)
963 shader_spirv_invalidate_compute_program(wined3d_context_vk(device
->contexts
[i
]), program
);
967 static void shader_spirv_invalidate_graphics_program_variant(struct wined3d_context_vk
*context_vk
,
968 const struct shader_spirv_graphics_program_variant_vk
*variant
)
970 enum wined3d_shader_type shader_type
;
972 for (shader_type
= 0; shader_type
< WINED3D_SHADER_TYPE_GRAPHICS_COUNT
; ++shader_type
)
974 if (context_vk
->graphics
.vk_modules
[shader_type
] != variant
->vk_module
)
977 context_vk
->graphics
.vk_modules
[shader_type
] = VK_NULL_HANDLE
;
978 context_vk
->c
.shader_update_mask
|= (1u << shader_type
);
982 static void shader_spirv_invalidate_contexts_graphics_program_variant(struct wined3d_device
*device
,
983 const struct shader_spirv_graphics_program_variant_vk
*variant
)
987 for (i
= 0; i
< device
->context_count
; ++i
)
989 shader_spirv_invalidate_graphics_program_variant(wined3d_context_vk(device
->contexts
[i
]), variant
);
993 static void shader_spirv_destroy_compute_vk(struct wined3d_shader
*shader
)
995 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(shader
->device
);
996 struct shader_spirv_compute_program_vk
*program
= shader
->backend_data
;
997 struct wined3d_vk_info
*vk_info
= &device_vk
->vk_info
;
999 shader_spirv_invalidate_contexts_compute_program(&device_vk
->d
, program
);
1000 VK_CALL(vkDestroyPipeline(device_vk
->vk_device
, program
->vk_pipeline
, NULL
));
1001 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, program
->vk_module
, NULL
));
1002 vkd3d_shader_free_scan_descriptor_info(&program
->descriptor_info
);
1003 shader
->backend_data
= NULL
;
1007 static void shader_spirv_destroy(struct wined3d_shader
*shader
)
1009 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(shader
->device
);
1010 struct shader_spirv_graphics_program_variant_vk
*variant_vk
;
1011 struct wined3d_vk_info
*vk_info
= &device_vk
->vk_info
;
1012 struct shader_spirv_graphics_program_vk
*program_vk
;
1015 if (!shader
->backend_data
)
1018 if (shader
->reg_maps
.shader_version
.type
== WINED3D_SHADER_TYPE_COMPUTE
)
1020 shader_spirv_destroy_compute_vk(shader
);
1024 program_vk
= shader
->backend_data
;
1025 for (i
= 0; i
< program_vk
->variant_count
; ++i
)
1027 variant_vk
= &program_vk
->variants
[i
];
1028 shader_spirv_invalidate_contexts_graphics_program_variant(&device_vk
->d
, variant_vk
);
1029 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, variant_vk
->vk_module
, NULL
));
1031 heap_free(program_vk
->variants
);
1032 vkd3d_shader_free_scan_descriptor_info(&program_vk
->descriptor_info
);
1034 shader
->backend_data
= NULL
;
1035 heap_free(program_vk
);
1038 static HRESULT
shader_spirv_alloc(struct wined3d_device
*device
,
1039 const struct wined3d_vertex_pipe_ops
*vertex_pipe
, const struct wined3d_fragment_pipe_ops
*fragment_pipe
)
1041 struct fragment_caps fragment_caps
;
1042 void *vertex_priv
, *fragment_priv
;
1043 struct shader_spirv_priv
*priv
;
1045 if (!(priv
= heap_alloc(sizeof(*priv
))))
1046 return E_OUTOFMEMORY
;
1048 if (!(vertex_priv
= vertex_pipe
->vp_alloc(&spirv_shader_backend_vk
, priv
)))
1050 ERR("Failed to initialise vertex pipe.\n");
1055 if (!(fragment_priv
= fragment_pipe
->alloc_private(&spirv_shader_backend_vk
, priv
)))
1057 ERR("Failed to initialise fragment pipe.\n");
1058 vertex_pipe
->vp_free(device
, NULL
);
1063 priv
->vertex_pipe
= vertex_pipe
;
1064 priv
->fragment_pipe
= fragment_pipe
;
1065 fragment_pipe
->get_caps(device
->adapter
, &fragment_caps
);
1066 priv
->ffp_proj_control
= fragment_caps
.wined3d_caps
& WINED3D_FRAGMENT_CAP_PROJ_CONTROL
;
1067 memset(&priv
->bindings
, 0, sizeof(priv
->bindings
));
1069 device
->vertex_priv
= vertex_priv
;
1070 device
->fragment_priv
= fragment_priv
;
1071 device
->shader_priv
= priv
;
1076 static void shader_spirv_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1078 struct shader_spirv_priv
*priv
= device
->shader_priv
;
1080 shader_spirv_resource_bindings_cleanup(&priv
->bindings
);
1081 priv
->fragment_pipe
->free_private(device
, context
);
1082 priv
->vertex_pipe
->vp_free(device
, context
);
1086 static BOOL
shader_spirv_allocate_context_data(struct wined3d_context
*context
)
1091 static void shader_spirv_free_context_data(struct wined3d_context
*context
)
1095 static void shader_spirv_init_context_state(struct wined3d_context
*context
)
1099 static void shader_spirv_get_caps(const struct wined3d_adapter
*adapter
, struct shader_caps
*caps
)
1101 caps
->vs_version
= min(wined3d_settings
.max_sm_vs
, 5);
1102 caps
->hs_version
= min(wined3d_settings
.max_sm_hs
, 5);
1103 caps
->ds_version
= min(wined3d_settings
.max_sm_ds
, 5);
1104 caps
->gs_version
= min(wined3d_settings
.max_sm_gs
, 5);
1105 caps
->ps_version
= min(wined3d_settings
.max_sm_ps
, 5);
1106 caps
->cs_version
= min(wined3d_settings
.max_sm_cs
, 5);
1108 caps
->vs_uniform_count
= WINED3D_MAX_VS_CONSTS_F
;
1109 caps
->ps_uniform_count
= WINED3D_MAX_PS_CONSTS_F
;
1110 caps
->ps_1x_max_value
= FLT_MAX
;
1111 caps
->varying_count
= 0;
1112 caps
->wined3d_caps
= WINED3D_SHADER_CAP_VS_CLIPPING
1113 | WINED3D_SHADER_CAP_SRGB_WRITE
1114 | WINED3D_SHADER_CAP_FULL_FFP_VARYINGS
;
1117 static BOOL
shader_spirv_color_fixup_supported(struct color_fixup_desc fixup
)
1119 return is_identity_fixup(fixup
);
1122 static BOOL
shader_spirv_has_ffp_proj_control(void *shader_priv
)
1124 struct shader_spirv_priv
*priv
= shader_priv
;
1126 return priv
->ffp_proj_control
;
1129 static uint64_t shader_spirv_compile(struct wined3d_context
*context
, const struct wined3d_shader_desc
*shader_desc
,
1130 enum wined3d_shader_type shader_type
)
1132 struct shader_spirv_resource_bindings bindings
= {0};
1133 return (uint64_t)shader_spirv_compile_shader(wined3d_context_vk(context
), shader_desc
, shader_type
, NULL
, &bindings
, NULL
);
1136 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk
=
1138 .shader_handle_instruction
= shader_spirv_handle_instruction
,
1139 .shader_precompile
= shader_spirv_precompile
,
1140 .shader_select
= shader_spirv_select
,
1141 .shader_select_compute
= shader_spirv_select_compute
,
1142 .shader_disable
= shader_spirv_disable
,
1143 .shader_update_float_vertex_constants
= shader_spirv_update_float_vertex_constants
,
1144 .shader_update_float_pixel_constants
= shader_spirv_update_float_pixel_constants
,
1145 .shader_load_constants
= shader_spirv_load_constants
,
1146 .shader_destroy
= shader_spirv_destroy
,
1147 .shader_alloc_private
= shader_spirv_alloc
,
1148 .shader_free_private
= shader_spirv_free
,
1149 .shader_allocate_context_data
= shader_spirv_allocate_context_data
,
1150 .shader_free_context_data
= shader_spirv_free_context_data
,
1151 .shader_init_context_state
= shader_spirv_init_context_state
,
1152 .shader_get_caps
= shader_spirv_get_caps
,
1153 .shader_color_fixup_supported
= shader_spirv_color_fixup_supported
,
1154 .shader_has_ffp_proj_control
= shader_spirv_has_ffp_proj_control
,
1155 .shader_compile
= shader_spirv_compile
,
1158 const struct wined3d_shader_backend_ops
*wined3d_spirv_shader_backend_init_vk(void)
1160 if (!wined3d_init_vkd3d())
1163 return &spirv_shader_backend_vk
;
1166 void wined3d_spirv_shader_backend_cleanup(void)
1168 wined3d_unload_vkd3d_shader();
1171 static void spirv_vertex_pipe_vk_vp_enable(const struct wined3d_context
*context
, BOOL enable
)
1173 /* Nothing to do. */
1176 static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter
*adapter
, struct wined3d_vertex_caps
*caps
)
1178 memset(caps
, 0, sizeof(*caps
));
1181 static uint32_t spirv_vertex_pipe_vk_vp_get_emul_mask(const struct wined3d_gl_info
*gl_info
)
1186 static void *spirv_vertex_pipe_vk_vp_alloc(const struct wined3d_shader_backend_ops
*shader_backend
, void *shader_priv
)
1188 if (shader_backend
!= &spirv_shader_backend_vk
)
1190 FIXME("SPIR-V vertex pipe without SPIR-V shader backend not implemented.\n");
1197 static void spirv_vertex_pipe_vk_vp_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1199 /* Nothing to do. */
1202 static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states
[] =
1204 {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE
), {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE
), state_nop
}},
1205 {STATE_RENDER(WINED3D_RS_CLIPPING
), {STATE_RENDER(WINED3D_RS_CLIPPING
), state_nop
}},
1206 {STATE_RENDER(WINED3D_RS_LIGHTING
), {STATE_RENDER(WINED3D_RS_LIGHTING
), state_nop
}},
1207 {STATE_RENDER(WINED3D_RS_AMBIENT
), {STATE_RENDER(WINED3D_RS_AMBIENT
), state_nop
}},
1208 {STATE_RENDER(WINED3D_RS_COLORVERTEX
), {STATE_RENDER(WINED3D_RS_COLORVERTEX
), state_nop
}},
1209 {STATE_RENDER(WINED3D_RS_LOCALVIEWER
), {STATE_RENDER(WINED3D_RS_LOCALVIEWER
), state_nop
}},
1210 {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS
), {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS
), state_nop
}},
1211 {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE
), state_nop
}},
1212 {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE
), state_nop
}},
1213 {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE
), state_nop
}},
1214 {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE
), state_nop
}},
1215 {STATE_RENDER(WINED3D_RS_VERTEXBLEND
), {STATE_RENDER(WINED3D_RS_VERTEXBLEND
), state_nop
}},
1216 {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE
), {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE
), state_nop
}},
1217 {STATE_RENDER(WINED3D_RS_POINTSIZE
), {STATE_RENDER(WINED3D_RS_POINTSIZE
), state_nop
}},
1218 {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN
), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN
), state_nop
}},
1219 {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE
), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE
), state_nop
}},
1220 {STATE_RENDER(WINED3D_RS_POINTSCALE_A
), {STATE_RENDER(WINED3D_RS_POINTSCALE_A
), state_nop
}},
1221 {STATE_RENDER(WINED3D_RS_POINTSCALE_B
), {STATE_RENDER(WINED3D_RS_POINTSCALE_B
), state_nop
}},
1222 {STATE_RENDER(WINED3D_RS_POINTSCALE_C
), {STATE_RENDER(WINED3D_RS_POINTSCALE_C
), state_nop
}},
1223 {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX
), {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX
), state_nop
}},
1224 {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE
), {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE
), state_nop
}},
1225 {STATE_RENDER(WINED3D_RS_TWEENFACTOR
), {STATE_RENDER(WINED3D_RS_TWEENFACTOR
), state_nop
}},
1226 {STATE_MATERIAL
, {STATE_MATERIAL
, state_nop
}},
1227 {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
), state_nop
}},
1228 {STATE_LIGHT_TYPE
, {STATE_LIGHT_TYPE
, state_nop
}},
1229 {0}, /* Terminate */
1232 static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk
=
1234 .vp_enable
= spirv_vertex_pipe_vk_vp_enable
,
1235 .vp_get_caps
= spirv_vertex_pipe_vk_vp_get_caps
,
1236 .vp_get_emul_mask
= spirv_vertex_pipe_vk_vp_get_emul_mask
,
1237 .vp_alloc
= spirv_vertex_pipe_vk_vp_alloc
,
1238 .vp_free
= spirv_vertex_pipe_vk_vp_free
,
1239 .vp_states
= spirv_vertex_pipe_vk_vp_states
,
1242 const struct wined3d_vertex_pipe_ops
*wined3d_spirv_vertex_pipe_init_vk(void)
1244 return &spirv_vertex_pipe_vk
;
1247 static void spirv_fragment_pipe_vk_fp_enable(const struct wined3d_context
*context
, BOOL enable
)
1249 /* Nothing to do. */
1252 static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter
*adapter
, struct fragment_caps
*caps
)
1254 memset(caps
, 0, sizeof(*caps
));
1257 static uint32_t spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_gl_info
*gl_info
)
1262 static void *spirv_fragment_pipe_vk_fp_alloc(const struct wined3d_shader_backend_ops
*shader_backend
, void *shader_priv
)
1264 if (shader_backend
!= &spirv_shader_backend_vk
)
1266 FIXME("SPIR-V fragment pipe without SPIR-V shader backend not implemented.\n");
1273 static void spirv_fragment_pipe_vk_fp_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1275 /* Nothing to do. */
1278 static BOOL
spirv_fragment_pipe_vk_fp_alloc_context_data(struct wined3d_context
*context
)
1283 static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context
*context
)
1285 /* Nothing to do. */
1288 static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states
[] =
1290 {STATE_RENDER(WINED3D_RS_SHADEMODE
), {STATE_RENDER(WINED3D_RS_SHADEMODE
), state_nop
}},
1291 {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE
), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE
), state_nop
}},
1292 {STATE_RENDER(WINED3D_RS_ALPHAREF
), {STATE_RENDER(WINED3D_RS_ALPHAREF
), state_nop
}},
1293 {STATE_RENDER(WINED3D_RS_ALPHAFUNC
), {STATE_RENDER(WINED3D_RS_ALPHAFUNC
), state_nop
}},
1294 {STATE_RENDER(WINED3D_RS_FOGENABLE
), {STATE_RENDER(WINED3D_RS_FOGENABLE
), state_nop
}},
1295 {STATE_RENDER(WINED3D_RS_SPECULARENABLE
), {STATE_RENDER(WINED3D_RS_SPECULARENABLE
), state_nop
}},
1296 {STATE_RENDER(WINED3D_RS_FOGCOLOR
), {STATE_RENDER(WINED3D_RS_FOGCOLOR
), state_nop
}},
1297 {STATE_RENDER(WINED3D_RS_FOGTABLEMODE
), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE
), state_nop
}},
1298 {STATE_RENDER(WINED3D_RS_FOGSTART
), {STATE_RENDER(WINED3D_RS_FOGSTART
), state_nop
}},
1299 {STATE_RENDER(WINED3D_RS_FOGEND
), {STATE_RENDER(WINED3D_RS_FOGEND
), state_nop
}},
1300 {STATE_RENDER(WINED3D_RS_FOGDENSITY
), {STATE_RENDER(WINED3D_RS_FOGDENSITY
), state_nop
}},
1301 {STATE_RENDER(WINED3D_RS_COLORKEYENABLE
), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE
), state_nop
}},
1302 {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR
), {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR
), state_nop
}},
1303 {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE
), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE
), state_nop
}},
1304 {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE
), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE
), state_nop
}},
1305 {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE
), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE
), state_nop
}},
1306 {STATE_POINT_ENABLE
, {STATE_POINT_ENABLE
, state_nop
}},
1307 {STATE_COLOR_KEY
, {STATE_COLOR_KEY
, state_nop
}},
1308 {0}, /* Terminate */
1311 static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk
=
1313 .fp_enable
= spirv_fragment_pipe_vk_fp_enable
,
1314 .get_caps
= spirv_fragment_pipe_vk_fp_get_caps
,
1315 .get_emul_mask
= spirv_fragment_pipe_vk_fp_get_emul_mask
,
1316 .alloc_private
= spirv_fragment_pipe_vk_fp_alloc
,
1317 .free_private
= spirv_fragment_pipe_vk_fp_free
,
1318 .allocate_context_data
= spirv_fragment_pipe_vk_fp_alloc_context_data
,
1319 .free_context_data
= spirv_fragment_pipe_vk_fp_free_context_data
,
1320 .color_fixup_supported
= shader_spirv_color_fixup_supported
,
1321 .states
= spirv_fragment_pipe_vk_fp_states
,
1324 const struct wined3d_fragment_pipe_ops
*wined3d_spirv_fragment_pipe_init_vk(void)
1326 return &spirv_fragment_pipe_vk
;
1331 const struct wined3d_shader_backend_ops
*wined3d_spirv_shader_backend_init_vk(void)
1333 ERR_(winediag
)("Wine was built without libvkd3d-shader support.\n");
1337 void wined3d_spirv_shader_backend_cleanup(void)
1341 const struct wined3d_vertex_pipe_ops
*wined3d_spirv_vertex_pipe_init_vk(void)
1343 return &none_vertex_pipe
;
1346 const struct wined3d_fragment_pipe_ops
*wined3d_spirv_fragment_pipe_init_vk(void)
1348 return &none_fragment_pipe
;
1351 #endif /* defined(SONAME_LIBVKD3D_SHADER) */