Now use new CommandBuffer class for reflective shadowmaps

This commit is contained in:
Elderme
2015-11-12 22:13:18 +01:00
parent 97d497a0b5
commit 5c02c58ded
7 changed files with 126 additions and 88 deletions

View File

@@ -60,29 +60,9 @@
prefilled_tex[1], prefilled_tex[2], prefilled_tex[3]);
}
template<typename T>
void CommandBuffer::fillMaterial(int material_id,
MeshMap *mesh_map,
T *instance_buffer)
{
m_offset[material_id] = m_command_buffer_offset;
FillInstances<T>(mesh_map[material_id],
m_meshes[material_id],
instance_buffer,
m_draw_indirect_cmd,
m_instance_buffer_offset,
m_command_buffer_offset,
m_poly_count);
m_size[material_id] = m_command_buffer_offset - m_instance_buffer_offset;
}
CommandBuffer::CommandBuffer():
m_offset(NULL), m_size(NULL), m_poly_count(0)
template<int N>
CommandBuffer<N>::CommandBuffer():
m_poly_count(0)
{
glGenBuffers(1, &m_draw_indirect_cmd_id);
glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_draw_indirect_cmd_id);
@@ -104,20 +84,15 @@ m_offset(NULL), m_size(NULL), m_poly_count(0)
}
}
CommandBuffer::~CommandBuffer()
template<int N>
CommandBuffer<N>::~CommandBuffer()
{
delete[] m_meshes;
glDeleteBuffers(1, &m_draw_indirect_cmd_id);
delete[] m_offset;
delete[] m_size;
}
SolidCommandBuffer::SolidCommandBuffer(): CommandBuffer()
{
m_meshes = new std::vector<GLMesh *>[static_cast<int>(Material::SHADERTYPE_COUNT)];
m_offset = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
m_size = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
}
void SolidCommandBuffer::fill(MeshMap *mesh_map)
@@ -218,9 +193,6 @@ void SolidCommandBuffer::fill(MeshMap *mesh_map)
ShadowCommandBuffer::ShadowCommandBuffer(): CommandBuffer()
{
m_meshes = new std::vector<GLMesh *>[4 * static_cast<int>(Material::SHADERTYPE_COUNT)];
m_offset = new size_t[4 * static_cast<int>(Material::SHADERTYPE_COUNT)];
m_size = new size_t[4 * static_cast<int>(Material::SHADERTYPE_COUNT)];
}
void ShadowCommandBuffer::fill(MeshMap *mesh_map)
@@ -228,6 +200,13 @@ void ShadowCommandBuffer::fill(MeshMap *mesh_map)
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
//clear meshes
for(int i=0;i<4*Material::SHADERTYPE_COUNT;i++)
{
m_meshes[i].clear();
}
InstanceDataSingleTex *shadow_instance_buffer;
if (CVS->supportsAsyncInstanceUpload())
@@ -281,9 +260,6 @@ void ShadowCommandBuffer::fill(MeshMap *mesh_map)
ReflectiveShadowMapCommandBuffer::ReflectiveShadowMapCommandBuffer(): CommandBuffer()
{
m_meshes = new std::vector<GLMesh *>[static_cast<int>(Material::SHADERTYPE_COUNT)];
m_offset = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
m_size = new size_t[static_cast<int>(Material::SHADERTYPE_COUNT)];
}
@@ -292,11 +268,18 @@ void ReflectiveShadowMapCommandBuffer::fill(MeshMap *mesh_map)
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
//clear meshes
for(int i=0;i<Material::SHADERTYPE_COUNT;i++)
{
m_meshes[i].clear();
}
InstanceDataSingleTex *rsm_instance_buffer;
if (CVS->supportsAsyncInstanceUpload())
{
rsm_instance_buffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeShadow);
rsm_instance_buffer = (InstanceDataSingleTex*)VAOManager::getInstance()->getInstanceBufferPtr(InstanceTypeRSM);
}
else
{
@@ -319,7 +302,7 @@ void ReflectiveShadowMapCommandBuffer::fill(MeshMap *mesh_map)
Material::SHADERTYPE_ALPHA_TEST,
Material::SHADERTYPE_SOLID_UNLIT,
Material::SHADERTYPE_DETAIL_MAP,
Material::SHADERTYPE_NORMAL_MAP,
Material::SHADERTYPE_NORMAL_MAP
};
int material_id;
@@ -340,17 +323,17 @@ void ReflectiveShadowMapCommandBuffer::fill(MeshMap *mesh_map)
} //ReflectiveShadowMapCommandBuffer::fill
GlowCommandBuffer::GlowCommandBuffer()
{
m_meshes = new std::vector<GLMesh *>[1];
m_offset = new size_t[1];
m_size = new size_t[1];
{
}
void GlowCommandBuffer::fill(MeshMap *mesh_map)
{
m_instance_buffer_offset = 0;
m_command_buffer_offset = 0;
m_poly_count = 0;
m_poly_count = 0;
m_meshes[0].clear();
GlowInstanceData *glow_instance_buffer;
if (CVS->supportsAsyncInstanceUpload())

View File

@@ -88,6 +88,7 @@ void FillInstances_impl(InstanceList instance_list,
poly_count += (instance_buffer_offset - initial_offset) * mesh->IndexCount / 3;
}
//TODO: clean draw_calls and remove this function
template<typename T>
void FillInstances( const MeshMap &gathered_GL_mesh,
std::vector<GLMesh *> &instanced_list,
@@ -119,15 +120,16 @@ template<>
void expandTexSecondPass<GrassMat>(const GLMesh &mesh,
const std::vector<GLuint> &prefilled_tex);
template<int N>
class CommandBuffer
{
protected:
std::vector<GLMesh *> *m_meshes;
GLuint m_draw_indirect_cmd_id;
DrawElementsIndirectCommand *m_draw_indirect_cmd;
size_t *m_offset;
size_t *m_size;
std::vector<GLMesh *> m_meshes[N];
size_t m_offset[N];
size_t m_size[N];
size_t m_poly_count;
size_t m_instance_buffer_offset;
size_t m_command_buffer_offset;
@@ -135,8 +137,19 @@ protected:
template<typename T>
void fillMaterial(int material_id,
MeshMap *mesh_map,
T *instance_buffer);
T *instance_buffer)
{
m_offset[material_id] = m_command_buffer_offset;
for(auto& instance_list : mesh_map[material_id])
{
FillInstances_impl<T>(instance_list.second, instance_buffer, m_draw_indirect_cmd, m_instance_buffer_offset, m_command_buffer_offset, m_poly_count);
if (!CVS->isAZDOEnabled())
m_meshes[material_id].push_back(instance_list.second.front().first);
}
m_size[material_id] = m_command_buffer_offset - m_instance_buffer_offset;
}
public:
CommandBuffer();
@@ -154,23 +167,24 @@ public:
template<typename T, typename...Uniforms>
void drawIndirect(Uniforms...uniforms) const
void drawIndirectFirstPass(Uniforms...uniforms) const
{
T::InstancedFirstPassShader::getInstance()->use();
T::InstancedFirstPassShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType, T::Instance));
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
T::Instance));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
#ifdef DEBUG
#ifdef DEBUG
if (mesh->VAOType != T::VertexType)
{
Log::error("RenderGeometry", "Wrong instanced vertex format (hint : %s)",
Log::error("CommandBuffer", "Wrong instanced vertex format (hint : %s)",
mesh->textures[0]->getName().getPath().c_str());
continue;
}
#endif
#endif
TexExpander<typename T::InstancedFirstPassShader>::template expandTex(*mesh, T::FirstPassTextures);
glDrawElementsIndirect(GL_TRIANGLES,
@@ -178,12 +192,12 @@ public:
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
}
} //drawIndirectFirstPass
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirect2ndPass(const std::vector<GLuint> &prefilled_tex,
void drawIndirectSecondPass(const std::vector<GLuint> &prefilled_tex,
Uniforms...uniforms ) const
{
T::InstancedSecondPassShader::getInstance()->use();
@@ -199,10 +213,32 @@ public:
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
}
} //drawIndirectSecondPass
// ----------------------------------------------------------------------------
template<typename T, typename...Uniforms>
void drawIndirectReflectiveShadowMap(Uniforms ...uniforms) const
{
T::InstancedRSMShader::getInstance()->use();
T::InstancedRSMShader::getInstance()->setUniforms(uniforms...);
glBindVertexArray(VAOManager::getInstance()->getInstanceVAO(T::VertexType,
InstanceTypeRSM));
for (unsigned i = 0; i < m_meshes[T::MaterialType].size(); i++)
{
GLMesh *mesh = m_meshes[T::MaterialType][i];
TexExpander<typename T::InstancedRSMShader>::template expandTex(*mesh, T::RSMTextures);
glDrawElementsIndirect(GL_TRIANGLES,
GL_UNSIGNED_SHORT,
(const void*)((m_offset[T::MaterialType] + i) * sizeof(DrawElementsIndirectCommand)));
}
} //drawIndirectReflectiveShadowMap
@@ -232,28 +268,30 @@ public:
class SolidCommandBuffer: public CommandBuffer
class SolidCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADERTYPE_COUNT)>
{
public:
SolidCommandBuffer();
void fill(MeshMap *mesh_map);
};
class ShadowCommandBuffer: public CommandBuffer
class ShadowCommandBuffer: public CommandBuffer<4*static_cast<int>(Material::SHADERTYPE_COUNT)>
{
public:
ShadowCommandBuffer();
void fill(MeshMap *mesh_map);
};
class ReflectiveShadowMapCommandBuffer: public CommandBuffer
class ReflectiveShadowMapCommandBuffer: public CommandBuffer<static_cast<int>(Material::SHADERTYPE_COUNT)>
{
public:
ReflectiveShadowMapCommandBuffer();
void fill(MeshMap *mesh_map);
};
class GlowCommandBuffer: public CommandBuffer
class GlowCommandBuffer: public CommandBuffer<1>
{
public:
GlowCommandBuffer();

View File

@@ -543,7 +543,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
m_solid_cmd_buffer.fill(m_solid_pass_mesh);
}
#pragma omp section
{
{
size_t offset = 0, current_cmd = 0;
if (!CVS->supportsAsyncInstanceUpload())
@@ -578,6 +578,8 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
}
#pragma omp section
{
//m_shadow_cmd_buffer.fill(m_shadow_pass_mesh);
irr_driver->setPhase(SHADOW_PASS);
size_t offset = 0, current_cmd = 0;
@@ -615,7 +617,9 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
#pragma omp section
if (!shadow_matrices.isRSMMapAvail())
{
size_t offset = 0, current_cmd = 0;
m_reflective_shadow_map_cmd_buffer.fill(m_reflective_shadow_map_mesh);
/*size_t offset = 0, current_cmd = 0;
if (!CVS->supportsAsyncInstanceUpload())
{
glBindBuffer(GL_ARRAY_BUFFER, VAOManager::getInstance()->getInstanceBuffer(InstanceTypeRSM));
@@ -649,7 +653,7 @@ void DrawCalls::prepareDrawCalls( ShadowMatrices& shadow_matrices, scene::ICamer
{
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
}
}*/
}
}
PROFILER_POP_CPU_MARKER();
@@ -700,26 +704,34 @@ void DrawCalls::multidrawIndirectSolidCmd(Material::ShaderType shader_type) cons
void DrawCalls::drawIndirectSolidFirstPass() const
{
m_solid_cmd_buffer.drawIndirect<DefaultMaterial>();
m_solid_cmd_buffer.drawIndirect<AlphaRef>();
m_solid_cmd_buffer.drawIndirect<UnlitMat>();
m_solid_cmd_buffer.drawIndirect<SphereMap>();
m_solid_cmd_buffer.drawIndirect<GrassMat>(windDir);
m_solid_cmd_buffer.drawIndirect<DetailMat>();
m_solid_cmd_buffer.drawIndirect<NormalMat>();
m_solid_cmd_buffer.drawIndirectFirstPass<DefaultMaterial>();
m_solid_cmd_buffer.drawIndirectFirstPass<AlphaRef>();
m_solid_cmd_buffer.drawIndirectFirstPass<UnlitMat>();
m_solid_cmd_buffer.drawIndirectFirstPass<SphereMap>();
m_solid_cmd_buffer.drawIndirectFirstPass<GrassMat>(windDir);
m_solid_cmd_buffer.drawIndirectFirstPass<DetailMat>();
m_solid_cmd_buffer.drawIndirectFirstPass<NormalMat>();
}
void DrawCalls::drawIndirectSolidSecondPass(const std::vector<GLuint> &prefilled_tex) const
{
m_solid_cmd_buffer.drawIndirect2ndPass<DefaultMaterial>(prefilled_tex);
m_solid_cmd_buffer.drawIndirect2ndPass<AlphaRef>(prefilled_tex);
m_solid_cmd_buffer.drawIndirect2ndPass<UnlitMat>(prefilled_tex);
m_solid_cmd_buffer.drawIndirect2ndPass<SphereMap>(prefilled_tex);
m_solid_cmd_buffer.drawIndirect2ndPass<GrassMat>(prefilled_tex, windDir, irr_driver->getSunDirection());
m_solid_cmd_buffer.drawIndirect2ndPass<DetailMat>(prefilled_tex);
m_solid_cmd_buffer.drawIndirect2ndPass<NormalMat>(prefilled_tex);
m_solid_cmd_buffer.drawIndirectSecondPass<DefaultMaterial>(prefilled_tex);
m_solid_cmd_buffer.drawIndirectSecondPass<AlphaRef>(prefilled_tex);
m_solid_cmd_buffer.drawIndirectSecondPass<UnlitMat>(prefilled_tex);
m_solid_cmd_buffer.drawIndirectSecondPass<SphereMap>(prefilled_tex);
m_solid_cmd_buffer.drawIndirectSecondPass<GrassMat>(prefilled_tex, windDir, irr_driver->getSunDirection());
m_solid_cmd_buffer.drawIndirectSecondPass<DetailMat>(prefilled_tex);
m_solid_cmd_buffer.drawIndirectSecondPass<NormalMat>(prefilled_tex);
}
void DrawCalls::drawIndirectReflectiveShadowMaps(const core::matrix4 &rsm_matrix) const
{
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<DefaultMaterial>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<AlphaRef>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<UnlitMat>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<NormalMat>(rsm_matrix);
m_reflective_shadow_map_cmd_buffer.drawIndirectReflectiveShadowMap<DetailMat>(rsm_matrix);
}

View File

@@ -98,6 +98,10 @@ public:
void renderParticlesList() const;
inline void bindSolidCmd() const { m_solid_cmd_buffer.bind(); }
inline void bindReflectiveShadowMapsCmd() const { m_reflective_shadow_map_cmd_buffer.bind(); }
inline bool isSolidCmdEmpty(Material::ShaderType shader_type) const
{ return m_solid_cmd_buffer.isEmpty(shader_type); }
void drawIndirectSolidCmd(Material::ShaderType shader_type, int i) const;
@@ -106,6 +110,9 @@ public:
void drawIndirectSolidFirstPass() const;
//void multidrawIndirectSolidCmd() const; //TODO
void drawIndirectSolidSecondPass(const std::vector<GLuint> &prefilled_tex) const;
void drawIndirectReflectiveShadowMaps(const core::matrix4 &rsm_matrix) const;
};
#endif //HEADER_DRAW_CALLS_HPP

