Allow using SSBO for skinning if supported

This commit is contained in:
Benau 2017-10-20 01:27:44 +08:00
parent 0d96906d54
commit 553b2439ac
10 changed files with 84 additions and 27 deletions

View File

@ -64,10 +64,12 @@ layout (std140) uniform LightingData
float rL22; float rL22;
}; };
layout (std140) uniform SkinningData #ifdef SSBO_SKINNING
layout (std140, binding = 0) readonly buffer SkinningData
{ {
mat4 joint_matrices[MAX_BONES]; mat4 joint_matrices[MAX_BONES];
}; };
#endif
#endif #endif
#endif // HEADER_TXT #endif // HEADER_TXT

View File

@ -78,11 +78,15 @@ void main(void)
{ {
break; break;
} }
#ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#else
mat4 joint_matrix = mat4( mat4 joint_matrix = mat4(
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3)); texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3));
#endif
skinned_position += Weight[i] * joint_matrix * idle_position; skinned_position += Weight[i] * joint_matrix * idle_position;
skinned_normal += Weight[i] * joint_matrix * idle_normal; skinned_normal += Weight[i] * joint_matrix * idle_normal;
skinned_tangent += Weight[i] * joint_matrix * idle_tangent; skinned_tangent += Weight[i] * joint_matrix * idle_tangent;

View File

@ -57,11 +57,15 @@ void main(void)
{ {
break; break;
} }
#ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#else
mat4 joint_matrix = mat4( mat4 joint_matrix = mat4(
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3)); texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3));
#endif
skinned_position += Weight[i] * joint_matrix * idle_position; skinned_position += Weight[i] * joint_matrix * idle_position;
} }
} }

View File

@ -75,7 +75,9 @@ void main(void)
{ {
break; break;
} }
#ifdef GL_ES #ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#elif defined(GL_ES)
mat4 joint_matrix = mat4( mat4 joint_matrix = mat4(
texelFetch(skinning_tex, ivec2(0, skinning_offset + Joint[i]), 0), texelFetch(skinning_tex, ivec2(0, skinning_offset + Joint[i]), 0),
texelFetch(skinning_tex, ivec2(1, skinning_offset + Joint[i]), 0), texelFetch(skinning_tex, ivec2(1, skinning_offset + Joint[i]), 0),

View File

@ -38,11 +38,21 @@ void main(void)
{ {
break; break;
} }
#ifdef SSBO_SKINNING
mat4 joint_matrix = joint_matrices[Joint[i] + skinning_offset];
#elif defined(GL_ES)
mat4 joint_matrix = mat4(
texelFetch(skinning_tex, ivec2(0, skinning_offset + Joint[i]), 0),
texelFetch(skinning_tex, ivec2(1, skinning_offset + Joint[i]), 0),
texelFetch(skinning_tex, ivec2(2, skinning_offset + Joint[i]), 0),
texelFetch(skinning_tex, ivec2(3, skinning_offset + Joint[i]), 0));
#else
mat4 joint_matrix = mat4( mat4 joint_matrix = mat4(
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 1),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2), texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 2),
texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3)); texelFetch(skinning_tex, (Joint[i] + skinning_offset) * 4 + 3));
#endif
skinned_position += Weight[i] * joint_matrix * idle_position; skinned_position += Weight[i] * joint_matrix * idle_position;
} }
} }

View File

@ -685,19 +685,30 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices,
PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0); PROFILER_PUSH_CPU_MARKER("- Animations/Buffer upload", 0x0, 0x0, 0x0);
shadow_matrices.updateUBO(); shadow_matrices.updateUBO();
if (CVS->supportsHardwareSkinning())
{
#ifdef USE_GLES2 #ifdef USE_GLES2
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture()); glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
#else #else
glBindBuffer(GL_TEXTURE_BUFFER, SharedGPUObjects::getSkinningBuffer()); glBindBuffer(CVS->isARBShaderStorageBufferObjectUsable() ?
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER,
SharedGPUObjects::getSkinningBuffer());
#endif #endif
}
for (unsigned i = 0; i < m_deferred_update.size(); i++) for (unsigned i = 0; i < m_deferred_update.size(); i++)
{
m_deferred_update[i]->updateGL(); m_deferred_update[i]->updateGL();
PROFILER_POP_CPU_MARKER(); }
if (CVS->supportsHardwareSkinning())
{
#ifdef USE_GLES2 #ifdef USE_GLES2
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
#else #else
glBindBuffer(GL_TEXTURE_BUFFER, 0); glBindBuffer(CVS->isARBShaderStorageBufferObjectUsable() ?
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER, 0);
#endif #endif
}
PROFILER_POP_CPU_MARKER();
PROFILER_PUSH_CPU_MARKER("- cpu particle upload", 0x3F, 0x03, 0x61); PROFILER_PUSH_CPU_MARKER("- cpu particle upload", 0x3F, 0x03, 0x61);
CPUParticleManager::getInstance()->uploadAll(); CPUParticleManager::getInstance()->uploadAll();

View File

