r600g: optimise the draw emission packets for r600/eg
[mesa.git] / src / gallium / drivers / softpipe / sp_query.c
index b959af63aff59e6ebe8a24d4b18bb39a85664bd2..4ae69c1c2bdaf5cbdf147f37394860e4fd4b1b3c 100644 (file)
@@ -41,6 +41,7 @@ struct softpipe_query {
    unsigned type;
    uint64_t start;
    uint64_t end;
+   struct pipe_query_data_so_statistics so;
 };
 
 
@@ -55,7 +56,11 @@ softpipe_create_query(struct pipe_context *pipe,
 {
    struct softpipe_query* sq;
 
-   assert(type == PIPE_QUERY_OCCLUSION_COUNTER || type == PIPE_QUERY_TIME_ELAPSED);
+   assert(type == PIPE_QUERY_OCCLUSION_COUNTER ||
+          type == PIPE_QUERY_TIME_ELAPSED ||
+          type == PIPE_QUERY_SO_STATISTICS ||
+          type == PIPE_QUERY_GPU_FINISHED ||
+          type == PIPE_QUERY_TIMESTAMP_DISJOINT);
    sq = CALLOC_STRUCT( softpipe_query );
    sq->type = type;
 
@@ -75,7 +80,7 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct softpipe_context *softpipe = softpipe_context( pipe );
    struct softpipe_query *sq = softpipe_query(q);
-   
+
    switch (sq->type) {
    case PIPE_QUERY_OCCLUSION_COUNTER:
       sq->start = softpipe->occlusion_count;
@@ -83,6 +88,13 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    case PIPE_QUERY_TIME_ELAPSED:
       sq->start = 1000*os_time_get();
       break;
+   case PIPE_QUERY_SO_STATISTICS:
+      sq->so.num_primitives_written = 0;
+      sq->so.primitives_storage_needed = 0;
+      break;
+   case PIPE_QUERY_GPU_FINISHED:
+      break;
+   case PIPE_QUERY_TIMESTAMP_DISJOINT:
    default:
       assert(0);
       break;
@@ -106,6 +118,15 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
    case PIPE_QUERY_TIME_ELAPSED:
       sq->end = 1000*os_time_get();
       break;
+   case PIPE_QUERY_SO_STATISTICS:
+      sq->so.num_primitives_written =
+         softpipe->so_stats.num_primitives_written;
+      sq->so.primitives_storage_needed =
+         softpipe->so_stats.primitives_storage_needed;
+      break;
+   case PIPE_QUERY_GPU_FINISHED:
+   case PIPE_QUERY_TIMESTAMP_DISJOINT:
+      break;
    default:
       assert(0);
       break;
@@ -118,10 +139,32 @@ static boolean
 softpipe_get_query_result(struct pipe_context *pipe, 
                          struct pipe_query *q,
                          boolean wait,
-                         uint64_t *result )
+                         void *vresult)
 {
    struct softpipe_query *sq = softpipe_query(q);
-   *result = sq->end - sq->start;
+   uint64_t *result = (uint64_t*)vresult;
+
+   switch (sq->type) {
+   case PIPE_QUERY_SO_STATISTICS:
+      memcpy(vresult, &sq->so,
+             sizeof(struct pipe_query_data_so_statistics));
+      break;
+   case PIPE_QUERY_GPU_FINISHED:
+      *result = TRUE;
+      break;
+   case PIPE_QUERY_TIMESTAMP_DISJOINT: {
+      struct pipe_query_data_timestamp_disjoint td;
+      /*os_get_time is in microseconds*/
+      td.frequency = 1000000;
+      td.disjoint = FALSE;
+      memcpy(vresult, &sq->so,
+             sizeof(struct pipe_query_data_timestamp_disjoint));
+   }
+      break;
+   default:
+      *result = sq->end - sq->start;
+      break;
+   }
    return TRUE;
 }