Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2008-2009 Maciej Cencora <m.cencora@gmail.com>
  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.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Maciej Cencora <m.cencora@gmail.com>
  25.  *
  26.  */
  27. #include "radeon_common.h"
  28. #include "radeon_queryobj.h"
  29. #include "radeon_debug.h"
  30.  
  31. #include "main/imports.h"
  32. #include "main/simple_list.h"
  33.  
  34. #include <inttypes.h>
  35.  
  36. static void radeonQueryGetResult(struct gl_context *ctx, struct gl_query_object *q)
  37. {
  38.         struct radeon_query_object *query = (struct radeon_query_object *)q;
  39.         uint32_t *result;
  40.         int i;
  41.  
  42.         radeon_print(RADEON_STATE, RADEON_VERBOSE,
  43.                         "%s: query id %d, result %d\n",
  44.                         __FUNCTION__, query->Base.Id, (int) query->Base.Result);
  45.  
  46.         radeon_bo_map(query->bo, GL_FALSE);
  47.         result = query->bo->ptr;
  48.  
  49.         query->Base.Result = 0;
  50.         for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
  51.                 query->Base.Result += LE32_TO_CPU(result[i]);
  52.                 radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, LE32_TO_CPU(result[i]));
  53.         }
  54.  
  55.         radeon_bo_unmap(query->bo);
  56. }
  57.  
  58. static struct gl_query_object * radeonNewQueryObject(struct gl_context *ctx, GLuint id)
  59. {
  60.         struct radeon_query_object *query;
  61.  
  62.         query = calloc(1, sizeof(struct radeon_query_object));
  63.  
  64.         query->Base.Id = id;
  65.         query->Base.Result = 0;
  66.         query->Base.Active = GL_FALSE;
  67.         query->Base.Ready = GL_TRUE;
  68.  
  69.         radeon_print(RADEON_STATE, RADEON_VERBOSE,"%s: query id %d\n", __FUNCTION__, query->Base.Id);
  70.  
  71.         return &query->Base;
  72. }
  73.  
  74. static void radeonDeleteQuery(struct gl_context *ctx, struct gl_query_object *q)
  75. {
  76.         struct radeon_query_object *query = (struct radeon_query_object *)q;
  77.  
  78.         radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
  79.  
  80.         if (query->bo) {
  81.                 radeon_bo_unref(query->bo);
  82.         }
  83.  
  84.         free(query);
  85. }
  86.  
  87. static void radeonWaitQuery(struct gl_context *ctx, struct gl_query_object *q)
  88. {
  89.         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
  90.         struct radeon_query_object *query = (struct radeon_query_object *)q;
  91.  
  92.         /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
  93.         if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs))
  94.                 ctx->Driver.Flush(ctx);
  95.  
  96.         radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
  97.  
  98.         radeonQueryGetResult(ctx, q);
  99.  
  100.         query->Base.Ready = GL_TRUE;
  101. }
  102.  
  103.  
  104. static void radeonBeginQuery(struct gl_context *ctx, struct gl_query_object *q)
  105. {
  106.         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
  107.         struct radeon_query_object *query = (struct radeon_query_object *)q;
  108.  
  109.         radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
  110.  
  111.         assert(radeon->query.current == NULL);
  112.  
  113.         if (radeon->dma.flush)
  114.                 radeon->dma.flush(&radeon->glCtx);
  115.  
  116.         if (!query->bo) {
  117.                 query->bo = radeon_bo_open(radeon->radeonScreen->bom, 0, RADEON_QUERY_PAGE_SIZE, RADEON_QUERY_PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
  118.         }
  119.         query->curr_offset = 0;
  120.  
  121.         radeon->query.current = query;
  122.  
  123.         radeon->query.queryobj.dirty = GL_TRUE;
  124.         radeon->hw.is_dirty = GL_TRUE;
  125. }
  126.  
  127. void radeonEmitQueryEnd(struct gl_context *ctx)
  128. {
  129.         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
  130.         struct radeon_query_object *query = radeon->query.current;
  131.  
  132.         if (!query)
  133.                 return;
  134.  
  135.         if (query->emitted_begin == GL_FALSE)
  136.                 return;
  137.  
  138.         radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
  139.  
  140.         radeon_cs_space_check_with_bo(radeon->cmdbuf.cs,
  141.                                       query->bo,
  142.                                       0, RADEON_GEM_DOMAIN_GTT);
  143.  
  144.         radeon->vtbl.emit_query_finish(radeon);
  145. }
  146.  
  147. static void radeonEndQuery(struct gl_context *ctx, struct gl_query_object *q)
  148. {
  149.         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
  150.  
  151.         radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
  152.  
  153.         if (radeon->dma.flush)
  154.                 radeon->dma.flush(&radeon->glCtx);
  155.         radeonEmitQueryEnd(ctx);
  156.  
  157.         radeon->query.current = NULL;
  158. }
  159.  
  160. static void radeonCheckQuery(struct gl_context *ctx, struct gl_query_object *q)
  161. {
  162.         radeon_print(RADEON_STATE, RADEON_TRACE, "%s: query id %d\n", __FUNCTION__, q->Id);
  163. \
  164. #ifdef DRM_RADEON_GEM_BUSY
  165.         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
  166.  
  167.         struct radeon_query_object *query = (struct radeon_query_object *)q;
  168.         uint32_t domain;
  169.  
  170.         /* Need to perform a flush, as per ARB_occlusion_query spec */
  171.         if (radeon_bo_is_referenced_by_cs(query->bo, radeon->cmdbuf.cs)) {
  172.                 ctx->Driver.Flush(ctx);
  173.         }
  174.  
  175.         if (radeon_bo_is_busy(query->bo, &domain) == 0) {
  176.                 radeonQueryGetResult(ctx, q);
  177.                 query->Base.Ready = GL_TRUE;
  178.         }
  179. #else
  180.         radeonWaitQuery(ctx, q);
  181. #endif
  182. }
  183.  
  184. void radeonInitQueryObjFunctions(struct dd_function_table *functions)
  185. {
  186.         functions->NewQueryObject = radeonNewQueryObject;
  187.         functions->DeleteQuery = radeonDeleteQuery;
  188.         functions->BeginQuery = radeonBeginQuery;
  189.         functions->EndQuery = radeonEndQuery;
  190.         functions->CheckQuery = radeonCheckQuery;
  191.         functions->WaitQuery = radeonWaitQuery;
  192. }
  193.  
  194. int radeon_check_query_active(struct gl_context *ctx, struct radeon_state_atom *atom)
  195. {
  196.         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
  197.         struct radeon_query_object *query = radeon->query.current;
  198.  
  199.         if (!query || query->emitted_begin)
  200.                 return 0;
  201.         return atom->cmd_size;
  202. }
  203.  
  204. void radeon_emit_queryobj(struct gl_context *ctx, struct radeon_state_atom *atom)
  205. {
  206.         radeonContextPtr radeon = RADEON_CONTEXT(ctx);
  207.         BATCH_LOCALS(radeon);
  208.         int dwords;
  209.  
  210.         dwords = (*atom->check) (ctx, atom);
  211.  
  212.         BEGIN_BATCH_NO_AUTOSTATE(dwords);
  213.         OUT_BATCH_TABLE(atom->cmd, dwords);
  214.         END_BATCH();
  215.  
  216.         radeon->query.current->emitted_begin = GL_TRUE;
  217. }
  218.