This is to rework the surface code like radeonsi.
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Dave Airlie <airlied@redhat.com>
if (dst_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL &&
(pending_clears & vk_format_aspects(image->vk_format)) == vk_format_aspects(image->vk_format) &&
cmd_buffer->state.render_area.offset.x == 0 && cmd_buffer->state.render_area.offset.y == 0 &&
- cmd_buffer->state.render_area.extent.width == image->extent.width &&
- cmd_buffer->state.render_area.extent.height == image->extent.height) {
+ cmd_buffer->state.render_area.extent.width == image->info.width &&
+ cmd_buffer->state.render_area.extent.height == image->info.height) {
/* The clear will initialize htile. */
return;
} else if (src_layout == VK_IMAGE_LAYOUT_UNDEFINED &&
cb->cb_color_attrib = S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] == VK_SWIZZLE_1) |
S_028C74_TILE_MODE_INDEX(tile_mode_index);
- if (iview->image->samples > 1) {
- unsigned log_samples = util_logbase2(iview->image->samples);
+ if (iview->image->info.samples > 1) {
+ unsigned log_samples = util_logbase2(iview->image->info.samples);
cb->cb_color_attrib |= S_028C74_NUM_SAMPLES(log_samples) |
S_028C74_NUM_FRAGMENTS(log_samples);
format != V_028C70_COLOR_24_8) |
S_028C70_NUMBER_TYPE(ntype) |
S_028C70_ENDIAN(endian);
- if (iview->image->samples > 1)
+ if (iview->image->info.samples > 1)
if (iview->image->fmask.size)
cb->cb_color_info |= S_028C70_COMPRESSION(1);
if (device->physical_device->rad_info.chip_class >= VI) {
unsigned max_uncompressed_block_size = 2;
- if (iview->image->samples > 1) {
+ if (iview->image->info.samples > 1) {
if (iview->image->surface.bpe == 1)
max_uncompressed_block_size = 0;
else if (iview->image->surface.bpe == 2)
ds->db_depth_info = S_02803C_ADDR5_SWIZZLE_MASK(1);
ds->db_z_info = S_028040_FORMAT(format) | S_028040_ZRANGE_PRECISION(1);
- if (iview->image->samples > 1)
- ds->db_z_info |= S_028040_NUM_SAMPLES(util_logbase2(iview->image->samples));
+ if (iview->image->info.samples > 1)
+ ds->db_z_info |= S_028040_NUM_SAMPLES(util_logbase2(iview->image->info.samples));
if (iview->image->surface.flags & RADEON_SURF_SBUFFER)
ds->db_stencil_info = S_028044_FORMAT(V_028044_STENCIL_8);
* Check piglit's arb_texture_multisample-stencil-clear
* test if you want to try changing this.
*/
- if (iview->image->samples <= 1)
+ if (iview->image->info.samples <= 1)
ds->db_stencil_info |= S_028044_ALLOW_EXPCLEAR(1);
} else
/* Use all of the htile_buffer for depth if there's no stencil. */
data_format = 0;
}
- type = radv_tex_dim(image->type, view_type, image->array_size, image->samples,
+ type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
height = 1;
- depth = image->array_size;
+ depth = image->info.array_size;
} else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY ||
type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
if (view_type != VK_IMAGE_VIEW_TYPE_3D)
- depth = image->array_size;
+ depth = image->info.array_size;
} else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
- depth = image->array_size / 6;
+ depth = image->info.array_size / 6;
state[0] = 0;
state[1] = (S_008F14_DATA_FORMAT_GFX6(data_format) |
S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
- S_008F1C_BASE_LEVEL(image->samples > 1 ?
+ S_008F1C_BASE_LEVEL(image->info.samples > 1 ?
0 : first_level) |
- S_008F1C_LAST_LEVEL(image->samples > 1 ?
- util_logbase2(image->samples) :
+ S_008F1C_LAST_LEVEL(image->info.samples > 1 ?
+ util_logbase2(image->info.samples) :
last_level) |
- S_008F1C_POW2_PAD(image->levels > 1) |
+ S_008F1C_POW2_PAD(image->info.levels > 1) |
S_008F1C_TYPE(type));
state[4] = S_008F20_DEPTH(depth - 1);
state[5] = (S_008F24_BASE_ARRAY(first_layer) |
/* The last dword is unused by hw. The shader uses it to clear
* bits in the first dword of sampler state.
*/
- if (device->physical_device->rad_info.chip_class <= CIK && image->samples <= 1) {
+ if (device->physical_device->rad_info.chip_class <= CIK && image->info.samples <= 1) {
if (first_level == last_level)
state[7] = C_008F30_MAX_ANISO_RATIO;
else
va = gpu_address + image->offset + image->fmask.offset;
- switch (image->samples) {
+ switch (image->info.samples) {
case 2:
fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
break;
si_make_texture_descriptor(device, image, true,
(VkImageViewType)image->type, image->vk_format,
- &fixedmapping, 0, image->levels - 1, 0,
- image->array_size,
- image->extent.width, image->extent.height,
- image->extent.depth,
+ &fixedmapping, 0, image->info.levels - 1, 0,
+ image->info.array_size,
+ image->info.width, image->info.height,
+ image->info.depth,
desc, NULL);
si_set_mutable_tex_desc_fields(device, image, &image->surface.level[0], 0, 0,
memcpy(&md->metadata[2], desc, sizeof(desc));
/* Dwords [10:..] contain the mipmap level offsets. */
- for (i = 0; i <= image->levels - 1; i++)
+ for (i = 0; i <= image->info.levels - 1; i++)
md->metadata[10+i] = image->surface.level[i].offset >> 8;
- md->size_metadata = (11 + image->levels - 1) * 4;
+ md->size_metadata = (11 + image->info.levels - 1) * 4;
}
void
radv_image_alloc_fmask(struct radv_device *device,
struct radv_image *image)
{
- radv_image_get_fmask_info(device, image, image->samples, &image->fmask);
+ radv_image_get_fmask_info(device, image, image->info.samples, &image->fmask);
image->fmask.offset = align64(image->size, image->fmask.alignment);
image->size = image->fmask.offset + image->fmask.size;
out->slice_tile_max -= 1;
out->alignment = MAX2(256, base_align);
- out->size = (image->type == VK_IMAGE_TYPE_3D ? image->extent.depth : image->array_size) *
+ out->size = (image->type == VK_IMAGE_TYPE_3D ? image->info.depth : image->info.array_size) *
align(slice_bytes, base_align);
}
radv_image_alloc_htile(struct radv_device *device,
struct radv_image *image)
{
- if ((device->debug_flags & RADV_DEBUG_NO_HIZ) || image->levels > 1) {
+ if ((device->debug_flags & RADV_DEBUG_NO_HIZ) || image->info.levels > 1) {
image->surface.htile_size = 0;
return;
}
memset(image, 0, sizeof(*image));
image->type = pCreateInfo->imageType;
- image->extent = pCreateInfo->extent;
+ image->info.width = pCreateInfo->extent.width;
+ image->info.height = pCreateInfo->extent.height;
+ image->info.depth = pCreateInfo->extent.depth;
+ image->info.samples = pCreateInfo->samples;
+ image->info.array_size = pCreateInfo->arrayLayers;
+ image->info.levels = pCreateInfo->mipLevels;
+
image->vk_format = pCreateInfo->format;
- image->levels = pCreateInfo->mipLevels;
- image->array_size = pCreateInfo->arrayLayers;
- image->samples = pCreateInfo->samples;
image->tiling = pCreateInfo->tiling;
image->usage = pCreateInfo->usage;
image->flags = pCreateInfo->flags;
if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
pCreateInfo->mipLevels == 1 &&
- !image->surface.dcc_size && image->extent.depth == 1 && can_cmask_dcc)
+ !image->surface.dcc_size && image->info.depth == 1 && can_cmask_dcc)
radv_image_alloc_cmask(device, image);
- if (image->samples > 1 && vk_format_is_color(pCreateInfo->format)) {
+ 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)) {
switch (image->type) {
case VK_IMAGE_TYPE_1D:
case VK_IMAGE_TYPE_2D:
- assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <= image->array_size);
+ assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <= image->info.array_size);
break;
case VK_IMAGE_TYPE_3D:
assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1
- <= radv_minify(image->extent.depth, range->baseMipLevel));
+ <= radv_minify(image->info.depth, range->baseMipLevel));
break;
default:
unreachable("bad VkImageType");
}
iview->extent = (VkExtent3D) {
- .width = radv_minify(image->extent.width , range->baseMipLevel),
- .height = radv_minify(image->extent.height, range->baseMipLevel),
- .depth = radv_minify(image->extent.depth , range->baseMipLevel),
+ .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),
float tex_coord[3];
} vb_data[3];
- assert(src_image->samples == dest_image->samples);
+ assert(src_image->info.samples == dest_image->info.samples);
unsigned vb_size = 3 * sizeof(*vb_data);
vb_data[0] = (struct blit_vb_data) {
.tex_coord = {
* vkCmdBlitImage must not be used for multisampled source or
* destination images. Use vkCmdResolveImage for this purpose.
*/
- assert(src_image->samples == 1);
- assert(dest_image->samples == 1);
+ assert(src_image->info.samples == 1);
+ assert(dest_image->info.samples == 1);
radv_meta_save_graphics_reset_vport_scissor(&saved_state, cmd_buffer);
VK_SHADER_STAGE_COMPUTE_BIT, 0, 16,
push_constants);
- radv_unaligned_dispatch(cmd_buffer, dst->image->extent.width, dst->image->extent.height, 1);
+ radv_unaligned_dispatch(cmd_buffer, dst->image->info.width, dst->image->info.height, 1);
}
const uint32_t subpass_att = clear_att->colorAttachment;
const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
- const uint32_t samples = iview->image->samples;
+ const uint32_t samples = iview->image->info.samples;
const uint32_t samples_log2 = ffs(samples) - 1;
unsigned fs_key = radv_format_meta_fs_key(iview->vk_format);
struct radv_pipeline *pipeline;
VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
VkImageAspectFlags aspects = clear_att->aspectMask;
const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
- const uint32_t samples = iview->image->samples;
+ const uint32_t samples = iview->image->info.samples;
const uint32_t samples_log2 = ffs(samples) - 1;
VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
uint32_t offset;
/* all layers are bound */
if (iview->base_layer > 0)
goto fail;
- if (iview->image->array_size != iview->layer_count)
+ if (iview->image->info.array_size != iview->layer_count)
goto fail;
- if (iview->image->levels > 1)
+ if (iview->image->info.levels > 1)
goto fail;
if (iview->image->surface.level[0].mode < RADEON_SURF_MODE_1D)
goto fail;
-
if (!radv_image_extent_compare(iview->image, &iview->extent))
goto fail;
if (clear_rect->rect.offset.x || clear_rect->rect.offset.y ||
- clear_rect->rect.extent.width != iview->image->extent.width ||
- clear_rect->rect.extent.height != iview->image->extent.height)
+ clear_rect->rect.extent.width != iview->image->info.width ||
+ clear_rect->rect.extent.height != iview->image->info.height)
goto fail;
if (clear_rect->baseArrayLayer != 0)
goto fail;
- if (clear_rect->layerCount != iview->image->array_size)
+ if (clear_rect->layerCount != iview->image->info.array_size)
goto fail;
/* DCC */
const VkImageSubresourceRange *range = &ranges[r];
for (uint32_t l = 0; l < radv_get_levelCount(image, range); ++l) {
const uint32_t layer_count = image->type == VK_IMAGE_TYPE_3D ?
- radv_minify(image->extent.depth, range->baseMipLevel + l) :
+ radv_minify(image->info.depth, range->baseMipLevel + l) :
radv_get_layerCount(image, range);
for (uint32_t s = 0; s < layer_count; ++s) {
/* The Vulkan 1.0 spec says "dstImage must have a sample count equal to
* VK_SAMPLE_COUNT_1_BIT."
*/
- assert(image->samples == 1);
+ assert(image->info.samples == 1);
if (cs)
radv_meta_begin_bufimage(cmd_buffer, &saved_state.compute);
* vkCmdCopyImage can be used to copy image data between multisample
* images, but both images must have the same number of samples.
*/
- assert(src_image->samples == dest_image->samples);
+ assert(src_image->info.samples == dest_image->info.samples);
if (cs)
radv_meta_begin_itoi(cmd_buffer, &saved_state.compute);
else
image_copy.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
image_copy.dstSubresource.layerCount = 1;
- image_copy.extent.width = image->extent.width;
- image_copy.extent.height = image->extent.height;
+ image_copy.extent.width = image->info.width;
+ image_copy.extent.height = image->info.height;
image_copy.extent.depth = 1;
meta_copy_image(cmd_buffer, image, linear_image,
struct radv_meta_saved_pass_state saved_pass_state;
VkDevice device_h = radv_device_to_handle(cmd_buffer->device);
VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
- uint32_t width = radv_minify(image->extent.width,
+ uint32_t width = radv_minify(image->info.width,
subresourceRange->baseMipLevel);
- uint32_t height = radv_minify(image->extent.height,
+ uint32_t height = radv_minify(image->info.height,
subresourceRange->baseMipLevel);
if (!image->surface.htile_size)
.pAttachments = (VkImageView[]) {
radv_image_view_to_handle(&iview)
},
- .width = image->extent.width,
- .height = image->extent.height,
+ .width = image->info.width,
+ .height = image->info.height,
.layers = 1
},
&cmd_buffer->pool->alloc,
0,
},
.extent = {
- image->extent.width,
- image->extent.height,
+ image->info.width,
+ image->info.height,
}
},
.clearValueCount = 0,
VK_SUBPASS_CONTENTS_INLINE);
emit_fast_clear_flush(cmd_buffer,
- &(VkExtent2D) { image->extent.width, image->extent.height },
+ &(VkExtent2D) { image->info.width, image->info.height },
image->fmask.size > 0);
radv_CmdEndRenderPass(cmd_buffer_h);
regions[0].dstOffset.z)
use_compute_resolve = true;
- if (regions[0].extent.width != src_image->extent.width ||
- regions[0].extent.height != src_image->extent.height ||
- regions[0].extent.depth != src_image->extent.depth)
+ if (regions[0].extent.width != src_image->info.width ||
+ regions[0].extent.height != src_image->info.height ||
+ regions[0].extent.depth != src_image->info.depth)
use_compute_resolve = true;
} else
use_compute_resolve = true;
radv_meta_save_graphics_reset_vport_scissor_novertex(&saved_state, cmd_buffer);
- assert(src_image->samples > 1);
- assert(dest_image->samples == 1);
+ assert(src_image->info.samples > 1);
+ assert(dest_image->info.samples == 1);
- if (src_image->samples >= 16) {
+ if (src_image->info.samples >= 16) {
/* See commit aa3f9aaf31e9056a255f9e0472ebdfdaa60abe54 for the
* glBlitFramebuffer workaround for samples >= 16.
*/
"samples >= 16");
}
- if (src_image->array_size > 1)
+ if (src_image->info.array_size > 1)
radv_finishme("vkCmdResolveImage: multisample array images");
if (dest_image->surface.dcc_size) {
radv_image_view_to_handle(&src_iview),
radv_image_view_to_handle(&dest_iview),
},
- .width = radv_minify(dest_image->extent.width,
+ .width = radv_minify(dest_image->info.width,
region->dstSubresource.mipLevel),
- .height = radv_minify(dest_image->extent.height,
+ .height = radv_minify(dest_image->info.height,
region->dstSubresource.mipLevel),
.layers = 1
},
{
struct radv_device *device = cmd_buffer->device;
struct radv_meta_saved_compute_state saved_state;
- const uint32_t samples = src_image->samples;
+ const uint32_t samples = src_image->info.samples;
const uint32_t samples_log2 = ffs(samples) - 1;
for (uint32_t r = 0; r < region_count; ++r) {
*/
VkFormat vk_format;
VkImageAspectFlags aspects;
- VkExtent3D extent;
- uint32_t levels;
- uint32_t array_size;
- uint32_t samples; /**< VkImageCreateInfo::samples */
+ struct radeon_surf_info info;
VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
VkImageTiling tiling; /** VkImageCreateInfo::tiling */
VkImageCreateFlags flags; /** VkImageCreateInfo::flags */
const VkImageSubresourceRange *range)
{
return range->layerCount == VK_REMAINING_ARRAY_LAYERS ?
- image->array_size - range->baseArrayLayer : range->layerCount;
+ image->info.array_size - range->baseArrayLayer : range->layerCount;
}
static inline uint32_t
const VkImageSubresourceRange *range)
{
return range->levelCount == VK_REMAINING_MIP_LEVELS ?
- image->levels - range->baseMipLevel : range->levelCount;
+ image->info.levels - range->baseMipLevel : range->levelCount;
}
struct radeon_bo_metadata;
radv_image_extent_compare(const struct radv_image *image,
const VkExtent3D *extent)
{
- if (memcmp(extent, &image->extent, sizeof(*extent)))
+ if (extent->width != image->info.width ||
+ extent->height != image->info.height ||
+ extent->depth != image->info.depth)
return false;
return true;
}
#define RADEON_SURF_SET(v, field) (((v) & RADEON_SURF_ ## field ## _MASK) << RADEON_SURF_ ## field ## _SHIFT)
#define RADEON_SURF_CLR(v, field) ((v) & ~(RADEON_SURF_ ## field ## _MASK << RADEON_SURF_ ## field ## _SHIFT))
+struct radeon_surf_info {
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+ uint32_t samples;
+ uint32_t array_size;
+ uint32_t levels;
+};
+
struct radeon_surf_level {
uint64_t offset;
uint64_t slice_size;