~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/microsoft/compiler/dxil_nir.c

  • Committer: mmach
  • Date: 2023-11-02 21:31:35 UTC
  • Revision ID: netbit73@gmail.com-20231102213135-18d4tzh7tj0uz752
2023-11-02 22:11:57

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 */
23
23
 
24
24
#include "dxil_nir.h"
 
25
#include "dxil_module.h"
25
26
 
26
27
#include "nir_builder.h"
27
28
#include "nir_deref.h"
 
29
#include "nir_worklist.h"
28
30
#include "nir_to_dxil.h"
29
31
#include "util/u_math.h"
30
32
#include "vulkan/vulkan_core.h"
56
58
 
57
59
      dst_comps[i] = nir_u2uN(b, src_comps[src_offs], dst_bit_size);
58
60
      for (unsigned j = 1; j < comps_per_dst && src_offs + j < num_src_comps; j++) {
59
 
         nir_ssa_def *tmp = nir_ishl(b, nir_u2uN(b, src_comps[src_offs + j], dst_bit_size),
60
 
                                          nir_imm_int(b, j * src_bit_size));
 
61
         nir_ssa_def *tmp = nir_ishl_imm(b, nir_u2uN(b, src_comps[src_offs + j], dst_bit_size),
 
62
                                         j * src_bit_size);
61
63
         dst_comps[i] = nir_ior(b, dst_comps[i], tmp);
62
64
      }
63
65
   }
65
67
   return nir_vec(b, dst_comps, num_dst_comps);
66
68
}
67
69
 
68
 
static nir_ssa_def *
69
 
build_load_ptr_dxil(nir_builder *b, nir_deref_instr *deref, nir_ssa_def *idx)
70
 
{
71
 
   return nir_load_ptr_dxil(b, 1, 32, &deref->dest.ssa, idx);
72
 
}
73
 
 
74
 
static bool
75
 
lower_load_deref(nir_builder *b, nir_intrinsic_instr *intr)
76
 
{
77
 
   assert(intr->dest.is_ssa);
78
 
 
79
 
   b->cursor = nir_before_instr(&intr->instr);
80
 
 
81
 
   nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
82
 
   if (!nir_deref_mode_is(deref, nir_var_shader_temp))
83
 
      return false;
84
 
   nir_ssa_def *ptr = nir_u2u32(b, nir_build_deref_offset(b, deref, cl_type_size_align));
85
 
   nir_ssa_def *offset = nir_iand(b, ptr, nir_inot(b, nir_imm_int(b, 3)));
86
 
 
87
 
   assert(intr->dest.is_ssa);
88
 
   unsigned num_components = nir_dest_num_components(intr->dest);
89
 
   unsigned bit_size = nir_dest_bit_size(intr->dest);
90
 
   unsigned load_size = MAX2(32, bit_size);
91
 
   unsigned num_bits = num_components * bit_size;
92
 
   nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
93
 
   unsigned comp_idx = 0;
94
 
 
95
 
   nir_deref_path path;
96
 
   nir_deref_path_init(&path, deref, NULL);
97
 
   nir_ssa_def *base_idx = nir_ishr(b, offset, nir_imm_int(b, 2 /* log2(32 / 8) */));
98
 
 
99
 
   /* Split loads into 32-bit chunks */
100
 
   for (unsigned i = 0; i < num_bits; i += load_size) {
101
 
      unsigned subload_num_bits = MIN2(num_bits - i, load_size);
102
 
      nir_ssa_def *idx = nir_iadd(b, base_idx, nir_imm_int(b, i / 32));
103
 
      nir_ssa_def *vec32 = build_load_ptr_dxil(b, path.path[0], idx);
104
 
 
105
 
      if (load_size == 64) {
106
 
         idx = nir_iadd(b, idx, nir_imm_int(b, 1));
107
 
         vec32 = nir_vec2(b, vec32,
108
 
                             build_load_ptr_dxil(b, path.path[0], idx));
109
 
      }
110
 
 
111
 
      /* If we have 2 bytes or less to load we need to adjust the u32 value so
112
 
       * we can always extract the LSB.
113
 
       */
114
 
      if (subload_num_bits <= 16) {
115
 
         nir_ssa_def *shift = nir_imul(b, nir_iand(b, ptr, nir_imm_int(b, 3)),
116
 
                                          nir_imm_int(b, 8));
117
 
         vec32 = nir_ushr(b, vec32, shift);
118
 
      }
119
 
 
120
 
      /* And now comes the pack/unpack step to match the original type. */
121
 
      nir_ssa_def *temp_vec = nir_extract_bits(b, &vec32, 1, 0, subload_num_bits / bit_size, bit_size);
122
 
      for (unsigned comp = 0; comp < subload_num_bits / bit_size; ++comp, ++comp_idx)
123
 
         comps[comp_idx] = nir_channel(b, temp_vec, comp);
124
 
   }
125
 
 
126
 
   nir_deref_path_finish(&path);
127
 
   assert(comp_idx == num_components);
128
 
   nir_ssa_def *result = nir_vec(b, comps, num_components);
129
 
   nir_ssa_def_rewrite_uses(&intr->dest.ssa, result);
130
 
   nir_instr_remove(&intr->instr);
131
 
   return true;
132
 
}
133
 
 
134
 
static nir_ssa_def *
135
 
ubo_load_select_32b_comps(nir_builder *b, nir_ssa_def *vec32,
136
 
                          nir_ssa_def *offset, unsigned alignment)
137
 
{
138
 
   assert(alignment >= 16 || alignment == 8 ||
139
 
          alignment == 4 || alignment == 2 ||
140
 
          alignment == 1);
141
 
   assert(vec32->num_components == 4);
142
 
 
143
 
   if (alignment > 8)
144
 
      return vec32;
145
 
 
146
 
   nir_ssa_def *comps[4];
147
 
   nir_ssa_def *cond;
148
 
 
149
 
   for (unsigned i = 0; i < 4; i++)
150
 
      comps[i] = nir_channel(b, vec32, i);
151
 
 
152
 
   /* If we have 8bytes alignment or less, select which half the vec4 should
153
 
    * be used.
154
 
    */
155
 
   cond = nir_ine(b, nir_iand(b, offset, nir_imm_int(b, 0x8)),
156
 
                                 nir_imm_int(b, 0));
157
 
 
158
 
   comps[0] = nir_bcsel(b, cond, comps[2], comps[0]);
159
 
   comps[1] = nir_bcsel(b, cond, comps[3], comps[1]);
160
 
 
161
 
   if (alignment == 8)
162
 
      return nir_vec(b, comps, 2);
163
 
 
164
 
   /* 4 byte align or less needed, select which of the 32bit component should be
165
 
    * used and return it. The sub-32bit split is handled in nir_extract_bits().
166
 
    */
167
 
   cond = nir_ine(b, nir_iand(b, offset, nir_imm_int(b, 0x4)),
168
 
                                 nir_imm_int(b, 0));
169
 
   return nir_bcsel(b, cond, comps[1], comps[0]);
170
 
}
171
 
 
172
 
nir_ssa_def *
173
 
build_load_ubo_dxil(nir_builder *b, nir_ssa_def *buffer,
174
 
                    nir_ssa_def *offset, unsigned num_components,
175
 
                    unsigned bit_size, unsigned alignment)
176
 
{
177
 
   nir_ssa_def *idx = nir_ushr(b, offset, nir_imm_int(b, 4));
178
 
   nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
179
 
   unsigned num_bits = num_components * bit_size;
180
 
   unsigned comp_idx = 0;
181
 
 
182
 
   /* We need to split loads in 16byte chunks because that's the
183
 
    * granularity of cBufferLoadLegacy().
184
 
    */
185
 
   for (unsigned i = 0; i < num_bits; i += (16 * 8)) {
186
 
      /* For each 16byte chunk (or smaller) we generate a 32bit ubo vec
187
 
       * load.
188
 
       */
189
 
      unsigned subload_num_bits = MIN2(num_bits - i, 16 * 8);
190
 
      nir_ssa_def *vec32 =
191
 
         nir_load_ubo_dxil(b, 4, 32, buffer, nir_iadd(b, idx, nir_imm_int(b, i / (16 * 8))));
192
 
 
193
 
      /* First re-arrange the vec32 to account for intra 16-byte offset. */
194
 
      assert(subload_num_bits / 8 <= alignment);
195
 
      vec32 = ubo_load_select_32b_comps(b, vec32, offset, alignment);
196
 
 
197
 
      /* If we have 2 bytes or less to load we need to adjust the u32 value so
198
 
       * we can always extract the LSB.
199
 
       */
200
 
      if (alignment <= 2) {
201
 
         nir_ssa_def *shift = nir_imul(b, nir_iand(b, offset,
202
 
                                                      nir_imm_int(b, 3)),
203
 
                                          nir_imm_int(b, 8));
204
 
         vec32 = nir_ushr(b, vec32, shift);
205
 
      }
206
 
 
207
 
      /* And now comes the pack/unpack step to match the original type. */
208
 
      nir_ssa_def *temp_vec = nir_extract_bits(b, &vec32, 1, 0, subload_num_bits / bit_size, bit_size);
209
 
      for (unsigned comp = 0; comp < subload_num_bits / bit_size; ++comp, ++comp_idx)
210
 
         comps[comp_idx] = nir_channel(b, temp_vec, comp);
211
 
   }
212
 
 
213
 
   assert(comp_idx == num_components);
214
 
   return nir_vec(b, comps, num_components);
215
 
}
216
 
 
217
 
static bool
218
 
lower_load_ssbo(nir_builder *b, nir_intrinsic_instr *intr, unsigned min_bit_size)
219
 
{
220
 
   assert(intr->dest.is_ssa);
221
 
   assert(intr->src[0].is_ssa);
222
 
   assert(intr->src[1].is_ssa);
223
 
 
224
 
   b->cursor = nir_before_instr(&intr->instr);
225
 
 
226
 
   unsigned src_bit_size = nir_dest_bit_size(intr->dest);
227
 
   unsigned store_bit_size = CLAMP(src_bit_size, min_bit_size, 32);
228
 
   unsigned offset_mask = store_bit_size / 8 - 1;
229
 
 
230
 
   nir_ssa_def *buffer = intr->src[0].ssa;
231
 
   nir_ssa_def *offset = nir_iand(b, intr->src[1].ssa, nir_imm_int(b, ~offset_mask));
232
 
   enum gl_access_qualifier access = nir_intrinsic_access(intr);
233
 
   unsigned num_components = nir_dest_num_components(intr->dest);
234
 
   unsigned num_bits = num_components * src_bit_size;
235
 
 
236
 
   nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
237
 
   unsigned comp_idx = 0;
238
 
 
239
 
   /* We need to split loads in 4-component chunks because that's the optimal
240
 
    * granularity of bufferLoad(). Minimum alignment is 2-byte.
241
 
    */
242
 
   for (unsigned i = 0; i < num_bits; i += 4 * store_bit_size) {
243
 
      /* For each 4-component chunk (or smaller) we generate a N-bit ssbo vec load. */
244
 
      unsigned subload_num_bits = MIN2(num_bits - i, 4 * store_bit_size);
245
 
 
246
 
      /* The number of components to store depends on the number of bytes. */
247
 
      nir_ssa_def *result =
248
 
         nir_load_ssbo(b, DIV_ROUND_UP(subload_num_bits, store_bit_size), store_bit_size,
249
 
                       buffer, nir_iadd(b, offset, nir_imm_int(b, i / 8)),
250
 
                       .align_mul = store_bit_size / 8,
251
 
                       .align_offset = 0,
252
 
                       .access = access);
253
 
 
254
 
      /* If we have an unaligned load we need to adjust the result value so
255
 
       * we can always extract the LSB.
256
 
       */
257
 
      if (nir_intrinsic_align(intr) < store_bit_size / 8) {
258
 
         nir_ssa_def *shift = nir_imul(b, nir_iand(b, intr->src[1].ssa, nir_imm_int(b, offset_mask)),
259
 
                                          nir_imm_int(b, 8));
260
 
         result = nir_ushr(b, result, shift);
261
 
      }
262
 
 
263
 
      /* And now comes the pack/unpack step to match the original type. */
264
 
      nir_ssa_def *temp_vec = nir_extract_bits(b, &result, 1, 0, subload_num_bits / src_bit_size, src_bit_size);
265
 
      for (unsigned comp = 0; comp < subload_num_bits / src_bit_size; ++comp, ++comp_idx)
266
 
         comps[comp_idx] = nir_channel(b, temp_vec, comp);
267
 
   }
268
 
 
269
 
   assert(comp_idx == num_components);
270
 
   nir_ssa_def *result = nir_vec(b, comps, num_components);
271
 
   nir_ssa_def_rewrite_uses(&intr->dest.ssa, result);
272
 
   nir_instr_remove(&intr->instr);
273
 
   return true;
274
 
}
275
 
 
276
 
