1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2013 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci * Authors:
24bf215546Sopenharmony_ci *    Francisco Jerez <currojerez@riseup.net>
25bf215546Sopenharmony_ci */
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci#include <assert.h>
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "shaderimage.h"
30bf215546Sopenharmony_ci#include "mtypes.h"
31bf215546Sopenharmony_ci#include "formats.h"
32bf215546Sopenharmony_ci#include "errors.h"
33bf215546Sopenharmony_ci#include "hash.h"
34bf215546Sopenharmony_ci#include "context.h"
35bf215546Sopenharmony_ci#include "texobj.h"
36bf215546Sopenharmony_ci#include "teximage.h"
37bf215546Sopenharmony_ci#include "enums.h"
38bf215546Sopenharmony_ci#include "api_exec_decl.h"
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci#include "state_tracker/st_context.h"
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_cimesa_format
43bf215546Sopenharmony_ci_mesa_get_shader_image_format(GLenum format)
44bf215546Sopenharmony_ci{
45bf215546Sopenharmony_ci   switch (format) {
46bf215546Sopenharmony_ci   case GL_RGBA32F:
47bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_FLOAT32;
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci   case GL_RGBA16F:
50bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_FLOAT16;
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   case GL_RG32F:
53bf215546Sopenharmony_ci      return MESA_FORMAT_RG_FLOAT32;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   case GL_RG16F:
56bf215546Sopenharmony_ci      return MESA_FORMAT_RG_FLOAT16;
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci   case GL_R11F_G11F_B10F:
59bf215546Sopenharmony_ci      return MESA_FORMAT_R11G11B10_FLOAT;
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   case GL_R32F:
62bf215546Sopenharmony_ci      return MESA_FORMAT_R_FLOAT32;
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ci   case GL_R16F:
65bf215546Sopenharmony_ci      return MESA_FORMAT_R_FLOAT16;
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ci   case GL_RGBA32UI:
68bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_UINT32;
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci   case GL_RGBA16UI:
71bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_UINT16;
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   case GL_RGB10_A2UI:
74bf215546Sopenharmony_ci      return MESA_FORMAT_R10G10B10A2_UINT;
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   case GL_RGBA8UI:
77bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_UINT8;
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci   case GL_RG32UI:
80bf215546Sopenharmony_ci      return MESA_FORMAT_RG_UINT32;
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci   case GL_RG16UI:
83bf215546Sopenharmony_ci      return MESA_FORMAT_RG_UINT16;
84bf215546Sopenharmony_ci
85bf215546Sopenharmony_ci   case GL_RG8UI:
86bf215546Sopenharmony_ci      return MESA_FORMAT_RG_UINT8;
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci   case GL_R32UI:
89bf215546Sopenharmony_ci      return MESA_FORMAT_R_UINT32;
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci   case GL_R16UI:
92bf215546Sopenharmony_ci      return MESA_FORMAT_R_UINT16;
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   case GL_R8UI:
95bf215546Sopenharmony_ci      return MESA_FORMAT_R_UINT8;
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   case GL_RGBA32I:
98bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_SINT32;
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci   case GL_RGBA16I:
101bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_SINT16;
102bf215546Sopenharmony_ci
103bf215546Sopenharmony_ci   case GL_RGBA8I:
104bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_SINT8;
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   case GL_RG32I:
107bf215546Sopenharmony_ci      return MESA_FORMAT_RG_SINT32;
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci   case GL_RG16I:
110bf215546Sopenharmony_ci      return MESA_FORMAT_RG_SINT16;
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   case GL_RG8I:
113bf215546Sopenharmony_ci      return MESA_FORMAT_RG_SINT8;
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci   case GL_R32I:
116bf215546Sopenharmony_ci      return MESA_FORMAT_R_SINT32;
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci   case GL_R16I:
119bf215546Sopenharmony_ci      return MESA_FORMAT_R_SINT16;
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci   case GL_R8I:
122bf215546Sopenharmony_ci      return MESA_FORMAT_R_SINT8;
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   case GL_RGBA16:
125bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_UNORM16;
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci   case GL_RGB10_A2:
128bf215546Sopenharmony_ci      return MESA_FORMAT_R10G10B10A2_UNORM;
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci   case GL_RGBA8:
131bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_UNORM8;
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   case GL_RG16:
134bf215546Sopenharmony_ci      return MESA_FORMAT_RG_UNORM16;
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_ci   case GL_RG8:
137bf215546Sopenharmony_ci      return MESA_FORMAT_RG_UNORM8;
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   case GL_R16:
140bf215546Sopenharmony_ci      return MESA_FORMAT_R_UNORM16;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci   case GL_R8:
143bf215546Sopenharmony_ci      return MESA_FORMAT_R_UNORM8;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci   case GL_RGBA16_SNORM:
146bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_SNORM16;
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci   case GL_RGBA8_SNORM:
149bf215546Sopenharmony_ci      return MESA_FORMAT_RGBA_SNORM8;
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci   case GL_RG16_SNORM:
152bf215546Sopenharmony_ci      return MESA_FORMAT_RG_SNORM16;
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci   case GL_RG8_SNORM:
155bf215546Sopenharmony_ci      return MESA_FORMAT_RG_SNORM8;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci   case GL_R16_SNORM:
158bf215546Sopenharmony_ci      return MESA_FORMAT_R_SNORM16;
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ci   case GL_R8_SNORM:
161bf215546Sopenharmony_ci      return MESA_FORMAT_R_SNORM8;
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci   default:
164bf215546Sopenharmony_ci      return MESA_FORMAT_NONE;
165bf215546Sopenharmony_ci   }
166bf215546Sopenharmony_ci}
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_cienum image_format_class
169bf215546Sopenharmony_ci{
170bf215546Sopenharmony_ci   /** Not a valid image format. */
171bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_NONE = 0,
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci   /** Classes of image formats you can cast into each other. */
174bf215546Sopenharmony_ci   /** \{ */
175bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_1X8,
176bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_1X16,
177bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_1X32,
178bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_2X8,
179bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_2X16,
180bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_2X32,
181bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_10_11_11,
182bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_4X8,
183bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_4X16,
184bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_4X32,
185bf215546Sopenharmony_ci   IMAGE_FORMAT_CLASS_2_10_10_10
186bf215546Sopenharmony_ci   /** \} */
187bf215546Sopenharmony_ci};
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_cistatic enum image_format_class
190bf215546Sopenharmony_ciget_image_format_class(mesa_format format)
191bf215546Sopenharmony_ci{
192bf215546Sopenharmony_ci   switch (format) {
193bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_FLOAT32:
194bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X32;
195bf215546Sopenharmony_ci
196bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_FLOAT16:
197bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X16;
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci   case MESA_FORMAT_RG_FLOAT32:
200bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X32;
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   case MESA_FORMAT_RG_FLOAT16:
203bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X16;
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   case MESA_FORMAT_R11G11B10_FLOAT:
206bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_10_11_11;
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   case MESA_FORMAT_R_FLOAT32:
209bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X32;
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_ci   case MESA_FORMAT_R_FLOAT16:
212bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X16;
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_UINT32:
215bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X32;
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_UINT16:
218bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X16;
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci   case MESA_FORMAT_R10G10B10A2_UINT:
221bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2_10_10_10;
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_UINT8:
224bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X8;
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   case MESA_FORMAT_RG_UINT32:
227bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X32;
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci   case MESA_FORMAT_RG_UINT16:
230bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X16;
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci   case MESA_FORMAT_RG_UINT8:
233bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X8;
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci   case MESA_FORMAT_R_UINT32:
236bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X32;
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci   case MESA_FORMAT_R_UINT16:
239bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X16;
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci   case MESA_FORMAT_R_UINT8:
242bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X8;
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_SINT32:
245bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X32;
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_SINT16:
248bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X16;
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_SINT8:
251bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X8;
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci   case MESA_FORMAT_RG_SINT32:
254bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X32;
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   case MESA_FORMAT_RG_SINT16:
257bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X16;
258bf215546Sopenharmony_ci
259bf215546Sopenharmony_ci   case MESA_FORMAT_RG_SINT8:
260bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X8;
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci   case MESA_FORMAT_R_SINT32:
263bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X32;
264bf215546Sopenharmony_ci
265bf215546Sopenharmony_ci   case MESA_FORMAT_R_SINT16:
266bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X16;
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ci   case MESA_FORMAT_R_SINT8:
269bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X8;
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_UNORM16:
272bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X16;
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci   case MESA_FORMAT_R10G10B10A2_UNORM:
275bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2_10_10_10;
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_UNORM8:
278bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X8;
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   case MESA_FORMAT_RG_UNORM16:
281bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X16;
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci   case MESA_FORMAT_RG_UNORM8:
284bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X8;
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_ci   case MESA_FORMAT_R_UNORM16:
287bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X16;
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   case MESA_FORMAT_R_UNORM8:
290bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X8;
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_SNORM16:
293bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X16;
294bf215546Sopenharmony_ci
295bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_SNORM8:
296bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_4X8;
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_ci   case MESA_FORMAT_RG_SNORM16:
299bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X16;
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci   case MESA_FORMAT_RG_SNORM8:
302bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_2X8;
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci   case MESA_FORMAT_R_SNORM16:
305bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X16;
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ci   case MESA_FORMAT_R_SNORM8:
308bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_1X8;
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci   default:
311bf215546Sopenharmony_ci      return IMAGE_FORMAT_CLASS_NONE;
312bf215546Sopenharmony_ci   }
313bf215546Sopenharmony_ci}
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_cistatic GLenum
316bf215546Sopenharmony_ci_image_format_class_to_glenum(enum image_format_class class)
317bf215546Sopenharmony_ci{
318bf215546Sopenharmony_ci   switch (class) {
319bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_NONE:
320bf215546Sopenharmony_ci      return GL_NONE;
321bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_1X8:
322bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_1_X_8;
323bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_1X16:
324bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_1_X_16;
325bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_1X32:
326bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_1_X_32;
327bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_2X8:
328bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_2_X_8;
329bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_2X16:
330bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_2_X_16;
331bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_2X32:
332bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_2_X_32;
333bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_10_11_11:
334bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_11_11_10;
335bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_4X8:
336bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_4_X_8;
337bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_4X16:
338bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_4_X_16;
339bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_4X32:
340bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_4_X_32;
341bf215546Sopenharmony_ci   case IMAGE_FORMAT_CLASS_2_10_10_10:
342bf215546Sopenharmony_ci      return GL_IMAGE_CLASS_10_10_10_2;
343bf215546Sopenharmony_ci   default:
344bf215546Sopenharmony_ci      assert(!"Invalid image_format_class");
345bf215546Sopenharmony_ci      return GL_NONE;
346bf215546Sopenharmony_ci   }
347bf215546Sopenharmony_ci}
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ciGLenum
350bf215546Sopenharmony_ci_mesa_get_image_format_class(GLenum format)
351bf215546Sopenharmony_ci{
352bf215546Sopenharmony_ci   mesa_format tex_format = _mesa_get_shader_image_format(format);
353bf215546Sopenharmony_ci   if (tex_format == MESA_FORMAT_NONE)
354bf215546Sopenharmony_ci      return GL_NONE;
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ci   enum image_format_class class = get_image_format_class(tex_format);
357bf215546Sopenharmony_ci   return _image_format_class_to_glenum(class);
358bf215546Sopenharmony_ci}
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_cibool
361bf215546Sopenharmony_ci_mesa_is_shader_image_format_supported(const struct gl_context *ctx,
362bf215546Sopenharmony_ci                                       GLenum format)
363bf215546Sopenharmony_ci{
364bf215546Sopenharmony_ci   switch (format) {
365bf215546Sopenharmony_ci   /* Formats supported on both desktop and ES GL, c.f. table 8.27 of the
366bf215546Sopenharmony_ci    * OpenGL ES 3.1 specification.
367bf215546Sopenharmony_ci    */
368bf215546Sopenharmony_ci   case GL_RGBA32F:
369bf215546Sopenharmony_ci   case GL_RGBA16F:
370bf215546Sopenharmony_ci   case GL_R32F:
371bf215546Sopenharmony_ci   case GL_RGBA32UI:
372bf215546Sopenharmony_ci   case GL_RGBA16UI:
373bf215546Sopenharmony_ci   case GL_RGBA8UI:
374bf215546Sopenharmony_ci   case GL_R32UI:
375bf215546Sopenharmony_ci   case GL_RGBA32I:
376bf215546Sopenharmony_ci   case GL_RGBA16I:
377bf215546Sopenharmony_ci   case GL_RGBA8I:
378bf215546Sopenharmony_ci   case GL_R32I:
379bf215546Sopenharmony_ci   case GL_RGBA8:
380bf215546Sopenharmony_ci   case GL_RGBA8_SNORM:
381bf215546Sopenharmony_ci      return true;
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci   /* Formats supported on unextended desktop GL and the original
384bf215546Sopenharmony_ci    * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2
385bf215546Sopenharmony_ci    * specification or by GLES 3.1 with GL_NV_image_formats extension.
386bf215546Sopenharmony_ci    */
387bf215546Sopenharmony_ci   case GL_RG32F:
388bf215546Sopenharmony_ci   case GL_RG16F:
389bf215546Sopenharmony_ci   case GL_R11F_G11F_B10F:
390bf215546Sopenharmony_ci   case GL_R16F:
391bf215546Sopenharmony_ci   case GL_RGB10_A2UI:
392bf215546Sopenharmony_ci   case GL_RG32UI:
393bf215546Sopenharmony_ci   case GL_RG16UI:
394bf215546Sopenharmony_ci   case GL_RG8UI:
395bf215546Sopenharmony_ci   case GL_R16UI:
396bf215546Sopenharmony_ci   case GL_R8UI:
397bf215546Sopenharmony_ci   case GL_RG32I:
398bf215546Sopenharmony_ci   case GL_RG16I:
399bf215546Sopenharmony_ci   case GL_RG8I:
400bf215546Sopenharmony_ci   case GL_R16I:
401bf215546Sopenharmony_ci   case GL_R8I:
402bf215546Sopenharmony_ci   case GL_RGB10_A2:
403bf215546Sopenharmony_ci   case GL_RG8:
404bf215546Sopenharmony_ci   case GL_R8:
405bf215546Sopenharmony_ci   case GL_RG8_SNORM:
406bf215546Sopenharmony_ci   case GL_R8_SNORM:
407bf215546Sopenharmony_ci      return true;
408bf215546Sopenharmony_ci
409bf215546Sopenharmony_ci   /* Formats supported on unextended desktop GL and the original
410bf215546Sopenharmony_ci    * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2
411bf215546Sopenharmony_ci    * specification.
412bf215546Sopenharmony_ci    *
413bf215546Sopenharmony_ci    * Following formats are supported by GLES 3.1 with GL_NV_image_formats &
414bf215546Sopenharmony_ci    * GL_EXT_texture_norm16 extensions.
415bf215546Sopenharmony_ci    */
416bf215546Sopenharmony_ci   case GL_RGBA16:
417bf215546Sopenharmony_ci   case GL_RGBA16_SNORM:
418bf215546Sopenharmony_ci   case GL_RG16:
419bf215546Sopenharmony_ci   case GL_RG16_SNORM:
420bf215546Sopenharmony_ci   case GL_R16:
421bf215546Sopenharmony_ci   case GL_R16_SNORM:
422bf215546Sopenharmony_ci      return _mesa_is_desktop_gl(ctx) || _mesa_has_EXT_texture_norm16(ctx);
423bf215546Sopenharmony_ci
424bf215546Sopenharmony_ci   default:
425bf215546Sopenharmony_ci      return false;
426bf215546Sopenharmony_ci   }
427bf215546Sopenharmony_ci}
428bf215546Sopenharmony_ci
429bf215546Sopenharmony_cistruct gl_image_unit
430bf215546Sopenharmony_ci_mesa_default_image_unit(struct gl_context *ctx)
431bf215546Sopenharmony_ci{
432bf215546Sopenharmony_ci   const GLenum format = _mesa_is_desktop_gl(ctx) ? GL_R8 : GL_R32UI;
433bf215546Sopenharmony_ci   const struct gl_image_unit u = {
434bf215546Sopenharmony_ci      .Access = GL_READ_ONLY,
435bf215546Sopenharmony_ci      .Format = format,
436bf215546Sopenharmony_ci      ._ActualFormat = _mesa_get_shader_image_format(format)
437bf215546Sopenharmony_ci   };
438bf215546Sopenharmony_ci   return u;
439bf215546Sopenharmony_ci}
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_civoid
442bf215546Sopenharmony_ci_mesa_init_image_units(struct gl_context *ctx)
443bf215546Sopenharmony_ci{
444bf215546Sopenharmony_ci   unsigned i;
445bf215546Sopenharmony_ci
446bf215546Sopenharmony_ci   ASSERT_BITFIELD_SIZE(struct gl_image_unit, Format, MESA_FORMAT_COUNT);
447bf215546Sopenharmony_ci
448bf215546Sopenharmony_ci   for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i)
449bf215546Sopenharmony_ci      ctx->ImageUnits[i] = _mesa_default_image_unit(ctx);
450bf215546Sopenharmony_ci}
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci
453bf215546Sopenharmony_civoid
454bf215546Sopenharmony_ci_mesa_free_image_textures(struct gl_context *ctx)
455bf215546Sopenharmony_ci{
456bf215546Sopenharmony_ci   unsigned i;
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci   for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i)
459bf215546Sopenharmony_ci      _mesa_reference_texobj(&ctx->ImageUnits[i].TexObj, NULL);
460bf215546Sopenharmony_ci}
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ciGLboolean
463bf215546Sopenharmony_ci_mesa_is_image_unit_valid(struct gl_context *ctx, struct gl_image_unit *u)
464bf215546Sopenharmony_ci{
465bf215546Sopenharmony_ci   struct gl_texture_object *t = u->TexObj;
466bf215546Sopenharmony_ci   mesa_format tex_format;
467bf215546Sopenharmony_ci
468bf215546Sopenharmony_ci   if (!t)
469bf215546Sopenharmony_ci      return GL_FALSE;
470bf215546Sopenharmony_ci
471bf215546Sopenharmony_ci   if (!t->_BaseComplete && !t->_MipmapComplete)
472bf215546Sopenharmony_ci       _mesa_test_texobj_completeness(ctx, t);
473bf215546Sopenharmony_ci
474bf215546Sopenharmony_ci   if (u->Level < t->Attrib.BaseLevel ||
475bf215546Sopenharmony_ci       u->Level > t->_MaxLevel ||
476bf215546Sopenharmony_ci       (u->Level == t->Attrib.BaseLevel && !t->_BaseComplete) ||
477bf215546Sopenharmony_ci       (u->Level != t->Attrib.BaseLevel && !t->_MipmapComplete))
478bf215546Sopenharmony_ci      return GL_FALSE;
479bf215546Sopenharmony_ci
480bf215546Sopenharmony_ci   if (_mesa_tex_target_is_layered(t->Target) &&
481bf215546Sopenharmony_ci       u->_Layer >= _mesa_get_texture_layers(t, u->Level))
482bf215546Sopenharmony_ci      return GL_FALSE;
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci   if (t->Target == GL_TEXTURE_BUFFER) {
485bf215546Sopenharmony_ci      tex_format = _mesa_get_shader_image_format(t->BufferObjectFormat);
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_ci   } else {
488bf215546Sopenharmony_ci      struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ?
489bf215546Sopenharmony_ci                                      t->Image[u->_Layer][u->Level] :
490bf215546Sopenharmony_ci                                      t->Image[0][u->Level]);
491bf215546Sopenharmony_ci
492bf215546Sopenharmony_ci      if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples)
493bf215546Sopenharmony_ci         return GL_FALSE;
494bf215546Sopenharmony_ci
495bf215546Sopenharmony_ci      tex_format = _mesa_get_shader_image_format(img->InternalFormat);
496bf215546Sopenharmony_ci   }
497bf215546Sopenharmony_ci
498bf215546Sopenharmony_ci   if (!tex_format)
499bf215546Sopenharmony_ci      return GL_FALSE;
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ci   switch (t->Attrib.ImageFormatCompatibilityType) {
502bf215546Sopenharmony_ci   case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE:
503bf215546Sopenharmony_ci      if (_mesa_get_format_bytes(tex_format) !=
504bf215546Sopenharmony_ci          _mesa_get_format_bytes(u->_ActualFormat))
505bf215546Sopenharmony_ci         return GL_FALSE;
506bf215546Sopenharmony_ci      break;
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci   case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS:
509bf215546Sopenharmony_ci      if (get_image_format_class(tex_format) !=
510bf215546Sopenharmony_ci          get_image_format_class(u->_ActualFormat))
511bf215546Sopenharmony_ci         return GL_FALSE;
512bf215546Sopenharmony_ci      break;
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_ci   default:
515bf215546Sopenharmony_ci      assert(!"Unexpected image format compatibility type");
516bf215546Sopenharmony_ci   }
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_ci   return GL_TRUE;
519bf215546Sopenharmony_ci}
520bf215546Sopenharmony_ci
521bf215546Sopenharmony_cistatic GLboolean
522bf215546Sopenharmony_civalidate_bind_image_texture(struct gl_context *ctx, GLuint unit,
523bf215546Sopenharmony_ci                            GLuint texture, GLint level, GLint layer,
524bf215546Sopenharmony_ci                            GLenum access, GLenum format, bool check_level_layer)
525bf215546Sopenharmony_ci{
526bf215546Sopenharmony_ci   assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);
527bf215546Sopenharmony_ci
528bf215546Sopenharmony_ci   if (unit >= ctx->Const.MaxImageUnits) {
529bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)");
530bf215546Sopenharmony_ci      return GL_FALSE;
531bf215546Sopenharmony_ci   }
532bf215546Sopenharmony_ci
533bf215546Sopenharmony_ci   if (check_level_layer) {
534bf215546Sopenharmony_ci      /* EXT_shader_image_load_store doesn't throw an error if level or
535bf215546Sopenharmony_ci       * layer is negative.
536bf215546Sopenharmony_ci       */
537bf215546Sopenharmony_ci      if (level < 0) {
538bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)");
539bf215546Sopenharmony_ci         return GL_FALSE;
540bf215546Sopenharmony_ci      }
541bf215546Sopenharmony_ci
542bf215546Sopenharmony_ci         if (layer < 0) {
543bf215546Sopenharmony_ci            _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)");
544bf215546Sopenharmony_ci            return GL_FALSE;
545bf215546Sopenharmony_ci      }
546bf215546Sopenharmony_ci   }
547bf215546Sopenharmony_ci
548bf215546Sopenharmony_ci   if (access != GL_READ_ONLY &&
549bf215546Sopenharmony_ci       access != GL_WRITE_ONLY &&
550bf215546Sopenharmony_ci       access != GL_READ_WRITE) {
551bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)");
552bf215546Sopenharmony_ci      return GL_FALSE;
553bf215546Sopenharmony_ci   }
554bf215546Sopenharmony_ci
555bf215546Sopenharmony_ci   if (!_mesa_is_shader_image_format_supported(ctx, format)) {
556bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)");
557bf215546Sopenharmony_ci      return GL_FALSE;
558bf215546Sopenharmony_ci   }
559bf215546Sopenharmony_ci
560bf215546Sopenharmony_ci   return GL_TRUE;
561bf215546Sopenharmony_ci}
562bf215546Sopenharmony_ci
563bf215546Sopenharmony_cistatic void
564bf215546Sopenharmony_ciset_image_binding(struct gl_image_unit *u, struct gl_texture_object *texObj,
565bf215546Sopenharmony_ci                  GLint level, GLboolean layered, GLint layer, GLenum access,
566bf215546Sopenharmony_ci                  GLenum format)
567bf215546Sopenharmony_ci{
568bf215546Sopenharmony_ci   u->Level = level;
569bf215546Sopenharmony_ci   u->Access = access;
570bf215546Sopenharmony_ci   u->Format = format;
571bf215546Sopenharmony_ci   u->_ActualFormat = _mesa_get_shader_image_format(format);
572bf215546Sopenharmony_ci
573bf215546Sopenharmony_ci   if (texObj && _mesa_tex_target_is_layered(texObj->Target)) {
574bf215546Sopenharmony_ci      u->Layered = layered;
575bf215546Sopenharmony_ci      u->Layer = layer;
576bf215546Sopenharmony_ci   } else {
577bf215546Sopenharmony_ci      u->Layered = GL_FALSE;
578bf215546Sopenharmony_ci      u->Layer = 0;
579bf215546Sopenharmony_ci   }
580bf215546Sopenharmony_ci   u->_Layer = (u->Layered ? 0 : u->Layer);
581bf215546Sopenharmony_ci
582bf215546Sopenharmony_ci   _mesa_reference_texobj(&u->TexObj, texObj);
583bf215546Sopenharmony_ci}
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_cistatic void
586bf215546Sopenharmony_cibind_image_texture(struct gl_context *ctx, struct gl_texture_object *texObj,
587bf215546Sopenharmony_ci                   GLuint unit, GLint level, GLboolean layered, GLint layer,
588bf215546Sopenharmony_ci                   GLenum access, GLenum format)
589bf215546Sopenharmony_ci{
590bf215546Sopenharmony_ci   struct gl_image_unit *u;
591bf215546Sopenharmony_ci
592bf215546Sopenharmony_ci   u = &ctx->ImageUnits[unit];
593bf215546Sopenharmony_ci
594bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, 0, 0);
595bf215546Sopenharmony_ci   ctx->NewDriverState |= ST_NEW_IMAGE_UNITS;
596bf215546Sopenharmony_ci
597bf215546Sopenharmony_ci   set_image_binding(u, texObj, level, layered, layer, access, format);
598bf215546Sopenharmony_ci}
599bf215546Sopenharmony_ci
600bf215546Sopenharmony_civoid GLAPIENTRY
601bf215546Sopenharmony_ci_mesa_BindImageTexture_no_error(GLuint unit, GLuint texture, GLint level,
602bf215546Sopenharmony_ci                                GLboolean layered, GLint layer, GLenum access,
603bf215546Sopenharmony_ci                                GLenum format)
604bf215546Sopenharmony_ci{
605bf215546Sopenharmony_ci   struct gl_texture_object *texObj = NULL;
606bf215546Sopenharmony_ci
607bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
608bf215546Sopenharmony_ci
609bf215546Sopenharmony_ci   if (texture)
610bf215546Sopenharmony_ci      texObj = _mesa_lookup_texture(ctx, texture);
611bf215546Sopenharmony_ci
612bf215546Sopenharmony_ci   bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format);
613bf215546Sopenharmony_ci}
614bf215546Sopenharmony_ci
615bf215546Sopenharmony_civoid GLAPIENTRY
616bf215546Sopenharmony_ci_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
617bf215546Sopenharmony_ci                       GLboolean layered, GLint layer, GLenum access,
618bf215546Sopenharmony_ci                       GLenum format)
619bf215546Sopenharmony_ci{
620bf215546Sopenharmony_ci   struct gl_texture_object *texObj = NULL;
621bf215546Sopenharmony_ci
622bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
623bf215546Sopenharmony_ci
624bf215546Sopenharmony_ci   if (!validate_bind_image_texture(ctx, unit, texture, level, layer, access,
625bf215546Sopenharmony_ci                                    format, true))
626bf215546Sopenharmony_ci      return;
627bf215546Sopenharmony_ci
628bf215546Sopenharmony_ci   if (texture) {
629bf215546Sopenharmony_ci      texObj = _mesa_lookup_texture(ctx, texture);
630bf215546Sopenharmony_ci
631bf215546Sopenharmony_ci      if (!texObj) {
632bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)");
633bf215546Sopenharmony_ci         return;
634bf215546Sopenharmony_ci      }
635bf215546Sopenharmony_ci
636bf215546Sopenharmony_ci      /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES
637bf215546Sopenharmony_ci       * 3.1 spec:
638bf215546Sopenharmony_ci       *
639bf215546Sopenharmony_ci       * "An INVALID_OPERATION error is generated if texture is not the name
640bf215546Sopenharmony_ci       *  of an immutable texture object."
641bf215546Sopenharmony_ci       *
642bf215546Sopenharmony_ci       * However note that issue 7 of the GL_OES_texture_buffer spec
643bf215546Sopenharmony_ci       * recognizes that there is no way to create immutable buffer textures,
644bf215546Sopenharmony_ci       * so those are excluded from this requirement.
645bf215546Sopenharmony_ci       *
646bf215546Sopenharmony_ci       * Additionally, issue 10 of the OES_EGL_image_external_essl3 spec
647bf215546Sopenharmony_ci       * states that glBindImageTexture must accept external texture objects.
648bf215546Sopenharmony_ci       */
649bf215546Sopenharmony_ci      if (_mesa_is_gles(ctx) && !texObj->Immutable && !texObj->External &&
650bf215546Sopenharmony_ci          texObj->Target != GL_TEXTURE_BUFFER) {
651bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_OPERATION,
652bf215546Sopenharmony_ci                     "glBindImageTexture(!immutable)");
653bf215546Sopenharmony_ci         return;
654bf215546Sopenharmony_ci      }
655bf215546Sopenharmony_ci   }
656bf215546Sopenharmony_ci
657bf215546Sopenharmony_ci   bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format);
658bf215546Sopenharmony_ci}
659bf215546Sopenharmony_ci
660bf215546Sopenharmony_civoid GLAPIENTRY
661bf215546Sopenharmony_ci_mesa_BindImageTextureEXT(GLuint index, GLuint texture, GLint level,
662bf215546Sopenharmony_ci                          GLboolean layered, GLint layer, GLenum access,
663bf215546Sopenharmony_ci                          GLint format)
664bf215546Sopenharmony_ci{
665bf215546Sopenharmony_ci   struct gl_texture_object *texObj = NULL;
666bf215546Sopenharmony_ci
667bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
668bf215546Sopenharmony_ci
669bf215546Sopenharmony_ci   if (!validate_bind_image_texture(ctx, index, texture, level, layer, access,
670bf215546Sopenharmony_ci                                    format, false))
671bf215546Sopenharmony_ci      return;
672bf215546Sopenharmony_ci
673bf215546Sopenharmony_ci   if (texture) {
674bf215546Sopenharmony_ci      texObj = _mesa_lookup_texture(ctx, texture);
675bf215546Sopenharmony_ci
676bf215546Sopenharmony_ci      if (!texObj) {
677bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTextureEXT(texture)");
678bf215546Sopenharmony_ci         return;
679bf215546Sopenharmony_ci      }
680bf215546Sopenharmony_ci   }
681bf215546Sopenharmony_ci
682bf215546Sopenharmony_ci   bind_image_texture(ctx, texObj, index, level, layered, layer, access, format);
683bf215546Sopenharmony_ci}
684bf215546Sopenharmony_ci
685bf215546Sopenharmony_cistatic ALWAYS_INLINE void
686bf215546Sopenharmony_cibind_image_textures(struct gl_context *ctx, GLuint first, GLuint count,
687bf215546Sopenharmony_ci                    const GLuint *textures, bool no_error)
688bf215546Sopenharmony_ci{
689bf215546Sopenharmony_ci   int i;
690bf215546Sopenharmony_ci
691bf215546Sopenharmony_ci   /* Assume that at least one binding will be changed */
692bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, 0, 0);
693bf215546Sopenharmony_ci   ctx->NewDriverState |= ST_NEW_IMAGE_UNITS;
694bf215546Sopenharmony_ci
695bf215546Sopenharmony_ci   /* Note that the error semantics for multi-bind commands differ from
696bf215546Sopenharmony_ci    * those of other GL commands.
697bf215546Sopenharmony_ci    *
698bf215546Sopenharmony_ci    * The Issues section in the ARB_multi_bind spec says:
699bf215546Sopenharmony_ci    *
700bf215546Sopenharmony_ci    *    "(11) Typically, OpenGL specifies that if an error is generated by
701bf215546Sopenharmony_ci    *          a command, that command has no effect.  This is somewhat
702bf215546Sopenharmony_ci    *          unfortunate for multi-bind commands, because it would require
703bf215546Sopenharmony_ci    *          a first pass to scan the entire list of bound objects for
704bf215546Sopenharmony_ci    *          errors and then a second pass to actually perform the
705bf215546Sopenharmony_ci    *          bindings.  Should we have different error semantics?
706bf215546Sopenharmony_ci    *
707bf215546Sopenharmony_ci    *       RESOLVED:  Yes.  In this specification, when the parameters for
708bf215546Sopenharmony_ci    *       one of the <count> binding points are invalid, that binding
709bf215546Sopenharmony_ci    *       point is not updated and an error will be generated.  However,
710bf215546Sopenharmony_ci    *       other binding points in the same command will be updated if
711bf215546Sopenharmony_ci    *       their parameters are valid and no other error occurs."
712bf215546Sopenharmony_ci    */
713bf215546Sopenharmony_ci
714bf215546Sopenharmony_ci   _mesa_HashLockMutex(ctx->Shared->TexObjects);
715bf215546Sopenharmony_ci
716bf215546Sopenharmony_ci   for (i = 0; i < count; i++) {
717bf215546Sopenharmony_ci      struct gl_image_unit *u = &ctx->ImageUnits[first + i];
718bf215546Sopenharmony_ci      const GLuint texture = textures ? textures[i] : 0;
719bf215546Sopenharmony_ci
720bf215546Sopenharmony_ci      if (texture) {
721bf215546Sopenharmony_ci         struct gl_texture_object *texObj = u->TexObj;
722bf215546Sopenharmony_ci         GLenum tex_format;
723bf215546Sopenharmony_ci
724bf215546Sopenharmony_ci         if (!texObj || texObj->Name != texture) {
725bf215546Sopenharmony_ci            texObj = _mesa_lookup_texture_locked(ctx, texture);
726bf215546Sopenharmony_ci            if (!no_error && !texObj) {
727bf215546Sopenharmony_ci               /* The ARB_multi_bind spec says:
728bf215546Sopenharmony_ci                *
729bf215546Sopenharmony_ci                *    "An INVALID_OPERATION error is generated if any value
730bf215546Sopenharmony_ci                *     in <textures> is not zero or the name of an existing
731bf215546Sopenharmony_ci                *     texture object (per binding)."
732bf215546Sopenharmony_ci                */
733bf215546Sopenharmony_ci               _mesa_error(ctx, GL_INVALID_OPERATION,
734bf215546Sopenharmony_ci                           "glBindImageTextures(textures[%d]=%u "
735bf215546Sopenharmony_ci                           "is not zero or the name of an existing texture "
736bf215546Sopenharmony_ci                           "object)", i, texture);
737bf215546Sopenharmony_ci               continue;
738bf215546Sopenharmony_ci            }
739bf215546Sopenharmony_ci         }
740bf215546Sopenharmony_ci
741bf215546Sopenharmony_ci         if (texObj->Target == GL_TEXTURE_BUFFER) {
742bf215546Sopenharmony_ci            tex_format = texObj->BufferObjectFormat;
743bf215546Sopenharmony_ci         } else {
744bf215546Sopenharmony_ci            struct gl_texture_image *image = texObj->Image[0][0];
745bf215546Sopenharmony_ci
746bf215546Sopenharmony_ci            if (!no_error && (!image || image->Width == 0 ||
747bf215546Sopenharmony_ci                              image->Height == 0 || image->Depth == 0)) {
748bf215546Sopenharmony_ci               /* The ARB_multi_bind spec says:
749bf215546Sopenharmony_ci                *
750bf215546Sopenharmony_ci                *    "An INVALID_OPERATION error is generated if the width,
751bf215546Sopenharmony_ci                *     height, or depth of the level zero texture image of
752bf215546Sopenharmony_ci                *     any texture in <textures> is zero (per binding)."
753bf215546Sopenharmony_ci                */
754bf215546Sopenharmony_ci               _mesa_error(ctx, GL_INVALID_OPERATION,
755bf215546Sopenharmony_ci                           "glBindImageTextures(the width, height or depth "
756bf215546Sopenharmony_ci                           "of the level zero texture image of "
757bf215546Sopenharmony_ci                           "textures[%d]=%u is zero)", i, texture);
758bf215546Sopenharmony_ci               continue;
759bf215546Sopenharmony_ci            }
760bf215546Sopenharmony_ci
761bf215546Sopenharmony_ci            tex_format = image->InternalFormat;
762bf215546Sopenharmony_ci         }
763bf215546Sopenharmony_ci
764bf215546Sopenharmony_ci         if (!no_error &&
765bf215546Sopenharmony_ci             !_mesa_is_shader_image_format_supported(ctx, tex_format)) {
766bf215546Sopenharmony_ci            /* The ARB_multi_bind spec says:
767bf215546Sopenharmony_ci             *
768bf215546Sopenharmony_ci             *   "An INVALID_OPERATION error is generated if the internal
769bf215546Sopenharmony_ci             *    format of the level zero texture image of any texture
770bf215546Sopenharmony_ci             *    in <textures> is not found in table 8.33 (per binding)."
771bf215546Sopenharmony_ci             */
772bf215546Sopenharmony_ci            _mesa_error(ctx, GL_INVALID_OPERATION,
773bf215546Sopenharmony_ci                        "glBindImageTextures(the internal format %s of "
774bf215546Sopenharmony_ci                        "the level zero texture image of textures[%d]=%u "
775bf215546Sopenharmony_ci                        "is not supported)",
776bf215546Sopenharmony_ci                        _mesa_enum_to_string(tex_format),
777bf215546Sopenharmony_ci                        i, texture);
778bf215546Sopenharmony_ci            continue;
779bf215546Sopenharmony_ci         }
780bf215546Sopenharmony_ci
781bf215546Sopenharmony_ci         /* Update the texture binding */
782bf215546Sopenharmony_ci         set_image_binding(u, texObj, 0,
783bf215546Sopenharmony_ci                           _mesa_tex_target_is_layered(texObj->Target),
784bf215546Sopenharmony_ci                           0, GL_READ_WRITE, tex_format);
785bf215546Sopenharmony_ci      } else {
786bf215546Sopenharmony_ci         /* Unbind the texture from the unit */
787bf215546Sopenharmony_ci         set_image_binding(u, NULL, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8);
788bf215546Sopenharmony_ci      }
789bf215546Sopenharmony_ci   }
790bf215546Sopenharmony_ci
791bf215546Sopenharmony_ci   _mesa_HashUnlockMutex(ctx->Shared->TexObjects);
792bf215546Sopenharmony_ci}
793bf215546Sopenharmony_ci
794bf215546Sopenharmony_civoid GLAPIENTRY
795bf215546Sopenharmony_ci_mesa_BindImageTextures_no_error(GLuint first, GLsizei count,
796bf215546Sopenharmony_ci                                 const GLuint *textures)
797bf215546Sopenharmony_ci{
798bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
799bf215546Sopenharmony_ci
800bf215546Sopenharmony_ci   bind_image_textures(ctx, first, count, textures, true);
801bf215546Sopenharmony_ci}
802bf215546Sopenharmony_ci
803bf215546Sopenharmony_civoid GLAPIENTRY
804bf215546Sopenharmony_ci_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
805bf215546Sopenharmony_ci{
806bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
807bf215546Sopenharmony_ci
808bf215546Sopenharmony_ci   if (!ctx->Extensions.ARB_shader_image_load_store &&
809bf215546Sopenharmony_ci       !_mesa_is_gles31(ctx)) {
810bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()");
811bf215546Sopenharmony_ci      return;
812bf215546Sopenharmony_ci   }
813bf215546Sopenharmony_ci
814bf215546Sopenharmony_ci   if (first + count > ctx->Const.MaxImageUnits) {
815bf215546Sopenharmony_ci      /* The ARB_multi_bind spec says:
816bf215546Sopenharmony_ci       *
817bf215546Sopenharmony_ci       *    "An INVALID_OPERATION error is generated if <first> + <count>
818bf215546Sopenharmony_ci       *     is greater than the number of image units supported by
819bf215546Sopenharmony_ci       *     the implementation."
820bf215546Sopenharmony_ci       */
821bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION,
822bf215546Sopenharmony_ci                  "glBindImageTextures(first=%u + count=%d > the value of "
823bf215546Sopenharmony_ci                  "GL_MAX_IMAGE_UNITS=%u)",
824bf215546Sopenharmony_ci                  first, count, ctx->Const.MaxImageUnits);
825bf215546Sopenharmony_ci      return;
826bf215546Sopenharmony_ci   }
827bf215546Sopenharmony_ci
828bf215546Sopenharmony_ci   bind_image_textures(ctx, first, count, textures, false);
829bf215546Sopenharmony_ci}
830