Skip to content

Commit

Permalink
drm/vmwgfx: Cleanup the cursor snooping code
Browse files Browse the repository at this point in the history
Cursor snooping depended on implicit size and format which made debugging
quite difficult. Make the code easier to following by making everything
explicit and instead of using magic numbers predefine all the
parameters the code depends on.

Also fixes incorrectly computed pitches for non-aligned cursor snoops.
Fix which has no practical effect because non-aligned cursor snoops
are not used by the X11 driver and Wayland cursors will go through
mob cursors, instead of surface dma's.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Michael Banack <banackm@vmware.com>
Reviewed-by: Martin Krastev <krastevm@vmware.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221026031936.1004280-2-zack@kde.org
  • Loading branch information
Zack Rusin committed Oct 31, 2022
1 parent 4cf949c commit da7ffb9
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 17 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@
#define VMW_RES_SHADER ttm_driver_type4
#define VMW_RES_HT_ORDER 12

#define VMW_CURSOR_SNOOP_FORMAT SVGA3D_A8R8G8B8
#define VMW_CURSOR_SNOOP_WIDTH 64
#define VMW_CURSOR_SNOOP_HEIGHT 64

#define MKSSTAT_CAPACITY_LOG2 5U
#define MKSSTAT_CAPACITY (1U << MKSSTAT_CAPACITY_LOG2)

Expand Down
29 changes: 17 additions & 12 deletions drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@
*
**************************************************************************/

#include "vmwgfx_kms.h"
#include "vmw_surface_cache.h"

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_rect.h>
#include <drm/drm_sysfs.h>

#include "vmwgfx_kms.h"

void vmw_du_cleanup(struct vmw_display_unit *du)
{
struct vmw_private *dev_priv = vmw_priv(du->primary.dev);
Expand Down Expand Up @@ -351,7 +352,6 @@ static void vmw_cursor_update_position(struct vmw_private *dev_priv,
spin_unlock(&dev_priv->cursor_lock);
}


void vmw_kms_cursor_snoop(struct vmw_surface *srf,
struct ttm_object_file *tfile,
struct ttm_buffer_object *bo,
Expand All @@ -369,6 +369,9 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
SVGA3dCmdSurfaceDMA dma;
} *cmd;
int i, ret;
const struct SVGA3dSurfaceDesc *desc =
vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
const u32 image_pitch = VMW_CURSOR_SNOOP_WIDTH * desc->pitchBytesPerBlock;

cmd = container_of(header, struct vmw_dma_cmd, header);

Expand All @@ -394,7 +397,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
box->x != 0 || box->y != 0 || box->z != 0 ||
box->srcx != 0 || box->srcy != 0 || box->srcz != 0 ||
box->d != 1 || box_count != 1 ||
box->w > 64 || box->h > 64) {
box->w > VMW_CURSOR_SNOOP_WIDTH || box->h > VMW_CURSOR_SNOOP_HEIGHT) {
/* TODO handle none page aligned offsets */
/* TODO handle more dst & src != 0 */
/* TODO handle more then one copy */
Expand All @@ -408,7 +411,7 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,
}

kmap_offset = cmd->dma.guest.ptr.offset >> PAGE_SHIFT;
kmap_num = (64*64*4) >> PAGE_SHIFT;
kmap_num = (VMW_CURSOR_SNOOP_HEIGHT*image_pitch) >> PAGE_SHIFT;

ret = ttm_bo_reserve(bo, true, false, NULL);
if (unlikely(ret != 0)) {
Expand All @@ -422,14 +425,15 @@ void vmw_kms_cursor_snoop(struct vmw_surface *srf,

virtual = ttm_kmap_obj_virtual(&map, &dummy);

if (box->w == 64 && cmd->dma.guest.pitch == 64*4) {
memcpy(srf->snooper.image, virtual, 64*64*4);
if (box->w == VMW_CURSOR_SNOOP_WIDTH && cmd->dma.guest.pitch == image_pitch) {
memcpy(srf->snooper.image, virtual,
VMW_CURSOR_SNOOP_HEIGHT*image_pitch);
} else {
/* Image is unsigned pointer. */
for (i = 0; i < box->h; i++)
memcpy(srf->snooper.image + i * 64,
memcpy(srf->snooper.image + i * image_pitch,
virtual + i * cmd->dma.guest.pitch,
box->w * 4);
box->w * desc->pitchBytesPerBlock);
}

srf->snooper.age++;
Expand Down Expand Up @@ -480,7 +484,8 @@ void vmw_kms_cursor_post_execbuf(struct vmw_private *dev_priv)
du->cursor_age = du->cursor_surface->snooper.age;
vmw_send_define_cursor_cmd(dev_priv,
du->cursor_surface->snooper.image,
64, 64,
VMW_CURSOR_SNOOP_WIDTH,
VMW_CURSOR_SNOOP_HEIGHT,
du->hotspot_x + du->core_hotspot_x,
du->hotspot_y + du->core_hotspot_y);
}
Expand Down Expand Up @@ -1806,7 +1811,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
if (IS_ERR(vfb)) {
ret = PTR_ERR(vfb);
goto err_out;
}
}

err_out:
/* vmw_user_lookup_handle takes one ref so does new_fb */
Expand Down Expand Up @@ -2326,7 +2331,7 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv,
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry;
}
}
goto out_fini;
}
}
Expand Down
14 changes: 9 additions & 5 deletions drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,11 +815,15 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
res->backup_size = cur_bo_offset;
if (metadata->scanout &&
metadata->num_sizes == 1 &&
metadata->sizes[0].width == 64 &&
metadata->sizes[0].height == 64 &&
metadata->format == SVGA3D_A8R8G8B8) {

srf->snooper.image = kzalloc(64 * 64 * 4, GFP_KERNEL);
metadata->sizes[0].width == VMW_CURSOR_SNOOP_WIDTH &&
metadata->sizes[0].height == VMW_CURSOR_SNOOP_HEIGHT &&
metadata->format == VMW_CURSOR_SNOOP_FORMAT) {
const struct SVGA3dSurfaceDesc *desc =
vmw_surface_get_desc(VMW_CURSOR_SNOOP_FORMAT);
const u32 cursor_size_bytes = VMW_CURSOR_SNOOP_WIDTH *
VMW_CURSOR_SNOOP_HEIGHT *
desc->pitchBytesPerBlock;
srf->snooper.image = kzalloc(cursor_size_bytes, GFP_KERNEL);
if (!srf->snooper.image) {
DRM_ERROR("Failed to allocate cursor_image\n");
ret = -ENOMEM;
Expand Down

0 comments on commit da7ffb9

Please sign in to comment.