shaderimage.c revision 848b8605
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 "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 61static mesa_format 62get_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 187enum 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 208static enum image_format_class 209get_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 334static GLboolean 335validate_image_unit(struct gl_context *ctx, struct gl_image_unit *u) 336{ 337 struct gl_texture_object *t = u->TexObj; 338 struct gl_texture_image *img; 339 340 if (!t || u->Level < t->BaseLevel || 341 u->Level > t->_MaxLevel) 342 return GL_FALSE; 343 344 _mesa_test_texobj_completeness(ctx, t); 345 346 if ((u->Level == t->BaseLevel && !t->_BaseComplete) || 347 (u->Level != t->BaseLevel && !t->_MipmapComplete)) 348 return GL_FALSE; 349 350 if (_mesa_tex_target_is_layered(t->Target) && 351 u->Layer >= _mesa_get_texture_layers(t, u->Level)) 352 return GL_FALSE; 353 354 if (t->Target == GL_TEXTURE_CUBE_MAP) 355 img = t->Image[u->Layer][u->Level]; 356 else 357 img = t->Image[0][u->Level]; 358 359 if (!img || img->Border || 360 get_image_format_class(img->TexFormat) == IMAGE_FORMAT_CLASS_NONE || 361 img->NumSamples > ctx->Const.MaxImageSamples) 362 return GL_FALSE; 363 364 switch (t->ImageFormatCompatibilityType) { 365 case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE: 366 if (_mesa_get_format_bytes(img->TexFormat) != 367 _mesa_get_format_bytes(u->_ActualFormat)) 368 return GL_FALSE; 369 break; 370 371 case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS: 372 if (get_image_format_class(img->TexFormat) != 373 get_image_format_class(u->_ActualFormat)) 374 return GL_FALSE; 375 break; 376 377 default: 378 assert(!"Unexpected image format compatibility type"); 379 } 380 381 return GL_TRUE; 382} 383 384void 385_mesa_validate_image_units(struct gl_context *ctx) 386{ 387 int i; 388 389 for (i = 0; i < ctx->Const.MaxImageUnits; ++i) { 390 struct gl_image_unit *u = &ctx->ImageUnits[i]; 391 u->_Valid = validate_image_unit(ctx, u); 392 } 393} 394 395static GLboolean 396validate_bind_image_texture(struct gl_context *ctx, GLuint unit, 397 GLuint texture, GLint level, GLboolean layered, 398 GLint layer, GLenum access, GLenum format) 399{ 400 assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); 401 402 if (unit >= ctx->Const.MaxImageUnits) { 403 _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)"); 404 return GL_FALSE; 405 } 406 407 if (level < 0) { 408 _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)"); 409 return GL_FALSE; 410 } 411 412 if (layer < 0) { 413 _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)"); 414 return GL_FALSE; 415 } 416 417 if (access != GL_READ_ONLY && 418 access != GL_WRITE_ONLY && 419 access != GL_READ_WRITE) { 420 _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)"); 421 return GL_FALSE; 422 } 423 424 if (!get_image_format(format)) { 425 _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)"); 426 return GL_FALSE; 427 } 428 429 return GL_TRUE; 430} 431 432void GLAPIENTRY 433_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, 434 GLboolean layered, GLint layer, GLenum access, 435 GLenum format) 436{ 437 GET_CURRENT_CONTEXT(ctx); 438 struct gl_texture_object *t = NULL; 439 struct gl_image_unit *u; 440 441 if (!validate_bind_image_texture(ctx, unit, texture, level, 442 layered, layer, access, format)) 443 return; 444 445 u = &ctx->ImageUnits[unit]; 446 447 FLUSH_VERTICES(ctx, 0); 448 ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 449 450 if (texture) { 451 t = _mesa_lookup_texture(ctx, texture); 452 if (!t) { 453 _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)"); 454 return; 455 } 456 457 _mesa_reference_texobj(&u->TexObj, t); 458 u->Level = level; 459 u->Access = access; 460 u->Format = format; 461 u->_ActualFormat = get_image_format(format); 462 463 if (_mesa_tex_target_is_layered(t->Target)) { 464 u->Layered = layered; 465 u->Layer = (layered ? 0 : layer); 466 } else { 467 u->Layered = GL_FALSE; 468 u->Layer = 0; 469 } 470 471 } else { 472 _mesa_reference_texobj(&u->TexObj, NULL); 473 } 474 475 u->_Valid = validate_image_unit(ctx, u); 476 477 if (ctx->Driver.BindImageTexture) 478 ctx->Driver.BindImageTexture(ctx, u, t, level, layered, 479 layer, access, format); 480} 481 482void GLAPIENTRY 483_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures) 484{ 485 GET_CURRENT_CONTEXT(ctx); 486 int i; 487 488 if (!ctx->Extensions.ARB_shader_image_load_store) { 489 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()"); 490 return; 491 } 492 493 if (first + count > ctx->Const.MaxImageUnits) { 494 /* The ARB_multi_bind spec says: 495 * 496 * "An INVALID_OPERATION error is generated if <first> + <count> 497 * is greater than the number of image units supported by 498 * the implementation." 499 */ 500 _mesa_error(ctx, GL_INVALID_OPERATION, 501 "glBindImageTextures(first=%u + count=%d > the value of " 502 "GL_MAX_IMAGE_UNITS=%u)", 503 first, count, ctx->Const.MaxImageUnits); 504 return; 505 } 506 507 /* Assume that at least one binding will be changed */ 508 FLUSH_VERTICES(ctx, 0); 509 ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 510 511 /* Note that the error semantics for multi-bind commands differ from 512 * those of other GL commands. 513 * 514 * The Issues section in the ARB_multi_bind spec says: 515 * 516 * "(11) Typically, OpenGL specifies that if an error is generated by 517 * a command, that command has no effect. This is somewhat 518 * unfortunate for multi-bind commands, because it would require 519 * a first pass to scan the entire list of bound objects for 520 * errors and then a second pass to actually perform the 521 * bindings. Should we have different error semantics? 522 * 523 * RESOLVED: Yes. In this specification, when the parameters for 524 * one of the <count> binding points are invalid, that binding 525 * point is not updated and an error will be generated. However, 526 * other binding points in the same command will be updated if 527 * their parameters are valid and no other error occurs." 528 */ 529 530 _mesa_begin_texture_lookups(ctx); 531 532 for (i = 0; i < count; i++) { 533 struct gl_image_unit *u = &ctx->ImageUnits[first + i]; 534 const GLuint texture = textures ? textures[i] : 0; 535 536 if (texture != 0) { 537 struct gl_texture_object *texObj; 538 struct gl_texture_image *image; 539 mesa_format actualFormat; 540 541 if (!u->TexObj || u->TexObj->Name != texture) { 542 texObj = _mesa_lookup_texture_locked(ctx, texture); 543 if (!texObj) { 544 /* The ARB_multi_bind spec says: 545 * 546 * "An INVALID_OPERATION error is generated if any value 547 * in <textures> is not zero or the name of an existing 548 * texture object (per binding)." 549 */ 550 _mesa_error(ctx, GL_INVALID_OPERATION, 551 "glBindImageTextures(textures[%d]=%u " 552 "is not zero or the name of an existing texture " 553 "object)", i, texture); 554 continue; 555 } 556 } else { 557 texObj = u->TexObj; 558 } 559 560 image = texObj->Image[0][0]; 561 562 if (!image || image->Width == 0 || image->Height == 0 || image->Depth == 0) { 563 /* The ARB_multi_bind spec says: 564 * 565 * "An INVALID_OPERATION error is generated if the width, 566 * height, or depth of the level zero texture image of 567 * any texture in <textures> is zero (per binding)." 568 */ 569 _mesa_error(ctx, GL_INVALID_OPERATION, 570 "glBindImageTextures(the width, height or depth " 571 "of the level zero texture image of " 572 "textures[%d]=%u is zero)", i, texture); 573 continue; 574 } 575 576 actualFormat = get_image_format(image->InternalFormat); 577 578 if (actualFormat == MESA_FORMAT_NONE) { 579 /* The ARB_multi_bind spec says: 580 * 581 * "An INVALID_OPERATION error is generated if the internal 582 * format of the level zero texture image of any texture 583 * in <textures> is not found in table 8.33 (per binding)." 584 */ 585 _mesa_error(ctx, GL_INVALID_OPERATION, 586 "glBindImageTextures(the internal format %s of " 587 "the level zero texture image of textures[%d]=%u " 588 "is not supported)", 589 _mesa_lookup_enum_by_nr(image->InternalFormat), 590 i, texture); 591 continue; 592 } 593 594 /* Update the texture binding */ 595 _mesa_reference_texobj(&u->TexObj, texObj); 596 u->Level = 0; 597 u->Layered = _mesa_tex_target_is_layered(texObj->Target); 598 u->Layer = 0; 599 u->Access = GL_READ_WRITE; 600 u->Format = image->InternalFormat; 601 u->_ActualFormat = actualFormat; 602 u->_Valid = validate_image_unit(ctx, u); 603 } else { 604 /* Unbind the texture from the unit */ 605 _mesa_reference_texobj(&u->TexObj, NULL); 606 u->Level = 0; 607 u->Layered = GL_FALSE; 608 u->Layer = 0; 609 u->Access = GL_READ_ONLY; 610 u->Format = GL_R8; 611 u->_ActualFormat = MESA_FORMAT_R_UNORM8; 612 u->_Valid = GL_FALSE; 613 } 614 615 /* Pass the BindImageTexture call down to the device driver */ 616 if (ctx->Driver.BindImageTexture) 617 ctx->Driver.BindImageTexture(ctx, u, u->TexObj, u->Level, u->Layered, 618 u->Layer, u->Access, u->Format); 619 } 620 621 _mesa_end_texture_lookups(ctx); 622} 623 624void GLAPIENTRY 625_mesa_MemoryBarrier(GLbitfield barriers) 626{ 627 GET_CURRENT_CONTEXT(ctx); 628 629 if (ctx->Driver.MemoryBarrier) 630 ctx->Driver.MemoryBarrier(ctx, barriers); 631} 632