1b8e80941Smrg/*
2b8e80941Smrg * Copyright (C) 2017-2018 Rob Clark <robclark@freedesktop.org>
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20b8e80941Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21b8e80941Smrg * SOFTWARE.
22b8e80941Smrg *
23b8e80941Smrg * Authors:
24b8e80941Smrg *    Rob Clark <robclark@freedesktop.org>
25b8e80941Smrg */
26b8e80941Smrg
27b8e80941Smrg#include "ir3_image.h"
28b8e80941Smrg
29b8e80941Smrg
30b8e80941Smrg/*
31b8e80941Smrg * SSBO/Image to/from IBO/tex hw mapping table:
32b8e80941Smrg */
33b8e80941Smrg
34b8e80941Smrgvoid
35b8e80941Smrgir3_ibo_mapping_init(struct ir3_ibo_mapping *mapping, unsigned num_textures)
36b8e80941Smrg{
37b8e80941Smrg	memset(mapping, IBO_INVALID, sizeof(*mapping));
38b8e80941Smrg	mapping->num_ibo = 0;
39b8e80941Smrg	mapping->num_tex = 0;
40b8e80941Smrg	mapping->tex_base = num_textures;
41b8e80941Smrg}
42b8e80941Smrg
43b8e80941Smrgunsigned
44b8e80941Smrgir3_ssbo_to_ibo(struct ir3_ibo_mapping *mapping, unsigned ssbo)
45b8e80941Smrg{
46b8e80941Smrg	if (mapping->ssbo_to_ibo[ssbo] == IBO_INVALID) {
47b8e80941Smrg		unsigned ibo = mapping->num_ibo++;
48b8e80941Smrg		mapping->ssbo_to_ibo[ssbo] = ibo;
49b8e80941Smrg		mapping->ibo_to_image[ibo] = IBO_SSBO | ssbo;
50b8e80941Smrg	}
51b8e80941Smrg	return mapping->ssbo_to_ibo[ssbo];
52b8e80941Smrg}
53b8e80941Smrg
54b8e80941Smrgunsigned
55b8e80941Smrgir3_ssbo_to_tex(struct ir3_ibo_mapping *mapping, unsigned ssbo)
56b8e80941Smrg{
57b8e80941Smrg	if (mapping->ssbo_to_tex[ssbo] == IBO_INVALID) {
58b8e80941Smrg		unsigned tex = mapping->num_tex++;
59b8e80941Smrg		mapping->ssbo_to_tex[ssbo] = tex;
60b8e80941Smrg		mapping->tex_to_image[tex] = IBO_SSBO | ssbo;
61b8e80941Smrg	}
62b8e80941Smrg	return mapping->ssbo_to_tex[ssbo] + mapping->tex_base;
63b8e80941Smrg}
64b8e80941Smrg
65b8e80941Smrgunsigned
66b8e80941Smrgir3_image_to_ibo(struct ir3_ibo_mapping *mapping, unsigned image)
67b8e80941Smrg{
68b8e80941Smrg	if (mapping->image_to_ibo[image] == IBO_INVALID) {
69b8e80941Smrg		unsigned ibo = mapping->num_ibo++;
70b8e80941Smrg		mapping->image_to_ibo[image] = ibo;
71b8e80941Smrg		mapping->ibo_to_image[ibo] = image;
72b8e80941Smrg	}
73b8e80941Smrg	return mapping->image_to_ibo[image];
74b8e80941Smrg}
75b8e80941Smrg
76b8e80941Smrgunsigned
77b8e80941Smrgir3_image_to_tex(struct ir3_ibo_mapping *mapping, unsigned image)
78b8e80941Smrg{
79b8e80941Smrg	if (mapping->image_to_tex[image] == IBO_INVALID) {
80b8e80941Smrg		unsigned tex = mapping->num_tex++;
81b8e80941Smrg		mapping->image_to_tex[image] = tex;
82b8e80941Smrg		mapping->tex_to_image[tex] = image;
83b8e80941Smrg	}
84b8e80941Smrg	return mapping->image_to_tex[image] + mapping->tex_base;
85b8e80941Smrg}
86b8e80941Smrg
87b8e80941Smrg/* Helper to parse the deref for an image to get image slot.  This should be
88b8e80941Smrg * mapped to tex or ibo idx using ir3_image_to_tex() or ir3_image_to_ibo().
89b8e80941Smrg */
90b8e80941Smrgunsigned
91b8e80941Smrgir3_get_image_slot(nir_deref_instr *deref)
92b8e80941Smrg{
93b8e80941Smrg	unsigned int loc = 0;
94b8e80941Smrg	unsigned inner_size = 1;
95b8e80941Smrg
96b8e80941Smrg	while (deref->deref_type != nir_deref_type_var) {
97b8e80941Smrg		assert(deref->deref_type == nir_deref_type_array);
98b8e80941Smrg		unsigned const_index = nir_src_as_uint(deref->arr.index);
99b8e80941Smrg
100b8e80941Smrg		/* Go to the next instruction */
101b8e80941Smrg		deref = nir_deref_instr_parent(deref);
102b8e80941Smrg
103b8e80941Smrg		assert(glsl_type_is_array(deref->type));
104b8e80941Smrg		const unsigned array_len = glsl_get_length(deref->type);
105b8e80941Smrg		loc += MIN2(const_index, array_len - 1) * inner_size;
106b8e80941Smrg
107b8e80941Smrg		/* Update the inner size */
108b8e80941Smrg		inner_size *= array_len;
109b8e80941Smrg	}
110b8e80941Smrg
111b8e80941Smrg	loc += deref->var->data.driver_location;
112b8e80941Smrg
113b8e80941Smrg	return loc;
114b8e80941Smrg}
115b8e80941Smrg
116b8e80941Smrg/* see tex_info() for equiv logic for texture instructions.. it would be
117b8e80941Smrg * nice if this could be better unified..
118b8e80941Smrg */
119b8e80941Smrgunsigned
120b8e80941Smrgir3_get_image_coords(const nir_variable *var, unsigned *flagsp)
121b8e80941Smrg{
122b8e80941Smrg	const struct glsl_type *type = glsl_without_array(var->type);
123b8e80941Smrg	unsigned coords, flags = 0;
124b8e80941Smrg
125b8e80941Smrg	switch (glsl_get_sampler_dim(type)) {
126b8e80941Smrg	case GLSL_SAMPLER_DIM_1D:
127b8e80941Smrg	case GLSL_SAMPLER_DIM_BUF:
128b8e80941Smrg		coords = 1;
129b8e80941Smrg		break;
130b8e80941Smrg	case GLSL_SAMPLER_DIM_2D:
131b8e80941Smrg	case GLSL_SAMPLER_DIM_RECT:
132b8e80941Smrg	case GLSL_SAMPLER_DIM_EXTERNAL:
133b8e80941Smrg	case GLSL_SAMPLER_DIM_MS:
134b8e80941Smrg		coords = 2;
135b8e80941Smrg		break;
136b8e80941Smrg	case GLSL_SAMPLER_DIM_3D:
137b8e80941Smrg	case GLSL_SAMPLER_DIM_CUBE:
138b8e80941Smrg		flags |= IR3_INSTR_3D;
139b8e80941Smrg		coords = 3;
140b8e80941Smrg		break;
141b8e80941Smrg	default:
142b8e80941Smrg		unreachable("bad sampler dim");
143b8e80941Smrg		return 0;
144b8e80941Smrg	}
145b8e80941Smrg
146b8e80941Smrg	if (glsl_sampler_type_is_array(type)) {
147b8e80941Smrg		/* note: unlike tex_info(), adjust # of coords to include array idx: */
148b8e80941Smrg		coords++;
149b8e80941Smrg		flags |= IR3_INSTR_A;
150b8e80941Smrg	}
151b8e80941Smrg
152b8e80941Smrg	if (flagsp)
153b8e80941Smrg		*flagsp = flags;
154b8e80941Smrg
155b8e80941Smrg	return coords;
156b8e80941Smrg}
157b8e80941Smrg
158b8e80941Smrgtype_t
159b8e80941Smrgir3_get_image_type(const nir_variable *var)
160b8e80941Smrg{
161b8e80941Smrg	switch (glsl_get_sampler_result_type(glsl_without_array(var->type))) {
162b8e80941Smrg	case GLSL_TYPE_UINT:
163b8e80941Smrg		return TYPE_U32;
164b8e80941Smrg	case GLSL_TYPE_INT:
165b8e80941Smrg		return TYPE_S32;
166b8e80941Smrg	case GLSL_TYPE_FLOAT:
167b8e80941Smrg		return TYPE_F32;
168b8e80941Smrg	default:
169b8e80941Smrg		unreachable("bad sampler type.");
170b8e80941Smrg		return 0;
171b8e80941Smrg	}
172b8e80941Smrg}
173b8e80941Smrg
174b8e80941Smrg/* Returns the number of components for the different image formats
175b8e80941Smrg * supported by the GLES 3.1 spec, plus those added by the
176b8e80941Smrg * GL_NV_image_formats extension.
177b8e80941Smrg */
178b8e80941Smrgunsigned
179b8e80941Smrgir3_get_num_components_for_glformat(GLuint format)
180b8e80941Smrg{
181b8e80941Smrg	switch (format) {
182b8e80941Smrg	case GL_R32F:
183b8e80941Smrg	case GL_R32I:
184b8e80941Smrg	case GL_R32UI:
185b8e80941Smrg	case GL_R16F:
186b8e80941Smrg	case GL_R16I:
187b8e80941Smrg	case GL_R16UI:
188b8e80941Smrg	case GL_R16:
189b8e80941Smrg	case GL_R16_SNORM:
190b8e80941Smrg	case GL_R8I:
191b8e80941Smrg	case GL_R8UI:
192b8e80941Smrg	case GL_R8:
193b8e80941Smrg	case GL_R8_SNORM:
194b8e80941Smrg		return 1;
195b8e80941Smrg
196b8e80941Smrg	case GL_RG32F:
197b8e80941Smrg	case GL_RG32I:
198b8e80941Smrg	case GL_RG32UI:
199b8e80941Smrg	case GL_RG16F:
200b8e80941Smrg	case GL_RG16I:
201b8e80941Smrg	case GL_RG16UI:
202b8e80941Smrg	case GL_RG16:
203b8e80941Smrg	case GL_RG16_SNORM:
204b8e80941Smrg	case GL_RG8I:
205b8e80941Smrg	case GL_RG8UI:
206b8e80941Smrg	case GL_RG8:
207b8e80941Smrg	case GL_RG8_SNORM:
208b8e80941Smrg		return 2;
209b8e80941Smrg
210b8e80941Smrg	case GL_R11F_G11F_B10F:
211b8e80941Smrg		return 3;
212b8e80941Smrg
213b8e80941Smrg	case GL_RGBA32F:
214b8e80941Smrg	case GL_RGBA32I:
215b8e80941Smrg	case GL_RGBA32UI:
216b8e80941Smrg	case GL_RGBA16F:
217b8e80941Smrg	case GL_RGBA16I:
218b8e80941Smrg	case GL_RGBA16UI:
219b8e80941Smrg	case GL_RGBA16:
220b8e80941Smrg	case GL_RGBA16_SNORM:
221b8e80941Smrg	case GL_RGBA8I:
222b8e80941Smrg	case GL_RGBA8UI:
223b8e80941Smrg	case GL_RGBA8:
224b8e80941Smrg	case GL_RGBA8_SNORM:
225b8e80941Smrg	case GL_RGB10_A2UI:
226b8e80941Smrg	case GL_RGB10_A2:
227b8e80941Smrg		return 4;
228b8e80941Smrg
229b8e80941Smrg	case GL_NONE:
230b8e80941Smrg		/* Omitting the image format qualifier is allowed on desktop GL
231b8e80941Smrg		 * profiles. Assuming 4 components is always safe.
232b8e80941Smrg		 */
233b8e80941Smrg		return 4;
234b8e80941Smrg
235b8e80941Smrg	default:
236b8e80941Smrg		/* Return 4 components also for all other formats we don't know
237b8e80941Smrg		 * about. The format should have been validated already by
238b8e80941Smrg		 * the higher level API, but drop a debug message just in case.
239b8e80941Smrg		 */
240b8e80941Smrg		debug_printf("Unhandled GL format %u while emitting imageStore()\n",
241b8e80941Smrg					 format);
242b8e80941Smrg		return 4;
243b8e80941Smrg	}
244b8e80941Smrg}
245