What is the use of block name in Vulkan GLSL? - glsl

Take this GLSL sample code:
layout(set = 0, binding = 0) uniform BlockName {
mat4 someMtx;
} instanceName;
What is the purpose of "BlockName" in this context?
I know you can use the block name to match inputs/outputs of pipeline stages. But what is the purpose for uniform blocks in Vulkan?

The purpose is that GLSL requires it.
GLSL was made for OpenGL. It can be used with Vulkan, but the actual features of GLSL were made to serve the needs of OpenGL. Since Vulkan is a very different API, that means you're going to sometimes have vestigial functionality.
Like these.
In OpenGL, resources are identified, and can be queried, by name. Two resources are the same resource if they use the same name (they also have to match with other properties or an error results, but a name match is a requirement). As such, block names were made part of the grammar of GLSL interface blocks. You can't not have them on any interface blocks (UBOs being a subset of interface blocks).
Vulkan (and SPIR-V) doesn't care about names. For interface variables, the name remains useful because the GLSL code itself uses that name when it wants to access that variable. But block names were only used by the external API; they were never used by GLSL code itself.
So when you use a GLSL construct that uses an interface-only name to feed an API that doesn't care about interface names, you get block names: a name that needs to exist because GLSL requires it but doesn't actually do the thing GLSL expects it to.

Related

Does uniform binding point shared between different stages at the same program?

I look at this link https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
It says different program can share same binding point's uniform value, but it doesn't mention whether the vertex shader and fragment shader could share them same uniform buffer ?
If they could share, did I need to define the same uniform twice with the same name and the same binding
glBindBufferRange doesn't take a shader stage when you bind a buffer. As such, UBO binding points are not stage specific. Binding point 0, for example, is the same binding point whether you use it in a VS, FS, or both. Both names represent the same bound buffer object.
did I need to define the same uniform twice with the same name and the same binding
Yes, in exactly the same way that if you want to share some class in two different cpp files, both files have to have the same class definition. In C++, this is typically done via a header. In GLSL, it happens however you want it to happen.

OpenGL - glGen* and unique identifiers

OpenGL defines a few glGen* functions, for example:
glGenTextures
glGenFrameBuffers
glGenBuffers
Does id generated by glGen function is unique globally or only within a glGen context - for example glGenTextures ?
Object names are only unique within a given space of object names. Usually, that means for the object type itself: texture names, buffer names, etc.
The only exception to this are shader and program objects who share the same name space, and thus their names cannot overlap.

Don't break backwards-compatibility messages in a DDS system

I'm involved in a project which uses DDS as a protocol to communicate and C++ as language. As you know exchanged messages are called Topics. Well, sometimes a team must change a topic definition, as a consequence of this, other software which depends on this topic stops working, it is necessary to update the topic everywhere and recompile. So, my question is, do you know how not to break backwards compatiblity? I have been searching and I have found google protocol buffer, they say this:
"You can add new fields to your message formats without breaking
backwards-compatibility; old binaries simply ignore the new field when
parsing. So if you have a communications protocol that uses protocol
buffers as its data format, you can extend your protocol without
having to worry about breaking existing code."
Any other idea?
Thanks in advance.
The OMG specification Extensible and Dynamic Topic Types for DDS (or DDS-XTypes for short) addresses your problem. Quoted from that specification:
The Type System supports type evolution so that it is possible to
“evolve the type” as described above and retain interoperability
between components that use different versions of the type
Not all DDS implementations currently support XTypes, so you might have to resort to a different solution. For example, you could include a version numbering scheme in your Topic name to avoid typing conflicts between different components. In order to make sure every component receives the right data it needs, you can create a service that has the responsibility to forward between different versions of the Topics as needed. This service has to be aware of the different versions of the Topics and should take care of filling default values and/or transform between their different types. Whether or not this is a viable solution depends, among other things, on your system requirements.
The use of a different type system like Protocol Buffers inside DDS is not recommended if it is just for the purpose of solving the type evolution problem. You would essentially be transporting your PB messages as data opaque to the DDS middleware. This means that you would also lose some of the nice tooling features like dynamic discovery and display of types, because the PB messages are not understood by the DDS middleware. Also, your applications would become more complex because they would be responsible for invoking the right PB de/serialization methods. It is easier to let DDS take care of all that.
Whichever route you take, it is recommended that you manage your data model evolution tightly. If you let just anybody add or remove some attributes to their liking, the situation will become difficult to maintain quickly.
The level of support for protocol buffers with DDS depends on how its implemented. With PrismTech's Vortex for instance, you don't lose content-awareness, nor dynamic discovery nor display of types as both the middleware and its tools DO understand the PB messages. W.r.t. 'populating' your PB-based topic, thats conform the PB-standard and generated transparently by the protoc compiler, so one could state that if you're familiar with protobuf (and perhaps not with OMG's IDL alternative), then you can really benefit from a proper integration of DDS and GPB that retains the global-dataspace advantages yet i.c.w. a well-known/popular type-system (GPB)
You could try wrapping the DDS layer in your own communication layer.
Define a set of DDS Types and DDS Profiles that covers all your needs.
Then each topic will be define as one of those types associated to one of those profiles.
For example you could have a type for strings, and a binary type.
If you use the same compiler for all your software, you can even safely memcopy a C struct to the binary type.
module atsevents {
valuetype DataType {
public string<128> mDataId;
public boolean mCustomField1;
public boolean mCustomField2;
};
valuetype StringDataType : DataType {
public string<128> mDataKey; //#key
public string<1024> mData;
};
valuetype BinaryDataType : DataType {
public string<128> mDataKey; //#key
public sequence<octet, 1024> mData;
public unsigned long mTypeHash;
}
}

C++ / OOP: Class with implicit dependency on other class

I'm writing a program in OpenGL. There is a Gfx class which holds an OpenGL context and wraps the OpenGL library.
There is also a Texture class which wraps OpenGL texture names (including generation and deletion). The Texture class naturally has an implicit dependency on the Gfx class. But I want RAII, no pointers, and therefore think that the Texture class must be publicly accessible.
What is the cleanest way to express the dependency on a constructed Gfx instance?
Assuming the texture cannot exist without the context, looks like the constructor argument is proper in this case, possibly a std::shared_ptr<Gfx> (hope this is excused from your no-pointer policy - I consider it a C++ construct). This way Gfx will linger as long as at least one Texture is not disposed.

Is using "Key" design pattern in shader class possible?

First of all, i don't know if the "key" pattern is accepted as general patter, but some sorts of it have been appearing all over SO recently, so...
What I want to do?
Create shader manipulation class in C++. My issue here particularly focuses on setting uniform values (values sent from C++ to GLSL "directly").
What's the problem?
(Quick explanation, so that people not accustomed to OpenGL can contribute too) -
Uniform variables are set by using global glUniform* functions, taking as first parameter the location of the uniform in currently bound shader (int);
So the common usage is:
glBindProgram(myProgramNum);
int Location = glGetUniformLocation(myProgramNum, "myUniformParameterName");
float myValue = 42.f; // arbitrary data
glUniform1f (Location, myValue);
I've created some of the methods I need to encapsulate the above, such as
void SetUniform1f (std::string const& name, float a);
void SetUniformVector3 (std::string const& name, CVector3 const& vec);
void SetUniformMatrix4 (std::string const& name, CMatrix4 const& mat);
I've noticed, however, that all these use the glGetUniformLocation(int, const char*). As some of them will be used in realtime, this would cause unnecessary performance overhead.
The first idea
I've thought that I could create two versions of each function - one taking std::string and value, and second int and value, thus allowing faster access.
However, it would make them no better than the pure OpenGL access, since user would still be able to send malicious parameter to them.
The second idea
So, the proper way do to it would be to generate some sort of "Key" object from shader class, containing location of given uniform. It would however need to be linked to specific CShader class instance, because one could generate key in one object and pass it to another, causing unwanted behavior.
And my question is - is something like this possible in C++? Do I have to keep pointer to "parent" object in the key object and test if it's valid parameter every time, or are there any language/Boost features that will allow some sort of syntaxic sugar around it?
What I was able to deduce myself, the key class should be nested in CShader, and had CShader as friend. Also it should declare trivial constructor private, and overload copy-constructor so that copied objects will still be valid keys.
You need only an integer to set an uniform variable. Indeed, instead of calling a bunch of glGetUniformLocation, why don't you cache those values in a std::map<std::string, int>? Querying the map would be faster, isn't it?
Not everything is clear in you question (parent pointer?, malicious values?), but at the end an hypothetical user of a CShader class wants a shortcut for setting up uniform values. Indeed you can query uniforms after shader linkage (using glGetActiveUniform) or you can query uniform and cache uniform location when necessary.