All of lore.kernel.org
 help / color / mirror / Atom feed
* mesa: Patch that fix/add missing WAIT_RING calls
@ 2010-12-16 11:22 Michel Hermier
       [not found] ` <AANLkTinj4TObB1Mb9mG3T74OQiyKd+vK1Dk-WYuT6=Qc-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 5+ messages in thread
From: Michel Hermier @ 2010-12-16 11:22 UTC (permalink / raw)
  To: nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

[-- Attachment #1: Type: text/plain, Size: 305 bytes --]

Hi,
While trying to run a 3D app I needed to modify/add some WAIT_RING
calls so the push buffer is properly checked, before we try to blindly
push to it (sine OUT_RING don't perform this checks yet, I have a
small patch for that for libdrm).
I allready discussed about it with lynxeye and shining on IRC.

[-- Attachment #2: WAIT_RING-fixes.diff --]
[-- Type: application/octet-stream, Size: 10356 bytes --]

diff --git a/src/gallium/drivers/nvfx/nvfx_draw.c b/src/gallium/drivers/nvfx/nvfx_draw.c
index 61f888a..0d14e44 100644
--- a/src/gallium/drivers/nvfx/nvfx_draw.c
+++ b/src/gallium/drivers/nvfx/nvfx_draw.c
@@ -30,7 +30,7 @@ nvfx_render_flush(struct draw_stage *stage, unsigned flags)
 	struct nouveau_channel *chan = nvfx->screen->base.channel;
 
 	if (rs->prim != NV30_3D_VERTEX_BEGIN_END_STOP) {
-		assert(AVAIL_RING(chan) >= 2);
+		WAIT_RING(chan, 2);
 		OUT_RING(chan, RING_3D(NV30_3D_VERTEX_BEGIN_END, 1));
 		OUT_RING(chan, NV30_3D_VERTEX_BEGIN_END_STOP);
 		rs->prim = NV30_3D_VERTEX_BEGIN_END_STOP;
@@ -63,6 +63,7 @@ nvfx_render_prim(struct draw_stage *stage, struct prim_header *prim,
 	/* Switch primitive modes if necessary */
 	if (rs->prim != mode) {
 		if (rs->prim != NV30_3D_VERTEX_BEGIN_END_STOP) {
+			WAIT_RING(chan, 2);
 			OUT_RING(chan, RING_3D(NV30_3D_VERTEX_BEGIN_END, 1));
 			OUT_RING(chan, NV30_3D_VERTEX_BEGIN_END_STOP);
 		}
@@ -74,16 +75,19 @@ nvfx_render_prim(struct draw_stage *stage, struct prim_header *prim,
 			int i;
 			for(i = 0; i < 32; ++i)
 			{
+				WAIT_RING(chan, 2);
 				OUT_RING(chan, RING_3D(0x1dac, 1));
 				OUT_RING(chan, 0);
 			}
 		}
 
+		WAIT_RING(chan, 2);
 		OUT_RING(chan, RING_3D(NV30_3D_VERTEX_BEGIN_END, 1));
 		OUT_RING  (chan, mode);
 		rs->prim = mode;
 	}
 
+	WAIT_RING(chan, num_attribs * 4 * count + 1);
 	OUT_RING(chan, RING_3D_NI(NV30_3D_VERTEX_DATA, num_attribs * 4 * count));
 	if(no_elements) {
 		OUT_RING(chan, 0);
diff --git a/src/gallium/drivers/nvfx/nvfx_push.c b/src/gallium/drivers/nvfx/nvfx_push.c
index ebf47e6..ecde30b 100644
--- a/src/gallium/drivers/nvfx/nvfx_push.c
+++ b/src/gallium/drivers/nvfx/nvfx_push.c
@@ -29,6 +29,7 @@ emit_edgeflag(void *priv, boolean enabled)
 	struct push_context* ctx = priv;
 	struct nouveau_channel *chan = ctx->chan;
 
+	WAIT_RING(chan, 2);
 	OUT_RING(chan, RING_3D(NV30_3D_EDGEFLAG, 1));
 	OUT_RING(chan, enabled ? 1 : 0);
 }
@@ -44,6 +45,7 @@ emit_vertices_lookup8(void *priv, unsigned start, unsigned count)
                 unsigned push = MIN2(count, ctx->max_vertices_per_packet);
                 unsigned length = push * ctx->vertex_length;
 
+		WAIT_RING(ctx->chan, length + 1);
                 OUT_RING(ctx->chan, RING_3D_NI(NV30_3D_VERTEX_DATA, length));
                 ctx->translate->run_elts8(ctx->translate, elts, push, 0, ctx->chan->cur);
                 ctx->chan->cur += length;
@@ -64,6 +66,7 @@ emit_vertices_lookup16(void *priv, unsigned start, unsigned count)
                 unsigned push = MIN2(count, ctx->max_vertices_per_packet);
                 unsigned length = push * ctx->vertex_length;
 
+		WAIT_RING(ctx->chan, length + 1);
                 OUT_RING(ctx->chan, RING_3D_NI(NV30_3D_VERTEX_DATA, length));
                 ctx->translate->run_elts16(ctx->translate, elts, push, 0, ctx->chan->cur);
                 ctx->chan->cur += length;
@@ -84,6 +87,7 @@ emit_vertices_lookup32(void *priv, unsigned start, unsigned count)
                 unsigned push = MIN2(count, ctx->max_vertices_per_packet);
                 unsigned length = push * ctx->vertex_length;
 
+		WAIT_RING(ctx->chan, length + 1);
                 OUT_RING(ctx->chan, RING_3D_NI(NV30_3D_VERTEX_DATA, length));
                 ctx->translate->run_elts(ctx->translate, elts, push, 0, ctx->chan->cur);
                 ctx->chan->cur += length;
@@ -103,6 +107,7 @@ emit_vertices(void *priv, unsigned start, unsigned count)
 		unsigned push = MIN2(count, ctx->max_vertices_per_packet);
 		unsigned length = push * ctx->vertex_length;
 
+		WAIT_RING(ctx->chan, length + 1);
 		OUT_RING(ctx->chan, RING_3D_NI(NV30_3D_VERTEX_DATA, length));
 		ctx->translate->run(ctx->translate, start, push, 0, ctx->chan->cur);
 		ctx->chan->cur += length;
@@ -119,8 +124,9 @@ emit_ranges(void* priv, unsigned start, unsigned vc, unsigned reg)
 	struct nouveau_channel *chan = ctx->chan;
 	unsigned nr = (vc & 0xff);
 	if (nr) {
+		WAIT_RING(chan, 2);
 		OUT_RING(chan, RING_3D(reg, 1));
-		OUT_RING  (chan, ((nr - 1) << 24) | start);
+		OUT_RING(chan, ((nr - 1) << 24) | start);
 		start += nr;
 	}
 
@@ -130,6 +136,7 @@ emit_ranges(void* priv, unsigned start, unsigned vc, unsigned reg)
 
 		nr -= push;
 
+		WAIT_RING(chan, push + 1);
 		OUT_RING(chan, RING_3D_NI(reg, push));
 		while (push--) {
 			OUT_RING(chan, ((0x100 - 1) << 24) | start);
@@ -159,8 +166,9 @@ emit_elt8(void* priv, unsigned start, unsigned vc)
 	int idxbias = ctx->idxbias;
 
 	if (vc & 1) {
+		WAIT_RING(chan, 2);
 		OUT_RING(chan, RING_3D(NV30_3D_VB_ELEMENT_U32, 1));
-		OUT_RING  (chan, elts[0]);
+		OUT_RING(chan, elts[0]);
 		elts++; vc--;
 	}
 
@@ -168,6 +176,7 @@ emit_elt8(void* priv, unsigned start, unsigned vc)
 		unsigned i;
 		unsigned push = MIN2(vc, 2047 * 2);
 
+		WAIT_RING(chan, (push >> 1) + 1);
 		OUT_RING(chan, RING_3D_NI(NV30_3D_VB_ELEMENT_U16, push >> 1));
 		for (i = 0; i < push; i+=2)
 			OUT_RING(chan, ((elts[i+1] + idxbias) << 16) | (elts[i] + idxbias));
@@ -186,6 +195,7 @@ emit_elt16(void* priv, unsigned start, unsigned vc)
 	int idxbias = ctx->idxbias;
 
 	if (vc & 1) {
+		WAIT_RING(chan, 2);
 		OUT_RING(chan, RING_3D(NV30_3D_VB_ELEMENT_U32, 1));
 		OUT_RING  (chan, elts[0]);
 		elts++; vc--;
@@ -195,6 +205,7 @@ emit_elt16(void* priv, unsigned start, unsigned vc)
 		unsigned i;
 		unsigned push = MIN2(vc, 2047 * 2);
 
+		WAIT_RING(chan, (push >> 1) + 1);
 		OUT_RING(chan, RING_3D_NI(NV30_3D_VB_ELEMENT_U16, push >> 1));
 		for (i = 0; i < push; i+=2)
 			OUT_RING(chan, ((elts[i+1] + idxbias) << 16) | (elts[i] + idxbias));
@@ -215,6 +226,7 @@ emit_elt32(void* priv, unsigned start, unsigned vc)
 	while (vc) {
 		unsigned push = MIN2(vc, 2047);
 
+		WAIT_RING(chan, push + 1);
 		OUT_RING(chan, RING_3D_NI(NV30_3D_VB_ELEMENT_U32, push));
 		assert(AVAIL_RING(chan) >= push);
 		if(idxbias)
@@ -374,14 +386,17 @@ nvfx_push_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 					int i;
 					for(i = 0; i < 32; ++i)
 					{
+						WAIT_RING(chan, 2);
 						OUT_RING(chan, RING_3D(0x1dac, 1));
 						OUT_RING(chan, 0);
 					}
 				}
 
+				WAIT_RING(chan, 2);
 				OUT_RING(chan, RING_3D(NV30_3D_VERTEX_BEGIN_END, 1));
 				OUT_RING(chan, hw_mode);
 				done = util_split_prim_next(&s, max_verts);
+				WAIT_RING(chan, 2);
 				OUT_RING(chan, RING_3D(NV30_3D_VERTEX_BEGIN_END, 1));
 				OUT_RING(chan, 0);
 
diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c
index 501fdd4..670ef39 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_emit.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c
@@ -130,7 +130,7 @@ nvfx_ucp_validate(struct nvfx_context* nvfx)
 		OUT_RING(chan, RING_3D(NV30_3D_VP_CLIP_PLANES_ENABLE, 1));
 		OUT_RING(chan, 0);
 
-		WAIT_RING(chan, 6 * 4 + 1);
+		WAIT_RING(chan, nvfx->clip.nr * 4 + 1);
 		OUT_RING(chan, RING_3D(NV30_3D_VP_CLIP_PLANE(0, 0), nvfx->clip.nr * 4));
 		OUT_RINGp(chan, &nvfx->clip.ucp[0][0], nvfx->clip.nr * 4);
 	}
@@ -155,6 +155,7 @@ nvfx_vertprog_ucp_validate(struct nvfx_context* nvfx)
 		if(vp->clip_nr >= 0)
 		{
 			idx = vp->nr_insns - 7 + vp->clip_nr;
+			WAIT_RING(chan, 7);
 			OUT_RING(chan, RING_3D(NV30_3D_VP_UPLOAD_FROM_ID, 1));
 			OUT_RING(chan,  vp->exec->start + idx);
 			OUT_RING(chan, RING_3D(NV30_3D_VP_UPLOAD_INST(0), 4));
@@ -163,6 +164,7 @@ nvfx_vertprog_ucp_validate(struct nvfx_context* nvfx)
 
 		 /* set last instruction bit */
 		idx = vp->nr_insns - 7 + nvfx->clip.nr;
+		WAIT_RING(chan, 7);
 		OUT_RING(chan, RING_3D(NV30_3D_VP_UPLOAD_FROM_ID, 1));
 		OUT_RING(chan,  vp->exec->start + idx);
 		OUT_RING(chan, RING_3D(NV30_3D_VP_UPLOAD_INST(0), 4));
@@ -172,9 +174,9 @@ nvfx_vertprog_ucp_validate(struct nvfx_context* nvfx)
 	}
 
 	// TODO: only do this for the ones changed
-	WAIT_RING(chan, 6 * 6);
 	for(i = 0; i < nvfx->clip.nr; ++i)
 	{
+		WAIT_RING(chan, 6);
 		OUT_RING(chan, RING_3D(NV30_3D_VP_UPLOAD_CONST_ID, 5));
 		OUT_RING(chan, vp->data->start + i);
 		OUT_RINGp (chan, nvfx->clip.ucp[i], 4);
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index 597664e..6641c15 100644
--- a/src/gallium/drivers/nvfx/nvfx_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -254,7 +254,6 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
 	if (!elements)
 		return TRUE;
 
-	MARK_RING(chan, (5 + 2) * 16 + 2 + 11, 16 + 2);
 	for(unsigned i = 0; i < nvfx->vtxelt->num_constant; ++i)
 	{
 		struct nvfx_low_frequency_element *ve = &nvfx->vtxelt->constant[i];
@@ -262,10 +261,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);
+		WAIT_RING(chan, ve->ncomp + 1);
 		nvfx_emit_vtx_attr(chan, ve->idx, v, ve->ncomp);
 	}
 
-
+	WAIT_RING(chan, elements + 1);
 	OUT_RING(chan, RING_3D(NV30_3D_VTXFMT(0), elements));
 	if(nvfx->use_vertex_buffers)
 	{
@@ -297,11 +297,13 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
 		unsigned i;
 		/* seems to be some kind of cache flushing */
 		for(i = 0; i < 3; ++i) {
+			WAIT_RING(chan, 2);
 			OUT_RING(chan, RING_3D(0x1718, 1));
 			OUT_RING(chan, 0);
 		}
 	}
 
+	MARK_RING(chan, elements + 1, nvfx->vtxelt->num_per_vertex);
 	OUT_RING(chan, RING_3D(NV30_3D_VTXBUF(0), elements));
 	if(nvfx->use_vertex_buffers)
 	{
@@ -330,6 +332,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
 			OUT_RING(chan, 0);
 	}
 
+	WAIT_RING(chan, 2);
 	OUT_RING(chan, RING_3D(0x1710, 1));
 	OUT_RING(chan, 0);
 
@@ -348,8 +351,7 @@ nvfx_vbo_swtnl_validate(struct nvfx_context *nvfx)
 	if (!elements)
 		return;
 
-	WAIT_RING(chan, (1 + 6 + 1 + 2) + elements * 2);
-
+	WAIT_RING(chan, elements + 1);
 	OUT_RING(chan, RING_3D(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);
@@ -360,15 +362,18 @@ nvfx_vbo_swtnl_validate(struct nvfx_context *nvfx)
 		unsigned i;
 		/* seems to be some kind of cache flushing */
 		for(i = 0; i < 3; ++i) {
+			WAIT_RING(chan, 2);
 			OUT_RING(chan, RING_3D(0x1718, 1));
 			OUT_RING(chan, 0);
 		}
 	}
 
+	WAIT_RING(chan, elements +1);
 	OUT_RING(chan, RING_3D(NV30_3D_VTXBUF(0), elements));
 	for (unsigned i = 0; i < elements; i++)
 		OUT_RING(chan, 0);
 
+	WAIT_RING(chan, 2);
 	OUT_RING(chan, RING_3D(0x1710, 1));
 	OUT_RING(chan, 0);
 

[-- Attachment #3: Type: text/plain, Size: 181 bytes --]

_______________________________________________
Nouveau mailing list
Nouveau-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
http://lists.freedesktop.org/mailman/listinfo/nouveau

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-12-20  9:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-16 11:22 mesa: Patch that fix/add missing WAIT_RING calls Michel Hermier
     [not found] ` <AANLkTinj4TObB1Mb9mG3T74OQiyKd+vK1Dk-WYuT6=Qc-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-12-16 16:20   ` Lucas Stach
2010-12-17  9:23     ` Michel Hermier
2010-12-19 13:32   ` Xavier Chantry
     [not found]     ` <AANLkTikmqfYmmNqrNxYAn9f2KiP6V2fk01uCLuOnGZSj-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2010-12-20  9:16       ` Michel Hermier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.