~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/freedreno/ir3/ir3_shader.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
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 FROM,
20
 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 
 * SOFTWARE.
22
 
 *
23
 
 * Authors:
24
 
 *    Rob Clark <robclark@freedesktop.org>
25
 
 */
26
 
 
27
 
#include "util/format/u_format.h"
28
 
#include "util/u_atomic.h"
29
 
#include "util/u_math.h"
30
 
#include "util/u_memory.h"
31
 
#include "util/u_string.h"
32
 
 
33
 
#include "drm/freedreno_drmif.h"
34
 
 
35
 
#include "ir3_assembler.h"
36
 
#include "ir3_compiler.h"
37
 
#include "ir3_nir.h"
38
 
#include "ir3_parser.h"
39
 
#include "ir3_shader.h"
40
 
 
41
 
#include "isa/isa.h"
42
 
 
43
 
#include "disasm.h"
44
 
 
45
 
int
46
 
ir3_glsl_type_size(const struct glsl_type *type, bool bindless)
47
 
{
48
 
   return glsl_count_attribute_slots(type, false);
49
 
}
50
 
 
51
 
/* for vertex shader, the inputs are loaded into registers before the shader
52
 
 * is executed, so max_regs from the shader instructions might not properly
53
 
 * reflect the # of registers actually used, especially in case passthrough
54
 
 * varyings.
55
 
 *
56
 
 * Likewise, for fragment shader, we can have some regs which are passed
57
 
 * input values but never touched by the resulting shader (ie. as result
58
 
 * of dead code elimination or simply because we don't know how to turn
59
 
 * the reg off.
60
 
 */
61
 
static void
62
 
fixup_regfootprint(struct ir3_shader_variant *v)
63
 
{
64
 
   unsigned i;
65
 
 
66
 
   for (i = 0; i < v->inputs_count; i++) {
67
 
      /* skip frag inputs fetch via bary.f since their reg's are
68
 
       * not written by gpu before shader starts (and in fact the
69
 
       * regid's might not even be valid)
70
 
       */
71
 
      if (v->inputs[i].bary)
72
 
         continue;
73
 
 
74
 
      /* ignore high regs that are global to all threads in a warp
75
 
       * (they exist by default) (a5xx+)
76
 
       */
77
 
      if (v->inputs[i].regid >= regid(48, 0))
78
 
         continue;
79
 
 
80
 
      if (v->inputs[i].compmask) {
81
 
         unsigned n = util_last_bit(v->inputs[i].compmask) - 1;
82
 
         int32_t regid = v->inputs[i].regid + n;
83
 
         if (v->inputs[i].half) {
84
 
            if (!v->mergedregs) {
85
 
               v->info.max_half_reg = MAX2(v->info.max_half_reg, regid >> 2);
86
 
            } else {
87
 
               v->info.max_reg = MAX2(v->info.max_reg, regid >> 3);
88
 
            }
89
 
         } else {
90
 
            v->info.max_reg = MAX2(v->info.max_reg, regid >> 2);
91
 
         }
92
 
      }
93
 
   }
94
 
 
95
 
   for (i = 0; i < v->outputs_count; i++) {
96
 
      /* for ex, VS shaders with tess don't have normal varying outs: */
97
 
      if (!VALIDREG(v->outputs[i].regid))
98
 
         continue;
99
 
      int32_t regid = v->outputs[i].regid + 3;
100
 
      if (v->outputs[i].half) {
101
 
         if (!v->mergedregs) {
102
 
            v->info.max_half_reg = MAX2(v->info.max_half_reg, regid >> 2);
103
 
         } else {
104
 
            v->info.max_reg = MAX2(v->info.max_reg, regid >> 3);
105
 
         }
106
 
      } else {
107
 
         v->info.max_reg = MAX2(v->info.max_reg, regid >> 2);
108
 
      }
109
 
   }
110
 
 
111
 
   for (i = 0; i < v->num_sampler_prefetch; i++) {
112
 
      unsigned n = util_last_bit(v->sampler_prefetch[i].wrmask) - 1;
113
 
      int32_t regid = v->sampler_prefetch[i].dst + n;
114
 
      if (v->sampler_prefetch[i].half_precision) {
115
 
         if (!v->mergedregs) {
116
 
            v->info.max_half_reg = MAX2(v->info.max_half_reg, regid >> 2);
117
 
         } else {
118
 
            v->info.max_reg = MAX2(v->info.max_reg, regid >> 3);
119
 
         }
120
 
      } else {
121
 
         v->info.max_reg = MAX2(v->info.max_reg, regid >> 2);
122
 
      }
123
 
   }
124
 
}
125
 
 
126
 
/* wrapper for ir3_assemble() which does some info fixup based on
127
 
 * shader state.  Non-static since used by ir3_cmdline too.
128
 
 */
129
 
void *
130
 
ir3_shader_assemble(struct ir3_shader_variant *v)
131
 
