From 72bc7693bddf7729458d3719137d5e0eb980dc7b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 27 Oct 2018 14:24:47 +0200 Subject: [PATCH] - refactored main vertex buffer (but didn't merge with hwrender class yet. --- src/gl/data/gl_vertexbuffer.cpp | 113 ++++++++------------------- src/gl/data/gl_vertexbuffer.h | 73 +++++++---------- src/gl/models/gl_models.cpp | 5 +- src/gl/renderer/gl_postprocess.cpp | 6 +- src/gl/renderer/gl_renderer.cpp | 10 +-- src/gl/renderer/gl_renderstate.cpp | 38 ++++++--- src/gl/renderer/gl_renderstate.h | 2 + src/gl/scene/gl_drawinfo.cpp | 4 +- src/gl/system/glsys_vertexbuffer.cpp | 2 +- src/gl/system/glsys_vertexbuffer.h | 2 +- src/hwrenderer/data/vertexbuffer.h | 2 +- 11 files changed, 102 insertions(+), 155 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index dfe55cf50..9fc8a0825 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -29,6 +29,7 @@ #include "doomtype.h" #include "p_local.h" #include "r_state.h" +#include "cmdlib.h" #include "gl_load/gl_interface.h" #include "gl/renderer/gl_renderer.h" #include "gl/shaders/gl_shader.h" @@ -122,94 +123,50 @@ void FSkyVertexBuffer::BindVBO() //========================================================================== FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) -: FVertexBuffer(true), FFlatVertexGenerator(width, height) +: FFlatVertexGenerator(width, height) { - mPersistent = screen->BuffersArePersistent(); - ibo_id = 0; - glGenBuffers(1, &ibo_id); - if (mPersistent) - { - unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); - DPrintf(DMSG_NOTIFY, "Using persistent buffer\n"); - } - 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"); - } + mVertexBuffer = screen->CreateVertexBuffer(); + mIndexBuffer = screen->CreateIndexBuffer(); + + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + mVertexBuffer->SetData(bytesize, nullptr, false); + + static const FVertexBufferAttribute format[] = { + { 0, VATTR_VERTEX, VFmt_Float3, myoffsetof(FFlatVertex, x) }, + { 0, VATTR_TEXCOORD, VFmt_Float2, myoffsetof(FFlatVertex, u) } + }; + mVertexBuffer->SetFormat(1, 2, sizeof(FFlatVertex), format); + mIndex = mCurIndex = 0; mNumReserved = NUM_RESERVED; - - mMap = map; - Map(); - memcpy(map, &vbo_shadowdata[0], mNumReserved * sizeof(FFlatVertex)); - Unmap(); + Copy(0, NUM_RESERVED); } FFlatVertexBuffer::~FFlatVertexBuffer() { - if (vbo_id != 0) - { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - if (ibo_id != 0) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDeleteBuffers(1, &ibo_id); - } - map = nullptr; + delete mIndexBuffer; + delete mVertexBuffer; + mIndexBuffer = nullptr; + mVertexBuffer = nullptr; +} + +void FFlatVertexBuffer::Copy(int start, int count) +{ + Map(); + memcpy(GetBuffer(start), &vbo_shadowdata[0], count * sizeof(FFlatVertex)); + Unmap(); } void FFlatVertexBuffer::OutputResized(int width, int height) { FFlatVertexGenerator::OutputResized(width, height); - Map(); - memcpy(&map[4], &vbo_shadowdata[4], 4 * sizeof(FFlatVertex)); - Unmap(); + Copy(4, 4); } -void FFlatVertexBuffer::BindVBO() +void FFlatVertexBuffer::Bind(FRenderState &state) { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); - 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; - } + state.SetVertexBuffer(mVertexBuffer, 0, 0); + state.SetIndexBuffer(mIndexBuffer); } //========================================================================== @@ -223,12 +180,6 @@ void FFlatVertexBuffer::CreateVBO() vbo_shadowdata.Resize(mNumReserved); FFlatVertexGenerator::CreateVertices(); mCurIndex = mIndex = vbo_shadowdata.Size(); - Map(); - memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); - 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); - } + Copy(0, mIndex); + mIndexBuffer->SetData(ibo_data.Size() * sizeof(uint32_t), &ibo_data[0]); } diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 7316585e2..35615bf6d 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -39,6 +39,7 @@ struct secplane_t; struct subsector_t; struct sector_t; class FMaterial; +class FRenderState; @@ -83,36 +84,42 @@ public: void BindVBO(); void set(FSimpleVertex *verts, int count); void EnableColorArray(bool on); -}; +}; -class FFlatVertexBuffer : public FVertexBuffer, public FFlatVertexGenerator +class FFlatVertexBuffer : public FFlatVertexGenerator { - unsigned int ibo_id; - FFlatVertex *map; + IVertexBuffer *mVertexBuffer; + IIndexBuffer *mIndexBuffer; + unsigned int mIndex; std::atomic mCurIndex; std::mutex mBufferMutex; unsigned int mNumReserved; - bool mPersistent; static const unsigned int BUFFER_SIZE = 2000000; static const unsigned int BUFFER_SIZE_TO_USE = 1999500; + public: FFlatVertexBuffer(int width, int height); ~FFlatVertexBuffer(); void OutputResized(int width, int height); - - void BindVBO(); - + void Bind(FRenderState &state); 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 @@ -133,46 +140,22 @@ public: 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() { mCurIndex = mIndex; } - void Map(); - void Unmap(); + void Map() + { + mVertexBuffer->Map(); + mMap = GetBuffer(0); + } + + void Unmap() + { + mMap = nullptr; + mVertexBuffer->Unmap(); + } }; diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index fd0f02dfc..48ad733da 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -118,7 +118,7 @@ void FGLModelRenderer::SetVertexBuffer(IModelVertexBuffer *buffer) void FGLModelRenderer::ResetVertexBuffer() { - gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); + GLRenderer->mVBO->Bind(gl_RenderState); } void FGLModelRenderer::SetInterpolation(double inter) @@ -130,9 +130,8 @@ void FGLModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int trans { FMaterial * tex = FMaterial::ValidateTexture(skin, false); gl_RenderState.ApplyMaterial(tex, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1); - + /*if (modellightindex != -1)*/ gl_RenderState.SetLightIndex(modellightindex); gl_RenderState.Apply(); - if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex); } void FGLModelRenderer::DrawArrays(int start, int count) diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 09d859dc1..737c6d6ce 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -52,9 +52,9 @@ CVAR(Int, gl_dither_bpc, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) void FGLRenderer::RenderScreenQuad() { - mVBO->BindVBO(); - gl_RenderState.ResetVertexBuffer(); - GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); + mVBO->Bind(gl_RenderState); + gl_RenderState.ApplyBuffers(); + glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); } void FGLRenderer::PostProcessScene(int fixedcm, const std::function &afterBloomDrawEndScene2D) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index b8b09c772..1d43e1fb4 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -103,7 +103,7 @@ void FGLRenderer::Initialize(int width, int height) mSkyVBO = new FSkyVertexBuffer; mLights = new FLightBuffer(); mViewpoints = new GLViewpointBuffer; - gl_RenderState.SetVertexBuffer(mVBO); + GLRenderer->mVBO->Bind(gl_RenderState); mFBID = 0; mOldFBID = 0; @@ -197,7 +197,7 @@ void FGLRenderer::EndOffscreen() sector_t *FGLRenderer::RenderView(player_t* player) { - gl_RenderState.SetVertexBuffer(mVBO); + GLRenderer->mVBO->Bind(gl_RenderState); mVBO->Reset(); sector_t *retsec; @@ -319,8 +319,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i mBuffers = mSaveBuffers; P_FindParticleSubsectors(); // make sure that all recently spawned particles have a valid subsector. - gl_RenderState.SetVertexBuffer(mVBO); - mVBO->Reset(); + GLRenderer->mVBO->Bind(gl_RenderState); + mVBO->Reset(); mLights->Clear(); mViewpoints->Clear(); @@ -537,7 +537,7 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer) glDisable(GL_SCISSOR_TEST); gl_RenderState.SetRenderStyle(STYLE_Translucent); - gl_RenderState.SetVertexBuffer(mVBO); + GLRenderer->mVBO->Bind(gl_RenderState); gl_RenderState.EnableTexture(true); gl_RenderState.EnableBrightmap(true); gl_RenderState.SetTextureMode(TM_NORMAL); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index f14edb68f..f9198d3fb 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -199,6 +199,14 @@ bool FGLRenderState::ApplyShader() matrixToGL(identityMatrix, activeShader->modelmatrix_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; } @@ -209,7 +217,7 @@ bool FGLRenderState::ApplyShader() // //========================================================================== -void FGLRenderState::Apply() +void FGLRenderState::ApplyState() { if (mRenderStyle != stRenderStyle) { @@ -251,7 +259,10 @@ void FGLRenderState::Apply() glPolygonOffset(mBias.mFactor, mBias.mUnits); mBias.mChanged = false; } +} +void FGLRenderState::ApplyBuffers() +{ if (mVertexBuffer != nullptr) { if (mVertexBuffer != mCurrentVertexBuffer || mVertexOffsets[0] != mCurrentVertexOffsets[0] || mVertexOffsets[1] != mCurrentVertexOffsets[1]) @@ -261,6 +272,12 @@ void FGLRenderState::Apply() mCurrentVertexBuffer = mVertexBuffer; mCurrentVertexOffsets[0] = mVertexOffsets[0]; mCurrentVertexOffsets[1] = mVertexOffsets[1]; + mCurrentFVertexBuffer = nullptr; + } + if (mIndexBuffer != mCurrentIndexBuffer) + { + static_cast(mIndexBuffer)->Bind(); + mCurrentIndexBuffer = mIndexBuffer; } } else if (mFVertexBuffer != mCurrentFVertexBuffer) @@ -268,20 +285,16 @@ void FGLRenderState::Apply() if (mFVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0); else mFVertexBuffer->BindVBO(); mCurrentFVertexBuffer = mFVertexBuffer; + mCurrentVertexBuffer = nullptr; + mCurrentIndexBuffer = nullptr; } - ApplyShader(); } - - -void FGLRenderState::ApplyLightIndex(int index) +void FGLRenderState::Apply() { - if (index == -2) index = mLightIndex; // temporary workaround so that both old and new code can be handled. - if (index > -1 && GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER) - { - index = GLRenderer->mLights->BindUBO(index); - } - activeShader->muLightIndex.Set(index); + ApplyState(); + ApplyBuffers(); + ApplyShader(); } //=========================================================================== @@ -382,5 +395,6 @@ void FGLRenderState::ApplyBlendMode() // Needs to be redone 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); } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 9cb4bd60c..31c605cf8 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -73,6 +73,7 @@ class FGLRenderState : public FRenderState int mNumDrawBuffers = 1; bool ApplyShader(); + void ApplyState(); // Texture binding state FMaterial *lastMaterial = nullptr; @@ -102,6 +103,7 @@ public: void ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader); void Apply(); + void ApplyBuffers(); void ApplyLightIndex(int index); void ApplyBlendMode(); diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 82359533a..c7eda62f6 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -220,7 +220,6 @@ void FDrawInfo::Draw(EDrawType dt, FRenderState &state, int index, int count, bo if (apply) { gl_RenderState.Apply(); - gl_RenderState.ApplyLightIndex(-2); } drawcalls.Clock(); glDrawArrays(dt2gl[dt], index, count); @@ -233,10 +232,9 @@ void FDrawInfo::DrawIndexed(EDrawType dt, FRenderState &state, int index, int co if (apply) { gl_RenderState.Apply(); - gl_RenderState.ApplyLightIndex(-2); } 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(); } diff --git a/src/gl/system/glsys_vertexbuffer.cpp b/src/gl/system/glsys_vertexbuffer.cpp index f11b2d2d7..19cc349e0 100644 --- a/src/gl/system/glsys_vertexbuffer.cpp +++ b/src/gl/system/glsys_vertexbuffer.cpp @@ -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 uint8_t VFmtToSize[] = {4, 3, 2, 1, 4, 4}; diff --git a/src/gl/system/glsys_vertexbuffer.h b/src/gl/system/glsys_vertexbuffer.h index 8f8678373..d90722ecf 100644 --- a/src/gl/system/glsys_vertexbuffer.h +++ b/src/gl/system/glsys_vertexbuffer.h @@ -23,7 +23,7 @@ public: GLVertexBuffer(); ~GLVertexBuffer(); 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 Map() override; void Unmap() override; diff --git a/src/hwrenderer/data/vertexbuffer.h b/src/hwrenderer/data/vertexbuffer.h index d59006127..3b2392dc8 100644 --- a/src/hwrenderer/data/vertexbuffer.h +++ b/src/hwrenderer/data/vertexbuffer.h @@ -42,7 +42,7 @@ protected: public: virtual ~IVertexBuffer() {} 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 Unmap() {} void *Memory() { assert(map); return map; }