From 5f0f9f0486e9cf43939dfbd1051298f05da1eec4 Mon Sep 17 00:00:00 2001 From: Xavier Chantry Date: Sat, 25 Dec 2010 16:39:01 +0100 Subject: nvfx: restore BEGIN_RING usage Michel Hermier reported libdrm segfault (and kernel crash) on nv40 using gallium : http://www.mail-archive.com/nouveau@lists.freedesktop.org/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 Signed-off-by: Francisco Jerez --- src/gallium/drivers/nvfx/nvfx_context.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/gallium/drivers/nvfx/nvfx_context.h') diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index 6ef2a6945d7..2238aa1ad0e 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -339,30 +339,31 @@ extern void nvfx_init_vertprog_functions(struct nvfx_context *nvfx); /* nvfx_push.c */ extern void nvfx_push_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info); -/* must WAIT_RING(chan, ncomp + 1) or equivalent beforehand! */ -static inline void nvfx_emit_vtx_attr(struct nouveau_channel* chan, unsigned attrib, const float* v, unsigned ncomp) +static inline void nvfx_emit_vtx_attr(struct nouveau_channel* chan, + struct nouveau_grobj *eng3d, unsigned attrib, const float* v, + unsigned ncomp) { switch (ncomp) { case 4: - OUT_RING(chan, RING_3D(NV30_3D_VTX_ATTR_4F_X(attrib), 4)); + BEGIN_RING(chan, eng3d, NV30_3D_VTX_ATTR_4F_X(attrib), 4); OUT_RING(chan, fui(v[0])); OUT_RING(chan, fui(v[1])); OUT_RING(chan, fui(v[2])); OUT_RING(chan, fui(v[3])); break; case 3: - OUT_RING(chan, RING_3D(NV30_3D_VTX_ATTR_3F_X(attrib), 3)); + BEGIN_RING(chan, eng3d, NV30_3D_VTX_ATTR_3F_X(attrib), 3); OUT_RING(chan, fui(v[0])); OUT_RING(chan, fui(v[1])); OUT_RING(chan, fui(v[2])); break; case 2: - OUT_RING(chan, RING_3D(NV30_3D_VTX_ATTR_2F_X(attrib), 2)); + BEGIN_RING(chan, eng3d, NV30_3D_VTX_ATTR_2F_X(attrib), 2); OUT_RING(chan, fui(v[0])); OUT_RING(chan, fui(v[1])); break; case 1: - OUT_RING(chan, RING_3D(NV30_3D_VTX_ATTR_1F(attrib), 1)); + BEGIN_RING(chan, eng3d, NV30_3D_VTX_ATTR_1F(attrib), 1); OUT_RING(chan, fui(v[0])); break; } -- cgit v1.2.3