mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-26 12:26:18 +00:00
shader_recompiler: Add swizzle support for unsupported formats. (#1869)
* shader_recompiler: Add swizzle support for unsupported formats. * renderer_vulkan: Rework MRT swizzles and add unsupported format swizzle support. * shader_recompiler: Clean up swizzle handling and handle ImageRead storage swizzle. * shader_recompiler: Fix type errors * liverpool_to_vk: Remove redundant clear color swizzles. * shader_recompiler: Reduce CompositeConstruct to constants where possible. * shader_recompiler: Fix ImageRead/Write and StoreBufferFormatF32 types. * amdgpu: Add a few more unsupported format remaps.
This commit is contained in:
parent
284f473a52
commit
41d64a200d
22 changed files with 522 additions and 282 deletions
|
@ -25,34 +25,28 @@ void Translator::EmitExport(const GcnInst& inst) {
|
|||
IR::VectorReg(inst.src[3].code),
|
||||
};
|
||||
|
||||
const auto swizzle = [&](u32 comp) {
|
||||
const auto set_attribute = [&](u32 comp, IR::F32 value) {
|
||||
if (!IR::IsMrt(attrib)) {
|
||||
return comp;
|
||||
ir.SetAttribute(attrib, value, comp);
|
||||
return;
|
||||
}
|
||||
const u32 index = u32(attrib) - u32(IR::Attribute::RenderTarget0);
|
||||
switch (runtime_info.fs_info.color_buffers[index].mrt_swizzle) {
|
||||
case MrtSwizzle::Identity:
|
||||
return comp;
|
||||
case MrtSwizzle::Alt:
|
||||
static constexpr std::array<u32, 4> AltSwizzle = {2, 1, 0, 3};
|
||||
return AltSwizzle[comp];
|
||||
case MrtSwizzle::Reverse:
|
||||
static constexpr std::array<u32, 4> RevSwizzle = {3, 2, 1, 0};
|
||||
return RevSwizzle[comp];
|
||||
case MrtSwizzle::ReverseAlt:
|
||||
static constexpr std::array<u32, 4> AltRevSwizzle = {3, 0, 1, 2};
|
||||
return AltRevSwizzle[comp];
|
||||
default:
|
||||
UNREACHABLE();
|
||||
const auto [r, g, b, a] = runtime_info.fs_info.color_buffers[index].swizzle;
|
||||
const std::array swizzle_array = {r, g, b, a};
|
||||
const auto swizzled_comp = swizzle_array[comp];
|
||||
if (u32(swizzled_comp) < u32(AmdGpu::CompSwizzle::Red)) {
|
||||
ir.SetAttribute(attrib, value, comp);
|
||||
return;
|
||||
}
|
||||
ir.SetAttribute(attrib, value, u32(swizzled_comp) - u32(AmdGpu::CompSwizzle::Red));
|
||||
};
|
||||
|
||||
const auto unpack = [&](u32 idx) {
|
||||
const IR::Value value = ir.UnpackHalf2x16(ir.GetVectorReg(vsrc[idx]));
|
||||
const IR::F32 r = IR::F32{ir.CompositeExtract(value, 0)};
|
||||
const IR::F32 g = IR::F32{ir.CompositeExtract(value, 1)};
|
||||
ir.SetAttribute(attrib, r, swizzle(idx * 2));
|
||||
ir.SetAttribute(attrib, g, swizzle(idx * 2 + 1));
|
||||
set_attribute(idx * 2, r);
|
||||
set_attribute(idx * 2 + 1, g);
|
||||
};
|
||||
|
||||
// Components are float16 packed into a VGPR
|
||||
|
@ -73,7 +67,7 @@ void Translator::EmitExport(const GcnInst& inst) {
|
|||
continue;
|
||||
}
|
||||
const IR::F32 comp = ir.GetVectorReg<IR::F32>(vsrc[i]);
|
||||
ir.SetAttribute(attrib, comp, swizzle(i));
|
||||
set_attribute(i, comp);
|
||||
}
|
||||
}
|
||||
if (IR::IsMrt(attrib)) {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "shader_recompiler/info.h"
|
||||
#include "shader_recompiler/ir/attribute.h"
|
||||
#include "shader_recompiler/ir/reg.h"
|
||||
#include "shader_recompiler/ir/reinterpret.h"
|
||||
#include "shader_recompiler/runtime_info.h"
|
||||
#include "video_core/amdgpu/resource.h"
|
||||
#include "video_core/amdgpu/types.h"
|
||||
|
@ -475,26 +476,12 @@ void Translator::EmitFetch(const GcnInst& inst) {
|
|||
|
||||
// Read the V# of the attribute to figure out component number and type.
|
||||
const auto buffer = info.ReadUdReg<AmdGpu::Buffer>(attrib.sgpr_base, attrib.dword_offset);
|
||||
const auto values =
|
||||
ir.CompositeConstruct(ir.GetAttribute(attr, 0), ir.GetAttribute(attr, 1),
|
||||
ir.GetAttribute(attr, 2), ir.GetAttribute(attr, 3));
|
||||
const auto swizzled = ApplySwizzle(ir, values, buffer.DstSelect());
|
||||
for (u32 i = 0; i < 4; i++) {
|
||||
const IR::F32 comp = [&] {
|
||||
switch (buffer.GetSwizzle(i)) {
|
||||
case AmdGpu::CompSwizzle::One:
|
||||
return ir.Imm32(1.f);
|
||||
case AmdGpu::CompSwizzle::Zero:
|
||||
return ir.Imm32(0.f);
|
||||
case AmdGpu::CompSwizzle::Red:
|
||||
return ir.GetAttribute(attr, 0);
|
||||
case AmdGpu::CompSwizzle::Green:
|
||||
return ir.GetAttribute(attr, 1);
|
||||
case AmdGpu::CompSwizzle::Blue:
|
||||
return ir.GetAttribute(attr, 2);
|
||||
case AmdGpu::CompSwizzle::Alpha:
|
||||
return ir.GetAttribute(attr, 3);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}();
|
||||
ir.SetVectorReg(dst_reg++, comp);
|
||||
ir.SetVectorReg(dst_reg++, IR::F32{ir.CompositeExtract(swizzled, i)});
|
||||
}
|
||||
|
||||
// In case of programmable step rates we need to fallback to instance data pulling in
|
||||
|
|
|
@ -326,7 +326,7 @@ void Translator::BUFFER_STORE_FORMAT(u32 num_dwords, const GcnInst& inst) {
|
|||
|
||||
const IR::VectorReg src_reg{inst.src[1].code};
|
||||
|
||||
std::array<IR::Value, 4> comps{};
|
||||
std::array<IR::F32, 4> comps{};
|
||||
for (u32 i = 0; i < num_dwords; i++) {
|
||||
comps[i] = ir.GetVectorReg<IR::F32>(src_reg + i);
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ void Translator::IMAGE_LOAD(bool has_mip, const GcnInst& inst) {
|
|||
if (((mimg.dmask >> i) & 1) == 0) {
|
||||
continue;
|
||||
}
|
||||
IR::U32 value = IR::U32{ir.CompositeExtract(texel, i)};
|
||||
IR::F32 value = IR::F32{ir.CompositeExtract(texel, i)};
|
||||
ir.SetVectorReg(dest_reg++, value);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue