[Mesa-dev] [PATCH 06/19] radv: store the list of attachments for every subpass

Samuel Pitoiset samuel.pitoiset at gmail.com
Tue Jan 29 21:18:51 UTC 2019


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 at gmail.com>
---
 src/amd/vulkan/radv_cmd_buffer.c      | 16 +++---
 src/amd/vulkan/radv_meta_clear.c      | 41 +++++++++-------
 src/amd/vulkan/radv_meta_resolve.c    |  2 +-
 src/amd/vulkan/radv_meta_resolve_fs.c |  2 +-
 src/amd/vulkan/radv_pass.c            | 70 ++++++++++++++++++++-------
 src/amd/vulkan/radv_pipeline.c        | 15 +++---
 src/amd/vulkan/radv_private.h         |  5 +-
 7 files changed, 96 insertions(+), 55 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 003dcbd5fb2..440f09a363c 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -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);
diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c
index 06f25aa46d7..c68ce1ee8a8 100644
--- a/src/amd/vulkan/radv_meta_clear.c
+++ b/src/amd/vulkan/radv_meta_clear.c
@@ -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,17 +1652,19 @@ radv_cmd_buffer_clear_subpass(struct radv_cmd_buffer *cmd_buffer)
 					      &post_flush);
 	}
 
-	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,
-			.clearValue = cmd_state->attachments[ds].clear_value,
-		};
-
-		radv_subpass_clear_attachment(cmd_buffer,
-					      &cmd_state->attachments[ds],
-					      &clear_att, &pre_flush,
-					      &post_flush);
+	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,
+				.clearValue = cmd_state->attachments[ds].clear_value,
+			};
+
+			radv_subpass_clear_attachment(cmd_buffer,
+						      &cmd_state->attachments[ds],
+						      &clear_att, &pre_flush,
+						      &post_flush);
+		}
 	}
 
 	radv_meta_restore(&saved_state, cmd_buffer);
diff --git a/src/amd/vulkan/radv_meta_resolve.c b/src/amd/vulkan/radv_meta_resolve.c
index 821f47c9671..baa5746b8ab 100644
--- a/src/amd/vulkan/radv_meta_resolve.c
+++ b/src/amd/vulkan/radv_meta_resolve.c
@@ -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);
diff --git a/src/amd/vulkan/radv_meta_resolve_fs.c b/src/amd/vulkan/radv_meta_resolve_fs.c
index 47af4bb1d86..1ab7ece8dfb 100644
--- a/src/amd/vulkan/radv_meta_resolve_fs.c
+++ b/src/amd/vulkan/radv_meta_resolve_fs.c
@@ -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);
diff --git a/src/amd/vulkan/radv_pass.c b/src/amd/vulkan/radv_pass.c
index 3a70006f6bb..1102ef689b2 100644
--- a/src/amd/vulkan/radv_pass.c
+++ b/src/amd/vulkan/radv_pass.c
@@ -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;
diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index 138e153f9a4..c96f86bff63 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -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);
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index d64eee80f65..a4b611f18d3 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -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;
-- 
2.20.1



More information about the mesa-dev mailing list