~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/amd/compiler/tests/helpers.cpp

  • 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 "helpers.h"
 
25
 
 
26
#include "common/amd_family.h"
25
27
#include "vulkan/vk_format.h"
26
 
#include "common/amd_family.h"
27
 
#include <stdio.h>
28
 
#include <sstream>
 
28
 
29
29
#include <llvm-c/Target.h>
 
30
 
30
31
#include <mutex>
 
32
#include <sstream>
 
33
#include <stdio.h>
31
34
 
32
35
using namespace aco;
33
36
 
34
37
extern "C" {
35
 
PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
36
 
        VkInstance                                  instance,
37
 
        const char*                                 pName);
 
38
PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName);
38
39
}
39
40
 
40
41
ac_shader_config config;
47
48
static VkDevice device_cache[CHIP_LAST] = {VK_NULL_HANDLE};
48
49
static std::mutex create_device_mutex;
49
50
 
50
 
#define FUNCTION_LIST\
51
 
   ITEM(CreateInstance)\
52
 
   ITEM(DestroyInstance)\
53
 
   ITEM(EnumeratePhysicalDevices)\
54
 
   ITEM(GetPhysicalDeviceProperties2)\
55
 
   ITEM(CreateDevice)\
56
 
   ITEM(DestroyDevice)\
57
 
   ITEM(CreateShaderModule)\
58
 
   ITEM(DestroyShaderModule)\
59
 
   ITEM(CreateGraphicsPipelines)\
60
 
   ITEM(CreateComputePipelines)\
61
 
   ITEM(DestroyPipeline)\
62
 
   ITEM(CreateDescriptorSetLayout)\
63
 
   ITEM(DestroyDescriptorSetLayout)\
64
 
   ITEM(CreatePipelineLayout)\
65
 
   ITEM(DestroyPipelineLayout)\
66
 
   ITEM(CreateRenderPass)\
67
 
   ITEM(DestroyRenderPass)\
68
 
   ITEM(GetPipelineExecutablePropertiesKHR)\
 
51
#define FUNCTION_LIST                                                                              \
 
52
   ITEM(CreateInstance)                                                                            \
 
53
   ITEM(DestroyInstance)                                                                           \
 
54
   ITEM(EnumeratePhysicalDevices)                                                                  \
 
55
   ITEM(GetPhysicalDeviceProperties2)                                                              \
 
56
   ITEM(CreateDevice)                                                                              \
 
57
   ITEM(DestroyDevice)                                                                             \
 
58
   ITEM(CreateShaderModule)                                                                        \
 
59
   ITEM(DestroyShaderModule)                                                                       \
 
60
   ITEM(CreateGraphicsPipelines)                                                                   \
 
61
   ITEM(CreateComputePipelines)                                                                    \
 
62
   ITEM(DestroyPipeline)                                                                           \
 
63
   ITEM(CreateDescriptorSetLayout)                                                                 \
 
64
   ITEM(DestroyDescriptorSetLayout)                                                                \
 
65
   ITEM(CreatePipelineLayout)                                                                      \
 
66
   ITEM(DestroyPipelineLayout)                                                                     \
 
67
   ITEM(CreateRenderPass)                                                                          \
 
68
   ITEM(DestroyRenderPass)                                                                         \
 
69
   ITEM(GetPipelineExecutablePropertiesKHR)                                                        \
69
70
   ITEM(GetPipelineExecutableInternalRepresentationsKHR)
70
71
 
71
72
#define ITEM(n) PFN_vk##n n;
72
73
FUNCTION_LIST
73
74
#undef ITEM
74
75
 
75
 
void create_program(enum amd_gfx_level gfx_level, Stage stage, unsigned wave_size, enum radeon_family family)
 
76
void
 
77
create_program(enum amd_gfx_level gfx_level, Stage stage, unsigned wave_size,
 
78
               enum radeon_family family)
76
79
{
77
80
   memset(&config, 0, sizeof(config));
78
81
   info.wave_size = wave_size;
90
93
   program->debug.func = nullptr;
91
94
   program->debug.private_data = nullptr;
92
95
 
93
 
   Block *block = program->create_and_insert_block();
 
96
   Block* block = program->create_and_insert_block();
94
97
   block->kind = block_kind_top_level;
95
98
 
96
99
   bld = Builder(program.get(), &program->blocks[0]);
98
101
   config.float_mode = program->blocks[0].fp_mode.val;
99
102
}
100
103
 
101
 
bool setup_cs(const char *input_spec, enum amd_gfx_level gfx_level,
102
 
              enum radeon_family family, const char* subvariant,
103
 
              unsigned wave_size)
 
104
bool
 
105
setup_cs(const char* input_spec, enum amd_gfx_level gfx_level, enum radeon_family family,
 
106
         const char* subvariant, unsigned wave_size)
104
107
{
105
108
   if (!set_variant(gfx_level, subvariant))
106
109
      return false;
117
120
         input_classes.push_back(RegClass::get(type, size * (in_bytes ? 1 : 4)));
118
121
 
119
122
         input_spec += 2 + in_bytes;
120
 
         while (input_spec[0] == ' ') input_spec++;
 
123
         while (input_spec[0] == ' ')
 
124
            input_spec++;
121
125
      }
122
126
 
123
127
      aco_ptr<Instruction> startpgm{create_instruction<Pseudo_instruction>(
132
136
   return true;
133
137
}
134
138
 
135
 
void finish_program(Program *prog)
 
139
void
 
140
finish_program(Program* prog)
136
141
{
137
142
   for (Block& BB : prog->blocks) {
138
143
      for (unsigned idx : BB.linear_preds)
149
154
   }
150
155
}
151
156
 
152
 
void finish_validator_test()
 
157
void
 
158
finish_validator_test()
153
159
{
154
160
   finish_program(program.get());
155
161
   aco_print_program(program.get(), output);
160
166
      fprintf(output, "Validation failed\n");
161
167
}
162
168
 
163
 
void finish_opt_test()
 
169
void
 
170
finish_opt_test()
164
171
{
165
172
   finish_program(program.get());
166
173
   if (!aco::validate_ir(program.get())) {
175
182
   aco_print_program(program.get(), output);
176
183
}
177
184
 
178
 
void finish_setup_reduce_temp_test()
 
185
void
 
186
finish_setup_reduce_temp_test()
179
187
{
180
188
   finish_program(program.get());
181
189
   if (!aco::validate_ir(program.get())) {
190
198
   aco_print_program(program.get(), output);
191
199
}
192
200
 
193
 
void finish_ra_test(ra_test_policy policy, bool lower)
 
201
void
 
202
finish_ra_test(ra_test_policy policy, bool lower)
194
203
{
195
204
   finish_program(program.get());
196
205
   if (!aco::validate_ir(program.get())) {
215
224
   aco_print_program(program.get(), output);
216
225
}
217
226
 
218
 
void finish_optimizer_postRA_test()
 
227
void
 
228
finish_optimizer_postRA_test()
219
229
{
220
230
   finish_program(program.get());
221
231
   aco::optimize_postRA(program.get());
222
232
   aco_print_program(program.get(), output);
223
233
}
224
234
 
225
 
void finish_to_hw_instr_test()
 
235
void
 
236
finish_to_hw_instr_test()
226
237
{
227
238
   finish_program(program.get());
228
239
   aco::lower_to_hw_instr(program.get());
229
240
   aco_print_program(program.get(), output);
230
241
}
231
242
 
232
 
void finish_waitcnt_test()
 
243
void
 
244
finish_waitcnt_test()
233
245
{
234
246
   finish_program(program.get());
235
247
   aco::insert_wait_states(program.get());
236
248
   aco_print_program(program.get(), output);
237
249
}
238
250
 
239
 
void finish_insert_nops_test()
 
251
void
 
252
finish_insert_nops_test()
240
253
{
241
254
   finish_program(program.get());
242
255
   aco::insert_NOPs(program.get());
243
256
   aco_print_program(program.get(), output);
244
257
}
245
258
 
246
 
void finish_form_hard_clause_test()
 
259
void
 
260
finish_form_hard_clause_test()
247
261
{
248
262
   finish_program(program.get());
249
263
   aco::form_hard_clauses(program.get());
250
264
   aco_print_program(program.get(), output);
251
265
}
252
266
 
253
 
void finish_assembler_test()
 
267
void
 
268
finish_assembler_test()
254
269
{
255
270
   finish_program(program.get());
256
271
   std::vector<uint32_t> binary;
257
 
   unsigned exec_size = emit_program(program.get(), binary);
 
272
   unsigned exec_size = emit_program(program.get(), binary, NULL);
258
273
 
259
274
   /* we could use CLRX for disassembly but that would require it to be
260
275
    * installed */
261
276
   if (program->gfx_level >= GFX8) {
262
277
      print_asm(program.get(), binary, exec_size / 4u, output);
263
278
   } else {
264
 
      //TODO: maybe we should use CLRX and skip this test if it's not available?
 
279
      // TODO: maybe we should use CLRX and skip this test if it's not available?
265
280
      for (uint32_t dword : binary)
266
281
         fprintf(output, "%.8x\n", dword);
267
282
   }
268
283
}
269
284
 
270
 
void writeout(unsigned i, Temp tmp)
 
285
void
 
286
writeout(unsigned i, Temp tmp)
271
287
{
272
288
   if (tmp.id())
273
289
      bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), tmp);
275
291
      bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i));
276
292
}
277
293
 
278
 
void writeout(unsigned i, aco::Builder::Result res)
 
294
void
 
295
writeout(unsigned i, aco::Builder::Result res)
279
296
{
280
297
   bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), res);
281
298
}
282
299
 
283
 
void writeout(unsigned i, Operand op)
 
300
void
 
301
writeout(unsigned i, Operand op)
284
302
{
285
303
   bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), op);
286
304
}
287
305
 
288
 
void writeout(unsigned i, Operand op0, Operand op1)
 
306
void
 
307
writeout(unsigned i, Operand op0, Operand op1)
289
308
{
290
309
   bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), op0, op1);
291
310
}
292
311
 
293
 
Temp fneg(Temp src, Builder b)
 
312
Temp
 
313
fneg(Temp src, Builder b)
294
314
{
295
315
   if (src.bytes() == 2)
296
316
      return b.vop2(aco_opcode::v_mul_f16, b.def(v2b), Operand::c16(0xbc00u), src);
298
318
      return b.vop2(aco_opcode::v_mul_f32, b.def(v1), Operand::c32(0xbf800000u), src);
299
319
}
300
320
 
301
 
Temp fabs(Temp src, Builder b)
 
321
Temp
 
