Skip to content

GL3+: validate VertexDeclaration against shader inputs #2646

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions RenderSystems/GL3Plus/src/GLSL/include/OgreGLSLShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ namespace Ogre {
void extractUniforms(int block = -1) const;
void extractBufferBlocks(GLenum type) const;

void extractAttributes();

mutable HardwareBufferPtr mDefaultBuffer;
bool mHasSamplerBinding;
};
Expand Down
16 changes: 16 additions & 0 deletions RenderSystems/GL3Plus/src/GLSL/src/OgreGLSLShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,20 @@ namespace Ogre {
mLinked = 0;
}

void GLSLShader::extractAttributes()
{
GLint numAttributes = 0;
OGRE_CHECK_GL_ERROR(glGetProgramInterfaceiv(mGLProgramHandle, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numAttributes));
GLenum prop = GL_LOCATION;
for (int attr = 0; attr < numAttributes; ++attr)
{
GLint val;
OGRE_CHECK_GL_ERROR(
glGetProgramResourceiv(mGLProgramHandle, GL_PROGRAM_INPUT, attr, 1, &prop, 1, NULL, &val));
mActiveInputs.push_back(val);
}
}

void GLSLShader::extractUniforms(int block) const
{
GLint numUniforms = 0;
Expand Down Expand Up @@ -642,6 +656,8 @@ namespace Ogre {
extractUniforms();
extractBufferBlocks(GL_UNIFORM_BLOCK);
extractBufferBlocks(GL_SHADER_STORAGE_BLOCK);
if(mType == GPT_VERTEX_PROGRAM)
extractAttributes();
return;
}

Expand Down
2 changes: 2 additions & 0 deletions RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1098,6 +1098,8 @@ namespace Ogre {
if (updateVAO)
vao->bindToGpu(this, op.vertexData->vertexBufferBinding, 0);

mCurrentShader[GPT_VERTEX_PROGRAM]->validateDeclaration(op.vertexData->vertexDeclaration);

// We treat index buffer binding inside VAO as volatile, always updating and never relying onto it,
// as one shared vertex buffer could be rendered with several index buffers, from submeshes and/or LODs
if (op.useIndexes)
Expand Down
4 changes: 4 additions & 0 deletions RenderSystems/GLSupport/include/GLSL/OgreGLSLShaderCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ namespace Ogre {

/// GLSL does not provide access to the low level code of the shader, so use this shader for binding as well
GpuProgram* _getBindingDelegate(void) override { return this; }

void validateDeclaration(const VertexDeclaration* decl);
protected:
/// GLSL does not provide access to the low level implementation of the shader, so this method s a no-op
void createLowLevelImpl() override {}
Expand Down Expand Up @@ -144,6 +146,8 @@ namespace Ogre {
/// Pointer to the uniform cache for this shader
GLUniformCache mUniformCache;

std::vector<int> mActiveInputs; // only for vertex shaders

/// Keep track of the number of shaders created.
static uint mShaderCount;
};
Expand Down
23 changes: 23 additions & 0 deletions RenderSystems/GLSupport/src/GLSL/OgreGLSLShaderCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ THE SOFTWARE.

#include "OgreGLSLShaderCommon.h"
#include "OgreGLSLPreprocessor.h"
#include "OgreGLSLProgramCommon.h"

namespace Ogre {
//-----------------------------------------------------------------------
Expand All @@ -44,6 +45,28 @@ namespace Ogre {
GLSLShaderCommon::CmdAttach GLSLShaderCommon::msCmdAttach;
GLSLShaderCommon::CmdColumnMajorMatrices GLSLShaderCommon::msCmdColumnMajorMatrices;

void GLSLShaderCommon::validateDeclaration(const VertexDeclaration* decl)
{
for(auto sloc : mActiveInputs)
{
bool found = false;
for (const VertexElement & elem : decl->getElements())
{
auto eidx = GLSLProgramCommon::getFixedAttributeIndex(elem.getSemantic(), elem.getIndex());
if(eidx == sloc)
{
found = true;
break;
}
}
if (!found)
{
LogManager::getSingleton().logError("Vertex Shader " + mName + " consumes input at location " +
std::to_string(sloc) + " but no such VertexElement provided");
}
}
}

String GLSLShaderCommon::getResourceLogName() const
{
if(mLoadFromFile)
Expand Down