radv: store the list of attachments for every subpass

This reworks how the depth stencil attachment is used for
simplicity. This also introduces radv_render_pass_compile()
helper that will be used for further optimizations.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
Samuel Pitoiset
2019-01-29 22:18:51 +01:00
parent a7c7d811f1
commit a20c2e38d8
7 changed files with 95 additions and 54 deletions

View File

@@ -1205,10 +1205,10 @@ radv_update_bound_fast_clear_ds(struct radv_cmd_buffer *cmd_buffer,
if (!framebuffer || !subpass)
return;
att_idx = subpass->depth_stencil_attachment.attachment;
if (att_idx == VK_ATTACHMENT_UNUSED)
if (!subpass->depth_stencil_attachment)
return;
att_idx = subpass->depth_stencil_attachment->attachment;
att = &framebuffer->attachments[att_idx];
if (att->attachment->image != image)
return;
@@ -1222,7 +1222,7 @@ radv_update_bound_fast_clear_ds(struct radv_cmd_buffer *cmd_buffer,
*/
if ((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
ds_clear_value.depth == 0.0) {
VkImageLayout layout = subpass->depth_stencil_attachment.layout;
VkImageLayout layout = subpass->depth_stencil_attachment->layout;
radv_update_zrange_precision(cmd_buffer, &att->ds, image,
layout, false);
@@ -1575,9 +1575,9 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer)
num_bpp64_colorbufs++;
}
if(subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
int idx = subpass->depth_stencil_attachment.attachment;
VkImageLayout layout = subpass->depth_stencil_attachment.layout;
if (subpass->depth_stencil_attachment) {
int idx = subpass->depth_stencil_attachment->attachment;
VkImageLayout layout = subpass->depth_stencil_attachment->layout;
struct radv_attachment_info *att = &framebuffer->attachments[idx];
struct radv_image *image = att->attachment->image;
radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, att->attachment->bo);
@@ -3412,9 +3412,9 @@ radv_cmd_buffer_begin_subpass(struct radv_cmd_buffer *cmd_buffer,
subpass->input_attachments[i]);
}
if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
if (subpass->depth_stencil_attachment) {
radv_handle_subpass_image_transition(cmd_buffer,
subpass->depth_stencil_attachment);
*subpass->depth_stencil_attachment);
}
radv_cmd_buffer_set_subpass(cmd_buffer, subpass);

View File

@@ -423,7 +423,7 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
.color_attachments = (struct radv_subpass_attachment[]) {
subpass->color_attachments[clear_att->colorAttachment]
},
.depth_stencil_attachment = (struct radv_subpass_attachment) { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_UNDEFINED }
.depth_stencil_attachment = NULL,
};
radv_cmd_buffer_set_subpass(cmd_buffer, &clear_subpass);
@@ -702,7 +702,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
struct radv_meta_state *meta_state = &device->meta_state;
const struct radv_subpass *subpass = cmd_buffer->state.subpass;
const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
const uint32_t pass_att = subpass->depth_stencil_attachment->attachment;
VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
VkImageAspectFlags aspects = clear_att->aspectMask;
const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
@@ -731,7 +731,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
iview,
samples_log2,
aspects,
subpass->depth_stencil_attachment.layout,
subpass->depth_stencil_attachment->layout,
clear_rect,
clear_value);
if (!pipeline)
@@ -741,7 +741,7 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
pipeline);
if (depth_view_can_fast_clear(cmd_buffer, iview, aspects,
subpass->depth_stencil_attachment.layout,
subpass->depth_stencil_attachment->layout,
clear_rect, clear_value))
radv_update_ds_clear_metadata(cmd_buffer, iview->image,
clear_value, aspects);
@@ -1536,8 +1536,8 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer,
emit_color_clear(cmd_buffer, clear_att, clear_rect, view_mask);
}
} else {
const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
VkImageLayout image_layout = subpass->depth_stencil_attachment.layout;
const uint32_t pass_att = subpass->depth_stencil_attachment->attachment;
VkImageLayout image_layout = subpass->depth_stencil_attachment->layout;
const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
@@ -1580,7 +1580,10 @@ radv_subpass_needs_clear(struct radv_cmd_buffer *cmd_buffer)
return true;
}
a = cmd_state->subpass->depth_stencil_attachment.attachment;
if (!cmd_state->subpass->depth_stencil_attachment)
return false;
a = cmd_state->subpass->depth_stencil_attachment->attachment;
return radv_attachment_needs_clear(cmd_state, a);
}
@@ -1649,7 +1652,8 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
&post_flush);
}
uint32_t ds = cmd_state->subpass->depth_stencil_attachment.attachment;
if (cmd_state->subpass->depth_stencil_attachment) {
uint32_t ds = cmd_state->subpass->depth_stencil_attachment->attachment;
if (radv_attachment_needs_clear(cmd_state, ds)) {
VkClearAttachment clear_att = {
.aspectMask = cmd_state->attachments[ds].pending_clear_aspects,
@@ -1661,6 +1665,7 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
&clear_att, &pre_flush,
&post_flush);
}
}
radv_meta_restore(&saved_state, cmd_buffer);
cmd_buffer->state.flush_bits |= post_flush;

