1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Red Hat.
3*61046927SAndroid Build Coastguard Worker * Copyright © 2016 Bas Nieuwenhuizen
4*61046927SAndroid Build Coastguard Worker *
5*61046927SAndroid Build Coastguard Worker * based in part on anv driver which is:
6*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
7*61046927SAndroid Build Coastguard Worker *
8*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
9*61046927SAndroid Build Coastguard Worker */
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "radv_pipeline.h"
12*61046927SAndroid Build Coastguard Worker #include "meta/radv_meta.h"
13*61046927SAndroid Build Coastguard Worker #include "nir/nir.h"
14*61046927SAndroid Build Coastguard Worker #include "nir/nir_builder.h"
15*61046927SAndroid Build Coastguard Worker #include "nir/nir_serialize.h"
16*61046927SAndroid Build Coastguard Worker #include "nir/radv_nir.h"
17*61046927SAndroid Build Coastguard Worker #include "spirv/nir_spirv.h"
18*61046927SAndroid Build Coastguard Worker #include "util/disk_cache.h"
19*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
20*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
21*61046927SAndroid Build Coastguard Worker #include "radv_cs.h"
22*61046927SAndroid Build Coastguard Worker #include "radv_debug.h"
23*61046927SAndroid Build Coastguard Worker #include "radv_pipeline_rt.h"
24*61046927SAndroid Build Coastguard Worker #include "radv_rmv.h"
25*61046927SAndroid Build Coastguard Worker #include "radv_shader.h"
26*61046927SAndroid Build Coastguard Worker #include "radv_shader_args.h"
27*61046927SAndroid Build Coastguard Worker #include "vk_pipeline.h"
28*61046927SAndroid Build Coastguard Worker #include "vk_render_pass.h"
29*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
32*61046927SAndroid Build Coastguard Worker #include "ac_binary.h"
33*61046927SAndroid Build Coastguard Worker #include "ac_nir.h"
34*61046927SAndroid Build Coastguard Worker #include "ac_shader_util.h"
35*61046927SAndroid Build Coastguard Worker #include "aco_interface.h"
36*61046927SAndroid Build Coastguard Worker #include "sid.h"
37*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
38*61046927SAndroid Build Coastguard Worker #include "vk_nir_convert_ycbcr.h"
39*61046927SAndroid Build Coastguard Worker #include "vk_ycbcr_conversion.h"
40*61046927SAndroid Build Coastguard Worker #if AMD_LLVM_AVAILABLE
41*61046927SAndroid Build Coastguard Worker #include "ac_llvm_util.h"
42*61046927SAndroid Build Coastguard Worker #endif
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker bool
radv_shader_need_indirect_descriptor_sets(const struct radv_shader * shader)45*61046927SAndroid Build Coastguard Worker radv_shader_need_indirect_descriptor_sets(const struct radv_shader *shader)
46*61046927SAndroid Build Coastguard Worker {
47*61046927SAndroid Build Coastguard Worker const struct radv_userdata_info *loc = radv_get_user_sgpr_info(shader, AC_UD_INDIRECT_DESCRIPTOR_SETS);
48*61046927SAndroid Build Coastguard Worker return loc->sgpr_idx != -1;
49*61046927SAndroid Build Coastguard Worker }
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker bool
radv_pipeline_capture_shaders(const struct radv_device * device,VkPipelineCreateFlags2KHR flags)52*61046927SAndroid Build Coastguard Worker radv_pipeline_capture_shaders(const struct radv_device *device, VkPipelineCreateFlags2KHR flags)
53*61046927SAndroid Build Coastguard Worker {
54*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
55*61046927SAndroid Build Coastguard Worker const struct radv_instance *instance = radv_physical_device_instance(pdev);
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker return (flags & VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR) ||
58*61046927SAndroid Build Coastguard Worker (instance->debug_flags & RADV_DEBUG_DUMP_SHADERS) || device->keep_shader_info;
59*61046927SAndroid Build Coastguard Worker }
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker bool
radv_pipeline_capture_shader_stats(const struct radv_device * device,VkPipelineCreateFlags2KHR flags)62*61046927SAndroid Build Coastguard Worker radv_pipeline_capture_shader_stats(const struct radv_device *device, VkPipelineCreateFlags2KHR flags)
63*61046927SAndroid Build Coastguard Worker {
64*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
65*61046927SAndroid Build Coastguard Worker const struct radv_instance *instance = radv_physical_device_instance(pdev);
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker return (flags & VK_PIPELINE_CREATE_2_CAPTURE_STATISTICS_BIT_KHR) ||
68*61046927SAndroid Build Coastguard Worker (instance->debug_flags & RADV_DEBUG_DUMP_SHADER_STATS) || device->keep_shader_info;
69*61046927SAndroid Build Coastguard Worker }
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker void
radv_pipeline_init(struct radv_device * device,struct radv_pipeline * pipeline,enum radv_pipeline_type type)72*61046927SAndroid Build Coastguard Worker radv_pipeline_init(struct radv_device *device, struct radv_pipeline *pipeline, enum radv_pipeline_type type)
73*61046927SAndroid Build Coastguard Worker {
74*61046927SAndroid Build Coastguard Worker vk_object_base_init(&device->vk, &pipeline->base, VK_OBJECT_TYPE_PIPELINE);
75*61046927SAndroid Build Coastguard Worker
76*61046927SAndroid Build Coastguard Worker pipeline->type = type;
77*61046927SAndroid Build Coastguard Worker }
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker void
radv_pipeline_destroy(struct radv_device * device,struct radv_pipeline * pipeline,const VkAllocationCallbacks * allocator)80*61046927SAndroid Build Coastguard Worker radv_pipeline_destroy(struct radv_device *device, struct radv_pipeline *pipeline,
81*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *allocator)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker if (pipeline->cache_object)
84*61046927SAndroid Build Coastguard Worker vk_pipeline_cache_object_unref(&device->vk, pipeline->cache_object);
85*61046927SAndroid Build Coastguard Worker
86*61046927SAndroid Build Coastguard Worker switch (pipeline->type) {
87*61046927SAndroid Build Coastguard Worker case RADV_PIPELINE_GRAPHICS:
88*61046927SAndroid Build Coastguard Worker radv_destroy_graphics_pipeline(device, radv_pipeline_to_graphics(pipeline));
89*61046927SAndroid Build Coastguard Worker break;
90*61046927SAndroid Build Coastguard Worker case RADV_PIPELINE_GRAPHICS_LIB:
91*61046927SAndroid Build Coastguard Worker radv_destroy_graphics_lib_pipeline(device, radv_pipeline_to_graphics_lib(pipeline));
92*61046927SAndroid Build Coastguard Worker break;
93*61046927SAndroid Build Coastguard Worker case RADV_PIPELINE_COMPUTE:
94*61046927SAndroid Build Coastguard Worker radv_destroy_compute_pipeline(device, radv_pipeline_to_compute(pipeline));
95*61046927SAndroid Build Coastguard Worker break;
96*61046927SAndroid Build Coastguard Worker case RADV_PIPELINE_RAY_TRACING:
97*61046927SAndroid Build Coastguard Worker radv_destroy_ray_tracing_pipeline(device, radv_pipeline_to_ray_tracing(pipeline));
98*61046927SAndroid Build Coastguard Worker break;
99*61046927SAndroid Build Coastguard Worker default:
100*61046927SAndroid Build Coastguard Worker unreachable("invalid pipeline type");
101*61046927SAndroid Build Coastguard Worker }
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker radv_rmv_log_resource_destroy(device, (uint64_t)radv_pipeline_to_handle(pipeline));
104*61046927SAndroid Build Coastguard Worker vk_object_base_finish(&pipeline->base);
105*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, allocator, pipeline);
106*61046927SAndroid Build Coastguard Worker }
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
radv_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)109*61046927SAndroid Build Coastguard Worker radv_DestroyPipeline(VkDevice _device, VkPipeline _pipeline, const VkAllocationCallbacks *pAllocator)
110*61046927SAndroid Build Coastguard Worker {
111*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(radv_device, device, _device);
112*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(radv_pipeline, pipeline, _pipeline);
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker if (!_pipeline)
115*61046927SAndroid Build Coastguard Worker return;
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Worker radv_pipeline_destroy(device, pipeline, pAllocator);
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker struct radv_shader_stage_key
radv_pipeline_get_shader_key(const struct radv_device * device,const VkPipelineShaderStageCreateInfo * stage,VkPipelineCreateFlags2KHR flags,const void * pNext)121*61046927SAndroid Build Coastguard Worker radv_pipeline_get_shader_key(const struct radv_device *device, const VkPipelineShaderStageCreateInfo *stage,
122*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR flags, const void *pNext)
123*61046927SAndroid Build Coastguard Worker {
124*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
125*61046927SAndroid Build Coastguard Worker const struct radv_instance *instance = radv_physical_device_instance(pdev);
126*61046927SAndroid Build Coastguard Worker gl_shader_stage s = vk_to_mesa_shader_stage(stage->stage);
127*61046927SAndroid Build Coastguard Worker struct vk_pipeline_robustness_state rs;
128*61046927SAndroid Build Coastguard Worker struct radv_shader_stage_key key = {0};
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker key.keep_statistic_info = radv_pipeline_capture_shader_stats(device, flags);
131*61046927SAndroid Build Coastguard Worker
132*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_2_DISABLE_OPTIMIZATION_BIT_KHR)
133*61046927SAndroid Build Coastguard Worker key.optimisations_disabled = 1;
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR)
136*61046927SAndroid Build Coastguard Worker key.view_index_from_device_index = 1;
137*61046927SAndroid Build Coastguard Worker
138*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV)
139*61046927SAndroid Build Coastguard Worker key.indirect_bindable = 1;
140*61046927SAndroid Build Coastguard Worker
141*61046927SAndroid Build Coastguard Worker if (stage->stage & RADV_GRAPHICS_STAGE_BITS) {
142*61046927SAndroid Build Coastguard Worker key.version = instance->drirc.override_graphics_shader_version;
143*61046927SAndroid Build Coastguard Worker } else if (stage->stage & RADV_RT_STAGE_BITS) {
144*61046927SAndroid Build Coastguard Worker key.version = instance->drirc.override_ray_tracing_shader_version;
145*61046927SAndroid Build Coastguard Worker } else {
146*61046927SAndroid Build Coastguard Worker assert(stage->stage == VK_SHADER_STAGE_COMPUTE_BIT);
147*61046927SAndroid Build Coastguard Worker key.version = instance->drirc.override_compute_shader_version;
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker vk_pipeline_robustness_state_fill(&device->vk, &rs, pNext, stage->pNext);
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker radv_set_stage_key_robustness(&rs, s, &key);
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *const subgroup_size =
155*61046927SAndroid Build Coastguard Worker vk_find_struct_const(stage->pNext, PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO);
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker if (subgroup_size) {
158*61046927SAndroid Build Coastguard Worker if (subgroup_size->requiredSubgroupSize == 32)
159*61046927SAndroid Build Coastguard Worker key.subgroup_required_size = RADV_REQUIRED_WAVE32;
160*61046927SAndroid Build Coastguard Worker else if (subgroup_size->requiredSubgroupSize == 64)
161*61046927SAndroid Build Coastguard Worker key.subgroup_required_size = RADV_REQUIRED_WAVE64;
162*61046927SAndroid Build Coastguard Worker else
163*61046927SAndroid Build Coastguard Worker unreachable("Unsupported required subgroup size.");
164*61046927SAndroid Build Coastguard Worker }
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker if (stage->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT) {
167*61046927SAndroid Build Coastguard Worker key.subgroup_require_full = 1;
168*61046927SAndroid Build Coastguard Worker }
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker return key;
171*61046927SAndroid Build Coastguard Worker }
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker void
radv_pipeline_stage_init(VkPipelineCreateFlags2KHR pipeline_flags,const VkPipelineShaderStageCreateInfo * sinfo,const struct radv_pipeline_layout * pipeline_layout,const struct radv_shader_stage_key * stage_key,struct radv_shader_stage * out_stage)174*61046927SAndroid Build Coastguard Worker radv_pipeline_stage_init(VkPipelineCreateFlags2KHR pipeline_flags,
175*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *sinfo,
176*61046927SAndroid Build Coastguard Worker const struct radv_pipeline_layout *pipeline_layout,
177*61046927SAndroid Build Coastguard Worker const struct radv_shader_stage_key *stage_key, struct radv_shader_stage *out_stage)
178*61046927SAndroid Build Coastguard Worker {
179*61046927SAndroid Build Coastguard Worker const VkShaderModuleCreateInfo *minfo = vk_find_struct_const(sinfo->pNext, SHADER_MODULE_CREATE_INFO);
180*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageModuleIdentifierCreateInfoEXT *iinfo =
181*61046927SAndroid Build Coastguard Worker vk_find_struct_const(sinfo->pNext, PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT);
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker if (sinfo->module == VK_NULL_HANDLE && !minfo && !iinfo)
184*61046927SAndroid Build Coastguard Worker return;
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker memset(out_stage, 0, sizeof(*out_stage));
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker out_stage->stage = vk_to_mesa_shader_stage(sinfo->stage);
189*61046927SAndroid Build Coastguard Worker out_stage->next_stage = MESA_SHADER_NONE;
190*61046927SAndroid Build Coastguard Worker out_stage->entrypoint = sinfo->pName;
191*61046927SAndroid Build Coastguard Worker out_stage->spec_info = sinfo->pSpecializationInfo;
192*61046927SAndroid Build Coastguard Worker out_stage->feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
193*61046927SAndroid Build Coastguard Worker out_stage->key = *stage_key;
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker if (sinfo->module != VK_NULL_HANDLE) {
196*61046927SAndroid Build Coastguard Worker struct vk_shader_module *module = vk_shader_module_from_handle(sinfo->module);
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker out_stage->spirv.data = module->data;
199*61046927SAndroid Build Coastguard Worker out_stage->spirv.size = module->size;
200*61046927SAndroid Build Coastguard Worker out_stage->spirv.object = &module->base;
201*61046927SAndroid Build Coastguard Worker
202*61046927SAndroid Build Coastguard Worker if (module->nir)
203*61046927SAndroid Build Coastguard Worker out_stage->internal_nir = module->nir;
204*61046927SAndroid Build Coastguard Worker } else if (minfo) {
205*61046927SAndroid Build Coastguard Worker out_stage->spirv.data = (const char *)minfo->pCode;
206*61046927SAndroid Build Coastguard Worker out_stage->spirv.size = minfo->codeSize;
207*61046927SAndroid Build Coastguard Worker }
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker radv_shader_layout_init(pipeline_layout, out_stage->stage, &out_stage->layout);
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker vk_pipeline_hash_shader_stage(pipeline_flags, sinfo, NULL, out_stage->shader_sha1);
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker void
radv_shader_layout_init(const struct radv_pipeline_layout * pipeline_layout,gl_shader_stage stage,struct radv_shader_layout * layout)215*61046927SAndroid Build Coastguard Worker radv_shader_layout_init(const struct radv_pipeline_layout *pipeline_layout, gl_shader_stage stage,
216*61046927SAndroid Build Coastguard Worker struct radv_shader_layout *layout)
217*61046927SAndroid Build Coastguard Worker {
218*61046927SAndroid Build Coastguard Worker layout->num_sets = pipeline_layout->num_sets;
219*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < pipeline_layout->num_sets; i++) {
220*61046927SAndroid Build Coastguard Worker layout->set[i].layout = pipeline_layout->set[i].layout;
221*61046927SAndroid Build Coastguard Worker layout->set[i].dynamic_offset_start = pipeline_layout->set[i].dynamic_offset_start;
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker
224*61046927SAndroid Build Coastguard Worker layout->push_constant_size = pipeline_layout->push_constant_size;
225*61046927SAndroid Build Coastguard Worker layout->use_dynamic_descriptors = pipeline_layout->dynamic_offset_count &&
226*61046927SAndroid Build Coastguard Worker (pipeline_layout->dynamic_shader_stages & mesa_to_vk_shader_stage(stage));
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker static const struct vk_ycbcr_conversion_state *
ycbcr_conversion_lookup(const void * data,uint32_t set,uint32_t binding,uint32_t array_index)230*61046927SAndroid Build Coastguard Worker ycbcr_conversion_lookup(const void *data, uint32_t set, uint32_t binding, uint32_t array_index)
231*61046927SAndroid Build Coastguard Worker {
232*61046927SAndroid Build Coastguard Worker const struct radv_shader_layout *layout = data;
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker const struct radv_descriptor_set_layout *set_layout = layout->set[set].layout;
235*61046927SAndroid Build Coastguard Worker const struct vk_ycbcr_conversion_state *ycbcr_samplers = radv_immutable_ycbcr_samplers(set_layout, binding);
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker if (!ycbcr_samplers)
238*61046927SAndroid Build Coastguard Worker return NULL;
239*61046927SAndroid Build Coastguard Worker
240*61046927SAndroid Build Coastguard Worker return ycbcr_samplers + array_index;
241*61046927SAndroid Build Coastguard Worker }
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker static unsigned
lower_bit_size_callback(const nir_instr * instr,void * _)244*61046927SAndroid Build Coastguard Worker lower_bit_size_callback(const nir_instr *instr, void *_)
245*61046927SAndroid Build Coastguard Worker {
246*61046927SAndroid Build Coastguard Worker struct radv_device *device = _;
247*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
248*61046927SAndroid Build Coastguard Worker enum amd_gfx_level chip = pdev->info.gfx_level;
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_alu)
251*61046927SAndroid Build Coastguard Worker return 0;
252*61046927SAndroid Build Coastguard Worker nir_alu_instr *alu = nir_instr_as_alu(instr);
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker /* If an instruction is not scalarized by this point,
255*61046927SAndroid Build Coastguard Worker * it can be emitted as packed instruction */
256*61046927SAndroid Build Coastguard Worker if (alu->def.num_components > 1)
257*61046927SAndroid Build Coastguard Worker return 0;
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker if (alu->def.bit_size & (8 | 16)) {
260*61046927SAndroid Build Coastguard Worker unsigned bit_size = alu->def.bit_size;
261*61046927SAndroid Build Coastguard Worker switch (alu->op) {
262*61046927SAndroid Build Coastguard Worker case nir_op_bitfield_select:
263*61046927SAndroid Build Coastguard Worker case nir_op_imul_high:
264*61046927SAndroid Build Coastguard Worker case nir_op_umul_high:
265*61046927SAndroid Build Coastguard Worker case nir_op_uadd_carry:
266*61046927SAndroid Build Coastguard Worker case nir_op_usub_borrow:
267*61046927SAndroid Build Coastguard Worker return 32;
268*61046927SAndroid Build Coastguard Worker case nir_op_iabs:
269*61046927SAndroid Build Coastguard Worker case nir_op_imax:
270*61046927SAndroid Build Coastguard Worker case nir_op_umax:
271*61046927SAndroid Build Coastguard Worker case nir_op_imin:
272*61046927SAndroid Build Coastguard Worker case nir_op_umin:
273*61046927SAndroid Build Coastguard Worker case nir_op_ishr:
274*61046927SAndroid Build Coastguard Worker case nir_op_ushr:
275*61046927SAndroid Build Coastguard Worker case nir_op_ishl:
276*61046927SAndroid Build Coastguard Worker case nir_op_isign:
277*61046927SAndroid Build Coastguard Worker case nir_op_uadd_sat:
278*61046927SAndroid Build Coastguard Worker case nir_op_usub_sat:
279*61046927SAndroid Build Coastguard Worker return (bit_size == 8 || !(chip >= GFX8 && alu->def.divergent)) ? 32 : 0;
280*61046927SAndroid Build Coastguard Worker case nir_op_iadd_sat:
281*61046927SAndroid Build Coastguard Worker case nir_op_isub_sat:
282*61046927SAndroid Build Coastguard Worker return bit_size == 8 || !alu->def.divergent ? 32 : 0;
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker default:
285*61046927SAndroid Build Coastguard Worker return 0;
286*61046927SAndroid Build Coastguard Worker }
287*61046927SAndroid Build Coastguard Worker }
288*61046927SAndroid Build Coastguard Worker
289*61046927SAndroid Build Coastguard Worker if (nir_src_bit_size(alu->src[0].src) & (8 | 16)) {
290*61046927SAndroid Build Coastguard Worker unsigned bit_size = nir_src_bit_size(alu->src[0].src);
291*61046927SAndroid Build Coastguard Worker switch (alu->op) {
292*61046927SAndroid Build Coastguard Worker case nir_op_bit_count:
293*61046927SAndroid Build Coastguard Worker case nir_op_find_lsb:
294*61046927SAndroid Build Coastguard Worker case nir_op_ufind_msb:
295*61046927SAndroid Build Coastguard Worker return 32;
296*61046927SAndroid Build Coastguard Worker case nir_op_ilt:
297*61046927SAndroid Build Coastguard Worker case nir_op_ige:
298*61046927SAndroid Build Coastguard Worker case nir_op_ieq:
299*61046927SAndroid Build Coastguard Worker case nir_op_ine:
300*61046927SAndroid Build Coastguard Worker case nir_op_ult:
301*61046927SAndroid Build Coastguard Worker case nir_op_uge:
302*61046927SAndroid Build Coastguard Worker case nir_op_bitz:
303*61046927SAndroid Build Coastguard Worker case nir_op_bitnz:
304*61046927SAndroid Build Coastguard Worker return (bit_size == 8 || !(chip >= GFX8 && alu->def.divergent)) ? 32 : 0;
305*61046927SAndroid Build Coastguard Worker default:
306*61046927SAndroid Build Coastguard Worker return 0;
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker return 0;
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker static uint8_t
opt_vectorize_callback(const nir_instr * instr,const void * _)314*61046927SAndroid Build Coastguard Worker opt_vectorize_callback(const nir_instr *instr, const void *_)
315*61046927SAndroid Build Coastguard Worker {
316*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_alu)
317*61046927SAndroid Build Coastguard Worker return 0;
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker const struct radv_device *device = _;
320*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
321*61046927SAndroid Build Coastguard Worker enum amd_gfx_level chip = pdev->info.gfx_level;
322*61046927SAndroid Build Coastguard Worker if (chip < GFX9)
323*61046927SAndroid Build Coastguard Worker return 1;
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker const nir_alu_instr *alu = nir_instr_as_alu(instr);
326*61046927SAndroid Build Coastguard Worker const unsigned bit_size = alu->def.bit_size;
327*61046927SAndroid Build Coastguard Worker if (bit_size != 16)
328*61046927SAndroid Build Coastguard Worker return 1;
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker return aco_nir_op_supports_packed_math_16bit(alu) ? 2 : 1;
331*61046927SAndroid Build Coastguard Worker }
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker static nir_component_mask_t
non_uniform_access_callback(const nir_src * src,void * _)334*61046927SAndroid Build Coastguard Worker non_uniform_access_callback(const nir_src *src, void *_)
335*61046927SAndroid Build Coastguard Worker {
336*61046927SAndroid Build Coastguard Worker if (src->ssa->num_components == 1)
337*61046927SAndroid Build Coastguard Worker return 0x1;
338*61046927SAndroid Build Coastguard Worker return nir_chase_binding(*src).success ? 0x2 : 0x3;
339*61046927SAndroid Build Coastguard Worker }
340*61046927SAndroid Build Coastguard Worker
341*61046927SAndroid Build Coastguard Worker void
radv_postprocess_nir(struct radv_device * device,const struct radv_graphics_state_key * gfx_state,struct radv_shader_stage * stage)342*61046927SAndroid Build Coastguard Worker radv_postprocess_nir(struct radv_device *device, const struct radv_graphics_state_key *gfx_state,
343*61046927SAndroid Build Coastguard Worker struct radv_shader_stage *stage)
344*61046927SAndroid Build Coastguard Worker {
345*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
346*61046927SAndroid Build Coastguard Worker const struct radv_instance *instance = radv_physical_device_instance(pdev);
347*61046927SAndroid Build Coastguard Worker enum amd_gfx_level gfx_level = pdev->info.gfx_level;
348*61046927SAndroid Build Coastguard Worker bool progress;
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker /* Wave and workgroup size should already be filled. */
351*61046927SAndroid Build Coastguard Worker assert(stage->info.wave_size && stage->info.workgroup_size);
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker if (stage->stage == MESA_SHADER_FRAGMENT) {
354*61046927SAndroid Build Coastguard Worker if (!stage->key.optimisations_disabled) {
355*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_cse);
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, radv_nir_lower_fs_intrinsics, stage, gfx_state);
358*61046927SAndroid Build Coastguard Worker }
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker /* LLVM could support more of these in theory. */
361*61046927SAndroid Build Coastguard Worker bool use_llvm = radv_use_llvm_for_stage(pdev, stage->stage);
362*61046927SAndroid Build Coastguard Worker bool has_inverse_ballot = true;
363*61046927SAndroid Build Coastguard Worker #if AMD_LLVM_AVAILABLE
364*61046927SAndroid Build Coastguard Worker has_inverse_ballot = !use_llvm || LLVM_VERSION_MAJOR >= 17;
365*61046927SAndroid Build Coastguard Worker #endif
366*61046927SAndroid Build Coastguard Worker radv_nir_opt_tid_function_options tid_options = {
367*61046927SAndroid Build Coastguard Worker .use_masked_swizzle_amd = true,
368*61046927SAndroid Build Coastguard Worker .use_dpp16_shift_amd = !use_llvm && gfx_level >= GFX8,
369*61046927SAndroid Build Coastguard Worker .use_clustered_rotate = !use_llvm,
370*61046927SAndroid Build Coastguard Worker .hw_subgroup_size = stage->info.wave_size,
371*61046927SAndroid Build Coastguard Worker .hw_ballot_bit_size = has_inverse_ballot ? stage->info.wave_size : 0,
372*61046927SAndroid Build Coastguard Worker .hw_ballot_num_comp = has_inverse_ballot ? 1 : 0,
373*61046927SAndroid Build Coastguard Worker };
374*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, radv_nir_opt_tid_function, &tid_options);
375*61046927SAndroid Build Coastguard Worker
376*61046927SAndroid Build Coastguard Worker enum nir_lower_non_uniform_access_type lower_non_uniform_access_types =
377*61046927SAndroid Build Coastguard Worker nir_lower_non_uniform_ubo_access | nir_lower_non_uniform_ssbo_access | nir_lower_non_uniform_texture_access |
378*61046927SAndroid Build Coastguard Worker nir_lower_non_uniform_image_access;
379*61046927SAndroid Build Coastguard Worker
380*61046927SAndroid Build Coastguard Worker /* In practice, most shaders do not have non-uniform-qualified
381*61046927SAndroid Build Coastguard Worker * accesses (see
382*61046927SAndroid Build Coastguard Worker * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17558#note_1475069)
383*61046927SAndroid Build Coastguard Worker * thus a cheaper and likely to fail check is run first.
384*61046927SAndroid Build Coastguard Worker */
385*61046927SAndroid Build Coastguard Worker if (nir_has_non_uniform_access(stage->nir, lower_non_uniform_access_types)) {
386*61046927SAndroid Build Coastguard Worker if (!stage->key.optimisations_disabled) {
387*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_non_uniform_access);
388*61046927SAndroid Build Coastguard Worker }
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker if (!radv_use_llvm_for_stage(pdev, stage->stage)) {
391*61046927SAndroid Build Coastguard Worker nir_lower_non_uniform_access_options options = {
392*61046927SAndroid Build Coastguard Worker .types = lower_non_uniform_access_types,
393*61046927SAndroid Build Coastguard Worker .callback = &non_uniform_access_callback,
394*61046927SAndroid Build Coastguard Worker .callback_data = NULL,
395*61046927SAndroid Build Coastguard Worker };
396*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_non_uniform_access, &options);
397*61046927SAndroid Build Coastguard Worker }
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_memory_model);
400*61046927SAndroid Build Coastguard Worker
401*61046927SAndroid Build Coastguard Worker nir_load_store_vectorize_options vectorize_opts = {
402*61046927SAndroid Build Coastguard Worker .modes = nir_var_mem_ssbo | nir_var_mem_ubo | nir_var_mem_push_const | nir_var_mem_shared | nir_var_mem_global |
403*61046927SAndroid Build Coastguard Worker nir_var_shader_temp,
404*61046927SAndroid Build Coastguard Worker .callback = ac_nir_mem_vectorize_callback,
405*61046927SAndroid Build Coastguard Worker .cb_data = &gfx_level,
406*61046927SAndroid Build Coastguard Worker .robust_modes = 0,
407*61046927SAndroid Build Coastguard Worker /* On GFX6, read2/write2 is out-of-bounds if the offset register is negative, even if
408*61046927SAndroid Build Coastguard Worker * the final offset is not.
409*61046927SAndroid Build Coastguard Worker */
410*61046927SAndroid Build Coastguard Worker .has_shared2_amd = gfx_level >= GFX7,
411*61046927SAndroid Build Coastguard Worker };
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker if (stage->key.uniform_robustness2)
414*61046927SAndroid Build Coastguard Worker vectorize_opts.robust_modes |= nir_var_mem_ubo;
415*61046927SAndroid Build Coastguard Worker
416*61046927SAndroid Build Coastguard Worker if (stage->key.storage_robustness2)
417*61046927SAndroid Build Coastguard Worker vectorize_opts.robust_modes |= nir_var_mem_ssbo;
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker if (!stage->key.optimisations_disabled) {
420*61046927SAndroid Build Coastguard Worker progress = false;
421*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, stage->nir, nir_opt_load_store_vectorize, &vectorize_opts);
422*61046927SAndroid Build Coastguard Worker if (progress) {
423*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_copy_prop);
424*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_shrink_stores, !instance->drirc.disable_shrink_image_store);
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker /* Ensure vectorized load_push_constant still have constant offsets, for
427*61046927SAndroid Build Coastguard Worker * radv_nir_apply_pipeline_layout. */
428*61046927SAndroid Build Coastguard Worker if (stage->args.ac.inline_push_const_mask)
429*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_constant_folding);
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker /* Gather info again, to update whether 8/16-bit are used. */
432*61046927SAndroid Build Coastguard Worker nir_shader_gather_info(stage->nir, nir_shader_get_entrypoint(stage->nir));
433*61046927SAndroid Build Coastguard Worker }
434*61046927SAndroid Build Coastguard Worker }
435*61046927SAndroid Build Coastguard Worker
436*61046927SAndroid Build Coastguard Worker NIR_PASS(
437*61046927SAndroid Build Coastguard Worker _, stage->nir, ac_nir_lower_subdword_loads,
438*61046927SAndroid Build Coastguard Worker (ac_nir_lower_subdword_options){.modes_1_comp = nir_var_mem_ubo | nir_var_mem_push_const,
439*61046927SAndroid Build Coastguard Worker .modes_N_comps = nir_var_mem_ubo | nir_var_mem_push_const | nir_var_mem_ssbo});
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker progress = false;
442*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, stage->nir, nir_vk_lower_ycbcr_tex, ycbcr_conversion_lookup, &stage->layout);
443*61046927SAndroid Build Coastguard Worker /* Gather info in the case that nir_vk_lower_ycbcr_tex might have emitted resinfo instructions. */
444*61046927SAndroid Build Coastguard Worker if (progress)
445*61046927SAndroid Build Coastguard Worker nir_shader_gather_info(stage->nir, nir_shader_get_entrypoint(stage->nir));
446*61046927SAndroid Build Coastguard Worker
447*61046927SAndroid Build Coastguard Worker bool fix_derivs_in_divergent_cf =
448*61046927SAndroid Build Coastguard Worker stage->stage == MESA_SHADER_FRAGMENT && !radv_use_llvm_for_stage(pdev, stage->stage);
449*61046927SAndroid Build Coastguard Worker if (fix_derivs_in_divergent_cf) {
450*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_convert_to_lcssa, true, true);
451*61046927SAndroid Build Coastguard Worker nir_divergence_analysis(stage->nir);
452*61046927SAndroid Build Coastguard Worker }
453*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, ac_nir_lower_tex,
454*61046927SAndroid Build Coastguard Worker &(ac_nir_lower_tex_options){
455*61046927SAndroid Build Coastguard Worker .gfx_level = gfx_level,
456*61046927SAndroid Build Coastguard Worker .lower_array_layer_round_even = !pdev->info.conformant_trunc_coord || device->disable_trunc_coord,
457*61046927SAndroid Build Coastguard Worker .fix_derivs_in_divergent_cf = fix_derivs_in_divergent_cf,
458*61046927SAndroid Build Coastguard Worker .max_wqm_vgprs = 64, // TODO: improve spiller and RA support for linear VGPRs
459*61046927SAndroid Build Coastguard Worker });
460*61046927SAndroid Build Coastguard Worker if (fix_derivs_in_divergent_cf)
461*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_remove_phis); /* cleanup LCSSA phis */
462*61046927SAndroid Build Coastguard Worker
463*61046927SAndroid Build Coastguard Worker if (stage->nir->info.uses_resource_info_query)
464*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, ac_nir_lower_resinfo, gfx_level);
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker NIR_PASS_V(stage->nir, radv_nir_apply_pipeline_layout, device, stage);
467*61046927SAndroid Build Coastguard Worker
468*61046927SAndroid Build Coastguard Worker if (!stage->key.optimisations_disabled) {
469*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_shrink_vectors, true);
470*61046927SAndroid Build Coastguard Worker }
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_alu_width, opt_vectorize_callback, device);
473*61046927SAndroid Build Coastguard Worker
474*61046927SAndroid Build Coastguard Worker nir_move_options sink_opts = nir_move_const_undef | nir_move_copies;
475*61046927SAndroid Build Coastguard Worker
476*61046927SAndroid Build Coastguard Worker if (!stage->key.optimisations_disabled) {
477*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_licm);
478*61046927SAndroid Build Coastguard Worker if (stage->stage != MESA_SHADER_FRAGMENT || !pdev->cache_key.disable_sinking_load_input_fs)
479*61046927SAndroid Build Coastguard Worker sink_opts |= nir_move_load_input;
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_sink, sink_opts);
482*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_move, nir_move_load_input | nir_move_const_undef | nir_move_copies);
483*61046927SAndroid Build Coastguard Worker }
484*61046927SAndroid Build Coastguard Worker
485*61046927SAndroid Build Coastguard Worker /* Lower VS inputs. We need to do this after nir_opt_sink, because
486*61046927SAndroid Build Coastguard Worker * load_input can be reordered, but buffer loads can't.
487*61046927SAndroid Build Coastguard Worker */
488*61046927SAndroid Build Coastguard Worker if (stage->stage == MESA_SHADER_VERTEX) {
489*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, radv_nir_lower_vs_inputs, stage, gfx_state, &pdev->info);
490*61046927SAndroid Build Coastguard Worker }
491*61046927SAndroid Build Coastguard Worker
492*61046927SAndroid Build Coastguard Worker /* Lower I/O intrinsics to memory instructions. */
493*61046927SAndroid Build Coastguard Worker bool is_last_vgt_stage = radv_is_last_vgt_stage(stage);
494*61046927SAndroid Build Coastguard Worker bool io_to_mem = radv_nir_lower_io_to_mem(device, stage);
495*61046927SAndroid Build Coastguard Worker bool lowered_ngg = stage->info.is_ngg && is_last_vgt_stage;
496*61046927SAndroid Build Coastguard Worker if (lowered_ngg) {
497*61046927SAndroid Build Coastguard Worker radv_lower_ngg(device, stage, gfx_state);
498*61046927SAndroid Build Coastguard Worker } else if (is_last_vgt_stage) {
499*61046927SAndroid Build Coastguard Worker if (stage->stage != MESA_SHADER_GEOMETRY) {
500*61046927SAndroid Build Coastguard Worker NIR_PASS_V(stage->nir, ac_nir_lower_legacy_vs, gfx_level,
501*61046927SAndroid Build Coastguard Worker stage->info.outinfo.clip_dist_mask | stage->info.outinfo.cull_dist_mask,
502*61046927SAndroid Build Coastguard Worker stage->info.outinfo.vs_output_param_offset, stage->info.outinfo.param_exports,
503*61046927SAndroid Build Coastguard Worker stage->info.outinfo.export_prim_id, false, false, false, stage->info.force_vrs_per_vertex);
504*61046927SAndroid Build Coastguard Worker
505*61046927SAndroid Build Coastguard Worker } else {
506*61046927SAndroid Build Coastguard Worker bool emulate_ngg_gs_query_pipeline_stat = pdev->emulate_ngg_gs_query_pipeline_stat;
507*61046927SAndroid Build Coastguard Worker
508*61046927SAndroid Build Coastguard Worker ac_nir_gs_output_info gs_out_info = {
509*61046927SAndroid Build Coastguard Worker .streams = stage->info.gs.output_streams,
510*61046927SAndroid Build Coastguard Worker .usage_mask = stage->info.gs.output_usage_mask,
511*61046927SAndroid Build Coastguard Worker };
512*61046927SAndroid Build Coastguard Worker NIR_PASS_V(stage->nir, ac_nir_lower_legacy_gs, false, emulate_ngg_gs_query_pipeline_stat, &gs_out_info);
513*61046927SAndroid Build Coastguard Worker }
514*61046927SAndroid Build Coastguard Worker } else if (stage->stage == MESA_SHADER_FRAGMENT) {
515*61046927SAndroid Build Coastguard Worker ac_nir_lower_ps_options options = {
516*61046927SAndroid Build Coastguard Worker .gfx_level = gfx_level,
517*61046927SAndroid Build Coastguard Worker .family = pdev->info.family,
518*61046927SAndroid Build Coastguard Worker .use_aco = !radv_use_llvm_for_stage(pdev, stage->stage),
519*61046927SAndroid Build Coastguard Worker .uses_discard = true,
520*61046927SAndroid Build Coastguard Worker .alpha_func = COMPARE_FUNC_ALWAYS,
521*61046927SAndroid Build Coastguard Worker .no_color_export = stage->info.ps.has_epilog,
522*61046927SAndroid Build Coastguard Worker .no_depth_export = stage->info.ps.exports_mrtz_via_epilog,
523*61046927SAndroid Build Coastguard Worker
524*61046927SAndroid Build Coastguard Worker .bc_optimize_for_persp = G_0286CC_PERSP_CENTER_ENA(stage->info.ps.spi_ps_input_ena) &&
525*61046927SAndroid Build Coastguard Worker G_0286CC_PERSP_CENTROID_ENA(stage->info.ps.spi_ps_input_ena),
526*61046927SAndroid Build Coastguard Worker .bc_optimize_for_linear = G_0286CC_LINEAR_CENTER_ENA(stage->info.ps.spi_ps_input_ena) &&
527*61046927SAndroid Build Coastguard Worker G_0286CC_LINEAR_CENTROID_ENA(stage->info.ps.spi_ps_input_ena),
528*61046927SAndroid Build Coastguard Worker };
529*61046927SAndroid Build Coastguard Worker
530*61046927SAndroid Build Coastguard Worker if (!options.no_color_export) {
531*61046927SAndroid Build Coastguard Worker options.dual_src_blend_swizzle = gfx_state->ps.epilog.mrt0_is_dual_src && gfx_level >= GFX11;
532*61046927SAndroid Build Coastguard Worker options.color_is_int8 = gfx_state->ps.epilog.color_is_int8;
533*61046927SAndroid Build Coastguard Worker options.color_is_int10 = gfx_state->ps.epilog.color_is_int10;
534*61046927SAndroid Build Coastguard Worker options.enable_mrt_output_nan_fixup =
535*61046927SAndroid Build Coastguard Worker gfx_state->ps.epilog.enable_mrt_output_nan_fixup && !stage->nir->info.internal;
536*61046927SAndroid Build Coastguard Worker /* Need to filter out unwritten color slots. */
537*61046927SAndroid Build Coastguard Worker options.spi_shader_col_format = gfx_state->ps.epilog.spi_shader_col_format & stage->info.ps.colors_written;
538*61046927SAndroid Build Coastguard Worker options.alpha_to_one = gfx_state->ps.epilog.alpha_to_one;
539*61046927SAndroid Build Coastguard Worker }
540*61046927SAndroid Build Coastguard Worker
541*61046927SAndroid Build Coastguard Worker if (!options.no_depth_export) {
542*61046927SAndroid Build Coastguard Worker /* Compared to gfx_state.ps.alpha_to_coverage_via_mrtz,
543*61046927SAndroid Build Coastguard Worker * radv_shader_info.ps.writes_mrt0_alpha need any depth/stencil/sample_mask exist.
544*61046927SAndroid Build Coastguard Worker * ac_nir_lower_ps() require this field to reflect whether alpha via mrtz is really
545*61046927SAndroid Build Coastguard Worker * present.
546*61046927SAndroid Build Coastguard Worker */
547*61046927SAndroid Build Coastguard Worker options.alpha_to_coverage_via_mrtz = stage->info.ps.writes_mrt0_alpha;
548*61046927SAndroid Build Coastguard Worker }
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker NIR_PASS_V(stage->nir, ac_nir_lower_ps, &options);
551*61046927SAndroid Build Coastguard Worker }
552*61046927SAndroid Build Coastguard Worker
553*61046927SAndroid Build Coastguard Worker if (radv_shader_should_clear_lds(device, stage->nir)) {
554*61046927SAndroid Build Coastguard Worker const unsigned chunk_size = 16; /* max single store size */
555*61046927SAndroid Build Coastguard Worker const unsigned shared_size = ALIGN(stage->nir->info.shared_size, chunk_size);
556*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_clear_shared_memory, shared_size, chunk_size);
557*61046927SAndroid Build Coastguard Worker }
558*61046927SAndroid Build Coastguard Worker
559*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_int64);
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_idiv_const, 8);
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_idiv,
564*61046927SAndroid Build Coastguard Worker &(nir_lower_idiv_options){
565*61046927SAndroid Build Coastguard Worker .allow_fp16 = gfx_level >= GFX9,
566*61046927SAndroid Build Coastguard Worker });
567*61046927SAndroid Build Coastguard Worker
568*61046927SAndroid Build Coastguard Worker if (radv_use_llvm_for_stage(pdev, stage->stage))
569*61046927SAndroid Build Coastguard Worker NIR_PASS_V(stage->nir, nir_lower_io_to_scalar, nir_var_mem_global, NULL, NULL);
570*61046927SAndroid Build Coastguard Worker
571*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, ac_nir_lower_global_access);
572*61046927SAndroid Build Coastguard Worker NIR_PASS_V(stage->nir, ac_nir_lower_intrinsics_to_args, gfx_level, radv_select_hw_stage(&stage->info, gfx_level),
573*61046927SAndroid Build Coastguard Worker &stage->args.ac);
574*61046927SAndroid Build Coastguard Worker NIR_PASS_V(stage->nir, radv_nir_lower_abi, gfx_level, stage, gfx_state, pdev->info.address32_hi);
575*61046927SAndroid Build Coastguard Worker radv_optimize_nir_algebraic(
576*61046927SAndroid Build Coastguard Worker stage->nir, io_to_mem || lowered_ngg || stage->stage == MESA_SHADER_COMPUTE || stage->stage == MESA_SHADER_TASK,
577*61046927SAndroid Build Coastguard Worker gfx_level >= GFX7);
578*61046927SAndroid Build Coastguard Worker
579*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_fp16_casts, nir_lower_fp16_split_fp64);
580*61046927SAndroid Build Coastguard Worker
581*61046927SAndroid Build Coastguard Worker if (stage->nir->info.bit_sizes_int & (8 | 16)) {
582*61046927SAndroid Build Coastguard Worker if (gfx_level >= GFX8) {
583*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_convert_to_lcssa, true, true);
584*61046927SAndroid Build Coastguard Worker nir_divergence_analysis(stage->nir);
585*61046927SAndroid Build Coastguard Worker }
586*61046927SAndroid Build Coastguard Worker
587*61046927SAndroid Build Coastguard Worker if (nir_lower_bit_size(stage->nir, lower_bit_size_callback, device)) {
588*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_constant_folding);
589*61046927SAndroid Build Coastguard Worker }
590*61046927SAndroid Build Coastguard Worker
591*61046927SAndroid Build Coastguard Worker if (gfx_level >= GFX8)
592*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_remove_phis); /* cleanup LCSSA phis */
593*61046927SAndroid Build Coastguard Worker }
594*61046927SAndroid Build Coastguard Worker if (gfx_level >= GFX9) {
595*61046927SAndroid Build Coastguard Worker bool separate_g16 = gfx_level >= GFX10;
596*61046927SAndroid Build Coastguard Worker struct nir_opt_tex_srcs_options opt_srcs_options[] = {
597*61046927SAndroid Build Coastguard Worker {
598*61046927SAndroid Build Coastguard Worker .sampler_dims = ~(BITFIELD_BIT(GLSL_SAMPLER_DIM_CUBE) | BITFIELD_BIT(GLSL_SAMPLER_DIM_BUF)),
599*61046927SAndroid Build Coastguard Worker .src_types = (1 << nir_tex_src_coord) | (1 << nir_tex_src_lod) | (1 << nir_tex_src_bias) |
600*61046927SAndroid Build Coastguard Worker (1 << nir_tex_src_min_lod) | (1 << nir_tex_src_ms_index) |
601*61046927SAndroid Build Coastguard Worker (separate_g16 ? 0 : (1 << nir_tex_src_ddx) | (1 << nir_tex_src_ddy)),
602*61046927SAndroid Build Coastguard Worker },
603*61046927SAndroid Build Coastguard Worker {
604*61046927SAndroid Build Coastguard Worker .sampler_dims = ~BITFIELD_BIT(GLSL_SAMPLER_DIM_CUBE),
605*61046927SAndroid Build Coastguard Worker .src_types = (1 << nir_tex_src_ddx) | (1 << nir_tex_src_ddy),
606*61046927SAndroid Build Coastguard Worker },
607*61046927SAndroid Build Coastguard Worker };
608*61046927SAndroid Build Coastguard Worker struct nir_opt_16bit_tex_image_options opt_16bit_options = {
609*61046927SAndroid Build Coastguard Worker .rounding_mode = nir_rounding_mode_undef,
610*61046927SAndroid Build Coastguard Worker .opt_tex_dest_types = nir_type_float | nir_type_int | nir_type_uint,
611*61046927SAndroid Build Coastguard Worker .opt_image_dest_types = nir_type_float | nir_type_int | nir_type_uint,
612*61046927SAndroid Build Coastguard Worker .integer_dest_saturates = true,
613*61046927SAndroid Build Coastguard Worker .opt_image_store_data = true,
614*61046927SAndroid Build Coastguard Worker .opt_image_srcs = true,
615*61046927SAndroid Build Coastguard Worker .opt_srcs_options_count = separate_g16 ? 2 : 1,
616*61046927SAndroid Build Coastguard Worker .opt_srcs_options = opt_srcs_options,
617*61046927SAndroid Build Coastguard Worker };
618*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_16bit_tex_image, &opt_16bit_options);
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker if (!stage->key.optimisations_disabled &&
621*61046927SAndroid Build Coastguard Worker ((stage->nir->info.bit_sizes_int | stage->nir->info.bit_sizes_float) & 16)) {
622*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_vectorize, opt_vectorize_callback, device);
623*61046927SAndroid Build Coastguard Worker }
624*61046927SAndroid Build Coastguard Worker }
625*61046927SAndroid Build Coastguard Worker
626*61046927SAndroid Build Coastguard Worker /* cleanup passes */
627*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_alu_width, opt_vectorize_callback, device);
628*61046927SAndroid Build Coastguard Worker
629*61046927SAndroid Build Coastguard Worker /* This pass changes the global float control mode to RTZ, so can't be used
630*61046927SAndroid Build Coastguard Worker * with LLVM, which only supports RTNE, or RT, where the mode needs to match
631*61046927SAndroid Build Coastguard Worker * across separately compiled stages.
632*61046927SAndroid Build Coastguard Worker */
633*61046927SAndroid Build Coastguard Worker if (!radv_use_llvm_for_stage(pdev, stage->stage) && !gl_shader_stage_is_rt(stage->stage))
634*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, ac_nir_opt_pack_half, gfx_level);
635*61046927SAndroid Build Coastguard Worker
636*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_load_const_to_scalar);
637*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_copy_prop);
638*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_dce);
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker if (!stage->key.optimisations_disabled) {
641*61046927SAndroid Build Coastguard Worker sink_opts |= nir_move_comparisons | nir_move_load_ubo | nir_move_load_ssbo | nir_move_alu;
642*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_sink, sink_opts);
643*61046927SAndroid Build Coastguard Worker
644*61046927SAndroid Build Coastguard Worker nir_move_options move_opts = nir_move_const_undef | nir_move_load_ubo | nir_move_load_input |
645*61046927SAndroid Build Coastguard Worker nir_move_comparisons | nir_move_copies | nir_move_alu;
646*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_move, move_opts);
647*61046927SAndroid Build Coastguard Worker
648*61046927SAndroid Build Coastguard Worker /* Run nir_opt_move again to make sure that comparision are as close as possible to the first use to prevent SCC
649*61046927SAndroid Build Coastguard Worker * spilling.
650*61046927SAndroid Build Coastguard Worker */
651*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_move, nir_move_comparisons);
652*61046927SAndroid Build Coastguard Worker }
653*61046927SAndroid Build Coastguard Worker }
654*61046927SAndroid Build Coastguard Worker
655*61046927SAndroid Build Coastguard Worker bool
radv_shader_should_clear_lds(const struct radv_device * device,const nir_shader * shader)656*61046927SAndroid Build Coastguard Worker radv_shader_should_clear_lds(const struct radv_device *device, const nir_shader *shader)
657*61046927SAndroid Build Coastguard Worker {
658*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
659*61046927SAndroid Build Coastguard Worker const struct radv_instance *instance = radv_physical_device_instance(pdev);
660*61046927SAndroid Build Coastguard Worker
661*61046927SAndroid Build Coastguard Worker return (shader->info.stage == MESA_SHADER_COMPUTE || shader->info.stage == MESA_SHADER_MESH ||
662*61046927SAndroid Build Coastguard Worker shader->info.stage == MESA_SHADER_TASK) &&
663*61046927SAndroid Build Coastguard Worker shader->info.shared_size > 0 && instance->drirc.clear_lds;
664*61046927SAndroid Build Coastguard Worker }
665*61046927SAndroid Build Coastguard Worker
666*61046927SAndroid Build Coastguard Worker static uint32_t
radv_get_executable_count(struct radv_pipeline * pipeline)667*61046927SAndroid Build Coastguard Worker radv_get_executable_count(struct radv_pipeline *pipeline)
668*61046927SAndroid Build Coastguard Worker {
669*61046927SAndroid Build Coastguard Worker uint32_t ret = 0;
670*61046927SAndroid Build Coastguard Worker
671*61046927SAndroid Build Coastguard Worker if (pipeline->type == RADV_PIPELINE_RAY_TRACING) {
672*61046927SAndroid Build Coastguard Worker struct radv_ray_tracing_pipeline *rt_pipeline = radv_pipeline_to_ray_tracing(pipeline);
673*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rt_pipeline->stage_count; i++)
674*61046927SAndroid Build Coastguard Worker ret += rt_pipeline->stages[i].shader ? 1 : 0;
675*61046927SAndroid Build Coastguard Worker }
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
678*61046927SAndroid Build Coastguard Worker if (!pipeline->shaders[i])
679*61046927SAndroid Build Coastguard Worker continue;
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker ret += 1u;
682*61046927SAndroid Build Coastguard Worker if (i == MESA_SHADER_GEOMETRY && pipeline->gs_copy_shader) {
683*61046927SAndroid Build Coastguard Worker ret += 1u;
684*61046927SAndroid Build Coastguard Worker }
685*61046927SAndroid Build Coastguard Worker }
686*61046927SAndroid Build Coastguard Worker
687*61046927SAndroid Build Coastguard Worker return ret;
688*61046927SAndroid Build Coastguard Worker }
689*61046927SAndroid Build Coastguard Worker
690*61046927SAndroid Build Coastguard Worker static struct radv_shader *
radv_get_shader_from_executable_index(struct radv_pipeline * pipeline,int index,gl_shader_stage * stage)691*61046927SAndroid Build Coastguard Worker radv_get_shader_from_executable_index(struct radv_pipeline *pipeline, int index, gl_shader_stage *stage)
692*61046927SAndroid Build Coastguard Worker {
693*61046927SAndroid Build Coastguard Worker if (pipeline->type == RADV_PIPELINE_RAY_TRACING) {
694*61046927SAndroid Build Coastguard Worker struct radv_ray_tracing_pipeline *rt_pipeline = radv_pipeline_to_ray_tracing(pipeline);
695*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rt_pipeline->stage_count; i++) {
696*61046927SAndroid Build Coastguard Worker struct radv_ray_tracing_stage *rt_stage = &rt_pipeline->stages[i];
697*61046927SAndroid Build Coastguard Worker if (!rt_stage->shader)
698*61046927SAndroid Build Coastguard Worker continue;
699*61046927SAndroid Build Coastguard Worker
700*61046927SAndroid Build Coastguard Worker if (!index) {
701*61046927SAndroid Build Coastguard Worker *stage = rt_stage->stage;
702*61046927SAndroid Build Coastguard Worker return rt_stage->shader;
703*61046927SAndroid Build Coastguard Worker }
704*61046927SAndroid Build Coastguard Worker
705*61046927SAndroid Build Coastguard Worker index--;
706*61046927SAndroid Build Coastguard Worker }
707*61046927SAndroid Build Coastguard Worker }
708*61046927SAndroid Build Coastguard Worker
709*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MESA_VULKAN_SHADER_STAGES; ++i) {
710*61046927SAndroid Build Coastguard Worker if (!pipeline->shaders[i])
711*61046927SAndroid Build Coastguard Worker continue;
712*61046927SAndroid Build Coastguard Worker if (!index) {
713*61046927SAndroid Build Coastguard Worker *stage = i;
714*61046927SAndroid Build Coastguard Worker return pipeline->shaders[i];
715*61046927SAndroid Build Coastguard Worker }
716*61046927SAndroid Build Coastguard Worker
717*61046927SAndroid Build Coastguard Worker --index;
718*61046927SAndroid Build Coastguard Worker
719*61046927SAndroid Build Coastguard Worker if (i == MESA_SHADER_GEOMETRY && pipeline->gs_copy_shader) {
720*61046927SAndroid Build Coastguard Worker if (!index) {
721*61046927SAndroid Build Coastguard Worker *stage = i;
722*61046927SAndroid Build Coastguard Worker return pipeline->gs_copy_shader;
723*61046927SAndroid Build Coastguard Worker }
724*61046927SAndroid Build Coastguard Worker --index;
725*61046927SAndroid Build Coastguard Worker }
726*61046927SAndroid Build Coastguard Worker }
727*61046927SAndroid Build Coastguard Worker
728*61046927SAndroid Build Coastguard Worker *stage = -1;
729*61046927SAndroid Build Coastguard Worker return NULL;
730*61046927SAndroid Build Coastguard Worker }
731*61046927SAndroid Build Coastguard Worker
732*61046927SAndroid Build Coastguard Worker /* Basically strlcpy (which does not exist on linux) specialized for
733*61046927SAndroid Build Coastguard Worker * descriptions. */
734*61046927SAndroid Build Coastguard Worker static void
desc_copy(char * desc,const char * src)735*61046927SAndroid Build Coastguard Worker desc_copy(char *desc, const char *src)
736*61046927SAndroid Build Coastguard Worker {
737*61046927SAndroid Build Coastguard Worker int len = strlen(src);
738*61046927SAndroid Build Coastguard Worker assert(len < VK_MAX_DESCRIPTION_SIZE);
739*61046927SAndroid Build Coastguard Worker memcpy(desc, src, len);
740*61046927SAndroid Build Coastguard Worker memset(desc + len, 0, VK_MAX_DESCRIPTION_SIZE - len);
741*61046927SAndroid Build Coastguard Worker }
742*61046927SAndroid Build Coastguard Worker
743*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_GetPipelineExecutablePropertiesKHR(VkDevice _device,const VkPipelineInfoKHR * pPipelineInfo,uint32_t * pExecutableCount,VkPipelineExecutablePropertiesKHR * pProperties)744*61046927SAndroid Build Coastguard Worker radv_GetPipelineExecutablePropertiesKHR(VkDevice _device, const VkPipelineInfoKHR *pPipelineInfo,
745*61046927SAndroid Build Coastguard Worker uint32_t *pExecutableCount, VkPipelineExecutablePropertiesKHR *pProperties)
746*61046927SAndroid Build Coastguard Worker {
747*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(radv_pipeline, pipeline, pPipelineInfo->pipeline);
748*61046927SAndroid Build Coastguard Worker const uint32_t total_count = radv_get_executable_count(pipeline);
749*61046927SAndroid Build Coastguard Worker
750*61046927SAndroid Build Coastguard Worker if (!pProperties) {
751*61046927SAndroid Build Coastguard Worker *pExecutableCount = total_count;
752*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
753*61046927SAndroid Build Coastguard Worker }
754*61046927SAndroid Build Coastguard Worker
755*61046927SAndroid Build Coastguard Worker const uint32_t count = MIN2(total_count, *pExecutableCount);
756*61046927SAndroid Build Coastguard Worker for (uint32_t executable_idx = 0; executable_idx < count; executable_idx++) {
757*61046927SAndroid Build Coastguard Worker gl_shader_stage stage;
758*61046927SAndroid Build Coastguard Worker struct radv_shader *shader = radv_get_shader_from_executable_index(pipeline, executable_idx, &stage);
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker pProperties[executable_idx].stages = mesa_to_vk_shader_stage(stage);
761*61046927SAndroid Build Coastguard Worker
762*61046927SAndroid Build Coastguard Worker const char *name = _mesa_shader_stage_to_string(stage);
763*61046927SAndroid Build Coastguard Worker const char *description = NULL;
764*61046927SAndroid Build Coastguard Worker switch (stage) {
765*61046927SAndroid Build Coastguard Worker case MESA_SHADER_VERTEX:
766*61046927SAndroid Build Coastguard Worker description = "Vulkan Vertex Shader";
767*61046927SAndroid Build Coastguard Worker break;
768*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_CTRL:
769*61046927SAndroid Build Coastguard Worker if (!pipeline->shaders[MESA_SHADER_VERTEX]) {
770*61046927SAndroid Build Coastguard Worker pProperties[executable_idx].stages |= VK_SHADER_STAGE_VERTEX_BIT;
771*61046927SAndroid Build Coastguard Worker name = "vertex + tessellation control";
772*61046927SAndroid Build Coastguard Worker description = "Combined Vulkan Vertex and Tessellation Control Shaders";
773*61046927SAndroid Build Coastguard Worker } else {
774*61046927SAndroid Build Coastguard Worker description = "Vulkan Tessellation Control Shader";
775*61046927SAndroid Build Coastguard Worker }
776*61046927SAndroid Build Coastguard Worker break;
777*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_EVAL:
778*61046927SAndroid Build Coastguard Worker description = "Vulkan Tessellation Evaluation Shader";
779*61046927SAndroid Build Coastguard Worker break;
780*61046927SAndroid Build Coastguard Worker case MESA_SHADER_GEOMETRY:
781*61046927SAndroid Build Coastguard Worker if (shader->info.type == RADV_SHADER_TYPE_GS_COPY) {
782*61046927SAndroid Build Coastguard Worker name = "geometry copy";
783*61046927SAndroid Build Coastguard Worker description = "Extra shader stage that loads the GS output ringbuffer into the rasterizer";
784*61046927SAndroid Build Coastguard Worker break;
785*61046927SAndroid Build Coastguard Worker }
786*61046927SAndroid Build Coastguard Worker
787*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[MESA_SHADER_TESS_CTRL] && !pipeline->shaders[MESA_SHADER_TESS_EVAL]) {
788*61046927SAndroid Build Coastguard Worker pProperties[executable_idx].stages |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
789*61046927SAndroid Build Coastguard Worker name = "tessellation evaluation + geometry";
790*61046927SAndroid Build Coastguard Worker description = "Combined Vulkan Tessellation Evaluation and Geometry Shaders";
791*61046927SAndroid Build Coastguard Worker } else if (!pipeline->shaders[MESA_SHADER_TESS_CTRL] && !pipeline->shaders[MESA_SHADER_VERTEX]) {
792*61046927SAndroid Build Coastguard Worker pProperties[executable_idx].stages |= VK_SHADER_STAGE_VERTEX_BIT;
793*61046927SAndroid Build Coastguard Worker name = "vertex + geometry";
794*61046927SAndroid Build Coastguard Worker description = "Combined Vulkan Vertex and Geometry Shaders";
795*61046927SAndroid Build Coastguard Worker } else {
796*61046927SAndroid Build Coastguard Worker description = "Vulkan Geometry Shader";
797*61046927SAndroid Build Coastguard Worker }
798*61046927SAndroid Build Coastguard Worker break;
799*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT:
800*61046927SAndroid Build Coastguard Worker description = "Vulkan Fragment Shader";
801*61046927SAndroid Build Coastguard Worker break;
802*61046927SAndroid Build Coastguard Worker case MESA_SHADER_COMPUTE:
803*61046927SAndroid Build Coastguard Worker description = "Vulkan Compute Shader";
804*61046927SAndroid Build Coastguard Worker break;
805*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MESH:
806*61046927SAndroid Build Coastguard Worker description = "Vulkan Mesh Shader";
807*61046927SAndroid Build Coastguard Worker break;
808*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TASK:
809*61046927SAndroid Build Coastguard Worker description = "Vulkan Task Shader";
810*61046927SAndroid Build Coastguard Worker break;
811*61046927SAndroid Build Coastguard Worker case MESA_SHADER_RAYGEN:
812*61046927SAndroid Build Coastguard Worker description = "Vulkan Ray Generation Shader";
813*61046927SAndroid Build Coastguard Worker break;
814*61046927SAndroid Build Coastguard Worker case MESA_SHADER_ANY_HIT:
815*61046927SAndroid Build Coastguard Worker description = "Vulkan Any-Hit Shader";
816*61046927SAndroid Build Coastguard Worker break;
817*61046927SAndroid Build Coastguard Worker case MESA_SHADER_CLOSEST_HIT:
818*61046927SAndroid Build Coastguard Worker description = "Vulkan Closest-Hit Shader";
819*61046927SAndroid Build Coastguard Worker break;
820*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MISS:
821*61046927SAndroid Build Coastguard Worker description = "Vulkan Miss Shader";
822*61046927SAndroid Build Coastguard Worker break;
823*61046927SAndroid Build Coastguard Worker case MESA_SHADER_INTERSECTION:
824*61046927SAndroid Build Coastguard Worker description = "Shader responsible for traversing the acceleration structure";
825*61046927SAndroid Build Coastguard Worker break;
826*61046927SAndroid Build Coastguard Worker case MESA_SHADER_CALLABLE:
827*61046927SAndroid Build Coastguard Worker description = "Vulkan Callable Shader";
828*61046927SAndroid Build Coastguard Worker break;
829*61046927SAndroid Build Coastguard Worker default:
830*61046927SAndroid Build Coastguard Worker unreachable("Unsupported shader stage");
831*61046927SAndroid Build Coastguard Worker }
832*61046927SAndroid Build Coastguard Worker
833*61046927SAndroid Build Coastguard Worker pProperties[executable_idx].subgroupSize = shader->info.wave_size;
834*61046927SAndroid Build Coastguard Worker desc_copy(pProperties[executable_idx].name, name);
835*61046927SAndroid Build Coastguard Worker desc_copy(pProperties[executable_idx].description, description);
836*61046927SAndroid Build Coastguard Worker }
837*61046927SAndroid Build Coastguard Worker
838*61046927SAndroid Build Coastguard Worker VkResult result = *pExecutableCount < total_count ? VK_INCOMPLETE : VK_SUCCESS;
839*61046927SAndroid Build Coastguard Worker *pExecutableCount = count;
840*61046927SAndroid Build Coastguard Worker return result;
841*61046927SAndroid Build Coastguard Worker }
842*61046927SAndroid Build Coastguard Worker
843*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_GetPipelineExecutableStatisticsKHR(VkDevice _device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pStatisticCount,VkPipelineExecutableStatisticKHR * pStatistics)844*61046927SAndroid Build Coastguard Worker radv_GetPipelineExecutableStatisticsKHR(VkDevice _device, const VkPipelineExecutableInfoKHR *pExecutableInfo,
845*61046927SAndroid Build Coastguard Worker uint32_t *pStatisticCount, VkPipelineExecutableStatisticKHR *pStatistics)
846*61046927SAndroid Build Coastguard Worker {
847*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(radv_device, device, _device);
848*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(radv_pipeline, pipeline, pExecutableInfo->pipeline);
849*61046927SAndroid Build Coastguard Worker gl_shader_stage stage;
850*61046927SAndroid Build Coastguard Worker struct radv_shader *shader =
851*61046927SAndroid Build Coastguard Worker radv_get_shader_from_executable_index(pipeline, pExecutableInfo->executableIndex, &stage);
852*61046927SAndroid Build Coastguard Worker
853*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
854*61046927SAndroid Build Coastguard Worker const enum amd_gfx_level gfx_level = pdev->info.gfx_level;
855*61046927SAndroid Build Coastguard Worker
856*61046927SAndroid Build Coastguard Worker unsigned lds_increment =
857*61046927SAndroid Build Coastguard Worker gfx_level >= GFX11 && stage == MESA_SHADER_FRAGMENT ? 1024 : pdev->info.lds_encode_granularity;
858*61046927SAndroid Build Coastguard Worker
859*61046927SAndroid Build Coastguard Worker VkPipelineExecutableStatisticKHR *s = pStatistics;
860*61046927SAndroid Build Coastguard Worker VkPipelineExecutableStatisticKHR *end = s + (pStatistics ? *pStatisticCount : 0);
861*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
862*61046927SAndroid Build Coastguard Worker
863*61046927SAndroid Build Coastguard Worker if (s < end) {
864*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Driver pipeline hash");
865*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Driver pipeline hash used by RGP");
866*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
867*61046927SAndroid Build Coastguard Worker s->value.u64 = pipeline->pipeline_hash;
868*61046927SAndroid Build Coastguard Worker }
869*61046927SAndroid Build Coastguard Worker ++s;
870*61046927SAndroid Build Coastguard Worker
871*61046927SAndroid Build Coastguard Worker if (s < end) {
872*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "SGPRs");
873*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Number of SGPR registers allocated per subgroup");
874*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
875*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->config.num_sgprs;
876*61046927SAndroid Build Coastguard Worker }
877*61046927SAndroid Build Coastguard Worker ++s;
878*61046927SAndroid Build Coastguard Worker
879*61046927SAndroid Build Coastguard Worker if (s < end) {
880*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "VGPRs");
881*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Number of VGPR registers allocated per subgroup");
882*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
883*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->config.num_vgprs;
884*61046927SAndroid Build Coastguard Worker }
885*61046927SAndroid Build Coastguard Worker ++s;
886*61046927SAndroid Build Coastguard Worker
887*61046927SAndroid Build Coastguard Worker if (s < end) {
888*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Spilled SGPRs");
889*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Number of SGPR registers spilled per subgroup");
890*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
891*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->config.spilled_sgprs;
892*61046927SAndroid Build Coastguard Worker }
893*61046927SAndroid Build Coastguard Worker ++s;
894*61046927SAndroid Build Coastguard Worker
895*61046927SAndroid Build Coastguard Worker if (s < end) {
896*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Spilled VGPRs");
897*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Number of VGPR registers spilled per subgroup");
898*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
899*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->config.spilled_vgprs;
900*61046927SAndroid Build Coastguard Worker }
901*61046927SAndroid Build Coastguard Worker ++s;
902*61046927SAndroid Build Coastguard Worker
903*61046927SAndroid Build Coastguard Worker if (s < end) {
904*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Code size");
905*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Code size in bytes");
906*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
907*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->exec_size;
908*61046927SAndroid Build Coastguard Worker }
909*61046927SAndroid Build Coastguard Worker ++s;
910*61046927SAndroid Build Coastguard Worker
911*61046927SAndroid Build Coastguard Worker if (s < end) {
912*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "LDS size");
913*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "LDS size in bytes per workgroup");
914*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
915*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->config.lds_size * lds_increment;
916*61046927SAndroid Build Coastguard Worker }
917*61046927SAndroid Build Coastguard Worker ++s;
918*61046927SAndroid Build Coastguard Worker
919*61046927SAndroid Build Coastguard Worker if (s < end) {
920*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Scratch size");
921*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Private memory in bytes per subgroup");
922*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
923*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->config.scratch_bytes_per_wave;
924*61046927SAndroid Build Coastguard Worker }
925*61046927SAndroid Build Coastguard Worker ++s;
926*61046927SAndroid Build Coastguard Worker
927*61046927SAndroid Build Coastguard Worker if (s < end) {
928*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Subgroups per SIMD");
929*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "The maximum number of subgroups in flight on a SIMD unit");
930*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
931*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->max_waves;
932*61046927SAndroid Build Coastguard Worker }
933*61046927SAndroid Build Coastguard Worker ++s;
934*61046927SAndroid Build Coastguard Worker
935*61046927SAndroid Build Coastguard Worker if (s < end) {
936*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Combined inputs");
937*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Number of input slots reserved for the shader (including merged stages)");
938*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
939*61046927SAndroid Build Coastguard Worker s->value.u64 = 0;
940*61046927SAndroid Build Coastguard Worker
941*61046927SAndroid Build Coastguard Worker switch (stage) {
942*61046927SAndroid Build Coastguard Worker case MESA_SHADER_VERTEX:
943*61046927SAndroid Build Coastguard Worker if (gfx_level <= GFX8 || (!shader->info.vs.as_es && !shader->info.vs.as_ls)) {
944*61046927SAndroid Build Coastguard Worker /* VS inputs when VS is a separate stage */
945*61046927SAndroid Build Coastguard Worker s->value.u64 += util_bitcount(shader->info.vs.input_slot_usage_mask);
946*61046927SAndroid Build Coastguard Worker }
947*61046927SAndroid Build Coastguard Worker break;
948*61046927SAndroid Build Coastguard Worker
949*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_CTRL:
950*61046927SAndroid Build Coastguard Worker if (gfx_level >= GFX9) {
951*61046927SAndroid Build Coastguard Worker /* VS inputs when pipeline has tess */
952*61046927SAndroid Build Coastguard Worker s->value.u64 += util_bitcount(shader->info.vs.input_slot_usage_mask);
953*61046927SAndroid Build Coastguard Worker }
954*61046927SAndroid Build Coastguard Worker
955*61046927SAndroid Build Coastguard Worker /* VS -> TCS inputs */
956*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.tcs.num_linked_inputs;
957*61046927SAndroid Build Coastguard Worker break;
958*61046927SAndroid Build Coastguard Worker
959*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_EVAL:
960*61046927SAndroid Build Coastguard Worker if (gfx_level <= GFX8 || !shader->info.tes.as_es) {
961*61046927SAndroid Build Coastguard Worker /* TCS -> TES inputs when TES is a separate stage */
962*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.tes.num_linked_inputs + shader->info.tes.num_linked_patch_inputs;
963*61046927SAndroid Build Coastguard Worker }
964*61046927SAndroid Build Coastguard Worker break;
965*61046927SAndroid Build Coastguard Worker
966*61046927SAndroid Build Coastguard Worker case MESA_SHADER_GEOMETRY:
967*61046927SAndroid Build Coastguard Worker /* The IO stats of the GS copy shader are already reflected by GS and FS, so leave it empty. */
968*61046927SAndroid Build Coastguard Worker if (shader->info.type == RADV_SHADER_TYPE_GS_COPY)
969*61046927SAndroid Build Coastguard Worker break;
970*61046927SAndroid Build Coastguard Worker
971*61046927SAndroid Build Coastguard Worker if (gfx_level >= GFX9) {
972*61046927SAndroid Build Coastguard Worker if (shader->info.gs.es_type == MESA_SHADER_VERTEX) {
973*61046927SAndroid Build Coastguard Worker /* VS inputs when pipeline has GS but no tess */
974*61046927SAndroid Build Coastguard Worker s->value.u64 += util_bitcount(shader->info.vs.input_slot_usage_mask);
975*61046927SAndroid Build Coastguard Worker } else if (shader->info.gs.es_type == MESA_SHADER_TESS_EVAL) {
976*61046927SAndroid Build Coastguard Worker /* TCS -> TES inputs when pipeline has GS */
977*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.tes.num_linked_inputs + shader->info.tes.num_linked_patch_inputs;
978*61046927SAndroid Build Coastguard Worker }
979*61046927SAndroid Build Coastguard Worker }
980*61046927SAndroid Build Coastguard Worker
981*61046927SAndroid Build Coastguard Worker /* VS -> GS or TES -> GS inputs */
982*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.gs.num_linked_inputs;
983*61046927SAndroid Build Coastguard Worker break;
984*61046927SAndroid Build Coastguard Worker
985*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT:
986*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.ps.num_interp + shader->info.ps.num_prim_interp;
987*61046927SAndroid Build Coastguard Worker break;
988*61046927SAndroid Build Coastguard Worker
989*61046927SAndroid Build Coastguard Worker default:
990*61046927SAndroid Build Coastguard Worker /* Other stages don't have IO or we are not interested in them. */
991*61046927SAndroid Build Coastguard Worker break;
992*61046927SAndroid Build Coastguard Worker }
993*61046927SAndroid Build Coastguard Worker }
994*61046927SAndroid Build Coastguard Worker ++s;
995*61046927SAndroid Build Coastguard Worker
996*61046927SAndroid Build Coastguard Worker if (s < end) {
997*61046927SAndroid Build Coastguard Worker desc_copy(s->name, "Combined outputs");
998*61046927SAndroid Build Coastguard Worker desc_copy(s->description, "Number of output slots reserved for the shader (including merged stages)");
999*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
1000*61046927SAndroid Build Coastguard Worker s->value.u64 = 0;
1001*61046927SAndroid Build Coastguard Worker
1002*61046927SAndroid Build Coastguard Worker switch (stage) {
1003*61046927SAndroid Build Coastguard Worker case MESA_SHADER_VERTEX:
1004*61046927SAndroid Build Coastguard Worker if (!shader->info.vs.as_ls && !shader->info.vs.as_es) {
1005*61046927SAndroid Build Coastguard Worker /* VS -> FS outputs. */
1006*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.outinfo.pos_exports + shader->info.outinfo.param_exports +
1007*61046927SAndroid Build Coastguard Worker shader->info.outinfo.prim_param_exports;
1008*61046927SAndroid Build Coastguard Worker } else if (gfx_level <= GFX8) {
1009*61046927SAndroid Build Coastguard Worker /* VS -> TCS, VS -> GS outputs on GFX6-8 */
1010*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.vs.num_linked_outputs;
1011*61046927SAndroid Build Coastguard Worker }
1012*61046927SAndroid Build Coastguard Worker break;
1013*61046927SAndroid Build Coastguard Worker
1014*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_CTRL:
1015*61046927SAndroid Build Coastguard Worker if (gfx_level >= GFX9) {
1016*61046927SAndroid Build Coastguard Worker /* VS -> TCS outputs on GFX9+ */
1017*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.vs.num_linked_outputs;
1018*61046927SAndroid Build Coastguard Worker }
1019*61046927SAndroid Build Coastguard Worker
1020*61046927SAndroid Build Coastguard Worker /* TCS -> TES outputs */
1021*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.tcs.num_linked_outputs + shader->info.tcs.num_linked_patch_outputs;
1022*61046927SAndroid Build Coastguard Worker break;
1023*61046927SAndroid Build Coastguard Worker
1024*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_EVAL:
1025*61046927SAndroid Build Coastguard Worker if (!shader->info.tes.as_es) {
1026*61046927SAndroid Build Coastguard Worker /* TES -> FS outputs */
1027*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.outinfo.pos_exports + shader->info.outinfo.param_exports +
1028*61046927SAndroid Build Coastguard Worker shader->info.outinfo.prim_param_exports;
1029*61046927SAndroid Build Coastguard Worker } else if (gfx_level <= GFX8) {
1030*61046927SAndroid Build Coastguard Worker /* TES -> GS outputs on GFX6-8 */
1031*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.tes.num_linked_outputs;
1032*61046927SAndroid Build Coastguard Worker }
1033*61046927SAndroid Build Coastguard Worker break;
1034*61046927SAndroid Build Coastguard Worker
1035*61046927SAndroid Build Coastguard Worker case MESA_SHADER_GEOMETRY:
1036*61046927SAndroid Build Coastguard Worker /* The IO stats of the GS copy shader are already reflected by GS and FS, so leave it empty. */
1037*61046927SAndroid Build Coastguard Worker if (shader->info.type == RADV_SHADER_TYPE_GS_COPY)
1038*61046927SAndroid Build Coastguard Worker break;
1039*61046927SAndroid Build Coastguard Worker
1040*61046927SAndroid Build Coastguard Worker if (gfx_level >= GFX9) {
1041*61046927SAndroid Build Coastguard Worker if (shader->info.gs.es_type == MESA_SHADER_VERTEX) {
1042*61046927SAndroid Build Coastguard Worker /* VS -> GS outputs on GFX9+ */
1043*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.vs.num_linked_outputs;
1044*61046927SAndroid Build Coastguard Worker } else if (shader->info.gs.es_type == MESA_SHADER_TESS_EVAL) {
1045*61046927SAndroid Build Coastguard Worker /* TES -> GS outputs on GFX9+ */
1046*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.tes.num_linked_outputs;
1047*61046927SAndroid Build Coastguard Worker }
1048*61046927SAndroid Build Coastguard Worker }
1049*61046927SAndroid Build Coastguard Worker
1050*61046927SAndroid Build Coastguard Worker if (shader->info.is_ngg) {
1051*61046927SAndroid Build Coastguard Worker /* GS -> FS outputs (GFX10+ NGG) */
1052*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.outinfo.pos_exports + shader->info.outinfo.param_exports +
1053*61046927SAndroid Build Coastguard Worker shader->info.outinfo.prim_param_exports;
1054*61046927SAndroid Build Coastguard Worker } else {
1055*61046927SAndroid Build Coastguard Worker /* GS -> FS outputs (GFX6-10.3 legacy) */
1056*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.gs.gsvs_vertex_size / 16;
1057*61046927SAndroid Build Coastguard Worker }
1058*61046927SAndroid Build Coastguard Worker break;
1059*61046927SAndroid Build Coastguard Worker
1060*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MESH:
1061*61046927SAndroid Build Coastguard Worker /* MS -> FS outputs */
1062*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.outinfo.pos_exports + shader->info.outinfo.param_exports +
1063*61046927SAndroid Build Coastguard Worker shader->info.outinfo.prim_param_exports;
1064*61046927SAndroid Build Coastguard Worker break;
1065*61046927SAndroid Build Coastguard Worker
1066*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT:
1067*61046927SAndroid Build Coastguard Worker s->value.u64 += shader->info.ps.colors_written + !!shader->info.ps.writes_z +
1068*61046927SAndroid Build Coastguard Worker !!shader->info.ps.writes_stencil + !!shader->info.ps.writes_sample_mask +
1069*61046927SAndroid Build Coastguard Worker !!shader->info.ps.writes_mrt0_alpha;
1070*61046927SAndroid Build Coastguard Worker break;
1071*61046927SAndroid Build Coastguard Worker
1072*61046927SAndroid Build Coastguard Worker default:
1073*61046927SAndroid Build Coastguard Worker /* Other stages don't have IO or we are not interested in them. */
1074*61046927SAndroid Build Coastguard Worker break;
1075*61046927SAndroid Build Coastguard Worker }
1076*61046927SAndroid Build Coastguard Worker }
1077*61046927SAndroid Build Coastguard Worker ++s;
1078*61046927SAndroid Build Coastguard Worker
1079*61046927SAndroid Build Coastguard Worker if (shader->statistics) {
1080*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < aco_num_statistics; i++) {
1081*61046927SAndroid Build Coastguard Worker const struct aco_compiler_statistic_info *info = &aco_statistic_infos[i];
1082*61046927SAndroid Build Coastguard Worker if (s < end) {
1083*61046927SAndroid Build Coastguard Worker desc_copy(s->name, info->name);
1084*61046927SAndroid Build Coastguard Worker desc_copy(s->description, info->desc);
1085*61046927SAndroid Build Coastguard Worker s->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
1086*61046927SAndroid Build Coastguard Worker s->value.u64 = shader->statistics[i];
1087*61046927SAndroid Build Coastguard Worker }
1088*61046927SAndroid Build Coastguard Worker ++s;
1089*61046927SAndroid Build Coastguard Worker }
1090*61046927SAndroid Build Coastguard Worker }
1091*61046927SAndroid Build Coastguard Worker
1092*61046927SAndroid Build Coastguard Worker if (!pStatistics)
1093*61046927SAndroid Build Coastguard Worker *pStatisticCount = s - pStatistics;
1094*61046927SAndroid Build Coastguard Worker else if (s > end) {
1095*61046927SAndroid Build Coastguard Worker *pStatisticCount = end - pStatistics;
1096*61046927SAndroid Build Coastguard Worker result = VK_INCOMPLETE;
1097*61046927SAndroid Build Coastguard Worker } else {
1098*61046927SAndroid Build Coastguard Worker *pStatisticCount = s - pStatistics;
1099*61046927SAndroid Build Coastguard Worker }
1100*61046927SAndroid Build Coastguard Worker
1101*61046927SAndroid Build Coastguard Worker return result;
1102*61046927SAndroid Build Coastguard Worker }
1103*61046927SAndroid Build Coastguard Worker
1104*61046927SAndroid Build Coastguard Worker static VkResult
radv_copy_representation(void * data,size_t * data_size,const char * src)1105*61046927SAndroid Build Coastguard Worker radv_copy_representation(void *data, size_t *data_size, const char *src)
1106*61046927SAndroid Build Coastguard Worker {
1107*61046927SAndroid Build Coastguard Worker size_t total_size = strlen(src) + 1;
1108*61046927SAndroid Build Coastguard Worker
1109*61046927SAndroid Build Coastguard Worker if (!data) {
1110*61046927SAndroid Build Coastguard Worker *data_size = total_size;
1111*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
1112*61046927SAndroid Build Coastguard Worker }
1113*61046927SAndroid Build Coastguard Worker
1114*61046927SAndroid Build Coastguard Worker size_t size = MIN2(total_size, *data_size);
1115*61046927SAndroid Build Coastguard Worker
1116*61046927SAndroid Build Coastguard Worker memcpy(data, src, size);
1117*61046927SAndroid Build Coastguard Worker if (size)
1118*61046927SAndroid Build Coastguard Worker *((char *)data + size - 1) = 0;
1119*61046927SAndroid Build Coastguard Worker return size < total_size ? VK_INCOMPLETE : VK_SUCCESS;
1120*61046927SAndroid Build Coastguard Worker }
1121*61046927SAndroid Build Coastguard Worker
1122*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_GetPipelineExecutableInternalRepresentationsKHR(VkDevice _device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pInternalRepresentationCount,VkPipelineExecutableInternalRepresentationKHR * pInternalRepresentations)1123*61046927SAndroid Build Coastguard Worker radv_GetPipelineExecutableInternalRepresentationsKHR(
1124*61046927SAndroid Build Coastguard Worker VkDevice _device, const VkPipelineExecutableInfoKHR *pExecutableInfo, uint32_t *pInternalRepresentationCount,
1125*61046927SAndroid Build Coastguard Worker VkPipelineExecutableInternalRepresentationKHR *pInternalRepresentations)
1126*61046927SAndroid Build Coastguard Worker {
1127*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(radv_device, device, _device);
1128*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(radv_pipeline, pipeline, pExecutableInfo->pipeline);
1129*61046927SAndroid Build Coastguard Worker const struct radv_physical_device *pdev = radv_device_physical(device);
1130*61046927SAndroid Build Coastguard Worker gl_shader_stage stage;
1131*61046927SAndroid Build Coastguard Worker struct radv_shader *shader =
1132*61046927SAndroid Build Coastguard Worker radv_get_shader_from_executable_index(pipeline, pExecutableInfo->executableIndex, &stage);
1133*61046927SAndroid Build Coastguard Worker
1134*61046927SAndroid Build Coastguard Worker VkPipelineExecutableInternalRepresentationKHR *p = pInternalRepresentations;
1135*61046927SAndroid Build Coastguard Worker VkPipelineExecutableInternalRepresentationKHR *end =
1136*61046927SAndroid Build Coastguard Worker p + (pInternalRepresentations ? *pInternalRepresentationCount : 0);
1137*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
1138*61046927SAndroid Build Coastguard Worker /* optimized NIR */
1139*61046927SAndroid Build Coastguard Worker if (p < end) {
1140*61046927SAndroid Build Coastguard Worker p->isText = true;
1141*61046927SAndroid Build Coastguard Worker desc_copy(p->name, "NIR Shader(s)");
1142*61046927SAndroid Build Coastguard Worker desc_copy(p->description, "The optimized NIR shader(s)");
1143*61046927SAndroid Build Coastguard Worker if (radv_copy_representation(p->pData, &p->dataSize, shader->nir_string) != VK_SUCCESS)
1144*61046927SAndroid Build Coastguard Worker result = VK_INCOMPLETE;
1145*61046927SAndroid Build Coastguard Worker }
1146*61046927SAndroid Build Coastguard Worker ++p;
1147*61046927SAndroid Build Coastguard Worker
1148*61046927SAndroid Build Coastguard Worker /* backend IR */
1149*61046927SAndroid Build Coastguard Worker if (p < end) {
1150*61046927SAndroid Build Coastguard Worker p->isText = true;
1151*61046927SAndroid Build Coastguard Worker if (radv_use_llvm_for_stage(pdev, stage)) {
1152*61046927SAndroid Build Coastguard Worker desc_copy(p->name, "LLVM IR");
1153*61046927SAndroid Build Coastguard Worker desc_copy(p->description, "The LLVM IR after some optimizations");
1154*61046927SAndroid Build Coastguard Worker } else {
1155*61046927SAndroid Build Coastguard Worker desc_copy(p->name, "ACO IR");
1156*61046927SAndroid Build Coastguard Worker desc_copy(p->description, "The ACO IR after some optimizations");
1157*61046927SAndroid Build Coastguard Worker }
1158*61046927SAndroid Build Coastguard Worker if (radv_copy_representation(p->pData, &p->dataSize, shader->ir_string) != VK_SUCCESS)
1159*61046927SAndroid Build Coastguard Worker result = VK_INCOMPLETE;
1160*61046927SAndroid Build Coastguard Worker }
1161*61046927SAndroid Build Coastguard Worker ++p;
1162*61046927SAndroid Build Coastguard Worker
1163*61046927SAndroid Build Coastguard Worker /* Disassembler */
1164*61046927SAndroid Build Coastguard Worker if (p < end && shader->disasm_string) {
1165*61046927SAndroid Build Coastguard Worker p->isText = true;
1166*61046927SAndroid Build Coastguard Worker desc_copy(p->name, "Assembly");
1167*61046927SAndroid Build Coastguard Worker desc_copy(p->description, "Final Assembly");
1168*61046927SAndroid Build Coastguard Worker if (radv_copy_representation(p->pData, &p->dataSize, shader->disasm_string) != VK_SUCCESS)
1169*61046927SAndroid Build Coastguard Worker result = VK_INCOMPLETE;
1170*61046927SAndroid Build Coastguard Worker }
1171*61046927SAndroid Build Coastguard Worker ++p;
1172*61046927SAndroid Build Coastguard Worker
1173*61046927SAndroid Build Coastguard Worker if (!pInternalRepresentations)
1174*61046927SAndroid Build Coastguard Worker *pInternalRepresentationCount = p - pInternalRepresentations;
1175*61046927SAndroid Build Coastguard Worker else if (p > end) {
1176*61046927SAndroid Build Coastguard Worker result = VK_INCOMPLETE;
1177*61046927SAndroid Build Coastguard Worker *pInternalRepresentationCount = end - pInternalRepresentations;
1178*61046927SAndroid Build Coastguard Worker } else {
1179*61046927SAndroid Build Coastguard Worker *pInternalRepresentationCount = p - pInternalRepresentations;
1180*61046927SAndroid Build Coastguard Worker }
1181*61046927SAndroid Build Coastguard Worker
1182*61046927SAndroid Build Coastguard Worker return result;
1183*61046927SAndroid Build Coastguard Worker }
1184*61046927SAndroid Build Coastguard Worker
1185*61046927SAndroid Build Coastguard Worker static void
vk_shader_module_finish(void * _module)1186*61046927SAndroid Build Coastguard Worker vk_shader_module_finish(void *_module)
1187*61046927SAndroid Build Coastguard Worker {
1188*61046927SAndroid Build Coastguard Worker struct vk_shader_module *module = _module;
1189*61046927SAndroid Build Coastguard Worker vk_object_base_finish(&module->base);
1190*61046927SAndroid Build Coastguard Worker }
1191*61046927SAndroid Build Coastguard Worker
1192*61046927SAndroid Build Coastguard Worker VkPipelineShaderStageCreateInfo *
radv_copy_shader_stage_create_info(struct radv_device * device,uint32_t stageCount,const VkPipelineShaderStageCreateInfo * pStages,void * mem_ctx)1193*61046927SAndroid Build Coastguard Worker radv_copy_shader_stage_create_info(struct radv_device *device, uint32_t stageCount,
1194*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *pStages, void *mem_ctx)
1195*61046927SAndroid Build Coastguard Worker {
1196*61046927SAndroid Build Coastguard Worker VkPipelineShaderStageCreateInfo *new_stages;
1197*61046927SAndroid Build Coastguard Worker
1198*61046927SAndroid Build Coastguard Worker size_t size = sizeof(VkPipelineShaderStageCreateInfo) * stageCount;
1199*61046927SAndroid Build Coastguard Worker new_stages = ralloc_size(mem_ctx, size);
1200*61046927SAndroid Build Coastguard Worker if (!new_stages)
1201*61046927SAndroid Build Coastguard Worker return NULL;
1202*61046927SAndroid Build Coastguard Worker
1203*61046927SAndroid Build Coastguard Worker if (size)
1204*61046927SAndroid Build Coastguard Worker memcpy(new_stages, pStages, size);
1205*61046927SAndroid Build Coastguard Worker
1206*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < stageCount; i++) {
1207*61046927SAndroid Build Coastguard Worker VK_FROM_HANDLE(vk_shader_module, module, new_stages[i].module);
1208*61046927SAndroid Build Coastguard Worker
1209*61046927SAndroid Build Coastguard Worker const VkShaderModuleCreateInfo *minfo = vk_find_struct_const(pStages[i].pNext, SHADER_MODULE_CREATE_INFO);
1210*61046927SAndroid Build Coastguard Worker
1211*61046927SAndroid Build Coastguard Worker if (module) {
1212*61046927SAndroid Build Coastguard Worker struct vk_shader_module *new_module = ralloc_size(mem_ctx, sizeof(struct vk_shader_module) + module->size);
1213*61046927SAndroid Build Coastguard Worker if (!new_module)
1214*61046927SAndroid Build Coastguard Worker return NULL;
1215*61046927SAndroid Build Coastguard Worker
1216*61046927SAndroid Build Coastguard Worker ralloc_set_destructor(new_module, vk_shader_module_finish);
1217*61046927SAndroid Build Coastguard Worker vk_object_base_init(&device->vk, &new_module->base, VK_OBJECT_TYPE_SHADER_MODULE);
1218*61046927SAndroid Build Coastguard Worker
1219*61046927SAndroid Build Coastguard Worker new_module->nir = NULL;
1220*61046927SAndroid Build Coastguard Worker memcpy(new_module->hash, module->hash, sizeof(module->hash));
1221*61046927SAndroid Build Coastguard Worker new_module->size = module->size;
1222*61046927SAndroid Build Coastguard Worker memcpy(new_module->data, module->data, module->size);
1223*61046927SAndroid Build Coastguard Worker
1224*61046927SAndroid Build Coastguard Worker module = new_module;
1225*61046927SAndroid Build Coastguard Worker } else if (minfo) {
1226*61046927SAndroid Build Coastguard Worker module = ralloc_size(mem_ctx, sizeof(struct vk_shader_module) + minfo->codeSize);
1227*61046927SAndroid Build Coastguard Worker if (!module)
1228*61046927SAndroid Build Coastguard Worker return NULL;
1229*61046927SAndroid Build Coastguard Worker
1230*61046927SAndroid Build Coastguard Worker vk_shader_module_init(&device->vk, module, minfo);
1231*61046927SAndroid Build Coastguard Worker }
1232*61046927SAndroid Build Coastguard Worker
1233*61046927SAndroid Build Coastguard Worker if (module) {
1234*61046927SAndroid Build Coastguard Worker const VkSpecializationInfo *spec = new_stages[i].pSpecializationInfo;
1235*61046927SAndroid Build Coastguard Worker if (spec) {
1236*61046927SAndroid Build Coastguard Worker VkSpecializationInfo *new_spec = ralloc(mem_ctx, VkSpecializationInfo);
1237*61046927SAndroid Build Coastguard Worker if (!new_spec)
1238*61046927SAndroid Build Coastguard Worker return NULL;
1239*61046927SAndroid Build Coastguard Worker
1240*61046927SAndroid Build Coastguard Worker new_spec->mapEntryCount = spec->mapEntryCount;
1241*61046927SAndroid Build Coastguard Worker uint32_t map_entries_size = sizeof(VkSpecializationMapEntry) * spec->mapEntryCount;
1242*61046927SAndroid Build Coastguard Worker new_spec->pMapEntries = ralloc_size(mem_ctx, map_entries_size);
1243*61046927SAndroid Build Coastguard Worker if (!new_spec->pMapEntries)
1244*61046927SAndroid Build Coastguard Worker return NULL;
1245*61046927SAndroid Build Coastguard Worker memcpy((void *)new_spec->pMapEntries, spec->pMapEntries, map_entries_size);
1246*61046927SAndroid Build Coastguard Worker
1247*61046927SAndroid Build Coastguard Worker new_spec->dataSize = spec->dataSize;
1248*61046927SAndroid Build Coastguard Worker new_spec->pData = ralloc_size(mem_ctx, spec->dataSize);
1249*61046927SAndroid Build Coastguard Worker if (!new_spec->pData)
1250*61046927SAndroid Build Coastguard Worker return NULL;
1251*61046927SAndroid Build Coastguard Worker memcpy((void *)new_spec->pData, spec->pData, spec->dataSize);
1252*61046927SAndroid Build Coastguard Worker
1253*61046927SAndroid Build Coastguard Worker new_stages[i].pSpecializationInfo = new_spec;
1254*61046927SAndroid Build Coastguard Worker }
1255*61046927SAndroid Build Coastguard Worker
1256*61046927SAndroid Build Coastguard Worker new_stages[i].module = vk_shader_module_to_handle(module);
1257*61046927SAndroid Build Coastguard Worker new_stages[i].pName = ralloc_strdup(mem_ctx, new_stages[i].pName);
1258*61046927SAndroid Build Coastguard Worker if (!new_stages[i].pName)
1259*61046927SAndroid Build Coastguard Worker return NULL;
1260*61046927SAndroid Build Coastguard Worker new_stages[i].pNext = NULL;
1261*61046927SAndroid Build Coastguard Worker }
1262*61046927SAndroid Build Coastguard Worker }
1263*61046927SAndroid Build Coastguard Worker
1264*61046927SAndroid Build Coastguard Worker return new_stages;
1265*61046927SAndroid Build Coastguard Worker }
1266*61046927SAndroid Build Coastguard Worker
1267*61046927SAndroid Build Coastguard Worker void
radv_pipeline_hash(const struct radv_device * device,const struct radv_pipeline_layout * pipeline_layout,struct mesa_sha1 * ctx)1268*61046927SAndroid Build Coastguard Worker radv_pipeline_hash(const struct radv_device *device, const struct radv_pipeline_layout *pipeline_layout,
1269*61046927SAndroid Build Coastguard Worker struct mesa_sha1 *ctx)
1270*61046927SAndroid Build Coastguard Worker {
1271*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, device->cache_hash, sizeof(device->cache_hash));
1272*61046927SAndroid Build Coastguard Worker if (pipeline_layout)
1273*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, pipeline_layout->hash, sizeof(pipeline_layout->hash));
1274*61046927SAndroid Build Coastguard Worker }
1275*61046927SAndroid Build Coastguard Worker
1276*61046927SAndroid Build Coastguard Worker void
radv_pipeline_hash_shader_stage(VkPipelineCreateFlags2KHR pipeline_flags,const VkPipelineShaderStageCreateInfo * sinfo,const struct radv_shader_stage_key * stage_key,struct mesa_sha1 * ctx)1277*61046927SAndroid Build Coastguard Worker radv_pipeline_hash_shader_stage(VkPipelineCreateFlags2KHR pipeline_flags,
1278*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *sinfo,
1279*61046927SAndroid Build Coastguard Worker const struct radv_shader_stage_key *stage_key, struct mesa_sha1 *ctx)
1280*61046927SAndroid Build Coastguard Worker {
1281*61046927SAndroid Build Coastguard Worker unsigned char shader_sha1[SHA1_DIGEST_LENGTH];
1282*61046927SAndroid Build Coastguard Worker
1283*61046927SAndroid Build Coastguard Worker vk_pipeline_hash_shader_stage(pipeline_flags, sinfo, NULL, shader_sha1);
1284*61046927SAndroid Build Coastguard Worker
1285*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, shader_sha1, sizeof(shader_sha1));
1286*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, stage_key, sizeof(*stage_key));
1287*61046927SAndroid Build Coastguard Worker }
1288