radv: add set_loc_shader_ptr() helper
[mesa.git] / src / amd / vulkan / radv_query.c
index cc943d5de074f4f40eb39b0dc24089b0740c4ef5..3749e2f43d1179518f6745773bb11dd247d0303a 100644 (file)
@@ -1079,7 +1079,8 @@ void radv_CmdResetQueryPool(
 
 static void emit_begin_query(struct radv_cmd_buffer *cmd_buffer,
                             uint64_t va,
-                            VkQueryType query_type)
+                            VkQueryType query_type,
+                            VkQueryControlFlags flags)
 {
        struct radeon_winsys_cs *cs = cmd_buffer->cs;
        switch (query_type) {
@@ -1087,8 +1088,27 @@ static void emit_begin_query(struct radv_cmd_buffer *cmd_buffer,
                radeon_check_space(cmd_buffer->device->ws, cs, 7);
 
                ++cmd_buffer->state.active_occlusion_queries;
-               if (cmd_buffer->state.active_occlusion_queries == 1)
+               if (cmd_buffer->state.active_occlusion_queries == 1) {
+                       if (flags & VK_QUERY_CONTROL_PRECISE_BIT) {
+                               /* This is the first occlusion query, enable
+                                * the hint if the precision bit is set.
+                                */
+                               cmd_buffer->state.perfect_occlusion_queries_enabled = true;
+                       }
+
                        radv_set_db_count_control(cmd_buffer);
+               } else {
+                       if ((flags & VK_QUERY_CONTROL_PRECISE_BIT) &&
+                           !cmd_buffer->state.perfect_occlusion_queries_enabled) {
+                               /* This is not the first query, but this one
+                                * needs to enable precision, DB_COUNT_CONTROL
+                                * has to be updated accordingly.
+                                */
+                               cmd_buffer->state.perfect_occlusion_queries_enabled = true;
+
+                               radv_set_db_count_control(cmd_buffer);
+                       }
+               }
 
                radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0));
                radeon_emit(cs, EVENT_TYPE(V_028A90_ZPASS_DONE) | EVENT_INDEX(1));
@@ -1119,9 +1139,15 @@ static void emit_end_query(struct radv_cmd_buffer *cmd_buffer,
                radeon_check_space(cmd_buffer->device->ws, cs, 14);
 
                cmd_buffer->state.active_occlusion_queries--;
-               if (cmd_buffer->state.active_occlusion_queries == 0)
+               if (cmd_buffer->state.active_occlusion_queries == 0) {
                        radv_set_db_count_control(cmd_buffer);
 
+                       /* Reset the perfect occlusion queries hint now that no
+                        * queries are active.
+                        */
+                       cmd_buffer->state.perfect_occlusion_queries_enabled = false;
+               }
+
                radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0));
                radeon_emit(cs, EVENT_TYPE(V_028A90_ZPASS_DONE) | EVENT_INDEX(1));
                radeon_emit(cs, va + 8);
@@ -1177,26 +1203,7 @@ void radv_CmdBeginQuery(
 
        va += pool->stride * query;
 
-       emit_begin_query(cmd_buffer, va, pool->type);
-
-       /*
-        * For multiview we have to emit a query for each bit in the mask,
-        * however the first query we emit will get the totals for all the
-        * operations, so we don't want to get a real value in the other
-        * queries. This emits a fake begin/end sequence so the waiting
-        * code gets a completed query value and doesn't hang, but the
-        * query returns 0.
-        */
-       if (cmd_buffer->state.subpass && cmd_buffer->state.subpass->view_mask) {
-               uint64_t avail_va = va + pool->availability_offset + 4 * query;
-
-               for (unsigned i = 0; i < util_bitcount(cmd_buffer->state.subpass->view_mask); i++) {
-                       va += pool->stride;
-                       avail_va += 4;
-                       emit_begin_query(cmd_buffer, va, pool->type);
-                       emit_end_query(cmd_buffer, va, avail_va, pool->type);
-               }
-       }
+       emit_begin_query(cmd_buffer, va, pool->type, flags);
 }
 
 
@@ -1215,6 +1222,26 @@ void radv_CmdEndQuery(
         * currently be active, which means the BO is already in the list.
         */
        emit_end_query(cmd_buffer, va, avail_va, pool->type);
+
+       /*
+        * For multiview we have to emit a query for each bit in the mask,
+        * however the first query we emit will get the totals for all the
+        * operations, so we don't want to get a real value in the other
+        * queries. This emits a fake begin/end sequence so the waiting
+        * code gets a completed query value and doesn't hang, but the
+        * query returns 0.
+        */
+       if (cmd_buffer->state.subpass && cmd_buffer->state.subpass->view_mask) {
+               uint64_t avail_va = va + pool->availability_offset + 4 * query;
+
+
+               for (unsigned i = 1; i < util_bitcount(cmd_buffer->state.subpass->view_mask); i++) {
+                       va += pool->stride;
+                       avail_va += 4;
+                       emit_begin_query(cmd_buffer, va, pool->type, 0);
+                       emit_end_query(cmd_buffer, va, avail_va, pool->type);
+               }
+       }
 }
 
 void radv_CmdWriteTimestamp(