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