322
fabs(Temp src, Builder b)
302
323
{
303
324
   if (src.bytes() == 2) {
304
 
      Builder::Result res = b.vop2_e64(aco_opcode::v_mul_f16, b.def(v2b), Operand::c16(0x3c00), src);
 
325
      Builder::Result res =
 
326
         b.vop2_e64(aco_opcode::v_mul_f16, b.def(v2b), Operand::c16(0x3c00), src);
305
327
      res->valu().abs[1] = true;
306
328
      return res;
307
329
   } else {
308
 
      Builder::Result res = b.vop2_e64(aco_opcode::v_mul_f32, b.def(v1), Operand::c32(0x3f800000u), src);
 
330
      Builder::Result res =
 
331
         b.vop2_e64(aco_opcode::v_mul_f32, b.def(v1), Operand::c32(0x3f800000u), src);
309
332
      res->valu().abs[1] = true;
310
333
      return res;
311
334
   }
312
335
}
313
336
 
314
 
Temp f2f32(Temp src, Builder b)
 
337
Temp
 
338
f2f32(Temp src, Builder b)
315
339
{
316
340
   return b.vop1(aco_opcode::v_cvt_f32_f16, b.def(v1), src);
317
341
}
318
342
 
319
 
Temp f2f16(Temp src, Builder b)
 
343
Temp
 
344
f2f16(Temp src, Builder b)
320
345
{
321
346
   return b.vop1(aco_opcode::v_cvt_f16_f32, b.def(v2b), src);
322
347
}
323
348
 
324
 
Temp u2u16(Temp src, Builder b)
 
349
Temp
 
350
u2u16(Temp src, Builder b)
325
351
{
326
352
   return b.pseudo(aco_opcode::p_extract_vector, b.def(v2b), src, Operand::zero());
327
353
}
328
354
 
329
 
Temp fadd(Temp src0, Temp src1, Builder b)
 
355
Temp
 
356
fadd(Temp src0, Temp src1, Builder b)
330
357
{
331
358
   if (src0.bytes() == 2)
332
359
      return b.vop2(aco_opcode::v_add_f16, b.def(v2b), src0, src1);
334
361
      return b.vop2(aco_opcode::v_add_f32, b.def(v1), src0, src1);
335
362
}
336
363
 
337
 
Temp fmul(Temp src0, Temp src1, Builder b)
 
364
Temp
 
365
fmul(Temp src0, Temp src1, Builder b)
338
366
{
339
367
   if (src0.bytes() == 2)
340
368
      return b.vop2(aco_opcode::v_mul_f16, b.def(v2b), src0, src1);
342
370
      return b.vop2(aco_opcode::v_mul_f32, b.def(v1), src0, src1);
343
371
}
344
372
 
345
 
Temp fma(Temp src0, Temp src1, Temp src2, Builder b)
 
373
Temp
 
374
fma(Temp src0, Temp src1, Temp src2, Builder b)
346
375
{
347
376
   if (src0.bytes() == 2)
348
377
      return b.vop3(aco_opcode::v_fma_f16, b.def(v2b), src0, src1, src2);
350
379
      return b.vop3(aco_opcode::v_fma_f32, b.def(v1), src0, src1, src2);
351
380
}
352
381
 
353
 
Temp fsat(Temp src, Builder b)
 
382
Temp
 
383
fsat(Temp src, Builder b)
354
384
{
355
385
   if (src.bytes() == 2)
356
 
      return b.vop3(aco_opcode::v_med3_f16, b.def(v2b), Operand::c16(0u),
357
 
                    Operand::c16(0x3c00u), src);
 
386
      return b.vop3(aco_opcode::v_med3_f16, b.def(v2b), Operand::c16(0u), Operand::c16(0x3c00u),
 
387
                    src);
358
388
   else
359
 
      return b.vop3(aco_opcode::v_med3_f32, b.def(v1), Operand::zero(),
360
 
                    Operand::c32(0x3f800000u), src);
 
389
      return b.vop3(aco_opcode::v_med3_f32, b.def(v1), Operand::zero(), Operand::c32(0x3f800000u),
 
390
                    src);
361
391
}
362
392
 
363
 
Temp fmin(Temp src0, Temp src1, Builder b)
 
393
Temp
 
394
fmin(Temp src0, Temp src1, Builder b)
364
395
{
365
396
   return b.vop2(aco_opcode::v_min_f32, b.def(v1), src0, src1);
366
397
}
367
398
 
368
 
Temp fmax(Temp src0, Temp src1, Builder b)
 
399
Temp
 
400
fmax(Temp src0, Temp src1, Builder b)
369
401
{
370
402
   return b.vop2(aco_opcode::v_max_f32, b.def(v1), src0, src1);
371
403
}
372
404
 
373
 
Temp ext_ushort(Temp src, unsigned idx, Builder b)
 
405
Temp
 
406
ext_ushort(Temp src, unsigned idx, Builder b)
374
407
{
375
408
   return b.pseudo(aco_opcode::p_extract, b.def(src.regClass()), src, Operand::c32(idx),
376
409
                   Operand::c32(16u), Operand::c32(false));
377
410
}
378
411
 
379
 
Temp ext_ubyte(Temp src, unsigned idx, Builder b)
 
412
Temp
 
413
ext_ubyte(Temp src, unsigned idx, Builder b)
380
414
{
381
415
   return b.pseudo(aco_opcode::p_extract, b.def(src.regClass()), src, Operand::c32(idx),
382
416
                   Operand::c32(8u), Operand::c32(false));
383
417
}
384
418
 
385
 
void emit_divergent_if_else(Program* prog, aco::Builder& b, Operand cond, std::function<void()> then,
386
 
                            std::function<void()> els)
 
