mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-05 16:29:59 +00:00
shader: Improve VOTE.VTG stub
This commit is contained in:
parent
12f5f32098
commit
ecb30c9072
7 changed files with 147 additions and 4 deletions
|
@ -59,6 +59,14 @@ void EmitSetZFlag(EmitContext& ctx);
|
||||||
void EmitSetSFlag(EmitContext& ctx);
|
void EmitSetSFlag(EmitContext& ctx);
|
||||||
void EmitSetCFlag(EmitContext& ctx);
|
void EmitSetCFlag(EmitContext& ctx);
|
||||||
void EmitSetOFlag(EmitContext& ctx);
|
void EmitSetOFlag(EmitContext& ctx);
|
||||||
|
void EmitGetFCSMFlag(EmitContext& ctx);
|
||||||
|
void EmitGetTAFlag(EmitContext& ctx);
|
||||||
|
void EmitGetTRFlag(EmitContext& ctx);
|
||||||
|
void EmitGetMXFlag(EmitContext& ctx);
|
||||||
|
void EmitSetFCSMFlag(EmitContext& ctx);
|
||||||
|
void EmitSetTAFlag(EmitContext& ctx);
|
||||||
|
void EmitSetTRFlag(EmitContext& ctx);
|
||||||
|
void EmitSetMXFlag(EmitContext& ctx);
|
||||||
Id EmitWorkgroupId(EmitContext& ctx);
|
Id EmitWorkgroupId(EmitContext& ctx);
|
||||||
Id EmitLocalInvocationId(EmitContext& ctx);
|
Id EmitLocalInvocationId(EmitContext& ctx);
|
||||||
Id EmitLoadLocal(EmitContext& ctx, Id word_offset);
|
Id EmitLoadLocal(EmitContext& ctx, Id word_offset);
|
||||||
|
|
|
@ -263,6 +263,38 @@ void EmitSetOFlag(EmitContext&) {
|
||||||
throw NotImplementedException("SPIR-V Instruction");
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmitGetFCSMFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitGetTAFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitGetTRFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitGetMXFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitSetFCSMFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitSetTAFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitSetTRFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitSetMXFlag(EmitContext&) {
|
||||||
|
throw NotImplementedException("SPIR-V Instruction");
|
||||||
|
}
|
||||||
|
|
||||||
Id EmitWorkgroupId(EmitContext& ctx) {
|
Id EmitWorkgroupId(EmitContext& ctx) {
|
||||||
return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id);
|
return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,38 @@ void IREmitter::SetOFlag(const U1& value) {
|
||||||
Inst(Opcode::SetOFlag, value);
|
Inst(Opcode::SetOFlag, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
U1 IREmitter::GetFCSMFlag() {
|
||||||
|
return Inst<U1>(Opcode::GetFCSMFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
U1 IREmitter::GetTAFlag() {
|
||||||
|
return Inst<U1>(Opcode::GetTAFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
U1 IREmitter::GetTRFlag() {
|
||||||
|
return Inst<U1>(Opcode::GetTRFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
U1 IREmitter::GetMXFlag() {
|
||||||
|
return Inst<U1>(Opcode::GetMXFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IREmitter::SetFCSMFlag(const U1& value) {
|
||||||
|
Inst(Opcode::SetFCSMFlag, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IREmitter::SetTAFlag(const U1& value) {
|
||||||
|
Inst(Opcode::SetTAFlag, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IREmitter::SetTRFlag(const U1& value) {
|
||||||
|
Inst(Opcode::SetTRFlag, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IREmitter::SetMXFlag(const U1& value) {
|
||||||
|
Inst(Opcode::SetMXFlag, value);
|
||||||
|
}
|
||||||
|
|
||||||
static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
|
static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
|
||||||
switch (flow_test) {
|
switch (flow_test) {
|
||||||
case FlowTest::F:
|
case FlowTest::F:
|
||||||
|
@ -256,13 +288,14 @@ static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) {
|
||||||
return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag());
|
return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag());
|
||||||
case FlowTest::RGT:
|
case FlowTest::RGT:
|
||||||
return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag()));
|
return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag()));
|
||||||
|
|
||||||
|
case FlowTest::FCSM_TR:
|
||||||
|
return ir.LogicalAnd(ir.GetFCSMFlag(), ir.GetTRFlag());
|
||||||
case FlowTest::CSM_TA:
|
case FlowTest::CSM_TA:
|
||||||
case FlowTest::CSM_TR:
|
case FlowTest::CSM_TR:
|
||||||
case FlowTest::CSM_MX:
|
case FlowTest::CSM_MX:
|
||||||
case FlowTest::FCSM_TA:
|
case FlowTest::FCSM_TA:
|
||||||
case FlowTest::FCSM_TR:
|
|
||||||
case FlowTest::FCSM_MX:
|
case FlowTest::FCSM_MX:
|
||||||
return ir.Imm1(false);
|
|
||||||
default:
|
default:
|
||||||
throw NotImplementedException("Flow test {}", flow_test);
|
throw NotImplementedException("Flow test {}", flow_test);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,16 @@ public:
|
||||||
void SetCFlag(const U1& value);
|
void SetCFlag(const U1& value);
|
||||||
void SetOFlag(const U1& value);
|
void SetOFlag(const U1& value);
|
||||||
|
|
||||||
|
[[nodiscard]] U1 GetFCSMFlag();
|
||||||
|
[[nodiscard]] U1 GetTAFlag();
|
||||||
|
[[nodiscard]] U1 GetTRFlag();
|
||||||
|
[[nodiscard]] U1 GetMXFlag();
|
||||||
|
|
||||||
|
void SetFCSMFlag(const U1& value);
|
||||||
|
void SetTAFlag(const U1& value);
|
||||||
|
void SetTRFlag(const U1& value);
|
||||||
|
void SetMXFlag(const U1& value);
|
||||||
|
|
||||||
[[nodiscard]] U1 Condition(IR::Condition cond);
|
[[nodiscard]] U1 Condition(IR::Condition cond);
|
||||||
[[nodiscard]] U1 GetFlowTestResult(FlowTest test);
|
[[nodiscard]] U1 GetFlowTestResult(FlowTest test);
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,18 @@ OPCODE(GetZFlag, U1, Void
|
||||||
OPCODE(GetSFlag, U1, Void, )
|
OPCODE(GetSFlag, U1, Void, )
|
||||||
OPCODE(GetCFlag, U1, Void, )
|
OPCODE(GetCFlag, U1, Void, )
|
||||||
OPCODE(GetOFlag, U1, Void, )
|
OPCODE(GetOFlag, U1, Void, )
|
||||||
|
OPCODE(GetFCSMFlag, U1, Void, )
|
||||||
|
OPCODE(GetTAFlag, U1, Void, )
|
||||||
|
OPCODE(GetTRFlag, U1, Void, )
|
||||||
|
OPCODE(GetMXFlag, U1, Void, )
|
||||||
OPCODE(SetZFlag, Void, U1, )
|
OPCODE(SetZFlag, Void, U1, )
|
||||||
OPCODE(SetSFlag, Void, U1, )
|
OPCODE(SetSFlag, Void, U1, )
|
||||||
OPCODE(SetCFlag, Void, U1, )
|
OPCODE(SetCFlag, Void, U1, )
|
||||||
OPCODE(SetOFlag, Void, U1, )
|
OPCODE(SetOFlag, Void, U1, )
|
||||||
|
OPCODE(SetFCSMFlag, Void, U1, )
|
||||||
|
OPCODE(SetTAFlag, Void, U1, )
|
||||||
|
OPCODE(SetTRFlag, Void, U1, )
|
||||||
|
OPCODE(SetMXFlag, Void, U1, )
|
||||||
OPCODE(WorkgroupId, U32x3, )
|
OPCODE(WorkgroupId, U32x3, )
|
||||||
OPCODE(LocalInvocationId, U32x3, )
|
OPCODE(LocalInvocationId, U32x3, )
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,10 @@ void TranslatorVisitor::VOTE(u64 insn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TranslatorVisitor::VOTE_vtg(u64) {
|
void TranslatorVisitor::VOTE_vtg(u64) {
|
||||||
// Stub
|
// LOG_WARNING("VOTE.VTG: Stubbed!");
|
||||||
|
auto imm = ir.Imm1(false);
|
||||||
|
ir.SetFCSMFlag(imm);
|
||||||
|
ir.SetTRFlag(imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Shader::Maxwell
|
} // namespace Shader::Maxwell
|
||||||
|
|
|
@ -38,6 +38,10 @@ struct ZeroFlagTag : FlagTag {};
|
||||||
struct SignFlagTag : FlagTag {};
|
struct SignFlagTag : FlagTag {};
|
||||||
struct CarryFlagTag : FlagTag {};
|
struct CarryFlagTag : FlagTag {};
|
||||||
struct OverflowFlagTag : FlagTag {};
|
struct OverflowFlagTag : FlagTag {};
|
||||||
|
struct FCSMFlagTag : FlagTag {};
|
||||||
|
struct TAFlagTag : FlagTag {};
|
||||||
|
struct TRFlagTag : FlagTag {};
|
||||||
|
struct MXFlagTag : FlagTag {};
|
||||||
|
|
||||||
struct GotoVariable : FlagTag {
|
struct GotoVariable : FlagTag {
|
||||||
GotoVariable() = default;
|
GotoVariable() = default;
|
||||||
|
@ -53,7 +57,8 @@ struct IndirectBranchVariable {
|
||||||
};
|
};
|
||||||
|
|
||||||
using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
|
using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag,
|
||||||
OverflowFlagTag, GotoVariable, IndirectBranchVariable>;
|
OverflowFlagTag, FCSMFlagTag, TAFlagTag, TRFlagTag, MXFlagTag,
|
||||||
|
GotoVariable, IndirectBranchVariable>;
|
||||||
using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
|
using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>;
|
||||||
|
|
||||||
struct DefTable {
|
struct DefTable {
|
||||||
|
@ -89,6 +94,22 @@ struct DefTable {
|
||||||
return overflow_flag;
|
return overflow_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ValueMap& operator[](FCSMFlagTag) noexcept {
|
||||||
|
return fcsm_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ValueMap& operator[](TAFlagTag) noexcept {
|
||||||
|
return ta_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ValueMap& operator[](TRFlagTag) noexcept {
|
||||||
|
return tr_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] ValueMap& operator[](MXFlagTag) noexcept {
|
||||||
|
return mr_flag;
|
||||||
|
}
|
||||||
|
|
||||||
std::array<ValueMap, IR::NUM_USER_REGS> regs;
|
std::array<ValueMap, IR::NUM_USER_REGS> regs;
|
||||||
std::array<ValueMap, IR::NUM_USER_PREDS> preds;
|
std::array<ValueMap, IR::NUM_USER_PREDS> preds;
|
||||||
boost::container::flat_map<u32, ValueMap> goto_vars;
|
boost::container::flat_map<u32, ValueMap> goto_vars;
|
||||||
|
@ -97,6 +118,10 @@ struct DefTable {
|
||||||
ValueMap sign_flag;
|
ValueMap sign_flag;
|
||||||
ValueMap carry_flag;
|
ValueMap carry_flag;
|
||||||
ValueMap overflow_flag;
|
ValueMap overflow_flag;
|
||||||
|
ValueMap fcsm_flag;
|
||||||
|
ValueMap ta_flag;
|
||||||
|
ValueMap tr_flag;
|
||||||
|
ValueMap mr_flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
IR::Opcode UndefOpcode(IR::Reg) noexcept {
|
IR::Opcode UndefOpcode(IR::Reg) noexcept {
|
||||||
|
@ -247,6 +272,18 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
|
||||||
case IR::Opcode::SetOFlag:
|
case IR::Opcode::SetOFlag:
|
||||||
pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0));
|
pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0));
|
||||||
break;
|
break;
|
||||||
|
case IR::Opcode::SetFCSMFlag:
|
||||||
|
pass.WriteVariable(FCSMFlagTag{}, block, inst.Arg(0));
|
||||||
|
break;
|
||||||
|
case IR::Opcode::SetTAFlag:
|
||||||
|
pass.WriteVariable(TAFlagTag{}, block, inst.Arg(0));
|
||||||
|
break;
|
||||||
|
case IR::Opcode::SetTRFlag:
|
||||||
|
pass.WriteVariable(TRFlagTag{}, block, inst.Arg(0));
|
||||||
|
break;
|
||||||
|
case IR::Opcode::SetMXFlag:
|
||||||
|
pass.WriteVariable(MXFlagTag{}, block, inst.Arg(0));
|
||||||
|
break;
|
||||||
case IR::Opcode::GetRegister:
|
case IR::Opcode::GetRegister:
|
||||||
if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) {
|
if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) {
|
||||||
inst.ReplaceUsesWith(pass.ReadVariable(reg, block));
|
inst.ReplaceUsesWith(pass.ReadVariable(reg, block));
|
||||||
|
@ -275,6 +312,18 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) {
|
||||||
case IR::Opcode::GetOFlag:
|
case IR::Opcode::GetOFlag:
|
||||||
inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block));
|
inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block));
|
||||||
break;
|
break;
|
||||||
|
case IR::Opcode::GetFCSMFlag:
|
||||||
|
inst.ReplaceUsesWith(pass.ReadVariable(FCSMFlagTag{}, block));
|
||||||
|
break;
|
||||||
|
case IR::Opcode::GetTAFlag:
|
||||||
|
inst.ReplaceUsesWith(pass.ReadVariable(TAFlagTag{}, block));
|
||||||
|
break;
|
||||||
|
case IR::Opcode::GetTRFlag:
|
||||||
|
inst.ReplaceUsesWith(pass.ReadVariable(TRFlagTag{}, block));
|
||||||
|
break;
|
||||||
|
case IR::Opcode::GetMXFlag:
|
||||||
|
inst.ReplaceUsesWith(pass.ReadVariable(MXFlagTag{}, block));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue