Emit matrix layouts in structs directly.

Unlike GLSL, child structs do not inherit matrix layouts.
This commit is contained in:
Hans-Kristian Arntzen 2018-06-05 09:42:07 +02:00
parent b1196f2ace
commit f1e8555801
4 changed files with 115 additions and 6 deletions

View File

@ -0,0 +1,37 @@
struct Foo
{
row_major float4x4 v;
row_major float4x4 w;
};
cbuffer _17 : register(b0)
{
Foo _17_foo : packoffset(c0);
};
static float4 FragColor;
static float4 vUV;
struct SPIRV_Cross_Input
{
float4 vUV : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
FragColor = mul(mul(vUV, _17_foo.w), _17_foo.v);
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vUV = stage_input.vUV;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,46 @@
struct NonFoo
{
float4x4 v;
float4x4 w;
};
struct Foo
{
row_major float4x4 v;
row_major float4x4 w;
};
cbuffer _17 : register(b0)
{
Foo _17_foo : packoffset(c0);
};
static float4 FragColor;
static float4 vUV;
struct SPIRV_Cross_Input
{
float4 vUV : TEXCOORD0;
};
struct SPIRV_Cross_Output
{
float4 FragColor : SV_Target0;
};
void frag_main()
{
NonFoo f;
f.v = _17_foo.v;
f.w = _17_foo.w;
FragColor = mul(mul(vUV, f.w), f.v);
}
SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input)
{
vUV = stage_input.vUV;
frag_main();
SPIRV_Cross_Output stage_output;
stage_output.FragColor = FragColor;
return stage_output;
}

View File

@ -0,0 +1,29 @@
#version 450
struct Foo
{
mat4 v;
mat4 w;
};
struct NonFoo
{
mat4 v;
mat4 w;
};
layout(std140, binding = 0) uniform UBO
{
layout(column_major) Foo foo;
};
layout(location = 0) out vec4 FragColor;
layout(location = 0) in vec4 vUV;
void main()
{
NonFoo f;
f.v = foo.v;
f.w = foo.w;
FragColor = f.v * (f.w * vUV);
}

View File

@ -1778,13 +1778,10 @@ void CompilerHLSL::emit_resources()
string CompilerHLSL::layout_for_member(const SPIRType &type, uint32_t index)
{
auto flags = combined_decoration_for_member(type, index);
auto &flags = get_member_decoration_bitset(type.self, index);
bool is_block = meta[type.self].decoration.decoration_flags.get(DecorationBlock) ||
meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock);
if (!is_block)
return "";
// HLSL can emit row_major or column_major decoration in any struct.
// Do not try to merge combined decorations for children like in GLSL.
// Flip the convention. HLSL is a bit odd in that the memory layout is column major ... but the language API is "row-major".
// The way to deal with this is to multiply everything in inverse order, and reverse the memory layout.