if(self.changes&pipeline_mask)
handle = device.get_pipeline_cache().get_pipeline(self);
- if(self.changes&(PipelineState::UNIFORMS|PipelineState::TEXTURES))
+ if(self.changes&(PipelineState::SHPROG|PipelineState::UNIFORMS|PipelineState::TEXTURES))
{
- unsigned changed_sets = 0;
+ unsigned changed_sets = (self.changes&PipelineState::SHPROG ? ~0U : 0U);
for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
- if(u.changed && u.binding>=0)
+ if(u.changed || changed_sets==~0U)
{
- changed_sets |= 1<<(u.binding>>20);
+ u.used = self.shprog->uses_binding(u.binding);
+ if(u.binding>=0)
+ changed_sets |= 1<<(u.binding>>20);
u.changed = false;
}
+ for(const PipelineState::BoundTexture &t: self.textures)
+ if(t.changed || changed_sets==~0U)
+ {
+ t.used = self.shprog->uses_binding(t.binding);
+ changed_sets |= 1<<(t.binding>>20);
+ if(t.sampler)
+ t.sampler->refresh();
+ t.changed = false;
+ }
descriptor_set_handles.resize(self.shprog->get_n_descriptor_sets());
for(unsigned i=0; i<descriptor_set_handles.size(); ++i)
blend_attachments[i].colorWriteMask = get_vulkan_color_mask(blend->write_mask);
}
}
+ else
+ {
+ for(unsigned i=0; i<n_color_attachments; ++i)
+ blend_attachments[i].colorWriteMask = VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT;
+ }
blend_info->sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
blend_info->attachmentCount = n_color_attachments;
uint64_t result = hash<64>(0, 0);
for(const PipelineState::BoundUniformBlock &b: self.uniform_blocks)
- if(b.block && b.binding>=0 && static_cast<unsigned>(b.binding>>20)==index)
+ if(b.used && b.binding>=0 && static_cast<unsigned>(b.binding>>20)==index)
{
result = hash_update<64>(result, b.binding);
result = hash_update<64>(result, reinterpret_cast<uintptr_t>(b.block));
}
+ for(const PipelineState::BoundTexture &t: self.textures)
+ if(t.used && (t.binding>>20)==index)
+ {
+ result = hash_update<64>(result, t.binding);
+ result = hash_update<64>(result, reinterpret_cast<uintptr_t>(t.texture));
+ result = hash_update<64>(result, reinterpret_cast<uintptr_t>(t.sampler));
+ }
return result;
}
unsigned n_buffers = 0;
for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
- if(u.block && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
+ if(u.used && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
++n_buffers;
-
- StructureBuilder sb(buffer, 2);
- VkWriteDescriptorSet *&writes = sb.add<VkWriteDescriptorSet>(n_buffers);
+ unsigned n_images = 0;
+ for(const PipelineState::BoundTexture &t: self.textures)
+ if(t.used && (t.binding>>20)==index)
+ ++n_images;
+ 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 *write_ptr = writes;
VkDescriptorBufferInfo *buffer_ptr = buffers;
+ VkDescriptorImageInfo *image_ptr = images;
for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
- if(u.block && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
+ if(u.used && u.binding>=0 && static_cast<unsigned>(u.binding>>20)==index)
{
buffer_ptr->buffer = handle_cast<::VkBuffer>(u.block->get_buffer()->handle);
buffer_ptr->offset = u.block->get_offset();
++write_ptr;
}
- return n_buffers;
+ for(const PipelineState::BoundTexture &t: self.textures)
+ if(t.used && (t.binding>>20)==index)
+ {
+ image_ptr->sampler = handle_cast<::VkSampler>(t.sampler->handle);
+ image_ptr->imageView = handle_cast<::VkImageView>(t.texture->view_handle);
+ image_ptr->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+ write_ptr->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_ptr->dstBinding = t.binding&0xFFFFF;
+ write_ptr->descriptorCount = 1;
+ write_ptr->descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+ write_ptr->pImageInfo = image_ptr;
+
+ ++image_ptr;
+ ++write_ptr;
+ }
+
+ return n_writes;
}
void VulkanPipelineState::apply(VkCommandBuffer command_buffer) const
if(!self.uniform_blocks.empty())
{
const PipelineState::BoundUniformBlock &first_block = self.uniform_blocks.front();
- if(first_block.block && first_block.binding==ReflectData::PUSH_CONSTANT && first_block.changed)
+ 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, VK_SHADER_STAGE_ALL,
+ vk.CmdPushConstants(command_buffer, self.shprog->layout_handle, self.shprog->stage_flags,
pc_block.get_offset(), pc_block.get_data_size(), pc_block.get_data_pointer());
}
}