Bug 1556763 - Add layout qualifier to fragment shader output for advanced blend. r=kvark

When using an advanced blend equation, fragment shader output must be
marked with a matching layout qualifier. Not doing so was causing
subsequent glDraw* operations to fail.

This patch adds a new shader feature, WR_FEATURE_ADVANCED_BLEND, which
requires the necessary extension and adds the qualifier. Variants of
the brush_image shaders are created with this feature, and are used
whenever a brush_image shader is requested for BlendMode::Advanced.

Differential Revision: https://phabricator.services.mozilla.com/D34617

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jamie Nicol 2019-06-15 11:56:14 +00:00
parent d88f8facc2
commit ce7a78895a
4 changed files with 60 additions and 9 deletions

View File

@ -18,6 +18,10 @@
#extension GL_OES_EGL_image_external_essl3 : require
#endif
#ifdef WR_FEATURE_ADVANCED_BLEND
#extension GL_KHR_blend_equation_advanced : require
#endif
#ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
#ifdef GL_ES
#extension GL_EXT_blend_func_extended : require
@ -107,6 +111,10 @@
#endif
#else
// Fragment shader outputs
#ifdef WR_FEATURE_ADVANCED_BLEND
layout(blend_support_all_equations) out;
#endif
#ifdef WR_FEATURE_DUAL_SOURCE_BLENDING
layout(location = 0, index = 0) out vec4 oFragColor;
layout(location = 0, index = 1) out vec4 oFragBlend;

View File

@ -903,6 +903,8 @@ pub struct Capabilities {
/// is available on some mobile GPUs. This allows fast access to
/// the per-pixel tile memory.
pub supports_pixel_local_storage: bool,
/// Whether advanced blend equations are supported.
pub supports_advanced_blend_equation: bool,
/// Whether KHR_debug is supported for getting debug messages from
/// the driver.
pub supports_khr_debug: bool,
@ -1311,6 +1313,9 @@ impl Device {
ext_framebuffer_fetch &&
ext_pixel_local_storage;
let supports_advanced_blend_equation =
supports_extension(&extensions, "GL_KHR_blend_equation_advanced");
// On Adreno GPUs PBO texture upload is only performed asynchronously
// if the stride of the data in the PBO is a multiple of 256 bytes.
// Other platforms may have similar requirements and should be added
@ -1334,6 +1339,7 @@ impl Device {
supports_copy_image_sub_data,
supports_blit_to_texture_array,
supports_pixel_local_storage,
supports_advanced_blend_equation,
supports_khr_debug,
},

View File

@ -1793,7 +1793,7 @@ impl Renderer {
!device.get_capabilities().supports_pixel_local_storage;
let ext_blend_equation_advanced =
options.allow_advanced_blend_equation &&
device.supports_extension("GL_KHR_blend_equation_advanced");
device.get_capabilities().supports_advanced_blend_equation;
let ext_blend_equation_advanced_coherent =
device.supports_extension("GL_KHR_blend_equation_advanced_coherent");

View File

@ -47,6 +47,7 @@ pub const IMAGE_BUFFER_KINDS: [ImageBufferKind; 4] = [
ImageBufferKind::Texture2DArray,
];
const ADVANCED_BLEND_FEATURE: &str = "ADVANCED_BLEND";
const ALPHA_FEATURE: &str = "ALPHA_PASS";
const DEBUG_OVERDRAW_FEATURE: &str = "DEBUG_OVERDRAW";
const DITHERING_FEATURE: &str = "DITHERING";
@ -258,6 +259,7 @@ impl LazilyCompiledShader {
struct BrushShader {
opaque: LazilyCompiledShader,
alpha: LazilyCompiledShader,
advanced_blend: Option<LazilyCompiledShader>,
dual_source: Option<LazilyCompiledShader>,
debug_overdraw: LazilyCompiledShader,
}
@ -268,6 +270,7 @@ impl BrushShader {
device: &mut Device,
features: &[&'static str],
precache_flags: ShaderPrecacheFlags,
advanced_blend: bool,
dual_source: bool,
use_pixel_local_storage: bool,
) -> Result<Self, ShaderError> {
@ -293,6 +296,25 @@ impl BrushShader {
precache_flags,
)?;
let advanced_blend = if advanced_blend &&
device.get_capabilities().supports_advanced_blend_equation
{
let mut advanced_blend_features = alpha_features.to_vec();
advanced_blend_features.push(ADVANCED_BLEND_FEATURE);
let shader = LazilyCompiledShader::new(
ShaderKind::Brush,
name,
&advanced_blend_features,
device,
precache_flags,
)?;
Some(shader)
} else {
None
};
// If using PLS, we disable all subpixel AA implicitly. Subpixel AA is always
// disabled on mobile devices anyway, due to uncertainty over the subpixel
// layout configuration.
@ -327,6 +349,7 @@ impl BrushShader {
Ok(BrushShader {
opaque,
alpha,
advanced_blend,
dual_source,
debug_overdraw,
})
@ -341,8 +364,12 @@ impl BrushShader {
BlendMode::PremultipliedAlpha |
BlendMode::PremultipliedDestOut |
BlendMode::SubpixelConstantTextColor(..) |
BlendMode::SubpixelWithBgColor |
BlendMode::Advanced(_) => &mut self.alpha,
BlendMode::SubpixelWithBgColor => &mut self.alpha,
BlendMode::Advanced(_) => {
self.advanced_blend
.as_mut()
.expect("bug: no advanced blend shader loaded")
}
BlendMode::SubpixelDualSource => {
self.dual_source
.as_mut()
@ -354,6 +381,9 @@ impl BrushShader {
fn deinit(self, device: &mut Device) {
self.opaque.deinit(device);
self.alpha.deinit(device);
if let Some(advanced_blend) = self.advanced_blend {
advanced_blend.deinit(device);
}
if let Some(dual_source) = self.dual_source {
dual_source.deinit(device);
}
@ -534,7 +564,8 @@ impl Shaders {
device,
&[],
options.precache_flags,
false,
false /* advanced blend */,
false /* dual source */,
use_pixel_local_storage,
)?;
@ -543,7 +574,8 @@ impl Shaders {
device,
&[],
options.precache_flags,
false,
false /* advanced blend */,
false /* dual source */,
use_pixel_local_storage,
)?;
@ -552,7 +584,8 @@ impl Shaders {
device,
&[],
options.precache_flags,
false,
false /* advanced blend */,
false /* dual source */,
use_pixel_local_storage,
)?;
@ -565,7 +598,8 @@ impl Shaders {
&[]
},
options.precache_flags,
false,
false /* advanced blend */,
false /* dual source */,
use_pixel_local_storage,
)?;
@ -578,7 +612,8 @@ impl Shaders {
&[]
},
options.precache_flags,
false,
false /* advanced blend */,
false /* dual source */,
use_pixel_local_storage,
)?;
@ -720,6 +755,7 @@ impl Shaders {
device,
&image_features,
options.precache_flags,
options.allow_advanced_blend_equation,
options.allow_dual_source_blending,
use_pixel_local_storage,
)?);
@ -747,7 +783,8 @@ impl Shaders {
device,
&yuv_features,
options.precache_flags,
false,
false /* advanced blend */,
false /* dual source */,
use_pixel_local_storage,
)?;
let index = Self::get_yuv_shader_index(