GL: Respect minimum UBO alignment requirement (#794)
* GL: Respect minimum UBO alignment requirement * Use glBindBufferRange for UBOs * Fix fragment shadergen UBO bindings * Nit
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <stb_image_write.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <bit>
|
||||
#include <cmrc/cmrc.hpp>
|
||||
|
||||
@@ -179,6 +180,10 @@ void RendererGL::initGraphicsContextInternal() {
|
||||
driverInfo.supportsExtFbFetch = (GLAD_GL_EXT_shader_framebuffer_fetch != 0);
|
||||
driverInfo.supportsArmFbFetch = (GLAD_GL_ARM_shader_framebuffer_fetch != 0);
|
||||
|
||||
// UBOs have an alignment requirement we have to respect
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, reinterpret_cast<GLint*>(&driverInfo.uboAlignment));
|
||||
driverInfo.uboAlignment = std::max<GLuint>(driverInfo.uboAlignment, 16);
|
||||
|
||||
// Initialize the default vertex shader used with shadergen
|
||||
std::string defaultShadergenVSSource = fragShaderGen.getDefaultVertexShader();
|
||||
defaultShadergenVs.create({defaultShadergenVSSource.c_str(), defaultShadergenVSSource.size()}, OpenGL::Vertex);
|
||||
@@ -930,11 +935,6 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
|
||||
glUniformBlockBinding(program.handle(), vertexUBOIndex, vsUBOBlockBinding);
|
||||
}
|
||||
}
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, fsUBOBlockBinding, shadergenFragmentUBO->GetGLBufferId());
|
||||
|
||||
if (usingAcceleratedShader) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, vsUBOBlockBinding, hwShaderUniformUBO->GetGLBufferId());
|
||||
}
|
||||
|
||||
// Upload uniform data to our shader's UBO
|
||||
PICA::FragmentUniforms uniforms;
|
||||
@@ -1020,10 +1020,21 @@ OpenGL::Program& RendererGL::getSpecializedShader() {
|
||||
|
||||
// Upload fragment uniforms to UBO
|
||||
shadergenFragmentUBO->Bind();
|
||||
auto mapRes = shadergenFragmentUBO->Map(4, sizeof(PICA::FragmentUniforms));
|
||||
std::memcpy(mapRes.pointer, &uniforms, sizeof(PICA::FragmentUniforms));
|
||||
auto uboRes = shadergenFragmentUBO->Map(driverInfo.uboAlignment, sizeof(PICA::FragmentUniforms));
|
||||
std::memcpy(uboRes.pointer, &uniforms, sizeof(PICA::FragmentUniforms));
|
||||
shadergenFragmentUBO->Unmap(sizeof(PICA::FragmentUniforms));
|
||||
|
||||
// Bind our UBOs
|
||||
glBindBufferRange(
|
||||
GL_UNIFORM_BUFFER, fsUBOBlockBinding, shadergenFragmentUBO->GetGLBufferId(), uboRes.buffer_offset, sizeof(PICA::FragmentUniforms)
|
||||
);
|
||||
|
||||
if (usingAcceleratedShader) {
|
||||
glBindBufferRange(
|
||||
GL_UNIFORM_BUFFER, vsUBOBlockBinding, hwShaderUniformUBO->GetGLBufferId(), hwShaderUniformUBOOffset, PICAShader::totalUniformSize()
|
||||
);
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
@@ -1074,11 +1085,14 @@ bool RendererGL::prepareForDraw(ShaderUnit& shaderUnit, PICA::DrawAcceleration*
|
||||
generatedVertexShader = &(*shader);
|
||||
hwShaderUniformUBO->Bind();
|
||||
|
||||
// Upload shader uniforms to our UBO
|
||||
if (shaderUnit.vs.uniformsDirty) {
|
||||
shaderUnit.vs.uniformsDirty = false;
|
||||
auto mapRes = hwShaderUniformUBO->Map(4, PICAShader::totalUniformSize());
|
||||
std::memcpy(mapRes.pointer, shaderUnit.vs.getUniformPointer(), PICAShader::totalUniformSize());
|
||||
auto uboRes = hwShaderUniformUBO->Map(driverInfo.uboAlignment, PICAShader::totalUniformSize());
|
||||
std::memcpy(uboRes.pointer, shaderUnit.vs.getUniformPointer(), PICAShader::totalUniformSize());
|
||||
hwShaderUniformUBO->Unmap(PICAShader::totalUniformSize());
|
||||
|
||||
hwShaderUniformUBOOffset = uboRes.buffer_offset;
|
||||
}
|
||||
|
||||
performIndexedRender = accel->indexed;
|
||||
|
||||
Reference in New Issue
Block a user