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
34void
35ir3_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
43unsigned
44ir3_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
54unsigned
55ir3_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
65unsigned
66ir3_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
76unsigned
77ir3_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 */
90unsigned
91ir3_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 */
119unsigned
120ir3_get_image_coords(const nir_variable *var, unsigned *flagsp)
121{
122	const struct glsl_type *type = glsl_without_array(var->type);
123	unsigned coords, flags = 0;
124
125	switch (glsl_get_sampler_dim(type)) {
126	case GLSL_SAMPLER_DIM_1D:
127	case GLSL_SAMPLER_DIM_BUF:
128		coords = 1;
129		break;
130	case GLSL_SAMPLER_DIM_2D:
131	case GLSL_SAMPLER_DIM_RECT:
132	case GLSL_SAMPLER_DIM_EXTERNAL:
133	case GLSL_SAMPLER_DIM_MS:
134		coords = 2;
135		break;
136	case GLSL_SAMPLER_DIM_3D:
137	case GLSL_SAMPLER_DIM_CUBE:
138		flags |= IR3_INSTR_3D;
139		coords = 3;
140		break;
141	default:
142		unreachable("bad sampler dim");
143		return 0;
144	}
145
146	if (glsl_sampler_type_is_array(type)) {
147		/* note: unlike tex_info(), adjust # of coords to include array idx: */
148		coords++;
149		flags |= IR3_INSTR_A;
150	}
151
152	if (flagsp)
153		*flagsp = flags;
154
155	return coords;
156}
157
158type_t
159ir3_get_image_type(const nir_variable *var)
160{
161	switch (glsl_get_sampler_result_type(glsl_without_array(var->type))) {
162	case GLSL_TYPE_UINT:
163		return TYPE_U32;
164	case GLSL_TYPE_INT:
165		return TYPE_S32;
166	case GLSL_TYPE_FLOAT:
167		return TYPE_F32;
168	default:
169		unreachable("bad sampler type.");
170		return 0;
171	}
172}
173
174/* Returns the number of components for the different image formats
175 * supported by the GLES 3.1 spec, plus those added by the
176 * GL_NV_image_formats extension.
177 */
178unsigned
179ir3_get_num_components_for_glformat(GLuint format)
180{
181	switch (format) {
182	case GL_R32F:
183	case GL_R32I:
184	case GL_R32UI:
185	case GL_R16F:
186	case GL_R16I:
187	case GL_R16UI:
188	case GL_R16:
189	case GL_R16_SNORM:
190	case GL_R8I:
191	case GL_R8UI:
192	case GL_R8:
193	case GL_R8_SNORM:
194		return 1;
195
196	case GL_RG32F:
197	case GL_RG32I:
198	case GL_RG32UI:
199	case GL_RG16F:
200	case GL_RG16I:
201	case GL_RG16UI:
202	case GL_RG16:
203	case GL_RG16_SNORM:
204	case GL_RG8I:
205	case GL_RG8UI:
206	case GL_RG8:
207	case GL_RG8_SNORM:
208		return 2;
209
210	case GL_R11F_G11F_B10F:
211		return 3;
212
213	case GL_RGBA32F:
214	case GL_RGBA32I:
215	case GL_RGBA32UI:
216	case GL_RGBA16F:
217	case GL_RGBA16I:
218	case GL_RGBA16UI:
219	case GL_RGBA16:
220	case GL_RGBA16_SNORM:
221	case GL_RGBA8I:
222	case GL_RGBA8UI:
223	case GL_RGBA8:
224	case GL_RGBA8_SNORM:
225	case GL_RGB10_A2UI:
226	case GL_RGB10_A2:
227		return 4;
228
229	case GL_NONE:
230		/* Omitting the image format qualifier is allowed on desktop GL
231		 * profiles. Assuming 4 components is always safe.
232		 */
233		return 4;
234
235	default:
236		/* Return 4 components also for all other formats we don't know
237		 * about. The format should have been validated already by
238		 * the higher level API, but drop a debug message just in case.
239		 */
240		debug_printf("Unhandled GL format %u while emitting imageStore()\n",
241					 format);
242		return 4;
243	}
244}
245