1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2017 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 12bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 21bf215546Sopenharmony_ci */ 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_ci/** 24bf215546Sopenharmony_ci * @file iris_program.c 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci * This file contains the driver interface for compiling shaders. 27bf215546Sopenharmony_ci * 28bf215546Sopenharmony_ci * See iris_program_cache.c for the in-memory program cache where the 29bf215546Sopenharmony_ci * compiled shaders are stored. 30bf215546Sopenharmony_ci */ 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include <stdio.h> 33bf215546Sopenharmony_ci#include <errno.h> 34bf215546Sopenharmony_ci#include "pipe/p_defines.h" 35bf215546Sopenharmony_ci#include "pipe/p_state.h" 36bf215546Sopenharmony_ci#include "pipe/p_context.h" 37bf215546Sopenharmony_ci#include "pipe/p_screen.h" 38bf215546Sopenharmony_ci#include "util/u_atomic.h" 39bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 40bf215546Sopenharmony_ci#include "util/debug.h" 41bf215546Sopenharmony_ci#include "util/u_async_debug.h" 42bf215546Sopenharmony_ci#include "compiler/nir/nir.h" 43bf215546Sopenharmony_ci#include "compiler/nir/nir_builder.h" 44bf215546Sopenharmony_ci#include "compiler/nir/nir_serialize.h" 45bf215546Sopenharmony_ci#include "intel/compiler/brw_compiler.h" 46bf215546Sopenharmony_ci#include "intel/compiler/brw_nir.h" 47bf215546Sopenharmony_ci#include "intel/compiler/brw_prim.h" 48bf215546Sopenharmony_ci#include "iris_context.h" 49bf215546Sopenharmony_ci#include "nir/tgsi_to_nir.h" 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci#define KEY_INIT(prefix) \ 52bf215546Sopenharmony_ci .prefix.program_string_id = ish->program_id, \ 53bf215546Sopenharmony_ci .prefix.limit_trig_input_range = screen->driconf.limit_trig_input_range 54bf215546Sopenharmony_ci#define BRW_KEY_INIT(gen, prog_id, limit_trig_input) \ 55bf215546Sopenharmony_ci .base.program_string_id = prog_id, \ 56bf215546Sopenharmony_ci .base.limit_trig_input_range = limit_trig_input, \ 57bf215546Sopenharmony_ci .base.tex.swizzles[0 ... BRW_MAX_SAMPLERS - 1] = 0x688, \ 58bf215546Sopenharmony_ci .base.tex.compressed_multisample_layout_mask = ~0, \ 59bf215546Sopenharmony_ci .base.tex.msaa_16 = (gen >= 9 ? ~0 : 0) 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cistruct iris_threaded_compile_job { 62bf215546Sopenharmony_ci struct iris_screen *screen; 63bf215546Sopenharmony_ci struct u_upload_mgr *uploader; 64bf215546Sopenharmony_ci struct util_debug_callback *dbg; 65bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish; 66bf215546Sopenharmony_ci struct iris_compiled_shader *shader; 67bf215546Sopenharmony_ci}; 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_cistatic unsigned 70bf215546Sopenharmony_ciget_new_program_id(struct iris_screen *screen) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci return p_atomic_inc_return(&screen->program_id); 73bf215546Sopenharmony_ci} 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_civoid 76bf215546Sopenharmony_ciiris_finalize_program(struct iris_compiled_shader *shader, 77bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data, 78bf215546Sopenharmony_ci uint32_t *streamout, 79bf215546Sopenharmony_ci enum brw_param_builtin *system_values, 80bf215546Sopenharmony_ci unsigned num_system_values, 81bf215546Sopenharmony_ci unsigned kernel_input_size, 82bf215546Sopenharmony_ci unsigned num_cbufs, 83bf215546Sopenharmony_ci const struct iris_binding_table *bt) 84bf215546Sopenharmony_ci{ 85bf215546Sopenharmony_ci shader->prog_data = prog_data; 86bf215546Sopenharmony_ci shader->streamout = streamout; 87bf215546Sopenharmony_ci shader->system_values = system_values; 88bf215546Sopenharmony_ci shader->num_system_values = num_system_values; 89bf215546Sopenharmony_ci shader->kernel_input_size = kernel_input_size; 90bf215546Sopenharmony_ci shader->num_cbufs = num_cbufs; 91bf215546Sopenharmony_ci shader->bt = *bt; 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci ralloc_steal(shader, shader->prog_data); 94bf215546Sopenharmony_ci ralloc_steal(shader->prog_data, (void *)prog_data->relocs); 95bf215546Sopenharmony_ci ralloc_steal(shader->prog_data, prog_data->param); 96bf215546Sopenharmony_ci ralloc_steal(shader, shader->streamout); 97bf215546Sopenharmony_ci ralloc_steal(shader, shader->system_values); 98bf215546Sopenharmony_ci} 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_cistatic struct brw_vs_prog_key 101bf215546Sopenharmony_ciiris_to_brw_vs_key(const struct iris_screen *screen, 102bf215546Sopenharmony_ci const struct iris_vs_prog_key *key) 103bf215546Sopenharmony_ci{ 104bf215546Sopenharmony_ci return (struct brw_vs_prog_key) { 105bf215546Sopenharmony_ci BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id, 106bf215546Sopenharmony_ci key->vue.base.limit_trig_input_range), 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci /* Don't tell the backend about our clip plane constants, we've 109bf215546Sopenharmony_ci * already lowered them in NIR and don't want it doing it again. 110bf215546Sopenharmony_ci */ 111bf215546Sopenharmony_ci .nr_userclip_plane_consts = 0, 112bf215546Sopenharmony_ci }; 113bf215546Sopenharmony_ci} 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_cistatic struct brw_tcs_prog_key 116bf215546Sopenharmony_ciiris_to_brw_tcs_key(const struct iris_screen *screen, 117bf215546Sopenharmony_ci const struct iris_tcs_prog_key *key) 118bf215546Sopenharmony_ci{ 119bf215546Sopenharmony_ci return (struct brw_tcs_prog_key) { 120bf215546Sopenharmony_ci BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id, 121bf215546Sopenharmony_ci key->vue.base.limit_trig_input_range), 122bf215546Sopenharmony_ci ._tes_primitive_mode = key->_tes_primitive_mode, 123bf215546Sopenharmony_ci .input_vertices = key->input_vertices, 124bf215546Sopenharmony_ci .patch_outputs_written = key->patch_outputs_written, 125bf215546Sopenharmony_ci .outputs_written = key->outputs_written, 126bf215546Sopenharmony_ci .quads_workaround = key->quads_workaround, 127bf215546Sopenharmony_ci }; 128bf215546Sopenharmony_ci} 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_cistatic struct brw_tes_prog_key 131bf215546Sopenharmony_ciiris_to_brw_tes_key(const struct iris_screen *screen, 132bf215546Sopenharmony_ci const struct iris_tes_prog_key *key) 133bf215546Sopenharmony_ci{ 134bf215546Sopenharmony_ci return (struct brw_tes_prog_key) { 135bf215546Sopenharmony_ci BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id, 136bf215546Sopenharmony_ci key->vue.base.limit_trig_input_range), 137bf215546Sopenharmony_ci .patch_inputs_read = key->patch_inputs_read, 138bf215546Sopenharmony_ci .inputs_read = key->inputs_read, 139bf215546Sopenharmony_ci }; 140bf215546Sopenharmony_ci} 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_cistatic struct brw_gs_prog_key 143bf215546Sopenharmony_ciiris_to_brw_gs_key(const struct iris_screen *screen, 144bf215546Sopenharmony_ci const struct iris_gs_prog_key *key) 145bf215546Sopenharmony_ci{ 146bf215546Sopenharmony_ci return (struct brw_gs_prog_key) { 147bf215546Sopenharmony_ci BRW_KEY_INIT(screen->devinfo.ver, key->vue.base.program_string_id, 148bf215546Sopenharmony_ci key->vue.base.limit_trig_input_range), 149bf215546Sopenharmony_ci }; 150bf215546Sopenharmony_ci} 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_cistatic struct brw_wm_prog_key 153bf215546Sopenharmony_ciiris_to_brw_fs_key(const struct iris_screen *screen, 154bf215546Sopenharmony_ci const struct iris_fs_prog_key *key) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci return (struct brw_wm_prog_key) { 157bf215546Sopenharmony_ci BRW_KEY_INIT(screen->devinfo.ver, key->base.program_string_id, 158bf215546Sopenharmony_ci key->base.limit_trig_input_range), 159bf215546Sopenharmony_ci .nr_color_regions = key->nr_color_regions, 160bf215546Sopenharmony_ci .flat_shade = key->flat_shade, 161bf215546Sopenharmony_ci .alpha_test_replicate_alpha = key->alpha_test_replicate_alpha, 162bf215546Sopenharmony_ci .alpha_to_coverage = key->alpha_to_coverage, 163bf215546Sopenharmony_ci .clamp_fragment_color = key->clamp_fragment_color, 164bf215546Sopenharmony_ci .persample_interp = key->persample_interp, 165bf215546Sopenharmony_ci .multisample_fbo = key->multisample_fbo, 166bf215546Sopenharmony_ci .force_dual_color_blend = key->force_dual_color_blend, 167bf215546Sopenharmony_ci .coherent_fb_fetch = key->coherent_fb_fetch, 168bf215546Sopenharmony_ci .color_outputs_valid = key->color_outputs_valid, 169bf215546Sopenharmony_ci .input_slots_valid = key->input_slots_valid, 170bf215546Sopenharmony_ci .ignore_sample_mask_out = !key->multisample_fbo, 171bf215546Sopenharmony_ci }; 172bf215546Sopenharmony_ci} 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_cistatic struct brw_cs_prog_key 175bf215546Sopenharmony_ciiris_to_brw_cs_key(const struct iris_screen *screen, 176bf215546Sopenharmony_ci const struct iris_cs_prog_key *key) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci return (struct brw_cs_prog_key) { 179bf215546Sopenharmony_ci BRW_KEY_INIT(screen->devinfo.ver, key->base.program_string_id, 180bf215546Sopenharmony_ci key->base.limit_trig_input_range), 181bf215546Sopenharmony_ci }; 182bf215546Sopenharmony_ci} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_cistatic void * 185bf215546Sopenharmony_ciupload_state(struct u_upload_mgr *uploader, 186bf215546Sopenharmony_ci struct iris_state_ref *ref, 187bf215546Sopenharmony_ci unsigned size, 188bf215546Sopenharmony_ci unsigned alignment) 189bf215546Sopenharmony_ci{ 190bf215546Sopenharmony_ci void *p = NULL; 191bf215546Sopenharmony_ci u_upload_alloc(uploader, 0, size, alignment, &ref->offset, &ref->res, &p); 192bf215546Sopenharmony_ci return p; 193bf215546Sopenharmony_ci} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_civoid 196bf215546Sopenharmony_ciiris_upload_ubo_ssbo_surf_state(struct iris_context *ice, 197bf215546Sopenharmony_ci struct pipe_shader_buffer *buf, 198bf215546Sopenharmony_ci struct iris_state_ref *surf_state, 199bf215546Sopenharmony_ci isl_surf_usage_flags_t usage) 200bf215546Sopenharmony_ci{ 201bf215546Sopenharmony_ci struct pipe_context *ctx = &ice->ctx; 202bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) ctx->screen; 203bf215546Sopenharmony_ci bool ssbo = usage & ISL_SURF_USAGE_STORAGE_BIT; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci void *map = 206bf215546Sopenharmony_ci upload_state(ice->state.surface_uploader, surf_state, 207bf215546Sopenharmony_ci screen->isl_dev.ss.size, 64); 208bf215546Sopenharmony_ci if (!unlikely(map)) { 209bf215546Sopenharmony_ci surf_state->res = NULL; 210bf215546Sopenharmony_ci return; 211bf215546Sopenharmony_ci } 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci struct iris_resource *res = (void *) buf->buffer; 214bf215546Sopenharmony_ci struct iris_bo *surf_bo = iris_resource_bo(surf_state->res); 215bf215546Sopenharmony_ci surf_state->offset += iris_bo_offset_from_base_address(surf_bo); 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci const bool dataport = ssbo || !screen->compiler->indirect_ubos_use_sampler; 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci isl_buffer_fill_state(&screen->isl_dev, map, 220bf215546Sopenharmony_ci .address = res->bo->address + res->offset + 221bf215546Sopenharmony_ci buf->buffer_offset, 222bf215546Sopenharmony_ci .size_B = buf->buffer_size - res->offset, 223bf215546Sopenharmony_ci .format = dataport ? ISL_FORMAT_RAW 224bf215546Sopenharmony_ci : ISL_FORMAT_R32G32B32A32_FLOAT, 225bf215546Sopenharmony_ci .swizzle = ISL_SWIZZLE_IDENTITY, 226bf215546Sopenharmony_ci .stride_B = 1, 227bf215546Sopenharmony_ci .mocs = iris_mocs(res->bo, &screen->isl_dev, usage)); 228bf215546Sopenharmony_ci} 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_cistatic nir_ssa_def * 231bf215546Sopenharmony_ciget_aoa_deref_offset(nir_builder *b, 232bf215546Sopenharmony_ci nir_deref_instr *deref, 233bf215546Sopenharmony_ci unsigned elem_size) 234bf215546Sopenharmony_ci{ 235bf215546Sopenharmony_ci unsigned array_size = elem_size; 236bf215546Sopenharmony_ci nir_ssa_def *offset = nir_imm_int(b, 0); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci while (deref->deref_type != nir_deref_type_var) { 239bf215546Sopenharmony_ci assert(deref->deref_type == nir_deref_type_array); 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci /* This level's element size is the previous level's array size */ 242bf215546Sopenharmony_ci nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1); 243bf215546Sopenharmony_ci assert(deref->arr.index.ssa); 244bf215546Sopenharmony_ci offset = nir_iadd(b, offset, 245bf215546Sopenharmony_ci nir_imul(b, index, nir_imm_int(b, array_size))); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci deref = nir_deref_instr_parent(deref); 248bf215546Sopenharmony_ci assert(glsl_type_is_array(deref->type)); 249bf215546Sopenharmony_ci array_size *= glsl_get_length(deref->type); 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci /* Accessing an invalid surface index with the dataport can result in a 253bf215546Sopenharmony_ci * hang. According to the spec "if the index used to select an individual 254bf215546Sopenharmony_ci * element is negative or greater than or equal to the size of the array, 255bf215546Sopenharmony_ci * the results of the operation are undefined but may not lead to 256bf215546Sopenharmony_ci * termination" -- which is one of the possible outcomes of the hang. 257bf215546Sopenharmony_ci * Clamp the index to prevent access outside of the array bounds. 258bf215546Sopenharmony_ci */ 259bf215546Sopenharmony_ci return nir_umin(b, offset, nir_imm_int(b, array_size - elem_size)); 260bf215546Sopenharmony_ci} 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_cistatic void 263bf215546Sopenharmony_ciiris_lower_storage_image_derefs(nir_shader *nir) 264bf215546Sopenharmony_ci{ 265bf215546Sopenharmony_ci nir_function_impl *impl = nir_shader_get_entrypoint(nir); 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci nir_builder b; 268bf215546Sopenharmony_ci nir_builder_init(&b, impl); 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci nir_foreach_block(block, impl) { 271bf215546Sopenharmony_ci nir_foreach_instr_safe(instr, block) { 272bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 273bf215546Sopenharmony_ci continue; 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 276bf215546Sopenharmony_ci switch (intrin->intrinsic) { 277bf215546Sopenharmony_ci case nir_intrinsic_image_deref_load: 278bf215546Sopenharmony_ci case nir_intrinsic_image_deref_store: 279bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_add: 280bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_imin: 281bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_umin: 282bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_imax: 283bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_umax: 284bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_and: 285bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_or: 286bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_xor: 287bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_exchange: 288bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_comp_swap: 289bf215546Sopenharmony_ci case nir_intrinsic_image_deref_size: 290bf215546Sopenharmony_ci case nir_intrinsic_image_deref_samples: 291bf215546Sopenharmony_ci case nir_intrinsic_image_deref_load_raw_intel: 292bf215546Sopenharmony_ci case nir_intrinsic_image_deref_store_raw_intel: { 293bf215546Sopenharmony_ci nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); 294bf215546Sopenharmony_ci nir_variable *var = nir_deref_instr_get_variable(deref); 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci b.cursor = nir_before_instr(&intrin->instr); 297bf215546Sopenharmony_ci nir_ssa_def *index = 298bf215546Sopenharmony_ci nir_iadd(&b, nir_imm_int(&b, var->data.driver_location), 299bf215546Sopenharmony_ci get_aoa_deref_offset(&b, deref, 1)); 300bf215546Sopenharmony_ci nir_rewrite_image_intrinsic(intrin, index, false); 301bf215546Sopenharmony_ci break; 302bf215546Sopenharmony_ci } 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci default: 305bf215546Sopenharmony_ci break; 306bf215546Sopenharmony_ci } 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci} 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_cistatic bool 312bf215546Sopenharmony_ciiris_uses_image_atomic(const nir_shader *shader) 313bf215546Sopenharmony_ci{ 314bf215546Sopenharmony_ci nir_foreach_function(function, shader) { 315bf215546Sopenharmony_ci if (function->impl == NULL) 316bf215546Sopenharmony_ci continue; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci nir_foreach_block(block, function->impl) { 319bf215546Sopenharmony_ci nir_foreach_instr(instr, block) { 320bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 321bf215546Sopenharmony_ci continue; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 324bf215546Sopenharmony_ci switch (intrin->intrinsic) { 325bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_add: 326bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_imin: 327bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_umin: 328bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_imax: 329bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_umax: 330bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_and: 331bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_or: 332bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_xor: 333bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_exchange: 334bf215546Sopenharmony_ci case nir_intrinsic_image_deref_atomic_comp_swap: 335bf215546Sopenharmony_ci unreachable("Should have been lowered in " 336bf215546Sopenharmony_ci "iris_lower_storage_image_derefs"); 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_add: 339bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_imin: 340bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_umin: 341bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_imax: 342bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_umax: 343bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_and: 344bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_or: 345bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_xor: 346bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_exchange: 347bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_comp_swap: 348bf215546Sopenharmony_ci return true; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci default: 351bf215546Sopenharmony_ci break; 352bf215546Sopenharmony_ci } 353bf215546Sopenharmony_ci } 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci } 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci return false; 358bf215546Sopenharmony_ci} 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci/** 361bf215546Sopenharmony_ci * Undo nir_lower_passthrough_edgeflags but keep the inputs_read flag. 362bf215546Sopenharmony_ci */ 363bf215546Sopenharmony_cistatic bool 364bf215546Sopenharmony_ciiris_fix_edge_flags(nir_shader *nir) 365bf215546Sopenharmony_ci{ 366bf215546Sopenharmony_ci if (nir->info.stage != MESA_SHADER_VERTEX) { 367bf215546Sopenharmony_ci nir_shader_preserve_all_metadata(nir); 368bf215546Sopenharmony_ci return false; 369bf215546Sopenharmony_ci } 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci nir_variable *var = nir_find_variable_with_location(nir, nir_var_shader_out, 372bf215546Sopenharmony_ci VARYING_SLOT_EDGE); 373bf215546Sopenharmony_ci if (!var) { 374bf215546Sopenharmony_ci nir_shader_preserve_all_metadata(nir); 375bf215546Sopenharmony_ci return false; 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci var->data.mode = nir_var_shader_temp; 379bf215546Sopenharmony_ci nir->info.outputs_written &= ~VARYING_BIT_EDGE; 380bf215546Sopenharmony_ci nir->info.inputs_read &= ~VERT_BIT_EDGEFLAG; 381bf215546Sopenharmony_ci nir_fixup_deref_modes(nir); 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci nir_foreach_function(f, nir) { 384bf215546Sopenharmony_ci if (f->impl) { 385bf215546Sopenharmony_ci nir_metadata_preserve(f->impl, nir_metadata_block_index | 386bf215546Sopenharmony_ci nir_metadata_dominance | 387bf215546Sopenharmony_ci nir_metadata_live_ssa_defs | 388bf215546Sopenharmony_ci nir_metadata_loop_analysis); 389bf215546Sopenharmony_ci } else { 390bf215546Sopenharmony_ci nir_metadata_preserve(f->impl, nir_metadata_all); 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci } 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci return true; 395bf215546Sopenharmony_ci} 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci/** 398bf215546Sopenharmony_ci * Fix an uncompiled shader's stream output info. 399bf215546Sopenharmony_ci * 400bf215546Sopenharmony_ci * Core Gallium stores output->register_index as a "slot" number, where 401bf215546Sopenharmony_ci * slots are assigned consecutively to all outputs in info->outputs_written. 402bf215546Sopenharmony_ci * This naive packing of outputs doesn't work for us - we too have slots, 403bf215546Sopenharmony_ci * but the layout is defined by the VUE map, which we won't have until we 404bf215546Sopenharmony_ci * compile a specific shader variant. So, we remap these and simply store 405bf215546Sopenharmony_ci * VARYING_SLOT_* in our copy's output->register_index fields. 406bf215546Sopenharmony_ci * 407bf215546Sopenharmony_ci * We also fix up VARYING_SLOT_{LAYER,VIEWPORT,PSIZ} to select the Y/Z/W 408bf215546Sopenharmony_ci * components of our VUE header. See brw_vue_map.c for the layout. 409bf215546Sopenharmony_ci */ 410bf215546Sopenharmony_cistatic void 411bf215546Sopenharmony_ciupdate_so_info(struct pipe_stream_output_info *so_info, 412bf215546Sopenharmony_ci uint64_t outputs_written) 413bf215546Sopenharmony_ci{ 414bf215546Sopenharmony_ci uint8_t reverse_map[64] = {}; 415bf215546Sopenharmony_ci unsigned slot = 0; 416bf215546Sopenharmony_ci while (outputs_written) { 417bf215546Sopenharmony_ci reverse_map[slot++] = u_bit_scan64(&outputs_written); 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci for (unsigned i = 0; i < so_info->num_outputs; i++) { 421bf215546Sopenharmony_ci struct pipe_stream_output *output = &so_info->output[i]; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */ 424bf215546Sopenharmony_ci output->register_index = reverse_map[output->register_index]; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci /* The VUE header contains three scalar fields packed together: 427bf215546Sopenharmony_ci * - gl_PointSize is stored in VARYING_SLOT_PSIZ.w 428bf215546Sopenharmony_ci * - gl_Layer is stored in VARYING_SLOT_PSIZ.y 429bf215546Sopenharmony_ci * - gl_ViewportIndex is stored in VARYING_SLOT_PSIZ.z 430bf215546Sopenharmony_ci */ 431bf215546Sopenharmony_ci switch (output->register_index) { 432bf215546Sopenharmony_ci case VARYING_SLOT_LAYER: 433bf215546Sopenharmony_ci assert(output->num_components == 1); 434bf215546Sopenharmony_ci output->register_index = VARYING_SLOT_PSIZ; 435bf215546Sopenharmony_ci output->start_component = 1; 436bf215546Sopenharmony_ci break; 437bf215546Sopenharmony_ci case VARYING_SLOT_VIEWPORT: 438bf215546Sopenharmony_ci assert(output->num_components == 1); 439bf215546Sopenharmony_ci output->register_index = VARYING_SLOT_PSIZ; 440bf215546Sopenharmony_ci output->start_component = 2; 441bf215546Sopenharmony_ci break; 442bf215546Sopenharmony_ci case VARYING_SLOT_PSIZ: 443bf215546Sopenharmony_ci assert(output->num_components == 1); 444bf215546Sopenharmony_ci output->start_component = 3; 445bf215546Sopenharmony_ci break; 446bf215546Sopenharmony_ci } 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci //info->outputs_written |= 1ull << output->register_index; 449bf215546Sopenharmony_ci } 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_cistatic void 453bf215546Sopenharmony_cisetup_vec4_image_sysval(uint32_t *sysvals, uint32_t idx, 454bf215546Sopenharmony_ci unsigned offset, unsigned n) 455bf215546Sopenharmony_ci{ 456bf215546Sopenharmony_ci assert(offset % sizeof(uint32_t) == 0); 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci for (unsigned i = 0; i < n; ++i) 459bf215546Sopenharmony_ci sysvals[i] = BRW_PARAM_IMAGE(idx, offset / sizeof(uint32_t) + i); 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci for (unsigned i = n; i < 4; ++i) 462bf215546Sopenharmony_ci sysvals[i] = BRW_PARAM_BUILTIN_ZERO; 463bf215546Sopenharmony_ci} 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci/** 466bf215546Sopenharmony_ci * Associate NIR uniform variables with the prog_data->param[] mechanism 467bf215546Sopenharmony_ci * used by the backend. Also, decide which UBOs we'd like to push in an 468bf215546Sopenharmony_ci * ideal situation (though the backend can reduce this). 469bf215546Sopenharmony_ci */ 470bf215546Sopenharmony_cistatic void 471bf215546Sopenharmony_ciiris_setup_uniforms(const struct brw_compiler *compiler, 472bf215546Sopenharmony_ci void *mem_ctx, 473bf215546Sopenharmony_ci nir_shader *nir, 474bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data, 475bf215546Sopenharmony_ci unsigned kernel_input_size, 476bf215546Sopenharmony_ci enum brw_param_builtin **out_system_values, 477bf215546Sopenharmony_ci unsigned *out_num_system_values, 478bf215546Sopenharmony_ci unsigned *out_num_cbufs) 479bf215546Sopenharmony_ci{ 480bf215546Sopenharmony_ci UNUSED const struct intel_device_info *devinfo = compiler->devinfo; 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci unsigned system_values_start = ALIGN(kernel_input_size, sizeof(uint32_t)); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci const unsigned IRIS_MAX_SYSTEM_VALUES = 485bf215546Sopenharmony_ci PIPE_MAX_SHADER_IMAGES * BRW_IMAGE_PARAM_SIZE; 486bf215546Sopenharmony_ci enum brw_param_builtin *system_values = 487bf215546Sopenharmony_ci rzalloc_array(mem_ctx, enum brw_param_builtin, IRIS_MAX_SYSTEM_VALUES); 488bf215546Sopenharmony_ci unsigned num_system_values = 0; 489bf215546Sopenharmony_ci 490bf215546Sopenharmony_ci unsigned patch_vert_idx = -1; 491bf215546Sopenharmony_ci unsigned ucp_idx[IRIS_MAX_CLIP_PLANES]; 492bf215546Sopenharmony_ci unsigned img_idx[PIPE_MAX_SHADER_IMAGES]; 493bf215546Sopenharmony_ci unsigned variable_group_size_idx = -1; 494bf215546Sopenharmony_ci unsigned work_dim_idx = -1; 495bf215546Sopenharmony_ci memset(ucp_idx, -1, sizeof(ucp_idx)); 496bf215546Sopenharmony_ci memset(img_idx, -1, sizeof(img_idx)); 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci nir_function_impl *impl = nir_shader_get_entrypoint(nir); 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_ci nir_builder b; 501bf215546Sopenharmony_ci nir_builder_init(&b, impl); 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci b.cursor = nir_before_block(nir_start_block(impl)); 504bf215546Sopenharmony_ci nir_ssa_def *temp_ubo_name = nir_ssa_undef(&b, 1, 32); 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci /* Turn system value intrinsics into uniforms */ 507bf215546Sopenharmony_ci nir_foreach_block(block, impl) { 508bf215546Sopenharmony_ci nir_foreach_instr_safe(instr, block) { 509bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 510bf215546Sopenharmony_ci continue; 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 513bf215546Sopenharmony_ci nir_ssa_def *offset; 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci switch (intrin->intrinsic) { 516bf215546Sopenharmony_ci case nir_intrinsic_load_constant: { 517bf215546Sopenharmony_ci unsigned load_size = intrin->dest.ssa.num_components * 518bf215546Sopenharmony_ci intrin->dest.ssa.bit_size / 8; 519bf215546Sopenharmony_ci unsigned load_align = intrin->dest.ssa.bit_size / 8; 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci /* This one is special because it reads from the shader constant 522bf215546Sopenharmony_ci * data and not cbuf0 which gallium uploads for us. 523bf215546Sopenharmony_ci */ 524bf215546Sopenharmony_ci b.cursor = nir_instr_remove(&intrin->instr); 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci nir_ssa_def *offset = 527bf215546Sopenharmony_ci nir_iadd_imm(&b, nir_ssa_for_src(&b, intrin->src[0], 1), 528bf215546Sopenharmony_ci nir_intrinsic_base(intrin)); 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci assert(load_size < b.shader->constant_data_size); 531bf215546Sopenharmony_ci unsigned max_offset = b.shader->constant_data_size - load_size; 532bf215546Sopenharmony_ci offset = nir_umin(&b, offset, nir_imm_int(&b, max_offset)); 533bf215546Sopenharmony_ci 534bf215546Sopenharmony_ci nir_ssa_def *const_data_base_addr = nir_pack_64_2x32_split(&b, 535bf215546Sopenharmony_ci nir_load_reloc_const_intel(&b, BRW_SHADER_RELOC_CONST_DATA_ADDR_LOW), 536bf215546Sopenharmony_ci nir_load_reloc_const_intel(&b, BRW_SHADER_RELOC_CONST_DATA_ADDR_HIGH)); 537bf215546Sopenharmony_ci 538bf215546Sopenharmony_ci nir_ssa_def *data = 539bf215546Sopenharmony_ci nir_load_global(&b, nir_iadd(&b, const_data_base_addr, 540bf215546Sopenharmony_ci nir_u2u64(&b, offset)), 541bf215546Sopenharmony_ci load_align, 542bf215546Sopenharmony_ci intrin->dest.ssa.num_components, 543bf215546Sopenharmony_ci intrin->dest.ssa.bit_size); 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_ci nir_ssa_def_rewrite_uses(&intrin->dest.ssa, 546bf215546Sopenharmony_ci data); 547bf215546Sopenharmony_ci continue; 548bf215546Sopenharmony_ci } 549bf215546Sopenharmony_ci case nir_intrinsic_load_user_clip_plane: { 550bf215546Sopenharmony_ci unsigned ucp = nir_intrinsic_ucp_id(intrin); 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_ci if (ucp_idx[ucp] == -1) { 553bf215546Sopenharmony_ci ucp_idx[ucp] = num_system_values; 554bf215546Sopenharmony_ci num_system_values += 4; 555bf215546Sopenharmony_ci } 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) { 558bf215546Sopenharmony_ci system_values[ucp_idx[ucp] + i] = 559bf215546Sopenharmony_ci BRW_PARAM_BUILTIN_CLIP_PLANE(ucp, i); 560bf215546Sopenharmony_ci } 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci b.cursor = nir_before_instr(instr); 563bf215546Sopenharmony_ci offset = nir_imm_int(&b, system_values_start + 564bf215546Sopenharmony_ci ucp_idx[ucp] * sizeof(uint32_t)); 565bf215546Sopenharmony_ci break; 566bf215546Sopenharmony_ci } 567bf215546Sopenharmony_ci case nir_intrinsic_load_patch_vertices_in: 568bf215546Sopenharmony_ci if (patch_vert_idx == -1) 569bf215546Sopenharmony_ci patch_vert_idx = num_system_values++; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci system_values[patch_vert_idx] = 572bf215546Sopenharmony_ci BRW_PARAM_BUILTIN_PATCH_VERTICES_IN; 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci b.cursor = nir_before_instr(instr); 575bf215546Sopenharmony_ci offset = nir_imm_int(&b, system_values_start + 576bf215546Sopenharmony_ci patch_vert_idx * sizeof(uint32_t)); 577bf215546Sopenharmony_ci break; 578bf215546Sopenharmony_ci case nir_intrinsic_image_deref_load_param_intel: { 579bf215546Sopenharmony_ci assert(devinfo->ver < 9); 580bf215546Sopenharmony_ci nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]); 581bf215546Sopenharmony_ci nir_variable *var = nir_deref_instr_get_variable(deref); 582bf215546Sopenharmony_ci 583bf215546Sopenharmony_ci if (img_idx[var->data.binding] == -1) { 584bf215546Sopenharmony_ci /* GL only allows arrays of arrays of images. */ 585bf215546Sopenharmony_ci assert(glsl_type_is_image(glsl_without_array(var->type))); 586bf215546Sopenharmony_ci unsigned num_images = MAX2(1, glsl_get_aoa_size(var->type)); 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci for (int i = 0; i < num_images; i++) { 589bf215546Sopenharmony_ci const unsigned img = var->data.binding + i; 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci img_idx[img] = num_system_values; 592bf215546Sopenharmony_ci num_system_values += BRW_IMAGE_PARAM_SIZE; 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci uint32_t *img_sv = &system_values[img_idx[img]]; 595bf215546Sopenharmony_ci 596bf215546Sopenharmony_ci setup_vec4_image_sysval( 597bf215546Sopenharmony_ci img_sv + BRW_IMAGE_PARAM_OFFSET_OFFSET, img, 598bf215546Sopenharmony_ci offsetof(struct brw_image_param, offset), 2); 599bf215546Sopenharmony_ci setup_vec4_image_sysval( 600bf215546Sopenharmony_ci img_sv + BRW_IMAGE_PARAM_SIZE_OFFSET, img, 601bf215546Sopenharmony_ci offsetof(struct brw_image_param, size), 3); 602bf215546Sopenharmony_ci setup_vec4_image_sysval( 603bf215546Sopenharmony_ci img_sv + BRW_IMAGE_PARAM_STRIDE_OFFSET, img, 604bf215546Sopenharmony_ci offsetof(struct brw_image_param, stride), 4); 605bf215546Sopenharmony_ci setup_vec4_image_sysval( 606bf215546Sopenharmony_ci img_sv + BRW_IMAGE_PARAM_TILING_OFFSET, img, 607bf215546Sopenharmony_ci offsetof(struct brw_image_param, tiling), 3); 608bf215546Sopenharmony_ci setup_vec4_image_sysval( 609bf215546Sopenharmony_ci img_sv + BRW_IMAGE_PARAM_SWIZZLING_OFFSET, img, 610bf215546Sopenharmony_ci offsetof(struct brw_image_param, swizzling), 2); 611bf215546Sopenharmony_ci } 612bf215546Sopenharmony_ci } 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci b.cursor = nir_before_instr(instr); 615bf215546Sopenharmony_ci offset = nir_iadd(&b, 616bf215546Sopenharmony_ci get_aoa_deref_offset(&b, deref, BRW_IMAGE_PARAM_SIZE * 4), 617bf215546Sopenharmony_ci nir_imm_int(&b, system_values_start + 618bf215546Sopenharmony_ci img_idx[var->data.binding] * 4 + 619bf215546Sopenharmony_ci nir_intrinsic_base(intrin) * 16)); 620bf215546Sopenharmony_ci break; 621bf215546Sopenharmony_ci } 622bf215546Sopenharmony_ci case nir_intrinsic_load_workgroup_size: { 623bf215546Sopenharmony_ci assert(nir->info.workgroup_size_variable); 624bf215546Sopenharmony_ci if (variable_group_size_idx == -1) { 625bf215546Sopenharmony_ci variable_group_size_idx = num_system_values; 626bf215546Sopenharmony_ci num_system_values += 3; 627bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 628bf215546Sopenharmony_ci system_values[variable_group_size_idx + i] = 629bf215546Sopenharmony_ci BRW_PARAM_BUILTIN_WORK_GROUP_SIZE_X + i; 630bf215546Sopenharmony_ci } 631bf215546Sopenharmony_ci } 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_ci b.cursor = nir_before_instr(instr); 634bf215546Sopenharmony_ci offset = nir_imm_int(&b, system_values_start + 635bf215546Sopenharmony_ci variable_group_size_idx * sizeof(uint32_t)); 636bf215546Sopenharmony_ci break; 637bf215546Sopenharmony_ci } 638bf215546Sopenharmony_ci case nir_intrinsic_load_work_dim: { 639bf215546Sopenharmony_ci if (work_dim_idx == -1) { 640bf215546Sopenharmony_ci work_dim_idx = num_system_values++; 641bf215546Sopenharmony_ci system_values[work_dim_idx] = BRW_PARAM_BUILTIN_WORK_DIM; 642bf215546Sopenharmony_ci } 643bf215546Sopenharmony_ci b.cursor = nir_before_instr(instr); 644bf215546Sopenharmony_ci offset = nir_imm_int(&b, system_values_start + 645bf215546Sopenharmony_ci work_dim_idx * sizeof(uint32_t)); 646bf215546Sopenharmony_ci break; 647bf215546Sopenharmony_ci } 648bf215546Sopenharmony_ci case nir_intrinsic_load_kernel_input: { 649bf215546Sopenharmony_ci assert(nir_intrinsic_base(intrin) + 650bf215546Sopenharmony_ci nir_intrinsic_range(intrin) <= kernel_input_size); 651bf215546Sopenharmony_ci b.cursor = nir_before_instr(instr); 652bf215546Sopenharmony_ci offset = nir_iadd_imm(&b, intrin->src[0].ssa, 653bf215546Sopenharmony_ci nir_intrinsic_base(intrin)); 654bf215546Sopenharmony_ci break; 655bf215546Sopenharmony_ci } 656bf215546Sopenharmony_ci default: 657bf215546Sopenharmony_ci continue; 658bf215546Sopenharmony_ci } 659bf215546Sopenharmony_ci 660bf215546Sopenharmony_ci nir_ssa_def *load = 661bf215546Sopenharmony_ci nir_load_ubo(&b, intrin->dest.ssa.num_components, intrin->dest.ssa.bit_size, 662bf215546Sopenharmony_ci temp_ubo_name, offset, 663bf215546Sopenharmony_ci .align_mul = 4, 664bf215546Sopenharmony_ci .align_offset = 0, 665bf215546Sopenharmony_ci .range_base = 0, 666bf215546Sopenharmony_ci .range = ~0); 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci nir_ssa_def_rewrite_uses(&intrin->dest.ssa, 669bf215546Sopenharmony_ci load); 670bf215546Sopenharmony_ci nir_instr_remove(instr); 671bf215546Sopenharmony_ci } 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci 674bf215546Sopenharmony_ci nir_validate_shader(nir, "before remapping"); 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci /* Uniforms are stored in constant buffer 0, the 677bf215546Sopenharmony_ci * user-facing UBOs are indexed by one. So if any constant buffer is 678bf215546Sopenharmony_ci * needed, the constant buffer 0 will be needed, so account for it. 679bf215546Sopenharmony_ci */ 680bf215546Sopenharmony_ci unsigned num_cbufs = nir->info.num_ubos; 681bf215546Sopenharmony_ci if (num_cbufs || nir->num_uniforms) 682bf215546Sopenharmony_ci num_cbufs++; 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci /* Place the new params in a new cbuf. */ 685bf215546Sopenharmony_ci if (num_system_values > 0 || kernel_input_size > 0) { 686bf215546Sopenharmony_ci unsigned sysval_cbuf_index = num_cbufs; 687bf215546Sopenharmony_ci num_cbufs++; 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci system_values = reralloc(mem_ctx, system_values, enum brw_param_builtin, 690bf215546Sopenharmony_ci num_system_values); 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci nir_foreach_block(block, impl) { 693bf215546Sopenharmony_ci nir_foreach_instr_safe(instr, block) { 694bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 695bf215546Sopenharmony_ci continue; 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci nir_intrinsic_instr *load = nir_instr_as_intrinsic(instr); 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci if (load->intrinsic != nir_intrinsic_load_ubo) 700bf215546Sopenharmony_ci continue; 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ci b.cursor = nir_before_instr(instr); 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci assert(load->src[0].is_ssa); 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci if (load->src[0].ssa == temp_ubo_name) { 707bf215546Sopenharmony_ci nir_ssa_def *imm = nir_imm_int(&b, sysval_cbuf_index); 708bf215546Sopenharmony_ci nir_instr_rewrite_src(instr, &load->src[0], 709bf215546Sopenharmony_ci nir_src_for_ssa(imm)); 710bf215546Sopenharmony_ci } 711bf215546Sopenharmony_ci } 712bf215546Sopenharmony_ci } 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci /* We need to fold the new iadds for brw_nir_analyze_ubo_ranges */ 715bf215546Sopenharmony_ci nir_opt_constant_folding(nir); 716bf215546Sopenharmony_ci } else { 717bf215546Sopenharmony_ci ralloc_free(system_values); 718bf215546Sopenharmony_ci system_values = NULL; 719bf215546Sopenharmony_ci } 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci assert(num_cbufs < PIPE_MAX_CONSTANT_BUFFERS); 722bf215546Sopenharmony_ci nir_validate_shader(nir, "after remap"); 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci /* We don't use params[] but gallium leaves num_uniforms set. We use this 725bf215546Sopenharmony_ci * to detect when cbuf0 exists but we don't need it anymore when we get 726bf215546Sopenharmony_ci * here. Instead, zero it out so that the back-end doesn't get confused 727bf215546Sopenharmony_ci * when nr_params * 4 != num_uniforms != nr_params * 4. 728bf215546Sopenharmony_ci */ 729bf215546Sopenharmony_ci nir->num_uniforms = 0; 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci *out_system_values = system_values; 732bf215546Sopenharmony_ci *out_num_system_values = num_system_values; 733bf215546Sopenharmony_ci *out_num_cbufs = num_cbufs; 734bf215546Sopenharmony_ci} 735bf215546Sopenharmony_ci 736bf215546Sopenharmony_cistatic const char *surface_group_names[] = { 737bf215546Sopenharmony_ci [IRIS_SURFACE_GROUP_RENDER_TARGET] = "render target", 738bf215546Sopenharmony_ci [IRIS_SURFACE_GROUP_RENDER_TARGET_READ] = "non-coherent render target read", 739bf215546Sopenharmony_ci [IRIS_SURFACE_GROUP_CS_WORK_GROUPS] = "CS work groups", 740bf215546Sopenharmony_ci [IRIS_SURFACE_GROUP_TEXTURE] = "texture", 741bf215546Sopenharmony_ci [IRIS_SURFACE_GROUP_UBO] = "ubo", 742bf215546Sopenharmony_ci [IRIS_SURFACE_GROUP_SSBO] = "ssbo", 743bf215546Sopenharmony_ci [IRIS_SURFACE_GROUP_IMAGE] = "image", 744bf215546Sopenharmony_ci}; 745bf215546Sopenharmony_ci 746bf215546Sopenharmony_cistatic void 747bf215546Sopenharmony_ciiris_print_binding_table(FILE *fp, const char *name, 748bf215546Sopenharmony_ci const struct iris_binding_table *bt) 749bf215546Sopenharmony_ci{ 750bf215546Sopenharmony_ci STATIC_ASSERT(ARRAY_SIZE(surface_group_names) == IRIS_SURFACE_GROUP_COUNT); 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci uint32_t total = 0; 753bf215546Sopenharmony_ci uint32_t compacted = 0; 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) { 756bf215546Sopenharmony_ci uint32_t size = bt->sizes[i]; 757bf215546Sopenharmony_ci total += size; 758bf215546Sopenharmony_ci if (size) 759bf215546Sopenharmony_ci compacted += util_bitcount64(bt->used_mask[i]); 760bf215546Sopenharmony_ci } 761bf215546Sopenharmony_ci 762bf215546Sopenharmony_ci if (total == 0) { 763bf215546Sopenharmony_ci fprintf(fp, "Binding table for %s is empty\n\n", name); 764bf215546Sopenharmony_ci return; 765bf215546Sopenharmony_ci } 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_ci if (total != compacted) { 768bf215546Sopenharmony_ci fprintf(fp, "Binding table for %s " 769bf215546Sopenharmony_ci "(compacted to %u entries from %u entries)\n", 770bf215546Sopenharmony_ci name, compacted, total); 771bf215546Sopenharmony_ci } else { 772bf215546Sopenharmony_ci fprintf(fp, "Binding table for %s (%u entries)\n", name, total); 773bf215546Sopenharmony_ci } 774bf215546Sopenharmony_ci 775bf215546Sopenharmony_ci uint32_t entry = 0; 776bf215546Sopenharmony_ci for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) { 777bf215546Sopenharmony_ci uint64_t mask = bt->used_mask[i]; 778bf215546Sopenharmony_ci while (mask) { 779bf215546Sopenharmony_ci int index = u_bit_scan64(&mask); 780bf215546Sopenharmony_ci fprintf(fp, " [%u] %s #%d\n", entry++, surface_group_names[i], index); 781bf215546Sopenharmony_ci } 782bf215546Sopenharmony_ci } 783bf215546Sopenharmony_ci fprintf(fp, "\n"); 784bf215546Sopenharmony_ci} 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_cienum { 787bf215546Sopenharmony_ci /* Max elements in a surface group. */ 788bf215546Sopenharmony_ci SURFACE_GROUP_MAX_ELEMENTS = 64, 789bf215546Sopenharmony_ci}; 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci/** 792bf215546Sopenharmony_ci * Map a <group, index> pair to a binding table index. 793bf215546Sopenharmony_ci * 794bf215546Sopenharmony_ci * For example: <UBO, 5> => binding table index 12 795bf215546Sopenharmony_ci */ 796bf215546Sopenharmony_ciuint32_t 797bf215546Sopenharmony_ciiris_group_index_to_bti(const struct iris_binding_table *bt, 798bf215546Sopenharmony_ci enum iris_surface_group group, uint32_t index) 799bf215546Sopenharmony_ci{ 800bf215546Sopenharmony_ci assert(index < bt->sizes[group]); 801bf215546Sopenharmony_ci uint64_t mask = bt->used_mask[group]; 802bf215546Sopenharmony_ci uint64_t bit = 1ull << index; 803bf215546Sopenharmony_ci if (bit & mask) { 804bf215546Sopenharmony_ci return bt->offsets[group] + util_bitcount64((bit - 1) & mask); 805bf215546Sopenharmony_ci } else { 806bf215546Sopenharmony_ci return IRIS_SURFACE_NOT_USED; 807bf215546Sopenharmony_ci } 808bf215546Sopenharmony_ci} 809bf215546Sopenharmony_ci 810bf215546Sopenharmony_ci/** 811bf215546Sopenharmony_ci * Map a binding table index back to a <group, index> pair. 812bf215546Sopenharmony_ci * 813bf215546Sopenharmony_ci * For example: binding table index 12 => <UBO, 5> 814bf215546Sopenharmony_ci */ 815bf215546Sopenharmony_ciuint32_t 816bf215546Sopenharmony_ciiris_bti_to_group_index(const struct iris_binding_table *bt, 817bf215546Sopenharmony_ci enum iris_surface_group group, uint32_t bti) 818bf215546Sopenharmony_ci{ 819bf215546Sopenharmony_ci uint64_t used_mask = bt->used_mask[group]; 820bf215546Sopenharmony_ci assert(bti >= bt->offsets[group]); 821bf215546Sopenharmony_ci 822bf215546Sopenharmony_ci uint32_t c = bti - bt->offsets[group]; 823bf215546Sopenharmony_ci while (used_mask) { 824bf215546Sopenharmony_ci int i = u_bit_scan64(&used_mask); 825bf215546Sopenharmony_ci if (c == 0) 826bf215546Sopenharmony_ci return i; 827bf215546Sopenharmony_ci c--; 828bf215546Sopenharmony_ci } 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_ci return IRIS_SURFACE_NOT_USED; 831bf215546Sopenharmony_ci} 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_cistatic void 834bf215546Sopenharmony_cirewrite_src_with_bti(nir_builder *b, struct iris_binding_table *bt, 835bf215546Sopenharmony_ci nir_instr *instr, nir_src *src, 836bf215546Sopenharmony_ci enum iris_surface_group group) 837bf215546Sopenharmony_ci{ 838bf215546Sopenharmony_ci assert(bt->sizes[group] > 0); 839bf215546Sopenharmony_ci 840bf215546Sopenharmony_ci b->cursor = nir_before_instr(instr); 841bf215546Sopenharmony_ci nir_ssa_def *bti; 842bf215546Sopenharmony_ci if (nir_src_is_const(*src)) { 843bf215546Sopenharmony_ci uint32_t index = nir_src_as_uint(*src); 844bf215546Sopenharmony_ci bti = nir_imm_intN_t(b, iris_group_index_to_bti(bt, group, index), 845bf215546Sopenharmony_ci src->ssa->bit_size); 846bf215546Sopenharmony_ci } else { 847bf215546Sopenharmony_ci /* Indirect usage makes all the surfaces of the group to be available, 848bf215546Sopenharmony_ci * so we can just add the base. 849bf215546Sopenharmony_ci */ 850bf215546Sopenharmony_ci assert(bt->used_mask[group] == BITFIELD64_MASK(bt->sizes[group])); 851bf215546Sopenharmony_ci bti = nir_iadd_imm(b, src->ssa, bt->offsets[group]); 852bf215546Sopenharmony_ci } 853bf215546Sopenharmony_ci nir_instr_rewrite_src(instr, src, nir_src_for_ssa(bti)); 854bf215546Sopenharmony_ci} 855bf215546Sopenharmony_ci 856bf215546Sopenharmony_cistatic void 857bf215546Sopenharmony_cimark_used_with_src(struct iris_binding_table *bt, nir_src *src, 858bf215546Sopenharmony_ci enum iris_surface_group group) 859bf215546Sopenharmony_ci{ 860bf215546Sopenharmony_ci assert(bt->sizes[group] > 0); 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_ci if (nir_src_is_const(*src)) { 863bf215546Sopenharmony_ci uint64_t index = nir_src_as_uint(*src); 864bf215546Sopenharmony_ci assert(index < bt->sizes[group]); 865bf215546Sopenharmony_ci bt->used_mask[group] |= 1ull << index; 866bf215546Sopenharmony_ci } else { 867bf215546Sopenharmony_ci /* There's an indirect usage, we need all the surfaces. */ 868bf215546Sopenharmony_ci bt->used_mask[group] = BITFIELD64_MASK(bt->sizes[group]); 869bf215546Sopenharmony_ci } 870bf215546Sopenharmony_ci} 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_cistatic bool 873bf215546Sopenharmony_ciskip_compacting_binding_tables(void) 874bf215546Sopenharmony_ci{ 875bf215546Sopenharmony_ci static int skip = -1; 876bf215546Sopenharmony_ci if (skip < 0) 877bf215546Sopenharmony_ci skip = env_var_as_boolean("INTEL_DISABLE_COMPACT_BINDING_TABLE", false); 878bf215546Sopenharmony_ci return skip; 879bf215546Sopenharmony_ci} 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_ci/** 882bf215546Sopenharmony_ci * Set up the binding table indices and apply to the shader. 883bf215546Sopenharmony_ci */ 884bf215546Sopenharmony_cistatic void 885bf215546Sopenharmony_ciiris_setup_binding_table(const struct intel_device_info *devinfo, 886bf215546Sopenharmony_ci struct nir_shader *nir, 887bf215546Sopenharmony_ci struct iris_binding_table *bt, 888bf215546Sopenharmony_ci unsigned num_render_targets, 889bf215546Sopenharmony_ci unsigned num_system_values, 890bf215546Sopenharmony_ci unsigned num_cbufs) 891bf215546Sopenharmony_ci{ 892bf215546Sopenharmony_ci const struct shader_info *info = &nir->info; 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci memset(bt, 0, sizeof(*bt)); 895bf215546Sopenharmony_ci 896bf215546Sopenharmony_ci /* Set the sizes for each surface group. For some groups, we already know 897bf215546Sopenharmony_ci * upfront how many will be used, so mark them. 898bf215546Sopenharmony_ci */ 899bf215546Sopenharmony_ci if (info->stage == MESA_SHADER_FRAGMENT) { 900bf215546Sopenharmony_ci bt->sizes[IRIS_SURFACE_GROUP_RENDER_TARGET] = num_render_targets; 901bf215546Sopenharmony_ci /* All render targets used. */ 902bf215546Sopenharmony_ci bt->used_mask[IRIS_SURFACE_GROUP_RENDER_TARGET] = 903bf215546Sopenharmony_ci BITFIELD64_MASK(num_render_targets); 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_ci /* Setup render target read surface group in order to support non-coherent 906bf215546Sopenharmony_ci * framebuffer fetch on Gfx8 907bf215546Sopenharmony_ci */ 908bf215546Sopenharmony_ci if (devinfo->ver == 8 && info->outputs_read) { 909bf215546Sopenharmony_ci bt->sizes[IRIS_SURFACE_GROUP_RENDER_TARGET_READ] = num_render_targets; 910bf215546Sopenharmony_ci bt->used_mask[IRIS_SURFACE_GROUP_RENDER_TARGET_READ] = 911bf215546Sopenharmony_ci BITFIELD64_MASK(num_render_targets); 912bf215546Sopenharmony_ci } 913bf215546Sopenharmony_ci } else if (info->stage == MESA_SHADER_COMPUTE) { 914bf215546Sopenharmony_ci bt->sizes[IRIS_SURFACE_GROUP_CS_WORK_GROUPS] = 1; 915bf215546Sopenharmony_ci } 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci bt->sizes[IRIS_SURFACE_GROUP_TEXTURE] = BITSET_LAST_BIT(info->textures_used); 918bf215546Sopenharmony_ci bt->used_mask[IRIS_SURFACE_GROUP_TEXTURE] = info->textures_used[0]; 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_ci bt->sizes[IRIS_SURFACE_GROUP_IMAGE] = info->num_images; 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci /* Allocate an extra slot in the UBO section for NIR constants. 923bf215546Sopenharmony_ci * Binding table compaction will remove it if unnecessary. 924bf215546Sopenharmony_ci * 925bf215546Sopenharmony_ci * We don't include them in iris_compiled_shader::num_cbufs because 926bf215546Sopenharmony_ci * they are uploaded separately from shs->constbuf[], but from a shader 927bf215546Sopenharmony_ci * point of view, they're another UBO (at the end of the section). 928bf215546Sopenharmony_ci */ 929bf215546Sopenharmony_ci bt->sizes[IRIS_SURFACE_GROUP_UBO] = num_cbufs + 1; 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci bt->sizes[IRIS_SURFACE_GROUP_SSBO] = info->num_ssbos; 932bf215546Sopenharmony_ci 933bf215546Sopenharmony_ci for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) 934bf215546Sopenharmony_ci assert(bt->sizes[i] <= SURFACE_GROUP_MAX_ELEMENTS); 935bf215546Sopenharmony_ci 936bf215546Sopenharmony_ci /* Mark surfaces used for the cases we don't have the information available 937bf215546Sopenharmony_ci * upfront. 938bf215546Sopenharmony_ci */ 939bf215546Sopenharmony_ci nir_function_impl *impl = nir_shader_get_entrypoint(nir); 940bf215546Sopenharmony_ci nir_foreach_block (block, impl) { 941bf215546Sopenharmony_ci nir_foreach_instr (instr, block) { 942bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 943bf215546Sopenharmony_ci continue; 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 946bf215546Sopenharmony_ci switch (intrin->intrinsic) { 947bf215546Sopenharmony_ci case nir_intrinsic_load_num_workgroups: 948bf215546Sopenharmony_ci bt->used_mask[IRIS_SURFACE_GROUP_CS_WORK_GROUPS] = 1; 949bf215546Sopenharmony_ci break; 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci case nir_intrinsic_load_output: 952bf215546Sopenharmony_ci if (devinfo->ver == 8) { 953bf215546Sopenharmony_ci mark_used_with_src(bt, &intrin->src[0], 954bf215546Sopenharmony_ci IRIS_SURFACE_GROUP_RENDER_TARGET_READ); 955bf215546Sopenharmony_ci } 956bf215546Sopenharmony_ci break; 957bf215546Sopenharmony_ci 958bf215546Sopenharmony_ci case nir_intrinsic_image_size: 959bf215546Sopenharmony_ci case nir_intrinsic_image_load: 960bf215546Sopenharmony_ci case nir_intrinsic_image_store: 961bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_add: 962bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_imin: 963bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_umin: 964bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_imax: 965bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_umax: 966bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_and: 967bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_or: 968bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_xor: 969bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_exchange: 970bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_comp_swap: 971bf215546Sopenharmony_ci case nir_intrinsic_image_load_raw_intel: 972bf215546Sopenharmony_ci case nir_intrinsic_image_store_raw_intel: 973bf215546Sopenharmony_ci mark_used_with_src(bt, &intrin->src[0], IRIS_SURFACE_GROUP_IMAGE); 974bf215546Sopenharmony_ci break; 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_ci case nir_intrinsic_load_ubo: 977bf215546Sopenharmony_ci mark_used_with_src(bt, &intrin->src[0], IRIS_SURFACE_GROUP_UBO); 978bf215546Sopenharmony_ci break; 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_ci case nir_intrinsic_store_ssbo: 981bf215546Sopenharmony_ci mark_used_with_src(bt, &intrin->src[1], IRIS_SURFACE_GROUP_SSBO); 982bf215546Sopenharmony_ci break; 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci case nir_intrinsic_get_ssbo_size: 985bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_add: 986bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_imin: 987bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_umin: 988bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_imax: 989bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_umax: 990bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_and: 991bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_or: 992bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_xor: 993bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_exchange: 994bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_comp_swap: 995bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_fmin: 996bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_fmax: 997bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_fcomp_swap: 998bf215546Sopenharmony_ci case nir_intrinsic_load_ssbo: 999bf215546Sopenharmony_ci mark_used_with_src(bt, &intrin->src[0], IRIS_SURFACE_GROUP_SSBO); 1000bf215546Sopenharmony_ci break; 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci default: 1003bf215546Sopenharmony_ci break; 1004bf215546Sopenharmony_ci } 1005bf215546Sopenharmony_ci } 1006bf215546Sopenharmony_ci } 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci /* When disable we just mark everything as used. */ 1009bf215546Sopenharmony_ci if (unlikely(skip_compacting_binding_tables())) { 1010bf215546Sopenharmony_ci for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) 1011bf215546Sopenharmony_ci bt->used_mask[i] = BITFIELD64_MASK(bt->sizes[i]); 1012bf215546Sopenharmony_ci } 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci /* Calculate the offsets and the binding table size based on the used 1015bf215546Sopenharmony_ci * surfaces. After this point, the functions to go between "group indices" 1016bf215546Sopenharmony_ci * and binding table indices can be used. 1017bf215546Sopenharmony_ci */ 1018bf215546Sopenharmony_ci uint32_t next = 0; 1019bf215546Sopenharmony_ci for (int i = 0; i < IRIS_SURFACE_GROUP_COUNT; i++) { 1020bf215546Sopenharmony_ci if (bt->used_mask[i] != 0) { 1021bf215546Sopenharmony_ci bt->offsets[i] = next; 1022bf215546Sopenharmony_ci next += util_bitcount64(bt->used_mask[i]); 1023bf215546Sopenharmony_ci } 1024bf215546Sopenharmony_ci } 1025bf215546Sopenharmony_ci bt->size_bytes = next * 4; 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci if (INTEL_DEBUG(DEBUG_BT)) { 1028bf215546Sopenharmony_ci iris_print_binding_table(stderr, gl_shader_stage_name(info->stage), bt); 1029bf215546Sopenharmony_ci } 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_ci /* Apply the binding table indices. The backend compiler is not expected 1032bf215546Sopenharmony_ci * to change those, as we haven't set any of the *_start entries in brw 1033bf215546Sopenharmony_ci * binding_table. 1034bf215546Sopenharmony_ci */ 1035bf215546Sopenharmony_ci nir_builder b; 1036bf215546Sopenharmony_ci nir_builder_init(&b, impl); 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci nir_foreach_block (block, impl) { 1039bf215546Sopenharmony_ci nir_foreach_instr (instr, block) { 1040bf215546Sopenharmony_ci if (instr->type == nir_instr_type_tex) { 1041bf215546Sopenharmony_ci nir_tex_instr *tex = nir_instr_as_tex(instr); 1042bf215546Sopenharmony_ci tex->texture_index = 1043bf215546Sopenharmony_ci iris_group_index_to_bti(bt, IRIS_SURFACE_GROUP_TEXTURE, 1044bf215546Sopenharmony_ci tex->texture_index); 1045bf215546Sopenharmony_ci continue; 1046bf215546Sopenharmony_ci } 1047bf215546Sopenharmony_ci 1048bf215546Sopenharmony_ci if (instr->type != nir_instr_type_intrinsic) 1049bf215546Sopenharmony_ci continue; 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ci nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); 1052bf215546Sopenharmony_ci switch (intrin->intrinsic) { 1053bf215546Sopenharmony_ci case nir_intrinsic_image_size: 1054bf215546Sopenharmony_ci case nir_intrinsic_image_load: 1055bf215546Sopenharmony_ci case nir_intrinsic_image_store: 1056bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_add: 1057bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_imin: 1058bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_umin: 1059bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_imax: 1060bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_umax: 1061bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_and: 1062bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_or: 1063bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_xor: 1064bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_exchange: 1065bf215546Sopenharmony_ci case nir_intrinsic_image_atomic_comp_swap: 1066bf215546Sopenharmony_ci case nir_intrinsic_image_load_raw_intel: 1067bf215546Sopenharmony_ci case nir_intrinsic_image_store_raw_intel: 1068bf215546Sopenharmony_ci rewrite_src_with_bti(&b, bt, instr, &intrin->src[0], 1069bf215546Sopenharmony_ci IRIS_SURFACE_GROUP_IMAGE); 1070bf215546Sopenharmony_ci break; 1071bf215546Sopenharmony_ci 1072bf215546Sopenharmony_ci case nir_intrinsic_load_ubo: 1073bf215546Sopenharmony_ci rewrite_src_with_bti(&b, bt, instr, &intrin->src[0], 1074bf215546Sopenharmony_ci IRIS_SURFACE_GROUP_UBO); 1075bf215546Sopenharmony_ci break; 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ci case nir_intrinsic_store_ssbo: 1078bf215546Sopenharmony_ci rewrite_src_with_bti(&b, bt, instr, &intrin->src[1], 1079bf215546Sopenharmony_ci IRIS_SURFACE_GROUP_SSBO); 1080bf215546Sopenharmony_ci break; 1081bf215546Sopenharmony_ci 1082bf215546Sopenharmony_ci case nir_intrinsic_load_output: 1083bf215546Sopenharmony_ci if (devinfo->ver == 8) { 1084bf215546Sopenharmony_ci rewrite_src_with_bti(&b, bt, instr, &intrin->src[0], 1085bf215546Sopenharmony_ci IRIS_SURFACE_GROUP_RENDER_TARGET_READ); 1086bf215546Sopenharmony_ci } 1087bf215546Sopenharmony_ci break; 1088bf215546Sopenharmony_ci 1089bf215546Sopenharmony_ci case nir_intrinsic_get_ssbo_size: 1090bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_add: 1091bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_imin: 1092bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_umin: 1093bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_imax: 1094bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_umax: 1095bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_and: 1096bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_or: 1097bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_xor: 1098bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_exchange: 1099bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_comp_swap: 1100bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_fmin: 1101bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_fmax: 1102bf215546Sopenharmony_ci case nir_intrinsic_ssbo_atomic_fcomp_swap: 1103bf215546Sopenharmony_ci case nir_intrinsic_load_ssbo: 1104bf215546Sopenharmony_ci rewrite_src_with_bti(&b, bt, instr, &intrin->src[0], 1105bf215546Sopenharmony_ci IRIS_SURFACE_GROUP_SSBO); 1106bf215546Sopenharmony_ci break; 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci default: 1109bf215546Sopenharmony_ci break; 1110bf215546Sopenharmony_ci } 1111bf215546Sopenharmony_ci } 1112bf215546Sopenharmony_ci } 1113bf215546Sopenharmony_ci} 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_cistatic void 1116bf215546Sopenharmony_ciiris_debug_recompile(struct iris_screen *screen, 1117bf215546Sopenharmony_ci struct util_debug_callback *dbg, 1118bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 1119bf215546Sopenharmony_ci const struct brw_base_prog_key *key) 1120bf215546Sopenharmony_ci{ 1121bf215546Sopenharmony_ci if (!ish || list_is_empty(&ish->variants) 1122bf215546Sopenharmony_ci || list_is_singular(&ish->variants)) 1123bf215546Sopenharmony_ci return; 1124bf215546Sopenharmony_ci 1125bf215546Sopenharmony_ci const struct brw_compiler *c = screen->compiler; 1126bf215546Sopenharmony_ci const struct shader_info *info = &ish->nir->info; 1127bf215546Sopenharmony_ci 1128bf215546Sopenharmony_ci brw_shader_perf_log(c, dbg, "Recompiling %s shader for program %s: %s\n", 1129bf215546Sopenharmony_ci _mesa_shader_stage_to_string(info->stage), 1130bf215546Sopenharmony_ci info->name ? info->name : "(no identifier)", 1131bf215546Sopenharmony_ci info->label ? info->label : ""); 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci struct iris_compiled_shader *shader = 1134bf215546Sopenharmony_ci list_first_entry(&ish->variants, struct iris_compiled_shader, link); 1135bf215546Sopenharmony_ci const void *old_iris_key = &shader->key; 1136bf215546Sopenharmony_ci 1137bf215546Sopenharmony_ci union brw_any_prog_key old_key; 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_ci switch (info->stage) { 1140bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 1141bf215546Sopenharmony_ci old_key.vs = iris_to_brw_vs_key(screen, old_iris_key); 1142bf215546Sopenharmony_ci break; 1143bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 1144bf215546Sopenharmony_ci old_key.tcs = iris_to_brw_tcs_key(screen, old_iris_key); 1145bf215546Sopenharmony_ci break; 1146bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 1147bf215546Sopenharmony_ci old_key.tes = iris_to_brw_tes_key(screen, old_iris_key); 1148bf215546Sopenharmony_ci break; 1149bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 1150bf215546Sopenharmony_ci old_key.gs = iris_to_brw_gs_key(screen, old_iris_key); 1151bf215546Sopenharmony_ci break; 1152bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 1153bf215546Sopenharmony_ci old_key.wm = iris_to_brw_fs_key(screen, old_iris_key); 1154bf215546Sopenharmony_ci break; 1155bf215546Sopenharmony_ci case MESA_SHADER_COMPUTE: 1156bf215546Sopenharmony_ci old_key.cs = iris_to_brw_cs_key(screen, old_iris_key); 1157bf215546Sopenharmony_ci break; 1158bf215546Sopenharmony_ci default: 1159bf215546Sopenharmony_ci unreachable("invalid shader stage"); 1160bf215546Sopenharmony_ci } 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci brw_debug_key_recompile(c, dbg, info->stage, &old_key.base, key); 1163bf215546Sopenharmony_ci} 1164bf215546Sopenharmony_ci 1165bf215546Sopenharmony_cistatic void 1166bf215546Sopenharmony_cicheck_urb_size(struct iris_context *ice, 1167bf215546Sopenharmony_ci unsigned needed_size, 1168bf215546Sopenharmony_ci gl_shader_stage stage) 1169bf215546Sopenharmony_ci{ 1170bf215546Sopenharmony_ci unsigned last_allocated_size = ice->shaders.urb.size[stage]; 1171bf215546Sopenharmony_ci 1172bf215546Sopenharmony_ci /* If the last URB allocation wasn't large enough for our needs, 1173bf215546Sopenharmony_ci * flag it as needing to be reconfigured. Otherwise, we can use 1174bf215546Sopenharmony_ci * the existing config. However, if the URB is constrained, and 1175bf215546Sopenharmony_ci * we can shrink our size for this stage, we may be able to gain 1176bf215546Sopenharmony_ci * extra concurrency by reconfiguring it to be smaller. Do so. 1177bf215546Sopenharmony_ci */ 1178bf215546Sopenharmony_ci if (last_allocated_size < needed_size || 1179bf215546Sopenharmony_ci (ice->shaders.urb.constrained && last_allocated_size > needed_size)) { 1180bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_URB; 1181bf215546Sopenharmony_ci } 1182bf215546Sopenharmony_ci} 1183bf215546Sopenharmony_ci 1184bf215546Sopenharmony_ci/** 1185bf215546Sopenharmony_ci * Get the shader for the last enabled geometry stage. 1186bf215546Sopenharmony_ci * 1187bf215546Sopenharmony_ci * This stage is the one which will feed stream output and the rasterizer. 1188bf215546Sopenharmony_ci */ 1189bf215546Sopenharmony_cistatic gl_shader_stage 1190bf215546Sopenharmony_cilast_vue_stage(struct iris_context *ice) 1191bf215546Sopenharmony_ci{ 1192bf215546Sopenharmony_ci if (ice->shaders.uncompiled[MESA_SHADER_GEOMETRY]) 1193bf215546Sopenharmony_ci return MESA_SHADER_GEOMETRY; 1194bf215546Sopenharmony_ci 1195bf215546Sopenharmony_ci if (ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL]) 1196bf215546Sopenharmony_ci return MESA_SHADER_TESS_EVAL; 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ci return MESA_SHADER_VERTEX; 1199bf215546Sopenharmony_ci} 1200bf215546Sopenharmony_ci 1201bf215546Sopenharmony_ci/** 1202bf215546Sopenharmony_ci * \param added Set to \c true if the variant was added to the list (i.e., a 1203bf215546Sopenharmony_ci * variant matching \c key was not found). Set to \c false 1204bf215546Sopenharmony_ci * otherwise. 1205bf215546Sopenharmony_ci */ 1206bf215546Sopenharmony_cistatic inline struct iris_compiled_shader * 1207bf215546Sopenharmony_cifind_or_add_variant(const struct iris_screen *screen, 1208bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 1209bf215546Sopenharmony_ci enum iris_program_cache_id cache_id, 1210bf215546Sopenharmony_ci const void *key, unsigned key_size, 1211bf215546Sopenharmony_ci bool *added) 1212bf215546Sopenharmony_ci{ 1213bf215546Sopenharmony_ci struct list_head *start = ish->variants.next; 1214bf215546Sopenharmony_ci 1215bf215546Sopenharmony_ci *added = false; 1216bf215546Sopenharmony_ci 1217bf215546Sopenharmony_ci if (screen->precompile) { 1218bf215546Sopenharmony_ci /* Check the first list entry. There will always be at least one 1219bf215546Sopenharmony_ci * variant in the list (most likely the precompile variant), and 1220bf215546Sopenharmony_ci * other contexts only append new variants, so we can safely check 1221bf215546Sopenharmony_ci * it without locking, saving that cost in the common case. 1222bf215546Sopenharmony_ci */ 1223bf215546Sopenharmony_ci struct iris_compiled_shader *first = 1224bf215546Sopenharmony_ci list_first_entry(&ish->variants, struct iris_compiled_shader, link); 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci if (memcmp(&first->key, key, key_size) == 0) { 1227bf215546Sopenharmony_ci util_queue_fence_wait(&first->ready); 1228bf215546Sopenharmony_ci return first; 1229bf215546Sopenharmony_ci } 1230bf215546Sopenharmony_ci 1231bf215546Sopenharmony_ci /* Skip this one in the loop below */ 1232bf215546Sopenharmony_ci start = first->link.next; 1233bf215546Sopenharmony_ci } 1234bf215546Sopenharmony_ci 1235bf215546Sopenharmony_ci struct iris_compiled_shader *variant = NULL; 1236bf215546Sopenharmony_ci 1237bf215546Sopenharmony_ci /* If it doesn't match, we have to walk the list; other contexts may be 1238bf215546Sopenharmony_ci * concurrently appending shaders to it, so we need to lock here. 1239bf215546Sopenharmony_ci */ 1240bf215546Sopenharmony_ci simple_mtx_lock(&ish->lock); 1241bf215546Sopenharmony_ci 1242bf215546Sopenharmony_ci list_for_each_entry_from(struct iris_compiled_shader, v, start, 1243bf215546Sopenharmony_ci &ish->variants, link) { 1244bf215546Sopenharmony_ci if (memcmp(&v->key, key, key_size) == 0) { 1245bf215546Sopenharmony_ci variant = v; 1246bf215546Sopenharmony_ci break; 1247bf215546Sopenharmony_ci } 1248bf215546Sopenharmony_ci } 1249bf215546Sopenharmony_ci 1250bf215546Sopenharmony_ci if (variant == NULL) { 1251bf215546Sopenharmony_ci variant = iris_create_shader_variant(screen, NULL, cache_id, 1252bf215546Sopenharmony_ci key_size, key); 1253bf215546Sopenharmony_ci 1254bf215546Sopenharmony_ci /* Append our new variant to the shader's variant list. */ 1255bf215546Sopenharmony_ci list_addtail(&variant->link, &ish->variants); 1256bf215546Sopenharmony_ci *added = true; 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci simple_mtx_unlock(&ish->lock); 1259bf215546Sopenharmony_ci } else { 1260bf215546Sopenharmony_ci simple_mtx_unlock(&ish->lock); 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ci util_queue_fence_wait(&variant->ready); 1263bf215546Sopenharmony_ci } 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_ci return variant; 1266bf215546Sopenharmony_ci} 1267bf215546Sopenharmony_ci 1268bf215546Sopenharmony_cistatic void 1269bf215546Sopenharmony_ciiris_threaded_compile_job_delete(void *_job, UNUSED void *_gdata, 1270bf215546Sopenharmony_ci UNUSED int thread_index) 1271bf215546Sopenharmony_ci{ 1272bf215546Sopenharmony_ci free(_job); 1273bf215546Sopenharmony_ci} 1274bf215546Sopenharmony_ci 1275bf215546Sopenharmony_cistatic void 1276bf215546Sopenharmony_ciiris_schedule_compile(struct iris_screen *screen, 1277bf215546Sopenharmony_ci struct util_queue_fence *ready_fence, 1278bf215546Sopenharmony_ci struct util_debug_callback *dbg, 1279bf215546Sopenharmony_ci struct iris_threaded_compile_job *job, 1280bf215546Sopenharmony_ci util_queue_execute_func execute) 1281bf215546Sopenharmony_ci 1282bf215546Sopenharmony_ci{ 1283bf215546Sopenharmony_ci struct util_async_debug_callback async_debug; 1284bf215546Sopenharmony_ci 1285bf215546Sopenharmony_ci if (dbg) { 1286bf215546Sopenharmony_ci u_async_debug_init(&async_debug); 1287bf215546Sopenharmony_ci job->dbg = &async_debug.base; 1288bf215546Sopenharmony_ci } 1289bf215546Sopenharmony_ci 1290bf215546Sopenharmony_ci util_queue_add_job(&screen->shader_compiler_queue, job, ready_fence, execute, 1291bf215546Sopenharmony_ci iris_threaded_compile_job_delete, 0); 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci if (screen->driconf.sync_compile || dbg) 1294bf215546Sopenharmony_ci util_queue_fence_wait(ready_fence); 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_ci if (dbg) { 1297bf215546Sopenharmony_ci u_async_debug_drain(&async_debug, dbg); 1298bf215546Sopenharmony_ci u_async_debug_cleanup(&async_debug); 1299bf215546Sopenharmony_ci } 1300bf215546Sopenharmony_ci} 1301bf215546Sopenharmony_ci 1302bf215546Sopenharmony_ci/** 1303bf215546Sopenharmony_ci * Compile a vertex shader, and upload the assembly. 1304bf215546Sopenharmony_ci */ 1305bf215546Sopenharmony_cistatic void 1306bf215546Sopenharmony_ciiris_compile_vs(struct iris_screen *screen, 1307bf215546Sopenharmony_ci struct u_upload_mgr *uploader, 1308bf215546Sopenharmony_ci struct util_debug_callback *dbg, 1309bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 1310bf215546Sopenharmony_ci struct iris_compiled_shader *shader) 1311bf215546Sopenharmony_ci{ 1312bf215546Sopenharmony_ci const struct brw_compiler *compiler = screen->compiler; 1313bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 1314bf215546Sopenharmony_ci void *mem_ctx = ralloc_context(NULL); 1315bf215546Sopenharmony_ci struct brw_vs_prog_data *vs_prog_data = 1316bf215546Sopenharmony_ci rzalloc(mem_ctx, struct brw_vs_prog_data); 1317bf215546Sopenharmony_ci struct brw_vue_prog_data *vue_prog_data = &vs_prog_data->base; 1318bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data = &vue_prog_data->base; 1319bf215546Sopenharmony_ci enum brw_param_builtin *system_values; 1320bf215546Sopenharmony_ci unsigned num_system_values; 1321bf215546Sopenharmony_ci unsigned num_cbufs; 1322bf215546Sopenharmony_ci 1323bf215546Sopenharmony_ci nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir); 1324bf215546Sopenharmony_ci const struct iris_vs_prog_key *const key = &shader->key.vs; 1325bf215546Sopenharmony_ci 1326bf215546Sopenharmony_ci if (key->vue.nr_userclip_plane_consts) { 1327bf215546Sopenharmony_ci nir_function_impl *impl = nir_shader_get_entrypoint(nir); 1328bf215546Sopenharmony_ci nir_lower_clip_vs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1, 1329bf215546Sopenharmony_ci true, false, NULL); 1330bf215546Sopenharmony_ci nir_lower_io_to_temporaries(nir, impl, true, false); 1331bf215546Sopenharmony_ci nir_lower_global_vars_to_local(nir); 1332bf215546Sopenharmony_ci nir_lower_vars_to_ssa(nir); 1333bf215546Sopenharmony_ci nir_shader_gather_info(nir, impl); 1334bf215546Sopenharmony_ci } 1335bf215546Sopenharmony_ci 1336bf215546Sopenharmony_ci prog_data->use_alt_mode = nir->info.use_legacy_math_rules; 1337bf215546Sopenharmony_ci 1338bf215546Sopenharmony_ci iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values, 1339bf215546Sopenharmony_ci &num_system_values, &num_cbufs); 1340bf215546Sopenharmony_ci 1341bf215546Sopenharmony_ci struct iris_binding_table bt; 1342bf215546Sopenharmony_ci iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0, 1343bf215546Sopenharmony_ci num_system_values, num_cbufs); 1344bf215546Sopenharmony_ci 1345bf215546Sopenharmony_ci brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges); 1346bf215546Sopenharmony_ci 1347bf215546Sopenharmony_ci brw_compute_vue_map(devinfo, 1348bf215546Sopenharmony_ci &vue_prog_data->vue_map, nir->info.outputs_written, 1349bf215546Sopenharmony_ci nir->info.separate_shader, /* pos_slots */ 1); 1350bf215546Sopenharmony_ci 1351bf215546Sopenharmony_ci struct brw_vs_prog_key brw_key = iris_to_brw_vs_key(screen, key); 1352bf215546Sopenharmony_ci 1353bf215546Sopenharmony_ci struct brw_compile_vs_params params = { 1354bf215546Sopenharmony_ci .nir = nir, 1355bf215546Sopenharmony_ci .key = &brw_key, 1356bf215546Sopenharmony_ci .prog_data = vs_prog_data, 1357bf215546Sopenharmony_ci .log_data = dbg, 1358bf215546Sopenharmony_ci }; 1359bf215546Sopenharmony_ci 1360bf215546Sopenharmony_ci const unsigned *program = brw_compile_vs(compiler, mem_ctx, ¶ms); 1361bf215546Sopenharmony_ci if (program == NULL) { 1362bf215546Sopenharmony_ci dbg_printf("Failed to compile vertex shader: %s\n", params.error_str); 1363bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci shader->compilation_failed = true; 1366bf215546Sopenharmony_ci util_queue_fence_signal(&shader->ready); 1367bf215546Sopenharmony_ci 1368bf215546Sopenharmony_ci return; 1369bf215546Sopenharmony_ci } 1370bf215546Sopenharmony_ci 1371bf215546Sopenharmony_ci shader->compilation_failed = false; 1372bf215546Sopenharmony_ci 1373bf215546Sopenharmony_ci iris_debug_recompile(screen, dbg, ish, &brw_key.base); 1374bf215546Sopenharmony_ci 1375bf215546Sopenharmony_ci uint32_t *so_decls = 1376bf215546Sopenharmony_ci screen->vtbl.create_so_decl_list(&ish->stream_output, 1377bf215546Sopenharmony_ci &vue_prog_data->vue_map); 1378bf215546Sopenharmony_ci 1379bf215546Sopenharmony_ci iris_finalize_program(shader, prog_data, so_decls, system_values, 1380bf215546Sopenharmony_ci num_system_values, 0, num_cbufs, &bt); 1381bf215546Sopenharmony_ci 1382bf215546Sopenharmony_ci iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_VS, 1383bf215546Sopenharmony_ci sizeof(*key), key, program); 1384bf215546Sopenharmony_ci 1385bf215546Sopenharmony_ci iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key)); 1386bf215546Sopenharmony_ci 1387bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1388bf215546Sopenharmony_ci} 1389bf215546Sopenharmony_ci 1390bf215546Sopenharmony_ci/** 1391bf215546Sopenharmony_ci * Update the current vertex shader variant. 1392bf215546Sopenharmony_ci * 1393bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed. 1394bf215546Sopenharmony_ci */ 1395bf215546Sopenharmony_cistatic void 1396bf215546Sopenharmony_ciiris_update_compiled_vs(struct iris_context *ice) 1397bf215546Sopenharmony_ci{ 1398bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 1399bf215546Sopenharmony_ci struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_VERTEX]; 1400bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_driver; 1401bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 1402bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_VERTEX]; 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_ci struct iris_vs_prog_key key = { KEY_INIT(vue.base) }; 1405bf215546Sopenharmony_ci screen->vtbl.populate_vs_key(ice, &ish->nir->info, last_vue_stage(ice), &key); 1406bf215546Sopenharmony_ci 1407bf215546Sopenharmony_ci struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_VS]; 1408bf215546Sopenharmony_ci bool added; 1409bf215546Sopenharmony_ci struct iris_compiled_shader *shader = 1410bf215546Sopenharmony_ci find_or_add_variant(screen, ish, IRIS_CACHE_VS, &key, sizeof(key), &added); 1411bf215546Sopenharmony_ci 1412bf215546Sopenharmony_ci if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader, 1413bf215546Sopenharmony_ci &key, sizeof(key))) { 1414bf215546Sopenharmony_ci iris_compile_vs(screen, uploader, &ice->dbg, ish, shader); 1415bf215546Sopenharmony_ci } 1416bf215546Sopenharmony_ci 1417bf215546Sopenharmony_ci if (shader->compilation_failed) 1418bf215546Sopenharmony_ci shader = NULL; 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_ci if (old != shader) { 1421bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_VERTEX], 1422bf215546Sopenharmony_ci shader); 1423bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_VF_SGVS; 1424bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_VS | 1425bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_BINDINGS_VS | 1426bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_CONSTANTS_VS; 1427bf215546Sopenharmony_ci shs->sysvals_need_upload = true; 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci unsigned urb_entry_size = shader ? 1430bf215546Sopenharmony_ci ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0; 1431bf215546Sopenharmony_ci check_urb_size(ice, urb_entry_size, MESA_SHADER_VERTEX); 1432bf215546Sopenharmony_ci } 1433bf215546Sopenharmony_ci} 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_ci/** 1436bf215546Sopenharmony_ci * Get the shader_info for a given stage, or NULL if the stage is disabled. 1437bf215546Sopenharmony_ci */ 1438bf215546Sopenharmony_ciconst struct shader_info * 1439bf215546Sopenharmony_ciiris_get_shader_info(const struct iris_context *ice, gl_shader_stage stage) 1440bf215546Sopenharmony_ci{ 1441bf215546Sopenharmony_ci const struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[stage]; 1442bf215546Sopenharmony_ci 1443bf215546Sopenharmony_ci if (!ish) 1444bf215546Sopenharmony_ci return NULL; 1445bf215546Sopenharmony_ci 1446bf215546Sopenharmony_ci const nir_shader *nir = ish->nir; 1447bf215546Sopenharmony_ci return &nir->info; 1448bf215546Sopenharmony_ci} 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_ci/** 1451bf215546Sopenharmony_ci * Get the union of TCS output and TES input slots. 1452bf215546Sopenharmony_ci * 1453bf215546Sopenharmony_ci * TCS and TES need to agree on a common URB entry layout. In particular, 1454bf215546Sopenharmony_ci * the data for all patch vertices is stored in a single URB entry (unlike 1455bf215546Sopenharmony_ci * GS which has one entry per input vertex). This means that per-vertex 1456bf215546Sopenharmony_ci * array indexing needs a stride. 1457bf215546Sopenharmony_ci * 1458bf215546Sopenharmony_ci * SSO requires locations to match, but doesn't require the number of 1459bf215546Sopenharmony_ci * outputs/inputs to match (in fact, the TCS often has extra outputs). 1460bf215546Sopenharmony_ci * So, we need to take the extra step of unifying these on the fly. 1461bf215546Sopenharmony_ci */ 1462bf215546Sopenharmony_cistatic void 1463bf215546Sopenharmony_ciget_unified_tess_slots(const struct iris_context *ice, 1464bf215546Sopenharmony_ci uint64_t *per_vertex_slots, 1465bf215546Sopenharmony_ci uint32_t *per_patch_slots) 1466bf215546Sopenharmony_ci{ 1467bf215546Sopenharmony_ci const struct shader_info *tcs = 1468bf215546Sopenharmony_ci iris_get_shader_info(ice, MESA_SHADER_TESS_CTRL); 1469bf215546Sopenharmony_ci const struct shader_info *tes = 1470bf215546Sopenharmony_ci iris_get_shader_info(ice, MESA_SHADER_TESS_EVAL); 1471bf215546Sopenharmony_ci 1472bf215546Sopenharmony_ci *per_vertex_slots = tes->inputs_read; 1473bf215546Sopenharmony_ci *per_patch_slots = tes->patch_inputs_read; 1474bf215546Sopenharmony_ci 1475bf215546Sopenharmony_ci if (tcs) { 1476bf215546Sopenharmony_ci *per_vertex_slots |= tcs->outputs_written; 1477bf215546Sopenharmony_ci *per_patch_slots |= tcs->patch_outputs_written; 1478bf215546Sopenharmony_ci } 1479bf215546Sopenharmony_ci} 1480bf215546Sopenharmony_ci 1481bf215546Sopenharmony_ci/** 1482bf215546Sopenharmony_ci * Compile a tessellation control shader, and upload the assembly. 1483bf215546Sopenharmony_ci */ 1484bf215546Sopenharmony_cistatic void 1485bf215546Sopenharmony_ciiris_compile_tcs(struct iris_screen *screen, 1486bf215546Sopenharmony_ci struct hash_table *passthrough_ht, 1487bf215546Sopenharmony_ci struct u_upload_mgr *uploader, 1488bf215546Sopenharmony_ci struct util_debug_callback *dbg, 1489bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 1490bf215546Sopenharmony_ci struct iris_compiled_shader *shader) 1491bf215546Sopenharmony_ci{ 1492bf215546Sopenharmony_ci const struct brw_compiler *compiler = screen->compiler; 1493bf215546Sopenharmony_ci const struct nir_shader_compiler_options *options = 1494bf215546Sopenharmony_ci compiler->nir_options[MESA_SHADER_TESS_CTRL]; 1495bf215546Sopenharmony_ci void *mem_ctx = ralloc_context(NULL); 1496bf215546Sopenharmony_ci struct brw_tcs_prog_data *tcs_prog_data = 1497bf215546Sopenharmony_ci rzalloc(mem_ctx, struct brw_tcs_prog_data); 1498bf215546Sopenharmony_ci struct brw_vue_prog_data *vue_prog_data = &tcs_prog_data->base; 1499bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data = &vue_prog_data->base; 1500bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 1501bf215546Sopenharmony_ci enum brw_param_builtin *system_values = NULL; 1502bf215546Sopenharmony_ci unsigned num_system_values = 0; 1503bf215546Sopenharmony_ci unsigned num_cbufs = 0; 1504bf215546Sopenharmony_ci 1505bf215546Sopenharmony_ci nir_shader *nir; 1506bf215546Sopenharmony_ci 1507bf215546Sopenharmony_ci struct iris_binding_table bt; 1508bf215546Sopenharmony_ci 1509bf215546Sopenharmony_ci const struct iris_tcs_prog_key *const key = &shader->key.tcs; 1510bf215546Sopenharmony_ci struct brw_tcs_prog_key brw_key = iris_to_brw_tcs_key(screen, key); 1511bf215546Sopenharmony_ci 1512bf215546Sopenharmony_ci if (ish) { 1513bf215546Sopenharmony_ci nir = nir_shader_clone(mem_ctx, ish->nir); 1514bf215546Sopenharmony_ci 1515bf215546Sopenharmony_ci iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values, 1516bf215546Sopenharmony_ci &num_system_values, &num_cbufs); 1517bf215546Sopenharmony_ci iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0, 1518bf215546Sopenharmony_ci num_system_values, num_cbufs); 1519bf215546Sopenharmony_ci brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges); 1520bf215546Sopenharmony_ci } else { 1521bf215546Sopenharmony_ci nir = 1522bf215546Sopenharmony_ci brw_nir_create_passthrough_tcs(mem_ctx, compiler, options, &brw_key); 1523bf215546Sopenharmony_ci 1524bf215546Sopenharmony_ci /* Reserve space for passing the default tess levels as constants. */ 1525bf215546Sopenharmony_ci num_cbufs = 1; 1526bf215546Sopenharmony_ci num_system_values = 8; 1527bf215546Sopenharmony_ci system_values = 1528bf215546Sopenharmony_ci rzalloc_array(mem_ctx, enum brw_param_builtin, num_system_values); 1529bf215546Sopenharmony_ci prog_data->param = rzalloc_array(mem_ctx, uint32_t, num_system_values); 1530bf215546Sopenharmony_ci prog_data->nr_params = num_system_values; 1531bf215546Sopenharmony_ci 1532bf215546Sopenharmony_ci if (key->_tes_primitive_mode == TESS_PRIMITIVE_QUADS) { 1533bf215546Sopenharmony_ci for (int i = 0; i < 4; i++) 1534bf215546Sopenharmony_ci system_values[7 - i] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X + i; 1535bf215546Sopenharmony_ci 1536bf215546Sopenharmony_ci system_values[3] = BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_X; 1537bf215546Sopenharmony_ci system_values[2] = BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_Y; 1538bf215546Sopenharmony_ci } else if (key->_tes_primitive_mode == TESS_PRIMITIVE_TRIANGLES) { 1539bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) 1540bf215546Sopenharmony_ci system_values[7 - i] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X + i; 1541bf215546Sopenharmony_ci 1542bf215546Sopenharmony_ci system_values[4] = BRW_PARAM_BUILTIN_TESS_LEVEL_INNER_X; 1543bf215546Sopenharmony_ci } else { 1544bf215546Sopenharmony_ci assert(key->_tes_primitive_mode == TESS_PRIMITIVE_ISOLINES); 1545bf215546Sopenharmony_ci system_values[7] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_Y; 1546bf215546Sopenharmony_ci system_values[6] = BRW_PARAM_BUILTIN_TESS_LEVEL_OUTER_X; 1547bf215546Sopenharmony_ci } 1548bf215546Sopenharmony_ci 1549bf215546Sopenharmony_ci /* Manually setup the TCS binding table. */ 1550bf215546Sopenharmony_ci memset(&bt, 0, sizeof(bt)); 1551bf215546Sopenharmony_ci bt.sizes[IRIS_SURFACE_GROUP_UBO] = 1; 1552bf215546Sopenharmony_ci bt.used_mask[IRIS_SURFACE_GROUP_UBO] = 1; 1553bf215546Sopenharmony_ci bt.size_bytes = 4; 1554bf215546Sopenharmony_ci 1555bf215546Sopenharmony_ci prog_data->ubo_ranges[0].length = 1; 1556bf215546Sopenharmony_ci } 1557bf215546Sopenharmony_ci 1558bf215546Sopenharmony_ci struct brw_compile_tcs_params params = { 1559bf215546Sopenharmony_ci .nir = nir, 1560bf215546Sopenharmony_ci .key = &brw_key, 1561bf215546Sopenharmony_ci .prog_data = tcs_prog_data, 1562bf215546Sopenharmony_ci .log_data = dbg, 1563bf215546Sopenharmony_ci }; 1564bf215546Sopenharmony_ci 1565bf215546Sopenharmony_ci const unsigned *program = brw_compile_tcs(compiler, mem_ctx, ¶ms); 1566bf215546Sopenharmony_ci if (program == NULL) { 1567bf215546Sopenharmony_ci dbg_printf("Failed to compile control shader: %s\n", params.error_str); 1568bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1569bf215546Sopenharmony_ci 1570bf215546Sopenharmony_ci shader->compilation_failed = true; 1571bf215546Sopenharmony_ci util_queue_fence_signal(&shader->ready); 1572bf215546Sopenharmony_ci 1573bf215546Sopenharmony_ci return; 1574bf215546Sopenharmony_ci } 1575bf215546Sopenharmony_ci 1576bf215546Sopenharmony_ci shader->compilation_failed = false; 1577bf215546Sopenharmony_ci 1578bf215546Sopenharmony_ci iris_debug_recompile(screen, dbg, ish, &brw_key.base); 1579bf215546Sopenharmony_ci 1580bf215546Sopenharmony_ci iris_finalize_program(shader, prog_data, NULL, system_values, 1581bf215546Sopenharmony_ci num_system_values, 0, num_cbufs, &bt); 1582bf215546Sopenharmony_ci 1583bf215546Sopenharmony_ci iris_upload_shader(screen, ish, shader, passthrough_ht, uploader, 1584bf215546Sopenharmony_ci IRIS_CACHE_TCS, sizeof(*key), key, program); 1585bf215546Sopenharmony_ci 1586bf215546Sopenharmony_ci if (ish) 1587bf215546Sopenharmony_ci iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key)); 1588bf215546Sopenharmony_ci 1589bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1590bf215546Sopenharmony_ci} 1591bf215546Sopenharmony_ci 1592bf215546Sopenharmony_ci/** 1593bf215546Sopenharmony_ci * Update the current tessellation control shader variant. 1594bf215546Sopenharmony_ci * 1595bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed. 1596bf215546Sopenharmony_ci */ 1597bf215546Sopenharmony_cistatic void 1598bf215546Sopenharmony_ciiris_update_compiled_tcs(struct iris_context *ice) 1599bf215546Sopenharmony_ci{ 1600bf215546Sopenharmony_ci struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_TESS_CTRL]; 1601bf215546Sopenharmony_ci struct iris_uncompiled_shader *tcs = 1602bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_TESS_CTRL]; 1603bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 1604bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_driver; 1605bf215546Sopenharmony_ci const struct brw_compiler *compiler = screen->compiler; 1606bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 1607bf215546Sopenharmony_ci 1608bf215546Sopenharmony_ci const struct shader_info *tes_info = 1609bf215546Sopenharmony_ci iris_get_shader_info(ice, MESA_SHADER_TESS_EVAL); 1610bf215546Sopenharmony_ci struct iris_tcs_prog_key key = { 1611bf215546Sopenharmony_ci .vue.base.program_string_id = tcs ? tcs->program_id : 0, 1612bf215546Sopenharmony_ci ._tes_primitive_mode = tes_info->tess._primitive_mode, 1613bf215546Sopenharmony_ci .input_vertices = 1614bf215546Sopenharmony_ci !tcs || compiler->use_tcs_8_patch ? ice->state.vertices_per_patch : 0, 1615bf215546Sopenharmony_ci .quads_workaround = devinfo->ver < 9 && 1616bf215546Sopenharmony_ci tes_info->tess._primitive_mode == TESS_PRIMITIVE_QUADS && 1617bf215546Sopenharmony_ci tes_info->tess.spacing == TESS_SPACING_EQUAL, 1618bf215546Sopenharmony_ci }; 1619bf215546Sopenharmony_ci get_unified_tess_slots(ice, &key.outputs_written, 1620bf215546Sopenharmony_ci &key.patch_outputs_written); 1621bf215546Sopenharmony_ci screen->vtbl.populate_tcs_key(ice, &key); 1622bf215546Sopenharmony_ci 1623bf215546Sopenharmony_ci struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_TCS]; 1624bf215546Sopenharmony_ci struct iris_compiled_shader *shader; 1625bf215546Sopenharmony_ci bool added = false; 1626bf215546Sopenharmony_ci 1627bf215546Sopenharmony_ci if (tcs != NULL) { 1628bf215546Sopenharmony_ci shader = find_or_add_variant(screen, tcs, IRIS_CACHE_TCS, &key, 1629bf215546Sopenharmony_ci sizeof(key), &added); 1630bf215546Sopenharmony_ci } else { 1631bf215546Sopenharmony_ci /* Look for and possibly create a passthrough TCS */ 1632bf215546Sopenharmony_ci shader = iris_find_cached_shader(ice, IRIS_CACHE_TCS, sizeof(key), &key); 1633bf215546Sopenharmony_ci 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ci if (shader == NULL) { 1636bf215546Sopenharmony_ci shader = iris_create_shader_variant(screen, ice->shaders.cache, 1637bf215546Sopenharmony_ci IRIS_CACHE_TCS, sizeof(key), &key); 1638bf215546Sopenharmony_ci added = true; 1639bf215546Sopenharmony_ci } 1640bf215546Sopenharmony_ci 1641bf215546Sopenharmony_ci } 1642bf215546Sopenharmony_ci 1643bf215546Sopenharmony_ci /* If the shader was not found in (whichever cache), call iris_compile_tcs 1644bf215546Sopenharmony_ci * if either ish is NULL or the shader could not be found in the disk 1645bf215546Sopenharmony_ci * cache. 1646bf215546Sopenharmony_ci */ 1647bf215546Sopenharmony_ci if (added && 1648bf215546Sopenharmony_ci (tcs == NULL || !iris_disk_cache_retrieve(screen, uploader, tcs, shader, 1649bf215546Sopenharmony_ci &key, sizeof(key)))) { 1650bf215546Sopenharmony_ci iris_compile_tcs(screen, ice->shaders.cache, uploader, &ice->dbg, tcs, 1651bf215546Sopenharmony_ci shader); 1652bf215546Sopenharmony_ci } 1653bf215546Sopenharmony_ci 1654bf215546Sopenharmony_ci if (shader->compilation_failed) 1655bf215546Sopenharmony_ci shader = NULL; 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci if (old != shader) { 1658bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_CTRL], 1659bf215546Sopenharmony_ci shader); 1660bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_TCS | 1661bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_BINDINGS_TCS | 1662bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_CONSTANTS_TCS; 1663bf215546Sopenharmony_ci shs->sysvals_need_upload = true; 1664bf215546Sopenharmony_ci 1665bf215546Sopenharmony_ci unsigned urb_entry_size = shader ? 1666bf215546Sopenharmony_ci ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0; 1667bf215546Sopenharmony_ci check_urb_size(ice, urb_entry_size, MESA_SHADER_TESS_CTRL); 1668bf215546Sopenharmony_ci } 1669bf215546Sopenharmony_ci} 1670bf215546Sopenharmony_ci 1671bf215546Sopenharmony_ci/** 1672bf215546Sopenharmony_ci * Compile a tessellation evaluation shader, and upload the assembly. 1673bf215546Sopenharmony_ci */ 1674bf215546Sopenharmony_cistatic void 1675bf215546Sopenharmony_ciiris_compile_tes(struct iris_screen *screen, 1676bf215546Sopenharmony_ci struct u_upload_mgr *uploader, 1677bf215546Sopenharmony_ci struct util_debug_callback *dbg, 1678bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 1679bf215546Sopenharmony_ci struct iris_compiled_shader *shader) 1680bf215546Sopenharmony_ci{ 1681bf215546Sopenharmony_ci const struct brw_compiler *compiler = screen->compiler; 1682bf215546Sopenharmony_ci void *mem_ctx = ralloc_context(NULL); 1683bf215546Sopenharmony_ci struct brw_tes_prog_data *tes_prog_data = 1684bf215546Sopenharmony_ci rzalloc(mem_ctx, struct brw_tes_prog_data); 1685bf215546Sopenharmony_ci struct brw_vue_prog_data *vue_prog_data = &tes_prog_data->base; 1686bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data = &vue_prog_data->base; 1687bf215546Sopenharmony_ci enum brw_param_builtin *system_values; 1688bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 1689bf215546Sopenharmony_ci unsigned num_system_values; 1690bf215546Sopenharmony_ci unsigned num_cbufs; 1691bf215546Sopenharmony_ci 1692bf215546Sopenharmony_ci nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir); 1693bf215546Sopenharmony_ci const struct iris_tes_prog_key *const key = &shader->key.tes; 1694bf215546Sopenharmony_ci 1695bf215546Sopenharmony_ci if (key->vue.nr_userclip_plane_consts) { 1696bf215546Sopenharmony_ci nir_function_impl *impl = nir_shader_get_entrypoint(nir); 1697bf215546Sopenharmony_ci nir_lower_clip_vs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1, 1698bf215546Sopenharmony_ci true, false, NULL); 1699bf215546Sopenharmony_ci nir_lower_io_to_temporaries(nir, impl, true, false); 1700bf215546Sopenharmony_ci nir_lower_global_vars_to_local(nir); 1701bf215546Sopenharmony_ci nir_lower_vars_to_ssa(nir); 1702bf215546Sopenharmony_ci nir_shader_gather_info(nir, impl); 1703bf215546Sopenharmony_ci } 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_ci iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values, 1706bf215546Sopenharmony_ci &num_system_values, &num_cbufs); 1707bf215546Sopenharmony_ci 1708bf215546Sopenharmony_ci struct iris_binding_table bt; 1709bf215546Sopenharmony_ci iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0, 1710bf215546Sopenharmony_ci num_system_values, num_cbufs); 1711bf215546Sopenharmony_ci 1712bf215546Sopenharmony_ci brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges); 1713bf215546Sopenharmony_ci 1714bf215546Sopenharmony_ci struct brw_vue_map input_vue_map; 1715bf215546Sopenharmony_ci brw_compute_tess_vue_map(&input_vue_map, key->inputs_read, 1716bf215546Sopenharmony_ci key->patch_inputs_read); 1717bf215546Sopenharmony_ci 1718bf215546Sopenharmony_ci struct brw_tes_prog_key brw_key = iris_to_brw_tes_key(screen, key); 1719bf215546Sopenharmony_ci 1720bf215546Sopenharmony_ci struct brw_compile_tes_params params = { 1721bf215546Sopenharmony_ci .nir = nir, 1722bf215546Sopenharmony_ci .key = &brw_key, 1723bf215546Sopenharmony_ci .prog_data = tes_prog_data, 1724bf215546Sopenharmony_ci .input_vue_map = &input_vue_map, 1725bf215546Sopenharmony_ci .log_data = dbg, 1726bf215546Sopenharmony_ci }; 1727bf215546Sopenharmony_ci 1728bf215546Sopenharmony_ci const unsigned *program = brw_compile_tes(compiler, mem_ctx, ¶ms); 1729bf215546Sopenharmony_ci if (program == NULL) { 1730bf215546Sopenharmony_ci dbg_printf("Failed to compile evaluation shader: %s\n", params.error_str); 1731bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1732bf215546Sopenharmony_ci 1733bf215546Sopenharmony_ci shader->compilation_failed = true; 1734bf215546Sopenharmony_ci util_queue_fence_signal(&shader->ready); 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci return; 1737bf215546Sopenharmony_ci } 1738bf215546Sopenharmony_ci 1739bf215546Sopenharmony_ci shader->compilation_failed = false; 1740bf215546Sopenharmony_ci 1741bf215546Sopenharmony_ci iris_debug_recompile(screen, dbg, ish, &brw_key.base); 1742bf215546Sopenharmony_ci 1743bf215546Sopenharmony_ci uint32_t *so_decls = 1744bf215546Sopenharmony_ci screen->vtbl.create_so_decl_list(&ish->stream_output, 1745bf215546Sopenharmony_ci &vue_prog_data->vue_map); 1746bf215546Sopenharmony_ci 1747bf215546Sopenharmony_ci iris_finalize_program(shader, prog_data, so_decls, system_values, 1748bf215546Sopenharmony_ci num_system_values, 0, num_cbufs, &bt); 1749bf215546Sopenharmony_ci 1750bf215546Sopenharmony_ci iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_TES, 1751bf215546Sopenharmony_ci sizeof(*key), key, program); 1752bf215546Sopenharmony_ci 1753bf215546Sopenharmony_ci iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key)); 1754bf215546Sopenharmony_ci 1755bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1756bf215546Sopenharmony_ci} 1757bf215546Sopenharmony_ci 1758bf215546Sopenharmony_ci/** 1759bf215546Sopenharmony_ci * Update the current tessellation evaluation shader variant. 1760bf215546Sopenharmony_ci * 1761bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed. 1762bf215546Sopenharmony_ci */ 1763bf215546Sopenharmony_cistatic void 1764bf215546Sopenharmony_ciiris_update_compiled_tes(struct iris_context *ice) 1765bf215546Sopenharmony_ci{ 1766bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 1767bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_driver; 1768bf215546Sopenharmony_ci struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_TESS_EVAL]; 1769bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 1770bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL]; 1771bf215546Sopenharmony_ci 1772bf215546Sopenharmony_ci struct iris_tes_prog_key key = { KEY_INIT(vue.base) }; 1773bf215546Sopenharmony_ci get_unified_tess_slots(ice, &key.inputs_read, &key.patch_inputs_read); 1774bf215546Sopenharmony_ci screen->vtbl.populate_tes_key(ice, &ish->nir->info, last_vue_stage(ice), &key); 1775bf215546Sopenharmony_ci 1776bf215546Sopenharmony_ci struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_TES]; 1777bf215546Sopenharmony_ci bool added; 1778bf215546Sopenharmony_ci struct iris_compiled_shader *shader = 1779bf215546Sopenharmony_ci find_or_add_variant(screen, ish, IRIS_CACHE_TES, &key, sizeof(key), &added); 1780bf215546Sopenharmony_ci 1781bf215546Sopenharmony_ci if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader, 1782bf215546Sopenharmony_ci &key, sizeof(key))) { 1783bf215546Sopenharmony_ci iris_compile_tes(screen, uploader, &ice->dbg, ish, shader); 1784bf215546Sopenharmony_ci } 1785bf215546Sopenharmony_ci 1786bf215546Sopenharmony_ci if (shader->compilation_failed) 1787bf215546Sopenharmony_ci shader = NULL; 1788bf215546Sopenharmony_ci 1789bf215546Sopenharmony_ci if (old != shader) { 1790bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_EVAL], 1791bf215546Sopenharmony_ci shader); 1792bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_TES | 1793bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_BINDINGS_TES | 1794bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_CONSTANTS_TES; 1795bf215546Sopenharmony_ci shs->sysvals_need_upload = true; 1796bf215546Sopenharmony_ci 1797bf215546Sopenharmony_ci unsigned urb_entry_size = shader ? 1798bf215546Sopenharmony_ci ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0; 1799bf215546Sopenharmony_ci check_urb_size(ice, urb_entry_size, MESA_SHADER_TESS_EVAL); 1800bf215546Sopenharmony_ci } 1801bf215546Sopenharmony_ci 1802bf215546Sopenharmony_ci /* TODO: Could compare and avoid flagging this. */ 1803bf215546Sopenharmony_ci const struct shader_info *tes_info = &ish->nir->info; 1804bf215546Sopenharmony_ci if (BITSET_TEST(tes_info->system_values_read, SYSTEM_VALUE_VERTICES_IN)) { 1805bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CONSTANTS_TES; 1806bf215546Sopenharmony_ci ice->state.shaders[MESA_SHADER_TESS_EVAL].sysvals_need_upload = true; 1807bf215546Sopenharmony_ci } 1808bf215546Sopenharmony_ci} 1809bf215546Sopenharmony_ci 1810bf215546Sopenharmony_ci/** 1811bf215546Sopenharmony_ci * Compile a geometry shader, and upload the assembly. 1812bf215546Sopenharmony_ci */ 1813bf215546Sopenharmony_cistatic void 1814bf215546Sopenharmony_ciiris_compile_gs(struct iris_screen *screen, 1815bf215546Sopenharmony_ci struct u_upload_mgr *uploader, 1816bf215546Sopenharmony_ci struct util_debug_callback *dbg, 1817bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 1818bf215546Sopenharmony_ci struct iris_compiled_shader *shader) 1819bf215546Sopenharmony_ci{ 1820bf215546Sopenharmony_ci const struct brw_compiler *compiler = screen->compiler; 1821bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 1822bf215546Sopenharmony_ci void *mem_ctx = ralloc_context(NULL); 1823bf215546Sopenharmony_ci struct brw_gs_prog_data *gs_prog_data = 1824bf215546Sopenharmony_ci rzalloc(mem_ctx, struct brw_gs_prog_data); 1825bf215546Sopenharmony_ci struct brw_vue_prog_data *vue_prog_data = &gs_prog_data->base; 1826bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data = &vue_prog_data->base; 1827bf215546Sopenharmony_ci enum brw_param_builtin *system_values; 1828bf215546Sopenharmony_ci unsigned num_system_values; 1829bf215546Sopenharmony_ci unsigned num_cbufs; 1830bf215546Sopenharmony_ci 1831bf215546Sopenharmony_ci nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir); 1832bf215546Sopenharmony_ci const struct iris_gs_prog_key *const key = &shader->key.gs; 1833bf215546Sopenharmony_ci 1834bf215546Sopenharmony_ci if (key->vue.nr_userclip_plane_consts) { 1835bf215546Sopenharmony_ci nir_function_impl *impl = nir_shader_get_entrypoint(nir); 1836bf215546Sopenharmony_ci nir_lower_clip_gs(nir, (1 << key->vue.nr_userclip_plane_consts) - 1, 1837bf215546Sopenharmony_ci false, NULL); 1838bf215546Sopenharmony_ci nir_lower_io_to_temporaries(nir, impl, true, false); 1839bf215546Sopenharmony_ci nir_lower_global_vars_to_local(nir); 1840bf215546Sopenharmony_ci nir_lower_vars_to_ssa(nir); 1841bf215546Sopenharmony_ci nir_shader_gather_info(nir, impl); 1842bf215546Sopenharmony_ci } 1843bf215546Sopenharmony_ci 1844bf215546Sopenharmony_ci iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values, 1845bf215546Sopenharmony_ci &num_system_values, &num_cbufs); 1846bf215546Sopenharmony_ci 1847bf215546Sopenharmony_ci struct iris_binding_table bt; 1848bf215546Sopenharmony_ci iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0, 1849bf215546Sopenharmony_ci num_system_values, num_cbufs); 1850bf215546Sopenharmony_ci 1851bf215546Sopenharmony_ci brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges); 1852bf215546Sopenharmony_ci 1853bf215546Sopenharmony_ci brw_compute_vue_map(devinfo, 1854bf215546Sopenharmony_ci &vue_prog_data->vue_map, nir->info.outputs_written, 1855bf215546Sopenharmony_ci nir->info.separate_shader, /* pos_slots */ 1); 1856bf215546Sopenharmony_ci 1857bf215546Sopenharmony_ci struct brw_gs_prog_key brw_key = iris_to_brw_gs_key(screen, key); 1858bf215546Sopenharmony_ci 1859bf215546Sopenharmony_ci struct brw_compile_gs_params params = { 1860bf215546Sopenharmony_ci .nir = nir, 1861bf215546Sopenharmony_ci .key = &brw_key, 1862bf215546Sopenharmony_ci .prog_data = gs_prog_data, 1863bf215546Sopenharmony_ci .log_data = dbg, 1864bf215546Sopenharmony_ci }; 1865bf215546Sopenharmony_ci 1866bf215546Sopenharmony_ci const unsigned *program = brw_compile_gs(compiler, mem_ctx, ¶ms); 1867bf215546Sopenharmony_ci if (program == NULL) { 1868bf215546Sopenharmony_ci dbg_printf("Failed to compile geometry shader: %s\n", params.error_str); 1869bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1870bf215546Sopenharmony_ci 1871bf215546Sopenharmony_ci shader->compilation_failed = true; 1872bf215546Sopenharmony_ci util_queue_fence_signal(&shader->ready); 1873bf215546Sopenharmony_ci 1874bf215546Sopenharmony_ci return; 1875bf215546Sopenharmony_ci } 1876bf215546Sopenharmony_ci 1877bf215546Sopenharmony_ci shader->compilation_failed = false; 1878bf215546Sopenharmony_ci 1879bf215546Sopenharmony_ci iris_debug_recompile(screen, dbg, ish, &brw_key.base); 1880bf215546Sopenharmony_ci 1881bf215546Sopenharmony_ci uint32_t *so_decls = 1882bf215546Sopenharmony_ci screen->vtbl.create_so_decl_list(&ish->stream_output, 1883bf215546Sopenharmony_ci &vue_prog_data->vue_map); 1884bf215546Sopenharmony_ci 1885bf215546Sopenharmony_ci iris_finalize_program(shader, prog_data, so_decls, system_values, 1886bf215546Sopenharmony_ci num_system_values, 0, num_cbufs, &bt); 1887bf215546Sopenharmony_ci 1888bf215546Sopenharmony_ci iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_GS, 1889bf215546Sopenharmony_ci sizeof(*key), key, program); 1890bf215546Sopenharmony_ci 1891bf215546Sopenharmony_ci iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key)); 1892bf215546Sopenharmony_ci 1893bf215546Sopenharmony_ci ralloc_free(mem_ctx); 1894bf215546Sopenharmony_ci} 1895bf215546Sopenharmony_ci 1896bf215546Sopenharmony_ci/** 1897bf215546Sopenharmony_ci * Update the current geometry shader variant. 1898bf215546Sopenharmony_ci * 1899bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed. 1900bf215546Sopenharmony_ci */ 1901bf215546Sopenharmony_cistatic void 1902bf215546Sopenharmony_ciiris_update_compiled_gs(struct iris_context *ice) 1903bf215546Sopenharmony_ci{ 1904bf215546Sopenharmony_ci struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_GEOMETRY]; 1905bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_driver; 1906bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 1907bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_GEOMETRY]; 1908bf215546Sopenharmony_ci struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_GS]; 1909bf215546Sopenharmony_ci struct iris_compiled_shader *shader = NULL; 1910bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 1911bf215546Sopenharmony_ci 1912bf215546Sopenharmony_ci if (ish) { 1913bf215546Sopenharmony_ci struct iris_gs_prog_key key = { KEY_INIT(vue.base) }; 1914bf215546Sopenharmony_ci screen->vtbl.populate_gs_key(ice, &ish->nir->info, last_vue_stage(ice), &key); 1915bf215546Sopenharmony_ci 1916bf215546Sopenharmony_ci bool added; 1917bf215546Sopenharmony_ci 1918bf215546Sopenharmony_ci shader = find_or_add_variant(screen, ish, IRIS_CACHE_GS, &key, 1919bf215546Sopenharmony_ci sizeof(key), &added); 1920bf215546Sopenharmony_ci 1921bf215546Sopenharmony_ci if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader, 1922bf215546Sopenharmony_ci &key, sizeof(key))) { 1923bf215546Sopenharmony_ci iris_compile_gs(screen, uploader, &ice->dbg, ish, shader); 1924bf215546Sopenharmony_ci } 1925bf215546Sopenharmony_ci 1926bf215546Sopenharmony_ci if (shader->compilation_failed) 1927bf215546Sopenharmony_ci shader = NULL; 1928bf215546Sopenharmony_ci } 1929bf215546Sopenharmony_ci 1930bf215546Sopenharmony_ci if (old != shader) { 1931bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_GEOMETRY], 1932bf215546Sopenharmony_ci shader); 1933bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_GS | 1934bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_BINDINGS_GS | 1935bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_CONSTANTS_GS; 1936bf215546Sopenharmony_ci shs->sysvals_need_upload = true; 1937bf215546Sopenharmony_ci 1938bf215546Sopenharmony_ci unsigned urb_entry_size = shader ? 1939bf215546Sopenharmony_ci ((struct brw_vue_prog_data *) shader->prog_data)->urb_entry_size : 0; 1940bf215546Sopenharmony_ci check_urb_size(ice, urb_entry_size, MESA_SHADER_GEOMETRY); 1941bf215546Sopenharmony_ci } 1942bf215546Sopenharmony_ci} 1943bf215546Sopenharmony_ci 1944bf215546Sopenharmony_ci/** 1945bf215546Sopenharmony_ci * Compile a fragment (pixel) shader, and upload the assembly. 1946bf215546Sopenharmony_ci */ 1947bf215546Sopenharmony_cistatic void 1948bf215546Sopenharmony_ciiris_compile_fs(struct iris_screen *screen, 1949bf215546Sopenharmony_ci struct u_upload_mgr *uploader, 1950bf215546Sopenharmony_ci struct util_debug_callback *dbg, 1951bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 1952bf215546Sopenharmony_ci struct iris_compiled_shader *shader, 1953bf215546Sopenharmony_ci struct brw_vue_map *vue_map) 1954bf215546Sopenharmony_ci{ 1955bf215546Sopenharmony_ci const struct brw_compiler *compiler = screen->compiler; 1956bf215546Sopenharmony_ci void *mem_ctx = ralloc_context(NULL); 1957bf215546Sopenharmony_ci struct brw_wm_prog_data *fs_prog_data = 1958bf215546Sopenharmony_ci rzalloc(mem_ctx, struct brw_wm_prog_data); 1959bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data = &fs_prog_data->base; 1960bf215546Sopenharmony_ci enum brw_param_builtin *system_values; 1961bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 1962bf215546Sopenharmony_ci unsigned num_system_values; 1963bf215546Sopenharmony_ci unsigned num_cbufs; 1964bf215546Sopenharmony_ci 1965bf215546Sopenharmony_ci nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir); 1966bf215546Sopenharmony_ci const struct iris_fs_prog_key *const key = &shader->key.fs; 1967bf215546Sopenharmony_ci 1968bf215546Sopenharmony_ci prog_data->use_alt_mode = nir->info.use_legacy_math_rules; 1969bf215546Sopenharmony_ci 1970bf215546Sopenharmony_ci iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 0, &system_values, 1971bf215546Sopenharmony_ci &num_system_values, &num_cbufs); 1972bf215546Sopenharmony_ci 1973bf215546Sopenharmony_ci /* Lower output variables to load_output intrinsics before setting up 1974bf215546Sopenharmony_ci * binding tables, so iris_setup_binding_table can map any load_output 1975bf215546Sopenharmony_ci * intrinsics to IRIS_SURFACE_GROUP_RENDER_TARGET_READ on Gfx8 for 1976bf215546Sopenharmony_ci * non-coherent framebuffer fetches. 1977bf215546Sopenharmony_ci */ 1978bf215546Sopenharmony_ci brw_nir_lower_fs_outputs(nir); 1979bf215546Sopenharmony_ci 1980bf215546Sopenharmony_ci /* On Gfx11+, shader RT write messages have a "Null Render Target" bit 1981bf215546Sopenharmony_ci * and do not need a binding table entry with a null surface. Earlier 1982bf215546Sopenharmony_ci * generations need an entry for a null surface. 1983bf215546Sopenharmony_ci */ 1984bf215546Sopenharmony_ci int null_rts = devinfo->ver < 11 ? 1 : 0; 1985bf215546Sopenharmony_ci 1986bf215546Sopenharmony_ci struct iris_binding_table bt; 1987bf215546Sopenharmony_ci iris_setup_binding_table(devinfo, nir, &bt, 1988bf215546Sopenharmony_ci MAX2(key->nr_color_regions, null_rts), 1989bf215546Sopenharmony_ci num_system_values, num_cbufs); 1990bf215546Sopenharmony_ci 1991bf215546Sopenharmony_ci brw_nir_analyze_ubo_ranges(compiler, nir, NULL, prog_data->ubo_ranges); 1992bf215546Sopenharmony_ci 1993bf215546Sopenharmony_ci struct brw_wm_prog_key brw_key = iris_to_brw_fs_key(screen, key); 1994bf215546Sopenharmony_ci 1995bf215546Sopenharmony_ci struct brw_compile_fs_params params = { 1996bf215546Sopenharmony_ci .nir = nir, 1997bf215546Sopenharmony_ci .key = &brw_key, 1998bf215546Sopenharmony_ci .prog_data = fs_prog_data, 1999bf215546Sopenharmony_ci 2000bf215546Sopenharmony_ci .allow_spilling = true, 2001bf215546Sopenharmony_ci .vue_map = vue_map, 2002bf215546Sopenharmony_ci 2003bf215546Sopenharmony_ci .log_data = dbg, 2004bf215546Sopenharmony_ci }; 2005bf215546Sopenharmony_ci 2006bf215546Sopenharmony_ci const unsigned *program = brw_compile_fs(compiler, mem_ctx, ¶ms); 2007bf215546Sopenharmony_ci if (program == NULL) { 2008bf215546Sopenharmony_ci dbg_printf("Failed to compile fragment shader: %s\n", params.error_str); 2009bf215546Sopenharmony_ci ralloc_free(mem_ctx); 2010bf215546Sopenharmony_ci 2011bf215546Sopenharmony_ci shader->compilation_failed = true; 2012bf215546Sopenharmony_ci util_queue_fence_signal(&shader->ready); 2013bf215546Sopenharmony_ci 2014bf215546Sopenharmony_ci return; 2015bf215546Sopenharmony_ci } 2016bf215546Sopenharmony_ci 2017bf215546Sopenharmony_ci shader->compilation_failed = false; 2018bf215546Sopenharmony_ci 2019bf215546Sopenharmony_ci iris_debug_recompile(screen, dbg, ish, &brw_key.base); 2020bf215546Sopenharmony_ci 2021bf215546Sopenharmony_ci iris_finalize_program(shader, prog_data, NULL, system_values, 2022bf215546Sopenharmony_ci num_system_values, 0, num_cbufs, &bt); 2023bf215546Sopenharmony_ci 2024bf215546Sopenharmony_ci iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_FS, 2025bf215546Sopenharmony_ci sizeof(*key), key, program); 2026bf215546Sopenharmony_ci 2027bf215546Sopenharmony_ci iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key)); 2028bf215546Sopenharmony_ci 2029bf215546Sopenharmony_ci ralloc_free(mem_ctx); 2030bf215546Sopenharmony_ci} 2031bf215546Sopenharmony_ci 2032bf215546Sopenharmony_ci/** 2033bf215546Sopenharmony_ci * Update the current fragment shader variant. 2034bf215546Sopenharmony_ci * 2035bf215546Sopenharmony_ci * Fill out the key, look in the cache, compile and bind if needed. 2036bf215546Sopenharmony_ci */ 2037bf215546Sopenharmony_cistatic void 2038bf215546Sopenharmony_ciiris_update_compiled_fs(struct iris_context *ice) 2039bf215546Sopenharmony_ci{ 2040bf215546Sopenharmony_ci struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_FRAGMENT]; 2041bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_driver; 2042bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 2043bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_FRAGMENT]; 2044bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 2045bf215546Sopenharmony_ci struct iris_fs_prog_key key = { KEY_INIT(base) }; 2046bf215546Sopenharmony_ci screen->vtbl.populate_fs_key(ice, &ish->nir->info, &key); 2047bf215546Sopenharmony_ci 2048bf215546Sopenharmony_ci struct brw_vue_map *last_vue_map = 2049bf215546Sopenharmony_ci &brw_vue_prog_data(ice->shaders.last_vue_shader->prog_data)->vue_map; 2050bf215546Sopenharmony_ci 2051bf215546Sopenharmony_ci if (ish->nos & (1ull << IRIS_NOS_LAST_VUE_MAP)) 2052bf215546Sopenharmony_ci key.input_slots_valid = last_vue_map->slots_valid; 2053bf215546Sopenharmony_ci 2054bf215546Sopenharmony_ci struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_FS]; 2055bf215546Sopenharmony_ci bool added; 2056bf215546Sopenharmony_ci struct iris_compiled_shader *shader = 2057bf215546Sopenharmony_ci find_or_add_variant(screen, ish, IRIS_CACHE_FS, &key, 2058bf215546Sopenharmony_ci sizeof(key), &added); 2059bf215546Sopenharmony_ci 2060bf215546Sopenharmony_ci if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader, 2061bf215546Sopenharmony_ci &key, sizeof(key))) { 2062bf215546Sopenharmony_ci iris_compile_fs(screen, uploader, &ice->dbg, ish, shader, last_vue_map); 2063bf215546Sopenharmony_ci } 2064bf215546Sopenharmony_ci 2065bf215546Sopenharmony_ci if (shader->compilation_failed) 2066bf215546Sopenharmony_ci shader = NULL; 2067bf215546Sopenharmony_ci 2068bf215546Sopenharmony_ci if (old != shader) { 2069bf215546Sopenharmony_ci // XXX: only need to flag CLIP if barycentric has NONPERSPECTIVE 2070bf215546Sopenharmony_ci // toggles. might be able to avoid flagging SBE too. 2071bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_FRAGMENT], 2072bf215546Sopenharmony_ci shader); 2073bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_WM | 2074bf215546Sopenharmony_ci IRIS_DIRTY_CLIP | 2075bf215546Sopenharmony_ci IRIS_DIRTY_SBE; 2076bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_FS | 2077bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_BINDINGS_FS | 2078bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_CONSTANTS_FS; 2079bf215546Sopenharmony_ci shs->sysvals_need_upload = true; 2080bf215546Sopenharmony_ci } 2081bf215546Sopenharmony_ci} 2082bf215546Sopenharmony_ci 2083bf215546Sopenharmony_ci/** 2084bf215546Sopenharmony_ci * Update the last enabled stage's VUE map. 2085bf215546Sopenharmony_ci * 2086bf215546Sopenharmony_ci * When the shader feeding the rasterizer's output interface changes, we 2087bf215546Sopenharmony_ci * need to re-emit various packets. 2088bf215546Sopenharmony_ci */ 2089bf215546Sopenharmony_cistatic void 2090bf215546Sopenharmony_ciupdate_last_vue_map(struct iris_context *ice, 2091bf215546Sopenharmony_ci struct iris_compiled_shader *shader) 2092bf215546Sopenharmony_ci{ 2093bf215546Sopenharmony_ci struct brw_vue_prog_data *vue_prog_data = (void *) shader->prog_data; 2094bf215546Sopenharmony_ci struct brw_vue_map *vue_map = &vue_prog_data->vue_map; 2095bf215546Sopenharmony_ci struct brw_vue_map *old_map = !ice->shaders.last_vue_shader ? NULL : 2096bf215546Sopenharmony_ci &brw_vue_prog_data(ice->shaders.last_vue_shader->prog_data)->vue_map; 2097bf215546Sopenharmony_ci const uint64_t changed_slots = 2098bf215546Sopenharmony_ci (old_map ? old_map->slots_valid : 0ull) ^ vue_map->slots_valid; 2099bf215546Sopenharmony_ci 2100bf215546Sopenharmony_ci if (changed_slots & VARYING_BIT_VIEWPORT) { 2101bf215546Sopenharmony_ci ice->state.num_viewports = 2102bf215546Sopenharmony_ci (vue_map->slots_valid & VARYING_BIT_VIEWPORT) ? IRIS_MAX_VIEWPORTS : 1; 2103bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_CLIP | 2104bf215546Sopenharmony_ci IRIS_DIRTY_SF_CL_VIEWPORT | 2105bf215546Sopenharmony_ci IRIS_DIRTY_CC_VIEWPORT | 2106bf215546Sopenharmony_ci IRIS_DIRTY_SCISSOR_RECT; 2107bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_FS | 2108bf215546Sopenharmony_ci ice->state.stage_dirty_for_nos[IRIS_NOS_LAST_VUE_MAP]; 2109bf215546Sopenharmony_ci } 2110bf215546Sopenharmony_ci 2111bf215546Sopenharmony_ci if (changed_slots || (old_map && old_map->separate != vue_map->separate)) { 2112bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_SBE; 2113bf215546Sopenharmony_ci } 2114bf215546Sopenharmony_ci 2115bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.last_vue_shader, shader); 2116bf215546Sopenharmony_ci} 2117bf215546Sopenharmony_ci 2118bf215546Sopenharmony_cistatic void 2119bf215546Sopenharmony_ciiris_update_pull_constant_descriptors(struct iris_context *ice, 2120bf215546Sopenharmony_ci gl_shader_stage stage) 2121bf215546Sopenharmony_ci{ 2122bf215546Sopenharmony_ci struct iris_compiled_shader *shader = ice->shaders.prog[stage]; 2123bf215546Sopenharmony_ci 2124bf215546Sopenharmony_ci if (!shader || !shader->prog_data->has_ubo_pull) 2125bf215546Sopenharmony_ci return; 2126bf215546Sopenharmony_ci 2127bf215546Sopenharmony_ci struct iris_shader_state *shs = &ice->state.shaders[stage]; 2128bf215546Sopenharmony_ci bool any_new_descriptors = 2129bf215546Sopenharmony_ci shader->num_system_values > 0 && shs->sysvals_need_upload; 2130bf215546Sopenharmony_ci 2131bf215546Sopenharmony_ci unsigned bound_cbufs = shs->bound_cbufs; 2132bf215546Sopenharmony_ci 2133bf215546Sopenharmony_ci while (bound_cbufs) { 2134bf215546Sopenharmony_ci const int i = u_bit_scan(&bound_cbufs); 2135bf215546Sopenharmony_ci struct pipe_shader_buffer *cbuf = &shs->constbuf[i]; 2136bf215546Sopenharmony_ci struct iris_state_ref *surf_state = &shs->constbuf_surf_state[i]; 2137bf215546Sopenharmony_ci if (!surf_state->res && cbuf->buffer) { 2138bf215546Sopenharmony_ci iris_upload_ubo_ssbo_surf_state(ice, cbuf, surf_state, 2139bf215546Sopenharmony_ci ISL_SURF_USAGE_CONSTANT_BUFFER_BIT); 2140bf215546Sopenharmony_ci any_new_descriptors = true; 2141bf215546Sopenharmony_ci } 2142bf215546Sopenharmony_ci } 2143bf215546Sopenharmony_ci 2144bf215546Sopenharmony_ci if (any_new_descriptors) 2145bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_BINDINGS_VS << stage; 2146bf215546Sopenharmony_ci} 2147bf215546Sopenharmony_ci 2148bf215546Sopenharmony_ci/** 2149bf215546Sopenharmony_ci * Update the current shader variants for the given state. 2150bf215546Sopenharmony_ci * 2151bf215546Sopenharmony_ci * This should be called on every draw call to ensure that the correct 2152bf215546Sopenharmony_ci * shaders are bound. It will also flag any dirty state triggered by 2153bf215546Sopenharmony_ci * swapping out those shaders. 2154bf215546Sopenharmony_ci */ 2155bf215546Sopenharmony_civoid 2156bf215546Sopenharmony_ciiris_update_compiled_shaders(struct iris_context *ice) 2157bf215546Sopenharmony_ci{ 2158bf215546Sopenharmony_ci const uint64_t stage_dirty = ice->state.stage_dirty; 2159bf215546Sopenharmony_ci 2160bf215546Sopenharmony_ci if (stage_dirty & (IRIS_STAGE_DIRTY_UNCOMPILED_TCS | 2161bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_UNCOMPILED_TES)) { 2162bf215546Sopenharmony_ci struct iris_uncompiled_shader *tes = 2163bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL]; 2164bf215546Sopenharmony_ci if (tes) { 2165bf215546Sopenharmony_ci iris_update_compiled_tcs(ice); 2166bf215546Sopenharmony_ci iris_update_compiled_tes(ice); 2167bf215546Sopenharmony_ci } else { 2168bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_CTRL], NULL); 2169bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_EVAL], NULL); 2170bf215546Sopenharmony_ci ice->state.stage_dirty |= 2171bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_TCS | IRIS_STAGE_DIRTY_TES | 2172bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_BINDINGS_TCS | IRIS_STAGE_DIRTY_BINDINGS_TES | 2173bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_CONSTANTS_TCS | IRIS_STAGE_DIRTY_CONSTANTS_TES; 2174bf215546Sopenharmony_ci 2175bf215546Sopenharmony_ci if (ice->shaders.urb.constrained) 2176bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_URB; 2177bf215546Sopenharmony_ci } 2178bf215546Sopenharmony_ci } 2179bf215546Sopenharmony_ci 2180bf215546Sopenharmony_ci if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_VS) 2181bf215546Sopenharmony_ci iris_update_compiled_vs(ice); 2182bf215546Sopenharmony_ci if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_GS) 2183bf215546Sopenharmony_ci iris_update_compiled_gs(ice); 2184bf215546Sopenharmony_ci 2185bf215546Sopenharmony_ci if (stage_dirty & (IRIS_STAGE_DIRTY_UNCOMPILED_GS | 2186bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_UNCOMPILED_TES)) { 2187bf215546Sopenharmony_ci const struct iris_compiled_shader *gs = 2188bf215546Sopenharmony_ci ice->shaders.prog[MESA_SHADER_GEOMETRY]; 2189bf215546Sopenharmony_ci const struct iris_compiled_shader *tes = 2190bf215546Sopenharmony_ci ice->shaders.prog[MESA_SHADER_TESS_EVAL]; 2191bf215546Sopenharmony_ci 2192bf215546Sopenharmony_ci bool points_or_lines = false; 2193bf215546Sopenharmony_ci 2194bf215546Sopenharmony_ci if (gs) { 2195bf215546Sopenharmony_ci const struct brw_gs_prog_data *gs_prog_data = (void *) gs->prog_data; 2196bf215546Sopenharmony_ci points_or_lines = 2197bf215546Sopenharmony_ci gs_prog_data->output_topology == _3DPRIM_POINTLIST || 2198bf215546Sopenharmony_ci gs_prog_data->output_topology == _3DPRIM_LINESTRIP; 2199bf215546Sopenharmony_ci } else if (tes) { 2200bf215546Sopenharmony_ci const struct brw_tes_prog_data *tes_data = (void *) tes->prog_data; 2201bf215546Sopenharmony_ci points_or_lines = 2202bf215546Sopenharmony_ci tes_data->output_topology == BRW_TESS_OUTPUT_TOPOLOGY_LINE || 2203bf215546Sopenharmony_ci tes_data->output_topology == BRW_TESS_OUTPUT_TOPOLOGY_POINT; 2204bf215546Sopenharmony_ci } 2205bf215546Sopenharmony_ci 2206bf215546Sopenharmony_ci if (ice->shaders.output_topology_is_points_or_lines != points_or_lines) { 2207bf215546Sopenharmony_ci /* Outbound to XY Clip enables */ 2208bf215546Sopenharmony_ci ice->shaders.output_topology_is_points_or_lines = points_or_lines; 2209bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_CLIP; 2210bf215546Sopenharmony_ci } 2211bf215546Sopenharmony_ci } 2212bf215546Sopenharmony_ci 2213bf215546Sopenharmony_ci gl_shader_stage last_stage = last_vue_stage(ice); 2214bf215546Sopenharmony_ci struct iris_compiled_shader *shader = ice->shaders.prog[last_stage]; 2215bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[last_stage]; 2216bf215546Sopenharmony_ci update_last_vue_map(ice, shader); 2217bf215546Sopenharmony_ci if (ice->state.streamout != shader->streamout) { 2218bf215546Sopenharmony_ci ice->state.streamout = shader->streamout; 2219bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_SO_DECL_LIST | IRIS_DIRTY_STREAMOUT; 2220bf215546Sopenharmony_ci } 2221bf215546Sopenharmony_ci 2222bf215546Sopenharmony_ci if (ice->state.streamout_active) { 2223bf215546Sopenharmony_ci for (int i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { 2224bf215546Sopenharmony_ci struct iris_stream_output_target *so = 2225bf215546Sopenharmony_ci (void *) ice->state.so_target[i]; 2226bf215546Sopenharmony_ci if (so) 2227bf215546Sopenharmony_ci so->stride = ish->stream_output.stride[i] * sizeof(uint32_t); 2228bf215546Sopenharmony_ci } 2229bf215546Sopenharmony_ci } 2230bf215546Sopenharmony_ci 2231bf215546Sopenharmony_ci if (stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_FS) 2232bf215546Sopenharmony_ci iris_update_compiled_fs(ice); 2233bf215546Sopenharmony_ci 2234bf215546Sopenharmony_ci for (int i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) { 2235bf215546Sopenharmony_ci if (ice->state.stage_dirty & (IRIS_STAGE_DIRTY_CONSTANTS_VS << i)) 2236bf215546Sopenharmony_ci iris_update_pull_constant_descriptors(ice, i); 2237bf215546Sopenharmony_ci } 2238bf215546Sopenharmony_ci} 2239bf215546Sopenharmony_ci 2240bf215546Sopenharmony_cistatic void 2241bf215546Sopenharmony_ciiris_compile_cs(struct iris_screen *screen, 2242bf215546Sopenharmony_ci struct u_upload_mgr *uploader, 2243bf215546Sopenharmony_ci struct util_debug_callback *dbg, 2244bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 2245bf215546Sopenharmony_ci struct iris_compiled_shader *shader) 2246bf215546Sopenharmony_ci{ 2247bf215546Sopenharmony_ci const struct brw_compiler *compiler = screen->compiler; 2248bf215546Sopenharmony_ci void *mem_ctx = ralloc_context(NULL); 2249bf215546Sopenharmony_ci struct brw_cs_prog_data *cs_prog_data = 2250bf215546Sopenharmony_ci rzalloc(mem_ctx, struct brw_cs_prog_data); 2251bf215546Sopenharmony_ci struct brw_stage_prog_data *prog_data = &cs_prog_data->base; 2252bf215546Sopenharmony_ci enum brw_param_builtin *system_values; 2253bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 2254bf215546Sopenharmony_ci unsigned num_system_values; 2255bf215546Sopenharmony_ci unsigned num_cbufs; 2256bf215546Sopenharmony_ci 2257bf215546Sopenharmony_ci nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir); 2258bf215546Sopenharmony_ci const struct iris_cs_prog_key *const key = &shader->key.cs; 2259bf215546Sopenharmony_ci 2260bf215546Sopenharmony_ci NIR_PASS_V(nir, brw_nir_lower_cs_intrinsics); 2261bf215546Sopenharmony_ci 2262bf215546Sopenharmony_ci iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, 2263bf215546Sopenharmony_ci ish->kernel_input_size, 2264bf215546Sopenharmony_ci &system_values, &num_system_values, &num_cbufs); 2265bf215546Sopenharmony_ci 2266bf215546Sopenharmony_ci struct iris_binding_table bt; 2267bf215546Sopenharmony_ci iris_setup_binding_table(devinfo, nir, &bt, /* num_render_targets */ 0, 2268bf215546Sopenharmony_ci num_system_values, num_cbufs); 2269bf215546Sopenharmony_ci 2270bf215546Sopenharmony_ci struct brw_cs_prog_key brw_key = iris_to_brw_cs_key(screen, key); 2271bf215546Sopenharmony_ci 2272bf215546Sopenharmony_ci struct brw_compile_cs_params params = { 2273bf215546Sopenharmony_ci .nir = nir, 2274bf215546Sopenharmony_ci .key = &brw_key, 2275bf215546Sopenharmony_ci .prog_data = cs_prog_data, 2276bf215546Sopenharmony_ci .log_data = dbg, 2277bf215546Sopenharmony_ci }; 2278bf215546Sopenharmony_ci 2279bf215546Sopenharmony_ci const unsigned *program = brw_compile_cs(compiler, mem_ctx, ¶ms); 2280bf215546Sopenharmony_ci if (program == NULL) { 2281bf215546Sopenharmony_ci dbg_printf("Failed to compile compute shader: %s\n", params.error_str); 2282bf215546Sopenharmony_ci 2283bf215546Sopenharmony_ci shader->compilation_failed = true; 2284bf215546Sopenharmony_ci util_queue_fence_signal(&shader->ready); 2285bf215546Sopenharmony_ci 2286bf215546Sopenharmony_ci return; 2287bf215546Sopenharmony_ci } 2288bf215546Sopenharmony_ci 2289bf215546Sopenharmony_ci shader->compilation_failed = false; 2290bf215546Sopenharmony_ci 2291bf215546Sopenharmony_ci iris_debug_recompile(screen, dbg, ish, &brw_key.base); 2292bf215546Sopenharmony_ci 2293bf215546Sopenharmony_ci iris_finalize_program(shader, prog_data, NULL, system_values, 2294bf215546Sopenharmony_ci num_system_values, ish->kernel_input_size, num_cbufs, 2295bf215546Sopenharmony_ci &bt); 2296bf215546Sopenharmony_ci 2297bf215546Sopenharmony_ci iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_CS, 2298bf215546Sopenharmony_ci sizeof(*key), key, program); 2299bf215546Sopenharmony_ci 2300bf215546Sopenharmony_ci iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key)); 2301bf215546Sopenharmony_ci 2302bf215546Sopenharmony_ci ralloc_free(mem_ctx); 2303bf215546Sopenharmony_ci} 2304bf215546Sopenharmony_ci 2305bf215546Sopenharmony_cistatic void 2306bf215546Sopenharmony_ciiris_update_compiled_cs(struct iris_context *ice) 2307bf215546Sopenharmony_ci{ 2308bf215546Sopenharmony_ci struct iris_shader_state *shs = &ice->state.shaders[MESA_SHADER_COMPUTE]; 2309bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_driver; 2310bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 2311bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_COMPUTE]; 2312bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 2313bf215546Sopenharmony_ci struct iris_cs_prog_key key = { KEY_INIT(base) }; 2314bf215546Sopenharmony_ci screen->vtbl.populate_cs_key(ice, &key); 2315bf215546Sopenharmony_ci 2316bf215546Sopenharmony_ci struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_CS]; 2317bf215546Sopenharmony_ci bool added; 2318bf215546Sopenharmony_ci struct iris_compiled_shader *shader = 2319bf215546Sopenharmony_ci find_or_add_variant(screen, ish, IRIS_CACHE_CS, &key, 2320bf215546Sopenharmony_ci sizeof(key), &added); 2321bf215546Sopenharmony_ci 2322bf215546Sopenharmony_ci if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader, 2323bf215546Sopenharmony_ci &key, sizeof(key))) { 2324bf215546Sopenharmony_ci iris_compile_cs(screen, uploader, &ice->dbg, ish, shader); 2325bf215546Sopenharmony_ci } 2326bf215546Sopenharmony_ci 2327bf215546Sopenharmony_ci if (shader->compilation_failed) 2328bf215546Sopenharmony_ci shader = NULL; 2329bf215546Sopenharmony_ci 2330bf215546Sopenharmony_ci if (old != shader) { 2331bf215546Sopenharmony_ci iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_COMPUTE], 2332bf215546Sopenharmony_ci shader); 2333bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_CS | 2334bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_BINDINGS_CS | 2335bf215546Sopenharmony_ci IRIS_STAGE_DIRTY_CONSTANTS_CS; 2336bf215546Sopenharmony_ci shs->sysvals_need_upload = true; 2337bf215546Sopenharmony_ci } 2338bf215546Sopenharmony_ci} 2339bf215546Sopenharmony_ci 2340bf215546Sopenharmony_civoid 2341bf215546Sopenharmony_ciiris_update_compiled_compute_shader(struct iris_context *ice) 2342bf215546Sopenharmony_ci{ 2343bf215546Sopenharmony_ci if (ice->state.stage_dirty & IRIS_STAGE_DIRTY_UNCOMPILED_CS) 2344bf215546Sopenharmony_ci iris_update_compiled_cs(ice); 2345bf215546Sopenharmony_ci 2346bf215546Sopenharmony_ci if (ice->state.stage_dirty & IRIS_STAGE_DIRTY_CONSTANTS_CS) 2347bf215546Sopenharmony_ci iris_update_pull_constant_descriptors(ice, MESA_SHADER_COMPUTE); 2348bf215546Sopenharmony_ci} 2349bf215546Sopenharmony_ci 2350bf215546Sopenharmony_civoid 2351bf215546Sopenharmony_ciiris_fill_cs_push_const_buffer(struct brw_cs_prog_data *cs_prog_data, 2352bf215546Sopenharmony_ci unsigned threads, 2353bf215546Sopenharmony_ci uint32_t *dst) 2354bf215546Sopenharmony_ci{ 2355bf215546Sopenharmony_ci assert(brw_cs_push_const_total_size(cs_prog_data, threads) > 0); 2356bf215546Sopenharmony_ci assert(cs_prog_data->push.cross_thread.size == 0); 2357bf215546Sopenharmony_ci assert(cs_prog_data->push.per_thread.dwords == 1); 2358bf215546Sopenharmony_ci assert(cs_prog_data->base.param[0] == BRW_PARAM_BUILTIN_SUBGROUP_ID); 2359bf215546Sopenharmony_ci for (unsigned t = 0; t < threads; t++) 2360bf215546Sopenharmony_ci dst[8 * t] = t; 2361bf215546Sopenharmony_ci} 2362bf215546Sopenharmony_ci 2363bf215546Sopenharmony_ci/** 2364bf215546Sopenharmony_ci * Allocate scratch BOs as needed for the given per-thread size and stage. 2365bf215546Sopenharmony_ci */ 2366bf215546Sopenharmony_cistruct iris_bo * 2367bf215546Sopenharmony_ciiris_get_scratch_space(struct iris_context *ice, 2368bf215546Sopenharmony_ci unsigned per_thread_scratch, 2369bf215546Sopenharmony_ci gl_shader_stage stage) 2370bf215546Sopenharmony_ci{ 2371bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 2372bf215546Sopenharmony_ci struct iris_bufmgr *bufmgr = screen->bufmgr; 2373bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 2374bf215546Sopenharmony_ci 2375bf215546Sopenharmony_ci unsigned encoded_size = ffs(per_thread_scratch) - 11; 2376bf215546Sopenharmony_ci assert(encoded_size < ARRAY_SIZE(ice->shaders.scratch_bos)); 2377bf215546Sopenharmony_ci assert(per_thread_scratch == 1 << (encoded_size + 10)); 2378bf215546Sopenharmony_ci 2379bf215546Sopenharmony_ci /* On GFX version 12.5, scratch access changed to a surface-based model. 2380bf215546Sopenharmony_ci * Instead of each shader type having its own layout based on IDs passed 2381bf215546Sopenharmony_ci * from the relevant fixed-function unit, all scratch access is based on 2382bf215546Sopenharmony_ci * thread IDs like it always has been for compute. 2383bf215546Sopenharmony_ci */ 2384bf215546Sopenharmony_ci if (devinfo->verx10 >= 125) 2385bf215546Sopenharmony_ci stage = MESA_SHADER_COMPUTE; 2386bf215546Sopenharmony_ci 2387bf215546Sopenharmony_ci struct iris_bo **bop = &ice->shaders.scratch_bos[encoded_size][stage]; 2388bf215546Sopenharmony_ci 2389bf215546Sopenharmony_ci if (!*bop) { 2390bf215546Sopenharmony_ci assert(stage < ARRAY_SIZE(devinfo->max_scratch_ids)); 2391bf215546Sopenharmony_ci uint32_t size = per_thread_scratch * devinfo->max_scratch_ids[stage]; 2392bf215546Sopenharmony_ci *bop = iris_bo_alloc(bufmgr, "scratch", size, 1024, 2393bf215546Sopenharmony_ci IRIS_MEMZONE_SHADER, 0); 2394bf215546Sopenharmony_ci } 2395bf215546Sopenharmony_ci 2396bf215546Sopenharmony_ci return *bop; 2397bf215546Sopenharmony_ci} 2398bf215546Sopenharmony_ci 2399bf215546Sopenharmony_ciconst struct iris_state_ref * 2400bf215546Sopenharmony_ciiris_get_scratch_surf(struct iris_context *ice, 2401bf215546Sopenharmony_ci unsigned per_thread_scratch) 2402bf215546Sopenharmony_ci{ 2403bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; 2404bf215546Sopenharmony_ci ASSERTED const struct intel_device_info *devinfo = &screen->devinfo; 2405bf215546Sopenharmony_ci 2406bf215546Sopenharmony_ci assert(devinfo->verx10 >= 125); 2407bf215546Sopenharmony_ci 2408bf215546Sopenharmony_ci unsigned encoded_size = ffs(per_thread_scratch) - 11; 2409bf215546Sopenharmony_ci assert(encoded_size < ARRAY_SIZE(ice->shaders.scratch_surfs)); 2410bf215546Sopenharmony_ci assert(per_thread_scratch == 1 << (encoded_size + 10)); 2411bf215546Sopenharmony_ci 2412bf215546Sopenharmony_ci struct iris_state_ref *ref = &ice->shaders.scratch_surfs[encoded_size]; 2413bf215546Sopenharmony_ci 2414bf215546Sopenharmony_ci if (ref->res) 2415bf215546Sopenharmony_ci return ref; 2416bf215546Sopenharmony_ci 2417bf215546Sopenharmony_ci struct iris_bo *scratch_bo = 2418bf215546Sopenharmony_ci iris_get_scratch_space(ice, per_thread_scratch, MESA_SHADER_COMPUTE); 2419bf215546Sopenharmony_ci 2420bf215546Sopenharmony_ci void *map = upload_state(ice->state.bindless_uploader, ref, 2421bf215546Sopenharmony_ci screen->isl_dev.ss.size, 64); 2422bf215546Sopenharmony_ci 2423bf215546Sopenharmony_ci isl_buffer_fill_state(&screen->isl_dev, map, 2424bf215546Sopenharmony_ci .address = scratch_bo->address, 2425bf215546Sopenharmony_ci .size_B = scratch_bo->size, 2426bf215546Sopenharmony_ci .format = ISL_FORMAT_RAW, 2427bf215546Sopenharmony_ci .swizzle = ISL_SWIZZLE_IDENTITY, 2428bf215546Sopenharmony_ci .mocs = iris_mocs(scratch_bo, &screen->isl_dev, 0), 2429bf215546Sopenharmony_ci .stride_B = per_thread_scratch, 2430bf215546Sopenharmony_ci .is_scratch = true); 2431bf215546Sopenharmony_ci 2432bf215546Sopenharmony_ci return ref; 2433bf215546Sopenharmony_ci} 2434bf215546Sopenharmony_ci 2435bf215546Sopenharmony_ci/* ------------------------------------------------------------------- */ 2436bf215546Sopenharmony_ci 2437bf215546Sopenharmony_ci/** 2438bf215546Sopenharmony_ci * The pipe->create_[stage]_state() driver hooks. 2439bf215546Sopenharmony_ci * 2440bf215546Sopenharmony_ci * Performs basic NIR preprocessing, records any state dependencies, and 2441bf215546Sopenharmony_ci * returns an iris_uncompiled_shader as the Gallium CSO. 2442bf215546Sopenharmony_ci * 2443bf215546Sopenharmony_ci * Actual shader compilation to assembly happens later, at first use. 2444bf215546Sopenharmony_ci */ 2445bf215546Sopenharmony_cistatic void * 2446bf215546Sopenharmony_ciiris_create_uncompiled_shader(struct iris_screen *screen, 2447bf215546Sopenharmony_ci nir_shader *nir, 2448bf215546Sopenharmony_ci const struct pipe_stream_output_info *so_info) 2449bf215546Sopenharmony_ci{ 2450bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 2451bf215546Sopenharmony_ci calloc(1, sizeof(struct iris_uncompiled_shader)); 2452bf215546Sopenharmony_ci if (!ish) 2453bf215546Sopenharmony_ci return NULL; 2454bf215546Sopenharmony_ci 2455bf215546Sopenharmony_ci pipe_reference_init(&ish->ref, 1); 2456bf215546Sopenharmony_ci list_inithead(&ish->variants); 2457bf215546Sopenharmony_ci simple_mtx_init(&ish->lock, mtx_plain); 2458bf215546Sopenharmony_ci util_queue_fence_init(&ish->ready); 2459bf215546Sopenharmony_ci 2460bf215546Sopenharmony_ci ish->uses_atomic_load_store = iris_uses_image_atomic(nir); 2461bf215546Sopenharmony_ci 2462bf215546Sopenharmony_ci ish->program_id = get_new_program_id(screen); 2463bf215546Sopenharmony_ci ish->nir = nir; 2464bf215546Sopenharmony_ci if (so_info) { 2465bf215546Sopenharmony_ci memcpy(&ish->stream_output, so_info, sizeof(*so_info)); 2466bf215546Sopenharmony_ci update_so_info(&ish->stream_output, nir->info.outputs_written); 2467bf215546Sopenharmony_ci } 2468bf215546Sopenharmony_ci 2469bf215546Sopenharmony_ci if (screen->disk_cache) { 2470bf215546Sopenharmony_ci /* Serialize the NIR to a binary blob that we can hash for the disk 2471bf215546Sopenharmony_ci * cache. Drop unnecessary information (like variable names) 2472bf215546Sopenharmony_ci * so the serialized NIR is smaller, and also to let us detect more 2473bf215546Sopenharmony_ci * isomorphic shaders when hashing, increasing cache hits. 2474bf215546Sopenharmony_ci */ 2475bf215546Sopenharmony_ci struct blob blob; 2476bf215546Sopenharmony_ci blob_init(&blob); 2477bf215546Sopenharmony_ci nir_serialize(&blob, nir, true); 2478bf215546Sopenharmony_ci _mesa_sha1_compute(blob.data, blob.size, ish->nir_sha1); 2479bf215546Sopenharmony_ci blob_finish(&blob); 2480bf215546Sopenharmony_ci } 2481bf215546Sopenharmony_ci 2482bf215546Sopenharmony_ci return ish; 2483bf215546Sopenharmony_ci} 2484bf215546Sopenharmony_ci 2485bf215546Sopenharmony_cistatic void * 2486bf215546Sopenharmony_ciiris_create_compute_state(struct pipe_context *ctx, 2487bf215546Sopenharmony_ci const struct pipe_compute_state *state) 2488bf215546Sopenharmony_ci{ 2489bf215546Sopenharmony_ci struct iris_context *ice = (void *) ctx; 2490bf215546Sopenharmony_ci struct iris_screen *screen = (void *) ctx->screen; 2491bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_unsync; 2492bf215546Sopenharmony_ci const nir_shader_compiler_options *options = 2493bf215546Sopenharmony_ci screen->compiler->nir_options[MESA_SHADER_COMPUTE]; 2494bf215546Sopenharmony_ci 2495bf215546Sopenharmony_ci nir_shader *nir; 2496bf215546Sopenharmony_ci switch (state->ir_type) { 2497bf215546Sopenharmony_ci case PIPE_SHADER_IR_NIR: 2498bf215546Sopenharmony_ci nir = (void *)state->prog; 2499bf215546Sopenharmony_ci break; 2500bf215546Sopenharmony_ci 2501bf215546Sopenharmony_ci case PIPE_SHADER_IR_NIR_SERIALIZED: { 2502bf215546Sopenharmony_ci struct blob_reader reader; 2503bf215546Sopenharmony_ci const struct pipe_binary_program_header *hdr = state->prog; 2504bf215546Sopenharmony_ci blob_reader_init(&reader, hdr->blob, hdr->num_bytes); 2505bf215546Sopenharmony_ci nir = nir_deserialize(NULL, options, &reader); 2506bf215546Sopenharmony_ci break; 2507bf215546Sopenharmony_ci } 2508bf215546Sopenharmony_ci 2509bf215546Sopenharmony_ci default: 2510bf215546Sopenharmony_ci unreachable("Unsupported IR"); 2511bf215546Sopenharmony_ci } 2512bf215546Sopenharmony_ci 2513bf215546Sopenharmony_ci /* Most of iris doesn't really care about the difference between compute 2514bf215546Sopenharmony_ci * shaders and kernels. We also tend to hard-code COMPUTE everywhere so 2515bf215546Sopenharmony_ci * it's way easier if we just normalize to COMPUTE here. 2516bf215546Sopenharmony_ci */ 2517bf215546Sopenharmony_ci assert(nir->info.stage == MESA_SHADER_COMPUTE || 2518bf215546Sopenharmony_ci nir->info.stage == MESA_SHADER_KERNEL); 2519bf215546Sopenharmony_ci nir->info.stage = MESA_SHADER_COMPUTE; 2520bf215546Sopenharmony_ci 2521bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 2522bf215546Sopenharmony_ci iris_create_uncompiled_shader(screen, nir, NULL); 2523bf215546Sopenharmony_ci ish->kernel_input_size = state->req_input_mem; 2524bf215546Sopenharmony_ci ish->kernel_shared_size = state->req_local_mem; 2525bf215546Sopenharmony_ci 2526bf215546Sopenharmony_ci // XXX: disallow more than 64KB of shared variables 2527bf215546Sopenharmony_ci 2528bf215546Sopenharmony_ci if (screen->precompile) { 2529bf215546Sopenharmony_ci struct iris_cs_prog_key key = { KEY_INIT(base) }; 2530bf215546Sopenharmony_ci 2531bf215546Sopenharmony_ci struct iris_compiled_shader *shader = 2532bf215546Sopenharmony_ci iris_create_shader_variant(screen, NULL, IRIS_CACHE_CS, 2533bf215546Sopenharmony_ci sizeof(key), &key); 2534bf215546Sopenharmony_ci 2535bf215546Sopenharmony_ci /* Append our new variant to the shader's variant list. */ 2536bf215546Sopenharmony_ci list_addtail(&shader->link, &ish->variants); 2537bf215546Sopenharmony_ci 2538bf215546Sopenharmony_ci if (!iris_disk_cache_retrieve(screen, uploader, ish, shader, 2539bf215546Sopenharmony_ci &key, sizeof(key))) { 2540bf215546Sopenharmony_ci iris_compile_cs(screen, uploader, &ice->dbg, ish, shader); 2541bf215546Sopenharmony_ci } 2542bf215546Sopenharmony_ci } 2543bf215546Sopenharmony_ci 2544bf215546Sopenharmony_ci return ish; 2545bf215546Sopenharmony_ci} 2546bf215546Sopenharmony_ci 2547bf215546Sopenharmony_cistatic void 2548bf215546Sopenharmony_ciiris_compile_shader(void *_job, UNUSED void *_gdata, UNUSED int thread_index) 2549bf215546Sopenharmony_ci{ 2550bf215546Sopenharmony_ci const struct iris_threaded_compile_job *job = 2551bf215546Sopenharmony_ci (struct iris_threaded_compile_job *) _job; 2552bf215546Sopenharmony_ci 2553bf215546Sopenharmony_ci struct iris_screen *screen = job->screen; 2554bf215546Sopenharmony_ci struct u_upload_mgr *uploader = job->uploader; 2555bf215546Sopenharmony_ci struct util_debug_callback *dbg = job->dbg; 2556bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = job->ish; 2557bf215546Sopenharmony_ci struct iris_compiled_shader *shader = job->shader; 2558bf215546Sopenharmony_ci 2559bf215546Sopenharmony_ci switch (ish->nir->info.stage) { 2560bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 2561bf215546Sopenharmony_ci iris_compile_vs(screen, uploader, dbg, ish, shader); 2562bf215546Sopenharmony_ci break; 2563bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 2564bf215546Sopenharmony_ci iris_compile_tcs(screen, NULL, uploader, dbg, ish, shader); 2565bf215546Sopenharmony_ci break; 2566bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 2567bf215546Sopenharmony_ci iris_compile_tes(screen, uploader, dbg, ish, shader); 2568bf215546Sopenharmony_ci break; 2569bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 2570bf215546Sopenharmony_ci iris_compile_gs(screen, uploader, dbg, ish, shader); 2571bf215546Sopenharmony_ci break; 2572bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 2573bf215546Sopenharmony_ci iris_compile_fs(screen, uploader, dbg, ish, shader, NULL); 2574bf215546Sopenharmony_ci break; 2575bf215546Sopenharmony_ci 2576bf215546Sopenharmony_ci default: 2577bf215546Sopenharmony_ci unreachable("Invalid shader stage."); 2578bf215546Sopenharmony_ci } 2579bf215546Sopenharmony_ci} 2580bf215546Sopenharmony_ci 2581bf215546Sopenharmony_cistatic void * 2582bf215546Sopenharmony_ciiris_create_shader_state(struct pipe_context *ctx, 2583bf215546Sopenharmony_ci const struct pipe_shader_state *state) 2584bf215546Sopenharmony_ci{ 2585bf215546Sopenharmony_ci struct iris_context *ice = (void *) ctx; 2586bf215546Sopenharmony_ci struct iris_screen *screen = (void *) ctx->screen; 2587bf215546Sopenharmony_ci struct nir_shader *nir; 2588bf215546Sopenharmony_ci 2589bf215546Sopenharmony_ci if (state->type == PIPE_SHADER_IR_TGSI) 2590bf215546Sopenharmony_ci nir = tgsi_to_nir(state->tokens, ctx->screen, false); 2591bf215546Sopenharmony_ci else 2592bf215546Sopenharmony_ci nir = state->ir.nir; 2593bf215546Sopenharmony_ci 2594bf215546Sopenharmony_ci const struct shader_info *const info = &nir->info; 2595bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = 2596bf215546Sopenharmony_ci iris_create_uncompiled_shader(screen, nir, &state->stream_output); 2597bf215546Sopenharmony_ci 2598bf215546Sopenharmony_ci union iris_any_prog_key key; 2599bf215546Sopenharmony_ci unsigned key_size = 0; 2600bf215546Sopenharmony_ci 2601bf215546Sopenharmony_ci memset(&key, 0, sizeof(key)); 2602bf215546Sopenharmony_ci 2603bf215546Sopenharmony_ci switch (info->stage) { 2604bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 2605bf215546Sopenharmony_ci /* User clip planes */ 2606bf215546Sopenharmony_ci if (info->clip_distance_array_size == 0) 2607bf215546Sopenharmony_ci ish->nos |= (1ull << IRIS_NOS_RASTERIZER); 2608bf215546Sopenharmony_ci 2609bf215546Sopenharmony_ci key.vs = (struct iris_vs_prog_key) { KEY_INIT(vue.base) }; 2610bf215546Sopenharmony_ci key_size = sizeof(key.vs); 2611bf215546Sopenharmony_ci break; 2612bf215546Sopenharmony_ci 2613bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: { 2614bf215546Sopenharmony_ci key.tcs = (struct iris_tcs_prog_key) { 2615bf215546Sopenharmony_ci KEY_INIT(vue.base), 2616bf215546Sopenharmony_ci // XXX: make sure the linker fills this out from the TES... 2617bf215546Sopenharmony_ci ._tes_primitive_mode = 2618bf215546Sopenharmony_ci info->tess._primitive_mode ? info->tess._primitive_mode 2619bf215546Sopenharmony_ci : TESS_PRIMITIVE_TRIANGLES, 2620bf215546Sopenharmony_ci .outputs_written = info->outputs_written, 2621bf215546Sopenharmony_ci .patch_outputs_written = info->patch_outputs_written, 2622bf215546Sopenharmony_ci }; 2623bf215546Sopenharmony_ci 2624bf215546Sopenharmony_ci /* 8_PATCH mode needs the key to contain the input patch dimensionality. 2625bf215546Sopenharmony_ci * We don't have that information, so we randomly guess that the input 2626bf215546Sopenharmony_ci * and output patches are the same size. This is a bad guess, but we 2627bf215546Sopenharmony_ci * can't do much better. 2628bf215546Sopenharmony_ci */ 2629bf215546Sopenharmony_ci if (screen->compiler->use_tcs_8_patch) 2630bf215546Sopenharmony_ci key.tcs.input_vertices = info->tess.tcs_vertices_out; 2631bf215546Sopenharmony_ci 2632bf215546Sopenharmony_ci key_size = sizeof(key.tcs); 2633bf215546Sopenharmony_ci break; 2634bf215546Sopenharmony_ci } 2635bf215546Sopenharmony_ci 2636bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 2637bf215546Sopenharmony_ci /* User clip planes */ 2638bf215546Sopenharmony_ci if (info->clip_distance_array_size == 0) 2639bf215546Sopenharmony_ci ish->nos |= (1ull << IRIS_NOS_RASTERIZER); 2640bf215546Sopenharmony_ci 2641bf215546Sopenharmony_ci key.tes = (struct iris_tes_prog_key) { 2642bf215546Sopenharmony_ci KEY_INIT(vue.base), 2643bf215546Sopenharmony_ci // XXX: not ideal, need TCS output/TES input unification 2644bf215546Sopenharmony_ci .inputs_read = info->inputs_read, 2645bf215546Sopenharmony_ci .patch_inputs_read = info->patch_inputs_read, 2646bf215546Sopenharmony_ci }; 2647bf215546Sopenharmony_ci 2648bf215546Sopenharmony_ci key_size = sizeof(key.tes); 2649bf215546Sopenharmony_ci break; 2650bf215546Sopenharmony_ci 2651bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 2652bf215546Sopenharmony_ci /* User clip planes */ 2653bf215546Sopenharmony_ci if (info->clip_distance_array_size == 0) 2654bf215546Sopenharmony_ci ish->nos |= (1ull << IRIS_NOS_RASTERIZER); 2655bf215546Sopenharmony_ci 2656bf215546Sopenharmony_ci key.gs = (struct iris_gs_prog_key) { KEY_INIT(vue.base) }; 2657bf215546Sopenharmony_ci key_size = sizeof(key.gs); 2658bf215546Sopenharmony_ci break; 2659bf215546Sopenharmony_ci 2660bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 2661bf215546Sopenharmony_ci ish->nos |= (1ull << IRIS_NOS_FRAMEBUFFER) | 2662bf215546Sopenharmony_ci (1ull << IRIS_NOS_DEPTH_STENCIL_ALPHA) | 2663bf215546Sopenharmony_ci (1ull << IRIS_NOS_RASTERIZER) | 2664bf215546Sopenharmony_ci (1ull << IRIS_NOS_BLEND); 2665bf215546Sopenharmony_ci 2666bf215546Sopenharmony_ci /* The program key needs the VUE map if there are > 16 inputs */ 2667bf215546Sopenharmony_ci if (util_bitcount64(info->inputs_read & BRW_FS_VARYING_INPUT_MASK) > 16) { 2668bf215546Sopenharmony_ci ish->nos |= (1ull << IRIS_NOS_LAST_VUE_MAP); 2669bf215546Sopenharmony_ci } 2670bf215546Sopenharmony_ci 2671bf215546Sopenharmony_ci const uint64_t color_outputs = info->outputs_written & 2672bf215546Sopenharmony_ci ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) | 2673bf215546Sopenharmony_ci BITFIELD64_BIT(FRAG_RESULT_STENCIL) | 2674bf215546Sopenharmony_ci BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)); 2675bf215546Sopenharmony_ci 2676bf215546Sopenharmony_ci bool can_rearrange_varyings = 2677bf215546Sopenharmony_ci util_bitcount64(info->inputs_read & BRW_FS_VARYING_INPUT_MASK) <= 16; 2678bf215546Sopenharmony_ci 2679bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 2680bf215546Sopenharmony_ci 2681bf215546Sopenharmony_ci key.fs = (struct iris_fs_prog_key) { 2682bf215546Sopenharmony_ci KEY_INIT(base), 2683bf215546Sopenharmony_ci .nr_color_regions = util_bitcount(color_outputs), 2684bf215546Sopenharmony_ci .coherent_fb_fetch = devinfo->ver >= 9, 2685bf215546Sopenharmony_ci .input_slots_valid = 2686bf215546Sopenharmony_ci can_rearrange_varyings ? 0 : info->inputs_read | VARYING_BIT_POS, 2687bf215546Sopenharmony_ci }; 2688bf215546Sopenharmony_ci 2689bf215546Sopenharmony_ci key_size = sizeof(key.fs); 2690bf215546Sopenharmony_ci break; 2691bf215546Sopenharmony_ci 2692bf215546Sopenharmony_ci default: 2693bf215546Sopenharmony_ci unreachable("Invalid shader stage."); 2694bf215546Sopenharmony_ci } 2695bf215546Sopenharmony_ci 2696bf215546Sopenharmony_ci if (screen->precompile) { 2697bf215546Sopenharmony_ci struct u_upload_mgr *uploader = ice->shaders.uploader_unsync; 2698bf215546Sopenharmony_ci 2699bf215546Sopenharmony_ci struct iris_compiled_shader *shader = 2700bf215546Sopenharmony_ci iris_create_shader_variant(screen, NULL, 2701bf215546Sopenharmony_ci (enum iris_program_cache_id) info->stage, 2702bf215546Sopenharmony_ci key_size, &key); 2703bf215546Sopenharmony_ci 2704bf215546Sopenharmony_ci /* Append our new variant to the shader's variant list. */ 2705bf215546Sopenharmony_ci list_addtail(&shader->link, &ish->variants); 2706bf215546Sopenharmony_ci 2707bf215546Sopenharmony_ci if (!iris_disk_cache_retrieve(screen, uploader, ish, shader, 2708bf215546Sopenharmony_ci &key, key_size)) { 2709bf215546Sopenharmony_ci assert(!util_queue_fence_is_signalled(&shader->ready)); 2710bf215546Sopenharmony_ci 2711bf215546Sopenharmony_ci struct iris_threaded_compile_job *job = calloc(1, sizeof(*job)); 2712bf215546Sopenharmony_ci 2713bf215546Sopenharmony_ci job->screen = screen; 2714bf215546Sopenharmony_ci job->uploader = uploader; 2715bf215546Sopenharmony_ci job->ish = ish; 2716bf215546Sopenharmony_ci job->shader = shader; 2717bf215546Sopenharmony_ci 2718bf215546Sopenharmony_ci iris_schedule_compile(screen, &ish->ready, &ice->dbg, job, 2719bf215546Sopenharmony_ci iris_compile_shader); 2720bf215546Sopenharmony_ci } 2721bf215546Sopenharmony_ci } 2722bf215546Sopenharmony_ci 2723bf215546Sopenharmony_ci return ish; 2724bf215546Sopenharmony_ci} 2725bf215546Sopenharmony_ci 2726bf215546Sopenharmony_ci/** 2727bf215546Sopenharmony_ci * Called when the refcount on the iris_uncompiled_shader reaches 0. 2728bf215546Sopenharmony_ci * 2729bf215546Sopenharmony_ci * Frees the iris_uncompiled_shader. 2730bf215546Sopenharmony_ci * 2731bf215546Sopenharmony_ci * \sa iris_delete_shader_state 2732bf215546Sopenharmony_ci */ 2733bf215546Sopenharmony_civoid 2734bf215546Sopenharmony_ciiris_destroy_shader_state(struct pipe_context *ctx, void *state) 2735bf215546Sopenharmony_ci{ 2736bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = state; 2737bf215546Sopenharmony_ci 2738bf215546Sopenharmony_ci /* No need to take ish->lock; we hold the last reference to ish */ 2739bf215546Sopenharmony_ci list_for_each_entry_safe(struct iris_compiled_shader, shader, 2740bf215546Sopenharmony_ci &ish->variants, link) { 2741bf215546Sopenharmony_ci list_del(&shader->link); 2742bf215546Sopenharmony_ci 2743bf215546Sopenharmony_ci iris_shader_variant_reference(&shader, NULL); 2744bf215546Sopenharmony_ci } 2745bf215546Sopenharmony_ci 2746bf215546Sopenharmony_ci simple_mtx_destroy(&ish->lock); 2747bf215546Sopenharmony_ci util_queue_fence_destroy(&ish->ready); 2748bf215546Sopenharmony_ci 2749bf215546Sopenharmony_ci ralloc_free(ish->nir); 2750bf215546Sopenharmony_ci free(ish); 2751bf215546Sopenharmony_ci} 2752bf215546Sopenharmony_ci 2753bf215546Sopenharmony_ci/** 2754bf215546Sopenharmony_ci * The pipe->delete_[stage]_state() driver hooks. 2755bf215546Sopenharmony_ci * 2756bf215546Sopenharmony_ci * \sa iris_destroy_shader_state 2757bf215546Sopenharmony_ci */ 2758bf215546Sopenharmony_cistatic void 2759bf215546Sopenharmony_ciiris_delete_shader_state(struct pipe_context *ctx, void *state) 2760bf215546Sopenharmony_ci{ 2761bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = state; 2762bf215546Sopenharmony_ci struct iris_context *ice = (void *) ctx; 2763bf215546Sopenharmony_ci 2764bf215546Sopenharmony_ci const gl_shader_stage stage = ish->nir->info.stage; 2765bf215546Sopenharmony_ci 2766bf215546Sopenharmony_ci if (ice->shaders.uncompiled[stage] == ish) { 2767bf215546Sopenharmony_ci ice->shaders.uncompiled[stage] = NULL; 2768bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage; 2769bf215546Sopenharmony_ci } 2770bf215546Sopenharmony_ci 2771bf215546Sopenharmony_ci if (pipe_reference(&ish->ref, NULL)) 2772bf215546Sopenharmony_ci iris_destroy_shader_state(ctx, state); 2773bf215546Sopenharmony_ci} 2774bf215546Sopenharmony_ci 2775bf215546Sopenharmony_ci/** 2776bf215546Sopenharmony_ci * The pipe->bind_[stage]_state() driver hook. 2777bf215546Sopenharmony_ci * 2778bf215546Sopenharmony_ci * Binds an uncompiled shader as the current one for a particular stage. 2779bf215546Sopenharmony_ci * Updates dirty tracking to account for the shader's NOS. 2780bf215546Sopenharmony_ci */ 2781bf215546Sopenharmony_cistatic void 2782bf215546Sopenharmony_cibind_shader_state(struct iris_context *ice, 2783bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish, 2784bf215546Sopenharmony_ci gl_shader_stage stage) 2785bf215546Sopenharmony_ci{ 2786bf215546Sopenharmony_ci uint64_t stage_dirty_bit = IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage; 2787bf215546Sopenharmony_ci const uint64_t nos = ish ? ish->nos : 0; 2788bf215546Sopenharmony_ci 2789bf215546Sopenharmony_ci const struct shader_info *old_info = iris_get_shader_info(ice, stage); 2790bf215546Sopenharmony_ci const struct shader_info *new_info = ish ? &ish->nir->info : NULL; 2791bf215546Sopenharmony_ci 2792bf215546Sopenharmony_ci if ((old_info ? BITSET_LAST_BIT(old_info->textures_used) : 0) != 2793bf215546Sopenharmony_ci (new_info ? BITSET_LAST_BIT(new_info->textures_used) : 0)) { 2794bf215546Sopenharmony_ci ice->state.stage_dirty |= IRIS_STAGE_DIRTY_SAMPLER_STATES_VS << stage; 2795bf215546Sopenharmony_ci } 2796bf215546Sopenharmony_ci 2797bf215546Sopenharmony_ci ice->shaders.uncompiled[stage] = ish; 2798bf215546Sopenharmony_ci ice->state.stage_dirty |= stage_dirty_bit; 2799bf215546Sopenharmony_ci 2800bf215546Sopenharmony_ci /* Record that CSOs need to mark IRIS_DIRTY_UNCOMPILED_XS when they change 2801bf215546Sopenharmony_ci * (or that they no longer need to do so). 2802bf215546Sopenharmony_ci */ 2803bf215546Sopenharmony_ci for (int i = 0; i < IRIS_NOS_COUNT; i++) { 2804bf215546Sopenharmony_ci if (nos & (1 << i)) 2805bf215546Sopenharmony_ci ice->state.stage_dirty_for_nos[i] |= stage_dirty_bit; 2806bf215546Sopenharmony_ci else 2807bf215546Sopenharmony_ci ice->state.stage_dirty_for_nos[i] &= ~stage_dirty_bit; 2808bf215546Sopenharmony_ci } 2809bf215546Sopenharmony_ci} 2810bf215546Sopenharmony_ci 2811bf215546Sopenharmony_cistatic void 2812bf215546Sopenharmony_ciiris_bind_vs_state(struct pipe_context *ctx, void *state) 2813bf215546Sopenharmony_ci{ 2814bf215546Sopenharmony_ci struct iris_context *ice = (struct iris_context *)ctx; 2815bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = state; 2816bf215546Sopenharmony_ci 2817bf215546Sopenharmony_ci if (ish) { 2818bf215546Sopenharmony_ci const struct shader_info *info = &ish->nir->info; 2819bf215546Sopenharmony_ci if (ice->state.window_space_position != info->vs.window_space_position) { 2820bf215546Sopenharmony_ci ice->state.window_space_position = info->vs.window_space_position; 2821bf215546Sopenharmony_ci 2822bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_CLIP | 2823bf215546Sopenharmony_ci IRIS_DIRTY_RASTER | 2824bf215546Sopenharmony_ci IRIS_DIRTY_CC_VIEWPORT; 2825bf215546Sopenharmony_ci } 2826bf215546Sopenharmony_ci 2827bf215546Sopenharmony_ci const bool uses_draw_params = 2828bf215546Sopenharmony_ci BITSET_TEST(info->system_values_read, SYSTEM_VALUE_FIRST_VERTEX) || 2829bf215546Sopenharmony_ci BITSET_TEST(info->system_values_read, SYSTEM_VALUE_BASE_INSTANCE); 2830bf215546Sopenharmony_ci const bool uses_derived_draw_params = 2831bf215546Sopenharmony_ci BITSET_TEST(info->system_values_read, SYSTEM_VALUE_DRAW_ID) || 2832bf215546Sopenharmony_ci BITSET_TEST(info->system_values_read, SYSTEM_VALUE_IS_INDEXED_DRAW); 2833bf215546Sopenharmony_ci const bool needs_sgvs_element = uses_draw_params || 2834bf215546Sopenharmony_ci BITSET_TEST(info->system_values_read, SYSTEM_VALUE_INSTANCE_ID) || 2835bf215546Sopenharmony_ci BITSET_TEST(info->system_values_read, 2836bf215546Sopenharmony_ci SYSTEM_VALUE_VERTEX_ID_ZERO_BASE); 2837bf215546Sopenharmony_ci 2838bf215546Sopenharmony_ci if (ice->state.vs_uses_draw_params != uses_draw_params || 2839bf215546Sopenharmony_ci ice->state.vs_uses_derived_draw_params != uses_derived_draw_params || 2840bf215546Sopenharmony_ci ice->state.vs_needs_edge_flag != info->vs.needs_edge_flag || 2841bf215546Sopenharmony_ci ice->state.vs_needs_sgvs_element != needs_sgvs_element) { 2842bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS | 2843bf215546Sopenharmony_ci IRIS_DIRTY_VERTEX_ELEMENTS; 2844bf215546Sopenharmony_ci } 2845bf215546Sopenharmony_ci 2846bf215546Sopenharmony_ci ice->state.vs_uses_draw_params = uses_draw_params; 2847bf215546Sopenharmony_ci ice->state.vs_uses_derived_draw_params = uses_derived_draw_params; 2848bf215546Sopenharmony_ci ice->state.vs_needs_sgvs_element = needs_sgvs_element; 2849bf215546Sopenharmony_ci ice->state.vs_needs_edge_flag = info->vs.needs_edge_flag; 2850bf215546Sopenharmony_ci } 2851bf215546Sopenharmony_ci 2852bf215546Sopenharmony_ci bind_shader_state((void *) ctx, state, MESA_SHADER_VERTEX); 2853bf215546Sopenharmony_ci} 2854bf215546Sopenharmony_ci 2855bf215546Sopenharmony_cistatic void 2856bf215546Sopenharmony_ciiris_bind_tcs_state(struct pipe_context *ctx, void *state) 2857bf215546Sopenharmony_ci{ 2858bf215546Sopenharmony_ci bind_shader_state((void *) ctx, state, MESA_SHADER_TESS_CTRL); 2859bf215546Sopenharmony_ci} 2860bf215546Sopenharmony_ci 2861bf215546Sopenharmony_cistatic void 2862bf215546Sopenharmony_ciiris_bind_tes_state(struct pipe_context *ctx, void *state) 2863bf215546Sopenharmony_ci{ 2864bf215546Sopenharmony_ci struct iris_context *ice = (struct iris_context *)ctx; 2865bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) ctx->screen; 2866bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 2867bf215546Sopenharmony_ci 2868bf215546Sopenharmony_ci /* Enabling/disabling optional stages requires a URB reconfiguration. */ 2869bf215546Sopenharmony_ci if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_TESS_EVAL]) 2870bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_URB | (devinfo->verx10 >= 125 ? 2871bf215546Sopenharmony_ci IRIS_DIRTY_VFG : 0); 2872bf215546Sopenharmony_ci 2873bf215546Sopenharmony_ci bind_shader_state((void *) ctx, state, MESA_SHADER_TESS_EVAL); 2874bf215546Sopenharmony_ci} 2875bf215546Sopenharmony_ci 2876bf215546Sopenharmony_cistatic void 2877bf215546Sopenharmony_ciiris_bind_gs_state(struct pipe_context *ctx, void *state) 2878bf215546Sopenharmony_ci{ 2879bf215546Sopenharmony_ci struct iris_context *ice = (struct iris_context *)ctx; 2880bf215546Sopenharmony_ci 2881bf215546Sopenharmony_ci /* Enabling/disabling optional stages requires a URB reconfiguration. */ 2882bf215546Sopenharmony_ci if (!!state != !!ice->shaders.uncompiled[MESA_SHADER_GEOMETRY]) 2883bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_URB; 2884bf215546Sopenharmony_ci 2885bf215546Sopenharmony_ci bind_shader_state((void *) ctx, state, MESA_SHADER_GEOMETRY); 2886bf215546Sopenharmony_ci} 2887bf215546Sopenharmony_ci 2888bf215546Sopenharmony_cistatic void 2889bf215546Sopenharmony_ciiris_bind_fs_state(struct pipe_context *ctx, void *state) 2890bf215546Sopenharmony_ci{ 2891bf215546Sopenharmony_ci struct iris_context *ice = (struct iris_context *) ctx; 2892bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) ctx->screen; 2893bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 2894bf215546Sopenharmony_ci struct iris_uncompiled_shader *old_ish = 2895bf215546Sopenharmony_ci ice->shaders.uncompiled[MESA_SHADER_FRAGMENT]; 2896bf215546Sopenharmony_ci struct iris_uncompiled_shader *new_ish = state; 2897bf215546Sopenharmony_ci 2898bf215546Sopenharmony_ci const unsigned color_bits = 2899bf215546Sopenharmony_ci BITFIELD64_BIT(FRAG_RESULT_COLOR) | 2900bf215546Sopenharmony_ci BITFIELD64_RANGE(FRAG_RESULT_DATA0, BRW_MAX_DRAW_BUFFERS); 2901bf215546Sopenharmony_ci 2902bf215546Sopenharmony_ci /* Fragment shader outputs influence HasWriteableRT */ 2903bf215546Sopenharmony_ci if (!old_ish || !new_ish || 2904bf215546Sopenharmony_ci (old_ish->nir->info.outputs_written & color_bits) != 2905bf215546Sopenharmony_ci (new_ish->nir->info.outputs_written & color_bits)) 2906bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_PS_BLEND; 2907bf215546Sopenharmony_ci 2908bf215546Sopenharmony_ci if (devinfo->ver == 8) 2909bf215546Sopenharmony_ci ice->state.dirty |= IRIS_DIRTY_PMA_FIX; 2910bf215546Sopenharmony_ci 2911bf215546Sopenharmony_ci bind_shader_state((void *) ctx, state, MESA_SHADER_FRAGMENT); 2912bf215546Sopenharmony_ci} 2913bf215546Sopenharmony_ci 2914bf215546Sopenharmony_cistatic void 2915bf215546Sopenharmony_ciiris_bind_cs_state(struct pipe_context *ctx, void *state) 2916bf215546Sopenharmony_ci{ 2917bf215546Sopenharmony_ci bind_shader_state((void *) ctx, state, MESA_SHADER_COMPUTE); 2918bf215546Sopenharmony_ci} 2919bf215546Sopenharmony_ci 2920bf215546Sopenharmony_cistatic char * 2921bf215546Sopenharmony_ciiris_finalize_nir(struct pipe_screen *_screen, void *nirptr) 2922bf215546Sopenharmony_ci{ 2923bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *)_screen; 2924bf215546Sopenharmony_ci struct nir_shader *nir = (struct nir_shader *) nirptr; 2925bf215546Sopenharmony_ci const struct intel_device_info *devinfo = &screen->devinfo; 2926bf215546Sopenharmony_ci 2927bf215546Sopenharmony_ci NIR_PASS_V(nir, iris_fix_edge_flags); 2928bf215546Sopenharmony_ci 2929bf215546Sopenharmony_ci brw_preprocess_nir(screen->compiler, nir, NULL); 2930bf215546Sopenharmony_ci 2931bf215546Sopenharmony_ci NIR_PASS_V(nir, brw_nir_lower_storage_image, devinfo); 2932bf215546Sopenharmony_ci NIR_PASS_V(nir, iris_lower_storage_image_derefs); 2933bf215546Sopenharmony_ci 2934bf215546Sopenharmony_ci nir_sweep(nir); 2935bf215546Sopenharmony_ci 2936bf215546Sopenharmony_ci return NULL; 2937bf215546Sopenharmony_ci} 2938bf215546Sopenharmony_ci 2939bf215546Sopenharmony_cistatic void 2940bf215546Sopenharmony_ciiris_set_max_shader_compiler_threads(struct pipe_screen *pscreen, 2941bf215546Sopenharmony_ci unsigned max_threads) 2942bf215546Sopenharmony_ci{ 2943bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) pscreen; 2944bf215546Sopenharmony_ci util_queue_adjust_num_threads(&screen->shader_compiler_queue, max_threads); 2945bf215546Sopenharmony_ci} 2946bf215546Sopenharmony_ci 2947bf215546Sopenharmony_cistatic bool 2948bf215546Sopenharmony_ciiris_is_parallel_shader_compilation_finished(struct pipe_screen *pscreen, 2949bf215546Sopenharmony_ci void *v_shader, 2950bf215546Sopenharmony_ci enum pipe_shader_type p_stage) 2951bf215546Sopenharmony_ci{ 2952bf215546Sopenharmony_ci struct iris_screen *screen = (struct iris_screen *) pscreen; 2953bf215546Sopenharmony_ci 2954bf215546Sopenharmony_ci /* Threaded compilation is only used for the precompile. If precompile is 2955bf215546Sopenharmony_ci * disabled, threaded compilation is "done." 2956bf215546Sopenharmony_ci */ 2957bf215546Sopenharmony_ci if (!screen->precompile) 2958bf215546Sopenharmony_ci return true; 2959bf215546Sopenharmony_ci 2960bf215546Sopenharmony_ci struct iris_uncompiled_shader *ish = v_shader; 2961bf215546Sopenharmony_ci 2962bf215546Sopenharmony_ci /* When precompile is enabled, the first entry is the precompile variant. 2963bf215546Sopenharmony_ci * Check the ready fence of the precompile variant. 2964bf215546Sopenharmony_ci */ 2965bf215546Sopenharmony_ci struct iris_compiled_shader *first = 2966bf215546Sopenharmony_ci list_first_entry(&ish->variants, struct iris_compiled_shader, link); 2967bf215546Sopenharmony_ci 2968bf215546Sopenharmony_ci return util_queue_fence_is_signalled(&first->ready); 2969bf215546Sopenharmony_ci} 2970bf215546Sopenharmony_ci 2971bf215546Sopenharmony_civoid 2972bf215546Sopenharmony_ciiris_init_screen_program_functions(struct pipe_screen *pscreen) 2973bf215546Sopenharmony_ci{ 2974bf215546Sopenharmony_ci pscreen->is_parallel_shader_compilation_finished = 2975bf215546Sopenharmony_ci iris_is_parallel_shader_compilation_finished; 2976bf215546Sopenharmony_ci pscreen->set_max_shader_compiler_threads = 2977bf215546Sopenharmony_ci iris_set_max_shader_compiler_threads; 2978bf215546Sopenharmony_ci pscreen->finalize_nir = iris_finalize_nir; 2979bf215546Sopenharmony_ci} 2980bf215546Sopenharmony_ci 2981bf215546Sopenharmony_civoid 2982bf215546Sopenharmony_ciiris_init_program_functions(struct pipe_context *ctx) 2983bf215546Sopenharmony_ci{ 2984bf215546Sopenharmony_ci ctx->create_vs_state = iris_create_shader_state; 2985bf215546Sopenharmony_ci ctx->create_tcs_state = iris_create_shader_state; 2986bf215546Sopenharmony_ci ctx->create_tes_state = iris_create_shader_state; 2987bf215546Sopenharmony_ci ctx->create_gs_state = iris_create_shader_state; 2988bf215546Sopenharmony_ci ctx->create_fs_state = iris_create_shader_state; 2989bf215546Sopenharmony_ci ctx->create_compute_state = iris_create_compute_state; 2990bf215546Sopenharmony_ci 2991bf215546Sopenharmony_ci ctx->delete_vs_state = iris_delete_shader_state; 2992bf215546Sopenharmony_ci ctx->delete_tcs_state = iris_delete_shader_state; 2993bf215546Sopenharmony_ci ctx->delete_tes_state = iris_delete_shader_state; 2994bf215546Sopenharmony_ci ctx->delete_gs_state = iris_delete_shader_state; 2995bf215546Sopenharmony_ci ctx->delete_fs_state = iris_delete_shader_state; 2996bf215546Sopenharmony_ci ctx->delete_compute_state = iris_delete_shader_state; 2997bf215546Sopenharmony_ci 2998bf215546Sopenharmony_ci ctx->bind_vs_state = iris_bind_vs_state; 2999bf215546Sopenharmony_ci ctx->bind_tcs_state = iris_bind_tcs_state; 3000bf215546Sopenharmony_ci ctx->bind_tes_state = iris_bind_tes_state; 3001bf215546Sopenharmony_ci ctx->bind_gs_state = iris_bind_gs_state; 3002bf215546Sopenharmony_ci ctx->bind_fs_state = iris_bind_fs_state; 3003bf215546Sopenharmony_ci ctx->bind_compute_state = iris_bind_cs_state; 3004bf215546Sopenharmony_ci} 3005