mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-23 14:19:55 -06:00
Compute shader renderer (#2041)
* nothing works yet * don't double buffer 3D framebuffers for the GL Renderer looks like leftovers from when 3D+2D composition was done in the frontend * oops * it works! * implement display capture for compute renderer it's actually just all stolen from the regular OpenGL renderer * fix bad indirect call * handle cleanup properly * add hires rendering to the compute shader renderer * fix UB also misc changes to use more unsigned multiplication also fix framebuffer resize * correct edge filling behaviour when AA is disabled * fix full color textures * fix edge marking (polygon id is 6-bit not 5) also make the code a bit nicer * take all edge cases into account for XMin/XMax calculation * use hires coordinate again * stop using fixed size buffers based on scale factor in shaders this makes shader compile times tolerable on Wintel - beginning of the shader cache - increase size of tile idx in workdesc to 20 bits * apparently & is not defined on bvec4 why does this even compile on Intel and Nvidia? * put the texture cache into it's own file * add compute shader renderer properly to the GUI also add option to toggle using high resolution vertex coordinates * unbind sampler object in compute shader renderer * fix GetRangedBitMask for 64 bit aligned 64 bits pretty embarassing * convert NonStupidBitfield.h back to LF only new lines * actually adapt to latest changes * fix stupid merge * actually make compute shader renderer work with newest changes * show progress on shader compilation * remove merge leftover
This commit is contained in:
@ -22,6 +22,7 @@
|
||||
#include <inttypes.h>
|
||||
#include "Platform.h"
|
||||
#include "Config.h"
|
||||
#include "GPU.h"
|
||||
|
||||
|
||||
namespace Config
|
||||
@ -59,6 +60,7 @@ bool Threaded3D;
|
||||
|
||||
int GL_ScaleFactor;
|
||||
bool GL_BetterPolygons;
|
||||
bool GL_HiresCoordinates;
|
||||
|
||||
bool LimitFPS;
|
||||
int MaxFPS;
|
||||
@ -246,11 +248,12 @@ ConfigEntry ConfigFile[] =
|
||||
{"ScreenVSync", 1, &ScreenVSync, false, false},
|
||||
{"ScreenVSyncInterval", 0, &ScreenVSyncInterval, 1, false},
|
||||
|
||||
{"3DRenderer", 0, &_3DRenderer, 0, false},
|
||||
{"3DRenderer", 0, &_3DRenderer, renderer3D_Software, false},
|
||||
{"Threaded3D", 1, &Threaded3D, true, false},
|
||||
|
||||
{"GL_ScaleFactor", 0, &GL_ScaleFactor, 1, false},
|
||||
{"GL_BetterPolygons", 1, &GL_BetterPolygons, false, false},
|
||||
{"GL_HiresCoordinates", 1, &GL_HiresCoordinates, true, false},
|
||||
|
||||
{"LimitFPS", 1, &LimitFPS, true, false},
|
||||
{"MaxFPS", 0, &MaxFPS, 1000, false},
|
||||
|
@ -51,6 +51,16 @@ enum
|
||||
micInputType_MAX,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
renderer3D_Software = 0,
|
||||
#ifdef OGLRENDERER_ENABLED
|
||||
renderer3D_OpenGL,
|
||||
renderer3D_OpenGLCompute,
|
||||
#endif
|
||||
renderer3D_Max,
|
||||
};
|
||||
|
||||
namespace Config
|
||||
{
|
||||
|
||||
@ -103,6 +113,7 @@ extern bool Threaded3D;
|
||||
|
||||
extern int GL_ScaleFactor;
|
||||
extern bool GL_BetterPolygons;
|
||||
extern bool GL_HiresCoordinates;
|
||||
|
||||
extern bool LimitFPS;
|
||||
extern int MaxFPS;
|
||||
|
@ -52,10 +52,12 @@
|
||||
#include "DSi_I2C.h"
|
||||
#include "GPU3D_Soft.h"
|
||||
#include "GPU3D_OpenGL.h"
|
||||
#include "GPU3D_Compute.h"
|
||||
|
||||
#include "Savestate.h"
|
||||
|
||||
#include "ROMManager.h"
|
||||
#include "EmuThread.h"
|
||||
//#include "ArchiveUtil.h"
|
||||
//#include "CameraManager.h"
|
||||
|
||||
@ -94,9 +96,8 @@ EmuThread::EmuThread(QObject* parent) : QThread(parent)
|
||||
}
|
||||
|
||||
std::unique_ptr<NDS> EmuThread::CreateConsole(
|
||||
std::unique_ptr<melonDS::NDSCart::CartCommon>&& ndscart,
|
||||
std::unique_ptr<melonDS::GBACart::CartCommon>&& gbacart
|
||||
) noexcept
|
||||
std::unique_ptr<melonDS::NDSCart::CartCommon> &&ndscart,
|
||||
std::unique_ptr<melonDS::GBACart::CartCommon> &&gbacart) noexcept
|
||||
{
|
||||
auto arm7bios = ROMManager::LoadARM7BIOS();
|
||||
if (!arm7bios)
|
||||
@ -326,21 +327,12 @@ void EmuThread::run()
|
||||
videoRenderer = 0;
|
||||
}
|
||||
|
||||
if (videoRenderer == 0)
|
||||
{ // If we're using the software renderer...
|
||||
NDS->GPU.SetRenderer3D(std::make_unique<SoftRenderer>(Config::Threaded3D != 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto glrenderer = melonDS::GLRenderer::New();
|
||||
glrenderer->SetRenderSettings(Config::GL_BetterPolygons, Config::GL_ScaleFactor);
|
||||
NDS->GPU.SetRenderer3D(std::move(glrenderer));
|
||||
}
|
||||
updateRenderer();
|
||||
|
||||
Input::Init();
|
||||
|
||||
u32 nframes = 0;
|
||||
double perfCountsSec = 1.0 / SDL_GetPerformanceFrequency();
|
||||
perfCountsSec = 1.0 / SDL_GetPerformanceFrequency();
|
||||
double lastTime = SDL_GetPerformanceCounter() * perfCountsSec;
|
||||
double frameLimitError = 0.0;
|
||||
double lastMeasureTime = lastTime;
|
||||
@ -451,20 +443,9 @@ void EmuThread::run()
|
||||
videoRenderer = 0;
|
||||
}
|
||||
|
||||
videoRenderer = screenGL ? Config::_3DRenderer : 0;
|
||||
updateRenderer();
|
||||
|
||||
videoSettingsDirty = false;
|
||||
|
||||
if (videoRenderer == 0)
|
||||
{ // If we're using the software renderer...
|
||||
NDS->GPU.SetRenderer3D(std::make_unique<SoftRenderer>(Config::Threaded3D != 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto glrenderer = melonDS::GLRenderer::New();
|
||||
glrenderer->SetRenderSettings(Config::GL_BetterPolygons, Config::GL_ScaleFactor);
|
||||
NDS->GPU.SetRenderer3D(std::move(glrenderer));
|
||||
}
|
||||
}
|
||||
|
||||
// process input and hotkeys
|
||||
@ -512,7 +493,16 @@ void EmuThread::run()
|
||||
|
||||
|
||||
// emulate
|
||||
u32 nlines = NDS->RunFrame();
|
||||
u32 nlines;
|
||||
if (NDS->GPU.GetRenderer3D().NeedsShaderCompile())
|
||||
{
|
||||
compileShaders();
|
||||
nlines = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
nlines = NDS->RunFrame();
|
||||
}
|
||||
|
||||
if (ROMManager::NDSSave)
|
||||
ROMManager::NDSSave->CheckFlush();
|
||||
@ -750,3 +740,53 @@ bool EmuThread::emuIsActive()
|
||||
{
|
||||
return (RunningSomething == 1);
|
||||
}
|
||||
|
||||
void EmuThread::updateRenderer()
|
||||
{
|
||||
if (videoRenderer != lastVideoRenderer)
|
||||
{
|
||||
printf("creating renderer %d\n", videoRenderer);
|
||||
switch (videoRenderer)
|
||||
{
|
||||
case renderer3D_Software:
|
||||
NDS->GPU.SetRenderer3D(std::make_unique<SoftRenderer>());
|
||||
break;
|
||||
case renderer3D_OpenGL:
|
||||
NDS->GPU.SetRenderer3D(GLRenderer::New());
|
||||
break;
|
||||
case renderer3D_OpenGLCompute:
|
||||
NDS->GPU.SetRenderer3D(ComputeRenderer::New());
|
||||
break;
|
||||
default: __builtin_unreachable();
|
||||
}
|
||||
}
|
||||
lastVideoRenderer = videoRenderer;
|
||||
|
||||
switch (videoRenderer)
|
||||
{
|
||||
case renderer3D_Software:
|
||||
static_cast<SoftRenderer&>(NDS->GPU.GetRenderer3D()).SetThreaded(Config::Threaded3D, NDS->GPU);
|
||||
break;
|
||||
case renderer3D_OpenGL:
|
||||
static_cast<GLRenderer&>(NDS->GPU.GetRenderer3D()).SetRenderSettings(Config::GL_BetterPolygons, Config::GL_ScaleFactor);
|
||||
break;
|
||||
case renderer3D_OpenGLCompute:
|
||||
static_cast<ComputeRenderer&>(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
|
||||
{
|
||||
NDS->GPU.GetRenderer3D().ShaderCompileStep(currentShader, shadersCount);
|
||||
} while (NDS->GPU.GetRenderer3D().NeedsShaderCompile() &&
|
||||
(SDL_GetPerformanceCounter() - startTime) * perfCountsSec < 1.0 / 6.0);
|
||||
mainWindow->osdAddMessage(0, "Compiling shader %d/%d", currentShader+1, shadersCount);
|
||||
}
|
||||
|
@ -94,6 +94,9 @@ signals:
|
||||
void syncVolumeLevel();
|
||||
|
||||
private:
|
||||
void updateRenderer();
|
||||
void compileShaders();
|
||||
|
||||
std::unique_ptr<melonDS::NDS> CreateConsole(
|
||||
std::unique_ptr<melonDS::NDSCart::CartCommon>&& ndscart,
|
||||
std::unique_ptr<melonDS::GBACart::CartCommon>&& gbacart
|
||||
@ -127,8 +130,9 @@ private:
|
||||
|
||||
int autoScreenSizing;
|
||||
|
||||
int videoRenderer;
|
||||
bool videoSettingsDirty;
|
||||
int lastVideoRenderer = -1;
|
||||
|
||||
double perfCountsSec;
|
||||
};
|
||||
|
||||
#endif // EMUTHREAD_H
|
||||
|
@ -709,19 +709,17 @@ void ScreenPanelGL::initOpenGL()
|
||||
|
||||
glContext->MakeCurrent();
|
||||
|
||||
OpenGL::BuildShaderProgram(kScreenVS, kScreenFS, screenShaderProgram, "ScreenShader");
|
||||
GLuint pid = screenShaderProgram[2];
|
||||
glBindAttribLocation(pid, 0, "vPosition");
|
||||
glBindAttribLocation(pid, 1, "vTexcoord");
|
||||
glBindFragDataLocation(pid, 0, "oColor");
|
||||
OpenGL::CompileVertexFragmentProgram(screenShaderProgram,
|
||||
kScreenVS, kScreenFS,
|
||||
"ScreenShader",
|
||||
{{"vPosition", 0}, {"vTexcoord", 1}},
|
||||
{{"oColor", 0}});
|
||||
|
||||
OpenGL::LinkShaderProgram(screenShaderProgram);
|
||||
glUseProgram(screenShaderProgram);
|
||||
glUniform1i(glGetUniformLocation(screenShaderProgram, "ScreenTex"), 0);
|
||||
|
||||
glUseProgram(pid);
|
||||
glUniform1i(glGetUniformLocation(pid, "ScreenTex"), 0);
|
||||
|
||||
screenShaderScreenSizeULoc = glGetUniformLocation(pid, "uScreenSize");
|
||||
screenShaderTransformULoc = glGetUniformLocation(pid, "uTransform");
|
||||
screenShaderScreenSizeULoc = glGetUniformLocation(screenShaderProgram, "uScreenSize");
|
||||
screenShaderTransformULoc = glGetUniformLocation(screenShaderProgram, "uTransform");
|
||||
|
||||
// to prevent bleeding between both parts of the screen
|
||||
// with bilinear filtering enabled
|
||||
@ -769,21 +767,19 @@ void ScreenPanelGL::initOpenGL()
|
||||
memset(zeroData, 0, sizeof(zeroData));
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 2, GL_RGBA, GL_UNSIGNED_BYTE, zeroData);
|
||||
|
||||
OpenGL::CompileVertexFragmentProgram(osdShader,
|
||||
kScreenVS_OSD, kScreenFS_OSD,
|
||||
"OSDShader",
|
||||
{{"vPosition", 0}},
|
||||
{{"oColor", 0}});
|
||||
|
||||
OpenGL::BuildShaderProgram(kScreenVS_OSD, kScreenFS_OSD, osdShader, "OSDShader");
|
||||
glUseProgram(osdShader);
|
||||
glUniform1i(glGetUniformLocation(osdShader, "OSDTex"), 0);
|
||||
|
||||
pid = osdShader[2];
|
||||
glBindAttribLocation(pid, 0, "vPosition");
|
||||
glBindFragDataLocation(pid, 0, "oColor");
|
||||
|
||||
OpenGL::LinkShaderProgram(osdShader);
|
||||
glUseProgram(pid);
|
||||
glUniform1i(glGetUniformLocation(pid, "OSDTex"), 0);
|
||||
|
||||
osdScreenSizeULoc = glGetUniformLocation(pid, "uScreenSize");
|
||||
osdPosULoc = glGetUniformLocation(pid, "uOSDPos");
|
||||
osdSizeULoc = glGetUniformLocation(pid, "uOSDSize");
|
||||
osdScaleFactorULoc = glGetUniformLocation(pid, "uScaleFactor");
|
||||
osdScreenSizeULoc = glGetUniformLocation(osdShader, "uScreenSize");
|
||||
osdPosULoc = glGetUniformLocation(osdShader, "uOSDPos");
|
||||
osdSizeULoc = glGetUniformLocation(osdShader, "uOSDSize");
|
||||
osdScaleFactorULoc = glGetUniformLocation(osdShader, "uScaleFactor");
|
||||
|
||||
const float osdvertices[6*2] =
|
||||
{
|
||||
@ -818,8 +814,7 @@ void ScreenPanelGL::deinitOpenGL()
|
||||
glDeleteVertexArrays(1, &screenVertexArray);
|
||||
glDeleteBuffers(1, &screenVertexBuffer);
|
||||
|
||||
OpenGL::DeleteShaderProgram(screenShaderProgram);
|
||||
|
||||
glDeleteProgram(screenShaderProgram);
|
||||
|
||||
for (const auto& [key, tex] : osdTextures)
|
||||
{
|
||||
@ -830,8 +825,7 @@ void ScreenPanelGL::deinitOpenGL()
|
||||
glDeleteVertexArrays(1, &osdVertexArray);
|
||||
glDeleteBuffers(1, &osdVertexBuffer);
|
||||
|
||||
OpenGL::DeleteShaderProgram(osdShader);
|
||||
|
||||
glDeleteProgram(osdShader);
|
||||
|
||||
glContext->DoneCurrent();
|
||||
|
||||
@ -885,7 +879,7 @@ void ScreenPanelGL::drawScreenGL()
|
||||
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
glUseProgram(screenShaderProgram[2]);
|
||||
glUseProgram(screenShaderProgram);
|
||||
glUniform2f(screenShaderScreenSizeULoc, w / factor, h / factor);
|
||||
|
||||
int frontbuf = emuThread->FrontBuffer;
|
||||
@ -895,7 +889,7 @@ void ScreenPanelGL::drawScreenGL()
|
||||
if (emuThread->NDS->GPU.GetRenderer3D().Accelerated)
|
||||
{
|
||||
// hardware-accelerated render
|
||||
static_cast<GLRenderer&>(emuThread->NDS->GPU.GetRenderer3D()).GetCompositor().BindOutputTexture(frontbuf);
|
||||
emuThread->NDS->GPU.GetRenderer3D().BindOutputTexture(frontbuf);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -936,7 +930,7 @@ void ScreenPanelGL::drawScreenGL()
|
||||
|
||||
u32 y = kOSDMargin;
|
||||
|
||||
glUseProgram(osdShader[2]);
|
||||
glUseProgram(osdShader);
|
||||
|
||||
glUniform2f(osdScreenSizeULoc, w, h);
|
||||
glUniform1f(osdScaleFactorULoc, factor);
|
||||
|
@ -172,7 +172,7 @@ private:
|
||||
|
||||
GLuint screenVertexBuffer, screenVertexArray;
|
||||
GLuint screenTexture;
|
||||
GLuint screenShaderProgram[3];
|
||||
GLuint screenShaderProgram;
|
||||
GLuint screenShaderTransformULoc, screenShaderScreenSizeULoc;
|
||||
|
||||
QMutex screenSettingsLock;
|
||||
@ -181,7 +181,7 @@ private:
|
||||
|
||||
int lastScreenWidth = -1, lastScreenHeight = -1;
|
||||
|
||||
GLuint osdShader[3];
|
||||
GLuint osdShader;
|
||||
GLint osdScreenSizeULoc, osdPosULoc, osdSizeULoc;
|
||||
GLfloat osdScaleFactorULoc;
|
||||
GLuint osdVertexArray;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "types.h"
|
||||
#include "Platform.h"
|
||||
#include "Config.h"
|
||||
#include "GPU.h"
|
||||
|
||||
#include "VideoSettingsDialog.h"
|
||||
#include "ui_VideoSettingsDialog.h"
|
||||
@ -30,11 +31,20 @@
|
||||
|
||||
inline bool UsesGL()
|
||||
{
|
||||
return (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
|
||||
return (Config::ScreenUseGL != 0) || (Config::_3DRenderer != renderer3D_Software);
|
||||
}
|
||||
|
||||
VideoSettingsDialog* VideoSettingsDialog::currentDlg = nullptr;
|
||||
|
||||
void VideoSettingsDialog::setEnabled()
|
||||
{
|
||||
bool softwareRenderer = Config::_3DRenderer == renderer3D_Software;
|
||||
ui->cbGLDisplay->setEnabled(softwareRenderer);
|
||||
ui->cbSoftwareThreaded->setEnabled(softwareRenderer);
|
||||
ui->cbxGLResolution->setEnabled(!softwareRenderer);
|
||||
ui->cbBetterPolygons->setEnabled(Config::_3DRenderer == renderer3D_OpenGL);
|
||||
ui->cbxComputeHiResCoords->setEnabled(Config::_3DRenderer == renderer3D_OpenGLCompute);
|
||||
}
|
||||
|
||||
VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(new Ui::VideoSettingsDialog)
|
||||
{
|
||||
@ -48,10 +58,12 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
|
||||
oldSoftThreaded = Config::Threaded3D;
|
||||
oldGLScale = Config::GL_ScaleFactor;
|
||||
oldGLBetterPolygons = Config::GL_BetterPolygons;
|
||||
oldHiresCoordinates = Config::GL_HiresCoordinates;
|
||||
|
||||
grp3DRenderer = new QButtonGroup(this);
|
||||
grp3DRenderer->addButton(ui->rb3DSoftware, 0);
|
||||
grp3DRenderer->addButton(ui->rb3DOpenGL, 1);
|
||||
grp3DRenderer->addButton(ui->rb3DSoftware, renderer3D_Software);
|
||||
grp3DRenderer->addButton(ui->rb3DOpenGL, renderer3D_OpenGL);
|
||||
grp3DRenderer->addButton(ui->rb3DCompute, renderer3D_OpenGLCompute);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
connect(grp3DRenderer, SIGNAL(buttonClicked(int)), this, SLOT(onChange3DRenderer(int)));
|
||||
#else
|
||||
@ -75,25 +87,13 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
|
||||
ui->cbxGLResolution->setCurrentIndex(Config::GL_ScaleFactor-1);
|
||||
|
||||
ui->cbBetterPolygons->setChecked(Config::GL_BetterPolygons != 0);
|
||||
ui->cbxComputeHiResCoords->setChecked(Config::GL_HiresCoordinates != 0);
|
||||
|
||||
if (!Config::ScreenVSync)
|
||||
ui->sbVSyncInterval->setEnabled(false);
|
||||
setVsyncControlEnable(UsesGL());
|
||||
|
||||
if (Config::_3DRenderer == 0)
|
||||
{
|
||||
ui->cbGLDisplay->setEnabled(true);
|
||||
ui->cbSoftwareThreaded->setEnabled(true);
|
||||
ui->cbxGLResolution->setEnabled(false);
|
||||
ui->cbBetterPolygons->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->cbGLDisplay->setEnabled(false);
|
||||
ui->cbSoftwareThreaded->setEnabled(false);
|
||||
ui->cbxGLResolution->setEnabled(true);
|
||||
ui->cbBetterPolygons->setEnabled(true);
|
||||
}
|
||||
setEnabled();
|
||||
}
|
||||
|
||||
VideoSettingsDialog::~VideoSettingsDialog()
|
||||
@ -119,6 +119,7 @@ void VideoSettingsDialog::on_VideoSettingsDialog_rejected()
|
||||
Config::Threaded3D = oldSoftThreaded;
|
||||
Config::GL_ScaleFactor = oldGLScale;
|
||||
Config::GL_BetterPolygons = oldGLBetterPolygons;
|
||||
Config::GL_HiresCoordinates = oldHiresCoordinates;
|
||||
|
||||
emit updateVideoSettings(old_gl != UsesGL());
|
||||
|
||||
@ -133,31 +134,18 @@ void VideoSettingsDialog::setVsyncControlEnable(bool hasOGL)
|
||||
|
||||
void VideoSettingsDialog::onChange3DRenderer(int renderer)
|
||||
{
|
||||
bool old_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
|
||||
bool old_gl = UsesGL();
|
||||
|
||||
Config::_3DRenderer = renderer;
|
||||
|
||||
if (renderer == 0)
|
||||
{
|
||||
ui->cbGLDisplay->setEnabled(true);
|
||||
ui->cbSoftwareThreaded->setEnabled(true);
|
||||
ui->cbxGLResolution->setEnabled(false);
|
||||
ui->cbBetterPolygons->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->cbGLDisplay->setEnabled(false);
|
||||
ui->cbSoftwareThreaded->setEnabled(false);
|
||||
ui->cbxGLResolution->setEnabled(true);
|
||||
ui->cbBetterPolygons->setEnabled(true);
|
||||
}
|
||||
setEnabled();
|
||||
|
||||
emit updateVideoSettings(old_gl != UsesGL());
|
||||
}
|
||||
|
||||
void VideoSettingsDialog::on_cbGLDisplay_stateChanged(int state)
|
||||
{
|
||||
bool old_gl = (Config::ScreenUseGL != 0) || (Config::_3DRenderer != 0);
|
||||
bool old_gl = UsesGL();
|
||||
|
||||
Config::ScreenUseGL = (state != 0);
|
||||
|
||||
@ -205,3 +193,10 @@ void VideoSettingsDialog::on_cbBetterPolygons_stateChanged(int state)
|
||||
|
||||
emit updateVideoSettings(false);
|
||||
}
|
||||
|
||||
void VideoSettingsDialog::on_cbxComputeHiResCoords_stateChanged(int state)
|
||||
{
|
||||
Config::GL_HiresCoordinates = (state != 0);
|
||||
|
||||
emit updateVideoSettings(false);
|
||||
}
|
||||
|
@ -65,10 +65,12 @@ private slots:
|
||||
|
||||
void on_cbxGLResolution_currentIndexChanged(int idx);
|
||||
void on_cbBetterPolygons_stateChanged(int state);
|
||||
void on_cbxComputeHiResCoords_stateChanged(int state);
|
||||
|
||||
void on_cbSoftwareThreaded_stateChanged(int state);
|
||||
private:
|
||||
void setVsyncControlEnable(bool hasOGL);
|
||||
void setEnabled();
|
||||
|
||||
Ui::VideoSettingsDialog* ui;
|
||||
|
||||
@ -81,6 +83,7 @@ private:
|
||||
int oldSoftThreaded;
|
||||
int oldGLScale;
|
||||
int oldGLBetterPolygons;
|
||||
int oldHiresCoordinates;
|
||||
};
|
||||
|
||||
#endif // VIDEOSETTINGSDIALOG_H
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>408</width>
|
||||
<width>427</width>
|
||||
<height>262</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -24,7 +24,7 @@
|
||||
<enum>QLayout::SetFixedSize</enum>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>-1</number>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
@ -39,13 +39,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QComboBox" name="cbxGLResolution">
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>The resolution at which the 3D graphics will be rendered. Higher resolutions improve graphics quality when the main window is enlarged, but may also cause glitches.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="cbBetterPolygons">
|
||||
<property name="whatsThis">
|
||||
@ -56,6 +49,20 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QComboBox" name="cbxGLResolution">
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>The resolution at which the 3D graphics will be rendered. Higher resolutions improve graphics quality when the main window is enlarged, but may also cause glitches.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="cbxComputeHiResCoords">
|
||||
<property name="text">
|
||||
<string>Use high resolution coordinates</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -94,23 +101,7 @@
|
||||
<string>Display settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>The interval at which to synchronize to the monitor's refresh rate. Set to 1 for a 60Hz monitor, 2 for 120Hz, ...</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VSync interval:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="7" column="1">
|
||||
<widget class="QSpinBox" name="sbVSyncInterval">
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>The interval at which to synchronize to the monitor's refresh rate. Set to 1 for a 60Hz monitor, 2 for 120Hz, ...</p></body></html></string>
|
||||
@ -123,7 +114,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="cbGLDisplay">
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>Use OpenGL to draw the DS screens to the main window. May result in better frame pacing. Mandatory when using the OpenGL 3D renderer.</p></body></html></string>
|
||||
@ -133,17 +124,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="cbVSync">
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>When using OpenGL, synchronize the video output to your monitor's refresh rate.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VSync</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<item row="4" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -159,13 +140,39 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="cbVSync">
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>When using OpenGL, synchronize the video output to your monitor's refresh rate.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VSync</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>The interval at which to synchronize to the monitor's refresh rate. Set to 1 for a 60Hz monitor, 2 for 120Hz, ...</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>VSync interval:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="rb3DOpenGL">
|
||||
<property name="whatsThis">
|
||||
<string><html><head/><body><p>The OpenGL renderer may be faster than software and supports graphical enhancements, but is more prone to glitches.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OpenGL</string>
|
||||
<string>OpenGL (Classic)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -186,6 +193,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QRadioButton" name="rb3DCompute">
|
||||
<property name="text">
|
||||
<string>OpenGL (Compute shader)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -2048,6 +2048,7 @@ void MainWindow::onUpdateVideoSettings(bool glchange)
|
||||
connect(emuThread, SIGNAL(windowUpdate()), panel, SLOT(repaint()));
|
||||
}
|
||||
|
||||
printf("update video settings\n");
|
||||
videoSettingsDirty = true;
|
||||
|
||||
if (glchange)
|
||||
|
@ -175,10 +175,6 @@ bool camStarted[2];
|
||||
//extern int AspectRatiosNum;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static bool FileExtensionInList(const QString& filename, const QStringList& extensions, Qt::CaseSensitivity cs = Qt::CaseInsensitive)
|
||||
{
|
||||
return std::any_of(extensions.cbegin(), extensions.cend(), [&](const auto& ext) {
|
||||
@ -339,10 +335,10 @@ int main(int argc, char** argv)
|
||||
|
||||
if (!Config::Load()) QMessageBox::critical(NULL, "melonDS", "Unable to write to config.\nPlease check the write permissions of the folder you placed melonDS in.");
|
||||
|
||||
#define SANITIZE(var, min, max) { var = std::clamp(var, min, max); }
|
||||
#define SANITIZE(var, min, max) { var = std::clamp<int>(var, min, max); }
|
||||
SANITIZE(Config::ConsoleType, 0, 1);
|
||||
#ifdef OGLRENDERER_ENABLED
|
||||
SANITIZE(Config::_3DRenderer, 0, 1); // 0 is the software renderer, 1 is the OpenGL renderer
|
||||
SANITIZE(Config::_3DRenderer, 0, renderer3D_Max);
|
||||
#else
|
||||
SANITIZE(Config::_3DRenderer, 0, 0);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user