Reading uint8_t from storage buffers adds (unnecessarily) UniformAndStorageBuffer8BitAccess capability
zeux opened this issue · 0 comments
zeux commented
(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.