[PATCH v2 4/4] wined3d: Implement UAV clears on the Vulkan backend.

Jan Sikorski jsikorski at codeweavers.com
Tue Aug 17 09:02:20 CDT 2021


Based on the vkd3d implementation.

Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
 dlls/wined3d/adapter_vk.c         |   4 +
 dlls/wined3d/arb_program_shader.c |   9 +
 dlls/wined3d/context_vk.c         |   2 +-
 dlls/wined3d/glsl_shader.c        |   9 +
 dlls/wined3d/shader.c             |   8 +
 dlls/wined3d/shader_spirv.c       | 111 ++++++++-
 dlls/wined3d/view.c               | 334 ++++++++++++++++++++++---
 dlls/wined3d/wined3d_private.h    |  52 ++++
 dlls/wined3d/wined3d_shaders.h    | 388 ++++++++++++++++++++++++++++++
 9 files changed, 876 insertions(+), 41 deletions(-)
 create mode 100644 dlls/wined3d/wined3d_shaders.h

diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index c7da02865ea..941b1ed41ac 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);
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 1b533107f64..d988759fc2b 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -5637,6 +5637,14 @@ 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, const struct wined3d_shader_resource_bindings *bindings,
+        const struct wined3d_shader_push_constants *push_constants, const struct wined3d_stream_output_desc *so_desc)
+{
+    ERR("Not implemented.\n");
+    return 0;
+}
+
 const struct wined3d_shader_backend_ops arb_program_shader_backend =
 {
     shader_arb_handle_instruction,
@@ -5656,6 +5664,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 88d8080f5dd..ec426d568ba 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -2559,7 +2559,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 5ae90148dc8..4bc45146925 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -11490,6 +11490,14 @@ 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, const struct wined3d_shader_resource_bindings *bindings,
+        const struct wined3d_shader_push_constants *push_constants, const struct wined3d_stream_output_desc *so_desc)
+{
+    ERR("Not implemented.\n");
+    return 0;
+}
+
 const struct wined3d_shader_backend_ops glsl_shader_backend =
 {
     shader_glsl_handle_instruction,
@@ -11509,6 +11517,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..e29b76c92bb 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -3279,6 +3279,13 @@ 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, const struct wined3d_shader_resource_bindings *bindings,
+        const struct wined3d_shader_push_constants *push_constants, const struct wined3d_stream_output_desc *so_desc)
+{
+    return 0;
+}
+
 const struct wined3d_shader_backend_ops none_shader_backend =
 {
     shader_none_handle_instruction,
@@ -3298,6 +3305,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 c09eb724c2c..eb391dd9a87 100644
--- a/dlls/wined3d/shader_spirv.c
+++ b/dlls/wined3d/shader_spirv.c
@@ -319,7 +319,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)
 {
@@ -672,6 +672,28 @@ static enum wined3d_shader_descriptor_type wined3d_descriptor_type_from_vkd3d(en
     }
 }
 
