Fix bugs with row-major matrices inside flattened UBOs.
This commit is contained in:
parent
d93dc38415
commit
3eb2e52c4e
@ -1,10 +1,11 @@
|
||||
#version 310 es
|
||||
|
||||
uniform vec4 UBO[8];
|
||||
uniform vec4 UBO[12];
|
||||
in vec4 aVertex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 v = mat4x2(UBO[8].xy, UBO[9].xy, UBO[10].xy, UBO[11].xy) * aVertex;
|
||||
gl_Position = (mat4(UBO[0], UBO[1], UBO[2], UBO[3]) * aVertex) + (aVertex * mat4(UBO[4], UBO[5], UBO[6], UBO[7]));
|
||||
}
|
||||
|
||||
|
25
reference/shaders/flatten/struct.rowmajor.flatten.vert
Normal file
25
reference/shaders/flatten/struct.rowmajor.flatten.vert
Normal file
@ -0,0 +1,25 @@
|
||||
#version 310 es
|
||||
|
||||
struct Foo
|
||||
{
|
||||
mat3x4 MVP0;
|
||||
mat3x4 MVP1;
|
||||
};
|
||||
|
||||
uniform vec4 UBO[8];
|
||||
layout(location = 0) in vec4 v0;
|
||||
layout(location = 1) in vec4 v1;
|
||||
layout(location = 0) out vec3 V0;
|
||||
layout(location = 1) out vec3 V1;
|
||||
|
||||
void main()
|
||||
{
|
||||
Foo f;
|
||||
f.MVP0 = Foo(transpose(mat4x3(UBO[0].xyz, UBO[1].xyz, UBO[2].xyz, UBO[3].xyz)), transpose(mat4x3(UBO[4].xyz, UBO[5].xyz, UBO[6].xyz, UBO[7].xyz))).MVP0;
|
||||
f.MVP1 = Foo(transpose(mat4x3(UBO[0].xyz, UBO[1].xyz, UBO[2].xyz, UBO[3].xyz)), transpose(mat4x3(UBO[4].xyz, UBO[5].xyz, UBO[6].xyz, UBO[7].xyz))).MVP1;
|
||||
vec3 a = v0 * f.MVP0;
|
||||
vec3 b = v1 * f.MVP1;
|
||||
V0 = a;
|
||||
V1 = b;
|
||||
}
|
||||
|
@ -4,11 +4,13 @@ layout(std140) uniform UBO
|
||||
{
|
||||
layout(column_major) mat4 uMVPR;
|
||||
layout(row_major) mat4 uMVPC;
|
||||
layout(row_major) mat2x4 uMVP;
|
||||
};
|
||||
|
||||
in vec4 aVertex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 v = aVertex * uMVP;
|
||||
gl_Position = uMVPR * aVertex + uMVPC * aVertex;
|
||||
}
|
||||
|
26
shaders/flatten/struct.rowmajor.flatten.vert
Normal file
26
shaders/flatten/struct.rowmajor.flatten.vert
Normal file
@ -0,0 +1,26 @@
|
||||
#version 310 es
|
||||
|
||||
struct Foo
|
||||
{
|
||||
mat3x4 MVP0;
|
||||
mat3x4 MVP1;
|
||||
};
|
||||
|
||||
layout(std140, binding = 0) uniform UBO
|
||||
{
|
||||
layout(row_major) Foo foo;
|
||||
};
|
||||
|
||||
layout(location = 0) in vec4 v0;
|
||||
layout(location = 1) in vec4 v1;
|
||||
layout(location = 0) out vec3 V0;
|
||||
layout(location = 1) out vec3 V1;
|
||||
|
||||
void main()
|
||||
{
|
||||
Foo f = foo;
|
||||
vec3 a = v0 * f.MVP0;
|
||||
vec3 b = v1 * f.MVP1;
|
||||
V0 = a;
|
||||
V1 = b;
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
#include "GLSL.std.450.h"
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <utility>
|
||||
|
||||
using namespace spv;
|
||||
using namespace spirv_cross;
|
||||
@ -3352,15 +3353,30 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin
|
||||
expr += type_to_glsl_constructor(target_type);
|
||||
expr += "(";
|
||||
|
||||
// Need to have an extra indices for the member so we can find matrix strides.
|
||||
vector<uint32_t> indices_copy(indices, indices + count);
|
||||
indices_copy.push_back(0);
|
||||
|
||||
for (size_t i = 0; i < target_type.member_types.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
expr += ", ";
|
||||
|
||||
const SPIRType &member_type = get<SPIRType>(target_type.member_types[i]);
|
||||
uint32_t member_offset = type_struct_member_offset(target_type, uint32_t(i));
|
||||
|
||||
expr += flattened_access_chain(base, indices, count, member_type, offset + member_offset);
|
||||
// The indices should be IDs, but to avoid creating new dummy SPIRConstant here,
|
||||
// use MSB to indicate literals.
|
||||
indices_copy.back() = uint32_t(i) | 0x80000000u;
|
||||
|
||||
bool need_transpose = false;
|
||||
if (member_type.columns > 1)
|
||||
flattened_access_chain_offset(base, indices_copy.data(), count + 1, offset, &need_transpose);
|
||||
|
||||
auto tmp = flattened_access_chain(base, indices_copy.data(), count + 1, member_type, offset);
|
||||
if (need_transpose)
|
||||
expr += convert_row_major_matrix(tmp);
|
||||
else
|
||||
expr += tmp;
|
||||
}
|
||||
|
||||
expr += ")";
|
||||
@ -3374,17 +3390,24 @@ std::string CompilerGLSL::flattened_access_chain_matrix(uint32_t base, const uin
|
||||
std::string expr;
|
||||
|
||||
uint32_t matrix_stride = 0;
|
||||
flattened_access_chain_offset(base, indices, count, offset, nullptr, &matrix_stride);
|
||||
bool need_transpose = false;
|
||||
flattened_access_chain_offset(base, indices, count, offset, &need_transpose, &matrix_stride);
|
||||
|
||||
expr += type_to_glsl_constructor(target_type);
|
||||
assert(matrix_stride);
|
||||
|
||||
SPIRType tmp_type = target_type;
|
||||
if (need_transpose)
|
||||
swap(tmp_type.vecsize, tmp_type.columns);
|
||||
|
||||
expr += type_to_glsl_constructor(tmp_type);
|
||||
expr += "(";
|
||||
|
||||
for (uint32_t i = 0; i < target_type.columns; i++)
|
||||
for (uint32_t i = 0; i < tmp_type.columns; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
expr += ", ";
|
||||
|
||||
expr += flattened_access_chain_vector_scalar(base, indices, count, target_type, offset + i * matrix_stride);
|
||||
expr += flattened_access_chain_vector_scalar(base, indices, count, tmp_type, offset + i * matrix_stride);
|
||||
}
|
||||
|
||||
expr += ")";
|
||||
@ -3471,23 +3494,28 @@ std::pair<std::string, uint32_t> CompilerGLSL::flattened_access_chain_offset(uin
|
||||
// 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)
|
||||
{
|
||||
index = get<SPIRConstant>(index).scalar();
|
||||
// The indices should be IDs, but to avoid creating new dummy SPIRConstant here,
|
||||
// use MSB to indicate literals.
|
||||
// See flattened_access_chain_struct.
|
||||
index = (index & 0x80000000u) ? (index & 0x7fffffffu) : get<SPIRConstant>(index).scalar();
|
||||
|
||||
if (index >= type->member_types.size())
|
||||
SPIRV_CROSS_THROW("Member index is out of bounds!");
|
||||
|
||||
offset += type_struct_member_offset(*type, index);
|
||||
|
||||
row_major_matrix_needs_conversion =
|
||||
(combined_decoration_for_member(*type, index) & (1ull << DecorationRowMajor)) != 0;
|
||||
|
||||
current_type = type->member_types[index];
|
||||
|
||||
auto &struct_type = *type;
|
||||
type = &get<SPIRType>(type->member_types[index]);
|
||||
|
||||
if (type->columns > 1)
|
||||
{
|
||||
matrix_stride = type_struct_member_matrix_stride(struct_type, index);
|
||||
row_major_matrix_needs_conversion =
|
||||
(combined_decoration_for_member(struct_type, index) & (1ull << DecorationRowMajor)) != 0;
|
||||
}
|
||||
else
|
||||
row_major_matrix_needs_conversion = false;
|
||||
}
|
||||
// Matrix -> Vector
|
||||
else if (type->columns > 1)
|
||||
|
Loading…
Reference in New Issue
Block a user