mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 05:06:40 +00:00
Improve shader recompiler
This commit is contained in:
@@ -75,7 +75,7 @@ if (CLANG AND (KYTY_LINKER STREQUAL LLD))
|
|||||||
set(KYTY_LD_OPTIONS "-fuse-ld=lld")
|
set(KYTY_LD_OPTIONS "-fuse-ld=lld")
|
||||||
endif()
|
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)
|
include(src_script.cmake)
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "Emulator/Common.h"
|
#include "Emulator/Common.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef KYTY_EMU_ENABLED
|
#ifdef KYTY_EMU_ENABLED
|
||||||
|
|
||||||
namespace Kyty::Libs::Graphics {
|
namespace Kyty::Libs::Graphics {
|
||||||
@@ -27,9 +29,6 @@ enum class ShaderType
|
|||||||
enum class ShaderInstructionType
|
enum class ShaderInstructionType
|
||||||
{
|
{
|
||||||
Unknown,
|
Unknown,
|
||||||
DsAppend,
|
|
||||||
DsConsume,
|
|
||||||
Exp,
|
|
||||||
BufferLoadDword,
|
BufferLoadDword,
|
||||||
BufferLoadFormatX,
|
BufferLoadFormatX,
|
||||||
BufferLoadFormatXy,
|
BufferLoadFormatXy,
|
||||||
@@ -37,50 +36,78 @@ enum class ShaderInstructionType
|
|||||||
BufferLoadFormatXyzw,
|
BufferLoadFormatXyzw,
|
||||||
BufferStoreDword,
|
BufferStoreDword,
|
||||||
BufferStoreFormatX,
|
BufferStoreFormatX,
|
||||||
|
DsAppend,
|
||||||
|
DsConsume,
|
||||||
|
Exp,
|
||||||
ImageSample,
|
ImageSample,
|
||||||
TBufferLoadFormatXyzw,
|
SAddI32,
|
||||||
|
SAndB32,
|
||||||
SAndn2B64,
|
SAndn2B64,
|
||||||
SAndSaveexecB64,
|
SAndSaveexecB64,
|
||||||
SEndpgm,
|
|
||||||
SCbranchExecz,
|
|
||||||
SLshlB32,
|
|
||||||
SLoadDwordx4,
|
|
||||||
SLoadDwordx8,
|
|
||||||
SBufferLoadDword,
|
SBufferLoadDword,
|
||||||
|
SBufferLoadDwordx16,
|
||||||
|
SBufferLoadDwordx2,
|
||||||
SBufferLoadDwordx4,
|
SBufferLoadDwordx4,
|
||||||
SBufferLoadDwordx8,
|
SBufferLoadDwordx8,
|
||||||
SBufferLoadDwordx16,
|
SCbranchExecz,
|
||||||
|
SCbranchScc0,
|
||||||
|
SCmpEqU32,
|
||||||
|
SEndpgm,
|
||||||
|
SLoadDwordx4,
|
||||||
|
SLoadDwordx8,
|
||||||
|
SLshlB32,
|
||||||
|
SLshrB32,
|
||||||
SMovB32,
|
SMovB32,
|
||||||
SMovB64,
|
SMovB64,
|
||||||
|
SMulI32,
|
||||||
|
SNorB64,
|
||||||
|
SOrB64,
|
||||||
|
SCselectB32,
|
||||||
SSetpcB64,
|
SSetpcB64,
|
||||||
SSwappcB64,
|
SSwappcB64,
|
||||||
SWaitcnt,
|
SWaitcnt,
|
||||||
SWqmB64,
|
SWqmB64,
|
||||||
|
TBufferLoadFormatXyzw,
|
||||||
VAddI32,
|
VAddI32,
|
||||||
VAndB32,
|
VAndB32,
|
||||||
|
VAshrrevI32,
|
||||||
|
VBfeU32,
|
||||||
VCmpEqF32,
|
VCmpEqF32,
|
||||||
VCmpEqU32,
|
VCmpEqU32,
|
||||||
|
VCmpGtI32,
|
||||||
VCmpLeF32,
|
VCmpLeF32,
|
||||||
VCmpLeU32,
|
VCmpLeU32,
|
||||||
VCmpNeU32,
|
|
||||||
VCmpNeqF32,
|
VCmpNeqF32,
|
||||||
|
VCmpNeU32,
|
||||||
VCmpxEqU32,
|
VCmpxEqU32,
|
||||||
VCmpxGtU32,
|
VCmpxGtU32,
|
||||||
|
VCmpxNeU32,
|
||||||
VCndmaskB32,
|
VCndmaskB32,
|
||||||
VCvtF32U32,
|
VCvtF32U32,
|
||||||
|
VCvtF32Ubyte0,
|
||||||
|
VCvtF32Ubyte1,
|
||||||
|
VCvtF32Ubyte2,
|
||||||
|
VCvtF32Ubyte3,
|
||||||
VCvtPkrtzF16F32,
|
VCvtPkrtzF16F32,
|
||||||
VCvtU32F32,
|
VCvtU32F32,
|
||||||
|
VInterpP1F32,
|
||||||
|
VInterpP2F32,
|
||||||
|
VLshlrevB32,
|
||||||
|
VLshrB32,
|
||||||
|
VLshrrevB32,
|
||||||
VMacF32,
|
VMacF32,
|
||||||
VMadakF32,
|
VMadakF32,
|
||||||
VMadF32,
|
VMadF32,
|
||||||
|
VMadU32U24,
|
||||||
VMaxF32,
|
VMaxF32,
|
||||||
VMbcntHiU32B32,
|
VMbcntHiU32B32,
|
||||||
VMbcntLoU32B32,
|
VMbcntLoU32B32,
|
||||||
VMinF32,
|
VMinF32,
|
||||||
VMovB32,
|
VMovB32,
|
||||||
VMulF32,
|
VMulF32,
|
||||||
VInterpP1F32,
|
VMulLoI32,
|
||||||
VInterpP2F32,
|
VMulU32U24,
|
||||||
|
VNotB32,
|
||||||
VRcpF32,
|
VRcpF32,
|
||||||
VRsqF32,
|
VRsqF32,
|
||||||
VSadU32,
|
VSadU32,
|
||||||
@@ -123,6 +150,7 @@ enum FormatByte : uint64_t
|
|||||||
S2A4, // operand_array_to_str(inst.src[2], 4)
|
S2A4, // operand_array_to_str(inst.src[2], 4)
|
||||||
Attr, // attr%u.%u <- inst.src[1].constant.u, inst.src[2].constant.u
|
Attr, // attr%u.%u <- inst.src[1].constant.u, inst.src[2].constant.u
|
||||||
Idxen, // idxen
|
Idxen, // idxen
|
||||||
|
Offen, // offen
|
||||||
Float4, // format:float4
|
Float4, // format:float4
|
||||||
Pos0, // pos0
|
Pos0, // pos0
|
||||||
Done, // done
|
Done, // done
|
||||||
@@ -131,6 +159,7 @@ enum FormatByte : uint64_t
|
|||||||
Param2, // param2
|
Param2, // param2
|
||||||
Param3, // param3
|
Param3, // param3
|
||||||
Mrt0, // mrt_color0
|
Mrt0, // mrt_color0
|
||||||
|
Off, // off
|
||||||
Compr, // compr
|
Compr, // compr
|
||||||
Vm, // vm
|
Vm, // vm
|
||||||
L, // label_%u
|
L, // label_%u
|
||||||
@@ -155,6 +184,7 @@ enum Format : uint64_t
|
|||||||
Empty = FormatDefine({N}),
|
Empty = FormatDefine({N}),
|
||||||
Imm = FormatDefine({S0}),
|
Imm = FormatDefine({S0}),
|
||||||
Label = FormatDefine({L}),
|
Label = FormatDefine({L}),
|
||||||
|
Mrt0OffOffComprVmDone = FormatDefine({Mrt0, Off, Off, Compr, Vm, Done}),
|
||||||
Mrt0Vsrc0Vsrc1ComprVmDone = FormatDefine({Mrt0, S0, S1, Compr, Vm, Done}),
|
Mrt0Vsrc0Vsrc1ComprVmDone = FormatDefine({Mrt0, S0, S1, Compr, Vm, Done}),
|
||||||
Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone = FormatDefine({Mrt0, S0, S1, S2, S3, Vm, Done}),
|
Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone = FormatDefine({Mrt0, S0, S1, S2, S3, Vm, Done}),
|
||||||
Param0Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param0, S0, S1, S2, S3}),
|
Param0Vsrc0Vsrc1Vsrc2Vsrc3 = FormatDefine({Param0, S0, S1, S2, S3}),
|
||||||
@@ -166,26 +196,30 @@ enum Format : uint64_t
|
|||||||
Sdst4SbaseSoffset = FormatDefine({DA4, S0A2, S1}),
|
Sdst4SbaseSoffset = FormatDefine({DA4, S0A2, S1}),
|
||||||
Sdst8SbaseSoffset = FormatDefine({DA8, S0A2, S1}),
|
Sdst8SbaseSoffset = FormatDefine({DA8, S0A2, S1}),
|
||||||
SdstSvSoffset = FormatDefine({D, S0A4, S1}),
|
SdstSvSoffset = FormatDefine({D, S0A4, S1}),
|
||||||
|
Sdst2SvSoffset = FormatDefine({DA2, S0A4, S1}),
|
||||||
Sdst4SvSoffset = FormatDefine({DA4, S0A4, S1}),
|
Sdst4SvSoffset = FormatDefine({DA4, S0A4, S1}),
|
||||||
Sdst8SvSoffset = FormatDefine({DA8, S0A4, S1}),
|
Sdst8SvSoffset = FormatDefine({DA8, S0A4, S1}),
|
||||||
Sdst16SvSoffset = FormatDefine({DA16, S0A4, S1}),
|
Sdst16SvSoffset = FormatDefine({DA16, S0A4, S1}),
|
||||||
SVdstSVsrc0 = FormatDefine({D, S0}),
|
SVdstSVsrc0 = FormatDefine({D, S0}),
|
||||||
SVdstSVsrc0SVsrc1 = FormatDefine({D, S0, S1}),
|
SVdstSVsrc0SVsrc1 = FormatDefine({D, S0, S1}),
|
||||||
Sdst2Ssrc02 = FormatDefine({DA2, S0A2}),
|
Sdst2Ssrc02 = FormatDefine({DA2, S0A2}),
|
||||||
|
Sdst2Ssrc0 = FormatDefine({DA2, S0}),
|
||||||
Sdst2Ssrc02Ssrc12 = FormatDefine({DA2, S0A2, S1A2}),
|
Sdst2Ssrc02Ssrc12 = FormatDefine({DA2, S0A2, S1A2}),
|
||||||
SmaskVsrc0Vsrc1 = FormatDefine({DA2, S0, S1}),
|
SmaskVsrc0Vsrc1 = FormatDefine({DA2, S0, S1}),
|
||||||
|
Ssrc0Ssrc1 = FormatDefine({S0, S1}),
|
||||||
Vdata1VaddrSvSoffsIdxen = FormatDefine({D, S0, S1A4, S2, Idxen}),
|
Vdata1VaddrSvSoffsIdxen = FormatDefine({D, S0, S1A4, S2, Idxen}),
|
||||||
Vdata2VaddrSvSoffsIdxen = FormatDefine({DA2, S0, S1A4, S2, Idxen}),
|
Vdata2VaddrSvSoffsIdxen = FormatDefine({DA2, S0, S1A4, S2, Idxen}),
|
||||||
Vdata3VaddrSvSoffsIdxen = FormatDefine({DA3, S0, S1A4, S2, Idxen}),
|
Vdata3VaddrSvSoffsIdxen = FormatDefine({DA3, S0, S1A4, S2, Idxen}),
|
||||||
Vdata4VaddrSvSoffsIdxen = FormatDefine({DA4, S0, S1A4, S2, Idxen}),
|
Vdata4VaddrSvSoffsIdxen = FormatDefine({DA4, S0, S1A4, S2, Idxen}),
|
||||||
Vdata4VaddrSvSoffsIdxenFloat4 = FormatDefine({DA4, S0, S1A4, S2, Idxen, Float4}),
|
Vdata4VaddrSvSoffsIdxenFloat4 = FormatDefine({DA4, S0, S1A4, S2, Idxen, Float4}),
|
||||||
|
Vdata4Vaddr2SvSoffsOffenIdxenFloat4 = FormatDefine({DA4, S0A2, S1A4, S2, Offen, Idxen, Float4}),
|
||||||
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
Vdata3Vaddr3StSsDmask7 = FormatDefine({DA3, S0A3, S1A8, S2A4, Dmask7}),
|
||||||
Vdata4Vaddr3StSsDmaskF = FormatDefine({DA4, S0A3, S1A8, S2A4, DmaskF}),
|
Vdata4Vaddr3StSsDmaskF = FormatDefine({DA4, S0A3, S1A8, S2A4, DmaskF}),
|
||||||
VdstVsrc0Vsrc1Smask2 = FormatDefine({D, S0, S1, S2A2}),
|
VdstVsrc0Vsrc1Smask2 = FormatDefine({D, S0, S1, S2A2}),
|
||||||
VdstVsrc0Vsrc1Vsrc2 = FormatDefine({D, S0, S1, S2}),
|
VdstVsrc0Vsrc1Vsrc2 = FormatDefine({D, S0, S1, S2}),
|
||||||
VdstVsrcAttrChan = FormatDefine({D, S0, Attr}),
|
VdstVsrcAttrChan = FormatDefine({D, S0, Attr}),
|
||||||
VdstSdst2Vsrc0Vsrc1 = FormatDefine({D, D2A2, S0, S1}),
|
VdstSdst2Vsrc0Vsrc1 = FormatDefine({D, D2A2, S0, S1}),
|
||||||
VdstGds = FormatDefine({D, Gds})
|
VdstGds = FormatDefine({D, Gds}),
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ShaderInstructionFormat
|
} // namespace ShaderInstructionFormat
|
||||||
@@ -201,6 +235,7 @@ enum class ShaderOperandType
|
|||||||
ExecLo,
|
ExecLo,
|
||||||
ExecHi,
|
ExecHi,
|
||||||
ExecZ,
|
ExecZ,
|
||||||
|
Scc,
|
||||||
Vgpr,
|
Vgpr,
|
||||||
Sgpr,
|
Sgpr,
|
||||||
M0
|
M0
|
||||||
@@ -240,6 +275,12 @@ struct ShaderInstruction
|
|||||||
ShaderOperand dst2;
|
ShaderOperand dst2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ShaderLabel
|
||||||
|
{
|
||||||
|
uint32_t dst;
|
||||||
|
uint32_t src;
|
||||||
|
};
|
||||||
|
|
||||||
class ShaderCode
|
class ShaderCode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -249,8 +290,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] const Vector<ShaderInstruction>& GetInstructions() const { return m_instructions; }
|
[[nodiscard]] const Vector<ShaderInstruction>& GetInstructions() const { return m_instructions; }
|
||||||
Vector<ShaderInstruction>& GetInstructions() { return m_instructions; }
|
Vector<ShaderInstruction>& GetInstructions() { return m_instructions; }
|
||||||
[[nodiscard]] const Vector<uint32_t>& GetLabels() const { return m_labels; }
|
[[nodiscard]] const Vector<ShaderLabel>& GetLabels() const { return m_labels; }
|
||||||
Vector<uint32_t>& GetLabels() { return m_labels; }
|
Vector<ShaderLabel>& GetLabels() { return m_labels; }
|
||||||
|
|
||||||
[[nodiscard]] String DbgDump() const;
|
[[nodiscard]] String DbgDump() const;
|
||||||
|
|
||||||
@@ -259,9 +300,16 @@ public:
|
|||||||
[[nodiscard]] ShaderType GetType() const { return m_type; }
|
[[nodiscard]] ShaderType GetType() const { return m_type; }
|
||||||
void SetType(ShaderType type) { this->m_type = 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:
|
private:
|
||||||
Vector<ShaderInstruction> m_instructions;
|
Vector<ShaderInstruction> m_instructions;
|
||||||
Vector<uint32_t> m_labels;
|
Vector<ShaderLabel> m_labels;
|
||||||
ShaderType m_type = ShaderType::Unknown;
|
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,
|
TileGetDepthSize(z.width, z.height, z.z_info.format, z.stencil_info.format, htile, neo, &stencil_size, &htile_size, &depth_size,
|
||||||
&pitch);
|
&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)
|
switch (z.z_info.format * 2 + z.stencil_info.format)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,8 @@
|
|||||||
#ifdef KYTY_EMU_ENABLED
|
#ifdef KYTY_EMU_ENABLED
|
||||||
|
|
||||||
#define KYTY_SHADER_PARSER_ARGS \
|
#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_SHADER_PARSER(f) static uint32_t f(KYTY_SHADER_PARSER_ARGS)
|
||||||
#define KYTY_CP_OP_PARSER_ARGS \
|
#define KYTY_CP_OP_PARSER_ARGS \
|
||||||
[[maybe_unused]] CommandProcessor *cp, [[maybe_unused]] uint32_t cmd_id, [[maybe_unused]] const uint32_t *buffer, \
|
[[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::ExecHi: ret = U"exec_hi"; break;
|
||||||
case ShaderOperandType::ExecLo: ret = U"exec_lo"; break;
|
case ShaderOperandType::ExecLo: ret = U"exec_lo"; break;
|
||||||
case ShaderOperandType::ExecZ: ret = U"execz"; break;
|
case ShaderOperandType::ExecZ: ret = U"execz"; break;
|
||||||
|
case ShaderOperandType::Scc: ret = U"scc"; break;
|
||||||
case ShaderOperandType::M0: ret = U"m0"; break;
|
case ShaderOperandType::M0: ret = U"m0"; break;
|
||||||
case ShaderOperandType::Vgpr: ret = String::FromPrintf("v%d", op.register_id); 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;
|
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;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXIT_IF(ret == U"???");
|
||||||
|
|
||||||
if (op.negate)
|
if (op.negate)
|
||||||
{
|
{
|
||||||
return U"-" + ret;
|
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::Unknown: return U"Unknown"; break;
|
||||||
case ShaderInstructionFormat::Empty: return U"Empty"; break;
|
case ShaderInstructionFormat::Empty: return U"Empty"; break;
|
||||||
case ShaderInstructionFormat::Imm: return U"Imm"; break;
|
case ShaderInstructionFormat::Imm: return U"Imm"; break;
|
||||||
|
case ShaderInstructionFormat::Mrt0OffOffComprVmDone: return U"Mrt0OffOffComprVmDone"; break;
|
||||||
case ShaderInstructionFormat::Mrt0Vsrc0Vsrc1ComprVmDone: return U"Mrt0Vsrc0Vsrc1ComprVmDone"; break;
|
case ShaderInstructionFormat::Mrt0Vsrc0Vsrc1ComprVmDone: return U"Mrt0Vsrc0Vsrc1ComprVmDone"; break;
|
||||||
case ShaderInstructionFormat::Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone: return U"Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone"; break;
|
case ShaderInstructionFormat::Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone: return U"Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone"; break;
|
||||||
case ShaderInstructionFormat::Param0Vsrc0Vsrc1Vsrc2Vsrc3: return U"Param0Vsrc0Vsrc1Vsrc2Vsrc3"; 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::Sdst4SbaseSoffset: return U"Sdst4SbaseSoffset"; break;
|
||||||
case ShaderInstructionFormat::Sdst8SbaseSoffset: return U"Sdst8SbaseSoffset"; break;
|
case ShaderInstructionFormat::Sdst8SbaseSoffset: return U"Sdst8SbaseSoffset"; break;
|
||||||
case ShaderInstructionFormat::SdstSvSoffset: return U"SdstSvSoffset"; break;
|
case ShaderInstructionFormat::SdstSvSoffset: return U"SdstSvSoffset"; break;
|
||||||
|
case ShaderInstructionFormat::Sdst2SvSoffset: return U"Sdst2SvSoffset"; break;
|
||||||
case ShaderInstructionFormat::Sdst4SvSoffset: return U"Sdst4SvSoffset"; break;
|
case ShaderInstructionFormat::Sdst4SvSoffset: return U"Sdst4SvSoffset"; break;
|
||||||
case ShaderInstructionFormat::Sdst8SvSoffset: return U"Sdst8SvSoffset"; break;
|
case ShaderInstructionFormat::Sdst8SvSoffset: return U"Sdst8SvSoffset"; break;
|
||||||
case ShaderInstructionFormat::Sdst16SvSoffset: return U"Sdst16SvSoffset"; break;
|
case ShaderInstructionFormat::Sdst16SvSoffset: return U"Sdst16SvSoffset"; break;
|
||||||
case ShaderInstructionFormat::SVdstSVsrc0: return U"SVdstSVsrc0"; break;
|
case ShaderInstructionFormat::SVdstSVsrc0: return U"SVdstSVsrc0"; break;
|
||||||
case ShaderInstructionFormat::Sdst2Ssrc02: return U"Sdst2Ssrc02"; break;
|
case ShaderInstructionFormat::Sdst2Ssrc02: return U"Sdst2Ssrc02"; break;
|
||||||
|
case ShaderInstructionFormat::Sdst2Ssrc0: return U"Sdst2Ssrc0"; break;
|
||||||
case ShaderInstructionFormat::Sdst2Ssrc02Ssrc12: return U"Sdst2Ssrc02Ssrc12"; break;
|
case ShaderInstructionFormat::Sdst2Ssrc02Ssrc12: return U"Sdst2Ssrc02Ssrc12"; break;
|
||||||
case ShaderInstructionFormat::SmaskVsrc0Vsrc1: return U"SmaskVsrc0Vsrc1"; break;
|
case ShaderInstructionFormat::SmaskVsrc0Vsrc1: return U"SmaskVsrc0Vsrc1"; break;
|
||||||
|
case ShaderInstructionFormat::Ssrc0Ssrc1: return U"Ssrc0Ssrc1"; break;
|
||||||
case ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxen: return U"Vdata1VaddrSvSoffsIdxen"; break;
|
case ShaderInstructionFormat::Vdata1VaddrSvSoffsIdxen: return U"Vdata1VaddrSvSoffsIdxen"; break;
|
||||||
case ShaderInstructionFormat::Vdata2VaddrSvSoffsIdxen: return U"Vdata2VaddrSvSoffsIdxen"; break;
|
case ShaderInstructionFormat::Vdata2VaddrSvSoffsIdxen: return U"Vdata2VaddrSvSoffsIdxen"; break;
|
||||||
case ShaderInstructionFormat::Vdata3VaddrSvSoffsIdxen: return U"Vdata3VaddrSvSoffsIdxen"; break;
|
case ShaderInstructionFormat::Vdata3VaddrSvSoffsIdxen: return U"Vdata3VaddrSvSoffsIdxen"; break;
|
||||||
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxen: return U"Vdata4VaddrSvSoffsIdxen"; break;
|
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxen: return U"Vdata4VaddrSvSoffsIdxen"; break;
|
||||||
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4: return U"Vdata4VaddrSvSoffsIdxenFloat4"; break;
|
case ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4: return U"Vdata4VaddrSvSoffsIdxenFloat4"; break;
|
||||||
|
case ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4: return U"Vdata4Vaddr2SvSoffsOffenIdxenFloat4"; break;
|
||||||
case ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7: return U"Vdata4Vaddr3StSsDmask7"; break;
|
case ShaderInstructionFormat::Vdata3Vaddr3StSsDmask7: return U"Vdata4Vaddr3StSsDmask7"; break;
|
||||||
case ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF: return U"Vdata4Vaddr3StSsDmaskF"; break;
|
case ShaderInstructionFormat::Vdata4Vaddr3StSsDmaskF: return U"Vdata4Vaddr3StSsDmaskF"; break;
|
||||||
case ShaderInstructionFormat::SVdstSVsrc0SVsrc1: return U"SVdstSVsrc0SVsrc1"; break;
|
case ShaderInstructionFormat::SVdstSVsrc0SVsrc1: return U"SVdstSVsrc0SVsrc1"; break;
|
||||||
@@ -202,6 +211,7 @@ static String dbg_fmt_print(const ShaderInstruction& inst)
|
|||||||
{
|
{
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
int src_num = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
String s;
|
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::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::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::Idxen: s = U"idxen"; break;
|
||||||
|
case ShaderInstructionFormat::Offen: s = U"offen"; break;
|
||||||
case ShaderInstructionFormat::Float4: s = U"format:float4"; break;
|
case ShaderInstructionFormat::Float4: s = U"format:float4"; break;
|
||||||
case ShaderInstructionFormat::Pos0: s = U"pos0"; break;
|
case ShaderInstructionFormat::Pos0: s = U"pos0"; break;
|
||||||
case ShaderInstructionFormat::Done: s = U"done"; 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::Param2: s = U"param2"; break;
|
||||||
case ShaderInstructionFormat::Param3: s = U"param3"; break;
|
case ShaderInstructionFormat::Param3: s = U"param3"; break;
|
||||||
case ShaderInstructionFormat::Mrt0: s = U"mrt_color0"; 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::Compr: s = U"compr"; break;
|
||||||
case ShaderInstructionFormat::Vm: s = U"vm"; 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;
|
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;
|
case ShaderInstructionFormat::Gds: s = U"gds"; break;
|
||||||
default: EXIT("unknown code: %u\n", static_cast<uint32_t>(fu));
|
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);
|
str = s + (str.IsEmpty() ? U"" : U", " + str);
|
||||||
f >>= 8u;
|
f >>= 8u;
|
||||||
}
|
}
|
||||||
|
EXIT_IF(src_num != inst.src_num);
|
||||||
if (inst.dst.multiplier == 2.0f)
|
if (inst.dst.multiplier == 2.0f)
|
||||||
{
|
{
|
||||||
str += " mul:2";
|
str += " mul:2";
|
||||||
@@ -294,7 +327,7 @@ String ShaderCode::DbgDump() const
|
|||||||
String ret;
|
String ret;
|
||||||
for (const auto& inst: m_instructions)
|
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);
|
ret += String::FromPrintf("label_%04" PRIx32 ":\n", inst.pc);
|
||||||
}
|
}
|
||||||
@@ -363,6 +396,108 @@ static ShaderOperand operand_parse(uint32_t code)
|
|||||||
return ret;
|
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)
|
KYTY_SHADER_PARSER(shader_parse_sop1)
|
||||||
{
|
{
|
||||||
EXIT_IF(dst == nullptr);
|
EXIT_IF(dst == nullptr);
|
||||||
@@ -395,10 +530,19 @@ KYTY_SHADER_PARSER(shader_parse_sop1)
|
|||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
inst.type = ShaderInstructionType::SMovB64;
|
inst.type = ShaderInstructionType::SMovB64;
|
||||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02;
|
|
||||||
inst.dst.size = 2;
|
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;
|
inst.src[0].size = 2;
|
||||||
break;
|
break;
|
||||||
|
case ShaderOperandType::IntegerInlineConstant: inst.format = ShaderInstructionFormat::Sdst2Ssrc0; break;
|
||||||
|
default: EXIT("unknown src0 type");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0x0a:
|
case 0x0a:
|
||||||
inst.type = ShaderInstructionType::SWqmB64;
|
inst.type = ShaderInstructionType::SWqmB64;
|
||||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02;
|
inst.format = ShaderInstructionFormat::Sdst2Ssrc02;
|
||||||
@@ -430,51 +574,6 @@ KYTY_SHADER_PARSER(shader_parse_sop1)
|
|||||||
return size;
|
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)
|
KYTY_SHADER_PARSER(shader_parse_sop2)
|
||||||
{
|
{
|
||||||
EXIT_IF(dst == nullptr);
|
EXIT_IF(dst == nullptr);
|
||||||
@@ -486,10 +585,16 @@ KYTY_SHADER_PARSER(shader_parse_sop2)
|
|||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x7d: return shader_parse_sop1(pc, src, buffer, dst); break;
|
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;
|
case 0x7f: return shader_parse_sopp(pc, src, buffer, dst); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opcode >= 0x60)
|
||||||
|
{
|
||||||
|
return shader_parse_sopk(pc, src, buffer, dst);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ssrc1 = (buffer[0] >> 8u) & 0xffu;
|
uint32_t ssrc1 = (buffer[0] >> 8u) & 0xffu;
|
||||||
uint32_t ssrc0 = (buffer[0] >> 0u) & 0xffu;
|
uint32_t ssrc0 = (buffer[0] >> 0u) & 0xffu;
|
||||||
uint32_t sdst = (buffer[0] >> 16u) & 0x7fu;
|
uint32_t sdst = (buffer[0] >> 16u) & 0x7fu;
|
||||||
@@ -519,6 +624,16 @@ KYTY_SHADER_PARSER(shader_parse_sop2)
|
|||||||
|
|
||||||
switch (opcode)
|
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:
|
case 0x15:
|
||||||
inst.type = ShaderInstructionType::SAndn2B64;
|
inst.type = ShaderInstructionType::SAndn2B64;
|
||||||
inst.format = ShaderInstructionFormat::Sdst2Ssrc02Ssrc12;
|
inst.format = ShaderInstructionFormat::Sdst2Ssrc02Ssrc12;
|
||||||
@@ -526,7 +641,16 @@ KYTY_SHADER_PARSER(shader_parse_sop2)
|
|||||||
inst.src[0].size = 2;
|
inst.src[0].size = 2;
|
||||||
inst.src[1].size = 2;
|
inst.src[1].size = 2;
|
||||||
break;
|
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 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);
|
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++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||||
|
inst.dst.type = ShaderOperandType::VccLo;
|
||||||
|
inst.dst.size = 2;
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x0d:
|
case 0x02: inst.type = ShaderInstructionType::VCmpEqF32; break;
|
||||||
inst.type = ShaderInstructionType::VCmpNeqF32;
|
case 0x0d: inst.type = ShaderInstructionType::VCmpNeqF32; break;
|
||||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
case 0x84: inst.type = ShaderInstructionType::VCmpGtI32; break;
|
||||||
inst.dst.type = ShaderOperandType::VccLo;
|
case 0xc2: inst.type = ShaderInstructionType::VCmpEqU32; break;
|
||||||
inst.dst.size = 2;
|
case 0xc5: inst.type = ShaderInstructionType::VCmpNeU32; break;
|
||||||
break;
|
case 0xd2: inst.type = ShaderInstructionType::VCmpxEqU32; break;
|
||||||
case 0xc2:
|
case 0xd4: inst.type = ShaderInstructionType::VCmpxGtU32; break;
|
||||||
inst.type = ShaderInstructionType::VCmpEqU32;
|
case 0xd5: inst.type = ShaderInstructionType::VCmpxNeU32; break;
|
||||||
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;
|
|
||||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vopc opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
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++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x01:
|
case 0x01: inst.type = ShaderInstructionType::VMovB32; break;
|
||||||
inst.type = ShaderInstructionType::VMovB32;
|
case 0x06: inst.type = ShaderInstructionType::VCvtF32U32; break;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
case 0x07: inst.type = ShaderInstructionType::VCvtU32F32; break;
|
||||||
break;
|
case 0x11: inst.type = ShaderInstructionType::VCvtF32Ubyte0; break;
|
||||||
case 0x06:
|
case 0x12: inst.type = ShaderInstructionType::VCvtF32Ubyte1; break;
|
||||||
inst.type = ShaderInstructionType::VCvtF32U32;
|
case 0x13: inst.type = ShaderInstructionType::VCvtF32Ubyte2; break;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
case 0x14: inst.type = ShaderInstructionType::VCvtF32Ubyte3; break;
|
||||||
break;
|
case 0x2a: inst.type = ShaderInstructionType::VRcpF32; break;
|
||||||
case 0x07:
|
case 0x2e: inst.type = ShaderInstructionType::VRsqF32; break;
|
||||||
inst.type = ShaderInstructionType::VCvtU32F32;
|
case 0x33: inst.type = ShaderInstructionType::VSqrtF32; break;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0;
|
case 0x37: inst.type = ShaderInstructionType::VNotB32; break;
|
||||||
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;
|
|
||||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop1 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
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++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
@@ -692,34 +789,18 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
|||||||
inst.src[2].size = 2;
|
inst.src[2].size = 2;
|
||||||
inst.src_num = 3;
|
inst.src_num = 3;
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04: inst.type = ShaderInstructionType::VSubF32; break;
|
||||||
inst.type = ShaderInstructionType::VSubF32;
|
case 0x05: inst.type = ShaderInstructionType::VSubrevF32; break;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
case 0x08: inst.type = ShaderInstructionType::VMulF32; break;
|
||||||
break;
|
case 0x0b: inst.type = ShaderInstructionType::VMulU32U24; break;
|
||||||
case 0x05:
|
case 0x0f: inst.type = ShaderInstructionType::VMinF32; break;
|
||||||
inst.type = ShaderInstructionType::VSubrevF32;
|
case 0x10: inst.type = ShaderInstructionType::VMaxF32; break;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
case 0x15: inst.type = ShaderInstructionType::VLshrB32; break;
|
||||||
break;
|
case 0x16: inst.type = ShaderInstructionType::VLshrrevB32; break;
|
||||||
case 0x08:
|
case 0x18: inst.type = ShaderInstructionType::VAshrrevI32; break;
|
||||||
inst.type = ShaderInstructionType::VMulF32;
|
case 0x1a: inst.type = ShaderInstructionType::VLshlrevB32; break;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
case 0x1b: inst.type = ShaderInstructionType::VAndB32; break;
|
||||||
break;
|
case 0x1f: inst.type = ShaderInstructionType::VMacF32; 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 0x21:
|
case 0x21:
|
||||||
inst.type = ShaderInstructionType::VMadakF32;
|
inst.type = ShaderInstructionType::VMadakF32;
|
||||||
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
||||||
@@ -729,14 +810,8 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
|||||||
inst.src[2].size = 0;
|
inst.src[2].size = 0;
|
||||||
size++;
|
size++;
|
||||||
break;
|
break;
|
||||||
case 0x23:
|
case 0x23: inst.type = ShaderInstructionType::VMbcntLoU32B32; break;
|
||||||
inst.type = ShaderInstructionType::VMbcntLoU32B32;
|
case 0x24: inst.type = ShaderInstructionType::VMbcntHiU32B32; break;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
|
||||||
break;
|
|
||||||
case 0x24:
|
|
||||||
inst.type = ShaderInstructionType::VMbcntHiU32B32;
|
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
|
||||||
break;
|
|
||||||
case 0x25:
|
case 0x25:
|
||||||
inst.type = ShaderInstructionType::VAddI32;
|
inst.type = ShaderInstructionType::VAddI32;
|
||||||
inst.format = ShaderInstructionFormat::VdstSdst2Vsrc0Vsrc1;
|
inst.format = ShaderInstructionFormat::VdstSdst2Vsrc0Vsrc1;
|
||||||
@@ -755,10 +830,7 @@ KYTY_SHADER_PARSER(shader_parse_vop2)
|
|||||||
inst.dst2.type = ShaderOperandType::VccLo;
|
inst.dst2.type = ShaderOperandType::VccLo;
|
||||||
inst.dst2.size = 2;
|
inst.dst2.size = 2;
|
||||||
break;
|
break;
|
||||||
case 0x2f:
|
case 0x2f: inst.type = ShaderInstructionType::VCvtPkrtzF16F32; break;
|
||||||
inst.type = ShaderInstructionType::VCvtPkrtzF16F32;
|
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
|
||||||
break;
|
|
||||||
case 0x3e: return shader_parse_vopc(pc, src, buffer, dst); break;
|
case 0x3e: return shader_parse_vopc(pc, src, buffer, dst); break;
|
||||||
case 0x3f: return shader_parse_vop1(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);
|
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++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x02:
|
case 0x02:
|
||||||
@@ -856,6 +930,13 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||||||
inst.dst = operand_parse(vdst);
|
inst.dst = operand_parse(vdst);
|
||||||
inst.dst.size = 2;
|
inst.dst.size = 2;
|
||||||
break;
|
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:
|
case 0xc2:
|
||||||
inst.type = ShaderInstructionType::VCmpEqU32;
|
inst.type = ShaderInstructionType::VCmpEqU32;
|
||||||
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
inst.format = ShaderInstructionFormat::SmaskVsrc0Vsrc1;
|
||||||
@@ -885,10 +966,12 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||||||
case 0x104:
|
case 0x104:
|
||||||
inst.type = ShaderInstructionType::VSubF32;
|
inst.type = ShaderInstructionType::VSubF32;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||||
|
inst.src_num = 2;
|
||||||
break;
|
break;
|
||||||
case 0x108:
|
case 0x108:
|
||||||
inst.type = ShaderInstructionType::VMulF32;
|
inst.type = ShaderInstructionType::VMulF32;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||||
|
inst.src_num = 2;
|
||||||
break;
|
break;
|
||||||
case 0x11f:
|
case 0x11f:
|
||||||
inst.type = ShaderInstructionType::VMacF32;
|
inst.type = ShaderInstructionType::VMacF32;
|
||||||
@@ -903,14 +986,16 @@ KYTY_SHADER_PARSER(shader_parse_vop3)
|
|||||||
case 0x12f:
|
case 0x12f:
|
||||||
inst.type = ShaderInstructionType::VCvtPkrtzF16F32;
|
inst.type = ShaderInstructionType::VCvtPkrtzF16F32;
|
||||||
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||||
|
inst.src_num = 2;
|
||||||
break;
|
break;
|
||||||
case 0x141:
|
case 0x141: inst.type = ShaderInstructionType::VMadF32; break;
|
||||||
inst.type = ShaderInstructionType::VMadF32;
|
case 0x143: inst.type = ShaderInstructionType::VMadU32U24; break;
|
||||||
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
case 0x148: inst.type = ShaderInstructionType::VBfeU32; break;
|
||||||
break;
|
case 0x15d: inst.type = ShaderInstructionType::VSadU32; break;
|
||||||
case 0x15d:
|
case 0x16b:
|
||||||
inst.type = ShaderInstructionType::VSadU32;
|
inst.type = ShaderInstructionType::VMulLoI32;
|
||||||
inst.format = ShaderInstructionFormat::VdstVsrc0Vsrc1Vsrc2;
|
inst.format = ShaderInstructionFormat::SVdstSVsrc0SVsrc1;
|
||||||
|
inst.src_num = 2;
|
||||||
break;
|
break;
|
||||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown vop3 opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
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 vsrc2 = (buffer[1] >> 16u) & 0xffu;
|
||||||
uint32_t vsrc3 = (buffer[1] >> 24u) & 0xffu;
|
uint32_t vsrc3 = (buffer[1] >> 24u) & 0xffu;
|
||||||
|
|
||||||
EXIT_NOT_IMPLEMENTED(en != 0xf);
|
|
||||||
|
|
||||||
ShaderInstruction inst;
|
ShaderInstruction inst;
|
||||||
inst.pc = pc;
|
inst.pc = pc;
|
||||||
inst.src[0] = operand_parse(vsrc0 + 256);
|
inst.src[0] = operand_parse(vsrc0 + 256);
|
||||||
@@ -952,27 +1035,39 @@ KYTY_SHADER_PARSER(shader_parse_exp)
|
|||||||
switch (target)
|
switch (target)
|
||||||
{
|
{
|
||||||
case 0x00:
|
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.format = ShaderInstructionFormat::Mrt0Vsrc0Vsrc1ComprVmDone;
|
||||||
inst.src_num = 2;
|
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;
|
inst.format = ShaderInstructionFormat::Mrt0Vsrc0Vsrc1Vsrc2Vsrc3VmDone;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 0x0c:
|
case 0x0c:
|
||||||
if (done != 0)
|
if (done != 0 && en == 0xf)
|
||||||
{
|
{
|
||||||
inst.format = ShaderInstructionFormat::Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done;
|
inst.format = ShaderInstructionFormat::Pos0Vsrc0Vsrc1Vsrc2Vsrc3Done;
|
||||||
};
|
};
|
||||||
break;
|
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 0x20: inst.format = ShaderInstructionFormat::Param0Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||||
case 0x21: inst.format = ShaderInstructionFormat::Param1Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
case 0x21: inst.format = ShaderInstructionFormat::Param1Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||||
case 0x22: inst.format = ShaderInstructionFormat::Param2Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
case 0x22: inst.format = ShaderInstructionFormat::Param2Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||||
case 0x23: inst.format = ShaderInstructionFormat::Param3Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
case 0x23: inst.format = ShaderInstructionFormat::Param3Vsrc0Vsrc1Vsrc2Vsrc3; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (inst.format == ShaderInstructionFormat::Unknown)
|
if (inst.format == ShaderInstructionFormat::Unknown)
|
||||||
{
|
{
|
||||||
@@ -1039,6 +1134,12 @@ KYTY_SHADER_PARSER(shader_parse_smrd)
|
|||||||
inst.format = ShaderInstructionFormat::SdstSvSoffset;
|
inst.format = ShaderInstructionFormat::SdstSvSoffset;
|
||||||
inst.src[0].size = 4;
|
inst.src[0].size = 4;
|
||||||
break;
|
break;
|
||||||
|
case 0x09:
|
||||||
|
inst.type = ShaderInstructionType::SBufferLoadDwordx2;
|
||||||
|
inst.format = ShaderInstructionFormat::Sdst2SvSoffset;
|
||||||
|
inst.src[0].size = 4;
|
||||||
|
inst.dst.size = 2;
|
||||||
|
break;
|
||||||
case 0x0a:
|
case 0x0a:
|
||||||
inst.type = ShaderInstructionType::SBufferLoadDwordx4;
|
inst.type = ShaderInstructionType::SBufferLoadDwordx4;
|
||||||
inst.format = ShaderInstructionFormat::Sdst4SvSoffset;
|
inst.format = ShaderInstructionFormat::Sdst4SvSoffset;
|
||||||
@@ -1293,7 +1394,7 @@ KYTY_SHADER_PARSER(shader_parse_mtbuf)
|
|||||||
uint32_t vaddr = (buffer[1] >> 0u) & 0xffu;
|
uint32_t vaddr = (buffer[1] >> 0u) & 0xffu;
|
||||||
|
|
||||||
EXIT_NOT_IMPLEMENTED(idxen == 0);
|
EXIT_NOT_IMPLEMENTED(idxen == 0);
|
||||||
EXIT_NOT_IMPLEMENTED(offen == 1);
|
// EXIT_NOT_IMPLEMENTED(offen == 1);
|
||||||
EXIT_NOT_IMPLEMENTED(offset != 0);
|
EXIT_NOT_IMPLEMENTED(offset != 0);
|
||||||
EXIT_NOT_IMPLEMENTED(glc == 1);
|
EXIT_NOT_IMPLEMENTED(glc == 1);
|
||||||
EXIT_NOT_IMPLEMENTED(slc == 1);
|
EXIT_NOT_IMPLEMENTED(slc == 1);
|
||||||
@@ -1317,12 +1418,15 @@ KYTY_SHADER_PARSER(shader_parse_mtbuf)
|
|||||||
size++;
|
size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inst.src[1].size = 4;
|
||||||
|
|
||||||
switch (opcode) // NOLINT
|
switch (opcode) // NOLINT
|
||||||
{
|
{
|
||||||
case 0x03:
|
case 0x03:
|
||||||
inst.type = ShaderInstructionType::TBufferLoadFormatXyzw;
|
inst.type = ShaderInstructionType::TBufferLoadFormatXyzw;
|
||||||
inst.format = ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4;
|
inst.format = (offen == 1 ? ShaderInstructionFormat::Vdata4Vaddr2SvSoffsOffenIdxenFloat4
|
||||||
inst.src[1].size = 4;
|
: ShaderInstructionFormat::Vdata4VaddrSvSoffsIdxenFloat4);
|
||||||
|
inst.src[0].size += static_cast<int>(offen);
|
||||||
inst.dst.size = 4;
|
inst.dst.size = 4;
|
||||||
break;
|
break;
|
||||||
default: printf("%s", dst->DbgDump().C_Str()); EXIT("unknown mtbuf opcode: 0x%02" PRIx32 " at addr 0x%08" PRIx32 "\n", opcode, pc);
|
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);
|
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))
|
(instruction == 0xBE802000 && type == ShaderType::Fetch))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -1512,23 +1617,23 @@ static void bi_print(const char* func, const ShaderBinaryInfo& bi)
|
|||||||
{
|
{
|
||||||
printf("%s\n", func);
|
printf("%s\n", func);
|
||||||
|
|
||||||
printf("\t m_signature = %.7s\n", bi.signature);
|
printf("\t signature = %.7s\n", bi.signature);
|
||||||
printf("\t m_version = 0x%02" PRIx8 "\n", bi.version);
|
printf("\t 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 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 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 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 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 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 chunk_usage_base_offset_dw = 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 num_input_usage_slots = 0x%02" PRIx8 "\n", bi.num_input_usage_slots);
|
||||||
printf("\t m_isSrt = 0x%02" PRIx8 "\n", bi.is_srt);
|
printf("\t is_srt = 0x%02" PRIx8 "\n", bi.is_srt);
|
||||||
printf("\t m_isSrtUsedInfoValid = 0x%02" PRIx8 "\n", bi.is_srt_used_info_valid);
|
printf("\t is_srt_used_info_valid = 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 is_extended_usage_info = 0x%02" PRIx8 "\n", bi.is_extended_usage_info);
|
||||||
printf("\t m_reserved2 = 0x%02" PRIx8 "\n", bi.reserved2);
|
printf("\t reserved2 = 0x%02" PRIx8 "\n", bi.reserved2);
|
||||||
printf("\t m_reserved3 = 0x%02" PRIx8 "\n", bi.reserved3);
|
printf("\t reserved3 = 0x%02" PRIx8 "\n", bi.reserved3);
|
||||||
printf("\t m_shaderHash0 = 0x%08" PRIx32 "\n", bi.hash0);
|
printf("\t hash0 = 0x%08" PRIx32 "\n", bi.hash0);
|
||||||
printf("\t m_shaderHash1 = 0x%08" PRIx32 "\n", bi.hash1);
|
printf("\t hash1 = 0x%08" PRIx32 "\n", bi.hash1);
|
||||||
printf("\t m_crc32 = 0x%08" PRIx32 "\n", bi.crc32);
|
printf("\t crc32 = 0x%08" PRIx32 "\n", bi.crc32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vs_check(const VsStageRegisters& vs)
|
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(ps_info == nullptr);
|
||||||
EXIT_IF(regs == 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_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;
|
ps_info->ps_pixel_kill_enable = regs->ps_regs.shader_kill_enable;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user