~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/intel/compiler/brw_vec4_tcs.cpp

  • Committer: mmach
  • Date: 2022-09-22 19:58:36 UTC
  • Revision ID: netbit73@gmail.com-20220922195836-9nl9joew85y8d25o
2022-07-04 12:44:28

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
/**
 
25
 * \file brw_vec4_tcs.cpp
 
26
 *
 
27
 * Tessellaton control shader specific code derived from the vec4_visitor class.
 
28
 */
 
29
 
 
30
#include "brw_nir.h"
 
31
#include "brw_vec4_tcs.h"
 
32
#include "brw_fs.h"
 
33
#include "dev/intel_debug.h"
 
34
 
 
35
namespace brw {
 
36
 
 
37
vec4_tcs_visitor::vec4_tcs_visitor(const struct brw_compiler *compiler,
 
38
                                   void *log_data,
 
39
                                   const struct brw_tcs_prog_key *key,
 
40
                                   struct brw_tcs_prog_data *prog_data,
 
41
                                   const nir_shader *nir,
 
42
                                   void *mem_ctx,
 
43
                                   bool debug_enabled)
 
44
   : vec4_visitor(compiler, log_data, &key->base.tex, &prog_data->base,
 
45
                  nir, mem_ctx, false, debug_enabled),
 
46
     key(key)
 
47
{
 
48
}
 
49
 
 
50
 
 
51
void
 
52
vec4_tcs_visitor::setup_payload()
 
53
{
 
54
   int reg = 0;
 
55
 
 
56
   /* The payload always contains important data in r0, which contains
 
57
    * the URB handles that are passed on to the URB write at the end
 
58
    * of the thread.
 
59
    */
 
60
   reg++;
 
61
 
 
62
   /* r1.0 - r4.7 may contain the input control point URB handles,
 
63
    * which we use to pull vertex data.
 
64
    */
 
65
   reg += 4;
 
66
 
 
67
   /* Push constants may start at r5.0 */
 
68
   reg = setup_uniforms(reg);
 
69
 
 
70
   this->first_non_payload_grf = reg;
 
71
}
 
72
 
 
73
 
 
74
void
 
75
vec4_tcs_visitor::emit_prolog()
 
76
{
 
77
   invocation_id = src_reg(this, glsl_type::uint_type);
 
78
   emit(TCS_OPCODE_GET_INSTANCE_ID, dst_reg(invocation_id));
 
79
 
 
80
   /* HS threads are dispatched with the dispatch mask set to 0xFF.
 
81
    * If there are an odd number of output vertices, then the final
 
82
    * HS instance dispatched will only have its bottom half doing real
 
83
    * work, and so we need to disable the upper half:
 
84
    */
 
85
   if (nir->info.tess.tcs_vertices_out % 2) {
 
86
      emit(CMP(dst_null_d(), invocation_id,
 
87
               brw_imm_ud(nir->info.tess.tcs_vertices_out),
 
88
               BRW_CONDITIONAL_L));
 
89
 
 
90
      /* Matching ENDIF is in emit_thread_end() */
 
91
      emit(IF(BRW_PREDICATE_NORMAL));
 
92
   }
 
93
}
 
94
 
 
95
 
 
96
void
 
97
vec4_tcs_visitor::emit_thread_end()
 
98
{
 
99
   vec4_instruction *inst;
 
100
   current_annotation = "thread end";
 
101
 
 
102
   if (nir->info.tess.tcs_vertices_out % 2) {
 
103
      emit(BRW_OPCODE_ENDIF);
 
104
   }
 
105
 
 
106
   if (devinfo->ver == 7) {
 
107
      struct brw_tcs_prog_data *tcs_prog_data =
 
108
         (struct brw_tcs_prog_data *) prog_data;
 
109
 
 
110
      current_annotation = "release input vertices";
 
111
 
 
112
      /* Synchronize all threads, so we know that no one is still
 
113
       * using the input URB handles.
 
114
       */
 
115
      if (tcs_prog_data->instances > 1) {
 
116
         dst_reg header = dst_reg(this, glsl_type::uvec4_type);
 
117
         emit(TCS_OPCODE_CREATE_BARRIER_HEADER, header);
 
118
         emit(SHADER_OPCODE_BARRIER, dst_null_ud(), src_reg(header));
 
119
      }
 
120
 
 
121
      /* Make thread 0 (invocations <1, 0>) release pairs of ICP handles.
 
122
       * We want to compare the bottom half of invocation_id with 0, but
 
123
       * use that truth value for the top half as well.  Unfortunately,
 
124
       * we don't have stride in the vec4 world, nor UV immediates in
 
125
       * align16, so we need an opcode to get invocation_id<0,4,0>.
 
126
       */
 
127
      set_condmod(BRW_CONDITIONAL_Z,
 
128
                  emit(TCS_OPCODE_SRC0_010_IS_ZERO, dst_null_d(),
 
129
                       invocation_id));
 
130
      emit(IF(BRW_PREDICATE_NORMAL));
 
131
      for (unsigned i = 0; i < key->input_vertices; i += 2) {
 
132
         /* If we have an odd number of input vertices, the last will be
 
133
          * unpaired.  We don't want to use an interleaved URB write in
 
134
          * that case.
 
135
          */
 
136
         const bool is_unpaired = i == key->input_vertices - 1;
 
137
 
 
138
         dst_reg header(this, glsl_type::uvec4_type);
 
139
         emit(TCS_OPCODE_RELEASE_INPUT, header, brw_imm_ud(i),
 
140
              brw_imm_ud(is_unpaired));
 
141
      }
 
142
      emit(BRW_OPCODE_ENDIF);
 
143
   }
 
144
 
 
145
   inst = emit(TCS_OPCODE_THREAD_END);
 
146
   inst->base_mrf = 14;
 
147
   inst->mlen = 2;
 
148
}
 
149
 
 
150
 
 
151
void
 
152
vec4_tcs_visitor::emit_input_urb_read(const dst_reg &dst,
 
153
                                      const src_reg &vertex_index,
 
154
                                      unsigned base_offset,
 
155
                                      unsigned first_component,
 
156
                                      const src_reg &indirect_offset)
 
157
{
 
158
   vec4_instruction *inst;
 
159
   dst_reg temp(this, glsl_type::ivec4_type);
 
160
   temp.type = dst.type;
 
161
 
 
162
   /* Set up the message header to reference the proper parts of the URB */
 
163
   dst_reg header = dst_reg(this, glsl_type::uvec4_type);
 
164
   inst = emit(TCS_OPCODE_SET_INPUT_URB_OFFSETS, header, vertex_index,
 
165
               indirect_offset);
 
166
   inst->force_writemask_all = true;
 
167
 
 
168
   /* Read into a temporary, ignoring writemasking. */
 
169
   inst = emit(VEC4_OPCODE_URB_READ, temp, src_reg(header));
 
170
   inst->offset = base_offset;
 
171
   inst->mlen = 1;
 
172
   inst->base_mrf = -1;
 
173
 
 
174
   /* Copy the temporary to the destination to deal with writemasking.
 
175
    *
 
176
    * Also attempt to deal with gl_PointSize being in the .w component.
 
177
    */
 
178
   if (inst->offset == 0 && indirect_offset.file == BAD_FILE) {
 
179
      emit(MOV(dst, swizzle(src_reg(temp), BRW_SWIZZLE_WWWW)));
 
180
   } else {
 
181
      src_reg src = src_reg(temp);
 
182
      src.swizzle = BRW_SWZ_COMP_INPUT(first_component);
 
183
      emit(MOV(dst, src));
 
184
   }
 
185
}
 
186
 
 
187
void
 
188
vec4_tcs_visitor::emit_output_urb_read(const dst_reg &dst,
 
189
                                       unsigned base_offset,
 
190
                                       unsigned first_component,
 
191
                                       const src_reg &indirect_offset)
 
192
{
 
193
   vec4_instruction *inst;
 
194
 
 
195
   /* Set up the message header to reference the proper parts of the URB */
 
196
   dst_reg header = dst_reg(this, glsl_type::uvec4_type);
 
197
   inst = emit(TCS_OPCODE_SET_OUTPUT_URB_OFFSETS, header,
 
198
               brw_imm_ud(dst.writemask << first_component), indirect_offset);
 
199
   inst->force_writemask_all = true;
 
200
 
 
201
   vec4_instruction *read = emit(VEC4_OPCODE_URB_READ, dst, src_reg(header));
 
202
   read->offset = base_offset;
 
203
   read->mlen = 1;
 
204
   read->base_mrf = -1;
 
205
 
 
206
   if (first_component) {
 
207
      /* Read into a temporary and copy with a swizzle and writemask. */
 
208
      read->dst = retype(dst_reg(this, glsl_type::ivec4_type), dst.type);
 
209
      emit(MOV(dst, swizzle(src_reg(read->dst),
 
210
                            BRW_SWZ_COMP_INPUT(first_component))));
 
211
   }
 
212
}
 
213
 
 
214
void
 
215
vec4_tcs_visitor::emit_urb_write(const src_reg &value,
 
216
                                 unsigned writemask,
 
217
                                 unsigned base_offset,
 
218
                                 const src_reg &indirect_offset)
 
219
{
 
220
   if (writemask == 0)
 
221
      return;
 
222
 
 
223
   src_reg message(this, glsl_type::uvec4_type, 2);
 
224
   vec4_instruction *inst;
 
225
 
 
226
   inst = emit(TCS_OPCODE_SET_OUTPUT_URB_OFFSETS, dst_reg(message),
 
227
               brw_imm_ud(writemask), indirect_offset);
 
228
   inst->force_writemask_all = true;
 
229
   inst = emit(MOV(byte_offset(dst_reg(retype(message, value.type)), REG_SIZE),
 
230
                   value));
 
231
   inst->force_writemask_all = true;
 
232
 
 
233
   inst = emit(TCS_OPCODE_URB_WRITE, dst_null_f(), message);
 
234
   inst->offset = base_offset;
 
235
   inst->mlen = 2;
 
236
   inst->base_mrf = -1;
 
237
}
 
238
 
 
239
void
 
240
vec4_tcs_visitor::nir_emit_intrinsic(nir_intrinsic_instr *instr)
 
241
{
 
242
   switch (instr->intrinsic) {
 
243
   case nir_intrinsic_load_invocation_id:
 
244
      emit(MOV(get_nir_dest(instr->dest, BRW_REGISTER_TYPE_UD),
 
245
               invocation_id));
 
246
      break;
 
247
   case nir_intrinsic_load_primitive_id:
 
248
      emit(TCS_OPCODE_GET_PRIMITIVE_ID,
 
249
           get_nir_dest(instr->dest, BRW_REGISTER_TYPE_UD));
 
250
      break;
 
251
   case nir_intrinsic_load_patch_vertices_in:
 
252
      emit(MOV(get_nir_dest(instr->dest, BRW_REGISTER_TYPE_D),
 
253
               brw_imm_d(key->input_vertices)));
 
254
      break;
 
255
   case nir_intrinsic_load_per_vertex_input: {
 
256
      assert(nir_dest_bit_size(instr->dest) == 32);
 
257
      src_reg indirect_offset = get_indirect_offset(instr);
 
258
      unsigned imm_offset = instr->const_index[0];
 
259
 
 
260
      src_reg vertex_index = retype(get_nir_src_imm(instr->src[0]),
 
261
                                    BRW_REGISTER_TYPE_UD);
 
262
 
 
263
      unsigned first_component = nir_intrinsic_component(instr);
 
264
      dst_reg dst = get_nir_dest(instr->dest, BRW_REGISTER_TYPE_D);
 
265
      dst.writemask = brw_writemask_for_size(instr->num_components);
 
266
      emit_input_urb_read(dst, vertex_index, imm_offset,
 
267
                          first_component, indirect_offset);
 
268
      break;
 
269
   }
 
270
   case nir_intrinsic_load_input:
 
271
      unreachable("nir_lower_io should use load_per_vertex_input intrinsics");
 
272
      break;
 
273
   case nir_intrinsic_load_output:
 
274
   case nir_intrinsic_load_per_vertex_output: {
 
275
      src_reg indirect_offset = get_indirect_offset(instr);
 
276
      unsigned imm_offset = instr->const_index[0];
 
277
 
 
278
      dst_reg dst = get_nir_dest(instr->dest, BRW_REGISTER_TYPE_D);
 
279
      dst.writemask = brw_writemask_for_size(instr->num_components);
 
280
 
 
281
      emit_output_urb_read(dst, imm_offset, nir_intrinsic_component(instr),
 
282
                           indirect_offset);
 
283
      break;
 
284
   }
 
285
   case nir_intrinsic_store_output:
 
286
   case nir_intrinsic_store_per_vertex_output: {
 
287
      assert(nir_src_bit_size(instr->src[0]) == 32);
 
288
      src_reg value = get_nir_src(instr->src[0]);
 
289
      unsigned mask = instr->const_index[1];
 
290
      unsigned swiz = BRW_SWIZZLE_XYZW;
 
291
 
 
292
      src_reg indirect_offset = get_indirect_offset(instr);
 
293
      unsigned imm_offset = instr->const_index[0];
 
294
 
 
295
      unsigned first_component = nir_intrinsic_component(instr);
 
296
      if (first_component) {
 
297
         assert(swiz == BRW_SWIZZLE_XYZW);
 
298
         swiz = BRW_SWZ_COMP_OUTPUT(first_component);
 
299
         mask = mask << first_component;
 
300
      }
 
301
 
 
302
      emit_urb_write(swizzle(value, swiz), mask,
 
303
                     imm_offset, indirect_offset);
 
304
      break;
 
305
   }
 
306
 
 
307
   case nir_intrinsic_control_barrier: {
 
308
      dst_reg header = dst_reg(this, glsl_type::uvec4_type);
 
309
      emit(TCS_OPCODE_CREATE_BARRIER_HEADER, header);
 
310
      emit(SHADER_OPCODE_BARRIER, dst_null_ud(), src_reg(header));
 
311
      break;
 
312
   }
 
313
 
 
314
   case nir_intrinsic_memory_barrier_tcs_patch:
 
315
      break;
 
316
 
 
317
   default:
 
318
      vec4_visitor::nir_emit_intrinsic(instr);
 
319
   }
 
320
}
 
321
 
 
322
/**
 
323
 * Return the number of patches to accumulate before an 8_PATCH mode thread is
 
324
 * launched.  In cases with a large number of input control points and a large
 
325
 * amount of VS outputs, the VS URB space needed to store an entire 8 patches
 
326
 * worth of data can be prohibitive, so it can be beneficial to launch threads
 
327
 * early.
 
328
 *
 
329
 * See the 3DSTATE_HS::Patch Count Threshold documentation for the recommended
 
330
 * values.  Note that 0 means to "disable" early dispatch, meaning to wait for
 
331
 * a full 8 patches as normal.
 
332
 */
 
333
static int
 
334
get_patch_count_threshold(int input_control_points)
 
335
{
 
336
   if (input_control_points <= 4)
 
337
      return 0;
 
338
   else if (input_control_points <= 6)
 
339
      return 5;
 
340
   else if (input_control_points <= 8)
 
341
      return 4;
 
342
   else if (input_control_points <= 10)
 
343
      return 3;
 
344
   else if (input_control_points <= 14)
 
345
      return 2;
 
346
 
 
347
   /* Return patch count 1 for PATCHLIST_15 - PATCHLIST_32 */
 
348
   return 1;
 
349
}
 
350
 
 
351
} /* namespace brw */
 
