gallium/radeon: disable CMASK on handle export if sharing doesn't allow it (v2)

v2: remove the list of all contexts

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
Marek Olšák 2016-02-24 22:04:47 +01:00
parent 970b979da1
commit 60c08aa90b
4 changed files with 61 additions and 2 deletions

View file

@ -1672,7 +1672,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
bool render_cond_bit = rctx->b.render_cond && !rctx->b.render_cond_force_off;
uint64_t mask;
unsigned num_patches;
unsigned num_patches, dirty_fb_counter;
if (!info.indirect && !info.count && (info.indexed || !info.count_from_stream_output)) {
return;
@ -1688,6 +1688,13 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
rctx->b.dma.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
}
/* Re-emit the framebuffer state if needed. */
dirty_fb_counter = p_atomic_read(&rctx->b.screen->dirty_fb_counter);
if (dirty_fb_counter != rctx->b.last_dirty_fb_counter) {
rctx->b.last_dirty_fb_counter = dirty_fb_counter;
r600_mark_atom_dirty(rctx, &rctx->framebuffer.atom);
}
if (!r600_update_derived_state(rctx)) {
/* useless to render because current rendering command
* can't be achieved

View file

@ -325,6 +325,13 @@ struct r600_common_screen {
/* Performance counters. */
struct r600_perfcounters *perfcounters;
/* If pipe_screen wants to re-emit the framebuffer state of all
* contexts, it should atomically increment this. Each context will
* compare this with its own last known value of the counter before
* drawing and re-emit the framebuffer state accordingly.
*/
unsigned dirty_fb_counter;
};
/* This encapsulates a state or an operation which can emitted into the GPU
@ -392,6 +399,7 @@ struct r600_common_context {
struct pipe_fence_handle *last_sdma_fence;
unsigned initial_gfx_cs_size;
unsigned gpu_reset_counter;
unsigned last_dirty_fb_counter;
struct u_upload_mgr *uploader;
struct u_suballocator *allocator_so_filled_size;

View file

@ -249,6 +249,11 @@ static void r600_texture_init_metadata(struct r600_texture *rtex,
metadata->scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
}
static void r600_dirty_all_framebuffer_states(struct r600_common_screen *rscreen)
{
p_atomic_inc(&rscreen->dirty_fb_counter);
}
static void r600_eliminate_fast_color_clear(struct r600_common_screen *rscreen,
struct r600_texture *rtex)
{
@ -260,6 +265,30 @@ static void r600_eliminate_fast_color_clear(struct r600_common_screen *rscreen,
pipe_mutex_unlock(rscreen->aux_context_lock);
}
static void r600_texture_disable_cmask(struct r600_common_screen *rscreen,
struct r600_texture *rtex)
{
if (!rtex->cmask.size)
return;
assert(rtex->resource.b.b.nr_samples <= 1);
/* Disable CMASK. */
memset(&rtex->cmask, 0, sizeof(rtex->cmask));
rtex->cmask.base_address_reg = rtex->resource.gpu_address >> 8;
if (rscreen->chip_class >= SI)
rtex->cb_color_info &= ~SI_S_028C70_FAST_CLEAR(1);
else
rtex->cb_color_info &= ~EG_S_028C70_FAST_CLEAR(1);
if (rtex->cmask_buffer != &rtex->resource)
pipe_resource_reference((struct pipe_resource**)&rtex->cmask_buffer, NULL);
/* Notify all contexts about the change. */
r600_dirty_all_framebuffer_states(rscreen);
}
static boolean r600_texture_get_handle(struct pipe_screen* screen,
struct pipe_resource *resource,
struct winsys_handle *whandle,
@ -285,6 +314,11 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH)) {
/* Eliminate fast clear (both CMASK and DCC) */
r600_eliminate_fast_color_clear(rscreen, rtex);
/* Disable CMASK if flush_resource isn't going
* to be called.
*/
r600_texture_disable_cmask(rscreen, rtex);
}
r600_texture_init_metadata(rtex, &metadata);

View file

@ -763,7 +763,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
struct si_context *sctx = (struct si_context *)ctx;
struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
struct pipe_index_buffer ib = {};
unsigned mask;
unsigned mask, dirty_fb_counter;
if (!info->count && !info->indirect &&
(info->indexed || !info->count_from_stream_output))
@ -782,6 +782,16 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
return;
}
/* Re-emit the framebuffer state if needed. */
dirty_fb_counter = p_atomic_read(&sctx->b.screen->dirty_fb_counter);
if (dirty_fb_counter != sctx->b.last_dirty_fb_counter) {
sctx->b.last_dirty_fb_counter = dirty_fb_counter;
sctx->framebuffer.dirty_cbufs |=
((1 << sctx->framebuffer.state.nr_cbufs) - 1);
sctx->framebuffer.dirty_zsbuf = true;
si_mark_atom_dirty(sctx, &sctx->framebuffer.atom);
}
si_decompress_textures(sctx);
/* Set the rasterization primitive type.