mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	shader_ir: Unify constant buffer offset values
Constant buffer values on the shader IR were using different offsets if the access direct or indirect. cbuf34 has a non-multiplied offset while cbuf36 does. On shader decoding this commit multiplies it by four on cbuf34 queries.
This commit is contained in:
		
							parent
							
								
									3c3d9afd61
								
							
						
					
					
						commit
						477d616f7d
					
				| @ -1248,11 +1248,19 @@ union Instruction { | |||||||
|     union { |     union { | ||||||
|         BitField<20, 14, u64> offset; |         BitField<20, 14, u64> offset; | ||||||
|         BitField<34, 5, u64> index; |         BitField<34, 5, u64> index; | ||||||
|  | 
 | ||||||
|  |         u64 GetOffset() const { | ||||||
|  |             return offset * 4; | ||||||
|  |         } | ||||||
|     } cbuf34; |     } cbuf34; | ||||||
| 
 | 
 | ||||||
|     union { |     union { | ||||||
|         BitField<20, 16, s64> offset; |         BitField<20, 16, s64> offset; | ||||||
|         BitField<36, 5, u64> index; |         BitField<36, 5, u64> index; | ||||||
|  | 
 | ||||||
|  |         s64 GetOffset() const { | ||||||
|  |             return offset; | ||||||
|  |         } | ||||||
|     } cbuf36; |     } cbuf36; | ||||||
| 
 | 
 | ||||||
|     // Unsure about the size of this one.
 |     // Unsure about the size of this one.
 | ||||||
|  | |||||||
| @ -957,7 +957,7 @@ void RasterizerOpenGL::SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::Shader | |||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             // Buffer is accessed directly, upload just what we use
 |             // Buffer is accessed directly, upload just what we use
 | ||||||
|             size = used_buffer.GetSize() * sizeof(float); |             size = used_buffer.GetSize(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140
 |         // Align the actual size so it ends up being a multiple of vec4 to meet the OpenGL std140
 | ||||||
|  | |||||||
| @ -543,8 +543,9 @@ private: | |||||||
|             if (const auto immediate = std::get_if<ImmediateNode>(offset)) { |             if (const auto immediate = std::get_if<ImmediateNode>(offset)) { | ||||||
|                 // Direct access
 |                 // Direct access
 | ||||||
|                 const u32 offset_imm = immediate->GetValue(); |                 const u32 offset_imm = immediate->GetValue(); | ||||||
|                 return fmt::format("{}[{}][{}]", GetConstBuffer(cbuf->GetIndex()), offset_imm / 4, |                 ASSERT_MSG(offset_imm % 4 == 0, "Unaligned cbuf direct access"); | ||||||
|                                    offset_imm % 4); |                 return fmt::format("{}[{}][{}]", GetConstBuffer(cbuf->GetIndex()), | ||||||
|  |                                    offset_imm / (4 * 4), (offset_imm / 4) % 4); | ||||||
| 
 | 
 | ||||||
|             } else if (std::holds_alternative<OperationNode>(*offset)) { |             } else if (std::holds_alternative<OperationNode>(*offset)) { | ||||||
|                 // Indirect access
 |                 // Indirect access
 | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ u32 ShaderIR::DecodeArithmetic(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|         } else if (instr.is_b_gpr) { |         } else if (instr.is_b_gpr) { | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|         } else { |         } else { | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ u32 ShaderIR::DecodeArithmeticHalf(BasicBlock& bb, const BasicBlock& code, u32 p | |||||||
|         switch (opcode->get().GetId()) { |         switch (opcode->get().GetId()) { | ||||||
|         case OpCode::Id::HADD2_C: |         case OpCode::Id::HADD2_C: | ||||||
|         case OpCode::Id::HMUL2_C: |         case OpCode::Id::HMUL2_C: | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         case OpCode::Id::HADD2_R: |         case OpCode::Id::HADD2_R: | ||||||
|         case OpCode::Id::HMUL2_R: |         case OpCode::Id::HMUL2_R: | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, const BasicBlock& code, u3 | |||||||
|         } else if (instr.is_b_gpr) { |         } else if (instr.is_b_gpr) { | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|         } else { |         } else { | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -48,7 +48,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|             if (instr.is_b_gpr) { |             if (instr.is_b_gpr) { | ||||||
|                 return GetRegister(instr.gpr20); |                 return GetRegister(instr.gpr20); | ||||||
|             } else { |             } else { | ||||||
|                 return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |                 return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|             } |             } | ||||||
|         }(); |         }(); | ||||||
|         const bool input_signed = instr.conversion.is_input_signed; |         const bool input_signed = instr.conversion.is_input_signed; | ||||||
| @ -72,7 +72,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|             if (instr.is_b_gpr) { |             if (instr.is_b_gpr) { | ||||||
|                 return GetRegister(instr.gpr20); |                 return GetRegister(instr.gpr20); | ||||||
|             } else { |             } else { | ||||||
|                 return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |                 return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|             } |             } | ||||||
|         }(); |         }(); | ||||||
| 
 | 
 | ||||||
| @ -110,7 +110,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|             if (instr.is_b_gpr) { |             if (instr.is_b_gpr) { | ||||||
|                 return GetRegister(instr.gpr20); |                 return GetRegister(instr.gpr20); | ||||||
|             } else { |             } else { | ||||||
|                 return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |                 return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|             } |             } | ||||||
|         }(); |         }(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,14 +27,14 @@ u32 ShaderIR::DecodeFfma(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|     auto [op_b, op_c] = [&]() -> std::tuple<Node, Node> { |     auto [op_b, op_c] = [&]() -> std::tuple<Node, Node> { | ||||||
|         switch (opcode->get().GetId()) { |         switch (opcode->get().GetId()) { | ||||||
|         case OpCode::Id::FFMA_CR: { |         case OpCode::Id::FFMA_CR: { | ||||||
|             return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), |             return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()), | ||||||
|                     GetRegister(instr.gpr39)}; |                     GetRegister(instr.gpr39)}; | ||||||
|         } |         } | ||||||
|         case OpCode::Id::FFMA_RR: |         case OpCode::Id::FFMA_RR: | ||||||
|             return {GetRegister(instr.gpr20), GetRegister(instr.gpr39)}; |             return {GetRegister(instr.gpr20), GetRegister(instr.gpr39)}; | ||||||
|         case OpCode::Id::FFMA_RC: { |         case OpCode::Id::FFMA_RC: { | ||||||
|             return {GetRegister(instr.gpr39), |             return {GetRegister(instr.gpr39), | ||||||
|                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)}; |                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())}; | ||||||
|         } |         } | ||||||
|         case OpCode::Id::FFMA_IMM: |         case OpCode::Id::FFMA_IMM: | ||||||
|             return {GetImmediate19(instr), GetRegister(instr.gpr39)}; |             return {GetImmediate19(instr), GetRegister(instr.gpr39)}; | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ u32 ShaderIR::DecodeFloatSet(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|         } else if (instr.is_b_gpr) { |         } else if (instr.is_b_gpr) { | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|         } else { |         } else { | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ u32 ShaderIR::DecodeFloatSetPredicate(BasicBlock& bb, const BasicBlock& code, u3 | |||||||
|         } else if (instr.is_b_gpr) { |         } else if (instr.is_b_gpr) { | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|         } else { |         } else { | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
|     op_b = GetOperandAbsNegFloat(op_b, instr.fsetp.abs_b, false); |     op_b = GetOperandAbsNegFloat(op_b, instr.fsetp.abs_b, false); | ||||||
|  | |||||||
| @ -39,13 +39,14 @@ u32 ShaderIR::DecodeHfma2(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|             neg_b = instr.hfma2.negate_b; |             neg_b = instr.hfma2.negate_b; | ||||||
|             neg_c = instr.hfma2.negate_c; |             neg_c = instr.hfma2.negate_c; | ||||||
|             return {instr.hfma2.saturate, instr.hfma2.type_b, |             return {instr.hfma2.saturate, instr.hfma2.type_b, | ||||||
|                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), instr.hfma2.type_reg39, |                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()), | ||||||
|                     GetRegister(instr.gpr39)}; |                     instr.hfma2.type_reg39, GetRegister(instr.gpr39)}; | ||||||
|         case OpCode::Id::HFMA2_RC: |         case OpCode::Id::HFMA2_RC: | ||||||
|             neg_b = instr.hfma2.negate_b; |             neg_b = instr.hfma2.negate_b; | ||||||
|             neg_c = instr.hfma2.negate_c; |             neg_c = instr.hfma2.negate_c; | ||||||
|             return {instr.hfma2.saturate, instr.hfma2.type_reg39, GetRegister(instr.gpr39), |             return {instr.hfma2.saturate, instr.hfma2.type_reg39, GetRegister(instr.gpr39), | ||||||
|                     instr.hfma2.type_b, GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)}; |                     instr.hfma2.type_b, | ||||||
|  |                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())}; | ||||||
|         case OpCode::Id::HFMA2_RR: |         case OpCode::Id::HFMA2_RR: | ||||||
|             neg_b = instr.hfma2.rr.negate_b; |             neg_b = instr.hfma2.rr.negate_b; | ||||||
|             neg_c = instr.hfma2.rr.negate_c; |             neg_c = instr.hfma2.rr.negate_c; | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ u32 ShaderIR::DecodeIntegerSet(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|         } else if (instr.is_b_gpr) { |         } else if (instr.is_b_gpr) { | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|         } else { |         } else { | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ u32 ShaderIR::DecodeIntegerSetPredicate(BasicBlock& bb, const BasicBlock& code, | |||||||
|         } else if (instr.is_b_gpr) { |         } else if (instr.is_b_gpr) { | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|         } else { |         } else { | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -80,7 +80,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|         Node index = GetRegister(instr.gpr8); |         Node index = GetRegister(instr.gpr8); | ||||||
| 
 | 
 | ||||||
|         const Node op_a = |         const Node op_a = | ||||||
|             GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, index); |             GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index); | ||||||
| 
 | 
 | ||||||
|         switch (instr.ld_c.type.Value()) { |         switch (instr.ld_c.type.Value()) { | ||||||
|         case Tegra::Shader::UniformType::Single: |         case Tegra::Shader::UniformType::Single: | ||||||
| @ -89,7 +89,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
| 
 | 
 | ||||||
|         case Tegra::Shader::UniformType::Double: { |         case Tegra::Shader::UniformType::Double: { | ||||||
|             const Node op_b = |             const Node op_b = | ||||||
|                 GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, index); |                 GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 4, index); | ||||||
| 
 | 
 | ||||||
|             SetTemporal(bb, 0, op_a); |             SetTemporal(bb, 0, op_a); | ||||||
|             SetTemporal(bb, 1, op_b); |             SetTemporal(bb, 1, op_b); | ||||||
| @ -142,7 +142,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|         ASSERT(cbuf != nullptr); |         ASSERT(cbuf != nullptr); | ||||||
|         const auto cbuf_offset_imm = std::get_if<ImmediateNode>(cbuf->GetOffset()); |         const auto cbuf_offset_imm = std::get_if<ImmediateNode>(cbuf->GetOffset()); | ||||||
|         ASSERT(cbuf_offset_imm != nullptr); |         ASSERT(cbuf_offset_imm != nullptr); | ||||||
|         const auto cbuf_offset = cbuf_offset_imm->GetValue() * 4; |         const auto cbuf_offset = cbuf_offset_imm->GetValue(); | ||||||
| 
 | 
 | ||||||
|         bb.push_back(Comment( |         bb.push_back(Comment( | ||||||
|             fmt::format("Base address is c[0x{:x}][0x{:x}]", cbuf->GetIndex(), cbuf_offset))); |             fmt::format("Base address is c[0x{:x}][0x{:x}]", cbuf->GetIndex(), cbuf_offset))); | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ u32 ShaderIR::DecodeShift(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|         } else if (instr.is_b_gpr) { |         } else if (instr.is_b_gpr) { | ||||||
|             return GetRegister(instr.gpr20); |             return GetRegister(instr.gpr20); | ||||||
|         } else { |         } else { | ||||||
|             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); |             return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); | ||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -32,13 +32,14 @@ u32 ShaderIR::DecodeXmad(BasicBlock& bb, const BasicBlock& code, u32 pc) { | |||||||
|     auto [is_merge, op_b, op_c] = [&]() -> std::tuple<bool, Node, Node> { |     auto [is_merge, op_b, op_c] = [&]() -> std::tuple<bool, Node, Node> { | ||||||
|         switch (opcode->get().GetId()) { |         switch (opcode->get().GetId()) { | ||||||
|         case OpCode::Id::XMAD_CR: |         case OpCode::Id::XMAD_CR: | ||||||
|             return {instr.xmad.merge_56, GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), |             return {instr.xmad.merge_56, | ||||||
|  |                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()), | ||||||
|                     GetRegister(instr.gpr39)}; |                     GetRegister(instr.gpr39)}; | ||||||
|         case OpCode::Id::XMAD_RR: |         case OpCode::Id::XMAD_RR: | ||||||
|             return {instr.xmad.merge_37, GetRegister(instr.gpr20), GetRegister(instr.gpr39)}; |             return {instr.xmad.merge_37, GetRegister(instr.gpr20), GetRegister(instr.gpr39)}; | ||||||
|         case OpCode::Id::XMAD_RC: |         case OpCode::Id::XMAD_RC: | ||||||
|             return {false, GetRegister(instr.gpr39), |             return {false, GetRegister(instr.gpr39), | ||||||
|                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)}; |                     GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())}; | ||||||
|         case OpCode::Id::XMAD_IMM: |         case OpCode::Id::XMAD_IMM: | ||||||
|             return {instr.xmad.merge_37, Immediate(static_cast<u32>(instr.xmad.imm20_16)), |             return {instr.xmad.merge_37, Immediate(static_cast<u32>(instr.xmad.imm20_16)), | ||||||
|                     GetRegister(instr.gpr39)}; |                     GetRegister(instr.gpr39)}; | ||||||
|  | |||||||
| @ -249,7 +249,7 @@ public: | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     u32 GetSize() const { |     u32 GetSize() const { | ||||||
|         return max_offset + 1; |         return max_offset + sizeof(float); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
						ReinUsesLisp