mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 14:19:55 -06:00
MERGEZORZ II
This commit is contained in:
@ -68,6 +68,7 @@ bool Threaded3D;
|
|||||||
|
|
||||||
int GL_ScaleFactor;
|
int GL_ScaleFactor;
|
||||||
bool GL_BetterPolygons;
|
bool GL_BetterPolygons;
|
||||||
|
bool GL_HiresCoordinates;
|
||||||
|
|
||||||
bool LimitFPS;
|
bool LimitFPS;
|
||||||
int MaxFPS;
|
int MaxFPS;
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "DSi_I2C.h"
|
#include "DSi_I2C.h"
|
||||||
#include "GPU3D_Soft.h"
|
#include "GPU3D_Soft.h"
|
||||||
#include "GPU3D_OpenGL.h"
|
#include "GPU3D_OpenGL.h"
|
||||||
|
#include "GPU3D_Compute.h"
|
||||||
|
|
||||||
#include "Savestate.h"
|
#include "Savestate.h"
|
||||||
|
|
||||||
@ -169,18 +170,7 @@ void EmuThread::run()
|
|||||||
//screenGL = nullptr;
|
//screenGL = nullptr;
|
||||||
//videoRenderer = 0;
|
//videoRenderer = 0;
|
||||||
|
|
||||||
if (videoRenderer == 0)
|
updateRenderer();
|
||||||
{ // If we're using the software renderer...
|
|
||||||
emuInstance->nds->GPU.SetRenderer3D(std::make_unique<SoftRenderer>(Config::Threaded3D != 0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mainWindow->makeCurrentGL();
|
|
||||||
|
|
||||||
auto glrenderer = melonDS::GLRenderer::New();
|
|
||||||
glrenderer->SetRenderSettings(Config::GL_BetterPolygons, Config::GL_ScaleFactor);
|
|
||||||
emuInstance->nds->GPU.SetRenderer3D(std::move(glrenderer));
|
|
||||||
}
|
|
||||||
|
|
||||||
Input::Init();
|
Input::Init();
|
||||||
|
|
||||||
@ -301,20 +291,9 @@ void EmuThread::run()
|
|||||||
videoRenderer = 0;
|
videoRenderer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
videoRenderer = useOpenGL ? Config::_3DRenderer : 0;
|
updateRenderer();
|
||||||
|
|
||||||
videoSettingsDirty = false;
|
videoSettingsDirty = false;
|
||||||
|
|
||||||
if (videoRenderer == 0)
|
|
||||||
{ // If we're using the software renderer...
|
|
||||||
emuInstance->nds->GPU.SetRenderer3D(std::make_unique<SoftRenderer>(Config::Threaded3D != 0));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto glrenderer = melonDS::GLRenderer::New();
|
|
||||||
glrenderer->SetRenderSettings(Config::GL_BetterPolygons, Config::GL_ScaleFactor);
|
|
||||||
emuInstance->nds->GPU.SetRenderer3D(std::move(glrenderer));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// process input and hotkeys
|
// process input and hotkeys
|
||||||
@ -362,7 +341,16 @@ void EmuThread::run()
|
|||||||
|
|
||||||
|
|
||||||
// emulate
|
// emulate
|
||||||
u32 nlines = emuInstance->nds->RunFrame();
|
u32 nlines;
|
||||||
|
if (emuInstance->nds->GPU.GetRenderer3D().NeedsShaderCompile())
|
||||||
|
{
|
||||||
|
compileShaders();
|
||||||
|
nlines = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nlines = emuInstance->nds->RunFrame();
|
||||||
|
}
|
||||||
|
|
||||||
if (emuInstance->ndsSave)
|
if (emuInstance->ndsSave)
|
||||||
emuInstance->ndsSave->CheckFlush();
|
emuInstance->ndsSave->CheckFlush();
|
||||||
@ -615,3 +603,53 @@ bool EmuThread::emuIsActive()
|
|||||||
{
|
{
|
||||||
return (RunningSomething == 1);
|
return (RunningSomething == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmuThread::updateRenderer()
|
||||||
|
{
|
||||||
|
if (videoRenderer != lastVideoRenderer)
|
||||||
|
{
|
||||||
|
printf("creating renderer %d\n", videoRenderer);
|
||||||
|
switch (videoRenderer)
|
||||||
|
{
|
||||||
|
case renderer3D_Software:
|
||||||
|
emuInstance->nds->GPU.SetRenderer3D(std::make_unique<SoftRenderer>());
|
||||||
|
break;
|
||||||
|
case renderer3D_OpenGL:
|
||||||
|
emuInstance->nds->GPU.SetRenderer3D(GLRenderer::New());
|
||||||
|
break;
|
||||||
|
case renderer3D_OpenGLCompute:
|
||||||
|
emuInstance->nds->GPU.SetRenderer3D(ComputeRenderer::New());
|
||||||
|
break;
|
||||||
|
default: __builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastVideoRenderer = videoRenderer;
|
||||||
|
|
||||||
|
switch (videoRenderer)
|
||||||
|
{
|
||||||
|
case renderer3D_Software:
|
||||||
|
static_cast<SoftRenderer&>(emuInstance->nds->GPU.GetRenderer3D()).SetThreaded(Config::Threaded3D, emuInstance->nds->GPU);
|
||||||
|
break;
|
||||||
|
case renderer3D_OpenGL:
|
||||||
|
static_cast<GLRenderer&>(emuInstance->nds->GPU.GetRenderer3D()).SetRenderSettings(Config::GL_BetterPolygons, Config::GL_ScaleFactor);
|
||||||
|
break;
|
||||||
|
case renderer3D_OpenGLCompute:
|
||||||
|
static_cast<ComputeRenderer&>(emuInstance->nds->GPU.GetRenderer3D()).SetRenderSettings(Config::GL_ScaleFactor, Config::GL_HiresCoordinates);
|
||||||
|
break;
|
||||||
|
default: __builtin_unreachable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuThread::compileShaders()
|
||||||
|
{
|
||||||
|
int currentShader, shadersCount;
|
||||||
|
u64 startTime = SDL_GetPerformanceCounter();
|
||||||
|
// kind of hacky to look at the wallclock, though it is easier than
|
||||||
|
// than disabling vsync
|
||||||
|
do
|
||||||
|
{
|
||||||
|
emuInstance->nds->GPU.GetRenderer3D().ShaderCompileStep(currentShader, shadersCount);
|
||||||
|
} while (emuInstance->nds->GPU.GetRenderer3D().NeedsShaderCompile() &&
|
||||||
|
(SDL_GetPerformanceCounter() - startTime) * perfCountsSec < 1.0 / 6.0);
|
||||||
|
mainWindow->osdAddMessage(0, "Compiling shader %d/%d", currentShader+1, shadersCount);
|
||||||
|
}
|
||||||
|
@ -93,6 +93,9 @@ signals:
|
|||||||
void syncVolumeLevel();
|
void syncVolumeLevel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateRenderer();
|
||||||
|
void compileShaders();
|
||||||
|
|
||||||
enum EmuStatusKind
|
enum EmuStatusKind
|
||||||
{
|
{
|
||||||
emuStatus_Exit,
|
emuStatus_Exit,
|
||||||
@ -125,6 +128,10 @@ private:
|
|||||||
|
|
||||||
int autoScreenSizing;
|
int autoScreenSizing;
|
||||||
|
|
||||||
|
int lastVideoRenderer = -1;
|
||||||
|
|
||||||
|
double perfCountsSec;
|
||||||
|
|
||||||
bool useOpenGL;
|
bool useOpenGL;
|
||||||
int videoRenderer;
|
int videoRenderer;
|
||||||
bool videoSettingsDirty;
|
bool videoSettingsDirty;
|
||||||
|
@ -739,19 +739,17 @@ void ScreenPanelGL::initOpenGL()
|
|||||||
|
|
||||||
glContext->MakeCurrent();
|
glContext->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
|
||||||
@ -800,20 +798,19 @@ void ScreenPanelGL::initOpenGL()
|
|||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 2, GL_RGBA, GL_UNSIGNED_BYTE, zeroData);
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 2, GL_RGBA, GL_UNSIGNED_BYTE, zeroData);
|
||||||
|
|
||||||
|
|
||||||
OpenGL::BuildShaderProgram(kScreenVS_OSD, kScreenFS_OSD, osdShader, "OSDShader");
|
OpenGL::CompileVertexFragmentProgram(osdShader,
|
||||||
|
kScreenVS_OSD, kScreenFS_OSD,
|
||||||
|
"OSDShader",
|
||||||
|
{{"vPosition", 0}},
|
||||||
|
{{"oColor", 0}});
|
||||||
|
|
||||||
pid = osdShader[2];
|
glUseProgram(osdShader);
|
||||||
glBindAttribLocation(pid, 0, "vPosition");
|
glUniform1i(glGetUniformLocation(osdShader, "OSDTex"), 0);
|
||||||
glBindFragDataLocation(pid, 0, "oColor");
|
|
||||||
|
|
||||||
OpenGL::LinkShaderProgram(osdShader);
|
osdScreenSizeULoc = glGetUniformLocation(osdShader, "uScreenSize");
|
||||||
glUseProgram(pid);
|
osdPosULoc = glGetUniformLocation(osdShader, "uOSDPos");
|
||||||
glUniform1i(glGetUniformLocation(pid, "OSDTex"), 0);
|
osdSizeULoc = glGetUniformLocation(osdShader, "uOSDSize");
|
||||||
|
osdScaleFactorULoc = glGetUniformLocation(osdShader, "uScaleFactor");
|
||||||
osdScreenSizeULoc = glGetUniformLocation(pid, "uScreenSize");
|
|
||||||
osdPosULoc = glGetUniformLocation(pid, "uOSDPos");
|
|
||||||
osdSizeULoc = glGetUniformLocation(pid, "uOSDSize");
|
|
||||||
osdScaleFactorULoc = glGetUniformLocation(pid, "uScaleFactor");
|
|
||||||
|
|
||||||
const float osdvertices[6*2] =
|
const float osdvertices[6*2] =
|
||||||
{
|
{
|
||||||
@ -848,7 +845,7 @@ void ScreenPanelGL::deinitOpenGL()
|
|||||||
glDeleteVertexArrays(1, &screenVertexArray);
|
glDeleteVertexArrays(1, &screenVertexArray);
|
||||||
glDeleteBuffers(1, &screenVertexBuffer);
|
glDeleteBuffers(1, &screenVertexBuffer);
|
||||||
|
|
||||||
OpenGL::DeleteShaderProgram(screenShaderProgram);
|
glDeleteProgram(screenShaderProgram);
|
||||||
|
|
||||||
|
|
||||||
for (const auto& [key, tex] : osdTextures)
|
for (const auto& [key, tex] : osdTextures)
|
||||||
@ -860,7 +857,7 @@ void ScreenPanelGL::deinitOpenGL()
|
|||||||
glDeleteVertexArrays(1, &osdVertexArray);
|
glDeleteVertexArrays(1, &osdVertexArray);
|
||||||
glDeleteBuffers(1, &osdVertexBuffer);
|
glDeleteBuffers(1, &osdVertexBuffer);
|
||||||
|
|
||||||
OpenGL::DeleteShaderProgram(osdShader);
|
glDeleteProgram(osdShader);
|
||||||
|
|
||||||
|
|
||||||
glContext->DoneCurrent();
|
glContext->DoneCurrent();
|
||||||
@ -928,7 +925,7 @@ void ScreenPanelGL::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 = emuThread->FrontBuffer;
|
int frontbuf = emuThread->FrontBuffer;
|
||||||
@ -938,7 +935,7 @@ void ScreenPanelGL::drawScreenGL()
|
|||||||
if (nds->GPU.GetRenderer3D().Accelerated)
|
if (nds->GPU.GetRenderer3D().Accelerated)
|
||||||
{
|
{
|
||||||
// hardware-accelerated render
|
// hardware-accelerated render
|
||||||
static_cast<GLRenderer&>(nds->GPU.GetRenderer3D()).GetCompositor().BindOutputTexture(frontbuf);
|
nds->GPU.GetRenderer3D().BindOutputTexture(frontbuf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -979,7 +976,7 @@ void ScreenPanelGL::drawScreenGL()
|
|||||||
|
|
||||||
u32 y = kOSDMargin;
|
u32 y = kOSDMargin;
|
||||||
|
|
||||||
glUseProgram(osdShader[2]);
|
glUseProgram(osdShader);
|
||||||
|
|
||||||
glUniform2f(osdScreenSizeULoc, w, h);
|
glUniform2f(osdScreenSizeULoc, w, h);
|
||||||
glUniform1f(osdScaleFactorULoc, factor);
|
glUniform1f(osdScaleFactorULoc, factor);
|
||||||
|
Reference in New Issue
Block a user