- 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 "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)
{
mPersistent = screen->BuffersArePersistent();
ibo_id = 0;
glGenBuffers(1, &ibo_id);
if (mPersistent)
: FFlatVertexGenerator(width, height)
{
mVertexBuffer = screen->CreateVertexBuffer();
mIndexBuffer = screen->CreateIndexBuffer();
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->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);
delete mIndexBuffer;
delete mVertexBuffer;
mIndexBuffer = nullptr;
mVertexBuffer = nullptr;
}
if (ibo_id != 0)
void FFlatVertexBuffer::Copy(int start, int count)
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &ibo_id);
}
map = nullptr;
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]);
}

View File

@ -39,6 +39,7 @@ struct secplane_t;
struct subsector_t;
struct sector_t;
class FMaterial;
class FRenderState;
@ -85,34 +86,40 @@ public:
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<unsigned int> 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<class T>
@ -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();
}
};

View File

@ -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)

View File

@ -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<void()> &afterBloomDrawEndScene2D)

View File

@ -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,7 +319,7 @@ 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);
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);

View File

@ -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<GLIndexBuffer*>(mIndexBuffer)->Bind();
mCurrentIndexBuffer = mIndexBuffer;
}
}
else if (mFVertexBuffer != mCurrentFVertexBuffer)
@ -268,22 +285,18 @@ void FGLRenderState::Apply()
if (mFVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0);
else mFVertexBuffer->BindVBO();
mCurrentFVertexBuffer = mFVertexBuffer;
mCurrentVertexBuffer = nullptr;
mCurrentIndexBuffer = nullptr;
}
}
void FGLRenderState::Apply()
{
ApplyState();
ApplyBuffers();
ApplyShader();
}
void FGLRenderState::ApplyLightIndex(int index)
{
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);
}
//===========================================================================
//
// Binds a texture to the renderer
@ -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);
}

View File

@ -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();

View File

@ -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();
}

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 uint8_t VFmtToSize[] = {4, 3, 2, 1, 4, 4};

View File

@ -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;

View File

@ -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; }