forked from eden-emu/eden
		
	shader: Add partial rasterizer integration
This commit is contained in:
		
							parent
							
								
									72990df7ba
								
							
						
					
					
						commit
						260743f371
					
				
					 54 changed files with 1929 additions and 568 deletions
				
			
		|  | @ -1,15 +0,0 @@ | |||
| // Copyright 2021 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "shader_recompiler/exception.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||||
| 
 | ||||
| namespace Shader::Maxwell { | ||||
| 
 | ||||
| void TranslatorVisitor::EXIT(u64) { | ||||
|     ir.Exit(); | ||||
| } | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  | @ -0,0 +1,43 @@ | |||
| // Copyright 2021 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "shader_recompiler/exception.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||||
| 
 | ||||
| namespace Shader::Maxwell { | ||||
| namespace { | ||||
| void ExitFragment(TranslatorVisitor& v) { | ||||
|     const ProgramHeader sph{v.env.SPH()}; | ||||
|     IR::Reg src_reg{IR::Reg::R0}; | ||||
|     for (u32 render_target = 0; render_target < 8; ++render_target) { | ||||
|         const std::array<bool, 4> mask{sph.ps.EnabledOutputComponents(render_target)}; | ||||
|         for (u32 component = 0; component < 4; ++component) { | ||||
|             if (!mask[component]) { | ||||
|                 continue; | ||||
|             } | ||||
|             v.ir.SetFragColor(render_target, component, v.F(src_reg)); | ||||
|             ++src_reg; | ||||
|         } | ||||
|     } | ||||
|     if (sph.ps.omap.sample_mask != 0) { | ||||
|         throw NotImplementedException("Sample mask"); | ||||
|     } | ||||
|     if (sph.ps.omap.depth != 0) { | ||||
|         throw NotImplementedException("Fragment depth"); | ||||
|     } | ||||
| } | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| void TranslatorVisitor::EXIT() { | ||||
|     switch (env.ShaderStage()) { | ||||
|     case Stage::Fragment: | ||||
|         ExitFragment(*this); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  | @ -108,7 +108,7 @@ public: | |||
|     void DSETP_reg(u64 insn); | ||||
|     void DSETP_cbuf(u64 insn); | ||||
|     void DSETP_imm(u64 insn); | ||||
|     void EXIT(u64 insn); | ||||
|     void EXIT(); | ||||
|     void F2F_reg(u64 insn); | ||||
|     void F2F_cbuf(u64 insn); | ||||
|     void F2F_imm(u64 insn); | ||||
|  | @ -220,7 +220,7 @@ public: | |||
|     void JCAL(u64 insn); | ||||
|     void JMP(u64 insn); | ||||
|     void JMX(u64 insn); | ||||
|     void KIL(u64 insn); | ||||
|     void KIL(); | ||||
|     void LD(u64 insn); | ||||
|     void LDC(u64 insn); | ||||
|     void LDG(u64 insn); | ||||
|  |  | |||
|  | @ -11,6 +11,13 @@ | |||
| 
 | ||||
| namespace Shader::Maxwell { | ||||
| namespace { | ||||
| enum class Size : u64 { | ||||
|     B32, | ||||
|     B64, | ||||
|     B96, | ||||
|     B128, | ||||
| }; | ||||
| 
 | ||||
| enum class InterpolationMode : u64 { | ||||
|     Pass, | ||||
|     Multiply, | ||||
|  | @ -23,8 +30,85 @@ enum class SampleMode : u64 { | |||
|     Centroid, | ||||
|     Offset, | ||||
| }; | ||||
| 
 | ||||
| int NumElements(Size size) { | ||||
|     switch (size) { | ||||
|     case Size::B32: | ||||
|         return 1; | ||||
|     case Size::B64: | ||||
|         return 2; | ||||
|     case Size::B96: | ||||
|         return 3; | ||||
|     case Size::B128: | ||||
|         return 4; | ||||
|     } | ||||
|     throw InvalidArgument("Invalid size {}", size); | ||||
| } | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| void TranslatorVisitor::ALD(u64 insn) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<0, 8, IR::Reg> dest_reg; | ||||
|         BitField<8, 8, IR::Reg> index_reg; | ||||
|         BitField<20, 10, u64> absolute_offset; | ||||
|         BitField<20, 11, s64> relative_offset; | ||||
|         BitField<39, 8, IR::Reg> stream_reg; | ||||
|         BitField<32, 1, u64> o; | ||||
|         BitField<31, 1, u64> patch; | ||||
|         BitField<47, 2, Size> size; | ||||
|     } const ald{insn}; | ||||
| 
 | ||||
|     if (ald.o != 0) { | ||||
|         throw NotImplementedException("O"); | ||||
|     } | ||||
|     if (ald.patch != 0) { | ||||
|         throw NotImplementedException("P"); | ||||
|     } | ||||
|     if (ald.index_reg != IR::Reg::RZ) { | ||||
|         throw NotImplementedException("Indexed"); | ||||
|     } | ||||
|     const u64 offset{ald.absolute_offset.Value()}; | ||||
|     if (offset % 4 != 0) { | ||||
|         throw NotImplementedException("Unaligned absolute offset {}", offset); | ||||
|     } | ||||
|     const int num_elements{NumElements(ald.size)}; | ||||
|     for (int element = 0; element < num_elements; ++element) { | ||||
|         F(ald.dest_reg + element, ir.GetAttribute(IR::Attribute{offset / 4 + element})); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::AST(u64 insn) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<0, 8, IR::Reg> src_reg; | ||||
|         BitField<8, 8, IR::Reg> index_reg; | ||||
|         BitField<20, 10, u64> absolute_offset; | ||||
|         BitField<20, 11, s64> relative_offset; | ||||
|         BitField<31, 1, u64> patch; | ||||
|         BitField<39, 8, IR::Reg> stream_reg; | ||||
|         BitField<47, 2, Size> size; | ||||
|     } const ast{insn}; | ||||
| 
 | ||||
|     if (ast.patch != 0) { | ||||
|         throw NotImplementedException("P"); | ||||
|     } | ||||
|     if (ast.stream_reg != IR::Reg::RZ) { | ||||
|         throw NotImplementedException("Stream store"); | ||||
|     } | ||||
|     if (ast.index_reg != IR::Reg::RZ) { | ||||
|         throw NotImplementedException("Indexed store"); | ||||
|     } | ||||
|     const u64 offset{ast.absolute_offset.Value()}; | ||||
|     if (offset % 4 != 0) { | ||||
|         throw NotImplementedException("Unaligned absolute offset {}", offset); | ||||
|     } | ||||
|     const int num_elements{NumElements(ast.size)}; | ||||
|     for (int element = 0; element < num_elements; ++element) { | ||||
|         ir.SetAttribute(IR::Attribute{offset / 4 + element}, F(ast.src_reg + element)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::IPA(u64 insn) { | ||||
|     // IPA is the instruction used to read varyings from a fragment shader.
 | ||||
|     // gl_FragCoord is mapped to the gl_Position attribute.
 | ||||
|  | @ -51,7 +135,7 @@ void TranslatorVisitor::IPA(u64 insn) { | |||
|     // }
 | ||||
|     const bool is_indexed{ipa.idx != 0 && ipa.index_reg != IR::Reg::RZ}; | ||||
|     if (is_indexed) { | ||||
|         throw NotImplementedException("IPA.IDX"); | ||||
|         throw NotImplementedException("IDX"); | ||||
|     } | ||||
| 
 | ||||
|     const IR::Attribute attribute{ipa.attribute}; | ||||
|  |  | |||
|  | @ -17,14 +17,6 @@ void TranslatorVisitor::AL2P(u64) { | |||
|     ThrowNotImplemented(Opcode::AL2P); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::ALD(u64) { | ||||
|     ThrowNotImplemented(Opcode::ALD); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::AST(u64) { | ||||
|     ThrowNotImplemented(Opcode::AST); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::ATOM_cas(u64) { | ||||
|     ThrowNotImplemented(Opcode::ATOM_cas); | ||||
| } | ||||
|  | @ -153,10 +145,6 @@ void TranslatorVisitor::DSETP_imm(u64) { | |||
|     ThrowNotImplemented(Opcode::DSETP_imm); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::EXIT(u64) { | ||||
|     throw LogicError("Visting EXIT instruction"); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::F2F_reg(u64) { | ||||
|     ThrowNotImplemented(Opcode::F2F_reg); | ||||
| } | ||||
|  | @ -345,8 +333,8 @@ void TranslatorVisitor::JMX(u64) { | |||
|     ThrowNotImplemented(Opcode::JMX); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::KIL(u64) { | ||||
|     ThrowNotImplemented(Opcode::KIL); | ||||
| void TranslatorVisitor::KIL() { | ||||
|     // KIL is a no-op
 | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::LD(u64) { | ||||
|  |  | |||
|  | @ -215,7 +215,7 @@ void TranslatorVisitor::TEX(u64 insn) { | |||
|         BitField<36, 13, u64> cbuf_offset; | ||||
|     } const tex{insn}; | ||||
| 
 | ||||
|     Impl(*this, insn, tex.aoffi != 0, tex.blod, tex.lc != 0, static_cast<u32>(tex.cbuf_offset)); | ||||
|     Impl(*this, insn, tex.aoffi != 0, tex.blod, tex.lc != 0, static_cast<u32>(tex.cbuf_offset * 4)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::TEX_b(u64 insn) { | ||||
|  |  | |||
|  | @ -70,7 +70,7 @@ IR::F32 ReadArray(TranslatorVisitor& v, const IR::U32& value) { | |||
| 
 | ||||
| IR::Value Sample(TranslatorVisitor& v, u64 insn) { | ||||
|     const Encoding texs{insn}; | ||||
|     const IR::U32 handle{v.ir.Imm32(static_cast<u32>(texs.cbuf_offset))}; | ||||
|     const IR::U32 handle{v.ir.Imm32(static_cast<u32>(texs.cbuf_offset * 4))}; | ||||
|     const IR::F32 zero{v.ir.Imm32(0.0f)}; | ||||
|     const IR::Reg reg_a{texs.src_reg_a}; | ||||
|     const IR::Reg reg_b{texs.src_reg_b}; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ReinUsesLisp
						ReinUsesLisp