2 * Copyright 2018 Henri Verbeet for CodeWeavers
3 * Copyright 2019 Józef Kucia for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "wined3d_private.h"
21 #include "wined3d_vk.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader
);
25 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk
;
27 static const struct vkd3d_shader_compile_option spirv_compile_options
[] =
29 {VKD3D_SHADER_COMPILE_OPTION_API_VERSION
, VKD3D_SHADER_API_VERSION_1_7
},
30 {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE
, 0},
33 struct shader_spirv_resource_bindings
35 struct vkd3d_shader_resource_binding
*bindings
;
36 SIZE_T bindings_size
, binding_count
;
38 struct vkd3d_shader_uav_counter_binding uav_counters
[MAX_UNORDERED_ACCESS_VIEWS
];
39 SIZE_T uav_counter_count
;
41 VkDescriptorSetLayoutBinding
*vk_bindings
;
42 SIZE_T vk_bindings_size
, vk_binding_count
;
44 size_t binding_base
[WINED3D_SHADER_TYPE_COUNT
];
45 enum wined3d_shader_type so_stage
;
48 struct shader_spirv_priv
50 const struct wined3d_vertex_pipe_ops
*vertex_pipe
;
51 const struct wined3d_fragment_pipe_ops
*fragment_pipe
;
53 struct shader_spirv_resource_bindings bindings
;
56 #define MAX_SM1_INTER_STAGE_VARYINGS 12
58 struct shader_spirv_compile_arguments
64 struct vkd3d_shader_varying_map varying_map
[MAX_SM1_INTER_STAGE_VARYINGS
];
65 unsigned int varying_count
;
69 uint32_t alpha_swizzle
;
70 unsigned int sample_count
;
71 bool dual_source_blending
;
76 struct shader_spirv_graphics_program_variant_vk
78 struct shader_spirv_compile_arguments compile_args
;
79 const struct wined3d_stream_output_desc
*so_desc
;
82 VkShaderModule vk_module
;
85 struct shader_spirv_graphics_program_vk
87 struct shader_spirv_graphics_program_variant_vk
*variants
;
88 SIZE_T variants_size
, variant_count
;
90 struct vkd3d_shader_scan_descriptor_info descriptor_info
;
91 struct vkd3d_shader_scan_signature_info signature_info
;
94 struct shader_spirv_compute_program_vk
96 VkShaderModule vk_module
;
97 VkPipeline vk_pipeline
;
98 VkPipelineLayout vk_pipeline_layout
;
99 VkDescriptorSetLayout vk_set_layout
;
101 struct vkd3d_shader_scan_descriptor_info descriptor_info
;
104 struct wined3d_shader_spirv_compile_args
106 struct vkd3d_shader_varying_map_info varying_map
;
107 struct vkd3d_shader_spirv_target_info spirv_target
;
108 enum vkd3d_shader_spirv_extension extensions
[1];
109 struct vkd3d_shader_parameter sample_count
;
110 unsigned int ps_alpha_swizzle
[WINED3D_MAX_RENDER_TARGETS
];
113 struct wined3d_shader_spirv_shader_interface
115 struct vkd3d_shader_interface_info vkd3d_interface
;
116 struct vkd3d_shader_transform_feedback_info xfb_info
;
119 static void shader_spirv_handle_instruction(const struct wined3d_shader_instruction
*ins
)
123 static void shader_spirv_compile_arguments_init(struct shader_spirv_compile_arguments
*args
,
124 const struct wined3d_context
*context
, const struct wined3d_shader
*shader
,
125 const struct wined3d_state
*state
, unsigned int sample_count
)
127 struct wined3d_rendertarget_view
*rtv
;
130 memset(args
, 0, sizeof(*args
));
132 switch (shader
->reg_maps
.shader_version
.type
)
134 case WINED3D_SHADER_TYPE_PIXEL
:
135 for (i
= 0; i
< ARRAY_SIZE(state
->fb
.render_targets
); ++i
)
137 if (!(rtv
= state
->fb
.render_targets
[i
]) || rtv
->format
->id
== WINED3DFMT_NULL
)
139 if (rtv
->format
->id
== WINED3DFMT_A8_UNORM
&& !is_identity_fixup(rtv
->format
->color_fixup
))
140 args
->u
.fs
.alpha_swizzle
|= 1u << i
;
142 args
->u
.fs
.sample_count
= sample_count
;
143 args
->u
.fs
.dual_source_blending
= state
->blend_state
&& state
->blend_state
->dual_source
;
146 case WINED3D_SHADER_TYPE_VERTEX
:
148 struct wined3d_shader
*ps
= state
->shader
[WINED3D_SHADER_TYPE_PIXEL
];
150 if (shader
->reg_maps
.shader_version
.major
< 4 && ps
)
152 struct shader_spirv_graphics_program_vk
*vs_program
= shader
->backend_data
;
153 struct shader_spirv_graphics_program_vk
*ps_program
= ps
->backend_data
;
155 if (ps_program
->signature_info
.input
.element_count
> ARRAY_SIZE(args
->u
.vs
.varying_map
))
156 ERR("Unexpected inter-stage varying count %u.\n", ps_program
->signature_info
.input
.element_count
);
157 vkd3d_shader_build_varying_map(&vs_program
->signature_info
.output
,
158 &ps_program
->signature_info
.input
, &args
->u
.vs
.varying_count
, args
->u
.vs
.varying_map
);
168 static void shader_spirv_init_compile_args(const struct wined3d_vk_info
*vk_info
,
169 struct wined3d_shader_spirv_compile_args
*args
,
170 struct vkd3d_shader_interface_info
*vkd3d_interface
, enum vkd3d_shader_spirv_environment environment
,
171 enum wined3d_shader_type shader_type
, enum vkd3d_shader_source_type source_type
,
172 const struct shader_spirv_compile_arguments
*compile_args
)
176 memset(args
, 0, sizeof(*args
));
177 args
->spirv_target
.type
= VKD3D_SHADER_STRUCTURE_TYPE_SPIRV_TARGET_INFO
;
178 args
->spirv_target
.next
= vkd3d_interface
;
179 args
->spirv_target
.entry_point
= "main";
180 args
->spirv_target
.environment
= environment
;
182 args
->spirv_target
.extensions
= args
->extensions
;
184 if (vk_info
->supported
[WINED3D_VK_EXT_SHADER_STENCIL_EXPORT
])
185 args
->extensions
[args
->spirv_target
.extension_count
++] = VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT
;
186 assert(args
->spirv_target
.extension_count
<= ARRAY_SIZE(args
->extensions
));
188 if (shader_type
== WINED3D_SHADER_TYPE_PIXEL
)
190 unsigned int rt_alpha_swizzle
= compile_args
->u
.fs
.alpha_swizzle
;
191 struct vkd3d_shader_parameter
*shader_parameter
;
193 shader_parameter
= &args
->sample_count
;
194 shader_parameter
->name
= VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT
;
195 shader_parameter
->type
= VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT
;
196 shader_parameter
->data_type
= VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32
;
197 shader_parameter
->u
.immediate_constant
.u
.u32
= compile_args
->u
.fs
.sample_count
;
199 args
->spirv_target
.dual_source_blending
= compile_args
->u
.fs
.dual_source_blending
;
201 args
->spirv_target
.parameter_count
= 1;
202 args
->spirv_target
.parameters
= shader_parameter
;
204 for (i
= 0; i
< ARRAY_SIZE(args
->ps_alpha_swizzle
); ++i
)
206 if (rt_alpha_swizzle
&& (1u << i
))
207 args
->ps_alpha_swizzle
[i
] = VKD3D_SHADER_SWIZZLE(W
, X
, Y
, Z
);
209 args
->ps_alpha_swizzle
[i
] = VKD3D_SHADER_NO_SWIZZLE
;
212 args
->spirv_target
.output_swizzles
= args
->ps_alpha_swizzle
;
213 args
->spirv_target
.output_swizzle_count
= ARRAY_SIZE(args
->ps_alpha_swizzle
);
215 else if (shader_type
== WINED3D_SHADER_TYPE_VERTEX
)
217 if (source_type
== VKD3D_SHADER_SOURCE_D3D_BYTECODE
)
219 args
->spirv_target
.next
= &args
->varying_map
;
221 args
->varying_map
.type
= VKD3D_SHADER_STRUCTURE_TYPE_VARYING_MAP_INFO
;
222 args
->varying_map
.next
= vkd3d_interface
;
223 args
->varying_map
.varying_map
= compile_args
->u
.vs
.varying_map
;
224 args
->varying_map
.varying_count
= compile_args
->u
.vs
.varying_count
;
229 static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_shader_interface
*iface
,
230 const struct shader_spirv_resource_bindings
*b
, const struct wined3d_stream_output_desc
*so_desc
)
232 memset(iface
, 0, sizeof(*iface
));
233 iface
->vkd3d_interface
.type
= VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO
;
237 iface
->xfb_info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO
;
238 iface
->xfb_info
.next
= NULL
;
240 iface
->xfb_info
.elements
= (const struct vkd3d_shader_transform_feedback_element
*)so_desc
->elements
;
241 iface
->xfb_info
.element_count
= so_desc
->element_count
;
242 iface
->xfb_info
.buffer_strides
= so_desc
->buffer_strides
;
243 iface
->xfb_info
.buffer_stride_count
= so_desc
->buffer_stride_count
;
245 iface
->vkd3d_interface
.next
= &iface
->xfb_info
;
248 iface
->vkd3d_interface
.bindings
= b
->bindings
;
249 iface
->vkd3d_interface
.binding_count
= b
->binding_count
;
251 iface
->vkd3d_interface
.uav_counters
= b
->uav_counters
;
252 iface
->vkd3d_interface
.uav_counter_count
= b
->uav_counter_count
;
255 static VkShaderModule
shader_spirv_compile_shader(struct wined3d_context_vk
*context_vk
,
256 const struct wined3d_shader_desc
*shader_desc
, enum vkd3d_shader_source_type source_type
,
257 enum wined3d_shader_type shader_type
, const struct shader_spirv_compile_arguments
*args
,
258 const struct shader_spirv_resource_bindings
*bindings
, const struct wined3d_stream_output_desc
*so_desc
)
260 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
261 const struct wined3d_vk_info
*vk_info
= &device_vk
->vk_info
;
262 struct wined3d_shader_spirv_compile_args compile_args
;
263 struct wined3d_shader_spirv_shader_interface iface
;
264 VkShaderModuleCreateInfo shader_create_info
;
265 struct vkd3d_shader_compile_info info
;
266 struct vkd3d_shader_code spirv
;
267 VkShaderModule module
;
272 shader_spirv_init_shader_interface_vk(&iface
, bindings
, so_desc
);
273 shader_spirv_init_compile_args(vk_info
, &compile_args
, &iface
.vkd3d_interface
,
274 VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0
, shader_type
, source_type
, args
);
276 info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO
;
277 info
.next
= &compile_args
.spirv_target
;
278 info
.source
.code
= shader_desc
->byte_code
;
279 info
.source
.size
= shader_desc
->byte_code_size
;
280 info
.source_type
= source_type
;
281 info
.target_type
= VKD3D_SHADER_TARGET_SPIRV_BINARY
;
282 info
.options
= spirv_compile_options
;
283 info
.option_count
= ARRAY_SIZE(spirv_compile_options
);
284 info
.log_level
= VKD3D_SHADER_LOG_WARNING
;
285 info
.source_name
= NULL
;
287 ret
= vkd3d_shader_compile(&info
, &spirv
, &messages
);
288 if (messages
&& *messages
&& FIXME_ON(d3d_shader
))
290 const char *ptr
, *end
, *line
;
292 FIXME("Shader log:\n");
294 end
= ptr
+ strlen(ptr
);
295 while ((line
= wined3d_get_line(&ptr
, end
)))
297 FIXME(" %.*s", (int)(ptr
- line
), line
);
301 vkd3d_shader_free_messages(messages
);
305 ERR("Failed to compile shader, ret %d.\n", ret
);
306 return VK_NULL_HANDLE
;
309 shader_create_info
.sType
= VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO
;
310 shader_create_info
.pNext
= NULL
;
311 shader_create_info
.flags
= 0;
312 shader_create_info
.codeSize
= spirv
.size
;
313 shader_create_info
.pCode
= spirv
.code
;
314 if ((vr
= VK_CALL(vkCreateShaderModule(device_vk
->vk_device
, &shader_create_info
, NULL
, &module
))) < 0)
316 vkd3d_shader_free_shader_code(&spirv
);
317 WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr
));
318 return VK_NULL_HANDLE
;
321 vkd3d_shader_free_shader_code(&spirv
);
326 static struct shader_spirv_graphics_program_variant_vk
*shader_spirv_find_graphics_program_variant_vk(
327 struct shader_spirv_priv
*priv
, struct wined3d_context_vk
*context_vk
, struct wined3d_shader
*shader
,
328 const struct wined3d_state
*state
, const struct shader_spirv_resource_bindings
*bindings
)
330 enum wined3d_shader_type shader_type
= shader
->reg_maps
.shader_version
.type
;
331 struct shader_spirv_graphics_program_variant_vk
*variant_vk
;
332 size_t binding_base
= bindings
->binding_base
[shader_type
];
333 const struct wined3d_stream_output_desc
*so_desc
= NULL
;
334 struct shader_spirv_graphics_program_vk
*program_vk
;
335 struct shader_spirv_compile_arguments args
;
336 struct wined3d_shader_desc shader_desc
;
337 size_t variant_count
, i
;
339 shader_spirv_compile_arguments_init(&args
, &context_vk
->c
, shader
, state
, context_vk
->sample_count
);
340 if (bindings
->so_stage
== shader_type
)
341 so_desc
= state
->shader
[WINED3D_SHADER_TYPE_GEOMETRY
]->u
.gs
.so_desc
;
343 if (!(program_vk
= shader
->backend_data
))
346 variant_count
= program_vk
->variant_count
;
347 for (i
= 0; i
< variant_count
; ++i
)
349 variant_vk
= &program_vk
->variants
[i
];
350 if (variant_vk
->so_desc
== so_desc
&& variant_vk
->binding_base
== binding_base
351 && !memcmp(&variant_vk
->compile_args
, &args
, sizeof(args
)))
355 if (!wined3d_array_reserve((void **)&program_vk
->variants
, &program_vk
->variants_size
,
356 variant_count
+ 1, sizeof(*program_vk
->variants
)))
359 variant_vk
= &program_vk
->variants
[variant_count
];
360 variant_vk
->compile_args
= args
;
361 variant_vk
->binding_base
= binding_base
;
363 if (shader
->source_type
== VKD3D_SHADER_SOURCE_D3D_BYTECODE
)
365 shader_desc
.byte_code
= shader
->function
;
366 shader_desc
.byte_code_size
= shader
->functionLength
;
370 shader_desc
.byte_code
= shader
->byte_code
;
371 shader_desc
.byte_code_size
= shader
->byte_code_size
;
374 if (!(variant_vk
->vk_module
= shader_spirv_compile_shader(context_vk
, &shader_desc
,
375 shader
->source_type
, shader_type
, &args
, bindings
, so_desc
)))
377 ++program_vk
->variant_count
;
382 static struct shader_spirv_compute_program_vk
*shader_spirv_find_compute_program_vk(struct shader_spirv_priv
*priv
,
383 struct wined3d_context_vk
*context_vk
, struct wined3d_shader
*shader
,
384 const struct shader_spirv_resource_bindings
*bindings
)
386 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(context_vk
->c
.device
);
387 const struct wined3d_vk_info
*vk_info
= context_vk
->vk_info
;
388 struct shader_spirv_compute_program_vk
*program
;
389 struct wined3d_pipeline_layout_vk
*layout
;
390 VkComputePipelineCreateInfo pipeline_info
;
391 struct wined3d_shader_desc shader_desc
;
394 if (!(program
= shader
->backend_data
))
397 if (program
->vk_module
)
400 shader_desc
.byte_code
= shader
->byte_code
;
401 shader_desc
.byte_code_size
= shader
->byte_code_size
;
403 if (!(program
->vk_module
= shader_spirv_compile_shader(context_vk
, &shader_desc
,
404 shader
->source_type
, WINED3D_SHADER_TYPE_COMPUTE
, NULL
, bindings
, NULL
)))
407 if (!(layout
= wined3d_context_vk_get_pipeline_layout(context_vk
,
408 bindings
->vk_bindings
, bindings
->vk_binding_count
)))
410 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, program
->vk_module
, NULL
));
411 program
->vk_module
= VK_NULL_HANDLE
;
414 program
->vk_set_layout
= layout
->vk_set_layout
;
415 program
->vk_pipeline_layout
= layout
->vk_pipeline_layout
;
417 pipeline_info
.sType
= VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO
;
418 pipeline_info
.pNext
= NULL
;
419 pipeline_info
.flags
= 0;
420 pipeline_info
.stage
.sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
;
421 pipeline_info
.stage
.pNext
= NULL
;
422 pipeline_info
.stage
.flags
= 0;
423 pipeline_info
.stage
.stage
= VK_SHADER_STAGE_COMPUTE_BIT
;
424 pipeline_info
.stage
.pName
= "main";
425 pipeline_info
.stage
.pSpecializationInfo
= NULL
;
426 pipeline_info
.stage
.module
= program
->vk_module
;
427 pipeline_info
.layout
= program
->vk_pipeline_layout
;
428 pipeline_info
.basePipelineHandle
= VK_NULL_HANDLE
;
429 pipeline_info
.basePipelineIndex
= -1;
430 if ((vr
= VK_CALL(vkCreateComputePipelines(device_vk
->vk_device
,
431 VK_NULL_HANDLE
, 1, &pipeline_info
, NULL
, &program
->vk_pipeline
))) < 0)
433 ERR("Failed to create Vulkan compute pipeline, vr %s.\n", wined3d_debug_vkresult(vr
));
434 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, program
->vk_module
, NULL
));
435 program
->vk_module
= VK_NULL_HANDLE
;
442 static void shader_spirv_resource_bindings_cleanup(struct shader_spirv_resource_bindings
*bindings
)
444 free(bindings
->vk_bindings
);
445 free(bindings
->bindings
);
448 static bool shader_spirv_resource_bindings_add_vk_binding(struct shader_spirv_resource_bindings
*bindings
,
449 VkDescriptorType vk_type
, VkShaderStageFlagBits vk_stage
, size_t *binding_idx
)
451 SIZE_T binding_count
= bindings
->vk_binding_count
;
452 VkDescriptorSetLayoutBinding
*binding
;
454 if (!wined3d_array_reserve((void **)&bindings
->vk_bindings
, &bindings
->vk_bindings_size
,
455 binding_count
+ 1, sizeof(*bindings
->vk_bindings
)))
458 *binding_idx
= binding_count
;
459 binding
= &bindings
->vk_bindings
[binding_count
];
460 binding
->binding
= binding_count
;
461 binding
->descriptorType
= vk_type
;
462 binding
->descriptorCount
= 1;
463 binding
->stageFlags
= vk_stage
;
464 binding
->pImmutableSamplers
= NULL
;
465 ++bindings
->vk_binding_count
;
470 static bool shader_spirv_resource_bindings_add_binding(struct shader_spirv_resource_bindings
*bindings
,
471 enum vkd3d_shader_descriptor_type vkd3d_type
, VkDescriptorType vk_type
, size_t register_idx
,
472 enum vkd3d_shader_visibility vkd3d_visibility
, VkShaderStageFlagBits vk_stage
,
473 uint32_t flags
, size_t *binding_idx
)
475 SIZE_T binding_count
= bindings
->binding_count
;
476 struct vkd3d_shader_resource_binding
*binding
;
478 if (!wined3d_array_reserve((void **)&bindings
->bindings
, &bindings
->bindings_size
,
479 binding_count
+ 1, sizeof(*bindings
->bindings
)))
482 if (!shader_spirv_resource_bindings_add_vk_binding(bindings
, vk_type
, vk_stage
, binding_idx
))
485 binding
= &bindings
->bindings
[binding_count
];
486 binding
->type
= vkd3d_type
;
487 binding
->register_space
= 0;
488 binding
->register_index
= register_idx
;
489 binding
->shader_visibility
= vkd3d_visibility
;
490 binding
->flags
= flags
;
491 binding
->binding
.set
= 0;
492 binding
->binding
.binding
= *binding_idx
;
493 binding
->binding
.count
= 1;
494 ++bindings
->binding_count
;
499 static bool shader_spirv_resource_bindings_add_uav_counter_binding(struct shader_spirv_resource_bindings
*bindings
,
500 size_t register_idx
, enum vkd3d_shader_visibility vkd3d_visibility
,
501 VkShaderStageFlagBits vk_stage
, size_t *binding_idx
)
503 SIZE_T uav_counter_count
= bindings
->uav_counter_count
;
504 struct vkd3d_shader_uav_counter_binding
*counter
;
506 if (uav_counter_count
>= ARRAY_SIZE(bindings
->uav_counters
))
509 if (!shader_spirv_resource_bindings_add_vk_binding(bindings
,
510 VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
, vk_stage
, binding_idx
))
513 counter
= &bindings
->uav_counters
[uav_counter_count
];
514 counter
->register_space
= 0;
515 counter
->register_index
= register_idx
;
516 counter
->shader_visibility
= vkd3d_visibility
;
517 counter
->binding
.set
= 0;
518 counter
->binding
.binding
= *binding_idx
;
519 counter
->binding
.count
= 1;
521 ++bindings
->uav_counter_count
;
526 static bool wined3d_shader_resource_bindings_add_binding(struct wined3d_shader_resource_bindings
*bindings
,
527 enum wined3d_shader_type shader_type
, enum wined3d_shader_descriptor_type shader_descriptor_type
,
528 size_t resource_idx
, enum wined3d_shader_resource_type resource_type
,
529 enum wined3d_data_type resource_data_type
, size_t binding_idx
)
531 struct wined3d_shader_resource_binding
*binding
;
532 SIZE_T binding_count
= bindings
->count
;
534 if (!wined3d_array_reserve((void **)&bindings
->bindings
, &bindings
->size
,
535 binding_count
+ 1, sizeof(*bindings
->bindings
)))
538 binding
= &bindings
->bindings
[binding_count
];
539 binding
->shader_type
= shader_type
;
540 binding
->shader_descriptor_type
= shader_descriptor_type
;
541 binding
->resource_idx
= resource_idx
;
542 binding
->resource_type
= resource_type
;
543 binding
->resource_data_type
= resource_data_type
;
544 binding
->binding_idx
= binding_idx
;
550 static VkDescriptorType
vk_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type
,
551 enum vkd3d_shader_resource_type resource_type
)
555 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
:
556 return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
;
558 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
:
559 if (resource_type
== VKD3D_SHADER_RESOURCE_BUFFER
)
560 return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
;
561 return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
;
563 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
:
564 if (resource_type
== VKD3D_SHADER_RESOURCE_BUFFER
)
565 return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
;
566 return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
;
568 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
:
569 return VK_DESCRIPTOR_TYPE_SAMPLER
;
572 FIXME("Unhandled descriptor type %#x.\n", type
);
577 static enum wined3d_shader_descriptor_type
wined3d_descriptor_type_from_vkd3d(enum vkd3d_shader_descriptor_type type
)
581 case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV
:
582 return WINED3D_SHADER_DESCRIPTOR_TYPE_CBV
;
584 case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV
:
585 return WINED3D_SHADER_DESCRIPTOR_TYPE_SRV
;
587 case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
:
588 return WINED3D_SHADER_DESCRIPTOR_TYPE_UAV
;
590 case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
:
591 return WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER
;
594 FIXME("Unhandled descriptor type %#x.\n", type
);
599 static enum wined3d_shader_resource_type
wined3d_shader_resource_type_from_vkd3d(enum vkd3d_shader_resource_type t
)
601 return (enum wined3d_shader_resource_type
)t
;
604 static enum wined3d_data_type
wined3d_data_type_from_vkd3d(enum vkd3d_shader_resource_data_type t
)
608 case VKD3D_SHADER_RESOURCE_DATA_UNORM
:
609 return WINED3D_DATA_UNORM
;
610 case VKD3D_SHADER_RESOURCE_DATA_SNORM
:
611 return WINED3D_DATA_SNORM
;
612 case VKD3D_SHADER_RESOURCE_DATA_INT
:
613 return WINED3D_DATA_INT
;
614 case VKD3D_SHADER_RESOURCE_DATA_UINT
:
615 return WINED3D_DATA_UINT
;
616 case VKD3D_SHADER_RESOURCE_DATA_FLOAT
:
617 return WINED3D_DATA_FLOAT
;
618 case VKD3D_SHADER_RESOURCE_DATA_MIXED
:
619 return WINED3D_DATA_UINT
;
621 FIXME("Unhandled resource data type %#x.\n", t
);
622 return WINED3D_DATA_FLOAT
;
626 static bool shader_spirv_resource_bindings_init(struct shader_spirv_resource_bindings
*bindings
,
627 struct wined3d_shader_resource_bindings
*wined3d_bindings
,
628 const struct wined3d_state
*state
, uint32_t shader_mask
)
630 const struct vkd3d_shader_scan_descriptor_info
*descriptor_info
;
631 enum wined3d_shader_descriptor_type wined3d_type
;
632 enum vkd3d_shader_visibility shader_visibility
;
633 enum wined3d_shader_type shader_type
;
634 VkDescriptorType vk_descriptor_type
;
635 VkShaderStageFlagBits vk_stage
;
636 struct wined3d_shader
*shader
;
640 bindings
->binding_count
= 0;
641 bindings
->uav_counter_count
= 0;
642 bindings
->vk_binding_count
= 0;
643 bindings
->so_stage
= WINED3D_SHADER_TYPE_GEOMETRY
;
644 wined3d_bindings
->count
= 0;
646 for (shader_type
= 0; shader_type
< WINED3D_SHADER_TYPE_COUNT
; ++shader_type
)
648 bindings
->binding_base
[shader_type
] = bindings
->vk_binding_count
;
650 if (!(shader_mask
& (1u << shader_type
)) || !(shader
= state
->shader
[shader_type
]))
653 if (shader_type
== WINED3D_SHADER_TYPE_COMPUTE
)
655 descriptor_info
= &((struct shader_spirv_compute_program_vk
*)shader
->backend_data
)->descriptor_info
;
659 descriptor_info
= &((struct shader_spirv_graphics_program_vk
*)shader
->backend_data
)->descriptor_info
;
660 if (shader_type
== WINED3D_SHADER_TYPE_GEOMETRY
&& !shader
->function
)
661 bindings
->so_stage
= WINED3D_SHADER_TYPE_VERTEX
;
664 vk_stage
= vk_shader_stage_from_wined3d(shader_type
);
665 shader_visibility
= vkd3d_shader_visibility_from_wined3d(shader_type
);
667 for (i
= 0; i
< descriptor_info
->descriptor_count
; ++i
)
669 const struct vkd3d_shader_descriptor_info
*d
= &descriptor_info
->descriptors
[i
];
672 if (d
->register_space
)
674 WARN("Unsupported register space %u.\n", d
->register_space
);
678 if (d
->resource_type
== VKD3D_SHADER_RESOURCE_BUFFER
)
679 flags
= VKD3D_SHADER_BINDING_FLAG_BUFFER
;
681 flags
= VKD3D_SHADER_BINDING_FLAG_IMAGE
;
683 vk_descriptor_type
= vk_descriptor_type_from_vkd3d(d
->type
, d
->resource_type
);
684 if (!shader_spirv_resource_bindings_add_binding(bindings
, d
->type
, vk_descriptor_type
,
685 d
->register_index
, shader_visibility
, vk_stage
, flags
, &binding_idx
))
688 wined3d_type
= wined3d_descriptor_type_from_vkd3d(d
->type
);
689 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings
, shader_type
,
690 wined3d_type
, d
->register_index
, wined3d_shader_resource_type_from_vkd3d(d
->resource_type
),
691 wined3d_data_type_from_vkd3d(d
->resource_data_type
), binding_idx
))
694 if (d
->type
== VKD3D_SHADER_DESCRIPTOR_TYPE_UAV
695 && (d
->flags
& VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER
))
697 if (!shader_spirv_resource_bindings_add_uav_counter_binding(bindings
,
698 d
->register_index
, shader_visibility
, vk_stage
, &binding_idx
))
700 if (!wined3d_shader_resource_bindings_add_binding(wined3d_bindings
,
701 shader_type
, WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER
, d
->register_index
,
702 WINED3D_SHADER_RESOURCE_BUFFER
, WINED3D_DATA_UINT
, binding_idx
))
711 static void shader_spirv_scan_shader(struct wined3d_shader
*shader
,
712 struct vkd3d_shader_scan_descriptor_info
*descriptor_info
,
713 struct vkd3d_shader_scan_signature_info
*signature_info
)
715 struct vkd3d_shader_compile_info info
;
719 memset(descriptor_info
, 0, sizeof(*descriptor_info
));
720 descriptor_info
->type
= VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO
;
724 memset(signature_info
, 0, sizeof(*signature_info
));
725 signature_info
->type
= VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO
;
726 descriptor_info
->next
= signature_info
;
729 info
.type
= VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO
;
730 info
.next
= descriptor_info
;
731 if (shader
->source_type
== VKD3D_SHADER_SOURCE_D3D_BYTECODE
)
733 info
.source
.code
= shader
->function
;
734 info
.source
.size
= shader
->functionLength
;
738 info
.source
.code
= shader
->byte_code
;
739 info
.source
.size
= shader
->byte_code_size
;
741 info
.source_type
= shader
->source_type
;
742 info
.target_type
= VKD3D_SHADER_TARGET_SPIRV_BINARY
;
743 info
.options
= spirv_compile_options
;
744 info
.option_count
= ARRAY_SIZE(spirv_compile_options
);
745 info
.log_level
= VKD3D_SHADER_LOG_WARNING
;
746 info
.source_name
= NULL
;
748 if ((ret
= vkd3d_shader_scan(&info
, &messages
)) < 0)
749 ERR("Failed to scan shader, ret %d.\n", ret
);
750 if (messages
&& *messages
&& FIXME_ON(d3d_shader
))
752 const char *ptr
, *end
, *line
;
754 FIXME("Shader log:\n");
756 end
= ptr
+ strlen(ptr
);
757 while ((line
= wined3d_get_line(&ptr
, end
)))
759 FIXME(" %.*s", (int)(ptr
- line
), line
);
763 vkd3d_shader_free_messages(messages
);
766 static void shader_spirv_precompile_compute(struct wined3d_shader
*shader
)
768 struct shader_spirv_compute_program_vk
*program_vk
;
770 if (!(program_vk
= shader
->backend_data
))
772 if (!(program_vk
= calloc(1, sizeof(*program_vk
))))
773 ERR("Failed to allocate program.\n");
774 shader
->backend_data
= program_vk
;
777 shader_spirv_scan_shader(shader
, &program_vk
->descriptor_info
, NULL
);
780 static void shader_spirv_precompile(void *shader_priv
, struct wined3d_shader
*shader
)
782 struct shader_spirv_graphics_program_vk
*program_vk
;
784 TRACE("shader_priv %p, shader %p.\n", shader_priv
, shader
);
786 if (shader
->reg_maps
.shader_version
.type
== WINED3D_SHADER_TYPE_COMPUTE
)
788 shader_spirv_precompile_compute(shader
);
792 if (!(program_vk
= shader
->backend_data
))
794 if (!(program_vk
= calloc(1, sizeof(*program_vk
))))
795 ERR("Failed to allocate program.\n");
796 shader
->backend_data
= program_vk
;
799 shader_spirv_scan_shader(shader
, &program_vk
->descriptor_info
, &program_vk
->signature_info
);
802 static void shader_spirv_apply_draw_state(void *shader_priv
, struct wined3d_context
*context
,
803 const struct wined3d_state
*state
)
805 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
806 struct shader_spirv_graphics_program_variant_vk
*variant_vk
;
807 struct shader_spirv_resource_bindings
*bindings
;
808 size_t binding_base
[WINED3D_SHADER_TYPE_COUNT
];
809 struct wined3d_pipeline_layout_vk
*layout_vk
;
810 struct shader_spirv_priv
*priv
= shader_priv
;
811 enum wined3d_shader_type shader_type
;
812 struct wined3d_shader
*shader
;
814 priv
->vertex_pipe
->vp_apply_draw_state(context
, state
);
815 priv
->fragment_pipe
->fp_apply_draw_state(context
, state
);
817 bindings
= &priv
->bindings
;
818 memcpy(binding_base
, bindings
->binding_base
, sizeof(bindings
->binding_base
));
819 if (!shader_spirv_resource_bindings_init(bindings
, &context_vk
->graphics
.bindings
,
820 state
, ~(1u << WINED3D_SHADER_TYPE_COMPUTE
)))
822 ERR("Failed to initialise shader resource bindings.\n");
825 if (context
->shader_update_mask
& (1u << WINED3D_SHADER_TYPE_GEOMETRY
))
826 context
->shader_update_mask
|= 1u << bindings
->so_stage
;
828 layout_vk
= wined3d_context_vk_get_pipeline_layout(context_vk
, bindings
->vk_bindings
, bindings
->vk_binding_count
);
829 context_vk
->graphics
.vk_set_layout
= layout_vk
->vk_set_layout
;
830 context_vk
->graphics
.vk_pipeline_layout
= layout_vk
->vk_pipeline_layout
;
832 for (shader_type
= 0; shader_type
< ARRAY_SIZE(context_vk
->graphics
.vk_modules
); ++shader_type
)
834 if (!(context
->shader_update_mask
& (1u << shader_type
)) && (!context_vk
->graphics
.vk_modules
[shader_type
]
835 || binding_base
[shader_type
] == bindings
->binding_base
[shader_type
]))
838 if (!(shader
= state
->shader
[shader_type
]) || !shader
->function
)
840 context_vk
->graphics
.vk_modules
[shader_type
] = VK_NULL_HANDLE
;
844 if (!(variant_vk
= shader_spirv_find_graphics_program_variant_vk(priv
, context_vk
, shader
, state
, bindings
)))
846 context_vk
->graphics
.vk_modules
[shader_type
] = variant_vk
->vk_module
;
852 context_vk
->graphics
.vk_set_layout
= VK_NULL_HANDLE
;
853 context_vk
->graphics
.vk_pipeline_layout
= VK_NULL_HANDLE
;
856 static void shader_spirv_apply_compute_state(void *shader_priv
,
857 struct wined3d_context
*context
, const struct wined3d_state
*state
)
859 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
860 struct shader_spirv_compute_program_vk
*program
;
861 struct shader_spirv_priv
*priv
= shader_priv
;
862 struct wined3d_shader
*shader
;
864 if (!shader_spirv_resource_bindings_init(&priv
->bindings
,
865 &context_vk
->compute
.bindings
, state
, 1u << WINED3D_SHADER_TYPE_COMPUTE
))
866 ERR("Failed to initialise shader resource bindings.\n");
868 if ((shader
= state
->shader
[WINED3D_SHADER_TYPE_COMPUTE
]))
869 program
= shader_spirv_find_compute_program_vk(priv
, context_vk
, shader
, &priv
->bindings
);
875 context_vk
->compute
.vk_pipeline
= program
->vk_pipeline
;
876 context_vk
->compute
.vk_set_layout
= program
->vk_set_layout
;
877 context_vk
->compute
.vk_pipeline_layout
= program
->vk_pipeline_layout
;
881 context_vk
->compute
.vk_pipeline
= VK_NULL_HANDLE
;
882 context_vk
->compute
.vk_set_layout
= VK_NULL_HANDLE
;
883 context_vk
->compute
.vk_pipeline_layout
= VK_NULL_HANDLE
;
887 static void shader_spirv_disable(void *shader_priv
, struct wined3d_context
*context
)
889 struct wined3d_context_vk
*context_vk
= wined3d_context_vk(context
);
890 struct shader_spirv_priv
*priv
= shader_priv
;
892 priv
->vertex_pipe
->vp_disable(context
);
893 priv
->fragment_pipe
->fp_disable(context
);
895 context_vk
->compute
.vk_pipeline
= VK_NULL_HANDLE
;
896 context
->shader_update_mask
= (1u << WINED3D_SHADER_TYPE_PIXEL
)
897 | (1u << WINED3D_SHADER_TYPE_VERTEX
)
898 | (1u << WINED3D_SHADER_TYPE_GEOMETRY
)
899 | (1u << WINED3D_SHADER_TYPE_HULL
)
900 | (1u << WINED3D_SHADER_TYPE_DOMAIN
)
901 | (1u << WINED3D_SHADER_TYPE_COMPUTE
);
904 static void shader_spirv_update_float_vertex_constants(struct wined3d_device
*device
, UINT start
, UINT count
)
906 WARN("Not implemented.\n");
909 static void shader_spirv_update_float_pixel_constants(struct wined3d_device
*device
, UINT start
, UINT count
)
911 WARN("Not implemented.\n");
914 static void shader_spirv_invalidate_compute_program(struct wined3d_context_vk
*context_vk
,
915 const struct shader_spirv_compute_program_vk
*program
)
917 if (context_vk
->compute
.vk_pipeline
== program
->vk_pipeline
)
919 context_vk
->c
.shader_update_mask
|= (1u << WINED3D_SHADER_TYPE_COMPUTE
);
920 context_vk
->compute
.vk_pipeline
= VK_NULL_HANDLE
;
924 static void shader_spirv_invalidate_contexts_compute_program(struct wined3d_device
*device
,
925 const struct shader_spirv_compute_program_vk
*program
)
929 for (i
= 0; i
< device
->context_count
; ++i
)
931 shader_spirv_invalidate_compute_program(wined3d_context_vk(device
->contexts
[i
]), program
);
935 static void shader_spirv_invalidate_graphics_program_variant(struct wined3d_context_vk
*context_vk
,
936 const struct shader_spirv_graphics_program_variant_vk
*variant
)
938 enum wined3d_shader_type shader_type
;
940 for (shader_type
= 0; shader_type
< WINED3D_SHADER_TYPE_GRAPHICS_COUNT
; ++shader_type
)
942 if (context_vk
->graphics
.vk_modules
[shader_type
] != variant
->vk_module
)
945 context_vk
->graphics
.vk_modules
[shader_type
] = VK_NULL_HANDLE
;
946 context_vk
->c
.shader_update_mask
|= (1u << shader_type
);
950 static void shader_spirv_invalidate_contexts_graphics_program_variant(struct wined3d_device
*device
,
951 const struct shader_spirv_graphics_program_variant_vk
*variant
)
955 for (i
= 0; i
< device
->context_count
; ++i
)
957 shader_spirv_invalidate_graphics_program_variant(wined3d_context_vk(device
->contexts
[i
]), variant
);
961 static void shader_spirv_destroy_compute_vk(struct wined3d_shader
*shader
)
963 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(shader
->device
);
964 struct shader_spirv_compute_program_vk
*program
= shader
->backend_data
;
965 struct wined3d_context_vk
*context_vk
= &device_vk
->context_vk
;
966 struct wined3d_vk_info
*vk_info
= &device_vk
->vk_info
;
968 shader_spirv_invalidate_contexts_compute_program(&device_vk
->d
, program
);
969 wined3d_context_vk_destroy_vk_pipeline(context_vk
, program
->vk_pipeline
, context_vk
->current_command_buffer
.id
);
970 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, program
->vk_module
, NULL
));
971 vkd3d_shader_free_scan_descriptor_info(&program
->descriptor_info
);
972 shader
->backend_data
= NULL
;
976 static void shader_spirv_destroy(struct wined3d_shader
*shader
)
978 struct wined3d_device_vk
*device_vk
= wined3d_device_vk(shader
->device
);
979 struct shader_spirv_graphics_program_variant_vk
*variant_vk
;
980 struct wined3d_vk_info
*vk_info
= &device_vk
->vk_info
;
981 struct shader_spirv_graphics_program_vk
*program_vk
;
984 if (!shader
->backend_data
)
987 if (shader
->reg_maps
.shader_version
.type
== WINED3D_SHADER_TYPE_COMPUTE
)
989 shader_spirv_destroy_compute_vk(shader
);
993 program_vk
= shader
->backend_data
;
994 for (i
= 0; i
< program_vk
->variant_count
; ++i
)
996 variant_vk
= &program_vk
->variants
[i
];
997 shader_spirv_invalidate_contexts_graphics_program_variant(&device_vk
->d
, variant_vk
);
998 VK_CALL(vkDestroyShaderModule(device_vk
->vk_device
, variant_vk
->vk_module
, NULL
));
1000 free(program_vk
->variants
);
1001 vkd3d_shader_free_scan_descriptor_info(&program_vk
->descriptor_info
);
1002 vkd3d_shader_free_scan_signature_info(&program_vk
->signature_info
);
1004 shader
->backend_data
= NULL
;
1008 static HRESULT
shader_spirv_alloc(struct wined3d_device
*device
,
1009 const struct wined3d_vertex_pipe_ops
*vertex_pipe
, const struct wined3d_fragment_pipe_ops
*fragment_pipe
)
1011 void *vertex_priv
, *fragment_priv
;
1012 struct shader_spirv_priv
*priv
;
1014 if (!(priv
= malloc(sizeof(*priv
))))
1015 return E_OUTOFMEMORY
;
1017 if (!(vertex_priv
= vertex_pipe
->vp_alloc(&spirv_shader_backend_vk
, priv
)))
1019 ERR("Failed to initialise vertex pipe.\n");
1024 if (!(fragment_priv
= fragment_pipe
->alloc_private(&spirv_shader_backend_vk
, priv
)))
1026 ERR("Failed to initialise fragment pipe.\n");
1027 vertex_pipe
->vp_free(device
, NULL
);
1032 priv
->vertex_pipe
= vertex_pipe
;
1033 priv
->fragment_pipe
= fragment_pipe
;
1034 memset(&priv
->bindings
, 0, sizeof(priv
->bindings
));
1036 device
->vertex_priv
= vertex_priv
;
1037 device
->fragment_priv
= fragment_priv
;
1038 device
->shader_priv
= priv
;
1043 static void shader_spirv_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1045 struct shader_spirv_priv
*priv
= device
->shader_priv
;
1047 shader_spirv_resource_bindings_cleanup(&priv
->bindings
);
1048 priv
->fragment_pipe
->free_private(device
, context
);
1049 priv
->vertex_pipe
->vp_free(device
, context
);
1053 static BOOL
shader_spirv_allocate_context_data(struct wined3d_context
*context
)
1058 static void shader_spirv_free_context_data(struct wined3d_context
*context
)
1062 static void shader_spirv_init_context_state(struct wined3d_context
*context
)
1066 static void shader_spirv_get_caps(const struct wined3d_adapter
*adapter
, struct shader_caps
*caps
)
1068 caps
->vs_version
= min(wined3d_settings
.max_sm_vs
, 5);
1069 caps
->hs_version
= min(wined3d_settings
.max_sm_hs
, 5);
1070 caps
->ds_version
= min(wined3d_settings
.max_sm_ds
, 5);
1071 caps
->gs_version
= min(wined3d_settings
.max_sm_gs
, 5);
1072 caps
->ps_version
= min(wined3d_settings
.max_sm_ps
, 5);
1073 caps
->cs_version
= min(wined3d_settings
.max_sm_cs
, 5);
1075 caps
->vs_uniform_count
= WINED3D_MAX_VS_CONSTS_F
;
1076 caps
->ps_uniform_count
= WINED3D_MAX_PS_CONSTS_F
;
1077 caps
->ps_1x_max_value
= FLT_MAX
;
1078 caps
->varying_count
= 0;
1079 caps
->wined3d_caps
= WINED3D_SHADER_CAP_FULL_FFP_VARYINGS
;
1082 static BOOL
shader_spirv_color_fixup_supported(struct color_fixup_desc fixup
)
1084 return is_identity_fixup(fixup
);
1087 static uint64_t shader_spirv_compile(struct wined3d_context
*context
, const struct wined3d_shader_desc
*shader_desc
,
1088 enum wined3d_shader_type shader_type
)
1090 struct shader_spirv_resource_bindings bindings
= {0};
1091 return (uint64_t)shader_spirv_compile_shader(wined3d_context_vk(context
), shader_desc
,
1092 VKD3D_SHADER_SOURCE_DXBC_TPF
, shader_type
, NULL
, &bindings
, NULL
);
1095 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk
=
1097 .shader_handle_instruction
= shader_spirv_handle_instruction
,
1098 .shader_precompile
= shader_spirv_precompile
,
1099 .shader_apply_draw_state
= shader_spirv_apply_draw_state
,
1100 .shader_apply_compute_state
= shader_spirv_apply_compute_state
,
1101 .shader_disable
= shader_spirv_disable
,
1102 .shader_update_float_vertex_constants
= shader_spirv_update_float_vertex_constants
,
1103 .shader_update_float_pixel_constants
= shader_spirv_update_float_pixel_constants
,
1104 .shader_destroy
= shader_spirv_destroy
,
1105 .shader_alloc_private
= shader_spirv_alloc
,
1106 .shader_free_private
= shader_spirv_free
,
1107 .shader_allocate_context_data
= shader_spirv_allocate_context_data
,
1108 .shader_free_context_data
= shader_spirv_free_context_data
,
1109 .shader_init_context_state
= shader_spirv_init_context_state
,
1110 .shader_get_caps
= shader_spirv_get_caps
,
1111 .shader_color_fixup_supported
= shader_spirv_color_fixup_supported
,
1112 .shader_compile
= shader_spirv_compile
,
1115 const struct wined3d_shader_backend_ops
*wined3d_spirv_shader_backend_init_vk(void)
1117 TRACE("Using %s.\n", vkd3d_shader_get_version(NULL
, NULL
));
1119 return &spirv_shader_backend_vk
;
1122 static void spirv_vertex_pipe_vk_vp_apply_draw_state(struct wined3d_context
*context
, const struct wined3d_state
*state
)
1124 /* Nothing to do. */
1127 static void spirv_vertex_pipe_vk_vp_disable(const struct wined3d_context
*context
)
1129 /* Nothing to do. */
1132 static void spirv_vertex_pipe_vk_vp_get_caps(const struct wined3d_adapter
*adapter
, struct wined3d_vertex_caps
*caps
)
1134 memset(caps
, 0, sizeof(*caps
));
1137 static unsigned int spirv_vertex_pipe_vk_vp_get_emul_mask(const struct wined3d_adapter
*adapter
)
1142 static void *spirv_vertex_pipe_vk_vp_alloc(const struct wined3d_shader_backend_ops
*shader_backend
, void *shader_priv
)
1144 if (shader_backend
!= &spirv_shader_backend_vk
)
1146 FIXME("SPIR-V vertex pipe without SPIR-V shader backend not implemented.\n");
1153 static void spirv_vertex_pipe_vk_vp_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1155 /* Nothing to do. */
1158 static const struct wined3d_state_entry_template spirv_vertex_pipe_vk_vp_states
[] =
1160 {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE
), {STATE_RENDER(WINED3D_RS_RANGEFOGENABLE
), state_nop
}},
1161 {STATE_RENDER(WINED3D_RS_CLIPPING
), {STATE_RENDER(WINED3D_RS_CLIPPING
), state_nop
}},
1162 {STATE_RENDER(WINED3D_RS_LIGHTING
), {STATE_RENDER(WINED3D_RS_LIGHTING
), state_nop
}},
1163 {STATE_RENDER(WINED3D_RS_COLORVERTEX
), {STATE_RENDER(WINED3D_RS_COLORVERTEX
), state_nop
}},
1164 {STATE_RENDER(WINED3D_RS_LOCALVIEWER
), {STATE_RENDER(WINED3D_RS_LOCALVIEWER
), state_nop
}},
1165 {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS
), {STATE_RENDER(WINED3D_RS_NORMALIZENORMALS
), state_nop
}},
1166 {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE
), state_nop
}},
1167 {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE
), state_nop
}},
1168 {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE
), state_nop
}},
1169 {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE
), {STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE
), state_nop
}},
1170 {STATE_RENDER(WINED3D_RS_VERTEXBLEND
), {STATE_RENDER(WINED3D_RS_VERTEXBLEND
), state_nop
}},
1171 {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE
), {STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE
), state_nop
}},
1172 {STATE_RENDER(WINED3D_RS_POINTSIZE
), {STATE_RENDER(WINED3D_RS_POINTSIZE
), state_nop
}},
1173 {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN
), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN
), state_nop
}},
1174 {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE
), {STATE_RENDER(WINED3D_RS_POINTSCALEENABLE
), state_nop
}},
1175 {STATE_RENDER(WINED3D_RS_POINTSCALE_A
), {STATE_RENDER(WINED3D_RS_POINTSCALE_A
), state_nop
}},
1176 {STATE_RENDER(WINED3D_RS_POINTSCALE_B
), {STATE_RENDER(WINED3D_RS_POINTSCALE_B
), state_nop
}},
1177 {STATE_RENDER(WINED3D_RS_POINTSCALE_C
), {STATE_RENDER(WINED3D_RS_POINTSCALE_C
), state_nop
}},
1178 {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX
), {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX
), state_nop
}},
1179 {STATE_MATERIAL
, {STATE_MATERIAL
, state_nop
}},
1180 {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX
), state_nop
}},
1181 {STATE_LIGHT_TYPE
, {STATE_LIGHT_TYPE
, state_nop
}},
1182 {0}, /* Terminate */
1185 static const struct wined3d_vertex_pipe_ops spirv_vertex_pipe_vk
=
1187 .vp_apply_draw_state
= spirv_vertex_pipe_vk_vp_apply_draw_state
,
1188 .vp_disable
= spirv_vertex_pipe_vk_vp_disable
,
1189 .vp_get_caps
= spirv_vertex_pipe_vk_vp_get_caps
,
1190 .vp_get_emul_mask
= spirv_vertex_pipe_vk_vp_get_emul_mask
,
1191 .vp_alloc
= spirv_vertex_pipe_vk_vp_alloc
,
1192 .vp_free
= spirv_vertex_pipe_vk_vp_free
,
1193 .vp_states
= spirv_vertex_pipe_vk_vp_states
,
1196 const struct wined3d_vertex_pipe_ops
*wined3d_spirv_vertex_pipe_init_vk(void)
1198 return &spirv_vertex_pipe_vk
;
1201 static void spirv_fragment_pipe_vk_fp_apply_draw_state(
1202 struct wined3d_context
*context
, const struct wined3d_state
*state
)
1204 /* Nothing to do. */
1207 static void spirv_fragment_pipe_vk_fp_disable(const struct wined3d_context
*context
)
1209 /* Nothing to do. */
1212 static void spirv_fragment_pipe_vk_fp_get_caps(const struct wined3d_adapter
*adapter
, struct fragment_caps
*caps
)
1214 memset(caps
, 0, sizeof(*caps
));
1217 static unsigned int spirv_fragment_pipe_vk_fp_get_emul_mask(const struct wined3d_adapter
*adapter
)
1222 static void *spirv_fragment_pipe_vk_fp_alloc(const struct wined3d_shader_backend_ops
*shader_backend
, void *shader_priv
)
1224 if (shader_backend
!= &spirv_shader_backend_vk
)
1226 FIXME("SPIR-V fragment pipe without SPIR-V shader backend not implemented.\n");
1233 static void spirv_fragment_pipe_vk_fp_free(struct wined3d_device
*device
, struct wined3d_context
*context
)
1235 /* Nothing to do. */
1238 static BOOL
spirv_fragment_pipe_vk_fp_alloc_context_data(struct wined3d_context
*context
)
1243 static void spirv_fragment_pipe_vk_fp_free_context_data(struct wined3d_context
*context
)
1245 /* Nothing to do. */
1248 static const struct wined3d_state_entry_template spirv_fragment_pipe_vk_fp_states
[] =
1250 {STATE_RENDER(WINED3D_RS_SHADEMODE
), {STATE_RENDER(WINED3D_RS_SHADEMODE
), state_nop
}},
1251 {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE
), {STATE_RENDER(WINED3D_RS_ALPHATESTENABLE
), state_nop
}},
1252 {STATE_RENDER(WINED3D_RS_ALPHAREF
), {STATE_RENDER(WINED3D_RS_ALPHAREF
), state_nop
}},
1253 {STATE_RENDER(WINED3D_RS_ALPHAFUNC
), {STATE_RENDER(WINED3D_RS_ALPHAFUNC
), state_nop
}},
1254 {STATE_RENDER(WINED3D_RS_FOGENABLE
), {STATE_RENDER(WINED3D_RS_FOGENABLE
), state_nop
}},
1255 {STATE_RENDER(WINED3D_RS_FOGCOLOR
), {STATE_RENDER(WINED3D_RS_FOGCOLOR
), state_nop
}},
1256 {STATE_RENDER(WINED3D_RS_FOGTABLEMODE
), {STATE_RENDER(WINED3D_RS_FOGTABLEMODE
), state_nop
}},
1257 {STATE_RENDER(WINED3D_RS_FOGSTART
), {STATE_RENDER(WINED3D_RS_FOGSTART
), state_nop
}},
1258 {STATE_RENDER(WINED3D_RS_FOGEND
), {STATE_RENDER(WINED3D_RS_FOGEND
), state_nop
}},
1259 {STATE_RENDER(WINED3D_RS_FOGDENSITY
), {STATE_RENDER(WINED3D_RS_FOGDENSITY
), state_nop
}},
1260 {STATE_RENDER(WINED3D_RS_COLORKEYENABLE
), {STATE_RENDER(WINED3D_RS_COLORKEYENABLE
), state_nop
}},
1261 {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE
), {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE
), state_nop
}},
1262 {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE
), {STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE
), state_nop
}},
1263 {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE
), {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE
), state_nop
}},
1264 {STATE_POINT_ENABLE
, {STATE_POINT_ENABLE
, state_nop
}},
1265 {0}, /* Terminate */
1268 static const struct wined3d_fragment_pipe_ops spirv_fragment_pipe_vk
=
1270 .fp_apply_draw_state
= spirv_fragment_pipe_vk_fp_apply_draw_state
,
1271 .fp_disable
= spirv_fragment_pipe_vk_fp_disable
,
1272 .get_caps
= spirv_fragment_pipe_vk_fp_get_caps
,
1273 .get_emul_mask
= spirv_fragment_pipe_vk_fp_get_emul_mask
,
1274 .alloc_private
= spirv_fragment_pipe_vk_fp_alloc
,
1275 .free_private
= spirv_fragment_pipe_vk_fp_free
,
1276 .allocate_context_data
= spirv_fragment_pipe_vk_fp_alloc_context_data
,
1277 .free_context_data
= spirv_fragment_pipe_vk_fp_free_context_data
,
1278 .color_fixup_supported
= shader_spirv_color_fixup_supported
,
1279 .states
= spirv_fragment_pipe_vk_fp_states
,
1282 const struct wined3d_fragment_pipe_ops
*wined3d_spirv_fragment_pipe_init_vk(void)
1284 return &spirv_fragment_pipe_vk
;