[Mesa-dev] [PATCH 2/2] llvmpipe: handle NULL color buffer pointers
Brian Paul
brianp at vmware.com
Thu Jan 16 08:19:07 PST 2014
On 01/15/2014 07:11 PM, Roland Scheidegger wrote:
> Looks good overall, just some minor quibbles inline.
>
> Roland
>
> Am 16.01.2014 03:15, schrieb Brian Paul:
>> Fixes regression from 9baa45f78b8ca7d66280e36009b6a685055d7cd6
>> ---
>> src/gallium/drivers/llvmpipe/lp_rast.c | 44 +++++---
>> src/gallium/drivers/llvmpipe/lp_rast_priv.h | 11 +-
>> src/gallium/drivers/llvmpipe/lp_scene.c | 6 +-
>> src/gallium/drivers/llvmpipe/lp_setup.c | 2 +-
>> src/gallium/drivers/llvmpipe/lp_state_fs.c | 152 +++++++++++++++------------
>> 5 files changed, 126 insertions(+), 89 deletions(-)
>>
>> diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
>> index 6feec94..3e25ff0 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_rast.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_rast.c
>> @@ -124,7 +124,8 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
>> unsigned i;
>> union util_color uc;
>>
>> - if (util_format_is_pure_integer(scene->fb.cbufs[0]->format)) {
>> + if (scene->fb.cbufs[0] &&
>> + util_format_is_pure_integer(scene->fb.cbufs[0]->format)) {
> This isn't quite correct, since if the first fb is NULL but the second
> is a pure int you'd end up in the non pure int code path below. Maybe
> would be easier if just iterating over all fbs in the outermost loop and
> doing that decision per fb (this only worked because mixed int/fixed fbs
> weren't allowed, but it should be quite ok deciding that per fb anyway).
OK, I'll put in a loop.
>
>> /*
>> * We expect int/uint clear values here, though some APIs
>> * might disagree (but in any case util_pack_color()
>> @@ -174,20 +175,22 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
>> 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_box(scene->cbufs[i].map,
>> - scene->fb.cbufs[i]->format,
>> - scene->cbufs[i].stride,
>> - scene->cbufs[i].layer_stride,
>> - task->x,
>> - task->y,
>> - 0,
>> - task->width,
>> - task->height,
>> - scene->fb_max_layer + 1,
>> - &uc);
>> + if (scene->fb.cbufs[i]) {
>> + util_pack_color(arg.clear_color.f,
>> + scene->fb.cbufs[i]->format, &uc);
>> +
>> + util_fill_box(scene->cbufs[i].map,
>> + scene->fb.cbufs[i]->format,
>> + scene->cbufs[i].stride,
>> + scene->cbufs[i].layer_stride,
>> + task->x,
>> + task->y,
>> + 0,
>> + task->width,
>> + task->height,
>> + scene->fb_max_layer + 1,
>> + &uc);
>> + }
>> }
>> }
>> }
>> @@ -444,8 +447,15 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
>>
>> /* color buffer */
>> for (i = 0; i < scene->fb.nr_cbufs; i++) {
>> - stride[i] = scene->cbufs[i].stride;
>> - color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer);
>> + if (scene->fb.cbufs[i]) {
>> + stride[i] = scene->cbufs[i].stride;
>> + color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y,
>> + inputs->layer);
>> + }
>> + else {
>> + stride[i] = 0;
>> + color[i] = NULL;
>> + }
>> }
>>
>> /* depth buffer */
>> diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
>> index bc361b6..063a70e 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
>> +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
>> @@ -293,8 +293,15 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
>>
>> /* color buffer */
>> for (i = 0; i < scene->fb.nr_cbufs; i++) {
>> - stride[i] = scene->cbufs[i].stride;
>> - color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer);
>> + if (scene->fb.cbufs[i]) {
>> + stride[i] = scene->cbufs[i].stride;
>> + color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y,
>> + inputs->layer);
>> + }
>> + else {
>> + stride[i] = 0;
>> + color[i] = NULL;
>> + }
>> }
>>
>> if (scene->zsbuf.map) {
>> diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
>> index 0296b79..134ab86 100644
>> --- a/src/gallium/drivers/llvmpipe/lp_scene.c
>> +++ b/src/gallium/drivers/llvmpipe/lp_scene.c
>> @@ -156,6 +156,10 @@ lp_scene_begin_rasterization(struct lp_scene *scene)
>>
>> for (i = 0; i < scene->fb.nr_cbufs; i++) {
>> struct pipe_surface *cbuf = scene->fb.cbufs[i];
>> +
>> + if (!cbuf)
>> + continue;
> I wonder if it would be a good idea to set the stride/map fields to 0
> here just for some extra safety as hopefully they aren't accessed.
> Though at second look it might be guaranteed they really are zero already.
I could add the zero-ing code. I did so elsewhere too just to be safe.
So let's be consistent.
We should also set layer_stride=0 for non-texture resources below that,
just to be safe.
>> +
>> if (llvmpipe_resource_is_texture(cbuf->texture)) {
>> scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture,
>> cbuf->u.tex.level);
>> @@ -521,7 +525,7 @@ void lp_scene_begin_binning( struct lp_scene *scene,
>> */
>> for (i = 0; i < scene->fb.nr_cbufs; i++) {
>> struct pipe_surface *cbuf = scene->fb.cbufs[i];
>> - if (llvmpipe_resource_is_texture(cbuf->texture)) {
>> + if (cbuf && llvmpipe_resource_is_texture(cbuf->texture)) {
>> max_layer = MIN2(max_layer, cbuf->u.tex.last_layer - cbuf->u.tex.first_layer);
> Hmm I think this can't work correctly, it there's any NULL cbuf the else
> clause would be taken hence max_layer would incorrectly be set to zero.
Yeah, that's wrong. But another questions is: if all the cbufs[] happen
to be NULL, then max_layer will be ~0. Is that what we want, or don't
we care?
I'll post v2 in a minute...
-Brian
More information about the mesa-dev
mailing list