mesa: split bind_buffer_range_uniform_buffer() in two
[mesa.git] / src / mesa / main / pixelstore.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
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.
23 */
24
25 /**
26 * \file pixelstore.c
27 * glPixelStore functions.
28 */
29
30
31 #include "glheader.h"
32 #include "bufferobj.h"
33 #include "context.h"
34 #include "pixelstore.h"
35 #include "mtypes.h"
36
37
38 void GLAPIENTRY
39 _mesa_PixelStorei( GLenum pname, GLint param )
40 {
41 /* NOTE: this call can't be compiled into the display list */
42 GET_CURRENT_CONTEXT(ctx);
43
44 switch (pname) {
45 case GL_PACK_SWAP_BYTES:
46 if (!_mesa_is_desktop_gl(ctx))
47 goto invalid_enum_error;
48 ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
49 break;
50 case GL_PACK_LSB_FIRST:
51 if (!_mesa_is_desktop_gl(ctx))
52 goto invalid_enum_error;
53 ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
54 break;
55 case GL_PACK_ROW_LENGTH:
56 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
57 goto invalid_enum_error;
58 if (param<0)
59 goto invalid_value_error;
60 ctx->Pack.RowLength = param;
61 break;
62 case GL_PACK_IMAGE_HEIGHT:
63 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
64 goto invalid_enum_error;
65 if (param<0)
66 goto invalid_value_error;
67 ctx->Pack.ImageHeight = param;
68 break;
69 case GL_PACK_SKIP_PIXELS:
70 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
71 goto invalid_enum_error;
72 if (param<0)
73 goto invalid_value_error;
74 ctx->Pack.SkipPixels = param;
75 break;
76 case GL_PACK_SKIP_ROWS:
77 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
78 goto invalid_enum_error;
79 if (param<0)
80 goto invalid_value_error;
81 ctx->Pack.SkipRows = param;
82 break;
83 case GL_PACK_SKIP_IMAGES:
84 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
85 goto invalid_enum_error;
86 if (param<0)
87 goto invalid_value_error;
88 ctx->Pack.SkipImages = param;
89 break;
90 case GL_PACK_ALIGNMENT:
91 if (param!=1 && param!=2 && param!=4 && param!=8)
92 goto invalid_value_error;
93 ctx->Pack.Alignment = param;
94 break;
95 case GL_PACK_INVERT_MESA:
96 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.MESA_pack_invert)
97 goto invalid_enum_error;
98 ctx->Pack.Invert = param;
99 break;
100 case GL_PACK_COMPRESSED_BLOCK_WIDTH:
101 if (!_mesa_is_desktop_gl(ctx))
102 goto invalid_enum_error;
103 if (param<0)
104 goto invalid_value_error;
105 ctx->Pack.CompressedBlockWidth = param;
106 break;
107 case GL_PACK_COMPRESSED_BLOCK_HEIGHT:
108 if (!_mesa_is_desktop_gl(ctx))
109 goto invalid_enum_error;
110 if (param<0)
111 goto invalid_value_error;
112 ctx->Pack.CompressedBlockHeight = param;
113 break;
114 case GL_PACK_COMPRESSED_BLOCK_DEPTH:
115 if (!_mesa_is_desktop_gl(ctx))
116 goto invalid_enum_error;
117 if (param<0)
118 goto invalid_value_error;
119 ctx->Pack.CompressedBlockDepth = param;
120 break;
121 case GL_PACK_COMPRESSED_BLOCK_SIZE:
122 if (!_mesa_is_desktop_gl(ctx))
123 goto invalid_enum_error;
124 if (param<0)
125 goto invalid_value_error;
126 ctx->Pack.CompressedBlockSize = param;
127 break;
128
129 case GL_UNPACK_SWAP_BYTES:
130 if (!_mesa_is_desktop_gl(ctx))
131 goto invalid_enum_error;
132 ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
133 break;
134 case GL_UNPACK_LSB_FIRST:
135 if (!_mesa_is_desktop_gl(ctx))
136 goto invalid_enum_error;
137 ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
138 break;
139 case GL_UNPACK_ROW_LENGTH:
140 if (ctx->API == API_OPENGLES)
141 goto invalid_enum_error;
142 if (param<0)
143 goto invalid_value_error;
144 ctx->Unpack.RowLength = param;
145 break;
146 case GL_UNPACK_IMAGE_HEIGHT:
147 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
148 goto invalid_enum_error;
149 if (param<0)
150 goto invalid_value_error;
151 ctx->Unpack.ImageHeight = param;
152 break;
153 case GL_UNPACK_SKIP_PIXELS:
154 if (ctx->API == API_OPENGLES)
155 goto invalid_enum_error;
156 if (param<0)
157 goto invalid_value_error;
158 ctx->Unpack.SkipPixels = param;
159 break;
160 case GL_UNPACK_SKIP_ROWS:
161 if (ctx->API == API_OPENGLES)
162 goto invalid_enum_error;
163 if (param<0)
164 goto invalid_value_error;
165 ctx->Unpack.SkipRows = param;
166 break;
167 case GL_UNPACK_SKIP_IMAGES:
168 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
169 goto invalid_enum_error;
170 if (param < 0)
171 goto invalid_value_error;
172 ctx->Unpack.SkipImages = param;
173 break;
174 case GL_UNPACK_ALIGNMENT:
175 if (param!=1 && param!=2 && param!=4 && param!=8)
176 goto invalid_value_error;
177 ctx->Unpack.Alignment = param;
178 break;
179 case GL_UNPACK_COMPRESSED_BLOCK_WIDTH:
180 if (!_mesa_is_desktop_gl(ctx))
181 goto invalid_enum_error;
182 if (param<0)
183 goto invalid_value_error;
184 ctx->Unpack.CompressedBlockWidth = param;
185 break;
186 case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT:
187 if (!_mesa_is_desktop_gl(ctx))
188 goto invalid_enum_error;
189 if (param<0)
190 goto invalid_value_error;
191 ctx->Unpack.CompressedBlockHeight = param;
192 break;
193 case GL_UNPACK_COMPRESSED_BLOCK_DEPTH:
194 if (!_mesa_is_desktop_gl(ctx))
195 goto invalid_enum_error;
196 if (param<0)
197 goto invalid_value_error;
198 ctx->Unpack.CompressedBlockDepth = param;
199 break;
200 case GL_UNPACK_COMPRESSED_BLOCK_SIZE:
201 if (!_mesa_is_desktop_gl(ctx))
202 goto invalid_enum_error;
203 if (param<0)
204 goto invalid_value_error;
205 ctx->Unpack.CompressedBlockSize = param;
206 break;
207 default:
208 goto invalid_enum_error;
209 }
210
211 return;
212
213 invalid_enum_error:
214 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
215 return;
216
217 invalid_value_error:
218 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
219 return;
220 }
221
222
223 void GLAPIENTRY
224 _mesa_PixelStoref( GLenum pname, GLfloat param )
225 {
226 _mesa_PixelStorei( pname, IROUND(param) );
227 }
228
229
230
231 /**
232 * Initialize the context's pixel store state.
233 */
234 void
235 _mesa_init_pixelstore( struct gl_context *ctx )
236 {
237 /* Pixel transfer */
238 ctx->Pack.Alignment = 4;
239 ctx->Pack.RowLength = 0;
240 ctx->Pack.ImageHeight = 0;
241 ctx->Pack.SkipPixels = 0;
242 ctx->Pack.SkipRows = 0;
243 ctx->Pack.SkipImages = 0;
244 ctx->Pack.SwapBytes = GL_FALSE;
245 ctx->Pack.LsbFirst = GL_FALSE;
246 ctx->Pack.Invert = GL_FALSE;
247 ctx->Pack.CompressedBlockWidth = 0;
248 ctx->Pack.CompressedBlockHeight = 0;
249 ctx->Pack.CompressedBlockDepth = 0;
250 ctx->Pack.CompressedBlockSize = 0;
251 _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj,
252 ctx->Shared->NullBufferObj);
253 ctx->Unpack.Alignment = 4;
254 ctx->Unpack.RowLength = 0;
255 ctx->Unpack.ImageHeight = 0;
256 ctx->Unpack.SkipPixels = 0;
257 ctx->Unpack.SkipRows = 0;
258 ctx->Unpack.SkipImages = 0;
259 ctx->Unpack.SwapBytes = GL_FALSE;
260 ctx->Unpack.LsbFirst = GL_FALSE;
261 ctx->Unpack.Invert = GL_FALSE;
262 ctx->Unpack.CompressedBlockWidth = 0;
263 ctx->Unpack.CompressedBlockHeight = 0;
264 ctx->Unpack.CompressedBlockDepth = 0;
265 ctx->Unpack.CompressedBlockSize = 0;
266 _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj,
267 ctx->Shared->NullBufferObj);
268
269 /*
270 * _mesa_unpack_image() returns image data in this format. When we
271 * execute image commands (glDrawPixels(), glTexImage(), etc) from
272 * within display lists we have to be sure to set the current
273 * unpacking parameters to these values!
274 */
275 ctx->DefaultPacking.Alignment = 1;
276 ctx->DefaultPacking.RowLength = 0;
277 ctx->DefaultPacking.SkipPixels = 0;
278 ctx->DefaultPacking.SkipRows = 0;
279 ctx->DefaultPacking.ImageHeight = 0;
280 ctx->DefaultPacking.SkipImages = 0;
281 ctx->DefaultPacking.SwapBytes = GL_FALSE;
282 ctx->DefaultPacking.LsbFirst = GL_FALSE;
283 ctx->DefaultPacking.Invert = GL_FALSE;
284 _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj,
285 ctx->Shared->NullBufferObj);
286 }
287
288
289 /**
290 * Check if the given compressed pixel storage parameters are legal.
291 * Record a GL error if illegal.
292 * \return true if legal, false if illegal
293 */
294 bool
295 _mesa_compressed_pixel_storage_error_check(
296 struct gl_context *ctx,
297 GLint dimensions,
298 const struct gl_pixelstore_attrib *packing,
299 const char *caller)
300 {
301 if (!_mesa_is_desktop_gl(ctx) || !packing->CompressedBlockSize)
302 return true;
303
304 if (packing->CompressedBlockWidth &&
305 packing->SkipPixels % packing->CompressedBlockWidth) {
306 _mesa_error(ctx, GL_INVALID_OPERATION,
307 "%s(skip-pixels %% block-width)", caller);
308 return false;
309 }
310
311 if (dimensions > 1 &&
312 packing->CompressedBlockHeight &&
313 packing->SkipRows % packing->CompressedBlockHeight) {
314 _mesa_error(ctx, GL_INVALID_OPERATION,
315 "%s(skip-rows %% block-height)", caller);
316 return false;
317 }
318
319 if (dimensions > 2 &&
320 packing->CompressedBlockDepth &&
321 packing->SkipImages % packing->CompressedBlockDepth) {
322 _mesa_error(ctx, GL_INVALID_OPERATION,
323 "%s(skip-images %% block-depth)", caller);
324 return false;
325 }
326
327 return true;
328 }