Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  */
  23. #include "radeonsi_pipe.h"
  24. #include "sid.h"
  25.  
  26. static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type)
  27. {
  28.         struct r600_context *rctx = (struct r600_context *)ctx;
  29.  
  30.         return (struct pipe_query*)r600_context_query_create(rctx, query_type);
  31. }
  32.  
  33. static void r600_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
  34. {
  35.         struct r600_context *rctx = (struct r600_context *)ctx;
  36.  
  37.         r600_context_query_destroy(rctx, (struct r600_query *)query);
  38. }
  39.  
  40. static void r600_begin_query(struct pipe_context *ctx, struct pipe_query *query)
  41. {
  42.         struct r600_context *rctx = (struct r600_context *)ctx;
  43.         struct r600_query *rquery = (struct r600_query *)query;
  44.  
  45.         memset(&rquery->result, 0, sizeof(rquery->result));
  46.         rquery->results_start = rquery->results_end;
  47.         r600_query_begin(rctx, (struct r600_query *)query);
  48.         LIST_ADDTAIL(&rquery->list, &rctx->active_query_list);
  49. }
  50.  
  51. static void r600_end_query(struct pipe_context *ctx, struct pipe_query *query)
  52. {
  53.         struct r600_context *rctx = (struct r600_context *)ctx;
  54.         struct r600_query *rquery = (struct r600_query *)query;
  55.  
  56.         r600_query_end(rctx, rquery);
  57.         LIST_DELINIT(&rquery->list);
  58. }
  59.  
  60. static boolean r600_get_query_result(struct pipe_context *ctx,
  61.                                         struct pipe_query *query,
  62.                                         boolean wait, union pipe_query_result *vresult)
  63. {
  64.         struct r600_context *rctx = (struct r600_context *)ctx;
  65.         struct r600_query *rquery = (struct r600_query *)query;
  66.  
  67.         return r600_context_query_result(rctx, rquery, wait, vresult);
  68. }
  69.  
  70. static void r600_render_condition(struct pipe_context *ctx,
  71.                                   struct pipe_query *query,
  72.                                   boolean condition,
  73.                                   uint mode)
  74. {
  75.         struct r600_context *rctx = (struct r600_context *)ctx;
  76.         struct r600_query *rquery = (struct r600_query *)query;
  77.         int wait_flag = 0;
  78.  
  79.         /* If we already have nonzero result, render unconditionally */
  80.         if (query != NULL && rquery->result.u64 != 0) {
  81.                 if (rctx->current_render_cond) {
  82.                         r600_render_condition(ctx, NULL, FALSE, 0);
  83.                 }
  84.                 return;
  85.         }
  86.  
  87.         rctx->current_render_cond = query;
  88.         rctx->current_render_cond_cond = condition;
  89.         rctx->current_render_cond_mode = mode;
  90.  
  91.         if (query == NULL) {
  92.                 if (rctx->predicate_drawing) {
  93.                         rctx->predicate_drawing = false;
  94.                         r600_query_predication(rctx, NULL, PREDICATION_OP_CLEAR, 1);
  95.                 }
  96.                 return;
  97.         }
  98.  
  99.         if (mode == PIPE_RENDER_COND_WAIT ||
  100.             mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
  101.                 wait_flag = 1;
  102.         }
  103.  
  104.         rctx->predicate_drawing = true;
  105.  
  106.         switch (rquery->type) {
  107.         case PIPE_QUERY_OCCLUSION_COUNTER:
  108.         case PIPE_QUERY_OCCLUSION_PREDICATE:
  109.                 r600_query_predication(rctx, rquery, PREDICATION_OP_ZPASS, wait_flag);
  110.                 break;
  111.         case PIPE_QUERY_PRIMITIVES_EMITTED:
  112.         case PIPE_QUERY_PRIMITIVES_GENERATED:
  113.         case PIPE_QUERY_SO_STATISTICS:
  114.         case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
  115.                 r600_query_predication(rctx, rquery, PREDICATION_OP_PRIMCOUNT, wait_flag);
  116.                 break;
  117.         default:
  118.                 assert(0);
  119.         }
  120. }
  121.  
  122. void r600_init_query_functions(struct r600_context *rctx)
  123. {
  124.         rctx->context.create_query = r600_create_query;
  125.         rctx->context.destroy_query = r600_destroy_query;
  126.         rctx->context.begin_query = r600_begin_query;
  127.         rctx->context.end_query = r600_end_query;
  128.         rctx->context.get_query_result = r600_get_query_result;
  129.  
  130.         if (rctx->screen->info.r600_num_backends > 0)
  131.             rctx->context.render_condition = r600_render_condition;
  132. }
  133.