summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvfx/nvfx_vbo.c
diff options
context:
space:
mode:
authorXavier Chantry <[email protected]>2010-12-25 16:39:01 +0100
committerFrancisco Jerez <[email protected]>2010-12-25 20:37:39 +0100
commit5f0f9f0486e9cf43939dfbd1051298f05da1eec4 (patch)
tree123fe69d9a1fe97cc27df68522c5fafb5fd3ee0b /src/gallium/drivers/nvfx/nvfx_vbo.c
parentb01b73c482474609aceb6bb13b083e96c06ba353 (diff)
nvfx: restore BEGIN_RING usage
Michel Hermier reported libdrm segfault (and kernel crash) on nv40 using gallium : http://www.mail-archive.com/[email protected]/msg06563.html It turns out these were caused by some missing WAIT_RING (or wrong computation of the WAIT_RING sizes). Unlike all other libdrm_nouveau users, nvfx gallium tried to use a mininum calls of WAIT_RING, one WAIT_RING could apply to many methods for different code paths and spread across several functions. This made it too tricky to find out what the missing or wrong WAIT_RING was. By restoring BEGIN_RING, we force one WAIT_RING per method, and it's much easier to check if the free size required in the pushbuffer is correct. As curro said, "let's keep it simple for the maintainers until the big bottlenecks are gone" Benchmarked on nv35 with openarena, nexuiz and ut2004 and no performance regression. The core of this patch was made with Coccinelle, with minor manual fixes made on top. Tested-by: Michel Hermier <[email protected]> Signed-off-by: Francisco Jerez <[email protected]>
Diffstat (limited to 'src/gallium/drivers/nvfx/nvfx_vbo.c')
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vbo.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index 339b31786d6..b02e7b76344 100644
--- a/src/gallium/drivers/nvfx/nvfx_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -246,6 +246,7 @@ boolean
nvfx_vbo_validate(struct nvfx_context *nvfx)
{
struct nouveau_channel* chan = nvfx->screen->base.channel;
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
int i;
int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr);
unsigned vb_flags = nvfx->screen->vertex_buffer_reloc_flags | NOUVEAU_BO_RD;
@@ -261,11 +262,11 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
struct nvfx_buffer* buffer = nvfx_buffer(vb->buffer);
float v[4];
ve->fetch_rgba_float(v, buffer->data + vb->buffer_offset + ve->src_offset, 0, 0);
- nvfx_emit_vtx_attr(chan, ve->idx, v, ve->ncomp);
+ nvfx_emit_vtx_attr(chan, eng3d, ve->idx, v, ve->ncomp);
}
- OUT_RING(chan, RING_3D(NV30_3D_VTXFMT(0), elements));
+ BEGIN_RING(chan, eng3d, NV30_3D_VTXFMT(0), elements);
if(nvfx->use_vertex_buffers)
{
unsigned idx = 0;
@@ -296,12 +297,12 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
unsigned i;
/* seems to be some kind of cache flushing */
for(i = 0; i < 3; ++i) {
- OUT_RING(chan, RING_3D(0x1718, 1));
+ BEGIN_RING(chan, eng3d, 0x1718, 1);
OUT_RING(chan, 0);
}
}
- OUT_RING(chan, RING_3D(NV30_3D_VTXBUF(0), elements));
+ BEGIN_RING(chan, eng3d, NV30_3D_VTXBUF(0), elements);
if(nvfx->use_vertex_buffers)
{
unsigned idx = 0;
@@ -329,7 +330,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
OUT_RING(chan, 0);
}
- OUT_RING(chan, RING_3D(0x1710, 1));
+ BEGIN_RING(chan, eng3d, 0x1710, 1);
OUT_RING(chan, 0);
nvfx->hw_vtxelt_nr = nvfx->vtxelt->num_elements;
@@ -341,15 +342,14 @@ void
nvfx_vbo_swtnl_validate(struct nvfx_context *nvfx)
{
struct nouveau_channel* chan = nvfx->screen->base.channel;
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
unsigned num_outputs = nvfx->vertprog->draw_elements;
int elements = MAX2(num_outputs, nvfx->hw_vtxelt_nr);
if (!elements)
return;
- WAIT_RING(chan, (1 + 6 + 1 + 2) + elements * 2);
-
- OUT_RING(chan, RING_3D(NV30_3D_VTXFMT(0), elements));
+ BEGIN_RING(chan, eng3d, NV30_3D_VTXFMT(0), elements);
for(unsigned i = 0; i < num_outputs; ++i)
OUT_RING(chan, (4 << NV30_3D_VTXFMT_SIZE__SHIFT) | NV30_3D_VTXFMT_TYPE_V32_FLOAT);
for(unsigned i = num_outputs; i < elements; ++i)
@@ -359,16 +359,16 @@ nvfx_vbo_swtnl_validate(struct nvfx_context *nvfx)
unsigned i;
/* seems to be some kind of cache flushing */
for(i = 0; i < 3; ++i) {
- OUT_RING(chan, RING_3D(0x1718, 1));
+ BEGIN_RING(chan, eng3d, 0x1718, 1);
OUT_RING(chan, 0);
}
}
- OUT_RING(chan, RING_3D(NV30_3D_VTXBUF(0), elements));
+ BEGIN_RING(chan, eng3d, NV30_3D_VTXBUF(0), elements);
for (unsigned i = 0; i < elements; i++)
OUT_RING(chan, 0);
- OUT_RING(chan, RING_3D(0x1710, 1));
+ BEGIN_RING(chan, eng3d, 0x1710, 1);
OUT_RING(chan, 0);
nvfx->hw_vtxelt_nr = num_outputs;
@@ -407,6 +407,7 @@ static void
nvfx_idxbuf_emit(struct nvfx_context* nvfx, unsigned ib_flags)
{
struct nouveau_channel* chan = nvfx->screen->base.channel;
+ struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
unsigned ib_format = (nvfx->idxbuf.index_size == 2) ? NV30_3D_IDXBUF_FORMAT_TYPE_U16 : NV30_3D_IDXBUF_FORMAT_TYPE_U32;
struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf.buffer)->bo;
ib_flags |= nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD;