shaderimage.c revision 01e04c3f
1af69d88dSmrg/* 2af69d88dSmrg * Copyright 2013 Intel Corporation 3af69d88dSmrg * 4af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5af69d88dSmrg * copy of this software and associated documentation files (the "Software"), 6af69d88dSmrg * to deal in the Software without restriction, including without limitation 7af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9af69d88dSmrg * Software is furnished to do so, subject to the following conditions: 10af69d88dSmrg * 11af69d88dSmrg * The above copyright notice and this permission notice (including the next 12af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the 13af69d88dSmrg * Software. 14af69d88dSmrg * 15af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21af69d88dSmrg * DEALINGS IN THE SOFTWARE. 22af69d88dSmrg * 23af69d88dSmrg * Authors: 24af69d88dSmrg * Francisco Jerez <currojerez@riseup.net> 25af69d88dSmrg */ 26af69d88dSmrg 27af69d88dSmrg#include <assert.h> 28af69d88dSmrg 29af69d88dSmrg#include "shaderimage.h" 30af69d88dSmrg#include "mtypes.h" 31af69d88dSmrg#include "formats.h" 32af69d88dSmrg#include "errors.h" 3301e04c3fSmrg#include "hash.h" 34af69d88dSmrg#include "context.h" 35af69d88dSmrg#include "texobj.h" 36af69d88dSmrg#include "teximage.h" 37af69d88dSmrg#include "enums.h" 38af69d88dSmrg 39af69d88dSmrg/* 40af69d88dSmrg * Define endian-invariant aliases for some mesa formats that are 41af69d88dSmrg * defined in terms of their channel layout from LSB to MSB in a 42af69d88dSmrg * 32-bit word. The actual byte offsets matter here because the user 43af69d88dSmrg * is allowed to bit-cast one format into another and get predictable 44af69d88dSmrg * results. 45af69d88dSmrg */ 46af69d88dSmrg#ifdef MESA_BIG_ENDIAN 47af69d88dSmrg# define MESA_FORMAT_RGBA_8 MESA_FORMAT_A8B8G8R8_UNORM 48af69d88dSmrg# define MESA_FORMAT_RG_16 MESA_FORMAT_G16R16_UNORM 49af69d88dSmrg# define MESA_FORMAT_RG_8 MESA_FORMAT_G8R8_UNORM 50af69d88dSmrg# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_A8B8G8R8_SNORM 51af69d88dSmrg# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_G16R16_SNORM 52af69d88dSmrg# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_G8R8_SNORM 53af69d88dSmrg#else 54af69d88dSmrg# define MESA_FORMAT_RGBA_8 MESA_FORMAT_R8G8B8A8_UNORM 55af69d88dSmrg# define MESA_FORMAT_RG_16 MESA_FORMAT_R16G16_UNORM 56af69d88dSmrg# define MESA_FORMAT_RG_8 MESA_FORMAT_R8G8_UNORM 57af69d88dSmrg# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_R8G8B8A8_SNORM 58af69d88dSmrg# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_R16G16_SNORM 59af69d88dSmrg# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_R8G8_SNORM 60af69d88dSmrg#endif 61af69d88dSmrg 6201e04c3fSmrgmesa_format 6301e04c3fSmrg_mesa_get_shader_image_format(GLenum format) 64af69d88dSmrg{ 65af69d88dSmrg switch (format) { 66af69d88dSmrg case GL_RGBA32F: 67af69d88dSmrg return MESA_FORMAT_RGBA_FLOAT32; 68af69d88dSmrg 69af69d88dSmrg case GL_RGBA16F: 70af69d88dSmrg return MESA_FORMAT_RGBA_FLOAT16; 71af69d88dSmrg 72af69d88dSmrg case GL_RG32F: 73af69d88dSmrg return MESA_FORMAT_RG_FLOAT32; 74af69d88dSmrg 75af69d88dSmrg case GL_RG16F: 76af69d88dSmrg return MESA_FORMAT_RG_FLOAT16; 77af69d88dSmrg 78af69d88dSmrg case GL_R11F_G11F_B10F: 79af69d88dSmrg return MESA_FORMAT_R11G11B10_FLOAT; 80af69d88dSmrg 81af69d88dSmrg case GL_R32F: 82af69d88dSmrg return MESA_FORMAT_R_FLOAT32; 83af69d88dSmrg 84af69d88dSmrg case GL_R16F: 85af69d88dSmrg return MESA_FORMAT_R_FLOAT16; 86af69d88dSmrg 87af69d88dSmrg case GL_RGBA32UI: 88af69d88dSmrg return MESA_FORMAT_RGBA_UINT32; 89af69d88dSmrg 90af69d88dSmrg case GL_RGBA16UI: 91af69d88dSmrg return MESA_FORMAT_RGBA_UINT16; 92af69d88dSmrg 93af69d88dSmrg case GL_RGB10_A2UI: 94af69d88dSmrg return MESA_FORMAT_R10G10B10A2_UINT; 95af69d88dSmrg 96af69d88dSmrg case GL_RGBA8UI: 97af69d88dSmrg return MESA_FORMAT_RGBA_UINT8; 98af69d88dSmrg 99af69d88dSmrg case GL_RG32UI: 100af69d88dSmrg return MESA_FORMAT_RG_UINT32; 101af69d88dSmrg 102af69d88dSmrg case GL_RG16UI: 103af69d88dSmrg return MESA_FORMAT_RG_UINT16; 104af69d88dSmrg 105af69d88dSmrg case GL_RG8UI: 106af69d88dSmrg return MESA_FORMAT_RG_UINT8; 107af69d88dSmrg 108af69d88dSmrg case GL_R32UI: 109af69d88dSmrg return MESA_FORMAT_R_UINT32; 110af69d88dSmrg 111af69d88dSmrg case GL_R16UI: 112af69d88dSmrg return MESA_FORMAT_R_UINT16; 113af69d88dSmrg 114af69d88dSmrg case GL_R8UI: 115af69d88dSmrg return MESA_FORMAT_R_UINT8; 116af69d88dSmrg 117af69d88dSmrg case GL_RGBA32I: 118af69d88dSmrg return MESA_FORMAT_RGBA_SINT32; 119af69d88dSmrg 120af69d88dSmrg case GL_RGBA16I: 121af69d88dSmrg return MESA_FORMAT_RGBA_SINT16; 122af69d88dSmrg 123af69d88dSmrg case GL_RGBA8I: 124af69d88dSmrg return MESA_FORMAT_RGBA_SINT8; 125af69d88dSmrg 126af69d88dSmrg case GL_RG32I: 127af69d88dSmrg return MESA_FORMAT_RG_SINT32; 128af69d88dSmrg 129af69d88dSmrg case GL_RG16I: 130af69d88dSmrg return MESA_FORMAT_RG_SINT16; 131af69d88dSmrg 132af69d88dSmrg case GL_RG8I: 133af69d88dSmrg return MESA_FORMAT_RG_SINT8; 134af69d88dSmrg 135af69d88dSmrg case GL_R32I: 136af69d88dSmrg return MESA_FORMAT_R_SINT32; 137af69d88dSmrg 138af69d88dSmrg case GL_R16I: 139af69d88dSmrg return MESA_FORMAT_R_SINT16; 140af69d88dSmrg 141af69d88dSmrg case GL_R8I: 142af69d88dSmrg return MESA_FORMAT_R_SINT8; 143af69d88dSmrg 144af69d88dSmrg case GL_RGBA16: 145af69d88dSmrg return MESA_FORMAT_RGBA_UNORM16; 146af69d88dSmrg 147af69d88dSmrg case GL_RGB10_A2: 148af69d88dSmrg return MESA_FORMAT_R10G10B10A2_UNORM; 149af69d88dSmrg 150af69d88dSmrg case GL_RGBA8: 151af69d88dSmrg return MESA_FORMAT_RGBA_8; 152af69d88dSmrg 153af69d88dSmrg case GL_RG16: 154af69d88dSmrg return MESA_FORMAT_RG_16; 155af69d88dSmrg 156af69d88dSmrg case GL_RG8: 157af69d88dSmrg return MESA_FORMAT_RG_8; 158af69d88dSmrg 159af69d88dSmrg case GL_R16: 160af69d88dSmrg return MESA_FORMAT_R_UNORM16; 161af69d88dSmrg 162af69d88dSmrg case GL_R8: 163af69d88dSmrg return MESA_FORMAT_R_UNORM8; 164af69d88dSmrg 165af69d88dSmrg case GL_RGBA16_SNORM: 166af69d88dSmrg return MESA_FORMAT_RGBA_SNORM16; 167af69d88dSmrg 168af69d88dSmrg case GL_RGBA8_SNORM: 169af69d88dSmrg return MESA_FORMAT_SIGNED_RGBA_8; 170af69d88dSmrg 171af69d88dSmrg case GL_RG16_SNORM: 172af69d88dSmrg return MESA_FORMAT_SIGNED_RG_16; 173af69d88dSmrg 174af69d88dSmrg case GL_RG8_SNORM: 175af69d88dSmrg return MESA_FORMAT_SIGNED_RG_8; 176af69d88dSmrg 177af69d88dSmrg case GL_R16_SNORM: 178af69d88dSmrg return MESA_FORMAT_R_SNORM16; 179af69d88dSmrg 180af69d88dSmrg case GL_R8_SNORM: 181af69d88dSmrg return MESA_FORMAT_R_SNORM8; 182af69d88dSmrg 183af69d88dSmrg default: 184af69d88dSmrg return MESA_FORMAT_NONE; 185af69d88dSmrg } 186af69d88dSmrg} 187af69d88dSmrg 188af69d88dSmrgenum image_format_class 189af69d88dSmrg{ 190af69d88dSmrg /** Not a valid image format. */ 191af69d88dSmrg IMAGE_FORMAT_CLASS_NONE = 0, 192af69d88dSmrg 193af69d88dSmrg /** Classes of image formats you can cast into each other. */ 194af69d88dSmrg /** \{ */ 195af69d88dSmrg IMAGE_FORMAT_CLASS_1X8, 196af69d88dSmrg IMAGE_FORMAT_CLASS_1X16, 197af69d88dSmrg IMAGE_FORMAT_CLASS_1X32, 198af69d88dSmrg IMAGE_FORMAT_CLASS_2X8, 199af69d88dSmrg IMAGE_FORMAT_CLASS_2X16, 200af69d88dSmrg IMAGE_FORMAT_CLASS_2X32, 201af69d88dSmrg IMAGE_FORMAT_CLASS_10_11_11, 202af69d88dSmrg IMAGE_FORMAT_CLASS_4X8, 203af69d88dSmrg IMAGE_FORMAT_CLASS_4X16, 204af69d88dSmrg IMAGE_FORMAT_CLASS_4X32, 205af69d88dSmrg IMAGE_FORMAT_CLASS_2_10_10_10 206af69d88dSmrg /** \} */ 207af69d88dSmrg}; 208af69d88dSmrg 209af69d88dSmrgstatic enum image_format_class 210af69d88dSmrgget_image_format_class(mesa_format format) 211af69d88dSmrg{ 212af69d88dSmrg switch (format) { 213af69d88dSmrg case MESA_FORMAT_RGBA_FLOAT32: 214af69d88dSmrg return IMAGE_FORMAT_CLASS_4X32; 215af69d88dSmrg 216af69d88dSmrg case MESA_FORMAT_RGBA_FLOAT16: 217af69d88dSmrg return IMAGE_FORMAT_CLASS_4X16; 218af69d88dSmrg 219af69d88dSmrg case MESA_FORMAT_RG_FLOAT32: 220af69d88dSmrg return IMAGE_FORMAT_CLASS_2X32; 221af69d88dSmrg 222af69d88dSmrg case MESA_FORMAT_RG_FLOAT16: 223af69d88dSmrg return IMAGE_FORMAT_CLASS_2X16; 224af69d88dSmrg 225af69d88dSmrg case MESA_FORMAT_R11G11B10_FLOAT: 226af69d88dSmrg return IMAGE_FORMAT_CLASS_10_11_11; 227af69d88dSmrg 228af69d88dSmrg case MESA_FORMAT_R_FLOAT32: 229af69d88dSmrg return IMAGE_FORMAT_CLASS_1X32; 230af69d88dSmrg 231af69d88dSmrg case MESA_FORMAT_R_FLOAT16: 232af69d88dSmrg return IMAGE_FORMAT_CLASS_1X16; 233af69d88dSmrg 234af69d88dSmrg case MESA_FORMAT_RGBA_UINT32: 235af69d88dSmrg return IMAGE_FORMAT_CLASS_4X32; 236af69d88dSmrg 237af69d88dSmrg case MESA_FORMAT_RGBA_UINT16: 238af69d88dSmrg return IMAGE_FORMAT_CLASS_4X16; 239af69d88dSmrg 240af69d88dSmrg case MESA_FORMAT_R10G10B10A2_UINT: 241af69d88dSmrg return IMAGE_FORMAT_CLASS_2_10_10_10; 242af69d88dSmrg 243af69d88dSmrg case MESA_FORMAT_RGBA_UINT8: 244af69d88dSmrg return IMAGE_FORMAT_CLASS_4X8; 245af69d88dSmrg 246af69d88dSmrg case MESA_FORMAT_RG_UINT32: 247af69d88dSmrg return IMAGE_FORMAT_CLASS_2X32; 248af69d88dSmrg 249af69d88dSmrg case MESA_FORMAT_RG_UINT16: 250af69d88dSmrg return IMAGE_FORMAT_CLASS_2X16; 251af69d88dSmrg 252af69d88dSmrg case MESA_FORMAT_RG_UINT8: 253af69d88dSmrg return IMAGE_FORMAT_CLASS_2X8; 254af69d88dSmrg 255af69d88dSmrg case MESA_FORMAT_R_UINT32: 256af69d88dSmrg return IMAGE_FORMAT_CLASS_1X32; 257af69d88dSmrg 258af69d88dSmrg case MESA_FORMAT_R_UINT16: 259af69d88dSmrg return IMAGE_FORMAT_CLASS_1X16; 260af69d88dSmrg 261af69d88dSmrg case MESA_FORMAT_R_UINT8: 262af69d88dSmrg return IMAGE_FORMAT_CLASS_1X8; 263af69d88dSmrg 264af69d88dSmrg case MESA_FORMAT_RGBA_SINT32: 265af69d88dSmrg return IMAGE_FORMAT_CLASS_4X32; 266af69d88dSmrg 267af69d88dSmrg case MESA_FORMAT_RGBA_SINT16: 268af69d88dSmrg return IMAGE_FORMAT_CLASS_4X16; 269af69d88dSmrg 270af69d88dSmrg case MESA_FORMAT_RGBA_SINT8: 271af69d88dSmrg return IMAGE_FORMAT_CLASS_4X8; 272af69d88dSmrg 273af69d88dSmrg case MESA_FORMAT_RG_SINT32: 274af69d88dSmrg return IMAGE_FORMAT_CLASS_2X32; 275af69d88dSmrg 276af69d88dSmrg case MESA_FORMAT_RG_SINT16: 277af69d88dSmrg return IMAGE_FORMAT_CLASS_2X16; 278af69d88dSmrg 279af69d88dSmrg case MESA_FORMAT_RG_SINT8: 280af69d88dSmrg return IMAGE_FORMAT_CLASS_2X8; 281af69d88dSmrg 282af69d88dSmrg case MESA_FORMAT_R_SINT32: 283af69d88dSmrg return IMAGE_FORMAT_CLASS_1X32; 284af69d88dSmrg 285af69d88dSmrg case MESA_FORMAT_R_SINT16: 286af69d88dSmrg return IMAGE_FORMAT_CLASS_1X16; 287af69d88dSmrg 288af69d88dSmrg case MESA_FORMAT_R_SINT8: 289af69d88dSmrg return IMAGE_FORMAT_CLASS_1X8; 290af69d88dSmrg 291af69d88dSmrg case MESA_FORMAT_RGBA_UNORM16: 292af69d88dSmrg return IMAGE_FORMAT_CLASS_4X16; 293af69d88dSmrg 294af69d88dSmrg case MESA_FORMAT_R10G10B10A2_UNORM: 295af69d88dSmrg return IMAGE_FORMAT_CLASS_2_10_10_10; 296af69d88dSmrg 297af69d88dSmrg case MESA_FORMAT_RGBA_8: 298af69d88dSmrg return IMAGE_FORMAT_CLASS_4X8; 299af69d88dSmrg 300af69d88dSmrg case MESA_FORMAT_RG_16: 301af69d88dSmrg return IMAGE_FORMAT_CLASS_2X16; 302af69d88dSmrg 303af69d88dSmrg case MESA_FORMAT_RG_8: 304af69d88dSmrg return IMAGE_FORMAT_CLASS_2X8; 305af69d88dSmrg 306af69d88dSmrg case MESA_FORMAT_R_UNORM16: 307af69d88dSmrg return IMAGE_FORMAT_CLASS_1X16; 308af69d88dSmrg 309af69d88dSmrg case MESA_FORMAT_R_UNORM8: 310af69d88dSmrg return IMAGE_FORMAT_CLASS_1X8; 311af69d88dSmrg 312af69d88dSmrg case MESA_FORMAT_RGBA_SNORM16: 313af69d88dSmrg return IMAGE_FORMAT_CLASS_4X16; 314af69d88dSmrg 315af69d88dSmrg case MESA_FORMAT_SIGNED_RGBA_8: 316af69d88dSmrg return IMAGE_FORMAT_CLASS_4X8; 317af69d88dSmrg 318af69d88dSmrg case MESA_FORMAT_SIGNED_RG_16: 319af69d88dSmrg return IMAGE_FORMAT_CLASS_2X16; 320af69d88dSmrg 321af69d88dSmrg case MESA_FORMAT_SIGNED_RG_8: 322af69d88dSmrg return IMAGE_FORMAT_CLASS_2X8; 323af69d88dSmrg 324af69d88dSmrg case MESA_FORMAT_R_SNORM16: 325af69d88dSmrg return IMAGE_FORMAT_CLASS_1X16; 326af69d88dSmrg 327af69d88dSmrg case MESA_FORMAT_R_SNORM8: 328af69d88dSmrg return IMAGE_FORMAT_CLASS_1X8; 329af69d88dSmrg 330af69d88dSmrg default: 331af69d88dSmrg return IMAGE_FORMAT_CLASS_NONE; 332af69d88dSmrg } 333af69d88dSmrg} 334af69d88dSmrg 33501e04c3fSmrgstatic GLenum 33601e04c3fSmrg_image_format_class_to_glenum(enum image_format_class class) 33701e04c3fSmrg{ 33801e04c3fSmrg switch (class) { 33901e04c3fSmrg case IMAGE_FORMAT_CLASS_NONE: 34001e04c3fSmrg return GL_NONE; 34101e04c3fSmrg case IMAGE_FORMAT_CLASS_1X8: 34201e04c3fSmrg return GL_IMAGE_CLASS_1_X_8; 34301e04c3fSmrg case IMAGE_FORMAT_CLASS_1X16: 34401e04c3fSmrg return GL_IMAGE_CLASS_1_X_16; 34501e04c3fSmrg case IMAGE_FORMAT_CLASS_1X32: 34601e04c3fSmrg return GL_IMAGE_CLASS_1_X_32; 34701e04c3fSmrg case IMAGE_FORMAT_CLASS_2X8: 34801e04c3fSmrg return GL_IMAGE_CLASS_2_X_8; 34901e04c3fSmrg case IMAGE_FORMAT_CLASS_2X16: 35001e04c3fSmrg return GL_IMAGE_CLASS_2_X_16; 35101e04c3fSmrg case IMAGE_FORMAT_CLASS_2X32: 35201e04c3fSmrg return GL_IMAGE_CLASS_2_X_32; 35301e04c3fSmrg case IMAGE_FORMAT_CLASS_10_11_11: 35401e04c3fSmrg return GL_IMAGE_CLASS_11_11_10; 35501e04c3fSmrg case IMAGE_FORMAT_CLASS_4X8: 35601e04c3fSmrg return GL_IMAGE_CLASS_4_X_8; 35701e04c3fSmrg case IMAGE_FORMAT_CLASS_4X16: 35801e04c3fSmrg return GL_IMAGE_CLASS_4_X_16; 35901e04c3fSmrg case IMAGE_FORMAT_CLASS_4X32: 36001e04c3fSmrg return GL_IMAGE_CLASS_4_X_32; 36101e04c3fSmrg case IMAGE_FORMAT_CLASS_2_10_10_10: 36201e04c3fSmrg return GL_IMAGE_CLASS_10_10_10_2; 36301e04c3fSmrg default: 36401e04c3fSmrg assert(!"Invalid image_format_class"); 36501e04c3fSmrg return GL_NONE; 36601e04c3fSmrg } 36701e04c3fSmrg} 36801e04c3fSmrg 36901e04c3fSmrgGLenum 37001e04c3fSmrg_mesa_get_image_format_class(GLenum format) 37101e04c3fSmrg{ 37201e04c3fSmrg mesa_format tex_format = _mesa_get_shader_image_format(format); 37301e04c3fSmrg if (tex_format == MESA_FORMAT_NONE) 37401e04c3fSmrg return GL_NONE; 37501e04c3fSmrg 37601e04c3fSmrg enum image_format_class class = get_image_format_class(tex_format); 37701e04c3fSmrg return _image_format_class_to_glenum(class); 37801e04c3fSmrg} 37901e04c3fSmrg 38001e04c3fSmrgbool 38101e04c3fSmrg_mesa_is_shader_image_format_supported(const struct gl_context *ctx, 38201e04c3fSmrg GLenum format) 38301e04c3fSmrg{ 38401e04c3fSmrg switch (format) { 38501e04c3fSmrg /* Formats supported on both desktop and ES GL, c.f. table 8.27 of the 38601e04c3fSmrg * OpenGL ES 3.1 specification. 38701e04c3fSmrg */ 38801e04c3fSmrg case GL_RGBA32F: 38901e04c3fSmrg case GL_RGBA16F: 39001e04c3fSmrg case GL_R32F: 39101e04c3fSmrg case GL_RGBA32UI: 39201e04c3fSmrg case GL_RGBA16UI: 39301e04c3fSmrg case GL_RGBA8UI: 39401e04c3fSmrg case GL_R32UI: 39501e04c3fSmrg case GL_RGBA32I: 39601e04c3fSmrg case GL_RGBA16I: 39701e04c3fSmrg case GL_RGBA8I: 39801e04c3fSmrg case GL_R32I: 39901e04c3fSmrg case GL_RGBA8: 40001e04c3fSmrg case GL_RGBA8_SNORM: 40101e04c3fSmrg return true; 40201e04c3fSmrg 40301e04c3fSmrg /* Formats supported on unextended desktop GL and the original 40401e04c3fSmrg * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2 40501e04c3fSmrg * specification or by GLES 3.1 with GL_NV_image_formats extension. 40601e04c3fSmrg */ 40701e04c3fSmrg case GL_RG32F: 40801e04c3fSmrg case GL_RG16F: 40901e04c3fSmrg case GL_R11F_G11F_B10F: 41001e04c3fSmrg case GL_R16F: 41101e04c3fSmrg case GL_RGB10_A2UI: 41201e04c3fSmrg case GL_RG32UI: 41301e04c3fSmrg case GL_RG16UI: 41401e04c3fSmrg case GL_RG8UI: 41501e04c3fSmrg case GL_R16UI: 41601e04c3fSmrg case GL_R8UI: 41701e04c3fSmrg case GL_RG32I: 41801e04c3fSmrg case GL_RG16I: 41901e04c3fSmrg case GL_RG8I: 42001e04c3fSmrg case GL_R16I: 42101e04c3fSmrg case GL_R8I: 42201e04c3fSmrg case GL_RGB10_A2: 42301e04c3fSmrg case GL_RG8: 42401e04c3fSmrg case GL_R8: 42501e04c3fSmrg case GL_RG8_SNORM: 42601e04c3fSmrg case GL_R8_SNORM: 42701e04c3fSmrg return true; 42801e04c3fSmrg 42901e04c3fSmrg /* Formats supported on unextended desktop GL and the original 43001e04c3fSmrg * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2 43101e04c3fSmrg * specification. 43201e04c3fSmrg * 43301e04c3fSmrg * Following formats are supported by GLES 3.1 with GL_NV_image_formats & 43401e04c3fSmrg * GL_EXT_texture_norm16 extensions. 43501e04c3fSmrg */ 43601e04c3fSmrg case GL_RGBA16: 43701e04c3fSmrg case GL_RGBA16_SNORM: 43801e04c3fSmrg case GL_RG16: 43901e04c3fSmrg case GL_RG16_SNORM: 44001e04c3fSmrg case GL_R16: 44101e04c3fSmrg case GL_R16_SNORM: 44201e04c3fSmrg return _mesa_is_desktop_gl(ctx) || _mesa_has_EXT_texture_norm16(ctx); 44301e04c3fSmrg 44401e04c3fSmrg default: 44501e04c3fSmrg return false; 44601e04c3fSmrg } 44701e04c3fSmrg} 44801e04c3fSmrg 44901e04c3fSmrgstruct gl_image_unit 45001e04c3fSmrg_mesa_default_image_unit(struct gl_context *ctx) 45101e04c3fSmrg{ 45201e04c3fSmrg const GLenum format = _mesa_is_desktop_gl(ctx) ? GL_R8 : GL_R32UI; 45301e04c3fSmrg const struct gl_image_unit u = { 45401e04c3fSmrg .Access = GL_READ_ONLY, 45501e04c3fSmrg .Format = format, 45601e04c3fSmrg ._ActualFormat = _mesa_get_shader_image_format(format) 45701e04c3fSmrg }; 45801e04c3fSmrg return u; 45901e04c3fSmrg} 46001e04c3fSmrg 46101e04c3fSmrgvoid 46201e04c3fSmrg_mesa_init_image_units(struct gl_context *ctx) 46301e04c3fSmrg{ 46401e04c3fSmrg unsigned i; 46501e04c3fSmrg 46601e04c3fSmrg ASSERT_BITFIELD_SIZE(struct gl_image_unit, Format, MESA_FORMAT_COUNT); 46701e04c3fSmrg 46801e04c3fSmrg for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i) 46901e04c3fSmrg ctx->ImageUnits[i] = _mesa_default_image_unit(ctx); 47001e04c3fSmrg} 47101e04c3fSmrg 47201e04c3fSmrgGLboolean 47301e04c3fSmrg_mesa_is_image_unit_valid(struct gl_context *ctx, struct gl_image_unit *u) 474af69d88dSmrg{ 475af69d88dSmrg struct gl_texture_object *t = u->TexObj; 47601e04c3fSmrg mesa_format tex_format; 477af69d88dSmrg 47801e04c3fSmrg if (!t) 479af69d88dSmrg return GL_FALSE; 480af69d88dSmrg 48101e04c3fSmrg if (!t->_BaseComplete && !t->_MipmapComplete) 48201e04c3fSmrg _mesa_test_texobj_completeness(ctx, t); 483af69d88dSmrg 48401e04c3fSmrg if (u->Level < t->BaseLevel || 48501e04c3fSmrg u->Level > t->_MaxLevel || 48601e04c3fSmrg (u->Level == t->BaseLevel && !t->_BaseComplete) || 487af69d88dSmrg (u->Level != t->BaseLevel && !t->_MipmapComplete)) 488af69d88dSmrg return GL_FALSE; 489af69d88dSmrg 490af69d88dSmrg if (_mesa_tex_target_is_layered(t->Target) && 49101e04c3fSmrg u->_Layer >= _mesa_get_texture_layers(t, u->Level)) 492af69d88dSmrg return GL_FALSE; 493af69d88dSmrg 49401e04c3fSmrg if (t->Target == GL_TEXTURE_BUFFER) { 49501e04c3fSmrg tex_format = _mesa_get_shader_image_format(t->BufferObjectFormat); 49601e04c3fSmrg 49701e04c3fSmrg } else { 49801e04c3fSmrg struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ? 49901e04c3fSmrg t->Image[u->_Layer][u->Level] : 50001e04c3fSmrg t->Image[0][u->Level]); 50101e04c3fSmrg 50201e04c3fSmrg if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples) 50301e04c3fSmrg return GL_FALSE; 50401e04c3fSmrg 50501e04c3fSmrg tex_format = _mesa_get_shader_image_format(img->InternalFormat); 50601e04c3fSmrg } 507af69d88dSmrg 50801e04c3fSmrg if (!tex_format) 509af69d88dSmrg return GL_FALSE; 510af69d88dSmrg 511af69d88dSmrg switch (t->ImageFormatCompatibilityType) { 512af69d88dSmrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE: 51301e04c3fSmrg if (_mesa_get_format_bytes(tex_format) != 514af69d88dSmrg _mesa_get_format_bytes(u->_ActualFormat)) 515af69d88dSmrg return GL_FALSE; 516af69d88dSmrg break; 517af69d88dSmrg 518af69d88dSmrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS: 51901e04c3fSmrg if (get_image_format_class(tex_format) != 520af69d88dSmrg get_image_format_class(u->_ActualFormat)) 521af69d88dSmrg return GL_FALSE; 522af69d88dSmrg break; 523af69d88dSmrg 524af69d88dSmrg default: 525af69d88dSmrg assert(!"Unexpected image format compatibility type"); 526af69d88dSmrg } 527af69d88dSmrg 528af69d88dSmrg return GL_TRUE; 529af69d88dSmrg} 530af69d88dSmrg 531af69d88dSmrgstatic GLboolean 532af69d88dSmrgvalidate_bind_image_texture(struct gl_context *ctx, GLuint unit, 53301e04c3fSmrg GLuint texture, GLint level, GLint layer, 53401e04c3fSmrg GLenum access, GLenum format) 535af69d88dSmrg{ 536af69d88dSmrg assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); 537af69d88dSmrg 538af69d88dSmrg if (unit >= ctx->Const.MaxImageUnits) { 539af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)"); 540af69d88dSmrg return GL_FALSE; 541af69d88dSmrg } 542af69d88dSmrg 543af69d88dSmrg if (level < 0) { 544af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)"); 545af69d88dSmrg return GL_FALSE; 546af69d88dSmrg } 547af69d88dSmrg 548af69d88dSmrg if (layer < 0) { 549af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)"); 550af69d88dSmrg return GL_FALSE; 551af69d88dSmrg } 552af69d88dSmrg 553af69d88dSmrg if (access != GL_READ_ONLY && 554af69d88dSmrg access != GL_WRITE_ONLY && 555af69d88dSmrg access != GL_READ_WRITE) { 556af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)"); 557af69d88dSmrg return GL_FALSE; 558af69d88dSmrg } 559af69d88dSmrg 56001e04c3fSmrg if (!_mesa_is_shader_image_format_supported(ctx, format)) { 561af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)"); 562af69d88dSmrg return GL_FALSE; 563af69d88dSmrg } 564af69d88dSmrg 565af69d88dSmrg return GL_TRUE; 566af69d88dSmrg} 567af69d88dSmrg 56801e04c3fSmrgstatic void 56901e04c3fSmrgset_image_binding(struct gl_image_unit *u, struct gl_texture_object *texObj, 57001e04c3fSmrg GLint level, GLboolean layered, GLint layer, GLenum access, 57101e04c3fSmrg GLenum format) 572af69d88dSmrg{ 57301e04c3fSmrg u->Level = level; 57401e04c3fSmrg u->Access = access; 57501e04c3fSmrg u->Format = format; 57601e04c3fSmrg u->_ActualFormat = _mesa_get_shader_image_format(format); 57701e04c3fSmrg 57801e04c3fSmrg if (texObj && _mesa_tex_target_is_layered(texObj->Target)) { 57901e04c3fSmrg u->Layered = layered; 58001e04c3fSmrg u->Layer = layer; 58101e04c3fSmrg u->_Layer = (u->Layered ? 0 : u->Layer); 58201e04c3fSmrg } else { 58301e04c3fSmrg u->Layered = GL_FALSE; 58401e04c3fSmrg u->Layer = 0; 58501e04c3fSmrg } 586af69d88dSmrg 58701e04c3fSmrg _mesa_reference_texobj(&u->TexObj, texObj); 58801e04c3fSmrg} 58901e04c3fSmrg 59001e04c3fSmrgstatic void 59101e04c3fSmrgbind_image_texture(struct gl_context *ctx, struct gl_texture_object *texObj, 59201e04c3fSmrg GLuint unit, GLint level, GLboolean layered, GLint layer, 59301e04c3fSmrg GLenum access, GLenum format) 59401e04c3fSmrg{ 59501e04c3fSmrg struct gl_image_unit *u; 596af69d88dSmrg 597af69d88dSmrg u = &ctx->ImageUnits[unit]; 598af69d88dSmrg 599af69d88dSmrg FLUSH_VERTICES(ctx, 0); 600af69d88dSmrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 601af69d88dSmrg 60201e04c3fSmrg set_image_binding(u, texObj, level, layered, layer, access, format); 60301e04c3fSmrg} 604af69d88dSmrg 60501e04c3fSmrgvoid GLAPIENTRY 60601e04c3fSmrg_mesa_BindImageTexture_no_error(GLuint unit, GLuint texture, GLint level, 60701e04c3fSmrg GLboolean layered, GLint layer, GLenum access, 60801e04c3fSmrg GLenum format) 60901e04c3fSmrg{ 61001e04c3fSmrg struct gl_texture_object *texObj = NULL; 611af69d88dSmrg 61201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 613af69d88dSmrg 61401e04c3fSmrg if (texture) 61501e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 616af69d88dSmrg 61701e04c3fSmrg bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format); 618af69d88dSmrg} 619af69d88dSmrg 620af69d88dSmrgvoid GLAPIENTRY 62101e04c3fSmrg_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, 62201e04c3fSmrg GLboolean layered, GLint layer, GLenum access, 62301e04c3fSmrg GLenum format) 624af69d88dSmrg{ 62501e04c3fSmrg struct gl_texture_object *texObj = NULL; 62601e04c3fSmrg 627af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 628af69d88dSmrg 62901e04c3fSmrg if (!validate_bind_image_texture(ctx, unit, texture, level, layer, access, 63001e04c3fSmrg format)) 631af69d88dSmrg return; 632af69d88dSmrg 63301e04c3fSmrg if (texture) { 63401e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 63501e04c3fSmrg 63601e04c3fSmrg if (!texObj) { 63701e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)"); 63801e04c3fSmrg return; 63901e04c3fSmrg } 64001e04c3fSmrg 64101e04c3fSmrg /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES 64201e04c3fSmrg * 3.1 spec: 643af69d88dSmrg * 64401e04c3fSmrg * "An INVALID_OPERATION error is generated if texture is not the name 64501e04c3fSmrg * of an immutable texture object." 64601e04c3fSmrg * 64701e04c3fSmrg * However note that issue 7 of the GL_OES_texture_buffer spec 64801e04c3fSmrg * recognizes that there is no way to create immutable buffer textures, 64901e04c3fSmrg * so those are excluded from this requirement. 650af69d88dSmrg */ 65101e04c3fSmrg if (_mesa_is_gles(ctx) && !texObj->Immutable && 65201e04c3fSmrg texObj->Target != GL_TEXTURE_BUFFER) { 65301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 65401e04c3fSmrg "glBindImageTexture(!immutable)"); 65501e04c3fSmrg return; 65601e04c3fSmrg } 657af69d88dSmrg } 658af69d88dSmrg 65901e04c3fSmrg bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format); 66001e04c3fSmrg} 66101e04c3fSmrg 66201e04c3fSmrgstatic ALWAYS_INLINE void 66301e04c3fSmrgbind_image_textures(struct gl_context *ctx, GLuint first, GLuint count, 66401e04c3fSmrg const GLuint *textures, bool no_error) 66501e04c3fSmrg{ 66601e04c3fSmrg int i; 66701e04c3fSmrg 668af69d88dSmrg /* Assume that at least one binding will be changed */ 669af69d88dSmrg FLUSH_VERTICES(ctx, 0); 670af69d88dSmrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 671af69d88dSmrg 672af69d88dSmrg /* Note that the error semantics for multi-bind commands differ from 673af69d88dSmrg * those of other GL commands. 674af69d88dSmrg * 675af69d88dSmrg * The Issues section in the ARB_multi_bind spec says: 676af69d88dSmrg * 677af69d88dSmrg * "(11) Typically, OpenGL specifies that if an error is generated by 678af69d88dSmrg * a command, that command has no effect. This is somewhat 679af69d88dSmrg * unfortunate for multi-bind commands, because it would require 680af69d88dSmrg * a first pass to scan the entire list of bound objects for 681af69d88dSmrg * errors and then a second pass to actually perform the 682af69d88dSmrg * bindings. Should we have different error semantics? 683af69d88dSmrg * 684af69d88dSmrg * RESOLVED: Yes. In this specification, when the parameters for 685af69d88dSmrg * one of the <count> binding points are invalid, that binding 686af69d88dSmrg * point is not updated and an error will be generated. However, 687af69d88dSmrg * other binding points in the same command will be updated if 688af69d88dSmrg * their parameters are valid and no other error occurs." 689af69d88dSmrg */ 690af69d88dSmrg 69101e04c3fSmrg _mesa_HashLockMutex(ctx->Shared->TexObjects); 692af69d88dSmrg 693af69d88dSmrg for (i = 0; i < count; i++) { 694af69d88dSmrg struct gl_image_unit *u = &ctx->ImageUnits[first + i]; 695af69d88dSmrg const GLuint texture = textures ? textures[i] : 0; 696af69d88dSmrg 69701e04c3fSmrg if (texture) { 69801e04c3fSmrg struct gl_texture_object *texObj = u->TexObj; 69901e04c3fSmrg GLenum tex_format; 700af69d88dSmrg 70101e04c3fSmrg if (!texObj || texObj->Name != texture) { 702af69d88dSmrg texObj = _mesa_lookup_texture_locked(ctx, texture); 70301e04c3fSmrg if (!no_error && !texObj) { 704af69d88dSmrg /* The ARB_multi_bind spec says: 705af69d88dSmrg * 706af69d88dSmrg * "An INVALID_OPERATION error is generated if any value 707af69d88dSmrg * in <textures> is not zero or the name of an existing 708af69d88dSmrg * texture object (per binding)." 709af69d88dSmrg */ 710af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 711af69d88dSmrg "glBindImageTextures(textures[%d]=%u " 712af69d88dSmrg "is not zero or the name of an existing texture " 713af69d88dSmrg "object)", i, texture); 714af69d88dSmrg continue; 715af69d88dSmrg } 716af69d88dSmrg } 717af69d88dSmrg 71801e04c3fSmrg if (texObj->Target == GL_TEXTURE_BUFFER) { 71901e04c3fSmrg tex_format = texObj->BufferObjectFormat; 72001e04c3fSmrg } else { 72101e04c3fSmrg struct gl_texture_image *image = texObj->Image[0][0]; 722af69d88dSmrg 72301e04c3fSmrg if (!no_error && (!image || image->Width == 0 || 72401e04c3fSmrg image->Height == 0 || image->Depth == 0)) { 72501e04c3fSmrg /* The ARB_multi_bind spec says: 72601e04c3fSmrg * 72701e04c3fSmrg * "An INVALID_OPERATION error is generated if the width, 72801e04c3fSmrg * height, or depth of the level zero texture image of 72901e04c3fSmrg * any texture in <textures> is zero (per binding)." 73001e04c3fSmrg */ 73101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 73201e04c3fSmrg "glBindImageTextures(the width, height or depth " 73301e04c3fSmrg "of the level zero texture image of " 73401e04c3fSmrg "textures[%d]=%u is zero)", i, texture); 73501e04c3fSmrg continue; 73601e04c3fSmrg } 737af69d88dSmrg 73801e04c3fSmrg tex_format = image->InternalFormat; 73901e04c3fSmrg } 740af69d88dSmrg 74101e04c3fSmrg if (!no_error && 74201e04c3fSmrg !_mesa_is_shader_image_format_supported(ctx, tex_format)) { 743af69d88dSmrg /* The ARB_multi_bind spec says: 744af69d88dSmrg * 745af69d88dSmrg * "An INVALID_OPERATION error is generated if the internal 746af69d88dSmrg * format of the level zero texture image of any texture 747af69d88dSmrg * in <textures> is not found in table 8.33 (per binding)." 748af69d88dSmrg */ 749af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 750af69d88dSmrg "glBindImageTextures(the internal format %s of " 751af69d88dSmrg "the level zero texture image of textures[%d]=%u " 752af69d88dSmrg "is not supported)", 75301e04c3fSmrg _mesa_enum_to_string(tex_format), 754af69d88dSmrg i, texture); 755af69d88dSmrg continue; 756af69d88dSmrg } 757af69d88dSmrg 758af69d88dSmrg /* Update the texture binding */ 75901e04c3fSmrg set_image_binding(u, texObj, 0, 76001e04c3fSmrg _mesa_tex_target_is_layered(texObj->Target), 76101e04c3fSmrg 0, GL_READ_WRITE, tex_format); 762af69d88dSmrg } else { 763af69d88dSmrg /* Unbind the texture from the unit */ 76401e04c3fSmrg set_image_binding(u, NULL, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8); 765af69d88dSmrg } 766af69d88dSmrg } 767af69d88dSmrg 76801e04c3fSmrg _mesa_HashUnlockMutex(ctx->Shared->TexObjects); 76901e04c3fSmrg} 77001e04c3fSmrg 77101e04c3fSmrgvoid GLAPIENTRY 77201e04c3fSmrg_mesa_BindImageTextures_no_error(GLuint first, GLsizei count, 77301e04c3fSmrg const GLuint *textures) 77401e04c3fSmrg{ 77501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 77601e04c3fSmrg 77701e04c3fSmrg bind_image_textures(ctx, first, count, textures, true); 778af69d88dSmrg} 779af69d88dSmrg 780af69d88dSmrgvoid GLAPIENTRY 78101e04c3fSmrg_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures) 782af69d88dSmrg{ 783af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 784af69d88dSmrg 78501e04c3fSmrg if (!ctx->Extensions.ARB_shader_image_load_store) { 78601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()"); 78701e04c3fSmrg return; 78801e04c3fSmrg } 78901e04c3fSmrg 79001e04c3fSmrg if (first + count > ctx->Const.MaxImageUnits) { 79101e04c3fSmrg /* The ARB_multi_bind spec says: 79201e04c3fSmrg * 79301e04c3fSmrg * "An INVALID_OPERATION error is generated if <first> + <count> 79401e04c3fSmrg * is greater than the number of image units supported by 79501e04c3fSmrg * the implementation." 79601e04c3fSmrg */ 79701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 79801e04c3fSmrg "glBindImageTextures(first=%u + count=%d > the value of " 79901e04c3fSmrg "GL_MAX_IMAGE_UNITS=%u)", 80001e04c3fSmrg first, count, ctx->Const.MaxImageUnits); 80101e04c3fSmrg return; 80201e04c3fSmrg } 80301e04c3fSmrg 80401e04c3fSmrg bind_image_textures(ctx, first, count, textures, false); 805af69d88dSmrg} 806