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