Optimized Buffer locking/filling
Former-commit-id: 41cb66257f3eeef375086bf51f26230a06ca9eb8
This commit is contained in:
parent
aa67a52e9c
commit
9f780ef2bd
|
|
@ -30,7 +30,7 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable
|
|||
bool Create(unsigned int length, nzUInt8 typeSize, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
void Destroy();
|
||||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int length);
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard = false);
|
||||
|
||||
NzBufferImpl* GetImpl() const;
|
||||
unsigned int GetLength() const;
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class NAZARA_API NzBufferImpl
|
|||
virtual bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static) = 0;
|
||||
virtual void Destroy() = 0;
|
||||
|
||||
virtual bool Fill(const void* data, unsigned int offset, unsigned int size) = 0;
|
||||
virtual bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false) = 0;
|
||||
|
||||
virtual void* GetPointer() = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/HardwareBuffer.hpp>
|
||||
#include <Nazara/Core/Clock.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
|
|
@ -105,29 +106,32 @@ void NzHardwareBuffer::Destroy()
|
|||
glDeleteBuffers(1, &m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
|
||||
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
unsigned int totalSize = m_parent->GetSize();
|
||||
|
||||
if (!forceDiscard)
|
||||
forceDiscard = (size == totalSize);
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (forceDiscard)
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], totalSize, nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
// Il semblerait que glBuffer(Sub)Data soit plus performant que glMapBuffer(Range) en dessous d'un certain seuil
|
||||
// http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/
|
||||
if (size < 32*1024)
|
||||
{
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (size == m_parent->GetSize())
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], size, nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
glBufferSubData(NzOpenGL::BufferTarget[m_type], offset, size, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
||||
nzUInt8* ptr = mapBuffer(m_type, (forceDiscard) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
|
|
@ -141,7 +145,7 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
|
|||
// Une erreur rare est survenue, nous devons réinitialiser le buffer
|
||||
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
|
||||
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], totalSize, nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -175,6 +179,9 @@ void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
|
|||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
|
||||
if (access == nzBufferAccess_DiscardAndWrite)
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
void* ptr = mapBuffer(m_type, access, offset, size);
|
||||
|
||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class NzHardwareBuffer : public NzBufferImpl
|
|||
bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
void Destroy();
|
||||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size);
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard);
|
||||
|
||||
void* GetPointer();
|
||||
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ void NzRenderer::FillInstancingBuffer(const NzRenderer::InstancingData* instanci
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!s_instancingBuffer->Fill(instancingData, 0, instanceCount))
|
||||
if (!s_instancingBuffer->Fill(instancingData, 0, instanceCount, true))
|
||||
NazaraError("Failed to fill instancing buffer");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void NzBuffer::Destroy()
|
|||
}
|
||||
}
|
||||
|
||||
bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
|
||||
bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length, bool forceDiscard)
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (!m_impl)
|
||||
|
|
@ -133,7 +133,7 @@ bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int length)
|
|||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize);
|
||||
return m_impl->Fill(data, offset*m_typeSize, ((length == 0) ? m_length-offset : length)*m_typeSize, forceDiscard);
|
||||
}
|
||||
|
||||
NzBufferImpl* NzBuffer::GetImpl() const
|
||||
|
|
|
|||
|
|
@ -44,8 +44,10 @@ void NzSoftwareBuffer::Destroy()
|
|||
delete[] m_buffer;
|
||||
}
|
||||
|
||||
bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
|
||||
bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard)
|
||||
{
|
||||
NazaraUnused(forceDiscard);
|
||||
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (m_mapped)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class NzSoftwareBuffer : public NzBufferImpl
|
|||
bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static);
|
||||
void Destroy();
|
||||
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size);
|
||||
bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard);
|
||||
|
||||
void* GetPointer();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue