diff options
author | Marek Olšák <[email protected]> | 2016-02-24 22:04:47 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2016-03-09 15:02:27 +0100 |
commit | 60c08aa90bce4c8766a747c8517f7ff6987937f0 (patch) | |
tree | 049d87112cbb6fca483a302fcf4edd9e91f1b4e7 /src/gallium/drivers/radeon | |
parent | 970b979da1639d57e89169f96cc0064db9dae43a (diff) |
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 <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeon')
-rw-r--r-- | src/gallium/drivers/radeon/r600_pipe_common.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 34 |
2 files changed, 42 insertions, 0 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 3bbbfbbd528..7763ea30777 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -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; diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index ec2f2454b1c..65b17a01dc3 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -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); |