diff --git a/computeshader/computeshader.cpp b/computeshader/computeshader.cpp index b9c7897a..e775b65a 100644 --- a/computeshader/computeshader.cpp +++ b/computeshader/computeshader.cpp @@ -102,10 +102,10 @@ public: vkFreeCommandBuffers(device, cmdPool, 1, &computeCmdBuffer); textureLoader->destroyTexture(textureColorMap); + textureLoader->destroyTexture(textureComputeTarget); } - // Prepare an empty texture as the blit target from - // the offscreen framebuffer + // Prepare a texture target that is used to store compute shader calculations void prepareTextureTarget(vkTools::VulkanTexture *tex, uint32_t width, uint32_t height, VkFormat format) { VkFormatProperties formatProperties; @@ -113,9 +113,8 @@ public: // Get device properties for the requested texture format vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &formatProperties); - // Check if blit destination is supported for the requested format - // Only try for optimal tiling, linear tiling usually won't support blit as destination anyway - assert(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT); + // Check if requested image format supports image storage operations + assert(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT); // Prepare blit target texture tex->width = width; @@ -129,8 +128,10 @@ public: imageCreateInfo.arrayLayers = 1; imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; - // Texture will be sampled in a shader and is also the blit destination - imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + // Image will be sampled in the fragment shader and used as storage target in the compute shader + imageCreateInfo.usage = + VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_STORAGE_BIT; imageCreateInfo.flags = 0; VkMemoryAllocateInfo memAllocInfo = vkTools::initializers::memoryAllocateInfo(); @@ -411,7 +412,10 @@ public: std::vector poolSizes = { vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2), + // Graphics pipeline uses image samplers for display vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4), + // Compute pipeline uses storage images image loads and stores + vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 2), }; VkDescriptorPoolCreateInfo descriptorPoolInfo = @@ -630,12 +634,12 @@ public: std::vector setLayoutBindings = { // Binding 0 : Sampled image (read) vkTools::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT, 0), // Binding 1 : Sampled image (write) vkTools::initializers::descriptorSetLayoutBinding( - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT, 1), }; @@ -676,12 +680,12 @@ public: std::vector computeTexDescriptors = { vkTools::initializers::descriptorImageInfo( - textureColorMap.sampler, + VK_NULL_HANDLE, textureColorMap.view, VK_IMAGE_LAYOUT_GENERAL), vkTools::initializers::descriptorImageInfo( - textureComputeTarget.sampler, + VK_NULL_HANDLE, textureComputeTarget.view, VK_IMAGE_LAYOUT_GENERAL) }; @@ -690,14 +694,14 @@ public: { // Binding 0 : Sampled image (read) vkTools::initializers::writeDescriptorSet( - computeDescriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + computeDescriptorSet, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 0, &computeTexDescriptors[0]), // Binding 1 : Sampled image (write) vkTools::initializers::writeDescriptorSet( computeDescriptorSet, - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, &computeTexDescriptors[1]) };