diff options
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_miptree.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 46 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_query.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 65 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state.c | 19 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state_validate.c | 92 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_surface.c | 13 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tex.c | 31 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_texture.h | 71 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_transfer.c | 76 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_vbo.c | 197 |
13 files changed, 470 insertions, 199 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index e02afc4be9..6e8f4f9750 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -31,15 +31,23 @@ static void nv50_flush(struct pipe_context *pipe, unsigned flags, struct pipe_fence_handle **fence) { - struct nv50_context *nv50 = (struct nv50_context *)pipe; - - FIRE_RING(nv50->screen->base.channel); + struct nv50_context *nv50 = nv50_context(pipe); + struct nouveau_channel *chan = nv50->screen->base.channel; + struct nouveau_grobj *eng2d = nv50->screen->eng2d; + + /* We need this in the ddx for reliable composite, not sure what we're + * actually flushing. We generate all our own flushes with flags = 0. */ + WAIT_RING(chan, 3); + BEGIN_RING(chan, eng2d, 0x0110, 1); + OUT_RING (chan, 0); + + FIRE_RING(chan); } static void nv50_destroy(struct pipe_context *pipe) { - struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nv50_context *nv50 = nv50_context(pipe); draw_destroy(nv50->draw); FREE(nv50); @@ -112,5 +120,3 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id) return &nv50->pipe; } - - diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 9b8cc4d37d..4de6e8cfa2 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -71,6 +71,7 @@ struct nv50_sampler_stateobj { struct nv50_miptree_level { int *image_offset; unsigned pitch; + unsigned tile_mode; }; struct nv50_miptree { @@ -119,6 +120,7 @@ struct nv50_state { struct nouveau_stateobj *fragprog; struct nouveau_stateobj *vtxfmt; struct nouveau_stateobj *vtxbuf; + struct nouveau_stateobj *vtxattr; }; struct nv50_context { diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 6b605ba416..dd1b0303bd 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -42,8 +42,14 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) mt->base.screen = pscreen; switch (pt->format) { + case PIPE_FORMAT_Z32_FLOAT: + tile_flags = 0x4800; + break; case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z16_UNORM: + tile_flags = 0x1800; + break; + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: tile_flags = 0x2800; break; default: @@ -81,20 +87,27 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) lvl->image_offset = CALLOC(mt->image_nr, sizeof(int)); lvl->pitch = align(pt->width[l] * pt->block.size, 64); + lvl->tile_mode = tile_mode; width = MAX2(1, width >> 1); height = MAX2(1, height >> 1); depth = MAX2(1, depth >> 1); + + if (tile_mode && height <= (tile_h >> 1)) { + tile_mode--; + tile_h >>= 1; + } } for (i = 0; i < mt->image_nr; i++) { for (l = 0; l <= pt->last_level; l++) { struct nv50_miptree_level *lvl = &mt->level[l]; int size; + tile_h = 1 << (lvl->tile_mode + 2); size = align(pt->width[l], 8) * pt->block.size; size = align(size, 64); - size *= align(pt->height[l], tile_h) * pt->block.size; + size *= align(pt->height[l], tile_h); lvl->image_offset[i] = mt->total_size; @@ -103,12 +116,12 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp) } ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size, - tile_mode, tile_flags, &mt->bo); + mt->level[0].tile_mode, tile_flags, &mt->bo); if (ret) { FREE(mt); return NULL; } - + return &mt->base; } @@ -145,7 +158,7 @@ nv50_miptree_destroy(struct pipe_texture *pt) struct nv50_miptree *mt = nv50_miptree(pt); nouveau_bo_ref(NULL, &mt->bo); - FREE(mt); + FREE(mt); } static struct pipe_surface * @@ -188,8 +201,8 @@ nv50_miptree_surface_del(struct pipe_surface *ps) { struct nv50_surface *s = nv50_surface(ps); - pipe_texture_reference(&ps->texture, NULL); - FREE(s); + pipe_texture_reference(&ps->texture, NULL); + FREE(s); } void diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index 5f7d06dbec..289c3485e0 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -251,7 +251,7 @@ alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx) if (pc->r_temp[idx] || pc->r_temp[idx + 1] || pc->r_temp[idx + 2] || pc->r_temp[idx + 3]) - return alloc_temp4(pc, dst, idx + 1); + return alloc_temp4(pc, dst, idx + 4); for (i = 0; i < 4; i++) { dst[i] = CALLOC_STRUCT(nv50_reg); @@ -296,7 +296,7 @@ kill_temp_temp(struct nv50_pc *pc) static int ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w) { - pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * r * sizeof(float)), + pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * 4 * sizeof(float)), (pc->immd_nr + 1) * 4 * sizeof(float)); pc->immd_buf[(pc->immd_nr * 4) + 0] = x; pc->immd_buf[(pc->immd_nr * 4) + 1] = y; @@ -1014,6 +1014,7 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask, break; } + /* some cards need t[0]'s hw index to be a multiple of 4 */ alloc_temp4(pc, t, 0); if (proj) { @@ -1809,10 +1810,10 @@ nv50_program_tx_prep(struct nv50_pc *pc) const struct tgsi_full_immediate *imm = &p.FullToken.FullImmediate; - ctor_immd(pc, imm->u.ImmediateFloat32[0].Float, - imm->u.ImmediateFloat32[1].Float, - imm->u.ImmediateFloat32[2].Float, - imm->u.ImmediateFloat32[3].Float); + ctor_immd(pc, imm->u[0].Float, + imm->u[1].Float, + imm->u[2].Float, + imm->u[3].Float); } break; case TGSI_TOKEN_TYPE_DECLARATION: @@ -2221,9 +2222,9 @@ nv50_program_upload_data(struct nv50_context *nv50, float *map, while (count) { unsigned nr = count > 2047 ? 2047 : count; - BEGIN_RING(chan, tesla, 0x00000f00, 1); + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, (cbuf << 0) | (start << 8)); - BEGIN_RING(chan, tesla, 0x40000f04, nr); + BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr); OUT_RINGp (chan, map, nr); map += nr; @@ -2345,7 +2346,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) } so = so_new(4,2); - so_method(so, nv50->screen->tesla, 0x1280, 3); + so_method(so, nv50->screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PUPLOAD << 16) | 0x0800); //(p->exec_size * 4)); @@ -2364,9 +2365,9 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) continue; } - BEGIN_RING(chan, tesla, 0x0f00, 1); + BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1); OUT_RING (chan, (start << 8) | NV50_CB_PUPLOAD); - BEGIN_RING(chan, tesla, 0x40000f04, nr); + BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr); OUT_RINGp (chan, up + start, nr); start += nr; @@ -2399,15 +2400,15 @@ nv50_vertprog_validate(struct nv50_context *nv50) NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, 0x1650, 2); + so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2); so_data (so, p->cfg.vp.attr[0]); so_data (so, p->cfg.vp.attr[1]); - so_method(so, tesla, 0x16b8, 1); + so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); so_data (so, p->cfg.high_result); - so_method(so, tesla, 0x16ac, 2); + so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 2); so_data (so, p->cfg.high_result); //8); so_data (so, p->cfg.high_temp); - so_method(so, tesla, 0x140c, 1); + so_method(so, tesla, NV50TCL_VP_START_ID, 1); so_data (so, 0); /* program start offset */ so_ref(so, &nv50->state.vertprog); so_ref(NULL, &so); @@ -2436,24 +2437,24 @@ nv50_fragprog_validate(struct nv50_context *nv50) NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); - so_method(so, tesla, 0x1904, 4); + so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4); so_data (so, p->cfg.fp.regs[0]); /* 0x01000404 / 0x00040404 */ so_data (so, 0x00000004); so_data (so, 0x00000000); so_data (so, 0x00000000); - so_method(so, tesla, 0x16bc, p->cfg.fp.high_map); + so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), p->cfg.fp.high_map); for (i = 0; i < p->cfg.fp.high_map; i++) so_data(so, p->cfg.fp.map[i]); - so_method(so, tesla, 0x1988, 2); + so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 2); so_data (so, p->cfg.fp.regs[1]); /* 0x08040404 / 0x0f000401 */ so_data (so, p->cfg.high_temp); - so_method(so, tesla, 0x1298, 1); + so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1); so_data (so, p->cfg.high_result); - so_method(so, tesla, 0x19a8, 1); + so_method(so, tesla, NV50TCL_FP_CTRL_UNK19A8, 1); so_data (so, p->cfg.fp.regs[2]); - so_method(so, tesla, 0x196c, 1); + so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1); so_data (so, p->cfg.fp.regs[3]); - so_method(so, tesla, 0x1414, 1); + so_method(so, tesla, NV50TCL_FP_START_ID, 1); so_data (so, 0); /* program start offset */ so_ref(so, &nv50->state.fragprog); so_ref(NULL, &so); @@ -2478,4 +2479,3 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) p->translated = 0; } - diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 940e04365f..5305c93d59 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -94,7 +94,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq) struct nv50_query *q = nv50_query(pq); WAIT_RING (chan, 5); - BEGIN_RING(chan, tesla, 0x1b00, 4); + BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4); OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); OUT_RING (chan, 0x00000000); @@ -107,13 +107,13 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq, boolean wait, uint64_t *result) { struct nv50_query *q = nv50_query(pq); - - /*XXX: Want to be able to return FALSE here instead of blocking - * until the result is available.. - */ + int ret; if (!q->ready) { - nouveau_bo_map(q->bo, NOUVEAU_BO_RD); + ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD | + wait ? 0 : NOUVEAU_BO_NOWAIT); + if (ret) + return false; q->result = ((uint32_t *)q->bo->map)[1]; q->ready = TRUE; nouveau_bo_unmap(q->bo); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index fd39fa738b..c7f80a2203 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -37,8 +37,17 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_R5G6B5_UNORM: + return TRUE; + default: + break; + } + } else + if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { + switch (format) { + case PIPE_FORMAT_Z32_FLOAT: case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8Z24_UNORM: return TRUE; default: break; @@ -101,6 +110,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) return 1; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: return 0; + case PIPE_CAP_TGSI_CONT_SUPPORTED: + return 0; + case PIPE_CAP_BLEND_EQUATION_SEPARATE: + return 1; case NOUVEAU_CAP_HW_VTXBUF: return 1; case NOUVEAU_CAP_HW_IDXBUF: @@ -176,7 +189,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) nv50_transfer_init_screen_functions(pscreen); /* DMA engine object */ - ret = nouveau_grobj_alloc(chan, 0xbeef5039, 0x5039, &screen->m2mf); + ret = nouveau_grobj_alloc(chan, 0xbeef5039, + NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf); if (ret) { NOUVEAU_ERR("Error creating M2MF object: %d\n", ret); nv50_screen_destroy(pscreen); @@ -185,7 +199,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BIND_RING(chan, screen->m2mf, 1); /* 2D object */ - ret = nouveau_grobj_alloc(chan, 0xbeef502d, 0x502d, &screen->eng2d); + ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); if (ret) { NOUVEAU_ERR("Error creating 2D object: %d\n", ret); nv50_screen_destroy(pscreen); @@ -196,14 +210,15 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) /* 3D object */ switch (chipset & 0xf0) { case 0x50: - tesla_class = 0x5097; + tesla_class = NV50TCL; break; case 0x80: case 0x90: - tesla_class = 0x8297; + /* this stupid name should be corrected. */ + tesla_class = NV54TCL; break; case 0xa0: - tesla_class = 0x8397; + tesla_class = NVA0TCL; break; default: NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset); @@ -217,7 +232,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } - ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla); + ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, + &screen->tesla); if (ret) { NOUVEAU_ERR("Error creating 3D object: %d\n", ret); nv50_screen_destroy(pscreen); @@ -235,7 +251,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) /* Static M2MF init */ so = so_new(32, 0); - so_method(so, screen->m2mf, 0x0180, 3); + so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); so_data (so, screen->sync->handle); so_data (so, chan->vram->handle); so_data (so, chan->vram->handle); @@ -278,9 +294,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_method(so, screen->tesla, 0x13bc, 1); so_data (so, 0x54); + /* origin is top left (set to 1 for bottom left) */ so_method(so, screen->tesla, 0x13ac, 1); - so_data (so, 1); - so_method(so, screen->tesla, 0x16b8, 1); + so_data (so, 0); + so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); so_data (so, 8); /* constant buffers for immediates and VP/FP parameters */ @@ -318,33 +335,33 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_data (so, 0x000BBNP1); */ - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PMISC << 16) | 0x00000800); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000001 | (NV50_CB_PMISC << 12)); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000031 | (NV50_CB_PMISC << 12)); - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PVP << 16) | 0x00000800); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000101 | (NV50_CB_PVP << 12)); - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_PFP << 16) | 0x00000800); - so_method(so, screen->tesla, 0x1694, 1); + so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); so_data (so, 0x00000131 | (NV50_CB_PFP << 12)); /* Texture sampler/image unit setup - we abuse the constant buffer @@ -358,13 +375,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_TIC << 16) | 0x0800); - so_method(so, screen->tesla, 0x1574, 3); + so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | @@ -377,13 +394,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) return NULL; } - so_method(so, screen->tesla, 0x1280, 3); + so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); so_data (so, (NV50_CB_TSC << 16) | 0x0800); - so_method(so, screen->tesla, 0x155c, 3); + so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | @@ -393,7 +410,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) /* Vertex array limits - max them out */ for (i = 0; i < 16; i++) { - so_method(so, screen->tesla, 0x1080 + (i * 8), 2); + so_method(so, screen->tesla, NV50TCL_UNK1080_OFFSET_HIGH(i), 2); so_data (so, 0x000000ff); so_data (so, 0xffffffff); } @@ -405,6 +422,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) so_method(so, screen->tesla, 0x1234, 1); so_data (so, 1); + /* activate first scissor rectangle */ + so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE, 1); + so_data (so, 1); + so_emit(chan, so); so_ref (so, &screen->static_init); so_ref (NULL, &so); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 116866a8e7..ef4154d303 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -205,11 +205,16 @@ nv50_sampler_state_create(struct pipe_context *pipe, } limit = CLAMP(cso->lod_bias, -16.0, 15.0); - tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 11; + tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 12; tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) | ((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8); + tsc[4] = fui(cso->border_color[0]); + tsc[5] = fui(cso->border_color[1]); + tsc[6] = fui(cso->border_color[2]); + tsc[7] = fui(cso->border_color[3]); + sso->normalized = cso->normalized_coords; return (void *)sso; } @@ -404,35 +409,35 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } - /*XXX: yes, I know they're backwards.. header needs fixing */ + /* XXX: keep hex values until header is updated (names reversed) */ if (cso->stencil[0].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5); + so_method(so, tesla, 0x1380, 8); so_data (so, 1); so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); - so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3); so_data (so, cso->stencil[0].ref_value); so_data (so, cso->stencil[0].writemask); so_data (so, cso->stencil[0].valuemask); } else { - so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1); + so_method(so, tesla, 0x1380, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, tesla, 0x1594, 5); so_data (so, 1); so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); + so_method(so, tesla, 0x0f54, 3); so_data (so, cso->stencil[1].ref_value); so_data (so, cso->stencil[1].writemask); so_data (so, cso->stencil[1].valuemask); } else { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1); + so_method(so, tesla, 0x1594, 1); so_data (so, 0); } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index 0caf4b4e91..99d5b96e45 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -55,15 +55,15 @@ nv50_state_validate_fb(struct nv50_context *nv50) NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0); switch (fb->cbufs[i]->format) { case PIPE_FORMAT_A8R8G8B8_UNORM: - so_data(so, 0xcf); + so_data(so, NV50TCL_RT_FORMAT_A8R8G8B8_UNORM); break; case PIPE_FORMAT_R5G6B5_UNORM: - so_data(so, 0xe8); + so_data(so, NV50TCL_RT_FORMAT_R5G6B5_UNORM); break; default: NOUVEAU_ERR("AIIII unknown format %s\n", pf_name(fb->cbufs[i]->format)); - so_data(so, 0xe6); + so_data(so, NV50TCL_RT_FORMAT_X8R8G8B8_UNORM); break; } so_data(so, bo->tile_mode << 4); @@ -92,16 +92,22 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0); switch (fb->zsbuf->format) { + case PIPE_FORMAT_Z32_FLOAT: + so_data(so, NV50TCL_ZETA_FORMAT_Z32_FLOAT); + break; case PIPE_FORMAT_Z24S8_UNORM: - so_data(so, 0x16); + so_data(so, NV50TCL_ZETA_FORMAT_Z24S8_UNORM); + break; + case PIPE_FORMAT_X8Z24_UNORM: + so_data(so, NV50TCL_ZETA_FORMAT_X8Z24_UNORM); break; - case PIPE_FORMAT_Z16_UNORM: - so_data(so, 0x15); + case PIPE_FORMAT_S8Z24_UNORM: + so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM); break; default: NOUVEAU_ERR("AIIII unknown format %s\n", pf_name(fb->zsbuf->format)); - so_data(so, 0x16); + so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM); break; } so_data(so, bo->tile_mode << 4); @@ -109,7 +115,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, 0x1538, 1); so_data (so, 1); - so_method(so, tesla, 0x1228, 3); + so_method(so, tesla, NV50TCL_ZETA_HORIZ, 3); so_data (so, fb->zsbuf->width); so_data (so, fb->zsbuf->height); so_data (so, 0x00010001); @@ -118,12 +124,18 @@ nv50_state_validate_fb(struct nv50_context *nv50) so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2); so_data (so, w << 16); so_data (so, h << 16); - so_method(so, tesla, 0x0e04, 2); + /* set window lower left corner */ + so_method(so, tesla, NV50TCL_WINDOW_LEFT, 2); + so_data (so, 0); + so_data (so, 0); + /* set screen scissor rectangle */ + so_method(so, tesla, NV50TCL_SCREEN_SCISSOR_HORIZ, 2); so_data (so, w << 16); so_data (so, h << 16); - so_method(so, tesla, 0xdf8, 2); - so_data (so, 0); - so_data (so, h); + + /* we set scissors to framebuffer size when they're 'turned off' */ + nv50->dirty |= NV50_NEW_SCISSOR; + so_ref(NULL, &nv50->state.scissor); so_ref(so, &nv50->state.fb); so_ref(NULL, &so); @@ -136,7 +148,32 @@ nv50_state_emit(struct nv50_context *nv50) struct nouveau_channel *chan = screen->base.channel; if (nv50->pctx_id != screen->cur_pctx) { - nv50->state.dirty |= 0xffffffff; + if (nv50->state.fb) + nv50->state.dirty |= NV50_NEW_FRAMEBUFFER; + if (nv50->state.blend) + nv50->state.dirty |= NV50_NEW_BLEND; + if (nv50->state.zsa) + nv50->state.dirty |= NV50_NEW_ZSA; + if (nv50->state.vertprog) + nv50->state.dirty |= NV50_NEW_VERTPROG; + if (nv50->state.fragprog) + nv50->state.dirty |= NV50_NEW_FRAGPROG; + if (nv50->state.rast) + nv50->state.dirty |= NV50_NEW_RASTERIZER; + if (nv50->state.blend_colour) + nv50->state.dirty |= NV50_NEW_BLEND_COLOUR; + if (nv50->state.stipple) + nv50->state.dirty |= NV50_NEW_STIPPLE; + if (nv50->state.scissor) + nv50->state.dirty |= NV50_NEW_SCISSOR; + if (nv50->state.viewport) + nv50->state.dirty |= NV50_NEW_VIEWPORT; + if (nv50->state.tsc_upload) + nv50->state.dirty |= NV50_NEW_SAMPLER; + if (nv50->state.tic_upload) + nv50->state.dirty |= NV50_NEW_TEXTURE; + if (nv50->state.vtxfmt && nv50->state.vtxbuf) + nv50->state.dirty |= NV50_NEW_ARRAYS; screen->cur_pctx = nv50->pctx_id; } @@ -167,6 +204,8 @@ nv50_state_emit(struct nv50_context *nv50) if (nv50->state.dirty & NV50_NEW_ARRAYS) { so_emit(chan, nv50->state.vtxfmt); so_emit(chan, nv50->state.vtxbuf); + if (nv50->state.vtxattr) + so_emit(chan, nv50->state.vtxattr); } nv50->state.dirty = 0; @@ -232,13 +271,13 @@ nv50_state_validate(struct nv50_context *nv50) nv50->state.scissor_enabled = rast->scissor; so = so_new(3, 0); - so_method(so, tesla, 0x0ff4, 2); + so_method(so, tesla, NV50TCL_SCISSOR_HORIZ, 2); if (nv50->state.scissor_enabled) { - so_data(so, ((s->maxx - s->minx) << 16) | s->minx); - so_data(so, ((s->maxy - s->miny) << 16) | s->miny); + so_data(so, (s->maxx << 16) | s->minx); + so_data(so, (s->maxy << 16) | s->miny); } else { - so_data(so, (8192 << 16)); - so_data(so, (8192 << 16)); + so_data(so, (nv50->framebuffer.width << 16)); + so_data(so, (nv50->framebuffer.height << 16)); } so_ref(so, &nv50->state.scissor); so_ref(NULL, &so); @@ -262,20 +301,22 @@ scissor_uptodate: so = so_new(12, 0); if (!bypass) { - so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3); + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3); so_data (so, fui(nv50->viewport.translate[0])); so_data (so, fui(nv50->viewport.translate[1])); so_data (so, fui(nv50->viewport.translate[2])); - so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3); + so_method(so, tesla, NV50TCL_VIEWPORT_SCALE(0), 3); so_data (so, fui(nv50->viewport.scale[0])); - so_data (so, fui(-nv50->viewport.scale[1])); + so_data (so, fui(nv50->viewport.scale[1])); so_data (so, fui(nv50->viewport.scale[2])); - so_method(so, tesla, 0x192c, 1); + + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); so_data (so, 1); + /* no idea what 0f90 does */ so_method(so, tesla, 0x0f90, 1); so_data (so, 0); } else { - so_method(so, tesla, 0x192c, 1); + so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); so_data (so, 0); so_method(so, tesla, 0x0f90, 1); so_data (so, 1); @@ -291,9 +332,10 @@ viewport_uptodate: int i; so = so_new(nv50->sampler_nr * 8 + 3, 0); - so_method(so, tesla, 0x0f00, 1); + so_method(so, tesla, NV50TCL_CB_ADDR, 1); so_data (so, NV50_CB_TSC); - so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8); + so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000, + nv50->sampler_nr * 8); for (i = 0; i < nv50->sampler_nr; i++) so_datap (so, nv50->sampler[i]->tsc, 8); so_ref(so, &nv50->state.tsc_upload); diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index 8db3b6d344..edaf4b055a 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -35,14 +35,13 @@ nv50_format(enum pipe_format format) { switch (format) { case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_Z24S8_UNORM: - return NV50_2D_DST_FORMAT_32BPP; + return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM; case PIPE_FORMAT_X8R8G8B8_UNORM: - return NV50_2D_DST_FORMAT_24BPP; + return NV50_2D_DST_FORMAT_X8R8G8B8_UNORM; case PIPE_FORMAT_R5G6B5_UNORM: - return NV50_2D_DST_FORMAT_16BPP; + return NV50_2D_DST_FORMAT_R5G6B5_UNORM; case PIPE_FORMAT_A8_UNORM: - return NV50_2D_DST_FORMAT_8BPP; + return NV50_2D_DST_FORMAT_R8_UNORM; default: return -1; } @@ -145,7 +144,7 @@ nv50_surface_copy(struct pipe_context *pipe, struct pipe_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { - struct nv50_context *nv50 = (struct nv50_context *)pipe; + struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; assert(src->format == dest->format); @@ -159,7 +158,7 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, unsigned destx, unsigned desty, unsigned width, unsigned height, unsigned value) { - struct nv50_context *nv50 = (struct nv50_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; diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index ff40c2ad81..14c68b96e1 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -32,30 +32,30 @@ nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so, switch (mt->base.format) { case PIPE_FORMAT_A8R8G8B8_UNORM: so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_8_8_8_8); break; case PIPE_FORMAT_A1R5G5B5_UNORM: so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_1_5_5_5); break; case PIPE_FORMAT_A4R4G4B4_UNORM: so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_4_4_4_4); break; case PIPE_FORMAT_R5G6B5_UNORM: so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM | - NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM | + NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM | NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM | - NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM | + NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM | NV50TIC_0_0_FMT_5_6_5); break; case PIPE_FORMAT_L8_UNORM: @@ -145,25 +145,28 @@ nv50_tex_validate(struct nv50_context *nv50) push += MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2; so = so_new(push, nv50->miptree_nr * 2); - so_method(so, tesla, 0x0f00, 1); + so_method(so, tesla, NV50TCL_CB_ADDR, 1); so_data (so, NV50_CB_TIC); for (unit = 0; unit < nv50->miptree_nr; unit++) { struct nv50_miptree *mt = nv50->miptree[unit]; - so_method(so, tesla, 0x40000f04, 8); + so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 8); if (nv50_tex_construct(nv50, so, mt, unit)) { NOUVEAU_ERR("failed tex validate\n"); so_ref(NULL, &so); return; } - so_method(so, tesla, 0x1458, 1); - so_data (so, (unit << 9) | (unit << 1) | 1); + so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1); + so_data (so, (unit << NV50TCL_SET_SAMPLER_TEX_TIC_SHIFT) | + (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | + NV50TCL_SET_SAMPLER_TEX_VALID); } for (; unit < nv50->state.miptree_nr; unit++) { - so_method(so, tesla, 0x1458, 1); - so_data (so, (unit << 1) | 0); + so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1); + so_data (so, + (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | 0); } so_ref(so, &nv50->state.tic_upload); diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h index aca622c73b..207fb039f7 100644 --- a/src/gallium/drivers/nv50/nv50_texture.h +++ b/src/gallium/drivers/nv50/nv50_texture.h @@ -14,13 +14,13 @@ #define NV50TIC_0_0_MAPA_C2 0x20000000 #define NV50TIC_0_0_MAPA_C3 0x28000000 #define NV50TIC_0_0_MAPA_ONE 0x38000000 -#define NV50TIC_0_0_MAPR_MASK 0x07000000 -#define NV50TIC_0_0_MAPR_ZERO 0x00000000 -#define NV50TIC_0_0_MAPR_C0 0x02000000 -#define NV50TIC_0_0_MAPR_C1 0x03000000 -#define NV50TIC_0_0_MAPR_C2 0x04000000 -#define NV50TIC_0_0_MAPR_C3 0x05000000 -#define NV50TIC_0_0_MAPR_ONE 0x07000000 +#define NV50TIC_0_0_MAPB_MASK 0x07000000 +#define NV50TIC_0_0_MAPB_ZERO 0x00000000 +#define NV50TIC_0_0_MAPB_C0 0x02000000 +#define NV50TIC_0_0_MAPB_C1 0x03000000 +#define NV50TIC_0_0_MAPB_C2 0x04000000 +#define NV50TIC_0_0_MAPB_C3 0x05000000 +#define NV50TIC_0_0_MAPB_ONE 0x07000000 #define NV50TIC_0_0_MAPG_MASK 0x00e00000 #define NV50TIC_0_0_MAPG_ZERO 0x00000000 #define NV50TIC_0_0_MAPG_C0 0x00400000 @@ -28,31 +28,49 @@ #define NV50TIC_0_0_MAPG_C2 0x00800000 #define NV50TIC_0_0_MAPG_C3 0x00a00000 #define NV50TIC_0_0_MAPG_ONE 0x00e00000 -#define NV50TIC_0_0_MAPB_MASK 0x001c0000 -#define NV50TIC_0_0_MAPB_ZERO 0x00000000 -#define NV50TIC_0_0_MAPB_C0 0x00080000 -#define NV50TIC_0_0_MAPB_C1 0x000c0000 -#define NV50TIC_0_0_MAPB_C2 0x00100000 -#define NV50TIC_0_0_MAPB_C3 0x00140000 -#define NV50TIC_0_0_MAPB_ONE 0x001c0000 +#define NV50TIC_0_0_MAPR_MASK 0x001c0000 +#define NV50TIC_0_0_MAPR_ZERO 0x00000000 +#define NV50TIC_0_0_MAPR_C0 0x00080000 +#define NV50TIC_0_0_MAPR_C1 0x000c0000 +#define NV50TIC_0_0_MAPR_C2 0x00100000 +#define NV50TIC_0_0_MAPR_C3 0x00140000 +#define NV50TIC_0_0_MAPR_ONE 0x001c0000 #define NV50TIC_0_0_TYPEA_MASK 0x00038000 #define NV50TIC_0_0_TYPEA_UNORM 0x00010000 -#define NV50TIC_0_0_TYPER_MASK 0x00007000 -#define NV50TIC_0_0_TYPER_UNORM 0x00002000 +#define NV50TIC_0_0_TYPEA_SNORM 0x00008000 +#define NV50TIC_0_0_TYPEA_FLOAT 0x00038000 +#define NV50TIC_0_0_TYPEB_MASK 0x00007000 +#define NV50TIC_0_0_TYPEB_UNORM 0x00002000 +#define NV50TIC_0_0_TYPEB_SNORM 0x00001000 +#define NV50TIC_0_0_TYPEB_FLOAT 0x00007000 #define NV50TIC_0_0_TYPEG_MASK 0x00000e00 #define NV50TIC_0_0_TYPEG_UNORM 0x00000400 -#define NV50TIC_0_0_TYPEB_MASK 0x000001c0 -#define NV50TIC_0_0_TYPEB_UNORM 0x00000080 -#define NV50TIC_0_0_FMT_MASK 0x0000003c +#define NV50TIC_0_0_TYPEG_SNORM 0x00000200 +#define NV50TIC_0_0_TYPEG_FLOAT 0x00000e00 +#define NV50TIC_0_0_TYPER_MASK 0x000001c0 +#define NV50TIC_0_0_TYPER_UNORM 0x00000080 +#define NV50TIC_0_0_TYPER_SNORM 0x00000040 +#define NV50TIC_0_0_TYPER_FLOAT 0x000001c0 +#define NV50TIC_0_0_FMT_MASK 0x0000003f +#define NV50TIC_0_0_FMT_32_32_32_32 0x00000001 +#define NV50TIC_0_0_FMT_16_16_16_16 0x00000003 +#define NV50TIC_0_0_FMT_32_32 0x00000004 #define NV50TIC_0_0_FMT_8_8_8_8 0x00000008 +#define NV50TIC_0_0_FMT_2_10_10_10 0x00000009 +#define NV50TIC_0_0_FMT_32 0x0000000f #define NV50TIC_0_0_FMT_4_4_4_4 0x00000012 -#define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 +/* #define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 */ +#define NV50TIC_0_0_FMT_1_5_5_5 0x00000014 #define NV50TIC_0_0_FMT_5_6_5 0x00000015 #define NV50TIC_0_0_FMT_8_8 0x00000018 +#define NV50TIC_0_0_FMT_16 0x0000001b #define NV50TIC_0_0_FMT_8 0x0000001d +#define NV50TIC_0_0_FMT_10_11_11 0x00000021 #define NV50TIC_0_0_FMT_DXT1 0x00000024 #define NV50TIC_0_0_FMT_DXT3 0x00000025 #define NV50TIC_0_0_FMT_DXT5 0x00000026 +#define NV50TIC_0_0_FMT_RGTC1 0x00000027 +#define NV50TIC_0_0_FMT_RGTC2 0x00000028 #define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff #define NV50TIC_0_1_OFFSET_LOW_SHIFT 0 @@ -102,6 +120,7 @@ #define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_EDGE 0x00000140 #define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_BORDER 0x00000180 #define NV50TSC_1_0_WRAPR_MIRROR_CLAMP 0x000001c0 +#define NV50TSC_1_0_MAX_ANISOTROPY_MASK 0x00700000 #define NV50TSC_1_1_MAGF_MASK 0x00000003 #define NV50TSC_1_1_MAGF_NEAREST 0x00000001 @@ -113,17 +132,19 @@ #define NV50TSC_1_1_MIPF_NONE 0x00000040 #define NV50TSC_1_1_MIPF_NEAREST 0x00000080 #define NV50TSC_1_1_MIPF_LINEAR 0x000000c0 +#define NV50TSC_1_1_LOD_BIAS_MASK 0x01fff000 -#define NV50TSC_1_2_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_2_MIN_LOD_MASK 0x00000f00 +#define NV50TSC_1_2_MAX_LOD_MASK 0x00f00000 #define NV50TSC_1_3_UNKNOWN_MASK 0xffffffff -#define NV50TSC_1_4_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_4_BORDER_COLOR_RED_MASK 0xffffffff -#define NV50TSC_1_5_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_5_BORDER_COLOR_GREEN_MASK 0xffffffff -#define NV50TSC_1_6_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_6_BORDER_COLOR_BLUE_MASK 0xffffffff -#define NV50TSC_1_7_UNKNOWN_MASK 0xffffffff +#define NV50TSC_1_7_BORDER_COLOR_ALPHA_MASK 0xffffffff #endif diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index d0b7f0bef4..d2b5e4d75d 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -8,6 +8,7 @@ struct nv50_transfer { struct pipe_transfer base; struct nouveau_bo *bo; unsigned level_offset; + unsigned level_tiling; int level_pitch; int level_width; int level_height; @@ -16,11 +17,14 @@ struct nv50_transfer { }; static void -nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, - unsigned src_offset, int src_pitch, int sx, int sy, - int sw, int sh, struct nouveau_bo *dst_bo, - unsigned dst_offset, int dst_pitch, int dx, int dy, - int dw, int dh, int cpp, int width, int height, +nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, + struct nouveau_bo *src_bo, unsigned src_offset, + int src_pitch, unsigned src_tile_mode, + int sx, int sy, int sw, int sh, + struct nouveau_bo *dst_bo, unsigned dst_offset, + int dst_pitch, unsigned dst_tile_mode, + int dx, int dy, int dw, int dh, + int cpp, int width, int height, unsigned src_reloc, unsigned dst_reloc) { struct nv50_screen *screen = nv50_screen(pscreen); @@ -33,15 +37,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, WAIT_RING (chan, 14); if (!src_bo->tile_flags) { - BEGIN_RING(chan, m2mf, 0x0200, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1); OUT_RING (chan, 1); - BEGIN_RING(chan, m2mf, 0x0314, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1); OUT_RING (chan, src_pitch); src_offset += (sy * src_pitch) + (sx * cpp); } else { - BEGIN_RING(chan, m2mf, 0x0200, 6); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 6); OUT_RING (chan, 0); - OUT_RING (chan, src_bo->tile_mode << 4); + OUT_RING (chan, src_tile_mode << 4); OUT_RING (chan, sw * cpp); OUT_RING (chan, sh); OUT_RING (chan, 1); @@ -49,15 +56,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, } if (!dst_bo->tile_flags) { - BEGIN_RING(chan, m2mf, 0x021c, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1); OUT_RING (chan, 1); - BEGIN_RING(chan, m2mf, 0x0318, 1); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1); OUT_RING (chan, dst_pitch); dst_offset += (dy * dst_pitch) + (dx * cpp); } else { - BEGIN_RING(chan, m2mf, 0x021c, 6); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 6); OUT_RING (chan, 0); - OUT_RING (chan, dst_bo->tile_mode << 4); + OUT_RING (chan, dst_tile_mode << 4); OUT_RING (chan, dw * cpp); OUT_RING (chan, dh); OUT_RING (chan, 1); @@ -68,25 +78,30 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo, int line_count = height > 2047 ? 2047 : height; WAIT_RING (chan, 15); - BEGIN_RING(chan, m2mf, 0x0238, 2); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2); OUT_RELOCh(chan, src_bo, src_offset, src_reloc); OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc); - BEGIN_RING(chan, m2mf, 0x030c, 2); + BEGIN_RING(chan, m2mf, + NV50_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) { - BEGIN_RING(chan, m2mf, 0x0218, 1); - OUT_RING (chan, (dy << 16) | sx); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1); + OUT_RING (chan, (sy << 16) | sx); } else { src_offset += (line_count * src_pitch); } if (dst_bo->tile_flags) { - BEGIN_RING(chan, m2mf, 0x0234, 1); - OUT_RING (chan, (sy << 16) | dx); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1); + OUT_RING (chan, (dy << 16) | dx); } else { dst_offset += (line_count * dst_pitch); } - BEGIN_RING(chan, m2mf, 0x031c, 4); + BEGIN_RING(chan, m2mf, + NV50_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4); OUT_RING (chan, width * cpp); OUT_RING (chan, line_count); OUT_RING (chan, 0x00000101); @@ -136,6 +151,7 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, tx->level_width = mt->base.width[level]; tx->level_height = mt->base.height[level]; tx->level_offset = lvl->image_offset[image]; + tx->level_tiling = lvl->tile_mode; tx->level_x = x; tx->level_y = y; ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, @@ -147,9 +163,11 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, if (usage != PIPE_TRANSFER_WRITE) { nv50_transfer_rect_m2mf(pscreen, mt->bo, tx->level_offset, - tx->level_pitch, x, y, tx->level_width, - tx->level_height, tx->bo, 0, - tx->base.stride, 0, 0, + tx->level_pitch, tx->level_tiling, + x, y, + tx->level_width, tx->level_height, + tx->bo, 0, tx->base.stride, + tx->bo->tile_mode, 0, 0, tx->base.width, tx->base.height, tx->base.block.size, w, h, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, @@ -168,12 +186,14 @@ nv50_transfer_del(struct pipe_transfer *ptx) if (ptx->usage != PIPE_TRANSFER_READ) { struct pipe_screen *pscreen = ptx->texture->screen; nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride, - 0, 0, tx->base.width, tx->base.height, - mt->bo, tx->level_offset, - tx->level_pitch, tx->level_x, - tx->level_y, tx->level_width, - tx->level_height, tx->base.block.size, + tx->bo->tile_mode, 0, 0, tx->base.width, tx->base.height, + mt->bo, tx->level_offset, + tx->level_pitch, tx->level_tiling, + tx->level_x, tx->level_y, + tx->level_width, tx->level_height, + tx->base.block.size, tx->base.width, + tx->base.height, NOUVEAU_BO_GART, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART); } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index f81929f238..36f1b24b2f 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -49,6 +49,82 @@ nv50_prim(unsigned mode) return NV50TCL_VERTEX_BEGIN_POINTS; } +static INLINE uint32_t +nv50_vbo_type_to_hw(unsigned type) +{ + switch (type) { + case PIPE_FORMAT_TYPE_FLOAT: + return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT; + case PIPE_FORMAT_TYPE_UNORM: + return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM; + case PIPE_FORMAT_TYPE_SNORM: + return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM; + case PIPE_FORMAT_TYPE_USCALED: + return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED; + case PIPE_FORMAT_TYPE_SSCALED: + return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED; + /* + case PIPE_FORMAT_TYPE_UINT: + return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UINT; + case PIPE_FORMAT_TYPE_SINT: + return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SINT; */ + default: + return 0; + } +} + +static INLINE uint32_t +nv50_vbo_size_to_hw(unsigned size, unsigned nr_c) +{ + static const uint32_t hw_values[] = { + 0, 0, 0, 0, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8_8, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16_16, + 0, 0, 0, 0, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32, + NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32_32 }; + + /* we'd also have R11G11B10 and R10G10B10A2 */ + + assert(nr_c > 0 && nr_c <= 4); + + if (size > 32) + return 0; + size >>= (3 - 2); + + return hw_values[size + (nr_c - 1)]; +} + +static INLINE uint32_t +nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve) +{ + uint32_t hw_type, hw_size; + enum pipe_format pf = ve->src_format; + unsigned size = pf_size_x(pf) << pf_exp2(pf); + + hw_type = nv50_vbo_type_to_hw(pf_type(pf)); + hw_size = nv50_vbo_size_to_hw(size, ve->nr_components); + + if (!hw_type || !hw_size) { + NOUVEAU_ERR("unsupported vbo format: %s\n", pf_name(pf)); + abort(); + return 0x24e80000; + } + + if (pf_swizzle_x(pf) == 2) /* BGRA */ + hw_size |= (1 << 31); /* no real swizzle bits :-( */ + + return (hw_type | hw_size); +} + boolean nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) @@ -139,7 +215,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map, } static INLINE void -nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map, +nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map, unsigned start, unsigned count) { struct nouveau_channel *chan = nv50->screen->tesla->channel; @@ -201,49 +277,101 @@ nv50_draw_elements(struct pipe_context *pipe, return TRUE; } +static INLINE boolean +nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib, + struct nouveau_stateobj **pso, + struct pipe_vertex_element *ve, + struct pipe_vertex_buffer *vb) + +{ + struct nouveau_stateobj *so; + struct nouveau_grobj *tesla = nv50->screen->tesla; + struct nouveau_bo *bo = nouveau_bo(vb->buffer); + float *v; + int ret; + enum pipe_format pf = ve->src_format; + + if ((pf_type(pf) != PIPE_FORMAT_TYPE_FLOAT) || + (pf_size_x(pf) << pf_exp2(pf)) != 32) + return FALSE; + + ret = nouveau_bo_map(bo, NOUVEAU_BO_RD); + if (ret) + return FALSE; + v = (float *)(bo->map + (vb->buffer_offset + ve->src_offset)); + + so = *pso; + if (!so) + *pso = so = so_new(nv50->vtxelt_nr * 5, 0); + + switch (ve->nr_components) { + case 4: + so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4); + so_data (so, fui(v[0])); + so_data (so, fui(v[1])); + so_data (so, fui(v[2])); + so_data (so, fui(v[3])); + break; + case 3: + so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 4); + so_data (so, fui(v[0])); + so_data (so, fui(v[1])); + so_data (so, fui(v[2])); + break; + case 2: + so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 4); + so_data (so, fui(v[0])); + so_data (so, fui(v[1])); + break; + case 1: + so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 4); + so_data (so, fui(v[0])); + break; + default: + nouveau_bo_unmap(bo); + return FALSE; + } + + nouveau_bo_unmap(bo); + return TRUE; +} + void nv50_vbo_validate(struct nv50_context *nv50) { struct nouveau_grobj *tesla = nv50->screen->tesla; - struct nouveau_stateobj *vtxbuf, *vtxfmt; - int i; + struct nouveau_stateobj *vtxbuf, *vtxfmt, *vtxattr; + unsigned i; + + /* don't validate if Gallium took away our buffers */ + if (nv50->vtxbuf_nr == 0) + return; - vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2); + vtxattr = NULL; + vtxbuf = so_new(nv50->vtxelt_nr * 7, nv50->vtxelt_nr * 4); vtxfmt = so_new(nv50->vtxelt_nr + 1, 0); - so_method(vtxfmt, tesla, 0x1ac0, nv50->vtxelt_nr); + so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0), + nv50->vtxelt_nr); for (i = 0; i < nv50->vtxelt_nr; i++) { struct pipe_vertex_element *ve = &nv50->vtxelt[i]; struct pipe_vertex_buffer *vb = &nv50->vtxbuf[ve->vertex_buffer_index]; struct nouveau_bo *bo = nouveau_bo(vb->buffer); + uint32_t hw = nv50_vbo_vtxelt_to_hw(ve); - switch (ve->src_format) { - case PIPE_FORMAT_R32G32B32A32_FLOAT: - so_data(vtxfmt, 0x7e080000 | i); - break; - case PIPE_FORMAT_R32G32B32_FLOAT: - so_data(vtxfmt, 0x7e100000 | i); - break; - case PIPE_FORMAT_R32G32_FLOAT: - so_data(vtxfmt, 0x7e200000 | i); - break; - case PIPE_FORMAT_R32_FLOAT: - so_data(vtxfmt, 0x7e900000 | i); - break; - case PIPE_FORMAT_R8G8B8A8_UNORM: - so_data(vtxfmt, 0x24500000 | i); - break; - default: - { - NOUVEAU_ERR("invalid vbo format %s\n", - pf_name(ve->src_format)); - assert(0); - return; - } + if (!vb->stride && + nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) { + so_data(vtxfmt, hw | (1 << 4)); + + so_method(vtxbuf, tesla, + NV50TCL_VERTEX_ARRAY_FORMAT(i), 1); + so_data (vtxbuf, 0); + continue; } + so_data(vtxfmt, hw | i); - so_method(vtxbuf, tesla, 0x900 + (i * 16), 3); + so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3); so_data (vtxbuf, 0x20000000 | vb->stride); so_reloc (vtxbuf, bo, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | @@ -251,11 +379,22 @@ nv50_vbo_validate(struct nv50_context *nv50) so_reloc (vtxbuf, bo, vb->buffer_offset + ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); + + /* vertex array limits */ + so_method(vtxbuf, tesla, 0x1080 + (i * 8), 2); + so_reloc (vtxbuf, bo, vb->buffer->size - 1, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | + NOUVEAU_BO_HIGH, 0, 0); + so_reloc (vtxbuf, bo, vb->buffer->size - 1, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | + NOUVEAU_BO_LOW, 0, 0); } so_ref (vtxfmt, &nv50->state.vtxfmt); so_ref (vtxbuf, &nv50->state.vtxbuf); + so_ref (vtxattr, &nv50->state.vtxattr); so_ref (NULL, &vtxbuf); so_ref (NULL, &vtxfmt); + so_ref (NULL, &vtxattr); } |