virgl: fix stride + layer_stride inconsistency
With blob resources, stride doesn't necesarily have to equal width * bpp. The use case for this a minigbm blob resource with blob mem BLOB_MEM_HOST3D_GUEST imported into guest Mesa. In addition, for BLOB_MEM_HOST we can repurpose the transfer ioctls to also flush caches if need be, so this seems a good time to fix this issue. Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4821>
This commit is contained in:
parent
87383e3163
commit
5c2129d434
|
@ -1429,10 +1429,18 @@ void virgl_encode_transfer(struct virgl_screen *vs, struct virgl_cmd_buf *buf,
|
|||
struct virgl_transfer *trans, uint32_t direction)
|
||||
{
|
||||
uint32_t command;
|
||||
struct virgl_resource *vres = virgl_resource(trans->base.resource);
|
||||
enum virgl_transfer3d_encode_stride stride_type =
|
||||
virgl_transfer3d_host_inferred_stride;
|
||||
|
||||
if (trans->base.box.depth == 1 && trans->base.level == 0 &&
|
||||
trans->base.resource->target == PIPE_TEXTURE_2D &&
|
||||
vres->blob_mem == VIRGL_BLOB_MEM_HOST3D_GUEST)
|
||||
stride_type = virgl_transfer3d_explicit_stride;
|
||||
|
||||
command = VIRGL_CMD0(VIRGL_CCMD_TRANSFER3D, 0, VIRGL_TRANSFER3D_SIZE);
|
||||
virgl_encoder_write_dword(buf, command);
|
||||
virgl_encoder_transfer3d_common(vs, buf, trans,
|
||||
virgl_transfer3d_host_inferred_stride);
|
||||
virgl_encoder_transfer3d_common(vs, buf, trans, stride_type);
|
||||
virgl_encoder_write_dword(buf, trans->offset);
|
||||
virgl_encoder_write_dword(buf, direction);
|
||||
}
|
||||
|
|
|
@ -265,6 +265,7 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws,
|
|||
res->res_handle = createcmd.res_handle;
|
||||
res->bo_handle = createcmd.bo_handle;
|
||||
res->size = size;
|
||||
res->target = target;
|
||||
pipe_reference_init(&res->reference, 1);
|
||||
p_atomic_set(&res->external, false);
|
||||
p_atomic_set(&res->num_cs_references, 0);
|
||||
|
@ -280,6 +281,27 @@ virgl_drm_winsys_resource_create(struct virgl_winsys *qws,
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Previously, with DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, all host resources had
|
||||
* a guest memory shadow resource with size = stride * bpp. Virglrenderer
|
||||
* would guess the stride implicitly when performing transfer operations, if
|
||||
* the stride wasn't specified. Interestingly, vtest would specify the stride.
|
||||
*
|
||||
* Guessing the stride breaks down with YUV images, which may be imported into
|
||||
* Mesa as 3R8 images. It also doesn't work if an external allocator
|
||||
* (i.e, minigbm) decides to use a stride not equal to stride * bpp. With blob
|
||||
* resources, the size = stride * bpp restriction no longer holds, so use
|
||||
* explicit strides passed into Mesa.
|
||||
*/
|
||||
static inline bool use_explicit_stride(struct virgl_hw_res *res, uint32_t level,
|
||||
uint32_t depth)
|
||||
{
|
||||
return (params[param_resource_blob].value &&
|
||||
res->blob_mem == VIRTGPU_BLOB_MEM_HOST3D_GUEST &&
|
||||
res->target == PIPE_TEXTURE_2D &&
|
||||
level == 0 && depth == 1);
|
||||
}
|
||||
|
||||
static int
|
||||
virgl_bo_transfer_put(struct virgl_winsys *vws,
|
||||
struct virgl_hw_res *res,
|
||||
|
@ -302,8 +324,10 @@ virgl_bo_transfer_put(struct virgl_winsys *vws,
|
|||
tohostcmd.box.d = box->depth;
|
||||
tohostcmd.offset = buf_offset;
|
||||
tohostcmd.level = level;
|
||||
// tohostcmd.stride = stride;
|
||||
// tohostcmd.layer_stride = stride;
|
||||
|
||||
if (use_explicit_stride(res, level, box->depth))
|
||||
tohostcmd.stride = stride;
|
||||
|
||||
return drmIoctl(vdws->fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &tohostcmd);
|
||||
}
|
||||
|
||||
|
@ -323,14 +347,16 @@ virgl_bo_transfer_get(struct virgl_winsys *vws,
|
|||
fromhostcmd.bo_handle = res->bo_handle;
|
||||
fromhostcmd.level = level;
|
||||
fromhostcmd.offset = buf_offset;
|
||||
// fromhostcmd.stride = stride;
|
||||
// fromhostcmd.layer_stride = layer_stride;
|
||||
fromhostcmd.box.x = box->x;
|
||||
fromhostcmd.box.y = box->y;
|
||||
fromhostcmd.box.z = box->z;
|
||||
fromhostcmd.box.w = box->width;
|
||||
fromhostcmd.box.h = box->height;
|
||||
fromhostcmd.box.d = box->depth;
|
||||
|
||||
if (use_explicit_stride(res, level, box->depth))
|
||||
fromhostcmd.stride = stride;
|
||||
|
||||
return drmIoctl(vdws->fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &fromhostcmd);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ struct hash_table;
|
|||
|
||||
struct virgl_hw_res {
|
||||
struct pipe_reference reference;
|
||||
enum pipe_texture_target target;
|
||||
uint32_t res_handle;
|
||||
uint32_t bo_handle;
|
||||
int num_cs_references;
|
||||
|
|
Loading…
Reference in New Issue