summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-01-09 10:08:06 +0000
committerKeith Whitwell <[email protected]>2009-01-09 10:08:06 +0000
commite3734593aea202e99e77febea7b86c904080939f (patch)
tree69856674e2062c55ec5eec95eb0e31225a943084 /src/gallium/drivers/nv50
parent221352bbd79a0ea92ce31cffb65537f62ee5668e (diff)
parent5cad143e545775acacee294049345c6a3868c51d (diff)
Merge commit 'origin/gallium-0.2' into gallium-xlib-rework
Conflicts: progs/glsl/Makefile
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h4
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c42
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c95
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c2
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 5d377f2d067..0958bba334a 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 28a8bdc0fab..24973712324 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 d6fbdd18243..d66e1d0949d 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 26bd90ccc5e..777e77906d5 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;