softpipe: Remove unnecessary headers.
[mesa.git] / src / mesa / main / pixel.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file pixel.c
28 * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer)
29 */
30
31 #include "glheader.h"
32 #include "bufferobj.h"
33 #include "colormac.h"
34 #include "context.h"
35 #include "macros.h"
36 #include "pixel.h"
37 #include "mtypes.h"
38 #include "glapi/dispatch.h"
39
40
41 #if FEATURE_pixel_transfer
42
43
44 /**********************************************************************/
45 /***** glPixelZoom *****/
46 /**********************************************************************/
47
48 static void GLAPIENTRY
49 _mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
50 {
51 GET_CURRENT_CONTEXT(ctx);
52
53 if (ctx->Pixel.ZoomX == xfactor &&
54 ctx->Pixel.ZoomY == yfactor)
55 return;
56
57 FLUSH_VERTICES(ctx, _NEW_PIXEL);
58 ctx->Pixel.ZoomX = xfactor;
59 ctx->Pixel.ZoomY = yfactor;
60 }
61
62
63
64 /**********************************************************************/
65 /***** glPixelMap *****/
66 /**********************************************************************/
67
68 /**
69 * Return pointer to a pixelmap by name.
70 */
71 static struct gl_pixelmap *
72 get_pixelmap(GLcontext *ctx, GLenum map)
73 {
74 switch (map) {
75 case GL_PIXEL_MAP_I_TO_I:
76 return &ctx->PixelMaps.ItoI;
77 case GL_PIXEL_MAP_S_TO_S:
78 return &ctx->PixelMaps.StoS;
79 case GL_PIXEL_MAP_I_TO_R:
80 return &ctx->PixelMaps.ItoR;
81 case GL_PIXEL_MAP_I_TO_G:
82 return &ctx->PixelMaps.ItoG;
83 case GL_PIXEL_MAP_I_TO_B:
84 return &ctx->PixelMaps.ItoB;
85 case GL_PIXEL_MAP_I_TO_A:
86 return &ctx->PixelMaps.ItoA;
87 case GL_PIXEL_MAP_R_TO_R:
88 return &ctx->PixelMaps.RtoR;
89 case GL_PIXEL_MAP_G_TO_G:
90 return &ctx->PixelMaps.GtoG;
91 case GL_PIXEL_MAP_B_TO_B:
92 return &ctx->PixelMaps.BtoB;
93 case GL_PIXEL_MAP_A_TO_A:
94 return &ctx->PixelMaps.AtoA;
95 default:
96 return NULL;
97 }
98 }
99
100
101 /**
102 * Helper routine used by the other _mesa_PixelMap() functions.
103 */
104 static void
105 store_pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize,
106 const GLfloat *values)
107 {
108 GLint i;
109 struct gl_pixelmap *pm = get_pixelmap(ctx, map);
110 if (!pm) {
111 _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)");
112 return;
113 }
114
115 switch (map) {
116 case GL_PIXEL_MAP_S_TO_S:
117 /* special case */
118 ctx->PixelMaps.StoS.Size = mapsize;
119 for (i = 0; i < mapsize; i++) {
120 ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]);
121 }
122 break;
123 case GL_PIXEL_MAP_I_TO_I:
124 /* special case */
125 ctx->PixelMaps.ItoI.Size = mapsize;
126 for (i = 0; i < mapsize; i++) {
127 ctx->PixelMaps.ItoI.Map[i] = values[i];
128 }
129 break;
130 default:
131 /* general case */
132 pm->Size = mapsize;
133 for (i = 0; i < mapsize; i++) {
134 GLfloat val = CLAMP(values[i], 0.0F, 1.0F);
135 pm->Map[i] = val;
136 pm->Map8[i] = (GLint) (val * 255.0F);
137 }
138 }
139 }
140
141
142 /**
143 * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap().
144 */
145 static GLboolean
146 validate_pbo_access(GLcontext *ctx, struct gl_pixelstore_attrib *pack,
147 GLsizei mapsize, GLenum format, GLenum type,
148 const GLvoid *ptr)
149 {
150 GLboolean ok;
151
152 /* Note, need to use DefaultPacking and Unpack's buffer object */
153 ctx->DefaultPacking.BufferObj = pack->BufferObj;
154
155 ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
156 format, type, ptr);
157
158 /* restore */
159 ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
160
161 if (!ok) {
162 _mesa_error(ctx, GL_INVALID_OPERATION,
163 "glPixelMap(invalid PBO access)");
164 }
165 return ok;
166 }
167
168
169 static void GLAPIENTRY
170 _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
171 {
172 GET_CURRENT_CONTEXT(ctx);
173 ASSERT_OUTSIDE_BEGIN_END(ctx);
174
175 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
176 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
177 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
178 return;
179 }
180
181 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
182 /* test that mapsize is a power of two */
183 if (!_mesa_is_pow_two(mapsize)) {
184 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
185 return;
186 }
187 }
188
189 FLUSH_VERTICES(ctx, _NEW_PIXEL);
190
191 if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
192 GL_INTENSITY, GL_FLOAT, values)) {
193 return;
194 }
195
196 values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
197 if (!values) {
198 if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
199 _mesa_error(ctx, GL_INVALID_OPERATION,
200 "glPixelMapfv(PBO is mapped)");
201 }
202 return;
203 }
204
205 store_pixelmap(ctx, map, mapsize, values);
206
207 _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
208 }
209
210
211 static void GLAPIENTRY
212 _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
213 {
214 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
215 GET_CURRENT_CONTEXT(ctx);
216 ASSERT_OUTSIDE_BEGIN_END(ctx);
217
218 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
219 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
220 return;
221 }
222
223 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
224 /* test that mapsize is a power of two */
225 if (!_mesa_is_pow_two(mapsize)) {
226 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
227 return;
228 }
229 }
230
231 FLUSH_VERTICES(ctx, _NEW_PIXEL);
232
233 if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
234 GL_INTENSITY, GL_UNSIGNED_INT, values)) {
235 return;
236 }
237
238 values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
239 if (!values) {
240 if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
241 _mesa_error(ctx, GL_INVALID_OPERATION,
242 "glPixelMapuiv(PBO is mapped)");
243 }
244 return;
245 }
246
247 /* convert to floats */
248 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
249 GLint i;
250 for (i = 0; i < mapsize; i++) {
251 fvalues[i] = (GLfloat) values[i];
252 }
253 }
254 else {
255 GLint i;
256 for (i = 0; i < mapsize; i++) {
257 fvalues[i] = UINT_TO_FLOAT( values[i] );
258 }
259 }
260
261 _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
262
263 store_pixelmap(ctx, map, mapsize, fvalues);
264 }
265
266
267 static void GLAPIENTRY
268 _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
269 {
270 GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
271 GET_CURRENT_CONTEXT(ctx);
272 ASSERT_OUTSIDE_BEGIN_END(ctx);
273
274 if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) {
275 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" );
276 return;
277 }
278
279 if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) {
280 /* test that mapsize is a power of two */
281 if (!_mesa_is_pow_two(mapsize)) {
282 _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" );
283 return;
284 }
285 }
286
287 FLUSH_VERTICES(ctx, _NEW_PIXEL);
288
289 if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
290 GL_INTENSITY, GL_UNSIGNED_SHORT, values)) {
291 return;
292 }
293
294 values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
295 if (!values) {
296 if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
297 _mesa_error(ctx, GL_INVALID_OPERATION,
298 "glPixelMapusv(PBO is mapped)");
299 }
300 return;
301 }
302
303 /* convert to floats */
304 if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) {
305 GLint i;
306 for (i = 0; i < mapsize; i++) {
307 fvalues[i] = (GLfloat) values[i];
308 }
309 }
310 else {
311 GLint i;
312 for (i = 0; i < mapsize; i++) {
313 fvalues[i] = USHORT_TO_FLOAT( values[i] );
314 }
315 }
316
317 _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
318
319 store_pixelmap(ctx, map, mapsize, fvalues);
320 }
321
322
323 static void GLAPIENTRY
324 _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
325 {
326 GET_CURRENT_CONTEXT(ctx);
327 GLuint mapsize, i;
328 const struct gl_pixelmap *pm;
329
330 ASSERT_OUTSIDE_BEGIN_END(ctx);
331
332 pm = get_pixelmap(ctx, map);
333 if (!pm) {
334 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)");
335 return;
336 }
337
338 mapsize = pm->Size;
339
340 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
341 GL_INTENSITY, GL_FLOAT, values)) {
342 return;
343 }
344
345 values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
346 if (!values) {
347 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
348 _mesa_error(ctx, GL_INVALID_OPERATION,
349 "glGetPixelMapfv(PBO is mapped)");
350 }
351 return;
352 }
353
354 if (map == GL_PIXEL_MAP_S_TO_S) {
355 /* special case */
356 for (i = 0; i < mapsize; i++) {
357 values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i];
358 }
359 }
360 else {
361 MEMCPY(values, pm->Map, mapsize * sizeof(GLfloat));
362 }
363
364 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
365 }
366
367
368 static void GLAPIENTRY
369 _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
370 {
371 GET_CURRENT_CONTEXT(ctx);
372 GLint mapsize, i;
373 const struct gl_pixelmap *pm;
374
375 ASSERT_OUTSIDE_BEGIN_END(ctx);
376
377 pm = get_pixelmap(ctx, map);
378 if (!pm) {
379 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)");
380 return;
381 }
382 mapsize = pm->Size;
383
384 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
385 GL_INTENSITY, GL_UNSIGNED_INT, values)) {
386 return;
387 }
388
389 values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
390 if (!values) {
391 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
392 _mesa_error(ctx, GL_INVALID_OPERATION,
393 "glGetPixelMapuiv(PBO is mapped)");
394 }
395 return;
396 }
397
398 if (map == GL_PIXEL_MAP_S_TO_S) {
399 /* special case */
400 MEMCPY(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint));
401 }
402 else {
403 for (i = 0; i < mapsize; i++) {
404 values[i] = FLOAT_TO_UINT( pm->Map[i] );
405 }
406 }
407
408 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
409 }
410
411
412 static void GLAPIENTRY
413 _mesa_GetPixelMapusv( GLenum map, GLushort *values )
414 {
415 GET_CURRENT_CONTEXT(ctx);
416 GLint mapsize, i;
417 const struct gl_pixelmap *pm;
418
419 ASSERT_OUTSIDE_BEGIN_END(ctx);
420
421 pm = get_pixelmap(ctx, map);
422 if (!pm) {
423 _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)");
424 return;
425 }
426 mapsize = pm ? pm->Size : 0;
427
428 if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
429 GL_INTENSITY, GL_UNSIGNED_SHORT, values)) {
430 return;
431 }
432
433 values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
434 if (!values) {
435 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
436 _mesa_error(ctx, GL_INVALID_OPERATION,
437 "glGetPixelMapusv(PBO is mapped)");
438 }
439 return;
440 }
441
442 switch (map) {
443 /* special cases */
444 case GL_PIXEL_MAP_I_TO_I:
445 for (i = 0; i < mapsize; i++) {
446 values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0, 65535.);
447 }
448 break;
449 case GL_PIXEL_MAP_S_TO_S:
450 for (i = 0; i < mapsize; i++) {
451 values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0, 65535.);
452 }
453 break;
454 default:
455 for (i = 0; i < mapsize; i++) {
456 CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] );
457 }
458 }
459
460 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
461 }
462
463
464
465 /**********************************************************************/
466 /***** glPixelTransfer *****/
467 /**********************************************************************/
468
469
470 /*
471 * Implements glPixelTransfer[fi] whether called immediately or from a
472 * display list.
473 */
474 static void GLAPIENTRY
475 _mesa_PixelTransferf( GLenum pname, GLfloat param )
476 {
477 GET_CURRENT_CONTEXT(ctx);
478 ASSERT_OUTSIDE_BEGIN_END(ctx);
479
480 switch (pname) {
481 case GL_MAP_COLOR:
482 if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE))
483 return;
484 FLUSH_VERTICES(ctx, _NEW_PIXEL);
485 ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
486 break;
487 case GL_MAP_STENCIL:
488 if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE))
489 return;
490 FLUSH_VERTICES(ctx, _NEW_PIXEL);
491 ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
492 break;
493 case GL_INDEX_SHIFT:
494 if (ctx->Pixel.IndexShift == (GLint) param)
495 return;
496 FLUSH_VERTICES(ctx, _NEW_PIXEL);
497 ctx->Pixel.IndexShift = (GLint) param;
498 break;
499 case GL_INDEX_OFFSET:
500 if (ctx->Pixel.IndexOffset == (GLint) param)
501 return;
502 FLUSH_VERTICES(ctx, _NEW_PIXEL);
503 ctx->Pixel.IndexOffset = (GLint) param;
504 break;
505 case GL_RED_SCALE:
506 if (ctx->Pixel.RedScale == param)
507 return;
508 FLUSH_VERTICES(ctx, _NEW_PIXEL);
509 ctx->Pixel.RedScale = param;
510 break;
511 case GL_RED_BIAS:
512 if (ctx->Pixel.RedBias == param)
513 return;
514 FLUSH_VERTICES(ctx, _NEW_PIXEL);
515 ctx->Pixel.RedBias = param;
516 break;
517 case GL_GREEN_SCALE:
518 if (ctx->Pixel.GreenScale == param)
519 return;
520 FLUSH_VERTICES(ctx, _NEW_PIXEL);
521 ctx->Pixel.GreenScale = param;
522 break;
523 case GL_GREEN_BIAS:
524 if (ctx->Pixel.GreenBias == param)
525 return;
526 FLUSH_VERTICES(ctx, _NEW_PIXEL);
527 ctx->Pixel.GreenBias = param;
528 break;
529 case GL_BLUE_SCALE:
530 if (ctx->Pixel.BlueScale == param)
531 return;
532 FLUSH_VERTICES(ctx, _NEW_PIXEL);
533 ctx->Pixel.BlueScale = param;
534 break;
535 case GL_BLUE_BIAS:
536 if (ctx->Pixel.BlueBias == param)
537 return;
538 FLUSH_VERTICES(ctx, _NEW_PIXEL);
539 ctx->Pixel.BlueBias = param;
540 break;
541 case GL_ALPHA_SCALE:
542 if (ctx->Pixel.AlphaScale == param)
543 return;
544 FLUSH_VERTICES(ctx, _NEW_PIXEL);
545 ctx->Pixel.AlphaScale = param;
546 break;
547 case GL_ALPHA_BIAS:
548 if (ctx->Pixel.AlphaBias == param)
549 return;
550 FLUSH_VERTICES(ctx, _NEW_PIXEL);
551 ctx->Pixel.AlphaBias = param;
552 break;
553 case GL_DEPTH_SCALE:
554 if (ctx->Pixel.DepthScale == param)
555 return;
556 FLUSH_VERTICES(ctx, _NEW_PIXEL);
557 ctx->Pixel.DepthScale = param;
558 break;
559 case GL_DEPTH_BIAS:
560 if (ctx->Pixel.DepthBias == param)
561 return;
562 FLUSH_VERTICES(ctx, _NEW_PIXEL);
563 ctx->Pixel.DepthBias = param;
564 break;
565 case GL_POST_COLOR_MATRIX_RED_SCALE:
566 if (ctx->Pixel.PostColorMatrixScale[0] == param)
567 return;
568 FLUSH_VERTICES(ctx, _NEW_PIXEL);
569 ctx->Pixel.PostColorMatrixScale[0] = param;
570 break;
571 case GL_POST_COLOR_MATRIX_RED_BIAS:
572 if (ctx->Pixel.PostColorMatrixBias[0] == param)
573 return;
574 FLUSH_VERTICES(ctx, _NEW_PIXEL);
575 ctx->Pixel.PostColorMatrixBias[0] = param;
576 break;
577 case GL_POST_COLOR_MATRIX_GREEN_SCALE:
578 if (ctx->Pixel.PostColorMatrixScale[1] == param)
579 return;
580 FLUSH_VERTICES(ctx, _NEW_PIXEL);
581 ctx->Pixel.PostColorMatrixScale[1] = param;
582 break;
583 case GL_POST_COLOR_MATRIX_GREEN_BIAS:
584 if (ctx->Pixel.PostColorMatrixBias[1] == param)
585 return;
586 FLUSH_VERTICES(ctx, _NEW_PIXEL);
587 ctx->Pixel.PostColorMatrixBias[1] = param;
588 break;
589 case GL_POST_COLOR_MATRIX_BLUE_SCALE:
590 if (ctx->Pixel.PostColorMatrixScale[2] == param)
591 return;
592 FLUSH_VERTICES(ctx, _NEW_PIXEL);
593 ctx->Pixel.PostColorMatrixScale[2] = param;
594 break;
595 case GL_POST_COLOR_MATRIX_BLUE_BIAS:
596 if (ctx->Pixel.PostColorMatrixBias[2] == param)
597 return;
598 FLUSH_VERTICES(ctx, _NEW_PIXEL);
599 ctx->Pixel.PostColorMatrixBias[2] = param;
600 break;
601 case GL_POST_COLOR_MATRIX_ALPHA_SCALE:
602 if (ctx->Pixel.PostColorMatrixScale[3] == param)
603 return;
604 FLUSH_VERTICES(ctx, _NEW_PIXEL);
605 ctx->Pixel.PostColorMatrixScale[3] = param;
606 break;
607 case GL_POST_COLOR_MATRIX_ALPHA_BIAS:
608 if (ctx->Pixel.PostColorMatrixBias[3] == param)
609 return;
610 FLUSH_VERTICES(ctx, _NEW_PIXEL);
611 ctx->Pixel.PostColorMatrixBias[3] = param;
612 break;
613 case GL_POST_CONVOLUTION_RED_SCALE:
614 if (ctx->Pixel.PostConvolutionScale[0] == param)
615 return;
616 FLUSH_VERTICES(ctx, _NEW_PIXEL);
617 ctx->Pixel.PostConvolutionScale[0] = param;
618 break;
619 case GL_POST_CONVOLUTION_RED_BIAS:
620 if (ctx->Pixel.PostConvolutionBias[0] == param)
621 return;
622 FLUSH_VERTICES(ctx, _NEW_PIXEL);
623 ctx->Pixel.PostConvolutionBias[0] = param;
624 break;
625 case GL_POST_CONVOLUTION_GREEN_SCALE:
626 if (ctx->Pixel.PostConvolutionScale[1] == param)
627 return;
628 FLUSH_VERTICES(ctx, _NEW_PIXEL);
629 ctx->Pixel.PostConvolutionScale[1] = param;
630 break;
631 case GL_POST_CONVOLUTION_GREEN_BIAS:
632 if (ctx->Pixel.PostConvolutionBias[1] == param)
633 return;
634 FLUSH_VERTICES(ctx, _NEW_PIXEL);
635 ctx->Pixel.PostConvolutionBias[1] = param;
636 break;
637 case GL_POST_CONVOLUTION_BLUE_SCALE:
638 if (ctx->Pixel.PostConvolutionScale[2] == param)
639 return;
640 FLUSH_VERTICES(ctx, _NEW_PIXEL);
641 ctx->Pixel.PostConvolutionScale[2] = param;
642 break;
643 case GL_POST_CONVOLUTION_BLUE_BIAS:
644 if (ctx->Pixel.PostConvolutionBias[2] == param)
645 return;
646 FLUSH_VERTICES(ctx, _NEW_PIXEL);
647 ctx->Pixel.PostConvolutionBias[2] = param;
648 break;
649 case GL_POST_CONVOLUTION_ALPHA_SCALE:
650 if (ctx->Pixel.PostConvolutionScale[3] == param)
651 return;
652 FLUSH_VERTICES(ctx, _NEW_PIXEL);
653 ctx->Pixel.PostConvolutionScale[3] = param;
654 break;
655 case GL_POST_CONVOLUTION_ALPHA_BIAS:
656 if (ctx->Pixel.PostConvolutionBias[3] == param)
657 return;
658 FLUSH_VERTICES(ctx, _NEW_PIXEL);
659 ctx->Pixel.PostConvolutionBias[3] = param;
660 break;
661 default:
662 _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
663 return;
664 }
665 }
666
667
668 static void GLAPIENTRY
669 _mesa_PixelTransferi( GLenum pname, GLint param )
670 {
671 _mesa_PixelTransferf( pname, (GLfloat) param );
672 }
673
674
675
676 /**********************************************************************/
677 /***** State Management *****/
678 /**********************************************************************/
679
680 /*
681 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
682 * pixel transfer operations are enabled.
683 */
684 static void
685 update_image_transfer_state(GLcontext *ctx)
686 {
687 GLuint mask = 0;
688
689 if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F ||
690 ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F ||
691 ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F ||
692 ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F)
693 mask |= IMAGE_SCALE_BIAS_BIT;
694
695 if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset)
696 mask |= IMAGE_SHIFT_OFFSET_BIT;
697
698 if (ctx->Pixel.MapColorFlag)
699 mask |= IMAGE_MAP_COLOR_BIT;
700
701 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION])
702 mask |= IMAGE_COLOR_TABLE_BIT;
703
704 if (ctx->Pixel.Convolution1DEnabled ||
705 ctx->Pixel.Convolution2DEnabled ||
706 ctx->Pixel.Separable2DEnabled) {
707 mask |= IMAGE_CONVOLUTION_BIT;
708 if (ctx->Pixel.PostConvolutionScale[0] != 1.0F ||
709 ctx->Pixel.PostConvolutionScale[1] != 1.0F ||
710 ctx->Pixel.PostConvolutionScale[2] != 1.0F ||
711 ctx->Pixel.PostConvolutionScale[3] != 1.0F ||
712 ctx->Pixel.PostConvolutionBias[0] != 0.0F ||
713 ctx->Pixel.PostConvolutionBias[1] != 0.0F ||
714 ctx->Pixel.PostConvolutionBias[2] != 0.0F ||
715 ctx->Pixel.PostConvolutionBias[3] != 0.0F) {
716 mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS;
717 }
718 }
719
720 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION])
721 mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT;
722
723 if (ctx->ColorMatrixStack.Top->type != MATRIX_IDENTITY ||
724 ctx->Pixel.PostColorMatrixScale[0] != 1.0F ||
725 ctx->Pixel.PostColorMatrixBias[0] != 0.0F ||
726 ctx->Pixel.PostColorMatrixScale[1] != 1.0F ||
727 ctx->Pixel.PostColorMatrixBias[1] != 0.0F ||
728 ctx->Pixel.PostColorMatrixScale[2] != 1.0F ||
729 ctx->Pixel.PostColorMatrixBias[2] != 0.0F ||
730 ctx->Pixel.PostColorMatrixScale[3] != 1.0F ||
731 ctx->Pixel.PostColorMatrixBias[3] != 0.0F)
732 mask |= IMAGE_COLOR_MATRIX_BIT;
733
734 if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX])
735 mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT;
736
737 if (ctx->Pixel.HistogramEnabled)
738 mask |= IMAGE_HISTOGRAM_BIT;
739
740 if (ctx->Pixel.MinMaxEnabled)
741 mask |= IMAGE_MIN_MAX_BIT;
742
743 ctx->_ImageTransferState = mask;
744 }
745
746
747 /**
748 * Update mesa pixel transfer derived state.
749 */
750 void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
751 {
752 if (new_state & _NEW_COLOR_MATRIX)
753 _math_matrix_analyse( ctx->ColorMatrixStack.Top );
754
755 /* References ColorMatrix.type (derived above).
756 */
757 if (new_state & _MESA_NEW_TRANSFER_STATE)
758 update_image_transfer_state(ctx);
759 }
760
761
762 void
763 _mesa_init_pixel_dispatch(struct _glapi_table *disp)
764 {
765 SET_GetPixelMapfv(disp, _mesa_GetPixelMapfv);
766 SET_GetPixelMapuiv(disp, _mesa_GetPixelMapuiv);
767 SET_GetPixelMapusv(disp, _mesa_GetPixelMapusv);
768 SET_PixelMapfv(disp, _mesa_PixelMapfv);
769 SET_PixelMapuiv(disp, _mesa_PixelMapuiv);
770 SET_PixelMapusv(disp, _mesa_PixelMapusv);
771 SET_PixelTransferf(disp, _mesa_PixelTransferf);
772 SET_PixelTransferi(disp, _mesa_PixelTransferi);
773 SET_PixelZoom(disp, _mesa_PixelZoom);
774 }
775
776
777 #endif /* FEATURE_pixel_transfer */
778
779
780 /**********************************************************************/
781 /***** Initialization *****/
782 /**********************************************************************/
783
784 static void
785 init_pixelmap(struct gl_pixelmap *map)
786 {
787 map->Size = 1;
788 map->Map[0] = 0.0;
789 map->Map8[0] = 0;
790 }
791
792
793 /**
794 * Initialize the context's PIXEL attribute group.
795 */
796 void
797 _mesa_init_pixel( GLcontext *ctx )
798 {
799 int i;
800
801 /* Pixel group */
802 ctx->Pixel.RedBias = 0.0;
803 ctx->Pixel.RedScale = 1.0;
804 ctx->Pixel.GreenBias = 0.0;
805 ctx->Pixel.GreenScale = 1.0;
806 ctx->Pixel.BlueBias = 0.0;
807 ctx->Pixel.BlueScale = 1.0;
808 ctx->Pixel.AlphaBias = 0.0;
809 ctx->Pixel.AlphaScale = 1.0;
810 ctx->Pixel.DepthBias = 0.0;
811 ctx->Pixel.DepthScale = 1.0;
812 ctx->Pixel.IndexOffset = 0;
813 ctx->Pixel.IndexShift = 0;
814 ctx->Pixel.ZoomX = 1.0;
815 ctx->Pixel.ZoomY = 1.0;
816 ctx->Pixel.MapColorFlag = GL_FALSE;
817 ctx->Pixel.MapStencilFlag = GL_FALSE;
818 init_pixelmap(&ctx->PixelMaps.StoS);
819 init_pixelmap(&ctx->PixelMaps.ItoI);
820 init_pixelmap(&ctx->PixelMaps.ItoR);
821 init_pixelmap(&ctx->PixelMaps.ItoG);
822 init_pixelmap(&ctx->PixelMaps.ItoB);
823 init_pixelmap(&ctx->PixelMaps.ItoA);
824 init_pixelmap(&ctx->PixelMaps.RtoR);
825 init_pixelmap(&ctx->PixelMaps.GtoG);
826 init_pixelmap(&ctx->PixelMaps.BtoB);
827 init_pixelmap(&ctx->PixelMaps.AtoA);
828 ctx->Pixel.HistogramEnabled = GL_FALSE;
829 ctx->Pixel.MinMaxEnabled = GL_FALSE;
830 ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0);
831 ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0);
832 for (i = 0; i < COLORTABLE_MAX; i++) {
833 ASSIGN_4V(ctx->Pixel.ColorTableScale[i], 1.0, 1.0, 1.0, 1.0);
834 ASSIGN_4V(ctx->Pixel.ColorTableBias[i], 0.0, 0.0, 0.0, 0.0);
835 ctx->Pixel.ColorTableEnabled[i] = GL_FALSE;
836 }
837 ctx->Pixel.Convolution1DEnabled = GL_FALSE;
838 ctx->Pixel.Convolution2DEnabled = GL_FALSE;
839 ctx->Pixel.Separable2DEnabled = GL_FALSE;
840 for (i = 0; i < 3; i++) {
841 ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0);
842 ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE;
843 ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0);
844 ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0);
845 }
846 for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) {
847 ctx->Convolution1D.Filter[i] = 0.0;
848 ctx->Convolution2D.Filter[i] = 0.0;
849 ctx->Separable2D.Filter[i] = 0.0;
850 }
851 ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0);
852 ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0);
853 /* GL_SGI_texture_color_table */
854 ASSIGN_4V(ctx->Pixel.TextureColorTableScale, 1.0, 1.0, 1.0, 1.0);
855 ASSIGN_4V(ctx->Pixel.TextureColorTableBias, 0.0, 0.0, 0.0, 0.0);
856
857 if (ctx->Visual.doubleBufferMode) {
858 ctx->Pixel.ReadBuffer = GL_BACK;
859 }
860 else {
861 ctx->Pixel.ReadBuffer = GL_FRONT;
862 }
863
864 /* Miscellaneous */
865 ctx->_ImageTransferState = 0;
866 }