mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-06 18:53:16 +00:00
graphics: Improve handling of color buffer and storage image swizzles (#1763)
* liverpool_to_vk: Remove wrong component swap formats * shader_recompiler: Handle storage and buffer format swizzles * shader_recompiler: Skip unsupported depth export * image_view: Remove image format swizzle * Platform support is not always guaranteed
This commit is contained in:
parent
028be3ba5d
commit
722a0e36be
6 changed files with 66 additions and 49 deletions
|
@ -52,6 +52,10 @@ struct Buffer {
|
|||
return std::memcmp(this, &other, sizeof(Buffer)) == 0;
|
||||
}
|
||||
|
||||
u32 DstSelect() const {
|
||||
return dst_sel_x | (dst_sel_y << 3) | (dst_sel_z << 6) | (dst_sel_w << 9);
|
||||
}
|
||||
|
||||
CompSwizzle GetSwizzle(u32 comp) const noexcept {
|
||||
const std::array select{dst_sel_x, dst_sel_y, dst_sel_z, dst_sel_w};
|
||||
return static_cast<CompSwizzle>(select[comp]);
|
||||
|
@ -204,6 +208,11 @@ struct Image {
|
|||
return dst_sel_x | (dst_sel_y << 3) | (dst_sel_z << 6) | (dst_sel_w << 9);
|
||||
}
|
||||
|
||||
CompSwizzle GetSwizzle(u32 comp) const noexcept {
|
||||
const std::array select{dst_sel_x, dst_sel_y, dst_sel_z, dst_sel_w};
|
||||
return static_cast<CompSwizzle>(select[comp]);
|
||||
}
|
||||
|
||||
static char SelectComp(u32 sel) {
|
||||
switch (sel) {
|
||||
case 0:
|
||||
|
|
|
@ -699,15 +699,6 @@ vk::Format AdjustColorBufferFormat(vk::Format base_format,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
} else if (comp_swap_reverse) {
|
||||
switch (base_format) {
|
||||
case vk::Format::eR8G8B8A8Unorm:
|
||||
return vk::Format::eA8B8G8R8UnormPack32;
|
||||
case vk::Format::eR8G8B8A8Srgb:
|
||||
return vk::Format::eA8B8G8R8SrgbPack32;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return base_format;
|
||||
}
|
||||
|
|
|
@ -50,34 +50,6 @@ vk::ComponentSwizzle ConvertComponentSwizzle(u32 dst_sel) {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsIdentityMapping(u32 dst_sel, u32 num_components) {
|
||||
return (num_components == 1 && dst_sel == 0b001'000'000'100) ||
|
||||
(num_components == 2 && dst_sel == 0b001'000'101'100) ||
|
||||
(num_components == 3 && dst_sel == 0b001'110'101'100) ||
|
||||
(num_components == 4 && dst_sel == 0b111'110'101'100);
|
||||
}
|
||||
|
||||
vk::Format TrySwizzleFormat(vk::Format format, u32 dst_sel) {
|
||||
// BGRA
|
||||
if (dst_sel == 0b111100101110) {
|
||||
switch (format) {
|
||||
case vk::Format::eR8G8B8A8Unorm:
|
||||
return vk::Format::eB8G8R8A8Unorm;
|
||||
case vk::Format::eR8G8B8A8Snorm:
|
||||
return vk::Format::eB8G8R8A8Snorm;
|
||||
case vk::Format::eR8G8B8A8Uint:
|
||||
return vk::Format::eB8G8R8A8Uint;
|
||||
case vk::Format::eR8G8B8A8Sint:
|
||||
return vk::Format::eB8G8R8A8Sint;
|
||||
case vk::Format::eR8G8B8A8Srgb:
|
||||
return vk::Format::eB8G8R8A8Srgb;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageResource& desc) noexcept
|
||||
: is_storage{desc.is_storage} {
|
||||
const auto dfmt = image.GetDataFmt();
|
||||
|
@ -120,17 +92,6 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso
|
|||
mapping.b = ConvertComponentSwizzle(image.dst_sel_z);
|
||||
mapping.a = ConvertComponentSwizzle(image.dst_sel_w);
|
||||
}
|
||||
// Check for unfortunate case of storage images being swizzled
|
||||
const u32 num_comps = AmdGpu::NumComponents(image.GetDataFmt());
|
||||
const u32 dst_sel = image.DstSelect();
|
||||
if (is_storage && !IsIdentityMapping(dst_sel, num_comps)) {
|
||||
if (auto new_format = TrySwizzleFormat(format, dst_sel); new_format != format) {
|
||||
format = new_format;
|
||||
return;
|
||||
}
|
||||
LOG_ERROR(Render_Vulkan, "Storage image (num_comps = {}) requires swizzling {}", num_comps,
|
||||
image.DstSelectName());
|
||||
}
|
||||
}
|
||||
|
||||
ImageViewInfo::ImageViewInfo(const AmdGpu::Liverpool::ColorBuffer& col_buffer) noexcept {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue