shader: allow partial SDWA destinations for V_NOT_B32 (#684)
This commit is contained in:
parent
e930657bf6
commit
cfb110e0aa
|
|
@ -521,7 +521,8 @@ constexpr Vop1SdwaRule VOP1_SDWA_RULES[] = {
|
|||
{Opcode::V_CVT_F32_U32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false},
|
||||
{Opcode::V_CVT_F32_I32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false},
|
||||
{Opcode::V_CVT_F32_UBYTE0, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false},
|
||||
{Opcode::V_NOT_B32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false},
|
||||
{Opcode::V_NOT_B32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), SdwaSelBytes() | SdwaSelWords(),
|
||||
SdwaSelFull(), false},
|
||||
{Opcode::V_FFBL_B32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), 0, 0, false},
|
||||
{Opcode::V_CVT_F32_F16, SdwaSelWords() | SdwaSelFull(), 0, 0, true},
|
||||
{Opcode::V_CVT_F16_F32, SdwaSelBytes() | SdwaSelWords() | SdwaSelFull(), SdwaSelWords(),
|
||||
|
|
|
|||
|
|
@ -18065,6 +18065,29 @@ TestCase Vop1SdwaNotCapturedByte0Source() {
|
|||
return test;
|
||||
}
|
||||
|
||||
TestCase Vop1SdwaNotPreservesHighWordDestination() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendBufferLoadDword(&code, 0, 30);
|
||||
AppendVMovLiteral(&code, 3, 0xabcd5555u);
|
||||
code.push_back(0x7e066ef9u);
|
||||
code.push_back(0x00061400u);
|
||||
AppendStoreVgpr(&code, 3, 0);
|
||||
AppendEnd(&code);
|
||||
|
||||
TestCase test;
|
||||
test.name = "Vop1SdwaNotPreservesHighWordDestination";
|
||||
test.code = std::move(code);
|
||||
test.initial = {0x12345678u};
|
||||
test.expected = {0xabcda987u};
|
||||
test.opcodes = {O::BUFFER_LOAD_DWORD, O::V_MOV_B32, O::V_NOT_B32,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
test.ir_counts = {{" = BitwiseNot32 ", 1}};
|
||||
test.required_spirv = {"OpNot"};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase Vop1SdwaMovByteDestinations() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
|
|
@ -27176,6 +27199,7 @@ std::vector<TestCase> MakeCases() {
|
|||
AddCase(VectorFfbhI32NativeAndVop3OnGpu);
|
||||
AddCase(Vop1SdwaFfblCapturedHighWordSource);
|
||||
AddCase(Vop1SdwaNotCapturedByte0Source);
|
||||
AddCase(Vop1SdwaNotPreservesHighWordDestination);
|
||||
AddCase(Vop1SdwaMovByteDestinations);
|
||||
AddCase(Vop2SdwaSubNcExactByte2Destination);
|
||||
AddCase(Vop2SdwaAddNcCapturedHighWordDestination);
|
||||
|
|
|
|||
|
|
@ -3435,6 +3435,62 @@ void TestNewShaderRecompilerCapturedVop1SdwaByteConvert() {
|
|||
CheckSpirvBinaryValidates(result.spirv);
|
||||
}
|
||||
|
||||
void TestNewShaderRecompilerVop1SdwaNotDestination() {
|
||||
auto options = MakeCompileOptions(ShaderType::Pixel);
|
||||
|
||||
const auto check_destination = [&](uint32_t modifier, uint32_t dst_sel,
|
||||
uint32_t dst_unused) {
|
||||
const uint32_t shader[] = {
|
||||
0x7e066ef9u, modifier, EncodeExp0(0x00, 0x1),
|
||||
EncodeExp1(3, 0, 0, 0), EncodeSopp(0x01),
|
||||
};
|
||||
|
||||
ShaderRecompiler::Decoder::Instruction decoded;
|
||||
ShaderRecompiler::Decoder::DecodeInstruction(shader, 0, decoded);
|
||||
Check(decoded.opcode == ShaderRecompiler::Decoder::Opcode::V_NOT_B32,
|
||||
"V_NOT_B32 SDWA opcode did not decode");
|
||||
Check(decoded.word_count == 2u,
|
||||
"V_NOT_B32 SDWA instruction has the wrong word count");
|
||||
Check(decoded.dst.kind == ShaderRecompiler::Decoder::OperandKind::Vgpr &&
|
||||
decoded.dst.reg == 3u && decoded.dst.sdwa_sel == dst_sel &&
|
||||
decoded.dst.sdwa_dst_unused == dst_unused &&
|
||||
decoded.dst.explicit_sdwa_dst,
|
||||
"V_NOT_B32 SDWA destination metadata is incorrect");
|
||||
Check(decoded.src0.kind == ShaderRecompiler::Decoder::OperandKind::Vgpr &&
|
||||
decoded.src0.reg == 0u && decoded.src0.sdwa_sel == 6u &&
|
||||
!decoded.src0.negate && !decoded.src0.absolute,
|
||||
"V_NOT_B32 SDWA source metadata is incorrect");
|
||||
|
||||
auto result = RecompileForTest(shader, options);
|
||||
CheckSpirvBinaryValidates(result.spirv);
|
||||
};
|
||||
|
||||
check_destination(0x00061400u, 4u, 2u);
|
||||
check_destination(0x00060500u, 5u, 0u);
|
||||
check_destination(0x00060000u, 0u, 0u);
|
||||
|
||||
const auto check_rejected = [&](uint32_t modifier, const char *message) {
|
||||
const uint32_t instruction[] = {0x7e066ef9u, modifier};
|
||||
|
||||
ShaderRecompiler::Decoder::Instruction decoded;
|
||||
ShaderRecompiler::Decoder::DecodeInstruction(instruction, 0, decoded);
|
||||
Check(decoded.word_count == 2u &&
|
||||
decoded.opcode == ShaderRecompiler::Decoder::Opcode::UNSUPPORTED,
|
||||
message);
|
||||
};
|
||||
|
||||
check_rejected(0x00060700u, "V_NOT_B32 SDWA accepted destination selector 7");
|
||||
check_rejected(0x00070600u, "V_NOT_B32 SDWA accepted source selector 7");
|
||||
check_rejected(0x00061c00u,
|
||||
"V_NOT_B32 SDWA accepted destination unused value 3");
|
||||
check_rejected(0x00160400u, "V_NOT_B32 SDWA accepted source negation");
|
||||
check_rejected(0x00260400u, "V_NOT_B32 SDWA accepted source absolute");
|
||||
check_rejected(0x00062400u, "V_NOT_B32 SDWA accepted clamp");
|
||||
check_rejected(0x00064400u, "V_NOT_B32 SDWA accepted output modifier");
|
||||
check_rejected(0x00000400u,
|
||||
"V_NOT_B32 SDWA partial destination accepted a byte source");
|
||||
}
|
||||
|
||||
void TestNewShaderRecompilerBootB16PackedAndSdwaOpcodes() {
|
||||
const uint32_t shader[] = {
|
||||
0xd7070001u,
|
||||
|
|
@ -13397,6 +13453,7 @@ int main() {
|
|||
TestNewShaderRecompilerDsReadWrite2Translation();
|
||||
TestNewShaderRecompilerDsWideAndAtomicTranslation();
|
||||
TestNewShaderRecompilerCapturedVop1SdwaByteConvert();
|
||||
TestNewShaderRecompilerVop1SdwaNotDestination();
|
||||
TestNewShaderRecompilerScalarMemoryBindingDomains();
|
||||
// Opcode semantics and optimized SPIR-V are exercised by
|
||||
// ShaderRecompilerComputeTests; keep the distinct decoder contract checks
|
||||
|
|
|
|||
Loading…
Reference in New Issue