xref: /aosp_15_r20/external/mesa3d/src/freedreno/ir3/ir3_image.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2017-2018 Rob Clark <[email protected]>
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * Authors:
6*61046927SAndroid Build Coastguard Worker  *    Rob Clark <[email protected]>
7*61046927SAndroid Build Coastguard Worker  */
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker #include "ir3_image.h"
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker /*
12*61046927SAndroid Build Coastguard Worker  * SSBO/Image to/from IBO/tex hw mapping table:
13*61046927SAndroid Build Coastguard Worker  */
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker void
ir3_ibo_mapping_init(struct ir3_ibo_mapping * mapping,unsigned num_textures)16*61046927SAndroid Build Coastguard Worker ir3_ibo_mapping_init(struct ir3_ibo_mapping *mapping, unsigned num_textures)
17*61046927SAndroid Build Coastguard Worker {
18*61046927SAndroid Build Coastguard Worker    memset(mapping, IBO_INVALID, sizeof(*mapping));
19*61046927SAndroid Build Coastguard Worker    mapping->num_tex = 0;
20*61046927SAndroid Build Coastguard Worker    mapping->tex_base = num_textures;
21*61046927SAndroid Build Coastguard Worker }
22*61046927SAndroid Build Coastguard Worker 
23*61046927SAndroid Build Coastguard Worker struct ir3_instruction *
ir3_ssbo_to_ibo(struct ir3_context * ctx,nir_src src)24*61046927SAndroid Build Coastguard Worker ir3_ssbo_to_ibo(struct ir3_context *ctx, nir_src src)
25*61046927SAndroid Build Coastguard Worker {
26*61046927SAndroid Build Coastguard Worker    if (ir3_bindless_resource(src))
27*61046927SAndroid Build Coastguard Worker       ctx->so->bindless_ibo = true;
28*61046927SAndroid Build Coastguard Worker    return ir3_get_src(ctx, &src)[0];
29*61046927SAndroid Build Coastguard Worker }
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker unsigned
ir3_ssbo_to_tex(struct ir3_ibo_mapping * mapping,unsigned ssbo)32*61046927SAndroid Build Coastguard Worker ir3_ssbo_to_tex(struct ir3_ibo_mapping *mapping, unsigned ssbo)
33*61046927SAndroid Build Coastguard Worker {
34*61046927SAndroid Build Coastguard Worker    if (mapping->ssbo_to_tex[ssbo] == IBO_INVALID) {
35*61046927SAndroid Build Coastguard Worker       unsigned tex = mapping->num_tex++;
36*61046927SAndroid Build Coastguard Worker       mapping->ssbo_to_tex[ssbo] = tex;
37*61046927SAndroid Build Coastguard Worker       mapping->tex_to_image[tex] = IBO_SSBO | ssbo;
38*61046927SAndroid Build Coastguard Worker    }
39*61046927SAndroid Build Coastguard Worker    return mapping->ssbo_to_tex[ssbo] + mapping->tex_base;
40*61046927SAndroid Build Coastguard Worker }
41*61046927SAndroid Build Coastguard Worker 
42*61046927SAndroid Build Coastguard Worker struct ir3_instruction *
ir3_image_to_ibo(struct ir3_context * ctx,nir_src src)43*61046927SAndroid Build Coastguard Worker ir3_image_to_ibo(struct ir3_context *ctx, nir_src src)
44*61046927SAndroid Build Coastguard Worker {
45*61046927SAndroid Build Coastguard Worker    if (ir3_bindless_resource(src)) {
46*61046927SAndroid Build Coastguard Worker       ctx->so->bindless_ibo = true;
47*61046927SAndroid Build Coastguard Worker       return ir3_get_src(ctx, &src)[0];
48*61046927SAndroid Build Coastguard Worker    }
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker    if (nir_src_is_const(src)) {
51*61046927SAndroid Build Coastguard Worker       int image_idx = nir_src_as_uint(src);
52*61046927SAndroid Build Coastguard Worker       return create_immed(ctx->block, ctx->s->info.num_ssbos + image_idx);
53*61046927SAndroid Build Coastguard Worker    } else {
54*61046927SAndroid Build Coastguard Worker       struct ir3_instruction *image_idx = ir3_get_src(ctx, &src)[0];
55*61046927SAndroid Build Coastguard Worker       if (ctx->s->info.num_ssbos) {
56*61046927SAndroid Build Coastguard Worker          return ir3_ADD_U(ctx->block,
57*61046927SAndroid Build Coastguard Worker             image_idx, 0,
58*61046927SAndroid Build Coastguard Worker             create_immed(ctx->block, ctx->s->info.num_ssbos), 0);
59*61046927SAndroid Build Coastguard Worker       } else {
60*61046927SAndroid Build Coastguard Worker          return image_idx;
61*61046927SAndroid Build Coastguard Worker       }
62*61046927SAndroid Build Coastguard Worker    }
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker unsigned
ir3_image_to_tex(struct ir3_ibo_mapping * mapping,unsigned image)66*61046927SAndroid Build Coastguard Worker ir3_image_to_tex(struct ir3_ibo_mapping *mapping, unsigned image)
67*61046927SAndroid Build Coastguard Worker {
68*61046927SAndroid Build Coastguard Worker    if (mapping->image_to_tex[image] == IBO_INVALID) {
69*61046927SAndroid Build Coastguard Worker       unsigned tex = mapping->num_tex++;
70*61046927SAndroid Build Coastguard Worker       mapping->image_to_tex[image] = tex;
71*61046927SAndroid Build Coastguard Worker       mapping->tex_to_image[tex] = image;
72*61046927SAndroid Build Coastguard Worker    }
73*61046927SAndroid Build Coastguard Worker    return mapping->image_to_tex[image] + mapping->tex_base;
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker /* see tex_info() for equiv logic for texture instructions.. it would be
77*61046927SAndroid Build Coastguard Worker  * nice if this could be better unified..
78*61046927SAndroid Build Coastguard Worker  */
79*61046927SAndroid Build Coastguard Worker unsigned
ir3_get_image_coords(const nir_intrinsic_instr * instr,unsigned * flagsp)80*61046927SAndroid Build Coastguard Worker ir3_get_image_coords(const nir_intrinsic_instr *instr, unsigned *flagsp)
81*61046927SAndroid Build Coastguard Worker {
82*61046927SAndroid Build Coastguard Worker    enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
83*61046927SAndroid Build Coastguard Worker    unsigned coords = nir_image_intrinsic_coord_components(instr);
84*61046927SAndroid Build Coastguard Worker    unsigned flags = 0;
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker    if (dim == GLSL_SAMPLER_DIM_CUBE || nir_intrinsic_image_array(instr))
87*61046927SAndroid Build Coastguard Worker       flags |= IR3_INSTR_A;
88*61046927SAndroid Build Coastguard Worker    else if (dim == GLSL_SAMPLER_DIM_3D)
89*61046927SAndroid Build Coastguard Worker       flags |= IR3_INSTR_3D;
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker    if (flagsp)
92*61046927SAndroid Build Coastguard Worker       *flagsp = flags;
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    return coords;
95*61046927SAndroid Build Coastguard Worker }
96*61046927SAndroid Build Coastguard Worker 
97*61046927SAndroid Build Coastguard Worker type_t
ir3_get_type_for_image_intrinsic(const nir_intrinsic_instr * instr)98*61046927SAndroid Build Coastguard Worker ir3_get_type_for_image_intrinsic(const nir_intrinsic_instr *instr)
99*61046927SAndroid Build Coastguard Worker {
100*61046927SAndroid Build Coastguard Worker    const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
101*61046927SAndroid Build Coastguard Worker    int bit_size = info->has_dest ? instr->def.bit_size : nir_src_bit_size(instr->src[3]);
102*61046927SAndroid Build Coastguard Worker 
103*61046927SAndroid Build Coastguard Worker    nir_alu_type type = nir_type_uint;
104*61046927SAndroid Build Coastguard Worker    switch (instr->intrinsic) {
105*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_image_load:
106*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_bindless_image_load:
107*61046927SAndroid Build Coastguard Worker       type = nir_alu_type_get_base_type(nir_intrinsic_dest_type(instr));
108*61046927SAndroid Build Coastguard Worker       /* SpvOpAtomicLoad doesn't have dest type */
109*61046927SAndroid Build Coastguard Worker       if (type == nir_type_invalid)
110*61046927SAndroid Build Coastguard Worker          type = nir_type_uint;
111*61046927SAndroid Build Coastguard Worker       break;
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_image_store:
114*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_bindless_image_store:
115*61046927SAndroid Build Coastguard Worker       type = nir_alu_type_get_base_type(nir_intrinsic_src_type(instr));
116*61046927SAndroid Build Coastguard Worker       /* SpvOpAtomicStore doesn't have src type */
117*61046927SAndroid Build Coastguard Worker       if (type == nir_type_invalid)
118*61046927SAndroid Build Coastguard Worker          type = nir_type_uint;
119*61046927SAndroid Build Coastguard Worker       break;
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_image_atomic:
122*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_bindless_image_atomic:
123*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_image_atomic_swap:
124*61046927SAndroid Build Coastguard Worker    case nir_intrinsic_bindless_image_atomic_swap:
125*61046927SAndroid Build Coastguard Worker       type = nir_atomic_op_type(nir_intrinsic_atomic_op(instr));
126*61046927SAndroid Build Coastguard Worker       break;
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    default:
129*61046927SAndroid Build Coastguard Worker       unreachable("Unhandled NIR image intrinsic");
130*61046927SAndroid Build Coastguard Worker    }
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    switch (type) {
133*61046927SAndroid Build Coastguard Worker    case nir_type_uint:
134*61046927SAndroid Build Coastguard Worker       return bit_size == 16 ? TYPE_U16 : TYPE_U32;
135*61046927SAndroid Build Coastguard Worker    case nir_type_int:
136*61046927SAndroid Build Coastguard Worker       return bit_size == 16 ? TYPE_S16 : TYPE_S32;
137*61046927SAndroid Build Coastguard Worker    case nir_type_float:
138*61046927SAndroid Build Coastguard Worker       return bit_size == 16 ? TYPE_F16 : TYPE_F32;
139*61046927SAndroid Build Coastguard Worker    default:
140*61046927SAndroid Build Coastguard Worker       unreachable("bad type");
141*61046927SAndroid Build Coastguard Worker    }
142*61046927SAndroid Build Coastguard Worker }
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker /* Returns the number of components for the different image formats
145*61046927SAndroid Build Coastguard Worker  * supported by the GLES 3.1 spec, plus those added by the
146*61046927SAndroid Build Coastguard Worker  * GL_NV_image_formats extension.
147*61046927SAndroid Build Coastguard Worker  */
148*61046927SAndroid Build Coastguard Worker unsigned
ir3_get_num_components_for_image_format(enum pipe_format format)149*61046927SAndroid Build Coastguard Worker ir3_get_num_components_for_image_format(enum pipe_format format)
150*61046927SAndroid Build Coastguard Worker {
151*61046927SAndroid Build Coastguard Worker    if (format == PIPE_FORMAT_NONE)
152*61046927SAndroid Build Coastguard Worker       return 4;
153*61046927SAndroid Build Coastguard Worker    else
154*61046927SAndroid Build Coastguard Worker       return util_format_get_nr_components(format);
155*61046927SAndroid Build Coastguard Worker }
156