View File

@@ -675,7 +675,7 @@ radv_cmd_buffer_resolve_subpass(struct radv_cmd_buffer *cmd_buffer)
struct radv_subpass resolve_subpass = {
.color_count = 2,
.color_attachments = (struct radv_subpass_attachment[]) { src_att, dest_att },
.depth_stencil_attachment = { .attachment = VK_ATTACHMENT_UNUSED },
.depth_stencil_attachment = NULL,
};
radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass);

View File

@@ -620,7 +620,7 @@ radv_cmd_buffer_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer)
struct radv_subpass resolve_subpass = {
.color_count = 1,
.color_attachments = (struct radv_subpass_attachment[]) { dest_att },
.depth_stencil_attachment = { .attachment = VK_ATTACHMENT_UNUSED },
.depth_stencil_attachment = NULL,
};
radv_cmd_buffer_set_subpass(cmd_buffer, &resolve_subpass);

View File

@@ -28,6 +28,32 @@
#include "vk_util.h"
static void
radv_render_pass_compile(struct radv_render_pass *pass)
{
for (uint32_t i = 0; i < pass->subpass_count; i++) {
struct radv_subpass *subpass = &pass->subpasses[i];
/* We don't allow depth_stencil_attachment to be non-NULL and
* be VK_ATTACHMENT_UNUSED. This way something can just check
* for NULL and be guaranteed that they have a valid
* attachment.
*/
if (subpass->depth_stencil_attachment &&
subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
subpass->depth_stencil_attachment = NULL;
}
}
static unsigned
radv_num_subpass_attachments(const VkSubpassDescription *desc)
{
return desc->inputAttachmentCount +
desc->colorAttachmentCount +
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
(desc->pDepthStencilAttachment != NULL);
}
VkResult radv_CreateRenderPass(
VkDevice _device,
const VkRenderPassCreateInfo* pCreateInfo,
@@ -82,13 +108,8 @@ VkResult radv_CreateRenderPass(
uint32_t subpass_attachment_count = 0;
struct radv_subpass_attachment *p;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
subpass_attachment_count +=
desc->inputAttachmentCount +
desc->colorAttachmentCount +
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
(desc->pDepthStencilAttachment != NULL);
radv_num_subpass_attachments(&pCreateInfo->pSubpasses[i]);
}
if (subpass_attachment_count) {
@@ -111,6 +132,9 @@ VkResult radv_CreateRenderPass(
subpass->input_count = desc->inputAttachmentCount;
subpass->color_count = desc->colorAttachmentCount;
subpass->attachment_count = radv_num_subpass_attachments(desc);
subpass->attachments = p;
if (multiview_info)
subpass->view_mask = multiview_info->pViewMasks[i];
@@ -159,15 +183,15 @@ VkResult radv_CreateRenderPass(
}
if (desc->pDepthStencilAttachment) {
subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
subpass->depth_stencil_attachment = p++;
*subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
.attachment = desc->pDepthStencilAttachment->attachment,
.layout = desc->pDepthStencilAttachment->layout,
};
if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
depth_sample_count = pCreateInfo->pAttachments[desc->pDepthStencilAttachment->attachment].samples;
}
} else {
subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
}
subpass->max_sample_count = MAX2(color_sample_count,
@@ -197,11 +221,22 @@ VkResult radv_CreateRenderPass(
}
}
radv_render_pass_compile(pass);
*pRenderPass = radv_render_pass_to_handle(pass);
return VK_SUCCESS;
}
static unsigned
radv_num_subpass_attachments2(const VkSubpassDescription2KHR *desc)
{
return desc->inputAttachmentCount +
desc->colorAttachmentCount +
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
(desc->pDepthStencilAttachment != NULL);
}
VkResult radv_CreateRenderPass2KHR(
VkDevice _device,
const VkRenderPassCreateInfo2KHR* pCreateInfo,
@@ -245,13 +280,8 @@ VkResult radv_CreateRenderPass2KHR(
uint32_t subpass_attachment_count = 0;
struct radv_subpass_attachment *p;
for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
subpass_attachment_count +=
desc->inputAttachmentCount +
desc->colorAttachmentCount +
(desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
(desc->pDepthStencilAttachment != NULL);
radv_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
}
if (subpass_attachment_count) {
@@ -274,6 +304,8 @@ VkResult radv_CreateRenderPass2KHR(
subpass->input_count = desc->inputAttachmentCount;
subpass->color_count = desc->colorAttachmentCount;
subpass->attachment_count = radv_num_subpass_attachments2(desc);
subpass->attachments = p;
subpass->view_mask = desc->viewMask;
if (desc->inputAttachmentCount > 0) {
@@ -321,15 +353,15 @@ VkResult radv_CreateRenderPass2KHR(
}
if (desc->pDepthStencilAttachment) {
subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
subpass->depth_stencil_attachment = p++;
*subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
.attachment = desc->pDepthStencilAttachment->attachment,
.layout = desc->pDepthStencilAttachment->layout,
};
if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
depth_sample_count = pCreateInfo->pAttachments[desc->pDepthStencilAttachment->attachment].samples;
}
} else {
subpass->depth_stencil_attachment.attachment = VK_ATTACHMENT_UNUSED;
}
subpass->max_sample_count = MAX2(color_sample_count,
@@ -359,6 +391,8 @@ VkResult radv_CreateRenderPass2KHR(
}
}
radv_render_pass_compile(pass);
*pRenderPass = radv_render_pass_to_handle(pass);
return VK_SUCCESS;

View File

@@ -966,11 +966,11 @@ radv_pipeline_out_of_order_rast(struct radv_pipeline *pipeline,
};
if (pCreateInfo->pDepthStencilState &&
subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
subpass->depth_stencil_attachment) {
const VkPipelineDepthStencilStateCreateInfo *vkds =
pCreateInfo->pDepthStencilState;
struct radv_render_pass_attachment *attachment =
pass->attachments + subpass->depth_stencil_attachment.attachment;
pass->attachments + subpass->depth_stencil_attachment->attachment;
bool has_stencil = vk_format_is_stencil(attachment->format);
struct radv_dsa_order_invariance order_invariance[2];
struct radv_shader_variant *ps =
@@ -1401,8 +1401,7 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline *pipeline,
* disabled or if the subpass of the render pass the pipeline is created
* against does not use a depth/stencil attachment.
*/
if (needed_states &&
subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
if (needed_states && subpass->depth_stencil_attachment) {
assert(pCreateInfo->pDepthStencilState);
if (states & RADV_DYNAMIC_DEPTH_BOUNDS) {
@@ -2506,8 +2505,8 @@ radv_compute_bin_size(struct radv_pipeline *pipeline, const VkGraphicsPipelineCr
extent = color_entry->extent;
if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED) {
struct radv_render_pass_attachment *attachment = pass->attachments + subpass->depth_stencil_attachment.attachment;
if (subpass->depth_stencil_attachment) {
struct radv_render_pass_attachment *attachment = pass->attachments + subpass->depth_stencil_attachment->attachment;
/* Coefficients taken from AMDVLK */
unsigned depth_coeff = vk_format_is_depth(attachment->format) ? 5 : 0;
@@ -2598,8 +2597,8 @@ radv_pipeline_generate_depth_stencil_state(struct radeon_cmdbuf *ctx_cs,
uint32_t db_render_control = 0, db_render_override2 = 0;
uint32_t db_render_override = 0;
if (subpass->depth_stencil_attachment.attachment != VK_ATTACHMENT_UNUSED)
attachment = pass->attachments + subpass->depth_stencil_attachment.attachment;
if (subpass->depth_stencil_attachment)
attachment = pass->attachments + subpass->depth_stencil_attachment->attachment;
bool has_depth_attachment = attachment && vk_format_is_depth(attachment->format);
bool has_stencil_attachment = attachment && vk_format_is_stencil(attachment->format);

View File

@@ -1815,12 +1815,15 @@ struct radv_subpass_attachment {
};
struct radv_subpass {
uint32_t attachment_count;
struct radv_subpass_attachment * attachments;
uint32_t input_count;
uint32_t color_count;
struct radv_subpass_attachment * input_attachments;
struct radv_subpass_attachment * color_attachments;
struct radv_subpass_attachment * resolve_attachments;
struct radv_subpass_attachment depth_stencil_attachment;
struct radv_subpass_attachment * depth_stencil_attachment;
/** Subpass has at least one resolve attachment */
bool has_resolve;