From 0a3f0ff2645d03d5f572cc26932595b8df400505 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Tue, 30 Aug 2011 13:08:27 +0200 Subject: [PATCH] nv50: add support for linear textures and render targets --- src/gallium/drivers/nouveau/nouveau_winsys.h | 2 ++ src/gallium/drivers/nv50/nv50_miptree.c | 3 ++ .../drivers/nv50/nv50_state_validate.c | 27 ++++++++++++----- src/gallium/drivers/nv50/nv50_surface.c | 12 +++++++- src/gallium/drivers/nv50/nv50_tex.c | 29 ++++++++++++++++--- src/gallium/drivers/nv50/nv50_winsys.h | 2 +- src/gallium/drivers/nvc0/nvc0_winsys.h | 2 +- 7 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 484f870bd86..37416f78bc1 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -17,6 +17,8 @@ #define NV04_PFIFO_MAX_PACKET_LEN 2047 #endif +#define NOUVEAU_RESOURCE_FLAG_LINEAR (PIPE_RESOURCE_FLAG_DRV_PRIV << 0) + static INLINE uint32_t nouveau_screen_transfer_flags(unsigned pipe) { diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 3537681d4d7..239be19d604 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -107,6 +107,9 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed) if (!compressed) tile_flags &= ~0x30000; + if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR)) + tile_flags &= ~0x3ff00; + return tile_flags; } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 369daf8ffa6..05f32ea78d2 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -31,13 +31,26 @@ nv50_validate_fb(struct nv50_context *nv50) OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); OUT_RING (chan, nv50_format_table[sf->base.format].rt); - OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); - OUT_RING (chan, mt->layer_stride >> 2); - BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2); - OUT_RING (chan, sf->width); - OUT_RING (chan, sf->height); - BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); - OUT_RING (chan, sf->depth); + if (likely(nouveau_bo_tile_layout(bo))) { + OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); + OUT_RING (chan, mt->layer_stride >> 2); + BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2); + OUT_RING (chan, sf->width); + OUT_RING (chan, sf->height); + BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); + OUT_RING (chan, sf->depth); + } else { + OUT_RING (chan, 0); + OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2); + OUT_RING (chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch); + OUT_RING (chan, sf->height); + BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); + OUT_RING (chan, 0); + + assert(!fb->zsbuf); + assert(!mt->ms_mode); + } ms_mode = mt->ms_mode; diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 57339f89a36..b0a8497c1e7 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -290,11 +290,19 @@ nv50_clear_render_target(struct pipe_context *pipe, OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2); - OUT_RING (chan, sf->width); + if (nouveau_bo_tile_layout(bo)) + OUT_RING(chan, sf->width); + else + OUT_RING(chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch); OUT_RING (chan, sf->height); BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1); OUT_RING (chan, 1); + if (!nouveau_bo_tile_layout(bo)) { + BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); + OUT_RING (chan, 0); + } + /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */ BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2); @@ -324,6 +332,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, struct nouveau_bo *bo = mt->base.bo; uint32_t mode = 0; + assert(nouveau_bo_tile_layout(bo)); /* ZETA cannot be linear */ + if (clear_flags & PIPE_CLEAR_DEPTH) { BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1); OUT_RINGf (chan, depth); diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 73db9ca4fd1..9436ac295de 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -51,6 +51,24 @@ nv50_tic_swizzle(uint32_t tc, unsigned swz, boolean tex_int) } } +static void +nv50_init_tic_entry_linear(uint32_t *tic, struct pipe_resource *res) +{ + if (res->target == PIPE_BUFFER) { + tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER; + tic[4] = res->width0; + } else { + struct nv50_miptree *mt = nv50_miptree(res); + + tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT; + if (res->target != PIPE_TEXTURE_RECT) + tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; + tic[3] = mt->level[0].pitch; + tic[4] = res->width0; + tic[5] = (1 << 16) | res->height0; + } +} + struct pipe_sampler_view * nv50_create_sampler_view(struct pipe_context *pipe, struct pipe_resource *texture, @@ -105,6 +123,11 @@ nv50_create_sampler_view(struct pipe_context *pipe, if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) tic[2] |= NV50_TIC_2_COLORSPACE_SRGB; + if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) { + nv50_init_tic_entry_linear(tic, texture); + return &view->pipe; + } + if (mt->base.base.target != PIPE_TEXTURE_RECT) tic[2] |= NV50_TIC_2_NORMALIZED_COORDS; @@ -147,6 +170,7 @@ nv50_create_sampler_view(struct pipe_context *pipe, tic[2] |= NV50_TIC_2_TARGET_2D_ARRAY; break; case PIPE_BUFFER: + assert(0); /* should be linear and handled above ! */ tic[2] |= NV50_TIC_2_TARGET_BUFFER | NV50_TIC_2_LINEAR; break; default: @@ -154,10 +178,7 @@ nv50_create_sampler_view(struct pipe_context *pipe, return FALSE; } - if (mt->base.base.target == PIPE_BUFFER) - tic[3] = mt->base.base.width0; - else - tic[3] = 0x00300000; + tic[3] = 0x00300000; tic[4] = (1 << 31) | (mt->base.base.width0 << mt->ms_x); diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h index afa2a00c7a2..694c78a2fbd 100644 --- a/src/gallium/drivers/nv50/nv50_winsys.h +++ b/src/gallium/drivers/nv50/nv50_winsys.h @@ -41,7 +41,7 @@ int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); static inline uint32_t -nouveau_bo_tile_layout(struct nouveau_bo *bo) +nouveau_bo_tile_layout(const struct nouveau_bo *bo) { return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK; } diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h index 6519ce8e19f..0fcf9944c14 100644 --- a/src/gallium/drivers/nvc0/nvc0_winsys.h +++ b/src/gallium/drivers/nvc0/nvc0_winsys.h @@ -39,7 +39,7 @@ int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); static inline uint32_t -nouveau_bo_tile_layout(struct nouveau_bo *bo) +nouveau_bo_tile_layout(const struct nouveau_bo *bo) { return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK; } -- 2.30.2