Shader: Implemented compound predicates in fsetp.
You can specify three predicates in an fsetp instruction: P1 = (Value1 Comp Value2) OP P0; P2 = !(Value1 Comp Value2) OP P0;
This commit is contained in:
		
							parent
							
								
									55e6296e71
								
							
						
					
					
						commit
						126270d963
					
				| @ -597,6 +597,45 @@ private: | ||||
|         return variable; | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Returns the comparison string to use to compare two values in the 'set' family of | ||||
|      * instructions. | ||||
|      * @params condition The condition used in the 'set'-family instruction. | ||||
|      * @returns String corresponding to the GLSL operator that matches the desired comparison. | ||||
|      */ | ||||
|     std::string GetPredicateComparison(Tegra::Shader::PredCondition condition) const { | ||||
|         using Tegra::Shader::PredCondition; | ||||
|         static const std::unordered_map<PredCondition, const char*> PredicateComparisonStrings = { | ||||
|             {PredCondition::LessThan, "<"}, | ||||
|             {PredCondition::Equal, "=="}, | ||||
|             {PredCondition::LessEqual, "<="}, | ||||
|         }; | ||||
| 
 | ||||
|         auto comparison = PredicateComparisonStrings.find(condition); | ||||
|         ASSERT_MSG(comparison != PredicateComparisonStrings.end(), | ||||
|                    "Unknown predicate comparison operation"); | ||||
|         return comparison->second; | ||||
|     } | ||||
| 
 | ||||
|     /**
 | ||||
|      * Returns the operator string to use to combine two predicates in the 'setp' family of | ||||
|      * instructions. | ||||
|      * @params operation The operator used in the 'setp'-family instruction. | ||||
|      * @returns String corresponding to the GLSL operator that matches the desired operator. | ||||
|      */ | ||||
|     std::string GetPredicateCombiner(Tegra::Shader::PredOperation operation) const { | ||||
|         using Tegra::Shader::PredOperation; | ||||
|         static const std::unordered_map<PredOperation, const char*> PredicateOperationStrings = { | ||||
|             {PredOperation::And, "&&"}, | ||||
|             {PredOperation::Or, "||"}, | ||||
|             {PredOperation::Xor, "^"}, | ||||
|         }; | ||||
| 
 | ||||
|         auto op = PredicateOperationStrings.find(operation); | ||||
|         ASSERT_MSG(op != PredicateOperationStrings.end(), "Unknown predicate operation"); | ||||
|         return op->second; | ||||
|     } | ||||
| 
 | ||||
|     /*
 | ||||
|      * Returns whether the instruction at the specified offset is a 'sched' instruction. | ||||
|      * Sched instructions always appear before a sequence of 3 instructions. | ||||
| @ -888,28 +927,25 @@ private: | ||||
|             } | ||||
| 
 | ||||
|             using Tegra::Shader::Pred; | ||||
|             ASSERT_MSG(instr.fsetp.pred0 == static_cast<u64>(Pred::UnusedIndex) && | ||||
|                            instr.fsetp.pred39 == static_cast<u64>(Pred::UnusedIndex), | ||||
|                        "Compound predicates are not implemented"); | ||||
| 
 | ||||
|             // We can't use the constant predicate as destination.
 | ||||
|             ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | ||||
| 
 | ||||
|             using Tegra::Shader::PredCondition; | ||||
|             switch (instr.fsetp.cond) { | ||||
|             case PredCondition::LessThan: | ||||
|                 SetPredicate(instr.fsetp.pred3, '(' + op_a + ") < (" + op_b + ')'); | ||||
|                 break; | ||||
|             case PredCondition::Equal: | ||||
|                 SetPredicate(instr.fsetp.pred3, '(' + op_a + ") == (" + op_b + ')'); | ||||
|                 break; | ||||
|             case PredCondition::LessEqual: | ||||
|                 SetPredicate(instr.fsetp.pred3, '(' + op_a + ") <= (" + op_b + ')'); | ||||
|                 break; | ||||
|             default: | ||||
|                 NGLOG_CRITICAL(HW_GPU, "Unhandled predicate condition: {} (a: {}, b: {})", | ||||
|                                static_cast<unsigned>(instr.fsetp.cond.Value()), op_a, op_b); | ||||
|                 UNREACHABLE(); | ||||
|             std::string second_pred = | ||||
|                 GetPredicateCondition(instr.fsetp.pred39, instr.fsetp.neg_pred != 0); | ||||
| 
 | ||||
|             std::string comparator = GetPredicateComparison(instr.fsetp.cond); | ||||
|             std::string combiner = GetPredicateCombiner(instr.fsetp.op); | ||||
| 
 | ||||
|             std::string predicate = '(' + op_a + ") " + comparator + " (" + op_b + ')'; | ||||
|             // Set the primary predicate to the result of Predicate OP SecondPredicate
 | ||||
|             SetPredicate(instr.fsetp.pred3, | ||||
|                          '(' + predicate + ") " + combiner + " (" + second_pred + ')'); | ||||
| 
 | ||||
|             if (instr.fsetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) { | ||||
|                 // Set the secondary predicate to the result of !Predicate OP SecondPredicate, if
 | ||||
|                 // enabled
 | ||||
|                 SetPredicate(instr.fsetp.pred0, | ||||
|                              "!(" + predicate + ") " + combiner + " (" + second_pred + ')'); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Subv
						Subv