diff options
author | Ilia Mirkin <[email protected]> | 2015-11-22 14:03:29 -0500 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2015-11-23 11:17:15 -0500 |
commit | 81b16350fa2e7c1b47d976be12d2313283f22e24 (patch) | |
tree | 785e69c2c3a2258c6f2e790e4afe74f4feae3f90 /src/gallium/drivers/freedreno/a4xx/fd4_emit.c | |
parent | 6f17f19b17d6150788e713f92f6a05ef410c4060 (diff) |
freedreno/a4xx: use a factor of 32767 for snorm8 blending
It appears that the hardware wants the integer to be scaled the same way
that the hardware representation is. snorm16 uses one of the float
factors, so this is only relevant for snorm8.
This fixes a number of subcases of
bin/fbo-blending-formats GL_EXT_texture_snorm
Signed-off-by: Ilia Mirkin <[email protected]>
Cc: [email protected]
Diffstat (limited to 'src/gallium/drivers/freedreno/a4xx/fd4_emit.c')
-rw-r--r-- | src/gallium/drivers/freedreno/a4xx/fd4_emit.c | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 0e4a8cad8c7..69f263e3ba8 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -662,19 +662,48 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, A4XX_RB_FS_OUTPUT_SAMPLE_MASK(0xffff)); } - if (dirty & FD_DIRTY_BLEND_COLOR) { + if (dirty & (FD_DIRTY_BLEND_COLOR | FD_DIRTY_FRAMEBUFFER)) { struct pipe_blend_color *bcolor = &ctx->blend_color; + struct pipe_framebuffer_state *pfb = &ctx->framebuffer; + float factor = 65535.0; + int i; + + for (i = 0; i < pfb->nr_cbufs; i++) { + enum pipe_format format = pipe_surface_format(pfb->cbufs[i]); + const struct util_format_description *desc = + util_format_description(format); + int j; + + if (desc->is_mixed) + continue; + + j = util_format_get_first_non_void_channel(format); + if (j == -1) + continue; + + if (desc->channel[j].size > 8 || !desc->channel[j].normalized || + desc->channel[j].pure_integer) + continue; + + /* Just use the first unorm8/snorm8 render buffer. Can't keep + * everyone happy. + */ + if (desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED) + factor = 32767.0; + break; + } + OUT_PKT0(ring, REG_A4XX_RB_BLEND_RED, 8); - OUT_RING(ring, A4XX_RB_BLEND_RED_UINT(bcolor->color[0] * 65535.0) | + OUT_RING(ring, A4XX_RB_BLEND_RED_UINT(bcolor->color[0] * factor) | A4XX_RB_BLEND_RED_FLOAT(bcolor->color[0])); OUT_RING(ring, A4XX_RB_BLEND_RED_F32(bcolor->color[0])); - OUT_RING(ring, A4XX_RB_BLEND_GREEN_UINT(bcolor->color[1] * 65535.0) | + OUT_RING(ring, A4XX_RB_BLEND_GREEN_UINT(bcolor->color[1] * factor) | A4XX_RB_BLEND_GREEN_FLOAT(bcolor->color[1])); OUT_RING(ring, A4XX_RB_BLEND_GREEN_F32(bcolor->color[1])); - OUT_RING(ring, A4XX_RB_BLEND_BLUE_UINT(bcolor->color[2] * 65535.0) | + OUT_RING(ring, A4XX_RB_BLEND_BLUE_UINT(bcolor->color[2] * factor) | A4XX_RB_BLEND_BLUE_FLOAT(bcolor->color[2])); OUT_RING(ring, A4XX_RB_BLEND_BLUE_F32(bcolor->color[2])); - OUT_RING(ring, A4XX_RB_BLEND_ALPHA_UINT(bcolor->color[3] * 65535.0) | + OUT_RING(ring, A4XX_RB_BLEND_ALPHA_UINT(bcolor->color[3] * factor) | A4XX_RB_BLEND_ALPHA_FLOAT(bcolor->color[3])); OUT_RING(ring, A4XX_RB_BLEND_ALPHA_F32(bcolor->color[3])); } |