Skip to content

Generated OpLoad does not respect the minimum type alignment #4058

@maxime-modulopi

Description

@maxime-modulopi

glslang version: 16.0.0 (SDK 1.4.328.0)

Given this shader:

GLSL code
#version 460 core

#extension GL_EXT_buffer_reference: require
#extension GL_EXT_scalar_block_layout: require
#extension GL_EXT_nonuniform_qualifier: require

struct Vertex
{
	vec3 position;
	vec2 texCoord;
	vec3 normal;
};

layout (buffer_reference, buffer_reference_align = 4, scalar) readonly buffer VertexBuffer
{
	Vertex vertex;
};

layout (buffer_reference, buffer_reference_align = 8, scalar) readonly buffer ParametersBuffer
{
	VertexBuffer vertexBuffer;
};

layout(push_constant) uniform constants
{
	ParametersBuffer u_params;
};

void main()
{
	gl_Position = vec4(u_params.vertexBuffer.vertex.position, 1.0);
}
SPIR-V code
OpCapability Shader
OpCapability PhysicalStorageBufferAddresses
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint Vertex %4 "main" %13 %25
OpSource GLSL 460
OpSourceExtension "GL_EXT_buffer_reference"
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_EXT_scalar_block_layout"
OpName %4 "main"
OpName %11 "gl_PerVertex"
OpMemberName %11 0 "gl_Position"
OpMemberName %11 1 "gl_PointSize"
OpMemberName %11 2 "gl_ClipDistance"
OpMemberName %11 3 "gl_CullDistance"
OpName %13 ""
OpName %17 "constants"
OpMemberName %17 0 "u_params"
OpName %19 "ParametersBuffer"
OpMemberName %19 0 "vertexBuffer"
OpName %22 "Vertex"
OpMemberName %22 0 "position"
OpMemberName %22 1 "texCoord"
OpMemberName %22 2 "normal"
OpName %23 "VertexBuffer"
OpMemberName %23 0 "vertex"
OpName %25 ""
OpDecorate %11 Block
OpMemberDecorate %11 0 BuiltIn Position
OpMemberDecorate %11 1 BuiltIn PointSize
OpMemberDecorate %11 2 BuiltIn ClipDistance
OpMemberDecorate %11 3 BuiltIn CullDistance
OpDecorate %17 Block
OpMemberDecorate %17 0 Offset 0
OpDecorate %19 Block
OpMemberDecorate %19 0 NonWritable
OpMemberDecorate %19 0 Offset 0
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 12
OpMemberDecorate %22 2 Offset 20
OpDecorate %23 Block
OpMemberDecorate %23 0 NonWritable
OpMemberDecorate %23 0 Offset 0
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
%7 = OpTypeVector %6 4
%8 = OpTypeInt 32 0
%9 = OpConstant %8 1
%10 = OpTypeArray %6 %9
%11 = OpTypeStruct %7 %6 %10 %10
%12 = OpTypePointer Output %11
%13 = OpVariable %12 Output
%14 = OpTypeInt 32 1
%15 = OpConstant %14 0
OpTypeForwardPointer %16 PhysicalStorageBuffer
%17 = OpTypeStruct %16
OpTypeForwardPointer %18 PhysicalStorageBuffer
%19 = OpTypeStruct %18
%20 = OpTypeVector %6 3
%21 = OpTypeVector %6 2
%22 = OpTypeStruct %20 %21 %20
%23 = OpTypeStruct %22
%18 = OpTypePointer PhysicalStorageBuffer %23
%16 = OpTypePointer PhysicalStorageBuffer %19
%24 = OpTypePointer PushConstant %17
%25 = OpVariable %24 PushConstant
%26 = OpTypePointer PushConstant %16
%29 = OpTypePointer PhysicalStorageBuffer %18
%32 = OpTypePointer PhysicalStorageBuffer %20
%35 = OpConstant %6 1.0
%40 = OpTypePointer Output %7
%4 = OpFunction %2 None %3
%5 = OpLabel
%27 = OpAccessChain %26 %25 %15
%28 = OpLoad %16 %27
%30 = OpAccessChain %29 %28 %15
%31 = OpLoad %18 %30 Aligned 4
%33 = OpAccessChain %32 %31 %15 %15
%34 = OpLoad %20 %33 Aligned 4
%36 = OpCompositeExtract %6 %34 0
%37 = OpCompositeExtract %6 %34 1
%38 = OpCompositeExtract %6 %34 2
%39 = OpCompositeConstruct %7 %36 %37 %38 %35
%41 = OpAccessChain %40 %13 %15
OpStore %41 %39
OpReturn
OpFunctionEnd

The first OpLoad loads the u_params variable.
It is loaded from push constants, so I believe the absence of alignment is expected.

The second OpLoad loads the vertexBuffer variable.
This variable being a 64-bit pointer, its load should have Aligned 8 instead of Aligned 4.
The alignment can be confirmed because:

  1. The implicit ParametersBuffer struct has buffer_reference_align = 8
  2. The vertexBuffer variable is padded to a 8-byte alignment within the struct because of its type's alignment requirement

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions