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