[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