summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-07-27 21:57:40 +0200
committerChristian König <deathsimple@vodafone.de>2012-07-30 15:02:04 +0200
commit86490bc150dd108d5917bb0f4636a9545fbf1b8e (patch)
tree9b3399cdd5bc617090eff92d18dcc4288fe2ffb8
parent7dace3a3cf894adb51a21ff6b08f58608ea33831 (diff)
radeonsi: fix db and stencil setup v2
v2: fix tiling for small pitches, that finally makes glxgears and readPixSanity work Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
-rw-r--r--src/gallium/drivers/radeonsi/r600_resource.h1
-rw-r--r--src/gallium/drivers/radeonsi/r600_texture.c22
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c102
3 files changed, 58 insertions, 67 deletions
diff --git a/src/gallium/drivers/radeonsi/r600_resource.h b/src/gallium/drivers/radeonsi/r600_resource.h
index b4427a165de..678bf12778d 100644
--- a/src/gallium/drivers/radeonsi/r600_resource.h
+++ b/src/gallium/drivers/radeonsi/r600_resource.h
@@ -52,13 +52,12 @@ struct r600_resource_texture {
unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS];
unsigned array_mode[PIPE_MAX_TEXTURE_LEVELS];
unsigned pitch_override;
unsigned size;
unsigned depth;
unsigned dirty_db;
- struct r600_resource_texture *stencil; /* Stencil is in a separate buffer on Evergreen. */
struct r600_resource_texture *flushed_depth_texture;
boolean is_flushing_texture;
struct radeon_surface surface;
};
#define R600_TEX_IS_TILED(tex, level) ((tex)->array_mode[level] != V_009910_ARRAY_LINEAR_GENERAL && (tex)->array_mode[level] != V_009910_ARRAY_LINEAR_ALIGNED)
diff --git a/src/gallium/drivers/radeonsi/r600_texture.c b/src/gallium/drivers/radeonsi/r600_texture.c
index 38ff36df1e9..e34247ef40a 100644
--- a/src/gallium/drivers/radeonsi/r600_texture.c
+++ b/src/gallium/drivers/radeonsi/r600_texture.c
@@ -482,15 +482,12 @@ static void r600_texture_destroy(struct pipe_screen *screen,
struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
struct si_resource *resource = &rtex->resource;
if (rtex->flushed_depth_texture)
si_resource_reference(&rtex->flushed_depth_texture, NULL);
- if (rtex->stencil)
- si_resource_reference(&rtex->stencil, NULL);
-
pb_reference(&resource->buf, NULL);
FREE(rtex);
}
static const struct u_resource_vtbl r600_texture_vtbl =
{
@@ -540,47 +537,28 @@ r600_texture_create_object(struct pipe_screen *screen,
r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override);
if (r) {
FREE(rtex);
return NULL;
}
- /* If we initialized separate stencil for Evergreen. place it after depth. */
- if (rtex->stencil) {
- unsigned stencil_align, stencil_offset;
-
- stencil_align = r600_get_base_alignment(screen, rtex->stencil->real_format, array_mode);
- stencil_offset = align(rtex->size, stencil_align);
-
- for (unsigned i = 0; i <= rtex->stencil->resource.b.b.last_level; i++)
- rtex->stencil->offset[i] += stencil_offset;
-
- rtex->size = stencil_offset + rtex->stencil->size;
- }
-
/* Now create the backing buffer. */
if (!buf && alloc_bo) {
struct pipe_resource *ptex = &rtex->resource.b.b;
unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
base_align = rtex->surface.bo_alignment;
if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) {
- si_resource_reference(&rtex->stencil, NULL);
FREE(rtex);
return NULL;
}
} else if (buf) {
resource->buf = buf;
resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
}
- if (rtex->stencil) {
- pb_reference(&rtex->stencil->resource.buf, rtex->resource.buf);
- rtex->stencil->resource.cs_buf = rtex->resource.cs_buf;
- rtex->stencil->resource.domains = rtex->resource.domains;
- }
return rtex;
}
struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
const struct pipe_resource *templ)
{
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index b2dabf586a3..94b8b43a878 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1501,87 +1501,101 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
static void si_db(struct r600_context *rctx, struct si_pm4_state *pm4,
const struct pipe_framebuffer_state *state)
{
struct r600_resource_texture *rtex;
struct r600_surface *surf;
- unsigned level, first_layer, pitch, slice, format;
- uint32_t db_z_info, stencil_info;
- uint64_t offset;
+ unsigned level, pitch, slice, format;
+ uint32_t z_info, s_info;
+ uint64_t z_offs, s_offs;
if (state->zsbuf == NULL) {
si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0);
si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0);
return;
}
surf = (struct r600_surface *)state->zsbuf;
level = surf->base.u.tex.level;
rtex = (struct r600_resource_texture*)surf->base.texture;
- first_layer = surf->base.u.tex.first_layer;
format = si_translate_dbformat(rtex->real_format);
- offset = r600_resource_va(rctx->context.screen, surf->base.texture);
- offset += rtex->surface.level[level].offset;
+ z_offs = r600_resource_va(rctx->context.screen, surf->base.texture);
+ z_offs += rtex->surface.level[level].offset;
+
+ s_offs = r600_resource_va(rctx->context.screen, surf->base.texture);
+ s_offs += rtex->surface.stencil_offset;
+ z_offs += rtex->surface.level[level].offset / 4;
+
+ z_offs >>= 8;
+ s_offs >>= 8;
+
pitch = (rtex->surface.level[level].nblk_x / 8) - 1;
slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
if (slice) {
slice = slice - 1;
}
- offset >>= 8;
- si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
- si_pm4_set_reg(pm4, R_028048_DB_Z_READ_BASE, offset);
- si_pm4_set_reg(pm4, R_028050_DB_Z_WRITE_BASE, offset);
- si_pm4_set_reg(pm4, R_028008_DB_DEPTH_VIEW,
- S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) |
- S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer));
+ z_info = S_028040_FORMAT(format);
+ s_info = S_028044_FORMAT(1);
- db_z_info = S_028040_FORMAT(format);
- stencil_info = S_028044_FORMAT(rtex->stencil != 0);
+ if (rtex->surface.level[level].mode == RADEON_SURF_MODE_1D) {
+ z_info |= S_028040_TILE_MODE_INDEX(4);
+ s_info |= S_028044_TILE_MODE_INDEX(4);
- switch (format) {
- case V_028040_Z_16:
- db_z_info |= S_028040_TILE_MODE_INDEX(5);
- stencil_info |= S_028044_TILE_MODE_INDEX(5);
- break;
- case V_028040_Z_24:
- case V_028040_Z_32_FLOAT:
- db_z_info |= S_028040_TILE_MODE_INDEX(6);
- stencil_info |= S_028044_TILE_MODE_INDEX(6);
- break;
- default:
- db_z_info |= S_028040_TILE_MODE_INDEX(7);
- stencil_info |= S_028044_TILE_MODE_INDEX(7);
- }
-
- if (rtex->stencil) {
- uint64_t stencil_offset =
- r600_texture_get_offset(rtex->stencil, level, first_layer);
-
- stencil_offset += r600_resource_va(rctx->context.screen, (void*)rtex->stencil);
- stencil_offset >>= 8;
+ } else if (rtex->surface.level[level].mode == RADEON_SURF_MODE_2D) {
+ switch (format) {
+ case V_028040_Z_16:
+ z_info |= S_028040_TILE_MODE_INDEX(5);
+ s_info |= S_028044_TILE_MODE_INDEX(5);
+ break;
+ case V_028040_Z_24:
+ case V_028040_Z_32_FLOAT:
+ z_info |= S_028040_TILE_MODE_INDEX(6);
+ s_info |= S_028044_TILE_MODE_INDEX(6);
+ break;
+ default:
+ z_info |= S_028040_TILE_MODE_INDEX(7);
+ s_info |= S_028044_TILE_MODE_INDEX(7);
+ }
- si_pm4_add_bo(pm4, &rtex->stencil->resource, RADEON_USAGE_READWRITE);
- si_pm4_set_reg(pm4, R_02804C_DB_STENCIL_READ_BASE, stencil_offset);
- si_pm4_set_reg(pm4, R_028054_DB_STENCIL_WRITE_BASE, stencil_offset);
- si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, stencil_info);
} else {
+ R600_ERR("Invalid DB tiling mode %d!\n",
+ rtex->surface.level[level].mode);
+ si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0);
si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0);
+ return;
}
+ si_pm4_set_reg(pm4, R_028008_DB_DEPTH_VIEW,
+ S_028008_SLICE_START(state->zsbuf->u.tex.first_layer) |
+ S_028008_SLICE_MAX(state->zsbuf->u.tex.last_layer));
+
+ si_pm4_set_reg(pm4, R_02803C_DB_DEPTH_INFO, 0x1);
if (format != ~0U) {
- si_pm4_set_reg(pm4, R_02803C_DB_DEPTH_INFO, 0x1);
- si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, db_z_info);
- si_pm4_set_reg(pm4, R_028058_DB_DEPTH_SIZE, S_028058_PITCH_TILE_MAX(pitch));
- si_pm4_set_reg(pm4, R_02805C_DB_DEPTH_SLICE, S_02805C_SLICE_TILE_MAX(slice));
+ si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, z_info);
} else {
si_pm4_set_reg(pm4, R_028040_DB_Z_INFO, 0);
}
+
+ if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
+ si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, s_info);
+ } else {
+ si_pm4_set_reg(pm4, R_028044_DB_STENCIL_INFO, 0);
+ }
+
+ si_pm4_add_bo(pm4, &rtex->resource, RADEON_USAGE_READWRITE);
+ si_pm4_set_reg(pm4, R_028048_DB_Z_READ_BASE, z_offs);
+ si_pm4_set_reg(pm4, R_02804C_DB_STENCIL_READ_BASE, s_offs);
+ si_pm4_set_reg(pm4, R_028050_DB_Z_WRITE_BASE, z_offs);
+ si_pm4_set_reg(pm4, R_028054_DB_STENCIL_WRITE_BASE, s_offs);
+
+ si_pm4_set_reg(pm4, R_028058_DB_DEPTH_SIZE, S_028058_PITCH_TILE_MAX(pitch));
+ si_pm4_set_reg(pm4, R_02805C_DB_DEPTH_SLICE, S_02805C_SLICE_TILE_MAX(slice));
}
static void si_set_framebuffer_state(struct pipe_context *ctx,
const struct pipe_framebuffer_state *state)
{
struct r600_context *rctx = (struct r600_context *)ctx;