Mesa (master): r300: fix vertex programs with big number of params (>255) under KMS

Brian Paul brianp at kemper.freedesktop.org
Thu Mar 25 22:14:02 UTC 2010


Module: Mesa
Branch: master
Commit: 7a77effb0b7eeefd5eb350aa9a487e10f62eb7ed
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7a77effb0b7eeefd5eb350aa9a487e10f62eb7ed

Author: Maciej Cencora <m.cencora at gmail.com>
Date:   Sun Mar 21 12:10:06 2010 +0100

r300: fix vertex programs with big number of params (>255) under KMS

UMS will probably require some kernel work

---

 src/mesa/drivers/dri/r300/r300_cmdbuf.c   |   40 ++++++++++++++++++++++++----
 src/mesa/drivers/dri/r300/r300_vertprog.c |    6 +++-
 2 files changed, 39 insertions(+), 7 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index 6cfa568..8eb596d 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -83,6 +83,23 @@ static int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom)
 	return cnt ? (cnt * 4) + extra : 0;
 }
 
+static int check_vpp(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+    r300ContextPtr r300 = R300_CONTEXT(ctx);
+    int cnt;
+    int extra = 1;
+
+    if (r300->radeon.radeonScreen->kernel_mm) {
+        cnt = r300->selected_vp->code.constants.Count * 4;
+        extra = 5;
+    } else {
+        cnt = vpu_count(atom->cmd);
+        extra = 1;
+    }
+
+    return cnt ? (cnt * 4) + extra : 0;
+}
+
 void r300_emit_vpu(struct r300_context *r300,
                    uint32_t *data,
                    unsigned len,
@@ -101,15 +118,26 @@ static void emit_vpu_state(GLcontext *ctx, struct radeon_state_atom * atom)
 {
     r300ContextPtr r300 = R300_CONTEXT(ctx);
     drm_r300_cmd_header_t cmd;
-    uint32_t addr, ndw;
+    uint32_t addr;
 
     cmd.u = atom->cmd[0];
     addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo;
-    ndw = atom->check(ctx, atom);
 
     r300_emit_vpu(r300, &atom->cmd[1], vpu_count(atom->cmd) * 4, addr);
 }
 
+static void emit_vpp_state(GLcontext *ctx, struct radeon_state_atom * atom)
+{
+    r300ContextPtr r300 = R300_CONTEXT(ctx);
+    drm_r300_cmd_header_t cmd;
+    uint32_t addr;
+
+    cmd.u = atom->cmd[0];
+    addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo;
+
+    r300_emit_vpu(r300, &atom->cmd[1], r300->selected_vp->code.constants.Count * 4, addr);
+}
+
 void r500_emit_fp(struct r300_context *r300,
                   uint32_t *data,
                   unsigned len,
@@ -784,11 +812,11 @@ void r300InitCmdBuf(r300ContextPtr r300)
 			r300->hw.vpi.emit = emit_vpu_state;
 
 		if (is_r500) {
-			ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
+			ALLOC_STATE(vpp, vpp, R300_VPP_CMDSIZE, 0);
 			r300->hw.vpp.cmd[0] =
 				cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0);
 			if (r300->radeon.radeonScreen->kernel_mm)
-				r300->hw.vpp.emit = emit_vpu_state;
+				r300->hw.vpp.emit = emit_vpp_state;
 
 			ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
 			r300->hw.vps.cmd[0] =
@@ -805,11 +833,11 @@ void r300InitCmdBuf(r300ContextPtr r300)
 					r300->hw.vpucp[i].emit = emit_vpu_state;
 			}
 		} else {
-			ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
+			ALLOC_STATE(vpp, vpp, R300_VPP_CMDSIZE, 0);
 			r300->hw.vpp.cmd[0] =
 				cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0);
 			if (r300->radeon.radeonScreen->kernel_mm)
-				r300->hw.vpp.emit = emit_vpu_state;
+				r300->hw.vpp.emit = emit_vpp_state;
 
 			ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
 			r300->hw.vps.cmd[0] =
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index e77cd61..53fe948 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -392,7 +392,11 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
 	R300_STATECHANGE(rmesa, vap_cntl);
 	R300_STATECHANGE(rmesa, vpp);
 	param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
-	bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
+	if (!rmesa->radeon.radeonScreen->kernel_mm && param_count > 255 * 4) {
+		WARN_ONCE("Too many VP params, expect rendering errors\n");
+	}
+	/* Prevent the overflow (vpu.count is u8) */
+	bump_vpu_count(rmesa->hw.vpp.cmd, MIN2(255 * 4, param_count));
 	param_count /= 4;
 
 	r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->code));




More information about the mesa-commit mailing list