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" 33b8e80941Smrg#include "hash.h" 34848b8605Smrg#include "context.h" 35848b8605Smrg#include "texobj.h" 36848b8605Smrg#include "teximage.h" 37848b8605Smrg#include "enums.h" 38848b8605Smrg 39848b8605Smrg/* 40848b8605Smrg * Define endian-invariant aliases for some mesa formats that are 41848b8605Smrg * defined in terms of their channel layout from LSB to MSB in a 42848b8605Smrg * 32-bit word. The actual byte offsets matter here because the user 43848b8605Smrg * is allowed to bit-cast one format into another and get predictable 44848b8605Smrg * results. 45848b8605Smrg */ 46848b8605Smrg#ifdef MESA_BIG_ENDIAN 47848b8605Smrg# define MESA_FORMAT_RGBA_8 MESA_FORMAT_A8B8G8R8_UNORM 48848b8605Smrg# define MESA_FORMAT_RG_16 MESA_FORMAT_G16R16_UNORM 49848b8605Smrg# define MESA_FORMAT_RG_8 MESA_FORMAT_G8R8_UNORM 50848b8605Smrg# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_A8B8G8R8_SNORM 51848b8605Smrg# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_G16R16_SNORM 52848b8605Smrg# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_G8R8_SNORM 53848b8605Smrg#else 54848b8605Smrg# define MESA_FORMAT_RGBA_8 MESA_FORMAT_R8G8B8A8_UNORM 55848b8605Smrg# define MESA_FORMAT_RG_16 MESA_FORMAT_R16G16_UNORM 56848b8605Smrg# define MESA_FORMAT_RG_8 MESA_FORMAT_R8G8_UNORM 57848b8605Smrg# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_R8G8B8A8_SNORM 58848b8605Smrg# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_R16G16_SNORM 59848b8605Smrg# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_R8G8_SNORM 60848b8605Smrg#endif 61848b8605Smrg 62b8e80941Smrgmesa_format 63b8e80941Smrg_mesa_get_shader_image_format(GLenum format) 64848b8605Smrg{ 65848b8605Smrg switch (format) { 66848b8605Smrg case GL_RGBA32F: 67848b8605Smrg return MESA_FORMAT_RGBA_FLOAT32; 68848b8605Smrg 69848b8605Smrg case GL_RGBA16F: 70848b8605Smrg return MESA_FORMAT_RGBA_FLOAT16; 71848b8605Smrg 72848b8605Smrg case GL_RG32F: 73848b8605Smrg return MESA_FORMAT_RG_FLOAT32; 74848b8605Smrg 75848b8605Smrg case GL_RG16F: 76848b8605Smrg return MESA_FORMAT_RG_FLOAT16; 77848b8605Smrg 78848b8605Smrg case GL_R11F_G11F_B10F: 79848b8605Smrg return MESA_FORMAT_R11G11B10_FLOAT; 80848b8605Smrg 81848b8605Smrg case GL_R32F: 82848b8605Smrg return MESA_FORMAT_R_FLOAT32; 83848b8605Smrg 84848b8605Smrg case GL_R16F: 85848b8605Smrg return MESA_FORMAT_R_FLOAT16; 86848b8605Smrg 87848b8605Smrg case GL_RGBA32UI: 88848b8605Smrg return MESA_FORMAT_RGBA_UINT32; 89848b8605Smrg 90848b8605Smrg case GL_RGBA16UI: 91848b8605Smrg return MESA_FORMAT_RGBA_UINT16; 92848b8605Smrg 93848b8605Smrg case GL_RGB10_A2UI: 94848b8605Smrg return MESA_FORMAT_R10G10B10A2_UINT; 95848b8605Smrg 96848b8605Smrg case GL_RGBA8UI: 97848b8605Smrg return MESA_FORMAT_RGBA_UINT8; 98848b8605Smrg 99848b8605Smrg case GL_RG32UI: 100848b8605Smrg return MESA_FORMAT_RG_UINT32; 101848b8605Smrg 102848b8605Smrg case GL_RG16UI: 103848b8605Smrg return MESA_FORMAT_RG_UINT16; 104848b8605Smrg 105848b8605Smrg case GL_RG8UI: 106848b8605Smrg return MESA_FORMAT_RG_UINT8; 107848b8605Smrg 108848b8605Smrg case GL_R32UI: 109848b8605Smrg return MESA_FORMAT_R_UINT32; 110848b8605Smrg 111848b8605Smrg case GL_R16UI: 112848b8605Smrg return MESA_FORMAT_R_UINT16; 113848b8605Smrg 114848b8605Smrg case GL_R8UI: 115848b8605Smrg return MESA_FORMAT_R_UINT8; 116848b8605Smrg 117848b8605Smrg case GL_RGBA32I: 118848b8605Smrg return MESA_FORMAT_RGBA_SINT32; 119848b8605Smrg 120848b8605Smrg case GL_RGBA16I: 121848b8605Smrg return MESA_FORMAT_RGBA_SINT16; 122848b8605Smrg 123848b8605Smrg case GL_RGBA8I: 124848b8605Smrg return MESA_FORMAT_RGBA_SINT8; 125848b8605Smrg 126848b8605Smrg case GL_RG32I: 127848b8605Smrg return MESA_FORMAT_RG_SINT32; 128848b8605Smrg 129848b8605Smrg case GL_RG16I: 130848b8605Smrg return MESA_FORMAT_RG_SINT16; 131848b8605Smrg 132848b8605Smrg case GL_RG8I: 133848b8605Smrg return MESA_FORMAT_RG_SINT8; 134848b8605Smrg 135848b8605Smrg case GL_R32I: 136848b8605Smrg return MESA_FORMAT_R_SINT32; 137848b8605Smrg 138848b8605Smrg case GL_R16I: 139848b8605Smrg return MESA_FORMAT_R_SINT16; 140848b8605Smrg 141848b8605Smrg case GL_R8I: 142848b8605Smrg return MESA_FORMAT_R_SINT8; 143848b8605Smrg 144848b8605Smrg case GL_RGBA16: 145848b8605Smrg return MESA_FORMAT_RGBA_UNORM16; 146848b8605Smrg 147848b8605Smrg case GL_RGB10_A2: 148848b8605Smrg return MESA_FORMAT_R10G10B10A2_UNORM; 149848b8605Smrg 150848b8605Smrg case GL_RGBA8: 151848b8605Smrg return MESA_FORMAT_RGBA_8; 152848b8605Smrg 153848b8605Smrg case GL_RG16: 154848b8605Smrg return MESA_FORMAT_RG_16; 155848b8605Smrg 156848b8605Smrg case GL_RG8: 157848b8605Smrg return MESA_FORMAT_RG_8; 158848b8605Smrg 159848b8605Smrg case GL_R16: 160848b8605Smrg return MESA_FORMAT_R_UNORM16; 161848b8605Smrg 162848b8605Smrg case GL_R8: 163848b8605Smrg return MESA_FORMAT_R_UNORM8; 164848b8605Smrg 165848b8605Smrg case GL_RGBA16_SNORM: 166848b8605Smrg return MESA_FORMAT_RGBA_SNORM16; 167848b8605Smrg 168848b8605Smrg case GL_RGBA8_SNORM: 169848b8605Smrg return MESA_FORMAT_SIGNED_RGBA_8; 170848b8605Smrg 171848b8605Smrg case GL_RG16_SNORM: 172848b8605Smrg return MESA_FORMAT_SIGNED_RG_16; 173848b8605Smrg 174848b8605Smrg case GL_RG8_SNORM: 175848b8605Smrg return MESA_FORMAT_SIGNED_RG_8; 176848b8605Smrg 177848b8605Smrg case GL_R16_SNORM: 178848b8605Smrg return MESA_FORMAT_R_SNORM16; 179848b8605Smrg 180848b8605Smrg case GL_R8_SNORM: 181848b8605Smrg return MESA_FORMAT_R_SNORM8; 182848b8605Smrg 183848b8605Smrg default: 184848b8605Smrg return MESA_FORMAT_NONE; 185848b8605Smrg } 186848b8605Smrg} 187848b8605Smrg 188848b8605Smrgenum image_format_class 189848b8605Smrg{ 190848b8605Smrg /** Not a valid image format. */ 191848b8605Smrg IMAGE_FORMAT_CLASS_NONE = 0, 192848b8605Smrg 193848b8605Smrg /** Classes of image formats you can cast into each other. */ 194848b8605Smrg /** \{ */ 195848b8605Smrg IMAGE_FORMAT_CLASS_1X8, 196848b8605Smrg IMAGE_FORMAT_CLASS_1X16, 197848b8605Smrg IMAGE_FORMAT_CLASS_1X32, 198848b8605Smrg IMAGE_FORMAT_CLASS_2X8, 199848b8605Smrg IMAGE_FORMAT_CLASS_2X16, 200848b8605Smrg IMAGE_FORMAT_CLASS_2X32, 201848b8605Smrg IMAGE_FORMAT_CLASS_10_11_11, 202848b8605Smrg IMAGE_FORMAT_CLASS_4X8, 203848b8605Smrg IMAGE_FORMAT_CLASS_4X16, 204848b8605Smrg IMAGE_FORMAT_CLASS_4X32, 205848b8605Smrg IMAGE_FORMAT_CLASS_2_10_10_10 206848b8605Smrg /** \} */ 207848b8605Smrg}; 208848b8605Smrg 209848b8605Smrgstatic enum image_format_class 210848b8605Smrgget_image_format_class(mesa_format format) 211848b8605Smrg{ 212848b8605Smrg switch (format) { 213848b8605Smrg case MESA_FORMAT_RGBA_FLOAT32: 214848b8605Smrg return IMAGE_FORMAT_CLASS_4X32; 215848b8605Smrg 216848b8605Smrg case MESA_FORMAT_RGBA_FLOAT16: 217848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 218848b8605Smrg 219848b8605Smrg case MESA_FORMAT_RG_FLOAT32: 220848b8605Smrg return IMAGE_FORMAT_CLASS_2X32; 221848b8605Smrg 222848b8605Smrg case MESA_FORMAT_RG_FLOAT16: 223848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 224848b8605Smrg 225848b8605Smrg case MESA_FORMAT_R11G11B10_FLOAT: 226848b8605Smrg return IMAGE_FORMAT_CLASS_10_11_11; 227848b8605Smrg 228848b8605Smrg case MESA_FORMAT_R_FLOAT32: 229848b8605Smrg return IMAGE_FORMAT_CLASS_1X32; 230848b8605Smrg 231848b8605Smrg case MESA_FORMAT_R_FLOAT16: 232848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 233848b8605Smrg 234848b8605Smrg case MESA_FORMAT_RGBA_UINT32: 235848b8605Smrg return IMAGE_FORMAT_CLASS_4X32; 236848b8605Smrg 237848b8605Smrg case MESA_FORMAT_RGBA_UINT16: 238848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 239848b8605Smrg 240848b8605Smrg case MESA_FORMAT_R10G10B10A2_UINT: 241848b8605Smrg return IMAGE_FORMAT_CLASS_2_10_10_10; 242848b8605Smrg 243848b8605Smrg case MESA_FORMAT_RGBA_UINT8: 244848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 245848b8605Smrg 246848b8605Smrg case MESA_FORMAT_RG_UINT32: 247848b8605Smrg return IMAGE_FORMAT_CLASS_2X32; 248848b8605Smrg 249848b8605Smrg case MESA_FORMAT_RG_UINT16: 250848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 251848b8605Smrg 252848b8605Smrg case MESA_FORMAT_RG_UINT8: 253848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 254848b8605Smrg 255848b8605Smrg case MESA_FORMAT_R_UINT32: 256848b8605Smrg return IMAGE_FORMAT_CLASS_1X32; 257848b8605Smrg 258848b8605Smrg case MESA_FORMAT_R_UINT16: 259848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 260848b8605Smrg 261848b8605Smrg case MESA_FORMAT_R_UINT8: 262848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 263848b8605Smrg 264848b8605Smrg case MESA_FORMAT_RGBA_SINT32: 265848b8605Smrg return IMAGE_FORMAT_CLASS_4X32; 266848b8605Smrg 267848b8605Smrg case MESA_FORMAT_RGBA_SINT16: 268848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 269848b8605Smrg 270848b8605Smrg case MESA_FORMAT_RGBA_SINT8: 271848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 272848b8605Smrg 273848b8605Smrg case MESA_FORMAT_RG_SINT32: 274848b8605Smrg return IMAGE_FORMAT_CLASS_2X32; 275848b8605Smrg 276848b8605Smrg case MESA_FORMAT_RG_SINT16: 277848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 278848b8605Smrg 279848b8605Smrg case MESA_FORMAT_RG_SINT8: 280848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 281848b8605Smrg 282848b8605Smrg case MESA_FORMAT_R_SINT32: 283848b8605Smrg return IMAGE_FORMAT_CLASS_1X32; 284848b8605Smrg 285848b8605Smrg case MESA_FORMAT_R_SINT16: 286848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 287848b8605Smrg 288848b8605Smrg case MESA_FORMAT_R_SINT8: 289848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 290848b8605Smrg 291848b8605Smrg case MESA_FORMAT_RGBA_UNORM16: 292848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 293848b8605Smrg 294848b8605Smrg case MESA_FORMAT_R10G10B10A2_UNORM: 295848b8605Smrg return IMAGE_FORMAT_CLASS_2_10_10_10; 296848b8605Smrg 297848b8605Smrg case MESA_FORMAT_RGBA_8: 298848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 299848b8605Smrg 300848b8605Smrg case MESA_FORMAT_RG_16: 301848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 302848b8605Smrg 303848b8605Smrg case MESA_FORMAT_RG_8: 304848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 305848b8605Smrg 306848b8605Smrg case MESA_FORMAT_R_UNORM16: 307848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 308848b8605Smrg 309848b8605Smrg case MESA_FORMAT_R_UNORM8: 310848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 311848b8605Smrg 312848b8605Smrg case MESA_FORMAT_RGBA_SNORM16: 313848b8605Smrg return IMAGE_FORMAT_CLASS_4X16; 314848b8605Smrg 315848b8605Smrg case MESA_FORMAT_SIGNED_RGBA_8: 316848b8605Smrg return IMAGE_FORMAT_CLASS_4X8; 317848b8605Smrg 318848b8605Smrg case MESA_FORMAT_SIGNED_RG_16: 319848b8605Smrg return IMAGE_FORMAT_CLASS_2X16; 320848b8605Smrg 321848b8605Smrg case MESA_FORMAT_SIGNED_RG_8: 322848b8605Smrg return IMAGE_FORMAT_CLASS_2X8; 323848b8605Smrg 324848b8605Smrg case MESA_FORMAT_R_SNORM16: 325848b8605Smrg return IMAGE_FORMAT_CLASS_1X16; 326848b8605Smrg 327848b8605Smrg case MESA_FORMAT_R_SNORM8: 328848b8605Smrg return IMAGE_FORMAT_CLASS_1X8; 329848b8605Smrg 330848b8605Smrg default: 331848b8605Smrg return IMAGE_FORMAT_CLASS_NONE; 332848b8605Smrg } 333848b8605Smrg} 334848b8605Smrg 335b8e80941Smrgstatic GLenum 336b8e80941Smrg_image_format_class_to_glenum(enum image_format_class class) 337b8e80941Smrg{ 338b8e80941Smrg switch (class) { 339b8e80941Smrg case IMAGE_FORMAT_CLASS_NONE: 340b8e80941Smrg return GL_NONE; 341b8e80941Smrg case IMAGE_FORMAT_CLASS_1X8: 342b8e80941Smrg return GL_IMAGE_CLASS_1_X_8; 343b8e80941Smrg case IMAGE_FORMAT_CLASS_1X16: 344b8e80941Smrg return GL_IMAGE_CLASS_1_X_16; 345b8e80941Smrg case IMAGE_FORMAT_CLASS_1X32: 346b8e80941Smrg return GL_IMAGE_CLASS_1_X_32; 347b8e80941Smrg case IMAGE_FORMAT_CLASS_2X8: 348b8e80941Smrg return GL_IMAGE_CLASS_2_X_8; 349b8e80941Smrg case IMAGE_FORMAT_CLASS_2X16: 350b8e80941Smrg return GL_IMAGE_CLASS_2_X_16; 351b8e80941Smrg case IMAGE_FORMAT_CLASS_2X32: 352b8e80941Smrg return GL_IMAGE_CLASS_2_X_32; 353b8e80941Smrg case IMAGE_FORMAT_CLASS_10_11_11: 354b8e80941Smrg return GL_IMAGE_CLASS_11_11_10; 355b8e80941Smrg case IMAGE_FORMAT_CLASS_4X8: 356b8e80941Smrg return GL_IMAGE_CLASS_4_X_8; 357b8e80941Smrg case IMAGE_FORMAT_CLASS_4X16: 358b8e80941Smrg return GL_IMAGE_CLASS_4_X_16; 359b8e80941Smrg case IMAGE_FORMAT_CLASS_4X32: 360b8e80941Smrg return GL_IMAGE_CLASS_4_X_32; 361b8e80941Smrg case IMAGE_FORMAT_CLASS_2_10_10_10: 362b8e80941Smrg return GL_IMAGE_CLASS_10_10_10_2; 363b8e80941Smrg default: 364b8e80941Smrg assert(!"Invalid image_format_class"); 365b8e80941Smrg return GL_NONE; 366b8e80941Smrg } 367b8e80941Smrg} 368b8e80941Smrg 369b8e80941SmrgGLenum 370b8e80941Smrg_mesa_get_image_format_class(GLenum format) 371b8e80941Smrg{ 372b8e80941Smrg mesa_format tex_format = _mesa_get_shader_image_format(format); 373b8e80941Smrg if (tex_format == MESA_FORMAT_NONE) 374b8e80941Smrg return GL_NONE; 375b8e80941Smrg 376b8e80941Smrg enum image_format_class class = get_image_format_class(tex_format); 377b8e80941Smrg return _image_format_class_to_glenum(class); 378b8e80941Smrg} 379b8e80941Smrg 380b8e80941Smrgbool 381b8e80941Smrg_mesa_is_shader_image_format_supported(const struct gl_context *ctx, 382b8e80941Smrg GLenum format) 383b8e80941Smrg{ 384b8e80941Smrg switch (format) { 385b8e80941Smrg /* Formats supported on both desktop and ES GL, c.f. table 8.27 of the 386b8e80941Smrg * OpenGL ES 3.1 specification. 387b8e80941Smrg */ 388b8e80941Smrg case GL_RGBA32F: 389b8e80941Smrg case GL_RGBA16F: 390b8e80941Smrg case GL_R32F: 391b8e80941Smrg case GL_RGBA32UI: 392b8e80941Smrg case GL_RGBA16UI: 393b8e80941Smrg case GL_RGBA8UI: 394b8e80941Smrg case GL_R32UI: 395b8e80941Smrg case GL_RGBA32I: 396b8e80941Smrg case GL_RGBA16I: 397b8e80941Smrg case GL_RGBA8I: 398b8e80941Smrg case GL_R32I: 399b8e80941Smrg case GL_RGBA8: 400b8e80941Smrg case GL_RGBA8_SNORM: 401b8e80941Smrg return true; 402b8e80941Smrg 403b8e80941Smrg /* Formats supported on unextended desktop GL and the original 404b8e80941Smrg * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2 405b8e80941Smrg * specification or by GLES 3.1 with GL_NV_image_formats extension. 406b8e80941Smrg */ 407b8e80941Smrg case GL_RG32F: 408b8e80941Smrg case GL_RG16F: 409b8e80941Smrg case GL_R11F_G11F_B10F: 410b8e80941Smrg case GL_R16F: 411b8e80941Smrg case GL_RGB10_A2UI: 412b8e80941Smrg case GL_RG32UI: 413b8e80941Smrg case GL_RG16UI: 414b8e80941Smrg case GL_RG8UI: 415b8e80941Smrg case GL_R16UI: 416b8e80941Smrg case GL_R8UI: 417b8e80941Smrg case GL_RG32I: 418b8e80941Smrg case GL_RG16I: 419b8e80941Smrg case GL_RG8I: 420b8e80941Smrg case GL_R16I: 421b8e80941Smrg case GL_R8I: 422b8e80941Smrg case GL_RGB10_A2: 423b8e80941Smrg case GL_RG8: 424b8e80941Smrg case GL_R8: 425b8e80941Smrg case GL_RG8_SNORM: 426b8e80941Smrg case GL_R8_SNORM: 427b8e80941Smrg return true; 428b8e80941Smrg 429b8e80941Smrg /* Formats supported on unextended desktop GL and the original 430b8e80941Smrg * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2 431b8e80941Smrg * specification. 432b8e80941Smrg * 433b8e80941Smrg * Following formats are supported by GLES 3.1 with GL_NV_image_formats & 434b8e80941Smrg * GL_EXT_texture_norm16 extensions. 435b8e80941Smrg */ 436b8e80941Smrg case GL_RGBA16: 437b8e80941Smrg case GL_RGBA16_SNORM: 438b8e80941Smrg case GL_RG16: 439b8e80941Smrg case GL_RG16_SNORM: 440b8e80941Smrg case GL_R16: 441b8e80941Smrg case GL_R16_SNORM: 442b8e80941Smrg return _mesa_is_desktop_gl(ctx) || _mesa_has_EXT_texture_norm16(ctx); 443b8e80941Smrg 444b8e80941Smrg default: 445b8e80941Smrg return false; 446b8e80941Smrg } 447b8e80941Smrg} 448b8e80941Smrg 449b8e80941Smrgstruct gl_image_unit 450b8e80941Smrg_mesa_default_image_unit(struct gl_context *ctx) 451b8e80941Smrg{ 452b8e80941Smrg const GLenum format = _mesa_is_desktop_gl(ctx) ? GL_R8 : GL_R32UI; 453b8e80941Smrg const struct gl_image_unit u = { 454b8e80941Smrg .Access = GL_READ_ONLY, 455b8e80941Smrg .Format = format, 456b8e80941Smrg ._ActualFormat = _mesa_get_shader_image_format(format) 457b8e80941Smrg }; 458b8e80941Smrg return u; 459b8e80941Smrg} 460b8e80941Smrg 461b8e80941Smrgvoid 462b8e80941Smrg_mesa_init_image_units(struct gl_context *ctx) 463b8e80941Smrg{ 464b8e80941Smrg unsigned i; 465b8e80941Smrg 466b8e80941Smrg ASSERT_BITFIELD_SIZE(struct gl_image_unit, Format, MESA_FORMAT_COUNT); 467b8e80941Smrg 468b8e80941Smrg for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i) 469b8e80941Smrg ctx->ImageUnits[i] = _mesa_default_image_unit(ctx); 470b8e80941Smrg} 471b8e80941Smrg 472b8e80941Smrg 473b8e80941Smrgvoid 474b8e80941Smrg_mesa_free_image_textures(struct gl_context *ctx) 475b8e80941Smrg{ 476b8e80941Smrg unsigned i; 477b8e80941Smrg 478b8e80941Smrg for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i) 479b8e80941Smrg _mesa_reference_texobj(&ctx->ImageUnits[i].TexObj, NULL); 480b8e80941Smrg} 481b8e80941Smrg 482b8e80941SmrgGLboolean 483b8e80941Smrg_mesa_is_image_unit_valid(struct gl_context *ctx, struct gl_image_unit *u) 484848b8605Smrg{ 485848b8605Smrg struct gl_texture_object *t = u->TexObj; 486b8e80941Smrg mesa_format tex_format; 487848b8605Smrg 488b8e80941Smrg if (!t) 489848b8605Smrg return GL_FALSE; 490848b8605Smrg 491b8e80941Smrg if (!t->_BaseComplete && !t->_MipmapComplete) 492b8e80941Smrg _mesa_test_texobj_completeness(ctx, t); 493848b8605Smrg 494b8e80941Smrg if (u->Level < t->BaseLevel || 495b8e80941Smrg u->Level > t->_MaxLevel || 496b8e80941Smrg (u->Level == t->BaseLevel && !t->_BaseComplete) || 497848b8605Smrg (u->Level != t->BaseLevel && !t->_MipmapComplete)) 498848b8605Smrg return GL_FALSE; 499848b8605Smrg 500848b8605Smrg if (_mesa_tex_target_is_layered(t->Target) && 501b8e80941Smrg u->_Layer >= _mesa_get_texture_layers(t, u->Level)) 502848b8605Smrg return GL_FALSE; 503848b8605Smrg 504b8e80941Smrg if (t->Target == GL_TEXTURE_BUFFER) { 505b8e80941Smrg tex_format = _mesa_get_shader_image_format(t->BufferObjectFormat); 506b8e80941Smrg 507b8e80941Smrg } else { 508b8e80941Smrg struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ? 509b8e80941Smrg t->Image[u->_Layer][u->Level] : 510b8e80941Smrg t->Image[0][u->Level]); 511b8e80941Smrg 512b8e80941Smrg if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples) 513b8e80941Smrg return GL_FALSE; 514848b8605Smrg 515b8e80941Smrg tex_format = _mesa_get_shader_image_format(img->InternalFormat); 516b8e80941Smrg } 517b8e80941Smrg 518b8e80941Smrg if (!tex_format) 519848b8605Smrg return GL_FALSE; 520848b8605Smrg 521848b8605Smrg switch (t->ImageFormatCompatibilityType) { 522848b8605Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE: 523b8e80941Smrg if (_mesa_get_format_bytes(tex_format) != 524848b8605Smrg _mesa_get_format_bytes(u->_ActualFormat)) 525848b8605Smrg return GL_FALSE; 526848b8605Smrg break; 527848b8605Smrg 528848b8605Smrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS: 529b8e80941Smrg if (get_image_format_class(tex_format) != 530848b8605Smrg get_image_format_class(u->_ActualFormat)) 531848b8605Smrg return GL_FALSE; 532848b8605Smrg break; 533848b8605Smrg 534848b8605Smrg default: 535848b8605Smrg assert(!"Unexpected image format compatibility type"); 536848b8605Smrg } 537848b8605Smrg 538848b8605Smrg return GL_TRUE; 539848b8605Smrg} 540848b8605Smrg 541848b8605Smrgstatic GLboolean 542848b8605Smrgvalidate_bind_image_texture(struct gl_context *ctx, GLuint unit, 543b8e80941Smrg GLuint texture, GLint level, GLint layer, 544b8e80941Smrg GLenum access, GLenum format) 545848b8605Smrg{ 546848b8605Smrg assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); 547848b8605Smrg 548848b8605Smrg if (unit >= ctx->Const.MaxImageUnits) { 549848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)"); 550848b8605Smrg return GL_FALSE; 551848b8605Smrg } 552848b8605Smrg 553848b8605Smrg if (level < 0) { 554848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)"); 555848b8605Smrg return GL_FALSE; 556848b8605Smrg } 557848b8605Smrg 558848b8605Smrg if (layer < 0) { 559848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)"); 560848b8605Smrg return GL_FALSE; 561848b8605Smrg } 562848b8605Smrg 563848b8605Smrg if (access != GL_READ_ONLY && 564848b8605Smrg access != GL_WRITE_ONLY && 565848b8605Smrg access != GL_READ_WRITE) { 566848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)"); 567848b8605Smrg return GL_FALSE; 568848b8605Smrg } 569848b8605Smrg 570b8e80941Smrg if (!_mesa_is_shader_image_format_supported(ctx, format)) { 571848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)"); 572848b8605Smrg return GL_FALSE; 573848b8605Smrg } 574848b8605Smrg 575848b8605Smrg return GL_TRUE; 576848b8605Smrg} 577848b8605Smrg 578b8e80941Smrgstatic void 579b8e80941Smrgset_image_binding(struct gl_image_unit *u, struct gl_texture_object *texObj, 580b8e80941Smrg GLint level, GLboolean layered, GLint layer, GLenum access, 581b8e80941Smrg GLenum format) 582848b8605Smrg{ 583b8e80941Smrg u->Level = level; 584b8e80941Smrg u->Access = access; 585b8e80941Smrg u->Format = format; 586b8e80941Smrg u->_ActualFormat = _mesa_get_shader_image_format(format); 587b8e80941Smrg 588b8e80941Smrg if (texObj && _mesa_tex_target_is_layered(texObj->Target)) { 589b8e80941Smrg u->Layered = layered; 590b8e80941Smrg u->Layer = layer; 591b8e80941Smrg u->_Layer = (u->Layered ? 0 : u->Layer); 592b8e80941Smrg } else { 593b8e80941Smrg u->Layered = GL_FALSE; 594b8e80941Smrg u->Layer = 0; 595b8e80941Smrg } 596848b8605Smrg 597b8e80941Smrg _mesa_reference_texobj(&u->TexObj, texObj); 598b8e80941Smrg} 599b8e80941Smrg 600b8e80941Smrgstatic void 601b8e80941Smrgbind_image_texture(struct gl_context *ctx, struct gl_texture_object *texObj, 602b8e80941Smrg GLuint unit, GLint level, GLboolean layered, GLint layer, 603b8e80941Smrg GLenum access, GLenum format) 604b8e80941Smrg{ 605b8e80941Smrg struct gl_image_unit *u; 606848b8605Smrg 607848b8605Smrg u = &ctx->ImageUnits[unit]; 608848b8605Smrg 609848b8605Smrg FLUSH_VERTICES(ctx, 0); 610848b8605Smrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 611848b8605Smrg 612b8e80941Smrg set_image_binding(u, texObj, level, layered, layer, access, format); 613b8e80941Smrg} 614848b8605Smrg 615b8e80941Smrgvoid GLAPIENTRY 616b8e80941Smrg_mesa_BindImageTexture_no_error(GLuint unit, GLuint texture, GLint level, 617b8e80941Smrg GLboolean layered, GLint layer, GLenum access, 618b8e80941Smrg GLenum format) 619b8e80941Smrg{ 620b8e80941Smrg struct gl_texture_object *texObj = NULL; 621848b8605Smrg 622b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 623848b8605Smrg 624b8e80941Smrg if (texture) 625b8e80941Smrg texObj = _mesa_lookup_texture(ctx, texture); 626848b8605Smrg 627b8e80941Smrg bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format); 628848b8605Smrg} 629848b8605Smrg 630848b8605Smrgvoid GLAPIENTRY 631b8e80941Smrg_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, 632b8e80941Smrg GLboolean layered, GLint layer, GLenum access, 633b8e80941Smrg GLenum format) 634848b8605Smrg{ 635b8e80941Smrg struct gl_texture_object *texObj = NULL; 636b8e80941Smrg 637848b8605Smrg GET_CURRENT_CONTEXT(ctx); 638848b8605Smrg 639b8e80941Smrg if (!validate_bind_image_texture(ctx, unit, texture, level, layer, access, 640b8e80941Smrg format)) 641848b8605Smrg return; 642848b8605Smrg 643b8e80941Smrg if (texture) { 644b8e80941Smrg texObj = _mesa_lookup_texture(ctx, texture); 645b8e80941Smrg 646b8e80941Smrg if (!texObj) { 647b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)"); 648b8e80941Smrg return; 649b8e80941Smrg } 650b8e80941Smrg 651b8e80941Smrg /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES 652b8e80941Smrg * 3.1 spec: 653848b8605Smrg * 654b8e80941Smrg * "An INVALID_OPERATION error is generated if texture is not the name 655b8e80941Smrg * of an immutable texture object." 656b8e80941Smrg * 657b8e80941Smrg * However note that issue 7 of the GL_OES_texture_buffer spec 658b8e80941Smrg * recognizes that there is no way to create immutable buffer textures, 659b8e80941Smrg * so those are excluded from this requirement. 660848b8605Smrg */ 661b8e80941Smrg if (_mesa_is_gles(ctx) && !texObj->Immutable && 662b8e80941Smrg texObj->Target != GL_TEXTURE_BUFFER) { 663b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 664b8e80941Smrg "glBindImageTexture(!immutable)"); 665b8e80941Smrg return; 666b8e80941Smrg } 667848b8605Smrg } 668848b8605Smrg 669b8e80941Smrg bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format); 670b8e80941Smrg} 671b8e80941Smrg 672b8e80941Smrgstatic ALWAYS_INLINE void 673b8e80941Smrgbind_image_textures(struct gl_context *ctx, GLuint first, GLuint count, 674b8e80941Smrg const GLuint *textures, bool no_error) 675b8e80941Smrg{ 676b8e80941Smrg int i; 677b8e80941Smrg 678848b8605Smrg /* Assume that at least one binding will be changed */ 679848b8605Smrg FLUSH_VERTICES(ctx, 0); 680848b8605Smrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 681848b8605Smrg 682848b8605Smrg /* Note that the error semantics for multi-bind commands differ from 683848b8605Smrg * those of other GL commands. 684848b8605Smrg * 685848b8605Smrg * The Issues section in the ARB_multi_bind spec says: 686848b8605Smrg * 687848b8605Smrg * "(11) Typically, OpenGL specifies that if an error is generated by 688848b8605Smrg * a command, that command has no effect. This is somewhat 689848b8605Smrg * unfortunate for multi-bind commands, because it would require 690848b8605Smrg * a first pass to scan the entire list of bound objects for 691848b8605Smrg * errors and then a second pass to actually perform the 692848b8605Smrg * bindings. Should we have different error semantics? 693848b8605Smrg * 694848b8605Smrg * RESOLVED: Yes. In this specification, when the parameters for 695848b8605Smrg * one of the <count> binding points are invalid, that binding 696848b8605Smrg * point is not updated and an error will be generated. However, 697848b8605Smrg * other binding points in the same command will be updated if 698848b8605Smrg * their parameters are valid and no other error occurs." 699848b8605Smrg */ 700848b8605Smrg 701b8e80941Smrg _mesa_HashLockMutex(ctx->Shared->TexObjects); 702848b8605Smrg 703848b8605Smrg for (i = 0; i < count; i++) { 704848b8605Smrg struct gl_image_unit *u = &ctx->ImageUnits[first + i]; 705848b8605Smrg const GLuint texture = textures ? textures[i] : 0; 706848b8605Smrg 707b8e80941Smrg if (texture) { 708b8e80941Smrg struct gl_texture_object *texObj = u->TexObj; 709b8e80941Smrg GLenum tex_format; 710848b8605Smrg 711b8e80941Smrg if (!texObj || texObj->Name != texture) { 712848b8605Smrg texObj = _mesa_lookup_texture_locked(ctx, texture); 713b8e80941Smrg if (!no_error && !texObj) { 714848b8605Smrg /* The ARB_multi_bind spec says: 715848b8605Smrg * 716848b8605Smrg * "An INVALID_OPERATION error is generated if any value 717848b8605Smrg * in <textures> is not zero or the name of an existing 718848b8605Smrg * texture object (per binding)." 719848b8605Smrg */ 720848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 721848b8605Smrg "glBindImageTextures(textures[%d]=%u " 722848b8605Smrg "is not zero or the name of an existing texture " 723848b8605Smrg "object)", i, texture); 724848b8605Smrg continue; 725848b8605Smrg } 726848b8605Smrg } 727848b8605Smrg 728b8e80941Smrg if (texObj->Target == GL_TEXTURE_BUFFER) { 729b8e80941Smrg tex_format = texObj->BufferObjectFormat; 730b8e80941Smrg } else { 731b8e80941Smrg struct gl_texture_image *image = texObj->Image[0][0]; 732848b8605Smrg 733b8e80941Smrg if (!no_error && (!image || image->Width == 0 || 734b8e80941Smrg image->Height == 0 || image->Depth == 0)) { 735b8e80941Smrg /* The ARB_multi_bind spec says: 736b8e80941Smrg * 737b8e80941Smrg * "An INVALID_OPERATION error is generated if the width, 738b8e80941Smrg * height, or depth of the level zero texture image of 739b8e80941Smrg * any texture in <textures> is zero (per binding)." 740b8e80941Smrg */ 741b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 742b8e80941Smrg "glBindImageTextures(the width, height or depth " 743b8e80941Smrg "of the level zero texture image of " 744b8e80941Smrg "textures[%d]=%u is zero)", i, texture); 745b8e80941Smrg continue; 746b8e80941Smrg } 747848b8605Smrg 748b8e80941Smrg tex_format = image->InternalFormat; 749b8e80941Smrg } 750848b8605Smrg 751b8e80941Smrg if (!no_error && 752b8e80941Smrg !_mesa_is_shader_image_format_supported(ctx, tex_format)) { 753848b8605Smrg /* The ARB_multi_bind spec says: 754848b8605Smrg * 755848b8605Smrg * "An INVALID_OPERATION error is generated if the internal 756848b8605Smrg * format of the level zero texture image of any texture 757848b8605Smrg * in <textures> is not found in table 8.33 (per binding)." 758848b8605Smrg */ 759848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 760848b8605Smrg "glBindImageTextures(the internal format %s of " 761848b8605Smrg "the level zero texture image of textures[%d]=%u " 762848b8605Smrg "is not supported)", 763b8e80941Smrg _mesa_enum_to_string(tex_format), 764848b8605Smrg i, texture); 765848b8605Smrg continue; 766848b8605Smrg } 767848b8605Smrg 768848b8605Smrg /* Update the texture binding */ 769b8e80941Smrg set_image_binding(u, texObj, 0, 770b8e80941Smrg _mesa_tex_target_is_layered(texObj->Target), 771b8e80941Smrg 0, GL_READ_WRITE, tex_format); 772848b8605Smrg } else { 773848b8605Smrg /* Unbind the texture from the unit */ 774b8e80941Smrg set_image_binding(u, NULL, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8); 775848b8605Smrg } 776848b8605Smrg } 777848b8605Smrg 778b8e80941Smrg _mesa_HashUnlockMutex(ctx->Shared->TexObjects); 779848b8605Smrg} 780848b8605Smrg 781848b8605Smrgvoid GLAPIENTRY 782b8e80941Smrg_mesa_BindImageTextures_no_error(GLuint first, GLsizei count, 783b8e80941Smrg const GLuint *textures) 784848b8605Smrg{ 785848b8605Smrg GET_CURRENT_CONTEXT(ctx); 786848b8605Smrg 787b8e80941Smrg bind_image_textures(ctx, first, count, textures, true); 788b8e80941Smrg} 789b8e80941Smrg 790b8e80941Smrgvoid GLAPIENTRY 791b8e80941Smrg_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures) 792b8e80941Smrg{ 793b8e80941Smrg GET_CURRENT_CONTEXT(ctx); 794b8e80941Smrg 795b8e80941Smrg if (!ctx->Extensions.ARB_shader_image_load_store) { 796b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()"); 797b8e80941Smrg return; 798b8e80941Smrg } 799b8e80941Smrg 800b8e80941Smrg if (first + count > ctx->Const.MaxImageUnits) { 801b8e80941Smrg /* The ARB_multi_bind spec says: 802b8e80941Smrg * 803b8e80941Smrg * "An INVALID_OPERATION error is generated if <first> + <count> 804b8e80941Smrg * is greater than the number of image units supported by 805b8e80941Smrg * the implementation." 806b8e80941Smrg */ 807b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 808b8e80941Smrg "glBindImageTextures(first=%u + count=%d > the value of " 809b8e80941Smrg "GL_MAX_IMAGE_UNITS=%u)", 810b8e80941Smrg first, count, ctx->Const.MaxImageUnits); 811b8e80941Smrg return; 812b8e80941Smrg } 813b8e80941Smrg 814b8e80941Smrg bind_image_textures(ctx, first, count, textures, false); 815848b8605Smrg} 816