mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Pica/VertexShader: Fix a bug in the bitfield definitions and add the "negate" field for swizzlers.
This commit is contained in:
		
							parent
							
								
									26ade98411
								
							
						
					
					
						commit
						62c36a4ef0
					
				
					 2 changed files with 92 additions and 14 deletions
				
			
		|  | @ -65,26 +65,32 @@ static void ProcessShaderCode(VertexShaderState& state) { | |||
|         const Instruction& instr = *(const Instruction*)state.program_counter; | ||||
|         state.debug.max_offset = std::max<u32>(state.debug.max_offset, 1 + (state.program_counter - shader_memory)); | ||||
| 
 | ||||
|         const float24* src1_ = (instr.common.src1 < 0x10) ? state.input_register_table[instr.common.src1] | ||||
|                              : (instr.common.src1 < 0x20) ? &state.temporary_registers[instr.common.src1-0x10].x | ||||
|                              : (instr.common.src1 < 0x80) ? &shader_uniforms.f[instr.common.src1-0x20].x | ||||
|         const float24* src1_ = (instr.common.src1 < 0x10) ? state.input_register_table[instr.common.src1.GetIndex()] | ||||
|                              : (instr.common.src1 < 0x20) ? &state.temporary_registers[instr.common.src1.GetIndex()].x | ||||
|                              : (instr.common.src1 < 0x80) ? &shader_uniforms.f[instr.common.src1.GetIndex()].x | ||||
|                              : nullptr; | ||||
|         const float24* src2_ = (instr.common.src2 < 0x10) ? state.input_register_table[instr.common.src2] | ||||
|                              : &state.temporary_registers[instr.common.src2-0x10].x; | ||||
|         // TODO: Unsure about the limit values
 | ||||
|         float24* dest = (instr.common.dest <= 0x1C) ? state.output_register_table[instr.common.dest] | ||||
|                              : (instr.common.dest <= 0x3C) ? nullptr | ||||
|                              : (instr.common.dest <= 0x7C) ? &state.temporary_registers[(instr.common.dest-0x40)/4][instr.common.dest%4] | ||||
|         const float24* src2_ = (instr.common.src2 < 0x10) ? state.input_register_table[instr.common.src2.GetIndex()] | ||||
|                              : &state.temporary_registers[instr.common.src2.GetIndex()].x; | ||||
|         float24* dest = (instr.common.dest < 0x08) ? state.output_register_table[4*instr.common.dest.GetIndex()] | ||||
|                       : (instr.common.dest < 0x10) ? nullptr | ||||
|                       : (instr.common.dest < 0x20) ? &state.temporary_registers[instr.common.dest.GetIndex()][0] | ||||
|                       : nullptr; | ||||
| 
 | ||||
|         const SwizzlePattern& swizzle = *(SwizzlePattern*)&swizzle_data[instr.common.operand_desc_id]; | ||||
|         const bool negate_src1 = swizzle.negate; | ||||
| 
 | ||||
|         const float24 src1[4] = { | ||||
|         float24 src1[4] = { | ||||
|             src1_[(int)swizzle.GetSelectorSrc1(0)], | ||||
|             src1_[(int)swizzle.GetSelectorSrc1(1)], | ||||
|             src1_[(int)swizzle.GetSelectorSrc1(2)], | ||||
|             src1_[(int)swizzle.GetSelectorSrc1(3)], | ||||
|         }; | ||||
|         if (negate_src1) { | ||||
|             src1[0] = src1[0] * float24::FromFloat32(-1); | ||||
|             src1[1] = src1[1] * float24::FromFloat32(-1); | ||||
|             src1[2] = src1[2] * float24::FromFloat32(-1); | ||||
|             src1[3] = src1[3] * float24::FromFloat32(-1); | ||||
|         } | ||||
|         const float24 src2[4] = { | ||||
|             src2_[(int)swizzle.GetSelectorSrc2(0)], | ||||
|             src2_[(int)swizzle.GetSelectorSrc2(1)], | ||||
|  |  | |||
|  | @ -117,9 +117,78 @@ union Instruction { | |||
|     // while "dest" addresses individual floats.
 | ||||
|     union { | ||||
|         BitField<0x00, 0x5, u32> operand_desc_id; | ||||
|         BitField<0x07, 0x5, u32> src2; | ||||
|         BitField<0x0c, 0x7, u32> src1; | ||||
|         BitField<0x13, 0x7, u32> dest; | ||||
| 
 | ||||
|         template<class BitFieldType> | ||||
|         struct SourceRegister : BitFieldType { | ||||
|             enum RegisterType { | ||||
|                 Input, | ||||
|                 Temporary, | ||||
|                 FloatUniform | ||||
|             }; | ||||
| 
 | ||||
|             RegisterType GetRegisterType() const { | ||||
|                 if (BitFieldType::Value() < 0x10) | ||||
|                     return Input; | ||||
|                 else if (BitFieldType::Value() < 0x20) | ||||
|                     return Temporary; | ||||
|                 else | ||||
|                     return FloatUniform; | ||||
|             } | ||||
| 
 | ||||
|             int GetIndex() const { | ||||
|                 if (GetRegisterType() == Input) | ||||
|                     return BitFieldType::Value(); | ||||
|                 else if (GetRegisterType() == Temporary) | ||||
|                     return BitFieldType::Value() - 0x10; | ||||
|                 else if (GetRegisterType() == FloatUniform) | ||||
|                     return BitFieldType::Value() - 0x20; | ||||
|             } | ||||
| 
 | ||||
|             std::string GetRegisterName() const { | ||||
|                 std::map<RegisterType, std::string> type = { | ||||
|                     { Input, "i" }, | ||||
|                     { Temporary, "t" }, | ||||
|                     { FloatUniform, "f" }, | ||||
|                 }; | ||||
|                 return type[GetRegisterType()] + std::to_string(GetIndex()); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         SourceRegister<BitField<0x07, 0x5, u32>> src2; | ||||
|         SourceRegister<BitField<0x0c, 0x7, u32>> src1; | ||||
| 
 | ||||
|         struct : BitField<0x15, 0x5, u32> | ||||
|         { | ||||
|             enum RegisterType { | ||||
|                 Output, | ||||
|                 Temporary, | ||||
|                 Unknown | ||||
|             }; | ||||
|             RegisterType GetRegisterType() const { | ||||
|                 if (Value() < 0x8) | ||||
|                     return Output; | ||||
|                 else if (Value() < 0x10) | ||||
|                     return Unknown; | ||||
|                 else | ||||
|                     return Temporary; | ||||
|             } | ||||
|             int GetIndex() const { | ||||
|                 if (GetRegisterType() == Output) | ||||
|                     return Value(); | ||||
|                 else if (GetRegisterType() == Temporary) | ||||
|                     return Value() - 0x10; | ||||
|                 else | ||||
|                     return Value(); | ||||
|             } | ||||
|             std::string GetRegisterName() const { | ||||
|                 std::map<RegisterType, std::string> type = { | ||||
|                     { Output, "o" }, | ||||
|                     { Temporary, "t" }, | ||||
|                     { Unknown, "u" } | ||||
|                 }; | ||||
|                 return type[GetRegisterType()] + std::to_string(GetIndex()); | ||||
|             } | ||||
|         } dest; | ||||
|     } common; | ||||
| 
 | ||||
|     // Format used for flow control instructions ("if")
 | ||||
|  | @ -128,6 +197,7 @@ union Instruction { | |||
|         BitField<0x0a, 0xc, u32> offset_words; | ||||
|     } flow_control; | ||||
| }; | ||||
| static_assert(std::is_standard_layout<Instruction>::value, "Structure is not using standard layout!"); | ||||
| 
 | ||||
| union SwizzlePattern { | ||||
|     u32 hex; | ||||
|  | @ -185,6 +255,8 @@ union SwizzlePattern { | |||
|     // Components of "dest" that should be written to: LSB=dest.w, MSB=dest.x
 | ||||
|     BitField< 0, 4, u32> dest_mask; | ||||
| 
 | ||||
|     BitField< 4, 1, u32> negate; // negates src1
 | ||||
| 
 | ||||
|     BitField< 5, 2, Selector> src1_selector_3; | ||||
|     BitField< 7, 2, Selector> src1_selector_2; | ||||
|     BitField< 9, 2, Selector> src1_selector_1; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue