Mesa (master): freedreno: Split ir3_const's user buffer and indirect upload APIs.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Aug 5 23:25:22 UTC 2020


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

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jul  9 16:57:29 2020 -0700

freedreno: Split ir3_const's user buffer and indirect upload APIs.

They're almost entirely split by whether you're uploading user buffer or
from a BO.  While I'm rewriting the API, drop the emit_const ->
fdN_emit_const wrapper in favor of a #define before the header and a
little helper for the asserts.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5990>

---

 src/gallium/drivers/freedreno/a3xx/fd3_emit.c  |  70 +++++------
 src/gallium/drivers/freedreno/a4xx/fd4_emit.c  |  68 +++++------
 src/gallium/drivers/freedreno/a5xx/fd5_emit.c  |  69 +++++------
 src/gallium/drivers/freedreno/a6xx/fd6_const.c | 156 ++++++++++++-------------
 src/gallium/drivers/freedreno/ir3/ir3_const.h  |  57 ++++++---
 5 files changed, 199 insertions(+), 221 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 09817c092e5..5d5be9d39e8 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -43,6 +43,8 @@
 #include "fd3_format.h"
 #include "fd3_zsa.h"
 
+#define emit_const_user fd3_emit_const_user
+#define emit_const_bo fd3_emit_const_bo
 #include "ir3_const.h"
 
 static const enum adreno_state_block sb[] = {
@@ -55,41 +57,37 @@ static const enum adreno_state_block sb[] = {
  * sizedwords:     size of const value buffer
  */
 static void
-fd3_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
-		uint32_t regid, uint32_t offset, uint32_t sizedwords,
-		const uint32_t *dwords, struct pipe_resource *prsc)
+fd3_emit_const_user(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v,
+		uint32_t regid, uint32_t sizedwords, const uint32_t *dwords)
 {
-	uint32_t i, sz;
-	enum adreno_state_src src;
-
-	debug_assert((regid % 4) == 0);
-	debug_assert((sizedwords % 4) == 0);
-
-	if (prsc) {
-		sz = 0;
-		src = SS_INDIRECT;
-	} else {
-		sz = sizedwords;
-		src = SS_DIRECT;
-	}
+	emit_const_asserts(ring, v, regid, sizedwords);
 
-	OUT_PKT3(ring, CP_LOAD_STATE, 2 + sz);
+	OUT_PKT3(ring, CP_LOAD_STATE, 2 + sizedwords);
 	OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid/2) |
-			CP_LOAD_STATE_0_STATE_SRC(src) |
-			CP_LOAD_STATE_0_STATE_BLOCK(sb[type]) |
+			CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
+			CP_LOAD_STATE_0_STATE_BLOCK(sb[v->type]) |
 			CP_LOAD_STATE_0_NUM_UNIT(sizedwords/2));
-	if (prsc) {
-		struct fd_bo *bo = fd_resource(prsc)->bo;
-		OUT_RELOC(ring, bo, offset,
-				CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS), 0);
-	} else {
-		OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) |
-				CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS));
-		dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
-	}
-	for (i = 0; i < sz; i++) {
+	OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) |
+			CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS));
+	for (int i = 0; i < sizedwords; i++)
 		OUT_RING(ring, dwords[i]);
-	}
+}
+
+static void
+fd3_emit_const_bo(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,
+		uint32_t regid, uint32_t offset, uint32_t sizedwords,
+		struct fd_bo *bo)
+{
+	emit_const_asserts(ring, v, regid, sizedwords);
+
+	OUT_PKT3(ring, CP_LOAD_STATE, 2);
+	OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid/2) |
+			CP_LOAD_STATE_0_STATE_SRC(SS_INDIRECT) |
+			CP_LOAD_STATE_0_STATE_BLOCK(sb[v->type]) |
+			CP_LOAD_STATE_0_NUM_UNIT(sizedwords/2));
+	OUT_RELOC(ring, bo, offset,
+			CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS), 0);
 }
 
 static void
@@ -127,18 +125,6 @@ is_stateobj(struct fd_ringbuffer *ring)
 	return false;
 }
 
