From 4c2247538394a313e1e90bfcd07c1ab9c7d41281 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Fri, 12 Nov 2010 15:17:40 +0100 Subject: nvc0: import nvc0 gallium driver --- src/gallium/drivers/nvc0/nvc0_push2.c | 329 ++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 src/gallium/drivers/nvc0/nvc0_push2.c (limited to 'src/gallium/drivers/nvc0/nvc0_push2.c') diff --git a/src/gallium/drivers/nvc0/nvc0_push2.c b/src/gallium/drivers/nvc0/nvc0_push2.c new file mode 100644 index 0000000000..3f9359cf25 --- /dev/null +++ b/src/gallium/drivers/nvc0/nvc0_push2.c @@ -0,0 +1,329 @@ + +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "translate/translate.h" + +#include "nvc0_context.h" +#include "nvc0_resource.h" + +#include "nvc0_3d.xml.h" + +struct push_context { + struct nvc0_context *nvc0; + + uint vertex_size; + + void *idxbuf; + uint idxsize; + + float edgeflag; + int edgeflag_input; + + struct { + void *map; + void (*push)(struct nouveau_channel *, void *); + uint32_t stride; + uint32_t divisor; + uint32_t step; + } attr[32]; + int num_attrs; +}; + +static void +emit_b32_1(struct nouveau_channel *chan, void *data) +{ + uint32_t *v = data; + + OUT_RING(chan, v[0]); +} + +static void +emit_b32_2(struct nouveau_channel *chan, void *data) +{ + uint32_t *v = data; + + OUT_RING(chan, v[0]); + OUT_RING(chan, v[1]); +} + +static void +emit_b32_3(struct nouveau_channel *chan, void *data) +{ + uint32_t *v = data; + + OUT_RING(chan, v[0]); + OUT_RING(chan, v[1]); + OUT_RING(chan, v[2]); +} + +static void +emit_b32_4(struct nouveau_channel *chan, void *data) +{ + uint32_t *v = data; + + OUT_RING(chan, v[0]); + OUT_RING(chan, v[1]); + OUT_RING(chan, v[2]); + OUT_RING(chan, v[3]); +} + +static void +emit_b16_1(struct nouveau_channel *chan, void *data) +{ + uint16_t *v = data; + + OUT_RING(chan, v[0]); +} + +static void +emit_b16_3(struct nouveau_channel *chan, void *data) +{ + uint16_t *v = data; + + OUT_RING(chan, (v[1] << 16) | v[0]); + OUT_RING(chan, v[2]); +} + +static void +emit_b08_1(struct nouveau_channel *chan, void *data) +{ + uint8_t *v = data; + + OUT_RING(chan, v[0]); +} + +static void +emit_b08_3(struct nouveau_channel *chan, void *data) +{ + uint8_t *v = data; + + OUT_RING(chan, (v[2] << 16) | (v[1] << 8) | v[0]); +} + +static void +emit_b64_1(struct nouveau_channel *chan, void *data) +{ + double *v = data; + + OUT_RINGf(chan, v[0]); +} + +static void +emit_b64_2(struct nouveau_channel *chan, void *data) +{ + double *v = data; + + OUT_RINGf(chan, v[0]); + OUT_RINGf(chan, v[1]); +} + +static void +emit_b64_3(struct nouveau_channel *chan, void *data) +{ + double *v = data; + + OUT_RINGf(chan, v[0]); + OUT_RINGf(chan, v[1]); + OUT_RINGf(chan, v[2]); +} + +static void +emit_b64_4(struct nouveau_channel *chan, void *data) +{ + double *v = data; + + OUT_RINGf(chan, v[0]); + OUT_RINGf(chan, v[1]); + OUT_RINGf(chan, v[2]); + OUT_RINGf(chan, v[3]); +} + +static INLINE void +emit_vertex(struct push_context *ctx, unsigned n) +{ + struct nouveau_channel *chan = ctx->nvc0->screen->base.channel; + int i; + + if (ctx->edgeflag_input < 32) { + /* TODO */ + } + + BEGIN_RING_NI(chan, RING_3D(VERTEX_DATA), ctx->vertex_size); + for (i = 0; i < ctx->num_attrs; ++i) + ctx->attr[i].push(chan, + (uint8_t *)ctx->attr[i].map + n * ctx->attr[i].stride); +} + +static void +emit_edgeflag(struct push_context *ctx, boolean enabled) +{ + struct nouveau_channel *chan = ctx->nvc0->screen->base.channel; + + INLIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), enabled); +} + +static void +emit_elt08(struct push_context *ctx, unsigned start, unsigned count) +{ + uint8_t *idxbuf = ctx->idxbuf; + + while (count--) + emit_vertex(ctx, idxbuf[start++]); +} + +static void +emit_elt16(struct push_context *ctx, unsigned start, unsigned count) +{ + uint16_t *idxbuf = ctx->idxbuf; + + while (count--) + emit_vertex(ctx, idxbuf[start++]); +} + +static void +emit_elt32(struct push_context *ctx, unsigned start, unsigned count) +{ + uint32_t *idxbuf = ctx->idxbuf; + + while (count--) + emit_vertex(ctx, idxbuf[start++]); +} + +static void +emit_seq(struct push_context *ctx, unsigned start, unsigned count) +{ + while (count--) + emit_vertex(ctx, start++); +} + +#define NVC0_PRIM_GL_CASE(n) \ + case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n + +static INLINE unsigned +nvc0_prim_gl(unsigned prim) +{ + switch (prim) { + NVC0_PRIM_GL_CASE(POINTS); + NVC0_PRIM_GL_CASE(LINES); + NVC0_PRIM_GL_CASE(LINE_LOOP); + NVC0_PRIM_GL_CASE(LINE_STRIP); + NVC0_PRIM_GL_CASE(TRIANGLES); + NVC0_PRIM_GL_CASE(TRIANGLE_STRIP); + NVC0_PRIM_GL_CASE(TRIANGLE_FAN); + NVC0_PRIM_GL_CASE(QUADS); + NVC0_PRIM_GL_CASE(QUAD_STRIP); + NVC0_PRIM_GL_CASE(POLYGON); + NVC0_PRIM_GL_CASE(LINES_ADJACENCY); + NVC0_PRIM_GL_CASE(LINE_STRIP_ADJACENCY); + NVC0_PRIM_GL_CASE(TRIANGLES_ADJACENCY); + NVC0_PRIM_GL_CASE(TRIANGLE_STRIP_ADJACENCY); + /* + NVC0_PRIM_GL_CASE(PATCHES); */ + default: + return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_POINTS; + break; + } +} + +void +nvc0_push_vbo2(struct nvc0_context *nvc0, const struct pipe_draw_info *info) +{ + struct push_context ctx; + unsigned i, n; + unsigned inst = info->instance_count; + unsigned prim = nvc0_prim_gl(info->mode); + + ctx.nvc0 = nvc0; + ctx.vertex_size = nvc0->vertex->vtx_size; + ctx.idxbuf = NULL; + ctx.num_attrs = 0; + ctx.edgeflag = 0.5f; + ctx.edgeflag_input = 32; + + for (i = 0; i < nvc0->vertex->num_elements; ++i) { + struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe; + struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[ve->vertex_buffer_index]; + struct nouveau_bo *bo = nvc0_resource(vb->buffer)->bo; + unsigned nr_components; + + if (!(nvc0->vbo_fifo & (1 << i))) + continue; + n = ctx.num_attrs++; + + if (nouveau_bo_map(bo, NOUVEAU_BO_RD)) + return; + ctx.attr[n].map = (uint8_t *)bo->map + vb->buffer_offset + ve->src_offset; + + nouveau_bo_unmap(bo); + + ctx.attr[n].stride = vb->stride; + ctx.attr[n].divisor = ve->instance_divisor; + + nr_components = util_format_get_nr_components(ve->src_format); + switch (util_format_get_component_bits(ve->src_format, + UTIL_FORMAT_COLORSPACE_RGB, 0)) { + case 8: + switch (nr_components) { + case 1: ctx.attr[n].push = emit_b08_1; break; + case 2: ctx.attr[n].push = emit_b16_1; break; + case 3: ctx.attr[n].push = emit_b08_3; break; + case 4: ctx.attr[n].push = emit_b32_1; break; + } + break; + case 16: + switch (nr_components) { + case 1: ctx.attr[n].push = emit_b16_1; break; + case 2: ctx.attr[n].push = emit_b32_1; break; + case 3: ctx.attr[n].push = emit_b16_3; break; + case 4: ctx.attr[n].push = emit_b32_2; break; + } + break; + case 32: + switch (nr_components) { + case 1: ctx.attr[n].push = emit_b32_1; break; + case 2: ctx.attr[n].push = emit_b32_2; break; + case 3: ctx.attr[n].push = emit_b32_3; break; + case 4: ctx.attr[n].push = emit_b32_4; break; + } + break; + default: + assert(0); + break; + } + } + + if (info->indexed) { + struct nvc0_resource *res = nvc0_resource(nvc0->idxbuf.buffer); + if (!res || nouveau_bo_map(res->bo, NOUVEAU_BO_RD)) + return; + ctx.idxbuf = res->bo->map; + nouveau_bo_unmap(res->bo); + ctx.idxsize = nvc0->idxbuf.index_size; + } else { + ctx.idxsize = 0; + } + + while (inst--) { + BEGIN_RING(nvc0->screen->base.channel, RING_3D(VERTEX_BEGIN_GL), 1); + OUT_RING (nvc0->screen->base.channel, prim); + switch (ctx.idxsize) { + case 0: + emit_seq(&ctx, info->start, info->count); + break; + case 1: + emit_elt08(&ctx, info->start, info->count); + break; + case 2: + emit_elt16(&ctx, info->start, info->count); + break; + case 4: + emit_elt32(&ctx, info->start, info->count); + break; + } + INLIN_RING(nvc0->screen->base.channel, RING_3D(VERTEX_END_GL), 0); + + prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; + } +} -- cgit v1.2.3 From 99f9a9727ca315e4ee4371fc05be4798ffb46214 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Sun, 19 Dec 2010 21:33:37 +0100 Subject: nvc0: add the index buffer offset where missing --- src/gallium/drivers/nvc0/nvc0_push.c | 2 ++ src/gallium/drivers/nvc0/nvc0_push2.c | 2 +- src/gallium/drivers/nvc0/nvc0_vbo.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nvc0/nvc0_push2.c') diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index 1bdc8e88a7..8cb05cdd09 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -227,6 +227,8 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) PIPE_TRANSFER_READ, &transfer); if (!ctx.idxbuf) return; + ctx.idxbuf = (uint8_t *)ctx.idxbuf + nvc0->idxbuf.offset; + index_size = nvc0->idxbuf.index_size; ctx.primitive_restart = info->primitive_restart; ctx.restart_index = info->restart_index; diff --git a/src/gallium/drivers/nvc0/nvc0_push2.c b/src/gallium/drivers/nvc0/nvc0_push2.c index 3f9359cf25..07dd7b56b9 100644 --- a/src/gallium/drivers/nvc0/nvc0_push2.c +++ b/src/gallium/drivers/nvc0/nvc0_push2.c @@ -298,7 +298,7 @@ nvc0_push_vbo2(struct nvc0_context *nvc0, const struct pipe_draw_info *info) struct nvc0_resource *res = nvc0_resource(nvc0->idxbuf.buffer); if (!res || nouveau_bo_map(res->bo, NOUVEAU_BO_RD)) return; - ctx.idxbuf = res->bo->map; + ctx.idxbuf = (uint8_t *)res->bo->map + nvc0->idxbuf.offset + res->offset; nouveau_bo_unmap(res->bo); ctx.idxsize = nvc0->idxbuf.index_size; } else { diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index 84951ed945..f1d5910e3d 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -459,6 +459,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, PIPE_TRANSFER_READ, &transfer); if (!data) return; + data = (uint8_t *)data + nvc0->idxbuf.offset; while (instance_count--) { BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1); -- cgit v1.2.3 From 9f2cf899578464a7448d7abec681bde42eb3d2f2 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Sun, 19 Dec 2010 22:49:50 +0100 Subject: nvc0: s/INLIN_RING/IMMED_RING --- src/gallium/drivers/nvc0/nvc0_push.c | 2 +- src/gallium/drivers/nvc0/nvc0_push2.c | 4 ++-- src/gallium/drivers/nvc0/nvc0_state_validate.c | 2 +- src/gallium/drivers/nvc0/nvc0_vbo.c | 12 ++++++------ src/gallium/drivers/nvc0/nvc0_winsys.h | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/gallium/drivers/nvc0/nvc0_push2.c') diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index 8cb05cdd09..5116929b50 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -261,7 +261,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) assert(0); break; } - INLIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 0); + IMMED_RING(ctx.chan, RING_3D(VERTEX_END_GL), 0); ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } diff --git a/src/gallium/drivers/nvc0/nvc0_push2.c b/src/gallium/drivers/nvc0/nvc0_push2.c index 07dd7b56b9..1f4ba256c1 100644 --- a/src/gallium/drivers/nvc0/nvc0_push2.c +++ b/src/gallium/drivers/nvc0/nvc0_push2.c @@ -161,7 +161,7 @@ emit_edgeflag(struct push_context *ctx, boolean enabled) { struct nouveau_channel *chan = ctx->nvc0->screen->base.channel; - INLIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), enabled); + IMMED_RING(chan, RING_3D(EDGEFLAG_ENABLE), enabled); } static void @@ -322,7 +322,7 @@ nvc0_push_vbo2(struct nvc0_context *nvc0, const struct pipe_draw_info *info) emit_elt32(&ctx, info->start, info->count); break; } - INLIN_RING(nvc0->screen->base.channel, RING_3D(VERTEX_END_GL), 0); + IMMED_RING(nvc0->screen->base.channel, RING_3D(VERTEX_END_GL), 0); prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index a395b18a99..f20e7e962c 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -249,7 +249,7 @@ nvc0_validate_clip(struct nvc0_context *nvc0) BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1); OUT_RING (chan, (1 << nvc0->clip.nr) - 1); } else { - INLIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 0); + IMMED_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 0); } } diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index f1d5910e3d..93b9a56178 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -172,13 +172,13 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) if (unlikely(ve->pipe.instance_divisor)) { if (!(nvc0->state.instance_bits & (1 << i))) { - INLIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); + IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1); } BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1); OUT_RING (chan, ve->pipe.instance_divisor); } else if (unlikely(nvc0->state.instance_bits & (1 << i))) { - INLIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); + IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0); } nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, res, NOUVEAU_BO_RD); @@ -308,7 +308,7 @@ nvc0_draw_arrays(struct nvc0_context *nvc0, BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2); OUT_RING (chan, start); OUT_RING (chan, count); - INLIN_RING(chan, RING_3D(VERTEX_END_GL), 0); + IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } @@ -450,7 +450,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, OUT_RING (chan, index_size); OUT_RING (chan, start); OUT_RING (chan, count); - INLIN_RING(chan, RING_3D(VERTEX_END_GL), 0); + IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } @@ -481,7 +481,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten, assert(0); return; } - INLIN_RING(chan, RING_3D(VERTEX_END_GL), 0); + IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0); prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } @@ -540,7 +540,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) if (info->restart_index > 65535) shorten = FALSE; } else { - INLIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 0); + IMMED_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 0); } nvc0->state.prim_restart = info->primitive_restart; } else diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h index 34bc536765..85f8ed4da4 100644 --- a/src/gallium/drivers/nvc0/nvc0_winsys.h +++ b/src/gallium/drivers/nvc0/nvc0_winsys.h @@ -82,7 +82,7 @@ BEGIN_RING_1I(struct nouveau_channel *chan, uint32_t mthd, unsigned size) /* inline-data */ static INLINE void -INLIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data) +IMMED_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data) { WAIT_RING(chan, 1); OUT_RING (chan, (0x8 << 28) | (data << 16) | mthd); -- cgit v1.2.3 From c024c1d75fdce72fe2de2d6b987b796fc9561115 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Sun, 2 Jan 2011 22:39:50 +0100 Subject: nvc0: fix resource unmap after vertex push --- src/gallium/drivers/nvc0/nvc0_push.c | 11 +++-------- src/gallium/drivers/nvc0/nvc0_push2.c | 4 ++++ src/gallium/drivers/nvc0/nvc0_resource.h | 3 +-- 3 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src/gallium/drivers/nvc0/nvc0_push2.c') diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index 779a477599..ccbb776447 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -201,7 +201,6 @@ void nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) { struct push_context ctx; - struct pipe_transfer *transfer = NULL; unsigned i, index_size; unsigned inst = info->instance_count; @@ -267,12 +266,8 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) } if (info->indexed) - pipe_buffer_unmap(&nvc0->pipe, transfer); + nvc0_resource_unmap(nvc0_resource(nvc0->idxbuf.buffer)); - for (i = 0; i < nvc0->num_vtxbufs; ++i) { - struct nvc0_resource *res = nvc0_resource(nvc0->vtxbuf[i].buffer); - - if (res->bo) - nouveau_bo_unmap(res->bo); - } + for (i = 0; i < nvc0->num_vtxbufs; ++i) + nvc0_resource_unmap(nvc0_resource(nvc0->vtxbuf[i].buffer)); } diff --git a/src/gallium/drivers/nvc0/nvc0_push2.c b/src/gallium/drivers/nvc0/nvc0_push2.c index 1f4ba256c1..6f51600558 100644 --- a/src/gallium/drivers/nvc0/nvc0_push2.c +++ b/src/gallium/drivers/nvc0/nvc0_push2.c @@ -1,4 +1,6 @@ +#if 0 /* not used, kept for now to compare with util/translate */ + #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_inlines.h" @@ -327,3 +329,5 @@ nvc0_push_vbo2(struct nvc0_context *nvc0, const struct pipe_draw_info *info) prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } } + +#endif diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h index 0ffb9e8fa6..d33e2f0ed0 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.h +++ b/src/gallium/drivers/nvc0/nvc0_resource.h @@ -102,8 +102,7 @@ nvc0_resource_map_offset(struct nvc0_context *nvc0, static INLINE void nvc0_resource_unmap(struct nvc0_resource *res) { - if (res->domain != 0 && 0) - nouveau_bo_unmap(res->bo); + /* no-op */ } #define NVC0_TILE_DIM_SHIFT(m, d) (((m) >> (d * 4)) & 0xf) -- cgit v1.2.3