ThibG from irc reported an issue with transparent cursors, i noticed the ddx had a workaround, which wasn't in the kms code.
ThibG (whoever you are), please test. The patch is untested. Maarten.
From 7ce90b3297782e5ecada6e4e917be7a9c316d082 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis <madman2...@gmail.com> Date: Mon, 20 Jul 2009 21:46:08 +0200 Subject: [PATCH] nv04: import hw workaround for partially transparent pixels from the ddx - Untested, ThibG from IRC should test this at least. --- drivers/gpu/drm/nouveau/nouveau_crtc.h | 3 - drivers/gpu/drm/nouveau/nv04_crtc.c | 90 +++++++++++++++++++++++++++++++- drivers/gpu/drm/nouveau/nv50_crtc.c | 2 +- 3 files changed, 90 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_crtc.h b/drivers/gpu/drm/nouveau/nouveau_crtc.h index d8f18f9..b9b4c8a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_crtc.h +++ b/drivers/gpu/drm/nouveau/nouveau_crtc.h @@ -76,9 +76,6 @@ struct nouveau_crtc { int nv50_crtc_create(struct drm_device *dev, int index); int nv50_cursor_init(struct nouveau_crtc *); void nv50_cursor_fini(struct nouveau_crtc *); -int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file_priv, - uint32_t buffer_handle, uint32_t width, - uint32_t height); int nv50_crtc_cursor_move(struct drm_crtc *drm_crtc, int x, int y); int nv04_cursor_init(struct nouveau_crtc *); diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index f27f6fe..02edb5f 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -857,6 +857,94 @@ static void nv_crtc_destroy(struct drm_crtc *crtc) { } +int +nv04_crtc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file_priv, + uint32_t buffer_handle, uint32_t width, uint32_t height) +{ + struct drm_device *dev = drm_crtc->dev; + struct nouveau_crtc *crtc = to_nouveau_crtc(drm_crtc); + int ret = 0; + + if (width != 64 || height != 64) + return -EINVAL; + + if (crtc->cursor.nvbo) { + nouveau_bo_unpin(crtc->cursor.nvbo); + nouveau_bo_ref(NULL, &crtc->cursor.nvbo); + } + + if (buffer_handle) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_gem_object *gem; + struct nouveau_bo *nvbo; + uint32_t alpha; + uint32_t *pixel; + int i; + + gem = drm_gem_object_lookup(dev, file_priv, buffer_handle); + if (!gem) + return -EINVAL; + nvbo = nouveau_gem_object(gem); + + nouveau_bo_ref(nvbo, &crtc->cursor.nvbo); + mutex_lock(&dev->struct_mutex); + drm_gem_object_unreference(gem); + mutex_unlock(&dev->struct_mutex); + + ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM); + if (ret) { + nouveau_bo_ref(NULL, &crtc->cursor.nvbo); + return ret; + } + + ret = nouveau_bo_map(nvbo); + if (ret) { + nouveau_bo_ref(NULL, &crtc->cursor.nvbo); + return ret; + } + + /* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) + * alpha cursors (though NPM in combination with fp dithering + * may not work on nv11, from "nv" driver history). + * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND + * set and is what the blob uses, however we get given PM cursors + * so we use PM mode. + */ + + pixel = nvbo->kmap.virtual; + + for (i = 0; i < 64*64; i++) { + /* hw gets unhappy if alpha <= rgb values. for a PM image + * "less than" shouldn't happen; fix "equal to" case by adding + * one to alpha channel (slightly inaccurate, but so is + * attempting to get back to NPM images, due to limits of + * integer precision). + */ + + alpha = pixel[i] >> 24; + /* fully transparent and solid colors are fine */ + if (alpha > 0 && alpha < 255) + pixel[i] = ((alpha + 1) << 24) | (pixel[i] & 0xFFFFFF); + +#ifdef __BIG_ENDIAN + if (dev_priv->chipset == 0x11) + pixel[i] = lswapl(pixel[i]); +#endif + } + + nouveau_bo_unmap(nvbo); + + crtc->cursor.offset = nvbo->bo.offset - + dev_priv->vm_vram_base; + crtc->cursor.set_offset(crtc, crtc->cursor.offset); + crtc->cursor.show(crtc, true); + } else { + crtc->cursor.hide(crtc, true); + } + + return ret; +} + #define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) static void nv_crtc_gamma_load(struct nouveau_crtc *nv_crtc) @@ -972,7 +1060,7 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, static const struct drm_crtc_funcs nv04_crtc_funcs = { .save = nv_crtc_save, .restore = nv_crtc_restore, - .cursor_set = nv50_crtc_cursor_set, + .cursor_set = nv04_crtc_cursor_set, .cursor_move = nv50_crtc_cursor_move, .gamma_set = nv_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index b1351e4..e6772ac 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -367,7 +367,7 @@ static void nv50_crtc_destroy(struct drm_crtc *drm_crtc) kfree(crtc); } -int +static int nv50_crtc_cursor_set(struct drm_crtc *drm_crtc, struct drm_file *file_priv, uint32_t buffer_handle, uint32_t width, uint32_t height) { -- 1.6.3.3
_______________________________________________ Nouveau mailing list Nouveau@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/nouveau