GLSL `Semantics/BuiltIn Variables` & `centroid` & `Interface blocks`

Started by
5 comments, last by akhin 12 years ago
Hi everyone ,

I have some questions regarding porting HLSL to GLSL :

1. Regarding the HLSL shader framework I have , I have large structs
with member variables which use semantics such as Color Color1 Vpos Vface Texcoord[N] and Texcoord[N]_centroid...

As I understand , there are no semantics in GLSL , but built-in variables such gl_fragColor and so on.

So my question is that what woud you suggest to port those structs with variables using semantics ?
Shall I make member variables with semantics global or are there any other ways you could suggest ?

2. I can`t use `location` qualifier and `centroid in/out` qualifier at the same time

I can have a struct like :

out struct test
{
centroid in float red;
layout(location = 1) float green;
layout(location = 2) float blue;
} ;

but I cant have :

out struct test
{
layout(location = 0) centroid in float red;
layout(location = 1) float green;
layout(location = 2) float blue;
} ;


The compiler says : `Location can be set only once `

On the other hand I can use `centroid in/out` qualifier together with location qualifier for a variable :

layout(location = 0) centroid out float t1;

So how can I use the centroid in/out qualifier at the same time with a location qualifier
for a struct member ?

3. I am trying to understand the difference between a struct and an interface block( in/out/uniform ).
I guess you can just create one instance of an interface so they will be just a set of global variables ?
Advertisement
I do not know anything about HLSL, but i try to help anyway.


1. /.../ built-in variables such gl_fragColor and so on. /.../

Most of such build in variables have been deprecated. Might want to avoid using them (and use generic ones with whatever qualifiers make sense for your specific case). Also, yes, you can redeclare them with your own qualifiers too.

A few quick reference cards (always worth spreading around):
www.khronos.org/files/opengl-quick-reference-card.pdf
www.khronos.org/files/opengl4-quick-reference-card.pdf

/.../


3. I am trying to understand the difference between a struct and an interface block( in/out/uniform ).
I guess you can just create one instance of an interface so they will be just a set of global variables ?

Blocks are used to communicate between shader stages and with them (just convenience or efficiency [uniform blocks with std memory layout instead of separate uniforms]). A struct is just a sctuct as in any other programming language. Not sure what the confusion is :/

------
Edit: wait, what!? I must have been blind. "out struct test" !? You are mixing structs with interface blocks - they are not the same. Remove the struct part. (Do you have an nvidia card by any chance?)

Edit2: went to refresh my memory about "struct" usage/syntax, but realized another oddity: "layout location" does not really make any sense with centroid. Also, readding the note that: block is defined as "out", but the "red" with centroid qualifier in it is "in" - they should agree with each other.
Firstly I have an AMD card.

1. I am not supposed to use in/out qualifiers with structs ? Does that mean if I am going to share things between stages
they should be either interfaces or just global variables using in/out qualifiers ?

2. In HLSL side, I am using semantics like TEXCOORD4_centroid , and I was planning to use something like
layout(location=4) to match TEXCOORDs. And at the same time I want to specify that that variable should be sampled by
centroid sampling method

How can I achieve this ?

3. Regarding mixing `in centroid` with an `out struct` ,I was trying the code above in a vertex shader so that I want to output that struct and that is working like that.
On the other hand the compiler doesn`t allow me to use centroid with out in a vertex shader but it just allows `centroid in` in a vertex shader.

1. I am not supposed to use in/out qualifiers with structs ? Does that mean if I am going to share things between stages
they should be either interfaces or just global variables using in/out qualifiers ?

Tried to find what the rules are with struct, but was not able to discern it in the time allotted :/. edit: ok, i think i remember it now - more useful stuff after next quote.

in / out global variables and/or interface blocks are the only way to communicate between shader stages.


2. In HLSL side, I am using semantics like TEXCOORD4_centroid , and I was planning to use something like
layout(location=4) to match TEXCOORDs. And at the same time I want to specify that that variable should be sampled by
centroid sampling method

like:

layout(location=4) centroid in vec4 attr;

or, probably (edit: remembered something, interface blocks are not allowed for vertex input not fragment output), also:

// vertex shader
in struct name {
layout(location=4) centroid in vec4 attr; // note that "in" agrees with parent declaration
layout(location= ... etc for whatever other stuff
} instance_name;
// access: instance_name.attr



3. Regarding mixing `in centroid` with an `out struct` ,I was trying the code above in a vertex shader so that I want to output that struct and that is working like that.
On the other hand the compiler doesn`t allow me to use centroid with out in a vertex shader but it just allows `centroid in` in a vertex shader.

Probably because you are mixing in and out - it can not be both at the same time.

// vertex shader
out block_name2 {
controid out vec4 attr;
...
} fs;
// fragment shader
in block_name2 {
controid in vec4 attr;
...
} fs;
// blocknames etc get automatically matched/connected between stages by name.
By the way as I have tested , I can use in out with structs so that I can share structs between shader stages.
But I am trying to understand its pros and cons against non-uniform in/out interface blocks :


// inside the vertex shader
out struct test
{
ATTRIB(0) float red;
ATTRIB(1) float green;
ATTRIB(2) float blue;
} ;
test v_out;



But I think that is working because I use I declare a global variable with that struct type ?
There are two "ways" to get stuff out:
1) out type instName; // one var - where type is any type (float, vector, matrix ... and even structs)
2) out blockName { ... } instName; // multiple vars (aka. interface block)

Separating the declaration of the struct type and its instantiations should not matter with non-broken compilers.

edit: I doubt there is any real difference between using a struct in in/out or an interface block as far as interface is concerned (if you leave "out" out of the struct declaration then you can use it for non-interface business too - that is not an option for interface blocks obviously).

PS. your use of separate floats for red, green, blue is a bit alarming: one should prefer vectors to avoid extra work for rasterizer.
Tanzanite , thanks a lot for all your help ,

things are clear in my side now

and as for my struct usage ofcourse I am not going to use rgb stuff inside structs like this , it was just for example.

This topic is closed to new replies.

Advertisement