From a6b7c0bcbebb7532b6728500a868b7c985e3f822 Mon Sep 17 00:00:00 2001 From: Younes Manton Date: Mon, 1 Dec 2008 22:24:19 -0500 Subject: nouveau: nv04-nv40 linear <-> swizzled conversion. --- src/gallium/winsys/drm/nouveau/nv04_surface.c | 151 +++++++++++++------------- 1 file changed, 78 insertions(+), 73 deletions(-) (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 d08955de71..4f37af7927 100644 --- a/src/gallium/winsys/drm/nouveau/nv04_surface.c +++ b/src/gallium/winsys/drm/nouveau/nv04_surface.c @@ -37,7 +37,11 @@ nv04_surface_format(enum pipe_format format) return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; case PIPE_FORMAT_R5G6B5_UNORM: return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + case PIPE_FORMAT_R16_SNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y16; + case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM: + return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8; case PIPE_FORMAT_Z24S8_UNORM: return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; default: @@ -61,6 +65,69 @@ nv04_rect_format(enum pipe_format format) } } +static INLINE int +nv04_scaled_image_format(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_A1R5G5B5_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A1R5G5B5; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_X8R8G8B8; + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_R16_SNORM: + return NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; + default: + return -1; + } +} + +static void +nv04_surface_copy_swizzle(struct nouveau_context *nv, unsigned dx, unsigned dy, + unsigned sx, unsigned sy, unsigned w, unsigned h) +{ + struct nouveau_channel *chan = nv->nvc->channel; + struct pipe_surface *dst = nv->surf_dst; + struct pipe_surface *src = nv->surf_src; + + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); + OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_FORMAT, 2); + OUT_RING (chan, nv04_surface_format(dst->format) | + log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | + log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); + OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, nv->nvc->NvSwzSurf->handle); + + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + OUT_RING (chan, nv04_scaled_image_format(src->format)); + OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING (chan, 0); + OUT_RING (chan, h << 16 | w); + OUT_RING (chan, 0); + OUT_RING (chan, h << 16 | w); + OUT_RING (chan, 1 << 20); + OUT_RING (chan, 1 << 20); + BEGIN_RING(chan, nv->nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING (chan, h << 16 | w); + OUT_RING (chan, src->stride | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset, + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); + OUT_RING (chan, 0); +} + static void nv04_surface_copy_m2mf(struct nouveau_context *nv, unsigned dx, unsigned dy, unsigned sx, unsigned sy, unsigned w, unsigned h) @@ -107,56 +174,6 @@ 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) @@ -169,9 +186,17 @@ nv04_surface_copy_prep(struct nouveau_context *nv, struct pipe_surface *dst, /* 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);*/ + if (src->texture && dst->texture) { + unsigned int src_linear = src->texture->tex_usage & + NOUVEAU_TEXTURE_USAGE_LINEAR; + unsigned int dst_linear = dst->texture->tex_usage & + NOUVEAU_TEXTURE_USAGE_LINEAR; + if (src_linear ^ dst_linear) { + nv->surface_copy = nv04_surface_copy_swizzle; + nv->surf_dst = dst; + nv->surf_src = src; + return 0; + } } /* NV_CONTEXT_SURFACES_2D has buffer alignment restrictions, fallback @@ -359,10 +384,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSwzSurf, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_NOTIFY, 1); - OUT_RING (chan, nvc->sync_notifier->handle); - BEGIN_RING(chan, nvc->NvSwzSurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); - OUT_RING (chan, nvc->channel->vram->handle); if (chipset < 0x10) { class = NV04_SCALED_IMAGE_FROM_MEMORY; @@ -381,22 +402,6 @@ nouveau_surface_channel_create_nv04(struct nouveau_channel_context *nvc) } BIND_RING (chan, nvc->NvSIFM, nvc->next_subchannel++); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - OUT_RING (chan, nvc->channel->vram->handle); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); - OUT_RING (chan, nvc->NvSwzSurf->handle); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_PATTERN, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_ROP, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA1, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_BETA4, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, nvc->NvSIFM, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1); - OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); return 0; } -- cgit v1.2.3