GLSL: Support GL_EXT_scalar_block_layout.
This commit is contained in:
parent
138d0e326d
commit
6f091e7c8f
@ -4,7 +4,7 @@
|
|||||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
layout(buffer_reference) buffer Node;
|
layout(buffer_reference) buffer Node;
|
||||||
layout(buffer_reference, std140) buffer Node
|
layout(buffer_reference, std430) buffer Node
|
||||||
{
|
{
|
||||||
layout(offset = 0) int value;
|
layout(offset = 0) int value;
|
||||||
layout(offset = 16) Node next;
|
layout(offset = 16) Node next;
|
||||||
|
@ -0,0 +1,147 @@
|
|||||||
|
#version 310 es
|
||||||
|
#extension GL_EXT_scalar_block_layout : require
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
|
struct S0
|
||||||
|
{
|
||||||
|
vec2 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S1
|
||||||
|
{
|
||||||
|
vec3 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S2
|
||||||
|
{
|
||||||
|
vec3 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S3
|
||||||
|
{
|
||||||
|
vec2 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S4
|
||||||
|
{
|
||||||
|
vec2 c;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Content
|
||||||
|
{
|
||||||
|
S0 m0s[1];
|
||||||
|
S1 m1s[1];
|
||||||
|
S2 m2s[1];
|
||||||
|
S0 m0;
|
||||||
|
S1 m1;
|
||||||
|
S2 m2;
|
||||||
|
S3 m3;
|
||||||
|
float m4;
|
||||||
|
S4 m3s[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S0_1
|
||||||
|
{
|
||||||
|
vec2 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S1_1
|
||||||
|
{
|
||||||
|
vec3 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S2_1
|
||||||
|
{
|
||||||
|
vec3 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S3_1
|
||||||
|
{
|
||||||
|
vec2 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S4_1
|
||||||
|
{
|
||||||
|
vec2 c;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Content_1
|
||||||
|
{
|
||||||
|
S0_1 m0s[1];
|
||||||
|
S1_1 m1s[1];
|
||||||
|
S2_1 m2s[1];
|
||||||
|
S0_1 m0;
|
||||||
|
S1_1 m1;
|
||||||
|
S2_1 m2;
|
||||||
|
S3_1 m3;
|
||||||
|
float m4;
|
||||||
|
S4_1 m3s[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(set = 0, binding = 1, scalar) restrict buffer SSBO1
|
||||||
|
{
|
||||||
|
Content content;
|
||||||
|
Content content1[2];
|
||||||
|
Content content2;
|
||||||
|
mat2 m0;
|
||||||
|
mat2 m1;
|
||||||
|
mat2x3 m2[4];
|
||||||
|
mat3x2 m3;
|
||||||
|
layout(row_major) mat2 m4;
|
||||||
|
layout(row_major) mat2 m5[9];
|
||||||
|
layout(row_major) mat2x3 m6[4][2];
|
||||||
|
layout(row_major) mat3x2 m7;
|
||||||
|
float array[];
|
||||||
|
} ssbo_430;
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0, std140) restrict buffer SSBO0
|
||||||
|
{
|
||||||
|
Content_1 content;
|
||||||
|
Content_1 content1[2];
|
||||||
|
Content_1 content2;
|
||||||
|
mat2 m0;
|
||||||
|
mat2 m1;
|
||||||
|
mat2x3 m2[4];
|
||||||
|
mat3x2 m3;
|
||||||
|
layout(row_major) mat2 m4;
|
||||||
|
layout(row_major) mat2 m5[9];
|
||||||
|
layout(row_major) mat2x3 m6[4][2];
|
||||||
|
layout(row_major) mat3x2 m7;
|
||||||
|
float array[];
|
||||||
|
} ssbo_140;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ssbo_430.content.m0s[0].a[0] = ssbo_140.content.m0s[0].a[0];
|
||||||
|
ssbo_430.content.m0s[0].b = ssbo_140.content.m0s[0].b;
|
||||||
|
ssbo_430.content.m1s[0].a = ssbo_140.content.m1s[0].a;
|
||||||
|
ssbo_430.content.m1s[0].b = ssbo_140.content.m1s[0].b;
|
||||||
|
ssbo_430.content.m2s[0].a[0] = ssbo_140.content.m2s[0].a[0];
|
||||||
|
ssbo_430.content.m2s[0].b = ssbo_140.content.m2s[0].b;
|
||||||
|
ssbo_430.content.m0.a[0] = ssbo_140.content.m0.a[0];
|
||||||
|
ssbo_430.content.m0.b = ssbo_140.content.m0.b;
|
||||||
|
ssbo_430.content.m1.a = ssbo_140.content.m1.a;
|
||||||
|
ssbo_430.content.m1.b = ssbo_140.content.m1.b;
|
||||||
|
ssbo_430.content.m2.a[0] = ssbo_140.content.m2.a[0];
|
||||||
|
ssbo_430.content.m2.b = ssbo_140.content.m2.b;
|
||||||
|
ssbo_430.content.m3.a = ssbo_140.content.m3.a;
|
||||||
|
ssbo_430.content.m3.b = ssbo_140.content.m3.b;
|
||||||
|
ssbo_430.content.m4 = ssbo_140.content.m4;
|
||||||
|
ssbo_430.content.m3s[0].c = ssbo_140.content.m3s[0].c;
|
||||||
|
ssbo_430.content.m3s[1].c = ssbo_140.content.m3s[1].c;
|
||||||
|
ssbo_430.content.m3s[2].c = ssbo_140.content.m3s[2].c;
|
||||||
|
ssbo_430.content.m3s[3].c = ssbo_140.content.m3s[3].c;
|
||||||
|
ssbo_430.content.m3s[4].c = ssbo_140.content.m3s[4].c;
|
||||||
|
ssbo_430.content.m3s[5].c = ssbo_140.content.m3s[5].c;
|
||||||
|
ssbo_430.content.m3s[6].c = ssbo_140.content.m3s[6].c;
|
||||||
|
ssbo_430.content.m3s[7].c = ssbo_140.content.m3s[7].c;
|
||||||
|
}
|
||||||
|
|
@ -4,7 +4,7 @@
|
|||||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
layout(buffer_reference) buffer Node;
|
layout(buffer_reference) buffer Node;
|
||||||
layout(buffer_reference, std140) buffer Node
|
layout(buffer_reference, std430) buffer Node
|
||||||
{
|
{
|
||||||
layout(offset = 0) int value;
|
layout(offset = 0) int value;
|
||||||
layout(offset = 16) Node next;
|
layout(offset = 16) Node next;
|
||||||
|
@ -0,0 +1,147 @@
|
|||||||
|
#version 310 es
|
||||||
|
#extension GL_EXT_scalar_block_layout : require
|
||||||
|
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
|
|
||||||
|
struct S0
|
||||||
|
{
|
||||||
|
vec2 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S1
|
||||||
|
{
|
||||||
|
vec3 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S2
|
||||||
|
{
|
||||||
|
vec3 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S3
|
||||||
|
{
|
||||||
|
vec2 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S4
|
||||||
|
{
|
||||||
|
vec2 c;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Content
|
||||||
|
{
|
||||||
|
S0 m0s[1];
|
||||||
|
S1 m1s[1];
|
||||||
|
S2 m2s[1];
|
||||||
|
S0 m0;
|
||||||
|
S1 m1;
|
||||||
|
S2 m2;
|
||||||
|
S3 m3;
|
||||||
|
float m4;
|
||||||
|
S4 m3s[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S0_1
|
||||||
|
{
|
||||||
|
vec2 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S1_1
|
||||||
|
{
|
||||||
|
vec3 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S2_1
|
||||||
|
{
|
||||||
|
vec3 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S3_1
|
||||||
|
{
|
||||||
|
vec2 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S4_1
|
||||||
|
{
|
||||||
|
vec2 c;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Content_1
|
||||||
|
{
|
||||||
|
S0_1 m0s[1];
|
||||||
|
S1_1 m1s[1];
|
||||||
|
S2_1 m2s[1];
|
||||||
|
S0_1 m0;
|
||||||
|
S1_1 m1;
|
||||||
|
S2_1 m2;
|
||||||
|
S3_1 m3;
|
||||||
|
float m4;
|
||||||
|
S4_1 m3s[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(set = 0, binding = 1, scalar) restrict buffer SSBO1
|
||||||
|
{
|
||||||
|
Content content;
|
||||||
|
Content content1[2];
|
||||||
|
Content content2;
|
||||||
|
mat2 m0;
|
||||||
|
mat2 m1;
|
||||||
|
mat2x3 m2[4];
|
||||||
|
mat3x2 m3;
|
||||||
|
layout(row_major) mat2 m4;
|
||||||
|
layout(row_major) mat2 m5[9];
|
||||||
|
layout(row_major) mat2x3 m6[4][2];
|
||||||
|
layout(row_major) mat3x2 m7;
|
||||||
|
float array[];
|
||||||
|
} ssbo_430;
|
||||||
|
|
||||||
|
layout(set = 0, binding = 0, std140) restrict buffer SSBO0
|
||||||
|
{
|
||||||
|
Content_1 content;
|
||||||
|
Content_1 content1[2];
|
||||||
|
Content_1 content2;
|
||||||
|
mat2 m0;
|
||||||
|
mat2 m1;
|
||||||
|
mat2x3 m2[4];
|
||||||
|
mat3x2 m3;
|
||||||
|
layout(row_major) mat2 m4;
|
||||||
|
layout(row_major) mat2 m5[9];
|
||||||
|
layout(row_major) mat2x3 m6[4][2];
|
||||||
|
layout(row_major) mat3x2 m7;
|
||||||
|
float array[];
|
||||||
|
} ssbo_140;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ssbo_430.content.m0s[0].a[0] = ssbo_140.content.m0s[0].a[0];
|
||||||
|
ssbo_430.content.m0s[0].b = ssbo_140.content.m0s[0].b;
|
||||||
|
ssbo_430.content.m1s[0].a = ssbo_140.content.m1s[0].a;
|
||||||
|
ssbo_430.content.m1s[0].b = ssbo_140.content.m1s[0].b;
|
||||||
|
ssbo_430.content.m2s[0].a[0] = ssbo_140.content.m2s[0].a[0];
|
||||||
|
ssbo_430.content.m2s[0].b = ssbo_140.content.m2s[0].b;
|
||||||
|
ssbo_430.content.m0.a[0] = ssbo_140.content.m0.a[0];
|
||||||
|
ssbo_430.content.m0.b = ssbo_140.content.m0.b;
|
||||||
|
ssbo_430.content.m1.a = ssbo_140.content.m1.a;
|
||||||
|
ssbo_430.content.m1.b = ssbo_140.content.m1.b;
|
||||||
|
ssbo_430.content.m2.a[0] = ssbo_140.content.m2.a[0];
|
||||||
|
ssbo_430.content.m2.b = ssbo_140.content.m2.b;
|
||||||
|
ssbo_430.content.m3.a = ssbo_140.content.m3.a;
|
||||||
|
ssbo_430.content.m3.b = ssbo_140.content.m3.b;
|
||||||
|
ssbo_430.content.m4 = ssbo_140.content.m4;
|
||||||
|
ssbo_430.content.m3s[0].c = ssbo_140.content.m3s[0].c;
|
||||||
|
ssbo_430.content.m3s[1].c = ssbo_140.content.m3s[1].c;
|
||||||
|
ssbo_430.content.m3s[2].c = ssbo_140.content.m3s[2].c;
|
||||||
|
ssbo_430.content.m3s[3].c = ssbo_140.content.m3s[3].c;
|
||||||
|
ssbo_430.content.m3s[4].c = ssbo_140.content.m3s[4].c;
|
||||||
|
ssbo_430.content.m3s[5].c = ssbo_140.content.m3s[5].c;
|
||||||
|
ssbo_430.content.m3s[6].c = ssbo_140.content.m3s[6].c;
|
||||||
|
ssbo_430.content.m3s[7].c = ssbo_140.content.m3s[7].c;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
|||||||
|
#version 310 es
|
||||||
|
#extension GL_EXT_scalar_block_layout : require
|
||||||
|
|
||||||
|
layout(local_size_x = 1) in;
|
||||||
|
|
||||||
|
struct S0
|
||||||
|
{
|
||||||
|
vec2 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S1
|
||||||
|
{
|
||||||
|
vec3 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S2
|
||||||
|
{
|
||||||
|
vec3 a[1];
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S3
|
||||||
|
{
|
||||||
|
vec2 a;
|
||||||
|
float b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct S4
|
||||||
|
{
|
||||||
|
vec2 c;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Content
|
||||||
|
{
|
||||||
|
S0 m0s[1];
|
||||||
|
S1 m1s[1];
|
||||||
|
S2 m2s[1];
|
||||||
|
S0 m0;
|
||||||
|
S1 m1;
|
||||||
|
S2 m2;
|
||||||
|
S3 m3;
|
||||||
|
float m4;
|
||||||
|
|
||||||
|
S4 m3s[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(binding = 1, scalar) restrict buffer SSBO1
|
||||||
|
{
|
||||||
|
Content content;
|
||||||
|
Content content1[2];
|
||||||
|
Content content2;
|
||||||
|
|
||||||
|
layout(column_major) mat2 m0;
|
||||||
|
layout(column_major) mat2 m1;
|
||||||
|
layout(column_major) mat2x3 m2[4];
|
||||||
|
layout(column_major) mat3x2 m3;
|
||||||
|
layout(row_major) mat2 m4;
|
||||||
|
layout(row_major) mat2 m5[9];
|
||||||
|
layout(row_major) mat2x3 m6[4][2];
|
||||||
|
layout(row_major) mat3x2 m7;
|
||||||
|
float array[];
|
||||||
|
} ssbo_430;
|
||||||
|
|
||||||
|
layout(binding = 0, std140) restrict buffer SSBO0
|
||||||
|
{
|
||||||
|
Content content;
|
||||||
|
Content content1[2];
|
||||||
|
Content content2;
|
||||||
|
|
||||||
|
layout(column_major) mat2 m0;
|
||||||
|
layout(column_major) mat2 m1;
|
||||||
|
layout(column_major) mat2x3 m2[4];
|
||||||
|
layout(column_major) mat3x2 m3;
|
||||||
|
layout(row_major) mat2 m4;
|
||||||
|
layout(row_major) mat2 m5[9];
|
||||||
|
layout(row_major) mat2x3 m6[4][2];
|
||||||
|
layout(row_major) mat3x2 m7;
|
||||||
|
|
||||||
|
float array[];
|
||||||
|
} ssbo_140;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ssbo_430.content = ssbo_140.content;
|
||||||
|
}
|
||||||
|
|
@ -106,7 +106,9 @@ enum BufferPackingStandard
|
|||||||
BufferPackingStd140EnhancedLayout,
|
BufferPackingStd140EnhancedLayout,
|
||||||
BufferPackingStd430EnhancedLayout,
|
BufferPackingStd430EnhancedLayout,
|
||||||
BufferPackingHLSLCbuffer,
|
BufferPackingHLSLCbuffer,
|
||||||
BufferPackingHLSLCbufferPackOffset
|
BufferPackingHLSLCbufferPackOffset,
|
||||||
|
BufferPackingScalar,
|
||||||
|
BufferPackingScalarEnhancedLayout
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EntryPoint
|
struct EntryPoint
|
||||||
|
128
spirv_glsl.cpp
128
spirv_glsl.cpp
@ -106,6 +106,7 @@ static bool packing_has_flexible_offset(BufferPackingStandard packing)
|
|||||||
{
|
{
|
||||||
case BufferPackingStd140:
|
case BufferPackingStd140:
|
||||||
case BufferPackingStd430:
|
case BufferPackingStd430:
|
||||||
|
case BufferPackingScalar:
|
||||||
case BufferPackingHLSLCbuffer:
|
case BufferPackingHLSLCbuffer:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -114,6 +115,19 @@ static bool packing_has_flexible_offset(BufferPackingStandard packing)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool packing_is_scalar(BufferPackingStandard packing)
|
||||||
|
{
|
||||||
|
switch (packing)
|
||||||
|
{
|
||||||
|
case BufferPackingScalar:
|
||||||
|
case BufferPackingScalarEnhancedLayout:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BufferPackingStandard packing_to_substruct_packing(BufferPackingStandard packing)
|
static BufferPackingStandard packing_to_substruct_packing(BufferPackingStandard packing)
|
||||||
{
|
{
|
||||||
switch (packing)
|
switch (packing)
|
||||||
@ -124,6 +138,8 @@ static BufferPackingStandard packing_to_substruct_packing(BufferPackingStandard
|
|||||||
return BufferPackingStd430;
|
return BufferPackingStd430;
|
||||||
case BufferPackingHLSLCbufferPackOffset:
|
case BufferPackingHLSLCbufferPackOffset:
|
||||||
return BufferPackingHLSLCbuffer;
|
return BufferPackingHLSLCbuffer;
|
||||||
|
case BufferPackingScalarEnhancedLayout:
|
||||||
|
return BufferPackingScalar;
|
||||||
default:
|
default:
|
||||||
return packing;
|
return packing;
|
||||||
}
|
}
|
||||||
@ -1045,6 +1061,10 @@ uint32_t CompilerGLSL::type_to_packed_alignment(const SPIRType &type, const Bits
|
|||||||
{
|
{
|
||||||
const uint32_t base_alignment = type_to_packed_base_size(type, packing);
|
const uint32_t base_alignment = type_to_packed_base_size(type, packing);
|
||||||
|
|
||||||
|
// Alignment requirement for scalar block layout is always the alignment for the most basic component.
|
||||||
|
if (packing_is_scalar(packing))
|
||||||
|
return base_alignment;
|
||||||
|
|
||||||
// Vectors are *not* aligned in HLSL, but there's an extra rule where vectors cannot straddle
|
// Vectors are *not* aligned in HLSL, but there's an extra rule where vectors cannot straddle
|
||||||
// a vec4, this is handled outside since that part knows our current offset.
|
// a vec4, this is handled outside since that part knows our current offset.
|
||||||
if (type.columns == 1 && packing_is_hlsl(packing))
|
if (type.columns == 1 && packing_is_hlsl(packing))
|
||||||
@ -1168,27 +1188,34 @@ uint32_t CompilerGLSL::type_to_packed_size(const SPIRType &type, const Bitset &f
|
|||||||
{
|
{
|
||||||
const uint32_t base_alignment = type_to_packed_base_size(type, packing);
|
const uint32_t base_alignment = type_to_packed_base_size(type, packing);
|
||||||
|
|
||||||
if (type.columns == 1)
|
if (packing_is_scalar(packing))
|
||||||
size = type.vecsize * base_alignment;
|
|
||||||
|
|
||||||
if (flags.get(DecorationColMajor) && type.columns > 1)
|
|
||||||
{
|
{
|
||||||
if (packing_is_vec4_padded(packing))
|
size = type.vecsize * type.columns * base_alignment;
|
||||||
size = type.columns * 4 * base_alignment;
|
|
||||||
else if (type.vecsize == 3)
|
|
||||||
size = type.columns * 4 * base_alignment;
|
|
||||||
else
|
|
||||||
size = type.columns * type.vecsize * base_alignment;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (flags.get(DecorationRowMajor) && type.vecsize > 1)
|
|
||||||
{
|
{
|
||||||
if (packing_is_vec4_padded(packing))
|
if (type.columns == 1)
|
||||||
size = type.vecsize * 4 * base_alignment;
|
size = type.vecsize * base_alignment;
|
||||||
else if (type.columns == 3)
|
|
||||||
size = type.vecsize * 4 * base_alignment;
|
if (flags.get(DecorationColMajor) && type.columns > 1)
|
||||||
else
|
{
|
||||||
size = type.vecsize * type.columns * base_alignment;
|
if (packing_is_vec4_padded(packing))
|
||||||
|
size = type.columns * 4 * base_alignment;
|
||||||
|
else if (type.vecsize == 3)
|
||||||
|
size = type.columns * 4 * base_alignment;
|
||||||
|
else
|
||||||
|
size = type.columns * type.vecsize * base_alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags.get(DecorationRowMajor) && type.vecsize > 1)
|
||||||
|
{
|
||||||
|
if (packing_is_vec4_padded(packing))
|
||||||
|
size = type.vecsize * 4 * base_alignment;
|
||||||
|
else if (type.columns == 3)
|
||||||
|
size = type.vecsize * 4 * base_alignment;
|
||||||
|
else
|
||||||
|
size = type.vecsize * type.columns * base_alignment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,37 +1463,11 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
|
|||||||
// If SPIR-V does not comply with either layout, we cannot really work around it.
|
// If SPIR-V does not comply with either layout, we cannot really work around it.
|
||||||
if (can_use_buffer_blocks && (ubo_block || emulated_ubo))
|
if (can_use_buffer_blocks && (ubo_block || emulated_ubo))
|
||||||
{
|
{
|
||||||
if (buffer_is_packing_standard(type, BufferPackingStd140))
|
attr.push_back(buffer_to_packing_standard(type, false));
|
||||||
attr.push_back("std140");
|
|
||||||
else if (buffer_is_packing_standard(type, BufferPackingStd140EnhancedLayout))
|
|
||||||
{
|
|
||||||
attr.push_back("std140");
|
|
||||||
// Fallback time. We might be able to use the ARB_enhanced_layouts to deal with this difference,
|
|
||||||
// however, we can only use layout(offset) on the block itself, not any substructs, so the substructs better be the appropriate layout.
|
|
||||||
// Enhanced layouts seem to always work in Vulkan GLSL, so no need for extensions there.
|
|
||||||
if (options.es && !options.vulkan_semantics)
|
|
||||||
SPIRV_CROSS_THROW("Uniform buffer block cannot be expressed as std140. ES-targets do "
|
|
||||||
"not support GL_ARB_enhanced_layouts.");
|
|
||||||
if (!options.es && !options.vulkan_semantics && options.version < 440)
|
|
||||||
require_extension_internal("GL_ARB_enhanced_layouts");
|
|
||||||
|
|
||||||
// This is a very last minute to check for this, but use this unused decoration to mark that we should emit
|
|
||||||
// explicit offsets for this block type.
|
|
||||||
// layout_for_variable() will be called before the actual buffer emit.
|
|
||||||
// The alternative is a full pass before codegen where we deduce this decoration,
|
|
||||||
// but then we are just doing the exact same work twice, and more complexity.
|
|
||||||
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SPIRV_CROSS_THROW("Uniform buffer cannot be expressed as std140, even with enhanced layouts. You can try "
|
|
||||||
"flattening this block to "
|
|
||||||
"support a more flexible layout.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (can_use_buffer_blocks && (push_constant_block || ssbo_block))
|
else if (can_use_buffer_blocks && (push_constant_block || ssbo_block))
|
||||||
{
|
{
|
||||||
attr.push_back(buffer_to_packing_standard(type));
|
attr.push_back(buffer_to_packing_standard(type, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// For images, the type itself adds a layout qualifer.
|
// For images, the type itself adds a layout qualifer.
|
||||||
@ -1487,12 +1488,28 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
string CompilerGLSL::buffer_to_packing_standard(const SPIRType &type)
|
string CompilerGLSL::buffer_to_packing_standard(const SPIRType &type, bool check_std430)
|
||||||
{
|
{
|
||||||
if (buffer_is_packing_standard(type, BufferPackingStd430))
|
if (check_std430 && buffer_is_packing_standard(type, BufferPackingStd430))
|
||||||
return "std430";
|
return "std430";
|
||||||
else if (buffer_is_packing_standard(type, BufferPackingStd140))
|
else if (buffer_is_packing_standard(type, BufferPackingStd140))
|
||||||
return "std140";
|
return "std140";
|
||||||
|
else if (options.vulkan_semantics && buffer_is_packing_standard(type, BufferPackingScalar))
|
||||||
|
{
|
||||||
|
require_extension_internal("GL_EXT_scalar_block_layout");
|
||||||
|
return "scalar";
|
||||||
|
}
|
||||||
|
else if (check_std430 && buffer_is_packing_standard(type, BufferPackingStd430EnhancedLayout))
|
||||||
|
{
|
||||||
|
if (options.es && !options.vulkan_semantics)
|
||||||
|
SPIRV_CROSS_THROW("Push constant block cannot be expressed as neither std430 nor std140. ES-targets do "
|
||||||
|
"not support GL_ARB_enhanced_layouts.");
|
||||||
|
if (!options.es && !options.vulkan_semantics && options.version < 440)
|
||||||
|
require_extension_internal("GL_ARB_enhanced_layouts");
|
||||||
|
|
||||||
|
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
|
||||||
|
return "std430";
|
||||||
|
}
|
||||||
else if (buffer_is_packing_standard(type, BufferPackingStd140EnhancedLayout))
|
else if (buffer_is_packing_standard(type, BufferPackingStd140EnhancedLayout))
|
||||||
{
|
{
|
||||||
// Fallback time. We might be able to use the ARB_enhanced_layouts to deal with this difference,
|
// Fallback time. We might be able to use the ARB_enhanced_layouts to deal with this difference,
|
||||||
@ -1507,20 +1524,15 @@ string CompilerGLSL::buffer_to_packing_standard(const SPIRType &type)
|
|||||||
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
|
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
|
||||||
return "std140";
|
return "std140";
|
||||||
}
|
}
|
||||||
else if (buffer_is_packing_standard(type, BufferPackingStd430EnhancedLayout))
|
else if (options.vulkan_semantics && buffer_is_packing_standard(type, BufferPackingScalarEnhancedLayout))
|
||||||
{
|
{
|
||||||
if (options.es && !options.vulkan_semantics)
|
|
||||||
SPIRV_CROSS_THROW("Push constant block cannot be expressed as neither std430 nor std140. ES-targets do "
|
|
||||||
"not support GL_ARB_enhanced_layouts.");
|
|
||||||
if (!options.es && !options.vulkan_semantics && options.version < 440)
|
|
||||||
require_extension_internal("GL_ARB_enhanced_layouts");
|
|
||||||
|
|
||||||
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
|
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
|
||||||
return "std430";
|
require_extension_internal("GL_EXT_scalar_block_layout");
|
||||||
|
return "scalar";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SPIRV_CROSS_THROW("Buffer block cannot be expressed as neither std430 nor std140, even with enhanced "
|
SPIRV_CROSS_THROW("Buffer block cannot be expressed as any of std430, std140, scalar, even with enhanced "
|
||||||
"layouts. You can try flattening this block to support a more flexible layout.");
|
"layouts. You can try flattening this block to support a more flexible layout.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1644,7 +1656,7 @@ void CompilerGLSL::emit_buffer_reference_block(SPIRType &type, bool forward_decl
|
|||||||
if (!forward_declaration)
|
if (!forward_declaration)
|
||||||
{
|
{
|
||||||
if (type.basetype == SPIRType::Struct)
|
if (type.basetype == SPIRType::Struct)
|
||||||
statement("layout(buffer_reference, ", buffer_to_packing_standard(type), ") buffer ", buffer_name);
|
statement("layout(buffer_reference, ", buffer_to_packing_standard(type, true), ") buffer ", buffer_name);
|
||||||
else
|
else
|
||||||
statement("layout(buffer_reference) buffer ", buffer_name);
|
statement("layout(buffer_reference) buffer ", buffer_name);
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ protected:
|
|||||||
|
|
||||||
bool buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing, uint32_t start_offset = 0,
|
bool buffer_is_packing_standard(const SPIRType &type, BufferPackingStandard packing, uint32_t start_offset = 0,
|
||||||
uint32_t end_offset = ~(0u));
|
uint32_t end_offset = ~(0u));
|
||||||
std::string buffer_to_packing_standard(const SPIRType &type);
|
std::string buffer_to_packing_standard(const SPIRType &type, bool enable_std430);
|
||||||
|
|
||||||
uint32_t type_to_packed_base_size(const SPIRType &type, BufferPackingStandard packing);
|
uint32_t type_to_packed_base_size(const SPIRType &type, BufferPackingStandard packing);
|
||||||
uint32_t type_to_packed_alignment(const SPIRType &type, const Bitset &flags, BufferPackingStandard packing);
|
uint32_t type_to_packed_alignment(const SPIRType &type, const Bitset &flags, BufferPackingStandard packing);
|
||||||
|
Loading…
Reference in New Issue
Block a user