diff --git a/src/GPU3D.h b/src/GPU3D.h index cc651cc6..c3e6a7f1 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -354,6 +354,9 @@ public: virtual void PrepareCaptureFrame() {} virtual void BindOutputTexture(int buffer) {} + virtual bool NeedsShaderCompile() { return false; } + virtual void ShaderCompileStep(int& current, int& count) {} + protected: Renderer3D(bool Accelerated); }; diff --git a/src/GPU3D_Compute.cpp b/src/GPU3D_Compute.cpp index 6424498b..bf1f4712 100644 --- a/src/GPU3D_Compute.cpp +++ b/src/GPU3D_Compute.cpp @@ -57,7 +57,119 @@ bool ComputeRenderer::CompileShader(GLuint& shader, const std::string& source, c return OpenGL::CompileComputeProgram(shader, shaderSource.c_str(), shaderName.c_str()); } -void blah(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam) +void ComputeRenderer::ShaderCompileStep(int& current, int& count) +{ + current = ShaderStepIdx; + ShaderStepIdx++; + count = 33; + switch (current) + { + case 0: + CompileShader(ShaderInterpXSpans[0], ComputeRendererShaders::InterpSpans, {"InterpSpans", "ZBuffer"}); + return; + case 1: + CompileShader(ShaderInterpXSpans[1], ComputeRendererShaders::InterpSpans, {"InterpSpans", "WBuffer"}); + return; + case 2: + CompileShader(ShaderBinCombined, ComputeRendererShaders::BinCombined, {"BinCombined"}); + return; + case 3: + CompileShader(ShaderDepthBlend[0], ComputeRendererShaders::DepthBlend, {"DepthBlend", "ZBuffer"}); + return; + case 4: + CompileShader(ShaderDepthBlend[1], ComputeRendererShaders::DepthBlend, {"DepthBlend", "WBuffer"}); + return; + case 5: + CompileShader(ShaderRasteriseNoTexture[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "NoTexture"}); + return; + case 6: + CompileShader(ShaderRasteriseNoTexture[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "NoTexture"}); + return; + case 7: + CompileShader(ShaderRasteriseNoTextureToon[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "NoTexture", "Toon"}); + return; + case 8: + CompileShader(ShaderRasteriseNoTextureToon[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "NoTexture", "Toon"}); + return; + case 9: + CompileShader(ShaderRasteriseNoTextureHighlight[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "NoTexture", "Highlight"}); + return; + case 10: + CompileShader(ShaderRasteriseNoTextureHighlight[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "NoTexture", "Highlight"}); + return; + case 11: + CompileShader(ShaderRasteriseUseTextureDecal[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Decal"}); + return; + case 12: + CompileShader(ShaderRasteriseUseTextureDecal[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Decal"}); + return; + case 13: + CompileShader(ShaderRasteriseUseTextureModulate[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Modulate"}); + return; + case 14: + CompileShader(ShaderRasteriseUseTextureModulate[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Modulate"}); + return; + case 15: + CompileShader(ShaderRasteriseUseTextureToon[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Toon"}); + return; + case 16: + CompileShader(ShaderRasteriseUseTextureToon[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Toon"}); + return; + case 17: + CompileShader(ShaderRasteriseUseTextureHighlight[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Highlight"}); + return; + case 18: + CompileShader(ShaderRasteriseUseTextureHighlight[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Highlight"}); + return; + case 19: + CompileShader(ShaderRasteriseShadowMask[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "ShadowMask"}); + return; + case 20: + CompileShader(ShaderRasteriseShadowMask[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "ShadowMask"}); + return; + case 21: + CompileShader(ShaderClearCoarseBinMask, ComputeRendererShaders::ClearCoarseBinMask, {"ClearCoarseBinMask"}); + return; + case 22: + CompileShader(ShaderClearIndirectWorkCount, ComputeRendererShaders::ClearIndirectWorkCount, {"ClearIndirectWorkCount"}); + return; + case 23: + CompileShader(ShaderCalculateWorkListOffset, ComputeRendererShaders::CalcOffsets, {"CalculateWorkOffsets"}); + return; + case 24: + CompileShader(ShaderSortWork, ComputeRendererShaders::SortWork, {"SortWork"}); + return; + case 25: + CompileShader(ShaderFinalPass[0], ComputeRendererShaders::FinalPass, {"FinalPass"}); + return; + case 26: + CompileShader(ShaderFinalPass[1], ComputeRendererShaders::FinalPass, {"FinalPass", "EdgeMarking"}); + return; + case 27: + CompileShader(ShaderFinalPass[2], ComputeRendererShaders::FinalPass, {"FinalPass", "Fog"}); + return; + case 28: + CompileShader(ShaderFinalPass[3], ComputeRendererShaders::FinalPass, {"FinalPass", "EdgeMarking", "Fog"}); + return; + case 29: + CompileShader(ShaderFinalPass[4], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing"}); + return; + case 30: + CompileShader(ShaderFinalPass[5], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing", "EdgeMarking"}); + return; + case 31: + CompileShader(ShaderFinalPass[6], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing", "Fog"}); + return; + case 32: + CompileShader(ShaderFinalPass[7], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing", "EdgeMarking", "Fog"}); + return; + default: + __builtin_unreachable(); + return; + } +} + +void blah(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { printf("%s\n", message); } @@ -192,6 +304,8 @@ void ComputeRenderer::SetRenderSettings(int scale, bool highResolutionCoordinate DeleteShaders(); } + ShaderStepIdx = 0; + ScaleFactor = scale; ScreenWidth = 256 * ScaleFactor; ScreenHeight = 192 * ScaleFactor; @@ -241,40 +355,6 @@ void ComputeRenderer::SetRenderSettings(int scale, bool highResolutionCoordinate glBindTexture(GL_TEXTURE_BUFFER, YSpanIndicesTexture); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA16UI, YSpanIndicesTextureMemory); - - CompileShader(ShaderInterpXSpans[0], ComputeRendererShaders::InterpSpans, {"InterpSpans", "ZBuffer"}); - CompileShader(ShaderInterpXSpans[1], ComputeRendererShaders::InterpSpans, {"InterpSpans", "WBuffer"}); - CompileShader(ShaderBinCombined, ComputeRendererShaders::BinCombined, {"BinCombined"}); - CompileShader(ShaderDepthBlend[0], ComputeRendererShaders::DepthBlend, {"DepthBlend", "ZBuffer"}); - CompileShader(ShaderDepthBlend[1], ComputeRendererShaders::DepthBlend, {"DepthBlend", "WBuffer"}); - CompileShader(ShaderRasteriseNoTexture[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "NoTexture"}); - CompileShader(ShaderRasteriseNoTexture[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "NoTexture"}); - CompileShader(ShaderRasteriseNoTextureToon[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "NoTexture", "Toon"}); - CompileShader(ShaderRasteriseNoTextureToon[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "NoTexture", "Toon"}); - CompileShader(ShaderRasteriseNoTextureHighlight[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "NoTexture", "Highlight"}); - CompileShader(ShaderRasteriseNoTextureHighlight[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "NoTexture", "Highlight"}); - CompileShader(ShaderRasteriseUseTextureDecal[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Decal"}); - CompileShader(ShaderRasteriseUseTextureDecal[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Decal"}); - CompileShader(ShaderRasteriseUseTextureModulate[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Modulate"}); - CompileShader(ShaderRasteriseUseTextureModulate[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Modulate"}); - CompileShader(ShaderRasteriseUseTextureToon[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Toon"}); - CompileShader(ShaderRasteriseUseTextureToon[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Toon"}); - CompileShader(ShaderRasteriseUseTextureHighlight[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "UseTexture", "Highlight"}); - CompileShader(ShaderRasteriseUseTextureHighlight[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "UseTexture", "Highlight"}); - CompileShader(ShaderRasteriseShadowMask[0], ComputeRendererShaders::Rasterise, {"Rasterise", "ZBuffer", "ShadowMask"}); - CompileShader(ShaderRasteriseShadowMask[1], ComputeRendererShaders::Rasterise, {"Rasterise", "WBuffer", "ShadowMask"}); - CompileShader(ShaderClearCoarseBinMask, ComputeRendererShaders::ClearCoarseBinMask, {"ClearCoarseBinMask"}); - CompileShader(ShaderClearIndirectWorkCount, ComputeRendererShaders::ClearIndirectWorkCount, {"ClearIndirectWorkCount"}); - CompileShader(ShaderCalculateWorkListOffset, ComputeRendererShaders::CalcOffsets, {"CalculateWorkOffsets"}); - CompileShader(ShaderSortWork, ComputeRendererShaders::SortWork, {"SortWork"}); - CompileShader(ShaderFinalPass[0], ComputeRendererShaders::FinalPass, {"FinalPass"}); - CompileShader(ShaderFinalPass[1], ComputeRendererShaders::FinalPass, {"FinalPass", "EdgeMarking"}); - CompileShader(ShaderFinalPass[2], ComputeRendererShaders::FinalPass, {"FinalPass", "Fog"}); - CompileShader(ShaderFinalPass[3], ComputeRendererShaders::FinalPass, {"FinalPass", "EdgeMarking", "Fog"}); - CompileShader(ShaderFinalPass[4], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing"}); - CompileShader(ShaderFinalPass[5], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing", "EdgeMarking"}); - CompileShader(ShaderFinalPass[6], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing", "Fog"}); - CompileShader(ShaderFinalPass[7], ComputeRendererShaders::FinalPass, {"FinalPass", "AntiAliasing", "EdgeMarking", "Fog"}); } void ComputeRenderer::VCount144(GPU& gpu) diff --git a/src/GPU3D_Compute.h b/src/GPU3D_Compute.h index d37b6ef4..7544c09e 100644 --- a/src/GPU3D_Compute.h +++ b/src/GPU3D_Compute.h @@ -58,6 +58,9 @@ public: void Blit(const GPU& gpu) override; void Stop(const GPU& gpu) override; + + bool NeedsShaderCompile() { return ShaderStepIdx != 33; } + void ShaderCompileStep(int& current, int& count) override; private: ComputeRenderer(GLCompositor&& compositor); @@ -223,6 +226,8 @@ private: GLCompositor CurGLCompositor; + int ShaderStepIdx = 0; + void DeleteShaders(); void SetupAttrs(SpanSetupY* span, Polygon* poly, int from, int to); diff --git a/src/frontend/qt_sdl/EmuThread.cpp b/src/frontend/qt_sdl/EmuThread.cpp index c62902b7..abb0e8ac 100644 --- a/src/frontend/qt_sdl/EmuThread.cpp +++ b/src/frontend/qt_sdl/EmuThread.cpp @@ -332,7 +332,7 @@ void EmuThread::run() 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; @@ -443,7 +443,6 @@ void EmuThread::run() videoRenderer = 0; } - printf("miau\n"); updateRenderer(); videoSettingsDirty = false; @@ -494,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(); @@ -768,3 +776,17 @@ void EmuThread::updateRenderer() 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); +} diff --git a/src/frontend/qt_sdl/EmuThread.h b/src/frontend/qt_sdl/EmuThread.h index 5246c1de..4b19acf9 100644 --- a/src/frontend/qt_sdl/EmuThread.h +++ b/src/frontend/qt_sdl/EmuThread.h @@ -95,6 +95,7 @@ signals: private: void updateRenderer(); + void compileShaders(); std::unique_ptr CreateConsole( std::unique_ptr&& ndscart, @@ -130,6 +131,8 @@ private: int autoScreenSizing; int lastVideoRenderer = -1; + + double perfCountsSec; }; #endif // EMUTHREAD_H