[virglrenderer-devel] [PATCH 3/5] vrend: store offsets into backing ivo for mipmaps and use it when reading data back (v3)

Gurchetan Singh gurchetansingh at chromium.org
Tue Jun 19 15:07:27 UTC 2018


Reviewed-by: Gurchetan Singh <gurchetansingh at chromium.org>
On Tue, Jun 19, 2018 at 1:43 AM Gert Wollny <gert.wollny at collabora.com> wrote:
>
> In the copy fallback, when a texture can not be rendered, the data that resides
> in the backing iovec needs to be used. For the non-zero levels of mip-map textures
> the data is located at an offset. This patch adds storing this offset and using it
> when data is read from the backing iovec and updating the dst iov. We limit the
> mip-map levels for which this is done to 1-17, which is enough to cover
> 32kx32k textures. The patch also fixes the stride when accessing mip-map levels.
>
> Fixes:
>   dEQP-GLES3.functional.texture.specification.teximage3d_depth.depth_component24_2d_array
>   dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth_component32f_2d_array
>   dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth_component24_2d_array
>   dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth_component16_2d_array
>   dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth32f_stencil8_2d_array
>   dEQP-GLES3.functional.texture.specification.texsubimage3d_depth.depth24_stencil8_2d_array
>
> v2: * rebase and remove unused variables
>     * also correct offset when writing to the destination backing iovec
>
> v3: * follow mesa/virgl notation and range for storing the mip-map offsets
>       Suggested-by: Gurchetan Singh <gurchetansingh at chromium.org>
>
> Signed-off-by: Jakob Bornecrantz <jakob at collabora.com> (v1)
> Signed-off-by: Gert Wollny <gert.wollny at collabora.com>
> ---
>  src/vrend_renderer.c | 30 +++++++++++++++++++++++++-----
>  src/vrend_renderer.h |  6 ++++++
>  2 files changed, 31 insertions(+), 5 deletions(-)
>
> diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
> index 1f709ad..ec5427b 100644
> --- a/src/vrend_renderer.c
> +++ b/src/vrend_renderer.c
> @@ -5405,6 +5405,19 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
>           x = info->box->x;
>           y = invert ? (int)res->base.height0 - info->box->y - info->box->height : info->box->y;
>
> +
> +         /* mipmaps are usually passed in one iov, and we need to keep the offset
> +          * into the data in case we want to read back the data of a surface
> +          * that can not be rendered. Since we can not assume that the whole texture
> +          * is filled, we evaluate the offset for origin (0,0,0). Since it is also
> +          * possible that a resource is reused and resized update the offset every time.
> +          */
> +         if (info->level < VR_MAX_TEXTURE_2D_LEVELS) {
> +            int64_t level_height = u_minify(res->base.height0, info->level);
> +            res->mipmap_offsets[info->level] = info->offset -
> +                                               ((info->box->z * level_height + y) * stride + x * elsize);
> +         }
> +
>           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 +6101,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 +6122,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 < VR_MAX_TEXTURE_2D_LEVELS) {
> +         src_offset = src_res->mipmap_offsets[src_level];
> +         dst_offset = dst_res->mipmap_offsets[src_level];
> +      }
> +
> +      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 5a48990..e702d8e 100644
> --- a/src/vrend_renderer.h
> +++ b/src/vrend_renderer.h
> @@ -44,6 +44,11 @@ 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.
> + * Value mirrored from mesa/virgl
> + */
> +#define VR_MAX_TEXTURE_2D_LEVELS 15
> +
>  struct vrend_resource {
>     struct pipe_resource base;
>     GLuint id;
> @@ -62,6 +67,7 @@ struct vrend_resource {
>     char *ptr;
>     struct iovec *iov;
>     uint32_t num_iovs;
> +   uint64_t mipmap_offsets[VR_MAX_TEXTURE_2D_LEVELS];
>  };
>
>  /* assume every format is sampler friendly */
> --
> 2.17.1
>


More information about the virglrenderer-devel mailing list