DXIL Disassembly custom handling for DXOp::Pack4x8, DXOp::Unpack4x8

This commit is contained in:
Jake Turner
2024-12-15 17:31:05 +00:00
parent f2d2d73d2e
commit 0043cfd613
3 changed files with 104 additions and 0 deletions
@@ -628,6 +628,20 @@ enum class QuadOpKind : uint32_t
// horizontal and vertical direction
};
// Packing/unpacking intrinsics
enum class UnpackMode : uint32_t
{
Unsigned = 0, // not sign extended
Signed = 1, // sign extended
};
enum class PackMode : uint32_t
{
Trunc = 0, // Pack low bits, drop the rest
UClamp = 1, // Unsigned clamp - [0, 255] for 8-bits
SClamp = 2, // Signed clamp - [-128, 127] for 8-bits
};
enum class BarrierMode : uint32_t
{
Invalid = 0,
@@ -1774,6 +1788,8 @@ DECLARE_REFLECTION_ENUM(DXIL::Attribute);
DECLARE_STRINGISE_TYPE(DXIL::InstructionFlags);
DECLARE_STRINGISE_TYPE(DXIL::AtomicBinOpCode);
DECLARE_STRINGISE_TYPE(DXIL::QuadOpKind);
DECLARE_STRINGISE_TYPE(DXIL::PackMode);
DECLARE_STRINGISE_TYPE(DXIL::UnpackMode);
DECLARE_STRINGISE_TYPE(DXIL::Operation);
DECLARE_STRINGISE_TYPE(DXIL::DXOp);
DECLARE_STRINGISE_TYPE(DXIL::Type::TypeKind);
@@ -4100,6 +4100,71 @@ void Program::MakeRDDisassemblyString(const DXBC::Reflection *reflection)
}
break;
}
case DXOp::Pack4x8:
{
// Pack4x8(packMode,x,y,z,w)
// SM6.6: pack_u8, pack_s8, pack_clamp_u8 (0-255), pack_s8, pack_clamp_s8 (-128-127)
// packs vector of 4 signed or unsigned values into a packed datatype, drops or clamps unused bits
PackMode packMode;
// const Type *retType = inst.type;
if(getival<PackMode>(inst.args[1], packMode))
{
if(packMode == PackMode::Trunc)
lineStr += "pack_";
else
lineStr += "pack_clamp_";
lineStr += "s8";
lineStr += "(";
bool needComma = false;
for(uint32_t a = 2; a < 6; ++a)
{
if(!isUndef(inst.args[a]))
{
if(needComma)
lineStr += ", ";
lineStr += GetArgId(inst, a);
needComma = true;
}
}
lineStr += ")";
}
else
{
showDxFuncName = true;
}
break;
}
case DXOp::Unpack4x8:
{
// Unpack4x8(unpackMode,pk)
// SM6.6: unpack_s8s16, unpack_s8s32, unpack_u8u16, unpack_u8u32
// unpacks 4 8-bit signed or unsigned values into int32 or int16 vector
UnpackMode unpackMode;
if(getival<UnpackMode>(inst.args[1], unpackMode))
{
const Type *retType = inst.type;
RDCASSERTEQUAL(retType->type, Type::Struct);
if(retType->members.empty())
{
showDxFuncName = true;
break;
}
uint32_t bitWidth = retType->members[0]->bitWidth;
if(unpackMode == UnpackMode::Signed)
lineStr += StringFormat::Fmt("unpack_s8s%d", bitWidth);
else
lineStr += StringFormat::Fmt("unpack_u8u%d", bitWidth);
lineStr += "(";
lineStr += GetArgId(inst, 2);
lineStr += ")";
}
else
{
showDxFuncName = true;
}
break;
}
case DXOp::QuadOp:
{
// QuadOp(value,op)
@@ -139,6 +139,29 @@ rdcstr DoStringise(const DXIL::QuadOpKind &el)
END_ENUM_STRINGISE();
};
template <>
rdcstr DoStringise(const DXIL::PackMode &el)
{
BEGIN_ENUM_STRINGISE(DXIL::PackMode)
{
STRINGISE_ENUM_CLASS(Trunc)
STRINGISE_ENUM_CLASS(UClamp)
STRINGISE_ENUM_CLASS(SClamp)
}
END_ENUM_STRINGISE();
};
template <>
rdcstr DoStringise(const DXIL::UnpackMode &el)
{
BEGIN_ENUM_STRINGISE(DXIL::UnpackMode)
{
STRINGISE_ENUM_CLASS(Unsigned)
STRINGISE_ENUM_CLASS(Signed)
}
END_ENUM_STRINGISE();
};
template <>
rdcstr DoStringise(const DXIL::Operation &el)
{