diff --git a/src/amd/common/ac_descriptors.h b/src/amd/common/ac_descriptors.h index 99cafa8a110..f938edc593c 100644 --- a/src/amd/common/ac_descriptors.h +++ b/src/amd/common/ac_descriptors.h @@ -17,6 +17,7 @@ extern "C" { #endif +#define DUPL_16BITS_IN_DWORD(x) (((x) << 16) | (x)) #define DUPL_8BITS_IN_DWORD(x) (((x) << 24) | ((x) << 16) | ((x) << 8) | (x)) #define DUPL_4BITS_IN_DWORD(x) DUPL_8BITS_IN_DWORD((x) | ((x) << 4)) @@ -67,6 +68,45 @@ enum { CMASK_8xMSAA_FMASK_UNCOMPRESSED_COLOR_EXPANDED = CMASK_MSAA_CODE(3, 3), }; +enum { + /* Don't ever use this. Clear CMASK instead. */ + FMASK_CLEAR_0 = 0, + + /* These can be used only if FMASK is uncompressed in CMASK. + * + * Uncompressed doesn't mean expanded. + * - FMASK compression only affects bandwidth, not stored values. The compression is done by CMASK. + * - Expanded FMASK means that specific values are stored in it such that FMASK has no effect. + * FMASK expansion is a layout transition only required before MSAA image stores. + * - CB_FMASK_DECOMPRESS is a layout transition required before any shader access, and does: + * 1. FMASK decompression: Eliminating CMASK compression. + * 2. CMASK fast color clear elimination: Writing the clear value in CB_COLORi_CLEAR_WORDj + * registers to cleared areas of the color image. + * ! It doesn't do FMASK expansion, which must be done by a compute shader. + * - GFX8-10.3: To avoid CB_FMASK_DECOMPRESS before shader access (except MSAA image stores): + * - Use FMASK with TC-compatible CMASK. (enabled by FMASK_COMPRESS_1FRAG_ONLY) + * - Use DCC for fast MSAA color clears instead of CMASK. + */ + FMASK_2xMSAA_EXPANDED = DUPL_8BITS_IN_DWORD(0x02), + FMASK_4xMSAA_EXPANDED = DUPL_8BITS_IN_DWORD(0xE4), + FMASK_8xMSAA_EXPANDED = 0x76543210, + + FMASK_EQAA_2S_1F_EXPANDED = FMASK_2xMSAA_EXPANDED, + FMASK_EQAA_4S_1F_EXPANDED = DUPL_8BITS_IN_DWORD(0x0E), + FMASK_EQAA_8S_1F_EXPANDED = DUPL_8BITS_IN_DWORD(0xFE), + FMASK_EQAA_16S_1F_EXPANDED = DUPL_16BITS_IN_DWORD(0xFFFE), + + FMASK_EQAA_4S_2F_EXPANDED = DUPL_8BITS_IN_DWORD(0xA4), + FMASK_EQAA_8S_2F_EXPANDED = DUPL_16BITS_IN_DWORD(0xAAA4), + FMASK_EQAA_16S_2F_EXPANDED = 0xAAAAAAA4, + + FMASK_EQAA_8S_4F_EXPANDED = 0x44443210, + FMASK_EQAA_16S_4F_EXPANDED = 0x4444444444443210ull, /* 8-byte clear value */ + + /* Enums don't allow such large numbers. */ + #define FMASK_EQAA_16S_8F_EXPANDED 0x8888888876543210ull /* 8-byte clear value */ +}; + typedef union { /* Z only */ struct { diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index d65491d1e55..b8bcdede794 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -14298,7 +14298,12 @@ radv_init_cmask(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, co uint32_t radv_init_fmask(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image, const VkImageSubresourceRange *range) { - static const uint32_t fmask_clear_values[4] = {0x00000000, 0x02020202, 0xE4E4E4E4, 0x76543210}; + static const uint32_t fmask_clear_values[4] = { + 0, /* unused */ + FMASK_2xMSAA_EXPANDED, + FMASK_4xMSAA_EXPANDED, + FMASK_8xMSAA_EXPANDED, + }; uint32_t log2_samples = util_logbase2(image->vk.samples); uint32_t value = fmask_clear_values[log2_samples]; struct radv_barrier_data barrier = {0}; diff --git a/src/gallium/drivers/radeonsi/si_compute_blit.c b/src/gallium/drivers/radeonsi/si_compute_blit.c index d80df6404df..26b071ed1e7 100644 --- a/src/gallium/drivers/radeonsi/si_compute_blit.c +++ b/src/gallium/drivers/radeonsi/si_compute_blit.c @@ -481,14 +481,26 @@ void si_compute_expand_fmask(struct pipe_context *ctx, struct pipe_resource *tex pipe_resource_reference(&saved_image.resource, NULL); /* Array of fully expanded FMASK values, arranged by [log2(fragments)][log2(samples)-1]. */ -#define INVALID 0 /* never used */ - static const uint64_t fmask_expand_values[][4] = { - /* samples */ - /* 2 (8 bpp) 4 (8 bpp) 8 (8-32bpp) 16 (16-64bpp) fragments */ - {0x02020202, 0x0E0E0E0E, 0xFEFEFEFE, 0xFFFEFFFE}, /* 1 */ - {0x02020202, 0xA4A4A4A4, 0xAAA4AAA4, 0xAAAAAAA4}, /* 2 */ - {INVALID, 0xE4E4E4E4, 0x44443210, 0x4444444444443210}, /* 4 */ - {INVALID, INVALID, 0x76543210, 0x8888888876543210}, /* 8 */ + static const uint64_t fmask_expand_values[4][4] = { + {FMASK_EQAA_2S_1F_EXPANDED, + FMASK_EQAA_4S_1F_EXPANDED, + FMASK_EQAA_8S_1F_EXPANDED, + FMASK_EQAA_16S_1F_EXPANDED}, + + {FMASK_2xMSAA_EXPANDED, + FMASK_EQAA_4S_2F_EXPANDED, + FMASK_EQAA_8S_2F_EXPANDED, + FMASK_EQAA_16S_2F_EXPANDED}, + + {0, /* unused */ + FMASK_4xMSAA_EXPANDED, + FMASK_EQAA_8S_4F_EXPANDED, + FMASK_EQAA_16S_4F_EXPANDED}, + + {0, /* unused */ + 0, /* unused */ + FMASK_8xMSAA_EXPANDED, + FMASK_EQAA_16S_8F_EXPANDED}, }; /* Clear FMASK to identity. */