• 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 "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 
42 mesa_format
_mesa_get_shader_image_format(GLenum 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 
168 enum 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 
189 static enum image_format_class
get_image_format_class(mesa_format format)190 get_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 
315 static GLenum
_image_format_class_to_glenum(enum image_format_class class)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 
349 GLenum
_mesa_get_image_format_class(GLenum format)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 
360 bool
_mesa_is_shader_image_format_supported(const struct gl_context * ctx,GLenum format)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 
429 struct gl_image_unit
_mesa_default_image_unit(struct gl_context * ctx)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 
441 void
_mesa_init_image_units(struct gl_context * ctx)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 
453 void
_mesa_free_image_textures(struct gl_context * ctx)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 
462 GLboolean
_mesa_is_image_unit_valid(struct gl_context * ctx,struct gl_image_unit * u)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 
521 static GLboolean
validate_bind_image_texture(struct gl_context * ctx,GLuint unit,GLuint texture,GLint level,GLint layer,GLenum access,GLenum format,bool check_level_layer)522 validate_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 
563 static void
set_image_binding(struct gl_image_unit * u,struct gl_texture_object * texObj,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)564 set_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 
585 static void
bind_image_texture(struct gl_context * ctx,struct gl_texture_object * texObj,GLuint unit,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)586 bind_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 
600 void GLAPIENTRY
_mesa_BindImageTexture_no_error(GLuint unit,GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)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 
615 void GLAPIENTRY
_mesa_BindImageTexture(GLuint unit,GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)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 
660 void GLAPIENTRY
_mesa_BindImageTextureEXT(GLuint index,GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLint format)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 
685 static ALWAYS_INLINE void
bind_image_textures(struct gl_context * ctx,GLuint first,GLuint count,const GLuint * textures,bool no_error)686 bind_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 
794 void GLAPIENTRY
_mesa_BindImageTextures_no_error(GLuint first,GLsizei count,const GLuint * textures)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 
803 void GLAPIENTRY
_mesa_BindImageTextures(GLuint first,GLsizei count,const GLuint * textures)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