[Mesa-dev] [PATCH 2/5] radeonsi: fix error paths of si_texture_transfer_map

Timothy Arceri tarceri at itsqueeze.com
Tue Apr 24 00:01:22 UTC 2018



On 20/04/18 17:19, Nicolai Hähnle wrote:
> On 12.04.2018 02:10, Timothy Arceri wrote:
>>
>>
>> On 11/04/18 20:56, Nicolai Hähnle wrote:
>>> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>>>
>>> trans is zero-initialized, but trans->resource is setup immediately so
>>> needs to be dereferenced.
>>> ---
>>>   src/gallium/drivers/radeonsi/si_texture.c | 25 
>>> ++++++++++++-------------
>>>   1 file changed, 12 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/src/gallium/drivers/radeonsi/si_texture.c 
>>> b/src/gallium/drivers/radeonsi/si_texture.c
>>> index 0bab2a6c45b..907e8c8cec9 100644
>>> --- a/src/gallium/drivers/radeonsi/si_texture.c
>>> +++ b/src/gallium/drivers/radeonsi/si_texture.c
>>> @@ -1728,49 +1728,46 @@ static void *si_texture_transfer_map(struct 
>>> pipe_context *ctx,
>>>                * then decompress the temporary one to staging.
>>>                *
>>>                * Only the region being mapped is transfered.
>>>                */
>>>               struct pipe_resource resource;
>>>               si_init_temp_resource_from_box(&resource, texture, box, 
>>> level, 0);
>>>               if (!si_init_flushed_depth_texture(ctx, &resource, 
>>> &staging_depth)) {
>>>                   PRINT_ERR("failed to create temporary texture to 
>>> hold untiled copy\n");
>>> -                FREE(trans);
>>> -                return NULL;
>>> +                goto fail_trans;
>>>               }
>>>               if (usage & PIPE_TRANSFER_READ) {
>>>                   struct pipe_resource *temp = 
>>> ctx->screen->resource_create(ctx->screen, &resource);
>>>                   if (!temp) {
>>>                       PRINT_ERR("failed to create a temporary depth 
>>> texture\n");
>>> -                    FREE(trans);
>>> -                    return NULL;
>>> +                    goto fail_trans;
>>>                   }
>>>                   si_copy_region_with_blit(ctx, temp, 0, 0, 0, 0, 
>>> texture, level, box);
>>>                   si_blit_decompress_depth(ctx, (struct 
>>> r600_texture*)temp, staging_depth,
>>>                                0, 0, 0, box->depth, 0, 0);
>>>                   pipe_resource_reference(&temp, NULL);
>>>               }
>>>               /* Just get the strides. */
>>>               si_texture_get_offset(sctx->screen, staging_depth, 
>>> level, NULL,
>>>                           &trans->b.b.stride,
>>>                           &trans->b.b.layer_stride);
>>>           } else {
>>>               /* XXX: only readback the rectangle which is being 
>>> mapped? */
>>>               /* XXX: when discard is true, no need to read back from 
>>> depth texture */
>>>               if (!si_init_flushed_depth_texture(ctx, texture, 
>>> &staging_depth)) {
>>>                   PRINT_ERR("failed to create temporary texture to 
>>> hold untiled copy\n");
>>> -                FREE(trans);
>>> -                return NULL;
>>> +                goto fail_trans;
>>>               }
>>>               si_blit_decompress_depth(ctx, rtex, staging_depth,
>>>                            level, level,
>>>                            box->z, box->z + box->depth - 1,
>>>                            0, 0);
>>>               offset = si_texture_get_offset(sctx->screen, 
>>> staging_depth,
>>>                                level, box,
>>>                                &trans->b.b.stride,
>>> @@ -1785,22 +1782,21 @@ static void *si_texture_transfer_map(struct 
>>> pipe_context *ctx,
>>>           si_init_temp_resource_from_box(&resource, texture, box, level,
>>>                            SI_RESOURCE_FLAG_TRANSFER);
>>>           resource.usage = (usage & PIPE_TRANSFER_READ) ?
>>>               PIPE_USAGE_STAGING : PIPE_USAGE_STREAM;
>>>           /* Create the temporary texture. */
>>>           staging = (struct 
>>> r600_texture*)ctx->screen->resource_create(ctx->screen, &resource);
>>>           if (!staging) {
>>>               PRINT_ERR("failed to create temporary texture to hold 
>>> untiled copy\n");
>>> -            FREE(trans);
>>> -            return NULL;
>>> +            goto fail_trans;
>>>           }
>>>           trans->staging = &staging->resource;
>>>           /* Just get the strides. */
>>>           si_texture_get_offset(sctx->screen, staging, 0, NULL,
>>>                       &trans->b.b.stride,
>>>                       &trans->b.b.layer_stride);
>>>           if (usage & PIPE_TRANSFER_READ)
>>>               si_copy_to_staging_texture(ctx, trans);
>>> @@ -1809,28 +1805,31 @@ static void *si_texture_transfer_map(struct 
>>> pipe_context *ctx,
>>>           buf = trans->staging;
>>>       } else {
>>>           /* the resource is mapped directly */
>>>           offset = si_texture_get_offset(sctx->screen, rtex, level, box,
>>>                            &trans->b.b.stride,
>>>                            &trans->b.b.layer_stride);
>>>           buf = &rtex->resource;
>>>       }
>>> -    if (!(map = si_buffer_map_sync_with_rings(sctx, buf, usage))) {
>>> -        r600_resource_reference(&trans->staging, NULL);
>>> -        FREE(trans);
>>> -        return NULL;
>>> -    }
>>> +    if (!(map = si_buffer_map_sync_with_rings(sctx, buf, usage)))
>>> +        goto fail_trans;
>>>       *ptransfer = &trans->b.b;
>>>       return map + offset;
>>> +
>>> +fail_trans:
>>> +    r600_resource_reference(&trans->staging, NULL);
>>
>> this needs to be:
>>
>> if (trans->staging)
>>     r600_resource_reference(&trans->staging, NULL);
> 
> No, that's really not necessary. Only &trans->staging needs to be 
> non-NULL. r600_resource_reference is basically an assignment with 
> reference counting, both the old and the new value can be NULL 
> simultaneously, see pipe_reference_described.

Yeah ignore the comment. I seem to have confused myself when I was 
reviewing this, on second look it seems fine.

> 
> Cheers,
> Nicolai
> 
>>
>> Otherwise:
>>
>> Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>
>>
>>> +    pipe_resource_reference(&trans->b.b.resource, NULL);
>>> +    FREE(trans);
>>> +    return NULL;
>>>   }
>>>   static void si_texture_transfer_unmap(struct pipe_context *ctx,
>>>                         struct pipe_transfer* transfer)
>>>   {
>>>       struct si_context *sctx = (struct si_context*)ctx;
>>>       struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
>>>       struct pipe_resource *texture = transfer->resource;
>>>       struct r600_texture *rtex = (struct r600_texture*)texture;
>>>
> 
> 


More information about the mesa-dev mailing list