[Mesa-dev] [PATCH 2/2] r600: fix textureSize queries with tbos

sroland at vmware.com sroland at vmware.com
Sat Dec 23 07:19:57 UTC 2017


From: Roland Scheidegger <sroland at vmware.com>

piglit doesn't care, but I'm quite confident that the size actually bound
as range should be reported and not the base size of the resource.
Also, the array in the constant buffer looks overallocated by a factor of 4.
For eg, also decrease the size by another factor of 2 by using the same
constant slot for both buffer size (required for txq for TBOs) and the number
of layers for cube arrays, as these are mutually exclusive. Could of course use
some more logic and only actually do this for the samplers/images/buffers where
it's required rather than for all, but ah well...
(FWIW I believe the txq for TBOs would be fixable on EG without using a
constant buffer by using the GET_BUFFER_RESINFO vc fetch, but for cube map
arrays we'd still need the buffer as it's unfixable since the hw requires
always 0 unfortunately.)
---
 src/gallium/drivers/r600/r600_shader.c       | 18 +++++++-------
 src/gallium/drivers/r600/r600_state_common.c | 35 +++++++++++++++++-----------
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 6cdbfd3063..8a63621c2f 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -6955,9 +6955,9 @@ static int r600_do_buffer_txq(struct r600_shader_ctx *ctx, int reg_idx, int offs
 	alu.op = ALU_OP1_MOV;
 	alu.src[0].sel = R600_SHADER_BUFFER_INFO_SEL;
 	if (ctx->bc->chip_class >= EVERGREEN) {
-		/* channel 0 or 2 of each word */
-		alu.src[0].sel += (id / 2);
-		alu.src[0].chan = (id % 2) * 2;
+		/* with eg each dword is either buf size or number of cubes */
+		alu.src[0].sel += id / 4;
+		alu.src[0].chan = id % 4;
 	} else {
 		/* r600 we have them at channel 2 of the second dword */
 		alu.src[0].sel += (id * 2) + 1;
@@ -7615,9 +7615,9 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
 
 		alu.src[0].sel = R600_SHADER_BUFFER_INFO_SEL;
 		if (ctx->bc->chip_class >= EVERGREEN) {
-			/* channel 1 or 3 of each word */
-			alu.src[0].sel += (id / 2);
-			alu.src[0].chan = ((id % 2) * 2) + 1;
+			/* with eg each dword is either buf size or number of cubes */
+			alu.src[0].sel += id / 4;
+			alu.src[0].chan = id % 4;
 		} else {
 			/* r600 we have them at channel 2 of the second dword */
 			alu.src[0].sel += (id * 2) + 1;
@@ -8782,9 +8782,9 @@ static int tgsi_resq(struct r600_shader_ctx *ctx)
 		alu.op = ALU_OP1_MOV;
 
 		alu.src[0].sel = R600_SHADER_BUFFER_INFO_SEL;
-		/* channel 1 or 3 of each word */
-		alu.src[0].sel += (id / 2);
-		alu.src[0].chan = ((id % 2) * 2) + 1;
+		/* with eg each dword is either buf size or number of cubes */
+		alu.src[0].sel += id / 4;
+		alu.src[0].chan = id % 4;
 		alu.src[0].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
 		tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
 		alu.last = 1;
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index e5a5a33367..e9996cb3fa 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -902,7 +902,6 @@ struct r600_pipe_shader_selector *r600_create_shader_state_tokens(struct pipe_co
 								  unsigned pipe_shader_type)
 {
 	struct r600_pipe_shader_selector *sel = CALLOC_STRUCT(r600_pipe_shader_selector);
-	int i;
 
 	sel->type = pipe_shader_type;
 	sel->tokens = tgsi_dup_tokens(tokens);
@@ -1326,7 +1325,7 @@ static void r600_setup_buffer_constants(struct r600_context *rctx, int shader_ty
 	samplers->views.dirty_buffer_constants = FALSE;
 
 	bits = util_last_bit(samplers->views.enabled_mask);
-	array_size = bits * 8 * sizeof(uint32_t) * 4;
+	array_size = bits * 8 * sizeof(uint32_t);
 
 	constants = r600_alloc_buf_consts(rctx, shader_type, array_size, &base_offset);
 
@@ -1349,7 +1348,8 @@ static void r600_setup_buffer_constants(struct r600_context *rctx, int shader_ty
 			} else
 				constants[offset + 4] = 0;
 
-			constants[offset + 5] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
+			constants[offset + 5] = samplers->views.views[i]->base.u.buf.size /
+				            util_format_get_blocksize(samplers->views.views[i]->base.format);
 			constants[offset + 6] = samplers->views.views[i]->base.texture->array_size / 6;
 		}
 	}
@@ -1396,25 +1396,33 @@ void eg_setup_buffer_constants(struct r600_context *rctx, int shader_type)
 	img_bits = bits;
 	if (buffers)
 		bits += util_last_bit(buffers->enabled_mask);
-	array_size = bits * 2 * sizeof(uint32_t) * 4;
+	array_size = bits * sizeof(uint32_t);
 
 	constants = r600_alloc_buf_consts(rctx, shader_type, array_size,
 					  &base_offset);
 
 	for (i = 0; i < sview_bits; i++) {
 		if (samplers->views.enabled_mask & (1 << i)) {
-			uint32_t offset = (base_offset / 4) + i * 2;
-			constants[offset] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
-			constants[offset + 1] = samplers->views.views[i]->base.texture->array_size / 6;
+			uint32_t offset = (base_offset / 4) + i;
+			if (samplers->views.views[i]->base.target == PIPE_BUFFER) {
+				constants[offset] = samplers->views.views[i]->base.u.buf.size /
+					        util_format_get_blocksize(samplers->views.views[i]->base.format);
+			} else {
+				constants[offset] = samplers->views.views[i]->base.texture->array_size / 6;
+			}
 		}
 	}
 	if (images) {
 		for (i = sview_bits; i < img_bits; i++) {
 			int idx = i - sview_bits;
 			if (images->enabled_mask & (1 << idx)) {
-				uint32_t offset = (base_offset / 4) + i * 2;
-				constants[offset] = images->views[i].base.resource->width0 / util_format_get_blocksize(images->views[i].base.format);
-				constants[offset + 1] = images->views[i].base.resource->array_size / 6;
+				uint32_t offset = (base_offset / 4) + i;
+				if (images->views[i].base.resource->target == PIPE_BUFFER) {
+					constants[offset] = images->views[i].base.u.buf.size /
+						        util_format_get_blocksize(images->views[i].base.format);
+				} else {
+					constants[offset] = images->views[i].base.resource->array_size / 6;
+				}
 			}
 		}
 	}
@@ -1422,9 +1430,10 @@ void eg_setup_buffer_constants(struct r600_context *rctx, int shader_type)
 		for (i = img_bits; i < bits; i++) {
 			int idx = i - img_bits;
 			if (buffers->enabled_mask & (1 << idx)) {
-				uint32_t offset = (base_offset / 4) + i * 2;
-				constants[offset] = buffers->views[i].base.resource->width0 / util_format_get_blocksize(buffers->views[i].base.format);
-				constants[offset + 1] = 0;
+				uint32_t offset = (base_offset / 4) + i;
+				assert(buffers->views[i].base.resource->target == PIPE_BUFFER);
+				constants[offset] = buffers->views[i].base.u.buf.size /
+					        util_format_get_blocksize(buffers->views[i].base.format);
 			}
 		}
 	}
-- 
2.12.3



More information about the mesa-dev mailing list