[Mesa-dev] [RFC] gallium/u_blitter: support blitting PIPE_BUFFERs

Roland Scheidegger sroland at vmware.com
Wed Nov 22 17:36:07 UTC 2017


Am 22.11.2017 um 16:56 schrieb Rob Clark:
> So, I could potentially do this for a5xx, which actually has a sort of
> blit engine.  But for earlier gen's, everything is a glDraw(), and I
> don't want to duplicate the functionality of u_blitter.
> 
> I suppose I could bypass util_blitter_blit() and use
> util_blitter_blit_generic() directly..

I still don't really see the need for such gross hacks.
gallium fully supports rendering to buffers (most drivers don't,
llvmpipe does), and texturing from them. Therefore, I think you could
just use a proper buffer sampler view template (using the offset/size
fields instead of level/layer). Likewise, don't use the level/layer
fields for surface views, but the first_element/last_element fields
(looks like right now you're actually relying on the blit code using the
wrong fields for buffers...).
You just need to handle sampling from buffers and rendering to buffers
properly in your driver, and make sure the blitter code handles the
restrictions appropriately (e.g. must use txf, not ordinary texture
lookups).

Albeit in any case you're still restricted to tiny buffers - while the
first_element in surface views can give you access to large buffers (no
idea if your hw could comply with that...) you're still restricted to
16k or so (whatever your viewport limits are) wrt actually writing in
one shot. (Technically, you could get 16 times more than that limit
since buffers are compatible to any format, so you can use rgba32ui, but
then your offsets and sizes need to be aligned, and you can't
communicate the format to the blitter code.)
If you want to support large buffers, you probably need to wrap them in
a fake (untiled) 2d resource.

Roland


> BR,
> -R
> 
> On Wed, Nov 22, 2017 at 10:14 AM, Roland Scheidegger <sroland at vmware.com> wrote:
>> I don't think this is a good idea.
>> 1D and buffer resources are fundamentally incompatible, it is highly
>> illegal to use targets in views which are incompatible, so I'd rather
>> not see such atrocities in shared code.
>> I think you really want to fix up your resource_copy_region
>> implementation one way or another so it can do gpu copies for buffers.
>>
>> Roland
>>
>> Am 22.11.2017 um 15:43 schrieb Rob Clark:
>>> It is useful for staging/shadow transfers for drivers to be able to blit
>>> BUFFERs.  Treat them as R8 1D textures for this purpose.
>>>
>>> Signed-off-by: Rob Clark <robdclark at gmail.com>
>>> ---
>>> This works at least if 1D textures are linear, so I suppose might not
>>> work for all drivers.  Although I'm not entirely sure what the point
>>> of a tiled 1D texture is.  And I guess drivers for which this wouldn't
>>> work could continue to just not use u_blitter for BUFFERs.
>>>
>>>  src/gallium/auxiliary/util/u_blitter.c | 12 ++++++++++--
>>>  1 file changed, 10 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
>>> index 476ef08737e..7ba7b5aa57d 100644
>>> --- a/src/gallium/auxiliary/util/u_blitter.c
>>> +++ b/src/gallium/auxiliary/util/u_blitter.c
>>> @@ -1445,7 +1445,10 @@ void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
>>>                                        unsigned dstz)
>>>  {
>>>     memset(dst_templ, 0, sizeof(*dst_templ));
>>> -   dst_templ->format = util_format_linear(dst->format);
>>> +   if (dst->target == PIPE_BUFFER)
>>> +      dst_templ->format = PIPE_FORMAT_R8_UINT;
>>> +   else
>>> +      dst_templ->format = util_format_linear(dst->format);
>>>     dst_templ->u.tex.level = dstlevel;
>>>     dst_templ->u.tex.first_layer = dstz;
>>>     dst_templ->u.tex.last_layer = dstz;
>>> @@ -1482,7 +1485,12 @@ void util_blitter_default_src_texture(struct blitter_context *blitter,
>>>     else
>>>        src_templ->target = src->target;
>>>
>>> -   src_templ->format = util_format_linear(src->format);
>>> +   if (src->target  == PIPE_BUFFER) {
>>> +      src_templ->target = PIPE_TEXTURE_1D;
>>> +      src_templ->format = PIPE_FORMAT_R8_UINT;
>>> +   } else {
>>> +      src_templ->format = util_format_linear(src->format);
>>> +   }
>>>     src_templ->u.tex.first_level = srclevel;
>>>     src_templ->u.tex.last_level = srclevel;
>>>     src_templ->u.tex.first_layer = 0;
>>>
>>



More information about the mesa-dev mailing list