Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/KhronosGroup/SPIRV-Cross.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Kristian Arntzen <post@arntzen-software.no>2019-02-13 18:39:59 +0300
committerHans-Kristian Arntzen <post@arntzen-software.no>2019-02-13 18:39:59 +0300
commitd7090b8322ef4394424711081bad8af104b49603 (patch)
tree8244ad8536987d7f3b416888e906ce79a6927e9a
parentd9ed3dcc7a7e62e5f95fd8f24e3d35e7e402ae92 (diff)
GLSL: Fix block name shenanigans in edge cases.
When we force recompile, the old var.self name we used as a fallback name might have been disturbed, so we should recover certain names back to their original form in case we are forced to take a recompile to make the naming algorithm more deterministic.
-rw-r--r--reference/opt/shaders/asm/comp/recompile-block-naming.asm.comp35
-rw-r--r--reference/shaders/asm/comp/recompile-block-naming.asm.comp36
-rw-r--r--shaders/asm/comp/recompile-block-naming.asm.comp140
-rw-r--r--spirv_glsl.cpp32
-rw-r--r--spirv_glsl.hpp3
-rw-r--r--spirv_hlsl.cpp4
6 files changed, 243 insertions, 7 deletions
diff --git a/reference/opt/shaders/asm/comp/recompile-block-naming.asm.comp b/reference/opt/shaders/asm/comp/recompile-block-naming.asm.comp
new file mode 100644
index 00000000..ff83de34
--- /dev/null
+++ b/reference/opt/shaders/asm/comp/recompile-block-naming.asm.comp
@@ -0,0 +1,35 @@
+#version 450
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+
+layout(binding = 0, std430) buffer MyFirstBuffer
+{
+ uint _data[];
+} MyFirstBuffer_1;
+
+layout(binding = 0, std430) buffer MySecondBuffer
+{
+ uint _data[];
+} MySecondBuffer_1;
+
+layout(binding = 0, std430) buffer MyThirdBuffer
+{
+ uint _data[];
+} MyThirdBuffer_1;
+
+void main()
+{
+ uint _105 = MyFirstBuffer_1._data[0];
+ uint _109 = MyFirstBuffer_1._data[1];
+ uint _113 = MyFirstBuffer_1._data[2];
+ uint _117 = MyFirstBuffer_1._data[3];
+ uint _122 = MySecondBuffer_1._data[1];
+ uint _126 = MySecondBuffer_1._data[2];
+ uint _130 = MySecondBuffer_1._data[3];
+ uint _134 = MySecondBuffer_1._data[4];
+ uvec4 _140 = uvec4(_105, _109, _113, _117) + uvec4(_122, _126, _130, _134);
+ MyThirdBuffer_1._data[0] = _140.x;
+ MyThirdBuffer_1._data[1] = _140.y;
+ MyThirdBuffer_1._data[2] = _140.z;
+ MyThirdBuffer_1._data[3] = _140.w;
+}
+
diff --git a/reference/shaders/asm/comp/recompile-block-naming.asm.comp b/reference/shaders/asm/comp/recompile-block-naming.asm.comp
new file mode 100644
index 00000000..aeb1ed16
--- /dev/null
+++ b/reference/shaders/asm/comp/recompile-block-naming.asm.comp
@@ -0,0 +1,36 @@
+#version 450
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+
+layout(binding = 0, std430) buffer MyFirstBuffer
+{
+ uint _data[];
+} MyFirstBuffer_1;
+
+layout(binding = 0, std430) buffer MySecondBuffer
+{
+ uint _data[];
+} MySecondBuffer_1;
+
+layout(binding = 0, std430) buffer MyThirdBuffer
+{
+ uint _data[];
+} MyThirdBuffer_1;
+
+void _main()
+{
+ int byteAddrTemp = 0 >> 2;
+ uvec4 a = uvec4(MyFirstBuffer_1._data[byteAddrTemp], MyFirstBuffer_1._data[byteAddrTemp + 1], MyFirstBuffer_1._data[byteAddrTemp + 2], MyFirstBuffer_1._data[byteAddrTemp + 3]);
+ int byteAddrTemp_1 = 4 >> 2;
+ uvec4 b = uvec4(MySecondBuffer_1._data[byteAddrTemp_1], MySecondBuffer_1._data[byteAddrTemp_1 + 1], MySecondBuffer_1._data[byteAddrTemp_1 + 2], MySecondBuffer_1._data[byteAddrTemp_1 + 3]);
+ int byteAddrTemp_2 = 0 >> 2;
+ MyThirdBuffer_1._data[byteAddrTemp_2] = (a + b).x;
+ MyThirdBuffer_1._data[byteAddrTemp_2 + 1] = (a + b).y;
+ MyThirdBuffer_1._data[byteAddrTemp_2 + 2] = (a + b).z;
+ MyThirdBuffer_1._data[byteAddrTemp_2 + 3] = (a + b).w;
+}
+
+void main()
+{
+ _main();
+}
+
diff --git a/shaders/asm/comp/recompile-block-naming.asm.comp b/shaders/asm/comp/recompile-block-naming.asm.comp
new file mode 100644
index 00000000..227a82b1
--- /dev/null
+++ b/shaders/asm/comp/recompile-block-naming.asm.comp
@@ -0,0 +1,140 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 97
+; Schema: 0
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpSource HLSL 500
+ OpName %main "main"
+ OpName %_main_ "@main("
+ OpName %a "a"
+ OpName %byteAddrTemp "byteAddrTemp"
+ OpName %MyFirstBuffer "MyFirstBuffer"
+ OpMemberName %MyFirstBuffer 0 "@data"
+ OpName %MyFirstBuffer_0 "MyFirstBuffer"
+ OpName %b "b"
+ OpName %byteAddrTemp_0 "byteAddrTemp"
+ OpName %MySecondBuffer "MySecondBuffer"
+ OpName %byteAddrTemp_1 "byteAddrTemp"
+ OpName %MyThirdBuffer "MyThirdBuffer"
+ OpDecorate %_runtimearr_uint ArrayStride 4
+ OpMemberDecorate %MyFirstBuffer 0 Offset 0
+ OpDecorate %MyFirstBuffer BufferBlock
+ OpDecorate %MyFirstBuffer_0 DescriptorSet 0
+ OpDecorate %MyFirstBuffer_0 Binding 0
+ OpDecorate %MySecondBuffer DescriptorSet 0
+ OpDecorate %MySecondBuffer Binding 0
+ OpDecorate %MyThirdBuffer DescriptorSet 0
+ OpDecorate %MyThirdBuffer Binding 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v4uint = OpTypeVector %uint 4
+%_ptr_Function_v4uint = OpTypePointer Function %v4uint
+ %int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+ %int_0 = OpConstant %int 0
+ %int_2 = OpConstant %int 2
+%_runtimearr_uint = OpTypeRuntimeArray %uint
+%MyFirstBuffer = OpTypeStruct %_runtimearr_uint
+%_ptr_Uniform_MyFirstBuffer = OpTypePointer Uniform %MyFirstBuffer
+%MyFirstBuffer_0 = OpVariable %_ptr_Uniform_MyFirstBuffer Uniform
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+ %int_1 = OpConstant %int 1
+ %int_3 = OpConstant %int 3
+ %int_4 = OpConstant %int 4
+%MySecondBuffer = OpVariable %_ptr_Uniform_MyFirstBuffer Uniform
+%MyThirdBuffer = OpVariable %_ptr_Uniform_MyFirstBuffer Uniform
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %96 = OpFunctionCall %void %_main_
+ OpReturn
+ OpFunctionEnd
+ %_main_ = OpFunction %void None %3
+ %7 = OpLabel
+ %a = OpVariable %_ptr_Function_v4uint Function
+%byteAddrTemp = OpVariable %_ptr_Function_int Function
+ %b = OpVariable %_ptr_Function_v4uint Function
+%byteAddrTemp_0 = OpVariable %_ptr_Function_int Function
+%byteAddrTemp_1 = OpVariable %_ptr_Function_int Function
+ %17 = OpShiftRightArithmetic %int %int_0 %int_2
+ OpStore %byteAddrTemp %17
+ %22 = OpLoad %int %byteAddrTemp
+ %24 = OpAccessChain %_ptr_Uniform_uint %MyFirstBuffer_0 %int_0 %22
+ %25 = OpLoad %uint %24
+ %26 = OpLoad %int %byteAddrTemp
+ %28 = OpIAdd %int %26 %int_1
+ %29 = OpAccessChain %_ptr_Uniform_uint %MyFirstBuffer_0 %int_0 %28
+ %30 = OpLoad %uint %29
+ %31 = OpLoad %int %byteAddrTemp
+ %32 = OpIAdd %int %31 %int_2
+ %33 = OpAccessChain %_ptr_Uniform_uint %MyFirstBuffer_0 %int_0 %32
+ %34 = OpLoad %uint %33
+ %35 = OpLoad %int %byteAddrTemp
+ %37 = OpIAdd %int %35 %int_3
+ %38 = OpAccessChain %_ptr_Uniform_uint %MyFirstBuffer_0 %int_0 %37
+ %39 = OpLoad %uint %38
+ %40 = OpCompositeConstruct %v4uint %25 %30 %34 %39
+ OpStore %a %40
+ %44 = OpShiftRightArithmetic %int %int_4 %int_2
+ OpStore %byteAddrTemp_0 %44
+ %46 = OpLoad %int %byteAddrTemp_0
+ %47 = OpAccessChain %_ptr_Uniform_uint %MySecondBuffer %int_0 %46
+ %48 = OpLoad %uint %47
+ %49 = OpLoad %int %byteAddrTemp_0
+ %50 = OpIAdd %int %49 %int_1
+ %51 = OpAccessChain %_ptr_Uniform_uint %MySecondBuffer %int_0 %50
+ %52 = OpLoad %uint %51
+ %53 = OpLoad %int %byteAddrTemp_0
+ %54 = OpIAdd %int %53 %int_2
+ %55 = OpAccessChain %_ptr_Uniform_uint %MySecondBuffer %int_0 %54
+ %56 = OpLoad %uint %55
+ %57 = OpLoad %int %byteAddrTemp_0
+ %58 = OpIAdd %int %57 %int_3
+ %59 = OpAccessChain %_ptr_Uniform_uint %MySecondBuffer %int_0 %58
+ %60 = OpLoad %uint %59
+ %61 = OpCompositeConstruct %v4uint %48 %52 %56 %60
+ OpStore %b %61
+ %63 = OpShiftRightArithmetic %int %int_0 %int_2
+ OpStore %byteAddrTemp_1 %63
+ %65 = OpLoad %int %byteAddrTemp_1
+ %66 = OpLoad %v4uint %a
+ %67 = OpLoad %v4uint %b
+ %68 = OpIAdd %v4uint %66 %67
+ %70 = OpCompositeExtract %uint %68 0
+ %71 = OpAccessChain %_ptr_Uniform_uint %MyThirdBuffer %int_0 %65
+ OpStore %71 %70
+ %72 = OpLoad %int %byteAddrTemp_1
+ %73 = OpIAdd %int %72 %int_1
+ %74 = OpLoad %v4uint %a
+ %75 = OpLoad %v4uint %b
+ %76 = OpIAdd %v4uint %74 %75
+ %78 = OpCompositeExtract %uint %76 1
+ %79 = OpAccessChain %_ptr_Uniform_uint %MyThirdBuffer %int_0 %73
+ OpStore %79 %78
+ %80 = OpLoad %int %byteAddrTemp_1
+ %81 = OpIAdd %int %80 %int_2
+ %82 = OpLoad %v4uint %a
+ %83 = OpLoad %v4uint %b
+ %84 = OpIAdd %v4uint %82 %83
+ %86 = OpCompositeExtract %uint %84 2
+ %87 = OpAccessChain %_ptr_Uniform_uint %MyThirdBuffer %int_0 %81
+ OpStore %87 %86
+ %88 = OpLoad %int %byteAddrTemp_1
+ %89 = OpIAdd %int %88 %int_3
+ %90 = OpLoad %v4uint %a
+ %91 = OpLoad %v4uint %b
+ %92 = OpIAdd %v4uint %90 %91
+ %94 = OpCompositeExtract %uint %92 3
+ %95 = OpAccessChain %_ptr_Uniform_uint %MyThirdBuffer %int_0 %89
+ OpStore %95 %94
+ OpReturn
+ OpFunctionEnd
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index 6666933f..3cec020e 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -262,13 +262,7 @@ void CompilerGLSL::reset()
expression_usage_counts.clear();
forwarded_temporaries.clear();
- resource_names.clear();
- block_input_names.clear();
- block_output_names.clear();
- block_ubo_names.clear();
- block_ssbo_names.clear();
- block_names.clear();
- function_overloads.clear();
+ reset_name_caches();
ir.for_each_typed_id<SPIRFunction>([&](uint32_t, SPIRFunction &func) {
func.active = false;
@@ -1561,6 +1555,10 @@ void CompilerGLSL::emit_buffer_block_native(const SPIRVariable &var)
i++;
}
+ // var.self can be used as a backup name for the block name,
+ // so we need to make sure we don't disturb the name here on a recompile.
+ // It will need to be reset if we have to recompile.
+ preserve_alias_on_reset(var.self);
add_resource_name(var.self);
end_scope_decl(to_name(var.self) + type_to_array_glsl(type));
statement("");
@@ -10984,3 +10982,23 @@ void CompilerGLSL::bitcast_to_builtin_store(uint32_t target_id, std::string &exp
void CompilerGLSL::emit_block_hints(const SPIRBlock &)
{
}
+
+void CompilerGLSL::preserve_alias_on_reset(uint32_t id)
+{
+ preserved_aliases[id] = get_name(id);
+}
+
+void CompilerGLSL::reset_name_caches()
+{
+ for (auto &preserved : preserved_aliases)
+ set_name(preserved.first, preserved.second);
+
+ preserved_aliases.clear();
+ resource_names.clear();
+ block_input_names.clear();
+ block_output_names.clear();
+ block_ubo_names.clear();
+ block_ssbo_names.clear();
+ block_names.clear();
+ function_overloads.clear();
+}
diff --git a/spirv_glsl.hpp b/spirv_glsl.hpp
index 4c9f5e98..f94043b9 100644
--- a/spirv_glsl.hpp
+++ b/spirv_glsl.hpp
@@ -358,6 +358,9 @@ protected:
std::unordered_set<std::string> block_ssbo_names;
std::unordered_set<std::string> block_names; // A union of all block_*_names.
std::unordered_map<std::string, std::unordered_set<uint64_t>> function_overloads;
+ std::unordered_map<uint32_t, std::string> preserved_aliases;
+ void preserve_alias_on_reset(uint32_t id);
+ void reset_name_caches();
bool processing_entry_point = false;
diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp
index 4ba264b7..c3191577 100644
--- a/spirv_hlsl.cpp
+++ b/spirv_hlsl.cpp
@@ -1838,6 +1838,10 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
declared_block_names[var.self] = buffer_name;
type.member_name_cache.clear();
+ // var.self can be used as a backup name for the block name,
+ // so we need to make sure we don't disturb the name here on a recompile.
+ // It will need to be reset if we have to recompile.
+ preserve_alias_on_reset(var.self);
add_resource_name(var.self);
statement("cbuffer ", buffer_name, to_resource_binding(var));
begin_scope();