419
void
 
420
emit_divergent_if_else(Program* prog, aco::Builder& b, Operand cond, std::function<void()> then,
 
421
                       std::function<void()> els)
387
422
{
388
423
   prog->blocks.reserve(prog->blocks.size() + 6);
389
424
 
418
453
   PhysReg saved_exec_reg(84);
419
454
 
420
455
   b.reset(if_block);
421
 
   Temp saved_exec = b.sop1(Builder::s_and_saveexec, b.def(b.lm, saved_exec_reg), Definition(scc, s1), Definition(exec, b.lm), cond, Operand(exec, b.lm));
422
 
   b.branch(aco_opcode::p_cbranch_nz, Definition(vcc, bld.lm), then_logical->index, then_linear->index);
 
456
   Temp saved_exec = b.sop1(Builder::s_and_saveexec, b.def(b.lm, saved_exec_reg),
 
457
                            Definition(scc, s1), Definition(exec, b.lm), cond, Operand(exec, b.lm));
 
458
   b.branch(aco_opcode::p_cbranch_nz, Definition(vcc, bld.lm), then_logical->index,
 
459
            then_linear->index);
423
460
 
424
461
   b.reset(then_logical);
425
462
   b.pseudo(aco_opcode::p_logical_start);
431
468
   b.branch(aco_opcode::p_branch, Definition(vcc, bld.lm), invert->index);
432
469
 
433
470
   b.reset(invert);
434
 
   b.sop2(Builder::s_andn2, Definition(exec, bld.lm), Definition(scc, s1), Operand(saved_exec, saved_exec_reg), Operand(exec, bld.lm));
435
 
   b.branch(aco_opcode::p_cbranch_nz, Definition(vcc, bld.lm), else_logical->index, else_linear->index);
 
471
   b.sop2(Builder::s_andn2, Definition(exec, bld.lm), Definition(scc, s1),
 
472
          Operand(saved_exec, saved_exec_reg), Operand(exec, bld.lm));
 
473
   b.branch(aco_opcode::p_cbranch_nz, Definition(vcc, bld.lm), else_logical->index,
 
474
            else_linear->index);
436
475
 
437
476
   b.reset(else_logical);
438
477
   b.pseudo(aco_opcode::p_logical_start);
444
483
   b.branch(aco_opcode::p_branch, Definition(vcc, bld.lm), endif_block->index);
445
484
 
446
485
   b.reset(endif_block);
447
 
   b.pseudo(aco_opcode::p_parallelcopy, Definition(exec, bld.lm), Operand(saved_exec, saved_exec_reg));
 
486
   b.pseudo(aco_opcode::p_parallelcopy, Definition(exec, bld.lm),
 
487
            Operand(saved_exec, saved_exec_reg));
448
488
}
449
489
 
450
 
VkDevice get_vk_device(enum amd_gfx_level gfx_level)
 
490
VkDevice
 
491
get_vk_device(enum amd_gfx_level gfx_level)
451
492
{
452
493
   enum radeon_family family;
453
494
   switch (gfx_level) {
454
 
   case GFX6:
455
 
      family = CHIP_TAHITI;
456
 
      break;
457
 
   case GFX7:
458
 
      family = CHIP_BONAIRE;
459
 
      break;
460
 
   case GFX8:
461
 
      family = CHIP_POLARIS10;
462
 
      break;
463
 
   case GFX9:
464
 
      family = CHIP_VEGA10;
465
 
      break;
466
 
   case GFX10:
467
 
      family = CHIP_NAVI10;
468
 
      break;
469
 
   case GFX10_3:
470
 
      family = CHIP_NAVI21;
471
 
      break;
472
 
   case GFX11:
473
 
      family = CHIP_GFX1100;
474
 
      break;
475
 
   default:
476
 
      family = CHIP_UNKNOWN;
477
 
      break;
 
495
   case GFX6: family = CHIP_TAHITI; break;
 
496
   case GFX7: family = CHIP_BONAIRE; break;
 
497
   case GFX8: family = CHIP_POLARIS10; break;
 
498
   case GFX9: family = CHIP_VEGA10; break;
 
499
   case GFX10: family = CHIP_NAVI10; break;
 
500
   case GFX10_3: family = CHIP_NAVI21; break;
 
501
   case GFX11: family = CHIP_GFX1100; break;
 
502
   default: family = CHIP_UNKNOWN; break;
478
503
   }
479
504
   return get_vk_device(family);
480
505
}
481
506
 
482
 
VkDevice get_vk_device(enum radeon_family family)
 
507
VkDevice
 
