Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2013 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
  21.  * DEALINGS IN THE SOFTWARE.
  22.  */
  23.  
  24. #include "brw_context.h"
  25. #include "brw_state.h"
  26. #include "brw_defines.h"
  27. #include "intel_batchbuffer.h"
  28.  
  29. static void
  30. upload_gs_state(struct brw_context *brw)
  31. {
  32.    const struct brw_stage_state *stage_state = &brw->gs.base;
  33.    const int max_threads_shift = brw->is_haswell ?
  34.       HSW_GS_MAX_THREADS_SHIFT : GEN6_GS_MAX_THREADS_SHIFT;
  35.    /* BRW_NEW_GEOMETRY_PROGRAM */
  36.    bool active = brw->geometry_program;
  37.    /* BRW_NEW_GS_PROG_DATA */
  38.    const struct brw_vue_prog_data *prog_data = &brw->gs.prog_data->base;
  39.  
  40.    /**
  41.     * From Graphics BSpec: 3D-Media-GPGPU Engine > 3D Pipeline Stages >
  42.     * Geometry > Geometry Shader > State:
  43.     *
  44.     *     "Note: Because of corruption in IVB:GT2, software needs to flush the
  45.     *     whole fixed function pipeline when the GS enable changes value in
  46.     *     the 3DSTATE_GS."
  47.     *
  48.     * The hardware architects have clarified that in this context "flush the
  49.     * whole fixed function pipeline" means to emit a PIPE_CONTROL with the "CS
  50.     * Stall" bit set.
  51.     */
  52.    if (!brw->is_haswell && brw->gt == 2 && brw->gs.enabled != active)
  53.       gen7_emit_cs_stall_flush(brw);
  54.  
  55.    if (active) {
  56.       BEGIN_BATCH(7);
  57.       OUT_BATCH(_3DSTATE_GS << 16 | (7 - 2));
  58.       OUT_BATCH(stage_state->prog_offset);
  59.       OUT_BATCH(((ALIGN(stage_state->sampler_count, 4)/4) <<
  60.                  GEN6_GS_SAMPLER_COUNT_SHIFT) |
  61.                 ((brw->gs.prog_data->base.base.binding_table.size_bytes / 4) <<
  62.                  GEN6_GS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
  63.  
  64.       if (brw->gs.prog_data->base.base.total_scratch) {
  65.          OUT_RELOC(stage_state->scratch_bo,
  66.                    I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
  67.                    ffs(brw->gs.prog_data->base.base.total_scratch) - 11);
  68.       } else {
  69.          OUT_BATCH(0);
  70.       }
  71.  
  72.       uint32_t dw4 =
  73.          ((brw->gs.prog_data->output_vertex_size_hwords * 2 - 1) <<
  74.           GEN7_GS_OUTPUT_VERTEX_SIZE_SHIFT) |
  75.          (brw->gs.prog_data->output_topology <<
  76.           GEN7_GS_OUTPUT_TOPOLOGY_SHIFT) |
  77.          (prog_data->urb_read_length <<
  78.           GEN6_GS_URB_READ_LENGTH_SHIFT) |
  79.          (0 << GEN6_GS_URB_ENTRY_READ_OFFSET_SHIFT) |
  80.          (prog_data->base.dispatch_grf_start_reg <<
  81.           GEN6_GS_DISPATCH_START_GRF_SHIFT);
  82.  
  83.       /* Note: the meaning of the GEN7_GS_REORDER_TRAILING bit changes between
  84.        * Ivy Bridge and Haswell.
  85.        *
  86.        * On Ivy Bridge, setting this bit causes the vertices of a triangle
  87.        * strip to be delivered to the geometry shader in an order that does
  88.        * not strictly follow the OpenGL spec, but preserves triangle
  89.        * orientation.  For example, if the vertices are (1, 2, 3, 4, 5), then
  90.        * the geometry shader sees triangles:
  91.        *
  92.        * (1, 2, 3), (2, 4, 3), (3, 4, 5)
  93.        *
  94.        * (Clearing the bit is even worse, because it fails to preserve
  95.        * orientation).
  96.        *
  97.        * Triangle strips with adjacency always ordered in a way that preserves
  98.        * triangle orientation but does not strictly follow the OpenGL spec,
  99.        * regardless of the setting of this bit.
  100.        *
  101.        * On Haswell, both triangle strips and triangle strips with adjacency
  102.        * are always ordered in a way that preserves triangle orientation.
  103.        * Setting this bit causes the ordering to strictly follow the OpenGL
  104.        * spec.
  105.        *
  106.        * So in either case we want to set the bit.  Unfortunately on Ivy
  107.        * Bridge this will get the order close to correct but not perfect.
  108.        */
  109.       uint32_t dw5 =
  110.          ((brw->max_gs_threads - 1) << max_threads_shift) |
  111.          (brw->gs.prog_data->control_data_header_size_hwords <<
  112.           GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT) |
  113.          ((brw->gs.prog_data->invocations - 1) <<
  114.           GEN7_GS_INSTANCE_CONTROL_SHIFT) |
  115.          brw->gs.prog_data->dispatch_mode |
  116.          GEN6_GS_STATISTICS_ENABLE |
  117.          (brw->gs.prog_data->include_primitive_id ?
  118.           GEN7_GS_INCLUDE_PRIMITIVE_ID : 0) |
  119.          GEN7_GS_REORDER_TRAILING |
  120.          GEN7_GS_ENABLE;
  121.       uint32_t dw6 = 0;
  122.  
  123.       if (brw->is_haswell) {
  124.          dw6 |= brw->gs.prog_data->control_data_format <<
  125.             HSW_GS_CONTROL_DATA_FORMAT_SHIFT;
  126.       } else {
  127.          dw5 |= brw->gs.prog_data->control_data_format <<
  128.             IVB_GS_CONTROL_DATA_FORMAT_SHIFT;
  129.       }
  130.  
  131.       OUT_BATCH(dw4);
  132.       OUT_BATCH(dw5);
  133.       OUT_BATCH(dw6);
  134.       ADVANCE_BATCH();
  135.    } else {
  136.       BEGIN_BATCH(7);
  137.       OUT_BATCH(_3DSTATE_GS << 16 | (7 - 2));
  138.       OUT_BATCH(0); /* prog_bo */
  139.       OUT_BATCH((0 << GEN6_GS_SAMPLER_COUNT_SHIFT) |
  140.                 (0 << GEN6_GS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
  141.       OUT_BATCH(0); /* scratch space base offset */
  142.       OUT_BATCH((1 << GEN6_GS_DISPATCH_START_GRF_SHIFT) |
  143.                 (0 << GEN6_GS_URB_READ_LENGTH_SHIFT) |
  144.                 GEN7_GS_INCLUDE_VERTEX_HANDLES |
  145.                 (0 << GEN6_GS_URB_ENTRY_READ_OFFSET_SHIFT));
  146.       OUT_BATCH((0 << GEN6_GS_MAX_THREADS_SHIFT) |
  147.                 GEN6_GS_STATISTICS_ENABLE);
  148.       OUT_BATCH(0);
  149.       ADVANCE_BATCH();
  150.    }
  151.    brw->gs.enabled = active;
  152. }
  153.  
  154. const struct brw_tracked_state gen7_gs_state = {
  155.    .dirty = {
  156.       .mesa  = _NEW_TRANSFORM,
  157.       .brw   = BRW_NEW_BATCH |
  158.                BRW_NEW_CONTEXT |
  159.                BRW_NEW_GEOMETRY_PROGRAM |
  160.                BRW_NEW_GS_PROG_DATA,
  161.    },
  162.    .emit = upload_gs_state,
  163. };
  164.