summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2009-12-21 01:38:45 +0100
committerCorbin Simpson <[email protected]>2010-01-06 12:49:15 -0800
commit7c902b43d84f5508764e64d95f7359897a1aad0a (patch)
treef1e765c570f7c4ae2f7f9cb60c08eb17fbcb68ae
parent6b9b3213c545644d155be54fd633e8b630a22465 (diff)
r300g: optimize blending by conditionally disabling reads from the colorbuffer
-rw-r--r--src/gallium/drivers/r300/r300_reg.h2
-rw-r--r--src/gallium/drivers/r300/r300_state.c31
2 files changed, 30 insertions, 3 deletions
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 0aa1da07f8b..034bfc15cf9 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -2186,6 +2186,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_1 (4 << 3)
# define R300_DISCARD_SRC_PIXELS_SRC_COLOR_1 (5 << 3)
# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_1 (6 << 3)
+# define R500_SRC_ALPHA_0_NO_READ (1 << 30)
+# define R500_SRC_ALPHA_1_NO_READ (1 << 31)
/* the following are shared between CBLEND and ABLEND */
# define R300_FCN_MASK (3 << 12)
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index f8cce112ee6..872a393321d 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -198,9 +198,36 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
srcA == PIPE_BLENDFACTOR_DST_ALPHA ||
srcA == PIPE_BLENDFACTOR_INV_DST_COLOR ||
srcA == PIPE_BLENDFACTOR_INV_DST_ALPHA ||
- srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
+ srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE) {
+ /* Enable reading from the colorbuffer. */
blend->blend_control |= R300_READ_ENABLE;
+ if (r300_screen(r300_context(pipe)->context.screen)->caps->is_r500) {
+ /* Optimization: Depending on incoming pixels, we can
+ * conditionally disable the reading in hardware... */
+ if (eqRGB != PIPE_BLEND_MIN && eqA != PIPE_BLEND_MIN &&
+ eqRGB != PIPE_BLEND_MAX && eqA != PIPE_BLEND_MAX) {
+ /* Disable reading if SRC_ALPHA == 0. */
+ if ((dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
+ dstRGB == PIPE_BLENDFACTOR_ZERO) &&
+ (dstA == PIPE_BLENDFACTOR_SRC_COLOR ||
+ dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||
+ dstA == PIPE_BLENDFACTOR_ZERO)) {
+ blend->blend_control |= R500_SRC_ALPHA_0_NO_READ;
+ }
+
+ /* Disable reading if SRC_ALPHA == 1. */
+ if ((dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+ dstRGB == PIPE_BLENDFACTOR_ZERO) &&
+ (dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+ dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+ dstA == PIPE_BLENDFACTOR_ZERO)) {
+ blend->blend_control |= R500_SRC_ALPHA_1_NO_READ;
+ }
+ }
+ }
+ }
+
/* Optimization: discard pixels which don't change the colorbuffer.
*
* The code below is non-trivial and some math is involved.
@@ -246,8 +273,6 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
}
}
- /* XXX implement the optimization with SRC_ALPHA_?_NO_READ */
-
/* separate alpha */
if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
blend->blend_control |= R300_SEPARATE_ALPHA_ENABLE;