+static enum vkd3d_shader_descriptor_type vkd3d_descriptor_type_from_wined3d(enum wined3d_shader_descriptor_type type)
+{
+    switch (type)
+    {
+        case WINED3D_SHADER_DESCRIPTOR_TYPE_CBV:
+            return VKD3D_SHADER_DESCRIPTOR_TYPE_CBV;
+
+        case WINED3D_SHADER_DESCRIPTOR_TYPE_SRV:
+            return VKD3D_SHADER_DESCRIPTOR_TYPE_SRV;
+
+        case WINED3D_SHADER_DESCRIPTOR_TYPE_UAV:
+            return VKD3D_SHADER_DESCRIPTOR_TYPE_UAV;
+
+        case WINED3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
+            return VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER;
+
+        default:
+            FIXME("Unhandled descriptor type %#x.\n", type);
+            return ~0u;
+    }
+}
+
 static enum wined3d_shader_resource_type wined3d_shader_resource_type_from_vkd3d(enum vkd3d_shader_resource_type t)
 {
     return (enum wined3d_shader_resource_type)t;
@@ -1158,6 +1180,92 @@ 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, const struct wined3d_shader_resource_bindings *bindings,
+        const struct wined3d_shader_push_constants *push_constants, const struct wined3d_stream_output_desc *so_desc)
+{
+    struct shader_spirv_interface iface;
+    unsigned int uav_counter_count = 0;
+    unsigned int binding_count = 0;
+    VkShaderModule module;
+    unsigned int i;
+
+    iface.bindings = heap_alloc(sizeof(*iface.bindings) * bindings->count +
+            sizeof(*iface.push_constants) * push_constants->count +
+            MAX_UNORDERED_ACCESS_VIEWS * sizeof(*iface.uav_counters));
+    if (!iface.bindings)
+    {
+        ERR("Failed to allocate storage.\n");
+        return VK_NULL_HANDLE;
+    }
+    iface.push_constants = (struct vkd3d_shader_push_constant_buffer *)(iface.bindings + bindings->count);
+    iface.uav_counters = (struct vkd3d_shader_uav_counter_binding *)(iface.push_constants + push_constants->count);
+
+    for (i = 0; i < bindings->count; ++i)
+    {
+        struct wined3d_shader_resource_binding *binding = &bindings->bindings[i];
+        struct vkd3d_shader_descriptor_binding vkd3d_target_binding;
+        struct vkd3d_shader_uav_counter_binding *vkd3d_counter;
+        struct vkd3d_shader_resource_binding *vkd3d_binding;
+
+        vkd3d_target_binding.set = 0;
+        vkd3d_target_binding.binding = binding->binding_idx;
+        vkd3d_target_binding.count = 1;
+
+        if (binding->shader_descriptor_type == WINED3D_SHADER_DESCRIPTOR_TYPE_UAV_COUNTER)
+        {
+            if (uav_counter_count >= MAX_UNORDERED_ACCESS_VIEWS)
+            {
+                ERR("Skipping UAV counter.\n");
+                continue;
+            }
+            vkd3d_counter = (void *)&iface.uav_counters[uav_counter_count];
+            vkd3d_counter->register_space = 0;
+            vkd3d_counter->register_index = binding->resource_idx;
+            vkd3d_counter->shader_visibility = vkd3d_shader_visibility_from_wined3d(shader_type);
+            vkd3d_counter->binding = vkd3d_target_binding;
+            vkd3d_counter->offset = 0;
+            ++uav_counter_count;
+            continue;
+        }
+
+        vkd3d_binding = (void *)&iface.bindings[binding_count];
+        vkd3d_binding->type = vkd3d_descriptor_type_from_wined3d(binding->shader_descriptor_type);
+        vkd3d_binding->register_space = 0;
+        vkd3d_binding->register_index = binding->resource_idx;
+        vkd3d_binding->shader_visibility = vkd3d_shader_visibility_from_wined3d(shader_type);
+
+        if (binding->resource_type == WINED3D_SHADER_RESOURCE_BUFFER)
+            vkd3d_binding->flags = VKD3D_SHADER_BINDING_FLAG_BUFFER;
+        else
+            vkd3d_binding->flags = VKD3D_SHADER_BINDING_FLAG_IMAGE;
+
+        vkd3d_binding->binding = vkd3d_target_binding;
+        ++binding_count;
+    }
+
+    for (i = 0; i < push_constants->count; ++i)
+    {
+        struct vkd3d_shader_push_constant_buffer *vkd3d_push_constant = (void *)&iface.push_constants[i];
+        struct wined3d_shader_push_constant *push_constant = &push_constants->push_constants[i];
+
+        vkd3d_push_constant->register_space = 0;
+        vkd3d_push_constant->register_index = push_constant->resource_idx;
+        vkd3d_push_constant->shader_visibility = vkd3d_shader_visibility_from_wined3d(shader_type);
+        vkd3d_push_constant->offset = push_constant->offset;
+        vkd3d_push_constant->size = push_constant->size;
+    }
+
+    iface.binding_count = binding_count;
+    iface.push_constant_count = push_constants->count;
+    iface.uav_counter_count = uav_counter_count;
+
+    module = shader_spirv_compile(wined3d_context_vk(context), shader_desc, shader_type, NULL, &iface, so_desc);
+
+    heap_free((void *)iface.bindings);
+    return (uint64_t)module;
+}
+
 static const struct wined3d_shader_backend_ops spirv_shader_backend_vk =
 {
     .shader_handle_instruction = shader_spirv_handle_instruction,
@@ -1177,6 +1285,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/view.c b/dlls/wined3d/view.c
index dfca8fc53f8..43d09781820 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,322 @@ 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)
+{
+    struct wined3d_shader_push_constants push_constants;
+    struct wined3d_shader_resource_binding uav_binding;
+    struct wined3d_shader_push_constant push_constant;
+    struct wined3d_shader_resource_bindings bindings;
+    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;
+
+    uav_binding.shader_type = WINED3D_SHADER_TYPE_COMPUTE;
+    uav_binding.shader_descriptor_type = WINED3D_SHADER_DESCRIPTOR_TYPE_UAV;
+    uav_binding.resource_idx = 0;
+    uav_binding.resource_type = resource_type;
+    uav_binding.resource_data_type = WINED3D_DATA_UAV;
+    uav_binding.binding_idx = 0;
+
+    bindings.bindings = &uav_binding;
+    bindings.size = bindings.count = 1;
+
+    push_constant.resource_idx = 0;
+    push_constant.offset = 0;
+    push_constant.size = sizeof(struct wined3d_uav_clear_constants_vk);
+
+    push_constants.push_constants = &push_constant;
+    push_constants.size = push_constants.count = 1;
+
+    shader_module = (VkShaderModule)context->device->adapter->shader_backend->shader_compile(context, &shader_desc,
+            WINED3D_SHADER_TYPE_COMPUTE, &bindings, &push_constants, NULL);
+    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_binding;
+    VkPushConstantRange push_constant;
+
+    push_constant.offset = 0;
+    push_constant.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
+    push_constant.size = sizeof(struct wined3d_uav_clear_constants_vk);
+
+    vk_set_binding.binding = 0;
+    vk_set_binding.descriptorCount = 1;
+    vk_set_binding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
+    vk_set_binding.pImmutableSamplers = NULL;
+
+    vk_set_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+    state->image_layout = wined3d_context_vk_get_pipeline_layout(context_vk, &vk_set_binding, 1, &push_constant, 1);
+
+    vk_set_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    state->buffer_layout = wined3d_context_vk_get_pipeline_layout(context_vk, &vk_set_binding, 1, &push_constant, 1);
+
+#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_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;
+    struct wined3d_uav_clear_pipelines_vk *pipelines;
+    struct wined3d_pipeline_layout_vk *layout;
+    struct wined3d_uav_clear_state_vk *state;
+    struct wined3d_texture_vk *texture_vk;
     const struct wined3d_vk_info *vk_info;
-    const struct wined3d_format *format;
-    struct wined3d_buffer_vk *buffer_vk;
+    struct wined3d_device_vk *device_vk;
     struct wined3d_resource *resource;
     VkCommandBuffer vk_command_buffer;
-    VkBufferMemoryBarrier vk_barrier;
-    VkAccessFlags access_mask;
-    unsigned int offset, size;
+    struct wined3d_texture *texture;
+    VkWriteDescriptorSet vk_write;
+    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));
-        return;
+        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;
     }
 
