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
];
192 GLhalfARB
*dst
= (GLhalfARB
*) destination
;
194 /* get GLuint values */
196 /* convert to GLhalf */
197 for (i
= 0; i
< n
* comps
; i
++) {
198 dst
[i
] = _mesa_float_to_half((GLfloat
) temp
[i
]);
200 if (packing
->SwapBytes
) {
201 _mesa_swap2((GLushort
*) dst
, n
* comps
);
205 case GL_UNSIGNED_BYTE_3_3_2
:
206 if (format
== GL_RGB
) {
207 GLubyte
*dst
= (GLubyte
*) destination
;
209 for (i
= 0; i
< n
; i
++) {
210 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x7) << 5)
211 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
212 | ((rgba
[i
][BCOMP
] & 0x3) );
216 GLubyte
*dst
= (GLubyte
*) destination
;
218 ASSERT(format
== GL_BGR
);
219 for (i
= 0; i
< n
; i
++) {
220 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x7) << 5)
221 | ((rgba
[i
][GCOMP
] & 0x7) << 2)
222 | ((rgba
[i
][RCOMP
] & 0x3) );
226 case GL_UNSIGNED_BYTE_2_3_3_REV
:
227 if (format
== GL_RGB
) {
228 GLubyte
*dst
= (GLubyte
*) destination
;
230 for (i
= 0; i
< n
; i
++) {
231 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3) << 6)
232 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
233 | ((rgba
[i
][BCOMP
] & 0x7) );
237 GLubyte
*dst
= (GLubyte
*) destination
;
239 ASSERT(format
== GL_BGR
);
240 for (i
= 0; i
< n
; i
++) {
241 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3) << 6)
242 | ((rgba
[i
][GCOMP
] & 0x7) << 3)
243 | ((rgba
[i
][RCOMP
] & 0x7) );
247 case GL_UNSIGNED_SHORT_5_6_5
:
248 if (format
== GL_RGB
) {
249 GLushort
*dst
= (GLushort
*) destination
;
251 for (i
= 0; i
< n
; i
++) {
252 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
253 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
254 | ((rgba
[i
][BCOMP
] & 0x1f) );
258 GLushort
*dst
= (GLushort
*) destination
;
260 ASSERT(format
== GL_BGR
);
261 for (i
= 0; i
< n
; i
++) {
262 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
263 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
264 | ((rgba
[i
][RCOMP
] & 0x1f) );
268 case GL_UNSIGNED_SHORT_5_6_5_REV
:
269 if (format
== GL_RGB
) {
270 GLushort
*dst
= (GLushort
*) destination
;
272 for (i
= 0; i
< n
; i
++) {
273 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
274 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
275 | ((rgba
[i
][RCOMP
] & 0x1f) );
279 GLushort
*dst
= (GLushort
*) destination
;
281 ASSERT(format
== GL_BGR
);
282 for (i
= 0; i
< n
; i
++) {
283 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
284 | ((rgba
[i
][GCOMP
] & 0x3f) << 5)
285 | ((rgba
[i
][BCOMP
] & 0x1f) );
289 case GL_UNSIGNED_SHORT_4_4_4_4
:
290 if (format
== GL_RGBA
) {
291 GLushort
*dst
= (GLushort
*) destination
;
293 for (i
= 0; i
< n
; i
++) {
294 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
295 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
296 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
297 | ((rgba
[i
][ACOMP
] & 0xf) );
300 else if (format
== GL_BGRA
) {
301 GLushort
*dst
= (GLushort
*) destination
;
303 for (i
= 0; i
< n
; i
++) {
304 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xf) << 12)
305 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
306 | ((rgba
[i
][RCOMP
] & 0xf) << 4)
307 | ((rgba
[i
][ACOMP
] & 0xf) );
311 GLushort
*dst
= (GLushort
*) destination
;
313 ASSERT(format
== GL_ABGR_EXT
);
314 for (i
= 0; i
< n
; i
++) {
315 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
316 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
317 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
318 | ((rgba
[i
][RCOMP
] & 0xf) );
322 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
323 if (format
== GL_RGBA
) {
324 GLushort
*dst
= (GLushort
*) destination
;
326 for (i
= 0; i
< n
; i
++) {
327 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
328 | ((rgba
[i
][BCOMP
] & 0xf) << 8)
329 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
330 | ((rgba
[i
][RCOMP
] & 0xf) );
333 else if (format
== GL_BGRA
) {
334 GLushort
*dst
= (GLushort
*) destination
;
336 for (i
= 0; i
< n
; i
++) {
337 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xf) << 12)
338 | ((rgba
[i
][RCOMP
] & 0xf) << 8)
339 | ((rgba
[i
][GCOMP
] & 0xf) << 4)
340 | ((rgba
[i
][BCOMP
] & 0xf) );
344 GLushort
*dst
= (GLushort
*) destination
;
346 ASSERT(format
== GL_ABGR_EXT
);
347 for (i
= 0; i
< n
; i
++) {
348 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xf) << 12)
349 | ((rgba
[i
][GCOMP
] & 0xf) << 8)
350 | ((rgba
[i
][BCOMP
] & 0xf) << 4)
351 | ((rgba
[i
][ACOMP
] & 0xf) );
355 case GL_UNSIGNED_SHORT_5_5_5_1
:
356 if (format
== GL_RGBA
) {
357 GLushort
*dst
= (GLushort
*) destination
;
359 for (i
= 0; i
< n
; i
++) {
360 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
361 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
362 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
363 | ((rgba
[i
][ACOMP
] & 0x1) );
366 else if (format
== GL_BGRA
) {
367 GLushort
*dst
= (GLushort
*) destination
;
369 for (i
= 0; i
< n
; i
++) {
370 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x1f) << 11)
371 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
372 | ((rgba
[i
][RCOMP
] & 0x1f) << 1)
373 | ((rgba
[i
][ACOMP
] & 0x1) );
377 GLushort
*dst
= (GLushort
*) destination
;
379 ASSERT(format
== GL_ABGR_EXT
);
380 for (i
= 0; i
< n
; i
++) {
381 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
382 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
383 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
384 | ((rgba
[i
][RCOMP
] & 0x1) );
388 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
389 if (format
== GL_RGBA
) {
390 GLushort
*dst
= (GLushort
*) destination
;
392 for (i
= 0; i
< n
; i
++) {
393 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
394 | ((rgba
[i
][BCOMP
] & 0x1f) << 6)
395 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
396 | ((rgba
[i
][RCOMP
] & 0x1) );
399 else if (format
== GL_BGRA
) {
400 GLushort
*dst
= (GLushort
*) destination
;
402 for (i
= 0; i
< n
; i
++) {
403 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x1f) << 11)
404 | ((rgba
[i
][RCOMP
] & 0x1f) << 6)
405 | ((rgba
[i
][GCOMP
] & 0x1f) << 1)
406 | ((rgba
[i
][BCOMP
] & 0x1) );
410 GLushort
*dst
= (GLushort
*) destination
;
412 ASSERT(format
== GL_ABGR_EXT
);
413 for (i
= 0; i
< n
; i
++) {
414 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x1f) << 11)
415 | ((rgba
[i
][GCOMP
] & 0x1f) << 6)
416 | ((rgba
[i
][BCOMP
] & 0x1f) << 1)
417 | ((rgba
[i
][ACOMP
] & 0x1) );
421 case GL_UNSIGNED_INT_8_8_8_8
:
422 if (format
== GL_RGBA
) {
423 GLuint
*dst
= (GLuint
*) destination
;
425 for (i
= 0; i
< n
; i
++) {
426 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
427 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
428 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
429 | ((rgba
[i
][ACOMP
] & 0xff) );
432 else if (format
== GL_BGRA
) {
433 GLuint
*dst
= (GLuint
*) destination
;
435 for (i
= 0; i
< n
; i
++) {
436 dst
[i
] = ((rgba
[i
][BCOMP
] & 0xff) << 24)
437 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
438 | ((rgba
[i
][RCOMP
] & 0xff) << 8)
439 | ((rgba
[i
][ACOMP
] & 0xff) );
443 GLuint
*dst
= (GLuint
*) destination
;
445 ASSERT(format
== GL_ABGR_EXT
);
446 for (i
= 0; i
< n
; i
++) {
447 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
448 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
449 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
450 | ((rgba
[i
][RCOMP
] & 0xff) );
454 case GL_UNSIGNED_INT_8_8_8_8_REV
:
455 if (format
== GL_RGBA
) {
456 GLuint
*dst
= (GLuint
*) destination
;
458 for (i
= 0; i
< n
; i
++) {
459 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
460 | ((rgba
[i
][BCOMP
] & 0xff) << 16)
461 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
462 | ((rgba
[i
][RCOMP
] & 0xff) );
465 else if (format
== GL_BGRA
) {
466 GLuint
*dst
= (GLuint
*) destination
;
468 for (i
= 0; i
< n
; i
++) {
469 dst
[i
] = ((rgba
[i
][ACOMP
] & 0xff) << 24)
470 | ((rgba
[i
][RCOMP
] & 0xff) << 16)
471 | ((rgba
[i
][GCOMP
] & 0xff) << 8)
472 | ((rgba
[i
][BCOMP
] & 0xff) );
476 GLuint
*dst
= (GLuint
*) destination
;
478 ASSERT(format
== GL_ABGR_EXT
);
479 for (i
= 0; i
< n
; i
++) {
480 dst
[i
] = ((rgba
[i
][RCOMP
] & 0xff) << 24)
481 | ((rgba
[i
][GCOMP
] & 0xff) << 16)
482 | ((rgba
[i
][BCOMP
] & 0xff) << 8)
483 | ((rgba
[i
][ACOMP
] & 0xff) );
487 case GL_UNSIGNED_INT_10_10_10_2
:
488 if (format
== GL_RGBA
) {
489 GLuint
*dst
= (GLuint
*) destination
;
491 for (i
= 0; i
< n
; i
++) {
492 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
493 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
494 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
495 | ((rgba
[i
][ACOMP
] & 0x3) );
498 else if (format
== GL_BGRA
) {
499 GLuint
*dst
= (GLuint
*) destination
;
501 for (i
= 0; i
< n
; i
++) {
502 dst
[i
] = ((rgba
[i
][BCOMP
] & 0x3ff) << 22)
503 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
504 | ((rgba
[i
][RCOMP
] & 0x3ff) << 2)
505 | ((rgba
[i
][ACOMP
] & 0x3) );
509 GLuint
*dst
= (GLuint
*) destination
;
511 ASSERT(format
== GL_ABGR_EXT
);
512 for (i
= 0; i
< n
; i
++) {
513 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
514 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
515 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
516 | ((rgba
[i
][RCOMP
] & 0x3) );
520 case GL_UNSIGNED_INT_2_10_10_10_REV
:
521 if (format
== GL_RGBA
) {
522 GLuint
*dst
= (GLuint
*) destination
;
524 for (i
= 0; i
< n
; i
++) {
525 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
526 | ((rgba
[i
][BCOMP
] & 0x3ff) << 12)
527 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
528 | ((rgba
[i
][RCOMP
] & 0x3) );
531 else if (format
== GL_BGRA
) {
532 GLuint
*dst
= (GLuint
*) destination
;
534 for (i
= 0; i
< n
; i
++) {
535 dst
[i
] = ((rgba
[i
][ACOMP
] & 0x3ff) << 22)
536 | ((rgba
[i
][RCOMP
] & 0x3ff) << 12)
537 | ((rgba
[i
][GCOMP
] & 0x3ff) << 2)
538 | ((rgba
[i
][BCOMP
] & 0x3) );
542 GLuint
*dst
= (GLuint
*) destination
;
544 ASSERT(format
== GL_ABGR_EXT
);
545 for (i
= 0; i
< n
; i
++) {
546 dst
[i
] = ((rgba
[i
][RCOMP
] & 0x3ff) << 22)
547 | ((rgba
[i
][GCOMP
] & 0x3ff) << 12)
548 | ((rgba
[i
][BCOMP
] & 0x3ff) << 2)
549 | ((rgba
[i
][ACOMP
] & 0x3) );
554 _mesa_problem(ctx
, "Bad type in pack_histogram");
562 * Given an internalFormat token passed to glHistogram or glMinMax,
563 * return the corresponding base format.
564 * Return -1 if invalid token.
567 base_histogram_format( GLenum format
)
582 case GL_LUMINANCE_ALPHA
:
583 case GL_LUMINANCE4_ALPHA4
:
584 case GL_LUMINANCE6_ALPHA2
:
585 case GL_LUMINANCE8_ALPHA8
:
586 case GL_LUMINANCE12_ALPHA4
:
587 case GL_LUMINANCE12_ALPHA12
:
588 case GL_LUMINANCE16_ALPHA16
:
589 return GL_LUMINANCE_ALPHA
;
609 return -1; /* error */
615 /**********************************************************************
620 /* this is defined below */
621 static void GLAPIENTRY
_mesa_ResetMinmax(GLenum target
);
624 static void GLAPIENTRY
625 _mesa_GetMinmax(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
627 GET_CURRENT_CONTEXT(ctx
);
628 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
630 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
631 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax");
635 if (target
!= GL_MINMAX
) {
636 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmax(target)");
640 if (format
!= GL_RED
&&
641 format
!= GL_GREEN
&&
643 format
!= GL_ALPHA
&&
648 format
!= GL_ABGR_EXT
&&
649 format
!= GL_LUMINANCE
&&
650 format
!= GL_LUMINANCE_ALPHA
) {
651 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMax(format)");
654 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
655 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmax(format or type)");
660 values
= _mesa_map_validate_pbo_dest(ctx
, 1, &ctx
->Pack
, 2, 1, 1,
661 format
, type
, values
, "glGetMinmax");
666 GLfloat minmax
[2][4];
667 minmax
[0][RCOMP
] = CLAMP(ctx
->MinMax
.Min
[RCOMP
], 0.0F
, 1.0F
);
668 minmax
[0][GCOMP
] = CLAMP(ctx
->MinMax
.Min
[GCOMP
], 0.0F
, 1.0F
);
669 minmax
[0][BCOMP
] = CLAMP(ctx
->MinMax
.Min
[BCOMP
], 0.0F
, 1.0F
);
670 minmax
[0][ACOMP
] = CLAMP(ctx
->MinMax
.Min
[ACOMP
], 0.0F
, 1.0F
);
671 minmax
[1][RCOMP
] = CLAMP(ctx
->MinMax
.Max
[RCOMP
], 0.0F
, 1.0F
);
672 minmax
[1][GCOMP
] = CLAMP(ctx
->MinMax
.Max
[GCOMP
], 0.0F
, 1.0F
);
673 minmax
[1][BCOMP
] = CLAMP(ctx
->MinMax
.Max
[BCOMP
], 0.0F
, 1.0F
);
674 minmax
[1][ACOMP
] = CLAMP(ctx
->MinMax
.Max
[ACOMP
], 0.0F
, 1.0F
);
675 _mesa_pack_rgba_span_float(ctx
, 2, minmax
,
676 format
, type
, values
, &ctx
->Pack
, 0x0);
679 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
682 _mesa_ResetMinmax(GL_MINMAX
);
687 static void GLAPIENTRY
688 _mesa_GetHistogram(GLenum target
, GLboolean reset
, GLenum format
, GLenum type
, GLvoid
*values
)
690 GET_CURRENT_CONTEXT(ctx
);
691 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
693 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
694 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram");
698 if (target
!= GL_HISTOGRAM
) {
699 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(target)");
703 if (format
!= GL_RED
&&
704 format
!= GL_GREEN
&&
706 format
!= GL_ALPHA
&&
711 format
!= GL_ABGR_EXT
&&
712 format
!= GL_LUMINANCE
&&
713 format
!= GL_LUMINANCE_ALPHA
) {
714 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogram(format)");
717 if (!_mesa_is_legal_format_and_type(ctx
, format
, type
)) {
718 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogram(format or type)");
722 values
= _mesa_map_validate_pbo_dest(ctx
, 1, &ctx
->Pack
,
723 ctx
->Histogram
.Width
, 1, 1,
724 format
, type
, values
,
729 pack_histogram(ctx
, ctx
->Histogram
.Width
,
730 (CONST
GLuint (*)[4]) ctx
->Histogram
.Count
,
731 format
, type
, values
, &ctx
->Pack
);
733 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
737 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
738 ctx
->Histogram
.Count
[i
][0] = 0;
739 ctx
->Histogram
.Count
[i
][1] = 0;
740 ctx
->Histogram
.Count
[i
][2] = 0;
741 ctx
->Histogram
.Count
[i
][3] = 0;
747 static void GLAPIENTRY
748 _mesa_GetHistogramParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
750 GET_CURRENT_CONTEXT(ctx
);
751 ASSERT_OUTSIDE_BEGIN_END(ctx
);
753 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
754 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameterfv");
758 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
759 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(target)");
764 case GL_HISTOGRAM_WIDTH
:
765 *params
= (GLfloat
) ctx
->Histogram
.Width
;
767 case GL_HISTOGRAM_FORMAT
:
768 *params
= (GLfloat
) ctx
->Histogram
.Format
;
770 case GL_HISTOGRAM_RED_SIZE
:
771 *params
= (GLfloat
) ctx
->Histogram
.RedSize
;
773 case GL_HISTOGRAM_GREEN_SIZE
:
774 *params
= (GLfloat
) ctx
->Histogram
.GreenSize
;
776 case GL_HISTOGRAM_BLUE_SIZE
:
777 *params
= (GLfloat
) ctx
->Histogram
.BlueSize
;
779 case GL_HISTOGRAM_ALPHA_SIZE
:
780 *params
= (GLfloat
) ctx
->Histogram
.AlphaSize
;
782 case GL_HISTOGRAM_LUMINANCE_SIZE
:
783 *params
= (GLfloat
) ctx
->Histogram
.LuminanceSize
;
785 case GL_HISTOGRAM_SINK
:
786 *params
= (GLfloat
) ctx
->Histogram
.Sink
;
789 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameterfv(pname)");
794 static void GLAPIENTRY
795 _mesa_GetHistogramParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
797 GET_CURRENT_CONTEXT(ctx
);
798 ASSERT_OUTSIDE_BEGIN_END(ctx
);
800 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
801 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetHistogramParameteriv");
805 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
806 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(target)");
811 case GL_HISTOGRAM_WIDTH
:
812 *params
= (GLint
) ctx
->Histogram
.Width
;
814 case GL_HISTOGRAM_FORMAT
:
815 *params
= (GLint
) ctx
->Histogram
.Format
;
817 case GL_HISTOGRAM_RED_SIZE
:
818 *params
= (GLint
) ctx
->Histogram
.RedSize
;
820 case GL_HISTOGRAM_GREEN_SIZE
:
821 *params
= (GLint
) ctx
->Histogram
.GreenSize
;
823 case GL_HISTOGRAM_BLUE_SIZE
:
824 *params
= (GLint
) ctx
->Histogram
.BlueSize
;
826 case GL_HISTOGRAM_ALPHA_SIZE
:
827 *params
= (GLint
) ctx
->Histogram
.AlphaSize
;
829 case GL_HISTOGRAM_LUMINANCE_SIZE
:
830 *params
= (GLint
) ctx
->Histogram
.LuminanceSize
;
832 case GL_HISTOGRAM_SINK
:
833 *params
= (GLint
) ctx
->Histogram
.Sink
;
836 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHistogramParameteriv(pname)");
841 static void GLAPIENTRY
842 _mesa_GetMinmaxParameterfv(GLenum target
, GLenum pname
, GLfloat
*params
)
844 GET_CURRENT_CONTEXT(ctx
);
845 ASSERT_OUTSIDE_BEGIN_END(ctx
);
847 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
848 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameterfv");
851 if (target
!= GL_MINMAX
) {
852 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameterfv(target)");
855 if (pname
== GL_MINMAX_FORMAT
) {
856 *params
= (GLfloat
) ctx
->MinMax
.Format
;
858 else if (pname
== GL_MINMAX_SINK
) {
859 *params
= (GLfloat
) ctx
->MinMax
.Sink
;
862 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameterfv(pname)");
867 static void GLAPIENTRY
868 _mesa_GetMinmaxParameteriv(GLenum target
, GLenum pname
, GLint
*params
)
870 GET_CURRENT_CONTEXT(ctx
);
871 ASSERT_OUTSIDE_BEGIN_END(ctx
);
873 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
874 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetMinmaxParameteriv");
877 if (target
!= GL_MINMAX
) {
878 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinmaxParameteriv(target)");
881 if (pname
== GL_MINMAX_FORMAT
) {
882 *params
= (GLint
) ctx
->MinMax
.Format
;
884 else if (pname
== GL_MINMAX_SINK
) {
885 *params
= (GLint
) ctx
->MinMax
.Sink
;
888 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetMinMaxParameteriv(pname)");
893 static void GLAPIENTRY
894 _mesa_Histogram(GLenum target
, GLsizei width
, GLenum internalFormat
, GLboolean sink
)
897 GLboolean error
= GL_FALSE
;
898 GET_CURRENT_CONTEXT(ctx
);
899 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
901 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
902 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glHistogram");
906 if (target
!= GL_HISTOGRAM
&& target
!= GL_PROXY_HISTOGRAM
) {
907 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(target)");
911 if (width
< 0 || width
> HISTOGRAM_TABLE_SIZE
) {
912 if (target
== GL_PROXY_HISTOGRAM
) {
917 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
919 _mesa_error(ctx
, GL_TABLE_TOO_LARGE
, "glHistogram(width)");
924 if (width
!= 0 && !_mesa_is_pow_two(width
)) {
925 if (target
== GL_PROXY_HISTOGRAM
) {
929 _mesa_error(ctx
, GL_INVALID_VALUE
, "glHistogram(width)");
934 if (base_histogram_format(internalFormat
) < 0) {
935 if (target
== GL_PROXY_HISTOGRAM
) {
939 _mesa_error(ctx
, GL_INVALID_ENUM
, "glHistogram(internalFormat)");
944 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
946 /* reset histograms */
947 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
948 ctx
->Histogram
.Count
[i
][0] = 0;
949 ctx
->Histogram
.Count
[i
][1] = 0;
950 ctx
->Histogram
.Count
[i
][2] = 0;
951 ctx
->Histogram
.Count
[i
][3] = 0;
955 ctx
->Histogram
.Width
= 0;
956 ctx
->Histogram
.Format
= 0;
957 ctx
->Histogram
.RedSize
= 0;
958 ctx
->Histogram
.GreenSize
= 0;
959 ctx
->Histogram
.BlueSize
= 0;
960 ctx
->Histogram
.AlphaSize
= 0;
961 ctx
->Histogram
.LuminanceSize
= 0;
964 ctx
->Histogram
.Width
= width
;
965 ctx
->Histogram
.Format
= internalFormat
;
966 ctx
->Histogram
.Sink
= sink
;
967 ctx
->Histogram
.RedSize
= 8 * sizeof(GLuint
);
968 ctx
->Histogram
.GreenSize
= 8 * sizeof(GLuint
);
969 ctx
->Histogram
.BlueSize
= 8 * sizeof(GLuint
);
970 ctx
->Histogram
.AlphaSize
= 8 * sizeof(GLuint
);
971 ctx
->Histogram
.LuminanceSize
= 8 * sizeof(GLuint
);
976 static void GLAPIENTRY
977 _mesa_Minmax(GLenum target
, GLenum internalFormat
, GLboolean sink
)
979 GET_CURRENT_CONTEXT(ctx
);
980 ASSERT_OUTSIDE_BEGIN_END(ctx
);
982 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
983 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glMinmax");
987 if (target
!= GL_MINMAX
) {
988 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(target)");
992 if (base_histogram_format(internalFormat
) < 0) {
993 _mesa_error(ctx
, GL_INVALID_ENUM
, "glMinMax(internalFormat)");
997 if (ctx
->MinMax
.Sink
== sink
)
999 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
1000 ctx
->MinMax
.Sink
= sink
;
1004 static void GLAPIENTRY
1005 _mesa_ResetHistogram(GLenum target
)
1008 GET_CURRENT_CONTEXT(ctx
);
1009 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
); /* sideeffects */
1011 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1012 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetHistogram");
1016 if (target
!= GL_HISTOGRAM
) {
1017 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetHistogram(target)");
1021 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1022 ctx
->Histogram
.Count
[i
][0] = 0;
1023 ctx
->Histogram
.Count
[i
][1] = 0;
1024 ctx
->Histogram
.Count
[i
][2] = 0;
1025 ctx
->Histogram
.Count
[i
][3] = 0;
1030 static void GLAPIENTRY
1031 _mesa_ResetMinmax(GLenum target
)
1033 GET_CURRENT_CONTEXT(ctx
);
1034 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
);
1036 if (!ctx
->Extensions
.EXT_histogram
&& !ctx
->Extensions
.ARB_imaging
) {
1037 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glResetMinmax");
1041 if (target
!= GL_MINMAX
) {
1042 _mesa_error(ctx
, GL_INVALID_ENUM
, "glResetMinMax(target)");
1046 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1047 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1048 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1049 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;
1054 _mesa_init_histogram_dispatch(struct _glapi_table
*disp
)
1056 SET_GetHistogram(disp
, _mesa_GetHistogram
);
1057 SET_GetHistogramParameterfv(disp
, _mesa_GetHistogramParameterfv
);
1058 SET_GetHistogramParameteriv(disp
, _mesa_GetHistogramParameteriv
);
1059 SET_GetMinmax(disp
, _mesa_GetMinmax
);
1060 SET_GetMinmaxParameterfv(disp
, _mesa_GetMinmaxParameterfv
);
1061 SET_GetMinmaxParameteriv(disp
, _mesa_GetMinmaxParameteriv
);
1062 SET_Histogram(disp
, _mesa_Histogram
);
1063 SET_Minmax(disp
, _mesa_Minmax
);
1064 SET_ResetHistogram(disp
, _mesa_ResetHistogram
);
1065 SET_ResetMinmax(disp
, _mesa_ResetMinmax
);
1069 #endif /* FEATURE_histogram */
1072 /**********************************************************************/
1073 /***** Initialization *****/
1074 /**********************************************************************/
1076 void _mesa_init_histogram( GLcontext
* ctx
)
1080 /* Histogram group */
1081 ctx
->Histogram
.Width
= 0;
1082 ctx
->Histogram
.Format
= GL_RGBA
;
1083 ctx
->Histogram
.Sink
= GL_FALSE
;
1084 ctx
->Histogram
.RedSize
= 0;
1085 ctx
->Histogram
.GreenSize
= 0;
1086 ctx
->Histogram
.BlueSize
= 0;
1087 ctx
->Histogram
.AlphaSize
= 0;
1088 ctx
->Histogram
.LuminanceSize
= 0;
1089 for (i
= 0; i
< HISTOGRAM_TABLE_SIZE
; i
++) {
1090 ctx
->Histogram
.Count
[i
][0] = 0;
1091 ctx
->Histogram
.Count
[i
][1] = 0;
1092 ctx
->Histogram
.Count
[i
][2] = 0;
1093 ctx
->Histogram
.Count
[i
][3] = 0;
1097 ctx
->MinMax
.Format
= GL_RGBA
;
1098 ctx
->MinMax
.Sink
= GL_FALSE
;
1099 ctx
->MinMax
.Min
[RCOMP
] = 1000; ctx
->MinMax
.Max
[RCOMP
] = -1000;
1100 ctx
->MinMax
.Min
[GCOMP
] = 1000; ctx
->MinMax
.Max
[GCOMP
] = -1000;
1101 ctx
->MinMax
.Min
[BCOMP
] = 1000; ctx
->MinMax
.Max
[BCOMP
] = -1000;
1102 ctx
->MinMax
.Min
[ACOMP
] = 1000; ctx
->MinMax
.Max
[ACOMP
] = -1000;