Based in part on vkd3d-proton patches by Philip Rebohle and Hans-Kristian Arntzen.
Signed-off-by: Conor McCarthy <cmccarthy(a)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