From: Bas Nieuwenhuizen Date: Mon, 16 Jul 2018 18:51:26 +0000 (+0200) Subject: radv: Add multiple planes to images. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=42d159f2766421b7a2858aa8de7762e8dfc9257f;p=mesa.git radv: Add multiple planes to images. No functional changes. This temporarily uses plane 0 for everything. Long term plan is that only single plane images get to use metadata like htile/dcc/cmask/fmask. Reviewed-by: Samuel Pitoiset --- diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 7ee5a5ca7dc..2fa55e6ab00 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -1070,7 +1070,7 @@ radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, radeon_emit(cmd_buffer->cs, S_028C98_BASE_256B(cb->cb_dcc_base >> 32)); radeon_set_context_reg(cmd_buffer->cs, R_0287A0_CB_MRT0_EPITCH + index * 4, - S_0287A0_EPITCH(att->attachment->image->surface.u.gfx9.surf.epitch)); + cb->cb_mrt_epitch); } else { 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); @@ -1585,12 +1585,13 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer) radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, att->attachment->bo); - assert(att->attachment->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT); + assert(att->attachment->aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_PLANE_0_BIT | + VK_IMAGE_ASPECT_PLANE_1_BIT | VK_IMAGE_ASPECT_PLANE_2_BIT)); radv_emit_fb_color_state(cmd_buffer, i, att, image, layout); radv_load_color_clear_metadata(cmd_buffer, image, i); - if (image->surface.bpe >= 8) + if (image->planes[0].surface.bpe >= 8) num_bpp64_colorbufs++; } @@ -4436,10 +4437,10 @@ static void radv_initialize_htile(struct radv_cmd_buffer *cmd_buffer, assert(range->baseMipLevel == 0); assert(range->levelCount == 1 || range->levelCount == VK_REMAINING_ARRAY_LAYERS); unsigned layer_count = radv_get_layerCount(image, range); - uint64_t size = image->surface.htile_slice_size * layer_count; + uint64_t size = image->planes[0].surface.htile_slice_size * layer_count; VkImageAspectFlags aspects = VK_IMAGE_ASPECT_DEPTH_BIT; uint64_t offset = image->offset + image->htile_offset + - image->surface.htile_slice_size * range->baseArrayLayer; + image->planes[0].surface.htile_slice_size * range->baseArrayLayer; struct radv_cmd_state *state = &cmd_buffer->state; VkClearDepthStencilValue value = {}; diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 5d5bfb1df24..caae5f1ad15 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -4142,12 +4142,12 @@ VkDeviceAddress radv_GetBufferDeviceAddressEXT( static inline unsigned -si_tile_mode_index(const struct radv_image *image, unsigned level, bool stencil) +si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil) { if (stencil) - return image->surface.u.legacy.stencil_tiling_index[level]; + return plane->surface.u.legacy.stencil_tiling_index[level]; else - return image->surface.u.legacy.tiling_index[level]; + return plane->surface.u.legacy.tiling_index[level]; } static uint32_t radv_surface_max_layer_count(struct radv_image_view *iview) @@ -4168,9 +4168,9 @@ radv_init_dcc_control_reg(struct radv_device *device, return 0; if (iview->image->info.samples > 1) { - if (iview->image->surface.bpe == 1) + if (iview->image->planes[0].surface.bpe == 1) max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B; - else if (iview->image->surface.bpe == 2) + else if (iview->image->planes[0].surface.bpe == 2) max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_128B; } @@ -4215,7 +4215,8 @@ radv_initialise_color_surface(struct radv_device *device, unsigned ntype, format, swap, endian; unsigned blend_clamp = 0, blend_bypass = 0; uint64_t va; - const struct radeon_surf *surf = &iview->image->surface; + const struct radv_image_plane *plane = &iview->image->planes[0]; + const struct radeon_surf *surf = &plane->surface; desc = vk_format_description(iview->vk_format); @@ -4224,35 +4225,37 @@ radv_initialise_color_surface(struct radv_device *device, /* Intensity is implemented as Red, so treat it that way. */ cb->cb_color_attrib = S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] == VK_SWIZZLE_1); - va = radv_buffer_get_va(iview->bo) + iview->image->offset; + va = radv_buffer_get_va(iview->bo) + iview->image->offset + plane->offset; cb->cb_color_base = va >> 8; if (device->physical_device->rad_info.chip_class >= GFX9) { struct gfx9_surf_meta_flags meta; if (iview->image->dcc_offset) - meta = iview->image->surface.u.gfx9.dcc; + meta = surf->u.gfx9.dcc; else - meta = iview->image->surface.u.gfx9.cmask; + meta = surf->u.gfx9.cmask; - cb->cb_color_attrib |= S_028C74_COLOR_SW_MODE(iview->image->surface.u.gfx9.surf.swizzle_mode) | - S_028C74_FMASK_SW_MODE(iview->image->surface.u.gfx9.fmask.swizzle_mode) | + cb->cb_color_attrib |= S_028C74_COLOR_SW_MODE(surf->u.gfx9.surf.swizzle_mode) | + S_028C74_FMASK_SW_MODE(surf->u.gfx9.fmask.swizzle_mode) | S_028C74_RB_ALIGNED(meta.rb_aligned) | S_028C74_PIPE_ALIGNED(meta.pipe_aligned); - cb->cb_color_base += iview->image->surface.u.gfx9.surf_offset >> 8; - cb->cb_color_base |= iview->image->surface.tile_swizzle; + cb->cb_color_base += surf->u.gfx9.surf_offset >> 8; + cb->cb_color_base |= surf->tile_swizzle; + + cb->cb_mrt_epitch = S_0287A0_EPITCH(surf->u.gfx9.surf.epitch); } else { const struct legacy_surf_level *level_info = &surf->u.legacy.level[iview->base_mip]; unsigned pitch_tile_max, slice_tile_max, tile_mode_index; cb->cb_color_base += level_info->offset >> 8; if (level_info->mode == RADEON_SURF_MODE_2D) - cb->cb_color_base |= iview->image->surface.tile_swizzle; + cb->cb_color_base |= surf->tile_swizzle; pitch_tile_max = level_info->nblk_x / 8 - 1; slice_tile_max = (level_info->nblk_x * level_info->nblk_y) / 64 - 1; - tile_mode_index = si_tile_mode_index(iview->image, iview->base_mip, false); + tile_mode_index = si_tile_mode_index(plane, iview->base_mip, false); cb->cb_color_pitch = S_028C64_TILE_MAX(pitch_tile_max); cb->cb_color_slice = S_028C68_TILE_MAX(slice_tile_max); @@ -4282,7 +4285,7 @@ radv_initialise_color_surface(struct radv_device *device, va = radv_buffer_get_va(iview->bo) + iview->image->offset; va += iview->image->dcc_offset; cb->cb_dcc_base = va >> 8; - cb->cb_dcc_base |= iview->image->surface.tile_swizzle; + cb->cb_dcc_base |= surf->tile_swizzle; uint32_t max_slice = radv_surface_max_layer_count(iview) - 1; cb->cb_color_view = S_028C6C_SLICE_START(iview->base_layer) | @@ -4365,7 +4368,7 @@ radv_initialise_color_surface(struct radv_device *device, /* This must be set for fast clear to work without FMASK. */ if (!radv_image_has_fmask(iview->image) && device->physical_device->rad_info.chip_class == SI) { - unsigned bankh = util_logbase2(iview->image->surface.u.legacy.bankh); + unsigned bankh = util_logbase2(surf->u.legacy.bankh); cb->cb_color_attrib |= S_028C74_FMASK_BANK_HEIGHT(bankh); } @@ -4375,7 +4378,7 @@ radv_initialise_color_surface(struct radv_device *device, cb->cb_color_view |= S_028C6C_MIP_LEVEL(iview->base_mip); cb->cb_color_attrib |= S_028C74_MIP0_DEPTH(mip0_depth) | - S_028C74_RESOURCE_TYPE(iview->image->surface.u.gfx9.resource_type); + S_028C74_RESOURCE_TYPE(surf->u.gfx9.resource_type); cb->cb_color_attrib2 = S_028C68_MIP0_WIDTH(iview->extent.width - 1) | S_028C68_MIP0_HEIGHT(iview->extent.height - 1) | S_028C68_MAX_MIP(iview->image->info.levels - 1); @@ -4430,6 +4433,11 @@ radv_initialise_ds_surface(struct radv_device *device, unsigned format, stencil_format; uint64_t va, s_offs, z_offs; bool stencil_only = false; + const struct radv_image_plane *plane = &iview->image->planes[0]; + const struct radeon_surf *surf = &plane->surface; + + assert(vk_format_get_plane_count(iview->image->vk_format) == 1); + memset(ds, 0, sizeof(*ds)); switch (iview->image->vk_format) { case VK_FORMAT_D24_UNORM_S8_UINT: @@ -4456,7 +4464,7 @@ radv_initialise_ds_surface(struct radv_device *device, } format = radv_translate_dbformat(iview->image->vk_format); - stencil_format = iview->image->surface.has_stencil ? + stencil_format = surf->has_stencil ? V_028044_STENCIL_8 : V_028044_STENCIL_INVALID; uint32_t max_slice = radv_surface_max_layer_count(iview) - 1; @@ -4470,19 +4478,19 @@ radv_initialise_ds_surface(struct radv_device *device, s_offs = z_offs = va; if (device->physical_device->rad_info.chip_class >= GFX9) { - assert(iview->image->surface.u.gfx9.surf_offset == 0); - s_offs += iview->image->surface.u.gfx9.stencil_offset; + assert(surf->u.gfx9.surf_offset == 0); + s_offs += surf->u.gfx9.stencil_offset; ds->db_z_info = S_028038_FORMAT(format) | S_028038_NUM_SAMPLES(util_logbase2(iview->image->info.samples)) | - S_028038_SW_MODE(iview->image->surface.u.gfx9.surf.swizzle_mode) | + S_028038_SW_MODE(surf->u.gfx9.surf.swizzle_mode) | S_028038_MAXMIP(iview->image->info.levels - 1) | S_028038_ZRANGE_PRECISION(1); ds->db_stencil_info = S_02803C_FORMAT(stencil_format) | - S_02803C_SW_MODE(iview->image->surface.u.gfx9.stencil.swizzle_mode); + S_02803C_SW_MODE(surf->u.gfx9.stencil.swizzle_mode); - ds->db_z_info2 = S_028068_EPITCH(iview->image->surface.u.gfx9.surf.epitch); - ds->db_stencil_info2 = S_02806C_EPITCH(iview->image->surface.u.gfx9.stencil.epitch); + ds->db_z_info2 = S_028068_EPITCH(surf->u.gfx9.surf.epitch); + ds->db_stencil_info2 = S_02806C_EPITCH(surf->u.gfx9.stencil.epitch); ds->db_depth_view |= S_028008_MIPID(level); ds->db_depth_size = S_02801C_X_MAX(iview->image->info.width - 1) | @@ -4500,24 +4508,24 @@ radv_initialise_ds_surface(struct radv_device *device, ds->db_stencil_info |= S_02803C_ITERATE_FLUSH(1); } - if (!iview->image->surface.has_stencil) + if (!surf->has_stencil) /* Use all of the htile_buffer for depth if there's no stencil. */ ds->db_stencil_info |= S_02803C_TILE_STENCIL_DISABLE(1); va = radv_buffer_get_va(iview->bo) + iview->image->offset + iview->image->htile_offset; ds->db_htile_data_base = va >> 8; ds->db_htile_surface = S_028ABC_FULL_CACHE(1) | - S_028ABC_PIPE_ALIGNED(iview->image->surface.u.gfx9.htile.pipe_aligned) | - S_028ABC_RB_ALIGNED(iview->image->surface.u.gfx9.htile.rb_aligned); + S_028ABC_PIPE_ALIGNED(surf->u.gfx9.htile.pipe_aligned) | + S_028ABC_RB_ALIGNED(surf->u.gfx9.htile.rb_aligned); } } else { - const struct legacy_surf_level *level_info = &iview->image->surface.u.legacy.level[level]; + const struct legacy_surf_level *level_info = &surf->u.legacy.level[level]; if (stencil_only) - level_info = &iview->image->surface.u.legacy.stencil_level[level]; + level_info = &surf->u.legacy.stencil_level[level]; - z_offs += iview->image->surface.u.legacy.level[level].offset; - s_offs += iview->image->surface.u.legacy.stencil_level[level].offset; + z_offs += surf->u.legacy.level[level].offset; + s_offs += surf->u.legacy.stencil_level[level].offset; ds->db_depth_info = S_02803C_ADDR5_SWIZZLE_MASK(!radv_image_is_tc_compat_htile(iview->image)); ds->db_z_info = S_028040_FORMAT(format) | S_028040_ZRANGE_PRECISION(1); @@ -4528,9 +4536,9 @@ radv_initialise_ds_surface(struct radv_device *device, if (device->physical_device->rad_info.chip_class >= CIK) { struct radeon_info *info = &device->physical_device->rad_info; - unsigned tiling_index = iview->image->surface.u.legacy.tiling_index[level]; - unsigned stencil_index = iview->image->surface.u.legacy.stencil_tiling_index[level]; - unsigned macro_index = iview->image->surface.u.legacy.macro_tile_index; + unsigned tiling_index = surf->u.legacy.tiling_index[level]; + unsigned stencil_index = surf->u.legacy.stencil_tiling_index[level]; + unsigned macro_index = surf->u.legacy.macro_tile_index; unsigned tile_mode = info->si_tile_mode_array[tiling_index]; unsigned stencil_tile_mode = info->si_tile_mode_array[stencil_index]; unsigned macro_mode = info->cik_macrotile_mode_array[macro_index]; @@ -4548,9 +4556,9 @@ radv_initialise_ds_surface(struct radv_device *device, ds->db_z_info |= S_028040_TILE_SPLIT(G_009910_TILE_SPLIT(tile_mode)); ds->db_stencil_info |= S_028044_TILE_SPLIT(G_009910_TILE_SPLIT(stencil_tile_mode)); } else { - unsigned tile_mode_index = si_tile_mode_index(iview->image, level, false); + unsigned tile_mode_index = si_tile_mode_index(&iview->image->planes[0], level, false); ds->db_z_info |= S_028040_TILE_MODE_INDEX(tile_mode_index); - tile_mode_index = si_tile_mode_index(iview->image, level, true); + tile_mode_index = si_tile_mode_index(&iview->image->planes[0], level, true); ds->db_stencil_info |= S_028044_TILE_MODE_INDEX(tile_mode_index); if (stencil_only) ds->db_z_info |= S_028040_TILE_MODE_INDEX(tile_mode_index); @@ -4563,7 +4571,7 @@ radv_initialise_ds_surface(struct radv_device *device, if (radv_htile_enabled(iview->image, level)) { ds->db_z_info |= S_028040_TILE_SURFACE_ENABLE(1); - if (!iview->image->surface.has_stencil && + if (!surf->has_stencil && !radv_image_is_tc_compat_htile(iview->image)) /* Use all of the htile_buffer for depth if there's no stencil. */ ds->db_stencil_info |= S_028044_TILE_STENCIL_DISABLE(1); @@ -4613,10 +4621,10 @@ VkResult radv_CreateFramebuffer( VkImageView _iview = pCreateInfo->pAttachments[i]; struct radv_image_view *iview = radv_image_view_from_handle(_iview); framebuffer->attachments[i].attachment = iview; - if (iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) { - radv_initialise_color_surface(device, &framebuffer->attachments[i].cb, iview); - } else if (iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { + if (iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { radv_initialise_ds_surface(device, &framebuffer->attachments[i].ds, iview); + } else { + radv_initialise_color_surface(device, &framebuffer->attachments[i].cb, iview); } framebuffer->width = MIN2(framebuffer->width, iview->extent.width); framebuffer->height = MIN2(framebuffer->height, iview->extent.height); diff --git a/src/amd/vulkan/radv_image.c b/src/amd/vulkan/radv_image.c index 6fea8f911d3..35fc19c55da 100644 --- a/src/amd/vulkan/radv_image.c +++ b/src/amd/vulkan/radv_image.c @@ -149,7 +149,8 @@ radv_use_dcc_for_image(struct radv_device *device, if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) return false; - if (vk_format_is_subsampled(pCreateInfo->format)) + if (vk_format_is_subsampled(pCreateInfo->format) || + vk_format_get_plane_count(pCreateInfo->format) > 1) return false; /* TODO: Enable DCC for mipmaps and array layers. */ @@ -202,21 +203,22 @@ static int radv_init_surface(struct radv_device *device, const struct radv_image *image, struct radeon_surf *surface, + unsigned plane_id, const struct radv_image_create_info *create_info) { const VkImageCreateInfo *pCreateInfo = create_info->vk_info; unsigned array_mode = radv_choose_tiling(device, create_info); - const struct vk_format_description *desc = - vk_format_description(pCreateInfo->format); + VkFormat format = vk_format_get_plane_format(pCreateInfo->format, plane_id); + const struct vk_format_description *desc = vk_format_description(format); bool is_depth, is_stencil; is_depth = vk_format_has_depth(desc); is_stencil = vk_format_has_stencil(desc); - surface->blk_w = vk_format_get_blockwidth(pCreateInfo->format); - surface->blk_h = vk_format_get_blockheight(pCreateInfo->format); + surface->blk_w = vk_format_get_blockwidth(format); + surface->blk_h = vk_format_get_blockheight(format); - surface->bpe = vk_format_get_blocksize(vk_format_depth_only(pCreateInfo->format)); + surface->bpe = vk_format_get_blocksize(vk_format_depth_only(format)); /* align byte per element on dword */ if (surface->bpe == 3) { surface->bpe = 4; @@ -274,12 +276,12 @@ static uint32_t si_get_bo_metadata_word1(struct radv_device *device) } static inline unsigned -si_tile_mode_index(const struct radv_image *image, unsigned level, bool stencil) +si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil) { if (stencil) - return image->surface.u.legacy.stencil_tiling_index[level]; + return plane->surface.u.legacy.stencil_tiling_index[level]; else - return image->surface.u.legacy.tiling_index[level]; + return plane->surface.u.legacy.tiling_index[level]; } static unsigned radv_map_swizzle(unsigned swizzle) @@ -347,22 +349,23 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, unsigned block_width, bool is_stencil, bool is_storage_image, uint32_t *state) { + struct radv_image_plane *plane = &image->planes[0]; uint64_t gpu_address = image->bo ? radv_buffer_get_va(image->bo) + image->offset : 0; - uint64_t va = gpu_address; + uint64_t va = gpu_address + plane->offset; enum chip_class chip_class = device->physical_device->rad_info.chip_class; uint64_t meta_va = 0; if (chip_class >= GFX9) { if (is_stencil) - va += image->surface.u.gfx9.stencil_offset; + va += plane->surface.u.gfx9.stencil_offset; else - va += image->surface.u.gfx9.surf_offset; + va += plane->surface.u.gfx9.surf_offset; } else va += base_level_info->offset; state[0] = va >> 8; if (chip_class >= GFX9 || base_level_info->mode == RADEON_SURF_MODE_2D) - state[0] |= image->surface.tile_swizzle; + state[0] |= plane->surface.tile_swizzle; state[1] &= C_008F14_BASE_ADDRESS_HI; state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40); @@ -381,7 +384,7 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, if (meta_va) { state[6] |= S_008F28_COMPRESSION_EN(1); state[7] = meta_va >> 8; - state[7] |= image->surface.tile_swizzle; + state[7] |= plane->surface.tile_swizzle; } } @@ -390,11 +393,11 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, state[4] &= C_008F20_PITCH_GFX9; if (is_stencil) { - state[3] |= S_008F1C_SW_MODE(image->surface.u.gfx9.stencil.swizzle_mode); - state[4] |= S_008F20_PITCH_GFX9(image->surface.u.gfx9.stencil.epitch); + state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.stencil.swizzle_mode); + state[4] |= S_008F20_PITCH_GFX9(plane->surface.u.gfx9.stencil.epitch); } else { - state[3] |= S_008F1C_SW_MODE(image->surface.u.gfx9.surf.swizzle_mode); - state[4] |= S_008F20_PITCH_GFX9(image->surface.u.gfx9.surf.epitch); + state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.surf.swizzle_mode); + state[4] |= S_008F20_PITCH_GFX9(plane->surface.u.gfx9.surf.epitch); } state[5] &= C_008F24_META_DATA_ADDRESS & @@ -404,9 +407,9 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, struct gfx9_surf_meta_flags meta; if (image->dcc_offset) - meta = image->surface.u.gfx9.dcc; + meta = plane->surface.u.gfx9.dcc; else - meta = image->surface.u.gfx9.htile; + meta = plane->surface.u.gfx9.htile; state[5] |= S_008F24_META_DATA_ADDRESS(meta_va >> 40) | S_008F24_META_PIPE_ALIGNED(meta.pipe_aligned) | @@ -415,7 +418,7 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, } else { /* SI-CI-VI */ unsigned pitch = base_level_info->nblk_x * block_width; - unsigned index = si_tile_mode_index(image, base_level, is_stencil); + unsigned index = si_tile_mode_index(plane, base_level, is_stencil); state[3] &= C_008F1C_TILING_INDEX; state[3] |= S_008F1C_TILING_INDEX(index); @@ -606,6 +609,8 @@ si_make_texture_descriptor(struct radv_device *device, uint64_t gpu_address = radv_buffer_get_va(image->bo); uint64_t va; + assert(image->plane_count == 1); + va = gpu_address + image->offset + image->fmask.offset; if (device->physical_device->rad_info.chip_class >= GFX9) { @@ -659,11 +664,11 @@ si_make_texture_descriptor(struct radv_device *device, fmask_state[7] = 0; if (device->physical_device->rad_info.chip_class >= GFX9) { - fmask_state[3] |= S_008F1C_SW_MODE(image->surface.u.gfx9.fmask.swizzle_mode); + fmask_state[3] |= S_008F1C_SW_MODE(image->planes[0].surface.u.gfx9.fmask.swizzle_mode); fmask_state[4] |= S_008F20_DEPTH(last_layer) | - S_008F20_PITCH_GFX9(image->surface.u.gfx9.fmask.epitch); - fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(image->surface.u.gfx9.cmask.pipe_aligned) | - S_008F24_META_RB_ALIGNED(image->surface.u.gfx9.cmask.rb_aligned); + S_008F20_PITCH_GFX9(image->planes[0].surface.u.gfx9.fmask.epitch); + fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(image->planes[0].surface.u.gfx9.cmask.pipe_aligned) | + S_008F24_META_RB_ALIGNED(image->planes[0].surface.u.gfx9.cmask.rb_aligned); } else { fmask_state[3] |= S_008F1C_TILING_INDEX(image->fmask.tile_mode_index); fmask_state[4] |= S_008F20_DEPTH(depth - 1) | @@ -682,6 +687,8 @@ radv_query_opaque_metadata(struct radv_device *device, static const VkComponentMapping fixedmapping; uint32_t desc[8], i; + assert(image->plane_count == 1); + /* Metadata image format format version 1: * [0] = 1 (metadata format identifier) * [1] = (VENDOR_ID << 16) | PCI_ID @@ -705,8 +712,8 @@ radv_query_opaque_metadata(struct radv_device *device, image->info.depth, desc, NULL); - si_set_mutable_tex_desc_fields(device, image, &image->surface.u.legacy.level[0], 0, 0, - image->surface.blk_w, false, false, desc); + si_set_mutable_tex_desc_fields(device, image, &image->planes[0].surface.u.legacy.level[0], 0, 0, + image->planes[0].surface.blk_w, false, false, desc); /* Clear the base address and set the relative DCC offset. */ desc[0] = 0; @@ -719,7 +726,7 @@ radv_query_opaque_metadata(struct radv_device *device, /* Dwords [10:..] contain the mipmap level offsets. */ if (device->physical_device->rad_info.chip_class <= VI) { for (i = 0; i <= image->info.levels - 1; i++) - md->metadata[10+i] = image->surface.u.legacy.level[i].offset >> 8; + md->metadata[10+i] = image->planes[0].surface.u.legacy.level[i].offset >> 8; md->size_metadata = (11 + image->info.levels - 1) * 4; } } @@ -729,7 +736,7 @@ radv_init_metadata(struct radv_device *device, struct radv_image *image, struct radeon_bo_metadata *metadata) { - struct radeon_surf *surface = &image->surface; + struct radeon_surf *surface = &image->planes[0].surface; memset(metadata, 0, sizeof(*metadata)); @@ -760,19 +767,19 @@ radv_image_get_fmask_info(struct radv_device *device, struct radv_fmask_info *out) { if (device->physical_device->rad_info.chip_class >= GFX9) { - out->alignment = image->surface.fmask_alignment; - out->size = image->surface.fmask_size; - out->tile_swizzle = image->surface.fmask_tile_swizzle; + out->alignment = image->planes[0].surface.fmask_alignment; + out->size = image->planes[0].surface.fmask_size; + out->tile_swizzle = image->planes[0].surface.fmask_tile_swizzle; return; } - out->slice_tile_max = image->surface.u.legacy.fmask.slice_tile_max; - out->tile_mode_index = image->surface.u.legacy.fmask.tiling_index; - out->pitch_in_pixels = image->surface.u.legacy.fmask.pitch_in_pixels; - out->bank_height = image->surface.u.legacy.fmask.bankh; - out->tile_swizzle = image->surface.fmask_tile_swizzle; - out->alignment = image->surface.fmask_alignment; - out->size = image->surface.fmask_size; + out->slice_tile_max = image->planes[0].surface.u.legacy.fmask.slice_tile_max; + out->tile_mode_index = image->planes[0].surface.u.legacy.fmask.tiling_index; + out->pitch_in_pixels = image->planes[0].surface.u.legacy.fmask.pitch_in_pixels; + out->bank_height = image->planes[0].surface.u.legacy.fmask.bankh; + out->tile_swizzle = image->planes[0].surface.fmask_tile_swizzle; + out->alignment = image->planes[0].surface.fmask_alignment; + out->size = image->planes[0].surface.fmask_size; assert(!out->tile_swizzle || !image->shareable); } @@ -797,9 +804,11 @@ radv_image_get_cmask_info(struct radv_device *device, unsigned num_pipes = device->physical_device->rad_info.num_tile_pipes; unsigned cl_width, cl_height; + assert(image->plane_count == 1); + if (device->physical_device->rad_info.chip_class >= GFX9) { - out->alignment = image->surface.cmask_alignment; - out->size = image->surface.cmask_size; + out->alignment = image->planes[0].surface.cmask_alignment; + out->size = image->planes[0].surface.cmask_size; return; } @@ -827,8 +836,8 @@ radv_image_get_cmask_info(struct radv_device *device, unsigned base_align = num_pipes * pipe_interleave_bytes; - unsigned width = align(image->surface.u.legacy.level[0].nblk_x, cl_width*8); - unsigned height = align(image->surface.u.legacy.level[0].nblk_y, cl_height*8); + unsigned width = align(image->planes[0].surface.u.legacy.level[0].nblk_x, cl_width*8); + unsigned height = align(image->planes[0].surface.u.legacy.level[0].nblk_y, cl_height*8); unsigned slice_elements = (width * height) / (8*8); /* Each element of CMASK is a nibble. */ @@ -863,22 +872,24 @@ radv_image_alloc_cmask(struct radv_device *device, static void radv_image_alloc_dcc(struct radv_image *image) { - image->dcc_offset = align64(image->size, image->surface.dcc_alignment); + assert(image->plane_count == 1); + + image->dcc_offset = align64(image->size, image->planes[0].surface.dcc_alignment); /* + 16 for storing the clear values + dcc pred */ - image->clear_value_offset = image->dcc_offset + image->surface.dcc_size; + image->clear_value_offset = image->dcc_offset + image->planes[0].surface.dcc_size; image->fce_pred_offset = image->clear_value_offset + 8; image->dcc_pred_offset = image->clear_value_offset + 16; - image->size = image->dcc_offset + image->surface.dcc_size + 24; - image->alignment = MAX2(image->alignment, image->surface.dcc_alignment); + image->size = image->dcc_offset + image->planes[0].surface.dcc_size + 24; + image->alignment = MAX2(image->alignment, image->planes[0].surface.dcc_alignment); } static void radv_image_alloc_htile(struct radv_image *image) { - image->htile_offset = align64(image->size, image->surface.htile_alignment); + image->htile_offset = align64(image->size, image->planes[0].surface.htile_alignment); /* + 8 for storing the clear values */ - image->clear_value_offset = image->htile_offset + image->surface.htile_size; + image->clear_value_offset = image->htile_offset + image->planes[0].surface.htile_size; image->size = image->clear_value_offset + 8; if (radv_image_is_tc_compat_htile(image)) { /* Metadata for the TC-compatible HTILE hardware bug which @@ -888,7 +899,7 @@ radv_image_alloc_htile(struct radv_image *image) image->tc_compat_zrange_offset = image->clear_value_offset + 8; image->size = image->clear_value_offset + 16; } - image->alignment = align64(image->alignment, image->surface.htile_alignment); + image->alignment = align64(image->alignment, image->planes[0].surface.htile_alignment); } static inline bool @@ -918,7 +929,7 @@ radv_image_can_enable_dcc(struct radv_image *image) static inline bool radv_image_can_enable_cmask(struct radv_image *image) { - if (image->surface.bpe > 8 && image->info.samples == 1) { + if (image->planes[0].surface.bpe > 8 && image->info.samples == 1) { /* Do not enable CMASK for non-MSAA images (fast color clear) * because 128 bit formats are not supported, but FMASK might * still be used. @@ -929,7 +940,7 @@ radv_image_can_enable_cmask(struct radv_image *image) return radv_image_can_enable_dcc_or_cmask(image) && image->info.levels == 1 && image->info.depth == 1 && - !image->surface.is_linear; + !image->planes[0].surface.is_linear; } static inline bool @@ -946,6 +957,18 @@ radv_image_can_enable_htile(struct radv_image *image) image->info.width * image->info.height >= 8 * 8; } +static void radv_image_disable_dcc(struct radv_image *image) +{ + for (unsigned i = 0; i < image->plane_count; ++i) + image->planes[i].surface.dcc_size = 0; +} + +static void radv_image_disable_htile(struct radv_image *image) +{ + for (unsigned i = 0; i < image->plane_count; ++i) + image->planes[i].surface.htile_size = 0; +} + VkResult radv_image_create(VkDevice _device, const struct radv_image_create_info *create_info, @@ -957,6 +980,9 @@ radv_image_create(VkDevice _device, struct radv_image *image = NULL; assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); + const unsigned plane_count = vk_format_get_plane_count(pCreateInfo->format); + const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count; + radv_assert(pCreateInfo->mipLevels > 0); radv_assert(pCreateInfo->arrayLayers > 0); radv_assert(pCreateInfo->samples > 0); @@ -964,7 +990,7 @@ radv_image_create(VkDevice _device, radv_assert(pCreateInfo->extent.height > 0); radv_assert(pCreateInfo->extent.depth > 0); - image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8, + image = vk_zalloc2(&device->alloc, alloc, image_struct_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (!image) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -999,12 +1025,30 @@ radv_image_create(VkDevice _device, image->info.surf_index = &device->image_mrt_offset_counter; } - radv_init_surface(device, image, &image->surface, create_info); + image->plane_count = plane_count; + image->size = 0; + image->alignment = 1; + for (unsigned plane = 0; plane < plane_count; ++plane) { + struct ac_surf_info info = image->info; + radv_init_surface(device, image, &image->planes[plane].surface, plane, create_info); + + if (plane) { + const struct vk_format_description *desc = vk_format_description(pCreateInfo->format); + assert(info.width % desc->width_divisor == 0); + assert(info.height % desc->height_divisor == 0); - device->ws->surface_init(device->ws, &image->info, &image->surface); + info.width /= desc->width_divisor; + info.height /= desc->height_divisor; + } + + device->ws->surface_init(device->ws, &info, &image->planes[plane].surface); - image->size = image->surface.surf_size; - image->alignment = image->surface.surf_alignment; + image->planes[plane].offset = align(image->size, image->planes[plane].surface.surf_alignment); + image->size = image->planes[plane].offset + image->planes[plane].surface.surf_size; + image->alignment = image->planes[plane].surface.surf_alignment; + + image->planes[plane].format = vk_format_get_plane_format(image->vk_format, plane); + } if (!create_info->no_metadata_planes) { /* Try to enable DCC first. */ @@ -1019,7 +1063,7 @@ radv_image_create(VkDevice _device, } } else { /* When DCC cannot be enabled, try CMASK. */ - image->surface.dcc_size = 0; + radv_image_disable_dcc(image); if (radv_image_can_enable_cmask(image)) { radv_image_alloc_cmask(device, image); } @@ -1032,15 +1076,15 @@ radv_image_create(VkDevice _device, /* Otherwise, try to enable HTILE for depth surfaces. */ if (radv_image_can_enable_htile(image) && !(device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) { - image->tc_compatible_htile = image->surface.flags & RADEON_SURF_TC_COMPATIBLE_HTILE; + image->tc_compatible_htile = image->planes[0].surface.flags & RADEON_SURF_TC_COMPATIBLE_HTILE; radv_image_alloc_htile(image); } else { - image->surface.htile_size = 0; + radv_image_disable_htile(image); } } } else { - image->surface.dcc_size = 0; - image->surface.htile_size = 0; + radv_image_disable_dcc(image); + radv_image_disable_htile(image); } if (pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { @@ -1065,9 +1109,11 @@ static void radv_image_view_make_descriptor(struct radv_image_view *iview, struct radv_device *device, const VkComponentMapping *components, - bool is_storage_image) + bool is_storage_image, unsigned plane_id) { struct radv_image *image = iview->image; + struct radv_image_plane *plane = &image->planes[plane_id]; + const struct vk_format_description *format_desc = vk_format_description(image->vk_format); bool is_stencil = iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT; uint32_t blk_w; uint32_t *descriptor; @@ -1079,8 +1125,8 @@ radv_image_view_make_descriptor(struct radv_image_view *iview, descriptor = iview->descriptor; } - assert(image->surface.blk_w % vk_format_get_blockwidth(image->vk_format) == 0); - blk_w = image->surface.blk_w / vk_format_get_blockwidth(image->vk_format) * vk_format_get_blockwidth(iview->vk_format); + assert(plane->surface.blk_w % vk_format_get_blockwidth(image->vk_format) == 0); + blk_w = plane->surface.blk_w / vk_format_get_blockwidth(image->vk_format) * vk_format_get_blockwidth(iview->vk_format); if (device->physical_device->rad_info.chip_class >= GFX9) hw_level = iview->base_mip; @@ -1091,8 +1137,8 @@ radv_image_view_make_descriptor(struct radv_image_view *iview, hw_level, hw_level + iview->level_count - 1, iview->base_layer, iview->base_layer + iview->layer_count - 1, - iview->extent.width, - iview->extent.height, + iview->extent.width / (plane_id ? format_desc->width_divisor : 1), + iview->extent.height / (plane_id ? format_desc->height_divisor : 1), iview->extent.depth, descriptor, descriptor + 8); @@ -1100,9 +1146,9 @@ radv_image_view_make_descriptor(struct radv_image_view *iview, const struct legacy_surf_level *base_level_info = NULL; if (device->physical_device->rad_info.chip_class <= GFX9) { if (is_stencil) - base_level_info = &image->surface.u.legacy.stencil_level[iview->base_mip]; + base_level_info = &plane->surface.u.legacy.stencil_level[iview->base_mip]; else - base_level_info = &image->surface.u.legacy.level[iview->base_mip]; + base_level_info = &plane->surface.u.legacy.level[iview->base_mip]; } si_set_mutable_tex_desc_fields(device, image, base_level_info, @@ -1202,8 +1248,8 @@ radv_image_view_init(struct radv_image_view *iview, lvl_width <<= range->baseMipLevel; lvl_height <<= range->baseMipLevel; - iview->extent.width = CLAMP(lvl_width, iview->extent.width, iview->image->surface.u.gfx9.surf_pitch); - iview->extent.height = CLAMP(lvl_height, iview->extent.height, iview->image->surface.u.gfx9.surf_height); + iview->extent.width = CLAMP(lvl_width, iview->extent.width, iview->image->planes[0].surface.u.gfx9.surf_pitch); + iview->extent.height = CLAMP(lvl_height, iview->extent.height, iview->image->planes[0].surface.u.gfx9.surf_height); } } @@ -1212,8 +1258,8 @@ radv_image_view_init(struct radv_image_view *iview, iview->base_mip = range->baseMipLevel; iview->level_count = radv_get_levelCount(image, range); - radv_image_view_make_descriptor(iview, device, &pCreateInfo->components, false); - radv_image_view_make_descriptor(iview, device, &pCreateInfo->components, true); + radv_image_view_make_descriptor(iview, device, &pCreateInfo->components, false, 0); + radv_image_view_make_descriptor(iview, device, &pCreateInfo->components, true, 0); } bool radv_layout_has_htile(const struct radv_image *image, @@ -1330,10 +1376,11 @@ void radv_GetImageSubresourceLayout( RADV_FROM_HANDLE(radv_device, device, _device); int level = pSubresource->mipLevel; int layer = pSubresource->arrayLayer; - struct radeon_surf *surface = &image->surface; + struct radv_image_plane *plane = &image->planes[0]; + struct radeon_surf *surface = &plane->surface; if (device->physical_device->rad_info.chip_class >= GFX9) { - pLayout->offset = surface->u.gfx9.offset[level] + surface->u.gfx9.surf_slice_size * layer; + pLayout->offset = plane->offset + surface->u.gfx9.offset[level] + surface->u.gfx9.surf_slice_size * layer; pLayout->rowPitch = surface->u.gfx9.surf_pitch * surface->bpe; pLayout->arrayPitch = surface->u.gfx9.surf_slice_size; pLayout->depthPitch = surface->u.gfx9.surf_slice_size; @@ -1341,7 +1388,7 @@ void radv_GetImageSubresourceLayout( if (image->type == VK_IMAGE_TYPE_3D) pLayout->size *= u_minify(image->info.depth, level); } else { - pLayout->offset = surface->u.legacy.level[level].offset + (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4 * layer; + pLayout->offset = plane->offset + surface->u.legacy.level[level].offset + (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4 * layer; pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe; pLayout->arrayPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4; pLayout->depthPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4; diff --git a/src/amd/vulkan/radv_meta_bufimage.c b/src/amd/vulkan/radv_meta_bufimage.c index a1b7bd1d6f8..4c8bfa0462b 100644 --- a/src/amd/vulkan/radv_meta_bufimage.c +++ b/src/amd/vulkan/radv_meta_bufimage.c @@ -1644,9 +1644,9 @@ get_image_stride_for_r32g32b32(struct radv_cmd_buffer *cmd_buffer, unsigned stride; if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) { - stride = surf->image->surface.u.gfx9.surf_pitch; + stride = surf->image->planes[0].surface.u.gfx9.surf_pitch; } else { - stride = surf->image->surface.u.legacy.level[0].nblk_x * 3; + stride = surf->image->planes[0].surface.u.legacy.level[0].nblk_x * 3; } return stride; diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c index 101ef4344f4..40ecfe001d1 100644 --- a/src/amd/vulkan/radv_meta_clear.c +++ b/src/amd/vulkan/radv_meta_clear.c @@ -869,7 +869,7 @@ radv_get_htile_fast_clear_value(const struct radv_image *image, { uint32_t clear_value; - if (!image->surface.has_stencil) { + if (!image->planes[0].surface.has_stencil) { clear_value = value.depth ? 0xfffffff0 : 0; } else { clear_value = value.depth ? 0xfffc0000 : 0; @@ -883,7 +883,7 @@ radv_get_htile_mask(const struct radv_image *image, VkImageAspectFlags aspects) { uint32_t mask = 0; - if (!image->surface.has_stencil) { + if (!image->planes[0].surface.has_stencil) { /* All the HTILE buffer is used when there is no stencil. */ mask = UINT32_MAX; } else { @@ -1034,13 +1034,13 @@ radv_fast_clear_depth(struct radv_cmd_buffer *cmd_buffer, /* Clear the whole HTILE buffer. */ flush_bits = radv_fill_buffer(cmd_buffer, iview->image->bo, iview->image->offset + iview->image->htile_offset, - iview->image->surface.htile_size, clear_word); + iview->image->planes[0].surface.htile_size, clear_word); } else { /* Only clear depth or stencil bytes in the HTILE buffer. */ assert(cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9); flush_bits = clear_htile_mask(cmd_buffer, iview->image->bo, iview->image->offset + iview->image->htile_offset, - iview->image->surface.htile_size, clear_word, + iview->image->planes[0].surface.htile_size, clear_word, htile_mask); } @@ -1341,7 +1341,7 @@ radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer, return radv_fill_buffer(cmd_buffer, image->bo, image->offset + image->dcc_offset, - image->surface.dcc_size, value); + image->planes[0].surface.dcc_size, value); } static void vi_get_fast_clear_parameters(VkFormat format, diff --git a/src/amd/vulkan/radv_meta_resolve.c b/src/amd/vulkan/radv_meta_resolve.c index fa441285371..ade5d438438 100644 --- a/src/amd/vulkan/radv_meta_resolve.c +++ b/src/amd/vulkan/radv_meta_resolve.c @@ -352,7 +352,8 @@ static void radv_pick_resolve_method_images(struct radv_image *src_image, 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) { + } else if (dest_image->planes[0].surface.micro_tile_mode != + src_image->planes[0].surface.micro_tile_mode) { *method = RESOLVE_COMPUTE; } } diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 248a5ec0ac7..f8f00e63af5 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1493,6 +1493,13 @@ struct radv_cmask_info { unsigned slice_tile_max; }; + +struct radv_image_plane { + VkFormat format; + struct radeon_surf surface; + uint64_t offset; +}; + struct radv_image { VkImageType type; /* The original VkFormat provided by the client. This may not match any @@ -1518,7 +1525,6 @@ struct radv_image { uint64_t dcc_offset; uint64_t htile_offset; bool tc_compatible_htile; - struct radeon_surf surface; struct radv_fmask_info fmask; struct radv_cmask_info cmask; @@ -1536,6 +1542,9 @@ struct radv_image { /* For VK_ANDROID_native_buffer, the WSI image owns the memory, */ VkDeviceMemory owned_memory; + + unsigned plane_count; + struct radv_image_plane planes[0]; }; /* Whether the image has a htile that is known consistent with the contents of @@ -1586,7 +1595,7 @@ radv_image_has_fmask(const struct radv_image *image) static inline bool radv_image_has_dcc(const struct radv_image *image) { - return image->surface.dcc_size; + return image->planes[0].surface.dcc_size; } /** @@ -1596,7 +1605,7 @@ static inline bool radv_dcc_enabled(const struct radv_image *image, unsigned level) { return radv_image_has_dcc(image) && - level < image->surface.num_dcc_levels; + level < image->planes[0].surface.num_dcc_levels; } /** @@ -1616,7 +1625,7 @@ radv_image_has_CB_metadata(const struct radv_image *image) static inline bool radv_image_has_htile(const struct radv_image *image) { - return image->surface.htile_size; + return image->planes[0].surface.htile_size; } /** @@ -1766,7 +1775,6 @@ struct radv_color_buffer_info { uint64_t cb_color_cmask; uint64_t cb_color_fmask; uint64_t cb_dcc_base; - uint32_t cb_color_pitch; uint32_t cb_color_slice; uint32_t cb_color_view; uint32_t cb_color_info; @@ -1775,6 +1783,10 @@ struct radv_color_buffer_info { uint32_t cb_dcc_control; uint32_t cb_color_cmask_slice; uint32_t cb_color_fmask_slice; + union { + uint32_t cb_color_pitch; // GFX6-GFX8 + uint32_t cb_mrt_epitch; // GFX9+ + }; }; struct radv_ds_buffer_info {