From a05d0063fc5f9232008bcde7ad214df628cd4e72 Mon Sep 17 00:00:00 2001 From: psucien Date: Thu, 27 Jun 2024 23:46:53 +0200 Subject: [PATCH] renderer_vulkan: added support for MSAA attachments --- .../ir/passes/resource_tracking_pass.cpp | 16 ++++++++++------ src/video_core/amdgpu/liverpool.h | 17 ++++++++++++++++- .../renderer_vulkan/liverpool_to_vk.cpp | 13 +++++++++++++ .../renderer_vulkan/liverpool_to_vk.h | 2 ++ .../renderer_vulkan/vk_graphics_pipeline.cpp | 2 +- .../renderer_vulkan/vk_graphics_pipeline.h | 1 + src/video_core/renderer_vulkan/vk_instance.cpp | 1 + .../renderer_vulkan/vk_pipeline_cache.cpp | 1 + src/video_core/texture_cache/image.cpp | 3 ++- 9 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index 8e1c186c4..ac4191978 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -294,15 +294,19 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip const IR::Inst* body = inst.Arg(1).InstRecursive(); const auto [coords, arg] = [&] -> std::pair { switch (image.GetType()) { - case AmdGpu::ImageType::Color1D: + case AmdGpu::ImageType::Color1D: // x return {body->Arg(0), body->Arg(1)}; - case AmdGpu::ImageType::Color1DArray: - case AmdGpu::ImageType::Color2D: + case AmdGpu::ImageType::Color1DArray: // x, slice + [[fallthrough]]; + case AmdGpu::ImageType::Color2D: // x, y return {ir.CompositeConstruct(body->Arg(0), body->Arg(1)), body->Arg(2)}; - case AmdGpu::ImageType::Color2DArray: - case AmdGpu::ImageType::Color3D: + case AmdGpu::ImageType::Color2DArray: // x, y, slice + [[fallthrough]]; + case AmdGpu::ImageType::Color2DMsaa: // x, y, frag + [[fallthrough]]; + case AmdGpu::ImageType::Color3D: // x, y, z return {ir.CompositeConstruct(body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)}; - case AmdGpu::ImageType::Cube: + case AmdGpu::ImageType::Cube: // x, y, face return {PatchCubeCoord(ir, body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)}; default: UNREACHABLE_MSG("Unknown image type {}", image.GetType()); diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index 352bc241a..bcc1187ad 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -791,6 +791,18 @@ struct Liverpool { BitField<1, 1, u32> stencil_clear_enable; }; + union AaConfig { + BitField<0, 3, u32> msaa_num_samples; + BitField<4, 1, u32> aa_mask_centroid_dtmn; + BitField<13, 4, u32> max_sample_dst; + BitField<20, 3, u32> msaa_exposed_samples; + BitField<24, 2, u32> detail_to_exposed_mode; + + u32 NumSamples() const { + return 1 << msaa_num_samples; + } + }; + union Regs { struct { INSERT_PADDING_WORDS(0x2C08); @@ -858,7 +870,9 @@ struct Liverpool { u32 enable_primitive_id; INSERT_PADDING_WORDS(0xA2DF - 0xA2A1 - 1); PolygonOffset poly_offset; - INSERT_PADDING_WORDS(0xA318 - 0xA2DF - 5); + INSERT_PADDING_WORDS(0xA2F8 - 0xA2DF - 5); + AaConfig aa_config; + INSERT_PADDING_WORDS(0xA318 - 0xA2F8 - 1); ColorBuffer color_buffers[NumColorBuffers]; INSERT_PADDING_WORDS(0xC242 - 0xA390); PrimitiveType primitive_type; @@ -1022,6 +1036,7 @@ static_assert(GFX6_3D_REG_INDEX(index_size) == 0xA29D); static_assert(GFX6_3D_REG_INDEX(index_buffer_type) == 0xA29F); static_assert(GFX6_3D_REG_INDEX(enable_primitive_id) == 0xA2A1); static_assert(GFX6_3D_REG_INDEX(poly_offset) == 0xA2DF); +static_assert(GFX6_3D_REG_INDEX(aa_config) == 0xA2F8); static_assert(GFX6_3D_REG_INDEX(color_buffers[0].base_address) == 0xA318); static_assert(GFX6_3D_REG_INDEX(color_buffers[0].pitch) == 0xA319); static_assert(GFX6_3D_REG_INDEX(color_buffers[0].slice) == 0xA31A); diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index f95d8f111..6594aab97 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -482,4 +482,17 @@ vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color return {.color = color}; } +vk::SampleCountFlagBits NumSamples(u32 num_samples) { + switch (num_samples) { + case 1: + return vk::SampleCountFlagBits::e1; + case 2: + return vk::SampleCountFlagBits::e2; + case 4: + return vk::SampleCountFlagBits::e4; + default: + UNREACHABLE(); + } +} + } // namespace Vulkan::LiverpoolToVK diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.h b/src/video_core/renderer_vulkan/liverpool_to_vk.h index 90589db62..aae396307 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.h +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.h @@ -48,6 +48,8 @@ vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format, vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer); +vk::SampleCountFlagBits NumSamples(u32 num_samples); + void EmitQuadToTriangleListIndices(u8* out_indices, u32 num_vertices); } // namespace Vulkan::LiverpoolToVK diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index b3401ec1b..bd7a80290 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -92,7 +92,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul }; const vk::PipelineMultisampleStateCreateInfo multisampling = { - .rasterizationSamples = vk::SampleCountFlagBits::e1, + .rasterizationSamples = LiverpoolToVK::NumSamples(key.num_samples), .sampleShadingEnable = false, }; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index cccd35e35..060a26953 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -38,6 +38,7 @@ struct GraphicsPipelineKey { float depth_bias_slope_factor; float depth_bias_clamp; u32 depth_bias_enable; + u32 num_samples = 1; Liverpool::StencilControl stencil; Liverpool::StencilRefMask stencil_ref_front; Liverpool::StencilRefMask stencil_ref_back; diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index afaf30055..ecc273149 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -205,6 +205,7 @@ bool Instance::CreateDevice() { .logicOp = features.logicOp, .samplerAnisotropy = features.samplerAnisotropy, .fragmentStoresAndAtomics = features.fragmentStoresAndAtomics, + .shaderStorageImageMultisample = true, .shaderClipDistance = features.shaderClipDistance, }, }, diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 96e731956..a6d4b7700 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -114,6 +114,7 @@ void PipelineCache::RefreshGraphicsKey() { key.cull_mode = regs.polygon_control.CullingMode(); key.clip_space = regs.clipper_control.clip_space; key.front_face = regs.polygon_control.front_face; + key.num_samples = regs.aa_config.NumSamples(); const auto& db = regs.depth_buffer; if (key.depth.depth_enable) { diff --git a/src/video_core/texture_cache/image.cpp b/src/video_core/texture_cache/image.cpp index 101e57700..22006eb81 100644 --- a/src/video_core/texture_cache/image.cpp +++ b/src/video_core/texture_cache/image.cpp @@ -252,6 +252,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, }, .mipLevels = static_cast(info.resources.levels), .arrayLayers = static_cast(info.resources.layers), + .samples = LiverpoolToVK::NumSamples(info.num_samples), .tiling = vk::ImageTiling::eOptimal, .usage = usage, .initialLayout = vk::ImageLayout::eUndefined, @@ -267,7 +268,7 @@ Image::Image(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, } Transit(vk::ImageLayout::eGeneral, vk::AccessFlagBits::eNone); -} +} // namespace VideoCore void Image::Transit(vk::ImageLayout dst_layout, vk::Flags dst_mask) { if (dst_layout == layout && dst_mask == access_mask) {