summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeon')
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h8
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c34
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);