mirror of
				https://git.h3cjp.net/H3cJP/citra.git
				synced 2025-10-31 15:04:53 +00:00 
			
		
		
		
	shader: Implement R2P
This commit is contained in:
		
							parent
							
								
									924f0a9149
								
							
						
					
					
						commit
						7d6ba5b984
					
				|  | @ -94,6 +94,7 @@ add_library(shader_recompiler STATIC | |||
|     frontend/maxwell/translate/impl/logic_operation_three_input.cpp | ||||
|     frontend/maxwell/translate/impl/move_predicate_to_register.cpp | ||||
|     frontend/maxwell/translate/impl/move_register.cpp | ||||
|     frontend/maxwell/translate/impl/move_register_to_predicate.cpp | ||||
|     frontend/maxwell/translate/impl/move_special_register.cpp | ||||
|     frontend/maxwell/translate/impl/not_implemented.cpp | ||||
|     frontend/maxwell/translate/impl/predicate_set_predicate.cpp | ||||
|  |  | |||
|  | @ -120,6 +120,7 @@ void EmitCompositeExtractF64x4(EmitContext& ctx); | |||
| Id EmitCompositeInsertF64x2(EmitContext& ctx, Id composite, Id object, u32 index); | ||||
| Id EmitCompositeInsertF64x3(EmitContext& ctx, Id composite, Id object, u32 index); | ||||
| Id EmitCompositeInsertF64x4(EmitContext& ctx, Id composite, Id object, u32 index); | ||||
| Id EmitSelectU1(EmitContext& ctx, Id cond, Id true_value, Id false_value); | ||||
| Id EmitSelectU8(EmitContext& ctx, Id cond, Id true_value, Id false_value); | ||||
| Id EmitSelectU16(EmitContext& ctx, Id cond, Id true_value, Id false_value); | ||||
| Id EmitSelectU32(EmitContext& ctx, Id cond, Id true_value, Id false_value); | ||||
|  | @ -242,7 +243,7 @@ Id EmitBitwiseOr32(EmitContext& ctx, Id a, Id b); | |||
| Id EmitBitwiseXor32(EmitContext& ctx, Id a, Id b); | ||||
| Id EmitBitFieldInsert(EmitContext& ctx, Id base, Id insert, Id offset, Id count); | ||||
| Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count); | ||||
| Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count); | ||||
| Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count); | ||||
| Id EmitBitReverse32(EmitContext& ctx, Id value); | ||||
| Id EmitBitCount32(EmitContext& ctx, Id value); | ||||
| Id EmitBitwiseNot32(EmitContext& ctx, Id value); | ||||
|  |  | |||
|  | @ -114,8 +114,13 @@ Id EmitBitFieldSExtract(EmitContext& ctx, Id base, Id offset, Id count) { | |||
|     return ctx.OpBitFieldSExtract(ctx.U32[1], base, offset, count); | ||||
| } | ||||
| 
 | ||||
