• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
gen8_upload_gs_state(struct brw_context * brw)30 gen8_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    /* BRW_NEW_GEOMETRY_PROGRAM */
35    bool active = brw->geometry_program;
36    /* BRW_NEW_GS_PROG_DATA */
37    const struct brw_stage_prog_data *prog_data = stage_state->prog_data;
38    const struct brw_vue_prog_data *vue_prog_data =
39       brw_vue_prog_data(stage_state->prog_data);
40    const struct brw_gs_prog_data *gs_prog_data =
41       brw_gs_prog_data(stage_state->prog_data);
42 
43    if (active) {
44       int urb_entry_write_offset = 1;
45       uint32_t urb_entry_output_length =
46          ((vue_prog_data->vue_map.num_slots + 1) / 2 - urb_entry_write_offset);
47 
48       if (urb_entry_output_length == 0)
49          urb_entry_output_length = 1;
50 
51       BEGIN_BATCH(10);
52       OUT_BATCH(_3DSTATE_GS << 16 | (10 - 2));
53       OUT_BATCH(stage_state->prog_offset);
54       OUT_BATCH(0);
55       OUT_BATCH(gs_prog_data->vertices_in |
56                 ((ALIGN(stage_state->sampler_count, 4)/4) <<
57                  GEN6_GS_SAMPLER_COUNT_SHIFT) |
58                 ((prog_data->binding_table.size_bytes / 4) <<
59                  GEN6_GS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
60 
61       if (prog_data->total_scratch) {
62          OUT_RELOC64(stage_state->scratch_bo,
63                      I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
64                      ffs(stage_state->per_thread_scratch) - 11);
65       } else {
66          OUT_BATCH(0);
67          OUT_BATCH(0);
68       }
69 
70       /* DW6 */
71       OUT_BATCH(((gs_prog_data->output_vertex_size_hwords * 2 - 1) <<
72                  GEN7_GS_OUTPUT_VERTEX_SIZE_SHIFT) |
73                 (gs_prog_data->output_topology <<
74                  GEN7_GS_OUTPUT_TOPOLOGY_SHIFT) |
75                 (vue_prog_data->include_vue_handles ?
76                  GEN7_GS_INCLUDE_VERTEX_HANDLES : 0) |
77                 (vue_prog_data->urb_read_length <<
78                  GEN6_GS_URB_READ_LENGTH_SHIFT) |
79                 (0 << GEN6_GS_URB_ENTRY_READ_OFFSET_SHIFT) |
80                 (prog_data->dispatch_grf_start_reg <<
81                  GEN6_GS_DISPATCH_START_GRF_SHIFT));
82 
83       uint32_t dw7 = (gs_prog_data->control_data_header_size_hwords <<
84                       GEN7_GS_CONTROL_DATA_HEADER_SIZE_SHIFT) |
85                      SET_FIELD(vue_prog_data->dispatch_mode,
86                                GEN7_GS_DISPATCH_MODE) |
87                      ((gs_prog_data->invocations - 1) <<
88                       GEN7_GS_INSTANCE_CONTROL_SHIFT) |
89                       GEN6_GS_STATISTICS_ENABLE |
90                       (gs_prog_data->include_primitive_id ?
91                        GEN7_GS_INCLUDE_PRIMITIVE_ID : 0) |
92                       GEN7_GS_REORDER_TRAILING |
93                       GEN7_GS_ENABLE;
94       uint32_t dw8 = gs_prog_data->control_data_format <<
95                      HSW_GS_CONTROL_DATA_FORMAT_SHIFT;
96 
97       if (gs_prog_data->static_vertex_count != -1) {
98          dw8 |= GEN8_GS_STATIC_OUTPUT |
99                 SET_FIELD(gs_prog_data->static_vertex_count,
100                           GEN8_GS_STATIC_VERTEX_COUNT);
101       }
102 
103       if (brw->gen < 9)
104          dw7 |= (devinfo->max_gs_threads / 2 - 1) << HSW_GS_MAX_THREADS_SHIFT;
105       else
106          dw8 |= devinfo->max_gs_threads - 1;
107 
108       /* DW7 */
109       OUT_BATCH(dw7);
110 
111       /* DW8 */
112       OUT_BATCH(dw8);
113 
114       /* DW9 */
115       OUT_BATCH(vue_prog_data->cull_distance_mask |
116                 (urb_entry_output_length << GEN8_GS_URB_OUTPUT_LENGTH_SHIFT) |
117                 (urb_entry_write_offset <<
118                  GEN8_GS_URB_ENTRY_OUTPUT_OFFSET_SHIFT));
119       ADVANCE_BATCH();
120    } else {
121       BEGIN_BATCH(10);
122       OUT_BATCH(_3DSTATE_GS << 16 | (10 - 2));
123       OUT_BATCH(0); /* prog_bo */
124       OUT_BATCH(0);
125       OUT_BATCH(0);
126       OUT_BATCH(0); /* scratch space base offset */
127       OUT_BATCH(0);
128       OUT_BATCH(0);
129       OUT_BATCH(GEN6_GS_STATISTICS_ENABLE);
130       OUT_BATCH(0);
131       OUT_BATCH(0);
132       ADVANCE_BATCH();
133    }
134 }
135 
136 const struct brw_tracked_state gen8_gs_state = {
137    .dirty = {
138       .mesa  = 0,
139       .brw   = BRW_NEW_BATCH |
140                BRW_NEW_BLORP |
141                BRW_NEW_CONTEXT |
142                BRW_NEW_GEOMETRY_PROGRAM |
143                BRW_NEW_GS_PROG_DATA,
144    },
145    .emit = gen8_upload_gs_state,
146 };
147