On Thu, Dec 21, 2017 at 11:25:04AM -0500, Andres Rodriguez wrote: > > > On 2017-12-21 07:02 AM, Topi Pohjolainen wrote: > > v2: Store image size in order to know how much memory to import, > > see glImportMemoryFdEXT(). > > > > v3: > > - use "goto fail" for all failure paths (Andres) > > - use VkExternalMemoryImageCreateInfoKHR (Fredrik) > > - check for dedicated using > > vkGetImageMemoryRequirements2KHR() (Fredrik) > > > > Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> > > --- > > tests/spec/ext_memory_object/vk_common.c | 13 ++ > > tests/spec/ext_memory_object/vk_common.h | 53 +++++ > > tests/spec/ext_memory_object/vk_fb.c | 346 > > +++++++++++++++++++++++++++++++ > > 3 files changed, 412 insertions(+) > > create mode 100644 tests/spec/ext_memory_object/vk_fb.c > > > > diff --git a/tests/spec/ext_memory_object/vk_common.c > > b/tests/spec/ext_memory_object/vk_common.c > > index 2c664742a..eaecdf8cd 100644 > > --- a/tests/spec/ext_memory_object/vk_common.c > > +++ b/tests/spec/ext_memory_object/vk_common.c > > @@ -570,3 +570,16 @@ vk_create_fence(VkDevice dev) > > return fence; > > } > > + > > +PFN_vkGetImageMemoryRequirements2KHR > > +vk_get_proc_addr_for_image_mem_req(VkDevice dev) > > +{ > > + static PFN_vkGetImageMemoryRequirements2KHR get_mem_req = NULL; > > + > > + if (get_mem_req == NULL) > > + get_mem_req = (PFN_vkGetImageMemoryRequirements2KHR) > > + vkGetDeviceProcAddr( > > + dev, "vkGetImageMemoryRequirements2KHR"); > > + > > + return get_mem_req; > > +} > > diff --git a/tests/spec/ext_memory_object/vk_common.h > > b/tests/spec/ext_memory_object/vk_common.h > > index b4c22575c..c9d920523 100644 > > --- a/tests/spec/ext_memory_object/vk_common.h > > +++ b/tests/spec/ext_memory_object/vk_common.h > > @@ -44,12 +44,62 @@ struct vk_vertex_buffer { > > VkDeviceMemory mem; > > }; > > +struct vk_image { > > + VkImage image; > > + VkDeviceMemory mem; > > + VkDeviceSize size; > > +}; > > + > > +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; > > +}; > > + > > +static inline VkImageType > > +vk_get_image_type(unsigned h, unsigned z) > > +{ > > + if (h == 1) > > + return VK_IMAGE_TYPE_1D; > > + > > + if (z > 1) > > + return VK_IMAGE_TYPE_3D; > > + > > + return VK_IMAGE_TYPE_2D; > > +} > > + > > void > > vk_core_init(struct vk_core *core); > > void > > vk_core_cleanup(struct vk_core *core); > > +void > > +vk_create_image(struct vk_core *core, VkFormat format, > > + unsigned w, unsigned h, unsigned z, unsigned num_samples, > > + unsigned num_levels, unsigned num_layers, > > + VkImageUsageFlagBits usage, VkImageTiling tiling, > > + struct vk_image *image); > > + > > +void > > +vk_destroy_image(VkDevice dev, struct vk_image *image); > > + > > +void > > +vk_setup_fb(struct vk_core *core, > > + unsigned w, unsigned h, unsigned num_samples, > > + VkFormat color_fmt, VkImageTiling color_tiling, > > + VkFormat depth_fmt, VkImageTiling depth_tiling, > > + unsigned layers, struct vk_fb *fb); > > + > > +void > > +vk_fb_destroy(VkDevice dev, struct vk_fb *fb); > > + > > VkRenderPass > > vk_create_render_pass(VkDevice dev, > > VkFormat format, unsigned num_samples, > > @@ -88,4 +138,7 @@ vk_draw(struct vk_core *core, VkPipeline pipeline, > > VkBuffer vb, VkFence fence); > > VkFence > > vk_create_fence(VkDevice dev); > > +PFN_vkGetImageMemoryRequirements2KHR > > +vk_get_proc_addr_for_image_mem_req(VkDevice dev); > > + > > #endif > > 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..42609e900 > > --- /dev/null > > +++ b/tests/spec/ext_memory_object/vk_fb.c > > @@ -0,0 +1,346 @@ > > +/* > > + * 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" > > + > > +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); > > +} > > + > > +static void > > +vk_alloc_image_mem(struct vk_core *core, struct vk_image *image) > > +{ > > + const VkImageMemoryRequirementsInfo2KHR req_info = { > > + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, > > + .image = image->image > > + }; > > + VkMemoryDedicatedRequirementsKHR dedicated_info = { > > + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR > > + }; > > + VkMemoryRequirements2KHR mem_reqs = { > > + .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, > > + .pNext = &dedicated_info > > + }; > > + PFN_vkGetImageMemoryRequirements2KHR vk_get_image_mem_req_2_khr = > > + vk_get_proc_addr_for_image_mem_req(core->dev); > > + > > + vk_get_image_mem_req_2_khr(core->dev, &req_info, &mem_reqs); > > + > > + if (dedicated_info.requiresDedicatedAllocation) { > > + VkMemoryDedicatedAllocateInfoKHR dedicated_alloc_info = > > { > > + .sType = > > VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, > > + .image = image->image > > + }; > > + > > + image->mem = vk_alloc_mem( > > + core, &mem_reqs.memoryRequirements, > > + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, > > Also need to check if DEVICE_LOCAL_BIT is supported by > mem_reqs.memoryTypeBits.
Ok, I'll look into that, thanks! > > > > + &dedicated_alloc_info); > > + } else { > > + image->mem = vk_alloc_mem( > > + core, &mem_reqs.memoryRequirements, > > + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, > > + NULL); > > + } > > + > > To avoid duplicated codepaths here: > > void *pExt = VK_NULL_HANDLE; > VkMemoryDedicatedAllocateInfoKHR dedicated_alloc_info = { ... }; > pExt = dedicated_info.requiresDedicatedAllocation ? > dedicated_alloc_info : VK_NULL_HANDLE; I thought about that but didn't like to include dedicated_alloc_info on path that wouldn't need it. But I'm just as fine doing it this way. I'll see what it looks like when I get the LOCAL_BIT addressed. > > > > > + image->size = mem_reqs.memoryRequirements.size; > > +} > > + > > +void > > +vk_create_image(struct vk_core *core, VkFormat format, > > + unsigned w, unsigned h, unsigned z, unsigned num_samples, > > + unsigned num_levels, unsigned num_layers, > > + VkImageUsageFlagBits usage, VkImageTiling tiling, > > + struct vk_image *image) > > +{ > > + const VkExternalMemoryImageCreateInfoKHR ext_image_info = { > > + .sType = > > VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR, > > + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR, > > + }; > > + const VkImageCreateInfo info = { > > + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, > > + .pNext = &ext_image_info, > > + .imageType = vk_get_image_type(h, z), > > + .tiling = tiling, > > + .mipLevels = num_levels, > > + .arrayLayers = num_layers, > > + .samples = (VkSampleCountFlagBits)num_samples, > > + .format = format, > > + .extent = { > > + .width = w, > > + .height = h, > > + .depth = z, > > + }, > > + .usage = usage, > > + }; > > + > > + image->image = VK_NULL_HANDLE; > > + image->mem = VK_NULL_HANDLE; > > + > > + if (vkCreateImage( > > + core->dev, &info, NULL, &image->image) != VK_SUCCESS) > > + goto fail; > > + > > + vk_alloc_image_mem(core, image); > > + if (image->mem == VK_NULL_HANDLE) > > + goto fail; > > + > > + if (vkBindImageMemory( > > + core->dev, image->image, image->mem, 0) != VK_SUCCESS) > > + goto fail; > > + > > + return; > > + > > +fail: > > + vk_destroy_image(core->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(struct vk_core *core, VkFormat format, > > + unsigned w, unsigned h, unsigned num_samples, > > + VkImageAspectFlagBits aspect_mask, > > + VkImageUsageFlagBits usage, VkImageTiling tiling, > > + 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(core, format, w, h, 1, num_samples, > > + level_count, layer_count, usage, tiling, &att->image); > > + if (att->image.image == VK_NULL_HANDLE) > > + return; > > + > > + att->view = vk_create_image_view( > > + core->dev, att->image.image, format, aspect_mask, > > + base_level, level_count, base_layer, layer_count); > > + if (att->view == VK_NULL_HANDLE) { > > + vk_destroy_image(core->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(struct vk_core *core, > > + unsigned w, unsigned h, unsigned num_samples, > > + VkFormat color_format, VkImageTiling color_tiling, > > + VkFormat depth_format, VkImageTiling depth_tiling, > > + unsigned layers, 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( > > + core, color_format, w, h, num_samples, > > + VK_IMAGE_ASPECT_COLOR_BIT, > > + usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, > > + color_tiling, 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( > > + core, depth_format, w, h, num_samples, > > + aspect_mask, > > + usage | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, > > + depth_tiling, 0, 1, 0, layers, &fb->depth); > > + if (fb->depth.image.image == VK_NULL_HANDLE) > > + goto fail; > > + } > > + > > + fb->render_pass = vk_create_fb_render_pass( > > + core->dev, num_samples, color_format, depth_format); > > + if (fb->render_pass == VK_NULL_HANDLE) > > + goto fail; > > + > > + fb->fb = vk_create_fb( > > + core->dev, fb->render_pass, w, h, layers, > > + fb->color.view, fb->depth.view); > > + if (fb->fb != VK_NULL_HANDLE) > > + return; > > + > > +fail: > > + vk_fb_destroy(core->dev, fb); > > + (void)memset(fb, 0, sizeof(*fb)); > > +} > > _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit