+static uint32_t
+radv_get_cmask_fast_clear_value(const struct radv_image *image)
+{
+ uint32_t value = 0; /* Default value when no DCC. */
+
+ /* The fast-clear value is different for images that have both DCC and
+ * CMASK metadata.
+ */
+ if (radv_image_has_dcc(image)) {
+ /* DCC fast clear with MSAA should clear CMASK to 0xC. */
+ return image->info.samples > 1 ? 0xcccccccc : 0xffffffff;
+ }
+
+ return value;
+}
+
+uint32_t
+radv_clear_cmask(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_image *image, uint32_t value)
+{
+ return radv_fill_buffer(cmd_buffer, image->bo,
+ image->offset + image->cmask.offset,
+ image->cmask.size, value);
+}
+
+uint32_t
+radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_image *image, uint32_t value)
+{
+ return radv_fill_buffer(cmd_buffer, image->bo,
+ image->offset + image->dcc_offset,
+ image->surface.dcc_size, value);
+}
+
+static void vi_get_fast_clear_parameters(VkFormat format,
+ const VkClearColorValue *clear_value,
+ uint32_t* reset_value,
+ bool *can_avoid_fast_clear_elim)
+{
+ bool values[4] = {};
+ int extra_channel;
+ bool main_value = false;
+ bool extra_value = false;
+ int i;
+ *can_avoid_fast_clear_elim = false;
+
+ *reset_value = 0x20202020U;
+
+ const struct vk_format_description *desc = vk_format_description(format);
+ if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32 ||
+ format == VK_FORMAT_R5G6B5_UNORM_PACK16 ||
+ format == VK_FORMAT_B5G6R5_UNORM_PACK16)
+ extra_channel = -1;
+ else if (desc->layout == VK_FORMAT_LAYOUT_PLAIN) {
+ if (radv_translate_colorswap(format, false) <= 1)
+ extra_channel = desc->nr_channels - 1;
+ else
+ extra_channel = 0;
+ } else
+ return;
+
+ for (i = 0; i < 4; i++) {
+ int index = desc->swizzle[i] - VK_SWIZZLE_X;
+ if (desc->swizzle[i] < VK_SWIZZLE_X ||
+ desc->swizzle[i] > VK_SWIZZLE_W)
+ continue;
+
+ if (desc->channel[i].pure_integer &&
+ desc->channel[i].type == VK_FORMAT_TYPE_SIGNED) {
+ /* Use the maximum value for clamping the clear color. */
+ int max = u_bit_consecutive(0, desc->channel[i].size - 1);
+
+ values[i] = clear_value->int32[i] != 0;
+ if (clear_value->int32[i] != 0 && MIN2(clear_value->int32[i], max) != max)
+ return;
+ } else if (desc->channel[i].pure_integer &&
+ desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) {
+ /* Use the maximum value for clamping the clear color. */
+ unsigned max = u_bit_consecutive(0, desc->channel[i].size);
+
+ values[i] = clear_value->uint32[i] != 0U;
+ if (clear_value->uint32[i] != 0U && MIN2(clear_value->uint32[i], max) != max)
+ return;
+ } else {
+ values[i] = clear_value->float32[i] != 0.0F;
+ if (clear_value->float32[i] != 0.0F && clear_value->float32[i] != 1.0F)
+ return;
+ }
+
+ if (index == extra_channel)
+ extra_value = values[i];
+ else
+ main_value = values[i];
+ }
+
+ for (int i = 0; i < 4; ++i)
+ if (values[i] != main_value &&
+ desc->swizzle[i] - VK_SWIZZLE_X != extra_channel &&
+ desc->swizzle[i] >= VK_SWIZZLE_X &&
+ desc->swizzle[i] <= VK_SWIZZLE_W)
+ return;
+
+ *can_avoid_fast_clear_elim = true;
+ if (main_value)
+ *reset_value |= 0x80808080U;
+
+ if (extra_value)
+ *reset_value |= 0x40404040U;
+ return;
+}
+