mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 14:19:55 -06:00
nothing works yet
This commit is contained in:
@ -66,6 +66,7 @@ if (ENABLE_OGLRENDERER)
|
|||||||
GPU_OpenGL.cpp
|
GPU_OpenGL.cpp
|
||||||
GPU_OpenGL_shaders.h
|
GPU_OpenGL_shaders.h
|
||||||
GPU3D_OpenGL.cpp
|
GPU3D_OpenGL.cpp
|
||||||
|
GPU3D_Compute.cpp
|
||||||
GPU3D_OpenGL_shaders.h
|
GPU3D_OpenGL_shaders.h
|
||||||
OpenGLSupport.cpp)
|
OpenGLSupport.cpp)
|
||||||
|
|
||||||
|
@ -169,6 +169,7 @@ extern std::unique_ptr<Renderer3D> CurrentRenderer;
|
|||||||
|
|
||||||
#ifdef OGLRENDERER_ENABLED
|
#ifdef OGLRENDERER_ENABLED
|
||||||
#include "GPU3D_OpenGL.h"
|
#include "GPU3D_OpenGL.h"
|
||||||
|
#include "GPU3D_Compute.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1451
src/GPU3D_Compute.cpp
Normal file
1451
src/GPU3D_Compute.cpp
Normal file
File diff suppressed because it is too large
Load Diff
263
src/GPU3D_Compute.h
Normal file
263
src/GPU3D_Compute.h
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016-2022 melonDS team
|
||||||
|
|
||||||
|
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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GPU3D_COMPUTE
|
||||||
|
#define GPU3D_COMPUTE
|
||||||
|
|
||||||
|
#include "GPU3D.h"
|
||||||
|
|
||||||
|
#include "OpenGLSupport.h"
|
||||||
|
|
||||||
|
#include "NonStupidBitfield.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace GPU3D
|
||||||
|
{
|
||||||
|
|
||||||
|
class ComputeRenderer : public Renderer3D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ComputeRenderer();
|
||||||
|
~ComputeRenderer() override;
|
||||||
|
|
||||||
|
bool Init() override;
|
||||||
|
void DeInit() override;
|
||||||
|
void Reset() override;
|
||||||
|
|
||||||
|
void SetRenderSettings(GPU::RenderSettings& settings) override;
|
||||||
|
|
||||||
|
void VCount144() override;
|
||||||
|
|
||||||
|
void RenderFrame() override;
|
||||||
|
void RestartFrame() override;
|
||||||
|
u32* GetLine(int line) override;
|
||||||
|
|
||||||
|
//dk::Fence FrameReady = {};
|
||||||
|
//dk::Fence FrameReserveFence = {};
|
||||||
|
private:
|
||||||
|
GLuint ShaderInterpXSpans[2];
|
||||||
|
GLuint ShaderBinCombined;
|
||||||
|
GLuint ShaderDepthBlend[2];
|
||||||
|
GLuint ShaderRasteriseNoTexture[2];
|
||||||
|
GLuint ShaderRasteriseNoTextureToon[2];
|
||||||
|
GLuint ShaderRasteriseNoTextureHighlight[2];
|
||||||
|
GLuint ShaderRasteriseUseTextureDecal[2];
|
||||||
|
GLuint ShaderRasteriseUseTextureModulate[2];
|
||||||
|
GLuint ShaderRasteriseUseTextureToon[2];
|
||||||
|
GLuint ShaderRasteriseUseTextureHighlight[2];
|
||||||
|
GLuint ShaderRasteriseShadowMask[2];
|
||||||
|
GLuint ShaderClearCoarseBinMask;
|
||||||
|
GLuint ShaderClearIndirectWorkCount;
|
||||||
|
GLuint ShaderCalculateWorkListOffset;
|
||||||
|
GLuint ShaderSortWork;
|
||||||
|
GLuint ShaderFinalPass[8];
|
||||||
|
|
||||||
|
GLuint YSpanIndicesTextureMemory;
|
||||||
|
GLuint YSpanIndicesTexture;
|
||||||
|
GLuint YSpanSetupMemory;
|
||||||
|
GLuint XSpanSetupMemory;
|
||||||
|
GLuint BinResultMemory;
|
||||||
|
GLuint RenderPolygonMemory;
|
||||||
|
GLuint TileMemory;
|
||||||
|
GLuint FinalTileMemory;
|
||||||
|
|
||||||
|
u32 DummyLine[256] = {};
|
||||||
|
|
||||||
|
struct SpanSetupY
|
||||||
|
{
|
||||||
|
// Attributes
|
||||||
|
s32 Z0, Z1, W0, W1;
|
||||||
|
s32 ColorR0, ColorG0, ColorB0;
|
||||||
|
s32 ColorR1, ColorG1, ColorB1;
|
||||||
|
s32 TexcoordU0, TexcoordV0;
|
||||||
|
s32 TexcoordU1, TexcoordV1;
|
||||||
|
|
||||||
|
// Interpolator
|
||||||
|
s32 I0, I1;
|
||||||
|
s32 Linear;
|
||||||
|
s32 IRecip;
|
||||||
|
s32 W0n, W0d, W1d;
|
||||||
|
|
||||||
|
// Slope
|
||||||
|
s32 Increment;
|
||||||
|
|
||||||
|
s32 X0, X1, Y0, Y1;
|
||||||
|
s32 XMin, XMax;
|
||||||
|
s32 DxInitial;
|
||||||
|
|
||||||
|
s32 XCovIncr;
|
||||||
|
u32 IsDummy, __pad1;
|
||||||
|
};
|
||||||
|
struct SpanSetupX
|
||||||
|
{
|
||||||
|
s32 X0, X1;
|
||||||
|
|
||||||
|
s32 EdgeLenL, EdgeLenR, EdgeCovL, EdgeCovR;
|
||||||
|
|
||||||
|
s32 XRecip;
|
||||||
|
|
||||||
|
u32 Flags;
|
||||||
|
|
||||||
|
s32 Z0, Z1, W0, W1;
|
||||||
|
s32 ColorR0, ColorG0, ColorB0;
|
||||||
|
s32 ColorR1, ColorG1, ColorB1;
|
||||||
|
s32 TexcoordU0, TexcoordV0;
|
||||||
|
s32 TexcoordU1, TexcoordV1;
|
||||||
|
|
||||||
|
s32 CovLInitial, CovRInitial;
|
||||||
|
};
|
||||||
|
struct SetupIndices
|
||||||
|
{
|
||||||
|
u16 PolyIdx, SpanIdxL, SpanIdxR, Y;
|
||||||
|
};
|
||||||
|
struct RenderPolygon
|
||||||
|
{
|
||||||
|
u32 FirstXSpan;
|
||||||
|
s32 YTop, YBot;
|
||||||
|
|
||||||
|
s32 XMin, XMax;
|
||||||
|
s32 XMinY, XMaxY;
|
||||||
|
|
||||||
|
u32 Variant;
|
||||||
|
u32 Attr;
|
||||||
|
|
||||||
|
float TextureLayer;
|
||||||
|
u32 __pad0, __pad1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int TileSize = 8;
|
||||||
|
static const int CoarseTileCountX = 8;
|
||||||
|
static const int CoarseTileCountY = 4;
|
||||||
|
static const int CoarseTileW = CoarseTileCountX * TileSize;
|
||||||
|
static const int CoarseTileH = CoarseTileCountY * TileSize;
|
||||||
|
|
||||||
|
static const int TilesPerLine = 256/TileSize;
|
||||||
|
static const int TileLines = 192/TileSize;
|
||||||
|
|
||||||
|
static const int BinStride = 2048/32;
|
||||||
|
static const int CoarseBinStride = BinStride/32;
|
||||||
|
|
||||||
|
static const int MaxWorkTiles = TilesPerLine*TileLines*48;
|
||||||
|
static const int MaxVariants = 256;
|
||||||
|
|
||||||
|
static const int UniformIdxCurVariant = 0;
|
||||||
|
static const int UniformIdxTextureSize = 1;
|
||||||
|
|
||||||
|
struct BinResult
|
||||||
|
{
|
||||||
|
u32 VariantWorkCount[MaxVariants*4];
|
||||||
|
u32 SortedWorkOffset[MaxVariants];
|
||||||
|
|
||||||
|
u32 SortWorkWorkCount[4];
|
||||||
|
u32 UnsortedWorkDescs[MaxWorkTiles*2];
|
||||||
|
u32 SortedWork[MaxWorkTiles*2];
|
||||||
|
|
||||||
|
u32 BinnedMaskCoarse[TilesPerLine*TileLines*CoarseBinStride];
|
||||||
|
u32 BinnedMask[TilesPerLine*TileLines*BinStride];
|
||||||
|
u32 WorkOffsets[TilesPerLine*TileLines*BinStride];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Tiles
|
||||||
|
{
|
||||||
|
u32 ColorTiles[MaxWorkTiles*TileSize*TileSize];
|
||||||
|
u32 DepthTiles[MaxWorkTiles*TileSize*TileSize];
|
||||||
|
u32 AttrStencilTiles[MaxWorkTiles*TileSize*TileSize];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FinalTiles
|
||||||
|
{
|
||||||
|
u32 ColorResult[256*192*2];
|
||||||
|
u32 DepthResult[256*192*2];
|
||||||
|
u32 AttrResult[256*192*2];
|
||||||
|
};
|
||||||
|
|
||||||
|
// eh those are pretty bad guesses
|
||||||
|
// though real hw shouldn't be eable to render all 2048 polygons on every line either
|
||||||
|
static const int MaxYSpanIndices = 64*2048;
|
||||||
|
static const int MaxYSpanSetups = 6144*2;
|
||||||
|
SetupIndices YSpanIndices[MaxYSpanIndices];
|
||||||
|
SpanSetupY YSpanSetups[MaxYSpanSetups];
|
||||||
|
RenderPolygon RenderPolygons[2048];
|
||||||
|
|
||||||
|
struct TexArrayEntry
|
||||||
|
{
|
||||||
|
u16 TexArrayIdx;
|
||||||
|
u16 LayerIdx;
|
||||||
|
};
|
||||||
|
struct TexArray
|
||||||
|
{
|
||||||
|
GLuint Image;
|
||||||
|
u32 ImageDescriptor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TexCacheEntry
|
||||||
|
{
|
||||||
|
u32 DescriptorIdx;
|
||||||
|
u32 LastVariant; // very cheap way to make variant lookup faster
|
||||||
|
|
||||||
|
u32 TextureRAMStart[2], TextureRAMSize[2];
|
||||||
|
u32 TexPalStart, TexPalSize;
|
||||||
|
u8 WidthLog2, HeightLog2;
|
||||||
|
TexArrayEntry Texture;
|
||||||
|
|
||||||
|
u64 TextureHash[2];
|
||||||
|
u64 TexPalHash;
|
||||||
|
};
|
||||||
|
std::unordered_map<u64, TexCacheEntry> TexCache;
|
||||||
|
|
||||||
|
struct MetaUniform
|
||||||
|
{
|
||||||
|
u32 NumPolygons;
|
||||||
|
u32 NumVariants;
|
||||||
|
|
||||||
|
u32 AlphaRef;
|
||||||
|
u32 DispCnt;
|
||||||
|
|
||||||
|
u32 ToonTable[4*34];
|
||||||
|
|
||||||
|
u32 ClearColor, ClearDepth, ClearAttr;
|
||||||
|
|
||||||
|
u32 FogOffset, FogShift, FogColor;
|
||||||
|
|
||||||
|
u32 XScroll;
|
||||||
|
};
|
||||||
|
GLuint MetaUniformMemory;
|
||||||
|
|
||||||
|
static const u32 TexCacheMaxImages = 4096;
|
||||||
|
|
||||||
|
u32 FreeImageDescriptorsCount = 0;
|
||||||
|
u32 FreeImageDescriptors[TexCacheMaxImages];
|
||||||
|
|
||||||
|
std::vector<TexArrayEntry> FreeTextures[8][8];
|
||||||
|
std::vector<TexArray> TexArrays[8][8];
|
||||||
|
|
||||||
|
u32 TextureDecodingBuffer[1024*1024];
|
||||||
|
|
||||||
|
TexCacheEntry& GetTexture(u32 textureParam, u32 paletteParam);
|
||||||
|
|
||||||
|
void SetupAttrs(SpanSetupY* span, Polygon* poly, int from, int to);
|
||||||
|
void SetupYSpan(int polynum, SpanSetupY* span, Polygon* poly, int from, int to, u32 y, int side);
|
||||||
|
void SetupYSpanDummy(SpanSetupY* span, Polygon* poly, int vertex, int side);
|
||||||
|
|
||||||
|
bool CompileShader(GLuint& shader, const char* source, const std::initializer_list<const char*>& defines);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1502
src/GPU3D_Compute_shaders.h
Normal file
1502
src/GPU3D_Compute_shaders.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -49,25 +49,18 @@ bool GLRenderer::BuildRenderShader(u32 flags, const char* vs, const char* fs)
|
|||||||
strcpy(&fsbuf[headerlen], kRenderFSCommon);
|
strcpy(&fsbuf[headerlen], kRenderFSCommon);
|
||||||
strcpy(&fsbuf[headerlen + fsclen], fs);
|
strcpy(&fsbuf[headerlen + fsclen], fs);
|
||||||
|
|
||||||
bool ret = OpenGL::BuildShaderProgram(vsbuf, fsbuf, RenderShader[flags], shadername);
|
GLuint prog;
|
||||||
|
bool ret = OpenGL::CompileVertexFragmentProgram(prog,
|
||||||
|
vsbuf, fsbuf,
|
||||||
|
shadername,
|
||||||
|
{{"vPosition", 0}, {"vColor", 1}, {"vTexcoord", 2}, {"vPolygonAttr", 3}},
|
||||||
|
{{"oColor", 0}, {"oAttr", 1}});
|
||||||
|
|
||||||
delete[] vsbuf;
|
delete[] vsbuf;
|
||||||
delete[] fsbuf;
|
delete[] fsbuf;
|
||||||
|
|
||||||
if (!ret) return false;
|
if (!ret) return false;
|
||||||
|
|
||||||
GLuint prog = RenderShader[flags][2];
|
|
||||||
|
|
||||||
glBindAttribLocation(prog, 0, "vPosition");
|
|
||||||
glBindAttribLocation(prog, 1, "vColor");
|
|
||||||
glBindAttribLocation(prog, 2, "vTexcoord");
|
|
||||||
glBindAttribLocation(prog, 3, "vPolygonAttr");
|
|
||||||
glBindFragDataLocation(prog, 0, "oColor");
|
|
||||||
glBindFragDataLocation(prog, 1, "oAttr");
|
|
||||||
|
|
||||||
if (!OpenGL::LinkShaderProgram(RenderShader[flags]))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
GLint uni_id = glGetUniformBlockIndex(prog, "uConfig");
|
GLint uni_id = glGetUniformBlockIndex(prog, "uConfig");
|
||||||
glUniformBlockBinding(prog, uni_id, 0);
|
glUniformBlockBinding(prog, uni_id, 0);
|
||||||
|
|
||||||
@ -78,13 +71,15 @@ bool GLRenderer::BuildRenderShader(u32 flags, const char* vs, const char* fs)
|
|||||||
uni_id = glGetUniformLocation(prog, "TexPalMem");
|
uni_id = glGetUniformLocation(prog, "TexPalMem");
|
||||||
glUniform1i(uni_id, 1);
|
glUniform1i(uni_id, 1);
|
||||||
|
|
||||||
|
RenderShader[flags] = prog;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLRenderer::UseRenderShader(u32 flags)
|
void GLRenderer::UseRenderShader(u32 flags)
|
||||||
{
|
{
|
||||||
if (CurShaderID == flags) return;
|
if (CurShaderID == flags) return;
|
||||||
glUseProgram(RenderShader[flags][2]);
|
glUseProgram(RenderShader[flags]);
|
||||||
CurShaderID = flags;
|
CurShaderID = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,21 +113,17 @@ std::unique_ptr<GLRenderer> GLRenderer::New() noexcept
|
|||||||
glDepthRange(0, 1);
|
glDepthRange(0, 1);
|
||||||
glClearDepth(1.0);
|
glClearDepth(1.0);
|
||||||
|
|
||||||
|
if (!OpenGL::CompileVertexFragmentProgram(result->ClearShaderPlain,
|
||||||
if (!OpenGL::BuildShaderProgram(kClearVS, kClearFS, result->ClearShaderPlain, "ClearShader"))
|
kClearVS, kClearFS,
|
||||||
|
"ClearShader",
|
||||||
|
{{"vPosition", 0}},
|
||||||
|
{{"oColor", 0}, {"oAttr", 1}}))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
glBindAttribLocation(result->ClearShaderPlain[2], 0, "vPosition");
|
result->ClearUniformLoc[0] = glGetUniformLocation(result->ClearShaderPlain, "uColor");
|
||||||
glBindFragDataLocation(result->ClearShaderPlain[2], 0, "oColor");
|
result->ClearUniformLoc[1] = glGetUniformLocation(result->ClearShaderPlain, "uDepth");
|
||||||
glBindFragDataLocation(result->ClearShaderPlain[2], 1, "oAttr");
|
result->ClearUniformLoc[2] = glGetUniformLocation(result->ClearShaderPlain, "uOpaquePolyID");
|
||||||
|
result->ClearUniformLoc[3] = glGetUniformLocation(result->ClearShaderPlain, "uFogFlag");
|
||||||
if (!OpenGL::LinkShaderProgram(result->ClearShaderPlain))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
result->ClearUniformLoc[0] = glGetUniformLocation(result->ClearShaderPlain[2], "uColor");
|
|
||||||
result->ClearUniformLoc[1] = glGetUniformLocation(result->ClearShaderPlain[2], "uDepth");
|
|
||||||
result->ClearUniformLoc[2] = glGetUniformLocation(result->ClearShaderPlain[2], "uOpaquePolyID");
|
|
||||||
result->ClearUniformLoc[3] = glGetUniformLocation(result->ClearShaderPlain[2], "uFogFlag");
|
|
||||||
|
|
||||||
memset(result->RenderShader, 0, sizeof(RenderShader));
|
memset(result->RenderShader, 0, sizeof(RenderShader));
|
||||||
|
|
||||||
@ -160,42 +151,35 @@ std::unique_ptr<GLRenderer> GLRenderer::New() noexcept
|
|||||||
if (!result->BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer, kRenderVS_W, kRenderFS_WSM))
|
if (!result->BuildRenderShader(RenderFlag_ShadowMask | RenderFlag_WBuffer, kRenderVS_W, kRenderFS_WSM))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!OpenGL::BuildShaderProgram(kFinalPassVS, kFinalPassEdgeFS, result->FinalPassEdgeShader, "FinalPassEdgeShader"))
|
if (!OpenGL::CompileVertexFragmentProgram(result->FinalPassEdgeShader,
|
||||||
|
kFinalPassVS, kFinalPassEdgeFS,
|
||||||
|
"FinalPassEdgeShader",
|
||||||
|
{{"vPosition", 0}},
|
||||||
|
{{"oColor", 0}}))
|
||||||
|
return nullptr;
|
||||||
|
if (!OpenGL::CompileVertexFragmentProgram(result->FinalPassFogShader,
|
||||||
|
kFinalPassVS, kFinalPassFogFS,
|
||||||
|
"FinalPassFogShader",
|
||||||
|
{{"vPosition", 0}},
|
||||||
|
{{"oColor", 0}}))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!OpenGL::BuildShaderProgram(kFinalPassVS, kFinalPassFogFS, result->FinalPassFogShader, "FinalPassFogShader"))
|
GLuint uni_id = glGetUniformBlockIndex(result->FinalPassEdgeShader, "uConfig");
|
||||||
return nullptr;
|
glUniformBlockBinding(result->FinalPassEdgeShader, uni_id, 0);
|
||||||
|
|
||||||
glBindAttribLocation(result->FinalPassEdgeShader[2], 0, "vPosition");
|
glUseProgram(result->FinalPassEdgeShader);
|
||||||
glBindFragDataLocation(result->FinalPassEdgeShader[2], 0, "oColor");
|
uni_id = glGetUniformLocation(result->FinalPassEdgeShader, "DepthBuffer");
|
||||||
|
|
||||||
if (!OpenGL::LinkShaderProgram(result->FinalPassEdgeShader))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
GLint uni_id = glGetUniformBlockIndex(result->FinalPassEdgeShader[2], "uConfig");
|
|
||||||
glUniformBlockBinding(result->FinalPassEdgeShader[2], uni_id, 0);
|
|
||||||
|
|
||||||
glUseProgram(result->FinalPassEdgeShader[2]);
|
|
||||||
|
|
||||||
uni_id = glGetUniformLocation(result->FinalPassEdgeShader[2], "DepthBuffer");
|
|
||||||
glUniform1i(uni_id, 0);
|
glUniform1i(uni_id, 0);
|
||||||
uni_id = glGetUniformLocation(result->FinalPassEdgeShader[2], "AttrBuffer");
|
uni_id = glGetUniformLocation(result->FinalPassEdgeShader, "AttrBuffer");
|
||||||
glUniform1i(uni_id, 1);
|
glUniform1i(uni_id, 1);
|
||||||
|
|
||||||
glBindAttribLocation(result->FinalPassFogShader[2], 0, "vPosition");
|
uni_id = glGetUniformBlockIndex(result->FinalPassFogShader, "uConfig");
|
||||||
glBindFragDataLocation(result->FinalPassFogShader[2], 0, "oColor");
|
glUniformBlockBinding(result->FinalPassFogShader, uni_id, 0);
|
||||||
|
|
||||||
if (!OpenGL::LinkShaderProgram(result->FinalPassFogShader))
|
glUseProgram(result->FinalPassFogShader);
|
||||||
return nullptr;
|
uni_id = glGetUniformLocation(result->FinalPassFogShader, "DepthBuffer");
|
||||||
|
|
||||||
uni_id = glGetUniformBlockIndex(result->FinalPassFogShader[2], "uConfig");
|
|
||||||
glUniformBlockBinding(result->FinalPassFogShader[2], uni_id, 0);
|
|
||||||
|
|
||||||
glUseProgram(result->FinalPassFogShader[2]);
|
|
||||||
|
|
||||||
uni_id = glGetUniformLocation(result->FinalPassFogShader[2], "DepthBuffer");
|
|
||||||
glUniform1i(uni_id, 0);
|
glUniform1i(uni_id, 0);
|
||||||
uni_id = glGetUniformLocation(result->FinalPassFogShader[2], "AttrBuffer");
|
uni_id = glGetUniformLocation(result->FinalPassFogShader, "AttrBuffer");
|
||||||
glUniform1i(uni_id, 1);
|
glUniform1i(uni_id, 1);
|
||||||
|
|
||||||
|
|
||||||
@ -320,8 +304,8 @@ GLRenderer::~GLRenderer()
|
|||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
if (!RenderShader[i][2]) continue;
|
if (!RenderShader[i]) continue;
|
||||||
OpenGL::DeleteShaderProgram(RenderShader[i]);
|
glDeleteProgram(RenderShader[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1093,7 +1077,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
|||||||
// edge marking
|
// edge marking
|
||||||
// TODO: depth/polyid values at screen edges
|
// TODO: depth/polyid values at screen edges
|
||||||
|
|
||||||
glUseProgram(FinalPassEdgeShader[2]);
|
glUseProgram(FinalPassEdgeShader);
|
||||||
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
|
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
|
||||||
|
|
||||||
@ -1104,7 +1088,7 @@ void GLRenderer::RenderSceneChunk(int y, int h)
|
|||||||
{
|
{
|
||||||
// fog
|
// fog
|
||||||
|
|
||||||
glUseProgram(FinalPassFogShader[2]);
|
glUseProgram(FinalPassFogShader);
|
||||||
|
|
||||||
if (RenderDispCnt & (1<<6))
|
if (RenderDispCnt & (1<<6))
|
||||||
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
@ -1238,7 +1222,7 @@ void GLRenderer::RenderFrame()
|
|||||||
// TODO: check whether 'clear polygon ID' affects translucent polyID
|
// TODO: check whether 'clear polygon ID' affects translucent polyID
|
||||||
// (for example when alpha is 1..30)
|
// (for example when alpha is 1..30)
|
||||||
{
|
{
|
||||||
glUseProgram(ClearShaderPlain[2]);
|
glUseProgram(ClearShaderPlain);
|
||||||
glDepthFunc(GL_ALWAYS);
|
glDepthFunc(GL_ALWAYS);
|
||||||
|
|
||||||
u32 r = RenderClearAttr1 & 0x1F;
|
u32 r = RenderClearAttr1 & 0x1F;
|
||||||
|
@ -84,13 +84,13 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GLuint ClearShaderPlain[3] {};
|
GLuint ClearShaderPlain {};
|
||||||
|
|
||||||
GLuint RenderShader[16][3] {};
|
GLuint RenderShader[16] {};
|
||||||
GLuint CurShaderID = -1;
|
GLuint CurShaderID = -1;
|
||||||
|
|
||||||
GLuint FinalPassEdgeShader[3] {};
|
GLuint FinalPassEdgeShader {};
|
||||||
GLuint FinalPassFogShader[3] {};
|
GLuint FinalPassFogShader {};
|
||||||
|
|
||||||
// std140 compliant structure
|
// std140 compliant structure
|
||||||
struct
|
struct
|
||||||
|
@ -36,32 +36,27 @@ using namespace OpenGL;
|
|||||||
std::unique_ptr<GLCompositor> GLCompositor::New() noexcept
|
std::unique_ptr<GLCompositor> GLCompositor::New() noexcept
|
||||||
{
|
{
|
||||||
assert(glBindAttribLocation != nullptr);
|
assert(glBindAttribLocation != nullptr);
|
||||||
|
GLuint CompShader {};
|
||||||
|
|
||||||
std::array<GLuint, 3> CompShader {};
|
if (!OpenGL::CompileVertexFragmentProgram(CompShader,
|
||||||
if (!OpenGL::BuildShaderProgram(kCompositorVS, kCompositorFS_Nearest, &CompShader[0], "CompositorShader"))
|
kCompositorVS, kCompositorFS_Nearest,
|
||||||
return nullptr;
|
"CompositorShader",
|
||||||
|
{{"vPosition", 0}, {"vTexcoord", 1}},
|
||||||
glBindAttribLocation(CompShader[2], 0, "vPosition");
|
{{"oColor", 0}}))
|
||||||
glBindAttribLocation(CompShader[2], 1, "vTexcoord");
|
|
||||||
glBindFragDataLocation(CompShader[2], 0, "oColor");
|
|
||||||
|
|
||||||
if (!OpenGL::LinkShaderProgram(CompShader.data()))
|
|
||||||
// OpenGL::LinkShaderProgram already deletes the shader program object
|
|
||||||
// if linking the shaders together failed.
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return std::unique_ptr<GLCompositor>(new GLCompositor(CompShader));
|
return std::unique_ptr<GLCompositor>(new GLCompositor(CompShader));
|
||||||
}
|
}
|
||||||
|
|
||||||
GLCompositor::GLCompositor(std::array<GLuint, 3> compShader) noexcept : CompShader(compShader)
|
GLCompositor::GLCompositor(GLuint compShader) noexcept : CompShader(compShader)
|
||||||
{
|
{
|
||||||
CompScaleLoc = glGetUniformLocation(CompShader[2], "u3DScale");
|
CompScaleLoc = glGetUniformLocation(CompShader, "u3DScale");
|
||||||
Comp3DXPosLoc = glGetUniformLocation(CompShader[2], "u3DXPos");
|
Comp3DXPosLoc = glGetUniformLocation(CompShader, "u3DXPos");
|
||||||
|
|
||||||
glUseProgram(CompShader[2]);
|
glUseProgram(CompShader);
|
||||||
GLuint screenTextureUniform = glGetUniformLocation(CompShader[2], "ScreenTex");
|
GLuint screenTextureUniform = glGetUniformLocation(CompShader, "ScreenTex");
|
||||||
glUniform1i(screenTextureUniform, 0);
|
glUniform1i(screenTextureUniform, 0);
|
||||||
GLuint _3dTextureUniform = glGetUniformLocation(CompShader[2], "_3DTex");
|
GLuint _3dTextureUniform = glGetUniformLocation(CompShader, "_3DTex");
|
||||||
glUniform1i(_3dTextureUniform, 1);
|
glUniform1i(_3dTextureUniform, 1);
|
||||||
|
|
||||||
// all this mess is to prevent bleeding
|
// all this mess is to prevent bleeding
|
||||||
@ -136,7 +131,7 @@ GLCompositor::~GLCompositor()
|
|||||||
glDeleteVertexArrays(1, &CompVertexArrayID);
|
glDeleteVertexArrays(1, &CompVertexArrayID);
|
||||||
glDeleteBuffers(1, &CompVertexBufferID);
|
glDeleteBuffers(1, &CompVertexBufferID);
|
||||||
|
|
||||||
OpenGL::DeleteShaderProgram(CompShader.data());
|
glDeleteProgram(CompShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLCompositor::Reset()
|
void GLCompositor::Reset()
|
||||||
@ -200,7 +195,7 @@ void GLCompositor::RenderFrame()
|
|||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
// TODO: select more shaders (filtering, etc)
|
// TODO: select more shaders (filtering, etc)
|
||||||
OpenGL::UseShaderProgram(CompShader.data());
|
glUseProgram(CompShader);
|
||||||
glUniform1ui(CompScaleLoc, Scale);
|
glUniform1ui(CompScaleLoc, Scale);
|
||||||
|
|
||||||
// TODO: support setting this midframe, if ever needed
|
// TODO: support setting this midframe, if ever needed
|
||||||
|
@ -44,12 +44,12 @@ public:
|
|||||||
void RenderFrame();
|
void RenderFrame();
|
||||||
void BindOutputTexture(int buf);
|
void BindOutputTexture(int buf);
|
||||||
private:
|
private:
|
||||||
GLCompositor(std::array<GLuint, 3> CompShader) noexcept;
|
GLCompositor(GLuint CompShader) noexcept;
|
||||||
|
|
||||||
int Scale;
|
int Scale;
|
||||||
int ScreenH, ScreenW;
|
int ScreenH, ScreenW;
|
||||||
|
|
||||||
std::array<GLuint, 3> CompShader;
|
GLuint CompShader;
|
||||||
GLuint CompScaleLoc;
|
GLuint CompScaleLoc;
|
||||||
GLuint Comp3DXPosLoc;
|
GLuint Comp3DXPosLoc;
|
||||||
|
|
||||||
|
@ -26,6 +26,32 @@
|
|||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
inline u64 GetRangedBitMask(u32 idx, u32 startBit, u32 bitsCount)
|
||||||
|
{
|
||||||
|
u32 startEntry = startBit >> 6;
|
||||||
|
u64 entriesCount = ((startBit + bitsCount + 0x3F) >> 6) - startEntry;
|
||||||
|
|
||||||
|
if (entriesCount > 1)
|
||||||
|
{
|
||||||
|
if (idx == startEntry)
|
||||||
|
return 0xFFFFFFFFFFFFFFFF << (startBit & 0x3F);
|
||||||
|
if (((startBit + bitsCount) & 0x3F) && idx == startEntry + entriesCount - 1)
|
||||||
|
return ~(0xFFFFFFFFFFFFFFFF << ((startBit + bitsCount) & 0x3F));
|
||||||
|
else
|
||||||
|
return 0xFFFFFFFFFFFFFFFF;
|
||||||
|
|
||||||
|
return 0xFFFFFFFFFFFFFFFF;
|
||||||
|
}
|
||||||
|
else if (idx == startEntry)
|
||||||
|
{
|
||||||
|
return ((1ULL << bitsCount) - 1) << (startBit & 0x3F);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// like std::bitset but less stupid and optimised for
|
// like std::bitset but less stupid and optimised for
|
||||||
// our use case (keeping track of memory invalidations)
|
// our use case (keeping track of memory invalidations)
|
||||||
|
|
||||||
@ -164,6 +190,11 @@ struct NonStupidBitField
|
|||||||
return Ref{*this, idx};
|
return Ref{*this, idx};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator[](u32 idx) const
|
||||||
|
{
|
||||||
|
return Data[idx >> 6] & (1ULL << (idx & 0x3F));
|
||||||
|
}
|
||||||
|
|
||||||
void SetRange(u32 startBit, u32 bitsCount)
|
void SetRange(u32 startBit, u32 bitsCount)
|
||||||
{
|
{
|
||||||
u32 startEntry = startBit >> 6;
|
u32 startEntry = startBit >> 6;
|
||||||
@ -185,6 +216,26 @@ struct NonStupidBitField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Min() const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < DataLength; i++)
|
||||||
|
{
|
||||||
|
if (Data[i])
|
||||||
|
return i * 64 + __builtin_ctzll(Data[i]);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Max() const
|
||||||
|
{
|
||||||
|
for (int i = DataLength - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (Data[i])
|
||||||
|
return i * 64 + (63 - __builtin_clzll(Data[i]));
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
NonStupidBitField& operator|=(const NonStupidBitField<Size>& other)
|
NonStupidBitField& operator|=(const NonStupidBitField<Size>& other)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < DataLength; i++)
|
for (u32 i = 0; i < DataLength; i++)
|
||||||
@ -193,6 +244,7 @@ struct NonStupidBitField
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
NonStupidBitField& operator&=(const NonStupidBitField<Size>& other)
|
NonStupidBitField& operator&=(const NonStupidBitField<Size>& other)
|
||||||
{
|
{
|
||||||
for (u32 i = 0; i < DataLength; i++)
|
for (u32 i = 0; i < DataLength; i++)
|
||||||
@ -201,6 +253,20 @@ struct NonStupidBitField
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < DataLength - 1; i++)
|
||||||
|
{
|
||||||
|
if (Data[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (Data[DataLength-1] & ((Size&0x3F) ? ~(0xFFFFFFFFFFFFFFFF << (Size&0x3F)) : 0xFFFFFFFFFFFFFFFF))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,9 @@ using Platform::LogLevel;
|
|||||||
namespace OpenGL
|
namespace OpenGL
|
||||||
{
|
{
|
||||||
|
|
||||||
bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name)
|
#define checkGLError() if (glGetError() != GL_NO_ERROR) printf("error %d\n", __LINE__)
|
||||||
|
|
||||||
|
bool CompilerShader(GLuint& id, const char* source, const char* name, const char* type)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int res;
|
int res;
|
||||||
@ -35,61 +37,31 @@ bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char*
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ids[0] = glCreateShader(GL_VERTEX_SHADER);
|
len = strlen(source);
|
||||||
len = strlen(vs);
|
glShaderSource(id, 1, &source, &len);
|
||||||
glShaderSource(ids[0], 1, &vs, &len);
|
checkGLError();
|
||||||
glCompileShader(ids[0]);
|
glCompileShader(id);
|
||||||
|
checkGLError();
|
||||||
|
|
||||||
glGetShaderiv(ids[0], GL_COMPILE_STATUS, &res);
|
glGetShaderiv(id, GL_COMPILE_STATUS, &res);
|
||||||
|
checkGLError();
|
||||||
if (res != GL_TRUE)
|
if (res != GL_TRUE)
|
||||||
{
|
{
|
||||||
glGetShaderiv(ids[0], GL_INFO_LOG_LENGTH, &res);
|
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &res);
|
||||||
if (res < 1) res = 1024;
|
if (res < 1) res = 1024;
|
||||||
char* log = new char[res+1];
|
char* log = new char[res+1];
|
||||||
glGetShaderInfoLog(ids[0], res+1, NULL, log);
|
glGetShaderInfoLog(id, res+1, NULL, log);
|
||||||
Log(LogLevel::Error, "OpenGL: failed to compile vertex shader %s: %s\n", name, log);
|
Log(LogLevel::Error, "OpenGL: failed to compile %s shader %s: %s\n", type, name, log);
|
||||||
Log(LogLevel::Debug, "shader source:\n--\n%s\n--\n", vs);
|
Log(LogLevel::Debug, "shader source:\n--\n%s\n--\n", source);
|
||||||
delete[] log;
|
delete[] log;
|
||||||
|
|
||||||
glDeleteShader(ids[0]);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ids[1] = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
len = strlen(fs);
|
|
||||||
glShaderSource(ids[1], 1, &fs, &len);
|
|
||||||
glCompileShader(ids[1]);
|
|
||||||
|
|
||||||
glGetShaderiv(ids[1], GL_COMPILE_STATUS, &res);
|
|
||||||
if (res != GL_TRUE)
|
|
||||||
{
|
|
||||||
glGetShaderiv(ids[1], GL_INFO_LOG_LENGTH, &res);
|
|
||||||
if (res < 1) res = 1024;
|
|
||||||
char* log = new char[res+1];
|
|
||||||
glGetShaderInfoLog(ids[1], res+1, NULL, log);
|
|
||||||
Log(LogLevel::Error, "OpenGL: failed to compile fragment shader %s: %s\n", name, log);
|
|
||||||
//printf("shader source:\n--\n%s\n--\n", fs);
|
|
||||||
delete[] log;
|
|
||||||
|
|
||||||
FILE* logf = fopen("shaderfail.log", "w");
|
|
||||||
fwrite(fs, len+1, 1, logf);
|
|
||||||
fclose(logf);
|
|
||||||
|
|
||||||
glDeleteShader(ids[0]);
|
|
||||||
glDeleteShader(ids[1]);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ids[2] = glCreateProgram();
|
|
||||||
glAttachShader(ids[2], ids[0]);
|
|
||||||
glAttachShader(ids[2], ids[1]);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinkShaderProgram(GLuint* ids)
|
bool LinkProgram(GLuint& result, GLuint* ids, int numIds)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@ -99,46 +71,100 @@ bool LinkShaderProgram(GLuint* ids)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
glLinkProgram(ids[2]);
|
for (int i = 0; i < numIds; i++)
|
||||||
|
{
|
||||||
|
glAttachShader(result, ids[i]);
|
||||||
|
checkGLError();
|
||||||
|
}
|
||||||
|
|
||||||
glDetachShader(ids[2], ids[0]);
|
glLinkProgram(result);
|
||||||
glDetachShader(ids[2], ids[1]);
|
|
||||||
|
|
||||||
glDeleteShader(ids[0]);
|
for (int i = 0; i < numIds; i++)
|
||||||
glDeleteShader(ids[1]);
|
glDetachShader(result, ids[i]);
|
||||||
|
|
||||||
glGetProgramiv(ids[2], GL_LINK_STATUS, &res);
|
glGetProgramiv(result, GL_LINK_STATUS, &res);
|
||||||
if (res != GL_TRUE)
|
if (res != GL_TRUE)
|
||||||
{
|
{
|
||||||
glGetProgramiv(ids[2], GL_INFO_LOG_LENGTH, &res);
|
glGetProgramiv(result, GL_INFO_LOG_LENGTH, &res);
|
||||||
if (res < 1) res = 1024;
|
if (res < 1) res = 1024;
|
||||||
char* log = new char[res+1];
|
char* log = new char[res+1];
|
||||||
glGetProgramInfoLog(ids[2], res+1, NULL, log);
|
glGetProgramInfoLog(result, res+1, NULL, log);
|
||||||
Log(LogLevel::Error, "OpenGL: failed to link shader program: %s\n", log);
|
Log(LogLevel::Error, "OpenGL: failed to link shader program: %s\n", log);
|
||||||
delete[] log;
|
delete[] log;
|
||||||
|
|
||||||
glDeleteProgram(ids[2]);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteShaderProgram(GLuint* ids)
|
bool CompileComputeProgram(GLuint& result, const char* source, const char* name)
|
||||||
{
|
{
|
||||||
|
GLuint shader = glCreateShader(GL_COMPUTE_SHADER);
|
||||||
|
bool linkingSucess = false;
|
||||||
if (glDeleteProgram)
|
if (glDeleteProgram)
|
||||||
{ // If OpenGL isn't loaded, then there's no shader program to delete
|
{ // If OpenGL isn't loaded, then there's no shader program to delete
|
||||||
glDeleteProgram(ids[2]);
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = glCreateProgram();
|
||||||
|
|
||||||
|
printf("compiling %s", name);
|
||||||
|
if (!CompilerShader(shader, source, name, "compute"))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
linkingSucess = LinkProgram(result, &shader, 1);
|
||||||
|
|
||||||
|
error:
|
||||||
|
glDeleteShader(shader);
|
||||||
|
|
||||||
|
if (!linkingSucess)
|
||||||
|
glDeleteProgram(result);
|
||||||
|
|
||||||
|
return linkingSucess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UseShaderProgram(GLuint* ids)
|
bool CompileVertexFragmentProgram(GLuint& result,
|
||||||
|
const char* vs, const char* fs,
|
||||||
|
const char* name,
|
||||||
|
const std::initializer_list<AttributeTarget>& vertexInAttrs,
|
||||||
|
const std::initializer_list<AttributeTarget>& fragmentOutAttrs)
|
||||||
{
|
{
|
||||||
if (glUseProgram)
|
GLuint shaders[2] =
|
||||||
{ // If OpenGL isn't loaded, then there's no shader program to use
|
{
|
||||||
glUseProgram(ids[2]);
|
glCreateShader(GL_VERTEX_SHADER),
|
||||||
|
glCreateShader(GL_FRAGMENT_SHADER)
|
||||||
|
};
|
||||||
|
result = glCreateProgram();
|
||||||
|
|
||||||
|
bool linkingSucess = false;
|
||||||
|
|
||||||
|
if (!CompilerShader(shaders[0], vs, name, "vertex"))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!CompilerShader(shaders[1], fs, name, "fragment"))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
|
||||||
|
for (const AttributeTarget& target : vertexInAttrs)
|
||||||
|
{
|
||||||
|
glBindAttribLocation(result, target.Location, target.Name);
|
||||||
}
|
}
|
||||||
|
for (const AttributeTarget& target : fragmentOutAttrs)
|
||||||
|
{
|
||||||
|
glBindFragDataLocation(result, target.Location, target.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
linkingSucess = LinkProgram(result, shaders, 2);
|
||||||
|
|
||||||
|
error:
|
||||||
|
glDeleteShader(shaders[1]);
|
||||||
|
glDeleteShader(shaders[0]);
|
||||||
|
|
||||||
|
if (!linkingSucess)
|
||||||
|
glDeleteProgram(result);
|
||||||
|
|
||||||
|
return linkingSucess;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,19 @@
|
|||||||
namespace OpenGL
|
namespace OpenGL
|
||||||
{
|
{
|
||||||
|
|
||||||
bool BuildShaderProgram(const char* vs, const char* fs, GLuint* ids, const char* name);
|
struct AttributeTarget
|
||||||
bool LinkShaderProgram(GLuint* ids);
|
{
|
||||||
void DeleteShaderProgram(GLuint* ids);
|
const char* Name;
|
||||||
void UseShaderProgram(GLuint* ids);
|
u32 Location;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool CompileVertexFragmentProgram(GLuint& result,
|
||||||
|
const char* vs, const char* fs,
|
||||||
|
const char* name,
|
||||||
|
const std::initializer_list<AttributeTarget>& vertexInAttrs,
|
||||||
|
const std::initializer_list<AttributeTarget>& fragmentOutAttrs);
|
||||||
|
|
||||||
|
bool CompileComputeProgram(GLuint& result, const char* source, const char* name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ set(SOURCES_QT_SDL
|
|||||||
ROMInfoDialog.cpp
|
ROMInfoDialog.cpp
|
||||||
RAMInfoDialog.cpp
|
RAMInfoDialog.cpp
|
||||||
TitleManagerDialog.cpp
|
TitleManagerDialog.cpp
|
||||||
|
RTCSettingsDialog.cpp
|
||||||
Input.cpp
|
Input.cpp
|
||||||
LAN_PCap.cpp
|
LAN_PCap.cpp
|
||||||
LAN_Socket.cpp
|
LAN_Socket.cpp
|
||||||
|
@ -57,7 +57,7 @@ struct Item
|
|||||||
|
|
||||||
std::deque<Item> ItemQueue;
|
std::deque<Item> ItemQueue;
|
||||||
|
|
||||||
GLuint Shader[3];
|
GLuint Shader;
|
||||||
GLint uScreenSize, uOSDPos, uOSDSize;
|
GLint uScreenSize, uOSDPos, uOSDSize;
|
||||||
GLfloat uScaleFactor;
|
GLfloat uScaleFactor;
|
||||||
GLuint OSDVertexArray;
|
GLuint OSDVertexArray;
|
||||||
@ -70,20 +70,19 @@ bool Init(bool openGL)
|
|||||||
{
|
{
|
||||||
if (openGL)
|
if (openGL)
|
||||||
{
|
{
|
||||||
OpenGL::BuildShaderProgram(kScreenVS_OSD, kScreenFS_OSD, Shader, "OSDShader");
|
OpenGL::CompileVertexFragmentProgram(Shader,
|
||||||
|
kScreenVS_OSD, kScreenFS_OSD,
|
||||||
|
"OSDShader",
|
||||||
|
{{"vPosition", 0}},
|
||||||
|
{{"oColor", 0}});
|
||||||
|
|
||||||
GLuint pid = Shader[2];
|
glUseProgram(Shader);
|
||||||
glBindAttribLocation(pid, 0, "vPosition");
|
glUniform1i(glGetUniformLocation(Shader, "OSDTex"), 0);
|
||||||
glBindFragDataLocation(pid, 0, "oColor");
|
|
||||||
|
|
||||||
OpenGL::LinkShaderProgram(Shader);
|
uScreenSize = glGetUniformLocation(Shader, "uScreenSize");
|
||||||
glUseProgram(pid);
|
uOSDPos = glGetUniformLocation(Shader, "uOSDPos");
|
||||||
glUniform1i(glGetUniformLocation(pid, "OSDTex"), 0);
|
uOSDSize = glGetUniformLocation(Shader, "uOSDSize");
|
||||||
|
uScaleFactor = glGetUniformLocation(Shader, "uScaleFactor");
|
||||||
uScreenSize = glGetUniformLocation(pid, "uScreenSize");
|
|
||||||
uOSDPos = glGetUniformLocation(pid, "uOSDPos");
|
|
||||||
uOSDSize = glGetUniformLocation(pid, "uOSDSize");
|
|
||||||
uScaleFactor = glGetUniformLocation(pid, "uScaleFactor");
|
|
||||||
|
|
||||||
float vertices[6*2] =
|
float vertices[6*2] =
|
||||||
{
|
{
|
||||||
@ -425,7 +424,7 @@ void DrawGL(float w, float h)
|
|||||||
|
|
||||||
u32 y = kOSDMargin;
|
u32 y = kOSDMargin;
|
||||||
|
|
||||||
glUseProgram(Shader[2]);
|
glUseProgram(Shader);
|
||||||
|
|
||||||
glUniform2f(uScreenSize, w, h);
|
glUniform2f(uScreenSize, w, h);
|
||||||
glUniform1f(uScaleFactor, mainWindow->devicePixelRatioF());
|
glUniform1f(uScaleFactor, mainWindow->devicePixelRatioF());
|
||||||
|
@ -228,19 +228,17 @@ void EmuThread::initOpenGL()
|
|||||||
oglContext = windowctx;
|
oglContext = windowctx;
|
||||||
oglContext->MakeCurrent();
|
oglContext->MakeCurrent();
|
||||||
|
|
||||||
OpenGL::BuildShaderProgram(kScreenVS, kScreenFS, screenShaderProgram, "ScreenShader");
|
OpenGL::CompileVertexFragmentProgram(screenShaderProgram,
|
||||||
GLuint pid = screenShaderProgram[2];
|
kScreenVS, kScreenFS,
|
||||||
glBindAttribLocation(pid, 0, "vPosition");
|
"ScreenShader",
|
||||||
glBindAttribLocation(pid, 1, "vTexcoord");
|
{{"vPosition", 0}, {"vTexcoord", 1}},
|
||||||
glBindFragDataLocation(pid, 0, "oColor");
|
{{"oColor", 0}});
|
||||||
|
|
||||||
OpenGL::LinkShaderProgram(screenShaderProgram);
|
glUseProgram(screenShaderProgram);
|
||||||
|
glUniform1i(glGetUniformLocation(screenShaderProgram, "ScreenTex"), 0);
|
||||||
|
|
||||||
glUseProgram(pid);
|
screenShaderScreenSizeULoc = glGetUniformLocation(screenShaderProgram, "uScreenSize");
|
||||||
glUniform1i(glGetUniformLocation(pid, "ScreenTex"), 0);
|
screenShaderTransformULoc = glGetUniformLocation(screenShaderProgram, "uTransform");
|
||||||
|
|
||||||
screenShaderScreenSizeULoc = glGetUniformLocation(pid, "uScreenSize");
|
|
||||||
screenShaderTransformULoc = glGetUniformLocation(pid, "uTransform");
|
|
||||||
|
|
||||||
// to prevent bleeding between both parts of the screen
|
// to prevent bleeding between both parts of the screen
|
||||||
// with bilinear filtering enabled
|
// with bilinear filtering enabled
|
||||||
@ -300,7 +298,7 @@ void EmuThread::deinitOpenGL()
|
|||||||
glDeleteVertexArrays(1, &screenVertexArray);
|
glDeleteVertexArrays(1, &screenVertexArray);
|
||||||
glDeleteBuffers(1, &screenVertexBuffer);
|
glDeleteBuffers(1, &screenVertexBuffer);
|
||||||
|
|
||||||
OpenGL::DeleteShaderProgram(screenShaderProgram);
|
glDeleteProgram(screenShaderProgram);
|
||||||
|
|
||||||
OSD::DeInit();
|
OSD::DeInit();
|
||||||
|
|
||||||
@ -749,7 +747,7 @@ void EmuThread::drawScreenGL()
|
|||||||
|
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
|
|
||||||
glUseProgram(screenShaderProgram[2]);
|
glUseProgram(screenShaderProgram);
|
||||||
glUniform2f(screenShaderScreenSizeULoc, w / factor, h / factor);
|
glUniform2f(screenShaderScreenSizeULoc, w / factor, h / factor);
|
||||||
|
|
||||||
int frontbuf = FrontBuffer;
|
int frontbuf = FrontBuffer;
|
||||||
|
@ -121,7 +121,7 @@ private:
|
|||||||
GL::Context* oglContext = nullptr;
|
GL::Context* oglContext = nullptr;
|
||||||
GLuint screenVertexBuffer, screenVertexArray;
|
GLuint screenVertexBuffer, screenVertexArray;
|
||||||
GLuint screenTexture;
|
GLuint screenTexture;
|
||||||
GLuint screenShaderProgram[3];
|
GLuint screenShaderProgram;
|
||||||
GLuint screenShaderTransformULoc, screenShaderScreenSizeULoc;
|
GLuint screenShaderTransformULoc, screenShaderScreenSizeULoc;
|
||||||
|
|
||||||
QMutex screenSettingsLock;
|
QMutex screenSettingsLock;
|
||||||
|
Reference in New Issue
Block a user