1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2019 Raspberry Pi Ltd
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker #include "v3dv_debug.h"
27*61046927SAndroid Build Coastguard Worker #include "v3dv_private.h"
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker #include "common/v3d_debug.h"
30*61046927SAndroid Build Coastguard Worker #include "qpu/qpu_disasm.h"
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker #include "compiler/nir/nir_builder.h"
33*61046927SAndroid Build Coastguard Worker #include "nir/nir_serialize.h"
34*61046927SAndroid Build Coastguard Worker
35*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
36*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
37*61046927SAndroid Build Coastguard Worker
38*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
39*61046927SAndroid Build Coastguard Worker #include "vk_nir_convert_ycbcr.h"
40*61046927SAndroid Build Coastguard Worker #include "vk_pipeline.h"
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker static VkResult
43*61046927SAndroid Build Coastguard Worker compute_vpm_config(struct v3dv_pipeline *pipeline);
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker void
v3dv_print_v3d_key(struct v3d_key * key,uint32_t v3d_key_size)46*61046927SAndroid Build Coastguard Worker v3dv_print_v3d_key(struct v3d_key *key,
47*61046927SAndroid Build Coastguard Worker uint32_t v3d_key_size)
48*61046927SAndroid Build Coastguard Worker {
49*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
50*61046927SAndroid Build Coastguard Worker unsigned char sha1[20];
51*61046927SAndroid Build Coastguard Worker char sha1buf[41];
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
54*61046927SAndroid Build Coastguard Worker
55*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, key, v3d_key_size);
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, sha1);
58*61046927SAndroid Build Coastguard Worker _mesa_sha1_format(sha1buf, sha1);
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker fprintf(stderr, "key %p: %s\n", key, sha1buf);
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker static void
pipeline_compute_sha1_from_nir(struct v3dv_pipeline_stage * p_stage)64*61046927SAndroid Build Coastguard Worker pipeline_compute_sha1_from_nir(struct v3dv_pipeline_stage *p_stage)
65*61046927SAndroid Build Coastguard Worker {
66*61046927SAndroid Build Coastguard Worker VkPipelineShaderStageCreateInfo info = {
67*61046927SAndroid Build Coastguard Worker .module = vk_shader_module_handle_from_nir(p_stage->nir),
68*61046927SAndroid Build Coastguard Worker .pName = p_stage->entrypoint,
69*61046927SAndroid Build Coastguard Worker .stage = mesa_to_vk_shader_stage(p_stage->nir->info.stage),
70*61046927SAndroid Build Coastguard Worker };
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker vk_pipeline_hash_shader_stage(0, &info, NULL, p_stage->shader_sha1);
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker
75*61046927SAndroid Build Coastguard Worker void
v3dv_shader_variant_destroy(struct v3dv_device * device,struct v3dv_shader_variant * variant)76*61046927SAndroid Build Coastguard Worker v3dv_shader_variant_destroy(struct v3dv_device *device,
77*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant)
78*61046927SAndroid Build Coastguard Worker {
79*61046927SAndroid Build Coastguard Worker /* The assembly BO is shared by all variants in the pipeline, so it can't
80*61046927SAndroid Build Coastguard Worker * be freed here and should be freed with the pipeline
81*61046927SAndroid Build Coastguard Worker */
82*61046927SAndroid Build Coastguard Worker if (variant->qpu_insts) {
83*61046927SAndroid Build Coastguard Worker free(variant->qpu_insts);
84*61046927SAndroid Build Coastguard Worker variant->qpu_insts = NULL;
85*61046927SAndroid Build Coastguard Worker }
86*61046927SAndroid Build Coastguard Worker ralloc_free(variant->prog_data.base);
87*61046927SAndroid Build Coastguard Worker vk_free(&device->vk.alloc, variant);
88*61046927SAndroid Build Coastguard Worker }
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker static void
destroy_pipeline_stage(struct v3dv_device * device,struct v3dv_pipeline_stage * p_stage,const VkAllocationCallbacks * pAllocator)91*61046927SAndroid Build Coastguard Worker destroy_pipeline_stage(struct v3dv_device *device,
92*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage,
93*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
94*61046927SAndroid Build Coastguard Worker {
95*61046927SAndroid Build Coastguard Worker if (!p_stage)
96*61046927SAndroid Build Coastguard Worker return;
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker ralloc_free(p_stage->nir);
99*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, p_stage);
100*61046927SAndroid Build Coastguard Worker }
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker static void
pipeline_free_stages(struct v3dv_device * device,struct v3dv_pipeline * pipeline,const VkAllocationCallbacks * pAllocator)103*61046927SAndroid Build Coastguard Worker pipeline_free_stages(struct v3dv_device *device,
104*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline,
105*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
106*61046927SAndroid Build Coastguard Worker {
107*61046927SAndroid Build Coastguard Worker assert(pipeline);
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
110*61046927SAndroid Build Coastguard Worker destroy_pipeline_stage(device, pipeline->stages[stage], pAllocator);
111*61046927SAndroid Build Coastguard Worker pipeline->stages[stage] = NULL;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker }
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker static void
v3dv_destroy_pipeline(struct v3dv_pipeline * pipeline,struct v3dv_device * device,const VkAllocationCallbacks * pAllocator)116*61046927SAndroid Build Coastguard Worker v3dv_destroy_pipeline(struct v3dv_pipeline *pipeline,
117*61046927SAndroid Build Coastguard Worker struct v3dv_device *device,
118*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
119*61046927SAndroid Build Coastguard Worker {
120*61046927SAndroid Build Coastguard Worker if (!pipeline)
121*61046927SAndroid Build Coastguard Worker return;
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker pipeline_free_stages(device, pipeline, pAllocator);
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker if (pipeline->shared_data) {
126*61046927SAndroid Build Coastguard Worker v3dv_pipeline_shared_data_unref(device, pipeline->shared_data);
127*61046927SAndroid Build Coastguard Worker pipeline->shared_data = NULL;
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker if (pipeline->spill.bo) {
131*61046927SAndroid Build Coastguard Worker assert(pipeline->spill.size_per_thread > 0);
132*61046927SAndroid Build Coastguard Worker v3dv_bo_free(device, pipeline->spill.bo);
133*61046927SAndroid Build Coastguard Worker }
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker if (pipeline->default_attribute_values) {
136*61046927SAndroid Build Coastguard Worker v3dv_bo_free(device, pipeline->default_attribute_values);
137*61046927SAndroid Build Coastguard Worker pipeline->default_attribute_values = NULL;
138*61046927SAndroid Build Coastguard Worker }
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker if (pipeline->executables.mem_ctx)
141*61046927SAndroid Build Coastguard Worker ralloc_free(pipeline->executables.mem_ctx);
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker if (pipeline->layout)
144*61046927SAndroid Build Coastguard Worker v3dv_pipeline_layout_unref(device, pipeline->layout, pAllocator);
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker vk_object_free(&device->vk, pAllocator, pipeline);
147*61046927SAndroid Build Coastguard Worker }
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
v3dv_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)150*61046927SAndroid Build Coastguard Worker v3dv_DestroyPipeline(VkDevice _device,
151*61046927SAndroid Build Coastguard Worker VkPipeline _pipeline,
152*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
153*61046927SAndroid Build Coastguard Worker {
154*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_device, device, _device);
155*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline, pipeline, _pipeline);
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker if (!pipeline)
158*61046927SAndroid Build Coastguard Worker return;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker v3dv_destroy_pipeline(pipeline, device, pAllocator);
161*61046927SAndroid Build Coastguard Worker }
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker static const struct spirv_to_nir_options default_spirv_options = {
164*61046927SAndroid Build Coastguard Worker .ubo_addr_format = nir_address_format_32bit_index_offset,
165*61046927SAndroid Build Coastguard Worker .ssbo_addr_format = nir_address_format_32bit_index_offset,
166*61046927SAndroid Build Coastguard Worker .phys_ssbo_addr_format = nir_address_format_2x32bit_global,
167*61046927SAndroid Build Coastguard Worker .push_const_addr_format = nir_address_format_logical,
168*61046927SAndroid Build Coastguard Worker .shared_addr_format = nir_address_format_32bit_offset,
169*61046927SAndroid Build Coastguard Worker };
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *
v3dv_pipeline_get_nir_options(const struct v3d_device_info * devinfo)172*61046927SAndroid Build Coastguard Worker v3dv_pipeline_get_nir_options(const struct v3d_device_info *devinfo)
173*61046927SAndroid Build Coastguard Worker {
174*61046927SAndroid Build Coastguard Worker static bool initialized = false;
175*61046927SAndroid Build Coastguard Worker static nir_shader_compiler_options options = {
176*61046927SAndroid Build Coastguard Worker .lower_uadd_sat = true,
177*61046927SAndroid Build Coastguard Worker .lower_usub_sat = true,
178*61046927SAndroid Build Coastguard Worker .lower_iadd_sat = true,
179*61046927SAndroid Build Coastguard Worker .lower_all_io_to_temps = true,
180*61046927SAndroid Build Coastguard Worker .lower_extract_byte = true,
181*61046927SAndroid Build Coastguard Worker .lower_extract_word = true,
182*61046927SAndroid Build Coastguard Worker .lower_insert_byte = true,
183*61046927SAndroid Build Coastguard Worker .lower_insert_word = true,
184*61046927SAndroid Build Coastguard Worker .lower_bitfield_insert = true,
185*61046927SAndroid Build Coastguard Worker .lower_bitfield_extract = true,
186*61046927SAndroid Build Coastguard Worker .lower_bitfield_reverse = true,
187*61046927SAndroid Build Coastguard Worker .lower_bit_count = true,
188*61046927SAndroid Build Coastguard Worker .lower_cs_local_id_to_index = true,
189*61046927SAndroid Build Coastguard Worker .lower_ffract = true,
190*61046927SAndroid Build Coastguard Worker .lower_fmod = true,
191*61046927SAndroid Build Coastguard Worker .lower_pack_unorm_2x16 = true,
192*61046927SAndroid Build Coastguard Worker .lower_pack_snorm_2x16 = true,
193*61046927SAndroid Build Coastguard Worker .lower_unpack_unorm_2x16 = true,
194*61046927SAndroid Build Coastguard Worker .lower_unpack_snorm_2x16 = true,
195*61046927SAndroid Build Coastguard Worker .lower_pack_unorm_4x8 = true,
196*61046927SAndroid Build Coastguard Worker .lower_pack_snorm_4x8 = true,
197*61046927SAndroid Build Coastguard Worker .lower_unpack_unorm_4x8 = true,
198*61046927SAndroid Build Coastguard Worker .lower_unpack_snorm_4x8 = true,
199*61046927SAndroid Build Coastguard Worker .lower_pack_half_2x16 = true,
200*61046927SAndroid Build Coastguard Worker .lower_unpack_half_2x16 = true,
201*61046927SAndroid Build Coastguard Worker .lower_pack_32_2x16 = true,
202*61046927SAndroid Build Coastguard Worker .lower_pack_32_2x16_split = true,
203*61046927SAndroid Build Coastguard Worker .lower_unpack_32_2x16_split = true,
204*61046927SAndroid Build Coastguard Worker .lower_mul_2x32_64 = true,
205*61046927SAndroid Build Coastguard Worker .lower_fdiv = true,
206*61046927SAndroid Build Coastguard Worker .lower_find_lsb = true,
207*61046927SAndroid Build Coastguard Worker .lower_ffma16 = true,
208*61046927SAndroid Build Coastguard Worker .lower_ffma32 = true,
209*61046927SAndroid Build Coastguard Worker .lower_ffma64 = true,
210*61046927SAndroid Build Coastguard Worker .lower_flrp32 = true,
211*61046927SAndroid Build Coastguard Worker .lower_fpow = true,
212*61046927SAndroid Build Coastguard Worker .lower_fsqrt = true,
213*61046927SAndroid Build Coastguard Worker .lower_ifind_msb = true,
214*61046927SAndroid Build Coastguard Worker .lower_isign = true,
215*61046927SAndroid Build Coastguard Worker .lower_ldexp = true,
216*61046927SAndroid Build Coastguard Worker .lower_mul_high = true,
217*61046927SAndroid Build Coastguard Worker .lower_wpos_pntc = false,
218*61046927SAndroid Build Coastguard Worker .lower_to_scalar = true,
219*61046927SAndroid Build Coastguard Worker .lower_device_index_to_zero = true,
220*61046927SAndroid Build Coastguard Worker .lower_fquantize2f16 = true,
221*61046927SAndroid Build Coastguard Worker .lower_ufind_msb = true,
222*61046927SAndroid Build Coastguard Worker .has_fsub = true,
223*61046927SAndroid Build Coastguard Worker .has_isub = true,
224*61046927SAndroid Build Coastguard Worker .has_uclz = true,
225*61046927SAndroid Build Coastguard Worker .vertex_id_zero_based = false, /* FIXME: to set this to true, the intrinsic
226*61046927SAndroid Build Coastguard Worker * needs to be supported */
227*61046927SAndroid Build Coastguard Worker .lower_interpolate_at = true,
228*61046927SAndroid Build Coastguard Worker .max_unroll_iterations = 16,
229*61046927SAndroid Build Coastguard Worker .force_indirect_unrolling = (nir_var_shader_in | nir_var_function_temp),
230*61046927SAndroid Build Coastguard Worker .divergence_analysis_options =
231*61046927SAndroid Build Coastguard Worker nir_divergence_multiple_workgroup_per_compute_subgroup,
232*61046927SAndroid Build Coastguard Worker .discard_is_demote = true,
233*61046927SAndroid Build Coastguard Worker .has_ddx_intrinsics = true,
234*61046927SAndroid Build Coastguard Worker .scalarize_ddx = true,
235*61046927SAndroid Build Coastguard Worker };
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker if (!initialized) {
238*61046927SAndroid Build Coastguard Worker options.lower_fsat = devinfo->ver < 71;
239*61046927SAndroid Build Coastguard Worker initialized = true;
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker return &options;
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker
245*61046927SAndroid Build Coastguard Worker static const struct vk_ycbcr_conversion_state *
lookup_ycbcr_conversion(const void * _pipeline_layout,uint32_t set,uint32_t binding,uint32_t array_index)246*61046927SAndroid Build Coastguard Worker lookup_ycbcr_conversion(const void *_pipeline_layout, uint32_t set,
247*61046927SAndroid Build Coastguard Worker uint32_t binding, uint32_t array_index)
248*61046927SAndroid Build Coastguard Worker {
249*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_layout *pipeline_layout =
250*61046927SAndroid Build Coastguard Worker (struct v3dv_pipeline_layout *) _pipeline_layout;
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker assert(set < pipeline_layout->num_sets);
253*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_layout *set_layout =
254*61046927SAndroid Build Coastguard Worker pipeline_layout->set[set].layout;
255*61046927SAndroid Build Coastguard Worker
256*61046927SAndroid Build Coastguard Worker assert(binding < set_layout->binding_count);
257*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_binding_layout *bind_layout =
258*61046927SAndroid Build Coastguard Worker &set_layout->binding[binding];
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker if (bind_layout->immutable_samplers_offset) {
261*61046927SAndroid Build Coastguard Worker const struct v3dv_sampler *immutable_samplers =
262*61046927SAndroid Build Coastguard Worker v3dv_immutable_samplers(set_layout, bind_layout);
263*61046927SAndroid Build Coastguard Worker const struct v3dv_sampler *sampler = &immutable_samplers[array_index];
264*61046927SAndroid Build Coastguard Worker return sampler->conversion ? &sampler->conversion->state : NULL;
265*61046927SAndroid Build Coastguard Worker } else {
266*61046927SAndroid Build Coastguard Worker return NULL;
267*61046927SAndroid Build Coastguard Worker }
268*61046927SAndroid Build Coastguard Worker }
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker static void
preprocess_nir(nir_shader * nir)271*61046927SAndroid Build Coastguard Worker preprocess_nir(nir_shader *nir)
272*61046927SAndroid Build Coastguard Worker {
273*61046927SAndroid Build Coastguard Worker const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = {
274*61046927SAndroid Build Coastguard Worker .frag_coord = true,
275*61046927SAndroid Build Coastguard Worker .point_coord = true,
276*61046927SAndroid Build Coastguard Worker };
277*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker /* Vulkan uses the separate-shader linking model */
280*61046927SAndroid Build Coastguard Worker nir->info.separate_shader = true;
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker /* Make sure we lower variable initializers on output variables so that
283*61046927SAndroid Build Coastguard Worker * nir_remove_dead_variables below sees the corresponding stores
284*61046927SAndroid Build Coastguard Worker */
285*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_variable_initializers, nir_var_shader_out);
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker if (nir->info.stage == MESA_SHADER_FRAGMENT)
288*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_io_to_vector, nir_var_shader_out);
289*61046927SAndroid Build Coastguard Worker if (nir->info.stage == MESA_SHADER_FRAGMENT) {
290*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_input_attachments,
291*61046927SAndroid Build Coastguard Worker &(nir_input_attachment_options) {
292*61046927SAndroid Build Coastguard Worker .use_fragcoord_sysval = false,
293*61046927SAndroid Build Coastguard Worker });
294*61046927SAndroid Build Coastguard Worker }
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_io_to_temporaries,
297*61046927SAndroid Build Coastguard Worker nir_shader_get_entrypoint(nir), true, false);
298*61046927SAndroid Build Coastguard Worker
299*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_system_values);
300*61046927SAndroid Build Coastguard Worker
301*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_alu_to_scalar, NULL, NULL);
302*61046927SAndroid Build Coastguard Worker
303*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_normalize_cubemap_coords);
304*61046927SAndroid Build Coastguard Worker
305*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_global_vars_to_local);
306*61046927SAndroid Build Coastguard Worker
307*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_split_var_copies);
308*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_split_struct_vars, nir_var_function_temp);
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, nir);
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io,
313*61046927SAndroid Build Coastguard Worker nir_var_mem_push_const,
314*61046927SAndroid Build Coastguard Worker nir_address_format_32bit_offset);
315*61046927SAndroid Build Coastguard Worker
316*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io,
317*61046927SAndroid Build Coastguard Worker nir_var_mem_ubo | nir_var_mem_ssbo,
318*61046927SAndroid Build Coastguard Worker nir_address_format_32bit_index_offset);
319*61046927SAndroid Build Coastguard Worker
320*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io,
321*61046927SAndroid Build Coastguard Worker nir_var_mem_global,
322*61046927SAndroid Build Coastguard Worker nir_address_format_2x32bit_global);
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_load_const_to_scalar);
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker /* Lower a bunch of stuff */
327*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_var_copies);
328*61046927SAndroid Build Coastguard Worker
329*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_indirect_derefs, nir_var_shader_in, UINT32_MAX);
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_indirect_derefs,
332*61046927SAndroid Build Coastguard Worker nir_var_function_temp, 2);
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_array_deref_of_vec,
335*61046927SAndroid Build Coastguard Worker nir_var_mem_ubo | nir_var_mem_ssbo, NULL,
336*61046927SAndroid Build Coastguard Worker nir_lower_direct_array_deref_of_vec_load);
337*61046927SAndroid Build Coastguard Worker
338*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_frexp);
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker /* Get rid of split copies */
341*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, nir);
342*61046927SAndroid Build Coastguard Worker }
343*61046927SAndroid Build Coastguard Worker
344*61046927SAndroid Build Coastguard Worker static nir_shader *
shader_module_compile_to_nir(struct v3dv_device * device,struct v3dv_pipeline_stage * stage)345*61046927SAndroid Build Coastguard Worker shader_module_compile_to_nir(struct v3dv_device *device,
346*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *stage)
347*61046927SAndroid Build Coastguard Worker {
348*61046927SAndroid Build Coastguard Worker assert(stage->module || stage->module_info);
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker nir_shader *nir;
351*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *nir_options =
352*61046927SAndroid Build Coastguard Worker v3dv_pipeline_get_nir_options(&device->devinfo);
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker gl_shader_stage gl_stage = broadcom_shader_stage_to_gl(stage->stage);
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo stage_info = {
357*61046927SAndroid Build Coastguard Worker .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
358*61046927SAndroid Build Coastguard Worker .pNext = !stage->module ? stage->module_info : NULL,
359*61046927SAndroid Build Coastguard Worker .stage = mesa_to_vk_shader_stage(gl_stage),
360*61046927SAndroid Build Coastguard Worker .module = vk_shader_module_to_handle((struct vk_shader_module *)stage->module),
361*61046927SAndroid Build Coastguard Worker .pName = stage->entrypoint,
362*61046927SAndroid Build Coastguard Worker .pSpecializationInfo = stage->spec_info,
363*61046927SAndroid Build Coastguard Worker };
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker /* vk_pipeline_shader_stage_to_nir also handles internal shaders when
366*61046927SAndroid Build Coastguard Worker * module->nir != NULL. It also calls nir_validate_shader on both cases
367*61046927SAndroid Build Coastguard Worker * so we don't have to call it here.
368*61046927SAndroid Build Coastguard Worker */
369*61046927SAndroid Build Coastguard Worker VkResult result = vk_pipeline_shader_stage_to_nir(&device->vk,
370*61046927SAndroid Build Coastguard Worker stage->pipeline->flags,
371*61046927SAndroid Build Coastguard Worker &stage_info,
372*61046927SAndroid Build Coastguard Worker &default_spirv_options,
373*61046927SAndroid Build Coastguard Worker nir_options,
374*61046927SAndroid Build Coastguard Worker NULL, &nir);
375*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
376*61046927SAndroid Build Coastguard Worker return NULL;
377*61046927SAndroid Build Coastguard Worker assert(nir->info.stage == gl_stage);
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker if (V3D_DBG(SHADERDB) && (!stage->module || stage->module->nir == NULL)) {
380*61046927SAndroid Build Coastguard Worker char sha1buf[41];
381*61046927SAndroid Build Coastguard Worker _mesa_sha1_format(sha1buf, stage->pipeline->sha1);
382*61046927SAndroid Build Coastguard Worker nir->info.name = ralloc_strdup(nir, sha1buf);
383*61046927SAndroid Build Coastguard Worker }
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker if (V3D_DBG(NIR) || v3d_debug_flag_for_shader_stage(gl_stage)) {
386*61046927SAndroid Build Coastguard Worker fprintf(stderr, "NIR after vk_pipeline_shader_stage_to_nir: %s prog %d NIR:\n",
387*61046927SAndroid Build Coastguard Worker broadcom_shader_stage_name(stage->stage),
388*61046927SAndroid Build Coastguard Worker stage->program_id);
389*61046927SAndroid Build Coastguard Worker nir_print_shader(nir, stderr);
390*61046927SAndroid Build Coastguard Worker fprintf(stderr, "\n");
391*61046927SAndroid Build Coastguard Worker }
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker preprocess_nir(nir);
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker return nir;
396*61046927SAndroid Build Coastguard Worker }
397*61046927SAndroid Build Coastguard Worker
398*61046927SAndroid Build Coastguard Worker static int
type_size_vec4(const struct glsl_type * type,bool bindless)399*61046927SAndroid Build Coastguard Worker type_size_vec4(const struct glsl_type *type, bool bindless)
400*61046927SAndroid Build Coastguard Worker {
401*61046927SAndroid Build Coastguard Worker return glsl_count_attribute_slots(type, false);
402*61046927SAndroid Build Coastguard Worker }
403*61046927SAndroid Build Coastguard Worker
404*61046927SAndroid Build Coastguard Worker /* FIXME: the number of parameters for this method is somewhat big. Perhaps
405*61046927SAndroid Build Coastguard Worker * rethink.
406*61046927SAndroid Build Coastguard Worker */
407*61046927SAndroid Build Coastguard Worker static unsigned
descriptor_map_add(struct v3dv_descriptor_map * map,int set,int binding,int array_index,int array_size,int start_index,uint8_t return_size,uint8_t plane)408*61046927SAndroid Build Coastguard Worker descriptor_map_add(struct v3dv_descriptor_map *map,
409*61046927SAndroid Build Coastguard Worker int set,
410*61046927SAndroid Build Coastguard Worker int binding,
411*61046927SAndroid Build Coastguard Worker int array_index,
412*61046927SAndroid Build Coastguard Worker int array_size,
413*61046927SAndroid Build Coastguard Worker int start_index,
414*61046927SAndroid Build Coastguard Worker uint8_t return_size,
415*61046927SAndroid Build Coastguard Worker uint8_t plane)
416*61046927SAndroid Build Coastguard Worker {
417*61046927SAndroid Build Coastguard Worker assert(array_index < array_size);
418*61046927SAndroid Build Coastguard Worker assert(return_size == 16 || return_size == 32);
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker unsigned index = start_index;
421*61046927SAndroid Build Coastguard Worker for (; index < map->num_desc; index++) {
422*61046927SAndroid Build Coastguard Worker if (map->used[index] &&
423*61046927SAndroid Build Coastguard Worker set == map->set[index] &&
424*61046927SAndroid Build Coastguard Worker binding == map->binding[index] &&
425*61046927SAndroid Build Coastguard Worker array_index == map->array_index[index] &&
426*61046927SAndroid Build Coastguard Worker plane == map->plane[index]) {
427*61046927SAndroid Build Coastguard Worker assert(array_size == map->array_size[index]);
428*61046927SAndroid Build Coastguard Worker if (return_size != map->return_size[index]) {
429*61046927SAndroid Build Coastguard Worker /* It the return_size is different it means that the same sampler
430*61046927SAndroid Build Coastguard Worker * was used for operations with different precision
431*61046927SAndroid Build Coastguard Worker * requirement. In this case we need to ensure that we use the
432*61046927SAndroid Build Coastguard Worker * larger one.
433*61046927SAndroid Build Coastguard Worker */
434*61046927SAndroid Build Coastguard Worker map->return_size[index] = 32;
435*61046927SAndroid Build Coastguard Worker }
436*61046927SAndroid Build Coastguard Worker return index;
437*61046927SAndroid Build Coastguard Worker } else if (!map->used[index]) {
438*61046927SAndroid Build Coastguard Worker break;
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker assert(index < DESCRIPTOR_MAP_SIZE);
443*61046927SAndroid Build Coastguard Worker assert(!map->used[index]);
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker map->used[index] = true;
446*61046927SAndroid Build Coastguard Worker map->set[index] = set;
447*61046927SAndroid Build Coastguard Worker map->binding[index] = binding;
448*61046927SAndroid Build Coastguard Worker map->array_index[index] = array_index;
449*61046927SAndroid Build Coastguard Worker map->array_size[index] = array_size;
450*61046927SAndroid Build Coastguard Worker map->return_size[index] = return_size;
451*61046927SAndroid Build Coastguard Worker map->plane[index] = plane;
452*61046927SAndroid Build Coastguard Worker map->num_desc = MAX2(map->num_desc, index + 1);
453*61046927SAndroid Build Coastguard Worker
454*61046927SAndroid Build Coastguard Worker return index;
455*61046927SAndroid Build Coastguard Worker }
456*61046927SAndroid Build Coastguard Worker
457*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state {
458*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline;
459*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_layout *layout;
460*61046927SAndroid Build Coastguard Worker bool needs_default_sampler_state;
461*61046927SAndroid Build Coastguard Worker };
462*61046927SAndroid Build Coastguard Worker
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker static void
lower_load_push_constant(nir_builder * b,nir_intrinsic_instr * instr,struct lower_pipeline_layout_state * state)465*61046927SAndroid Build Coastguard Worker lower_load_push_constant(nir_builder *b, nir_intrinsic_instr *instr,
466*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state *state)
467*61046927SAndroid Build Coastguard Worker {
468*61046927SAndroid Build Coastguard Worker assert(instr->intrinsic == nir_intrinsic_load_push_constant);
469*61046927SAndroid Build Coastguard Worker instr->intrinsic = nir_intrinsic_load_uniform;
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker static struct v3dv_descriptor_map*
pipeline_get_descriptor_map(struct v3dv_pipeline * pipeline,VkDescriptorType desc_type,gl_shader_stage gl_stage,bool is_sampler)473*61046927SAndroid Build Coastguard Worker pipeline_get_descriptor_map(struct v3dv_pipeline *pipeline,
474*61046927SAndroid Build Coastguard Worker VkDescriptorType desc_type,
475*61046927SAndroid Build Coastguard Worker gl_shader_stage gl_stage,
476*61046927SAndroid Build Coastguard Worker bool is_sampler)
477*61046927SAndroid Build Coastguard Worker {
478*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage broadcom_stage =
479*61046927SAndroid Build Coastguard Worker gl_shader_stage_to_broadcom(gl_stage);
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker assert(pipeline->shared_data &&
482*61046927SAndroid Build Coastguard Worker pipeline->shared_data->maps[broadcom_stage]);
483*61046927SAndroid Build Coastguard Worker
484*61046927SAndroid Build Coastguard Worker switch(desc_type) {
485*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_SAMPLER:
486*61046927SAndroid Build Coastguard Worker return &pipeline->shared_data->maps[broadcom_stage]->sampler_map;
487*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
488*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
489*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
490*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
491*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
492*61046927SAndroid Build Coastguard Worker return &pipeline->shared_data->maps[broadcom_stage]->texture_map;
493*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
494*61046927SAndroid Build Coastguard Worker return is_sampler ?
495*61046927SAndroid Build Coastguard Worker &pipeline->shared_data->maps[broadcom_stage]->sampler_map :
496*61046927SAndroid Build Coastguard Worker &pipeline->shared_data->maps[broadcom_stage]->texture_map;
497*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
498*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
499*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:
500*61046927SAndroid Build Coastguard Worker return &pipeline->shared_data->maps[broadcom_stage]->ubo_map;
501*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
502*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
503*61046927SAndroid Build Coastguard Worker return &pipeline->shared_data->maps[broadcom_stage]->ssbo_map;
504*61046927SAndroid Build Coastguard Worker default:
505*61046927SAndroid Build Coastguard Worker unreachable("Descriptor type unknown or not having a descriptor map");
506*61046927SAndroid Build Coastguard Worker }
507*61046927SAndroid Build Coastguard Worker }
508*61046927SAndroid Build Coastguard Worker
509*61046927SAndroid Build Coastguard Worker /* Gathers info from the intrinsic (set and binding) and then lowers it so it
510*61046927SAndroid Build Coastguard Worker * could be used by the v3d_compiler */
511*61046927SAndroid Build Coastguard Worker static void
lower_vulkan_resource_index(nir_builder * b,nir_intrinsic_instr * instr,struct lower_pipeline_layout_state * state)512*61046927SAndroid Build Coastguard Worker lower_vulkan_resource_index(nir_builder *b,
513*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *instr,
514*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state *state)
515*61046927SAndroid Build Coastguard Worker {
516*61046927SAndroid Build Coastguard Worker assert(instr->intrinsic == nir_intrinsic_vulkan_resource_index);
517*61046927SAndroid Build Coastguard Worker
518*61046927SAndroid Build Coastguard Worker nir_const_value *const_val = nir_src_as_const_value(instr->src[0]);
519*61046927SAndroid Build Coastguard Worker
520*61046927SAndroid Build Coastguard Worker unsigned set = nir_intrinsic_desc_set(instr);
521*61046927SAndroid Build Coastguard Worker unsigned binding = nir_intrinsic_binding(instr);
522*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_layout *set_layout = state->layout->set[set].layout;
523*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_binding_layout *binding_layout =
524*61046927SAndroid Build Coastguard Worker &set_layout->binding[binding];
525*61046927SAndroid Build Coastguard Worker unsigned index = 0;
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker switch (binding_layout->type) {
528*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
529*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
530*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
531*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
532*61046927SAndroid Build Coastguard Worker case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: {
533*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_map *descriptor_map =
534*61046927SAndroid Build Coastguard Worker pipeline_get_descriptor_map(state->pipeline, binding_layout->type,
535*61046927SAndroid Build Coastguard Worker b->shader->info.stage, false);
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker if (!const_val)
538*61046927SAndroid Build Coastguard Worker unreachable("non-constant vulkan_resource_index array index");
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker /* At compile-time we will need to know if we are processing a UBO load
541*61046927SAndroid Build Coastguard Worker * for an inline or a regular UBO so we can handle inline loads like
542*61046927SAndroid Build Coastguard Worker * push constants. At the level of NIR level however, the inline
543*61046927SAndroid Build Coastguard Worker * information is gone, so we rely on the index to make this distinction.
544*61046927SAndroid Build Coastguard Worker * Particularly, we reserve indices 1..MAX_INLINE_UNIFORM_BUFFERS for
545*61046927SAndroid Build Coastguard Worker * inline buffers. This means that at the descriptor map level
546*61046927SAndroid Build Coastguard Worker * we store inline buffers at slots 0..MAX_INLINE_UNIFORM_BUFFERS - 1,
547*61046927SAndroid Build Coastguard Worker * and regular UBOs at indices starting from MAX_INLINE_UNIFORM_BUFFERS.
548*61046927SAndroid Build Coastguard Worker */
549*61046927SAndroid Build Coastguard Worker uint32_t start_index = 0;
550*61046927SAndroid Build Coastguard Worker if (binding_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
551*61046927SAndroid Build Coastguard Worker binding_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
552*61046927SAndroid Build Coastguard Worker start_index += MAX_INLINE_UNIFORM_BUFFERS;
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker
555*61046927SAndroid Build Coastguard Worker index = descriptor_map_add(descriptor_map, set, binding,
556*61046927SAndroid Build Coastguard Worker const_val->u32,
557*61046927SAndroid Build Coastguard Worker binding_layout->array_size,
558*61046927SAndroid Build Coastguard Worker start_index,
559*61046927SAndroid Build Coastguard Worker 32 /* return_size: doesn't really apply for this case */,
560*61046927SAndroid Build Coastguard Worker 0);
561*61046927SAndroid Build Coastguard Worker break;
562*61046927SAndroid Build Coastguard Worker }
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker default:
565*61046927SAndroid Build Coastguard Worker unreachable("unsupported descriptor type for vulkan_resource_index");
566*61046927SAndroid Build Coastguard Worker break;
567*61046927SAndroid Build Coastguard Worker }
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker /* Since we use the deref pass, both vulkan_resource_index and
570*61046927SAndroid Build Coastguard Worker * vulkan_load_descriptor return a vec2 providing an index and
571*61046927SAndroid Build Coastguard Worker * offset. Our backend compiler only cares about the index part.
572*61046927SAndroid Build Coastguard Worker */
573*61046927SAndroid Build Coastguard Worker nir_def_replace(&instr->def, nir_imm_ivec2(b, index, 0));
574*61046927SAndroid Build Coastguard Worker }
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker static uint8_t
tex_instr_get_and_remove_plane_src(nir_tex_instr * tex)577*61046927SAndroid Build Coastguard Worker tex_instr_get_and_remove_plane_src(nir_tex_instr *tex)
578*61046927SAndroid Build Coastguard Worker {
579*61046927SAndroid Build Coastguard Worker int plane_src_idx = nir_tex_instr_src_index(tex, nir_tex_src_plane);
580*61046927SAndroid Build Coastguard Worker if (plane_src_idx < 0)
581*61046927SAndroid Build Coastguard Worker return 0;
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker uint8_t plane = nir_src_as_uint(tex->src[plane_src_idx].src);
584*61046927SAndroid Build Coastguard Worker nir_tex_instr_remove_src(tex, plane_src_idx);
585*61046927SAndroid Build Coastguard Worker return plane;
586*61046927SAndroid Build Coastguard Worker }
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Worker /* Returns return_size, so it could be used for the case of not having a
589*61046927SAndroid Build Coastguard Worker * sampler object
590*61046927SAndroid Build Coastguard Worker */
591*61046927SAndroid Build Coastguard Worker static uint8_t
lower_tex_src(nir_builder * b,nir_tex_instr * instr,unsigned src_idx,struct lower_pipeline_layout_state * state)592*61046927SAndroid Build Coastguard Worker lower_tex_src(nir_builder *b,
593*61046927SAndroid Build Coastguard Worker nir_tex_instr *instr,
594*61046927SAndroid Build Coastguard Worker unsigned src_idx,
595*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state *state)
596*61046927SAndroid Build Coastguard Worker {
597*61046927SAndroid Build Coastguard Worker nir_def *index = NULL;
598*61046927SAndroid Build Coastguard Worker unsigned base_index = 0;
599*61046927SAndroid Build Coastguard Worker unsigned array_elements = 1;
600*61046927SAndroid Build Coastguard Worker nir_tex_src *src = &instr->src[src_idx];
601*61046927SAndroid Build Coastguard Worker bool is_sampler = src->src_type == nir_tex_src_sampler_deref;
602*61046927SAndroid Build Coastguard Worker
603*61046927SAndroid Build Coastguard Worker uint8_t plane = tex_instr_get_and_remove_plane_src(instr);
604*61046927SAndroid Build Coastguard Worker
605*61046927SAndroid Build Coastguard Worker /* We compute first the offsets */
606*61046927SAndroid Build Coastguard Worker nir_deref_instr *deref = nir_instr_as_deref(src->src.ssa->parent_instr);
607*61046927SAndroid Build Coastguard Worker while (deref->deref_type != nir_deref_type_var) {
608*61046927SAndroid Build Coastguard Worker nir_deref_instr *parent =
609*61046927SAndroid Build Coastguard Worker nir_instr_as_deref(deref->parent.ssa->parent_instr);
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker assert(deref->deref_type == nir_deref_type_array);
612*61046927SAndroid Build Coastguard Worker
613*61046927SAndroid Build Coastguard Worker if (nir_src_is_const(deref->arr.index) && index == NULL) {
614*61046927SAndroid Build Coastguard Worker /* We're still building a direct index */
615*61046927SAndroid Build Coastguard Worker base_index += nir_src_as_uint(deref->arr.index) * array_elements;
616*61046927SAndroid Build Coastguard Worker } else {
617*61046927SAndroid Build Coastguard Worker if (index == NULL) {
618*61046927SAndroid Build Coastguard Worker /* We used to be direct but not anymore */
619*61046927SAndroid Build Coastguard Worker index = nir_imm_int(b, base_index);
620*61046927SAndroid Build Coastguard Worker base_index = 0;
621*61046927SAndroid Build Coastguard Worker }
622*61046927SAndroid Build Coastguard Worker
623*61046927SAndroid Build Coastguard Worker index = nir_iadd(b, index,
624*61046927SAndroid Build Coastguard Worker nir_imul_imm(b, deref->arr.index.ssa,
625*61046927SAndroid Build Coastguard Worker array_elements));
626*61046927SAndroid Build Coastguard Worker }
627*61046927SAndroid Build Coastguard Worker
628*61046927SAndroid Build Coastguard Worker array_elements *= glsl_get_length(parent->type);
629*61046927SAndroid Build Coastguard Worker
630*61046927SAndroid Build Coastguard Worker deref = parent;
631*61046927SAndroid Build Coastguard Worker }
632*61046927SAndroid Build Coastguard Worker
633*61046927SAndroid Build Coastguard Worker if (index)
634*61046927SAndroid Build Coastguard Worker index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
635*61046927SAndroid Build Coastguard Worker
636*61046927SAndroid Build Coastguard Worker /* We have the offsets, we apply them, rewriting the source or removing
637*61046927SAndroid Build Coastguard Worker * instr if needed
638*61046927SAndroid Build Coastguard Worker */
639*61046927SAndroid Build Coastguard Worker if (index) {
640*61046927SAndroid Build Coastguard Worker nir_src_rewrite(&src->src, index);
641*61046927SAndroid Build Coastguard Worker
642*61046927SAndroid Build Coastguard Worker src->src_type = is_sampler ?
643*61046927SAndroid Build Coastguard Worker nir_tex_src_sampler_offset :
644*61046927SAndroid Build Coastguard Worker nir_tex_src_texture_offset;
645*61046927SAndroid Build Coastguard Worker } else {
646*61046927SAndroid Build Coastguard Worker nir_tex_instr_remove_src(instr, src_idx);
647*61046927SAndroid Build Coastguard Worker }
648*61046927SAndroid Build Coastguard Worker
649*61046927SAndroid Build Coastguard Worker uint32_t set = deref->var->data.descriptor_set;
650*61046927SAndroid Build Coastguard Worker uint32_t binding = deref->var->data.binding;
651*61046927SAndroid Build Coastguard Worker /* FIXME: this is a really simplified check for the precision to be used
652*61046927SAndroid Build Coastguard Worker * for the sampling. Right now we are only checking for the variables used
653*61046927SAndroid Build Coastguard Worker * on the operation itself, but there are other cases that we could use to
654*61046927SAndroid Build Coastguard Worker * infer the precision requirement.
655*61046927SAndroid Build Coastguard Worker */
656*61046927SAndroid Build Coastguard Worker bool relaxed_precision = deref->var->data.precision == GLSL_PRECISION_MEDIUM ||
657*61046927SAndroid Build Coastguard Worker deref->var->data.precision == GLSL_PRECISION_LOW;
658*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_layout *set_layout = state->layout->set[set].layout;
659*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_binding_layout *binding_layout =
660*61046927SAndroid Build Coastguard Worker &set_layout->binding[binding];
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker /* For input attachments, the shader includes the attachment_idx. As we are
663*61046927SAndroid Build Coastguard Worker * treating them as a texture, we only want the base_index
664*61046927SAndroid Build Coastguard Worker */
665*61046927SAndroid Build Coastguard Worker uint32_t array_index = binding_layout->type != VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ?
666*61046927SAndroid Build Coastguard Worker deref->var->data.index + base_index :
667*61046927SAndroid Build Coastguard Worker base_index;
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker uint8_t return_size;
670*61046927SAndroid Build Coastguard Worker if (V3D_DBG(TMU_16BIT))
671*61046927SAndroid Build Coastguard Worker return_size = 16;
672*61046927SAndroid Build Coastguard Worker else if (V3D_DBG(TMU_32BIT))
673*61046927SAndroid Build Coastguard Worker return_size = 32;
674*61046927SAndroid Build Coastguard Worker else
675*61046927SAndroid Build Coastguard Worker return_size = relaxed_precision ? 16 : 32;
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_map *map =
678*61046927SAndroid Build Coastguard Worker pipeline_get_descriptor_map(state->pipeline, binding_layout->type,
679*61046927SAndroid Build Coastguard Worker b->shader->info.stage, is_sampler);
680*61046927SAndroid Build Coastguard Worker int desc_index =
681*61046927SAndroid Build Coastguard Worker descriptor_map_add(map,
682*61046927SAndroid Build Coastguard Worker deref->var->data.descriptor_set,
683*61046927SAndroid Build Coastguard Worker deref->var->data.binding,
684*61046927SAndroid Build Coastguard Worker array_index,
685*61046927SAndroid Build Coastguard Worker binding_layout->array_size,
686*61046927SAndroid Build Coastguard Worker 0,
687*61046927SAndroid Build Coastguard Worker return_size,
688*61046927SAndroid Build Coastguard Worker plane);
689*61046927SAndroid Build Coastguard Worker
690*61046927SAndroid Build Coastguard Worker if (is_sampler)
691*61046927SAndroid Build Coastguard Worker instr->sampler_index = desc_index;
692*61046927SAndroid Build Coastguard Worker else
693*61046927SAndroid Build Coastguard Worker instr->texture_index = desc_index;
694*61046927SAndroid Build Coastguard Worker
695*61046927SAndroid Build Coastguard Worker return return_size;
696*61046927SAndroid Build Coastguard Worker }
697*61046927SAndroid Build Coastguard Worker
698*61046927SAndroid Build Coastguard Worker static bool
lower_sampler(nir_builder * b,nir_tex_instr * instr,struct lower_pipeline_layout_state * state)699*61046927SAndroid Build Coastguard Worker lower_sampler(nir_builder *b,
700*61046927SAndroid Build Coastguard Worker nir_tex_instr *instr,
701*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state *state)
702*61046927SAndroid Build Coastguard Worker {
703*61046927SAndroid Build Coastguard Worker uint8_t return_size = 0;
704*61046927SAndroid Build Coastguard Worker
705*61046927SAndroid Build Coastguard Worker int texture_idx =
706*61046927SAndroid Build Coastguard Worker nir_tex_instr_src_index(instr, nir_tex_src_texture_deref);
707*61046927SAndroid Build Coastguard Worker
708*61046927SAndroid Build Coastguard Worker if (texture_idx >= 0)
709*61046927SAndroid Build Coastguard Worker return_size = lower_tex_src(b, instr, texture_idx, state);
710*61046927SAndroid Build Coastguard Worker
711*61046927SAndroid Build Coastguard Worker int sampler_idx =
712*61046927SAndroid Build Coastguard Worker nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref);
713*61046927SAndroid Build Coastguard Worker
714*61046927SAndroid Build Coastguard Worker if (sampler_idx >= 0) {
715*61046927SAndroid Build Coastguard Worker assert(nir_tex_instr_need_sampler(instr));
716*61046927SAndroid Build Coastguard Worker lower_tex_src(b, instr, sampler_idx, state);
717*61046927SAndroid Build Coastguard Worker }
718*61046927SAndroid Build Coastguard Worker
719*61046927SAndroid Build Coastguard Worker if (texture_idx < 0 && sampler_idx < 0)
720*61046927SAndroid Build Coastguard Worker return false;
721*61046927SAndroid Build Coastguard Worker
722*61046927SAndroid Build Coastguard Worker /* If the instruction doesn't have a sampler (i.e. txf) we use backend_flags
723*61046927SAndroid Build Coastguard Worker * to bind a default sampler state to configure precission.
724*61046927SAndroid Build Coastguard Worker */
725*61046927SAndroid Build Coastguard Worker if (sampler_idx < 0) {
726*61046927SAndroid Build Coastguard Worker state->needs_default_sampler_state = true;
727*61046927SAndroid Build Coastguard Worker instr->backend_flags = return_size == 16 ?
728*61046927SAndroid Build Coastguard Worker V3DV_NO_SAMPLER_16BIT_IDX : V3DV_NO_SAMPLER_32BIT_IDX;
729*61046927SAndroid Build Coastguard Worker }
730*61046927SAndroid Build Coastguard Worker
731*61046927SAndroid Build Coastguard Worker return true;
732*61046927SAndroid Build Coastguard Worker }
733*61046927SAndroid Build Coastguard Worker
734*61046927SAndroid Build Coastguard Worker /* FIXME: really similar to lower_tex_src, perhaps refactor? */
735*61046927SAndroid Build Coastguard Worker static void
lower_image_deref(nir_builder * b,nir_intrinsic_instr * instr,struct lower_pipeline_layout_state * state)736*61046927SAndroid Build Coastguard Worker lower_image_deref(nir_builder *b,
737*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *instr,
738*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state *state)
739*61046927SAndroid Build Coastguard Worker {
740*61046927SAndroid Build Coastguard Worker nir_deref_instr *deref = nir_src_as_deref(instr->src[0]);
741*61046927SAndroid Build Coastguard Worker nir_def *index = NULL;
742*61046927SAndroid Build Coastguard Worker unsigned array_elements = 1;
743*61046927SAndroid Build Coastguard Worker unsigned base_index = 0;
744*61046927SAndroid Build Coastguard Worker
745*61046927SAndroid Build Coastguard Worker while (deref->deref_type != nir_deref_type_var) {
746*61046927SAndroid Build Coastguard Worker nir_deref_instr *parent =
747*61046927SAndroid Build Coastguard Worker nir_instr_as_deref(deref->parent.ssa->parent_instr);
748*61046927SAndroid Build Coastguard Worker
749*61046927SAndroid Build Coastguard Worker assert(deref->deref_type == nir_deref_type_array);
750*61046927SAndroid Build Coastguard Worker
751*61046927SAndroid Build Coastguard Worker if (nir_src_is_const(deref->arr.index) && index == NULL) {
752*61046927SAndroid Build Coastguard Worker /* We're still building a direct index */
753*61046927SAndroid Build Coastguard Worker base_index += nir_src_as_uint(deref->arr.index) * array_elements;
754*61046927SAndroid Build Coastguard Worker } else {
755*61046927SAndroid Build Coastguard Worker if (index == NULL) {
756*61046927SAndroid Build Coastguard Worker /* We used to be direct but not anymore */
757*61046927SAndroid Build Coastguard Worker index = nir_imm_int(b, base_index);
758*61046927SAndroid Build Coastguard Worker base_index = 0;
759*61046927SAndroid Build Coastguard Worker }
760*61046927SAndroid Build Coastguard Worker
761*61046927SAndroid Build Coastguard Worker index = nir_iadd(b, index,
762*61046927SAndroid Build Coastguard Worker nir_imul_imm(b, deref->arr.index.ssa,
763*61046927SAndroid Build Coastguard Worker array_elements));
764*61046927SAndroid Build Coastguard Worker }
765*61046927SAndroid Build Coastguard Worker
766*61046927SAndroid Build Coastguard Worker array_elements *= glsl_get_length(parent->type);
767*61046927SAndroid Build Coastguard Worker
768*61046927SAndroid Build Coastguard Worker deref = parent;
769*61046927SAndroid Build Coastguard Worker }
770*61046927SAndroid Build Coastguard Worker
771*61046927SAndroid Build Coastguard Worker if (index)
772*61046927SAndroid Build Coastguard Worker index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
773*61046927SAndroid Build Coastguard Worker
774*61046927SAndroid Build Coastguard Worker uint32_t set = deref->var->data.descriptor_set;
775*61046927SAndroid Build Coastguard Worker uint32_t binding = deref->var->data.binding;
776*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_layout *set_layout = state->layout->set[set].layout;
777*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_set_binding_layout *binding_layout =
778*61046927SAndroid Build Coastguard Worker &set_layout->binding[binding];
779*61046927SAndroid Build Coastguard Worker
780*61046927SAndroid Build Coastguard Worker uint32_t array_index = deref->var->data.index + base_index;
781*61046927SAndroid Build Coastguard Worker
782*61046927SAndroid Build Coastguard Worker assert(binding_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
783*61046927SAndroid Build Coastguard Worker binding_layout->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
784*61046927SAndroid Build Coastguard Worker
785*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_map *map =
786*61046927SAndroid Build Coastguard Worker pipeline_get_descriptor_map(state->pipeline, binding_layout->type,
787*61046927SAndroid Build Coastguard Worker b->shader->info.stage, false);
788*61046927SAndroid Build Coastguard Worker
789*61046927SAndroid Build Coastguard Worker int desc_index =
790*61046927SAndroid Build Coastguard Worker descriptor_map_add(map,
791*61046927SAndroid Build Coastguard Worker deref->var->data.descriptor_set,
792*61046927SAndroid Build Coastguard Worker deref->var->data.binding,
793*61046927SAndroid Build Coastguard Worker array_index,
794*61046927SAndroid Build Coastguard Worker binding_layout->array_size,
795*61046927SAndroid Build Coastguard Worker 0,
796*61046927SAndroid Build Coastguard Worker 32 /* return_size: doesn't apply for textures */,
797*61046927SAndroid Build Coastguard Worker 0);
798*61046927SAndroid Build Coastguard Worker
799*61046927SAndroid Build Coastguard Worker /* Note: we don't need to do anything here in relation to the precision and
800*61046927SAndroid Build Coastguard Worker * the output size because for images we can infer that info from the image
801*61046927SAndroid Build Coastguard Worker * intrinsic, that includes the image format (see
802*61046927SAndroid Build Coastguard Worker * NIR_INTRINSIC_FORMAT). That is done by the v3d compiler.
803*61046927SAndroid Build Coastguard Worker */
804*61046927SAndroid Build Coastguard Worker
805*61046927SAndroid Build Coastguard Worker index = nir_imm_int(b, desc_index);
806*61046927SAndroid Build Coastguard Worker
807*61046927SAndroid Build Coastguard Worker nir_rewrite_image_intrinsic(instr, index, false);
808*61046927SAndroid Build Coastguard Worker }
809*61046927SAndroid Build Coastguard Worker
810*61046927SAndroid Build Coastguard Worker static bool
lower_intrinsic(nir_builder * b,nir_intrinsic_instr * instr,struct lower_pipeline_layout_state * state)811*61046927SAndroid Build Coastguard Worker lower_intrinsic(nir_builder *b,
812*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *instr,
813*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state *state)
814*61046927SAndroid Build Coastguard Worker {
815*61046927SAndroid Build Coastguard Worker switch (instr->intrinsic) {
816*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_push_constant:
817*61046927SAndroid Build Coastguard Worker lower_load_push_constant(b, instr, state);
818*61046927SAndroid Build Coastguard Worker return true;
819*61046927SAndroid Build Coastguard Worker
820*61046927SAndroid Build Coastguard Worker case nir_intrinsic_vulkan_resource_index:
821*61046927SAndroid Build Coastguard Worker lower_vulkan_resource_index(b, instr, state);
822*61046927SAndroid Build Coastguard Worker return true;
823*61046927SAndroid Build Coastguard Worker
824*61046927SAndroid Build Coastguard Worker case nir_intrinsic_load_vulkan_descriptor: {
825*61046927SAndroid Build Coastguard Worker /* Loading the descriptor happens as part of load/store instructions,
826*61046927SAndroid Build Coastguard Worker * so for us this is a no-op.
827*61046927SAndroid Build Coastguard Worker */
828*61046927SAndroid Build Coastguard Worker nir_def_replace(&instr->def, instr->src[0].ssa);
829*61046927SAndroid Build Coastguard Worker return true;
830*61046927SAndroid Build Coastguard Worker }
831*61046927SAndroid Build Coastguard Worker
832*61046927SAndroid Build Coastguard Worker case nir_intrinsic_image_deref_load:
833*61046927SAndroid Build Coastguard Worker case nir_intrinsic_image_deref_store:
834*61046927SAndroid Build Coastguard Worker case nir_intrinsic_image_deref_atomic:
835*61046927SAndroid Build Coastguard Worker case nir_intrinsic_image_deref_atomic_swap:
836*61046927SAndroid Build Coastguard Worker case nir_intrinsic_image_deref_size:
837*61046927SAndroid Build Coastguard Worker case nir_intrinsic_image_deref_samples:
838*61046927SAndroid Build Coastguard Worker lower_image_deref(b, instr, state);
839*61046927SAndroid Build Coastguard Worker return true;
840*61046927SAndroid Build Coastguard Worker
841*61046927SAndroid Build Coastguard Worker default:
842*61046927SAndroid Build Coastguard Worker return false;
843*61046927SAndroid Build Coastguard Worker }
844*61046927SAndroid Build Coastguard Worker }
845*61046927SAndroid Build Coastguard Worker
846*61046927SAndroid Build Coastguard Worker static bool
lower_pipeline_layout_cb(nir_builder * b,nir_instr * instr,void * _state)847*61046927SAndroid Build Coastguard Worker lower_pipeline_layout_cb(nir_builder *b,
848*61046927SAndroid Build Coastguard Worker nir_instr *instr,
849*61046927SAndroid Build Coastguard Worker void *_state)
850*61046927SAndroid Build Coastguard Worker {
851*61046927SAndroid Build Coastguard Worker bool progress = false;
852*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state *state = _state;
853*61046927SAndroid Build Coastguard Worker
854*61046927SAndroid Build Coastguard Worker b->cursor = nir_before_instr(instr);
855*61046927SAndroid Build Coastguard Worker switch (instr->type) {
856*61046927SAndroid Build Coastguard Worker case nir_instr_type_tex:
857*61046927SAndroid Build Coastguard Worker progress |= lower_sampler(b, nir_instr_as_tex(instr), state);
858*61046927SAndroid Build Coastguard Worker break;
859*61046927SAndroid Build Coastguard Worker case nir_instr_type_intrinsic:
860*61046927SAndroid Build Coastguard Worker progress |= lower_intrinsic(b, nir_instr_as_intrinsic(instr), state);
861*61046927SAndroid Build Coastguard Worker break;
862*61046927SAndroid Build Coastguard Worker default:
863*61046927SAndroid Build Coastguard Worker break;
864*61046927SAndroid Build Coastguard Worker }
865*61046927SAndroid Build Coastguard Worker
866*61046927SAndroid Build Coastguard Worker return progress;
867*61046927SAndroid Build Coastguard Worker }
868*61046927SAndroid Build Coastguard Worker
869*61046927SAndroid Build Coastguard Worker static bool
lower_pipeline_layout_info(nir_shader * shader,struct v3dv_pipeline * pipeline,const struct v3dv_pipeline_layout * layout,bool * needs_default_sampler_state)870*61046927SAndroid Build Coastguard Worker lower_pipeline_layout_info(nir_shader *shader,
871*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline,
872*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_layout *layout,
873*61046927SAndroid Build Coastguard Worker bool *needs_default_sampler_state)
874*61046927SAndroid Build Coastguard Worker {
875*61046927SAndroid Build Coastguard Worker bool progress = false;
876*61046927SAndroid Build Coastguard Worker
877*61046927SAndroid Build Coastguard Worker struct lower_pipeline_layout_state state = {
878*61046927SAndroid Build Coastguard Worker .pipeline = pipeline,
879*61046927SAndroid Build Coastguard Worker .layout = layout,
880*61046927SAndroid Build Coastguard Worker .needs_default_sampler_state = false,
881*61046927SAndroid Build Coastguard Worker };
882*61046927SAndroid Build Coastguard Worker
883*61046927SAndroid Build Coastguard Worker progress = nir_shader_instructions_pass(shader, lower_pipeline_layout_cb,
884*61046927SAndroid Build Coastguard Worker nir_metadata_control_flow,
885*61046927SAndroid Build Coastguard Worker &state);
886*61046927SAndroid Build Coastguard Worker
887*61046927SAndroid Build Coastguard Worker *needs_default_sampler_state = state.needs_default_sampler_state;
888*61046927SAndroid Build Coastguard Worker
889*61046927SAndroid Build Coastguard Worker return progress;
890*61046927SAndroid Build Coastguard Worker }
891*61046927SAndroid Build Coastguard Worker
892*61046927SAndroid Build Coastguard Worker /* This flips gl_PointCoord.y to match Vulkan requirements */
893*61046927SAndroid Build Coastguard Worker static bool
lower_point_coord_cb(nir_builder * b,nir_intrinsic_instr * intr,void * _state)894*61046927SAndroid Build Coastguard Worker lower_point_coord_cb(nir_builder *b, nir_intrinsic_instr *intr, void *_state)
895*61046927SAndroid Build Coastguard Worker {
896*61046927SAndroid Build Coastguard Worker if (intr->intrinsic != nir_intrinsic_load_input)
897*61046927SAndroid Build Coastguard Worker return false;
898*61046927SAndroid Build Coastguard Worker
899*61046927SAndroid Build Coastguard Worker if (nir_intrinsic_io_semantics(intr).location != VARYING_SLOT_PNTC)
900*61046927SAndroid Build Coastguard Worker return false;
901*61046927SAndroid Build Coastguard Worker
902*61046927SAndroid Build Coastguard Worker b->cursor = nir_after_instr(&intr->instr);
903*61046927SAndroid Build Coastguard Worker nir_def *result = &intr->def;
904*61046927SAndroid Build Coastguard Worker result =
905*61046927SAndroid Build Coastguard Worker nir_vector_insert_imm(b, result,
906*61046927SAndroid Build Coastguard Worker nir_fsub_imm(b, 1.0, nir_channel(b, result, 1)), 1);
907*61046927SAndroid Build Coastguard Worker nir_def_rewrite_uses_after(&intr->def,
908*61046927SAndroid Build Coastguard Worker result, result->parent_instr);
909*61046927SAndroid Build Coastguard Worker return true;
910*61046927SAndroid Build Coastguard Worker }
911*61046927SAndroid Build Coastguard Worker
912*61046927SAndroid Build Coastguard Worker static bool
v3d_nir_lower_point_coord(nir_shader * s)913*61046927SAndroid Build Coastguard Worker v3d_nir_lower_point_coord(nir_shader *s)
914*61046927SAndroid Build Coastguard Worker {
915*61046927SAndroid Build Coastguard Worker assert(s->info.stage == MESA_SHADER_FRAGMENT);
916*61046927SAndroid Build Coastguard Worker return nir_shader_intrinsics_pass(s, lower_point_coord_cb,
917*61046927SAndroid Build Coastguard Worker nir_metadata_control_flow, NULL);
918*61046927SAndroid Build Coastguard Worker }
919*61046927SAndroid Build Coastguard Worker
920*61046927SAndroid Build Coastguard Worker static void
lower_fs_io(nir_shader * nir)921*61046927SAndroid Build Coastguard Worker lower_fs_io(nir_shader *nir)
922*61046927SAndroid Build Coastguard Worker {
923*61046927SAndroid Build Coastguard Worker /* Our backend doesn't handle array fragment shader outputs */
924*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
925*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_shader_out, NULL);
926*61046927SAndroid Build Coastguard Worker
927*61046927SAndroid Build Coastguard Worker nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs,
928*61046927SAndroid Build Coastguard Worker MESA_SHADER_FRAGMENT);
929*61046927SAndroid Build Coastguard Worker
930*61046927SAndroid Build Coastguard Worker nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
931*61046927SAndroid Build Coastguard Worker MESA_SHADER_FRAGMENT);
932*61046927SAndroid Build Coastguard Worker
933*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_io, nir_var_shader_in | nir_var_shader_out,
934*61046927SAndroid Build Coastguard Worker type_size_vec4, 0);
935*61046927SAndroid Build Coastguard Worker }
936*61046927SAndroid Build Coastguard Worker
937*61046927SAndroid Build Coastguard Worker static void
lower_gs_io(struct nir_shader * nir)938*61046927SAndroid Build Coastguard Worker lower_gs_io(struct nir_shader *nir)
939*61046927SAndroid Build Coastguard Worker {
940*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
941*61046927SAndroid Build Coastguard Worker
942*61046927SAndroid Build Coastguard Worker nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs,
943*61046927SAndroid Build Coastguard Worker MESA_SHADER_GEOMETRY);
944*61046927SAndroid Build Coastguard Worker
945*61046927SAndroid Build Coastguard Worker nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
946*61046927SAndroid Build Coastguard Worker MESA_SHADER_GEOMETRY);
947*61046927SAndroid Build Coastguard Worker }
948*61046927SAndroid Build Coastguard Worker
949*61046927SAndroid Build Coastguard Worker static void
lower_vs_io(struct nir_shader * nir)950*61046927SAndroid Build Coastguard Worker lower_vs_io(struct nir_shader *nir)
951*61046927SAndroid Build Coastguard Worker {
952*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
953*61046927SAndroid Build Coastguard Worker
954*61046927SAndroid Build Coastguard Worker nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs,
955*61046927SAndroid Build Coastguard Worker MESA_SHADER_VERTEX);
956*61046927SAndroid Build Coastguard Worker
957*61046927SAndroid Build Coastguard Worker nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
958*61046927SAndroid Build Coastguard Worker MESA_SHADER_VERTEX);
959*61046927SAndroid Build Coastguard Worker
960*61046927SAndroid Build Coastguard Worker /* FIXME: if we call nir_lower_io, we get a crash later. Likely because it
961*61046927SAndroid Build Coastguard Worker * overlaps with v3d_nir_lower_io. Need further research though.
962*61046927SAndroid Build Coastguard Worker */
963*61046927SAndroid Build Coastguard Worker }
964*61046927SAndroid Build Coastguard Worker
965*61046927SAndroid Build Coastguard Worker static void
shader_debug_output(const char * message,void * data)966*61046927SAndroid Build Coastguard Worker shader_debug_output(const char *message, void *data)
967*61046927SAndroid Build Coastguard Worker {
968*61046927SAndroid Build Coastguard Worker /* FIXME: We probably don't want to debug anything extra here, and in fact
969*61046927SAndroid Build Coastguard Worker * the compiler is not using this callback too much, only as an alternative
970*61046927SAndroid Build Coastguard Worker * way to debug out the shaderdb stats, that you can already get using
971*61046927SAndroid Build Coastguard Worker * V3D_DEBUG=shaderdb. Perhaps it would make sense to revisit the v3d
972*61046927SAndroid Build Coastguard Worker * compiler to remove that callback.
973*61046927SAndroid Build Coastguard Worker */
974*61046927SAndroid Build Coastguard Worker }
975*61046927SAndroid Build Coastguard Worker
976*61046927SAndroid Build Coastguard Worker static void
pipeline_populate_v3d_key(struct v3d_key * key,const struct v3dv_pipeline_stage * p_stage,uint32_t ucp_enables)977*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_key(struct v3d_key *key,
978*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_stage *p_stage,
979*61046927SAndroid Build Coastguard Worker uint32_t ucp_enables)
980*61046927SAndroid Build Coastguard Worker {
981*61046927SAndroid Build Coastguard Worker assert(p_stage->pipeline->shared_data &&
982*61046927SAndroid Build Coastguard Worker p_stage->pipeline->shared_data->maps[p_stage->stage]);
983*61046927SAndroid Build Coastguard Worker
984*61046927SAndroid Build Coastguard Worker /* The following values are default values used at pipeline create. We use
985*61046927SAndroid Build Coastguard Worker * there 32 bit as default return size.
986*61046927SAndroid Build Coastguard Worker */
987*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_map *sampler_map =
988*61046927SAndroid Build Coastguard Worker &p_stage->pipeline->shared_data->maps[p_stage->stage]->sampler_map;
989*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_map *texture_map =
990*61046927SAndroid Build Coastguard Worker &p_stage->pipeline->shared_data->maps[p_stage->stage]->texture_map;
991*61046927SAndroid Build Coastguard Worker
992*61046927SAndroid Build Coastguard Worker key->num_tex_used = texture_map->num_desc;
993*61046927SAndroid Build Coastguard Worker assert(key->num_tex_used <= V3D_MAX_TEXTURE_SAMPLERS);
994*61046927SAndroid Build Coastguard Worker for (uint32_t tex_idx = 0; tex_idx < texture_map->num_desc; tex_idx++) {
995*61046927SAndroid Build Coastguard Worker key->tex[tex_idx].swizzle[0] = PIPE_SWIZZLE_X;
996*61046927SAndroid Build Coastguard Worker key->tex[tex_idx].swizzle[1] = PIPE_SWIZZLE_Y;
997*61046927SAndroid Build Coastguard Worker key->tex[tex_idx].swizzle[2] = PIPE_SWIZZLE_Z;
998*61046927SAndroid Build Coastguard Worker key->tex[tex_idx].swizzle[3] = PIPE_SWIZZLE_W;
999*61046927SAndroid Build Coastguard Worker }
1000*61046927SAndroid Build Coastguard Worker
1001*61046927SAndroid Build Coastguard Worker key->num_samplers_used = sampler_map->num_desc;
1002*61046927SAndroid Build Coastguard Worker assert(key->num_samplers_used <= V3D_MAX_TEXTURE_SAMPLERS);
1003*61046927SAndroid Build Coastguard Worker for (uint32_t sampler_idx = 0; sampler_idx < sampler_map->num_desc;
1004*61046927SAndroid Build Coastguard Worker sampler_idx++) {
1005*61046927SAndroid Build Coastguard Worker key->sampler[sampler_idx].return_size =
1006*61046927SAndroid Build Coastguard Worker sampler_map->return_size[sampler_idx];
1007*61046927SAndroid Build Coastguard Worker
1008*61046927SAndroid Build Coastguard Worker key->sampler[sampler_idx].return_channels =
1009*61046927SAndroid Build Coastguard Worker key->sampler[sampler_idx].return_size == 32 ? 4 : 2;
1010*61046927SAndroid Build Coastguard Worker }
1011*61046927SAndroid Build Coastguard Worker
1012*61046927SAndroid Build Coastguard Worker switch (p_stage->stage) {
1013*61046927SAndroid Build Coastguard Worker case BROADCOM_SHADER_VERTEX:
1014*61046927SAndroid Build Coastguard Worker case BROADCOM_SHADER_VERTEX_BIN:
1015*61046927SAndroid Build Coastguard Worker key->is_last_geometry_stage =
1016*61046927SAndroid Build Coastguard Worker p_stage->pipeline->stages[BROADCOM_SHADER_GEOMETRY] == NULL;
1017*61046927SAndroid Build Coastguard Worker break;
1018*61046927SAndroid Build Coastguard Worker case BROADCOM_SHADER_GEOMETRY:
1019*61046927SAndroid Build Coastguard Worker case BROADCOM_SHADER_GEOMETRY_BIN:
1020*61046927SAndroid Build Coastguard Worker /* FIXME: while we don't implement tessellation shaders */
1021*61046927SAndroid Build Coastguard Worker key->is_last_geometry_stage = true;
1022*61046927SAndroid Build Coastguard Worker break;
1023*61046927SAndroid Build Coastguard Worker case BROADCOM_SHADER_FRAGMENT:
1024*61046927SAndroid Build Coastguard Worker case BROADCOM_SHADER_COMPUTE:
1025*61046927SAndroid Build Coastguard Worker key->is_last_geometry_stage = false;
1026*61046927SAndroid Build Coastguard Worker break;
1027*61046927SAndroid Build Coastguard Worker default:
1028*61046927SAndroid Build Coastguard Worker unreachable("unsupported shader stage");
1029*61046927SAndroid Build Coastguard Worker }
1030*61046927SAndroid Build Coastguard Worker
1031*61046927SAndroid Build Coastguard Worker /* Vulkan doesn't have fixed function state for user clip planes. Instead,
1032*61046927SAndroid Build Coastguard Worker * shaders can write to gl_ClipDistance[], in which case the SPIR-V compiler
1033*61046927SAndroid Build Coastguard Worker * takes care of adding a single compact array variable at
1034*61046927SAndroid Build Coastguard Worker * VARYING_SLOT_CLIP_DIST0, so we don't need any user clip plane lowering.
1035*61046927SAndroid Build Coastguard Worker *
1036*61046927SAndroid Build Coastguard Worker * The only lowering we are interested is specific to the fragment shader,
1037*61046927SAndroid Build Coastguard Worker * where we want to emit discards to honor writes to gl_ClipDistance[] in
1038*61046927SAndroid Build Coastguard Worker * previous stages. This is done via nir_lower_clip_fs() so we only set up
1039*61046927SAndroid Build Coastguard Worker * the ucp enable mask for that stage.
1040*61046927SAndroid Build Coastguard Worker */
1041*61046927SAndroid Build Coastguard Worker key->ucp_enables = ucp_enables;
1042*61046927SAndroid Build Coastguard Worker
1043*61046927SAndroid Build Coastguard Worker const VkPipelineRobustnessBufferBehaviorEXT robust_buffer_enabled =
1044*61046927SAndroid Build Coastguard Worker VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT;
1045*61046927SAndroid Build Coastguard Worker
1046*61046927SAndroid Build Coastguard Worker const VkPipelineRobustnessImageBehaviorEXT robust_image_enabled =
1047*61046927SAndroid Build Coastguard Worker VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT;
1048*61046927SAndroid Build Coastguard Worker
1049*61046927SAndroid Build Coastguard Worker key->robust_uniform_access =
1050*61046927SAndroid Build Coastguard Worker p_stage->robustness.uniform_buffers == robust_buffer_enabled;
1051*61046927SAndroid Build Coastguard Worker key->robust_storage_access =
1052*61046927SAndroid Build Coastguard Worker p_stage->robustness.storage_buffers == robust_buffer_enabled;
1053*61046927SAndroid Build Coastguard Worker key->robust_image_access =
1054*61046927SAndroid Build Coastguard Worker p_stage->robustness.images == robust_image_enabled;
1055*61046927SAndroid Build Coastguard Worker }
1056*61046927SAndroid Build Coastguard Worker
1057*61046927SAndroid Build Coastguard Worker /* FIXME: anv maps to hw primitive type. Perhaps eventually we would do the
1058*61046927SAndroid Build Coastguard Worker * same. For not using prim_mode that is the one already used on v3d
1059*61046927SAndroid Build Coastguard Worker */
1060*61046927SAndroid Build Coastguard Worker static const enum mesa_prim vk_to_mesa_prim[] = {
1061*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = MESA_PRIM_POINTS,
1062*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = MESA_PRIM_LINES,
1063*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = MESA_PRIM_LINE_STRIP,
1064*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = MESA_PRIM_TRIANGLES,
1065*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = MESA_PRIM_TRIANGLE_STRIP,
1066*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = MESA_PRIM_TRIANGLE_FAN,
1067*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY] = MESA_PRIM_LINES_ADJACENCY,
1068*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY] = MESA_PRIM_LINE_STRIP_ADJACENCY,
1069*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY] = MESA_PRIM_TRIANGLES_ADJACENCY,
1070*61046927SAndroid Build Coastguard Worker [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = MESA_PRIM_TRIANGLE_STRIP_ADJACENCY,
1071*61046927SAndroid Build Coastguard Worker };
1072*61046927SAndroid Build Coastguard Worker
1073*61046927SAndroid Build Coastguard Worker uint32_t
v3dv_pipeline_primitive(VkPrimitiveTopology vk_prim)1074*61046927SAndroid Build Coastguard Worker v3dv_pipeline_primitive(VkPrimitiveTopology vk_prim)
1075*61046927SAndroid Build Coastguard Worker {
1076*61046927SAndroid Build Coastguard Worker return v3d_hw_prim_type(vk_to_mesa_prim[vk_prim]);
1077*61046927SAndroid Build Coastguard Worker }
1078*61046927SAndroid Build Coastguard Worker
1079*61046927SAndroid Build Coastguard Worker static const enum pipe_logicop vk_to_pipe_logicop[] = {
1080*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_CLEAR] = PIPE_LOGICOP_CLEAR,
1081*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_AND] = PIPE_LOGICOP_AND,
1082*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_AND_REVERSE] = PIPE_LOGICOP_AND_REVERSE,
1083*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_COPY] = PIPE_LOGICOP_COPY,
1084*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_AND_INVERTED] = PIPE_LOGICOP_AND_INVERTED,
1085*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_NO_OP] = PIPE_LOGICOP_NOOP,
1086*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_XOR] = PIPE_LOGICOP_XOR,
1087*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_OR] = PIPE_LOGICOP_OR,
1088*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_NOR] = PIPE_LOGICOP_NOR,
1089*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_EQUIVALENT] = PIPE_LOGICOP_EQUIV,
1090*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_INVERT] = PIPE_LOGICOP_INVERT,
1091*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_OR_REVERSE] = PIPE_LOGICOP_OR_REVERSE,
1092*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_COPY_INVERTED] = PIPE_LOGICOP_COPY_INVERTED,
1093*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_OR_INVERTED] = PIPE_LOGICOP_OR_INVERTED,
1094*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_NAND] = PIPE_LOGICOP_NAND,
1095*61046927SAndroid Build Coastguard Worker [VK_LOGIC_OP_SET] = PIPE_LOGICOP_SET,
1096*61046927SAndroid Build Coastguard Worker };
1097*61046927SAndroid Build Coastguard Worker
1098*61046927SAndroid Build Coastguard Worker static bool
enable_line_smooth(struct v3dv_pipeline * pipeline,const VkPipelineRasterizationStateCreateInfo * rs_info)1099*61046927SAndroid Build Coastguard Worker enable_line_smooth(struct v3dv_pipeline *pipeline,
1100*61046927SAndroid Build Coastguard Worker const VkPipelineRasterizationStateCreateInfo *rs_info)
1101*61046927SAndroid Build Coastguard Worker {
1102*61046927SAndroid Build Coastguard Worker if (!pipeline->rasterization_enabled)
1103*61046927SAndroid Build Coastguard Worker return false;
1104*61046927SAndroid Build Coastguard Worker
1105*61046927SAndroid Build Coastguard Worker const VkPipelineRasterizationLineStateCreateInfoKHR *ls_info =
1106*61046927SAndroid Build Coastguard Worker vk_find_struct_const(rs_info->pNext,
1107*61046927SAndroid Build Coastguard Worker PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_KHR);
1108*61046927SAndroid Build Coastguard Worker
1109*61046927SAndroid Build Coastguard Worker if (!ls_info)
1110*61046927SAndroid Build Coastguard Worker return false;
1111*61046927SAndroid Build Coastguard Worker
1112*61046927SAndroid Build Coastguard Worker /* Although topology is dynamic now, the topology class can't change
1113*61046927SAndroid Build Coastguard Worker * because we don't support dynamicPrimitiveTopologyUnrestricted, so we can
1114*61046927SAndroid Build Coastguard Worker * use the static topology from the pipeline for this.
1115*61046927SAndroid Build Coastguard Worker */
1116*61046927SAndroid Build Coastguard Worker switch(pipeline->topology) {
1117*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINES:
1118*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINE_LOOP:
1119*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINE_STRIP:
1120*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINES_ADJACENCY:
1121*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINE_STRIP_ADJACENCY:
1122*61046927SAndroid Build Coastguard Worker return ls_info->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_KHR;
1123*61046927SAndroid Build Coastguard Worker default:
1124*61046927SAndroid Build Coastguard Worker return false;
1125*61046927SAndroid Build Coastguard Worker }
1126*61046927SAndroid Build Coastguard Worker }
1127*61046927SAndroid Build Coastguard Worker
1128*61046927SAndroid Build Coastguard Worker static void
v3d_fs_key_set_color_attachment(struct v3d_fs_key * key,const struct v3dv_pipeline_stage * p_stage,uint32_t index,VkFormat fb_format)1129*61046927SAndroid Build Coastguard Worker v3d_fs_key_set_color_attachment(struct v3d_fs_key *key,
1130*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_stage *p_stage,
1131*61046927SAndroid Build Coastguard Worker uint32_t index,
1132*61046927SAndroid Build Coastguard Worker VkFormat fb_format)
1133*61046927SAndroid Build Coastguard Worker {
1134*61046927SAndroid Build Coastguard Worker key->cbufs |= 1 << index;
1135*61046927SAndroid Build Coastguard Worker
1136*61046927SAndroid Build Coastguard Worker enum pipe_format fb_pipe_format = vk_format_to_pipe_format(fb_format);
1137*61046927SAndroid Build Coastguard Worker
1138*61046927SAndroid Build Coastguard Worker /* If logic operations are enabled then we might emit color reads and we
1139*61046927SAndroid Build Coastguard Worker * need to know the color buffer format and swizzle for that
1140*61046927SAndroid Build Coastguard Worker */
1141*61046927SAndroid Build Coastguard Worker if (key->logicop_func != PIPE_LOGICOP_COPY) {
1142*61046927SAndroid Build Coastguard Worker /* Framebuffer formats should be single plane */
1143*61046927SAndroid Build Coastguard Worker assert(vk_format_get_plane_count(fb_format) == 1);
1144*61046927SAndroid Build Coastguard Worker key->color_fmt[index].format = fb_pipe_format;
1145*61046927SAndroid Build Coastguard Worker memcpy(key->color_fmt[index].swizzle,
1146*61046927SAndroid Build Coastguard Worker v3dv_get_format_swizzle(p_stage->pipeline->device, fb_format, 0),
1147*61046927SAndroid Build Coastguard Worker sizeof(key->color_fmt[index].swizzle));
1148*61046927SAndroid Build Coastguard Worker }
1149*61046927SAndroid Build Coastguard Worker
1150*61046927SAndroid Build Coastguard Worker const struct util_format_description *desc =
1151*61046927SAndroid Build Coastguard Worker vk_format_description(fb_format);
1152*61046927SAndroid Build Coastguard Worker
1153*61046927SAndroid Build Coastguard Worker if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT &&
1154*61046927SAndroid Build Coastguard Worker desc->channel[0].size == 32) {
1155*61046927SAndroid Build Coastguard Worker key->f32_color_rb |= 1 << index;
1156*61046927SAndroid Build Coastguard Worker }
1157*61046927SAndroid Build Coastguard Worker
1158*61046927SAndroid Build Coastguard Worker if (p_stage->nir->info.fs.untyped_color_outputs) {
1159*61046927SAndroid Build Coastguard Worker if (util_format_is_pure_uint(fb_pipe_format))
1160*61046927SAndroid Build Coastguard Worker key->uint_color_rb |= 1 << index;
1161*61046927SAndroid Build Coastguard Worker else if (util_format_is_pure_sint(fb_pipe_format))
1162*61046927SAndroid Build Coastguard Worker key->int_color_rb |= 1 << index;
1163*61046927SAndroid Build Coastguard Worker }
1164*61046927SAndroid Build Coastguard Worker }
1165*61046927SAndroid Build Coastguard Worker
1166*61046927SAndroid Build Coastguard Worker static void
pipeline_populate_v3d_fs_key(struct v3d_fs_key * key,const VkGraphicsPipelineCreateInfo * pCreateInfo,const struct vk_render_pass_state * rendering_info,const struct v3dv_pipeline_stage * p_stage,bool has_geometry_shader,uint32_t ucp_enables)1167*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_fs_key(struct v3d_fs_key *key,
1168*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
1169*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rendering_info,
1170*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_stage *p_stage,
1171*61046927SAndroid Build Coastguard Worker bool has_geometry_shader,
1172*61046927SAndroid Build Coastguard Worker uint32_t ucp_enables)
1173*61046927SAndroid Build Coastguard Worker {
1174*61046927SAndroid Build Coastguard Worker assert(p_stage->stage == BROADCOM_SHADER_FRAGMENT);
1175*61046927SAndroid Build Coastguard Worker
1176*61046927SAndroid Build Coastguard Worker memset(key, 0, sizeof(*key));
1177*61046927SAndroid Build Coastguard Worker
1178*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = p_stage->pipeline->device;
1179*61046927SAndroid Build Coastguard Worker assert(device);
1180*61046927SAndroid Build Coastguard Worker
1181*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_key(&key->base, p_stage, ucp_enables);
1182*61046927SAndroid Build Coastguard Worker
1183*61046927SAndroid Build Coastguard Worker const VkPipelineInputAssemblyStateCreateInfo *ia_info =
1184*61046927SAndroid Build Coastguard Worker pCreateInfo->pInputAssemblyState;
1185*61046927SAndroid Build Coastguard Worker uint8_t topology = vk_to_mesa_prim[ia_info->topology];
1186*61046927SAndroid Build Coastguard Worker
1187*61046927SAndroid Build Coastguard Worker key->is_points = (topology == MESA_PRIM_POINTS);
1188*61046927SAndroid Build Coastguard Worker key->is_lines = (topology >= MESA_PRIM_LINES &&
1189*61046927SAndroid Build Coastguard Worker topology <= MESA_PRIM_LINE_STRIP);
1190*61046927SAndroid Build Coastguard Worker
1191*61046927SAndroid Build Coastguard Worker if (key->is_points) {
1192*61046927SAndroid Build Coastguard Worker /* This mask represents state for GL_ARB_point_sprite which is not
1193*61046927SAndroid Build Coastguard Worker * relevant to Vulkan.
1194*61046927SAndroid Build Coastguard Worker */
1195*61046927SAndroid Build Coastguard Worker key->point_sprite_mask = 0;
1196*61046927SAndroid Build Coastguard Worker
1197*61046927SAndroid Build Coastguard Worker /* Vulkan mandates upper left. */
1198*61046927SAndroid Build Coastguard Worker key->point_coord_upper_left = true;
1199*61046927SAndroid Build Coastguard Worker }
1200*61046927SAndroid Build Coastguard Worker
1201*61046927SAndroid Build Coastguard Worker key->has_gs = has_geometry_shader;
1202*61046927SAndroid Build Coastguard Worker
1203*61046927SAndroid Build Coastguard Worker const VkPipelineColorBlendStateCreateInfo *cb_info =
1204*61046927SAndroid Build Coastguard Worker p_stage->pipeline->rasterization_enabled ?
1205*61046927SAndroid Build Coastguard Worker pCreateInfo->pColorBlendState : NULL;
1206*61046927SAndroid Build Coastguard Worker
1207*61046927SAndroid Build Coastguard Worker key->logicop_func = cb_info && cb_info->logicOpEnable == VK_TRUE ?
1208*61046927SAndroid Build Coastguard Worker vk_to_pipe_logicop[cb_info->logicOp] :
1209*61046927SAndroid Build Coastguard Worker PIPE_LOGICOP_COPY;
1210*61046927SAndroid Build Coastguard Worker
1211*61046927SAndroid Build Coastguard Worker /* Multisample rasterization state must be ignored if rasterization
1212*61046927SAndroid Build Coastguard Worker * is disabled.
1213*61046927SAndroid Build Coastguard Worker */
1214*61046927SAndroid Build Coastguard Worker const VkPipelineMultisampleStateCreateInfo *ms_info =
1215*61046927SAndroid Build Coastguard Worker p_stage->pipeline->rasterization_enabled ? pCreateInfo->pMultisampleState : NULL;
1216*61046927SAndroid Build Coastguard Worker if (ms_info) {
1217*61046927SAndroid Build Coastguard Worker assert(ms_info->rasterizationSamples == VK_SAMPLE_COUNT_1_BIT ||
1218*61046927SAndroid Build Coastguard Worker ms_info->rasterizationSamples == VK_SAMPLE_COUNT_4_BIT);
1219*61046927SAndroid Build Coastguard Worker key->msaa = ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT;
1220*61046927SAndroid Build Coastguard Worker
1221*61046927SAndroid Build Coastguard Worker if (key->msaa)
1222*61046927SAndroid Build Coastguard Worker key->sample_alpha_to_coverage = ms_info->alphaToCoverageEnable;
1223*61046927SAndroid Build Coastguard Worker
1224*61046927SAndroid Build Coastguard Worker key->sample_alpha_to_one = ms_info->alphaToOneEnable;
1225*61046927SAndroid Build Coastguard Worker }
1226*61046927SAndroid Build Coastguard Worker
1227*61046927SAndroid Build Coastguard Worker key->line_smoothing = enable_line_smooth(p_stage->pipeline,
1228*61046927SAndroid Build Coastguard Worker pCreateInfo->pRasterizationState);
1229*61046927SAndroid Build Coastguard Worker
1230*61046927SAndroid Build Coastguard Worker /* This is intended for V3D versions before 4.1, otherwise we just use the
1231*61046927SAndroid Build Coastguard Worker * tile buffer load/store swap R/B bit.
1232*61046927SAndroid Build Coastguard Worker */
1233*61046927SAndroid Build Coastguard Worker key->swap_color_rb = 0;
1234*61046927SAndroid Build Coastguard Worker
1235*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rendering_info->color_attachment_count; i++) {
1236*61046927SAndroid Build Coastguard Worker if (rendering_info->color_attachment_formats[i] == VK_FORMAT_UNDEFINED)
1237*61046927SAndroid Build Coastguard Worker continue;
1238*61046927SAndroid Build Coastguard Worker v3d_fs_key_set_color_attachment(key, p_stage, i,
1239*61046927SAndroid Build Coastguard Worker rendering_info->color_attachment_formats[i]);
1240*61046927SAndroid Build Coastguard Worker }
1241*61046927SAndroid Build Coastguard Worker }
1242*61046927SAndroid Build Coastguard Worker
1243*61046927SAndroid Build Coastguard Worker static void
setup_stage_outputs_from_next_stage_inputs(uint8_t next_stage_num_inputs,struct v3d_varying_slot * next_stage_input_slots,uint8_t * num_used_outputs,struct v3d_varying_slot * used_output_slots,uint32_t size_of_used_output_slots)1244*61046927SAndroid Build Coastguard Worker setup_stage_outputs_from_next_stage_inputs(
1245*61046927SAndroid Build Coastguard Worker uint8_t next_stage_num_inputs,
1246*61046927SAndroid Build Coastguard Worker struct v3d_varying_slot *next_stage_input_slots,
1247*61046927SAndroid Build Coastguard Worker uint8_t *num_used_outputs,
1248*61046927SAndroid Build Coastguard Worker struct v3d_varying_slot *used_output_slots,
1249*61046927SAndroid Build Coastguard Worker uint32_t size_of_used_output_slots)
1250*61046927SAndroid Build Coastguard Worker {
1251*61046927SAndroid Build Coastguard Worker *num_used_outputs = next_stage_num_inputs;
1252*61046927SAndroid Build Coastguard Worker memcpy(used_output_slots, next_stage_input_slots, size_of_used_output_slots);
1253*61046927SAndroid Build Coastguard Worker }
1254*61046927SAndroid Build Coastguard Worker
1255*61046927SAndroid Build Coastguard Worker static void
pipeline_populate_v3d_gs_key(struct v3d_gs_key * key,const VkGraphicsPipelineCreateInfo * pCreateInfo,const struct v3dv_pipeline_stage * p_stage)1256*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_gs_key(struct v3d_gs_key *key,
1257*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
1258*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_stage *p_stage)
1259*61046927SAndroid Build Coastguard Worker {
1260*61046927SAndroid Build Coastguard Worker assert(p_stage->stage == BROADCOM_SHADER_GEOMETRY ||
1261*61046927SAndroid Build Coastguard Worker p_stage->stage == BROADCOM_SHADER_GEOMETRY_BIN);
1262*61046927SAndroid Build Coastguard Worker
1263*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = p_stage->pipeline->device;
1264*61046927SAndroid Build Coastguard Worker assert(device);
1265*61046927SAndroid Build Coastguard Worker
1266*61046927SAndroid Build Coastguard Worker memset(key, 0, sizeof(*key));
1267*61046927SAndroid Build Coastguard Worker
1268*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_key(&key->base, p_stage, 0);
1269*61046927SAndroid Build Coastguard Worker
1270*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline = p_stage->pipeline;
1271*61046927SAndroid Build Coastguard Worker
1272*61046927SAndroid Build Coastguard Worker key->per_vertex_point_size =
1273*61046927SAndroid Build Coastguard Worker p_stage->nir->info.outputs_written & (1ull << VARYING_SLOT_PSIZ);
1274*61046927SAndroid Build Coastguard Worker
1275*61046927SAndroid Build Coastguard Worker key->is_coord = broadcom_shader_stage_is_binning(p_stage->stage);
1276*61046927SAndroid Build Coastguard Worker
1277*61046927SAndroid Build Coastguard Worker assert(key->base.is_last_geometry_stage);
1278*61046927SAndroid Build Coastguard Worker if (key->is_coord) {
1279*61046927SAndroid Build Coastguard Worker /* Output varyings in the last binning shader are only used for transform
1280*61046927SAndroid Build Coastguard Worker * feedback. Set to 0 as VK_EXT_transform_feedback is not supported.
1281*61046927SAndroid Build Coastguard Worker */
1282*61046927SAndroid Build Coastguard Worker key->num_used_outputs = 0;
1283*61046927SAndroid Build Coastguard Worker } else {
1284*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *fs_variant =
1285*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT];
1286*61046927SAndroid Build Coastguard Worker
1287*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(sizeof(key->used_outputs) ==
1288*61046927SAndroid Build Coastguard Worker sizeof(fs_variant->prog_data.fs->input_slots));
1289*61046927SAndroid Build Coastguard Worker
1290*61046927SAndroid Build Coastguard Worker setup_stage_outputs_from_next_stage_inputs(
1291*61046927SAndroid Build Coastguard Worker fs_variant->prog_data.fs->num_inputs,
1292*61046927SAndroid Build Coastguard Worker fs_variant->prog_data.fs->input_slots,
1293*61046927SAndroid Build Coastguard Worker &key->num_used_outputs,
1294*61046927SAndroid Build Coastguard Worker key->used_outputs,
1295*61046927SAndroid Build Coastguard Worker sizeof(key->used_outputs));
1296*61046927SAndroid Build Coastguard Worker }
1297*61046927SAndroid Build Coastguard Worker }
1298*61046927SAndroid Build Coastguard Worker
1299*61046927SAndroid Build Coastguard Worker static void
pipeline_populate_v3d_vs_key(struct v3d_vs_key * key,const VkGraphicsPipelineCreateInfo * pCreateInfo,const struct v3dv_pipeline_stage * p_stage)1300*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_vs_key(struct v3d_vs_key *key,
1301*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
1302*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_stage *p_stage)
1303*61046927SAndroid Build Coastguard Worker {
1304*61046927SAndroid Build Coastguard Worker assert(p_stage->stage == BROADCOM_SHADER_VERTEX ||
1305*61046927SAndroid Build Coastguard Worker p_stage->stage == BROADCOM_SHADER_VERTEX_BIN);
1306*61046927SAndroid Build Coastguard Worker
1307*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = p_stage->pipeline->device;
1308*61046927SAndroid Build Coastguard Worker assert(device);
1309*61046927SAndroid Build Coastguard Worker
1310*61046927SAndroid Build Coastguard Worker memset(key, 0, sizeof(*key));
1311*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_key(&key->base, p_stage, 0);
1312*61046927SAndroid Build Coastguard Worker
1313*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline = p_stage->pipeline;
1314*61046927SAndroid Build Coastguard Worker
1315*61046927SAndroid Build Coastguard Worker key->per_vertex_point_size =
1316*61046927SAndroid Build Coastguard Worker p_stage->nir->info.outputs_written & (1ull << VARYING_SLOT_PSIZ);
1317*61046927SAndroid Build Coastguard Worker
1318*61046927SAndroid Build Coastguard Worker key->is_coord = broadcom_shader_stage_is_binning(p_stage->stage);
1319*61046927SAndroid Build Coastguard Worker
1320*61046927SAndroid Build Coastguard Worker if (key->is_coord) { /* Binning VS*/
1321*61046927SAndroid Build Coastguard Worker if (key->base.is_last_geometry_stage) {
1322*61046927SAndroid Build Coastguard Worker /* Output varyings in the last binning shader are only used for
1323*61046927SAndroid Build Coastguard Worker * transform feedback. Set to 0 as VK_EXT_transform_feedback is not
1324*61046927SAndroid Build Coastguard Worker * supported.
1325*61046927SAndroid Build Coastguard Worker */
1326*61046927SAndroid Build Coastguard Worker key->num_used_outputs = 0;
1327*61046927SAndroid Build Coastguard Worker } else {
1328*61046927SAndroid Build Coastguard Worker /* Linking against GS binning program */
1329*61046927SAndroid Build Coastguard Worker assert(pipeline->stages[BROADCOM_SHADER_GEOMETRY]);
1330*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *gs_bin_variant =
1331*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN];
1332*61046927SAndroid Build Coastguard Worker
1333*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(sizeof(key->used_outputs) ==
1334*61046927SAndroid Build Coastguard Worker sizeof(gs_bin_variant->prog_data.gs->input_slots));
1335*61046927SAndroid Build Coastguard Worker
1336*61046927SAndroid Build Coastguard Worker setup_stage_outputs_from_next_stage_inputs(
1337*61046927SAndroid Build Coastguard Worker gs_bin_variant->prog_data.gs->num_inputs,
1338*61046927SAndroid Build Coastguard Worker gs_bin_variant->prog_data.gs->input_slots,
1339*61046927SAndroid Build Coastguard Worker &key->num_used_outputs,
1340*61046927SAndroid Build Coastguard Worker key->used_outputs,
1341*61046927SAndroid Build Coastguard Worker sizeof(key->used_outputs));
1342*61046927SAndroid Build Coastguard Worker }
1343*61046927SAndroid Build Coastguard Worker } else { /* Render VS */
1344*61046927SAndroid Build Coastguard Worker if (pipeline->stages[BROADCOM_SHADER_GEOMETRY]) {
1345*61046927SAndroid Build Coastguard Worker /* Linking against GS render program */
1346*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *gs_variant =
1347*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY];
1348*61046927SAndroid Build Coastguard Worker
1349*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(sizeof(key->used_outputs) ==
1350*61046927SAndroid Build Coastguard Worker sizeof(gs_variant->prog_data.gs->input_slots));
1351*61046927SAndroid Build Coastguard Worker
1352*61046927SAndroid Build Coastguard Worker setup_stage_outputs_from_next_stage_inputs(
1353*61046927SAndroid Build Coastguard Worker gs_variant->prog_data.gs->num_inputs,
1354*61046927SAndroid Build Coastguard Worker gs_variant->prog_data.gs->input_slots,
1355*61046927SAndroid Build Coastguard Worker &key->num_used_outputs,
1356*61046927SAndroid Build Coastguard Worker key->used_outputs,
1357*61046927SAndroid Build Coastguard Worker sizeof(key->used_outputs));
1358*61046927SAndroid Build Coastguard Worker } else {
1359*61046927SAndroid Build Coastguard Worker /* Linking against FS program */
1360*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *fs_variant =
1361*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT];
1362*61046927SAndroid Build Coastguard Worker
1363*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(sizeof(key->used_outputs) ==
1364*61046927SAndroid Build Coastguard Worker sizeof(fs_variant->prog_data.fs->input_slots));
1365*61046927SAndroid Build Coastguard Worker
1366*61046927SAndroid Build Coastguard Worker setup_stage_outputs_from_next_stage_inputs(
1367*61046927SAndroid Build Coastguard Worker fs_variant->prog_data.fs->num_inputs,
1368*61046927SAndroid Build Coastguard Worker fs_variant->prog_data.fs->input_slots,
1369*61046927SAndroid Build Coastguard Worker &key->num_used_outputs,
1370*61046927SAndroid Build Coastguard Worker key->used_outputs,
1371*61046927SAndroid Build Coastguard Worker sizeof(key->used_outputs));
1372*61046927SAndroid Build Coastguard Worker }
1373*61046927SAndroid Build Coastguard Worker }
1374*61046927SAndroid Build Coastguard Worker
1375*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputStateCreateInfo *vi_info =
1376*61046927SAndroid Build Coastguard Worker pCreateInfo->pVertexInputState;
1377*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) {
1378*61046927SAndroid Build Coastguard Worker const VkVertexInputAttributeDescription *desc =
1379*61046927SAndroid Build Coastguard Worker &vi_info->pVertexAttributeDescriptions[i];
1380*61046927SAndroid Build Coastguard Worker assert(desc->location < MAX_VERTEX_ATTRIBS);
1381*61046927SAndroid Build Coastguard Worker if (desc->format == VK_FORMAT_B8G8R8A8_UNORM ||
1382*61046927SAndroid Build Coastguard Worker desc->format == VK_FORMAT_A2R10G10B10_UNORM_PACK32) {
1383*61046927SAndroid Build Coastguard Worker key->va_swap_rb_mask |= 1 << (VERT_ATTRIB_GENERIC0 + desc->location);
1384*61046927SAndroid Build Coastguard Worker }
1385*61046927SAndroid Build Coastguard Worker }
1386*61046927SAndroid Build Coastguard Worker }
1387*61046927SAndroid Build Coastguard Worker
1388*61046927SAndroid Build Coastguard Worker /**
1389*61046927SAndroid Build Coastguard Worker * Creates the initial form of the pipeline stage for a binning shader by
1390*61046927SAndroid Build Coastguard Worker * cloning the render shader and flagging it as a coordinate shader.
1391*61046927SAndroid Build Coastguard Worker *
1392*61046927SAndroid Build Coastguard Worker * Returns NULL if it was not able to allocate the object, so it should be
1393*61046927SAndroid Build Coastguard Worker * handled as a VK_ERROR_OUT_OF_HOST_MEMORY error.
1394*61046927SAndroid Build Coastguard Worker */
1395*61046927SAndroid Build Coastguard Worker static struct v3dv_pipeline_stage *
pipeline_stage_create_binning(const struct v3dv_pipeline_stage * src,const VkAllocationCallbacks * pAllocator)1396*61046927SAndroid Build Coastguard Worker pipeline_stage_create_binning(const struct v3dv_pipeline_stage *src,
1397*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
1398*61046927SAndroid Build Coastguard Worker {
1399*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = src->pipeline->device;
1400*61046927SAndroid Build Coastguard Worker
1401*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage =
1402*61046927SAndroid Build Coastguard Worker vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
1403*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1404*61046927SAndroid Build Coastguard Worker
1405*61046927SAndroid Build Coastguard Worker if (p_stage == NULL)
1406*61046927SAndroid Build Coastguard Worker return NULL;
1407*61046927SAndroid Build Coastguard Worker
1408*61046927SAndroid Build Coastguard Worker assert(src->stage == BROADCOM_SHADER_VERTEX ||
1409*61046927SAndroid Build Coastguard Worker src->stage == BROADCOM_SHADER_GEOMETRY);
1410*61046927SAndroid Build Coastguard Worker
1411*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage bin_stage =
1412*61046927SAndroid Build Coastguard Worker src->stage == BROADCOM_SHADER_VERTEX ?
1413*61046927SAndroid Build Coastguard Worker BROADCOM_SHADER_VERTEX_BIN :
1414*61046927SAndroid Build Coastguard Worker BROADCOM_SHADER_GEOMETRY_BIN;
1415*61046927SAndroid Build Coastguard Worker
1416*61046927SAndroid Build Coastguard Worker p_stage->pipeline = src->pipeline;
1417*61046927SAndroid Build Coastguard Worker p_stage->stage = bin_stage;
1418*61046927SAndroid Build Coastguard Worker p_stage->entrypoint = src->entrypoint;
1419*61046927SAndroid Build Coastguard Worker p_stage->module = src->module;
1420*61046927SAndroid Build Coastguard Worker p_stage->module_info = src->module_info;
1421*61046927SAndroid Build Coastguard Worker
1422*61046927SAndroid Build Coastguard Worker /* For binning shaders we will clone the NIR code from the corresponding
1423*61046927SAndroid Build Coastguard Worker * render shader later, when we call pipeline_compile_xxx_shader. This way
1424*61046927SAndroid Build Coastguard Worker * we only have to run the relevant NIR lowerings once for render shaders
1425*61046927SAndroid Build Coastguard Worker */
1426*61046927SAndroid Build Coastguard Worker p_stage->nir = NULL;
1427*61046927SAndroid Build Coastguard Worker p_stage->program_id = src->program_id;
1428*61046927SAndroid Build Coastguard Worker p_stage->spec_info = src->spec_info;
1429*61046927SAndroid Build Coastguard Worker p_stage->feedback = (VkPipelineCreationFeedback) { 0 };
1430*61046927SAndroid Build Coastguard Worker p_stage->robustness = src->robustness;
1431*61046927SAndroid Build Coastguard Worker memcpy(p_stage->shader_sha1, src->shader_sha1, 20);
1432*61046927SAndroid Build Coastguard Worker
1433*61046927SAndroid Build Coastguard Worker return p_stage;
1434*61046927SAndroid Build Coastguard Worker }
1435*61046927SAndroid Build Coastguard Worker
1436*61046927SAndroid Build Coastguard Worker /*
1437*61046927SAndroid Build Coastguard Worker * Based on some creation flags we assume that the QPU would be needed later
1438*61046927SAndroid Build Coastguard Worker * to gather further info. In that case we just keep the qput_insts around,
1439*61046927SAndroid Build Coastguard Worker * instead of map/unmap the bo later.
1440*61046927SAndroid Build Coastguard Worker */
1441*61046927SAndroid Build Coastguard Worker static bool
pipeline_keep_qpu(struct v3dv_pipeline * pipeline)1442*61046927SAndroid Build Coastguard Worker pipeline_keep_qpu(struct v3dv_pipeline *pipeline)
1443*61046927SAndroid Build Coastguard Worker {
1444*61046927SAndroid Build Coastguard Worker return pipeline->flags &
1445*61046927SAndroid Build Coastguard Worker (VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR |
1446*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR);
1447*61046927SAndroid Build Coastguard Worker }
1448*61046927SAndroid Build Coastguard Worker
1449*61046927SAndroid Build Coastguard Worker /**
1450*61046927SAndroid Build Coastguard Worker * Returns false if it was not able to allocate or map the assembly bo memory.
1451*61046927SAndroid Build Coastguard Worker */
1452*61046927SAndroid Build Coastguard Worker static bool
upload_assembly(struct v3dv_pipeline * pipeline)1453*61046927SAndroid Build Coastguard Worker upload_assembly(struct v3dv_pipeline *pipeline)
1454*61046927SAndroid Build Coastguard Worker {
1455*61046927SAndroid Build Coastguard Worker uint32_t total_size = 0;
1456*61046927SAndroid Build Coastguard Worker for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
1457*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant =
1458*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[stage];
1459*61046927SAndroid Build Coastguard Worker
1460*61046927SAndroid Build Coastguard Worker if (variant != NULL)
1461*61046927SAndroid Build Coastguard Worker total_size += variant->qpu_insts_size;
1462*61046927SAndroid Build Coastguard Worker }
1463*61046927SAndroid Build Coastguard Worker
1464*61046927SAndroid Build Coastguard Worker struct v3dv_bo *bo = v3dv_bo_alloc(pipeline->device, total_size,
1465*61046927SAndroid Build Coastguard Worker "pipeline shader assembly", true);
1466*61046927SAndroid Build Coastguard Worker if (!bo) {
1467*61046927SAndroid Build Coastguard Worker fprintf(stderr, "failed to allocate memory for shader\n");
1468*61046927SAndroid Build Coastguard Worker return false;
1469*61046927SAndroid Build Coastguard Worker }
1470*61046927SAndroid Build Coastguard Worker
1471*61046927SAndroid Build Coastguard Worker bool ok = v3dv_bo_map(pipeline->device, bo, total_size);
1472*61046927SAndroid Build Coastguard Worker if (!ok) {
1473*61046927SAndroid Build Coastguard Worker fprintf(stderr, "failed to map source shader buffer\n");
1474*61046927SAndroid Build Coastguard Worker return false;
1475*61046927SAndroid Build Coastguard Worker }
1476*61046927SAndroid Build Coastguard Worker
1477*61046927SAndroid Build Coastguard Worker uint32_t offset = 0;
1478*61046927SAndroid Build Coastguard Worker for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
1479*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant =
1480*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[stage];
1481*61046927SAndroid Build Coastguard Worker
1482*61046927SAndroid Build Coastguard Worker if (variant != NULL) {
1483*61046927SAndroid Build Coastguard Worker variant->assembly_offset = offset;
1484*61046927SAndroid Build Coastguard Worker
1485*61046927SAndroid Build Coastguard Worker memcpy(bo->map + offset, variant->qpu_insts, variant->qpu_insts_size);
1486*61046927SAndroid Build Coastguard Worker offset += variant->qpu_insts_size;
1487*61046927SAndroid Build Coastguard Worker
1488*61046927SAndroid Build Coastguard Worker if (!pipeline_keep_qpu(pipeline)) {
1489*61046927SAndroid Build Coastguard Worker free(variant->qpu_insts);
1490*61046927SAndroid Build Coastguard Worker variant->qpu_insts = NULL;
1491*61046927SAndroid Build Coastguard Worker }
1492*61046927SAndroid Build Coastguard Worker }
1493*61046927SAndroid Build Coastguard Worker }
1494*61046927SAndroid Build Coastguard Worker assert(total_size == offset);
1495*61046927SAndroid Build Coastguard Worker
1496*61046927SAndroid Build Coastguard Worker pipeline->shared_data->assembly_bo = bo;
1497*61046927SAndroid Build Coastguard Worker
1498*61046927SAndroid Build Coastguard Worker return true;
1499*61046927SAndroid Build Coastguard Worker }
1500*61046927SAndroid Build Coastguard Worker
1501*61046927SAndroid Build Coastguard Worker static void
pipeline_hash_graphics(const struct v3dv_pipeline * pipeline,struct v3dv_pipeline_key * key,unsigned char * sha1_out)1502*61046927SAndroid Build Coastguard Worker pipeline_hash_graphics(const struct v3dv_pipeline *pipeline,
1503*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_key *key,
1504*61046927SAndroid Build Coastguard Worker unsigned char *sha1_out)
1505*61046927SAndroid Build Coastguard Worker {
1506*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
1507*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
1508*61046927SAndroid Build Coastguard Worker
1509*61046927SAndroid Build Coastguard Worker if (pipeline->layout) {
1510*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &pipeline->layout->sha1,
1511*61046927SAndroid Build Coastguard Worker sizeof(pipeline->layout->sha1));
1512*61046927SAndroid Build Coastguard Worker }
1513*61046927SAndroid Build Coastguard Worker
1514*61046927SAndroid Build Coastguard Worker /* We need to include all shader stages in the sha1 key as linking may
1515*61046927SAndroid Build Coastguard Worker * modify the shader code in any stage. An alternative would be to use the
1516*61046927SAndroid Build Coastguard Worker * serialized NIR, but that seems like an overkill.
1517*61046927SAndroid Build Coastguard Worker */
1518*61046927SAndroid Build Coastguard Worker for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
1519*61046927SAndroid Build Coastguard Worker if (broadcom_shader_stage_is_binning(stage))
1520*61046927SAndroid Build Coastguard Worker continue;
1521*61046927SAndroid Build Coastguard Worker
1522*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage = pipeline->stages[stage];
1523*61046927SAndroid Build Coastguard Worker if (p_stage == NULL)
1524*61046927SAndroid Build Coastguard Worker continue;
1525*61046927SAndroid Build Coastguard Worker
1526*61046927SAndroid Build Coastguard Worker assert(stage != BROADCOM_SHADER_COMPUTE);
1527*61046927SAndroid Build Coastguard Worker
1528*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, p_stage->shader_sha1, sizeof(p_stage->shader_sha1));
1529*61046927SAndroid Build Coastguard Worker }
1530*61046927SAndroid Build Coastguard Worker
1531*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, key, sizeof(struct v3dv_pipeline_key));
1532*61046927SAndroid Build Coastguard Worker
1533*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, sha1_out);
1534*61046927SAndroid Build Coastguard Worker }
1535*61046927SAndroid Build Coastguard Worker
1536*61046927SAndroid Build Coastguard Worker static void
pipeline_hash_compute(const struct v3dv_pipeline * pipeline,struct v3dv_pipeline_key * key,unsigned char * sha1_out)1537*61046927SAndroid Build Coastguard Worker pipeline_hash_compute(const struct v3dv_pipeline *pipeline,
1538*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_key *key,
1539*61046927SAndroid Build Coastguard Worker unsigned char *sha1_out)
1540*61046927SAndroid Build Coastguard Worker {
1541*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
1542*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
1543*61046927SAndroid Build Coastguard Worker
1544*61046927SAndroid Build Coastguard Worker if (pipeline->layout) {
1545*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &pipeline->layout->sha1,
1546*61046927SAndroid Build Coastguard Worker sizeof(pipeline->layout->sha1));
1547*61046927SAndroid Build Coastguard Worker }
1548*61046927SAndroid Build Coastguard Worker
1549*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage =
1550*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_COMPUTE];
1551*61046927SAndroid Build Coastguard Worker
1552*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, p_stage->shader_sha1, sizeof(p_stage->shader_sha1));
1553*61046927SAndroid Build Coastguard Worker
1554*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, key, sizeof(struct v3dv_pipeline_key));
1555*61046927SAndroid Build Coastguard Worker
1556*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, sha1_out);
1557*61046927SAndroid Build Coastguard Worker }
1558*61046927SAndroid Build Coastguard Worker
1559*61046927SAndroid Build Coastguard Worker /* Checks that the pipeline has enough spill size to use for any of their
1560*61046927SAndroid Build Coastguard Worker * variants
1561*61046927SAndroid Build Coastguard Worker */
1562*61046927SAndroid Build Coastguard Worker static void
pipeline_check_spill_size(struct v3dv_pipeline * pipeline)1563*61046927SAndroid Build Coastguard Worker pipeline_check_spill_size(struct v3dv_pipeline *pipeline)
1564*61046927SAndroid Build Coastguard Worker {
1565*61046927SAndroid Build Coastguard Worker uint32_t max_spill_size = 0;
1566*61046927SAndroid Build Coastguard Worker
1567*61046927SAndroid Build Coastguard Worker for(uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
1568*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant =
1569*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[stage];
1570*61046927SAndroid Build Coastguard Worker
1571*61046927SAndroid Build Coastguard Worker if (variant != NULL) {
1572*61046927SAndroid Build Coastguard Worker max_spill_size = MAX2(variant->prog_data.base->spill_size,
1573*61046927SAndroid Build Coastguard Worker max_spill_size);
1574*61046927SAndroid Build Coastguard Worker }
1575*61046927SAndroid Build Coastguard Worker }
1576*61046927SAndroid Build Coastguard Worker
1577*61046927SAndroid Build Coastguard Worker if (max_spill_size > 0) {
1578*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = pipeline->device;
1579*61046927SAndroid Build Coastguard Worker
1580*61046927SAndroid Build Coastguard Worker /* The TIDX register we use for choosing the area to access
1581*61046927SAndroid Build Coastguard Worker * for scratch space is: (core << 6) | (qpu << 2) | thread.
1582*61046927SAndroid Build Coastguard Worker * Even at minimum threadcount in a particular shader, that
1583*61046927SAndroid Build Coastguard Worker * means we still multiply by qpus by 4.
1584*61046927SAndroid Build Coastguard Worker */
1585*61046927SAndroid Build Coastguard Worker const uint32_t total_spill_size =
1586*61046927SAndroid Build Coastguard Worker 4 * device->devinfo.qpu_count * max_spill_size;
1587*61046927SAndroid Build Coastguard Worker if (pipeline->spill.bo) {
1588*61046927SAndroid Build Coastguard Worker assert(pipeline->spill.size_per_thread > 0);
1589*61046927SAndroid Build Coastguard Worker v3dv_bo_free(device, pipeline->spill.bo);
1590*61046927SAndroid Build Coastguard Worker }
1591*61046927SAndroid Build Coastguard Worker pipeline->spill.bo =
1592*61046927SAndroid Build Coastguard Worker v3dv_bo_alloc(device, total_spill_size, "spill", true);
1593*61046927SAndroid Build Coastguard Worker pipeline->spill.size_per_thread = max_spill_size;
1594*61046927SAndroid Build Coastguard Worker }
1595*61046927SAndroid Build Coastguard Worker }
1596*61046927SAndroid Build Coastguard Worker
1597*61046927SAndroid Build Coastguard Worker /**
1598*61046927SAndroid Build Coastguard Worker * Creates a new shader_variant_create. Note that for prog_data is not const,
1599*61046927SAndroid Build Coastguard Worker * so it is assumed that the caller will prove a pointer that the
1600*61046927SAndroid Build Coastguard Worker * shader_variant will own.
1601*61046927SAndroid Build Coastguard Worker *
1602*61046927SAndroid Build Coastguard Worker * Creation doesn't include allocate a BO to store the content of qpu_insts,
1603*61046927SAndroid Build Coastguard Worker * as we will try to share the same bo for several shader variants. Also note
1604*61046927SAndroid Build Coastguard Worker * that qpu_ints being NULL is valid, for example if we are creating the
1605*61046927SAndroid Build Coastguard Worker * shader_variants from the cache, so we can just upload the assembly of all
1606*61046927SAndroid Build Coastguard Worker * the shader stages at once.
1607*61046927SAndroid Build Coastguard Worker */
1608*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *
v3dv_shader_variant_create(struct v3dv_device * device,enum broadcom_shader_stage stage,struct v3d_prog_data * prog_data,uint32_t prog_data_size,uint32_t assembly_offset,uint64_t * qpu_insts,uint32_t qpu_insts_size,VkResult * out_vk_result)1609*61046927SAndroid Build Coastguard Worker v3dv_shader_variant_create(struct v3dv_device *device,
1610*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage stage,
1611*61046927SAndroid Build Coastguard Worker struct v3d_prog_data *prog_data,
1612*61046927SAndroid Build Coastguard Worker uint32_t prog_data_size,
1613*61046927SAndroid Build Coastguard Worker uint32_t assembly_offset,
1614*61046927SAndroid Build Coastguard Worker uint64_t *qpu_insts,
1615*61046927SAndroid Build Coastguard Worker uint32_t qpu_insts_size,
1616*61046927SAndroid Build Coastguard Worker VkResult *out_vk_result)
1617*61046927SAndroid Build Coastguard Worker {
1618*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant =
1619*61046927SAndroid Build Coastguard Worker vk_zalloc(&device->vk.alloc, sizeof(*variant), 8,
1620*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1621*61046927SAndroid Build Coastguard Worker
1622*61046927SAndroid Build Coastguard Worker if (variant == NULL) {
1623*61046927SAndroid Build Coastguard Worker *out_vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
1624*61046927SAndroid Build Coastguard Worker return NULL;
1625*61046927SAndroid Build Coastguard Worker }
1626*61046927SAndroid Build Coastguard Worker
1627*61046927SAndroid Build Coastguard Worker variant->stage = stage;
1628*61046927SAndroid Build Coastguard Worker variant->prog_data_size = prog_data_size;
1629*61046927SAndroid Build Coastguard Worker variant->prog_data.base = prog_data;
1630*61046927SAndroid Build Coastguard Worker
1631*61046927SAndroid Build Coastguard Worker variant->assembly_offset = assembly_offset;
1632*61046927SAndroid Build Coastguard Worker variant->qpu_insts_size = qpu_insts_size;
1633*61046927SAndroid Build Coastguard Worker variant->qpu_insts = qpu_insts;
1634*61046927SAndroid Build Coastguard Worker
1635*61046927SAndroid Build Coastguard Worker *out_vk_result = VK_SUCCESS;
1636*61046927SAndroid Build Coastguard Worker
1637*61046927SAndroid Build Coastguard Worker return variant;
1638*61046927SAndroid Build Coastguard Worker }
1639*61046927SAndroid Build Coastguard Worker
1640*61046927SAndroid Build Coastguard Worker /* For a given key, it returns the compiled version of the shader. Returns a
1641*61046927SAndroid Build Coastguard Worker * new reference to the shader_variant to the caller, or NULL.
1642*61046927SAndroid Build Coastguard Worker *
1643*61046927SAndroid Build Coastguard Worker * If the method returns NULL it means that something wrong happened:
1644*61046927SAndroid Build Coastguard Worker * * Not enough memory: this is one of the possible outcomes defined by
1645*61046927SAndroid Build Coastguard Worker * vkCreateXXXPipelines. out_vk_result will return the proper oom error.
1646*61046927SAndroid Build Coastguard Worker * * Compilation error: hypothetically this shouldn't happen, as the spec
1647*61046927SAndroid Build Coastguard Worker * states that vkShaderModule needs to be created with a valid SPIR-V, so
1648*61046927SAndroid Build Coastguard Worker * any compilation failure is a driver bug. In the practice, something as
1649*61046927SAndroid Build Coastguard Worker * common as failing to register allocate can lead to a compilation
1650*61046927SAndroid Build Coastguard Worker * failure. In that case the only option (for any driver) is
1651*61046927SAndroid Build Coastguard Worker * VK_ERROR_UNKNOWN, even if we know that the problem was a compiler
1652*61046927SAndroid Build Coastguard Worker * error.
1653*61046927SAndroid Build Coastguard Worker */
1654*61046927SAndroid Build Coastguard Worker static struct v3dv_shader_variant *
pipeline_compile_shader_variant(struct v3dv_pipeline_stage * p_stage,struct v3d_key * key,size_t key_size,const VkAllocationCallbacks * pAllocator,VkResult * out_vk_result)1655*61046927SAndroid Build Coastguard Worker pipeline_compile_shader_variant(struct v3dv_pipeline_stage *p_stage,
1656*61046927SAndroid Build Coastguard Worker struct v3d_key *key,
1657*61046927SAndroid Build Coastguard Worker size_t key_size,
1658*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
1659*61046927SAndroid Build Coastguard Worker VkResult *out_vk_result)
1660*61046927SAndroid Build Coastguard Worker {
1661*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
1662*61046927SAndroid Build Coastguard Worker
1663*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline = p_stage->pipeline;
1664*61046927SAndroid Build Coastguard Worker struct v3dv_physical_device *physical_device = pipeline->device->pdevice;
1665*61046927SAndroid Build Coastguard Worker const struct v3d_compiler *compiler = physical_device->compiler;
1666*61046927SAndroid Build Coastguard Worker gl_shader_stage gl_stage = broadcom_shader_stage_to_gl(p_stage->stage);
1667*61046927SAndroid Build Coastguard Worker
1668*61046927SAndroid Build Coastguard Worker if (V3D_DBG(NIR) || v3d_debug_flag_for_shader_stage(gl_stage)) {
1669*61046927SAndroid Build Coastguard Worker fprintf(stderr, "Just before v3d_compile: %s prog %d NIR:\n",
1670*61046927SAndroid Build Coastguard Worker broadcom_shader_stage_name(p_stage->stage),
1671*61046927SAndroid Build Coastguard Worker p_stage->program_id);
1672*61046927SAndroid Build Coastguard Worker nir_print_shader(p_stage->nir, stderr);
1673*61046927SAndroid Build Coastguard Worker fprintf(stderr, "\n");
1674*61046927SAndroid Build Coastguard Worker }
1675*61046927SAndroid Build Coastguard Worker
1676*61046927SAndroid Build Coastguard Worker uint64_t *qpu_insts;
1677*61046927SAndroid Build Coastguard Worker uint32_t qpu_insts_size;
1678*61046927SAndroid Build Coastguard Worker struct v3d_prog_data *prog_data;
1679*61046927SAndroid Build Coastguard Worker uint32_t prog_data_size = v3d_prog_data_size(gl_stage);
1680*61046927SAndroid Build Coastguard Worker
1681*61046927SAndroid Build Coastguard Worker qpu_insts = v3d_compile(compiler,
1682*61046927SAndroid Build Coastguard Worker key, &prog_data,
1683*61046927SAndroid Build Coastguard Worker p_stage->nir,
1684*61046927SAndroid Build Coastguard Worker shader_debug_output, NULL,
1685*61046927SAndroid Build Coastguard Worker p_stage->program_id, 0,
1686*61046927SAndroid Build Coastguard Worker &qpu_insts_size);
1687*61046927SAndroid Build Coastguard Worker
1688*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant = NULL;
1689*61046927SAndroid Build Coastguard Worker
1690*61046927SAndroid Build Coastguard Worker if (!qpu_insts) {
1691*61046927SAndroid Build Coastguard Worker fprintf(stderr, "Failed to compile %s prog %d NIR to VIR\n",
1692*61046927SAndroid Build Coastguard Worker broadcom_shader_stage_name(p_stage->stage),
1693*61046927SAndroid Build Coastguard Worker p_stage->program_id);
1694*61046927SAndroid Build Coastguard Worker *out_vk_result = VK_ERROR_UNKNOWN;
1695*61046927SAndroid Build Coastguard Worker } else {
1696*61046927SAndroid Build Coastguard Worker variant =
1697*61046927SAndroid Build Coastguard Worker v3dv_shader_variant_create(pipeline->device, p_stage->stage,
1698*61046927SAndroid Build Coastguard Worker prog_data, prog_data_size,
1699*61046927SAndroid Build Coastguard Worker 0, /* assembly_offset, no final value yet */
1700*61046927SAndroid Build Coastguard Worker qpu_insts, qpu_insts_size,
1701*61046927SAndroid Build Coastguard Worker out_vk_result);
1702*61046927SAndroid Build Coastguard Worker }
1703*61046927SAndroid Build Coastguard Worker /* At this point we don't need anymore the nir shader, but we are freeing
1704*61046927SAndroid Build Coastguard Worker * all the temporary p_stage structs used during the pipeline creation when
1705*61046927SAndroid Build Coastguard Worker * we finish it, so let's not worry about freeing the nir here.
1706*61046927SAndroid Build Coastguard Worker */
1707*61046927SAndroid Build Coastguard Worker
1708*61046927SAndroid Build Coastguard Worker p_stage->feedback.duration += os_time_get_nano() - stage_start;
1709*61046927SAndroid Build Coastguard Worker
1710*61046927SAndroid Build Coastguard Worker return variant;
1711*61046927SAndroid Build Coastguard Worker }
1712*61046927SAndroid Build Coastguard Worker
1713*61046927SAndroid Build Coastguard Worker static void
link_shaders(nir_shader * producer,nir_shader * consumer)1714*61046927SAndroid Build Coastguard Worker link_shaders(nir_shader *producer, nir_shader *consumer)
1715*61046927SAndroid Build Coastguard Worker {
1716*61046927SAndroid Build Coastguard Worker assert(producer);
1717*61046927SAndroid Build Coastguard Worker assert(consumer);
1718*61046927SAndroid Build Coastguard Worker
1719*61046927SAndroid Build Coastguard Worker if (producer->options->lower_to_scalar) {
1720*61046927SAndroid Build Coastguard Worker NIR_PASS(_, producer, nir_lower_io_to_scalar_early, nir_var_shader_out);
1721*61046927SAndroid Build Coastguard Worker NIR_PASS(_, consumer, nir_lower_io_to_scalar_early, nir_var_shader_in);
1722*61046927SAndroid Build Coastguard Worker }
1723*61046927SAndroid Build Coastguard Worker
1724*61046927SAndroid Build Coastguard Worker nir_lower_io_arrays_to_elements(producer, consumer);
1725*61046927SAndroid Build Coastguard Worker
1726*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, producer);
1727*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, consumer);
1728*61046927SAndroid Build Coastguard Worker
1729*61046927SAndroid Build Coastguard Worker if (nir_link_opt_varyings(producer, consumer))
1730*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, consumer);
1731*61046927SAndroid Build Coastguard Worker
1732*61046927SAndroid Build Coastguard Worker NIR_PASS(_, producer, nir_remove_dead_variables, nir_var_shader_out, NULL);
1733*61046927SAndroid Build Coastguard Worker NIR_PASS(_, consumer, nir_remove_dead_variables, nir_var_shader_in, NULL);
1734*61046927SAndroid Build Coastguard Worker
1735*61046927SAndroid Build Coastguard Worker if (nir_remove_unused_varyings(producer, consumer)) {
1736*61046927SAndroid Build Coastguard Worker NIR_PASS(_, producer, nir_lower_global_vars_to_local);
1737*61046927SAndroid Build Coastguard Worker NIR_PASS(_, consumer, nir_lower_global_vars_to_local);
1738*61046927SAndroid Build Coastguard Worker
1739*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, producer);
1740*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, consumer);
1741*61046927SAndroid Build Coastguard Worker
1742*61046927SAndroid Build Coastguard Worker /* Optimizations can cause varyings to become unused.
1743*61046927SAndroid Build Coastguard Worker * nir_compact_varyings() depends on all dead varyings being removed so
1744*61046927SAndroid Build Coastguard Worker * we need to call nir_remove_dead_variables() again here.
1745*61046927SAndroid Build Coastguard Worker */
1746*61046927SAndroid Build Coastguard Worker NIR_PASS(_, producer, nir_remove_dead_variables, nir_var_shader_out, NULL);
1747*61046927SAndroid Build Coastguard Worker NIR_PASS(_, consumer, nir_remove_dead_variables, nir_var_shader_in, NULL);
1748*61046927SAndroid Build Coastguard Worker }
1749*61046927SAndroid Build Coastguard Worker }
1750*61046927SAndroid Build Coastguard Worker
1751*61046927SAndroid Build Coastguard Worker static void
pipeline_lower_nir(struct v3dv_pipeline * pipeline,struct v3dv_pipeline_stage * p_stage,struct v3dv_pipeline_layout * layout)1752*61046927SAndroid Build Coastguard Worker pipeline_lower_nir(struct v3dv_pipeline *pipeline,
1753*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage,
1754*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_layout *layout)
1755*61046927SAndroid Build Coastguard Worker {
1756*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
1757*61046927SAndroid Build Coastguard Worker
1758*61046927SAndroid Build Coastguard Worker assert(pipeline->shared_data &&
1759*61046927SAndroid Build Coastguard Worker pipeline->shared_data->maps[p_stage->stage]);
1760*61046927SAndroid Build Coastguard Worker
1761*61046927SAndroid Build Coastguard Worker NIR_PASS_V(p_stage->nir, nir_vk_lower_ycbcr_tex,
1762*61046927SAndroid Build Coastguard Worker lookup_ycbcr_conversion, layout);
1763*61046927SAndroid Build Coastguard Worker
1764*61046927SAndroid Build Coastguard Worker nir_shader_gather_info(p_stage->nir, nir_shader_get_entrypoint(p_stage->nir));
1765*61046927SAndroid Build Coastguard Worker
1766*61046927SAndroid Build Coastguard Worker /* We add this because we need a valid sampler for nir_lower_tex to do
1767*61046927SAndroid Build Coastguard Worker * unpacking of the texture operation result, even for the case where there
1768*61046927SAndroid Build Coastguard Worker * is no sampler state.
1769*61046927SAndroid Build Coastguard Worker *
1770*61046927SAndroid Build Coastguard Worker * We add two of those, one for the case we need a 16bit return_size, and
1771*61046927SAndroid Build Coastguard Worker * another for the case we need a 32bit return size.
1772*61046927SAndroid Build Coastguard Worker */
1773*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_maps *maps =
1774*61046927SAndroid Build Coastguard Worker pipeline->shared_data->maps[p_stage->stage];
1775*61046927SAndroid Build Coastguard Worker
1776*61046927SAndroid Build Coastguard Worker UNUSED unsigned index;
1777*61046927SAndroid Build Coastguard Worker index = descriptor_map_add(&maps->sampler_map, -1, -1, -1, 0, 0, 16, 0);
1778*61046927SAndroid Build Coastguard Worker assert(index == V3DV_NO_SAMPLER_16BIT_IDX);
1779*61046927SAndroid Build Coastguard Worker
1780*61046927SAndroid Build Coastguard Worker index = descriptor_map_add(&maps->sampler_map, -2, -2, -2, 0, 0, 32, 0);
1781*61046927SAndroid Build Coastguard Worker assert(index == V3DV_NO_SAMPLER_32BIT_IDX);
1782*61046927SAndroid Build Coastguard Worker
1783*61046927SAndroid Build Coastguard Worker /* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
1784*61046927SAndroid Build Coastguard Worker bool needs_default_sampler_state = false;
1785*61046927SAndroid Build Coastguard Worker NIR_PASS(_, p_stage->nir, lower_pipeline_layout_info, pipeline, layout,
1786*61046927SAndroid Build Coastguard Worker &needs_default_sampler_state);
1787*61046927SAndroid Build Coastguard Worker
1788*61046927SAndroid Build Coastguard Worker /* If in the end we didn't need to use the default sampler states and the
1789*61046927SAndroid Build Coastguard Worker * shader doesn't need any other samplers, get rid of them so we can
1790*61046927SAndroid Build Coastguard Worker * recognize that this program doesn't use any samplers at all.
1791*61046927SAndroid Build Coastguard Worker */
1792*61046927SAndroid Build Coastguard Worker if (!needs_default_sampler_state && maps->sampler_map.num_desc == 2)
1793*61046927SAndroid Build Coastguard Worker maps->sampler_map.num_desc = 0;
1794*61046927SAndroid Build Coastguard Worker
1795*61046927SAndroid Build Coastguard Worker p_stage->feedback.duration += os_time_get_nano() - stage_start;
1796*61046927SAndroid Build Coastguard Worker }
1797*61046927SAndroid Build Coastguard Worker
1798*61046927SAndroid Build Coastguard Worker /**
1799*61046927SAndroid Build Coastguard Worker * The SPIR-V compiler will insert a sized compact array for
1800*61046927SAndroid Build Coastguard Worker * VARYING_SLOT_CLIP_DIST0 if the vertex shader writes to gl_ClipDistance[],
1801*61046927SAndroid Build Coastguard Worker * where the size of the array determines the number of active clip planes.
1802*61046927SAndroid Build Coastguard Worker */
1803*61046927SAndroid Build Coastguard Worker static uint32_t
get_ucp_enable_mask(struct v3dv_pipeline_stage * p_stage)1804*61046927SAndroid Build Coastguard Worker get_ucp_enable_mask(struct v3dv_pipeline_stage *p_stage)
1805*61046927SAndroid Build Coastguard Worker {
1806*61046927SAndroid Build Coastguard Worker assert(p_stage->stage == BROADCOM_SHADER_VERTEX);
1807*61046927SAndroid Build Coastguard Worker const nir_shader *shader = p_stage->nir;
1808*61046927SAndroid Build Coastguard Worker assert(shader);
1809*61046927SAndroid Build Coastguard Worker
1810*61046927SAndroid Build Coastguard Worker nir_foreach_variable_with_modes(var, shader, nir_var_shader_out) {
1811*61046927SAndroid Build Coastguard Worker if (var->data.location == VARYING_SLOT_CLIP_DIST0) {
1812*61046927SAndroid Build Coastguard Worker assert(var->data.compact);
1813*61046927SAndroid Build Coastguard Worker return (1 << glsl_get_length(var->type)) - 1;
1814*61046927SAndroid Build Coastguard Worker }
1815*61046927SAndroid Build Coastguard Worker }
1816*61046927SAndroid Build Coastguard Worker return 0;
1817*61046927SAndroid Build Coastguard Worker }
1818*61046927SAndroid Build Coastguard Worker
1819*61046927SAndroid Build Coastguard Worker static nir_shader *
pipeline_stage_get_nir(struct v3dv_pipeline_stage * p_stage,struct v3dv_pipeline * pipeline,struct v3dv_pipeline_cache * cache)1820*61046927SAndroid Build Coastguard Worker pipeline_stage_get_nir(struct v3dv_pipeline_stage *p_stage,
1821*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline,
1822*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_cache *cache)
1823*61046927SAndroid Build Coastguard Worker {
1824*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
1825*61046927SAndroid Build Coastguard Worker
1826*61046927SAndroid Build Coastguard Worker nir_shader *nir = NULL;
1827*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *nir_options =
1828*61046927SAndroid Build Coastguard Worker v3dv_pipeline_get_nir_options(&pipeline->device->devinfo);
1829*61046927SAndroid Build Coastguard Worker
1830*61046927SAndroid Build Coastguard Worker nir = v3dv_pipeline_cache_search_for_nir(pipeline, cache,
1831*61046927SAndroid Build Coastguard Worker nir_options,
1832*61046927SAndroid Build Coastguard Worker p_stage->shader_sha1);
1833*61046927SAndroid Build Coastguard Worker
1834*61046927SAndroid Build Coastguard Worker if (nir) {
1835*61046927SAndroid Build Coastguard Worker assert(nir->info.stage == broadcom_shader_stage_to_gl(p_stage->stage));
1836*61046927SAndroid Build Coastguard Worker
1837*61046927SAndroid Build Coastguard Worker /* A NIR cache hit doesn't avoid the large majority of pipeline stage
1838*61046927SAndroid Build Coastguard Worker * creation so the cache hit is not recorded in the pipeline feedback
1839*61046927SAndroid Build Coastguard Worker * flags
1840*61046927SAndroid Build Coastguard Worker */
1841*61046927SAndroid Build Coastguard Worker
1842*61046927SAndroid Build Coastguard Worker p_stage->feedback.duration += os_time_get_nano() - stage_start;
1843*61046927SAndroid Build Coastguard Worker
1844*61046927SAndroid Build Coastguard Worker return nir;
1845*61046927SAndroid Build Coastguard Worker }
1846*61046927SAndroid Build Coastguard Worker
1847*61046927SAndroid Build Coastguard Worker nir = shader_module_compile_to_nir(pipeline->device, p_stage);
1848*61046927SAndroid Build Coastguard Worker
1849*61046927SAndroid Build Coastguard Worker if (nir) {
1850*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_cache *default_cache =
1851*61046927SAndroid Build Coastguard Worker &pipeline->device->default_pipeline_cache;
1852*61046927SAndroid Build Coastguard Worker
1853*61046927SAndroid Build Coastguard Worker v3dv_pipeline_cache_upload_nir(pipeline, cache, nir,
1854*61046927SAndroid Build Coastguard Worker p_stage->shader_sha1);
1855*61046927SAndroid Build Coastguard Worker
1856*61046927SAndroid Build Coastguard Worker /* Ensure that the variant is on the default cache, as cmd_buffer could
1857*61046927SAndroid Build Coastguard Worker * need to change the current variant
1858*61046927SAndroid Build Coastguard Worker */
1859*61046927SAndroid Build Coastguard Worker if (default_cache != cache) {
1860*61046927SAndroid Build Coastguard Worker v3dv_pipeline_cache_upload_nir(pipeline, default_cache, nir,
1861*61046927SAndroid Build Coastguard Worker p_stage->shader_sha1);
1862*61046927SAndroid Build Coastguard Worker }
1863*61046927SAndroid Build Coastguard Worker
1864*61046927SAndroid Build Coastguard Worker p_stage->feedback.duration += os_time_get_nano() - stage_start;
1865*61046927SAndroid Build Coastguard Worker
1866*61046927SAndroid Build Coastguard Worker return nir;
1867*61046927SAndroid Build Coastguard Worker }
1868*61046927SAndroid Build Coastguard Worker
1869*61046927SAndroid Build Coastguard Worker /* FIXME: this shouldn't happen, raise error? */
1870*61046927SAndroid Build Coastguard Worker return NULL;
1871*61046927SAndroid Build Coastguard Worker }
1872*61046927SAndroid Build Coastguard Worker
1873*61046927SAndroid Build Coastguard Worker static VkResult
pipeline_compile_vertex_shader(struct v3dv_pipeline * pipeline,const VkAllocationCallbacks * pAllocator,const VkGraphicsPipelineCreateInfo * pCreateInfo)1874*61046927SAndroid Build Coastguard Worker pipeline_compile_vertex_shader(struct v3dv_pipeline *pipeline,
1875*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
1876*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo)
1877*61046927SAndroid Build Coastguard Worker {
1878*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_vs =
1879*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_VERTEX];
1880*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_vs_bin =
1881*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_VERTEX_BIN];
1882*61046927SAndroid Build Coastguard Worker
1883*61046927SAndroid Build Coastguard Worker assert(p_stage_vs_bin != NULL);
1884*61046927SAndroid Build Coastguard Worker if (p_stage_vs_bin->nir == NULL) {
1885*61046927SAndroid Build Coastguard Worker assert(p_stage_vs->nir);
1886*61046927SAndroid Build Coastguard Worker p_stage_vs_bin->nir = nir_shader_clone(NULL, p_stage_vs->nir);
1887*61046927SAndroid Build Coastguard Worker }
1888*61046927SAndroid Build Coastguard Worker
1889*61046927SAndroid Build Coastguard Worker VkResult vk_result;
1890*61046927SAndroid Build Coastguard Worker struct v3d_vs_key key;
1891*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_vs_key(&key, pCreateInfo, p_stage_vs);
1892*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX] =
1893*61046927SAndroid Build Coastguard Worker pipeline_compile_shader_variant(p_stage_vs, &key.base, sizeof(key),
1894*61046927SAndroid Build Coastguard Worker pAllocator, &vk_result);
1895*61046927SAndroid Build Coastguard Worker if (vk_result != VK_SUCCESS)
1896*61046927SAndroid Build Coastguard Worker return vk_result;
1897*61046927SAndroid Build Coastguard Worker
1898*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_vs_key(&key, pCreateInfo, p_stage_vs_bin);
1899*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN] =
1900*61046927SAndroid Build Coastguard Worker pipeline_compile_shader_variant(p_stage_vs_bin, &key.base, sizeof(key),
1901*61046927SAndroid Build Coastguard Worker pAllocator, &vk_result);
1902*61046927SAndroid Build Coastguard Worker
1903*61046927SAndroid Build Coastguard Worker return vk_result;
1904*61046927SAndroid Build Coastguard Worker }
1905*61046927SAndroid Build Coastguard Worker
1906*61046927SAndroid Build Coastguard Worker static VkResult
pipeline_compile_geometry_shader(struct v3dv_pipeline * pipeline,const VkAllocationCallbacks * pAllocator,const VkGraphicsPipelineCreateInfo * pCreateInfo)1907*61046927SAndroid Build Coastguard Worker pipeline_compile_geometry_shader(struct v3dv_pipeline *pipeline,
1908*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
1909*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo)
1910*61046927SAndroid Build Coastguard Worker {
1911*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_gs =
1912*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_GEOMETRY];
1913*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_gs_bin =
1914*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_GEOMETRY_BIN];
1915*61046927SAndroid Build Coastguard Worker
1916*61046927SAndroid Build Coastguard Worker assert(p_stage_gs);
1917*61046927SAndroid Build Coastguard Worker assert(p_stage_gs_bin != NULL);
1918*61046927SAndroid Build Coastguard Worker if (p_stage_gs_bin->nir == NULL) {
1919*61046927SAndroid Build Coastguard Worker assert(p_stage_gs->nir);
1920*61046927SAndroid Build Coastguard Worker p_stage_gs_bin->nir = nir_shader_clone(NULL, p_stage_gs->nir);
1921*61046927SAndroid Build Coastguard Worker }
1922*61046927SAndroid Build Coastguard Worker
1923*61046927SAndroid Build Coastguard Worker VkResult vk_result;
1924*61046927SAndroid Build Coastguard Worker struct v3d_gs_key key;
1925*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_gs_key(&key, pCreateInfo, p_stage_gs);
1926*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY] =
1927*61046927SAndroid Build Coastguard Worker pipeline_compile_shader_variant(p_stage_gs, &key.base, sizeof(key),
1928*61046927SAndroid Build Coastguard Worker pAllocator, &vk_result);
1929*61046927SAndroid Build Coastguard Worker if (vk_result != VK_SUCCESS)
1930*61046927SAndroid Build Coastguard Worker return vk_result;
1931*61046927SAndroid Build Coastguard Worker
1932*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_gs_key(&key, pCreateInfo, p_stage_gs_bin);
1933*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN] =
1934*61046927SAndroid Build Coastguard Worker pipeline_compile_shader_variant(p_stage_gs_bin, &key.base, sizeof(key),
1935*61046927SAndroid Build Coastguard Worker pAllocator, &vk_result);
1936*61046927SAndroid Build Coastguard Worker
1937*61046927SAndroid Build Coastguard Worker return vk_result;
1938*61046927SAndroid Build Coastguard Worker }
1939*61046927SAndroid Build Coastguard Worker
1940*61046927SAndroid Build Coastguard Worker static VkResult
pipeline_compile_fragment_shader(struct v3dv_pipeline * pipeline,const VkAllocationCallbacks * pAllocator,const VkGraphicsPipelineCreateInfo * pCreateInfo)1941*61046927SAndroid Build Coastguard Worker pipeline_compile_fragment_shader(struct v3dv_pipeline *pipeline,
1942*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
1943*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo)
1944*61046927SAndroid Build Coastguard Worker {
1945*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_vs =
1946*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_VERTEX];
1947*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_fs =
1948*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_FRAGMENT];
1949*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_gs =
1950*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_GEOMETRY];
1951*61046927SAndroid Build Coastguard Worker
1952*61046927SAndroid Build Coastguard Worker struct v3d_fs_key key;
1953*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_fs_key(&key, pCreateInfo, &pipeline->rendering_info,
1954*61046927SAndroid Build Coastguard Worker p_stage_fs, p_stage_gs != NULL,
1955*61046927SAndroid Build Coastguard Worker get_ucp_enable_mask(p_stage_vs));
1956*61046927SAndroid Build Coastguard Worker
1957*61046927SAndroid Build Coastguard Worker if (key.is_points) {
1958*61046927SAndroid Build Coastguard Worker assert(key.point_coord_upper_left);
1959*61046927SAndroid Build Coastguard Worker NIR_PASS(_, p_stage_fs->nir, v3d_nir_lower_point_coord);
1960*61046927SAndroid Build Coastguard Worker }
1961*61046927SAndroid Build Coastguard Worker
1962*61046927SAndroid Build Coastguard Worker VkResult vk_result;
1963*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT] =
1964*61046927SAndroid Build Coastguard Worker pipeline_compile_shader_variant(p_stage_fs, &key.base, sizeof(key),
1965*61046927SAndroid Build Coastguard Worker pAllocator, &vk_result);
1966*61046927SAndroid Build Coastguard Worker
1967*61046927SAndroid Build Coastguard Worker return vk_result;
1968*61046927SAndroid Build Coastguard Worker }
1969*61046927SAndroid Build Coastguard Worker
1970*61046927SAndroid Build Coastguard Worker static void
pipeline_populate_graphics_key(struct v3dv_pipeline * pipeline,struct v3dv_pipeline_key * key,const VkGraphicsPipelineCreateInfo * pCreateInfo)1971*61046927SAndroid Build Coastguard Worker pipeline_populate_graphics_key(struct v3dv_pipeline *pipeline,
1972*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_key *key,
1973*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo)
1974*61046927SAndroid Build Coastguard Worker {
1975*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = pipeline->device;
1976*61046927SAndroid Build Coastguard Worker assert(device);
1977*61046927SAndroid Build Coastguard Worker
1978*61046927SAndroid Build Coastguard Worker memset(key, 0, sizeof(*key));
1979*61046927SAndroid Build Coastguard Worker
1980*61046927SAndroid Build Coastguard Worker key->line_smooth = pipeline->line_smooth;
1981*61046927SAndroid Build Coastguard Worker
1982*61046927SAndroid Build Coastguard Worker const VkPipelineInputAssemblyStateCreateInfo *ia_info =
1983*61046927SAndroid Build Coastguard Worker pCreateInfo->pInputAssemblyState;
1984*61046927SAndroid Build Coastguard Worker key->topology = vk_to_mesa_prim[ia_info->topology];
1985*61046927SAndroid Build Coastguard Worker
1986*61046927SAndroid Build Coastguard Worker const VkPipelineColorBlendStateCreateInfo *cb_info =
1987*61046927SAndroid Build Coastguard Worker pipeline->rasterization_enabled ? pCreateInfo->pColorBlendState : NULL;
1988*61046927SAndroid Build Coastguard Worker
1989*61046927SAndroid Build Coastguard Worker key->logicop_func = cb_info && cb_info->logicOpEnable == VK_TRUE ?
1990*61046927SAndroid Build Coastguard Worker vk_to_pipe_logicop[cb_info->logicOp] :
1991*61046927SAndroid Build Coastguard Worker PIPE_LOGICOP_COPY;
1992*61046927SAndroid Build Coastguard Worker
1993*61046927SAndroid Build Coastguard Worker /* Multisample rasterization state must be ignored if rasterization
1994*61046927SAndroid Build Coastguard Worker * is disabled.
1995*61046927SAndroid Build Coastguard Worker */
1996*61046927SAndroid Build Coastguard Worker const VkPipelineMultisampleStateCreateInfo *ms_info =
1997*61046927SAndroid Build Coastguard Worker pipeline->rasterization_enabled ? pCreateInfo->pMultisampleState : NULL;
1998*61046927SAndroid Build Coastguard Worker if (ms_info) {
1999*61046927SAndroid Build Coastguard Worker assert(ms_info->rasterizationSamples == VK_SAMPLE_COUNT_1_BIT ||
2000*61046927SAndroid Build Coastguard Worker ms_info->rasterizationSamples == VK_SAMPLE_COUNT_4_BIT);
2001*61046927SAndroid Build Coastguard Worker key->msaa = ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT;
2002*61046927SAndroid Build Coastguard Worker
2003*61046927SAndroid Build Coastguard Worker if (key->msaa)
2004*61046927SAndroid Build Coastguard Worker key->sample_alpha_to_coverage = ms_info->alphaToCoverageEnable;
2005*61046927SAndroid Build Coastguard Worker
2006*61046927SAndroid Build Coastguard Worker key->sample_alpha_to_one = ms_info->alphaToOneEnable;
2007*61046927SAndroid Build Coastguard Worker }
2008*61046927SAndroid Build Coastguard Worker
2009*61046927SAndroid Build Coastguard Worker struct vk_render_pass_state *ri = &pipeline->rendering_info;
2010*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < ri->color_attachment_count; i++) {
2011*61046927SAndroid Build Coastguard Worker if (ri->color_attachment_formats[i] == VK_FORMAT_UNDEFINED)
2012*61046927SAndroid Build Coastguard Worker continue;
2013*61046927SAndroid Build Coastguard Worker
2014*61046927SAndroid Build Coastguard Worker key->cbufs |= 1 << i;
2015*61046927SAndroid Build Coastguard Worker
2016*61046927SAndroid Build Coastguard Worker VkFormat fb_format = ri->color_attachment_formats[i];
2017*61046927SAndroid Build Coastguard Worker enum pipe_format fb_pipe_format = vk_format_to_pipe_format(fb_format);
2018*61046927SAndroid Build Coastguard Worker
2019*61046927SAndroid Build Coastguard Worker /* If logic operations are enabled then we might emit color reads and we
2020*61046927SAndroid Build Coastguard Worker * need to know the color buffer format and swizzle for that
2021*61046927SAndroid Build Coastguard Worker */
2022*61046927SAndroid Build Coastguard Worker if (key->logicop_func != PIPE_LOGICOP_COPY) {
2023*61046927SAndroid Build Coastguard Worker /* Framebuffer formats should be single plane */
2024*61046927SAndroid Build Coastguard Worker assert(vk_format_get_plane_count(fb_format) == 1);
2025*61046927SAndroid Build Coastguard Worker key->color_fmt[i].format = fb_pipe_format;
2026*61046927SAndroid Build Coastguard Worker memcpy(key->color_fmt[i].swizzle,
2027*61046927SAndroid Build Coastguard Worker v3dv_get_format_swizzle(pipeline->device, fb_format, 0),
2028*61046927SAndroid Build Coastguard Worker sizeof(key->color_fmt[i].swizzle));
2029*61046927SAndroid Build Coastguard Worker }
2030*61046927SAndroid Build Coastguard Worker
2031*61046927SAndroid Build Coastguard Worker const struct util_format_description *desc =
2032*61046927SAndroid Build Coastguard Worker vk_format_description(fb_format);
2033*61046927SAndroid Build Coastguard Worker
2034*61046927SAndroid Build Coastguard Worker if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT &&
2035*61046927SAndroid Build Coastguard Worker desc->channel[0].size == 32) {
2036*61046927SAndroid Build Coastguard Worker key->f32_color_rb |= 1 << i;
2037*61046927SAndroid Build Coastguard Worker }
2038*61046927SAndroid Build Coastguard Worker }
2039*61046927SAndroid Build Coastguard Worker
2040*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputStateCreateInfo *vi_info =
2041*61046927SAndroid Build Coastguard Worker pCreateInfo->pVertexInputState;
2042*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < vi_info->vertexAttributeDescriptionCount; i++) {
2043*61046927SAndroid Build Coastguard Worker const VkVertexInputAttributeDescription *desc =
2044*61046927SAndroid Build Coastguard Worker &vi_info->pVertexAttributeDescriptions[i];
2045*61046927SAndroid Build Coastguard Worker assert(desc->location < MAX_VERTEX_ATTRIBS);
2046*61046927SAndroid Build Coastguard Worker if (desc->format == VK_FORMAT_B8G8R8A8_UNORM ||
2047*61046927SAndroid Build Coastguard Worker desc->format == VK_FORMAT_A2R10G10B10_UNORM_PACK32) {
2048*61046927SAndroid Build Coastguard Worker key->va_swap_rb_mask |= 1 << (VERT_ATTRIB_GENERIC0 + desc->location);
2049*61046927SAndroid Build Coastguard Worker }
2050*61046927SAndroid Build Coastguard Worker }
2051*61046927SAndroid Build Coastguard Worker
2052*61046927SAndroid Build Coastguard Worker key->has_multiview = ri->view_mask != 0;
2053*61046927SAndroid Build Coastguard Worker }
2054*61046927SAndroid Build Coastguard Worker
2055*61046927SAndroid Build Coastguard Worker static void
pipeline_populate_compute_key(struct v3dv_pipeline * pipeline,struct v3dv_pipeline_key * key,const VkComputePipelineCreateInfo * pCreateInfo)2056*61046927SAndroid Build Coastguard Worker pipeline_populate_compute_key(struct v3dv_pipeline *pipeline,
2057*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_key *key,
2058*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfo)
2059*61046927SAndroid Build Coastguard Worker {
2060*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = pipeline->device;
2061*61046927SAndroid Build Coastguard Worker assert(device);
2062*61046927SAndroid Build Coastguard Worker
2063*61046927SAndroid Build Coastguard Worker /* We use the same pipeline key for graphics and compute, but we don't need
2064*61046927SAndroid Build Coastguard Worker * to add a field to flag compute keys because this key is not used alone
2065*61046927SAndroid Build Coastguard Worker * to search in the cache, we also use the SPIR-V or the serialized NIR for
2066*61046927SAndroid Build Coastguard Worker * example, which already flags compute shaders.
2067*61046927SAndroid Build Coastguard Worker */
2068*61046927SAndroid Build Coastguard Worker memset(key, 0, sizeof(*key));
2069*61046927SAndroid Build Coastguard Worker }
2070*61046927SAndroid Build Coastguard Worker
2071*61046927SAndroid Build Coastguard Worker static struct v3dv_pipeline_shared_data *
v3dv_pipeline_shared_data_new_empty(const unsigned char sha1_key[20],struct v3dv_pipeline * pipeline,bool is_graphics_pipeline)2072*61046927SAndroid Build Coastguard Worker v3dv_pipeline_shared_data_new_empty(const unsigned char sha1_key[20],
2073*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline,
2074*61046927SAndroid Build Coastguard Worker bool is_graphics_pipeline)
2075*61046927SAndroid Build Coastguard Worker {
2076*61046927SAndroid Build Coastguard Worker /* We create new_entry using the device alloc. Right now shared_data is ref
2077*61046927SAndroid Build Coastguard Worker * and unref by both the pipeline and the pipeline cache, so we can't
2078*61046927SAndroid Build Coastguard Worker * ensure that the cache or pipeline alloc will be available on the last
2079*61046927SAndroid Build Coastguard Worker * unref.
2080*61046927SAndroid Build Coastguard Worker */
2081*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_shared_data *new_entry =
2082*61046927SAndroid Build Coastguard Worker vk_zalloc2(&pipeline->device->vk.alloc, NULL,
2083*61046927SAndroid Build Coastguard Worker sizeof(struct v3dv_pipeline_shared_data), 8,
2084*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2085*61046927SAndroid Build Coastguard Worker
2086*61046927SAndroid Build Coastguard Worker if (new_entry == NULL)
2087*61046927SAndroid Build Coastguard Worker return NULL;
2088*61046927SAndroid Build Coastguard Worker
2089*61046927SAndroid Build Coastguard Worker for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
2090*61046927SAndroid Build Coastguard Worker /* We don't need specific descriptor maps for binning stages we use the
2091*61046927SAndroid Build Coastguard Worker * map for the render stage.
2092*61046927SAndroid Build Coastguard Worker */
2093*61046927SAndroid Build Coastguard Worker if (broadcom_shader_stage_is_binning(stage))
2094*61046927SAndroid Build Coastguard Worker continue;
2095*61046927SAndroid Build Coastguard Worker
2096*61046927SAndroid Build Coastguard Worker if ((is_graphics_pipeline && stage == BROADCOM_SHADER_COMPUTE) ||
2097*61046927SAndroid Build Coastguard Worker (!is_graphics_pipeline && stage != BROADCOM_SHADER_COMPUTE)) {
2098*61046927SAndroid Build Coastguard Worker continue;
2099*61046927SAndroid Build Coastguard Worker }
2100*61046927SAndroid Build Coastguard Worker
2101*61046927SAndroid Build Coastguard Worker if (stage == BROADCOM_SHADER_GEOMETRY &&
2102*61046927SAndroid Build Coastguard Worker !pipeline->stages[BROADCOM_SHADER_GEOMETRY]) {
2103*61046927SAndroid Build Coastguard Worker /* We always inject a custom GS if we have multiview */
2104*61046927SAndroid Build Coastguard Worker if (!pipeline->rendering_info.view_mask)
2105*61046927SAndroid Build Coastguard Worker continue;
2106*61046927SAndroid Build Coastguard Worker }
2107*61046927SAndroid Build Coastguard Worker
2108*61046927SAndroid Build Coastguard Worker struct v3dv_descriptor_maps *new_maps =
2109*61046927SAndroid Build Coastguard Worker vk_zalloc2(&pipeline->device->vk.alloc, NULL,
2110*61046927SAndroid Build Coastguard Worker sizeof(struct v3dv_descriptor_maps), 8,
2111*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2112*61046927SAndroid Build Coastguard Worker
2113*61046927SAndroid Build Coastguard Worker if (new_maps == NULL)
2114*61046927SAndroid Build Coastguard Worker goto fail;
2115*61046927SAndroid Build Coastguard Worker
2116*61046927SAndroid Build Coastguard Worker new_entry->maps[stage] = new_maps;
2117*61046927SAndroid Build Coastguard Worker }
2118*61046927SAndroid Build Coastguard Worker
2119*61046927SAndroid Build Coastguard Worker new_entry->maps[BROADCOM_SHADER_VERTEX_BIN] =
2120*61046927SAndroid Build Coastguard Worker new_entry->maps[BROADCOM_SHADER_VERTEX];
2121*61046927SAndroid Build Coastguard Worker
2122*61046927SAndroid Build Coastguard Worker new_entry->maps[BROADCOM_SHADER_GEOMETRY_BIN] =
2123*61046927SAndroid Build Coastguard Worker new_entry->maps[BROADCOM_SHADER_GEOMETRY];
2124*61046927SAndroid Build Coastguard Worker
2125*61046927SAndroid Build Coastguard Worker new_entry->ref_cnt = 1;
2126*61046927SAndroid Build Coastguard Worker memcpy(new_entry->sha1_key, sha1_key, 20);
2127*61046927SAndroid Build Coastguard Worker
2128*61046927SAndroid Build Coastguard Worker return new_entry;
2129*61046927SAndroid Build Coastguard Worker
2130*61046927SAndroid Build Coastguard Worker fail:
2131*61046927SAndroid Build Coastguard Worker if (new_entry != NULL) {
2132*61046927SAndroid Build Coastguard Worker for (uint8_t stage = 0; stage < BROADCOM_SHADER_STAGES; stage++) {
2133*61046927SAndroid Build Coastguard Worker if (new_entry->maps[stage] != NULL)
2134*61046927SAndroid Build Coastguard Worker vk_free(&pipeline->device->vk.alloc, new_entry->maps[stage]);
2135*61046927SAndroid Build Coastguard Worker }
2136*61046927SAndroid Build Coastguard Worker }
2137*61046927SAndroid Build Coastguard Worker
2138*61046927SAndroid Build Coastguard Worker vk_free(&pipeline->device->vk.alloc, new_entry);
2139*61046927SAndroid Build Coastguard Worker
2140*61046927SAndroid Build Coastguard Worker return NULL;
2141*61046927SAndroid Build Coastguard Worker }
2142*61046927SAndroid Build Coastguard Worker
2143*61046927SAndroid Build Coastguard Worker static void
write_creation_feedback(struct v3dv_pipeline * pipeline,const void * next,const VkPipelineCreationFeedback * pipeline_feedback,uint32_t stage_count,const VkPipelineShaderStageCreateInfo * stages)2144*61046927SAndroid Build Coastguard Worker write_creation_feedback(struct v3dv_pipeline *pipeline,
2145*61046927SAndroid Build Coastguard Worker const void *next,
2146*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedback *pipeline_feedback,
2147*61046927SAndroid Build Coastguard Worker uint32_t stage_count,
2148*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *stages)
2149*61046927SAndroid Build Coastguard Worker {
2150*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedbackCreateInfo *create_feedback =
2151*61046927SAndroid Build Coastguard Worker vk_find_struct_const(next, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
2152*61046927SAndroid Build Coastguard Worker
2153*61046927SAndroid Build Coastguard Worker if (create_feedback) {
2154*61046927SAndroid Build Coastguard Worker typed_memcpy(create_feedback->pPipelineCreationFeedback,
2155*61046927SAndroid Build Coastguard Worker pipeline_feedback,
2156*61046927SAndroid Build Coastguard Worker 1);
2157*61046927SAndroid Build Coastguard Worker
2158*61046927SAndroid Build Coastguard Worker const uint32_t feedback_stage_count =
2159*61046927SAndroid Build Coastguard Worker create_feedback->pipelineStageCreationFeedbackCount;
2160*61046927SAndroid Build Coastguard Worker assert(feedback_stage_count <= stage_count);
2161*61046927SAndroid Build Coastguard Worker
2162*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < feedback_stage_count; i++) {
2163*61046927SAndroid Build Coastguard Worker gl_shader_stage s = vk_to_mesa_shader_stage(stages[i].stage);
2164*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage bs = gl_shader_stage_to_broadcom(s);
2165*61046927SAndroid Build Coastguard Worker
2166*61046927SAndroid Build Coastguard Worker create_feedback->pPipelineStageCreationFeedbacks[i] =
2167*61046927SAndroid Build Coastguard Worker pipeline->stages[bs]->feedback;
2168*61046927SAndroid Build Coastguard Worker
2169*61046927SAndroid Build Coastguard Worker if (broadcom_shader_stage_is_render_with_binning(bs)) {
2170*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage bs_bin =
2171*61046927SAndroid Build Coastguard Worker broadcom_binning_shader_stage_for_render_stage(bs);
2172*61046927SAndroid Build Coastguard Worker create_feedback->pPipelineStageCreationFeedbacks[i].duration +=
2173*61046927SAndroid Build Coastguard Worker pipeline->stages[bs_bin]->feedback.duration;
2174*61046927SAndroid Build Coastguard Worker }
2175*61046927SAndroid Build Coastguard Worker }
2176*61046927SAndroid Build Coastguard Worker }
2177*61046927SAndroid Build Coastguard Worker }
2178*61046927SAndroid Build Coastguard Worker
2179*61046927SAndroid Build Coastguard Worker /* Note that although PrimitiveTopology is now dynamic, it is still safe to
2180*61046927SAndroid Build Coastguard Worker * compute the gs_input/output_primitive from the topology saved at the
2181*61046927SAndroid Build Coastguard Worker * pipeline, as the topology class will not change, because we don't support
2182*61046927SAndroid Build Coastguard Worker * dynamicPrimitiveTopologyUnrestricted
2183*61046927SAndroid Build Coastguard Worker */
2184*61046927SAndroid Build Coastguard Worker static enum mesa_prim
multiview_gs_input_primitive_from_pipeline(struct v3dv_pipeline * pipeline)2185*61046927SAndroid Build Coastguard Worker multiview_gs_input_primitive_from_pipeline(struct v3dv_pipeline *pipeline)
2186*61046927SAndroid Build Coastguard Worker {
2187*61046927SAndroid Build Coastguard Worker switch (pipeline->topology) {
2188*61046927SAndroid Build Coastguard Worker case MESA_PRIM_POINTS:
2189*61046927SAndroid Build Coastguard Worker return MESA_PRIM_POINTS;
2190*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINES:
2191*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINE_STRIP:
2192*61046927SAndroid Build Coastguard Worker return MESA_PRIM_LINES;
2193*61046927SAndroid Build Coastguard Worker case MESA_PRIM_TRIANGLES:
2194*61046927SAndroid Build Coastguard Worker case MESA_PRIM_TRIANGLE_STRIP:
2195*61046927SAndroid Build Coastguard Worker case MESA_PRIM_TRIANGLE_FAN:
2196*61046927SAndroid Build Coastguard Worker return MESA_PRIM_TRIANGLES;
2197*61046927SAndroid Build Coastguard Worker default:
2198*61046927SAndroid Build Coastguard Worker /* Since we don't allow GS with multiview, we can only see non-adjacency
2199*61046927SAndroid Build Coastguard Worker * primitives.
2200*61046927SAndroid Build Coastguard Worker */
2201*61046927SAndroid Build Coastguard Worker unreachable("Unexpected pipeline primitive type");
2202*61046927SAndroid Build Coastguard Worker }
2203*61046927SAndroid Build Coastguard Worker }
2204*61046927SAndroid Build Coastguard Worker
2205*61046927SAndroid Build Coastguard Worker static enum mesa_prim
multiview_gs_output_primitive_from_pipeline(struct v3dv_pipeline * pipeline)2206*61046927SAndroid Build Coastguard Worker multiview_gs_output_primitive_from_pipeline(struct v3dv_pipeline *pipeline)
2207*61046927SAndroid Build Coastguard Worker {
2208*61046927SAndroid Build Coastguard Worker switch (pipeline->topology) {
2209*61046927SAndroid Build Coastguard Worker case MESA_PRIM_POINTS:
2210*61046927SAndroid Build Coastguard Worker return MESA_PRIM_POINTS;
2211*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINES:
2212*61046927SAndroid Build Coastguard Worker case MESA_PRIM_LINE_STRIP:
2213*61046927SAndroid Build Coastguard Worker return MESA_PRIM_LINE_STRIP;
2214*61046927SAndroid Build Coastguard Worker case MESA_PRIM_TRIANGLES:
2215*61046927SAndroid Build Coastguard Worker case MESA_PRIM_TRIANGLE_STRIP:
2216*61046927SAndroid Build Coastguard Worker case MESA_PRIM_TRIANGLE_FAN:
2217*61046927SAndroid Build Coastguard Worker return MESA_PRIM_TRIANGLE_STRIP;
2218*61046927SAndroid Build Coastguard Worker default:
2219*61046927SAndroid Build Coastguard Worker /* Since we don't allow GS with multiview, we can only see non-adjacency
2220*61046927SAndroid Build Coastguard Worker * primitives.
2221*61046927SAndroid Build Coastguard Worker */
2222*61046927SAndroid Build Coastguard Worker unreachable("Unexpected pipeline primitive type");
2223*61046927SAndroid Build Coastguard Worker }
2224*61046927SAndroid Build Coastguard Worker }
2225*61046927SAndroid Build Coastguard Worker
2226*61046927SAndroid Build Coastguard Worker static bool
pipeline_add_multiview_gs(struct v3dv_pipeline * pipeline,struct v3dv_pipeline_cache * cache,const VkAllocationCallbacks * pAllocator)2227*61046927SAndroid Build Coastguard Worker pipeline_add_multiview_gs(struct v3dv_pipeline *pipeline,
2228*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_cache *cache,
2229*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
2230*61046927SAndroid Build Coastguard Worker {
2231*61046927SAndroid Build Coastguard Worker /* Create the passthrough GS from the VS output interface */
2232*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_vs = pipeline->stages[BROADCOM_SHADER_VERTEX];
2233*61046927SAndroid Build Coastguard Worker p_stage_vs->nir = pipeline_stage_get_nir(p_stage_vs, pipeline, cache);
2234*61046927SAndroid Build Coastguard Worker nir_shader *vs_nir = p_stage_vs->nir;
2235*61046927SAndroid Build Coastguard Worker
2236*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *options =
2237*61046927SAndroid Build Coastguard Worker v3dv_pipeline_get_nir_options(&pipeline->device->devinfo);
2238*61046927SAndroid Build Coastguard Worker nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_GEOMETRY, options,
2239*61046927SAndroid Build Coastguard Worker "multiview broadcast gs");
2240*61046927SAndroid Build Coastguard Worker nir_shader *nir = b.shader;
2241*61046927SAndroid Build Coastguard Worker nir->info.inputs_read = vs_nir->info.outputs_written;
2242*61046927SAndroid Build Coastguard Worker nir->info.outputs_written = vs_nir->info.outputs_written |
2243*61046927SAndroid Build Coastguard Worker (1ull << VARYING_SLOT_LAYER);
2244*61046927SAndroid Build Coastguard Worker
2245*61046927SAndroid Build Coastguard Worker uint32_t vertex_count = mesa_vertices_per_prim(pipeline->topology);
2246*61046927SAndroid Build Coastguard Worker nir->info.gs.input_primitive =
2247*61046927SAndroid Build Coastguard Worker multiview_gs_input_primitive_from_pipeline(pipeline);
2248*61046927SAndroid Build Coastguard Worker nir->info.gs.output_primitive =
2249*61046927SAndroid Build Coastguard Worker multiview_gs_output_primitive_from_pipeline(pipeline);
2250*61046927SAndroid Build Coastguard Worker nir->info.gs.vertices_in = vertex_count;
2251*61046927SAndroid Build Coastguard Worker nir->info.gs.vertices_out = nir->info.gs.vertices_in;
2252*61046927SAndroid Build Coastguard Worker nir->info.gs.invocations = 1;
2253*61046927SAndroid Build Coastguard Worker nir->info.gs.active_stream_mask = 0x1;
2254*61046927SAndroid Build Coastguard Worker
2255*61046927SAndroid Build Coastguard Worker /* Make a list of GS input/output variables from the VS outputs */
2256*61046927SAndroid Build Coastguard Worker nir_variable *in_vars[100];
2257*61046927SAndroid Build Coastguard Worker nir_variable *out_vars[100];
2258*61046927SAndroid Build Coastguard Worker uint32_t var_count = 0;
2259*61046927SAndroid Build Coastguard Worker nir_foreach_shader_out_variable(out_vs_var, vs_nir) {
2260*61046927SAndroid Build Coastguard Worker char name[8];
2261*61046927SAndroid Build Coastguard Worker snprintf(name, ARRAY_SIZE(name), "in_%d", var_count);
2262*61046927SAndroid Build Coastguard Worker
2263*61046927SAndroid Build Coastguard Worker in_vars[var_count] =
2264*61046927SAndroid Build Coastguard Worker nir_variable_create(nir, nir_var_shader_in,
2265*61046927SAndroid Build Coastguard Worker glsl_array_type(out_vs_var->type, vertex_count, 0),
2266*61046927SAndroid Build Coastguard Worker name);
2267*61046927SAndroid Build Coastguard Worker in_vars[var_count]->data.location = out_vs_var->data.location;
2268*61046927SAndroid Build Coastguard Worker in_vars[var_count]->data.location_frac = out_vs_var->data.location_frac;
2269*61046927SAndroid Build Coastguard Worker in_vars[var_count]->data.interpolation = out_vs_var->data.interpolation;
2270*61046927SAndroid Build Coastguard Worker
2271*61046927SAndroid Build Coastguard Worker snprintf(name, ARRAY_SIZE(name), "out_%d", var_count);
2272*61046927SAndroid Build Coastguard Worker out_vars[var_count] =
2273*61046927SAndroid Build Coastguard Worker nir_variable_create(nir, nir_var_shader_out, out_vs_var->type, name);
2274*61046927SAndroid Build Coastguard Worker out_vars[var_count]->data.location = out_vs_var->data.location;
2275*61046927SAndroid Build Coastguard Worker out_vars[var_count]->data.interpolation = out_vs_var->data.interpolation;
2276*61046927SAndroid Build Coastguard Worker
2277*61046927SAndroid Build Coastguard Worker var_count++;
2278*61046927SAndroid Build Coastguard Worker }
2279*61046927SAndroid Build Coastguard Worker
2280*61046927SAndroid Build Coastguard Worker /* Add the gl_Layer output variable */
2281*61046927SAndroid Build Coastguard Worker nir_variable *out_layer =
2282*61046927SAndroid Build Coastguard Worker nir_variable_create(nir, nir_var_shader_out, glsl_int_type(),
2283*61046927SAndroid Build Coastguard Worker "out_Layer");
2284*61046927SAndroid Build Coastguard Worker out_layer->data.location = VARYING_SLOT_LAYER;
2285*61046927SAndroid Build Coastguard Worker
2286*61046927SAndroid Build Coastguard Worker /* Get the view index value that we will write to gl_Layer */
2287*61046927SAndroid Build Coastguard Worker nir_def *layer =
2288*61046927SAndroid Build Coastguard Worker nir_load_system_value(&b, nir_intrinsic_load_view_index, 0, 1, 32);
2289*61046927SAndroid Build Coastguard Worker
2290*61046927SAndroid Build Coastguard Worker /* Emit all output vertices */
2291*61046927SAndroid Build Coastguard Worker for (uint32_t vi = 0; vi < vertex_count; vi++) {
2292*61046927SAndroid Build Coastguard Worker /* Emit all output varyings */
2293*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < var_count; i++) {
2294*61046927SAndroid Build Coastguard Worker nir_deref_instr *in_value =
2295*61046927SAndroid Build Coastguard Worker nir_build_deref_array_imm(&b, nir_build_deref_var(&b, in_vars[i]), vi);
2296*61046927SAndroid Build Coastguard Worker nir_copy_deref(&b, nir_build_deref_var(&b, out_vars[i]), in_value);
2297*61046927SAndroid Build Coastguard Worker }
2298*61046927SAndroid Build Coastguard Worker
2299*61046927SAndroid Build Coastguard Worker /* Emit gl_Layer write */
2300*61046927SAndroid Build Coastguard Worker nir_store_var(&b, out_layer, layer, 0x1);
2301*61046927SAndroid Build Coastguard Worker
2302*61046927SAndroid Build Coastguard Worker nir_emit_vertex(&b, 0);
2303*61046927SAndroid Build Coastguard Worker }
2304*61046927SAndroid Build Coastguard Worker nir_end_primitive(&b, 0);
2305*61046927SAndroid Build Coastguard Worker
2306*61046927SAndroid Build Coastguard Worker /* Make sure we run our pre-process NIR passes so we produce NIR compatible
2307*61046927SAndroid Build Coastguard Worker * with what we expect from SPIR-V modules.
2308*61046927SAndroid Build Coastguard Worker */
2309*61046927SAndroid Build Coastguard Worker preprocess_nir(nir);
2310*61046927SAndroid Build Coastguard Worker
2311*61046927SAndroid Build Coastguard Worker /* Attach the geometry shader to the pipeline */
2312*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = pipeline->device;
2313*61046927SAndroid Build Coastguard Worker struct v3dv_physical_device *physical_device = device->pdevice;
2314*61046927SAndroid Build Coastguard Worker
2315*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage =
2316*61046927SAndroid Build Coastguard Worker vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
2317*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2318*61046927SAndroid Build Coastguard Worker
2319*61046927SAndroid Build Coastguard Worker if (p_stage == NULL) {
2320*61046927SAndroid Build Coastguard Worker ralloc_free(nir);
2321*61046927SAndroid Build Coastguard Worker return false;
2322*61046927SAndroid Build Coastguard Worker }
2323*61046927SAndroid Build Coastguard Worker
2324*61046927SAndroid Build Coastguard Worker p_stage->pipeline = pipeline;
2325*61046927SAndroid Build Coastguard Worker p_stage->stage = BROADCOM_SHADER_GEOMETRY;
2326*61046927SAndroid Build Coastguard Worker p_stage->entrypoint = "main";
2327*61046927SAndroid Build Coastguard Worker p_stage->module = NULL;
2328*61046927SAndroid Build Coastguard Worker p_stage->module_info = NULL;
2329*61046927SAndroid Build Coastguard Worker p_stage->nir = nir;
2330*61046927SAndroid Build Coastguard Worker pipeline_compute_sha1_from_nir(p_stage);
2331*61046927SAndroid Build Coastguard Worker p_stage->program_id = p_atomic_inc_return(&physical_device->next_program_id);
2332*61046927SAndroid Build Coastguard Worker p_stage->robustness = pipeline->stages[BROADCOM_SHADER_VERTEX]->robustness;
2333*61046927SAndroid Build Coastguard Worker
2334*61046927SAndroid Build Coastguard Worker pipeline->has_gs = true;
2335*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_GEOMETRY] = p_stage;
2336*61046927SAndroid Build Coastguard Worker pipeline->active_stages |= MESA_SHADER_GEOMETRY;
2337*61046927SAndroid Build Coastguard Worker
2338*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_GEOMETRY_BIN] =
2339*61046927SAndroid Build Coastguard Worker pipeline_stage_create_binning(p_stage, pAllocator);
2340*61046927SAndroid Build Coastguard Worker if (pipeline->stages[BROADCOM_SHADER_GEOMETRY_BIN] == NULL)
2341*61046927SAndroid Build Coastguard Worker return false;
2342*61046927SAndroid Build Coastguard Worker
2343*61046927SAndroid Build Coastguard Worker return true;
2344*61046927SAndroid Build Coastguard Worker }
2345*61046927SAndroid Build Coastguard Worker
2346*61046927SAndroid Build Coastguard Worker static void
pipeline_check_buffer_device_address(struct v3dv_pipeline * pipeline)2347*61046927SAndroid Build Coastguard Worker pipeline_check_buffer_device_address(struct v3dv_pipeline *pipeline)
2348*61046927SAndroid Build Coastguard Worker {
2349*61046927SAndroid Build Coastguard Worker for (int i = BROADCOM_SHADER_VERTEX; i < BROADCOM_SHADER_STAGES; i++) {
2350*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant = pipeline->shared_data->variants[i];
2351*61046927SAndroid Build Coastguard Worker if (variant && variant->prog_data.base->has_global_address) {
2352*61046927SAndroid Build Coastguard Worker pipeline->uses_buffer_device_address = true;
2353*61046927SAndroid Build Coastguard Worker return;
2354*61046927SAndroid Build Coastguard Worker }
2355*61046927SAndroid Build Coastguard Worker }
2356*61046927SAndroid Build Coastguard Worker
2357*61046927SAndroid Build Coastguard Worker pipeline->uses_buffer_device_address = false;
2358*61046927SAndroid Build Coastguard Worker }
2359*61046927SAndroid Build Coastguard Worker
2360*61046927SAndroid Build Coastguard Worker /*
2361*61046927SAndroid Build Coastguard Worker * It compiles a pipeline. Note that it also allocate internal object, but if
2362*61046927SAndroid Build Coastguard Worker * some allocations success, but other fails, the method is not freeing the
2363*61046927SAndroid Build Coastguard Worker * successful ones.
2364*61046927SAndroid Build Coastguard Worker *
2365*61046927SAndroid Build Coastguard Worker * This is done to simplify the code, as what we do in this case is just call
2366*61046927SAndroid Build Coastguard Worker * the pipeline destroy method, and this would handle freeing the internal
2367*61046927SAndroid Build Coastguard Worker * objects allocated. We just need to be careful setting to NULL the objects
2368*61046927SAndroid Build Coastguard Worker * not allocated.
2369*61046927SAndroid Build Coastguard Worker */
2370*61046927SAndroid Build Coastguard Worker static VkResult
pipeline_compile_graphics(struct v3dv_pipeline * pipeline,struct v3dv_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)2371*61046927SAndroid Build Coastguard Worker pipeline_compile_graphics(struct v3dv_pipeline *pipeline,
2372*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_cache *cache,
2373*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
2374*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
2375*61046927SAndroid Build Coastguard Worker {
2376*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
2377*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
2378*61046927SAndroid Build Coastguard Worker };
2379*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
2380*61046927SAndroid Build Coastguard Worker
2381*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = pipeline->device;
2382*61046927SAndroid Build Coastguard Worker struct v3dv_physical_device *physical_device = device->pdevice;
2383*61046927SAndroid Build Coastguard Worker
2384*61046927SAndroid Build Coastguard Worker /* First pass to get some common info from the shader, and create the
2385*61046927SAndroid Build Coastguard Worker * individual pipeline_stage objects
2386*61046927SAndroid Build Coastguard Worker */
2387*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
2388*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
2389*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
2390*61046927SAndroid Build Coastguard Worker
2391*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage =
2392*61046927SAndroid Build Coastguard Worker vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
2393*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2394*61046927SAndroid Build Coastguard Worker
2395*61046927SAndroid Build Coastguard Worker if (p_stage == NULL)
2396*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
2397*61046927SAndroid Build Coastguard Worker
2398*61046927SAndroid Build Coastguard Worker p_stage->program_id =
2399*61046927SAndroid Build Coastguard Worker p_atomic_inc_return(&physical_device->next_program_id);
2400*61046927SAndroid Build Coastguard Worker
2401*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage broadcom_stage =
2402*61046927SAndroid Build Coastguard Worker gl_shader_stage_to_broadcom(stage);
2403*61046927SAndroid Build Coastguard Worker
2404*61046927SAndroid Build Coastguard Worker p_stage->pipeline = pipeline;
2405*61046927SAndroid Build Coastguard Worker p_stage->stage = broadcom_stage;
2406*61046927SAndroid Build Coastguard Worker p_stage->entrypoint = sinfo->pName;
2407*61046927SAndroid Build Coastguard Worker p_stage->module = vk_shader_module_from_handle(sinfo->module);
2408*61046927SAndroid Build Coastguard Worker p_stage->spec_info = sinfo->pSpecializationInfo;
2409*61046927SAndroid Build Coastguard Worker if (!p_stage->module) {
2410*61046927SAndroid Build Coastguard Worker p_stage->module_info =
2411*61046927SAndroid Build Coastguard Worker vk_find_struct_const(sinfo->pNext, SHADER_MODULE_CREATE_INFO);
2412*61046927SAndroid Build Coastguard Worker }
2413*61046927SAndroid Build Coastguard Worker
2414*61046927SAndroid Build Coastguard Worker vk_pipeline_robustness_state_fill(&device->vk, &p_stage->robustness,
2415*61046927SAndroid Build Coastguard Worker pCreateInfo->pNext, sinfo->pNext);
2416*61046927SAndroid Build Coastguard Worker
2417*61046927SAndroid Build Coastguard Worker vk_pipeline_hash_shader_stage(pipeline->flags,
2418*61046927SAndroid Build Coastguard Worker &pCreateInfo->pStages[i],
2419*61046927SAndroid Build Coastguard Worker &p_stage->robustness,
2420*61046927SAndroid Build Coastguard Worker p_stage->shader_sha1);
2421*61046927SAndroid Build Coastguard Worker
2422*61046927SAndroid Build Coastguard Worker pipeline->active_stages |= sinfo->stage;
2423*61046927SAndroid Build Coastguard Worker
2424*61046927SAndroid Build Coastguard Worker /* We will try to get directly the compiled shader variant, so let's not
2425*61046927SAndroid Build Coastguard Worker * worry about getting the nir shader for now.
2426*61046927SAndroid Build Coastguard Worker */
2427*61046927SAndroid Build Coastguard Worker p_stage->nir = NULL;
2428*61046927SAndroid Build Coastguard Worker pipeline->stages[broadcom_stage] = p_stage;
2429*61046927SAndroid Build Coastguard Worker if (broadcom_stage == BROADCOM_SHADER_GEOMETRY)
2430*61046927SAndroid Build Coastguard Worker pipeline->has_gs = true;
2431*61046927SAndroid Build Coastguard Worker
2432*61046927SAndroid Build Coastguard Worker if (broadcom_shader_stage_is_render_with_binning(broadcom_stage)) {
2433*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage broadcom_stage_bin =
2434*61046927SAndroid Build Coastguard Worker broadcom_binning_shader_stage_for_render_stage(broadcom_stage);
2435*61046927SAndroid Build Coastguard Worker
2436*61046927SAndroid Build Coastguard Worker pipeline->stages[broadcom_stage_bin] =
2437*61046927SAndroid Build Coastguard Worker pipeline_stage_create_binning(p_stage, pAllocator);
2438*61046927SAndroid Build Coastguard Worker
2439*61046927SAndroid Build Coastguard Worker if (pipeline->stages[broadcom_stage_bin] == NULL)
2440*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
2441*61046927SAndroid Build Coastguard Worker }
2442*61046927SAndroid Build Coastguard Worker }
2443*61046927SAndroid Build Coastguard Worker
2444*61046927SAndroid Build Coastguard Worker /* Add a no-op fragment shader if needed */
2445*61046927SAndroid Build Coastguard Worker if (!pipeline->stages[BROADCOM_SHADER_FRAGMENT]) {
2446*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *compiler_options =
2447*61046927SAndroid Build Coastguard Worker v3dv_pipeline_get_nir_options(&pipeline->device->devinfo);
2448*61046927SAndroid Build Coastguard Worker nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT,
2449*61046927SAndroid Build Coastguard Worker compiler_options,
2450*61046927SAndroid Build Coastguard Worker "noop_fs");
2451*61046927SAndroid Build Coastguard Worker
2452*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage =
2453*61046927SAndroid Build Coastguard Worker vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*p_stage), 8,
2454*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2455*61046927SAndroid Build Coastguard Worker
2456*61046927SAndroid Build Coastguard Worker if (p_stage == NULL)
2457*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
2458*61046927SAndroid Build Coastguard Worker
2459*61046927SAndroid Build Coastguard Worker p_stage->pipeline = pipeline;
2460*61046927SAndroid Build Coastguard Worker p_stage->stage = BROADCOM_SHADER_FRAGMENT;
2461*61046927SAndroid Build Coastguard Worker p_stage->entrypoint = "main";
2462*61046927SAndroid Build Coastguard Worker p_stage->module = NULL;
2463*61046927SAndroid Build Coastguard Worker p_stage->module_info = NULL;
2464*61046927SAndroid Build Coastguard Worker p_stage->nir = b.shader;
2465*61046927SAndroid Build Coastguard Worker vk_pipeline_robustness_state_fill(&device->vk, &p_stage->robustness,
2466*61046927SAndroid Build Coastguard Worker NULL, NULL);
2467*61046927SAndroid Build Coastguard Worker pipeline_compute_sha1_from_nir(p_stage);
2468*61046927SAndroid Build Coastguard Worker p_stage->program_id =
2469*61046927SAndroid Build Coastguard Worker p_atomic_inc_return(&physical_device->next_program_id);
2470*61046927SAndroid Build Coastguard Worker
2471*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_FRAGMENT] = p_stage;
2472*61046927SAndroid Build Coastguard Worker pipeline->active_stages |= MESA_SHADER_FRAGMENT;
2473*61046927SAndroid Build Coastguard Worker }
2474*61046927SAndroid Build Coastguard Worker
2475*61046927SAndroid Build Coastguard Worker /* If multiview is enabled, we inject a custom passthrough geometry shader
2476*61046927SAndroid Build Coastguard Worker * to broadcast draw calls to the appropriate views.
2477*61046927SAndroid Build Coastguard Worker */
2478*61046927SAndroid Build Coastguard Worker const uint32_t view_mask = pipeline->rendering_info.view_mask;
2479*61046927SAndroid Build Coastguard Worker assert(!view_mask ||
2480*61046927SAndroid Build Coastguard Worker (!pipeline->has_gs && !pipeline->stages[BROADCOM_SHADER_GEOMETRY]));
2481*61046927SAndroid Build Coastguard Worker if (view_mask) {
2482*61046927SAndroid Build Coastguard Worker if (!pipeline_add_multiview_gs(pipeline, cache, pAllocator))
2483*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
2484*61046927SAndroid Build Coastguard Worker }
2485*61046927SAndroid Build Coastguard Worker
2486*61046927SAndroid Build Coastguard Worker /* First we try to get the variants from the pipeline cache (unless we are
2487*61046927SAndroid Build Coastguard Worker * required to capture internal representations, since in that case we need
2488*61046927SAndroid Build Coastguard Worker * compile).
2489*61046927SAndroid Build Coastguard Worker */
2490*61046927SAndroid Build Coastguard Worker bool needs_executable_info =
2491*61046927SAndroid Build Coastguard Worker pipeline->flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
2492*61046927SAndroid Build Coastguard Worker if (!needs_executable_info) {
2493*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_key pipeline_key;
2494*61046927SAndroid Build Coastguard Worker pipeline_populate_graphics_key(pipeline, &pipeline_key, pCreateInfo);
2495*61046927SAndroid Build Coastguard Worker pipeline_hash_graphics(pipeline, &pipeline_key, pipeline->sha1);
2496*61046927SAndroid Build Coastguard Worker
2497*61046927SAndroid Build Coastguard Worker bool cache_hit = false;
2498*61046927SAndroid Build Coastguard Worker
2499*61046927SAndroid Build Coastguard Worker pipeline->shared_data =
2500*61046927SAndroid Build Coastguard Worker v3dv_pipeline_cache_search_for_pipeline(cache,
2501*61046927SAndroid Build Coastguard Worker pipeline->sha1,
2502*61046927SAndroid Build Coastguard Worker &cache_hit);
2503*61046927SAndroid Build Coastguard Worker
2504*61046927SAndroid Build Coastguard Worker if (pipeline->shared_data != NULL) {
2505*61046927SAndroid Build Coastguard Worker /* A correct pipeline must have at least a VS and FS */
2506*61046927SAndroid Build Coastguard Worker assert(pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX]);
2507*61046927SAndroid Build Coastguard Worker assert(pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN]);
2508*61046927SAndroid Build Coastguard Worker assert(pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT]);
2509*61046927SAndroid Build Coastguard Worker assert(!pipeline->stages[BROADCOM_SHADER_GEOMETRY] ||
2510*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY]);
2511*61046927SAndroid Build Coastguard Worker assert(!pipeline->stages[BROADCOM_SHADER_GEOMETRY] ||
2512*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN]);
2513*61046927SAndroid Build Coastguard Worker
2514*61046927SAndroid Build Coastguard Worker if (cache_hit && cache != &pipeline->device->default_pipeline_cache)
2515*61046927SAndroid Build Coastguard Worker pipeline_feedback.flags |=
2516*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
2517*61046927SAndroid Build Coastguard Worker
2518*61046927SAndroid Build Coastguard Worker goto success;
2519*61046927SAndroid Build Coastguard Worker }
2520*61046927SAndroid Build Coastguard Worker }
2521*61046927SAndroid Build Coastguard Worker
2522*61046927SAndroid Build Coastguard Worker if (pipeline->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)
2523*61046927SAndroid Build Coastguard Worker return VK_PIPELINE_COMPILE_REQUIRED;
2524*61046927SAndroid Build Coastguard Worker
2525*61046927SAndroid Build Coastguard Worker /* Otherwise we try to get the NIR shaders (either from the original SPIR-V
2526*61046927SAndroid Build Coastguard Worker * shader or the pipeline cache) and compile.
2527*61046927SAndroid Build Coastguard Worker */
2528*61046927SAndroid Build Coastguard Worker pipeline->shared_data =
2529*61046927SAndroid Build Coastguard Worker v3dv_pipeline_shared_data_new_empty(pipeline->sha1, pipeline, true);
2530*61046927SAndroid Build Coastguard Worker if (!pipeline->shared_data)
2531*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
2532*61046927SAndroid Build Coastguard Worker
2533*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_vs = pipeline->stages[BROADCOM_SHADER_VERTEX];
2534*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_fs = pipeline->stages[BROADCOM_SHADER_FRAGMENT];
2535*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage_gs = pipeline->stages[BROADCOM_SHADER_GEOMETRY];
2536*61046927SAndroid Build Coastguard Worker
2537*61046927SAndroid Build Coastguard Worker p_stage_vs->feedback.flags |=
2538*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
2539*61046927SAndroid Build Coastguard Worker if (p_stage_gs)
2540*61046927SAndroid Build Coastguard Worker p_stage_gs->feedback.flags |=
2541*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
2542*61046927SAndroid Build Coastguard Worker p_stage_fs->feedback.flags |=
2543*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
2544*61046927SAndroid Build Coastguard Worker
2545*61046927SAndroid Build Coastguard Worker if (!p_stage_vs->nir)
2546*61046927SAndroid Build Coastguard Worker p_stage_vs->nir = pipeline_stage_get_nir(p_stage_vs, pipeline, cache);
2547*61046927SAndroid Build Coastguard Worker if (p_stage_gs && !p_stage_gs->nir)
2548*61046927SAndroid Build Coastguard Worker p_stage_gs->nir = pipeline_stage_get_nir(p_stage_gs, pipeline, cache);
2549*61046927SAndroid Build Coastguard Worker if (!p_stage_fs->nir)
2550*61046927SAndroid Build Coastguard Worker p_stage_fs->nir = pipeline_stage_get_nir(p_stage_fs, pipeline, cache);
2551*61046927SAndroid Build Coastguard Worker
2552*61046927SAndroid Build Coastguard Worker /* Linking + pipeline lowerings */
2553*61046927SAndroid Build Coastguard Worker if (p_stage_gs) {
2554*61046927SAndroid Build Coastguard Worker link_shaders(p_stage_gs->nir, p_stage_fs->nir);
2555*61046927SAndroid Build Coastguard Worker link_shaders(p_stage_vs->nir, p_stage_gs->nir);
2556*61046927SAndroid Build Coastguard Worker } else {
2557*61046927SAndroid Build Coastguard Worker link_shaders(p_stage_vs->nir, p_stage_fs->nir);
2558*61046927SAndroid Build Coastguard Worker }
2559*61046927SAndroid Build Coastguard Worker
2560*61046927SAndroid Build Coastguard Worker pipeline_lower_nir(pipeline, p_stage_fs, pipeline->layout);
2561*61046927SAndroid Build Coastguard Worker lower_fs_io(p_stage_fs->nir);
2562*61046927SAndroid Build Coastguard Worker
2563*61046927SAndroid Build Coastguard Worker if (p_stage_gs) {
2564*61046927SAndroid Build Coastguard Worker pipeline_lower_nir(pipeline, p_stage_gs, pipeline->layout);
2565*61046927SAndroid Build Coastguard Worker lower_gs_io(p_stage_gs->nir);
2566*61046927SAndroid Build Coastguard Worker }
2567*61046927SAndroid Build Coastguard Worker
2568*61046927SAndroid Build Coastguard Worker pipeline_lower_nir(pipeline, p_stage_vs, pipeline->layout);
2569*61046927SAndroid Build Coastguard Worker lower_vs_io(p_stage_vs->nir);
2570*61046927SAndroid Build Coastguard Worker
2571*61046927SAndroid Build Coastguard Worker /* Compiling to vir */
2572*61046927SAndroid Build Coastguard Worker VkResult vk_result;
2573*61046927SAndroid Build Coastguard Worker
2574*61046927SAndroid Build Coastguard Worker /* We should have got all the variants or no variants from the cache */
2575*61046927SAndroid Build Coastguard Worker assert(!pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT]);
2576*61046927SAndroid Build Coastguard Worker vk_result = pipeline_compile_fragment_shader(pipeline, pAllocator,
2577*61046927SAndroid Build Coastguard Worker pCreateInfo);
2578*61046927SAndroid Build Coastguard Worker if (vk_result != VK_SUCCESS)
2579*61046927SAndroid Build Coastguard Worker return vk_result;
2580*61046927SAndroid Build Coastguard Worker
2581*61046927SAndroid Build Coastguard Worker assert(!pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY] &&
2582*61046927SAndroid Build Coastguard Worker !pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN]);
2583*61046927SAndroid Build Coastguard Worker
2584*61046927SAndroid Build Coastguard Worker if (p_stage_gs) {
2585*61046927SAndroid Build Coastguard Worker vk_result =
2586*61046927SAndroid Build Coastguard Worker pipeline_compile_geometry_shader(pipeline, pAllocator, pCreateInfo);
2587*61046927SAndroid Build Coastguard Worker if (vk_result != VK_SUCCESS)
2588*61046927SAndroid Build Coastguard Worker return vk_result;
2589*61046927SAndroid Build Coastguard Worker }
2590*61046927SAndroid Build Coastguard Worker
2591*61046927SAndroid Build Coastguard Worker assert(!pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX] &&
2592*61046927SAndroid Build Coastguard Worker !pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX_BIN]);
2593*61046927SAndroid Build Coastguard Worker
2594*61046927SAndroid Build Coastguard Worker vk_result = pipeline_compile_vertex_shader(pipeline, pAllocator, pCreateInfo);
2595*61046927SAndroid Build Coastguard Worker if (vk_result != VK_SUCCESS)
2596*61046927SAndroid Build Coastguard Worker return vk_result;
2597*61046927SAndroid Build Coastguard Worker
2598*61046927SAndroid Build Coastguard Worker if (!upload_assembly(pipeline))
2599*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2600*61046927SAndroid Build Coastguard Worker
2601*61046927SAndroid Build Coastguard Worker v3dv_pipeline_cache_upload_pipeline(pipeline, cache);
2602*61046927SAndroid Build Coastguard Worker
2603*61046927SAndroid Build Coastguard Worker success:
2604*61046927SAndroid Build Coastguard Worker
2605*61046927SAndroid Build Coastguard Worker pipeline_check_buffer_device_address(pipeline);
2606*61046927SAndroid Build Coastguard Worker
2607*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
2608*61046927SAndroid Build Coastguard Worker write_creation_feedback(pipeline,
2609*61046927SAndroid Build Coastguard Worker pCreateInfo->pNext,
2610*61046927SAndroid Build Coastguard Worker &pipeline_feedback,
2611*61046927SAndroid Build Coastguard Worker pCreateInfo->stageCount,
2612*61046927SAndroid Build Coastguard Worker pCreateInfo->pStages);
2613*61046927SAndroid Build Coastguard Worker
2614*61046927SAndroid Build Coastguard Worker /* Since we have the variants in the pipeline shared data we can now free
2615*61046927SAndroid Build Coastguard Worker * the pipeline stages.
2616*61046927SAndroid Build Coastguard Worker */
2617*61046927SAndroid Build Coastguard Worker if (!needs_executable_info)
2618*61046927SAndroid Build Coastguard Worker pipeline_free_stages(device, pipeline, pAllocator);
2619*61046927SAndroid Build Coastguard Worker
2620*61046927SAndroid Build Coastguard Worker pipeline_check_spill_size(pipeline);
2621*61046927SAndroid Build Coastguard Worker
2622*61046927SAndroid Build Coastguard Worker return compute_vpm_config(pipeline);
2623*61046927SAndroid Build Coastguard Worker }
2624*61046927SAndroid Build Coastguard Worker
2625*61046927SAndroid Build Coastguard Worker static VkResult
compute_vpm_config(struct v3dv_pipeline * pipeline)2626*61046927SAndroid Build Coastguard Worker compute_vpm_config(struct v3dv_pipeline *pipeline)
2627*61046927SAndroid Build Coastguard Worker {
2628*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *vs_variant =
2629*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX];
2630*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *vs_bin_variant =
2631*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_VERTEX];
2632*61046927SAndroid Build Coastguard Worker struct v3d_vs_prog_data *vs = vs_variant->prog_data.vs;
2633*61046927SAndroid Build Coastguard Worker struct v3d_vs_prog_data *vs_bin =vs_bin_variant->prog_data.vs;
2634*61046927SAndroid Build Coastguard Worker
2635*61046927SAndroid Build Coastguard Worker struct v3d_gs_prog_data *gs = NULL;
2636*61046927SAndroid Build Coastguard Worker struct v3d_gs_prog_data *gs_bin = NULL;
2637*61046927SAndroid Build Coastguard Worker if (pipeline->has_gs) {
2638*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *gs_variant =
2639*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY];
2640*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *gs_bin_variant =
2641*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_GEOMETRY_BIN];
2642*61046927SAndroid Build Coastguard Worker gs = gs_variant->prog_data.gs;
2643*61046927SAndroid Build Coastguard Worker gs_bin = gs_bin_variant->prog_data.gs;
2644*61046927SAndroid Build Coastguard Worker }
2645*61046927SAndroid Build Coastguard Worker
2646*61046927SAndroid Build Coastguard Worker if (!v3d_compute_vpm_config(&pipeline->device->devinfo,
2647*61046927SAndroid Build Coastguard Worker vs_bin, vs, gs_bin, gs,
2648*61046927SAndroid Build Coastguard Worker &pipeline->vpm_cfg_bin,
2649*61046927SAndroid Build Coastguard Worker &pipeline->vpm_cfg)) {
2650*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2651*61046927SAndroid Build Coastguard Worker }
2652*61046927SAndroid Build Coastguard Worker
2653*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2654*61046927SAndroid Build Coastguard Worker }
2655*61046927SAndroid Build Coastguard Worker
2656*61046927SAndroid Build Coastguard Worker static bool
stencil_op_is_no_op(struct vk_stencil_test_face_state * stencil)2657*61046927SAndroid Build Coastguard Worker stencil_op_is_no_op(struct vk_stencil_test_face_state *stencil)
2658*61046927SAndroid Build Coastguard Worker {
2659*61046927SAndroid Build Coastguard Worker return stencil->op.depth_fail == VK_STENCIL_OP_KEEP &&
2660*61046927SAndroid Build Coastguard Worker stencil->op.compare == VK_COMPARE_OP_ALWAYS;
2661*61046927SAndroid Build Coastguard Worker }
2662*61046927SAndroid Build Coastguard Worker
2663*61046927SAndroid Build Coastguard Worker /* Computes the ez_state based on a given vk_dynamic_graphics_state. Note
2664*61046927SAndroid Build Coastguard Worker * that the parameter dyn doesn't need to be pipeline->dynamic_graphics_state,
2665*61046927SAndroid Build Coastguard Worker * as this method can be used by the cmd_buffer too.
2666*61046927SAndroid Build Coastguard Worker */
2667*61046927SAndroid Build Coastguard Worker void
v3dv_compute_ez_state(struct vk_dynamic_graphics_state * dyn,struct v3dv_pipeline * pipeline,enum v3dv_ez_state * ez_state,bool * incompatible_ez_test)2668*61046927SAndroid Build Coastguard Worker v3dv_compute_ez_state(struct vk_dynamic_graphics_state *dyn,
2669*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline,
2670*61046927SAndroid Build Coastguard Worker enum v3dv_ez_state *ez_state,
2671*61046927SAndroid Build Coastguard Worker bool *incompatible_ez_test)
2672*61046927SAndroid Build Coastguard Worker {
2673*61046927SAndroid Build Coastguard Worker if (!dyn->ds.depth.test_enable) {
2674*61046927SAndroid Build Coastguard Worker *ez_state = V3D_EZ_DISABLED;
2675*61046927SAndroid Build Coastguard Worker return;
2676*61046927SAndroid Build Coastguard Worker }
2677*61046927SAndroid Build Coastguard Worker
2678*61046927SAndroid Build Coastguard Worker switch (dyn->ds.depth.compare_op) {
2679*61046927SAndroid Build Coastguard Worker case VK_COMPARE_OP_LESS:
2680*61046927SAndroid Build Coastguard Worker case VK_COMPARE_OP_LESS_OR_EQUAL:
2681*61046927SAndroid Build Coastguard Worker *ez_state = V3D_EZ_LT_LE;
2682*61046927SAndroid Build Coastguard Worker break;
2683*61046927SAndroid Build Coastguard Worker case VK_COMPARE_OP_GREATER:
2684*61046927SAndroid Build Coastguard Worker case VK_COMPARE_OP_GREATER_OR_EQUAL:
2685*61046927SAndroid Build Coastguard Worker *ez_state = V3D_EZ_GT_GE;
2686*61046927SAndroid Build Coastguard Worker break;
2687*61046927SAndroid Build Coastguard Worker case VK_COMPARE_OP_NEVER:
2688*61046927SAndroid Build Coastguard Worker case VK_COMPARE_OP_EQUAL:
2689*61046927SAndroid Build Coastguard Worker *ez_state = V3D_EZ_UNDECIDED;
2690*61046927SAndroid Build Coastguard Worker break;
2691*61046927SAndroid Build Coastguard Worker default:
2692*61046927SAndroid Build Coastguard Worker *ez_state = V3D_EZ_DISABLED;
2693*61046927SAndroid Build Coastguard Worker *incompatible_ez_test = true;
2694*61046927SAndroid Build Coastguard Worker break;
2695*61046927SAndroid Build Coastguard Worker }
2696*61046927SAndroid Build Coastguard Worker
2697*61046927SAndroid Build Coastguard Worker /* If stencil is enabled and is not a no-op, we need to disable EZ */
2698*61046927SAndroid Build Coastguard Worker if (dyn->ds.stencil.test_enable &&
2699*61046927SAndroid Build Coastguard Worker (!stencil_op_is_no_op(&dyn->ds.stencil.front) ||
2700*61046927SAndroid Build Coastguard Worker !stencil_op_is_no_op(&dyn->ds.stencil.back))) {
2701*61046927SAndroid Build Coastguard Worker *ez_state = V3D_EZ_DISABLED;
2702*61046927SAndroid Build Coastguard Worker }
2703*61046927SAndroid Build Coastguard Worker
2704*61046927SAndroid Build Coastguard Worker /* If the FS writes Z, then it may update against the chosen EZ direction */
2705*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *fs_variant =
2706*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_FRAGMENT];
2707*61046927SAndroid Build Coastguard Worker if (fs_variant && fs_variant->prog_data.fs->writes_z &&
2708*61046927SAndroid Build Coastguard Worker !fs_variant->prog_data.fs->writes_z_from_fep) {
2709*61046927SAndroid Build Coastguard Worker *ez_state = V3D_EZ_DISABLED;
2710*61046927SAndroid Build Coastguard Worker }
2711*61046927SAndroid Build Coastguard Worker }
2712*61046927SAndroid Build Coastguard Worker
2713*61046927SAndroid Build Coastguard Worker
2714*61046927SAndroid Build Coastguard Worker static void
pipeline_set_sample_mask(struct v3dv_pipeline * pipeline,const VkPipelineMultisampleStateCreateInfo * ms_info)2715*61046927SAndroid Build Coastguard Worker pipeline_set_sample_mask(struct v3dv_pipeline *pipeline,
2716*61046927SAndroid Build Coastguard Worker const VkPipelineMultisampleStateCreateInfo *ms_info)
2717*61046927SAndroid Build Coastguard Worker {
2718*61046927SAndroid Build Coastguard Worker pipeline->sample_mask = (1 << V3D_MAX_SAMPLES) - 1;
2719*61046927SAndroid Build Coastguard Worker
2720*61046927SAndroid Build Coastguard Worker /* Ignore pSampleMask if we are not enabling multisampling. The hardware
2721*61046927SAndroid Build Coastguard Worker * requires this to be 0xf or 0x0 if using a single sample.
2722*61046927SAndroid Build Coastguard Worker */
2723*61046927SAndroid Build Coastguard Worker if (ms_info && ms_info->pSampleMask &&
2724*61046927SAndroid Build Coastguard Worker ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT) {
2725*61046927SAndroid Build Coastguard Worker pipeline->sample_mask &= ms_info->pSampleMask[0];
2726*61046927SAndroid Build Coastguard Worker }
2727*61046927SAndroid Build Coastguard Worker }
2728*61046927SAndroid Build Coastguard Worker
2729*61046927SAndroid Build Coastguard Worker static void
pipeline_set_sample_rate_shading(struct v3dv_pipeline * pipeline,const VkPipelineMultisampleStateCreateInfo * ms_info)2730*61046927SAndroid Build Coastguard Worker pipeline_set_sample_rate_shading(struct v3dv_pipeline *pipeline,
2731*61046927SAndroid Build Coastguard Worker const VkPipelineMultisampleStateCreateInfo *ms_info)
2732*61046927SAndroid Build Coastguard Worker {
2733*61046927SAndroid Build Coastguard Worker pipeline->sample_rate_shading =
2734*61046927SAndroid Build Coastguard Worker ms_info && ms_info->rasterizationSamples > VK_SAMPLE_COUNT_1_BIT &&
2735*61046927SAndroid Build Coastguard Worker ms_info->sampleShadingEnable;
2736*61046927SAndroid Build Coastguard Worker }
2737*61046927SAndroid Build Coastguard Worker
2738*61046927SAndroid Build Coastguard Worker static void
pipeline_setup_rendering_info(struct v3dv_device * device,struct v3dv_pipeline * pipeline,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc)2739*61046927SAndroid Build Coastguard Worker pipeline_setup_rendering_info(struct v3dv_device *device,
2740*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline,
2741*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
2742*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
2743*61046927SAndroid Build Coastguard Worker {
2744*61046927SAndroid Build Coastguard Worker struct vk_render_pass_state *rp = &pipeline->rendering_info;
2745*61046927SAndroid Build Coastguard Worker
2746*61046927SAndroid Build Coastguard Worker if (pipeline->pass) {
2747*61046927SAndroid Build Coastguard Worker assert(pipeline->subpass);
2748*61046927SAndroid Build Coastguard Worker struct v3dv_render_pass *pass = pipeline->pass;
2749*61046927SAndroid Build Coastguard Worker struct v3dv_subpass *subpass = pipeline->subpass;
2750*61046927SAndroid Build Coastguard Worker const uint32_t attachment_idx = subpass->ds_attachment.attachment;
2751*61046927SAndroid Build Coastguard Worker
2752*61046927SAndroid Build Coastguard Worker rp->view_mask = subpass->view_mask;
2753*61046927SAndroid Build Coastguard Worker
2754*61046927SAndroid Build Coastguard Worker rp->depth_attachment_format = VK_FORMAT_UNDEFINED;
2755*61046927SAndroid Build Coastguard Worker rp->stencil_attachment_format = VK_FORMAT_UNDEFINED;
2756*61046927SAndroid Build Coastguard Worker rp->attachments = MESA_VK_RP_ATTACHMENT_NONE;
2757*61046927SAndroid Build Coastguard Worker if (attachment_idx != VK_ATTACHMENT_UNUSED) {
2758*61046927SAndroid Build Coastguard Worker VkFormat ds_format = pass->attachments[attachment_idx].desc.format;
2759*61046927SAndroid Build Coastguard Worker if (vk_format_has_depth(ds_format)) {
2760*61046927SAndroid Build Coastguard Worker rp->depth_attachment_format = ds_format;
2761*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
2762*61046927SAndroid Build Coastguard Worker }
2763*61046927SAndroid Build Coastguard Worker if (vk_format_has_stencil(ds_format)) {
2764*61046927SAndroid Build Coastguard Worker rp->stencil_attachment_format = ds_format;
2765*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
2766*61046927SAndroid Build Coastguard Worker }
2767*61046927SAndroid Build Coastguard Worker }
2768*61046927SAndroid Build Coastguard Worker
2769*61046927SAndroid Build Coastguard Worker rp->color_attachment_count = subpass->color_count;
2770*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < subpass->color_count; i++) {
2771*61046927SAndroid Build Coastguard Worker const uint32_t attachment_idx = subpass->color_attachments[i].attachment;
2772*61046927SAndroid Build Coastguard Worker if (attachment_idx == VK_ATTACHMENT_UNUSED) {
2773*61046927SAndroid Build Coastguard Worker rp->color_attachment_formats[i] = VK_FORMAT_UNDEFINED;
2774*61046927SAndroid Build Coastguard Worker continue;
2775*61046927SAndroid Build Coastguard Worker }
2776*61046927SAndroid Build Coastguard Worker rp->color_attachment_formats[i] =
2777*61046927SAndroid Build Coastguard Worker pass->attachments[attachment_idx].desc.format;
2778*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i);
2779*61046927SAndroid Build Coastguard Worker }
2780*61046927SAndroid Build Coastguard Worker return;
2781*61046927SAndroid Build Coastguard Worker }
2782*61046927SAndroid Build Coastguard Worker
2783*61046927SAndroid Build Coastguard Worker const VkPipelineRenderingCreateInfo *ri =
2784*61046927SAndroid Build Coastguard Worker vk_find_struct_const(pCreateInfo->pNext,
2785*61046927SAndroid Build Coastguard Worker PIPELINE_RENDERING_CREATE_INFO);
2786*61046927SAndroid Build Coastguard Worker if (ri) {
2787*61046927SAndroid Build Coastguard Worker rp->view_mask = ri->viewMask;
2788*61046927SAndroid Build Coastguard Worker
2789*61046927SAndroid Build Coastguard Worker rp->color_attachment_count = ri->colorAttachmentCount;
2790*61046927SAndroid Build Coastguard Worker for (int i = 0; i < ri->colorAttachmentCount; i++) {
2791*61046927SAndroid Build Coastguard Worker rp->color_attachment_formats[i] = ri->pColorAttachmentFormats[i];
2792*61046927SAndroid Build Coastguard Worker if (rp->color_attachment_formats[i] != VK_FORMAT_UNDEFINED) {
2793*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i);
2794*61046927SAndroid Build Coastguard Worker }
2795*61046927SAndroid Build Coastguard Worker }
2796*61046927SAndroid Build Coastguard Worker
2797*61046927SAndroid Build Coastguard Worker rp->depth_attachment_format = ri->depthAttachmentFormat;
2798*61046927SAndroid Build Coastguard Worker if (ri->depthAttachmentFormat != VK_FORMAT_UNDEFINED)
2799*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_DEPTH_BIT;
2800*61046927SAndroid Build Coastguard Worker
2801*61046927SAndroid Build Coastguard Worker rp->stencil_attachment_format = ri->stencilAttachmentFormat;
2802*61046927SAndroid Build Coastguard Worker if (ri->stencilAttachmentFormat != VK_FORMAT_UNDEFINED)
2803*61046927SAndroid Build Coastguard Worker rp->attachments |= MESA_VK_RP_ATTACHMENT_STENCIL_BIT;
2804*61046927SAndroid Build Coastguard Worker
2805*61046927SAndroid Build Coastguard Worker return;
2806*61046927SAndroid Build Coastguard Worker }
2807*61046927SAndroid Build Coastguard Worker
2808*61046927SAndroid Build Coastguard Worker /* From the Vulkan spec for VkPipelineRenderingCreateInfo:
2809*61046927SAndroid Build Coastguard Worker *
2810*61046927SAndroid Build Coastguard Worker * "if this structure is not specified, and the pipeline does not include
2811*61046927SAndroid Build Coastguard Worker * a VkRenderPass, viewMask and colorAttachmentCount are 0, and
2812*61046927SAndroid Build Coastguard Worker * depthAttachmentFormat and stencilAttachmentFormat are
2813*61046927SAndroid Build Coastguard Worker * VK_FORMAT_UNDEFINED.
2814*61046927SAndroid Build Coastguard Worker */
2815*61046927SAndroid Build Coastguard Worker pipeline->rendering_info = (struct vk_render_pass_state) {
2816*61046927SAndroid Build Coastguard Worker .view_mask = 0,
2817*61046927SAndroid Build Coastguard Worker .attachments = 0,
2818*61046927SAndroid Build Coastguard Worker .color_attachment_count = 0,
2819*61046927SAndroid Build Coastguard Worker .depth_attachment_format = VK_FORMAT_UNDEFINED,
2820*61046927SAndroid Build Coastguard Worker .stencil_attachment_format = VK_FORMAT_UNDEFINED,
2821*61046927SAndroid Build Coastguard Worker };
2822*61046927SAndroid Build Coastguard Worker }
2823*61046927SAndroid Build Coastguard Worker
2824*61046927SAndroid Build Coastguard Worker static VkResult
pipeline_init_dynamic_state(struct v3dv_device * device,struct v3dv_pipeline * pipeline,struct vk_graphics_pipeline_all_state * pipeline_all_state,struct vk_graphics_pipeline_state * pipeline_state,const VkGraphicsPipelineCreateInfo * pCreateInfo)2825*61046927SAndroid Build Coastguard Worker pipeline_init_dynamic_state(struct v3dv_device *device,
2826*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline,
2827*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_all_state *pipeline_all_state,
2828*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_state *pipeline_state,
2829*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo)
2830*61046927SAndroid Build Coastguard Worker {
2831*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
2832*61046927SAndroid Build Coastguard Worker result = vk_graphics_pipeline_state_fill(&pipeline->device->vk, pipeline_state,
2833*61046927SAndroid Build Coastguard Worker pCreateInfo, &pipeline->rendering_info, 0,
2834*61046927SAndroid Build Coastguard Worker pipeline_all_state, NULL, 0, NULL);
2835*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2836*61046927SAndroid Build Coastguard Worker return result;
2837*61046927SAndroid Build Coastguard Worker
2838*61046927SAndroid Build Coastguard Worker vk_dynamic_graphics_state_fill(&pipeline->dynamic_graphics_state, pipeline_state);
2839*61046927SAndroid Build Coastguard Worker
2840*61046927SAndroid Build Coastguard Worker struct v3dv_dynamic_state *v3dv_dyn = &pipeline->dynamic;
2841*61046927SAndroid Build Coastguard Worker struct vk_dynamic_graphics_state *dyn = &pipeline->dynamic_graphics_state;
2842*61046927SAndroid Build Coastguard Worker
2843*61046927SAndroid Build Coastguard Worker if (BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_VP_VIEWPORTS) ||
2844*61046927SAndroid Build Coastguard Worker BITSET_TEST(dyn->set, MESA_VK_DYNAMIC_VP_SCISSORS)) {
2845*61046927SAndroid Build Coastguard Worker /* FIXME: right now we don't support multiViewport so viewporst[0] would
2846*61046927SAndroid Build Coastguard Worker * work now, but would need to change if we allow multiple viewports.
2847*61046927SAndroid Build Coastguard Worker */
2848*61046927SAndroid Build Coastguard Worker v3dv_X(device, viewport_compute_xform)(&dyn->vp.viewports[0],
2849*61046927SAndroid Build Coastguard Worker v3dv_dyn->viewport.scale[0],
2850*61046927SAndroid Build Coastguard Worker v3dv_dyn->viewport.translate[0]);
2851*61046927SAndroid Build Coastguard Worker
2852*61046927SAndroid Build Coastguard Worker }
2853*61046927SAndroid Build Coastguard Worker
2854*61046927SAndroid Build Coastguard Worker v3dv_dyn->color_write_enable =
2855*61046927SAndroid Build Coastguard Worker (1ull << (4 * V3D_MAX_RENDER_TARGETS(device->devinfo.ver))) - 1;
2856*61046927SAndroid Build Coastguard Worker if (pipeline_state->cb) {
2857*61046927SAndroid Build Coastguard Worker const uint8_t color_writes = pipeline_state->cb->color_write_enables;
2858*61046927SAndroid Build Coastguard Worker v3dv_dyn->color_write_enable = 0;
2859*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pipeline_state->cb->attachment_count; i++) {
2860*61046927SAndroid Build Coastguard Worker v3dv_dyn->color_write_enable |=
2861*61046927SAndroid Build Coastguard Worker (color_writes & BITFIELD_BIT(i)) ? (0xfu << (i * 4)) : 0;
2862*61046927SAndroid Build Coastguard Worker }
2863*61046927SAndroid Build Coastguard Worker }
2864*61046927SAndroid Build Coastguard Worker
2865*61046927SAndroid Build Coastguard Worker return result;
2866*61046927SAndroid Build Coastguard Worker }
2867*61046927SAndroid Build Coastguard Worker
2868*61046927SAndroid Build Coastguard Worker static VkResult
pipeline_init(struct v3dv_pipeline * pipeline,struct v3dv_device * device,struct v3dv_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator)2869*61046927SAndroid Build Coastguard Worker pipeline_init(struct v3dv_pipeline *pipeline,
2870*61046927SAndroid Build Coastguard Worker struct v3dv_device *device,
2871*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_cache *cache,
2872*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
2873*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
2874*61046927SAndroid Build Coastguard Worker {
2875*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
2876*61046927SAndroid Build Coastguard Worker
2877*61046927SAndroid Build Coastguard Worker pipeline->device = device;
2878*61046927SAndroid Build Coastguard Worker
2879*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline_layout, layout, pCreateInfo->layout);
2880*61046927SAndroid Build Coastguard Worker pipeline->layout = layout;
2881*61046927SAndroid Build Coastguard Worker v3dv_pipeline_layout_ref(pipeline->layout);
2882*61046927SAndroid Build Coastguard Worker
2883*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_render_pass, render_pass, pCreateInfo->renderPass);
2884*61046927SAndroid Build Coastguard Worker if (render_pass) {
2885*61046927SAndroid Build Coastguard Worker assert(pCreateInfo->subpass < render_pass->subpass_count);
2886*61046927SAndroid Build Coastguard Worker pipeline->pass = render_pass;
2887*61046927SAndroid Build Coastguard Worker pipeline->subpass = &render_pass->subpasses[pCreateInfo->subpass];
2888*61046927SAndroid Build Coastguard Worker }
2889*61046927SAndroid Build Coastguard Worker
2890*61046927SAndroid Build Coastguard Worker pipeline_setup_rendering_info(device, pipeline, pCreateInfo, pAllocator);
2891*61046927SAndroid Build Coastguard Worker
2892*61046927SAndroid Build Coastguard Worker const VkPipelineInputAssemblyStateCreateInfo *ia_info =
2893*61046927SAndroid Build Coastguard Worker pCreateInfo->pInputAssemblyState;
2894*61046927SAndroid Build Coastguard Worker pipeline->topology = vk_to_mesa_prim[ia_info->topology];
2895*61046927SAndroid Build Coastguard Worker
2896*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_all_state all;
2897*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_state pipeline_state = { };
2898*61046927SAndroid Build Coastguard Worker result = pipeline_init_dynamic_state(device, pipeline, &all, &pipeline_state,
2899*61046927SAndroid Build Coastguard Worker pCreateInfo);
2900*61046927SAndroid Build Coastguard Worker
2901*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2902*61046927SAndroid Build Coastguard Worker /* Caller would already destroy the pipeline, and we didn't allocate any
2903*61046927SAndroid Build Coastguard Worker * extra info. We don't need to do anything else.
2904*61046927SAndroid Build Coastguard Worker */
2905*61046927SAndroid Build Coastguard Worker return result;
2906*61046927SAndroid Build Coastguard Worker }
2907*61046927SAndroid Build Coastguard Worker
2908*61046927SAndroid Build Coastguard Worker /* If rasterization is disabled, we just disable it through the CFG_BITS
2909*61046927SAndroid Build Coastguard Worker * packet, so for building the pipeline we always assume it is enabled
2910*61046927SAndroid Build Coastguard Worker */
2911*61046927SAndroid Build Coastguard Worker const bool raster_enabled =
2912*61046927SAndroid Build Coastguard Worker (pipeline_state.rs && !pipeline_state.rs->rasterizer_discard_enable) ||
2913*61046927SAndroid Build Coastguard Worker BITSET_TEST(pipeline_state.dynamic, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE);
2914*61046927SAndroid Build Coastguard Worker
2915*61046927SAndroid Build Coastguard Worker pipeline->rasterization_enabled = raster_enabled;
2916*61046927SAndroid Build Coastguard Worker
2917*61046927SAndroid Build Coastguard Worker const VkPipelineViewportStateCreateInfo *vp_info =
2918*61046927SAndroid Build Coastguard Worker raster_enabled ? pCreateInfo->pViewportState : NULL;
2919*61046927SAndroid Build Coastguard Worker
2920*61046927SAndroid Build Coastguard Worker const VkPipelineDepthStencilStateCreateInfo *ds_info =
2921*61046927SAndroid Build Coastguard Worker raster_enabled ? pCreateInfo->pDepthStencilState : NULL;
2922*61046927SAndroid Build Coastguard Worker
2923*61046927SAndroid Build Coastguard Worker const VkPipelineRasterizationStateCreateInfo *rs_info =
2924*61046927SAndroid Build Coastguard Worker raster_enabled ? pCreateInfo->pRasterizationState : NULL;
2925*61046927SAndroid Build Coastguard Worker
2926*61046927SAndroid Build Coastguard Worker const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_info =
2927*61046927SAndroid Build Coastguard Worker raster_enabled ? vk_find_struct_const(
2928*61046927SAndroid Build Coastguard Worker rs_info->pNext,
2929*61046927SAndroid Build Coastguard Worker PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT) :
2930*61046927SAndroid Build Coastguard Worker NULL;
2931*61046927SAndroid Build Coastguard Worker
2932*61046927SAndroid Build Coastguard Worker const VkPipelineRasterizationLineStateCreateInfoEXT *ls_info =
2933*61046927SAndroid Build Coastguard Worker raster_enabled ? vk_find_struct_const(
2934*61046927SAndroid Build Coastguard Worker rs_info->pNext,
2935*61046927SAndroid Build Coastguard Worker PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT) :
2936*61046927SAndroid Build Coastguard Worker NULL;
2937*61046927SAndroid Build Coastguard Worker
2938*61046927SAndroid Build Coastguard Worker const VkPipelineColorBlendStateCreateInfo *cb_info =
2939*61046927SAndroid Build Coastguard Worker raster_enabled ? pCreateInfo->pColorBlendState : NULL;
2940*61046927SAndroid Build Coastguard Worker
2941*61046927SAndroid Build Coastguard Worker const VkPipelineMultisampleStateCreateInfo *ms_info =
2942*61046927SAndroid Build Coastguard Worker raster_enabled ? pCreateInfo->pMultisampleState : NULL;
2943*61046927SAndroid Build Coastguard Worker
2944*61046927SAndroid Build Coastguard Worker const VkPipelineViewportDepthClipControlCreateInfoEXT *depth_clip_control =
2945*61046927SAndroid Build Coastguard Worker vp_info ? vk_find_struct_const(vp_info->pNext,
2946*61046927SAndroid Build Coastguard Worker PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT) :
2947*61046927SAndroid Build Coastguard Worker NULL;
2948*61046927SAndroid Build Coastguard Worker
2949*61046927SAndroid Build Coastguard Worker if (depth_clip_control)
2950*61046927SAndroid Build Coastguard Worker pipeline->negative_one_to_one = depth_clip_control->negativeOneToOne;
2951*61046927SAndroid Build Coastguard Worker
2952*61046927SAndroid Build Coastguard Worker v3dv_X(device, pipeline_pack_state)(pipeline, cb_info, ds_info,
2953*61046927SAndroid Build Coastguard Worker rs_info, pv_info, ls_info,
2954*61046927SAndroid Build Coastguard Worker ms_info,
2955*61046927SAndroid Build Coastguard Worker &pipeline_state);
2956*61046927SAndroid Build Coastguard Worker
2957*61046927SAndroid Build Coastguard Worker pipeline_set_sample_mask(pipeline, ms_info);
2958*61046927SAndroid Build Coastguard Worker pipeline_set_sample_rate_shading(pipeline, ms_info);
2959*61046927SAndroid Build Coastguard Worker pipeline->line_smooth = enable_line_smooth(pipeline, rs_info);
2960*61046927SAndroid Build Coastguard Worker
2961*61046927SAndroid Build Coastguard Worker result = pipeline_compile_graphics(pipeline, cache, pCreateInfo, pAllocator);
2962*61046927SAndroid Build Coastguard Worker
2963*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2964*61046927SAndroid Build Coastguard Worker /* Caller would already destroy the pipeline, and we didn't allocate any
2965*61046927SAndroid Build Coastguard Worker * extra info. We don't need to do anything else.
2966*61046927SAndroid Build Coastguard Worker */
2967*61046927SAndroid Build Coastguard Worker return result;
2968*61046927SAndroid Build Coastguard Worker }
2969*61046927SAndroid Build Coastguard Worker
2970*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputStateCreateInfo *vi_info =
2971*61046927SAndroid Build Coastguard Worker pCreateInfo->pVertexInputState;
2972*61046927SAndroid Build Coastguard Worker
2973*61046927SAndroid Build Coastguard Worker const VkPipelineVertexInputDivisorStateCreateInfoEXT *vd_info =
2974*61046927SAndroid Build Coastguard Worker vk_find_struct_const(vi_info->pNext,
2975*61046927SAndroid Build Coastguard Worker PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT);
2976*61046927SAndroid Build Coastguard Worker
2977*61046927SAndroid Build Coastguard Worker v3dv_X(device, pipeline_pack_compile_state)(pipeline, vi_info, vd_info);
2978*61046927SAndroid Build Coastguard Worker
2979*61046927SAndroid Build Coastguard Worker if (v3dv_X(device, pipeline_needs_default_attribute_values)(pipeline)) {
2980*61046927SAndroid Build Coastguard Worker pipeline->default_attribute_values =
2981*61046927SAndroid Build Coastguard Worker v3dv_X(pipeline->device, create_default_attribute_values)(pipeline->device, pipeline);
2982*61046927SAndroid Build Coastguard Worker
2983*61046927SAndroid Build Coastguard Worker if (!pipeline->default_attribute_values)
2984*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2985*61046927SAndroid Build Coastguard Worker } else {
2986*61046927SAndroid Build Coastguard Worker pipeline->default_attribute_values = NULL;
2987*61046927SAndroid Build Coastguard Worker }
2988*61046927SAndroid Build Coastguard Worker
2989*61046927SAndroid Build Coastguard Worker /* This must be done after the pipeline has been compiled */
2990*61046927SAndroid Build Coastguard Worker v3dv_compute_ez_state(&pipeline->dynamic_graphics_state,
2991*61046927SAndroid Build Coastguard Worker pipeline,
2992*61046927SAndroid Build Coastguard Worker &pipeline->ez_state,
2993*61046927SAndroid Build Coastguard Worker &pipeline->incompatible_ez_test);
2994*61046927SAndroid Build Coastguard Worker
2995*61046927SAndroid Build Coastguard Worker return result;
2996*61046927SAndroid Build Coastguard Worker }
2997*61046927SAndroid Build Coastguard Worker
2998*61046927SAndroid Build Coastguard Worker static VkPipelineCreateFlagBits2KHR
pipeline_create_info_get_flags(VkPipelineCreateFlags flags,const void * pNext)2999*61046927SAndroid Build Coastguard Worker pipeline_create_info_get_flags(VkPipelineCreateFlags flags, const void *pNext)
3000*61046927SAndroid Build Coastguard Worker {
3001*61046927SAndroid Build Coastguard Worker const VkPipelineCreateFlags2CreateInfoKHR *flags2 =
3002*61046927SAndroid Build Coastguard Worker vk_find_struct_const(pNext, PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR);
3003*61046927SAndroid Build Coastguard Worker if (flags2)
3004*61046927SAndroid Build Coastguard Worker return flags2->flags;
3005*61046927SAndroid Build Coastguard Worker else
3006*61046927SAndroid Build Coastguard Worker return flags;
3007*61046927SAndroid Build Coastguard Worker }
3008*61046927SAndroid Build Coastguard Worker
3009*61046927SAndroid Build Coastguard Worker static VkResult
graphics_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline,VkPipelineCreateFlagBits2KHR * flags)3010*61046927SAndroid Build Coastguard Worker graphics_pipeline_create(VkDevice _device,
3011*61046927SAndroid Build Coastguard Worker VkPipelineCache _cache,
3012*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
3013*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
3014*61046927SAndroid Build Coastguard Worker VkPipeline *pPipeline,
3015*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlagBits2KHR *flags)
3016*61046927SAndroid Build Coastguard Worker {
3017*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_device, device, _device);
3018*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline_cache, cache, _cache);
3019*61046927SAndroid Build Coastguard Worker
3020*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline;
3021*61046927SAndroid Build Coastguard Worker VkResult result;
3022*61046927SAndroid Build Coastguard Worker
3023*61046927SAndroid Build Coastguard Worker *flags = pipeline_create_info_get_flags(pCreateInfo->flags,
3024*61046927SAndroid Build Coastguard Worker pCreateInfo->pNext);
3025*61046927SAndroid Build Coastguard Worker
3026*61046927SAndroid Build Coastguard Worker /* Use the default pipeline cache if none is specified */
3027*61046927SAndroid Build Coastguard Worker if (cache == NULL && device->instance->default_pipeline_cache_enabled)
3028*61046927SAndroid Build Coastguard Worker cache = &device->default_pipeline_cache;
3029*61046927SAndroid Build Coastguard Worker
3030*61046927SAndroid Build Coastguard Worker pipeline = vk_object_zalloc(&device->vk, pAllocator, sizeof(*pipeline),
3031*61046927SAndroid Build Coastguard Worker VK_OBJECT_TYPE_PIPELINE);
3032*61046927SAndroid Build Coastguard Worker
3033*61046927SAndroid Build Coastguard Worker if (pipeline == NULL)
3034*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
3035*61046927SAndroid Build Coastguard Worker
3036*61046927SAndroid Build Coastguard Worker pipeline->flags = *flags;
3037*61046927SAndroid Build Coastguard Worker result = pipeline_init(pipeline, device, cache, pCreateInfo, pAllocator);
3038*61046927SAndroid Build Coastguard Worker
3039*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3040*61046927SAndroid Build Coastguard Worker v3dv_destroy_pipeline(pipeline, device, pAllocator);
3041*61046927SAndroid Build Coastguard Worker if (result == VK_PIPELINE_COMPILE_REQUIRED)
3042*61046927SAndroid Build Coastguard Worker *pPipeline = VK_NULL_HANDLE;
3043*61046927SAndroid Build Coastguard Worker return result;
3044*61046927SAndroid Build Coastguard Worker }
3045*61046927SAndroid Build Coastguard Worker
3046*61046927SAndroid Build Coastguard Worker *pPipeline = v3dv_pipeline_to_handle(pipeline);
3047*61046927SAndroid Build Coastguard Worker
3048*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3049*61046927SAndroid Build Coastguard Worker }
3050*61046927SAndroid Build Coastguard Worker
3051*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
v3dv_CreateGraphicsPipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)3052*61046927SAndroid Build Coastguard Worker v3dv_CreateGraphicsPipelines(VkDevice _device,
3053*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
3054*61046927SAndroid Build Coastguard Worker uint32_t count,
3055*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfos,
3056*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
3057*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
3058*61046927SAndroid Build Coastguard Worker {
3059*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_device, device, _device);
3060*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
3061*61046927SAndroid Build Coastguard Worker
3062*61046927SAndroid Build Coastguard Worker if (V3D_DBG(SHADERS))
3063*61046927SAndroid Build Coastguard Worker mtx_lock(&device->pdevice->mutex);
3064*61046927SAndroid Build Coastguard Worker
3065*61046927SAndroid Build Coastguard Worker uint32_t i = 0;
3066*61046927SAndroid Build Coastguard Worker for (; i < count; i++) {
3067*61046927SAndroid Build Coastguard Worker VkResult local_result;
3068*61046927SAndroid Build Coastguard Worker
3069*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlagBits2KHR flags;
3070*61046927SAndroid Build Coastguard Worker local_result = graphics_pipeline_create(_device,
3071*61046927SAndroid Build Coastguard Worker pipelineCache,
3072*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
3073*61046927SAndroid Build Coastguard Worker pAllocator,
3074*61046927SAndroid Build Coastguard Worker &pPipelines[i],
3075*61046927SAndroid Build Coastguard Worker &flags);
3076*61046927SAndroid Build Coastguard Worker
3077*61046927SAndroid Build Coastguard Worker if (local_result != VK_SUCCESS) {
3078*61046927SAndroid Build Coastguard Worker result = local_result;
3079*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
3080*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT)
3081*61046927SAndroid Build Coastguard Worker break;
3082*61046927SAndroid Build Coastguard Worker }
3083*61046927SAndroid Build Coastguard Worker }
3084*61046927SAndroid Build Coastguard Worker
3085*61046927SAndroid Build Coastguard Worker for (; i < count; i++)
3086*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
3087*61046927SAndroid Build Coastguard Worker
3088*61046927SAndroid Build Coastguard Worker if (V3D_DBG(SHADERS))
3089*61046927SAndroid Build Coastguard Worker mtx_unlock(&device->pdevice->mutex);
3090*61046927SAndroid Build Coastguard Worker
3091*61046927SAndroid Build Coastguard Worker return result;
3092*61046927SAndroid Build Coastguard Worker }
3093*61046927SAndroid Build Coastguard Worker
3094*61046927SAndroid Build Coastguard Worker static void
shared_type_info(const struct glsl_type * type,unsigned * size,unsigned * align)3095*61046927SAndroid Build Coastguard Worker shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align)
3096*61046927SAndroid Build Coastguard Worker {
3097*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_vector_or_scalar(type));
3098*61046927SAndroid Build Coastguard Worker
3099*61046927SAndroid Build Coastguard Worker uint32_t comp_size = glsl_type_is_boolean(type)
3100*61046927SAndroid Build Coastguard Worker ? 4 : glsl_get_bit_size(type) / 8;
3101*61046927SAndroid Build Coastguard Worker unsigned length = glsl_get_vector_elements(type);
3102*61046927SAndroid Build Coastguard Worker *size = comp_size * length,
3103*61046927SAndroid Build Coastguard Worker *align = comp_size * (length == 3 ? 4 : length);
3104*61046927SAndroid Build Coastguard Worker }
3105*61046927SAndroid Build Coastguard Worker
3106*61046927SAndroid Build Coastguard Worker static void
lower_compute(struct nir_shader * nir)3107*61046927SAndroid Build Coastguard Worker lower_compute(struct nir_shader *nir)
3108*61046927SAndroid Build Coastguard Worker {
3109*61046927SAndroid Build Coastguard Worker if (!nir->info.shared_memory_explicit_layout) {
3110*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_vars_to_explicit_types,
3111*61046927SAndroid Build Coastguard Worker nir_var_mem_shared, shared_type_info);
3112*61046927SAndroid Build Coastguard Worker }
3113*61046927SAndroid Build Coastguard Worker
3114*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io,
3115*61046927SAndroid Build Coastguard Worker nir_var_mem_shared, nir_address_format_32bit_offset);
3116*61046927SAndroid Build Coastguard Worker
3117*61046927SAndroid Build Coastguard Worker struct nir_lower_compute_system_values_options sysval_options = {
3118*61046927SAndroid Build Coastguard Worker .has_base_workgroup_id = true,
3119*61046927SAndroid Build Coastguard Worker };
3120*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_compute_system_values, &sysval_options);
3121*61046927SAndroid Build Coastguard Worker }
3122*61046927SAndroid Build Coastguard Worker
3123*61046927SAndroid Build Coastguard Worker static VkResult
pipeline_compile_compute(struct v3dv_pipeline * pipeline,struct v3dv_pipeline_cache * cache,const VkComputePipelineCreateInfo * info,const VkAllocationCallbacks * alloc)3124*61046927SAndroid Build Coastguard Worker pipeline_compile_compute(struct v3dv_pipeline *pipeline,
3125*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_cache *cache,
3126*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *info,
3127*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
3128*61046927SAndroid Build Coastguard Worker {
3129*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
3130*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
3131*61046927SAndroid Build Coastguard Worker };
3132*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
3133*61046927SAndroid Build Coastguard Worker
3134*61046927SAndroid Build Coastguard Worker struct v3dv_device *device = pipeline->device;
3135*61046927SAndroid Build Coastguard Worker struct v3dv_physical_device *physical_device = device->pdevice;
3136*61046927SAndroid Build Coastguard Worker
3137*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *sinfo = &info->stage;
3138*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
3139*61046927SAndroid Build Coastguard Worker
3140*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_stage *p_stage =
3141*61046927SAndroid Build Coastguard Worker vk_zalloc2(&device->vk.alloc, alloc, sizeof(*p_stage), 8,
3142*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
3143*61046927SAndroid Build Coastguard Worker if (!p_stage)
3144*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
3145*61046927SAndroid Build Coastguard Worker
3146*61046927SAndroid Build Coastguard Worker p_stage->program_id = p_atomic_inc_return(&physical_device->next_program_id);
3147*61046927SAndroid Build Coastguard Worker p_stage->pipeline = pipeline;
3148*61046927SAndroid Build Coastguard Worker p_stage->stage = gl_shader_stage_to_broadcom(stage);
3149*61046927SAndroid Build Coastguard Worker p_stage->entrypoint = sinfo->pName;
3150*61046927SAndroid Build Coastguard Worker p_stage->module = vk_shader_module_from_handle(sinfo->module);
3151*61046927SAndroid Build Coastguard Worker p_stage->spec_info = sinfo->pSpecializationInfo;
3152*61046927SAndroid Build Coastguard Worker p_stage->feedback = (VkPipelineCreationFeedback) { 0 };
3153*61046927SAndroid Build Coastguard Worker if (!p_stage->module) {
3154*61046927SAndroid Build Coastguard Worker p_stage->module_info =
3155*61046927SAndroid Build Coastguard Worker vk_find_struct_const(sinfo->pNext, SHADER_MODULE_CREATE_INFO);
3156*61046927SAndroid Build Coastguard Worker }
3157*61046927SAndroid Build Coastguard Worker
3158*61046927SAndroid Build Coastguard Worker vk_pipeline_robustness_state_fill(&device->vk, &p_stage->robustness,
3159*61046927SAndroid Build Coastguard Worker info->pNext, sinfo->pNext);
3160*61046927SAndroid Build Coastguard Worker
3161*61046927SAndroid Build Coastguard Worker vk_pipeline_hash_shader_stage(pipeline->flags,
3162*61046927SAndroid Build Coastguard Worker &info->stage,
3163*61046927SAndroid Build Coastguard Worker &p_stage->robustness,
3164*61046927SAndroid Build Coastguard Worker p_stage->shader_sha1);
3165*61046927SAndroid Build Coastguard Worker
3166*61046927SAndroid Build Coastguard Worker p_stage->nir = NULL;
3167*61046927SAndroid Build Coastguard Worker
3168*61046927SAndroid Build Coastguard Worker pipeline->stages[BROADCOM_SHADER_COMPUTE] = p_stage;
3169*61046927SAndroid Build Coastguard Worker pipeline->active_stages |= sinfo->stage;
3170*61046927SAndroid Build Coastguard Worker
3171*61046927SAndroid Build Coastguard Worker /* First we try to get the variants from the pipeline cache (unless we are
3172*61046927SAndroid Build Coastguard Worker * required to capture internal representations, since in that case we need
3173*61046927SAndroid Build Coastguard Worker * compile).
3174*61046927SAndroid Build Coastguard Worker */
3175*61046927SAndroid Build Coastguard Worker bool needs_executable_info =
3176*61046927SAndroid Build Coastguard Worker pipeline->flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR;
3177*61046927SAndroid Build Coastguard Worker if (!needs_executable_info) {
3178*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_key pipeline_key;
3179*61046927SAndroid Build Coastguard Worker pipeline_populate_compute_key(pipeline, &pipeline_key, info);
3180*61046927SAndroid Build Coastguard Worker pipeline_hash_compute(pipeline, &pipeline_key, pipeline->sha1);
3181*61046927SAndroid Build Coastguard Worker
3182*61046927SAndroid Build Coastguard Worker bool cache_hit = false;
3183*61046927SAndroid Build Coastguard Worker pipeline->shared_data =
3184*61046927SAndroid Build Coastguard Worker v3dv_pipeline_cache_search_for_pipeline(cache, pipeline->sha1, &cache_hit);
3185*61046927SAndroid Build Coastguard Worker
3186*61046927SAndroid Build Coastguard Worker if (pipeline->shared_data != NULL) {
3187*61046927SAndroid Build Coastguard Worker assert(pipeline->shared_data->variants[BROADCOM_SHADER_COMPUTE]);
3188*61046927SAndroid Build Coastguard Worker if (cache_hit && cache != &pipeline->device->default_pipeline_cache)
3189*61046927SAndroid Build Coastguard Worker pipeline_feedback.flags |=
3190*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
3191*61046927SAndroid Build Coastguard Worker
3192*61046927SAndroid Build Coastguard Worker goto success;
3193*61046927SAndroid Build Coastguard Worker }
3194*61046927SAndroid Build Coastguard Worker }
3195*61046927SAndroid Build Coastguard Worker
3196*61046927SAndroid Build Coastguard Worker if (pipeline->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)
3197*61046927SAndroid Build Coastguard Worker return VK_PIPELINE_COMPILE_REQUIRED;
3198*61046927SAndroid Build Coastguard Worker
3199*61046927SAndroid Build Coastguard Worker pipeline->shared_data = v3dv_pipeline_shared_data_new_empty(pipeline->sha1,
3200*61046927SAndroid Build Coastguard Worker pipeline,
3201*61046927SAndroid Build Coastguard Worker false);
3202*61046927SAndroid Build Coastguard Worker if (!pipeline->shared_data)
3203*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
3204*61046927SAndroid Build Coastguard Worker
3205*61046927SAndroid Build Coastguard Worker p_stage->feedback.flags |= VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
3206*61046927SAndroid Build Coastguard Worker
3207*61046927SAndroid Build Coastguard Worker /* If not found on cache, compile it */
3208*61046927SAndroid Build Coastguard Worker p_stage->nir = pipeline_stage_get_nir(p_stage, pipeline, cache);
3209*61046927SAndroid Build Coastguard Worker assert(p_stage->nir);
3210*61046927SAndroid Build Coastguard Worker
3211*61046927SAndroid Build Coastguard Worker v3d_optimize_nir(NULL, p_stage->nir);
3212*61046927SAndroid Build Coastguard Worker pipeline_lower_nir(pipeline, p_stage, pipeline->layout);
3213*61046927SAndroid Build Coastguard Worker lower_compute(p_stage->nir);
3214*61046927SAndroid Build Coastguard Worker
3215*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
3216*61046927SAndroid Build Coastguard Worker
3217*61046927SAndroid Build Coastguard Worker struct v3d_key key;
3218*61046927SAndroid Build Coastguard Worker memset(&key, 0, sizeof(key));
3219*61046927SAndroid Build Coastguard Worker pipeline_populate_v3d_key(&key, p_stage, 0);
3220*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[BROADCOM_SHADER_COMPUTE] =
3221*61046927SAndroid Build Coastguard Worker pipeline_compile_shader_variant(p_stage, &key, sizeof(key),
3222*61046927SAndroid Build Coastguard Worker alloc, &result);
3223*61046927SAndroid Build Coastguard Worker
3224*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
3225*61046927SAndroid Build Coastguard Worker return result;
3226*61046927SAndroid Build Coastguard Worker
3227*61046927SAndroid Build Coastguard Worker if (!upload_assembly(pipeline))
3228*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_DEVICE_MEMORY;
3229*61046927SAndroid Build Coastguard Worker
3230*61046927SAndroid Build Coastguard Worker v3dv_pipeline_cache_upload_pipeline(pipeline, cache);
3231*61046927SAndroid Build Coastguard Worker
3232*61046927SAndroid Build Coastguard Worker success:
3233*61046927SAndroid Build Coastguard Worker
3234*61046927SAndroid Build Coastguard Worker pipeline_check_buffer_device_address(pipeline);
3235*61046927SAndroid Build Coastguard Worker
3236*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
3237*61046927SAndroid Build Coastguard Worker write_creation_feedback(pipeline,
3238*61046927SAndroid Build Coastguard Worker info->pNext,
3239*61046927SAndroid Build Coastguard Worker &pipeline_feedback,
3240*61046927SAndroid Build Coastguard Worker 1,
3241*61046927SAndroid Build Coastguard Worker &info->stage);
3242*61046927SAndroid Build Coastguard Worker
3243*61046927SAndroid Build Coastguard Worker /* As we got the variants in pipeline->shared_data, after compiling we
3244*61046927SAndroid Build Coastguard Worker * don't need the pipeline_stages.
3245*61046927SAndroid Build Coastguard Worker */
3246*61046927SAndroid Build Coastguard Worker if (!needs_executable_info)
3247*61046927SAndroid Build Coastguard Worker pipeline_free_stages(device, pipeline, alloc);
3248*61046927SAndroid Build Coastguard Worker
3249*61046927SAndroid Build Coastguard Worker pipeline_check_spill_size(pipeline);
3250*61046927SAndroid Build Coastguard Worker
3251*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3252*61046927SAndroid Build Coastguard Worker }
3253*61046927SAndroid Build Coastguard Worker
3254*61046927SAndroid Build Coastguard Worker static VkResult
compute_pipeline_init(struct v3dv_pipeline * pipeline,struct v3dv_device * device,struct v3dv_pipeline_cache * cache,const VkComputePipelineCreateInfo * info,const VkAllocationCallbacks * alloc)3255*61046927SAndroid Build Coastguard Worker compute_pipeline_init(struct v3dv_pipeline *pipeline,
3256*61046927SAndroid Build Coastguard Worker struct v3dv_device *device,
3257*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_cache *cache,
3258*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *info,
3259*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
3260*61046927SAndroid Build Coastguard Worker {
3261*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline_layout, layout, info->layout);
3262*61046927SAndroid Build Coastguard Worker
3263*61046927SAndroid Build Coastguard Worker pipeline->device = device;
3264*61046927SAndroid Build Coastguard Worker pipeline->layout = layout;
3265*61046927SAndroid Build Coastguard Worker v3dv_pipeline_layout_ref(pipeline->layout);
3266*61046927SAndroid Build Coastguard Worker
3267*61046927SAndroid Build Coastguard Worker VkResult result = pipeline_compile_compute(pipeline, cache, info, alloc);
3268*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
3269*61046927SAndroid Build Coastguard Worker return result;
3270*61046927SAndroid Build Coastguard Worker
3271*61046927SAndroid Build Coastguard Worker return result;
3272*61046927SAndroid Build Coastguard Worker }
3273*61046927SAndroid Build Coastguard Worker
3274*61046927SAndroid Build Coastguard Worker static VkResult
compute_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline,VkPipelineCreateFlagBits2KHR * flags)3275*61046927SAndroid Build Coastguard Worker compute_pipeline_create(VkDevice _device,
3276*61046927SAndroid Build Coastguard Worker VkPipelineCache _cache,
3277*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfo,
3278*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
3279*61046927SAndroid Build Coastguard Worker VkPipeline *pPipeline,
3280*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlagBits2KHR *flags)
3281*61046927SAndroid Build Coastguard Worker {
3282*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_device, device, _device);
3283*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline_cache, cache, _cache);
3284*61046927SAndroid Build Coastguard Worker
3285*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline *pipeline;
3286*61046927SAndroid Build Coastguard Worker VkResult result;
3287*61046927SAndroid Build Coastguard Worker
3288*61046927SAndroid Build Coastguard Worker *flags = pipeline_create_info_get_flags(pCreateInfo->flags,
3289*61046927SAndroid Build Coastguard Worker pCreateInfo->pNext);
3290*61046927SAndroid Build Coastguard Worker
3291*61046927SAndroid Build Coastguard Worker /* Use the default pipeline cache if none is specified */
3292*61046927SAndroid Build Coastguard Worker if (cache == NULL && device->instance->default_pipeline_cache_enabled)
3293*61046927SAndroid Build Coastguard Worker cache = &device->default_pipeline_cache;
3294*61046927SAndroid Build Coastguard Worker
3295*61046927SAndroid Build Coastguard Worker pipeline = vk_object_zalloc(&device->vk, pAllocator, sizeof(*pipeline),
3296*61046927SAndroid Build Coastguard Worker VK_OBJECT_TYPE_PIPELINE);
3297*61046927SAndroid Build Coastguard Worker if (pipeline == NULL)
3298*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
3299*61046927SAndroid Build Coastguard Worker
3300*61046927SAndroid Build Coastguard Worker pipeline->flags = *flags;
3301*61046927SAndroid Build Coastguard Worker result = compute_pipeline_init(pipeline, device, cache,
3302*61046927SAndroid Build Coastguard Worker pCreateInfo, pAllocator);
3303*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3304*61046927SAndroid Build Coastguard Worker v3dv_destroy_pipeline(pipeline, device, pAllocator);
3305*61046927SAndroid Build Coastguard Worker if (result == VK_PIPELINE_COMPILE_REQUIRED)
3306*61046927SAndroid Build Coastguard Worker *pPipeline = VK_NULL_HANDLE;
3307*61046927SAndroid Build Coastguard Worker return result;
3308*61046927SAndroid Build Coastguard Worker }
3309*61046927SAndroid Build Coastguard Worker
3310*61046927SAndroid Build Coastguard Worker *pPipeline = v3dv_pipeline_to_handle(pipeline);
3311*61046927SAndroid Build Coastguard Worker
3312*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3313*61046927SAndroid Build Coastguard Worker }
3314*61046927SAndroid Build Coastguard Worker
3315*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
v3dv_CreateComputePipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)3316*61046927SAndroid Build Coastguard Worker v3dv_CreateComputePipelines(VkDevice _device,
3317*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
3318*61046927SAndroid Build Coastguard Worker uint32_t createInfoCount,
3319*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfos,
3320*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
3321*61046927SAndroid Build Coastguard Worker VkPipeline *pPipelines)
3322*61046927SAndroid Build Coastguard Worker {
3323*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_device, device, _device);
3324*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
3325*61046927SAndroid Build Coastguard Worker
3326*61046927SAndroid Build Coastguard Worker if (V3D_DBG(SHADERS))
3327*61046927SAndroid Build Coastguard Worker mtx_lock(&device->pdevice->mutex);
3328*61046927SAndroid Build Coastguard Worker
3329*61046927SAndroid Build Coastguard Worker uint32_t i = 0;
3330*61046927SAndroid Build Coastguard Worker for (; i < createInfoCount; i++) {
3331*61046927SAndroid Build Coastguard Worker VkResult local_result;
3332*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlagBits2KHR flags;
3333*61046927SAndroid Build Coastguard Worker local_result = compute_pipeline_create(_device,
3334*61046927SAndroid Build Coastguard Worker pipelineCache,
3335*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
3336*61046927SAndroid Build Coastguard Worker pAllocator,
3337*61046927SAndroid Build Coastguard Worker &pPipelines[i],
3338*61046927SAndroid Build Coastguard Worker &flags);
3339*61046927SAndroid Build Coastguard Worker
3340*61046927SAndroid Build Coastguard Worker if (local_result != VK_SUCCESS) {
3341*61046927SAndroid Build Coastguard Worker result = local_result;
3342*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
3343*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT)
3344*61046927SAndroid Build Coastguard Worker break;
3345*61046927SAndroid Build Coastguard Worker }
3346*61046927SAndroid Build Coastguard Worker }
3347*61046927SAndroid Build Coastguard Worker
3348*61046927SAndroid Build Coastguard Worker for (; i < createInfoCount; i++)
3349*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
3350*61046927SAndroid Build Coastguard Worker
3351*61046927SAndroid Build Coastguard Worker if (V3D_DBG(SHADERS))
3352*61046927SAndroid Build Coastguard Worker mtx_unlock(&device->pdevice->mutex);
3353*61046927SAndroid Build Coastguard Worker
3354*61046927SAndroid Build Coastguard Worker return result;
3355*61046927SAndroid Build Coastguard Worker }
3356*61046927SAndroid Build Coastguard Worker
3357*61046927SAndroid Build Coastguard Worker static nir_shader *
pipeline_get_nir(struct v3dv_pipeline * pipeline,enum broadcom_shader_stage stage)3358*61046927SAndroid Build Coastguard Worker pipeline_get_nir(struct v3dv_pipeline *pipeline,
3359*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage stage)
3360*61046927SAndroid Build Coastguard Worker {
3361*61046927SAndroid Build Coastguard Worker assert(stage >= 0 && stage < BROADCOM_SHADER_STAGES);
3362*61046927SAndroid Build Coastguard Worker if (pipeline->stages[stage])
3363*61046927SAndroid Build Coastguard Worker return pipeline->stages[stage]->nir;
3364*61046927SAndroid Build Coastguard Worker
3365*61046927SAndroid Build Coastguard Worker return NULL;
3366*61046927SAndroid Build Coastguard Worker }
3367*61046927SAndroid Build Coastguard Worker
3368*61046927SAndroid Build Coastguard Worker static struct v3d_prog_data *
pipeline_get_prog_data(struct v3dv_pipeline * pipeline,enum broadcom_shader_stage stage)3369*61046927SAndroid Build Coastguard Worker pipeline_get_prog_data(struct v3dv_pipeline *pipeline,
3370*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage stage)
3371*61046927SAndroid Build Coastguard Worker {
3372*61046927SAndroid Build Coastguard Worker if (pipeline->shared_data->variants[stage])
3373*61046927SAndroid Build Coastguard Worker return pipeline->shared_data->variants[stage]->prog_data.base;
3374*61046927SAndroid Build Coastguard Worker return NULL;
3375*61046927SAndroid Build Coastguard Worker }
3376*61046927SAndroid Build Coastguard Worker
3377*61046927SAndroid Build Coastguard Worker static uint64_t *
pipeline_get_qpu(struct v3dv_pipeline * pipeline,enum broadcom_shader_stage stage,uint32_t * qpu_size)3378*61046927SAndroid Build Coastguard Worker pipeline_get_qpu(struct v3dv_pipeline *pipeline,
3379*61046927SAndroid Build Coastguard Worker enum broadcom_shader_stage stage,
3380*61046927SAndroid Build Coastguard Worker uint32_t *qpu_size)
3381*61046927SAndroid Build Coastguard Worker {
3382*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant =
3383*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[stage];
3384*61046927SAndroid Build Coastguard Worker if (!variant) {
3385*61046927SAndroid Build Coastguard Worker *qpu_size = 0;
3386*61046927SAndroid Build Coastguard Worker return NULL;
3387*61046927SAndroid Build Coastguard Worker }
3388*61046927SAndroid Build Coastguard Worker
3389*61046927SAndroid Build Coastguard Worker *qpu_size = variant->qpu_insts_size;
3390*61046927SAndroid Build Coastguard Worker return variant->qpu_insts;
3391*61046927SAndroid Build Coastguard Worker }
3392*61046927SAndroid Build Coastguard Worker
3393*61046927SAndroid Build Coastguard Worker /* FIXME: we use the same macro in various drivers, maybe move it to
3394*61046927SAndroid Build Coastguard Worker * the common vk_util.h?
3395*61046927SAndroid Build Coastguard Worker */
3396*61046927SAndroid Build Coastguard Worker #define WRITE_STR(field, ...) ({ \
3397*61046927SAndroid Build Coastguard Worker memset(field, 0, sizeof(field)); \
3398*61046927SAndroid Build Coastguard Worker UNUSED int _i = snprintf(field, sizeof(field), __VA_ARGS__); \
3399*61046927SAndroid Build Coastguard Worker assert(_i > 0 && _i < sizeof(field)); \
3400*61046927SAndroid Build Coastguard Worker })
3401*61046927SAndroid Build Coastguard Worker
3402*61046927SAndroid Build Coastguard Worker static bool
write_ir_text(VkPipelineExecutableInternalRepresentationKHR * ir,const char * data)3403*61046927SAndroid Build Coastguard Worker write_ir_text(VkPipelineExecutableInternalRepresentationKHR* ir,
3404*61046927SAndroid Build Coastguard Worker const char *data)
3405*61046927SAndroid Build Coastguard Worker {
3406*61046927SAndroid Build Coastguard Worker ir->isText = VK_TRUE;
3407*61046927SAndroid Build Coastguard Worker
3408*61046927SAndroid Build Coastguard Worker size_t data_len = strlen(data) + 1;
3409*61046927SAndroid Build Coastguard Worker
3410*61046927SAndroid Build Coastguard Worker if (ir->pData == NULL) {
3411*61046927SAndroid Build Coastguard Worker ir->dataSize = data_len;
3412*61046927SAndroid Build Coastguard Worker return true;
3413*61046927SAndroid Build Coastguard Worker }
3414*61046927SAndroid Build Coastguard Worker
3415*61046927SAndroid Build Coastguard Worker strncpy(ir->pData, data, ir->dataSize);
3416*61046927SAndroid Build Coastguard Worker if (ir->dataSize < data_len)
3417*61046927SAndroid Build Coastguard Worker return false;
3418*61046927SAndroid Build Coastguard Worker
3419*61046927SAndroid Build Coastguard Worker ir->dataSize = data_len;
3420*61046927SAndroid Build Coastguard Worker return true;
3421*61046927SAndroid Build Coastguard Worker }
3422*61046927SAndroid Build Coastguard Worker
3423*61046927SAndroid Build Coastguard Worker static void
append(char ** str,size_t * offset,const char * fmt,...)3424*61046927SAndroid Build Coastguard Worker append(char **str, size_t *offset, const char *fmt, ...)
3425*61046927SAndroid Build Coastguard Worker {
3426*61046927SAndroid Build Coastguard Worker va_list args;
3427*61046927SAndroid Build Coastguard Worker va_start(args, fmt);
3428*61046927SAndroid Build Coastguard Worker ralloc_vasprintf_rewrite_tail(str, offset, fmt, args);
3429*61046927SAndroid Build Coastguard Worker va_end(args);
3430*61046927SAndroid Build Coastguard Worker }
3431*61046927SAndroid Build Coastguard Worker
3432*61046927SAndroid Build Coastguard Worker static void
pipeline_collect_executable_data(struct v3dv_pipeline * pipeline)3433*61046927SAndroid Build Coastguard Worker pipeline_collect_executable_data(struct v3dv_pipeline *pipeline)
3434*61046927SAndroid Build Coastguard Worker {
3435*61046927SAndroid Build Coastguard Worker if (pipeline->executables.mem_ctx)
3436*61046927SAndroid Build Coastguard Worker return;
3437*61046927SAndroid Build Coastguard Worker
3438*61046927SAndroid Build Coastguard Worker pipeline->executables.mem_ctx = ralloc_context(NULL);
3439*61046927SAndroid Build Coastguard Worker util_dynarray_init(&pipeline->executables.data,
3440*61046927SAndroid Build Coastguard Worker pipeline->executables.mem_ctx);
3441*61046927SAndroid Build Coastguard Worker
3442*61046927SAndroid Build Coastguard Worker /* Don't crash for failed/bogus pipelines */
3443*61046927SAndroid Build Coastguard Worker if (!pipeline->shared_data)
3444*61046927SAndroid Build Coastguard Worker return;
3445*61046927SAndroid Build Coastguard Worker
3446*61046927SAndroid Build Coastguard Worker for (int s = BROADCOM_SHADER_VERTEX; s <= BROADCOM_SHADER_COMPUTE; s++) {
3447*61046927SAndroid Build Coastguard Worker VkShaderStageFlags vk_stage =
3448*61046927SAndroid Build Coastguard Worker mesa_to_vk_shader_stage(broadcom_shader_stage_to_gl(s));
3449*61046927SAndroid Build Coastguard Worker if (!(vk_stage & pipeline->active_stages))
3450*61046927SAndroid Build Coastguard Worker continue;
3451*61046927SAndroid Build Coastguard Worker
3452*61046927SAndroid Build Coastguard Worker char *nir_str = NULL;
3453*61046927SAndroid Build Coastguard Worker char *qpu_str = NULL;
3454*61046927SAndroid Build Coastguard Worker
3455*61046927SAndroid Build Coastguard Worker if (pipeline_keep_qpu(pipeline)) {
3456*61046927SAndroid Build Coastguard Worker nir_shader *nir = pipeline_get_nir(pipeline, s);
3457*61046927SAndroid Build Coastguard Worker nir_str = nir ?
3458*61046927SAndroid Build Coastguard Worker nir_shader_as_str(nir, pipeline->executables.mem_ctx) : NULL;
3459*61046927SAndroid Build Coastguard Worker
3460*61046927SAndroid Build Coastguard Worker uint32_t qpu_size;
3461*61046927SAndroid Build Coastguard Worker uint64_t *qpu = pipeline_get_qpu(pipeline, s, &qpu_size);
3462*61046927SAndroid Build Coastguard Worker if (qpu) {
3463*61046927SAndroid Build Coastguard Worker uint32_t qpu_inst_count = qpu_size / sizeof(uint64_t);
3464*61046927SAndroid Build Coastguard Worker qpu_str = rzalloc_size(pipeline->executables.mem_ctx,
3465*61046927SAndroid Build Coastguard Worker qpu_inst_count * 96);
3466*61046927SAndroid Build Coastguard Worker size_t offset = 0;
3467*61046927SAndroid Build Coastguard Worker for (int i = 0; i < qpu_inst_count; i++) {
3468*61046927SAndroid Build Coastguard Worker const char *str = v3d_qpu_disasm(&pipeline->device->devinfo, qpu[i]);
3469*61046927SAndroid Build Coastguard Worker append(&qpu_str, &offset, "%s\n", str);
3470*61046927SAndroid Build Coastguard Worker ralloc_free((void *)str);
3471*61046927SAndroid Build Coastguard Worker }
3472*61046927SAndroid Build Coastguard Worker }
3473*61046927SAndroid Build Coastguard Worker }
3474*61046927SAndroid Build Coastguard Worker
3475*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_executable_data data = {
3476*61046927SAndroid Build Coastguard Worker .stage = s,
3477*61046927SAndroid Build Coastguard Worker .nir_str = nir_str,
3478*61046927SAndroid Build Coastguard Worker .qpu_str = qpu_str,
3479*61046927SAndroid Build Coastguard Worker };
3480*61046927SAndroid Build Coastguard Worker util_dynarray_append(&pipeline->executables.data,
3481*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_executable_data, data);
3482*61046927SAndroid Build Coastguard Worker }
3483*61046927SAndroid Build Coastguard Worker }
3484*61046927SAndroid Build Coastguard Worker
3485*61046927SAndroid Build Coastguard Worker static const struct v3dv_pipeline_executable_data *
pipeline_get_executable(struct v3dv_pipeline * pipeline,uint32_t index)3486*61046927SAndroid Build Coastguard Worker pipeline_get_executable(struct v3dv_pipeline *pipeline, uint32_t index)
3487*61046927SAndroid Build Coastguard Worker {
3488*61046927SAndroid Build Coastguard Worker assert(index < util_dynarray_num_elements(&pipeline->executables.data,
3489*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_executable_data));
3490*61046927SAndroid Build Coastguard Worker return util_dynarray_element(&pipeline->executables.data,
3491*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_executable_data,
3492*61046927SAndroid Build Coastguard Worker index);
3493*61046927SAndroid Build Coastguard Worker }
3494*61046927SAndroid Build Coastguard Worker
3495*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
v3dv_GetPipelineExecutableInternalRepresentationsKHR(VkDevice device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pInternalRepresentationCount,VkPipelineExecutableInternalRepresentationKHR * pInternalRepresentations)3496*61046927SAndroid Build Coastguard Worker v3dv_GetPipelineExecutableInternalRepresentationsKHR(
3497*61046927SAndroid Build Coastguard Worker VkDevice device,
3498*61046927SAndroid Build Coastguard Worker const VkPipelineExecutableInfoKHR *pExecutableInfo,
3499*61046927SAndroid Build Coastguard Worker uint32_t *pInternalRepresentationCount,
3500*61046927SAndroid Build Coastguard Worker VkPipelineExecutableInternalRepresentationKHR *pInternalRepresentations)
3501*61046927SAndroid Build Coastguard Worker {
3502*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline, pipeline, pExecutableInfo->pipeline);
3503*61046927SAndroid Build Coastguard Worker
3504*61046927SAndroid Build Coastguard Worker pipeline_collect_executable_data(pipeline);
3505*61046927SAndroid Build Coastguard Worker
3506*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutableInternalRepresentationKHR, out,
3507*61046927SAndroid Build Coastguard Worker pInternalRepresentations, pInternalRepresentationCount);
3508*61046927SAndroid Build Coastguard Worker
3509*61046927SAndroid Build Coastguard Worker bool incomplete = false;
3510*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_executable_data *exe =
3511*61046927SAndroid Build Coastguard Worker pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
3512*61046927SAndroid Build Coastguard Worker
3513*61046927SAndroid Build Coastguard Worker if (exe->nir_str) {
3514*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableInternalRepresentationKHR,
3515*61046927SAndroid Build Coastguard Worker &out, ir) {
3516*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->name, "NIR (%s)", broadcom_shader_stage_name(exe->stage));
3517*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->description, "Final NIR form");
3518*61046927SAndroid Build Coastguard Worker if (!write_ir_text(ir, exe->nir_str))
3519*61046927SAndroid Build Coastguard Worker incomplete = true;
3520*61046927SAndroid Build Coastguard Worker }
3521*61046927SAndroid Build Coastguard Worker }
3522*61046927SAndroid Build Coastguard Worker
3523*61046927SAndroid Build Coastguard Worker if (exe->qpu_str) {
3524*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableInternalRepresentationKHR,
3525*61046927SAndroid Build Coastguard Worker &out, ir) {
3526*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->name, "QPU (%s)", broadcom_shader_stage_name(exe->stage));
3527*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->description, "Final QPU assembly");
3528*61046927SAndroid Build Coastguard Worker if (!write_ir_text(ir, exe->qpu_str))
3529*61046927SAndroid Build Coastguard Worker incomplete = true;
3530*61046927SAndroid Build Coastguard Worker }
3531*61046927SAndroid Build Coastguard Worker }
3532*61046927SAndroid Build Coastguard Worker
3533*61046927SAndroid Build Coastguard Worker return incomplete ? VK_INCOMPLETE : vk_outarray_status(&out);
3534*61046927SAndroid Build Coastguard Worker }
3535*61046927SAndroid Build Coastguard Worker
3536*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
v3dv_GetPipelineExecutablePropertiesKHR(VkDevice device,const VkPipelineInfoKHR * pPipelineInfo,uint32_t * pExecutableCount,VkPipelineExecutablePropertiesKHR * pProperties)3537*61046927SAndroid Build Coastguard Worker v3dv_GetPipelineExecutablePropertiesKHR(
3538*61046927SAndroid Build Coastguard Worker VkDevice device,
3539*61046927SAndroid Build Coastguard Worker const VkPipelineInfoKHR *pPipelineInfo,
3540*61046927SAndroid Build Coastguard Worker uint32_t *pExecutableCount,
3541*61046927SAndroid Build Coastguard Worker VkPipelineExecutablePropertiesKHR *pProperties)
3542*61046927SAndroid Build Coastguard Worker {
3543*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline, pipeline, pPipelineInfo->pipeline);
3544*61046927SAndroid Build Coastguard Worker
3545*61046927SAndroid Build Coastguard Worker pipeline_collect_executable_data(pipeline);
3546*61046927SAndroid Build Coastguard Worker
3547*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutablePropertiesKHR, out,
3548*61046927SAndroid Build Coastguard Worker pProperties, pExecutableCount);
3549*61046927SAndroid Build Coastguard Worker
3550*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&pipeline->executables.data,
3551*61046927SAndroid Build Coastguard Worker struct v3dv_pipeline_executable_data, exe) {
3552*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutablePropertiesKHR, &out, props) {
3553*61046927SAndroid Build Coastguard Worker gl_shader_stage mesa_stage = broadcom_shader_stage_to_gl(exe->stage);
3554*61046927SAndroid Build Coastguard Worker props->stages = mesa_to_vk_shader_stage(mesa_stage);
3555*61046927SAndroid Build Coastguard Worker
3556*61046927SAndroid Build Coastguard Worker WRITE_STR(props->name, "%s (%s)",
3557*61046927SAndroid Build Coastguard Worker _mesa_shader_stage_to_abbrev(mesa_stage),
3558*61046927SAndroid Build Coastguard Worker broadcom_shader_stage_is_binning(exe->stage) ?
3559*61046927SAndroid Build Coastguard Worker "Binning" : "Render");
3560*61046927SAndroid Build Coastguard Worker
3561*61046927SAndroid Build Coastguard Worker WRITE_STR(props->description, "%s",
3562*61046927SAndroid Build Coastguard Worker _mesa_shader_stage_to_string(mesa_stage));
3563*61046927SAndroid Build Coastguard Worker
3564*61046927SAndroid Build Coastguard Worker props->subgroupSize = V3D_CHANNELS;
3565*61046927SAndroid Build Coastguard Worker }
3566*61046927SAndroid Build Coastguard Worker }
3567*61046927SAndroid Build Coastguard Worker
3568*61046927SAndroid Build Coastguard Worker return vk_outarray_status(&out);
3569*61046927SAndroid Build Coastguard Worker }
3570*61046927SAndroid Build Coastguard Worker
3571*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
v3dv_GetPipelineExecutableStatisticsKHR(VkDevice device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pStatisticCount,VkPipelineExecutableStatisticKHR * pStatistics)3572*61046927SAndroid Build Coastguard Worker v3dv_GetPipelineExecutableStatisticsKHR(
3573*61046927SAndroid Build Coastguard Worker VkDevice device,
3574*61046927SAndroid Build Coastguard Worker const VkPipelineExecutableInfoKHR *pExecutableInfo,
3575*61046927SAndroid Build Coastguard Worker uint32_t *pStatisticCount,
3576*61046927SAndroid Build Coastguard Worker VkPipelineExecutableStatisticKHR *pStatistics)
3577*61046927SAndroid Build Coastguard Worker {
3578*61046927SAndroid Build Coastguard Worker V3DV_FROM_HANDLE(v3dv_pipeline, pipeline, pExecutableInfo->pipeline);
3579*61046927SAndroid Build Coastguard Worker
3580*61046927SAndroid Build Coastguard Worker pipeline_collect_executable_data(pipeline);
3581*61046927SAndroid Build Coastguard Worker
3582*61046927SAndroid Build Coastguard Worker const struct v3dv_pipeline_executable_data *exe =
3583*61046927SAndroid Build Coastguard Worker pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
3584*61046927SAndroid Build Coastguard Worker
3585*61046927SAndroid Build Coastguard Worker struct v3d_prog_data *prog_data =
3586*61046927SAndroid Build Coastguard Worker pipeline_get_prog_data(pipeline, exe->stage);
3587*61046927SAndroid Build Coastguard Worker
3588*61046927SAndroid Build Coastguard Worker struct v3dv_shader_variant *variant =
3589*61046927SAndroid Build Coastguard Worker pipeline->shared_data->variants[exe->stage];
3590*61046927SAndroid Build Coastguard Worker uint32_t qpu_inst_count = variant->qpu_insts_size / sizeof(uint64_t);
3591*61046927SAndroid Build Coastguard Worker
3592*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutableStatisticKHR, out,
3593*61046927SAndroid Build Coastguard Worker pStatistics, pStatisticCount);
3594*61046927SAndroid Build Coastguard Worker
3595*61046927SAndroid Build Coastguard Worker if (qpu_inst_count > 0) {
3596*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
3597*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Compile Strategy");
3598*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description, "Chosen compile strategy index");
3599*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
3600*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->compile_strategy_idx;
3601*61046927SAndroid Build Coastguard Worker }
3602*61046927SAndroid Build Coastguard Worker
3603*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
3604*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Instruction Count");
3605*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description, "Number of QPU instructions");
3606*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
3607*61046927SAndroid Build Coastguard Worker stat->value.u64 = qpu_inst_count;
3608*61046927SAndroid Build Coastguard Worker }
3609*61046927SAndroid Build Coastguard Worker
3610*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
3611*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Thread Count");
3612*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description, "Number of QPU threads dispatched");
3613*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
3614*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->threads;
3615*61046927SAndroid Build Coastguard Worker }
3616*61046927SAndroid Build Coastguard Worker
3617*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
3618*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Spill Size");
3619*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description, "Size of the spill buffer in bytes");
3620*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
3621*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->spill_size;
3622*61046927SAndroid Build Coastguard Worker }
3623*61046927SAndroid Build Coastguard Worker
3624*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
3625*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "TMU Spills");
3626*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description, "Number of times a register was spilled "
3627*61046927SAndroid Build Coastguard Worker "to memory");
3628*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
3629*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->spill_size;
3630*61046927SAndroid Build Coastguard Worker }
3631*61046927SAndroid Build Coastguard Worker
3632*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
3633*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "TMU Fills");
3634*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description, "Number of times a register was filled "
3635*61046927SAndroid Build Coastguard Worker "from memory");
3636*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
3637*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->spill_size;
3638*61046927SAndroid Build Coastguard Worker }
3639*61046927SAndroid Build Coastguard Worker
3640*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
3641*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "QPU Read Stalls");
3642*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description, "Number of cycles the QPU stalls for a "
3643*61046927SAndroid Build Coastguard Worker "register read dependency");
3644*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
3645*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->qpu_read_stalls;
3646*61046927SAndroid Build Coastguard Worker }
3647*61046927SAndroid Build Coastguard Worker }
3648*61046927SAndroid Build Coastguard Worker
3649*61046927SAndroid Build Coastguard Worker return vk_outarray_status(&out);
3650*61046927SAndroid Build Coastguard Worker }
3651