From 583bbfb3aed3ded6ca060155c1ebbd4f39138a31 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 24 Sep 2010 20:33:10 +0200 Subject: nv50: use formats table in nv50_surface.c --- src/gallium/drivers/nv50/nv50_surface.c | 63 +++++++++++---------------------- 1 file changed, 20 insertions(+), 43 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_surface.c') diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 3e61203adf..623024ce77 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -52,48 +52,26 @@ nv50_2d_format_faithful(enum pipe_format format) } } -static INLINE int -nv50_format(enum pipe_format format) +static INLINE uint8_t +nv50_2d_format(enum pipe_format format) { - switch (format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM; - case PIPE_FORMAT_B8G8R8X8_UNORM: - return NV50_2D_DST_FORMAT_X8R8G8B8_UNORM; - case PIPE_FORMAT_B8G8R8A8_SRGB: - return NV50_2D_DST_FORMAT_A8R8G8B8_SRGB; - case PIPE_FORMAT_B8G8R8X8_SRGB: - return NV50_2D_DST_FORMAT_X8R8G8B8_SRGB; - case PIPE_FORMAT_B5G6R5_UNORM: - return NV50_2D_DST_FORMAT_R5G6B5_UNORM; - case PIPE_FORMAT_B5G5R5A1_UNORM: - return NV50_2D_DST_FORMAT_A1R5G5B5_UNORM; - case PIPE_FORMAT_B10G10R10A2_UNORM: - return NV50_2D_DST_FORMAT_A2R10G10B10_UNORM; - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_R8_UNORM: - return NV50_2D_DST_FORMAT_R8_UNORM; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - return NV50_2D_DST_FORMAT_R32G32B32A32_FLOAT; - case PIPE_FORMAT_R32G32B32_FLOAT: - return NV50_2D_DST_FORMAT_R32G32B32X32_FLOAT; - case PIPE_FORMAT_Z32_FLOAT: - return NV50_2D_DST_FORMAT_R32_FLOAT; + uint8_t id = nv50_format_table[format].rt; - /* only because we require src format == dst format: */ - case PIPE_FORMAT_R16G16_SNORM: - case PIPE_FORMAT_R16G16_UNORM: - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM; - case PIPE_FORMAT_L8A8_UNORM: - case PIPE_FORMAT_B4G4R4A4_UNORM: - return NV50_2D_DST_FORMAT_R16_UNORM; + /* Hardware values for color formats range from 0xc0 to 0xff, + * but the 2D engine doesn't support all of them. + */ + if ((id >= 0xc0) && (0xff0843e080608409ULL & (1ULL << (id - 0xc0)))) + return id; + switch (util_format_get_blocksize(format)) { + case 1: + return NV50_2D_DST_FORMAT_R8_UNORM; + case 2: + return NV50_2D_DST_FORMAT_R16_UNORM; + case 4: + return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM; default: - return -1; + return 0; } } @@ -107,8 +85,8 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT; int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD); - format = nv50_format(ps->format); - if (format < 0) { + format = nv50_2d_format(ps->format); + if (!format) { NOUVEAU_ERR("invalid/unsupported surface format: %s\n", util_format_name(ps->format)); return 1; @@ -237,8 +215,8 @@ nv50_clear_render_target(struct pipe_context *pipe, union util_color uc; util_pack_color(rgba, dst->format, &uc); - format = nv50_format(dst->format); - if (format < 0) + format = nv50_2d_format(dst->format); + if (!format) return; ret = MARK_RING (chan, 16 + 32, 2); @@ -258,7 +236,6 @@ nv50_clear_render_target(struct pipe_context *pipe, OUT_RING (chan, dsty); OUT_RING (chan, width); OUT_RING (chan, height); - } void -- cgit v1.2.3 From 2ef1d759b34fb6e9795d70a7c7b6c6c274c64bf8 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 24 Sep 2010 22:46:51 +0200 Subject: nv50: use CLEAR_BUFFERS for surface fills The 2D engine's fill doesn't seem suited for RGBA32F or ZS buffers. --- src/gallium/drivers/nv50/nv50_reg.h | 3 + src/gallium/drivers/nv50/nv50_screen.c | 3 + src/gallium/drivers/nv50/nv50_surface.c | 110 +++++++++++++++++++++++++------- 3 files changed, 94 insertions(+), 22 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_surface.c') diff --git a/src/gallium/drivers/nv50/nv50_reg.h b/src/gallium/drivers/nv50/nv50_reg.h index 365576fdd0..949838b33f 100644 --- a/src/gallium/drivers/nv50/nv50_reg.h +++ b/src/gallium/drivers/nv50/nv50_reg.h @@ -1018,6 +1018,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NV50TCL_FP_START_ID 0x00001414 #define NV50TCL_GP_VERTEX_OUTPUT_COUNT 0x00001420 #define NV50TCL_VB_ELEMENT_BASE 0x00001434 +#define NV50TCL_CLEAR_FLAGS 0x0000143c +#define NV50TCL_CLEAR_FLAGS_OGL (1 << 0) +#define NV50TCL_CLEAR_FLAGS_D3D (1 << 4) #define NV50TCL_INSTANCE_BASE 0x00001438 #define NV50TCL_CODE_CB_FLUSH 0x00001440 #define NV50TCL_BIND_TSC(x) (0x00001444+((x)*8)) diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 7c9342b747..c5115372ed 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -457,6 +457,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); OUT_RING (chan, 8); + BEGIN_RING(chan, screen->tesla, NV50TCL_CLEAR_FLAGS, 1); + OUT_RING (chan, NV50TCL_CLEAR_FLAGS_D3D); + /* constant buffers for immediates and VP/FP parameters */ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4, &screen->constbuf_misc[0]); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 623024ce77..3f3166261b 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -199,7 +199,6 @@ nv50_surface_copy(struct pipe_context *pipe, nv50_miptree_surface_del(ps_dst); } -/* XXX this should probably look more along the lines of nv50_clear */ static void nv50_clear_render_target(struct pipe_context *pipe, struct pipe_surface *dst, @@ -209,33 +208,99 @@ nv50_clear_render_target(struct pipe_context *pipe, { struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; - struct nouveau_channel *chan = screen->eng2d->channel; - struct nouveau_grobj *eng2d = screen->eng2d; - int format, ret; - union util_color uc; - util_pack_color(rgba, dst->format, &uc); + struct nouveau_channel *chan = screen->base.channel; + struct nouveau_grobj *tesla = screen->tesla; + struct nv50_miptree *mt = nv50_miptree(dst->texture); + struct nouveau_bo *bo = mt->base.bo; - format = nv50_2d_format(dst->format); - if (!format) - return; + BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4); + OUT_RINGf (chan, rgba[0]); + OUT_RINGf (chan, rgba[1]); + OUT_RINGf (chan, rgba[2]); + OUT_RINGf (chan, rgba[3]); - ret = MARK_RING (chan, 16 + 32, 2); - if (ret) + if (MARK_RING(chan, 18, 2)) return; - ret = nv50_surface_set(screen, dst, 1); - if (ret) + BEGIN_RING(chan, tesla, NV50TCL_RT_CONTROL, 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, tesla, NV50TCL_RT_ADDRESS_HIGH(0), 5); + OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (chan, nv50_format_table[dst->format].rt); + OUT_RING (chan, mt->level[dst->level].tile_mode << 4); + OUT_RING (chan, 0); + BEGIN_RING(chan, tesla, NV50TCL_RT_HORIZ(0), 2); + OUT_RING (chan, dst->width); + OUT_RING (chan, dst->height); + BEGIN_RING(chan, tesla, NV50TCL_RT_ARRAY_MODE, 1); + OUT_RING (chan, 1); + + /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */ + + BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2); + OUT_RING (chan, (width << 16) | dstx); + OUT_RING (chan, (height << 16) | dsty); + + BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1); + OUT_RING (chan, 0x3c); + + nv50->dirty |= NV50_NEW_FRAMEBUFFER; +} + +static void +nv50_clear_depth_stencil(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ + struct nv50_context *nv50 = nv50_context(pipe); + struct nv50_screen *screen = nv50->screen; + struct nouveau_channel *chan = screen->base.channel; + struct nouveau_grobj *tesla = screen->tesla; + struct nv50_miptree *mt = nv50_miptree(dst->texture); + struct nouveau_bo *bo = mt->base.bo; + uint32_t mode = 0; + + if (clear_flags & PIPE_CLEAR_DEPTH) { + BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1); + OUT_RINGf (chan, depth); + mode |= NV50TCL_CLEAR_BUFFERS_Z; + } + + if (clear_flags & PIPE_CLEAR_STENCIL) { + BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1); + OUT_RING (chan, stencil & 0xff); + mode |= NV50TCL_CLEAR_BUFFERS_S; + } + + if (MARK_RING(chan, 17, 2)) return; - BEGIN_RING(chan, eng2d, NV50_2D_DRAW_SHAPE, 3); - OUT_RING (chan, NV50_2D_DRAW_SHAPE_RECTANGLES); - OUT_RING (chan, format); - OUT_RING (chan, uc.ui); - BEGIN_RING(chan, eng2d, NV50_2D_DRAW_POINT32_X(0), 4); - OUT_RING (chan, dstx); - OUT_RING (chan, dsty); - OUT_RING (chan, width); - OUT_RING (chan, height); + BEGIN_RING(chan, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5); + OUT_RELOCh(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RELOCl(chan, bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + OUT_RING (chan, nv50_format_table[dst->format].rt); + OUT_RING (chan, mt->level[dst->level].tile_mode << 4); + OUT_RING (chan, 0); + BEGIN_RING(chan, tesla, NV50TCL_ZETA_ENABLE, 1); + OUT_RING (chan, 1); + BEGIN_RING(chan, tesla, NV50TCL_ZETA_HORIZ, 3); + OUT_RING (chan, dst->width); + OUT_RING (chan, dst->height); + OUT_RING (chan, (1 << 16) | 1); + + BEGIN_RING(chan, tesla, NV50TCL_VIEWPORT_HORIZ(0), 2); + OUT_RING (chan, (width << 16) | dstx); + OUT_RING (chan, (height << 16) | dsty); + + BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1); + OUT_RING (chan, mode); + + nv50->dirty |= NV50_NEW_FRAMEBUFFER; } void @@ -243,6 +308,7 @@ nv50_init_surface_functions(struct nv50_context *nv50) { nv50->pipe.resource_copy_region = nv50_surface_copy; nv50->pipe.clear_render_target = nv50_clear_render_target; + nv50->pipe.clear_depth_stencil = nv50_clear_depth_stencil; } -- cgit v1.2.3 From 9c439e3c7af7fd1704d44e3ba1a013de7febde37 Mon Sep 17 00:00:00 2001 From: Xavier Chantry Date: Fri, 15 Oct 2010 15:53:13 +0200 Subject: nv50: apply layout_mask to tile_flags The tile_flags now store more than just nv50 page table entry bits. --- src/gallium/drivers/nv50/nv50_context.h | 3 +++ src/gallium/drivers/nv50/nv50_surface.c | 2 +- src/gallium/drivers/nv50/nv50_transfer.c | 10 +++++----- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nv50/nv50_surface.c') diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index ac69c7848e..bf6a577188 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -26,6 +26,9 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); +#define nouveau_bo_tile_layout(nvbo) \ + ((nvbo)->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) + /* Constant buffer assignment */ #define NV50_CB_PMISC 0 #define NV50_CB_PVP 1 diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 3f3166261b..f70c138fe1 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -92,7 +92,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) return 1; } - if (!bo->tile_flags) { + if (!nouveau_bo_tile_layout(bo)) { BEGIN_RING(chan, eng2d, mthd, 2); OUT_RING (chan, format); OUT_RING (chan, 1); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index f973cf24b9..0cc2f4a837 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -45,7 +45,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, WAIT_RING (chan, 14); - if (!src_bo->tile_flags) { + if (!nouveau_bo_tile_layout(src_bo)) { BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1); OUT_RING (chan, 1); @@ -64,7 +64,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, OUT_RING (chan, sz); /* copying only 1 zslice per call */ } - if (!dst_bo->tile_flags) { + if (!nouveau_bo_tile_layout(dst_bo)) { BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1); OUT_RING (chan, 1); @@ -95,14 +95,14 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2); OUT_RELOCl(chan, src_bo, src_offset, src_reloc); OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc); - if (src_bo->tile_flags) { + if (nouveau_bo_tile_layout(src_bo)) { BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1); OUT_RING (chan, (sy << 16) | (sx * cpp)); } else { src_offset += (line_count * src_pitch); } - if (dst_bo->tile_flags) { + if (nouveau_bo_tile_layout(dst_bo)) { BEGIN_RING(chan, m2mf, NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1); OUT_RING (chan, (dy << 16) | (dx * cpp)); @@ -280,7 +280,7 @@ nv50_upload_sifc(struct nv50_context *nv50, MARK_RING (chan, 32, 2); /* flush on lack of space or relocs */ - if (bo->tile_flags) { + if (nouveau_bo_tile_layout(bo)) { BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5); OUT_RING (chan, dst_format); OUT_RING (chan, 0); -- cgit v1.2.3