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