shaderimage.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * Copyright 2013 Intel Corporation 3848b8605Smrg * 4848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5848b8605Smrg * copy of this software and associated documentation files (the "Software"), 6848b8605Smrg * to deal in the Software without restriction, including without limitation 7848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 9848b8605Smrg * Software is furnished to do so, subject to the following conditions: 10848b8605Smrg * 11848b8605Smrg * The above copyright notice and this permission notice (including the next 12848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the 13848b8605Smrg * Software. 14848b8605Smrg * 15848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21848b8605Smrg * DEALINGS IN THE SOFTWARE. 22848b8605Smrg * 23848b8605Smrg * Authors: 24848b8605Smrg * Francisco Jerez <currojerez@riseup.net> 25848b8605Smrg */ 26848b8605Smrg 27848b8605Smrg#include <assert.h> 28848b8605Smrg 29848b8605Smrg#include "shaderimage.h" 30848b8605Smrg#include "mtypes.h" 31848b8605Smrg#include "formats.h" 32848b8605Smrg#include "errors.h" 33848b8605Smrg#include "context.h" 34848b8605Smrg#include "texobj.h" 35848b8605Smrg#include "teximage.h" 36848b8605Smrg#include "enums.h" 37848b8605Smrg 38848b8605Smrg/* 39848b8605Smrg * Define endian-invariant aliases for some mesa formats that are 40848b8605Smrg * defined in terms of their channel layout from LSB to MSB in a 41848b8605Smrg * 32-bit word. The actual byte offsets matter here because the user 42848b8605Smrg * is allowed to bit-cast one format into another and get predictable 43848b8605Smrg * results. 44848b8605Smrg */ 45848b8605Smrg#ifdef MESA_BIG_ENDIAN 46848b8605Smrg# define MESA_FORMAT_RGBA_8 MESA_FORMAT_A8B8G8R8_UNORM 47848b8605Smrg# define MESA_FORMAT_RG_16 MESA_FORMAT_G16R16_UNORM 48848b8605Smrg# define MESA_FORMAT_RG_8 MESA_FORMAT_G8R8_UNORM 49848b8605Smrg# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_A8B8G8R8_SNORM 50848b8605Smrg# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_G16R16_SNORM 51848b8605Smrg# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_G8R8_SNORM 52848b8605Smrg#else 53848b8605Smrg# define MESA_FORMAT_RGBA_8 MESA_FORMAT_R8G8B8A8_UNORM 54848b8605Smrg# define MESA_FORMAT_RG_16 MESA_FORMAT_R16G16_UNORM 55848b8605Smrg# define MESA_FORMAT_RG_8 MESA_FORMAT_R8G8_UNORM 56848b8605Smrg# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_R8G8B8A8_SNORM 57848b8605Smrg# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_R16G16_SNORM 58848b8605Smrg# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_R8G8_SNORM 59848b8605Smrg#endif 60848b8605Smrg 61848b8605Smrgstatic mesa_format 62848b8605Smrgget_image_format(GLenum format) 63848b8605Smrg{ 64848b8605Smrg switch (format) { 65848b8605Smrg case GL_RGBA32F: 66848b8605Smrg return MESA_FORMAT_RGBA_FLOAT32; 67848b8605Smrg 68848b8605Smrg case GL_RGBA16F: 69848b8605Smrg return MESA_FORMAT_RGBA_FLOAT16; 70848b8605Smrg 71848b8605Smrg case GL_RG32F: 72848b8605Smrg return MESA_FORMAT_RG_FLOAT32; 73848b8605Smrg 74848b8605Smrg case GL_RG16F: 75848b8605Smrg return MESA_FORMAT_RG_FLOAT16; 76848b8605Smrg 77848b8605Smrg case GL_R11F_G11F_B10F: 78848b8605Smrg return MESA_FORMAT_R11G11B10_FLOAT; 79848b8605Smrg 80848b8605Smrg case GL_R32F: 81848b8605Smrg return MESA_FORMAT_R_FLOAT32; 82848b8605Smrg 83848b8605Smrg case GL_R16F: 84848b8605Smrg return MESA_FORMAT_R_FLOAT16; 85848b8605Smrg 86848b8605Smrg case GL_RGBA32UI: 87848b8605Smrg return MESA_FORMAT_RGBA_UINT32; 88848b8605Smrg 89848b8605Smrg case GL_RGBA16UI: 90848b8605Smrg return MESA_FORMAT_RGBA_UINT16; 91848b8605Smrg 92848b8605Smrg case GL_RGB10_A2UI: 93848b8605Smrg return MESA_FORMAT_R10G10B10A2_UINT; 94848b8605Smrg 95848b8605Smrg case GL_RGBA8UI: 96848b8605Smrg return MESA_FORMAT_RGBA_UINT8; 97848b8605Smrg 98848b8605Smrg case GL_RG32UI: 99848b8605Smrg return MESA_FORMAT_RG_UINT32; 100848b8605Smrg 101848b8605Smrg case GL_RG16UI: 102848b8605Smrg return MESA_FORMAT_RG_UINT16; 103848b8605Smrg 104848b8605Smrg case GL_RG8UI: 105848b8605Smrg return MESA_FORMAT_RG_UINT8; 106848b8605Smrg 107848b8605Smrg case GL_R32UI: 108848b8605Smrg return MESA_FORMAT_R_UINT32; 109848b8605Smrg 110848b8605Smrg case GL_R16UI: 111848b8605Smrg return MESA_FORMAT_R_UINT16; 112848b8605Smrg 113848b8605Smrg case GL_R8UI: 114848b8605Smrg return MESA_FORMAT_R_UINT8; 115848b8605Smrg 116848b8605Smrg case GL_RGBA32I: 117848b8605Smrg return MESA_FORMAT_RGBA_SINT32; 118848b8605Smrg 119848b8605Smrg case GL_RGBA16I: 120848b8605Smrg return MESA_FORMAT_RGBA_SINT16; 121848b8605Smrg 122848b8605Smrg case GL_RGBA8I: 123848b8605Smrg return MESA_FORMAT_RGBA_SINT8; 124848b8605Smrg 125848b8605Smrg case GL_RG32I: 126848b8605Smrg return MESA_FORMAT_RG_SINT32; 127848b8605Smrg 128848b8605Smrg case GL_RG16I: 129848b8605Smrg return MESA_FORMAT_RG_SINT16; 130848b8605Smrg 131848b8605Smrg case GL_RG8I: 132848b8605Smrg return MESA_FORMAT_RG_SINT8; 133848b8605Smrg 134848b8605Smrg case GL_R32I: 135848b8605Smrg return MESA_FORMAT_R_SINT32; 136848b8605Smrg 137848b8605Smrg case GL_R16I: 138848b8605Smrg return MESA_FORMAT_R_SINT16; 139848b8605Smrg 140848b8605Smrg case GL_R8I: 141848b8605Smrg return MESA_FORMAT_R_SINT8; 142848b8605Smrg 143848b8605Smrg case GL_RGBA16: 144848b8605Smrg return MESA_FORMAT_RGBA_UNORM16; 145848b8605Smrg 146848b8605Smrg case GL_RGB10_A2: 147848b8605Smrg return MESA_FORMAT_R10G10B10A2_UNORM; 148848b8605Smrg 149848b8605Smrg case GL_RGBA8: 150848b8605Smrg return MESA_FORMAT_RGBA_8; 151848b8605Smrg 152848b8605Smrg case GL_RG16: 153848b8605Smrg return MESA_FORMAT_RG_16; 154848b8605Smrg 155848b8605Smrg case GL_RG8: 156848b8605Smrg return MESA_FORMAT_RG_8; 157848b8605Smrg 158848b8605Smrg case GL_R16: 159848b8605Smrg return MESA_FORMAT_R_UNORM16; 160848b8605Smrg 161848b8605Smrg case GL_R8: 162848b8605Smrg return MESA_FORMAT_R_UNORM8; 163848b8605Smrg 164848b8605Smrg case GL_RGBA16_SNORM: 165848b8605Smrg return MESA_FORMAT_RGBA_SNORM16; 166848b8605Smrg 167848b8605Smrg case GL_RGBA8_SNORM: 168848b8605Smrg return MESA_FORMAT_SIGNED_RGBA_8; 169848b8605Smrg 170848b8605Smrg case GL_RG16_SNORM: 171848b8605Smrg return MESA_FORMAT_SIGNED_RG_16; 172848b8605Smrg 173848b8605Smrg case GL_RG8_SNORM: 174848b8605Smrg return MESA_FORMAT_SIGNED_RG_8; 175848b8605Smrg 176848b8605Smrg case GL_R16_SNORM: 177848b8605Smrg return MESA_FORMAT_R_SNORM16; 178848b8605Smrg 179848b8605Smrg case GL_R8_SNORM: 180848b8605Smrg return MESA_FORMAT_R_SNORM8; 181848b8605Smrg 182848b8605Smrg default: 183848b8605Smrg return MESA_FORMAT_NONE; 184848b8605Smrg } 185848b8605Smrg} 186848b8605Smrg 187848b8605Smrgenum image_format_class 188848b8605Smrg{ 189848b8605Smrg /** Not a valid image format. */ 190848b8605Smrg IMAGE_FORMAT_CLASS_NONE = 0, 191848b8605Smrg 192848b8605Smrg /** Classes of image formats you can cast into each other. */ 193848b8605Smrg /** \{ */ 194848b8605Smrg IMAGE_FORMAT_CLASS_1X8, 195848b8605Smrg IMAGE_FORMAT_CLASS_1X16, 196848b8605Smrg IMAGE_FORMAT_CLASS_1X32, 197848b8605Smrg IMAGE_FORMAT_CLASS_2X8, 198848b8605Smrg IMAGE_FORMAT_CLASS_2X16, 199848b8605Smrg IMAGE_FORMAT_CLASS_2X32, 200848b8605Smrg IMAGE_FORMAT_CLASS_10_11_11, 201848b8605Smrg IMAGE_FORMAT_CLASS_4X8, 202848b8605Smrg IMAGE_FORMAT_CLASS_4X16, 203848b8605Smrg IMAGE_FORMAT_CLASS_4X32, 204848b8605Smrg IMAGE_FORMAT_CLASS_2_10_10_10 205848b8605Smrg /** \} */ 206848b8605Smrg}; 207848b8605Smrg 208848b8605Smrgstatic enum image_format_class 209848b8605Smrgget_image_format_class(mesa_format format) 210848b8605Smrg{ 211848b8605Smrg switch (format) { 212848b8605Smrg case MESA_FORMAT_RGBA_FLOAT32: 213848b8605Smrg return IMAGE_FORMAT_CLASS_4X32; 214848b8605Smrg 215848b8605Smrg case MESA_FORMAT_RGBA_FLOAT16: 216848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 217848b8605Smrg 218848b8605Smrg case MESA_FORMAT_RG_FLOAT32: 219848b8605Smrg return IMAGE_FORMAT_CLASS_2X32; 220848b8605Smrg 221848b8605Smrg case MESA_FORMAT_RG_FLOAT16: 222848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 223848b8605Smrg 224848b8605Smrg case MESA_FORMAT_R11G11B10_FLOAT: 225848b8605Smrg return IMAGE_FORMAT_CLASS_10_11_11; 226848b8605Smrg 227848b8605Smrg case MESA_FORMAT_R_FLOAT32: 228848b8605Smrg return IMAGE_FORMAT_CLASS_1X32; 229848b8605Smrg 230848b8605Smrg case MESA_FORMAT_R_FLOAT16: 231848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 232848b8605Smrg 233848b8605Smrg case MESA_FORMAT_RGBA_UINT32: 234848b8605Smrg return IMAGE_FORMAT_CLASS_4X32; 235848b8605Smrg 236848b8605Smrg case MESA_FORMAT_RGBA_UINT16: 237848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 238848b8605Smrg 239848b8605Smrg case MESA_FORMAT_R10G10B10A2_UINT: 240848b8605Smrg return IMAGE_FORMAT_CLASS_2_10_10_10; 241848b8605Smrg 242848b8605Smrg case MESA_FORMAT_RGBA_UINT8: 243848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 244848b8605Smrg 245848b8605Smrg case MESA_FORMAT_RG_UINT32: 246848b8605Smrg return IMAGE_FORMAT_CLASS_2X32; 247848b8605Smrg 248848b8605Smrg case MESA_FORMAT_RG_UINT16: 249848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 250848b8605Smrg 251848b8605Smrg case MESA_FORMAT_RG_UINT8: 252848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 253848b8605Smrg 254848b8605Smrg case MESA_FORMAT_R_UINT32: 255848b8605Smrg return IMAGE_FORMAT_CLASS_1X32; 256848b8605Smrg 257848b8605Smrg case MESA_FORMAT_R_UINT16: 258848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 259848b8605Smrg 260848b8605Smrg case MESA_FORMAT_R_UINT8: 261848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 262848b8605Smrg 263848b8605Smrg case MESA_FORMAT_RGBA_SINT32: 264848b8605Smrg return IMAGE_FORMAT_CLASS_4X32; 265848b8605Smrg 266848b8605Smrg case MESA_FORMAT_RGBA_SINT16: 267848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 268848b8605Smrg 269848b8605Smrg case MESA_FORMAT_RGBA_SINT8: 270848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 271848b8605Smrg 272848b8605Smrg case MESA_FORMAT_RG_SINT32: 273848b8605Smrg return IMAGE_FORMAT_CLASS_2X32; 274848b8605Smrg 275848b8605Smrg case MESA_FORMAT_RG_SINT16: 276848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 277848b8605Smrg 278848b8605Smrg case MESA_FORMAT_RG_SINT8: 279848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 280848b8605Smrg 281848b8605Smrg case MESA_FORMAT_R_SINT32: 282848b8605Smrg return IMAGE_FORMAT_CLASS_1X32; 283848b8605Smrg 284848b8605Smrg case MESA_FORMAT_R_SINT16: 285848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 286848b8605Smrg 287848b8605Smrg case MESA_FORMAT_R_SINT8: 288848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 289848b8605Smrg 290848b8605Smrg case MESA_FORMAT_RGBA_UNORM16: 291848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 292848b8605Smrg 293848b8605Smrg case MESA_FORMAT_R10G10B10A2_UNORM: 294848b8605Smrg return IMAGE_FORMAT_CLASS_2_10_10_10; 295848b8605Smrg 296848b8605Smrg case MESA_FORMAT_RGBA_8: 297848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 298848b8605Smrg 299848b8605Smrg case MESA_FORMAT_RG_16: 300848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 301848b8605Smrg 302848b8605Smrg case MESA_FORMAT_RG_8: 303848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 304848b8605Smrg 305848b8605Smrg case MESA_FORMAT_R_UNORM16: 306848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 307848b8605Smrg 308848b8605Smrg case MESA_FORMAT_R_UNORM8: 309848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 310848b8605Smrg 311848b8605Smrg case MESA_FORMAT_RGBA_SNORM16: 312848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 313848b8605Smrg 314848b8605Smrg case MESA_FORMAT_SIGNED_RGBA_8: 315848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 316848b8605Smrg 317848b8605Smrg case MESA_FORMAT_SIGNED_RG_16: 318848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 319848b8605Smrg 320848b8605Smrg case MESA_FORMAT_SIGNED_RG_8: 321848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 322848b8605Smrg 323848b8605Smrg case MESA_FORMAT_R_SNORM16: 324848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 325848b8605Smrg 326848b8605Smrg case MESA_FORMAT_R_SNORM8: 327848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 328848b8605Smrg 329848b8605Smrg default: 330848b8605Smrg return IMAGE_FORMAT_CLASS_NONE; 331848b8605Smrg } 332848b8605Smrg} 333848b8605Smrg 334848b8605Smrgstatic GLboolean 335848b8605Smrgvalidate_image_unit(struct gl_context *ctx, struct gl_image_unit *u) 336848b8605Smrg{ 337848b8605Smrg struct gl_texture_object *t = u->TexObj; 338848b8605Smrg struct gl_texture_image *img; 339848b8605Smrg 340848b8605Smrg if (!t || u->Level < t->BaseLevel || 341848b8605Smrg u->Level > t->_MaxLevel) 342848b8605Smrg return GL_FALSE; 343848b8605Smrg 344848b8605Smrg _mesa_test_texobj_completeness(ctx, t); 345848b8605Smrg 346848b8605Smrg if ((u->Level == t->BaseLevel && !t->_BaseComplete) || 347848b8605Smrg (u->Level != t->BaseLevel && !t->_MipmapComplete)) 348848b8605Smrg return GL_FALSE; 349848b8605Smrg 350848b8605Smrg if (_mesa_tex_target_is_layered(t->Target) && 351848b8605Smrg u->Layer >= _mesa_get_texture_layers(t, u->Level)) 352848b8605Smrg return GL_FALSE; 353848b8605Smrg 354848b8605Smrg if (t->Target == GL_TEXTURE_CUBE_MAP) 355848b8605Smrg img = t->Image[u->Layer][u->Level]; 356848b8605Smrg else 357848b8605Smrg img = t->Image[0][u->Level]; 358848b8605Smrg 359848b8605Smrg if (!img || img->Border || 360848b8605Smrg get_image_format_class(img->TexFormat) == IMAGE_FORMAT_CLASS_NONE || 361848b8605Smrg img->NumSamples > ctx->Const.MaxImageSamples) 362848b8605Smrg return GL_FALSE; 363848b8605Smrg 364848b8605Smrg switch (t->ImageFormatCompatibilityType) { 365848b8605Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE: 366848b8605Smrg if (_mesa_get_format_bytes(img->TexFormat) != 367848b8605Smrg _mesa_get_format_bytes(u->_ActualFormat)) 368848b8605Smrg return GL_FALSE; 369848b8605Smrg break; 370848b8605Smrg 371848b8605Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS: 372848b8605Smrg if (get_image_format_class(img->TexFormat) != 373848b8605Smrg get_image_format_class(u->_ActualFormat)) 374848b8605Smrg return GL_FALSE; 375848b8605Smrg break; 376848b8605Smrg 377848b8605Smrg default: 378848b8605Smrg assert(!"Unexpected image format compatibility type"); 379848b8605Smrg } 380848b8605Smrg 381848b8605Smrg return GL_TRUE; 382848b8605Smrg} 383848b8605Smrg 384848b8605Smrgvoid 385848b8605Smrg_mesa_validate_image_units(struct gl_context *ctx) 386848b8605Smrg{ 387848b8605Smrg int i; 388848b8605Smrg 389848b8605Smrg for (i = 0; i < ctx->Const.MaxImageUnits; ++i) { 390848b8605Smrg struct gl_image_unit *u = &ctx->ImageUnits[i]; 391848b8605Smrg u->_Valid = validate_image_unit(ctx, u); 392848b8605Smrg } 393848b8605Smrg} 394848b8605Smrg 395848b8605Smrgstatic GLboolean 396848b8605Smrgvalidate_bind_image_texture(struct gl_context *ctx, GLuint unit, 397848b8605Smrg GLuint texture, GLint level, GLboolean layered, 398848b8605Smrg GLint layer, GLenum access, GLenum format) 399848b8605Smrg{ 400848b8605Smrg assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); 401848b8605Smrg 402848b8605Smrg if (unit >= ctx->Const.MaxImageUnits) { 403848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)"); 404848b8605Smrg return GL_FALSE; 405848b8605Smrg } 406848b8605Smrg 407848b8605Smrg if (level < 0) { 408848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)"); 409848b8605Smrg return GL_FALSE; 410848b8605Smrg } 411848b8605Smrg 412848b8605Smrg if (layer < 0) { 413848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)"); 414848b8605Smrg return GL_FALSE; 415848b8605Smrg } 416848b8605Smrg 417848b8605Smrg if (access != GL_READ_ONLY && 418848b8605Smrg access != GL_WRITE_ONLY && 419848b8605Smrg access != GL_READ_WRITE) { 420848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)"); 421848b8605Smrg return GL_FALSE; 422848b8605Smrg } 423848b8605Smrg 424848b8605Smrg if (!get_image_format(format)) { 425848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)"); 426848b8605Smrg return GL_FALSE; 427848b8605Smrg } 428848b8605Smrg 429848b8605Smrg return GL_TRUE; 430848b8605Smrg} 431848b8605Smrg 432848b8605Smrgvoid GLAPIENTRY 433848b8605Smrg_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, 434848b8605Smrg GLboolean layered, GLint layer, GLenum access, 435848b8605Smrg GLenum format) 436848b8605Smrg{ 437848b8605Smrg GET_CURRENT_CONTEXT(ctx); 438848b8605Smrg struct gl_texture_object *t = NULL; 439848b8605Smrg struct gl_image_unit *u; 440848b8605Smrg 441848b8605Smrg if (!validate_bind_image_texture(ctx, unit, texture, level, 442848b8605Smrg layered, layer, access, format)) 443848b8605Smrg return; 444848b8605Smrg 445848b8605Smrg u = &ctx->ImageUnits[unit]; 446848b8605Smrg 447848b8605Smrg FLUSH_VERTICES(ctx, 0); 448848b8605Smrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 449848b8605Smrg 450848b8605Smrg if (texture) { 451848b8605Smrg t = _mesa_lookup_texture(ctx, texture); 452848b8605Smrg if (!t) { 453848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)"); 454848b8605Smrg return; 455848b8605Smrg } 456848b8605Smrg 457848b8605Smrg _mesa_reference_texobj(&u->TexObj, t); 458848b8605Smrg u->Level = level; 459848b8605Smrg u->Access = access; 460848b8605Smrg u->Format = format; 461848b8605Smrg u->_ActualFormat = get_image_format(format); 462848b8605Smrg 463848b8605Smrg if (_mesa_tex_target_is_layered(t->Target)) { 464848b8605Smrg u->Layered = layered; 465848b8605Smrg u->Layer = (layered ? 0 : layer); 466848b8605Smrg } else { 467848b8605Smrg u->Layered = GL_FALSE; 468848b8605Smrg u->Layer = 0; 469848b8605Smrg } 470848b8605Smrg 471848b8605Smrg } else { 472848b8605Smrg _mesa_reference_texobj(&u->TexObj, NULL); 473848b8605Smrg } 474848b8605Smrg 475848b8605Smrg u->_Valid = validate_image_unit(ctx, u); 476848b8605Smrg 477848b8605Smrg if (ctx->Driver.BindImageTexture) 478848b8605Smrg ctx->Driver.BindImageTexture(ctx, u, t, level, layered, 479848b8605Smrg layer, access, format); 480848b8605Smrg} 481848b8605Smrg 482848b8605Smrgvoid GLAPIENTRY 483848b8605Smrg_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures) 484848b8605Smrg{ 485848b8605Smrg GET_CURRENT_CONTEXT(ctx); 486848b8605Smrg int i; 487848b8605Smrg 488848b8605Smrg if (!ctx->Extensions.ARB_shader_image_load_store) { 489848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()"); 490848b8605Smrg return; 491848b8605Smrg } 492848b8605Smrg 493848b8605Smrg if (first + count > ctx->Const.MaxImageUnits) { 494848b8605Smrg /* The ARB_multi_bind spec says: 495848b8605Smrg * 496848b8605Smrg * "An INVALID_OPERATION error is generated if <first> + <count> 497848b8605Smrg * is greater than the number of image units supported by 498848b8605Smrg * the implementation." 499848b8605Smrg */ 500848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 501848b8605Smrg "glBindImageTextures(first=%u + count=%d > the value of " 502848b8605Smrg "GL_MAX_IMAGE_UNITS=%u)", 503848b8605Smrg first, count, ctx->Const.MaxImageUnits); 504848b8605Smrg return; 505848b8605Smrg } 506848b8605Smrg 507848b8605Smrg /* Assume that at least one binding will be changed */ 508848b8605Smrg FLUSH_VERTICES(ctx, 0); 509848b8605Smrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 510848b8605Smrg 511848b8605Smrg /* Note that the error semantics for multi-bind commands differ from 512848b8605Smrg * those of other GL commands. 513848b8605Smrg * 514848b8605Smrg * The Issues section in the ARB_multi_bind spec says: 515848b8605Smrg * 516848b8605Smrg * "(11) Typically, OpenGL specifies that if an error is generated by 517848b8605Smrg * a command, that command has no effect. This is somewhat 518848b8605Smrg * unfortunate for multi-bind commands, because it would require 519848b8605Smrg * a first pass to scan the entire list of bound objects for 520848b8605Smrg * errors and then a second pass to actually perform the 521848b8605Smrg * bindings. Should we have different error semantics? 522848b8605Smrg * 523848b8605Smrg * RESOLVED: Yes. In this specification, when the parameters for 524848b8605Smrg * one of the <count> binding points are invalid, that binding 525848b8605Smrg * point is not updated and an error will be generated. However, 526848b8605Smrg * other binding points in the same command will be updated if 527848b8605Smrg * their parameters are valid and no other error occurs." 528848b8605Smrg */ 529848b8605Smrg 530848b8605Smrg _mesa_begin_texture_lookups(ctx); 531848b8605Smrg 532848b8605Smrg for (i = 0; i < count; i++) { 533848b8605Smrg struct gl_image_unit *u = &ctx->ImageUnits[first + i]; 534848b8605Smrg const GLuint texture = textures ? textures[i] : 0; 535848b8605Smrg 536848b8605Smrg if (texture != 0) { 537848b8605Smrg struct gl_texture_object *texObj; 538848b8605Smrg struct gl_texture_image *image; 539848b8605Smrg mesa_format actualFormat; 540848b8605Smrg 541848b8605Smrg if (!u->TexObj || u->TexObj->Name != texture) { 542848b8605Smrg texObj = _mesa_lookup_texture_locked(ctx, texture); 543848b8605Smrg if (!texObj) { 544848b8605Smrg /* The ARB_multi_bind spec says: 545848b8605Smrg * 546848b8605Smrg * "An INVALID_OPERATION error is generated if any value 547848b8605Smrg * in <textures> is not zero or the name of an existing 548848b8605Smrg * texture object (per binding)." 549848b8605Smrg */ 550848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 551848b8605Smrg "glBindImageTextures(textures[%d]=%u " 552848b8605Smrg "is not zero or the name of an existing texture " 553848b8605Smrg "object)", i, texture); 554848b8605Smrg continue; 555848b8605Smrg } 556848b8605Smrg } else { 557848b8605Smrg texObj = u->TexObj; 558848b8605Smrg } 559848b8605Smrg 560848b8605Smrg image = texObj->Image[0][0]; 561848b8605Smrg 562848b8605Smrg if (!image || image->Width == 0 || image->Height == 0 || image->Depth == 0) { 563848b8605Smrg /* The ARB_multi_bind spec says: 564848b8605Smrg * 565848b8605Smrg * "An INVALID_OPERATION error is generated if the width, 566848b8605Smrg * height, or depth of the level zero texture image of 567848b8605Smrg * any texture in <textures> is zero (per binding)." 568848b8605Smrg */ 569848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 570848b8605Smrg "glBindImageTextures(the width, height or depth " 571848b8605Smrg "of the level zero texture image of " 572848b8605Smrg "textures[%d]=%u is zero)", i, texture); 573848b8605Smrg continue; 574848b8605Smrg } 575848b8605Smrg 576848b8605Smrg actualFormat = get_image_format(image->InternalFormat); 577848b8605Smrg 578848b8605Smrg if (actualFormat == MESA_FORMAT_NONE) { 579848b8605Smrg /* The ARB_multi_bind spec says: 580848b8605Smrg * 581848b8605Smrg * "An INVALID_OPERATION error is generated if the internal 582848b8605Smrg * format of the level zero texture image of any texture 583848b8605Smrg * in <textures> is not found in table 8.33 (per binding)." 584848b8605Smrg */ 585848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 586848b8605Smrg "glBindImageTextures(the internal format %s of " 587848b8605Smrg "the level zero texture image of textures[%d]=%u " 588848b8605Smrg "is not supported)", 589848b8605Smrg _mesa_lookup_enum_by_nr(image->InternalFormat), 590848b8605Smrg i, texture); 591848b8605Smrg continue; 592848b8605Smrg } 593848b8605Smrg 594848b8605Smrg /* Update the texture binding */ 595848b8605Smrg _mesa_reference_texobj(&u->TexObj, texObj); 596848b8605Smrg u->Level = 0; 597848b8605Smrg u->Layered = _mesa_tex_target_is_layered(texObj->Target); 598848b8605Smrg u->Layer = 0; 599848b8605Smrg u->Access = GL_READ_WRITE; 600848b8605Smrg u->Format = image->InternalFormat; 601848b8605Smrg u->_ActualFormat = actualFormat; 602848b8605Smrg u->_Valid = validate_image_unit(ctx, u); 603848b8605Smrg } else { 604848b8605Smrg /* Unbind the texture from the unit */ 605848b8605Smrg _mesa_reference_texobj(&u->TexObj, NULL); 606848b8605Smrg u->Level = 0; 607848b8605Smrg u->Layered = GL_FALSE; 608848b8605Smrg u->Layer = 0; 609848b8605Smrg u->Access = GL_READ_ONLY; 610848b8605Smrg u->Format = GL_R8; 611848b8605Smrg u->_ActualFormat = MESA_FORMAT_R_UNORM8; 612848b8605Smrg u->_Valid = GL_FALSE; 613848b8605Smrg } 614848b8605Smrg 615848b8605Smrg /* Pass the BindImageTexture call down to the device driver */ 616848b8605Smrg if (ctx->Driver.BindImageTexture) 617848b8605Smrg ctx->Driver.BindImageTexture(ctx, u, u->TexObj, u->Level, u->Layered, 618848b8605Smrg u->Layer, u->Access, u->Format); 619848b8605Smrg } 620848b8605Smrg 621848b8605Smrg _mesa_end_texture_lookups(ctx); 622848b8605Smrg} 623848b8605Smrg 624848b8605Smrgvoid GLAPIENTRY 625848b8605Smrg_mesa_MemoryBarrier(GLbitfield barriers) 626848b8605Smrg{ 627848b8605Smrg GET_CURRENT_CONTEXT(ctx); 628848b8605Smrg 629848b8605Smrg if (ctx->Driver.MemoryBarrier) 630848b8605Smrg ctx->Driver.MemoryBarrier(ctx, barriers); 631848b8605Smrg} 632