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

Conor McCarthy cmccarthy at codeweavers.com
Mon Aug 30 22:04:08 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>
---
v4: Add 'nonuniform' to trace output for non-uniform registers.
Supersedes 212272.
---
 libs/vkd3d-shader/dxbc.c                 |  3 ++-
 libs/vkd3d-shader/spirv.c                | 31 +++++++++++++++++++++---
 libs/vkd3d-shader/trace.c                | 14 +++++++++++
 libs/vkd3d-shader/vkd3d_shader_private.h |  1 +
 tests/d3d12.c                            |  3 +--
 5 files changed, 46 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/trace.c b/libs/vkd3d-shader/trace.c
index df0ebf05..39fe8451 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -324,6 +324,7 @@ struct vkd3d_d3d_asm_colours
 {
     const char *reset;
     const char *literal;
+    const char *modifier;
     const char *opcode;
     const char *reg;
     const char *swizzle;
@@ -804,6 +805,11 @@ static void shader_print_subscript_range(struct vkd3d_d3d_asm_compiler *compiler
         vkd3d_string_buffer_printf(&compiler->buffer, "*]");
 }
 
+static void shader_print_nonuniform(struct vkd3d_d3d_asm_compiler *compiler)
+{
+    shader_addline(&compiler->buffer, " %s{ nonuniform }%s", compiler->colours.modifier, compiler->colours.reset);
+}
+
 static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const struct vkd3d_shader_register *reg,
         bool is_declaration)
 {
@@ -1192,6 +1198,9 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
             shader_addline(buffer, "%c", write_mask_chars[3]);
         shader_addline(buffer, "%s", compiler->colours.reset);
     }
+
+    if (param->reg.non_uniform)
+        shader_print_nonuniform(compiler);
 }
 
 static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
@@ -1261,6 +1270,9 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
     }
     if (src_modifier == VKD3DSPSM_ABS || src_modifier == VKD3DSPSM_ABSNEG)
         shader_addline(buffer, "|");
+
+    if (param->reg.non_uniform)
+        shader_print_nonuniform(compiler);
 }
 
 static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
@@ -1787,6 +1799,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(void *data,
     {
         .reset = "",
         .literal = "",
+        .modifier = "",
         .opcode = "",
         .reg = "",
         .swizzle = "",
@@ -1797,6 +1810,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(void *data,
     {
         .reset = "\x1b[m",
         .literal = "\x1b[95m",
+        .modifier = "\x1b[2;37m",
         .opcode = "\x1b[96;1m",
         .reg = "\x1b[96m",
         .swizzle = "\x1b[93m",
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