Keep track of current texture layouts
* Fixes a few compute pipeline validation errors
This commit is contained in:
parent
1c52c348ed
commit
d999485325
3 changed files with 81 additions and 63 deletions
|
@ -377,6 +377,8 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
|
||||||
if(check_flag(info.usage, GFXTextureUsage::Storage))
|
if(check_flag(info.usage, GFXTextureUsage::Storage))
|
||||||
imageUsage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
imageUsage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
||||||
|
|
||||||
|
texture->usage = info.usage;
|
||||||
|
|
||||||
VkImageAspectFlagBits imageAspect;
|
VkImageAspectFlagBits imageAspect;
|
||||||
if (info.format == GFXPixelFormat::DEPTH_32F)
|
if (info.format == GFXPixelFormat::DEPTH_32F)
|
||||||
imageAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
|
imageAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
|
@ -431,6 +433,8 @@ GFXTexture* GFXVulkan::create_texture(const GFXTextureCreateInfo& info) {
|
||||||
texture->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
texture->layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
texture->current_layout = texture->layout;
|
||||||
|
|
||||||
// allocate memory
|
// allocate memory
|
||||||
VkMemoryRequirements memRequirements;
|
VkMemoryRequirements memRequirements;
|
||||||
vkGetImageMemoryRequirements(device, texture->handle, &memRequirements);
|
vkGetImageMemoryRequirements(device, texture->handle, &memRequirements);
|
||||||
|
@ -950,9 +954,11 @@ GFXPipeline* GFXVulkan::create_graphics_pipeline(const GFXGraphicsPipelineCreate
|
||||||
case GFXBindingType::StorageBuffer:
|
case GFXBindingType::StorageBuffer:
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||||
break;
|
break;
|
||||||
case GFXBindingType::Texture:
|
case GFXBindingType::Texture: {
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
break;
|
pipeline->bindings_marked_as_normal_images.push_back(binding.binding);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case GFXBindingType::StorageImage:
|
case GFXBindingType::StorageImage:
|
||||||
{
|
{
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
@ -1083,8 +1089,10 @@ GFXPipeline* GFXVulkan::create_compute_pipeline(const GFXComputePipelineCreateIn
|
||||||
case GFXBindingType::StorageBuffer:
|
case GFXBindingType::StorageBuffer:
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||||
break;
|
break;
|
||||||
case GFXBindingType::Texture:
|
case GFXBindingType::Texture: {
|
||||||
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
pipeline->bindings_marked_as_normal_images.push_back(binding.binding);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case GFXBindingType::StorageImage:
|
case GFXBindingType::StorageImage:
|
||||||
{
|
{
|
||||||
|
@ -1388,8 +1396,10 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
|
||||||
break;
|
break;
|
||||||
case GFXCommandType::Draw:
|
case GFXCommandType::Draw:
|
||||||
{
|
{
|
||||||
if(try_bind_descriptor())
|
if(try_bind_descriptor()) {
|
||||||
vkCmdDraw(cmd, command.data.draw.vertex_count, command.data.draw.instance_count, command.data.draw.vertex_offset, command.data.draw.base_instance);
|
vkCmdDraw(cmd, command.data.draw.vertex_count, command.data.draw.instance_count,
|
||||||
|
command.data.draw.vertex_offset, command.data.draw.base_instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GFXCommandType::DrawIndexed:
|
case GFXCommandType::DrawIndexed:
|
||||||
|
@ -1467,8 +1477,27 @@ void GFXVulkan::submit(GFXCommandBuffer* command_buffer, const int identifier) {
|
||||||
break;
|
break;
|
||||||
case GFXCommandType::Dispatch:
|
case GFXCommandType::Dispatch:
|
||||||
{
|
{
|
||||||
if(try_bind_descriptor())
|
if(try_bind_descriptor()) {
|
||||||
vkCmdDispatch(cmd, command.data.dispatch.group_count_x, command.data.dispatch.group_count_y, command.data.dispatch.group_count_z);
|
for(auto binding : currentPipeline->bindings_marked_as_storage_images) {
|
||||||
|
auto tex = (GFXVulkanTexture*)boundTextures[binding];
|
||||||
|
inlineTransitionImageLayout(cmd, tex->handle, tex->format, tex->aspect, tex->range, tex->current_layout, VK_IMAGE_LAYOUT_GENERAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkCmdDispatch(cmd, command.data.dispatch.group_count_x, command.data.dispatch.group_count_y,
|
||||||
|
command.data.dispatch.group_count_z);
|
||||||
|
|
||||||
|
for(auto binding : currentPipeline->bindings_marked_as_storage_images) {
|
||||||
|
auto tex = (GFXVulkanTexture*)boundTextures[binding];
|
||||||
|
|
||||||
|
VkImageLayout next_layout = tex->layout;
|
||||||
|
if((tex->usage & GFXTextureUsage::Sampled) == GFXTextureUsage::Sampled)
|
||||||
|
next_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
|
inlineTransitionImageLayout(cmd, tex->handle, tex->format, tex->aspect, tex->range, VK_IMAGE_LAYOUT_GENERAL, next_layout);
|
||||||
|
|
||||||
|
tex->current_layout = next_layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GFXCommandType::PushGroup:
|
case GFXCommandType::PushGroup:
|
||||||
|
@ -2002,8 +2031,7 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSe
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// update set
|
// update set
|
||||||
int i = 0;
|
for (auto [i, buffer] : utility::enumerate(boundShaderBuffers)) {
|
||||||
for (auto& buffer : boundShaderBuffers) {
|
|
||||||
if (buffer.buffer != nullptr) {
|
if (buffer.buffer != nullptr) {
|
||||||
GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer.buffer;
|
GFXVulkanBuffer* vulkanBuffer = (GFXVulkanBuffer*)buffer.buffer;
|
||||||
|
|
||||||
|
@ -2022,69 +2050,55 @@ void GFXVulkan::cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSe
|
||||||
|
|
||||||
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
|
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
for (auto [i, texture] : utility::enumerate(boundTextures)) {
|
||||||
for (auto& texture : boundTextures) {
|
if (texture != nullptr) {
|
||||||
if (texture == nullptr) {
|
GFXVulkanTexture* vulkanTexture = (GFXVulkanTexture*) texture;
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GFXVulkanTexture* vulkanTexture = (GFXVulkanTexture*)texture;
|
VkDescriptorImageInfo imageInfo = {};
|
||||||
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
imageInfo.imageView = vulkanTexture->view;
|
||||||
|
imageInfo.sampler = vulkanTexture->sampler;
|
||||||
|
|
||||||
VkDescriptorImageInfo imageInfo = {};
|
VkWriteDescriptorSet descriptorWrite = {};
|
||||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
imageInfo.imageView = vulkanTexture->view;
|
descriptorWrite.dstSet = descriptorSet;
|
||||||
imageInfo.sampler = vulkanTexture->sampler;
|
descriptorWrite.dstBinding = i;
|
||||||
|
descriptorWrite.descriptorCount = 1;
|
||||||
|
|
||||||
VkWriteDescriptorSet descriptorWrite = {};
|
if (utility::contains(pipeline->bindings_marked_as_storage_images, i)) {
|
||||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
descriptorWrite.dstSet = descriptorSet;
|
imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||||
descriptorWrite.dstBinding = i;
|
} else if (utility::contains(pipeline->bindings_marked_as_sampled_images, i)) {
|
||||||
descriptorWrite.descriptorCount = 1;
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
} else {
|
||||||
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
}
|
||||||
|
|
||||||
if (utility::contains(pipeline->bindings_marked_as_storage_images, i)) {
|
descriptorWrite.pImageInfo = &imageInfo;
|
||||||
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
||||||
imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
|
||||||
} else if (utility::contains(pipeline->bindings_marked_as_sampled_images, i)) {
|
|
||||||
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
|
||||||
} else {
|
|
||||||
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptorWrite.pImageInfo = &imageInfo;
|
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
|
||||||
|
}
|
||||||
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
for (auto& [i, sampler] : utility::enumerate(boundSamplers)) {
|
||||||
for (auto& sampler : boundSamplers) {
|
if (sampler != nullptr) {
|
||||||
if (sampler == nullptr) {
|
GFXVulkanSampler* vulkanSampler = (GFXVulkanSampler*) sampler;
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GFXVulkanSampler* vulkanSampler = (GFXVulkanSampler*)sampler;
|
VkDescriptorImageInfo imageInfo = {};
|
||||||
|
imageInfo.sampler = vulkanSampler->sampler;
|
||||||
|
|
||||||
VkDescriptorImageInfo imageInfo = {};
|
VkWriteDescriptorSet descriptorWrite = {};
|
||||||
imageInfo.sampler = vulkanSampler->sampler;
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptorWrite.dstSet = descriptorSet;
|
||||||
|
descriptorWrite.dstBinding = i;
|
||||||
|
descriptorWrite.descriptorCount = 1;
|
||||||
|
descriptorWrite.pImageInfo = &imageInfo;
|
||||||
|
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||||
|
|
||||||
VkWriteDescriptorSet descriptorWrite = {};
|
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
|
||||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
}
|
||||||
descriptorWrite.dstSet = descriptorSet;
|
|
||||||
descriptorWrite.dstBinding = i;
|
|
||||||
descriptorWrite.descriptorCount = 1;
|
|
||||||
descriptorWrite.pImageInfo = &imageInfo;
|
|
||||||
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
|
|
||||||
|
|
||||||
vkUpdateDescriptorSets(device, 1, &descriptorWrite, 0, nullptr);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline->cachedDescriptorSets[hash] = descriptorSet;
|
pipeline->cachedDescriptorSets[hash] = descriptorSet;
|
||||||
|
|
|
@ -15,7 +15,8 @@ public:
|
||||||
|
|
||||||
VkDescriptorSetLayout descriptorLayout;
|
VkDescriptorSetLayout descriptorLayout;
|
||||||
|
|
||||||
std::vector<int> bindings_marked_as_storage_images;
|
std::vector<int> bindings_marked_as_normal_images;
|
||||||
|
std::vector<int> bindings_marked_as_storage_images;
|
||||||
std::vector<int> bindings_marked_as_sampled_images;
|
std::vector<int> bindings_marked_as_sampled_images;
|
||||||
|
|
||||||
// dynamic descriptor sets
|
// dynamic descriptor sets
|
||||||
|
|
|
@ -15,6 +15,9 @@ public:
|
||||||
|
|
||||||
VkFormat format;
|
VkFormat format;
|
||||||
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
VkImageLayout current_layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
VkImageAspectFlagBits aspect;
|
VkImageAspectFlagBits aspect;
|
||||||
VkImageSubresourceRange range;
|
VkImageSubresourceRange range;
|
||||||
|
|
||||||
|
GFXTextureUsage usage;
|
||||||
};
|
};
|
||||||
|
|
Reference in a new issue