@ -146,9 +146,8 @@ private:
/** End of recursive implementation of assignUniforms. */ /** End of recursive implementation of assignUniforms. */
void assignUniformsImpl() void assignUniformsImpl()
{ {
bindPoint("MatrixData", 0); bindPoint("MatrixesData", 0);
bindPoint("LightingData", 1); bindPoint("LightingData", 1);
bindPoint("SkinningData", 2);
} // assignUniformsImpl } // assignUniformsImpl
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -384,29 +383,45 @@ public:
class SkinnedMeshShader class SkinnedMeshShader
{ {
private: private:
GLuint m_skinning_tex_location; GLuint m_skinning_location;
public: public:
SkinnedMeshShader() : m_skinning_tex_location(0) {} SkinnedMeshShader() : m_skinning_location(0) {}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
template <typename Shader> template <typename Shader>
void init(Shader* s) void init(Shader* s)
{ {
s->use(); s->use();
m_skinning_tex_location = s->getUniformLocation("skinning_tex"); #ifndef USE_GLES2
glUniform1i(m_skinning_tex_location, 15); if (CVS->isARBShaderStorageBufferObjectUsable() &&
CVS->supportsHardwareSkinning())
{
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0,
SharedGPUObjects::getSkinningBuffer());
}
else
#endif
{
m_skinning_location = s->getUniformLocation("skinning_tex");
glUniform1i(m_skinning_location, 15);
}
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void bindSkinningTexture() void bindSkinningTexture()
{ {
glActiveTexture(GL_TEXTURE0 + 15);
#ifdef USE_GLES2 #ifdef USE_GLES2
glActiveTexture(GL_TEXTURE0 + 15);
glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture()); glBindTexture(GL_TEXTURE_2D, SharedGPUObjects::getSkinningTexture());
glBindSampler(15, 0);
#else #else
if (!CVS->isARBShaderStorageBufferObjectUsable())
{
glActiveTexture(GL_TEXTURE0 + 15);
glBindTexture(GL_TEXTURE_BUFFER, glBindTexture(GL_TEXTURE_BUFFER,
SharedGPUObjects::getSkinningTexture()); SharedGPUObjects::getSkinningTexture());
#endif
glBindSampler(15, 0); glBindSampler(15, 0);
} }
#endif
}
}; };

View File

@ -170,7 +170,9 @@ GLuint ShaderFilesManager::loadShader(const std::string &file, unsigned type)
code << "#define Advanced_Lighting_Enabled\n"; code << "#define Advanced_Lighting_Enabled\n";
if (CVS->isARBSRGBFramebufferUsable()) if (CVS->isARBSRGBFramebufferUsable())
code << "#define sRGB_Framebuffer_Usable\n"; code << "#define sRGB_Framebuffer_Usable\n";
if (CVS->isARBShaderStorageBufferObjectUsable() &&
CVS->supportsHardwareSkinning())
code << "#define SSBO_SKINNING\n";
#if !defined(USE_GLES2) #if !defined(USE_GLES2)
// shader compilation fails with some drivers if there is no precision // shader compilation fails with some drivers if there is no precision
// qualifier // qualifier

View File

@ -174,14 +174,19 @@ void SharedGPUObjects::initSkinning()
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
#else #else
glGenBuffers(1, &m_skinning_buf); glGenBuffers(1, &m_skinning_buf);
glBindBuffer(GL_TEXTURE_BUFFER, m_skinning_buf); const bool ssbo = CVS->isARBShaderStorageBufferObjectUsable();
glBufferData(GL_TEXTURE_BUFFER, 65536, NULL, GL_DYNAMIC_DRAW); const GLenum buffer = ssbo ? GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER;
glBindBuffer(buffer, m_skinning_buf);
glBufferData(buffer, 65536, NULL, GL_DYNAMIC_DRAW);
if (!ssbo)
{
glBindTexture(GL_TEXTURE_BUFFER, m_skinning_tex); glBindTexture(GL_TEXTURE_BUFFER, m_skinning_tex);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_skinning_buf); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_skinning_buf);
glBindTexture(GL_TEXTURE_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindBuffer(GL_TEXTURE_BUFFER, 0); }
glBindBuffer(buffer, 0);
#endif #endif
} // initSkinningTBO } // initSkinning
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void SharedGPUObjects::init() void SharedGPUObjects::init()

View File

@ -382,7 +382,9 @@ void STKAnimatedMesh::uploadJoints(const irr::core::matrix4& m,
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (offset >> 6) + joint, 16, 1, GL_RGBA, glTexSubImage2D(GL_TEXTURE_2D, 0, 0, (offset >> 6) + joint, 16, 1, GL_RGBA,
GL_FLOAT, m.pointer()); GL_FLOAT, m.pointer());
#else #else
glBufferSubData(GL_TEXTURE_BUFFER, offset + joint * 16 * sizeof(float), glBufferSubData(CVS->isARBShaderStorageBufferObjectUsable() ?
GL_SHADER_STORAGE_BUFFER : GL_TEXTURE_BUFFER,
offset + joint * 16 * sizeof(float),
16 * sizeof(float), m.pointer()); 16 * sizeof(float), m.pointer());
#endif #endif
} }