glsl: Add a lowering pass to handle advanced blending modes.
authorKenneth Graunke <kenneth@whitecape.org>
Mon, 27 Jun 2016 18:32:16 +0000 (11:32 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Fri, 26 Aug 2016 02:22:10 +0000 (19:22 -0700)
commit8ab50f5dd14fb720316e65d9553e7cad5c50bf87
tree483403faaff53b705dcff9a5861460675783a9f6
parente299661166a77c3cfc8a59c874bdb1e2179aa160
glsl: Add a lowering pass to handle advanced blending modes.

Many GPUs cannot handle GL_KHR_blend_equation_advanced natively, and
need to emulate it in the pixel shader.  This lowering pass implements
all the necessary math for advanced blending.  It fetches the existing
framebuffer value using the MESA_shader_framebuffer_fetch built-in
variables, and the previous commit's state var uniform to select
which equation to use.

This is done at the GLSL IR level to make it easy for all drivers to
implement the GL_KHR_blend_equation_advanced extension and share code.

Drivers need to hook up MESA_shader_framebuffer_fetch functionality:
1. Hook up the fb_fetch_output variable
2. Implement BlendBarrier()

Then to get KHR_blend_equation_advanced, they simply need to:
3. Disable hardware blending based on ctx->Color._AdvancedBlendEnabled
4. Call this lowering pass.

Very little driver specific code should be required.

v2: Handle multiple output variables per render target (which may exist
    due to ARB_enhanced_layouts), and array variables (even with one
    render target, we might have out vec4 color[1]), and non-vec4
    variables (it's easier than finding spec text to justify not
    handling it).  Thanks to Francisco Jerez for the feedback.
v3: Lower main returns so that we have a single exit point where we
    can add our blending epilogue (caught by Francisco Jerez).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
src/compiler/Makefile.sources
src/compiler/glsl/ir_optimization.h
src/compiler/glsl/lower_blend_equation_advanced.cpp [new file with mode: 0644]