- refactored main vertex buffer (but didn't merge with hwrender class yet.

This commit is contained in:
Christoph Oelckers 2018-10-27 14:24:47 +02:00
parent 332ab220ad
commit 72bc7693bd
11 changed files with 102 additions and 155 deletions

View File

@ -29,6 +29,7 @@
#include "doomtype.h" #include "doomtype.h"
#include "p_local.h" #include "p_local.h"
#include "r_state.h" #include "r_state.h"
#include "cmdlib.h"
#include "gl_load/gl_interface.h" #include "gl_load/gl_interface.h"
#include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderer.h"
#include "gl/shaders/gl_shader.h" #include "gl/shaders/gl_shader.h"
@ -122,94 +123,50 @@ void FSkyVertexBuffer::BindVBO()
//========================================================================== //==========================================================================
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
: FVertexBuffer(true), FFlatVertexGenerator(width, height) : FFlatVertexGenerator(width, height)
{ {
mPersistent = screen->BuffersArePersistent(); mVertexBuffer = screen->CreateVertexBuffer();
ibo_id = 0; mIndexBuffer = screen->CreateIndexBuffer();
glGenBuffers(1, &ibo_id);
if (mPersistent) unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
{ mVertexBuffer->SetData(bytesize, nullptr, false);
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); static const FVertexBufferAttribute format[] = {
glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); { 0, VATTR_VERTEX, VFmt_Float3, myoffsetof(FFlatVertex, x) },
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); { 0, VATTR_TEXCOORD, VFmt_Float2, myoffsetof(FFlatVertex, u) }
DPrintf(DMSG_NOTIFY, "Using persistent buffer\n"); };
} mVertexBuffer->SetFormat(1, 2, sizeof(FFlatVertex), format);
else
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW);
map = nullptr;
DPrintf(DMSG_NOTIFY, "Using deferred buffer\n");
}
mIndex = mCurIndex = 0; mIndex = mCurIndex = 0;
mNumReserved = NUM_RESERVED; mNumReserved = NUM_RESERVED;
Copy(0, NUM_RESERVED);
mMap = map;
Map();
memcpy(map, &vbo_shadowdata[0], mNumReserved * sizeof(FFlatVertex));
Unmap();
} }
FFlatVertexBuffer::~FFlatVertexBuffer() FFlatVertexBuffer::~FFlatVertexBuffer()
{ {
if (vbo_id != 0) delete mIndexBuffer;
{ delete mVertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); mIndexBuffer = nullptr;
glUnmapBuffer(GL_ARRAY_BUFFER); mVertexBuffer = nullptr;
glBindBuffer(GL_ARRAY_BUFFER, 0); }
}
if (ibo_id != 0) void FFlatVertexBuffer::Copy(int start, int count)
{ {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); Map();
glDeleteBuffers(1, &ibo_id); memcpy(GetBuffer(start), &vbo_shadowdata[0], count * sizeof(FFlatVertex));
} Unmap();
map = nullptr;
} }
void FFlatVertexBuffer::OutputResized(int width, int height) void FFlatVertexBuffer::OutputResized(int width, int height)
{ {
FFlatVertexGenerator::OutputResized(width, height); FFlatVertexGenerator::OutputResized(width, height);
Map(); Copy(4, 4);
memcpy(&map[4], &vbo_shadowdata[4], 4 * sizeof(FFlatVertex));
Unmap();
} }
void FFlatVertexBuffer::BindVBO() void FFlatVertexBuffer::Bind(FRenderState &state)
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); state.SetVertexBuffer(mVertexBuffer, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); state.SetIndexBuffer(mIndexBuffer);
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glDisableVertexAttribArray(VATTR_COLOR);
glDisableVertexAttribArray(VATTR_VERTEX2);
glDisableVertexAttribArray(VATTR_NORMAL);
}
void FFlatVertexBuffer::Map()
{
if (!mPersistent)
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
gl_RenderState.ResetVertexBuffer();
mMap = map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
}
}
void FFlatVertexBuffer::Unmap()
{
if (!mPersistent)
{
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
gl_RenderState.ResetVertexBuffer();
glUnmapBuffer(GL_ARRAY_BUFFER);
mMap = map = nullptr;
}
} }
//========================================================================== //==========================================================================
@ -223,12 +180,6 @@ void FFlatVertexBuffer::CreateVBO()
vbo_shadowdata.Resize(mNumReserved); vbo_shadowdata.Resize(mNumReserved);
FFlatVertexGenerator::CreateVertices(); FFlatVertexGenerator::CreateVertices();
mCurIndex = mIndex = vbo_shadowdata.Size(); mCurIndex = mIndex = vbo_shadowdata.Size();
Map(); Copy(0, mIndex);
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); mIndexBuffer->SetData(ibo_data.Size() * sizeof(uint32_t), &ibo_data[0]);
Unmap();
if (ibo_id > 0)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibo_data.Size() * sizeof(uint32_t), &ibo_data[0], GL_STATIC_DRAW);
}
} }

