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