2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
27 * glPixelStore functions.
32 #include "bufferobj.h"
34 #include "pixelstore.h"
36 #include "util/rounding.h"
39 static ALWAYS_INLINE
void
40 pixel_storei(GLenum pname
, GLint param
, bool no_error
)
42 /* NOTE: this call can't be compiled into the display list */
43 GET_CURRENT_CONTEXT(ctx
);
46 case GL_PACK_SWAP_BYTES
:
47 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
48 goto invalid_enum_error
;
49 ctx
->Pack
.SwapBytes
= param
? GL_TRUE
: GL_FALSE
;
51 case GL_PACK_LSB_FIRST
:
52 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
53 goto invalid_enum_error
;
54 ctx
->Pack
.LsbFirst
= param
? GL_TRUE
: GL_FALSE
;
56 case GL_PACK_ROW_LENGTH
:
57 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
58 goto invalid_enum_error
;
59 if (!no_error
&& param
<0)
60 goto invalid_value_error
;
61 ctx
->Pack
.RowLength
= param
;
63 case GL_PACK_IMAGE_HEIGHT
:
64 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
65 goto invalid_enum_error
;
66 if (!no_error
&& param
<0)
67 goto invalid_value_error
;
68 ctx
->Pack
.ImageHeight
= param
;
70 case GL_PACK_SKIP_PIXELS
:
71 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
72 goto invalid_enum_error
;
73 if (!no_error
&& param
<0)
74 goto invalid_value_error
;
75 ctx
->Pack
.SkipPixels
= param
;
77 case GL_PACK_SKIP_ROWS
:
78 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
79 goto invalid_enum_error
;
80 if (!no_error
&& param
<0)
81 goto invalid_value_error
;
82 ctx
->Pack
.SkipRows
= param
;
84 case GL_PACK_SKIP_IMAGES
:
85 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
86 goto invalid_enum_error
;
87 if (!no_error
&& param
<0)
88 goto invalid_value_error
;
89 ctx
->Pack
.SkipImages
= param
;
91 case GL_PACK_ALIGNMENT
:
92 if (!no_error
&& param
!=1 && param
!=2 && param
!=4 && param
!=8)
93 goto invalid_value_error
;
94 ctx
->Pack
.Alignment
= param
;
96 case GL_PACK_INVERT_MESA
:
98 (!_mesa_is_desktop_gl(ctx
) || !ctx
->Extensions
.MESA_pack_invert
))
99 goto invalid_enum_error
;
100 ctx
->Pack
.Invert
= param
;
102 case GL_PACK_COMPRESSED_BLOCK_WIDTH
:
103 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
104 goto invalid_enum_error
;
105 if (!no_error
&& param
<0)
106 goto invalid_value_error
;
107 ctx
->Pack
.CompressedBlockWidth
= param
;
109 case GL_PACK_COMPRESSED_BLOCK_HEIGHT
:
110 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
111 goto invalid_enum_error
;
112 if (!no_error
&& param
<0)
113 goto invalid_value_error
;
114 ctx
->Pack
.CompressedBlockHeight
= param
;
116 case GL_PACK_COMPRESSED_BLOCK_DEPTH
:
117 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
118 goto invalid_enum_error
;
119 if (!no_error
&& param
<0)
120 goto invalid_value_error
;
121 ctx
->Pack
.CompressedBlockDepth
= param
;
123 case GL_PACK_COMPRESSED_BLOCK_SIZE
:
124 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
125 goto invalid_enum_error
;
126 if (!no_error
&& param
<0)
127 goto invalid_value_error
;
128 ctx
->Pack
.CompressedBlockSize
= param
;
131 case GL_UNPACK_SWAP_BYTES
:
132 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
133 goto invalid_enum_error
;
134 ctx
->Unpack
.SwapBytes
= param
? GL_TRUE
: GL_FALSE
;
136 case GL_UNPACK_LSB_FIRST
:
137 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
138 goto invalid_enum_error
;
139 ctx
->Unpack
.LsbFirst
= param
? GL_TRUE
: GL_FALSE
;
141 case GL_UNPACK_ROW_LENGTH
:
142 if (!no_error
&& ctx
->API
== API_OPENGLES
)
143 goto invalid_enum_error
;
144 if (!no_error
&& param
<0)
145 goto invalid_value_error
;
146 ctx
->Unpack
.RowLength
= param
;
148 case GL_UNPACK_IMAGE_HEIGHT
:
149 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
150 goto invalid_enum_error
;
151 if (!no_error
&& param
<0)
152 goto invalid_value_error
;
153 ctx
->Unpack
.ImageHeight
= param
;
155 case GL_UNPACK_SKIP_PIXELS
:
156 if (!no_error
&& ctx
->API
== API_OPENGLES
)
157 goto invalid_enum_error
;
158 if (!no_error
&& param
<0)
159 goto invalid_value_error
;
160 ctx
->Unpack
.SkipPixels
= param
;
162 case GL_UNPACK_SKIP_ROWS
:
163 if (!no_error
&& ctx
->API
== API_OPENGLES
)
164 goto invalid_enum_error
;
165 if (!no_error
&& param
<0)
166 goto invalid_value_error
;
167 ctx
->Unpack
.SkipRows
= param
;
169 case GL_UNPACK_SKIP_IMAGES
:
170 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
171 goto invalid_enum_error
;
172 if (!no_error
&& param
< 0)
173 goto invalid_value_error
;
174 ctx
->Unpack
.SkipImages
= param
;
176 case GL_UNPACK_ALIGNMENT
:
177 if (!no_error
&& param
!=1 && param
!=2 && param
!=4 && param
!=8)
178 goto invalid_value_error
;
179 ctx
->Unpack
.Alignment
= param
;
181 case GL_UNPACK_COMPRESSED_BLOCK_WIDTH
:
182 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
183 goto invalid_enum_error
;
184 if (!no_error
&& param
<0)
185 goto invalid_value_error
;
186 ctx
->Unpack
.CompressedBlockWidth
= param
;
188 case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT
:
189 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
190 goto invalid_enum_error
;
191 if (!no_error
&& param
<0)
192 goto invalid_value_error
;
193 ctx
->Unpack
.CompressedBlockHeight
= param
;
195 case GL_UNPACK_COMPRESSED_BLOCK_DEPTH
:
196 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
197 goto invalid_enum_error
;
198 if (!no_error
&& param
<0)
199 goto invalid_value_error
;
200 ctx
->Unpack
.CompressedBlockDepth
= param
;
202 case GL_UNPACK_COMPRESSED_BLOCK_SIZE
:
203 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
204 goto invalid_enum_error
;
205 if (!no_error
&& param
<0)
206 goto invalid_value_error
;
207 ctx
->Unpack
.CompressedBlockSize
= param
;
211 goto invalid_enum_error
;
213 unreachable("invalid pixel store enum");
219 _mesa_error(ctx
, GL_INVALID_ENUM
, "glPixelStore");
223 _mesa_error(ctx
, GL_INVALID_VALUE
, "glPixelStore(param)");
229 _mesa_PixelStorei(GLenum pname
, GLint param
)
231 pixel_storei(pname
, param
, false);
236 _mesa_PixelStoref(GLenum pname
, GLfloat param
)
238 _mesa_PixelStorei(pname
, lroundf(param
));
243 _mesa_PixelStorei_no_error(GLenum pname
, GLint param
)
245 pixel_storei(pname
, param
, true);
250 _mesa_PixelStoref_no_error(GLenum pname
, GLfloat param
)
252 _mesa_PixelStorei_no_error(pname
, lroundf(param
));
257 * Initialize the context's pixel store state.
260 _mesa_init_pixelstore(struct gl_context
*ctx
)
263 ctx
->Pack
.Alignment
= 4;
264 ctx
->Pack
.RowLength
= 0;
265 ctx
->Pack
.ImageHeight
= 0;
266 ctx
->Pack
.SkipPixels
= 0;
267 ctx
->Pack
.SkipRows
= 0;
268 ctx
->Pack
.SkipImages
= 0;
269 ctx
->Pack
.SwapBytes
= GL_FALSE
;
270 ctx
->Pack
.LsbFirst
= GL_FALSE
;
271 ctx
->Pack
.Invert
= GL_FALSE
;
272 ctx
->Pack
.CompressedBlockWidth
= 0;
273 ctx
->Pack
.CompressedBlockHeight
= 0;
274 ctx
->Pack
.CompressedBlockDepth
= 0;
275 ctx
->Pack
.CompressedBlockSize
= 0;
276 _mesa_reference_buffer_object(ctx
, &ctx
->Pack
.BufferObj
, NULL
);
277 ctx
->Unpack
.Alignment
= 4;
278 ctx
->Unpack
.RowLength
= 0;
279 ctx
->Unpack
.ImageHeight
= 0;
280 ctx
->Unpack
.SkipPixels
= 0;
281 ctx
->Unpack
.SkipRows
= 0;
282 ctx
->Unpack
.SkipImages
= 0;
283 ctx
->Unpack
.SwapBytes
= GL_FALSE
;
284 ctx
->Unpack
.LsbFirst
= GL_FALSE
;
285 ctx
->Unpack
.Invert
= GL_FALSE
;
286 ctx
->Unpack
.CompressedBlockWidth
= 0;
287 ctx
->Unpack
.CompressedBlockHeight
= 0;
288 ctx
->Unpack
.CompressedBlockDepth
= 0;
289 ctx
->Unpack
.CompressedBlockSize
= 0;
290 _mesa_reference_buffer_object(ctx
, &ctx
->Unpack
.BufferObj
, NULL
);
293 * _mesa_unpack_image() returns image data in this format. When we
294 * execute image commands (glDrawPixels(), glTexImage(), etc) from
295 * within display lists we have to be sure to set the current
296 * unpacking parameters to these values!
298 ctx
->DefaultPacking
.Alignment
= 1;
299 ctx
->DefaultPacking
.RowLength
= 0;
300 ctx
->DefaultPacking
.SkipPixels
= 0;
301 ctx
->DefaultPacking
.SkipRows
= 0;
302 ctx
->DefaultPacking
.ImageHeight
= 0;
303 ctx
->DefaultPacking
.SkipImages
= 0;
304 ctx
->DefaultPacking
.SwapBytes
= GL_FALSE
;
305 ctx
->DefaultPacking
.LsbFirst
= GL_FALSE
;
306 ctx
->DefaultPacking
.Invert
= GL_FALSE
;
307 _mesa_reference_buffer_object(ctx
, &ctx
->DefaultPacking
.BufferObj
, NULL
);
312 * Check if the given compressed pixel storage parameters are legal.
313 * Record a GL error if illegal.
314 * \return true if legal, false if illegal
317 _mesa_compressed_pixel_storage_error_check(
318 struct gl_context
*ctx
,
320 const struct gl_pixelstore_attrib
*packing
,
323 if (!_mesa_is_desktop_gl(ctx
) || !packing
->CompressedBlockSize
)
326 if (packing
->CompressedBlockWidth
&&
327 packing
->SkipPixels
% packing
->CompressedBlockWidth
) {
328 _mesa_error(ctx
, GL_INVALID_OPERATION
,
329 "%s(skip-pixels %% block-width)", caller
);
333 if (dimensions
> 1 &&
334 packing
->CompressedBlockHeight
&&
335 packing
->SkipRows
% packing
->CompressedBlockHeight
) {
336 _mesa_error(ctx
, GL_INVALID_OPERATION
,
337 "%s(skip-rows %% block-height)", caller
);
341 if (dimensions
> 2 &&
342 packing
->CompressedBlockDepth
&&
343 packing
->SkipImages
% packing
->CompressedBlockDepth
) {
344 _mesa_error(ctx
, GL_INVALID_OPERATION
,
345 "%s(skip-images %% block-depth)", caller
);