summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2016-03-29 01:36:40 +0200
committerMarek Olšák <[email protected]>2016-04-05 15:32:40 +0200
commita64dbdf612805daff0bbc70bba26053bd226ae70 (patch)
tree7f65ac2dc031ccd81c1174caf4799d0ee019a490 /src/gallium
parent25f96d2b9766afa61a518667268e3134f43451e2 (diff)
gallium/radeon: allow multiple exports of the same texture with different usage
Instead of failing an assertion, disable DCC and CMASK on the first export that needs it, and merge the external usage flags. v2: clear the EXPLICIT_FLUSH flag if it's not set; whitespace fixes Reviewed-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 83fc0021227..4850b73f291 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -329,6 +329,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
struct r600_resource *res = (struct r600_resource*)resource;
struct r600_texture *rtex = (struct r600_texture*)resource;
struct radeon_bo_metadata metadata;
+ bool update_metadata = false;
/* This is not supported now, but it might be required for OpenCL
* interop in the future.
@@ -337,29 +338,30 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
(resource->nr_samples > 1 || rtex->is_depth))
return false;
- if (!res->is_shared) {
- res->is_shared = true;
- res->external_usage = usage;
-
- if (resource->target != PIPE_BUFFER) {
- /* Since shader image stores don't support DCC on VI,
- * disable it for external clients that want write
- * access.
- */
- if (usage & PIPE_HANDLE_USAGE_WRITE)
- r600_texture_disable_dcc(rscreen, rtex);
+ if (resource->target != PIPE_BUFFER) {
+ /* Since shader image stores don't support DCC on VI,
+ * disable it for external clients that want write
+ * access.
+ */
+ if (usage & PIPE_HANDLE_USAGE_WRITE && rtex->dcc_offset) {
+ r600_texture_disable_dcc(rscreen, rtex);
+ update_metadata = true;
+ }
- if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH)) {
- /* Eliminate fast clear (both CMASK and DCC) */
- r600_eliminate_fast_color_clear(rscreen, rtex);
+ if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
+ rtex->cmask.size) {
+ /* 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);
- }
+ /* Disable CMASK if flush_resource isn't going
+ * to be called.
+ */
+ r600_texture_disable_cmask(rscreen, rtex);
+ update_metadata = true;
+ }
- /* Set metadata. */
+ /* Set metadata. */
+ if (!res->is_shared || update_metadata) {
r600_texture_init_metadata(rtex, &metadata);
if (rscreen->query_opaque_metadata)
rscreen->query_opaque_metadata(rscreen, rtex,
@@ -367,8 +369,18 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
rscreen->ws->buffer_set_metadata(res->buf, &metadata);
}
+ }
+
+ if (res->is_shared) {
+ /* USAGE_EXPLICIT_FLUSH must be cleared if at least one user
+ * doesn't set it.
+ */
+ res->external_usage |= usage & ~PIPE_HANDLE_USAGE_EXPLICIT_FLUSH;
+ if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH))
+ res->external_usage &= ~PIPE_HANDLE_USAGE_EXPLICIT_FLUSH;
} else {
- assert(res->external_usage == usage);
+ res->is_shared = true;
+ res->external_usage = usage;
}
return rscreen->ws->buffer_get_handle(res->buf,