Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2009 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.  *    Eric Anholt <eric@anholt.net>
  25.  *
  26.  */
  27.  
  28. #include "main/macros.h"
  29. #include "intel_batchbuffer.h"
  30. #include "brw_context.h"
  31. #include "brw_state.h"
  32. #include "brw_defines.h"
  33.  
  34. /**
  35.  * When the GS is not in use, we assign the entire URB space to the VS.  When
  36.  * the GS is in use, we split the URB space evenly between the VS and the GS.
  37.  * This is not ideal, but it's simple.
  38.  *
  39.  *           URB size / 2                   URB size / 2
  40.  *   _____________-______________   _____________-______________
  41.  *  /                            \ /                            \
  42.  * +-------------------------------------------------------------+
  43.  * | Vertex Shader Entries        | Geometry Shader Entries      |
  44.  * +-------------------------------------------------------------+
  45.  *
  46.  * Sandybridge GT1 has 32kB of URB space, while GT2 has 64kB.
  47.  * (See the Sandybridge PRM, Volume 2, Part 1, Section 1.4.7: 3DSTATE_URB.)
  48.  */
  49. static void
  50. gen6_upload_urb( struct brw_context *brw )
  51. {
  52.    int nr_vs_entries, nr_gs_entries;
  53.    int total_urb_size = brw->urb.size * 1024; /* in bytes */
  54.  
  55.    bool gs_present = brw->ff_gs.prog_active || brw->geometry_program;
  56.  
  57.    /* BRW_NEW_VS_PROG_DATA */
  58.    unsigned vs_size = MAX2(brw->vs.prog_data->base.urb_entry_size, 1);
  59.  
  60.    /* Whe using GS to do transform feedback only we use the same VUE layout for
  61.     * VS outputs and GS outputs (as it's what the SF and Clipper expect), so we
  62.     * can simply make the GS URB entry size the same as for the VS.  This may
  63.     * technically be too large in cases where we have few vertex attributes and
  64.     * a lot of varyings, since the VS size is determined by the larger of the
  65.     * two. For now, it's safe.
  66.     *
  67.     * For user-provided GS the assumption above does not hold since the GS
  68.     * outputs can be different from the VS outputs.
  69.     */
  70.    unsigned gs_size = vs_size;
  71.    if (brw->geometry_program) {
  72.       gs_size = brw->gs.prog_data->base.urb_entry_size;
  73.       assert(gs_size >= 1);
  74.    }
  75.  
  76.    /* Calculate how many entries fit in each stage's section of the URB */
  77.    if (gs_present) {
  78.       nr_vs_entries = (total_urb_size/2) / (vs_size * 128);
  79.       nr_gs_entries = (total_urb_size/2) / (gs_size * 128);
  80.    } else {
  81.       nr_vs_entries = total_urb_size / (vs_size * 128);
  82.       nr_gs_entries = 0;
  83.    }
  84.  
  85.    /* Then clamp to the maximum allowed by the hardware */
  86.    if (nr_vs_entries > brw->urb.max_vs_entries)
  87.       nr_vs_entries = brw->urb.max_vs_entries;
  88.  
  89.    if (nr_gs_entries > brw->urb.max_gs_entries)
  90.       nr_gs_entries = brw->urb.max_gs_entries;
  91.  
  92.    /* Finally, both must be a multiple of 4 (see 3DSTATE_URB in the PRM). */
  93.    brw->urb.nr_vs_entries = ROUND_DOWN_TO(nr_vs_entries, 4);
  94.    brw->urb.nr_gs_entries = ROUND_DOWN_TO(nr_gs_entries, 4);
  95.  
  96.    assert(brw->urb.nr_vs_entries >= brw->urb.min_vs_entries);
  97.    assert(brw->urb.nr_vs_entries % 4 == 0);
  98.    assert(brw->urb.nr_gs_entries % 4 == 0);
  99.    assert(vs_size <= 5);
  100.    assert(gs_size <= 5);
  101.  
  102.    BEGIN_BATCH(3);
  103.    OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2));
  104.    OUT_BATCH(((vs_size - 1) << GEN6_URB_VS_SIZE_SHIFT) |
  105.              ((brw->urb.nr_vs_entries) << GEN6_URB_VS_ENTRIES_SHIFT));
  106.    OUT_BATCH(((gs_size - 1) << GEN6_URB_GS_SIZE_SHIFT) |
  107.              ((brw->urb.nr_gs_entries) << GEN6_URB_GS_ENTRIES_SHIFT));
  108.    ADVANCE_BATCH();
  109.  
  110.    /* From the PRM Volume 2 part 1, section 1.4.7:
  111.     *
  112.     *   Because of a urb corruption caused by allocating a previous gsunit’s
  113.     *   urb entry to vsunit software is required to send a "GS NULL
  114.     *   Fence"(Send URB fence with VS URB size == 1 and GS URB size == 0) plus
  115.     *   a dummy DRAW call before any case where VS will be taking over GS URB
  116.     *   space.
  117.     *
  118.     * It is not clear exactly what this means ("URB fence" is a command that
  119.     * doesn't exist on Gen6).  So for now we just do a full pipeline flush as
  120.     * a workaround.
  121.     */
  122.    if (brw->urb.gs_present && !gs_present)
  123.       intel_batchbuffer_emit_mi_flush(brw);
  124.    brw->urb.gs_present = gs_present;
  125. }
  126.  
  127. const struct brw_tracked_state gen6_urb = {
  128.    .dirty = {
  129.       .mesa = 0,
  130.       .brw = BRW_NEW_CONTEXT |
  131.              BRW_NEW_FF_GS_PROG_DATA |
  132.              BRW_NEW_GEOMETRY_PROGRAM |
  133.              BRW_NEW_GS_PROG_DATA |
  134.              BRW_NEW_VS_PROG_DATA,
  135.    },
  136.    .emit = gen6_upload_urb,
  137. };
  138.