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