From 3f01cbb98c4c4425be6ec3d4b368471bf048ad64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 4 Jan 2021 23:51:34 +0100 Subject: [PATCH] Initialize/Deinitialize the shader translation system once globally. Fixes #13839. --- Common/GPU/Shader.cpp | 10 ++++++++++ Common/GPU/Shader.h | 3 +++ Common/GPU/ShaderTranslation.cpp | 13 +++++++------ GPU/Common/PresentationCommon.cpp | 8 +++++--- GPU/D3D11/FramebufferManagerD3D11.cpp | 5 ----- GPU/Directx9/FramebufferManagerDX9.cpp | 5 ----- GPU/Software/SoftGpu.cpp | 11 ----------- UI/NativeApp.cpp | 5 +++++ 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Common/GPU/Shader.cpp b/Common/GPU/Shader.cpp index 394a6eed32..14b703f544 100644 --- a/Common/GPU/Shader.cpp +++ b/Common/GPU/Shader.cpp @@ -17,6 +17,16 @@ const char *ShaderLanguageAsString(ShaderLanguage lang) { } } +const char *ShaderStageAsString(ShaderStage stage) { + switch (stage) { + case ShaderStage::Fragment: return "Fragment"; + case ShaderStage::Vertex: return "Vertex"; + case ShaderStage::Geometry: return "Geometry"; + case ShaderStage::Compute: return "Compute"; + default: return "(unknown)"; + } +} + ShaderLanguageDesc::ShaderLanguageDesc(ShaderLanguage lang) { Init(lang); } diff --git a/Common/GPU/Shader.h b/Common/GPU/Shader.h index 36bfbe36ce..4fc5ba4f0a 100644 --- a/Common/GPU/Shader.h +++ b/Common/GPU/Shader.h @@ -28,6 +28,9 @@ enum class ShaderStage { Compute, }; +const char *ShaderStageAsString(ShaderStage lang); + + struct ShaderLanguageDesc { ShaderLanguageDesc() {} explicit ShaderLanguageDesc(ShaderLanguage lang); diff --git a/Common/GPU/ShaderTranslation.cpp b/Common/GPU/ShaderTranslation.cpp index 842863a5e5..5d92d2fd7d 100644 --- a/Common/GPU/ShaderTranslation.cpp +++ b/Common/GPU/ShaderTranslation.cpp @@ -53,7 +53,7 @@ extern void init_resources(TBuiltInResource &Resources); -static EShLanguage GetLanguage(const ShaderStage stage) { +static EShLanguage GetShLanguageFromStage(const ShaderStage stage) { switch (stage) { case ShaderStage::Vertex: return EShLangVertex; case ShaderStage::Geometry: return EShLangGeometry; @@ -234,15 +234,16 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, const ShaderLan *errorMessage = ""; glslang::TProgram program; - const char *shaderStrings[1]; + const char *shaderStrings[1]{}; - TBuiltInResource Resources; + TBuiltInResource Resources{}; init_resources(Resources); // Don't enable SPIR-V and Vulkan rules when parsing GLSL. Our postshaders are written in oldschool GLES 2.0. EShMessages messages = EShMessages::EShMsgDefault; - EShLanguage shaderStage = GetLanguage(stage); + EShLanguage shaderStage = GetShLanguageFromStage(stage); + glslang::TShader shader(shaderStage); shaderStrings[0] = src.c_str(); @@ -250,7 +251,7 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, const ShaderLan // TODO: Should set settings here based on srcLang. if (!shader.parse(&Resources, 100, EProfile::ECompatibilityProfile, false, false, messages)) { - *errorMessage = std::string("GLSL parser failure: ") + shader.getInfoLog() + shader.getInfoDebugLog(); + *errorMessage = StringFromFormat("%s parser failure: %s\n%s", ShaderStageAsString(stage), shader.getInfoLog(), shader.getInfoDebugLog()); return false; // something didn't work } @@ -258,7 +259,7 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, const ShaderLan program.addShader(&shader); if (!program.link(messages)) { - *errorMessage = std::string("Linker failure: ") + shader.getInfoLog() + shader.getInfoDebugLog(); + *errorMessage = StringFromFormat("%s linker failure: %s\n%s", ShaderStageAsString(stage), shader.getInfoLog(), shader.getInfoDebugLog()); return false; } diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 571c396846..eb1e8d8cd9 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -239,7 +239,8 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha return false; } - std::string vsError, fsError; + std::string vsError; + std::string fsError; // All post shaders are written in GLSL 1.0 so that's what we pass in here as a "from" language. Draw::ShaderModule *vs = CompileShaderModule(ShaderStage::Vertex, GLSL_1xx, vsSourceGLSL, &vsError); @@ -248,7 +249,7 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha // Don't worry, CompileShaderModule makes sure they get freed if one succeeded. if (!fs || !vs) { std::string errorString = vsError + "\n" + fsError; - // DO NOT turn this into a report, as it will pollute our logs with all kinds of + // DO NOT turn this into an ERROR_LOG_REPORT, as it will pollute our logs with all kinds of // user shader experiments. ERROR_LOG(FRAMEBUF, "Failed to build post-processing program from %s and %s!\n%s", shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), errorString.c_str()); ShowPostShaderError(errorString); @@ -263,6 +264,7 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha { "u_setting", 4, 4, UniformType::FLOAT4, offsetof(PostShaderUniforms, setting) }, { "u_video", 5, 5, UniformType::FLOAT1, offsetof(PostShaderUniforms, video) }, } }; + Draw::Pipeline *pipeline = CreatePipeline({ vs, fs }, true, &postShaderDesc); if (!pipeline) return false; @@ -353,7 +355,7 @@ void PresentationCommon::ShowPostShaderError(const std::string &errorString) { } } if (!firstLine.empty()) { - host->NotifyUserMessage("Post-shader error: " + firstLine + "...", 10.0f, 0xFF3090FF); + host->NotifyUserMessage("Post-shader error: " + firstLine + "...:\n" + errorString, 10.0f, 0xFF3090FF); } else { host->NotifyUserMessage("Post-shader error, see log for details", 10.0f, 0xFF3090FF); } diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index 51dbaf4018..fbafe04285 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -36,7 +36,6 @@ #include "GPU/Debugger/Stepping.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" -#include "Common/GPU/ShaderTranslation.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/D3D11/FramebufferManagerD3D11.h" #include "GPU/D3D11/ShaderManagerD3D11.h" @@ -125,15 +124,11 @@ FramebufferManagerD3D11::FramebufferManagerD3D11(Draw::DrawContext *draw) uint32_t nullData[1]{}; context_->UpdateSubresource(nullTexture_, 0, nullptr, nullData, 1, 0); - ShaderTranslationInit(); - presentation_->SetLanguage(HLSL_D3D11); preferredPixelsFormat_ = Draw::DataFormat::B8G8R8A8_UNORM; } FramebufferManagerD3D11::~FramebufferManagerD3D11() { - ShaderTranslationShutdown(); - // Drawing cleanup if (quadVertexShader_) quadVertexShader_->Release(); diff --git a/GPU/Directx9/FramebufferManagerDX9.cpp b/GPU/Directx9/FramebufferManagerDX9.cpp index 70db6442b1..f47678456c 100644 --- a/GPU/Directx9/FramebufferManagerDX9.cpp +++ b/GPU/Directx9/FramebufferManagerDX9.cpp @@ -31,7 +31,6 @@ #include "Common/GPU/D3D9/D3D9StateCache.h" #include "GPU/Common/FramebufferManagerCommon.h" #include "GPU/Common/PresentationCommon.h" -#include "Common/GPU/ShaderTranslation.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/Directx9/FramebufferManagerDX9.h" #include "GPU/Directx9/ShaderManagerDX9.h" @@ -114,15 +113,11 @@ static const D3DVERTEXELEMENT9 g_FramebufferVertexElements[] = { memset(rect.pBits, 0, 4); nullTex_->UnlockRect(0); - ShaderTranslationInit(); - presentation_->SetLanguage(HLSL_D3D9); preferredPixelsFormat_ = Draw::DataFormat::B8G8R8A8_UNORM; } FramebufferManagerDX9::~FramebufferManagerDX9() { - ShaderTranslationShutdown(); - if (pFramebufferVertexShader) { pFramebufferVertexShader->Release(); pFramebufferVertexShader = nullptr; diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index cd9d443945..bff4f56be6 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -78,11 +78,9 @@ SoftGPU::SoftGPU(GraphicsContext *gfxCtx, Draw::DrawContext *draw) presentation_->SetLanguage(draw_->GetShaderLanguageDesc().shaderLanguage); break; case GPUBackend::DIRECT3D9: - ShaderTranslationInit(); presentation_->SetLanguage(HLSL_D3D9); break; case GPUBackend::DIRECT3D11: - ShaderTranslationInit(); presentation_->SetLanguage(HLSL_D3D11); break; case GPUBackend::VULKAN: @@ -119,15 +117,6 @@ SoftGPU::~SoftGPU() { if (presentation_) { delete presentation_; - switch (GetGPUBackend()) { - case GPUBackend::DIRECT3D9: - case GPUBackend::DIRECT3D11: - ShaderTranslationShutdown(); - break; - case GPUBackend::OPENGL: - case GPUBackend::VULKAN: - break; - } } Sampler::Shutdown(); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 5c32ba6190..fd1133b415 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -75,6 +75,7 @@ #include "Common/MemArena.h" #include "Common/GraphicsContext.h" #include "Common/OSVersion.h" +#include "Common/GPU/ShaderTranslation.h" #include "Core/Config.h" #include "Core/ConfigValues.h" @@ -438,6 +439,8 @@ static void ClearFailedGPUBackends() { void NativeInit(int argc, const char *argv[], const char *savegame_dir, const char *external_dir, const char *cache_dir) { net::Init(); // This needs to happen before we load the config. So on Windows we also run it in Main. It's fine to call multiple times. + ShaderTranslationInit(); + InitFastMath(cpu_info.bNEON); SetupAudioFormats(); @@ -1404,6 +1407,8 @@ void NativeShutdown() { g_Discord.Shutdown(); + ShaderTranslationShutdown(); + // Avoid shutting this down when restarting core. if (!restarting) LogManager::Shutdown();