summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Subv2018-06-03 19:17:31 -0500
committerGravatar Subv2018-06-03 19:17:31 -0500
commitd57333406d09c6b193c2660bdb692320e5d328e5 (patch)
treeddb79d0cbf7298f6ad09f4df5ff314f10d609c4d
parentMerge pull request #492 from mailwl/time (diff)
downloadyuzu-d57333406d09c6b193c2660bdb692320e5d328e5.tar.gz
yuzu-d57333406d09c6b193c2660bdb692320e5d328e5.tar.xz
yuzu-d57333406d09c6b193c2660bdb692320e5d328e5.zip
GPU: Partial implementation of long GPU queries.
Long queries write a 128-bit result value to memory, which consists of a 64 bit query value and a 64 bit timestamp. In this implementation, only select=Zero of the Crop unit is implemented, this writes the query sequence as a 64 bit value, and a 0u64 value for the timestamp, since we emulate an infinitely fast GPU. This specific type was hwtested, but more rigorous tests should be performed in the future for the other types.
-rw-r--r--src/video_core/engines/maxwell_3d.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 23e70cd8a..ef12d9300 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -156,16 +156,15 @@ void Maxwell3D::ProcessQueryGet() {
156 // TODO(Subv): Support the other query units. 156 // TODO(Subv): Support the other query units.
157 ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop, 157 ASSERT_MSG(regs.query.query_get.unit == Regs::QueryUnit::Crop,
158 "Units other than CROP are unimplemented"); 158 "Units other than CROP are unimplemented");
159 ASSERT_MSG(regs.query.query_get.short_query,
160 "Writing the entire query result structure is unimplemented");
161 159
162 u32 value = Memory::Read32(*address); 160 u32 value = Memory::Read32(*address);
163 u32 result = 0; 161 u64 result = 0;
164 162
165 // TODO(Subv): Support the other query variables 163 // TODO(Subv): Support the other query variables
166 switch (regs.query.query_get.select) { 164 switch (regs.query.query_get.select) {
167 case Regs::QuerySelect::Zero: 165 case Regs::QuerySelect::Zero:
168 result = 0; 166 // This seems to actually write the query sequence to the query address.
167 result = regs.query.query_sequence;
169 break; 168 break;
170 default: 169 default:
171 UNIMPLEMENTED_MSG("Unimplemented query select type {}", 170 UNIMPLEMENTED_MSG("Unimplemented query select type {}",
@@ -174,15 +173,31 @@ void Maxwell3D::ProcessQueryGet() {
174 173
175 // TODO(Subv): Research and implement how query sync conditions work. 174 // TODO(Subv): Research and implement how query sync conditions work.
176 175
176 struct LongQueryResult {
177 u64_le value;
178 u64_le timestamp;
179 };
180 static_assert(sizeof(LongQueryResult) == 16, "LongQueryResult has wrong size");
181
177 switch (regs.query.query_get.mode) { 182 switch (regs.query.query_get.mode) {
178 case Regs::QueryMode::Write: 183 case Regs::QueryMode::Write:
179 case Regs::QueryMode::Write2: { 184 case Regs::QueryMode::Write2: {
180 // Write the current query sequence to the sequence address.
181 u32 sequence = regs.query.query_sequence; 185 u32 sequence = regs.query.query_sequence;
182 Memory::Write32(*address, sequence); 186 if (regs.query.query_get.short_query) {
183 187 // Write the current query sequence to the sequence address.
184 // TODO(Subv): Write the proper query response structure to the address when not using short 188 // TODO(Subv): Find out what happens if you use a long query type but mark it as a short
185 // mode. 189 // query.
190 Memory::Write32(*address, sequence);
191 } else {
192 // Write the 128-bit result structure in long mode. Note: We emulate an infinitely fast
193 // GPU, this command may actually take a while to complete in real hardware due to GPU
194 // wait queues.
195 LongQueryResult query_result{};
196 query_result.value = result;
197 // TODO(Subv): Generate a real GPU timestamp and write it here instead of 0
198 query_result.timestamp = 0;
199 Memory::WriteBlock(*address, &query_result, sizeof(query_result));
200 }
186 break; 201 break;
187 } 202 }
188 default: 203 default: