Skip to content

Reading uint8_t from storage buffers adds (unnecessarily) UniformAndStorageBuffer8BitAccess capability #1539

@zeux

Description

@zeux

(yes, this is me and my uint8_t shader again)

This shader:

#version 450

#extension GL_EXT_shader_16bit_storage: require
#extension GL_EXT_shader_8bit_storage: require

struct Vertex
{
	float vx, vy, vz;
	uint8_t nx, ny, nz, nw;
	float tu, tv;
};

layout(binding = 0) readonly buffer Vertices
{
	Vertex vertices[];
};

layout(location = 0) out vec4 color;

void main()
{
	vec3 position = vec3(vertices[gl_VertexIndex].vx, vertices[gl_VertexIndex].vy, vertices[gl_VertexIndex].vz);
	vec3 normal = vec3(int(vertices[gl_VertexIndex].nx), int(vertices[gl_VertexIndex].ny), int(vertices[gl_VertexIndex].nz)) / 127.0 - 1.0;
	vec2 texcoord = vec2(vertices[gl_VertexIndex].tu, vertices[gl_VertexIndex].tv);

	gl_Position = vec4(position * vec3(1, 1, 0.5) + vec3(0, 0, 0.5), 1.0);

	color = vec4(normal * 0.5 + vec3(0.5), 1.0);
}

Gets compiled into a shader with these capabilities:

               OpCapability Shader
               OpCapability StorageBuffer8BitAccess
               OpCapability UniformAndStorageBuffer8BitAccess

It seems to me that UniformAndStorageBuffer8BitAccess is unnecessary; I hit this because on the C++ side, you can enable these features separately, and I was only enabling 8-bit storage buffer access which seems correct to me. I don't think glslang should be adding both and instead should only add StorageBuffer8BitAccess.

After talking to @sheredom it seems like there might be some subtle differences here between SPIRV 1.0 and SPIRV 1.3 that I didn't fully grasp, but selecting SPIRV 1.3 (via --target-env vulkan1.1) still produces a shader that requires both capabilities.

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