Skip to content

Commit 4e9e212

Browse files
committed
GL3+: validate VertexDeclaration against shader inputs
like D3D11 does. Catches bugs like missing tangents
1 parent fd13ef3 commit 4e9e212

File tree

5 files changed

+47
-0
lines changed

5 files changed

+47
-0
lines changed

RenderSystems/GL3Plus/src/GLSL/include/OgreGLSLShader.h

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ namespace Ogre {
7070
void extractUniforms(int block = -1) const;
7171
void extractBufferBlocks(GLenum type) const;
7272

73+
void extractAttributes();
74+
7375
mutable HardwareBufferPtr mDefaultBuffer;
7476
bool mHasSamplerBinding;
7577
};

RenderSystems/GL3Plus/src/GLSL/src/OgreGLSLShader.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,20 @@ namespace Ogre {
486486
mLinked = 0;
487487
}
488488

489+
void GLSLShader::extractAttributes()
490+
{
491+
GLint numAttributes = 0;
492+
OGRE_CHECK_GL_ERROR(glGetProgramInterfaceiv(mGLProgramHandle, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numAttributes));
493+
GLenum prop = GL_LOCATION;
494+
for (int attr = 0; attr < numAttributes; ++attr)
495+
{
496+
GLint val;
497+
OGRE_CHECK_GL_ERROR(
498+
glGetProgramResourceiv(mGLProgramHandle, GL_PROGRAM_INPUT, attr, 1, &prop, 1, NULL, &val));
499+
mActiveInputs.push_back(val);
500+
}
501+
}
502+
489503
void GLSLShader::extractUniforms(int block) const
490504
{
491505
GLint numUniforms = 0;
@@ -642,6 +656,8 @@ namespace Ogre {
642656
extractUniforms();
643657
extractBufferBlocks(GL_UNIFORM_BLOCK);
644658
extractBufferBlocks(GL_SHADER_STORAGE_BLOCK);
659+
if(mType == GPT_VERTEX_PROGRAM)
660+
extractAttributes();
645661
return;
646662
}
647663

RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,8 @@ namespace Ogre {
10981098
if (updateVAO)
10991099
vao->bindToGpu(this, op.vertexData->vertexBufferBinding, 0);
11001100

1101+
mCurrentShader[GPT_VERTEX_PROGRAM]->validateDeclaration(op.vertexData->vertexDeclaration);
1102+
11011103
// We treat index buffer binding inside VAO as volatile, always updating and never relying onto it,
11021104
// as one shared vertex buffer could be rendered with several index buffers, from submeshes and/or LODs
11031105
if (op.useIndexes)

RenderSystems/GLSupport/include/GLSL/OgreGLSLShaderCommon.h

+4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ namespace Ogre {
106106

107107
/// GLSL does not provide access to the low level code of the shader, so use this shader for binding as well
108108
GpuProgram* _getBindingDelegate(void) override { return this; }
109+
110+
void validateDeclaration(const VertexDeclaration* decl);
109111
protected:
110112
/// GLSL does not provide access to the low level implementation of the shader, so this method s a no-op
111113
void createLowLevelImpl() override {}
@@ -144,6 +146,8 @@ namespace Ogre {
144146
/// Pointer to the uniform cache for this shader
145147
GLUniformCache mUniformCache;
146148

149+
std::vector<int> mActiveInputs; // only for vertex shaders
150+
147151
/// Keep track of the number of shaders created.
148152
static uint mShaderCount;
149153
};

RenderSystems/GLSupport/src/GLSL/OgreGLSLShaderCommon.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ THE SOFTWARE.
3636

3737
#include "OgreGLSLShaderCommon.h"
3838
#include "OgreGLSLPreprocessor.h"
39+
#include "OgreGLSLProgramCommon.h"
3940

4041
namespace Ogre {
4142
//-----------------------------------------------------------------------
@@ -44,6 +45,28 @@ namespace Ogre {
4445
GLSLShaderCommon::CmdAttach GLSLShaderCommon::msCmdAttach;
4546
GLSLShaderCommon::CmdColumnMajorMatrices GLSLShaderCommon::msCmdColumnMajorMatrices;
4647

48+
void GLSLShaderCommon::validateDeclaration(const VertexDeclaration* decl)
49+
{
50+
for(auto sloc : mActiveInputs)
51+
{
52+
bool found = false;
53+
for (const VertexElement & elem : decl->getElements())
54+
{
55+
auto eidx = GLSLProgramCommon::getFixedAttributeIndex(elem.getSemantic(), elem.getIndex());
56+
if(eidx == sloc)
57+
{
58+
found = true;
59+
break;
60+
}
61+
}
62+
if (!found)
63+
{
64+
LogManager::getSingleton().logError("Vertex Shader " + mName + " consumes input at location " +
65+
std::to_string(sloc) + " but no such VertexElement provided");
66+
}
67+
}
68+
}
69+
4770
String GLSLShaderCommon::getResourceLogName() const
4871
{
4972
if(mLoadFromFile)

0 commit comments

Comments
 (0)