summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2013-01-10 18:10:20 -0800
committerRoland Scheidegger <[email protected]>2013-01-10 18:10:20 -0800
commitbabab2876080af0fe65249dff559244aebd0b87e (patch)
treef4d44a31ed1a35ba76001c57695947985daa9f1e /src/gallium/drivers/llvmpipe
parent5785f22d230bc7249dfcd91bbbaa4e77816128e4 (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')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_clear.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c104
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h2
5 files changed, 87 insertions, 31 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c
index cc90dc42c65..b00910a4711 100644
--- a/src/gallium/drivers/llvmpipe/lp_clear.c
+++ b/src/gallium/drivers/llvmpipe/lp_clear.c
@@ -59,5 +59,5 @@ llvmpipe_clear(struct pipe_context *pipe,
if (LP_PERF & PERF_NO_DEPTH)
buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
- lp_setup_clear( llvmpipe->setup, color->f, depth, stencil, buffers );
+ lp_setup_clear( llvmpipe->setup, color, depth, stencil, buffers );
}
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);
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 315601e1b6a..2f5fa227619 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -152,7 +152,7 @@ union lp_rast_cmd_arg {
unsigned plane_mask;
} triangle;
const struct lp_rast_state *set_state;
- float clear_color[4];
+ union pipe_color_union clear_color;
struct {
uint32_t value;
uint32_t mask;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 5aba7a25342..ffa0fe6eaa3 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -385,7 +385,7 @@ lp_setup_bind_framebuffer( struct lp_setup_context *setup,
static boolean
lp_setup_try_clear( struct lp_setup_context *setup,
- const float *color,
+ const union pipe_color_union *color,
double depth,
unsigned stencil,
unsigned flags )
@@ -399,7 +399,7 @@ lp_setup_try_clear( struct lp_setup_context *setup,
if (flags & PIPE_CLEAR_COLOR) {
for (i = 0; i < 4; i++)
- color_arg.clear_color[i] = color[i];
+ color_arg.clear_color.i[i] = color->i[i];
}
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
@@ -458,7 +458,7 @@ lp_setup_try_clear( struct lp_setup_context *setup,
}
if (flags & PIPE_CLEAR_COLOR) {
- memcpy(setup->clear.color.clear_color,
+ memcpy(&setup->clear.color.clear_color,
&color_arg,
sizeof setup->clear.color.clear_color);
}
@@ -469,7 +469,7 @@ lp_setup_try_clear( struct lp_setup_context *setup,
void
lp_setup_clear( struct lp_setup_context *setup,
- const float *color,
+ const union pipe_color_union *color,
double depth,
unsigned stencil,
unsigned flags )
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 55b710dd2b4..de29601329f 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -55,7 +55,7 @@ lp_setup_create( struct pipe_context *pipe,
void
lp_setup_clear(struct lp_setup_context *setup,
- const float *clear_color,
+ const union pipe_color_union *clear_color,
double clear_depth,
unsigned clear_stencil,
unsigned flags);