- moved around a few more files.

This commit is contained in:
Christoph Oelckers 2020-04-25 22:17:41 +02:00
parent b9e3c9681b
commit b6cc31eb0d
8 changed files with 7 additions and 5 deletions

View file

@ -0,0 +1,83 @@
#pragma once
#include <stddef.h>
#include <assert.h>
class FRenderState;
// The low level code needs to know which attributes exist.
// OpenGL needs to change the state of all of them per buffer binding.
// VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want.
enum
{
VATTR_VERTEX,
VATTR_TEXCOORD,
VATTR_COLOR,
VATTR_VERTEX2,
VATTR_NORMAL,
VATTR_NORMAL2,
VATTR_MAX
};
enum EVertexAttributeFormat
{
VFmt_Float4,
VFmt_Float3,
VFmt_Float2,
VFmt_Float,
VFmt_Byte4,
VFmt_Packed_A2R10G10B10,
};
struct FVertexBufferAttribute
{
int binding;
int location;
int format;
int offset;
};
class IBuffer
{
protected:
size_t buffersize = 0;
void *map = nullptr;
public:
IBuffer() = default;
IBuffer(const IBuffer &) = delete;
IBuffer &operator=(const IBuffer &) = delete;
virtual ~IBuffer() = default;
virtual void SetData(size_t size, const void *data, bool staticdata = true) = 0;
virtual void SetSubData(size_t offset, size_t size, const void *data) = 0;
virtual void *Lock(unsigned int size) = 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 Unmap() {}
void *Memory() { assert(map); return map; }
size_t Size() { return buffersize; }
};
class IVertexBuffer : virtual public IBuffer
{
public:
virtual void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) = 0;
};
// This merely exists to have a dedicated type for index buffers to inherit from.
class IIndexBuffer : virtual public IBuffer
{
// Element size is fixed to 4, thanks to OpenGL requiring this info to be coded into the glDrawElements call.
// This mostly prohibits a more flexible buffer setup but GZDoom doesn't use any other format anyway.
// 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(FRenderState *state, size_t start, size_t length) = 0;
};

View file

@ -0,0 +1,33 @@
#pragma once
#include <stdint.h>
#include "tflags.h"
// A render queue is what contains all render commands.
// On Vulkan there can be several of them so this interface is needed to allow for the needed parallelism.
// On OpenGL the render state is global so all this will do is to translate the system independent calls into OpenGL API calls.
enum class ColormaskBits
{
RED = 1,
GREEN = 2,
BLUE = 4,
ALPHA = 8
};
typedef TFlags<ColormaskBits, uint8_t> Colormask;
class IRenderQueue
{
Colormask mColorMask;
Colormask GetColorMask() const
{
return mColorMask;
}
virtual void SetColorMask(Colormask mask) = 0;
};

View file

@ -0,0 +1,154 @@
#pragma once
#include <vector>
#include "hwrenderer/data/buffers.h"
#include "v_video.h"
enum
{
LIGHTBUF_BINDINGPOINT = 1,
POSTPROCESS_BINDINGPOINT = 2,
VIEWPOINT_BINDINGPOINT = 3,
LIGHTNODES_BINDINGPOINT = 4,
LIGHTLINES_BINDINGPOINT = 5,
LIGHTLIST_BINDINGPOINT = 6
};
enum class UniformType
{
Int,
UInt,
Float,
Vec2,
Vec3,
Vec4,
IVec2,
IVec3,
IVec4,
UVec2,
UVec3,
UVec4,
Mat4
};
class UniformFieldDesc
{
public:
UniformFieldDesc() { }
UniformFieldDesc(const char *name, UniformType type, std::size_t offset) : Name(name), Type(type), Offset(offset) { }
const char *Name;
UniformType Type;
std::size_t Offset;
};
class UniformBlockDecl
{
public:
static FString Create(const char *name, const std::vector<UniformFieldDesc> &fields, int bindingpoint)
{
FString decl;
FString layout;
if (bindingpoint == -1)
{
layout = "push_constant";
}
else if (screen->glslversion < 4.20)
{
layout = "std140";
}
else
{
layout.Format("std140, binding = %d", bindingpoint);
}
decl.Format("layout(%s) uniform %s\n{\n", layout.GetChars(), name);
for (size_t i = 0; i < fields.size(); i++)
{
decl.AppendFormat("\t%s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name);
}
decl += "};\n";
return decl;
}
private:
static const char *GetTypeStr(UniformType type)
{
switch (type)
{
default:
case UniformType::Int: return "int";
case UniformType::UInt: return "uint";
case UniformType::Float: return "float";
case UniformType::Vec2: return "vec2";
case UniformType::Vec3: return "vec3";
case UniformType::Vec4: return "vec4";
case UniformType::IVec2: return "ivec2";
case UniformType::IVec3: return "ivec3";
case UniformType::IVec4: return "ivec4";
case UniformType::UVec2: return "uvec2";
case UniformType::UVec3: return "uvec3";
case UniformType::UVec4: return "uvec4";
case UniformType::Mat4: return "mat4";
}
}
};
template<typename T, int bindingpoint>
class ShaderUniforms
{
public:
ShaderUniforms()
{
memset(&Values, 0, sizeof(Values));
}
~ShaderUniforms()
{
if (mBuffer != nullptr)
delete mBuffer;
}
int BindingPoint() const
{
return bindingpoint;
}
FString CreateDeclaration(const char *name, const std::vector<UniformFieldDesc> &fields)
{
mFields = fields;
return UniformBlockDecl::Create(name, fields, bindingpoint);
}
void Init()
{
if (mBuffer == nullptr)
mBuffer = screen->CreateDataBuffer(bindingpoint, false, false);
}
void SetData()
{
if (mBuffer != nullptr)
mBuffer->SetData(sizeof(T), &Values);
}
IDataBuffer* GetBuffer() const
{
// OpenGL needs to mess around with this in ways that should not be part of the interface.
return mBuffer;
}
T *operator->() { return &Values; }
const T *operator->() const { return &Values; }
T Values;
private:
ShaderUniforms(const ShaderUniforms &) = delete;
ShaderUniforms &operator=(const ShaderUniforms &) = delete;
IDataBuffer *mBuffer = nullptr;
std::vector<UniformFieldDesc> mFields;
};

View file

@ -39,6 +39,7 @@
#include "cmdlib.h"
#include "v_draw.h"
#include "i_interface.h"
#include "printf.h"
#define NUMSCALEMODES countof(vScaleTable)
extern bool setsizeneeded;