-    format = view_vk->v.format;
-    if (format->id != WINED3DFMT_R32_UINT && format->id != WINED3DFMT_R32_SINT)
+    if (vk_pipeline == VK_NULL_HANDLE)
     {
-        FIXME("Not implemented for format %s.\n", debug_d3dformat(format->id));
+        ERR("Pipeline was not correctly initialized.\n");
         return;
     }
 
-    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);
+    vk_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    vk_write.pNext = NULL;
+    vk_write.dstBinding = 0;
+    vk_write.dstArrayElement = 0;
+    vk_write.descriptorCount = 1;
+    vk_write.pImageInfo = NULL;
 
-    get_buffer_view_range(&buffer_vk->b, &view_vk->v.desc, format, &offset, &size);
+    if (resource->type == WINED3D_RTYPE_BUFFER)
+    {
+        uav_location = WINED3D_LOCATION_BUFFER;
+        layout = state->buffer_layout;
+        vk_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        vk_write.pTexelBufferView = &view_vk->view_vk.u.vk_buffer_view;
 
-    if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
+        constants.extent.width  = view_desc->u.buffer.count;
+        constants.extent.height = 1;
+    }
+    else
+    {
+        texture = wined3d_texture_from_resource(resource);
+        texture_vk = wined3d_texture_vk(texture);
+        uav_location = WINED3D_LOCATION_TEXTURE_RGB;
+        layout = state->image_layout;
+        vk_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+        vk_write.pImageInfo = &view_vk->view_vk.u.vk_image_info;
+        if (!vk_write.pImageInfo->imageView)
+            vk_write.pImageInfo = wined3d_texture_vk_get_default_image_info(texture_vk, context_vk);
+
+        level = view_desc->u.texture.level_idx;
+        constants.extent.width  = wined3d_texture_get_level_width(texture, level);
+        constants.extent.height = wined3d_texture_get_level_height(texture, 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;
+
+    wined3d_view_load_location(resource, view_desc, &context_vk->c, uav_location);
+    wined3d_unordered_access_view_invalidate_location(&view_vk->v, ~uav_location);
+    wined3d_context_vk_reference_unordered_access_view(context_vk, view_vk);
+
+    vk_info = context_vk->vk_info;
+
+    vr = wined3d_context_vk_create_vk_descriptor_set(context_vk, layout->vk_set_layout, &vk_write.dstSet);
+    if (vr != VK_SUCCESS)
+    {
+        ERR("Failed to create descriptor set.\n");
         return;
+    }
+
+    VK_CALL(vkUpdateDescriptorSets(device_vk->vk_device, 1, &vk_write, 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;
+    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_write.dstSet, 0, NULL));
+    VK_CALL(vkCmdPushConstants(vk_command_buffer, layout->vk_pipeline_layout,
+            VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(constants), &constants));
+    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);
 }
 
 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 f7a8812c2bd..96f256d2bef 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1488,6 +1488,9 @@ struct gs_compile_args
     DWORD interpolation_mode[WINED3D_PACKED_INTERPOLATION_SIZE];
 };
 
