[Mesa-dev] [PATCH 2/2] radv: add support for VK_KHR_create_renderpass2

Samuel Pitoiset samuel.pitoiset at gmail.com
Sun Jul 8 15:47:52 UTC 2018


VkCreateRenderPass2KHR() is quite similar to VkCreateRenderPass()
but refactoring the code is a bit painful.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
 src/amd/vulkan/radv_cmd_buffer.c  |  24 +++++
 src/amd/vulkan/radv_extensions.py |   1 +
 src/amd/vulkan/radv_pass.c        | 169 ++++++++++++++++++++++++++++++
 3 files changed, 194 insertions(+)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 0ddddf50f6..5807718b6e 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -3060,6 +3060,15 @@ void radv_CmdBeginRenderPass(
 	radv_cmd_buffer_clear_subpass(cmd_buffer);
 }
 
+void radv_CmdBeginRenderPass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBeginInfo,
+    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo)
+{
+	radv_CmdBeginRenderPass(commandBuffer, pRenderPassBeginInfo,
+				pSubpassBeginInfo->contents);
+}
+
 void radv_CmdNextSubpass(
     VkCommandBuffer                             commandBuffer,
     VkSubpassContents                           contents)
@@ -3075,6 +3084,14 @@ void radv_CmdNextSubpass(
 	radv_cmd_buffer_clear_subpass(cmd_buffer);
 }
 
+void radv_CmdNextSubpass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassBeginInfoKHR*                pSubpassBeginInfo,
+    const VkSubpassEndInfoKHR*                  pSubpassEndInfo)
+{
+	radv_CmdNextSubpass(commandBuffer, pSubpassBeginInfo->contents);
+}
+
 static void radv_emit_view_index(struct radv_cmd_buffer *cmd_buffer, unsigned index)
 {
 	struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
@@ -3955,6 +3972,13 @@ void radv_CmdEndRenderPass(
 	cmd_buffer->state.framebuffer = NULL;
 }
 
+void radv_CmdEndRenderPass2KHR(
+    VkCommandBuffer                             commandBuffer,
+    const VkSubpassEndInfoKHR*                  pSubpassEndInfo)
+{
+	radv_CmdEndRenderPass(commandBuffer);
+}
+
 /*
  * For HTILE we have the following interesting clear words:
  *   0xfffff30f: Uncompressed, full depth range, for depth+stencil HTILE
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index a0f1038110..13b26c9f0b 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -52,6 +52,7 @@ class Extension:
 EXTENSIONS = [
     Extension('VK_ANDROID_native_buffer',                 5, 'ANDROID && device->rad_info.has_syncobj_wait_for_submit'),
     Extension('VK_KHR_bind_memory2',                      1, True),
+    Extension('VK_KHR_create_renderpass2',                1, True),
     Extension('VK_KHR_dedicated_allocation',              1, True),
     Extension('VK_KHR_descriptor_update_template',        1, True),
     Extension('VK_KHR_device_group',                      1, True),
diff --git a/src/amd/vulkan/radv_pass.c b/src/amd/vulkan/radv_pass.c
index 0e0f767751..2191093391 100644
--- a/src/amd/vulkan/radv_pass.c
+++ b/src/amd/vulkan/radv_pass.c
@@ -197,6 +197,175 @@ VkResult radv_CreateRenderPass(
 	return VK_SUCCESS;
 }
 
+VkResult radv_CreateRenderPass2KHR(
+    VkDevice                                    _device,
+    const VkRenderPassCreateInfo2KHR*           pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkRenderPass*                               pRenderPass)
+{
+	RADV_FROM_HANDLE(radv_device, device, _device);
+	struct radv_render_pass *pass;
+	size_t size;
+	size_t attachments_offset;
+	VkRenderPassMultiviewCreateInfoKHR *multiview_info = NULL;
+
+	assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
+
+	size = sizeof(*pass);
+	size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
+	attachments_offset = size;
+	size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
+
+	pass = vk_alloc2(&device->alloc, pAllocator, size, 8,
+			   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+	if (pass == NULL)
+		return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+	memset(pass, 0, size);
+	pass->attachment_count = pCreateInfo->attachmentCount;
+	pass->subpass_count = pCreateInfo->subpassCount;
+	pass->attachments = (void *) pass + attachments_offset;
+
+	vk_foreach_struct(ext, pCreateInfo->pNext) {
+		switch(ext->sType) {
+		case  VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR:
+			multiview_info = ( VkRenderPassMultiviewCreateInfoKHR*)ext;
+			break;
+		default:
+			break;
+		}
+	}
+
+	for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+		struct radv_render_pass_attachment *att = &pass->attachments[i];
+
+		att->format = pCreateInfo->pAttachments[i].format;
+		att->samples = pCreateInfo->pAttachments[i].samples;
+		att->load_op = pCreateInfo->pAttachments[i].loadOp;
+		att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
+		att->initial_layout =  pCreateInfo->pAttachments[i].initialLayout;
+		att->final_layout =  pCreateInfo->pAttachments[i].finalLayout;
+		// att->store_op = pCreateInfo->pAttachments[i].storeOp;
+		// att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
+	}
+	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);
+	}
+
+	if (subpass_attachment_count) {
+		pass->subpass_attachments =
+			vk_alloc2(&device->alloc, pAllocator,
+				    subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8,
+				    VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+		if (pass->subpass_attachments == NULL) {
+			vk_free2(&device->alloc, pAllocator, pass);
+			return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+		}
+	} else
+		pass->subpass_attachments = NULL;
+
+	p = pass->subpass_attachments;
+	for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+		const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
+		uint32_t color_sample_count = 1, depth_sample_count = 1;
+		struct radv_subpass *subpass = &pass->subpasses[i];
+
+		subpass->input_count = desc->inputAttachmentCount;
+		subpass->color_count = desc->colorAttachmentCount;
+		if (multiview_info)
+			subpass->view_mask = multiview_info->pViewMasks[i];
+
+		if (desc->inputAttachmentCount > 0) {
+			subpass->input_attachments = p;
+			p += desc->inputAttachmentCount;
+
+			for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
+				subpass->input_attachments[j] = (struct radv_subpass_attachment) {
+					.attachment = desc->pInputAttachments[j].attachment,
+					.layout = desc->pInputAttachments[j].layout,
+				};
+				if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED)
+					pass->attachments[desc->pInputAttachments[j].attachment].view_mask |= subpass->view_mask;
+			}
+		}
+
+		if (desc->colorAttachmentCount > 0) {
+			subpass->color_attachments = p;
+			p += desc->colorAttachmentCount;
+
+			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
+				subpass->color_attachments[j] = (struct radv_subpass_attachment) {
+					.attachment = desc->pColorAttachments[j].attachment,
+					.layout = desc->pColorAttachments[j].layout,
+				};
+				if (desc->pColorAttachments[j].attachment != VK_ATTACHMENT_UNUSED) {
+					pass->attachments[desc->pColorAttachments[j].attachment].view_mask |= subpass->view_mask;
+					color_sample_count = pCreateInfo->pAttachments[desc->pColorAttachments[j].attachment].samples;
+				}
+			}
+		}
+
+		subpass->has_resolve = false;
+		if (desc->pResolveAttachments) {
+			subpass->resolve_attachments = p;
+			p += desc->colorAttachmentCount;
+
+			for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
+				uint32_t a = desc->pResolveAttachments[j].attachment;
+				subpass->resolve_attachments[j] = (struct radv_subpass_attachment) {
+					.attachment = desc->pResolveAttachments[j].attachment,
+					.layout = desc->pResolveAttachments[j].layout,
+				};
+				if (a != VK_ATTACHMENT_UNUSED) {
+					subpass->has_resolve = true;
+					pass->attachments[desc->pResolveAttachments[j].attachment].view_mask |= subpass->view_mask;
+				}
+			}
+		}
+
+		if (desc->pDepthStencilAttachment) {
+			subpass->depth_stencil_attachment = (struct radv_subpass_attachment) {
+				.attachment = desc->pDepthStencilAttachment->attachment,
+				.layout = desc->pDepthStencilAttachment->layout,
+			};
+			if (desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
+				pass->attachments[desc->pDepthStencilAttachment->attachment].view_mask |= subpass->view_mask;
+				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,
+						 depth_sample_count);
+	}
+
+	for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) {
+		uint32_t dst = pCreateInfo->pDependencies[i].dstSubpass;
+		if (dst == VK_SUBPASS_EXTERNAL) {
+			pass->end_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
+			pass->end_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
+			pass->end_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
+		} else {
+			pass->subpasses[dst].start_barrier.src_stage_mask = pCreateInfo->pDependencies[i].srcStageMask;
+			pass->subpasses[dst].start_barrier.src_access_mask = pCreateInfo->pDependencies[i].srcAccessMask;
+			pass->subpasses[dst].start_barrier.dst_access_mask = pCreateInfo->pDependencies[i].dstAccessMask;
+		}
+	}
+
+	*pRenderPass = radv_render_pass_to_handle(pass);
+
+	return VK_SUCCESS;
+}
+
 void radv_DestroyRenderPass(
 	VkDevice                                    _device,
 	VkRenderPass                                _pass,
-- 
2.18.0



More information about the mesa-dev mailing list