[virglrenderer-devel] [PATCH 3/5] vrend: store offsets into backing ivo for mipmaps and use it when reading data back (v2)
Gert Wollny
gert.wollny at collabora.com
Mon Jun 18 06:13:55 UTC 2018
Am Freitag, den 15.06.2018, 15:50 -0700 schrieb Gurchetan Singh:
> Patches 1, 2, 4, and 5 are:
Thanks for the review.
> > + if (info->level> 0 && info->level <=
> > MAX_READBACK_MIPMAP_LEVELS) {
>
> Why don't you just have a case for level 0? Right now it's a little
> confusing to follow. It's also consistent with
> EGL_EXT_image_dma_buf_import offsets.
The size of the offset array is limied, so I have to check the upper
bound, otherwise we might later try to read from unallocated memory. I
can think of how to make it more clear but in the end it's the same.
> > + int64_t level_height = u_minify(res->base.height0,
> > info->level);
> >
> > + res->mipmap_offsets[info->level-1] = info->offset -
> >
> > + ((info->box->z *
> > level_height + y) * stride + x * elsize);
> >
> >
>
> I don't fully understand this calculation.
> From virgl_texture_transfer_map it seems info->offset represents the
> start of the transfer from with given {x, y, z} coordination in the
> texture. So:
> info->offset == info->box->z * level_height + y * level_stride + x *
> elsize
level_height is the numbers of rows in the mip-map level, you still
have to multiply with the stride to get the number of bytes for a full
slice, hence for info->box->z slices you have an offset of ( info-
>box->z * level_height * level_stride) bytes, adding the bytes per y
rows you get
( info->box->z * level_height * level_stride) + y * level_stride
= ( info->box->z * level_height + y) * level_stride (reduce four
operations to three)and to this you add the number of bytes to get to x
(= x* elsize).
> So won't mipmap_offsets always be zero?
The offset for the mipmap data is only zero for the 0-level, if it
would alway be zero the tests would passwithout this patch.
> Also nit: parens would make more sense like this -- info->offset
> - (info->box->z * level_height + y * stride + x * elsize);
Same as above, you forgot that for a slice the number of bytes is
(level_height*stride).
Best, Gert
>
> > + }
> >
> > +
> >
> > if (res->base.format == (enum
> > pipe_format)VIRGL_FORMAT_Z24X8_UNORM) {
> >
> > /* we get values from the guest as 24-bit scaled
> > integers
> >
> > but we give them to the host GL and it interprets
> > them
> >
> > @@ -6088,8 +6102,6 @@ static void
> > vrend_resource_copy_fallback(struct vrend_resource *src_res,
> >
> >
> >
> > box = *src_box;
> >
> > box.depth = vrend_get_texture_depth(src_res, src_level);
> >
> > -
> >
> > - src_stride = util_format_get_stride(src_res->base.format,
> > src_res->base.width0);
> >
> > dst_stride = util_format_get_stride(dst_res->base.format,
> > dst_res->base.width0);
> >
> >
> >
> > /* this is ugly need to do a full GetTexImage */
> >
> > @@ -6111,12 +6123,21 @@ static void
> > vrend_resource_copy_fallback(struct vrend_resource *src_res,
> >
> > * iovec to have the data we need, otherwise we can use
> > glGetTexture
> >
> > */
> >
> > if (vrend_state.use_gles) {
> >
> > - read_transfer_data(&src_res->base, src_res->iov, src_res-
> > >num_iovs,
> >
> > - tptr, src_stride, &box, src_level, 0,
> > false);
> >
> > + uint64_t src_offset = 0;
> >
> > + uint64_t dst_offset = 0;
> >
> > + if (src_level > 0 && src_level <=
> > MAX_READBACK_MIPMAP_LEVELS) {
> >
> > + src_offset = src_res->mipmap_offsets[src_level-1];
> >
> > + dst_offset = dst_res->mipmap_offsets[src_level-1];
> >
> > + }
> >
> > +
> >
> > + src_stride = util_format_get_nblocksx(src_res->base.format,
> >
> > + u_minify(src_res-
> > >base.width0, src_level)) * elsize;
> >
> > + read_transfer_data(&src_res->base, src_res->iov, src_res-
> > >num_iovs, tptr,
> >
> > + src_stride, &box, src_level, src_offset,
> > false);
> >
> > /* In on GLES Sync the iov that backs the dst resource
> > because
> >
> > * we might need it in a chain copy A->B, B->C */
> >
> > write_transfer_data(&dst_res->base, dst_res->iov, dst_res-
> > >num_iovs, tptr,
> >
> > - dst_stride, &box, src_level, 0, false);
> >
> > + dst_stride, &box, src_level, dst_offset,
> > false);
> >
> > /* we get values from the guest as 24-bit scaled integers
> >
> > but we give them to the host GL and it interprets them
> >
> > as 32-bit scaled integers, so we need to scale them here
> > */
> >
> > diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
> >
> > index 042d439..258c439 100644
> >
> > --- a/src/vrend_renderer.h
> >
> > +++ b/src/vrend_renderer.h
> >
> > @@ -44,6 +44,9 @@ struct virgl_gl_ctx_param {
> >
> > extern int vrend_dump_shaders;
> >
> > struct vrend_context;
> >
> >
> >
> > +/* Number of mipmap levels for which to keep the backing iov
> > offsets */
> >
> > +#define MAX_READBACK_MIPMAP_LEVELS 16
> >
> > +
> >
> > struct vrend_resource {
> >
> > struct pipe_resource base;
> >
> > GLuint id;
> >
> > @@ -62,6 +65,7 @@ struct vrend_resource {
> >
> > char *ptr;
> >
> > struct iovec *iov;
> >
> > uint32_t num_iovs;
> >
> > + uint64_t mipmap_offsets[MAX_READBACK_MIPMAP_LEVELS];
> >
> > };
> >
> >
> >
> > /* assume every format is sampler friendly */
> >
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/virglrenderer-devel/attachments/20180618/4ff6665f/attachment.html>
More information about the virglrenderer-devel
mailing list