]> git.tdb.fi Git - libs/gl.git/blobdiff - source/backends/vulkan/pipelinestate_backend.cpp
Make StructureBuilder return const references to the pointers
[libs/gl.git] / source / backends / vulkan / pipelinestate_backend.cpp
index 02e7993c665fb52dd95e9ff3f92020cfb2584a68..87e03242d329ae90fb66d5346cefe9a4af4e195e 100644 (file)
@@ -41,6 +41,12 @@ void VulkanPipelineState::update() const
        if(changes&PipelineState::VERTEX_SETUP)
                self.vertex_setup->refresh();
 
+       if(changes&PipelineState::SHPROG)
+       {
+               push_const_compat = hash<32>(self.shprog->stage_flags);
+               push_const_compat = hash_update<32>(push_const_compat, self.shprog->get_push_constants_size());
+       }
+
        constexpr unsigned pipeline_mask = PipelineState::SHPROG|PipelineState::VERTEX_SETUP|PipelineState::FACE_CULL|
                PipelineState::DEPTH_TEST|PipelineState::STENCIL_TEST|PipelineState::BLEND|PipelineState::PRIMITIVE_TYPE;
        if(changes&pipeline_mask)
@@ -77,9 +83,14 @@ void VulkanPipelineState::update() const
                if(changed_sets)
                {
                        descriptor_set_slots.resize(self.shprog->get_n_descriptor_sets());
+                       first_changed_desc_set = descriptor_set_slots.size();
                        for(unsigned i=0; i<descriptor_set_slots.size(); ++i)
                                if(changed_sets&(1<<i))
+                               {
                                        descriptor_set_slots[i] = device.get_descriptor_pool().get_descriptor_set_slot(self, i);
+                                       first_changed_desc_set = min(first_changed_desc_set, i);
+                               }
+
                        unapplied |= PipelineState::UNIFORMS;
                }
        }
@@ -149,16 +160,16 @@ void VulkanPipelineState::fill_creation_info(vector<char> &buffer) const
        }
 
        StructureBuilder sb(buffer, 10);
-       VkGraphicsPipelineCreateInfo *&pipeline_info = sb.add<VkGraphicsPipelineCreateInfo>();
-       VkPipelineInputAssemblyStateCreateInfo *&input_assembly_info = sb.add<VkPipelineInputAssemblyStateCreateInfo>();
-       VkPipelineViewportStateCreateInfo *&viewport_info = sb.add<VkPipelineViewportStateCreateInfo>();
-       VkPipelineRasterizationStateCreateInfo *&raster_info = sb.add<VkPipelineRasterizationStateCreateInfo>();
-       VkPipelineMultisampleStateCreateInfo *&multisample_info = sb.add<VkPipelineMultisampleStateCreateInfo>();
-       VkPipelineDepthStencilStateCreateInfo *&depth_stencil_info = sb.add<VkPipelineDepthStencilStateCreateInfo>();
-       VkPipelineColorBlendStateCreateInfo *&blend_info = sb.add<VkPipelineColorBlendStateCreateInfo>();
-       VkPipelineColorBlendAttachmentState *&blend_attachments = sb.add<VkPipelineColorBlendAttachmentState>(n_color_attachments);
-       VkPipelineDynamicStateCreateInfo *&dynamic_info = sb.add<VkPipelineDynamicStateCreateInfo>();
-       VkDynamicState *&dynamic_states = sb.add<VkDynamicState>(2);
+       VkGraphicsPipelineCreateInfo *const &pipeline_info = sb.add<VkGraphicsPipelineCreateInfo>();
+       VkPipelineInputAssemblyStateCreateInfo *const &input_assembly_info = sb.add<VkPipelineInputAssemblyStateCreateInfo>();
+       VkPipelineViewportStateCreateInfo *const &viewport_info = sb.add<VkPipelineViewportStateCreateInfo>();
+       VkPipelineRasterizationStateCreateInfo *const &raster_info = sb.add<VkPipelineRasterizationStateCreateInfo>();
+       VkPipelineMultisampleStateCreateInfo *const &multisample_info = sb.add<VkPipelineMultisampleStateCreateInfo>();
+       VkPipelineDepthStencilStateCreateInfo *const &depth_stencil_info = sb.add<VkPipelineDepthStencilStateCreateInfo>();
+       VkPipelineColorBlendStateCreateInfo *const &blend_info = sb.add<VkPipelineColorBlendStateCreateInfo>();
+       VkPipelineColorBlendAttachmentState *const &blend_attachments = sb.add<VkPipelineColorBlendAttachmentState>(n_color_attachments);
+       VkPipelineDynamicStateCreateInfo *const &dynamic_info = sb.add<VkPipelineDynamicStateCreateInfo>();
+       VkDynamicState *const &dynamic_states = sb.add<VkDynamicState>(2);
 
        input_assembly_info->sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
        input_assembly_info->topology = static_cast<VkPrimitiveTopology>(get_vulkan_primitive_type(self.primitive_type));