{
132
 
   const struct ir3_compiler *compiler = v->shader->compiler;
133
 
   struct ir3_info *info = &v->info;
134
 
   uint32_t *bin;
135
 
 
136
 
   ir3_collect_info(v);
137
 
 
138
 
   if (v->constant_data_size) {
139
 
      /* Make sure that where we're about to place the constant_data is safe
140
 
       * to indirectly upload from.
141
 
       */
142
 
      info->constant_data_offset =
143
 
         align(info->size, v->shader->compiler->const_upload_unit * 16);
144
 
      info->size = info->constant_data_offset + v->constant_data_size;
145
 
   }
146
 
 
147
 
   /* Pad out the size so that when turnip uploads the shaders in
148
 
    * sequence, the starting offset of the next one is properly aligned.
149
 
    */
150
 
   info->size = align(info->size, compiler->instr_align * sizeof(uint64_t));
151
 
 
152
 
   bin = isa_assemble(v);
153
 
   if (!bin)
154
 
      return NULL;
155
 
 
156
 
   /* Append the immediates after the end of the program.  This lets us emit
157
 
    * the immediates as an indirect load, while avoiding creating another BO.
158
 
    */
159
 
   if (v->constant_data_size)
160
 
      memcpy(&bin[info->constant_data_offset / 4], v->constant_data,
161
 
             v->constant_data_size);
162
 
   ralloc_free(v->constant_data);
163
 
   v->constant_data = NULL;
164
 
 
165
 
   /* NOTE: if relative addressing is used, we set constlen in
166
 
    * the compiler (to worst-case value) since we don't know in
167
 
    * the assembler what the max addr reg value can be:
168
 
    */
169
 
   v->constlen = MAX2(v->constlen, info->max_const + 1);
170
 
 
171
 
   if (v->constlen > ir3_const_state(v)->offsets.driver_param)
172
 
      v->need_driver_params = true;
173
 
 
174
 
   /* On a4xx and newer, constlen must be a multiple of 16 dwords even though
175
 
    * uploads are in units of 4 dwords. Round it up here to make calculations
176
 
    * regarding the shared constlen simpler.
177
 
    */
178
 
   if (compiler->gen >= 4)
179
 
      v->constlen = align(v->constlen, 4);
180
 
 
181
 
   /* Use the per-wave layout by default on a6xx for compute shaders. It
182
 
    * should result in better performance when loads/stores are to a uniform
183
 
    * index.
184
 
    */
185
 
   v->pvtmem_per_wave = compiler->gen >= 6 && !info->multi_dword_ldp_stp &&
186
 
                        ((v->type == MESA_SHADER_COMPUTE) ||
187
 
                         (v->type == MESA_SHADER_KERNEL));
188
 
 
189
 
   fixup_regfootprint(v);
190
 
 
191
 
   return bin;
192
 
}
193
 
 
194
 
static bool
195
 
try_override_shader_variant(struct ir3_shader_variant *v,
196
 
                            const char *identifier)
197
 
{
198
 
   assert(ir3_shader_override_path);
199
 
 
200
 
   char *name =
201
 
      ralloc_asprintf(NULL, "%s/%s.asm", ir3_shader_override_path, identifier);
202
 
 
203
 
   FILE *f = fopen(name, "r");
204
 
 
205
 
   if (!f) {
206
 
      ralloc_free(name);
207
 
      return false;
208
 
   }
209
 
 
210
 
   struct ir3_kernel_info info;
211
 
   info.numwg = INVALID_REG;
212
 
   v->ir = ir3_parse(v, &info, f);
213
 
 
214
 
   fclose(f);
215
 
 
216
 
   if (!v->ir) {
217
 
      fprintf(stderr, "Failed to parse %s\n", name);
218
 
      exit(1);
219
 
   }
220
 
 
221
 
   v->bin = ir3_shader_assemble(v);
222
 
   if (!v->bin) {
223
 
      fprintf(stderr, "Failed to assemble %s\n", name);
224
 
      exit(1);
225
 
   }
226
 
 
227
 
   ralloc_free(name);
228
 
   return true;
229
 
}
230
 
 
231
 
static void
232
 
assemble_variant(struct ir3_shader_variant *v)
233
 
