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
This commit is contained in:
parent
5785f22d23
commit
babab28760
|
@ -329,6 +329,8 @@ util_unpack_color_ub(enum pipe_format format, union util_color *uc,
|
|||
|
||||
/**
|
||||
* Note rgba outside [0,1] will be clamped for int pixel formats.
|
||||
* This will not work (and might not really be useful with float input)
|
||||
* for pure integer formats (which lack the pack_rgba_float function).
|
||||
*/
|
||||
static INLINE void
|
||||
util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc)
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
clear_color[i] = float_to_ubyte(arg.clear_color[i]);
|
||||
}
|
||||
|
||||
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++) {
|
||||
const struct lp_scene *scene = task->scene;
|
||||
if (scene->fb.nr_cbufs) {
|
||||
unsigned i;
|
||||
union util_color uc;
|
||||
|
||||
util_pack_color(arg.clear_color,
|
||||
scene->fb.cbufs[i]->format, &uc);
|
||||
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]);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
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 < 4; ++i) {
|
||||
clear_color[i] = float_to_ubyte(arg.clear_color.f[i]);
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue