From 6d2c68e0e885a93a4b94ca56c49240728d4a6e35 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Wed, 26 May 2021 12:50:45 +0300 Subject: [PATCH] updated, needs fixes --- src/vk.c | 769 ++++++++++++++++++++++++++++++++++++++++++++------------------ src/vk.h | 39 +++- 2 files changed, 580 insertions(+), 228 deletions(-) diff --git a/src/vk.c b/src/vk.c index a94e13a..d280e00 100644 --- a/src/vk.c +++ b/src/vk.c @@ -11,7 +11,61 @@ static VkRect2D scissor; /* static functions */ static VkSampleCountFlagBits -get_num_samples(uint32_t num_samples); +get_num_samples(uint32_t num_samples) +{ + switch(num_samples) { + case 64: + return VK_SAMPLE_COUNT_64_BIT; + case 32: + return VK_SAMPLE_COUNT_32_BIT; + case 16: + return VK_SAMPLE_COUNT_16_BIT; + case 8: + return VK_SAMPLE_COUNT_8_BIT; + case 4: + return VK_SAMPLE_COUNT_4_BIT; + case 2: + return VK_SAMPLE_COUNT_2_BIT; + case 1: + break; + default: + fprintf(stderr, "Invalid number of samples in VkSampleCountFlagBits. Using one sample.\n"); + break; + } + return VK_SAMPLE_COUNT_1_BIT; +} + +static VkAccessFlagBits +get_access_mask(const VkImageLayout layout) +{ + /* dstAccessMask of barriers must be supported from the pipeline + * stage, see also access scopes and this table: + * https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#synchronization-access-types-supported + */ + switch (layout) { + case VK_IMAGE_LAYOUT_UNDEFINED: + return 0; + case VK_IMAGE_LAYOUT_GENERAL: + return VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; + case VK_IMAGE_LAYOUT_PREINITIALIZED: + return VK_ACCESS_HOST_WRITE_BIT; + case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: + return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: + return VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; + case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: + return VK_ACCESS_TRANSFER_READ_BIT; + case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: + return VK_ACCESS_TRANSFER_WRITE_BIT; + case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: + return 0; + default: + return 0; + }; + + return 0; +} static void enable_validation_layers(VkInstanceCreateInfo *info) @@ -40,24 +94,6 @@ enable_validation_layers(VkInstanceCreateInfo *info) } } -static void -fill_uuid(VkPhysicalDevice pdev, uint8_t *deviceUUID, uint8_t *driverUUID) -{ - VkPhysicalDeviceIDProperties devProp; - VkPhysicalDeviceProperties2 prop2; - - memset(&devProp, 0, sizeof devProp); - devProp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; - - memset(&prop2, 0, sizeof prop2); - prop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; - prop2.pNext = &devProp; - - vkGetPhysicalDeviceProperties2(pdev, &prop2); - memcpy(deviceUUID, devProp.deviceUUID, VK_UUID_SIZE); - memcpy(driverUUID, devProp.driverUUID, VK_UUID_SIZE); -} - static VkInstance create_instance(bool enable_layers) { @@ -78,7 +114,7 @@ create_instance(bool enable_layers) enable_validation_layers(&inst_info); if (vkCreateInstance(&inst_info, 0, &inst) != VK_SUCCESS) - return VK_NULL_HANDLE; + return 0; return inst; } @@ -93,12 +129,12 @@ select_physical_device(VkInstance inst) if ((res = vkEnumeratePhysicalDevices(inst, &dev_count, 0)) != VK_SUCCESS) - return VK_NULL_HANDLE; + return 0; pdevices = malloc(dev_count * sizeof(VkPhysicalDevice)); if (vkEnumeratePhysicalDevices(inst, &dev_count, pdevices) != VK_SUCCESS) - return VK_NULL_HANDLE; + return 0; pdevice0 = pdevices[0]; free(pdevices); @@ -109,6 +145,7 @@ select_physical_device(VkInstance inst) static VkDevice create_device(struct vk_ctx *ctx, VkPhysicalDevice pdev) { + /* FIXME: swapchain */ const char *deviceExtensions[] = { "VK_KHR_external_memory_fd", "VK_KHR_external_semaphore_fd" }; VkDeviceQueueCreateInfo dev_queue_info; @@ -123,7 +160,7 @@ create_device(struct vk_ctx *ctx, VkPhysicalDevice pdev) vkGetPhysicalDeviceQueueFamilyProperties(pdev, &prop_count, 0); if (prop_count < 0) { fprintf(stderr, "Invalid queue family properties.\n"); - return VK_NULL_HANDLE; + return 0; } fam_props = malloc(prop_count * sizeof *fam_props); @@ -151,24 +188,27 @@ create_device(struct vk_ctx *ctx, VkPhysicalDevice pdev) dev_info.ppEnabledExtensionNames = deviceExtensions; if (vkCreateDevice(pdev, &dev_info, 0, &dev) != VK_SUCCESS) - return VK_NULL_HANDLE; + return 0; return dev; } -static VkPipelineCache -create_pipeline_cache(VkDevice dev) +static void +fill_uuid(VkPhysicalDevice pdev, uint8_t *deviceUUID, uint8_t *driverUUID) { - VkPipelineCacheCreateInfo pcache_info; - VkPipelineCache pcache; + VkPhysicalDeviceIDProperties devProp; + VkPhysicalDeviceProperties2 prop2; - memset(&pcache_info, 0, sizeof pcache_info); - pcache_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + memset(&devProp, 0, sizeof devProp); + devProp.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES; - if (vkCreatePipelineCache(dev, &pcache_info, 0, &pcache) != VK_SUCCESS) - return VK_NULL_HANDLE; + memset(&prop2, 0, sizeof prop2); + prop2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + prop2.pNext = &devProp; - return pcache; + vkGetPhysicalDeviceProperties2(pdev, &prop2); + memcpy(deviceUUID, devProp.deviceUUID, VK_UUID_SIZE); + memcpy(driverUUID, devProp.driverUUID, VK_UUID_SIZE); } static VkCommandPool @@ -184,15 +224,15 @@ create_cmd_pool(struct vk_ctx *ctx) cmd_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; if (vkCreateCommandPool(dev, &cmd_pool_info, 0, &cmd_pool) != VK_SUCCESS) - return VK_NULL_HANDLE; + return 0; return cmd_pool; } static VkRenderPass create_renderpass(struct vk_ctx *ctx, - struct vk_image_props *color_img_props, - struct vk_image_props *depth_img_props) + struct vk_image_props *color_img_props, + struct vk_image_props *depth_img_props) { uint32_t num_attachments = 2; VkAttachmentDescription att_dsc[2]; @@ -209,14 +249,23 @@ create_renderpass(struct vk_ctx *ctx, att_dsc[0].initialLayout = color_img_props->in_layout; att_dsc[0].finalLayout = color_img_props->end_layout; att_dsc[0].format = color_img_props->format; + att_dsc[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + att_dsc[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; att_dsc[1].samples = get_num_samples(depth_img_props->num_samples); + /* We might want to reuse a depth buffer */ - if (depth_img_props->in_layout != VK_IMAGE_LAYOUT_UNDEFINED) + if (depth_img_props->in_layout != VK_IMAGE_LAYOUT_UNDEFINED) { att_dsc[1].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - else + att_dsc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; + } + else { att_dsc[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + att_dsc[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + } + att_dsc[1].storeOp = VK_ATTACHMENT_STORE_OP_STORE; + att_dsc[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; att_dsc[1].initialLayout = depth_img_props->in_layout; att_dsc[1].finalLayout = depth_img_props->end_layout; att_dsc[1].format = depth_img_props->format; @@ -315,7 +364,7 @@ get_aspect_from_depth_format(VkFormat depth_format) default: break; } - return VK_NULL_HANDLE; + return 0; } static VkPipelineStageFlags @@ -339,7 +388,7 @@ get_pipeline_stage_flags(const VkImageLayout layout) case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: return VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; default: - return 0; + break; } return 0; } @@ -389,7 +438,7 @@ create_framebuffer(struct vk_ctx *ctx, color_info.format = color_att->props.format; color_info.subresourceRange = sr; - if (vkCreateImageView(ctx->dev, &color_info, 0, &atts[0]) != VK_SUCCESS) { + if (vkCreateImageView(ctx->dev, &color_info, 0, &color_att->obj.img_view) != VK_SUCCESS) { fprintf(stderr, "Failed to create color image view for framebuffer.\n"); vk_destroy_image(ctx, &color_att->obj); goto fail; @@ -411,12 +460,16 @@ create_framebuffer(struct vk_ctx *ctx, depth_info.format = depth_att->props.format; depth_info.subresourceRange = sr; - if (vkCreateImageView(ctx->dev, &depth_info, 0, &atts[1]) != VK_SUCCESS) { + if (vkCreateImageView(ctx->dev, &depth_info, 0, &depth_att->obj.img_view) != VK_SUCCESS) { + fprintf(stderr, "Failed to create depth image view for framebuffer.\n"); vk_destroy_image(ctx, &depth_att->obj); goto fail; } + atts[0] = color_att->obj.img_view; + atts[1] = depth_att->obj.img_view; + memset(&fb_info, 0, sizeof fb_info); fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; fb_info.renderPass = renderer->renderpass; @@ -460,12 +513,12 @@ create_shader_module(struct vk_ctx *ctx, static void create_pipeline(struct vk_ctx *ctx, - uint32_t width, - uint32_t height, - uint32_t num_samples, - bool enable_depth, - bool enable_stencil, - struct vk_renderer *renderer) + uint32_t width, + uint32_t height, + uint32_t num_samples, + bool enable_depth, + bool enable_stencil, + struct vk_renderer *renderer) { VkVertexInputBindingDescription vert_bind_dsc[1]; VkVertexInputAttributeDescription vert_att_dsc[1]; @@ -515,19 +568,23 @@ create_pipeline(struct vk_ctx *ctx, vert_bind_dsc[0].stride = stride; vert_bind_dsc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + /* If using vbo, we have setup vertex_info in the renderer. */ + bool use_vbo = renderer->vertex_info.num_verts > 0; + /* VkPipelineVertexInputStateCreateInfo */ memset(&vert_input_info, 0, sizeof vert_input_info); vert_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vert_input_info.vertexBindingDescriptionCount = 1; + vert_input_info.vertexBindingDescriptionCount = use_vbo ? 1 : 0; vert_input_info.pVertexBindingDescriptions = vert_bind_dsc; - vert_input_info.vertexAttributeDescriptionCount = 1; + vert_input_info.vertexAttributeDescriptionCount = use_vbo ? 1 : 0; vert_input_info.pVertexAttributeDescriptions = vert_att_dsc; /* VkPipelineInputAssemblyStateCreateInfo */ memset(&asm_info, 0, sizeof asm_info); asm_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; asm_info.topology = renderer->vertex_info.topology ? - renderer->vertex_info.topology : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + renderer->vertex_info.topology + : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; asm_info.primitiveRestartEnable = false; /* VkViewport */ @@ -609,9 +666,9 @@ create_pipeline(struct vk_ctx *ctx, /* VkPipelineColorBlendAttachmentState */ memset(&cb_att_state[0], 0, sizeof cb_att_state[0]); cb_att_state[0].colorWriteMask = (VK_COLOR_COMPONENT_R_BIT | - VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | - VK_COLOR_COMPONENT_A_BIT); + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT); /* VkPipelineColorBlendStateCreateInfo */ memset(&cb_info, 0, sizeof cb_info); @@ -670,49 +727,14 @@ create_pipeline(struct vk_ctx *ctx, pipeline_info.stageCount = 2; pipeline_info.pStages = sdr_stages; - if (vkCreateGraphicsPipelines(ctx->dev, ctx->cache, 1, - &pipeline_info, 0, &renderer->pipeline) != - VK_SUCCESS) { + if (vkCreateGraphicsPipelines(ctx->dev, 0, 1, + &pipeline_info, 0, + &renderer->pipeline) != VK_SUCCESS) { fprintf(stderr, "Failed to create graphics pipeline.\n"); renderer->pipeline = VK_NULL_HANDLE; } } -static VkAccessFlagBits -get_access_mask(const VkImageLayout layout) -{ - switch (layout) { - case VK_IMAGE_LAYOUT_UNDEFINED: - return 0; - case VK_IMAGE_LAYOUT_GENERAL: - return VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | - VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT | - VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_HOST_WRITE_BIT | - VK_ACCESS_HOST_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT; - case VK_IMAGE_LAYOUT_PREINITIALIZED: - return VK_ACCESS_HOST_WRITE_BIT; - case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: - return VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | - VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; - case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: - return VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; - case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: - return VK_ACCESS_TRANSFER_READ_BIT; - case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: - return VK_ACCESS_TRANSFER_WRITE_BIT; - case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: - return 0; - default: - return 0; - }; - - return 0; -} - static VkCommandBuffer create_cmd_buf(VkDevice dev, VkCommandPool cmd_pool) { @@ -726,7 +748,7 @@ create_cmd_buf(VkDevice dev, VkCommandPool cmd_pool) alloc_info.commandPool = cmd_pool; if (vkAllocateCommandBuffers(dev, &alloc_info, &cmd_buf) != VK_SUCCESS) - return VK_NULL_HANDLE; + return 0; return cmd_buf; } @@ -753,47 +775,25 @@ get_memory_type_idx(VkPhysicalDevice pdev, return UINT32_MAX; } -static VkSampleCountFlagBits -get_num_samples(uint32_t num_samples) -{ - switch(num_samples) { - case 64: - return VK_SAMPLE_COUNT_64_BIT; - case 32: - return VK_SAMPLE_COUNT_32_BIT; - case 16: - return VK_SAMPLE_COUNT_16_BIT; - case 8: - return VK_SAMPLE_COUNT_8_BIT; - case 4: - return VK_SAMPLE_COUNT_4_BIT; - case 2: - return VK_SAMPLE_COUNT_2_BIT; - case 1: - break; - default: - fprintf(stderr, "Invalid number of samples in VkSampleCountFlagBits. Using one sample.\n"); - break; - } - return VK_SAMPLE_COUNT_1_BIT; -} - static VkDeviceMemory alloc_memory(struct vk_ctx *ctx, - const VkMemoryRequirements *mem_reqs, - VkImage image, - VkBuffer buffer, - VkMemoryPropertyFlagBits prop_flags) + bool is_external, + const VkMemoryRequirements *mem_reqs, + VkImage image, + VkBuffer buffer, + VkMemoryPropertyFlagBits prop_flags) { VkExportMemoryAllocateInfo exp_mem_info; VkMemoryAllocateInfo mem_alloc_info; VkDeviceMemory mem; VkMemoryDedicatedAllocateInfoKHR ded_info; - memset(&exp_mem_info, 0, sizeof exp_mem_info); - exp_mem_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO; - exp_mem_info.handleTypes = - VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; + if (is_external) { + memset(&exp_mem_info, 0, sizeof exp_mem_info); + exp_mem_info.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO; + exp_mem_info.handleTypes = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; + } memset(&mem_alloc_info, 0, sizeof mem_alloc_info); mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; @@ -804,7 +804,7 @@ alloc_memory(struct vk_ctx *ctx, if (mem_alloc_info.memoryTypeIndex == UINT32_MAX) { fprintf(stderr, "No suitable memory type index found.\n"); - return VK_NULL_HANDLE; + return 0; } if (image || buffer) { @@ -818,7 +818,7 @@ alloc_memory(struct vk_ctx *ctx, if (vkAllocateMemory(ctx->dev, &mem_alloc_info, 0, &mem) != VK_SUCCESS) - return VK_NULL_HANDLE; + return 0; return mem; } @@ -845,11 +845,13 @@ alloc_image_memory(struct vk_ctx *ctx, struct vk_image_obj *img_obj) vkGetImageMemoryRequirements2(ctx->dev, &req_info2, &mem_reqs2); img_obj->mobj.mem = alloc_memory(ctx, - &mem_reqs2.memoryRequirements, - ded_reqs.requiresDedicatedAllocation? img_obj->img : VK_NULL_HANDLE, - VK_NULL_HANDLE, - mem_reqs2.memoryRequirements.memoryTypeBits & - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + true, /* is_external = FIXME */ + &mem_reqs2.memoryRequirements, + ded_reqs.requiresDedicatedAllocation ? + img_obj->img : VK_NULL_HANDLE, + VK_NULL_HANDLE, + mem_reqs2.memoryRequirements.memoryTypeBits & + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); img_obj->mobj.mem_sz = mem_reqs2.memoryRequirements.size; img_obj->mobj.dedicated = ded_reqs.requiresDedicatedAllocation; @@ -858,7 +860,8 @@ alloc_image_memory(struct vk_ctx *ctx, struct vk_image_obj *img_obj) return false; } - if (vkBindImageMemory(ctx->dev, img_obj->img, img_obj->mobj.mem, 0) != VK_SUCCESS) { + if (vkBindImageMemory(ctx->dev, img_obj->img, img_obj->mobj.mem, 0) != + VK_SUCCESS) { fprintf(stderr, "Failed to bind image memory.\n"); return false; } @@ -869,20 +872,76 @@ alloc_image_memory(struct vk_ctx *ctx, struct vk_image_obj *img_obj) static bool are_props_supported(struct vk_ctx *ctx, struct vk_image_props *props) { + VkPhysicalDeviceExternalImageFormatInfo ext_img_fmt_info; + VkExternalImageFormatProperties ext_img_fmt_props; + + int i; VkPhysicalDeviceImageFormatInfo2 img_fmt_info; VkImageFormatProperties2 img_fmt_props; + VkImageUsageFlagBits all_flags[] = { + VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VK_IMAGE_USAGE_SAMPLED_BIT, + VK_IMAGE_USAGE_STORAGE_BIT, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + /* Shouldn't be used together with COLOR, DEPTH_STENCIL + * attachment bits: + * VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + * Provided by VK_EXT_fragment_density_map + * VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT, + * Provided by VK_NV_shading_rate_image + * VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, + * Provided by VK_KHR_fragment_shading_rate + * VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + */ + }; + VkImageUsageFlagBits flags = 0; + + VkExternalMemoryFeatureFlagBits export_feature_flags = + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT; + VkExternalMemoryHandleTypeFlagBits handle_type = + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; + + memset(&ext_img_fmt_info, 0, sizeof ext_img_fmt_info); + ext_img_fmt_info.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO; + ext_img_fmt_info.handleType = handle_type; + + memset(&ext_img_fmt_props, 0, sizeof ext_img_fmt_props); + ext_img_fmt_props.sType = + VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES; + + memset(&img_fmt_props, 0, sizeof img_fmt_props); + img_fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; + img_fmt_props.pNext = &ext_img_fmt_props; memset(&img_fmt_info, 0, sizeof img_fmt_info); img_fmt_info.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2; - img_fmt_info.pNext = 0; + img_fmt_info.pNext = &ext_img_fmt_info; img_fmt_info.format = props->format; img_fmt_info.type = get_image_type(props->h, props->depth); img_fmt_info.tiling = props->tiling; - img_fmt_info.usage = props->usage ? props->usage : VK_IMAGE_USAGE_TRANSFER_SRC_BIT; - memset(&img_fmt_props, 0, sizeof img_fmt_props); - img_fmt_props.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; + for (i = 0; i < ARRAY_SIZE(all_flags); i++) { + img_fmt_info.usage = all_flags[i]; + if (vkGetPhysicalDeviceImageFormatProperties2(ctx->pdev, + &img_fmt_info, + &img_fmt_props) == VK_SUCCESS) { + flags |= all_flags[i]; + } + } + + /* usage can't be null */ + if (flags) { + img_fmt_info.usage = flags; + } + else { + fprintf(stderr, "Unsupported Vulkan format properties: usage.\n"); + return false; + } if (vkGetPhysicalDeviceImageFormatProperties2 (ctx->pdev, &img_fmt_info, &img_fmt_props) != VK_SUCCESS) { @@ -890,10 +949,20 @@ are_props_supported(struct vk_ctx *ctx, struct vk_image_props *props) "Unsupported Vulkan format properties.\n"); return false; } + props->usage = flags; + + if (props->need_export && + !(ext_img_fmt_props.externalMemoryProperties.externalMemoryFeatures + & export_feature_flags)) { + fprintf(stderr, "Unsupported Vulkan external memory features.\n"); + return false; + } return true; } +/* exposed Vulkan functions */ + bool vk_init_ctx(struct vk_ctx *ctx) { @@ -928,18 +997,13 @@ vk_init_ctx_for_rendering(struct vk_ctx *ctx) return false; } - if ((ctx->cache = create_pipeline_cache(ctx->dev)) == VK_NULL_HANDLE) { - fprintf(stderr, "Failed to create pipeline cache.\n"); - goto fail; - } - if ((ctx->cmd_pool = create_cmd_pool(ctx)) == VK_NULL_HANDLE) { fprintf(stderr, "Failed to create command pool.\n"); goto fail; } if ((ctx->cmd_buf = create_cmd_buf(ctx->dev, ctx->cmd_pool)) == - VK_NULL_HANDLE) { + VK_NULL_HANDLE) { fprintf(stderr, "Failed to create command buffer.\n"); goto fail; } @@ -960,20 +1024,29 @@ fail: void vk_cleanup_ctx(struct vk_ctx *ctx) { - if (ctx->cmd_buf != VK_NULL_HANDLE) + if (ctx->cmd_buf != VK_NULL_HANDLE) { + vkResetCommandBuffer(ctx->cmd_buf, + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); vkFreeCommandBuffers(ctx->dev, ctx->cmd_pool, 1, &ctx->cmd_buf); + ctx->cmd_buf = VK_NULL_HANDLE; + } - if (ctx->cmd_pool != VK_NULL_HANDLE) + if (ctx->cmd_pool != VK_NULL_HANDLE) { + vkResetCommandPool(ctx->dev, ctx->cmd_pool, + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT); vkDestroyCommandPool(ctx->dev, ctx->cmd_pool, 0); + ctx->cmd_pool = VK_NULL_HANDLE; + } - if (ctx->cache != VK_NULL_HANDLE) - vkDestroyPipelineCache(ctx->dev, ctx->cache, 0); - - if (ctx->dev != VK_NULL_HANDLE) + if (ctx->dev != VK_NULL_HANDLE) { vkDestroyDevice(ctx->dev, 0); + ctx->dev = VK_NULL_HANDLE; + } - if (ctx->inst != VK_NULL_HANDLE) + if (ctx->inst != VK_NULL_HANDLE) { vkDestroyInstance(ctx->inst, 0); + ctx->inst = VK_NULL_HANDLE; + } } bool @@ -992,10 +1065,12 @@ vk_create_image(struct vk_ctx *ctx, img_info.extent.height = props->h; img_info.extent.depth = props->depth; img_info.mipLevels = props->num_levels ? props->num_levels : 1; - img_info.arrayLayers = props->num_layers ? props->num_layers : VK_SAMPLE_COUNT_1_BIT; + img_info.arrayLayers = props->num_layers ? + props->num_layers : VK_SAMPLE_COUNT_1_BIT; img_info.samples = get_num_samples(props->num_samples); img_info.tiling = props->tiling; - img_info.usage = props->usage ? props->usage : VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + img_info.usage = props->usage ? + props->usage : VK_IMAGE_USAGE_TRANSFER_SRC_BIT; img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -1030,19 +1105,68 @@ vk_destroy_image(struct vk_ctx *ctx, struct vk_image_obj *img_obj) } bool +vk_create_ext_image(struct vk_ctx *ctx, + struct vk_image_props *props, struct vk_image_obj *img) +{ + VkExternalMemoryImageCreateInfo ext_img_info; + VkImageCreateInfo img_info; + + memset(&ext_img_info, 0, sizeof ext_img_info); + ext_img_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO; + ext_img_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; + + memset(&img_info, 0, sizeof img_info); + img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + img_info.pNext = &ext_img_info; + img_info.imageType = get_image_type(props->h, props->depth); + img_info.format = props->format; + img_info.extent.width = props->w; + img_info.extent.height = props->h; + img_info.extent.depth = props->depth; + img_info.mipLevels = props->num_levels ? props->num_levels : 1; + img_info.arrayLayers = props->num_layers ? props->num_layers : VK_SAMPLE_COUNT_1_BIT; + img_info.samples = get_num_samples(props->num_samples); + img_info.tiling = props->tiling; + img_info.usage = props->usage; + img_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + img_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + /* issue 17 of EXT_external_objects + * Required in OpenGL implementations that support + * ARB_texture_view, OES_texture_view, EXT_texture_view, + * or OpenGL 4.3 and above. + */ + img_info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; + + if (vkCreateImage(ctx->dev, &img_info, 0, &img->img) != VK_SUCCESS) + goto fail; + + if(!alloc_image_memory(ctx, img)) + goto fail; + + return true; + +fail: + fprintf(stderr, "Failed to create external image.\n"); + vk_destroy_image(ctx, img); + img->img = VK_NULL_HANDLE; + img->mobj.mem = VK_NULL_HANDLE; + return false; +} + +bool vk_fill_ext_image_props(struct vk_ctx *ctx, - uint32_t w, - uint32_t h, - uint32_t d, - uint32_t num_samples, - uint32_t num_levels, - uint32_t num_layers, - VkFormat format, - VkImageTiling tiling, - VkImageUsageFlagBits usage, - VkImageLayout in_layout, - VkImageLayout end_layout, - struct vk_image_props *props) + uint32_t w, + uint32_t h, + uint32_t d, + uint32_t num_samples, + uint32_t num_levels, + uint32_t num_layers, + VkFormat format, + VkImageTiling tiling, + VkImageLayout in_layout, + VkImageLayout end_layout, + bool need_export, + struct vk_image_props *props) { props->w = w; props->h = h; @@ -1053,11 +1177,11 @@ vk_fill_ext_image_props(struct vk_ctx *ctx, props->num_layers = num_layers; props->format = format; - props->usage = usage; props->tiling = tiling; props->in_layout = in_layout; props->end_layout = end_layout; + props->need_export = need_export; if (!are_props_supported(ctx, props)) return false; @@ -1067,22 +1191,23 @@ vk_fill_ext_image_props(struct vk_ctx *ctx, bool vk_create_renderer(struct vk_ctx *ctx, - const char *vs_src, - unsigned int vs_size, - const char *fs_src, - unsigned int fs_size, - bool enable_depth, - bool enable_stencil, - struct vk_image_att *color_att, - struct vk_image_att *depth_att, - struct vk_vertex_info *vert_info, - struct vk_renderer *renderer) + const char *vs_src, + unsigned int vs_size, + const char *fs_src, + unsigned int fs_size, + bool enable_depth, + bool enable_stencil, + struct vk_image_att *color_att, + struct vk_image_att *depth_att, + struct vk_vertex_info *vert_info, + struct vk_renderer *renderer) { memset(&renderer->vertex_info, 0, sizeof renderer->vertex_info); if (vert_info) renderer->vertex_info = *vert_info; - renderer->renderpass = create_renderpass(ctx, &color_att->props, &depth_att->props); + renderer->renderpass = create_renderpass(ctx, &color_att->props, + &depth_att->props); if (renderer->renderpass == VK_NULL_HANDLE) goto fail; @@ -1099,7 +1224,8 @@ vk_create_renderer(struct vk_ctx *ctx, goto fail; create_pipeline(ctx, color_att->props.w, color_att->props.h, - color_att->props.num_samples, enable_depth, enable_stencil, renderer); + color_att->props.num_samples, enable_depth, + enable_stencil, renderer); if (renderer->pipeline == VK_NULL_HANDLE) goto fail; @@ -1114,29 +1240,62 @@ fail: void vk_destroy_renderer(struct vk_ctx *ctx, - struct vk_renderer *renderer) + struct vk_renderer *renderer) { - if (renderer->renderpass != VK_NULL_HANDLE) + if (renderer->renderpass != VK_NULL_HANDLE) { vkDestroyRenderPass(ctx->dev, renderer->renderpass, 0); + renderer->renderpass = VK_NULL_HANDLE; + } - if (renderer->vs != VK_NULL_HANDLE) + if (renderer->vs != VK_NULL_HANDLE) { vkDestroyShaderModule(ctx->dev, renderer->vs, 0); + renderer->vs = VK_NULL_HANDLE; + } - if (renderer->fs != VK_NULL_HANDLE) + if (renderer->fs != VK_NULL_HANDLE) { vkDestroyShaderModule(ctx->dev, renderer->fs, 0); + renderer->fs = VK_NULL_HANDLE; + } - if (renderer->pipeline != VK_NULL_HANDLE) - vkDestroyPipeline(ctx->dev, renderer->pipeline, 0); - - if (renderer->fb != VK_NULL_HANDLE) + if (renderer->fb != VK_NULL_HANDLE) { vkDestroyFramebuffer(ctx->dev, renderer->fb, 0); + renderer->fb = VK_NULL_HANDLE; + } - if (renderer->pipeline_layout != VK_NULL_HANDLE) + if (renderer->pipeline != VK_NULL_HANDLE) { + vkDestroyPipeline(ctx->dev, renderer->pipeline, 0); + renderer->pipeline = VK_NULL_HANDLE; + } + + if (renderer->pipeline_layout != VK_NULL_HANDLE) { vkDestroyPipelineLayout(ctx->dev, renderer->pipeline_layout, 0); + renderer->pipeline_layout = VK_NULL_HANDLE; + } +} + +bool +vk_create_ext_buffer(struct vk_ctx *ctx, + uint32_t sz, + VkBufferUsageFlagBits usage, + struct vk_buf *bo) +{ + VkExternalMemoryBufferCreateInfo ext_bo_info; + + memset(&ext_bo_info, 0, sizeof ext_bo_info); + ext_bo_info.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO; + ext_bo_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; + + if (!vk_create_buffer(ctx, true, sz, usage, &ext_bo_info, bo)) { + fprintf(stderr, "Failed to allocate external buffer.\n"); + return false; + } + + return true; } bool vk_create_buffer(struct vk_ctx *ctx, + bool is_external, uint32_t sz, VkBufferUsageFlagBits usage, void *pnext, @@ -1166,9 +1325,10 @@ vk_create_buffer(struct vk_ctx *ctx, * vkInvalidateMappedMemoryRanges are not needed to flush host * writes to the device or make device writes visible to the * host, respectively. */ - bo->mobj.mem = alloc_memory(ctx, &mem_reqs, VK_NULL_HANDLE, VK_NULL_HANDLE, - VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); + bo->mobj.mem = alloc_memory(ctx, is_external, &mem_reqs, VK_NULL_HANDLE, + VK_NULL_HANDLE, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); if (bo->mobj.mem == VK_NULL_HANDLE) goto fail; @@ -1335,11 +1495,176 @@ vk_draw(struct vk_ctx *ctx, int num_vertices = vbo ? renderer->vertex_info.num_verts : 4; vkCmdDraw(ctx->cmd_buf, num_vertices, 1, 0, 0); + vkCmdEndRenderPass(ctx->cmd_buf); + if (attachments) { + VkImageMemoryBarrier *barriers = + calloc(n_attachments, sizeof(VkImageMemoryBarrier)); + VkImageMemoryBarrier *barrier = barriers; + for (uint32_t n = 0; n < n_attachments; n++, barrier++) { + struct vk_image_att *att = &attachments[n]; + VkImageAspectFlagBits depth_stencil_flags = + get_aspect_from_depth_format(att->props.format); + bool is_depth = (depth_stencil_flags != 0); + + /* Insert barrier to mark ownership transfer. */ + barrier->sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier->oldLayout = is_depth ? + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + barrier->newLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier->srcAccessMask = get_access_mask(barrier->oldLayout); + barrier->dstAccessMask = get_access_mask(barrier->newLayout); + barrier->srcQueueFamilyIndex = ctx->qfam_idx; + barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL; + barrier->image = att->obj.img; + barrier->subresourceRange.aspectMask = is_depth ? + depth_stencil_flags : + VK_IMAGE_ASPECT_COLOR_BIT; + barrier->subresourceRange.baseMipLevel = 0; + barrier->subresourceRange.levelCount = 1; + barrier->subresourceRange.baseArrayLayer = 0; + barrier->subresourceRange.layerCount = 1; + } + + vkCmdPipelineBarrier(ctx->cmd_buf, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + 0, NULL, + 0, NULL, + n_attachments, barriers); + free(barriers); + } + + vkEndCommandBuffer(ctx->cmd_buf); + + if (vkQueueSubmit(ctx->queue, 1, &submit_info, VK_NULL_HANDLE) != VK_SUCCESS) { + fprintf(stderr, "Failed to submit queue.\n"); + } + + if (!semaphores) + vkQueueWaitIdle(ctx->queue); +} + +void +vk_clear_color(struct vk_ctx *ctx, + struct vk_buf *vbo, + struct vk_renderer *renderer, + float *vk_fb_color, + uint32_t vk_fb_color_count, + struct vk_semaphores *semaphores, + bool has_wait, bool has_signal, + struct vk_image_att *attachments, + uint32_t n_attachments, + float x, float y, + float w, float h) +{ + VkCommandBufferBeginInfo cmd_begin_info; + VkRenderPassBeginInfo rp_begin_info; + VkRect2D rp_area; + VkClearValue clear_values[2]; + VkSubmitInfo submit_info; + VkPipelineStageFlagBits stage_flags; + VkImageSubresourceRange img_range; + + assert(vk_fb_color_count == 4); + + /* VkCommandBufferBeginInfo */ + memset(&cmd_begin_info, 0, sizeof cmd_begin_info); + cmd_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + cmd_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + /* VkRect2D render area */ + memset(&rp_area, 0, sizeof rp_area); + rp_area.extent.width = (uint32_t)w; + rp_area.extent.height = (uint32_t)h; + rp_area.offset.x = x; + rp_area.offset.y = y; + + /* VkClearValue */ + memset(&clear_values[0], 0, sizeof clear_values[0]); + clear_values[0].color.float32[0] = vk_fb_color[0]; /* red */ + clear_values[0].color.float32[1] = vk_fb_color[1]; /* green */ + clear_values[0].color.float32[2] = vk_fb_color[2]; /* blue */ + clear_values[0].color.float32[3] = vk_fb_color[3]; /* alpha */ + + memset(&clear_values[1], 0, sizeof clear_values[1]); + clear_values[1].depthStencil.depth = 1.0; + clear_values[1].depthStencil.stencil = 0; + + /* VkRenderPassBeginInfo */ + memset(&rp_begin_info, 0, sizeof rp_begin_info); + rp_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rp_begin_info.renderPass = renderer->renderpass; + rp_begin_info.framebuffer = renderer->fb; + rp_begin_info.renderArea = rp_area; + rp_begin_info.clearValueCount = 2; + rp_begin_info.pClearValues = clear_values; + + /* VkSubmitInfo */ + stage_flags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; + + memset(&submit_info, 0, sizeof submit_info); + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = &ctx->cmd_buf; + + /* FIXME */ + if (has_wait) { + submit_info.pWaitDstStageMask = &stage_flags; + submit_info.waitSemaphoreCount = 1; + submit_info.pWaitSemaphores = &semaphores->frame_done; + } + + if (has_signal) { + submit_info.signalSemaphoreCount = 1; + submit_info.pSignalSemaphores = &semaphores->frame_ready; + } + + img_range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + img_range.baseMipLevel = 0; + img_range.levelCount = 1; + img_range.baseArrayLayer = 0; + img_range.layerCount = 1; + + vkBeginCommandBuffer(ctx->cmd_buf, &cmd_begin_info); + vk_transition_image_layout(&attachments[0], + ctx->cmd_buf, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_GENERAL, + VK_QUEUE_FAMILY_EXTERNAL, + ctx->qfam_idx); + vkCmdClearColorImage(ctx->cmd_buf, + attachments[0].obj.img, + VK_IMAGE_LAYOUT_GENERAL, + &clear_values[0].color, + 1, + &img_range); + + vkCmdBeginRenderPass(ctx->cmd_buf, &rp_begin_info, VK_SUBPASS_CONTENTS_INLINE); + + viewport.x = x; + viewport.y = y; + viewport.width = w; + viewport.height = h; + + scissor.offset.x = x; + scissor.offset.y = y; + scissor.extent.width = w; + scissor.extent.height = h; + + vkCmdSetViewport(ctx->cmd_buf, 0, 1, &viewport); + vkCmdSetScissor(ctx->cmd_buf, 0, 1, &scissor); + + vkCmdBindPipeline(ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, renderer->pipeline); + + vkCmdEndRenderPass(ctx->cmd_buf); if (attachments) { VkImageMemoryBarrier *barriers = calloc(n_attachments, sizeof(VkImageMemoryBarrier)); VkImageMemoryBarrier *barrier = barriers; + for (uint32_t n = 0; n < n_attachments; n++, barrier++) { struct vk_image_att *att = &attachments[n]; @@ -1353,6 +1678,8 @@ vk_draw(struct vk_ctx *ctx, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; barrier->newLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier->srcAccessMask = get_access_mask(barrier->oldLayout); + barrier->dstAccessMask = get_access_mask(barrier->newLayout); barrier->srcQueueFamilyIndex = ctx->qfam_idx; barrier->dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL; barrier->image = att->obj.img; @@ -1366,7 +1693,7 @@ vk_draw(struct vk_ctx *ctx, } vkCmdPipelineBarrier(ctx->cmd_buf, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, @@ -1375,22 +1702,21 @@ vk_draw(struct vk_ctx *ctx, free(barriers); } - vkCmdEndRenderPass(ctx->cmd_buf); vkEndCommandBuffer(ctx->cmd_buf); if (vkQueueSubmit(ctx->queue, 1, &submit_info, VK_NULL_HANDLE) != VK_SUCCESS) { fprintf(stderr, "Failed to submit queue.\n"); } - if (!semaphores) + if (!semaphores && !has_wait && !has_signal) vkQueueWaitIdle(ctx->queue); } void vk_copy_image_to_buffer(struct vk_ctx *ctx, - struct vk_image_att *src_img, - struct vk_buf *dst_bo, - float w, float h) + struct vk_image_att *src_img, + struct vk_buf *dst_bo, + float w, float h) { VkCommandBufferBeginInfo cmd_begin_info; VkSubmitInfo submit_info; @@ -1409,11 +1735,11 @@ vk_copy_image_to_buffer(struct vk_ctx *ctx, vkBeginCommandBuffer(ctx->cmd_buf, &cmd_begin_info); if (src_img->props.end_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && dst_bo) { vk_transition_image_layout(src_img, - ctx->cmd_buf, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_QUEUE_FAMILY_EXTERNAL, - ctx->qfam_idx); + ctx->cmd_buf, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_QUEUE_FAMILY_EXTERNAL, + ctx->qfam_idx); /* copy image to buf */ VkBufferImageCopy copy_region = { @@ -1421,7 +1747,8 @@ vk_copy_image_to_buffer(struct vk_ctx *ctx, .bufferRowLength = w, .bufferImageHeight = h, .imageSubresource = { - .aspectMask = aspect_mask ? aspect_mask : VK_IMAGE_ASPECT_COLOR_BIT, + .aspectMask = aspect_mask ? aspect_mask + : VK_IMAGE_ASPECT_COLOR_BIT, .mipLevel = 0, .baseArrayLayer = 0, .layerCount = 1, @@ -1431,16 +1758,16 @@ vk_copy_image_to_buffer(struct vk_ctx *ctx, }; vkCmdCopyImageToBuffer(ctx->cmd_buf, - src_img->obj.img, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - dst_bo->buf, 1, ©_region); + src_img->obj.img, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + dst_bo->buf, 1, ©_region); vk_transition_image_layout(src_img, - ctx->cmd_buf, - VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_QUEUE_FAMILY_EXTERNAL, - ctx->qfam_idx); + ctx->cmd_buf, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_QUEUE_FAMILY_EXTERNAL, + ctx->qfam_idx); VkBufferMemoryBarrier write_finish_buffer_memory_barrier = { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, @@ -1454,12 +1781,12 @@ vk_copy_image_to_buffer(struct vk_ctx *ctx, }; vkCmdPipelineBarrier(ctx->cmd_buf, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_HOST_BIT, - (VkDependencyFlags) 0, 0, NULL, - 1, &write_finish_buffer_memory_barrier, - 0, NULL); - } + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_HOST_BIT, + (VkDependencyFlags) 0, 0, NULL, + 1, &write_finish_buffer_memory_barrier, + 0, NULL); + } vkEndCommandBuffer(ctx->cmd_buf); if (vkQueueSubmit(ctx->queue, 1, &submit_info, VK_NULL_HANDLE) != VK_SUCCESS) { @@ -1468,6 +1795,7 @@ vk_copy_image_to_buffer(struct vk_ctx *ctx, vkQueueWaitIdle(ctx->queue); } +// FIXME: external bool vk_create_semaphores(struct vk_ctx *ctx, struct vk_semaphores *semaphores) @@ -1529,12 +1857,13 @@ vk_transition_image_layout(struct vk_image_att *img_att, barrier.srcQueueFamilyIndex = src_queue_fam_idx; barrier.dstQueueFamilyIndex = dst_queue_fam_idx; barrier.image = img_att->obj.img; - barrier.subresourceRange.aspectMask = aspect_mask ? aspect_mask : VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.aspectMask = aspect_mask ? aspect_mask : + VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.layerCount = 1; vkCmdPipelineBarrier(cmd_buf, - get_pipeline_stage_flags(old_layout), - get_pipeline_stage_flags(new_layout), - 0, 0, VK_NULL_HANDLE, 0, VK_NULL_HANDLE, 1, &barrier); + get_pipeline_stage_flags(old_layout), + get_pipeline_stage_flags(new_layout), + 0, 0, VK_NULL_HANDLE, 0, VK_NULL_HANDLE, 1, &barrier); } diff --git a/src/vk.h b/src/vk.h index 97496b8..f28930f 100644 --- a/src/vk.h +++ b/src/vk.h @@ -10,7 +10,6 @@ struct vk_ctx VkInstance inst; VkPhysicalDevice pdev; VkDevice dev; - VkPipelineCache cache; VkCommandPool cmd_pool; VkCommandBuffer cmd_buf; @@ -38,6 +37,8 @@ struct vk_image_props VkImageLayout in_layout; VkImageLayout end_layout; + + bool need_export; }; struct vk_mem_obj { @@ -48,12 +49,7 @@ struct vk_mem_obj { struct vk_image_obj { VkImage img; - struct vk_mem_obj mobj; -}; - -struct vk_buf -{ - VkBuffer buf; + VkImageView img_view; struct vk_mem_obj mobj; }; @@ -70,6 +66,13 @@ struct vk_vertex_info VkPrimitiveTopology topology; }; +struct vk_buf +{ + VkBuffer buf; + struct vk_mem_obj mobj; +}; + + struct vk_renderer { VkPipeline pipeline; @@ -120,15 +123,16 @@ vk_fill_ext_image_props(struct vk_ctx *ctx, uint32_t num_layers, VkFormat format, VkImageTiling tiling, - VkImageUsageFlagBits usage, VkImageLayout in_layout, VkImageLayout end_layout, + bool need_export, struct vk_image_props *props); /* buffers */ bool vk_create_buffer(struct vk_ctx *ctx, + bool is_external, uint32_t sz, VkBufferUsageFlagBits usage, void *pnext, @@ -142,6 +146,13 @@ vk_update_buffer_data(struct vk_ctx *ctx, uint32_t data_sz, struct vk_buf *bo); +bool +vk_create_ext_buffer(struct vk_ctx *ctx, + uint32_t sz, + VkBufferUsageFlagBits usage, + struct vk_buf *bo); + + /* semaphores */ bool @@ -183,6 +194,18 @@ vk_draw(struct vk_ctx *ctx, uint32_t n_attachments, float x, float y, float w, float h); +void +vk_clear_color(struct vk_ctx *ctx, + struct vk_buf *vbo, + struct vk_renderer *renderer, + float *vk_fb_color, + uint32_t vk_fb_color_count, + struct vk_semaphores *semaphores, + bool has_wait, bool has_signal, + struct vk_image_att *attachments, + uint32_t n_attachments, + float x, float y, float w, float h); + /* transitions */ void -- 1.7.10.4