HLSL: Implement stores for complex composites in ByteAddressBuffers.
This commit is contained in:
parent
ca9398c122
commit
151ff1e870
@ -0,0 +1,76 @@
|
||||
struct Baz
|
||||
{
|
||||
float c;
|
||||
};
|
||||
|
||||
struct Bar
|
||||
{
|
||||
float d[2][4];
|
||||
Baz baz[2];
|
||||
};
|
||||
|
||||
struct Foo
|
||||
{
|
||||
column_major float2x2 a;
|
||||
float2 b;
|
||||
Bar c[5];
|
||||
};
|
||||
|
||||
static const uint3 gl_WorkGroupSize = uint3(1u, 1u, 1u);
|
||||
|
||||
RWByteAddressBuffer _10 : register(u0);
|
||||
|
||||
void comp_main()
|
||||
{
|
||||
Foo _64;
|
||||
_64.a = asfloat(uint2x2(_10.Load(0), _10.Load(8), _10.Load(4), _10.Load(12)));
|
||||
_64.b = asfloat(uint2(_10.Load(16), _10.Load(24)));
|
||||
[unroll]
|
||||
for (int _0ident = 0; _0ident < 5; _0ident++)
|
||||
{
|
||||
[unroll]
|
||||
for (int _1ident = 0; _1ident < 2; _1ident++)
|
||||
{
|
||||
[unroll]
|
||||
for (int _2ident = 0; _2ident < 4; _2ident++)
|
||||
{
|
||||
_64.c[_0ident].d[_1ident][_2ident] = asfloat(_10.Load(_2ident * 4 + _1ident * 16 + _0ident * 40 + 24));
|
||||
}
|
||||
}
|
||||
[unroll]
|
||||
for (int _3ident = 0; _3ident < 2; _3ident++)
|
||||
{
|
||||
_64.c[_0ident].baz[_3ident].c = asfloat(_10.Load(_3ident * 4 + _0ident * 40 + 56));
|
||||
}
|
||||
}
|
||||
_10.Store(224, asuint(_64.a[0].x));
|
||||
_10.Store(228, asuint(_64.a[1].x));
|
||||
_10.Store(232, asuint(_64.a[0].y));
|
||||
_10.Store(236, asuint(_64.a[1].y));
|
||||
_10.Store(240, asuint(_64.b.x));
|
||||
_10.Store(248, asuint(_64.b.y));
|
||||
[unroll]
|
||||
for (int _4ident = 0; _4ident < 5; _4ident++)
|
||||
{
|
||||
[unroll]
|
||||
for (int _5ident = 0; _5ident < 2; _5ident++)
|
||||
{
|
||||
[unroll]
|
||||
for (int _6ident = 0; _6ident < 4; _6ident++)
|
||||
{
|
||||
_10.Store(_6ident * 4 + _5ident * 16 + _4ident * 40 + 248, asuint(_64.c[_4ident].d[_5ident][_6ident]));
|
||||
}
|
||||
}
|
||||
[unroll]
|
||||
for (int _7ident = 0; _7ident < 2; _7ident++)
|
||||
{
|
||||
_10.Store(_7ident * 4 + _4ident * 40 + 280, asuint(_64.c[_4ident].baz[_7ident].c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void main()
|
||||
{
|
||||
comp_main();
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: Khronos Glslang Reference Front End; 8
|
||||
; Bound: 437
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %main "main"
|
||||
OpExecutionMode %main LocalSize 1 1 1
|
||||
OpSource GLSL 450
|
||||
OpName %main "main"
|
||||
OpName %Baz "Baz"
|
||||
OpMemberName %Baz 0 "c"
|
||||
OpName %Bar "Bar"
|
||||
OpMemberName %Bar 0 "d"
|
||||
OpMemberName %Bar 1 "baz"
|
||||
OpName %Foo "Foo"
|
||||
OpMemberName %Foo 0 "a"
|
||||
OpMemberName %Foo 1 "b"
|
||||
OpMemberName %Foo 2 "c"
|
||||
OpName %Baz_0 "Baz"
|
||||
OpMemberName %Baz_0 0 "c"
|
||||
OpName %Bar_0 "Bar"
|
||||
OpMemberName %Bar_0 0 "d"
|
||||
OpMemberName %Bar_0 1 "baz"
|
||||
OpName %Foo_0 "Foo"
|
||||
OpMemberName %Foo_0 0 "a"
|
||||
OpMemberName %Foo_0 1 "b"
|
||||
OpMemberName %Foo_0 2 "c"
|
||||
OpName %SSBO "SSBO"
|
||||
OpMemberName %SSBO 0 "foo"
|
||||
OpMemberName %SSBO 1 "foo2"
|
||||
OpName %_ ""
|
||||
OpDecorate %_arr_float_uint_4_0 ArrayStride 4
|
||||
OpDecorate %_arr__arr_float_uint_4_0_uint_2 ArrayStride 16
|
||||
OpMemberDecorate %Baz_0 0 Offset 0
|
||||
OpDecorate %_arr_Baz_0_uint_2 ArrayStride 4
|
||||
OpMemberDecorate %Bar_0 0 Offset 0
|
||||
OpMemberDecorate %Bar_0 1 Offset 32
|
||||
OpDecorate %_arr_Bar_0_uint_5 ArrayStride 40
|
||||
OpMemberDecorate %Foo_0 0 RowMajor
|
||||
OpMemberDecorate %Foo_0 0 Offset 0
|
||||
OpMemberDecorate %Foo_0 0 MatrixStride 8
|
||||
OpMemberDecorate %Foo_0 1 Offset 16
|
||||
OpMemberDecorate %Foo_0 2 Offset 24
|
||||
OpMemberDecorate %SSBO 0 Offset 0
|
||||
OpMemberDecorate %SSBO 1 Offset 224
|
||||
OpDecorate %SSBO BufferBlock
|
||||
OpDecorate %_ DescriptorSet 0
|
||||
OpDecorate %_ Binding 0
|
||||
OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
|
||||
%void = OpTypeVoid
|
||||
%3 = OpTypeFunction %void
|
||||
%float = OpTypeFloat 32
|
||||
%v2float = OpTypeVector %float 2
|
||||
%mat2v2float = OpTypeMatrix %v2float 2
|
||||
%uint = OpTypeInt 32 0
|
||||
%uint_4 = OpConstant %uint 4
|
||||
%_arr_float_uint_4 = OpTypeArray %float %uint_4
|
||||
%uint_2 = OpConstant %uint 2
|
||||
%_arr__arr_float_uint_4_uint_2 = OpTypeArray %_arr_float_uint_4 %uint_2
|
||||
%Baz = OpTypeStruct %float
|
||||
%_arr_Baz_uint_2 = OpTypeArray %Baz %uint_2
|
||||
%Bar = OpTypeStruct %_arr__arr_float_uint_4_uint_2 %_arr_Baz_uint_2
|
||||
%uint_5 = OpConstant %uint 5
|
||||
%_arr_Bar_uint_5 = OpTypeArray %Bar %uint_5
|
||||
%Foo = OpTypeStruct %mat2v2float %v2float %_arr_Bar_uint_5
|
||||
%_ptr_Function_Foo = OpTypePointer Function %Foo
|
||||
%_arr_float_uint_4_0 = OpTypeArray %float %uint_4
|
||||
%_arr__arr_float_uint_4_0_uint_2 = OpTypeArray %_arr_float_uint_4_0 %uint_2
|
||||
%Baz_0 = OpTypeStruct %float
|
||||
%_arr_Baz_0_uint_2 = OpTypeArray %Baz_0 %uint_2
|
||||
%Bar_0 = OpTypeStruct %_arr__arr_float_uint_4_0_uint_2 %_arr_Baz_0_uint_2
|
||||
%_arr_Bar_0_uint_5 = OpTypeArray %Bar_0 %uint_5
|
||||
%Foo_0 = OpTypeStruct %mat2v2float %v2float %_arr_Bar_0_uint_5
|
||||
%SSBO = OpTypeStruct %Foo_0 %Foo_0
|
||||
%_ptr_Uniform_SSBO = OpTypePointer Uniform %SSBO
|
||||
%_ = OpVariable %_ptr_Uniform_SSBO Uniform
|
||||
%int = OpTypeInt 32 1
|
||||
%int_0 = OpConstant %int 0
|
||||
%_ptr_Uniform_Foo_0 = OpTypePointer Uniform %Foo_0
|
||||
%_ptr_Function_mat2v2float = OpTypePointer Function %mat2v2float
|
||||
%int_1 = OpConstant %int 1
|
||||
%_ptr_Function_v2float = OpTypePointer Function %v2float
|
||||
%int_2 = OpConstant %int 2
|
||||
%_ptr_Function__arr_Bar_uint_5 = OpTypePointer Function %_arr_Bar_uint_5
|
||||
%_ptr_Function_Bar = OpTypePointer Function %Bar
|
||||
%_ptr_Function__arr__arr_float_uint_4_uint_2 = OpTypePointer Function %_arr__arr_float_uint_4_uint_2
|
||||
%_ptr_Function__arr_float_uint_4 = OpTypePointer Function %_arr_float_uint_4
|
||||
%_ptr_Function_float = OpTypePointer Function %float
|
||||
%int_3 = OpConstant %int 3
|
||||
%_ptr_Function__arr_Baz_uint_2 = OpTypePointer Function %_arr_Baz_uint_2
|
||||
%_ptr_Function_Baz = OpTypePointer Function %Baz
|
||||
%int_4 = OpConstant %int 4
|
||||
%float_1 = OpConstant %float 1
|
||||
%float_2 = OpConstant %float 2
|
||||
%float_5 = OpConstant %float 5
|
||||
%_ptr_Uniform_mat2v2float = OpTypePointer Uniform %mat2v2float
|
||||
%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
|
||||
%_ptr_Uniform__arr_Bar_0_uint_5 = OpTypePointer Uniform %_arr_Bar_0_uint_5
|
||||
%_ptr_Uniform_Bar_0 = OpTypePointer Uniform %Bar_0
|
||||
%_ptr_Uniform__arr__arr_float_uint_4_0_uint_2 = OpTypePointer Uniform %_arr__arr_float_uint_4_0_uint_2
|
||||
%_ptr_Uniform__arr_float_uint_4_0 = OpTypePointer Uniform %_arr_float_uint_4_0
|
||||
%_ptr_Uniform_float = OpTypePointer Uniform %float
|
||||
%_ptr_Uniform__arr_Baz_0_uint_2 = OpTypePointer Uniform %_arr_Baz_0_uint_2
|
||||
%_ptr_Uniform_Baz_0 = OpTypePointer Uniform %Baz_0
|
||||
%v3uint = OpTypeVector %uint 3
|
||||
%uint_1 = OpConstant %uint 1
|
||||
%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
|
||||
%main = OpFunction %void None %3
|
||||
%5 = OpLabel
|
||||
%ptr_load = OpAccessChain %_ptr_Uniform_Foo_0 %_ %int_0
|
||||
%ptr_store = OpAccessChain %_ptr_Uniform_Foo_0 %_ %int_1
|
||||
%loaded = OpLoad %Foo_0 %ptr_load
|
||||
OpStore %ptr_store %loaded
|
||||
OpReturn
|
||||
OpFunctionEnd
|
@ -6684,6 +6684,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
string expr;
|
||||
|
||||
bool index_is_literal = (flags & ACCESS_CHAIN_INDEX_IS_LITERAL_BIT) != 0;
|
||||
bool msb_is_id = (flags & ACCESS_CHAIN_LITERAL_MSB_FORCE_ID) != 0;
|
||||
bool chain_only = (flags & ACCESS_CHAIN_CHAIN_ONLY_BIT) != 0;
|
||||
bool ptr_chain = (flags & ACCESS_CHAIN_PTR_CHAIN_BIT) != 0;
|
||||
bool register_expression_read = (flags & ACCESS_CHAIN_SKIP_REGISTER_EXPRESSION_READ_BIT) == 0;
|
||||
@ -6728,14 +6729,24 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
bool pending_array_enclose = false;
|
||||
bool dimension_flatten = false;
|
||||
|
||||
const auto append_index = [&](uint32_t index) {
|
||||
access_chain_internal_append_index(expr, base, type, flags, access_chain_is_arrayed, index);
|
||||
const auto append_index = [&](uint32_t index, bool is_literal) {
|
||||
AccessChainFlags mod_flags = flags;
|
||||
if (!is_literal)
|
||||
mod_flags &= ~ACCESS_CHAIN_INDEX_IS_LITERAL_BIT;
|
||||
access_chain_internal_append_index(expr, base, type, mod_flags, access_chain_is_arrayed, index);
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
uint32_t index = indices[i];
|
||||
|
||||
bool is_literal = index_is_literal;
|
||||
if (is_literal && msb_is_id && (index >> 31u) != 0u)
|
||||
{
|
||||
is_literal = false;
|
||||
index &= 0x7fffffffu;
|
||||
}
|
||||
|
||||
// Pointer chains
|
||||
if (ptr_chain && i == 0)
|
||||
{
|
||||
@ -6752,7 +6763,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
if (options.flatten_multidimensional_arrays && dimension_flatten)
|
||||
{
|
||||
// If we are flattening multidimensional arrays, do manual stride computation.
|
||||
if (index_is_literal)
|
||||
if (is_literal)
|
||||
expr += convert_to_string(index);
|
||||
else
|
||||
expr += to_enclosed_expression(index, register_expression_read);
|
||||
@ -6773,7 +6784,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
}
|
||||
else
|
||||
{
|
||||
append_index(index);
|
||||
append_index(index, is_literal);
|
||||
}
|
||||
|
||||
if (type->basetype == SPIRType::ControlPointArray)
|
||||
@ -6820,11 +6831,11 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
else if (var->storage == StorageClassOutput)
|
||||
expr = join("gl_out[", to_expression(index, register_expression_read), "].", expr);
|
||||
else
|
||||
append_index(index);
|
||||
append_index(index, is_literal);
|
||||
break;
|
||||
|
||||
default:
|
||||
append_index(index);
|
||||
append_index(index, is_literal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -6833,7 +6844,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
// If we are flattening multidimensional arrays, do manual stride computation.
|
||||
auto &parent_type = get<SPIRType>(type->parent_type);
|
||||
|
||||
if (index_is_literal)
|
||||
if (is_literal)
|
||||
expr += convert_to_string(index);
|
||||
else
|
||||
expr += to_enclosed_expression(index, register_expression_read);
|
||||
@ -6856,7 +6867,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
// By throwing away the index, we imply the index was 0, which it must be for gl_SampleMask.
|
||||
else if (!builtin_translates_to_nonarray(BuiltIn(get_decoration(base, DecorationBuiltIn))))
|
||||
{
|
||||
append_index(index);
|
||||
append_index(index, is_literal);
|
||||
}
|
||||
|
||||
type_id = type->parent_type;
|
||||
@ -6868,7 +6879,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
// We also check if this member is a builtin, since we then replace the entire expression with the builtin one.
|
||||
else if (type->basetype == SPIRType::Struct)
|
||||
{
|
||||
if (!index_is_literal)
|
||||
if (!is_literal)
|
||||
index = get<SPIRConstant>(index).scalar();
|
||||
|
||||
if (index >= type->member_types.size())
|
||||
@ -6915,7 +6926,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
// by flipping indexing order of the matrix.
|
||||
|
||||
expr += "[";
|
||||
if (index_is_literal)
|
||||
if (is_literal)
|
||||
expr += convert_to_string(index);
|
||||
else
|
||||
expr += to_expression(index, register_expression_read);
|
||||
@ -6939,7 +6950,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
}
|
||||
}
|
||||
|
||||
if (index_is_literal && !is_packed && !row_major_matrix_needs_conversion)
|
||||
if (is_literal && !is_packed && !row_major_matrix_needs_conversion)
|
||||
{
|
||||
expr += ".";
|
||||
expr += index_to_swizzle(index);
|
||||
@ -6958,7 +6969,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
expr += index_to_swizzle(c.scalar());
|
||||
}
|
||||
}
|
||||
else if (index_is_literal)
|
||||
else if (is_literal)
|
||||
{
|
||||
// For packed vectors, we can only access them as an array, not by swizzle.
|
||||
expr += join("[", index, "]");
|
||||
|
@ -56,7 +56,8 @@ enum AccessChainFlagBits
|
||||
ACCESS_CHAIN_INDEX_IS_LITERAL_BIT = 1 << 0,
|
||||
ACCESS_CHAIN_CHAIN_ONLY_BIT = 1 << 1,
|
||||
ACCESS_CHAIN_PTR_CHAIN_BIT = 1 << 2,
|
||||
ACCESS_CHAIN_SKIP_REGISTER_EXPRESSION_READ_BIT = 1 << 3
|
||||
ACCESS_CHAIN_SKIP_REGISTER_EXPRESSION_READ_BIT = 1 << 3,
|
||||
ACCESS_CHAIN_LITERAL_MSB_FORCE_ID = 1 << 4
|
||||
};
|
||||
typedef uint32_t AccessChainFlags;
|
||||
|
||||
|
115
spirv_hlsl.cpp
115
spirv_hlsl.cpp
@ -3637,7 +3637,92 @@ void CompilerHLSL::emit_load(const Instruction &instruction)
|
||||
CompilerGLSL::emit_instruction(instruction);
|
||||
}
|
||||
|
||||
void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t value)
|
||||
void CompilerHLSL::write_access_chain_array(const SPIRAccessChain &chain, uint32_t value,
|
||||
const SmallVector<uint32_t> &composite_chain)
|
||||
{
|
||||
auto &type = get<SPIRType>(chain.basetype);
|
||||
|
||||
// Need to use a reserved identifier here since it might shadow an identifier in the access chain input or other loops.
|
||||
auto ident = get_unique_identifier();
|
||||
|
||||
uint32_t id = ir.increase_bound_by(2);
|
||||
uint32_t int_type_id = id + 1;
|
||||
SPIRType int_type;
|
||||
int_type.basetype = SPIRType::Int;
|
||||
int_type.width = 32;
|
||||
set<SPIRType>(int_type_id, int_type);
|
||||
set<SPIRExpression>(id, ident, int_type_id, true);
|
||||
set_name(id, ident);
|
||||
suppressed_usage_tracking.insert(id);
|
||||
|
||||
statement("[unroll]");
|
||||
statement("for (int ", ident, " = 0; ", ident, " < ", to_array_size(type, uint32_t(type.array.size() - 1)), "; ", ident, "++)");
|
||||
begin_scope();
|
||||
auto subchain = chain;
|
||||
subchain.dynamic_index = join(ident, " * ", chain.array_stride, " + ", chain.dynamic_index);
|
||||
subchain.basetype = type.parent_type;
|
||||
|
||||
// Forcefully allow us to use an ID here by setting MSB.
|
||||
auto subcomposite_chain = composite_chain;
|
||||
subcomposite_chain.push_back(0x80000000u | id);
|
||||
|
||||
if (!get<SPIRType>(subchain.basetype).array.empty())
|
||||
subchain.array_stride = get_decoration(subchain.basetype, DecorationArrayStride);
|
||||
|
||||
write_access_chain(subchain, value, subcomposite_chain);
|
||||
end_scope();
|
||||
}
|
||||
|
||||
void CompilerHLSL::write_access_chain_struct(const SPIRAccessChain &chain, uint32_t value,
|
||||
const SmallVector<uint32_t> &composite_chain)
|
||||
{
|
||||
auto &type = get<SPIRType>(chain.basetype);
|
||||
uint32_t member_count = uint32_t(type.member_types.size());
|
||||
auto subchain = chain;
|
||||
|
||||
auto subcomposite_chain = composite_chain;
|
||||
subcomposite_chain.push_back(0);
|
||||
|
||||
for (uint32_t i = 0; i < member_count; i++)
|
||||
{
|
||||
uint32_t offset = type_struct_member_offset(type, i);
|
||||
subchain.static_index = chain.static_index + offset;
|
||||
subchain.basetype = type.member_types[i];
|
||||
|
||||
auto &member_type = get<SPIRType>(subchain.basetype);
|
||||
if (member_type.columns > 1)
|
||||
{
|
||||
subchain.matrix_stride = type_struct_member_matrix_stride(type, i);
|
||||
subchain.row_major_matrix = has_member_decoration(type.self, i, DecorationRowMajor);
|
||||
}
|
||||
|
||||
if (!member_type.array.empty())
|
||||
subchain.array_stride = type_struct_member_array_stride(type, i);
|
||||
|
||||
subcomposite_chain.back() = i;
|
||||
write_access_chain(subchain, value, subcomposite_chain);
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerHLSL::write_access_chain_value(uint32_t value, const SmallVector<uint32_t> &composite_chain, bool enclose)
|
||||
{
|
||||
string ret;
|
||||
if (composite_chain.empty())
|
||||
ret = to_expression(value);
|
||||
else
|
||||
{
|
||||
AccessChainMeta meta;
|
||||
ret = access_chain_internal(value, composite_chain.data(), uint32_t(composite_chain.size()),
|
||||
ACCESS_CHAIN_INDEX_IS_LITERAL_BIT | ACCESS_CHAIN_LITERAL_MSB_FORCE_ID, &meta);
|
||||
}
|
||||
|
||||
if (enclose)
|
||||
ret = enclose_expression(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t value,
|
||||
const SmallVector<uint32_t> &composite_chain)
|
||||
{
|
||||
auto &type = get<SPIRType>(chain.basetype);
|
||||
|
||||
@ -3652,12 +3737,20 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
|
||||
target_type.vecsize = type.vecsize;
|
||||
target_type.columns = type.columns;
|
||||
|
||||
if (type.basetype == SPIRType::Struct)
|
||||
SPIRV_CROSS_THROW("Writing structs to RWByteAddressBuffer not yet supported.");
|
||||
if (type.width != 32)
|
||||
SPIRV_CROSS_THROW("Writing types other than 32-bit to RWByteAddressBuffer not yet supported.");
|
||||
if (!type.array.empty())
|
||||
SPIRV_CROSS_THROW("Reading arrays from ByteAddressBuffer not yet supported.");
|
||||
{
|
||||
write_access_chain_array(chain, value, composite_chain);
|
||||
register_write(chain.self);
|
||||
return;
|
||||
}
|
||||
else if (type.basetype == SPIRType::Struct)
|
||||
{
|
||||
write_access_chain_struct(chain, value, composite_chain);
|
||||
register_write(chain.self);
|
||||
return;
|
||||
}
|
||||
else if (type.width != 32)
|
||||
SPIRV_CROSS_THROW("Writing types other than 32-bit to RWByteAddressBuffer not yet supported.");
|
||||
|
||||
if (type.columns == 1 && !chain.row_major_matrix)
|
||||
{
|
||||
@ -3680,7 +3773,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
|
||||
SPIRV_CROSS_THROW("Unknown vector size.");
|
||||
}
|
||||
|
||||
auto store_expr = to_expression(value);
|
||||
auto store_expr = write_access_chain_value(value, composite_chain, false);
|
||||
auto bitcast_op = bitcast_glsl_op(target_type, type);
|
||||
if (!bitcast_op.empty())
|
||||
store_expr = join(bitcast_op, "(", store_expr, ")");
|
||||
@ -3691,7 +3784,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
|
||||
// Strided store.
|
||||
for (uint32_t r = 0; r < type.vecsize; r++)
|
||||
{
|
||||
auto store_expr = to_enclosed_expression(value);
|
||||
auto store_expr = write_access_chain_value(value, composite_chain, true);
|
||||
if (type.vecsize > 1)
|
||||
{
|
||||
store_expr += ".";
|
||||
@ -3729,7 +3822,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
|
||||
|
||||
for (uint32_t c = 0; c < type.columns; c++)
|
||||
{
|
||||
auto store_expr = join(to_enclosed_expression(value), "[", c, "]");
|
||||
auto store_expr = join(write_access_chain_value(value, composite_chain, true), "[", c, "]");
|
||||
auto bitcast_op = bitcast_glsl_op(target_type, type);
|
||||
if (!bitcast_op.empty())
|
||||
store_expr = join(bitcast_op, "(", store_expr, ")");
|
||||
@ -3743,7 +3836,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val
|
||||
{
|
||||
for (uint32_t c = 0; c < type.columns; c++)
|
||||
{
|
||||
auto store_expr = join(to_enclosed_expression(value), "[", c, "].", index_to_swizzle(r));
|
||||
auto store_expr = join(write_access_chain_value(value, composite_chain, true), "[", c, "].", index_to_swizzle(r));
|
||||
remove_duplicate_swizzle(store_expr);
|
||||
auto bitcast_op = bitcast_glsl_op(target_type, type);
|
||||
if (!bitcast_op.empty())
|
||||
@ -3762,7 +3855,7 @@ void CompilerHLSL::emit_store(const Instruction &instruction)
|
||||
auto ops = stream(instruction);
|
||||
auto *chain = maybe_get<SPIRAccessChain>(ops[0]);
|
||||
if (chain)
|
||||
write_access_chain(*chain, ops[1]);
|
||||
write_access_chain(*chain, ops[1], {});
|
||||
else
|
||||
CompilerGLSL::emit_instruction(instruction);
|
||||
}
|
||||
|
@ -185,7 +185,10 @@ private:
|
||||
void read_access_chain(std::string *expr, const std::string &lhs, const SPIRAccessChain &chain);
|
||||
void read_access_chain_struct(const std::string &lhs, const SPIRAccessChain &chain);
|
||||
void read_access_chain_array(const std::string &lhs, const SPIRAccessChain &chain);
|
||||
void write_access_chain(const SPIRAccessChain &chain, uint32_t value);
|
||||
void write_access_chain(const SPIRAccessChain &chain, uint32_t value, const SmallVector<uint32_t> &composite_chain);
|
||||
void write_access_chain_struct(const SPIRAccessChain &chain, uint32_t value, const SmallVector<uint32_t> &composite_chain);
|
||||
void write_access_chain_array(const SPIRAccessChain &chain, uint32_t value, const SmallVector<uint32_t> &composite_chain);
|
||||
std::string write_access_chain_value(uint32_t value, const SmallVector<uint32_t> &composite_chain, bool enclose);
|
||||
void emit_store(const Instruction &instruction);
|
||||
void emit_atomic(const uint32_t *ops, uint32_t length, spv::Op op);
|
||||
void emit_subgroup_op(const Instruction &i) override;
|
||||
|
Loading…
Reference in New Issue
Block a user