summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi/si_state.c
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2013-01-17 19:36:41 +0100
committerMichel Dänzer <[email protected]>2013-01-21 15:42:28 +0100
commit6f6112a2b982462667ba36a6f3ba381558780e8a (patch)
treeb4273ce12fca87afe1cfe0d375b38fbd1475a265 /src/gallium/drivers/radeonsi/si_state.c
parentbc398f908f8765edee48150dc7e3f24874bb03d9 (diff)
radeonsi: More assorted depth/stencil changes ported from r600g.
[ Squashed port of the following r600g commits: - Michel Dänzer ] commit 428e37c2da420f7dc14a2ea265f2387270f9bee1 Author: Marek Olšák <[email protected]> Date: Tue Oct 2 22:02:54 2012 +0200 r600g: add in-place DB decompression and texturing with DB tiling The decompression is done in-place and only the compressed tiles are decompressed. Note: R6xx-R7xx can do that only with Z16 and Z32F. The texture unit is programmed to use non-displayable tiling and depth ordering of samples, so that it can fetch the texture in the native DB format. The latest version of the libdrm surface allocator is required for stencil texturing to work. The old one didn't create the mipmap tree correctly. We need a separate mipmap tree for stencil, because the stencil mipmap offsets are not really depth offsets/4. There are still some known bugs, but this should save some memory and it also improves performance a little bit in Lightsmark (especially with low resolutions; tested with Radeon HD 5000). The DB->CB copy is still used for transfers. commit e2f623f1d6da9bc987582ff68d0471061ae44030 Author: Marek Olšák <[email protected]> Date: Sat Jul 28 13:55:59 2012 +0200 r600g: don't decompress depth or stencil if there isn't any commit 43e226b6efb77db2247741cc2057d9625a2cfa05 Author: Marek Olšák <[email protected]> Date: Wed Jul 18 00:32:50 2012 +0200 r600g: optimize uploading depth textures Make it only copy the portion of a depth texture being uploaded and not the whole 2D layer. There is also a little code cleanup. commit b242adbe5cfa165b252064a1ea36f802d8251ef1 Author: Marek Olšák <[email protected]> Date: Wed Jul 18 00:17:46 2012 +0200 r600g: remove needless wrapper r600_texture_depth_flush commit 611dd529425281d73f1f0ad2000362d4a5525a25 Author: Marek Olšák <[email protected]> Date: Wed Jul 18 00:05:14 2012 +0200 r600g: init_flushed_depth_texture should be able to report errors commit 80755ff56317446a8c89e611edc1fdf320d6779b Author: Marek Olšák <[email protected]> Date: Sat Jul 14 17:06:27 2012 +0200 r600g: properly track which textures are depth This fixes the issue with have_depth_texture never being set to false. commit fe1fd675565231b49d3ac53d0b4bec39d8bc6781 Author: Marek Olšák <[email protected]> Date: Sun Jul 8 03:10:37 2012 +0200 r600g: don't flush depth textures set as colorbuffers The only case a depth buffer can be set as a color buffer is when flushing. That wasn't always the case, but now this code isn't required anymore. commit 5a17d8318ec2c20bf86275044dc8f715105a88e7 Author: Marek Olšák <[email protected]> Date: Sun Jul 8 02:14:18 2012 +0200 r600g: flush depth textures bound to vertex shaders This was missing/broken. There are also minor code cleanups. commit dee58f94af833906863b0ff2955b20f3ab407e63 Author: Marek Olšák <[email protected]> Date: Sun Jul 8 01:54:24 2012 +0200 r600g: do fine-grained depth texture flushing - maintain a mask of which mipmap levels are dirty (instead of one big flag) - only flush what was requested at a given point and not the whole resource (most often only one level and one layer has to be flushed) Signed-off-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi/si_state.c')
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c91
1 files changed, 55 insertions, 36 deletions
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 3908b773b5c..cd40e1ac774 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -650,7 +650,8 @@ static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
si_pm4_delete_state(rctx, dsa, (struct si_state_dsa *)state);
}
-static void *si_create_db_flush_dsa(struct r600_context *rctx)
+static void *si_create_db_flush_dsa(struct r600_context *rctx, bool copy_depth,
+ bool copy_stencil)
{
struct pipe_depth_stencil_alpha_state dsa;
struct si_state_dsa *state;
@@ -658,10 +659,22 @@ static void *si_create_db_flush_dsa(struct r600_context *rctx)
memset(&dsa, 0, sizeof(dsa));
state = rctx->context.create_depth_stencil_alpha_state(&rctx->context, &dsa);
- si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
- S_028000_DEPTH_COPY(1) |
- S_028000_STENCIL_COPY(1) |
- S_028000_COPY_CENTROID(1));
+ if (copy_depth || copy_stencil) {
+ si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
+ S_028000_DEPTH_COPY(copy_depth) |
+ S_028000_STENCIL_COPY(copy_stencil) |
+ S_028000_COPY_CENTROID(1));
+ } else {
+ si_pm4_set_reg(&state->pm4, R_028000_DB_RENDER_CONTROL,
+ S_028000_DEPTH_COMPRESS_DISABLE(1) |
+ S_028000_STENCIL_COMPRESS_DISABLE(1));
+ si_pm4_set_reg(&state->pm4, R_02800C_DB_RENDER_OVERRIDE,
+ S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_DISABLE) |
+ S_02800C_FORCE_HIS_ENABLE0(V_02800C_FORCE_DISABLE) |
+ S_02800C_FORCE_HIS_ENABLE1(V_02800C_FORCE_DISABLE) |
+ S_02800C_DISABLE_TILE_RATE_TILES(1));
+ }
+
return state;
}
@@ -1581,16 +1594,6 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
surf = (struct r600_surface *)state->cbufs[cb];
rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture;
- if (rtex->is_depth)
- rctx->have_depth_fb = TRUE;
-
- if (rtex->is_depth && !rtex->is_flushing_texture) {
- r600_init_flushed_depth_texture(&rctx->context,
- state->cbufs[cb]->texture, NULL);
- rtex = rtex->flushed_depth_texture;
- assert(rtex);
- }
-
offset = rtex->surface.level[level].offset;
if (rtex->surface.level[level].mode < RADEON_SURF_MODE_1D) {
offset += rtex->surface.level[level].slice_size *
@@ -1786,7 +1789,6 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
util_copy_framebuffer_state(&rctx->framebuffer, state);
/* build states */
- rctx->have_depth_fb = 0;
rctx->export_16bpc = 0;
for (int i = 0; i < state->nr_cbufs; i++) {
si_cb(rctx, pm4, state, i);
@@ -2041,11 +2043,12 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
{
struct si_pipe_sampler_view *view = CALLOC_STRUCT(si_pipe_sampler_view);
struct r600_resource_texture *tmp = (struct r600_resource_texture*)texture;
- const struct util_format_description *desc = util_format_description(state->format);
+ const struct util_format_description *desc;
unsigned format, num_format;
uint32_t pitch = 0;
unsigned char state_swizzle[4], swizzle[4];
unsigned height, depth, width;
+ enum pipe_format pipe_format = state->format;
int first_non_void;
uint64_t va;
@@ -2064,9 +2067,26 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
state_swizzle[1] = state->swizzle_g;
state_swizzle[2] = state->swizzle_b;
state_swizzle[3] = state->swizzle_a;
+
+ /* Texturing with separate depth and stencil. */
+ if (tmp->is_depth && !tmp->is_flushing_texture) {
+ switch (pipe_format) {
+ case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
+ pipe_format = PIPE_FORMAT_Z32_FLOAT;
+ break;
+ case PIPE_FORMAT_X24S8_UINT:
+ case PIPE_FORMAT_S8X24_UINT:
+ case PIPE_FORMAT_X32_S8X24_UINT:
+ pipe_format = PIPE_FORMAT_S8_UINT;
+ break;
+ default:;
+ }
+ }
+
+ desc = util_format_description(pipe_format);
util_format_compose_swizzles(desc->swizzle, state_swizzle, swizzle);
- first_non_void = util_format_get_first_non_void_channel(state->format);
+ first_non_void = util_format_get_first_non_void_channel(pipe_format);
switch (desc->channel[first_non_void].type) {
case UTIL_FORMAT_TYPE_FLOAT:
num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
@@ -2079,21 +2099,11 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
num_format = V_008F14_IMG_NUM_FORMAT_UNORM;
}
- format = si_translate_texformat(ctx->screen, state->format, desc, first_non_void);
+ format = si_translate_texformat(ctx->screen, pipe_format, desc, first_non_void);
if (format == ~0) {
format = 0;
}
- if (tmp->is_depth && !tmp->is_flushing_texture) {
- r600_init_flushed_depth_texture(ctx, texture, NULL);
- tmp = tmp->flushed_depth_texture;
- if (!tmp) {
- FREE(view);
- return NULL;
- }
- texture = &tmp->resource.b.b;
- }
-
view->resource = &tmp->resource;
/* not supported any more */
@@ -2102,7 +2112,7 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx
width = tmp->surface.level[0].npix_x;
height = tmp->surface.level[0].npix_y;
depth = tmp->surface.level[0].npix_z;
- pitch = tmp->surface.level[0].nblk_x * util_format_get_blockwidth(state->format);
+ pitch = tmp->surface.level[0].nblk_x * util_format_get_blockwidth(pipe_format);
if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
height = 1;
@@ -2207,8 +2217,6 @@ static struct si_pm4_state *si_set_sampler_view(struct r600_context *rctx,
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
int i, j;
- rctx->have_depth_texture = FALSE;
-
if (!count)
goto out;
@@ -2220,11 +2228,19 @@ static struct si_pm4_state *si_set_sampler_view(struct r600_context *rctx,
(struct pipe_sampler_view **)&samplers->views[i],
views[i]);
- if (resource[i]) {
+ if (views[i]) {
struct r600_resource_texture *rtex =
- (struct r600_resource_texture *)views[i]->texture;
- rctx->have_depth_texture |= rtex->is_depth && !rtex->is_flushing_texture;
+ (struct r600_resource_texture*)views[i]->texture;
+
+ if (rtex->is_depth && !rtex->is_flushing_texture) {
+ samplers->depth_texture_mask |= 1 << i;
+ } else {
+ samplers->depth_texture_mask &= ~(1 << i);
+ }
+
si_pm4_add_bo(pm4, resource[i]->resource, RADEON_USAGE_READ);
+ } else {
+ samplers->depth_texture_mask &= ~(1 << i);
}
for (j = 0; j < Elements(resource[i]->state); ++j) {
@@ -2546,7 +2562,10 @@ void si_init_state_functions(struct r600_context *rctx)
rctx->context.create_depth_stencil_alpha_state = si_create_dsa_state;
rctx->context.bind_depth_stencil_alpha_state = si_bind_dsa_state;
rctx->context.delete_depth_stencil_alpha_state = si_delete_dsa_state;
- rctx->custom_dsa_flush = si_create_db_flush_dsa(rctx);
+ rctx->custom_dsa_flush_depth_stencil = si_create_db_flush_dsa(rctx, true, true);
+ rctx->custom_dsa_flush_depth = si_create_db_flush_dsa(rctx, true, false);
+ rctx->custom_dsa_flush_stencil = si_create_db_flush_dsa(rctx, false, true);
+ rctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(rctx, false, false);
rctx->context.set_clip_state = si_set_clip_state;
rctx->context.set_scissor_state = si_set_scissor_state;