nir/lower_idiv: add new llvm-based path
[mesa.git] / src / freedreno / ir3 / ir3_image.c
1 /*
2 * Copyright (C) 2017-2018 Rob Clark <robclark@freedesktop.org>
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:
24 * Rob Clark <robclark@freedesktop.org>
25 */
26
27 #include "ir3_image.h"
28
29
30 /*
31 * SSBO/Image to/from IBO/tex hw mapping table:
32 */
33
34 void
35 ir3_ibo_mapping_init(struct ir3_ibo_mapping *mapping, unsigned num_textures)
36 {
37 memset(mapping, IBO_INVALID, sizeof(*mapping));
38 mapping->num_ibo = 0;
39 mapping->num_tex = 0;
40 mapping->tex_base = num_textures;
41 }
42
43 unsigned
44 ir3_ssbo_to_ibo(struct ir3_ibo_mapping *mapping, unsigned ssbo)
45 {
46 if (mapping->ssbo_to_ibo[ssbo] == IBO_INVALID) {
47 unsigned ibo = mapping->num_ibo++;
48 mapping->ssbo_to_ibo[ssbo] = ibo;
49 mapping->ibo_to_image[ibo] = IBO_SSBO | ssbo;
50 }
51 return mapping->ssbo_to_ibo[ssbo];
52 }
53
54 unsigned
55 ir3_ssbo_to_tex(struct ir3_ibo_mapping *mapping, unsigned ssbo)
56 {
57 if (mapping->ssbo_to_tex[ssbo] == IBO_INVALID) {
58 unsigned tex = mapping->num_tex++;
59 mapping->ssbo_to_tex[ssbo] = tex;
60 mapping->tex_to_image[tex] = IBO_SSBO | ssbo;
61 }
62 return mapping->ssbo_to_tex[ssbo] + mapping->tex_base;
63 }
64
65 unsigned
66 ir3_image_to_ibo(struct ir3_ibo_mapping *mapping, unsigned image)
67 {
68 if (mapping->image_to_ibo[image] == IBO_INVALID) {
69 unsigned ibo = mapping->num_ibo++;
70 mapping->image_to_ibo[image] = ibo;
71 mapping->ibo_to_image[ibo] = image;
72 }
73 return mapping->image_to_ibo[image];
74 }
75
76 unsigned
77 ir3_image_to_tex(struct ir3_ibo_mapping *mapping, unsigned image)
78 {
79 if (mapping->image_to_tex[image] == IBO_INVALID) {
80 unsigned tex = mapping->num_tex++;
81 mapping->image_to_tex[image] = tex;
82 mapping->tex_to_image[tex] = image;
83 }
84 return mapping->image_to_tex[image] + mapping->tex_base;
85 }
86
87 /* Helper to parse the deref for an image to get image slot. This should be
88 * mapped to tex or ibo idx using ir3_image_to_tex() or ir3_image_to_ibo().
89 */
90 unsigned
91 ir3_get_image_slot(nir_deref_instr *deref)
92 {
93 unsigned int loc = 0;
94 unsigned inner_size = 1;
95
96 while (deref->deref_type != nir_deref_type_var) {
97 assert(deref->deref_type == nir_deref_type_array);
98 unsigned const_index = nir_src_as_uint(deref->arr.index);
99
100 /* Go to the next instruction */
101 deref = nir_deref_instr_parent(deref);
102
103 assert(glsl_type_is_array(deref->type));
104 const unsigned array_len = glsl_get_length(deref->type);
105 loc += MIN2(const_index, array_len - 1) * inner_size;
106
107 /* Update the inner size */
108 inner_size *= array_len;
109 }
110
111 loc += deref->var->data.driver_location;
112
113 return loc;
114 }
115
116 /* see tex_info() for equiv logic for texture instructions.. it would be
117 * nice if this could be better unified..
118 */
119 unsigned
120 ir3_get_image_coords(const nir_variable *var, unsigned *flagsp)
121 {
122 const struct glsl_type *type = glsl_without_array(var->type);
123 unsigned coords = glsl_get_sampler_coordinate_components(type);
124 unsigned flags = 0;
125
126 if (coords == 3)
127 flags |= IR3_INSTR_3D;
128
129 if (glsl_sampler_type_is_array(type))
130 flags |= IR3_INSTR_A;
131
132 if (flagsp)
133 *flagsp = flags;
134
135 return coords;
136 }
137
138 type_t
139 ir3_get_image_type(const nir_variable *var)
140 {
141 switch (glsl_get_sampler_result_type(glsl_without_array(var->type))) {
142 case GLSL_TYPE_UINT:
143 return TYPE_U32;
144 case GLSL_TYPE_INT:
145 return TYPE_S32;
146 case GLSL_TYPE_FLOAT:
147 return TYPE_F32;
148 default:
149 unreachable("bad sampler type.");
150 return 0;
151 }
152 }
153
154 /* Returns the number of components for the different image formats
155 * supported by the GLES 3.1 spec, plus those added by the
156 * GL_NV_image_formats extension.
157 */
158 unsigned
159 ir3_get_num_components_for_glformat(GLuint format)
160 {
161 switch (format) {
162 case GL_R32F:
163 case GL_R32I:
164 case GL_R32UI:
165 case GL_R16F:
166 case GL_R16I:
167 case GL_R16UI:
168 case GL_R16:
169 case GL_R16_SNORM:
170 case GL_R8I:
171 case GL_R8UI:
172 case GL_R8:
173 case GL_R8_SNORM:
174 return 1;
175
176 case GL_RG32F:
177 case GL_RG32I:
178 case GL_RG32UI:
179 case GL_RG16F:
180 case GL_RG16I:
181 case GL_RG16UI:
182 case GL_RG16:
183 case GL_RG16_SNORM:
184 case GL_RG8I:
185 case GL_RG8UI:
186 case GL_RG8:
187 case GL_RG8_SNORM:
188 return 2;
189
190 case GL_R11F_G11F_B10F:
191 return 3;
192
193 case GL_RGBA32F:
194 case GL_RGBA32I:
195 case GL_RGBA32UI:
196 case GL_RGBA16F:
197 case GL_RGBA16I:
198 case GL_RGBA16UI:
199 case GL_RGBA16:
200 case GL_RGBA16_SNORM:
201 case GL_RGBA8I:
202 case GL_RGBA8UI:
203 case GL_RGBA8:
204 case GL_RGBA8_SNORM:
205 case GL_RGB10_A2UI:
206 case GL_RGB10_A2:
207 return 4;
208
209 case GL_NONE:
210 /* Omitting the image format qualifier is allowed on desktop GL
211 * profiles. Assuming 4 components is always safe.
212 */
213 return 4;
214
215 default:
216 /* Return 4 components also for all other formats we don't know
217 * about. The format should have been validated already by
218 * the higher level API, but drop a debug message just in case.
219 */
220 debug_printf("Unhandled GL format %u while emitting imageStore()\n",
221 format);
222 return 4;
223 }
224 }