From f67628f030daaeb75812d434b083d9fc108329ba Mon Sep 17 00:00:00 2001 From: raphaelthegreat <47210458+raphaelthegreat@users.noreply.github.com> Date: Fri, 7 Jun 2024 15:48:37 +0300 Subject: [PATCH] liverpool: Fix wrong color buffer number type and viewport zscale * Also add some more formats --- src/video_core/amdgpu/liverpool.h | 7 +++-- src/video_core/amdgpu/resource.h | 12 +++++++- .../renderer_vulkan/liverpool_to_vk.cpp | 28 ++++++++++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index a190a870..e4d22cdc 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -512,8 +512,8 @@ struct Liverpool { float xoffset; float yscale; float yoffset; - float zoffset; float zscale; + float zoffset; }; union ViewportControl { @@ -570,6 +570,7 @@ struct Liverpool { Subtract = 1, Min = 2, Max = 3, + ReverseSubtract = 4, }; BitField<0, 5, BlendFactor> color_src_factor; @@ -618,7 +619,7 @@ struct Liverpool { BitField<0, 2, EndianSwap> endian; BitField<2, 5, DataFormat> format; BitField<7, 1, u32> linear_general; - BitField<8, 2, NumberFormat> number_type; + BitField<8, 3, NumberFormat> number_type; BitField<11, 2, SwapMode> comp_swap; BitField<13, 1, u32> fast_clear; BitField<14, 1, u32> compression; @@ -686,7 +687,7 @@ struct Liverpool { NumberFormat NumFormat() const { // There is a small difference between T# and CB number types, account for it. - return info.number_type == AmdGpu::NumberFormat::Uscaled ? AmdGpu::NumberFormat::Srgb + return info.number_type == AmdGpu::NumberFormat::SnormNz ? AmdGpu::NumberFormat::Srgb : info.number_type; } }; diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index 58e54118..ba2231b0 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -148,10 +148,20 @@ struct Image { } u32 NumLayers() const { - return last_array - base_array + 1; + u32 slices = type == ImageType::Color3D ? 1 : depth.Value() + 1; + if (type == ImageType::Cube) { + slices *= 6; + } + if (pow2pad) { + slices = std::bit_ceil(slices); + } + return slices; } u32 NumLevels() const { + if (type == ImageType::Color2DMsaa || type == ImageType::Color2DMsaaArray) { + return 1; + } return last_level + 1; } diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index eb319f09..000063d5 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -176,6 +176,8 @@ vk::BlendOp BlendOp(Liverpool::BlendControl::BlendFunc func) { return vk::BlendOp::eMin; case BlendFunc::Max: return vk::BlendOp::eMax; + case BlendFunc::ReverseSubtract: + return vk::BlendOp::eReverseSubtract; default: UNREACHABLE(); } @@ -316,7 +318,23 @@ vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat nu if (data_format == AmdGpu::DataFormat::FormatBc7 && num_format == AmdGpu::NumberFormat::Srgb) { return vk::Format::eBc7SrgbBlock; } - UNREACHABLE(); + if (data_format == AmdGpu::DataFormat::FormatBc1 && num_format == AmdGpu::NumberFormat::Unorm) { + return vk::Format::eBc1RgbaUnormBlock; + } + if (data_format == AmdGpu::DataFormat::FormatBc3 && num_format == AmdGpu::NumberFormat::Unorm) { + return vk::Format::eBc3UnormBlock; + } + if (data_format == AmdGpu::DataFormat::Format8_8_8_8 && + num_format == AmdGpu::NumberFormat::Uint) { + return vk::Format::eR8G8B8A8Uint; + } + if (data_format == AmdGpu::DataFormat::Format16 && num_format == AmdGpu::NumberFormat::Float) { + return vk::Format::eR16Sfloat; + } + if (data_format == AmdGpu::DataFormat::Format32 && num_format == AmdGpu::NumberFormat::Float) { + return vk::Format::eR32Sfloat; + } + UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format)); } vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat stencil_format) { @@ -328,6 +346,14 @@ vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat stencil_format == DepthBuffer::StencilFormat::Invalid) { return vk::Format::eD32Sfloat; } + if (z_format == DepthBuffer::ZFormat::Z16 && + stencil_format == DepthBuffer::StencilFormat::Invalid) { + return vk::Format::eD16Unorm; + } + if (z_format == DepthBuffer::ZFormat::Z16 && + stencil_format == DepthBuffer::StencilFormat::Stencil8) { + return vk::Format::eD16UnormS8Uint; + } UNREACHABLE(); }