View File

@ -39,6 +39,7 @@ struct secplane_t;
struct subsector_t; struct subsector_t;
struct sector_t; struct sector_t;
class FMaterial; class FMaterial;
class FRenderState;
@ -83,36 +84,42 @@ public:
void BindVBO(); void BindVBO();
void set(FSimpleVertex *verts, int count); void set(FSimpleVertex *verts, int count);
void EnableColorArray(bool on); void EnableColorArray(bool on);
}; };
class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator class FFlatVertexBuffer : public FFlatVertexGenerator
{ {
unsigned int ibo_id; IVertexBuffer *mVertexBuffer;
FFlatVertex *map; IIndexBuffer *mIndexBuffer;
unsigned int mIndex; unsigned int mIndex;
std::atomic<unsigned int> mCurIndex; std::atomic<unsigned int> mCurIndex;
std::mutex mBufferMutex; std::mutex mBufferMutex;
unsigned int mNumReserved; unsigned int mNumReserved;
bool mPersistent;
static const unsigned int BUFFER_SIZE = 2000000; static const unsigned int BUFFER_SIZE = 2000000;
static const unsigned int BUFFER_SIZE_TO_USE = 1999500; static const unsigned int BUFFER_SIZE_TO_USE = 1999500;
public: public:
FFlatVertexBuffer(int width, int height); FFlatVertexBuffer(int width, int height);
~FFlatVertexBuffer(); ~FFlatVertexBuffer();
void OutputResized(int width, int height); void OutputResized(int width, int height);
void Bind(FRenderState &state);
void BindVBO();
void CreateVBO(); void CreateVBO();
void Copy(int start, int count);
FFlatVertex *GetBuffer() FFlatVertex *GetBuffer(int index) const
{ {
return &map[mCurIndex]; FFlatVertex *ff = (FFlatVertex*)mVertexBuffer->Memory();
return &ff[index];
}
FFlatVertex *GetBuffer() const
{
return GetBuffer(mCurIndex);
} }
template<class T> template<class T>
@ -133,46 +140,22 @@ public:
return p; return p;
} }
unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset)
{
unsigned int newofs = (unsigned int)(newptr - map);
unsigned int diff = newofs - mCurIndex;
*poffset = mCurIndex;
mCurIndex = newofs;
if (mCurIndex >= BUFFER_SIZE_TO_USE) mCurIndex = mIndex;
return diff;
}
#ifdef __GL_PCH_H // we need the system includes for this but we cannot include them ourselves without creating #define clashes. The affected files wouldn't try to draw anyway.
void RenderArray(unsigned int primtype, unsigned int offset, unsigned int count)
{
drawcalls.Clock();
glDrawArrays(primtype, offset, count);
drawcalls.Unclock();
}
void RenderCurrent(FFlatVertex *newptr, unsigned int primtype, unsigned int *poffset = NULL, unsigned int *pcount = NULL)
{
unsigned int offset;
unsigned int count = GetCount(newptr, &offset);
RenderArray(primtype, offset, count);
if (poffset) *poffset = offset;
if (pcount) *pcount = count;
}
#endif
uint32_t *GetIndexPointer() const
{
return ibo_id == 0 ? &ibo_data[0] : nullptr;
}
void Reset() void Reset()
{ {
mCurIndex = mIndex; mCurIndex = mIndex;
} }
void Map(); void Map()
void Unmap(); {
mVertexBuffer->Map();
mMap = GetBuffer(0);
}
void Unmap()
{
mMap = nullptr;
mVertexBuffer->Unmap();
}
}; };

View File

@ -118,7 +118,7 @@ void FGLModelRenderer::SetVertexBuffer(IModelVertexBuffer *buffer)
void FGLModelRenderer::ResetVertexBuffer() void FGLModelRenderer::ResetVertexBuffer()
{ {
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); GLRenderer->mVBO->Bind(gl_RenderState);
} }
void FGLModelRenderer::SetInterpolation(double inter) void FGLModelRenderer::SetInterpolation(double inter)
@ -130,9 +130,8 @@ void FGLModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int trans
{ {
FMaterial * tex = FMaterial::ValidateTexture(skin, false); FMaterial * tex = FMaterial::ValidateTexture(skin, false);
gl_RenderState.ApplyMaterial(tex, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); gl_RenderState.ApplyMaterial(tex, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1);
/*if (modellightindex != -1)*/ gl_RenderState.SetLightIndex(modellightindex);
gl_RenderState.Apply(); gl_RenderState.Apply();
if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex);
} }
void FGLModelRenderer::DrawArrays(int start, int count) void FGLModelRenderer::DrawArrays(int start, int count)

View File

@ -52,9 +52,9 @@ CVAR(Int, gl_dither_bpc, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
void FGLRenderer::RenderScreenQuad() void FGLRenderer::RenderScreenQuad()
{ {
mVBO->BindVBO(); mVBO->Bind(gl_RenderState);
gl_RenderState.ResetVertexBuffer(); gl_RenderState.ApplyBuffers();
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4);
} }
void FGLRenderer::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) void FGLRenderer::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)

View File

