From: Conor McCarthy Subject: [PATCH vkd3d v4 9/9] vkd3d-shader: Decorate SPIR-V for non-uniform access where flagged in dxbc. Message-Id: <20210831030408.15548-1-cmccarthy@codeweavers.com> Date: Tue, 31 Aug 2021 13:04:08 +1000 Based in part on vkd3d-proton patches by Philip Rebohle and Hans-Kristian Arntzen. Signed-off-by: Conor McCarthy --- 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