nouveau: first draft of swizzle texture upload to vram
authorPatrice Mandin <pmandin@caramail.com>
Tue, 7 Oct 2008 19:47:45 +0000 (21:47 +0200)
committerPatrice Mandin <pmandin@caramail.com>
Tue, 7 Oct 2008 19:47:45 +0000 (21:47 +0200)
src/gallium/winsys/drm/nouveau/nv04_surface.c

index 36c913a7329648603138c81085bae6834133ab8a..5bf89e1952e4dc9ac068c196bf095f911016c5de 100644 (file)
@@ -3,6 +3,32 @@
 
 #include "nouveau_context.h"
 
+static INLINE int log2i(int i)
+{
+       int r = 0;
+
+       if (i & 0xffff0000) {
+               i >>= 16;
+               r += 16;
+       }
+       if (i & 0x0000ff00) {
+               i >>= 8;
+               r += 8;
+       }
+       if (i & 0x000000f0) {
+               i >>= 4;
+               r += 4;
+       }
+       if (i & 0x0000000c) {
+               i >>= 2;
+               r += 2;
+       }
+       if (i & 0x00000002) {
+               r += 1;
+       }
+       return r;
+}
+
 static INLINE int
 nv04_surface_format(enum pipe_format format)
 {
@@ -81,6 +107,56 @@ nv04_surface_copy_blit(struct nouveau_context *nv, unsigned dx, unsigned dy,
        OUT_RING  (chan, ( h << 16) |  w);
 }
 
+static int
+nv04_surface_copy_prep_swizzled(struct nouveau_context *nv,
+                               struct pipe_surface *dst,
+                               struct pipe_surface *src)
+{
+       struct nouveau_channel *chan = nv->nvc->channel;
+
+       BEGIN_RING(chan, nv->nvc->NvSwzSurf,
+                  NV04_SWIZZLED_SURFACE_FORMAT, 2);
+       /* FIXME: read destination format from somewhere */
+       OUT_RING  (chan,
+               NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8
+               | (log2i(dst->width)<<NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT)
+               | (log2i(dst->height)<<NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT) );
+       OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
+                  NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+       BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 13);
+       OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
+       /* FIXME: read source format from somewhere */
+       OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8);
+       OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, (src->height<<16) | src->width);
+       OUT_RING  (chan, 0);
+       OUT_RING  (chan, (src->height<<16) | src->width);
+       OUT_RING  (chan, 1<<20);
+       OUT_RING  (chan, 1<<20);
+       OUT_RING  (chan, (src->height<<16) | src->width);
+       OUT_RING  (chan,
+               src->stride
+               | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER
+               | NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
+       OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo,
+                  NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+       OUT_RING  (chan, 0);
+
+       BEGIN_RING(chan, nv->nvc->NvM2MF,
+                  NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
+       OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo,
+                  NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+       OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
+                  NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+       nv->surface_copy = nv04_surface_copy_m2mf;
+       nv->surf_dst = dst;
+       nv->surf_src = src;
+       return 0;
+}
+
 static int
 nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,
                       struct pipe_surface *src)
@@ -91,6 +167,13 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst,
        if (src->format != dst->format)
                return 1;
 
+       /* Setup transfer to swizzle the texture to vram if needed */
+       /* FIXME/TODO: check proper limits of this operation */
+       if (nouveau_buffer(dst->buffer)->bo->flags & NOUVEAU_BO_SWIZZLED) {
+               /* FIXME: Disable it for the moment */
+               /*return nv04_surface_copy_prep_swizzled(nv, dst, src);*/
+       }
+
        /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback
         * to NV_MEMORY_TO_MEMORY_FORMAT in this case.
         */