508
get_vk_device(enum radeon_family family)
483
509
{
484
510
   assert(family != CHIP_UNKNOWN);
485
511
 
496
522
   VkInstanceCreateInfo instance_create_info = {};
497
523
   instance_create_info.pApplicationInfo = &app_info;
498
524
   instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
499
 
   ASSERTED VkResult result = ((PFN_vkCreateInstance)vk_icdGetInstanceProcAddr(NULL, "vkCreateInstance"))(&instance_create_info, NULL, &instance_cache[family]);
 
525
   ASSERTED VkResult result = ((PFN_vkCreateInstance)vk_icdGetInstanceProcAddr(
 
526
      NULL, "vkCreateInstance"))(&instance_create_info, NULL, &instance_cache[family]);
500
527
   assert(result == VK_SUCCESS);
501
528
 
502
 
   #define ITEM(n) n = (PFN_vk##n)vk_icdGetInstanceProcAddr(instance_cache[family], "vk" #n);
 
529
#define ITEM(n) n = (PFN_vk##n)vk_icdGetInstanceProcAddr(instance_cache[family], "vk" #n);
503
530
   FUNCTION_LIST
504
 
   #undef ITEM
 
531
#undef ITEM
505
532
 
506
533
   uint32_t device_count = 1;
507
534
   VkPhysicalDevice device = VK_NULL_HANDLE;
511
538
 
512
539
   VkDeviceCreateInfo device_create_info = {};
513
540
   device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
514
 
   static const char *extensions[] = {"VK_KHR_pipeline_executable_properties"};
 
541
   static const char* extensions[] = {"VK_KHR_pipeline_executable_properties"};
515
542
   device_create_info.enabledExtensionCount = sizeof(extensions) / sizeof(extensions[0]);
516
543
   device_create_info.ppEnabledExtensionNames = extensions;
517
544
   result = CreateDevice(device, &device_create_info, NULL, &device_cache[family]);
520
547
}
521
548
 
522
549
static struct DestroyDevices {
523
 
   ~DestroyDevices() {
 
550
   ~DestroyDevices()
 
551
   {
524
552
      for (unsigned i = 0; i < CHIP_LAST; i++) {
525
553
         if (!device_cache[i])
526
554
            continue;
530
558
   }
531
559
} destroy_devices;
532
560
 
533
 
void print_pipeline_ir(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits stages,
534
 
                       const char *name, bool remove_encoding)
 
561
void
 
562
print_pipeline_ir(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits stages,
 
563
                  const char* name, bool remove_encoding)
535
564
{
536
565
   uint32_t executable_count = 16;
537
566
   VkPipelineExecutablePropertiesKHR executables[16];
539
568
   pipeline_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
540
569
   pipeline_info.pNext = NULL;
541
570
   pipeline_info.pipeline = pipeline;
542
 
   ASSERTED VkResult result = GetPipelineExecutablePropertiesKHR(device, &pipeline_info, &executable_count, executables);
 
571
   ASSERTED VkResult result =
 
572
      GetPipelineExecutablePropertiesKHR(device, &pipeline_info, &executable_count, executables);
543
573
   assert(result == VK_SUCCESS);
544
574
 
545
575
   uint32_t executable = 0;
570
600
   }
571
601
   assert(requested_ir && "Could not find requested IR");
572
602
 
573
 
   char *data = (char*)malloc(requested_ir->dataSize);
 
603
   char* data = (char*)malloc(requested_ir->dataSize);
574
604
   requested_ir->pData = data;
575
605
   result = GetPipelineExecutableInternalRepresentationsKHR(device, &exec_info, &ir_count, ir);
576
606
   assert(result == VK_SUCCESS);
577
607
 
578
608
   if (remove_encoding) {
579
 
      for (char *c = data; *c; c++) {
 
609
      for (char* c = data; *c; c++) {
580
610
         if (*c == ';') {
581
611
            for (; *c && *c != '\n'; c++)
582
612
               *c = ' ';
588
618
   free(data);
589
619
}
590
620
 
591
 
VkShaderModule __qoCreateShaderModule(VkDevice dev, const QoShaderModuleCreateInfo *module_info)
 
621
VkShaderModule
 
622
__qoCreateShaderModule(VkDevice dev, const QoShaderModuleCreateInfo* module_info)
592
623
{
593
 
    VkShaderModuleCreateInfo vk_module_info;
594
 
    vk_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
595
 
    vk_module_info.pNext = NULL;
596
 
    vk_module_info.flags = 0;
597
 
    vk_module_info.codeSize = module_info->spirvSize;
598
 
    vk_module_info.pCode = (const uint32_t*)module_info->pSpirv;
599
 
 
600
 
    VkShaderModule module;
601
 
    ASSERTED VkResult result = CreateShaderModule(dev, &vk_module_info, NULL, &module);
602
 
    assert(result == VK_SUCCESS);
603
 
 
604
 
    return module;
 
624
   VkShaderModuleCreateInfo vk_module_info;
 
625
   vk_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
 
626
   vk_module_info.pNext = NULL;
 
627
   vk_module_info.flags = 0;
 
628
   vk_module_info.codeSize = module_info->spirvSize;
 
629
   vk_module_info.pCode = (const uint32_t*)module_info->pSpirv;
 
630
 
 
631
   VkShaderModule module;
 
632
   ASSERTED VkResult result = CreateShaderModule(dev, &vk_module_info, NULL, &module);
 
633
   assert(result == VK_SUCCESS);
 
634
 
 
635
   return module;
605
636
}
606
637
 
607
 
PipelineBuilder::PipelineBuilder(VkDevice dev) {
 
638
PipelineBuilder::PipelineBuilder(VkDevice dev)
 
639
{
608
640
   memset(this, 0, sizeof(*this));
609
641
   topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
610
642
   device = dev;
615
647
   DestroyPipeline(device, pipeline, NULL);
616
648
 
617
649
   for (unsigned i = 0; i < (is_compute() ? 1 : gfx_pipeline_info.stageCount); i++) {
618
 
      VkPipelineShaderStageCreateInfo *stage_info = &stages[i];
 
650
      VkPipelineShaderStageCreateInfo* stage_info = &stages[i];
619
651
      if (owned_stages & stage_info->stage)
620
652
         DestroyShaderModule(device, stage_info->module, NULL);
621
653
   }
628
660
   DestroyRenderPass(device, render_pass, NULL);
629
661
}
630
662
 
631
 
void PipelineBuilder::add_desc_binding(VkShaderStageFlags stage_flags, uint32_t layout,
632
 
                                       uint32_t binding, VkDescriptorType type, uint32_t count)
 
663
void
 
664
PipelineBuilder::add_desc_binding(VkShaderStageFlags stage_flags, uint32_t layout, uint32_t binding,
 
665
                                  VkDescriptorType type, uint32_t count)
633
666
{
634
667
   desc_layouts_used |= 1ull << layout;
635
668
   desc_bindings[layout][num_desc_bindings[layout]++] = {binding, type, count, stage_flags, NULL};
636
669
}
637
670
 
638
 
void PipelineBuilder::add_vertex_binding(uint32_t binding, uint32_t stride, VkVertexInputRate rate)
 
671
void
 
672
PipelineBuilder::add_vertex_binding(uint32_t binding, uint32_t stride, VkVertexInputRate rate)
639
673
{
640
674
   vs_bindings[vs_input.vertexBindingDescriptionCount++] = {binding, stride, rate};
641
675
}
642
676
 
643
 
void PipelineBuilder::add_vertex_attribute(uint32_t location, uint32_t binding, VkFormat format, uint32_t offset)
 
677
void
 
678
PipelineBuilder::add_vertex_attribute(uint32_t location, uint32_t binding, VkFormat format,
 
679
                                      uint32_t offset)
644
680
{
645
681
   vs_attributes[vs_input.vertexAttributeDescriptionCount++] = {location, binding, format, offset};
646
682
}
647
683
 
648
 
void PipelineBuilder::add_resource_decls(QoShaderModuleCreateInfo *module)
 
684
void
 
685
PipelineBuilder::add_resource_decls(QoShaderModuleCreateInfo* module)
649
686
{
650
687
   for (unsigned i = 0; i < module->declarationCount; i++) {
651
 
      const QoShaderDecl *decl = &module->pDeclarations[i];
 
688
      const QoShaderDecl* decl = &module->pDeclarations[i];
652
689
      switch (decl->decl_type) {
653
690
      case QoShaderDeclType_ubo:
654
 
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
 
691
         add_desc_binding(module->stage, decl->set, decl->binding,
 
692
                          VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
655
693
         break;
656
694
      case QoShaderDeclType_ssbo:
657
 
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
 
695
         add_desc_binding(module->stage, decl->set, decl->binding,
 
696
                          VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
658
697
         break;
659
698
      case QoShaderDeclType_img_buf:
660
 
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
 
699
         add_desc_binding(module->stage, decl->set, decl->binding,
 
700
                          VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
661
701
         break;
662
702
      case QoShaderDeclType_img:
663
 
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
 
703
         add_desc_binding(module->stage, decl->set, decl->binding,
 
704
                          VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
664
705
         break;
665
706
      case QoShaderDeclType_tex_buf:
666
 
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
 
707
         add_desc_binding(module->stage, decl->set, decl->binding,
 
708
                          VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
667
709
         break;
668
710
      case QoShaderDeclType_combined:
669
 
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
 
711
         add_desc_binding(module->stage, decl->set, decl->binding,
 
712
                          VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
670
713
         break;
671
714
      case QoShaderDeclType_tex:
672
 
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
 
715
         add_desc_binding(module->stage, decl->set, decl->binding,
 
716
                          VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
673
717
         break;
674
718
      case QoShaderDeclType_samp:
675
719
         add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_SAMPLER);
676
720
         break;
677
 
      default:
678
 
         break;
 
721
      default: break;
679
722
      }
680
723
   }
681
724
}
682
725
 
683
 
void PipelineBuilder::add_io_decls(QoShaderModuleCreateInfo *module)
 
726
void
 
727
PipelineBuilder::add_io_decls(QoShaderModuleCreateInfo* module)
684
728
{
685
729
   unsigned next_vtx_offset = 0;
686
730
   for (unsigned i = 0; i < module->declarationCount; i++) {
687
 
      const QoShaderDecl *decl = &module->pDeclarations[i];
 
731
      const QoShaderDecl* decl = &module->pDeclarations[i];
688
732
      switch (decl->decl_type) {
689
733
      case QoShaderDeclType_in:
690
734
         if (module->stage == VK_SHADER_STAGE_VERTEX_BIT) {
691
735
            if (!strcmp(decl->type, "float") || decl->type[0] == 'v')
692
 
               add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_SFLOAT, next_vtx_offset);
 
736
               add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_SFLOAT,
 
737
                                    next_vtx_offset);
693
738
            else if (decl->type[0] == 'u')
694
 
               add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_UINT, next_vtx_offset);
 
739
               add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_UINT,
 
740
                                    next_vtx_offset);
695
741
            else if (decl->type[0] == 'i')
696
 
               add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_SINT, next_vtx_offset);
 
742
               add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_SINT,
 
743
                                    next_vtx_offset);
697
744
            next_vtx_offset += 16;
698
745
         }
699
746
         break;
707
754
               color_outputs[decl->location] = VK_FORMAT_R32G32B32A32_SINT;
708
755
         }
709
756
         break;
710
 
      default:
711
 
         break;
 
757
      default: break;
712
758
      }
713
759
   }
714
760
   if (next_vtx_offset)
715
761
      add_vertex_binding(0, next_vtx_offset);
716
762
}
717
763
 
718
 
void PipelineBuilder::add_stage(VkShaderStageFlagBits stage, VkShaderModule module, const char *name)
 
764
void
 
765
PipelineBuilder::add_stage(VkShaderStageFlagBits stage, VkShaderModule module, const char* name)
719
766
{
720
 
   VkPipelineShaderStageCreateInfo *stage_info;
 
767
   VkPipelineShaderStageCreateInfo* stage_info;
721
768
   if (stage == VK_SHADER_STAGE_COMPUTE_BIT)
722
769
      stage_info = &stages[0];
723
770
   else
732
779
   owned_stages |= stage;
733
780
}
734
781
 
735
 
void PipelineBuilder::add_stage(VkShaderStageFlagBits stage, QoShaderModuleCreateInfo module, const char *name)
 
782
void
 
783
PipelineBuilder::add_stage(VkShaderStageFlagBits stage, QoShaderModuleCreateInfo module,
 
784
                           const char* name)
736
785
{
737
786
   add_stage(stage, __qoCreateShaderModule(device, &module), name);
738
787
   add_resource_decls(&module);
739
788
   add_io_decls(&module);
740
789
}
741
790
 
742
 
void PipelineBuilder::add_vsfs(VkShaderModule vs, VkShaderModule fs)
743
 
{
744
 
   add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs);
745
 
   add_stage(VK_SHADER_STAGE_FRAGMENT_BIT, fs);
746
 
}
747
 
 
748
 
void PipelineBuilder::add_vsfs(QoShaderModuleCreateInfo vs, QoShaderModuleCreateInfo fs)
749
 
{
750
 
   add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs);
751
 
   add_stage(VK_SHADER_STAGE_FRAGMENT_BIT, fs);
752
 
}
753
 
 
754
 
void PipelineBuilder::add_cs(VkShaderModule cs)
755
 
{
756
 
   add_stage(VK_SHADER_STAGE_COMPUTE_BIT, cs);
757
 
}
758
 
 
759
 
void PipelineBuilder::add_cs(QoShaderModuleCreateInfo cs)
760
 
{
761
 
   add_stage(VK_SHADER_STAGE_COMPUTE_BIT, cs);
762
 
}
763
 
 
764
 
bool PipelineBuilder::is_compute() {
 
791
void
 
792
PipelineBuilder::add_vsfs(VkShaderModule vs, VkShaderModule fs)
 
793
{
 
794
   add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs);
 
795
   add_stage(VK_SHADER_STAGE_FRAGMENT_BIT, fs);
 
796
}
 
797
 
 
798
void
 
799
PipelineBuilder::add_vsfs(QoShaderModuleCreateInfo vs, QoShaderModuleCreateInfo fs)
 
800
{
 
801
   add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs);
 
802
   add_stage(VK_SHADER_STAGE_FRAGMENT_BIT, fs);
 
803
}
 
804
 
 
805
void
 
806
PipelineBuilder::add_cs(VkShaderModule cs)
 
807
{
 
808
   add_stage(VK_SHADER_STAGE_COMPUTE_BIT, cs);
 
809
}
 
810
 
 
811
void
 
812
PipelineBuilder::add_cs(QoShaderModuleCreateInfo cs)
 
813
{
 
814
   add_stage(VK_SHADER_STAGE_COMPUTE_BIT, cs);
 
815
}
 
816
 
 
817
bool
 
818
PipelineBuilder::is_compute()
 
819
{
765
820
   return gfx_pipeline_info.stageCount == 0;
766
821
}
767
822
 
768
 
void PipelineBuilder::create_compute_pipeline() {
 
823
void
 
824
PipelineBuilder::create_compute_pipeline()
 
825
{
769
826
   VkComputePipelineCreateInfo create_info;
770
827
   create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
771
828
   create_info.pNext = NULL;
775
832
   create_info.basePipelineHandle = VK_NULL_HANDLE;
776
833
   create_info.basePipelineIndex = 0;
777
834
 
778
 
   ASSERTED VkResult result = CreateComputePipelines(device, VK_NULL_HANDLE, 1, &create_info, NULL, &pipeline);
 
835
   ASSERTED VkResult result =
 
836
      CreateComputePipelines(device, VK_NULL_HANDLE, 1, &create_info, NULL, &pipeline);
779
837
   assert(result == VK_SUCCESS);
780
838
}
781
839
 
782
 
void PipelineBuilder::create_graphics_pipeline() {
 
840
void
 
841
PipelineBuilder::create_graphics_pipeline()
 
842
{
783
843
   /* create the create infos */
784
844
   if (!samples)
785
845
      samples = VK_SAMPLE_COUNT_1_BIT;
792
852
      if (color_outputs[i] == VK_FORMAT_UNDEFINED)
793
853
         continue;
794
854
 
795
 
      VkAttachmentDescription *desc = &attachment_descs[num_color_attachments];
 
855
      VkAttachmentDescription* desc = &attachment_descs[num_color_attachments];
796
856
      desc->flags = 0;
797
857
      desc->format = color_outputs[i];
798
858
      desc->samples = samples;
803
863
      desc->initialLayout = VK_IMAGE_LAYOUT_GENERAL;
804
864
      desc->finalLayout = VK_IMAGE_LAYOUT_GENERAL;
805
865
 
806
 
      VkAttachmentReference *ref = &color_attachments[num_color_attachments];
 
866
      VkAttachmentReference* ref = &color_attachments[num_color_attachments];
807
867
      ref->attachment = num_color_attachments;
808
868
      ref->layout = VK_IMAGE_LAYOUT_GENERAL;
809
869
 
810
 
      VkPipelineColorBlendAttachmentState *blend = &blend_attachment_states[num_color_attachments];
 
870
      VkPipelineColorBlendAttachmentState* blend = &blend_attachment_states[num_color_attachments];
811
871
      blend->blendEnable = false;
812
 
      blend->colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
813
 
                              VK_COLOR_COMPONENT_G_BIT |
814
 
                              VK_COLOR_COMPONENT_B_BIT |
815
 
                              VK_COLOR_COMPONENT_A_BIT;
 
872
      blend->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
 
873
                              VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
816
874
 
817
875
      num_color_attachments++;
818
876
   }
820
878
   unsigned num_attachments = num_color_attachments;
821
879
   VkAttachmentReference ds_attachment;
822
880
   if (ds_output != VK_FORMAT_UNDEFINED) {
823
 
      VkAttachmentDescription *desc = &attachment_descs[num_attachments];
 
881
      VkAttachmentDescription* desc = &attachment_descs[num_attachments];
824
882
      desc->flags = 0;
825
883
      desc->format = ds_output;
826
884
      desc->samples = samples;
902
960
   ds_state.front.passOp = VK_STENCIL_OP_REPLACE;
903
961
   ds_state.front.depthFailOp = VK_STENCIL_OP_REPLACE;
904
962
   ds_state.front.compareOp = VK_COMPARE_OP_ALWAYS;
905
 
   ds_state.front.compareMask = 0xffffffff,
906
 
   ds_state.front.writeMask = 0;
 
963
   ds_state.front.compareMask = 0xffffffff, ds_state.front.writeMask = 0;
907
964
   ds_state.front.reference = 0;
908
965
   ds_state.back = ds_state.front;
909
966
 
915
972
   color_blend_state.attachmentCount = num_color_attachments;
916
973
   color_blend_state.pAttachments = blend_attachment_states;
917
974
 
918
 
   VkDynamicState dynamic_states[9] = {
919
 
      VK_DYNAMIC_STATE_VIEWPORT,
920
 
      VK_DYNAMIC_STATE_SCISSOR,
921
 
      VK_DYNAMIC_STATE_LINE_WIDTH,
922
 
      VK_DYNAMIC_STATE_DEPTH_BIAS,
923
 
      VK_DYNAMIC_STATE_BLEND_CONSTANTS,
924
 
      VK_DYNAMIC_STATE_DEPTH_BOUNDS,
925
 
      VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
926
 
      VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
927
 
      VK_DYNAMIC_STATE_STENCIL_REFERENCE
928
 
   };
 
975
   VkDynamicState dynamic_states[9] = {VK_DYNAMIC_STATE_VIEWPORT,
 
976
                                       VK_DYNAMIC_STATE_SCISSOR,
 
977
                                       VK_DYNAMIC_STATE_LINE_WIDTH,
 
978
                                       VK_DYNAMIC_STATE_DEPTH_BIAS,
 
979
                                       VK_DYNAMIC_STATE_BLEND_CONSTANTS,
 
980
                                       VK_DYNAMIC_STATE_DEPTH_BOUNDS,
 
981
                                       VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
 
982
                                       VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
 
983
                                       VK_DYNAMIC_STATE_STENCIL_REFERENCE};
929
984
 
930
985
   VkPipelineDynamicStateCreateInfo dynamic_state;
931
986
   dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
985
1040
   assert(result == VK_SUCCESS);
986
1041
}
987
1042
 
988
 
void PipelineBuilder::create_pipeline() {
 
1043
void
 
1044
PipelineBuilder::create_pipeline()
 
1045
{
989
1046
   unsigned num_desc_layouts = 0;
990
1047
   for (unsigned i = 0; i < 64; i++) {
991
1048
      if (!(desc_layouts_used & (1ull << i)))
998
1055
      desc_layout_info.bindingCount = num_desc_bindings[i];
999
1056
      desc_layout_info.pBindings = desc_bindings[i];
1000
1057
 
1001
 
      ASSERTED VkResult result = CreateDescriptorSetLayout(device, &desc_layout_info, NULL, &desc_layouts[num_desc_layouts]);
 
1058
      ASSERTED VkResult result = CreateDescriptorSetLayout(device, &desc_layout_info, NULL,
 
1059
                                                           &desc_layouts[num_desc_layouts]);
1002
1060
      assert(result == VK_SUCCESS);
1003
1061
      num_desc_layouts++;
1004
1062
   }
1012
1070
   pipeline_layout_info.setLayoutCount = num_desc_layouts;
1013
1071
   pipeline_layout_info.pSetLayouts = desc_layouts;
1014
1072
 
1015
 
   ASSERTED VkResult result = CreatePipelineLayout(device, &pipeline_layout_info, NULL, &pipeline_layout);
 
1073
   ASSERTED VkResult result =
 
1074
      CreatePipelineLayout(device, &pipeline_layout_info, NULL, &pipeline_layout);
1016
1075
   assert(result == VK_SUCCESS);
1017
1076
 
1018
1077
   if (is_compute())
1021
1080
      create_graphics_pipeline();
1022
1081
}
1023
1082
 
1024
 
void PipelineBuilder::print_ir(VkShaderStageFlagBits stage_flags, const char *name, bool remove_encoding)
 
1083
void
 
1084
PipelineBuilder::print_ir(VkShaderStageFlagBits stage_flags, const char* name, bool remove_encoding)
1025
1085
{
1026
1086
   if (!pipeline)
1027
1087
      create_pipeline();