Allow for a more modular renderer backends (#990)

* Draft GPU3D renderer modularization

* Update sources C++ standard to C++17

The top-level `CMakeLists.txt` is already using the C++17 standard.

* Move GLCompositor into class type

Some other misc fixes to push towards better modularity

* Make renderer-implementation types move-only

These types are going to be holding onto handles
of GPU-side resources and shouldn't ever be copied around.

* Fix OSX: Remove 'register' storage class specifier

`register` has been removed in C++17...
But this keyword hasn't done anything in years anyways.

OSX builds consider this "warning" an error and it
stops the whole build.

* Add RestartFrame to Renderer3D interface

* Move Accelerated property to Renderer3D interface

There are points in the code base where we do:
`renderer != 0` to know if we are feeding
an openGL renderer. Rather than that we can instead just have this be
a property of the renderer itself.
With this pattern a renderer can just say how it wants its data to come
in rather than have everyone know that they're talking to an OpenGL
renderer.

* Remove Accelerated flag from GPU

* Move 2D_Soft interface in separate header

Also make the current 2D engine an "owned" unique_ptr.

* Update alignment attribute to standard alignas

Uses standardized `alignas` rather than compiler-specific
attributes.

https://en.cppreference.com/w/cpp/language/alignas

* Fix Clang: alignas specifier

Alignment must be specified before the array to align the entire array.

https://en.cppreference.com/w/cpp/language/alignas

* Converted Renderer3D Accelerated to variable

This flag is checked a lot during scanline rasterization. So rather
than having an expensive vtable-lookup call during mainline rendering
code, it is now a public constant bool type that is written to only once
during Renderer3D initialization.
This commit is contained in:
Wunk
2021-02-09 14:38:51 -08:00
committed by GitHub
parent 891427c75c
commit a7029aebae
16 changed files with 1039 additions and 836 deletions

152
src/GPU3D_OpenGL.h Normal file
View File

@ -0,0 +1,152 @@
/*
Copyright 2016-2020 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#pragma once
#include "GPU3D.h"
#include "OpenGLSupport.h"
namespace GPU3D
{
class GLRenderer : public Renderer3D
{
public:
GLRenderer();
virtual ~GLRenderer() override {};
virtual bool Init() override;
virtual void DeInit() override;
virtual void Reset() override;
virtual void SetRenderSettings(GPU::RenderSettings& settings) override;
virtual void VCount144() override {};
virtual void RenderFrame() override;
virtual u32* GetLine(int line) override;
void SetupAccelFrame();
void PrepareCaptureFrame();
private:
// GL version requirements
// * texelFetch: 3.0 (GLSL 1.30) (3.2/1.50 for MS)
// * UBO: 3.1
struct RendererPolygon
{
Polygon* PolyData;
u32 NumIndices;
u32 IndicesOffset;
GLuint PrimType;
u32 NumEdgeIndices;
u32 EdgeIndicesOffset;
u32 RenderKey;
};
RendererPolygon PolygonList[2048];
bool BuildRenderShader(u32 flags, const char* vs, const char* fs);
void UseRenderShader(u32 flags);
void SetupPolygon(RendererPolygon* rp, Polygon* polygon);
u32* SetupVertex(Polygon* poly, int vid, Vertex* vtx, u32 vtxattr, u32* vptr);
void BuildPolygons(RendererPolygon* polygons, int npolys);
int RenderSinglePolygon(int i);
int RenderPolygonBatch(int i);
int RenderPolygonEdgeBatch(int i);
void RenderSceneChunk(int y, int h);
enum
{
RenderFlag_WBuffer = 0x01,
RenderFlag_Trans = 0x02,
RenderFlag_ShadowMask = 0x04,
RenderFlag_Edge = 0x08,
};
GLuint ClearShaderPlain[3];
GLuint RenderShader[16][3];
GLuint CurShaderID = -1;
GLuint FinalPassEdgeShader[3];
GLuint FinalPassFogShader[3];
// std140 compliant structure
struct
{
float uScreenSize[2]; // vec2 0 / 2
u32 uDispCnt; // int 2 / 1
u32 __pad0;
float uToonColors[32][4]; // vec4[32] 4 / 128
float uEdgeColors[8][4]; // vec4[8] 132 / 32
float uFogColor[4]; // vec4 164 / 4
float uFogDensity[34][4]; // float[34] 168 / 136
u32 uFogOffset; // int 304 / 1
u32 uFogShift; // int 305 / 1
u32 _pad1[2]; // int 306 / 2
} ShaderConfig;
GLuint ShaderConfigUBO;
int NumFinalPolys, NumOpaqueFinalPolys;
GLuint ClearVertexBufferID, ClearVertexArrayID;
GLint ClearUniformLoc[4];
// vertex buffer
// * XYZW: 4x16bit
// * RGBA: 4x8bit
// * ST: 2x16bit
// * polygon data: 3x32bit (polygon/texture attributes)
//
// polygon attributes:
// * bit4-7, 11, 14-15, 24-29: POLYGON_ATTR
// * bit16-20: Z shift
// * bit8: front-facing (?)
// * bit9: W-buffering (?)
GLuint VertexBufferID;
u32 VertexBuffer[10240 * 7];
u32 NumVertices;
GLuint VertexArrayID;
GLuint IndexBufferID;
u16 IndexBuffer[2048 * 40];
u32 NumIndices, NumEdgeIndices;
const u32 EdgeIndicesOffset = 2048 * 30;
GLuint TexMemID;
GLuint TexPalMemID;
int ScaleFactor;
bool BetterPolygons;
int ScreenW, ScreenH;
GLuint FramebufferTex[8];
int FrontBuffer;
GLuint FramebufferID[4], PixelbufferID;
u32 Framebuffer[256*192];
};
}