video_out: proper sRGB output workflow

This commit is contained in:
psucien 2024-06-15 23:16:53 +02:00
parent b2b45bf480
commit b02ec385b2
9 changed files with 60 additions and 21 deletions

View file

@ -276,12 +276,7 @@ vk::BorderColor BorderColor(AmdGpu::BorderColor color) {
}
}
vk::Format SurfaceFormat(
AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format,
Liverpool::ColorBuffer::SwapMode comp_swap /*= Liverpool::ColorBuffer::SwapMode::Standard*/) {
ASSERT_MSG(comp_swap == Liverpool::ColorBuffer::SwapMode::Standard ||
comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate,
"Unsupported component swap mode {}", static_cast<u32>(comp_swap));
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) {
if (data_format == AmdGpu::DataFormat::Format32_32_32_32 &&
num_format == AmdGpu::NumberFormat::Float) {
@ -293,14 +288,11 @@ vk::Format SurfaceFormat(
}
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
num_format == AmdGpu::NumberFormat::Unorm) {
return comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate
? vk::Format::eB8G8R8A8Unorm
: vk::Format::eR8G8B8A8Unorm;
return vk::Format::eR8G8B8A8Unorm;
}
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
num_format == AmdGpu::NumberFormat::Srgb) {
return comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate ? vk::Format::eB8G8R8A8Srgb
: vk::Format::eR8G8B8A8Srgb;
return vk::Format::eR8G8B8A8Srgb;
}
if (data_format == AmdGpu::DataFormat::Format32_32_32 &&
num_format == AmdGpu::NumberFormat::Float) {
@ -362,6 +354,31 @@ vk::Format SurfaceFormat(
UNREACHABLE_MSG("Unknown data_format={} and num_format={}", u32(data_format), u32(num_format));
}
vk::Format AdjustColorBufferFormat(vk::Format base_format,
Liverpool::ColorBuffer::SwapMode comp_swap, bool is_vo_surface) {
ASSERT_MSG(comp_swap == Liverpool::ColorBuffer::SwapMode::Standard ||
comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate,
"Unsupported component swap mode {}", static_cast<u32>(comp_swap));
const bool comp_swap_alt = comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate;
switch (base_format) {
case vk::Format::eR8G8B8A8Unorm:
return comp_swap_alt ? vk::Format::eB8G8R8A8Unorm : base_format;
case vk::Format::eB8G8R8A8Unorm:
return comp_swap_alt ? vk::Format::eR8G8B8A8Unorm : base_format;
case vk::Format::eR8G8B8A8Srgb:
return comp_swap_alt ? vk::Format::eB8G8R8A8Unorm
: is_vo_surface ? vk::Format::eR8G8B8A8Unorm
: base_format;
case vk::Format::eB8G8R8A8Srgb:
return comp_swap_alt ? vk::Format::eR8G8B8A8Unorm
: is_vo_surface ? vk::Format::eB8G8R8A8Unorm
: base_format;
}
UNREACHABLE_MSG("Unsupported base format {}", vk::to_string(base_format));
}
vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat stencil_format) {
if (z_format == DepthBuffer::ZFormat::Z32Float &&
stencil_format == DepthBuffer::StencilFormat::Stencil8) {

View file

@ -38,9 +38,10 @@ vk::SamplerMipmapMode MipFilter(AmdGpu::MipFilter filter);
vk::BorderColor BorderColor(AmdGpu::BorderColor color);
vk::Format SurfaceFormat(
AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format,
Liverpool::ColorBuffer::SwapMode comp_swap = Liverpool::ColorBuffer::SwapMode::Standard);
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format);
vk::Format AdjustColorBufferFormat(vk::Format base_format,
Liverpool::ColorBuffer::SwapMode comp_swap, bool is_vo_surface);
vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format,
Liverpool::DepthBuffer::StencilFormat stencil_format);

View file

@ -4,6 +4,7 @@
#pragma once
#include <condition_variable>
#include "video_core/amdgpu/liverpool.h"
#include "video_core/renderer_vulkan/vk_instance.h"
#include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_swapchain.h"
@ -50,10 +51,17 @@ public:
VideoCore::Image& RegisterVideoOutSurface(
const Libraries::VideoOut::BufferAttributeGroup& attribute, VAddr cpu_address) {
vo_buffers_addr.emplace_back(cpu_address);
const auto info = VideoCore::ImageInfo{attribute};
return texture_cache.FindImage(info, cpu_address);
}
bool IsVideoOutSurface(const AmdGpu::Liverpool::ColorBuffer& color_buffer) {
return std::find_if(vo_buffers_addr.cbegin(), vo_buffers_addr.cend(), [&](VAddr vo_buffer) {
return vo_buffer == color_buffer.Address();
}) != vo_buffers_addr.cend();
}
bool ShowSplash(Frame* frame = nullptr);
void Present(Frame* frame);
void RecreateFrame(Frame* frame, u32 width, u32 height);
@ -76,6 +84,7 @@ private:
std::condition_variable free_cv;
std::condition_variable_any frame_cv;
std::optional<VideoCore::Image> splash_img;
std::vector<VAddr> vo_buffers_addr;
};
} // namespace Vulkan

View file

@ -8,11 +8,14 @@
#include "shader_recompiler/exception.h"
#include "shader_recompiler/recompiler.h"
#include "shader_recompiler/runtime_info.h"
#include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "video_core/renderer_vulkan/vk_instance.h"
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
#include "video_core/renderer_vulkan/vk_scheduler.h"
#include "video_core/renderer_vulkan/vk_shader_util.h"
extern std::unique_ptr<Vulkan::RendererVulkan> renderer;
namespace Vulkan {
Shader::Info MakeShaderInfo(Shader::Stage stage, std::span<const u32, 16> user_data,
@ -129,8 +132,11 @@ void PipelineCache::RefreshGraphicsKey() {
if (!col_buf) {
continue;
}
key.color_formats[remapped_cb] = LiverpoolToVK::SurfaceFormat(
col_buf.info.format, col_buf.NumFormat(), col_buf.info.comp_swap.Value());
const auto base_format =
LiverpoolToVK::SurfaceFormat(col_buf.info.format, col_buf.NumFormat());
const auto is_vo_surface = renderer->IsVideoOutSurface(col_buf);
key.color_formats[remapped_cb] = LiverpoolToVK::AdjustColorBufferFormat(
base_format, col_buf.info.comp_swap.Value(), is_vo_surface);
key.blend_controls[remapped_cb] = regs.blend_control[cb];
key.blend_controls[remapped_cb].enable.Assign(key.blend_controls[remapped_cb].enable &&
!col_buf.info.blend_bypass);