-void
-emit_const(struct fd_ringbuffer *ring,
-		const struct ir3_shader_variant *v, uint32_t dst_offset,
-		uint32_t offset, uint32_t size, const void *user_buffer,
-		struct pipe_resource *buffer)
-{
-	/* TODO inline this */
-	assert(dst_offset + size <= v->constlen * 4);
-	fd3_emit_const(ring, v->type, dst_offset,
-			offset, size, user_buffer, buffer);
-}
-
 static void
 emit_const_ptrs(struct fd_ringbuffer *ring,
 		const struct ir3_shader_variant *v, uint32_t dst_offset,
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
index 9e9f80b43b0..603a81f7536 100644
--- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
+++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c
@@ -43,6 +43,8 @@
 #include "fd4_format.h"
 #include "fd4_zsa.h"
 
+#define emit_const_user fd4_emit_const_user
+#define emit_const_bo fd4_emit_const_bo
 #include "ir3_const.h"
 
 /* regid:          base const register
@@ -50,41 +52,37 @@
  * sizedwords:     size of const value buffer
  */
 static void
-fd4_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
-		uint32_t regid, uint32_t offset, uint32_t sizedwords,
-		const uint32_t *dwords, struct pipe_resource *prsc)
+fd4_emit_const_user(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v, uint32_t regid, uint32_t sizedwords,
+		const uint32_t *dwords)
 {
-	uint32_t i, sz;
-	enum a4xx_state_src src;
+	emit_const_asserts(ring, v, regid, sizedwords);
 
-	debug_assert((regid % 4) == 0);
-	debug_assert((sizedwords % 4) == 0);
+	OUT_PKT3(ring, CP_LOAD_STATE4, 2 + sizedwords);
+	OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
+			CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
+			CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
+			CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
+	OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
+			CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
+	for (int i = 0; i < sizedwords; i++)
+		OUT_RING(ring, dwords[i]);
+}
 
-	if (prsc) {
-		sz = 0;
-		src = SS4_INDIRECT;
-	} else {
-		sz = sizedwords;
-		src = SS4_DIRECT;
-	}
+static void
+fd4_emit_const_bo(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,
+		uint32_t regid, uint32_t offset, uint32_t sizedwords,
+		struct fd_bo *bo)
+{
+	emit_const_asserts(ring, v, regid, sizedwords);
 
-	OUT_PKT3(ring, CP_LOAD_STATE4, 2 + sz);
+	OUT_PKT3(ring, CP_LOAD_STATE4, 2);
 	OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
-			CP_LOAD_STATE4_0_STATE_SRC(src) |
-			CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(type)) |
+			CP_LOAD_STATE4_0_STATE_SRC(SS4_INDIRECT) |
+			CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
 			CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
-	if (prsc) {
-		struct fd_bo *bo = fd_resource(prsc)->bo;
-		OUT_RELOC(ring, bo, offset,
-				CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
-	} else {
-		OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
-				CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
-		dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
-	}
-	for (i = 0; i < sz; i++) {
-		OUT_RING(ring, dwords[i]);
-	}
+	OUT_RELOC(ring, bo, offset,
+			CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
 }
 
 static void
@@ -122,18 +120,6 @@ is_stateobj(struct fd_ringbuffer *ring)
 	return false;
 }
 
-void
-emit_const(struct fd_ringbuffer *ring,
-		const struct ir3_shader_variant *v, uint32_t dst_offset,
-		uint32_t offset, uint32_t size, const void *user_buffer,
-		struct pipe_resource *buffer)
-{
-	/* TODO inline this */
-	assert(dst_offset + size <= v->constlen * 4);
-	fd4_emit_const(ring, v->type, dst_offset,
-			offset, size, user_buffer, buffer);
-}
-
 static void
 emit_const_ptrs(struct fd_ringbuffer *ring,
 		const struct ir3_shader_variant *v, uint32_t dst_offset,
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
index 62bcfd1ca18..1a1037c3a0e 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
@@ -46,6 +46,8 @@
 #include "fd5_format.h"
 #include "fd5_zsa.h"
 
+#define emit_const_user fd5_emit_const_user
+#define emit_const_bo fd5_emit_const_bo
 #include "ir3_const.h"
 
 /* regid:          base const register
@@ -53,42 +55,37 @@
  * sizedwords:     size of const value buffer
  */
 static void
-fd5_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
-		uint32_t regid, uint32_t offset, uint32_t sizedwords,
-		const uint32_t *dwords, struct pipe_resource *prsc)
+fd5_emit_const_user(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v, uint32_t regid, uint32_t sizedwords,
+		const uint32_t *dwords)
 {
-	uint32_t i, sz;
-	enum a4xx_state_src src;
+	emit_const_asserts(ring, v, regid, sizedwords);
 
-	debug_assert((regid % 4) == 0);
-	debug_assert((sizedwords % 4) == 0);
+	OUT_PKT7(ring, CP_LOAD_STATE4, 3 + sizedwords);
+	OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
+			CP_LOAD_STATE4_0_STATE_SRC(SS4_DIRECT) |
+			CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
+			CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
+	OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
+			CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
+	OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
+	for (int i = 0; i < sizedwords; i++)
+		OUT_RING(ring, ((uint32_t *)dwords)[i]);
+}
 
-	if (prsc) {
-		sz = 0;
-		src = SS4_INDIRECT;
-	} else {
-		sz = sizedwords;
-		src = SS4_DIRECT;
-	}
+static void
+fd5_emit_const_bo(struct fd_ringbuffer *ring, const struct ir3_shader_variant *v,
+		uint32_t regid, uint32_t offset, uint32_t sizedwords, struct fd_bo *bo)
+{
+	emit_const_asserts(ring, v, regid, sizedwords);
 
-	OUT_PKT7(ring, CP_LOAD_STATE4, 3 + sz);
+	OUT_PKT7(ring, CP_LOAD_STATE4, 3);
 	OUT_RING(ring, CP_LOAD_STATE4_0_DST_OFF(regid/4) |
-			CP_LOAD_STATE4_0_STATE_SRC(src) |
-			CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(type)) |
+			CP_LOAD_STATE4_0_STATE_SRC(SS4_INDIRECT) |
+			CP_LOAD_STATE4_0_STATE_BLOCK(fd4_stage2shadersb(v->type)) |
 			CP_LOAD_STATE4_0_NUM_UNIT(sizedwords/4));
-	if (prsc) {
-		struct fd_bo *bo = fd_resource(prsc)->bo;
-		OUT_RELOC(ring, bo, offset,
-				CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
-	} else {
-		OUT_RING(ring, CP_LOAD_STATE4_1_EXT_SRC_ADDR(0) |
-				CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS));
-		OUT_RING(ring, CP_LOAD_STATE4_2_EXT_SRC_ADDR_HI(0));
-		dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
-	}
-	for (i = 0; i < sz; i++) {
-		OUT_RING(ring, dwords[i]);
-	}
+	OUT_RELOC(ring, bo, offset,
+			CP_LOAD_STATE4_1_STATE_TYPE(ST4_CONSTANTS), 0);
 }
 
 static void
@@ -130,18 +127,6 @@ is_stateobj(struct fd_ringbuffer *ring)
 	return false;
 }
 