| Id EmitBitFieldUExtract(EmitContext& ctx, Id base, Id offset, Id count) { | ||||
|     return ctx.OpBitFieldUExtract(ctx.U32[1], base, offset, count); | ||||
| Id EmitBitFieldUExtract(EmitContext& ctx, IR::Inst* inst, Id base, Id offset, Id count) { | ||||
|     const Id result{ctx.OpBitFieldUExtract(ctx.U32[1], base, offset, count)}; | ||||
|     if (IR::Inst* const zero{inst->GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp)}) { | ||||
|         zero->SetDefinition(ctx.OpIEqual(ctx.U1, result, ctx.u32_zero_value)); | ||||
|         zero->Invalidate(); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| Id EmitBitReverse32(EmitContext& ctx, Id value) { | ||||
|  |  | |||
|  | @ -6,6 +6,10 @@ | |||
| 
 | ||||
| namespace Shader::Backend::SPIRV { | ||||
| 
 | ||||
| Id EmitSelectU1(EmitContext& ctx, Id cond, Id true_value, Id false_value) { | ||||
|     return ctx.OpSelect(ctx.U1, cond, true_value, false_value); | ||||
| } | ||||
| 
 | ||||
| Id EmitSelectU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Id cond, | ||||
|                 [[maybe_unused]] Id true_value, [[maybe_unused]] Id false_value) { | ||||
|     throw NotImplementedException("SPIR-V Instruction"); | ||||
|  |  | |||
|  | @ -412,6 +412,8 @@ Value IREmitter::Select(const U1& condition, const Value& true_value, const Valu | |||
|         throw InvalidArgument("Mismatching types {} and {}", true_value.Type(), false_value.Type()); | ||||
|     } | ||||
|     switch (true_value.Type()) { | ||||
|     case Type::U1: | ||||
|         return Inst(Opcode::SelectU1, condition, true_value, false_value); | ||||
|     case Type::U8: | ||||
|         return Inst(Opcode::SelectU8, condition, true_value, false_value); | ||||
|     case Type::U16: | ||||
|  |  | |||
|  | @ -115,6 +115,7 @@ OPCODE(CompositeInsertF64x3,                                F64x3,          F64x | |||
| OPCODE(CompositeInsertF64x4,                                F64x4,          F64x4,          F64,            U32,                            ) | ||||
| 
 | ||||
| // Select operations
 | ||||
| OPCODE(SelectU1,                                            U1,             U1,             U1,             U1,                             ) | ||||
| OPCODE(SelectU8,                                            U8,             U1,             U8,             U8,                             ) | ||||
| OPCODE(SelectU16,                                           U16,            U1,             U16,            U16,                            ) | ||||
| OPCODE(SelectU32,                                           U32,            U1,             U32,            U32,                            ) | ||||
|  |  | |||
|  | @ -0,0 +1,71 @@ | |||
| // Copyright 2021 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/bit_field.h" | ||||
| #include "shader_recompiler/exception.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||||
| 
 | ||||
| namespace Shader::Maxwell { | ||||
| namespace { | ||||
| enum class Mode : u64 { | ||||
|     PR, | ||||
|     CC, | ||||
| }; | ||||
| 
 | ||||
| void SetFlag(IR::IREmitter& ir, const IR::U1& inv_mask_bit, const IR::U1& src_bit, u32 index) { | ||||
|     switch (index) { | ||||
|     case 0: | ||||
|         return ir.SetZFlag(IR::U1{ir.Select(inv_mask_bit, ir.GetZFlag(), src_bit)}); | ||||
|     case 1: | ||||
|         return ir.SetSFlag(IR::U1{ir.Select(inv_mask_bit, ir.GetSFlag(), src_bit)}); | ||||
|     case 2: | ||||
|         return ir.SetCFlag(IR::U1{ir.Select(inv_mask_bit, ir.GetCFlag(), src_bit)}); | ||||
|     case 3: | ||||
|         return ir.SetOFlag(IR::U1{ir.Select(inv_mask_bit, ir.GetOFlag(), src_bit)}); | ||||
|     default: | ||||
|         throw LogicError("Unreachable R2P index"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void R2P(TranslatorVisitor& v, u64 insn, const IR::U32& mask) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<8, 8, IR::Reg> src_reg; | ||||
|         BitField<40, 1, Mode> mode; | ||||
|         BitField<41, 2, u64> byte_selector; | ||||
|     } const r2p{insn}; | ||||
|     const IR::U32 src{v.X(r2p.src_reg)}; | ||||
|     const IR::U32 count{v.ir.Imm32(1)}; | ||||
|     const bool pr_mode{r2p.mode == Mode::PR}; | ||||
|     const u32 num_items{pr_mode ? 7U : 4U}; | ||||
|     const u32 offset_base{static_cast<u32>(r2p.byte_selector) * 8}; | ||||
|     for (u32 index = 0; index < num_items; ++index) { | ||||
|         const IR::U32 offset{v.ir.Imm32(offset_base + index)}; | ||||
|         const IR::U1 src_zero{v.ir.GetZeroFromOp(v.ir.BitFieldExtract(src, offset, count, false))}; | ||||
|         const IR::U1 src_bit{v.ir.LogicalNot(src_zero)}; | ||||
|         const IR::U32 mask_bfe{v.ir.BitFieldExtract(mask, v.ir.Imm32(index), count, false)}; | ||||
|         const IR::U1 inv_mask_bit{v.ir.GetZeroFromOp(mask_bfe)}; | ||||
|         if (pr_mode) { | ||||
|             const IR::Pred pred{index}; | ||||
|             v.ir.SetPred(pred, IR::U1{v.ir.Select(inv_mask_bit, v.ir.GetPred(pred), src_bit)}); | ||||
|         } else { | ||||
|             SetFlag(v.ir, inv_mask_bit, src_bit, index); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| void TranslatorVisitor::R2P_reg(u64 insn) { | ||||
|     R2P(*this, insn, GetReg20(insn)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::R2P_cbuf(u64 insn) { | ||||
|     R2P(*this, insn, GetCbuf(insn)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::R2P_imm(u64 insn) { | ||||
|     R2P(*this, insn, GetImm20(insn)); | ||||
| } | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  | @ -513,18 +513,6 @@ void TranslatorVisitor::R2B(u64) { | |||
|     ThrowNotImplemented(Opcode::R2B); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::R2P_reg(u64) { | ||||
|     ThrowNotImplemented(Opcode::R2P_reg); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::R2P_cbuf(u64) { | ||||
|     ThrowNotImplemented(Opcode::R2P_cbuf); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::R2P_imm(u64) { | ||||
|     ThrowNotImplemented(Opcode::R2P_imm); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::RAM(u64) { | ||||
|     ThrowNotImplemented(Opcode::RAM); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue