Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2014 Intel Corporation
  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.  *    Neil Roberts <neil@linux.intel.com>
  25.  */
  26.  
  27. /** @file brw_conditional_render.c
  28.  *
  29.  * Support for conditional rendering based on query objects
  30.  * (GL_NV_conditional_render, GL_ARB_conditional_render_inverted) on Gen7+.
  31.  */
  32.  
  33. #include "main/imports.h"
  34. #include "main/condrender.h"
  35.  
  36. #include "brw_context.h"
  37. #include "brw_defines.h"
  38. #include "intel_batchbuffer.h"
  39.  
  40. static void
  41. set_predicate_enable(struct brw_context *brw,
  42.                      bool value)
  43. {
  44.    if (value)
  45.       brw->predicate.state = BRW_PREDICATE_STATE_RENDER;
  46.    else
  47.       brw->predicate.state = BRW_PREDICATE_STATE_DONT_RENDER;
  48. }
  49.  
  50. static void
  51. set_predicate_for_result(struct brw_context *brw,
  52.                          struct brw_query_object *query,
  53.                          bool inverted)
  54. {
  55.    int load_op;
  56.  
  57.    assert(query->bo != NULL);
  58.  
  59.    brw_load_register_mem64(brw,
  60.                            MI_PREDICATE_SRC0,
  61.                            query->bo,
  62.                            I915_GEM_DOMAIN_INSTRUCTION,
  63.                            0, /* write domain */
  64.                            0 /* offset */);
  65.    brw_load_register_mem64(brw,
  66.                            MI_PREDICATE_SRC1,
  67.                            query->bo,
  68.                            I915_GEM_DOMAIN_INSTRUCTION,
  69.                            0, /* write domain */
  70.                            8 /* offset */);
  71.  
  72.    if (inverted)
  73.       load_op = MI_PREDICATE_LOADOP_LOAD;
  74.    else
  75.       load_op = MI_PREDICATE_LOADOP_LOADINV;
  76.  
  77.    BEGIN_BATCH(1);
  78.    OUT_BATCH(GEN7_MI_PREDICATE |
  79.              load_op |
  80.              MI_PREDICATE_COMBINEOP_SET |
  81.              MI_PREDICATE_COMPAREOP_SRCS_EQUAL);
  82.    ADVANCE_BATCH();
  83.  
  84.    brw->predicate.state = BRW_PREDICATE_STATE_USE_BIT;
  85. }
  86.  
  87. static void
  88. brw_begin_conditional_render(struct gl_context *ctx,
  89.                              struct gl_query_object *q,
  90.                              GLenum mode)
  91. {
  92.    struct brw_context *brw = brw_context(ctx);
  93.    struct brw_query_object *query = (struct brw_query_object *) q;
  94.    bool inverted;
  95.  
  96.    if (!brw->predicate.supported)
  97.       return;
  98.  
  99.    switch (mode) {
  100.    case GL_QUERY_WAIT:
  101.    case GL_QUERY_NO_WAIT:
  102.    case GL_QUERY_BY_REGION_WAIT:
  103.    case GL_QUERY_BY_REGION_NO_WAIT:
  104.       inverted = false;
  105.       break;
  106.    case GL_QUERY_WAIT_INVERTED:
  107.    case GL_QUERY_NO_WAIT_INVERTED:
  108.    case GL_QUERY_BY_REGION_WAIT_INVERTED:
  109.    case GL_QUERY_BY_REGION_NO_WAIT_INVERTED:
  110.       inverted = true;
  111.       break;
  112.    default:
  113.       unreachable("Unexpected conditional render mode");
  114.    }
  115.  
  116.    /* If there are already samples from a BLT operation or if the query object
  117.     * is ready then we can avoid looking at the values in the buffer and just
  118.     * decide whether to draw using the CPU without stalling.
  119.     */
  120.    if (query->Base.Result || query->Base.Ready)
  121.       set_predicate_enable(brw, (query->Base.Result != 0) ^ inverted);
  122.    else
  123.       set_predicate_for_result(brw, query, inverted);
  124. }
  125.  
  126. static void
  127. brw_end_conditional_render(struct gl_context *ctx,
  128.                            struct gl_query_object *q)
  129. {
  130.    struct brw_context *brw = brw_context(ctx);
  131.  
  132.    /* When there is no longer a conditional render in progress it should
  133.     * always render.
  134.     */
  135.    brw->predicate.state = BRW_PREDICATE_STATE_RENDER;
  136. }
  137.  
  138. void
  139. brw_init_conditional_render_functions(struct dd_function_table *functions)
  140. {
  141.    functions->BeginConditionalRender = brw_begin_conditional_render;
  142.    functions->EndConditionalRender = brw_end_conditional_render;
  143. }
  144.  
  145. bool
  146. brw_check_conditional_render(struct brw_context *brw)
  147. {
  148.    if (brw->predicate.supported) {
  149.       /* In some cases it is possible to determine that the primitives should
  150.        * be skipped without needing the predicate enable bit and still without
  151.        * stalling.
  152.        */
  153.       return brw->predicate.state != BRW_PREDICATE_STATE_DONT_RENDER;
  154.    } else if (brw->ctx.Query.CondRenderQuery) {
  155.       perf_debug("Conditional rendering is implemented in software and may "
  156.                  "stall.\n");
  157.       return _mesa_check_conditional_render(&brw->ctx);
  158.    } else {
  159.       return true;
  160.    }
  161. }
  162.