Maxwell3D: Correct query reporting.
This commit is contained in:
		
				
					committed by
					
						 FernandoS27
						FernandoS27
					
				
			
			
				
	
			
			
			
						parent
						
							84ea9c2b42
						
					
				
				
					commit
					0cb3bcfbb7
				
			| @@ -519,61 +519,66 @@ void Maxwell3D::ProcessFirmwareCall4() { | |||||||
|     regs.reg_array[0xd00] = 1; |     regs.reg_array[0xd00] = 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| void Maxwell3D::ProcessQueryGet() { | void Maxwell3D::StampQueryResult(u64 payload, bool long_query) { | ||||||
|     const GPUVAddr sequence_address{regs.query.QueryAddress()}; |  | ||||||
|     // Since the sequence address is given as a GPU VAddr, we have to convert it to an application |  | ||||||
|     // VAddr before writing. |  | ||||||
|  |  | ||||||
|     // TODO(Subv): Support the other query units. |  | ||||||
|     ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, |  | ||||||
|                "Units other than CROP are unimplemented"); |  | ||||||
|  |  | ||||||
|     u64 result = 0; |  | ||||||
|  |  | ||||||
|     // TODO(Subv): Support the other query variables |  | ||||||
|     switch (regs.query.query_get.select) { |  | ||||||
|     case Regs::QuerySelect::Zero: |  | ||||||
|         // This seems to actually write the query sequence to the query address. |  | ||||||
|         result = regs.query.query_sequence; |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|         result = 1; |  | ||||||
|         UNIMPLEMENTED_MSG("Unimplemented query select type {}", |  | ||||||
|                           static_cast<u32>(regs.query.query_get.select.Value())); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // TODO(Subv): Research and implement how query sync conditions work. |  | ||||||
|  |  | ||||||
|     struct LongQueryResult { |     struct LongQueryResult { | ||||||
|         u64_le value; |         u64_le value; | ||||||
|         u64_le timestamp; |         u64_le timestamp; | ||||||
|     }; |     }; | ||||||
|     static_assert(sizeof(LongQueryResult) == 16, "LongQueryResult has wrong size"); |     static_assert(sizeof(LongQueryResult) == 16, "LongQueryResult has wrong size"); | ||||||
|  |     const GPUVAddr sequence_address{regs.query.QueryAddress()}; | ||||||
|  |     if (long_query) { | ||||||
|  |         // Write the 128-bit result structure in long mode. Note: We emulate an infinitely fast | ||||||
|  |         // GPU, this command may actually take a while to complete in real hardware due to GPU | ||||||
|  |         // wait queues. | ||||||
|  |         LongQueryResult query_result{}; | ||||||
|  |         query_result.value = payload; | ||||||
|  |         // TODO(Subv): Generate a real GPU timestamp and write it here instead of CoreTiming | ||||||
|  |         query_result.timestamp = system.CoreTiming().GetTicks(); | ||||||
|  |         memory_manager.WriteBlock(sequence_address, &query_result, sizeof(query_result)); | ||||||
|  |     } else { | ||||||
|  |         memory_manager.Write<u32>(sequence_address, static_cast<u32>(payload)); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|     switch (regs.query.query_get.mode) { | void Maxwell3D::ProcessQueryGet() { | ||||||
|     case Regs::QueryMode::Write: |     // TODO(Subv): Support the other query units. | ||||||
|     case Regs::QueryMode::Write2: { |     ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, | ||||||
|         u32 sequence = regs.query.query_sequence; |                "Units other than CROP are unimplemented"); | ||||||
|         if (regs.query.query_get.short_query) { |  | ||||||
|             // Write the current query sequence to the sequence address. |     switch (regs.query.query_get.operation) { | ||||||
|             // TODO(Subv): Find out what happens if you use a long query type but mark it as a short |     case Regs::QueryOperation::Release: { | ||||||
|             // query. |         u64 result = regs.query.query_sequence; | ||||||
|             memory_manager.Write<u32>(sequence_address, sequence); |         StampQueryResult(result, regs.query.query_get.short_query == 0); | ||||||
|         } else { |         break; | ||||||
|             // Write the 128-bit result structure in long mode. Note: We emulate an infinitely fast |     } | ||||||
|             // GPU, this command may actually take a while to complete in real hardware due to GPU |     case Regs::QueryOperation::Acquire: { | ||||||
|             // wait queues. |         // Todo(Blinkhawk): Under this operation, the GPU waits for the CPU | ||||||
|             LongQueryResult query_result{}; |         // to write a value that matches the current payload. | ||||||
|             query_result.value = result; |         UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE"); | ||||||
|             // TODO(Subv): Generate a real GPU timestamp and write it here instead of CoreTiming |         break; | ||||||
|             query_result.timestamp = system.CoreTiming().GetTicks(); |     } | ||||||
|             memory_manager.WriteBlock(sequence_address, &query_result, sizeof(query_result)); |     case Regs::QueryOperation::Counter: { | ||||||
|         } |         u64 result{}; | ||||||
|  |         switch (regs.query.query_get.select) { | ||||||
|  |         case Regs::QuerySelect::Zero: | ||||||
|  |             result = 0; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             result = 1; | ||||||
|  |             UNIMPLEMENTED_MSG("Unimplemented query select type {}", | ||||||
|  |                               static_cast<u32>(regs.query.query_get.select.Value())); | ||||||
|  |         } | ||||||
|  |         StampQueryResult(result, regs.query.query_get.short_query == 0); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |     case Regs::QueryOperation::Trap: { | ||||||
|  |         UNIMPLEMENTED_MSG("Unimplemented query operation TRAP"); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |     default: { | ||||||
|  |         UNIMPLEMENTED_MSG("Unknown query operation"); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     default: |  | ||||||
|         UNIMPLEMENTED_MSG("Query mode {} not implemented", |  | ||||||
|                           static_cast<u32>(regs.query.query_get.mode.Value())); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -71,12 +71,11 @@ public: | |||||||
|         static constexpr std::size_t MaxConstBuffers = 18; |         static constexpr std::size_t MaxConstBuffers = 18; | ||||||
|         static constexpr std::size_t MaxConstBufferSize = 0x10000; |         static constexpr std::size_t MaxConstBufferSize = 0x10000; | ||||||
|  |  | ||||||
|         enum class QueryMode : u32 { |         enum class QueryOperation : u32 { | ||||||
|             Write = 0, |             Release = 0, | ||||||
|             Sync = 1, |             Acquire = 1, | ||||||
|             // TODO(Subv): It is currently unknown what the difference between method 2 and method 0 |             Counter = 2, | ||||||
|             // is. |             Trap = 3, | ||||||
|             Write2 = 2, |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         enum class QueryUnit : u32 { |         enum class QueryUnit : u32 { | ||||||
| @@ -1077,7 +1076,7 @@ public: | |||||||
|                     u32 query_sequence; |                     u32 query_sequence; | ||||||
|                     union { |                     union { | ||||||
|                         u32 raw; |                         u32 raw; | ||||||
|                         BitField<0, 2, QueryMode> mode; |                         BitField<0, 2, QueryOperation> operation; | ||||||
|                         BitField<4, 1, u32> fence; |                         BitField<4, 1, u32> fence; | ||||||
|                         BitField<12, 4, QueryUnit> unit; |                         BitField<12, 4, QueryUnit> unit; | ||||||
|                         BitField<16, 1, QuerySyncCondition> sync_cond; |                         BitField<16, 1, QuerySyncCondition> sync_cond; | ||||||
| @@ -1409,6 +1408,9 @@ private: | |||||||
|     /// Handles a write to the QUERY_GET register. |     /// Handles a write to the QUERY_GET register. | ||||||
|     void ProcessQueryGet(); |     void ProcessQueryGet(); | ||||||
|  |  | ||||||
|  |     // Writes the query result accordingly | ||||||
|  |     void StampQueryResult(u64 payload, bool long_query); | ||||||
|  |  | ||||||
|     // Handles Conditional Rendering |     // Handles Conditional Rendering | ||||||
|     void ProcessQueryCondition(); |     void ProcessQueryCondition(); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user