[Mesa-dev] [PATCH v2 4/5] gallium: Make a helper for doing Z32_FLOAT_S8X24_UINT mappings.

Nicolai Hähnle nhaehnle at gmail.com
Thu Nov 30 14:53:34 UTC 2017


On 28.11.2017 15:01, Rob Clark wrote:
> On Tue, Nov 21, 2017 at 4:13 PM, Eric Anholt <eric at anholt.net> wrote:
>> v2: Remove the callback, leave avoiding the recursion up to the caller
>>      (probably by rewriting the vtbl either in pctx or u_resource_vtbl)
> 
> hmm, that is still a bit ugly..  and looking at the equiv thing that
> Ilia implemented in freedreno, I think there is also so special
> handling needed for ->transfer_flush_region()..
> 
> If you don't want to add it in u_resource/_vtbl (and I agree, a per
> rsc vtbl is kinda unneeded), maybe we could introduce in a similar
> way, u_transfer_vtbl/u_transfer_resource/u_transfer, ie.
> 
>    struct u_transfer_resource {
>       struct pipe_resource b;
>       struct pipe_resource *stencil; /* holds separate stencil buffer
> for z32x24s8 */
>    }
> 
>    struct u_transfer {
>       struct pipe_transfer b;
>       void *staging;
>    }
> 
>    struct u_transfer_vtbl {
>       struct pipe_resource (*resource_create)(...);
>       void (*resource_destroy)(...);
>       void *(*transfer_map)(...);
>       void (*transfer_flush_region)(...);
>       void (*transfer_unmap)(...);
>       bool lower_z32s8;
>       bool lower_rgtc;
>    }

I think this makes sense.

Keep in mind that u_threaded_context also has a threaded_transfer 
wrapper of pipe_transfer. It doesn't really do anything for textures, 
but it might be useful to stay compatible. It's unlikely that radeonsi 
will start using these helpers, but other drivers may want to use 
Gallium threading.

Cheers,
Nicolai


> 
> Note that I had schemes to move the rgtc handling that freedreno does
> over to this new scheme too.  Probably the MSAA resolve stuff could be
> folded into this same scheme, I haven't thought about that yet.
> 
> The vtbl ptr doesn't have to be global.  I think we can just stash a
> pointer in pipe_context like what is done for draw module and a few
> other things.
> 
> If you want, I can take a stab at this approach, since I'm also
> messing w/ a staging buffer approach for uploads to flushed but busy
> buffers/textures to avoid a stall, and that gets easier once the
> staging stuff is separated ;-)
> 
> BR,
> -R
> 
>> ---
>>   src/gallium/auxiliary/util/u_transfer.c | 114 ++++++++++++++++++++++++++++++++
>>   src/gallium/auxiliary/util/u_transfer.h |  11 +++
>>   2 files changed, 125 insertions(+)
>>
>> diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
>> index 104d0505aaa8..2d219721dcf8 100644
>> --- a/src/gallium/auxiliary/util/u_transfer.c
>> +++ b/src/gallium/auxiliary/util/u_transfer.c
>> @@ -1,4 +1,5 @@
>>   #include "pipe/p_context.h"
>> +#include "util/u_format_zs.h"
>>   #include "util/u_surface.h"
>>   #include "util/u_inlines.h"
>>   #include "util/u_transfer.h"
>> @@ -272,3 +273,116 @@ void u_transfer_unmap_msaa_helper(struct pipe_context *pctx,
>>      pipe_resource_reference(&trans->ss, NULL);
>>      free(trans);
>>   }
>> +
>> +struct u_transfer_z32f_s8_helper {
>> +   struct pipe_transfer base;
>> +   struct pipe_transfer *z_ptrans;
>> +   struct pipe_transfer *s_ptrans;
>> +   void *z, *s;
>> +   void *merged;
>> +};
>> +
>> +/**
>> + * Helper to implement the PIPE_FORMAT_Z32_FLOAT_S8X24_UINT mappings when the
>> + * driver stores the Z and S in separate resources.
>> + *
>> + * We malloc temporary storage, map each resource, and use the CPU to pack the
>> + * values into the temporary.
>> + *
>> + * Note that the driver's unmap will be called with our ptrans: They need to
>> + * detect it and call u_transfer_unmap_z32f_s8_helper() and return
>> + * immediately.
>> + *
>> + * In both the map and unmap paths, the driver will need to be careful to
>> + * unwrap its transfer_map()/unmap() method that would call us, so that it
>> + * doesn't recurse when we call back into it.
>> + */
>> +void *
>> +u_transfer_map_z32f_s8_helper(struct pipe_context *pctx,
>> +                              struct pipe_resource *z,
>> +                              struct pipe_resource *s,
>> +                              unsigned level, unsigned usage,
>> +                              const struct pipe_box *box,
>> +                              struct pipe_transfer **pptrans)
>> +{
>> +   struct u_transfer_z32f_s8_helper *trans = calloc(1, sizeof(*trans));
>> +   if (!trans)
>> +      return NULL;
>> +   struct pipe_transfer *ptrans = &trans->base;
>> +
>> +   pipe_resource_reference(&ptrans->resource, z);
>> +   ptrans->level = level;
>> +   ptrans->usage = usage;
>> +   ptrans->box = *box;
>> +
>> +   trans->z = pctx->transfer_map(pctx, z, level, usage, box,
>> +                                 &trans->z_ptrans);
>> +   if (!trans->z)
>> +      goto fail_unref;
>> +   trans->s = pctx->transfer_map(pctx, s, level, usage, box,
>> +                                 &trans->s_ptrans);
>> +   if (!trans->s)
>> +      goto fail_unmap_z;
>> +
>> +   ptrans->stride = 8 * box->width;
>> +   trans->merged = malloc(ptrans->stride * box->height);
>> +   if (!trans->merged)
>> +      goto fail_unmap_s;
>> +
>> +   if (usage & PIPE_TRANSFER_READ) {
>> +      util_format_z32_float_s8x24_uint_pack_z_float(trans->merged,
>> +                                                    ptrans->stride,
>> +                                                    trans->z,
>> +                                                    trans->z_ptrans->stride,
>> +                                                    box->width,
>> +                                                    box->height);
>> +      util_format_z32_float_s8x24_uint_pack_s_8uint(trans->merged,
>> +                                                    ptrans->stride,
>> +                                                    trans->s,
>> +                                                    trans->s_ptrans->stride,
>> +                                                    box->width,
>> +                                                    box->height);
>> +   }
>> +
>> +   *pptrans = ptrans;
>> +   return trans->merged;
>> +
>> + fail_unmap_s:
>> +   pctx->transfer_unmap(pctx, trans->s_ptrans);
>> + fail_unmap_z:
>> +   pctx->transfer_unmap(pctx, trans->z_ptrans);
>> + fail_unref:
>> +   pipe_resource_reference(&ptrans->resource, NULL);
>> +   free(trans);
>> +   return NULL;
>> +}
>> +
>> +void u_transfer_unmap_z32f_s8_helper(struct pipe_context *pctx,
>> +                                     struct pipe_transfer *ptrans)
>> +{
>> +   struct u_transfer_z32f_s8_helper *trans =
>> +      (struct u_transfer_z32f_s8_helper *)ptrans;
>> +
>> +   if (ptrans->usage & PIPE_TRANSFER_WRITE) {
>> +      uint32_t width = ptrans->box.width;
>> +      uint32_t height = ptrans->box.height;
>> +
>> +      util_format_z32_float_s8x24_uint_unpack_z_float(trans->z,
>> +                                                      trans->z_ptrans->stride,
>> +                                                      trans->merged,
>> +                                                      ptrans->stride,
>> +                                                      width, height);
>> +      util_format_z32_float_s8x24_uint_unpack_s_8uint(trans->s,
>> +                                                      trans->s_ptrans->stride,
>> +                                                      trans->merged,
>> +                                                      ptrans->stride,
>> +                                                      width, height);
>> +   }
>> +
>> +   pctx->transfer_unmap(pctx, trans->s_ptrans);
>> +   pctx->transfer_unmap(pctx, trans->z_ptrans);
>> +
>> +   pipe_resource_reference(&ptrans->resource, NULL);
>> +   free(trans->merged);
>> +   free(trans);
>> +}
>> diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
>> index 237930c06007..0a8a649df1f5 100644
>> --- a/src/gallium/auxiliary/util/u_transfer.h
>> +++ b/src/gallium/auxiliary/util/u_transfer.h
>> @@ -24,6 +24,17 @@ u_transfer_map_msaa_helper(struct pipe_context *pctx,
>>   void u_transfer_unmap_msaa_helper(struct pipe_context *pctx,
>>                                     struct pipe_transfer *ptrans);
>>
>> +void *
>> +u_transfer_map_z32f_s8_helper(struct pipe_context *pctx,
>> +                              struct pipe_resource *z,
>> +                              struct pipe_resource *s,
>> +                              unsigned level, unsigned usage,
>> +                              const struct pipe_box *box,
>> +                              struct pipe_transfer **pptrans);
>> +
>> +void u_transfer_unmap_z32f_s8_helper(struct pipe_context *pctx,
>> +                                     struct pipe_transfer *ptrans);
>> +
>>   boolean u_default_resource_get_handle(struct pipe_screen *screen,
>>                                         struct pipe_resource *resource,
>>                                         struct winsys_handle *handle);
>> --
>> 2.15.0
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list