diff options
-rw-r--r-- | reference/opt/shaders/asm/comp/decoration-group.asm.comp | 38 | ||||
-rw-r--r-- | reference/shaders/asm/comp/decoration-group.asm.comp | 38 | ||||
-rw-r--r-- | shaders/asm/comp/decoration-group.asm.comp | 99 | ||||
-rw-r--r-- | spirv_parser.cpp | 74 |
4 files changed, 249 insertions, 0 deletions
diff --git a/reference/opt/shaders/asm/comp/decoration-group.asm.comp b/reference/opt/shaders/asm/comp/decoration-group.asm.comp new file mode 100644 index 00000000..28ad4d41 --- /dev/null +++ b/reference/opt/shaders/asm/comp/decoration-group.asm.comp @@ -0,0 +1,38 @@ +#version 430 +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +layout(binding = 5, std430) buffer _6_15 +{ + float _m0[]; +} _15; + +layout(binding = 0, std430) buffer _7_16 +{ + float _m0[]; +} _16; + +layout(binding = 1, std430) buffer _8_17 +{ + float _m0[]; +} _17; + +layout(binding = 2, std430) restrict readonly buffer _9_18 +{ + float _m0[]; +} _18; + +layout(binding = 3, std430) restrict readonly buffer _10_19 +{ + float _m0[]; +} _19; + +layout(binding = 4, std430) restrict readonly buffer _11_20 +{ + float _m0[]; +} _20; + +void main() +{ + _15._m0[gl_GlobalInvocationID.x] = (((_16._m0[gl_GlobalInvocationID.x] + _17._m0[gl_GlobalInvocationID.x]) + _18._m0[gl_GlobalInvocationID.x]) + _19._m0[gl_GlobalInvocationID.x]) + _20._m0[gl_GlobalInvocationID.x]; +} + diff --git a/reference/shaders/asm/comp/decoration-group.asm.comp b/reference/shaders/asm/comp/decoration-group.asm.comp new file mode 100644 index 00000000..28ad4d41 --- /dev/null +++ b/reference/shaders/asm/comp/decoration-group.asm.comp @@ -0,0 +1,38 @@ +#version 430 +layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; + +layout(binding = 5, std430) buffer _6_15 +{ + float _m0[]; +} _15; + +layout(binding = 0, std430) buffer _7_16 +{ + float _m0[]; +} _16; + +layout(binding = 1, std430) buffer _8_17 +{ + float _m0[]; +} _17; + +layout(binding = 2, std430) restrict readonly buffer _9_18 +{ + float _m0[]; +} _18; + +layout(binding = 3, std430) restrict readonly buffer _10_19 +{ + float _m0[]; +} _19; + +layout(binding = 4, std430) restrict readonly buffer _11_20 +{ + float _m0[]; +} _20; + +void main() +{ + _15._m0[gl_GlobalInvocationID.x] = (((_16._m0[gl_GlobalInvocationID.x] + _17._m0[gl_GlobalInvocationID.x]) + _18._m0[gl_GlobalInvocationID.x]) + _19._m0[gl_GlobalInvocationID.x]) + _20._m0[gl_GlobalInvocationID.x]; +} + diff --git a/shaders/asm/comp/decoration-group.asm.comp b/shaders/asm/comp/decoration-group.asm.comp new file mode 100644 index 00000000..b597b4bd --- /dev/null +++ b/shaders/asm/comp/decoration-group.asm.comp @@ -0,0 +1,99 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos SPIR-V Tools Assembler; 0 +; Bound: 58 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %1 "main" %2 + OpExecutionMode %1 LocalSize 1 1 1 + OpSource GLSL 430 + OpName %1 "main" + OpName %2 "gl_GlobalInvocationID" + OpDecorate %2 BuiltIn GlobalInvocationId + OpDecorate %3 ArrayStride 4 + OpDecorate %4 BufferBlock + OpDecorate %5 Offset 0 + %4 = OpDecorationGroup + %5 = OpDecorationGroup + OpGroupDecorate %4 %6 %7 %8 %9 %10 %11 + OpGroupMemberDecorate %5 %6 0 %7 0 %8 0 %9 0 %10 0 %11 0 + OpDecorate %12 DescriptorSet 0 + OpDecorate %13 DescriptorSet 0 + OpDecorate %13 NonWritable + OpDecorate %13 Restrict + %14 = OpDecorationGroup + %12 = OpDecorationGroup + %13 = OpDecorationGroup + OpGroupDecorate %12 %15 + OpGroupDecorate %12 %15 + OpGroupDecorate %12 %15 + OpDecorate %15 DescriptorSet 0 + OpDecorate %15 Binding 5 + OpGroupDecorate %14 %16 + OpDecorate %16 DescriptorSet 0 + OpDecorate %16 Binding 0 + OpGroupDecorate %12 %17 + OpDecorate %17 Binding 1 + OpGroupDecorate %13 %18 %19 + OpDecorate %18 Binding 2 + OpDecorate %19 Binding 3 + OpGroupDecorate %14 %20 + OpGroupDecorate %12 %20 + OpGroupDecorate %13 %20 + OpDecorate %20 Binding 4 + %21 = OpTypeBool + %22 = OpTypeVoid + %23 = OpTypeFunction %22 + %24 = OpTypeInt 32 0 + %25 = OpTypeInt 32 1 + %26 = OpTypeFloat 32 + %27 = OpTypeVector %24 3 + %28 = OpTypeVector %26 3 + %29 = OpTypePointer Input %27 + %30 = OpTypePointer Uniform %25 + %31 = OpTypePointer Uniform %26 + %32 = OpTypeRuntimeArray %25 + %3 = OpTypeRuntimeArray %26 + %2 = OpVariable %29 Input + %33 = OpConstant %25 0 + %6 = OpTypeStruct %3 + %34 = OpTypePointer Uniform %6 + %15 = OpVariable %34 Uniform + %7 = OpTypeStruct %3 + %35 = OpTypePointer Uniform %7 + %16 = OpVariable %35 Uniform + %8 = OpTypeStruct %3 + %36 = OpTypePointer Uniform %8 + %17 = OpVariable %36 Uniform + %9 = OpTypeStruct %3 + %37 = OpTypePointer Uniform %9 + %18 = OpVariable %37 Uniform + %10 = OpTypeStruct %3 + %38 = OpTypePointer Uniform %10 + %19 = OpVariable %38 Uniform + %11 = OpTypeStruct %3 + %39 = OpTypePointer Uniform %11 + %20 = OpVariable %39 Uniform + %1 = OpFunction %22 None %23 + %40 = OpLabel + %41 = OpLoad %27 %2 + %42 = OpCompositeExtract %24 %41 0 + %43 = OpAccessChain %31 %16 %33 %42 + %44 = OpAccessChain %31 %17 %33 %42 + %45 = OpAccessChain %31 %18 %33 %42 + %46 = OpAccessChain %31 %19 %33 %42 + %47 = OpAccessChain %31 %20 %33 %42 + %48 = OpAccessChain %31 %15 %33 %42 + %49 = OpLoad %26 %43 + %50 = OpLoad %26 %44 + %51 = OpLoad %26 %45 + %52 = OpLoad %26 %46 + %53 = OpLoad %26 %47 + %54 = OpFAdd %26 %49 %50 + %55 = OpFAdd %26 %54 %51 + %56 = OpFAdd %26 %55 %52 + %57 = OpFAdd %26 %56 %53 + OpStore %48 %57 + OpReturn + OpFunctionEnd diff --git a/spirv_parser.cpp b/spirv_parser.cpp index 3c70171e..0e611fe2 100644 --- a/spirv_parser.cpp +++ b/spirv_parser.cpp @@ -32,6 +32,18 @@ Parser::Parser(const uint32_t *spirv_data, size_t word_count) ir.spirv = vector<uint32_t>(spirv_data, spirv_data + word_count); } +static bool decoration_is_string(Decoration decoration) +{ + switch (decoration) + { + case DecorationHlslSemanticGOOGLE: + return true; + + default: + return false; + } +} + static inline uint32_t swap_endian(uint32_t v) { return ((v >> 24) & 0x000000ffu) | ((v >> 8) & 0x0000ff00u) | ((v << 8) & 0x00ff0000u) | ((v << 24) & 0xff000000u); @@ -300,9 +312,71 @@ void Parser::parse(const Instruction &instruction) break; } + case OpDecorationGroup: + { + // Noop, this simply means an ID should be a collector of decorations. + // The meta array is already a flat array of decorations which will contain the relevant decorations. + break; + } + + case OpGroupDecorate: + { + uint32_t group_id = ops[0]; + auto &decorations = ir.meta[group_id].decoration; + auto &flags = decorations.decoration_flags; + + // Copies decorations from one ID to another. Only copy decorations which are set in the group, + // i.e., we cannot just copy the meta structure directly. + for (uint32_t i = 1; i < length; i++) + { + uint32_t target = ops[i]; + flags.for_each_bit([&](uint32_t bit) { + auto decoration = static_cast<Decoration>(bit); + + if (decoration_is_string(decoration)) + { + ir.set_decoration_string(target, decoration, ir.get_decoration_string(group_id, decoration)); + } + else + { + ir.meta[target].decoration_word_offset[decoration] = + ir.meta[group_id].decoration_word_offset[decoration]; + ir.set_decoration(target, decoration, ir.get_decoration(group_id, decoration)); + } + }); + } + break; + } + + case OpGroupMemberDecorate: + { + uint32_t group_id = ops[0]; + auto &flags = ir.meta[group_id].decoration.decoration_flags; + + // Copies decorations from one ID to another. Only copy decorations which are set in the group, + // i.e., we cannot just copy the meta structure directly. + for (uint32_t i = 1; i + 1 < length; i += 2) + { + uint32_t target = ops[i + 0]; + uint32_t index = ops[i + 1]; + flags.for_each_bit([&](uint32_t bit) { + auto decoration = static_cast<Decoration>(bit); + + if (decoration_is_string(decoration)) + ir.set_member_decoration_string(target, index, decoration, + ir.get_decoration_string(group_id, decoration)); + else + ir.set_member_decoration(target, index, decoration, ir.get_decoration(group_id, decoration)); + }); + } + break; + } + case OpDecorate: case OpDecorateId: { + // OpDecorateId technically supports an array of arguments, but our only supported decorations are single uint, + // so merge decorate and decorate-id here. uint32_t id = ops[0]; auto decoration = static_cast<Decoration>(ops[1]); |