Implement GL_EXT_scalar_block_layout
This commit is contained in:
parent
7274bbc27c
commit
7da39ed968
@ -3459,6 +3459,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
|
|||||||
switch (type.getQualifier().layoutPacking) {
|
switch (type.getQualifier().layoutPacking) {
|
||||||
case glslang::ElpStd140:
|
case glslang::ElpStd140:
|
||||||
case glslang::ElpStd430:
|
case glslang::ElpStd430:
|
||||||
|
case glslang::ElpScalar:
|
||||||
return type.getQualifier().layoutPacking;
|
return type.getQualifier().layoutPacking;
|
||||||
default:
|
default:
|
||||||
return glslang::ElpNone;
|
return glslang::ElpNone;
|
||||||
@ -3470,7 +3471,7 @@ int TGlslangToSpvTraverser::getArrayStride(const glslang::TType& arrayType, glsl
|
|||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
int stride;
|
int stride;
|
||||||
glslangIntermediate->getBaseAlignment(arrayType, size, stride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
glslangIntermediate->getMemberAlignment(arrayType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
|
||||||
|
|
||||||
return stride;
|
return stride;
|
||||||
}
|
}
|
||||||
@ -3485,7 +3486,7 @@ int TGlslangToSpvTraverser::getMatrixStride(const glslang::TType& matrixType, gl
|
|||||||
|
|
||||||
int size;
|
int size;
|
||||||
int stride;
|
int stride;
|
||||||
glslangIntermediate->getBaseAlignment(elementType, size, stride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
glslangIntermediate->getMemberAlignment(elementType, size, stride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
|
||||||
|
|
||||||
return stride;
|
return stride;
|
||||||
}
|
}
|
||||||
@ -3527,7 +3528,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
|
|||||||
|
|
||||||
int memberSize;
|
int memberSize;
|
||||||
int dummyStride;
|
int dummyStride;
|
||||||
int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, dummyStride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
|
int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, matrixLayout == glslang::ElmRowMajor);
|
||||||
|
|
||||||
// Adjust alignment for HLSL rules
|
// Adjust alignment for HLSL rules
|
||||||
// TODO: make this consistent in early phases of code:
|
// TODO: make this consistent in early phases of code:
|
||||||
@ -3546,7 +3547,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
|
|||||||
glslang::RoundToPow2(currentOffset, memberAlignment);
|
glslang::RoundToPow2(currentOffset, memberAlignment);
|
||||||
|
|
||||||
// Bump up to vec4 if there is a bad straddle
|
// Bump up to vec4 if there is a bad straddle
|
||||||
if (glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset))
|
if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset))
|
||||||
glslang::RoundToPow2(currentOffset, 16);
|
glslang::RoundToPow2(currentOffset, 16);
|
||||||
|
|
||||||
nextOffset = currentOffset + memberSize;
|
nextOffset = currentOffset + memberSize;
|
||||||
|
@ -39,7 +39,7 @@ ERROR: 0:168: 'Binst' : cannot add storage, auxiliary, memory, interpolation, la
|
|||||||
ERROR: 0:169: 'Bblock' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable
|
ERROR: 0:169: 'Bblock' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable
|
||||||
ERROR: 0:170: 'Bfoo' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable
|
ERROR: 0:170: 'Bfoo' : cannot add storage, auxiliary, memory, interpolation, layout, or precision qualifier to an existing variable
|
||||||
ERROR: 0:172: 'std430' : not supported for this version or the enabled extensions
|
ERROR: 0:172: 'std430' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:172: 'std430' : requires the 'buffer' storage qualifier
|
ERROR: 0:172: 'std430 requires the buffer storage qualifier' : required extension not requested: GL_EXT_scalar_block_layout
|
||||||
ERROR: 0:175: '' : array size required
|
ERROR: 0:175: '' : array size required
|
||||||
ERROR: 0:185: 'assign' : cannot convert from ' temp 4-element array of highp float' to ' temp 3-element array of highp float'
|
ERROR: 0:185: 'assign' : cannot convert from ' temp 4-element array of highp float' to ' temp 3-element array of highp float'
|
||||||
ERROR: 0:186: 'assign' : cannot convert from ' temp 3-element array of highp float' to ' temp 4-element array of highp float'
|
ERROR: 0:186: 'assign' : cannot convert from ' temp 3-element array of highp float' to ' temp 4-element array of highp float'
|
||||||
|
@ -15,7 +15,7 @@ ERROR: 0:78: 'vertex-shader array-of-struct output' : not supported with this pr
|
|||||||
ERROR: 0:79: 'vertex-shader array-of-struct output' : not supported with this profile: es
|
ERROR: 0:79: 'vertex-shader array-of-struct output' : not supported with this profile: es
|
||||||
ERROR: 0:81: 'vertex-shader struct output containing an array' : not supported with this profile: es
|
ERROR: 0:81: 'vertex-shader struct output containing an array' : not supported with this profile: es
|
||||||
ERROR: 0:83: 'vertex-shader struct output containing structure' : not supported with this profile: es
|
ERROR: 0:83: 'vertex-shader struct output containing structure' : not supported with this profile: es
|
||||||
ERROR: 0:85: 'std430' : requires the 'buffer' storage qualifier
|
ERROR: 0:85: 'std430 requires the buffer storage qualifier' : required extension not requested: GL_EXT_scalar_block_layout
|
||||||
ERROR: 0:97: 's' : member of block cannot be or contain a sampler, image, or atomic_uint type
|
ERROR: 0:97: 's' : member of block cannot be or contain a sampler, image, or atomic_uint type
|
||||||
ERROR: 0:105: 'location' : overlapping use of location 12
|
ERROR: 0:105: 'location' : overlapping use of location 12
|
||||||
ERROR: 0:107: 'input block' : not supported in this stage: vertex
|
ERROR: 0:107: 'input block' : not supported in this stage: vertex
|
||||||
|
@ -46,7 +46,7 @@ ERROR: 0:142: 'r8_snorm' : does not apply to signed integer images
|
|||||||
ERROR: 0:143: 'rgba32ui' : does not apply to signed integer images
|
ERROR: 0:143: 'rgba32ui' : does not apply to signed integer images
|
||||||
ERROR: 0:144: 'r8ui' : does not apply to signed integer images
|
ERROR: 0:144: 'r8ui' : does not apply to signed integer images
|
||||||
ERROR: 0:147: 'offset on block member' : not supported for this version or the enabled extensions
|
ERROR: 0:147: 'offset on block member' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:147: 'offset/align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:147: 'offset/align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:157: 'textureQueryLevels' : no matching overloaded function found
|
ERROR: 0:157: 'textureQueryLevels' : no matching overloaded function found
|
||||||
ERROR: 0:157: 'assign' : cannot convert from ' const float' to ' temp int'
|
ERROR: 0:157: 'assign' : cannot convert from ' const float' to ' temp int'
|
||||||
ERROR: 0:158: 'textureQueryLevels' : no matching overloaded function found
|
ERROR: 0:158: 'textureQueryLevels' : no matching overloaded function found
|
||||||
|
@ -27,9 +27,9 @@ ERROR: 0:64: 'uniform buffer-member align' : not supported for this version or t
|
|||||||
ERROR: 0:65: 'uniform buffer-member align' : not supported for this version or the enabled extensions
|
ERROR: 0:65: 'uniform buffer-member align' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:65: 'offset on block member' : not supported for this version or the enabled extensions
|
ERROR: 0:65: 'offset on block member' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:66: 'offset on block member' : not supported for this version or the enabled extensions
|
ERROR: 0:66: 'offset on block member' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:64: 'align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:64: 'align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:65: 'offset/align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:65: 'offset/align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:66: 'offset/align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:66: 'offset/align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:71: 'offset on block member' : not supported for this version or the enabled extensions
|
ERROR: 0:71: 'offset on block member' : not supported for this version or the enabled extensions
|
||||||
ERROR: 0:74: 'gl_MaxTransformFeedbackBuffers' : required extension not requested: GL_ARB_enhanced_layouts
|
ERROR: 0:74: 'gl_MaxTransformFeedbackBuffers' : required extension not requested: GL_ARB_enhanced_layouts
|
||||||
ERROR: 0:75: 'gl_MaxTransformFeedbackInterleavedComponents' : required extension not requested: GL_ARB_enhanced_layouts
|
ERROR: 0:75: 'gl_MaxTransformFeedbackInterleavedComponents' : required extension not requested: GL_ARB_enhanced_layouts
|
||||||
|
@ -21,11 +21,11 @@ ERROR: 0:38: 'offset' : only applies to block members, not blocks
|
|||||||
ERROR: 0:39: 'output block' : not supported in this stage: fragment
|
ERROR: 0:39: 'output block' : not supported in this stage: fragment
|
||||||
ERROR: 0:39: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:39: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
ERROR: 0:39: 'offset' : only applies to block members, not blocks
|
ERROR: 0:39: 'offset' : only applies to block members, not blocks
|
||||||
ERROR: 0:42: 'align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:42: 'align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:43: 'align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:43: 'align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:43: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:43: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
ERROR: 0:44: 'output block' : not supported in this stage: fragment
|
ERROR: 0:44: 'output block' : not supported in this stage: fragment
|
||||||
ERROR: 0:44: 'align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:44: 'align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:44: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:44: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
ERROR: 0:46: 'offset' : cannot specify on a variable declaration
|
ERROR: 0:46: 'offset' : cannot specify on a variable declaration
|
||||||
ERROR: 0:47: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:47: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
@ -36,9 +36,9 @@ ERROR: 0:52: 'layout' : offset/align can only be used on a uniform or buffer
|
|||||||
ERROR: 0:54: 'layout' : matrix or packing qualifiers can only be used on a uniform or buffer
|
ERROR: 0:54: 'layout' : matrix or packing qualifiers can only be used on a uniform or buffer
|
||||||
ERROR: 0:55: 'layout' : cannot specify packing on a variable declaration
|
ERROR: 0:55: 'layout' : cannot specify packing on a variable declaration
|
||||||
ERROR: 0:57: 'align' : must be a power of 2
|
ERROR: 0:57: 'align' : must be a power of 2
|
||||||
ERROR: 0:58: 'offset/align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:58: 'offset/align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:62: 'offset/align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:62: 'offset/align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:63: 'offset/align' : can only be used with std140 or std430 layout packing
|
ERROR: 0:63: 'offset/align' : can only be used with std140, std430, or scalar layout packing
|
||||||
ERROR: 0:62: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:62: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
ERROR: 0:63: 'layout' : offset/align can only be used on a uniform or buffer
|
ERROR: 0:63: 'layout' : offset/align can only be used on a uniform or buffer
|
||||||
ERROR: 0:84: 'align' : must be a power of 2
|
ERROR: 0:84: 'align' : must be a power of 2
|
||||||
|
80
Test/baseResults/spv.scalarlayout.frag.out
Normal file
80
Test/baseResults/spv.scalarlayout.frag.out
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
spv.scalarlayout.frag
|
||||||
|
error: SPIRV-Tools Validation Errors
|
||||||
|
error: Structure id 17 decorated as Block for variable in Uniform storage class must follow standard uniform buffer layout rules: member 1 at offset 4 is not aligned to 8
|
||||||
|
%B1 = OpTypeStruct %float %v2float %v3float %_arr_float_uint_2 %mat2v3float %_arr_mat2v3float_uint_2 %float %S %_arr_S_uint_2
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80007
|
||||||
|
// Id's are bound by 20
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
Capability Float64
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "main"
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source GLSL 450
|
||||||
|
SourceExtension "GL_EXT_scalar_block_layout"
|
||||||
|
Name 4 "main"
|
||||||
|
Name 15 "S"
|
||||||
|
MemberName 15(S) 0 "a"
|
||||||
|
MemberName 15(S) 1 "b"
|
||||||
|
MemberName 15(S) 2 "c"
|
||||||
|
MemberName 15(S) 3 "d"
|
||||||
|
MemberName 15(S) 4 "e"
|
||||||
|
MemberName 15(S) 5 "f"
|
||||||
|
Name 17 "B1"
|
||||||
|
MemberName 17(B1) 0 "a"
|
||||||
|
MemberName 17(B1) 1 "b"
|
||||||
|
MemberName 17(B1) 2 "c"
|
||||||
|
MemberName 17(B1) 3 "d"
|
||||||
|
MemberName 17(B1) 4 "e"
|
||||||
|
MemberName 17(B1) 5 "f"
|
||||||
|
MemberName 17(B1) 6 "g"
|
||||||
|
MemberName 17(B1) 7 "h"
|
||||||
|
MemberName 17(B1) 8 "i"
|
||||||
|
Name 19 ""
|
||||||
|
Decorate 11 ArrayStride 4
|
||||||
|
Decorate 13 ArrayStride 24
|
||||||
|
MemberDecorate 15(S) 0 Offset 0
|
||||||
|
MemberDecorate 15(S) 1 Offset 4
|
||||||
|
MemberDecorate 15(S) 2 Offset 16
|
||||||
|
MemberDecorate 15(S) 3 Offset 24
|
||||||
|
MemberDecorate 15(S) 4 Offset 28
|
||||||
|
MemberDecorate 15(S) 5 Offset 40
|
||||||
|
Decorate 16 ArrayStride 48
|
||||||
|
MemberDecorate 17(B1) 0 Offset 0
|
||||||
|
MemberDecorate 17(B1) 1 Offset 4
|
||||||
|
MemberDecorate 17(B1) 2 Offset 12
|
||||||
|
MemberDecorate 17(B1) 3 Offset 24
|
||||||
|
MemberDecorate 17(B1) 4 ColMajor
|
||||||
|
MemberDecorate 17(B1) 4 Offset 32
|
||||||
|
MemberDecorate 17(B1) 4 MatrixStride 12
|
||||||
|
MemberDecorate 17(B1) 5 ColMajor
|
||||||
|
MemberDecorate 17(B1) 5 Offset 56
|
||||||
|
MemberDecorate 17(B1) 5 MatrixStride 12
|
||||||
|
MemberDecorate 17(B1) 6 Offset 104
|
||||||
|
MemberDecorate 17(B1) 7 Offset 112
|
||||||
|
MemberDecorate 17(B1) 8 Offset 160
|
||||||
|
Decorate 17(B1) Block
|
||||||
|
Decorate 19 DescriptorSet 0
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeFloat 32
|
||||||
|
7: TypeVector 6(float) 2
|
||||||
|
8: TypeVector 6(float) 3
|
||||||
|
9: TypeInt 32 0
|
||||||
|
10: 9(int) Constant 2
|
||||||
|
11: TypeArray 6(float) 10
|
||||||
|
12: TypeMatrix 8(fvec3) 2
|
||||||
|
13: TypeArray 12 10
|
||||||
|
14: TypeFloat 64
|
||||||
|
15(S): TypeStruct 6(float) 7(fvec2) 14(float64_t) 6(float) 8(fvec3) 6(float)
|
||||||
|
16: TypeArray 15(S) 10
|
||||||
|
17(B1): TypeStruct 6(float) 7(fvec2) 8(fvec3) 11 12 13 6(float) 15(S) 16
|
||||||
|
18: TypePointer Uniform 17(B1)
|
||||||
|
19: 18(ptr) Variable Uniform
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
72
Test/baseResults/spv.scalarlayoutfloat16.frag.out
Normal file
72
Test/baseResults/spv.scalarlayoutfloat16.frag.out
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
spv.scalarlayoutfloat16.frag
|
||||||
|
error: SPIRV-Tools Validation Errors
|
||||||
|
error: Structure id 15 decorated as Block for variable in Uniform storage class must follow standard uniform buffer layout rules: member 1 at offset 2 is not aligned to 4
|
||||||
|
%B1 = OpTypeStruct %half %v2half %v3half %_arr_half_uint_2 %half %S %_arr_S_uint_2
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80007
|
||||||
|
// Id's are bound by 18
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
Capability Float64
|
||||||
|
Capability StorageUniform16
|
||||||
|
Extension "SPV_KHR_16bit_storage"
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "main"
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source GLSL 450
|
||||||
|
SourceExtension "GL_EXT_scalar_block_layout"
|
||||||
|
SourceExtension "GL_EXT_shader_16bit_storage"
|
||||||
|
Name 4 "main"
|
||||||
|
Name 13 "S"
|
||||||
|
MemberName 13(S) 0 "a"
|
||||||
|
MemberName 13(S) 1 "b"
|
||||||
|
MemberName 13(S) 2 "c"
|
||||||
|
MemberName 13(S) 3 "d"
|
||||||
|
MemberName 13(S) 4 "e"
|
||||||
|
MemberName 13(S) 5 "f"
|
||||||
|
Name 15 "B1"
|
||||||
|
MemberName 15(B1) 0 "a"
|
||||||
|
MemberName 15(B1) 1 "b"
|
||||||
|
MemberName 15(B1) 2 "c"
|
||||||
|
MemberName 15(B1) 3 "d"
|
||||||
|
MemberName 15(B1) 4 "g"
|
||||||
|
MemberName 15(B1) 5 "h"
|
||||||
|
MemberName 15(B1) 6 "i"
|
||||||
|
Name 17 ""
|
||||||
|
Decorate 11 ArrayStride 2
|
||||||
|
MemberDecorate 13(S) 0 Offset 0
|
||||||
|
MemberDecorate 13(S) 1 Offset 2
|
||||||
|
MemberDecorate 13(S) 2 Offset 8
|
||||||
|
MemberDecorate 13(S) 3 Offset 16
|
||||||
|
MemberDecorate 13(S) 4 Offset 18
|
||||||
|
MemberDecorate 13(S) 5 Offset 24
|
||||||
|
Decorate 14 ArrayStride 32
|
||||||
|
MemberDecorate 15(B1) 0 Offset 0
|
||||||
|
MemberDecorate 15(B1) 1 Offset 2
|
||||||
|
MemberDecorate 15(B1) 2 Offset 6
|
||||||
|
MemberDecorate 15(B1) 3 Offset 12
|
||||||
|
MemberDecorate 15(B1) 4 Offset 16
|
||||||
|
MemberDecorate 15(B1) 5 Offset 24
|
||||||
|
MemberDecorate 15(B1) 6 Offset 56
|
||||||
|
Decorate 15(B1) Block
|
||||||
|
Decorate 17 DescriptorSet 0
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeFloat 16
|
||||||
|
7: TypeVector 6(float16_t) 2
|
||||||
|
8: TypeVector 6(float16_t) 3
|
||||||
|
9: TypeInt 32 0
|
||||||
|
10: 9(int) Constant 2
|
||||||
|
11: TypeArray 6(float16_t) 10
|
||||||
|
12: TypeFloat 64
|
||||||
|
13(S): TypeStruct 6(float16_t) 7(f16vec2) 12(float64_t) 6(float16_t) 8(f16vec3) 6(float16_t)
|
||||||
|
14: TypeArray 13(S) 10
|
||||||
|
15(B1): TypeStruct 6(float16_t) 7(f16vec2) 8(f16vec3) 11 6(float16_t) 13(S) 14
|
||||||
|
16: TypePointer Uniform 15(B1)
|
||||||
|
17: 16(ptr) Variable Uniform
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
32
Test/spv.scalarlayout.frag
Normal file
32
Test/spv.scalarlayout.frag
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#version 450 core
|
||||||
|
|
||||||
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
// Block memory layout
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
float a; // offset 0
|
||||||
|
vec2 b; // offset 4
|
||||||
|
double c; // offset 16
|
||||||
|
float d; // offset 24
|
||||||
|
vec3 e; // offset 28
|
||||||
|
float f; // offset 40
|
||||||
|
// size = 44, align = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(column_major, scalar) uniform B1
|
||||||
|
{
|
||||||
|
float a; // offset = 0
|
||||||
|
vec2 b; // offset = 4
|
||||||
|
vec3 c; // offset = 12
|
||||||
|
float d[2]; // offset = 24
|
||||||
|
mat2x3 e; // offset = 32, takes 24 bytes, matrixstride = 12
|
||||||
|
mat2x3 f[2]; // offset = 56, takes 48 bytes, matrixstride = 12, arraystride = 24
|
||||||
|
float g; // offset = 104
|
||||||
|
S h; // offset = 112 (aligned to multiple of 8)
|
||||||
|
S i[2]; // offset = 160 (aligned to multiple of 8) stride = 48
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
}
|
31
Test/spv.scalarlayoutfloat16.frag
Normal file
31
Test/spv.scalarlayoutfloat16.frag
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#version 450 core
|
||||||
|
|
||||||
|
#extension GL_EXT_shader_16bit_storage: enable
|
||||||
|
#extension GL_EXT_scalar_block_layout : enable
|
||||||
|
|
||||||
|
// Block memory layout
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
float16_t a; // offset 0
|
||||||
|
f16vec2 b; // offset 2
|
||||||
|
double c; // offset 8
|
||||||
|
float16_t d; // offset 16
|
||||||
|
f16vec3 e; // offset 18
|
||||||
|
float16_t f; // offset 24
|
||||||
|
// size = 26, align = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(column_major, scalar) uniform B1
|
||||||
|
{
|
||||||
|
float16_t a; // offset = 0
|
||||||
|
f16vec2 b; // offset = 2
|
||||||
|
f16vec3 c; // offset = 6
|
||||||
|
float16_t d[2]; // offset = 12 stride = 2
|
||||||
|
float16_t g; // offset = 16
|
||||||
|
S h; // offset = 24 (aligned to multiple of 8)
|
||||||
|
S i[2]; // offset = 56 (aligned to multiple of 8) stride = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
}
|
@ -277,6 +277,7 @@ enum TLayoutPacking {
|
|||||||
ElpStd140,
|
ElpStd140,
|
||||||
ElpStd430,
|
ElpStd430,
|
||||||
ElpPacked,
|
ElpPacked,
|
||||||
|
ElpScalar,
|
||||||
ElpCount // If expanding, see bitfield width below
|
ElpCount // If expanding, see bitfield width below
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -951,6 +952,7 @@ public:
|
|||||||
case ElpShared: return "shared";
|
case ElpShared: return "shared";
|
||||||
case ElpStd140: return "std140";
|
case ElpStd140: return "std140";
|
||||||
case ElpStd430: return "std430";
|
case ElpStd430: return "std430";
|
||||||
|
case ElpScalar: return "scalar";
|
||||||
default: return "none";
|
default: return "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4611,6 +4611,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
|
|||||||
publicType.qualifier.layoutPacking = ElpStd430;
|
publicType.qualifier.layoutPacking = ElpStd430;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (id == TQualifier::getLayoutPackingString(ElpScalar)) {
|
||||||
|
requireVulkan(loc, "scalar");
|
||||||
|
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "scalar block layout");
|
||||||
|
publicType.qualifier.layoutPacking = ElpScalar;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// TODO: compile-time performance: may need to stop doing linear searches
|
// TODO: compile-time performance: may need to stop doing linear searches
|
||||||
for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
|
for (TLayoutFormat format = (TLayoutFormat)(ElfNone + 1); format < ElfCount; format = (TLayoutFormat)(format + 1)) {
|
||||||
if (id == TQualifier::getLayoutFormatString(format)) {
|
if (id == TQualifier::getLayoutFormatString(format)) {
|
||||||
@ -6784,8 +6790,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
|
|
||||||
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
||||||
if (currentBlockQualifier.hasAlign()) {
|
if (currentBlockQualifier.hasAlign()) {
|
||||||
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430) {
|
if (defaultQualification.layoutPacking != ElpStd140 &&
|
||||||
error(loc, "can only be used with std140 or std430 layout packing", "align", "");
|
defaultQualification.layoutPacking != ElpStd430 &&
|
||||||
|
defaultQualification.layoutPacking != ElpScalar) {
|
||||||
|
error(loc, "can only be used with std140, std430, or scalar layout packing", "align", "");
|
||||||
defaultQualification.layoutAlign = -1;
|
defaultQualification.layoutAlign = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6834,8 +6842,10 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
// "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
|
// "The offset qualifier can only be used on block members of blocks declared with std140 or std430 layouts."
|
||||||
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
// "The align qualifier can only be used on blocks or block members, and only for blocks declared with std140 or std430 layouts."
|
||||||
if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
|
if (memberQualifier.hasAlign() || memberQualifier.hasOffset()) {
|
||||||
if (defaultQualification.layoutPacking != ElpStd140 && defaultQualification.layoutPacking != ElpStd430)
|
if (defaultQualification.layoutPacking != ElpStd140 &&
|
||||||
error(memberLoc, "can only be used with std140 or std430 layout packing", "offset/align", "");
|
defaultQualification.layoutPacking != ElpStd430 &&
|
||||||
|
defaultQualification.layoutPacking != ElpScalar)
|
||||||
|
error(memberLoc, "can only be used with std140, std430, or scalar layout packing", "offset/align", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
@ -6946,7 +6956,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
|
|||||||
profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
|
profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
|
||||||
profileRequires(loc, ENoProfile, 140, nullptr, "uniform block");
|
profileRequires(loc, ENoProfile, 140, nullptr, "uniform block");
|
||||||
if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.layoutPushConstant)
|
if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.layoutPushConstant)
|
||||||
error(loc, "requires the 'buffer' storage qualifier", "std430", "");
|
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier");
|
||||||
break;
|
break;
|
||||||
case EvqBuffer:
|
case EvqBuffer:
|
||||||
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
|
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
|
||||||
@ -7145,7 +7155,7 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
|||||||
{
|
{
|
||||||
if (!qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory())
|
if (!qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory())
|
||||||
return;
|
return;
|
||||||
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430)
|
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@ -7159,8 +7169,8 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
|
|||||||
// modify just the children's view of matrix layout, if there is one for this member
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
|
TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
|
||||||
int dummyStride;
|
int dummyStride;
|
||||||
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking == ElpStd140,
|
int memberAlignment = intermediate.getMemberAlignment(*typeList[member].type, memberSize, dummyStride, qualifier.layoutPacking,
|
||||||
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
|
subMatrixLayout != ElmNone ? subMatrixLayout == ElmRowMajor : qualifier.layoutMatrix == ElmRowMajor);
|
||||||
if (memberQualifier.hasOffset()) {
|
if (memberQualifier.hasOffset()) {
|
||||||
// "The specified offset must be a multiple
|
// "The specified offset must be a multiple
|
||||||
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||||
|
@ -204,6 +204,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
|
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
|
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
|
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_scalar_block_layout] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
||||||
@ -378,6 +379,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_EXT_shader_16bit_storage 1\n"
|
"#define GL_EXT_shader_16bit_storage 1\n"
|
||||||
"#define GL_EXT_shader_8bit_storage 1\n"
|
"#define GL_EXT_shader_8bit_storage 1\n"
|
||||||
"#define GL_EXT_samplerless_texture_functions 1\n"
|
"#define GL_EXT_samplerless_texture_functions 1\n"
|
||||||
|
"#define GL_EXT_scalar_block_layout 1\n"
|
||||||
|
|
||||||
// GL_KHR_shader_subgroup
|
// GL_KHR_shader_subgroup
|
||||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
"#define GL_KHR_shader_subgroup_basic 1\n"
|
||||||
|
@ -166,6 +166,7 @@ const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth
|
|||||||
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
||||||
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
|
const char* const E_GL_EXT_nonuniform_qualifier = "GL_EXT_nonuniform_qualifier";
|
||||||
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
|
const char* const E_GL_EXT_samplerless_texture_functions = "GL_EXT_samplerless_texture_functions";
|
||||||
|
const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_block_layout";
|
||||||
|
|
||||||
// Arrays of extensions for the above viewportEXTs duplications
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
|
@ -1372,10 +1372,11 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
|||||||
// stride comes from the flattening down to vectors.
|
// stride comes from the flattening down to vectors.
|
||||||
//
|
//
|
||||||
// Return value is the alignment of the type.
|
// Return value is the alignment of the type.
|
||||||
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, bool std140, bool rowMajor)
|
int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor)
|
||||||
{
|
{
|
||||||
int alignment;
|
int alignment;
|
||||||
|
|
||||||
|
bool std140 = layoutPacking == glslang::ElpStd140;
|
||||||
// When using the std140 storage layout, structures will be laid out in buffer
|
// When using the std140 storage layout, structures will be laid out in buffer
|
||||||
// storage with its members stored in monotonically increasing order based on their
|
// storage with its members stored in monotonically increasing order based on their
|
||||||
// location in the declaration. A structure and each structure member have a base
|
// location in the declaration. A structure and each structure member have a base
|
||||||
@ -1439,7 +1440,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
|||||||
if (type.isArray()) {
|
if (type.isArray()) {
|
||||||
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this might be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
TType derefType(type, 0);
|
TType derefType(type, 0);
|
||||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor);
|
||||||
if (std140)
|
if (std140)
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
RoundToPow2(size, alignment);
|
RoundToPow2(size, alignment);
|
||||||
@ -1459,7 +1460,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
|||||||
int memberSize;
|
int memberSize;
|
||||||
// modify just the children's view of matrix layout, if there is one for this member
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
||||||
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, std140,
|
int memberAlignment = getBaseAlignment(*memberList[m].type, memberSize, dummyStride, layoutPacking,
|
||||||
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||||
maxAlignment = std::max(maxAlignment, memberAlignment);
|
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||||
RoundToPow2(size, memberAlignment);
|
RoundToPow2(size, memberAlignment);
|
||||||
@ -1498,7 +1499,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, b
|
|||||||
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
// rule 5: deref to row, not to column, meaning the size of vector is num columns instead of num rows
|
||||||
TType derefType(type, 0, rowMajor);
|
TType derefType(type, 0, rowMajor);
|
||||||
|
|
||||||
alignment = getBaseAlignment(derefType, size, dummyStride, std140, rowMajor);
|
alignment = getBaseAlignment(derefType, size, dummyStride, layoutPacking, rowMajor);
|
||||||
if (std140)
|
if (std140)
|
||||||
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
alignment = std::max(baseAlignmentVec4Std140, alignment);
|
||||||
RoundToPow2(size, alignment);
|
RoundToPow2(size, alignment);
|
||||||
@ -1526,4 +1527,79 @@ bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
|
|||||||
: offset % 16 != 0;
|
: offset % 16 != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride, bool rowMajor)
|
||||||
|
{
|
||||||
|
int alignment;
|
||||||
|
|
||||||
|
stride = 0;
|
||||||
|
int dummyStride;
|
||||||
|
|
||||||
|
if (type.isArray()) {
|
||||||
|
TType derefType(type, 0);
|
||||||
|
alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor);
|
||||||
|
|
||||||
|
stride = size;
|
||||||
|
RoundToPow2(stride, alignment);
|
||||||
|
|
||||||
|
size = stride * (type.getOuterArraySize() - 1) + size;
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.getBasicType() == EbtStruct) {
|
||||||
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
int maxAlignment = 0;
|
||||||
|
for (size_t m = 0; m < memberList.size(); ++m) {
|
||||||
|
int memberSize;
|
||||||
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
|
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
||||||
|
int memberAlignment = getScalarAlignment(*memberList[m].type, memberSize, dummyStride,
|
||||||
|
(subMatrixLayout != ElmNone) ? (subMatrixLayout == ElmRowMajor) : rowMajor);
|
||||||
|
maxAlignment = std::max(maxAlignment, memberAlignment);
|
||||||
|
RoundToPow2(size, memberAlignment);
|
||||||
|
size += memberSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.isScalar())
|
||||||
|
return getBaseAlignmentScalar(type, size);
|
||||||
|
|
||||||
|
if (type.isVector()) {
|
||||||
|
int scalarAlign = getBaseAlignmentScalar(type, size);
|
||||||
|
|
||||||
|
size *= type.getVectorSize();
|
||||||
|
return scalarAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.isMatrix()) {
|
||||||
|
TType derefType(type, 0, rowMajor);
|
||||||
|
|
||||||
|
alignment = getScalarAlignment(derefType, size, dummyStride, rowMajor);
|
||||||
|
|
||||||
|
stride = size; // use intra-matrix stride for stride of a just a matrix
|
||||||
|
if (rowMajor)
|
||||||
|
size = stride * type.getMatrixRows();
|
||||||
|
else
|
||||||
|
size = stride * type.getMatrixCols();
|
||||||
|
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0); // all cases should be covered above
|
||||||
|
size = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TIntermediate::getMemberAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor)
|
||||||
|
{
|
||||||
|
if (layoutPacking == glslang::ElpScalar) {
|
||||||
|
return getScalarAlignment(type, size, stride, rowMajor);
|
||||||
|
} else {
|
||||||
|
return getBaseAlignment(type, size, stride, layoutPacking, rowMajor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
@ -634,7 +634,9 @@ public:
|
|||||||
int addXfbBufferOffset(const TType&);
|
int addXfbBufferOffset(const TType&);
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
|
||||||
static int getBaseAlignmentScalar(const TType&, int& size);
|
static int getBaseAlignmentScalar(const TType&, int& size);
|
||||||
static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
|
static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||||
|
static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
|
||||||
|
static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||||
static bool improperStraddle(const TType& type, int size, int offset);
|
static bool improperStraddle(const TType& type, int size, int offset);
|
||||||
bool promote(TIntermOperator*);
|
bool promote(TIntermOperator*);
|
||||||
|
|
||||||
|
@ -131,11 +131,11 @@ public:
|
|||||||
for (int m = 0; m <= index; ++m) {
|
for (int m = 0; m <= index; ++m) {
|
||||||
// modify just the children's view of matrix layout, if there is one for this member
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
TLayoutMatrix subMatrixLayout = memberList[m].type->getQualifier().layoutMatrix;
|
||||||
int memberAlignment = intermediate.getBaseAlignment(*memberList[m].type, memberSize, dummyStride,
|
int memberAlignment = intermediate.getMemberAlignment(*memberList[m].type, memberSize, dummyStride,
|
||||||
type.getQualifier().layoutPacking == ElpStd140,
|
type.getQualifier().layoutPacking,
|
||||||
subMatrixLayout != ElmNone
|
subMatrixLayout != ElmNone
|
||||||
? subMatrixLayout == ElmRowMajor
|
? subMatrixLayout == ElmRowMajor
|
||||||
: type.getQualifier().layoutMatrix == ElmRowMajor);
|
: type.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
RoundToPow2(offset, memberAlignment);
|
RoundToPow2(offset, memberAlignment);
|
||||||
if (m < index)
|
if (m < index)
|
||||||
offset += memberSize;
|
offset += memberSize;
|
||||||
@ -154,9 +154,9 @@ public:
|
|||||||
|
|
||||||
int lastMemberSize;
|
int lastMemberSize;
|
||||||
int dummyStride;
|
int dummyStride;
|
||||||
intermediate.getBaseAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride,
|
intermediate.getMemberAlignment(*memberList[lastIndex].type, lastMemberSize, dummyStride,
|
||||||
blockType.getQualifier().layoutPacking == ElpStd140,
|
blockType.getQualifier().layoutPacking,
|
||||||
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
blockType.getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
|
|
||||||
return lastOffset + lastMemberSize;
|
return lastOffset + lastMemberSize;
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,8 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
"spv.sampleId.frag",
|
"spv.sampleId.frag",
|
||||||
"spv.samplePosition.frag",
|
"spv.samplePosition.frag",
|
||||||
"spv.sampleMaskOverrideCoverage.frag",
|
"spv.sampleMaskOverrideCoverage.frag",
|
||||||
|
"spv.scalarlayout.frag",
|
||||||
|
"spv.scalarlayoutfloat16.frag",
|
||||||
"spv.shaderBallot.comp",
|
"spv.shaderBallot.comp",
|
||||||
"spv.shaderDrawParams.vert",
|
"spv.shaderDrawParams.vert",
|
||||||
"spv.shaderGroupVote.comp",
|
"spv.shaderGroupVote.comp",
|
||||||
|
@ -3477,8 +3477,8 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
|
|||||||
if (argStride != nullptr) {
|
if (argStride != nullptr) {
|
||||||
int size;
|
int size;
|
||||||
int stride;
|
int stride;
|
||||||
intermediate.getBaseAlignment(argArray->getType(), size, stride, false,
|
intermediate.getMemberAlignment(argArray->getType(), size, stride, argArray->getType().getQualifier().layoutPacking,
|
||||||
argArray->getType().getQualifier().layoutMatrix == ElmRowMajor);
|
argArray->getType().getQualifier().layoutMatrix == ElmRowMajor);
|
||||||
|
|
||||||
TIntermTyped* assign = intermediate.addAssign(EOpAssign, argStride,
|
TIntermTyped* assign = intermediate.addAssign(EOpAssign, argStride,
|
||||||
intermediate.addConstantUnion(stride, loc, true), loc);
|
intermediate.addConstantUnion(stride, loc, true), loc);
|
||||||
@ -8679,7 +8679,7 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType
|
|||||||
{
|
{
|
||||||
if (! qualifier.isUniformOrBuffer())
|
if (! qualifier.isUniformOrBuffer())
|
||||||
return;
|
return;
|
||||||
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430)
|
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@ -8693,11 +8693,11 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType
|
|||||||
// modify just the children's view of matrix layout, if there is one for this member
|
// modify just the children's view of matrix layout, if there is one for this member
|
||||||
TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
|
TLayoutMatrix subMatrixLayout = typeList[member].type->getQualifier().layoutMatrix;
|
||||||
int dummyStride;
|
int dummyStride;
|
||||||
int memberAlignment = intermediate.getBaseAlignment(*typeList[member].type, memberSize, dummyStride,
|
int memberAlignment = intermediate.getMemberAlignment(*typeList[member].type, memberSize, dummyStride,
|
||||||
qualifier.layoutPacking == ElpStd140,
|
qualifier.layoutPacking,
|
||||||
subMatrixLayout != ElmNone
|
subMatrixLayout != ElmNone
|
||||||
? subMatrixLayout == ElmRowMajor
|
? subMatrixLayout == ElmRowMajor
|
||||||
: qualifier.layoutMatrix == ElmRowMajor);
|
: qualifier.layoutMatrix == ElmRowMajor);
|
||||||
if (memberQualifier.hasOffset()) {
|
if (memberQualifier.hasOffset()) {
|
||||||
// "The specified offset must be a multiple
|
// "The specified offset must be a multiple
|
||||||
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
// of the base alignment of the type of the block member it qualifies, or a compile-time error results."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user