radv: Support DCC without a fast clear value.

For imported images we can't have one in the associated memory.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9998>
This commit is contained in:
Bas Nieuwenhuizen 2021-03-08 15:45:50 +01:00 committed by Marge Bot
parent f0861c803e
commit b61efd53b4
3 changed files with 38 additions and 11 deletions

View file

@ -2207,23 +2207,29 @@ radv_set_color_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
uint32_t color_values[2])
{
struct radeon_cmdbuf *cs = cmd_buffer->cs;
uint64_t va = radv_image_get_fast_clear_va(image, range->baseMipLevel);
uint32_t level_count = radv_get_levelCount(image, range);
uint32_t count = 2 * level_count;
assert(radv_image_has_cmask(image) ||
radv_dcc_enabled(image, range->baseMipLevel));
radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 2 + count, cmd_buffer->state.predicating));
radeon_emit(cs, S_370_DST_SEL(V_370_MEM) |
S_370_WR_CONFIRM(1) |
S_370_ENGINE_SEL(V_370_PFP));
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
if (radv_image_has_clear_value(image)) {
uint64_t va = radv_image_get_fast_clear_va(image, range->baseMipLevel);
for (uint32_t l = 0; l < level_count; l++) {
radeon_emit(cs, color_values[0]);
radeon_emit(cs, color_values[1]);
radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 2 + count, cmd_buffer->state.predicating));
radeon_emit(cs, S_370_DST_SEL(V_370_MEM) |
S_370_WR_CONFIRM(1) |
S_370_ENGINE_SEL(V_370_PFP));
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
for (uint32_t l = 0; l < level_count; l++) {
radeon_emit(cs, color_values[0]);
radeon_emit(cs, color_values[1]);
}
} else {
/* Some default value we can set in the update. */
assert(color_values[0] == 0 && color_values[1] == 0);
}
}
@ -2264,12 +2270,19 @@ radv_load_color_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
{
struct radeon_cmdbuf *cs = cmd_buffer->cs;
struct radv_image *image = iview->image;
uint64_t va = radv_image_get_fast_clear_va(image, iview->base_mip);
if (!radv_image_has_cmask(image) &&
!radv_dcc_enabled(image, iview->base_mip))
return;
if (!radv_image_has_clear_value(image)) {
uint32_t color_values[2] = {0, 0};
radv_update_bound_fast_clear_color(cmd_buffer, image, cb_idx,
color_values);
return;
}
uint64_t va = radv_image_get_fast_clear_va(image, iview->base_mip);
uint32_t reg = R_028C8C_CB_COLOR0_CLEAR_WORD0 + cb_idx * 0x3c;
if (cmd_buffer->device->physical_device->rad_info.has_load_ctx_reg_pkt) {

View file

@ -1636,6 +1636,10 @@ radv_can_fast_clear_color(struct radv_cmd_buffer *cmd_buffer,
clear_color, &clear_value))
return false;
if (!radv_image_has_clear_value(iview->image) &&
(clear_color[0] != 0 || clear_color[1] != 0))
return false;
if (radv_dcc_enabled(iview->image, iview->base_mip)) {
bool can_avoid_fast_clear_elim;
uint32_t reset_value;

View file

@ -2022,10 +2022,18 @@ radv_image_tile_stencil_disabled(const struct radv_device *device,
}
}
static inline bool
radv_image_has_clear_value(const struct radv_image *image)
{
return image->clear_value_offset != 0;
}
static inline uint64_t
radv_image_get_fast_clear_va(const struct radv_image *image,
uint32_t base_level)
{
assert(radv_image_has_clear_value(image));
uint64_t va = radv_buffer_get_va(image->bo);
va += image->offset + image->clear_value_offset + base_level * 8;
return va;
@ -2062,6 +2070,8 @@ static inline uint64_t
radv_get_ds_clear_value_va(const struct radv_image *image,
uint32_t base_level)
{
assert(radv_image_has_clear_value(image));
uint64_t va = radv_buffer_get_va(image->bo);
va += image->offset + image->clear_value_offset + base_level * 8;
return va;