[Piglit] [v3 05/11] ext_memory_object: Support for drawing with vulkan

Topi Pohjolainen topi.pohjolainen at gmail.com
Thu Dec 21 12:02:48 UTC 2017


v2:
   - do not leak mapped vertex buffer (Andres)
   - fix typo mem_regs -> mem_reqs (Andres)
   - vk_alloc_mem() with VkMemoryDedicatedAllocateInfoKHR (Fredrik)
   - pass struct vk_core as argument instead of using static

CC: Andres Rodriguez <andresx7 at gmail.com>
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 tests/spec/ext_memory_object/vk_common.c | 336 +++++++++++++++++++++++++++++++
 tests/spec/ext_memory_object/vk_common.h |  43 ++++
 2 files changed, 379 insertions(+)

diff --git a/tests/spec/ext_memory_object/vk_common.c b/tests/spec/ext_memory_object/vk_common.c
index 2c3e8272e..2c664742a 100644
--- a/tests/spec/ext_memory_object/vk_common.c
+++ b/tests/spec/ext_memory_object/vk_common.c
@@ -234,3 +234,339 @@ vk_core_cleanup(struct vk_core *core)
 	if (core->inst != VK_NULL_HANDLE)
 		vkDestroyInstance(core->inst, &test_alloc_cb);
 }
