static void
radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer,
int index,
- struct radv_attachment_info *att)
+ struct radv_attachment_info *att,
+ struct radv_image *image,
+ VkImageLayout layout)
{
bool is_vi = cmd_buffer->device->physical_device->rad_info.chip_class >= VI;
struct radv_color_buffer_info *cb = &att->cb;
+ uint32_t cb_color_info = cb->cb_color_info;
+
+ if (!radv_layout_dcc_compressed(image, layout,
+ radv_image_queue_family_mask(image,
+ cmd_buffer->queue_family_index,
+ cmd_buffer->queue_family_index))) {
+ cb_color_info &= C_028C70_DCC_ENABLE;
+ }
if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
radeon_set_context_reg_seq(cmd_buffer->cs, R_028C60_CB_COLOR0_BASE + index * 0x3c, 11);
radeon_emit(cmd_buffer->cs, cb->cb_color_base >> 32);
radeon_emit(cmd_buffer->cs, cb->cb_color_attrib2);
radeon_emit(cmd_buffer->cs, cb->cb_color_view);
- radeon_emit(cmd_buffer->cs, cb->cb_color_info);
+ radeon_emit(cmd_buffer->cs, cb_color_info);
radeon_emit(cmd_buffer->cs, cb->cb_color_attrib);
radeon_emit(cmd_buffer->cs, cb->cb_dcc_control);
radeon_emit(cmd_buffer->cs, cb->cb_color_cmask);
radeon_emit(cmd_buffer->cs, cb->cb_color_pitch);
radeon_emit(cmd_buffer->cs, cb->cb_color_slice);
radeon_emit(cmd_buffer->cs, cb->cb_color_view);
- radeon_emit(cmd_buffer->cs, cb->cb_color_info);
+ radeon_emit(cmd_buffer->cs, cb_color_info);
radeon_emit(cmd_buffer->cs, cb->cb_color_attrib);
radeon_emit(cmd_buffer->cs, cb->cb_dcc_control);
radeon_emit(cmd_buffer->cs, cb->cb_color_cmask);
int idx = subpass->color_attachments[i].attachment;
struct radv_attachment_info *att = &framebuffer->attachments[idx];
+ struct radv_image *image = att->attachment->image;
+ VkImageLayout layout = subpass->color_attachments[i].layout;
radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, att->attachment->bo, 8);
assert(att->attachment->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT);
- radv_emit_fb_color_state(cmd_buffer, i, att);
+ radv_emit_fb_color_state(cmd_buffer, i, att, image, layout);
- radv_load_color_clear_regs(cmd_buffer, att->attachment->image, i);
+ radv_load_color_clear_regs(cmd_buffer, image, i);
}
if(subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
const VkImageSubresourceRange *range)
{
if (src_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
- radv_initialize_dcc(cmd_buffer, image, 0x20202020u);
+ radv_initialize_dcc(cmd_buffer, image,
+ radv_layout_dcc_compressed(image, dst_layout, dst_queue_mask) ?
+ 0x20202020u : 0xffffffffu);
+ } else if (radv_layout_dcc_compressed(image, src_layout, src_queue_mask) &&
+ !radv_layout_dcc_compressed(image, dst_layout, dst_queue_mask)) {
+ radv_decompress_dcc(cmd_buffer, image, range);
} else if (radv_layout_can_fast_clear(image, src_layout, src_queue_mask) &&
!radv_layout_can_fast_clear(image, dst_layout, dst_queue_mask)) {
radv_fast_clear_flush_image_inplace(cmd_buffer, image, range);
static void radv_pick_resolve_method_images(struct radv_image *src_image,
struct radv_image *dest_image,
+ VkImageLayout dest_image_layout,
+ struct radv_cmd_buffer *cmd_buffer,
enum radv_resolve_method *method)
{
- if (dest_image->surface.num_dcc_levels > 0) {
+ uint32_t queue_mask = radv_image_queue_family_mask(dest_image,
+ cmd_buffer->queue_family_index,
+ cmd_buffer->queue_family_index);
+ if (radv_layout_dcc_compressed(dest_image, dest_image_layout, queue_mask)) {
*method = RESOLVE_FRAGMENT;
} else if (dest_image->surface.micro_tile_mode != src_image->surface.micro_tile_mode) {
*method = RESOLVE_COMPUTE;
resolve_method = RESOLVE_COMPUTE;
radv_pick_resolve_method_images(src_image, dest_image,
+ dest_image_layout, cmd_buffer,
&resolve_method);
if (resolve_method == RESOLVE_FRAGMENT) {
struct radv_image *dst_img = cmd_buffer->state.framebuffer->attachments[dest_att.attachment].attachment->image;
struct radv_image *src_img = cmd_buffer->state.framebuffer->attachments[src_att.attachment].attachment->image;
- radv_pick_resolve_method_images(dst_img, src_img, &resolve_method);
+ radv_pick_resolve_method_images(dst_img, src_img, dest_att.layout, cmd_buffer, &resolve_method);
if (resolve_method == RESOLVE_FRAGMENT) {
break;
}