2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
27 #include "bufferobj.h"
31 #include "histogram.h"
32 #include "glapi/dispatch.h"
39 * XXX the packed pixel formats haven't been tested.
42 pack_histogram( GLcontext
*ctx
,
43 GLuint n
, CONST GLuint rgba
[][4],
44 GLenum format
, GLenum type
, GLvoid
*destination
,
45 const struct gl_pixelstore_attrib
*packing
)
47 const GLint comps
= _mesa_components_in_format(format
);
48 GLuint luminance
[MAX_WIDTH
];
50 if (format
== GL_LUMINANCE
|| format
== GL_LUMINANCE_ALPHA
) {
52 for (i
= 0; i
< n
; i
++) {
53 luminance
[i
] = rgba
[i
][RCOMP
] + rgba
[i
][GCOMP
] + rgba
[i
][BCOMP
];
57 #define PACK_MACRO(TYPE) \
63 dst[i] = (TYPE) rgba[i][RCOMP]; \
67 dst[i] = (TYPE) rgba[i][GCOMP]; \
71 dst[i] = (TYPE) rgba[i][BCOMP]; \
75 dst[i] = (TYPE) rgba[i][ACOMP]; \
79 dst[i] = (TYPE) luminance[i]; \
81 case GL_LUMINANCE_ALPHA: \
83 dst[i*2+0] = (TYPE) luminance[i]; \
84 dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \
89 dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \
90 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
91 dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \
96 dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \
97 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
98 dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \
99 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
103 for (i=0;i<n;i++) { \
104 dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \
105 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
106 dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \
110 for (i=0;i<n;i++) { \
111 dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \
112 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
113 dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \
114 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
118 for (i=0;i<n;i++) { \
119 dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \
120 dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \
121 dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \
122 dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \
126 _mesa_problem(ctx, "bad format in pack_histogram"); \
131 case GL_UNSIGNED_BYTE
:
133 GLubyte
*dst
= (GLubyte
*) destination
;
139 GLbyte
*dst
= (GLbyte
*) destination
;
143 case GL_UNSIGNED_SHORT
:
145 GLushort
*dst
= (GLushort
*) destination
;
146 PACK_MACRO(GLushort
);
147 if (packing
->SwapBytes
) {
148 _mesa_swap2(dst
, n
* comps
);
154 GLshort
*dst
= (GLshort
*) destination
;
156 if (packing
->SwapBytes
) {
157 _mesa_swap2((GLushort
*) dst
, n
* comps
);
161 case GL_UNSIGNED_INT
:
163 GLuint
*dst
= (GLuint
*) destination
;
165 if (packing
->SwapBytes
) {
166 _mesa_swap4(dst
, n
* comps
);
172 GLint
*dst
= (GLint
*) destination
;
174 if (packing
->SwapBytes
) {
175 _mesa_swap4((GLuint
*) dst
, n
* comps
);
181 GLfloat
*dst
= (GLfloat
*) destination
;
183 if (packing
->SwapBytes
) {
184 _mesa_swap4((GLuint
*) dst
, n
* comps
);
188 case GL_HALF_FLOAT_ARB
:
190 /* temporarily store as GLuints */
191 GLuint temp
[4*HISTOGRAM_TABLE_SIZE
];
193 GLhalfARB
*half
= (GLhalfARB
*) destination
;
195 /* get GLuint values */
197 /* convert to GLhalf */
198 for (i
= 0; i
< n
* comps
; i
++) {
199 half
[i
] = _mesa_float_to_half((GLfloat
) temp
[i
]);
201 if (packing
->SwapBytes
) {
202 _mesa_swap2((GLushort
*) half
, n
* comps
);
206 case GL_UNSIGNED_BYTE_3_3_2
:
207 if (format
== GL_RGB
) {
208 GLubyte
*dst
= (GLubyte
*) destination
;
210 for (i
= 0; i
< n
; i
++) {
211 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x7) << 5)
212 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
213 | ((rgba
[i
][BCOMP
] & 0x3) );
217 GLubyte
*dst
= (GLubyte
*) destination
;
219 ASSERT(format
== GL_BGR
);
220 for (i
= 0; i
< n
; i
++) {
221 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x7) << 5)
222 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
223 | ((rgba
[i
][RCOMP
] & 0x3) );
227 case GL_UNSIGNED_BYTE_2_3_3_REV
:
228 if (format
== GL_RGB
) {
229 GLubyte
*dst
= (GLubyte
*) destination
;
231 for (i
= 0; i
< n
; i
++) {
232 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3) << 6)
233 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
234 | ((rgba
[i
][BCOMP
] & 0x7) );
238 GLubyte
*dst
= (GLubyte
*) destination
;
240 ASSERT(format
== GL_BGR
);
241 for (i
= 0; i
< n
; i
++) {
242 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3) << 6)
243 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
244 | ((rgba
[i
][RCOMP
] & 0x7) );
248 case GL_UNSIGNED_SHORT_5_6_5
:
249 if (format
== GL_RGB
) {
250 GLushort
*dst
= (GLushort
*) destination
;
252 for (i
= 0; i
< n
; i
++) {
253 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
254 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
255 | ((rgba
[i
][BCOMP
] & 0x1f) );
259 GLushort
*dst
= (GLushort
*) destination
;
261 ASSERT(format
== GL_BGR
);
262 for (i
= 0; i
< n
; i
++) {
263 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
264 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
265 | ((rgba
[i
][RCOMP
] & 0x1f) );
269 case GL_UNSIGNED_SHORT_5_6_5_REV
:
270 if (format
== GL_RGB
) {
271 GLushort
*dst
= (GLushort
*) destination
;
273 for (i
= 0; i
< n
; i
++) {
274 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
275 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
276 | ((rgba
[i
][RCOMP
] & 0x1f) );
280 GLushort
*dst
= (GLushort
*) destination
;
282 ASSERT(format
== GL_BGR
);
283 for (i
= 0; i
< n
; i
++) {
284 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
285 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
286 | ((rgba
[i
][BCOMP
] & 0x1f) );
290 case GL_UNSIGNED_SHORT_4_4_4_4
:
291 if (format
== GL_RGBA
) {
292 GLushort
*dst
= (GLushort
*) destination
;
294 for (i
= 0; i
< n
; i
++) {
295 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
296 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
297 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
298 | ((rgba
[i
][ACOMP
] & 0xf) );
301 else if (format
== GL_BGRA
) {
302 GLushort
*dst
= (GLushort
*) destination
;
304 for (i
= 0; i
< n
; i
++) {
305 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xf) << 12)
306 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
307 | ((rgba
[i
][RCOMP
] & 0xf) << 4)
308 | ((rgba
[i
][ACOMP
] & 0xf) );
312 GLushort
*dst
= (GLushort
*) destination
;
314 ASSERT(format
== GL_ABGR_EXT
);
315 for (i
= 0; i
< n
; i
++) {
316 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
317 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
318 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
319 | ((rgba
[i
][RCOMP
] & 0xf) );
323 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
324 if (format
== GL_RGBA
) {
325 GLushort
*dst
= (GLushort
*) destination
;
327 for (i
= 0; i
< n
; i
++) {
328 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
329 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
330 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
331 | ((rgba
[i
][RCOMP
] & 0xf) );
334 else if (format
== GL_BGRA
) {
335 GLushort
*dst
= (GLushort
*) destination
;
337 for (i
= 0; i
< n
; i
++) {
338 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
339 | ((rgba
[i
][RCOMP
] & 0xf) << 8)
340 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
341 | ((rgba
[i
][BCOMP
] & 0xf) );
345 GLushort
*dst
= (GLushort
*) destination
;
347 ASSERT(format
== GL_ABGR_EXT
);
348 for (i
= 0; i
< n
; i
++) {
349 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
350 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
351 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
352 | ((rgba
[i
][ACOMP
] & 0xf) );
356 case GL_UNSIGNED_SHORT_5_5_5_1
:
357 if (format
== GL_RGBA
) {
358 GLushort
*dst
= (GLushort
*) destination
;
360 for (i
= 0; i
< n
; i
++) {
361 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
362 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
363 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
364 | ((rgba
[i
][ACOMP
] & 0x1) );
367 else if (format
== GL_BGRA
) {
368 GLushort
*dst
= (GLushort
*) destination
;
370 for (i
= 0; i
< n
; i
++) {
371 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
372 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
373 | ((rgba
[i
][RCOMP
] & 0x1f) << 1)
374 | ((rgba
[i
][ACOMP
] & 0x1) );
378 GLushort
*dst
= (GLushort
*) destination
;
380 ASSERT(format
== GL_ABGR_EXT
);
381 for (i
= 0; i
< n
; i
++) {
382 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
383 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
384 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
385 | ((rgba
[i
][RCOMP
] & 0x1) );
389 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
390 if (format
== GL_RGBA
) {
391 GLushort
*dst
= (GLushort
*) destination
;
393 for (i
= 0; i
< n
; i
++) {
394 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
395 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
396 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
397 | ((rgba
[i
][RCOMP
] & 0x1) );
400 else if (format
== GL_BGRA
) {
401 GLushort
*dst
= (GLushort
*) destination
;
403 for (i
= 0; i
< n
; i
++) {
404 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
405 | ((rgba
[i
][RCOMP
] & 0x1f) << 6)
406 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
407 | ((rgba
[i
][BCOMP
] & 0x1) );
411 GLushort
*dst
= (GLushort
*) destination
;
413 ASSERT(format
== GL_ABGR_EXT
);
414 for (i
= 0; i
< n
; i
++) {
415 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
416 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
417 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
418 | ((rgba
[i
][ACOMP
] & 0x1) );
422 case GL_UNSIGNED_INT_8_8_8_8
:
423 if (format
== GL_RGBA
) {
424 GLuint
*dst
= (GLuint
*) destination
;
426 for (i
= 0; i
< n
; i
++) {
427 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
428 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
429 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
430 | ((rgba
[i
][ACOMP
] & 0xff) );
433 else if (format
== GL_BGRA
) {
434 GLuint
*dst
= (GLuint
*) destination
;
436 for (i
= 0; i
< n
; i
++) {
437 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xff) << 24)
438 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
439 | ((rgba
[i
][RCOMP
] & 0xff) << 8)
440 | ((rgba
[i
][ACOMP
] & 0xff) );
444 GLuint
*dst
= (GLuint
*) destination
;
446 ASSERT(format
== GL_ABGR_EXT
);
447 for (i
= 0; i
< n
; i
++) {
448 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
449 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
450 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
451 | ((rgba
[i
][RCOMP
] & 0xff) );
455 case GL_UNSIGNED_INT_8_8_8_8_REV
:
456 if (format
== GL_RGBA
) {
457 GLuint
*dst
= (GLuint
*) destination
;
459 for (i
= 0; i
< n
; i
++) {
460 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
461 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
462 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
463 | ((rgba
[i
][RCOMP
] & 0xff) );
466 else if (format
== GL_BGRA
) {
467 GLuint
*dst
= (GLuint
*) destination
;
469 for (i
= 0; i
< n
; i
++) {
470 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
471 | ((rgba
[i
][RCOMP
] & 0xff) << 16)
472 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
473 | ((rgba
[i
][BCOMP
] & 0xff) );
477 GLuint
*dst
= (GLuint
*) destination
;
479 ASSERT(format
== GL_ABGR_EXT
);
480 for (i
= 0; i
< n
; i
++) {
481 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
482 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
483 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
484 | ((rgba
[i
][ACOMP
] & 0xff) );
488 case GL_UNSIGNED_INT_10_10_10_2
:
489 if (format
== GL_RGBA
) {
490 GLuint
*dst
= (GLuint
*) destination
;
492 for (i
= 0; i
< n
; i
++) {
493 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
494 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
495 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
496 | ((rgba
[i
][ACOMP
] & 0x3) );
499 else if (format
== GL_BGRA
) {
500 GLuint
*dst
= (GLuint
*) destination
;
502 for (i
= 0; i
< n
; i
++) {
503 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3ff) << 22)
504 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
505 | ((rgba
[i
][RCOMP
] & 0x3ff) << 2)
506 | ((rgba
[i
][ACOMP
] & 0x3) );
510 GLuint
*dst
= (GLuint
*) destination
;
512 ASSERT(format
== GL_ABGR_EXT
);
513 for (i
= 0; i
< n
; i
++) {
514 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
515 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
516 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
517 | ((rgba
[i
][RCOMP
] & 0x3) );
521 case GL_UNSIGNED_INT_2_10_10_10_REV
:
522 if (format
== GL_RGBA
) {
523 GLuint
*dst
= (GLuint
*) destination
;
525 for (i
= 0; i
< n
; i
++) {
526 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
527 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
528 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
529 | ((rgba
[i
][RCOMP
] & 0x3) );
532 else if (format
== GL_BGRA
) {
533 GLuint
*dst
= (GLuint
*) destination
;
535 for (i
= 0; i
< n
; i
++) {
536 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
537 | ((rgba
[i
][RCOMP
] & 0x3ff) << 12)
538 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
539 | ((rgba
[i
][BCOMP
] & 0x3) );
543 GLuint
*dst
= (GLuint
*) destination
;
545 ASSERT(format
== GL_ABGR_EXT
);
546 for (i
= 0; i
< n
; i
++) {
547 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
548 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
549 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
550 | ((rgba
[i
][ACOMP
] & 0x3) );
555 _mesa_problem(ctx
, "Bad type in pack_histogram");
563 * Given an internalFormat token passed to glHistogram or glMinMax,
564 * return the corresponding base format.
565 * Return -1 if invalid token.
568 base_histogram_format( GLenum format
)
583 case GL_LUMINANCE_ALPHA
:
584 case GL_LUMINANCE4_ALPHA4
:
585 case GL_LUMINANCE6_ALPHA2
:
586 case GL_LUMINANCE8_ALPHA8
:
587 case GL_LUMINANCE12_ALPHA4
:
588 case GL_LUMINANCE12_ALPHA12
:
589 case GL_LUMINANCE16_ALPHA16
:
590 return GL_LUMINANCE_ALPHA
;
610 return -1; /* error */
616 /**********************************************************************
621 /* this is defined below */
622 static void GLAPIENTRY
_mesa_ResetMinmax(GLenum target
);
625 static void GLAPIENTRY
626 _mesa_GetMinmax(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
628 GET_CURRENT_CONTEXT(ctx
);
629 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
631 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
632 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax");
636 if (target
!= GL_MINMAX
) {
637 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmax(target)");
641 if (format
!= GL_RED
&&
642 format
!= GL_GREEN
&&
644 format
!= GL_ALPHA
&&
649 format
!= GL_ABGR_EXT
&&
650 format
!= GL_LUMINANCE
&&
651 format
!= GL_LUMINANCE_ALPHA
) {
652 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMax(format)");
655 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
656 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax(format or type)");
661 values
= _mesa_map_validate_pbo_dest(ctx
, 1, &ctx
->Pack
, 2, 1, 1,
662 format
, type
, values
, "glGetMinmax");
667 GLfloat minmax
[2][4];
668 minmax
[0][RCOMP
] = CLAMP(ctx
->MinMax
.Min
[RCOMP
], 0.0F
, 1.0F
);
669 minmax
[0][GCOMP
] = CLAMP(ctx
->MinMax
.Min
[GCOMP
], 0.0F
, 1.0F
);
670 minmax
[0][BCOMP
] = CLAMP(ctx
->MinMax
.Min
[BCOMP
], 0.0F
, 1.0F
);
671 minmax
[0][ACOMP
] = CLAMP(ctx
->MinMax
.Min
[ACOMP
], 0.0F
, 1.0F
);
672 minmax
[1][RCOMP
] = CLAMP(ctx
->MinMax
.Max
[RCOMP
], 0.0F
, 1.0F
);
673 minmax
[1][GCOMP
] = CLAMP(ctx
->MinMax
.Max
[GCOMP
], 0.0F
, 1.0F
);
674 minmax
[1][BCOMP
] = CLAMP(ctx
->MinMax
.Max
[BCOMP
], 0.0F
, 1.0F
);
675 minmax
[1][ACOMP
] = CLAMP(ctx
->MinMax
.Max
[ACOMP
], 0.0F
, 1.0F
);
676 _mesa_pack_rgba_span_float(ctx
, 2, minmax
,
677 format
, type
, values
, &ctx
->Pack
, 0x0);
680 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
683 _mesa_ResetMinmax(GL_MINMAX
);
688 static void GLAPIENTRY
689 _mesa_GetHistogram(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
691 GET_CURRENT_CONTEXT(ctx
);
692 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
694 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
695 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram");
699 if (target
!= GL_HISTOGRAM
) {
700 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(target)");
704 if (format
!= GL_RED
&&
705 format
!= GL_GREEN
&&
707 format
!= GL_ALPHA
&&
712 format
!= GL_ABGR_EXT
&&
713 format
!= GL_LUMINANCE
&&
714 format
!= GL_LUMINANCE_ALPHA
) {
715 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(format)");
718 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
719 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram(format or type)");
723 values
= _mesa_map_validate_pbo_dest(ctx
, 1, &ctx
->Pack
,
724 ctx
->Histogram
.Width
, 1, 1,
725 format
, type
, values
,
730 pack_histogram(ctx
, ctx
->Histogram
.Width
,
731 (CONST
GLuint (*)[4]) ctx
->Histogram
.Count
,
732 format
, type
, values
, &ctx
->Pack
);
734 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
738 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
739 ctx
->Histogram
.Count
[i
][0] = 0;
740 ctx
->Histogram
.Count
[i
][1] = 0;
741 ctx
->Histogram
.Count
[i
][2] = 0;
742 ctx
->Histogram
.Count
[i
][3] = 0;
748 static void GLAPIENTRY
749 _mesa_GetHistogramParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
751 GET_CURRENT_CONTEXT(ctx
);
752 ASSERT_OUTSIDE_BEGIN_END(ctx
);
754 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
755 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameterfv");
759 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
760 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(target)");
765 case GL_HISTOGRAM_WIDTH
:
766 *params
= (GLfloat
) ctx
->Histogram
.Width
;
768 case GL_HISTOGRAM_FORMAT
:
769 *params
= (GLfloat
) ctx
->Histogram
.Format
;
771 case GL_HISTOGRAM_RED_SIZE
:
772 *params
= (GLfloat
) ctx
->Histogram
.RedSize
;
774 case GL_HISTOGRAM_GREEN_SIZE
:
775 *params
= (GLfloat
) ctx
->Histogram
.GreenSize
;
777 case GL_HISTOGRAM_BLUE_SIZE
:
778 *params
= (GLfloat
) ctx
->Histogram
.BlueSize
;
780 case GL_HISTOGRAM_ALPHA_SIZE
:
781 *params
= (GLfloat
) ctx
->Histogram
.AlphaSize
;
783 case GL_HISTOGRAM_LUMINANCE_SIZE
:
784 *params
= (GLfloat
) ctx
->Histogram
.LuminanceSize
;
786 case GL_HISTOGRAM_SINK
:
787 *params
= (GLfloat
) ctx
->Histogram
.Sink
;
790 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(pname)");
795 static void GLAPIENTRY
796 _mesa_GetHistogramParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
798 GET_CURRENT_CONTEXT(ctx
);
799 ASSERT_OUTSIDE_BEGIN_END(ctx
);
801 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
802 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameteriv");
806 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
807 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(target)");
812 case GL_HISTOGRAM_WIDTH
:
813 *params
= (GLint
) ctx
->Histogram
.Width
;
815 case GL_HISTOGRAM_FORMAT
:
816 *params
= (GLint
) ctx
->Histogram
.Format
;
818 case GL_HISTOGRAM_RED_SIZE
:
819 *params
= (GLint
) ctx
->Histogram
.RedSize
;
821 case GL_HISTOGRAM_GREEN_SIZE
:
822 *params
= (GLint
) ctx
->Histogram
.GreenSize
;
824 case GL_HISTOGRAM_BLUE_SIZE
:
825 *params
= (GLint
) ctx
->Histogram
.BlueSize
;
827 case GL_HISTOGRAM_ALPHA_SIZE
:
828 *params
= (GLint
) ctx
->Histogram
.AlphaSize
;
830 case GL_HISTOGRAM_LUMINANCE_SIZE
:
831 *params
= (GLint
) ctx
->Histogram
.LuminanceSize
;
833 case GL_HISTOGRAM_SINK
:
834 *params
= (GLint
) ctx
->Histogram
.Sink
;
837 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(pname)");
842 static void GLAPIENTRY
843 _mesa_GetMinmaxParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
845 GET_CURRENT_CONTEXT(ctx
);
846 ASSERT_OUTSIDE_BEGIN_END(ctx
);
848 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
849 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameterfv");
852 if (target
!= GL_MINMAX
) {
853 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameterfv(target)");
856 if (pname
== GL_MINMAX_FORMAT
) {
857 *params
= (GLfloat
) ctx
->MinMax
.Format
;
859 else if (pname
== GL_MINMAX_SINK
) {
860 *params
= (GLfloat
) ctx
->MinMax
.Sink
;
863 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameterfv(pname)");
868 static void GLAPIENTRY
869 _mesa_GetMinmaxParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
871 GET_CURRENT_CONTEXT(ctx
);
872 ASSERT_OUTSIDE_BEGIN_END(ctx
);
874 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
875 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameteriv");
878 if (target
!= GL_MINMAX
) {
879 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameteriv(target)");
882 if (pname
== GL_MINMAX_FORMAT
) {
883 *params
= (GLint
) ctx
->MinMax
.Format
;
885 else if (pname
== GL_MINMAX_SINK
) {
886 *params
= (GLint
) ctx
->MinMax
.Sink
;
889 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameteriv(pname)");
894 static void GLAPIENTRY
895 _mesa_Histogram(GLenum target
, GLsizei width
, GLenum internalFormat
, GLboolean sink
)
898 GLboolean error
= GL_FALSE
;
899 GET_CURRENT_CONTEXT(ctx
);
900 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
902 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
903 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glHistogram");
907 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
908 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(target)");
912 if (width
< 0 || width
> HISTOGRAM_TABLE_SIZE
) {
913 if (target
== GL_PROXY_HISTOGRAM
) {
918 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
920 _mesa_error(ctx
, GL_TABLE_TOO_LARGE
, "glHistogram(width)");
925 if (width
!= 0 && !_mesa_is_pow_two(width
)) {
926 if (target
== GL_PROXY_HISTOGRAM
) {
930 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
935 if (base_histogram_format(internalFormat
) < 0) {
936 if (target
== GL_PROXY_HISTOGRAM
) {
940 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(internalFormat)");
945 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
947 /* reset histograms */
948 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
949 ctx
->Histogram
.Count
[i
][0] = 0;
950 ctx
->Histogram
.Count
[i
][1] = 0;
951 ctx
->Histogram
.Count
[i
][2] = 0;
952 ctx
->Histogram
.Count
[i
][3] = 0;
956 ctx
->Histogram
.Width
= 0;
957 ctx
->Histogram
.Format
= 0;
958 ctx
->Histogram
.RedSize
= 0;
959 ctx
->Histogram
.GreenSize
= 0;
960 ctx
->Histogram
.BlueSize
= 0;
961 ctx
->Histogram
.AlphaSize
= 0;
962 ctx
->Histogram
.LuminanceSize
= 0;
965 ctx
->Histogram
.Width
= width
;
966 ctx
->Histogram
.Format
= internalFormat
;
967 ctx
->Histogram
.Sink
= sink
;
968 ctx
->Histogram
.RedSize
= 8 * sizeof(GLuint
);
969 ctx
->Histogram
.GreenSize
= 8 * sizeof(GLuint
);
970 ctx
->Histogram
.BlueSize
= 8 * sizeof(GLuint
);
971 ctx
->Histogram
.AlphaSize
= 8 * sizeof(GLuint
);
972 ctx
->Histogram
.LuminanceSize
= 8 * sizeof(GLuint
);
977 static void GLAPIENTRY
978 _mesa_Minmax(GLenum target
, GLenum internalFormat
, GLboolean sink
)
980 GET_CURRENT_CONTEXT(ctx
);
981 ASSERT_OUTSIDE_BEGIN_END(ctx
);
983 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
984 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glMinmax");
988 if (target
!= GL_MINMAX
) {
989 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(target)");
993 if (base_histogram_format(internalFormat
) < 0) {
994 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(internalFormat)");
998 if (ctx
->MinMax
.Sink
== sink
)
1000 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
1001 ctx
->MinMax
.Sink
= sink
;
1005 static void GLAPIENTRY
1006 _mesa_ResetHistogram(GLenum target
)
1009 GET_CURRENT_CONTEXT(ctx
);
1010 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
1012 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1013 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetHistogram");
1017 if (target
!= GL_HISTOGRAM
) {
1018 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetHistogram(target)");
1022 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1023 ctx
->Histogram
.Count
[i
][0] = 0;
1024 ctx
->Histogram
.Count
[i
][1] = 0;
1025 ctx
->Histogram
.Count
[i
][2] = 0;
1026 ctx
->Histogram
.Count
[i
][3] = 0;
1031 static void GLAPIENTRY
1032 _mesa_ResetMinmax(GLenum target
)
1034 GET_CURRENT_CONTEXT(ctx
);
1035 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1037 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1038 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetMinmax");
1042 if (target
!= GL_MINMAX
) {
1043 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetMinMax(target)");
1047 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1048 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1049 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1050 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;
1055 _mesa_init_histogram_dispatch(struct _glapi_table
*disp
)
1057 SET_GetHistogram(disp
, _mesa_GetHistogram
);
1058 SET_GetHistogramParameterfv(disp
, _mesa_GetHistogramParameterfv
);
1059 SET_GetHistogramParameteriv(disp
, _mesa_GetHistogramParameteriv
);
1060 SET_GetMinmax(disp
, _mesa_GetMinmax
);
1061 SET_GetMinmaxParameterfv(disp
, _mesa_GetMinmaxParameterfv
);
1062 SET_GetMinmaxParameteriv(disp
, _mesa_GetMinmaxParameteriv
);
1063 SET_Histogram(disp
, _mesa_Histogram
);
1064 SET_Minmax(disp
, _mesa_Minmax
);
1065 SET_ResetHistogram(disp
, _mesa_ResetHistogram
);
1066 SET_ResetMinmax(disp
, _mesa_ResetMinmax
);
1070 #endif /* FEATURE_histogram */
1073 /**********************************************************************/
1074 /***** Initialization *****/
1075 /**********************************************************************/
1077 void _mesa_init_histogram( GLcontext
* ctx
)
1081 /* Histogram group */
1082 ctx
->Histogram
.Width
= 0;
1083 ctx
->Histogram
.Format
= GL_RGBA
;
1084 ctx
->Histogram
.Sink
= GL_FALSE
;
1085 ctx
->Histogram
.RedSize
= 0;
1086 ctx
->Histogram
.GreenSize
= 0;
1087 ctx
->Histogram
.BlueSize
= 0;
1088 ctx
->Histogram
.AlphaSize
= 0;
1089 ctx
->Histogram
.LuminanceSize
= 0;
1090 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1091 ctx
->Histogram
.Count
[i
][0] = 0;
1092 ctx
->Histogram
.Count
[i
][1] = 0;
1093 ctx
->Histogram
.Count
[i
][2] = 0;
1094 ctx
->Histogram
.Count
[i
][3] = 0;
1098 ctx
->MinMax
.Format
= GL_RGBA
;
1099 ctx
->MinMax
.Sink
= GL_FALSE
;
1100 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1101 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1102 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1103 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;