Signed-off-by: Francisco Jerez <[email protected]>
---
The same as the previous version but rebased over the latest kernel changes.

 drivers/gpu/drm/nouveau/nouveau_hw.h |   10 ++++
 drivers/gpu/drm/nouveau/nv04_crtc.c  |   95 +++++++++++++++++++++++----------
 2 files changed, 76 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h 
b/drivers/gpu/drm/nouveau/nouveau_hw.h
index 9d86461..129345e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.h
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.h
@@ -379,6 +379,16 @@ NVLockVgaCrtcs(struct drm_device *dev, bool lock)
        return waslocked;
 }
 
+/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
+#define NV04_CURSOR_SIZE 32
+/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
+#define NV10_CURSOR_SIZE 64
+
+static inline int nv_cursor_width(struct drm_device *dev)
+{
+       return nv_arch(dev) >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+}
+
 static inline void
 nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
 {
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c 
b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 4e56c25..e4910ea 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -839,6 +839,64 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int 
y,
        return 0;
 }
 
+static void nv04_cursor_upload(struct drm_device *dev, uint32_t *src, uint16_t 
*dst)
+{
+       int width = nv_cursor_width(dev);
+       uint32_t pixel;
+       int i, j;
+
+       for (i = 0; i < width; i++) {
+               for (j = 0; j < width; j++) {
+                       pixel = src[i*64 + j];
+
+                       dst[i*width + j] = (pixel & 0x80000000) >> 16
+                               | (pixel & 0xf80000) >> 9
+                               | (pixel & 0xf800) >> 6
+                               | (pixel & 0xf8) >> 3;
+               }
+       }
+}
+
+static void nv11_cursor_upload(struct drm_device *dev, uint32_t *src, uint32_t 
*dst)
+{
+       uint32_t pixel;
+       int alpha, i;
+
+       /* 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
+        */
+       for (i = 0; i < 64 * 64; i++) {
+               pixel = *src++;
+
+               /* 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 >> 24;
+               if (alpha > 0 && alpha < 255)
+                       pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24);
+
+#ifdef __BIG_ENDIAN
+               {
+                       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+                       if (dev_priv->chipset == 0x11) {
+                               pixel = ((pixel & 0x000000ff) << 24) |
+                                       ((pixel & 0x0000ff00) << 8) |
+                                       ((pixel & 0x00ff0000) >> 8) |
+                                       ((pixel & 0xff000000) >> 24);
+                       }
+               }
+#endif
+
+               *dst++ = pixel;
+       }
+}
+
 static int
 nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
                     uint32_t buffer_handle, uint32_t width, uint32_t height)
@@ -848,7 +906,8 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file 
*file_priv,
        struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
        struct nouveau_bo *cursor = NULL;
        struct drm_gem_object *gem;
-       int ret = 0, alpha, i;
+       void *src, *dst;
+       int ret = 0;
 
        if (width != 64 || height != 64)
                return -EINVAL;
@@ -867,35 +926,13 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct 
drm_file *file_priv,
        if (ret)
                goto out;
 
-       /* 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
-        */
-       for (i = 0; i < 64 * 64; i++) {
-               uint32_t pixel = nouveau_bo_rd32(cursor, i);
+       src = cursor->kmap.virtual;
+       dst = nv_crtc->cursor.nvbo->kmap.virtual;
 
-               /* 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 >> 24;
-               if (alpha > 0 && alpha < 255)
-                       pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24);
-
-#ifdef __BIG_ENDIAN
-               if (dev_priv->chipset == 0x11) {
-                       pixel = ((pixel & 0x000000ff) << 24) |
-                               ((pixel & 0x0000ff00) << 8) |
-                               ((pixel & 0x00ff0000) >> 8) |
-                               ((pixel & 0xff000000) >> 24);
-               }
-#endif
-
-               nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, pixel);
-       }
+       if (dev_priv->chipset >= 0x11)
+               nv11_cursor_upload(dev, src, dst);
+       else
+               nv04_cursor_upload(dev, src, dst);
 
        nouveau_bo_unmap(cursor);
        nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset;
-- 
1.6.3.3

_______________________________________________
Nouveau mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau

Reply via email to