Hello again,
I havestumbled upon a Steam Game Dev conference that featured a presentation on modern technique for vertex data streaming, in particular a method utilizes persistent buffers. I implemented the solution the presenter proposed, replacing my SSBO and VBO buffers with persistent ones.
Initialization:
// Object SSBO
glGenBuffers(1, &(this->objectSSBO));
glBindBuffer(GL_SHADER_STORAGE_BUFFER, this->objectSSBO);
glBufferStorage(GL_SHADER_STORAGE_BUFFER, graphics2DMaximumSSBOSize_Byte * 3, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
this->objectSSBOAddrStart = (graphics2DObjectData *) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, graphics2DMaximumSSBOSize_Byte * 3, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
// Object VBO
glGenBuffers(1, &(this->objectVBO));
glBindBuffer(GL_ARRAY_BUFFER, this->objectVBO);
glGenVertexArrays(1, &(this->objectVAO));
glBindVertexArray(this->objectVAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(graphics2DObjectVertexData), (GLvoid*)offsetof(graphics2DObjectVertexData, position));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(graphics2DObjectVertexData), (GLvoid*)offsetof(graphics2DObjectVertexData, uvCoordinates));
glEnableVertexAttribArray(1);
glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, sizeof(graphics2DObjectVertexData), (GLvoid*)offsetof(graphics2DObjectVertexData, objectIndex));
glEnableVertexAttribArray(2);
glBufferStorage(GL_ARRAY_BUFFER, graphics2DMaximumVBOSize_Byte*3, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
this->objectVBOAddrStart = (graphics2DObjectVertexData *) glMapBufferRange(GL_ARRAY_BUFFER, 0, graphics2DMaximumVBOSize_Byte * 3, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Synchronization:
// Waiting for buffer
GLenum waitStatus = GL_UNSIGNALED;
if (this->subSceneSync) {
while ((waitStatus != GL_ALREADY_SIGNALED) && (waitStatus != GL_CONDITION_SATISFIED))
{
waitStatus = glClientWaitSync(this->subSceneSync, GL_SYNC_FLUSH_COMMANDS_BIT, 1);
}
}
this->objectVBOAddr = this->objectVBOAddrStart + this->currentBuffer*graphics2DMaximumVBOSize_Byte;
this->objectSSBOAddr = this->objectSSBOAddrStart + this->currentBuffer*graphics2DMaximumSSBOSize_Byte;
/////////////////////////////////////
// FETCH AND RENDER HERE
/////////////////////////////////////
this->currentBuffer = (this->currentBuffer + 1) % 3;
// Locking the buffer
if (this->subSceneSync) glDeleteSync(this->subSceneSync);
this->subSceneSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
Rendering:
glBindFramebuffer(GL_FRAMEBUFFER, this->subSceneFBO1);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(graphics2DStage1ObjectShader);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->textureAsset->colorMapID);
glUniform1i(graphics2DStage1ObjectColorMapLocation, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, this->textureAsset->normalMapID);
glUniform1i(graphics2DStage1ObjectNormalMapLocation, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, this->textureAsset->specularMapID);
glUniform1i(graphics2DStage1ObjectSpecularMapLocation, 2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, this->textureAsset->lightMapID);
glUniform1i(graphics2DStage1ObjectLightMapLocation, 3);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_BLEND);
// Binding SSBO
glBindBuffer(GL_SHADER_STORAGE_BUFFER, this->objectSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, this->objectSSBO);
// Binding VBO
glBindVertexArray(this->objectVAO);
glBindBuffer(GL_ARRAY_BUFFER, this->objectVBO);
glDrawArrays(GL_TRIANGLES, graphics2DMaximumVerteces*this->currentBuffer, vertexIndex);
These are the only major changes from the last working version of my thing.
However nvoglv64.dll crashes during SSBO data filling for the very first object. Addresses seem to be good, all the buffer switching is proper as well. My video card does support the ARB_BUFFER_STORAGE extension. Is there anything else I can check to ensure the working order.
The program also crashes with just VBO being persistent, but it actually makes it past frame 1, so I don’t think having 2 persistent buffers is an issue.
Suggestions are appreciated.