@ -103,7 +103,7 @@ void FGLRenderer::Initialize(int width, int height)
mSkyVBO = new FSkyVertexBuffer; mSkyVBO = new FSkyVertexBuffer;
mLights = new FLightBuffer(); mLights = new FLightBuffer();
mViewpoints = new GLViewpointBuffer; mViewpoints = new GLViewpointBuffer;
gl_RenderState.SetVertexBuffer(mVBO); GLRenderer->mVBO->Bind(gl_RenderState);
mFBID = 0; mFBID = 0;
mOldFBID = 0; mOldFBID = 0;
@ -197,7 +197,7 @@ void FGLRenderer::EndOffscreen()
sector_t *FGLRenderer::RenderView(player_t* player) sector_t *FGLRenderer::RenderView(player_t* player)
{ {
gl_RenderState.SetVertexBuffer(mVBO); GLRenderer->mVBO->Bind(gl_RenderState);
mVBO->Reset(); mVBO->Reset();
sector_t *retsec; sector_t *retsec;
@ -319,8 +319,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
mBuffers = mSaveBuffers; mBuffers = mSaveBuffers;
P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector. P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector.
gl_RenderState.SetVertexBuffer(mVBO); GLRenderer->mVBO->Bind(gl_RenderState);
mVBO->Reset(); mVBO->Reset();
mLights->Clear(); mLights->Clear();
mViewpoints->Clear(); mViewpoints->Clear();
@ -537,7 +537,7 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
gl_RenderState.SetRenderStyle(STYLE_Translucent); gl_RenderState.SetRenderStyle(STYLE_Translucent);
gl_RenderState.SetVertexBuffer(mVBO); GLRenderer->mVBO->Bind(gl_RenderState);
gl_RenderState.EnableTexture(true); gl_RenderState.EnableTexture(true);
gl_RenderState.EnableBrightmap(true); gl_RenderState.EnableBrightmap(true);
gl_RenderState.SetTextureMode(TM_NORMAL); gl_RenderState.SetTextureMode(TM_NORMAL);

View File

@ -199,6 +199,14 @@ bool FGLRenderState::ApplyShader()
matrixToGL(identityMatrix, activeShader->modelmatrix_index); matrixToGL(identityMatrix, activeShader->modelmatrix_index);
matrixToGL(identityMatrix, activeShader->normalmodelmatrix_index); matrixToGL(identityMatrix, activeShader->normalmodelmatrix_index);
} }
auto index = mLightIndex;
if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER)
{
index = GLRenderer->mLights->BindUBO(index);
}
activeShader->muLightIndex.Set(index);
return true; return true;
} }
@ -209,7 +217,7 @@ bool FGLRenderState::ApplyShader()
// //
//========================================================================== //==========================================================================
void FGLRenderState::Apply() void FGLRenderState::ApplyState()
{ {
if (mRenderStyle != stRenderStyle) if (mRenderStyle != stRenderStyle)
{ {
@ -251,7 +259,10 @@ void FGLRenderState::Apply()
glPolygonOffset(mBias.mFactor, mBias.mUnits); glPolygonOffset(mBias.mFactor, mBias.mUnits);
mBias.mChanged = false; mBias.mChanged = false;
} }
}
void FGLRenderState::ApplyBuffers()
{
if (mVertexBuffer != nullptr) if (mVertexBuffer != nullptr)
{ {
if (mVertexBuffer != mCurrentVertexBuffer || mVertexOffsets[0] != mCurrentVertexOffsets[0] || mVertexOffsets[1] != mCurrentVertexOffsets[1]) if (mVertexBuffer != mCurrentVertexBuffer || mVertexOffsets[0] != mCurrentVertexOffsets[0] || mVertexOffsets[1] != mCurrentVertexOffsets[1])
@ -261,6 +272,12 @@ void FGLRenderState::Apply()
mCurrentVertexBuffer = mVertexBuffer; mCurrentVertexBuffer = mVertexBuffer;
mCurrentVertexOffsets[0] = mVertexOffsets[0]; mCurrentVertexOffsets[0] = mVertexOffsets[0];
mCurrentVertexOffsets[1] = mVertexOffsets[1]; mCurrentVertexOffsets[1] = mVertexOffsets[1];
mCurrentFVertexBuffer = nullptr;
}
if (mIndexBuffer != mCurrentIndexBuffer)
{
static_cast<GLIndexBuffer*>(mIndexBuffer)->Bind();
mCurrentIndexBuffer = mIndexBuffer;
} }
} }
else if (mFVertexBuffer != mCurrentFVertexBuffer) else if (mFVertexBuffer != mCurrentFVertexBuffer)
@ -268,20 +285,16 @@ void FGLRenderState::Apply()
if (mFVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0); if (mFVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0);
else mFVertexBuffer->BindVBO(); else mFVertexBuffer->BindVBO();
mCurrentFVertexBuffer = mFVertexBuffer; mCurrentFVertexBuffer = mFVertexBuffer;
mCurrentVertexBuffer = nullptr;
mCurrentIndexBuffer = nullptr;
} }
ApplyShader();
} }
void FGLRenderState::Apply()
void FGLRenderState::ApplyLightIndex(int index)
{ {
if (index == -2) index = mLightIndex; // temporary workaround so that both old and new code can be handled. ApplyState();
if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER) ApplyBuffers();
{ ApplyShader();
index = GLRenderer->mLights->BindUBO(index);
}
activeShader->muLightIndex.Set(index);
} }
//=========================================================================== //===========================================================================
@ -382,5 +395,6 @@ void FGLRenderState::ApplyBlendMode()
// Needs to be redone // Needs to be redone
void FGLRenderState::SetVertexBuffer(int which) void FGLRenderState::SetVertexBuffer(int which)
{ {
SetVertexBuffer(which == VB_Sky ? (FVertexBuffer*)GLRenderer->mSkyVBO : GLRenderer->mVBO); if (which == VB_Sky) SetVertexBuffer(GLRenderer->mSkyVBO);
else GLRenderer->mVBO->Bind(*this);
} }

