diff options
author | Marek Olšák <[email protected]> | 2016-03-29 01:36:40 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2016-04-05 15:32:40 +0200 |
commit | a64dbdf612805daff0bbc70bba26053bd226ae70 (patch) | |
tree | 7f65ac2dc031ccd81c1174caf4799d0ee019a490 | |
parent | 25f96d2b9766afa61a518667268e3134f43451e2 (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]>
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 54 |
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, |