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"
33 #include "main/dispatch.h"
40 * XXX the packed pixel formats haven't been tested.
43 pack_histogram( GLcontext
*ctx
,
44 GLuint n
, CONST GLuint rgba
[][4],
45 GLenum format
, GLenum type
, GLvoid
*destination
,
46 const struct gl_pixelstore_attrib
*packing
)
48 const GLint comps
= _mesa_components_in_format(format
);
49 GLuint luminance
[MAX_WIDTH
];
51 if (format
== GL_LUMINANCE
|| format
== GL_LUMINANCE_ALPHA
) {
53 for (i
= 0; i
< n
; i
++) {
54 luminance
[i
] = rgba
[i
][RCOMP
] + rgba
[i
][GCOMP
] + rgba
[i
][BCOMP
];
58 #define PACK_MACRO(TYPE) \
64 dst[i] = (TYPE) rgba[i][RCOMP]; \
68 dst[i] = (TYPE) rgba[i][GCOMP]; \
72 dst[i] = (TYPE) rgba[i][BCOMP]; \
76 dst[i] = (TYPE) rgba[i][ACOMP]; \
80 dst[i] = (TYPE) luminance[i]; \
82 case GL_LUMINANCE_ALPHA: \
84 dst[i*2+0] = (TYPE) luminance[i]; \
85 dst[i*2+1] = (TYPE) rgba[i][ACOMP]; \
90 dst[i*3+0] = (TYPE) rgba[i][RCOMP]; \
91 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
92 dst[i*3+2] = (TYPE) rgba[i][BCOMP]; \
97 dst[i*4+0] = (TYPE) rgba[i][RCOMP]; \
98 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
99 dst[i*4+2] = (TYPE) rgba[i][BCOMP]; \
100 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
104 for (i=0;i<n;i++) { \
105 dst[i*3+0] = (TYPE) rgba[i][BCOMP]; \
106 dst[i*3+1] = (TYPE) rgba[i][GCOMP]; \
107 dst[i*3+2] = (TYPE) rgba[i][RCOMP]; \
111 for (i=0;i<n;i++) { \
112 dst[i*4+0] = (TYPE) rgba[i][BCOMP]; \
113 dst[i*4+1] = (TYPE) rgba[i][GCOMP]; \
114 dst[i*4+2] = (TYPE) rgba[i][RCOMP]; \
115 dst[i*4+3] = (TYPE) rgba[i][ACOMP]; \
119 for (i=0;i<n;i++) { \
120 dst[i*4+0] = (TYPE) rgba[i][ACOMP]; \
121 dst[i*4+1] = (TYPE) rgba[i][BCOMP]; \
122 dst[i*4+2] = (TYPE) rgba[i][GCOMP]; \
123 dst[i*4+3] = (TYPE) rgba[i][RCOMP]; \
127 _mesa_problem(ctx, "bad format in pack_histogram"); \
132 case GL_UNSIGNED_BYTE
:
134 GLubyte
*dst
= (GLubyte
*) destination
;
140 GLbyte
*dst
= (GLbyte
*) destination
;
144 case GL_UNSIGNED_SHORT
:
146 GLushort
*dst
= (GLushort
*) destination
;
147 PACK_MACRO(GLushort
);
148 if (packing
->SwapBytes
) {
149 _mesa_swap2(dst
, n
* comps
);
155 GLshort
*dst
= (GLshort
*) destination
;
157 if (packing
->SwapBytes
) {
158 _mesa_swap2((GLushort
*) dst
, n
* comps
);
162 case GL_UNSIGNED_INT
:
164 GLuint
*dst
= (GLuint
*) destination
;
166 if (packing
->SwapBytes
) {
167 _mesa_swap4(dst
, n
* comps
);
173 GLint
*dst
= (GLint
*) destination
;
175 if (packing
->SwapBytes
) {
176 _mesa_swap4((GLuint
*) dst
, n
* comps
);
182 GLfloat
*dst
= (GLfloat
*) destination
;
184 if (packing
->SwapBytes
) {
185 _mesa_swap4((GLuint
*) dst
, n
* comps
);
189 case GL_HALF_FLOAT_ARB
:
191 /* temporarily store as GLuints */
192 GLuint temp
[4*HISTOGRAM_TABLE_SIZE
];
194 GLhalfARB
*half
= (GLhalfARB
*) destination
;
196 /* get GLuint values */
198 /* convert to GLhalf */
199 for (i
= 0; i
< n
* comps
; i
++) {
200 half
[i
] = _mesa_float_to_half((GLfloat
) temp
[i
]);
202 if (packing
->SwapBytes
) {
203 _mesa_swap2((GLushort
*) half
, n
* comps
);
207 case GL_UNSIGNED_BYTE_3_3_2
:
208 if (format
== GL_RGB
) {
209 GLubyte
*dst
= (GLubyte
*) destination
;
211 for (i
= 0; i
< n
; i
++) {
212 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x7) << 5)
213 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
214 | ((rgba
[i
][BCOMP
] & 0x3) );
218 GLubyte
*dst
= (GLubyte
*) destination
;
220 ASSERT(format
== GL_BGR
);
221 for (i
= 0; i
< n
; i
++) {
222 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x7) << 5)
223 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
224 | ((rgba
[i
][RCOMP
] & 0x3) );
228 case GL_UNSIGNED_BYTE_2_3_3_REV
:
229 if (format
== GL_RGB
) {
230 GLubyte
*dst
= (GLubyte
*) destination
;
232 for (i
= 0; i
< n
; i
++) {
233 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3) << 6)
234 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
235 | ((rgba
[i
][BCOMP
] & 0x7) );
239 GLubyte
*dst
= (GLubyte
*) destination
;
241 ASSERT(format
== GL_BGR
);
242 for (i
= 0; i
< n
; i
++) {
243 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3) << 6)
244 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
245 | ((rgba
[i
][RCOMP
] & 0x7) );
249 case GL_UNSIGNED_SHORT_5_6_5
:
250 if (format
== GL_RGB
) {
251 GLushort
*dst
= (GLushort
*) destination
;
253 for (i
= 0; i
< n
; i
++) {
254 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
255 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
256 | ((rgba
[i
][BCOMP
] & 0x1f) );
260 GLushort
*dst
= (GLushort
*) destination
;
262 ASSERT(format
== GL_BGR
);
263 for (i
= 0; i
< n
; i
++) {
264 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
265 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
266 | ((rgba
[i
][RCOMP
] & 0x1f) );
270 case GL_UNSIGNED_SHORT_5_6_5_REV
:
271 if (format
== GL_RGB
) {
272 GLushort
*dst
= (GLushort
*) destination
;
274 for (i
= 0; i
< n
; i
++) {
275 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
276 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
277 | ((rgba
[i
][RCOMP
] & 0x1f) );
281 GLushort
*dst
= (GLushort
*) destination
;
283 ASSERT(format
== GL_BGR
);
284 for (i
= 0; i
< n
; i
++) {
285 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
286 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
287 | ((rgba
[i
][BCOMP
] & 0x1f) );
291 case GL_UNSIGNED_SHORT_4_4_4_4
:
292 if (format
== GL_RGBA
) {
293 GLushort
*dst
= (GLushort
*) destination
;
295 for (i
= 0; i
< n
; i
++) {
296 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
297 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
298 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
299 | ((rgba
[i
][ACOMP
] & 0xf) );
302 else if (format
== GL_BGRA
) {
303 GLushort
*dst
= (GLushort
*) destination
;
305 for (i
= 0; i
< n
; i
++) {
306 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xf) << 12)
307 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
308 | ((rgba
[i
][RCOMP
] & 0xf) << 4)
309 | ((rgba
[i
][ACOMP
] & 0xf) );
313 GLushort
*dst
= (GLushort
*) destination
;
315 ASSERT(format
== GL_ABGR_EXT
);
316 for (i
= 0; i
< n
; i
++) {
317 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
318 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
319 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
320 | ((rgba
[i
][RCOMP
] & 0xf) );
324 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
325 if (format
== GL_RGBA
) {
326 GLushort
*dst
= (GLushort
*) destination
;
328 for (i
= 0; i
< n
; i
++) {
329 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
330 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
331 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
332 | ((rgba
[i
][RCOMP
] & 0xf) );
335 else if (format
== GL_BGRA
) {
336 GLushort
*dst
= (GLushort
*) destination
;
338 for (i
= 0; i
< n
; i
++) {
339 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
340 | ((rgba
[i
][RCOMP
] & 0xf) << 8)
341 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
342 | ((rgba
[i
][BCOMP
] & 0xf) );
346 GLushort
*dst
= (GLushort
*) destination
;
348 ASSERT(format
== GL_ABGR_EXT
);
349 for (i
= 0; i
< n
; i
++) {
350 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
351 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
352 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
353 | ((rgba
[i
][ACOMP
] & 0xf) );
357 case GL_UNSIGNED_SHORT_5_5_5_1
:
358 if (format
== GL_RGBA
) {
359 GLushort
*dst
= (GLushort
*) destination
;
361 for (i
= 0; i
< n
; i
++) {
362 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
363 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
364 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
365 | ((rgba
[i
][ACOMP
] & 0x1) );
368 else if (format
== GL_BGRA
) {
369 GLushort
*dst
= (GLushort
*) destination
;
371 for (i
= 0; i
< n
; i
++) {
372 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
373 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
374 | ((rgba
[i
][RCOMP
] & 0x1f) << 1)
375 | ((rgba
[i
][ACOMP
] & 0x1) );
379 GLushort
*dst
= (GLushort
*) destination
;
381 ASSERT(format
== GL_ABGR_EXT
);
382 for (i
= 0; i
< n
; i
++) {
383 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
384 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
385 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
386 | ((rgba
[i
][RCOMP
] & 0x1) );
390 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
391 if (format
== GL_RGBA
) {
392 GLushort
*dst
= (GLushort
*) destination
;
394 for (i
= 0; i
< n
; i
++) {
395 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
396 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
397 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
398 | ((rgba
[i
][RCOMP
] & 0x1) );
401 else if (format
== GL_BGRA
) {
402 GLushort
*dst
= (GLushort
*) destination
;
404 for (i
= 0; i
< n
; i
++) {
405 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
406 | ((rgba
[i
][RCOMP
] & 0x1f) << 6)
407 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
408 | ((rgba
[i
][BCOMP
] & 0x1) );
412 GLushort
*dst
= (GLushort
*) destination
;
414 ASSERT(format
== GL_ABGR_EXT
);
415 for (i
= 0; i
< n
; i
++) {
416 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
417 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
418 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
419 | ((rgba
[i
][ACOMP
] & 0x1) );
423 case GL_UNSIGNED_INT_8_8_8_8
:
424 if (format
== GL_RGBA
) {
425 GLuint
*dst
= (GLuint
*) destination
;
427 for (i
= 0; i
< n
; i
++) {
428 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
429 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
430 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
431 | ((rgba
[i
][ACOMP
] & 0xff) );
434 else if (format
== GL_BGRA
) {
435 GLuint
*dst
= (GLuint
*) destination
;
437 for (i
= 0; i
< n
; i
++) {
438 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xff) << 24)
439 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
440 | ((rgba
[i
][RCOMP
] & 0xff) << 8)
441 | ((rgba
[i
][ACOMP
] & 0xff) );
445 GLuint
*dst
= (GLuint
*) destination
;
447 ASSERT(format
== GL_ABGR_EXT
);
448 for (i
= 0; i
< n
; i
++) {
449 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
450 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
451 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
452 | ((rgba
[i
][RCOMP
] & 0xff) );
456 case GL_UNSIGNED_INT_8_8_8_8_REV
:
457 if (format
== GL_RGBA
) {
458 GLuint
*dst
= (GLuint
*) destination
;
460 for (i
= 0; i
< n
; i
++) {
461 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
462 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
463 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
464 | ((rgba
[i
][RCOMP
] & 0xff) );
467 else if (format
== GL_BGRA
) {
468 GLuint
*dst
= (GLuint
*) destination
;
470 for (i
= 0; i
< n
; i
++) {
471 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
472 | ((rgba
[i
][RCOMP
] & 0xff) << 16)
473 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
474 | ((rgba
[i
][BCOMP
] & 0xff) );
478 GLuint
*dst
= (GLuint
*) destination
;
480 ASSERT(format
== GL_ABGR_EXT
);
481 for (i
= 0; i
< n
; i
++) {
482 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
483 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
484 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
485 | ((rgba
[i
][ACOMP
] & 0xff) );
489 case GL_UNSIGNED_INT_10_10_10_2
:
490 if (format
== GL_RGBA
) {
491 GLuint
*dst
= (GLuint
*) destination
;
493 for (i
= 0; i
< n
; i
++) {
494 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
495 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
496 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
497 | ((rgba
[i
][ACOMP
] & 0x3) );
500 else if (format
== GL_BGRA
) {
501 GLuint
*dst
= (GLuint
*) destination
;
503 for (i
= 0; i
< n
; i
++) {
504 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3ff) << 22)
505 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
506 | ((rgba
[i
][RCOMP
] & 0x3ff) << 2)
507 | ((rgba
[i
][ACOMP
] & 0x3) );
511 GLuint
*dst
= (GLuint
*) destination
;
513 ASSERT(format
== GL_ABGR_EXT
);
514 for (i
= 0; i
< n
; i
++) {
515 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
516 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
517 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
518 | ((rgba
[i
][RCOMP
] & 0x3) );
522 case GL_UNSIGNED_INT_2_10_10_10_REV
:
523 if (format
== GL_RGBA
) {
524 GLuint
*dst
= (GLuint
*) destination
;
526 for (i
= 0; i
< n
; i
++) {
527 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
528 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
529 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
530 | ((rgba
[i
][RCOMP
] & 0x3) );
533 else if (format
== GL_BGRA
) {
534 GLuint
*dst
= (GLuint
*) destination
;
536 for (i
= 0; i
< n
; i
++) {
537 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
538 | ((rgba
[i
][RCOMP
] & 0x3ff) << 12)
539 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
540 | ((rgba
[i
][BCOMP
] & 0x3) );
544 GLuint
*dst
= (GLuint
*) destination
;
546 ASSERT(format
== GL_ABGR_EXT
);
547 for (i
= 0; i
< n
; i
++) {
548 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
549 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
550 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
551 | ((rgba
[i
][ACOMP
] & 0x3) );
556 _mesa_problem(ctx
, "Bad type in pack_histogram");
564 * Given an internalFormat token passed to glHistogram or glMinMax,
565 * return the corresponding base format.
566 * Return -1 if invalid token.
569 base_histogram_format( GLenum format
)
584 case GL_LUMINANCE_ALPHA
:
585 case GL_LUMINANCE4_ALPHA4
:
586 case GL_LUMINANCE6_ALPHA2
:
587 case GL_LUMINANCE8_ALPHA8
:
588 case GL_LUMINANCE12_ALPHA4
:
589 case GL_LUMINANCE12_ALPHA12
:
590 case GL_LUMINANCE16_ALPHA16
:
591 return GL_LUMINANCE_ALPHA
;
611 return -1; /* error */
617 /**********************************************************************
622 /* this is defined below */
623 static void GLAPIENTRY
_mesa_ResetMinmax(GLenum target
);
626 static void GLAPIENTRY
627 _mesa_GetMinmax(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
629 GET_CURRENT_CONTEXT(ctx
);
630 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
632 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
633 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax");
637 if (target
!= GL_MINMAX
) {
638 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmax(target)");
642 if (format
!= GL_RED
&&
643 format
!= GL_GREEN
&&
645 format
!= GL_ALPHA
&&
650 format
!= GL_ABGR_EXT
&&
651 format
!= GL_LUMINANCE
&&
652 format
!= GL_LUMINANCE_ALPHA
) {
653 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMax(format)");
656 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
657 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax(format or type)");
662 values
= _mesa_map_validate_pbo_dest(ctx
, 1, &ctx
->Pack
, 2, 1, 1,
663 format
, type
, values
, "glGetMinmax");
668 GLfloat minmax
[2][4];
669 minmax
[0][RCOMP
] = CLAMP(ctx
->MinMax
.Min
[RCOMP
], 0.0F
, 1.0F
);
670 minmax
[0][GCOMP
] = CLAMP(ctx
->MinMax
.Min
[GCOMP
], 0.0F
, 1.0F
);
671 minmax
[0][BCOMP
] = CLAMP(ctx
->MinMax
.Min
[BCOMP
], 0.0F
, 1.0F
);
672 minmax
[0][ACOMP
] = CLAMP(ctx
->MinMax
.Min
[ACOMP
], 0.0F
, 1.0F
);
673 minmax
[1][RCOMP
] = CLAMP(ctx
->MinMax
.Max
[RCOMP
], 0.0F
, 1.0F
);
674 minmax
[1][GCOMP
] = CLAMP(ctx
->MinMax
.Max
[GCOMP
], 0.0F
, 1.0F
);
675 minmax
[1][BCOMP
] = CLAMP(ctx
->MinMax
.Max
[BCOMP
], 0.0F
, 1.0F
);
676 minmax
[1][ACOMP
] = CLAMP(ctx
->MinMax
.Max
[ACOMP
], 0.0F
, 1.0F
);
677 _mesa_pack_rgba_span_float(ctx
, 2, minmax
,
678 format
, type
, values
, &ctx
->Pack
, 0x0);
681 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
684 _mesa_ResetMinmax(GL_MINMAX
);
689 static void GLAPIENTRY
690 _mesa_GetHistogram(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
692 GET_CURRENT_CONTEXT(ctx
);
693 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
695 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
696 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram");
700 if (target
!= GL_HISTOGRAM
) {
701 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(target)");
705 if (format
!= GL_RED
&&
706 format
!= GL_GREEN
&&
708 format
!= GL_ALPHA
&&
713 format
!= GL_ABGR_EXT
&&
714 format
!= GL_LUMINANCE
&&
715 format
!= GL_LUMINANCE_ALPHA
) {
716 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(format)");
719 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
720 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram(format or type)");
724 values
= _mesa_map_validate_pbo_dest(ctx
, 1, &ctx
->Pack
,
725 ctx
->Histogram
.Width
, 1, 1,
726 format
, type
, values
,
731 pack_histogram(ctx
, ctx
->Histogram
.Width
,
732 (CONST
GLuint (*)[4]) ctx
->Histogram
.Count
,
733 format
, type
, values
, &ctx
->Pack
);
735 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
739 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
740 ctx
->Histogram
.Count
[i
][0] = 0;
741 ctx
->Histogram
.Count
[i
][1] = 0;
742 ctx
->Histogram
.Count
[i
][2] = 0;
743 ctx
->Histogram
.Count
[i
][3] = 0;
749 static void GLAPIENTRY
750 _mesa_GetHistogramParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
752 GET_CURRENT_CONTEXT(ctx
);
753 ASSERT_OUTSIDE_BEGIN_END(ctx
);
755 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
756 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameterfv");
760 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
761 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(target)");
766 case GL_HISTOGRAM_WIDTH
:
767 *params
= (GLfloat
) ctx
->Histogram
.Width
;
769 case GL_HISTOGRAM_FORMAT
:
770 *params
= (GLfloat
) ctx
->Histogram
.Format
;
772 case GL_HISTOGRAM_RED_SIZE
:
773 *params
= (GLfloat
) ctx
->Histogram
.RedSize
;
775 case GL_HISTOGRAM_GREEN_SIZE
:
776 *params
= (GLfloat
) ctx
->Histogram
.GreenSize
;
778 case GL_HISTOGRAM_BLUE_SIZE
:
779 *params
= (GLfloat
) ctx
->Histogram
.BlueSize
;
781 case GL_HISTOGRAM_ALPHA_SIZE
:
782 *params
= (GLfloat
) ctx
->Histogram
.AlphaSize
;
784 case GL_HISTOGRAM_LUMINANCE_SIZE
:
785 *params
= (GLfloat
) ctx
->Histogram
.LuminanceSize
;
787 case GL_HISTOGRAM_SINK
:
788 *params
= (GLfloat
) ctx
->Histogram
.Sink
;
791 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(pname)");
796 static void GLAPIENTRY
797 _mesa_GetHistogramParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
799 GET_CURRENT_CONTEXT(ctx
);
800 ASSERT_OUTSIDE_BEGIN_END(ctx
);
802 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
803 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameteriv");
807 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
808 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(target)");
813 case GL_HISTOGRAM_WIDTH
:
814 *params
= (GLint
) ctx
->Histogram
.Width
;
816 case GL_HISTOGRAM_FORMAT
:
817 *params
= (GLint
) ctx
->Histogram
.Format
;
819 case GL_HISTOGRAM_RED_SIZE
:
820 *params
= (GLint
) ctx
->Histogram
.RedSize
;
822 case GL_HISTOGRAM_GREEN_SIZE
:
823 *params
= (GLint
) ctx
->Histogram
.GreenSize
;
825 case GL_HISTOGRAM_BLUE_SIZE
:
826 *params
= (GLint
) ctx
->Histogram
.BlueSize
;
828 case GL_HISTOGRAM_ALPHA_SIZE
:
829 *params
= (GLint
) ctx
->Histogram
.AlphaSize
;
831 case GL_HISTOGRAM_LUMINANCE_SIZE
:
832 *params
= (GLint
) ctx
->Histogram
.LuminanceSize
;
834 case GL_HISTOGRAM_SINK
:
835 *params
= (GLint
) ctx
->Histogram
.Sink
;
838 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(pname)");
843 static void GLAPIENTRY
844 _mesa_GetMinmaxParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
846 GET_CURRENT_CONTEXT(ctx
);
847 ASSERT_OUTSIDE_BEGIN_END(ctx
);
849 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
850 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameterfv");
853 if (target
!= GL_MINMAX
) {
854 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameterfv(target)");
857 if (pname
== GL_MINMAX_FORMAT
) {
858 *params
= (GLfloat
) ctx
->MinMax
.Format
;
860 else if (pname
== GL_MINMAX_SINK
) {
861 *params
= (GLfloat
) ctx
->MinMax
.Sink
;
864 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameterfv(pname)");
869 static void GLAPIENTRY
870 _mesa_GetMinmaxParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
872 GET_CURRENT_CONTEXT(ctx
);
873 ASSERT_OUTSIDE_BEGIN_END(ctx
);
875 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
876 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameteriv");
879 if (target
!= GL_MINMAX
) {
880 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameteriv(target)");
883 if (pname
== GL_MINMAX_FORMAT
) {
884 *params
= (GLint
) ctx
->MinMax
.Format
;
886 else if (pname
== GL_MINMAX_SINK
) {
887 *params
= (GLint
) ctx
->MinMax
.Sink
;
890 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameteriv(pname)");
895 static void GLAPIENTRY
896 _mesa_Histogram(GLenum target
, GLsizei width
, GLenum internalFormat
, GLboolean sink
)
899 GLboolean error
= GL_FALSE
;
900 GET_CURRENT_CONTEXT(ctx
);
901 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
903 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
904 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glHistogram");
908 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
909 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(target)");
913 if (width
< 0 || width
> HISTOGRAM_TABLE_SIZE
) {
914 if (target
== GL_PROXY_HISTOGRAM
) {
919 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
921 _mesa_error(ctx
, GL_TABLE_TOO_LARGE
, "glHistogram(width)");
926 if (width
!= 0 && !_mesa_is_pow_two(width
)) {
927 if (target
== GL_PROXY_HISTOGRAM
) {
931 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
936 if (base_histogram_format(internalFormat
) < 0) {
937 if (target
== GL_PROXY_HISTOGRAM
) {
941 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(internalFormat)");
946 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
948 /* reset histograms */
949 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
950 ctx
->Histogram
.Count
[i
][0] = 0;
951 ctx
->Histogram
.Count
[i
][1] = 0;
952 ctx
->Histogram
.Count
[i
][2] = 0;
953 ctx
->Histogram
.Count
[i
][3] = 0;
957 ctx
->Histogram
.Width
= 0;
958 ctx
->Histogram
.Format
= 0;
959 ctx
->Histogram
.RedSize
= 0;
960 ctx
->Histogram
.GreenSize
= 0;
961 ctx
->Histogram
.BlueSize
= 0;
962 ctx
->Histogram
.AlphaSize
= 0;
963 ctx
->Histogram
.LuminanceSize
= 0;
966 ctx
->Histogram
.Width
= width
;
967 ctx
->Histogram
.Format
= internalFormat
;
968 ctx
->Histogram
.Sink
= sink
;
969 ctx
->Histogram
.RedSize
= 8 * sizeof(GLuint
);
970 ctx
->Histogram
.GreenSize
= 8 * sizeof(GLuint
);
971 ctx
->Histogram
.BlueSize
= 8 * sizeof(GLuint
);
972 ctx
->Histogram
.AlphaSize
= 8 * sizeof(GLuint
);
973 ctx
->Histogram
.LuminanceSize
= 8 * sizeof(GLuint
);
978 static void GLAPIENTRY
979 _mesa_Minmax(GLenum target
, GLenum internalFormat
, GLboolean sink
)
981 GET_CURRENT_CONTEXT(ctx
);
982 ASSERT_OUTSIDE_BEGIN_END(ctx
);
984 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
985 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glMinmax");
989 if (target
!= GL_MINMAX
) {
990 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(target)");
994 if (base_histogram_format(internalFormat
) < 0) {
995 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(internalFormat)");
999 if (ctx
->MinMax
.Sink
== sink
)
1001 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
1002 ctx
->MinMax
.Sink
= sink
;
1006 static void GLAPIENTRY
1007 _mesa_ResetHistogram(GLenum target
)
1010 GET_CURRENT_CONTEXT(ctx
);
1011 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
1013 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1014 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetHistogram");
1018 if (target
!= GL_HISTOGRAM
) {
1019 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetHistogram(target)");
1023 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1024 ctx
->Histogram
.Count
[i
][0] = 0;
1025 ctx
->Histogram
.Count
[i
][1] = 0;
1026 ctx
->Histogram
.Count
[i
][2] = 0;
1027 ctx
->Histogram
.Count
[i
][3] = 0;
1032 static void GLAPIENTRY
1033 _mesa_ResetMinmax(GLenum target
)
1035 GET_CURRENT_CONTEXT(ctx
);
1036 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1038 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1039 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetMinmax");
1043 if (target
!= GL_MINMAX
) {
1044 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetMinMax(target)");
1048 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1049 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1050 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1051 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;
1056 _mesa_init_histogram_dispatch(struct _glapi_table
*disp
)
1058 SET_GetHistogram(disp
, _mesa_GetHistogram
);
1059 SET_GetHistogramParameterfv(disp
, _mesa_GetHistogramParameterfv
);
1060 SET_GetHistogramParameteriv(disp
, _mesa_GetHistogramParameteriv
);
1061 SET_GetMinmax(disp
, _mesa_GetMinmax
);
1062 SET_GetMinmaxParameterfv(disp
, _mesa_GetMinmaxParameterfv
);
1063 SET_GetMinmaxParameteriv(disp
, _mesa_GetMinmaxParameteriv
);
1064 SET_Histogram(disp
, _mesa_Histogram
);
1065 SET_Minmax(disp
, _mesa_Minmax
);
1066 SET_ResetHistogram(disp
, _mesa_ResetHistogram
);
1067 SET_ResetMinmax(disp
, _mesa_ResetMinmax
);
1071 #endif /* FEATURE_histogram */
1074 /**********************************************************************/
1075 /***** Initialization *****/
1076 /**********************************************************************/
1078 void _mesa_init_histogram( GLcontext
* ctx
)
1082 /* Histogram group */
1083 ctx
->Histogram
.Width
= 0;
1084 ctx
->Histogram
.Format
= GL_RGBA
;
1085 ctx
->Histogram
.Sink
= GL_FALSE
;
1086 ctx
->Histogram
.RedSize
= 0;
1087 ctx
->Histogram
.GreenSize
= 0;
1088 ctx
->Histogram
.BlueSize
= 0;
1089 ctx
->Histogram
.AlphaSize
= 0;
1090 ctx
->Histogram
.LuminanceSize
= 0;
1091 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1092 ctx
->Histogram
.Count
[i
][0] = 0;
1093 ctx
->Histogram
.Count
[i
][1] = 0;
1094 ctx
->Histogram
.Count
[i
][2] = 0;
1095 ctx
->Histogram
.Count
[i
][3] = 0;
1099 ctx
->MinMax
.Format
= GL_RGBA
;
1100 ctx
->MinMax
.Sink
= GL_FALSE
;
1101 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1102 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1103 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1104 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;