{
234
 
   v->bin = ir3_shader_assemble(v);
235
 
 
236
 
   bool dbg_enabled = shader_debug_enabled(v->shader->type);
237
 
   if (dbg_enabled || ir3_shader_override_path || v->disasm_info.write_disasm) {
238
 
      unsigned char sha1[21];
239
 
      char sha1buf[41];
240
 
 
241
 
      _mesa_sha1_compute(v->bin, v->info.size, sha1);
242
 
      _mesa_sha1_format(sha1buf, sha1);
243
 
 
244
 
      bool shader_overridden =
245
 
         ir3_shader_override_path && try_override_shader_variant(v, sha1buf);
246
 
 
247
 
      if (v->disasm_info.write_disasm) {
248
 
         char *stream_data = NULL;
249
 
         size_t stream_size = 0;
250
 
         FILE *stream = open_memstream(&stream_data, &stream_size);
251
 
 
252
 
         fprintf(stream,
253
 
                 "Native code%s for unnamed %s shader %s with sha1 %s:\n",
254
 
                 shader_overridden ? " (overridden)" : "", ir3_shader_stage(v),
255
 
                 v->shader->nir->info.name, sha1buf);
256
 
         ir3_shader_disasm(v, v->bin, stream);
257
 
 
258
 
         fclose(stream);
259
 
 
260
 
         v->disasm_info.disasm = ralloc_size(v->shader, stream_size + 1);
261
 
         memcpy(v->disasm_info.disasm, stream_data, stream_size);
262
 
         v->disasm_info.disasm[stream_size] = 0;
263
 
         free(stream_data);
264
 
      }
265
 
 
266
 
      if (dbg_enabled || shader_overridden) {
267
 
         char *stream_data = NULL;
268
 
         size_t stream_size = 0;
269
 
         FILE *stream = open_memstream(&stream_data, &stream_size);
270
 
 
271
 
         fprintf(stream,
272
 
                 "Native code%s for unnamed %s shader %s with sha1 %s:\n",
273
 
                 shader_overridden ? " (overridden)" : "", ir3_shader_stage(v),
274
 
                 v->shader->nir->info.name, sha1buf);
275
 
         if (v->shader->type == MESA_SHADER_FRAGMENT)
276
 
            fprintf(stream, "SIMD0\n");
277
 
         ir3_shader_disasm(v, v->bin, stream);
278
 
         fclose(stream);
279
 
 
280
 
         mesa_log_multiline(MESA_LOG_INFO, stream_data);
281
 
         free(stream_data);
282
 
      }
283
 
   }
284
 
 
285
 
   /* no need to keep the ir around beyond this point: */
286
 
   ir3_destroy(v->ir);
287
 
   v->ir = NULL;
288
 
}
289
 
 
290
 
static bool
291
 
compile_variant(struct ir3_shader_variant *v)
292
 
{
293
 
   int ret = ir3_compile_shader_nir(v->shader->compiler, v);
294
 
   if (ret) {
295
 
      mesa_loge("compile failed! (%s:%s)", v->shader->nir->info.name,
296
 
                v->shader->nir->info.label);
297
 
      return false;
298
 
   }
299
 
 
300
 
   assemble_variant(v);
301
 
   if (!v->bin) {
302
 
      mesa_loge("assemble failed! (%s:%s)", v->shader->nir->info.name,
303
 
                v->shader->nir->info.label);
304
 
      return false;
305
 
   }
306
 
 
307
 
   return true;
308
 
}
309
 
 
310
 
/*
311
 
 * For creating normal shader variants, 'nonbinning' is NULL.  For
312
 
 * creating binning pass shader, it is link to corresponding normal
313
 
 * (non-binning) variant.
314
 
 */
315
 
static struct ir3_shader_variant *
316
 
alloc_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
317
 
              struct ir3_shader_variant *nonbinning)
318
 
{
319
 
   void *mem_ctx = shader;
320
 
   /* hang the binning variant off it's non-binning counterpart instead
321
 
    * of the shader, to simplify the error cleanup paths
322
 
    */
323
 
   if (nonbinning)
324
 
      mem_ctx = nonbinning;
325
 
   struct ir3_shader_variant *v = rzalloc_size(mem_ctx, sizeof(*v));
326
 
 
327
 
   if (!v)
328
 
      return NULL;
329
 
 
330
 
   v->id = ++shader->variant_count;
331
 
   v->shader = shader;
332
 
   v->binning_pass = !!nonbinning;
333
 
   v->nonbinning = nonbinning;
334
 
   v->key = *key;
335
 
   v->type = shader->type;
336
 
   v->mergedregs = shader->compiler->gen >= 6;
337
 
 
338
 
   if (!v->binning_pass)
339
 
      v->const_state = rzalloc_size(v, sizeof(*v->const_state));
340
 
 
341
 
   return v;
342
 
}
343
 
 
344
 
static bool
345
 
needs_binning_variant(struct ir3_shader_variant *v)
346
 
{
347
 
   if ((v->type == MESA_SHADER_VERTEX) && ir3_has_binning_vs(&v->key))
348
 
      return true;
349
 
   return false;
350
 
}
351
 
 
352
 
static struct ir3_shader_variant *
353
 
create_variant(struct ir3_shader *shader, const struct ir3_shader_key *key,
354
 
               bool write_disasm)
355
 