static bool
277
 
lower_store_ssbo(nir_builder *b, nir_intrinsic_instr *intr, unsigned min_bit_size)
278
 
{
279
 
   b->cursor = nir_before_instr(&intr->instr);
280
 
 
281
 
   assert(intr->src[0].is_ssa);
282
 
   assert(intr->src[1].is_ssa);
283
 
   assert(intr->src[2].is_ssa);
284
 
 
285
 
   nir_ssa_def *val = intr->src[0].ssa;
286
 
   nir_ssa_def *buffer = intr->src[1].ssa;
287
 
 
288
 
   unsigned src_bit_size = val->bit_size;
289
 
   unsigned store_bit_size = CLAMP(src_bit_size, min_bit_size, 32);
290
 
   unsigned masked_store_bit_size = 32;
291
 
   unsigned num_components = val->num_components;
292
 
   unsigned num_bits = num_components * src_bit_size;
293
 
 
294
 
   unsigned offset_mask = store_bit_size / 8 - 1;
295
 
   unsigned masked_store_offset_mask = masked_store_bit_size / 8 - 1;
296
 
   nir_ssa_def *offset = nir_iand(b, intr->src[2].ssa, nir_imm_int(b, ~offset_mask));
297
 
   nir_ssa_def *masked_offset = nir_iand(b, intr->src[2].ssa, nir_imm_int(b, ~masked_store_offset_mask));
298
 
 
299
 
   nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS] = { 0 };
300
 
   unsigned comp_idx = 0;
301
 
 
302
 
   unsigned write_mask = nir_intrinsic_write_mask(intr);
303
 
   for (unsigned i = 0; i < num_components; i++)
304
 
      if (write_mask & (1 << i))
305
 
         comps[i] = nir_channel(b, val, i);
306
 
 
307
 
   /* We split stores in 4-component chunks because that's the optimal granularity
308
 
    * of bufferStore(). Minimum alignment is 2-byte. */
309
 
   unsigned bit_offset = 0;
310
 
   while (true) {
311
 
      /* Skip over holes in the write mask */
312
 
      while (comp_idx < num_components && comps[comp_idx] == NULL) {
313
 
         comp_idx++;
314
 
         bit_offset += src_bit_size;
315
 
      }
316
 
      if (comp_idx >= num_components)
317
 
         break;
318
 
 
319
 
      /* For each 4-component chunk (or smaller) we generate a ssbo vec
320
 
       * store. If a component is skipped by the write mask, do a smaller
321
 
       * sub-store
322
 
       */
323
 
      unsigned num_src_comps_stored = 0, substore_num_bits = 0;
324
 
      while(num_src_comps_stored + comp_idx < num_components &&
325
 
            substore_num_bits + bit_offset < num_bits &&
326
 
            substore_num_bits < 4 * store_bit_size &&
327
 
            comps[comp_idx + num_src_comps_stored]) {
328
 
         ++num_src_comps_stored;
329
 
         substore_num_bits += src_bit_size;
330
 
      }
331
 
      bool force_masked = false;
332
 
      if (substore_num_bits > store_bit_size &&
333
 
          substore_num_bits % store_bit_size != 0) {
334
 
         /* Split this into two, one unmasked store of the first bits,
335
 
          * and then the second loop iteration will handle a masked store
336
 
          * for the rest. */
337
 
         assert(num_src_comps_stored == 3);
338
 
         if (store_bit_size == 16) {
339
 
            assert(substore_num_bits < 32);
340
 
            /* If we're already doing atomics to store, just do one
341
 
             * 32bit masked store instead of a 16bit store and a masked
342
 
             * store for the other 8 bits. */
343
 
            force_masked = true;
344
 
         } else {
345
 
            --num_src_comps_stored;
346
 
            substore_num_bits = store_bit_size;
347
 
         }
348
 
      }
349
 
      nir_intrinsic_instr *store;
350
 
 
351
 
      if (substore_num_bits < store_bit_size || force_masked) {
352
 
         nir_ssa_def *store_vec = load_comps_to_vec(b, src_bit_size, &comps[comp_idx],
353
 
                                                    num_src_comps_stored, masked_store_bit_size);
354
 
         nir_ssa_def *mask = nir_imm_intN_t(b, (1 << substore_num_bits) - 1, masked_store_bit_size);
355
 
 
356
 
        /* If we have small alignments we need to place them correctly in the component. */
357
 
         if (nir_intrinsic_align(intr) <= masked_store_bit_size / 8) {
358
 
            nir_ssa_def *pos = nir_iand(b, intr->src[2].ssa, nir_imm_int(b, masked_store_offset_mask));
359
 
            nir_ssa_def *shift = nir_imul_imm(b, pos, 8);
360
 
 
361
 
            store_vec = nir_ishl(b, store_vec, shift);
362
 
            mask = nir_ishl(b, mask, shift);
363
 
         }
364
 
 
365
 
         nir_ssa_def *local_offset = nir_iadd(b, masked_offset, nir_imm_int(b, bit_offset / 8));
366
 
         store = nir_intrinsic_instr_create(b->shader,
367
 
                                            nir_intrinsic_store_ssbo_masked_dxil);
368
 
         store->src[0] = nir_src_for_ssa(store_vec);
369
 
         store->src[1] = nir_src_for_ssa(nir_inot(b, mask));
370
 
         store->src[2] = nir_src_for_ssa(buffer);
371
 
         store->src[3] = nir_src_for_ssa(local_offset);
372
 
      } else {
373
 
         nir_ssa_def *local_offset = nir_iadd(b, offset, nir_imm_int(b, bit_offset / 8));
374
 
         nir_ssa_def *store_vec = load_comps_to_vec(b, src_bit_size, &comps[comp_idx],
375
 
                                                    num_src_comps_stored, store_bit_size);
376
 
         store = nir_intrinsic_instr_create(b->shader,
377
 
                                            nir_intrinsic_store_ssbo);
378
 
         store->src[0] = nir_src_for_ssa(store_vec);
379
 
         store->src[1] = nir_src_for_ssa(buffer);
380
 
         store->src[2] = nir_src_for_ssa(local_offset);
381
 
 
382
 
         nir_intrinsic_set_align(store, store_bit_size / 8, 0);
383
 
      }
384
 
 
385
 
      /* The number of components to store depends on the number of bits. */
386
 
      store->num_components = DIV_ROUND_UP(substore_num_bits, store_bit_size);
387
 
      nir_builder_instr_insert(b, &store->instr);
388
 
      comp_idx += num_src_comps_stored;
389
 
      bit_offset += substore_num_bits;
390
 
 
391
 
      if (nir_intrinsic_has_write_mask(store))
392
 
         nir_intrinsic_set_write_mask(store, (1 << store->num_components) - 1);
393
 
   }
394
 
 
395
 
   nir_instr_remove(&intr->instr);
396
 
   return true;
397
 
}
398
 
 
399
 
static void
400
 
lower_load_vec32(nir_builder *b, nir_ssa_def *index, unsigned num_comps, nir_ssa_def **comps, nir_intrinsic_op op)
401
 
{
402
 
   for (unsigned i = 0; i < num_comps; i++) {
403
 
      nir_intrinsic_instr *load =
404
 
         nir_intrinsic_instr_create(b->shader, op);
405
 
 
406
 
      load->num_components = 1;
407
 
      load->src[0] = nir_src_for_ssa(nir_iadd(b, index, nir_imm_int(b, i)));
408
 
      nir_ssa_dest_init(&load->instr, &load->dest, 1, 32, NULL);
409
 
      nir_builder_instr_insert(b, &load->instr);
410
 
      comps[i] = &load->dest.ssa;
411
 
   }
412
 
}
413
 
 
414
 
static bool
415
 
lower_32b_offset_load(nir_builder *b, nir_intrinsic_instr *intr)
416
 