View File

@@ -852,7 +852,8 @@ void multidrawRSM(Args...args)
} // multidrawRSM
// ----------------------------------------------------------------------------
void GeometryPasses::renderReflectiveShadowMap(const ShadowMatrices& shadow_matrices,
void GeometryPasses::renderReflectiveShadowMap(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices,
const FrameBuffer& reflective_shadow_map_framebuffer)
{
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_RSM));
@@ -868,8 +869,7 @@ void GeometryPasses::renderReflectiveShadowMap(const ShadowMatrices& shadow_matr
drawRSM<SplattingMat, 1>(rsm_matrix);
if (CVS->supportsIndirectInstancingRendering())
glBindBuffer(GL_DRAW_INDIRECT_BUFFER,
RSMPassCmd::getInstance()->drawindirectcmd);
draw_calls.bindReflectiveShadowMapsCmd();
if (CVS->isAZDOEnabled())
{
@@ -881,10 +881,6 @@ void GeometryPasses::renderReflectiveShadowMap(const ShadowMatrices& shadow_matr
}
else if (CVS->supportsIndirectInstancingRendering())
{
renderRSMShadow<DefaultMaterial>(rsm_matrix);
renderRSMShadow<AlphaRef>(rsm_matrix);
renderRSMShadow<UnlitMat>(rsm_matrix);
renderRSMShadow<NormalMat>(rsm_matrix);
renderRSMShadow<DetailMat>(rsm_matrix);
draw_calls.drawIndirectReflectiveShadowMaps(rsm_matrix);
}
} // renderRSM

View File

@@ -44,7 +44,8 @@ public:
unsigned render_target);
void renderShadows(const ShadowMatrices& shadow_matrices,
const FrameBuffer& shadow_framebuffer);
void renderReflectiveShadowMap(const ShadowMatrices& shadow_matrices,
void renderReflectiveShadowMap(const DrawCalls& draw_calls,
const ShadowMatrices& shadow_matrices,
const FrameBuffer& reflective_shadow_map_framebuffer);

View File

@@ -191,7 +191,8 @@ void ShaderBasedRenderer::renderScene(scene::ICameraSceneNode * const camnode,
if (!m_shadow_matrices.isRSMMapAvail())
{
PROFILER_PUSH_CPU_MARKER("- RSM", 0xFF, 0x0, 0xFF);
m_geometry_passes.renderReflectiveShadowMap(m_shadow_matrices,
m_geometry_passes.renderReflectiveShadowMap(m_draw_calls,
m_shadow_matrices,
irr_driver->getRTT()->getReflectiveShadowMapFrameBuffer()); //TODO: move somewhere else as RSM are computed only once per track
m_shadow_matrices.setRSMMapAvail(true);
PROFILER_POP_CPU_MARKER();