shaderimage.c revision b9abf16e
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 472b9abf16eSmaya 473b9abf16eSmayavoid 474b9abf16eSmaya_mesa_free_image_textures(struct gl_context *ctx) 475b9abf16eSmaya{ 476b9abf16eSmaya unsigned i; 477b9abf16eSmaya 478b9abf16eSmaya for (i = 0; i < ARRAY_SIZE(ctx->ImageUnits); ++i) 479b9abf16eSmaya _mesa_reference_texobj(&ctx->ImageUnits[i].TexObj, NULL); 480b9abf16eSmaya} 481b9abf16eSmaya 48201e04c3fSmrgGLboolean 48301e04c3fSmrg_mesa_is_image_unit_valid(struct gl_context *ctx, struct gl_image_unit *u) 484af69d88dSmrg{ 485af69d88dSmrg struct gl_texture_object *t = u->TexObj; 48601e04c3fSmrg mesa_format tex_format; 487af69d88dSmrg 48801e04c3fSmrg if (!t) 489af69d88dSmrg return GL_FALSE; 490af69d88dSmrg 49101e04c3fSmrg if (!t->_BaseComplete && !t->_MipmapComplete) 49201e04c3fSmrg _mesa_test_texobj_completeness(ctx, t); 493af69d88dSmrg 49401e04c3fSmrg if (u->Level < t->BaseLevel || 49501e04c3fSmrg u->Level > t->_MaxLevel || 49601e04c3fSmrg (u->Level == t->BaseLevel && !t->_BaseComplete) || 497af69d88dSmrg (u->Level != t->BaseLevel && !t->_MipmapComplete)) 498af69d88dSmrg return GL_FALSE; 499af69d88dSmrg 500af69d88dSmrg if (_mesa_tex_target_is_layered(t->Target) && 50101e04c3fSmrg u->_Layer >= _mesa_get_texture_layers(t, u->Level)) 502af69d88dSmrg return GL_FALSE; 503af69d88dSmrg 50401e04c3fSmrg if (t->Target == GL_TEXTURE_BUFFER) { 50501e04c3fSmrg tex_format = _mesa_get_shader_image_format(t->BufferObjectFormat); 50601e04c3fSmrg 50701e04c3fSmrg } else { 50801e04c3fSmrg struct gl_texture_image *img = (t->Target == GL_TEXTURE_CUBE_MAP ? 50901e04c3fSmrg t->Image[u->_Layer][u->Level] : 51001e04c3fSmrg t->Image[0][u->Level]); 51101e04c3fSmrg 51201e04c3fSmrg if (!img || img->Border || img->NumSamples > ctx->Const.MaxImageSamples) 51301e04c3fSmrg return GL_FALSE; 51401e04c3fSmrg 51501e04c3fSmrg tex_format = _mesa_get_shader_image_format(img->InternalFormat); 51601e04c3fSmrg } 517af69d88dSmrg 51801e04c3fSmrg if (!tex_format) 519af69d88dSmrg return GL_FALSE; 520af69d88dSmrg 521af69d88dSmrg switch (t->ImageFormatCompatibilityType) { 522af69d88dSmrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE: 52301e04c3fSmrg if (_mesa_get_format_bytes(tex_format) != 524af69d88dSmrg _mesa_get_format_bytes(u->_ActualFormat)) 525af69d88dSmrg return GL_FALSE; 526af69d88dSmrg break; 527af69d88dSmrg 528af69d88dSmrg case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS: 52901e04c3fSmrg if (get_image_format_class(tex_format) != 530af69d88dSmrg get_image_format_class(u->_ActualFormat)) 531af69d88dSmrg return GL_FALSE; 532af69d88dSmrg break; 533af69d88dSmrg 534af69d88dSmrg default: 535af69d88dSmrg assert(!"Unexpected image format compatibility type"); 536af69d88dSmrg } 537af69d88dSmrg 538af69d88dSmrg return GL_TRUE; 539af69d88dSmrg} 540af69d88dSmrg 541af69d88dSmrgstatic GLboolean 542af69d88dSmrgvalidate_bind_image_texture(struct gl_context *ctx, GLuint unit, 54301e04c3fSmrg GLuint texture, GLint level, GLint layer, 54401e04c3fSmrg GLenum access, GLenum format) 545af69d88dSmrg{ 546af69d88dSmrg assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS); 547af69d88dSmrg 548af69d88dSmrg if (unit >= ctx->Const.MaxImageUnits) { 549af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)"); 550af69d88dSmrg return GL_FALSE; 551af69d88dSmrg } 552af69d88dSmrg 553af69d88dSmrg if (level < 0) { 554af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)"); 555af69d88dSmrg return GL_FALSE; 556af69d88dSmrg } 557af69d88dSmrg 558af69d88dSmrg if (layer < 0) { 559af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)"); 560af69d88dSmrg return GL_FALSE; 561af69d88dSmrg } 562af69d88dSmrg 563af69d88dSmrg if (access != GL_READ_ONLY && 564af69d88dSmrg access != GL_WRITE_ONLY && 565af69d88dSmrg access != GL_READ_WRITE) { 566af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)"); 567af69d88dSmrg return GL_FALSE; 568af69d88dSmrg } 569af69d88dSmrg 57001e04c3fSmrg if (!_mesa_is_shader_image_format_supported(ctx, format)) { 571af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)"); 572af69d88dSmrg return GL_FALSE; 573af69d88dSmrg } 574af69d88dSmrg 575af69d88dSmrg return GL_TRUE; 576af69d88dSmrg} 577af69d88dSmrg 57801e04c3fSmrgstatic void 57901e04c3fSmrgset_image_binding(struct gl_image_unit *u, struct gl_texture_object *texObj, 58001e04c3fSmrg GLint level, GLboolean layered, GLint layer, GLenum access, 58101e04c3fSmrg GLenum format) 582af69d88dSmrg{ 58301e04c3fSmrg u->Level = level; 58401e04c3fSmrg u->Access = access; 58501e04c3fSmrg u->Format = format; 58601e04c3fSmrg u->_ActualFormat = _mesa_get_shader_image_format(format); 58701e04c3fSmrg 58801e04c3fSmrg if (texObj && _mesa_tex_target_is_layered(texObj->Target)) { 58901e04c3fSmrg u->Layered = layered; 59001e04c3fSmrg u->Layer = layer; 59101e04c3fSmrg u->_Layer = (u->Layered ? 0 : u->Layer); 59201e04c3fSmrg } else { 59301e04c3fSmrg u->Layered = GL_FALSE; 59401e04c3fSmrg u->Layer = 0; 59501e04c3fSmrg } 596af69d88dSmrg 59701e04c3fSmrg _mesa_reference_texobj(&u->TexObj, texObj); 59801e04c3fSmrg} 59901e04c3fSmrg 60001e04c3fSmrgstatic void 60101e04c3fSmrgbind_image_texture(struct gl_context *ctx, struct gl_texture_object *texObj, 60201e04c3fSmrg GLuint unit, GLint level, GLboolean layered, GLint layer, 60301e04c3fSmrg GLenum access, GLenum format) 60401e04c3fSmrg{ 60501e04c3fSmrg struct gl_image_unit *u; 606af69d88dSmrg 607af69d88dSmrg u = &ctx->ImageUnits[unit]; 608af69d88dSmrg 609af69d88dSmrg FLUSH_VERTICES(ctx, 0); 610af69d88dSmrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 611af69d88dSmrg 61201e04c3fSmrg set_image_binding(u, texObj, level, layered, layer, access, format); 61301e04c3fSmrg} 614af69d88dSmrg 61501e04c3fSmrgvoid GLAPIENTRY 61601e04c3fSmrg_mesa_BindImageTexture_no_error(GLuint unit, GLuint texture, GLint level, 61701e04c3fSmrg GLboolean layered, GLint layer, GLenum access, 61801e04c3fSmrg GLenum format) 61901e04c3fSmrg{ 62001e04c3fSmrg struct gl_texture_object *texObj = NULL; 621af69d88dSmrg 62201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 623af69d88dSmrg 62401e04c3fSmrg if (texture) 62501e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 626af69d88dSmrg 62701e04c3fSmrg bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format); 628af69d88dSmrg} 629af69d88dSmrg 630af69d88dSmrgvoid GLAPIENTRY 63101e04c3fSmrg_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, 63201e04c3fSmrg GLboolean layered, GLint layer, GLenum access, 63301e04c3fSmrg GLenum format) 634af69d88dSmrg{ 63501e04c3fSmrg struct gl_texture_object *texObj = NULL; 63601e04c3fSmrg 637af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 638af69d88dSmrg 63901e04c3fSmrg if (!validate_bind_image_texture(ctx, unit, texture, level, layer, access, 64001e04c3fSmrg format)) 641af69d88dSmrg return; 642af69d88dSmrg 64301e04c3fSmrg if (texture) { 64401e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 64501e04c3fSmrg 64601e04c3fSmrg if (!texObj) { 64701e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)"); 64801e04c3fSmrg return; 64901e04c3fSmrg } 65001e04c3fSmrg 65101e04c3fSmrg /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES 65201e04c3fSmrg * 3.1 spec: 653af69d88dSmrg * 65401e04c3fSmrg * "An INVALID_OPERATION error is generated if texture is not the name 65501e04c3fSmrg * of an immutable texture object." 65601e04c3fSmrg * 65701e04c3fSmrg * However note that issue 7 of the GL_OES_texture_buffer spec 65801e04c3fSmrg * recognizes that there is no way to create immutable buffer textures, 65901e04c3fSmrg * so those are excluded from this requirement. 660af69d88dSmrg */ 66101e04c3fSmrg if (_mesa_is_gles(ctx) && !texObj->Immutable && 66201e04c3fSmrg texObj->Target != GL_TEXTURE_BUFFER) { 66301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 66401e04c3fSmrg "glBindImageTexture(!immutable)"); 66501e04c3fSmrg return; 66601e04c3fSmrg } 667af69d88dSmrg } 668af69d88dSmrg 66901e04c3fSmrg bind_image_texture(ctx, texObj, unit, level, layered, layer, access, format); 67001e04c3fSmrg} 67101e04c3fSmrg 67201e04c3fSmrgstatic ALWAYS_INLINE void 67301e04c3fSmrgbind_image_textures(struct gl_context *ctx, GLuint first, GLuint count, 67401e04c3fSmrg const GLuint *textures, bool no_error) 67501e04c3fSmrg{ 67601e04c3fSmrg int i; 67701e04c3fSmrg 678af69d88dSmrg /* Assume that at least one binding will be changed */ 679af69d88dSmrg FLUSH_VERTICES(ctx, 0); 680af69d88dSmrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 681af69d88dSmrg 682af69d88dSmrg /* Note that the error semantics for multi-bind commands differ from 683af69d88dSmrg * those of other GL commands. 684af69d88dSmrg * 685af69d88dSmrg * The Issues section in the ARB_multi_bind spec says: 686af69d88dSmrg * 687af69d88dSmrg * "(11) Typically, OpenGL specifies that if an error is generated by 688af69d88dSmrg * a command, that command has no effect. This is somewhat 689af69d88dSmrg * unfortunate for multi-bind commands, because it would require 690af69d88dSmrg * a first pass to scan the entire list of bound objects for 691af69d88dSmrg * errors and then a second pass to actually perform the 692af69d88dSmrg * bindings. Should we have different error semantics? 693af69d88dSmrg * 694af69d88dSmrg * RESOLVED: Yes. In this specification, when the parameters for 695af69d88dSmrg * one of the <count> binding points are invalid, that binding 696af69d88dSmrg * point is not updated and an error will be generated. However, 697af69d88dSmrg * other binding points in the same command will be updated if 698af69d88dSmrg * their parameters are valid and no other error occurs." 699af69d88dSmrg */ 700af69d88dSmrg 70101e04c3fSmrg _mesa_HashLockMutex(ctx->Shared->TexObjects); 702af69d88dSmrg 703af69d88dSmrg for (i = 0; i < count; i++) { 704af69d88dSmrg struct gl_image_unit *u = &ctx->ImageUnits[first + i]; 705af69d88dSmrg const GLuint texture = textures ? textures[i] : 0; 706af69d88dSmrg 70701e04c3fSmrg if (texture) { 70801e04c3fSmrg struct gl_texture_object *texObj = u->TexObj; 70901e04c3fSmrg GLenum tex_format; 710af69d88dSmrg 71101e04c3fSmrg if (!texObj || texObj->Name != texture) { 712af69d88dSmrg texObj = _mesa_lookup_texture_locked(ctx, texture); 71301e04c3fSmrg if (!no_error && !texObj) { 714af69d88dSmrg /* The ARB_multi_bind spec says: 715af69d88dSmrg * 716af69d88dSmrg * "An INVALID_OPERATION error is generated if any value 717af69d88dSmrg * in <textures> is not zero or the name of an existing 718af69d88dSmrg * texture object (per binding)." 719af69d88dSmrg */ 720af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 721af69d88dSmrg "glBindImageTextures(textures[%d]=%u " 722af69d88dSmrg "is not zero or the name of an existing texture " 723af69d88dSmrg "object)", i, texture); 724af69d88dSmrg continue; 725af69d88dSmrg } 726af69d88dSmrg } 727af69d88dSmrg 72801e04c3fSmrg if (texObj->Target == GL_TEXTURE_BUFFER) { 72901e04c3fSmrg tex_format = texObj->BufferObjectFormat; 73001e04c3fSmrg } else { 73101e04c3fSmrg struct gl_texture_image *image = texObj->Image[0][0]; 732af69d88dSmrg 73301e04c3fSmrg if (!no_error && (!image || image->Width == 0 || 73401e04c3fSmrg image->Height == 0 || image->Depth == 0)) { 73501e04c3fSmrg /* The ARB_multi_bind spec says: 73601e04c3fSmrg * 73701e04c3fSmrg * "An INVALID_OPERATION error is generated if the width, 73801e04c3fSmrg * height, or depth of the level zero texture image of 73901e04c3fSmrg * any texture in <textures> is zero (per binding)." 74001e04c3fSmrg */ 74101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 74201e04c3fSmrg "glBindImageTextures(the width, height or depth " 74301e04c3fSmrg "of the level zero texture image of " 74401e04c3fSmrg "textures[%d]=%u is zero)", i, texture); 74501e04c3fSmrg continue; 74601e04c3fSmrg } 747af69d88dSmrg 74801e04c3fSmrg tex_format = image->InternalFormat; 74901e04c3fSmrg } 750af69d88dSmrg 75101e04c3fSmrg if (!no_error && 75201e04c3fSmrg !_mesa_is_shader_image_format_supported(ctx, tex_format)) { 753af69d88dSmrg /* The ARB_multi_bind spec says: 754af69d88dSmrg * 755af69d88dSmrg * "An INVALID_OPERATION error is generated if the internal 756af69d88dSmrg * format of the level zero texture image of any texture 757af69d88dSmrg * in <textures> is not found in table 8.33 (per binding)." 758af69d88dSmrg */ 759af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 760af69d88dSmrg "glBindImageTextures(the internal format %s of " 761af69d88dSmrg "the level zero texture image of textures[%d]=%u " 762af69d88dSmrg "is not supported)", 76301e04c3fSmrg _mesa_enum_to_string(tex_format), 764af69d88dSmrg i, texture); 765af69d88dSmrg continue; 766af69d88dSmrg } 767af69d88dSmrg 768af69d88dSmrg /* Update the texture binding */ 76901e04c3fSmrg set_image_binding(u, texObj, 0, 77001e04c3fSmrg _mesa_tex_target_is_layered(texObj->Target), 77101e04c3fSmrg 0, GL_READ_WRITE, tex_format); 772af69d88dSmrg } else { 773af69d88dSmrg /* Unbind the texture from the unit */ 77401e04c3fSmrg set_image_binding(u, NULL, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8); 775af69d88dSmrg } 776af69d88dSmrg } 777af69d88dSmrg 77801e04c3fSmrg _mesa_HashUnlockMutex(ctx->Shared->TexObjects); 77901e04c3fSmrg} 78001e04c3fSmrg 78101e04c3fSmrgvoid GLAPIENTRY 78201e04c3fSmrg_mesa_BindImageTextures_no_error(GLuint first, GLsizei count, 78301e04c3fSmrg const GLuint *textures) 78401e04c3fSmrg{ 78501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 78601e04c3fSmrg 78701e04c3fSmrg bind_image_textures(ctx, first, count, textures, true); 788af69d88dSmrg} 789af69d88dSmrg 790af69d88dSmrgvoid GLAPIENTRY 79101e04c3fSmrg_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures) 792af69d88dSmrg{ 793af69d88dSmrg GET_CURRENT_CONTEXT(ctx); 794af69d88dSmrg 79501e04c3fSmrg if (!ctx->Extensions.ARB_shader_image_load_store) { 79601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()"); 79701e04c3fSmrg return; 79801e04c3fSmrg } 79901e04c3fSmrg 80001e04c3fSmrg if (first + count > ctx->Const.MaxImageUnits) { 80101e04c3fSmrg /* The ARB_multi_bind spec says: 80201e04c3fSmrg * 80301e04c3fSmrg * "An INVALID_OPERATION error is generated if <first> + <count> 80401e04c3fSmrg * is greater than the number of image units supported by 80501e04c3fSmrg * the implementation." 80601e04c3fSmrg */ 80701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 80801e04c3fSmrg "glBindImageTextures(first=%u + count=%d > the value of " 80901e04c3fSmrg "GL_MAX_IMAGE_UNITS=%u)", 81001e04c3fSmrg first, count, ctx->Const.MaxImageUnits); 81101e04c3fSmrg return; 81201e04c3fSmrg } 81301e04c3fSmrg 81401e04c3fSmrg bind_image_textures(ctx, first, count, textures, false); 815af69d88dSmrg} 816