{
356
 
   struct ir3_shader_variant *v = alloc_variant(shader, key, NULL);
357
 
 
358
 
   if (!v)
359
 
      goto fail;
360
 
 
361
 
   v->disasm_info.write_disasm = write_disasm;
362
 
 
363
 
   if (needs_binning_variant(v)) {
364
 
      v->binning = alloc_variant(shader, key, v);
365
 
      if (!v->binning)
366
 
         goto fail;
367
 
      v->binning->disasm_info.write_disasm = write_disasm;
368
 
   }
369
 
 
370
 
   if (ir3_disk_cache_retrieve(shader->compiler, v))
371
 
      return v;
372
 
 
373
 
   if (!shader->nir_finalized) {
374
 
      ir3_nir_post_finalize(shader);
375
 
 
376
 
      if (ir3_shader_debug & IR3_DBG_DISASM) {
377
 
         mesa_logi("dump nir%d: type=%d", shader->id, shader->type);
378
 
         nir_log_shaderi(shader->nir);
379
 
      }
380
 
 
381
 
      if (v->disasm_info.write_disasm) {
382
 
         v->disasm_info.nir = nir_shader_as_str(shader->nir, shader);
383
 
      }
384
 
 
385
 
      shader->nir_finalized = true;
386
 
   }
387
 
 
388
 
   if (!compile_variant(v))
389
 
      goto fail;
390
 
 
391
 
   if (needs_binning_variant(v) && !compile_variant(v->binning))
392
 
      goto fail;
393
 
 
394
 
   ir3_disk_cache_store(shader->compiler, v);
395
 
 
396
 
   return v;
397
 
 
398
 
fail:
399
 
   ralloc_free(v);
400
 
   return NULL;
401
 
}
402
 
 
403
 
static inline struct ir3_shader_variant *
404
 
shader_variant(struct ir3_shader *shader, const struct ir3_shader_key *key)
405
 
{
406
 
   struct ir3_shader_variant *v;
407
 
 
408
 
   for (v = shader->variants; v; v = v->next)
409
 
      if (ir3_shader_key_equal(key, &v->key))
410
 
         return v;
411
 
 
412
 
   return NULL;
413
 
}
414
 
 
415
 
struct ir3_shader_variant *
416
 
ir3_shader_get_variant(struct ir3_shader *shader,
417
 
                       const struct ir3_shader_key *key, bool binning_pass,
418
 
                       bool write_disasm, bool *created)
419
 
{
420
 
   mtx_lock(&shader->variants_lock);
421
 
   struct ir3_shader_variant *v = shader_variant(shader, key);
422
 
 
423
 
   if (!v) {
424
 
      /* compile new variant if it doesn't exist already: */
425
 
      v = create_variant(shader, key, write_disasm);
426
 
      if (v) {
427
 
         v->next = shader->variants;
428
 
         shader->variants = v;
429
 
         *created = true;
430
 
      }
431
 
   }
432
 
 
433
 
   if (v && binning_pass) {
434
 
      v = v->binning;
435
 
      assert(v);
436
 
   }
437
 
 
438
 
   mtx_unlock(&shader->variants_lock);
439
 
 
440
 
   return v;
441
 
}
442
 
 
443
 
void
444
 
ir3_shader_destroy(struct ir3_shader *shader)
445
 
{
446
 
   ralloc_free(shader->nir);
447
 
   mtx_destroy(&shader->variants_lock);
448
 
   ralloc_free(shader);
449
 
}
450
 
 
451
 
/**
452
 
 * Creates a bitmask of the used bits of the shader key by this particular
453
 
 * shader.  Used by the gallium driver to skip state-dependent recompiles when
454
 
 * possible.
455
 
 */
456
 
static void
457
 
ir3_setup_used_key(struct ir3_shader *shader)
458
 
{
459
 
   nir_shader *nir = shader->nir;
460
 
   struct shader_info *info = &nir->info;
461
 
   struct ir3_shader_key *key = &shader->key_mask;
462
 
 
463
 
   /* This key flag is just used to make for a cheaper ir3_shader_key_equal
464
 
    * check in the common case.
465
 
    */
466
 
   key->has_per_samp = true;
467
 
 
468
 
   key->safe_constlen = true;
469
 
 
470
 
   /* When clip/cull distances are natively supported, we only use
471
 
    * ucp_enables to determine whether to lower legacy clip planes to
472
 
    * gl_ClipDistance.
473
 
    */
474
 
   if (info->stage != MESA_SHADER_COMPUTE && (info->stage != MESA_SHADER_FRAGMENT || !shader->compiler->has_clip_cull))
475
 
      key->ucp_enables = 0xff;
476
 
 
477
 
   if (info->stage == MESA_SHADER_FRAGMENT) {
478
 
      key->fastc_srgb = ~0;
479
 
      key->fsamples = ~0;
480
 
      memset(key->fsampler_swizzles, 0xff, sizeof(key->fsampler_swizzles));
481
 
 
482
 
      if (info->inputs_read & VARYING_BITS_COLOR) {
483
 
         key->rasterflat = true;
484
 
      }
485
 
 
486
 
      if (info->inputs_read & VARYING_BIT_LAYER) {
487
 
         key->layer_zero = true;
488
 
      }
489
 
 
490
 
      if (info->inputs_read & VARYING_BIT_VIEWPORT) {
491
 
         key->view_zero = true;
492
 
      }
493
 
 
494
 
      /* Only used for deciding on behavior of
495
 
       * nir_intrinsic_load_barycentric_sample, or the centroid demotion
496
 
       * on older HW.
497
 
       */
498
 
      key->msaa = info->fs.uses_sample_qualifier ||
499
 
                  (shader->compiler->gen < 6 &&
500
 
                   (BITSET_TEST(info->system_values_read,
501
 
                                SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID) ||
502
 
                    BITSET_TEST(info->system_values_read,
503
 
                                SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID)));
504
 
   } else if (info->stage == MESA_SHADER_COMPUTE) {
505
 
      key->fastc_srgb = ~0;
506
 
      key->fsamples = ~0;
507
 
      memset(key->fsampler_swizzles, 0xff, sizeof(key->fsampler_swizzles));
508
 
   } else {
509
 
      key->tessellation = ~0;
510
 
      key->has_gs = true;
511
 
 
512
 
      if (info->stage == MESA_SHADER_VERTEX) {
513
 
         key->vastc_srgb = ~0;
514
 
         key->vsamples = ~0;
515
 
         memset(key->vsampler_swizzles, 0xff, sizeof(key->vsampler_swizzles));
516
 
      }
517
 
 
518
 
      if (info->stage == MESA_SHADER_TESS_CTRL)
519
 
         key->tcs_store_primid = true;
520
 
   }
521
 
}
522
 
 
523
 
