diff options
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_miptree.c | 42 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 95 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_query.c | 2 |
4 files changed, 107 insertions, 36 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 5d377f2d06..0958bba334 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -70,6 +70,10 @@ struct nv50_rasterizer_stateobj { struct nv50_miptree { struct pipe_texture base; struct pipe_buffer *buffer; + + int *image_offset; + int image_nr; + int total_size; }; static INLINE struct nv50_miptree * diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 28a8bdc0fa..2497371232 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -31,7 +31,8 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) { struct pipe_winsys *ws = pscreen->winsys; struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree); - unsigned usage, pitch; + unsigned usage, width = pt->width[0], height = pt->height[0]; + int i; mt->base = *pt; mt->base.refcount = 1; @@ -47,11 +48,31 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) break; } - pitch = ((pt->width[0] + 63) & ~63) * pt->block.size; - /*XXX*/ - pitch *= 2; + switch (pt->target) { + case PIPE_TEXTURE_3D: + mt->image_nr = pt->depth[0]; + break; + case PIPE_TEXTURE_CUBE: + mt->image_nr = 6; + break; + default: + mt->image_nr = 1; + break; + } + mt->image_offset = CALLOC(mt->image_nr, sizeof(int)); - mt->buffer = ws->buffer_create(ws, 256, usage, pitch * pt->height[0]); + for (i = 0; i < mt->image_nr; i++) { + int image_size; + + image_size = align(width, 8) * pt->block.size; + image_size = align(image_size, 64); + image_size *= align(height, 8) * pt->block.size; + + mt->image_offset[i] = mt->total_size; + mt->total_size += image_size; + } + + mt->buffer = ws->buffer_create(ws, 256, usage, mt->total_size); if (!mt->buffer) { FREE(mt); return NULL; @@ -83,6 +104,15 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, struct nv50_miptree *mt = nv50_miptree(pt); struct nv50_surface *s; struct pipe_surface *ps; + int img; + + if (pt->target == PIPE_TEXTURE_CUBE) + img = face; + else + if (pt->target == PIPE_TEXTURE_3D) + img = zslice; + else + img = 0; s = CALLOC_STRUCT(nv50_surface); if (!s) @@ -98,7 +128,7 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, ps->nblocksx = pt->nblocksx[level]; ps->nblocksy = pt->nblocksy[level]; ps->stride = ps->width * ps->block.size; - ps->offset = 0; + ps->offset = mt->image_offset[img]; ps->usage = flags; ps->status = PIPE_SURFACE_STATUS_DEFINED; diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c index d6fbdd1824..d66e1d0949 100644 --- a/src/gallium/drivers/nv50/nv50_program.c +++ b/src/gallium/drivers/nv50/nv50_program.c @@ -179,6 +179,38 @@ free_temp(struct nv50_pc *pc, struct nv50_reg *r) } } +static int +alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx) +{ + int i; + + if ((idx + 4) >= NV50_SU_MAX_TEMP) + return 1; + + 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); + + for (i = 0; i < 4; i++) { + dst[i] = CALLOC_STRUCT(nv50_reg); + dst[i]->type = P_TEMP; + dst[i]->index = -1; + dst[i]->hw = idx + i; + pc->r_temp[idx + i] = dst[i]; + } + + return 0; +} + +static void +free_temp4(struct nv50_pc *pc, struct nv50_reg *reg[4]) +{ + int i; + + for (i = 0; i < 4; i++) + free_temp(pc, reg[i]); +} + static struct nv50_reg * temp_temp(struct nv50_pc *pc) { @@ -902,7 +934,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) { const struct tgsi_full_instruction *inst = &tok->FullInstruction; struct nv50_reg *rdst[4], *dst[4], *src[3][4], *temp; - unsigned mask, sat; + unsigned mask, sat, unit; int i, c; mask = inst->FullDstRegisters[0].DstRegister.WriteMask; @@ -916,8 +948,13 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } for (i = 0; i < inst->Instruction.NumSrcRegs; i++) { + struct tgsi_full_src_register *fs = &inst->FullSrcRegisters[i]; + + if (fs->SrcRegister.File == TGSI_FILE_SAMPLER) + unit = fs->SrcRegister.Index; + for (c = 0; c < 4; c++) - src[i][c] = tgsi_src(pc, c, &inst->FullSrcRegisters[i]); + src[i][c] = tgsi_src(pc, c, fs); } if (sat) { @@ -1155,35 +1192,30 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok) } break; case TGSI_OPCODE_TEX: - { - struct nv50_reg *t0, *t1, *t2, *t3; - struct nv50_program_exec *e; + case TGSI_OPCODE_TXP: + { + struct nv50_reg *t[4]; + struct nv50_program_exec *e; - t0 = alloc_temp(pc, NULL); - t0 = alloc_temp(pc, NULL); - t1 = alloc_temp(pc, NULL); - t2 = alloc_temp(pc, NULL); - t3 = alloc_temp(pc, NULL); - emit_mov(pc, t0, src[0][0]); - emit_mov(pc, t1, src[0][1]); + alloc_temp4(pc, t, 0); + emit_mov(pc, t[0], src[0][0]); + emit_mov(pc, t[1], src[0][1]); - e = exec(pc); - e->inst[0] = 0xf6400000; - set_long(pc, e); - e->inst[1] |= 0x0000c004; - set_dst(pc, t0, e); - emit(pc, e); + e = exec(pc); + e->inst[0] = 0xf6400000; + e->inst[0] |= (unit << 9); + set_long(pc, e); + e->inst[1] |= 0x0000c004; + set_dst(pc, t[0], e); + emit(pc, e); - if (mask & (1 << 0)) emit_mov(pc, dst[0], t0); - if (mask & (1 << 1)) emit_mov(pc, dst[1], t1); - if (mask & (1 << 2)) emit_mov(pc, dst[2], t2); - if (mask & (1 << 3)) emit_mov(pc, dst[3], t3); + if (mask & (1 << 0)) emit_mov(pc, dst[0], t[0]); + if (mask & (1 << 1)) emit_mov(pc, dst[1], t[1]); + if (mask & (1 << 2)) emit_mov(pc, dst[2], t[2]); + if (mask & (1 << 3)) emit_mov(pc, dst[3], t[3]); - free_temp(pc, t0); - free_temp(pc, t1); - free_temp(pc, t2); - free_temp(pc, t3); - } + free_temp4(pc, t); + } break; case TGSI_OPCODE_XPD: temp = alloc_temp(pc, NULL); @@ -1570,8 +1602,13 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p) if (!upload) return; + NOUVEAU_ERR("-------\n"); up = ptr = MALLOC(p->exec_size * 4); for (e = p->exec_head; e; e = e->next) { + NOUVEAU_ERR("0x%08x\n", e->inst[0]); + if (is_long(e)) + NOUVEAU_ERR("0x%08x\n", e->inst[1]); + *(ptr++) = e->inst[0]; if (is_long(e)) *(ptr++) = e->inst[1]; @@ -1687,7 +1724,7 @@ nv50_fragprog_validate(struct nv50_context *nv50) void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) { - struct pipe_winsys *ws = nv50->pipe.winsys; + struct pipe_screen *pscreen = nv50->pipe.screen; while (p->exec_head) { struct nv50_program_exec *e = p->exec_head; @@ -1699,7 +1736,7 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p) p->exec_size = 0; if (p->buffer) - pipe_buffer_reference(ws, &p->buffer, NULL); + pipe_buffer_reference(pscreen, &p->buffer, NULL); nv50->screen->nvws->res_free(&p->data); diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c index 26bd90ccc5..777e77906d 100644 --- a/src/gallium/drivers/nv50/nv50_query.c +++ b/src/gallium/drivers/nv50/nv50_query.c @@ -51,7 +51,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *q) static boolean nv50_query_result(struct pipe_context *pipe, struct pipe_query *q, - boolean wait, uint64 *result) + boolean wait, uint64_t *result) { NOUVEAU_ERR("unimplemented\n"); *result = 0xdeadcafe; |