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