View File

@ -73,6 +73,7 @@ class FGLRenderState : public FRenderState
int mNumDrawBuffers = 1; int mNumDrawBuffers = 1;
bool ApplyShader(); bool ApplyShader();
void ApplyState();
// Texture binding state // Texture binding state
FMaterial *lastMaterial = nullptr; FMaterial *lastMaterial = nullptr;
@ -102,6 +103,7 @@ public:
void ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader); void ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader);
void Apply(); void Apply();
void ApplyBuffers();
void ApplyLightIndex(int index); void ApplyLightIndex(int index);
void ApplyBlendMode(); void ApplyBlendMode();

View File

@ -220,7 +220,6 @@ void FDrawInfo::Draw(EDrawType dt, FRenderState &state, int index, int count, bo
if (apply) if (apply)
{ {
gl_RenderState.Apply(); gl_RenderState.Apply();
gl_RenderState.ApplyLightIndex(-2);
} }
drawcalls.Clock(); drawcalls.Clock();
glDrawArrays(dt2gl[dt], index, count); glDrawArrays(dt2gl[dt], index, count);
@ -233,10 +232,9 @@ void FDrawInfo::DrawIndexed(EDrawType dt, FRenderState &state, int index, int co
if (apply) if (apply)
{ {
gl_RenderState.Apply(); gl_RenderState.Apply();
gl_RenderState.ApplyLightIndex(-2);
} }
drawcalls.Clock(); drawcalls.Clock();
glDrawElements(dt2gl[dt], count, GL_UNSIGNED_INT, GLRenderer->mVBO->GetIndexPointer() + index); glDrawElements(dt2gl[dt], count, GL_UNSIGNED_INT, (void*)(intptr_t)(index * sizeof(uint32_t)));
drawcalls.Unclock(); drawcalls.Unclock();
} }

View File

@ -102,7 +102,7 @@ void GLVertexBuffer::Unmap()
} }
} }
void GLVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, FVertexBufferAttribute *attrs) void GLVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs)
{ {
static int VFmtToGLFmt[] = { GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT_2_10_10_10_REV }; static int VFmtToGLFmt[] = { GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT_2_10_10_10_REV };
static uint8_t VFmtToSize[] = {4, 3, 2, 1, 4, 4}; static uint8_t VFmtToSize[] = {4, 3, 2, 1, 4, 4};

View File

@ -23,7 +23,7 @@ public:
GLVertexBuffer(); GLVertexBuffer();
~GLVertexBuffer(); ~GLVertexBuffer();
void SetData(size_t size, void *data, bool staticdata) override; void SetData(size_t size, void *data, bool staticdata) override;
void SetFormat(int numBindingPoints, int numAttributes, size_t stride, FVertexBufferAttribute *attrs) override; void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override;
void Bind(int *offsets); void Bind(int *offsets);
void Map() override; void Map() override;
void Unmap() override; void Unmap() override;

View File

@ -42,7 +42,7 @@ protected:
public: public:
virtual ~IVertexBuffer() {} virtual ~IVertexBuffer() {}
virtual void SetData(size_t size, void *data, bool staticdata = true) = 0; virtual void SetData(size_t size, void *data, bool staticdata = true) = 0;
virtual void SetFormat(int numBindingPoints, int numAttributes, size_t stride, FVertexBufferAttribute *attrs) = 0; virtual void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) = 0;
virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface. virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface.
virtual void Unmap() {} virtual void Unmap() {}
void *Memory() { assert(map); return map; } void *Memory() { assert(map); return map; }