Implement access chain flattening support for row major matrices
We currently only support access chains that end in a matrix by propagating "needs transpose" flag upstream which flips the matrix multiplication order. It's possible to support indexed extraction as well, however it would have to generate code like this: vec4 row = vec4(UBO[0].y, UBO[1].y, UBO[2].y, UBO[3].y); for a column equivalent of: vec4 row = UBO[1]; It is definitely possible to do so but it requires signaling the vector output that it needs to switch to per-component extraction which is a bit more trouble than this is worth for now.
This commit is contained in:
Родитель
1ec6c1a029
Коммит
62b27f1d81
|
@ -0,0 +1,10 @@
|
|||
#version 310 es
|
||||
|
||||
uniform vec4 UBO[8];
|
||||
in vec4 aVertex;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = (mat4(UBO[0], UBO[1], UBO[2], UBO[3]) * aVertex) + (aVertex * mat4(UBO[4], UBO[5], UBO[6], UBO[7]));
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#version 310 es
|
||||
|
||||
layout(std140) uniform UBO
|
||||
{
|
||||
layout(column_major) mat4 uMVPR;
|
||||
layout(row_major) mat4 uMVPC;
|
||||
};
|
||||
|
||||
in vec4 aVertex;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = uMVPR * aVertex + uMVPC * aVertex;
|
||||
}
|
|
@ -3295,7 +3295,7 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
|
|||
if (flattened_buffer_blocks.count(base))
|
||||
{
|
||||
if (need_transpose)
|
||||
*need_transpose = false;
|
||||
flattened_access_chain_offset(base, indices, count, 0, need_transpose);
|
||||
|
||||
return flattened_access_chain(base, indices, count, target_type, 0);
|
||||
}
|
||||
|
@ -3393,7 +3393,7 @@ std::string CompilerGLSL::flattened_access_chain_vector_scalar(uint32_t base, co
|
|||
return expr;
|
||||
}
|
||||
|
||||
std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uint32_t base, const uint32_t *indices, uint32_t count, uint32_t offset)
|
||||
std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uint32_t base, const uint32_t *indices, uint32_t count, uint32_t offset, bool *need_transpose)
|
||||
{
|
||||
const auto *type = &expression_type(base);
|
||||
uint32_t type_size = 0;
|
||||
|
@ -3402,6 +3402,7 @@ std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uin
|
|||
SPIRType temp;
|
||||
|
||||
std::string expr;
|
||||
bool row_major_matrix_needs_conversion = false;
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -3443,11 +3444,15 @@ std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uin
|
|||
offset += type_struct_member_offset(*type, index);
|
||||
|
||||
type_size = uint32_t(get_declared_struct_member_size(*type, index));
|
||||
row_major_matrix_needs_conversion = (combined_decoration_for_member(*type, index) & (1ull << DecorationRowMajor)) != 0;
|
||||
type = &get<SPIRType>(type->member_types[index]);
|
||||
}
|
||||
// Matrix -> Vector
|
||||
else if (type->columns > 1)
|
||||
{
|
||||
if (row_major_matrix_needs_conversion)
|
||||
SPIRV_CROSS_THROW("Matrix indexing is not supported for flattened row major matrices!");
|
||||
|
||||
if (ids[index].get_type() != TypeConstant)
|
||||
SPIRV_CROSS_THROW("Cannot flatten dynamic matrix indexing!");
|
||||
|
||||
|
@ -3481,6 +3486,9 @@ std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uin
|
|||
SPIRV_CROSS_THROW("Cannot subdivide a scalar value!");
|
||||
}
|
||||
|
||||
if (need_transpose)
|
||||
*need_transpose = row_major_matrix_needs_conversion;
|
||||
|
||||
return std::make_pair(expr, offset);
|
||||
}
|
||||
|
||||
|
@ -5642,13 +5650,6 @@ void CompilerGLSL::flatten_buffer_block(uint32_t id)
|
|||
if (type.member_types.empty())
|
||||
SPIRV_CROSS_THROW(name + " is an empty struct.");
|
||||
|
||||
uint64_t member_flags = 0;
|
||||
for (uint32_t i = 0; i < type.member_types.size(); i++)
|
||||
member_flags |= combined_decoration_for_member(type, i);
|
||||
|
||||
if (member_flags & (1ull << DecorationRowMajor))
|
||||
SPIRV_CROSS_THROW(name + " uses row major matrices which is not supported.");
|
||||
|
||||
flattened_buffer_blocks.insert(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -315,13 +315,13 @@ protected:
|
|||
bool suppress_usage_tracking = false);
|
||||
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, bool index_is_literal,
|
||||
bool chain_only = false, bool *need_transpose = nullptr);
|
||||
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, bool *need_transpose);
|
||||
std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, bool *need_transpose = nullptr);
|
||||
|
||||
std::string flattened_access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
|
||||
std::string flattened_access_chain_struct(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
|
||||
std::string flattened_access_chain_matrix(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
|
||||
std::string flattened_access_chain_vector_scalar(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, uint32_t offset);
|
||||
std::pair<std::string, uint32_t> flattened_access_chain_offset(uint32_t base, const uint32_t *indices, uint32_t count, uint32_t offset);
|
||||
std::pair<std::string, uint32_t> flattened_access_chain_offset(uint32_t base, const uint32_t *indices, uint32_t count, uint32_t offset, bool *need_transpose = nullptr);
|
||||
|
||||
const char *index_to_swizzle(uint32_t index);
|
||||
std::string remap_swizzle(uint32_t result_type, uint32_t input_components, uint32_t expr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче