cginternals / globjects

C++ library strictly wrapping OpenGL objects.
https://globjects.org
MIT License
539 stars 58 forks source link

VAO with DSA #394

Open PonchoBob opened 5 years ago

PonchoBob commented 5 years ago

Hello, please have look on the following piece of code

globjects::VertexArray::hintAttributeImplementation(globjects::VertexArray::AttributeImplementation::DirectStateAccessARB);

auto pVertexBuffer = globjects::Buffer::create(); pVertexBuffer->setStorage(vertices, gl::BufferStorageMask::GL_MAP_READ_BIT);

auto pIndexBuffer = globjects::Buffer::create(); pIndexBuffer->setStorage(indices, gl::BufferStorageMask::GL_MAP_READ_BIT);

//pVertexArray->bind();
auto pBinding1 = pVertexArray->binding(0); pBinding1->setBuffer(pVertexBuffer.get(), 0, sizeof(v3v3)); pBinding1->setAttribute(0);

When runing this code, I get the following error/debug message.

does not refer to an existing vertex array object. If I call pVertexArray->bind(); before setting the buffer and attributes format, everyhting is fine so far. But VAO with use of DSA usually do not need to bind before setting the buffer or attributes format. Is this by design ? In plain OpenGL this would be something like this here `glCreateBuffers(1, &vboId); ` `glCreateBuffers(1, &iboId); ` `glCreateVertexArrays(1, &vaoId);` `glNamedBufferStorage(vboId, vertices.size() * sizeof(v3v3), vertices.data(), GL_MAP_READ_BIT);` `glNamedBufferStorage(iboId, indices.size() * sizeof(uint32_t), indices.data(), GL_MAP_READ_BIT); ` `glVertexArrayVertexBuffer(vaoId, 0, vboId, 0, sizeof(v3v3));` `glVertexArrayElementBuffer(vaoId, iboId);` `glEnableVertexArrayAttrib(vaoId, 0); ` `glVertexArrayAttribFormat(vaoId, 0, 3, GL_FLOAT, GL_FALSE, 0); ` `glVertexArrayAttribBinding(vaoId, 0, 0); ` `glEnableVertexArrayAttrib(vaoId, 1);` `glVertexArrayAttribFormat(vaoId, 1, 3, GL_FLOAT, GL_FALSE, offsetof(v3v3, color));` `glVertexArrayAttribBinding(vaoId, 1, 0);` kind regards,
PonchoBob commented 5 years ago

Hello, the problem seems to be that the call of globjects::VertexArray::create() ends in glGenVertexArrays instead of glCreateVertexArrays.

I've already set globjects's VertexArray to use the DirectStateAccess extensions. How do you configure glbindings or globjects or both to invoke glCreateVertexArrays instead of glGenVertexArrays ?

kind regards.

PonchoBob commented 5 years ago

It seems, that VertexArray::create ignores the DSA settings VertexArrayObjectResource::VertexArrayObjectResource() : IDResource(createObject(glGenVertexArrays)) { }

kind regards,

Edit: seems to be a problem with the nvidia driver, but a dsa implementation would be nice.

PonchoBob commented 5 years ago

Sorry, next post. I had a look at the specifications to direct_state_access_arb and direct_state_access_ext.

Core DSA and EXT_DSA take different approaches to resolving this problem. In EXT_DSA, all of the DSA-style functions are permitted to take an object name that had no state data associated with it (ie: had not yet been bound). These functions were therefore required to be able to generate the default state behind those names, then perform whatever processing the function normally did.Core DSA does not do this. If you pass a new object to any of the core DSA functions, they will fail with GL_INVALID_OPERATION. Instead, the object's state must be initialized. This can be done via glBind functions (which goes against the point of the functionality), but the preferred method is to use the glCreate set of functions. These create object names and fill them with their initial state. Those object types which have a target that defines the type of that object (Textures and Query Objects) have this type specified by their glCreate* function. https://www.khronos.org/opengl/wiki/Direct_State_Access

Guess this brings it to the point. Wonder if AMD/ATI drivers accept a mixture of glGenVertexArrays followed by DSA functions related to the vertex array object.

kind regards.

scheibel commented 5 years ago

Thanks for the in-depth analysis. I can confirm that for DSA, the glCreate* functions should get used and that within globjects, this implementation path is missing. Problably we have to add implementation strategies for Vertex Arrays as well. And while we're at it, check other directly created objects within Resource.cpp as well.

PonchoBob commented 5 years ago

Hello, thank you for your comment. I'm a big fan of this library. I've implemented a strategy for the vertex arrays so far for testing. But you should consider to synchronize vao settings with the vao binding strategy. what i mean is, if you set the VAO strategy to use DSA implementations then the DSA strategy for vao bindings should be set automatically under the hood.

The VertexArray now has static void hintAttributeImplementation(AttributeImplementation impl); static void hintVertexArrayImplementation(VertexArrayImplementation impl);

But it should be only one method that sets the implementation strategy since the vao and binding belong together.

So far it works, but one method to change the implementation should be the goal.

I'll check the other dsa objects.

kind regards, PonchoBob

PonchoBob commented 5 years ago

Thanks for the in-depth analysis. I can confirm that for DSA, the glCreate* functions should get used and that within globjects, this implementation path is missing. Problably we have to add implementation strategies for Vertex Arrays as well. And while we're at it, check other directly created objects within Resource.cpp as well.

Hello there, "found" some more in the resource.cpp at line number 185 IDResource(createObject(glGenSampler))

Actually glCreateSamplers is the current DSA function. But using glGenSamplers with subsequent calls to glSamplerParameter* caused no errors, so....

kind regards