Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright © 2011 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.  
  24. #include "main/macros.h"
  25. #include "intel_batchbuffer.h"
  26. #include "brw_context.h"
  27. #include "brw_state.h"
  28. #include "brw_defines.h"
  29.  
  30. /**
  31.  * The following diagram shows how we partition the URB:
  32.  *
  33.  *      8kB         8kB              Rest of the URB space
  34.  *   ____-____   ____-____   _________________-_________________
  35.  *  /         \ /         \ /                                   \
  36.  * +-------------------------------------------------------------+
  37.  * | VS Push   | FS Push   | VS                                  |
  38.  * | Constants | Constants | Handles                             |
  39.  * +-------------------------------------------------------------+
  40.  *
  41.  * Notably, push constants must be stored at the beginning of the URB
  42.  * space, while entries can be stored anywhere.  Ivybridge and Haswell
  43.  * GT1/GT2 have a maximum constant buffer size of 16kB, while Haswell GT3
  44.  * doubles this (32kB).
  45.  *
  46.  * Currently we split the constant buffer space evenly between VS and FS.
  47.  * This is probably not ideal, but simple.
  48.  *
  49.  * Ivybridge GT1 and Haswell GT1 have 128kB of URB space.
  50.  * Ivybridge GT2 and Haswell GT2 have 256kB of URB space.
  51.  * Haswell GT3 has 512kB of URB space.
  52.  *
  53.  * See "Volume 2a: 3D Pipeline," section 1.8, "Volume 1b: Configurations",
  54.  * and the documentation for 3DSTATE_PUSH_CONSTANT_ALLOC_xS.
  55.  */
  56. void
  57. gen7_allocate_push_constants(struct brw_context *brw)
  58. {
  59.    unsigned size = 8;
  60.    if (brw->is_haswell && brw->gt == 3)
  61.       size = 16;
  62.  
  63.    BEGIN_BATCH(4);
  64.    OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_VS << 16 | (2 - 2));
  65.    OUT_BATCH(size);
  66.  
  67.    OUT_BATCH(_3DSTATE_PUSH_CONSTANT_ALLOC_PS << 16 | (2 - 2));
  68.    OUT_BATCH(size | size << GEN7_PUSH_CONSTANT_BUFFER_OFFSET_SHIFT);
  69.    ADVANCE_BATCH();
  70. }
  71.  
  72. static void
  73. gen7_upload_urb(struct brw_context *brw)
  74. {
  75.    const int push_size_kB = brw->is_haswell && brw->gt == 3 ? 32 : 16;
  76.  
  77.    /* Total space for entries is URB size - 16kB for push constants */
  78.    int handle_region_size = (brw->urb.size - push_size_kB) * 1024; /* bytes */
  79.  
  80.    /* CACHE_NEW_VS_PROG */
  81.    unsigned vs_size = MAX2(brw->vs.prog_data->base.urb_entry_size, 1);
  82.  
  83.    int nr_vs_entries = handle_region_size / (vs_size * 64);
  84.    if (nr_vs_entries > brw->urb.max_vs_entries)
  85.       nr_vs_entries = brw->urb.max_vs_entries;
  86.  
  87.    /* According to volume 2a, nr_vs_entries must be a multiple of 8. */
  88.    brw->urb.nr_vs_entries = ROUND_DOWN_TO(nr_vs_entries, 8);
  89.  
  90.    /* URB Starting Addresses are specified in multiples of 8kB. */
  91.    brw->urb.vs_start = push_size_kB / 8; /* skip over push constants */
  92.  
  93.    assert(brw->urb.nr_vs_entries % 8 == 0);
  94.    assert(brw->urb.nr_gs_entries % 8 == 0);
  95.    /* GS requirement */
  96.    assert(!brw->gs.prog_active);
  97.  
  98.    gen7_emit_vs_workaround_flush(brw);
  99.    gen7_emit_urb_state(brw, brw->urb.nr_vs_entries, vs_size, brw->urb.vs_start);
  100. }
  101.  
  102. void
  103. gen7_emit_urb_state(struct brw_context *brw, GLuint nr_vs_entries,
  104.                     GLuint vs_size, GLuint vs_start)
  105. {
  106.    BEGIN_BATCH(8);
  107.    OUT_BATCH(_3DSTATE_URB_VS << 16 | (2 - 2));
  108.    OUT_BATCH(nr_vs_entries |
  109.              ((vs_size - 1) << GEN7_URB_ENTRY_SIZE_SHIFT) |
  110.              (vs_start << GEN7_URB_STARTING_ADDRESS_SHIFT));
  111.  
  112.    /* Allocate the GS, HS, and DS zero space - we don't use them. */
  113.    OUT_BATCH(_3DSTATE_URB_GS << 16 | (2 - 2));
  114.    OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
  115.              (vs_start << GEN7_URB_STARTING_ADDRESS_SHIFT));
  116.  
  117.    OUT_BATCH(_3DSTATE_URB_HS << 16 | (2 - 2));
  118.    OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
  119.              (vs_start << GEN7_URB_STARTING_ADDRESS_SHIFT));
  120.  
  121.    OUT_BATCH(_3DSTATE_URB_DS << 16 | (2 - 2));
  122.    OUT_BATCH((0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
  123.              (vs_start << GEN7_URB_STARTING_ADDRESS_SHIFT));
  124.    ADVANCE_BATCH();
  125. }
  126.  
  127. const struct brw_tracked_state gen7_urb = {
  128.    .dirty = {
  129.       .mesa = 0,
  130.       .brw = BRW_NEW_CONTEXT,
  131.       .cache = (CACHE_NEW_VS_PROG | CACHE_NEW_GS_PROG),
  132.    },
  133.    .emit = gen7_upload_urb,
  134. };
  135.