r600g: add support for separately allocated CMASKs
v2: check for NULL cbufs Signed-off-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
committed by
Marek Olšák
parent
419cd5f2a2
commit
56d9a397aa
@@ -1555,8 +1555,11 @@ void evergreen_init_color_surface(struct r600_context *rctx,
|
||||
surf->export_16bpc = true;
|
||||
}
|
||||
|
||||
if (rtex->fmask_size && rtex->cmask_size) {
|
||||
color_info |= S_028C70_COMPRESSION(1) | S_028C70_FAST_CLEAR(1);
|
||||
if (rtex->fmask_size) {
|
||||
color_info |= S_028C70_COMPRESSION(1);
|
||||
}
|
||||
if (rtex->cmask_size) {
|
||||
color_info |= S_028C70_FAST_CLEAR(1);
|
||||
}
|
||||
|
||||
base_offset = r600_resource_va(rctx->b.b.screen, pipe_tex);
|
||||
@@ -1574,11 +1577,15 @@ void evergreen_init_color_surface(struct r600_context *rctx,
|
||||
S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
|
||||
}
|
||||
surf->cb_color_attrib = color_attrib;
|
||||
if (rtex->fmask_size && rtex->cmask_size) {
|
||||
if (rtex->fmask_size) {
|
||||
surf->cb_color_fmask = (base_offset + rtex->fmask_offset) >> 8;
|
||||
surf->cb_color_cmask = (base_offset + rtex->cmask_offset) >> 8;
|
||||
} else {
|
||||
surf->cb_color_fmask = surf->cb_color_base;
|
||||
}
|
||||
if (rtex->cmask_size) {
|
||||
uint64_t va = r600_resource_va(rctx->b.b.screen, &rtex->cmask->b.b);
|
||||
surf->cb_color_cmask = (va + rtex->cmask_offset) >> 8;
|
||||
} else {
|
||||
surf->cb_color_cmask = surf->cb_color_base;
|
||||
}
|
||||
surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask_slice_tile_max);
|
||||
@@ -2180,6 +2187,13 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
|
||||
&rctx->b.rings.gfx,
|
||||
(struct r600_resource*)cb->base.texture,
|
||||
RADEON_USAGE_READWRITE);
|
||||
unsigned cmask_reloc = 0;
|
||||
if (tex->cmask && tex->cmask != &tex->resource) {
|
||||
cmask_reloc = r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx,
|
||||
tex->cmask, RADEON_USAGE_READWRITE);
|
||||
} else {
|
||||
cmask_reloc = reloc;
|
||||
}
|
||||
|
||||
r600_write_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, 13);
|
||||
radeon_emit(cs, cb->cb_color_base); /* R_028C60_CB_COLOR0_BASE */
|
||||
@@ -2208,7 +2222,7 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
|
||||
radeon_emit(cs, reloc);
|
||||
|
||||
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C7C_CB_COLOR0_CMASK */
|
||||
radeon_emit(cs, reloc);
|
||||
radeon_emit(cs, cmask_reloc);
|
||||
|
||||
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C84_CB_COLOR0_FMASK */
|
||||
radeon_emit(cs, reloc);
|
||||
|
||||
@@ -644,11 +644,15 @@ void r600_flag_resource_cache_flush(struct r600_context *rctx,
|
||||
|
||||
/* Check colorbuffers. */
|
||||
for (i = 0; i < rctx->framebuffer.state.nr_cbufs; i++) {
|
||||
if (rctx->framebuffer.state.cbufs[i] &&
|
||||
rctx->framebuffer.state.cbufs[i]->texture == res) {
|
||||
struct r600_texture *tex =
|
||||
(struct r600_texture*)rctx->framebuffer.state.cbufs[i]->texture;
|
||||
struct r600_texture *tex;
|
||||
|
||||
if (rctx->framebuffer.state.cbufs[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tex = (struct r600_texture*)rctx->framebuffer.state.cbufs[i]->texture;
|
||||
|
||||
if (rctx->framebuffer.state.cbufs[i]->texture == res) {
|
||||
rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB |
|
||||
R600_CONTEXT_FLUSH_AND_INV |
|
||||
R600_CONTEXT_WAIT_3D_IDLE;
|
||||
@@ -658,6 +662,12 @@ void r600_flag_resource_cache_flush(struct r600_context *rctx,
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (tex && tex->cmask && tex->cmask != &tex->resource && &tex->cmask->b.b == res) {
|
||||
rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB_META |
|
||||
R600_CONTEXT_FLUSH_AND_INV |
|
||||
R600_CONTEXT_WAIT_3D_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check a depth buffer. */
|
||||
|
||||
@@ -71,6 +71,7 @@ struct r600_texture {
|
||||
/* use htile only for first level */
|
||||
float depth_clear;
|
||||
|
||||
struct r600_resource *cmask;
|
||||
unsigned color_clear_value[2];
|
||||
};
|
||||
|
||||
@@ -152,6 +153,8 @@ void r600_texture_get_fmask_info(struct r600_screen *rscreen,
|
||||
void r600_texture_get_cmask_info(struct r600_screen *rscreen,
|
||||
struct r600_texture *rtex,
|
||||
struct r600_cmask_info *out);
|
||||
void r600_texture_init_cmask(struct r600_screen *rscreen,
|
||||
struct r600_texture *rtex);
|
||||
struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
|
||||
const struct pipe_resource *templ);
|
||||
struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
|
||||
|
||||
@@ -301,6 +301,9 @@ static void r600_texture_destroy(struct pipe_screen *screen,
|
||||
pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
|
||||
|
||||
pipe_resource_reference((struct pipe_resource**)&rtex->htile, NULL);
|
||||
if (rtex->cmask != &rtex->resource) {
|
||||
pipe_resource_reference((struct pipe_resource**)&rtex->cmask, NULL);
|
||||
}
|
||||
pb_reference(&resource->buf, NULL);
|
||||
FREE(rtex);
|
||||
}
|
||||
@@ -431,6 +434,24 @@ static void r600_texture_allocate_cmask(struct r600_screen *rscreen,
|
||||
#endif
|
||||
}
|
||||
|
||||
void r600_texture_init_cmask(struct r600_screen *rscreen,
|
||||
struct r600_texture *rtex) {
|
||||
struct r600_cmask_info cmask;
|
||||
|
||||
assert(rtex->cmask_size == 0);
|
||||
|
||||
r600_texture_get_cmask_info(rscreen, rtex, &cmask);
|
||||
rtex->cmask_slice_tile_max = cmask.slice_tile_max;
|
||||
rtex->cmask_offset = 0;
|
||||
rtex->cmask_size = cmask.size;
|
||||
rtex->cmask = (struct r600_resource *)pipe_buffer_create(&rscreen->b.b,
|
||||
PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, rtex->cmask_size);
|
||||
|
||||
if (rtex->cmask == NULL) {
|
||||
rtex->cmask_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct r600_texture *
|
||||
r600_texture_create_object(struct pipe_screen *screen,
|
||||
const struct pipe_resource *base,
|
||||
@@ -464,9 +485,11 @@ r600_texture_create_object(struct pipe_screen *screen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rtex->cmask = NULL;
|
||||
if (base->nr_samples > 1 && !rtex->is_depth && !buf) {
|
||||
r600_texture_allocate_fmask(rscreen, rtex);
|
||||
r600_texture_allocate_cmask(rscreen, rtex);
|
||||
rtex->cmask = &rtex->resource;
|
||||
}
|
||||
|
||||
if (!rtex->is_depth && base->nr_samples > 1 &&
|
||||
@@ -532,7 +555,7 @@ r600_texture_create_object(struct pipe_screen *screen,
|
||||
|
||||
if (rtex->cmask_size) {
|
||||
/* Initialize the cmask to 0xCC (= compressed state). */
|
||||
r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
|
||||
r600_screen_clear_buffer(rscreen, &rtex->cmask->b.b,
|
||||
rtex->cmask_offset, rtex->cmask_size, 0xCC);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user