[PATCH vkd3d v3 9/9] vkd3d-shader: Decorate SPIR-V for non-uniform access where flagged in dxbc.

Conor McCarthy cmccarthy at codeweavers.com
Mon Aug 23 10:23:28 CDT 2021


Based in part on vkd3d-proton patches by Philip Rebohle and Hans-Kristian Arntzen.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d-shader/dxbc.c                 |  3 ++-
 libs/vkd3d-shader/spirv.c                | 31 +++++++++++++++++++++---
 libs/vkd3d-shader/vkd3d_shader_private.h |  1 +
 tests/d3d12.c                            |  3 +--
 4 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 4fa5213b..fb7f2164 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -1186,6 +1186,7 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
     {
         param->type = register_type_table[register_type];
     }
+    param->non_uniform = false;
     param->data_type = data_type;
 
     *modifier = VKD3DSPSM_NONE;
@@ -1234,7 +1235,7 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
                 WARN("Ignoring minimum precision %#x.\n", min_precis);
 
             if (non_uniform)
-                FIXME("Ignoring extended modifier NON_UNIFORM.\n");
+                param->non_uniform = true;
         }
         else if (type)
         {
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 695882c7..4a84fab3 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1842,7 +1842,8 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder,
             || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilitySampledImageArrayDynamicIndexing)
             || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageBufferArrayDynamicIndexing)
             || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT)
-            || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageImageArrayDynamicIndexing))
+            || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStorageImageArrayDynamicIndexing)
+            || vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityShaderNonUniformEXT))
         vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_descriptor_indexing");
 
     if (builder->ext_instr_set_glsl_450)
@@ -2675,6 +2676,15 @@ static void vkd3d_dxbc_compiler_emit_descriptor_binding_for_reg(struct vkd3d_dxb
     vkd3d_dxbc_compiler_emit_descriptor_binding(compiler, variable_id, &binding);
 }
 
+static void vkd3d_dxbc_compiler_decorate_nonuniform(struct vkd3d_dxbc_compiler *compiler,
+        uint32_t expression_id)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+
+    vkd3d_spirv_enable_capability(builder, SpvCapabilityShaderNonUniformEXT);
+    vkd3d_spirv_build_op_decorate(builder, expression_id, SpvDecorationNonUniformEXT, NULL, 0);
+}
+
 static const struct vkd3d_symbol *vkd3d_dxbc_compiler_put_symbol(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_symbol *symbol)
 {
@@ -3319,6 +3329,8 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
         ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id);
         register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
                 register_info->id, indexes, index_count);
+        if (reg->non_uniform)
+            vkd3d_dxbc_compiler_decorate_nonuniform(compiler, register_info->id);
     }
 }
 
@@ -7998,8 +8010,16 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil
         return;
     }
 
-    image->image_id = load ? vkd3d_spirv_build_op_load(builder,
-            image->image_type_id, image->id, SpvMemoryAccessMaskNone) : 0;
+    if (load)
+    {
+        image->image_id = vkd3d_spirv_build_op_load(builder, image->image_type_id, image->id, SpvMemoryAccessMaskNone);
+        if (resource_reg->non_uniform)
+            vkd3d_dxbc_compiler_decorate_nonuniform(compiler, image->image_id);
+    }
+    else
+    {
+        image->image_id = 0;
+    }
 
     image->image_type_id = vkd3d_dxbc_compiler_get_image_type_id(compiler, resource_reg,
             &symbol->info.resource.range, image->resource_type_info,
@@ -8028,9 +8048,14 @@ static void vkd3d_dxbc_compiler_prepare_image(struct vkd3d_dxbc_compiler *compil
 
         sampler_id = vkd3d_spirv_build_op_load(builder,
                 vkd3d_spirv_get_op_type_sampler(builder), sampler_var_id, SpvMemoryAccessMaskNone);
+        if (sampler_reg->non_uniform)
+            vkd3d_dxbc_compiler_decorate_nonuniform(compiler, sampler_id);
+
         sampled_image_type_id = vkd3d_spirv_get_op_type_sampled_image(builder, image->image_type_id);
         image->sampled_image_id = vkd3d_spirv_build_op_sampled_image(builder,
                 sampled_image_type_id, image->image_id, sampler_id);
+        if (resource_reg->non_uniform)
+            vkd3d_dxbc_compiler_decorate_nonuniform(compiler, image->sampled_image_id);
     }
     else
     {
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 54ac5326..bd4f9ff1 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -621,6 +621,7 @@ struct vkd3d_shader_register_index
 struct vkd3d_shader_register
 {
     enum vkd3d_shader_register_type type;
+    bool non_uniform;
     enum vkd3d_data_type data_type;
     struct vkd3d_shader_register_index idx[3];
     enum vkd3d_immconst_type immconst_type;
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 6948b1a0..9b471f2e 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -34962,7 +34962,7 @@ static void test_unbounded_resource_arrays(void)
                 D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
         get_buffer_readback_with_command_list(output_buffers[i], DXGI_FORMAT_R32_UINT, &rb, queue, command_list);
         /* Buffers at index >= 64 are aliased. */
-        todo_if(i != 10 && i != 74)
+        todo_if(i != 74)
         check_readback_data_uint(&rb, NULL, (i < 64 ? 63 - i : 127 - i) ^ 0x35, 0);
         release_resource_readback(&rb);
         reset_command_list(command_list, context.allocator);
@@ -35109,7 +35109,6 @@ static void test_unbounded_samplers(void)
     {
         unsigned int value = get_readback_uint(&rb, i, 0, 0);
         unsigned int expected = (i & 1) ? 100 : 10;
-        todo_if(i & 1)
         ok(value == expected, "Got %u, expected %u at %u.\n", value, expected, i);
     }
     release_resource_readback(&rb);
-- 
2.32.0




More information about the wine-devel mailing list