video_out: proper sRGB output workflow
This commit is contained in:
parent
b2b45bf480
commit
b02ec385b2
|
@ -276,12 +276,7 @@ vk::BorderColor BorderColor(AmdGpu::BorderColor color) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Format SurfaceFormat(
|
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) {
|
||||||
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));
|
|
||||||
|
|
||||||
if (data_format == AmdGpu::DataFormat::Format32_32_32_32 &&
|
if (data_format == AmdGpu::DataFormat::Format32_32_32_32 &&
|
||||||
num_format == AmdGpu::NumberFormat::Float) {
|
num_format == AmdGpu::NumberFormat::Float) {
|
||||||
|
@ -293,14 +288,11 @@ vk::Format SurfaceFormat(
|
||||||
}
|
}
|
||||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||||
num_format == AmdGpu::NumberFormat::Unorm) {
|
num_format == AmdGpu::NumberFormat::Unorm) {
|
||||||
return comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate
|
return vk::Format::eR8G8B8A8Unorm;
|
||||||
? vk::Format::eB8G8R8A8Unorm
|
|
||||||
: vk::Format::eR8G8B8A8Unorm;
|
|
||||||
}
|
}
|
||||||
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
if (data_format == AmdGpu::DataFormat::Format8_8_8_8 &&
|
||||||
num_format == AmdGpu::NumberFormat::Srgb) {
|
num_format == AmdGpu::NumberFormat::Srgb) {
|
||||||
return comp_swap == Liverpool::ColorBuffer::SwapMode::Alternate ? vk::Format::eB8G8R8A8Srgb
|
return vk::Format::eR8G8B8A8Srgb;
|
||||||
: vk::Format::eR8G8B8A8Srgb;
|
|
||||||
}
|
}
|
||||||
if (data_format == AmdGpu::DataFormat::Format32_32_32 &&
|
if (data_format == AmdGpu::DataFormat::Format32_32_32 &&
|
||||||
num_format == AmdGpu::NumberFormat::Float) {
|
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));
|
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) {
|
vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat stencil_format) {
|
||||||
if (z_format == DepthBuffer::ZFormat::Z32Float &&
|
if (z_format == DepthBuffer::ZFormat::Z32Float &&
|
||||||
stencil_format == DepthBuffer::StencilFormat::Stencil8) {
|
stencil_format == DepthBuffer::StencilFormat::Stencil8) {
|
||||||
|
|
|
@ -38,9 +38,10 @@ vk::SamplerMipmapMode MipFilter(AmdGpu::MipFilter filter);
|
||||||
|
|
||||||
vk::BorderColor BorderColor(AmdGpu::BorderColor color);
|
vk::BorderColor BorderColor(AmdGpu::BorderColor color);
|
||||||
|
|
||||||
vk::Format SurfaceFormat(
|
vk::Format SurfaceFormat(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format);
|
||||||
AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format,
|
|
||||||
Liverpool::ColorBuffer::SwapMode comp_swap = Liverpool::ColorBuffer::SwapMode::Standard);
|
vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
||||||
|
Liverpool::ColorBuffer::SwapMode comp_swap, bool is_vo_surface);
|
||||||
|
|
||||||
vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format,
|
vk::Format DepthFormat(Liverpool::DepthBuffer::ZFormat z_format,
|
||||||
Liverpool::DepthBuffer::StencilFormat stencil_format);
|
Liverpool::DepthBuffer::StencilFormat stencil_format);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include "video_core/amdgpu/liverpool.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
#include "video_core/renderer_vulkan/vk_swapchain.h"
|
#include "video_core/renderer_vulkan/vk_swapchain.h"
|
||||||
|
@ -50,10 +51,17 @@ public:
|
||||||
|
|
||||||
VideoCore::Image& RegisterVideoOutSurface(
|
VideoCore::Image& RegisterVideoOutSurface(
|
||||||
const Libraries::VideoOut::BufferAttributeGroup& attribute, VAddr cpu_address) {
|
const Libraries::VideoOut::BufferAttributeGroup& attribute, VAddr cpu_address) {
|
||||||
|
vo_buffers_addr.emplace_back(cpu_address);
|
||||||
const auto info = VideoCore::ImageInfo{attribute};
|
const auto info = VideoCore::ImageInfo{attribute};
|
||||||
return texture_cache.FindImage(info, cpu_address);
|
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);
|
bool ShowSplash(Frame* frame = nullptr);
|
||||||
void Present(Frame* frame);
|
void Present(Frame* frame);
|
||||||
void RecreateFrame(Frame* frame, u32 width, u32 height);
|
void RecreateFrame(Frame* frame, u32 width, u32 height);
|
||||||
|
@ -76,6 +84,7 @@ private:
|
||||||
std::condition_variable free_cv;
|
std::condition_variable free_cv;
|
||||||
std::condition_variable_any frame_cv;
|
std::condition_variable_any frame_cv;
|
||||||
std::optional<VideoCore::Image> splash_img;
|
std::optional<VideoCore::Image> splash_img;
|
||||||
|
std::vector<VAddr> vo_buffers_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
@ -8,11 +8,14 @@
|
||||||
#include "shader_recompiler/exception.h"
|
#include "shader_recompiler/exception.h"
|
||||||
#include "shader_recompiler/recompiler.h"
|
#include "shader_recompiler/recompiler.h"
|
||||||
#include "shader_recompiler/runtime_info.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_instance.h"
|
||||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||||
|
|
||||||
|
extern std::unique_ptr<Vulkan::RendererVulkan> renderer;
|
||||||
|
|
||||||
namespace Vulkan {
|
namespace Vulkan {
|
||||||
|
|
||||||
Shader::Info MakeShaderInfo(Shader::Stage stage, std::span<const u32, 16> user_data,
|
Shader::Info MakeShaderInfo(Shader::Stage stage, std::span<const u32, 16> user_data,
|
||||||
|
@ -129,8 +132,11 @@ void PipelineCache::RefreshGraphicsKey() {
|
||||||
if (!col_buf) {
|
if (!col_buf) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
key.color_formats[remapped_cb] = LiverpoolToVK::SurfaceFormat(
|
const auto base_format =
|
||||||
col_buf.info.format, col_buf.NumFormat(), col_buf.info.comp_swap.Value());
|
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] = regs.blend_control[cb];
|
||||||
key.blend_controls[remapped_cb].enable.Assign(key.blend_controls[remapped_cb].enable &&
|
key.blend_controls[remapped_cb].enable.Assign(key.blend_controls[remapped_cb].enable &&
|
||||||
!col_buf.info.blend_bypass);
|
!col_buf.info.blend_bypass);
|
||||||
|
|
|
@ -132,6 +132,7 @@ ImageInfo::ImageInfo(const Libraries::VideoOut::BufferAttributeGroup& group) noe
|
||||||
} else {
|
} else {
|
||||||
guest_size_bytes = pitch * 128 * ((size.height + 63) & (~63)) * 4;
|
guest_size_bytes = pitch * 128 * ((size.height + 63) & (~63)) * 4;
|
||||||
}
|
}
|
||||||
|
is_vo_surface = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
ImageInfo::ImageInfo(const AmdGpu::Liverpool::ColorBuffer& buffer,
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct ImageInfo {
|
||||||
|
|
||||||
bool is_tiled = false;
|
bool is_tiled = false;
|
||||||
bool is_storage = false;
|
bool is_storage = false;
|
||||||
|
bool is_vo_surface = false;
|
||||||
vk::Format pixel_format = vk::Format::eUndefined;
|
vk::Format pixel_format = vk::Format::eUndefined;
|
||||||
vk::ImageType type = vk::ImageType::e1D;
|
vk::ImageType type = vk::ImageType::e1D;
|
||||||
vk::ImageUsageFlags usage;
|
vk::ImageUsageFlags usage;
|
||||||
|
|
|
@ -62,9 +62,12 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexce
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) noexcept {
|
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer,
|
||||||
format = Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.info.format, col_buffer.NumFormat(),
|
bool is_vo_surface) noexcept {
|
||||||
col_buffer.info.comp_swap.Value());
|
const auto base_format =
|
||||||
|
Vulkan::LiverpoolToVK::SurfaceFormat(col_buffer.info.format, col_buffer.NumFormat());
|
||||||
|
format = Vulkan::LiverpoolToVK::AdjustColorBufferFormat(
|
||||||
|
base_format, col_buffer.info.comp_swap.Value(), is_vo_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info_, Image& image,
|
ImageView::ImageView(const Vulkan::Instance& instance, const ImageViewInfo& info_, Image& image,
|
||||||
|
|
|
@ -20,7 +20,8 @@ namespace VideoCore {
|
||||||
struct ImageViewInfo {
|
struct ImageViewInfo {
|
||||||
explicit ImageViewInfo() = default;
|
explicit ImageViewInfo() = default;
|
||||||
explicit ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexcept;
|
explicit ImageViewInfo(const AmdGpu::Image& image, bool is_storage) noexcept;
|
||||||
explicit ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) noexcept;
|
explicit ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer,
|
||||||
|
bool is_vo_surface) noexcept;
|
||||||
|
|
||||||
vk::ImageViewType type = vk::ImageViewType::e2D;
|
vk::ImageViewType type = vk::ImageViewType::e2D;
|
||||||
vk::Format format = vk::Format::eR8G8B8A8Unorm;
|
vk::Format format = vk::Format::eR8G8B8A8Unorm;
|
||||||
|
|
|
@ -183,7 +183,7 @@ ImageView& TextureCache::RenderTarget(const AmdGpu::Liverpool::ColorBuffer& buff
|
||||||
vk::AccessFlagBits::eColorAttachmentWrite |
|
vk::AccessFlagBits::eColorAttachmentWrite |
|
||||||
vk::AccessFlagBits::eColorAttachmentRead);
|
vk::AccessFlagBits::eColorAttachmentRead);
|
||||||
|
|
||||||
ImageViewInfo view_info{buffer};
|
ImageViewInfo view_info{buffer, image.info.is_vo_surface};
|
||||||
return RegisterImageView(image, view_info);
|
return RegisterImageView(image, view_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue