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