feat(shader): implement VOPC I16/U16 cmpx compares
This commit is contained in:
parent
a67b644ff6
commit
889af1d542
|
|
@ -203,6 +203,14 @@ if(BUILD_TESTING)
|
|||
set_tests_properties(ray_tracing_miss PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
add_executable(vector_compare_i16_u16_tests tests/VectorCompareI16U16.cpp)
|
||||
target_link_libraries(vector_compare_i16_u16_tests PRIVATE shader_recompiler_agc_driver libc)
|
||||
configure_windows_unwind(vector_compare_i16_u16_tests)
|
||||
add_test(NAME vector_compare_i16_u16 COMMAND vector_compare_i16_u16_tests)
|
||||
if(WIN32)
|
||||
set_tests_properties(vector_compare_i16_u16 PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
target_include_directories(guest_indexed_draw_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(guest_indexed_draw_tests PRIVATE libSceAgc libSceAgcDriver libc)
|
||||
configure_windows_unwind(guest_indexed_draw_tests)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
#include "Translation/TranslationContext.hpp"
|
||||
#include "RdnaDecoder/RdnaVectorOpDecoder.hpp"
|
||||
#include <array>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace ShaderRecompiler;
|
||||
static void Require(bool value) { if (!value) throw std::runtime_error("vector compare regression"); }
|
||||
static void Check(std::uint32_t encoding, RdnaOpcode opcode) {
|
||||
const std::array<std::uint32_t, 1> code{(encoding << 17u) | (1u << 9u) | 100u};
|
||||
const RdnaInstruction instruction = DecodeRdnaVopc(0u, code, 0u);
|
||||
Require(instruction.op == opcode);
|
||||
Require(instruction.family == RdnaInstructionFamily::VOPC);
|
||||
Require(IsVectorAluOpcode(instruction.op));
|
||||
Require(instruction.destination.kind == RdnaOperandKind::ExecLo);
|
||||
IrProgram program;
|
||||
auto& block = program.CreateBlock();
|
||||
program.SetEntryBlock(block);
|
||||
TranslationContext context(program, block, 256);
|
||||
context.TranslateInstruction(instruction);
|
||||
}
|
||||
int main() {
|
||||
Check(0x99u, RdnaOpcode::VCmpxLtI16);
|
||||
Check(0x9au, RdnaOpcode::VCmpxEqI16);
|
||||
Check(0x9bu, RdnaOpcode::VCmpxLeI16);
|
||||
Check(0x9cu, RdnaOpcode::VCmpxGtI16);
|
||||
Check(0x9du, RdnaOpcode::VCmpxNeI16);
|
||||
Check(0x9eu, RdnaOpcode::VCmpxGeI16);
|
||||
Check(0xbau, RdnaOpcode::VCmpxEqU16);
|
||||
Check(0xbbu, RdnaOpcode::VCmpxLeU16);
|
||||
Check(0xbdu, RdnaOpcode::VCmpxNeU16);
|
||||
Check(0xbeu, RdnaOpcode::VCmpxGeU16);
|
||||
}
|
||||
|
|
@ -394,6 +394,12 @@ enum class RdnaOpcode : std::uint16_t {
|
|||
VCmpGtI16,
|
||||
VCmpNeI16,
|
||||
VCmpGeI16,
|
||||
VCmpxLtI16,
|
||||
VCmpxEqI16,
|
||||
VCmpxLeI16,
|
||||
VCmpxGtI16,
|
||||
VCmpxNeI16,
|
||||
VCmpxGeI16,
|
||||
VCmpLtF16,
|
||||
VCmpEqF16,
|
||||
VCmpLeF16,
|
||||
|
|
@ -420,7 +426,11 @@ enum class RdnaOpcode : std::uint16_t {
|
|||
VCmpLeU16,
|
||||
VCmpGtU16,
|
||||
VCmpxLtU16,
|
||||
VCmpxEqU16,
|
||||
VCmpxLeU16,
|
||||
VCmpxGtU16,
|
||||
VCmpxNeU16,
|
||||
VCmpxGeU16,
|
||||
VCmpNeU16,
|
||||
VCmpGeU16,
|
||||
VCmpFU32,
|
||||
|
|
|
|||
|
|
@ -367,6 +367,12 @@ bool IsVectorAluOpcode(RdnaOpcode opcode) {
|
|||
case RdnaOpcode::VCmpGtI16:
|
||||
case RdnaOpcode::VCmpNeI16:
|
||||
case RdnaOpcode::VCmpGeI16:
|
||||
case RdnaOpcode::VCmpxLtI16:
|
||||
case RdnaOpcode::VCmpxEqI16:
|
||||
case RdnaOpcode::VCmpxLeI16:
|
||||
case RdnaOpcode::VCmpxGtI16:
|
||||
case RdnaOpcode::VCmpxNeI16:
|
||||
case RdnaOpcode::VCmpxGeI16:
|
||||
case RdnaOpcode::VCmpLtF16:
|
||||
case RdnaOpcode::VCmpEqF16:
|
||||
case RdnaOpcode::VCmpLeF16:
|
||||
|
|
@ -393,7 +399,11 @@ bool IsVectorAluOpcode(RdnaOpcode opcode) {
|
|||
case RdnaOpcode::VCmpLeU16:
|
||||
case RdnaOpcode::VCmpGtU16:
|
||||
case RdnaOpcode::VCmpxLtU16:
|
||||
case RdnaOpcode::VCmpxEqU16:
|
||||
case RdnaOpcode::VCmpxLeU16:
|
||||
case RdnaOpcode::VCmpxGtU16:
|
||||
case RdnaOpcode::VCmpxNeU16:
|
||||
case RdnaOpcode::VCmpxGeU16:
|
||||
case RdnaOpcode::VCmpNeU16:
|
||||
case RdnaOpcode::VCmpGeU16:
|
||||
case RdnaOpcode::VCmpFU32:
|
||||
|
|
|
|||
|
|
@ -258,6 +258,12 @@ constexpr VopcOpcodeInfo vopcOpcodes[] = {
|
|||
{0x95u, RdnaOpcode::VCmpxNeI32},
|
||||
{0x96u, RdnaOpcode::VCmpxGeI32},
|
||||
{0x98u, RdnaOpcode::VCmpxClassF32},
|
||||
{0x99u, RdnaOpcode::VCmpxLtI16},
|
||||
{0x9au, RdnaOpcode::VCmpxEqI16},
|
||||
{0x9bu, RdnaOpcode::VCmpxLeI16},
|
||||
{0x9cu, RdnaOpcode::VCmpxGtI16},
|
||||
{0x9du, RdnaOpcode::VCmpxNeI16},
|
||||
{0x9eu, RdnaOpcode::VCmpxGeI16},
|
||||
{0xa9u, RdnaOpcode::VCmpLtU16},
|
||||
{0xaau, RdnaOpcode::VCmpEqU16},
|
||||
{0xabu, RdnaOpcode::VCmpLeU16},
|
||||
|
|
@ -265,7 +271,11 @@ constexpr VopcOpcodeInfo vopcOpcodes[] = {
|
|||
{0xadu, RdnaOpcode::VCmpNeU16},
|
||||
{0xaeu, RdnaOpcode::VCmpGeU16},
|
||||
{0xb9u, RdnaOpcode::VCmpxLtU16, false},
|
||||
{0xbau, RdnaOpcode::VCmpxEqU16},
|
||||
{0xbbu, RdnaOpcode::VCmpxLeU16},
|
||||
{0xbcu, RdnaOpcode::VCmpxGtU16},
|
||||
{0xbdu, RdnaOpcode::VCmpxNeU16},
|
||||
{0xbeu, RdnaOpcode::VCmpxGeU16},
|
||||
{0xc0u, RdnaOpcode::VCmpFU32},
|
||||
{0xc1u, RdnaOpcode::VCmpLtU32},
|
||||
{0xc2u, RdnaOpcode::VCmpEqU32},
|
||||
|
|
@ -1124,8 +1134,18 @@ bool isVopcCompareExec(RdnaOpcode opcode) {
|
|||
case RdnaOpcode::VCmpxGeU32:
|
||||
case RdnaOpcode::VCmpxNeI64:
|
||||
case RdnaOpcode::VCmpxNeU64:
|
||||
case RdnaOpcode::VCmpxLtI16:
|
||||
case RdnaOpcode::VCmpxEqI16:
|
||||
case RdnaOpcode::VCmpxLeI16:
|
||||
case RdnaOpcode::VCmpxGtI16:
|
||||
case RdnaOpcode::VCmpxNeI16:
|
||||
case RdnaOpcode::VCmpxGeI16:
|
||||
case RdnaOpcode::VCmpxLtU16:
|
||||
case RdnaOpcode::VCmpxEqU16:
|
||||
case RdnaOpcode::VCmpxLeU16:
|
||||
case RdnaOpcode::VCmpxGtU16:
|
||||
case RdnaOpcode::VCmpxNeU16:
|
||||
case RdnaOpcode::VCmpxGeU16:
|
||||
case RdnaOpcode::VCmpxLtF16:
|
||||
case RdnaOpcode::VCmpxEqF16:
|
||||
case RdnaOpcode::VCmpxLeF16:
|
||||
|
|
|
|||
|
|
@ -148,15 +148,27 @@ bool TranslationContext::emitVector(const RdnaInstruction& inst) {
|
|||
case RdnaOpcode::VCmpEqU16:
|
||||
emitInteger16Compare(inst, IrOpcode::IEqual32, false, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxEqU16:
|
||||
emitInteger16Compare(inst, IrOpcode::IEqual32, false, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpEqI16:
|
||||
emitInteger16Compare(inst, IrOpcode::IEqual32, true, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxEqI16:
|
||||
emitInteger16Compare(inst, IrOpcode::IEqual32, true, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpNeU16:
|
||||
emitInteger16Compare(inst, IrOpcode::INotEqual32, false, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxNeU16:
|
||||
emitInteger16Compare(inst, IrOpcode::INotEqual32, false, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpNeI16:
|
||||
emitInteger16Compare(inst, IrOpcode::INotEqual32, true, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxNeI16:
|
||||
emitInteger16Compare(inst, IrOpcode::INotEqual32, true, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpGtU16:
|
||||
emitInteger16Compare(inst, IrOpcode::UGreaterThan32, false, false);
|
||||
return true;
|
||||
|
|
@ -166,6 +178,9 @@ bool TranslationContext::emitVector(const RdnaInstruction& inst) {
|
|||
case RdnaOpcode::VCmpGeU16:
|
||||
emitInteger16Compare(inst, IrOpcode::UGreaterThanEqual32, false, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxGeU16:
|
||||
emitInteger16Compare(inst, IrOpcode::UGreaterThanEqual32, false, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpLtU16:
|
||||
emitInteger16Compare(inst, IrOpcode::ULessThan32, false, false);
|
||||
return true;
|
||||
|
|
@ -175,18 +190,33 @@ bool TranslationContext::emitVector(const RdnaInstruction& inst) {
|
|||
case RdnaOpcode::VCmpLeU16:
|
||||
emitInteger16Compare(inst, IrOpcode::ULessThanEqual32, false, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxLeU16:
|
||||
emitInteger16Compare(inst, IrOpcode::ULessThanEqual32, false, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpGtI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SGreaterThan32, true, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxGtI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SGreaterThan32, true, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpGeI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SGreaterThanEqual32, true, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxGeI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SGreaterThanEqual32, true, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpLtI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SLessThan32, true, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxLtI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SLessThan32, true, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpLeI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SLessThanEqual32, true, false);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpxLeI16:
|
||||
emitInteger16Compare(inst, IrOpcode::SLessThanEqual32, true, true);
|
||||
return true;
|
||||
case RdnaOpcode::VCmpEqF32:
|
||||
emitFloatCompare(inst, IrOpcode::FPOrdEqual32, false, false);
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Reference in New Issue