radeon: use bo_is_idle interface for checking if OQ result is available
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_queryobj.c
index 70251946dff051971cbbcbdd13bbcb37e4a98745..e508f5f63121140c4f3ba7b4065c76444c99cf57 100644 (file)
 
 #define PAGE_SIZE 4096
 
+static int radeonQueryIsFlushed(GLcontext *ctx, struct gl_query_object *q)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
+
+       foreach(tmp, &radeon->query.not_flushed_head) {
+               if (tmp == query) {
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
 static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
 {
        struct radeon_query_object *query = (struct radeon_query_object *)q;
@@ -86,22 +100,11 @@ static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q)
 
 static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
 {
-       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
-       struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
+       struct radeon_query_object *query = (struct radeon_query_object *)q;
 
        /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
-       {
-               GLboolean found = GL_FALSE;
-               foreach(tmp, &radeon->query.not_flushed_head) {
-                       if (tmp == query) {
-                               found = GL_TRUE;
-                               break;
-                       }
-               }
-
-               if (found)
-                       ctx->Driver.Flush(ctx);
-       }
+       if (!radeonQueryIsFlushed(ctx, q))
+               ctx->Driver.Flush(ctx);
 
        if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
 
@@ -168,16 +171,32 @@ static void radeonEndQuery(GLcontext *ctx, struct gl_query_object *q)
        radeon->query.current = NULL;
 }
 
-/**
- * TODO:
- * should check if bo is idle, bo there's no interface to do it
- * just wait for result now
- */
 static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
 {
        if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
 
+#ifdef DRM_RADEON_GEM_BUSY
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       if (radeon->radeonScreen->kernel_mm) {
+               struct radeon_query_object *query = (struct radeon_query_object *)q;
+               uint32_t domain;
+
+               /* Need to perform a flush, as per ARB_occlusion_query spec */
+               if (!radeonQueryIsFlushed(ctx, q)) {
+                       ctx->Driver.Flush(ctx);
+               }
+
+               if (radeon_bo_is_busy(query->bo, &domain) == 0) {
+                       radeonQueryGetResult(ctx, q);
+                       query->Base.Ready = GL_TRUE;
+               }
+       } else {
+               radeonWaitQuery(ctx, q);
+       }
+#else
        radeonWaitQuery(ctx, q);
+#endif
 }
 
 void radeonInitQueryObjFunctions(struct dd_function_table *functions)