From af59f767a03da4dd434a6d655e3d0bc05feb298a Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Tue, 7 Oct 2008 21:47:45 +0200 Subject: nouveau: first draft of swizzle texture upload to vram --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 83 +++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'src/gallium/winsys/drm/nouveau') diff --git a/src/gallium/winsys/drm/nouveau/nv04_surface.c b/src/gallium/winsys/drm/nouveau/nv04_surface.c index 36c913a732..5bf89e1952 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -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)<height)<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. */ -- cgit v1.2.3