diff options
author | Roland Scheidegger <[email protected]> | 2013-01-10 18:10:20 -0800 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2013-01-10 18:10:20 -0800 |
commit | babab2876080af0fe65249dff559244aebd0b87e (patch) | |
tree | f4d44a31ed1a35ba76001c57695947985daa9f1e /src/gallium/drivers/llvmpipe/lp_rast.c | |
parent | 5785f22d230bc7249dfcd91bbbaa4e77816128e4 (diff) |
llvmpipe: fix clearing integer color buffers
We get int/uint clear color value in this case, and util_pack_color can't
handle these formats at all (even if it could, float input color isn't what
we want).
Pass through the color union appropriately and handle the packing ourselves
(as I couldn't think of a good generic util solution).
This gets piglit fbo_integer_precision_clear and
fbo_integer_readpixels_sint_uint from the ext_texture_integer test group from
segfault to pass (which only leaves fbo-blending from that group not working).
v2: fix up comments
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_rast.c')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_rast.c | 104 |
1 files changed, 80 insertions, 24 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 44e8324b2b1..2daf2fefa26 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -146,35 +146,91 @@ lp_rast_clear_color(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { const struct lp_scene *scene = task->scene; - uint8_t clear_color[4]; - unsigned i; + if (scene->fb.nr_cbufs) { + unsigned i; + union util_color uc; - for (i = 0; i < 4; ++i) { - clear_color[i] = float_to_ubyte(arg.clear_color[i]); - } + if (util_format_is_pure_integer(scene->fb.cbufs[0]->format)) { + /* + * We expect int/uint clear values here, though some APIs + * might disagree (but in any case util_pack_color() + * couldn't handle it)... + */ + LP_DBG(DEBUG_RAST, "%s pure int 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, + arg.clear_color.ui[0], + arg.clear_color.ui[1], + arg.clear_color.ui[2], + arg.clear_color.ui[3]); + + for (i = 0; i < scene->fb.nr_cbufs; i++) { + enum pipe_format format = scene->fb.cbufs[i]->format; + /* + * XXX the format_write_4i/ui functions do clamping to max value + * and I'm not sure that's actually right - spec doesn't seem to + * say much about that topic. If it is should probably adjust the + * border color handling to do the same. If not and chopping off + * bits is the way to go, the write_4i and write_4ui functions + * would be identical. + */ + if (util_format_is_pure_sint(format)) { + int rgba[4]; + rgba[0] = arg.clear_color.i[0]; + rgba[1] = arg.clear_color.i[1]; + rgba[2] = arg.clear_color.i[2]; + rgba[3] = arg.clear_color.i[3]; + + util_format_write_4i(format, rgba, 0, &uc, 0, 0, 0, 1, 1); + } + else { + unsigned rgba[4]; + rgba[0] = arg.clear_color.ui[0]; + rgba[1] = arg.clear_color.ui[1]; + rgba[2] = arg.clear_color.ui[2]; + rgba[3] = arg.clear_color.ui[3]; + + assert(util_format_is_pure_uint(format)); + util_format_write_4ui(format, rgba, 0, &uc, 0, 0, 0, 1, 1); + } - LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, - clear_color[0], - clear_color[1], - clear_color[2], - clear_color[3]); + util_fill_rect(scene->cbufs[i].map, + scene->fb.cbufs[i]->format, + scene->cbufs[i].stride, + task->x, + task->y, + TILE_SIZE, + TILE_SIZE, + &uc); + } + } + else { + uint8_t clear_color[4]; - for (i = 0; i < scene->fb.nr_cbufs; i++) { - const struct lp_scene *scene = task->scene; - union util_color uc; + for (i = 0; i < 4; ++i) { + clear_color[i] = float_to_ubyte(arg.clear_color.f[i]); + } - util_pack_color(arg.clear_color, - scene->fb.cbufs[i]->format, &uc); - - util_fill_rect(scene->cbufs[i].map, - scene->fb.cbufs[i]->format, - scene->cbufs[i].stride, - task->x, - task->y, - TILE_SIZE, - TILE_SIZE, - &uc); + LP_DBG(DEBUG_RAST, "%s 0x%x,0x%x,0x%x,0x%x\n", __FUNCTION__, + clear_color[0], + clear_color[1], + clear_color[2], + clear_color[3]); + + for (i = 0; i < scene->fb.nr_cbufs; i++) { + + util_pack_color(arg.clear_color.f, + scene->fb.cbufs[i]->format, &uc); + + util_fill_rect(scene->cbufs[i].map, + scene->fb.cbufs[i]->format, + scene->cbufs[i].stride, + task->x, + task->y, + TILE_SIZE, + TILE_SIZE, + &uc); + } + } } LP_COUNT(nr_color_tile_clear); |