-void
-emit_const(struct fd_ringbuffer *ring,
-		const struct ir3_shader_variant *v, uint32_t dst_offset,
-		uint32_t offset, uint32_t size, const void *user_buffer,
-		struct pipe_resource *buffer)
-{
-	/* TODO inline this */
-	assert(dst_offset + size <= v->constlen * 4);
-	fd5_emit_const(ring, v->type, dst_offset,
-			offset, size, user_buffer, buffer);
-}
-
 static void
 emit_const_ptrs(struct fd_ringbuffer *ring,
 		const struct ir3_shader_variant *v, uint32_t dst_offset,
diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_const.c b/src/gallium/drivers/freedreno/a6xx/fd6_const.c
index ecd81f5aff2..419a22d0708 100644
--- a/src/gallium/drivers/freedreno/a6xx/fd6_const.c
+++ b/src/gallium/drivers/freedreno/a6xx/fd6_const.c
@@ -25,82 +25,88 @@
 #include "fd6_const.h"
 #include "fd6_pack.h"
 
+#define emit_const_user fd6_emit_const_user
+#define emit_const_bo fd6_emit_const_bo
 #include "ir3_const.h"
 
 /* regid:          base const register
  * prsc or dwords: buffer containing constant values
  * sizedwords:     size of const value buffer
  */
-static void
-fd6_emit_const(struct fd_ringbuffer *ring, gl_shader_stage type,
-		uint32_t regid, uint32_t offset, uint32_t sizedwords,
-		const uint32_t *dwords, struct pipe_resource *prsc)
+void
+fd6_emit_const_user(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v, uint32_t regid,
+		uint32_t sizedwords, const uint32_t *dwords)
 {
-	if (prsc) {
-		struct fd_bo *bo = fd_resource(prsc)->bo;
-
-		if (fd6_geom_stage(type)) {
-			OUT_PKT(ring, CP_LOAD_STATE6_GEOM,
-					CP_LOAD_STATE6_0(
-							.dst_off     = regid/4,
-							.state_type  = ST6_CONSTANTS,
-							.state_src   = SS6_INDIRECT,
-							.state_block = fd6_stage2shadersb(type),
-							.num_unit    = DIV_ROUND_UP(sizedwords, 4)
-						),
-					CP_LOAD_STATE6_EXT_SRC_ADDR(
-							.bo          = bo,
-							.bo_offset   = offset
-						)
-				);
-		} else {
-			OUT_PKT(ring, CP_LOAD_STATE6_FRAG,
-					CP_LOAD_STATE6_0(
-							.dst_off     = regid/4,
-							.state_type  = ST6_CONSTANTS,
-							.state_src   = SS6_INDIRECT,
-							.state_block = fd6_stage2shadersb(type),
-							.num_unit    = DIV_ROUND_UP(sizedwords, 4)
-						),
-					CP_LOAD_STATE6_EXT_SRC_ADDR(
-							.bo          = bo,
-							.bo_offset   = offset
-						)
-				);
-		}
+	emit_const_asserts(ring, v, regid, sizedwords);
+
+	/* NOTE we cheat a bit here, since we know mesa is aligning
+	 * the size of the user buffer to 16 bytes.  And we want to
+	 * cut cycles in a hot path.
+	 */
+	uint32_t align_sz = align(sizedwords, 4);
+
+	if (fd6_geom_stage(v->type)) {
+		OUT_PKTBUF(ring, CP_LOAD_STATE6_GEOM, dwords, align_sz,
+				CP_LOAD_STATE6_0(
+					.dst_off     = regid/4,
+					.state_type  = ST6_CONSTANTS,
+					.state_src   = SS6_DIRECT,
+					.state_block = fd6_stage2shadersb(v->type),
+					.num_unit    = DIV_ROUND_UP(sizedwords, 4)
+					),
+				CP_LOAD_STATE6_1(),
+				CP_LOAD_STATE6_2()
+			);
 	} else {
-		/* NOTE we cheat a bit here, since we know mesa is aligning
-		 * the size of the user buffer to 16 bytes.  And we want to
-		 * cut cycles in a hot path.
-		 */
-		uint32_t align_sz = align(sizedwords, 4);
-		dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
-
-		if (fd6_geom_stage(type)) {
-			OUT_PKTBUF(ring, CP_LOAD_STATE6_GEOM, dwords, align_sz,
-					CP_LOAD_STATE6_0(
-							.dst_off     = regid/4,
-							.state_type  = ST6_CONSTANTS,
-							.state_src   = SS6_DIRECT,
-							.state_block = fd6_stage2shadersb(type),
-							.num_unit    = DIV_ROUND_UP(sizedwords, 4)
-						),
-					CP_LOAD_STATE6_1(),
-					CP_LOAD_STATE6_2()
-				);
-		} else {
-			OUT_PKTBUF(ring, CP_LOAD_STATE6_FRAG, dwords, align_sz,
-					CP_LOAD_STATE6_0(
-							.dst_off     = regid/4,
-							.state_type  = ST6_CONSTANTS,
-							.state_src   = SS6_DIRECT,
-							.state_block = fd6_stage2shadersb(type),
-							.num_unit    = DIV_ROUND_UP(sizedwords, 4)
-						),
-					CP_LOAD_STATE6_1(),
-					CP_LOAD_STATE6_2()
-				);
-		}
+		OUT_PKTBUF(ring, CP_LOAD_STATE6_FRAG, dwords, align_sz,
+				CP_LOAD_STATE6_0(
+					.dst_off     = regid/4,
+					.state_type  = ST6_CONSTANTS,
+					.state_src   = SS6_DIRECT,
+					.state_block = fd6_stage2shadersb(v->type),
+					.num_unit    = DIV_ROUND_UP(sizedwords, 4)
+					),
+				CP_LOAD_STATE6_1(),
+				CP_LOAD_STATE6_2()
+			);
+	}
+}
+void
+fd6_emit_const_bo(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v, uint32_t regid,
+		uint32_t offset, uint32_t sizedwords, struct fd_bo *bo)
+{
+	emit_const_asserts(ring, v, regid, sizedwords);
+
+	if (fd6_geom_stage(v->type)) {
+		OUT_PKT(ring, CP_LOAD_STATE6_GEOM,
+				CP_LOAD_STATE6_0(
+					.dst_off     = regid/4,
+					.state_type  = ST6_CONSTANTS,
+					.state_src   = SS6_INDIRECT,
+					.state_block = fd6_stage2shadersb(v->type),
+					.num_unit    = DIV_ROUND_UP(sizedwords, 4)
+					),
+				CP_LOAD_STATE6_EXT_SRC_ADDR(
+					.bo          = bo,
+					.bo_offset   = offset
+					)
+			);
+	} else {
+		OUT_PKT(ring, CP_LOAD_STATE6_FRAG,
+				CP_LOAD_STATE6_0(
+					.dst_off     = regid/4,
+					.state_type  = ST6_CONSTANTS,
+					.state_src   = SS6_INDIRECT,
+					.state_block = fd6_stage2shadersb(v->type),
+					.num_unit    = DIV_ROUND_UP(sizedwords, 4)
+					),
+				CP_LOAD_STATE6_EXT_SRC_ADDR(
+					.bo          = bo,
+					.bo_offset   = offset
+					)
+			);
 	}
 }
 
@@ -110,18 +116,6 @@ is_stateobj(struct fd_ringbuffer *ring)
 	return true;
 }
 
-void
-emit_const(struct fd_ringbuffer *ring,
-		const struct ir3_shader_variant *v, uint32_t dst_offset,
-		uint32_t offset, uint32_t size, const void *user_buffer,
-		struct pipe_resource *buffer)
-{
-	/* TODO inline this */
-	assert(dst_offset + size <= v->constlen * 4);
-	fd6_emit_const(ring, v->type, dst_offset,
-			offset, size, user_buffer, buffer);
-}
-
 static void
 emit_const_ptrs(struct fd_ringbuffer *ring,
 		const struct ir3_shader_variant *v, uint32_t dst_offset,
@@ -155,7 +149,7 @@ emit_stage_tess_consts(struct fd_ringbuffer *ring, struct ir3_shader_variant *v,
 	const unsigned regid = const_state->offsets.primitive_param;
 	int size = MIN2(1 + regid, v->constlen) - regid;
 	if (size > 0)
-		fd6_emit_const(ring, v->type, regid * 4, 0, num_params, params, NULL);
+		fd6_emit_const_user(ring, v, regid * 4, num_params, params);
 }
 
 static void
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_const.h b/src/gallium/drivers/freedreno/ir3/ir3_const.h
index a17f3bc8a4f..f840e5ee1d7 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_const.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3_const.h
@@ -39,15 +39,37 @@
 
 static bool is_stateobj(struct fd_ringbuffer *ring);
 
-static void emit_const(struct fd_ringbuffer *ring,
-		const struct ir3_shader_variant *v, uint32_t dst_offset,
+static void emit_const_user(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v, uint32_t regid,
+		uint32_t size, const uint32_t *user_buffer);
+
+static void emit_const_bo(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v, uint32_t regid,
+		uint32_t offset, uint32_t size,
+		struct fd_bo *bo);
+
+static void emit_const_prsc(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v, uint32_t regid,
 		uint32_t offset, uint32_t size,
-		const void *user_buffer, struct pipe_resource *buffer);
+		struct pipe_resource *buffer)
+{
+	struct fd_resource *rsc = fd_resource(buffer);
+	emit_const_bo(ring, v, regid, offset, size, rsc->bo);
+}
 
 static void emit_const_ptrs(struct fd_ringbuffer *ring,
 		const struct ir3_shader_variant *v, uint32_t dst_offset,
 		uint32_t num, struct pipe_resource **prscs, uint32_t *offsets);
 
+static void
+emit_const_asserts(struct fd_ringbuffer *ring,
+		const struct ir3_shader_variant *v,
+		uint32_t regid, uint32_t sizedwords)
+{
+	assert((regid % 4) == 0);
+	assert((sizedwords % 4) == 0);
+	assert(regid + sizedwords <= v->constlen * 4);
+}
 
 static void
 ring_wfi(struct fd_batch *batch, struct fd_ringbuffer *ring)
@@ -125,8 +147,13 @@ ir3_emit_user_consts(struct fd_screen *screen, const struct ir3_shader_variant *
 		debug_assert((size % 16) == 0);
 		debug_assert((offset % 16) == 0);
 
-		emit_const(ring, v, state->range[i].offset / 4,
-				offset, size / 4, cb->user_buffer, cb->buffer);
+		if (cb->user_buffer) {
+			emit_const_user(ring, v, state->range[i].offset / 4,
+				size / 4, cb->user_buffer + state->range[i].start);
+		} else {
+			emit_const_prsc(ring, v, state->range[i].offset / 4,
+					offset, size / 4, cb->buffer);
+		}
 	}
 }
 
@@ -196,7 +223,7 @@ ir3_emit_ssbo_sizes(struct fd_screen *screen, const struct ir3_shader_variant *v
 			sizes[off] = sb->sb[index].buffer_size;
 		}
 
-		emit_const(ring, v, offset * 4, 0, ARRAY_SIZE(sizes), sizes, NULL);
+		emit_const_user(ring, v, offset * 4, ARRAY_SIZE(sizes), sizes);
 	}
 }
 