352
 
 
353
extern "C" const unsigned *
 
354
brw_compile_tcs(const struct brw_compiler *compiler,
 
355
                void *mem_ctx,
 
356
                struct brw_compile_tcs_params *params)
 
357
{
 
358
   const struct intel_device_info *devinfo = compiler->devinfo;
 
359
   nir_shader *nir = params->nir;
 
360
   const struct brw_tcs_prog_key *key = params->key;
 
361
   struct brw_tcs_prog_data *prog_data = params->prog_data;
 
362
   struct brw_vue_prog_data *vue_prog_data = &prog_data->base;
 
363
 
 
364
   const bool is_scalar = compiler->scalar_stage[MESA_SHADER_TESS_CTRL];
 
365
   const bool debug_enabled = INTEL_DEBUG(DEBUG_TCS);
 
366
   const unsigned *assembly;
 
367
 
 
368
   vue_prog_data->base.stage = MESA_SHADER_TESS_CTRL;
 
369
   prog_data->base.base.ray_queries = nir->info.ray_queries;
 
370
   prog_data->base.base.total_scratch = 0;
 
371
 
 
372
   nir->info.outputs_written = key->outputs_written;
 
373
   nir->info.patch_outputs_written = key->patch_outputs_written;
 
374
 
 
375
   struct brw_vue_map input_vue_map;
 
376
   brw_compute_vue_map(devinfo, &input_vue_map, nir->info.inputs_read,
 
377
                       nir->info.separate_shader, 1);
 
378
   brw_compute_tess_vue_map(&vue_prog_data->vue_map,
 
379
                            nir->info.outputs_written,
 
380
                            nir->info.patch_outputs_written);
 
381
 
 
382
   brw_nir_apply_key(nir, compiler, &key->base, 8, is_scalar);
 
383
   brw_nir_lower_vue_inputs(nir, &input_vue_map);
 
384
   brw_nir_lower_tcs_outputs(nir, &vue_prog_data->vue_map,
 
385
                             key->_tes_primitive_mode);
 
386
   if (key->quads_workaround)
 
387
      brw_nir_apply_tcs_quads_workaround(nir);
 
388
 
 
389
   brw_postprocess_nir(nir, compiler, is_scalar, debug_enabled,
 
390
                       key->base.robust_buffer_access);
 
391
 
 
392
   bool has_primitive_id =
 
393
      BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID);
 