+struct wined3d_shader_resource_bindings;
+struct wined3d_shader_push_constants;
+
 struct wined3d_shader_backend_ops
 {
     void (*shader_handle_instruction)(const struct wined3d_shader_instruction *);
@@ -1511,6 +1514,9 @@ 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, const struct wined3d_shader_resource_bindings *bindings,
+        const struct wined3d_shader_push_constants *push_constants, const struct wined3d_stream_output_desc *so_desc);
 };
 
 extern const struct wined3d_shader_backend_ops glsl_shader_backend DECLSPEC_HIDDEN;
@@ -2513,6 +2519,19 @@ struct wined3d_shader_resource_bindings
     SIZE_T size, count;
 };
 
+struct wined3d_shader_push_constant
+{
+    size_t resource_idx;
+    unsigned int offset;
+    unsigned int size;
+};
+
+struct wined3d_shader_push_constants
+{
+    struct wined3d_shader_push_constant *push_constants;
+    SIZE_T size, count;
+};
+
 struct wined3d_shader_descriptor_writes_vk
 {
     VkWriteDescriptorSet *writes;
@@ -2666,6 +2685,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);
 
@@ -4006,6 +4027,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;
@@ -4023,6 +4070,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)
@@ -4039,6 +4088,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;
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
-- 
2.30.2




More information about the wine-devel mailing list