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