17ec681f3Smrg/* 27ec681f3Smrg * Copyright (C) 2020 Collabora Ltd. 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 207ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 217ec681f3Smrg * SOFTWARE. 227ec681f3Smrg * 237ec681f3Smrg * Authors (Collabora): 247ec681f3Smrg * Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> 257ec681f3Smrg */ 267ec681f3Smrg 277ec681f3Smrg#include "pan_ir.h" 287ec681f3Smrg#include "compiler/nir/nir_builder.h" 297ec681f3Smrg 307ec681f3Smrg/* TODO: ssbo_size */ 317ec681f3Smrgstatic int 327ec681f3Smrgpanfrost_sysval_for_ssbo(nir_intrinsic_instr *instr) 337ec681f3Smrg{ 347ec681f3Smrg nir_src index = instr->src[0]; 357ec681f3Smrg assert(nir_src_is_const(index)); 367ec681f3Smrg uint32_t uindex = nir_src_as_uint(index); 377ec681f3Smrg 387ec681f3Smrg return PAN_SYSVAL(SSBO, uindex); 397ec681f3Smrg} 407ec681f3Smrg 417ec681f3Smrgstatic int 427ec681f3Smrgpanfrost_sysval_for_sampler(nir_intrinsic_instr *instr) 437ec681f3Smrg{ 447ec681f3Smrg /* TODO: indirect samplers !!! */ 457ec681f3Smrg nir_src index = instr->src[0]; 467ec681f3Smrg assert(nir_src_is_const(index)); 477ec681f3Smrg uint32_t uindex = nir_src_as_uint(index); 487ec681f3Smrg 497ec681f3Smrg return PAN_SYSVAL(SAMPLER, uindex); 507ec681f3Smrg} 517ec681f3Smrg 527ec681f3Smrgstatic int 537ec681f3Smrgpanfrost_sysval_for_image_size(nir_intrinsic_instr *instr) 547ec681f3Smrg{ 557ec681f3Smrg nir_src index = instr->src[0]; 567ec681f3Smrg assert(nir_src_is_const(index)); 577ec681f3Smrg 587ec681f3Smrg bool is_array = nir_intrinsic_image_array(instr); 597ec681f3Smrg uint32_t uindex = nir_src_as_uint(index); 607ec681f3Smrg unsigned dim = nir_intrinsic_dest_components(instr) - is_array; 617ec681f3Smrg 627ec681f3Smrg return PAN_SYSVAL(IMAGE_SIZE, PAN_TXS_SYSVAL_ID(uindex, dim, is_array)); 637ec681f3Smrg} 647ec681f3Smrg 657ec681f3Smrgstatic unsigned 667ec681f3Smrgpanfrost_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr) 677ec681f3Smrg{ 687ec681f3Smrg switch (instr->intrinsic) { 697ec681f3Smrg case nir_intrinsic_load_viewport_scale: 707ec681f3Smrg return PAN_SYSVAL_VIEWPORT_SCALE; 717ec681f3Smrg case nir_intrinsic_load_viewport_offset: 727ec681f3Smrg return PAN_SYSVAL_VIEWPORT_OFFSET; 737ec681f3Smrg case nir_intrinsic_load_num_workgroups: 747ec681f3Smrg return PAN_SYSVAL_NUM_WORK_GROUPS; 757ec681f3Smrg case nir_intrinsic_load_workgroup_size: 767ec681f3Smrg return PAN_SYSVAL_LOCAL_GROUP_SIZE; 777ec681f3Smrg case nir_intrinsic_load_work_dim: 787ec681f3Smrg return PAN_SYSVAL_WORK_DIM; 797ec681f3Smrg case nir_intrinsic_load_sample_positions_pan: 807ec681f3Smrg return PAN_SYSVAL_SAMPLE_POSITIONS; 817ec681f3Smrg case nir_intrinsic_load_first_vertex: 827ec681f3Smrg case nir_intrinsic_load_base_vertex: 837ec681f3Smrg case nir_intrinsic_load_base_instance: 847ec681f3Smrg return PAN_SYSVAL_VERTEX_INSTANCE_OFFSETS; 857ec681f3Smrg case nir_intrinsic_load_draw_id: 867ec681f3Smrg return PAN_SYSVAL_DRAWID; 877ec681f3Smrg case nir_intrinsic_load_ssbo_address: 887ec681f3Smrg case nir_intrinsic_get_ssbo_size: 897ec681f3Smrg return panfrost_sysval_for_ssbo(instr); 907ec681f3Smrg case nir_intrinsic_load_sampler_lod_parameters_pan: 917ec681f3Smrg return panfrost_sysval_for_sampler(instr); 927ec681f3Smrg case nir_intrinsic_image_size: 937ec681f3Smrg return panfrost_sysval_for_image_size(instr); 947ec681f3Smrg case nir_intrinsic_load_blend_const_color_rgba: 957ec681f3Smrg return PAN_SYSVAL_BLEND_CONSTANTS; 967ec681f3Smrg default: 977ec681f3Smrg return ~0; 987ec681f3Smrg } 997ec681f3Smrg} 1007ec681f3Smrg 1017ec681f3Smrgint 1027ec681f3Smrgpanfrost_sysval_for_instr(nir_instr *instr, nir_dest *dest) 1037ec681f3Smrg{ 1047ec681f3Smrg nir_intrinsic_instr *intr; 1057ec681f3Smrg nir_dest *dst = NULL; 1067ec681f3Smrg nir_tex_instr *tex; 1077ec681f3Smrg unsigned sysval = ~0; 1087ec681f3Smrg 1097ec681f3Smrg switch (instr->type) { 1107ec681f3Smrg case nir_instr_type_intrinsic: 1117ec681f3Smrg intr = nir_instr_as_intrinsic(instr); 1127ec681f3Smrg sysval = panfrost_nir_sysval_for_intrinsic(intr); 1137ec681f3Smrg dst = &intr->dest; 1147ec681f3Smrg break; 1157ec681f3Smrg case nir_instr_type_tex: 1167ec681f3Smrg tex = nir_instr_as_tex(instr); 1177ec681f3Smrg if (tex->op != nir_texop_txs) 1187ec681f3Smrg break; 1197ec681f3Smrg 1207ec681f3Smrg sysval = PAN_SYSVAL(TEXTURE_SIZE, 1217ec681f3Smrg PAN_TXS_SYSVAL_ID(tex->texture_index, 1227ec681f3Smrg nir_tex_instr_dest_size(tex) - 1237ec681f3Smrg (tex->is_array ? 1 : 0), 1247ec681f3Smrg tex->is_array)); 1257ec681f3Smrg dst = &tex->dest; 1267ec681f3Smrg break; 1277ec681f3Smrg default: 1287ec681f3Smrg break; 1297ec681f3Smrg } 1307ec681f3Smrg 1317ec681f3Smrg if (dest && dst) 1327ec681f3Smrg *dest = *dst; 1337ec681f3Smrg 1347ec681f3Smrg return sysval; 1357ec681f3Smrg} 1367ec681f3Smrg 1377ec681f3Smrgunsigned 1387ec681f3Smrgpan_lookup_sysval(struct hash_table_u64 *sysval_to_id, 1397ec681f3Smrg struct panfrost_sysvals *sysvals, 1407ec681f3Smrg int sysval) 1417ec681f3Smrg{ 1427ec681f3Smrg /* Try to lookup */ 1437ec681f3Smrg 1447ec681f3Smrg void *cached = _mesa_hash_table_u64_search(sysval_to_id, sysval); 1457ec681f3Smrg 1467ec681f3Smrg if (cached) 1477ec681f3Smrg return ((uintptr_t) cached) - 1; 1487ec681f3Smrg 1497ec681f3Smrg /* Else assign */ 1507ec681f3Smrg 1517ec681f3Smrg unsigned id = sysvals->sysval_count++; 1527ec681f3Smrg assert(id < MAX_SYSVAL_COUNT); 1537ec681f3Smrg _mesa_hash_table_u64_insert(sysval_to_id, sysval, (void *) ((uintptr_t) id + 1)); 1547ec681f3Smrg sysvals->sysvals[id] = sysval; 1557ec681f3Smrg 1567ec681f3Smrg return id; 1577ec681f3Smrg} 1587ec681f3Smrg 1597ec681f3Smrgstruct hash_table_u64 * 1607ec681f3Smrgpanfrost_init_sysvals(struct panfrost_sysvals *sysvals, void *memctx) 1617ec681f3Smrg{ 1627ec681f3Smrg sysvals->sysval_count = 0; 1637ec681f3Smrg return _mesa_hash_table_u64_create(memctx); 1647ec681f3Smrg} 165