394
 
 
395
   prog_data->patch_count_threshold = brw::get_patch_count_threshold(key->input_vertices);
 
396
 
 
397
   if (compiler->use_tcs_8_patch &&
 
398
       nir->info.tess.tcs_vertices_out <= (devinfo->ver >= 12 ? 32 : 16) &&
 
399
       2 + has_primitive_id + key->input_vertices <= (devinfo->ver >= 12 ? 63 : 31)) {
 
400
      /* 3DSTATE_HS imposes two constraints on using 8_PATCH mode. First, the
 
401
       * "Instance" field limits the number of output vertices to [1, 16] on
 
402
       * gfx11 and below, or [1, 32] on gfx12 and above. Secondly, the
 
403
       * "Dispatch GRF Start Register for URB Data" field is limited to [0,
 
404
       * 31] - which imposes a limit on the input vertices.
 
405
       */
 
406
      vue_prog_data->dispatch_mode = DISPATCH_MODE_TCS_8_PATCH;
 
407
      prog_data->instances = nir->info.tess.tcs_vertices_out;
 
408
      prog_data->include_primitive_id = has_primitive_id;
 
409
   } else {
 
410
      unsigned verts_per_thread = is_scalar ? 8 : 2;
 
411
      vue_prog_data->dispatch_mode = DISPATCH_MODE_TCS_SINGLE_PATCH;
 
412
      prog_data->instances =
 
413
         DIV_ROUND_UP(nir->info.tess.tcs_vertices_out, verts_per_thread);
 
414
   }
 
415
 
 
416
   /* Compute URB entry size.  The maximum allowed URB entry size is 32k.
 
417
    * That divides up as follows:
 
418
    *
 
419
    *     32 bytes for the patch header (tessellation factors)
 
420
    *    480 bytes for per-patch varyings (a varying component is 4 bytes and
 
421
    *              gl_MaxTessPatchComponents = 120)
 
422
    *  16384 bytes for per-vertex varyings (a varying component is 4 bytes,
 
423
    *              gl_MaxPatchVertices = 32 and
 
424
    *              gl_MaxTessControlOutputComponents = 128)
 
425
    *
 
426
    *  15808 bytes left for varying packing overhead
 
427
    */
 
428
   const int num_per_patch_slots = vue_prog_data->vue_map.num_per_patch_slots;
 
429
   const int num_per_vertex_slots = vue_prog_data->vue_map.num_per_vertex_slots;
 
430
   unsigned output_size_bytes = 0;
 
431
   /* Note that the patch header is counted in num_per_patch_slots. */
 
432
   output_size_bytes += num_per_patch_slots * 16;
 
433
   output_size_bytes += nir->info.tess.tcs_vertices_out *
 
434
                        num_per_vertex_slots * 16;
 
435
 
 
436
   assert(output_size_bytes >= 1);
 
437
   if (output_size_bytes > GFX7_MAX_HS_URB_ENTRY_SIZE_BYTES)
 
438
      return NULL;
 
439
 
 
440
   /* URB entry sizes are stored as a multiple of 64 bytes. */
 
441
   vue_prog_data->urb_entry_size = ALIGN(output_size_bytes, 64) / 64;
 
442
 
 
443
   /* HS does not use the usual payload pushing from URB to GRFs,
 
444
    * because we don't have enough registers for a full-size payload, and
 
445
    * the hardware is broken on Haswell anyway.
 
446
    */
 
447
   vue_prog_data->urb_read_length = 0;
 
448
 
 
449
   if (unlikely(debug_enabled)) {
 
450
      fprintf(stderr, "TCS Input ");
 
451
      brw_print_vue_map(stderr, &input_vue_map, MESA_SHADER_TESS_CTRL);
 
452
      fprintf(stderr, "TCS Output ");
 
453
      brw_print_vue_map(stderr, &vue_prog_data->vue_map, MESA_SHADER_TESS_CTRL);
 
454
   }
 
455
 
 
456
   if (is_scalar) {
 
457
      fs_visitor v(compiler, params->log_data, mem_ctx, &key->base,
 
458
                   &prog_data->base.base, nir, 8, debug_enabled);
 
459
      if (!v.run_tcs()) {
 
460
         params->error_str = ralloc_strdup(mem_ctx, v.fail_msg);
 
461
         return NULL;
 
462
      }
 
463
 
 
464
      prog_data->base.base.dispatch_grf_start_reg = v.payload.num_regs;
 
465
 
 
466
      fs_generator g(compiler, params->log_data, mem_ctx,
 
467
                     &prog_data->base.base, false, MESA_SHADER_TESS_CTRL);
 
468
      if (unlikely(debug_enabled)) {
 
469
         g.enable_debug(ralloc_asprintf(mem_ctx,
 
470
                                        "%s tessellation control shader %s",
 
471
                                        nir->info.label ? nir->info.label
 
472
                                                        : "unnamed",
 
473
                                        nir->info.name));
 
474
      }
 
475
 
 
476
      g.generate_code(v.cfg, 8, v.shader_stats,
 
477
                      v.performance_analysis.require(), params->stats);
 
478
 
 
479
      g.add_const_data(nir->constant_data, nir->constant_data_size);
 
480
 
 
481
      assembly = g.get_assembly();
 
482
   } else {
 
483
      brw::vec4_tcs_visitor v(compiler, params->log_data, key, prog_data,
 
484
                              nir, mem_ctx, debug_enabled);
 
485
      if (!v.run()) {
 
486
         params->error_str = ralloc_strdup(mem_ctx, v.fail_msg);
 
487
         return NULL;
 
488
      }
 
489
 
 
490
      if (INTEL_DEBUG(DEBUG_TCS))
 
491
         v.dump_instructions();
 
492
 
 
493
 
 
494
      assembly = brw_vec4_generate_assembly(compiler, params->log_data, mem_ctx, nir,
 
495
                                            &prog_data->base, v.cfg,
 
496
                                            v.performance_analysis.require(),
 
497
                                            params->stats, debug_enabled);
 
498
   }
 
499
 
 
500
   return assembly;
 
501
}