/* Given an array of constlen's, decrease some of them so that the sum stays
524
 
 * within "combined_limit" while trying to fairly share the reduction. Returns
525
 
 * a bitfield of which stages should be trimmed.
526
 
 */
527
 
static uint32_t
528
 
trim_constlens(unsigned *constlens, unsigned first_stage, unsigned last_stage,
529
 
               unsigned combined_limit, unsigned safe_limit)
530
 
{
531
 
   unsigned cur_total = 0;
532
 
   for (unsigned i = first_stage; i <= last_stage; i++) {
533
 
      cur_total += constlens[i];
534
 
   }
535
 
 
536
 
   unsigned max_stage = 0;
537
 
   unsigned max_const = 0;
538
 
   uint32_t trimmed = 0;
539
 
 
540
 
   while (cur_total > combined_limit) {
541
 
      for (unsigned i = first_stage; i <= last_stage; i++) {
542
 
         if (constlens[i] >= max_const) {
543
 
            max_stage = i;
544
 
            max_const = constlens[i];
545
 
         }
546
 
      }
547
 
 
548
 
      assert(max_const > safe_limit);
549
 
      trimmed |= 1 << max_stage;
550
 
      cur_total = cur_total - max_const + safe_limit;
551
 
      constlens[max_stage] = safe_limit;
552
 
   }
553
 
 
554
 
   return trimmed;
555
 
}
556
 
 
557
 
/* Figures out which stages in the pipeline to use the "safe" constlen for, in
558
 
 * order to satisfy all shared constlen limits.
559
 
 */
560
 
uint32_t
561
 
ir3_trim_constlen(struct ir3_shader_variant **variants,
562
 
                  const struct ir3_compiler *compiler)
563
 
{
564
 
   unsigned constlens[MESA_SHADER_STAGES] = {};
565
 
 
566
 
   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
567
 
      if (variants[i])
568
 
         constlens[i] = variants[i]->constlen;
569
 
   }
570
 
 
571
 
   uint32_t trimmed = 0;
572
 
   STATIC_ASSERT(MESA_SHADER_STAGES <= 8 * sizeof(trimmed));
573
 
 
574
 
   /* There are two shared limits to take into account, the geometry limit on
575
 
    * a6xx and the total limit. The frag limit on a6xx only matters for a
576
 
    * single stage, so it's always satisfied with the first variant.
577
 
    */
578
 
   if (compiler->gen >= 6) {
579
 
      trimmed |=
580
 
         trim_constlens(constlens, MESA_SHADER_VERTEX, MESA_SHADER_GEOMETRY,
581
 
                        compiler->max_const_geom, compiler->max_const_safe);
582
 
   }
583
 
   trimmed |=
584
 
      trim_constlens(constlens, MESA_SHADER_VERTEX, MESA_SHADER_FRAGMENT,
585
 
                     compiler->max_const_pipeline, compiler->max_const_safe);
586
 
 
587
 
   return trimmed;
588
 
}
589
 
 
590
 
struct ir3_shader *
591
 
ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir,
592
 
                    const struct ir3_shader_options *options,
593
 
                    struct ir3_stream_output_info *stream_output)
594
 
{
595
 
   struct ir3_shader *shader = rzalloc_size(NULL, sizeof(*shader));
596
 
 
597
 
   mtx_init(&shader->variants_lock, mtx_plain);
598
 
   shader->compiler = compiler;
599
 
   shader->id = p_atomic_inc_return(&shader->compiler->shader_count);
600
 
   shader->type = nir->info.stage;
601
 
   if (stream_output)
602
 
      memcpy(&shader->stream_output, stream_output,
603
 
             sizeof(shader->stream_output));
604
 
   shader->num_reserved_user_consts = options->reserved_user_consts;
605
 
   shader->api_wavesize = options->api_wavesize;
606
 
   shader->real_wavesize = options->real_wavesize;
607
 
   shader->nir = nir;
608
 
 
609
 
   ir3_disk_cache_init_shader_key(compiler, shader);
610
 
 
611
 
   ir3_setup_used_key(shader);
612
 
 
613
 
   return shader;
614
 
}
615
 
 
616
 
static void
617
 
dump_reg(FILE *out, const char *name, uint32_t r)
618
 
