1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2015 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include <assert.h>
25*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
26*61046927SAndroid Build Coastguard Worker #include <string.h>
27*61046927SAndroid Build Coastguard Worker #include <unistd.h>
28*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
31*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
32*61046927SAndroid Build Coastguard Worker #include "common/intel_compute_slm.h"
33*61046927SAndroid Build Coastguard Worker #include "common/intel_l3_config.h"
34*61046927SAndroid Build Coastguard Worker #include "common/intel_sample_positions.h"
35*61046927SAndroid Build Coastguard Worker #include "compiler/brw_disasm.h"
36*61046927SAndroid Build Coastguard Worker #include "anv_private.h"
37*61046927SAndroid Build Coastguard Worker #include "compiler/brw_nir.h"
38*61046927SAndroid Build Coastguard Worker #include "compiler/brw_nir_rt.h"
39*61046927SAndroid Build Coastguard Worker #include "compiler/intel_nir.h"
40*61046927SAndroid Build Coastguard Worker #include "anv_nir.h"
41*61046927SAndroid Build Coastguard Worker #include "nir/nir_xfb_info.h"
42*61046927SAndroid Build Coastguard Worker #include "spirv/nir_spirv.h"
43*61046927SAndroid Build Coastguard Worker #include "vk_nir_convert_ycbcr.h"
44*61046927SAndroid Build Coastguard Worker #include "vk_nir.h"
45*61046927SAndroid Build Coastguard Worker #include "vk_pipeline.h"
46*61046927SAndroid Build Coastguard Worker #include "vk_render_pass.h"
47*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker struct lower_set_vtx_and_prim_count_state {
50*61046927SAndroid Build Coastguard Worker nir_variable *primitive_count;
51*61046927SAndroid Build Coastguard Worker };
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker static nir_variable *
anv_nir_prim_count_store(nir_builder * b,nir_def * val)54*61046927SAndroid Build Coastguard Worker anv_nir_prim_count_store(nir_builder *b, nir_def *val)
55*61046927SAndroid Build Coastguard Worker {
56*61046927SAndroid Build Coastguard Worker nir_variable *primitive_count =
57*61046927SAndroid Build Coastguard Worker nir_variable_create(b->shader,
58*61046927SAndroid Build Coastguard Worker nir_var_shader_out,
59*61046927SAndroid Build Coastguard Worker glsl_uint_type(),
60*61046927SAndroid Build Coastguard Worker "gl_PrimitiveCountNV");
61*61046927SAndroid Build Coastguard Worker primitive_count->data.location = VARYING_SLOT_PRIMITIVE_COUNT;
62*61046927SAndroid Build Coastguard Worker primitive_count->data.interpolation = INTERP_MODE_NONE;
63*61046927SAndroid Build Coastguard Worker
64*61046927SAndroid Build Coastguard Worker nir_def *local_invocation_index = nir_load_local_invocation_index(b);
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker nir_def *cmp = nir_ieq_imm(b, local_invocation_index, 0);
67*61046927SAndroid Build Coastguard Worker nir_if *if_stmt = nir_push_if(b, cmp);
68*61046927SAndroid Build Coastguard Worker {
69*61046927SAndroid Build Coastguard Worker nir_deref_instr *prim_count_deref = nir_build_deref_var(b, primitive_count);
70*61046927SAndroid Build Coastguard Worker nir_store_deref(b, prim_count_deref, val, 1);
71*61046927SAndroid Build Coastguard Worker }
72*61046927SAndroid Build Coastguard Worker nir_pop_if(b, if_stmt);
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker return primitive_count;
75*61046927SAndroid Build Coastguard Worker }
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker static bool
anv_nir_lower_set_vtx_and_prim_count_instr(nir_builder * b,nir_intrinsic_instr * intrin,void * data)78*61046927SAndroid Build Coastguard Worker anv_nir_lower_set_vtx_and_prim_count_instr(nir_builder *b,
79*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin,
80*61046927SAndroid Build Coastguard Worker void *data)
81*61046927SAndroid Build Coastguard Worker {
82*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic != nir_intrinsic_set_vertex_and_primitive_count)
83*61046927SAndroid Build Coastguard Worker return false;
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker /* Detect some cases of invalid primitive count. They might lead to URB
86*61046927SAndroid Build Coastguard Worker * memory corruption, where workgroups overwrite each other output memory.
87*61046927SAndroid Build Coastguard Worker */
88*61046927SAndroid Build Coastguard Worker if (nir_src_is_const(intrin->src[1]) &&
89*61046927SAndroid Build Coastguard Worker nir_src_as_uint(intrin->src[1]) > b->shader->info.mesh.max_primitives_out) {
90*61046927SAndroid Build Coastguard Worker assert(!"number of primitives bigger than max specified");
91*61046927SAndroid Build Coastguard Worker }
92*61046927SAndroid Build Coastguard Worker
93*61046927SAndroid Build Coastguard Worker struct lower_set_vtx_and_prim_count_state *state = data;
94*61046927SAndroid Build Coastguard Worker /* this intrinsic should show up only once */
95*61046927SAndroid Build Coastguard Worker assert(state->primitive_count == NULL);
96*61046927SAndroid Build Coastguard Worker
97*61046927SAndroid Build Coastguard Worker b->cursor = nir_before_instr(&intrin->instr);
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker state->primitive_count = anv_nir_prim_count_store(b, intrin->src[1].ssa);
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker nir_instr_remove(&intrin->instr);
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker return true;
104*61046927SAndroid Build Coastguard Worker }
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker static bool
anv_nir_lower_set_vtx_and_prim_count(nir_shader * nir)107*61046927SAndroid Build Coastguard Worker anv_nir_lower_set_vtx_and_prim_count(nir_shader *nir)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker struct lower_set_vtx_and_prim_count_state state = { NULL, };
110*61046927SAndroid Build Coastguard Worker
111*61046927SAndroid Build Coastguard Worker nir_shader_intrinsics_pass(nir, anv_nir_lower_set_vtx_and_prim_count_instr,
112*61046927SAndroid Build Coastguard Worker nir_metadata_none,
113*61046927SAndroid Build Coastguard Worker &state);
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker /* If we didn't find set_vertex_and_primitive_count, then we have to
116*61046927SAndroid Build Coastguard Worker * insert store of value 0 to primitive_count.
117*61046927SAndroid Build Coastguard Worker */
118*61046927SAndroid Build Coastguard Worker if (state.primitive_count == NULL) {
119*61046927SAndroid Build Coastguard Worker nir_builder b;
120*61046927SAndroid Build Coastguard Worker nir_function_impl *entrypoint = nir_shader_get_entrypoint(nir);
121*61046927SAndroid Build Coastguard Worker b = nir_builder_at(nir_before_impl(entrypoint));
122*61046927SAndroid Build Coastguard Worker nir_def *zero = nir_imm_int(&b, 0);
123*61046927SAndroid Build Coastguard Worker state.primitive_count = anv_nir_prim_count_store(&b, zero);
124*61046927SAndroid Build Coastguard Worker }
125*61046927SAndroid Build Coastguard Worker
126*61046927SAndroid Build Coastguard Worker assert(state.primitive_count != NULL);
127*61046927SAndroid Build Coastguard Worker return true;
128*61046927SAndroid Build Coastguard Worker }
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker /* Eventually, this will become part of anv_CreateShader. Unfortunately,
131*61046927SAndroid Build Coastguard Worker * we can't do that yet because we don't have the ability to copy nir.
132*61046927SAndroid Build Coastguard Worker */
133*61046927SAndroid Build Coastguard Worker static nir_shader *
anv_shader_stage_to_nir(struct anv_device * device,VkPipelineCreateFlags2KHR pipeline_flags,const VkPipelineShaderStageCreateInfo * stage_info,enum brw_robustness_flags robust_flags,void * mem_ctx)134*61046927SAndroid Build Coastguard Worker anv_shader_stage_to_nir(struct anv_device *device,
135*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR pipeline_flags,
136*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *stage_info,
137*61046927SAndroid Build Coastguard Worker enum brw_robustness_flags robust_flags,
138*61046927SAndroid Build Coastguard Worker void *mem_ctx)
139*61046927SAndroid Build Coastguard Worker {
140*61046927SAndroid Build Coastguard Worker const struct anv_physical_device *pdevice = device->physical;
141*61046927SAndroid Build Coastguard Worker const struct brw_compiler *compiler = pdevice->compiler;
142*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = vk_to_mesa_shader_stage(stage_info->stage);
143*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *nir_options =
144*61046927SAndroid Build Coastguard Worker compiler->nir_options[stage];
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker const struct spirv_to_nir_options spirv_options = {
147*61046927SAndroid Build Coastguard Worker .ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_flags),
148*61046927SAndroid Build Coastguard Worker .ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_flags),
149*61046927SAndroid Build Coastguard Worker .phys_ssbo_addr_format = nir_address_format_64bit_global,
150*61046927SAndroid Build Coastguard Worker .push_const_addr_format = nir_address_format_logical,
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker /* TODO: Consider changing this to an address format that has the NULL
153*61046927SAndroid Build Coastguard Worker * pointer equals to 0. That might be a better format to play nice
154*61046927SAndroid Build Coastguard Worker * with certain code / code generators.
155*61046927SAndroid Build Coastguard Worker */
156*61046927SAndroid Build Coastguard Worker .shared_addr_format = nir_address_format_32bit_offset,
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker .min_ubo_alignment = ANV_UBO_ALIGNMENT,
159*61046927SAndroid Build Coastguard Worker .min_ssbo_alignment = ANV_SSBO_ALIGNMENT,
160*61046927SAndroid Build Coastguard Worker };
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker nir_shader *nir;
163*61046927SAndroid Build Coastguard Worker VkResult result =
164*61046927SAndroid Build Coastguard Worker vk_pipeline_shader_stage_to_nir(&device->vk, pipeline_flags, stage_info,
165*61046927SAndroid Build Coastguard Worker &spirv_options, nir_options,
166*61046927SAndroid Build Coastguard Worker mem_ctx, &nir);
167*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
168*61046927SAndroid Build Coastguard Worker return NULL;
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker if (INTEL_DEBUG(intel_debug_flag_for_shader_stage(stage))) {
171*61046927SAndroid Build Coastguard Worker fprintf(stderr, "NIR (from SPIR-V) for %s shader:\n",
172*61046927SAndroid Build Coastguard Worker gl_shader_stage_name(stage));
173*61046927SAndroid Build Coastguard Worker nir_print_shader(nir, stderr);
174*61046927SAndroid Build Coastguard Worker }
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_io_to_temporaries,
177*61046927SAndroid Build Coastguard Worker nir_shader_get_entrypoint(nir), true, false);
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker return nir;
180*61046927SAndroid Build Coastguard Worker }
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker static VkResult
anv_pipeline_init(struct anv_pipeline * pipeline,struct anv_device * device,enum anv_pipeline_type type,VkPipelineCreateFlags2KHR flags,const VkAllocationCallbacks * pAllocator)183*61046927SAndroid Build Coastguard Worker anv_pipeline_init(struct anv_pipeline *pipeline,
184*61046927SAndroid Build Coastguard Worker struct anv_device *device,
185*61046927SAndroid Build Coastguard Worker enum anv_pipeline_type type,
186*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR flags,
187*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator)
188*61046927SAndroid Build Coastguard Worker {
189*61046927SAndroid Build Coastguard Worker VkResult result;
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker memset(pipeline, 0, sizeof(*pipeline));
192*61046927SAndroid Build Coastguard Worker
193*61046927SAndroid Build Coastguard Worker vk_object_base_init(&device->vk, &pipeline->base,
194*61046927SAndroid Build Coastguard Worker VK_OBJECT_TYPE_PIPELINE);
195*61046927SAndroid Build Coastguard Worker pipeline->device = device;
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker /* It's the job of the child class to provide actual backing storage for
198*61046927SAndroid Build Coastguard Worker * the batch by setting batch.start, batch.next, and batch.end.
199*61046927SAndroid Build Coastguard Worker */
200*61046927SAndroid Build Coastguard Worker pipeline->batch.alloc = pAllocator ? pAllocator : &device->vk.alloc;
201*61046927SAndroid Build Coastguard Worker pipeline->batch.relocs = &pipeline->batch_relocs;
202*61046927SAndroid Build Coastguard Worker pipeline->batch.status = VK_SUCCESS;
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker const bool uses_relocs = device->physical->uses_relocs;
205*61046927SAndroid Build Coastguard Worker result = anv_reloc_list_init(&pipeline->batch_relocs,
206*61046927SAndroid Build Coastguard Worker pipeline->batch.alloc, uses_relocs);
207*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
208*61046927SAndroid Build Coastguard Worker return result;
209*61046927SAndroid Build Coastguard Worker
210*61046927SAndroid Build Coastguard Worker pipeline->mem_ctx = ralloc_context(NULL);
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker pipeline->type = type;
213*61046927SAndroid Build Coastguard Worker pipeline->flags = flags;
214*61046927SAndroid Build Coastguard Worker
215*61046927SAndroid Build Coastguard Worker util_dynarray_init(&pipeline->executables, pipeline->mem_ctx);
216*61046927SAndroid Build Coastguard Worker
217*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_init(&pipeline->layout, device,
218*61046927SAndroid Build Coastguard Worker false /* independent_sets */);
219*61046927SAndroid Build Coastguard Worker
220*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
221*61046927SAndroid Build Coastguard Worker }
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_init_layout(struct anv_pipeline * pipeline,struct anv_pipeline_layout * pipeline_layout)224*61046927SAndroid Build Coastguard Worker anv_pipeline_init_layout(struct anv_pipeline *pipeline,
225*61046927SAndroid Build Coastguard Worker struct anv_pipeline_layout *pipeline_layout)
226*61046927SAndroid Build Coastguard Worker {
227*61046927SAndroid Build Coastguard Worker if (pipeline_layout) {
228*61046927SAndroid Build Coastguard Worker struct anv_pipeline_sets_layout *layout = &pipeline_layout->sets_layout;
229*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < layout->num_sets; s++) {
230*61046927SAndroid Build Coastguard Worker if (layout->set[s].layout == NULL)
231*61046927SAndroid Build Coastguard Worker continue;
232*61046927SAndroid Build Coastguard Worker
233*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_add(&pipeline->layout, s,
234*61046927SAndroid Build Coastguard Worker layout->set[s].layout);
235*61046927SAndroid Build Coastguard Worker }
236*61046927SAndroid Build Coastguard Worker }
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_hash(&pipeline->layout);
239*61046927SAndroid Build Coastguard Worker assert(!pipeline_layout ||
240*61046927SAndroid Build Coastguard Worker !memcmp(pipeline->layout.sha1,
241*61046927SAndroid Build Coastguard Worker pipeline_layout->sets_layout.sha1,
242*61046927SAndroid Build Coastguard Worker sizeof(pipeline_layout->sets_layout.sha1)));
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker
245*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_finish(struct anv_pipeline * pipeline,struct anv_device * device)246*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(struct anv_pipeline *pipeline,
247*61046927SAndroid Build Coastguard Worker struct anv_device *device)
248*61046927SAndroid Build Coastguard Worker {
249*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_fini(&pipeline->layout);
250*61046927SAndroid Build Coastguard Worker anv_reloc_list_finish(&pipeline->batch_relocs);
251*61046927SAndroid Build Coastguard Worker ralloc_free(pipeline->mem_ctx);
252*61046927SAndroid Build Coastguard Worker vk_object_base_finish(&pipeline->base);
253*61046927SAndroid Build Coastguard Worker }
254*61046927SAndroid Build Coastguard Worker
anv_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)255*61046927SAndroid Build Coastguard Worker void anv_DestroyPipeline(
256*61046927SAndroid Build Coastguard Worker VkDevice _device,
257*61046927SAndroid Build Coastguard Worker VkPipeline _pipeline,
258*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator)
259*61046927SAndroid Build Coastguard Worker {
260*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_device, device, _device);
261*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker if (!pipeline)
264*61046927SAndroid Build Coastguard Worker return;
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker ANV_RMV(resource_destroy, device, pipeline);
267*61046927SAndroid Build Coastguard Worker
268*61046927SAndroid Build Coastguard Worker switch (pipeline->type) {
269*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_GRAPHICS:
270*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_GRAPHICS_LIB: {
271*61046927SAndroid Build Coastguard Worker struct anv_graphics_base_pipeline *gfx_pipeline =
272*61046927SAndroid Build Coastguard Worker anv_pipeline_to_graphics_base(pipeline);
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(gfx_pipeline->shaders); s++) {
275*61046927SAndroid Build Coastguard Worker if (gfx_pipeline->shaders[s])
276*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, gfx_pipeline->shaders[s]);
277*61046927SAndroid Build Coastguard Worker }
278*61046927SAndroid Build Coastguard Worker break;
279*61046927SAndroid Build Coastguard Worker }
280*61046927SAndroid Build Coastguard Worker
281*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_COMPUTE: {
282*61046927SAndroid Build Coastguard Worker struct anv_compute_pipeline *compute_pipeline =
283*61046927SAndroid Build Coastguard Worker anv_pipeline_to_compute(pipeline);
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker if (compute_pipeline->cs)
286*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, compute_pipeline->cs);
287*61046927SAndroid Build Coastguard Worker
288*61046927SAndroid Build Coastguard Worker break;
289*61046927SAndroid Build Coastguard Worker }
290*61046927SAndroid Build Coastguard Worker
291*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_RAY_TRACING: {
292*61046927SAndroid Build Coastguard Worker struct anv_ray_tracing_pipeline *rt_pipeline =
293*61046927SAndroid Build Coastguard Worker anv_pipeline_to_ray_tracing(pipeline);
294*61046927SAndroid Build Coastguard Worker
295*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&rt_pipeline->shaders,
296*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *, shader) {
297*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, *shader);
298*61046927SAndroid Build Coastguard Worker }
299*61046927SAndroid Build Coastguard Worker break;
300*61046927SAndroid Build Coastguard Worker }
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker default:
303*61046927SAndroid Build Coastguard Worker unreachable("invalid pipeline type");
304*61046927SAndroid Build Coastguard Worker }
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(pipeline, device);
307*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage {
311*61046927SAndroid Build Coastguard Worker gl_shader_stage stage;
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker VkPipelineCreateFlags2KHR pipeline_flags;
314*61046927SAndroid Build Coastguard Worker struct vk_pipeline_robustness_state rstate;
315*61046927SAndroid Build Coastguard Worker
316*61046927SAndroid Build Coastguard Worker /* VkComputePipelineCreateInfo, VkGraphicsPipelineCreateInfo or
317*61046927SAndroid Build Coastguard Worker * VkRayTracingPipelineCreateInfoKHR pNext field
318*61046927SAndroid Build Coastguard Worker */
319*61046927SAndroid Build Coastguard Worker const void *pipeline_pNext;
320*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *info;
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker unsigned char shader_sha1[20];
323*61046927SAndroid Build Coastguard Worker uint32_t source_hash;
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker union brw_any_prog_key key;
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker struct {
328*61046927SAndroid Build Coastguard Worker gl_shader_stage stage;
329*61046927SAndroid Build Coastguard Worker unsigned char sha1[20];
330*61046927SAndroid Build Coastguard Worker } cache_key;
331*61046927SAndroid Build Coastguard Worker
332*61046927SAndroid Build Coastguard Worker nir_shader *nir;
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker struct {
335*61046927SAndroid Build Coastguard Worker nir_shader *nir;
336*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *bin;
337*61046927SAndroid Build Coastguard Worker } imported;
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker struct anv_push_descriptor_info push_desc_info;
340*61046927SAndroid Build Coastguard Worker
341*61046927SAndroid Build Coastguard Worker enum gl_subgroup_size subgroup_size_type;
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker enum brw_robustness_flags robust_flags;
344*61046927SAndroid Build Coastguard Worker
345*61046927SAndroid Build Coastguard Worker struct anv_pipeline_bind_map bind_map;
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker bool uses_bt_for_push_descs;
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker enum anv_dynamic_push_bits dynamic_push_values;
350*61046927SAndroid Build Coastguard Worker
351*61046927SAndroid Build Coastguard Worker union brw_any_prog_data prog_data;
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker uint32_t num_stats;
354*61046927SAndroid Build Coastguard Worker struct brw_compile_stats stats[3];
355*61046927SAndroid Build Coastguard Worker char *disasm[3];
356*61046927SAndroid Build Coastguard Worker
357*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback feedback;
358*61046927SAndroid Build Coastguard Worker uint32_t feedback_idx;
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker const unsigned *code;
361*61046927SAndroid Build Coastguard Worker
362*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *bin;
363*61046927SAndroid Build Coastguard Worker };
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker static void
anv_stage_allocate_bind_map_tables(struct anv_pipeline * pipeline,struct anv_pipeline_stage * stage,void * mem_ctx)366*61046927SAndroid Build Coastguard Worker anv_stage_allocate_bind_map_tables(struct anv_pipeline *pipeline,
367*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage,
368*61046927SAndroid Build Coastguard Worker void *mem_ctx)
369*61046927SAndroid Build Coastguard Worker {
370*61046927SAndroid Build Coastguard Worker struct anv_pipeline_binding *surface_bindings =
371*61046927SAndroid Build Coastguard Worker brw_shader_stage_requires_bindless_resources(stage->stage) ? NULL :
372*61046927SAndroid Build Coastguard Worker rzalloc_array(mem_ctx, struct anv_pipeline_binding, 256);
373*61046927SAndroid Build Coastguard Worker struct anv_pipeline_binding *sampler_bindings =
374*61046927SAndroid Build Coastguard Worker brw_shader_stage_requires_bindless_resources(stage->stage) ? NULL :
375*61046927SAndroid Build Coastguard Worker rzalloc_array(mem_ctx, struct anv_pipeline_binding, 256);
376*61046927SAndroid Build Coastguard Worker struct anv_pipeline_embedded_sampler_binding *embedded_sampler_bindings =
377*61046927SAndroid Build Coastguard Worker rzalloc_array(mem_ctx, struct anv_pipeline_embedded_sampler_binding,
378*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_embedded_sampler_count(
379*61046927SAndroid Build Coastguard Worker &pipeline->layout));
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker stage->bind_map = (struct anv_pipeline_bind_map) {
382*61046927SAndroid Build Coastguard Worker .surface_to_descriptor = surface_bindings,
383*61046927SAndroid Build Coastguard Worker .sampler_to_descriptor = sampler_bindings,
384*61046927SAndroid Build Coastguard Worker .embedded_sampler_to_binding = embedded_sampler_bindings,
385*61046927SAndroid Build Coastguard Worker };
386*61046927SAndroid Build Coastguard Worker }
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker static enum brw_robustness_flags
anv_get_robust_flags(const struct vk_pipeline_robustness_state * rstate)389*61046927SAndroid Build Coastguard Worker anv_get_robust_flags(const struct vk_pipeline_robustness_state *rstate)
390*61046927SAndroid Build Coastguard Worker {
391*61046927SAndroid Build Coastguard Worker return
392*61046927SAndroid Build Coastguard Worker ((rstate->storage_buffers !=
393*61046927SAndroid Build Coastguard Worker VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT) ?
394*61046927SAndroid Build Coastguard Worker BRW_ROBUSTNESS_SSBO : 0) |
395*61046927SAndroid Build Coastguard Worker ((rstate->uniform_buffers !=
396*61046927SAndroid Build Coastguard Worker VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT) ?
397*61046927SAndroid Build Coastguard Worker BRW_ROBUSTNESS_UBO : 0);
398*61046927SAndroid Build Coastguard Worker }
399*61046927SAndroid Build Coastguard Worker
400*61046927SAndroid Build Coastguard Worker static void
populate_base_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device)401*61046927SAndroid Build Coastguard Worker populate_base_prog_key(struct anv_pipeline_stage *stage,
402*61046927SAndroid Build Coastguard Worker const struct anv_device *device)
403*61046927SAndroid Build Coastguard Worker {
404*61046927SAndroid Build Coastguard Worker stage->key.base.robust_flags = anv_get_robust_flags(&stage->rstate);
405*61046927SAndroid Build Coastguard Worker stage->key.base.limit_trig_input_range =
406*61046927SAndroid Build Coastguard Worker device->physical->instance->limit_trig_input_range;
407*61046927SAndroid Build Coastguard Worker }
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker static void
populate_vs_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device)410*61046927SAndroid Build Coastguard Worker populate_vs_prog_key(struct anv_pipeline_stage *stage,
411*61046927SAndroid Build Coastguard Worker const struct anv_device *device)
412*61046927SAndroid Build Coastguard Worker {
413*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
416*61046927SAndroid Build Coastguard Worker }
417*61046927SAndroid Build Coastguard Worker
418*61046927SAndroid Build Coastguard Worker static void
populate_tcs_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device,unsigned input_vertices)419*61046927SAndroid Build Coastguard Worker populate_tcs_prog_key(struct anv_pipeline_stage *stage,
420*61046927SAndroid Build Coastguard Worker const struct anv_device *device,
421*61046927SAndroid Build Coastguard Worker unsigned input_vertices)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
424*61046927SAndroid Build Coastguard Worker
425*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker stage->key.tcs.input_vertices = input_vertices;
428*61046927SAndroid Build Coastguard Worker }
429*61046927SAndroid Build Coastguard Worker
430*61046927SAndroid Build Coastguard Worker static void
populate_tes_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device)431*61046927SAndroid Build Coastguard Worker populate_tes_prog_key(struct anv_pipeline_stage *stage,
432*61046927SAndroid Build Coastguard Worker const struct anv_device *device)
433*61046927SAndroid Build Coastguard Worker {
434*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
435*61046927SAndroid Build Coastguard Worker
436*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
437*61046927SAndroid Build Coastguard Worker }
438*61046927SAndroid Build Coastguard Worker
439*61046927SAndroid Build Coastguard Worker static void
populate_gs_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device)440*61046927SAndroid Build Coastguard Worker populate_gs_prog_key(struct anv_pipeline_stage *stage,
441*61046927SAndroid Build Coastguard Worker const struct anv_device *device)
442*61046927SAndroid Build Coastguard Worker {
443*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
446*61046927SAndroid Build Coastguard Worker }
447*61046927SAndroid Build Coastguard Worker
448*61046927SAndroid Build Coastguard Worker static bool
pipeline_has_coarse_pixel(const BITSET_WORD * dynamic,const struct vk_multisample_state * ms,const struct vk_fragment_shading_rate_state * fsr)449*61046927SAndroid Build Coastguard Worker pipeline_has_coarse_pixel(const BITSET_WORD *dynamic,
450*61046927SAndroid Build Coastguard Worker const struct vk_multisample_state *ms,
451*61046927SAndroid Build Coastguard Worker const struct vk_fragment_shading_rate_state *fsr)
452*61046927SAndroid Build Coastguard Worker {
453*61046927SAndroid Build Coastguard Worker /* The Vulkan 1.2.199 spec says:
454*61046927SAndroid Build Coastguard Worker *
455*61046927SAndroid Build Coastguard Worker * "If any of the following conditions are met, Cxy' must be set to
456*61046927SAndroid Build Coastguard Worker * {1,1}:
457*61046927SAndroid Build Coastguard Worker *
458*61046927SAndroid Build Coastguard Worker * * If Sample Shading is enabled.
459*61046927SAndroid Build Coastguard Worker * * [...]"
460*61046927SAndroid Build Coastguard Worker *
461*61046927SAndroid Build Coastguard Worker * And "sample shading" is defined as follows:
462*61046927SAndroid Build Coastguard Worker *
463*61046927SAndroid Build Coastguard Worker * "Sample shading is enabled for a graphics pipeline:
464*61046927SAndroid Build Coastguard Worker *
465*61046927SAndroid Build Coastguard Worker * * If the interface of the fragment shader entry point of the
466*61046927SAndroid Build Coastguard Worker * graphics pipeline includes an input variable decorated with
467*61046927SAndroid Build Coastguard Worker * SampleId or SamplePosition. In this case minSampleShadingFactor
468*61046927SAndroid Build Coastguard Worker * takes the value 1.0.
469*61046927SAndroid Build Coastguard Worker *
470*61046927SAndroid Build Coastguard Worker * * Else if the sampleShadingEnable member of the
471*61046927SAndroid Build Coastguard Worker * VkPipelineMultisampleStateCreateInfo structure specified when
472*61046927SAndroid Build Coastguard Worker * creating the graphics pipeline is set to VK_TRUE. In this case
473*61046927SAndroid Build Coastguard Worker * minSampleShadingFactor takes the value of
474*61046927SAndroid Build Coastguard Worker * VkPipelineMultisampleStateCreateInfo::minSampleShading.
475*61046927SAndroid Build Coastguard Worker *
476*61046927SAndroid Build Coastguard Worker * Otherwise, sample shading is considered disabled."
477*61046927SAndroid Build Coastguard Worker *
478*61046927SAndroid Build Coastguard Worker * The first bullet above is handled by the back-end compiler because those
479*61046927SAndroid Build Coastguard Worker * inputs both force per-sample dispatch. The second bullet is handled
480*61046927SAndroid Build Coastguard Worker * here. Note that this sample shading being enabled has nothing to do
481*61046927SAndroid Build Coastguard Worker * with minSampleShading.
482*61046927SAndroid Build Coastguard Worker */
483*61046927SAndroid Build Coastguard Worker if (ms != NULL && ms->sample_shading_enable)
484*61046927SAndroid Build Coastguard Worker return false;
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker /* Not dynamic & pipeline has a 1x1 fragment shading rate with no
487*61046927SAndroid Build Coastguard Worker * possibility for element of the pipeline to change the value or fragment
488*61046927SAndroid Build Coastguard Worker * shading rate not specified at all.
489*61046927SAndroid Build Coastguard Worker */
490*61046927SAndroid Build Coastguard Worker if (!BITSET_TEST(dynamic, MESA_VK_DYNAMIC_FSR) &&
491*61046927SAndroid Build Coastguard Worker (fsr == NULL ||
492*61046927SAndroid Build Coastguard Worker (fsr->fragment_size.width <= 1 &&
493*61046927SAndroid Build Coastguard Worker fsr->fragment_size.height <= 1 &&
494*61046927SAndroid Build Coastguard Worker fsr->combiner_ops[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR &&
495*61046927SAndroid Build Coastguard Worker fsr->combiner_ops[1] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR)))
496*61046927SAndroid Build Coastguard Worker return false;
497*61046927SAndroid Build Coastguard Worker
498*61046927SAndroid Build Coastguard Worker return true;
499*61046927SAndroid Build Coastguard Worker }
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker static void
populate_task_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device)502*61046927SAndroid Build Coastguard Worker populate_task_prog_key(struct anv_pipeline_stage *stage,
503*61046927SAndroid Build Coastguard Worker const struct anv_device *device)
504*61046927SAndroid Build Coastguard Worker {
505*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
506*61046927SAndroid Build Coastguard Worker
507*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
508*61046927SAndroid Build Coastguard Worker }
509*61046927SAndroid Build Coastguard Worker
510*61046927SAndroid Build Coastguard Worker static void
populate_mesh_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device,bool compact_mue)511*61046927SAndroid Build Coastguard Worker populate_mesh_prog_key(struct anv_pipeline_stage *stage,
512*61046927SAndroid Build Coastguard Worker const struct anv_device *device,
513*61046927SAndroid Build Coastguard Worker bool compact_mue)
514*61046927SAndroid Build Coastguard Worker {
515*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker stage->key.mesh.compact_mue = compact_mue;
520*61046927SAndroid Build Coastguard Worker }
521*61046927SAndroid Build Coastguard Worker
522*61046927SAndroid Build Coastguard Worker static uint32_t
rp_color_mask(const struct vk_render_pass_state * rp)523*61046927SAndroid Build Coastguard Worker rp_color_mask(const struct vk_render_pass_state *rp)
524*61046927SAndroid Build Coastguard Worker {
525*61046927SAndroid Build Coastguard Worker if (rp == NULL || !vk_render_pass_state_has_attachment_info(rp))
526*61046927SAndroid Build Coastguard Worker return ((1u << MAX_RTS) - 1);
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker uint32_t color_mask = 0;
529*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < rp->color_attachment_count; i++) {
530*61046927SAndroid Build Coastguard Worker if (rp->color_attachment_formats[i] != VK_FORMAT_UNDEFINED)
531*61046927SAndroid Build Coastguard Worker color_mask |= BITFIELD_BIT(i);
532*61046927SAndroid Build Coastguard Worker }
533*61046927SAndroid Build Coastguard Worker
534*61046927SAndroid Build Coastguard Worker return color_mask;
535*61046927SAndroid Build Coastguard Worker }
536*61046927SAndroid Build Coastguard Worker
537*61046927SAndroid Build Coastguard Worker static void
populate_wm_prog_key(struct anv_pipeline_stage * stage,const struct anv_graphics_base_pipeline * pipeline,const BITSET_WORD * dynamic,const struct vk_multisample_state * ms,const struct vk_fragment_shading_rate_state * fsr,const struct vk_render_pass_state * rp,const enum brw_sometimes is_mesh)538*61046927SAndroid Build Coastguard Worker populate_wm_prog_key(struct anv_pipeline_stage *stage,
539*61046927SAndroid Build Coastguard Worker const struct anv_graphics_base_pipeline *pipeline,
540*61046927SAndroid Build Coastguard Worker const BITSET_WORD *dynamic,
541*61046927SAndroid Build Coastguard Worker const struct vk_multisample_state *ms,
542*61046927SAndroid Build Coastguard Worker const struct vk_fragment_shading_rate_state *fsr,
543*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp,
544*61046927SAndroid Build Coastguard Worker const enum brw_sometimes is_mesh)
545*61046927SAndroid Build Coastguard Worker {
546*61046927SAndroid Build Coastguard Worker const struct anv_device *device = pipeline->base.device;
547*61046927SAndroid Build Coastguard Worker
548*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
551*61046927SAndroid Build Coastguard Worker
552*61046927SAndroid Build Coastguard Worker struct brw_wm_prog_key *key = &stage->key.wm;
553*61046927SAndroid Build Coastguard Worker
554*61046927SAndroid Build Coastguard Worker /* We set this to 0 here and set to the actual value before we call
555*61046927SAndroid Build Coastguard Worker * brw_compile_fs.
556*61046927SAndroid Build Coastguard Worker */
557*61046927SAndroid Build Coastguard Worker key->input_slots_valid = 0;
558*61046927SAndroid Build Coastguard Worker
559*61046927SAndroid Build Coastguard Worker /* XXX Vulkan doesn't appear to specify */
560*61046927SAndroid Build Coastguard Worker key->clamp_fragment_color = false;
561*61046927SAndroid Build Coastguard Worker
562*61046927SAndroid Build Coastguard Worker key->ignore_sample_mask_out = false;
563*61046927SAndroid Build Coastguard Worker
564*61046927SAndroid Build Coastguard Worker assert(rp == NULL || rp->color_attachment_count <= MAX_RTS);
565*61046927SAndroid Build Coastguard Worker /* Consider all inputs as valid until look at the NIR variables. */
566*61046927SAndroid Build Coastguard Worker key->color_outputs_valid = rp_color_mask(rp);
567*61046927SAndroid Build Coastguard Worker key->nr_color_regions = util_last_bit(key->color_outputs_valid);
568*61046927SAndroid Build Coastguard Worker
569*61046927SAndroid Build Coastguard Worker /* To reduce possible shader recompilations we would need to know if
570*61046927SAndroid Build Coastguard Worker * there is a SampleMask output variable to compute if we should emit
571*61046927SAndroid Build Coastguard Worker * code to workaround the issue that hardware disables alpha to coverage
572*61046927SAndroid Build Coastguard Worker * when there is SampleMask output.
573*61046927SAndroid Build Coastguard Worker *
574*61046927SAndroid Build Coastguard Worker * If the pipeline we compile the fragment shader in includes the output
575*61046927SAndroid Build Coastguard Worker * interface, then we can be sure whether alpha_coverage is enabled or not.
576*61046927SAndroid Build Coastguard Worker * If we don't have that output interface, then we have to compile the
577*61046927SAndroid Build Coastguard Worker * shader with some conditionals.
578*61046927SAndroid Build Coastguard Worker */
579*61046927SAndroid Build Coastguard Worker if (ms != NULL) {
580*61046927SAndroid Build Coastguard Worker /* VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751:
581*61046927SAndroid Build Coastguard Worker *
582*61046927SAndroid Build Coastguard Worker * "If the pipeline is being created with fragment shader state,
583*61046927SAndroid Build Coastguard Worker * pMultisampleState must be a valid pointer to a valid
584*61046927SAndroid Build Coastguard Worker * VkPipelineMultisampleStateCreateInfo structure"
585*61046927SAndroid Build Coastguard Worker *
586*61046927SAndroid Build Coastguard Worker * It's also required for the fragment output interface.
587*61046927SAndroid Build Coastguard Worker */
588*61046927SAndroid Build Coastguard Worker key->multisample_fbo =
589*61046927SAndroid Build Coastguard Worker BITSET_TEST(dynamic, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES) ?
590*61046927SAndroid Build Coastguard Worker BRW_SOMETIMES :
591*61046927SAndroid Build Coastguard Worker ms->rasterization_samples > 1 ? BRW_ALWAYS : BRW_NEVER;
592*61046927SAndroid Build Coastguard Worker key->persample_interp =
593*61046927SAndroid Build Coastguard Worker BITSET_TEST(dynamic, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES) ?
594*61046927SAndroid Build Coastguard Worker BRW_SOMETIMES :
595*61046927SAndroid Build Coastguard Worker (ms->sample_shading_enable &&
596*61046927SAndroid Build Coastguard Worker (ms->min_sample_shading * ms->rasterization_samples) > 1) ?
597*61046927SAndroid Build Coastguard Worker BRW_ALWAYS : BRW_NEVER;
598*61046927SAndroid Build Coastguard Worker key->alpha_to_coverage =
599*61046927SAndroid Build Coastguard Worker BITSET_TEST(dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE) ?
600*61046927SAndroid Build Coastguard Worker BRW_SOMETIMES :
601*61046927SAndroid Build Coastguard Worker (ms->alpha_to_coverage_enable ? BRW_ALWAYS : BRW_NEVER);
602*61046927SAndroid Build Coastguard Worker
603*61046927SAndroid Build Coastguard Worker /* TODO: We should make this dynamic */
604*61046927SAndroid Build Coastguard Worker if (device->physical->instance->sample_mask_out_opengl_behaviour)
605*61046927SAndroid Build Coastguard Worker key->ignore_sample_mask_out = !key->multisample_fbo;
606*61046927SAndroid Build Coastguard Worker } else {
607*61046927SAndroid Build Coastguard Worker /* Consider all inputs as valid until we look at the NIR variables. */
608*61046927SAndroid Build Coastguard Worker key->color_outputs_valid = (1u << MAX_RTS) - 1;
609*61046927SAndroid Build Coastguard Worker key->nr_color_regions = MAX_RTS;
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker key->alpha_to_coverage = BRW_SOMETIMES;
612*61046927SAndroid Build Coastguard Worker key->multisample_fbo = BRW_SOMETIMES;
613*61046927SAndroid Build Coastguard Worker key->persample_interp = BRW_SOMETIMES;
614*61046927SAndroid Build Coastguard Worker }
615*61046927SAndroid Build Coastguard Worker
616*61046927SAndroid Build Coastguard Worker key->mesh_input = is_mesh;
617*61046927SAndroid Build Coastguard Worker
618*61046927SAndroid Build Coastguard Worker /* Vulkan doesn't support fixed-function alpha test */
619*61046927SAndroid Build Coastguard Worker key->alpha_test_replicate_alpha = false;
620*61046927SAndroid Build Coastguard Worker
621*61046927SAndroid Build Coastguard Worker key->coarse_pixel =
622*61046927SAndroid Build Coastguard Worker device->vk.enabled_extensions.KHR_fragment_shading_rate &&
623*61046927SAndroid Build Coastguard Worker pipeline_has_coarse_pixel(dynamic, ms, fsr);
624*61046927SAndroid Build Coastguard Worker
625*61046927SAndroid Build Coastguard Worker key->null_push_constant_tbimr_workaround =
626*61046927SAndroid Build Coastguard Worker device->info->needs_null_push_constant_tbimr_workaround;
627*61046927SAndroid Build Coastguard Worker }
628*61046927SAndroid Build Coastguard Worker
629*61046927SAndroid Build Coastguard Worker static void
populate_cs_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device)630*61046927SAndroid Build Coastguard Worker populate_cs_prog_key(struct anv_pipeline_stage *stage,
631*61046927SAndroid Build Coastguard Worker const struct anv_device *device)
632*61046927SAndroid Build Coastguard Worker {
633*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
636*61046927SAndroid Build Coastguard Worker }
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker static void
populate_bs_prog_key(struct anv_pipeline_stage * stage,const struct anv_device * device,uint32_t ray_flags)639*61046927SAndroid Build Coastguard Worker populate_bs_prog_key(struct anv_pipeline_stage *stage,
640*61046927SAndroid Build Coastguard Worker const struct anv_device *device,
641*61046927SAndroid Build Coastguard Worker uint32_t ray_flags)
642*61046927SAndroid Build Coastguard Worker {
643*61046927SAndroid Build Coastguard Worker memset(&stage->key, 0, sizeof(stage->key));
644*61046927SAndroid Build Coastguard Worker
645*61046927SAndroid Build Coastguard Worker populate_base_prog_key(stage, device);
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker stage->key.bs.pipeline_ray_flags = ray_flags;
648*61046927SAndroid Build Coastguard Worker stage->key.bs.pipeline_ray_flags = ray_flags;
649*61046927SAndroid Build Coastguard Worker }
650*61046927SAndroid Build Coastguard Worker
651*61046927SAndroid Build Coastguard Worker static void
anv_stage_write_shader_hash(struct anv_pipeline_stage * stage,const struct anv_device * device)652*61046927SAndroid Build Coastguard Worker anv_stage_write_shader_hash(struct anv_pipeline_stage *stage,
653*61046927SAndroid Build Coastguard Worker const struct anv_device *device)
654*61046927SAndroid Build Coastguard Worker {
655*61046927SAndroid Build Coastguard Worker vk_pipeline_robustness_state_fill(&device->vk,
656*61046927SAndroid Build Coastguard Worker &stage->rstate,
657*61046927SAndroid Build Coastguard Worker stage->pipeline_pNext,
658*61046927SAndroid Build Coastguard Worker stage->info->pNext);
659*61046927SAndroid Build Coastguard Worker
660*61046927SAndroid Build Coastguard Worker vk_pipeline_hash_shader_stage(stage->pipeline_flags, stage->info,
661*61046927SAndroid Build Coastguard Worker &stage->rstate, stage->shader_sha1);
662*61046927SAndroid Build Coastguard Worker
663*61046927SAndroid Build Coastguard Worker stage->robust_flags = anv_get_robust_flags(&stage->rstate);
664*61046927SAndroid Build Coastguard Worker
665*61046927SAndroid Build Coastguard Worker /* Use lowest dword of source shader sha1 for shader hash. */
666*61046927SAndroid Build Coastguard Worker stage->source_hash = ((uint32_t*)stage->shader_sha1)[0];
667*61046927SAndroid Build Coastguard Worker }
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker static bool
anv_graphics_pipeline_stage_fragment_dynamic(const struct anv_pipeline_stage * stage)670*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_stage_fragment_dynamic(const struct anv_pipeline_stage *stage)
671*61046927SAndroid Build Coastguard Worker {
672*61046927SAndroid Build Coastguard Worker if (stage->stage != MESA_SHADER_FRAGMENT)
673*61046927SAndroid Build Coastguard Worker return false;
674*61046927SAndroid Build Coastguard Worker
675*61046927SAndroid Build Coastguard Worker return stage->key.wm.persample_interp == BRW_SOMETIMES ||
676*61046927SAndroid Build Coastguard Worker stage->key.wm.multisample_fbo == BRW_SOMETIMES ||
677*61046927SAndroid Build Coastguard Worker stage->key.wm.alpha_to_coverage == BRW_SOMETIMES;
678*61046927SAndroid Build Coastguard Worker }
679*61046927SAndroid Build Coastguard Worker
680*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_hash_common(struct mesa_sha1 * ctx,const struct anv_pipeline * pipeline)681*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_common(struct mesa_sha1 *ctx,
682*61046927SAndroid Build Coastguard Worker const struct anv_pipeline *pipeline)
683*61046927SAndroid Build Coastguard Worker {
684*61046927SAndroid Build Coastguard Worker struct anv_device *device = pipeline->device;
685*61046927SAndroid Build Coastguard Worker
686*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, pipeline->layout.sha1, sizeof(pipeline->layout.sha1));
687*61046927SAndroid Build Coastguard Worker
688*61046927SAndroid Build Coastguard Worker const bool indirect_descriptors = device->physical->indirect_descriptors;
689*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, &indirect_descriptors, sizeof(indirect_descriptors));
690*61046927SAndroid Build Coastguard Worker
691*61046927SAndroid Build Coastguard Worker const bool rba = device->robust_buffer_access;
692*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, &rba, sizeof(rba));
693*61046927SAndroid Build Coastguard Worker
694*61046927SAndroid Build Coastguard Worker const int spilling_rate = device->physical->compiler->spilling_rate;
695*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(ctx, &spilling_rate, sizeof(spilling_rate));
696*61046927SAndroid Build Coastguard Worker }
697*61046927SAndroid Build Coastguard Worker
698*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_hash_graphics(struct anv_graphics_base_pipeline * pipeline,struct anv_pipeline_stage * stages,uint32_t view_mask,unsigned char * sha1_out)699*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_graphics(struct anv_graphics_base_pipeline *pipeline,
700*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
701*61046927SAndroid Build Coastguard Worker uint32_t view_mask,
702*61046927SAndroid Build Coastguard Worker unsigned char *sha1_out)
703*61046927SAndroid Build Coastguard Worker {
704*61046927SAndroid Build Coastguard Worker const struct anv_device *device = pipeline->base.device;
705*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
706*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
707*61046927SAndroid Build Coastguard Worker
708*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_common(&ctx, &pipeline->base);
709*61046927SAndroid Build Coastguard Worker
710*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &view_mask, sizeof(view_mask));
711*61046927SAndroid Build Coastguard Worker
712*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
713*61046927SAndroid Build Coastguard Worker if (pipeline->base.active_stages & BITFIELD_BIT(s)) {
714*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, stages[s].shader_sha1,
715*61046927SAndroid Build Coastguard Worker sizeof(stages[s].shader_sha1));
716*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &stages[s].key, brw_prog_key_size(s));
717*61046927SAndroid Build Coastguard Worker }
718*61046927SAndroid Build Coastguard Worker }
719*61046927SAndroid Build Coastguard Worker
720*61046927SAndroid Build Coastguard Worker if (stages[MESA_SHADER_MESH].info || stages[MESA_SHADER_TASK].info) {
721*61046927SAndroid Build Coastguard Worker const uint8_t afs = device->physical->instance->assume_full_subgroups;
722*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &afs, sizeof(afs));
723*61046927SAndroid Build Coastguard Worker }
724*61046927SAndroid Build Coastguard Worker
725*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, sha1_out);
726*61046927SAndroid Build Coastguard Worker }
727*61046927SAndroid Build Coastguard Worker
728*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_hash_compute(struct anv_compute_pipeline * pipeline,struct anv_pipeline_stage * stage,unsigned char * sha1_out)729*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_compute(struct anv_compute_pipeline *pipeline,
730*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage,
731*61046927SAndroid Build Coastguard Worker unsigned char *sha1_out)
732*61046927SAndroid Build Coastguard Worker {
733*61046927SAndroid Build Coastguard Worker const struct anv_device *device = pipeline->base.device;
734*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
735*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
736*61046927SAndroid Build Coastguard Worker
737*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_common(&ctx, &pipeline->base);
738*61046927SAndroid Build Coastguard Worker
739*61046927SAndroid Build Coastguard Worker const uint8_t afs = device->physical->instance->assume_full_subgroups;
740*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &afs, sizeof(afs));
741*61046927SAndroid Build Coastguard Worker
742*61046927SAndroid Build Coastguard Worker const bool afswb = device->physical->instance->assume_full_subgroups_with_barrier;
743*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &afswb, sizeof(afswb));
744*61046927SAndroid Build Coastguard Worker
745*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, stage->shader_sha1,
746*61046927SAndroid Build Coastguard Worker sizeof(stage->shader_sha1));
747*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &stage->key.cs, sizeof(stage->key.cs));
748*61046927SAndroid Build Coastguard Worker
749*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, sha1_out);
750*61046927SAndroid Build Coastguard Worker }
751*61046927SAndroid Build Coastguard Worker
752*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_hash_ray_tracing_shader(struct anv_ray_tracing_pipeline * pipeline,struct anv_pipeline_stage * stage,unsigned char * sha1_out)753*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_ray_tracing_shader(struct anv_ray_tracing_pipeline *pipeline,
754*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage,
755*61046927SAndroid Build Coastguard Worker unsigned char *sha1_out)
756*61046927SAndroid Build Coastguard Worker {
757*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
758*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_common(&ctx, &pipeline->base);
761*61046927SAndroid Build Coastguard Worker
762*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, stage->shader_sha1, sizeof(stage->shader_sha1));
763*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &stage->key, sizeof(stage->key.bs));
764*61046927SAndroid Build Coastguard Worker
765*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, sha1_out);
766*61046927SAndroid Build Coastguard Worker }
767*61046927SAndroid Build Coastguard Worker
768*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_hash_ray_tracing_combined_shader(struct anv_ray_tracing_pipeline * pipeline,struct anv_pipeline_stage * intersection,struct anv_pipeline_stage * any_hit,unsigned char * sha1_out)769*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_ray_tracing_combined_shader(struct anv_ray_tracing_pipeline *pipeline,
770*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *intersection,
771*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *any_hit,
772*61046927SAndroid Build Coastguard Worker unsigned char *sha1_out)
773*61046927SAndroid Build Coastguard Worker {
774*61046927SAndroid Build Coastguard Worker struct mesa_sha1 ctx;
775*61046927SAndroid Build Coastguard Worker _mesa_sha1_init(&ctx);
776*61046927SAndroid Build Coastguard Worker
777*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, pipeline->base.layout.sha1,
778*61046927SAndroid Build Coastguard Worker sizeof(pipeline->base.layout.sha1));
779*61046927SAndroid Build Coastguard Worker
780*61046927SAndroid Build Coastguard Worker const bool rba = pipeline->base.device->robust_buffer_access;
781*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &rba, sizeof(rba));
782*61046927SAndroid Build Coastguard Worker
783*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, intersection->shader_sha1, sizeof(intersection->shader_sha1));
784*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &intersection->key, sizeof(intersection->key.bs));
785*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, any_hit->shader_sha1, sizeof(any_hit->shader_sha1));
786*61046927SAndroid Build Coastguard Worker _mesa_sha1_update(&ctx, &any_hit->key, sizeof(any_hit->key.bs));
787*61046927SAndroid Build Coastguard Worker
788*61046927SAndroid Build Coastguard Worker _mesa_sha1_final(&ctx, sha1_out);
789*61046927SAndroid Build Coastguard Worker }
790*61046927SAndroid Build Coastguard Worker
791*61046927SAndroid Build Coastguard Worker static VkResult
anv_pipeline_stage_get_nir(struct anv_pipeline * pipeline,struct vk_pipeline_cache * cache,void * mem_ctx,struct anv_pipeline_stage * stage)792*61046927SAndroid Build Coastguard Worker anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
793*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
794*61046927SAndroid Build Coastguard Worker void *mem_ctx,
795*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage)
796*61046927SAndroid Build Coastguard Worker {
797*61046927SAndroid Build Coastguard Worker const struct brw_compiler *compiler =
798*61046927SAndroid Build Coastguard Worker pipeline->device->physical->compiler;
799*61046927SAndroid Build Coastguard Worker const nir_shader_compiler_options *nir_options =
800*61046927SAndroid Build Coastguard Worker compiler->nir_options[stage->stage];
801*61046927SAndroid Build Coastguard Worker
802*61046927SAndroid Build Coastguard Worker stage->nir = anv_device_search_for_nir(pipeline->device, cache,
803*61046927SAndroid Build Coastguard Worker nir_options,
804*61046927SAndroid Build Coastguard Worker stage->shader_sha1,
805*61046927SAndroid Build Coastguard Worker mem_ctx);
806*61046927SAndroid Build Coastguard Worker if (stage->nir) {
807*61046927SAndroid Build Coastguard Worker assert(stage->nir->info.stage == stage->stage);
808*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
809*61046927SAndroid Build Coastguard Worker }
810*61046927SAndroid Build Coastguard Worker
811*61046927SAndroid Build Coastguard Worker /* VkPipelineShaderStageCreateInfo:
812*61046927SAndroid Build Coastguard Worker *
813*61046927SAndroid Build Coastguard Worker * "If a pipeline is not found, pipeline compilation is not possible and
814*61046927SAndroid Build Coastguard Worker * the implementation must fail as specified by
815*61046927SAndroid Build Coastguard Worker * VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT."
816*61046927SAndroid Build Coastguard Worker */
817*61046927SAndroid Build Coastguard Worker if (vk_pipeline_shader_stage_has_identifier(stage->info))
818*61046927SAndroid Build Coastguard Worker return VK_PIPELINE_COMPILE_REQUIRED;
819*61046927SAndroid Build Coastguard Worker
820*61046927SAndroid Build Coastguard Worker stage->nir = anv_shader_stage_to_nir(pipeline->device,
821*61046927SAndroid Build Coastguard Worker stage->pipeline_flags, stage->info,
822*61046927SAndroid Build Coastguard Worker stage->key.base.robust_flags, mem_ctx);
823*61046927SAndroid Build Coastguard Worker if (stage->nir) {
824*61046927SAndroid Build Coastguard Worker anv_device_upload_nir(pipeline->device, cache,
825*61046927SAndroid Build Coastguard Worker stage->nir, stage->shader_sha1);
826*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
827*61046927SAndroid Build Coastguard Worker }
828*61046927SAndroid Build Coastguard Worker
829*61046927SAndroid Build Coastguard Worker return vk_errorf(&pipeline->device->vk, VK_ERROR_UNKNOWN,
830*61046927SAndroid Build Coastguard Worker "Unable to load NIR");
831*61046927SAndroid Build Coastguard Worker }
832*61046927SAndroid Build Coastguard Worker
833*61046927SAndroid Build Coastguard Worker static const struct vk_ycbcr_conversion_state *
lookup_ycbcr_conversion(const void * _sets_layout,uint32_t set,uint32_t binding,uint32_t array_index)834*61046927SAndroid Build Coastguard Worker lookup_ycbcr_conversion(const void *_sets_layout, uint32_t set,
835*61046927SAndroid Build Coastguard Worker uint32_t binding, uint32_t array_index)
836*61046927SAndroid Build Coastguard Worker {
837*61046927SAndroid Build Coastguard Worker const struct anv_pipeline_sets_layout *sets_layout = _sets_layout;
838*61046927SAndroid Build Coastguard Worker
839*61046927SAndroid Build Coastguard Worker assert(set < MAX_SETS);
840*61046927SAndroid Build Coastguard Worker assert(binding < sets_layout->set[set].layout->binding_count);
841*61046927SAndroid Build Coastguard Worker const struct anv_descriptor_set_binding_layout *bind_layout =
842*61046927SAndroid Build Coastguard Worker &sets_layout->set[set].layout->binding[binding];
843*61046927SAndroid Build Coastguard Worker
844*61046927SAndroid Build Coastguard Worker if (bind_layout->immutable_samplers == NULL)
845*61046927SAndroid Build Coastguard Worker return NULL;
846*61046927SAndroid Build Coastguard Worker
847*61046927SAndroid Build Coastguard Worker array_index = MIN2(array_index, bind_layout->array_size - 1);
848*61046927SAndroid Build Coastguard Worker
849*61046927SAndroid Build Coastguard Worker const struct anv_sampler *sampler =
850*61046927SAndroid Build Coastguard Worker bind_layout->immutable_samplers[array_index];
851*61046927SAndroid Build Coastguard Worker
852*61046927SAndroid Build Coastguard Worker return sampler && sampler->vk.ycbcr_conversion ?
853*61046927SAndroid Build Coastguard Worker &sampler->vk.ycbcr_conversion->state : NULL;
854*61046927SAndroid Build Coastguard Worker }
855*61046927SAndroid Build Coastguard Worker
856*61046927SAndroid Build Coastguard Worker static void
shared_type_info(const struct glsl_type * type,unsigned * size,unsigned * align)857*61046927SAndroid Build Coastguard Worker shared_type_info(const struct glsl_type *type, unsigned *size, unsigned *align)
858*61046927SAndroid Build Coastguard Worker {
859*61046927SAndroid Build Coastguard Worker assert(glsl_type_is_vector_or_scalar(type));
860*61046927SAndroid Build Coastguard Worker
861*61046927SAndroid Build Coastguard Worker uint32_t comp_size = glsl_type_is_boolean(type)
862*61046927SAndroid Build Coastguard Worker ? 4 : glsl_get_bit_size(type) / 8;
863*61046927SAndroid Build Coastguard Worker unsigned length = glsl_get_vector_elements(type);
864*61046927SAndroid Build Coastguard Worker *size = comp_size * length,
865*61046927SAndroid Build Coastguard Worker *align = comp_size * (length == 3 ? 4 : length);
866*61046927SAndroid Build Coastguard Worker }
867*61046927SAndroid Build Coastguard Worker
868*61046927SAndroid Build Coastguard Worker static enum anv_dynamic_push_bits
anv_nir_compute_dynamic_push_bits(nir_shader * shader)869*61046927SAndroid Build Coastguard Worker anv_nir_compute_dynamic_push_bits(nir_shader *shader)
870*61046927SAndroid Build Coastguard Worker {
871*61046927SAndroid Build Coastguard Worker enum anv_dynamic_push_bits ret = 0;
872*61046927SAndroid Build Coastguard Worker
873*61046927SAndroid Build Coastguard Worker nir_foreach_function_impl(impl, shader) {
874*61046927SAndroid Build Coastguard Worker nir_foreach_block(block, impl) {
875*61046927SAndroid Build Coastguard Worker nir_foreach_instr(instr, block) {
876*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_intrinsic)
877*61046927SAndroid Build Coastguard Worker continue;
878*61046927SAndroid Build Coastguard Worker
879*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
880*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic != nir_intrinsic_load_push_constant)
881*61046927SAndroid Build Coastguard Worker continue;
882*61046927SAndroid Build Coastguard Worker
883*61046927SAndroid Build Coastguard Worker switch (nir_intrinsic_base(intrin)) {
884*61046927SAndroid Build Coastguard Worker case anv_drv_const_offset(gfx.tcs_input_vertices):
885*61046927SAndroid Build Coastguard Worker ret |= ANV_DYNAMIC_PUSH_INPUT_VERTICES;
886*61046927SAndroid Build Coastguard Worker break;
887*61046927SAndroid Build Coastguard Worker
888*61046927SAndroid Build Coastguard Worker default:
889*61046927SAndroid Build Coastguard Worker break;
890*61046927SAndroid Build Coastguard Worker }
891*61046927SAndroid Build Coastguard Worker }
892*61046927SAndroid Build Coastguard Worker }
893*61046927SAndroid Build Coastguard Worker }
894*61046927SAndroid Build Coastguard Worker
895*61046927SAndroid Build Coastguard Worker return ret;
896*61046927SAndroid Build Coastguard Worker }
897*61046927SAndroid Build Coastguard Worker
898*61046927SAndroid Build Coastguard Worker static void
anv_fixup_subgroup_size(struct anv_device * device,struct shader_info * info)899*61046927SAndroid Build Coastguard Worker anv_fixup_subgroup_size(struct anv_device *device, struct shader_info *info)
900*61046927SAndroid Build Coastguard Worker {
901*61046927SAndroid Build Coastguard Worker switch (info->stage) {
902*61046927SAndroid Build Coastguard Worker case MESA_SHADER_COMPUTE:
903*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TASK:
904*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MESH:
905*61046927SAndroid Build Coastguard Worker break;
906*61046927SAndroid Build Coastguard Worker default:
907*61046927SAndroid Build Coastguard Worker return;
908*61046927SAndroid Build Coastguard Worker }
909*61046927SAndroid Build Coastguard Worker
910*61046927SAndroid Build Coastguard Worker unsigned local_size = info->workgroup_size[0] *
911*61046927SAndroid Build Coastguard Worker info->workgroup_size[1] *
912*61046927SAndroid Build Coastguard Worker info->workgroup_size[2];
913*61046927SAndroid Build Coastguard Worker
914*61046927SAndroid Build Coastguard Worker /* Games don't always request full subgroups when they should,
915*61046927SAndroid Build Coastguard Worker * which can cause bugs, as they may expect bigger size of the
916*61046927SAndroid Build Coastguard Worker * subgroup than we choose for the execution.
917*61046927SAndroid Build Coastguard Worker */
918*61046927SAndroid Build Coastguard Worker if (device->physical->instance->assume_full_subgroups &&
919*61046927SAndroid Build Coastguard Worker info->uses_wide_subgroup_intrinsics &&
920*61046927SAndroid Build Coastguard Worker info->subgroup_size == SUBGROUP_SIZE_API_CONSTANT &&
921*61046927SAndroid Build Coastguard Worker local_size &&
922*61046927SAndroid Build Coastguard Worker local_size % BRW_SUBGROUP_SIZE == 0)
923*61046927SAndroid Build Coastguard Worker info->subgroup_size = SUBGROUP_SIZE_FULL_SUBGROUPS;
924*61046927SAndroid Build Coastguard Worker
925*61046927SAndroid Build Coastguard Worker if (device->physical->instance->assume_full_subgroups_with_barrier &&
926*61046927SAndroid Build Coastguard Worker info->stage == MESA_SHADER_COMPUTE &&
927*61046927SAndroid Build Coastguard Worker device->info->verx10 <= 125 &&
928*61046927SAndroid Build Coastguard Worker info->uses_control_barrier &&
929*61046927SAndroid Build Coastguard Worker info->subgroup_size == SUBGROUP_SIZE_VARYING &&
930*61046927SAndroid Build Coastguard Worker local_size &&
931*61046927SAndroid Build Coastguard Worker local_size % BRW_SUBGROUP_SIZE == 0)
932*61046927SAndroid Build Coastguard Worker info->subgroup_size = SUBGROUP_SIZE_FULL_SUBGROUPS;
933*61046927SAndroid Build Coastguard Worker
934*61046927SAndroid Build Coastguard Worker /* If the client requests that we dispatch full subgroups but doesn't
935*61046927SAndroid Build Coastguard Worker * allow us to pick a subgroup size, we have to smash it to the API
936*61046927SAndroid Build Coastguard Worker * value of 32. Performance will likely be terrible in this case but
937*61046927SAndroid Build Coastguard Worker * there's nothing we can do about that. The client should have chosen
938*61046927SAndroid Build Coastguard Worker * a size.
939*61046927SAndroid Build Coastguard Worker */
940*61046927SAndroid Build Coastguard Worker if (info->subgroup_size == SUBGROUP_SIZE_FULL_SUBGROUPS)
941*61046927SAndroid Build Coastguard Worker info->subgroup_size =
942*61046927SAndroid Build Coastguard Worker device->physical->instance->assume_full_subgroups != 0 ?
943*61046927SAndroid Build Coastguard Worker device->physical->instance->assume_full_subgroups : BRW_SUBGROUP_SIZE;
944*61046927SAndroid Build Coastguard Worker
945*61046927SAndroid Build Coastguard Worker /* Cooperative matrix extension requires that all invocations in a subgroup
946*61046927SAndroid Build Coastguard Worker * be active. As a result, when the application does not request a specific
947*61046927SAndroid Build Coastguard Worker * subgroup size, we must use SIMD32.
948*61046927SAndroid Build Coastguard Worker */
949*61046927SAndroid Build Coastguard Worker if (info->stage == MESA_SHADER_COMPUTE && info->cs.has_cooperative_matrix &&
950*61046927SAndroid Build Coastguard Worker info->subgroup_size < SUBGROUP_SIZE_REQUIRE_8) {
951*61046927SAndroid Build Coastguard Worker info->subgroup_size = BRW_SUBGROUP_SIZE;
952*61046927SAndroid Build Coastguard Worker }
953*61046927SAndroid Build Coastguard Worker }
954*61046927SAndroid Build Coastguard Worker
955*61046927SAndroid Build Coastguard Worker /* #define DEBUG_PRINTF_EXAMPLE 0 */
956*61046927SAndroid Build Coastguard Worker
957*61046927SAndroid Build Coastguard Worker #if DEBUG_PRINTF_EXAMPLE
958*61046927SAndroid Build Coastguard Worker static bool
print_ubo_load(nir_builder * b,nir_intrinsic_instr * intrin,UNUSED void * cb_data)959*61046927SAndroid Build Coastguard Worker print_ubo_load(nir_builder *b,
960*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *intrin,
961*61046927SAndroid Build Coastguard Worker UNUSED void *cb_data)
962*61046927SAndroid Build Coastguard Worker {
963*61046927SAndroid Build Coastguard Worker if (intrin->intrinsic != nir_intrinsic_load_ubo)
964*61046927SAndroid Build Coastguard Worker return false;
965*61046927SAndroid Build Coastguard Worker
966*61046927SAndroid Build Coastguard Worker b->cursor = nir_before_instr(&intrin->instr);
967*61046927SAndroid Build Coastguard Worker nir_printf_fmt(b, true, 64, "ubo=> pos=%02.2fx%02.2f offset=0x%08x\n",
968*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 0),
969*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 1),
970*61046927SAndroid Build Coastguard Worker intrin->src[1].ssa);
971*61046927SAndroid Build Coastguard Worker
972*61046927SAndroid Build Coastguard Worker b->cursor = nir_after_instr(&intrin->instr);
973*61046927SAndroid Build Coastguard Worker nir_printf_fmt(b, true, 64, "ubo<= pos=%02.2fx%02.2f offset=0x%08x val=0x%08x\n",
974*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 0),
975*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 1),
976*61046927SAndroid Build Coastguard Worker intrin->src[1].ssa,
977*61046927SAndroid Build Coastguard Worker &intrin->def);
978*61046927SAndroid Build Coastguard Worker return true;
979*61046927SAndroid Build Coastguard Worker }
980*61046927SAndroid Build Coastguard Worker #endif
981*61046927SAndroid Build Coastguard Worker
982*61046927SAndroid Build Coastguard Worker static bool
print_tex_handle(nir_builder * b,nir_instr * instr,UNUSED void * cb_data)983*61046927SAndroid Build Coastguard Worker print_tex_handle(nir_builder *b,
984*61046927SAndroid Build Coastguard Worker nir_instr *instr,
985*61046927SAndroid Build Coastguard Worker UNUSED void *cb_data)
986*61046927SAndroid Build Coastguard Worker {
987*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_tex)
988*61046927SAndroid Build Coastguard Worker return false;
989*61046927SAndroid Build Coastguard Worker
990*61046927SAndroid Build Coastguard Worker nir_tex_instr *tex = nir_instr_as_tex(instr);
991*61046927SAndroid Build Coastguard Worker
992*61046927SAndroid Build Coastguard Worker nir_src tex_src = {};
993*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < tex->num_srcs; i++) {
994*61046927SAndroid Build Coastguard Worker if (tex->src[i].src_type == nir_tex_src_texture_handle)
995*61046927SAndroid Build Coastguard Worker tex_src = tex->src[i].src;
996*61046927SAndroid Build Coastguard Worker }
997*61046927SAndroid Build Coastguard Worker
998*61046927SAndroid Build Coastguard Worker b->cursor = nir_before_instr(instr);
999*61046927SAndroid Build Coastguard Worker nir_printf_fmt(b, true, 64, "starting pos=%02.2fx%02.2f tex=0x%08x\n",
1000*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 0),
1001*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 1),
1002*61046927SAndroid Build Coastguard Worker tex_src.ssa);
1003*61046927SAndroid Build Coastguard Worker
1004*61046927SAndroid Build Coastguard Worker b->cursor = nir_after_instr(instr);
1005*61046927SAndroid Build Coastguard Worker nir_printf_fmt(b, true, 64, "done pos=%02.2fx%02.2f tex=0x%08x\n",
1006*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 0),
1007*61046927SAndroid Build Coastguard Worker nir_channel(b, nir_load_frag_coord(b), 1),
1008*61046927SAndroid Build Coastguard Worker tex_src.ssa);
1009*61046927SAndroid Build Coastguard Worker
1010*61046927SAndroid Build Coastguard Worker return true;
1011*61046927SAndroid Build Coastguard Worker }
1012*61046927SAndroid Build Coastguard Worker
1013*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_lower_nir(struct anv_pipeline * pipeline,void * mem_ctx,struct anv_pipeline_stage * stage,struct anv_pipeline_sets_layout * layout,uint32_t view_mask,bool use_primitive_replication)1014*61046927SAndroid Build Coastguard Worker anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
1015*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1016*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage,
1017*61046927SAndroid Build Coastguard Worker struct anv_pipeline_sets_layout *layout,
1018*61046927SAndroid Build Coastguard Worker uint32_t view_mask,
1019*61046927SAndroid Build Coastguard Worker bool use_primitive_replication)
1020*61046927SAndroid Build Coastguard Worker {
1021*61046927SAndroid Build Coastguard Worker const struct anv_physical_device *pdevice = pipeline->device->physical;
1022*61046927SAndroid Build Coastguard Worker const struct brw_compiler *compiler = pdevice->compiler;
1023*61046927SAndroid Build Coastguard Worker
1024*61046927SAndroid Build Coastguard Worker struct brw_stage_prog_data *prog_data = &stage->prog_data.base;
1025*61046927SAndroid Build Coastguard Worker nir_shader *nir = stage->nir;
1026*61046927SAndroid Build Coastguard Worker
1027*61046927SAndroid Build Coastguard Worker if (nir->info.stage == MESA_SHADER_FRAGMENT) {
1028*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_wpos_center);
1029*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_input_attachments,
1030*61046927SAndroid Build Coastguard Worker &(nir_input_attachment_options) {
1031*61046927SAndroid Build Coastguard Worker .use_fragcoord_sysval = true,
1032*61046927SAndroid Build Coastguard Worker .use_layer_id_sysval = true,
1033*61046927SAndroid Build Coastguard Worker });
1034*61046927SAndroid Build Coastguard Worker }
1035*61046927SAndroid Build Coastguard Worker
1036*61046927SAndroid Build Coastguard Worker if (nir->info.stage == MESA_SHADER_MESH ||
1037*61046927SAndroid Build Coastguard Worker nir->info.stage == MESA_SHADER_TASK) {
1038*61046927SAndroid Build Coastguard Worker nir_lower_compute_system_values_options options = {
1039*61046927SAndroid Build Coastguard Worker .lower_workgroup_id_to_index = true,
1040*61046927SAndroid Build Coastguard Worker /* nir_lower_idiv generates expensive code */
1041*61046927SAndroid Build Coastguard Worker .shortcut_1d_workgroup_id = compiler->devinfo->verx10 >= 125,
1042*61046927SAndroid Build Coastguard Worker };
1043*61046927SAndroid Build Coastguard Worker
1044*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_compute_system_values, &options);
1045*61046927SAndroid Build Coastguard Worker }
1046*61046927SAndroid Build Coastguard Worker
1047*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_vk_lower_ycbcr_tex, lookup_ycbcr_conversion, layout);
1048*61046927SAndroid Build Coastguard Worker
1049*61046927SAndroid Build Coastguard Worker if (pipeline->type == ANV_PIPELINE_GRAPHICS ||
1050*61046927SAndroid Build Coastguard Worker pipeline->type == ANV_PIPELINE_GRAPHICS_LIB) {
1051*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, anv_nir_lower_multiview, view_mask,
1052*61046927SAndroid Build Coastguard Worker use_primitive_replication);
1053*61046927SAndroid Build Coastguard Worker }
1054*61046927SAndroid Build Coastguard Worker
1055*61046927SAndroid Build Coastguard Worker if (nir->info.stage == MESA_SHADER_COMPUTE && nir->info.cs.has_cooperative_matrix) {
1056*61046927SAndroid Build Coastguard Worker anv_fixup_subgroup_size(pipeline->device, &nir->info);
1057*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, brw_nir_lower_cmat, nir->info.subgroup_size);
1058*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, nir_lower_indirect_derefs, nir_var_function_temp, 16);
1059*61046927SAndroid Build Coastguard Worker }
1060*61046927SAndroid Build Coastguard Worker
1061*61046927SAndroid Build Coastguard Worker /* The patch control points are delivered through a push constant when
1062*61046927SAndroid Build Coastguard Worker * dynamic.
1063*61046927SAndroid Build Coastguard Worker */
1064*61046927SAndroid Build Coastguard Worker if (nir->info.stage == MESA_SHADER_TESS_CTRL &&
1065*61046927SAndroid Build Coastguard Worker stage->key.tcs.input_vertices == 0)
1066*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, anv_nir_lower_load_patch_vertices_in);
1067*61046927SAndroid Build Coastguard Worker
1068*61046927SAndroid Build Coastguard Worker nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
1069*61046927SAndroid Build Coastguard Worker
1070*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, brw_nir_lower_storage_image,
1071*61046927SAndroid Build Coastguard Worker &(struct brw_nir_lower_storage_image_opts) {
1072*61046927SAndroid Build Coastguard Worker /* Anv only supports Gfx9+ which has better defined typed read
1073*61046927SAndroid Build Coastguard Worker * behavior. It allows us to only have to care about lowering
1074*61046927SAndroid Build Coastguard Worker * loads.
1075*61046927SAndroid Build Coastguard Worker */
1076*61046927SAndroid Build Coastguard Worker .devinfo = compiler->devinfo,
1077*61046927SAndroid Build Coastguard Worker .lower_loads = true,
1078*61046927SAndroid Build Coastguard Worker });
1079*61046927SAndroid Build Coastguard Worker
1080*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_global,
1081*61046927SAndroid Build Coastguard Worker nir_address_format_64bit_global);
1082*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_push_const,
1083*61046927SAndroid Build Coastguard Worker nir_address_format_32bit_offset);
1084*61046927SAndroid Build Coastguard Worker
1085*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, brw_nir_lower_ray_queries, &pdevice->info);
1086*61046927SAndroid Build Coastguard Worker
1087*61046927SAndroid Build Coastguard Worker stage->push_desc_info.used_descriptors =
1088*61046927SAndroid Build Coastguard Worker anv_nir_compute_used_push_descriptors(nir, layout);
1089*61046927SAndroid Build Coastguard Worker
1090*61046927SAndroid Build Coastguard Worker struct anv_pipeline_push_map push_map = {};
1091*61046927SAndroid Build Coastguard Worker
1092*61046927SAndroid Build Coastguard Worker /* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
1093*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, anv_nir_apply_pipeline_layout,
1094*61046927SAndroid Build Coastguard Worker pdevice, stage->key.base.robust_flags,
1095*61046927SAndroid Build Coastguard Worker layout->independent_sets,
1096*61046927SAndroid Build Coastguard Worker layout, &stage->bind_map, &push_map, mem_ctx);
1097*61046927SAndroid Build Coastguard Worker
1098*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ubo,
1099*61046927SAndroid Build Coastguard Worker anv_nir_ubo_addr_format(pdevice, stage->key.base.robust_flags));
1100*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ssbo,
1101*61046927SAndroid Build Coastguard Worker anv_nir_ssbo_addr_format(pdevice, stage->key.base.robust_flags));
1102*61046927SAndroid Build Coastguard Worker
1103*61046927SAndroid Build Coastguard Worker /* First run copy-prop to get rid of all of the vec() that address
1104*61046927SAndroid Build Coastguard Worker * calculations often create and then constant-fold so that, when we
1105*61046927SAndroid Build Coastguard Worker * get to anv_nir_lower_ubo_loads, we can detect constant offsets.
1106*61046927SAndroid Build Coastguard Worker */
1107*61046927SAndroid Build Coastguard Worker bool progress;
1108*61046927SAndroid Build Coastguard Worker do {
1109*61046927SAndroid Build Coastguard Worker progress = false;
1110*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_algebraic);
1111*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_copy_prop);
1112*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_constant_folding);
1113*61046927SAndroid Build Coastguard Worker NIR_PASS(progress, nir, nir_opt_dce);
1114*61046927SAndroid Build Coastguard Worker } while (progress);
1115*61046927SAndroid Build Coastguard Worker
1116*61046927SAndroid Build Coastguard Worker /* Required for nir_divergence_analysis() which is needed for
1117*61046927SAndroid Build Coastguard Worker * anv_nir_lower_ubo_loads.
1118*61046927SAndroid Build Coastguard Worker */
1119*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_convert_to_lcssa, true, true);
1120*61046927SAndroid Build Coastguard Worker nir_divergence_analysis(nir);
1121*61046927SAndroid Build Coastguard Worker
1122*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, anv_nir_lower_ubo_loads);
1123*61046927SAndroid Build Coastguard Worker
1124*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_opt_remove_phis);
1125*61046927SAndroid Build Coastguard Worker
1126*61046927SAndroid Build Coastguard Worker enum nir_lower_non_uniform_access_type lower_non_uniform_access_types =
1127*61046927SAndroid Build Coastguard Worker nir_lower_non_uniform_texture_access |
1128*61046927SAndroid Build Coastguard Worker nir_lower_non_uniform_image_access |
1129*61046927SAndroid Build Coastguard Worker nir_lower_non_uniform_get_ssbo_size;
1130*61046927SAndroid Build Coastguard Worker
1131*61046927SAndroid Build Coastguard Worker /* In practice, most shaders do not have non-uniform-qualified
1132*61046927SAndroid Build Coastguard Worker * accesses (see
1133*61046927SAndroid Build Coastguard Worker * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17558#note_1475069)
1134*61046927SAndroid Build Coastguard Worker * thus a cheaper and likely to fail check is run first.
1135*61046927SAndroid Build Coastguard Worker */
1136*61046927SAndroid Build Coastguard Worker if (nir_has_non_uniform_access(nir, lower_non_uniform_access_types)) {
1137*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_opt_non_uniform_access);
1138*61046927SAndroid Build Coastguard Worker
1139*61046927SAndroid Build Coastguard Worker /* We don't support non-uniform UBOs and non-uniform SSBO access is
1140*61046927SAndroid Build Coastguard Worker * handled naturally by falling back to A64 messages.
1141*61046927SAndroid Build Coastguard Worker */
1142*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_non_uniform_access,
1143*61046927SAndroid Build Coastguard Worker &(nir_lower_non_uniform_access_options) {
1144*61046927SAndroid Build Coastguard Worker .types = lower_non_uniform_access_types,
1145*61046927SAndroid Build Coastguard Worker .callback = NULL,
1146*61046927SAndroid Build Coastguard Worker });
1147*61046927SAndroid Build Coastguard Worker
1148*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, intel_nir_lower_non_uniform_resource_intel);
1149*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, intel_nir_cleanup_resource_intel);
1150*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_opt_dce);
1151*61046927SAndroid Build Coastguard Worker }
1152*61046927SAndroid Build Coastguard Worker
1153*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, anv_nir_update_resource_intel_block);
1154*61046927SAndroid Build Coastguard Worker
1155*61046927SAndroid Build Coastguard Worker stage->dynamic_push_values = anv_nir_compute_dynamic_push_bits(nir);
1156*61046927SAndroid Build Coastguard Worker
1157*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, anv_nir_compute_push_layout,
1158*61046927SAndroid Build Coastguard Worker pdevice, stage->key.base.robust_flags,
1159*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_stage_fragment_dynamic(stage),
1160*61046927SAndroid Build Coastguard Worker prog_data, &stage->bind_map, &push_map,
1161*61046927SAndroid Build Coastguard Worker pipeline->layout.type, mem_ctx);
1162*61046927SAndroid Build Coastguard Worker
1163*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, anv_nir_lower_resource_intel, pdevice,
1164*61046927SAndroid Build Coastguard Worker pipeline->layout.type);
1165*61046927SAndroid Build Coastguard Worker
1166*61046927SAndroid Build Coastguard Worker if (gl_shader_stage_uses_workgroup(nir->info.stage)) {
1167*61046927SAndroid Build Coastguard Worker if (!nir->info.shared_memory_explicit_layout) {
1168*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_vars_to_explicit_types,
1169*61046927SAndroid Build Coastguard Worker nir_var_mem_shared, shared_type_info);
1170*61046927SAndroid Build Coastguard Worker }
1171*61046927SAndroid Build Coastguard Worker
1172*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_explicit_io,
1173*61046927SAndroid Build Coastguard Worker nir_var_mem_shared, nir_address_format_32bit_offset);
1174*61046927SAndroid Build Coastguard Worker
1175*61046927SAndroid Build Coastguard Worker if (nir->info.zero_initialize_shared_memory &&
1176*61046927SAndroid Build Coastguard Worker nir->info.shared_size > 0) {
1177*61046927SAndroid Build Coastguard Worker /* The effective Shared Local Memory size is at least 1024 bytes and
1178*61046927SAndroid Build Coastguard Worker * is always rounded to a power of two, so it is OK to align the size
1179*61046927SAndroid Build Coastguard Worker * used by the shader to chunk_size -- which does simplify the logic.
1180*61046927SAndroid Build Coastguard Worker */
1181*61046927SAndroid Build Coastguard Worker const unsigned chunk_size = 16;
1182*61046927SAndroid Build Coastguard Worker const unsigned shared_size = ALIGN(nir->info.shared_size, chunk_size);
1183*61046927SAndroid Build Coastguard Worker assert(shared_size <=
1184*61046927SAndroid Build Coastguard Worker intel_compute_slm_calculate_size(compiler->devinfo->ver, nir->info.shared_size));
1185*61046927SAndroid Build Coastguard Worker
1186*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_zero_initialize_shared_memory,
1187*61046927SAndroid Build Coastguard Worker shared_size, chunk_size);
1188*61046927SAndroid Build Coastguard Worker }
1189*61046927SAndroid Build Coastguard Worker }
1190*61046927SAndroid Build Coastguard Worker
1191*61046927SAndroid Build Coastguard Worker if (gl_shader_stage_is_compute(nir->info.stage) ||
1192*61046927SAndroid Build Coastguard Worker gl_shader_stage_is_mesh(nir->info.stage)) {
1193*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, brw_nir_lower_cs_intrinsics, compiler->devinfo,
1194*61046927SAndroid Build Coastguard Worker &stage->prog_data.cs);
1195*61046927SAndroid Build Coastguard Worker }
1196*61046927SAndroid Build Coastguard Worker
1197*61046927SAndroid Build Coastguard Worker stage->push_desc_info.used_set_buffer =
1198*61046927SAndroid Build Coastguard Worker anv_nir_loads_push_desc_buffer(nir, layout, &stage->bind_map);
1199*61046927SAndroid Build Coastguard Worker stage->push_desc_info.fully_promoted_ubo_descriptors =
1200*61046927SAndroid Build Coastguard Worker anv_nir_push_desc_ubo_fully_promoted(nir, layout, &stage->bind_map);
1201*61046927SAndroid Build Coastguard Worker
1202*61046927SAndroid Build Coastguard Worker #if DEBUG_PRINTF_EXAMPLE
1203*61046927SAndroid Build Coastguard Worker if (stage->stage == MESA_SHADER_FRAGMENT) {
1204*61046927SAndroid Build Coastguard Worker nir_shader_intrinsics_pass(nir, print_ubo_load,
1205*61046927SAndroid Build Coastguard Worker nir_metadata_control_flow,
1206*61046927SAndroid Build Coastguard Worker NULL);
1207*61046927SAndroid Build Coastguard Worker }
1208*61046927SAndroid Build Coastguard Worker #endif
1209*61046927SAndroid Build Coastguard Worker
1210*61046927SAndroid Build Coastguard Worker stage->nir = nir;
1211*61046927SAndroid Build Coastguard Worker }
1212*61046927SAndroid Build Coastguard Worker
1213*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_link_vs(const struct brw_compiler * compiler,struct anv_pipeline_stage * vs_stage,struct anv_pipeline_stage * next_stage)1214*61046927SAndroid Build Coastguard Worker anv_pipeline_link_vs(const struct brw_compiler *compiler,
1215*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *vs_stage,
1216*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *next_stage)
1217*61046927SAndroid Build Coastguard Worker {
1218*61046927SAndroid Build Coastguard Worker if (next_stage)
1219*61046927SAndroid Build Coastguard Worker brw_nir_link_shaders(compiler, vs_stage->nir, next_stage->nir);
1220*61046927SAndroid Build Coastguard Worker }
1221*61046927SAndroid Build Coastguard Worker
1222*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compile_vs(const struct brw_compiler * compiler,void * mem_ctx,struct anv_graphics_base_pipeline * pipeline,struct anv_pipeline_stage * vs_stage,uint32_t view_mask,char ** error_str)1223*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_vs(const struct brw_compiler *compiler,
1224*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1225*61046927SAndroid Build Coastguard Worker struct anv_graphics_base_pipeline *pipeline,
1226*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *vs_stage,
1227*61046927SAndroid Build Coastguard Worker uint32_t view_mask,
1228*61046927SAndroid Build Coastguard Worker char **error_str)
1229*61046927SAndroid Build Coastguard Worker {
1230*61046927SAndroid Build Coastguard Worker /* When using Primitive Replication for multiview, each view gets its own
1231*61046927SAndroid Build Coastguard Worker * position slot.
1232*61046927SAndroid Build Coastguard Worker */
1233*61046927SAndroid Build Coastguard Worker uint32_t pos_slots =
1234*61046927SAndroid Build Coastguard Worker (vs_stage->nir->info.per_view_outputs & VARYING_BIT_POS) ?
1235*61046927SAndroid Build Coastguard Worker MAX2(1, util_bitcount(view_mask)) : 1;
1236*61046927SAndroid Build Coastguard Worker
1237*61046927SAndroid Build Coastguard Worker /* Only position is allowed to be per-view */
1238*61046927SAndroid Build Coastguard Worker assert(!(vs_stage->nir->info.per_view_outputs & ~VARYING_BIT_POS));
1239*61046927SAndroid Build Coastguard Worker
1240*61046927SAndroid Build Coastguard Worker brw_compute_vue_map(compiler->devinfo,
1241*61046927SAndroid Build Coastguard Worker &vs_stage->prog_data.vs.base.vue_map,
1242*61046927SAndroid Build Coastguard Worker vs_stage->nir->info.outputs_written,
1243*61046927SAndroid Build Coastguard Worker vs_stage->nir->info.separate_shader,
1244*61046927SAndroid Build Coastguard Worker pos_slots);
1245*61046927SAndroid Build Coastguard Worker
1246*61046927SAndroid Build Coastguard Worker vs_stage->num_stats = 1;
1247*61046927SAndroid Build Coastguard Worker
1248*61046927SAndroid Build Coastguard Worker struct brw_compile_vs_params params = {
1249*61046927SAndroid Build Coastguard Worker .base = {
1250*61046927SAndroid Build Coastguard Worker .nir = vs_stage->nir,
1251*61046927SAndroid Build Coastguard Worker .stats = vs_stage->stats,
1252*61046927SAndroid Build Coastguard Worker .log_data = pipeline->base.device,
1253*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
1254*61046927SAndroid Build Coastguard Worker .source_hash = vs_stage->source_hash,
1255*61046927SAndroid Build Coastguard Worker },
1256*61046927SAndroid Build Coastguard Worker .key = &vs_stage->key.vs,
1257*61046927SAndroid Build Coastguard Worker .prog_data = &vs_stage->prog_data.vs,
1258*61046927SAndroid Build Coastguard Worker };
1259*61046927SAndroid Build Coastguard Worker
1260*61046927SAndroid Build Coastguard Worker vs_stage->code = brw_compile_vs(compiler, ¶ms);
1261*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
1262*61046927SAndroid Build Coastguard Worker }
1263*61046927SAndroid Build Coastguard Worker
1264*61046927SAndroid Build Coastguard Worker static void
merge_tess_info(struct shader_info * tes_info,const struct shader_info * tcs_info)1265*61046927SAndroid Build Coastguard Worker merge_tess_info(struct shader_info *tes_info,
1266*61046927SAndroid Build Coastguard Worker const struct shader_info *tcs_info)
1267*61046927SAndroid Build Coastguard Worker {
1268*61046927SAndroid Build Coastguard Worker /* The Vulkan 1.0.38 spec, section 21.1 Tessellator says:
1269*61046927SAndroid Build Coastguard Worker *
1270*61046927SAndroid Build Coastguard Worker * "PointMode. Controls generation of points rather than triangles
1271*61046927SAndroid Build Coastguard Worker * or lines. This functionality defaults to disabled, and is
1272*61046927SAndroid Build Coastguard Worker * enabled if either shader stage includes the execution mode.
1273*61046927SAndroid Build Coastguard Worker *
1274*61046927SAndroid Build Coastguard Worker * and about Triangles, Quads, IsoLines, VertexOrderCw, VertexOrderCcw,
1275*61046927SAndroid Build Coastguard Worker * PointMode, SpacingEqual, SpacingFractionalEven, SpacingFractionalOdd,
1276*61046927SAndroid Build Coastguard Worker * and OutputVertices, it says:
1277*61046927SAndroid Build Coastguard Worker *
1278*61046927SAndroid Build Coastguard Worker * "One mode must be set in at least one of the tessellation
1279*61046927SAndroid Build Coastguard Worker * shader stages."
1280*61046927SAndroid Build Coastguard Worker *
1281*61046927SAndroid Build Coastguard Worker * So, the fields can be set in either the TCS or TES, but they must
1282*61046927SAndroid Build Coastguard Worker * agree if set in both. Our backend looks at TES, so bitwise-or in
1283*61046927SAndroid Build Coastguard Worker * the values from the TCS.
1284*61046927SAndroid Build Coastguard Worker */
1285*61046927SAndroid Build Coastguard Worker assert(tcs_info->tess.tcs_vertices_out == 0 ||
1286*61046927SAndroid Build Coastguard Worker tes_info->tess.tcs_vertices_out == 0 ||
1287*61046927SAndroid Build Coastguard Worker tcs_info->tess.tcs_vertices_out == tes_info->tess.tcs_vertices_out);
1288*61046927SAndroid Build Coastguard Worker tes_info->tess.tcs_vertices_out |= tcs_info->tess.tcs_vertices_out;
1289*61046927SAndroid Build Coastguard Worker
1290*61046927SAndroid Build Coastguard Worker assert(tcs_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
1291*61046927SAndroid Build Coastguard Worker tes_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
1292*61046927SAndroid Build Coastguard Worker tcs_info->tess.spacing == tes_info->tess.spacing);
1293*61046927SAndroid Build Coastguard Worker tes_info->tess.spacing |= tcs_info->tess.spacing;
1294*61046927SAndroid Build Coastguard Worker
1295*61046927SAndroid Build Coastguard Worker assert(tcs_info->tess._primitive_mode == 0 ||
1296*61046927SAndroid Build Coastguard Worker tes_info->tess._primitive_mode == 0 ||
1297*61046927SAndroid Build Coastguard Worker tcs_info->tess._primitive_mode == tes_info->tess._primitive_mode);
1298*61046927SAndroid Build Coastguard Worker tes_info->tess._primitive_mode |= tcs_info->tess._primitive_mode;
1299*61046927SAndroid Build Coastguard Worker tes_info->tess.ccw |= tcs_info->tess.ccw;
1300*61046927SAndroid Build Coastguard Worker tes_info->tess.point_mode |= tcs_info->tess.point_mode;
1301*61046927SAndroid Build Coastguard Worker }
1302*61046927SAndroid Build Coastguard Worker
1303*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_link_tcs(const struct brw_compiler * compiler,struct anv_pipeline_stage * tcs_stage,struct anv_pipeline_stage * tes_stage)1304*61046927SAndroid Build Coastguard Worker anv_pipeline_link_tcs(const struct brw_compiler *compiler,
1305*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *tcs_stage,
1306*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *tes_stage)
1307*61046927SAndroid Build Coastguard Worker {
1308*61046927SAndroid Build Coastguard Worker assert(tes_stage && tes_stage->stage == MESA_SHADER_TESS_EVAL);
1309*61046927SAndroid Build Coastguard Worker
1310*61046927SAndroid Build Coastguard Worker brw_nir_link_shaders(compiler, tcs_stage->nir, tes_stage->nir);
1311*61046927SAndroid Build Coastguard Worker
1312*61046927SAndroid Build Coastguard Worker nir_lower_patch_vertices(tes_stage->nir,
1313*61046927SAndroid Build Coastguard Worker tcs_stage->nir->info.tess.tcs_vertices_out,
1314*61046927SAndroid Build Coastguard Worker NULL);
1315*61046927SAndroid Build Coastguard Worker
1316*61046927SAndroid Build Coastguard Worker /* Copy TCS info into the TES info */
1317*61046927SAndroid Build Coastguard Worker merge_tess_info(&tes_stage->nir->info, &tcs_stage->nir->info);
1318*61046927SAndroid Build Coastguard Worker
1319*61046927SAndroid Build Coastguard Worker /* Whacking the key after cache lookup is a bit sketchy, but all of
1320*61046927SAndroid Build Coastguard Worker * this comes from the SPIR-V, which is part of the hash used for the
1321*61046927SAndroid Build Coastguard Worker * pipeline cache. So it should be safe.
1322*61046927SAndroid Build Coastguard Worker */
1323*61046927SAndroid Build Coastguard Worker tcs_stage->key.tcs._tes_primitive_mode =
1324*61046927SAndroid Build Coastguard Worker tes_stage->nir->info.tess._primitive_mode;
1325*61046927SAndroid Build Coastguard Worker }
1326*61046927SAndroid Build Coastguard Worker
1327*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compile_tcs(const struct brw_compiler * compiler,void * mem_ctx,struct anv_device * device,struct anv_pipeline_stage * tcs_stage,struct anv_pipeline_stage * prev_stage,char ** error_str)1328*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_tcs(const struct brw_compiler *compiler,
1329*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1330*61046927SAndroid Build Coastguard Worker struct anv_device *device,
1331*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *tcs_stage,
1332*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *prev_stage,
1333*61046927SAndroid Build Coastguard Worker char **error_str)
1334*61046927SAndroid Build Coastguard Worker {
1335*61046927SAndroid Build Coastguard Worker tcs_stage->key.tcs.outputs_written =
1336*61046927SAndroid Build Coastguard Worker tcs_stage->nir->info.outputs_written;
1337*61046927SAndroid Build Coastguard Worker tcs_stage->key.tcs.patch_outputs_written =
1338*61046927SAndroid Build Coastguard Worker tcs_stage->nir->info.patch_outputs_written;
1339*61046927SAndroid Build Coastguard Worker
1340*61046927SAndroid Build Coastguard Worker tcs_stage->num_stats = 1;
1341*61046927SAndroid Build Coastguard Worker
1342*61046927SAndroid Build Coastguard Worker struct brw_compile_tcs_params params = {
1343*61046927SAndroid Build Coastguard Worker .base = {
1344*61046927SAndroid Build Coastguard Worker .nir = tcs_stage->nir,
1345*61046927SAndroid Build Coastguard Worker .stats = tcs_stage->stats,
1346*61046927SAndroid Build Coastguard Worker .log_data = device,
1347*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
1348*61046927SAndroid Build Coastguard Worker .source_hash = tcs_stage->source_hash,
1349*61046927SAndroid Build Coastguard Worker },
1350*61046927SAndroid Build Coastguard Worker .key = &tcs_stage->key.tcs,
1351*61046927SAndroid Build Coastguard Worker .prog_data = &tcs_stage->prog_data.tcs,
1352*61046927SAndroid Build Coastguard Worker };
1353*61046927SAndroid Build Coastguard Worker
1354*61046927SAndroid Build Coastguard Worker tcs_stage->code = brw_compile_tcs(compiler, ¶ms);
1355*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
1356*61046927SAndroid Build Coastguard Worker }
1357*61046927SAndroid Build Coastguard Worker
1358*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_link_tes(const struct brw_compiler * compiler,struct anv_pipeline_stage * tes_stage,struct anv_pipeline_stage * next_stage)1359*61046927SAndroid Build Coastguard Worker anv_pipeline_link_tes(const struct brw_compiler *compiler,
1360*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *tes_stage,
1361*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *next_stage)
1362*61046927SAndroid Build Coastguard Worker {
1363*61046927SAndroid Build Coastguard Worker if (next_stage)
1364*61046927SAndroid Build Coastguard Worker brw_nir_link_shaders(compiler, tes_stage->nir, next_stage->nir);
1365*61046927SAndroid Build Coastguard Worker }
1366*61046927SAndroid Build Coastguard Worker
1367*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compile_tes(const struct brw_compiler * compiler,void * mem_ctx,struct anv_device * device,struct anv_pipeline_stage * tes_stage,struct anv_pipeline_stage * tcs_stage,char ** error_str)1368*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_tes(const struct brw_compiler *compiler,
1369*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1370*61046927SAndroid Build Coastguard Worker struct anv_device *device,
1371*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *tes_stage,
1372*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *tcs_stage,
1373*61046927SAndroid Build Coastguard Worker char **error_str)
1374*61046927SAndroid Build Coastguard Worker {
1375*61046927SAndroid Build Coastguard Worker tes_stage->key.tes.inputs_read =
1376*61046927SAndroid Build Coastguard Worker tcs_stage->nir->info.outputs_written;
1377*61046927SAndroid Build Coastguard Worker tes_stage->key.tes.patch_inputs_read =
1378*61046927SAndroid Build Coastguard Worker tcs_stage->nir->info.patch_outputs_written;
1379*61046927SAndroid Build Coastguard Worker
1380*61046927SAndroid Build Coastguard Worker tes_stage->num_stats = 1;
1381*61046927SAndroid Build Coastguard Worker
1382*61046927SAndroid Build Coastguard Worker struct brw_compile_tes_params params = {
1383*61046927SAndroid Build Coastguard Worker .base = {
1384*61046927SAndroid Build Coastguard Worker .nir = tes_stage->nir,
1385*61046927SAndroid Build Coastguard Worker .stats = tes_stage->stats,
1386*61046927SAndroid Build Coastguard Worker .log_data = device,
1387*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
1388*61046927SAndroid Build Coastguard Worker .source_hash = tes_stage->source_hash,
1389*61046927SAndroid Build Coastguard Worker },
1390*61046927SAndroid Build Coastguard Worker .key = &tes_stage->key.tes,
1391*61046927SAndroid Build Coastguard Worker .prog_data = &tes_stage->prog_data.tes,
1392*61046927SAndroid Build Coastguard Worker .input_vue_map = &tcs_stage->prog_data.tcs.base.vue_map,
1393*61046927SAndroid Build Coastguard Worker };
1394*61046927SAndroid Build Coastguard Worker
1395*61046927SAndroid Build Coastguard Worker tes_stage->code = brw_compile_tes(compiler, ¶ms);
1396*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
1397*61046927SAndroid Build Coastguard Worker }
1398*61046927SAndroid Build Coastguard Worker
1399*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_link_gs(const struct brw_compiler * compiler,struct anv_pipeline_stage * gs_stage,struct anv_pipeline_stage * next_stage)1400*61046927SAndroid Build Coastguard Worker anv_pipeline_link_gs(const struct brw_compiler *compiler,
1401*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *gs_stage,
1402*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *next_stage)
1403*61046927SAndroid Build Coastguard Worker {
1404*61046927SAndroid Build Coastguard Worker if (next_stage)
1405*61046927SAndroid Build Coastguard Worker brw_nir_link_shaders(compiler, gs_stage->nir, next_stage->nir);
1406*61046927SAndroid Build Coastguard Worker }
1407*61046927SAndroid Build Coastguard Worker
1408*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compile_gs(const struct brw_compiler * compiler,void * mem_ctx,struct anv_device * device,struct anv_pipeline_stage * gs_stage,struct anv_pipeline_stage * prev_stage,char ** error_str)1409*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_gs(const struct brw_compiler *compiler,
1410*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1411*61046927SAndroid Build Coastguard Worker struct anv_device *device,
1412*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *gs_stage,
1413*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *prev_stage,
1414*61046927SAndroid Build Coastguard Worker char **error_str)
1415*61046927SAndroid Build Coastguard Worker {
1416*61046927SAndroid Build Coastguard Worker brw_compute_vue_map(compiler->devinfo,
1417*61046927SAndroid Build Coastguard Worker &gs_stage->prog_data.gs.base.vue_map,
1418*61046927SAndroid Build Coastguard Worker gs_stage->nir->info.outputs_written,
1419*61046927SAndroid Build Coastguard Worker gs_stage->nir->info.separate_shader, 1);
1420*61046927SAndroid Build Coastguard Worker
1421*61046927SAndroid Build Coastguard Worker gs_stage->num_stats = 1;
1422*61046927SAndroid Build Coastguard Worker
1423*61046927SAndroid Build Coastguard Worker struct brw_compile_gs_params params = {
1424*61046927SAndroid Build Coastguard Worker .base = {
1425*61046927SAndroid Build Coastguard Worker .nir = gs_stage->nir,
1426*61046927SAndroid Build Coastguard Worker .stats = gs_stage->stats,
1427*61046927SAndroid Build Coastguard Worker .log_data = device,
1428*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
1429*61046927SAndroid Build Coastguard Worker .source_hash = gs_stage->source_hash,
1430*61046927SAndroid Build Coastguard Worker },
1431*61046927SAndroid Build Coastguard Worker .key = &gs_stage->key.gs,
1432*61046927SAndroid Build Coastguard Worker .prog_data = &gs_stage->prog_data.gs,
1433*61046927SAndroid Build Coastguard Worker };
1434*61046927SAndroid Build Coastguard Worker
1435*61046927SAndroid Build Coastguard Worker gs_stage->code = brw_compile_gs(compiler, ¶ms);
1436*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
1437*61046927SAndroid Build Coastguard Worker }
1438*61046927SAndroid Build Coastguard Worker
1439*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_link_task(const struct brw_compiler * compiler,struct anv_pipeline_stage * task_stage,struct anv_pipeline_stage * next_stage)1440*61046927SAndroid Build Coastguard Worker anv_pipeline_link_task(const struct brw_compiler *compiler,
1441*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *task_stage,
1442*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *next_stage)
1443*61046927SAndroid Build Coastguard Worker {
1444*61046927SAndroid Build Coastguard Worker assert(next_stage);
1445*61046927SAndroid Build Coastguard Worker assert(next_stage->stage == MESA_SHADER_MESH);
1446*61046927SAndroid Build Coastguard Worker brw_nir_link_shaders(compiler, task_stage->nir, next_stage->nir);
1447*61046927SAndroid Build Coastguard Worker }
1448*61046927SAndroid Build Coastguard Worker
1449*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compile_task(const struct brw_compiler * compiler,void * mem_ctx,struct anv_device * device,struct anv_pipeline_stage * task_stage,char ** error_str)1450*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_task(const struct brw_compiler *compiler,
1451*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1452*61046927SAndroid Build Coastguard Worker struct anv_device *device,
1453*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *task_stage,
1454*61046927SAndroid Build Coastguard Worker char **error_str)
1455*61046927SAndroid Build Coastguard Worker {
1456*61046927SAndroid Build Coastguard Worker task_stage->num_stats = 1;
1457*61046927SAndroid Build Coastguard Worker
1458*61046927SAndroid Build Coastguard Worker struct brw_compile_task_params params = {
1459*61046927SAndroid Build Coastguard Worker .base = {
1460*61046927SAndroid Build Coastguard Worker .nir = task_stage->nir,
1461*61046927SAndroid Build Coastguard Worker .stats = task_stage->stats,
1462*61046927SAndroid Build Coastguard Worker .log_data = device,
1463*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
1464*61046927SAndroid Build Coastguard Worker .source_hash = task_stage->source_hash,
1465*61046927SAndroid Build Coastguard Worker },
1466*61046927SAndroid Build Coastguard Worker .key = &task_stage->key.task,
1467*61046927SAndroid Build Coastguard Worker .prog_data = &task_stage->prog_data.task,
1468*61046927SAndroid Build Coastguard Worker };
1469*61046927SAndroid Build Coastguard Worker
1470*61046927SAndroid Build Coastguard Worker task_stage->code = brw_compile_task(compiler, ¶ms);
1471*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
1472*61046927SAndroid Build Coastguard Worker }
1473*61046927SAndroid Build Coastguard Worker
1474*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_link_mesh(const struct brw_compiler * compiler,struct anv_pipeline_stage * mesh_stage,struct anv_pipeline_stage * next_stage)1475*61046927SAndroid Build Coastguard Worker anv_pipeline_link_mesh(const struct brw_compiler *compiler,
1476*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *mesh_stage,
1477*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *next_stage)
1478*61046927SAndroid Build Coastguard Worker {
1479*61046927SAndroid Build Coastguard Worker if (next_stage) {
1480*61046927SAndroid Build Coastguard Worker brw_nir_link_shaders(compiler, mesh_stage->nir, next_stage->nir);
1481*61046927SAndroid Build Coastguard Worker }
1482*61046927SAndroid Build Coastguard Worker }
1483*61046927SAndroid Build Coastguard Worker
1484*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compile_mesh(const struct brw_compiler * compiler,void * mem_ctx,struct anv_device * device,struct anv_pipeline_stage * mesh_stage,struct anv_pipeline_stage * prev_stage,char ** error_str)1485*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_mesh(const struct brw_compiler *compiler,
1486*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1487*61046927SAndroid Build Coastguard Worker struct anv_device *device,
1488*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *mesh_stage,
1489*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *prev_stage,
1490*61046927SAndroid Build Coastguard Worker char **error_str)
1491*61046927SAndroid Build Coastguard Worker {
1492*61046927SAndroid Build Coastguard Worker mesh_stage->num_stats = 1;
1493*61046927SAndroid Build Coastguard Worker
1494*61046927SAndroid Build Coastguard Worker struct brw_compile_mesh_params params = {
1495*61046927SAndroid Build Coastguard Worker .base = {
1496*61046927SAndroid Build Coastguard Worker .nir = mesh_stage->nir,
1497*61046927SAndroid Build Coastguard Worker .stats = mesh_stage->stats,
1498*61046927SAndroid Build Coastguard Worker .log_data = device,
1499*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
1500*61046927SAndroid Build Coastguard Worker .source_hash = mesh_stage->source_hash,
1501*61046927SAndroid Build Coastguard Worker },
1502*61046927SAndroid Build Coastguard Worker .key = &mesh_stage->key.mesh,
1503*61046927SAndroid Build Coastguard Worker .prog_data = &mesh_stage->prog_data.mesh,
1504*61046927SAndroid Build Coastguard Worker };
1505*61046927SAndroid Build Coastguard Worker
1506*61046927SAndroid Build Coastguard Worker if (prev_stage) {
1507*61046927SAndroid Build Coastguard Worker assert(prev_stage->stage == MESA_SHADER_TASK);
1508*61046927SAndroid Build Coastguard Worker params.tue_map = &prev_stage->prog_data.task.map;
1509*61046927SAndroid Build Coastguard Worker }
1510*61046927SAndroid Build Coastguard Worker
1511*61046927SAndroid Build Coastguard Worker mesh_stage->code = brw_compile_mesh(compiler, ¶ms);
1512*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
1513*61046927SAndroid Build Coastguard Worker }
1514*61046927SAndroid Build Coastguard Worker
1515*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_link_fs(const struct brw_compiler * compiler,struct anv_pipeline_stage * stage,const struct vk_render_pass_state * rp)1516*61046927SAndroid Build Coastguard Worker anv_pipeline_link_fs(const struct brw_compiler *compiler,
1517*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage,
1518*61046927SAndroid Build Coastguard Worker const struct vk_render_pass_state *rp)
1519*61046927SAndroid Build Coastguard Worker {
1520*61046927SAndroid Build Coastguard Worker /* Initially the valid outputs value is set to all possible render targets
1521*61046927SAndroid Build Coastguard Worker * valid (see populate_wm_prog_key()), before we look at the shader
1522*61046927SAndroid Build Coastguard Worker * variables. Here we look at the output variables of the shader an compute
1523*61046927SAndroid Build Coastguard Worker * a correct number of render target outputs.
1524*61046927SAndroid Build Coastguard Worker */
1525*61046927SAndroid Build Coastguard Worker stage->key.wm.color_outputs_valid = 0;
1526*61046927SAndroid Build Coastguard Worker nir_foreach_shader_out_variable_safe(var, stage->nir) {
1527*61046927SAndroid Build Coastguard Worker if (var->data.location < FRAG_RESULT_DATA0)
1528*61046927SAndroid Build Coastguard Worker continue;
1529*61046927SAndroid Build Coastguard Worker
1530*61046927SAndroid Build Coastguard Worker const unsigned rt = var->data.location - FRAG_RESULT_DATA0;
1531*61046927SAndroid Build Coastguard Worker const unsigned array_len =
1532*61046927SAndroid Build Coastguard Worker glsl_type_is_array(var->type) ? glsl_get_length(var->type) : 1;
1533*61046927SAndroid Build Coastguard Worker assert(rt + array_len <= MAX_RTS);
1534*61046927SAndroid Build Coastguard Worker
1535*61046927SAndroid Build Coastguard Worker stage->key.wm.color_outputs_valid |= BITFIELD_RANGE(rt, array_len);
1536*61046927SAndroid Build Coastguard Worker }
1537*61046927SAndroid Build Coastguard Worker stage->key.wm.color_outputs_valid &= rp_color_mask(rp);
1538*61046927SAndroid Build Coastguard Worker stage->key.wm.nr_color_regions =
1539*61046927SAndroid Build Coastguard Worker util_last_bit(stage->key.wm.color_outputs_valid);
1540*61046927SAndroid Build Coastguard Worker
1541*61046927SAndroid Build Coastguard Worker unsigned num_rt_bindings;
1542*61046927SAndroid Build Coastguard Worker struct anv_pipeline_binding rt_bindings[MAX_RTS];
1543*61046927SAndroid Build Coastguard Worker if (stage->key.wm.nr_color_regions > 0) {
1544*61046927SAndroid Build Coastguard Worker assert(stage->key.wm.nr_color_regions <= MAX_RTS);
1545*61046927SAndroid Build Coastguard Worker for (unsigned rt = 0; rt < stage->key.wm.nr_color_regions; rt++) {
1546*61046927SAndroid Build Coastguard Worker if (stage->key.wm.color_outputs_valid & BITFIELD_BIT(rt)) {
1547*61046927SAndroid Build Coastguard Worker rt_bindings[rt] = (struct anv_pipeline_binding) {
1548*61046927SAndroid Build Coastguard Worker .set = ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS,
1549*61046927SAndroid Build Coastguard Worker .index = rt,
1550*61046927SAndroid Build Coastguard Worker .binding = UINT32_MAX,
1551*61046927SAndroid Build Coastguard Worker
1552*61046927SAndroid Build Coastguard Worker };
1553*61046927SAndroid Build Coastguard Worker } else {
1554*61046927SAndroid Build Coastguard Worker /* Setup a null render target */
1555*61046927SAndroid Build Coastguard Worker rt_bindings[rt] = (struct anv_pipeline_binding) {
1556*61046927SAndroid Build Coastguard Worker .set = ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS,
1557*61046927SAndroid Build Coastguard Worker .index = UINT32_MAX,
1558*61046927SAndroid Build Coastguard Worker .binding = UINT32_MAX,
1559*61046927SAndroid Build Coastguard Worker };
1560*61046927SAndroid Build Coastguard Worker }
1561*61046927SAndroid Build Coastguard Worker }
1562*61046927SAndroid Build Coastguard Worker num_rt_bindings = stage->key.wm.nr_color_regions;
1563*61046927SAndroid Build Coastguard Worker } else {
1564*61046927SAndroid Build Coastguard Worker /* Setup a null render target */
1565*61046927SAndroid Build Coastguard Worker rt_bindings[0] = (struct anv_pipeline_binding) {
1566*61046927SAndroid Build Coastguard Worker .set = ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS,
1567*61046927SAndroid Build Coastguard Worker .index = UINT32_MAX,
1568*61046927SAndroid Build Coastguard Worker };
1569*61046927SAndroid Build Coastguard Worker num_rt_bindings = 1;
1570*61046927SAndroid Build Coastguard Worker }
1571*61046927SAndroid Build Coastguard Worker
1572*61046927SAndroid Build Coastguard Worker assert(num_rt_bindings <= MAX_RTS);
1573*61046927SAndroid Build Coastguard Worker assert(stage->bind_map.surface_count == 0);
1574*61046927SAndroid Build Coastguard Worker typed_memcpy(stage->bind_map.surface_to_descriptor,
1575*61046927SAndroid Build Coastguard Worker rt_bindings, num_rt_bindings);
1576*61046927SAndroid Build Coastguard Worker stage->bind_map.surface_count += num_rt_bindings;
1577*61046927SAndroid Build Coastguard Worker }
1578*61046927SAndroid Build Coastguard Worker
1579*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compile_fs(const struct brw_compiler * compiler,void * mem_ctx,struct anv_device * device,struct anv_pipeline_stage * fs_stage,struct anv_pipeline_stage * prev_stage,struct anv_graphics_base_pipeline * pipeline,uint32_t view_mask,bool use_primitive_replication,char ** error_str)1580*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_fs(const struct brw_compiler *compiler,
1581*61046927SAndroid Build Coastguard Worker void *mem_ctx,
1582*61046927SAndroid Build Coastguard Worker struct anv_device *device,
1583*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *fs_stage,
1584*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *prev_stage,
1585*61046927SAndroid Build Coastguard Worker struct anv_graphics_base_pipeline *pipeline,
1586*61046927SAndroid Build Coastguard Worker uint32_t view_mask,
1587*61046927SAndroid Build Coastguard Worker bool use_primitive_replication,
1588*61046927SAndroid Build Coastguard Worker char **error_str)
1589*61046927SAndroid Build Coastguard Worker {
1590*61046927SAndroid Build Coastguard Worker /* When using Primitive Replication for multiview, each view gets its own
1591*61046927SAndroid Build Coastguard Worker * position slot.
1592*61046927SAndroid Build Coastguard Worker */
1593*61046927SAndroid Build Coastguard Worker uint32_t pos_slots = use_primitive_replication ?
1594*61046927SAndroid Build Coastguard Worker MAX2(1, util_bitcount(view_mask)) : 1;
1595*61046927SAndroid Build Coastguard Worker
1596*61046927SAndroid Build Coastguard Worker /* If we have a previous stage we can use that to deduce valid slots.
1597*61046927SAndroid Build Coastguard Worker * Otherwise, rely on inputs of the input shader.
1598*61046927SAndroid Build Coastguard Worker */
1599*61046927SAndroid Build Coastguard Worker if (prev_stage) {
1600*61046927SAndroid Build Coastguard Worker fs_stage->key.wm.input_slots_valid =
1601*61046927SAndroid Build Coastguard Worker prev_stage->prog_data.vue.vue_map.slots_valid;
1602*61046927SAndroid Build Coastguard Worker } else {
1603*61046927SAndroid Build Coastguard Worker struct intel_vue_map prev_vue_map;
1604*61046927SAndroid Build Coastguard Worker brw_compute_vue_map(compiler->devinfo,
1605*61046927SAndroid Build Coastguard Worker &prev_vue_map,
1606*61046927SAndroid Build Coastguard Worker fs_stage->nir->info.inputs_read,
1607*61046927SAndroid Build Coastguard Worker fs_stage->nir->info.separate_shader,
1608*61046927SAndroid Build Coastguard Worker pos_slots);
1609*61046927SAndroid Build Coastguard Worker
1610*61046927SAndroid Build Coastguard Worker fs_stage->key.wm.input_slots_valid = prev_vue_map.slots_valid;
1611*61046927SAndroid Build Coastguard Worker }
1612*61046927SAndroid Build Coastguard Worker
1613*61046927SAndroid Build Coastguard Worker struct brw_compile_fs_params params = {
1614*61046927SAndroid Build Coastguard Worker .base = {
1615*61046927SAndroid Build Coastguard Worker .nir = fs_stage->nir,
1616*61046927SAndroid Build Coastguard Worker .stats = fs_stage->stats,
1617*61046927SAndroid Build Coastguard Worker .log_data = device,
1618*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
1619*61046927SAndroid Build Coastguard Worker .source_hash = fs_stage->source_hash,
1620*61046927SAndroid Build Coastguard Worker },
1621*61046927SAndroid Build Coastguard Worker .key = &fs_stage->key.wm,
1622*61046927SAndroid Build Coastguard Worker .prog_data = &fs_stage->prog_data.wm,
1623*61046927SAndroid Build Coastguard Worker
1624*61046927SAndroid Build Coastguard Worker .allow_spilling = true,
1625*61046927SAndroid Build Coastguard Worker .max_polygons = UCHAR_MAX,
1626*61046927SAndroid Build Coastguard Worker };
1627*61046927SAndroid Build Coastguard Worker
1628*61046927SAndroid Build Coastguard Worker if (prev_stage && prev_stage->stage == MESA_SHADER_MESH) {
1629*61046927SAndroid Build Coastguard Worker params.mue_map = &prev_stage->prog_data.mesh.map;
1630*61046927SAndroid Build Coastguard Worker /* TODO(mesh): Slots valid, do we even use/rely on it? */
1631*61046927SAndroid Build Coastguard Worker }
1632*61046927SAndroid Build Coastguard Worker
1633*61046927SAndroid Build Coastguard Worker fs_stage->code = brw_compile_fs(compiler, ¶ms);
1634*61046927SAndroid Build Coastguard Worker *error_str = params.base.error_str;
1635*61046927SAndroid Build Coastguard Worker
1636*61046927SAndroid Build Coastguard Worker fs_stage->num_stats = (uint32_t)!!fs_stage->prog_data.wm.dispatch_multi +
1637*61046927SAndroid Build Coastguard Worker (uint32_t)fs_stage->prog_data.wm.dispatch_8 +
1638*61046927SAndroid Build Coastguard Worker (uint32_t)fs_stage->prog_data.wm.dispatch_16 +
1639*61046927SAndroid Build Coastguard Worker (uint32_t)fs_stage->prog_data.wm.dispatch_32;
1640*61046927SAndroid Build Coastguard Worker assert(fs_stage->num_stats <= ARRAY_SIZE(fs_stage->stats));
1641*61046927SAndroid Build Coastguard Worker }
1642*61046927SAndroid Build Coastguard Worker
1643*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_add_executable(struct anv_pipeline * pipeline,struct anv_pipeline_stage * stage,struct brw_compile_stats * stats,uint32_t code_offset)1644*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executable(struct anv_pipeline *pipeline,
1645*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage,
1646*61046927SAndroid Build Coastguard Worker struct brw_compile_stats *stats,
1647*61046927SAndroid Build Coastguard Worker uint32_t code_offset)
1648*61046927SAndroid Build Coastguard Worker {
1649*61046927SAndroid Build Coastguard Worker char *nir = NULL;
1650*61046927SAndroid Build Coastguard Worker if (stage->nir &&
1651*61046927SAndroid Build Coastguard Worker (pipeline->flags &
1652*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR)) {
1653*61046927SAndroid Build Coastguard Worker nir = nir_shader_as_str(stage->nir, pipeline->mem_ctx);
1654*61046927SAndroid Build Coastguard Worker }
1655*61046927SAndroid Build Coastguard Worker
1656*61046927SAndroid Build Coastguard Worker char *disasm = NULL;
1657*61046927SAndroid Build Coastguard Worker if (stage->code &&
1658*61046927SAndroid Build Coastguard Worker (pipeline->flags &
1659*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR)) {
1660*61046927SAndroid Build Coastguard Worker char *stream_data = NULL;
1661*61046927SAndroid Build Coastguard Worker size_t stream_size = 0;
1662*61046927SAndroid Build Coastguard Worker FILE *stream = open_memstream(&stream_data, &stream_size);
1663*61046927SAndroid Build Coastguard Worker
1664*61046927SAndroid Build Coastguard Worker uint32_t push_size = 0;
1665*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < 4; i++)
1666*61046927SAndroid Build Coastguard Worker push_size += stage->bind_map.push_ranges[i].length;
1667*61046927SAndroid Build Coastguard Worker if (push_size > 0) {
1668*61046927SAndroid Build Coastguard Worker fprintf(stream, "Push constant ranges:\n");
1669*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < 4; i++) {
1670*61046927SAndroid Build Coastguard Worker if (stage->bind_map.push_ranges[i].length == 0)
1671*61046927SAndroid Build Coastguard Worker continue;
1672*61046927SAndroid Build Coastguard Worker
1673*61046927SAndroid Build Coastguard Worker fprintf(stream, " RANGE%d (%dB): ", i,
1674*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].length * 32);
1675*61046927SAndroid Build Coastguard Worker
1676*61046927SAndroid Build Coastguard Worker switch (stage->bind_map.push_ranges[i].set) {
1677*61046927SAndroid Build Coastguard Worker case ANV_DESCRIPTOR_SET_NULL:
1678*61046927SAndroid Build Coastguard Worker fprintf(stream, "NULL");
1679*61046927SAndroid Build Coastguard Worker break;
1680*61046927SAndroid Build Coastguard Worker
1681*61046927SAndroid Build Coastguard Worker case ANV_DESCRIPTOR_SET_PUSH_CONSTANTS:
1682*61046927SAndroid Build Coastguard Worker fprintf(stream, "Vulkan push constants and API params");
1683*61046927SAndroid Build Coastguard Worker break;
1684*61046927SAndroid Build Coastguard Worker
1685*61046927SAndroid Build Coastguard Worker case ANV_DESCRIPTOR_SET_DESCRIPTORS_BUFFER:
1686*61046927SAndroid Build Coastguard Worker fprintf(stream, "Descriptor buffer (desc buffer) for set %d (start=%dB)",
1687*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].index,
1688*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].start * 32);
1689*61046927SAndroid Build Coastguard Worker break;
1690*61046927SAndroid Build Coastguard Worker
1691*61046927SAndroid Build Coastguard Worker case ANV_DESCRIPTOR_SET_DESCRIPTORS:
1692*61046927SAndroid Build Coastguard Worker fprintf(stream, "Descriptor buffer for set %d (start=%dB)",
1693*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].index,
1694*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].start * 32);
1695*61046927SAndroid Build Coastguard Worker break;
1696*61046927SAndroid Build Coastguard Worker
1697*61046927SAndroid Build Coastguard Worker case ANV_DESCRIPTOR_SET_NUM_WORK_GROUPS:
1698*61046927SAndroid Build Coastguard Worker unreachable("gl_NumWorkgroups is never pushed");
1699*61046927SAndroid Build Coastguard Worker
1700*61046927SAndroid Build Coastguard Worker case ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS:
1701*61046927SAndroid Build Coastguard Worker unreachable("Color attachments can't be pushed");
1702*61046927SAndroid Build Coastguard Worker
1703*61046927SAndroid Build Coastguard Worker default:
1704*61046927SAndroid Build Coastguard Worker fprintf(stream, "UBO (set=%d binding=%d start=%dB)",
1705*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].set,
1706*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].index,
1707*61046927SAndroid Build Coastguard Worker stage->bind_map.push_ranges[i].start * 32);
1708*61046927SAndroid Build Coastguard Worker break;
1709*61046927SAndroid Build Coastguard Worker }
1710*61046927SAndroid Build Coastguard Worker fprintf(stream, "\n");
1711*61046927SAndroid Build Coastguard Worker }
1712*61046927SAndroid Build Coastguard Worker fprintf(stream, "\n");
1713*61046927SAndroid Build Coastguard Worker }
1714*61046927SAndroid Build Coastguard Worker
1715*61046927SAndroid Build Coastguard Worker /* Creating this is far cheaper than it looks. It's perfectly fine to
1716*61046927SAndroid Build Coastguard Worker * do it for every binary.
1717*61046927SAndroid Build Coastguard Worker */
1718*61046927SAndroid Build Coastguard Worker brw_disassemble_with_errors(&pipeline->device->physical->compiler->isa,
1719*61046927SAndroid Build Coastguard Worker stage->code, code_offset, stream);
1720*61046927SAndroid Build Coastguard Worker
1721*61046927SAndroid Build Coastguard Worker fclose(stream);
1722*61046927SAndroid Build Coastguard Worker
1723*61046927SAndroid Build Coastguard Worker /* Copy it to a ralloc'd thing */
1724*61046927SAndroid Build Coastguard Worker disasm = ralloc_size(pipeline->mem_ctx, stream_size + 1);
1725*61046927SAndroid Build Coastguard Worker memcpy(disasm, stream_data, stream_size);
1726*61046927SAndroid Build Coastguard Worker disasm[stream_size] = 0;
1727*61046927SAndroid Build Coastguard Worker
1728*61046927SAndroid Build Coastguard Worker free(stream_data);
1729*61046927SAndroid Build Coastguard Worker }
1730*61046927SAndroid Build Coastguard Worker
1731*61046927SAndroid Build Coastguard Worker const struct anv_pipeline_executable exe = {
1732*61046927SAndroid Build Coastguard Worker .stage = stage->stage,
1733*61046927SAndroid Build Coastguard Worker .stats = *stats,
1734*61046927SAndroid Build Coastguard Worker .nir = nir,
1735*61046927SAndroid Build Coastguard Worker .disasm = disasm,
1736*61046927SAndroid Build Coastguard Worker };
1737*61046927SAndroid Build Coastguard Worker util_dynarray_append(&pipeline->executables,
1738*61046927SAndroid Build Coastguard Worker struct anv_pipeline_executable, exe);
1739*61046927SAndroid Build Coastguard Worker }
1740*61046927SAndroid Build Coastguard Worker
1741*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_add_executables(struct anv_pipeline * pipeline,struct anv_pipeline_stage * stage)1742*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executables(struct anv_pipeline *pipeline,
1743*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage)
1744*61046927SAndroid Build Coastguard Worker {
1745*61046927SAndroid Build Coastguard Worker if (stage->stage == MESA_SHADER_FRAGMENT) {
1746*61046927SAndroid Build Coastguard Worker /* We pull the prog data and stats out of the anv_shader_bin because
1747*61046927SAndroid Build Coastguard Worker * the anv_pipeline_stage may not be fully populated if we successfully
1748*61046927SAndroid Build Coastguard Worker * looked up the shader in a cache.
1749*61046927SAndroid Build Coastguard Worker */
1750*61046927SAndroid Build Coastguard Worker const struct brw_wm_prog_data *wm_prog_data =
1751*61046927SAndroid Build Coastguard Worker (const struct brw_wm_prog_data *)stage->bin->prog_data;
1752*61046927SAndroid Build Coastguard Worker struct brw_compile_stats *stats = stage->bin->stats;
1753*61046927SAndroid Build Coastguard Worker
1754*61046927SAndroid Build Coastguard Worker if (wm_prog_data->dispatch_8 ||
1755*61046927SAndroid Build Coastguard Worker wm_prog_data->dispatch_multi) {
1756*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executable(pipeline, stage, stats++, 0);
1757*61046927SAndroid Build Coastguard Worker }
1758*61046927SAndroid Build Coastguard Worker
1759*61046927SAndroid Build Coastguard Worker if (wm_prog_data->dispatch_16) {
1760*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executable(pipeline, stage, stats++,
1761*61046927SAndroid Build Coastguard Worker wm_prog_data->prog_offset_16);
1762*61046927SAndroid Build Coastguard Worker }
1763*61046927SAndroid Build Coastguard Worker
1764*61046927SAndroid Build Coastguard Worker if (wm_prog_data->dispatch_32) {
1765*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executable(pipeline, stage, stats++,
1766*61046927SAndroid Build Coastguard Worker wm_prog_data->prog_offset_32);
1767*61046927SAndroid Build Coastguard Worker }
1768*61046927SAndroid Build Coastguard Worker } else {
1769*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executable(pipeline, stage, stage->bin->stats, 0);
1770*61046927SAndroid Build Coastguard Worker }
1771*61046927SAndroid Build Coastguard Worker }
1772*61046927SAndroid Build Coastguard Worker
1773*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_account_shader(struct anv_pipeline * pipeline,struct anv_shader_bin * shader)1774*61046927SAndroid Build Coastguard Worker anv_pipeline_account_shader(struct anv_pipeline *pipeline,
1775*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *shader)
1776*61046927SAndroid Build Coastguard Worker {
1777*61046927SAndroid Build Coastguard Worker pipeline->scratch_size = MAX2(pipeline->scratch_size,
1778*61046927SAndroid Build Coastguard Worker shader->prog_data->total_scratch);
1779*61046927SAndroid Build Coastguard Worker
1780*61046927SAndroid Build Coastguard Worker pipeline->ray_queries = MAX2(pipeline->ray_queries,
1781*61046927SAndroid Build Coastguard Worker shader->prog_data->ray_queries);
1782*61046927SAndroid Build Coastguard Worker
1783*61046927SAndroid Build Coastguard Worker if (shader->push_desc_info.used_set_buffer) {
1784*61046927SAndroid Build Coastguard Worker pipeline->use_push_descriptor_buffer |=
1785*61046927SAndroid Build Coastguard Worker mesa_to_vk_shader_stage(shader->stage);
1786*61046927SAndroid Build Coastguard Worker }
1787*61046927SAndroid Build Coastguard Worker if (shader->push_desc_info.used_descriptors &
1788*61046927SAndroid Build Coastguard Worker ~shader->push_desc_info.fully_promoted_ubo_descriptors)
1789*61046927SAndroid Build Coastguard Worker pipeline->use_push_descriptor |= mesa_to_vk_shader_stage(shader->stage);
1790*61046927SAndroid Build Coastguard Worker }
1791*61046927SAndroid Build Coastguard Worker
1792*61046927SAndroid Build Coastguard Worker /* This function return true if a shader should not be looked at because of
1793*61046927SAndroid Build Coastguard Worker * fast linking. Instead we should use the shader binaries provided by
1794*61046927SAndroid Build Coastguard Worker * libraries.
1795*61046927SAndroid Build Coastguard Worker */
1796*61046927SAndroid Build Coastguard Worker static bool
anv_graphics_pipeline_skip_shader_compile(struct anv_graphics_base_pipeline * pipeline,struct anv_pipeline_stage * stages,bool link_optimize,gl_shader_stage stage)1797*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_skip_shader_compile(struct anv_graphics_base_pipeline *pipeline,
1798*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
1799*61046927SAndroid Build Coastguard Worker bool link_optimize,
1800*61046927SAndroid Build Coastguard Worker gl_shader_stage stage)
1801*61046927SAndroid Build Coastguard Worker {
1802*61046927SAndroid Build Coastguard Worker /* Always skip non active stages */
1803*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, stage))
1804*61046927SAndroid Build Coastguard Worker return true;
1805*61046927SAndroid Build Coastguard Worker
1806*61046927SAndroid Build Coastguard Worker /* When link optimizing, consider all stages */
1807*61046927SAndroid Build Coastguard Worker if (link_optimize)
1808*61046927SAndroid Build Coastguard Worker return false;
1809*61046927SAndroid Build Coastguard Worker
1810*61046927SAndroid Build Coastguard Worker /* Otherwise check if the stage was specified through
1811*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo
1812*61046927SAndroid Build Coastguard Worker */
1813*61046927SAndroid Build Coastguard Worker assert(stages[stage].info != NULL || stages[stage].imported.bin != NULL);
1814*61046927SAndroid Build Coastguard Worker return stages[stage].info == NULL;
1815*61046927SAndroid Build Coastguard Worker }
1816*61046927SAndroid Build Coastguard Worker
1817*61046927SAndroid Build Coastguard Worker static void
anv_graphics_pipeline_init_keys(struct anv_graphics_base_pipeline * pipeline,const struct vk_graphics_pipeline_state * state,struct anv_pipeline_stage * stages)1818*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_init_keys(struct anv_graphics_base_pipeline *pipeline,
1819*61046927SAndroid Build Coastguard Worker const struct vk_graphics_pipeline_state *state,
1820*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages)
1821*61046927SAndroid Build Coastguard Worker {
1822*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
1823*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
1824*61046927SAndroid Build Coastguard Worker continue;
1825*61046927SAndroid Build Coastguard Worker
1826*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
1827*61046927SAndroid Build Coastguard Worker
1828*61046927SAndroid Build Coastguard Worker const struct anv_device *device = pipeline->base.device;
1829*61046927SAndroid Build Coastguard Worker switch (stages[s].stage) {
1830*61046927SAndroid Build Coastguard Worker case MESA_SHADER_VERTEX:
1831*61046927SAndroid Build Coastguard Worker populate_vs_prog_key(&stages[s], device);
1832*61046927SAndroid Build Coastguard Worker break;
1833*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_CTRL:
1834*61046927SAndroid Build Coastguard Worker populate_tcs_prog_key(&stages[s],
1835*61046927SAndroid Build Coastguard Worker device,
1836*61046927SAndroid Build Coastguard Worker BITSET_TEST(state->dynamic,
1837*61046927SAndroid Build Coastguard Worker MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS) ?
1838*61046927SAndroid Build Coastguard Worker 0 : state->ts->patch_control_points);
1839*61046927SAndroid Build Coastguard Worker break;
1840*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_EVAL:
1841*61046927SAndroid Build Coastguard Worker populate_tes_prog_key(&stages[s], device);
1842*61046927SAndroid Build Coastguard Worker break;
1843*61046927SAndroid Build Coastguard Worker case MESA_SHADER_GEOMETRY:
1844*61046927SAndroid Build Coastguard Worker populate_gs_prog_key(&stages[s], device);
1845*61046927SAndroid Build Coastguard Worker break;
1846*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT: {
1847*61046927SAndroid Build Coastguard Worker /* Assume rasterization enabled in any of the following case :
1848*61046927SAndroid Build Coastguard Worker *
1849*61046927SAndroid Build Coastguard Worker * - We're a pipeline library without pre-rasterization information
1850*61046927SAndroid Build Coastguard Worker *
1851*61046927SAndroid Build Coastguard Worker * - Rasterization is not disabled in the non dynamic state
1852*61046927SAndroid Build Coastguard Worker *
1853*61046927SAndroid Build Coastguard Worker * - Rasterization disable is dynamic
1854*61046927SAndroid Build Coastguard Worker */
1855*61046927SAndroid Build Coastguard Worker const bool raster_enabled =
1856*61046927SAndroid Build Coastguard Worker state->rs == NULL ||
1857*61046927SAndroid Build Coastguard Worker !state->rs->rasterizer_discard_enable ||
1858*61046927SAndroid Build Coastguard Worker BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE);
1859*61046927SAndroid Build Coastguard Worker enum brw_sometimes is_mesh = BRW_NEVER;
1860*61046927SAndroid Build Coastguard Worker if (device->vk.enabled_extensions.EXT_mesh_shader) {
1861*61046927SAndroid Build Coastguard Worker if (anv_pipeline_base_has_stage(pipeline, MESA_SHADER_VERTEX))
1862*61046927SAndroid Build Coastguard Worker is_mesh = BRW_NEVER;
1863*61046927SAndroid Build Coastguard Worker else if (anv_pipeline_base_has_stage(pipeline, MESA_SHADER_MESH))
1864*61046927SAndroid Build Coastguard Worker is_mesh = BRW_ALWAYS;
1865*61046927SAndroid Build Coastguard Worker else {
1866*61046927SAndroid Build Coastguard Worker assert(pipeline->base.type == ANV_PIPELINE_GRAPHICS_LIB);
1867*61046927SAndroid Build Coastguard Worker is_mesh = BRW_SOMETIMES;
1868*61046927SAndroid Build Coastguard Worker }
1869*61046927SAndroid Build Coastguard Worker }
1870*61046927SAndroid Build Coastguard Worker populate_wm_prog_key(&stages[s],
1871*61046927SAndroid Build Coastguard Worker pipeline,
1872*61046927SAndroid Build Coastguard Worker state->dynamic,
1873*61046927SAndroid Build Coastguard Worker raster_enabled ? state->ms : NULL,
1874*61046927SAndroid Build Coastguard Worker state->fsr, state->rp, is_mesh);
1875*61046927SAndroid Build Coastguard Worker break;
1876*61046927SAndroid Build Coastguard Worker }
1877*61046927SAndroid Build Coastguard Worker
1878*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TASK:
1879*61046927SAndroid Build Coastguard Worker populate_task_prog_key(&stages[s], device);
1880*61046927SAndroid Build Coastguard Worker break;
1881*61046927SAndroid Build Coastguard Worker
1882*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MESH: {
1883*61046927SAndroid Build Coastguard Worker const bool compact_mue =
1884*61046927SAndroid Build Coastguard Worker !(pipeline->base.type == ANV_PIPELINE_GRAPHICS_LIB &&
1885*61046927SAndroid Build Coastguard Worker !anv_pipeline_base_has_stage(pipeline, MESA_SHADER_FRAGMENT));
1886*61046927SAndroid Build Coastguard Worker populate_mesh_prog_key(&stages[s], device, compact_mue);
1887*61046927SAndroid Build Coastguard Worker break;
1888*61046927SAndroid Build Coastguard Worker }
1889*61046927SAndroid Build Coastguard Worker
1890*61046927SAndroid Build Coastguard Worker default:
1891*61046927SAndroid Build Coastguard Worker unreachable("Invalid graphics shader stage");
1892*61046927SAndroid Build Coastguard Worker }
1893*61046927SAndroid Build Coastguard Worker
1894*61046927SAndroid Build Coastguard Worker stages[s].feedback.duration += os_time_get_nano() - stage_start;
1895*61046927SAndroid Build Coastguard Worker stages[s].feedback.flags |= VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
1896*61046927SAndroid Build Coastguard Worker }
1897*61046927SAndroid Build Coastguard Worker }
1898*61046927SAndroid Build Coastguard Worker
1899*61046927SAndroid Build Coastguard Worker static void
anv_graphics_lib_retain_shaders(struct anv_graphics_base_pipeline * pipeline,struct anv_pipeline_stage * stages,bool will_compile)1900*61046927SAndroid Build Coastguard Worker anv_graphics_lib_retain_shaders(struct anv_graphics_base_pipeline *pipeline,
1901*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
1902*61046927SAndroid Build Coastguard Worker bool will_compile)
1903*61046927SAndroid Build Coastguard Worker {
1904*61046927SAndroid Build Coastguard Worker /* There isn't much point in retaining NIR shaders on final pipelines. */
1905*61046927SAndroid Build Coastguard Worker assert(pipeline->base.type == ANV_PIPELINE_GRAPHICS_LIB);
1906*61046927SAndroid Build Coastguard Worker
1907*61046927SAndroid Build Coastguard Worker struct anv_graphics_lib_pipeline *lib = (struct anv_graphics_lib_pipeline *) pipeline;
1908*61046927SAndroid Build Coastguard Worker
1909*61046927SAndroid Build Coastguard Worker for (int s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
1910*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
1911*61046927SAndroid Build Coastguard Worker continue;
1912*61046927SAndroid Build Coastguard Worker
1913*61046927SAndroid Build Coastguard Worker memcpy(lib->retained_shaders[s].shader_sha1, stages[s].shader_sha1,
1914*61046927SAndroid Build Coastguard Worker sizeof(stages[s].shader_sha1));
1915*61046927SAndroid Build Coastguard Worker
1916*61046927SAndroid Build Coastguard Worker lib->retained_shaders[s].subgroup_size_type = stages[s].subgroup_size_type;
1917*61046927SAndroid Build Coastguard Worker
1918*61046927SAndroid Build Coastguard Worker nir_shader *nir = stages[s].nir != NULL ? stages[s].nir : stages[s].imported.nir;
1919*61046927SAndroid Build Coastguard Worker assert(nir != NULL);
1920*61046927SAndroid Build Coastguard Worker
1921*61046927SAndroid Build Coastguard Worker if (!will_compile) {
1922*61046927SAndroid Build Coastguard Worker lib->retained_shaders[s].nir = nir;
1923*61046927SAndroid Build Coastguard Worker } else {
1924*61046927SAndroid Build Coastguard Worker lib->retained_shaders[s].nir =
1925*61046927SAndroid Build Coastguard Worker nir_shader_clone(pipeline->base.mem_ctx, nir);
1926*61046927SAndroid Build Coastguard Worker }
1927*61046927SAndroid Build Coastguard Worker }
1928*61046927SAndroid Build Coastguard Worker }
1929*61046927SAndroid Build Coastguard Worker
1930*61046927SAndroid Build Coastguard Worker static bool
anv_graphics_pipeline_load_cached_shaders(struct anv_graphics_base_pipeline * pipeline,struct vk_pipeline_cache * cache,struct anv_pipeline_stage * stages,bool link_optimize,VkPipelineCreationFeedback * pipeline_feedback)1931*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_load_cached_shaders(struct anv_graphics_base_pipeline *pipeline,
1932*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
1933*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
1934*61046927SAndroid Build Coastguard Worker bool link_optimize,
1935*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback *pipeline_feedback)
1936*61046927SAndroid Build Coastguard Worker {
1937*61046927SAndroid Build Coastguard Worker struct anv_device *device = pipeline->base.device;
1938*61046927SAndroid Build Coastguard Worker unsigned cache_hits = 0, found = 0, imported = 0;
1939*61046927SAndroid Build Coastguard Worker
1940*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
1941*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
1942*61046927SAndroid Build Coastguard Worker continue;
1943*61046927SAndroid Build Coastguard Worker
1944*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
1945*61046927SAndroid Build Coastguard Worker
1946*61046927SAndroid Build Coastguard Worker bool cache_hit;
1947*61046927SAndroid Build Coastguard Worker stages[s].bin =
1948*61046927SAndroid Build Coastguard Worker anv_device_search_for_kernel(device, cache, &stages[s].cache_key,
1949*61046927SAndroid Build Coastguard Worker sizeof(stages[s].cache_key), &cache_hit);
1950*61046927SAndroid Build Coastguard Worker if (stages[s].bin) {
1951*61046927SAndroid Build Coastguard Worker found++;
1952*61046927SAndroid Build Coastguard Worker pipeline->shaders[s] = stages[s].bin;
1953*61046927SAndroid Build Coastguard Worker }
1954*61046927SAndroid Build Coastguard Worker
1955*61046927SAndroid Build Coastguard Worker if (cache_hit) {
1956*61046927SAndroid Build Coastguard Worker cache_hits++;
1957*61046927SAndroid Build Coastguard Worker stages[s].feedback.flags |=
1958*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
1959*61046927SAndroid Build Coastguard Worker }
1960*61046927SAndroid Build Coastguard Worker stages[s].feedback.duration += os_time_get_nano() - stage_start;
1961*61046927SAndroid Build Coastguard Worker }
1962*61046927SAndroid Build Coastguard Worker
1963*61046927SAndroid Build Coastguard Worker /* When not link optimizing, lookup the missing shader in the imported
1964*61046927SAndroid Build Coastguard Worker * libraries.
1965*61046927SAndroid Build Coastguard Worker */
1966*61046927SAndroid Build Coastguard Worker if (!link_optimize) {
1967*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
1968*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
1969*61046927SAndroid Build Coastguard Worker continue;
1970*61046927SAndroid Build Coastguard Worker
1971*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[s] != NULL)
1972*61046927SAndroid Build Coastguard Worker continue;
1973*61046927SAndroid Build Coastguard Worker
1974*61046927SAndroid Build Coastguard Worker if (stages[s].imported.bin == NULL)
1975*61046927SAndroid Build Coastguard Worker continue;
1976*61046927SAndroid Build Coastguard Worker
1977*61046927SAndroid Build Coastguard Worker stages[s].bin = stages[s].imported.bin;
1978*61046927SAndroid Build Coastguard Worker pipeline->shaders[s] = anv_shader_bin_ref(stages[s].imported.bin);
1979*61046927SAndroid Build Coastguard Worker pipeline->source_hashes[s] = stages[s].source_hash;
1980*61046927SAndroid Build Coastguard Worker imported++;
1981*61046927SAndroid Build Coastguard Worker }
1982*61046927SAndroid Build Coastguard Worker }
1983*61046927SAndroid Build Coastguard Worker
1984*61046927SAndroid Build Coastguard Worker if ((found + imported) == __builtin_popcount(pipeline->base.active_stages)) {
1985*61046927SAndroid Build Coastguard Worker if (cache_hits == found && found != 0) {
1986*61046927SAndroid Build Coastguard Worker pipeline_feedback->flags |=
1987*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
1988*61046927SAndroid Build Coastguard Worker }
1989*61046927SAndroid Build Coastguard Worker /* We found all our shaders in the cache. We're done. */
1990*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
1991*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[s] == NULL)
1992*61046927SAndroid Build Coastguard Worker continue;
1993*61046927SAndroid Build Coastguard Worker
1994*61046927SAndroid Build Coastguard Worker /* Only add the executables when we're not importing or doing link
1995*61046927SAndroid Build Coastguard Worker * optimizations. The imported executables are added earlier. Link
1996*61046927SAndroid Build Coastguard Worker * optimization can produce different binaries.
1997*61046927SAndroid Build Coastguard Worker */
1998*61046927SAndroid Build Coastguard Worker if (stages[s].imported.bin == NULL || link_optimize)
1999*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executables(&pipeline->base, &stages[s]);
2000*61046927SAndroid Build Coastguard Worker pipeline->source_hashes[s] = stages[s].source_hash;
2001*61046927SAndroid Build Coastguard Worker }
2002*61046927SAndroid Build Coastguard Worker return true;
2003*61046927SAndroid Build Coastguard Worker } else if (found > 0) {
2004*61046927SAndroid Build Coastguard Worker /* We found some but not all of our shaders. This shouldn't happen most
2005*61046927SAndroid Build Coastguard Worker * of the time but it can if we have a partially populated pipeline
2006*61046927SAndroid Build Coastguard Worker * cache.
2007*61046927SAndroid Build Coastguard Worker */
2008*61046927SAndroid Build Coastguard Worker assert(found < __builtin_popcount(pipeline->base.active_stages));
2009*61046927SAndroid Build Coastguard Worker
2010*61046927SAndroid Build Coastguard Worker /* With GPL, this might well happen if the app does an optimized
2011*61046927SAndroid Build Coastguard Worker * link.
2012*61046927SAndroid Build Coastguard Worker */
2013*61046927SAndroid Build Coastguard Worker if (!pipeline->base.device->vk.enabled_extensions.EXT_graphics_pipeline_library) {
2014*61046927SAndroid Build Coastguard Worker vk_perf(VK_LOG_OBJS(cache ? &cache->base :
2015*61046927SAndroid Build Coastguard Worker &pipeline->base.device->vk.base),
2016*61046927SAndroid Build Coastguard Worker "Found a partial pipeline in the cache. This is "
2017*61046927SAndroid Build Coastguard Worker "most likely caused by an incomplete pipeline cache "
2018*61046927SAndroid Build Coastguard Worker "import or export");
2019*61046927SAndroid Build Coastguard Worker }
2020*61046927SAndroid Build Coastguard Worker
2021*61046927SAndroid Build Coastguard Worker /* We're going to have to recompile anyway, so just throw away our
2022*61046927SAndroid Build Coastguard Worker * references to the shaders in the cache. We'll get them out of the
2023*61046927SAndroid Build Coastguard Worker * cache again as part of the compilation process.
2024*61046927SAndroid Build Coastguard Worker */
2025*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
2026*61046927SAndroid Build Coastguard Worker stages[s].feedback.flags = 0;
2027*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[s]) {
2028*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, pipeline->shaders[s]);
2029*61046927SAndroid Build Coastguard Worker pipeline->shaders[s] = NULL;
2030*61046927SAndroid Build Coastguard Worker }
2031*61046927SAndroid Build Coastguard Worker }
2032*61046927SAndroid Build Coastguard Worker }
2033*61046927SAndroid Build Coastguard Worker
2034*61046927SAndroid Build Coastguard Worker return false;
2035*61046927SAndroid Build Coastguard Worker }
2036*61046927SAndroid Build Coastguard Worker
2037*61046927SAndroid Build Coastguard Worker static const gl_shader_stage graphics_shader_order[] = {
2038*61046927SAndroid Build Coastguard Worker MESA_SHADER_VERTEX,
2039*61046927SAndroid Build Coastguard Worker MESA_SHADER_TESS_CTRL,
2040*61046927SAndroid Build Coastguard Worker MESA_SHADER_TESS_EVAL,
2041*61046927SAndroid Build Coastguard Worker MESA_SHADER_GEOMETRY,
2042*61046927SAndroid Build Coastguard Worker
2043*61046927SAndroid Build Coastguard Worker MESA_SHADER_TASK,
2044*61046927SAndroid Build Coastguard Worker MESA_SHADER_MESH,
2045*61046927SAndroid Build Coastguard Worker
2046*61046927SAndroid Build Coastguard Worker MESA_SHADER_FRAGMENT,
2047*61046927SAndroid Build Coastguard Worker };
2048*61046927SAndroid Build Coastguard Worker
2049*61046927SAndroid Build Coastguard Worker /* This function loads NIR only for stages specified in
2050*61046927SAndroid Build Coastguard Worker * VkGraphicsPipelineCreateInfo::pStages[]
2051*61046927SAndroid Build Coastguard Worker */
2052*61046927SAndroid Build Coastguard Worker static VkResult
anv_graphics_pipeline_load_nir(struct anv_graphics_base_pipeline * pipeline,struct vk_pipeline_cache * cache,struct anv_pipeline_stage * stages,void * mem_ctx,bool need_clone)2053*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_load_nir(struct anv_graphics_base_pipeline *pipeline,
2054*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
2055*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
2056*61046927SAndroid Build Coastguard Worker void *mem_ctx,
2057*61046927SAndroid Build Coastguard Worker bool need_clone)
2058*61046927SAndroid Build Coastguard Worker {
2059*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
2060*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
2061*61046927SAndroid Build Coastguard Worker continue;
2062*61046927SAndroid Build Coastguard Worker
2063*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
2064*61046927SAndroid Build Coastguard Worker
2065*61046927SAndroid Build Coastguard Worker assert(stages[s].stage == s);
2066*61046927SAndroid Build Coastguard Worker
2067*61046927SAndroid Build Coastguard Worker /* Only use the create NIR from the pStages[] element if we don't have
2068*61046927SAndroid Build Coastguard Worker * an imported library for the same stage.
2069*61046927SAndroid Build Coastguard Worker */
2070*61046927SAndroid Build Coastguard Worker if (stages[s].imported.bin == NULL) {
2071*61046927SAndroid Build Coastguard Worker VkResult result = anv_pipeline_stage_get_nir(&pipeline->base, cache,
2072*61046927SAndroid Build Coastguard Worker mem_ctx, &stages[s]);
2073*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2074*61046927SAndroid Build Coastguard Worker return result;
2075*61046927SAndroid Build Coastguard Worker } else {
2076*61046927SAndroid Build Coastguard Worker stages[s].nir = need_clone ?
2077*61046927SAndroid Build Coastguard Worker nir_shader_clone(mem_ctx, stages[s].imported.nir) :
2078*61046927SAndroid Build Coastguard Worker stages[s].imported.nir;
2079*61046927SAndroid Build Coastguard Worker }
2080*61046927SAndroid Build Coastguard Worker
2081*61046927SAndroid Build Coastguard Worker stages[s].feedback.duration += os_time_get_nano() - stage_start;
2082*61046927SAndroid Build Coastguard Worker }
2083*61046927SAndroid Build Coastguard Worker
2084*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2085*61046927SAndroid Build Coastguard Worker }
2086*61046927SAndroid Build Coastguard Worker
2087*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_nir_preprocess(struct anv_pipeline * pipeline,struct anv_pipeline_stage * stage)2088*61046927SAndroid Build Coastguard Worker anv_pipeline_nir_preprocess(struct anv_pipeline *pipeline,
2089*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage)
2090*61046927SAndroid Build Coastguard Worker {
2091*61046927SAndroid Build Coastguard Worker struct anv_device *device = pipeline->device;
2092*61046927SAndroid Build Coastguard Worker const struct brw_compiler *compiler = device->physical->compiler;
2093*61046927SAndroid Build Coastguard Worker
2094*61046927SAndroid Build Coastguard Worker const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = {
2095*61046927SAndroid Build Coastguard Worker .point_coord = true,
2096*61046927SAndroid Build Coastguard Worker };
2097*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
2098*61046927SAndroid Build Coastguard Worker
2099*61046927SAndroid Build Coastguard Worker const nir_opt_access_options opt_access_options = {
2100*61046927SAndroid Build Coastguard Worker .is_vulkan = true,
2101*61046927SAndroid Build Coastguard Worker };
2102*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_access, &opt_access_options);
2103*61046927SAndroid Build Coastguard Worker
2104*61046927SAndroid Build Coastguard Worker /* Vulkan uses the separate-shader linking model */
2105*61046927SAndroid Build Coastguard Worker stage->nir->info.separate_shader = true;
2106*61046927SAndroid Build Coastguard Worker
2107*61046927SAndroid Build Coastguard Worker struct brw_nir_compiler_opts opts = {
2108*61046927SAndroid Build Coastguard Worker .softfp64 = device->fp64_nir,
2109*61046927SAndroid Build Coastguard Worker /* Assume robustness with EXT_pipeline_robustness because this can be
2110*61046927SAndroid Build Coastguard Worker * turned on/off per pipeline and we have no visibility on this here.
2111*61046927SAndroid Build Coastguard Worker */
2112*61046927SAndroid Build Coastguard Worker .robust_image_access = device->vk.enabled_features.robustImageAccess ||
2113*61046927SAndroid Build Coastguard Worker device->vk.enabled_features.robustImageAccess2 ||
2114*61046927SAndroid Build Coastguard Worker device->vk.enabled_extensions.EXT_pipeline_robustness,
2115*61046927SAndroid Build Coastguard Worker .input_vertices = stage->nir->info.stage == MESA_SHADER_TESS_CTRL ?
2116*61046927SAndroid Build Coastguard Worker stage->key.tcs.input_vertices : 0,
2117*61046927SAndroid Build Coastguard Worker };
2118*61046927SAndroid Build Coastguard Worker brw_preprocess_nir(compiler, stage->nir, &opts);
2119*61046927SAndroid Build Coastguard Worker
2120*61046927SAndroid Build Coastguard Worker if (stage->nir->info.stage == MESA_SHADER_MESH) {
2121*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, anv_nir_lower_set_vtx_and_prim_count);
2122*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_dce);
2123*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_remove_dead_variables, nir_var_shader_out, NULL);
2124*61046927SAndroid Build Coastguard Worker }
2125*61046927SAndroid Build Coastguard Worker
2126*61046927SAndroid Build Coastguard Worker NIR_PASS(_, stage->nir, nir_opt_barrier_modes);
2127*61046927SAndroid Build Coastguard Worker
2128*61046927SAndroid Build Coastguard Worker nir_shader_gather_info(stage->nir, nir_shader_get_entrypoint(stage->nir));
2129*61046927SAndroid Build Coastguard Worker }
2130*61046927SAndroid Build Coastguard Worker
2131*61046927SAndroid Build Coastguard Worker static void
anv_fill_pipeline_creation_feedback(const struct anv_graphics_base_pipeline * pipeline,VkPipelineCreationFeedback * pipeline_feedback,const VkGraphicsPipelineCreateInfo * info,struct anv_pipeline_stage * stages)2132*61046927SAndroid Build Coastguard Worker anv_fill_pipeline_creation_feedback(const struct anv_graphics_base_pipeline *pipeline,
2133*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback *pipeline_feedback,
2134*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
2135*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages)
2136*61046927SAndroid Build Coastguard Worker {
2137*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedbackCreateInfo *create_feedback =
2138*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
2139*61046927SAndroid Build Coastguard Worker if (create_feedback) {
2140*61046927SAndroid Build Coastguard Worker *create_feedback->pPipelineCreationFeedback = *pipeline_feedback;
2141*61046927SAndroid Build Coastguard Worker
2142*61046927SAndroid Build Coastguard Worker /* VkPipelineCreationFeedbackCreateInfo:
2143*61046927SAndroid Build Coastguard Worker *
2144*61046927SAndroid Build Coastguard Worker * "An implementation must set or clear the
2145*61046927SAndroid Build Coastguard Worker * VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT in
2146*61046927SAndroid Build Coastguard Worker * VkPipelineCreationFeedback::flags for pPipelineCreationFeedback
2147*61046927SAndroid Build Coastguard Worker * and every element of pPipelineStageCreationFeedbacks."
2148*61046927SAndroid Build Coastguard Worker *
2149*61046927SAndroid Build Coastguard Worker */
2150*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < create_feedback->pipelineStageCreationFeedbackCount; i++) {
2151*61046927SAndroid Build Coastguard Worker create_feedback->pPipelineStageCreationFeedbacks[i].flags &=
2152*61046927SAndroid Build Coastguard Worker ~VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
2153*61046927SAndroid Build Coastguard Worker }
2154*61046927SAndroid Build Coastguard Worker /* This part is not really specified in the Vulkan spec at the moment.
2155*61046927SAndroid Build Coastguard Worker * We're kind of guessing what the CTS wants. We might need to update
2156*61046927SAndroid Build Coastguard Worker * when https://gitlab.khronos.org/vulkan/vulkan/-/issues/3115 is
2157*61046927SAndroid Build Coastguard Worker * clarified.
2158*61046927SAndroid Build Coastguard Worker */
2159*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
2160*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
2161*61046927SAndroid Build Coastguard Worker continue;
2162*61046927SAndroid Build Coastguard Worker
2163*61046927SAndroid Build Coastguard Worker if (stages[s].feedback_idx < create_feedback->pipelineStageCreationFeedbackCount) {
2164*61046927SAndroid Build Coastguard Worker create_feedback->pPipelineStageCreationFeedbacks[
2165*61046927SAndroid Build Coastguard Worker stages[s].feedback_idx] = stages[s].feedback;
2166*61046927SAndroid Build Coastguard Worker }
2167*61046927SAndroid Build Coastguard Worker }
2168*61046927SAndroid Build Coastguard Worker }
2169*61046927SAndroid Build Coastguard Worker }
2170*61046927SAndroid Build Coastguard Worker
2171*61046927SAndroid Build Coastguard Worker static uint32_t
anv_graphics_pipeline_imported_shader_count(struct anv_pipeline_stage * stages)2172*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_imported_shader_count(struct anv_pipeline_stage *stages)
2173*61046927SAndroid Build Coastguard Worker {
2174*61046927SAndroid Build Coastguard Worker uint32_t count = 0;
2175*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
2176*61046927SAndroid Build Coastguard Worker if (stages[s].imported.bin != NULL)
2177*61046927SAndroid Build Coastguard Worker count++;
2178*61046927SAndroid Build Coastguard Worker }
2179*61046927SAndroid Build Coastguard Worker return count;
2180*61046927SAndroid Build Coastguard Worker }
2181*61046927SAndroid Build Coastguard Worker
2182*61046927SAndroid Build Coastguard Worker static VkResult
anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline * pipeline,struct anv_pipeline_stage * stages,struct vk_pipeline_cache * cache,VkPipelineCreationFeedback * pipeline_feedback,const VkGraphicsPipelineCreateInfo * info,const struct vk_graphics_pipeline_state * state)2183*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
2184*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
2185*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
2186*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback *pipeline_feedback,
2187*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *info,
2188*61046927SAndroid Build Coastguard Worker const struct vk_graphics_pipeline_state *state)
2189*61046927SAndroid Build Coastguard Worker {
2190*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
2191*61046927SAndroid Build Coastguard Worker
2192*61046927SAndroid Build Coastguard Worker struct anv_device *device = pipeline->base.device;
2193*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = device->info;
2194*61046927SAndroid Build Coastguard Worker const struct brw_compiler *compiler = device->physical->compiler;
2195*61046927SAndroid Build Coastguard Worker
2196*61046927SAndroid Build Coastguard Worker /* Setup the shaders given in this VkGraphicsPipelineCreateInfo::pStages[].
2197*61046927SAndroid Build Coastguard Worker * Other shaders imported from libraries should have been added by
2198*61046927SAndroid Build Coastguard Worker * anv_graphics_pipeline_import_lib().
2199*61046927SAndroid Build Coastguard Worker */
2200*61046927SAndroid Build Coastguard Worker uint32_t shader_count = anv_graphics_pipeline_imported_shader_count(stages);
2201*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->stageCount; i++) {
2202*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = vk_to_mesa_shader_stage(info->pStages[i].stage);
2203*61046927SAndroid Build Coastguard Worker
2204*61046927SAndroid Build Coastguard Worker /* If a pipeline library is loaded in this stage, we should ignore the
2205*61046927SAndroid Build Coastguard Worker * pStages[] entry of the same stage.
2206*61046927SAndroid Build Coastguard Worker */
2207*61046927SAndroid Build Coastguard Worker if (stages[stage].imported.bin != NULL)
2208*61046927SAndroid Build Coastguard Worker continue;
2209*61046927SAndroid Build Coastguard Worker
2210*61046927SAndroid Build Coastguard Worker stages[stage].stage = stage;
2211*61046927SAndroid Build Coastguard Worker stages[stage].pipeline_flags = pipeline->base.flags;
2212*61046927SAndroid Build Coastguard Worker stages[stage].pipeline_pNext = info->pNext;
2213*61046927SAndroid Build Coastguard Worker stages[stage].info = &info->pStages[i];
2214*61046927SAndroid Build Coastguard Worker stages[stage].feedback_idx = shader_count++;
2215*61046927SAndroid Build Coastguard Worker
2216*61046927SAndroid Build Coastguard Worker anv_stage_write_shader_hash(&stages[stage], device);
2217*61046927SAndroid Build Coastguard Worker }
2218*61046927SAndroid Build Coastguard Worker
2219*61046927SAndroid Build Coastguard Worker /* Prepare shader keys for all shaders in pipeline->base.active_stages
2220*61046927SAndroid Build Coastguard Worker * (this includes libraries) before generating the hash for cache look up.
2221*61046927SAndroid Build Coastguard Worker *
2222*61046927SAndroid Build Coastguard Worker * We're doing this because the spec states that :
2223*61046927SAndroid Build Coastguard Worker *
2224*61046927SAndroid Build Coastguard Worker * "When an implementation is looking up a pipeline in a pipeline cache,
2225*61046927SAndroid Build Coastguard Worker * if that pipeline is being created using linked libraries,
2226*61046927SAndroid Build Coastguard Worker * implementations should always return an equivalent pipeline created
2227*61046927SAndroid Build Coastguard Worker * with VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT if available,
2228*61046927SAndroid Build Coastguard Worker * whether or not that bit was specified."
2229*61046927SAndroid Build Coastguard Worker *
2230*61046927SAndroid Build Coastguard Worker * So even if the application does not request link optimization, we have
2231*61046927SAndroid Build Coastguard Worker * to do our cache lookup with the entire set of shader sha1s so that we
2232*61046927SAndroid Build Coastguard Worker * can find what would be the best optimized pipeline in the case as if we
2233*61046927SAndroid Build Coastguard Worker * had compiled all the shaders together and known the full graphics state.
2234*61046927SAndroid Build Coastguard Worker */
2235*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_init_keys(pipeline, state, stages);
2236*61046927SAndroid Build Coastguard Worker
2237*61046927SAndroid Build Coastguard Worker uint32_t view_mask = state->rp ? state->rp->view_mask : 0;
2238*61046927SAndroid Build Coastguard Worker
2239*61046927SAndroid Build Coastguard Worker unsigned char sha1[20];
2240*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_graphics(pipeline, stages, view_mask, sha1);
2241*61046927SAndroid Build Coastguard Worker
2242*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
2243*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
2244*61046927SAndroid Build Coastguard Worker continue;
2245*61046927SAndroid Build Coastguard Worker
2246*61046927SAndroid Build Coastguard Worker stages[s].cache_key.stage = s;
2247*61046927SAndroid Build Coastguard Worker memcpy(stages[s].cache_key.sha1, sha1, sizeof(sha1));
2248*61046927SAndroid Build Coastguard Worker }
2249*61046927SAndroid Build Coastguard Worker
2250*61046927SAndroid Build Coastguard Worker const bool retain_shaders =
2251*61046927SAndroid Build Coastguard Worker pipeline->base.flags & VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
2252*61046927SAndroid Build Coastguard Worker const bool link_optimize =
2253*61046927SAndroid Build Coastguard Worker pipeline->base.flags & VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT;
2254*61046927SAndroid Build Coastguard Worker
2255*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
2256*61046927SAndroid Build Coastguard Worker const bool skip_cache_lookup =
2257*61046927SAndroid Build Coastguard Worker (pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
2258*61046927SAndroid Build Coastguard Worker
2259*61046927SAndroid Build Coastguard Worker if (!skip_cache_lookup) {
2260*61046927SAndroid Build Coastguard Worker bool found_all_shaders =
2261*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_load_cached_shaders(pipeline, cache, stages,
2262*61046927SAndroid Build Coastguard Worker link_optimize,
2263*61046927SAndroid Build Coastguard Worker pipeline_feedback);
2264*61046927SAndroid Build Coastguard Worker
2265*61046927SAndroid Build Coastguard Worker if (found_all_shaders) {
2266*61046927SAndroid Build Coastguard Worker /* If we need to retain shaders, we need to also load from the NIR
2267*61046927SAndroid Build Coastguard Worker * cache.
2268*61046927SAndroid Build Coastguard Worker */
2269*61046927SAndroid Build Coastguard Worker if (pipeline->base.type == ANV_PIPELINE_GRAPHICS_LIB && retain_shaders) {
2270*61046927SAndroid Build Coastguard Worker result = anv_graphics_pipeline_load_nir(pipeline, cache,
2271*61046927SAndroid Build Coastguard Worker stages,
2272*61046927SAndroid Build Coastguard Worker pipeline->base.mem_ctx,
2273*61046927SAndroid Build Coastguard Worker false /* need_clone */);
2274*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2275*61046927SAndroid Build Coastguard Worker vk_perf(VK_LOG_OBJS(cache ? &cache->base :
2276*61046927SAndroid Build Coastguard Worker &pipeline->base.device->vk.base),
2277*61046927SAndroid Build Coastguard Worker "Found all ISA shaders in the cache but not all NIR shaders.");
2278*61046927SAndroid Build Coastguard Worker } else {
2279*61046927SAndroid Build Coastguard Worker anv_graphics_lib_retain_shaders(pipeline, stages, false /* will_compile */);
2280*61046927SAndroid Build Coastguard Worker }
2281*61046927SAndroid Build Coastguard Worker }
2282*61046927SAndroid Build Coastguard Worker
2283*61046927SAndroid Build Coastguard Worker if (result == VK_SUCCESS)
2284*61046927SAndroid Build Coastguard Worker goto done;
2285*61046927SAndroid Build Coastguard Worker
2286*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
2287*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
2288*61046927SAndroid Build Coastguard Worker continue;
2289*61046927SAndroid Build Coastguard Worker
2290*61046927SAndroid Build Coastguard Worker if (stages[s].nir) {
2291*61046927SAndroid Build Coastguard Worker ralloc_free(stages[s].nir);
2292*61046927SAndroid Build Coastguard Worker stages[s].nir = NULL;
2293*61046927SAndroid Build Coastguard Worker }
2294*61046927SAndroid Build Coastguard Worker
2295*61046927SAndroid Build Coastguard Worker assert(pipeline->shaders[s] != NULL);
2296*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, pipeline->shaders[s]);
2297*61046927SAndroid Build Coastguard Worker pipeline->shaders[s] = NULL;
2298*61046927SAndroid Build Coastguard Worker }
2299*61046927SAndroid Build Coastguard Worker }
2300*61046927SAndroid Build Coastguard Worker }
2301*61046927SAndroid Build Coastguard Worker
2302*61046927SAndroid Build Coastguard Worker if (pipeline->base.flags & VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR)
2303*61046927SAndroid Build Coastguard Worker return VK_PIPELINE_COMPILE_REQUIRED;
2304*61046927SAndroid Build Coastguard Worker
2305*61046927SAndroid Build Coastguard Worker void *tmp_ctx = ralloc_context(NULL);
2306*61046927SAndroid Build Coastguard Worker
2307*61046927SAndroid Build Coastguard Worker result = anv_graphics_pipeline_load_nir(pipeline, cache, stages,
2308*61046927SAndroid Build Coastguard Worker tmp_ctx, link_optimize /* need_clone */);
2309*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
2310*61046927SAndroid Build Coastguard Worker goto fail;
2311*61046927SAndroid Build Coastguard Worker
2312*61046927SAndroid Build Coastguard Worker /* Retain shaders now if asked, this only applies to libraries */
2313*61046927SAndroid Build Coastguard Worker if (pipeline->base.type == ANV_PIPELINE_GRAPHICS_LIB && retain_shaders)
2314*61046927SAndroid Build Coastguard Worker anv_graphics_lib_retain_shaders(pipeline, stages, true /* will_compile */);
2315*61046927SAndroid Build Coastguard Worker
2316*61046927SAndroid Build Coastguard Worker /* The following steps will be executed for shaders we need to compile :
2317*61046927SAndroid Build Coastguard Worker *
2318*61046927SAndroid Build Coastguard Worker * - specified through VkGraphicsPipelineCreateInfo::pStages[]
2319*61046927SAndroid Build Coastguard Worker *
2320*61046927SAndroid Build Coastguard Worker * - or compiled from libraries with retained shaders (libraries
2321*61046927SAndroid Build Coastguard Worker * compiled with CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT) if the
2322*61046927SAndroid Build Coastguard Worker * pipeline has the CREATE_LINK_TIME_OPTIMIZATION_BIT flag.
2323*61046927SAndroid Build Coastguard Worker */
2324*61046927SAndroid Build Coastguard Worker
2325*61046927SAndroid Build Coastguard Worker /* Preprocess all NIR shaders. */
2326*61046927SAndroid Build Coastguard Worker for (int s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
2327*61046927SAndroid Build Coastguard Worker if (anv_graphics_pipeline_skip_shader_compile(pipeline, stages,
2328*61046927SAndroid Build Coastguard Worker link_optimize, s))
2329*61046927SAndroid Build Coastguard Worker continue;
2330*61046927SAndroid Build Coastguard Worker
2331*61046927SAndroid Build Coastguard Worker anv_stage_allocate_bind_map_tables(&pipeline->base, &stages[s], tmp_ctx);
2332*61046927SAndroid Build Coastguard Worker
2333*61046927SAndroid Build Coastguard Worker anv_pipeline_nir_preprocess(&pipeline->base, &stages[s]);
2334*61046927SAndroid Build Coastguard Worker }
2335*61046927SAndroid Build Coastguard Worker
2336*61046927SAndroid Build Coastguard Worker if (stages[MESA_SHADER_MESH].info && stages[MESA_SHADER_FRAGMENT].info) {
2337*61046927SAndroid Build Coastguard Worker anv_apply_per_prim_attr_wa(stages[MESA_SHADER_MESH].nir,
2338*61046927SAndroid Build Coastguard Worker stages[MESA_SHADER_FRAGMENT].nir,
2339*61046927SAndroid Build Coastguard Worker device,
2340*61046927SAndroid Build Coastguard Worker info);
2341*61046927SAndroid Build Coastguard Worker }
2342*61046927SAndroid Build Coastguard Worker
2343*61046927SAndroid Build Coastguard Worker /* Walk backwards to link */
2344*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *next_stage = NULL;
2345*61046927SAndroid Build Coastguard Worker for (int i = ARRAY_SIZE(graphics_shader_order) - 1; i >= 0; i--) {
2346*61046927SAndroid Build Coastguard Worker gl_shader_stage s = graphics_shader_order[i];
2347*61046927SAndroid Build Coastguard Worker if (anv_graphics_pipeline_skip_shader_compile(pipeline, stages,
2348*61046927SAndroid Build Coastguard Worker link_optimize, s))
2349*61046927SAndroid Build Coastguard Worker continue;
2350*61046927SAndroid Build Coastguard Worker
2351*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage = &stages[s];
2352*61046927SAndroid Build Coastguard Worker
2353*61046927SAndroid Build Coastguard Worker switch (s) {
2354*61046927SAndroid Build Coastguard Worker case MESA_SHADER_VERTEX:
2355*61046927SAndroid Build Coastguard Worker anv_pipeline_link_vs(compiler, stage, next_stage);
2356*61046927SAndroid Build Coastguard Worker break;
2357*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_CTRL:
2358*61046927SAndroid Build Coastguard Worker anv_pipeline_link_tcs(compiler, stage, next_stage);
2359*61046927SAndroid Build Coastguard Worker break;
2360*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_EVAL:
2361*61046927SAndroid Build Coastguard Worker anv_pipeline_link_tes(compiler, stage, next_stage);
2362*61046927SAndroid Build Coastguard Worker break;
2363*61046927SAndroid Build Coastguard Worker case MESA_SHADER_GEOMETRY:
2364*61046927SAndroid Build Coastguard Worker anv_pipeline_link_gs(compiler, stage, next_stage);
2365*61046927SAndroid Build Coastguard Worker break;
2366*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TASK:
2367*61046927SAndroid Build Coastguard Worker anv_pipeline_link_task(compiler, stage, next_stage);
2368*61046927SAndroid Build Coastguard Worker break;
2369*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MESH:
2370*61046927SAndroid Build Coastguard Worker anv_pipeline_link_mesh(compiler, stage, next_stage);
2371*61046927SAndroid Build Coastguard Worker break;
2372*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT:
2373*61046927SAndroid Build Coastguard Worker anv_pipeline_link_fs(compiler, stage, state->rp);
2374*61046927SAndroid Build Coastguard Worker break;
2375*61046927SAndroid Build Coastguard Worker default:
2376*61046927SAndroid Build Coastguard Worker unreachable("Invalid graphics shader stage");
2377*61046927SAndroid Build Coastguard Worker }
2378*61046927SAndroid Build Coastguard Worker
2379*61046927SAndroid Build Coastguard Worker next_stage = stage;
2380*61046927SAndroid Build Coastguard Worker }
2381*61046927SAndroid Build Coastguard Worker
2382*61046927SAndroid Build Coastguard Worker bool use_primitive_replication = false;
2383*61046927SAndroid Build Coastguard Worker if (devinfo->ver >= 12 && view_mask != 0) {
2384*61046927SAndroid Build Coastguard Worker /* For some pipelines HW Primitive Replication can be used instead of
2385*61046927SAndroid Build Coastguard Worker * instancing to implement Multiview. This depend on how viewIndex is
2386*61046927SAndroid Build Coastguard Worker * used in all the active shaders, so this check can't be done per
2387*61046927SAndroid Build Coastguard Worker * individual shaders.
2388*61046927SAndroid Build Coastguard Worker */
2389*61046927SAndroid Build Coastguard Worker nir_shader *shaders[ANV_GRAPHICS_SHADER_STAGE_COUNT] = {};
2390*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(shaders); s++)
2391*61046927SAndroid Build Coastguard Worker shaders[s] = stages[s].nir;
2392*61046927SAndroid Build Coastguard Worker
2393*61046927SAndroid Build Coastguard Worker use_primitive_replication =
2394*61046927SAndroid Build Coastguard Worker anv_check_for_primitive_replication(device,
2395*61046927SAndroid Build Coastguard Worker pipeline->base.active_stages,
2396*61046927SAndroid Build Coastguard Worker shaders, view_mask);
2397*61046927SAndroid Build Coastguard Worker }
2398*61046927SAndroid Build Coastguard Worker
2399*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *prev_stage = NULL;
2400*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(graphics_shader_order); i++) {
2401*61046927SAndroid Build Coastguard Worker gl_shader_stage s = graphics_shader_order[i];
2402*61046927SAndroid Build Coastguard Worker if (anv_graphics_pipeline_skip_shader_compile(pipeline, stages,
2403*61046927SAndroid Build Coastguard Worker link_optimize, s))
2404*61046927SAndroid Build Coastguard Worker continue;
2405*61046927SAndroid Build Coastguard Worker
2406*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage = &stages[s];
2407*61046927SAndroid Build Coastguard Worker
2408*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
2409*61046927SAndroid Build Coastguard Worker
2410*61046927SAndroid Build Coastguard Worker anv_pipeline_lower_nir(&pipeline->base, tmp_ctx, stage,
2411*61046927SAndroid Build Coastguard Worker &pipeline->base.layout, view_mask,
2412*61046927SAndroid Build Coastguard Worker use_primitive_replication);
2413*61046927SAndroid Build Coastguard Worker
2414*61046927SAndroid Build Coastguard Worker struct shader_info *cur_info = &stage->nir->info;
2415*61046927SAndroid Build Coastguard Worker
2416*61046927SAndroid Build Coastguard Worker if (prev_stage && compiler->nir_options[s]->unify_interfaces) {
2417*61046927SAndroid Build Coastguard Worker struct shader_info *prev_info = &prev_stage->nir->info;
2418*61046927SAndroid Build Coastguard Worker
2419*61046927SAndroid Build Coastguard Worker prev_info->outputs_written |= cur_info->inputs_read &
2420*61046927SAndroid Build Coastguard Worker ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
2421*61046927SAndroid Build Coastguard Worker cur_info->inputs_read |= prev_info->outputs_written &
2422*61046927SAndroid Build Coastguard Worker ~(VARYING_BIT_TESS_LEVEL_INNER | VARYING_BIT_TESS_LEVEL_OUTER);
2423*61046927SAndroid Build Coastguard Worker prev_info->patch_outputs_written |= cur_info->patch_inputs_read;
2424*61046927SAndroid Build Coastguard Worker cur_info->patch_inputs_read |= prev_info->patch_outputs_written;
2425*61046927SAndroid Build Coastguard Worker }
2426*61046927SAndroid Build Coastguard Worker
2427*61046927SAndroid Build Coastguard Worker anv_fixup_subgroup_size(device, cur_info);
2428*61046927SAndroid Build Coastguard Worker
2429*61046927SAndroid Build Coastguard Worker stage->feedback.duration += os_time_get_nano() - stage_start;
2430*61046927SAndroid Build Coastguard Worker
2431*61046927SAndroid Build Coastguard Worker prev_stage = stage;
2432*61046927SAndroid Build Coastguard Worker }
2433*61046927SAndroid Build Coastguard Worker
2434*61046927SAndroid Build Coastguard Worker /* In the case the platform can write the primitive variable shading rate
2435*61046927SAndroid Build Coastguard Worker * and KHR_fragment_shading_rate is enabled :
2436*61046927SAndroid Build Coastguard Worker * - there can be a fragment shader but we don't have it yet
2437*61046927SAndroid Build Coastguard Worker * - the fragment shader needs fragment shading rate
2438*61046927SAndroid Build Coastguard Worker *
2439*61046927SAndroid Build Coastguard Worker * figure out the last geometry stage that should write the primitive
2440*61046927SAndroid Build Coastguard Worker * shading rate, and ensure it is marked as used there. The backend will
2441*61046927SAndroid Build Coastguard Worker * write a default value if the shader doesn't actually write it.
2442*61046927SAndroid Build Coastguard Worker *
2443*61046927SAndroid Build Coastguard Worker * We iterate backwards in the stage and stop on the first shader that can
2444*61046927SAndroid Build Coastguard Worker * set the value.
2445*61046927SAndroid Build Coastguard Worker *
2446*61046927SAndroid Build Coastguard Worker * Don't apply this to MESH stages, as this is a per primitive thing.
2447*61046927SAndroid Build Coastguard Worker */
2448*61046927SAndroid Build Coastguard Worker if (devinfo->has_coarse_pixel_primitive_and_cb &&
2449*61046927SAndroid Build Coastguard Worker device->vk.enabled_extensions.KHR_fragment_shading_rate &&
2450*61046927SAndroid Build Coastguard Worker pipeline_has_coarse_pixel(state->dynamic, state->ms, state->fsr) &&
2451*61046927SAndroid Build Coastguard Worker (!stages[MESA_SHADER_FRAGMENT].info ||
2452*61046927SAndroid Build Coastguard Worker stages[MESA_SHADER_FRAGMENT].key.wm.coarse_pixel) &&
2453*61046927SAndroid Build Coastguard Worker stages[MESA_SHADER_MESH].nir == NULL) {
2454*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *last_psr = NULL;
2455*61046927SAndroid Build Coastguard Worker
2456*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(graphics_shader_order); i++) {
2457*61046927SAndroid Build Coastguard Worker gl_shader_stage s =
2458*61046927SAndroid Build Coastguard Worker graphics_shader_order[ARRAY_SIZE(graphics_shader_order) - i - 1];
2459*61046927SAndroid Build Coastguard Worker
2460*61046927SAndroid Build Coastguard Worker if (anv_graphics_pipeline_skip_shader_compile(pipeline, stages,
2461*61046927SAndroid Build Coastguard Worker link_optimize, s) ||
2462*61046927SAndroid Build Coastguard Worker !gl_shader_stage_can_set_fragment_shading_rate(s))
2463*61046927SAndroid Build Coastguard Worker continue;
2464*61046927SAndroid Build Coastguard Worker
2465*61046927SAndroid Build Coastguard Worker last_psr = &stages[s];
2466*61046927SAndroid Build Coastguard Worker break;
2467*61046927SAndroid Build Coastguard Worker }
2468*61046927SAndroid Build Coastguard Worker
2469*61046927SAndroid Build Coastguard Worker /* Only set primitive shading rate if there is a pre-rasterization
2470*61046927SAndroid Build Coastguard Worker * shader in this pipeline/pipeline-library.
2471*61046927SAndroid Build Coastguard Worker */
2472*61046927SAndroid Build Coastguard Worker if (last_psr)
2473*61046927SAndroid Build Coastguard Worker last_psr->nir->info.outputs_written |= VARYING_BIT_PRIMITIVE_SHADING_RATE;
2474*61046927SAndroid Build Coastguard Worker }
2475*61046927SAndroid Build Coastguard Worker
2476*61046927SAndroid Build Coastguard Worker prev_stage = NULL;
2477*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < ARRAY_SIZE(graphics_shader_order); i++) {
2478*61046927SAndroid Build Coastguard Worker gl_shader_stage s = graphics_shader_order[i];
2479*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage = &stages[s];
2480*61046927SAndroid Build Coastguard Worker
2481*61046927SAndroid Build Coastguard Worker if (anv_graphics_pipeline_skip_shader_compile(pipeline, stages, link_optimize, s))
2482*61046927SAndroid Build Coastguard Worker continue;
2483*61046927SAndroid Build Coastguard Worker
2484*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
2485*61046927SAndroid Build Coastguard Worker
2486*61046927SAndroid Build Coastguard Worker void *stage_ctx = ralloc_context(NULL);
2487*61046927SAndroid Build Coastguard Worker char *error_str = NULL;
2488*61046927SAndroid Build Coastguard Worker
2489*61046927SAndroid Build Coastguard Worker switch (s) {
2490*61046927SAndroid Build Coastguard Worker case MESA_SHADER_VERTEX:
2491*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_vs(compiler, stage_ctx, pipeline,
2492*61046927SAndroid Build Coastguard Worker stage, view_mask, &error_str);
2493*61046927SAndroid Build Coastguard Worker break;
2494*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_CTRL:
2495*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_tcs(compiler, stage_ctx, device,
2496*61046927SAndroid Build Coastguard Worker stage, prev_stage, &error_str);
2497*61046927SAndroid Build Coastguard Worker break;
2498*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TESS_EVAL:
2499*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_tes(compiler, stage_ctx, device,
2500*61046927SAndroid Build Coastguard Worker stage, prev_stage, &error_str);
2501*61046927SAndroid Build Coastguard Worker break;
2502*61046927SAndroid Build Coastguard Worker case MESA_SHADER_GEOMETRY:
2503*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_gs(compiler, stage_ctx, device,
2504*61046927SAndroid Build Coastguard Worker stage, prev_stage, &error_str);
2505*61046927SAndroid Build Coastguard Worker break;
2506*61046927SAndroid Build Coastguard Worker case MESA_SHADER_TASK:
2507*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_task(compiler, stage_ctx, device,
2508*61046927SAndroid Build Coastguard Worker stage, &error_str);
2509*61046927SAndroid Build Coastguard Worker break;
2510*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MESH:
2511*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_mesh(compiler, stage_ctx, device,
2512*61046927SAndroid Build Coastguard Worker stage, prev_stage, &error_str);
2513*61046927SAndroid Build Coastguard Worker break;
2514*61046927SAndroid Build Coastguard Worker case MESA_SHADER_FRAGMENT:
2515*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_fs(compiler, stage_ctx, device,
2516*61046927SAndroid Build Coastguard Worker stage, prev_stage, pipeline,
2517*61046927SAndroid Build Coastguard Worker view_mask, use_primitive_replication,
2518*61046927SAndroid Build Coastguard Worker &error_str);
2519*61046927SAndroid Build Coastguard Worker break;
2520*61046927SAndroid Build Coastguard Worker default:
2521*61046927SAndroid Build Coastguard Worker unreachable("Invalid graphics shader stage");
2522*61046927SAndroid Build Coastguard Worker }
2523*61046927SAndroid Build Coastguard Worker if (stage->code == NULL) {
2524*61046927SAndroid Build Coastguard Worker if (error_str)
2525*61046927SAndroid Build Coastguard Worker result = vk_errorf(pipeline, VK_ERROR_UNKNOWN, "%s", error_str);
2526*61046927SAndroid Build Coastguard Worker else
2527*61046927SAndroid Build Coastguard Worker result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2528*61046927SAndroid Build Coastguard Worker ralloc_free(stage_ctx);
2529*61046927SAndroid Build Coastguard Worker goto fail;
2530*61046927SAndroid Build Coastguard Worker }
2531*61046927SAndroid Build Coastguard Worker
2532*61046927SAndroid Build Coastguard Worker anv_nir_validate_push_layout(device->physical, &stage->prog_data.base,
2533*61046927SAndroid Build Coastguard Worker &stage->bind_map);
2534*61046927SAndroid Build Coastguard Worker
2535*61046927SAndroid Build Coastguard Worker struct anv_shader_upload_params upload_params = {
2536*61046927SAndroid Build Coastguard Worker .stage = s,
2537*61046927SAndroid Build Coastguard Worker .key_data = &stage->cache_key,
2538*61046927SAndroid Build Coastguard Worker .key_size = sizeof(stage->cache_key),
2539*61046927SAndroid Build Coastguard Worker .kernel_data = stage->code,
2540*61046927SAndroid Build Coastguard Worker .kernel_size = stage->prog_data.base.program_size,
2541*61046927SAndroid Build Coastguard Worker .prog_data = &stage->prog_data.base,
2542*61046927SAndroid Build Coastguard Worker .prog_data_size = brw_prog_data_size(s),
2543*61046927SAndroid Build Coastguard Worker .stats = stage->stats,
2544*61046927SAndroid Build Coastguard Worker .num_stats = stage->num_stats,
2545*61046927SAndroid Build Coastguard Worker .xfb_info = stage->nir->xfb_info,
2546*61046927SAndroid Build Coastguard Worker .bind_map = &stage->bind_map,
2547*61046927SAndroid Build Coastguard Worker .push_desc_info = &stage->push_desc_info,
2548*61046927SAndroid Build Coastguard Worker .dynamic_push_values = stage->dynamic_push_values,
2549*61046927SAndroid Build Coastguard Worker };
2550*61046927SAndroid Build Coastguard Worker
2551*61046927SAndroid Build Coastguard Worker stage->bin =
2552*61046927SAndroid Build Coastguard Worker anv_device_upload_kernel(device, cache, &upload_params);
2553*61046927SAndroid Build Coastguard Worker if (!stage->bin) {
2554*61046927SAndroid Build Coastguard Worker ralloc_free(stage_ctx);
2555*61046927SAndroid Build Coastguard Worker result = vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY);
2556*61046927SAndroid Build Coastguard Worker goto fail;
2557*61046927SAndroid Build Coastguard Worker }
2558*61046927SAndroid Build Coastguard Worker
2559*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executables(&pipeline->base, stage);
2560*61046927SAndroid Build Coastguard Worker pipeline->source_hashes[s] = stage->source_hash;
2561*61046927SAndroid Build Coastguard Worker pipeline->shaders[s] = stage->bin;
2562*61046927SAndroid Build Coastguard Worker
2563*61046927SAndroid Build Coastguard Worker ralloc_free(stage_ctx);
2564*61046927SAndroid Build Coastguard Worker
2565*61046927SAndroid Build Coastguard Worker stage->feedback.duration += os_time_get_nano() - stage_start;
2566*61046927SAndroid Build Coastguard Worker
2567*61046927SAndroid Build Coastguard Worker prev_stage = stage;
2568*61046927SAndroid Build Coastguard Worker }
2569*61046927SAndroid Build Coastguard Worker
2570*61046927SAndroid Build Coastguard Worker /* Finally add the imported shaders that were not compiled as part of this
2571*61046927SAndroid Build Coastguard Worker * step.
2572*61046927SAndroid Build Coastguard Worker */
2573*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
2574*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
2575*61046927SAndroid Build Coastguard Worker continue;
2576*61046927SAndroid Build Coastguard Worker
2577*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[s] != NULL)
2578*61046927SAndroid Build Coastguard Worker continue;
2579*61046927SAndroid Build Coastguard Worker
2580*61046927SAndroid Build Coastguard Worker /* We should have recompiled everything with link optimization. */
2581*61046927SAndroid Build Coastguard Worker assert(!link_optimize);
2582*61046927SAndroid Build Coastguard Worker
2583*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage = &stages[s];
2584*61046927SAndroid Build Coastguard Worker
2585*61046927SAndroid Build Coastguard Worker pipeline->source_hashes[s] = stage->source_hash;
2586*61046927SAndroid Build Coastguard Worker pipeline->shaders[s] = anv_shader_bin_ref(stage->imported.bin);
2587*61046927SAndroid Build Coastguard Worker }
2588*61046927SAndroid Build Coastguard Worker
2589*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_ctx);
2590*61046927SAndroid Build Coastguard Worker
2591*61046927SAndroid Build Coastguard Worker done:
2592*61046927SAndroid Build Coastguard Worker
2593*61046927SAndroid Build Coastguard Worker /* Write the feedback index into the pipeline */
2594*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
2595*61046927SAndroid Build Coastguard Worker if (!anv_pipeline_base_has_stage(pipeline, s))
2596*61046927SAndroid Build Coastguard Worker continue;
2597*61046927SAndroid Build Coastguard Worker
2598*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage = &stages[s];
2599*61046927SAndroid Build Coastguard Worker pipeline->feedback_index[s] = stage->feedback_idx;
2600*61046927SAndroid Build Coastguard Worker pipeline->robust_flags[s] = stage->robust_flags;
2601*61046927SAndroid Build Coastguard Worker
2602*61046927SAndroid Build Coastguard Worker anv_pipeline_account_shader(&pipeline->base, pipeline->shaders[s]);
2603*61046927SAndroid Build Coastguard Worker }
2604*61046927SAndroid Build Coastguard Worker
2605*61046927SAndroid Build Coastguard Worker pipeline_feedback->duration = os_time_get_nano() - pipeline_start;
2606*61046927SAndroid Build Coastguard Worker
2607*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[MESA_SHADER_FRAGMENT]) {
2608*61046927SAndroid Build Coastguard Worker pipeline->fragment_dynamic =
2609*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_stage_fragment_dynamic(
2610*61046927SAndroid Build Coastguard Worker &stages[MESA_SHADER_FRAGMENT]);
2611*61046927SAndroid Build Coastguard Worker }
2612*61046927SAndroid Build Coastguard Worker
2613*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2614*61046927SAndroid Build Coastguard Worker
2615*61046927SAndroid Build Coastguard Worker fail:
2616*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_ctx);
2617*61046927SAndroid Build Coastguard Worker
2618*61046927SAndroid Build Coastguard Worker for (unsigned s = 0; s < ARRAY_SIZE(pipeline->shaders); s++) {
2619*61046927SAndroid Build Coastguard Worker if (pipeline->shaders[s])
2620*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, pipeline->shaders[s]);
2621*61046927SAndroid Build Coastguard Worker }
2622*61046927SAndroid Build Coastguard Worker
2623*61046927SAndroid Build Coastguard Worker return result;
2624*61046927SAndroid Build Coastguard Worker }
2625*61046927SAndroid Build Coastguard Worker
2626*61046927SAndroid Build Coastguard Worker static VkResult
anv_pipeline_compile_cs(struct anv_compute_pipeline * pipeline,struct vk_pipeline_cache * cache,const VkComputePipelineCreateInfo * info)2627*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
2628*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
2629*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *info)
2630*61046927SAndroid Build Coastguard Worker {
2631*61046927SAndroid Build Coastguard Worker ASSERTED const VkPipelineShaderStageCreateInfo *sinfo = &info->stage;
2632*61046927SAndroid Build Coastguard Worker assert(sinfo->stage == VK_SHADER_STAGE_COMPUTE_BIT);
2633*61046927SAndroid Build Coastguard Worker
2634*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
2635*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
2636*61046927SAndroid Build Coastguard Worker };
2637*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
2638*61046927SAndroid Build Coastguard Worker
2639*61046927SAndroid Build Coastguard Worker struct anv_device *device = pipeline->base.device;
2640*61046927SAndroid Build Coastguard Worker const struct brw_compiler *compiler = device->physical->compiler;
2641*61046927SAndroid Build Coastguard Worker
2642*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage stage = {
2643*61046927SAndroid Build Coastguard Worker .stage = MESA_SHADER_COMPUTE,
2644*61046927SAndroid Build Coastguard Worker .info = &info->stage,
2645*61046927SAndroid Build Coastguard Worker .pipeline_flags = pipeline->base.flags,
2646*61046927SAndroid Build Coastguard Worker .pipeline_pNext = info->pNext,
2647*61046927SAndroid Build Coastguard Worker .cache_key = {
2648*61046927SAndroid Build Coastguard Worker .stage = MESA_SHADER_COMPUTE,
2649*61046927SAndroid Build Coastguard Worker },
2650*61046927SAndroid Build Coastguard Worker .feedback = {
2651*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
2652*61046927SAndroid Build Coastguard Worker },
2653*61046927SAndroid Build Coastguard Worker };
2654*61046927SAndroid Build Coastguard Worker anv_stage_write_shader_hash(&stage, device);
2655*61046927SAndroid Build Coastguard Worker
2656*61046927SAndroid Build Coastguard Worker populate_cs_prog_key(&stage, device);
2657*61046927SAndroid Build Coastguard Worker
2658*61046927SAndroid Build Coastguard Worker const bool skip_cache_lookup =
2659*61046927SAndroid Build Coastguard Worker (pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
2660*61046927SAndroid Build Coastguard Worker
2661*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_compute(pipeline, &stage, stage.cache_key.sha1);
2662*61046927SAndroid Build Coastguard Worker
2663*61046927SAndroid Build Coastguard Worker bool cache_hit = false;
2664*61046927SAndroid Build Coastguard Worker if (!skip_cache_lookup) {
2665*61046927SAndroid Build Coastguard Worker stage.bin = anv_device_search_for_kernel(device, cache,
2666*61046927SAndroid Build Coastguard Worker &stage.cache_key,
2667*61046927SAndroid Build Coastguard Worker sizeof(stage.cache_key),
2668*61046927SAndroid Build Coastguard Worker &cache_hit);
2669*61046927SAndroid Build Coastguard Worker }
2670*61046927SAndroid Build Coastguard Worker
2671*61046927SAndroid Build Coastguard Worker if (stage.bin == NULL &&
2672*61046927SAndroid Build Coastguard Worker (pipeline->base.flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT))
2673*61046927SAndroid Build Coastguard Worker return VK_PIPELINE_COMPILE_REQUIRED;
2674*61046927SAndroid Build Coastguard Worker
2675*61046927SAndroid Build Coastguard Worker void *mem_ctx = ralloc_context(NULL);
2676*61046927SAndroid Build Coastguard Worker if (stage.bin == NULL) {
2677*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
2678*61046927SAndroid Build Coastguard Worker
2679*61046927SAndroid Build Coastguard Worker anv_stage_allocate_bind_map_tables(&pipeline->base, &stage, mem_ctx);
2680*61046927SAndroid Build Coastguard Worker
2681*61046927SAndroid Build Coastguard Worker /* Set up a binding for the gl_NumWorkGroups */
2682*61046927SAndroid Build Coastguard Worker stage.bind_map.surface_count = 1;
2683*61046927SAndroid Build Coastguard Worker stage.bind_map.surface_to_descriptor[0] = (struct anv_pipeline_binding) {
2684*61046927SAndroid Build Coastguard Worker .set = ANV_DESCRIPTOR_SET_NUM_WORK_GROUPS,
2685*61046927SAndroid Build Coastguard Worker .binding = UINT32_MAX,
2686*61046927SAndroid Build Coastguard Worker };
2687*61046927SAndroid Build Coastguard Worker
2688*61046927SAndroid Build Coastguard Worker VkResult result = anv_pipeline_stage_get_nir(&pipeline->base, cache,
2689*61046927SAndroid Build Coastguard Worker mem_ctx, &stage);
2690*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2691*61046927SAndroid Build Coastguard Worker ralloc_free(mem_ctx);
2692*61046927SAndroid Build Coastguard Worker return result;
2693*61046927SAndroid Build Coastguard Worker }
2694*61046927SAndroid Build Coastguard Worker
2695*61046927SAndroid Build Coastguard Worker anv_pipeline_nir_preprocess(&pipeline->base, &stage);
2696*61046927SAndroid Build Coastguard Worker
2697*61046927SAndroid Build Coastguard Worker anv_pipeline_lower_nir(&pipeline->base, mem_ctx, &stage,
2698*61046927SAndroid Build Coastguard Worker &pipeline->base.layout, 0 /* view_mask */,
2699*61046927SAndroid Build Coastguard Worker false /* use_primitive_replication */);
2700*61046927SAndroid Build Coastguard Worker
2701*61046927SAndroid Build Coastguard Worker anv_fixup_subgroup_size(device, &stage.nir->info);
2702*61046927SAndroid Build Coastguard Worker
2703*61046927SAndroid Build Coastguard Worker stage.num_stats = 1;
2704*61046927SAndroid Build Coastguard Worker
2705*61046927SAndroid Build Coastguard Worker struct brw_compile_cs_params params = {
2706*61046927SAndroid Build Coastguard Worker .base = {
2707*61046927SAndroid Build Coastguard Worker .nir = stage.nir,
2708*61046927SAndroid Build Coastguard Worker .stats = stage.stats,
2709*61046927SAndroid Build Coastguard Worker .log_data = device,
2710*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
2711*61046927SAndroid Build Coastguard Worker .source_hash = stage.source_hash,
2712*61046927SAndroid Build Coastguard Worker },
2713*61046927SAndroid Build Coastguard Worker .key = &stage.key.cs,
2714*61046927SAndroid Build Coastguard Worker .prog_data = &stage.prog_data.cs,
2715*61046927SAndroid Build Coastguard Worker };
2716*61046927SAndroid Build Coastguard Worker
2717*61046927SAndroid Build Coastguard Worker stage.code = brw_compile_cs(compiler, ¶ms);
2718*61046927SAndroid Build Coastguard Worker if (stage.code == NULL) {
2719*61046927SAndroid Build Coastguard Worker VkResult result;
2720*61046927SAndroid Build Coastguard Worker
2721*61046927SAndroid Build Coastguard Worker if (params.base.error_str)
2722*61046927SAndroid Build Coastguard Worker result = vk_errorf(pipeline, VK_ERROR_UNKNOWN, "%s", params.base.error_str);
2723*61046927SAndroid Build Coastguard Worker else
2724*61046927SAndroid Build Coastguard Worker result = vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY);
2725*61046927SAndroid Build Coastguard Worker
2726*61046927SAndroid Build Coastguard Worker ralloc_free(mem_ctx);
2727*61046927SAndroid Build Coastguard Worker return result;
2728*61046927SAndroid Build Coastguard Worker }
2729*61046927SAndroid Build Coastguard Worker
2730*61046927SAndroid Build Coastguard Worker anv_nir_validate_push_layout(device->physical, &stage.prog_data.base,
2731*61046927SAndroid Build Coastguard Worker &stage.bind_map);
2732*61046927SAndroid Build Coastguard Worker
2733*61046927SAndroid Build Coastguard Worker if (!stage.prog_data.cs.uses_num_work_groups) {
2734*61046927SAndroid Build Coastguard Worker assert(stage.bind_map.surface_to_descriptor[0].set ==
2735*61046927SAndroid Build Coastguard Worker ANV_DESCRIPTOR_SET_NUM_WORK_GROUPS);
2736*61046927SAndroid Build Coastguard Worker stage.bind_map.surface_to_descriptor[0].set = ANV_DESCRIPTOR_SET_NULL;
2737*61046927SAndroid Build Coastguard Worker }
2738*61046927SAndroid Build Coastguard Worker
2739*61046927SAndroid Build Coastguard Worker struct anv_shader_upload_params upload_params = {
2740*61046927SAndroid Build Coastguard Worker .stage = MESA_SHADER_COMPUTE,
2741*61046927SAndroid Build Coastguard Worker .key_data = &stage.cache_key,
2742*61046927SAndroid Build Coastguard Worker .key_size = sizeof(stage.cache_key),
2743*61046927SAndroid Build Coastguard Worker .kernel_data = stage.code,
2744*61046927SAndroid Build Coastguard Worker .kernel_size = stage.prog_data.base.program_size,
2745*61046927SAndroid Build Coastguard Worker .prog_data = &stage.prog_data.base,
2746*61046927SAndroid Build Coastguard Worker .prog_data_size = sizeof(stage.prog_data.cs),
2747*61046927SAndroid Build Coastguard Worker .stats = stage.stats,
2748*61046927SAndroid Build Coastguard Worker .num_stats = stage.num_stats,
2749*61046927SAndroid Build Coastguard Worker .bind_map = &stage.bind_map,
2750*61046927SAndroid Build Coastguard Worker .push_desc_info = &stage.push_desc_info,
2751*61046927SAndroid Build Coastguard Worker .dynamic_push_values = stage.dynamic_push_values,
2752*61046927SAndroid Build Coastguard Worker };
2753*61046927SAndroid Build Coastguard Worker
2754*61046927SAndroid Build Coastguard Worker stage.bin = anv_device_upload_kernel(device, cache, &upload_params);
2755*61046927SAndroid Build Coastguard Worker if (!stage.bin) {
2756*61046927SAndroid Build Coastguard Worker ralloc_free(mem_ctx);
2757*61046927SAndroid Build Coastguard Worker return vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY);
2758*61046927SAndroid Build Coastguard Worker }
2759*61046927SAndroid Build Coastguard Worker
2760*61046927SAndroid Build Coastguard Worker stage.feedback.duration = os_time_get_nano() - stage_start;
2761*61046927SAndroid Build Coastguard Worker }
2762*61046927SAndroid Build Coastguard Worker
2763*61046927SAndroid Build Coastguard Worker anv_pipeline_account_shader(&pipeline->base, stage.bin);
2764*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executables(&pipeline->base, &stage);
2765*61046927SAndroid Build Coastguard Worker pipeline->source_hash = stage.source_hash;
2766*61046927SAndroid Build Coastguard Worker
2767*61046927SAndroid Build Coastguard Worker ralloc_free(mem_ctx);
2768*61046927SAndroid Build Coastguard Worker
2769*61046927SAndroid Build Coastguard Worker if (cache_hit) {
2770*61046927SAndroid Build Coastguard Worker stage.feedback.flags |=
2771*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
2772*61046927SAndroid Build Coastguard Worker pipeline_feedback.flags |=
2773*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
2774*61046927SAndroid Build Coastguard Worker }
2775*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
2776*61046927SAndroid Build Coastguard Worker
2777*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedbackCreateInfo *create_feedback =
2778*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
2779*61046927SAndroid Build Coastguard Worker if (create_feedback) {
2780*61046927SAndroid Build Coastguard Worker *create_feedback->pPipelineCreationFeedback = pipeline_feedback;
2781*61046927SAndroid Build Coastguard Worker
2782*61046927SAndroid Build Coastguard Worker if (create_feedback->pipelineStageCreationFeedbackCount) {
2783*61046927SAndroid Build Coastguard Worker assert(create_feedback->pipelineStageCreationFeedbackCount == 1);
2784*61046927SAndroid Build Coastguard Worker create_feedback->pPipelineStageCreationFeedbacks[0] = stage.feedback;
2785*61046927SAndroid Build Coastguard Worker }
2786*61046927SAndroid Build Coastguard Worker }
2787*61046927SAndroid Build Coastguard Worker
2788*61046927SAndroid Build Coastguard Worker pipeline->cs = stage.bin;
2789*61046927SAndroid Build Coastguard Worker
2790*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
2791*61046927SAndroid Build Coastguard Worker }
2792*61046927SAndroid Build Coastguard Worker
2793*61046927SAndroid Build Coastguard Worker static VkResult
anv_compute_pipeline_create(struct anv_device * device,struct vk_pipeline_cache * cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)2794*61046927SAndroid Build Coastguard Worker anv_compute_pipeline_create(struct anv_device *device,
2795*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
2796*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo *pCreateInfo,
2797*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
2798*61046927SAndroid Build Coastguard Worker VkPipeline *pPipeline)
2799*61046927SAndroid Build Coastguard Worker {
2800*61046927SAndroid Build Coastguard Worker struct anv_compute_pipeline *pipeline;
2801*61046927SAndroid Build Coastguard Worker VkResult result;
2802*61046927SAndroid Build Coastguard Worker
2803*61046927SAndroid Build Coastguard Worker assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);
2804*61046927SAndroid Build Coastguard Worker
2805*61046927SAndroid Build Coastguard Worker pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
2806*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2807*61046927SAndroid Build Coastguard Worker if (pipeline == NULL)
2808*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2809*61046927SAndroid Build Coastguard Worker
2810*61046927SAndroid Build Coastguard Worker result = anv_pipeline_init(&pipeline->base, device,
2811*61046927SAndroid Build Coastguard Worker ANV_PIPELINE_COMPUTE,
2812*61046927SAndroid Build Coastguard Worker vk_compute_pipeline_create_flags(pCreateInfo),
2813*61046927SAndroid Build Coastguard Worker pAllocator);
2814*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2815*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
2816*61046927SAndroid Build Coastguard Worker return result;
2817*61046927SAndroid Build Coastguard Worker }
2818*61046927SAndroid Build Coastguard Worker
2819*61046927SAndroid Build Coastguard Worker
2820*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
2821*61046927SAndroid Build Coastguard Worker anv_pipeline_init_layout(&pipeline->base, pipeline_layout);
2822*61046927SAndroid Build Coastguard Worker
2823*61046927SAndroid Build Coastguard Worker pipeline->base.active_stages = VK_SHADER_STAGE_COMPUTE_BIT;
2824*61046927SAndroid Build Coastguard Worker
2825*61046927SAndroid Build Coastguard Worker anv_batch_set_storage(&pipeline->base.batch, ANV_NULL_ADDRESS,
2826*61046927SAndroid Build Coastguard Worker pipeline->batch_data, sizeof(pipeline->batch_data));
2827*61046927SAndroid Build Coastguard Worker
2828*61046927SAndroid Build Coastguard Worker result = anv_pipeline_compile_cs(pipeline, cache, pCreateInfo);
2829*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
2830*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(&pipeline->base, device);
2831*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
2832*61046927SAndroid Build Coastguard Worker return result;
2833*61046927SAndroid Build Coastguard Worker }
2834*61046927SAndroid Build Coastguard Worker
2835*61046927SAndroid Build Coastguard Worker anv_genX(device->info, compute_pipeline_emit)(pipeline);
2836*61046927SAndroid Build Coastguard Worker
2837*61046927SAndroid Build Coastguard Worker ANV_RMV(compute_pipeline_create, device, pipeline, false);
2838*61046927SAndroid Build Coastguard Worker
2839*61046927SAndroid Build Coastguard Worker *pPipeline = anv_pipeline_to_handle(&pipeline->base);
2840*61046927SAndroid Build Coastguard Worker
2841*61046927SAndroid Build Coastguard Worker return pipeline->base.batch.status;
2842*61046927SAndroid Build Coastguard Worker }
2843*61046927SAndroid Build Coastguard Worker
anv_CreateComputePipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)2844*61046927SAndroid Build Coastguard Worker VkResult anv_CreateComputePipelines(
2845*61046927SAndroid Build Coastguard Worker VkDevice _device,
2846*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
2847*61046927SAndroid Build Coastguard Worker uint32_t count,
2848*61046927SAndroid Build Coastguard Worker const VkComputePipelineCreateInfo* pCreateInfos,
2849*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator,
2850*61046927SAndroid Build Coastguard Worker VkPipeline* pPipelines)
2851*61046927SAndroid Build Coastguard Worker {
2852*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_device, device, _device);
2853*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(vk_pipeline_cache, pipeline_cache, pipelineCache);
2854*61046927SAndroid Build Coastguard Worker
2855*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
2856*61046927SAndroid Build Coastguard Worker
2857*61046927SAndroid Build Coastguard Worker unsigned i;
2858*61046927SAndroid Build Coastguard Worker for (i = 0; i < count; i++) {
2859*61046927SAndroid Build Coastguard Worker const VkPipelineCreateFlags2KHR flags =
2860*61046927SAndroid Build Coastguard Worker vk_compute_pipeline_create_flags(&pCreateInfos[i]);
2861*61046927SAndroid Build Coastguard Worker VkResult res = anv_compute_pipeline_create(device, pipeline_cache,
2862*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
2863*61046927SAndroid Build Coastguard Worker pAllocator, &pPipelines[i]);
2864*61046927SAndroid Build Coastguard Worker
2865*61046927SAndroid Build Coastguard Worker if (res != VK_SUCCESS) {
2866*61046927SAndroid Build Coastguard Worker result = res;
2867*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR)
2868*61046927SAndroid Build Coastguard Worker break;
2869*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
2870*61046927SAndroid Build Coastguard Worker }
2871*61046927SAndroid Build Coastguard Worker }
2872*61046927SAndroid Build Coastguard Worker
2873*61046927SAndroid Build Coastguard Worker for (; i < count; i++)
2874*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
2875*61046927SAndroid Build Coastguard Worker
2876*61046927SAndroid Build Coastguard Worker return result;
2877*61046927SAndroid Build Coastguard Worker }
2878*61046927SAndroid Build Coastguard Worker
2879*61046927SAndroid Build Coastguard Worker /**
2880*61046927SAndroid Build Coastguard Worker * Calculate the desired L3 partitioning based on the current state of the
2881*61046927SAndroid Build Coastguard Worker * pipeline. For now this simply returns the conservative defaults calculated
2882*61046927SAndroid Build Coastguard Worker * by get_default_l3_weights(), but we could probably do better by gathering
2883*61046927SAndroid Build Coastguard Worker * more statistics from the pipeline state (e.g. guess of expected URB usage
2884*61046927SAndroid Build Coastguard Worker * and bound surfaces), or by using feed-back from performance counters.
2885*61046927SAndroid Build Coastguard Worker */
2886*61046927SAndroid Build Coastguard Worker void
anv_pipeline_setup_l3_config(struct anv_pipeline * pipeline,bool needs_slm)2887*61046927SAndroid Build Coastguard Worker anv_pipeline_setup_l3_config(struct anv_pipeline *pipeline, bool needs_slm)
2888*61046927SAndroid Build Coastguard Worker {
2889*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = pipeline->device->info;
2890*61046927SAndroid Build Coastguard Worker
2891*61046927SAndroid Build Coastguard Worker const struct intel_l3_weights w =
2892*61046927SAndroid Build Coastguard Worker intel_get_default_l3_weights(devinfo, true, needs_slm);
2893*61046927SAndroid Build Coastguard Worker
2894*61046927SAndroid Build Coastguard Worker pipeline->l3_config = intel_get_l3_config(devinfo, w);
2895*61046927SAndroid Build Coastguard Worker }
2896*61046927SAndroid Build Coastguard Worker
2897*61046927SAndroid Build Coastguard Worker static uint32_t
get_vs_input_elements(const struct brw_vs_prog_data * vs_prog_data)2898*61046927SAndroid Build Coastguard Worker get_vs_input_elements(const struct brw_vs_prog_data *vs_prog_data)
2899*61046927SAndroid Build Coastguard Worker {
2900*61046927SAndroid Build Coastguard Worker /* Pull inputs_read out of the VS prog data */
2901*61046927SAndroid Build Coastguard Worker const uint64_t inputs_read = vs_prog_data->inputs_read;
2902*61046927SAndroid Build Coastguard Worker const uint64_t double_inputs_read =
2903*61046927SAndroid Build Coastguard Worker vs_prog_data->double_inputs_read & inputs_read;
2904*61046927SAndroid Build Coastguard Worker assert((inputs_read & ((1 << VERT_ATTRIB_GENERIC0) - 1)) == 0);
2905*61046927SAndroid Build Coastguard Worker const uint32_t elements = inputs_read >> VERT_ATTRIB_GENERIC0;
2906*61046927SAndroid Build Coastguard Worker const uint32_t elements_double = double_inputs_read >> VERT_ATTRIB_GENERIC0;
2907*61046927SAndroid Build Coastguard Worker
2908*61046927SAndroid Build Coastguard Worker return __builtin_popcount(elements) -
2909*61046927SAndroid Build Coastguard Worker __builtin_popcount(elements_double) / 2;
2910*61046927SAndroid Build Coastguard Worker }
2911*61046927SAndroid Build Coastguard Worker
2912*61046927SAndroid Build Coastguard Worker static void
anv_graphics_pipeline_emit(struct anv_graphics_pipeline * pipeline,const struct vk_graphics_pipeline_state * state)2913*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_emit(struct anv_graphics_pipeline *pipeline,
2914*61046927SAndroid Build Coastguard Worker const struct vk_graphics_pipeline_state *state)
2915*61046927SAndroid Build Coastguard Worker {
2916*61046927SAndroid Build Coastguard Worker pipeline->view_mask = state->rp->view_mask;
2917*61046927SAndroid Build Coastguard Worker
2918*61046927SAndroid Build Coastguard Worker anv_pipeline_setup_l3_config(&pipeline->base.base, false);
2919*61046927SAndroid Build Coastguard Worker
2920*61046927SAndroid Build Coastguard Worker if (anv_pipeline_is_primitive(pipeline)) {
2921*61046927SAndroid Build Coastguard Worker const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline);
2922*61046927SAndroid Build Coastguard Worker
2923*61046927SAndroid Build Coastguard Worker /* The total number of vertex elements we need to program. We might need
2924*61046927SAndroid Build Coastguard Worker * a couple more to implement some of the draw parameters.
2925*61046927SAndroid Build Coastguard Worker */
2926*61046927SAndroid Build Coastguard Worker pipeline->svgs_count =
2927*61046927SAndroid Build Coastguard Worker (vs_prog_data->uses_vertexid ||
2928*61046927SAndroid Build Coastguard Worker vs_prog_data->uses_instanceid ||
2929*61046927SAndroid Build Coastguard Worker vs_prog_data->uses_firstvertex ||
2930*61046927SAndroid Build Coastguard Worker vs_prog_data->uses_baseinstance) + vs_prog_data->uses_drawid;
2931*61046927SAndroid Build Coastguard Worker
2932*61046927SAndroid Build Coastguard Worker pipeline->vs_input_elements = get_vs_input_elements(vs_prog_data);
2933*61046927SAndroid Build Coastguard Worker
2934*61046927SAndroid Build Coastguard Worker pipeline->vertex_input_elems =
2935*61046927SAndroid Build Coastguard Worker (BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_VI) ?
2936*61046927SAndroid Build Coastguard Worker 0 : pipeline->vs_input_elements) + pipeline->svgs_count;
2937*61046927SAndroid Build Coastguard Worker
2938*61046927SAndroid Build Coastguard Worker /* Our implementation of VK_KHR_multiview uses instancing to draw the
2939*61046927SAndroid Build Coastguard Worker * different views when primitive replication cannot be used. If the
2940*61046927SAndroid Build Coastguard Worker * client asks for instancing, we need to multiply by the client's
2941*61046927SAndroid Build Coastguard Worker * instance count at draw time and instance divisor in the vertex
2942*61046927SAndroid Build Coastguard Worker * bindings by the number of views ensure that we repeat the client's
2943*61046927SAndroid Build Coastguard Worker * per-instance data once for each view.
2944*61046927SAndroid Build Coastguard Worker */
2945*61046927SAndroid Build Coastguard Worker const bool uses_primitive_replication =
2946*61046927SAndroid Build Coastguard Worker anv_pipeline_get_last_vue_prog_data(pipeline)->vue_map.num_pos_slots > 1;
2947*61046927SAndroid Build Coastguard Worker pipeline->instance_multiplier = 1;
2948*61046927SAndroid Build Coastguard Worker if (pipeline->view_mask && !uses_primitive_replication)
2949*61046927SAndroid Build Coastguard Worker pipeline->instance_multiplier = util_bitcount(pipeline->view_mask);
2950*61046927SAndroid Build Coastguard Worker } else {
2951*61046927SAndroid Build Coastguard Worker assert(anv_pipeline_is_mesh(pipeline));
2952*61046927SAndroid Build Coastguard Worker /* TODO(mesh): Mesh vs. Multiview with Instancing. */
2953*61046927SAndroid Build Coastguard Worker }
2954*61046927SAndroid Build Coastguard Worker
2955*61046927SAndroid Build Coastguard Worker
2956*61046927SAndroid Build Coastguard Worker pipeline->dynamic_patch_control_points =
2957*61046927SAndroid Build Coastguard Worker anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_CTRL) &&
2958*61046927SAndroid Build Coastguard Worker BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS) &&
2959*61046927SAndroid Build Coastguard Worker (pipeline->base.shaders[MESA_SHADER_TESS_CTRL]->dynamic_push_values &
2960*61046927SAndroid Build Coastguard Worker ANV_DYNAMIC_PUSH_INPUT_VERTICES);
2961*61046927SAndroid Build Coastguard Worker
2962*61046927SAndroid Build Coastguard Worker if (pipeline->base.shaders[MESA_SHADER_FRAGMENT] && state->ms) {
2963*61046927SAndroid Build Coastguard Worker pipeline->sample_shading_enable = state->ms->sample_shading_enable;
2964*61046927SAndroid Build Coastguard Worker pipeline->min_sample_shading = state->ms->min_sample_shading;
2965*61046927SAndroid Build Coastguard Worker }
2966*61046927SAndroid Build Coastguard Worker
2967*61046927SAndroid Build Coastguard Worker const struct anv_device *device = pipeline->base.base.device;
2968*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = device->info;
2969*61046927SAndroid Build Coastguard Worker anv_genX(devinfo, graphics_pipeline_emit)(pipeline, state);
2970*61046927SAndroid Build Coastguard Worker }
2971*61046927SAndroid Build Coastguard Worker
2972*61046927SAndroid Build Coastguard Worker static void
anv_graphics_pipeline_import_layout(struct anv_graphics_base_pipeline * pipeline,struct anv_pipeline_sets_layout * layout)2973*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_import_layout(struct anv_graphics_base_pipeline *pipeline,
2974*61046927SAndroid Build Coastguard Worker struct anv_pipeline_sets_layout *layout)
2975*61046927SAndroid Build Coastguard Worker {
2976*61046927SAndroid Build Coastguard Worker pipeline->base.layout.independent_sets |= layout->independent_sets;
2977*61046927SAndroid Build Coastguard Worker
2978*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < layout->num_sets; s++) {
2979*61046927SAndroid Build Coastguard Worker if (layout->set[s].layout == NULL)
2980*61046927SAndroid Build Coastguard Worker continue;
2981*61046927SAndroid Build Coastguard Worker
2982*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_add(&pipeline->base.layout, s,
2983*61046927SAndroid Build Coastguard Worker layout->set[s].layout);
2984*61046927SAndroid Build Coastguard Worker }
2985*61046927SAndroid Build Coastguard Worker }
2986*61046927SAndroid Build Coastguard Worker
2987*61046927SAndroid Build Coastguard Worker static void
anv_graphics_pipeline_import_lib(struct anv_graphics_base_pipeline * pipeline,bool link_optimize,bool retain_shaders,struct anv_pipeline_stage * stages,struct anv_graphics_lib_pipeline * lib)2988*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_import_lib(struct anv_graphics_base_pipeline *pipeline,
2989*61046927SAndroid Build Coastguard Worker bool link_optimize,
2990*61046927SAndroid Build Coastguard Worker bool retain_shaders,
2991*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
2992*61046927SAndroid Build Coastguard Worker struct anv_graphics_lib_pipeline *lib)
2993*61046927SAndroid Build Coastguard Worker {
2994*61046927SAndroid Build Coastguard Worker struct anv_pipeline_sets_layout *lib_layout =
2995*61046927SAndroid Build Coastguard Worker &lib->base.base.layout;
2996*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_import_layout(pipeline, lib_layout);
2997*61046927SAndroid Build Coastguard Worker
2998*61046927SAndroid Build Coastguard Worker /* We can't have shaders specified twice through libraries. */
2999*61046927SAndroid Build Coastguard Worker assert((pipeline->base.active_stages & lib->base.base.active_stages) == 0);
3000*61046927SAndroid Build Coastguard Worker
3001*61046927SAndroid Build Coastguard Worker /* VK_EXT_graphics_pipeline_library:
3002*61046927SAndroid Build Coastguard Worker *
3003*61046927SAndroid Build Coastguard Worker * "To perform link time optimizations,
3004*61046927SAndroid Build Coastguard Worker * VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT must
3005*61046927SAndroid Build Coastguard Worker * be specified on all pipeline libraries that are being linked
3006*61046927SAndroid Build Coastguard Worker * together. Implementations should retain any additional information
3007*61046927SAndroid Build Coastguard Worker * needed to perform optimizations at the final link step when this bit
3008*61046927SAndroid Build Coastguard Worker * is present."
3009*61046927SAndroid Build Coastguard Worker */
3010*61046927SAndroid Build Coastguard Worker assert(!link_optimize || lib->retain_shaders);
3011*61046927SAndroid Build Coastguard Worker
3012*61046927SAndroid Build Coastguard Worker pipeline->base.active_stages |= lib->base.base.active_stages;
3013*61046927SAndroid Build Coastguard Worker
3014*61046927SAndroid Build Coastguard Worker /* Propagate the fragment dynamic flag, unless we're doing link
3015*61046927SAndroid Build Coastguard Worker * optimization, in that case we'll have all the state information and this
3016*61046927SAndroid Build Coastguard Worker * will never be dynamic.
3017*61046927SAndroid Build Coastguard Worker */
3018*61046927SAndroid Build Coastguard Worker if (!link_optimize) {
3019*61046927SAndroid Build Coastguard Worker if (lib->base.fragment_dynamic) {
3020*61046927SAndroid Build Coastguard Worker assert(lib->base.base.active_stages & VK_SHADER_STAGE_FRAGMENT_BIT);
3021*61046927SAndroid Build Coastguard Worker pipeline->fragment_dynamic = true;
3022*61046927SAndroid Build Coastguard Worker }
3023*61046927SAndroid Build Coastguard Worker }
3024*61046927SAndroid Build Coastguard Worker
3025*61046927SAndroid Build Coastguard Worker uint32_t shader_count = anv_graphics_pipeline_imported_shader_count(stages);
3026*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < ARRAY_SIZE(lib->base.shaders); s++) {
3027*61046927SAndroid Build Coastguard Worker if (lib->base.shaders[s] == NULL)
3028*61046927SAndroid Build Coastguard Worker continue;
3029*61046927SAndroid Build Coastguard Worker
3030*61046927SAndroid Build Coastguard Worker stages[s].stage = s;
3031*61046927SAndroid Build Coastguard Worker stages[s].feedback_idx = shader_count + lib->base.feedback_index[s];
3032*61046927SAndroid Build Coastguard Worker stages[s].robust_flags = lib->base.robust_flags[s];
3033*61046927SAndroid Build Coastguard Worker
3034*61046927SAndroid Build Coastguard Worker /* Always import the shader sha1, this will be used for cache lookup. */
3035*61046927SAndroid Build Coastguard Worker memcpy(stages[s].shader_sha1, lib->retained_shaders[s].shader_sha1,
3036*61046927SAndroid Build Coastguard Worker sizeof(stages[s].shader_sha1));
3037*61046927SAndroid Build Coastguard Worker stages[s].source_hash = lib->base.source_hashes[s];
3038*61046927SAndroid Build Coastguard Worker
3039*61046927SAndroid Build Coastguard Worker stages[s].subgroup_size_type = lib->retained_shaders[s].subgroup_size_type;
3040*61046927SAndroid Build Coastguard Worker stages[s].imported.nir = lib->retained_shaders[s].nir;
3041*61046927SAndroid Build Coastguard Worker stages[s].imported.bin = lib->base.shaders[s];
3042*61046927SAndroid Build Coastguard Worker }
3043*61046927SAndroid Build Coastguard Worker
3044*61046927SAndroid Build Coastguard Worker /* When not link optimizing, import the executables (shader descriptions
3045*61046927SAndroid Build Coastguard Worker * for VK_KHR_pipeline_executable_properties). With link optimization there
3046*61046927SAndroid Build Coastguard Worker * is a chance it'll produce different binaries, so we'll add the optimized
3047*61046927SAndroid Build Coastguard Worker * version later.
3048*61046927SAndroid Build Coastguard Worker */
3049*61046927SAndroid Build Coastguard Worker if (!link_optimize) {
3050*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&lib->base.base.executables,
3051*61046927SAndroid Build Coastguard Worker struct anv_pipeline_executable, exe) {
3052*61046927SAndroid Build Coastguard Worker util_dynarray_append(&pipeline->base.executables,
3053*61046927SAndroid Build Coastguard Worker struct anv_pipeline_executable, *exe);
3054*61046927SAndroid Build Coastguard Worker }
3055*61046927SAndroid Build Coastguard Worker }
3056*61046927SAndroid Build Coastguard Worker }
3057*61046927SAndroid Build Coastguard Worker
3058*61046927SAndroid Build Coastguard Worker static void
anv_graphics_lib_validate_shaders(struct anv_graphics_lib_pipeline * lib,bool retained_shaders)3059*61046927SAndroid Build Coastguard Worker anv_graphics_lib_validate_shaders(struct anv_graphics_lib_pipeline *lib,
3060*61046927SAndroid Build Coastguard Worker bool retained_shaders)
3061*61046927SAndroid Build Coastguard Worker {
3062*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < ARRAY_SIZE(lib->retained_shaders); s++) {
3063*61046927SAndroid Build Coastguard Worker if (anv_pipeline_base_has_stage(&lib->base, s)) {
3064*61046927SAndroid Build Coastguard Worker assert(!retained_shaders || lib->retained_shaders[s].nir != NULL);
3065*61046927SAndroid Build Coastguard Worker assert(lib->base.shaders[s] != NULL);
3066*61046927SAndroid Build Coastguard Worker }
3067*61046927SAndroid Build Coastguard Worker }
3068*61046927SAndroid Build Coastguard Worker }
3069*61046927SAndroid Build Coastguard Worker
3070*61046927SAndroid Build Coastguard Worker static VkResult
anv_graphics_lib_pipeline_create(struct anv_device * device,struct vk_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)3071*61046927SAndroid Build Coastguard Worker anv_graphics_lib_pipeline_create(struct anv_device *device,
3072*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
3073*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
3074*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
3075*61046927SAndroid Build Coastguard Worker VkPipeline *pPipeline)
3076*61046927SAndroid Build Coastguard Worker {
3077*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage stages[ANV_GRAPHICS_SHADER_STAGE_COUNT] = {};
3078*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
3079*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
3080*61046927SAndroid Build Coastguard Worker };
3081*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
3082*61046927SAndroid Build Coastguard Worker
3083*61046927SAndroid Build Coastguard Worker struct anv_graphics_lib_pipeline *pipeline;
3084*61046927SAndroid Build Coastguard Worker VkResult result;
3085*61046927SAndroid Build Coastguard Worker
3086*61046927SAndroid Build Coastguard Worker const VkPipelineCreateFlags2KHR flags =
3087*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_create_flags(pCreateInfo);
3088*61046927SAndroid Build Coastguard Worker assert(flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR);
3089*61046927SAndroid Build Coastguard Worker
3090*61046927SAndroid Build Coastguard Worker const VkPipelineLibraryCreateInfoKHR *libs_info =
3091*61046927SAndroid Build Coastguard Worker vk_find_struct_const(pCreateInfo->pNext,
3092*61046927SAndroid Build Coastguard Worker PIPELINE_LIBRARY_CREATE_INFO_KHR);
3093*61046927SAndroid Build Coastguard Worker
3094*61046927SAndroid Build Coastguard Worker pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
3095*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
3096*61046927SAndroid Build Coastguard Worker if (pipeline == NULL)
3097*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
3098*61046927SAndroid Build Coastguard Worker
3099*61046927SAndroid Build Coastguard Worker result = anv_pipeline_init(&pipeline->base.base, device,
3100*61046927SAndroid Build Coastguard Worker ANV_PIPELINE_GRAPHICS_LIB, flags,
3101*61046927SAndroid Build Coastguard Worker pAllocator);
3102*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3103*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
3104*61046927SAndroid Build Coastguard Worker if (result == VK_PIPELINE_COMPILE_REQUIRED)
3105*61046927SAndroid Build Coastguard Worker *pPipeline = VK_NULL_HANDLE;
3106*61046927SAndroid Build Coastguard Worker return result;
3107*61046927SAndroid Build Coastguard Worker }
3108*61046927SAndroid Build Coastguard Worker
3109*61046927SAndroid Build Coastguard Worker /* Capture the retain state before we compile/load any shader. */
3110*61046927SAndroid Build Coastguard Worker pipeline->retain_shaders =
3111*61046927SAndroid Build Coastguard Worker (flags & VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT) != 0;
3112*61046927SAndroid Build Coastguard Worker
3113*61046927SAndroid Build Coastguard Worker /* If we have libraries, import them first. */
3114*61046927SAndroid Build Coastguard Worker if (libs_info) {
3115*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < libs_info->libraryCount; i++) {
3116*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline_lib, libs_info->pLibraries[i]);
3117*61046927SAndroid Build Coastguard Worker struct anv_graphics_lib_pipeline *gfx_pipeline_lib =
3118*61046927SAndroid Build Coastguard Worker anv_pipeline_to_graphics_lib(pipeline_lib);
3119*61046927SAndroid Build Coastguard Worker
3120*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_state_merge(&pipeline->state, &gfx_pipeline_lib->state);
3121*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_import_lib(&pipeline->base,
3122*61046927SAndroid Build Coastguard Worker false /* link_optimize */,
3123*61046927SAndroid Build Coastguard Worker pipeline->retain_shaders,
3124*61046927SAndroid Build Coastguard Worker stages, gfx_pipeline_lib);
3125*61046927SAndroid Build Coastguard Worker }
3126*61046927SAndroid Build Coastguard Worker }
3127*61046927SAndroid Build Coastguard Worker
3128*61046927SAndroid Build Coastguard Worker result = vk_graphics_pipeline_state_fill(&device->vk,
3129*61046927SAndroid Build Coastguard Worker &pipeline->state, pCreateInfo,
3130*61046927SAndroid Build Coastguard Worker NULL /* driver_rp */,
3131*61046927SAndroid Build Coastguard Worker 0 /* driver_rp_flags */,
3132*61046927SAndroid Build Coastguard Worker &pipeline->all_state, NULL, 0, NULL);
3133*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3134*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(&pipeline->base.base, device);
3135*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
3136*61046927SAndroid Build Coastguard Worker return result;
3137*61046927SAndroid Build Coastguard Worker }
3138*61046927SAndroid Build Coastguard Worker
3139*61046927SAndroid Build Coastguard Worker pipeline->base.base.active_stages = pipeline->state.shader_stages;
3140*61046927SAndroid Build Coastguard Worker
3141*61046927SAndroid Build Coastguard Worker /* After we've imported all the libraries' layouts, import the pipeline
3142*61046927SAndroid Build Coastguard Worker * layout and hash the whole lot.
3143*61046927SAndroid Build Coastguard Worker */
3144*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
3145*61046927SAndroid Build Coastguard Worker if (pipeline_layout != NULL) {
3146*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_import_layout(&pipeline->base,
3147*61046927SAndroid Build Coastguard Worker &pipeline_layout->sets_layout);
3148*61046927SAndroid Build Coastguard Worker }
3149*61046927SAndroid Build Coastguard Worker
3150*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_hash(&pipeline->base.base.layout);
3151*61046927SAndroid Build Coastguard Worker
3152*61046927SAndroid Build Coastguard Worker /* Compile shaders. We can skip this if there are no active stage in that
3153*61046927SAndroid Build Coastguard Worker * pipeline.
3154*61046927SAndroid Build Coastguard Worker */
3155*61046927SAndroid Build Coastguard Worker if (pipeline->base.base.active_stages != 0) {
3156*61046927SAndroid Build Coastguard Worker result = anv_graphics_pipeline_compile(&pipeline->base, stages,
3157*61046927SAndroid Build Coastguard Worker cache, &pipeline_feedback,
3158*61046927SAndroid Build Coastguard Worker pCreateInfo, &pipeline->state);
3159*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3160*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(&pipeline->base.base, device);
3161*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
3162*61046927SAndroid Build Coastguard Worker return result;
3163*61046927SAndroid Build Coastguard Worker }
3164*61046927SAndroid Build Coastguard Worker }
3165*61046927SAndroid Build Coastguard Worker
3166*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
3167*61046927SAndroid Build Coastguard Worker
3168*61046927SAndroid Build Coastguard Worker anv_fill_pipeline_creation_feedback(&pipeline->base, &pipeline_feedback,
3169*61046927SAndroid Build Coastguard Worker pCreateInfo, stages);
3170*61046927SAndroid Build Coastguard Worker
3171*61046927SAndroid Build Coastguard Worker anv_graphics_lib_validate_shaders(
3172*61046927SAndroid Build Coastguard Worker pipeline,
3173*61046927SAndroid Build Coastguard Worker flags & VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT);
3174*61046927SAndroid Build Coastguard Worker
3175*61046927SAndroid Build Coastguard Worker *pPipeline = anv_pipeline_to_handle(&pipeline->base.base);
3176*61046927SAndroid Build Coastguard Worker
3177*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3178*61046927SAndroid Build Coastguard Worker }
3179*61046927SAndroid Build Coastguard Worker
3180*61046927SAndroid Build Coastguard Worker static VkResult
anv_graphics_pipeline_create(struct anv_device * device,struct vk_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)3181*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_create(struct anv_device *device,
3182*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
3183*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo *pCreateInfo,
3184*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *pAllocator,
3185*61046927SAndroid Build Coastguard Worker VkPipeline *pPipeline)
3186*61046927SAndroid Build Coastguard Worker {
3187*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage stages[ANV_GRAPHICS_SHADER_STAGE_COUNT] = {};
3188*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
3189*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
3190*61046927SAndroid Build Coastguard Worker };
3191*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
3192*61046927SAndroid Build Coastguard Worker
3193*61046927SAndroid Build Coastguard Worker struct anv_graphics_pipeline *pipeline;
3194*61046927SAndroid Build Coastguard Worker VkResult result;
3195*61046927SAndroid Build Coastguard Worker
3196*61046927SAndroid Build Coastguard Worker const VkPipelineCreateFlags2KHR flags =
3197*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_create_flags(pCreateInfo);
3198*61046927SAndroid Build Coastguard Worker assert((flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR) == 0);
3199*61046927SAndroid Build Coastguard Worker
3200*61046927SAndroid Build Coastguard Worker const VkPipelineLibraryCreateInfoKHR *libs_info =
3201*61046927SAndroid Build Coastguard Worker vk_find_struct_const(pCreateInfo->pNext,
3202*61046927SAndroid Build Coastguard Worker PIPELINE_LIBRARY_CREATE_INFO_KHR);
3203*61046927SAndroid Build Coastguard Worker
3204*61046927SAndroid Build Coastguard Worker pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
3205*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
3206*61046927SAndroid Build Coastguard Worker if (pipeline == NULL)
3207*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
3208*61046927SAndroid Build Coastguard Worker
3209*61046927SAndroid Build Coastguard Worker /* Initialize some information required by shaders */
3210*61046927SAndroid Build Coastguard Worker result = anv_pipeline_init(&pipeline->base.base, device,
3211*61046927SAndroid Build Coastguard Worker ANV_PIPELINE_GRAPHICS, flags,
3212*61046927SAndroid Build Coastguard Worker pAllocator);
3213*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3214*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
3215*61046927SAndroid Build Coastguard Worker return result;
3216*61046927SAndroid Build Coastguard Worker }
3217*61046927SAndroid Build Coastguard Worker
3218*61046927SAndroid Build Coastguard Worker const bool link_optimize =
3219*61046927SAndroid Build Coastguard Worker (flags & VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT) != 0;
3220*61046927SAndroid Build Coastguard Worker
3221*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_all_state all;
3222*61046927SAndroid Build Coastguard Worker struct vk_graphics_pipeline_state state = { };
3223*61046927SAndroid Build Coastguard Worker
3224*61046927SAndroid Build Coastguard Worker /* If we have libraries, import them first. */
3225*61046927SAndroid Build Coastguard Worker if (libs_info) {
3226*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < libs_info->libraryCount; i++) {
3227*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline_lib, libs_info->pLibraries[i]);
3228*61046927SAndroid Build Coastguard Worker struct anv_graphics_lib_pipeline *gfx_pipeline_lib =
3229*61046927SAndroid Build Coastguard Worker anv_pipeline_to_graphics_lib(pipeline_lib);
3230*61046927SAndroid Build Coastguard Worker
3231*61046927SAndroid Build Coastguard Worker /* If we have link time optimization, all libraries must be created
3232*61046927SAndroid Build Coastguard Worker * with
3233*61046927SAndroid Build Coastguard Worker * VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT.
3234*61046927SAndroid Build Coastguard Worker */
3235*61046927SAndroid Build Coastguard Worker assert(!link_optimize || gfx_pipeline_lib->retain_shaders);
3236*61046927SAndroid Build Coastguard Worker
3237*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_state_merge(&state, &gfx_pipeline_lib->state);
3238*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_import_lib(&pipeline->base,
3239*61046927SAndroid Build Coastguard Worker link_optimize,
3240*61046927SAndroid Build Coastguard Worker false,
3241*61046927SAndroid Build Coastguard Worker stages,
3242*61046927SAndroid Build Coastguard Worker gfx_pipeline_lib);
3243*61046927SAndroid Build Coastguard Worker }
3244*61046927SAndroid Build Coastguard Worker }
3245*61046927SAndroid Build Coastguard Worker
3246*61046927SAndroid Build Coastguard Worker result = vk_graphics_pipeline_state_fill(&device->vk, &state, pCreateInfo,
3247*61046927SAndroid Build Coastguard Worker NULL /* driver_rp */,
3248*61046927SAndroid Build Coastguard Worker 0 /* driver_rp_flags */,
3249*61046927SAndroid Build Coastguard Worker &all, NULL, 0, NULL);
3250*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3251*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(&pipeline->base.base, device);
3252*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
3253*61046927SAndroid Build Coastguard Worker return result;
3254*61046927SAndroid Build Coastguard Worker }
3255*61046927SAndroid Build Coastguard Worker
3256*61046927SAndroid Build Coastguard Worker pipeline->dynamic_state.vi = &pipeline->vertex_input;
3257*61046927SAndroid Build Coastguard Worker pipeline->dynamic_state.ms.sample_locations = &pipeline->base.sample_locations;
3258*61046927SAndroid Build Coastguard Worker vk_dynamic_graphics_state_fill(&pipeline->dynamic_state, &state);
3259*61046927SAndroid Build Coastguard Worker
3260*61046927SAndroid Build Coastguard Worker pipeline->base.base.active_stages = state.shader_stages;
3261*61046927SAndroid Build Coastguard Worker
3262*61046927SAndroid Build Coastguard Worker /* Sanity check on the shaders */
3263*61046927SAndroid Build Coastguard Worker assert(pipeline->base.base.active_stages & VK_SHADER_STAGE_VERTEX_BIT ||
3264*61046927SAndroid Build Coastguard Worker pipeline->base.base.active_stages & VK_SHADER_STAGE_MESH_BIT_EXT);
3265*61046927SAndroid Build Coastguard Worker
3266*61046927SAndroid Build Coastguard Worker if (anv_pipeline_is_mesh(pipeline)) {
3267*61046927SAndroid Build Coastguard Worker assert(device->physical->vk.supported_extensions.EXT_mesh_shader);
3268*61046927SAndroid Build Coastguard Worker }
3269*61046927SAndroid Build Coastguard Worker
3270*61046927SAndroid Build Coastguard Worker /* After we've imported all the libraries' layouts, import the pipeline
3271*61046927SAndroid Build Coastguard Worker * layout and hash the whole lot.
3272*61046927SAndroid Build Coastguard Worker */
3273*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
3274*61046927SAndroid Build Coastguard Worker if (pipeline_layout != NULL) {
3275*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_import_layout(&pipeline->base,
3276*61046927SAndroid Build Coastguard Worker &pipeline_layout->sets_layout);
3277*61046927SAndroid Build Coastguard Worker }
3278*61046927SAndroid Build Coastguard Worker
3279*61046927SAndroid Build Coastguard Worker anv_pipeline_sets_layout_hash(&pipeline->base.base.layout);
3280*61046927SAndroid Build Coastguard Worker
3281*61046927SAndroid Build Coastguard Worker /* Compile shaders, all required information should be have been copied in
3282*61046927SAndroid Build Coastguard Worker * the previous step. We can skip this if there are no active stage in that
3283*61046927SAndroid Build Coastguard Worker * pipeline.
3284*61046927SAndroid Build Coastguard Worker */
3285*61046927SAndroid Build Coastguard Worker result = anv_graphics_pipeline_compile(&pipeline->base, stages,
3286*61046927SAndroid Build Coastguard Worker cache, &pipeline_feedback,
3287*61046927SAndroid Build Coastguard Worker pCreateInfo, &state);
3288*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3289*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(&pipeline->base.base, device);
3290*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
3291*61046927SAndroid Build Coastguard Worker return result;
3292*61046927SAndroid Build Coastguard Worker }
3293*61046927SAndroid Build Coastguard Worker
3294*61046927SAndroid Build Coastguard Worker /* Prepare a batch for the commands and emit all the non dynamic ones.
3295*61046927SAndroid Build Coastguard Worker */
3296*61046927SAndroid Build Coastguard Worker anv_batch_set_storage(&pipeline->base.base.batch, ANV_NULL_ADDRESS,
3297*61046927SAndroid Build Coastguard Worker pipeline->batch_data, sizeof(pipeline->batch_data));
3298*61046927SAndroid Build Coastguard Worker
3299*61046927SAndroid Build Coastguard Worker if (pipeline->base.base.active_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3300*61046927SAndroid Build Coastguard Worker pipeline->base.base.active_stages |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
3301*61046927SAndroid Build Coastguard Worker
3302*61046927SAndroid Build Coastguard Worker if (anv_pipeline_is_mesh(pipeline))
3303*61046927SAndroid Build Coastguard Worker assert(device->physical->vk.supported_extensions.EXT_mesh_shader);
3304*61046927SAndroid Build Coastguard Worker
3305*61046927SAndroid Build Coastguard Worker anv_graphics_pipeline_emit(pipeline, &state);
3306*61046927SAndroid Build Coastguard Worker
3307*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
3308*61046927SAndroid Build Coastguard Worker
3309*61046927SAndroid Build Coastguard Worker anv_fill_pipeline_creation_feedback(&pipeline->base, &pipeline_feedback,
3310*61046927SAndroid Build Coastguard Worker pCreateInfo, stages);
3311*61046927SAndroid Build Coastguard Worker
3312*61046927SAndroid Build Coastguard Worker ANV_RMV(graphics_pipeline_create, device, pipeline, false);
3313*61046927SAndroid Build Coastguard Worker
3314*61046927SAndroid Build Coastguard Worker *pPipeline = anv_pipeline_to_handle(&pipeline->base.base);
3315*61046927SAndroid Build Coastguard Worker
3316*61046927SAndroid Build Coastguard Worker return pipeline->base.base.batch.status;
3317*61046927SAndroid Build Coastguard Worker }
3318*61046927SAndroid Build Coastguard Worker
anv_CreateGraphicsPipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)3319*61046927SAndroid Build Coastguard Worker VkResult anv_CreateGraphicsPipelines(
3320*61046927SAndroid Build Coastguard Worker VkDevice _device,
3321*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
3322*61046927SAndroid Build Coastguard Worker uint32_t count,
3323*61046927SAndroid Build Coastguard Worker const VkGraphicsPipelineCreateInfo* pCreateInfos,
3324*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator,
3325*61046927SAndroid Build Coastguard Worker VkPipeline* pPipelines)
3326*61046927SAndroid Build Coastguard Worker {
3327*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_device, device, _device);
3328*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(vk_pipeline_cache, pipeline_cache, pipelineCache);
3329*61046927SAndroid Build Coastguard Worker
3330*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
3331*61046927SAndroid Build Coastguard Worker
3332*61046927SAndroid Build Coastguard Worker unsigned i;
3333*61046927SAndroid Build Coastguard Worker for (i = 0; i < count; i++) {
3334*61046927SAndroid Build Coastguard Worker assert(pCreateInfos[i].sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
3335*61046927SAndroid Build Coastguard Worker
3336*61046927SAndroid Build Coastguard Worker const VkPipelineCreateFlags2KHR flags =
3337*61046927SAndroid Build Coastguard Worker vk_graphics_pipeline_create_flags(&pCreateInfos[i]);
3338*61046927SAndroid Build Coastguard Worker VkResult res;
3339*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR) {
3340*61046927SAndroid Build Coastguard Worker res = anv_graphics_lib_pipeline_create(device, pipeline_cache,
3341*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
3342*61046927SAndroid Build Coastguard Worker pAllocator,
3343*61046927SAndroid Build Coastguard Worker &pPipelines[i]);
3344*61046927SAndroid Build Coastguard Worker } else {
3345*61046927SAndroid Build Coastguard Worker res = anv_graphics_pipeline_create(device,
3346*61046927SAndroid Build Coastguard Worker pipeline_cache,
3347*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
3348*61046927SAndroid Build Coastguard Worker pAllocator, &pPipelines[i]);
3349*61046927SAndroid Build Coastguard Worker }
3350*61046927SAndroid Build Coastguard Worker
3351*61046927SAndroid Build Coastguard Worker if (res != VK_SUCCESS) {
3352*61046927SAndroid Build Coastguard Worker result = res;
3353*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR)
3354*61046927SAndroid Build Coastguard Worker break;
3355*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
3356*61046927SAndroid Build Coastguard Worker }
3357*61046927SAndroid Build Coastguard Worker }
3358*61046927SAndroid Build Coastguard Worker
3359*61046927SAndroid Build Coastguard Worker for (; i < count; i++)
3360*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
3361*61046927SAndroid Build Coastguard Worker
3362*61046927SAndroid Build Coastguard Worker return result;
3363*61046927SAndroid Build Coastguard Worker }
3364*61046927SAndroid Build Coastguard Worker
3365*61046927SAndroid Build Coastguard Worker static bool
should_remat_cb(nir_instr * instr,void * data)3366*61046927SAndroid Build Coastguard Worker should_remat_cb(nir_instr *instr, void *data)
3367*61046927SAndroid Build Coastguard Worker {
3368*61046927SAndroid Build Coastguard Worker if (instr->type != nir_instr_type_intrinsic)
3369*61046927SAndroid Build Coastguard Worker return false;
3370*61046927SAndroid Build Coastguard Worker
3371*61046927SAndroid Build Coastguard Worker return nir_instr_as_intrinsic(instr)->intrinsic == nir_intrinsic_resource_intel;
3372*61046927SAndroid Build Coastguard Worker }
3373*61046927SAndroid Build Coastguard Worker
3374*61046927SAndroid Build Coastguard Worker static VkResult
compile_upload_rt_shader(struct anv_ray_tracing_pipeline * pipeline,struct vk_pipeline_cache * cache,nir_shader * nir,struct anv_pipeline_stage * stage,void * mem_ctx)3375*61046927SAndroid Build Coastguard Worker compile_upload_rt_shader(struct anv_ray_tracing_pipeline *pipeline,
3376*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
3377*61046927SAndroid Build Coastguard Worker nir_shader *nir,
3378*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stage,
3379*61046927SAndroid Build Coastguard Worker void *mem_ctx)
3380*61046927SAndroid Build Coastguard Worker {
3381*61046927SAndroid Build Coastguard Worker const struct brw_compiler *compiler =
3382*61046927SAndroid Build Coastguard Worker pipeline->base.device->physical->compiler;
3383*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = compiler->devinfo;
3384*61046927SAndroid Build Coastguard Worker
3385*61046927SAndroid Build Coastguard Worker nir_shader **resume_shaders = NULL;
3386*61046927SAndroid Build Coastguard Worker uint32_t num_resume_shaders = 0;
3387*61046927SAndroid Build Coastguard Worker if (nir->info.stage != MESA_SHADER_COMPUTE) {
3388*61046927SAndroid Build Coastguard Worker const nir_lower_shader_calls_options opts = {
3389*61046927SAndroid Build Coastguard Worker .address_format = nir_address_format_64bit_global,
3390*61046927SAndroid Build Coastguard Worker .stack_alignment = BRW_BTD_STACK_ALIGN,
3391*61046927SAndroid Build Coastguard Worker .localized_loads = true,
3392*61046927SAndroid Build Coastguard Worker .vectorizer_callback = brw_nir_should_vectorize_mem,
3393*61046927SAndroid Build Coastguard Worker .vectorizer_data = NULL,
3394*61046927SAndroid Build Coastguard Worker .should_remat_callback = should_remat_cb,
3395*61046927SAndroid Build Coastguard Worker };
3396*61046927SAndroid Build Coastguard Worker
3397*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, nir_lower_shader_calls, &opts,
3398*61046927SAndroid Build Coastguard Worker &resume_shaders, &num_resume_shaders, mem_ctx);
3399*61046927SAndroid Build Coastguard Worker NIR_PASS(_, nir, brw_nir_lower_shader_calls, &stage->key.bs);
3400*61046927SAndroid Build Coastguard Worker NIR_PASS_V(nir, brw_nir_lower_rt_intrinsics, devinfo);
3401*61046927SAndroid Build Coastguard Worker }
3402*61046927SAndroid Build Coastguard Worker
3403*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_resume_shaders; i++) {
3404*61046927SAndroid Build Coastguard Worker NIR_PASS(_,resume_shaders[i], brw_nir_lower_shader_calls, &stage->key.bs);
3405*61046927SAndroid Build Coastguard Worker NIR_PASS_V(resume_shaders[i], brw_nir_lower_rt_intrinsics, devinfo);
3406*61046927SAndroid Build Coastguard Worker }
3407*61046927SAndroid Build Coastguard Worker
3408*61046927SAndroid Build Coastguard Worker struct brw_compile_bs_params params = {
3409*61046927SAndroid Build Coastguard Worker .base = {
3410*61046927SAndroid Build Coastguard Worker .nir = nir,
3411*61046927SAndroid Build Coastguard Worker .stats = stage->stats,
3412*61046927SAndroid Build Coastguard Worker .log_data = pipeline->base.device,
3413*61046927SAndroid Build Coastguard Worker .mem_ctx = mem_ctx,
3414*61046927SAndroid Build Coastguard Worker .source_hash = stage->source_hash,
3415*61046927SAndroid Build Coastguard Worker },
3416*61046927SAndroid Build Coastguard Worker .key = &stage->key.bs,
3417*61046927SAndroid Build Coastguard Worker .prog_data = &stage->prog_data.bs,
3418*61046927SAndroid Build Coastguard Worker .num_resume_shaders = num_resume_shaders,
3419*61046927SAndroid Build Coastguard Worker .resume_shaders = resume_shaders,
3420*61046927SAndroid Build Coastguard Worker };
3421*61046927SAndroid Build Coastguard Worker
3422*61046927SAndroid Build Coastguard Worker stage->code = brw_compile_bs(compiler, ¶ms);
3423*61046927SAndroid Build Coastguard Worker if (stage->code == NULL) {
3424*61046927SAndroid Build Coastguard Worker VkResult result;
3425*61046927SAndroid Build Coastguard Worker
3426*61046927SAndroid Build Coastguard Worker if (params.base.error_str)
3427*61046927SAndroid Build Coastguard Worker result = vk_errorf(pipeline, VK_ERROR_UNKNOWN, "%s", params.base.error_str);
3428*61046927SAndroid Build Coastguard Worker else
3429*61046927SAndroid Build Coastguard Worker result = vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY);
3430*61046927SAndroid Build Coastguard Worker
3431*61046927SAndroid Build Coastguard Worker return result;
3432*61046927SAndroid Build Coastguard Worker }
3433*61046927SAndroid Build Coastguard Worker
3434*61046927SAndroid Build Coastguard Worker struct anv_shader_upload_params upload_params = {
3435*61046927SAndroid Build Coastguard Worker .stage = stage->stage,
3436*61046927SAndroid Build Coastguard Worker .key_data = &stage->cache_key,
3437*61046927SAndroid Build Coastguard Worker .key_size = sizeof(stage->cache_key),
3438*61046927SAndroid Build Coastguard Worker .kernel_data = stage->code,
3439*61046927SAndroid Build Coastguard Worker .kernel_size = stage->prog_data.base.program_size,
3440*61046927SAndroid Build Coastguard Worker .prog_data = &stage->prog_data.base,
3441*61046927SAndroid Build Coastguard Worker .prog_data_size = brw_prog_data_size(stage->stage),
3442*61046927SAndroid Build Coastguard Worker .stats = stage->stats,
3443*61046927SAndroid Build Coastguard Worker .num_stats = 1,
3444*61046927SAndroid Build Coastguard Worker .bind_map = &stage->bind_map,
3445*61046927SAndroid Build Coastguard Worker .push_desc_info = &stage->push_desc_info,
3446*61046927SAndroid Build Coastguard Worker .dynamic_push_values = stage->dynamic_push_values,
3447*61046927SAndroid Build Coastguard Worker };
3448*61046927SAndroid Build Coastguard Worker
3449*61046927SAndroid Build Coastguard Worker stage->bin =
3450*61046927SAndroid Build Coastguard Worker anv_device_upload_kernel(pipeline->base.device, cache, &upload_params);
3451*61046927SAndroid Build Coastguard Worker if (stage->bin == NULL)
3452*61046927SAndroid Build Coastguard Worker return vk_error(pipeline, VK_ERROR_OUT_OF_HOST_MEMORY);
3453*61046927SAndroid Build Coastguard Worker
3454*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executables(&pipeline->base, stage);
3455*61046927SAndroid Build Coastguard Worker
3456*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3457*61046927SAndroid Build Coastguard Worker }
3458*61046927SAndroid Build Coastguard Worker
3459*61046927SAndroid Build Coastguard Worker static bool
is_rt_stack_size_dynamic(const VkRayTracingPipelineCreateInfoKHR * info)3460*61046927SAndroid Build Coastguard Worker is_rt_stack_size_dynamic(const VkRayTracingPipelineCreateInfoKHR *info)
3461*61046927SAndroid Build Coastguard Worker {
3462*61046927SAndroid Build Coastguard Worker if (info->pDynamicState == NULL)
3463*61046927SAndroid Build Coastguard Worker return false;
3464*61046927SAndroid Build Coastguard Worker
3465*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < info->pDynamicState->dynamicStateCount; i++) {
3466*61046927SAndroid Build Coastguard Worker if (info->pDynamicState->pDynamicStates[i] ==
3467*61046927SAndroid Build Coastguard Worker VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR)
3468*61046927SAndroid Build Coastguard Worker return true;
3469*61046927SAndroid Build Coastguard Worker }
3470*61046927SAndroid Build Coastguard Worker
3471*61046927SAndroid Build Coastguard Worker return false;
3472*61046927SAndroid Build Coastguard Worker }
3473*61046927SAndroid Build Coastguard Worker
3474*61046927SAndroid Build Coastguard Worker static void
anv_pipeline_compute_ray_tracing_stacks(struct anv_ray_tracing_pipeline * pipeline,const VkRayTracingPipelineCreateInfoKHR * info,uint32_t * stack_max)3475*61046927SAndroid Build Coastguard Worker anv_pipeline_compute_ray_tracing_stacks(struct anv_ray_tracing_pipeline *pipeline,
3476*61046927SAndroid Build Coastguard Worker const VkRayTracingPipelineCreateInfoKHR *info,
3477*61046927SAndroid Build Coastguard Worker uint32_t *stack_max)
3478*61046927SAndroid Build Coastguard Worker {
3479*61046927SAndroid Build Coastguard Worker if (is_rt_stack_size_dynamic(info)) {
3480*61046927SAndroid Build Coastguard Worker pipeline->stack_size = 0; /* 0 means dynamic */
3481*61046927SAndroid Build Coastguard Worker } else {
3482*61046927SAndroid Build Coastguard Worker /* From the Vulkan spec:
3483*61046927SAndroid Build Coastguard Worker *
3484*61046927SAndroid Build Coastguard Worker * "If the stack size is not set explicitly, the stack size for a
3485*61046927SAndroid Build Coastguard Worker * pipeline is:
3486*61046927SAndroid Build Coastguard Worker *
3487*61046927SAndroid Build Coastguard Worker * rayGenStackMax +
3488*61046927SAndroid Build Coastguard Worker * min(1, maxPipelineRayRecursionDepth) ×
3489*61046927SAndroid Build Coastguard Worker * max(closestHitStackMax, missStackMax,
3490*61046927SAndroid Build Coastguard Worker * intersectionStackMax + anyHitStackMax) +
3491*61046927SAndroid Build Coastguard Worker * max(0, maxPipelineRayRecursionDepth-1) ×
3492*61046927SAndroid Build Coastguard Worker * max(closestHitStackMax, missStackMax) +
3493*61046927SAndroid Build Coastguard Worker * 2 × callableStackMax"
3494*61046927SAndroid Build Coastguard Worker */
3495*61046927SAndroid Build Coastguard Worker pipeline->stack_size =
3496*61046927SAndroid Build Coastguard Worker stack_max[MESA_SHADER_RAYGEN] +
3497*61046927SAndroid Build Coastguard Worker MIN2(1, info->maxPipelineRayRecursionDepth) *
3498*61046927SAndroid Build Coastguard Worker MAX4(stack_max[MESA_SHADER_CLOSEST_HIT],
3499*61046927SAndroid Build Coastguard Worker stack_max[MESA_SHADER_MISS],
3500*61046927SAndroid Build Coastguard Worker stack_max[MESA_SHADER_INTERSECTION],
3501*61046927SAndroid Build Coastguard Worker stack_max[MESA_SHADER_ANY_HIT]) +
3502*61046927SAndroid Build Coastguard Worker MAX2(0, (int)info->maxPipelineRayRecursionDepth - 1) *
3503*61046927SAndroid Build Coastguard Worker MAX2(stack_max[MESA_SHADER_CLOSEST_HIT],
3504*61046927SAndroid Build Coastguard Worker stack_max[MESA_SHADER_MISS]) +
3505*61046927SAndroid Build Coastguard Worker 2 * stack_max[MESA_SHADER_CALLABLE];
3506*61046927SAndroid Build Coastguard Worker
3507*61046927SAndroid Build Coastguard Worker /* This is an extremely unlikely case but we need to set it to some
3508*61046927SAndroid Build Coastguard Worker * non-zero value so that we don't accidentally think it's dynamic.
3509*61046927SAndroid Build Coastguard Worker * Our minimum stack size is 2KB anyway so we could set to any small
3510*61046927SAndroid Build Coastguard Worker * value we like.
3511*61046927SAndroid Build Coastguard Worker */
3512*61046927SAndroid Build Coastguard Worker if (pipeline->stack_size == 0)
3513*61046927SAndroid Build Coastguard Worker pipeline->stack_size = 1;
3514*61046927SAndroid Build Coastguard Worker }
3515*61046927SAndroid Build Coastguard Worker }
3516*61046927SAndroid Build Coastguard Worker
3517*61046927SAndroid Build Coastguard Worker static enum brw_rt_ray_flags
anv_pipeline_get_pipeline_ray_flags(VkPipelineCreateFlags2KHR flags)3518*61046927SAndroid Build Coastguard Worker anv_pipeline_get_pipeline_ray_flags(VkPipelineCreateFlags2KHR flags)
3519*61046927SAndroid Build Coastguard Worker {
3520*61046927SAndroid Build Coastguard Worker uint32_t ray_flags = 0;
3521*61046927SAndroid Build Coastguard Worker
3522*61046927SAndroid Build Coastguard Worker const bool rt_skip_triangles =
3523*61046927SAndroid Build Coastguard Worker flags & VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR;
3524*61046927SAndroid Build Coastguard Worker const bool rt_skip_aabbs =
3525*61046927SAndroid Build Coastguard Worker flags & VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_AABBS_BIT_KHR;
3526*61046927SAndroid Build Coastguard Worker assert(!(rt_skip_triangles && rt_skip_aabbs));
3527*61046927SAndroid Build Coastguard Worker
3528*61046927SAndroid Build Coastguard Worker if (rt_skip_triangles)
3529*61046927SAndroid Build Coastguard Worker ray_flags |= BRW_RT_RAY_FLAG_SKIP_TRIANGLES;
3530*61046927SAndroid Build Coastguard Worker else if (rt_skip_aabbs)
3531*61046927SAndroid Build Coastguard Worker ray_flags |= BRW_RT_RAY_FLAG_SKIP_AABBS;
3532*61046927SAndroid Build Coastguard Worker
3533*61046927SAndroid Build Coastguard Worker return ray_flags;
3534*61046927SAndroid Build Coastguard Worker }
3535*61046927SAndroid Build Coastguard Worker
3536*61046927SAndroid Build Coastguard Worker static struct anv_pipeline_stage *
anv_pipeline_init_ray_tracing_stages(struct anv_ray_tracing_pipeline * pipeline,const VkRayTracingPipelineCreateInfoKHR * info,void * tmp_pipeline_ctx)3537*61046927SAndroid Build Coastguard Worker anv_pipeline_init_ray_tracing_stages(struct anv_ray_tracing_pipeline *pipeline,
3538*61046927SAndroid Build Coastguard Worker const VkRayTracingPipelineCreateInfoKHR *info,
3539*61046927SAndroid Build Coastguard Worker void *tmp_pipeline_ctx)
3540*61046927SAndroid Build Coastguard Worker {
3541*61046927SAndroid Build Coastguard Worker struct anv_device *device = pipeline->base.device;
3542*61046927SAndroid Build Coastguard Worker /* Create enough stage entries for all shader modules plus potential
3543*61046927SAndroid Build Coastguard Worker * combinaisons in the groups.
3544*61046927SAndroid Build Coastguard Worker */
3545*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages =
3546*61046927SAndroid Build Coastguard Worker rzalloc_array(tmp_pipeline_ctx, struct anv_pipeline_stage, info->stageCount);
3547*61046927SAndroid Build Coastguard Worker
3548*61046927SAndroid Build Coastguard Worker enum brw_rt_ray_flags ray_flags =
3549*61046927SAndroid Build Coastguard Worker anv_pipeline_get_pipeline_ray_flags(pipeline->base.flags);
3550*61046927SAndroid Build Coastguard Worker
3551*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->stageCount; i++) {
3552*61046927SAndroid Build Coastguard Worker const VkPipelineShaderStageCreateInfo *sinfo = &info->pStages[i];
3553*61046927SAndroid Build Coastguard Worker if (vk_pipeline_shader_stage_is_null(sinfo))
3554*61046927SAndroid Build Coastguard Worker continue;
3555*61046927SAndroid Build Coastguard Worker
3556*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
3557*61046927SAndroid Build Coastguard Worker
3558*61046927SAndroid Build Coastguard Worker stages[i] = (struct anv_pipeline_stage) {
3559*61046927SAndroid Build Coastguard Worker .stage = vk_to_mesa_shader_stage(sinfo->stage),
3560*61046927SAndroid Build Coastguard Worker .pipeline_flags = pipeline->base.flags,
3561*61046927SAndroid Build Coastguard Worker .pipeline_pNext = info->pNext,
3562*61046927SAndroid Build Coastguard Worker .info = sinfo,
3563*61046927SAndroid Build Coastguard Worker .cache_key = {
3564*61046927SAndroid Build Coastguard Worker .stage = vk_to_mesa_shader_stage(sinfo->stage),
3565*61046927SAndroid Build Coastguard Worker },
3566*61046927SAndroid Build Coastguard Worker .feedback = {
3567*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
3568*61046927SAndroid Build Coastguard Worker },
3569*61046927SAndroid Build Coastguard Worker };
3570*61046927SAndroid Build Coastguard Worker
3571*61046927SAndroid Build Coastguard Worker anv_stage_allocate_bind_map_tables(&pipeline->base, &stages[i],
3572*61046927SAndroid Build Coastguard Worker tmp_pipeline_ctx);
3573*61046927SAndroid Build Coastguard Worker
3574*61046927SAndroid Build Coastguard Worker pipeline->base.active_stages |= sinfo->stage;
3575*61046927SAndroid Build Coastguard Worker
3576*61046927SAndroid Build Coastguard Worker anv_stage_write_shader_hash(&stages[i], device);
3577*61046927SAndroid Build Coastguard Worker
3578*61046927SAndroid Build Coastguard Worker populate_bs_prog_key(&stages[i],
3579*61046927SAndroid Build Coastguard Worker pipeline->base.device,
3580*61046927SAndroid Build Coastguard Worker ray_flags);
3581*61046927SAndroid Build Coastguard Worker
3582*61046927SAndroid Build Coastguard Worker if (stages[i].stage != MESA_SHADER_INTERSECTION) {
3583*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_ray_tracing_shader(pipeline, &stages[i],
3584*61046927SAndroid Build Coastguard Worker stages[i].cache_key.sha1);
3585*61046927SAndroid Build Coastguard Worker }
3586*61046927SAndroid Build Coastguard Worker
3587*61046927SAndroid Build Coastguard Worker stages[i].feedback.duration += os_time_get_nano() - stage_start;
3588*61046927SAndroid Build Coastguard Worker }
3589*61046927SAndroid Build Coastguard Worker
3590*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->groupCount; i++) {
3591*61046927SAndroid Build Coastguard Worker const VkRayTracingShaderGroupCreateInfoKHR *ginfo = &info->pGroups[i];
3592*61046927SAndroid Build Coastguard Worker
3593*61046927SAndroid Build Coastguard Worker if (ginfo->type != VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR)
3594*61046927SAndroid Build Coastguard Worker continue;
3595*61046927SAndroid Build Coastguard Worker
3596*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
3597*61046927SAndroid Build Coastguard Worker
3598*61046927SAndroid Build Coastguard Worker uint32_t intersection_idx = ginfo->intersectionShader;
3599*61046927SAndroid Build Coastguard Worker assert(intersection_idx < info->stageCount);
3600*61046927SAndroid Build Coastguard Worker
3601*61046927SAndroid Build Coastguard Worker uint32_t any_hit_idx = ginfo->anyHitShader;
3602*61046927SAndroid Build Coastguard Worker if (any_hit_idx != VK_SHADER_UNUSED_KHR) {
3603*61046927SAndroid Build Coastguard Worker assert(any_hit_idx < info->stageCount);
3604*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_ray_tracing_combined_shader(pipeline,
3605*61046927SAndroid Build Coastguard Worker &stages[intersection_idx],
3606*61046927SAndroid Build Coastguard Worker &stages[any_hit_idx],
3607*61046927SAndroid Build Coastguard Worker stages[intersection_idx].cache_key.sha1);
3608*61046927SAndroid Build Coastguard Worker } else {
3609*61046927SAndroid Build Coastguard Worker anv_pipeline_hash_ray_tracing_shader(pipeline,
3610*61046927SAndroid Build Coastguard Worker &stages[intersection_idx],
3611*61046927SAndroid Build Coastguard Worker stages[intersection_idx].cache_key.sha1);
3612*61046927SAndroid Build Coastguard Worker }
3613*61046927SAndroid Build Coastguard Worker
3614*61046927SAndroid Build Coastguard Worker stages[intersection_idx].feedback.duration += os_time_get_nano() - stage_start;
3615*61046927SAndroid Build Coastguard Worker }
3616*61046927SAndroid Build Coastguard Worker
3617*61046927SAndroid Build Coastguard Worker return stages;
3618*61046927SAndroid Build Coastguard Worker }
3619*61046927SAndroid Build Coastguard Worker
3620*61046927SAndroid Build Coastguard Worker static bool
anv_ray_tracing_pipeline_load_cached_shaders(struct anv_ray_tracing_pipeline * pipeline,struct vk_pipeline_cache * cache,const VkRayTracingPipelineCreateInfoKHR * info,struct anv_pipeline_stage * stages)3621*61046927SAndroid Build Coastguard Worker anv_ray_tracing_pipeline_load_cached_shaders(struct anv_ray_tracing_pipeline *pipeline,
3622*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
3623*61046927SAndroid Build Coastguard Worker const VkRayTracingPipelineCreateInfoKHR *info,
3624*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages)
3625*61046927SAndroid Build Coastguard Worker {
3626*61046927SAndroid Build Coastguard Worker uint32_t shaders = 0, cache_hits = 0;
3627*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->stageCount; i++) {
3628*61046927SAndroid Build Coastguard Worker if (stages[i].info == NULL)
3629*61046927SAndroid Build Coastguard Worker continue;
3630*61046927SAndroid Build Coastguard Worker
3631*61046927SAndroid Build Coastguard Worker shaders++;
3632*61046927SAndroid Build Coastguard Worker
3633*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
3634*61046927SAndroid Build Coastguard Worker
3635*61046927SAndroid Build Coastguard Worker bool cache_hit;
3636*61046927SAndroid Build Coastguard Worker stages[i].bin = anv_device_search_for_kernel(pipeline->base.device, cache,
3637*61046927SAndroid Build Coastguard Worker &stages[i].cache_key,
3638*61046927SAndroid Build Coastguard Worker sizeof(stages[i].cache_key),
3639*61046927SAndroid Build Coastguard Worker &cache_hit);
3640*61046927SAndroid Build Coastguard Worker if (cache_hit) {
3641*61046927SAndroid Build Coastguard Worker cache_hits++;
3642*61046927SAndroid Build Coastguard Worker stages[i].feedback.flags |=
3643*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
3644*61046927SAndroid Build Coastguard Worker }
3645*61046927SAndroid Build Coastguard Worker
3646*61046927SAndroid Build Coastguard Worker if (stages[i].bin != NULL)
3647*61046927SAndroid Build Coastguard Worker anv_pipeline_add_executables(&pipeline->base, &stages[i]);
3648*61046927SAndroid Build Coastguard Worker
3649*61046927SAndroid Build Coastguard Worker stages[i].feedback.duration += os_time_get_nano() - stage_start;
3650*61046927SAndroid Build Coastguard Worker }
3651*61046927SAndroid Build Coastguard Worker
3652*61046927SAndroid Build Coastguard Worker return cache_hits == shaders;
3653*61046927SAndroid Build Coastguard Worker }
3654*61046927SAndroid Build Coastguard Worker
3655*61046927SAndroid Build Coastguard Worker static VkResult
anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline * pipeline,void * tmp_pipeline_ctx,struct anv_pipeline_stage * stages,struct vk_pipeline_cache * cache,const VkRayTracingPipelineCreateInfoKHR * info)3656*61046927SAndroid Build Coastguard Worker anv_pipeline_compile_ray_tracing(struct anv_ray_tracing_pipeline *pipeline,
3657*61046927SAndroid Build Coastguard Worker void *tmp_pipeline_ctx,
3658*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages,
3659*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
3660*61046927SAndroid Build Coastguard Worker const VkRayTracingPipelineCreateInfoKHR *info)
3661*61046927SAndroid Build Coastguard Worker {
3662*61046927SAndroid Build Coastguard Worker const struct intel_device_info *devinfo = pipeline->base.device->info;
3663*61046927SAndroid Build Coastguard Worker VkResult result;
3664*61046927SAndroid Build Coastguard Worker
3665*61046927SAndroid Build Coastguard Worker VkPipelineCreationFeedback pipeline_feedback = {
3666*61046927SAndroid Build Coastguard Worker .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
3667*61046927SAndroid Build Coastguard Worker };
3668*61046927SAndroid Build Coastguard Worker int64_t pipeline_start = os_time_get_nano();
3669*61046927SAndroid Build Coastguard Worker
3670*61046927SAndroid Build Coastguard Worker const bool skip_cache_lookup =
3671*61046927SAndroid Build Coastguard Worker (pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
3672*61046927SAndroid Build Coastguard Worker
3673*61046927SAndroid Build Coastguard Worker if (!skip_cache_lookup &&
3674*61046927SAndroid Build Coastguard Worker anv_ray_tracing_pipeline_load_cached_shaders(pipeline, cache, info, stages)) {
3675*61046927SAndroid Build Coastguard Worker pipeline_feedback.flags |=
3676*61046927SAndroid Build Coastguard Worker VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
3677*61046927SAndroid Build Coastguard Worker goto done;
3678*61046927SAndroid Build Coastguard Worker }
3679*61046927SAndroid Build Coastguard Worker
3680*61046927SAndroid Build Coastguard Worker if (pipeline->base.flags & VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR)
3681*61046927SAndroid Build Coastguard Worker return VK_PIPELINE_COMPILE_REQUIRED;
3682*61046927SAndroid Build Coastguard Worker
3683*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->stageCount; i++) {
3684*61046927SAndroid Build Coastguard Worker if (stages[i].info == NULL)
3685*61046927SAndroid Build Coastguard Worker continue;
3686*61046927SAndroid Build Coastguard Worker
3687*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
3688*61046927SAndroid Build Coastguard Worker
3689*61046927SAndroid Build Coastguard Worker VkResult result = anv_pipeline_stage_get_nir(&pipeline->base, cache,
3690*61046927SAndroid Build Coastguard Worker tmp_pipeline_ctx,
3691*61046927SAndroid Build Coastguard Worker &stages[i]);
3692*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
3693*61046927SAndroid Build Coastguard Worker return result;
3694*61046927SAndroid Build Coastguard Worker
3695*61046927SAndroid Build Coastguard Worker anv_pipeline_nir_preprocess(&pipeline->base, &stages[i]);
3696*61046927SAndroid Build Coastguard Worker
3697*61046927SAndroid Build Coastguard Worker anv_pipeline_lower_nir(&pipeline->base, tmp_pipeline_ctx, &stages[i],
3698*61046927SAndroid Build Coastguard Worker &pipeline->base.layout, 0 /* view_mask */,
3699*61046927SAndroid Build Coastguard Worker false /* use_primitive_replication */);
3700*61046927SAndroid Build Coastguard Worker
3701*61046927SAndroid Build Coastguard Worker stages[i].feedback.duration += os_time_get_nano() - stage_start;
3702*61046927SAndroid Build Coastguard Worker }
3703*61046927SAndroid Build Coastguard Worker
3704*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->stageCount; i++) {
3705*61046927SAndroid Build Coastguard Worker if (stages[i].info == NULL)
3706*61046927SAndroid Build Coastguard Worker continue;
3707*61046927SAndroid Build Coastguard Worker
3708*61046927SAndroid Build Coastguard Worker /* Shader found in cache already. */
3709*61046927SAndroid Build Coastguard Worker if (stages[i].bin != NULL)
3710*61046927SAndroid Build Coastguard Worker continue;
3711*61046927SAndroid Build Coastguard Worker
3712*61046927SAndroid Build Coastguard Worker /* We handle intersection shaders as part of the group */
3713*61046927SAndroid Build Coastguard Worker if (stages[i].stage == MESA_SHADER_INTERSECTION)
3714*61046927SAndroid Build Coastguard Worker continue;
3715*61046927SAndroid Build Coastguard Worker
3716*61046927SAndroid Build Coastguard Worker int64_t stage_start = os_time_get_nano();
3717*61046927SAndroid Build Coastguard Worker
3718*61046927SAndroid Build Coastguard Worker void *tmp_stage_ctx = ralloc_context(tmp_pipeline_ctx);
3719*61046927SAndroid Build Coastguard Worker
3720*61046927SAndroid Build Coastguard Worker nir_shader *nir = nir_shader_clone(tmp_stage_ctx, stages[i].nir);
3721*61046927SAndroid Build Coastguard Worker switch (stages[i].stage) {
3722*61046927SAndroid Build Coastguard Worker case MESA_SHADER_RAYGEN:
3723*61046927SAndroid Build Coastguard Worker brw_nir_lower_raygen(nir);
3724*61046927SAndroid Build Coastguard Worker break;
3725*61046927SAndroid Build Coastguard Worker
3726*61046927SAndroid Build Coastguard Worker case MESA_SHADER_ANY_HIT:
3727*61046927SAndroid Build Coastguard Worker brw_nir_lower_any_hit(nir, devinfo);
3728*61046927SAndroid Build Coastguard Worker break;
3729*61046927SAndroid Build Coastguard Worker
3730*61046927SAndroid Build Coastguard Worker case MESA_SHADER_CLOSEST_HIT:
3731*61046927SAndroid Build Coastguard Worker brw_nir_lower_closest_hit(nir);
3732*61046927SAndroid Build Coastguard Worker break;
3733*61046927SAndroid Build Coastguard Worker
3734*61046927SAndroid Build Coastguard Worker case MESA_SHADER_MISS:
3735*61046927SAndroid Build Coastguard Worker brw_nir_lower_miss(nir);
3736*61046927SAndroid Build Coastguard Worker break;
3737*61046927SAndroid Build Coastguard Worker
3738*61046927SAndroid Build Coastguard Worker case MESA_SHADER_INTERSECTION:
3739*61046927SAndroid Build Coastguard Worker unreachable("These are handled later");
3740*61046927SAndroid Build Coastguard Worker
3741*61046927SAndroid Build Coastguard Worker case MESA_SHADER_CALLABLE:
3742*61046927SAndroid Build Coastguard Worker brw_nir_lower_callable(nir);
3743*61046927SAndroid Build Coastguard Worker break;
3744*61046927SAndroid Build Coastguard Worker
3745*61046927SAndroid Build Coastguard Worker default:
3746*61046927SAndroid Build Coastguard Worker unreachable("Invalid ray-tracing shader stage");
3747*61046927SAndroid Build Coastguard Worker }
3748*61046927SAndroid Build Coastguard Worker
3749*61046927SAndroid Build Coastguard Worker result = compile_upload_rt_shader(pipeline, cache, nir, &stages[i],
3750*61046927SAndroid Build Coastguard Worker tmp_stage_ctx);
3751*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
3752*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_stage_ctx);
3753*61046927SAndroid Build Coastguard Worker return result;
3754*61046927SAndroid Build Coastguard Worker }
3755*61046927SAndroid Build Coastguard Worker
3756*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_stage_ctx);
3757*61046927SAndroid Build Coastguard Worker
3758*61046927SAndroid Build Coastguard Worker stages[i].feedback.duration += os_time_get_nano() - stage_start;
3759*61046927SAndroid Build Coastguard Worker }
3760*61046927SAndroid Build Coastguard Worker
3761*61046927SAndroid Build Coastguard Worker done:
3762*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < info->groupCount; i++) {
3763*61046927SAndroid Build Coastguard Worker const VkRayTracingShaderGroupCreateInfoKHR *ginfo = &info->pGroups[i];
3764*61046927SAndroid Build Coastguard Worker struct anv_rt_shader_group *group = &pipeline->groups[i];
3765*61046927SAndroid Build Coastguard Worker group->type = ginfo->type;
3766*61046927SAndroid Build Coastguard Worker switch (ginfo->type) {
3767*61046927SAndroid Build Coastguard Worker case VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR:
3768*61046927SAndroid Build Coastguard Worker assert(ginfo->generalShader < info->stageCount);
3769*61046927SAndroid Build Coastguard Worker group->general = stages[ginfo->generalShader].bin;
3770*61046927SAndroid Build Coastguard Worker break;
3771*61046927SAndroid Build Coastguard Worker
3772*61046927SAndroid Build Coastguard Worker case VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR:
3773*61046927SAndroid Build Coastguard Worker if (ginfo->anyHitShader < info->stageCount)
3774*61046927SAndroid Build Coastguard Worker group->any_hit = stages[ginfo->anyHitShader].bin;
3775*61046927SAndroid Build Coastguard Worker
3776*61046927SAndroid Build Coastguard Worker if (ginfo->closestHitShader < info->stageCount)
3777*61046927SAndroid Build Coastguard Worker group->closest_hit = stages[ginfo->closestHitShader].bin;
3778*61046927SAndroid Build Coastguard Worker break;
3779*61046927SAndroid Build Coastguard Worker
3780*61046927SAndroid Build Coastguard Worker case VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR: {
3781*61046927SAndroid Build Coastguard Worker if (ginfo->closestHitShader < info->stageCount)
3782*61046927SAndroid Build Coastguard Worker group->closest_hit = stages[ginfo->closestHitShader].bin;
3783*61046927SAndroid Build Coastguard Worker
3784*61046927SAndroid Build Coastguard Worker uint32_t intersection_idx = info->pGroups[i].intersectionShader;
3785*61046927SAndroid Build Coastguard Worker assert(intersection_idx < info->stageCount);
3786*61046927SAndroid Build Coastguard Worker
3787*61046927SAndroid Build Coastguard Worker /* Only compile this stage if not already found in the cache. */
3788*61046927SAndroid Build Coastguard Worker if (stages[intersection_idx].bin == NULL) {
3789*61046927SAndroid Build Coastguard Worker /* The any-hit and intersection shader have to be combined */
3790*61046927SAndroid Build Coastguard Worker uint32_t any_hit_idx = info->pGroups[i].anyHitShader;
3791*61046927SAndroid Build Coastguard Worker const nir_shader *any_hit = NULL;
3792*61046927SAndroid Build Coastguard Worker if (any_hit_idx < info->stageCount)
3793*61046927SAndroid Build Coastguard Worker any_hit = stages[any_hit_idx].nir;
3794*61046927SAndroid Build Coastguard Worker
3795*61046927SAndroid Build Coastguard Worker void *tmp_group_ctx = ralloc_context(tmp_pipeline_ctx);
3796*61046927SAndroid Build Coastguard Worker nir_shader *intersection =
3797*61046927SAndroid Build Coastguard Worker nir_shader_clone(tmp_group_ctx, stages[intersection_idx].nir);
3798*61046927SAndroid Build Coastguard Worker
3799*61046927SAndroid Build Coastguard Worker brw_nir_lower_combined_intersection_any_hit(intersection, any_hit,
3800*61046927SAndroid Build Coastguard Worker devinfo);
3801*61046927SAndroid Build Coastguard Worker
3802*61046927SAndroid Build Coastguard Worker result = compile_upload_rt_shader(pipeline, cache,
3803*61046927SAndroid Build Coastguard Worker intersection,
3804*61046927SAndroid Build Coastguard Worker &stages[intersection_idx],
3805*61046927SAndroid Build Coastguard Worker tmp_group_ctx);
3806*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_group_ctx);
3807*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
3808*61046927SAndroid Build Coastguard Worker return result;
3809*61046927SAndroid Build Coastguard Worker }
3810*61046927SAndroid Build Coastguard Worker
3811*61046927SAndroid Build Coastguard Worker group->intersection = stages[intersection_idx].bin;
3812*61046927SAndroid Build Coastguard Worker break;
3813*61046927SAndroid Build Coastguard Worker }
3814*61046927SAndroid Build Coastguard Worker
3815*61046927SAndroid Build Coastguard Worker default:
3816*61046927SAndroid Build Coastguard Worker unreachable("Invalid ray tracing shader group type");
3817*61046927SAndroid Build Coastguard Worker }
3818*61046927SAndroid Build Coastguard Worker }
3819*61046927SAndroid Build Coastguard Worker
3820*61046927SAndroid Build Coastguard Worker pipeline_feedback.duration = os_time_get_nano() - pipeline_start;
3821*61046927SAndroid Build Coastguard Worker
3822*61046927SAndroid Build Coastguard Worker const VkPipelineCreationFeedbackCreateInfo *create_feedback =
3823*61046927SAndroid Build Coastguard Worker vk_find_struct_const(info->pNext, PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
3824*61046927SAndroid Build Coastguard Worker if (create_feedback) {
3825*61046927SAndroid Build Coastguard Worker *create_feedback->pPipelineCreationFeedback = pipeline_feedback;
3826*61046927SAndroid Build Coastguard Worker
3827*61046927SAndroid Build Coastguard Worker uint32_t stage_count = create_feedback->pipelineStageCreationFeedbackCount;
3828*61046927SAndroid Build Coastguard Worker assert(stage_count == 0 || info->stageCount == stage_count);
3829*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < stage_count; i++) {
3830*61046927SAndroid Build Coastguard Worker gl_shader_stage s = vk_to_mesa_shader_stage(info->pStages[i].stage);
3831*61046927SAndroid Build Coastguard Worker create_feedback->pPipelineStageCreationFeedbacks[i] = stages[s].feedback;
3832*61046927SAndroid Build Coastguard Worker }
3833*61046927SAndroid Build Coastguard Worker }
3834*61046927SAndroid Build Coastguard Worker
3835*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3836*61046927SAndroid Build Coastguard Worker }
3837*61046927SAndroid Build Coastguard Worker
3838*61046927SAndroid Build Coastguard Worker VkResult
anv_device_init_rt_shaders(struct anv_device * device)3839*61046927SAndroid Build Coastguard Worker anv_device_init_rt_shaders(struct anv_device *device)
3840*61046927SAndroid Build Coastguard Worker {
3841*61046927SAndroid Build Coastguard Worker device->bvh_build_method = ANV_BVH_BUILD_METHOD_NEW_SAH;
3842*61046927SAndroid Build Coastguard Worker
3843*61046927SAndroid Build Coastguard Worker if (!device->vk.enabled_extensions.KHR_ray_tracing_pipeline)
3844*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3845*61046927SAndroid Build Coastguard Worker
3846*61046927SAndroid Build Coastguard Worker bool cache_hit;
3847*61046927SAndroid Build Coastguard Worker
3848*61046927SAndroid Build Coastguard Worker struct anv_push_descriptor_info empty_push_desc_info = {};
3849*61046927SAndroid Build Coastguard Worker struct anv_pipeline_bind_map empty_bind_map = {};
3850*61046927SAndroid Build Coastguard Worker struct brw_rt_trampoline {
3851*61046927SAndroid Build Coastguard Worker char name[16];
3852*61046927SAndroid Build Coastguard Worker struct brw_cs_prog_key key;
3853*61046927SAndroid Build Coastguard Worker } trampoline_key = {
3854*61046927SAndroid Build Coastguard Worker .name = "rt-trampoline",
3855*61046927SAndroid Build Coastguard Worker };
3856*61046927SAndroid Build Coastguard Worker device->rt_trampoline =
3857*61046927SAndroid Build Coastguard Worker anv_device_search_for_kernel(device, device->internal_cache,
3858*61046927SAndroid Build Coastguard Worker &trampoline_key, sizeof(trampoline_key),
3859*61046927SAndroid Build Coastguard Worker &cache_hit);
3860*61046927SAndroid Build Coastguard Worker if (device->rt_trampoline == NULL) {
3861*61046927SAndroid Build Coastguard Worker
3862*61046927SAndroid Build Coastguard Worker void *tmp_ctx = ralloc_context(NULL);
3863*61046927SAndroid Build Coastguard Worker nir_shader *trampoline_nir =
3864*61046927SAndroid Build Coastguard Worker brw_nir_create_raygen_trampoline(device->physical->compiler, tmp_ctx);
3865*61046927SAndroid Build Coastguard Worker
3866*61046927SAndroid Build Coastguard Worker trampoline_nir->info.subgroup_size = SUBGROUP_SIZE_REQUIRE_16;
3867*61046927SAndroid Build Coastguard Worker
3868*61046927SAndroid Build Coastguard Worker uint32_t dummy_params[4] = { 0, };
3869*61046927SAndroid Build Coastguard Worker struct brw_cs_prog_data trampoline_prog_data = {
3870*61046927SAndroid Build Coastguard Worker .base.nr_params = 4,
3871*61046927SAndroid Build Coastguard Worker .base.param = dummy_params,
3872*61046927SAndroid Build Coastguard Worker .uses_inline_data = true,
3873*61046927SAndroid Build Coastguard Worker .uses_btd_stack_ids = true,
3874*61046927SAndroid Build Coastguard Worker };
3875*61046927SAndroid Build Coastguard Worker struct brw_compile_cs_params params = {
3876*61046927SAndroid Build Coastguard Worker .base = {
3877*61046927SAndroid Build Coastguard Worker .nir = trampoline_nir,
3878*61046927SAndroid Build Coastguard Worker .log_data = device,
3879*61046927SAndroid Build Coastguard Worker .mem_ctx = tmp_ctx,
3880*61046927SAndroid Build Coastguard Worker },
3881*61046927SAndroid Build Coastguard Worker .key = &trampoline_key.key,
3882*61046927SAndroid Build Coastguard Worker .prog_data = &trampoline_prog_data,
3883*61046927SAndroid Build Coastguard Worker };
3884*61046927SAndroid Build Coastguard Worker const unsigned *tramp_data =
3885*61046927SAndroid Build Coastguard Worker brw_compile_cs(device->physical->compiler, ¶ms);
3886*61046927SAndroid Build Coastguard Worker
3887*61046927SAndroid Build Coastguard Worker struct anv_shader_upload_params upload_params = {
3888*61046927SAndroid Build Coastguard Worker .stage = MESA_SHADER_COMPUTE,
3889*61046927SAndroid Build Coastguard Worker .key_data = &trampoline_key,
3890*61046927SAndroid Build Coastguard Worker .key_size = sizeof(trampoline_key),
3891*61046927SAndroid Build Coastguard Worker .kernel_data = tramp_data,
3892*61046927SAndroid Build Coastguard Worker .kernel_size = trampoline_prog_data.base.program_size,
3893*61046927SAndroid Build Coastguard Worker .prog_data = &trampoline_prog_data.base,
3894*61046927SAndroid Build Coastguard Worker .prog_data_size = sizeof(trampoline_prog_data),
3895*61046927SAndroid Build Coastguard Worker .bind_map = &empty_bind_map,
3896*61046927SAndroid Build Coastguard Worker .push_desc_info = &empty_push_desc_info,
3897*61046927SAndroid Build Coastguard Worker };
3898*61046927SAndroid Build Coastguard Worker
3899*61046927SAndroid Build Coastguard Worker device->rt_trampoline =
3900*61046927SAndroid Build Coastguard Worker anv_device_upload_kernel(device, device->internal_cache,
3901*61046927SAndroid Build Coastguard Worker &upload_params);
3902*61046927SAndroid Build Coastguard Worker
3903*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_ctx);
3904*61046927SAndroid Build Coastguard Worker
3905*61046927SAndroid Build Coastguard Worker if (device->rt_trampoline == NULL)
3906*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
3907*61046927SAndroid Build Coastguard Worker }
3908*61046927SAndroid Build Coastguard Worker
3909*61046927SAndroid Build Coastguard Worker /* The cache already has a reference and it's not going anywhere so there
3910*61046927SAndroid Build Coastguard Worker * is no need to hold a second reference.
3911*61046927SAndroid Build Coastguard Worker */
3912*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, device->rt_trampoline);
3913*61046927SAndroid Build Coastguard Worker
3914*61046927SAndroid Build Coastguard Worker struct brw_rt_trivial_return {
3915*61046927SAndroid Build Coastguard Worker char name[16];
3916*61046927SAndroid Build Coastguard Worker struct brw_bs_prog_key key;
3917*61046927SAndroid Build Coastguard Worker } return_key = {
3918*61046927SAndroid Build Coastguard Worker .name = "rt-trivial-ret",
3919*61046927SAndroid Build Coastguard Worker };
3920*61046927SAndroid Build Coastguard Worker device->rt_trivial_return =
3921*61046927SAndroid Build Coastguard Worker anv_device_search_for_kernel(device, device->internal_cache,
3922*61046927SAndroid Build Coastguard Worker &return_key, sizeof(return_key),
3923*61046927SAndroid Build Coastguard Worker &cache_hit);
3924*61046927SAndroid Build Coastguard Worker if (device->rt_trivial_return == NULL) {
3925*61046927SAndroid Build Coastguard Worker void *tmp_ctx = ralloc_context(NULL);
3926*61046927SAndroid Build Coastguard Worker nir_shader *trivial_return_nir =
3927*61046927SAndroid Build Coastguard Worker brw_nir_create_trivial_return_shader(device->physical->compiler, tmp_ctx);
3928*61046927SAndroid Build Coastguard Worker
3929*61046927SAndroid Build Coastguard Worker NIR_PASS_V(trivial_return_nir, brw_nir_lower_rt_intrinsics, device->info);
3930*61046927SAndroid Build Coastguard Worker
3931*61046927SAndroid Build Coastguard Worker struct brw_bs_prog_data return_prog_data = { 0, };
3932*61046927SAndroid Build Coastguard Worker struct brw_compile_bs_params params = {
3933*61046927SAndroid Build Coastguard Worker .base = {
3934*61046927SAndroid Build Coastguard Worker .nir = trivial_return_nir,
3935*61046927SAndroid Build Coastguard Worker .log_data = device,
3936*61046927SAndroid Build Coastguard Worker .mem_ctx = tmp_ctx,
3937*61046927SAndroid Build Coastguard Worker },
3938*61046927SAndroid Build Coastguard Worker .key = &return_key.key,
3939*61046927SAndroid Build Coastguard Worker .prog_data = &return_prog_data,
3940*61046927SAndroid Build Coastguard Worker };
3941*61046927SAndroid Build Coastguard Worker const unsigned *return_data =
3942*61046927SAndroid Build Coastguard Worker brw_compile_bs(device->physical->compiler, ¶ms);
3943*61046927SAndroid Build Coastguard Worker
3944*61046927SAndroid Build Coastguard Worker struct anv_shader_upload_params upload_params = {
3945*61046927SAndroid Build Coastguard Worker .stage = MESA_SHADER_CALLABLE,
3946*61046927SAndroid Build Coastguard Worker .key_data = &return_key,
3947*61046927SAndroid Build Coastguard Worker .key_size = sizeof(return_key),
3948*61046927SAndroid Build Coastguard Worker .kernel_data = return_data,
3949*61046927SAndroid Build Coastguard Worker .kernel_size = return_prog_data.base.program_size,
3950*61046927SAndroid Build Coastguard Worker .prog_data = &return_prog_data.base,
3951*61046927SAndroid Build Coastguard Worker .prog_data_size = sizeof(return_prog_data),
3952*61046927SAndroid Build Coastguard Worker .bind_map = &empty_bind_map,
3953*61046927SAndroid Build Coastguard Worker .push_desc_info = &empty_push_desc_info,
3954*61046927SAndroid Build Coastguard Worker };
3955*61046927SAndroid Build Coastguard Worker
3956*61046927SAndroid Build Coastguard Worker device->rt_trivial_return =
3957*61046927SAndroid Build Coastguard Worker anv_device_upload_kernel(device, device->internal_cache,
3958*61046927SAndroid Build Coastguard Worker &upload_params);
3959*61046927SAndroid Build Coastguard Worker
3960*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_ctx);
3961*61046927SAndroid Build Coastguard Worker
3962*61046927SAndroid Build Coastguard Worker if (device->rt_trivial_return == NULL)
3963*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
3964*61046927SAndroid Build Coastguard Worker }
3965*61046927SAndroid Build Coastguard Worker
3966*61046927SAndroid Build Coastguard Worker /* The cache already has a reference and it's not going anywhere so there
3967*61046927SAndroid Build Coastguard Worker * is no need to hold a second reference.
3968*61046927SAndroid Build Coastguard Worker */
3969*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, device->rt_trivial_return);
3970*61046927SAndroid Build Coastguard Worker
3971*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
3972*61046927SAndroid Build Coastguard Worker }
3973*61046927SAndroid Build Coastguard Worker
3974*61046927SAndroid Build Coastguard Worker void
anv_device_finish_rt_shaders(struct anv_device * device)3975*61046927SAndroid Build Coastguard Worker anv_device_finish_rt_shaders(struct anv_device *device)
3976*61046927SAndroid Build Coastguard Worker {
3977*61046927SAndroid Build Coastguard Worker if (!device->vk.enabled_extensions.KHR_ray_tracing_pipeline)
3978*61046927SAndroid Build Coastguard Worker return;
3979*61046927SAndroid Build Coastguard Worker }
3980*61046927SAndroid Build Coastguard Worker
3981*61046927SAndroid Build Coastguard Worker static void
anv_ray_tracing_pipeline_init(struct anv_ray_tracing_pipeline * pipeline,struct anv_device * device,struct vk_pipeline_cache * cache,const VkRayTracingPipelineCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * alloc)3982*61046927SAndroid Build Coastguard Worker anv_ray_tracing_pipeline_init(struct anv_ray_tracing_pipeline *pipeline,
3983*61046927SAndroid Build Coastguard Worker struct anv_device *device,
3984*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache *cache,
3985*61046927SAndroid Build Coastguard Worker const VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
3986*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks *alloc)
3987*61046927SAndroid Build Coastguard Worker {
3988*61046927SAndroid Build Coastguard Worker util_dynarray_init(&pipeline->shaders, pipeline->base.mem_ctx);
3989*61046927SAndroid Build Coastguard Worker
3990*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, pCreateInfo->layout);
3991*61046927SAndroid Build Coastguard Worker anv_pipeline_init_layout(&pipeline->base, pipeline_layout);
3992*61046927SAndroid Build Coastguard Worker
3993*61046927SAndroid Build Coastguard Worker anv_pipeline_setup_l3_config(&pipeline->base, /* needs_slm */ false);
3994*61046927SAndroid Build Coastguard Worker }
3995*61046927SAndroid Build Coastguard Worker
3996*61046927SAndroid Build Coastguard Worker static void
assert_rt_stage_index_valid(const VkRayTracingPipelineCreateInfoKHR * pCreateInfo,uint32_t stage_idx,VkShaderStageFlags valid_stages)3997*61046927SAndroid Build Coastguard Worker assert_rt_stage_index_valid(const VkRayTracingPipelineCreateInfoKHR* pCreateInfo,
3998*61046927SAndroid Build Coastguard Worker uint32_t stage_idx,
3999*61046927SAndroid Build Coastguard Worker VkShaderStageFlags valid_stages)
4000*61046927SAndroid Build Coastguard Worker {
4001*61046927SAndroid Build Coastguard Worker if (stage_idx == VK_SHADER_UNUSED_KHR)
4002*61046927SAndroid Build Coastguard Worker return;
4003*61046927SAndroid Build Coastguard Worker
4004*61046927SAndroid Build Coastguard Worker assert(stage_idx <= pCreateInfo->stageCount);
4005*61046927SAndroid Build Coastguard Worker assert(util_bitcount(pCreateInfo->pStages[stage_idx].stage) == 1);
4006*61046927SAndroid Build Coastguard Worker assert(pCreateInfo->pStages[stage_idx].stage & valid_stages);
4007*61046927SAndroid Build Coastguard Worker }
4008*61046927SAndroid Build Coastguard Worker
4009*61046927SAndroid Build Coastguard Worker static VkResult
anv_ray_tracing_pipeline_create(VkDevice _device,struct vk_pipeline_cache * cache,const VkRayTracingPipelineCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)4010*61046927SAndroid Build Coastguard Worker anv_ray_tracing_pipeline_create(
4011*61046927SAndroid Build Coastguard Worker VkDevice _device,
4012*61046927SAndroid Build Coastguard Worker struct vk_pipeline_cache * cache,
4013*61046927SAndroid Build Coastguard Worker const VkRayTracingPipelineCreateInfoKHR* pCreateInfo,
4014*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator,
4015*61046927SAndroid Build Coastguard Worker VkPipeline* pPipeline)
4016*61046927SAndroid Build Coastguard Worker {
4017*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_device, device, _device);
4018*61046927SAndroid Build Coastguard Worker VkResult result;
4019*61046927SAndroid Build Coastguard Worker
4020*61046927SAndroid Build Coastguard Worker assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR);
4021*61046927SAndroid Build Coastguard Worker
4022*61046927SAndroid Build Coastguard Worker uint32_t group_count = pCreateInfo->groupCount;
4023*61046927SAndroid Build Coastguard Worker if (pCreateInfo->pLibraryInfo) {
4024*61046927SAndroid Build Coastguard Worker for (uint32_t l = 0; l < pCreateInfo->pLibraryInfo->libraryCount; l++) {
4025*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, library,
4026*61046927SAndroid Build Coastguard Worker pCreateInfo->pLibraryInfo->pLibraries[l]);
4027*61046927SAndroid Build Coastguard Worker struct anv_ray_tracing_pipeline *rt_library =
4028*61046927SAndroid Build Coastguard Worker anv_pipeline_to_ray_tracing(library);
4029*61046927SAndroid Build Coastguard Worker group_count += rt_library->group_count;
4030*61046927SAndroid Build Coastguard Worker }
4031*61046927SAndroid Build Coastguard Worker }
4032*61046927SAndroid Build Coastguard Worker
4033*61046927SAndroid Build Coastguard Worker VK_MULTIALLOC(ma);
4034*61046927SAndroid Build Coastguard Worker VK_MULTIALLOC_DECL(&ma, struct anv_ray_tracing_pipeline, pipeline, 1);
4035*61046927SAndroid Build Coastguard Worker VK_MULTIALLOC_DECL(&ma, struct anv_rt_shader_group, groups, group_count);
4036*61046927SAndroid Build Coastguard Worker if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, pAllocator,
4037*61046927SAndroid Build Coastguard Worker VK_SYSTEM_ALLOCATION_SCOPE_DEVICE))
4038*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
4039*61046927SAndroid Build Coastguard Worker
4040*61046927SAndroid Build Coastguard Worker result = anv_pipeline_init(&pipeline->base, device,
4041*61046927SAndroid Build Coastguard Worker ANV_PIPELINE_RAY_TRACING,
4042*61046927SAndroid Build Coastguard Worker vk_rt_pipeline_create_flags(pCreateInfo),
4043*61046927SAndroid Build Coastguard Worker pAllocator);
4044*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
4045*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
4046*61046927SAndroid Build Coastguard Worker return result;
4047*61046927SAndroid Build Coastguard Worker }
4048*61046927SAndroid Build Coastguard Worker
4049*61046927SAndroid Build Coastguard Worker pipeline->group_count = group_count;
4050*61046927SAndroid Build Coastguard Worker pipeline->groups = groups;
4051*61046927SAndroid Build Coastguard Worker
4052*61046927SAndroid Build Coastguard Worker ASSERTED const VkShaderStageFlags ray_tracing_stages =
4053*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_RAYGEN_BIT_KHR |
4054*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
4055*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
4056*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_MISS_BIT_KHR |
4057*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
4058*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_CALLABLE_BIT_KHR;
4059*61046927SAndroid Build Coastguard Worker
4060*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCreateInfo->stageCount; i++)
4061*61046927SAndroid Build Coastguard Worker assert((pCreateInfo->pStages[i].stage & ~ray_tracing_stages) == 0);
4062*61046927SAndroid Build Coastguard Worker
4063*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < pCreateInfo->groupCount; i++) {
4064*61046927SAndroid Build Coastguard Worker const VkRayTracingShaderGroupCreateInfoKHR *ginfo =
4065*61046927SAndroid Build Coastguard Worker &pCreateInfo->pGroups[i];
4066*61046927SAndroid Build Coastguard Worker assert_rt_stage_index_valid(pCreateInfo, ginfo->generalShader,
4067*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_RAYGEN_BIT_KHR |
4068*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_MISS_BIT_KHR |
4069*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_CALLABLE_BIT_KHR);
4070*61046927SAndroid Build Coastguard Worker assert_rt_stage_index_valid(pCreateInfo, ginfo->closestHitShader,
4071*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);
4072*61046927SAndroid Build Coastguard Worker assert_rt_stage_index_valid(pCreateInfo, ginfo->anyHitShader,
4073*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_ANY_HIT_BIT_KHR);
4074*61046927SAndroid Build Coastguard Worker assert_rt_stage_index_valid(pCreateInfo, ginfo->intersectionShader,
4075*61046927SAndroid Build Coastguard Worker VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
4076*61046927SAndroid Build Coastguard Worker switch (ginfo->type) {
4077*61046927SAndroid Build Coastguard Worker case VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR:
4078*61046927SAndroid Build Coastguard Worker assert(ginfo->generalShader < pCreateInfo->stageCount);
4079*61046927SAndroid Build Coastguard Worker assert(ginfo->anyHitShader == VK_SHADER_UNUSED_KHR);
4080*61046927SAndroid Build Coastguard Worker assert(ginfo->closestHitShader == VK_SHADER_UNUSED_KHR);
4081*61046927SAndroid Build Coastguard Worker assert(ginfo->intersectionShader == VK_SHADER_UNUSED_KHR);
4082*61046927SAndroid Build Coastguard Worker break;
4083*61046927SAndroid Build Coastguard Worker
4084*61046927SAndroid Build Coastguard Worker case VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR:
4085*61046927SAndroid Build Coastguard Worker assert(ginfo->generalShader == VK_SHADER_UNUSED_KHR);
4086*61046927SAndroid Build Coastguard Worker assert(ginfo->intersectionShader == VK_SHADER_UNUSED_KHR);
4087*61046927SAndroid Build Coastguard Worker break;
4088*61046927SAndroid Build Coastguard Worker
4089*61046927SAndroid Build Coastguard Worker case VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR:
4090*61046927SAndroid Build Coastguard Worker assert(ginfo->generalShader == VK_SHADER_UNUSED_KHR);
4091*61046927SAndroid Build Coastguard Worker break;
4092*61046927SAndroid Build Coastguard Worker
4093*61046927SAndroid Build Coastguard Worker default:
4094*61046927SAndroid Build Coastguard Worker unreachable("Invalid ray-tracing shader group type");
4095*61046927SAndroid Build Coastguard Worker }
4096*61046927SAndroid Build Coastguard Worker }
4097*61046927SAndroid Build Coastguard Worker
4098*61046927SAndroid Build Coastguard Worker anv_ray_tracing_pipeline_init(pipeline, device, cache,
4099*61046927SAndroid Build Coastguard Worker pCreateInfo, pAllocator);
4100*61046927SAndroid Build Coastguard Worker
4101*61046927SAndroid Build Coastguard Worker void *tmp_ctx = ralloc_context(NULL);
4102*61046927SAndroid Build Coastguard Worker
4103*61046927SAndroid Build Coastguard Worker struct anv_pipeline_stage *stages =
4104*61046927SAndroid Build Coastguard Worker anv_pipeline_init_ray_tracing_stages(pipeline, pCreateInfo, tmp_ctx);
4105*61046927SAndroid Build Coastguard Worker
4106*61046927SAndroid Build Coastguard Worker result = anv_pipeline_compile_ray_tracing(pipeline, tmp_ctx, stages,
4107*61046927SAndroid Build Coastguard Worker cache, pCreateInfo);
4108*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
4109*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_ctx);
4110*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&pipeline->shaders, struct anv_shader_bin *, shader)
4111*61046927SAndroid Build Coastguard Worker anv_shader_bin_unref(device, *shader);
4112*61046927SAndroid Build Coastguard Worker anv_pipeline_finish(&pipeline->base, device);
4113*61046927SAndroid Build Coastguard Worker vk_free2(&device->vk.alloc, pAllocator, pipeline);
4114*61046927SAndroid Build Coastguard Worker return result;
4115*61046927SAndroid Build Coastguard Worker }
4116*61046927SAndroid Build Coastguard Worker
4117*61046927SAndroid Build Coastguard Worker /* Compute the size of the scratch BO (for register spilling) by taking the
4118*61046927SAndroid Build Coastguard Worker * max of all the shaders in the pipeline. Also add the shaders to the list
4119*61046927SAndroid Build Coastguard Worker * of executables.
4120*61046927SAndroid Build Coastguard Worker */
4121*61046927SAndroid Build Coastguard Worker uint32_t stack_max[MESA_VULKAN_SHADER_STAGES] = {};
4122*61046927SAndroid Build Coastguard Worker for (uint32_t s = 0; s < pCreateInfo->stageCount; s++) {
4123*61046927SAndroid Build Coastguard Worker util_dynarray_append(&pipeline->shaders,
4124*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *,
4125*61046927SAndroid Build Coastguard Worker stages[s].bin);
4126*61046927SAndroid Build Coastguard Worker
4127*61046927SAndroid Build Coastguard Worker uint32_t stack_size =
4128*61046927SAndroid Build Coastguard Worker brw_bs_prog_data_const(stages[s].bin->prog_data)->max_stack_size;
4129*61046927SAndroid Build Coastguard Worker stack_max[stages[s].stage] = MAX2(stack_max[stages[s].stage], stack_size);
4130*61046927SAndroid Build Coastguard Worker
4131*61046927SAndroid Build Coastguard Worker anv_pipeline_account_shader(&pipeline->base, stages[s].bin);
4132*61046927SAndroid Build Coastguard Worker }
4133*61046927SAndroid Build Coastguard Worker
4134*61046927SAndroid Build Coastguard Worker anv_pipeline_compute_ray_tracing_stacks(pipeline, pCreateInfo, stack_max);
4135*61046927SAndroid Build Coastguard Worker
4136*61046927SAndroid Build Coastguard Worker if (pCreateInfo->pLibraryInfo) {
4137*61046927SAndroid Build Coastguard Worker uint32_t g = pCreateInfo->groupCount;
4138*61046927SAndroid Build Coastguard Worker for (uint32_t l = 0; l < pCreateInfo->pLibraryInfo->libraryCount; l++) {
4139*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, library,
4140*61046927SAndroid Build Coastguard Worker pCreateInfo->pLibraryInfo->pLibraries[l]);
4141*61046927SAndroid Build Coastguard Worker struct anv_ray_tracing_pipeline *rt_library =
4142*61046927SAndroid Build Coastguard Worker anv_pipeline_to_ray_tracing(library);
4143*61046927SAndroid Build Coastguard Worker for (uint32_t lg = 0; lg < rt_library->group_count; lg++) {
4144*61046927SAndroid Build Coastguard Worker pipeline->groups[g] = rt_library->groups[lg];
4145*61046927SAndroid Build Coastguard Worker pipeline->groups[g].imported = true;
4146*61046927SAndroid Build Coastguard Worker g++;
4147*61046927SAndroid Build Coastguard Worker }
4148*61046927SAndroid Build Coastguard Worker
4149*61046927SAndroid Build Coastguard Worker /* Account for shaders in the library. */
4150*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&rt_library->shaders,
4151*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *, shader) {
4152*61046927SAndroid Build Coastguard Worker util_dynarray_append(&pipeline->shaders,
4153*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *,
4154*61046927SAndroid Build Coastguard Worker anv_shader_bin_ref(*shader));
4155*61046927SAndroid Build Coastguard Worker anv_pipeline_account_shader(&pipeline->base, *shader);
4156*61046927SAndroid Build Coastguard Worker }
4157*61046927SAndroid Build Coastguard Worker
4158*61046927SAndroid Build Coastguard Worker /* Add the library shaders to this pipeline's executables. */
4159*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&rt_library->base.executables,
4160*61046927SAndroid Build Coastguard Worker struct anv_pipeline_executable, exe) {
4161*61046927SAndroid Build Coastguard Worker util_dynarray_append(&pipeline->base.executables,
4162*61046927SAndroid Build Coastguard Worker struct anv_pipeline_executable, *exe);
4163*61046927SAndroid Build Coastguard Worker }
4164*61046927SAndroid Build Coastguard Worker
4165*61046927SAndroid Build Coastguard Worker pipeline->base.active_stages |= rt_library->base.active_stages;
4166*61046927SAndroid Build Coastguard Worker }
4167*61046927SAndroid Build Coastguard Worker }
4168*61046927SAndroid Build Coastguard Worker
4169*61046927SAndroid Build Coastguard Worker anv_genX(device->info, ray_tracing_pipeline_emit)(pipeline);
4170*61046927SAndroid Build Coastguard Worker
4171*61046927SAndroid Build Coastguard Worker ralloc_free(tmp_ctx);
4172*61046927SAndroid Build Coastguard Worker
4173*61046927SAndroid Build Coastguard Worker ANV_RMV(rt_pipeline_create, device, pipeline, false);
4174*61046927SAndroid Build Coastguard Worker
4175*61046927SAndroid Build Coastguard Worker *pPipeline = anv_pipeline_to_handle(&pipeline->base);
4176*61046927SAndroid Build Coastguard Worker
4177*61046927SAndroid Build Coastguard Worker return pipeline->base.batch.status;
4178*61046927SAndroid Build Coastguard Worker }
4179*61046927SAndroid Build Coastguard Worker
4180*61046927SAndroid Build Coastguard Worker VkResult
anv_CreateRayTracingPipelinesKHR(VkDevice _device,VkDeferredOperationKHR deferredOperation,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkRayTracingPipelineCreateInfoKHR * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)4181*61046927SAndroid Build Coastguard Worker anv_CreateRayTracingPipelinesKHR(
4182*61046927SAndroid Build Coastguard Worker VkDevice _device,
4183*61046927SAndroid Build Coastguard Worker VkDeferredOperationKHR deferredOperation,
4184*61046927SAndroid Build Coastguard Worker VkPipelineCache pipelineCache,
4185*61046927SAndroid Build Coastguard Worker uint32_t createInfoCount,
4186*61046927SAndroid Build Coastguard Worker const VkRayTracingPipelineCreateInfoKHR* pCreateInfos,
4187*61046927SAndroid Build Coastguard Worker const VkAllocationCallbacks* pAllocator,
4188*61046927SAndroid Build Coastguard Worker VkPipeline* pPipelines)
4189*61046927SAndroid Build Coastguard Worker {
4190*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(vk_pipeline_cache, pipeline_cache, pipelineCache);
4191*61046927SAndroid Build Coastguard Worker
4192*61046927SAndroid Build Coastguard Worker VkResult result = VK_SUCCESS;
4193*61046927SAndroid Build Coastguard Worker
4194*61046927SAndroid Build Coastguard Worker unsigned i;
4195*61046927SAndroid Build Coastguard Worker for (i = 0; i < createInfoCount; i++) {
4196*61046927SAndroid Build Coastguard Worker const VkPipelineCreateFlags2KHR flags =
4197*61046927SAndroid Build Coastguard Worker vk_rt_pipeline_create_flags(&pCreateInfos[i]);
4198*61046927SAndroid Build Coastguard Worker VkResult res = anv_ray_tracing_pipeline_create(_device, pipeline_cache,
4199*61046927SAndroid Build Coastguard Worker &pCreateInfos[i],
4200*61046927SAndroid Build Coastguard Worker pAllocator, &pPipelines[i]);
4201*61046927SAndroid Build Coastguard Worker
4202*61046927SAndroid Build Coastguard Worker if (res != VK_SUCCESS) {
4203*61046927SAndroid Build Coastguard Worker result = res;
4204*61046927SAndroid Build Coastguard Worker if (flags & VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR)
4205*61046927SAndroid Build Coastguard Worker break;
4206*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
4207*61046927SAndroid Build Coastguard Worker }
4208*61046927SAndroid Build Coastguard Worker }
4209*61046927SAndroid Build Coastguard Worker
4210*61046927SAndroid Build Coastguard Worker for (; i < createInfoCount; i++)
4211*61046927SAndroid Build Coastguard Worker pPipelines[i] = VK_NULL_HANDLE;
4212*61046927SAndroid Build Coastguard Worker
4213*61046927SAndroid Build Coastguard Worker return result;
4214*61046927SAndroid Build Coastguard Worker }
4215*61046927SAndroid Build Coastguard Worker
4216*61046927SAndroid Build Coastguard Worker #define WRITE_STR(field, ...) ({ \
4217*61046927SAndroid Build Coastguard Worker memset(field, 0, sizeof(field)); \
4218*61046927SAndroid Build Coastguard Worker UNUSED int i = snprintf(field, sizeof(field), __VA_ARGS__); \
4219*61046927SAndroid Build Coastguard Worker assert(i > 0 && i < sizeof(field)); \
4220*61046927SAndroid Build Coastguard Worker })
4221*61046927SAndroid Build Coastguard Worker
anv_GetPipelineExecutablePropertiesKHR(VkDevice device,const VkPipelineInfoKHR * pPipelineInfo,uint32_t * pExecutableCount,VkPipelineExecutablePropertiesKHR * pProperties)4222*61046927SAndroid Build Coastguard Worker VkResult anv_GetPipelineExecutablePropertiesKHR(
4223*61046927SAndroid Build Coastguard Worker VkDevice device,
4224*61046927SAndroid Build Coastguard Worker const VkPipelineInfoKHR* pPipelineInfo,
4225*61046927SAndroid Build Coastguard Worker uint32_t* pExecutableCount,
4226*61046927SAndroid Build Coastguard Worker VkPipelineExecutablePropertiesKHR* pProperties)
4227*61046927SAndroid Build Coastguard Worker {
4228*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline, pPipelineInfo->pipeline);
4229*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutablePropertiesKHR, out,
4230*61046927SAndroid Build Coastguard Worker pProperties, pExecutableCount);
4231*61046927SAndroid Build Coastguard Worker
4232*61046927SAndroid Build Coastguard Worker util_dynarray_foreach (&pipeline->executables, struct anv_pipeline_executable, exe) {
4233*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutablePropertiesKHR, &out, props) {
4234*61046927SAndroid Build Coastguard Worker gl_shader_stage stage = exe->stage;
4235*61046927SAndroid Build Coastguard Worker props->stages = mesa_to_vk_shader_stage(stage);
4236*61046927SAndroid Build Coastguard Worker
4237*61046927SAndroid Build Coastguard Worker unsigned simd_width = exe->stats.dispatch_width;
4238*61046927SAndroid Build Coastguard Worker if (stage == MESA_SHADER_FRAGMENT) {
4239*61046927SAndroid Build Coastguard Worker if (exe->stats.max_polygons > 1)
4240*61046927SAndroid Build Coastguard Worker WRITE_STR(props->name, "SIMD%dx%d %s",
4241*61046927SAndroid Build Coastguard Worker exe->stats.max_polygons,
4242*61046927SAndroid Build Coastguard Worker simd_width / exe->stats.max_polygons,
4243*61046927SAndroid Build Coastguard Worker _mesa_shader_stage_to_string(stage));
4244*61046927SAndroid Build Coastguard Worker else
4245*61046927SAndroid Build Coastguard Worker WRITE_STR(props->name, "%s%d %s",
4246*61046927SAndroid Build Coastguard Worker simd_width ? "SIMD" : "vec",
4247*61046927SAndroid Build Coastguard Worker simd_width ? simd_width : 4,
4248*61046927SAndroid Build Coastguard Worker _mesa_shader_stage_to_string(stage));
4249*61046927SAndroid Build Coastguard Worker } else {
4250*61046927SAndroid Build Coastguard Worker WRITE_STR(props->name, "%s", _mesa_shader_stage_to_string(stage));
4251*61046927SAndroid Build Coastguard Worker }
4252*61046927SAndroid Build Coastguard Worker WRITE_STR(props->description, "%s%d %s shader",
4253*61046927SAndroid Build Coastguard Worker simd_width ? "SIMD" : "vec",
4254*61046927SAndroid Build Coastguard Worker simd_width ? simd_width : 4,
4255*61046927SAndroid Build Coastguard Worker _mesa_shader_stage_to_string(stage));
4256*61046927SAndroid Build Coastguard Worker
4257*61046927SAndroid Build Coastguard Worker /* The compiler gives us a dispatch width of 0 for vec4 but Vulkan
4258*61046927SAndroid Build Coastguard Worker * wants a subgroup size of 1.
4259*61046927SAndroid Build Coastguard Worker */
4260*61046927SAndroid Build Coastguard Worker props->subgroupSize = MAX2(simd_width, 1);
4261*61046927SAndroid Build Coastguard Worker }
4262*61046927SAndroid Build Coastguard Worker }
4263*61046927SAndroid Build Coastguard Worker
4264*61046927SAndroid Build Coastguard Worker return vk_outarray_status(&out);
4265*61046927SAndroid Build Coastguard Worker }
4266*61046927SAndroid Build Coastguard Worker
4267*61046927SAndroid Build Coastguard Worker static const struct anv_pipeline_executable *
anv_pipeline_get_executable(struct anv_pipeline * pipeline,uint32_t index)4268*61046927SAndroid Build Coastguard Worker anv_pipeline_get_executable(struct anv_pipeline *pipeline, uint32_t index)
4269*61046927SAndroid Build Coastguard Worker {
4270*61046927SAndroid Build Coastguard Worker assert(index < util_dynarray_num_elements(&pipeline->executables,
4271*61046927SAndroid Build Coastguard Worker struct anv_pipeline_executable));
4272*61046927SAndroid Build Coastguard Worker return util_dynarray_element(
4273*61046927SAndroid Build Coastguard Worker &pipeline->executables, struct anv_pipeline_executable, index);
4274*61046927SAndroid Build Coastguard Worker }
4275*61046927SAndroid Build Coastguard Worker
anv_GetPipelineExecutableStatisticsKHR(VkDevice device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pStatisticCount,VkPipelineExecutableStatisticKHR * pStatistics)4276*61046927SAndroid Build Coastguard Worker VkResult anv_GetPipelineExecutableStatisticsKHR(
4277*61046927SAndroid Build Coastguard Worker VkDevice device,
4278*61046927SAndroid Build Coastguard Worker const VkPipelineExecutableInfoKHR* pExecutableInfo,
4279*61046927SAndroid Build Coastguard Worker uint32_t* pStatisticCount,
4280*61046927SAndroid Build Coastguard Worker VkPipelineExecutableStatisticKHR* pStatistics)
4281*61046927SAndroid Build Coastguard Worker {
4282*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline, pExecutableInfo->pipeline);
4283*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutableStatisticKHR, out,
4284*61046927SAndroid Build Coastguard Worker pStatistics, pStatisticCount);
4285*61046927SAndroid Build Coastguard Worker
4286*61046927SAndroid Build Coastguard Worker const struct anv_pipeline_executable *exe =
4287*61046927SAndroid Build Coastguard Worker anv_pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
4288*61046927SAndroid Build Coastguard Worker
4289*61046927SAndroid Build Coastguard Worker const struct brw_stage_prog_data *prog_data;
4290*61046927SAndroid Build Coastguard Worker switch (pipeline->type) {
4291*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_GRAPHICS:
4292*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_GRAPHICS_LIB: {
4293*61046927SAndroid Build Coastguard Worker prog_data = anv_pipeline_to_graphics_base(pipeline)->shaders[exe->stage]->prog_data;
4294*61046927SAndroid Build Coastguard Worker break;
4295*61046927SAndroid Build Coastguard Worker }
4296*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_COMPUTE: {
4297*61046927SAndroid Build Coastguard Worker prog_data = anv_pipeline_to_compute(pipeline)->cs->prog_data;
4298*61046927SAndroid Build Coastguard Worker break;
4299*61046927SAndroid Build Coastguard Worker }
4300*61046927SAndroid Build Coastguard Worker case ANV_PIPELINE_RAY_TRACING: {
4301*61046927SAndroid Build Coastguard Worker struct anv_shader_bin **shader =
4302*61046927SAndroid Build Coastguard Worker util_dynarray_element(&anv_pipeline_to_ray_tracing(pipeline)->shaders,
4303*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *,
4304*61046927SAndroid Build Coastguard Worker pExecutableInfo->executableIndex);
4305*61046927SAndroid Build Coastguard Worker prog_data = (*shader)->prog_data;
4306*61046927SAndroid Build Coastguard Worker break;
4307*61046927SAndroid Build Coastguard Worker }
4308*61046927SAndroid Build Coastguard Worker default:
4309*61046927SAndroid Build Coastguard Worker unreachable("invalid pipeline type");
4310*61046927SAndroid Build Coastguard Worker }
4311*61046927SAndroid Build Coastguard Worker
4312*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4313*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Instruction Count");
4314*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4315*61046927SAndroid Build Coastguard Worker "Number of GEN instructions in the final generated "
4316*61046927SAndroid Build Coastguard Worker "shader executable.");
4317*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4318*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.instructions;
4319*61046927SAndroid Build Coastguard Worker }
4320*61046927SAndroid Build Coastguard Worker
4321*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4322*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "SEND Count");
4323*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4324*61046927SAndroid Build Coastguard Worker "Number of instructions in the final generated shader "
4325*61046927SAndroid Build Coastguard Worker "executable which access external units such as the "
4326*61046927SAndroid Build Coastguard Worker "constant cache or the sampler.");
4327*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4328*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.sends;
4329*61046927SAndroid Build Coastguard Worker }
4330*61046927SAndroid Build Coastguard Worker
4331*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4332*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Loop Count");
4333*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4334*61046927SAndroid Build Coastguard Worker "Number of loops (not unrolled) in the final generated "
4335*61046927SAndroid Build Coastguard Worker "shader executable.");
4336*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4337*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.loops;
4338*61046927SAndroid Build Coastguard Worker }
4339*61046927SAndroid Build Coastguard Worker
4340*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4341*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Cycle Count");
4342*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4343*61046927SAndroid Build Coastguard Worker "Estimate of the number of EU cycles required to execute "
4344*61046927SAndroid Build Coastguard Worker "the final generated executable. This is an estimate only "
4345*61046927SAndroid Build Coastguard Worker "and may vary greatly from actual run-time performance.");
4346*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4347*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.cycles;
4348*61046927SAndroid Build Coastguard Worker }
4349*61046927SAndroid Build Coastguard Worker
4350*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4351*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Spill Count");
4352*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4353*61046927SAndroid Build Coastguard Worker "Number of scratch spill operations. This gives a rough "
4354*61046927SAndroid Build Coastguard Worker "estimate of the cost incurred due to spilling temporary "
4355*61046927SAndroid Build Coastguard Worker "values to memory. If this is non-zero, you may want to "
4356*61046927SAndroid Build Coastguard Worker "adjust your shader to reduce register pressure.");
4357*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4358*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.spills;
4359*61046927SAndroid Build Coastguard Worker }
4360*61046927SAndroid Build Coastguard Worker
4361*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4362*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Fill Count");
4363*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4364*61046927SAndroid Build Coastguard Worker "Number of scratch fill operations. This gives a rough "
4365*61046927SAndroid Build Coastguard Worker "estimate of the cost incurred due to spilling temporary "
4366*61046927SAndroid Build Coastguard Worker "values to memory. If this is non-zero, you may want to "
4367*61046927SAndroid Build Coastguard Worker "adjust your shader to reduce register pressure.");
4368*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4369*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.fills;
4370*61046927SAndroid Build Coastguard Worker }
4371*61046927SAndroid Build Coastguard Worker
4372*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4373*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Scratch Memory Size");
4374*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4375*61046927SAndroid Build Coastguard Worker "Number of bytes of scratch memory required by the "
4376*61046927SAndroid Build Coastguard Worker "generated shader executable. If this is non-zero, you "
4377*61046927SAndroid Build Coastguard Worker "may want to adjust your shader to reduce register "
4378*61046927SAndroid Build Coastguard Worker "pressure.");
4379*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4380*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->total_scratch;
4381*61046927SAndroid Build Coastguard Worker }
4382*61046927SAndroid Build Coastguard Worker
4383*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4384*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Max dispatch width");
4385*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4386*61046927SAndroid Build Coastguard Worker "Largest SIMD dispatch width.");
4387*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4388*61046927SAndroid Build Coastguard Worker /* Report the max dispatch width only on the smallest SIMD variant */
4389*61046927SAndroid Build Coastguard Worker if (exe->stage != MESA_SHADER_FRAGMENT || exe->stats.dispatch_width == 8)
4390*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.max_dispatch_width;
4391*61046927SAndroid Build Coastguard Worker else
4392*61046927SAndroid Build Coastguard Worker stat->value.u64 = 0;
4393*61046927SAndroid Build Coastguard Worker }
4394*61046927SAndroid Build Coastguard Worker
4395*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4396*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Max live registers");
4397*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4398*61046927SAndroid Build Coastguard Worker "Maximum number of registers used across the entire shader.");
4399*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4400*61046927SAndroid Build Coastguard Worker stat->value.u64 = exe->stats.max_live_registers;
4401*61046927SAndroid Build Coastguard Worker }
4402*61046927SAndroid Build Coastguard Worker
4403*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4404*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Workgroup Memory Size");
4405*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4406*61046927SAndroid Build Coastguard Worker "Number of bytes of workgroup shared memory used by this "
4407*61046927SAndroid Build Coastguard Worker "shader including any padding.");
4408*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4409*61046927SAndroid Build Coastguard Worker if (gl_shader_stage_uses_workgroup(exe->stage))
4410*61046927SAndroid Build Coastguard Worker stat->value.u64 = prog_data->total_shared;
4411*61046927SAndroid Build Coastguard Worker else
4412*61046927SAndroid Build Coastguard Worker stat->value.u64 = 0;
4413*61046927SAndroid Build Coastguard Worker }
4414*61046927SAndroid Build Coastguard Worker
4415*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableStatisticKHR, &out, stat) {
4416*61046927SAndroid Build Coastguard Worker uint32_t hash = pipeline->type == ANV_PIPELINE_COMPUTE ?
4417*61046927SAndroid Build Coastguard Worker anv_pipeline_to_compute(pipeline)->source_hash :
4418*61046927SAndroid Build Coastguard Worker (pipeline->type == ANV_PIPELINE_GRAPHICS_LIB ||
4419*61046927SAndroid Build Coastguard Worker pipeline->type == ANV_PIPELINE_GRAPHICS) ?
4420*61046927SAndroid Build Coastguard Worker anv_pipeline_to_graphics_base(pipeline)->source_hashes[exe->stage] :
4421*61046927SAndroid Build Coastguard Worker 0 /* No source hash for ray tracing */;
4422*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->name, "Source hash");
4423*61046927SAndroid Build Coastguard Worker WRITE_STR(stat->description,
4424*61046927SAndroid Build Coastguard Worker "hash = 0x%08x. Hash generated from shader source.", hash);
4425*61046927SAndroid Build Coastguard Worker stat->format = VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR;
4426*61046927SAndroid Build Coastguard Worker stat->value.u64 = hash;
4427*61046927SAndroid Build Coastguard Worker }
4428*61046927SAndroid Build Coastguard Worker
4429*61046927SAndroid Build Coastguard Worker return vk_outarray_status(&out);
4430*61046927SAndroid Build Coastguard Worker }
4431*61046927SAndroid Build Coastguard Worker
4432*61046927SAndroid Build Coastguard Worker static bool
write_ir_text(VkPipelineExecutableInternalRepresentationKHR * ir,const char * data)4433*61046927SAndroid Build Coastguard Worker write_ir_text(VkPipelineExecutableInternalRepresentationKHR* ir,
4434*61046927SAndroid Build Coastguard Worker const char *data)
4435*61046927SAndroid Build Coastguard Worker {
4436*61046927SAndroid Build Coastguard Worker ir->isText = VK_TRUE;
4437*61046927SAndroid Build Coastguard Worker
4438*61046927SAndroid Build Coastguard Worker size_t data_len = strlen(data) + 1;
4439*61046927SAndroid Build Coastguard Worker
4440*61046927SAndroid Build Coastguard Worker if (ir->pData == NULL) {
4441*61046927SAndroid Build Coastguard Worker ir->dataSize = data_len;
4442*61046927SAndroid Build Coastguard Worker return true;
4443*61046927SAndroid Build Coastguard Worker }
4444*61046927SAndroid Build Coastguard Worker
4445*61046927SAndroid Build Coastguard Worker strncpy(ir->pData, data, ir->dataSize);
4446*61046927SAndroid Build Coastguard Worker if (ir->dataSize < data_len)
4447*61046927SAndroid Build Coastguard Worker return false;
4448*61046927SAndroid Build Coastguard Worker
4449*61046927SAndroid Build Coastguard Worker ir->dataSize = data_len;
4450*61046927SAndroid Build Coastguard Worker return true;
4451*61046927SAndroid Build Coastguard Worker }
4452*61046927SAndroid Build Coastguard Worker
anv_GetPipelineExecutableInternalRepresentationsKHR(VkDevice device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pInternalRepresentationCount,VkPipelineExecutableInternalRepresentationKHR * pInternalRepresentations)4453*61046927SAndroid Build Coastguard Worker VkResult anv_GetPipelineExecutableInternalRepresentationsKHR(
4454*61046927SAndroid Build Coastguard Worker VkDevice device,
4455*61046927SAndroid Build Coastguard Worker const VkPipelineExecutableInfoKHR* pExecutableInfo,
4456*61046927SAndroid Build Coastguard Worker uint32_t* pInternalRepresentationCount,
4457*61046927SAndroid Build Coastguard Worker VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations)
4458*61046927SAndroid Build Coastguard Worker {
4459*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline, pExecutableInfo->pipeline);
4460*61046927SAndroid Build Coastguard Worker VK_OUTARRAY_MAKE_TYPED(VkPipelineExecutableInternalRepresentationKHR, out,
4461*61046927SAndroid Build Coastguard Worker pInternalRepresentations, pInternalRepresentationCount);
4462*61046927SAndroid Build Coastguard Worker bool incomplete_text = false;
4463*61046927SAndroid Build Coastguard Worker
4464*61046927SAndroid Build Coastguard Worker const struct anv_pipeline_executable *exe =
4465*61046927SAndroid Build Coastguard Worker anv_pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
4466*61046927SAndroid Build Coastguard Worker
4467*61046927SAndroid Build Coastguard Worker if (exe->nir) {
4468*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableInternalRepresentationKHR, &out, ir) {
4469*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->name, "Final NIR");
4470*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->description,
4471*61046927SAndroid Build Coastguard Worker "Final NIR before going into the back-end compiler");
4472*61046927SAndroid Build Coastguard Worker
4473*61046927SAndroid Build Coastguard Worker if (!write_ir_text(ir, exe->nir))
4474*61046927SAndroid Build Coastguard Worker incomplete_text = true;
4475*61046927SAndroid Build Coastguard Worker }
4476*61046927SAndroid Build Coastguard Worker }
4477*61046927SAndroid Build Coastguard Worker
4478*61046927SAndroid Build Coastguard Worker if (exe->disasm) {
4479*61046927SAndroid Build Coastguard Worker vk_outarray_append_typed(VkPipelineExecutableInternalRepresentationKHR, &out, ir) {
4480*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->name, "GEN Assembly");
4481*61046927SAndroid Build Coastguard Worker WRITE_STR(ir->description,
4482*61046927SAndroid Build Coastguard Worker "Final GEN assembly for the generated shader binary");
4483*61046927SAndroid Build Coastguard Worker
4484*61046927SAndroid Build Coastguard Worker if (!write_ir_text(ir, exe->disasm))
4485*61046927SAndroid Build Coastguard Worker incomplete_text = true;
4486*61046927SAndroid Build Coastguard Worker }
4487*61046927SAndroid Build Coastguard Worker }
4488*61046927SAndroid Build Coastguard Worker
4489*61046927SAndroid Build Coastguard Worker return incomplete_text ? VK_INCOMPLETE : vk_outarray_status(&out);
4490*61046927SAndroid Build Coastguard Worker }
4491*61046927SAndroid Build Coastguard Worker
4492*61046927SAndroid Build Coastguard Worker VkResult
anv_GetRayTracingShaderGroupHandlesKHR(VkDevice _device,VkPipeline _pipeline,uint32_t firstGroup,uint32_t groupCount,size_t dataSize,void * pData)4493*61046927SAndroid Build Coastguard Worker anv_GetRayTracingShaderGroupHandlesKHR(
4494*61046927SAndroid Build Coastguard Worker VkDevice _device,
4495*61046927SAndroid Build Coastguard Worker VkPipeline _pipeline,
4496*61046927SAndroid Build Coastguard Worker uint32_t firstGroup,
4497*61046927SAndroid Build Coastguard Worker uint32_t groupCount,
4498*61046927SAndroid Build Coastguard Worker size_t dataSize,
4499*61046927SAndroid Build Coastguard Worker void* pData)
4500*61046927SAndroid Build Coastguard Worker {
4501*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_device, device, _device);
4502*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
4503*61046927SAndroid Build Coastguard Worker
4504*61046927SAndroid Build Coastguard Worker if (pipeline->type != ANV_PIPELINE_RAY_TRACING)
4505*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_FEATURE_NOT_PRESENT);
4506*61046927SAndroid Build Coastguard Worker
4507*61046927SAndroid Build Coastguard Worker struct anv_ray_tracing_pipeline *rt_pipeline =
4508*61046927SAndroid Build Coastguard Worker anv_pipeline_to_ray_tracing(pipeline);
4509*61046927SAndroid Build Coastguard Worker
4510*61046927SAndroid Build Coastguard Worker assert(firstGroup + groupCount <= rt_pipeline->group_count);
4511*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < groupCount; i++) {
4512*61046927SAndroid Build Coastguard Worker struct anv_rt_shader_group *group = &rt_pipeline->groups[firstGroup + i];
4513*61046927SAndroid Build Coastguard Worker memcpy(pData, group->handle, sizeof(group->handle));
4514*61046927SAndroid Build Coastguard Worker pData += sizeof(group->handle);
4515*61046927SAndroid Build Coastguard Worker }
4516*61046927SAndroid Build Coastguard Worker
4517*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
4518*61046927SAndroid Build Coastguard Worker }
4519*61046927SAndroid Build Coastguard Worker
4520*61046927SAndroid Build Coastguard Worker VkResult
anv_GetRayTracingCaptureReplayShaderGroupHandlesKHR(VkDevice _device,VkPipeline pipeline,uint32_t firstGroup,uint32_t groupCount,size_t dataSize,void * pData)4521*61046927SAndroid Build Coastguard Worker anv_GetRayTracingCaptureReplayShaderGroupHandlesKHR(
4522*61046927SAndroid Build Coastguard Worker VkDevice _device,
4523*61046927SAndroid Build Coastguard Worker VkPipeline pipeline,
4524*61046927SAndroid Build Coastguard Worker uint32_t firstGroup,
4525*61046927SAndroid Build Coastguard Worker uint32_t groupCount,
4526*61046927SAndroid Build Coastguard Worker size_t dataSize,
4527*61046927SAndroid Build Coastguard Worker void* pData)
4528*61046927SAndroid Build Coastguard Worker {
4529*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_device, device, _device);
4530*61046927SAndroid Build Coastguard Worker unreachable("Unimplemented");
4531*61046927SAndroid Build Coastguard Worker return vk_error(device, VK_ERROR_FEATURE_NOT_PRESENT);
4532*61046927SAndroid Build Coastguard Worker }
4533*61046927SAndroid Build Coastguard Worker
4534*61046927SAndroid Build Coastguard Worker VkDeviceSize
anv_GetRayTracingShaderGroupStackSizeKHR(VkDevice device,VkPipeline _pipeline,uint32_t group,VkShaderGroupShaderKHR groupShader)4535*61046927SAndroid Build Coastguard Worker anv_GetRayTracingShaderGroupStackSizeKHR(
4536*61046927SAndroid Build Coastguard Worker VkDevice device,
4537*61046927SAndroid Build Coastguard Worker VkPipeline _pipeline,
4538*61046927SAndroid Build Coastguard Worker uint32_t group,
4539*61046927SAndroid Build Coastguard Worker VkShaderGroupShaderKHR groupShader)
4540*61046927SAndroid Build Coastguard Worker {
4541*61046927SAndroid Build Coastguard Worker ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
4542*61046927SAndroid Build Coastguard Worker assert(pipeline->type == ANV_PIPELINE_RAY_TRACING);
4543*61046927SAndroid Build Coastguard Worker
4544*61046927SAndroid Build Coastguard Worker struct anv_ray_tracing_pipeline *rt_pipeline =
4545*61046927SAndroid Build Coastguard Worker anv_pipeline_to_ray_tracing(pipeline);
4546*61046927SAndroid Build Coastguard Worker
4547*61046927SAndroid Build Coastguard Worker assert(group < rt_pipeline->group_count);
4548*61046927SAndroid Build Coastguard Worker
4549*61046927SAndroid Build Coastguard Worker struct anv_shader_bin *bin;
4550*61046927SAndroid Build Coastguard Worker switch (groupShader) {
4551*61046927SAndroid Build Coastguard Worker case VK_SHADER_GROUP_SHADER_GENERAL_KHR:
4552*61046927SAndroid Build Coastguard Worker bin = rt_pipeline->groups[group].general;
4553*61046927SAndroid Build Coastguard Worker break;
4554*61046927SAndroid Build Coastguard Worker
4555*61046927SAndroid Build Coastguard Worker case VK_SHADER_GROUP_SHADER_CLOSEST_HIT_KHR:
4556*61046927SAndroid Build Coastguard Worker bin = rt_pipeline->groups[group].closest_hit;
4557*61046927SAndroid Build Coastguard Worker break;
4558*61046927SAndroid Build Coastguard Worker
4559*61046927SAndroid Build Coastguard Worker case VK_SHADER_GROUP_SHADER_ANY_HIT_KHR:
4560*61046927SAndroid Build Coastguard Worker bin = rt_pipeline->groups[group].any_hit;
4561*61046927SAndroid Build Coastguard Worker break;
4562*61046927SAndroid Build Coastguard Worker
4563*61046927SAndroid Build Coastguard Worker case VK_SHADER_GROUP_SHADER_INTERSECTION_KHR:
4564*61046927SAndroid Build Coastguard Worker bin = rt_pipeline->groups[group].intersection;
4565*61046927SAndroid Build Coastguard Worker break;
4566*61046927SAndroid Build Coastguard Worker
4567*61046927SAndroid Build Coastguard Worker default:
4568*61046927SAndroid Build Coastguard Worker unreachable("Invalid VkShaderGroupShader enum");
4569*61046927SAndroid Build Coastguard Worker }
4570*61046927SAndroid Build Coastguard Worker
4571*61046927SAndroid Build Coastguard Worker if (bin == NULL)
4572*61046927SAndroid Build Coastguard Worker return 0;
4573*61046927SAndroid Build Coastguard Worker
4574*61046927SAndroid Build Coastguard Worker return brw_bs_prog_data_const(bin->prog_data)->max_stack_size;
4575*61046927SAndroid Build Coastguard Worker }
4576