+
+VkRenderPass
+vk_create_render_pass(VkDevice dev,
+		      VkFormat format, unsigned num_samples,
+		      VkImageLayout sub_pass_layout,
+		      VkImageLayout final_layout)
+{
+        const VkRenderPassCreateInfo info = {
+                .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+		.attachmentCount = 1,
+		.pAttachments = (VkAttachmentDescription[]) { {
+			.samples = (VkSampleCountFlagBits)num_samples,
+    			.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
+    			.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+    			.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+    			.finalLayout = final_layout,
+			.format = format,
+		}, },
+		.subpassCount = 1,
+		.pSubpasses = (VkSubpassDescription[]) { {
+			.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+			.colorAttachmentCount = 1,
+			.pColorAttachments = (VkAttachmentReference[]) {
+			{
+				.layout = sub_pass_layout,
+			}, },
+			.preserveAttachmentCount = 1,
+			.pPreserveAttachments = (uint32_t[]) { 0 },
+		} },
+	};
+
+	VkRenderPass pass = VK_NULL_HANDLE;
+    	if (vkCreateRenderPass(dev, &info, NULL, &pass) != VK_SUCCESS)
+	        pass = VK_NULL_HANDLE;
+
+	return pass;
+}
+
+VkShaderModule
+vk_add_shader(VkDevice dev, const void *code, size_t size)
+{
+	const VkShaderModuleCreateInfo info = {
+	     .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
+	     .codeSize = size, 
+	     .pCode = code
+	};
+
+	VkShaderModule module = VK_NULL_HANDLE;
+	if (vkCreateShaderModule(dev, &info, NULL, &module) != VK_SUCCESS)
+	        module = VK_NULL_HANDLE;
+
+	return module;
+}
+
+VkPipeline
+vk_create_pipeline(struct vk_core *core,
+		   unsigned w, unsigned h, unsigned num_samples,
+		   VkPrimitiveTopology topology,
+		   unsigned attr_stride, VkFormat attr_format,
+		   VkRenderPass render_pass,
+		   VkShaderModule fs, VkShaderModule vs)
+{
+        const VkPipelineVertexInputStateCreateInfo vi_info = {
+		.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+		.vertexBindingDescriptionCount = 1,
+		.pVertexBindingDescriptions =
+			(VkVertexInputBindingDescription[]) { {
+				.binding = 0,
+				.stride = attr_stride,
+				.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
+		}, },
+		.vertexAttributeDescriptionCount = 1,
+		.pVertexAttributeDescriptions =
+			(VkVertexInputAttributeDescription[]) { {
+				.location = 0,
+				.binding = 0,
+				.format = attr_format,
+				.offset = 0
+		}, }
+	};
+	const VkPipelineInputAssemblyStateCreateInfo ia_info = {
+		.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+		.topology = topology,
+		.primitiveRestartEnable = false
+	};
+	const VkViewport viewport = { 0.0, 0.0, w, h, 0.0, 1.0 };
+	const VkRect2D scissor = { { 0, 0 }, {w, h } };
+	const VkPipelineViewportStateCreateInfo vp_info = {
+		.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+		.viewportCount = 1,
+		.pViewports = &viewport,
+		.scissorCount = 1,
+		.pScissors = &scissor
+	};
+	const VkPipelineRasterizationStateCreateInfo rs_info = {
+		.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
+    		.depthClampEnable = false,
+		.rasterizerDiscardEnable = false,
+		.polygonMode = VK_POLYGON_MODE_FILL,
+		.cullMode = VK_CULL_MODE_NONE,
+		.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
+		.depthBiasConstantFactor = 0.0f,
+		.depthBiasClamp = 0.0f,
+		.depthBiasSlopeFactor = 0.0f,
+		.lineWidth = 1.0f
+	};
+	const VkPipelineMultisampleStateCreateInfo ms_info = {
+		.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+		.rasterizationSamples = num_samples
+	};
+	const VkPipelineDepthStencilStateCreateInfo ds_info = {
+		.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+		.depthTestEnable = false,
+		.depthWriteEnable = false,
+		.depthBoundsTestEnable = false,
+		.stencilTestEnable = false,
+		.front = {
+			.compareMask = ~0,  /* default in OpenGL ES 3.1 */
+			.writeMask = ~0,    /* default in OpenGL ES 3.1 */
+			.reference = 0,     /* default in OpenGL ES 3.1 */
+		},
+		.back = {
+			.compareMask = ~0,  /* default in OpenGL ES 3.1 */
+			.writeMask = ~0,    /* default in OpenGL ES 3.1 */
+			.reference = 0,     /* default in OpenGL ES 3.1 */
+		},
+		.minDepthBounds = 0.0f, /* default in OpenGL ES 3.1 */
+		.maxDepthBounds = 1.0f  /* default in OpenGL ES 3.1 */
+	};
+	const VkPipelineColorBlendStateCreateInfo cb_info = {
+		.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+    		.attachmentCount = 1,
+    		.pAttachments = (VkPipelineColorBlendAttachmentState []) { {
+			.blendEnable = false,
+    			.colorWriteMask = (VK_COLOR_COMPONENT_R_BIT |
+					   VK_COLOR_COMPONENT_G_BIT |
+					   VK_COLOR_COMPONENT_B_BIT |
+					   VK_COLOR_COMPONENT_A_BIT)
+    		} },
+    		.blendConstants = {0.0f, 0.0f, 0.0f, 0.0f} /* default in OpenGL ES 3.1 */
+	};
+	const VkPipelineShaderStageCreateInfo stage_info[] = {
+		{
+			.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+                	.stage = VK_SHADER_STAGE_VERTEX_BIT,
+                	.module = vs,
+                	.pName = "main",
+		},
+		{
+			.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+			.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
+			.module = fs,
+			.pName = "main",
+		}
+	};
+	const VkGraphicsPipelineCreateInfo pipeline_info = {
+		.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+		.pInputAssemblyState = &ia_info,
+		.pViewportState = &vp_info,
+		.pRasterizationState = &rs_info,
+		.pMultisampleState = &ms_info,
+		.pDepthStencilState = &ds_info,
+		.pColorBlendState = &cb_info,
+		.stageCount = ARRAY_SIZE(stage_info),
+		.pStages = stage_info,
+		.pVertexInputState = &vi_info,
+		.renderPass = render_pass,
+		.subpass = 0,
+	};
+
+	VkPipeline pipeline = VK_NULL_HANDLE;
+	if (vkCreateGraphicsPipelines(
+		core->dev, core->pipeline_cache,
+		1, &pipeline_info, NULL, &pipeline) != VK_SUCCESS)
+		pipeline = VK_NULL_HANDLE;
+
+	return pipeline;
+}
+
+static uint32_t
+vk_get_memory_type_index(VkPhysicalDevice phys_dev,
+			 const VkMemoryRequirements *mem_reqs,
+			 VkMemoryPropertyFlagBits properties)
+{
+	VkPhysicalDeviceMemoryProperties props;
+
+	vkGetPhysicalDeviceMemoryProperties(phys_dev, &props);
+
+	for (uint32_t i = 0; i < props.memoryTypeCount; i++) {
+		const VkMemoryType *type = &props.memoryTypes[i];
+
+		if ((mem_reqs->memoryTypeBits & (1 << i)) &&
+		    (type->propertyFlags & properties) == properties) {
+			return i;
+			break;
+		}
+	}
+
+	return UINT32_MAX;
+}
+
+VkDeviceMemory
+vk_alloc_mem(struct vk_core *core, const VkMemoryRequirements *mem_reqs,
+	     VkMemoryPropertyFlagBits props,
+	     const VkMemoryDedicatedAllocateInfoKHR *dedicated)
+{
+	const VkMemoryAllocateInfo info = {
+		.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+		.pNext = dedicated,
+		.allocationSize = mem_reqs->size,
+		.memoryTypeIndex = vk_get_memory_type_index(
+					core->phys_dev, mem_reqs, props),
+	};
+	VkDeviceMemory mem = VK_NULL_HANDLE;
+
+	if (info.memoryTypeIndex == UINT32_MAX)
+		return VK_NULL_HANDLE;
+
+	if (vkAllocateMemory(core->dev, &info, NULL, &mem) != VK_SUCCESS)
+		mem = VK_NULL_HANDLE;
+
+	return mem;
+}
+
+static VkDeviceMemory
+vk_alloc_buffer(struct vk_core *core, VkBuffer buffer,
+		VkMemoryPropertyFlagBits props)
+{
+	VkMemoryRequirements mem_reqs;
+	vkGetBufferMemoryRequirements(core->dev, buffer, &mem_reqs);
+
+	return vk_alloc_mem(core, &mem_reqs, props, NULL);
+}
+
+void
+vk_setup_vertex_buffer(struct vk_core *core,
+		       const void *vertices, unsigned size,
+		       struct vk_vertex_buffer *vb)
+{
+	const VkBufferCreateInfo info = {
+		.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
+		.size = size,
+		.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
+	};
+	void *map;
+
+	vb->buf = VK_NULL_HANDLE;
+	vb->mem = VK_NULL_HANDLE;
+
+	if (vkCreateBuffer(core->dev, &info, NULL, &vb->buf) != VK_SUCCESS ||
+	    vb->buf == VK_NULL_HANDLE)
+		goto fail;
+
+	vb->mem = vk_alloc_buffer(
+		core, vb->buf, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+	if (vb->mem == VK_NULL_HANDLE)
+		goto fail;
+
+	if (vkBindBufferMemory(core->dev, vb->buf, vb->mem, 0) != VK_SUCCESS)
+		goto fail;
+
+	if (vkMapMemory(
+		core->dev, vb->mem, 0, info.size, 0, &map) != VK_SUCCESS)
+		goto fail;
+
+	memcpy(map, vertices, info.size);
+
+	vkUnmapMemory(core->dev, vb->mem);
+
+	return;
+
+fail:
+	if (vb->mem != VK_NULL_HANDLE)
+		vkFreeMemory(core->dev, vb->mem, NULL);
+
+	if (vb->buf != VK_NULL_HANDLE)
+		vkDestroyBuffer(core->dev, vb->buf, NULL);
+	
+	vb->buf = VK_NULL_HANDLE;
+	vb->mem = VK_NULL_HANDLE;
+}
+
+void
+vk_begin_render_pass(VkCommandBuffer cmd_buf,
+		     VkRenderPass render_pass, VkFramebuffer fb,
+		     unsigned w, unsigned h)
+{
+	const VkRenderPassBeginInfo info = {
+		.renderPass = render_pass,
+		.framebuffer = fb,
+		.renderArea = { { 0, 0 }, { w, h} },
+		.clearValueCount = 1,
+		.pClearValues = (VkClearValue[]) {
+			{ .color = { .float32 = {1.0, 0.0, 0.0, 1.0} } },
+		}
+	};
+
+	vkCmdBeginRenderPass(cmd_buf, &info, VK_SUBPASS_CONTENTS_INLINE);
+}
+
+bool
+vk_draw(struct vk_core *core, VkPipeline pipeline, VkBuffer vb, VkFence fence)
+{
+	const VkSubmitInfo submit_info = {
+		.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+		.commandBufferCount = 1,
+		.pCommandBuffers = &core->cmd_buf,
+	};
+	const VkDeviceSize dev_size = 0;
+
+	vkCmdBindVertexBuffers(core->cmd_buf, 0, 1, &vb, &dev_size);
+    	vkCmdBindPipeline(
+		core->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+    	vkCmdDraw(core->cmd_buf, 4, 1, 0, 0);
+	vkCmdEndRenderPass(core->cmd_buf);
+
+	if (vkEndCommandBuffer(core->cmd_buf) != VK_SUCCESS)
+		return false;
+
+	return vkQueueSubmit(
+		core->queue, 1, &submit_info, fence) == VK_SUCCESS;
+}
+
+VkFence
+vk_create_fence(VkDevice dev)
+{
+        const VkFenceCreateInfo info = {
+                .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+        };
+        VkFence fence = VK_NULL_HANDLE;
+
+        if (vkCreateFence(dev, &info, NULL, &fence) != VK_SUCCESS)
+                fence = VK_NULL_HANDLE;
+
+        return fence;
+}
diff --git a/tests/spec/ext_memory_object/vk_common.h b/tests/spec/ext_memory_object/vk_common.h
index 7674d95f3..b4c22575c 100644
--- a/tests/spec/ext_memory_object/vk_common.h
+++ b/tests/spec/ext_memory_object/vk_common.h
@@ -39,10 +39,53 @@ struct vk_core {
 	VkQueue queue;
 };
 
+struct vk_vertex_buffer {
+	VkBuffer buf;
+	VkDeviceMemory mem;
+};
+
 void
 vk_core_init(struct vk_core *core);
 
 void
 vk_core_cleanup(struct vk_core *core);
 
+VkRenderPass
+vk_create_render_pass(VkDevice dev,
+		      VkFormat format, unsigned num_samples,
+		      VkImageLayout sub_pass_layout,
+		      VkImageLayout final_layout);
+
+VkShaderModule
+vk_add_shader(VkDevice vk, const void *code, size_t size);
+
+VkPipeline
+vk_create_pipeline(struct vk_core *core,
+		   unsigned w, unsigned h, unsigned num_samples,
+		   VkPrimitiveTopology topology,
+		   unsigned attr_stride, VkFormat attr_format,
+		   VkRenderPass render_pass,
+		   VkShaderModule fs, VkShaderModule vs);
+
+VkDeviceMemory
+vk_alloc_mem(struct vk_core *core, const VkMemoryRequirements *mem_reqs,
+	     VkMemoryPropertyFlagBits props,
+	     const VkMemoryDedicatedAllocateInfoKHR *dedicated);
+
+void
+vk_setup_vertex_buffer(struct vk_core *core,
+		       const void *vertices, unsigned size,
+		       struct vk_vertex_buffer *vb);
+
+void
+vk_begin_render_pass(VkCommandBuffer cmd_buf,
+		     VkRenderPass render_pass, VkFramebuffer fb,
+		     unsigned w, unsigned h);
+
+bool
+vk_draw(struct vk_core *core, VkPipeline pipeline, VkBuffer vb, VkFence fence);
+
+VkFence
+vk_create_fence(VkDevice dev);
+
 #endif
-- 
2.14.1



More information about the Piglit mailing list