@@ -249,7 +276,7 @@ ir3_emit_image_dims(struct fd_screen *screen, const struct ir3_shader_variant *v
 		}
 		uint32_t size = MIN2(ARRAY_SIZE(dims), v->constlen * 4 - offset * 4);
 
-		emit_const(ring, v, offset * 4, 0, size, dims, NULL);
+		emit_const_user(ring, v, offset * 4, size, dims);
 	}
 }
 
@@ -271,7 +298,7 @@ ir3_emit_immediates(struct fd_screen *screen, const struct ir3_shader_variant *v
 	size *= 4;
 
 	if (size > 0)
-		emit_const(ring, v, base, 0, size, const_state->immediates, NULL);
+		emit_const_user(ring, v, base, size, const_state->immediates);
 }
 
 static inline void
@@ -297,7 +324,7 @@ ir3_emit_link_map(struct fd_screen *screen,
 	size *= 4;
 
 	if (size > 0)
-		emit_const(ring, v, base, 0, size, patch_locs, NULL);
+		emit_const_user(ring, v, base, size, patch_locs);
 }
 
 /* emit stream-out buffers: */
@@ -505,13 +532,13 @@ ir3_emit_vs_driver_params(const struct ir3_shader_variant *v,
 		ctx->screen->mem_to_mem(ring, vertex_params_rsc, 0,
 				indirect->buffer, src_off, 1);
 
-		emit_const(ring, v, offset * 4, 0,
-				vertex_params_size, NULL, vertex_params_rsc);
+		emit_const_prsc(ring, v, offset * 4, 0,
+				vertex_params_size, vertex_params_rsc);
 
 		pipe_resource_reference(&vertex_params_rsc, NULL);
 	} else {
-		emit_const(ring, v, offset * 4, 0,
-				vertex_params_size, vertex_params, NULL);
+		emit_const_user(ring, v, offset * 4,
+				vertex_params_size, vertex_params);
 	}
 
 	/* if needed, emit stream-out buffer addresses: */
@@ -584,7 +611,7 @@ ir3_emit_cs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin
 				indirect_offset = info->indirect_offset;
 			}
 
-			emit_const(ring, v, offset * 4, indirect_offset, 4, NULL, indirect);
+			emit_const_prsc(ring, v, offset * 4, indirect_offset, 4, indirect);
 
 			pipe_resource_reference(&indirect, NULL);
 		} else {
@@ -599,7 +626,7 @@ ir3_emit_cs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin
 			uint32_t size = MIN2(const_state->num_driver_params,
 					v->constlen * 4 - offset * 4);
 
-			emit_const(ring, v, offset * 4, 0, size, compute_params, NULL);
+			emit_const_user(ring, v, offset * 4, size, compute_params);
 		}
 	}
 }



More information about the mesa-commit mailing list