{
619
 
   if (r != regid(63, 0)) {
620
 
      const char *reg_type = (r & HALF_REG_ID) ? "hr" : "r";
621
 
      fprintf(out, "; %s: %s%d.%c\n", name, reg_type, (r & ~HALF_REG_ID) >> 2,
622
 
              "xyzw"[r & 0x3]);
623
 
   }
624
 
}
625
 
 
626
 
static void
627
 
dump_output(FILE *out, struct ir3_shader_variant *so, unsigned slot,
628
 
            const char *name)
629
 
{
630
 
   uint32_t regid;
631
 
   regid = ir3_find_output_regid(so, slot);
632
 
   dump_reg(out, name, regid);
633
 
}
634
 
 
635
 
static const char *
636
 
input_name(struct ir3_shader_variant *so, int i)
637
 
{
638
 
   if (so->inputs[i].sysval) {
639
 
      return gl_system_value_name(so->inputs[i].slot);
640
 
   } else if (so->type == MESA_SHADER_VERTEX) {
641
 
      return gl_vert_attrib_name(so->inputs[i].slot);
642
 
   } else {
643
 
      return gl_varying_slot_name_for_stage(so->inputs[i].slot, so->type);
644
 
   }
645
 
}
646
 
 
647
 
static const char *
648
 
output_name(struct ir3_shader_variant *so, int i)
649
 
{
650
 
   if (so->type == MESA_SHADER_FRAGMENT) {
651
 
      return gl_frag_result_name(so->outputs[i].slot);
652
 
   } else {
653
 
      switch (so->outputs[i].slot) {
654
 
      case VARYING_SLOT_GS_HEADER_IR3:
655
 
         return "GS_HEADER";
656
 
      case VARYING_SLOT_GS_VERTEX_FLAGS_IR3:
657
 
         return "GS_VERTEX_FLAGS";
658
 
      case VARYING_SLOT_TCS_HEADER_IR3:
659
 
         return "TCS_HEADER";
660
 
      default:
661
 
         return gl_varying_slot_name_for_stage(so->outputs[i].slot, so->type);
662
 
      }
663
 
   }
664
 
}
665
 
 
666
 
static void
667
 
dump_const_state(struct ir3_shader_variant *so, FILE *out)
668
 
{
669
 
   const struct ir3_const_state *cs = ir3_const_state(so);
670
 
   const struct ir3_ubo_analysis_state *us = &cs->ubo_state;
671
 
 
672
 
   fprintf(out, "; num_ubos:           %u\n", cs->num_ubos);
673
 
   fprintf(out, "; num_driver_params:  %u\n", cs->num_driver_params);
674
 
   fprintf(out, "; offsets:\n");
675
 
   if (cs->offsets.ubo != ~0)
676
 
      fprintf(out, ";   ubo:              c%u.x\n", cs->offsets.ubo);
677
 
   if (cs->offsets.image_dims != ~0)
678
 
      fprintf(out, ";   image_dims:       c%u.x\n", cs->offsets.image_dims);
679
 
   if (cs->offsets.kernel_params != ~0)
680
 
      fprintf(out, ";   kernel_params:    c%u.x\n", cs->offsets.kernel_params);
681
 
   if (cs->offsets.driver_param != ~0)
682
 
      fprintf(out, ";   driver_param:     c%u.x\n", cs->offsets.driver_param);
683
 
   if (cs->offsets.tfbo != ~0)
684
 
      fprintf(out, ";   tfbo:             c%u.x\n", cs->offsets.tfbo);
685
 
   if (cs->offsets.primitive_param != ~0)
686
 
      fprintf(out, ";   primitive_params: c%u.x\n", cs->offsets.primitive_param);
687
 
   if (cs->offsets.primitive_map != ~0)
688
 
      fprintf(out, ";   primitive_map:    c%u.x\n", cs->offsets.primitive_map);
689
 
   fprintf(out, "; ubo_state:\n");
690
 
   fprintf(out, ";   num_enabled:      %u\n", us->num_enabled);
691
 
   for (unsigned i = 0; i < us->num_enabled; i++) {
692
 
      const struct ir3_ubo_range *r = &us->range[i];
693
 
 
694
 
      assert((r->offset % 16) == 0);
695
 
 
696
 
      fprintf(out, ";   range[%u]:\n", i);
697
 
      fprintf(out, ";     block:          %u\n", r->ubo.block);
698
 
      if (r->ubo.bindless)
699
 
         fprintf(out, ";     bindless_base:  %u\n", r->ubo.bindless_base);
700
 
      fprintf(out, ";     offset:         c%u.x\n", r->offset/16);
701
 
 
702
 
      unsigned size = r->end - r->start;
703
 
      assert((size % 16) == 0);
704
 
 
705
 
      fprintf(out, ";     size:           %u vec4 (%ub -> %ub)\n", (size/16), r->start, r->end);
706
 
   }
707
 
}
708
 
 
709
 
void
710
 
ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin, FILE *out)
711
 
