diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index eccaab413c..401b7f72ff 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -28,6 +28,7 @@ #endif #include "FragmentShaderGenerator.h" +#include "Framebuffer.h" #include "../ge_constants.h" #include "../GPUState.h" #include @@ -202,10 +203,16 @@ void GenerateFragmentShader(char *buffer) { } if (enableAlphaTest) { - WRITE(p, "float roundTo255th(in float x) { float y = x + (0.49/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n"); + if (gstate_c.gpuVendor == GPU_VENDOR_POWERVR) + WRITE(p, "float roundTo255th(in float x) { float y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n"); + else + WRITE(p, "float roundAndScaleTo255f(in float x) { return floor(x * 255.0 + 0.5); }\n"); } if (enableColorTest) { - WRITE(p, "vec3 roundTo255thv(in vec3 x) { vec3 y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n"); + if (gstate_c.gpuVendor == GPU_VENDOR_POWERVR) + WRITE(p, "vec3 roundTo255thv(in vec3 x) { vec3 y = x + (0.5/255.0); return y - fract(y * 255.0) * (1.0 / 255.0); }\n"); + else + WRITE(p, "vec3 roundAndScaleTo255v(in vec3 x) { return floor(x * 255.0 + 0.5); }\n"); } WRITE(p, "void main() {\n"); @@ -272,7 +279,10 @@ void GenerateFragmentShader(char *buffer) { int alphaTestFunc = gstate.alphatest & 7; const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " }; // never/always don't make sense if (alphaTestFuncs[alphaTestFunc][0] != '#') { - WRITE(p, " if (roundTo255th(v.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]); + if (gstate_c.gpuVendor == GPU_VENDOR_POWERVR) + WRITE(p, " if (roundTo255th(v.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]); + else + WRITE(p, " if (roundAndScaleTo255f(v.a) %s u_alphacolorref.a) discard;\n", alphaTestFuncs[alphaTestFunc]); } } @@ -290,7 +300,10 @@ void GenerateFragmentShader(char *buffer) { const char *colorTestFuncs[] = { "#", "#", " != ", " == " }; // never/always don't make sense int colorTestMask = gstate.colormask; if (colorTestFuncs[colorTestFunc][0] != '#') { - WRITE(p, "if (roundTo255thv(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]); + if (gstate_c.gpuVendor == GPU_VENDOR_POWERVR) + WRITE(p, "if (roundTo255thv(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]); + else + WRITE(p, "if (roundAndScaleTo255v(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]); } } diff --git a/GPU/GLES/Framebuffer.cpp b/GPU/GLES/Framebuffer.cpp index 50ed9199e1..b6f7713801 100644 --- a/GPU/GLES/Framebuffer.cpp +++ b/GPU/GLES/Framebuffer.cpp @@ -191,14 +191,17 @@ FramebufferManager::FramebufferManager() : || vendor == "Intel Corporation" || vendor == "Tungsten Graphics, Inc") { // We'll assume this last one means Intel gpuVendor = GPU_VENDOR_INTEL; - } else if(vendor == "ARM") { + } else if(vendor == "ARM") gpuVendor = GPU_VENDOR_ARM; - } else { + else if(vendor == "Imagination Technologies") + gpuVendor = GPU_VENDOR_POWERVR; + else if(vendor == "Qualcomm") + gpuVendor = GPU_VENDOR_ADRENO; + else gpuVendor = GPU_VENDOR_UNKNOWN; - } - } else { + } else gpuVendor = GPU_VENDOR_UNKNOWN; - } + gstate_c.gpuVendor = gpuVendor; } FramebufferManager::~FramebufferManager() { diff --git a/GPU/GLES/Framebuffer.h b/GPU/GLES/Framebuffer.h index 87203c761a..f1ab46b1f9 100644 --- a/GPU/GLES/Framebuffer.h +++ b/GPU/GLES/Framebuffer.h @@ -49,6 +49,8 @@ enum { GPU_VENDOR_AMD = 2, GPU_VENDOR_INTEL = 3, GPU_VENDOR_ARM = 4, + GPU_VENDOR_POWERVR = 5, + GPU_VENDOR_ADRENO = 6, GPU_VENDOR_UNKNOWN = 0 }; diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index f66e202dad..291c4cf1a6 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -34,6 +34,7 @@ #include "GPU/GLES/ShaderManager.h" #include "GPU/GLES/TransformPipeline.h" #include "UI/OnScreenDisplay.h" +#include "Framebuffer.h" Shader::Shader(const char *code, uint32_t shaderType, bool useHWTransform) : failed_(false), useHWTransform_(useHWTransform) { source_ = code; @@ -195,13 +196,23 @@ static void SetColorUniform3Alpha(int uniform, u32 color, u8 alpha) { // This passes colors unscaled (e.g. 0 - 255 not 0 - 1.) static void SetColorUniform3Alpha255(int uniform, u32 color, u8 alpha) { - const float col[4] = { - (float)((color & 0xFF)) * (1.0f / 255.0f), - (float)((color & 0xFF00) >> 8) * (1.0f / 255.0f), - (float)((color & 0xFF0000) >> 16) * (1.0f / 255.0f), - (float)alpha * (1.0f / 255.0f) - }; - glUniform4fv(uniform, 1, col); + if (gstate_c.gpuVendor == GPU_VENDOR_POWERVR) { + const float col[4] = { + (float)((color & 0xFF)) * (1.0f / 255.0f), + (float)((color & 0xFF00) >> 8) * (1.0f / 255.0f), + (float)((color & 0xFF0000) >> 16) * (1.0f / 255.0f), + (float)alpha * (1.0f / 255.0f) + }; + glUniform4fv(uniform, 1, col); + } else { + const float col[4] = { + (float)((color & 0xFF)) , + (float)((color & 0xFF00) >> 8) , + (float)((color & 0xFF0000) >> 16) , + (float)alpha + }; + glUniform4fv(uniform, 1, col); + } } static void SetColorUniform3ExtraFloat(int uniform, u32 color, float extra) { diff --git a/GPU/GPUState.h b/GPU/GPUState.h index d13057810b..a8d7b52af4 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -285,6 +285,7 @@ struct GPUStateCache u32 curRTHeight; u32 getRelativeAddress(u32 data) const; + int gpuVendor; }; // TODO: Implement support for these.