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

View File

@ -16,118 +16,19 @@
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include "GPU3D_OpenGL.h"
#include <stdio.h>
#include <string.h>
#include "NDS.h"
#include "GPU.h"
#include "Config.h"
#include "OpenGLSupport.h"
#include "GPU3D_OpenGL_shaders.h"
namespace GPU3D
{
namespace GLRenderer
{
using namespace OpenGL;
// GL version requirements
// * texelFetch: 3.0 (GLSL 1.30) (3.2/1.50 for MS)
// * UBO: 3.1
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;
struct RendererPolygon
{
Polygon* PolyData;
u32 NumIndices;
u32 IndicesOffset;
GLuint PrimType;
u32 NumEdgeIndices;
u32 EdgeIndicesOffset;
u32 RenderKey;
};
RendererPolygon PolygonList[2048];
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];
bool BuildRenderShader(u32 flags, const char* vs, const char* fs)
bool GLRenderer::BuildRenderShader(u32 flags, const char* vs, const char* fs)
{
char shadername[32];
sprintf(shadername, "RenderShader%02X", flags);
@ -180,7 +81,7 @@ bool BuildRenderShader(u32 flags, const char* vs, const char* fs)
return true;
}
void UseRenderShader(u32 flags)
void GLRenderer::UseRenderShader(u32 flags)
{
if (CurShaderID == flags) return;
glUseProgram(RenderShader[flags][2]);
@ -196,7 +97,12 @@ void SetupDefaultTexParams(GLuint tex)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
bool Init()
GLRenderer::GLRenderer()
: Renderer3D(true)
{
}
bool GLRenderer::Init()
{
GLint uni_id;
@ -382,7 +288,7 @@ bool Init()
return true;
}
void DeInit()
void GLRenderer::DeInit()
{
glDeleteTextures(1, &TexMemID);
glDeleteTextures(1, &TexPalMemID);
@ -404,11 +310,11 @@ void DeInit()
}
}
void Reset()
void GLRenderer::Reset()
{
}
void SetRenderSettings(GPU::RenderSettings& settings)
void GLRenderer::SetRenderSettings(GPU::RenderSettings& settings)
{
int scale = settings.GL_ScaleFactor;
@ -462,7 +368,7 @@ void SetRenderSettings(GPU::RenderSettings& settings)
}
void SetupPolygon(RendererPolygon* rp, Polygon* polygon)
void GLRenderer::SetupPolygon(GLRenderer::RendererPolygon* rp, Polygon* polygon)
{
rp->PolyData = polygon;
@ -508,7 +414,7 @@ void SetupPolygon(RendererPolygon* rp, Polygon* polygon)
}
}
u32* SetupVertex(Polygon* poly, int vid, Vertex* vtx, u32 vtxattr, u32* vptr)
u32* GLRenderer::SetupVertex(Polygon* poly, int vid, Vertex* vtx, u32 vtxattr, u32* vptr)
{
u32 z = poly->FinalZ[vid];
u32 w = poly->FinalW[vid];
@ -569,7 +475,7 @@ u32* SetupVertex(Polygon* poly, int vid, Vertex* vtx, u32 vtxattr, u32* vptr)
return vptr;
}
void BuildPolygons(RendererPolygon* polygons, int npolys)
void GLRenderer::BuildPolygons(GLRenderer::RendererPolygon* polygons, int npolys)
{
u32* vptr = &VertexBuffer[0];
u32 vidx = 0;
@ -791,7 +697,7 @@ void BuildPolygons(RendererPolygon* polygons, int npolys)
NumEdgeIndices = eidx - EdgeIndicesOffset;
}
int RenderSinglePolygon(int i)
int GLRenderer::RenderSinglePolygon(int i)
{
RendererPolygon* rp = &PolygonList[i];
@ -800,7 +706,7 @@ int RenderSinglePolygon(int i)
return 1;
}
int RenderPolygonBatch(int i)
int GLRenderer::RenderPolygonBatch(int i)
{
RendererPolygon* rp = &PolygonList[i];
GLuint primtype = rp->PrimType;
@ -822,7 +728,7 @@ int RenderPolygonBatch(int i)
return numpolys;
}
int RenderPolygonEdgeBatch(int i)
int GLRenderer::RenderPolygonEdgeBatch(int i)
{
RendererPolygon* rp = &PolygonList[i];
u32 key = rp->RenderKey;
@ -842,7 +748,7 @@ int RenderPolygonEdgeBatch(int i)
return numpolys;
}
void RenderSceneChunk(int y, int h)
void GLRenderer::RenderSceneChunk(int y, int h)
{
u32 flags = 0;
if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer;
@ -1206,7 +1112,7 @@ void RenderSceneChunk(int y, int h)
}
void RenderFrame()
void GLRenderer::RenderFrame()
{
CurShaderID = -1;
@ -1381,7 +1287,7 @@ void RenderFrame()
FrontBuffer = FrontBuffer ? 0 : 1;
}
void PrepareCaptureFrame()
void GLRenderer::PrepareCaptureFrame()
{
// TODO: make sure this picks the right buffer when doing antialiasing
int original_fb = FrontBuffer^1;
@ -1396,7 +1302,7 @@ void PrepareCaptureFrame()
glReadPixels(0, 0, 256, 192, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
}
u32* GetLine(int line)
u32* GLRenderer::GetLine(int line)
{
int stride = 256;
@ -1419,10 +1325,9 @@ u32* GetLine(int line)
return &Framebuffer[stride * line];
}
void SetupAccelFrame()
void GLRenderer::SetupAccelFrame()
{
glBindTexture(GL_TEXTURE_2D, FramebufferTex[FrontBuffer]);
}
}
}