Archived
1
Fork 0

Keep track of current texture layouts

* Fixes a few compute pipeline validation errors
This commit is contained in:
redstrate 2021-06-01 10:16:59 -04:00
parent 1c52c348ed
commit d999485325
3 changed files with 81 additions and 63 deletions

View file

@ -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;

View file

@ -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

View file

@ -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;
}; };