summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2016-05-02 09:54:11 +0200
committerBas Nieuwenhuizen <[email protected]>2016-05-26 22:07:04 +0200
commitd27ff7d6838fef2419ffb05798967e785e196afb (patch)
tree1f35b9942f1d7522299ec3ea0c1e1e7596234406 /src/gallium/drivers/radeonsi
parent6e51fe75a4997328625753c9409b328f207d5e51 (diff)
radeonsi: Add buffer for offchip storage between TCS and TES.
The buffer is quite large, but should only be allocated if the application uses tessellation. Most non-games don't. v2: - Use the correct register for SI. - Add define for block size. Signed-off-by: Bas Nieuwenhuizen <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi')
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c1
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.h3
-rw-r--r--src/gallium/drivers/radeonsi/si_state_shaders.c18
4 files changed, 23 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 6700590dfac..eefc68a7f81 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -48,6 +48,7 @@ static void si_destroy_context(struct pipe_context *context)
pipe_resource_reference(&sctx->esgs_ring, NULL);
pipe_resource_reference(&sctx->gsvs_ring, NULL);
pipe_resource_reference(&sctx->tf_ring, NULL);
+ pipe_resource_reference(&sctx->tess_offchip_ring, NULL);
pipe_resource_reference(&sctx->null_const_buf.buffer, NULL);
r600_resource_reference(&sctx->border_color_buffer, NULL);
free(sctx->border_color_table);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 33d3d259e2a..e5b88c71dfd 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -256,6 +256,7 @@ struct si_context {
struct pipe_resource *esgs_ring;
struct pipe_resource *gsvs_ring;
struct pipe_resource *tf_ring;
+ struct pipe_resource *tess_offchip_ring;
union pipe_color_union *border_color_table; /* in CPU memory, any endian */
struct r600_resource *border_color_buffer;
union pipe_color_union *border_color_map; /* in VRAM (slow access), little endian */
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index f2a3b037a2c..a3589d4611d 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -40,6 +40,8 @@
#define SI_NUM_IMAGES 16
#define SI_NUM_SHADER_BUFFERS 16
+#define SI_TESS_OFFCHIP_BLOCK_SIZE (8192 * 4)
+
struct si_screen;
struct si_shader;
@@ -155,6 +157,7 @@ struct si_shader_data {
/* Private read-write buffer slots. */
enum {
SI_HS_RING_TESS_FACTOR,
+ SI_HS_RING_TESS_OFFCHIP,
SI_ES_RING_ESGS,
SI_GS_RING_ESGS,
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 13066ff3c7d..d8ae2b232e9 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1770,6 +1770,7 @@ static bool si_update_spi_tmpring_size(struct si_context *sctx)
static void si_init_tess_factor_ring(struct si_context *sctx)
{
+ unsigned offchip_blocks = sctx->b.chip_class >= CIK ? 256 : 64;
assert(!sctx->tf_ring);
sctx->tf_ring = pipe_buffer_create(sctx->b.b.screen, PIPE_BIND_CUSTOM,
@@ -1780,6 +1781,14 @@ static void si_init_tess_factor_ring(struct si_context *sctx)
assert(((sctx->tf_ring->width0 / 4) & C_030938_SIZE) == 0);
+ sctx->tess_offchip_ring = pipe_buffer_create(sctx->b.b.screen,
+ PIPE_BIND_CUSTOM,
+ PIPE_USAGE_DEFAULT,
+ offchip_blocks *
+ SI_TESS_OFFCHIP_BLOCK_SIZE);
+ if (!sctx->tess_offchip_ring)
+ return;
+
si_init_config_add_vgt_flush(sctx);
/* Append these registers to the init config state. */
@@ -1788,11 +1797,16 @@ static void si_init_tess_factor_ring(struct si_context *sctx)
S_030938_SIZE(sctx->tf_ring->width0 / 4));
si_pm4_set_reg(sctx->init_config, R_030940_VGT_TF_MEMORY_BASE,
r600_resource(sctx->tf_ring)->gpu_address >> 8);
+ si_pm4_set_reg(sctx->init_config, R_03093C_VGT_HS_OFFCHIP_PARAM,
+ S_03093C_OFFCHIP_BUFFERING(offchip_blocks - 1) |
+ S_03093C_OFFCHIP_GRANULARITY(V_03093C_X_8K_DWORDS));
} else {
si_pm4_set_reg(sctx->init_config, R_008988_VGT_TF_RING_SIZE,
S_008988_SIZE(sctx->tf_ring->width0 / 4));
si_pm4_set_reg(sctx->init_config, R_0089B8_VGT_TF_MEMORY_BASE,
r600_resource(sctx->tf_ring)->gpu_address >> 8);
+ si_pm4_set_reg(sctx->init_config, R_0089B0_VGT_HS_OFFCHIP_PARAM,
+ S_0089B0_OFFCHIP_BUFFERING(offchip_blocks - 1));
}
/* Flush the context to re-emit the init_config state.
@@ -1804,6 +1818,10 @@ static void si_init_tess_factor_ring(struct si_context *sctx)
si_set_ring_buffer(&sctx->b.b, SI_HS_RING_TESS_FACTOR, sctx->tf_ring,
0, sctx->tf_ring->width0, false, false, 0, 0, 0);
+
+ si_set_ring_buffer(&sctx->b.b, SI_HS_RING_TESS_OFFCHIP,
+ sctx->tess_offchip_ring, 0,
+ sctx->tess_offchip_ring->width0, false, false, 0, 0, 0);
}
/**