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