Initialize/Deinitialize the shader translation system once globally.

Fixes #13839.
This commit is contained in:
Henrik Rydgård 2021-01-04 23:51:34 +01:00
parent 92173d5ac4
commit 3f01cbb98c
8 changed files with 30 additions and 30 deletions

View File

@ -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);
}

View File

@ -28,6 +28,9 @@ enum class ShaderStage {
Compute,
};
const char *ShaderStageAsString(ShaderStage lang);
struct ShaderLanguageDesc {
ShaderLanguageDesc() {}
explicit ShaderLanguageDesc(ShaderLanguage lang);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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();

View File

@ -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;

View File

@ -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();

View File

@ -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();