Surface management rework (3/3) (#370)

* texture_cache: images overlap support

* renderer_vk: log messages on surfaces which require degamma

* missing barriers

* forced sync2 + better barriers

* Handling of depth target aliasing; added formats compatibility check

* Don't bind empty texel buffers

* Promote r32f textures to depth target if shader expects so

* Promote textures to depth if they use depth tiling

* fix for image leaking; detiler stream buffer removed
This commit is contained in:
psucien 2024-09-04 22:47:57 +02:00 committed by GitHub
parent b9c6093717
commit 28feb77982
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 847 additions and 72 deletions

View file

@ -104,6 +104,7 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
boost::container::static_vector<vk::DescriptorBufferInfo, 16> buffer_infos;
boost::container::static_vector<vk::DescriptorImageInfo, 16> image_infos;
boost::container::small_vector<vk::WriteDescriptorSet, 16> set_writes;
boost::container::small_vector<vk::BufferMemoryBarrier2, 16> buffer_barriers;
Shader::PushData push_data{};
u32 binding{};
@ -153,9 +154,9 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
for (const auto& desc : info->texture_buffers) {
const auto vsharp = desc.GetSharp(*info);
vk::BufferView& buffer_view = buffer_views.emplace_back(VK_NULL_HANDLE);
if (vsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid) {
const u32 size = vsharp.GetSize();
if (vsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid && size != 0) {
const VAddr address = vsharp.base_address;
const u32 size = vsharp.GetSize();
if (desc.is_written) {
if (texture_cache.TouchMeta(address, true)) {
LOG_TRACE(Render_Vulkan, "Metadata update skipped");
@ -183,6 +184,13 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
}
buffer_view = vk_buffer->View(offset_aligned, size + adjust, desc.is_written,
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
if (auto barrier =
vk_buffer->GetBarrier(desc.is_written ? vk::AccessFlagBits2::eShaderWrite
: vk::AccessFlagBits2::eShaderRead,
vk::PipelineStageFlagBits2::eComputeShader)) {
buffer_barriers.emplace_back(*barrier);
}
}
set_writes.push_back({
.dstSet = VK_NULL_HANDLE,
@ -222,6 +230,9 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
}
for (const auto& sampler : info->samplers) {
const auto ssharp = sampler.GetSharp(*info);
if (ssharp.force_degamma) {
LOG_WARNING(Render_Vulkan, "Texture requires gamma correction");
}
const auto vk_sampler = texture_cache.GetSampler(ssharp);
image_infos.emplace_back(vk_sampler, VK_NULL_HANDLE, vk::ImageLayout::eGeneral);
set_writes.push_back({
@ -239,6 +250,15 @@ bool ComputePipeline::BindResources(VideoCore::BufferCache& buffer_cache,
}
const auto cmdbuf = scheduler.CommandBuffer();
if (!buffer_barriers.empty()) {
auto dependencies = vk::DependencyInfo{
.bufferMemoryBarrierCount = u32(buffer_barriers.size()),
.pBufferMemoryBarriers = buffer_barriers.data(),
};
cmdbuf.pipelineBarrier2(dependencies);
}
cmdbuf.pushConstants(*pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0u, sizeof(push_data),
&push_data);
cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eCompute, *pipeline_layout, 0, set_writes);

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::BufferMemoryBarrier2, 16> buffer_barriers;
Shader::PushData push_data{};
u32 binding{};
@ -407,9 +408,9 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
for (const auto& tex_buffer : stage->texture_buffers) {
const auto vsharp = tex_buffer.GetSharp(*stage);
vk::BufferView& buffer_view = buffer_views.emplace_back(VK_NULL_HANDLE);
if (vsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid) {
const u32 size = vsharp.GetSize();
if (vsharp.GetDataFmt() != AmdGpu::DataFormat::FormatInvalid && size != 0) {
const VAddr address = vsharp.base_address;
const u32 size = vsharp.GetSize();
const u32 alignment = instance.TexelBufferMinAlignment();
const auto [vk_buffer, offset] =
buffer_cache.ObtainBuffer(address, size, tex_buffer.is_written, true);
@ -424,6 +425,12 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
}
buffer_view = vk_buffer->View(offset_aligned, size + adjust, tex_buffer.is_written,
vsharp.GetDataFmt(), vsharp.GetNumberFmt());
const auto dst_access = tex_buffer.is_written ? vk::AccessFlagBits2::eShaderWrite
: vk::AccessFlagBits2::eShaderRead;
if (auto barrier = vk_buffer->GetBarrier(
dst_access, vk::PipelineStageFlagBits2::eVertexShader)) {
buffer_barriers.emplace_back(*barrier);
}
}
set_writes.push_back({
.dstSet = VK_NULL_HANDLE,
@ -441,7 +448,7 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
const auto tsharp = image_desc.GetSharp(*stage);
if (tsharp) {
tsharps.emplace_back(tsharp);
VideoCore::ImageInfo image_info{tsharp};
VideoCore::ImageInfo image_info{tsharp, image_desc.is_depth};
VideoCore::ImageViewInfo view_info{tsharp, image_desc.is_storage};
const auto& image_view = texture_cache.FindTexture(image_info, view_info);
const auto& image = texture_cache.GetImage(image_view.image_id);
@ -465,6 +472,9 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
}
for (const auto& sampler : stage->samplers) {
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) {
@ -485,6 +495,15 @@ void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
}
const auto cmdbuf = scheduler.CommandBuffer();
if (!buffer_barriers.empty()) {
auto dependencies = vk::DependencyInfo{
.bufferMemoryBarrierCount = u32(buffer_barriers.size()),
.pBufferMemoryBarriers = buffer_barriers.data(),
};
cmdbuf.pipelineBarrier2(dependencies);
}
if (!set_writes.empty()) {
cmdbuf.pushDescriptorSetKHR(vk::PipelineBindPoint::eGraphics, *pipeline_layout, 0,
set_writes);

View file

@ -228,6 +228,7 @@ bool Instance::CreateDevice() {
const bool maintenance5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
add_extension(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
add_extension(VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME);
add_extension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
#ifdef __APPLE__
// Required by Vulkan spec if supported.

View file

@ -145,6 +145,14 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline() {
LOG_TRACE(Render_Vulkan, "FMask decompression pass skipped");
return nullptr;
}
if (regs.depth_render_control.depth_compress_disable) {
LOG_TRACE(Render_Vulkan, "HTile decompress skipped (depth)");
return nullptr;
}
if (regs.depth_render_control.stencil_compress_disable) {
LOG_TRACE(Render_Vulkan, "HTile decompress skipped (stencil)");
return nullptr;
}
if (!RefreshGraphicsKey()) {
return nullptr;
}

View file

@ -179,6 +179,10 @@ void Rasterizer::BeginRendering() {
const auto& regs = liverpool->regs;
RenderState state;
if (regs.color_control.degamma_enable) {
LOG_WARNING(Render_Vulkan, "Color buffers require gamma correction");
}
for (auto col_buf_id = 0u; col_buf_id < Liverpool::NumColorBuffers; ++col_buf_id) {
const auto& col_buf = regs.color_buffers[col_buf_id];
if (!col_buf) {