mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-07 17:11:17 +00:00
- replaced IUniformBuffer with IDataBuffer, which reuses the code for the other buffer types and is more flexible.
This commit is contained in:
parent
8abf09afe2
commit
a1fb1f60f4
13 changed files with 74 additions and 147 deletions
|
@ -1038,7 +1038,6 @@ set (PCH_SOURCES
|
||||||
g_statusbar/sbarinfo.cpp
|
g_statusbar/sbarinfo.cpp
|
||||||
g_statusbar/sbar_mugshot.cpp
|
g_statusbar/sbar_mugshot.cpp
|
||||||
g_statusbar/shared_sbar.cpp
|
g_statusbar/shared_sbar.cpp
|
||||||
gl/data/gl_uniformbuffer.cpp
|
|
||||||
gl/data/gl_viewpointbuffer.cpp
|
gl/data/gl_viewpointbuffer.cpp
|
||||||
gl/dynlights/gl_lightbuffer.cpp
|
gl/dynlights/gl_lightbuffer.cpp
|
||||||
gl/dynlights/gl_shadowmap.cpp
|
gl/dynlights/gl_shadowmap.cpp
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Copyright(C) 2018 Christoph Oelckers
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
|
||||||
//
|
|
||||||
//--------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
/*
|
|
||||||
** gl_uniformbuffer.cpp
|
|
||||||
** Uniform buffer abstraction class.
|
|
||||||
**
|
|
||||||
**/
|
|
||||||
|
|
||||||
|
|
||||||
#include "gl_load/gl_system.h"
|
|
||||||
#include "gl_load/gl_interface.h"
|
|
||||||
#include "gl_uniformbuffer.h"
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
GLUniformBuffer::GLUniformBuffer(size_t size, bool staticdraw)
|
|
||||||
: IUniformBuffer(size), mStaticDraw(staticdraw)
|
|
||||||
{
|
|
||||||
glGenBuffers(1, &mBufferId);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
GLUniformBuffer::~GLUniformBuffer()
|
|
||||||
{
|
|
||||||
if (mBufferId != 0)
|
|
||||||
{
|
|
||||||
glDeleteBuffers(1, &mBufferId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void GLUniformBuffer::SetData(const void *data)
|
|
||||||
{
|
|
||||||
if (mBufferId != 0)
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, mBufferId);
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, mSize, data, mStaticDraw? GL_STATIC_DRAW : GL_STREAM_DRAW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// This needs to go away later.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void GLUniformBuffer::Bind(int bindingpoint)
|
|
||||||
{
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, bindingpoint, mBufferId);
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "hwrenderer/data/uniformbuffer.h"
|
|
||||||
|
|
||||||
|
|
||||||
class GLUniformBuffer : public IUniformBuffer
|
|
||||||
{
|
|
||||||
unsigned mBufferId;
|
|
||||||
bool mStaticDraw;
|
|
||||||
|
|
||||||
public:
|
|
||||||
GLUniformBuffer(size_t size, bool staticdraw = false);
|
|
||||||
~GLUniformBuffer();
|
|
||||||
|
|
||||||
void SetData(const void *data) override;
|
|
||||||
void Bind(int bindingpoint) override;
|
|
||||||
|
|
||||||
unsigned ID() const
|
|
||||||
{
|
|
||||||
return mBufferId;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
|
@ -966,9 +966,9 @@ void FGLRenderBuffers::RenderEffect(const FString &name)
|
||||||
if (step.Uniforms.Size > 0)
|
if (step.Uniforms.Size > 0)
|
||||||
{
|
{
|
||||||
if (!shader->Uniforms)
|
if (!shader->Uniforms)
|
||||||
shader->Uniforms.reset(screen->CreateUniformBuffer(step.Uniforms.Size));
|
shader->Uniforms.reset(screen->CreateDataBuffer(POSTPROCESS_BINDINGPOINT, false));
|
||||||
shader->Uniforms->SetData(step.Uniforms.Data);
|
shader->Uniforms->SetData(step.Uniforms.Size, step.Uniforms.Data);
|
||||||
shader->Uniforms->Bind(POSTPROCESS_BINDINGPOINT);
|
shader->Uniforms->BindBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set shader
|
// Set shader
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
GLuint Handle() { return mProgram; }
|
GLuint Handle() { return mProgram; }
|
||||||
//explicit operator bool() const { return mProgram != 0; }
|
//explicit operator bool() const { return mProgram != 0; }
|
||||||
|
|
||||||
std::unique_ptr<IUniformBuffer> Uniforms;
|
std::unique_ptr<IDataBuffer> Uniforms;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FShaderProgram(const FShaderProgram &) = delete;
|
FShaderProgram(const FShaderProgram &) = delete;
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#include "gl/textures/gl_samplers.h"
|
#include "gl/textures/gl_samplers.h"
|
||||||
#include "hwrenderer/utility/hw_clock.h"
|
#include "hwrenderer/utility/hw_clock.h"
|
||||||
#include "hwrenderer/utility/hw_vrmodes.h"
|
#include "hwrenderer/utility/hw_vrmodes.h"
|
||||||
#include "gl/data/gl_uniformbuffer.h"
|
|
||||||
#include "hwrenderer/models/hw_models.h"
|
#include "hwrenderer/models/hw_models.h"
|
||||||
#include "gl/shaders/gl_shaderprogram.h"
|
#include "gl/shaders/gl_shaderprogram.h"
|
||||||
#include "gl_debug.h"
|
#include "gl_debug.h"
|
||||||
|
@ -353,11 +352,6 @@ FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli)
|
||||||
return new FGLModelRenderer(nullptr, gl_RenderState, mli);
|
return new FGLModelRenderer(nullptr, gl_RenderState, mli);
|
||||||
}
|
}
|
||||||
|
|
||||||
IUniformBuffer *OpenGLFrameBuffer::CreateUniformBuffer(size_t size, bool staticuse)
|
|
||||||
{
|
|
||||||
return new GLUniformBuffer(size, staticuse);
|
|
||||||
}
|
|
||||||
|
|
||||||
IShaderProgram *OpenGLFrameBuffer::CreateShaderProgram()
|
IShaderProgram *OpenGLFrameBuffer::CreateShaderProgram()
|
||||||
{
|
{
|
||||||
return new FShaderProgram;
|
return new FShaderProgram;
|
||||||
|
@ -373,6 +367,11 @@ IIndexBuffer *OpenGLFrameBuffer::CreateIndexBuffer()
|
||||||
return new GLIndexBuffer;
|
return new GLIndexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IDataBuffer *OpenGLFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo)
|
||||||
|
{
|
||||||
|
return new GLDataBuffer(bindingpoint, ssbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void OpenGLFrameBuffer::TextureFilterChanged()
|
void OpenGLFrameBuffer::TextureFilterChanged()
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,10 +41,10 @@ public:
|
||||||
void BeginFrame() override;
|
void BeginFrame() override;
|
||||||
void SetViewportRects(IntRect *bounds) override;
|
void SetViewportRects(IntRect *bounds) override;
|
||||||
void BlurScene(float amount) override;
|
void BlurScene(float amount) override;
|
||||||
IUniformBuffer *CreateUniformBuffer(size_t size, bool staticuse = false) override;
|
|
||||||
IShaderProgram *CreateShaderProgram() override;
|
IShaderProgram *CreateShaderProgram() override;
|
||||||
IVertexBuffer *CreateVertexBuffer() override;
|
IVertexBuffer *CreateVertexBuffer() override;
|
||||||
IIndexBuffer *CreateIndexBuffer() override;
|
IIndexBuffer *CreateIndexBuffer() override;
|
||||||
|
IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo) override;
|
||||||
|
|
||||||
// Retrieves a buffer containing image data for a screenshot.
|
// Retrieves a buffer containing image data for a screenshot.
|
||||||
// Hint: Pitch can be negative for upside-down images, in which case buffer
|
// Hint: Pitch can be negative for upside-down images, in which case buffer
|
||||||
|
|
|
@ -122,6 +122,32 @@ void GLBuffer::Unlock()
|
||||||
gl_RenderState.ResetVertexBuffer();
|
gl_RenderState.ResetVertexBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLBuffer::Resize(size_t newsize)
|
||||||
|
{
|
||||||
|
assert(!nomap); // only mappable buffers can be resized.
|
||||||
|
if (newsize > buffersize && !nomap)
|
||||||
|
{
|
||||||
|
// reallocate the buffer with twice the size
|
||||||
|
unsigned int oldbuffer = mBufferId;
|
||||||
|
|
||||||
|
// first unmap the old buffer
|
||||||
|
Bind();
|
||||||
|
glUnmapBuffer(mUseType);
|
||||||
|
|
||||||
|
glGenBuffers(1, &mBufferId);
|
||||||
|
SetData(newsize, nullptr, false);
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, oldbuffer);
|
||||||
|
|
||||||
|
// copy contents and delete the old buffer.
|
||||||
|
glCopyBufferSubData(GL_COPY_READ_BUFFER, mUseType, 0, 0, buffersize);
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||||
|
glDeleteBuffers(1, &oldbuffer);
|
||||||
|
buffersize = newsize;
|
||||||
|
gl_RenderState.ResetVertexBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Vertex buffer implementation
|
// Vertex buffer implementation
|
||||||
|
@ -171,3 +197,13 @@ void GLVertexBuffer::Bind(int *offsets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLDataBuffer::BindRange(size_t start, size_t length)
|
||||||
|
{
|
||||||
|
if (mUseType == GL_UNIFORM_BUFFER) // SSBO's cannot be rebound.
|
||||||
|
glBindBufferRange(mUseType, mBindingPoint, mBufferId, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLDataBuffer::BindBase()
|
||||||
|
{
|
||||||
|
glBindBufferBase(mUseType, mBindingPoint, mBufferId);
|
||||||
|
}
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
class GLBuffer : virtual public IBuffer
|
class GLBuffer : virtual public IBuffer
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
const int mUseType;
|
const int mUseType;
|
||||||
unsigned int mBufferId;
|
unsigned int mBufferId;
|
||||||
protected:
|
|
||||||
int mAllocationSize = 0;
|
int mAllocationSize = 0;
|
||||||
bool mPersistent = false;
|
bool mPersistent = false;
|
||||||
bool nomap = true;
|
bool nomap = true;
|
||||||
|
@ -22,6 +22,7 @@ protected:
|
||||||
void SetData(size_t size, void *data, bool staticdata) override;
|
void SetData(size_t size, void *data, bool staticdata) override;
|
||||||
void Map() override;
|
void Map() override;
|
||||||
void Unmap() override;
|
void Unmap() override;
|
||||||
|
void Resize(size_t newsize) override;
|
||||||
void *Lock(unsigned int size) override;
|
void *Lock(unsigned int size) override;
|
||||||
void Unlock() override;
|
void Unlock() override;
|
||||||
public:
|
public:
|
||||||
|
@ -56,3 +57,12 @@ public:
|
||||||
GLIndexBuffer() : GLBuffer(GL_ELEMENT_ARRAY_BUFFER) {}
|
GLIndexBuffer() : GLBuffer(GL_ELEMENT_ARRAY_BUFFER) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GLDataBuffer : public IDataBuffer, public GLBuffer
|
||||||
|
{
|
||||||
|
int mBindingPoint;
|
||||||
|
public:
|
||||||
|
GLDataBuffer(int bindingpoint, bool is_ssbo) : GLBuffer(is_ssbo? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER), mBindingPoint(bindingpoint) {}
|
||||||
|
void BindRange(size_t start, size_t length) override;
|
||||||
|
void BindBase() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "hwrenderer/data/uniformbuffer.h"
|
#include "hwrenderer/data/vertexbuffer.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -116,17 +116,17 @@ public:
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
if (mBuffer == nullptr)
|
if (mBuffer == nullptr)
|
||||||
mBuffer = screen->CreateUniformBuffer(sizeof(T));
|
mBuffer = screen->CreateDataBuffer(bindingpoint, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Set(bool bind = true)
|
void Set(bool bind = true)
|
||||||
{
|
{
|
||||||
if (mBuffer != nullptr)
|
if (mBuffer != nullptr)
|
||||||
mBuffer->SetData(&Values);
|
mBuffer->SetData(sizeof(T), &Values);
|
||||||
|
|
||||||
// Let's hope this can be done better when things have moved further ahead.
|
// Let's hope this can be done better when things have moved further ahead.
|
||||||
// This really is not the best place to add something that depends on API behavior.
|
// This really is not the best place to add something that depends on API behavior.
|
||||||
if (bind) mBuffer->Bind(bindingpoint);
|
if (bind) mBuffer->BindBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
T *operator->() { return &Values; }
|
T *operator->() { return &Values; }
|
||||||
|
@ -138,7 +138,7 @@ private:
|
||||||
ShaderUniforms(const ShaderUniforms &) = delete;
|
ShaderUniforms(const ShaderUniforms &) = delete;
|
||||||
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
|
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
|
||||||
|
|
||||||
IUniformBuffer *mBuffer = nullptr;
|
IDataBuffer *mBuffer = nullptr;
|
||||||
std::vector<UniformFieldDesc> mFields;
|
std::vector<UniformFieldDesc> mFields;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "zstring.h"
|
|
||||||
|
|
||||||
class IUniformBuffer
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
size_t mSize;
|
|
||||||
|
|
||||||
IUniformBuffer(size_t size) : mSize(size) {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~IUniformBuffer() {}
|
|
||||||
virtual void SetData(const void *data) = 0;
|
|
||||||
virtual void Bind(int bindingpoint) = 0; // This is only here for OpenGL. Vulkan doesn't need the ability to bind this at run time.
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
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 *Lock(unsigned int size) = 0;
|
virtual void *Lock(unsigned int size) = 0;
|
||||||
virtual void Unlock() = 0;
|
virtual void Unlock() = 0;
|
||||||
|
virtual void Resize(size_t newsize) = 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; }
|
||||||
|
@ -67,3 +68,11 @@ class IIndexBuffer : virtual public IBuffer
|
||||||
// Ob Vulkam, element size is a buffer property and of no concern to the drawing functions (as it should be.)
|
// Ob Vulkam, element size is a buffer property and of no concern to the drawing functions (as it should be.)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class IDataBuffer : virtual public IBuffer
|
||||||
|
{
|
||||||
|
// Can be either uniform or shader storage buffer, depending on its needs.
|
||||||
|
public:
|
||||||
|
virtual void BindRange(size_t start, size_t length) = 0;
|
||||||
|
virtual void BindBase() = 0;
|
||||||
|
|
||||||
|
};
|
|
@ -52,6 +52,7 @@ struct FPortalSceneState;
|
||||||
class FSkyVertexBuffer;
|
class FSkyVertexBuffer;
|
||||||
class IIndexBuffer;
|
class IIndexBuffer;
|
||||||
class IVertexBuffer;
|
class IVertexBuffer;
|
||||||
|
class IDataBuffer;
|
||||||
|
|
||||||
enum EHWCaps
|
enum EHWCaps
|
||||||
{
|
{
|
||||||
|
@ -335,7 +336,6 @@ public:
|
||||||
class FUniquePalette;
|
class FUniquePalette;
|
||||||
class IHardwareTexture;
|
class IHardwareTexture;
|
||||||
class FTexture;
|
class FTexture;
|
||||||
class IUniformBuffer;
|
|
||||||
|
|
||||||
// A canvas that represents the actual display. The video code is responsible
|
// A canvas that represents the actual display. The video code is responsible
|
||||||
// for actually implementing this. Built on top of SimpleCanvas, because it
|
// for actually implementing this. Built on top of SimpleCanvas, because it
|
||||||
|
@ -450,10 +450,10 @@ public:
|
||||||
virtual void BlurScene(float amount) {}
|
virtual void BlurScene(float amount) {}
|
||||||
|
|
||||||
// Interface to hardware rendering resources
|
// Interface to hardware rendering resources
|
||||||
virtual IUniformBuffer *CreateUniformBuffer(size_t size, bool staticuse = false) { return nullptr; }
|
|
||||||
virtual IShaderProgram *CreateShaderProgram() { return nullptr; }
|
virtual IShaderProgram *CreateShaderProgram() { return nullptr; }
|
||||||
virtual IVertexBuffer *CreateVertexBuffer() { return nullptr; }
|
virtual IVertexBuffer *CreateVertexBuffer() { return nullptr; }
|
||||||
virtual IIndexBuffer *CreateIndexBuffer() { return nullptr; }
|
virtual IIndexBuffer *CreateIndexBuffer() { return nullptr; }
|
||||||
|
virtual IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo) { return nullptr; }
|
||||||
bool BuffersArePersistent() { return !!(hwcaps & RFL_BUFFER_STORAGE); }
|
bool BuffersArePersistent() { return !!(hwcaps & RFL_BUFFER_STORAGE); }
|
||||||
|
|
||||||
// Begin/End 2D drawing operations.
|
// Begin/End 2D drawing operations.
|
||||||
|
|
Loading…
Reference in a new issue