diff --git a/src/common/rendering/gl/gl_framebuffer.cpp b/src/common/rendering/gl/gl_framebuffer.cpp index 33ecaac2b..0fa3a6068 100644 --- a/src/common/rendering/gl/gl_framebuffer.cpp +++ b/src/common/rendering/gl/gl_framebuffer.cpp @@ -166,8 +166,8 @@ void OpenGLFrameBuffer::InitializeState() mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight(), screen->mPipelineNbr); mSkyData = new FSkyVertexBuffer; - mViewpoints = new HWViewpointBuffer; - mLights = new FLightBuffer(); + mViewpoints = new HWViewpointBuffer(screen->mPipelineNbr); + mLights = new FLightBuffer(screen->mPipelineNbr); GLRenderer = new FGLRenderer(this); GLRenderer->Initialize(GetWidth(), GetHeight()); static_cast(mLights->GetBuffer())->BindBase(); diff --git a/src/common/rendering/hwrenderer/data/hw_lightbuffer.cpp b/src/common/rendering/hwrenderer/data/hw_lightbuffer.cpp index 2783ab669..5eef9c632 100644 --- a/src/common/rendering/hwrenderer/data/hw_lightbuffer.cpp +++ b/src/common/rendering/hwrenderer/data/hw_lightbuffer.cpp @@ -33,7 +33,8 @@ static const int ELEMENTS_PER_LIGHT = 4; // each light needs 4 vec4's. static const int ELEMENT_SIZE = (4*sizeof(float)); -FLightBuffer::FLightBuffer() +FLightBuffer::FLightBuffer(int pipelineNbr): + mPipelineNbr(pipelineNbr) { int maxNumberOfLights = 80000; @@ -59,8 +60,11 @@ FLightBuffer::FLightBuffer() mByteSize += screen->maxuniformblock; // to avoid mapping beyond the end of the buffer. } - mBuffer = screen->CreateDataBuffer(LIGHTBUF_BINDINGPOINT, mBufferType, false); - mBuffer->SetData(mByteSize, nullptr, false); + for (int n = 0; n < mPipelineNbr; n++) + { + mBufferPipeline[n] = screen->CreateDataBuffer(LIGHTBUF_BINDINGPOINT, mBufferType, false); + mBufferPipeline[n]->SetData(mByteSize, nullptr, false); + } Clear(); } @@ -73,6 +77,11 @@ FLightBuffer::~FLightBuffer() void FLightBuffer::Clear() { mIndex = 0; + + mPipelinePos++; + mPipelinePos %= mPipelineNbr; + + mBuffer = mBufferPipeline[mPipelinePos]; } int FLightBuffer::UploadLights(FDynLightData &data) diff --git a/src/common/rendering/hwrenderer/data/hw_lightbuffer.h b/src/common/rendering/hwrenderer/data/hw_lightbuffer.h index 2e5849346..cde25c0d2 100644 --- a/src/common/rendering/hwrenderer/data/hw_lightbuffer.h +++ b/src/common/rendering/hwrenderer/data/hw_lightbuffer.h @@ -1,6 +1,7 @@ #ifndef __GL_LIGHTBUFFER_H #define __GL_LIGHTBUFFER_H +#include "doomdef.h" #include "tarray.h" #include "hw_dynlightdata.h" #include "hwrenderer/data/buffers.h" @@ -12,6 +13,9 @@ class FRenderState; class FLightBuffer { IDataBuffer *mBuffer; + IDataBuffer* mBufferPipeline[MAX_PIPELINE_BUFFERS]; + int mPipelineNbr; + int mPipelinePos = 0; bool mBufferType; std::atomic mIndex; @@ -25,7 +29,7 @@ class FLightBuffer public: - FLightBuffer(); + FLightBuffer(int pipelineNbr = 1); ~FLightBuffer(); void Clear(); int UploadLights(FDynLightData &data); diff --git a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp index a265e7d11..c37306b8a 100644 --- a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp +++ b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.cpp @@ -33,13 +33,19 @@ static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough -HWViewpointBuffer::HWViewpointBuffer() +HWViewpointBuffer::HWViewpointBuffer(int pipelineNbr): + mPipelineNbr(pipelineNbr) { mBufferSize = INITIAL_BUFFER_SIZE; mBlockAlign = ((sizeof(HWViewpointUniforms) / screen->uniformblockalignment) + 1) * screen->uniformblockalignment; mByteSize = mBufferSize * mBlockAlign; - mBuffer = screen->CreateDataBuffer(VIEWPOINT_BINDINGPOINT, false, true); - mBuffer->SetData(mByteSize, nullptr, false); + + for (int n = 0; n < mPipelineNbr; n++) + { + mBufferPipeline[n] = screen->CreateDataBuffer(VIEWPOINT_BINDINGPOINT, false, true); + mBufferPipeline[n]->SetData(mByteSize, nullptr, false); + } + Clear(); mLastMappedIndex = UINT_MAX; mClipPlaneInfo.Push(0); @@ -57,7 +63,10 @@ void HWViewpointBuffer::CheckSize() { mBufferSize *= 2; mByteSize *= 2; - mBuffer->Resize(mByteSize); + for (int n = 0; n < mPipelineNbr; n++) + { + mBufferPipeline[n]->Resize(mByteSize); + } m2DHeight = m2DWidth = -1; } } @@ -89,9 +98,14 @@ void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height, int pll) matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f); matrices.CalcDependencies(); - mBuffer->Map(); - memcpy(mBuffer->Memory(), &matrices, sizeof(matrices)); - mBuffer->Unmap(); + + for (int n = 0; n < mPipelineNbr; n++) + { + mBufferPipeline[n]->Map(); + memcpy(mBufferPipeline[n]->Memory(), &matrices, sizeof(matrices)); + mBufferPipeline[n]->Unmap(); + } + m2DWidth = width; m2DHeight = height; mLastMappedIndex = -1; @@ -115,5 +129,10 @@ void HWViewpointBuffer::Clear() // Index 0 is reserved for the 2D projection. mUploadIndex = 1; mClipPlaneInfo.Resize(1); + + mPipelinePos++; + mPipelinePos %= mPipelineNbr; + + mBuffer = mBufferPipeline[mPipelinePos]; } diff --git a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h index 42c096704..80407c8bc 100644 --- a/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h +++ b/src/common/rendering/hwrenderer/data/hw_viewpointbuffer.h @@ -1,4 +1,4 @@ - +#include "doomdef.h" #include "tarray.h" #include "hwrenderer/data/buffers.h" @@ -8,6 +8,9 @@ class FRenderState; class HWViewpointBuffer { IDataBuffer *mBuffer; + IDataBuffer* mBufferPipeline[MAX_PIPELINE_BUFFERS]; + int mPipelineNbr; + int mPipelinePos = 0; unsigned int mBufferSize; unsigned int mBlockAlign; @@ -24,7 +27,7 @@ class HWViewpointBuffer public: - HWViewpointBuffer(); + HWViewpointBuffer(int pipelineNbr = 1); ~HWViewpointBuffer(); void Clear(); int Bind(FRenderState &di, unsigned int index);