mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 10:18:05 +02:00
radv: add mipmap support for the clear depth/stencil values
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
parent
e36e260c42
commit
218ce34962
2 changed files with 59 additions and 27 deletions
|
|
@ -1575,34 +1575,50 @@ radv_update_bound_fast_clear_ds(struct radv_cmd_buffer *cmd_buffer,
|
||||||
static void
|
static void
|
||||||
radv_set_ds_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
|
radv_set_ds_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
|
||||||
struct radv_image *image,
|
struct radv_image *image,
|
||||||
|
const VkImageSubresourceRange *range,
|
||||||
VkClearDepthStencilValue ds_clear_value,
|
VkClearDepthStencilValue ds_clear_value,
|
||||||
VkImageAspectFlags aspects)
|
VkImageAspectFlags aspects)
|
||||||
{
|
{
|
||||||
struct radeon_cmdbuf *cs = cmd_buffer->cs;
|
struct radeon_cmdbuf *cs = cmd_buffer->cs;
|
||||||
uint64_t va = radv_buffer_get_va(image->bo);
|
uint64_t va = radv_get_ds_clear_value_va(image, range->baseMipLevel);
|
||||||
unsigned reg_offset = 0, reg_count = 0;
|
uint32_t level_count = radv_get_levelCount(image, range);
|
||||||
|
|
||||||
va += image->offset + image->clear_value_offset;
|
if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
|
||||||
|
VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||||
|
/* Use the fastest way when both aspects are used. */
|
||||||
|
radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 2 + 2 * level_count, cmd_buffer->state.predicating));
|
||||||
|
radeon_emit(cs, S_370_DST_SEL(V_370_MEM) |
|
||||||
|
S_370_WR_CONFIRM(1) |
|
||||||
|
S_370_ENGINE_SEL(V_370_PFP));
|
||||||
|
radeon_emit(cs, va);
|
||||||
|
radeon_emit(cs, va >> 32);
|
||||||
|
|
||||||
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
|
for (uint32_t l = 0; l < level_count; l++) {
|
||||||
++reg_count;
|
radeon_emit(cs, ds_clear_value.stencil);
|
||||||
|
radeon_emit(cs, fui(ds_clear_value.depth));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
++reg_offset;
|
/* Otherwise we need one WRITE_DATA packet per level. */
|
||||||
va += 4;
|
for (uint32_t l = 0; l < level_count; l++) {
|
||||||
}
|
uint64_t va = radv_get_ds_clear_value_va(image, range->baseMipLevel + l);
|
||||||
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
|
unsigned value;
|
||||||
++reg_count;
|
|
||||||
|
|
||||||
radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 2 + reg_count, cmd_buffer->state.predicating));
|
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
|
||||||
radeon_emit(cs, S_370_DST_SEL(V_370_MEM) |
|
value = fui(ds_clear_value.depth);
|
||||||
S_370_WR_CONFIRM(1) |
|
va += 4;
|
||||||
S_370_ENGINE_SEL(V_370_PFP));
|
} else {
|
||||||
radeon_emit(cs, va);
|
value = ds_clear_value.stencil;
|
||||||
radeon_emit(cs, va >> 32);
|
}
|
||||||
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT)
|
|
||||||
radeon_emit(cs, ds_clear_value.stencil);
|
radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 3, cmd_buffer->state.predicating));
|
||||||
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
|
radeon_emit(cs, S_370_DST_SEL(V_370_MEM) |
|
||||||
radeon_emit(cs, fui(ds_clear_value.depth));
|
S_370_WR_CONFIRM(1) |
|
||||||
|
S_370_ENGINE_SEL(V_370_PFP));
|
||||||
|
radeon_emit(cs, va);
|
||||||
|
radeon_emit(cs, va >> 32);
|
||||||
|
radeon_emit(cs, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1665,11 +1681,19 @@ radv_update_ds_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
|
||||||
VkClearDepthStencilValue ds_clear_value,
|
VkClearDepthStencilValue ds_clear_value,
|
||||||
VkImageAspectFlags aspects)
|
VkImageAspectFlags aspects)
|
||||||
{
|
{
|
||||||
|
VkImageSubresourceRange range = {
|
||||||
|
.aspectMask = iview->aspect_mask,
|
||||||
|
.baseMipLevel = iview->base_mip,
|
||||||
|
.levelCount = iview->level_count,
|
||||||
|
.baseArrayLayer = iview->base_layer,
|
||||||
|
.layerCount = iview->layer_count,
|
||||||
|
};
|
||||||
struct radv_image *image = iview->image;
|
struct radv_image *image = iview->image;
|
||||||
|
|
||||||
assert(radv_image_has_htile(image));
|
assert(radv_image_has_htile(image));
|
||||||
|
|
||||||
radv_set_ds_clear_metadata(cmd_buffer, image, ds_clear_value, aspects);
|
radv_set_ds_clear_metadata(cmd_buffer, iview->image, &range,
|
||||||
|
ds_clear_value, aspects);
|
||||||
|
|
||||||
if (radv_image_is_tc_compat_htile(image) &&
|
if (radv_image_is_tc_compat_htile(image) &&
|
||||||
(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {
|
(aspects & VK_IMAGE_ASPECT_DEPTH_BIT)) {
|
||||||
|
|
@ -1686,15 +1710,14 @@ radv_update_ds_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
radv_load_ds_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
|
radv_load_ds_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
|
||||||
struct radv_image *image)
|
const struct radv_image_view *iview)
|
||||||
{
|
{
|
||||||
struct radeon_cmdbuf *cs = cmd_buffer->cs;
|
struct radeon_cmdbuf *cs = cmd_buffer->cs;
|
||||||
|
const struct radv_image *image = iview->image;
|
||||||
VkImageAspectFlags aspects = vk_format_aspects(image->vk_format);
|
VkImageAspectFlags aspects = vk_format_aspects(image->vk_format);
|
||||||
uint64_t va = radv_buffer_get_va(image->bo);
|
uint64_t va = radv_get_ds_clear_value_va(image, iview->base_mip);
|
||||||
unsigned reg_offset = 0, reg_count = 0;
|
unsigned reg_offset = 0, reg_count = 0;
|
||||||
|
|
||||||
va += image->offset + image->clear_value_offset;
|
|
||||||
|
|
||||||
if (!radv_image_has_htile(image))
|
if (!radv_image_has_htile(image))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1966,7 +1989,7 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer)
|
||||||
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
|
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
|
||||||
cmd_buffer->state.offset_scale = cmd_buffer->state.attachments[idx].ds.offset_scale;
|
cmd_buffer->state.offset_scale = cmd_buffer->state.attachments[idx].ds.offset_scale;
|
||||||
}
|
}
|
||||||
radv_load_ds_clear_metadata(cmd_buffer, image);
|
radv_load_ds_clear_metadata(cmd_buffer, iview);
|
||||||
} else {
|
} else {
|
||||||
if (cmd_buffer->device->physical_device->rad_info.chip_class == GFX9)
|
if (cmd_buffer->device->physical_device->rad_info.chip_class == GFX9)
|
||||||
radeon_set_context_reg_seq(cmd_buffer->cs, R_028038_DB_Z_INFO, 2);
|
radeon_set_context_reg_seq(cmd_buffer->cs, R_028038_DB_Z_INFO, 2);
|
||||||
|
|
@ -5081,7 +5104,7 @@ static void radv_initialize_htile(struct radv_cmd_buffer *cmd_buffer,
|
||||||
if (vk_format_is_stencil(image->vk_format))
|
if (vk_format_is_stencil(image->vk_format))
|
||||||
aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||||
|
|
||||||
radv_set_ds_clear_metadata(cmd_buffer, image, value, aspects);
|
radv_set_ds_clear_metadata(cmd_buffer, image, range, value, aspects);
|
||||||
|
|
||||||
if (radv_image_is_tc_compat_htile(image)) {
|
if (radv_image_is_tc_compat_htile(image)) {
|
||||||
/* Initialize the TC-compat metada value to 0 because by
|
/* Initialize the TC-compat metada value to 0 because by
|
||||||
|
|
|
||||||
|
|
@ -1814,6 +1814,15 @@ radv_get_tc_compat_zrange_va(const struct radv_image *image,
|
||||||
return va;
|
return va;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint64_t
|
||||||
|
radv_get_ds_clear_value_va(const struct radv_image *image,
|
||||||
|
uint32_t base_level)
|
||||||
|
{
|
||||||
|
uint64_t va = radv_buffer_get_va(image->bo);
|
||||||
|
va += image->offset + image->clear_value_offset + base_level * 8;
|
||||||
|
return va;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned radv_image_queue_family_mask(const struct radv_image *image, uint32_t family, uint32_t queue_family);
|
unsigned radv_image_queue_family_mask(const struct radv_image *image, uint32_t family, uint32_t queue_family);
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue