Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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.    /* CACHE_NEW_VS_PROG */
  56.    unsigned vs_size = MAX2(brw->vs.prog_data->base.urb_entry_size, 1);
  57.  
  58.    /* We use the same VUE layout for VS outputs and GS outputs (as it's what
  59.     * the SF and Clipper expect), so we can simply make the GS URB entry size
  60.     * the same as for the VS.  This may technically be too large in cases
  61.     * where we have few vertex attributes and a lot of varyings, since the VS
  62.     * size is determined by the larger of the two.  For now, it's safe.
  63.     */
  64.    unsigned gs_size = vs_size;
  65.  
  66.    /* Calculate how many entries fit in each stage's section of the URB */
  67.    if (brw->gs.prog_active) {
  68.       nr_vs_entries = (total_urb_size/2) / (vs_size * 128);
  69.       nr_gs_entries = (total_urb_size/2) / (gs_size * 128);
  70.    } else {
  71.       nr_vs_entries = total_urb_size / (vs_size * 128);
  72.       nr_gs_entries = 0;
  73.    }
  74.  
  75.    /* Then clamp to the maximum allowed by the hardware */
  76.    if (nr_vs_entries > brw->urb.max_vs_entries)
  77.       nr_vs_entries = brw->urb.max_vs_entries;
  78.  
  79.    if (nr_gs_entries > brw->urb.max_gs_entries)
  80.       nr_gs_entries = brw->urb.max_gs_entries;
  81.  
  82.    /* Finally, both must be a multiple of 4 (see 3DSTATE_URB in the PRM). */
  83.    brw->urb.nr_vs_entries = ROUND_DOWN_TO(nr_vs_entries, 4);
  84.    brw->urb.nr_gs_entries = ROUND_DOWN_TO(nr_gs_entries, 4);
  85.  
  86.    assert(brw->urb.nr_vs_entries >= 24);
  87.    assert(brw->urb.nr_vs_entries % 4 == 0);
  88.    assert(brw->urb.nr_gs_entries % 4 == 0);
  89.    assert(vs_size < 5);
  90.    assert(gs_size < 5);
  91.  
  92.    BEGIN_BATCH(3);
  93.    OUT_BATCH(_3DSTATE_URB << 16 | (3 - 2));
  94.    OUT_BATCH(((vs_size - 1) << GEN6_URB_VS_SIZE_SHIFT) |
  95.              ((brw->urb.nr_vs_entries) << GEN6_URB_VS_ENTRIES_SHIFT));
  96.    OUT_BATCH(((gs_size - 1) << GEN6_URB_GS_SIZE_SHIFT) |
  97.              ((brw->urb.nr_gs_entries) << GEN6_URB_GS_ENTRIES_SHIFT));
  98.    ADVANCE_BATCH();
  99.  
  100.    /* From the PRM Volume 2 part 1, section 1.4.7:
  101.     *
  102.     *   Because of a urb corruption caused by allocating a previous gsunit’s
  103.     *   urb entry to vsunit software is required to send a "GS NULL
  104.     *   Fence"(Send URB fence with VS URB size == 1 and GS URB size == 0) plus
  105.     *   a dummy DRAW call before any case where VS will be taking over GS URB
  106.     *   space.
  107.     *
  108.     * It is not clear exactly what this means ("URB fence" is a command that
  109.     * doesn't exist on Gen6).  So for now we just do a full pipeline flush as
  110.     * a workaround.
  111.     */
  112.    if (brw->urb.gen6_gs_previously_active && !brw->gs.prog_active)
  113.       intel_batchbuffer_emit_mi_flush(brw);
  114.    brw->urb.gen6_gs_previously_active = brw->gs.prog_active;
  115. }
  116.  
  117. const struct brw_tracked_state gen6_urb = {
  118.    .dirty = {
  119.       .mesa = 0,
  120.       .brw = BRW_NEW_CONTEXT,
  121.       .cache = (CACHE_NEW_VS_PROG | CACHE_NEW_GS_PROG),
  122.    },
  123.    .emit = gen6_upload_urb,
  124. };
  125.