Martin Perry
Martin Perry

Reputation: 9527

OpenGL - layout informations

I have GLSL compute shader. Very simple one. I specify input texture and output image, mapped to the texture.

layout (binding=2) uniform sampler2D srcTex;

layout (binding=5, r32f) writeonly uniform image2D destTex;

In my code, I need to call glBindImageTexture to attach texture to image. Now, first parameter of this function is

unit
    Specifies the index of the image unit to which to bind the texture 

I know, that I can set this value to 5 from code manually, but how to do this automatically.

If I create shader I use refraction to get variable names and its locations.

Upvotes: 0

Views: 635

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43329

If I create shader I use refraction to get variable names and its locations.

I think you mean reflection and not refraction, assuming you mean the programming language concept.

Now, the interesting thing here is that image2D and sampler2D are what are known as opaque types in GLSL (handles to an image unit). Ordinarily, you could use the modern glGetProgramResource* (...) API (GL_ARB_program_interface_query or core in 4.3) to query really detailed information about uniforms, buffers, etc. in a GLSL shader. However, opaque types are not considered program resources by GLSL and are not compatible with that feature - the information you want is related to the image unit the uniform references and not the uniform itself.

How can I get binding ID?

This is fairly straight-forward.

You can call glGetUniformiv (...) to get the value assigned to your image2D. On the GL-side of things opaque uniforms work no differently than any other uniform (for assigning and querying values), but in GLSL you cannot assign a value to an opaque data type using the = operator. That is why the layout (binding = ...) semantics were created, they allow you to assign the binding in the shader itself rather than having to call an API function and are completely optional.

How can I get texture format from layout (r32f) to set it in my code automatically?

That is not currently possible, and in the future may become irrelevant for loads (it already is for stores). You do not technically need an exact match here. As long as image format size / class match, you can do an image load no problem.

In truth, the only reason you have to declare the format in GLSL is so that the return format for imageLoad (...) is known at compile-time (that makes it irrelevant for writeonly qualified images). There is an EXT extension right now (GL_EXT_shader_image_load_formatted) that completely eliminates the need to establish the image format for non-writeonly images.

Even for non-writeonly images, since only the size / class need to match, I do not think you really need this. r32f has an image class of 1x32 and a size of 32, but the fact that it is floating-point is not relevant to anything. Thus, what you might really consider is naming your uniforms by their image class instead - call this uniform something like destTex_1x32 and it will be obvious that it's a 1-component 32-bit image.

Upvotes: 2

Related Questions