Use glslang to translate GLSL 1.x postshaders to GLSL 3.0 or later to appease strict GL Core drivers. Should fix #10362

Fixed small bugs, now tested and working on mac.

Add spirv-cross to cmake build
This commit is contained in:
Henrik Rydgård 2017-12-07 17:02:00 +01:00
parent 253bba28d8
commit 99b34c7b45
7 changed files with 76 additions and 2 deletions

View File

@ -1638,7 +1638,7 @@ endif()
set(CoreExtraLibs ${CoreExtraLibs} armips) set(CoreExtraLibs ${CoreExtraLibs} armips)
set(GlslangLibs glslang OGLCompiler OSDependent SPIRV SPVRemapper) set(GlslangLibs glslang OGLCompiler OSDependent SPIRV SPVRemapper spirv-cross-glsl)
target_link_libraries(${CoreLibName} Common native kirk cityhash sfmt19937 xbrz xxhash ${GlslangLibs} target_link_libraries(${CoreLibName} Common native kirk cityhash sfmt19937 xbrz xxhash ${GlslangLibs}
${CoreExtraLibs} ${OPENGL_LIBRARIES} ${X11_LIBRARIES} ${CMAKE_DL_LIBS}) ${CoreExtraLibs} ${OPENGL_LIBRARIES} ${X11_LIBRARIES} ${CMAKE_DL_LIBS})

View File

@ -32,6 +32,7 @@
#include "ShaderTranslation.h" #include "ShaderTranslation.h"
#include "ext/glslang/SPIRV/GlslangToSpv.h" #include "ext/glslang/SPIRV/GlslangToSpv.h"
#include "thin3d/thin3d.h" #include "thin3d/thin3d.h"
#include "gfx_es2/gpu_features.h"
#if !defined(ANDROID) #if !defined(ANDROID)
#include "ext/SPIRV-Cross/spirv.hpp" #include "ext/SPIRV-Cross/spirv.hpp"
@ -196,6 +197,9 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
bool result = ConvertToVulkanGLSL(dest, destMetadata, src, stage, errorMessage); bool result = ConvertToVulkanGLSL(dest, destMetadata, src, stage, errorMessage);
return result; return result;
} }
if (errorMessage) {
*errorMessage = "";
}
#if defined(ANDROID) #if defined(ANDROID)
return false; return false;
@ -307,6 +311,23 @@ bool TranslateShader(std::string *dest, ShaderLanguage destLang, TranslatedShade
*dest = glsl.compile(); *dest = glsl.compile();
return true; return true;
} }
case GLSL_300:
{
spirv_cross::CompilerGLSL glsl(std::move(spirv));
// The SPIR-V is now parsed, and we can perform reflection on it.
spirv_cross::ShaderResources resources = glsl.get_shader_resources();
// Set some options.
spirv_cross::CompilerGLSL::Options options;
if (gl_extensions.ver[0] >= 4) {
options.version = 400;
} else {
options.version = 300;
}
glsl.set_options(options);
// Compile to GLSL, ready to give to GL driver.
*dest = glsl.compile();
return true;
}
default: default:
return false; return false;
} }

View File

@ -25,6 +25,7 @@
#include "thin3d/thin3d.h" #include "thin3d/thin3d.h"
#include "base/timeutil.h" #include "base/timeutil.h"
#include "file/vfs.h"
#include "math/lin/matrix4x4.h" #include "math/lin/matrix4x4.h"
#include "Common/ColorConv.h" #include "Common/ColorConv.h"
@ -37,6 +38,7 @@
#include "GPU/GPUState.h" #include "GPU/GPUState.h"
#include "GPU/Common/PostShader.h" #include "GPU/Common/PostShader.h"
#include "GPU/Common/ShaderTranslation.h"
#include "GPU/Common/TextureDecoder.h" #include "GPU/Common/TextureDecoder.h"
#include "GPU/Common/FramebufferCommon.h" #include "GPU/Common/FramebufferCommon.h"
#include "GPU/Debugger/Stepping.h" #include "GPU/Debugger/Stepping.h"
@ -122,7 +124,44 @@ void FramebufferManagerGLES::CompilePostShader() {
if (shaderInfo) { if (shaderInfo) {
std::string errorString; std::string errorString;
postShaderAtOutputResolution_ = shaderInfo->outputResolution; postShaderAtOutputResolution_ = shaderInfo->outputResolution;
postShaderProgram_ = glsl_create(shaderInfo->vertexShaderFile.c_str(), shaderInfo->fragmentShaderFile.c_str(), &errorString);
size_t sz;
char *vs = (char *)VFSReadFile(shaderInfo->vertexShaderFile.c_str(), &sz);
if (!vs)
return;
char *fs = (char *)VFSReadFile(shaderInfo->fragmentShaderFile.c_str(), &sz);
if (!fs) {
free(vs);
return;
}
std::string vshader;
std::string fshader;
bool translationFailed = false;
if (gl_extensions.IsCoreContext) {
// Gonna have to upconvert the shaders.
std::string errorMessage;
if (!TranslateShader(&vshader, GLSL_300, nullptr, vs, GLSL_140, Draw::ShaderStage::VERTEX, &errorMessage)) {
translationFailed = true;
ELOG("Failed to translate post-vshader: %s", errorMessage.c_str());
}
if (!TranslateShader(&fshader, GLSL_300, nullptr, fs, GLSL_140, Draw::ShaderStage::FRAGMENT, &errorMessage)) {
translationFailed = true;
ELOG("Failed to translate post-fshader: %s", errorMessage.c_str());
}
} else {
vshader = vs;
fshader = fs;
}
if (!translationFailed) {
postShaderProgram_ = glsl_create_source(vshader.c_str(), fshader.c_str(), &errorString);
} else {
ERROR_LOG(FRAMEBUF, "Failed to translate post shader!");
}
free(vs);
free(fs);
if (!postShaderProgram_) { if (!postShaderProgram_) {
// DO NOT turn this into a report, as it will pollute our logs with all kinds of // DO NOT turn this into a report, as it will pollute our logs with all kinds of
// user shader experiments. // user shader experiments.

View File

@ -396,6 +396,9 @@ void SystemInfoScreen::CreateViews() {
} }
#endif #endif
#endif #endif
if (g_Config.iGPUBackend == GPU_BACKEND_OPENGL) {
deviceSpecs->Add(new InfoItem("Core Context", gl_extensions.IsCoreContext ? "Yes" : "No"));
}
deviceSpecs->Add(new ItemHeader("OS Information")); deviceSpecs->Add(new ItemHeader("OS Information"));
deviceSpecs->Add(new InfoItem("Memory Page Size", StringFromFormat("%d bytes", GetMemoryProtectPageSize()))); deviceSpecs->Add(new InfoItem("Memory Page Size", StringFromFormat("%d bytes", GetMemoryProtectPageSize())));
deviceSpecs->Add(new InfoItem("RW/RX exclusive: ", PlatformIsWXExclusive() ? "Yes" : "No")); deviceSpecs->Add(new InfoItem("RW/RX exclusive: ", PlatformIsWXExclusive() ? "Yes" : "No"));

View File

@ -28,6 +28,7 @@
#include "util/text/utf8.h" #include "util/text/utf8.h"
#include "i18n/i18n.h" #include "i18n/i18n.h"
#include "UI/OnScreenDisplay.h" #include "UI/OnScreenDisplay.h"
#include "ext/glslang/glslang/Public/ShaderLang.h"
#include "Windows/W32Util/Misc.h" #include "Windows/W32Util/Misc.h"
#include "Windows/GPU/WindowsGLContext.h" #include "Windows/GPU/WindowsGLContext.h"
@ -151,6 +152,7 @@ void DebugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
} }
bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_message) { bool WindowsGLContext::Init(HINSTANCE hInst, HWND window, std::string *error_message) {
glslang::InitializeProcess();
*error_message = "ok"; *error_message = "ok";
hWnd = window; hWnd = window;
GLuint PixelFormat; GLuint PixelFormat;
@ -398,6 +400,7 @@ void WindowsGLContext::Shutdown() {
hDC = NULL; hDC = NULL;
} }
hWnd = NULL; hWnd = NULL;
glslang::FinalizeProcess();
} }
void WindowsGLContext::Resize() { void WindowsGLContext::Resize() {

View File

@ -32,6 +32,7 @@ SDLJoystick *joystick = NULL;
#include "base/display.h" #include "base/display.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/timeutil.h" #include "base/timeutil.h"
#include "ext/glslang/glslang/Public/ShaderLang.h"
#include "gfx/gl_common.h" #include "gfx/gl_common.h"
#include "gfx_es2/gpu_features.h" #include "gfx_es2/gpu_features.h"
#include "input/input_state.h" #include "input/input_state.h"
@ -687,6 +688,8 @@ int main(int argc, char *argv[]) {
printf("Pixels: %i x %i\n", pixel_xres, pixel_yres); printf("Pixels: %i x %i\n", pixel_xres, pixel_yres);
printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres); printf("Virtual pixels: %i x %i\n", dp_xres, dp_yres);
glslang::InitializeProcess();
GraphicsContext *graphicsContext = new GLDummyGraphicsContext(); GraphicsContext *graphicsContext = new GLDummyGraphicsContext();
NativeInitGraphics(graphicsContext); NativeInitGraphics(graphicsContext);
@ -939,6 +942,7 @@ int main(int argc, char *argv[]) {
graphicsContext->Shutdown(); graphicsContext->Shutdown();
NativeShutdown(); NativeShutdown();
delete graphicsContext; delete graphicsContext;
glslang::FinalizeProcess();
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown // Faster exit, thanks to the OS. Remove this if you want to debug shutdown
// The speed difference is only really noticable on Linux. On Windows you do notice it though // The speed difference is only really noticable on Linux. On Windows you do notice it though
#ifndef MOBILE_DEVICE #ifndef MOBILE_DEVICE

View File

@ -13,6 +13,8 @@
#include <QLocale> #include <QLocale>
#include <QThread> #include <QThread>
#include "ext/glslang/glslang/Public/ShaderLang.h"
#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) #if QT_VERSION > QT_VERSION_CHECK(5, 0, 0)
#include <QStandardPaths> #include <QStandardPaths>
#ifdef QT_HAS_SYSTEMINFO #ifdef QT_HAS_SYSTEMINFO
@ -428,6 +430,7 @@ Q_DECL_EXPORT
#endif #endif
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
glslang::InitializeProcess();
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
QApplication::setAttribute(Qt::AA_X11InitThreads, true); QApplication::setAttribute(Qt::AA_X11InitThreads, true);
#endif #endif
@ -467,6 +470,7 @@ int main(int argc, char *argv[])
SDL_CloseAudio(); SDL_CloseAudio();
#endif #endif
NativeShutdown(); NativeShutdown();
glslang::FinalizeProcess();
return ret; return ret;
} }