diff --git a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp index a9c602ad3d..4be33e9eac 100644 --- a/Source/Core/VideoCommon/Src/LightingShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/LightingShaderGen.cpp @@ -213,7 +213,7 @@ char *GenerateLightingShader(char *p, int components, const char* materialsName, p = GenerateLightShader(p, i, workingchannel, lightsName, coloralpha); } } - WRITE(p, "%s%d = mat * saturate(lacc);\n", dest, j); + WRITE(p, "%s%d = mat * clamp(lacc, 0.0, 1.0);\n", dest, j); WRITE(p, "}\n"); } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index efc16566eb..9ab5752e88 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -272,7 +272,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType); static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); // static void WriteAlphaCompare(char *&p, int num, int comp); static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode, bool per_pixel_depth); -static void WriteFog(char *&p); +static void WriteFog(char *&p, API_TYPE ApiType); static const char *tevKSelTableC[] = // KCSEL { @@ -480,6 +480,17 @@ static void BuildSwapModeTable() } } +// We can't use function defines since the Qualcomm shader compiler doesn't support it +static const char *GLSLConvertFunctions[] = +{ + "frac", // HLSL + "fract", // GLSL + "lerp", + "mix" +}; +#define FUNC_FRAC 0 +#define FUNC_LERP 2 + const char* WriteRegister(API_TYPE ApiType, const char *prefix, const u32 num) { if (ApiType == API_OPENGL) @@ -508,7 +519,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType int numTexgen = bpmem.genMode.numtexgens; bool per_pixel_depth = bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable; - + bool bOpenGL = ApiType == API_OPENGL; char *p = text; WRITE(p, "//Pixel Shader for TEV stages\n"); WRITE(p, "//%i TEV stages, %i texgens, XXX IND stages\n", @@ -802,7 +813,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType } // emulation of unsigned 8 overflow when casting if needed if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) - WRITE(p, "\tprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "\tprev = %s(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); if (Pretest == AlphaTest::UNDETERMINED) @@ -826,7 +837,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType // scale to make result from frac correct WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n"); - WRITE(p, "zCoord = frac(zCoord);\n"); + WRITE(p, "zCoord = %s(zCoord);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n"); // Note: depth texture out put is only written to depth buffer if late depth test is used @@ -840,7 +851,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType } else { - WriteFog(p); + WriteFog(p, ApiType); WRITE(p, "\tocol0 = prev;\n"); } @@ -913,16 +924,14 @@ static const char *TEVCMPAlphaOPTable[16] = " %s.a + (abs(dot(%s.rgb, comp24) - dot(%s.rgb, comp24)) < (0.5f/255.0f) ? %s.a : 0.0f)",//#define TEVCMP_BGR24_EQ 13 " %s.a + ((%s.a >= (%s.a + (0.25f/255.0f))) ? %s.a : 0.0f)",//#define TEVCMP_A8_GT 14 " %s.a + (abs(%s.a - %s.a) < (0.5f/255.0f) ? %s.a : 0.0f)"//#define TEVCMP_A8_EQ 15 - }; - static void WriteStage(char *&p, int n, API_TYPE ApiType) { int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1); bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens; bool bHasIndStage = bpmem.tevind[n].IsActive() && bpmem.tevind[n].bt < bpmem.genMode.numindstages; - + bool bOpenGL = ApiType == API_OPENGL; // HACK to handle cases where the tex gen is not enabled if (!bHasTexCoord) texcoord = 0; @@ -1016,7 +1025,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { char *rasswap = swapModeTable[bpmem.combiners[n].alphaC.rswap]; WRITE(p, "rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap); - WRITE(p, "crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "crastemp = %s(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); } @@ -1049,7 +1058,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) WRITE(p, "konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]); if (kc > 7 || ka > 7) { - WRITE(p, "ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "ckonsttemp = %s(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); } else { @@ -1064,7 +1073,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl) { - WRITE(p, "cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cprev = %s(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[0].AlphaNeedOverflowControl = false; RegisterStates[0].ColorNeedOverflowControl = false; } @@ -1082,7 +1091,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl) { - WRITE(p, "cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cc0 = %s(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[1].AlphaNeedOverflowControl = false; RegisterStates[1].ColorNeedOverflowControl = false; } @@ -1100,7 +1109,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl) { - WRITE(p, "cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cc1 = %s(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[2].AlphaNeedOverflowControl = false; RegisterStates[2].ColorNeedOverflowControl = false; } @@ -1118,7 +1127,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) { if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl) { - WRITE(p, "cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); + WRITE(p, "cc2 = %s(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n", GLSLConvertFunctions[FUNC_FRAC + bOpenGL]); RegisterStates[3].AlphaNeedOverflowControl = false; RegisterStates[3].ColorNeedOverflowControl = false; } @@ -1135,7 +1144,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) // combine the color channel WRITE(p, "// color combine\n"); if (cc.clamp) - WRITE(p, "%s = saturate(", tevCOutputTable[cc.dest]); + WRITE(p, "%s = clamp(", tevCOutputTable[cc.dest]); else WRITE(p, "%s = ", tevCOutputTable[cc.dest]); @@ -1160,7 +1169,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) else if (cc.b == TEVCOLORARG_ZERO) WRITE(p, "%s*(float3(1.0f, 1.0f, 1.0f)-%s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.c + 16]); else - WRITE(p, "lerp(%s, %s, %s)", tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); + WRITE(p, "%s(%s, %s, %s)", GLSLConvertFunctions[FUNC_LERP + bOpenGL], tevCInputTable[cc.a + 16], tevCInputTable[cc.b + 16], tevCInputTable[cc.c + 16]); WRITE(p, "%s", tevBiasTable[cc.bias]); @@ -1177,7 +1186,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) tevCInputTable[cc.c + 16]); } if (cc.clamp) - WRITE(p, ")"); + WRITE(p, ", 0.0, 1.0)"); WRITE(p,";\n"); RegisterStates[ac.dest].AlphaNeedOverflowControl = (ac.clamp == 0); @@ -1186,7 +1195,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) // combine the alpha channel WRITE(p, "// alpha combine\n"); if (ac.clamp) - WRITE(p, "%s = saturate(", tevAOutputTable[ac.dest]); + WRITE(p, "%s = clamp(", tevAOutputTable[ac.dest]); else WRITE(p, "%s = ", tevAOutputTable[ac.dest]); @@ -1208,7 +1217,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) else if (ac.b == TEVALPHAARG_ZERO) WRITE(p, "%s.a*(1.0f-%s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.c + 8]); else - WRITE(p, "lerp(%s.a, %s.a, %s.a)", tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); + WRITE(p, "%s(%s.a, %s.a, %s.a)", GLSLConvertFunctions[FUNC_LERP + bOpenGL], tevAInputTable[ac.a + 8], tevAInputTable[ac.b + 8], tevAInputTable[ac.c + 8]); WRITE(p, "%s",tevBiasTable[ac.bias]); @@ -1227,7 +1236,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType) tevAInputTable[ac.c + 8]); } if (ac.clamp) - WRITE(p, ")"); + WRITE(p, ", 0.0, 1.0)"); WRITE(p, ";\n\n"); WRITE(p, "// TEV done\n"); } @@ -1319,8 +1328,10 @@ static const char *tevFogFuncsTable[] = "\tfog = 1.0f - fog;\n fog = pow(2.0f, -8.0f * fog * fog);\n" // backward exp2 }; -static void WriteFog(char *&p) +static void WriteFog(char *&p, API_TYPE ApiType) { + bool bOpenGL = ApiType == API_OPENGL; + if (bpmem.fog.c_proj_fsel.fsel == 0) return; // no Fog @@ -1347,7 +1358,7 @@ static void WriteFog(char *&p) WRITE (p, "\tze *= x_adjust;\n"); } - WRITE (p, "\tfloat fog = saturate(ze - " I_FOG"[1].z);\n"); + WRITE (p, "\tfloat fog = clamp(ze - " I_FOG"[1].z, 0.0, 1.0);\n"); if (bpmem.fog.c_proj_fsel.fsel > 3) { @@ -1359,5 +1370,5 @@ static void WriteFog(char *&p) WARN_LOG(VIDEO, "Unknown Fog Type! %08x", bpmem.fog.c_proj_fsel.fsel); } - WRITE(p, "\tprev.rgb = lerp(prev.rgb, " I_FOG"[0].rgb, fog);\n"); + WRITE(p, "\tprev.rgb = %s(prev.rgb, " I_FOG"[0].rgb, fog);\n", GLSLConvertFunctions[FUNC_LERP + bOpenGL]); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp index 2638a43fe6..5ce106601f 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/FramebufferManager.cpp @@ -86,6 +86,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms GL_REPORT_FBO_ERROR(); } +#ifndef USE_GLES3 else { // EFB targets will be renderbuffers in MSAA mode (required by OpenGL). @@ -151,7 +152,7 @@ FramebufferManager::FramebufferManager(int targetWidth, int targetHeight, int ms glBindFramebuffer(GL_FRAMEBUFFER, m_efbFramebuffer); } - +#endif // Create XFB framebuffer; targets will be created elsewhere. glGenFramebuffers(1, &m_xfbFramebuffer); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp index d24ab5a6a0..1b5ab26c73 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/ProgramShaderCache.cpp @@ -103,6 +103,7 @@ void SHADER::SetProgramVariables() void SHADER::SetProgramBindings() { +#ifndef USE_GLES3 if (g_ActiveConfig.backend_info.bSupportsDualSourceBlend) { // So we do support extended blending @@ -120,7 +121,7 @@ void SHADER::SetProgramBindings() // ogl2 shaders don't need to bind output colors. // gl_FragColor already point to color channel } - +#endif // Need to set some attribute locations glBindAttribLocation(glprogid, SHADER_POSITION_ATTRIB, "rawpos"); @@ -516,11 +517,6 @@ void ProgramShaderCache::CreateHeader ( void ) "#define float3 vec3\n" "#define float4 vec4\n" - // hlsl to glsl function translation - "#define frac(x) fract(x)\n" - "#define saturate(x) clamp(x, 0.0f, 1.0f)\n" - "#define lerp(x, y, z) mix(x, y, z)\n" - // glsl 120 hack "%s\n" "%s\n" diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 19472b5249..db628a8f54 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -1276,6 +1276,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } // Frame dumps are handled a little differently in Windows + // Frame dumping disabled entirely on GLES3 +#ifndef USE_GLES3 #if defined _WIN32 || defined HAVE_LIBAV if (g_ActiveConfig.bDumpFrames) { @@ -1372,7 +1374,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons bLastFrameDumped = false; } #endif - +#endif // Finish up the current frame, print some stats SetWindowSize(fbWidth, fbHeight);