From e754cca28872e0d0a564b8ee9cfbf505ee85e6e0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 20 Sep 2017 12:22:01 -0700 Subject: [PATCH] GLES: Add OpenGL 3.x core profile support. Need to define #version everywhere and avoid varying/etc. --- GPU/GLES/FramebufferManagerGLES.cpp | 15 ++++++++++++- GPU/GLES/StencilBufferGLES.cpp | 33 +++++++++++++++++------------ ext/native/gfx_es2/gpu_features.cpp | 28 ++++++++++++++++++++++++ ext/native/gfx_es2/gpu_features.h | 3 +++ ext/native/thin3d/thin3d.cpp | 21 +++++++++++++++++- ext/native/thin3d/thin3d_gl.cpp | 15 ++++++------- 6 files changed, 92 insertions(+), 23 deletions(-) diff --git a/GPU/GLES/FramebufferManagerGLES.cpp b/GPU/GLES/FramebufferManagerGLES.cpp index 6fad8a9ee91f..e51aad78a685 100644 --- a/GPU/GLES/FramebufferManagerGLES.cpp +++ b/GPU/GLES/FramebufferManagerGLES.cpp @@ -49,6 +49,12 @@ // #define DEBUG_READ_PIXELS 1 static const char tex_fs[] = + "#if __VERSION__ >= 130\n" + "#define varying in\n" + "#define texture2D texture\n" + "#define gl_FragColor fragColor0\n" + "out vec4 fragColor0;\n" + "#endif\n" #ifdef USING_GLES2 "precision mediump float;\n" #endif @@ -59,6 +65,10 @@ static const char tex_fs[] = "}\n"; static const char basic_vs[] = + "#if __VERSION__ >= 130\n" + "#define attribute in\n" + "#define varying out\n" + "#endif\n" "attribute vec4 a_position;\n" "attribute vec2 a_texcoord0;\n" "varying vec2 v_texcoord0;\n" @@ -87,7 +97,10 @@ void FramebufferManagerGLES::DisableState() { void FramebufferManagerGLES::CompileDraw2DProgram() { if (!draw2dprogram_) { std::string errorString; - draw2dprogram_ = glsl_create_source(basic_vs, tex_fs, &errorString); + static std::string vs_code, fs_code; + vs_code = ApplyGLSLPrelude(basic_vs, GL_VERTEX_SHADER); + fs_code = ApplyGLSLPrelude(tex_fs, GL_FRAGMENT_SHADER); + draw2dprogram_ = glsl_create_source(vs_code.c_str(), fs_code.c_str(), &errorString); if (!draw2dprogram_) { ERROR_LOG_REPORT(G3D, "Failed to compile draw2dprogram! This shouldn't happen.\n%s", errorString.c_str()); } else { diff --git a/GPU/GLES/StencilBufferGLES.cpp b/GPU/GLES/StencilBufferGLES.cpp index c431a5175789..d570214917b3 100644 --- a/GPU/GLES/StencilBufferGLES.cpp +++ b/GPU/GLES/StencilBufferGLES.cpp @@ -22,11 +22,16 @@ #include "GPU/GLES/ShaderManagerGLES.h" #include "GPU/GLES/TextureCacheGLES.h" -static const char *gles_prefix = -"#version 100\n" -"precision highp float;\n"; - static const char *stencil_fs = +"#ifdef GL_ES\n" +"precision highp float;\n" +"#endif\n" +"#if __VERSION__ >= 130\n" +"#define varying in\n" +"#define texture2D texture\n" +"#define gl_FragColor fragColor0\n" +"out vec4 fragColor0;\n" +"#endif\n" "varying vec2 v_texcoord0;\n" "uniform float u_stencilValue;\n" "uniform sampler2D tex;\n" @@ -39,6 +44,13 @@ static const char *stencil_fs = "}\n"; static const char *stencil_vs = +"#ifdef GL_ES\n" +"precision highp float;\n" +"#endif\n" +"#if __VERSION__ >= 130\n" +"#define attribute in\n" +"#define varying out\n" +"#endif\n" "attribute vec4 a_position;\n" "attribute vec2 a_texcoord0;\n" "varying vec2 v_texcoord0;\n" @@ -47,14 +59,6 @@ static const char *stencil_vs = " gl_Position = a_position;\n" "}\n"; -std::string GLSLES100PrefixProgram(std::string code) { - if (gl_extensions.IsGLES) { - return std::string(gles_prefix) + code; - } else { - return code; - } -} - static u8 StencilBits5551(const u8 *ptr8, u32 numPixels) { const u32 *ptr = (const u32 *)ptr8; @@ -152,7 +156,10 @@ bool FramebufferManagerGLES::NotifyStencilUpload(u32 addr, int size, bool skipZe if (!stencilUploadProgram_) { std::string errorString; - stencilUploadProgram_ = glsl_create_source(GLSLES100PrefixProgram(stencil_vs).c_str(), GLSLES100PrefixProgram(stencil_fs).c_str(), &errorString); + static std::string vs_code, fs_code; + vs_code = ApplyGLSLPrelude(stencil_vs, GL_VERTEX_SHADER); + fs_code = ApplyGLSLPrelude(stencil_fs, GL_FRAGMENT_SHADER); + stencilUploadProgram_ = glsl_create_source(vs_code.c_str(), fs_code.c_str(), &errorString); if (!stencilUploadProgram_) { ERROR_LOG_REPORT(G3D, "Failed to compile stencilUploadProgram! This shouldn't happen.\n%s", errorString.c_str()); } else { diff --git a/ext/native/gfx_es2/gpu_features.cpp b/ext/native/gfx_es2/gpu_features.cpp index a97a0f39f448..a3ef8af9aceb 100644 --- a/ext/native/gfx_es2/gpu_features.cpp +++ b/ext/native/gfx_es2/gpu_features.cpp @@ -444,3 +444,31 @@ void SetGLCoreContext(bool flag) { // For convenience, it'll get reset later. gl_extensions.IsCoreContext = useCoreContext; } + +static const char *glsl_fragment_prelude = +"#ifdef GL_ES\n" +"precision mediump float;\n" +"#endif\n"; + +std::string ApplyGLSLPrelude(const std::string &source, uint32_t stage) { + std::string temp; + std::string version = ""; + if (!gl_extensions.IsGLES && gl_extensions.IsCoreContext) { + // We need to add a corresponding #version. Apple drives fail without an exact match. + if (gl_extensions.VersionGEThan(3, 3)) { + version = StringFromFormat("#version %d%d0\n", gl_extensions.ver[0], gl_extensions.ver[1]); + } else if (gl_extensions.VersionGEThan(3, 2)) { + version = "#version 150\n"; + } else if (gl_extensions.VersionGEThan(3, 1)) { + version = "#version 140\n"; + } else { + version = "#version 130\n"; + } + } + if (stage == GL_FRAGMENT_SHADER) { + temp = version + glsl_fragment_prelude + source; + } else if (stage == GL_VERTEX_SHADER) { + temp = version + source; + } + return temp; +} diff --git a/ext/native/gfx_es2/gpu_features.h b/ext/native/gfx_es2/gpu_features.h index d8ea0de803af..3bc237c3f064 100644 --- a/ext/native/gfx_es2/gpu_features.h +++ b/ext/native/gfx_es2/gpu_features.h @@ -4,6 +4,7 @@ #pragma once +#include #include "base/NativeApp.h" enum { @@ -110,3 +111,5 @@ extern std::string g_all_egl_extensions; void CheckGLExtensions(); void SetGLCoreContext(bool flag); + +std::string ApplyGLSLPrelude(const std::string &source, uint32_t stage); diff --git a/ext/native/thin3d/thin3d.cpp b/ext/native/thin3d/thin3d.cpp index b04626760e9e..46ddbf3c5350 100644 --- a/ext/native/thin3d/thin3d.cpp +++ b/ext/native/thin3d/thin3d.cpp @@ -69,6 +69,12 @@ static const std::vector fsTexCol = { "#ifdef GL_ES\n" "precision lowp float;\n" "#endif\n" + "#if __VERSION__ >= 130\n" + "#define varying in\n" + "#define texture2D texture\n" + "#define gl_FragColor fragColor0\n" + "out vec4 fragColor0;\n" + "#endif\n" "varying vec4 oColor0;\n" "varying vec2 oTexCoord0;\n" "uniform sampler2D Sampler0;\n" @@ -107,6 +113,11 @@ static const std::vector fsCol = { "#ifdef GL_ES\n" "precision lowp float;\n" "#endif\n" + "#if __VERSION__ >= 130\n" + "#define varying in\n" + "#define gl_FragColor fragColor0\n" + "out vec4 fragColor0;\n" + "#endif\n" "varying vec4 oColor0;\n" "void main() { gl_FragColor = oColor0; }\n" }, @@ -136,6 +147,10 @@ static const std::vector fsCol = { static const std::vector vsCol = { { ShaderLanguage::GLSL_ES_200, + "#if __VERSION__ >= 130\n" + "#define attribute in\n" + "#define varying out\n" + "#endif\n" "attribute vec3 Position;\n" "attribute vec4 Color0;\n" "varying vec4 oColor0;\n" @@ -193,6 +208,10 @@ const UniformBufferDesc vsColBufDesc { sizeof(VsColUB), { static const std::vector vsTexCol = { { ShaderLanguage::GLSL_ES_200, + "#if __VERSION__ >= 130\n" + "#define attribute in\n" + "#define varying out\n" + "#endif\n" "attribute vec3 Position;\n" "attribute vec4 Color0;\n" "attribute vec2 TexCoord0;\n" @@ -285,4 +304,4 @@ DrawContext::~DrawContext() { } } -} // namespace Draw \ No newline at end of file +} // namespace Draw diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 2d4e6d968d7f..440fffe5a8d9 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -163,11 +163,6 @@ static const unsigned short primToGL[] = { class OpenGLBuffer; -static const char *glsl_fragment_prelude = -"#ifdef GL_ES\n" -"precision mediump float;\n" -"#endif\n"; - class OpenGLBlendState : public BlendState { public: bool enabled; @@ -332,9 +327,9 @@ bool OpenGLShaderModule::Compile(ShaderLanguage language, const uint8_t *data, s language_ = language; std::string temp; - // Add the prelude on automatically for fragment shaders. - if (glstage_ == GL_FRAGMENT_SHADER) { - temp = std::string(glsl_fragment_prelude) + source_; + // Add the prelude on automatically. + if (glstage_ == GL_FRAGMENT_SHADER || glstage_ == GL_VERTEX_SHADER) { + temp = ApplyGLSLPrelude(source_, glstage_); source_ = temp.c_str(); } @@ -1047,6 +1042,10 @@ bool OpenGLPipeline::LinkShaders() { glBindAttribLocation(program_, SEM_NORMAL, "Normal"); glBindAttribLocation(program_, SEM_TANGENT, "Tangent"); glBindAttribLocation(program_, SEM_BINORMAL, "Binormal"); + + if (gl_extensions.VersionGEThan(3, 3, 0)) { + glBindFragDataLocation(program_, 0, "fragColor0"); + } glLinkProgram(program_); GLint linkStatus = GL_FALSE;