radv: fix the availability bit for timestamp queries

Submitted by Samuel Pitoiset on May 21, 2019, 1:42 p.m.

Details

Message ID 20190521134204.13637-1-samuel.pitoiset@gmail.com
State New
Headers show
Series "radv: fix the availability bit for timestamp queries" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Samuel Pitoiset May 21, 2019, 1:42 p.m.
The previous code was just wrong because it copied the timestamp
value directly to the destination buffer. If the query pool was
resetted just before, the value was 0xFFFFFFFF which is considered
as available.

The new logic uses a WRITE_DATA packet to always initialize the
availability bit to zero, and it uses a COND_WRITE to packet to
set the bit if the timestamp is ready.

This fixes
dEQP-VK.pipeline.timestamp.misc_tests.reset_query_before_copy.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
---
 src/amd/common/sid.h        |  3 +++
 src/amd/vulkan/radv_query.c | 31 +++++++++++++++++++++++++------
 2 files changed, 28 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/amd/common/sid.h b/src/amd/common/sid.h
index 3c0b7001d2b..16faf0e3e66 100644
--- a/src/amd/common/sid.h
+++ b/src/amd/common/sid.h
@@ -182,6 +182,9 @@ 
 #define PKT3_SURFACE_SYNC                      0x43 /* deprecated on CIK, use ACQUIRE_MEM */
 #define PKT3_ME_INITIALIZE                     0x44 /* not on CIK */
 #define PKT3_COND_WRITE                        0x45
+#define		COND_WRITE_FUNC(x)		((x) & 0x7)
+#define		COND_WRITE_POLL_SPACE(x)	(((unsigned)(x) & 0x1) << 4)
+#define		COND_WRITE_WRITE_SPACE(x)	(((unsigned)(x) & 0x1) << 8)
 #define PKT3_EVENT_WRITE                       0x46
 #define PKT3_EVENT_WRITE_EOP                   0x47 /* not on GFX9 */
 #define         EOP_DST_SEL(x)				((x) << 16)
diff --git a/src/amd/vulkan/radv_query.c b/src/amd/vulkan/radv_query.c
index 63a2ab773a8..f2b88e9c300 100644
--- a/src/amd/vulkan/radv_query.c
+++ b/src/amd/vulkan/radv_query.c
@@ -1345,7 +1345,7 @@  void radv_CmdCopyQueryPoolResults(
 			unsigned query = firstQuery + i;
 			uint64_t local_src_va = va  + query * pool->stride;
 
-			MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cs, 19);
+			MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cs, 27);
 
 
 			if (flags & VK_QUERY_RESULT_WAIT_BIT) {
@@ -1360,13 +1360,32 @@  void radv_CmdCopyQueryPoolResults(
 			if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
 				uint64_t avail_dest_va = dest_va + elem_size;
 
-				radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0));
-				radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_SRC_MEM) |
-						COPY_DATA_DST_SEL(COPY_DATA_DST_MEM_GRBM));
-				radeon_emit(cs, local_src_va);
-				radeon_emit(cs, local_src_va >> 32);
+				/* Make sure to initialize the availability bit
+				 * to zero because the conditional packet will
+				 * only write 1 if the result is available.
+				 */
+				radeon_emit(cs, PKT3(PKT3_WRITE_DATA, 3, 0));
+				radeon_emit(cs, S_370_DST_SEL(V_370_MEM) |
+						S_370_WR_CONFIRM(1) |
+						S_370_ENGINE_SEL(V_370_PFP));
+				radeon_emit(cs, avail_dest_va);
+				radeon_emit(cs, avail_dest_va >> 32);
+				radeon_emit(cs, 0);
+
+				/* Set the availability bit to 1 only if the
+				 * high 32 bits of the timestamp is ready.
+				 */
+				radeon_emit(cs, PKT3(PKT3_COND_WRITE, 7, 0));
+				radeon_emit(cs, COND_WRITE_FUNC(4) | /* not equal */
+						COND_WRITE_POLL_SPACE(1) | /* memory */
+						COND_WRITE_WRITE_SPACE(1));
+				radeon_emit(cs, local_src_va + 4);
+				radeon_emit(cs, (local_src_va + 4) >> 32);
+				radeon_emit(cs, TIMESTAMP_NOT_READY >> 32);
+				radeon_emit(cs, 0xffffffff);
 				radeon_emit(cs, avail_dest_va);
 				radeon_emit(cs, avail_dest_va >> 32);
+				radeon_emit(cs, 1);
 			}
 
 			radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0));