54
54
GLuint program_size;
56
/* Gen6: VF has already converted into polygon, and LINELOOP is
57
* converted to LINESTRIP at the beginning of the 3D pipeline.
62
56
memset(&c, 0, sizeof(c));
65
/* Need to locate the two positions present in vertex + header.
66
* These are currently hardcoded:
68
c.nr_attrs = brw_count_bits(c.key.attrs);
71
c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
73
c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
75
c.nr_bytes = c.nr_regs * REG_SIZE;
59
/* The geometry shader needs to access the entire VUE. */
60
brw_compute_vue_map(&c.vue_map, intel, c.key.userclip_active, c.key.attrs);
61
c.nr_regs = (c.vue_map.num_slots + 1)/2;
88
74
brw_set_mask_control(&c.func, BRW_MASK_DISABLE);
91
/* Note that primitives which don't require a GS program have
92
* already been weeded out by this stage:
95
switch (key->primitive) {
97
brw_gs_quads( &c, key );
100
brw_gs_quad_strip( &c, key );
106
ralloc_free(mem_ctx);
76
if (intel->gen >= 6) {
79
/* On Sandybridge, we use the GS for implementing transform feedback
80
* (called "Stream Out" in the PRM).
82
switch (key->primitive) {
83
case _3DPRIM_POINTLIST:
85
check_edge_flag = false;
87
case _3DPRIM_LINELIST:
88
case _3DPRIM_LINESTRIP:
89
case _3DPRIM_LINELOOP:
91
check_edge_flag = false;
95
case _3DPRIM_TRISTRIP:
96
case _3DPRIM_RECTLIST:
98
check_edge_flag = false;
100
case _3DPRIM_QUADLIST:
101
case _3DPRIM_QUADSTRIP:
102
case _3DPRIM_POLYGON:
104
check_edge_flag = true;
107
assert(!"Unexpected primitive type in Gen6 SOL program.");
110
gen6_sol_program(&c, key, num_verts, check_edge_flag);
112
/* On Gen4-5, we use the GS to decompose certain types of primitives.
113
* Note that primitives which don't require a GS program have already
114
* been weeded out by now.
116
switch (key->primitive) {
117
case _3DPRIM_QUADLIST:
118
brw_gs_quads( &c, key );
120
case _3DPRIM_QUADSTRIP:
121
brw_gs_quad_strip( &c, key );
123
case _3DPRIM_LINELOOP:
127
ralloc_free(mem_ctx);
110
132
/* get the program
129
151
ralloc_free(mem_ctx);
132
static const GLenum gs_prim[GL_POLYGON+1] = {
145
154
static void populate_key( struct brw_context *brw,
146
155
struct brw_gs_prog_key *key )
157
static const unsigned swizzle_for_offset[4] = {
158
BRW_SWIZZLE4(0, 1, 2, 3),
159
BRW_SWIZZLE4(1, 2, 3, 3),
160
BRW_SWIZZLE4(2, 3, 3, 3),
161
BRW_SWIZZLE4(3, 3, 3, 3)
148
164
struct gl_context *ctx = &brw->intel.ctx;
149
165
struct intel_context *intel = &brw->intel;
154
170
key->attrs = brw->vs.prog_data->outputs_written;
156
172
/* BRW_NEW_PRIMITIVE */
157
key->primitive = gs_prim[brw->primitive];
173
key->primitive = brw->primitive;
160
176
key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
161
if (key->primitive == GL_QUADS && ctx->Light.ShadeModel != GL_FLAT) {
177
if (key->primitive == _3DPRIM_QUADLIST && ctx->Light.ShadeModel != GL_FLAT) {
162
178
/* Provide consistent primitive order with brw_set_prim's
163
179
* optimization of single quads to trifans.
165
key->pv_first = GL_TRUE;
168
key->need_gs_prog = (intel->gen >= 6)
170
: (brw->primitive == GL_QUADS ||
171
brw->primitive == GL_QUAD_STRIP ||
172
brw->primitive == GL_LINE_LOOP);
181
key->pv_first = true;
185
key->userclip_active = (ctx->Transform.ClipPlanesEnabled != 0);
187
if (intel->gen >= 7) {
188
/* On Gen7 and later, we don't use GS (yet). */
189
key->need_gs_prog = false;
190
} else if (intel->gen == 6) {
191
/* On Gen6, GS is used for transform feedback. */
192
/* _NEW_TRANSFORM_FEEDBACK */
193
if (ctx->TransformFeedback.CurrentObject->Active &&
194
!ctx->TransformFeedback.CurrentObject->Paused) {
195
const struct gl_shader_program *shaderprog =
196
ctx->Shader.CurrentVertexProgram;
197
const struct gl_transform_feedback_info *linked_xfb_info =
198
&shaderprog->LinkedTransformFeedback;
201
/* Make sure that the VUE slots won't overflow the unsigned chars in
202
* key->transform_feedback_bindings[].
204
STATIC_ASSERT(BRW_VERT_RESULT_MAX <= 256);
206
/* Make sure that we don't need more binding table entries than we've
207
* set aside for use in transform feedback. (We shouldn't, since we
208
* set aside enough binding table entries to have one per component).
210
assert(linked_xfb_info->NumOutputs <= BRW_MAX_SOL_BINDINGS);
212
key->need_gs_prog = true;
213
key->num_transform_feedback_bindings = linked_xfb_info->NumOutputs;
214
for (i = 0; i < key->num_transform_feedback_bindings; ++i) {
215
key->transform_feedback_bindings[i] =
216
linked_xfb_info->Outputs[i].OutputRegister;
217
key->transform_feedback_swizzles[i] =
218
swizzle_for_offset[linked_xfb_info->Outputs[i].ComponentOffset];
221
/* On Gen6, GS is also used for rasterizer discard. */
222
/* _NEW_RASTERIZER_DISCARD */
223
if (ctx->RasterDiscard) {
224
key->need_gs_prog = true;
225
key->rasterizer_discard = true;
228
/* Pre-gen6, GS is used to transform QUADLIST, QUADSTRIP, and LINELOOP
229
* into simpler primitives.
231
key->need_gs_prog = (brw->primitive == _3DPRIM_QUADLIST ||
232
brw->primitive == _3DPRIM_QUADSTRIP ||
233
brw->primitive == _3DPRIM_LINELOOP);
235
/* For testing, the environment variable INTEL_FORCE_GS can be used to
236
* force a GS program to be used, even if it's not necessary.
238
if (getenv("INTEL_FORCE_GS"))
239
key->need_gs_prog = true;
175
242
/* Calculate interpolants for triangle and line rasterization.
177
static void prepare_gs_prog(struct brw_context *brw)
245
brw_upload_gs_prog(struct brw_context *brw)
179
247
struct brw_gs_prog_key key;
180
248
/* Populate the key: