I'm trying to make a simple compute shader using a Shader Storage Buffer (SSBO) to pass data to the shader. I'm coding in C++ with GLFW3 and GLEW. I'm passing an array of integers into an SSBO, binding it to the index 0, and expecting to retrieve the data in the shader from a layout buffer
variable (as explained on various websites). However, I get an unexpected "undefined variable" error on shader compilation concerning this layout buffer variable, though it is clearly declared.
Here is the GLSL code of the compute shader (this script is only at its beginning) :
#version 430
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout (std430, binding = 0) buffer params
{
ivec3 dims;
};
int index(ivec3 coords){
ivec3 dims = params.dims;
return coords.x + dims.y * coords.y + dims.x * dims.y * coords.z;
}
void main() {
ivec3 coords = ivec3(gl_GlobalInvocationID);
int i = index(coords);
}
I get the error : 0(12) : error C1503: undefined variable "params"
Here is the C++ script that setups and runs the compute shader :
int dimensions[] {width, height, depth};
GLuint paramSSBO;
glGenBuffers(1, ¶mSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, paramSSBO);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(dimensions), &dimensions, GL_STREAM_READ);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, paramSSBO);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLuint computeShaderID;
GLuint csProgramID;
char* computeSource;
loadShaderSource(computeSource, "compute.glsl");
computeShaderID = glCreateShader(GL_COMPUTE_SHADER);
compileShader(computeShaderID, computeSource);
delete[] computeSource;
csProgramID = glCreateProgram();
glAttachShader(csProgramID, computeShaderID);
glLinkProgram(csProgramID);
glDeleteShader(computeShaderID);
glUseProgram(csProgramID);
glDispatchCompute(width, height, depth);
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
glUseProgram(0);
glDeleteBuffers(1, ¶mSSBO);
width
, height
and depth
are int
variables defined earlier in the program. I'm binding the dimensions
array to the index 0 and I expect to retrieve it in the ivec3
params.dims
variable in the shader. However the params
variable is said to be undefined when used in the index()
function.
This script is just the beginning and I wanted to add a second buffer where the shader would actually write its result, but I'm stuck here. For clarification : in the complete script I expect not to write in any texture (as all online examples show), but write the results in the second buffer from which I will get the data back into a C++ array for further use.
params
is not a variable. Nor is it a struct or class. It is the name of an interface block. And the name of an interface block is not really part of GLSL itself; it's part of OpenGL. It's the name used by the OpenGL API to represent that particular block.
You never use an interface block's name in the shader text itself, outside of defining it.
Unless you give your interface block an instance name, the names of all variables within that block are essentially part of the global namespace. Indeed, scoping those names is the whole point of giving the block an instance name.
So the correct way to access the dims
field in the interfae block is as "dims
".