* IN THE SOFTWARE.
*/
+#include "radv_debug.h"
#include "radv_private.h"
#include "vk_format.h"
#include "vk_util.h"
#include "util/debug.h"
#include "util/u_atomic.h"
static unsigned
-radv_choose_tiling(struct radv_device *Device,
+radv_choose_tiling(struct radv_device *device,
const struct radv_image_create_info *create_info)
{
const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
return RADEON_SURF_MODE_LINEAR_ALIGNED;
}
- /* Textures with a very small height are recommended to be linear. */
- if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D ||
- /* Only very thin and long 2D textures should benefit from
- * linear_aligned. */
- (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2))
- return RADEON_SURF_MODE_LINEAR_ALIGNED;
+ if (!vk_format_is_compressed(pCreateInfo->format) &&
+ !vk_format_is_depth_or_stencil(pCreateInfo->format)
+ && device->physical_device->rad_info.chip_class <= VI) {
+ /* this causes hangs in some VK CTS tests on GFX9. */
+ /* Textures with a very small height are recommended to be linear. */
+ if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D ||
+ /* Only very thin and long 2D textures should benefit from
+ * linear_aligned. */
+ (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2))
+ return RADEON_SURF_MODE_LINEAR_ALIGNED;
+ }
/* MSAA resources must be 2D tiled. */
if (pCreateInfo->samples > 1)
surface->flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
+ bool dcc_compatible_formats = !radv_is_colorbuffer_format_supported(pCreateInfo->format, &blendable);
+ if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
+ const struct VkImageFormatListCreateInfoKHR *format_list =
+ (const struct VkImageFormatListCreateInfoKHR *)
+ vk_find_struct_const(pCreateInfo->pNext,
+ IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
+ if (format_list) {
+ /* compatibility is transitive, so we only need to check
+ * one format with everything else. */
+ for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
+ if (!radv_dcc_formats_compatible(pCreateInfo->format,
+ format_list->pViewFormats[i]))
+ dcc_compatible_formats = false;
+ }
+ } else {
+ dcc_compatible_formats = false;
+ }
+ }
+
if ((pCreateInfo->usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_STORAGE_BIT)) ||
- (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) ||
+ !dcc_compatible_formats ||
(pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) ||
+ pCreateInfo->mipLevels > 1 || pCreateInfo->arrayLayers > 1 ||
device->physical_device->rad_info.chip_class < VI ||
- create_info->scanout || (device->debug_flags & RADV_DEBUG_NO_DCC) ||
- !radv_is_colorbuffer_format_supported(pCreateInfo->format, &blendable))
+ create_info->scanout || (device->debug_flags & RADV_DEBUG_NO_DCC))
surface->flags |= RADEON_SURF_DISABLE_DCC;
if (create_info->scanout)
surface->flags |= RADEON_SURF_SCANOUT;
state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
S_008F04_STRIDE(stride);
- if (device->physical_device->rad_info.chip_class < VI && stride) {
+ if (device->physical_device->rad_info.chip_class != VI && stride) {
range /= stride;
}
{
uint64_t gpu_address = image->bo ? device->ws->buffer_get_va(image->bo) + image->offset : 0;
uint64_t va = gpu_address;
- unsigned pitch = base_level_info->nblk_x * block_width;
enum chip_class chip_class = device->physical_device->rad_info.chip_class;
uint64_t meta_va = 0;
if (chip_class >= GFX9) {
va += base_level_info->offset;
state[0] = va >> 8;
- if (chip_class < GFX9)
+ if (chip_class >= GFX9 ||
+ base_level_info->mode == RADEON_SURF_MODE_2D)
state[0] |= image->surface.tile_swizzle;
state[1] &= C_008F14_BASE_ADDRESS_HI;
state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
- state[3] |= S_008F1C_TILING_INDEX(si_tile_mode_index(image, base_level,
- is_stencil));
- state[4] |= S_008F20_PITCH_GFX6(pitch - 1);
if (chip_class >= VI) {
state[6] &= C_008F28_COMPRESSION_EN;
meta_va += base_level_info->dcc_offset;
state[6] |= S_008F28_COMPRESSION_EN(1);
state[7] = meta_va >> 8;
- if (chip_class < GFX9)
- state[7] |= image->surface.tile_swizzle;
+ state[7] |= image->surface.tile_swizzle;
}
}
}
static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type,
- unsigned nr_layers, unsigned nr_samples, bool is_storage_image)
+ unsigned nr_layers, unsigned nr_samples, bool is_storage_image, bool gfx9)
{
if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE;
+
+ /* GFX9 allocates 1D textures as 2D. */
+ if (gfx9 && image_type == VK_IMAGE_TYPE_1D)
+ image_type = VK_IMAGE_TYPE_2D;
switch (image_type) {
case VK_IMAGE_TYPE_1D:
return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D;
}
type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
- is_storage_image);
+ is_storage_image, device->physical_device->rad_info.chip_class >= GFX9);
if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
height = 1;
depth = image->info.array_size;
state[4] |= S_008F20_BC_SWIZZLE(bc_swizzle);
state[5] |= S_008F24_MAX_MIP(image->info.samples > 1 ?
util_logbase2(image->info.samples) :
- last_level);
+ image->info.levels - 1);
} else {
state[3] |= S_008F1C_POW2_PAD(image->info.levels > 1);
state[4] |= S_008F20_DEPTH(depth - 1);
}
fmask_state[0] = va >> 8;
- if (device->physical_device->rad_info.chip_class < GFX9)
- fmask_state[0] |= image->surface.tile_swizzle;
+ fmask_state[0] |= image->fmask.tile_swizzle;
fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |
S_008F14_DATA_FORMAT_GFX6(fmask_format) |
S_008F14_NUM_FORMAT_GFX6(num_format);
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->type, view_type, 1, 0, false));
+ S_008F1C_TYPE(radv_tex_dim(image->type, view_type, 1, 0, false, false));
fmask_state[4] = 0;
fmask_state[5] = S_008F24_BASE_ARRAY(first_layer);
fmask_state[6] = 0;
memcpy(&md->metadata[2], desc, sizeof(desc));
/* Dwords [10:..] contain the mipmap level offsets. */
- for (i = 0; i <= image->info.levels - 1; i++)
- md->metadata[10+i] = image->surface.u.legacy.level[i].offset >> 8;
-
- md->size_metadata = (11 + image->info.levels - 1) * 4;
+ 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->size_metadata = (11 + image->info.levels - 1) * 4;
+ }
}
void
info.samples = 1;
fmask.flags = image->surface.flags | RADEON_SURF_FMASK;
+ if (!image->shareable)
+ info.surf_index = &device->fmask_mrt_offset_counter;
+
/* Force 2D tiling if it wasn't set. This may occur when creating
* FMASK for MSAA resolve on R6xx. On R6xx, the single-sample
* destination buffer must have an FMASK too. */
out->tile_mode_index = fmask.u.legacy.tiling_index[0];
out->pitch_in_pixels = fmask.u.legacy.level[0].nblk_x;
out->bank_height = fmask.u.legacy.bankh;
+ out->tile_swizzle = fmask.tile_swizzle;
out->alignment = MAX2(256, fmask.surf_alignment);
out->size = fmask.surf_size;
+
+ assert(!out->tile_swizzle || !image->shareable);
}
static void
if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
pCreateInfo->mipLevels == 1 &&
- !image->surface.dcc_size && image->info.depth == 1 && can_cmask_dcc)
+ !image->surface.dcc_size && image->info.depth == 1 && can_cmask_dcc &&
+ !image->surface.is_linear)
radv_image_alloc_cmask(device, image);
+
if (image->info.samples > 1 && vk_format_is_color(pCreateInfo->format)) {
radv_image_alloc_fmask(device, image);
} else if (vk_format_is_depth(pCreateInfo->format)) {
static void
radv_image_view_make_descriptor(struct radv_image_view *iview,
struct radv_device *device,
- const VkImageViewCreateInfo* pCreateInfo,
+ const VkComponentMapping *components,
bool is_storage_image)
{
- RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
- const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+ struct radv_image *image = iview->image;
bool is_stencil = iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT;
uint32_t blk_w;
uint32_t *descriptor;
uint32_t *fmask_descriptor;
+ uint32_t hw_level = 0;
if (is_storage_image) {
descriptor = iview->storage_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);
+ if (device->physical_device->rad_info.chip_class >= GFX9)
+ hw_level = iview->base_mip;
si_make_texture_descriptor(device, image, is_storage_image,
iview->type,
iview->vk_format,
- &pCreateInfo->components,
- 0, radv_get_levelCount(image, range) - 1,
- range->baseArrayLayer,
- range->baseArrayLayer + radv_get_layerCount(image, range) - 1,
+ components,
+ 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.depth,
descriptor,
fmask_descriptor);
+
+ 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];
+ else
+ base_level_info = &image->surface.u.legacy.level[iview->base_mip];
+ }
si_set_mutable_tex_desc_fields(device, image,
- is_stencil ? &image->surface.u.legacy.stencil_level[range->baseMipLevel]
- : &image->surface.u.legacy.level[range->baseMipLevel],
- range->baseMipLevel,
- range->baseMipLevel,
+ base_level_info,
+ iview->base_mip,
+ iview->base_mip,
blk_w, is_stencil, descriptor);
}
iview->vk_format = vk_format_depth_only(iview->vk_format);
}
- iview->extent = (VkExtent3D) {
- .width = radv_minify(image->info.width , range->baseMipLevel),
- .height = radv_minify(image->info.height, range->baseMipLevel),
- .depth = radv_minify(image->info.depth , range->baseMipLevel),
- };
+ if (device->physical_device->rad_info.chip_class >= GFX9) {
+ iview->extent = (VkExtent3D) {
+ .width = image->info.width,
+ .height = image->info.height,
+ .depth = image->info.depth,
+ };
+ } else {
+ iview->extent = (VkExtent3D) {
+ .width = radv_minify(image->info.width , range->baseMipLevel),
+ .height = radv_minify(image->info.height, range->baseMipLevel),
+ .depth = radv_minify(image->info.depth , range->baseMipLevel),
+ };
+ }
- iview->extent.width = round_up_u32(iview->extent.width * vk_format_get_blockwidth(iview->vk_format),
- vk_format_get_blockwidth(image->vk_format));
- iview->extent.height = round_up_u32(iview->extent.height * vk_format_get_blockheight(iview->vk_format),
- vk_format_get_blockheight(image->vk_format));
+ if (iview->vk_format != image->vk_format) {
+ iview->extent.width = round_up_u32(iview->extent.width * vk_format_get_blockwidth(iview->vk_format),
+ vk_format_get_blockwidth(image->vk_format));
+ iview->extent.height = round_up_u32(iview->extent.height * vk_format_get_blockheight(iview->vk_format),
+ vk_format_get_blockheight(image->vk_format));
+ }
iview->base_layer = range->baseArrayLayer;
iview->layer_count = radv_get_layerCount(image, range);
iview->base_mip = range->baseMipLevel;
+ iview->level_count = radv_get_levelCount(image, range);
- radv_image_view_make_descriptor(iview, device, pCreateInfo, false);
- radv_image_view_make_descriptor(iview, device, pCreateInfo, true);
+ radv_image_view_make_descriptor(iview, device, &pCreateInfo->components, false);
+ radv_image_view_make_descriptor(iview, device, &pCreateInfo->components, true);
}
bool radv_layout_has_htile(const struct radv_image *image,
}
void radv_GetImageSubresourceLayout(
- VkDevice device,
+ VkDevice _device,
VkImage _image,
const VkImageSubresource* pSubresource,
VkSubresourceLayout* pLayout)
{
RADV_FROM_HANDLE(radv_image, image, _image);
+ RADV_FROM_HANDLE(radv_device, device, _device);
int level = pSubresource->mipLevel;
int layer = pSubresource->arrayLayer;
struct radeon_surf *surface = &image->surface;
- pLayout->offset = surface->u.legacy.level[level].offset + surface->u.legacy.level[level].slice_size * layer;
- pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe;
- pLayout->arrayPitch = surface->u.legacy.level[level].slice_size;
- pLayout->depthPitch = surface->u.legacy.level[level].slice_size;
- pLayout->size = surface->u.legacy.level[level].slice_size;
- if (image->type == VK_IMAGE_TYPE_3D)
- pLayout->size *= u_minify(image->info.depth, level);
+ if (device->physical_device->rad_info.chip_class >= GFX9) {
+ pLayout->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;
+ pLayout->size = surface->u.gfx9.surf_slice_size;
+ if (image->type == VK_IMAGE_TYPE_3D)
+ pLayout->size *= u_minify(image->info.depth, level);
+ } else {
+ pLayout->offset = surface->u.legacy.level[level].offset + surface->u.legacy.level[level].slice_size * layer;
+ pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe;
+ pLayout->arrayPitch = surface->u.legacy.level[level].slice_size;
+ pLayout->depthPitch = surface->u.legacy.level[level].slice_size;
+ pLayout->size = surface->u.legacy.level[level].slice_size;
+ if (image->type == VK_IMAGE_TYPE_3D)
+ pLayout->size *= u_minify(image->info.depth, level);
+ }
}
void radv_buffer_view_init(struct radv_buffer_view *view,
struct radv_device *device,
- const VkBufferViewCreateInfo* pCreateInfo,
- struct radv_cmd_buffer *cmd_buffer)
+ const VkBufferViewCreateInfo* pCreateInfo)
{
RADV_FROM_HANDLE(radv_buffer, buffer, pCreateInfo->buffer);
if (!view)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- radv_buffer_view_init(view, device, pCreateInfo, NULL);
+ radv_buffer_view_init(view, device, pCreateInfo);
*pView = radv_buffer_view_to_handle(view);