]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/pipelinestate_backend.cpp
Add support for storage images in Renderer and PipelineState
[libs/gl.git] / source / backends / vulkan / pipelinestate_backend.cpp
index f32818049ef0b906c173edc6efb0ede4247a549f..5f9e7eb9185a4e812c1826edf0e071677e2b20d7 100644 (file)
@@ -64,12 +64,13 @@ void VulkanPipelineState::update() const
                        {
                                if(r.type==PipelineState::UNIFORM_BLOCK)
                                        r.used = self.shprog->uses_uniform_block_binding(r.binding);
-                               else if(r.type==PipelineState::TEXTURE)
+                               else if(r.type==PipelineState::SAMPLED_TEXTURE || r.type==PipelineState::STORAGE_TEXTURE)
                                {
                                        r.used = self.shprog->uses_texture_binding(r.binding);
                                        if(r.mip_level>=0)
                                                r.texture->refresh_mip_views();
-                                       r.sampler->refresh();
+                                       if(r.type==PipelineState::SAMPLED_TEXTURE)
+                                               r.sampler->refresh();
                                }
                                if(r.binding>=0)
                                        changed_sets |= 1<<(r.binding>>20);
@@ -285,12 +286,14 @@ uint64_t VulkanPipelineState::compute_descriptor_set_hash(unsigned index) const
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->block));
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->buffer->handle));
                }
-               else if(i->type==PipelineState::TEXTURE)
+               else if(i->type==PipelineState::SAMPLED_TEXTURE)
                {
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->texture->handle));
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->sampler->handle));
                        result = hash_update<64>(result, i->mip_level);
                }
+               else if(i->type==PipelineState::STORAGE_TEXTURE)
+                       result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->texture->handle));
                empty = false;
        }
 
@@ -330,7 +333,7 @@ unsigned VulkanPipelineState::fill_descriptor_writes(unsigned index, unsigned fr
                {
                        if(i->type==PipelineState::UNIFORM_BLOCK)
                                ++n_buffers;
-                       else if(i->type==PipelineState::TEXTURE)
+                       else if(i->type==PipelineState::SAMPLED_TEXTURE || i->type==PipelineState::STORAGE_TEXTURE)
                                ++n_images;
                }
        unsigned n_writes = n_buffers+n_images;
@@ -365,19 +368,28 @@ unsigned VulkanPipelineState::fill_descriptor_writes(unsigned index, unsigned fr
 
                        ++buffer_ptr;
                }
-               else if(i->type==PipelineState::TEXTURE)
+               else if(i->type==PipelineState::SAMPLED_TEXTURE || i->type==PipelineState::STORAGE_TEXTURE)
                {
-                       image_ptr->sampler = handle_cast<::VkSampler>(i->sampler->handle);
                        if(i->mip_level<0)
                                image_ptr->imageView = handle_cast<::VkImageView>(i->texture->view_handle);
                        else
                                image_ptr->imageView = handle_cast<::VkImageView>(i->texture->mip_view_handles[i->mip_level]);
-                       image_ptr->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+                       if(i->type==PipelineState::SAMPLED_TEXTURE)
+                       {
+                               image_ptr->sampler = handle_cast<::VkSampler>(i->sampler->handle);
+                               image_ptr->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+                               write_ptr->descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+                       }
+                       else if(i->type==PipelineState::STORAGE_TEXTURE)
+                       {
+                               image_ptr->imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+                               write_ptr->descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+                       }
 
                        write_ptr->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
                        write_ptr->dstBinding = i->binding&0xFFFFF;
                        write_ptr->descriptorCount = 1;
-                       write_ptr->descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
                        write_ptr->pImageInfo = image_ptr;
 
                        ++image_ptr;
@@ -389,6 +401,15 @@ unsigned VulkanPipelineState::fill_descriptor_writes(unsigned index, unsigned fr
        return n_writes;
 }
 
+void VulkanPipelineState::synchronize_resources(bool discard_fb_contents) const
+{
+       const PipelineState &self = *static_cast<const PipelineState *>(this);
+
+       for(const PipelineState::BoundResource &r: self.resources)
+               if(r.type==PipelineState::STORAGE_TEXTURE)
+                       r.texture->change_layout(-1, VK_IMAGE_LAYOUT_GENERAL, false);
+}
+
 void VulkanPipelineState::apply(const VulkanCommandRecorder &vkCmd, const VulkanPipelineState *last, unsigned frame, bool negative_viewport) const
 {
        const PipelineState &self = *static_cast<const PipelineState *>(this);