2 * Copyright 2013 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 * Francisco Jerez <currojerez@riseup.net>
29 #include "shaderimage.h"
38 * Define endian-invariant aliases for some mesa formats that are
39 * defined in terms of their channel layout from LSB to MSB in a
40 * 32-bit word. The actual byte offsets matter here because the user
41 * is allowed to bit-cast one format into another and get predictable
44 #ifdef MESA_BIG_ENDIAN
45 # define MESA_FORMAT_RGBA_8 MESA_FORMAT_A8B8G8R8_UNORM
46 # define MESA_FORMAT_RG_16 MESA_FORMAT_RG1616
47 # define MESA_FORMAT_RG_8 MESA_FORMAT_RG88
48 # define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_SIGNED_RGBA8888
49 # define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_SIGNED_RG1616
50 # define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_SIGNED_RG88
52 # define MESA_FORMAT_RGBA_8 MESA_FORMAT_R8G8B8A8_UNORM
53 # define MESA_FORMAT_RG_16 MESA_FORMAT_GR1616
54 # define MESA_FORMAT_RG_8 MESA_FORMAT_GR88
55 # define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_SIGNED_RGBA8888_REV
56 # define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_SIGNED_GR1616
57 # define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_SIGNED_RG88_REV
61 get_image_format(GLenum format
)
65 return MESA_FORMAT_RGBA_FLOAT32
;
68 return MESA_FORMAT_RGBA_FLOAT16
;
71 return MESA_FORMAT_RG_FLOAT32
;
74 return MESA_FORMAT_RG_FLOAT16
;
76 case GL_R11F_G11F_B10F
:
77 return MESA_FORMAT_R11_G11_B10_FLOAT
;
80 return MESA_FORMAT_R_FLOAT32
;
83 return MESA_FORMAT_R_FLOAT16
;
86 return MESA_FORMAT_RGBA_UINT32
;
89 return MESA_FORMAT_RGBA_UINT16
;
92 return MESA_FORMAT_ABGR2101010_UINT
;
95 return MESA_FORMAT_RGBA_UINT8
;
98 return MESA_FORMAT_RG_UINT32
;
101 return MESA_FORMAT_RG_UINT16
;
104 return MESA_FORMAT_RG_UINT8
;
107 return MESA_FORMAT_R_UINT32
;
110 return MESA_FORMAT_R_UINT16
;
113 return MESA_FORMAT_R_UINT8
;
116 return MESA_FORMAT_RGBA_INT32
;
119 return MESA_FORMAT_RGBA_INT16
;
122 return MESA_FORMAT_RGBA_INT8
;
125 return MESA_FORMAT_RG_INT32
;
128 return MESA_FORMAT_RG_INT16
;
131 return MESA_FORMAT_RG_INT8
;
134 return MESA_FORMAT_R_INT32
;
137 return MESA_FORMAT_R_INT16
;
140 return MESA_FORMAT_R_INT8
;
143 return MESA_FORMAT_RGBA_16
;
146 return MESA_FORMAT_ABGR2101010
;
149 return MESA_FORMAT_RGBA_8
;
152 return MESA_FORMAT_RG_16
;
155 return MESA_FORMAT_RG_8
;
158 return MESA_FORMAT_R16
;
161 return MESA_FORMAT_R8
;
163 case GL_RGBA16_SNORM
:
164 return MESA_FORMAT_SIGNED_RGBA_16
;
167 return MESA_FORMAT_SIGNED_RGBA_8
;
170 return MESA_FORMAT_SIGNED_RG_16
;
173 return MESA_FORMAT_SIGNED_RG_8
;
176 return MESA_FORMAT_SIGNED_R16
;
179 return MESA_FORMAT_SIGNED_R8
;
182 return MESA_FORMAT_NONE
;
186 enum image_format_class
188 /** Not a valid image format. */
189 IMAGE_FORMAT_CLASS_NONE
= 0,
191 /** Classes of image formats you can cast into each other. */
193 IMAGE_FORMAT_CLASS_1X8
,
194 IMAGE_FORMAT_CLASS_1X16
,
195 IMAGE_FORMAT_CLASS_1X32
,
196 IMAGE_FORMAT_CLASS_2X8
,
197 IMAGE_FORMAT_CLASS_2X16
,
198 IMAGE_FORMAT_CLASS_2X32
,
199 IMAGE_FORMAT_CLASS_10_11_11
,
200 IMAGE_FORMAT_CLASS_4X8
,
201 IMAGE_FORMAT_CLASS_4X16
,
202 IMAGE_FORMAT_CLASS_4X32
,
203 IMAGE_FORMAT_CLASS_2_10_10_10
207 static enum image_format_class
208 get_image_format_class(mesa_format format
)
211 case MESA_FORMAT_RGBA_FLOAT32
:
212 return IMAGE_FORMAT_CLASS_4X32
;
214 case MESA_FORMAT_RGBA_FLOAT16
:
215 return IMAGE_FORMAT_CLASS_4X16
;
217 case MESA_FORMAT_RG_FLOAT32
:
218 return IMAGE_FORMAT_CLASS_2X32
;
220 case MESA_FORMAT_RG_FLOAT16
:
221 return IMAGE_FORMAT_CLASS_2X16
;
223 case MESA_FORMAT_R11_G11_B10_FLOAT
:
224 return IMAGE_FORMAT_CLASS_10_11_11
;
226 case MESA_FORMAT_R_FLOAT32
:
227 return IMAGE_FORMAT_CLASS_1X32
;
229 case MESA_FORMAT_R_FLOAT16
:
230 return IMAGE_FORMAT_CLASS_1X16
;
232 case MESA_FORMAT_RGBA_UINT32
:
233 return IMAGE_FORMAT_CLASS_4X32
;
235 case MESA_FORMAT_RGBA_UINT16
:
236 return IMAGE_FORMAT_CLASS_4X16
;
238 case MESA_FORMAT_ABGR2101010_UINT
:
239 return IMAGE_FORMAT_CLASS_2_10_10_10
;
241 case MESA_FORMAT_RGBA_UINT8
:
242 return IMAGE_FORMAT_CLASS_4X8
;
244 case MESA_FORMAT_RG_UINT32
:
245 return IMAGE_FORMAT_CLASS_2X32
;
247 case MESA_FORMAT_RG_UINT16
:
248 return IMAGE_FORMAT_CLASS_2X16
;
250 case MESA_FORMAT_RG_UINT8
:
251 return IMAGE_FORMAT_CLASS_2X8
;
253 case MESA_FORMAT_R_UINT32
:
254 return IMAGE_FORMAT_CLASS_1X32
;
256 case MESA_FORMAT_R_UINT16
:
257 return IMAGE_FORMAT_CLASS_1X16
;
259 case MESA_FORMAT_R_UINT8
:
260 return IMAGE_FORMAT_CLASS_1X8
;
262 case MESA_FORMAT_RGBA_INT32
:
263 return IMAGE_FORMAT_CLASS_4X32
;
265 case MESA_FORMAT_RGBA_INT16
:
266 return IMAGE_FORMAT_CLASS_4X16
;
268 case MESA_FORMAT_RGBA_INT8
:
269 return IMAGE_FORMAT_CLASS_4X8
;
271 case MESA_FORMAT_RG_INT32
:
272 return IMAGE_FORMAT_CLASS_2X32
;
274 case MESA_FORMAT_RG_INT16
:
275 return IMAGE_FORMAT_CLASS_2X16
;
277 case MESA_FORMAT_RG_INT8
:
278 return IMAGE_FORMAT_CLASS_2X8
;
280 case MESA_FORMAT_R_INT32
:
281 return IMAGE_FORMAT_CLASS_1X32
;
283 case MESA_FORMAT_R_INT16
:
284 return IMAGE_FORMAT_CLASS_1X16
;
286 case MESA_FORMAT_R_INT8
:
287 return IMAGE_FORMAT_CLASS_1X8
;
289 case MESA_FORMAT_RGBA_16
:
290 return IMAGE_FORMAT_CLASS_4X16
;
292 case MESA_FORMAT_ABGR2101010
:
293 return IMAGE_FORMAT_CLASS_2_10_10_10
;
295 case MESA_FORMAT_RGBA_8
:
296 return IMAGE_FORMAT_CLASS_4X8
;
298 case MESA_FORMAT_RG_16
:
299 return IMAGE_FORMAT_CLASS_2X16
;
301 case MESA_FORMAT_RG_8
:
302 return IMAGE_FORMAT_CLASS_2X8
;
304 case MESA_FORMAT_R16
:
305 return IMAGE_FORMAT_CLASS_1X16
;
308 return IMAGE_FORMAT_CLASS_1X8
;
310 case MESA_FORMAT_SIGNED_RGBA_16
:
311 return IMAGE_FORMAT_CLASS_4X16
;
313 case MESA_FORMAT_SIGNED_RGBA_8
:
314 return IMAGE_FORMAT_CLASS_4X8
;
316 case MESA_FORMAT_SIGNED_RG_16
:
317 return IMAGE_FORMAT_CLASS_2X16
;
319 case MESA_FORMAT_SIGNED_RG_8
:
320 return IMAGE_FORMAT_CLASS_2X8
;
322 case MESA_FORMAT_SIGNED_R16
:
323 return IMAGE_FORMAT_CLASS_1X16
;
325 case MESA_FORMAT_SIGNED_R8
:
326 return IMAGE_FORMAT_CLASS_1X8
;
329 return IMAGE_FORMAT_CLASS_NONE
;
334 validate_image_unit(struct gl_context
*ctx
, struct gl_image_unit
*u
)
336 struct gl_texture_object
*t
= u
->TexObj
;
337 struct gl_texture_image
*img
;
339 if (!t
|| u
->Level
< t
->BaseLevel
||
340 u
->Level
> t
->_MaxLevel
)
343 _mesa_test_texobj_completeness(ctx
, t
);
345 if ((u
->Level
== t
->BaseLevel
&& !t
->_BaseComplete
) ||
346 (u
->Level
!= t
->BaseLevel
&& !t
->_MipmapComplete
))
349 if (_mesa_tex_target_is_layered(t
->Target
) &&
350 u
->Layer
>= _mesa_get_texture_layers(t
, u
->Level
))
353 if (t
->Target
== GL_TEXTURE_CUBE_MAP
)
354 img
= t
->Image
[u
->Layer
][u
->Level
];
356 img
= t
->Image
[0][u
->Level
];
358 if (!img
|| img
->Border
||
359 get_image_format_class(img
->TexFormat
) == IMAGE_FORMAT_CLASS_NONE
||
360 img
->NumSamples
> ctx
->Const
.MaxImageSamples
)
363 switch (t
->ImageFormatCompatibilityType
) {
364 case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE
:
365 if (_mesa_get_format_bytes(img
->TexFormat
) !=
366 _mesa_get_format_bytes(u
->_ActualFormat
))
370 case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS
:
371 if (get_image_format_class(img
->TexFormat
) !=
372 get_image_format_class(u
->_ActualFormat
))
377 assert(!"Unexpected image format compatibility type");
384 _mesa_validate_image_units(struct gl_context
*ctx
)
388 for (i
= 0; i
< ctx
->Const
.MaxImageUnits
; ++i
) {
389 struct gl_image_unit
*u
= &ctx
->ImageUnits
[i
];
390 u
->_Valid
= validate_image_unit(ctx
, u
);
395 validate_bind_image_texture(struct gl_context
*ctx
, GLuint unit
,
396 GLuint texture
, GLint level
, GLboolean layered
,
397 GLint layer
, GLenum access
, GLenum format
)
399 assert(ctx
->Const
.MaxImageUnits
<= MAX_IMAGE_UNITS
);
401 if (unit
>= ctx
->Const
.MaxImageUnits
) {
402 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindImageTexture(unit)");
407 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindImageTexture(level)");
412 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindImageTexture(layer)");
416 if (access
!= GL_READ_ONLY
&&
417 access
!= GL_WRITE_ONLY
&&
418 access
!= GL_READ_WRITE
) {
419 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindImageTexture(access)");
423 if (!get_image_format(format
)) {
424 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindImageTexture(format)");
432 _mesa_BindImageTexture(GLuint unit
, GLuint texture
, GLint level
,
433 GLboolean layered
, GLint layer
, GLenum access
,
436 GET_CURRENT_CONTEXT(ctx
);
437 struct gl_texture_object
*t
= NULL
;
438 struct gl_image_unit
*u
;
440 if (!validate_bind_image_texture(ctx
, unit
, texture
, level
,
441 layered
, layer
, access
, format
))
444 u
= &ctx
->ImageUnits
[unit
];
446 FLUSH_VERTICES(ctx
, 0);
447 ctx
->NewDriverState
|= ctx
->DriverFlags
.NewImageUnits
;
450 t
= _mesa_lookup_texture(ctx
, texture
);
452 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindImageTexture(texture)");
456 _mesa_reference_texobj(&u
->TexObj
, t
);
460 u
->_ActualFormat
= get_image_format(format
);
462 if (_mesa_tex_target_is_layered(t
->Target
)) {
463 u
->Layered
= layered
;
464 u
->Layer
= (layered
? 0 : layer
);
466 u
->Layered
= GL_FALSE
;
471 _mesa_reference_texobj(&u
->TexObj
, NULL
);
474 u
->_Valid
= validate_image_unit(ctx
, u
);
476 if (ctx
->Driver
.BindImageTexture
)
477 ctx
->Driver
.BindImageTexture(ctx
, u
, t
, level
, layered
,
478 layer
, access
, format
);
482 _mesa_MemoryBarrier(GLbitfield barriers
)
484 GET_CURRENT_CONTEXT(ctx
);
486 if (ctx
->Driver
.MemoryBarrier
)
487 ctx
->Driver
.MemoryBarrier(ctx
, barriers
);