summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600/r600_state_common.c
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2012-12-16 10:31:32 +0000
committerDave Airlie <[email protected]>2013-01-11 22:31:54 +0000
commitd23aa650015ec017649f5a4ce8cb12d8c314bd3a (patch)
treea76e70719be1969b929be5f96bc8f6993bfc653f /src/gallium/drivers/r600/r600_state_common.c
parent77c10225eef43eb428ebbc80f1dd426e3d33b281 (diff)
r600g: texture buffer object + glsl 1.40 enable support (v2)
This adds TBO support to r600g, and with GLSL 1.40 enabled, we now get 3.1 core profiles advertised for r600g. The r600/700 implementation is a bit different from the evergreen one, as r6/7 hw lacks vertex fetch swizzles. So we implement it by passing 5 constants per sampler to the shader, the shader uses the first 4 as masks for each component and the 5th as the alpha value to OR in. Now TXQ is also broken so we have to pass a constant for the buffer size, on evergreen we just pass this, on r6/7 we pass it as the 6th element in the const info buffer. v1.1: drop return as DDX doesn't use a texture type v2: add r600/700 support. Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/r600_state_common.c')
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c125
1 files changed, 114 insertions, 11 deletions
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 3b61413f84e..34977373d21 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -588,19 +588,20 @@ static void r600_set_sampler_views(struct pipe_context *pipe, unsigned shader,
struct r600_texture *rtex =
(struct r600_texture*)rviews[i]->base.texture;
- if (rtex->is_depth && !rtex->is_flushing_texture) {
- dst->views.compressed_depthtex_mask |= 1 << i;
- } else {
- dst->views.compressed_depthtex_mask &= ~(1 << i);
- }
+ if (rviews[i]->base.texture->target != PIPE_BUFFER) {
+ if (rtex->is_depth && !rtex->is_flushing_texture) {
+ dst->views.compressed_depthtex_mask |= 1 << i;
+ } else {
+ dst->views.compressed_depthtex_mask &= ~(1 << i);
+ }
- /* Track compressed colorbuffers. */
- if (rtex->cmask_size && rtex->fmask_size) {
- dst->views.compressed_colortex_mask |= 1 << i;
- } else {
- dst->views.compressed_colortex_mask &= ~(1 << i);
+ /* Track compressed colorbuffers. */
+ if (rtex->cmask_size && rtex->fmask_size) {
+ dst->views.compressed_colortex_mask |= 1 << i;
+ } else {
+ dst->views.compressed_colortex_mask &= ~(1 << i);
+ }
}
-
/* Changing from array to non-arrays textures and vice versa requires
* updating TEX_ARRAY_OVERRIDE in sampler states on R6xx-R7xx. */
if (rctx->chip_class <= R700 &&
@@ -625,6 +626,7 @@ static void r600_set_sampler_views(struct pipe_context *pipe, unsigned shader,
dst->views.compressed_depthtex_mask &= dst->views.enabled_mask;
dst->views.compressed_colortex_mask &= dst->views.enabled_mask;
dst->views.dirty_txq_constants = TRUE;
+ dst->views.dirty_buffer_constants = TRUE;
r600_sampler_views_dirty(rctx, &dst->views);
if (dirty_sampler_states_mask) {
@@ -1023,6 +1025,92 @@ static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask
rctx->sample_mask.atom.dirty = true;
}
+/*
+ * On r600/700 hw we don't have vertex fetch swizzle, though TBO
+ * doesn't require full swizzles it does need masking and setting alpha
+ * to one, so we setup a set of 5 constants with the masks + alpha value
+ * then in the shader, we AND the 4 components with 0xffffffff or 0,
+ * then OR the alpha with the value given here.
+ * We use a 6th constant to store the txq buffer size in
+ */
+static void r600_setup_buffer_constants(struct r600_context *rctx, int shader_type)
+{
+ struct r600_textures_info *samplers = &rctx->samplers[shader_type];
+ int bits;
+ uint32_t array_size;
+ struct pipe_constant_buffer cb;
+ int i, j;
+
+ if (!samplers->views.dirty_buffer_constants)
+ return;
+
+ samplers->views.dirty_buffer_constants = FALSE;
+
+ bits = util_last_bit(samplers->views.enabled_mask);
+ array_size = bits * 8 * sizeof(uint32_t) * 4;
+ samplers->buffer_constants = realloc(samplers->buffer_constants, array_size);
+ memset(samplers->buffer_constants, 0, array_size);
+ for (i = 0; i < bits; i++) {
+ if (samplers->views.enabled_mask & (1 << i)) {
+ int offset = i * 8;
+ const struct util_format_description *desc;
+ desc = util_format_description(samplers->views.views[i]->base.format);
+
+ for (j = 0; j < 4; j++)
+ if (j < desc->nr_channels)
+ samplers->buffer_constants[offset+j] = 0xffffffff;
+ else
+ samplers->buffer_constants[offset+j] = 0x0;
+ if (desc->nr_channels < 4) {
+ if (desc->channel[0].pure_integer)
+ samplers->buffer_constants[offset+4] = 1;
+ else
+ samplers->buffer_constants[offset+4] = 0x3f800000;
+ } else
+ samplers->buffer_constants[offset + 4] = 0;
+
+ samplers->buffer_constants[offset + 5] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
+ }
+ }
+
+ cb.buffer = NULL;
+ cb.user_buffer = samplers->buffer_constants;
+ cb.buffer_offset = 0;
+ cb.buffer_size = array_size;
+ rctx->context.set_constant_buffer(&rctx->context, shader_type, R600_BUFFER_INFO_CONST_BUFFER, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
+}
+
+/* On evergreen we only need to store the buffer size for TXQ */
+static void eg_setup_buffer_constants(struct r600_context *rctx, int shader_type)
+{
+ struct r600_textures_info *samplers = &rctx->samplers[shader_type];
+ int bits;
+ uint32_t array_size;
+ struct pipe_constant_buffer cb;
+ int i;
+
+ if (!samplers->views.dirty_buffer_constants)
+ return;
+
+ samplers->views.dirty_buffer_constants = FALSE;
+
+ bits = util_last_bit(samplers->views.enabled_mask);
+ array_size = bits * sizeof(uint32_t) * 4;
+ samplers->buffer_constants = realloc(samplers->buffer_constants, array_size);
+ memset(samplers->buffer_constants, 0, array_size);
+ for (i = 0; i < bits; i++)
+ if (samplers->views.enabled_mask & (1 << i))
+ samplers->buffer_constants[i] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
+
+ cb.buffer = NULL;
+ cb.user_buffer = samplers->buffer_constants;
+ cb.buffer_offset = 0;
+ cb.buffer_size = array_size;
+ rctx->context.set_constant_buffer(&rctx->context, shader_type, R600_BUFFER_INFO_CONST_BUFFER, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
+}
+
static void r600_setup_txq_cube_array_constants(struct r600_context *rctx, int shader_type)
{
struct r600_textures_info *samplers = &rctx->samplers[shader_type];
@@ -1090,6 +1178,21 @@ static bool r600_update_derived_state(struct r600_context *rctx)
if (ps_dirty)
r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate);
+ /* on R600 we stuff masks + txq info into one constant buffer */
+ /* on evergreen we only need a txq info one */
+ if (rctx->chip_class < EVERGREEN) {
+ if (rctx->ps_shader && rctx->ps_shader->current->shader.uses_tex_buffers)
+ r600_setup_buffer_constants(rctx, PIPE_SHADER_FRAGMENT);
+ if (rctx->vs_shader && rctx->vs_shader->current->shader.uses_tex_buffers)
+ r600_setup_buffer_constants(rctx, PIPE_SHADER_VERTEX);
+ } else {
+ if (rctx->ps_shader && rctx->ps_shader->current->shader.uses_tex_buffers)
+ eg_setup_buffer_constants(rctx, PIPE_SHADER_FRAGMENT);
+ if (rctx->vs_shader && rctx->vs_shader->current->shader.uses_tex_buffers)
+ eg_setup_buffer_constants(rctx, PIPE_SHADER_VERTEX);
+ }
+
+
if (rctx->ps_shader && rctx->ps_shader->current->shader.has_txq_cube_array_z_comp)
r600_setup_txq_cube_array_constants(rctx, PIPE_SHADER_FRAGMENT);
if (rctx->vs_shader && rctx->vs_shader->current->shader.has_txq_cube_array_z_comp)