From 0f0dc2c852723f397583dc0a771726d38c9e1df0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 29 Aug 2016 10:43:03 +0200 Subject: [PATCH] - implemented buffers for GL 3.x. These only get mapped during the data collection pass so the order of some things is different here. --- src/gl/data/gl_vertexbuffer.cpp | 63 ++++++++++++++++++++++++++---- src/gl/data/gl_vertexbuffer.h | 3 ++ src/gl/renderer/gl_postprocess.cpp | 2 +- src/gl/scene/gl_portal.cpp | 8 ++-- src/gl/scene/gl_scene.cpp | 4 +- src/gl/shaders/gl_shader.cpp | 2 +- src/gl/system/gl_interface.cpp | 8 +++- 7 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 7e77849545..31cb8d0b5c 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -126,6 +126,7 @@ void FSimpleVertexBuffer::EnableColorArray(bool on) void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count) { glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + gl_RenderState.ResetVertexBuffer(); gl_RenderState.SetVertexBuffer(this); glBufferData(GL_ARRAY_BUFFER, count * sizeof(*verts), verts, GL_STREAM_DRAW); } @@ -139,18 +140,32 @@ void FSimpleVertexBuffer::set(FSimpleVertex *verts, int count) FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) : FVertexBuffer(gl.buffermethod != BM_CLIENTARRAY) { - if (gl.buffermethod != BM_CLIENTARRAY) + switch (gl.buffermethod) + { + case BM_PERSISTENT: { 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); + break; } - else + + case BM_DEFERRED: + { + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, bytesize, NULL, GL_STREAM_DRAW); + map = nullptr; + break; + } + + case BM_CLIENTARRAY: { // The fallback path uses immediate mode rendering and does not set up an actual vertex buffer - vbo_shadowdata.Reserve(BUFFER_SIZE); map = new FFlatVertex[BUFFER_SIZE]; + break; + } } mIndex = mCurIndex = 0; mNumReserved = NUM_RESERVED; @@ -185,6 +200,13 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) vbo_shadowdata[18].Set(32767.0f, -32767.0f, 32767.0f, 0, 0); vbo_shadowdata[19].Set(32767.0f, -32767.0f, -32767.0f, 0, 0); + if (gl.buffermethod == BM_DEFERRED) + { + Map(); + memcpy(map, &vbo_shadowdata[0], mNumReserved * sizeof(FFlatVertex)); + Unmap(); + } + } FFlatVertexBuffer::~FFlatVertexBuffer() @@ -195,7 +217,7 @@ FFlatVertexBuffer::~FFlatVertexBuffer() glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); } - else + if (gl.buffermethod == BM_CLIENTARRAY) { delete[] map; } @@ -208,7 +230,7 @@ void FFlatVertexBuffer::BindVBO() glBindBuffer(GL_ARRAY_BUFFER, vbo_id); if (gl.glslversion > 0) { - if (vbo_id != 0) // set this up only if there is an actual buffer. + if (gl.buffermethod != BM_CLIENTARRAY) { glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x); glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u); @@ -226,12 +248,37 @@ void FFlatVertexBuffer::BindVBO() } else { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_FLOAT, sizeof(FFlatVertex), &map->x); + glTexCoordPointer(2, GL_FLOAT, sizeof(FFlatVertex), &map->u); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); } } +void FFlatVertexBuffer::Map() +{ + if (gl.buffermethod == BM_DEFERRED) + { + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + gl_RenderState.ResetVertexBuffer(); + map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT); + } +} + +void FFlatVertexBuffer::Unmap() +{ + if (gl.buffermethod == BM_DEFERRED) + { + unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + gl_RenderState.ResetVertexBuffer(); + glUnmapBuffer(GL_ARRAY_BUFFER); + map = nullptr; + } +} + //========================================================================== // // Initialize a single vertex @@ -412,7 +459,9 @@ void FFlatVertexBuffer::CreateVBO() vbo_shadowdata.Resize(mNumReserved); CreateFlatVBO(); mCurIndex = mIndex = vbo_shadowdata.Size(); + Map(); memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex)); + Unmap(); } //========================================================================== diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 68f1013675..88a1de2b89 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -149,6 +149,9 @@ public: mCurIndex = mIndex; } + void Map(); + void Unmap(); + private: int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor); int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor); diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 20f6f469f4..3a83f4caf5 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -114,7 +114,7 @@ void FGLRenderer::RenderScreenQuad() { mVBO->BindVBO(); gl_RenderState.ResetVertexBuffer(); - glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 4); } //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index 4b8d8eb275..cd3efb9e3b 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -163,8 +163,8 @@ void GLPortal::DrawPortalStencil() } if (NeedCap() && lines.Size() > 1) { - glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4); - glDrawArrays(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILTOP_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, FFlatVertexBuffer::STENCILBOTTOM_INDEX, 4); } } @@ -1178,9 +1178,9 @@ void GLHorizonPortal::DrawContents() for (unsigned i = 0; i < vcount; i += 4) { - glDrawArrays(GL_TRIANGLE_STRIP, voffset + i, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, voffset + i, 4); } - glDrawArrays(GL_TRIANGLE_STRIP, voffset + vcount, 10); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, voffset + vcount, 10); gl_RenderState.EnableTextureMatrix(false); PortalAll.Unclock(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 250ec0c532..08591283c0 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -284,6 +284,7 @@ void FGLRenderer::CreateScene() for(unsigned i=0;iglportal = NULL; gl_spriteindex=0; Bsp.Clock(); + GLRenderer->mVBO->Map(); R_SetView(); validcount++; // used for processing sidedefs only once by the renderer. gl_RenderBSPNode (nodes + numnodes - 1); @@ -295,6 +296,7 @@ void FGLRenderer::CreateScene() gl_drawinfo->HandleMissingTextures(); // Missing upper/lower textures gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks + GLRenderer->mVBO->Unmap(); ProcessAll.Unclock(); @@ -525,7 +527,7 @@ void gl_FillScreen() gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); // The fullscreen quad is stored at index 4 in the main vertex buffer. - glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); } //========================================================================== diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 67b9a2d6ae..8ac2b70933 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -125,7 +125,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n"; } } - //if (gl.buffermethod == BM_DEFERRED) + if (gl.buffermethod == BM_DEFERRED) { vp_comb << "#define USE_QUAD_DRAWER\n"; } diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index a7b1be6487..9eb1d779e5 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -204,8 +204,12 @@ void gl_LoadExtensions() } else if (gl.version < 3.0f) { - //if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.glslversion = 1.21f; // for pre-3.0 drivers that support capable hardware. Needed for Apple. - //else gl.glslversion = 0; + if (CheckExtension("GL_NV_GPU_shader4") || CheckExtension("GL_EXT_GPU_shader4")) gl.glslversion = 1.21f; // for pre-3.0 drivers that support capable hardware. Needed for Apple. + else + { + gl.buffermethod = BM_CLIENTARRAY; + gl.glslversion = 0; + } if (!CheckExtension("GL_EXT_packed_float")) gl.flags |= RFL_NO_RGBA16F; if (!CheckExtension("GL_EXT_packed_depth_stencil")) gl.flags |= RFL_NO_DEPTHSTENCIL;