From ba7d9abe25121527e2cb8c99f383641df5276dde Mon Sep 17 00:00:00 2001 From: mittorn Date: Tue, 29 Oct 2024 06:12:52 +0300 Subject: [PATCH] Separate reconstruction framebuffer --- vkplayer.cpp | 312 +++++++++++++++++++++++++++++++------------ vulkan_contructors.h | 5 + 2 files changed, 235 insertions(+), 82 deletions(-) diff --git a/vkplayer.cpp b/vkplayer.cpp index 9acf491..07eedde 100644 --- a/vkplayer.cpp +++ b/vkplayer.cpp @@ -24,7 +24,7 @@ extern "C" { // todo: REMOVE THIS. Why "simpliest triangle" demos even use this???? // It does not "HELP" drawing 2D triangle!!! It is not useful in engines using own matrix transform code! //#include -#define MAX_SWAPCHAIN_IMAGES 32 +#define MAX_SWAPCHAIN_IMAGES 8 // workaround for ffmpeg stable api nonsence with incompatible pointers between versions struct PointerWrap { @@ -47,8 +47,6 @@ struct Vertex struct DecoderImage { - VkSamplerYcbcrConversion ycbcr_sampler_conversion; - VkSampler ycbcr_sampler; VkImage image; VkDeviceMemory image_memory; // todo: deduplicate shared parameters @@ -59,7 +57,7 @@ struct DecoderImage }; -void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image) +void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image, const VkSamplerYcbcrConversionInfo &ycbcr_info) { CallWith(Image2dInfo(VK_IMAGE_USAGE_SAMPLED_BIT, VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, 1920, 1080, @@ -97,31 +95,7 @@ void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image $F(bindInfo[1], $(image) = image.image, $(memory) = image.image_memory, $(memoryOffset) = image.memory_offset_plane1); PFN_vkBindImageMemory2 pvkBindImageMemory2 = (PFN_vkBindImageMemory2)vkGetInstanceProcAddr(inst, "vkBindImageMemory2KHR"); pvkBindImageMemory2(dev.device, 2, bindInfo); - PFN_vkCreateSamplerYcbcrConversion pvkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)vkGetInstanceProcAddr(inst, "vkCreateSamplerYcbcrConversionKHR"); - - CallWith($M(VkSamplerYcbcrConversionCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO}, - $(format) = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, - $(ycbcrModel) = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY, - $(ycbcrRange) = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, - $(xChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN, // zero - $(yChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN, - $(chromaFilter) = VK_FILTER_NEAREST), // zero - pvkCreateSamplerYcbcrConversion(dev.device, &ref, NULL, &image.ycbcr_sampler_conversion)); - - $Sc ycbcr_info = $M(VkSamplerYcbcrConversionInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO}, - $(conversion) = image.ycbcr_sampler_conversion); - CallWith($M(VkSamplerCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, &ycbcr_info}, - $(magFilter) = VK_FILTER_NEAREST, - $(minFilter) = VK_FILTER_NEAREST, - $(mipmapMode) = VK_SAMPLER_MIPMAP_MODE_NEAREST, // zero - $(addressModeU) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - $(addressModeV) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - $(addressModeW) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - $(maxLod) = 1.0f, - $(borderColor) = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK), - vkCreateSampler(dev.device, &ref, NULL, &image.ycbcr_sampler); - ); CallWith($M(VkImageViewCreateInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &ycbcr_info}, $(image) = image.image, $(viewType) = VK_IMAGE_VIEW_TYPE_2D, $(format) = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, @@ -145,6 +119,8 @@ void CreateSoftwareImage(VkInstance inst, VulkanDevice &dev, DecoderImage &image static struct FFmpegDecoder { DecoderImage images[MAX_DECODER_FRAMES]; + VkSamplerYcbcrConversion ycbcr_sampler_conversion; + VkSampler ycbcr_sampler; // todo: align thread-shared data to unshare with immutable volatile int decode_index, present_index; pthread_t thread = 0; @@ -227,8 +203,33 @@ static void *DecoderThread(void*) static void SetupFFMpeg(VkInstance inst, VulkanDevice &dev) { + PFN_vkCreateSamplerYcbcrConversion pvkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)vkGetInstanceProcAddr(inst, "vkCreateSamplerYcbcrConversionKHR"); + + + CallWith($M(VkSamplerYcbcrConversionCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO}, + $(format) = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, + $(ycbcrModel) = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY, + $(ycbcrRange) = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, + $(xChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN, // zero + $(yChromaOffset) = VK_CHROMA_LOCATION_COSITED_EVEN, + $(chromaFilter) = VK_FILTER_NEAREST), // zero + pvkCreateSamplerYcbcrConversion(dev.device, &ref, NULL, &gFF.ycbcr_sampler_conversion)); + + $Sc ycbcr_info = $M(VkSamplerYcbcrConversionInfo{VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO}, + $(conversion) = gFF.ycbcr_sampler_conversion); + CallWith($M(VkSamplerCreateInfo{VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, &ycbcr_info}, + $(magFilter) = VK_FILTER_NEAREST, + $(minFilter) = VK_FILTER_NEAREST, + $(mipmapMode) = VK_SAMPLER_MIPMAP_MODE_NEAREST, // zero + $(addressModeU) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + $(addressModeV) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + $(addressModeW) = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + $(maxLod) = 1.0f, + $(borderColor) = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK), + vkCreateSampler(dev.device, &ref, NULL, &gFF.ycbcr_sampler); + ); for(int i = 0; i < MAX_DECODER_FRAMES; i++) - CreateSoftwareImage(inst, dev, gFF.images[i]); + CreateSoftwareImage(inst, dev, gFF.images[i], ycbcr_info); pthread_mutex_init(&gFF.mutex, NULL); pthread_cond_init(&gFF.cond, NULL); pthread_create(&gFF.thread, NULL, &DecoderThread, NULL); @@ -240,7 +241,7 @@ static void SetupFFMpeg(VkInstance inst, VulkanDevice &dev) struct GraphicsApplicationPipeline: BaseVulkanPipeline { - void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers) + void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers, int count) { device = dev; @@ -248,9 +249,9 @@ struct GraphicsApplicationPipeline: BaseVulkanPipeline //BasicBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,1,VK_SHADER_STAGE_VERTEX_BIT) BasicBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,1,VK_SHADER_STAGE_FRAGMENT_BIT, pImmutableSamplers) ); - CreatePool(1, + CreatePool(count, //BasicPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1) - BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1) + BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, count) ); VkShaderModule vp, fp; CreateGraphicsPipeline(renderPass, @@ -282,7 +283,7 @@ struct GraphicsApplicationPipeline: BaseVulkanPipeline struct ComputeApplicationPipeline: BaseVulkanPipeline { - void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers, int count) + void Init(VkDevice dev, VkRenderPass renderPass, VkSampler *pImmutableSamplers, int count1, int count2, int count3) { device = dev; @@ -290,9 +291,9 @@ struct ComputeApplicationPipeline: BaseVulkanPipeline BasicBinding(0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,1,VK_SHADER_STAGE_COMPUTE_BIT, pImmutableSamplers), BasicBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,1,VK_SHADER_STAGE_COMPUTE_BIT) ); - CreatePool(count, - BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, count), - BasicPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, count)); + CreatePool((count1 + count3) * count2, + BasicPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, count2 * count3), + BasicPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, count3 * count2 * count1)); VkShaderModule shader; CreateComputePipeline(ShaderFromFile(shader, "quad.comp.spv", VK_SHADER_STAGE_COMPUTE_BIT)); // todo: should not we destroy shader internally? @@ -311,15 +312,27 @@ struct GraphicsApplication VulkanContext context; VulkanDevice dev; GLFWwindow *window = NULL; + + // swapchain stuff VkSwapchainKHR swapchain; VkSurfaceKHR surface; VkImage swapchainImages[MAX_SWAPCHAIN_IMAGES]; unsigned int numSwapchainImages; VulkanFramebuffer swapchainFbs[MAX_SWAPCHAIN_IMAGES]; - VkCommandBuffer commandBuffers[MAX_SWAPCHAIN_IMAGES * RECONSTRUCTION_TARGET_FRAMES]; - VkCommandBuffer reconstructionCommandBuffers[MAX_DECODER_FRAMES * RECONSTRUCTION_TARGET_FRAMES]; VkFence chainFences[MAX_SWAPCHAIN_IMAGES]; VkSemaphore swapchainRenderSemaphore[MAX_SWAPCHAIN_IMAGES], swapchainPresentSemaphore[MAX_SWAPCHAIN_IMAGES]; + + // direct reconstruction to swapchain + VkCommandBuffer commandBuffers[MAX_SWAPCHAIN_IMAGES * MAX_DECODER_FRAMES]; + + // reconstruction to temporary framebuffer + VulkanFramebuffer reconstructionFbs[RECONSTRUCTION_TARGET_FRAMES]; + VkImage reconstructionImages[RECONSTRUCTION_TARGET_FRAMES]; + VkDeviceMemory reconstructionImagesMem[RECONSTRUCTION_TARGET_FRAMES]; + VkCommandBuffer reconstructionCommandBuffers[MAX_DECODER_FRAMES * RECONSTRUCTION_TARGET_FRAMES]; + VkCommandBuffer presentCommandBuffers[MAX_SWAPCHAIN_IMAGES * RECONSTRUCTION_TARGET_FRAMES]; + VkSemaphore reconstructionSemaphore[RECONSTRUCTION_TARGET_FRAMES]; + struct UBO { //glm::mat4 transformationMatrix; @@ -328,7 +341,9 @@ struct GraphicsApplication GraphicsApplicationPipeline graphicsPipeline; ComputeApplicationPipeline computePipeline; VkDescriptorSet descriptorSet; - VkDescriptorSet descriptorSets[MAX_SWAPCHAIN_IMAGES]; + VkDescriptorSet swapchainDescriptorSets[MAX_SWAPCHAIN_IMAGES*MAX_DECODER_FRAMES]; + VkDescriptorSet reconstructionDescriptorSets[RECONSTRUCTION_TARGET_FRAMES*MAX_DECODER_FRAMES]; + VkDescriptorSet decodeDescriptorSet[MAX_DECODER_FRAMES]; VulkanBuffer uboBuf; VulkanBuffer stagingVert; VulkanBuffer stagingInd; @@ -378,7 +393,7 @@ struct GraphicsApplication $(imageColorSpace) = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, $(imageExtent) = VkExtent2D{width, height}, $(imageArrayLayers),$(queueFamilyIndexCount),$(clipped), - $(imageUsage) = graphics?VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:VK_IMAGE_USAGE_STORAGE_BIT, + $(imageUsage) = VK_IMAGE_USAGE_TRANSFER_DST_BIT | (graphics?VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:VK_IMAGE_USAGE_STORAGE_BIT), $(pQueueFamilyIndices) = &dev.defaultFamilyIndex, $(preTransform) = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, $(compositeAlpha) = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR, @@ -468,7 +483,8 @@ struct GraphicsApplication #else #define ENABLE_VALIDATION_LAYERS 0 #endif - bool compute = true; + bool compute = false; + bool separateReconstruction = false; context.Create("streamingengine", "vulkan-playground-server", ENABLE_VALIDATION_LAYERS); dev.Create(context.FindPhysicalDevice(), compute?VK_QUEUE_COMPUTE_BIT : VK_QUEUE_GRAPHICS_BIT); dev.CreateDevice(context); @@ -476,24 +492,73 @@ struct GraphicsApplication int height = 1080; CreateWindow("demo", width, height, false); CreateSwapchain(width,height, !compute); + printf("%d swapchain images\n", numSwapchainImages); dev.CreateAndMap(uboBuf, sizeof(UBO)); SetupFFMpeg(context.instance, dev); + for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++) + { + VkSemaphoreCreateInfo semaphoreCreateInfo = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO}; + VK_CHECK_RESULT(vkCreateSemaphore(dev.device, &semaphoreCreateInfo, nullptr, &reconstructionSemaphore[i])); + CallWith(Image2dInfo(VK_IMAGE_USAGE_STORAGE_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_FORMAT_B8G8R8A8_UNORM, width, height), + vkCreateImage(dev.device, &ref,NULL, &reconstructionImages[i])); + + VkMemoryRequirements mem_reqs; + vkGetImageMemoryRequirements(dev.device, reconstructionImages[i], &mem_reqs); + + VkMemoryAllocateInfo mem_alloc = AllocateInfo(mem_reqs.size); + + if (!dev.GetMemoryType(mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + &mem_alloc.memoryTypeIndex)) + printf("Could not find memory type.\n"); + + VK_CHECK_RESULT(vkAllocateMemory(dev.device, &mem_alloc, NULL, &reconstructionImagesMem[i])); + VK_CHECK_RESULT(vkBindImageMemory(dev.device, reconstructionImages[i], reconstructionImagesMem[i], 0)); + } if(compute) { - computePipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.images[0].ycbcr_sampler, numSwapchainImages); + computePipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.ycbcr_sampler, numSwapchainImages, MAX_DECODER_FRAMES, RECONSTRUCTION_TARGET_FRAMES); for(int i = 0; i < numSwapchainImages; i++) { - descriptorSets[i] = computePipeline.AllocateSingleDescriptorSet(); - computePipeline.UpdateDescriptors(descriptorSets[i], gFF.images[0].image_view, gFF.images[0].ycbcr_sampler, swapchainFbs[i].color_view); + for(int j = 0; j < MAX_DECODER_FRAMES; j++) + { + int ci = MAX_DECODER_FRAMES * i + j; + swapchainDescriptorSets[ci] = computePipeline.AllocateSingleDescriptorSet(); + computePipeline.UpdateDescriptors(swapchainDescriptorSets[ci], gFF.images[j].image_view, gFF.ycbcr_sampler, swapchainFbs[i].color_view); + } + } + for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++) + { + CallWith($M(VkImageViewCreateInfo{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO}, + $(image) = reconstructionImages[i], $(viewType) = VK_IMAGE_VIEW_TYPE_2D, + $(format) = VK_FORMAT_B8G8R8A8_UNORM, + $(subresourceRange) = SubresourceRange()), + vkCreateImageView(dev.device, &ref, NULL, &reconstructionFbs[i].color_view)); + + for(int j = 0; j < MAX_DECODER_FRAMES; j++) + { + int ci = MAX_DECODER_FRAMES * i + j; + reconstructionDescriptorSets[ci] = computePipeline.AllocateSingleDescriptorSet(); + computePipeline.UpdateDescriptors(reconstructionDescriptorSets[ci], gFF.images[j].image_view, gFF.ycbcr_sampler, reconstructionFbs[i].color_view); + } } } else { - graphicsPipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.images[0].ycbcr_sampler); - descriptorSet = graphicsPipeline.AllocateSingleDescriptorSet(); - graphicsPipeline.UpdateDescriptors(descriptorSet, gFF.images[0].image_view, gFF.images[0].ycbcr_sampler); + graphicsPipeline.Init(dev.device, swapchainFbs[0].render_pass, &gFF.ycbcr_sampler, MAX_DECODER_FRAMES); + for(int j = 0; j < MAX_DECODER_FRAMES; j++) + { + decodeDescriptorSet[j] = graphicsPipeline.AllocateSingleDescriptorSet(); + graphicsPipeline.UpdateDescriptors(decodeDescriptorSet[j], gFF.images[j].image_view, gFF.ycbcr_sampler); + } + for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++) + { + reconstructionFbs[i].Create(dev.device); + reconstructionFbs[i].CreateDepthAttachment(dev,VK_FORMAT_D32_SFLOAT, width, height); + reconstructionFbs[i].Init(reconstructionImages[i],VK_FORMAT_B8G8R8A8_UNORM, width, height); + } } - updateUniformData(); + /*updateUniformData(); Vertex vertices[] = { { { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f } }, @@ -505,60 +570,143 @@ struct GraphicsApplication dev.CreateBuffer(stagingVert, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, sizeof(vertices), vertices); dev.CreateBuffer(stagingInd, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, sizeof(indices), indices); + */ for(int i = 0; i < numSwapchainImages; i++) { - commandBuffers[i] = dev.CreateCommandBuffer(); - //VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); - //vkCmdClearColorImage(commandBuffers[i], swapchainImages[i],VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, &color, 1, &range ); - if(!compute) + for(int j = 0; j < MAX_DECODER_FRAMES; j++) { - swapchainFbs[i].BeginRenderPass(commandBuffers[i]); - swapchainFbs[i].SetViewportAndScissor(commandBuffers[i]); + int ci = MAX_DECODER_FRAMES * i + j; + commandBuffers[ci] = dev.CreateCommandBuffer(); + //VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + //vkCmdClearColorImage(commandBuffers[i], swapchainImages[i],VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, &color, 1, &range ); + if(!compute) + { + swapchainFbs[i].BeginRenderPass(commandBuffers[ci]); + swapchainFbs[i].SetViewportAndScissor(commandBuffers[ci]); - vkCmdBindDescriptorSets(commandBuffers[i],VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); - vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipeline); - // VkDeviceSize offset = 0; - //vkCmdBindVertexBuffers(commandBuffers[i],0, 1, &stagingVert.buffer, &offset); - //vkCmdBindIndexBuffer(commandBuffers[i], stagingInd.buffer, 0, VK_INDEX_TYPE_UINT32); - //vkCmdDrawIndexed(commandBuffers[i], 3, 1, 0, 0, 0); - vkCmdDraw(commandBuffers[i], 4, 1, 0, 0); - vkCmdEndRenderPass(commandBuffers[i]); - VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + vkCmdBindDescriptorSets(commandBuffers[ci],VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipelineLayout, 0, 1, &decodeDescriptorSet[j], 0, nullptr); + vkCmdBindPipeline(commandBuffers[ci], VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipeline); + // VkDeviceSize offset = 0; + //vkCmdBindVertexBuffers(commandBuffers[i],0, 1, &stagingVert.buffer, &offset); + //vkCmdBindIndexBuffer(commandBuffers[i], stagingInd.buffer, 0, VK_INDEX_TYPE_UINT32); + //vkCmdDrawIndexed(commandBuffers[i], 3, 1, 0, 0, 0); + vkCmdDraw(commandBuffers[ci], 4, 1, 0, 0); + vkCmdEndRenderPass(commandBuffers[ci]); + VulkanTexture::SetImageLayout(commandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + } + else + { + const int WIDTH = 1920; // Size of rendered mandelbrot set. + const int HEIGHT = 1080; // Size of renderered mandelbrot set. + const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader. + VulkanTexture::SetImageLayout(commandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + vkCmdBindPipeline(commandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipeline); + vkCmdBindDescriptorSets(commandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipelineLayout, 0, 1, &swapchainDescriptorSets[ci], 0, NULL); + vkCmdDispatch(commandBuffers[ci], (uint32_t)ceil(WIDTH / float(WORKGROUP_SIZE)), (uint32_t)ceil(HEIGHT / float(WORKGROUP_SIZE)), 1); + VulkanTexture::SetImageLayout(commandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + } + vkEndCommandBuffer(commandBuffers[ci]); } - else - { - const int WIDTH = 1920; // Size of rendered mandelbrot set. - const int HEIGHT = 1080; // Size of renderered mandelbrot set. - const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader. - VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); - vkCmdBindPipeline(commandBuffers[i], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipeline); - vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipelineLayout, 0, 1, &descriptorSets[i], 0, NULL); - vkCmdDispatch(commandBuffers[i], (uint32_t)ceil(WIDTH / float(WORKGROUP_SIZE)), (uint32_t)ceil(HEIGHT / float(WORKGROUP_SIZE)), 1); - VulkanTexture::SetImageLayout(commandBuffers[i], swapchainImages[i], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); - } - vkEndCommandBuffer(commandBuffers[i]); VK_CHECK_RESULT(CallWith(FenceInfo(VK_FENCE_CREATE_SIGNALED_BIT), vkCreateFence(dev.device, &ref, NULL, &chainFences[i]))); } + for(int i = 0; i < numSwapchainImages; i++) + { + for(int j = 0; j < RECONSTRUCTION_TARGET_FRAMES; j++) + { + int ci = RECONSTRUCTION_TARGET_FRAMES*i+j; + presentCommandBuffers[ci] = dev.CreateCommandBuffer(); + //VulkanTexture::SetImageLayout(presentCommandBuffers[ci], reconstructionImages[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + VulkanTexture::SetImageLayout(presentCommandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + VkImageCopy regions = $M(VkImageCopy{}, $(srcSubresource) = SubresourceLayers(), $(dstSubresource) = SubresourceLayers(), $(extent) = VkExtent3D{1920, 1080, 1}); + vkCmdCopyImage(presentCommandBuffers[ci], reconstructionImages[j],VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, swapchainImages[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ions); + VulkanTexture::SetImageLayout(presentCommandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + vkEndCommandBuffer(presentCommandBuffers[ci]); + } + } + for(int i = 0; i < RECONSTRUCTION_TARGET_FRAMES; i++) + { + for(int j = 0; j < MAX_DECODER_FRAMES; j++) + { + int ci = RECONSTRUCTION_TARGET_FRAMES*i+j; + reconstructionCommandBuffers[ci] = dev.CreateCommandBuffer(); + if(!compute) + { + VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + + reconstructionFbs[i].BeginRenderPass(reconstructionCommandBuffers[ci]); + reconstructionFbs[i].SetViewportAndScissor(reconstructionCommandBuffers[ci]); + + vkCmdBindDescriptorSets(reconstructionCommandBuffers[ci],VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipelineLayout, 0, 1, &decodeDescriptorSet[j], 0, nullptr); + vkCmdBindPipeline(reconstructionCommandBuffers[ci], VK_PIPELINE_BIND_POINT_GRAPHICS,graphicsPipeline.pipeline); + // VkDeviceSize offset = 0; + //vkCmdBindVertexBuffers(commandBuffers[i],0, 1, &stagingVert.buffer, &offset); + //vkCmdBindIndexBuffer(commandBuffers[i], stagingInd.buffer, 0, VK_INDEX_TYPE_UINT32); + //vkCmdDrawIndexed(commandBuffers[i], 3, 1, 0, 0, 0); + vkCmdDraw(reconstructionCommandBuffers[ci], 4, 1, 0, 0); + vkCmdEndRenderPass(reconstructionCommandBuffers[ci]); + VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + } + else + { + const int WIDTH = 1920; // Size of rendered mandelbrot set. + const int HEIGHT = 1080; // Size of renderered mandelbrot set. + const int WORKGROUP_SIZE = 32; // Workgroup size in compute shader. + //VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], swapchainImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + vkCmdBindPipeline(reconstructionCommandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipeline); + vkCmdBindDescriptorSets(reconstructionCommandBuffers[ci], VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipelineLayout, 0, 1, &reconstructionDescriptorSets[ci], 0, NULL); + vkCmdDispatch(reconstructionCommandBuffers[ci], (uint32_t)ceil(WIDTH / float(WORKGROUP_SIZE)), (uint32_t)ceil(HEIGHT / float(WORKGROUP_SIZE)), 1); + VulkanTexture::SetImageLayout(reconstructionCommandBuffers[ci], reconstructionImages[i], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }); + } + vkEndCommandBuffer(reconstructionCommandBuffers[ci]); + } + } uint32_t idx = 0; int sem_idx = 0; + int ridx = 0; while(true) { updateUniformData(); sem_idx = (sem_idx + 1) % numSwapchainImages; waitFence(sem_idx); idx = AcquireImage(sem_idx); + int decoder_idx = WaitActiveFrame() & 3; VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; vkResetFences(dev.device,1, &chainFences[sem_idx]); - CallWith( - SubmitInfo( - commandBuffers[idx],$(waitSemaphoreCount), $(signalSemaphoreCount), - $(pWaitSemaphores) = &swapchainRenderSemaphore[sem_idx], - $(pSignalSemaphores) = &swapchainPresentSemaphore[idx], - $(pWaitDstStageMask) = &waitDstStageMask), - vkQueueSubmit(dev.defautQueue, 1, &ref, chainFences[sem_idx])); + + if(separateReconstruction) + { + CallWith( + SubmitInfo( + reconstructionCommandBuffers[ridx * MAX_DECODER_FRAMES + decoder_idx],$(waitSemaphoreCount), $(signalSemaphoreCount), + $(pWaitSemaphores) = &swapchainRenderSemaphore[sem_idx], + $(pSignalSemaphores) = &reconstructionSemaphore[ridx], + $(pWaitDstStageMask) = &waitDstStageMask), + vkQueueSubmit(dev.defautQueue, 1, &ref, NULL)); + CallWith( + SubmitInfo( + presentCommandBuffers[idx * RECONSTRUCTION_TARGET_FRAMES + ridx],$(waitSemaphoreCount), $(signalSemaphoreCount), + $(pWaitSemaphores) = &reconstructionSemaphore[ridx], + $(pSignalSemaphores) = &swapchainPresentSemaphore[idx], + $(pWaitDstStageMask) = &waitDstStageMask), + vkQueueSubmit(dev.defautQueue, 1, &ref, chainFences[sem_idx])); + ridx = (ridx + 1) & 3; + } + else + { + CallWith( + SubmitInfo( + commandBuffers[idx*MAX_DECODER_FRAMES + decoder_idx],$(waitSemaphoreCount), $(signalSemaphoreCount), + $(pWaitSemaphores) = &swapchainRenderSemaphore[sem_idx], + $(pSignalSemaphores) = &swapchainPresentSemaphore[idx], + $(pWaitDstStageMask) = &waitDstStageMask), + vkQueueSubmit(dev.defautQueue, 1, &ref, chainFences[sem_idx])); + } + PresentImage(idx); + } vkDeviceWaitIdle(dev.device); graphicsPipeline.Destroy(); diff --git a/vulkan_contructors.h b/vulkan_contructors.h index f7087c7..5cc418c 100644 --- a/vulkan_contructors.h +++ b/vulkan_contructors.h @@ -74,6 +74,11 @@ VkSubresourceLayout SubresourceLayout(VkDeviceSize pitch, const Args&... argumen { return $M(VkSubresourceLayout{0},$(rowPitch) = pitch,arguments...); } +template +VkImageSubresourceLayers SubresourceLayers(const Args&... arguments) +{ + return $M(VkImageSubresourceLayers{VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1}, arguments...); +} VkFenceCreateInfo FenceInfo(VkFenceCreateFlags flags = 0) {