xref: /aosp_15_r20/external/mesa3d/src/amd/compiler/tests/helpers.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2020 Valve Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker  */
6*61046927SAndroid Build Coastguard Worker #include "helpers.h"
7*61046927SAndroid Build Coastguard Worker 
8*61046927SAndroid Build Coastguard Worker #include "common/amd_family.h"
9*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include <llvm-c/Target.h>
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #include <mutex>
14*61046927SAndroid Build Coastguard Worker #include <sstream>
15*61046927SAndroid Build Coastguard Worker #include <stdio.h>
16*61046927SAndroid Build Coastguard Worker 
17*61046927SAndroid Build Coastguard Worker using namespace aco;
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker extern "C" {
20*61046927SAndroid Build Coastguard Worker PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName);
21*61046927SAndroid Build Coastguard Worker }
22*61046927SAndroid Build Coastguard Worker 
23*61046927SAndroid Build Coastguard Worker ac_shader_config config;
24*61046927SAndroid Build Coastguard Worker aco_shader_info info;
25*61046927SAndroid Build Coastguard Worker std::unique_ptr<Program> program;
26*61046927SAndroid Build Coastguard Worker Builder bld(NULL);
27*61046927SAndroid Build Coastguard Worker Temp inputs[16];
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker static radeon_info rad_info;
30*61046927SAndroid Build Coastguard Worker static nir_shader_compiler_options nir_options;
31*61046927SAndroid Build Coastguard Worker static nir_builder _nb;
32*61046927SAndroid Build Coastguard Worker nir_builder *nb;
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker static VkInstance instance_cache[CHIP_LAST] = {VK_NULL_HANDLE};
35*61046927SAndroid Build Coastguard Worker static VkDevice device_cache[CHIP_LAST] = {VK_NULL_HANDLE};
36*61046927SAndroid Build Coastguard Worker static std::mutex create_device_mutex;
37*61046927SAndroid Build Coastguard Worker 
38*61046927SAndroid Build Coastguard Worker #define FUNCTION_LIST                                                                              \
39*61046927SAndroid Build Coastguard Worker    ITEM(CreateInstance)                                                                            \
40*61046927SAndroid Build Coastguard Worker    ITEM(DestroyInstance)                                                                           \
41*61046927SAndroid Build Coastguard Worker    ITEM(EnumeratePhysicalDevices)                                                                  \
42*61046927SAndroid Build Coastguard Worker    ITEM(GetPhysicalDeviceProperties2)                                                              \
43*61046927SAndroid Build Coastguard Worker    ITEM(CreateDevice)                                                                              \
44*61046927SAndroid Build Coastguard Worker    ITEM(DestroyDevice)                                                                             \
45*61046927SAndroid Build Coastguard Worker    ITEM(CreateShaderModule)                                                                        \
46*61046927SAndroid Build Coastguard Worker    ITEM(DestroyShaderModule)                                                                       \
47*61046927SAndroid Build Coastguard Worker    ITEM(CreateGraphicsPipelines)                                                                   \
48*61046927SAndroid Build Coastguard Worker    ITEM(CreateComputePipelines)                                                                    \
49*61046927SAndroid Build Coastguard Worker    ITEM(DestroyPipeline)                                                                           \
50*61046927SAndroid Build Coastguard Worker    ITEM(CreateDescriptorSetLayout)                                                                 \
51*61046927SAndroid Build Coastguard Worker    ITEM(DestroyDescriptorSetLayout)                                                                \
52*61046927SAndroid Build Coastguard Worker    ITEM(CreatePipelineLayout)                                                                      \
53*61046927SAndroid Build Coastguard Worker    ITEM(DestroyPipelineLayout)                                                                     \
54*61046927SAndroid Build Coastguard Worker    ITEM(CreateRenderPass)                                                                          \
55*61046927SAndroid Build Coastguard Worker    ITEM(DestroyRenderPass)                                                                         \
56*61046927SAndroid Build Coastguard Worker    ITEM(GetPipelineExecutablePropertiesKHR)                                                        \
57*61046927SAndroid Build Coastguard Worker    ITEM(GetPipelineExecutableInternalRepresentationsKHR)
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker #define ITEM(n) PFN_vk##n n;
60*61046927SAndroid Build Coastguard Worker FUNCTION_LIST
61*61046927SAndroid Build Coastguard Worker #undef ITEM
62*61046927SAndroid Build Coastguard Worker 
63*61046927SAndroid Build Coastguard Worker void
create_program(enum amd_gfx_level gfx_level,Stage stage,unsigned wave_size,enum radeon_family family)64*61046927SAndroid Build Coastguard Worker create_program(enum amd_gfx_level gfx_level, Stage stage, unsigned wave_size,
65*61046927SAndroid Build Coastguard Worker                enum radeon_family family)
66*61046927SAndroid Build Coastguard Worker {
67*61046927SAndroid Build Coastguard Worker    memset(&config, 0, sizeof(config));
68*61046927SAndroid Build Coastguard Worker    info.wave_size = wave_size;
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    program.reset(new Program);
71*61046927SAndroid Build Coastguard Worker    aco::init_program(program.get(), stage, &info, gfx_level, family, false, &config);
72*61046927SAndroid Build Coastguard Worker    program->workgroup_size = UINT_MAX;
73*61046927SAndroid Build Coastguard Worker    calc_min_waves(program.get());
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    program->debug.func = nullptr;
76*61046927SAndroid Build Coastguard Worker    program->debug.private_data = nullptr;
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker    program->debug.output = output;
79*61046927SAndroid Build Coastguard Worker    program->debug.shorten_messages = true;
80*61046927SAndroid Build Coastguard Worker    program->debug.func = nullptr;
81*61046927SAndroid Build Coastguard Worker    program->debug.private_data = nullptr;
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker    Block* block = program->create_and_insert_block();
84*61046927SAndroid Build Coastguard Worker    block->kind = block_kind_top_level;
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker    bld = Builder(program.get(), &program->blocks[0]);
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker    config.float_mode = program->blocks[0].fp_mode.val;
89*61046927SAndroid Build Coastguard Worker }
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker bool
setup_cs(const char * input_spec,enum amd_gfx_level gfx_level,enum radeon_family family,const char * subvariant,unsigned wave_size)92*61046927SAndroid Build Coastguard Worker setup_cs(const char* input_spec, enum amd_gfx_level gfx_level, enum radeon_family family,
93*61046927SAndroid Build Coastguard Worker          const char* subvariant, unsigned wave_size)
94*61046927SAndroid Build Coastguard Worker {
95*61046927SAndroid Build Coastguard Worker    if (!set_variant(gfx_level, subvariant))
96*61046927SAndroid Build Coastguard Worker       return false;
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    memset(&info, 0, sizeof(info));
99*61046927SAndroid Build Coastguard Worker    create_program(gfx_level, compute_cs, wave_size, family);
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker    if (input_spec) {
102*61046927SAndroid Build Coastguard Worker       std::vector<RegClass> input_classes;
103*61046927SAndroid Build Coastguard Worker       while (input_spec[0]) {
104*61046927SAndroid Build Coastguard Worker          RegType type = input_spec[0] == 'v' ? RegType::vgpr : RegType::sgpr;
105*61046927SAndroid Build Coastguard Worker          unsigned size = input_spec[1] - '0';
106*61046927SAndroid Build Coastguard Worker          bool in_bytes = input_spec[2] == 'b';
107*61046927SAndroid Build Coastguard Worker          input_classes.push_back(RegClass::get(type, size * (in_bytes ? 1 : 4)));
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker          input_spec += 2 + in_bytes;
110*61046927SAndroid Build Coastguard Worker          while (input_spec[0] == ' ')
111*61046927SAndroid Build Coastguard Worker             input_spec++;
112*61046927SAndroid Build Coastguard Worker       }
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker       aco_ptr<Instruction> startpgm{
115*61046927SAndroid Build Coastguard Worker          create_instruction(aco_opcode::p_startpgm, Format::PSEUDO, 0, input_classes.size())};
116*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < input_classes.size(); i++) {
117*61046927SAndroid Build Coastguard Worker          inputs[i] = bld.tmp(input_classes[i]);
118*61046927SAndroid Build Coastguard Worker          startpgm->definitions[i] = Definition(inputs[i]);
119*61046927SAndroid Build Coastguard Worker       }
120*61046927SAndroid Build Coastguard Worker       bld.insert(std::move(startpgm));
121*61046927SAndroid Build Coastguard Worker    }
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker    return true;
124*61046927SAndroid Build Coastguard Worker }
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker bool
setup_nir_cs(enum amd_gfx_level gfx_level,gl_shader_stage stage,enum radeon_family family,const char * subvariant)127*61046927SAndroid Build Coastguard Worker setup_nir_cs(enum amd_gfx_level gfx_level, gl_shader_stage stage, enum radeon_family family, const char* subvariant)
128*61046927SAndroid Build Coastguard Worker {
129*61046927SAndroid Build Coastguard Worker    if (!set_variant(gfx_level, subvariant))
130*61046927SAndroid Build Coastguard Worker       return false;
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    if (family == CHIP_UNKNOWN) {
133*61046927SAndroid Build Coastguard Worker       switch (gfx_level) {
134*61046927SAndroid Build Coastguard Worker       case GFX6: family = CHIP_TAHITI; break;
135*61046927SAndroid Build Coastguard Worker       case GFX7: family = CHIP_BONAIRE; break;
136*61046927SAndroid Build Coastguard Worker       case GFX8: family = CHIP_POLARIS10; break;
137*61046927SAndroid Build Coastguard Worker       case GFX9: family = CHIP_VEGA10; break;
138*61046927SAndroid Build Coastguard Worker       case GFX10: family = CHIP_NAVI10; break;
139*61046927SAndroid Build Coastguard Worker       case GFX10_3: family = CHIP_NAVI21; break;
140*61046927SAndroid Build Coastguard Worker       case GFX11: family = CHIP_NAVI31; break;
141*61046927SAndroid Build Coastguard Worker       default: family = CHIP_UNKNOWN; break;
142*61046927SAndroid Build Coastguard Worker       }
143*61046927SAndroid Build Coastguard Worker    }
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker    memset(&rad_info, 0, sizeof(rad_info));
146*61046927SAndroid Build Coastguard Worker    rad_info.gfx_level = gfx_level;
147*61046927SAndroid Build Coastguard Worker    rad_info.family = family;
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker    memset(&nir_options, 0, sizeof(nir_options));
150*61046927SAndroid Build Coastguard Worker    ac_set_nir_options(&rad_info, false, &nir_options);
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker    glsl_type_singleton_init_or_ref();
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker    _nb = nir_builder_init_simple_shader(stage, &nir_options, "aco_test");
155*61046927SAndroid Build Coastguard Worker    nb = &_nb;
156*61046927SAndroid Build Coastguard Worker 
157*61046927SAndroid Build Coastguard Worker    return true;
158*61046927SAndroid Build Coastguard Worker }
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker void
finish_program(Program * prog,bool endpgm,bool dominance)161*61046927SAndroid Build Coastguard Worker finish_program(Program* prog, bool endpgm, bool dominance)
162*61046927SAndroid Build Coastguard Worker {
163*61046927SAndroid Build Coastguard Worker    for (Block& BB : prog->blocks) {
164*61046927SAndroid Build Coastguard Worker       for (unsigned idx : BB.linear_preds)
165*61046927SAndroid Build Coastguard Worker          prog->blocks[idx].linear_succs.emplace_back(BB.index);
166*61046927SAndroid Build Coastguard Worker       for (unsigned idx : BB.logical_preds)
167*61046927SAndroid Build Coastguard Worker          prog->blocks[idx].logical_succs.emplace_back(BB.index);
168*61046927SAndroid Build Coastguard Worker    }
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker    for (Block& block : prog->blocks) {
171*61046927SAndroid Build Coastguard Worker       if (block.linear_succs.size() == 0) {
172*61046927SAndroid Build Coastguard Worker          block.kind |= block_kind_uniform;
173*61046927SAndroid Build Coastguard Worker          if (endpgm)
174*61046927SAndroid Build Coastguard Worker             Builder(prog, &block).sopp(aco_opcode::s_endpgm);
175*61046927SAndroid Build Coastguard Worker       }
176*61046927SAndroid Build Coastguard Worker    }
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker    if (dominance)
179*61046927SAndroid Build Coastguard Worker       dominator_tree(program.get());
180*61046927SAndroid Build Coastguard Worker }
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker void
finish_validator_test()183*61046927SAndroid Build Coastguard Worker finish_validator_test()
184*61046927SAndroid Build Coastguard Worker {
185*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), true, true);
186*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
187*61046927SAndroid Build Coastguard Worker    fprintf(output, "Validation results:\n");
188*61046927SAndroid Build Coastguard Worker    if (aco::validate_ir(program.get()))
189*61046927SAndroid Build Coastguard Worker       fprintf(output, "Validation passed\n");
190*61046927SAndroid Build Coastguard Worker    else
191*61046927SAndroid Build Coastguard Worker       fprintf(output, "Validation failed\n");
192*61046927SAndroid Build Coastguard Worker }
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker void
finish_opt_test()195*61046927SAndroid Build Coastguard Worker finish_opt_test()
196*61046927SAndroid Build Coastguard Worker {
197*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), true, true);
198*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
199*61046927SAndroid Build Coastguard Worker       fail_test("Validation before optimization failed");
200*61046927SAndroid Build Coastguard Worker       return;
201*61046927SAndroid Build Coastguard Worker    }
202*61046927SAndroid Build Coastguard Worker    aco::optimize(program.get());
203*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
204*61046927SAndroid Build Coastguard Worker       fail_test("Validation after optimization failed");
205*61046927SAndroid Build Coastguard Worker       return;
206*61046927SAndroid Build Coastguard Worker    }
207*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker void
finish_setup_reduce_temp_test()211*61046927SAndroid Build Coastguard Worker finish_setup_reduce_temp_test()
212*61046927SAndroid Build Coastguard Worker {
213*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), true, true);
214*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
215*61046927SAndroid Build Coastguard Worker       fail_test("Validation before setup_reduce_temp failed");
216*61046927SAndroid Build Coastguard Worker       return;
217*61046927SAndroid Build Coastguard Worker    }
218*61046927SAndroid Build Coastguard Worker    aco::setup_reduce_temp(program.get());
219*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
220*61046927SAndroid Build Coastguard Worker       fail_test("Validation after setup_reduce_temp failed");
221*61046927SAndroid Build Coastguard Worker       return;
222*61046927SAndroid Build Coastguard Worker    }
223*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
224*61046927SAndroid Build Coastguard Worker }
225*61046927SAndroid Build Coastguard Worker 
226*61046927SAndroid Build Coastguard Worker void
finish_lower_subdword_test()227*61046927SAndroid Build Coastguard Worker finish_lower_subdword_test()
228*61046927SAndroid Build Coastguard Worker {
229*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), true, true);
230*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
231*61046927SAndroid Build Coastguard Worker       fail_test("Validation before lower_subdword failed");
232*61046927SAndroid Build Coastguard Worker       return;
233*61046927SAndroid Build Coastguard Worker    }
234*61046927SAndroid Build Coastguard Worker    aco::lower_subdword(program.get());
235*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
236*61046927SAndroid Build Coastguard Worker       fail_test("Validation after lower_subdword failed");
237*61046927SAndroid Build Coastguard Worker       return;
238*61046927SAndroid Build Coastguard Worker    }
239*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker 
242*61046927SAndroid Build Coastguard Worker void
finish_ra_test(ra_test_policy policy)243*61046927SAndroid Build Coastguard Worker finish_ra_test(ra_test_policy policy)
244*61046927SAndroid Build Coastguard Worker {
245*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), true, true);
246*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
247*61046927SAndroid Build Coastguard Worker       fail_test("Validation before register allocation failed");
248*61046927SAndroid Build Coastguard Worker       return;
249*61046927SAndroid Build Coastguard Worker    }
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker    program->workgroup_size = program->wave_size;
252*61046927SAndroid Build Coastguard Worker    aco::live_var_analysis(program.get());
253*61046927SAndroid Build Coastguard Worker    aco::register_allocation(program.get(), policy);
254*61046927SAndroid Build Coastguard Worker 
255*61046927SAndroid Build Coastguard Worker    if (aco::validate_ra(program.get())) {
256*61046927SAndroid Build Coastguard Worker       fail_test("Validation after register allocation failed");
257*61046927SAndroid Build Coastguard Worker       return;
258*61046927SAndroid Build Coastguard Worker    }
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker void
finish_optimizer_postRA_test()264*61046927SAndroid Build Coastguard Worker finish_optimizer_postRA_test()
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), true, true);
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
269*61046927SAndroid Build Coastguard Worker       fail_test("Validation before optimize_postRA failed");
270*61046927SAndroid Build Coastguard Worker       return;
271*61046927SAndroid Build Coastguard Worker    }
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker    aco::optimize_postRA(program.get());
274*61046927SAndroid Build Coastguard Worker 
275*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
276*61046927SAndroid Build Coastguard Worker       fail_test("Validation after optimize_postRA failed");
277*61046927SAndroid Build Coastguard Worker       return;
278*61046927SAndroid Build Coastguard Worker    }
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
281*61046927SAndroid Build Coastguard Worker }
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker void
finish_to_hw_instr_test()284*61046927SAndroid Build Coastguard Worker finish_to_hw_instr_test()
285*61046927SAndroid Build Coastguard Worker {
286*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), true, true);
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
289*61046927SAndroid Build Coastguard Worker       fail_test("Validation before lower_to_hw_instr failed");
290*61046927SAndroid Build Coastguard Worker       return;
291*61046927SAndroid Build Coastguard Worker    }
292*61046927SAndroid Build Coastguard Worker 
293*61046927SAndroid Build Coastguard Worker    aco::lower_to_hw_instr(program.get());
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
296*61046927SAndroid Build Coastguard Worker       fail_test("Validation after lower_to_hw_instr failed");
297*61046927SAndroid Build Coastguard Worker       return;
298*61046927SAndroid Build Coastguard Worker    }
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
301*61046927SAndroid Build Coastguard Worker }
302*61046927SAndroid Build Coastguard Worker 
303*61046927SAndroid Build Coastguard Worker void
finish_schedule_vopd_test()304*61046927SAndroid Build Coastguard Worker finish_schedule_vopd_test()
305*61046927SAndroid Build Coastguard Worker {
306*61046927SAndroid Build Coastguard Worker    finish_program(program.get());
307*61046927SAndroid Build Coastguard Worker    aco::schedule_vopd(program.get());
308*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker void
finish_waitcnt_test()312*61046927SAndroid Build Coastguard Worker finish_waitcnt_test()
313*61046927SAndroid Build Coastguard Worker {
314*61046927SAndroid Build Coastguard Worker    finish_program(program.get());
315*61046927SAndroid Build Coastguard Worker    aco::insert_waitcnt(program.get());
316*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker void
finish_insert_nops_test(bool endpgm)320*61046927SAndroid Build Coastguard Worker finish_insert_nops_test(bool endpgm)
321*61046927SAndroid Build Coastguard Worker {
322*61046927SAndroid Build Coastguard Worker    finish_program(program.get(), endpgm);
323*61046927SAndroid Build Coastguard Worker    aco::insert_NOPs(program.get());
324*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
325*61046927SAndroid Build Coastguard Worker }
326*61046927SAndroid Build Coastguard Worker 
327*61046927SAndroid Build Coastguard Worker void
finish_form_hard_clause_test()328*61046927SAndroid Build Coastguard Worker finish_form_hard_clause_test()
329*61046927SAndroid Build Coastguard Worker {
330*61046927SAndroid Build Coastguard Worker    finish_program(program.get());
331*61046927SAndroid Build Coastguard Worker    aco::form_hard_clauses(program.get());
332*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
333*61046927SAndroid Build Coastguard Worker }
334*61046927SAndroid Build Coastguard Worker 
335*61046927SAndroid Build Coastguard Worker void
finish_assembler_test()336*61046927SAndroid Build Coastguard Worker finish_assembler_test()
337*61046927SAndroid Build Coastguard Worker {
338*61046927SAndroid Build Coastguard Worker    finish_program(program.get());
339*61046927SAndroid Build Coastguard Worker    std::vector<uint32_t> binary;
340*61046927SAndroid Build Coastguard Worker    unsigned exec_size = emit_program(program.get(), binary);
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker    /* we could use CLRX for disassembly but that would require it to be
343*61046927SAndroid Build Coastguard Worker     * installed */
344*61046927SAndroid Build Coastguard Worker    if (program->gfx_level >= GFX8) {
345*61046927SAndroid Build Coastguard Worker       print_asm(program.get(), binary, exec_size / 4u, output);
346*61046927SAndroid Build Coastguard Worker    } else {
347*61046927SAndroid Build Coastguard Worker       // TODO: maybe we should use CLRX and skip this test if it's not available?
348*61046927SAndroid Build Coastguard Worker       for (uint32_t dword : binary)
349*61046927SAndroid Build Coastguard Worker          fprintf(output, "%.8x\n", dword);
350*61046927SAndroid Build Coastguard Worker    }
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker 
353*61046927SAndroid Build Coastguard Worker void
live_var_analysis_debug_func(void * private_data,enum aco_compiler_debug_level level,const char * message)354*61046927SAndroid Build Coastguard Worker live_var_analysis_debug_func(void* private_data, enum aco_compiler_debug_level level, const char* message)
355*61046927SAndroid Build Coastguard Worker {
356*61046927SAndroid Build Coastguard Worker    if (level == ACO_COMPILER_DEBUG_LEVEL_ERROR)
357*61046927SAndroid Build Coastguard Worker       *(bool *)private_data = true;
358*61046927SAndroid Build Coastguard Worker }
359*61046927SAndroid Build Coastguard Worker 
360*61046927SAndroid Build Coastguard Worker void
finish_isel_test(enum ac_hw_stage hw_stage,unsigned wave_size)361*61046927SAndroid Build Coastguard Worker finish_isel_test(enum ac_hw_stage hw_stage, unsigned wave_size)
362*61046927SAndroid Build Coastguard Worker {
363*61046927SAndroid Build Coastguard Worker    nir_validate_shader(nb->shader, "in finish_isel_test");
364*61046927SAndroid Build Coastguard Worker    nir_validate_ssa_dominance(nb->shader, "in finish_isel_test");
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    program.reset(new Program);
367*61046927SAndroid Build Coastguard Worker    program->debug.func = nullptr;
368*61046927SAndroid Build Coastguard Worker    program->debug.private_data = nullptr;
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker    ac_shader_args args = {};
371*61046927SAndroid Build Coastguard Worker 
372*61046927SAndroid Build Coastguard Worker    aco_compiler_options options = {};
373*61046927SAndroid Build Coastguard Worker    options.family = rad_info.family;
374*61046927SAndroid Build Coastguard Worker    options.gfx_level = rad_info.gfx_level;
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker    memset(&info, 0, sizeof(info));
377*61046927SAndroid Build Coastguard Worker    info.hw_stage = hw_stage;
378*61046927SAndroid Build Coastguard Worker    info.wave_size = wave_size;
379*61046927SAndroid Build Coastguard Worker    info.workgroup_size = nb->shader->info.workgroup_size[0] * nb->shader->info.workgroup_size[1] * nb->shader->info.workgroup_size[2];
380*61046927SAndroid Build Coastguard Worker 
381*61046927SAndroid Build Coastguard Worker    memset(&config, 0, sizeof(config));
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker    select_program(program.get(), 1, &nb->shader, &config, &options, &info, &args);
384*61046927SAndroid Build Coastguard Worker    dominator_tree(program.get());
385*61046927SAndroid Build Coastguard Worker    lower_phis(program.get());
386*61046927SAndroid Build Coastguard Worker 
387*61046927SAndroid Build Coastguard Worker    ralloc_free(nb->shader);
388*61046927SAndroid Build Coastguard Worker    glsl_type_singleton_decref();
389*61046927SAndroid Build Coastguard Worker 
390*61046927SAndroid Build Coastguard Worker    aco_print_program(program.get(), output);
391*61046927SAndroid Build Coastguard Worker 
392*61046927SAndroid Build Coastguard Worker    if (!aco::validate_ir(program.get())) {
393*61046927SAndroid Build Coastguard Worker       fail_test("Validation after instruction selection failed");
394*61046927SAndroid Build Coastguard Worker       return;
395*61046927SAndroid Build Coastguard Worker    }
396*61046927SAndroid Build Coastguard Worker    if (!aco::validate_cfg(program.get())) {
397*61046927SAndroid Build Coastguard Worker       fail_test("Invalidate CFG");
398*61046927SAndroid Build Coastguard Worker       return;
399*61046927SAndroid Build Coastguard Worker    }
400*61046927SAndroid Build Coastguard Worker 
401*61046927SAndroid Build Coastguard Worker    bool live_var_fail = false;
402*61046927SAndroid Build Coastguard Worker    program->debug.func = &live_var_analysis_debug_func;
403*61046927SAndroid Build Coastguard Worker    program->debug.private_data = &live_var_fail;
404*61046927SAndroid Build Coastguard Worker    aco::live_var_analysis(program.get());
405*61046927SAndroid Build Coastguard Worker    if (live_var_fail) {
406*61046927SAndroid Build Coastguard Worker       fail_test("Live var analysis failed");
407*61046927SAndroid Build Coastguard Worker       return;
408*61046927SAndroid Build Coastguard Worker    }
409*61046927SAndroid Build Coastguard Worker }
410*61046927SAndroid Build Coastguard Worker 
411*61046927SAndroid Build Coastguard Worker void
writeout(unsigned i,Temp tmp)412*61046927SAndroid Build Coastguard Worker writeout(unsigned i, Temp tmp)
413*61046927SAndroid Build Coastguard Worker {
414*61046927SAndroid Build Coastguard Worker    if (tmp.id())
415*61046927SAndroid Build Coastguard Worker       bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), tmp);
416*61046927SAndroid Build Coastguard Worker    else
417*61046927SAndroid Build Coastguard Worker       bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i));
418*61046927SAndroid Build Coastguard Worker }
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker void
writeout(unsigned i,aco::Builder::Result res)421*61046927SAndroid Build Coastguard Worker writeout(unsigned i, aco::Builder::Result res)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker    bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), res);
424*61046927SAndroid Build Coastguard Worker }
425*61046927SAndroid Build Coastguard Worker 
426*61046927SAndroid Build Coastguard Worker void
writeout(unsigned i,Operand op)427*61046927SAndroid Build Coastguard Worker writeout(unsigned i, Operand op)
428*61046927SAndroid Build Coastguard Worker {
429*61046927SAndroid Build Coastguard Worker    bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), op);
430*61046927SAndroid Build Coastguard Worker }
431*61046927SAndroid Build Coastguard Worker 
432*61046927SAndroid Build Coastguard Worker void
writeout(unsigned i,Operand op0,Operand op1)433*61046927SAndroid Build Coastguard Worker writeout(unsigned i, Operand op0, Operand op1)
434*61046927SAndroid Build Coastguard Worker {
435*61046927SAndroid Build Coastguard Worker    bld.pseudo(aco_opcode::p_unit_test, Operand::c32(i), op0, op1);
436*61046927SAndroid Build Coastguard Worker }
437*61046927SAndroid Build Coastguard Worker 
438*61046927SAndroid Build Coastguard Worker Temp
fneg(Temp src,Builder b)439*61046927SAndroid Build Coastguard Worker fneg(Temp src, Builder b)
440*61046927SAndroid Build Coastguard Worker {
441*61046927SAndroid Build Coastguard Worker    if (src.bytes() == 2)
442*61046927SAndroid Build Coastguard Worker       return b.vop2(aco_opcode::v_mul_f16, b.def(v2b), Operand::c16(0xbc00u), src);
443*61046927SAndroid Build Coastguard Worker    else
444*61046927SAndroid Build Coastguard Worker       return b.vop2(aco_opcode::v_mul_f32, b.def(v1), Operand::c32(0xbf800000u), src);
445*61046927SAndroid Build Coastguard Worker }
446*61046927SAndroid Build Coastguard Worker 
447*61046927SAndroid Build Coastguard Worker Temp
fabs(Temp src,Builder b)448*61046927SAndroid Build Coastguard Worker fabs(Temp src, Builder b)
449*61046927SAndroid Build Coastguard Worker {
450*61046927SAndroid Build Coastguard Worker    if (src.bytes() == 2) {
451*61046927SAndroid Build Coastguard Worker       Builder::Result res =
452*61046927SAndroid Build Coastguard Worker          b.vop2_e64(aco_opcode::v_mul_f16, b.def(v2b), Operand::c16(0x3c00), src);
453*61046927SAndroid Build Coastguard Worker       res->valu().abs[1] = true;
454*61046927SAndroid Build Coastguard Worker       return res;
455*61046927SAndroid Build Coastguard Worker    } else {
456*61046927SAndroid Build Coastguard Worker       Builder::Result res =
457*61046927SAndroid Build Coastguard Worker          b.vop2_e64(aco_opcode::v_mul_f32, b.def(v1), Operand::c32(0x3f800000u), src);
458*61046927SAndroid Build Coastguard Worker       res->valu().abs[1] = true;
459*61046927SAndroid Build Coastguard Worker       return res;
460*61046927SAndroid Build Coastguard Worker    }
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker Temp
f2f32(Temp src,Builder b)464*61046927SAndroid Build Coastguard Worker f2f32(Temp src, Builder b)
465*61046927SAndroid Build Coastguard Worker {
466*61046927SAndroid Build Coastguard Worker    return b.vop1(aco_opcode::v_cvt_f32_f16, b.def(v1), src);
467*61046927SAndroid Build Coastguard Worker }
468*61046927SAndroid Build Coastguard Worker 
469*61046927SAndroid Build Coastguard Worker Temp
f2f16(Temp src,Builder b)470*61046927SAndroid Build Coastguard Worker f2f16(Temp src, Builder b)
471*61046927SAndroid Build Coastguard Worker {
472*61046927SAndroid Build Coastguard Worker    return b.vop1(aco_opcode::v_cvt_f16_f32, b.def(v2b), src);
473*61046927SAndroid Build Coastguard Worker }
474*61046927SAndroid Build Coastguard Worker 
475*61046927SAndroid Build Coastguard Worker Temp
u2u16(Temp src,Builder b)476*61046927SAndroid Build Coastguard Worker u2u16(Temp src, Builder b)
477*61046927SAndroid Build Coastguard Worker {
478*61046927SAndroid Build Coastguard Worker    return b.pseudo(aco_opcode::p_extract_vector, b.def(v2b), src, Operand::zero());
479*61046927SAndroid Build Coastguard Worker }
480*61046927SAndroid Build Coastguard Worker 
481*61046927SAndroid Build Coastguard Worker Temp
fadd(Temp src0,Temp src1,Builder b)482*61046927SAndroid Build Coastguard Worker fadd(Temp src0, Temp src1, Builder b)
483*61046927SAndroid Build Coastguard Worker {
484*61046927SAndroid Build Coastguard Worker    if (src0.bytes() == 2)
485*61046927SAndroid Build Coastguard Worker       return b.vop2(aco_opcode::v_add_f16, b.def(v2b), src0, src1);
486*61046927SAndroid Build Coastguard Worker    else
487*61046927SAndroid Build Coastguard Worker       return b.vop2(aco_opcode::v_add_f32, b.def(v1), src0, src1);
488*61046927SAndroid Build Coastguard Worker }
489*61046927SAndroid Build Coastguard Worker 
490*61046927SAndroid Build Coastguard Worker Temp
fmul(Temp src0,Temp src1,Builder b)491*61046927SAndroid Build Coastguard Worker fmul(Temp src0, Temp src1, Builder b)
492*61046927SAndroid Build Coastguard Worker {
493*61046927SAndroid Build Coastguard Worker    if (src0.bytes() == 2)
494*61046927SAndroid Build Coastguard Worker       return b.vop2(aco_opcode::v_mul_f16, b.def(v2b), src0, src1);
495*61046927SAndroid Build Coastguard Worker    else
496*61046927SAndroid Build Coastguard Worker       return b.vop2(aco_opcode::v_mul_f32, b.def(v1), src0, src1);
497*61046927SAndroid Build Coastguard Worker }
498*61046927SAndroid Build Coastguard Worker 
499*61046927SAndroid Build Coastguard Worker Temp
fma(Temp src0,Temp src1,Temp src2,Builder b)500*61046927SAndroid Build Coastguard Worker fma(Temp src0, Temp src1, Temp src2, Builder b)
501*61046927SAndroid Build Coastguard Worker {
502*61046927SAndroid Build Coastguard Worker    if (src0.bytes() == 2)
503*61046927SAndroid Build Coastguard Worker       return b.vop3(aco_opcode::v_fma_f16, b.def(v2b), src0, src1, src2);
504*61046927SAndroid Build Coastguard Worker    else
505*61046927SAndroid Build Coastguard Worker       return b.vop3(aco_opcode::v_fma_f32, b.def(v1), src0, src1, src2);
506*61046927SAndroid Build Coastguard Worker }
507*61046927SAndroid Build Coastguard Worker 
508*61046927SAndroid Build Coastguard Worker Temp
fsat(Temp src,Builder b)509*61046927SAndroid Build Coastguard Worker fsat(Temp src, Builder b)
510*61046927SAndroid Build Coastguard Worker {
511*61046927SAndroid Build Coastguard Worker    if (src.bytes() == 2)
512*61046927SAndroid Build Coastguard Worker       return b.vop3(aco_opcode::v_med3_f16, b.def(v2b), Operand::c16(0u), Operand::c16(0x3c00u),
513*61046927SAndroid Build Coastguard Worker                     src);
514*61046927SAndroid Build Coastguard Worker    else
515*61046927SAndroid Build Coastguard Worker       return b.vop3(aco_opcode::v_med3_f32, b.def(v1), Operand::zero(), Operand::c32(0x3f800000u),
516*61046927SAndroid Build Coastguard Worker                     src);
517*61046927SAndroid Build Coastguard Worker }
518*61046927SAndroid Build Coastguard Worker 
519*61046927SAndroid Build Coastguard Worker Temp
fmin(Temp src0,Temp src1,Builder b)520*61046927SAndroid Build Coastguard Worker fmin(Temp src0, Temp src1, Builder b)
521*61046927SAndroid Build Coastguard Worker {
522*61046927SAndroid Build Coastguard Worker    return b.vop2(aco_opcode::v_min_f32, b.def(v1), src0, src1);
523*61046927SAndroid Build Coastguard Worker }
524*61046927SAndroid Build Coastguard Worker 
525*61046927SAndroid Build Coastguard Worker Temp
fmax(Temp src0,Temp src1,Builder b)526*61046927SAndroid Build Coastguard Worker fmax(Temp src0, Temp src1, Builder b)
527*61046927SAndroid Build Coastguard Worker {
528*61046927SAndroid Build Coastguard Worker    return b.vop2(aco_opcode::v_max_f32, b.def(v1), src0, src1);
529*61046927SAndroid Build Coastguard Worker }
530*61046927SAndroid Build Coastguard Worker 
531*61046927SAndroid Build Coastguard Worker Temp
ext_ushort(Temp src,unsigned idx,Builder b)532*61046927SAndroid Build Coastguard Worker ext_ushort(Temp src, unsigned idx, Builder b)
533*61046927SAndroid Build Coastguard Worker {
534*61046927SAndroid Build Coastguard Worker    return b.pseudo(aco_opcode::p_extract, b.def(src.regClass()), src, Operand::c32(idx),
535*61046927SAndroid Build Coastguard Worker                    Operand::c32(16u), Operand::c32(false));
536*61046927SAndroid Build Coastguard Worker }
537*61046927SAndroid Build Coastguard Worker 
538*61046927SAndroid Build Coastguard Worker Temp
ext_ubyte(Temp src,unsigned idx,Builder b)539*61046927SAndroid Build Coastguard Worker ext_ubyte(Temp src, unsigned idx, Builder b)
540*61046927SAndroid Build Coastguard Worker {
541*61046927SAndroid Build Coastguard Worker    return b.pseudo(aco_opcode::p_extract, b.def(src.regClass()), src, Operand::c32(idx),
542*61046927SAndroid Build Coastguard Worker                    Operand::c32(8u), Operand::c32(false));
543*61046927SAndroid Build Coastguard Worker }
544*61046927SAndroid Build Coastguard Worker 
545*61046927SAndroid Build Coastguard Worker void
emit_divergent_if_else(Program * prog,aco::Builder & b,Operand cond,std::function<void ()> then,std::function<void ()> els)546*61046927SAndroid Build Coastguard Worker emit_divergent_if_else(Program* prog, aco::Builder& b, Operand cond, std::function<void()> then,
547*61046927SAndroid Build Coastguard Worker                        std::function<void()> els)
548*61046927SAndroid Build Coastguard Worker {
549*61046927SAndroid Build Coastguard Worker    prog->blocks.reserve(prog->blocks.size() + 6);
550*61046927SAndroid Build Coastguard Worker 
551*61046927SAndroid Build Coastguard Worker    Block* if_block = &prog->blocks.back();
552*61046927SAndroid Build Coastguard Worker    Block* then_logical = prog->create_and_insert_block();
553*61046927SAndroid Build Coastguard Worker    Block* then_linear = prog->create_and_insert_block();
554*61046927SAndroid Build Coastguard Worker    Block* invert = prog->create_and_insert_block();
555*61046927SAndroid Build Coastguard Worker    Block* else_logical = prog->create_and_insert_block();
556*61046927SAndroid Build Coastguard Worker    Block* else_linear = prog->create_and_insert_block();
557*61046927SAndroid Build Coastguard Worker    Block* endif_block = prog->create_and_insert_block();
558*61046927SAndroid Build Coastguard Worker 
559*61046927SAndroid Build Coastguard Worker    if_block->kind |= block_kind_branch;
560*61046927SAndroid Build Coastguard Worker    invert->kind |= block_kind_invert;
561*61046927SAndroid Build Coastguard Worker    endif_block->kind |= block_kind_merge | (if_block->kind & block_kind_top_level);
562*61046927SAndroid Build Coastguard Worker 
563*61046927SAndroid Build Coastguard Worker    /* Set up logical CF */
564*61046927SAndroid Build Coastguard Worker    then_logical->logical_preds.push_back(if_block->index);
565*61046927SAndroid Build Coastguard Worker    else_logical->logical_preds.push_back(if_block->index);
566*61046927SAndroid Build Coastguard Worker    endif_block->logical_preds.push_back(then_logical->index);
567*61046927SAndroid Build Coastguard Worker    endif_block->logical_preds.push_back(else_logical->index);
568*61046927SAndroid Build Coastguard Worker 
569*61046927SAndroid Build Coastguard Worker    /* Set up linear CF */
570*61046927SAndroid Build Coastguard Worker    then_logical->linear_preds.push_back(if_block->index);
571*61046927SAndroid Build Coastguard Worker    then_linear->linear_preds.push_back(if_block->index);
572*61046927SAndroid Build Coastguard Worker    invert->linear_preds.push_back(then_logical->index);
573*61046927SAndroid Build Coastguard Worker    invert->linear_preds.push_back(then_linear->index);
574*61046927SAndroid Build Coastguard Worker    else_logical->linear_preds.push_back(invert->index);
575*61046927SAndroid Build Coastguard Worker    else_linear->linear_preds.push_back(invert->index);
576*61046927SAndroid Build Coastguard Worker    endif_block->linear_preds.push_back(else_logical->index);
577*61046927SAndroid Build Coastguard Worker    endif_block->linear_preds.push_back(else_linear->index);
578*61046927SAndroid Build Coastguard Worker 
579*61046927SAndroid Build Coastguard Worker    PhysReg saved_exec_reg(84);
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker    b.reset(if_block);
582*61046927SAndroid Build Coastguard Worker    Temp saved_exec = b.sop1(Builder::s_and_saveexec, b.def(b.lm, saved_exec_reg),
583*61046927SAndroid Build Coastguard Worker                             Definition(scc, s1), Definition(exec, b.lm), cond, Operand(exec, b.lm));
584*61046927SAndroid Build Coastguard Worker    b.branch(aco_opcode::p_cbranch_nz, Definition(vcc, bld.lm), then_logical->index,
585*61046927SAndroid Build Coastguard Worker             then_linear->index);
586*61046927SAndroid Build Coastguard Worker 
587*61046927SAndroid Build Coastguard Worker    b.reset(then_logical);
588*61046927SAndroid Build Coastguard Worker    b.pseudo(aco_opcode::p_logical_start);
589*61046927SAndroid Build Coastguard Worker    then();
590*61046927SAndroid Build Coastguard Worker    b.pseudo(aco_opcode::p_logical_end);
591*61046927SAndroid Build Coastguard Worker    b.branch(aco_opcode::p_branch, Definition(vcc, bld.lm), invert->index);
592*61046927SAndroid Build Coastguard Worker 
593*61046927SAndroid Build Coastguard Worker    b.reset(then_linear);
594*61046927SAndroid Build Coastguard Worker    b.branch(aco_opcode::p_branch, Definition(vcc, bld.lm), invert->index);
595*61046927SAndroid Build Coastguard Worker 
596*61046927SAndroid Build Coastguard Worker    b.reset(invert);
597*61046927SAndroid Build Coastguard Worker    b.sop2(Builder::s_andn2, Definition(exec, bld.lm), Definition(scc, s1),
598*61046927SAndroid Build Coastguard Worker           Operand(saved_exec, saved_exec_reg), Operand(exec, bld.lm));
599*61046927SAndroid Build Coastguard Worker    b.branch(aco_opcode::p_cbranch_nz, Definition(vcc, bld.lm), else_logical->index,
600*61046927SAndroid Build Coastguard Worker             else_linear->index);
601*61046927SAndroid Build Coastguard Worker 
602*61046927SAndroid Build Coastguard Worker    b.reset(else_logical);
603*61046927SAndroid Build Coastguard Worker    b.pseudo(aco_opcode::p_logical_start);
604*61046927SAndroid Build Coastguard Worker    els();
605*61046927SAndroid Build Coastguard Worker    b.pseudo(aco_opcode::p_logical_end);
606*61046927SAndroid Build Coastguard Worker    b.branch(aco_opcode::p_branch, Definition(vcc, bld.lm), endif_block->index);
607*61046927SAndroid Build Coastguard Worker 
608*61046927SAndroid Build Coastguard Worker    b.reset(else_linear);
609*61046927SAndroid Build Coastguard Worker    b.branch(aco_opcode::p_branch, Definition(vcc, bld.lm), endif_block->index);
610*61046927SAndroid Build Coastguard Worker 
611*61046927SAndroid Build Coastguard Worker    b.reset(endif_block);
612*61046927SAndroid Build Coastguard Worker    b.pseudo(aco_opcode::p_parallelcopy, Definition(exec, bld.lm),
613*61046927SAndroid Build Coastguard Worker             Operand(saved_exec, saved_exec_reg));
614*61046927SAndroid Build Coastguard Worker }
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker VkDevice
get_vk_device(enum amd_gfx_level gfx_level)617*61046927SAndroid Build Coastguard Worker get_vk_device(enum amd_gfx_level gfx_level)
618*61046927SAndroid Build Coastguard Worker {
619*61046927SAndroid Build Coastguard Worker    enum radeon_family family;
620*61046927SAndroid Build Coastguard Worker    switch (gfx_level) {
621*61046927SAndroid Build Coastguard Worker    case GFX6: family = CHIP_TAHITI; break;
622*61046927SAndroid Build Coastguard Worker    case GFX7: family = CHIP_BONAIRE; break;
623*61046927SAndroid Build Coastguard Worker    case GFX8: family = CHIP_POLARIS10; break;
624*61046927SAndroid Build Coastguard Worker    case GFX9: family = CHIP_VEGA10; break;
625*61046927SAndroid Build Coastguard Worker    case GFX10: family = CHIP_NAVI10; break;
626*61046927SAndroid Build Coastguard Worker    case GFX10_3: family = CHIP_NAVI21; break;
627*61046927SAndroid Build Coastguard Worker    case GFX11: family = CHIP_NAVI31; break;
628*61046927SAndroid Build Coastguard Worker    case GFX12: family = CHIP_GFX1200; break;
629*61046927SAndroid Build Coastguard Worker    default: family = CHIP_UNKNOWN; break;
630*61046927SAndroid Build Coastguard Worker    }
631*61046927SAndroid Build Coastguard Worker    return get_vk_device(family);
632*61046927SAndroid Build Coastguard Worker }
633*61046927SAndroid Build Coastguard Worker 
634*61046927SAndroid Build Coastguard Worker VkDevice
get_vk_device(enum radeon_family family)635*61046927SAndroid Build Coastguard Worker get_vk_device(enum radeon_family family)
636*61046927SAndroid Build Coastguard Worker {
637*61046927SAndroid Build Coastguard Worker    assert(family != CHIP_UNKNOWN);
638*61046927SAndroid Build Coastguard Worker 
639*61046927SAndroid Build Coastguard Worker    std::lock_guard<std::mutex> guard(create_device_mutex);
640*61046927SAndroid Build Coastguard Worker 
641*61046927SAndroid Build Coastguard Worker    if (device_cache[family])
642*61046927SAndroid Build Coastguard Worker       return device_cache[family];
643*61046927SAndroid Build Coastguard Worker 
644*61046927SAndroid Build Coastguard Worker    setenv("RADV_FORCE_FAMILY", ac_get_family_name(family), 1);
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker    VkApplicationInfo app_info = {};
647*61046927SAndroid Build Coastguard Worker    app_info.pApplicationName = "aco_tests";
648*61046927SAndroid Build Coastguard Worker    app_info.apiVersion = VK_API_VERSION_1_2;
649*61046927SAndroid Build Coastguard Worker    VkInstanceCreateInfo instance_create_info = {};
650*61046927SAndroid Build Coastguard Worker    instance_create_info.pApplicationInfo = &app_info;
651*61046927SAndroid Build Coastguard Worker    instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
652*61046927SAndroid Build Coastguard Worker    ASSERTED VkResult result = ((PFN_vkCreateInstance)vk_icdGetInstanceProcAddr(
653*61046927SAndroid Build Coastguard Worker       NULL, "vkCreateInstance"))(&instance_create_info, NULL, &instance_cache[family]);
654*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker #define ITEM(n) n = (PFN_vk##n)vk_icdGetInstanceProcAddr(instance_cache[family], "vk" #n);
657*61046927SAndroid Build Coastguard Worker    FUNCTION_LIST
658*61046927SAndroid Build Coastguard Worker #undef ITEM
659*61046927SAndroid Build Coastguard Worker 
660*61046927SAndroid Build Coastguard Worker    uint32_t device_count = 1;
661*61046927SAndroid Build Coastguard Worker    VkPhysicalDevice device = VK_NULL_HANDLE;
662*61046927SAndroid Build Coastguard Worker    result = EnumeratePhysicalDevices(instance_cache[family], &device_count, &device);
663*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
664*61046927SAndroid Build Coastguard Worker    assert(device != VK_NULL_HANDLE);
665*61046927SAndroid Build Coastguard Worker 
666*61046927SAndroid Build Coastguard Worker    VkDeviceCreateInfo device_create_info = {};
667*61046927SAndroid Build Coastguard Worker    device_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
668*61046927SAndroid Build Coastguard Worker    static const char* extensions[] = {"VK_KHR_pipeline_executable_properties"};
669*61046927SAndroid Build Coastguard Worker    device_create_info.enabledExtensionCount = sizeof(extensions) / sizeof(extensions[0]);
670*61046927SAndroid Build Coastguard Worker    device_create_info.ppEnabledExtensionNames = extensions;
671*61046927SAndroid Build Coastguard Worker    result = CreateDevice(device, &device_create_info, NULL, &device_cache[family]);
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker    return device_cache[family];
674*61046927SAndroid Build Coastguard Worker }
675*61046927SAndroid Build Coastguard Worker 
676*61046927SAndroid Build Coastguard Worker static struct DestroyDevices {
~DestroyDevicesDestroyDevices677*61046927SAndroid Build Coastguard Worker    ~DestroyDevices()
678*61046927SAndroid Build Coastguard Worker    {
679*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < CHIP_LAST; i++) {
680*61046927SAndroid Build Coastguard Worker          if (!device_cache[i])
681*61046927SAndroid Build Coastguard Worker             continue;
682*61046927SAndroid Build Coastguard Worker          DestroyDevice(device_cache[i], NULL);
683*61046927SAndroid Build Coastguard Worker          DestroyInstance(instance_cache[i], NULL);
684*61046927SAndroid Build Coastguard Worker       }
685*61046927SAndroid Build Coastguard Worker    }
686*61046927SAndroid Build Coastguard Worker } destroy_devices;
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker void
print_pipeline_ir(VkDevice device,VkPipeline pipeline,VkShaderStageFlagBits stages,const char * name,bool remove_encoding)689*61046927SAndroid Build Coastguard Worker print_pipeline_ir(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits stages,
690*61046927SAndroid Build Coastguard Worker                   const char* name, bool remove_encoding)
691*61046927SAndroid Build Coastguard Worker {
692*61046927SAndroid Build Coastguard Worker    uint32_t executable_count = 16;
693*61046927SAndroid Build Coastguard Worker    VkPipelineExecutablePropertiesKHR executables[16];
694*61046927SAndroid Build Coastguard Worker    VkPipelineInfoKHR pipeline_info;
695*61046927SAndroid Build Coastguard Worker    pipeline_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR;
696*61046927SAndroid Build Coastguard Worker    pipeline_info.pNext = NULL;
697*61046927SAndroid Build Coastguard Worker    pipeline_info.pipeline = pipeline;
698*61046927SAndroid Build Coastguard Worker    ASSERTED VkResult result =
699*61046927SAndroid Build Coastguard Worker       GetPipelineExecutablePropertiesKHR(device, &pipeline_info, &executable_count, executables);
700*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
701*61046927SAndroid Build Coastguard Worker 
702*61046927SAndroid Build Coastguard Worker    uint32_t executable = 0;
703*61046927SAndroid Build Coastguard Worker    for (; executable < executable_count; executable++) {
704*61046927SAndroid Build Coastguard Worker       if (executables[executable].stages == stages)
705*61046927SAndroid Build Coastguard Worker          break;
706*61046927SAndroid Build Coastguard Worker    }
707*61046927SAndroid Build Coastguard Worker    assert(executable != executable_count);
708*61046927SAndroid Build Coastguard Worker 
709*61046927SAndroid Build Coastguard Worker    VkPipelineExecutableInfoKHR exec_info;
710*61046927SAndroid Build Coastguard Worker    exec_info.sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR;
711*61046927SAndroid Build Coastguard Worker    exec_info.pNext = NULL;
712*61046927SAndroid Build Coastguard Worker    exec_info.pipeline = pipeline;
713*61046927SAndroid Build Coastguard Worker    exec_info.executableIndex = executable;
714*61046927SAndroid Build Coastguard Worker 
715*61046927SAndroid Build Coastguard Worker    uint32_t ir_count = 16;
716*61046927SAndroid Build Coastguard Worker    VkPipelineExecutableInternalRepresentationKHR ir[16];
717*61046927SAndroid Build Coastguard Worker    memset(ir, 0, sizeof(ir));
718*61046927SAndroid Build Coastguard Worker    result = GetPipelineExecutableInternalRepresentationsKHR(device, &exec_info, &ir_count, ir);
719*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker    VkPipelineExecutableInternalRepresentationKHR* requested_ir = nullptr;
722*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ir_count; ++i) {
723*61046927SAndroid Build Coastguard Worker       if (strcmp(ir[i].name, name) == 0) {
724*61046927SAndroid Build Coastguard Worker          requested_ir = &ir[i];
725*61046927SAndroid Build Coastguard Worker          break;
726*61046927SAndroid Build Coastguard Worker       }
727*61046927SAndroid Build Coastguard Worker    }
728*61046927SAndroid Build Coastguard Worker    assert(requested_ir && "Could not find requested IR");
729*61046927SAndroid Build Coastguard Worker 
730*61046927SAndroid Build Coastguard Worker    char* data = (char*)malloc(requested_ir->dataSize);
731*61046927SAndroid Build Coastguard Worker    requested_ir->pData = data;
732*61046927SAndroid Build Coastguard Worker    result = GetPipelineExecutableInternalRepresentationsKHR(device, &exec_info, &ir_count, ir);
733*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
734*61046927SAndroid Build Coastguard Worker 
735*61046927SAndroid Build Coastguard Worker    if (remove_encoding) {
736*61046927SAndroid Build Coastguard Worker       for (char* c = data; *c; c++) {
737*61046927SAndroid Build Coastguard Worker          if (*c == ';') {
738*61046927SAndroid Build Coastguard Worker             for (; *c && *c != '\n'; c++)
739*61046927SAndroid Build Coastguard Worker                *c = ' ';
740*61046927SAndroid Build Coastguard Worker          }
741*61046927SAndroid Build Coastguard Worker       }
742*61046927SAndroid Build Coastguard Worker    }
743*61046927SAndroid Build Coastguard Worker 
744*61046927SAndroid Build Coastguard Worker    fprintf(output, "%s", data);
745*61046927SAndroid Build Coastguard Worker    free(data);
746*61046927SAndroid Build Coastguard Worker }
747*61046927SAndroid Build Coastguard Worker 
748*61046927SAndroid Build Coastguard Worker VkShaderModule
__qoCreateShaderModule(VkDevice dev,const QoShaderModuleCreateInfo * module_info)749*61046927SAndroid Build Coastguard Worker __qoCreateShaderModule(VkDevice dev, const QoShaderModuleCreateInfo* module_info)
750*61046927SAndroid Build Coastguard Worker {
751*61046927SAndroid Build Coastguard Worker    VkShaderModuleCreateInfo vk_module_info;
752*61046927SAndroid Build Coastguard Worker    vk_module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
753*61046927SAndroid Build Coastguard Worker    vk_module_info.pNext = NULL;
754*61046927SAndroid Build Coastguard Worker    vk_module_info.flags = 0;
755*61046927SAndroid Build Coastguard Worker    vk_module_info.codeSize = module_info->spirvSize;
756*61046927SAndroid Build Coastguard Worker    vk_module_info.pCode = (const uint32_t*)module_info->pSpirv;
757*61046927SAndroid Build Coastguard Worker 
758*61046927SAndroid Build Coastguard Worker    VkShaderModule module;
759*61046927SAndroid Build Coastguard Worker    ASSERTED VkResult result = CreateShaderModule(dev, &vk_module_info, NULL, &module);
760*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
761*61046927SAndroid Build Coastguard Worker 
762*61046927SAndroid Build Coastguard Worker    return module;
763*61046927SAndroid Build Coastguard Worker }
764*61046927SAndroid Build Coastguard Worker 
PipelineBuilder(VkDevice dev)765*61046927SAndroid Build Coastguard Worker PipelineBuilder::PipelineBuilder(VkDevice dev)
766*61046927SAndroid Build Coastguard Worker {
767*61046927SAndroid Build Coastguard Worker    memset(this, 0, sizeof(*this));
768*61046927SAndroid Build Coastguard Worker    topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
769*61046927SAndroid Build Coastguard Worker    device = dev;
770*61046927SAndroid Build Coastguard Worker }
771*61046927SAndroid Build Coastguard Worker 
~PipelineBuilder()772*61046927SAndroid Build Coastguard Worker PipelineBuilder::~PipelineBuilder()
773*61046927SAndroid Build Coastguard Worker {
774*61046927SAndroid Build Coastguard Worker    DestroyPipeline(device, pipeline, NULL);
775*61046927SAndroid Build Coastguard Worker 
776*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < (is_compute() ? 1 : gfx_pipeline_info.stageCount); i++) {
777*61046927SAndroid Build Coastguard Worker       VkPipelineShaderStageCreateInfo* stage_info = &stages[i];
778*61046927SAndroid Build Coastguard Worker       if (owned_stages & stage_info->stage)
779*61046927SAndroid Build Coastguard Worker          DestroyShaderModule(device, stage_info->module, NULL);
780*61046927SAndroid Build Coastguard Worker    }
781*61046927SAndroid Build Coastguard Worker 
782*61046927SAndroid Build Coastguard Worker    DestroyPipelineLayout(device, pipeline_layout, NULL);
783*61046927SAndroid Build Coastguard Worker 
784*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < util_bitcount64(desc_layouts_used); i++)
785*61046927SAndroid Build Coastguard Worker       DestroyDescriptorSetLayout(device, desc_layouts[i], NULL);
786*61046927SAndroid Build Coastguard Worker 
787*61046927SAndroid Build Coastguard Worker    DestroyRenderPass(device, render_pass, NULL);
788*61046927SAndroid Build Coastguard Worker }
789*61046927SAndroid Build Coastguard Worker 
790*61046927SAndroid Build Coastguard Worker void
add_desc_binding(VkShaderStageFlags stage_flags,uint32_t layout,uint32_t binding,VkDescriptorType type,uint32_t count)791*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_desc_binding(VkShaderStageFlags stage_flags, uint32_t layout, uint32_t binding,
792*61046927SAndroid Build Coastguard Worker                                   VkDescriptorType type, uint32_t count)
793*61046927SAndroid Build Coastguard Worker {
794*61046927SAndroid Build Coastguard Worker    desc_layouts_used |= 1ull << layout;
795*61046927SAndroid Build Coastguard Worker    desc_bindings[layout][num_desc_bindings[layout]++] = {binding, type, count, stage_flags, NULL};
796*61046927SAndroid Build Coastguard Worker }
797*61046927SAndroid Build Coastguard Worker 
798*61046927SAndroid Build Coastguard Worker void
add_vertex_binding(uint32_t binding,uint32_t stride,VkVertexInputRate rate)799*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_vertex_binding(uint32_t binding, uint32_t stride, VkVertexInputRate rate)
800*61046927SAndroid Build Coastguard Worker {
801*61046927SAndroid Build Coastguard Worker    vs_bindings[vs_input.vertexBindingDescriptionCount++] = {binding, stride, rate};
802*61046927SAndroid Build Coastguard Worker }
803*61046927SAndroid Build Coastguard Worker 
804*61046927SAndroid Build Coastguard Worker void
add_vertex_attribute(uint32_t location,uint32_t binding,VkFormat format,uint32_t offset)805*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_vertex_attribute(uint32_t location, uint32_t binding, VkFormat format,
806*61046927SAndroid Build Coastguard Worker                                       uint32_t offset)
807*61046927SAndroid Build Coastguard Worker {
808*61046927SAndroid Build Coastguard Worker    vs_attributes[vs_input.vertexAttributeDescriptionCount++] = {location, binding, format, offset};
809*61046927SAndroid Build Coastguard Worker }
810*61046927SAndroid Build Coastguard Worker 
811*61046927SAndroid Build Coastguard Worker void
add_resource_decls(QoShaderModuleCreateInfo * module)812*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_resource_decls(QoShaderModuleCreateInfo* module)
813*61046927SAndroid Build Coastguard Worker {
814*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < module->declarationCount; i++) {
815*61046927SAndroid Build Coastguard Worker       const QoShaderDecl* decl = &module->pDeclarations[i];
816*61046927SAndroid Build Coastguard Worker       switch (decl->decl_type) {
817*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_ubo:
818*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding,
819*61046927SAndroid Build Coastguard Worker                           VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
820*61046927SAndroid Build Coastguard Worker          break;
821*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_ssbo:
822*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding,
823*61046927SAndroid Build Coastguard Worker                           VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
824*61046927SAndroid Build Coastguard Worker          break;
825*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_img_buf:
826*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding,
827*61046927SAndroid Build Coastguard Worker                           VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
828*61046927SAndroid Build Coastguard Worker          break;
829*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_img:
830*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding,
831*61046927SAndroid Build Coastguard Worker                           VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
832*61046927SAndroid Build Coastguard Worker          break;
833*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_tex_buf:
834*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding,
835*61046927SAndroid Build Coastguard Worker                           VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
836*61046927SAndroid Build Coastguard Worker          break;
837*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_combined:
838*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding,
839*61046927SAndroid Build Coastguard Worker                           VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
840*61046927SAndroid Build Coastguard Worker          break;
841*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_tex:
842*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding,
843*61046927SAndroid Build Coastguard Worker                           VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
844*61046927SAndroid Build Coastguard Worker          break;
845*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_samp:
846*61046927SAndroid Build Coastguard Worker          add_desc_binding(module->stage, decl->set, decl->binding, VK_DESCRIPTOR_TYPE_SAMPLER);
847*61046927SAndroid Build Coastguard Worker          break;
848*61046927SAndroid Build Coastguard Worker       default: break;
849*61046927SAndroid Build Coastguard Worker       }
850*61046927SAndroid Build Coastguard Worker    }
851*61046927SAndroid Build Coastguard Worker }
852*61046927SAndroid Build Coastguard Worker 
853*61046927SAndroid Build Coastguard Worker void
add_io_decls(QoShaderModuleCreateInfo * module)854*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_io_decls(QoShaderModuleCreateInfo* module)
855*61046927SAndroid Build Coastguard Worker {
856*61046927SAndroid Build Coastguard Worker    unsigned next_vtx_offset = 0;
857*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < module->declarationCount; i++) {
858*61046927SAndroid Build Coastguard Worker       const QoShaderDecl* decl = &module->pDeclarations[i];
859*61046927SAndroid Build Coastguard Worker       switch (decl->decl_type) {
860*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_in:
861*61046927SAndroid Build Coastguard Worker          if (module->stage == VK_SHADER_STAGE_VERTEX_BIT) {
862*61046927SAndroid Build Coastguard Worker             if (!strcmp(decl->type, "float") || decl->type[0] == 'v')
863*61046927SAndroid Build Coastguard Worker                add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_SFLOAT,
864*61046927SAndroid Build Coastguard Worker                                     next_vtx_offset);
865*61046927SAndroid Build Coastguard Worker             else if (decl->type[0] == 'u')
866*61046927SAndroid Build Coastguard Worker                add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_UINT,
867*61046927SAndroid Build Coastguard Worker                                     next_vtx_offset);
868*61046927SAndroid Build Coastguard Worker             else if (decl->type[0] == 'i')
869*61046927SAndroid Build Coastguard Worker                add_vertex_attribute(decl->location, 0, VK_FORMAT_R32G32B32A32_SINT,
870*61046927SAndroid Build Coastguard Worker                                     next_vtx_offset);
871*61046927SAndroid Build Coastguard Worker             next_vtx_offset += 16;
872*61046927SAndroid Build Coastguard Worker          }
873*61046927SAndroid Build Coastguard Worker          break;
874*61046927SAndroid Build Coastguard Worker       case QoShaderDeclType_out:
875*61046927SAndroid Build Coastguard Worker          if (module->stage == VK_SHADER_STAGE_FRAGMENT_BIT) {
876*61046927SAndroid Build Coastguard Worker             if (!strcmp(decl->type, "float") || decl->type[0] == 'v')
877*61046927SAndroid Build Coastguard Worker                color_outputs[decl->location] = VK_FORMAT_R32G32B32A32_SFLOAT;
878*61046927SAndroid Build Coastguard Worker             else if (decl->type[0] == 'u')
879*61046927SAndroid Build Coastguard Worker                color_outputs[decl->location] = VK_FORMAT_R32G32B32A32_UINT;
880*61046927SAndroid Build Coastguard Worker             else if (decl->type[0] == 'i')
881*61046927SAndroid Build Coastguard Worker                color_outputs[decl->location] = VK_FORMAT_R32G32B32A32_SINT;
882*61046927SAndroid Build Coastguard Worker          }
883*61046927SAndroid Build Coastguard Worker          break;
884*61046927SAndroid Build Coastguard Worker       default: break;
885*61046927SAndroid Build Coastguard Worker       }
886*61046927SAndroid Build Coastguard Worker    }
887*61046927SAndroid Build Coastguard Worker    if (next_vtx_offset)
888*61046927SAndroid Build Coastguard Worker       add_vertex_binding(0, next_vtx_offset);
889*61046927SAndroid Build Coastguard Worker }
890*61046927SAndroid Build Coastguard Worker 
891*61046927SAndroid Build Coastguard Worker void
add_stage(VkShaderStageFlagBits stage,VkShaderModule module,const char * name)892*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_stage(VkShaderStageFlagBits stage, VkShaderModule module, const char* name)
893*61046927SAndroid Build Coastguard Worker {
894*61046927SAndroid Build Coastguard Worker    VkPipelineShaderStageCreateInfo* stage_info;
895*61046927SAndroid Build Coastguard Worker    if (stage == VK_SHADER_STAGE_COMPUTE_BIT)
896*61046927SAndroid Build Coastguard Worker       stage_info = &stages[0];
897*61046927SAndroid Build Coastguard Worker    else
898*61046927SAndroid Build Coastguard Worker       stage_info = &stages[gfx_pipeline_info.stageCount++];
899*61046927SAndroid Build Coastguard Worker    stage_info->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
900*61046927SAndroid Build Coastguard Worker    stage_info->pNext = NULL;
901*61046927SAndroid Build Coastguard Worker    stage_info->flags = 0;
902*61046927SAndroid Build Coastguard Worker    stage_info->stage = stage;
903*61046927SAndroid Build Coastguard Worker    stage_info->module = module;
904*61046927SAndroid Build Coastguard Worker    stage_info->pName = name;
905*61046927SAndroid Build Coastguard Worker    stage_info->pSpecializationInfo = NULL;
906*61046927SAndroid Build Coastguard Worker    owned_stages |= stage;
907*61046927SAndroid Build Coastguard Worker }
908*61046927SAndroid Build Coastguard Worker 
909*61046927SAndroid Build Coastguard Worker void
add_stage(VkShaderStageFlagBits stage,QoShaderModuleCreateInfo module,const char * name)910*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_stage(VkShaderStageFlagBits stage, QoShaderModuleCreateInfo module,
911*61046927SAndroid Build Coastguard Worker                            const char* name)
912*61046927SAndroid Build Coastguard Worker {
913*61046927SAndroid Build Coastguard Worker    add_stage(stage, __qoCreateShaderModule(device, &module), name);
914*61046927SAndroid Build Coastguard Worker    add_resource_decls(&module);
915*61046927SAndroid Build Coastguard Worker    add_io_decls(&module);
916*61046927SAndroid Build Coastguard Worker }
917*61046927SAndroid Build Coastguard Worker 
918*61046927SAndroid Build Coastguard Worker void
add_vsfs(VkShaderModule vs,VkShaderModule fs)919*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_vsfs(VkShaderModule vs, VkShaderModule fs)
920*61046927SAndroid Build Coastguard Worker {
921*61046927SAndroid Build Coastguard Worker    add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs);
922*61046927SAndroid Build Coastguard Worker    add_stage(VK_SHADER_STAGE_FRAGMENT_BIT, fs);
923*61046927SAndroid Build Coastguard Worker }
924*61046927SAndroid Build Coastguard Worker 
925*61046927SAndroid Build Coastguard Worker void
add_vsfs(QoShaderModuleCreateInfo vs,QoShaderModuleCreateInfo fs)926*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_vsfs(QoShaderModuleCreateInfo vs, QoShaderModuleCreateInfo fs)
927*61046927SAndroid Build Coastguard Worker {
928*61046927SAndroid Build Coastguard Worker    add_stage(VK_SHADER_STAGE_VERTEX_BIT, vs);
929*61046927SAndroid Build Coastguard Worker    add_stage(VK_SHADER_STAGE_FRAGMENT_BIT, fs);
930*61046927SAndroid Build Coastguard Worker }
931*61046927SAndroid Build Coastguard Worker 
932*61046927SAndroid Build Coastguard Worker void
add_cs(VkShaderModule cs)933*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_cs(VkShaderModule cs)
934*61046927SAndroid Build Coastguard Worker {
935*61046927SAndroid Build Coastguard Worker    add_stage(VK_SHADER_STAGE_COMPUTE_BIT, cs);
936*61046927SAndroid Build Coastguard Worker }
937*61046927SAndroid Build Coastguard Worker 
938*61046927SAndroid Build Coastguard Worker void
add_cs(QoShaderModuleCreateInfo cs)939*61046927SAndroid Build Coastguard Worker PipelineBuilder::add_cs(QoShaderModuleCreateInfo cs)
940*61046927SAndroid Build Coastguard Worker {
941*61046927SAndroid Build Coastguard Worker    add_stage(VK_SHADER_STAGE_COMPUTE_BIT, cs);
942*61046927SAndroid Build Coastguard Worker }
943*61046927SAndroid Build Coastguard Worker 
944*61046927SAndroid Build Coastguard Worker bool
is_compute()945*61046927SAndroid Build Coastguard Worker PipelineBuilder::is_compute()
946*61046927SAndroid Build Coastguard Worker {
947*61046927SAndroid Build Coastguard Worker    return gfx_pipeline_info.stageCount == 0;
948*61046927SAndroid Build Coastguard Worker }
949*61046927SAndroid Build Coastguard Worker 
950*61046927SAndroid Build Coastguard Worker void
create_compute_pipeline()951*61046927SAndroid Build Coastguard Worker PipelineBuilder::create_compute_pipeline()
952*61046927SAndroid Build Coastguard Worker {
953*61046927SAndroid Build Coastguard Worker    VkComputePipelineCreateInfo create_info;
954*61046927SAndroid Build Coastguard Worker    create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
955*61046927SAndroid Build Coastguard Worker    create_info.pNext = NULL;
956*61046927SAndroid Build Coastguard Worker    create_info.flags = VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
957*61046927SAndroid Build Coastguard Worker    create_info.stage = stages[0];
958*61046927SAndroid Build Coastguard Worker    create_info.layout = pipeline_layout;
959*61046927SAndroid Build Coastguard Worker    create_info.basePipelineHandle = VK_NULL_HANDLE;
960*61046927SAndroid Build Coastguard Worker    create_info.basePipelineIndex = 0;
961*61046927SAndroid Build Coastguard Worker 
962*61046927SAndroid Build Coastguard Worker    ASSERTED VkResult result =
963*61046927SAndroid Build Coastguard Worker       CreateComputePipelines(device, VK_NULL_HANDLE, 1, &create_info, NULL, &pipeline);
964*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
965*61046927SAndroid Build Coastguard Worker }
966*61046927SAndroid Build Coastguard Worker 
967*61046927SAndroid Build Coastguard Worker void
create_graphics_pipeline()968*61046927SAndroid Build Coastguard Worker PipelineBuilder::create_graphics_pipeline()
969*61046927SAndroid Build Coastguard Worker {
970*61046927SAndroid Build Coastguard Worker    /* create the create infos */
971*61046927SAndroid Build Coastguard Worker    if (!samples)
972*61046927SAndroid Build Coastguard Worker       samples = VK_SAMPLE_COUNT_1_BIT;
973*61046927SAndroid Build Coastguard Worker 
974*61046927SAndroid Build Coastguard Worker    unsigned num_color_attachments = 0;
975*61046927SAndroid Build Coastguard Worker    VkPipelineColorBlendAttachmentState blend_attachment_states[16];
976*61046927SAndroid Build Coastguard Worker    VkAttachmentReference color_attachments[16];
977*61046927SAndroid Build Coastguard Worker    VkAttachmentDescription attachment_descs[17];
978*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < 16; i++) {
979*61046927SAndroid Build Coastguard Worker       if (color_outputs[i] == VK_FORMAT_UNDEFINED)
980*61046927SAndroid Build Coastguard Worker          continue;
981*61046927SAndroid Build Coastguard Worker 
982*61046927SAndroid Build Coastguard Worker       VkAttachmentDescription* desc = &attachment_descs[num_color_attachments];
983*61046927SAndroid Build Coastguard Worker       desc->flags = 0;
984*61046927SAndroid Build Coastguard Worker       desc->format = color_outputs[i];
985*61046927SAndroid Build Coastguard Worker       desc->samples = samples;
986*61046927SAndroid Build Coastguard Worker       desc->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
987*61046927SAndroid Build Coastguard Worker       desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
988*61046927SAndroid Build Coastguard Worker       desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
989*61046927SAndroid Build Coastguard Worker       desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
990*61046927SAndroid Build Coastguard Worker       desc->initialLayout = VK_IMAGE_LAYOUT_GENERAL;
991*61046927SAndroid Build Coastguard Worker       desc->finalLayout = VK_IMAGE_LAYOUT_GENERAL;
992*61046927SAndroid Build Coastguard Worker 
993*61046927SAndroid Build Coastguard Worker       VkAttachmentReference* ref = &color_attachments[num_color_attachments];
994*61046927SAndroid Build Coastguard Worker       ref->attachment = num_color_attachments;
995*61046927SAndroid Build Coastguard Worker       ref->layout = VK_IMAGE_LAYOUT_GENERAL;
996*61046927SAndroid Build Coastguard Worker 
997*61046927SAndroid Build Coastguard Worker       VkPipelineColorBlendAttachmentState* blend = &blend_attachment_states[num_color_attachments];
998*61046927SAndroid Build Coastguard Worker       blend->blendEnable = false;
999*61046927SAndroid Build Coastguard Worker       blend->colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
1000*61046927SAndroid Build Coastguard Worker                               VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1001*61046927SAndroid Build Coastguard Worker 
1002*61046927SAndroid Build Coastguard Worker       num_color_attachments++;
1003*61046927SAndroid Build Coastguard Worker    }
1004*61046927SAndroid Build Coastguard Worker 
1005*61046927SAndroid Build Coastguard Worker    unsigned num_attachments = num_color_attachments;
1006*61046927SAndroid Build Coastguard Worker    VkAttachmentReference ds_attachment;
1007*61046927SAndroid Build Coastguard Worker    if (ds_output != VK_FORMAT_UNDEFINED) {
1008*61046927SAndroid Build Coastguard Worker       VkAttachmentDescription* desc = &attachment_descs[num_attachments];
1009*61046927SAndroid Build Coastguard Worker       desc->flags = 0;
1010*61046927SAndroid Build Coastguard Worker       desc->format = ds_output;
1011*61046927SAndroid Build Coastguard Worker       desc->samples = samples;
1012*61046927SAndroid Build Coastguard Worker       desc->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1013*61046927SAndroid Build Coastguard Worker       desc->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
1014*61046927SAndroid Build Coastguard Worker       desc->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
1015*61046927SAndroid Build Coastguard Worker       desc->stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
1016*61046927SAndroid Build Coastguard Worker       desc->initialLayout = VK_IMAGE_LAYOUT_GENERAL;
1017*61046927SAndroid Build Coastguard Worker       desc->finalLayout = VK_IMAGE_LAYOUT_GENERAL;
1018*61046927SAndroid Build Coastguard Worker 
1019*61046927SAndroid Build Coastguard Worker       ds_attachment.attachment = num_color_attachments;
1020*61046927SAndroid Build Coastguard Worker       ds_attachment.layout = VK_IMAGE_LAYOUT_GENERAL;
1021*61046927SAndroid Build Coastguard Worker 
1022*61046927SAndroid Build Coastguard Worker       num_attachments++;
1023*61046927SAndroid Build Coastguard Worker    }
1024*61046927SAndroid Build Coastguard Worker 
1025*61046927SAndroid Build Coastguard Worker    vs_input.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
1026*61046927SAndroid Build Coastguard Worker    vs_input.pNext = NULL;
1027*61046927SAndroid Build Coastguard Worker    vs_input.flags = 0;
1028*61046927SAndroid Build Coastguard Worker    vs_input.pVertexBindingDescriptions = vs_bindings;
1029*61046927SAndroid Build Coastguard Worker    vs_input.pVertexAttributeDescriptions = vs_attributes;
1030*61046927SAndroid Build Coastguard Worker 
1031*61046927SAndroid Build Coastguard Worker    VkPipelineInputAssemblyStateCreateInfo assembly_state;
1032*61046927SAndroid Build Coastguard Worker    assembly_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
1033*61046927SAndroid Build Coastguard Worker    assembly_state.pNext = NULL;
1034*61046927SAndroid Build Coastguard Worker    assembly_state.flags = 0;
1035*61046927SAndroid Build Coastguard Worker    assembly_state.topology = topology;
1036*61046927SAndroid Build Coastguard Worker    assembly_state.primitiveRestartEnable = false;
1037*61046927SAndroid Build Coastguard Worker 
1038*61046927SAndroid Build Coastguard Worker    VkPipelineTessellationStateCreateInfo tess_state;
1039*61046927SAndroid Build Coastguard Worker    tess_state.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
1040*61046927SAndroid Build Coastguard Worker    tess_state.pNext = NULL;
1041*61046927SAndroid Build Coastguard Worker    tess_state.flags = 0;
1042*61046927SAndroid Build Coastguard Worker    tess_state.patchControlPoints = patch_size;
1043*61046927SAndroid Build Coastguard Worker 
1044*61046927SAndroid Build Coastguard Worker    VkPipelineViewportStateCreateInfo viewport_state;
1045*61046927SAndroid Build Coastguard Worker    viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
1046*61046927SAndroid Build Coastguard Worker    viewport_state.pNext = NULL;
1047*61046927SAndroid Build Coastguard Worker    viewport_state.flags = 0;
1048*61046927SAndroid Build Coastguard Worker    viewport_state.viewportCount = 1;
1049*61046927SAndroid Build Coastguard Worker    viewport_state.pViewports = NULL;
1050*61046927SAndroid Build Coastguard Worker    viewport_state.scissorCount = 1;
1051*61046927SAndroid Build Coastguard Worker    viewport_state.pScissors = NULL;
1052*61046927SAndroid Build Coastguard Worker 
1053*61046927SAndroid Build Coastguard Worker    VkPipelineRasterizationStateCreateInfo rasterization_state;
1054*61046927SAndroid Build Coastguard Worker    rasterization_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
1055*61046927SAndroid Build Coastguard Worker    rasterization_state.pNext = NULL;
1056*61046927SAndroid Build Coastguard Worker    rasterization_state.flags = 0;
1057*61046927SAndroid Build Coastguard Worker    rasterization_state.depthClampEnable = false;
1058*61046927SAndroid Build Coastguard Worker    rasterization_state.rasterizerDiscardEnable = false;
1059*61046927SAndroid Build Coastguard Worker    rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
1060*61046927SAndroid Build Coastguard Worker    rasterization_state.cullMode = VK_CULL_MODE_NONE;
1061*61046927SAndroid Build Coastguard Worker    rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
1062*61046927SAndroid Build Coastguard Worker    rasterization_state.depthBiasEnable = false;
1063*61046927SAndroid Build Coastguard Worker    rasterization_state.lineWidth = 1.0;
1064*61046927SAndroid Build Coastguard Worker 
1065*61046927SAndroid Build Coastguard Worker    VkPipelineMultisampleStateCreateInfo ms_state;
1066*61046927SAndroid Build Coastguard Worker    ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
1067*61046927SAndroid Build Coastguard Worker    ms_state.pNext = NULL;
1068*61046927SAndroid Build Coastguard Worker    ms_state.flags = 0;
1069*61046927SAndroid Build Coastguard Worker    ms_state.rasterizationSamples = samples;
1070*61046927SAndroid Build Coastguard Worker    ms_state.sampleShadingEnable = sample_shading_enable;
1071*61046927SAndroid Build Coastguard Worker    ms_state.minSampleShading = min_sample_shading;
1072*61046927SAndroid Build Coastguard Worker    VkSampleMask sample_mask = 0xffffffff;
1073*61046927SAndroid Build Coastguard Worker    ms_state.pSampleMask = &sample_mask;
1074*61046927SAndroid Build Coastguard Worker    ms_state.alphaToCoverageEnable = false;
1075*61046927SAndroid Build Coastguard Worker    ms_state.alphaToOneEnable = false;
1076*61046927SAndroid Build Coastguard Worker 
1077*61046927SAndroid Build Coastguard Worker    VkPipelineDepthStencilStateCreateInfo ds_state;
1078*61046927SAndroid Build Coastguard Worker    ds_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
1079*61046927SAndroid Build Coastguard Worker    ds_state.pNext = NULL;
1080*61046927SAndroid Build Coastguard Worker    ds_state.flags = 0;
1081*61046927SAndroid Build Coastguard Worker    ds_state.depthTestEnable = ds_output != VK_FORMAT_UNDEFINED;
1082*61046927SAndroid Build Coastguard Worker    ds_state.depthWriteEnable = true;
1083*61046927SAndroid Build Coastguard Worker    ds_state.depthCompareOp = VK_COMPARE_OP_ALWAYS;
1084*61046927SAndroid Build Coastguard Worker    ds_state.depthBoundsTestEnable = false;
1085*61046927SAndroid Build Coastguard Worker    ds_state.stencilTestEnable = true;
1086*61046927SAndroid Build Coastguard Worker    ds_state.front.failOp = VK_STENCIL_OP_KEEP;
1087*61046927SAndroid Build Coastguard Worker    ds_state.front.passOp = VK_STENCIL_OP_REPLACE;
1088*61046927SAndroid Build Coastguard Worker    ds_state.front.depthFailOp = VK_STENCIL_OP_REPLACE;
1089*61046927SAndroid Build Coastguard Worker    ds_state.front.compareOp = VK_COMPARE_OP_ALWAYS;
1090*61046927SAndroid Build Coastguard Worker    ds_state.front.compareMask = 0xffffffff, ds_state.front.writeMask = 0;
1091*61046927SAndroid Build Coastguard Worker    ds_state.front.reference = 0;
1092*61046927SAndroid Build Coastguard Worker    ds_state.back = ds_state.front;
1093*61046927SAndroid Build Coastguard Worker 
1094*61046927SAndroid Build Coastguard Worker    VkPipelineColorBlendStateCreateInfo color_blend_state;
1095*61046927SAndroid Build Coastguard Worker    color_blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
1096*61046927SAndroid Build Coastguard Worker    color_blend_state.pNext = NULL;
1097*61046927SAndroid Build Coastguard Worker    color_blend_state.flags = 0;
1098*61046927SAndroid Build Coastguard Worker    color_blend_state.logicOpEnable = false;
1099*61046927SAndroid Build Coastguard Worker    color_blend_state.attachmentCount = num_color_attachments;
1100*61046927SAndroid Build Coastguard Worker    color_blend_state.pAttachments = blend_attachment_states;
1101*61046927SAndroid Build Coastguard Worker 
1102*61046927SAndroid Build Coastguard Worker    VkDynamicState dynamic_states[9] = {VK_DYNAMIC_STATE_VIEWPORT,
1103*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_SCISSOR,
1104*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_LINE_WIDTH,
1105*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_DEPTH_BIAS,
1106*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_BLEND_CONSTANTS,
1107*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_DEPTH_BOUNDS,
1108*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
1109*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
1110*61046927SAndroid Build Coastguard Worker                                        VK_DYNAMIC_STATE_STENCIL_REFERENCE};
1111*61046927SAndroid Build Coastguard Worker 
1112*61046927SAndroid Build Coastguard Worker    VkPipelineDynamicStateCreateInfo dynamic_state;
1113*61046927SAndroid Build Coastguard Worker    dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
1114*61046927SAndroid Build Coastguard Worker    dynamic_state.pNext = NULL;
1115*61046927SAndroid Build Coastguard Worker    dynamic_state.flags = 0;
1116*61046927SAndroid Build Coastguard Worker    dynamic_state.dynamicStateCount = sizeof(dynamic_states) / sizeof(VkDynamicState);
1117*61046927SAndroid Build Coastguard Worker    dynamic_state.pDynamicStates = dynamic_states;
1118*61046927SAndroid Build Coastguard Worker 
1119*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
1120*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pNext = NULL;
1121*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.flags = VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
1122*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pVertexInputState = &vs_input;
1123*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pInputAssemblyState = &assembly_state;
1124*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pTessellationState = &tess_state;
1125*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pViewportState = &viewport_state;
1126*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pRasterizationState = &rasterization_state;
1127*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pMultisampleState = &ms_state;
1128*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pDepthStencilState = &ds_state;
1129*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pColorBlendState = &color_blend_state;
1130*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pDynamicState = &dynamic_state;
1131*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.subpass = 0;
1132*61046927SAndroid Build Coastguard Worker 
1133*61046927SAndroid Build Coastguard Worker    /* create the objects used to create the pipeline */
1134*61046927SAndroid Build Coastguard Worker    VkSubpassDescription subpass;
1135*61046927SAndroid Build Coastguard Worker    subpass.flags = 0;
1136*61046927SAndroid Build Coastguard Worker    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
1137*61046927SAndroid Build Coastguard Worker    subpass.inputAttachmentCount = 0;
1138*61046927SAndroid Build Coastguard Worker    subpass.pInputAttachments = NULL;
1139*61046927SAndroid Build Coastguard Worker    subpass.colorAttachmentCount = num_color_attachments;
1140*61046927SAndroid Build Coastguard Worker    subpass.pColorAttachments = color_attachments;
1141*61046927SAndroid Build Coastguard Worker    subpass.pResolveAttachments = NULL;
1142*61046927SAndroid Build Coastguard Worker    subpass.pDepthStencilAttachment = ds_output == VK_FORMAT_UNDEFINED ? NULL : &ds_attachment;
1143*61046927SAndroid Build Coastguard Worker    subpass.preserveAttachmentCount = 0;
1144*61046927SAndroid Build Coastguard Worker    subpass.pPreserveAttachments = NULL;
1145*61046927SAndroid Build Coastguard Worker 
1146*61046927SAndroid Build Coastguard Worker    VkRenderPassCreateInfo renderpass_info;
1147*61046927SAndroid Build Coastguard Worker    renderpass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
1148*61046927SAndroid Build Coastguard Worker    renderpass_info.pNext = NULL;
1149*61046927SAndroid Build Coastguard Worker    renderpass_info.flags = 0;
1150*61046927SAndroid Build Coastguard Worker    renderpass_info.attachmentCount = num_attachments;
1151*61046927SAndroid Build Coastguard Worker    renderpass_info.pAttachments = attachment_descs;
1152*61046927SAndroid Build Coastguard Worker    renderpass_info.subpassCount = 1;
1153*61046927SAndroid Build Coastguard Worker    renderpass_info.pSubpasses = &subpass;
1154*61046927SAndroid Build Coastguard Worker    renderpass_info.dependencyCount = 0;
1155*61046927SAndroid Build Coastguard Worker    renderpass_info.pDependencies = NULL;
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker    ASSERTED VkResult result = CreateRenderPass(device, &renderpass_info, NULL, &render_pass);
1158*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
1159*61046927SAndroid Build Coastguard Worker 
1160*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.layout = pipeline_layout;
1161*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.renderPass = render_pass;
1162*61046927SAndroid Build Coastguard Worker 
1163*61046927SAndroid Build Coastguard Worker    /* create the pipeline */
1164*61046927SAndroid Build Coastguard Worker    gfx_pipeline_info.pStages = stages;
1165*61046927SAndroid Build Coastguard Worker 
1166*61046927SAndroid Build Coastguard Worker    result = CreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &gfx_pipeline_info, NULL, &pipeline);
1167*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
1168*61046927SAndroid Build Coastguard Worker }
1169*61046927SAndroid Build Coastguard Worker 
1170*61046927SAndroid Build Coastguard Worker void
create_pipeline()1171*61046927SAndroid Build Coastguard Worker PipelineBuilder::create_pipeline()
1172*61046927SAndroid Build Coastguard Worker {
1173*61046927SAndroid Build Coastguard Worker    unsigned num_desc_layouts = 0;
1174*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < 64; i++) {
1175*61046927SAndroid Build Coastguard Worker       if (!(desc_layouts_used & (1ull << i)))
1176*61046927SAndroid Build Coastguard Worker          continue;
1177*61046927SAndroid Build Coastguard Worker 
1178*61046927SAndroid Build Coastguard Worker       VkDescriptorSetLayoutCreateInfo desc_layout_info;
1179*61046927SAndroid Build Coastguard Worker       desc_layout_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1180*61046927SAndroid Build Coastguard Worker       desc_layout_info.pNext = NULL;
1181*61046927SAndroid Build Coastguard Worker       desc_layout_info.flags = 0;
1182*61046927SAndroid Build Coastguard Worker       desc_layout_info.bindingCount = num_desc_bindings[i];
1183*61046927SAndroid Build Coastguard Worker       desc_layout_info.pBindings = desc_bindings[i];
1184*61046927SAndroid Build Coastguard Worker 
1185*61046927SAndroid Build Coastguard Worker       ASSERTED VkResult result = CreateDescriptorSetLayout(device, &desc_layout_info, NULL,
1186*61046927SAndroid Build Coastguard Worker                                                            &desc_layouts[num_desc_layouts]);
1187*61046927SAndroid Build Coastguard Worker       assert(result == VK_SUCCESS);
1188*61046927SAndroid Build Coastguard Worker       num_desc_layouts++;
1189*61046927SAndroid Build Coastguard Worker    }
1190*61046927SAndroid Build Coastguard Worker 
1191*61046927SAndroid Build Coastguard Worker    VkPipelineLayoutCreateInfo pipeline_layout_info;
1192*61046927SAndroid Build Coastguard Worker    pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1193*61046927SAndroid Build Coastguard Worker    pipeline_layout_info.pNext = NULL;
1194*61046927SAndroid Build Coastguard Worker    pipeline_layout_info.flags = 0;
1195*61046927SAndroid Build Coastguard Worker    pipeline_layout_info.pushConstantRangeCount = 1;
1196*61046927SAndroid Build Coastguard Worker    pipeline_layout_info.pPushConstantRanges = &push_constant_range;
1197*61046927SAndroid Build Coastguard Worker    pipeline_layout_info.setLayoutCount = num_desc_layouts;
1198*61046927SAndroid Build Coastguard Worker    pipeline_layout_info.pSetLayouts = desc_layouts;
1199*61046927SAndroid Build Coastguard Worker 
1200*61046927SAndroid Build Coastguard Worker    ASSERTED VkResult result =
1201*61046927SAndroid Build Coastguard Worker       CreatePipelineLayout(device, &pipeline_layout_info, NULL, &pipeline_layout);
1202*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
1203*61046927SAndroid Build Coastguard Worker 
1204*61046927SAndroid Build Coastguard Worker    if (is_compute())
1205*61046927SAndroid Build Coastguard Worker       create_compute_pipeline();
1206*61046927SAndroid Build Coastguard Worker    else
1207*61046927SAndroid Build Coastguard Worker       create_graphics_pipeline();
1208*61046927SAndroid Build Coastguard Worker }
1209*61046927SAndroid Build Coastguard Worker 
1210*61046927SAndroid Build Coastguard Worker void
print_ir(VkShaderStageFlagBits stage_flags,const char * name,bool remove_encoding)1211*61046927SAndroid Build Coastguard Worker PipelineBuilder::print_ir(VkShaderStageFlagBits stage_flags, const char* name, bool remove_encoding)
1212*61046927SAndroid Build Coastguard Worker {
1213*61046927SAndroid Build Coastguard Worker    if (!pipeline)
1214*61046927SAndroid Build Coastguard Worker       create_pipeline();
1215*61046927SAndroid Build Coastguard Worker    print_pipeline_ir(device, pipeline, stage_flags, name, remove_encoding);
1216*61046927SAndroid Build Coastguard Worker }
1217