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"
38 static ALWAYS_INLINE
void
39 pixel_storei(GLenum pname
, GLint param
, bool no_error
)
41 /* NOTE: this call can't be compiled into the display list */
42 GET_CURRENT_CONTEXT(ctx
);
45 case GL_PACK_SWAP_BYTES
:
46 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
47 goto invalid_enum_error
;
48 ctx
->Pack
.SwapBytes
= param
? GL_TRUE
: GL_FALSE
;
50 case GL_PACK_LSB_FIRST
:
51 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
52 goto invalid_enum_error
;
53 ctx
->Pack
.LsbFirst
= param
? GL_TRUE
: GL_FALSE
;
55 case GL_PACK_ROW_LENGTH
:
56 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
57 goto invalid_enum_error
;
58 if (!no_error
&& param
<0)
59 goto invalid_value_error
;
60 ctx
->Pack
.RowLength
= param
;
62 case GL_PACK_IMAGE_HEIGHT
:
63 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
64 goto invalid_enum_error
;
65 if (!no_error
&& param
<0)
66 goto invalid_value_error
;
67 ctx
->Pack
.ImageHeight
= param
;
69 case GL_PACK_SKIP_PIXELS
:
70 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
71 goto invalid_enum_error
;
72 if (!no_error
&& param
<0)
73 goto invalid_value_error
;
74 ctx
->Pack
.SkipPixels
= param
;
76 case GL_PACK_SKIP_ROWS
:
77 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
78 goto invalid_enum_error
;
79 if (!no_error
&& param
<0)
80 goto invalid_value_error
;
81 ctx
->Pack
.SkipRows
= param
;
83 case GL_PACK_SKIP_IMAGES
:
84 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
85 goto invalid_enum_error
;
86 if (!no_error
&& param
<0)
87 goto invalid_value_error
;
88 ctx
->Pack
.SkipImages
= param
;
90 case GL_PACK_ALIGNMENT
:
91 if (!no_error
&& param
!=1 && param
!=2 && param
!=4 && param
!=8)
92 goto invalid_value_error
;
93 ctx
->Pack
.Alignment
= param
;
95 case GL_PACK_INVERT_MESA
:
97 (!_mesa_is_desktop_gl(ctx
) || !ctx
->Extensions
.MESA_pack_invert
))
98 goto invalid_enum_error
;
99 ctx
->Pack
.Invert
= param
;
101 case GL_PACK_COMPRESSED_BLOCK_WIDTH
:
102 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
103 goto invalid_enum_error
;
104 if (!no_error
&& param
<0)
105 goto invalid_value_error
;
106 ctx
->Pack
.CompressedBlockWidth
= param
;
108 case GL_PACK_COMPRESSED_BLOCK_HEIGHT
:
109 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
110 goto invalid_enum_error
;
111 if (!no_error
&& param
<0)
112 goto invalid_value_error
;
113 ctx
->Pack
.CompressedBlockHeight
= param
;
115 case GL_PACK_COMPRESSED_BLOCK_DEPTH
:
116 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
117 goto invalid_enum_error
;
118 if (!no_error
&& param
<0)
119 goto invalid_value_error
;
120 ctx
->Pack
.CompressedBlockDepth
= param
;
122 case GL_PACK_COMPRESSED_BLOCK_SIZE
:
123 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
124 goto invalid_enum_error
;
125 if (!no_error
&& param
<0)
126 goto invalid_value_error
;
127 ctx
->Pack
.CompressedBlockSize
= param
;
130 case GL_UNPACK_SWAP_BYTES
:
131 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
132 goto invalid_enum_error
;
133 ctx
->Unpack
.SwapBytes
= param
? GL_TRUE
: GL_FALSE
;
135 case GL_UNPACK_LSB_FIRST
:
136 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
137 goto invalid_enum_error
;
138 ctx
->Unpack
.LsbFirst
= param
? GL_TRUE
: GL_FALSE
;
140 case GL_UNPACK_ROW_LENGTH
:
141 if (!no_error
&& ctx
->API
== API_OPENGLES
)
142 goto invalid_enum_error
;
143 if (!no_error
&& param
<0)
144 goto invalid_value_error
;
145 ctx
->Unpack
.RowLength
= param
;
147 case GL_UNPACK_IMAGE_HEIGHT
:
148 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
149 goto invalid_enum_error
;
150 if (!no_error
&& param
<0)
151 goto invalid_value_error
;
152 ctx
->Unpack
.ImageHeight
= param
;
154 case GL_UNPACK_SKIP_PIXELS
:
155 if (!no_error
&& ctx
->API
== API_OPENGLES
)
156 goto invalid_enum_error
;
157 if (!no_error
&& param
<0)
158 goto invalid_value_error
;
159 ctx
->Unpack
.SkipPixels
= param
;
161 case GL_UNPACK_SKIP_ROWS
:
162 if (!no_error
&& ctx
->API
== API_OPENGLES
)
163 goto invalid_enum_error
;
164 if (!no_error
&& param
<0)
165 goto invalid_value_error
;
166 ctx
->Unpack
.SkipRows
= param
;
168 case GL_UNPACK_SKIP_IMAGES
:
169 if (!no_error
&& !_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
170 goto invalid_enum_error
;
171 if (!no_error
&& param
< 0)
172 goto invalid_value_error
;
173 ctx
->Unpack
.SkipImages
= param
;
175 case GL_UNPACK_ALIGNMENT
:
176 if (!no_error
&& param
!=1 && param
!=2 && param
!=4 && param
!=8)
177 goto invalid_value_error
;
178 ctx
->Unpack
.Alignment
= param
;
180 case GL_UNPACK_COMPRESSED_BLOCK_WIDTH
:
181 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
182 goto invalid_enum_error
;
183 if (!no_error
&& param
<0)
184 goto invalid_value_error
;
185 ctx
->Unpack
.CompressedBlockWidth
= param
;
187 case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT
:
188 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
189 goto invalid_enum_error
;
190 if (!no_error
&& param
<0)
191 goto invalid_value_error
;
192 ctx
->Unpack
.CompressedBlockHeight
= param
;
194 case GL_UNPACK_COMPRESSED_BLOCK_DEPTH
:
195 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
196 goto invalid_enum_error
;
197 if (!no_error
&& param
<0)
198 goto invalid_value_error
;
199 ctx
->Unpack
.CompressedBlockDepth
= param
;
201 case GL_UNPACK_COMPRESSED_BLOCK_SIZE
:
202 if (!no_error
&& !_mesa_is_desktop_gl(ctx
))
203 goto invalid_enum_error
;
204 if (!no_error
&& param
<0)
205 goto invalid_value_error
;
206 ctx
->Unpack
.CompressedBlockSize
= param
;
210 goto invalid_enum_error
;
212 unreachable("invalid pixel store enum");
218 _mesa_error(ctx
, GL_INVALID_ENUM
, "glPixelStore");
222 _mesa_error(ctx
, GL_INVALID_VALUE
, "glPixelStore(param)");
228 _mesa_PixelStorei(GLenum pname
, GLint param
)
230 pixel_storei(pname
, param
, false);
235 _mesa_PixelStoref(GLenum pname
, GLfloat param
)
237 _mesa_PixelStorei(pname
, IROUND(param
));
242 _mesa_PixelStorei_no_error(GLenum pname
, GLint param
)
244 pixel_storei(pname
, param
, true);
249 _mesa_PixelStoref_no_error(GLenum pname
, GLfloat param
)
251 _mesa_PixelStorei_no_error(pname
, IROUND(param
));
256 * Initialize the context's pixel store state.
259 _mesa_init_pixelstore(struct gl_context
*ctx
)
262 ctx
->Pack
.Alignment
= 4;
263 ctx
->Pack
.RowLength
= 0;
264 ctx
->Pack
.ImageHeight
= 0;
265 ctx
->Pack
.SkipPixels
= 0;
266 ctx
->Pack
.SkipRows
= 0;
267 ctx
->Pack
.SkipImages
= 0;
268 ctx
->Pack
.SwapBytes
= GL_FALSE
;
269 ctx
->Pack
.LsbFirst
= GL_FALSE
;
270 ctx
->Pack
.Invert
= GL_FALSE
;
271 ctx
->Pack
.CompressedBlockWidth
= 0;
272 ctx
->Pack
.CompressedBlockHeight
= 0;
273 ctx
->Pack
.CompressedBlockDepth
= 0;
274 ctx
->Pack
.CompressedBlockSize
= 0;
275 _mesa_reference_buffer_object(ctx
, &ctx
->Pack
.BufferObj
,
276 ctx
->Shared
->NullBufferObj
);
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
,
291 ctx
->Shared
->NullBufferObj
);
294 * _mesa_unpack_image() returns image data in this format. When we
295 * execute image commands (glDrawPixels(), glTexImage(), etc) from
296 * within display lists we have to be sure to set the current
297 * unpacking parameters to these values!
299 ctx
->DefaultPacking
.Alignment
= 1;
300 ctx
->DefaultPacking
.RowLength
= 0;
301 ctx
->DefaultPacking
.SkipPixels
= 0;
302 ctx
->DefaultPacking
.SkipRows
= 0;
303 ctx
->DefaultPacking
.ImageHeight
= 0;
304 ctx
->DefaultPacking
.SkipImages
= 0;
305 ctx
->DefaultPacking
.SwapBytes
= GL_FALSE
;
306 ctx
->DefaultPacking
.LsbFirst
= GL_FALSE
;
307 ctx
->DefaultPacking
.Invert
= GL_FALSE
;
308 _mesa_reference_buffer_object(ctx
, &ctx
->DefaultPacking
.BufferObj
,
309 ctx
->Shared
->NullBufferObj
);
314 * Check if the given compressed pixel storage parameters are legal.
315 * Record a GL error if illegal.
316 * \return true if legal, false if illegal
319 _mesa_compressed_pixel_storage_error_check(
320 struct gl_context
*ctx
,
322 const struct gl_pixelstore_attrib
*packing
,
325 if (!_mesa_is_desktop_gl(ctx
) || !packing
->CompressedBlockSize
)
328 if (packing
->CompressedBlockWidth
&&
329 packing
->SkipPixels
% packing
->CompressedBlockWidth
) {
330 _mesa_error(ctx
, GL_INVALID_OPERATION
,
331 "%s(skip-pixels %% block-width)", caller
);
335 if (dimensions
> 1 &&
336 packing
->CompressedBlockHeight
&&
337 packing
->SkipRows
% packing
->CompressedBlockHeight
) {
338 _mesa_error(ctx
, GL_INVALID_OPERATION
,
339 "%s(skip-rows %% block-height)", caller
);
343 if (dimensions
> 2 &&
344 packing
->CompressedBlockDepth
&&
345 packing
->SkipImages
% packing
->CompressedBlockDepth
) {
346 _mesa_error(ctx
, GL_INVALID_OPERATION
,
347 "%s(skip-images %% block-depth)", caller
);