Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2012 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.  *    Jordan Justen <jordan.l.justen@intel.com>
  25.  *
  26.  */
  27.  
  28. #include "main/imports.h"
  29. #include "main/bufferobj.h"
  30. #include "main/varray.h"
  31.  
  32. #include "brw_context.h"
  33. #include "brw_defines.h"
  34. #include "brw_draw.h"
  35.  
  36. #include "intel_batchbuffer.h"
  37.  
  38. /**
  39.  * Check if the hardware's cut index support can handle the primitive
  40.  * restart index value (pre-Haswell only).
  41.  */
  42. static bool
  43. can_cut_index_handle_restart_index(struct gl_context *ctx,
  44.                                    const struct _mesa_index_buffer *ib)
  45. {
  46.    /* The FixedIndex variant means 0xFF, 0xFFFF, or 0xFFFFFFFF based on
  47.     * the index buffer type, which corresponds exactly to the hardware.
  48.     */
  49.    if (ctx->Array.PrimitiveRestartFixedIndex)
  50.       return true;
  51.  
  52.    bool cut_index_will_work;
  53.  
  54.    switch (ib->type) {
  55.    case GL_UNSIGNED_BYTE:
  56.       cut_index_will_work = ctx->Array.RestartIndex == 0xff;
  57.       break;
  58.    case GL_UNSIGNED_SHORT:
  59.       cut_index_will_work = ctx->Array.RestartIndex == 0xffff;
  60.       break;
  61.    case GL_UNSIGNED_INT:
  62.       cut_index_will_work = ctx->Array.RestartIndex == 0xffffffff;
  63.       break;
  64.    default:
  65.       cut_index_will_work = false;
  66.       assert(0);
  67.    }
  68.  
  69.    return cut_index_will_work;
  70. }
  71.  
  72. /**
  73.  * Check if the hardware's cut index support can handle the primitive
  74.  * restart case.
  75.  */
  76. static bool
  77. can_cut_index_handle_prims(struct gl_context *ctx,
  78.                            const struct _mesa_prim *prim,
  79.                            GLuint nr_prims,
  80.                            const struct _mesa_index_buffer *ib)
  81. {
  82.    struct brw_context *brw = brw_context(ctx);
  83.  
  84.    /* Otherwise Haswell can do it all. */
  85.    if (brw->gen >= 8 || brw->is_haswell)
  86.       return true;
  87.  
  88.    if (!can_cut_index_handle_restart_index(ctx, ib)) {
  89.       /* The primitive restart index can't be handled, so take
  90.        * the software path
  91.        */
  92.       return false;
  93.    }
  94.  
  95.    for ( ; nr_prims > 0; nr_prims--) {
  96.       switch(prim->mode) {
  97.       case GL_POINTS:
  98.       case GL_LINES:
  99.       case GL_LINE_STRIP:
  100.       case GL_TRIANGLES:
  101.       case GL_TRIANGLE_STRIP:
  102.          /* Cut index supports these primitive types */
  103.          break;
  104.       default:
  105.          /* Cut index does not support these primitive types */
  106.       //case GL_LINE_LOOP:
  107.       //case GL_TRIANGLE_FAN:
  108.       //case GL_QUADS:
  109.       //case GL_QUAD_STRIP:
  110.       //case GL_POLYGON:
  111.          return false;
  112.       }
  113.    }
  114.  
  115.    return true;
  116. }
  117.  
  118. /**
  119.  * Check if primitive restart is enabled, and if so, handle it properly.
  120.  *
  121.  * In some cases the support will be handled in software. When available
  122.  * hardware will handle primitive restart.
  123.  */
  124. GLboolean
  125. brw_handle_primitive_restart(struct gl_context *ctx,
  126.                              const struct _mesa_prim *prim,
  127.                              GLuint nr_prims,
  128.                              const struct _mesa_index_buffer *ib)
  129. {
  130.    struct brw_context *brw = brw_context(ctx);
  131.  
  132.    /* We only need to handle cases where there is an index buffer. */
  133.    if (ib == NULL) {
  134.       return GL_FALSE;
  135.    }
  136.  
  137.    /* If the driver has requested software handling of primitive restarts,
  138.     * then the VBO module has already taken care of things, and we can
  139.     * just draw as normal.
  140.     */
  141.    if (ctx->Const.PrimitiveRestartInSoftware) {
  142.       return GL_FALSE;
  143.    }
  144.  
  145.    /* If we have set the in_progress flag, then we are in the middle
  146.     * of handling the primitive restart draw.
  147.     */
  148.    if (brw->prim_restart.in_progress) {
  149.       return GL_FALSE;
  150.    }
  151.  
  152.    /* If PrimitiveRestart is not enabled, then we aren't concerned about
  153.     * handling this draw.
  154.     */
  155.    if (!(ctx->Array._PrimitiveRestart)) {
  156.       return GL_FALSE;
  157.    }
  158.  
  159.    /* Signal that we are in the process of handling the
  160.     * primitive restart draw
  161.     */
  162.    brw->prim_restart.in_progress = true;
  163.  
  164.    if (can_cut_index_handle_prims(ctx, prim, nr_prims, ib)) {
  165.       /* Cut index should work for primitive restart, so use it
  166.        */
  167.       brw->prim_restart.enable_cut_index = true;
  168.       brw_draw_prims(ctx, prim, nr_prims, ib, GL_FALSE, -1, -1, NULL);
  169.       brw->prim_restart.enable_cut_index = false;
  170.    } else {
  171.       /* Not all the primitive draw modes are supported by the cut index,
  172.        * so take the software path
  173.        */
  174.       vbo_sw_primitive_restart(ctx, prim, nr_prims, ib);
  175.    }
  176.  
  177.    brw->prim_restart.in_progress = false;
  178.  
  179.    /* The primitive restart draw was completed, so return true. */
  180.    return GL_TRUE;
  181. }
  182.  
  183. static void
  184. haswell_upload_cut_index(struct brw_context *brw)
  185. {
  186.    struct gl_context *ctx = &brw->ctx;
  187.  
  188.    /* Don't trigger on Ivybridge */
  189.    if (!brw->is_haswell)
  190.       return;
  191.  
  192.    const unsigned cut_index_setting =
  193.       ctx->Array._PrimitiveRestart ? HSW_CUT_INDEX_ENABLE : 0;
  194.  
  195.    /* BRW_NEW_INDEX_BUFFER */
  196.    unsigned cut_index;
  197.    if (brw->ib.ib) {
  198.       cut_index = _mesa_primitive_restart_index(ctx, brw->ib.type);
  199.    } else {
  200.       /* There's no index buffer, but primitive restart may still apply
  201.        * to glDrawArrays and such.  FIXED_INDEX mode only applies to drawing
  202.        * operations that use an index buffer, so we can ignore it and use
  203.        * the GL restart index directly.
  204.        */
  205.       cut_index = ctx->Array.RestartIndex;
  206.    }
  207.  
  208.    BEGIN_BATCH(2);
  209.    OUT_BATCH(_3DSTATE_VF << 16 | cut_index_setting | (2 - 2));
  210.    OUT_BATCH(cut_index);
  211.    ADVANCE_BATCH();
  212. }
  213.  
  214. const struct brw_tracked_state haswell_cut_index = {
  215.    .dirty = {
  216.       .mesa  = _NEW_TRANSFORM,
  217.       .brw   = BRW_NEW_INDEX_BUFFER,
  218.       .cache = 0,
  219.    },
  220.    .emit = haswell_upload_cut_index,
  221. };
  222.