Merge pull request #7567 from unknownbrackets/gpu-blend

Use framebuffer fetch more and on more devices
This commit is contained in:
Henrik Rydgård 2015-03-09 22:24:23 +01:00
commit 33b291a36e
3 changed files with 21 additions and 10 deletions

View File

@ -285,6 +285,8 @@ ReplaceBlendType ReplaceBlendWithShader() {
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
// We can't technically do this correctly (due to clamping) without reading the dst color.
// Using a copy isn't accurate either, though, when there's overlap.
if (gl_extensions.ANY_shader_framebuffer_fetch)
return !gstate_c.allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;
default:
@ -342,11 +344,15 @@ ReplaceBlendType ReplaceBlendWithShader() {
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
if (funcA == GE_SRCBLEND_SRCALPHA || funcA == GE_SRCBLEND_INVSRCALPHA) {
// Can't safely double alpha, will clamp. However, a copy may easily be worse due to overlap.
if (gl_extensions.ANY_shader_framebuffer_fetch)
return !gstate_c.allowShaderBlend ? REPLACE_BLEND_PRE_SRC_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
return REPLACE_BLEND_PRE_SRC_2X_ALPHA;
} else {
// This means dst alpha/color is used in the src factor.
// Unfortunately, copying here causes overlap problems in Silent Hill games (it seems?)
// We will just hope that doubling alpha for the dst factor will not clamp too badly.
if (gl_extensions.ANY_shader_framebuffer_fetch)
return !gstate_c.allowShaderBlend ? REPLACE_BLEND_2X_ALPHA : REPLACE_BLEND_COPY_FBO;
return REPLACE_BLEND_2X_ALPHA;
}
@ -493,6 +499,7 @@ void GenerateFragmentShader(char *buffer) {
bool highpFog = false;
bool highpTexcoord = false;
bool bitwiseOps = false;
const char *lastFragData = nullptr;
#if defined(USING_GLES2)
// Let's wait until we have a real use for this.
@ -518,9 +525,16 @@ void GenerateFragmentShader(char *buffer) {
highpFog = (gl_extensions.bugs & BUG_PVR_SHADER_PRECISION_BAD) ? true : false;
highpTexcoord = highpFog;
// GL_NV_shader_framebuffer_fetch available on mobile platform and ES 2.0 only but not desktop
if (gl_extensions.NV_shader_framebuffer_fetch) {
if (gl_extensions.EXT_shader_framebuffer_fetch) {
WRITE(p, "#extension GL_EXT_shader_framebuffer_fetch : require\n");
lastFragData = "gl_lastFragData[0]";
} else if (gl_extensions.NV_shader_framebuffer_fetch) {
// GL_NV_shader_framebuffer_fetch is available on mobile platform and ES 2.0 only but not on desktop.
WRITE(p, "#extension GL_NV_shader_framebuffer_fetch : require\n");
lastFragData = "gl_lastFragData[0]";
} else if (gl_extensions.ARM_shader_framebuffer_fetch) {
WRITE(p, "#extension GL_ARM_shader_framebuffer_fetch : require\n");
lastFragData = "gl_lastFragColorARM";
}
WRITE(p, "precision lowp float;\n");
@ -597,7 +611,7 @@ void GenerateFragmentShader(char *buffer) {
if (doTexture)
WRITE(p, "uniform sampler2D tex;\n");
if (!gstate.isModeClear() && replaceBlend > REPLACE_BLEND_STANDARD) {
if (!gl_extensions.NV_shader_framebuffer_fetch && replaceBlend == REPLACE_BLEND_COPY_FBO) {
if (!gl_extensions.ANY_shader_framebuffer_fetch && replaceBlend == REPLACE_BLEND_COPY_FBO) {
if (!texelFetch) {
WRITE(p, "uniform vec2 u_fbotexSize;\n");
}
@ -936,7 +950,6 @@ void GenerateFragmentShader(char *buffer) {
case GE_SRCBLEND_DSTALPHA: srcFactor = "ERROR"; break;
case GE_SRCBLEND_INVDSTALPHA: srcFactor = "ERROR"; break;
case GE_SRCBLEND_DOUBLESRCALPHA: srcFactor = "vec3(v.a * 2.0)"; break;
// TODO: Double inverse, or inverse double? Following softgpu for now...
case GE_SRCBLEND_DOUBLEINVSRCALPHA: srcFactor = "vec3(1.0 - v.a * 2.0)"; break;
case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "ERROR"; break;
case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "ERROR"; break;
@ -949,9 +962,8 @@ void GenerateFragmentShader(char *buffer) {
if (replaceBlend == REPLACE_BLEND_COPY_FBO) {
// If we have NV_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch, we skip the blit.
// We can just read the prev value more directly.
// TODO: EXT_shader_framebuffer_fetch on iOS 6, possibly others.
if (gl_extensions.NV_shader_framebuffer_fetch) {
WRITE(p, " lowp vec4 destColor = gl_LastFragData[0];\n");
if (gl_extensions.ANY_shader_framebuffer_fetch) {
WRITE(p, " lowp vec4 destColor = %s;\n", lastFragData);
} else if (!texelFetch) {
WRITE(p, " lowp vec4 destColor = %s(fbotex, gl_FragCoord.xy * u_fbotexSize.xy);\n", texture);
} else {
@ -974,7 +986,6 @@ void GenerateFragmentShader(char *buffer) {
case GE_SRCBLEND_DSTALPHA: srcFactor = "vec3(destColor.a)"; break;
case GE_SRCBLEND_INVDSTALPHA: srcFactor = "vec3(1.0 - destColor.a)"; break;
case GE_SRCBLEND_DOUBLESRCALPHA: srcFactor = "vec3(v.a * 2.0)"; break;
// TODO: Double inverse, or inverse double? Following softgpu for now...
case GE_SRCBLEND_DOUBLEINVSRCALPHA: srcFactor = "vec3(1.0 - v.a * 2.0)"; break;
case GE_SRCBLEND_DOUBLEDSTALPHA: srcFactor = "vec3(destColor.a * 2.0)"; break;
case GE_SRCBLEND_DOUBLEINVDSTALPHA: srcFactor = "vec3(1.0 - destColor.a * 2.0)"; break;

View File

@ -167,7 +167,7 @@ static inline bool blendColorSimilar(const Vec3f &a, const Vec3f &b, float margi
}
bool TransformDrawEngine::ApplyShaderBlending() {
if (gl_extensions.NV_shader_framebuffer_fetch) {
if (gl_extensions.ANY_shader_framebuffer_fetch) {
return true;
}

2
native

@ -1 +1 @@
Subproject commit dd1a40653fc3832f3100591bb3def90b33607711
Subproject commit 656fe78656a99b92cfbd144a148e93e95f5dab04