{
417
 
   assert(intr->dest.is_ssa);
418
 
   unsigned bit_size = nir_dest_bit_size(intr->dest);
419
 
   unsigned num_components = nir_dest_num_components(intr->dest);
420
 
   unsigned num_bits = num_components * bit_size;
421
 
 
422
 
   b->cursor = nir_before_instr(&intr->instr);
423
 
   nir_intrinsic_op op = intr->intrinsic;
 
70
static bool
 
71
lower_32b_offset_load(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var)
 
72
{
 
73
   assert(intr->dest.is_ssa);
 
74
   unsigned bit_size = nir_dest_bit_size(intr->dest);
 
75
   unsigned num_components = nir_dest_num_components(intr->dest);
 
76
   unsigned num_bits = num_components * bit_size;
 
77
 
 
78
   b->cursor = nir_before_instr(&intr->instr);
424
79
 
425
80
   assert(intr->src[0].is_ssa);
426
81
   nir_ssa_def *offset = intr->src[0].ssa;
427
 
   if (op == nir_intrinsic_load_shared) {
428
 
      offset = nir_iadd(b, offset, nir_imm_int(b, nir_intrinsic_base(intr)));
429
 
      op = nir_intrinsic_load_shared_dxil;
430
 
   } else {
 
82
   if (intr->intrinsic == nir_intrinsic_load_shared)
 
83
      offset = nir_iadd_imm(b, offset, nir_intrinsic_base(intr));
 
84
   else
431
85
      offset = nir_u2u32(b, offset);
432
 
      op = nir_intrinsic_load_scratch_dxil;
433
 
   }
434
 
   nir_ssa_def *index = nir_ushr(b, offset, nir_imm_int(b, 2));
 
86
   nir_ssa_def *index = nir_ushr_imm(b, offset, 2);
435
87
   nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
436
88
   nir_ssa_def *comps_32bit[NIR_MAX_VEC_COMPONENTS * 2];
437
89
 
439
91
    * is an i32 array and DXIL does not support type casts.
440
92
    */
441
93
   unsigned num_32bit_comps = DIV_ROUND_UP(num_bits, 32);
442
 
   lower_load_vec32(b, index, num_32bit_comps, comps_32bit, op);
 
94
   for (unsigned i = 0; i < num_32bit_comps; i++)
 
95
      comps_32bit[i] = nir_load_array_var(b, var, nir_iadd_imm(b, index, i));
443
96
   unsigned num_comps_per_pass = MIN2(num_32bit_comps, 4);
444
97
 
445
98
   for (unsigned i = 0; i < num_32bit_comps; i += num_comps_per_pass) {
452
105
       */
453
106
      if (num_bits <= 16) {
454
107
         nir_ssa_def *shift =
455
 
            nir_imul(b, nir_iand(b, offset, nir_imm_int(b, 3)),
456
 
                        nir_imm_int(b, 8));
 
108
            nir_imul_imm(b, nir_iand_imm(b, offset, 3), 8);
457
109
         vec32 = nir_ushr(b, vec32, shift);
458
110
      }
459
111
 
472
124
}
473
125
 
474
126
static void
475
 
lower_store_vec32(nir_builder *b, nir_ssa_def *index, nir_ssa_def *vec32, nir_intrinsic_op op)
476
 
{
477
 
   for (unsigned i = 0; i < vec32->num_components; i++) {
478
 
      nir_intrinsic_instr *store =
479
 
         nir_intrinsic_instr_create(b->shader, op);
480
 
 
481
 
      store->src[0] = nir_src_for_ssa(nir_channel(b, vec32, i));
482
 
      store->src[1] = nir_src_for_ssa(nir_iadd(b, index, nir_imm_int(b, i)));
483
 
      store->num_components = 1;
484
 
      nir_builder_instr_insert(b, &store->instr);
485
 
   }
486
 
}
487
 
 
488
 
static void
489
127
lower_masked_store_vec32(nir_builder *b, nir_ssa_def *offset, nir_ssa_def *index,
490
 
                         nir_ssa_def *vec32, unsigned num_bits, nir_intrinsic_op op, unsigned alignment)
 
128
                         nir_ssa_def *vec32, unsigned num_bits, nir_variable *var, unsigned alignment)
491
129
{
492
130
   nir_ssa_def *mask = nir_imm_int(b, (1 << num_bits) - 1);
493
131
 
494
132
   /* If we have small alignments, we need to place them correctly in the u32 component. */
495
133
   if (alignment <= 2) {
496
134
      nir_ssa_def *shift =
497
 
         nir_imul_imm(b, nir_iand(b, offset, nir_imm_int(b, 3)), 8);
 
135
         nir_imul_imm(b, nir_iand_imm(b, offset, 3), 8);
498
136
 
499
137
      vec32 = nir_ishl(b, vec32, shift);
500
138
      mask = nir_ishl(b, mask, shift);
501
139
   }
502
140
 
503
 
   if (op == nir_intrinsic_store_shared_dxil) {
 
141
   if (var->data.mode == nir_var_mem_shared) {
504
142
      /* Use the dedicated masked intrinsic */
505
 
      nir_store_shared_masked_dxil(b, vec32, nir_inot(b, mask), index);
 
143
      nir_deref_instr *deref = nir_build_deref_array(b, nir_build_deref_var(b, var), index);
 
144
      nir_deref_atomic(b, 32, &deref->dest.ssa, nir_inot(b, mask), .atomic_op = nir_atomic_op_iand);
 
145
      nir_deref_atomic(b, 32, &deref->dest.ssa, vec32, .atomic_op = nir_atomic_op_ior);
506
146
   } else {
507
147
      /* For scratch, since we don't need atomics, just generate the read-modify-write in NIR */
508
 
      nir_ssa_def *load = nir_load_scratch_dxil(b, 1, 32, index);
 
148
      nir_ssa_def *load = nir_load_array_var(b, var, index);
509
149
 
510
150
      nir_ssa_def *new_val = nir_ior(b, vec32,
511
151
                                     nir_iand(b,
512
152
                                              nir_inot(b, mask),
513
153
                                              load));
514
154
 
515
 
      lower_store_vec32(b, index, new_val, op);
 
155
      nir_store_array_var(b, var, index, new_val, 1);
516
156
   }
517
157
}
518
158
 
519
159
static bool
520
 
lower_32b_offset_store(nir_builder *b, nir_intrinsic_instr *intr)
 
160
lower_32b_offset_store(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var)
521
161
{
522
162
   assert(intr->src[0].is_ssa);
523
163
   unsigned num_components = nir_src_num_components(intr->src[0]);
525
165
   unsigned num_bits = num_components * bit_size;
526
166
 
527
167
   b->cursor = nir_before_instr(&intr->instr);
528
 
   nir_intrinsic_op op = intr->intrinsic;
529
168
 
530
169
   nir_ssa_def *offset = intr->src[1].ssa;
531
 
   if (op == nir_intrinsic_store_shared) {
532
 
      offset = nir_iadd(b, offset, nir_imm_int(b, nir_intrinsic_base(intr)));
533
 
      op = nir_intrinsic_store_shared_dxil;
534
 
   } else {
 
170
   if (intr->intrinsic == nir_intrinsic_store_shared)
 
171
      offset = nir_iadd_imm(b, offset, nir_intrinsic_base(intr));
 
172
   else
535
173
      offset = nir_u2u32(b, offset);
536
 
      op = nir_intrinsic_store_scratch_dxil;
537
 
   }
538
174
   nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
539
175
 
540
176
   unsigned comp_idx = 0;
545
181
   for (unsigned i = 0; i < num_bits; i += step) {
546
182
      /* For each 4byte chunk (or smaller) we generate a 32bit scalar store. */
547
183
      unsigned substore_num_bits = MIN2(num_bits - i, step);
548
 
      nir_ssa_def *local_offset = nir_iadd(b, offset, nir_imm_int(b, i / 8));
 
184
      nir_ssa_def *local_offset = nir_iadd_imm(b, offset, i / 8);
549
185
      nir_ssa_def *vec32 = load_comps_to_vec(b, bit_size, &comps[comp_idx],
550
186
                                             substore_num_bits / bit_size, 32);
551
 
      nir_ssa_def *index = nir_ushr(b, local_offset, nir_imm_int(b, 2));
 
187
      nir_ssa_def *index = nir_ushr_imm(b, local_offset, 2);
552
188
 
553
189
      /* For anything less than 32bits we need to use the masked version of the
554
190
       * intrinsic to preserve data living in the same 32bit slot. */
555
191
      if (substore_num_bits < 32) {
556
 
         lower_masked_store_vec32(b, local_offset, index, vec32, num_bits, op, nir_intrinsic_align(intr));
 
192
         lower_masked_store_vec32(b, local_offset, index, vec32, num_bits, var, nir_intrinsic_align(intr));
557
193
      } else {
558
 
         lower_store_vec32(b, index, vec32, op);
 
194
         for (unsigned i = 0; i < vec32->num_components; ++i)
 
195
            nir_store_array_var(b, var, nir_iadd_imm(b, index, i), nir_channel(b, vec32, i), 1);
559
196
      }
560
197
 
561
198
      comp_idx += substore_num_bits / bit_size;
566
203
   return true;
567
204
}
568
205
 
569
 
static void
570
 
ubo_to_temp_patch_deref_mode(nir_deref_instr *deref)
571
 
{
572
 
   deref->modes = nir_var_shader_temp;
573
 
   nir_foreach_use(use_src, &deref->dest.ssa) {
574
 
      if (use_src->parent_instr->type != nir_instr_type_deref)
575
 
         continue;
576
 
 
577
 
      nir_deref_instr *parent = nir_instr_as_deref(use_src->parent_instr);
578
 
      ubo_to_temp_patch_deref_mode(parent);
579
 
   }
580
 
}
581
 
 
582
 
static void
583
 
ubo_to_temp_update_entry(nir_deref_instr *deref, struct hash_entry *he)
584
 
{
585
 
   assert(nir_deref_mode_is(deref, nir_var_mem_constant));
586
 
   assert(deref->dest.is_ssa);
587
 
   assert(he->data);
588
 
 
589
 
   nir_foreach_use(use_src, &deref->dest.ssa) {
590
 
      if (use_src->parent_instr->type == nir_instr_type_deref) {
591
 
         ubo_to_temp_update_entry(nir_instr_as_deref(use_src->parent_instr), he);
592
 
      } else if (use_src->parent_instr->type == nir_instr_type_intrinsic) {
593
 
         nir_intrinsic_instr *intr = nir_instr_as_intrinsic(use_src->parent_instr);
594
 
         if (intr->intrinsic != nir_intrinsic_load_deref)
595
 
            he->data = NULL;
596
 
      } else {
597
 
         he->data = NULL;
598
 
      }
599
 
 
600
 
      if (!he->data)
601
 
         break;
602
 
   }
603
 
}
 
206
#define CONSTANT_LOCATION_UNVISITED 0
 
207
#define CONSTANT_LOCATION_VALID 1
 
208
#define CONSTANT_LOCATION_INVALID 2
604
209
 
605
210
bool
606
 
dxil_nir_lower_ubo_to_temp(nir_shader *nir)
 
211
dxil_nir_lower_constant_to_temp(nir_shader *nir)
607
212
{
608
 
   struct hash_table *ubo_to_temp = _mesa_pointer_hash_table_create(NULL);
609
213
   bool progress = false;
 
214
   nir_foreach_variable_with_modes(var, nir, nir_var_mem_constant)
 
215
      var->data.location = var->constant_initializer ?
 
216
         CONSTANT_LOCATION_UNVISITED : CONSTANT_LOCATION_INVALID;
610
217
 
611
218
   /* First pass: collect all UBO accesses that could be turned into
612
219
    * shader temp accesses.
613
220
    */
614
 
   foreach_list_typed(nir_function, func, node, &nir->functions) {
 
221
   nir_foreach_function(func, nir) {
615
222
      if (!func->is_entrypoint)
616
223
         continue;
617
224
      assert(func->impl);
623
230
 
624
231
            nir_deref_instr *deref = nir_instr_as_deref(instr);
625
232
            if (!nir_deref_mode_is(deref, nir_var_mem_constant) ||
626
 
                deref->deref_type != nir_deref_type_var)
627
 
                  continue;
628
 
 
629
 
            struct hash_entry *he =
630
 
               _mesa_hash_table_search(ubo_to_temp, deref->var);
631
 
 
632
 
            if (!he)
633
 
               he = _mesa_hash_table_insert(ubo_to_temp, deref->var, deref->var);
634
 
 
635
 
            if (!he->data)
 
233
                deref->deref_type != nir_deref_type_var ||
 
234
                deref->var->data.location == CONSTANT_LOCATION_INVALID)
636
235
               continue;
637
236
 
638
 
            ubo_to_temp_update_entry(deref, he);
 
237
            deref->var->data.location = nir_deref_instr_has_complex_use(deref, 0) ?
 
238
               CONSTANT_LOCATION_INVALID : CONSTANT_LOCATION_VALID;
639
239
         }
640
240
      }
641
241
   }
642
242
 
643
 
   hash_table_foreach(ubo_to_temp, he) {
644
 
      nir_variable *var = he->data;
645
 
 
646
 
      if (!var)
 
243
   nir_foreach_variable_with_modes(var, nir, nir_var_mem_constant) {
 
244
      if (var->data.location != CONSTANT_LOCATION_VALID)
647
245
         continue;
648
246
 
649
247
      /* Change the variable mode. */
650
248
      var->data.mode = nir_var_shader_temp;
651
249
 
652
 
      /* Make sure the variable has a name.
653
 
       * DXIL variables must have names.
654
 
       */
655
 
      if (!var->name)
656
 
         var->name = ralloc_asprintf(nir, "global_%d", exec_list_length(&nir->variables));
657
 
 
658
250
      progress = true;
659
251
   }
660
 
   _mesa_hash_table_destroy(ubo_to_temp, NULL);
661
252
 
662
253
   /* Second pass: patch all derefs that were accessing the converted UBOs
663
254
    * variables.
664
255
    */
665
 
   foreach_list_typed(nir_function, func, node, &nir->functions) {
 
256
   nir_foreach_function(func, nir) {
666
257
      if (!func->is_entrypoint)
667
258
         continue;
668
259
      assert(func->impl);
669
260
 
 
261
      nir_builder b = nir_builder_create(func->impl);
670
262
      nir_foreach_block(block, func->impl) {
671
263
         nir_foreach_instr_safe(instr, block) {
672
264
            if (instr->type != nir_instr_type_deref)
673
265
               continue;
674
266
 
675
267
            nir_deref_instr *deref = nir_instr_as_deref(instr);
676
 
            if (nir_deref_mode_is(deref, nir_var_mem_constant) &&
677
 
                deref->deref_type == nir_deref_type_var &&
678
 
                deref->var->data.mode == nir_var_shader_temp)
679
 
               ubo_to_temp_patch_deref_mode(deref);
 
268
            if (nir_deref_mode_is(deref, nir_var_mem_constant)) {
 
269
               nir_deref_instr *parent = deref;
 
270
               while (parent && parent->deref_type != nir_deref_type_var)
 
271
                  parent = nir_src_as_deref(parent->parent);
 
272
               if (parent && parent->var->data.mode != nir_var_mem_constant) {
 
273
                  deref->modes = parent->var->data.mode;
 
274
                  /* Also change "pointer" size to 32-bit since this is now a logical pointer */
 
275
                  deref->dest.ssa.bit_size = 32;
 
276
                  if (deref->deref_type == nir_deref_type_array) {
 
277
                     b.cursor = nir_before_instr(instr);
 
278
                     nir_src_rewrite_ssa(&deref->arr.index, nir_u2u32(&b, deref->arr.index.ssa));
 
279
                  }
 
280
               }
 
281
            }
680
282
         }
681
283
      }
682
284
   }
685
287
}
686
288
 
687
289
static bool
688
 
lower_load_ubo(nir_builder *b, nir_intrinsic_instr *intr)
689
 
{
690
 
   assert(intr->dest.is_ssa);
 
290
flatten_var_arrays(nir_builder *b, nir_instr *instr, void *data)
 
291
{
 
292
   if (instr->type != nir_instr_type_intrinsic)
 
293
      return false;
 
294
   nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
 
295
   switch (intr->intrinsic) {
 
296
   case nir_intrinsic_load_deref:
 
297
   case nir_intrinsic_store_deref:
 
298
   case nir_intrinsic_deref_atomic:
 
299
   case nir_intrinsic_deref_atomic_swap:
 
300
      break;
 
301
   default:
 
302
      return false;
 
303
   }
 
304
 
 
305
   nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
 
306
   nir_variable *var = NULL;
 
307
   for (nir_deref_instr *d = deref; d; d = nir_deref_instr_parent(d)) {
 
308
      if (d->deref_type == nir_deref_type_cast)
 
309
         return false;
 
310
      if (d->deref_type == nir_deref_type_var) {
 
311
         var = d->var;
 
312
         if (d->type == var->type)
 
313
            return false;
 
314
      }
 
315
   }
 
316
   if (!var)
 
317
      return false;
 
318
 
 
319
   nir_deref_path path;
 
320
   nir_deref_path_init(&path, deref, NULL);
 
321
 
 
322
   assert(path.path[0]->deref_type == nir_deref_type_var);
 
323
   b->cursor = nir_before_instr(&path.path[0]->instr);
 
324
   nir_deref_instr *new_var_deref = nir_build_deref_var(b, var);
 
325
   nir_ssa_def *index = NULL;
 
326
   for (unsigned level = 1; path.path[level]; ++level) {
 
327
      nir_deref_instr *arr_deref = path.path[level];
 
328
      assert(arr_deref->deref_type == nir_deref_type_array);
 
329
      b->cursor = nir_before_instr(&arr_deref->instr);
 
330
      nir_ssa_def *val = nir_imul_imm(b, arr_deref->arr.index.ssa,
 
331
                                      glsl_get_component_slots(arr_deref->type));
 
332
      if (index) {
 
333
         index = nir_iadd(b, index, val);
 
334
      } else {
 
335
         index = val;
 
336
      }
 
337
   }
 
338
 
 
339
   unsigned vector_comps = intr->num_components;
 
340
   if (vector_comps > 1) {
 
341
      b->cursor = nir_before_instr(instr);
 
342
      if (intr->intrinsic == nir_intrinsic_load_deref) {
 
343
         nir_ssa_def *components[NIR_MAX_VEC_COMPONENTS];
 
344
         for (unsigned i = 0; i < vector_comps; ++i) {
 
345
            nir_ssa_def *final_index = index ? nir_iadd_imm(b, index, i) : nir_imm_int(b, i);
 
346
            nir_deref_instr *comp_deref = nir_build_deref_array(b, new_var_deref, final_index);
 
347
            components[i] = nir_load_deref(b, comp_deref);
 
348
         }
 
349
         nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_vec(b, components, vector_comps));
 
350
      } else if (intr->intrinsic == nir_intrinsic_store_deref) {
 
351
         for (unsigned i = 0; i < vector_comps; ++i) {
 
352
            if (((1 << i) & nir_intrinsic_write_mask(intr)) == 0)
 
353
               continue;
 
354
            nir_ssa_def *final_index = index ? nir_iadd_imm(b, index, i) : nir_imm_int(b, i);
 
355
            nir_deref_instr *comp_deref = nir_build_deref_array(b, new_var_deref, final_index);
 
356
            nir_store_deref(b, comp_deref, nir_channel(b, intr->src[1].ssa, i), 1);
 
357
         }
 
358
      }
 
359
      nir_instr_remove(instr);
 
360
   } else {
 
361
      nir_src_rewrite_ssa(&intr->src[0], &nir_build_deref_array(b, new_var_deref, index)->dest.ssa);
 
362
   }
 
363
 
 
364
   nir_deref_path_finish(&path);
 
365
   return true;
 
366
}
 
367
 
 
368
static void
 
369
flatten_constant_initializer(nir_variable *var, nir_constant *src, nir_constant ***dest, unsigned vector_elements)
 
370
{
 
371
   if (src->num_elements == 0) {
 
372
      for (unsigned i = 0; i < vector_elements; ++i) {
 
373
         nir_constant *new_scalar = rzalloc(var, nir_constant);
 
374
         memcpy(&new_scalar->values[0], &src->values[i], sizeof(src->values[0]));
 
375
         new_scalar->is_null_constant = src->values[i].u64 == 0;
 
376
 
 
377
         nir_constant **array_entry = (*dest)++;
 
378
         *array_entry = new_scalar;
 
379
      }
 
380
   } else {
 
381
      for (unsigned i = 0; i < src->num_elements; ++i)
 
382
         flatten_constant_initializer(var, src->elements[i], dest, vector_elements);
 
383
   }
 
384
}
 
385
 
 
386
static bool
 
387
flatten_var_array_types(nir_variable *var)
 
388
{
 
389
   assert(!glsl_type_is_struct(glsl_without_array(var->type)));
 
390
   const struct glsl_type *matrix_type = glsl_without_array(var->type);
 
391
   if (!glsl_type_is_array_of_arrays(var->type) && glsl_get_components(matrix_type) == 1)
 
392
      return false;
 
393
 
 
394
   enum glsl_base_type base_type = glsl_get_base_type(matrix_type);
 
395
   const struct glsl_type *flattened_type = glsl_array_type(glsl_scalar_type(base_type),
 
396
                                                            glsl_get_component_slots(var->type), 0);
 
397
   var->type = flattened_type;
 
398
   if (var->constant_initializer) {
 
399
      nir_constant **new_elements = ralloc_array(var, nir_constant *, glsl_get_length(flattened_type));
 
400
      nir_constant **temp = new_elements;
 
401
      flatten_constant_initializer(var, var->constant_initializer, &temp, glsl_get_vector_elements(matrix_type));
 
402
      var->constant_initializer->num_elements = glsl_get_length(flattened_type);
 
403
      var->constant_initializer->elements = new_elements;
 
404
   }
 
405
   return true;
 
406
}
 
407
 
 
408
bool
 
409
dxil_nir_flatten_var_arrays(nir_shader *shader, nir_variable_mode modes)
 
410
{
 
411
   bool progress = false;
 
412
   nir_foreach_variable_with_modes(var, shader, modes & ~nir_var_function_temp)
 
413
      progress |= flatten_var_array_types(var);
 
414
 
 
415
   if (modes & nir_var_function_temp) {
 
416
      nir_foreach_function(func, shader) {
 
417
         if (!func->impl)
 
418
            continue;
 
419
         nir_foreach_function_temp_variable(var, func->impl)
 
420
            progress |= flatten_var_array_types(var);
 
421
      }
 
422
   }
 
423
 
 
424
   if (!progress)
 
425
      return false;
 
426
 
 
427
   nir_shader_instructions_pass(shader, flatten_var_arrays,
 
428
                                nir_metadata_block_index |
 
429
                                   nir_metadata_dominance |
 
430
                                   nir_metadata_loop_analysis,
 
431
                                NULL);
 
432
   nir_remove_dead_derefs(shader);
 
433
   return true;
 
434
}
 
435
 
 
436
static bool
 
437
lower_deref_bit_size(nir_builder *b, nir_instr *instr, void *data)
 
438
{
 
439
   if (instr->type != nir_instr_type_intrinsic)
 
440
      return false;
 
441
   nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
 
442
   switch (intr->intrinsic) {
 
443
   case nir_intrinsic_load_deref:
 
444
   case nir_intrinsic_store_deref:
 
445
      break;
 
446
   default:
 
447
      /* Atomics can't be smaller than 32-bit */
 
448
      return false;
 
449
   }
 
450
 
 
451
   nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
 
452
   nir_variable *var = nir_deref_instr_get_variable(deref);
 
453
   /* Only interested in full deref chains */
 
454
   if (!var)
 
455
      return false;
 
456
 
 
457
   const struct glsl_type *var_scalar_type = glsl_without_array(var->type);
 
458
   if (deref->type == var_scalar_type || !glsl_type_is_scalar(var_scalar_type))
 
459
      return false;
 
460
 
 
461
   assert(deref->deref_type == nir_deref_type_var || deref->deref_type == nir_deref_type_array);
 
462
   const struct glsl_type *old_glsl_type = deref->type;
 
463
   nir_alu_type old_type = nir_get_nir_type_for_glsl_type(old_glsl_type);
 
464
   nir_alu_type new_type = nir_get_nir_type_for_glsl_type(var_scalar_type);
 
465
   if (glsl_get_bit_size(old_glsl_type) < glsl_get_bit_size(var_scalar_type)) {
 
466
      deref->type = var_scalar_type;
 
467
      if (intr->intrinsic == nir_intrinsic_load_deref) {
 
468
         intr->dest.ssa.bit_size = glsl_get_bit_size(var_scalar_type);
 
469
         b->cursor = nir_after_instr(instr);
 
470
         nir_ssa_def *downcast = nir_type_convert(b, &intr->dest.ssa, new_type, old_type, nir_rounding_mode_undef);
 
471
         nir_ssa_def_rewrite_uses_after(&intr->dest.ssa, downcast, downcast->parent_instr);
 
472
      }
 
473
      else {
 
474
         b->cursor = nir_before_instr(instr);
 
475
         nir_ssa_def *upcast = nir_type_convert(b, intr->src[1].ssa, old_type, new_type, nir_rounding_mode_undef);
 
476
         nir_src_rewrite_ssa(&intr->src[1], upcast);
 
477
      }
 
478
 
 
479
      while (deref->deref_type == nir_deref_type_array) {
 
480
         nir_deref_instr *parent = nir_deref_instr_parent(deref);
 
481
         parent->type = glsl_type_wrap_in_arrays(deref->type, parent->type);
 
482
         deref = parent;
 
483
      }
 
484
   } else {
 
485
      /* Assumed arrays are already flattened */
 
486
      b->cursor = nir_before_instr(&deref->instr);
 
487
      nir_deref_instr *parent = nir_build_deref_var(b, var);
 
488
      if (deref->deref_type == nir_deref_type_array)
 
489
         deref = nir_build_deref_array(b, parent, nir_imul_imm(b, deref->arr.index.ssa, 2));
 
490
      else
 
491
         deref = nir_build_deref_array_imm(b, parent, 0);
 
492
      nir_deref_instr *deref2 = nir_build_deref_array(b, parent,
 
493
                                                      nir_iadd_imm(b, deref->arr.index.ssa, 1));
 
494
      b->cursor = nir_before_instr(instr);
 
495
      if (intr->intrinsic == nir_intrinsic_load_deref) {
 
496
         nir_ssa_def *src1 = nir_load_deref(b, deref);
 
497
         nir_ssa_def *src2 = nir_load_deref(b, deref2);
 
498
         nir_ssa_def_rewrite_uses(&intr->dest.ssa, nir_pack_64_2x32_split(b, src1, src2));
 
499
      } else {
 
500
         nir_ssa_def *src1 = nir_unpack_64_2x32_split_x(b, intr->src[1].ssa);
 
501
         nir_ssa_def *src2 = nir_unpack_64_2x32_split_y(b, intr->src[1].ssa);
 
502
         nir_store_deref(b, deref, src1, 1);
 
503
         nir_store_deref(b, deref, src2, 1);
 
504
      }
 
505
      nir_instr_remove(instr);
 
506
   }
 
507
   return true;
 
508
}
 
509
 
 
510
static bool
 
511
lower_var_bit_size_types(nir_variable *var, unsigned min_bit_size, unsigned max_bit_size)
 
512
{
 
513
   assert(!glsl_type_is_array_of_arrays(var->type) && !glsl_type_is_struct(var->type));
 
514
   const struct glsl_type *type = glsl_without_array(var->type);
 
515
   assert(glsl_type_is_scalar(type));
 
516
   enum glsl_base_type base_type = glsl_get_base_type(type);
 
517
   if (glsl_base_type_get_bit_size(base_type) < min_bit_size) {
 
518
      switch (min_bit_size) {
 
519
      case 16:
 
520
         switch (base_type) {
 
521
         case GLSL_TYPE_BOOL:
 
522
            base_type = GLSL_TYPE_UINT16;
 
523
            for (unsigned i = 0; i < (var->constant_initializer ? var->constant_initializer->num_elements : 0); ++i)
 
524
               var->constant_initializer->elements[i]->values[0].u16 = var->constant_initializer->elements[i]->values[0].b ? 0xffff : 0;
 
525
            break;
 
526
         case GLSL_TYPE_INT8:
 
527
            base_type = GLSL_TYPE_INT16;
 
528
            for (unsigned i = 0; i < (var->constant_initializer ? var->constant_initializer->num_elements : 0); ++i)
 
529
               var->constant_initializer->elements[i]->values[0].i16 = var->constant_initializer->elements[i]->values[0].i8;
 
530
            break;
 
531
         case GLSL_TYPE_UINT8: base_type = GLSL_TYPE_UINT16; break;
 
532
         default: unreachable("Unexpected base type");
 
533
         }
 
534
         break;
 
535
      case 32:
 
536
         switch (base_type) {
 
537
         case GLSL_TYPE_BOOL:
 
538
            base_type = GLSL_TYPE_UINT;
 
539
            for (unsigned i = 0; i < (var->constant_initializer ? var->constant_initializer->num_elements : 0); ++i)
 
540
               var->constant_initializer->elements[i]->values[0].u32 = var->constant_initializer->elements[i]->values[0].b ? 0xffffffff : 0;
 
541
            break;
 
542
         case GLSL_TYPE_INT8:
 
543
            base_type = GLSL_TYPE_INT;
 
544
            for (unsigned i = 0; i < (var->constant_initializer ? var->constant_initializer->num_elements : 0); ++i)
 
545
               var->constant_initializer->elements[i]->values[0].i32 = var->constant_initializer->elements[i]->values[0].i8;
 
546
            break;
 
547
         case GLSL_TYPE_INT16:
 
548
            base_type = GLSL_TYPE_INT;
 
549
            for (unsigned i = 0; i < (var->constant_initializer ? var->constant_initializer->num_elements : 0); ++i)
 
550
               var->constant_initializer->elements[i]->values[0].i32 = var->constant_initializer->elements[i]->values[0].i16;
 
551
            break;
 
552
         case GLSL_TYPE_FLOAT16:
 
553
            base_type = GLSL_TYPE_FLOAT;
 
554
            for (unsigned i = 0; i < (var->constant_initializer ? var->constant_initializer->num_elements : 0); ++i)
 
555
               var->constant_initializer->elements[i]->values[0].f32 = _mesa_half_to_float(var->constant_initializer->elements[i]->values[0].u16);
 
556
            break;
 
557
         case GLSL_TYPE_UINT8: base_type = GLSL_TYPE_UINT; break;
 
558
         case GLSL_TYPE_UINT16: base_type = GLSL_TYPE_UINT; break;
 
559
         default: unreachable("Unexpected base type");
 
560
         }
 
561
         break;
 
562
      default: unreachable("Unexpected min bit size");
 
563
      }
 
564
      var->type = glsl_type_wrap_in_arrays(glsl_scalar_type(base_type), var->type);
 
565
      return true;
 
566
   }
 
567
   if (glsl_base_type_bit_size(base_type) > max_bit_size) {
 
568
      assert(!glsl_type_is_array_of_arrays(var->type));
 
569
      var->type = glsl_array_type(glsl_scalar_type(GLSL_TYPE_UINT),
 
570
                                    glsl_type_is_array(var->type) ? glsl_get_length(var->type) * 2 : 2,
 
571
                                    0);
 
572
      if (var->constant_initializer) {
 
573
         unsigned num_elements = var->constant_initializer->num_elements ?
 
574
            var->constant_initializer->num_elements * 2 : 2;
 
575
         nir_constant **element_arr = ralloc_array(var, nir_constant *, num_elements);
 
576
         nir_constant *elements = rzalloc_array(var, nir_constant, num_elements);
 
577
         for (unsigned i = 0; i < var->constant_initializer->num_elements; ++i) {
 
578
            element_arr[i*2] = &elements[i*2];
 
579
            element_arr[i*2+1] = &elements[i*2+1];
 
580
            const nir_const_value *src = var->constant_initializer->num_elements ?
 
581
               var->constant_initializer->elements[i]->values : var->constant_initializer->values;
 
582
            elements[i*2].values[0].u32 = (uint32_t)src->u64;
 
583
            elements[i*2].is_null_constant = (uint32_t)src->u64 == 0;
 
584
            elements[i*2+1].values[0].u32 = (uint32_t)(src->u64 >> 32);
 
585
            elements[i*2+1].is_null_constant = (uint32_t)(src->u64 >> 32) == 0;
 
586
         }
 
587
         var->constant_initializer->num_elements = num_elements;
 
588
         var->constant_initializer->elements = element_arr;
 
589
      }
 
590
      return true;
 
591
   }
 
592
   return false;
 
593
}
 
594
 
 
595
bool
 
596
dxil_nir_lower_var_bit_size(nir_shader *shader, nir_variable_mode modes,
 
597
                            unsigned min_bit_size, unsigned max_bit_size)
 
598
{
 
599
   bool progress = false;
 
600
   nir_foreach_variable_with_modes(var, shader, modes & ~nir_var_function_temp)
 
601
      progress |= lower_var_bit_size_types(var, min_bit_size, max_bit_size);
 
602
 
 
603
   if (modes & nir_var_function_temp) {
 
604
      nir_foreach_function(func, shader) {
 
605
         if (!func->impl)
 
606
            continue;
 
607
         nir_foreach_function_temp_variable(var, func->impl)
 
608
            progress |= lower_var_bit_size_types(var, min_bit_size, max_bit_size);
 
609
      }
 
610
   }
 
611
 
 
612
   if (!progress)
 
613
      return false;
 
614
 
 
615
   nir_shader_instructions_pass(shader, lower_deref_bit_size,
 
616
                                nir_metadata_block_index |
 
617
                                   nir_metadata_dominance |
 
618
                                   nir_metadata_loop_analysis,
 
619
                                NULL);
 
620
   nir_remove_dead_derefs(shader);
 
621
   return true;
 
622
}
 
623
 
 
624
static bool
 
625
lower_shared_atomic(nir_builder *b, nir_intrinsic_instr *intr, nir_variable *var)
 
626
{
 
627
   b->cursor = nir_before_instr(&intr->instr);
 
628
 
691
629
   assert(intr->src[0].is_ssa);
692
 
   assert(intr->src[1].is_ssa);
693
 
 
694
 
   b->cursor = nir_before_instr(&intr->instr);
695
 
 
696
 
   nir_ssa_def *result =
697
 
      build_load_ubo_dxil(b, intr->src[0].ssa, intr->src[1].ssa,
698
 
                             nir_dest_num_components(intr->dest),
699
 
                             nir_dest_bit_size(intr->dest),
700
 
                             nir_intrinsic_align(intr));
 
630
   nir_ssa_def *offset =
 
631
      nir_iadd_imm(b, intr->src[0].ssa, nir_intrinsic_base(intr));
 
632
   nir_ssa_def *index = nir_ushr_imm(b, offset, 2);
 
633
 
 
634
   nir_deref_instr *deref = nir_build_deref_array(b, nir_build_deref_var(b, var), index);
 
635
   nir_ssa_def *result;
 
636
   if (intr->intrinsic == nir_intrinsic_shared_atomic_swap)
 
637
      result = nir_deref_atomic_swap(b, 32, &deref->dest.ssa, intr->src[1].ssa, intr->src[2].ssa,
 
638
                                     .atomic_op = nir_intrinsic_atomic_op(intr));
 
639
   else
 
640
      result = nir_deref_atomic(b, 32, &deref->dest.ssa, intr->src[1].ssa,
 
641
                                .atomic_op = nir_intrinsic_atomic_op(intr));
701
642
 
702
643
   nir_ssa_def_rewrite_uses(&intr->dest.ssa, result);
703
644
   nir_instr_remove(&intr->instr);
708
649
dxil_nir_lower_loads_stores_to_dxil(nir_shader *nir,
709
650
                                    const struct dxil_nir_lower_loads_stores_options *options)
710
651
{
711
 
   bool progress = false;
 
652
   bool progress = nir_remove_dead_variables(nir, nir_var_function_temp | nir_var_mem_shared, NULL);
 
653
   nir_variable *shared_var = NULL;
 
654
   if (nir->info.shared_size) {
 
655
      shared_var = nir_variable_create(nir, nir_var_mem_shared,
 
656
                                       glsl_array_type(glsl_uint_type(), DIV_ROUND_UP(nir->info.shared_size, 4), 4),
 
657
                                       "lowered_shared_mem");
 
658
   }
712
659
 
713
 
   foreach_list_typed(nir_function, func, node, &nir->functions) {
714
 
      if (!func->is_entrypoint)
 
660
   unsigned ptr_size = nir->info.cs.ptr_size;
 
661
   if (nir->info.stage == MESA_SHADER_KERNEL) {
 
662
      /* All the derefs created here will be used as GEP indices so force 32-bit */
 
663
      nir->info.cs.ptr_size = 32;
 
664
   }
 
665
   nir_foreach_function(func, nir) {
 
666
      if (!func->impl)
715
667
         continue;
716
 
      assert(func->impl);
717
 
 
718
 
      nir_builder b;
719
 
      nir_builder_init(&b, func->impl);
 
668
 
 
669
      nir_builder b = nir_builder_create(func->impl);
 
670
 
 
671
      nir_variable *scratch_var = NULL;
 
672
      if (nir->scratch_size) {
 
673
         const struct glsl_type *scratch_type = glsl_array_type(glsl_uint_type(), DIV_ROUND_UP(nir->scratch_size, 4), 4);
 
674
         scratch_var = nir_local_variable_create(func->impl, scratch_type, "lowered_scratch_mem");
 
675
      }
720
676
 
721
677
      nir_foreach_block(block, func->impl) {
722
678
         nir_foreach_instr_safe(instr, block) {
725
681
            nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
726
682
 
727
683
            switch (intr->intrinsic) {
728
 
            case nir_intrinsic_load_deref:
729
 
               progress |= lower_load_deref(&b, intr);
730
 
               break;
731
684
            case nir_intrinsic_load_shared:
 
685
               progress |= lower_32b_offset_load(&b, intr, shared_var);
 
686
               break;
732
687
            case nir_intrinsic_load_scratch:
733
 
               progress |= lower_32b_offset_load(&b, intr);
734
 
               break;
735
 
            case nir_intrinsic_load_ssbo:
736
 
               progress |= lower_load_ssbo(&b, intr, options->use_16bit_ssbo ? 16 : 32);
737
 
               break;
738
 
            case nir_intrinsic_load_ubo:
739
 
               progress |= lower_load_ubo(&b, intr);
 
688
               progress |= lower_32b_offset_load(&b, intr, scratch_var);
740
689
               break;
741
690
            case nir_intrinsic_store_shared:
 
691
               progress |= lower_32b_offset_store(&b, intr, shared_var);
 
692
               break;
742
693
            case nir_intrinsic_store_scratch:
743
 
               progress |= lower_32b_offset_store(&b, intr);
744
 
               break;
745
 
            case nir_intrinsic_store_ssbo:
746
 
               progress |= lower_store_ssbo(&b, intr, options->use_16bit_ssbo ? 16 : 32);
747
 
               break;
748
 
            default:
749
 
               break;
750
 
            }
751
 
         }
752
 
      }
753
 
   }
754
 
 
755
 
   return progress;
756
 
}
757
 
 
758
 
static bool
759
 
lower_shared_atomic(nir_builder *b, nir_intrinsic_instr *intr,
760
 
                    nir_intrinsic_op dxil_op)
761
 
{
762
 
   b->cursor = nir_before_instr(&intr->instr);
763
 
 
764
 
   assert(intr->src[0].is_ssa);
765
 
   nir_ssa_def *offset =
766
 
      nir_iadd(b, intr->src[0].ssa, nir_imm_int(b, nir_intrinsic_base(intr)));
767
 
   nir_ssa_def *index = nir_ushr(b, offset, nir_imm_int(b, 2));
768
 
 
769
 
   nir_intrinsic_instr *atomic = nir_intrinsic_instr_create(b->shader, dxil_op);
770
 
   atomic->src[0] = nir_src_for_ssa(index);
771
 
   assert(intr->src[1].is_ssa);
772
 
   atomic->src[1] = nir_src_for_ssa(intr->src[1].ssa);
773
 
   if (dxil_op == nir_intrinsic_shared_atomic_comp_swap_dxil) {
774
 
      assert(intr->src[2].is_ssa);
775
 
      atomic->src[2] = nir_src_for_ssa(intr->src[2].ssa);
776
 
   }
777
 
   atomic->num_components = 0;
778
 
   nir_ssa_dest_init(&atomic->instr, &atomic->dest, 1, 32, NULL);
779
 
 
780
 
   nir_builder_instr_insert(b, &atomic->instr);
781
 
   nir_ssa_def_rewrite_uses(&intr->dest.ssa, &atomic->dest.ssa);
782
 
   nir_instr_remove(&intr->instr);
783
 
   return true;
784
 
}
785
 
 
786
 
bool
787
 
dxil_nir_lower_atomics_to_dxil(nir_shader *nir)
788
 
{
789
 
   bool progress = false;
790
 
 
791
 
   foreach_list_typed(nir_function, func, node, &nir->functions) {
792
 
      if (!func->is_entrypoint)
793
 
         continue;
794
 
      assert(func->impl);
795
 
 
796
 
      nir_builder b;
797
 
      nir_builder_init(&b, func->impl);
798
 
 
799
 
      nir_foreach_block(block, func->impl) {
800
 
         nir_foreach_instr_safe(instr, block) {
801
 
            if (instr->type != nir_instr_type_intrinsic)
802
 
               continue;
803
 
            nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
804
 
 
805
 
            switch (intr->intrinsic) {
806
 
 
807
 
#define ATOMIC(op)                                                            \
808
 
  case nir_intrinsic_shared_atomic_##op:                                     \
809
 
     progress |= lower_shared_atomic(&b, intr,                                \
810
 
                                     nir_intrinsic_shared_atomic_##op##_dxil); \
811
 
     break
812
 
 
813
 
            ATOMIC(add);
814
 
            ATOMIC(imin);
815
 
            ATOMIC(umin);
816
 
            ATOMIC(imax);
817
 
            ATOMIC(umax);
818
 
            ATOMIC(and);
819
 
            ATOMIC(or);
820
 
            ATOMIC(xor);
821
 
            ATOMIC(exchange);
822
 
            ATOMIC(comp_swap);
823
 
 
824
 
#undef ATOMIC
825
 
            default:
826
 
               break;
827
 
            }
828
 
         }
829
 
      }
 
694
               progress |= lower_32b_offset_store(&b, intr, scratch_var);
 
695
               break;
 
696
            case nir_intrinsic_shared_atomic:
 
697
            case nir_intrinsic_shared_atomic_swap:
 
698
               progress |= lower_shared_atomic(&b, intr, shared_var);
 
699
               break;
 
700
            default:
 
701
               break;
 
702
            }
 
703
         }
 
704
      }
 
705
   }
 
706
   if (nir->info.stage == MESA_SHADER_KERNEL) {
 
707
      nir->info.cs.ptr_size = ptr_size;
830
708
   }
831
709
 
832
710
   return progress;
870
748
         continue;
871
749
      assert(func->impl);
872
750
 
873
 
      nir_builder b;
874
 
      nir_builder_init(&b, func->impl);
 
751
      nir_builder b = nir_builder_create(func->impl);
875
752
 
876
753
      nir_foreach_block(block, func->impl) {
877
754
         nir_foreach_instr_safe(instr, block) {
935
812
         continue;
936
813
      assert(func->impl);
937
814
 
938
 
      nir_builder b;
939
 
      nir_builder_init(&b, func->impl);
 
815
      nir_builder b = nir_builder_create(func->impl);
940
816
 
941
817
      nir_foreach_block(block, func->impl) {
942
818
         nir_foreach_instr_safe(instr, block) {
970
846
      nir_phi_instr_add_src(lowered, src->pred, nir_src_for_ssa(cast));
971
847
   }
972
848
 
973
 
   nir_ssa_dest_init(&lowered->instr, &lowered->dest,
974
 
                     num_components, new_bit_size, NULL);
 
849
   nir_ssa_dest_init(&lowered->instr, &lowered->dest, num_components,
 
850
                     new_bit_size);
975
851
 
976
852
   b->cursor = nir_before_instr(&phi->instr);
977
853
   nir_builder_instr_insert(b, &lowered->instr);
986
862
static bool
987
863
upcast_phi_impl(nir_function_impl *impl, unsigned min_bit_size)
988
864
{
989
 
   nir_builder b;
990
 
   nir_builder_init(&b, impl);
 
865
   nir_builder b = nir_builder_create(impl);
991
866
   bool progress = false;
992
867
 
993
868
   nir_foreach_block_reverse(block, impl) {
994
 
      nir_foreach_instr_safe(instr, block) {
995
 
         if (instr->type != nir_instr_type_phi)
996
 
            continue;
997
 
 
998
 
         nir_phi_instr *phi = nir_instr_as_phi(instr);
 
869
      nir_foreach_phi_safe(phi, block) {
999
870
         assert(phi->dest.is_ssa);
1000
871
 
1001
872
         if (phi->dest.ssa.bit_size == 1 ||
1568
1439
      ? 32 : intr->dest.ssa.bit_size;
1569
1440
 
1570
1441
   b->cursor = nir_before_instr(instr);
1571
 
   nir_ssa_def *result = nir_build_load_input(b, intr->dest.ssa.num_components, bit_size, nir_imm_int(b, 0),
 
1442
   nir_ssa_def *result = nir_load_input(b, intr->dest.ssa.num_components, bit_size, nir_imm_int(b, 0),
1572
1443
      .base = var->data.driver_location, .dest_type = dest_type);
1573
1444
 
1574
1445
   /* The nir_type_uint32 is really a nir_type_bool32, but that type is very
1821
1692
      nir_ssa_for_src(b, alu->src[0].src, nir_src_num_components(alu->src[0].src));
1822
1693
 
1823
1694
   nir_ssa_def *neg_inf_cond =
1824
 
      nir_flt(b, src, nir_imm_float(b, -65504.0f));
 
1695
      nir_flt_imm(b, src, -65504.0f);
1825
1696
   nir_ssa_def *pos_inf_cond =
1826
 
      nir_flt(b, nir_imm_float(b, 65504.0f), src);
 
1697
      nir_fgt_imm(b, src, 65504.0f);
1827
1698
   nir_ssa_def *zero_cond =
1828
 
      nir_flt(b, nir_fabs(b, src), nir_imm_float(b, ldexpf(1.0, -14)));
 
1699
      nir_flt_imm(b, nir_fabs(b, src), ldexpf(1.0, -14));
1829
1700
   nir_ssa_def *zero = nir_iand_imm(b, src, 1 << 31);
1830
1701
   nir_ssa_def *round = nir_iand_imm(b, src, ~BITFIELD_MASK(13));
1831
1702
 
1849
1720
      return false;
1850
1721
 
1851
1722
   nir_deref_instr *deref = nir_instr_as_deref(instr);
1852
 
   nir_variable *var =
1853
 
      deref->deref_type == nir_deref_type_var ? deref->var : NULL;
 
1723
   nir_variable *var = nir_deref_instr_get_variable(deref);
1854
1724
 
1855
1725
   if (var == data) {
1856
 
      deref->type = var->type;
 
1726
      deref->type = glsl_type_wrap_in_arrays(glsl_uint_type(), deref->type);
1857
1727
      return true;
1858
1728
   }
1859
1729
 
1866
1736
   nir_variable *fixed_var = NULL;
1867
1737
   nir_foreach_variable_with_modes(var, s, modes) {
1868
1738
      if (var->data.location == slot) {
1869
 
         if (var->type == glsl_uint_type())
 
1739
         const struct glsl_type *plain_type = glsl_without_array(var->type);
 
1740
         if (plain_type == glsl_uint_type())
1870
1741
            return false;
1871
1742
 
1872
 
         assert(var->type == glsl_int_type());
1873
 
         var->type = glsl_uint_type();
 
1743
         assert(plain_type == glsl_int_type());
 
1744
         var->type = glsl_type_wrap_in_arrays(glsl_uint_type(), var->type);
1874
1745
         fixed_var = var;
1875
1746
         break;
1876
1747
      }
2084
1955
      nir_pop_if(b, nif);
2085
1956
 
2086
1957
      nir_scoped_barrier(b,
2087
 
                         .execution_scope = NIR_SCOPE_WORKGROUP,
2088
 
                         .memory_scope = NIR_SCOPE_WORKGROUP,
 
1958
                         .execution_scope = SCOPE_WORKGROUP,
 
1959
                         .memory_scope = SCOPE_WORKGROUP,
2089
1960
                         .memory_semantics = NIR_MEMORY_ACQ_REL,
2090
1961
                         .memory_modes = nir_var_mem_shared);
2091
1962
 
2092
1963
      nif = nir_push_if(b, nir_elect(b, 1));
2093
 
      nir_ssa_def *subgroup_id_first_thread = nir_deref_atomic_add(b, 32, &counter_deref->dest.ssa, nir_imm_int(b, 1));
 
1964
      nir_ssa_def *subgroup_id_first_thread = nir_deref_atomic(b, 32, &counter_deref->dest.ssa, nir_imm_int(b, 1),
 
1965
                                                               .atomic_op = nir_atomic_op_iadd);
2094
1966
      nir_store_var(b, subgroup_id_local, subgroup_id_first_thread, 1);
2095
1967
      nir_pop_if(b, nif);
2096
1968
 
2217
2089
      if (!function->impl)
2218
2090
         continue;
2219
2091
 
2220
 
      nir_builder b;
2221
 
      nir_builder_init(&b, function->impl);
 
2092
      nir_builder b = nir_builder_create(function->impl);
2222
2093
 
2223
2094
      nir_foreach_block(block, function->impl) {
2224
2095
         nir_foreach_instr_safe(instr, block) {
2318
2189
 
2319
2190
   b->cursor = nir_before_instr(instr);
2320
2191
   nir_op op = nir_intrinsic_reduction_op(intr);
2321
 
   nir_ssa_def *subgroup_id = nir_build_load_subgroup_invocation(b);
2322
 
   nir_ssa_def *active_threads = nir_build_ballot(b, 4, 32, nir_imm_bool(b, true));
 
2192
   nir_ssa_def *subgroup_id = nir_load_subgroup_invocation(b);
 
2193
   nir_ssa_def *active_threads = nir_ballot(b, 4, 32, nir_imm_true(b));
2323
2194
   nir_ssa_def *base_value;
2324
2195
   uint32_t bit_size = intr->dest.ssa.bit_size;
2325
2196
   if (op == nir_op_iand || op == nir_op_umin)
2347
2218
   nir_if *nif = nir_push_if(b, intr->intrinsic == nir_intrinsic_inclusive_scan ?
2348
2219
      nir_ige(b, subgroup_id, loop_counter) :
2349
2220
      nir_ilt(b, loop_counter, subgroup_id));
2350
 
   nir_if *if_active_thread = nir_push_if(b, nir_build_ballot_bitfield_extract(b, 32, active_threads, loop_counter));
 
2221
   nir_if *if_active_thread = nir_push_if(b, nir_ballot_bitfield_extract(b, 32, active_threads, loop_counter));
2351
2222
   nir_ssa_def *result = nir_build_alu2(b, op,
2352
2223
                                        nir_load_var(b, result_var),
2353
 
                                        nir_build_read_invocation(b, intr->src[0].ssa, loop_counter));
 
2224
                                        nir_read_invocation(b, intr->src[0].ssa, loop_counter));
2354
2225
   nir_store_var(b, result_var, result, 1);
2355
2226
   nir_pop_if(b, if_active_thread);
2356
2227
   nir_store_var(b, loop_counter_var, nir_iadd_imm(b, loop_counter, 1), 1);
2411
2282
                                       nir_metadata_block_index | nir_metadata_dominance,
2412
2283
                                       var);
2413
2284
}
 
2285
 
 
2286
static bool
 
2287
move_consts(nir_builder *b, nir_instr *instr, void *data)
 
2288
{
 
2289
   bool progress = false;
 
2290
   switch (instr->type) {
 
2291
   case nir_instr_type_load_const: {
 
2292
      /* Sink load_const to their uses if there's multiple */
 
2293
      nir_load_const_instr *load_const = nir_instr_as_load_const(instr);
 
2294
      if (!list_is_singular(&load_const->def.uses)) {
 
2295
         nir_foreach_use_safe(src, &load_const->def) {
 
2296
            b->cursor = nir_before_src(src);
 
2297
            nir_load_const_instr *new_load = nir_load_const_instr_create(b->shader,
 
2298
                                                                         load_const->def.num_components,
 
2299
                                                                         load_const->def.bit_size);
 
2300
            memcpy(new_load->value, load_const->value, sizeof(load_const->value[0]) * load_const->def.num_components);
 
2301
            nir_builder_instr_insert(b, &new_load->instr);
 
2302
            nir_src_rewrite_ssa(src, &new_load->def);
 
2303
            progress = true;
 
2304
         }
 
2305
      }
 
2306
      return progress;
 
2307
   }
 
2308
   default:
 
2309
      return false;
 
2310
   }
 
2311
}
 
2312
 
 
2313
/* Sink all consts so that they have only have a single use.
 
2314
 * The DXIL backend will already de-dupe the constants to the
 
2315
 * same dxil_value if they have the same type, but this allows a single constant
 
2316
 * to have different types without bitcasts. */
 
2317
bool
 
2318
dxil_nir_move_consts(nir_shader *s)
 
2319
{
 
2320
   return nir_shader_instructions_pass(s, move_consts,
 
2321
                                       nir_metadata_block_index | nir_metadata_dominance,
 
2322
                                       NULL);
 
2323
}
 
2324
 
 
2325
static void
 
2326
clear_pass_flags(nir_function_impl *impl)
 
2327
{
 
2328
   nir_foreach_block(block, impl) {
 
2329
      nir_foreach_instr(instr, block) {
 
2330
         instr->pass_flags = 0;
 
2331
      }
 
2332
   }
 
2333
}
 
2334
 
 
2335
static bool
 
2336
add_dest_to_worklist(nir_dest *dest, void *state)
 
2337
{
 
2338
   assert(dest->is_ssa);
 
2339
   nir_foreach_use_including_if(src, &dest->ssa) {
 
2340
      assert(src->is_ssa);
 
2341
      if (src->is_if) {
 
2342
         nir_if *nif = src->parent_if;
 
2343
         nir_foreach_block_in_cf_node(block, &nif->cf_node) {
 
2344
            nir_foreach_instr(instr, block)
 
2345
               nir_instr_worklist_push_tail(state, instr);
 
2346
         }
 
2347
      } else
 
2348
         nir_instr_worklist_push_tail(state, src->parent_instr);
 
2349
   }
 
2350
   return true;
 
2351
}
 
2352
 
 
2353
static bool
 
2354
set_input_bits(struct dxil_module *mod, nir_intrinsic_instr *intr, BITSET_WORD *input_bits, uint32_t ***tables, const uint32_t **table_sizes)
 
2355
{
 
2356
   if (intr->intrinsic == nir_intrinsic_load_view_index) {
 
2357
      BITSET_SET(input_bits, 0);
 
2358
      return true;
 
2359
   }
 
2360
   
 
2361
   bool any_bits_set = false;
 
2362
   nir_src *row_src = intr->intrinsic == nir_intrinsic_load_per_vertex_input ? &intr->src[1] : &intr->src[0];
 
2363
   bool is_patch_constant = mod->shader_kind == DXIL_DOMAIN_SHADER && intr->intrinsic == nir_intrinsic_load_input;
 
2364
   const struct dxil_signature_record *sig_rec = is_patch_constant ?
 
2365
      &mod->patch_consts[nir_intrinsic_base(intr)] :
 
2366
      &mod->inputs[mod->input_mappings[nir_intrinsic_base(intr)]];
 
2367
   if (is_patch_constant) {
 
2368
      /* Redirect to the second I/O table */
 
2369
      *tables = *tables + 1;
 
2370
      *table_sizes = *table_sizes + 1;
 
2371
   }
 
2372
   for (uint32_t component = 0; component < intr->num_components; ++component) {
 
2373
      uint32_t base_element = 0;
 
2374
      uint32_t num_elements = sig_rec->num_elements;
 
2375
      if (nir_src_is_const(*row_src)) {
 
2376
         base_element = (uint32_t)nir_src_as_uint(*row_src);
 
2377
         num_elements = 1;
 
2378
      }
 
2379
      for (uint32_t element = 0; element < num_elements; ++element) {
 
2380
         uint32_t row = sig_rec->elements[element + base_element].reg;
 
2381
         if (row == 0xffffffff)
 
2382
            continue;
 
2383
         BITSET_SET(input_bits, row * 4 + component + nir_intrinsic_component(intr));
 
2384
         any_bits_set = true;
 
2385
      }
 
2386
   }
 
2387
   return any_bits_set;
 
2388
}
 
2389
 
 
2390
static bool
 
2391
set_output_bits(struct dxil_module *mod, nir_intrinsic_instr *intr, BITSET_WORD *input_bits, uint32_t **tables, const uint32_t *table_sizes)
 
2392
{
 
2393
   bool any_bits_set = false;
 
2394
   nir_src *row_src = intr->intrinsic == nir_intrinsic_store_per_vertex_output ? &intr->src[2] : &intr->src[1];
 
2395
   bool is_patch_constant = mod->shader_kind == DXIL_HULL_SHADER && intr->intrinsic == nir_intrinsic_store_output;
 
2396
   const struct dxil_signature_record *sig_rec = is_patch_constant ?
 
2397
      &mod->patch_consts[nir_intrinsic_base(intr)] :
 
2398
      &mod->outputs[nir_intrinsic_base(intr)];
 
2399
   for (uint32_t component = 0; component < intr->num_components; ++component) {
 
2400
      uint32_t base_element = 0;
 
2401
      uint32_t num_elements = sig_rec->num_elements;
 
2402
      if (nir_src_is_const(*row_src)) {
 
2403
         base_element = (uint32_t)nir_src_as_uint(*row_src);
 
2404
         num_elements = 1;
 
2405
      }
 
2406
      for (uint32_t element = 0; element < num_elements; ++element) {
 
2407
         uint32_t row = sig_rec->elements[element + base_element].reg;
 
2408
         if (row == 0xffffffff)
 
2409
            continue;
 
2410
         uint32_t stream = sig_rec->elements[element + base_element].stream;
 
2411
         uint32_t table_idx = is_patch_constant ? 1 : stream;
 
2412
         uint32_t *table = tables[table_idx];
 
2413
         uint32_t output_component = component + nir_intrinsic_component(intr);
 
2414
         uint32_t input_component;
 
2415
         BITSET_FOREACH_SET(input_component, input_bits, 32 * 4) {
 
2416
            uint32_t *table_for_input_component = table + table_sizes[table_idx] * input_component;
 
2417
            BITSET_SET(table_for_input_component, row * 4 + output_component);
 
2418
            any_bits_set = true;
 
2419
         }
 
2420
      }
 
2421
   }
 
2422
   return any_bits_set;
 
2423
}
 
2424
 
 
2425
static bool
 
2426
propagate_input_to_output_dependencies(struct dxil_module *mod, nir_intrinsic_instr *load_intr, uint32_t **tables, const uint32_t *table_sizes)
 
2427
{
 
2428
   /* Which input components are being loaded by this instruction */
 
2429
   BITSET_DECLARE(input_bits, 32 * 4) = { 0 };
 
2430
   if (!set_input_bits(mod, load_intr, input_bits, &tables, &table_sizes))
 
2431
      return false;
 
2432
 
 
2433
   nir_instr_worklist *worklist = nir_instr_worklist_create();
 
2434
   nir_instr_worklist_push_tail(worklist, &load_intr->instr);
 
2435
   bool any_bits_set = false;
 
2436
   nir_foreach_instr_in_worklist(instr, worklist) {
 
2437
      if (instr->pass_flags)
 
2438
         continue;
 
2439
 
 
2440
      instr->pass_flags = 1;
 
2441
      nir_foreach_dest(instr, add_dest_to_worklist, worklist);
 
2442
      switch (instr->type) {
 
2443
      case nir_instr_type_jump: {
 
2444
         nir_jump_instr *jump = nir_instr_as_jump(instr);
 
2445
         switch (jump->type) {
 
2446
         case nir_jump_break:
 
2447
         case nir_jump_continue: {
 
2448
            nir_cf_node *parent = &instr->block->cf_node;
 
2449
            while (parent->type != nir_cf_node_loop)
 
2450
               parent = parent->parent;
 
2451
            nir_foreach_block_in_cf_node(block, parent)
 
2452
               nir_foreach_instr(i, block)
 
2453
               nir_instr_worklist_push_tail(worklist, i);
 
2454
            }
 
2455
            break;
 
2456
         default:
 
2457
            unreachable("Don't expect any other jumps");
 
2458
         }
 
2459
         break;
 
2460
      }
 
2461
      case nir_instr_type_intrinsic: {
 
2462
         nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
 
2463
         switch (intr->intrinsic) {
 
2464
         case nir_intrinsic_store_output:
 
2465
         case nir_intrinsic_store_per_vertex_output:
 
2466
            any_bits_set |= set_output_bits(mod, intr, input_bits, tables, table_sizes);
 
2467
            break;
 
2468
            /* TODO: Memory writes */
 
2469
         default:
 
2470
            break;
 
2471
         }
 
2472
         break;
 
2473
      }
 
2474
      default:
 
2475
         break;
 
2476
      }
 
2477
   }
 
2478
 
 
2479
   nir_instr_worklist_destroy(worklist);
 
2480
   return any_bits_set;
 
2481
}
 
2482
 
 
2483
/* For every input load, compute the set of output stores that it can contribute to.
 
2484
 * If it contributes to a store to memory, If it's used for control flow, then any
 
2485
 * instruction in the CFG that it impacts is considered to contribute.
 
2486
 * Ideally, we should also handle stores to outputs/memory and then loads from that
 
2487
 * output/memory, but this is non-trivial and unclear how much impact that would have. */
 
2488
bool
 
2489
dxil_nir_analyze_io_dependencies(struct dxil_module *mod, nir_shader *s)
 
2490
{
 
2491
   bool any_outputs = false;
 
2492
   for (uint32_t i = 0; i < 4; ++i)
 
2493
      any_outputs |= mod->num_psv_outputs[i] > 0;
 
2494
   if (mod->shader_kind == DXIL_HULL_SHADER)
 
2495
      any_outputs |= mod->num_psv_patch_consts > 0;
 
2496
   if (!any_outputs)
 
2497
      return false;
 
2498
 
 
2499
   bool any_bits_set = false;
 
2500
   nir_foreach_function(func, s) {
 
2501
      assert(func->impl);
 
2502
      /* Hull shaders have a patch constant function */
 
2503
      assert(func->is_entrypoint || s->info.stage == MESA_SHADER_TESS_CTRL);
 
2504
 
 
2505
      /* Pass 1: input/view ID -> output dependencies */
 
2506
      nir_foreach_block(block, func->impl) {
 
2507
         nir_foreach_instr(instr, block) {
 
2508
            if (instr->type != nir_instr_type_intrinsic)
 
2509
               continue;
 
2510
            nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
 
2511
            uint32_t **tables = mod->io_dependency_table;
 
2512
            const uint32_t *table_sizes = mod->dependency_table_dwords_per_input;
 
2513
            switch (intr->intrinsic) {
 
2514
            case nir_intrinsic_load_view_index:
 
2515
               tables = mod->viewid_dependency_table;
 
2516
               FALLTHROUGH;
 
2517
            case nir_intrinsic_load_input:
 
2518
            case nir_intrinsic_load_per_vertex_input:
 
2519
            case nir_intrinsic_load_interpolated_input:
 
2520
               break;
 
2521
            default:
 
2522
               continue;
 
2523
            }
 
2524
 
 
2525
            clear_pass_flags(func->impl);
 
2526
            any_bits_set |= propagate_input_to_output_dependencies(mod, intr, tables, table_sizes);
 
2527
         }
 
2528
      }
 
2529
 
 
2530
      /* Pass 2: output -> output dependencies */
 
2531
      /* TODO */
 
2532
   }
 
2533
   return any_bits_set;
 
2534
}
 
2535
 
 
2536
static enum pipe_format
 
2537
get_format_for_var(unsigned num_comps, enum glsl_base_type sampled_type)
 
2538
{
 
2539
   switch (sampled_type) {
 
2540
   case GLSL_TYPE_INT:
 
2541
   case GLSL_TYPE_INT64:
 
2542
   case GLSL_TYPE_INT16:
 
2543
      switch (num_comps) {
 
2544
      case 1: return PIPE_FORMAT_R32_SINT;
 
2545
      case 2: return PIPE_FORMAT_R32G32_SINT;
 
2546
      case 3: return PIPE_FORMAT_R32G32B32_SINT;
 
2547
      case 4: return PIPE_FORMAT_R32G32B32A32_SINT;
 
2548
      default: unreachable("Invalid num_comps");
 
2549
      }
 
2550
   case GLSL_TYPE_UINT:
 
2551
   case GLSL_TYPE_UINT64:
 
2552
   case GLSL_TYPE_UINT16:
 
2553
      switch (num_comps) {
 
2554
      case 1: return PIPE_FORMAT_R32_UINT;
 
2555
      case 2: return PIPE_FORMAT_R32G32_UINT;
 
2556
      case 3: return PIPE_FORMAT_R32G32B32_UINT;
 
2557
      case 4: return PIPE_FORMAT_R32G32B32A32_UINT;
 
2558
      default: unreachable("Invalid num_comps");
 
2559
      }
 
2560
   case GLSL_TYPE_FLOAT:
 
2561
   case GLSL_TYPE_FLOAT16:
 
2562
   case GLSL_TYPE_DOUBLE:
 
2563
      switch (num_comps) {
 
2564
      case 1: return PIPE_FORMAT_R32_FLOAT;
 
2565
      case 2: return PIPE_FORMAT_R32G32_FLOAT;
 
2566
      case 3: return PIPE_FORMAT_R32G32B32_FLOAT;
 
2567
      case 4: return PIPE_FORMAT_R32G32B32A32_FLOAT;
 
2568
      default: unreachable("Invalid num_comps");
 
2569
      }
 
2570
   default: unreachable("Invalid sampler return type");
 
2571
   }
 
2572
}
 
2573
 
 
2574
static unsigned
 
2575
aoa_size(const struct glsl_type *type)
 
2576
{
 
2577
   return glsl_type_is_array(type) ? glsl_get_aoa_size(type) : 1;
 
2578
}
 
2579
 
 
2580
static bool
 
2581
guess_image_format_for_var(nir_shader *s, nir_variable *var)
 
2582
{
 
2583
   const struct glsl_type *base_type = glsl_without_array(var->type);
 
2584
   if (!glsl_type_is_image(base_type))
 
2585
      return false;
 
2586
   if (var->data.image.format != PIPE_FORMAT_NONE)
 
2587
      return false;
 
2588
 
 
2589
   nir_foreach_function(func, s) {
 
2590
      if (!func->impl)
 
2591
         continue;
 
2592
      nir_foreach_block(block, func->impl) {
 
2593
         nir_foreach_instr(instr, block) {
 
2594
            if (instr->type != nir_instr_type_intrinsic)
 
2595
               continue;
 
2596
            nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
 
2597
            switch (intr->intrinsic) {
 
2598
            case nir_intrinsic_image_deref_load:
 
2599
            case nir_intrinsic_image_deref_store:
 
2600
            case nir_intrinsic_image_deref_atomic:
 
2601
            case nir_intrinsic_image_deref_atomic_swap:
 
2602
               if (nir_intrinsic_get_var(intr, 0) != var)
 
2603
                  continue;
 
2604
               break;
 
2605
            case nir_intrinsic_image_load:
 
2606
            case nir_intrinsic_image_store:
 
2607
            case nir_intrinsic_image_atomic:
 
2608
            case nir_intrinsic_image_atomic_swap: {
 
2609
               unsigned binding = nir_src_as_uint(intr->src[0]);
 
2610
               if (binding < var->data.binding ||
 
2611
                   binding >= var->data.binding + aoa_size(var->type))
 
2612
                  continue;
 
2613
               break;
 
2614
               }
 
2615
            default:
 
2616
               continue;
 
2617
            }
 
2618
            break;
 
2619
 
 
2620
            switch (intr->intrinsic) {
 
2621
            case nir_intrinsic_image_deref_load:
 
2622
            case nir_intrinsic_image_load:
 
2623
            case nir_intrinsic_image_deref_store:
 
2624
            case nir_intrinsic_image_store:
 
2625
               /* Increase unknown formats up to 4 components if a 4-component accessor is used */
 
2626
               if (intr->num_components > util_format_get_nr_components(var->data.image.format))
 
2627
                  var->data.image.format = get_format_for_var(intr->num_components, glsl_get_sampler_result_type(base_type));
 
2628
               break;
 
2629
            default:
 
2630
               /* If an atomic is used, the image format must be 1-component; return immediately */
 
2631
               var->data.image.format = get_format_for_var(1, glsl_get_sampler_result_type(base_type));
 
2632
               return true;
 
2633
            }
 
2634
         }
 
2635
      }
 
2636
   }
 
2637
   /* Dunno what it is, assume 4-component */
 
2638
   if (var->data.image.format == PIPE_FORMAT_NONE)
 
2639
      var->data.image.format = get_format_for_var(4, glsl_get_sampler_result_type(base_type));
 
2640
   return true;
 
2641
}
 
2642
 
 
2643
static bool
 
2644
update_intrinsic_formats(nir_builder *b, nir_instr *instr, void *data)
 
2645
{
 
2646
   if (instr->type != nir_instr_type_intrinsic)
 
2647
      return false;
 
2648
   nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
 
2649
   if (!nir_intrinsic_has_format(intr))
 
2650
      return false;
 
2651
   nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
 
2652
   if (deref) {
 
2653
      nir_variable *var = nir_deref_instr_get_variable(deref);
 
2654
      if (var)
 
2655
         nir_intrinsic_set_format(intr, var->data.image.format);
 
2656
      return var != NULL;
 
2657
   }
 
2658
 
 
2659
   if (!nir_intrinsic_has_range_base(intr))
 
2660
      return false;
 
2661
 
 
2662
   unsigned binding = nir_src_as_uint(intr->src[0]);
 
2663
   nir_foreach_variable_with_modes(var, b->shader, nir_var_image) {
 
2664
      if (var->data.binding <= binding &&
 
2665
          var->data.binding + aoa_size(var->type) > binding) {
 
2666
         nir_intrinsic_set_format(intr, var->data.image.format);
 
2667
         return true;
 
2668
      }
 
2669
   }
 
2670
   return false;
 
2671
}
 
2672
 
 
2673
bool
 
2674
dxil_nir_guess_image_formats(nir_shader *s)
 
2675
{
 
2676
   bool progress = false;
 
2677
   nir_foreach_variable_with_modes(var, s, nir_var_image) {
 
2678
      progress |= guess_image_format_for_var(s, var);
 
2679
   }
 
2680
   nir_shader_instructions_pass(s, update_intrinsic_formats, nir_metadata_all, NULL);
 
2681
   return progress;
 
2682
}