mirror of
https://github.com/InoriRus/Kyty.git
synced 2024-06-21 14:01:47 -04:00
Improve shader recompiler
This commit is contained in:
parent
43f49c8763
commit
0242926a7c
|
@ -75,7 +75,7 @@ if (CLANG AND (KYTY_LINKER STREQUAL LLD))
|
|||
set(KYTY_LD_OPTIONS "-fuse-ld=lld")
|
||||
endif()
|
||||
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.1)
|
||||
project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.0.2)
|
||||
|
||||
include(src_script.cmake)
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include "Emulator/Common.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Graphics {
|
||||
|
@ -27,9 +29,6 @@ enum class ShaderType
|
|||
enum class ShaderInstructionType
|
||||
{
|
||||
Unknown,
|
||||
DsAppend,
|
||||
DsConsume,
|
||||
Exp,
|
||||
BufferLoadDword,
|
||||
BufferLoadFormatX,
|
||||
BufferLoadFormatXy,
|
||||
|
@ -37,50 +36,78 @@ enum class ShaderInstructionType
|
|||
BufferLoadFormatXyzw,
|
||||
BufferStoreDword,
|
||||
BufferStoreFormatX,
|
||||
DsAppend,
|
||||
DsConsume,
|
||||
Exp,
|
||||
ImageSample,
|
||||
TBufferLoadFormatXyzw,
|
||||
SAddI32,
|
||||
SAndB32,
|
||||
SAndn2B64,
|
||||
SAndSaveexecB64,
|
||||
SEndpgm,
|
||||
SCbranchExecz,
|
||||
SLshlB32,
|
||||
SLoadDwordx4,
|
||||
SLoadDwordx8,
|
||||
SBufferLoadDword,
|
||||
SBufferLoadDwordx16,
|
||||
SBufferLoadDwordx2,
|
||||
SBufferLoadDwordx4,
|
||||
SBufferLoadDwordx8,
|
||||
SBufferLoadDwordx16,
|
||||
SCbranchExecz,
|
||||
SCbranchScc0,
|
||||
SCmpEqU32,
|
||||
SEndpgm,
|
||||
SLoadDwordx4,
|
||||
SLoadDwordx8,
|
||||
SLshlB32,
|
||||
SLshrB32,
|
||||
SMovB32,
|
||||
SMovB64,
|
||||
SMulI32,
|
||||
SNorB64,
|
||||
SOrB64,
|
||||
SCselectB32,
|
||||
SSetpcB64,
|
||||
SSwappcB64,
|
||||
SWaitcnt,
|
||||
SWqmB64,
|
||||
TBufferLoadFormatXyzw,
|
||||
VAddI32,
|
||||
VAndB32,
|
||||
VAshrrevI32,
|
||||
VBfeU32,
|
||||
VCmpEqF32,
|
||||
VCmpEqU32,
|
||||
VCmpGtI32,
|
||||
VCmpLeF32,
|
||||
VCmpLeU32,
|
||||
VCmpNeU32,
|
||||
VCmpNeqF32,
|
||||
VCmpNeU32,
|
||||
VCmpxEqU32,
|
||||
VCmpxGtU32,
|
||||
VCmpxNeU32,
|
||||
VCndmaskB32,
|
||||
VCvtF32U32,
|
||||
VCvtF32Ubyte0,
|
||||
VCvtF32Ubyte1,
|
||||
VCvtF32Ubyte2,
|
||||
VCvtF32Ubyte3,
|
||||
VCvtPkrtzF16F32,
|
||||
VCvtU32F32,
|
||||
VInterpP1F32,
|
||||
VInterpP2F32,
|
||||
VLshlrevB32,
|
||||
VLshrB32,
|
||||
VLshrrevB32,
|
||||
VMacF32,
|
||||
VMadakF32,
|
||||
VMadF32,
|
||||
VMadU32U24,
|
||||
VMaxF32,
|
||||
VMbcntHiU32B32,
|
||||
VMbcntLoU32B32,
|
||||
VMinF32,
|
||||
VMovB32,
|
||||
VMulF32,
|
||||
VInterpP1F32,
|
||||
VInterpP2F32,
|
||||
VMulLoI32,
|
||||
VMulU32U24,
|
||||
VNotB32,
|
||||
VRcpF32,
|
||||
VRsqF32,
|
||||
VSadU32,
|
||||
|
@ -123,6 +150,7 @@ enum FormatByte : uint64_t
|
|||
S2A4, // operand_array_to_str(inst.src[2], 4)
|
||||
Attr, // attr%u.%u <- inst.src[1].constant.u, inst.src[2].constant.u
|
||||
Idxen, // idxen
|
||||
Offen, // offen
|
||||
Float4, // format:float4
|
||||
Pos0, // pos0
|
||||
Done, // done
|
||||
|
@ -131,6 +159,7 @@ enum FormatByte : uint64_t
|
|||
Param2, // param2
|
||||
Param3, // param3
|
||||
Mrt0, // mrt_color0
|
||||
Off, // off
|
||||
Compr, // compr
|
||||
Vm, // vm
|
||||
L, // label_%u
|
||||
|
@ -151,41 +180,46 @@ constexpr uint64_t FormatDefine(std::initializer_list<uint64_t> f)
|
|||
|
||||
enum Format : uint64_t
|
||||
{
|
||||
Unknown = FormatDefine({U}),
|
||||
Empty = FormatDefine({N}),
|
||||
Imm = FormatDefine({S0}),
|
||||
Label = FormatDefine({L}),
|
||||
Mrt0Vsrc0Vsrc1ComprVmDone = FormatDefine({Mrt0, S0, S1, Compr, Vm, Done}),
|
||||
Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone = FormatDefine({Mrt0, S0, S1, S2, S3, Vm, Done}),
|
||||
Param0Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param0, S0, S1, S2, S3}),
|
||||
Param1Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param1, S0, S1, S2, S3}),
|
||||
Param2Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param2, S0, S1, S2, S3}),
|
||||
Param3Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param3, S0, S1, S2, S3}),
|
||||
Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done = FormatDefine({Pos0, S0, S1, S2, S3, Done}),
|
||||
Saddr = FormatDefine({S0A2}),
|
||||
Sdst4SbaseSoffset = FormatDefine({DA4, S0A2, S1}),
|
||||
Sdst8SbaseSoffset = FormatDefine({DA8, S0A2, S1}),
|
||||
SdstSvSoffset = FormatDefine({D, S0A4, S1}),
|
||||
Sdst4SvSoffset = FormatDefine({DA4, S0A4, S1}),
|
||||
Sdst8SvSoffset = FormatDefine({DA8, S0A4, S1}),
|
||||
Sdst16SvSoffset = FormatDefine({DA16, S0A4, S1}),
|
||||
SVdstSVsrc0 = FormatDefine({D, S0}),
|
||||
SVdstSVsrc0SVsrc1 = FormatDefine({D, S0, S1}),
|
||||
Sdst2Ssrc02 = FormatDefine({DA2, S0A2}),
|
||||
Sdst2Ssrc02Ssrc12 = FormatDefine({DA2, S0A2, S1A2}),
|
||||
SmaskVsrc0Vsrc1 = FormatDefine({DA2, S0, S1}),
|
||||
Vdata1VaddrSvSoffsIdxen = FormatDefine({D, S0, S1A4, S2, Idxen}),
|
||||
Vdata2VaddrSvSoffsIdxen = FormatDefine({DA2, S0, S1A4, S2, Idxen}),
|
||||
Vdata3VaddrSvSoffsIdxen = FormatDefine({DA3, S0, S1A4, S2, Idxen}),
|
||||
Vdata4VaddrSvSoffsIdxen = FormatDefine({DA4, S0, S1A4, S2, Idxen}),
|
||||
Vdata4VaddrSvSoffsIdxenFloat4 = FormatDefine({DA4, S0, S1A4, S2, Idxen, Float4}),
|
||||
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
||||
Vdata4Vaddr3StSsDmaskF = FormatDefine({DA4, S0A3, S1A8, S2A4, DmaskF}),
|
||||
VdstVsrc0Vsrc1Smask2 = FormatDefine({D, S0, S1, S2A2}),
|
||||
VdstVsrc0Vsrc1Vsrc2 = FormatDefine({D, S0, S1, S2}),
|
||||
VdstVsrcAttrChan = FormatDefine({D, S0, Attr}),
|
||||
VdstSdst2Vsrc0Vsrc1 = FormatDefine({D, D2A2, S0, S1}),
|
||||
VdstGds = FormatDefine({D, Gds})
|
||||
Unknown = FormatDefine({U}),
|
||||
Empty = FormatDefine({N}),
|
||||
Imm = FormatDefine({S0}),
|
||||
Label = FormatDefine({L}),
|
||||
Mrt0OffOffComprVmDone = FormatDefine({Mrt0, Off, Off, Compr, Vm, Done}),
|
||||
Mrt0Vsrc0Vsrc1ComprVmDone = FormatDefine({Mrt0, S0, S1, Compr, Vm, Done}),
|
||||
Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone = FormatDefine({Mrt0, S0, S1, S2, S3, Vm, Done}),
|
||||
Param0Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param0, S0, S1, S2, S3}),
|
||||
Param1Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param1, S0, S1, S2, S3}),
|
||||
Param2Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param2, S0, S1, S2, S3}),
|
||||
Param3Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param3, S0, S1, S2, S3}),
|
||||
Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done = FormatDefine({Pos0, S0, S1, S2, S3, Done}),
|
||||
Saddr = FormatDefine({S0A2}),
|
||||
Sdst4SbaseSoffset = FormatDefine({DA4, S0A2, S1}),
|
||||
Sdst8SbaseSoffset = FormatDefine({DA8, S0A2, S1}),
|
||||
SdstSvSoffset = FormatDefine({D, S0A4, S1}),
|
||||
Sdst2SvSoffset = FormatDefine({DA2, S0A4, S1}),
|
||||
Sdst4SvSoffset = FormatDefine({DA4, S0A4, S1}),
|
||||
Sdst8SvSoffset = FormatDefine({DA8, S0A4, S1}),
|
||||
Sdst16SvSoffset = FormatDefine({DA16, S0A4, S1}),
|
||||
SVdstSVsrc0 = FormatDefine({D, S0}),
|
||||
SVdstSVsrc0SVsrc1 = FormatDefine({D, S0, S1}),
|
||||
Sdst2Ssrc02 = FormatDefine({DA2, S0A2}),
|
||||
Sdst2Ssrc0 = FormatDefine({DA2, S0}),
|
||||
Sdst2Ssrc02Ssrc12 = FormatDefine({DA2, S0A2, S1A2}),
|
||||
SmaskVsrc0Vsrc1 = FormatDefine({DA2, S0, S1}),
|
||||
Ssrc0Ssrc1 = FormatDefine({S0, S1}),
|
||||
Vdata1VaddrSvSoffsIdxen = FormatDefine({D, S0, S1A4, S2, Idxen}),
|
||||
Vdata2VaddrSvSoffsIdxen = FormatDefine({DA2, S0, S1A4, S2, Idxen}),
|
||||
Vdata3VaddrSvSoffsIdxen = FormatDefine({DA3, S0, S1A4, S2, Idxen}),
|
||||
Vdata4VaddrSvSoffsIdxen = FormatDefine({DA4, S0, S1A4, S2, Idxen}),
|
||||
Vdata4VaddrSvSoffsIdxenFloat4 = FormatDefine({DA4, S0, S1A4, S2, Idxen, Float4}),
|
||||
Vdata4Vaddr2SvSoffsOffenIdxenFloat4 = FormatDefine({DA4, S0A2, S1A4, S2, Offen, Idxen, Float4}),
|
||||
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
||||
Vdata4Vaddr3StSsDmaskF = FormatDefine({DA4, S0A3, S1A8, S2A4, DmaskF}),
|
||||
VdstVsrc0Vsrc1Smask2 = FormatDefine({D, S0, S1, S2A2}),
|
||||
VdstVsrc0Vsrc1Vsrc2 = FormatDefine({D, S0, S1, S2}),
|
||||
VdstVsrcAttrChan = FormatDefine({D, S0, Attr}),
|
||||
VdstSdst2Vsrc0Vsrc1 = FormatDefine({D, D2A2, S0, S1}),
|
||||
VdstGds = FormatDefine({D, Gds}),
|
||||
};
|
||||
|
||||
} // namespace ShaderInstructionFormat
|
||||
|
@ -201,6 +235,7 @@ enum class ShaderOperandType
|
|||
ExecLo,
|
||||
ExecHi,
|
||||
ExecZ,
|
||||
Scc,
|
||||
Vgpr,
|
||||
Sgpr,
|
||||
M0
|
||||
|
@ -240,6 +275,12 @@ struct ShaderInstruction
|
|||
ShaderOperand dst2;
|
||||
};
|
||||
|
||||
struct ShaderLabel
|
||||
{
|
||||
uint32_t dst;
|
||||
uint32_t src;
|
||||
};
|
||||
|
||||
class ShaderCode
|
||||
{
|
||||
public:
|
||||
|
@ -249,8 +290,8 @@ public:
|
|||
|
||||
[[nodiscard]] const Vector<ShaderInstruction>& GetInstructions() const { return m_instructions; }
|
||||
Vector<ShaderInstruction>& GetInstructions() { return m_instructions; }
|
||||
[[nodiscard]] const Vector<uint32_t>& GetLabels() const { return m_labels; }
|
||||
Vector<uint32_t>& GetLabels() { return m_labels; }
|
||||
[[nodiscard]] const Vector<ShaderLabel>& GetLabels() const { return m_labels; }
|
||||
Vector<ShaderLabel>& GetLabels() { return m_labels; }
|
||||
|
||||
[[nodiscard]] String DbgDump() const;
|
||||
|
||||
|
@ -259,9 +300,16 @@ public:
|
|||
[[nodiscard]] ShaderType GetType() const { return m_type; }
|
||||
void SetType(ShaderType type) { this->m_type = type; }
|
||||
|
||||
[[nodiscard]] bool HasAnyOf(std::initializer_list<ShaderInstructionType> types) const
|
||||
{
|
||||
return std::any_of(types.begin(), types.end(),
|
||||
[this](auto type)
|
||||
{ return m_instructions.Contains(type, [](auto inst, auto type) { return inst.type == type; }); });
|
||||
}
|
||||
|
||||
private:
|
||||
Vector<ShaderInstruction> m_instructions;
|
||||
Vector<uint32_t> m_labels;
|
||||
Vector<ShaderLabel> m_labels;
|
||||
ShaderType m_type = ShaderType::Unknown;
|
||||
};
|
||||
|
||||
|
|
|
@ -2616,7 +2616,7 @@ static void FindRenderDepthInfo(const HardwareContext& hw, RenderDepthInfo* r)
|
|||
TileGetDepthSize(z.width, z.height, z.z_info.format, z.stencil_info.format, htile, neo, &stencil_size, &htile_size, &depth_size,
|
||||
&pitch);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED((z.pitch_div8_minus1 + 1) * 8 != pitch);
|
||||
EXIT_NOT_IMPLEMENTED(pitch != 0 && (z.pitch_div8_minus1 + 1) * 8 != pitch);
|
||||
|
||||
switch (z.z_info.format * 2 + z.stencil_info.format)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
#define KYTY_SHADER_PARSER_ARGS \
|
||||
[[maybe_unused]] uint32_t pc, const uint32_t *src, [[maybe_unused]] const uint32_t *buffer, [[maybe_unused]] ShaderCode *dst
|
||||
[[maybe_unused]] uint32_t pc, [[maybe_unused]] const uint32_t *src, [[maybe_unused]] const uint32_t *buffer, \
|
||||
[[maybe_unused]] ShaderCode *dst
|
||||
#define KYTY_SHADER_PARSER(f) static uint32_t f(KYTY_SHADER_PARSER_ARGS)
|
||||
#define KYTY_CP_OP_PARSER_ARGS \
|
||||
[[maybe_unused]] CommandProcessor *cp, [[maybe_unused]] uint32_t cmd_id, [[maybe_unused]] const uint32_t *buffer, \
|
||||
|
@ -103,6 +104,7 @@ static String operand_to_str(ShaderOperand op)
|
|||
case ShaderOperandType::ExecHi: ret = U"exec_hi"; break;
|
||||
case ShaderOperandType::ExecLo: ret = U"exec_lo"; break;
|
||||
case ShaderOperandType::ExecZ: ret = U"execz"; break;
|
||||
case ShaderOperandType::Scc: ret = U"scc"; break;
|
||||
case ShaderOperandType::M0: ret = U"m0"; break;
|
||||
case ShaderOperandType::Vgpr: ret = String::FromPrintf("v%d", op.register_id); break;
|
||||
case ShaderOperandType::Sgpr: ret = String::FromPrintf("s%d", op.register_id); break;
|
||||
|
@ -142,6 +144,8 @@ static String operand_array_to_str(ShaderOperand op, int n)
|
|||
default: break;
|
||||
}
|
||||
|
||||
EXIT_IF(ret == U"???");
|
||||
|
||||
if (op.negate)
|
||||
{
|
||||
return U"-" + ret;
|
||||
|
@ -157,6 +161,7 @@ static String dbg_fmt_to_str(const ShaderInstruction& inst)
|
|||
case ShaderInstructionFormat::Unknown: return U"Unknown"; break;
|
||||
case ShaderInstructionFormat::Empty: return U"Empty"; break;
|
||||
case ShaderInstructionFormat::Imm: return U"Imm"; break;
|
||||
case ShaderInstructionFormat::Mrt0OffOffComprVmDone: return U"Mrt0OffOffComprVmDone"; break;
|
||||
case ShaderInstructionFormat::Mrt0Vsrc0Vsrc1ComprVmDone: return U"Mrt0Vsrc0Vsrc1ComprVmDone"; break;
|
||||
case ShaderInstructionFormat::Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone: return U"Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone"; break;
|
||||
case ShaderInstructionFormat::Param0Vsrc0Vsrc1Vsrc2Vsrc3: return U"Param0Vsrc0Vsrc1Vsrc2Vsrc3"; break;
|
||||
|
@ -168,18 +173,22 @@ static String dbg_fmt_to_str(const ShaderInstruction& inst)
|
|||
case ShaderInstructionFormat::Sdst4SbaseSoffset: return U"Sdst4SbaseSoffset"; break;
|
||||
case ShaderInstructionFormat::Sdst8SbaseSoffset: return U"Sdst8SbaseSoffset"; break;
|
||||
case ShaderInstructionFormat::SdstSvSoffset: return U"SdstSvSoffset"; break;
|
||||
case ShaderInstructionFormat::Sdst2SvSoffset: return U"Sdst2SvSoffset"; break;
|
||||
case ShaderInstructionFormat::Sdst4SvSoffset: return U"Sdst4SvSoffset"; break;
|
||||
case ShaderInstructionFormat::Sdst8SvSoffset: return U"Sdst8SvSoffset"; break;
|
||||
case ShaderInstructionFormat::Sdst16SvSoffset: return U"Sdst16SvSoffset"; break;
|
||||
case ShaderInstructionFormat::SVdstSVsrc0: return U"SVdstSVsrc0"; break;
|
||||
case ShaderInstructionFormat::Sdst2Ssrc02: return U"Sdst2Ssrc02"; break;
|
||||
case ShaderInstructionFormat::Sdst2Ssrc0: return U"Sdst2Ssrc0"; break;
|
||||
case ShaderInstructionFormat::Sdst2Ssrc02Ssrc12: return U"Sdst2Ssrc02Ssrc12"; break;
|
||||
case ShaderInstructionFormat::SmaskVsrc0Vsrc1: return U"SmaskVsrc0Vsrc1"; break;
|
||||
case ShaderInstructionFormat::Ssrc0Ssrc1: return U"Ssrc0Ssrc1"; break;
|
||||
case ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxen: return U"Vdata1VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata2VaddrSvSoffsIdxen: return U"Vdata2VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata3VaddrSvSoffsIdxen: return U"Vdata3VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxen: return U"Vdata4VaddrSvSoffsIdxen"; break;
|
||||
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4: return U"Vdata4VaddrSvSoffsIdxenFloat4"; break;
|
||||
case ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4: return U"Vdata4Vaddr2SvSoffsOffenIdxenFloat4"; break;
|
||||
case ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7: return U"Vdata4Vaddr3StSsDmask7"; break;
|
||||
case ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF: return U"Vdata4Vaddr3StSsDmaskF"; break;
|
||||
case ShaderInstructionFormat::SVdstSVsrc0SVsrc1: return U"SVdstSVsrc0SVsrc1"; break;
|
||||
|
@ -202,6 +211,7 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
|||
{
|
||||
return str;
|
||||
}
|
||||
int src_num = 0;
|
||||
for (;;)
|
||||
{
|
||||
String s;
|
||||
|
@ -238,6 +248,7 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
|||
case ShaderInstructionFormat::S2A4: s = operand_array_to_str(inst.src[2], 4); break;
|
||||
case ShaderInstructionFormat::Attr: s = String::FromPrintf("attr%u.%u", inst.src[1].constant.u, inst.src[2].constant.u); break;
|
||||
case ShaderInstructionFormat::Idxen: s = U"idxen"; break;
|
||||
case ShaderInstructionFormat::Offen: s = U"offen"; break;
|
||||
case ShaderInstructionFormat::Float4: s = U"format:float4"; break;
|
||||
case ShaderInstructionFormat::Pos0: s = U"pos0"; break;
|
||||
case ShaderInstructionFormat::Done: s = U"done"; break;
|
||||
|
@ -246,6 +257,7 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
|||
case ShaderInstructionFormat::Param2: s = U"param2"; break;
|
||||
case ShaderInstructionFormat::Param3: s = U"param3"; break;
|
||||
case ShaderInstructionFormat::Mrt0: s = U"mrt_color0"; break;
|
||||
case ShaderInstructionFormat::Off: s = U"off"; break;
|
||||
case ShaderInstructionFormat::Compr: s = U"compr"; break;
|
||||
case ShaderInstructionFormat::Vm: s = U"vm"; break;
|
||||
case ShaderInstructionFormat::L: s = String::FromPrintf("label_%04" PRIx32, inst.pc + 4 + inst.src[0].constant.i); break;
|
||||
|
@ -254,9 +266,30 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
|||
case ShaderInstructionFormat::Gds: s = U"gds"; break;
|
||||
default: EXIT("unknown code: %u\n", static_cast<uint32_t>(fu));
|
||||
}
|
||||
switch (fu)
|
||||
{
|
||||
case ShaderInstructionFormat::L:
|
||||
case ShaderInstructionFormat::S0:
|
||||
case ShaderInstructionFormat::S0A2:
|
||||
case ShaderInstructionFormat::S0A3:
|
||||
case ShaderInstructionFormat::S0A4: src_num = std::max(src_num, 1); break;
|
||||
case ShaderInstructionFormat::S1:
|
||||
case ShaderInstructionFormat::S1A2:
|
||||
case ShaderInstructionFormat::S1A3:
|
||||
case ShaderInstructionFormat::S1A4:
|
||||
case ShaderInstructionFormat::S1A8: src_num = std::max(src_num, 2); break;
|
||||
case ShaderInstructionFormat::S2:
|
||||
case ShaderInstructionFormat::S2A2:
|
||||
case ShaderInstructionFormat::S2A3:
|
||||
case ShaderInstructionFormat::S2A4:
|
||||
case ShaderInstructionFormat::Attr: src_num = std::max(src_num, 3); break;
|
||||
case ShaderInstructionFormat::S3: src_num = std::max(src_num, 4); break;
|
||||
default: break;
|
||||
}
|
||||
str = s + (str.IsEmpty() ? U"" : U", " + str);
|
||||
f >>= 8u;
|
||||
}
|
||||
EXIT_IF(src_num != inst.src_num);
|
||||
if (inst.dst.multiplier == 2.0f)
|
||||
{
|
||||
str += " mul:2";
|
||||
|
@ -294,7 +327,7 @@ String ShaderCode::DbgDump() const
|
|||
String ret;
|
||||
for (const auto& inst: m_instructions)
|
||||
{
|
||||
if (m_labels.Contains(inst.pc))
|
||||
if (m_labels.Contains(inst.pc, [](auto label, auto pc) { return label.dst == pc; }))
|
||||
{
|
||||
ret += String::FromPrintf("label_%04" PRIx32 ":\n", inst.pc);
|
||||
}
|
||||
|
@ -363,6 +396,108 @@ static ShaderOperand operand_parse(uint32_t code)
|
|||
return ret;
|
||||
}
|
||||
|
||||
KYTY_SHADER_PARSER(shader_parse_sopc)
|
||||
{
|
||||
EXIT_IF(dst == nullptr);
|
||||
EXIT_IF(src == nullptr);
|
||||
EXIT_IF(buffer == nullptr || buffer < src);
|
||||
|
||||
uint32_t ssrc1 = (buffer[0] >> 8u) & 0xffu;
|
||||
uint32_t ssrc0 = (buffer[0] >> 0u) & 0xffu;
|
||||
uint32_t opcode = (buffer[0] >> 16u) & 0x7fu;
|
||||
|
||||
ShaderInstruction inst;
|
||||
inst.pc = pc;
|
||||
inst.src[0] = operand_parse(ssrc0);
|
||||
inst.src[1] = operand_parse(ssrc1);
|
||||
inst.src_num = 2;
|
||||
|
||||
uint32_t size = 1;
|
||||
|
||||
if (inst.src[0].type == ShaderOperandType::LiteralConstant)
|
||||
{
|
||||
inst.src[0].constant.u = buffer[size];
|
||||
size++;
|
||||
}
|
||||
|
||||
if (inst.src[1].type == ShaderOperandType::LiteralConstant)
|
||||
{
|
||||
inst.src[1].constant.u = buffer[size];
|
||||
size++;
|
||||
}
|
||||
|
||||
inst.format = ShaderInstructionFormat::Ssrc0Ssrc1;
|
||||
|
||||
switch (opcode) // NOLINT
|
||||
{
|
||||
case 0x06: inst.type = ShaderInstructionType::SCmpEqU32; break;
|
||||
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown sopc opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
||||
dst->GetInstructions().Add(inst);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
KYTY_SHADER_PARSER(shader_parse_sopk)
|
||||
{
|
||||
KYTY_NOT_IMPLEMENTED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_SHADER_PARSER(shader_parse_sopp)
|
||||
{
|
||||
EXIT_IF(dst == nullptr);
|
||||
EXIT_IF(src == nullptr);
|
||||
EXIT_IF(buffer == nullptr || buffer < src);
|
||||
|
||||
uint32_t opcode = (buffer[0] >> 16u) & 0x7fu;
|
||||
uint32_t simm = (buffer[0] >> 0u) & 0xffffu;
|
||||
|
||||
ShaderInstruction inst;
|
||||
inst.pc = pc;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x01:
|
||||
inst.type = ShaderInstructionType::SEndpgm;
|
||||
inst.format = ShaderInstructionFormat::Empty;
|
||||
break;
|
||||
case 0x04:
|
||||
inst.type = ShaderInstructionType::SCbranchScc0;
|
||||
inst.format = ShaderInstructionFormat::Label;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.i = static_cast<int16_t>(simm) * 4;
|
||||
inst.src_num = 1;
|
||||
break;
|
||||
case 0x08:
|
||||
inst.type = ShaderInstructionType::SCbranchExecz;
|
||||
inst.format = ShaderInstructionFormat::Label;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.i = static_cast<int16_t>(simm) * 4;
|
||||
inst.src_num = 1;
|
||||
break;
|
||||
case 0x0c:
|
||||
inst.type = ShaderInstructionType::SWaitcnt;
|
||||
inst.format = ShaderInstructionFormat::Imm;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.u = simm;
|
||||
inst.src_num = 1;
|
||||
break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown sopp opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
||||
dst->GetInstructions().Add(inst);
|
||||
|
||||
if (inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchExecz)
|
||||
{
|
||||
dst->GetLabels().Add({inst.pc + 4 + inst.src[0].constant.i, inst.pc});
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_SHADER_PARSER(shader_parse_sop1)
|
||||
{
|
||||
EXIT_IF(dst == nullptr);
|
||||
|
@ -394,10 +529,19 @@ KYTY_SHADER_PARSER(shader_parse_sop1)
|
|||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
break;
|
||||
case 0x04:
|
||||
inst.type = ShaderInstructionType::SMovB64;
|
||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02;
|
||||
inst.dst.size = 2;
|
||||
inst.src[0].size = 2;
|
||||
inst.type = ShaderInstructionType::SMovB64;
|
||||
inst.dst.size = 2;
|
||||
switch (inst.src[0].type)
|
||||
{
|
||||
case ShaderOperandType::VccLo:
|
||||
case ShaderOperandType::ExecLo:
|
||||
case ShaderOperandType::Sgpr:
|
||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02;
|
||||
inst.src[0].size = 2;
|
||||
break;
|
||||
case ShaderOperandType::IntegerInlineConstant: inst.format = ShaderInstructionFormat::Sdst2Ssrc0; break;
|
||||
default: EXIT("unknown src0 type");
|
||||
}
|
||||
break;
|
||||
case 0x0a:
|
||||
inst.type = ShaderInstructionType::SWqmB64;
|
||||
|
@ -430,51 +574,6 @@ KYTY_SHADER_PARSER(shader_parse_sop1)
|
|||
return size;
|
||||
}
|
||||
|
||||
KYTY_SHADER_PARSER(shader_parse_sopp)
|
||||
{
|
||||
EXIT_IF(dst == nullptr);
|
||||
EXIT_IF(src == nullptr);
|
||||
EXIT_IF(buffer == nullptr || buffer < src);
|
||||
|
||||
uint32_t opcode = (buffer[0] >> 16u) & 0x7fu;
|
||||
uint32_t simm = (buffer[0] >> 0u) & 0xffffu;
|
||||
|
||||
ShaderInstruction inst;
|
||||
inst.pc = pc;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x01:
|
||||
inst.type = ShaderInstructionType::SEndpgm;
|
||||
inst.format = ShaderInstructionFormat::Empty;
|
||||
break;
|
||||
case 0x08:
|
||||
inst.type = ShaderInstructionType::SCbranchExecz;
|
||||
inst.format = ShaderInstructionFormat::Label;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.i = static_cast<int16_t>(simm) * 4;
|
||||
inst.src_num = 1;
|
||||
break;
|
||||
case 0x0c:
|
||||
inst.type = ShaderInstructionType::SWaitcnt;
|
||||
inst.format = ShaderInstructionFormat::Imm;
|
||||
inst.src[0].type = ShaderOperandType::LiteralConstant;
|
||||
inst.src[0].constant.u = simm;
|
||||
inst.src_num = 1;
|
||||
break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown sopp opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
||||
dst->GetInstructions().Add(inst);
|
||||
|
||||
if (inst.type == ShaderInstructionType::SCbranchExecz)
|
||||
{
|
||||
dst->GetLabels().Add(inst.pc + 4 + inst.src[0].constant.i);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_SHADER_PARSER(shader_parse_sop2)
|
||||
{
|
||||
EXIT_IF(dst == nullptr);
|
||||
|
@ -486,10 +585,16 @@ KYTY_SHADER_PARSER(shader_parse_sop2)
|
|||
switch (opcode)
|
||||
{
|
||||
case 0x7d: return shader_parse_sop1(pc, src, buffer, dst); break;
|
||||
case 0x7e: return shader_parse_sopc(pc, src, buffer, dst); break;
|
||||
case 0x7f: return shader_parse_sopp(pc, src, buffer, dst); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (opcode >= 0x60)
|
||||
{
|
||||
return shader_parse_sopk(pc, src, buffer, dst);
|
||||
}
|
||||
|
||||
uint32_t ssrc1 = (buffer[0] >> 8u) & 0xffu;
|
||||
uint32_t ssrc0 = (buffer[0] >> 0u) & 0xffu;
|
||||
uint32_t sdst = (buffer[0] >> 16u) & 0x7fu;
|
||||
|
@ -519,6 +624,16 @@ KYTY_SHADER_PARSER(shader_parse_sop2)
|
|||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x02: inst.type = ShaderInstructionType::SAddI32; break;
|
||||
case 0x0a: inst.type = ShaderInstructionType::SCselectB32; break;
|
||||
case 0x0e: inst.type = ShaderInstructionType::SAndB32; break;
|
||||
case 0x11:
|
||||
inst.type = ShaderInstructionType::SOrB64;
|
||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02Ssrc12;
|
||||
inst.dst.size = 2;
|
||||
inst.src[0].size = 2;
|
||||
inst.src[1].size = 2;
|
||||
break;
|
||||
case 0x15:
|
||||
inst.type = ShaderInstructionType::SAndn2B64;
|
||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02Ssrc12;
|
||||
|
@ -526,7 +641,16 @@ KYTY_SHADER_PARSER(shader_parse_sop2)
|
|||
inst.src[0].size = 2;
|
||||
inst.src[1].size = 2;
|
||||
break;
|
||||
case 0x1b:
|
||||
inst.type = ShaderInstructionType::SNorB64;
|
||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02Ssrc12;
|
||||
inst.dst.size = 2;
|
||||
inst.src[0].size = 2;
|
||||
inst.src[1].size = 2;
|
||||
break;
|
||||
case 0x1e: inst.type = ShaderInstructionType::SLshlB32; break;
|
||||
case 0x20: inst.type = ShaderInstructionType::SLshrB32; break;
|
||||
case 0x26: inst.type = ShaderInstructionType::SMulI32; break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown sop2 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
||||
|
@ -559,38 +683,20 @@ KYTY_SHADER_PARSER(shader_parse_vopc)
|
|||
size++;
|
||||
}
|
||||
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
inst.dst.type = ShaderOperandType::VccLo;
|
||||
inst.dst.size = 2;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x0d:
|
||||
inst.type = ShaderInstructionType::VCmpNeqF32;
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
inst.dst.type = ShaderOperandType::VccLo;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0xc2:
|
||||
inst.type = ShaderInstructionType::VCmpEqU32;
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
inst.dst.type = ShaderOperandType::VccLo;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0xc5:
|
||||
inst.type = ShaderInstructionType::VCmpNeU32;
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
inst.dst.type = ShaderOperandType::VccLo;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0xd2:
|
||||
inst.type = ShaderInstructionType::VCmpxEqU32;
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
inst.dst.type = ShaderOperandType::VccLo;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0xd4:
|
||||
inst.type = ShaderInstructionType::VCmpxGtU32;
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
inst.dst.type = ShaderOperandType::VccLo;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0x02: inst.type = ShaderInstructionType::VCmpEqF32; break;
|
||||
case 0x0d: inst.type = ShaderInstructionType::VCmpNeqF32; break;
|
||||
case 0x84: inst.type = ShaderInstructionType::VCmpGtI32; break;
|
||||
case 0xc2: inst.type = ShaderInstructionType::VCmpEqU32; break;
|
||||
case 0xc5: inst.type = ShaderInstructionType::VCmpNeU32; break;
|
||||
case 0xd2: inst.type = ShaderInstructionType::VCmpxEqU32; break;
|
||||
case 0xd4: inst.type = ShaderInstructionType::VCmpxGtU32; break;
|
||||
case 0xd5: inst.type = ShaderInstructionType::VCmpxNeU32; break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vopc opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
||||
|
@ -623,32 +729,21 @@ KYTY_SHADER_PARSER(shader_parse_vop1)
|
|||
size++;
|
||||
}
|
||||
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x01:
|
||||
inst.type = ShaderInstructionType::VMovB32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
break;
|
||||
case 0x06:
|
||||
inst.type = ShaderInstructionType::VCvtF32U32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
break;
|
||||
case 0x07:
|
||||
inst.type = ShaderInstructionType::VCvtU32F32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
break;
|
||||
case 0x2a:
|
||||
inst.type = ShaderInstructionType::VRcpF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
break;
|
||||
case 0x2e:
|
||||
inst.type = ShaderInstructionType::VRsqF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
break;
|
||||
case 0x33:
|
||||
inst.type = ShaderInstructionType::VSqrtF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||
break;
|
||||
case 0x01: inst.type = ShaderInstructionType::VMovB32; break;
|
||||
case 0x06: inst.type = ShaderInstructionType::VCvtF32U32; break;
|
||||
case 0x07: inst.type = ShaderInstructionType::VCvtU32F32; break;
|
||||
case 0x11: inst.type = ShaderInstructionType::VCvtF32Ubyte0; break;
|
||||
case 0x12: inst.type = ShaderInstructionType::VCvtF32Ubyte1; break;
|
||||
case 0x13: inst.type = ShaderInstructionType::VCvtF32Ubyte2; break;
|
||||
case 0x14: inst.type = ShaderInstructionType::VCvtF32Ubyte3; break;
|
||||
case 0x2a: inst.type = ShaderInstructionType::VRcpF32; break;
|
||||
case 0x2e: inst.type = ShaderInstructionType::VRsqF32; break;
|
||||
case 0x33: inst.type = ShaderInstructionType::VSqrtF32; break;
|
||||
case 0x37: inst.type = ShaderInstructionType::VNotB32; break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop1 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
||||
|
@ -683,6 +778,8 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
|||
size++;
|
||||
}
|
||||
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x00:
|
||||
|
@ -692,34 +789,18 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
|||
inst.src[2].size = 2;
|
||||
inst.src_num = 3;
|
||||
break;
|
||||
case 0x04:
|
||||
inst.type = ShaderInstructionType::VSubF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x05:
|
||||
inst.type = ShaderInstructionType::VSubrevF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x08:
|
||||
inst.type = ShaderInstructionType::VMulF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x0f:
|
||||
inst.type = ShaderInstructionType::VMinF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x10:
|
||||
inst.type = ShaderInstructionType::VMaxF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x1b:
|
||||
inst.type = ShaderInstructionType::VAndB32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x1f:
|
||||
inst.type = ShaderInstructionType::VMacF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x04: inst.type = ShaderInstructionType::VSubF32; break;
|
||||
case 0x05: inst.type = ShaderInstructionType::VSubrevF32; break;
|
||||
case 0x08: inst.type = ShaderInstructionType::VMulF32; break;
|
||||
case 0x0b: inst.type = ShaderInstructionType::VMulU32U24; break;
|
||||
case 0x0f: inst.type = ShaderInstructionType::VMinF32; break;
|
||||
case 0x10: inst.type = ShaderInstructionType::VMaxF32; break;
|
||||
case 0x15: inst.type = ShaderInstructionType::VLshrB32; break;
|
||||
case 0x16: inst.type = ShaderInstructionType::VLshrrevB32; break;
|
||||
case 0x18: inst.type = ShaderInstructionType::VAshrrevI32; break;
|
||||
case 0x1a: inst.type = ShaderInstructionType::VLshlrevB32; break;
|
||||
case 0x1b: inst.type = ShaderInstructionType::VAndB32; break;
|
||||
case 0x1f: inst.type = ShaderInstructionType::VMacF32; break;
|
||||
case 0x21:
|
||||
inst.type = ShaderInstructionType::VMadakF32;
|
||||
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
||||
|
@ -729,14 +810,8 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
|||
inst.src[2].size = 0;
|
||||
size++;
|
||||
break;
|
||||
case 0x23:
|
||||
inst.type = ShaderInstructionType::VMbcntLoU32B32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x24:
|
||||
inst.type = ShaderInstructionType::VMbcntHiU32B32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x23: inst.type = ShaderInstructionType::VMbcntLoU32B32; break;
|
||||
case 0x24: inst.type = ShaderInstructionType::VMbcntHiU32B32; break;
|
||||
case 0x25:
|
||||
inst.type = ShaderInstructionType::VAddI32;
|
||||
inst.format = ShaderInstructionFormat::VdstSdst2Vsrc0Vsrc1;
|
||||
|
@ -755,10 +830,7 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
|||
inst.dst2.type = ShaderOperandType::VccLo;
|
||||
inst.dst2.size = 2;
|
||||
break;
|
||||
case 0x2f:
|
||||
inst.type = ShaderInstructionType::VCvtPkrtzF16F32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
break;
|
||||
case 0x2f: inst.type = ShaderInstructionType::VCvtPkrtzF16F32; break;
|
||||
case 0x3e: return shader_parse_vopc(pc, src, buffer, dst); break;
|
||||
case 0x3f: return shader_parse_vop1(pc, src, buffer, dst); break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop2 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
|
@ -840,6 +912,8 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||
size++;
|
||||
}
|
||||
|
||||
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x02:
|
||||
|
@ -856,6 +930,13 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||
inst.dst = operand_parse(vdst);
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0x84:
|
||||
inst.type = ShaderInstructionType::VCmpGtI32;
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
inst.src_num = 2;
|
||||
inst.dst = operand_parse(vdst);
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0xc2:
|
||||
inst.type = ShaderInstructionType::VCmpEqU32;
|
||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||
|
@ -883,12 +964,14 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||
inst.src[2].size = 2;
|
||||
break;
|
||||
case 0x104:
|
||||
inst.type = ShaderInstructionType::VSubF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.type = ShaderInstructionType::VSubF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.src_num = 2;
|
||||
break;
|
||||
case 0x108:
|
||||
inst.type = ShaderInstructionType::VMulF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.type = ShaderInstructionType::VMulF32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.src_num = 2;
|
||||
break;
|
||||
case 0x11f:
|
||||
inst.type = ShaderInstructionType::VMacF32;
|
||||
|
@ -901,16 +984,18 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||
inst.src_num = 2;
|
||||
break;
|
||||
case 0x12f:
|
||||
inst.type = ShaderInstructionType::VCvtPkrtzF16F32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.type = ShaderInstructionType::VCvtPkrtzF16F32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.src_num = 2;
|
||||
break;
|
||||
case 0x141:
|
||||
inst.type = ShaderInstructionType::VMadF32;
|
||||
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
||||
break;
|
||||
case 0x15d:
|
||||
inst.type = ShaderInstructionType::VSadU32;
|
||||
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
||||
case 0x141: inst.type = ShaderInstructionType::VMadF32; break;
|
||||
case 0x143: inst.type = ShaderInstructionType::VMadU32U24; break;
|
||||
case 0x148: inst.type = ShaderInstructionType::VBfeU32; break;
|
||||
case 0x15d: inst.type = ShaderInstructionType::VSadU32; break;
|
||||
case 0x16b:
|
||||
inst.type = ShaderInstructionType::VMulLoI32;
|
||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||
inst.src_num = 2;
|
||||
break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop3 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
@ -937,8 +1022,6 @@ KYTY_SHADER_PARSER(shader_parse_exp)
|
|||
uint32_t vsrc2 = (buffer[1] >> 16u) & 0xffu;
|
||||
uint32_t vsrc3 = (buffer[1] >> 24u) & 0xffu;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(en != 0xf);
|
||||
|
||||
ShaderInstruction inst;
|
||||
inst.pc = pc;
|
||||
inst.src[0] = operand_parse(vsrc0 + 256);
|
||||
|
@ -952,28 +1035,40 @@ KYTY_SHADER_PARSER(shader_parse_exp)
|
|||
switch (target)
|
||||
{
|
||||
case 0x00:
|
||||
if (done != 0 && compr != 0 && vm != 0)
|
||||
if (done != 0 && compr != 0 && vm != 0 && en == 0x0)
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Mrt0OffOffComprVmDone;
|
||||
inst.src_num = 0;
|
||||
} else if (done != 0 && compr != 0 && vm != 0 && en == 0xf)
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Mrt0Vsrc0Vsrc1ComprVmDone;
|
||||
inst.src_num = 2;
|
||||
} else if (done != 0 && compr == 0 && vm != 0)
|
||||
} else if (done != 0 && compr == 0 && vm != 0 && en == 0xf)
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone;
|
||||
};
|
||||
break;
|
||||
case 0x0c:
|
||||
if (done != 0)
|
||||
if (done != 0 && en == 0xf)
|
||||
{
|
||||
inst.format = ShaderInstructionFormat::Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done;
|
||||
};
|
||||
break;
|
||||
case 0x20: inst.format = ShaderInstructionFormat::Param0Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x21: inst.format = ShaderInstructionFormat::Param1Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x22: inst.format = ShaderInstructionFormat::Param2Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x23: inst.format = ShaderInstructionFormat::Param3Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (inst.format == ShaderInstructionFormat::Unknown && done == 0 && compr == 0 && vm == 0 && en == 0xf)
|
||||
{
|
||||
switch (target)
|
||||
{
|
||||
case 0x20: inst.format = ShaderInstructionFormat::Param0Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x21: inst.format = ShaderInstructionFormat::Param1Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x22: inst.format = ShaderInstructionFormat::Param2Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
case 0x23: inst.format = ShaderInstructionFormat::Param3Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.format == ShaderInstructionFormat::Unknown)
|
||||
{
|
||||
printf("%s", dst->DbgDump().C_Str());
|
||||
|
@ -1039,6 +1134,12 @@ KYTY_SHADER_PARSER(shader_parse_smrd)
|
|||
inst.format = ShaderInstructionFormat::SdstSvSoffset;
|
||||
inst.src[0].size = 4;
|
||||
break;
|
||||
case 0x09:
|
||||
inst.type = ShaderInstructionType::SBufferLoadDwordx2;
|
||||
inst.format = ShaderInstructionFormat::Sdst2SvSoffset;
|
||||
inst.src[0].size = 4;
|
||||
inst.dst.size = 2;
|
||||
break;
|
||||
case 0x0a:
|
||||
inst.type = ShaderInstructionType::SBufferLoadDwordx4;
|
||||
inst.format = ShaderInstructionFormat::Sdst4SvSoffset;
|
||||
|
@ -1293,7 +1394,7 @@ KYTY_SHADER_PARSER(shader_parse_mtbuf)
|
|||
uint32_t vaddr = (buffer[1] >> 0u) & 0xffu;
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(idxen == 0);
|
||||
EXIT_NOT_IMPLEMENTED(offen == 1);
|
||||
// EXIT_NOT_IMPLEMENTED(offen == 1);
|
||||
EXIT_NOT_IMPLEMENTED(offset != 0);
|
||||
EXIT_NOT_IMPLEMENTED(glc == 1);
|
||||
EXIT_NOT_IMPLEMENTED(slc == 1);
|
||||
|
@ -1317,13 +1418,16 @@ KYTY_SHADER_PARSER(shader_parse_mtbuf)
|
|||
size++;
|
||||
}
|
||||
|
||||
inst.src[1].size = 4;
|
||||
|
||||
switch (opcode) // NOLINT
|
||||
{
|
||||
case 0x03:
|
||||
inst.type = ShaderInstructionType::TBufferLoadFormatXyzw;
|
||||
inst.format = ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4;
|
||||
inst.src[1].size = 4;
|
||||
inst.dst.size = 4;
|
||||
inst.type = ShaderInstructionType::TBufferLoadFormatXyzw;
|
||||
inst.format = (offen == 1 ? ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4
|
||||
: ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4);
|
||||
inst.src[0].size += static_cast<int>(offen);
|
||||
inst.dst.size = 4;
|
||||
break;
|
||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown mtbuf opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
||||
}
|
||||
|
@ -1426,7 +1530,8 @@ KYTY_SHADER_PARSER(shader_parse)
|
|||
EXIT("unknown code 0x%08" PRIx32 " at addr 0x%08" PRIx32 "\n", ptr[0], pc);
|
||||
}
|
||||
|
||||
if ((instruction == 0xBF810000 && (type == ShaderType::Vertex || type == ShaderType::Pixel || type == ShaderType::Compute)) ||
|
||||
if ((instruction == 0xBF810000 && (type == ShaderType::Vertex || type == ShaderType::Pixel || type == ShaderType::Compute) &&
|
||||
!dst->GetLabels().Contains(4 * static_cast<uint32_t>(ptr - src), [](auto label, auto pc) { return label.dst == pc; })) ||
|
||||
(instruction == 0xBE802000 && type == ShaderType::Fetch))
|
||||
{
|
||||
break;
|
||||
|
@ -1512,23 +1617,23 @@ static void bi_print(const char* func, const ShaderBinaryInfo& bi)
|
|||
{
|
||||
printf("%s\n", func);
|
||||
|
||||
printf("\t m_signature = %.7s\n", bi.signature);
|
||||
printf("\t m_version = 0x%02" PRIx8 "\n", bi.version);
|
||||
printf("\t m_pssl_or_cg = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.pssl_or_cg));
|
||||
printf("\t m_cached = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.cached));
|
||||
printf("\t m_type = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.type));
|
||||
printf("\t m_source_type = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.source_type));
|
||||
printf("\t m_length = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.length));
|
||||
printf("\t m_chunkUsageBaseOffsetInDW = 0x%02" PRIx8 "\n", bi.chunk_usage_base_offset_dw);
|
||||
printf("\t m_numInputUsageSlots = 0x%02" PRIx8 "\n", bi.num_input_usage_slots);
|
||||
printf("\t m_isSrt = 0x%02" PRIx8 "\n", bi.is_srt);
|
||||
printf("\t m_isSrtUsedInfoValid = 0x%02" PRIx8 "\n", bi.is_srt_used_info_valid);
|
||||
printf("\t m_isExtendedUsageInfo = 0x%02" PRIx8 "\n", bi.is_extended_usage_info);
|
||||
printf("\t m_reserved2 = 0x%02" PRIx8 "\n", bi.reserved2);
|
||||
printf("\t m_reserved3 = 0x%02" PRIx8 "\n", bi.reserved3);
|
||||
printf("\t m_shaderHash0 = 0x%08" PRIx32 "\n", bi.hash0);
|
||||
printf("\t m_shaderHash1 = 0x%08" PRIx32 "\n", bi.hash1);
|
||||
printf("\t m_crc32 = 0x%08" PRIx32 "\n", bi.crc32);
|
||||
printf("\t signature = %.7s\n", bi.signature);
|
||||
printf("\t version = 0x%02" PRIx8 "\n", bi.version);
|
||||
printf("\t pssl_or_cg = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.pssl_or_cg));
|
||||
printf("\t cached = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.cached));
|
||||
printf("\t type = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.type));
|
||||
printf("\t source_type = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.source_type));
|
||||
printf("\t length = 0x%08" PRIx32 "\n", static_cast<uint32_t>(bi.length));
|
||||
printf("\t chunk_usage_base_offset_dw = 0x%02" PRIx8 "\n", bi.chunk_usage_base_offset_dw);
|
||||
printf("\t num_input_usage_slots = 0x%02" PRIx8 "\n", bi.num_input_usage_slots);
|
||||
printf("\t is_srt = 0x%02" PRIx8 "\n", bi.is_srt);
|
||||
printf("\t is_srt_used_info_valid = 0x%02" PRIx8 "\n", bi.is_srt_used_info_valid);
|
||||
printf("\t is_extended_usage_info = 0x%02" PRIx8 "\n", bi.is_extended_usage_info);
|
||||
printf("\t reserved2 = 0x%02" PRIx8 "\n", bi.reserved2);
|
||||
printf("\t reserved3 = 0x%02" PRIx8 "\n", bi.reserved3);
|
||||
printf("\t hash0 = 0x%08" PRIx32 "\n", bi.hash0);
|
||||
printf("\t hash1 = 0x%08" PRIx32 "\n", bi.hash1);
|
||||
printf("\t crc32 = 0x%08" PRIx32 "\n", bi.crc32);
|
||||
}
|
||||
|
||||
static void vs_check(const VsStageRegisters& vs)
|
||||
|
@ -2089,7 +2194,7 @@ void ShaderGetInputInfoPS(const PixelShaderInfo* regs, const ShaderVertexInputIn
|
|||
EXIT_IF(ps_info == nullptr);
|
||||
EXIT_IF(regs == nullptr);
|
||||
|
||||
ps_info->input_num = regs->ps_input_num;
|
||||
ps_info->input_num = regs->ps_regs.ps_in_control;
|
||||
ps_info->ps_pos_xy = (regs->ps_regs.ps_input_ena == 0x00000302 && regs->ps_regs.ps_input_addr == 0x00000302);
|
||||
ps_info->ps_pixel_kill_enable = regs->ps_regs.shader_kill_enable;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue