[Piglit] [PATCH 5/6] ext_memory_object: Support for setting up vulkan framebuffer

Topi Pohjolainen topi.pohjolainen at gmail.com
Thu Nov 30 14:52:42 UTC 2017


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 tests/spec/ext_memory_object/vk_common.h |  25 +++
 tests/spec/ext_memory_object/vk_fb.c     | 300 +++++++++++++++++++++++++++++++
 2 files changed, 325 insertions(+)
 create mode 100644 tests/spec/ext_memory_object/vk_fb.c

diff --git a/tests/spec/ext_memory_object/vk_common.h b/tests/spec/ext_memory_object/vk_common.h
index 9e974ec36..3b7daf29c 100644
--- a/tests/spec/ext_memory_object/vk_common.h
+++ b/tests/spec/ext_memory_object/vk_common.h
@@ -34,12 +34,37 @@ struct vk_vertex_buffer {
 	VkDeviceMemory mem;
 };
 
+struct vk_image {
+	VkImage image;
+	VkDeviceMemory mem;
+};
+
+struct vk_attachment {
+	struct vk_image image;
+	VkImageView view;
+};
+
+struct vk_fb {
+	struct vk_attachment color;
+	struct vk_attachment depth;
+	VkRenderPass render_pass;
+	VkFramebuffer fb;
+};
+
 VkDevice
 vk_init(void);
 
 void
 vk_cleanup(void);
 
+void
+vk_setup_fb(VkDevice dev, unsigned w, unsigned h, unsigned num_samples,
+            unsigned layers, VkFormat color_fmt, VkFormat depth_fmt,
+            struct vk_fb *fb);
+
+void
+vk_fb_destroy(VkDevice dev, struct vk_fb *fb);
+
 VkRenderPass
 vk_create_render_pass(VkFormat format);
 
diff --git a/tests/spec/ext_memory_object/vk_fb.c b/tests/spec/ext_memory_object/vk_fb.c
new file mode 100644
index 000000000..db395394a
--- /dev/null
+++ b/tests/spec/ext_memory_object/vk_fb.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "vk_common.h"
+#include "piglit-util-gl.h"
+
+static void
+vk_destroy_image(VkDevice dev, struct vk_image *image)
+{
+	if (image->image != VK_NULL_HANDLE)
+		vkDestroyImage(dev, image->image, NULL);
+
+	if (image->mem != VK_NULL_HANDLE)
+		vkFreeMemory(dev, image->mem, NULL);
+}
+
+void
+vk_create_image(VkDevice dev, VkFormat format,
+		unsigned w, unsigned h, unsigned z, unsigned num_samples,
+		unsigned num_levels, unsigned num_layers,
+		VkImageUsageFlagBits usage, struct vk_image *image)
+{
+	const VkImageType image_type =
+		z > 1 ? VK_IMAGE_TYPE_3D : VK_IMAGE_TYPE_2D;
+	const VkImageCreateInfo info = {
+		.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+		.imageType = image_type,
+		.tiling = VK_IMAGE_TILING_OPTIMAL,
+		.mipLevels = num_levels,
+		.arrayLayers = num_layers,
+		.samples = (VkSampleCountFlagBits)num_samples,
+		.format = format,
+		.extent = {
+			.width = w,
+			.height = h,
+			.depth = z,
+		},
+		.usage = usage,
+	};
+	VkMemoryRequirements mem_reqs;
+
+	image->image = VK_NULL_HANDLE;
+	image->mem = VK_NULL_HANDLE;
+	
+	if (vkCreateImage(dev, &info, NULL, &image->image) != VK_SUCCESS)
+		goto fail;
+
+	vkGetImageMemoryRequirements(dev, image->image, &mem_reqs);
+
+	image->mem = vk_alloc_mem(
+			dev, &mem_reqs, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+	if (image->mem == VK_NULL_HANDLE)
+		goto fail;
+
+	if (vkBindImageMemory(dev, image->image, image->mem, 0) == VK_SUCCESS)
+		return;
+
+fail:
+	vk_destroy_image(dev, image);
+	image->image = VK_NULL_HANDLE;
+	image->mem = VK_NULL_HANDLE;
+}
+
+static VkImageView
+vk_create_image_view(VkDevice dev, VkImage image, VkFormat format,
+		     VkImageAspectFlagBits aspect_mask,
+		     unsigned base_level, unsigned level_count,
+		     unsigned base_layer, unsigned layer_count)
+{
+	const VkImageViewType type = layer_count > 1 ?
+		VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
+
+	const VkImageViewCreateInfo info = {
+		.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+		.viewType = type,
+		.image = image,
+        	.format = format,
+		.subresourceRange = {
+			.aspectMask = aspect_mask,
+			.baseMipLevel = base_level,
+			.levelCount = level_count,
+			.baseArrayLayer = base_layer,
+			.layerCount = layer_count,
+		},
+	};
+	VkImageView view = VK_NULL_HANDLE;
+
+	if (vkCreateImageView(dev, &info, NULL, &view) != VK_SUCCESS)
+		view = VK_NULL_HANDLE;
+
+	return view;
+}
+
+static void
+vk_create_attachment(VkDevice dev, VkFormat format,
+		     unsigned w, unsigned h, unsigned num_samples,
+		     VkImageAspectFlagBits aspect_mask,
+		     VkImageUsageFlagBits usage,
+		     unsigned base_level, unsigned level_count,
+		     unsigned base_layer, unsigned layer_count,
+		     struct vk_attachment *att)
+{
+	att->image.image = VK_NULL_HANDLE;
+	vk_create_image(dev, format, w, h, 1, num_samples,
+			level_count, layer_count, usage, &att->image);
+	if (att->image.image == VK_NULL_HANDLE)
+		return;
+
+	att->view = vk_create_image_view(
+			dev, att->image.image, format, aspect_mask,
+			base_level, level_count, base_layer, layer_count);
+	if (att->view == VK_NULL_HANDLE) {
+		vk_destroy_image(dev, &att->image);
+		att->image.image = VK_NULL_HANDLE;
+		att->image.mem = VK_NULL_HANDLE;
+	}
+}
+
+static VkRenderPass
+vk_create_fb_render_pass(VkDevice dev, unsigned num_samples,
+			 VkFormat color_format, VkFormat depth_format)
+{
+	const bool has_depth = depth_format != VK_FORMAT_UNDEFINED;
+	const VkAttachmentDescription attachments[] = {
+		{
+			.samples = (VkSampleCountFlagBits)num_samples,
+			.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+			.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+			.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+			.finalLayout = VK_IMAGE_LAYOUT_GENERAL,
+			.format = color_format
+		},
+		{
+			.samples = VK_SAMPLE_COUNT_1_BIT,
+			.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+			.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+			.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+			.finalLayout = VK_IMAGE_LAYOUT_GENERAL,
+			.format = depth_format
+		}
+	};
+	const VkAttachmentReference color_ref = {
+		.attachment = 0,
+		.layout = VK_IMAGE_LAYOUT_GENERAL,
+	};
+	const VkAttachmentReference depth_ref = {
+		.attachment = 1,
+		.layout = VK_IMAGE_LAYOUT_GENERAL,
+	};
+	const VkSubpassDescription sub_pass = {
+		.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+		.colorAttachmentCount = 1,
+		.pColorAttachments = &color_ref,
+		.pDepthStencilAttachment = has_depth ? &depth_ref : NULL,
+	};
+	const VkRenderPassCreateInfo info = {
+                .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                .attachmentCount = has_depth ? 2 : 1,
+		.pAttachments = attachments,
+		.subpassCount = 1,
+		.pSubpasses = &sub_pass,
+	};
+	VkRenderPass pass = VK_NULL_HANDLE;
+	if (vkCreateRenderPass(dev, &info, NULL, &pass) != VK_SUCCESS)
+		pass = VK_NULL_HANDLE;
+
+	return pass;
+}
+
+static VkFramebuffer
+vk_create_fb(VkDevice dev, VkRenderPass render_pass,
+	     unsigned w, unsigned h, unsigned layers,
+	     VkImageView color_view, VkImageView depth_view)
+{
+	const VkImageView attachments[2] = { color_view, depth_view };
+	const VkFramebufferCreateInfo info = {
+                .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+		.renderPass = render_pass,
+		.width = w,
+		.height = h,
+		.layers = layers,
+		.attachmentCount = depth_view != VK_NULL_HANDLE ? 2 : 1,
+		.pAttachments = attachments,
+	};
+	VkFramebuffer fb = VK_NULL_HANDLE;
+
+	if (vkCreateFramebuffer(dev, &info, NULL, &fb) != VK_SUCCESS)
+		fb = VK_NULL_HANDLE;
+
+	return fb;
+}
+
+static VkImageAspectFlagBits
+vk_get_depth_stencil_aspect_mask(VkFormat format)
+{
+	switch (format) {
+	case VK_FORMAT_D16_UNORM:
+	case VK_FORMAT_X8_D24_UNORM_PACK32:
+	case VK_FORMAT_D32_SFLOAT:
+	    return VK_IMAGE_ASPECT_DEPTH_BIT;
+	case VK_FORMAT_S8_UINT:
+	    return VK_IMAGE_ASPECT_STENCIL_BIT;
+	case VK_FORMAT_D16_UNORM_S8_UINT:
+	case VK_FORMAT_D24_UNORM_S8_UINT:
+	case VK_FORMAT_D32_SFLOAT_S8_UINT:
+	    return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+	default:
+	    assert(!"Invalid depthstencil format");
+	}
+}
+
+static void
+vk_destroy_attachment(VkDevice dev, struct vk_attachment *att)
+{
+	if (att->view != VK_NULL_HANDLE)
+		vkDestroyImageView(dev, att->view, NULL);
+
+	vk_destroy_image(dev, &att->image);
+}
+
+void
+vk_fb_destroy(VkDevice dev, struct vk_fb *fb)
+{
+	if (fb->fb != VK_NULL_HANDLE)
+		vkDestroyFramebuffer(dev, fb->fb, NULL);
+
+	if (fb->render_pass != VK_NULL_HANDLE)
+		vkDestroyRenderPass(dev, fb->render_pass, NULL);
+
+	vk_destroy_attachment(dev, &fb->color);
+	vk_destroy_attachment(dev, &fb->depth);
+}
+
+void
+vk_setup_fb(VkDevice dev, unsigned w, unsigned h, unsigned num_samples,
+	    unsigned layers, VkFormat color_format, VkFormat depth_format,
+	    struct vk_fb *fb)
+{
+	const VkImageUsageFlagBits usage = VK_IMAGE_USAGE_SAMPLED_BIT |
+					   VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+
+	(void)memset(fb, 0, sizeof(*fb));
+
+	if (color_format != VK_FORMAT_UNDEFINED) {
+		vk_create_attachment(
+			dev, color_format, w, h, num_samples,
+			VK_IMAGE_ASPECT_COLOR_BIT,
+			usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+			0, 1, 0, layers, &fb->color);
+		if (fb->color.image.image == VK_NULL_HANDLE)
+			return;
+	}
+
+	if (depth_format != VK_FORMAT_UNDEFINED) {
+		const VkImageAspectFlagBits aspect_mask =
+			vk_get_depth_stencil_aspect_mask(depth_format);
+
+		vk_create_attachment(
+			dev, depth_format, w, h, num_samples,
+			aspect_mask,
+			usage | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
+			0, 1, 0, layers, &fb->depth);
+		if (fb->depth.image.image == VK_NULL_HANDLE)
+			goto fail;
+	}
+
+	fb->render_pass = vk_create_fb_render_pass(
+				dev, num_samples, color_format, depth_format);
+	if (fb->render_pass == VK_NULL_HANDLE)
+		goto fail;
+
+	fb->fb = vk_create_fb(dev, fb->render_pass, w, h, layers,
+			      fb->color.view, fb->depth.view);
+	if (fb->fb != VK_NULL_HANDLE)
+		return;
+
+fail:
+	vk_fb_destroy(dev, fb);
+	(void)memset(fb, 0, sizeof(*fb));
+}
-- 
2.14.1



More information about the Piglit mailing list