[Mesa-dev] [PATCH 1/2] i965: Fix reference counting in new basevertex upload code.

Ian Romanick idr at freedesktop.org
Fri Sep 12 14:01:55 PDT 2014


On 09/12/2014 09:05 AM, Kenneth Graunke wrote:
> On Friday, September 12, 2014 08:35:03 AM Ian Romanick wrote:
>> On 09/10/2014 03:41 PM, Kenneth Graunke wrote:
>>> In the non-indirect draw case, we call intel_upload_data to upload
>>> gl_BaseVertex.  It makes brw->draw.draw_params_bo point to the upload
>>> buffer, and increments the upload BO reference count.
>>>
>>> So, we need to unreference it when making brw->draw.draw_params_bo point
>>> at something else, or else we'll retain a reference to stale upload
>>> buffers and hold on to them forever.
>>>
>>> This also means that the indirect case should increment the reference
>>> count on the indirect draw buffer when making brw->draw.draw_params_bo
>>> point at it.  That way, both paths increment the reference count, so
>>> we can safely unreference it every time.
>>>
>>> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
>>> Cc: "10.3" <mesa-stable at lists.freedesktop.org>
>>> ---
>>>  src/mesa/drivers/dri/i965/brw_draw.c | 3 +++
>>>  1 file changed, 3 insertions(+)
>>>
>>> diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
>>> index efa85de..b28eaf2 100644
>>> --- a/src/mesa/drivers/dri/i965/brw_draw.c
>>> +++ b/src/mesa/drivers/dri/i965/brw_draw.c
>>> @@ -434,10 +434,13 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
>>>        brw->draw.start_vertex_location = prims[i].start;
>>>        brw->draw.base_vertex_location = prims[i].basevertex;
>>>  
>>> +      drm_intel_bo_unreference(brw->draw.draw_params_bo);
>>> +
>>>        if (prims[i].is_indirect) {
>>>           /* Point draw_params_bo at the indirect buffer. */
>>>           brw->draw.draw_params_bo =
>>>              intel_buffer_object(ctx->DrawIndirectBuffer)->buffer;
>>> +         drm_intel_bo_reference(brw->draw.draw_params_bo);
>>
>> Is there are a race here, or do we know that the reference count is at
>> least two when we unreference above?
> 
> The idea is to unreference the buffer used for the previous draw call - which may be either a DrawIndirect buffer, or the upload buffer.  Then, we'll decide what buffer we want for the current draw call.
> 
> For background:
> 
> Legitimate GL-facing buffers hold a reference count until DeleteBuffer.
> brw->upload.bo holds a reference count on the upload buffer until batch flush, at which point we toss it and get a new (non-busy) upload buffer.
> 
> I think it works out in all cases.  Here's my logic:
> 
> Case: Non-indirect -> Non-indirect
> 
> If we haven't flushed the batch buffer, then brw->upload.bo still holds a
> reference to the upload buffer.  We drop our reference, then pick it back up.
> 
> If we've flushed the batch buffer, then brw->upload.bo will have been released,
> and will now point to a fresh buffer.  We may hold the last reference on the
> old upload buffer - but releasing it is okay, because we don't want it anymore.
> 
> We drop our reference to the old buffer, and take a reference on the new one.
> 
> Case: Indirect -> Indirect
> 
> The application may have switched out the indirect buffer between calls.
> 
> If not, it's still bound as ctx->DrawIndirectBuffer, which holds a gl_buffer_object::RefCount on the gl_buffer_object, keeping it alive.  So we can drop our reference and re-take it.
> 
> If they did, we drop our reference on the old one.  This could allow it to be
> freed, if the API-facing buffer was deleted.  But we don't care.  We take a
> reference to the new ctx->DrawIndirectBuffer's BO, which definitely exists.
> 
> Case: Non-indirect -> Indirect
> 
> We stop referencing the upload BO, and instead reference DrawIndirectBuffer.
> The upload BO will live or die based on other people holding refcounts,
> which is the desired behavior.
> 
> Case: Indirect -> Non-indirect
> 
> We stop referencing the BO which was bound as ctx->DrawIndirectBuffer when
> we prepared the previous draw call.  It will probably live, unless the API-
> facing buffer object was deleted and this was the last use...and that's okay.
> 
> We take a reference on the upload buffer, which is referenced by brw->upload.bo.

Okay.  That's convincing enough. :)

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>



-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140912/f5abd7cd/attachment.sig>


More information about the mesa-dev mailing list