vrend: store offsets into backing ivo for mipmaps and use it when reading data back (v3)

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@chromium.org>

Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Signed-off-by: Jakob Bornecrantz <jakob@collabora.com>
macos/master
Gert Wollny 7 years ago committed by Jakob Bornecrantz
parent 00e62addc3
commit 04f2080d89
  1. 32
      src/vrend_renderer.c
  2. 6
      src/vrend_renderer.h

@ -5414,6 +5414,19 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
x = info->box->x; x = info->box->x;
y = invert ? (int)res->base.height0 - info->box->y - info->box->height : info->box->y; 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) { if (res->base.format == (enum pipe_format)VIRGL_FORMAT_Z24X8_UNORM) {
/* we get values from the guest as 24-bit scaled integers /* we get values from the guest as 24-bit scaled integers
but we give them to the host GL and it interprets them but we give them to the host GL and it interprets them
@ -6097,8 +6110,6 @@ static void vrend_resource_copy_fallback(struct vrend_resource *src_res,
box = *src_box; box = *src_box;
box.depth = vrend_get_texture_depth(src_res, src_level); 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); dst_stride = util_format_get_stride(dst_res->base.format, dst_res->base.width0);
/* this is ugly need to do a full GetTexImage */ /* this is ugly need to do a full GetTexImage */
@ -6120,12 +6131,21 @@ static void vrend_resource_copy_fallback(struct vrend_resource *src_res,
* iovec to have the data we need, otherwise we can use glGetTexture * iovec to have the data we need, otherwise we can use glGetTexture
*/ */
if (vrend_state.use_gles) { if (vrend_state.use_gles) {
read_transfer_data(&src_res->base, src_res->iov, src_res->num_iovs, uint64_t src_offset = 0;
tptr, src_stride, &box, src_level, 0, false); uint64_t dst_offset = 0;
/* Sync the dst iovec backing store because 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);
/* When on GLES sync the iov that backs the dst resource because
* we might need it in a chain copy A->B, B->C */ * 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, 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 /* we get values from the guest as 24-bit scaled integers
but we give them to the host GL and it interprets them but we give them to the host GL and it interprets them
as 32-bit scaled integers, so we need to scale them here */ as 32-bit scaled integers, so we need to scale them here */

@ -44,6 +44,11 @@ struct virgl_gl_ctx_param {
extern int vrend_dump_shaders; extern int vrend_dump_shaders;
struct vrend_context; 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 vrend_resource {
struct pipe_resource base; struct pipe_resource base;
GLuint id; GLuint id;
@ -62,6 +67,7 @@ struct vrend_resource {
char *ptr; char *ptr;
struct iovec *iov; struct iovec *iov;
uint32_t num_iovs; uint32_t num_iovs;
uint64_t mipmap_offsets[VR_MAX_TEXTURE_2D_LEVELS];
}; };
/* assume every format is sampler friendly */ /* assume every format is sampler friendly */

Loading…
Cancel
Save