diff --git a/src/amd/common/ac_descriptors.c b/src/amd/common/ac_descriptors.c index 247e937c311..fb27d71e450 100644 --- a/src/amd/common/ac_descriptors.c +++ b/src/amd/common/ac_descriptors.c @@ -6,6 +6,7 @@ */ #include "ac_descriptors.h" +#include "ac_surface.h" #include "sid.h" @@ -62,3 +63,241 @@ ac_build_sampler_descriptor(const enum amd_gfx_level gfx_level, const struct ac_ desc[3] |= S_008F3C_BORDER_COLOR_PTR_GFX6(state->border_color_ptr); } } + +static void +ac_build_gfx6_fmask_descriptor(const enum amd_gfx_level gfx_level, const struct ac_fmask_state *state, uint32_t desc[8]) +{ + const struct radeon_surf *surf = state->surf; + const uint64_t va = state->va + surf->fmask_offset; + uint32_t data_format, num_format; + +#define FMASK(s, f) (((unsigned)(MAX2(1, s)) * 16) + (MAX2(1, f))) + if (gfx_level == GFX9) { + data_format = V_008F14_IMG_DATA_FORMAT_FMASK; + switch (FMASK(state->num_samples, state->num_storage_samples)) { + case FMASK(2, 1): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_1; + break; + case FMASK(2, 2): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_2; + break; + case FMASK(4, 1): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_1; + break; + case FMASK(4, 2): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_2; + break; + case FMASK(4, 4): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_4; + break; + case FMASK(8, 1): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_8_1; + break; + case FMASK(8, 2): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_16_8_2; + break; + case FMASK(8, 4): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_4; + break; + case FMASK(8, 8): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_8; + break; + case FMASK(16, 1): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_16_16_1; + break; + case FMASK(16, 2): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_16_2; + break; + case FMASK(16, 4): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_64_16_4; + break; + case FMASK(16, 8): + num_format = V_008F14_IMG_NUM_FORMAT_FMASK_64_16_8; + break; + default: + unreachable("invalid nr_samples"); + } + } else { + switch (FMASK(state->num_samples, state->num_storage_samples)) { + case FMASK(2, 1): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F1; + break; + case FMASK(2, 2): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2; + break; + case FMASK(4, 1): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F1; + break; + case FMASK(4, 2): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F2; + break; + case FMASK(4, 4): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4; + break; + case FMASK(8, 1): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S8_F1; + break; + case FMASK(8, 2): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK16_S8_F2; + break; + case FMASK(8, 4): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F4; + break; + case FMASK(8, 8): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8; + break; + case FMASK(16, 1): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK16_S16_F1; + break; + case FMASK(16, 2): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S16_F2; + break; + case FMASK(16, 4): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK64_S16_F4; + break; + case FMASK(16, 8): + data_format = V_008F14_IMG_DATA_FORMAT_FMASK64_S16_F8; + break; + default: + unreachable("invalid nr_samples"); + } + num_format = V_008F14_IMG_NUM_FORMAT_UINT; + } +#undef FMASK + + desc[0] = (va >> 8) | surf->fmask_tile_swizzle; + desc[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | + S_008F14_DATA_FORMAT(data_format) | + S_008F14_NUM_FORMAT(num_format); + desc[2] = S_008F18_WIDTH(state->width - 1) | + S_008F18_HEIGHT(state->height - 1); + desc[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | + S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | + S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | + S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) | + S_008F1C_TYPE(state->type); + desc[4] = 0; + desc[5] = S_008F24_BASE_ARRAY(state->first_layer); + desc[6] = 0; + desc[7] = 0; + + if (gfx_level == GFX9) { + desc[3] |= S_008F1C_SW_MODE(surf->u.gfx9.color.fmask_swizzle_mode); + desc[4] |= S_008F20_DEPTH(state->last_layer) | + S_008F20_PITCH(surf->u.gfx9.color.fmask_epitch); + desc[5] |= S_008F24_META_PIPE_ALIGNED(1) | + S_008F24_META_RB_ALIGNED(1); + + if (state->tc_compat_cmask) { + const uint64_t cmask_va = state->va + surf->cmask_offset; + + desc[5] |= S_008F24_META_DATA_ADDRESS(cmask_va >> 40); + desc[6] |= S_008F28_COMPRESSION_EN(1); + desc[7] |= cmask_va >> 8; + } + } else { + desc[3] |= S_008F1C_TILING_INDEX(surf->u.legacy.color.fmask.tiling_index); + desc[4] |= S_008F20_DEPTH(state->depth - 1) | + S_008F20_PITCH(surf->u.legacy.color.fmask.pitch_in_pixels - 1); + desc[5] |= S_008F24_LAST_ARRAY(state->last_layer); + + if (state->tc_compat_cmask) { + const uint64_t cmask_va = state->va + surf->cmask_offset; + + desc[6] |= S_008F28_COMPRESSION_EN(1); + desc[7] |= cmask_va >> 8; + } + } +} + +static void +ac_build_gfx10_fmask_descriptor(const enum amd_gfx_level gfx_level, const struct ac_fmask_state *state, uint32_t desc[8]) +{ + const struct radeon_surf *surf = state->surf; + const uint64_t va = state->va + surf->fmask_offset; + uint32_t format; + +#define FMASK(s, f) (((unsigned)(MAX2(1, s)) * 16) + (MAX2(1, f))) + switch (FMASK(state->num_samples, state->num_storage_samples)) { + case FMASK(2, 1): + format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F1; + break; + case FMASK(2, 2): + format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F2; + break; + case FMASK(4, 1): + format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F1; + break; + case FMASK(4, 2): + format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F2; + break; + case FMASK(4, 4): + format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F4; + break; + case FMASK(8, 1): + format = V_008F0C_GFX10_FORMAT_FMASK8_S8_F1; + break; + case FMASK(8, 2): + format = V_008F0C_GFX10_FORMAT_FMASK16_S8_F2; + break; + case FMASK(8, 4): + format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F4; + break; + case FMASK(8, 8): + format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F8; + break; + case FMASK(16, 1): + format = V_008F0C_GFX10_FORMAT_FMASK16_S16_F1; + break; + case FMASK(16, 2): + format = V_008F0C_GFX10_FORMAT_FMASK32_S16_F2; + break; + case FMASK(16, 4): + format = V_008F0C_GFX10_FORMAT_FMASK64_S16_F4; + break; + case FMASK(16, 8): + format = V_008F0C_GFX10_FORMAT_FMASK64_S16_F8; + break; + default: + unreachable("invalid nr_samples"); + } +#undef FMASK + + desc[0] = (va >> 8) | surf->fmask_tile_swizzle; + desc[1] = S_00A004_BASE_ADDRESS_HI(va >> 40) | + S_00A004_FORMAT_GFX10(format) | + S_00A004_WIDTH_LO(state->width - 1); + desc[2] = S_00A008_WIDTH_HI((state->width - 1) >> 2) | + S_00A008_HEIGHT(state->height - 1) | + S_00A008_RESOURCE_LEVEL(1); + desc[3] = S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) | + S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | + S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | + S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) | + S_00A00C_SW_MODE(surf->u.gfx9.color.fmask_swizzle_mode) | + S_00A00C_TYPE(state->type); + desc[4] = S_00A010_DEPTH_GFX10(state->last_layer) | S_00A010_BASE_ARRAY(state->first_layer); + desc[5] = 0; + desc[6] = S_00A018_META_PIPE_ALIGNED(1); + desc[7] = 0; + + if (state->tc_compat_cmask) { + uint64_t cmask_va = state->va + surf->cmask_offset; + + desc[6] |= S_00A018_COMPRESSION_EN(1); + desc[6] |= S_00A018_META_DATA_ADDRESS_LO(cmask_va >> 8); + desc[7] |= cmask_va >> 16; + } +} + +void +ac_build_fmask_descriptor(const enum amd_gfx_level gfx_level, const struct ac_fmask_state *state, uint32_t desc[8]) +{ + assert(gfx_level < GFX11); + + if (gfx_level >= GFX10) { + ac_build_gfx10_fmask_descriptor(gfx_level, state, desc); + } else { + ac_build_gfx6_fmask_descriptor(gfx_level, state, desc); + } +} diff --git a/src/amd/common/ac_descriptors.h b/src/amd/common/ac_descriptors.h index e3a88b92002..8ac534a70cf 100644 --- a/src/amd/common/ac_descriptors.h +++ b/src/amd/common/ac_descriptors.h @@ -40,6 +40,26 @@ ac_build_sampler_descriptor(const enum amd_gfx_level gfx_level, const struct ac_sampler_state *state, uint32_t desc[4]); +struct ac_fmask_state { + const struct radeon_surf *surf; + uint64_t va; + uint32_t width : 16; + uint32_t height : 16; + uint32_t depth : 14; + uint32_t type : 4; + uint32_t first_layer : 14; + uint32_t last_layer : 13; + + uint32_t num_samples : 5; + uint32_t num_storage_samples : 4; + uint32_t tc_compat_cmask : 1; +}; + +void +ac_build_fmask_descriptor(const enum amd_gfx_level gfx_level, + const struct ac_fmask_state *state, + uint32_t desc[8]); + #ifdef __cplusplus } #endif diff --git a/src/amd/vulkan/radv_image_view.c b/src/amd/vulkan/radv_image_view.c index 6f37b10dc15..7f363dacfee 100644 --- a/src/amd/vulkan/radv_image_view.c +++ b/src/amd/vulkan/radv_image_view.c @@ -16,6 +16,7 @@ #include "radv_formats.h" #include "radv_image.h" +#include "ac_descriptors.h" #include "gfx10_format_table.h" static unsigned @@ -344,49 +345,24 @@ gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *ima if (fmask_state) { if (radv_image_has_fmask(image)) { uint64_t gpu_address = radv_buffer_get_va(image->bindings[0].bo); - uint32_t format; - uint64_t va; assert(image->plane_count == 1); - va = gpu_address + image->bindings[0].offset + image->planes[0].surface.fmask_offset; + const struct ac_fmask_state ac_state = { + .surf = &image->planes[0].surface, + .va = gpu_address + image->bindings[0].offset, + .width = width, + .height = height, + .depth = depth, + .type = radv_tex_dim(image->vk.image_type, view_type, image->vk.array_layers, 0, false, false), + .first_layer = first_layer, + .last_layer = last_layer, + .num_samples = image->vk.samples, + .num_storage_samples = image->vk.samples, + .tc_compat_cmask = radv_image_is_tc_compat_cmask(image), + }; - switch (image->vk.samples) { - case 2: - format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F2; - break; - case 4: - format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F4; - break; - case 8: - format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F8; - break; - default: - unreachable("invalid nr_samples"); - } - - fmask_state[0] = (va >> 8) | image->planes[0].surface.fmask_tile_swizzle; - fmask_state[1] = - S_00A004_BASE_ADDRESS_HI(va >> 40) | S_00A004_FORMAT_GFX10(format) | S_00A004_WIDTH_LO(width - 1); - fmask_state[2] = - S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) | S_00A008_RESOURCE_LEVEL(1); - fmask_state[3] = - S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | - S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) | - S_00A00C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode) | - S_00A00C_TYPE(radv_tex_dim(image->vk.image_type, view_type, image->vk.array_layers, 0, false, false)); - fmask_state[4] = S_00A010_DEPTH_GFX10(last_layer) | S_00A010_BASE_ARRAY(first_layer); - fmask_state[5] = 0; - fmask_state[6] = S_00A018_META_PIPE_ALIGNED(1); - fmask_state[7] = 0; - - if (radv_image_is_tc_compat_cmask(image)) { - va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset; - - fmask_state[6] |= S_00A018_COMPRESSION_EN(1); - fmask_state[6] |= S_00A018_META_DATA_ADDRESS_LO(va >> 8); - fmask_state[7] |= va >> 16; - } + ac_build_fmask_descriptor(pdev->info.gfx_level, &ac_state, &fmask_state[0]); } else memset(fmask_state, 0, 8 * 4); } @@ -509,87 +485,25 @@ gfx6_make_texture_descriptor(struct radv_device *device, struct radv_image *imag /* Initialize the sampler view for FMASK. */ if (fmask_state) { if (radv_image_has_fmask(image)) { - uint32_t fmask_format; uint64_t gpu_address = radv_buffer_get_va(image->bindings[0].bo); - uint64_t va; assert(image->plane_count == 1); - va = gpu_address + image->bindings[0].offset + image->planes[0].surface.fmask_offset; + const struct ac_fmask_state ac_state = { + .surf = &image->planes[0].surface, + .va = gpu_address + image->bindings[0].offset, + .width = width, + .height = height, + .depth = depth, + .type = radv_tex_dim(image->vk.image_type, view_type, image->vk.array_layers, 0, false, false), + .first_layer = first_layer, + .last_layer = last_layer, + .num_samples = image->vk.samples, + .num_storage_samples = image->vk.samples, + .tc_compat_cmask = radv_image_is_tc_compat_cmask(image), + }; - if (pdev->info.gfx_level == GFX9) { - fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK; - switch (image->vk.samples) { - case 2: - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_2; - break; - case 4: - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_4; - break; - case 8: - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_8; - break; - default: - unreachable("invalid nr_samples"); - } - } else { - switch (image->vk.samples) { - case 2: - fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2; - break; - case 4: - fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4; - break; - case 8: - fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8; - break; - default: - assert(0); - fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID; - } - num_format = V_008F14_IMG_NUM_FORMAT_UINT; - } - - fmask_state[0] = va >> 8; - fmask_state[0] |= image->planes[0].surface.fmask_tile_swizzle; - fmask_state[1] = - S_008F14_BASE_ADDRESS_HI(va >> 40) | S_008F14_DATA_FORMAT(fmask_format) | S_008F14_NUM_FORMAT(num_format); - fmask_state[2] = S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1); - fmask_state[3] = - S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | - S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) | - S_008F1C_TYPE(radv_tex_dim(image->vk.image_type, view_type, image->vk.array_layers, 0, false, false)); - fmask_state[4] = 0; - fmask_state[5] = S_008F24_BASE_ARRAY(first_layer); - fmask_state[6] = 0; - fmask_state[7] = 0; - - if (pdev->info.gfx_level == GFX9) { - fmask_state[3] |= S_008F1C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode); - fmask_state[4] |= - S_008F20_DEPTH(last_layer) | S_008F20_PITCH(image->planes[0].surface.u.gfx9.color.fmask_epitch); - fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(1) | S_008F24_META_RB_ALIGNED(1); - - if (radv_image_is_tc_compat_cmask(image)) { - va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset; - - fmask_state[5] |= S_008F24_META_DATA_ADDRESS(va >> 40); - fmask_state[6] |= S_008F28_COMPRESSION_EN(1); - fmask_state[7] |= va >> 8; - } - } else { - fmask_state[3] |= S_008F1C_TILING_INDEX(image->planes[0].surface.u.legacy.color.fmask.tiling_index); - fmask_state[4] |= S_008F20_DEPTH(depth - 1) | - S_008F20_PITCH(image->planes[0].surface.u.legacy.color.fmask.pitch_in_pixels - 1); - fmask_state[5] |= S_008F24_LAST_ARRAY(last_layer); - - if (radv_image_is_tc_compat_cmask(image)) { - va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset; - - fmask_state[6] |= S_008F28_COMPRESSION_EN(1); - fmask_state[7] |= va >> 8; - } - } + ac_build_fmask_descriptor(pdev->info.gfx_level, &ac_state, &fmask_state[0]); } else memset(fmask_state, 0, 8 * 4); } diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index b3c91d6d58e..59597ce4cbc 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -4631,7 +4631,6 @@ static void gfx10_make_texture_descriptor( unsigned img_format; unsigned char swizzle[4]; unsigned type; - uint64_t va; desc = util_format_description(pipe_format); img_format = ac_get_gfx10_format_table(&screen->info)[pipe_format].img_format; @@ -4770,69 +4769,20 @@ static void gfx10_make_texture_descriptor( /* Initialize the sampler view for FMASK. */ if (tex->surface.fmask_offset) { - uint32_t format; + const struct ac_fmask_state ac_state = { + .surf = &tex->surface, + .va = tex->buffer.gpu_address, + .width = width, + .height = height, + .depth = depth, + .type = si_tex_dim(screen, tex, target, 0), + .first_layer = first_layer, + .last_layer = last_layer, + .num_samples = res->nr_samples, + .num_storage_samples = res->nr_storage_samples, + }; - va = tex->buffer.gpu_address + tex->surface.fmask_offset; - -#define FMASK(s, f) (((unsigned)(MAX2(1, s)) * 16) + (MAX2(1, f))) - switch (FMASK(res->nr_samples, res->nr_storage_samples)) { - case FMASK(2, 1): - format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F1; - break; - case FMASK(2, 2): - format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F2; - break; - case FMASK(4, 1): - format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F1; - break; - case FMASK(4, 2): - format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F2; - break; - case FMASK(4, 4): - format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F4; - break; - case FMASK(8, 1): - format = V_008F0C_GFX10_FORMAT_FMASK8_S8_F1; - break; - case FMASK(8, 2): - format = V_008F0C_GFX10_FORMAT_FMASK16_S8_F2; - break; - case FMASK(8, 4): - format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F4; - break; - case FMASK(8, 8): - format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F8; - break; - case FMASK(16, 1): - format = V_008F0C_GFX10_FORMAT_FMASK16_S16_F1; - break; - case FMASK(16, 2): - format = V_008F0C_GFX10_FORMAT_FMASK32_S16_F2; - break; - case FMASK(16, 4): - format = V_008F0C_GFX10_FORMAT_FMASK64_S16_F4; - break; - case FMASK(16, 8): - format = V_008F0C_GFX10_FORMAT_FMASK64_S16_F8; - break; - default: - unreachable("invalid nr_samples"); - } -#undef FMASK - fmask_state[0] = (va >> 8) | tex->surface.fmask_tile_swizzle; - fmask_state[1] = S_00A004_BASE_ADDRESS_HI(va >> 40) | S_00A004_FORMAT_GFX10(format) | - S_00A004_WIDTH_LO(width - 1); - fmask_state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) | - S_00A008_RESOURCE_LEVEL(1); - fmask_state[3] = - S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | - S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) | - S_00A00C_SW_MODE(tex->surface.u.gfx9.color.fmask_swizzle_mode) | - S_00A00C_TYPE(si_tex_dim(screen, tex, target, 0)); - fmask_state[4] = S_00A010_DEPTH_GFX10(last_layer) | S_00A010_BASE_ARRAY(first_layer); - fmask_state[5] = 0; - fmask_state[6] = S_00A018_META_PIPE_ALIGNED(1); - fmask_state[7] = 0; + ac_build_fmask_descriptor(screen->info.gfx_level, &ac_state, &fmask_state[0]); } } @@ -4860,7 +4810,6 @@ static void si_make_texture_descriptor(struct si_screen *screen, struct si_textu unsigned char swizzle[4]; int first_non_void; unsigned num_format, data_format, type, num_samples; - uint64_t va; desc = util_format_description(pipe_format); @@ -4983,129 +4932,20 @@ static void si_make_texture_descriptor(struct si_screen *screen, struct si_textu /* Initialize the sampler view for FMASK. */ if (tex->surface.fmask_offset) { - uint32_t data_format, num_format; + const struct ac_fmask_state ac_state = { + .surf = &tex->surface, + .va = tex->buffer.gpu_address, + .width = width, + .height = height, + .depth = depth, + .type = si_tex_dim(screen, tex, target, 0), + .first_layer = first_layer, + .last_layer = last_layer, + .num_samples = res->nr_samples, + .num_storage_samples = res->nr_storage_samples, + }; - va = tex->buffer.gpu_address + tex->surface.fmask_offset; - -#define FMASK(s, f) (((unsigned)(MAX2(1, s)) * 16) + (MAX2(1, f))) - if (screen->info.gfx_level == GFX9) { - data_format = V_008F14_IMG_DATA_FORMAT_FMASK; - switch (FMASK(res->nr_samples, res->nr_storage_samples)) { - case FMASK(2, 1): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_1; - break; - case FMASK(2, 2): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_2; - break; - case FMASK(4, 1): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_1; - break; - case FMASK(4, 2): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_2; - break; - case FMASK(4, 4): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_4; - break; - case FMASK(8, 1): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_8_1; - break; - case FMASK(8, 2): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_16_8_2; - break; - case FMASK(8, 4): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_4; - break; - case FMASK(8, 8): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_8; - break; - case FMASK(16, 1): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_16_16_1; - break; - case FMASK(16, 2): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_16_2; - break; - case FMASK(16, 4): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_64_16_4; - break; - case FMASK(16, 8): - num_format = V_008F14_IMG_NUM_FORMAT_FMASK_64_16_8; - break; - default: - unreachable("invalid nr_samples"); - } - } else { - switch (FMASK(res->nr_samples, res->nr_storage_samples)) { - case FMASK(2, 1): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F1; - break; - case FMASK(2, 2): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2; - break; - case FMASK(4, 1): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F1; - break; - case FMASK(4, 2): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F2; - break; - case FMASK(4, 4): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4; - break; - case FMASK(8, 1): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S8_F1; - break; - case FMASK(8, 2): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK16_S8_F2; - break; - case FMASK(8, 4): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F4; - break; - case FMASK(8, 8): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8; - break; - case FMASK(16, 1): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK16_S16_F1; - break; - case FMASK(16, 2): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S16_F2; - break; - case FMASK(16, 4): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK64_S16_F4; - break; - case FMASK(16, 8): - data_format = V_008F14_IMG_DATA_FORMAT_FMASK64_S16_F8; - break; - default: - unreachable("invalid nr_samples"); - } - num_format = V_008F14_IMG_NUM_FORMAT_UINT; - } -#undef FMASK - - fmask_state[0] = (va >> 8) | tex->surface.fmask_tile_swizzle; - fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | S_008F14_DATA_FORMAT(data_format) | - S_008F14_NUM_FORMAT(num_format); - fmask_state[2] = S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1); - fmask_state[3] = - S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | - S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) | - S_008F1C_TYPE(si_tex_dim(screen, tex, target, 0)); - fmask_state[4] = 0; - fmask_state[5] = S_008F24_BASE_ARRAY(first_layer); - fmask_state[6] = 0; - fmask_state[7] = 0; - - if (screen->info.gfx_level == GFX9) { - fmask_state[3] |= S_008F1C_SW_MODE(tex->surface.u.gfx9.color.fmask_swizzle_mode); - fmask_state[4] |= - S_008F20_DEPTH(last_layer) | S_008F20_PITCH(tex->surface.u.gfx9.color.fmask_epitch); - fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(1) | - S_008F24_META_RB_ALIGNED(1); - } else { - fmask_state[3] |= S_008F1C_TILING_INDEX(tex->surface.u.legacy.color.fmask.tiling_index); - fmask_state[4] |= S_008F20_DEPTH(depth - 1) | - S_008F20_PITCH(tex->surface.u.legacy.color.fmask.pitch_in_pixels - 1); - fmask_state[5] |= S_008F24_LAST_ARRAY(last_layer); - } + ac_build_fmask_descriptor(screen->info.gfx_level, &ac_state, &fmask_state[0]); } }