GL: Use std::array where applicable

This commit is contained in:
Lioncash 2019-08-24 19:06:09 -04:00
parent 07835b58fb
commit e3b44edd51
1 changed files with 166 additions and 118 deletions

View File

@ -93,22 +93,29 @@ class GLDataFactoryImpl final : public GLDataFactory, public GraphicsDataFactory
commitTransaction([this](IGraphicsDataFactory::Context& ctx) { commitTransaction([this](IGraphicsDataFactory::Context& ctx) {
auto vertex = ctx.newShaderStage((uint8_t*)GammaVS, 0, PipelineStage::Vertex); auto vertex = ctx.newShaderStage((uint8_t*)GammaVS, 0, PipelineStage::Vertex);
auto fragment = ctx.newShaderStage((uint8_t*)GammaFS, 0, PipelineStage::Fragment); auto fragment = ctx.newShaderStage((uint8_t*)GammaFS, 0, PipelineStage::Fragment);
AdditionalPipelineInfo info = { const AdditionalPipelineInfo info = {
BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, ZTest::None, false, true, false, CullMode::None}; BlendFactor::One, BlendFactor::Zero, Primitive::TriStrips, ZTest::None, false, true, false, CullMode::None};
const VertexElementDescriptor vfmt[] = {{VertexSemantic::Position4}, {VertexSemantic::UV4}}; const std::array<VertexElementDescriptor, 2> vfmt{{{VertexSemantic::Position4}, {VertexSemantic::UV4}}};
m_gammaShader = ctx.newShaderPipeline(vertex, fragment, vfmt, info); m_gammaShader = ctx.newShaderPipeline(vertex, fragment, vfmt.data(), info);
m_gammaLUT = ctx.newDynamicTexture(256, 256, TextureFormat::I16, TextureClampMode::ClampToEdge); m_gammaLUT = ctx.newDynamicTexture(256, 256, TextureFormat::I16, TextureClampMode::ClampToEdge);
const struct Vert { struct Vert {
float pos[4]; std::array<float, 4> pos;
float uv[4]; std::array<float, 4> uv;
} verts[4] = {{{-1.f, -1.f, 0.f, 1.f}, {0.f, 0.f, 0.f, 0.f}}, };
constexpr std::array<Vert, 4> verts{{
{{-1.f, -1.f, 0.f, 1.f}, {0.f, 0.f, 0.f, 0.f}},
{{1.f, -1.f, 0.f, 1.f}, {1.f, 0.f, 0.f, 0.f}}, {{1.f, -1.f, 0.f, 1.f}, {1.f, 0.f, 0.f, 0.f}},
{{-1.f, 1.f, 0.f, 1.f}, {0.f, 1.f, 0.f, 0.f}}, {{-1.f, 1.f, 0.f, 1.f}, {0.f, 1.f, 0.f, 0.f}},
{{1.f, 1.f, 0.f, 1.f}, {1.f, 1.f, 0.f, 0.f}}}; {{1.f, 1.f, 0.f, 1.f}, {1.f, 1.f, 0.f, 0.f}},
m_gammaVBO = ctx.newStaticBuffer(BufferUse::Vertex, verts, 32, 4); }};
ObjToken<ITexture> texs[] = {{}, m_gammaLUT.get()}; m_gammaVBO = ctx.newStaticBuffer(BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size());
m_gammaBinding = ctx.newShaderDataBinding(m_gammaShader, m_gammaVBO.get(), {}, {}, 0, nullptr, nullptr, 2, texs,
nullptr, nullptr); const std::array<ObjToken<ITexture>, 2> texs{{
{},
m_gammaLUT.get(),
}};
m_gammaBinding = ctx.newShaderDataBinding(m_gammaShader, m_gammaVBO.get(), {}, {}, 0, nullptr, nullptr,
texs.size(), texs.data(), nullptr, nullptr);
return true; return true;
} BooTrace); } BooTrace);
} }
@ -143,7 +150,12 @@ public:
bool areShadersReady() override { return true; } bool areShadersReady() override { return true; }
}; };
static const GLenum USE_TABLE[] = {GL_INVALID_ENUM, GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_UNIFORM_BUFFER}; constexpr std::array<GLenum, 4> USE_TABLE{
GL_INVALID_ENUM,
GL_ARRAY_BUFFER,
GL_ELEMENT_ARRAY_BUFFER,
GL_UNIFORM_BUFFER,
};
class GLGraphicsBufferS : public GraphicsDataNode<IGraphicsBufferS> { class GLGraphicsBufferS : public GraphicsDataNode<IGraphicsBufferS> {
friend class GLDataFactory; friend class GLDataFactory;
@ -174,25 +186,26 @@ class GLGraphicsBufferD : public GraphicsDataNode<IGraphicsBufferD, DataCls> {
friend class GLDataFactory; friend class GLDataFactory;
friend class GLDataFactoryImpl; friend class GLDataFactoryImpl;
friend struct GLCommandQueue; friend struct GLCommandQueue;
GLuint m_bufs[3]; std::array<GLuint, 3> m_bufs{};
GLenum m_target; GLenum m_target;
std::unique_ptr<uint8_t[]> m_cpuBuf; std::unique_ptr<uint8_t[]> m_cpuBuf;
size_t m_cpuSz = 0; size_t m_cpuSz = 0;
int m_validMask = 0; int m_validMask = 0;
GLGraphicsBufferD(const ObjToken<DataCls>& parent, BufferUse use, size_t sz) GLGraphicsBufferD(const ObjToken<DataCls>& parent, BufferUse use, size_t sz)
: GraphicsDataNode<IGraphicsBufferD, DataCls>(parent) : GraphicsDataNode<IGraphicsBufferD, DataCls>(parent)
, m_target(USE_TABLE[int(use)]) , m_target(USE_TABLE[int(use)])
, m_cpuBuf(new uint8_t[sz]) , m_cpuBuf(new uint8_t[sz])
, m_cpuSz(sz) { , m_cpuSz(sz) {
glGenBuffers(3, m_bufs); glGenBuffers(GLsizei(m_bufs.size()), m_bufs.data());
for (int i = 0; i < 3; ++i) { for (const GLuint buf : m_bufs) {
glBindBuffer(m_target, m_bufs[i]); glBindBuffer(m_target, buf);
glBufferData(m_target, m_cpuSz, nullptr, GL_STREAM_DRAW); glBufferData(m_target, m_cpuSz, nullptr, GL_STREAM_DRAW);
} }
} }
public: public:
~GLGraphicsBufferD() override { glDeleteBuffers(3, m_bufs); } ~GLGraphicsBufferD() override { glDeleteBuffers(GLsizei(m_bufs.size()), m_bufs.data()); }
void update(int b) { void update(int b) {
int slot = 1 << b; int slot = 1 << b;
@ -240,16 +253,16 @@ static void SetClampMode(GLenum target, TextureClampMode clampMode) {
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
GLfloat color[] = {1.f, 1.f, 1.f, 1.f}; constexpr std::array<GLfloat, 4> color{1.f, 1.f, 1.f, 1.f};
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color); glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color.data());
break; break;
} }
case TextureClampMode::ClampToBlack: { case TextureClampMode::ClampToBlack: {
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
GLfloat color[] = {0.f, 0.f, 0.f, 1.f}; constexpr std::array<GLfloat, 4> color{0.f, 0.f, 0.f, 1.f};
glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color); glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color.data());
break; break;
} }
case TextureClampMode::ClampToEdge: { case TextureClampMode::ClampToEdge: {
@ -441,7 +454,7 @@ public:
class GLTextureD : public GraphicsDataNode<ITextureD> { class GLTextureD : public GraphicsDataNode<ITextureD> {
friend class GLDataFactory; friend class GLDataFactory;
friend struct GLCommandQueue; friend struct GLCommandQueue;
GLuint m_texs[3]; std::array<GLuint, 3> m_texs{};
std::unique_ptr<uint8_t[]> m_cpuBuf; std::unique_ptr<uint8_t[]> m_cpuBuf;
size_t m_cpuSz = 0; size_t m_cpuSz = 0;
GLenum m_intFormat, m_format; GLenum m_intFormat, m_format;
@ -475,10 +488,10 @@ class GLTextureD : public GraphicsDataNode<ITextureD> {
m_cpuSz = width * height * pxPitch; m_cpuSz = width * height * pxPitch;
m_cpuBuf.reset(new uint8_t[m_cpuSz]); m_cpuBuf.reset(new uint8_t[m_cpuSz]);
GLenum compType = m_intFormat == GL_R16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; const GLenum compType = m_intFormat == GL_R16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
glGenTextures(3, m_texs); glGenTextures(GLsizei(m_texs.size()), m_texs.data());
for (int i = 0; i < 3; ++i) { for (const GLuint tex : m_texs) {
glBindTexture(GL_TEXTURE_2D, m_texs[i]); glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, m_intFormat, width, height, 0, m_format, compType, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, m_intFormat, width, height, 0, m_format, compType, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@ -487,7 +500,7 @@ class GLTextureD : public GraphicsDataNode<ITextureD> {
} }
public: public:
~GLTextureD() override { glDeleteTextures(3, m_texs); } ~GLTextureD() override { glDeleteTextures(GLsizei(m_texs.size()), m_texs.data()); }
void update(int b) { void update(int b) {
int slot = 1 << b; int slot = 1 << b;
@ -512,11 +525,13 @@ public:
void unmap() override { m_validMask = 0; } void unmap() override { m_validMask = 0; }
void setClampMode(TextureClampMode mode) override { void setClampMode(TextureClampMode mode) override {
if (m_clampMode == mode) if (m_clampMode == mode) {
return; return;
}
m_clampMode = mode; m_clampMode = mode;
for (int i = 0; i < 3; ++i) { for (const GLuint tex : m_texs) {
glBindTexture(GL_TEXTURE_2D, m_texs[i]); glBindTexture(GL_TEXTURE_2D, tex);
SetClampMode(GL_TEXTURE_2D, mode); SetClampMode(GL_TEXTURE_2D, mode);
} }
} }
@ -533,9 +548,9 @@ class GLTextureR : public GraphicsDataNode<ITextureR> {
friend class GLDataFactory; friend class GLDataFactory;
friend struct GLCommandQueue; friend struct GLCommandQueue;
struct GLCommandQueue* m_q; struct GLCommandQueue* m_q;
GLuint m_texs[2] = {}; std::array<GLuint, 2> m_texs{};
GLuint m_bindTexs[2][MAX_BIND_TEXS] = {}; std::array<std::array<GLuint, MAX_BIND_TEXS>, 2> m_bindTexs{};
GLuint m_bindFBOs[2][MAX_BIND_TEXS] = {}; std::array<std::array<GLuint, MAX_BIND_TEXS>, 2> m_bindFBOs{};
GLuint m_fbo = 0; GLuint m_fbo = 0;
size_t m_width = 0; size_t m_width = 0;
size_t m_height = 0; size_t m_height = 0;
@ -548,10 +563,10 @@ class GLTextureR : public GraphicsDataNode<ITextureR> {
public: public:
~GLTextureR() override { ~GLTextureR() override {
glDeleteTextures(2, m_texs); glDeleteTextures(GLsizei(m_texs.size()), m_texs.data());
glDeleteTextures(MAX_BIND_TEXS * 2, m_bindTexs[0]); glDeleteTextures(MAX_BIND_TEXS * 2, m_bindTexs[0].data());
if (m_samples > 1) if (m_samples > 1)
glDeleteFramebuffers(MAX_BIND_TEXS * 2, m_bindFBOs[0]); glDeleteFramebuffers(MAX_BIND_TEXS * 2, m_bindFBOs[0].data());
glDeleteFramebuffers(1, &m_fbo); glDeleteFramebuffers(1, &m_fbo);
} }
@ -593,29 +608,33 @@ public:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
for (int i = 0; i < MAX_BIND_TEXS; ++i) { for (const GLuint bindTex : m_bindTexs[0]) {
if (m_bindTexs[0][i]) { if (bindTex == 0) {
glBindTexture(GL_TEXTURE_2D, m_bindTexs[0][i]); continue;
glTexImage2D(GL_TEXTURE_2D, 0, m_colorFormat, width, height, 0, GL_RGBA, compType, nullptr);
}
} }
for (int i = 0; i < MAX_BIND_TEXS; ++i) { glBindTexture(GL_TEXTURE_2D, bindTex);
if (m_bindTexs[1][i]) { glTexImage2D(GL_TEXTURE_2D, 0, m_colorFormat, width, height, 0, GL_RGBA, compType, nullptr);
glBindTexture(GL_TEXTURE_2D, m_bindTexs[1][i]); }
for (const GLuint bindTex : m_bindTexs[1]) {
if (bindTex == 0) {
continue;
}
glBindTexture(GL_TEXTURE_2D, bindTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
nullptr); nullptr);
} }
} }
}
}; };
class GLTextureCubeR : public GraphicsDataNode<ITextureCubeR> { class GLTextureCubeR : public GraphicsDataNode<ITextureCubeR> {
friend class GLDataFactory; friend class GLDataFactory;
friend struct GLCommandQueue; friend struct GLCommandQueue;
struct GLCommandQueue* m_q; struct GLCommandQueue* m_q;
GLuint m_texs[2] = {}; std::array<GLuint, 2> m_texs{};
GLuint m_fbos[6] = {}; std::array<GLuint, 6> m_fbos{};
size_t m_width = 0; size_t m_width = 0;
size_t m_mipCount = 0; size_t m_mipCount = 0;
GLenum m_colorFormat; GLenum m_colorFormat;
@ -623,8 +642,8 @@ class GLTextureCubeR : public GraphicsDataNode<ITextureCubeR> {
public: public:
~GLTextureCubeR() override { ~GLTextureCubeR() override {
glDeleteTextures(2, m_texs); glDeleteTextures(GLsizei(m_texs.size()), m_texs.data());
glDeleteFramebuffers(6, m_fbos); glDeleteFramebuffers(GLsizei(m_fbos.size()), m_fbos.data());
} }
void setClampMode(TextureClampMode mode) override {} void setClampMode(TextureClampMode mode) override {}
@ -639,27 +658,29 @@ public:
glBindTexture(GL_TEXTURE_CUBE_MAP, m_texs[0]); glBindTexture(GL_TEXTURE_CUBE_MAP, m_texs[0]);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, m_mipCount - 1); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, m_mipCount - 1);
for (int f = 0; f < 6; ++f) { for (size_t f = 0; f < m_fbos.size(); ++f) {
size_t tmpWidth = m_width; size_t tmpWidth = m_width;
for (size_t m = 0; m < m_mipCount; ++m) { for (size_t m = 0; m < m_mipCount; ++m) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, m, m_colorFormat, tmpWidth, tmpWidth, glTexImage2D(GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f), m, m_colorFormat, tmpWidth, tmpWidth,
0, GL_RGBA, compType, nullptr); 0, GL_RGBA, compType, nullptr);
tmpWidth >>= 1; tmpWidth >>= 1;
} }
} }
glBindTexture(GL_TEXTURE_CUBE_MAP, m_texs[1]); glBindTexture(GL_TEXTURE_CUBE_MAP, m_texs[1]);
for (int f = 0; f < 6; ++f) for (size_t f = 0; f < m_fbos.size(); ++f) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, 0, GL_DEPTH_COMPONENT32F, m_width, m_width, 0, GL_DEPTH_COMPONENT, glTexImage2D(GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f), 0, GL_DEPTH_COMPONENT32F, m_width, m_width, 0,
GL_UNSIGNED_INT, nullptr); GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
}
} }
void resize(size_t width, size_t mips) { void resize(size_t width, size_t mips) {
m_width = width; m_width = width;
m_mipCount = mips; m_mipCount = mips;
_allocateTextures(); _allocateTextures();
for (int f = 0; f < 6; ++f) {
glBindFramebuffer(GL_FRAMEBUFFER, m_fbos[f]); for (const GLuint fbo : m_fbos) {
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
@ -684,17 +705,24 @@ ObjToken<ITextureSA> GLDataFactory::Context::newStaticArrayTexture(size_t width,
new GLTextureSA(m_data, width, height, layers, mips, fmt, clampMode, factory.m_glCtx->m_anisotropy, data, sz)}; new GLTextureSA(m_data, width, height, layers, mips, fmt, clampMode, factory.m_glCtx->m_anisotropy, data, sz)};
} }
static const GLenum PRIMITIVE_TABLE[] = {GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_PATCHES}; constexpr std::array<GLenum, 3> PRIMITIVE_TABLE{
GL_TRIANGLES,
GL_TRIANGLE_STRIP,
GL_PATCHES,
};
static const GLenum BLEND_FACTOR_TABLE[] = {GL_ZERO, GL_ONE, constexpr std::array<GLenum, 12> BLEND_FACTOR_TABLE{
GL_ZERO, GL_ONE,
GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA,
GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR}; GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR,
};
static const GLenum SHADER_STAGE_TABLE[] = { constexpr std::array<GLenum, 6> SHADER_STAGE_TABLE{
0, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER}; 0, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER, GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER,
};
class GLShaderStage : public GraphicsDataNode<IShaderStage> { class GLShaderStage : public GraphicsDataNode<IShaderStage> {
friend class GLDataFactory; friend class GLDataFactory;
@ -702,8 +730,9 @@ class GLShaderStage : public GraphicsDataNode<IShaderStage> {
std::vector<std::pair<std::string, int>> m_texNames; std::vector<std::pair<std::string, int>> m_texNames;
std::vector<std::pair<std::string, int>> m_blockNames; std::vector<std::pair<std::string, int>> m_blockNames;
static constexpr EShLanguage ShaderTypes[] = {EShLangVertex, EShLangVertex, EShLangFragment, static constexpr std::array<EShLanguage, 6> ShaderTypes{
EShLangGeometry, EShLangTessControl, EShLangTessEvaluation}; EShLangVertex, EShLangVertex, EShLangFragment, EShLangGeometry, EShLangTessControl, EShLangTessEvaluation,
};
/* Use glslang's reflection API to pull out uniform indices from Vulkan /* Use glslang's reflection API to pull out uniform indices from Vulkan
* version of shader. Aids in glGetUniformBlockIndex and glGetUniformLocation calls */ * version of shader. Aids in glGetUniformBlockIndex and glGetUniformLocation calls */
@ -803,15 +832,15 @@ protected:
bool m_alphaWrite = true; bool m_alphaWrite = true;
bool m_subtractBlend = false; bool m_subtractBlend = false;
bool m_overwriteAlpha = false; bool m_overwriteAlpha = false;
CullMode m_culling; CullMode m_culling{};
uint32_t m_patchSize = 0; uint32_t m_patchSize = 0;
mutable GLint m_uniLocs[BOO_GLSL_MAX_UNIFORM_COUNT]; mutable std::array<GLint, BOO_GLSL_MAX_UNIFORM_COUNT> m_uniLocs{};
GLShaderPipeline(const ObjToken<BaseGraphicsData>& parent, ObjToken<IShaderStage> vertex, GLShaderPipeline(const ObjToken<BaseGraphicsData>& parent, ObjToken<IShaderStage> vertex,
ObjToken<IShaderStage> fragment, ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control, ObjToken<IShaderStage> fragment, ObjToken<IShaderStage> geometry, ObjToken<IShaderStage> control,
ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt, ObjToken<IShaderStage> evaluation, const VertexFormatInfo& vtxFmt,
const AdditionalPipelineInfo& info) const AdditionalPipelineInfo& info)
: GraphicsDataNode<IShaderPipeline>(parent) { : GraphicsDataNode<IShaderPipeline>(parent) {
std::fill(std::begin(m_uniLocs), std::end(m_uniLocs), -1); m_uniLocs.fill(-1);
if (info.srcFac == BlendFactor::Subtract || info.dstFac == BlendFactor::Subtract) { if (info.srcFac == BlendFactor::Subtract || info.dstFac == BlendFactor::Subtract) {
m_sfactor = GL_SRC_ALPHA; m_sfactor = GL_SRC_ALPHA;
@ -1112,12 +1141,18 @@ ObjToken<IGraphicsBufferD> GLDataFactoryImpl::newPoolBuffer(BufferUse use, size_
return {new GLGraphicsBufferD<BaseGraphicsPool>(pool, use, stride * count)}; return {new GLGraphicsBufferD<BaseGraphicsPool>(pool, use, stride * count)};
} }
static const GLint SEMANTIC_COUNT_TABLE[] = {0, 3, 4, 3, 4, 4, 4, 2, 4, 4, 4}; constexpr std::array<GLint, 11> SEMANTIC_COUNT_TABLE{
0, 3, 4, 3, 4, 4, 4, 2, 4, 4, 4,
};
static const size_t SEMANTIC_SIZE_TABLE[] = {0, 12, 16, 12, 16, 16, 4, 8, 16, 16, 16}; constexpr std::array<size_t, 11> SEMANTIC_SIZE_TABLE{
0, 12, 16, 12, 16, 16, 4, 8, 16, 16, 16,
};
static const GLenum SEMANTIC_TYPE_TABLE[] = {GL_INVALID_ENUM, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, constexpr std::array<GLenum, 11> SEMANTIC_TYPE_TABLE{
GL_UNSIGNED_BYTE, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT}; GL_INVALID_ENUM, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT,
GL_UNSIGNED_BYTE, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT,
};
struct GLCommandQueue final : IGraphicsCommandQueue { struct GLCommandQueue final : IGraphicsCommandQueue {
Platform platform() const override { return IGraphicsDataFactory::Platform::OpenGL; } Platform platform() const override { return IGraphicsDataFactory::Platform::OpenGL; }
@ -1158,7 +1193,7 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
SWindowRect rect; SWindowRect rect;
float znear, zfar; float znear, zfar;
} viewport; } viewport;
float rgba[4]; std::array<float, 4> rgba;
GLbitfield flags; GLbitfield flags;
struct { struct {
size_t start; size_t start;
@ -1184,7 +1219,7 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
Command(Command&&) = default; Command(Command&&) = default;
Command& operator=(Command&&) = default; Command& operator=(Command&&) = default;
}; };
std::vector<Command> m_cmdBufs[3]; std::array<std::vector<Command>, 3> m_cmdBufs;
int m_fillBuf = 0; int m_fillBuf = 0;
int m_completeBuf = 0; int m_completeBuf = 0;
int m_drawBuf = 0; int m_drawBuf = 0;
@ -1212,20 +1247,22 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
std::vector<ObjToken<ITextureCubeR>> m_pendingCubeFboAdds; std::vector<ObjToken<ITextureCubeR>> m_pendingCubeFboAdds;
static void ConfigureVertexFormat(GLShaderDataBinding* fmt) { static void ConfigureVertexFormat(GLShaderDataBinding* fmt) {
glGenVertexArrays(3, fmt->m_vao.data()); glGenVertexArrays(GLsizei(fmt->m_vao.size()), fmt->m_vao.data());
size_t stride = 0; size_t stride = 0;
size_t instStride = 0; size_t instStride = 0;
auto pipeline = fmt->m_pipeline.cast<GLShaderPipeline>(); const auto* const pipeline = fmt->m_pipeline.cast<GLShaderPipeline>();
for (size_t i = 0; i < pipeline->m_elements.size(); ++i) { for (const auto desc : pipeline->m_elements) {
const VertexElementDescriptor& desc = pipeline->m_elements[i]; const size_t size = SEMANTIC_SIZE_TABLE[int(desc.semantic & VertexSemantic::SemanticMask)];
if (True(desc.semantic & VertexSemantic::Instanced))
instStride += SEMANTIC_SIZE_TABLE[int(desc.semantic & VertexSemantic::SemanticMask)]; if (True(desc.semantic & VertexSemantic::Instanced)) {
else instStride += size;
stride += SEMANTIC_SIZE_TABLE[int(desc.semantic & VertexSemantic::SemanticMask)]; } else {
stride += size;
}
} }
for (int b = 0; b < 3; ++b) { for (size_t b = 0; b < fmt->m_vao.size(); ++b) {
size_t offset = fmt->m_baseVert * stride; size_t offset = fmt->m_baseVert * stride;
size_t instOffset = fmt->m_baseInst * instStride; size_t instOffset = fmt->m_baseInst * instStride;
glBindVertexArray(fmt->m_vao[b]); glBindVertexArray(fmt->m_vao[b]);
@ -1240,28 +1277,31 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
if (vbo != lastVBO) { if (vbo != lastVBO) {
lastVBO = vbo; lastVBO = vbo;
if (lastVBO->dynamic()) if (lastVBO->dynamic())
static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastVBO)->bindVertex(b); static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastVBO)->bindVertex(int(b));
else else
static_cast<GLGraphicsBufferS*>(lastVBO)->bindVertex(); static_cast<GLGraphicsBufferS*>(lastVBO)->bindVertex();
} }
if (ebo != lastEBO) { if (ebo != lastEBO) {
lastEBO = ebo; lastEBO = ebo;
if (lastEBO->dynamic()) if (lastEBO->dynamic())
static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastEBO)->bindIndex(b); static_cast<GLGraphicsBufferD<BaseGraphicsData>*>(lastEBO)->bindIndex(int(b));
else else
static_cast<GLGraphicsBufferS*>(lastEBO)->bindIndex(); static_cast<GLGraphicsBufferS*>(lastEBO)->bindIndex();
} }
glEnableVertexAttribArray(i); glEnableVertexAttribArray(i);
int maskedSem = int(desc.semantic & VertexSemantic::SemanticMask); const int maskedSem = int(desc.semantic & VertexSemantic::SemanticMask);
const auto semanticCount = SEMANTIC_COUNT_TABLE[maskedSem];
const auto semanticType = SEMANTIC_TYPE_TABLE[maskedSem];
const auto semanticSize = SEMANTIC_SIZE_TABLE[maskedSem];
if (True(desc.semantic & VertexSemantic::Instanced)) { if (True(desc.semantic & VertexSemantic::Instanced)) {
glVertexAttribPointer(i, SEMANTIC_COUNT_TABLE[maskedSem], SEMANTIC_TYPE_TABLE[maskedSem], GL_TRUE, instStride, glVertexAttribPointer(i, semanticCount, semanticType, GL_TRUE, instStride, (void*)instOffset);
(void*)instOffset);
glVertexAttribDivisor(i, 1); glVertexAttribDivisor(i, 1);
instOffset += SEMANTIC_SIZE_TABLE[maskedSem]; instOffset += semanticSize;
} else { } else {
glVertexAttribPointer(i, SEMANTIC_COUNT_TABLE[maskedSem], SEMANTIC_TYPE_TABLE[maskedSem], GL_TRUE, stride, glVertexAttribPointer(i, semanticCount, semanticType, GL_TRUE, stride, (void*)offset);
(void*)offset); offset += semanticSize;
offset += SEMANTIC_SIZE_TABLE[maskedSem];
} }
} }
} }
@ -1276,14 +1316,14 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
if (tex->m_samples > 1) { if (tex->m_samples > 1) {
if (tex->m_colorBindCount) { if (tex->m_colorBindCount) {
glGenFramebuffers(tex->m_colorBindCount, tex->m_bindFBOs[0]); glGenFramebuffers(tex->m_colorBindCount, tex->m_bindFBOs[0].data());
for (size_t i = 0; i < tex->m_colorBindCount; ++i) { for (size_t i = 0; i < tex->m_colorBindCount; ++i) {
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[0][i]); glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[0][i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->m_bindTexs[0][i], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->m_bindTexs[0][i], 0);
} }
} }
if (tex->m_depthBindCount) { if (tex->m_depthBindCount) {
glGenFramebuffers(tex->m_depthBindCount, tex->m_bindFBOs[1]); glGenFramebuffers(tex->m_depthBindCount, tex->m_bindFBOs[1].data());
for (size_t i = 0; i < tex->m_depthBindCount; ++i) { for (size_t i = 0; i < tex->m_depthBindCount; ++i) {
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[1][i]); glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[1][i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex->m_bindTexs[1][i], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex->m_bindTexs[1][i], 0);
@ -1293,11 +1333,14 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
} }
static void ConfigureFBO(GLTextureCubeR* tex) { static void ConfigureFBO(GLTextureCubeR* tex) {
glGenFramebuffers(6, tex->m_fbos); glGenFramebuffers(GLsizei(tex->m_fbos.size()), tex->m_fbos.data());
for (int i = 0; i < 6; ++i) {
for (size_t i = 0; i < tex->m_fbos.size(); ++i) {
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_fbos[i]); glBindFramebuffer(GL_FRAMEBUFFER, tex->m_fbos[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, tex->m_texs[0], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i),
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, tex->m_texs[1], 0); tex->m_texs[0], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GLenum(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i),
tex->m_texs[1], 0);
} }
} }
@ -1536,7 +1579,7 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
int voffset = 0; int voffset = 0;
for (BaseGraphicsData& data : *dataFactory->m_dataHead) { for (BaseGraphicsData& data : *dataFactory->m_dataHead) {
if (GLTextureCubeR* cube = static_cast<GLTextureCubeR*>(data.getHead<ITextureCubeR>())) { if (GLTextureCubeR* cube = static_cast<GLTextureCubeR*>(data.getHead<ITextureCubeR>())) {
for (int i = 0; i < 6; ++i) { for (size_t i = 0; i < cube->m_fbos.size(); ++i) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, cube->m_fbos[i]); glBindFramebuffer(GL_READ_FRAMEBUFFER, cube->m_fbos[i]);
glBlitFramebuffer(0, 0, cube->m_width, cube->m_width, offset, voffset, glBlitFramebuffer(0, 0, cube->m_width, cube->m_width, offset, voffset,
cube->m_width + offset, cube->m_width + voffset, cube->m_width + offset, cube->m_width + voffset,
@ -1577,8 +1620,9 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
dataFactory->DestroyGammaResources(); dataFactory->DestroyGammaResources();
std::lock_guard<std::recursive_mutex> fmtLk(self->m_fmtMt); std::lock_guard<std::recursive_mutex> fmtLk(self->m_fmtMt);
if (self->m_pendingFmtDels.size()) { if (self->m_pendingFmtDels.size()) {
for (const auto& v : self->m_pendingFmtDels) for (const auto& v : self->m_pendingFmtDels) {
glDeleteVertexArrays(3, v.data()); glDeleteVertexArrays(GLsizei(v.size()), v.data());
}
self->m_pendingFmtDels.clear(); self->m_pendingFmtDels.clear();
} }
} }
@ -1595,10 +1639,12 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
if (m_running) { if (m_running) {
m_running = false; m_running = false;
m_cv.notify_one(); m_cv.notify_one();
if (m_thr.joinable()) if (m_thr.joinable()) {
m_thr.join(); m_thr.join();
for (int i = 0; i < 3; ++i) }
m_cmdBufs[i].clear(); for (auto& cmdBuf : m_cmdBufs) {
cmdBuf.clear();
}
} }
} }
@ -1760,10 +1806,10 @@ struct GLCommandQueue final : IGraphicsCommandQueue {
SCOPED_GRAPHICS_DEBUG_GROUP(this, "GLCommandQueue::execute", {1.f, 0.f, 0.f, 1.f}); SCOPED_GRAPHICS_DEBUG_GROUP(this, "GLCommandQueue::execute", {1.f, 0.f, 0.f, 1.f});
std::unique_lock<std::mutex> lk(m_mt); std::unique_lock<std::mutex> lk(m_mt);
m_completeBuf = m_fillBuf; m_completeBuf = m_fillBuf;
for (int i = 0; i < 3; ++i) { for (size_t i = 0; i < m_cmdBufs.size(); ++i) {
if (i == m_completeBuf || i == m_drawBuf) if (int(i) == m_completeBuf || int(i) == m_drawBuf)
continue; continue;
m_fillBuf = i; m_fillBuf = int(i);
break; break;
} }
@ -1839,16 +1885,18 @@ GLTextureR::GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue*
, m_colorFormat(colorFormat) , m_colorFormat(colorFormat)
, m_colorBindCount(colorBindingCount) , m_colorBindCount(colorBindingCount)
, m_depthBindCount(depthBindingCount) { , m_depthBindCount(depthBindingCount) {
glGenTextures(2, m_texs); glGenTextures(GLsizei(m_texs.size()), m_texs.data());
if (colorBindingCount) { if (colorBindingCount) {
if (colorBindingCount > MAX_BIND_TEXS) if (colorBindingCount > MAX_BIND_TEXS) {
Log.report(logvisor::Fatal, fmt("too many color bindings for render texture")); Log.report(logvisor::Fatal, fmt("too many color bindings for render texture"));
glGenTextures(colorBindingCount, m_bindTexs[0]); }
glGenTextures(colorBindingCount, m_bindTexs[0].data());
} }
if (depthBindingCount) { if (depthBindingCount) {
if (depthBindingCount > MAX_BIND_TEXS) if (depthBindingCount > MAX_BIND_TEXS) {
Log.report(logvisor::Fatal, fmt("too many depth bindings for render texture")); Log.report(logvisor::Fatal, fmt("too many depth bindings for render texture"));
glGenTextures(depthBindingCount, m_bindTexs[1]); }
glGenTextures(depthBindingCount, m_bindTexs[1].data());
} }
GLenum compType = colorFormat == GL_RGBA16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE; GLenum compType = colorFormat == GL_RGBA16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
@ -1906,7 +1954,7 @@ GLTextureCubeR::GLTextureCubeR(const ObjToken<BaseGraphicsData>& parent, GLComma
, m_width(width) , m_width(width)
, m_mipCount(mips) , m_mipCount(mips)
, m_colorFormat(colorFormat) { , m_colorFormat(colorFormat) {
glGenTextures(2, m_texs); glGenTextures(GLsizei(m_texs.size()), m_texs.data());
_allocateTextures(); _allocateTextures();