Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/view.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 0adb0a115dc..dfca8fc53f8 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -332,6 +332,25 @@ static void wined3d_view_invalidate_location(struct wined3d_resource *resource, wined3d_texture_invalidate_location(texture, sub_resource_idx, location); }
+static void wined3d_view_load_location(struct wined3d_resource *resource, + const struct wined3d_view_desc *desc, struct wined3d_context *context, DWORD location) +{ + unsigned int i, sub_resource_idx, layer_count; + struct wined3d_texture *texture; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + wined3d_buffer_load_location(buffer_from_resource(resource), context, location); + return; + } + + texture = texture_from_resource(resource); + sub_resource_idx = desc->u.texture.layer_idx * texture->level_count + desc->u.texture.level_idx; + layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? desc->u.texture.layer_count : 1; + for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count) + wined3d_texture_load_location(texture, sub_resource_idx, context, location); +} + ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *view) { ULONG refcount = InterlockedIncrement(&view->refcount); @@ -461,21 +480,7 @@ void wined3d_rendertarget_view_prepare_location(struct wined3d_rendertarget_view void wined3d_rendertarget_view_load_location(struct wined3d_rendertarget_view *view, struct wined3d_context *context, DWORD location) { - struct wined3d_resource *resource = view->resource; - unsigned int i, sub_resource_idx, layer_count; - struct wined3d_texture *texture; - - if (resource->type == WINED3D_RTYPE_BUFFER) - { - wined3d_buffer_load_location(buffer_from_resource(resource), context, location); - return; - } - - texture = texture_from_resource(resource); - sub_resource_idx = view->sub_resource_idx; - layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1; - for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count) - wined3d_texture_load_location(texture, sub_resource_idx, context, location); + wined3d_view_load_location(view->resource, &view->desc, context, location); }
void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view, DWORD location)
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- dlls/wined3d/shader_spirv.c | 74 ++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 22 deletions(-)
diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 7617ee9d6ef..1f1daacfe22 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -78,6 +78,15 @@ struct shader_spirv_compile_arguments } u; };
+struct shader_spirv_interface +{ + const struct vkd3d_shader_resource_binding *bindings; + SIZE_T binding_count; + + const struct vkd3d_shader_uav_counter_binding *uav_counters; + SIZE_T uav_counter_count; +}; + struct shader_spirv_graphics_program_variant_vk { struct shader_spirv_compile_arguments compile_args; @@ -278,8 +287,7 @@ static const char *get_line(const char **ptr) }
static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_shader_interface *iface, - struct wined3d_shader *shader, const struct shader_spirv_resource_bindings *b, - const struct wined3d_stream_output_desc *so_desc) + const struct shader_spirv_interface *i, const struct wined3d_stream_output_desc *so_desc) { memset(iface, 0, sizeof(*iface)); iface->vkd3d_interface.type = VKD3D_SHADER_STRUCTURE_TYPE_INTERFACE_INFO; @@ -297,23 +305,23 @@ static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_sh iface->vkd3d_interface.next = &iface->xfb_info; }
- iface->vkd3d_interface.bindings = b->bindings; - iface->vkd3d_interface.binding_count = b->binding_count; + iface->vkd3d_interface.bindings = i->bindings; + iface->vkd3d_interface.binding_count = i->binding_count;
- iface->vkd3d_interface.uav_counters = b->uav_counters; - iface->vkd3d_interface.uav_counter_count = b->uav_counter_count; + iface->vkd3d_interface.uav_counters = i->uav_counters; + iface->vkd3d_interface.uav_counter_count = i->uav_counter_count; }
static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk, - struct wined3d_shader *shader, const struct shader_spirv_compile_arguments *args, - const struct shader_spirv_resource_bindings *bindings, const struct wined3d_stream_output_desc *so_desc) + struct wined3d_shader_desc *shader_desc, enum wined3d_shader_type shader_type, + const struct shader_spirv_compile_arguments *args, const struct shader_spirv_interface *shader_interface, + const struct wined3d_stream_output_desc *so_desc) { struct wined3d_shader_spirv_compile_args compile_args; struct wined3d_shader_spirv_shader_interface iface; + VkShaderModuleCreateInfo shader_create_info; struct vkd3d_shader_compile_info info; const struct wined3d_vk_info *vk_info; - enum wined3d_shader_type shader_type; - VkShaderModuleCreateInfo shader_desc; struct wined3d_device_vk *device_vk; struct vkd3d_shader_code spirv; VkShaderModule module; @@ -321,15 +329,14 @@ static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk VkResult vr; int ret;
- shader_spirv_init_shader_interface_vk(&iface, shader, bindings, so_desc); - shader_type = shader->reg_maps.shader_version.type; + shader_spirv_init_shader_interface_vk(&iface, shader_interface, so_desc); shader_spirv_init_compile_args(&compile_args, &iface.vkd3d_interface, VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, shader_type, args);
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; info.next = &compile_args.spirv_target; - info.source.code = shader->byte_code; - info.source.size = shader->byte_code_size; + info.source.code = shader_desc->byte_code; + info.source.size = shader_desc->byte_code_size; info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; info.target_type = VKD3D_SHADER_TARGET_SPIRV_BINARY; info.options = NULL; @@ -361,12 +368,12 @@ static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk device_vk = wined3d_device_vk(context_vk->c.device); vk_info = &device_vk->vk_info;
- shader_desc.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shader_desc.pNext = NULL; - shader_desc.flags = 0; - shader_desc.codeSize = spirv.size; - shader_desc.pCode = spirv.code; - if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_desc, NULL, &module))) < 0) + shader_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_create_info.pNext = NULL; + shader_create_info.flags = 0; + shader_create_info.codeSize = spirv.size; + shader_create_info.pCode = spirv.code; + if ((vr = VK_CALL(vkCreateShaderModule(device_vk->vk_device, &shader_create_info, NULL, &module))) < 0) { vkd3d_shader_free_shader_code(&spirv); WARN("Failed to create Vulkan shader module, vr %s.\n", wined3d_debug_vkresult(vr)); @@ -387,7 +394,9 @@ static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphi size_t binding_base = bindings->binding_base[shader_type]; const struct wined3d_stream_output_desc *so_desc = NULL; struct shader_spirv_graphics_program_vk *program_vk; + struct shader_spirv_interface shader_interface; struct shader_spirv_compile_arguments args; + struct wined3d_shader_desc shader_desc; size_t variant_count, i;
shader_spirv_compile_arguments_init(&args, &context_vk->c, shader, state, context_vk->sample_count); @@ -413,7 +422,17 @@ static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphi variant_vk = &program_vk->variants[variant_count]; variant_vk->compile_args = args; variant_vk->binding_base = binding_base; - if (!(variant_vk->vk_module = shader_spirv_compile(context_vk, shader, &args, bindings, so_desc))) + + shader_interface.bindings = bindings->bindings; + shader_interface.binding_count = bindings->binding_count; + shader_interface.uav_counters = bindings->uav_counters; + shader_interface.uav_counter_count = bindings->uav_counter_count; + + shader_desc.byte_code = shader->byte_code; + shader_desc.byte_code_size = shader->byte_code_size; + + if (!(variant_vk->vk_module = shader_spirv_compile(context_vk, &shader_desc, shader_type, &args, + &shader_interface, so_desc))) return NULL; ++program_vk->variant_count;
@@ -427,8 +446,10 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); const struct wined3d_vk_info *vk_info = context_vk->vk_info; struct shader_spirv_compute_program_vk *program; + struct shader_spirv_interface shader_interface; struct wined3d_pipeline_layout_vk *layout; VkComputePipelineCreateInfo pipeline_info; + struct wined3d_shader_desc shader_desc; VkResult vr;
if (!(program = shader->backend_data)) @@ -437,7 +458,16 @@ static struct shader_spirv_compute_program_vk *shader_spirv_find_compute_program if (program->vk_module) return program;
- if (!(program->vk_module = shader_spirv_compile(context_vk, shader, NULL, bindings, NULL))) + shader_interface.bindings = bindings->bindings; + shader_interface.binding_count = bindings->binding_count; + shader_interface.uav_counters = bindings->uav_counters; + shader_interface.uav_counter_count = bindings->uav_counter_count; + + shader_desc.byte_code = shader->byte_code; + shader_desc.byte_code_size = shader->byte_code_size; + + if (!(program->vk_module = shader_spirv_compile(context_vk, &shader_desc, WINED3D_SHADER_TYPE_COMPUTE, + NULL, &shader_interface, NULL))) return NULL;
if (!(layout = wined3d_context_vk_get_pipeline_layout(context_vk,
On Thu, 23 Sept 2021 at 10:43, Jan Sikorski jsikorski@codeweavers.com wrote:
+struct shader_spirv_interface +{
- const struct vkd3d_shader_resource_binding *bindings;
- SIZE_T binding_count;
- const struct vkd3d_shader_uav_counter_binding *uav_counters;
- SIZE_T uav_counter_count;
+};
[...]
static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk,
struct wined3d_shader *shader, const struct shader_spirv_compile_arguments *args,
const struct shader_spirv_resource_bindings *bindings, const struct wined3d_stream_output_desc *so_desc)
struct wined3d_shader_desc *shader_desc, enum wined3d_shader_type shader_type,
const struct shader_spirv_compile_arguments *args, const struct shader_spirv_interface *shader_interface,
const struct wined3d_stream_output_desc *so_desc)
{ struct wined3d_shader_spirv_compile_args compile_args; struct wined3d_shader_spirv_shader_interface iface;
- VkShaderModuleCreateInfo shader_create_info; struct vkd3d_shader_compile_info info; const struct wined3d_vk_info *vk_info;
- enum wined3d_shader_type shader_type;
- VkShaderModuleCreateInfo shader_desc; struct wined3d_device_vk *device_vk; struct vkd3d_shader_code spirv; VkShaderModule module;
@@ -321,15 +329,14 @@ static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk VkResult vr; int ret;
- shader_spirv_init_shader_interface_vk(&iface, shader, bindings, so_desc);
- shader_type = shader->reg_maps.shader_version.type;
- shader_spirv_init_shader_interface_vk(&iface, shader_interface, so_desc); shader_spirv_init_compile_args(&compile_args, &iface.vkd3d_interface, VKD3D_SHADER_SPIRV_ENVIRONMENT_VULKAN_1_0, shader_type, args);
[...]
@@ -413,7 +422,17 @@ static struct shader_spirv_graphics_program_variant_vk *shader_spirv_find_graphi variant_vk = &program_vk->variants[variant_count]; variant_vk->compile_args = args; variant_vk->binding_base = binding_base;
- if (!(variant_vk->vk_module = shader_spirv_compile(context_vk, shader, &args, bindings, so_desc)))
- shader_interface.bindings = bindings->bindings;
- shader_interface.binding_count = bindings->binding_count;
- shader_interface.uav_counters = bindings->uav_counters;
- shader_interface.uav_counter_count = bindings->uav_counter_count;
- shader_desc.byte_code = shader->byte_code;
- shader_desc.byte_code_size = shader->byte_code_size;
- if (!(variant_vk->vk_module = shader_spirv_compile(context_vk, &shader_desc, shader_type, &args,
&shader_interface, so_desc))) return NULL;
It's not explicitly stated in the patch description, but I guess the idea here is to allow calling shader_spirv_compile() without passing it a wined3d_shader object. The shader_spirv_interface structure feels a little superfluous; it largely corresponds to part of the shader_spirv_resource_bindings structure that's currently passed in, and all it's fields are set to NULL for the call introduced in patch 3/3. We could arguably simply pass NULL for the current "bindings" parameter in patch 3/3, and then handle that NULL in shader_spirv_init_shader_interface_vk(). Alternatively, we could pass a vkd3d_shader_interface_info structure to shader_spirv_compile(), in which case calling shader_spirv_init_shader_interface_vk() would become the responsibility of the callers of shader_spirv_compile(), and we could still pass NULL in patch 3/3.
Patch 3/3 makes the "shader_desc" parameter const, but that seems more appropriate in this patch.
Based on the vkd3d implementation.
Signed-off-by: Jan Sikorski jsikorski@codeweavers.com --- v3: - don't use push constants for now - create new views if necessary - fixup for the R11G11B10 case - truncate uint values, for gpu's that saturate --- dlls/wined3d/adapter_vk.c | 6 +- dlls/wined3d/arb_program_shader.c | 8 + dlls/wined3d/context_vk.c | 2 +- dlls/wined3d/glsl_shader.c | 8 + dlls/wined3d/shader.c | 7 + dlls/wined3d/shader_spirv.c | 10 +- dlls/wined3d/texture.c | 3 + dlls/wined3d/utils.c | 29 +- dlls/wined3d/view.c | 425 +++++++++++++++++++++++++++--- dlls/wined3d/wined3d_private.h | 52 ++++ dlls/wined3d/wined3d_shaders.h | 388 +++++++++++++++++++++++++++ 11 files changed, 884 insertions(+), 54 deletions(-) create mode 100644 dlls/wined3d/wined3d_shaders.h
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 18c73312daf..91a6b92b4aa 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -719,6 +719,8 @@ static HRESULT adapter_vk_init_3d(struct wined3d_device *device) wined3d_device_create_default_samplers(device, &context_vk->c); wined3d_device_vk_create_null_resources(device_vk, context_vk); wined3d_device_vk_create_null_views(device_vk, context_vk); + if (device->adapter->d3d_info.feature_level >= WINED3D_FEATURE_LEVEL_11) + wined3d_device_vk_uav_clear_state_init(device_vk);
return WINED3D_OK; } @@ -740,6 +742,8 @@ static void adapter_vk_uninit_3d_cs(void *object) device->shader_backend->shader_destroy(shader); }
+ if (device->adapter->d3d_info.feature_level >= WINED3D_FEATURE_LEVEL_11) + wined3d_device_vk_uav_clear_state_cleanup(device_vk); device->blitter->ops->blitter_destroy(device->blitter, NULL); device->shader_backend->shader_free_private(device, &context_vk->c); wined3d_device_vk_destroy_null_views(device_vk, context_vk); @@ -1037,7 +1041,7 @@ static void adapter_vk_unmap_bo_address(struct wined3d_context *context, wined3d_bo_vk_unmap(bo, context_vk); }
-static void adapter_vk_copy_bo_address(struct wined3d_context *context, +void adapter_vk_copy_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size) { struct wined3d_context_vk *context_vk = wined3d_context_vk(context); diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 1b533107f64..eeb51448b01 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -5637,6 +5637,13 @@ static BOOL shader_arb_has_ffp_proj_control(void *shader_priv)
static void shader_arb_precompile(void *shader_priv, struct wined3d_shader *shader) {}
+static uint64_t shader_arb_shader_compile(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc, + enum wined3d_shader_type shader_type) +{ + ERR("Not implemented.\n"); + return 0; +} + const struct wined3d_shader_backend_ops arb_program_shader_backend = { shader_arb_handle_instruction, @@ -5656,6 +5663,7 @@ const struct wined3d_shader_backend_ops arb_program_shader_backend = shader_arb_get_caps, shader_arb_color_fixup_supported, shader_arb_has_ffp_proj_control, + shader_arb_shader_compile, };
/* ARB_fragment_program fixed function pipeline replacement definitions */ diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index aeaeca322ff..d0c24673490 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2558,7 +2558,7 @@ static VkResult wined3d_context_vk_create_vk_descriptor_pool(struct wined3d_devi return vr; }
-static VkResult wined3d_context_vk_create_vk_descriptor_set(struct wined3d_context_vk *context_vk, +VkResult wined3d_context_vk_create_vk_descriptor_set(struct wined3d_context_vk *context_vk, VkDescriptorSetLayout vk_set_layout, VkDescriptorSet *vk_descriptor_set) { struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device); diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index fb809052d83..adfbf60e726 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -11490,6 +11490,13 @@ static BOOL shader_glsl_has_ffp_proj_control(void *shader_priv) return priv->ffp_proj_control; }
+static uint64_t shader_glsl_shader_compile(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc, + enum wined3d_shader_type shader_type) +{ + ERR("Not implemented.\n"); + return 0; +} + const struct wined3d_shader_backend_ops glsl_shader_backend = { shader_glsl_handle_instruction, @@ -11509,6 +11516,7 @@ const struct wined3d_shader_backend_ops glsl_shader_backend = shader_glsl_get_caps, shader_glsl_color_fixup_supported, shader_glsl_has_ffp_proj_control, + shader_glsl_shader_compile, };
static void glsl_vertex_pipe_vp_enable(const struct wined3d_context *context, BOOL enable) {} diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index b34ec539014..fb7115a26dd 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -3279,6 +3279,12 @@ static BOOL shader_none_has_ffp_proj_control(void *shader_priv) return priv->ffp_proj_control; }
+static uint64_t shader_none_shader_compile(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc, + enum wined3d_shader_type shader_type) +{ + return 0; +} + const struct wined3d_shader_backend_ops none_shader_backend = { shader_none_handle_instruction, @@ -3298,6 +3304,7 @@ const struct wined3d_shader_backend_ops none_shader_backend = shader_none_get_caps, shader_none_color_fixup_supported, shader_none_has_ffp_proj_control, + shader_none_shader_compile, };
static unsigned int shader_max_version_from_feature_level(enum wined3d_feature_level level) diff --git a/dlls/wined3d/shader_spirv.c b/dlls/wined3d/shader_spirv.c index 1f1daacfe22..708a3e90741 100644 --- a/dlls/wined3d/shader_spirv.c +++ b/dlls/wined3d/shader_spirv.c @@ -313,7 +313,7 @@ static void shader_spirv_init_shader_interface_vk(struct wined3d_shader_spirv_sh }
static VkShaderModule shader_spirv_compile(struct wined3d_context_vk *context_vk, - struct wined3d_shader_desc *shader_desc, enum wined3d_shader_type shader_type, + const struct wined3d_shader_desc *shader_desc, enum wined3d_shader_type shader_type, const struct shader_spirv_compile_arguments *args, const struct shader_spirv_interface *shader_interface, const struct wined3d_stream_output_desc *so_desc) { @@ -1147,6 +1147,13 @@ static BOOL shader_spirv_has_ffp_proj_control(void *shader_priv) return priv->ffp_proj_control; }
+static uint64_t wined3d_spirv_compile(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc, + enum wined3d_shader_type shader_type) +{ + struct shader_spirv_interface iface = {0}; + return (uint64_t)shader_spirv_compile(wined3d_context_vk(context), shader_desc, shader_type, NULL, &iface, NULL); +} + static const struct wined3d_shader_backend_ops spirv_shader_backend_vk = { .shader_handle_instruction = shader_spirv_handle_instruction, @@ -1166,6 +1173,7 @@ static const struct wined3d_shader_backend_ops spirv_shader_backend_vk = .shader_get_caps = shader_spirv_get_caps, .shader_color_fixup_supported = shader_spirv_color_fixup_supported, .shader_has_ffp_proj_control = shader_spirv_has_ffp_proj_control, + .shader_compile = wined3d_spirv_compile, };
const struct wined3d_shader_backend_ops *wined3d_spirv_shader_backend_init_vk(void) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index f9babc6e28f..377281a12f7 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5115,6 +5115,9 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk, if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain) flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+ if (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS) + flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + switch (resource->type) { case WINED3D_RTYPE_TEXTURE_1D: diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 4019dd4d812..c08c28f13f5 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -174,19 +174,6 @@ static const struct wined3d_format_channels formats[] = {WINED3DFMT_B8G8R8X8_TYPELESS, 8, 8, 8, 0, 16, 8, 0, 0, 4, 0, 0}, };
-enum wined3d_channel_type -{ - WINED3D_CHANNEL_TYPE_NONE, - WINED3D_CHANNEL_TYPE_UNORM, - WINED3D_CHANNEL_TYPE_SNORM, - WINED3D_CHANNEL_TYPE_UINT, - WINED3D_CHANNEL_TYPE_SINT, - WINED3D_CHANNEL_TYPE_FLOAT, - WINED3D_CHANNEL_TYPE_DEPTH, - WINED3D_CHANNEL_TYPE_STENCIL, - WINED3D_CHANNEL_TYPE_UNUSED, -}; - struct wined3d_typed_format_info { enum wined3d_format_id id; @@ -4396,6 +4383,22 @@ const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *ad return format; }
+enum wined3d_format_id wined3d_get_typed_format_id(const struct wined3d_adapter *adapter, + const struct wined3d_format *format, enum wined3d_channel_type channel_type) +{ + const struct wined3d_typed_format_info *info; + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(typed_formats); ++i) + { + info = &typed_formats[i]; + if (info->typeless_id == format->typeless_id && map_channel_type(info->channels[0]) == channel_type) + return info->id; + } + + return WINED3DFMT_UNKNOWN; +} + BOOL wined3d_format_is_depth_view(enum wined3d_format_id resource_format_id, enum wined3d_format_id view_format_id) { diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index dfca8fc53f8..6a3a3e29ad9 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -21,6 +21,7 @@ #include "wine/port.h"
#include "wined3d_private.h" +#include "wined3d_shaders.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
@@ -1712,67 +1713,415 @@ HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_vi return hr; }
+struct wined3d_uav_clear_constants_vk +{ + VkClearColorValue color; + VkOffset2D offset; + VkExtent2D extent; +}; + +static VkPipeline create_uav_pipeline(struct wined3d_context_vk *context_vk, + struct wined3d_pipeline_layout_vk *layout, struct wined3d_shader_desc shader_desc, + enum wined3d_shader_resource_type resource_type) +{ + VkComputePipelineCreateInfo pipeline_info; + const struct wined3d_vk_info *vk_info; + struct wined3d_context *context; + VkShaderModule shader_module; + VkDevice vk_device; + VkPipeline result; + VkResult vr; + + vk_info = context_vk->vk_info; + context = &context_vk->c; + + shader_module = (VkShaderModule)context->device->adapter->shader_backend->shader_compile(context, &shader_desc, + WINED3D_SHADER_TYPE_COMPUTE); + if (shader_module == VK_NULL_HANDLE) + { + ERR("Failed to create shader.\n"); + return VK_NULL_HANDLE; + } + + pipeline_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipeline_info.pNext = NULL; + pipeline_info.flags = 0; + pipeline_info.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + pipeline_info.stage.pNext = NULL; + pipeline_info.stage.flags = 0; + pipeline_info.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; + pipeline_info.stage.pName = "main"; + pipeline_info.stage.pSpecializationInfo = NULL; + pipeline_info.stage.module = shader_module; + pipeline_info.layout = layout->vk_pipeline_layout; + pipeline_info.basePipelineHandle = VK_NULL_HANDLE; + pipeline_info.basePipelineIndex = -1; + + vk_device = wined3d_device_vk(context->device)->vk_device; + + if ((vr = VK_CALL(vkCreateComputePipelines(vk_device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &result))) < 0) + { + ERR("Failed to create Vulkan compute pipeline, vr %s.\n", wined3d_debug_vkresult(vr)); + return VK_NULL_HANDLE; + } + + VK_CALL(vkDestroyShaderModule(vk_device, shader_module, NULL)); + return result; +} + +void wined3d_device_vk_uav_clear_state_init(struct wined3d_device_vk *device_vk) +{ + struct wined3d_uav_clear_state_vk *state = &device_vk->uav_clear_state; + struct wined3d_context_vk *context_vk = &device_vk->context_vk; + VkDescriptorSetLayoutBinding vk_set_bindings[2]; + + vk_set_bindings[1].binding = 0; + vk_set_bindings[1].descriptorCount = 1; + vk_set_bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + vk_set_bindings[1].pImmutableSamplers = NULL; + vk_set_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + + vk_set_bindings[0].binding = 1; + vk_set_bindings[0].descriptorCount = 1; + vk_set_bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + vk_set_bindings[0].pImmutableSamplers = NULL; + + vk_set_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + state->image_layout = wined3d_context_vk_get_pipeline_layout(context_vk, vk_set_bindings, 2); + + vk_set_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + state->buffer_layout = wined3d_context_vk_get_pipeline_layout(context_vk, vk_set_bindings, 2); + +#define SHADER_DESC(name) (struct wined3d_shader_desc){ name, sizeof(name) } + state->float_pipelines.buffer = create_uav_pipeline(context_vk, state->buffer_layout, + SHADER_DESC(cs_uav_clear_buffer_float_code), WINED3D_SHADER_RESOURCE_BUFFER); + state->uint_pipelines.buffer = create_uav_pipeline(context_vk, state->buffer_layout, + SHADER_DESC(cs_uav_clear_buffer_uint_code), WINED3D_SHADER_RESOURCE_BUFFER); + state->float_pipelines.image_1d = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_1d_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_1D); + state->uint_pipelines.image_1d = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_1d_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_1D); + state->float_pipelines.image_1d_array = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_1d_array_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY); + state->uint_pipelines.image_1d_array = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_1d_array_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY); + state->float_pipelines.image_2d = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_2d_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_2D); + state->uint_pipelines.image_2d = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_2d_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_2D); + state->float_pipelines.image_2d_array = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_2d_array_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY); + state->uint_pipelines.image_2d_array = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_2d_array_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY); + state->float_pipelines.image_3d = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_3d_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_3D); + state->uint_pipelines.image_3d = create_uav_pipeline(context_vk, state->image_layout, + SHADER_DESC(cs_uav_clear_3d_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_3D); +#undef SHADER_DESC + + state->buffer_group_size = (struct wined3d_shader_thread_group_size){128, 1, 1}; + state->image_1d_group_size = (struct wined3d_shader_thread_group_size){ 64, 1, 1}; + state->image_1d_array_group_size = (struct wined3d_shader_thread_group_size){ 64, 1, 1}; + state->image_2d_group_size = (struct wined3d_shader_thread_group_size){ 8, 8, 1}; + state->image_2d_array_group_size = (struct wined3d_shader_thread_group_size){ 8, 8, 1}; + state->image_3d_group_size = (struct wined3d_shader_thread_group_size){ 8, 8, 1}; +} + +void wined3d_device_vk_uav_clear_state_cleanup(struct wined3d_device_vk *device_vk) +{ + struct wined3d_uav_clear_state_vk *state = &device_vk->uav_clear_state; + const struct wined3d_vk_info *vk_info = &device_vk->vk_info; + + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->float_pipelines.buffer, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->float_pipelines.image_1d, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->float_pipelines.image_1d_array, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->float_pipelines.image_2d, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->float_pipelines.image_2d_array, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->float_pipelines.image_3d, NULL)); + + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->uint_pipelines.buffer, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->uint_pipelines.image_1d, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->uint_pipelines.image_1d_array, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->uint_pipelines.image_2d, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->uint_pipelines.image_2d_array, NULL)); + VK_CALL(vkDestroyPipeline(device_vk->vk_device, state->uint_pipelines.image_3d, NULL)); +} + void wined3d_unordered_access_view_vk_clear(struct wined3d_unordered_access_view_vk *view_vk, const struct wined3d_uvec4 *clear_value, struct wined3d_context_vk *context_vk, bool fp) { + struct wined3d_bo_address cb_source_address, cb_destination_address; + const struct wined3d_format *view_format = view_vk->v.format; + struct wined3d_view_desc *view_desc = &view_vk->v.desc; + struct wined3d_uav_clear_constants_vk constants = {0}; + struct wined3d_device *device = context_vk->c.device; + struct wined3d_shader_thread_group_size group_count; + enum wined3d_format_id format_id = view_format->id; + struct wined3d_uav_clear_pipelines_vk *pipelines; + struct wined3d_texture_vk *texture_vk = NULL; + struct wined3d_pipeline_layout_vk *layout; + struct wined3d_uav_clear_state_vk *state; const struct wined3d_vk_info *vk_info; - const struct wined3d_format *format; - struct wined3d_buffer_vk *buffer_vk; + VkDescriptorImageInfo vk_image_info; + struct wined3d_device_vk *device_vk; + VkDescriptorBufferInfo buffer_info; struct wined3d_resource *resource; VkCommandBuffer vk_command_buffer; - VkBufferMemoryBarrier vk_barrier; - VkAccessFlags access_mask; - unsigned int offset, size; + struct wined3d_bo_vk constants_bo; + VkWriteDescriptorSet vk_writes[2]; + VkBufferView vk_buffer_view; + VkMemoryBarrier vk_barrier; + VkPipeline vk_pipeline; + DWORD uav_location; + unsigned int level; + bool is_array; + VkResult vr;
- TRACE("view_vk %p, clear_value %s, context_vk %p, fp %#x.\n", view_vk, debug_uvec4(clear_value), context_vk, fp); + device_vk = wined3d_device_vk(device); + state = &device_vk->uav_clear_state; + pipelines = fp ? &state->float_pipelines : &state->uint_pipelines;
resource = view_vk->v.resource; - if (resource->type != WINED3D_RTYPE_BUFFER) + is_array = view_desc->flags & WINED3D_VIEW_TEXTURE_ARRAY; + + switch (resource->type) { - FIXME("Not implemented for %s resources.\n", debug_d3dresourcetype(resource->type)); + case WINED3D_RTYPE_BUFFER: + vk_pipeline = pipelines->buffer; + group_count = state->buffer_group_size; + break; + case WINED3D_RTYPE_TEXTURE_1D: + if (is_array) + { + vk_pipeline = pipelines->image_1d_array; + group_count = state->image_1d_array_group_size; + } + else + { + vk_pipeline = pipelines->image_1d; + group_count = state->image_1d_group_size; + } + break; + case WINED3D_RTYPE_TEXTURE_2D: + if (is_array) + { + vk_pipeline = pipelines->image_2d_array; + group_count = state->image_2d_array_group_size; + } + else + { + vk_pipeline = pipelines->image_2d; + group_count = state->image_2d_group_size; + } + break; + case WINED3D_RTYPE_TEXTURE_3D: + vk_pipeline = pipelines->image_3d; + group_count = state->image_3d_group_size; + break; + + default: + ERR("Unhandled resource type %s.\n", debug_d3dresourcetype(resource->type)); + return; + } + + if (vk_pipeline == VK_NULL_HANDLE) + { + ERR("Pipeline was not correctly initialized.\n"); return; }
- format = view_vk->v.format; - if (format->id != WINED3DFMT_R32_UINT && format->id != WINED3DFMT_R32_SINT) + vk_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + vk_writes[0].pNext = NULL; + vk_writes[0].dstBinding = 1; + vk_writes[0].dstArrayElement = 0; + vk_writes[0].descriptorCount = 1; + vk_writes[0].pImageInfo = NULL; + vk_writes[0].pTexelBufferView = &vk_buffer_view; + vk_writes[0].pImageInfo = &vk_image_info; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + uav_location = WINED3D_LOCATION_BUFFER; + layout = state->buffer_layout; + vk_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + + constants.extent.width = view_desc->u.buffer.count; + constants.extent.height = 1; + } + else { - FIXME("Not implemented for format %s.\n", debug_d3dformat(format->id)); + texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(resource)); + + uav_location = WINED3D_LOCATION_TEXTURE_RGB; + layout = state->image_layout; + vk_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; + + level = view_desc->u.texture.level_idx; + constants.extent.width = wined3d_texture_get_level_width(&texture_vk->t, level); + constants.extent.height = wined3d_texture_get_level_height(&texture_vk->t, level); + group_count.z = (view_desc->u.texture.layer_count + group_count.z - 1) / group_count.z; + } + + group_count.x = (constants.extent.width + group_count.x - 1) / group_count.x; + group_count.y = (constants.extent.height + group_count.y - 1) / group_count.y; + + constants.color.uint32[0] = clear_value->x; + constants.color.uint32[1] = clear_value->y; + constants.color.uint32[2] = clear_value->z; + constants.color.uint32[3] = clear_value->w; + + if (!fp) + { + /* Make sure values are truncated, not saturated to some maximum value. */ + constants.color.uint32[0] &= ~(~0ull << view_format->red_size); + constants.color.uint32[1] &= ~(~0ull << view_format->green_size); + constants.color.uint32[2] &= ~(~0ull << view_format->blue_size); + constants.color.uint32[3] &= ~(~0ull << view_format->alpha_size); + + if (view_format->id == WINED3DFMT_R11G11B10_FLOAT) + { + constants.color.uint32[0] |= constants.color.uint32[1] << 11; + constants.color.uint32[0] |= constants.color.uint32[2] << 22; + format_id = WINED3DFMT_R32_UINT; + } + else + { + format_id = wined3d_get_typed_format_id(context_vk->c.device->adapter, view_format, + WINED3D_CHANNEL_TYPE_UINT); + } + } + + if (format_id == WINED3DFMT_UNKNOWN) + { + ERR("Unsupported format %s.", debug_d3dformat(view_format->id)); return; }
+ wined3d_view_load_location(resource, view_desc, &context_vk->c, uav_location); + wined3d_unordered_access_view_invalidate_location(&view_vk->v, ~uav_location); + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + if (format_id == view_format->id) + vk_buffer_view = view_vk->view_vk.u.vk_buffer_view; + else + { + vk_buffer_view = wined3d_view_vk_create_vk_buffer_view(context_vk, view_desc, + wined3d_buffer_vk(buffer_from_resource(resource)), wined3d_format_vk( + wined3d_get_format(context_vk->c.device->adapter, format_id, WINED3D_BIND_UNORDERED_ACCESS))); + if (vk_buffer_view == VK_NULL_HANDLE) + return; + } + } + else + { + if (format_id == view_format->id) + { + vk_image_info = view_vk->view_vk.u.vk_image_info; + if (!vk_image_info.imageView) + { + const VkDescriptorImageInfo *default_info; + if (!(default_info = wined3d_texture_vk_get_default_image_info(texture_vk, context_vk))) + return; + vk_image_info = *default_info; + } + } + else + { + vk_image_info.sampler = VK_NULL_HANDLE; + vk_image_info.imageLayout = texture_vk->layout; + vk_image_info.imageView = wined3d_view_vk_create_vk_image_view(context_vk, view_desc, texture_vk, + wined3d_format_vk(wined3d_get_format(context_vk->c.device->adapter, format_id, + WINED3D_BIND_UNORDERED_ACCESS)), + COLOR_FIXUP_IDENTITY, false); + + if (vk_image_info.imageView == VK_NULL_HANDLE) + return; + } + } + + vk_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + vk_writes[1].pNext = NULL; + vk_writes[1].dstBinding = 0; + vk_writes[1].dstArrayElement = 0; + vk_writes[1].descriptorCount = 1; + vk_writes[1].pImageInfo = NULL; + vk_writes[1].pTexelBufferView = NULL; + vk_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + vk_writes[1].pBufferInfo = &buffer_info; + + if (!wined3d_context_vk_create_bo(context_vk, sizeof(constants), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &constants_bo)) + { + ERR("Failed to create constants BO.\n"); + goto out; + } + + cb_source_address.buffer_object = 0; + cb_source_address.addr = (BYTE *)&constants; + cb_destination_address.buffer_object = (UINT_PTR)&constants_bo; + cb_destination_address.addr = 0; + + adapter_vk_copy_bo_address(&context_vk->c, &cb_destination_address, &cb_source_address, sizeof(constants)); + + buffer_info.buffer = constants_bo.vk_buffer; + buffer_info.range = constants_bo.size; + buffer_info.offset = constants_bo.buffer_offset; + vk_info = context_vk->vk_info; - buffer_vk = wined3d_buffer_vk(buffer_from_resource(resource)); - wined3d_buffer_load_location(&buffer_vk->b, &context_vk->c, WINED3D_LOCATION_BUFFER); - wined3d_buffer_invalidate_location(&buffer_vk->b, ~WINED3D_LOCATION_BUFFER);
- get_buffer_view_range(&buffer_vk->b, &view_vk->v.desc, format, &offset, &size); + vr = wined3d_context_vk_create_vk_descriptor_set(context_vk, layout->vk_set_layout, &vk_writes[0].dstSet); + if (vr != VK_SUCCESS) + { + ERR("Failed to create descriptor set.\n"); + wined3d_context_vk_destroy_bo(context_vk, &constants_bo); + goto out; + } + + vk_writes[1].dstSet = vk_writes[0].dstSet;
- if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk))) - return; + VK_CALL(vkUpdateDescriptorSets(device_vk->vk_device, 2, vk_writes, 0, NULL)); + + vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk); wined3d_context_vk_end_current_render_pass(context_vk);
- access_mask = vk_access_mask_from_bind_flags(buffer_vk->b.resource.bind_flags); - vk_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + wined3d_context_vk_reference_unordered_access_view(context_vk, view_vk); + wined3d_context_vk_reference_bo(context_vk, &constants_bo); + wined3d_context_vk_destroy_bo(context_vk, &constants_bo); + + vk_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; vk_barrier.pNext = NULL; - vk_barrier.srcAccessMask = access_mask; - vk_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - vk_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - vk_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - vk_barrier.buffer = buffer_vk->bo.vk_buffer; - vk_barrier.offset = buffer_vk->bo.buffer_offset + offset; - vk_barrier.size = size; - VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL)); - - VK_CALL(vkCmdFillBuffer(vk_command_buffer, buffer_vk->bo.vk_buffer, - buffer_vk->bo.buffer_offset + offset, size, clear_value->x)); - - vk_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - vk_barrier.dstAccessMask = access_mask; - VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, NULL, 1, &vk_barrier, 0, NULL)); - - wined3d_context_vk_reference_bo(context_vk, &buffer_vk->bo); + vk_barrier.srcAccessMask = vk_access_mask_from_bind_flags(resource->bind_flags); + vk_barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + + VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, + vk_pipeline_stage_mask_from_bind_flags(resource->bind_flags), + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, 1, &vk_barrier, 0, NULL, 0, NULL)); + VK_CALL(vkCmdBindPipeline(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline)); + VK_CALL(vkCmdBindDescriptorSets(vk_command_buffer, VK_PIPELINE_BIND_POINT_COMPUTE, + layout->vk_pipeline_layout, 0, 1, &vk_writes[0].dstSet, 0, NULL)); + VK_CALL(vkCmdDispatch(vk_command_buffer, group_count.x, group_count.y, group_count.z)); + + vk_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + vk_barrier.dstAccessMask = vk_access_mask_from_bind_flags(resource->bind_flags); + + VK_CALL(vkCmdPipelineBarrier(vk_command_buffer, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + vk_pipeline_stage_mask_from_bind_flags(resource->bind_flags), + 0, 1, &vk_barrier, 0, NULL, 0, NULL)); + + context_invalidate_compute_state(&context_vk->c, STATE_COMPUTE_SHADER); + +out: + if (format_id != view_format->id) + { + if (resource->type == WINED3D_RTYPE_BUFFER) + wined3d_context_vk_destroy_vk_buffer_view(context_vk, vk_buffer_view, view_vk->view_vk.command_buffer_id); + else + wined3d_context_vk_destroy_vk_image_view(context_vk, vk_image_info.imageView, + view_vk->view_vk.command_buffer_id); + } }
void wined3d_unordered_access_view_vk_update(struct wined3d_unordered_access_view_vk *uav_vk, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 85e8261e840..95da4c52664 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1524,6 +1524,8 @@ struct wined3d_shader_backend_ops void (*shader_get_caps)(const struct wined3d_adapter *adapter, struct shader_caps *caps); BOOL (*shader_color_fixup_supported)(struct color_fixup_desc fixup); BOOL (*shader_has_ffp_proj_control)(void *shader_priv); + uint64_t (*shader_compile)(struct wined3d_context *context, const struct wined3d_shader_desc *shader_desc, + enum wined3d_shader_type shader_type); };
extern const struct wined3d_shader_backend_ops glsl_shader_backend DECLSPEC_HIDDEN; @@ -2675,6 +2677,8 @@ void wined3d_context_vk_submit_command_buffer(struct wined3d_context_vk *context unsigned int wait_semaphore_count, const VkSemaphore *wait_semaphores, const VkPipelineStageFlags *wait_stages, unsigned int signal_semaphore_count, const VkSemaphore *signal_semaphores) DECLSPEC_HIDDEN; void wined3d_context_vk_wait_command_buffer(struct wined3d_context_vk *context_vk, uint64_t id) DECLSPEC_HIDDEN; +VkResult wined3d_context_vk_create_vk_descriptor_set(struct wined3d_context_vk *context_vk, + VkDescriptorSetLayout vk_set_layout, VkDescriptorSet *vk_descriptor_set) DECLSPEC_HIDDEN;
typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id);
@@ -3474,6 +3478,8 @@ struct wined3d_adapter *wined3d_adapter_vk_create(unsigned int ordinal, unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN; unsigned int wined3d_adapter_vk_get_memory_type_index(const struct wined3d_adapter_vk *adapter_vk, uint32_t memory_type_mask, VkMemoryPropertyFlags flags) DECLSPEC_HIDDEN; +void adapter_vk_copy_bo_address(struct wined3d_context *context, const struct wined3d_bo_address *dst, + const struct wined3d_bo_address *src, size_t size) DECLSPEC_HIDDEN;
struct wined3d_caps_gl_ctx { @@ -4016,6 +4022,32 @@ void wined3d_allocator_cleanup(struct wined3d_allocator *allocator) DECLSPEC_HID bool wined3d_allocator_init(struct wined3d_allocator *allocator, size_t pool_count, const struct wined3d_allocator_ops *allocator_ops) DECLSPEC_HIDDEN;
+struct wined3d_uav_clear_pipelines_vk +{ + VkPipeline buffer; + VkPipeline image_1d; + VkPipeline image_1d_array; + VkPipeline image_2d; + VkPipeline image_2d_array; + VkPipeline image_3d; +}; + +struct wined3d_uav_clear_state_vk +{ + struct wined3d_uav_clear_pipelines_vk float_pipelines; + struct wined3d_uav_clear_pipelines_vk uint_pipelines; + + struct wined3d_shader_thread_group_size buffer_group_size; + struct wined3d_shader_thread_group_size image_1d_group_size; + struct wined3d_shader_thread_group_size image_1d_array_group_size; + struct wined3d_shader_thread_group_size image_2d_group_size; + struct wined3d_shader_thread_group_size image_2d_array_group_size; + struct wined3d_shader_thread_group_size image_3d_group_size; + + struct wined3d_pipeline_layout_vk *image_layout; + struct wined3d_pipeline_layout_vk *buffer_layout; +}; + struct wined3d_device_vk { struct wined3d_device d; @@ -4033,6 +4065,8 @@ struct wined3d_device_vk struct wined3d_null_views_vk null_views_vk;
struct wined3d_allocator allocator; + + struct wined3d_uav_clear_state_vk uav_clear_state; };
static inline struct wined3d_device_vk *wined3d_device_vk(struct wined3d_device *device) @@ -4049,6 +4083,9 @@ void wined3d_device_vk_destroy_null_resources(struct wined3d_device_vk *device_v void wined3d_device_vk_destroy_null_views(struct wined3d_device_vk *device_vk, struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
+void wined3d_device_vk_uav_clear_state_init(struct wined3d_device_vk *device_vk) DECLSPEC_HIDDEN; +void wined3d_device_vk_uav_clear_state_cleanup(struct wined3d_device_vk *device_vk) DECLSPEC_HIDDEN; + static inline float wined3d_alpha_ref(const struct wined3d_state *state) { return (state->render_states[WINED3D_RS_ALPHAREF] & 0xff) / 255.0f; @@ -5808,6 +5845,19 @@ struct wined3d_color_key_conversion unsigned int width, unsigned int height, const struct wined3d_color_key *colour_key); };
+enum wined3d_channel_type +{ + WINED3D_CHANNEL_TYPE_NONE, + WINED3D_CHANNEL_TYPE_UNORM, + WINED3D_CHANNEL_TYPE_SNORM, + WINED3D_CHANNEL_TYPE_UINT, + WINED3D_CHANNEL_TYPE_SINT, + WINED3D_CHANNEL_TYPE_FLOAT, + WINED3D_CHANNEL_TYPE_DEPTH, + WINED3D_CHANNEL_TYPE_STENCIL, + WINED3D_CHANNEL_TYPE_UNUSED, +}; + struct wined3d_format { enum wined3d_format_id id; @@ -5853,6 +5903,8 @@ struct wined3d_format
const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *adapter, enum wined3d_format_id format_id, unsigned int bind_flags) DECLSPEC_HIDDEN; +enum wined3d_format_id wined3d_get_typed_format_id(const struct wined3d_adapter *adapter, + const struct wined3d_format *format, enum wined3d_channel_type channel_type) DECLSPEC_HIDDEN; void wined3d_format_calculate_pitch(const struct wined3d_format *format, unsigned int alignment, unsigned int width, unsigned int height, unsigned int *row_pitch, unsigned int *slice_pitch) DECLSPEC_HIDDEN; UINT wined3d_format_calculate_size(const struct wined3d_format *format, diff --git a/dlls/wined3d/wined3d_shaders.h b/dlls/wined3d/wined3d_shaders.h new file mode 100644 index 00000000000..db763290af9 --- /dev/null +++ b/dlls/wined3d/wined3d_shaders.h @@ -0,0 +1,388 @@ +/* + * Copyright 2019 Philip Rebohle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINED3D_SHADERS_H +#define __WINE_WINED3D_SHADERS_H + +static const uint32_t cs_uav_clear_buffer_float_code[] = +{ +#if 0 + RWBuffer<float4> dst; + + struct + { + float4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(128, 1, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (thread_id.x < u_info.dst_extent.x) + dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value; + } +#endif + 0x43425844, 0xe114ba61, 0xff6a0d0b, 0x7b25c8f4, 0xfcf7cf22, 0x00000001, 0x0000010c, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400089c, 0x0011e000, 0x00000000, 0x00005555, + 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000080, 0x00000001, 0x00000001, + 0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000, + 0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, + 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_buffer_uint_code[] = +{ +#if 0 + RWBuffer<uint4> dst; + + struct + { + uint4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(128, 1, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (thread_id.x < u_info.dst_extent.x) + dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value; + } +#endif + 0x43425844, 0x3afd0cfd, 0x5145c166, 0x5b9f76b8, 0xa73775cd, 0x00000001, 0x0000010c, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400089c, 0x0011e000, 0x00000000, 0x00004444, + 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000080, 0x00000001, 0x00000001, + 0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000, + 0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, + 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_1d_array_float_code[] = +{ +#if 0 + RWTexture1DArray<float4> dst; + + struct + { + float4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(64, 1, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (thread_id.x < u_info.dst_extent.x) + dst[int2(u_info.dst_offset.x + thread_id.x, thread_id.y)] = u_info.clear_value; + } +#endif + 0x43425844, 0x3d73bc2d, 0x2b635f3d, 0x6bf98e92, 0xbe0aa5d9, 0x00000001, 0x0000011c, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000c8, 0x00050050, 0x00000032, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400389c, 0x0011e000, 0x00000000, 0x00005555, + 0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, + 0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000, + 0x00000001, 0x04000036, 0x001000e2, 0x00000000, 0x00020556, 0x080000a4, 0x0011e0f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_1d_array_uint_code[] = +{ +#if 0 + RWTexture1DArray<uint4> dst; + + struct + { + uint4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(64, 1, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (thread_id.x < u_info.dst_extent.x) + dst[int2(u_info.dst_offset.x + thread_id.x, thread_id.y)] = u_info.clear_value; + } +#endif + 0x43425844, 0x2f0ca457, 0x72068b34, 0xd9dadc2b, 0xd3178c3e, 0x00000001, 0x0000011c, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000c8, 0x00050050, 0x00000032, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400389c, 0x0011e000, 0x00000000, 0x00004444, + 0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, + 0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000, + 0x00000001, 0x04000036, 0x001000e2, 0x00000000, 0x00020556, 0x080000a4, 0x0011e0f2, 0x00000000, + 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_1d_float_code[] = +{ +#if 0 + RWTexture1D<float4> dst; + + struct + { + float4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(64, 1, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (thread_id.x < u_info.dst_extent.x) + dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value; + } +#endif + 0x43425844, 0x05266503, 0x4b97006f, 0x01a5cc63, 0xe617d0a1, 0x00000001, 0x0000010c, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400109c, 0x0011e000, 0x00000000, 0x00005555, + 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, + 0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000, + 0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, + 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_1d_uint_code[] = +{ +#if 0 + RWTexture1D<uint4> dst; + + struct + { + uint4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(64, 1, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (thread_id.x < u_info.dst_extent.x) + dst[u_info.dst_offset.x + thread_id.x] = u_info.clear_value; + } +#endif + 0x43425844, 0x19d5c8f2, 0x3ca4ac24, 0x9e258499, 0xf0463fd6, 0x00000001, 0x0000010c, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000b8, 0x00050050, 0x0000002e, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400109c, 0x0011e000, 0x00000000, 0x00004444, + 0x0200005f, 0x00020012, 0x02000068, 0x00000001, 0x0400009b, 0x00000040, 0x00000001, 0x00000001, + 0x07000022, 0x00100012, 0x00000000, 0x0002000a, 0x0020802a, 0x00000000, 0x00000001, 0x0304001f, + 0x0010000a, 0x00000000, 0x0700001e, 0x00100012, 0x00000000, 0x0002000a, 0x0020800a, 0x00000000, + 0x00000001, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100006, 0x00000000, 0x00208e46, 0x00000000, + 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_2d_array_float_code[] = +{ +#if 0 + RWTexture2DArray<float4> dst; + + struct + { + float4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(8, 8, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (all(thread_id.xy < u_info.dst_extent.xy)) + dst[int3(u_info.dst_offset.xy + thread_id.xy, thread_id.z)] = u_info.clear_value; + } +#endif + 0x43425844, 0x924d2d2c, 0xb9166376, 0x99f83871, 0x8ef65025, 0x00000001, 0x00000138, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400409c, 0x0011e000, 0x00000000, 0x00005555, + 0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001, + 0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001, + 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001, + 0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_2d_array_uint_code[] = +{ +#if 0 + RWTexture2DArray<uint4> dst; + + struct + { + uint4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(8, 8, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (all(thread_id.xy < u_info.dst_extent.xy)) + dst[int3(u_info.dst_offset.xy + thread_id.xy, thread_id.z)] = u_info.clear_value; + } +#endif + 0x43425844, 0xa92219d4, 0xa2c5e47d, 0x0d308500, 0xf32197b4, 0x00000001, 0x00000138, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400409c, 0x0011e000, 0x00000000, 0x00004444, + 0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001, + 0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001, + 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001, + 0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_2d_float_code[] = +{ +#if 0 + RWTexture2D<float4> dst; + + struct + { + float4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(8, 8, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (all(thread_id.xy < u_info.dst_extent.xy)) + dst[u_info.dst_offset.xy + thread_id.xy] = u_info.clear_value; + } +#endif + 0x43425844, 0x6e735b3f, 0x7348c4fa, 0xb3634e42, 0x50e2d99b, 0x00000001, 0x00000128, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000d4, 0x00050050, 0x00000035, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400189c, 0x0011e000, 0x00000000, 0x00005555, + 0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001, + 0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001, + 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, + 0x00000000, 0x0700001e, 0x001000f2, 0x00000000, 0x00020546, 0x00208546, 0x00000000, 0x00000001, + 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, + 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_2d_uint_code[] = +{ +#if 0 + RWTexture2D<uint4> dst; + + struct + { + uint4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(8, 8, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (all(thread_id.xy < u_info.dst_extent.xy)) + dst[u_info.dst_offset.xy + thread_id.xy] = u_info.clear_value; + } +#endif + 0x43425844, 0xf01db5dd, 0xc7dc5e55, 0xb017c1a8, 0x55abd52d, 0x00000001, 0x00000128, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000d4, 0x00050050, 0x00000035, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400189c, 0x0011e000, 0x00000000, 0x00004444, + 0x0200005f, 0x00020032, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001, + 0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001, + 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, + 0x00000000, 0x0700001e, 0x001000f2, 0x00000000, 0x00020546, 0x00208546, 0x00000000, 0x00000001, + 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, + 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_3d_float_code[] = +{ +#if 0 + RWTexture3D<float4> dst; + + struct + { + float4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(8, 8, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (all(thread_id.xy < u_info.dst_extent.xy)) + dst[int3(u_info.dst_offset.xy, 0) + thread_id.xyz] = u_info.clear_value; + } +#endif + 0x43425844, 0x5d8f36a0, 0x30fa86a5, 0xfec7f2ef, 0xdfd76cbb, 0x00000001, 0x00000138, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400289c, 0x0011e000, 0x00000000, 0x00005555, + 0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001, + 0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001, + 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001, + 0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e, +}; + +static const uint32_t cs_uav_clear_3d_uint_code[] = +{ +#if 0 + RWTexture3D<uint4> dst; + + struct + { + uint4 clear_value; + int2 dst_offset; + int2 dst_extent; + } u_info; + + [numthreads(8, 8, 1)] + void main(int3 thread_id : SV_DispatchThreadID) + { + if (all(thread_id.xy < u_info.dst_extent.xy)) + dst[int3(u_info.dst_offset.xy, 0) + thread_id.xyz] = u_info.clear_value; + } +#endif + 0x43425844, 0x5b9c95b1, 0xc9bde4e3, 0x9aaff806, 0x24a1d264, 0x00000001, 0x00000138, 0x00000003, + 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, + 0x00000008, 0x00000000, 0x00000008, 0x58454853, 0x000000e4, 0x00050050, 0x00000039, 0x0100086a, + 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x0400289c, 0x0011e000, 0x00000000, 0x00004444, + 0x0200005f, 0x00020072, 0x02000068, 0x00000001, 0x0400009b, 0x00000008, 0x00000008, 0x00000001, + 0x07000022, 0x00100032, 0x00000000, 0x00020046, 0x00208ae6, 0x00000000, 0x00000001, 0x07000001, + 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, + 0x00000000, 0x0700001e, 0x00100032, 0x00000000, 0x00020046, 0x00208046, 0x00000000, 0x00000001, + 0x04000036, 0x001000c2, 0x00000000, 0x00020aa6, 0x080000a4, 0x0011e0f2, 0x00000000, 0x00100e46, + 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x01000015, 0x0100003e, +}; + +#endif
On Thu, 23 Sept 2021 at 10:43, Jan Sikorski jsikorski@codeweavers.com wrote:
@@ -1166,6 +1173,7 @@ static const struct wined3d_shader_backend_ops spirv_shader_backend_vk = .shader_get_caps = shader_spirv_get_caps, .shader_color_fixup_supported = shader_spirv_color_fixup_supported, .shader_has_ffp_proj_control = shader_spirv_has_ffp_proj_control,
- .shader_compile = wined3d_spirv_compile,
};
The name wined3d_spirv_compile() looks a bit out of place, I think. I guess that's to avoid clashing with the existing shader_spirv_compile(), but perhaps it makes sense to rename shader_spirv_compile() to e.g. shader_spirv_compile_spirv(), shader_spirv_compile_shader(), or some variant.
@@ -5115,6 +5115,9 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk, if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain) flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
- if (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS)
flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
This could probably be done as a separate change, and I think it deserves a comment that this is for creating views with a different format for UAV clears. We may as well use "else if", I guess.
+void wined3d_device_vk_uav_clear_state_init(struct wined3d_device_vk *device_vk) +{
- struct wined3d_uav_clear_state_vk *state = &device_vk->uav_clear_state;
- struct wined3d_context_vk *context_vk = &device_vk->context_vk;
- VkDescriptorSetLayoutBinding vk_set_bindings[2];
- vk_set_bindings[1].binding = 0;
- vk_set_bindings[1].descriptorCount = 1;
- vk_set_bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
- vk_set_bindings[1].pImmutableSamplers = NULL;
- vk_set_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
- vk_set_bindings[0].binding = 1;
- vk_set_bindings[0].descriptorCount = 1;
- vk_set_bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
- vk_set_bindings[0].pImmutableSamplers = NULL;
- vk_set_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
- state->image_layout = wined3d_context_vk_get_pipeline_layout(context_vk, vk_set_bindings, 2);
- vk_set_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
- state->buffer_layout = wined3d_context_vk_get_pipeline_layout(context_vk, vk_set_bindings, 2);
The initialisation order of "vk_set_bindings" seems a little odd. I suppose it's ok.
+#define SHADER_DESC(name) (struct wined3d_shader_desc){ name, sizeof(name) }
- state->float_pipelines.buffer = create_uav_pipeline(context_vk, state->buffer_layout,
SHADER_DESC(cs_uav_clear_buffer_float_code), WINED3D_SHADER_RESOURCE_BUFFER);
- state->uint_pipelines.buffer = create_uav_pipeline(context_vk, state->buffer_layout,
SHADER_DESC(cs_uav_clear_buffer_uint_code), WINED3D_SHADER_RESOURCE_BUFFER);
- state->float_pipelines.image_1d = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_1d_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_1D);
- state->uint_pipelines.image_1d = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_1d_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_1D);
- state->float_pipelines.image_1d_array = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_1d_array_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY);
- state->uint_pipelines.image_1d_array = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_1d_array_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_1DARRAY);
- state->float_pipelines.image_2d = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_2d_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_2D);
- state->uint_pipelines.image_2d = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_2d_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_2D);
- state->float_pipelines.image_2d_array = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_2d_array_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY);
- state->uint_pipelines.image_2d_array = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_2d_array_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_2DARRAY);
- state->float_pipelines.image_3d = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_3d_float_code), WINED3D_SHADER_RESOURCE_TEXTURE_3D);
- state->uint_pipelines.image_3d = create_uav_pipeline(context_vk, state->image_layout,
SHADER_DESC(cs_uav_clear_3d_uint_code), WINED3D_SHADER_RESOURCE_TEXTURE_3D);
+#undef SHADER_DESC
- state->buffer_group_size = (struct wined3d_shader_thread_group_size){128, 1, 1};
- state->image_1d_group_size = (struct wined3d_shader_thread_group_size){ 64, 1, 1};
- state->image_1d_array_group_size = (struct wined3d_shader_thread_group_size){ 64, 1, 1};
- state->image_2d_group_size = (struct wined3d_shader_thread_group_size){ 8, 8, 1};
- state->image_2d_array_group_size = (struct wined3d_shader_thread_group_size){ 8, 8, 1};
- state->image_3d_group_size = (struct wined3d_shader_thread_group_size){ 8, 8, 1};
+}
I'm not sure how we feel about compound literals in Wine these days. I guess they're convenient here, but they don't seem terribly hard to avoid either.
- if (!fp)
- {
/* Make sure values are truncated, not saturated to some maximum value. */
constants.color.uint32[0] &= ~(~0ull << view_format->red_size);
constants.color.uint32[1] &= ~(~0ull << view_format->green_size);
constants.color.uint32[2] &= ~(~0ull << view_format->blue_size);
constants.color.uint32[3] &= ~(~0ull << view_format->alpha_size);
That's wined3d_mask_from_size(), essentially.
On 27 Sep 2021, at 20:47, Henri Verbeet hverbeet@gmail.com wrote:
@@ -5115,6 +5115,9 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk, if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain) flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
- if (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS)
flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
This could probably be done as a separate change, and I think it deserves a comment that this is for creating views with a different format for UAV clears. We may as well use "else if", I guess.
I don’t see how it would fit in a separate change. Do you mean just setting this bit? Before the main patch it wouldn’t be used, and having the patch without it might cause crashes. Or do you mean creating the views code, in which case I guess I could put a FIXME there first?
- Jan
On Tue, 28 Sept 2021 at 16:43, Jan Sikorski jsikorski@codeweavers.com wrote:
On 27 Sep 2021, at 20:47, Henri Verbeet hverbeet@gmail.com wrote:
@@ -5115,6 +5115,9 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk, if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain) flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
- if (texture_vk->t.resource.bind_flags & WINED3D_BIND_UNORDERED_ACCESS)
flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
This could probably be done as a separate change, and I think it deserves a comment that this is for creating views with a different format for UAV clears. We may as well use "else if", I guess.
I don’t see how it would fit in a separate change. Do you mean just setting this bit? Before the main patch it wouldn’t be used, and having the patch without it might cause crashes. Or do you mean creating the views code, in which case I guess I could put a FIXME there first?
I mean just setting VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, yes. It's true that before the main patch there's nothing that depends on that bit being set, but it would still be a change in behaviour; in that sense it would still make sense as a bisection point.