missing barriers

This commit is contained in:
psucien 2024-08-31 00:04:24 +02:00
parent fdfdc56ce6
commit 72112271c0
2 changed files with 49 additions and 6 deletions

View file

@ -359,6 +359,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
boost::container::static_vector<vk::DescriptorBufferInfo, 32> buffer_infos;
boost::container::static_vector<vk::DescriptorImageInfo, 32> image_infos;
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
boost::container::small_vector<vk::BufferMemoryBarrier, 16> buffer_barriers;
Shader::PushData push_data{};
u32 binding{};
@ -424,6 +425,16 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
}
buffer_view = vk_buffer->View(offset_aligned, size + adjust, tex_buffer.is_written,
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
if (buffer_cache.IsRegionGpuModified(address, size)) {
buffer_barriers.push_back(vk::BufferMemoryBarrier{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eShaderRead,
.buffer = vk_buffer->Handle(),
.offset = offset,
.size = size,
});
}
}
set_writes.push_back({
.dstSet = VK_NULL_HANDLE,
@ -467,7 +478,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
auto ssharp = sampler.GetSharp(*stage);
if (ssharp.force_degamma) {
LOG_WARNING(Render_Vulkan, "Texture requires gamma correction");
}
}
if (sampler.disable_aniso) {
const auto& tsharp = tsharps[sampler.associated_image];
if (tsharp.base_level == 0 && tsharp.last_level == 0) {
@ -488,6 +499,14 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
}
const auto cmdbuf = scheduler.CommandBuffer();
if (!buffer_barriers.empty()) {
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader |
vk::PipelineStageFlagBits::eComputeShader,
vk::PipelineStageFlagBits::eFragmentShader,
vk::DependencyFlagBits::eByRegion, {}, buffer_barriers, {});
}
if (!set_writes.empty()) {
cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0,
set_writes);

View file

@ -286,10 +286,18 @@ ImageView& TextureCache::FindDepthTarget(const ImageInfo& image_info,
Image& image = slot_images[image_id];
image.flags |= ImageFlagBits::GpuModified;
image.flags &= ~ImageFlagBits::CpuModified;
image.aspect_mask = vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil;
image.aspect_mask = vk::ImageAspectFlagBits::eDepth;
const auto new_layout = view_info.is_storage ? vk::ImageLayout::eDepthStencilAttachmentOptimal
: vk::ImageLayout::eDepthStencilReadOnlyOptimal;
const bool has_stencil = image_info.usage.stencil;
if (has_stencil) {
image.aspect_mask |= vk::ImageAspectFlagBits::eStencil;
}
const auto new_layout = view_info.is_storage
? has_stencil ? vk::ImageLayout::eDepthStencilAttachmentOptimal
: vk::ImageLayout::eDepthAttachmentOptimal
: has_stencil ? vk::ImageLayout::eDepthStencilReadOnlyOptimal
: vk::ImageLayout::eDepthReadOnlyOptimal;
image.Transit(new_layout, vk::AccessFlagBits::eDepthStencilAttachmentWrite |
vk::AccessFlagBits::eDepthStencilAttachmentRead);
@ -372,6 +380,22 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
const auto [vk_buffer, buf_offset] = buffer_cache.ObtainTempBuffer(image_addr, image_size);
buffer = vk_buffer->Handle();
offset = buf_offset;
// The obtained buffer may be written by a shader so we need to emit a barrier to prevent
// RAW hazard
if (buffer_cache.IsRegionGpuModified(image_addr, image_size)) {
const vk::BufferMemoryBarrier post_barrier{
.srcAccessMask = vk::AccessFlagBits::eShaderWrite,
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
.buffer = buffer,
.offset = offset,
.size = image_size,
};
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eFragmentShader |
vk::PipelineStageFlagBits::eComputeShader,
vk::PipelineStageFlagBits::eTransfer,
vk::DependencyFlagBits::eByRegion, {}, post_barrier, {});
}
}
for (auto& copy : image_copy) {
@ -418,7 +442,7 @@ void TextureCache::UnregisterImage(ImageId image_id) {
}
void TextureCache::TrackImage(ImageId image_id) {
auto& image = slot_images[image_id];
auto& image = slot_images[image_id];
if (True(image.flags & ImageFlagBits::Tracked)) {
return;
}
@ -427,7 +451,7 @@ void TextureCache::TrackImage(ImageId image_id) {
}
void TextureCache::UntrackImage(ImageId image_id) {
auto& image = slot_images[image_id];
auto& image = slot_images[image_id];
if (False(image.flags & ImageFlagBits::Tracked)) {
return;
}