@@ -261,6 +272,7 @@ uint64_t VulkanPipelineState::compute_descriptor_set_hash(unsigned index) const
        const PipelineState &self = *static_cast<const PipelineState *>(this);
 
        uint64_t result = hash<64>(0, 0);
+       bool empty = true;
 
        auto i = lower_bound_member(self.uniform_blocks, static_cast<int>(index)<<20, &PipelineState::BoundUniformBlock::binding);
        for(; (i!=self.uniform_blocks.end() && static_cast<unsigned>(i->binding)>>20==index); ++i)
@@ -269,6 +281,7 @@ uint64_t VulkanPipelineState::compute_descriptor_set_hash(unsigned index) const
                        result = hash_update<64>(result, i->binding);
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->block));
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(i->buffer->handle));
+                       empty = false;
                }
 
        auto j = lower_bound_member(self.textures, index<<20, &PipelineState::BoundTexture::binding);
@@ -279,8 +292,12 @@ uint64_t VulkanPipelineState::compute_descriptor_set_hash(unsigned index) const
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(j->texture->handle));
                        result = hash_update<64>(result, reinterpret_cast<uintptr_t>(j->sampler->handle));
                        result = hash_update<64>(result, j->level);
+                       empty = false;
                }
 
+       if(!empty)
+               result = hash_update<64>(result, self.shprog->stage_flags);
+
        return result;
 }
 
@@ -319,9 +336,9 @@ unsigned VulkanPipelineState::fill_descriptor_writes(unsigned index, unsigned fr
        unsigned n_writes = n_buffers+n_images;
 
        StructureBuilder sb(buffer, 3);
-       VkWriteDescriptorSet *&writes = sb.add<VkWriteDescriptorSet>(n_writes);
-       VkDescriptorBufferInfo *&buffers = sb.add<VkDescriptorBufferInfo>(n_buffers);
-       VkDescriptorImageInfo *&images = sb.add<VkDescriptorImageInfo>(n_images);
+       VkWriteDescriptorSet *const &writes = sb.add<VkWriteDescriptorSet>(n_writes);
+       VkDescriptorBufferInfo *const &buffers = sb.add<VkDescriptorBufferInfo>(n_buffers);
+       VkDescriptorImageInfo *const &images = sb.add<VkDescriptorImageInfo>(n_images);
 
        VkWriteDescriptorSet *write_ptr = writes;
        VkDescriptorBufferInfo *buffer_ptr = buffers;
@@ -369,26 +386,34 @@ unsigned VulkanPipelineState::fill_descriptor_writes(unsigned index, unsigned fr
        return n_writes;
 }
 
-void VulkanPipelineState::apply(VkCommandBuffer command_buffer, const VulkanPipelineState *last, unsigned frame, bool negative_viewport) const
+void VulkanPipelineState::apply(const VulkanCommandRecorder &vkCmd, const VulkanPipelineState *last, unsigned frame, bool negative_viewport) const
 {
        const PipelineState &self = *static_cast<const PipelineState *>(this);
-       const VulkanFunctions &vk = device.get_functions();
 
-       unsigned first_changed_desc_set = 0;
        if(!last)
+       {
                unapplied = ~0U;
+               first_changed_desc_set = 0;
+       }
        else if(last!=this)
        {
                const PipelineState &last_ps = *static_cast<const PipelineState *>(last);
                if(handle!=last->handle)
+               {
                        unapplied |= PipelineState::SHPROG;
+                       if(self.push_const_compat!=last_ps.push_const_compat)
+                       {
+                               unapplied |= PipelineState::UNIFORMS;
+                               first_changed_desc_set = 0;
+                       }
+               }
                if(self.vertex_setup!=last_ps.vertex_setup)
                        unapplied |= PipelineState::VERTEX_SETUP;
-               for(unsigned i=0; (i<descriptor_set_slots.size() && i<last->descriptor_set_slots.size()); ++i)
-                       if(descriptor_set_slots[i]!=last->descriptor_set_slots[i])
+               for(unsigned i=0; i<descriptor_set_slots.size(); ++i)
+                       if(i>=last->descriptor_set_slots.size() || descriptor_set_slots[i]!=last->descriptor_set_slots[i])
                        {
                                unapplied |= PipelineState::UNIFORMS;
-                               first_changed_desc_set = i;
+                               first_changed_desc_set = min(first_changed_desc_set, i);
                                break;
                        }
                if(self.viewport!=last_ps.viewport)
@@ -398,14 +423,14 @@ void VulkanPipelineState::apply(VkCommandBuffer command_buffer, const VulkanPipe
        }
 
        if(unapplied&PipelineState::SHPROG)
-               vk.CmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, handle);
+               vkCmd.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, handle);
 
        if(unapplied&PipelineState::VERTEX_SETUP)
                if(const VertexSetup *vs = self.vertex_setup)
                {
-                       vk.CmdBindVertexBuffers(command_buffer, 0, vs->n_bindings, vs->buffers, vs->offsets);
+                       vkCmd.BindVertexBuffers(0, vs->n_bindings, vs->buffers, vs->offsets);
                        VkIndexType index_type = static_cast<VkIndexType>(get_vulkan_index_type(vs->get_index_type()));
-                       vk.CmdBindIndexBuffer(command_buffer, vs->get_index_buffer()->handle, 0, index_type);
+                       vkCmd.BindIndexBuffer(vs->get_index_buffer()->handle, 0, index_type);
                }
 
        if(!self.uniform_blocks.empty())
@@ -414,7 +439,7 @@ void VulkanPipelineState::apply(VkCommandBuffer command_buffer, const VulkanPipe
                if(first_block.used && first_block.binding==ReflectData::PUSH_CONSTANT)
                {
                        const UniformBlock &pc_block = *first_block.block;
-                       vk.CmdPushConstants(command_buffer, self.shprog->layout_handle, self.shprog->stage_flags,
+                       vkCmd.PushConstants(self.shprog->layout_handle, self.shprog->stage_flags,
                                pc_block.get_offset(), pc_block.get_data_size(), pc_block.get_data_pointer());
                }
        }
@@ -427,7 +452,7 @@ void VulkanPipelineState::apply(VkCommandBuffer command_buffer, const VulkanPipe
                        descriptor_set_handles.push_back(device.get_descriptor_pool().get_descriptor_set(
                                self.descriptor_set_slots[i], self, i, frame));
 
-               vk.CmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, self.shprog->layout_handle,
+               vkCmd.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, self.shprog->layout_handle,
                        first_changed_desc_set, descriptor_set_handles.size(), descriptor_set_handles.data(), 0, 0);
        }
 
@@ -450,7 +475,7 @@ void VulkanPipelineState::apply(VkCommandBuffer command_buffer, const VulkanPipe
                        }
                        viewport.minDepth = 0.0f;
                        viewport.maxDepth = 1.0f;
-                       vk.CmdSetViewport(command_buffer, 0, 1, &viewport);
+                       vkCmd.SetViewport(0, 1, &viewport);
                }
 
                if(unapplied&PipelineState::SCISSOR)
@@ -461,11 +486,12 @@ void VulkanPipelineState::apply(VkCommandBuffer command_buffer, const VulkanPipe
                        scissor.offset.y = scissor_rect.bottom;
                        scissor.extent.width = scissor_rect.width;
                        scissor.extent.height = scissor_rect.height;
-                       vk.CmdSetScissor(command_buffer, 0, 1, &scissor);
+                       vkCmd.SetScissor(0, 1, &scissor);
                }
        }
 
        unapplied = 0;
+       first_changed_desc_set = descriptor_set_slots.size();
 }
 
 } // namespace GL