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