From e1fea1e0c594cc7c5a404e7006a4b4b2f29200ae Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Mon, 24 Dec 2018 02:24:38 -0300 Subject: video_core: Implement IR based geometry shaders --- src/video_core/shader/decode/other.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/video_core/shader/decode/other.cpp') diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp index 9630ef831..1918762b8 100644 --- a/src/video_core/shader/decode/other.cpp +++ b/src/video_core/shader/decode/other.cpp @@ -12,6 +12,7 @@ namespace VideoCommon::Shader { using Tegra::Shader::ConditionCode; using Tegra::Shader::Instruction; using Tegra::Shader::OpCode; +using Tegra::Shader::Register; u32 ShaderIR::DecodeOther(BasicBlock& bb, u32 pc) { const Instruction instr = {program_code[pc]}; @@ -140,6 +141,30 @@ u32 ShaderIR::DecodeOther(BasicBlock& bb, u32 pc) { SetRegister(bb, instr.gpr0, value); break; } + case OpCode::Id::OUT_R: { + UNIMPLEMENTED_IF_MSG(instr.gpr20.Value() != Register::ZeroIndex, + "Stream buffer is not supported"); + + if (instr.out.emit) { + // gpr0 is used to store the next address and gpr8 contains the address to emit. + // Hardware uses pointers here but we just ignore it + bb.push_back(Operation(OperationCode::EmitVertex)); + SetRegister(bb, instr.gpr0, Immediate(0)); + } + if (instr.out.cut) { + bb.push_back(Operation(OperationCode::EndPrimitive)); + } + break; + } + case OpCode::Id::ISBERD: { + UNIMPLEMENTED_IF(instr.isberd.o != 0); + UNIMPLEMENTED_IF(instr.isberd.skew != 0); + UNIMPLEMENTED_IF(instr.isberd.shift != Tegra::Shader::IsberdShift::None); + UNIMPLEMENTED_IF(instr.isberd.mode != Tegra::Shader::IsberdMode::None); + LOG_WARNING(HW_GPU, "ISBERD instruction is incomplete"); + SetRegister(bb, instr.gpr0, GetRegister(instr.gpr8)); + break; + } case OpCode::Id::DEPBAR: { LOG_WARNING(HW_GPU, "DEPBAR instruction is stubbed"); break; -- cgit v1.2.3