for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
if(u.changed || changed_sets==~0U)
{
- u.used = self.shprog->uses_binding(u.binding);
+ u.used = self.shprog->uses_uniform_block_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);
+ t.used = self.shprog->uses_texture_binding(t.binding);
changed_sets |= 1<<(t.binding>>20);
+ if(t.texture && t.level>=0)
+ t.texture->refresh_mip_views();
if(t.sampler)
t.sampler->refresh();
t.changed = false;
{
result = hash_update<64>(result, b.binding);
result = hash_update<64>(result, reinterpret_cast<uintptr_t>(b.block));
+ result = hash_update<64>(result, reinterpret_cast<uintptr_t>(b.buffer));
}
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));
+ result = hash_update<64>(result, t.level);
}
return result;
for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
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->buffer = handle_cast<::VkBuffer>(u.buffer->handle);
buffer_ptr->offset = u.block->get_offset();
buffer_ptr->range = u.block->get_data_size();
write_ptr->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write_ptr->dstBinding = u.binding&0xFFFFF;
write_ptr->descriptorCount = 1;
- write_ptr->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+ write_ptr->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
write_ptr->pBufferInfo = buffer_ptr;
++buffer_ptr;
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);
+ if(t.level<0)
+ image_ptr->imageView = handle_cast<::VkImageView>(t.texture->view_handle);
+ else
+ image_ptr->imageView = handle_cast<::VkImageView>(t.texture->mip_view_handles[t.level]);
image_ptr->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
write_ptr->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
return n_writes;
}
-void VulkanPipelineState::apply(VkCommandBuffer command_buffer) const
+void VulkanPipelineState::apply(VkCommandBuffer command_buffer, unsigned frame, bool negative_viewport) const
{
const PipelineState &self = *static_cast<const PipelineState *>(this);
const VulkanFunctions &vk = device.get_functions();
}
}
- vk.CmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, self.shprog->layout_handle, 0, descriptor_set_handles.size(), descriptor_set_handles.data(), 0, 0);
+ if(!descriptor_set_handles.empty())
+ {
+ vector<uint32_t> dynamic_offsets;
+ dynamic_offsets.reserve(self.uniform_blocks.size());
+ for(const PipelineState::BoundUniformBlock &u: self.uniform_blocks)
+ if(u.used && u.binding>=0)
+ {
+ if(u.buffer->get_usage()==STREAMING)
+ dynamic_offsets.push_back(frame*u.buffer->get_size());
+ else
+ dynamic_offsets.push_back(0);
+ }
+
+ vk.CmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, self.shprog->layout_handle,
+ 0, descriptor_set_handles.size(), descriptor_set_handles.data(), dynamic_offsets.size(), dynamic_offsets.data());
+ }
VkViewport viewport = { };
if(self.viewport)
{
viewport.x = self.viewport->left;
- viewport.y = self.framebuffer->get_height()-(self.viewport->bottom+self.viewport->height);
+ viewport.y = self.viewport->bottom;
viewport.width = self.viewport->width;
viewport.height = self.viewport->height;
}
viewport.width = self.framebuffer->get_width();
viewport.height = self.framebuffer->get_height();
}
+ if(negative_viewport)
+ {
+ viewport.y += viewport.height;
+ viewport.height = -viewport.height;
+ }
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
vk.CmdSetViewport(command_buffer, 0, 1, &viewport);
if(self.scissor)
{
scissor.offset.x = self.scissor->left;
- scissor.offset.y = self.framebuffer->get_height()-(self.scissor->bottom+self.scissor->height);
+ scissor.offset.y = self.scissor->bottom;
scissor.extent.width = self.scissor->width;
scissor.extent.height = self.scissor->height;
}