{
712
 
   struct ir3 *ir = so->ir;
713
 
   struct ir3_register *reg;
714
 
   const char *type = ir3_shader_stage(so);
715
 
   uint8_t regid;
716
 
   unsigned i;
717
 
 
718
 
   dump_const_state(so, out);
719
 
 
720
 
   foreach_input_n (instr, i, ir) {
721
 
      reg = instr->dsts[0];
722
 
      regid = reg->num;
723
 
      fprintf(out, "@in(%sr%d.%c)\tin%d",
724
 
              (reg->flags & IR3_REG_HALF) ? "h" : "", (regid >> 2),
725
 
              "xyzw"[regid & 0x3], i);
726
 
 
727
 
      if (reg->wrmask > 0x1)
728
 
         fprintf(out, " (wrmask=0x%x)", reg->wrmask);
729
 
      fprintf(out, "\n");
730
 
   }
731
 
 
732
 
   /* print pre-dispatch texture fetches: */
733
 
   for (i = 0; i < so->num_sampler_prefetch; i++) {
734
 
      const struct ir3_sampler_prefetch *fetch = &so->sampler_prefetch[i];
735
 
      fprintf(out,
736
 
              "@tex(%sr%d.%c)\tsrc=%u, samp=%u, tex=%u, wrmask=0x%x, cmd=%u\n",
737
 
              fetch->half_precision ? "h" : "", fetch->dst >> 2,
738
 
              "xyzw"[fetch->dst & 0x3], fetch -> src, fetch -> samp_id,
739
 
              fetch -> tex_id, fetch -> wrmask, fetch -> cmd);
740
 
   }
741
 
 
742
 
   const struct ir3_const_state *const_state = ir3_const_state(so);
743
 
   for (i = 0; i < DIV_ROUND_UP(const_state->immediates_count, 4); i++) {
744
 
      fprintf(out, "@const(c%d.x)\t", const_state->offsets.immediate + i);
745
 
      fprintf(out, "0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
746
 
              const_state->immediates[i * 4 + 0],
747
 
              const_state->immediates[i * 4 + 1],
748
 
              const_state->immediates[i * 4 + 2],
749
 
              const_state->immediates[i * 4 + 3]);
750
 
   }
751
 
 
752
 
   isa_decode(bin, so->info.sizedwords * 4, out,
753
 
              &(struct isa_decode_options){
754
 
                 .gpu_id = fd_dev_gpu_id(ir->compiler->dev_id),
755
 
                 .show_errors = true,
756
 
                 .branch_labels = true,
757
 
              });
758
 
 
759
 
   fprintf(out, "; %s: outputs:", type);
760
 
   for (i = 0; i < so->outputs_count; i++) {
761
 
      uint8_t regid = so->outputs[i].regid;
762
 
      const char *reg_type = so->outputs[i].half ? "hr" : "r";
763
 
      fprintf(out, " %s%d.%c (%s)", reg_type, (regid >> 2), "xyzw"[regid & 0x3],
764
 
              output_name(so, i));
765
 
   }
766
 
   fprintf(out, "\n");
767
 
 
768
 
   fprintf(out, "; %s: inputs:", type);
769
 
   for (i = 0; i < so->inputs_count; i++) {
770
 
      uint8_t regid = so->inputs[i].regid;
771
 
      fprintf(out, " r%d.%c (%s slot=%d cm=%x,il=%u,b=%u)", (regid >> 2),
772
 
              "xyzw"[regid & 0x3], input_name(so, i), so -> inputs[i].slot,
773
 
              so->inputs[i].compmask, so->inputs[i].inloc, so->inputs[i].bary);
774
 
   }
775
 
   fprintf(out, "\n");
776
 
 
777
 
   /* print generic shader info: */
778
 
   fprintf(
779
 
      out,
780
 
      "; %s prog %d/%d: %u instr, %u nops, %u non-nops, %u mov, %u cov, %u dwords\n",
781
 
      type, so->shader->id, so->id, so->info.instrs_count, so->info.nops_count,
782
 
      so->info.instrs_count - so->info.nops_count, so->info.mov_count,
783
 
      so->info.cov_count, so->info.sizedwords);
784
 
 
785
 
   fprintf(out,
786
 
           "; %s prog %d/%d: %u last-baryf, %d half, %d full, %u constlen\n",
787
 
           type, so->shader->id, so->id, so->info.last_baryf,
788
 
           so->info.max_half_reg + 1, so->info.max_reg + 1, so->constlen);
789
 
 
790
 
   fprintf(
791
 
      out,
792
 
      "; %s prog %d/%d: %u cat0, %u cat1, %u cat2, %u cat3, %u cat4, %u cat5, %u cat6, %u cat7, \n",
793
 
      type, so->shader->id, so->id, so->info.instrs_per_cat[0],
794
 
      so->info.instrs_per_cat[1], so->info.instrs_per_cat[2],
795
 
      so->info.instrs_per_cat[3], so->info.instrs_per_cat[4],
796
 
      so->info.instrs_per_cat[5], so->info.instrs_per_cat[6],
797
 
      so->info.instrs_per_cat[7]);
798
 
 
799
 
   fprintf(
800
 
      out,
801
 
      "; %s prog %d/%d: %u sstall, %u (ss), %u systall, %u (sy), %d loops\n",
802
 
      type, so->shader->id, so->id, so->info.sstall, so->info.ss,
803
 
      so->info.systall, so->info.sy, so->loops);
804
 
 
805
 
   /* print shader type specific info: */
806
 
   switch (so->type) {
807
 
   case MESA_SHADER_VERTEX:
808
 
      dump_output(out, so, VARYING_SLOT_POS, "pos");
809
 
      dump_output(out, so, VARYING_SLOT_PSIZ, "psize");
810
 
      break;
811
 
   case MESA_SHADER_FRAGMENT:
812
 
      dump_reg(out, "pos (ij_pixel)",
813
 
               ir3_find_sysval_regid(so, SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL));
814
 
      dump_reg(
815
 
         out, "pos (ij_centroid)",
816
 
         ir3_find_sysval_regid(so, SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID));
817
 
      dump_reg(out, "pos (ij_size)",
818
 
               ir3_find_sysval_regid(so, SYSTEM_VALUE_BARYCENTRIC_PERSP_SIZE));
819
 
      dump_output(out, so, FRAG_RESULT_DEPTH, "posz");
820
 
      if (so->color0_mrt) {
821
 
         dump_output(out, so, FRAG_RESULT_COLOR, "color");
822
 
      } else {
823
 
         dump_output(out, so, FRAG_RESULT_DATA0, "data0");
824
 
         dump_output(out, so, FRAG_RESULT_DATA1, "data1");
825
 
         dump_output(out, so, FRAG_RESULT_DATA2, "data2");
826
 
         dump_output(out, so, FRAG_RESULT_DATA3, "data3");
827
 
         dump_output(out, so, FRAG_RESULT_DATA4, "data4");
828
 
         dump_output(out, so, FRAG_RESULT_DATA5, "data5");
829
 
         dump_output(out, so, FRAG_RESULT_DATA6, "data6");
830
 
         dump_output(out, so, FRAG_RESULT_DATA7, "data7");
831
 
      }
832
 
      dump_reg(out, "fragcoord",
833
 
               ir3_find_sysval_regid(so, SYSTEM_VALUE_FRAG_COORD));
834
 
      dump_reg(out, "fragface",
835
 
               ir3_find_sysval_regid(so, SYSTEM_VALUE_FRONT_FACE));
836
 
      break;
837
 
   default:
838
 
      /* TODO */
839
 
      break;
840
 
   }
841
 
 
842
 
   fprintf(out, "\n");
843
 
}
844
 
 
845
 
