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; |         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)); |         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] |         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-0x10].x |                              : (instr.common.src1 < 0x20) ? &state.temporary_registers[instr.common.src1.GetIndex()].x | ||||||
|                              : (instr.common.src1 < 0x80) ? &shader_uniforms.f[instr.common.src1-0x20].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] |  | ||||||
|                              : nullptr; |                              : nullptr; | ||||||
|  |         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 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(0)], | ||||||
|             src1_[(int)swizzle.GetSelectorSrc1(1)], |             src1_[(int)swizzle.GetSelectorSrc1(1)], | ||||||
|             src1_[(int)swizzle.GetSelectorSrc1(2)], |             src1_[(int)swizzle.GetSelectorSrc1(2)], | ||||||
|             src1_[(int)swizzle.GetSelectorSrc1(3)], |             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] = { |         const float24 src2[4] = { | ||||||
|             src2_[(int)swizzle.GetSelectorSrc2(0)], |             src2_[(int)swizzle.GetSelectorSrc2(0)], | ||||||
|             src2_[(int)swizzle.GetSelectorSrc2(1)], |             src2_[(int)swizzle.GetSelectorSrc2(1)], | ||||||
|  |  | ||||||
|  | @ -117,9 +117,78 @@ union Instruction { | ||||||
|     // while "dest" addresses individual floats.
 |     // while "dest" addresses individual floats.
 | ||||||
|     union { |     union { | ||||||
|         BitField<0x00, 0x5, u32> operand_desc_id; |         BitField<0x00, 0x5, u32> operand_desc_id; | ||||||
|         BitField<0x07, 0x5, u32> src2; | 
 | ||||||
|         BitField<0x0c, 0x7, u32> src1; |         template<class BitFieldType> | ||||||
|         BitField<0x13, 0x7, u32> dest; |         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; |     } common; | ||||||
| 
 | 
 | ||||||
|     // Format used for flow control instructions ("if")
 |     // Format used for flow control instructions ("if")
 | ||||||
|  | @ -128,6 +197,7 @@ union Instruction { | ||||||
|         BitField<0x0a, 0xc, u32> offset_words; |         BitField<0x0a, 0xc, u32> offset_words; | ||||||
|     } flow_control; |     } flow_control; | ||||||
| }; | }; | ||||||
|  | static_assert(std::is_standard_layout<Instruction>::value, "Structure is not using standard layout!"); | ||||||
| 
 | 
 | ||||||
| union SwizzlePattern { | union SwizzlePattern { | ||||||
|     u32 hex; |     u32 hex; | ||||||
|  | @ -185,6 +255,8 @@ union SwizzlePattern { | ||||||
|     // Components of "dest" that should be written to: LSB=dest.w, MSB=dest.x
 |     // Components of "dest" that should be written to: LSB=dest.w, MSB=dest.x
 | ||||||
|     BitField< 0, 4, u32> dest_mask; |     BitField< 0, 4, u32> dest_mask; | ||||||
| 
 | 
 | ||||||
|  |     BitField< 4, 1, u32> negate; // negates src1
 | ||||||
|  | 
 | ||||||
|     BitField< 5, 2, Selector> src1_selector_3; |     BitField< 5, 2, Selector> src1_selector_3; | ||||||
|     BitField< 7, 2, Selector> src1_selector_2; |     BitField< 7, 2, Selector> src1_selector_2; | ||||||
|     BitField< 9, 2, Selector> src1_selector_1; |     BitField< 9, 2, Selector> src1_selector_1; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue