@@ -63,6 +63,10 @@ VkRenderPass gaussRenderPass;
6363VkRenderPass gaussRenderPassFinal;
6464VkSampler linearSampler;
6565
66+ VulkanPipeline computePipeline;
67+ VkDescriptorSetLayout computeDescriptorSetLayout;
68+ VkDescriptorSet computeDescriptorSets[FRAMES_IN_FLIGHT];
69+
6670VkQueryPool timestampQueryPools[FRAMES_IN_FLIGHT];
6771
6872VkDescriptorPool imguiDescriptorPool;
@@ -224,7 +228,7 @@ void initApplication(SDL_Window* window) {
224228 context = initVulkan (instanceExtensionCount, enabledInstanceExtensions, ARRAY_COUNT (enabledDeviceExtensions), enabledDeviceExtensions);
225229
226230 SDL_Vulkan_CreateSurface (window, context->instance , &surface);
227- swapchain = createSwapchain (context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
231+ swapchain = createSwapchain (context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT );
228232
229233 recreateRenderPass ();
230234
@@ -313,9 +317,10 @@ void initApplication(SDL_Window* window) {
313317 VkDescriptorPoolSize poolSizes[] = {
314318 {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, FRAMES_IN_FLIGHT},
315319 {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, FRAMES_IN_FLIGHT},
320+ {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, FRAMES_IN_FLIGHT},
316321 };
317322 VkDescriptorPoolCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO};
318- createInfo.maxSets = FRAMES_IN_FLIGHT;
323+ createInfo.maxSets = FRAMES_IN_FLIGHT * 2 ;
319324 createInfo.poolSizeCount = ARRAY_COUNT (poolSizes);
320325 createInfo.pPoolSizes = poolSizes;
321326 VKA (vkCreateDescriptorPool (context->device , &createInfo, 0 , &modelDescriptorPool));
@@ -558,6 +563,24 @@ void initApplication(SDL_Window* window) {
558563 VKA (vkDeviceWaitIdle (context->device ));
559564 ImGui_ImplVulkan_DestroyFontUploadObjects ();
560565 }
566+
567+ {
568+ VkDescriptorSetLayoutBinding bindings[] = {
569+ {0 , VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1 , VK_SHADER_STAGE_COMPUTE_BIT, 0 },
570+ };
571+ VkDescriptorSetLayoutCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO};
572+ createInfo.bindingCount = ARRAY_COUNT (bindings);
573+ createInfo.pBindings = bindings;
574+ VK (vkCreateDescriptorSetLayout (context->device , &createInfo, 0 , &computeDescriptorSetLayout));
575+ }
576+ for (uint32_t i = 0 ; i < FRAMES_IN_FLIGHT; ++i) {
577+ VkDescriptorSetAllocateInfo allocateInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO};
578+ allocateInfo.descriptorPool = modelDescriptorPool;
579+ allocateInfo.descriptorSetCount = 1 ;
580+ allocateInfo.pSetLayouts = &computeDescriptorSetLayout;
581+ VKA (vkAllocateDescriptorSets (context->device , &allocateInfo, &computeDescriptorSets[i]));
582+ }
583+ computePipeline = createComputePipeline (context, " ../shaders/compute_comp.spv" , 1 , &computeDescriptorSetLayout, 0 , 0 );
561584}
562585
563586void recreateSwapchain () {
@@ -571,7 +594,7 @@ void recreateSwapchain() {
571594
572595
573596 VKA (vkDeviceWaitIdle (context->device ));
574- swapchain = createSwapchain (context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &oldSwapchain);
597+ swapchain = createSwapchain (context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT , &oldSwapchain);
575598
576599 destroySwapchain (context, &oldSwapchain);
577600 recreateRenderPass ();
@@ -747,6 +770,46 @@ void renderApplication() {
747770
748771 VK (vkCmdWriteTimestamp (commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, timestampQueryPools[frameIndex], 1 ));
749772
773+ { // Swapchain Attachment Output -> Compute Write
774+ VkImageSubresourceRange subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0 , 1 , 0 , 1 };
775+ VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
776+ imageBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
777+ imageBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
778+ imageBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
779+ imageBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
780+ imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
781+ imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
782+ imageBarrier.image = swapchain.images [imageIndex];
783+ imageBarrier.subresourceRange = subresourceRange;
784+ vkCmdPipelineBarrier (commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0 , 0 , 0 , 0 , 0 , 1 , &imageBarrier);
785+ }
786+
787+ vkCmdBindPipeline (commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipeline );
788+ imageInfo = {0 , swapchain.imageViews [imageIndex], VK_IMAGE_LAYOUT_GENERAL};
789+ descriptorWrite = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET};
790+ descriptorWrite.dstSet = computeDescriptorSets[frameIndex];
791+ descriptorWrite.dstBinding = 0 ;
792+ descriptorWrite.descriptorCount = 1 ;
793+ descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
794+ descriptorWrite.pImageInfo = &imageInfo;
795+ vkUpdateDescriptorSets (context->device , 1 , &descriptorWrite, 0 , 0 );
796+ vkCmdBindDescriptorSets (commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline.pipelineLayout , 0 , 1 , &computeDescriptorSets[frameIndex], 0 , 0 );
797+ vkCmdDispatch (commandBuffer, (swapchain.width + 7 ) / 8 , (swapchain.height + 7 ) / 8 , 1 );
798+
799+ { // Swapchain Compute Write -> Present
800+ VkImageSubresourceRange subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0 , 1 , 0 , 1 };
801+ VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
802+ imageBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
803+ imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
804+ imageBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
805+ imageBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
806+ imageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
807+ imageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
808+ imageBarrier.image = swapchain.images [imageIndex];
809+ imageBarrier.subresourceRange = subresourceRange;
810+ vkCmdPipelineBarrier (commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0 , 0 , 0 , 0 , 0 , 1 , &imageBarrier);
811+ }
812+
750813 VKA (vkEndCommandBuffer (commandBuffer));
751814 }
752815
@@ -802,6 +865,7 @@ void shutdownApplication() {
802865 VK (vkDestroyDescriptorSetLayout (context->device , spriteDescriptorLayout, 0 ));
803866 VK (vkDestroyDescriptorPool (context->device , gaussDescriptorPool, 0 ));
804867 VK (vkDestroyDescriptorSetLayout (context->device , gaussDescriptorSetLayout, 0 ));
868+ VK (vkDestroyDescriptorSetLayout (context->device , computeDescriptorSetLayout, 0 ));
805869 destroyBuffer (context, &spriteVertexBuffer);
806870 destroyBuffer (context, &spriteIndexBuffer);
807871 destroyImage (context, &image);
@@ -819,6 +883,7 @@ void shutdownApplication() {
819883 destroyPipeline (context, &modelPipeline);
820884 destroyPipeline (context, &gaussPipelineHorizontal);
821885 destroyPipeline (context, &gaussPipelineVertical);
886+ destroyPipeline (context, &computePipeline);
822887
823888 vkDestroySampler (context->device , sampler, 0 );
824889 vkDestroySampler (context->device , linearSampler, 0 );
0 commit comments