uint64_t
846
 
ir3_shader_outputs(const struct ir3_shader *so)
847
 
{
848
 
   return so->nir->info.outputs_written;
849
 
}
850
 
 
851
 
/* Add any missing varyings needed for stream-out.  Otherwise varyings not
852
 
 * used by fragment shader will be stripped out.
853
 
 */
854
 
void
855
 
ir3_link_stream_out(struct ir3_shader_linkage *l,
856
 
                    const struct ir3_shader_variant *v)
857
 
{
858
 
   const struct ir3_stream_output_info *strmout = &v->shader->stream_output;
859
 
 
860
 
   /*
861
 
    * First, any stream-out varyings not already in linkage map (ie. also
862
 
    * consumed by frag shader) need to be added:
863
 
    */
864
 
   for (unsigned i = 0; i < strmout->num_outputs; i++) {
865
 
      const struct ir3_stream_output *out = &strmout->output[i];
866
 
      unsigned k = out->register_index;
867
 
      unsigned compmask =
868
 
         (1 << (out->num_components + out->start_component)) - 1;
869
 
      unsigned idx, nextloc = 0;
870
 
 
871
 
      /* psize/pos need to be the last entries in linkage map, and will
872
 
       * get added link_stream_out, so skip over them:
873
 
       */
874
 
      if ((v->outputs[k].slot == VARYING_SLOT_PSIZ) ||
875
 
          (v->outputs[k].slot == VARYING_SLOT_POS))
876
 
         continue;
877
 
 
878
 
      for (idx = 0; idx < l->cnt; idx++) {
879
 
         if (l->var[idx].slot == v->outputs[k].slot)
880
 
            break;
881
 
         nextloc = MAX2(nextloc, l->var[idx].loc + 4);
882
 
      }
883
 
 
884
 
      /* add if not already in linkage map: */
885
 
      if (idx == l->cnt) {
886
 
         ir3_link_add(l, v->outputs[k].slot, v->outputs[k].regid,
887
 
                      compmask, nextloc);
888
 
      }
889
 
 
890
 
      /* expand component-mask if needed, ie streaming out all components
891
 
       * but frag shader doesn't consume all components:
892
 
       */
893
 
      if (compmask & ~l->var[idx].compmask) {
894
 
         l->var[idx].compmask |= compmask;
895
 
         l->max_loc = MAX2(
896
 
            l->max_loc, l->var[idx].loc + util_last_bit(l->var[idx].compmask));
897
 
      }
898
 
   }
899
 
}