iris: Don't try to CPU read imported clear color BOs
Previously, when importing a resource with modifiers that include clear color as auxiliary data, we were mapping the clear color BO on the CPU in order to set res->aux.clear_color to the value stored there. We are generally trying to avoid CPU mapping imported buffers, because in hybrid setups, they could be from a different device, and may not be mappable. So we'd like to avoid that here. This CPU-side knowledge of the clear color is only used in a few cases: 1. Avoiding a resolve due to a partial clear with a changing clear color 2. Avoiding disabling CCS when rendering to a texture view of a resource where the only format difference is sRGB vs. linear and the clear color is 0/1. Instead of mapping the clear color BO on the CPU, we instead set a flag indicating that we don't know the clear color, and reset it to known on our first clear. In the first case, the first partial fast clear of a resource would eat an extra resolve (there is no penalty if we clear the whole resource). The second case doesn't seem that critical, as it's someone rendering to an imported BO - when the common case is to texture from it. Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11888>
This commit is contained in:

committed by
Marge Bot

parent
373f0d6acc
commit
e83da2d8e3
@@ -114,7 +114,7 @@ can_fast_clear_color(struct iris_context *ice,
|
||||
* resource and not the renderbuffer.
|
||||
*/
|
||||
if (!iris_render_formats_color_compatible(render_format, res->surf.format,
|
||||
color)) {
|
||||
color, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -218,8 +218,8 @@ fast_clear_color(struct iris_context *ice,
|
||||
struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
|
||||
struct pipe_resource *p_res = (void *) res;
|
||||
|
||||
bool color_changed = !!memcmp(&res->aux.clear_color, &color,
|
||||
sizeof(color));
|
||||
bool color_changed = res->aux.clear_color_unknown ||
|
||||
memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0;
|
||||
|
||||
if (color_changed) {
|
||||
/* If we are clearing to a new clear value, we need to resolve fast
|
||||
@@ -257,16 +257,24 @@ fast_clear_color(struct iris_context *ice,
|
||||
res_lvl, 1, layer, 1,
|
||||
res->aux.usage,
|
||||
false);
|
||||
perf_debug(&ice->dbg,
|
||||
"Resolving resource (%p) level %d, layer %d: color changing from "
|
||||
"(%0.2f, %0.2f, %0.2f, %0.2f) to "
|
||||
"(%0.2f, %0.2f, %0.2f, %0.2f)\n",
|
||||
res, res_lvl, layer,
|
||||
res->aux.clear_color.f32[0],
|
||||
res->aux.clear_color.f32[1],
|
||||
res->aux.clear_color.f32[2],
|
||||
res->aux.clear_color.f32[3],
|
||||
color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
|
||||
if (res->aux.clear_color_unknown) {
|
||||
perf_debug(&ice->dbg,
|
||||
"Resolving resource (%p) level %d, layer %d: color changing from "
|
||||
"(unknown) to (%0.2f, %0.2f, %0.2f, %0.2f)\n",
|
||||
res, res_lvl, layer,
|
||||
color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
|
||||
} else {
|
||||
perf_debug(&ice->dbg,
|
||||
"Resolving resource (%p) level %d, layer %d: color changing from "
|
||||
"(%0.2f, %0.2f, %0.2f, %0.2f) to "
|
||||
"(%0.2f, %0.2f, %0.2f, %0.2f)\n",
|
||||
res, res_lvl, layer,
|
||||
res->aux.clear_color.f32[0],
|
||||
res->aux.clear_color.f32[1],
|
||||
res->aux.clear_color.f32[2],
|
||||
res->aux.clear_color.f32[3],
|
||||
color.f32[0], color.f32[1], color.f32[2], color.f32[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -463,7 +471,7 @@ fast_clear_depth(struct iris_context *ice,
|
||||
/* If we're clearing to a new clear value, then we need to resolve any clear
|
||||
* flags out of the HiZ buffer into the real depth buffer.
|
||||
*/
|
||||
if (res->aux.clear_color.f32[0] != depth) {
|
||||
if (res->aux.clear_color_unknown || res->aux.clear_color.f32[0] != depth) {
|
||||
for (unsigned res_level = 0; res_level < res->surf.levels; res_level++) {
|
||||
const unsigned level_layers =
|
||||
iris_get_num_logical_layers(res, res_level);
|
||||
|
@@ -957,13 +957,15 @@ iris_resource_prepare_texture(struct iris_context *ice,
|
||||
*/
|
||||
bool
|
||||
iris_render_formats_color_compatible(enum isl_format a, enum isl_format b,
|
||||
union isl_color_value color)
|
||||
union isl_color_value color,
|
||||
bool clear_color_unknown)
|
||||
{
|
||||
if (a == b)
|
||||
return true;
|
||||
|
||||
/* A difference in color space doesn't matter for 0/1 values. */
|
||||
if (isl_format_srgb_to_linear(a) == isl_format_srgb_to_linear(b) &&
|
||||
if (!clear_color_unknown &&
|
||||
isl_format_srgb_to_linear(a) == isl_format_srgb_to_linear(b) &&
|
||||
isl_color_value_is_zero_one(color, a)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1014,7 +1016,8 @@ iris_resource_render_aux_usage(struct iris_context *ice,
|
||||
*/
|
||||
if (!iris_render_formats_color_compatible(render_format,
|
||||
res->surf.format,
|
||||
res->aux.clear_color)) {
|
||||
res->aux.clear_color,
|
||||
res->aux.clear_color_unknown)) {
|
||||
return ISL_AUX_USAGE_NONE;
|
||||
}
|
||||
|
||||
|
@@ -940,9 +940,7 @@ iris_resource_finish_aux_import(struct pipe_screen *pscreen,
|
||||
iris_bo_reference(r[2]->aux.clear_color_bo);
|
||||
r[0]->aux.clear_color_bo = r[2]->aux.clear_color_bo;
|
||||
r[0]->aux.clear_color_offset = r[2]->aux.clear_color_offset;
|
||||
memcpy(res->aux.clear_color.f32,
|
||||
iris_bo_map(NULL, res->aux.clear_color_bo, MAP_READ|MAP_RAW) +
|
||||
res->aux.clear_color_offset, sizeof(res->aux.clear_color.f32));
|
||||
r[0]->aux.clear_color_unknown = true;
|
||||
} else if (num_main_planes == 2 && num_planes == 4) {
|
||||
import_aux_info(r[0], r[2]);
|
||||
import_aux_info(r[1], r[3]);
|
||||
@@ -2373,8 +2371,10 @@ iris_resource_set_clear_color(struct iris_context *ice,
|
||||
struct iris_resource *res,
|
||||
union isl_color_value color)
|
||||
{
|
||||
if (memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0) {
|
||||
if (res->aux.clear_color_unknown ||
|
||||
memcmp(&res->aux.clear_color, &color, sizeof(color)) != 0) {
|
||||
res->aux.clear_color = color;
|
||||
res->aux.clear_color_unknown = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -113,9 +113,17 @@ struct iris_resource {
|
||||
uint32_t offset;
|
||||
} extra_aux;
|
||||
|
||||
/**
|
||||
* When importing resources with a clear color, we may not know the
|
||||
* clear color on the CPU at first.
|
||||
*/
|
||||
bool clear_color_unknown;
|
||||
|
||||
/**
|
||||
* Fast clear color for this surface. For depth surfaces, the clear
|
||||
* value is stored as a float32 in the red component.
|
||||
*
|
||||
* Do not rely on this value if clear_color_unknown is set.
|
||||
*/
|
||||
union isl_color_value clear_color;
|
||||
|
||||
@@ -516,7 +524,8 @@ bool iris_has_color_unresolved(const struct iris_resource *res,
|
||||
|
||||
bool iris_render_formats_color_compatible(enum isl_format a,
|
||||
enum isl_format b,
|
||||
union isl_color_value color);
|
||||
union isl_color_value color,
|
||||
bool clear_color_unknown);
|
||||
enum isl_aux_usage iris_resource_render_aux_usage(struct iris_context *ice,
|
||||
struct iris_resource *res,
|
||||
uint32_t level,
|
||||
|
Reference in New Issue
Block a user