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