5f824b34294fe5cbe6d9f23c72420e584c99a118
2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 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.
28 * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer)
32 #include "bufferobj.h"
38 #include "main/dispatch.h"
41 #if FEATURE_pixel_transfer
44 /**********************************************************************/
45 /***** glPixelZoom *****/
46 /**********************************************************************/
48 static void GLAPIENTRY
49 _mesa_PixelZoom( GLfloat xfactor
, GLfloat yfactor
)
51 GET_CURRENT_CONTEXT(ctx
);
53 if (ctx
->Pixel
.ZoomX
== xfactor
&&
54 ctx
->Pixel
.ZoomY
== yfactor
)
57 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
58 ctx
->Pixel
.ZoomX
= xfactor
;
59 ctx
->Pixel
.ZoomY
= yfactor
;
64 /**********************************************************************/
65 /***** glPixelMap *****/
66 /**********************************************************************/
69 * Return pointer to a pixelmap by name.
71 static struct gl_pixelmap
*
72 get_pixelmap(struct gl_context
*ctx
, GLenum 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
;
102 * Helper routine used by the other _mesa_PixelMap() functions.
105 store_pixelmap(struct gl_context
*ctx
, GLenum map
, GLsizei mapsize
,
106 const GLfloat
*values
)
109 struct gl_pixelmap
*pm
= get_pixelmap(ctx
, map
);
111 _mesa_error(ctx
, GL_INVALID_ENUM
, "glPixelMap(map)");
116 case GL_PIXEL_MAP_S_TO_S
:
118 ctx
->PixelMaps
.StoS
.Size
= mapsize
;
119 for (i
= 0; i
< mapsize
; i
++) {
120 ctx
->PixelMaps
.StoS
.Map
[i
] = (GLfloat
)IROUND(values
[i
]);
123 case GL_PIXEL_MAP_I_TO_I
:
125 ctx
->PixelMaps
.ItoI
.Size
= mapsize
;
126 for (i
= 0; i
< mapsize
; i
++) {
127 ctx
->PixelMaps
.ItoI
.Map
[i
] = values
[i
];
133 for (i
= 0; i
< mapsize
; i
++) {
134 GLfloat val
= CLAMP(values
[i
], 0.0F
, 1.0F
);
136 pm
->Map8
[i
] = (GLint
) (val
* 255.0F
);
143 * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap().
146 validate_pbo_access(struct gl_context
*ctx
, struct gl_pixelstore_attrib
*pack
,
147 GLsizei mapsize
, GLenum format
, GLenum type
,
152 /* Note, need to use DefaultPacking and Unpack's buffer object */
153 _mesa_reference_buffer_object(ctx
,
154 &ctx
->DefaultPacking
.BufferObj
,
157 ok
= _mesa_validate_pbo_access(1, &ctx
->DefaultPacking
, mapsize
, 1, 1,
161 _mesa_reference_buffer_object(ctx
,
162 &ctx
->DefaultPacking
.BufferObj
,
163 ctx
->Shared
->NullBufferObj
);
166 _mesa_error(ctx
, GL_INVALID_OPERATION
,
167 "glPixelMap(invalid PBO access)");
173 static void GLAPIENTRY
174 _mesa_PixelMapfv( GLenum map
, GLsizei mapsize
, const GLfloat
*values
)
176 GET_CURRENT_CONTEXT(ctx
);
177 ASSERT_OUTSIDE_BEGIN_END(ctx
);
179 /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */
180 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
181 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapfv(mapsize)" );
185 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
186 /* test that mapsize is a power of two */
187 if (!_mesa_is_pow_two(mapsize
)) {
188 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapfv(mapsize)" );
193 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
195 if (!validate_pbo_access(ctx
, &ctx
->Unpack
, mapsize
,
196 GL_INTENSITY
, GL_FLOAT
, values
)) {
200 values
= (const GLfloat
*) _mesa_map_pbo_source(ctx
, &ctx
->Unpack
, values
);
202 if (_mesa_is_bufferobj(ctx
->Unpack
.BufferObj
)) {
203 _mesa_error(ctx
, GL_INVALID_OPERATION
,
204 "glPixelMapfv(PBO is mapped)");
209 store_pixelmap(ctx
, map
, mapsize
, values
);
211 _mesa_unmap_pbo_source(ctx
, &ctx
->Unpack
);
215 static void GLAPIENTRY
216 _mesa_PixelMapuiv(GLenum map
, GLsizei mapsize
, const GLuint
*values
)
218 GLfloat fvalues
[MAX_PIXEL_MAP_TABLE
];
219 GET_CURRENT_CONTEXT(ctx
);
220 ASSERT_OUTSIDE_BEGIN_END(ctx
);
222 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
223 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
227 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
228 /* test that mapsize is a power of two */
229 if (!_mesa_is_pow_two(mapsize
)) {
230 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
235 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
237 if (!validate_pbo_access(ctx
, &ctx
->Unpack
, mapsize
,
238 GL_INTENSITY
, GL_UNSIGNED_INT
, values
)) {
242 values
= (const GLuint
*) _mesa_map_pbo_source(ctx
, &ctx
->Unpack
, values
);
244 if (_mesa_is_bufferobj(ctx
->Unpack
.BufferObj
)) {
245 _mesa_error(ctx
, GL_INVALID_OPERATION
,
246 "glPixelMapuiv(PBO is mapped)");
251 /* convert to floats */
252 if (map
== GL_PIXEL_MAP_I_TO_I
|| map
== GL_PIXEL_MAP_S_TO_S
) {
254 for (i
= 0; i
< mapsize
; i
++) {
255 fvalues
[i
] = (GLfloat
) values
[i
];
260 for (i
= 0; i
< mapsize
; i
++) {
261 fvalues
[i
] = UINT_TO_FLOAT( values
[i
] );
265 _mesa_unmap_pbo_source(ctx
, &ctx
->Unpack
);
267 store_pixelmap(ctx
, map
, mapsize
, fvalues
);
271 static void GLAPIENTRY
272 _mesa_PixelMapusv(GLenum map
, GLsizei mapsize
, const GLushort
*values
)
274 GLfloat fvalues
[MAX_PIXEL_MAP_TABLE
];
275 GET_CURRENT_CONTEXT(ctx
);
276 ASSERT_OUTSIDE_BEGIN_END(ctx
);
278 if (mapsize
< 1 || mapsize
> MAX_PIXEL_MAP_TABLE
) {
279 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapusv(mapsize)" );
283 if (map
>= GL_PIXEL_MAP_S_TO_S
&& map
<= GL_PIXEL_MAP_I_TO_A
) {
284 /* test that mapsize is a power of two */
285 if (!_mesa_is_pow_two(mapsize
)) {
286 _mesa_error( ctx
, GL_INVALID_VALUE
, "glPixelMapuiv(mapsize)" );
291 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
293 if (!validate_pbo_access(ctx
, &ctx
->Unpack
, mapsize
,
294 GL_INTENSITY
, GL_UNSIGNED_SHORT
, values
)) {
298 values
= (const GLushort
*) _mesa_map_pbo_source(ctx
, &ctx
->Unpack
, values
);
300 if (_mesa_is_bufferobj(ctx
->Unpack
.BufferObj
)) {
301 _mesa_error(ctx
, GL_INVALID_OPERATION
,
302 "glPixelMapusv(PBO is mapped)");
307 /* convert to floats */
308 if (map
== GL_PIXEL_MAP_I_TO_I
|| map
== GL_PIXEL_MAP_S_TO_S
) {
310 for (i
= 0; i
< mapsize
; i
++) {
311 fvalues
[i
] = (GLfloat
) values
[i
];
316 for (i
= 0; i
< mapsize
; i
++) {
317 fvalues
[i
] = USHORT_TO_FLOAT( values
[i
] );
321 _mesa_unmap_pbo_source(ctx
, &ctx
->Unpack
);
323 store_pixelmap(ctx
, map
, mapsize
, fvalues
);
327 static void GLAPIENTRY
328 _mesa_GetPixelMapfv( GLenum map
, GLfloat
*values
)
330 GET_CURRENT_CONTEXT(ctx
);
332 const struct gl_pixelmap
*pm
;
334 ASSERT_OUTSIDE_BEGIN_END(ctx
);
336 pm
= get_pixelmap(ctx
, map
);
338 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapfv(map)");
344 if (!validate_pbo_access(ctx
, &ctx
->Pack
, mapsize
,
345 GL_INTENSITY
, GL_FLOAT
, values
)) {
349 values
= (GLfloat
*) _mesa_map_pbo_dest(ctx
, &ctx
->Pack
, values
);
351 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
352 _mesa_error(ctx
, GL_INVALID_OPERATION
,
353 "glGetPixelMapfv(PBO is mapped)");
358 if (map
== GL_PIXEL_MAP_S_TO_S
) {
360 for (i
= 0; i
< mapsize
; i
++) {
361 values
[i
] = (GLfloat
) ctx
->PixelMaps
.StoS
.Map
[i
];
365 memcpy(values
, pm
->Map
, mapsize
* sizeof(GLfloat
));
368 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
372 static void GLAPIENTRY
373 _mesa_GetPixelMapuiv( GLenum map
, GLuint
*values
)
375 GET_CURRENT_CONTEXT(ctx
);
377 const struct gl_pixelmap
*pm
;
379 ASSERT_OUTSIDE_BEGIN_END(ctx
);
381 pm
= get_pixelmap(ctx
, map
);
383 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapuiv(map)");
388 if (!validate_pbo_access(ctx
, &ctx
->Pack
, mapsize
,
389 GL_INTENSITY
, GL_UNSIGNED_INT
, values
)) {
393 values
= (GLuint
*) _mesa_map_pbo_dest(ctx
, &ctx
->Pack
, values
);
395 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
396 _mesa_error(ctx
, GL_INVALID_OPERATION
,
397 "glGetPixelMapuiv(PBO is mapped)");
402 if (map
== GL_PIXEL_MAP_S_TO_S
) {
404 memcpy(values
, ctx
->PixelMaps
.StoS
.Map
, mapsize
* sizeof(GLint
));
407 for (i
= 0; i
< mapsize
; i
++) {
408 values
[i
] = FLOAT_TO_UINT( pm
->Map
[i
] );
412 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
416 static void GLAPIENTRY
417 _mesa_GetPixelMapusv( GLenum map
, GLushort
*values
)
419 GET_CURRENT_CONTEXT(ctx
);
421 const struct gl_pixelmap
*pm
;
423 ASSERT_OUTSIDE_BEGIN_END(ctx
);
425 pm
= get_pixelmap(ctx
, map
);
427 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetPixelMapusv(map)");
432 if (!validate_pbo_access(ctx
, &ctx
->Pack
, mapsize
,
433 GL_INTENSITY
, GL_UNSIGNED_SHORT
, values
)) {
437 values
= (GLushort
*) _mesa_map_pbo_dest(ctx
, &ctx
->Pack
, values
);
439 if (_mesa_is_bufferobj(ctx
->Pack
.BufferObj
)) {
440 _mesa_error(ctx
, GL_INVALID_OPERATION
,
441 "glGetPixelMapusv(PBO is mapped)");
448 case GL_PIXEL_MAP_I_TO_I
:
449 for (i
= 0; i
< mapsize
; i
++) {
450 values
[i
] = (GLushort
) CLAMP(ctx
->PixelMaps
.ItoI
.Map
[i
], 0.0, 65535.);
453 case GL_PIXEL_MAP_S_TO_S
:
454 for (i
= 0; i
< mapsize
; i
++) {
455 values
[i
] = (GLushort
) CLAMP(ctx
->PixelMaps
.StoS
.Map
[i
], 0.0, 65535.);
459 for (i
= 0; i
< mapsize
; i
++) {
460 CLAMPED_FLOAT_TO_USHORT(values
[i
], pm
->Map
[i
] );
464 _mesa_unmap_pbo_dest(ctx
, &ctx
->Pack
);
469 /**********************************************************************/
470 /***** glPixelTransfer *****/
471 /**********************************************************************/
475 * Implements glPixelTransfer[fi] whether called immediately or from a
478 static void GLAPIENTRY
479 _mesa_PixelTransferf( GLenum pname
, GLfloat param
)
481 GET_CURRENT_CONTEXT(ctx
);
482 ASSERT_OUTSIDE_BEGIN_END(ctx
);
486 if (ctx
->Pixel
.MapColorFlag
== (param
? GL_TRUE
: GL_FALSE
))
488 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
489 ctx
->Pixel
.MapColorFlag
= param
? GL_TRUE
: GL_FALSE
;
492 if (ctx
->Pixel
.MapStencilFlag
== (param
? GL_TRUE
: GL_FALSE
))
494 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
495 ctx
->Pixel
.MapStencilFlag
= param
? GL_TRUE
: GL_FALSE
;
498 if (ctx
->Pixel
.IndexShift
== (GLint
) param
)
500 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
501 ctx
->Pixel
.IndexShift
= (GLint
) param
;
503 case GL_INDEX_OFFSET
:
504 if (ctx
->Pixel
.IndexOffset
== (GLint
) param
)
506 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
507 ctx
->Pixel
.IndexOffset
= (GLint
) param
;
510 if (ctx
->Pixel
.RedScale
== param
)
512 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
513 ctx
->Pixel
.RedScale
= param
;
516 if (ctx
->Pixel
.RedBias
== param
)
518 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
519 ctx
->Pixel
.RedBias
= param
;
522 if (ctx
->Pixel
.GreenScale
== param
)
524 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
525 ctx
->Pixel
.GreenScale
= param
;
528 if (ctx
->Pixel
.GreenBias
== param
)
530 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
531 ctx
->Pixel
.GreenBias
= param
;
534 if (ctx
->Pixel
.BlueScale
== param
)
536 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
537 ctx
->Pixel
.BlueScale
= param
;
540 if (ctx
->Pixel
.BlueBias
== param
)
542 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
543 ctx
->Pixel
.BlueBias
= param
;
546 if (ctx
->Pixel
.AlphaScale
== param
)
548 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
549 ctx
->Pixel
.AlphaScale
= param
;
552 if (ctx
->Pixel
.AlphaBias
== param
)
554 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
555 ctx
->Pixel
.AlphaBias
= param
;
558 if (ctx
->Pixel
.DepthScale
== param
)
560 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
561 ctx
->Pixel
.DepthScale
= param
;
564 if (ctx
->Pixel
.DepthBias
== param
)
566 FLUSH_VERTICES(ctx
, _NEW_PIXEL
);
567 ctx
->Pixel
.DepthBias
= param
;
570 _mesa_error( ctx
, GL_INVALID_ENUM
, "glPixelTransfer(pname)" );
576 static void GLAPIENTRY
577 _mesa_PixelTransferi( GLenum pname
, GLint param
)
579 _mesa_PixelTransferf( pname
, (GLfloat
) param
);
584 /**********************************************************************/
585 /***** State Management *****/
586 /**********************************************************************/
589 * Return a bitmask of IMAGE_*_BIT flags which to indicate which
590 * pixel transfer operations are enabled.
593 update_image_transfer_state(struct gl_context
*ctx
)
597 if (ctx
->Pixel
.RedScale
!= 1.0F
|| ctx
->Pixel
.RedBias
!= 0.0F
||
598 ctx
->Pixel
.GreenScale
!= 1.0F
|| ctx
->Pixel
.GreenBias
!= 0.0F
||
599 ctx
->Pixel
.BlueScale
!= 1.0F
|| ctx
->Pixel
.BlueBias
!= 0.0F
||
600 ctx
->Pixel
.AlphaScale
!= 1.0F
|| ctx
->Pixel
.AlphaBias
!= 0.0F
)
601 mask
|= IMAGE_SCALE_BIAS_BIT
;
603 if (ctx
->Pixel
.IndexShift
|| ctx
->Pixel
.IndexOffset
)
604 mask
|= IMAGE_SHIFT_OFFSET_BIT
;
606 if (ctx
->Pixel
.MapColorFlag
)
607 mask
|= IMAGE_MAP_COLOR_BIT
;
609 ctx
->_ImageTransferState
= mask
;
614 * Update mesa pixel transfer derived state.
616 void _mesa_update_pixel( struct gl_context
*ctx
, GLuint new_state
)
618 if (new_state
& _MESA_NEW_TRANSFER_STATE
)
619 update_image_transfer_state(ctx
);
624 _mesa_init_pixel_dispatch(struct _glapi_table
*disp
)
626 SET_GetPixelMapfv(disp
, _mesa_GetPixelMapfv
);
627 SET_GetPixelMapuiv(disp
, _mesa_GetPixelMapuiv
);
628 SET_GetPixelMapusv(disp
, _mesa_GetPixelMapusv
);
629 SET_PixelMapfv(disp
, _mesa_PixelMapfv
);
630 SET_PixelMapuiv(disp
, _mesa_PixelMapuiv
);
631 SET_PixelMapusv(disp
, _mesa_PixelMapusv
);
632 SET_PixelTransferf(disp
, _mesa_PixelTransferf
);
633 SET_PixelTransferi(disp
, _mesa_PixelTransferi
);
634 SET_PixelZoom(disp
, _mesa_PixelZoom
);
638 #endif /* FEATURE_pixel_transfer */
641 /**********************************************************************/
642 /***** Initialization *****/
643 /**********************************************************************/
646 init_pixelmap(struct gl_pixelmap
*map
)
655 * Initialize the context's PIXEL attribute group.
658 _mesa_init_pixel( struct gl_context
*ctx
)
661 ctx
->Pixel
.RedBias
= 0.0;
662 ctx
->Pixel
.RedScale
= 1.0;
663 ctx
->Pixel
.GreenBias
= 0.0;
664 ctx
->Pixel
.GreenScale
= 1.0;
665 ctx
->Pixel
.BlueBias
= 0.0;
666 ctx
->Pixel
.BlueScale
= 1.0;
667 ctx
->Pixel
.AlphaBias
= 0.0;
668 ctx
->Pixel
.AlphaScale
= 1.0;
669 ctx
->Pixel
.DepthBias
= 0.0;
670 ctx
->Pixel
.DepthScale
= 1.0;
671 ctx
->Pixel
.IndexOffset
= 0;
672 ctx
->Pixel
.IndexShift
= 0;
673 ctx
->Pixel
.ZoomX
= 1.0;
674 ctx
->Pixel
.ZoomY
= 1.0;
675 ctx
->Pixel
.MapColorFlag
= GL_FALSE
;
676 ctx
->Pixel
.MapStencilFlag
= GL_FALSE
;
677 init_pixelmap(&ctx
->PixelMaps
.StoS
);
678 init_pixelmap(&ctx
->PixelMaps
.ItoI
);
679 init_pixelmap(&ctx
->PixelMaps
.ItoR
);
680 init_pixelmap(&ctx
->PixelMaps
.ItoG
);
681 init_pixelmap(&ctx
->PixelMaps
.ItoB
);
682 init_pixelmap(&ctx
->PixelMaps
.ItoA
);
683 init_pixelmap(&ctx
->PixelMaps
.RtoR
);
684 init_pixelmap(&ctx
->PixelMaps
.GtoG
);
685 init_pixelmap(&ctx
->PixelMaps
.BtoB
);
686 init_pixelmap(&ctx
->PixelMaps
.AtoA
);
687 /* GL_SGI_texture_color_table */
688 ASSIGN_4V(ctx
->Pixel
.TextureColorTableScale
, 1.0, 1.0, 1.0, 1.0);
689 ASSIGN_4V(ctx
->Pixel
.TextureColorTableBias
, 0.0, 0.0, 0.0, 0.0);
691 if (ctx
->Visual
.doubleBufferMode
) {
692 ctx
->Pixel
.ReadBuffer
= GL_BACK
;
695 ctx
->Pixel
.ReadBuffer
= GL_FRONT
;
699 ctx
->_ImageTransferState
= 0;