Home | History | Annotate | Line # | Download | only in util
      1 /*
      2  * Copyright (C) 2020 Collabora Ltd.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21  * SOFTWARE.
     22  *
     23  * Authors (Collabora):
     24  *      Alyssa Rosenzweig <alyssa.rosenzweig (at) collabora.com>
     25  */
     26 
     27 #include "pan_ir.h"
     28 #include "compiler/nir/nir_builder.h"
     29 
     30 /* TODO: ssbo_size */
     31 static int
     32 panfrost_sysval_for_ssbo(nir_intrinsic_instr *instr)
     33 {
     34         nir_src index = instr->src[0];
     35         assert(nir_src_is_const(index));
     36         uint32_t uindex = nir_src_as_uint(index);
     37 
     38         return PAN_SYSVAL(SSBO, uindex);
     39 }
     40 
     41 static int
     42 panfrost_sysval_for_sampler(nir_intrinsic_instr *instr)
     43 {
     44         /* TODO: indirect samplers !!! */
     45         nir_src index = instr->src[0];
     46         assert(nir_src_is_const(index));
     47         uint32_t uindex = nir_src_as_uint(index);
     48 
     49         return PAN_SYSVAL(SAMPLER, uindex);
     50 }
     51 
     52 static int
     53 panfrost_sysval_for_image_size(nir_intrinsic_instr *instr)
     54 {
     55         nir_src index = instr->src[0];
     56         assert(nir_src_is_const(index));
     57 
     58         bool is_array = nir_intrinsic_image_array(instr);
     59         uint32_t uindex = nir_src_as_uint(index);
     60         unsigned dim = nir_intrinsic_dest_components(instr) - is_array;
     61 
     62         return PAN_SYSVAL(IMAGE_SIZE, PAN_TXS_SYSVAL_ID(uindex, dim, is_array));
     63 }
     64 
     65 static unsigned
     66 panfrost_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr)
     67 {
     68         switch (instr->intrinsic) {
     69         case nir_intrinsic_load_viewport_scale:
     70                 return PAN_SYSVAL_VIEWPORT_SCALE;
     71         case nir_intrinsic_load_viewport_offset:
     72                 return PAN_SYSVAL_VIEWPORT_OFFSET;
     73         case nir_intrinsic_load_num_workgroups:
     74                 return PAN_SYSVAL_NUM_WORK_GROUPS;
     75         case nir_intrinsic_load_workgroup_size:
     76                 return PAN_SYSVAL_LOCAL_GROUP_SIZE;
     77         case nir_intrinsic_load_work_dim:
     78                 return PAN_SYSVAL_WORK_DIM;
     79         case nir_intrinsic_load_sample_positions_pan:
     80                 return PAN_SYSVAL_SAMPLE_POSITIONS;
     81         case nir_intrinsic_load_first_vertex:
     82         case nir_intrinsic_load_base_vertex:
     83         case nir_intrinsic_load_base_instance:
     84                 return PAN_SYSVAL_VERTEX_INSTANCE_OFFSETS;
     85         case nir_intrinsic_load_draw_id:
     86                 return PAN_SYSVAL_DRAWID;
     87         case nir_intrinsic_load_ssbo_address:
     88         case nir_intrinsic_get_ssbo_size:
     89                 return panfrost_sysval_for_ssbo(instr);
     90         case nir_intrinsic_load_sampler_lod_parameters_pan:
     91                 return panfrost_sysval_for_sampler(instr);
     92         case nir_intrinsic_image_size:
     93                 return panfrost_sysval_for_image_size(instr);
     94         case nir_intrinsic_load_blend_const_color_rgba:
     95                 return PAN_SYSVAL_BLEND_CONSTANTS;
     96         default:
     97                 return ~0;
     98         }
     99 }
    100 
    101 int
    102 panfrost_sysval_for_instr(nir_instr *instr, nir_dest *dest)
    103 {
    104         nir_intrinsic_instr *intr;
    105         nir_dest *dst = NULL;
    106         nir_tex_instr *tex;
    107         unsigned sysval = ~0;
    108 
    109         switch (instr->type) {
    110         case nir_instr_type_intrinsic:
    111                 intr = nir_instr_as_intrinsic(instr);
    112                 sysval = panfrost_nir_sysval_for_intrinsic(intr);
    113                 dst = &intr->dest;
    114                 break;
    115         case nir_instr_type_tex:
    116                 tex = nir_instr_as_tex(instr);
    117                 if (tex->op != nir_texop_txs)
    118                         break;
    119 
    120                 sysval = PAN_SYSVAL(TEXTURE_SIZE,
    121                                     PAN_TXS_SYSVAL_ID(tex->texture_index,
    122                                                       nir_tex_instr_dest_size(tex) -
    123                                                       (tex->is_array ? 1 : 0),
    124                                                       tex->is_array));
    125                 dst  = &tex->dest;
    126                 break;
    127         default:
    128                 break;
    129         }
    130 
    131         if (dest && dst)
    132                 *dest = *dst;
    133 
    134         return sysval;
    135 }
    136 
    137 unsigned
    138 pan_lookup_sysval(struct hash_table_u64 *sysval_to_id,
    139                   struct panfrost_sysvals *sysvals,
    140                   int sysval)
    141 {
    142         /* Try to lookup */
    143 
    144         void *cached = _mesa_hash_table_u64_search(sysval_to_id, sysval);
    145 
    146         if (cached)
    147                 return ((uintptr_t) cached) - 1;
    148 
    149         /* Else assign */
    150 
    151         unsigned id = sysvals->sysval_count++;
    152         assert(id < MAX_SYSVAL_COUNT);
    153         _mesa_hash_table_u64_insert(sysval_to_id, sysval, (void *) ((uintptr_t) id + 1));
    154         sysvals->sysvals[id] = sysval;
    155 
    156         return id;
    157 }
    158 
    159 struct hash_table_u64 *
    160 panfrost_init_sysvals(struct panfrost_sysvals *sysvals, void *memctx)
    161 {
    162         sysvals->sysval_count = 0;
    163         return _mesa_hash_table_u64_create(memctx);
    164 }
    165