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