From 731026c19914629c53604e738711333de5cc1c6b Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Thu, 23 Feb 2017 12:41:22 +0100 Subject: [PATCH] D3D11: Can now switch post shader at runtime, and won't crash if they fail to translate correctly. --- GPU/D3D11/D3D11Util.cpp | 1 - GPU/D3D11/FramebufferManagerD3D11.cpp | 25 +++++- GPU/GLES/FramebufferManagerGLES.cpp | 113 +++++++++++++------------- GPU/GLES/FramebufferManagerGLES.h | 1 + Windows/MainWindowMenu.cpp | 1 - 5 files changed, 80 insertions(+), 61 deletions(-) diff --git a/GPU/D3D11/D3D11Util.cpp b/GPU/D3D11/D3D11Util.cpp index 1799c19fc3..35923a68c9 100644 --- a/GPU/D3D11/D3D11Util.cpp +++ b/GPU/D3D11/D3D11Util.cpp @@ -26,7 +26,6 @@ static std::vector CompileShaderToBytecode(const char *code, size_t cod compiledCode->Release(); return compiled; } - Crash(); return std::vector(); } diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index a55d0a658f..53ef030983 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -23,6 +23,7 @@ #include "base/basictypes.h" #include "file/vfs.h" #include "file/zip_read.h" +#include "i18n/i18n.h" #include "Common/ColorConv.h" #include "Common/MathUtil.h" @@ -44,6 +45,8 @@ #include "GPU/D3D11/TextureCacheD3D11.h" #include "GPU/D3D11/DrawEngineD3D11.h" +#include "UI/OnScreenDisplay.h" + #include "ext/native/thin3d/thin3d.h" #include @@ -211,8 +214,6 @@ void FramebufferManagerD3D11::DisableState() { } void FramebufferManagerD3D11::CompilePostShader() { - usePostShader_ = false; - SetNumExtraFBOs(0); std::string vsSource; @@ -233,9 +234,12 @@ void FramebufferManagerD3D11::CompilePostShader() { const ShaderInfo *shaderInfo = 0; if (g_Config.sPostShaderName == "Off") { + usePostShader_ = false; return; } + usePostShader_ = false; + shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName); if (shaderInfo) { postShaderAtOutputResolution_ = shaderInfo->outputResolution; @@ -261,6 +265,7 @@ void FramebufferManagerD3D11::CompilePostShader() { } else { return; } + I18NCategory *gr = GetI18NCategory("Graphics"); UINT flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; std::vector byteCode; @@ -852,11 +857,20 @@ void FramebufferManagerD3D11::PackDepthbuffer(VirtualFramebuffer *vfb, int x, in void FramebufferManagerD3D11::EndFrame() { if (resized_) { DestroyAllFBOs(false); + + // Check if postprocessing shader is doing upscaling as it requires native resolution + const ShaderInfo *shaderInfo = 0; + if (g_Config.sPostShaderName != "Off") { + shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName); + } + + postShaderIsUpscalingFilter_ = shaderInfo ? shaderInfo->isUpscalingFilter : false; + // Actually, auto mode should be more granular... // Round up to a zoom factor for the render size. int zoom = g_Config.iInternalResolution; - if (zoom == 0) { // auto mode - // Use the longest dimension + if (zoom == 0) { + // auto mode, use the longest dimension if (!g_Config.IsPortrait()) { zoom = (PSP_CoreParameter().pixelWidth + 479) / 480; } else { @@ -880,6 +894,9 @@ void FramebufferManagerD3D11::EndFrame() { ShowScreenResolution(); } resized_ = false; + + // Might have a new post shader - let's compile it. + CompilePostShader(); } } diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 11bfbf712d..75d3c4c88d 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -123,64 +123,67 @@ void FramebufferManagerGLES::CompileDraw2DProgram() { glsl_bind(draw2dprogram_); glUniform1i(draw2dprogram_->sampler0, 0); } - - SetNumExtraFBOs(0); - const ShaderInfo *shaderInfo = 0; - if (g_Config.sPostShaderName != "Off") { - shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName); - } - - if (shaderInfo) { - postShaderAtOutputResolution_ = shaderInfo->outputResolution; - postShaderProgram_ = glsl_create(shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), &errorString); - if (!postShaderProgram_) { - // DO NOT turn this into a report, as it will pollute our logs with all kinds of - // user shader experiments. - ERROR_LOG(G3D, "Failed to build post-processing program from %s and %s!\n%s", shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), errorString.c_str()); - // let's show the first line of the error string as an OSM. - std::set blacklistedLines; - // These aren't useful to show, skip to the first interesting line. - blacklistedLines.insert("Fragment shader failed to compile with the following errors:"); - blacklistedLines.insert("Vertex shader failed to compile with the following errors:"); - blacklistedLines.insert("Compile failed."); - blacklistedLines.insert(""); - - std::string firstLine; - size_t start = 0; - for (size_t i = 0; i < errorString.size(); i++) { - if (errorString[i] == '\n') { - firstLine = errorString.substr(start, i - start); - if (blacklistedLines.find(firstLine) == blacklistedLines.end()) { - break; - } - start = i + 1; - firstLine.clear(); - } - } - if (!firstLine.empty()) { - host->NotifyUserMessage("Post-shader error: " + firstLine + "...", 10.0f, 0xFF3090FF); - } else { - host->NotifyUserMessage("Post-shader error, see log for details", 10.0f, 0xFF3090FF); - } - usePostShader_ = false; - } else { - glsl_bind(postShaderProgram_); - glUniform1i(postShaderProgram_->sampler0, 0); - SetNumExtraFBOs(1); - deltaLoc_ = glsl_uniform_loc(postShaderProgram_, "u_texelDelta"); - pixelDeltaLoc_ = glsl_uniform_loc(postShaderProgram_, "u_pixelDelta"); - timeLoc_ = glsl_uniform_loc(postShaderProgram_, "u_time"); - usePostShader_ = true; - } - } else { - postShaderProgram_ = nullptr; - usePostShader_ = false; - } - - glsl_unbind(); + CompilePostShader(); } } +void FramebufferManagerGLES::CompilePostShader() { + SetNumExtraFBOs(0); + const ShaderInfo *shaderInfo = 0; + if (g_Config.sPostShaderName != "Off") { + shaderInfo = GetPostShaderInfo(g_Config.sPostShaderName); + } + + if (shaderInfo) { + std::string errorString; + postShaderAtOutputResolution_ = shaderInfo->outputResolution; + postShaderProgram_ = glsl_create(shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), &errorString); + if (!postShaderProgram_) { + // DO NOT turn this into a report, as it will pollute our logs with all kinds of + // user shader experiments. + ERROR_LOG(G3D, "Failed to build post-processing program from %s and %s!\n%s", shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), errorString.c_str()); + // let's show the first line of the error string as an OSM. + std::set blacklistedLines; + // These aren't useful to show, skip to the first interesting line. + blacklistedLines.insert("Fragment shader failed to compile with the following errors:"); + blacklistedLines.insert("Vertex shader failed to compile with the following errors:"); + blacklistedLines.insert("Compile failed."); + blacklistedLines.insert(""); + + std::string firstLine; + size_t start = 0; + for (size_t i = 0; i < errorString.size(); i++) { + if (errorString[i] == '\n') { + firstLine = errorString.substr(start, i - start); + if (blacklistedLines.find(firstLine) == blacklistedLines.end()) { + break; + } + start = i + 1; + firstLine.clear(); + } + } + if (!firstLine.empty()) { + host->NotifyUserMessage("Post-shader error: " + firstLine + "...", 10.0f, 0xFF3090FF); + } else { + host->NotifyUserMessage("Post-shader error, see log for details", 10.0f, 0xFF3090FF); + } + usePostShader_ = false; + } else { + glsl_bind(postShaderProgram_); + glUniform1i(postShaderProgram_->sampler0, 0); + SetNumExtraFBOs(1); + deltaLoc_ = glsl_uniform_loc(postShaderProgram_, "u_texelDelta"); + pixelDeltaLoc_ = glsl_uniform_loc(postShaderProgram_, "u_pixelDelta"); + timeLoc_ = glsl_uniform_loc(postShaderProgram_, "u_time"); + usePostShader_ = true; + } + } else { + postShaderProgram_ = nullptr; + usePostShader_ = false; + } + glsl_unbind(); +} + void FramebufferManagerGLES::Bind2DShader() { glsl_bind(draw2dprogram_); } diff --git a/GPU/GLES/FramebufferManagerGLES.h b/GPU/GLES/FramebufferManagerGLES.h index 260141d234..958189a978 100644 --- a/GPU/GLES/FramebufferManagerGLES.h +++ b/GPU/GLES/FramebufferManagerGLES.h @@ -112,6 +112,7 @@ private: void BindPostShader(const PostShaderUniforms &uniforms) override; void CompileDraw2DProgram(); void DestroyDraw2DProgram(); + void CompilePostShader(); void PackFramebufferAsync_(VirtualFramebuffer *vfb); // Not used under ES currently void PackFramebufferSync_(VirtualFramebuffer *vfb, int x, int y, int w, int h); diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index b62126b728..dcd2afd304 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -977,7 +977,6 @@ namespace MainWindow { g_Config.sPostShaderName = availableShaders[index]; NativeMessageReceived("gpu resized", ""); - break; }