pixel.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file pixel.c 28848b8605Smrg * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer) 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg#include "glheader.h" 32848b8605Smrg#include "bufferobj.h" 33848b8605Smrg#include "colormac.h" 34848b8605Smrg#include "context.h" 35848b8605Smrg#include "macros.h" 36848b8605Smrg#include "pixel.h" 37848b8605Smrg#include "pbo.h" 38848b8605Smrg#include "mtypes.h" 39848b8605Smrg#include "main/dispatch.h" 40848b8605Smrg 41848b8605Smrg 42848b8605Smrg/**********************************************************************/ 43848b8605Smrg/***** glPixelZoom *****/ 44848b8605Smrg/**********************************************************************/ 45848b8605Smrg 46848b8605Smrgvoid GLAPIENTRY 47848b8605Smrg_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ) 48848b8605Smrg{ 49848b8605Smrg GET_CURRENT_CONTEXT(ctx); 50848b8605Smrg 51848b8605Smrg if (ctx->Pixel.ZoomX == xfactor && 52848b8605Smrg ctx->Pixel.ZoomY == yfactor) 53848b8605Smrg return; 54848b8605Smrg 55848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 56848b8605Smrg ctx->Pixel.ZoomX = xfactor; 57848b8605Smrg ctx->Pixel.ZoomY = yfactor; 58848b8605Smrg} 59848b8605Smrg 60848b8605Smrg 61848b8605Smrg 62848b8605Smrg/**********************************************************************/ 63848b8605Smrg/***** glPixelMap *****/ 64848b8605Smrg/**********************************************************************/ 65848b8605Smrg 66848b8605Smrg/** 67848b8605Smrg * Return pointer to a pixelmap by name. 68848b8605Smrg */ 69848b8605Smrgstatic struct gl_pixelmap * 70848b8605Smrgget_pixelmap(struct gl_context *ctx, GLenum map) 71848b8605Smrg{ 72848b8605Smrg switch (map) { 73848b8605Smrg case GL_PIXEL_MAP_I_TO_I: 74848b8605Smrg return &ctx->PixelMaps.ItoI; 75848b8605Smrg case GL_PIXEL_MAP_S_TO_S: 76848b8605Smrg return &ctx->PixelMaps.StoS; 77848b8605Smrg case GL_PIXEL_MAP_I_TO_R: 78848b8605Smrg return &ctx->PixelMaps.ItoR; 79848b8605Smrg case GL_PIXEL_MAP_I_TO_G: 80848b8605Smrg return &ctx->PixelMaps.ItoG; 81848b8605Smrg case GL_PIXEL_MAP_I_TO_B: 82848b8605Smrg return &ctx->PixelMaps.ItoB; 83848b8605Smrg case GL_PIXEL_MAP_I_TO_A: 84848b8605Smrg return &ctx->PixelMaps.ItoA; 85848b8605Smrg case GL_PIXEL_MAP_R_TO_R: 86848b8605Smrg return &ctx->PixelMaps.RtoR; 87848b8605Smrg case GL_PIXEL_MAP_G_TO_G: 88848b8605Smrg return &ctx->PixelMaps.GtoG; 89848b8605Smrg case GL_PIXEL_MAP_B_TO_B: 90848b8605Smrg return &ctx->PixelMaps.BtoB; 91848b8605Smrg case GL_PIXEL_MAP_A_TO_A: 92848b8605Smrg return &ctx->PixelMaps.AtoA; 93848b8605Smrg default: 94848b8605Smrg return NULL; 95848b8605Smrg } 96848b8605Smrg} 97848b8605Smrg 98848b8605Smrg 99848b8605Smrg/** 100848b8605Smrg * Helper routine used by the other _mesa_PixelMap() functions. 101848b8605Smrg */ 102848b8605Smrgstatic void 103848b8605Smrgstore_pixelmap(struct gl_context *ctx, GLenum map, GLsizei mapsize, 104848b8605Smrg const GLfloat *values) 105848b8605Smrg{ 106848b8605Smrg GLint i; 107848b8605Smrg struct gl_pixelmap *pm = get_pixelmap(ctx, map); 108848b8605Smrg if (!pm) { 109848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)"); 110848b8605Smrg return; 111848b8605Smrg } 112848b8605Smrg 113848b8605Smrg switch (map) { 114848b8605Smrg case GL_PIXEL_MAP_S_TO_S: 115848b8605Smrg /* special case */ 116848b8605Smrg ctx->PixelMaps.StoS.Size = mapsize; 117848b8605Smrg for (i = 0; i < mapsize; i++) { 118848b8605Smrg ctx->PixelMaps.StoS.Map[i] = (GLfloat)IROUND(values[i]); 119848b8605Smrg } 120848b8605Smrg break; 121848b8605Smrg case GL_PIXEL_MAP_I_TO_I: 122848b8605Smrg /* special case */ 123848b8605Smrg ctx->PixelMaps.ItoI.Size = mapsize; 124848b8605Smrg for (i = 0; i < mapsize; i++) { 125848b8605Smrg ctx->PixelMaps.ItoI.Map[i] = values[i]; 126848b8605Smrg } 127848b8605Smrg break; 128848b8605Smrg default: 129848b8605Smrg /* general case */ 130848b8605Smrg pm->Size = mapsize; 131848b8605Smrg for (i = 0; i < mapsize; i++) { 132848b8605Smrg GLfloat val = CLAMP(values[i], 0.0F, 1.0F); 133848b8605Smrg pm->Map[i] = val; 134848b8605Smrg } 135848b8605Smrg } 136848b8605Smrg} 137848b8605Smrg 138848b8605Smrg 139848b8605Smrg/** 140848b8605Smrg * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap(). 141848b8605Smrg */ 142848b8605Smrgstatic GLboolean 143848b8605Smrgvalidate_pbo_access(struct gl_context *ctx, 144848b8605Smrg struct gl_pixelstore_attrib *pack, GLsizei mapsize, 145848b8605Smrg GLenum format, GLenum type, GLsizei clientMemSize, 146848b8605Smrg const GLvoid *ptr) 147848b8605Smrg{ 148848b8605Smrg GLboolean ok; 149848b8605Smrg 150848b8605Smrg /* Note, need to use DefaultPacking and Unpack's buffer object */ 151848b8605Smrg _mesa_reference_buffer_object(ctx, 152848b8605Smrg &ctx->DefaultPacking.BufferObj, 153848b8605Smrg pack->BufferObj); 154848b8605Smrg 155848b8605Smrg ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 156848b8605Smrg format, type, clientMemSize, ptr); 157848b8605Smrg 158848b8605Smrg /* restore */ 159848b8605Smrg _mesa_reference_buffer_object(ctx, 160848b8605Smrg &ctx->DefaultPacking.BufferObj, 161848b8605Smrg ctx->Shared->NullBufferObj); 162848b8605Smrg 163848b8605Smrg if (!ok) { 164848b8605Smrg if (_mesa_is_bufferobj(pack->BufferObj)) { 165848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 166848b8605Smrg "gl[Get]PixelMap*v(out of bounds PBO access)"); 167848b8605Smrg } else { 168848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 169848b8605Smrg "glGetnPixelMap*vARB(out of bounds access:" 170848b8605Smrg " bufSize (%d) is too small)", clientMemSize); 171848b8605Smrg } 172848b8605Smrg } 173848b8605Smrg return ok; 174848b8605Smrg} 175848b8605Smrg 176848b8605Smrg 177848b8605Smrgvoid GLAPIENTRY 178848b8605Smrg_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) 179848b8605Smrg{ 180848b8605Smrg GET_CURRENT_CONTEXT(ctx); 181848b8605Smrg 182848b8605Smrg /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */ 183848b8605Smrg if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 184848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 185848b8605Smrg return; 186848b8605Smrg } 187848b8605Smrg 188848b8605Smrg if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 189848b8605Smrg /* test that mapsize is a power of two */ 190848b8605Smrg if (!_mesa_is_pow_two(mapsize)) { 191848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 192848b8605Smrg return; 193848b8605Smrg } 194848b8605Smrg } 195848b8605Smrg 196848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 197848b8605Smrg 198848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 199848b8605Smrg GL_FLOAT, INT_MAX, values)) { 200848b8605Smrg return; 201848b8605Smrg } 202848b8605Smrg 203848b8605Smrg values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 204848b8605Smrg if (!values) { 205848b8605Smrg if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 206848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 207848b8605Smrg "glPixelMapfv(PBO is mapped)"); 208848b8605Smrg } 209848b8605Smrg return; 210848b8605Smrg } 211848b8605Smrg 212848b8605Smrg store_pixelmap(ctx, map, mapsize, values); 213848b8605Smrg 214848b8605Smrg _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 215848b8605Smrg} 216848b8605Smrg 217848b8605Smrg 218848b8605Smrgvoid GLAPIENTRY 219848b8605Smrg_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) 220848b8605Smrg{ 221848b8605Smrg GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 222848b8605Smrg GET_CURRENT_CONTEXT(ctx); 223848b8605Smrg 224848b8605Smrg if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 225848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 226848b8605Smrg return; 227848b8605Smrg } 228848b8605Smrg 229848b8605Smrg if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 230848b8605Smrg /* test that mapsize is a power of two */ 231848b8605Smrg if (!_mesa_is_pow_two(mapsize)) { 232848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 233848b8605Smrg return; 234848b8605Smrg } 235848b8605Smrg } 236848b8605Smrg 237848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 238848b8605Smrg 239848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 240848b8605Smrg GL_UNSIGNED_INT, INT_MAX, values)) { 241848b8605Smrg return; 242848b8605Smrg } 243848b8605Smrg 244848b8605Smrg values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 245848b8605Smrg if (!values) { 246848b8605Smrg if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 247848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 248848b8605Smrg "glPixelMapuiv(PBO is mapped)"); 249848b8605Smrg } 250848b8605Smrg return; 251848b8605Smrg } 252848b8605Smrg 253848b8605Smrg /* convert to floats */ 254848b8605Smrg if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 255848b8605Smrg GLint i; 256848b8605Smrg for (i = 0; i < mapsize; i++) { 257848b8605Smrg fvalues[i] = (GLfloat) values[i]; 258848b8605Smrg } 259848b8605Smrg } 260848b8605Smrg else { 261848b8605Smrg GLint i; 262848b8605Smrg for (i = 0; i < mapsize; i++) { 263848b8605Smrg fvalues[i] = UINT_TO_FLOAT( values[i] ); 264848b8605Smrg } 265848b8605Smrg } 266848b8605Smrg 267848b8605Smrg _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 268848b8605Smrg 269848b8605Smrg store_pixelmap(ctx, map, mapsize, fvalues); 270848b8605Smrg} 271848b8605Smrg 272848b8605Smrg 273848b8605Smrgvoid GLAPIENTRY 274848b8605Smrg_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) 275848b8605Smrg{ 276848b8605Smrg GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 277848b8605Smrg GET_CURRENT_CONTEXT(ctx); 278848b8605Smrg 279848b8605Smrg if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 280848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 281848b8605Smrg return; 282848b8605Smrg } 283848b8605Smrg 284848b8605Smrg if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 285848b8605Smrg /* test that mapsize is a power of two */ 286848b8605Smrg if (!_mesa_is_pow_two(mapsize)) { 287848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 288848b8605Smrg return; 289848b8605Smrg } 290848b8605Smrg } 291848b8605Smrg 292848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 293848b8605Smrg 294848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 295848b8605Smrg GL_UNSIGNED_SHORT, INT_MAX, values)) { 296848b8605Smrg return; 297848b8605Smrg } 298848b8605Smrg 299848b8605Smrg values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 300848b8605Smrg if (!values) { 301848b8605Smrg if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { 302848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 303848b8605Smrg "glPixelMapusv(PBO is mapped)"); 304848b8605Smrg } 305848b8605Smrg return; 306848b8605Smrg } 307848b8605Smrg 308848b8605Smrg /* convert to floats */ 309848b8605Smrg if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 310848b8605Smrg GLint i; 311848b8605Smrg for (i = 0; i < mapsize; i++) { 312848b8605Smrg fvalues[i] = (GLfloat) values[i]; 313848b8605Smrg } 314848b8605Smrg } 315848b8605Smrg else { 316848b8605Smrg GLint i; 317848b8605Smrg for (i = 0; i < mapsize; i++) { 318848b8605Smrg fvalues[i] = USHORT_TO_FLOAT( values[i] ); 319848b8605Smrg } 320848b8605Smrg } 321848b8605Smrg 322848b8605Smrg _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 323848b8605Smrg 324848b8605Smrg store_pixelmap(ctx, map, mapsize, fvalues); 325848b8605Smrg} 326848b8605Smrg 327848b8605Smrg 328848b8605Smrgvoid GLAPIENTRY 329848b8605Smrg_mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values ) 330848b8605Smrg{ 331848b8605Smrg GET_CURRENT_CONTEXT(ctx); 332848b8605Smrg GLint mapsize, i; 333848b8605Smrg const struct gl_pixelmap *pm; 334848b8605Smrg 335848b8605Smrg pm = get_pixelmap(ctx, map); 336848b8605Smrg if (!pm) { 337848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)"); 338848b8605Smrg return; 339848b8605Smrg } 340848b8605Smrg 341848b8605Smrg mapsize = pm->Size; 342848b8605Smrg 343848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 344848b8605Smrg GL_FLOAT, bufSize, values)) { 345848b8605Smrg return; 346848b8605Smrg } 347848b8605Smrg 348848b8605Smrg values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 349848b8605Smrg if (!values) { 350848b8605Smrg if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 351848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 352848b8605Smrg "glGetPixelMapfv(PBO is mapped)"); 353848b8605Smrg } 354848b8605Smrg return; 355848b8605Smrg } 356848b8605Smrg 357848b8605Smrg if (map == GL_PIXEL_MAP_S_TO_S) { 358848b8605Smrg /* special case */ 359848b8605Smrg for (i = 0; i < mapsize; i++) { 360848b8605Smrg values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i]; 361848b8605Smrg } 362848b8605Smrg } 363848b8605Smrg else { 364848b8605Smrg memcpy(values, pm->Map, mapsize * sizeof(GLfloat)); 365848b8605Smrg } 366848b8605Smrg 367848b8605Smrg _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 368848b8605Smrg} 369848b8605Smrg 370848b8605Smrg 371848b8605Smrgvoid GLAPIENTRY 372848b8605Smrg_mesa_GetPixelMapfv( GLenum map, GLfloat *values ) 373848b8605Smrg{ 374848b8605Smrg _mesa_GetnPixelMapfvARB(map, INT_MAX, values); 375848b8605Smrg} 376848b8605Smrg 377848b8605Smrgvoid GLAPIENTRY 378848b8605Smrg_mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values ) 379848b8605Smrg{ 380848b8605Smrg GET_CURRENT_CONTEXT(ctx); 381848b8605Smrg GLint mapsize, i; 382848b8605Smrg const struct gl_pixelmap *pm; 383848b8605Smrg 384848b8605Smrg pm = get_pixelmap(ctx, map); 385848b8605Smrg if (!pm) { 386848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)"); 387848b8605Smrg return; 388848b8605Smrg } 389848b8605Smrg 390848b8605Smrg mapsize = pm->Size; 391848b8605Smrg 392848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 393848b8605Smrg GL_UNSIGNED_INT, bufSize, values)) { 394848b8605Smrg return; 395848b8605Smrg } 396848b8605Smrg 397848b8605Smrg values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 398848b8605Smrg if (!values) { 399848b8605Smrg if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 400848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 401848b8605Smrg "glGetPixelMapuiv(PBO is mapped)"); 402848b8605Smrg } 403848b8605Smrg return; 404848b8605Smrg } 405848b8605Smrg 406848b8605Smrg if (map == GL_PIXEL_MAP_S_TO_S) { 407848b8605Smrg /* special case */ 408848b8605Smrg memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint)); 409848b8605Smrg } 410848b8605Smrg else { 411848b8605Smrg for (i = 0; i < mapsize; i++) { 412848b8605Smrg values[i] = FLOAT_TO_UINT( pm->Map[i] ); 413848b8605Smrg } 414848b8605Smrg } 415848b8605Smrg 416848b8605Smrg _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 417848b8605Smrg} 418848b8605Smrg 419848b8605Smrg 420848b8605Smrgvoid GLAPIENTRY 421848b8605Smrg_mesa_GetPixelMapuiv( GLenum map, GLuint *values ) 422848b8605Smrg{ 423848b8605Smrg _mesa_GetnPixelMapuivARB(map, INT_MAX, values); 424848b8605Smrg} 425848b8605Smrg 426848b8605Smrgvoid GLAPIENTRY 427848b8605Smrg_mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values ) 428848b8605Smrg{ 429848b8605Smrg GET_CURRENT_CONTEXT(ctx); 430848b8605Smrg GLint mapsize, i; 431848b8605Smrg const struct gl_pixelmap *pm; 432848b8605Smrg 433848b8605Smrg pm = get_pixelmap(ctx, map); 434848b8605Smrg if (!pm) { 435848b8605Smrg _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)"); 436848b8605Smrg return; 437848b8605Smrg } 438848b8605Smrg 439848b8605Smrg mapsize = pm->Size; 440848b8605Smrg 441848b8605Smrg if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 442848b8605Smrg GL_UNSIGNED_SHORT, bufSize, values)) { 443848b8605Smrg return; 444848b8605Smrg } 445848b8605Smrg 446848b8605Smrg values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 447848b8605Smrg if (!values) { 448848b8605Smrg if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { 449848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 450848b8605Smrg "glGetPixelMapusv(PBO is mapped)"); 451848b8605Smrg } 452848b8605Smrg return; 453848b8605Smrg } 454848b8605Smrg 455848b8605Smrg switch (map) { 456848b8605Smrg /* special cases */ 457848b8605Smrg case GL_PIXEL_MAP_I_TO_I: 458848b8605Smrg for (i = 0; i < mapsize; i++) { 459848b8605Smrg values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0, 65535.); 460848b8605Smrg } 461848b8605Smrg break; 462848b8605Smrg case GL_PIXEL_MAP_S_TO_S: 463848b8605Smrg for (i = 0; i < mapsize; i++) { 464848b8605Smrg values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0, 65535.); 465848b8605Smrg } 466848b8605Smrg break; 467848b8605Smrg default: 468848b8605Smrg for (i = 0; i < mapsize; i++) { 469848b8605Smrg CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] ); 470848b8605Smrg } 471848b8605Smrg } 472848b8605Smrg 473848b8605Smrg _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 474848b8605Smrg} 475848b8605Smrg 476848b8605Smrg 477848b8605Smrgvoid GLAPIENTRY 478848b8605Smrg_mesa_GetPixelMapusv( GLenum map, GLushort *values ) 479848b8605Smrg{ 480848b8605Smrg _mesa_GetnPixelMapusvARB(map, INT_MAX, values); 481848b8605Smrg} 482848b8605Smrg 483848b8605Smrg 484848b8605Smrg/**********************************************************************/ 485848b8605Smrg/***** glPixelTransfer *****/ 486848b8605Smrg/**********************************************************************/ 487848b8605Smrg 488848b8605Smrg 489848b8605Smrg/* 490848b8605Smrg * Implements glPixelTransfer[fi] whether called immediately or from a 491848b8605Smrg * display list. 492848b8605Smrg */ 493848b8605Smrgvoid GLAPIENTRY 494848b8605Smrg_mesa_PixelTransferf( GLenum pname, GLfloat param ) 495848b8605Smrg{ 496848b8605Smrg GET_CURRENT_CONTEXT(ctx); 497848b8605Smrg 498848b8605Smrg switch (pname) { 499848b8605Smrg case GL_MAP_COLOR: 500848b8605Smrg if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE)) 501848b8605Smrg return; 502848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 503848b8605Smrg ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE; 504848b8605Smrg break; 505848b8605Smrg case GL_MAP_STENCIL: 506848b8605Smrg if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE)) 507848b8605Smrg return; 508848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 509848b8605Smrg ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE; 510848b8605Smrg break; 511848b8605Smrg case GL_INDEX_SHIFT: 512848b8605Smrg if (ctx->Pixel.IndexShift == (GLint) param) 513848b8605Smrg return; 514848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 515848b8605Smrg ctx->Pixel.IndexShift = (GLint) param; 516848b8605Smrg break; 517848b8605Smrg case GL_INDEX_OFFSET: 518848b8605Smrg if (ctx->Pixel.IndexOffset == (GLint) param) 519848b8605Smrg return; 520848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 521848b8605Smrg ctx->Pixel.IndexOffset = (GLint) param; 522848b8605Smrg break; 523848b8605Smrg case GL_RED_SCALE: 524848b8605Smrg if (ctx->Pixel.RedScale == param) 525848b8605Smrg return; 526848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 527848b8605Smrg ctx->Pixel.RedScale = param; 528848b8605Smrg break; 529848b8605Smrg case GL_RED_BIAS: 530848b8605Smrg if (ctx->Pixel.RedBias == param) 531848b8605Smrg return; 532848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 533848b8605Smrg ctx->Pixel.RedBias = param; 534848b8605Smrg break; 535848b8605Smrg case GL_GREEN_SCALE: 536848b8605Smrg if (ctx->Pixel.GreenScale == param) 537848b8605Smrg return; 538848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 539848b8605Smrg ctx->Pixel.GreenScale = param; 540848b8605Smrg break; 541848b8605Smrg case GL_GREEN_BIAS: 542848b8605Smrg if (ctx->Pixel.GreenBias == param) 543848b8605Smrg return; 544848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 545848b8605Smrg ctx->Pixel.GreenBias = param; 546848b8605Smrg break; 547848b8605Smrg case GL_BLUE_SCALE: 548848b8605Smrg if (ctx->Pixel.BlueScale == param) 549848b8605Smrg return; 550848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 551848b8605Smrg ctx->Pixel.BlueScale = param; 552848b8605Smrg break; 553848b8605Smrg case GL_BLUE_BIAS: 554848b8605Smrg if (ctx->Pixel.BlueBias == param) 555848b8605Smrg return; 556848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 557848b8605Smrg ctx->Pixel.BlueBias = param; 558848b8605Smrg break; 559848b8605Smrg case GL_ALPHA_SCALE: 560848b8605Smrg if (ctx->Pixel.AlphaScale == param) 561848b8605Smrg return; 562848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 563848b8605Smrg ctx->Pixel.AlphaScale = param; 564848b8605Smrg break; 565848b8605Smrg case GL_ALPHA_BIAS: 566848b8605Smrg if (ctx->Pixel.AlphaBias == param) 567848b8605Smrg return; 568848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 569848b8605Smrg ctx->Pixel.AlphaBias = param; 570848b8605Smrg break; 571848b8605Smrg case GL_DEPTH_SCALE: 572848b8605Smrg if (ctx->Pixel.DepthScale == param) 573848b8605Smrg return; 574848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 575848b8605Smrg ctx->Pixel.DepthScale = param; 576848b8605Smrg break; 577848b8605Smrg case GL_DEPTH_BIAS: 578848b8605Smrg if (ctx->Pixel.DepthBias == param) 579848b8605Smrg return; 580848b8605Smrg FLUSH_VERTICES(ctx, _NEW_PIXEL); 581848b8605Smrg ctx->Pixel.DepthBias = param; 582848b8605Smrg break; 583848b8605Smrg default: 584848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); 585848b8605Smrg return; 586848b8605Smrg } 587848b8605Smrg} 588848b8605Smrg 589848b8605Smrg 590848b8605Smrgvoid GLAPIENTRY 591848b8605Smrg_mesa_PixelTransferi( GLenum pname, GLint param ) 592848b8605Smrg{ 593848b8605Smrg _mesa_PixelTransferf( pname, (GLfloat) param ); 594848b8605Smrg} 595848b8605Smrg 596848b8605Smrg 597848b8605Smrg 598848b8605Smrg/**********************************************************************/ 599848b8605Smrg/***** State Management *****/ 600848b8605Smrg/**********************************************************************/ 601848b8605Smrg 602848b8605Smrg/* 603848b8605Smrg * Return a bitmask of IMAGE_*_BIT flags which to indicate which 604848b8605Smrg * pixel transfer operations are enabled. 605848b8605Smrg */ 606848b8605Smrgstatic void 607848b8605Smrgupdate_image_transfer_state(struct gl_context *ctx) 608848b8605Smrg{ 609848b8605Smrg GLuint mask = 0; 610848b8605Smrg 611848b8605Smrg if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F || 612848b8605Smrg ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F || 613848b8605Smrg ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F || 614848b8605Smrg ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F) 615848b8605Smrg mask |= IMAGE_SCALE_BIAS_BIT; 616848b8605Smrg 617848b8605Smrg if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) 618848b8605Smrg mask |= IMAGE_SHIFT_OFFSET_BIT; 619848b8605Smrg 620848b8605Smrg if (ctx->Pixel.MapColorFlag) 621848b8605Smrg mask |= IMAGE_MAP_COLOR_BIT; 622848b8605Smrg 623848b8605Smrg ctx->_ImageTransferState = mask; 624848b8605Smrg} 625848b8605Smrg 626848b8605Smrg 627848b8605Smrg/** 628848b8605Smrg * Update mesa pixel transfer derived state. 629848b8605Smrg */ 630848b8605Smrgvoid _mesa_update_pixel( struct gl_context *ctx, GLuint new_state ) 631848b8605Smrg{ 632848b8605Smrg if (new_state & _NEW_PIXEL) 633848b8605Smrg update_image_transfer_state(ctx); 634848b8605Smrg} 635848b8605Smrg 636848b8605Smrg 637848b8605Smrg/**********************************************************************/ 638848b8605Smrg/***** Initialization *****/ 639848b8605Smrg/**********************************************************************/ 640848b8605Smrg 641848b8605Smrgstatic void 642848b8605Smrginit_pixelmap(struct gl_pixelmap *map) 643848b8605Smrg{ 644848b8605Smrg map->Size = 1; 645848b8605Smrg map->Map[0] = 0.0; 646848b8605Smrg} 647848b8605Smrg 648848b8605Smrg 649848b8605Smrg/** 650848b8605Smrg * Initialize the context's PIXEL attribute group. 651848b8605Smrg */ 652848b8605Smrgvoid 653848b8605Smrg_mesa_init_pixel( struct gl_context *ctx ) 654848b8605Smrg{ 655848b8605Smrg /* Pixel group */ 656848b8605Smrg ctx->Pixel.RedBias = 0.0; 657848b8605Smrg ctx->Pixel.RedScale = 1.0; 658848b8605Smrg ctx->Pixel.GreenBias = 0.0; 659848b8605Smrg ctx->Pixel.GreenScale = 1.0; 660848b8605Smrg ctx->Pixel.BlueBias = 0.0; 661848b8605Smrg ctx->Pixel.BlueScale = 1.0; 662848b8605Smrg ctx->Pixel.AlphaBias = 0.0; 663848b8605Smrg ctx->Pixel.AlphaScale = 1.0; 664848b8605Smrg ctx->Pixel.DepthBias = 0.0; 665848b8605Smrg ctx->Pixel.DepthScale = 1.0; 666848b8605Smrg ctx->Pixel.IndexOffset = 0; 667848b8605Smrg ctx->Pixel.IndexShift = 0; 668848b8605Smrg ctx->Pixel.ZoomX = 1.0; 669848b8605Smrg ctx->Pixel.ZoomY = 1.0; 670848b8605Smrg ctx->Pixel.MapColorFlag = GL_FALSE; 671848b8605Smrg ctx->Pixel.MapStencilFlag = GL_FALSE; 672848b8605Smrg init_pixelmap(&ctx->PixelMaps.StoS); 673848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoI); 674848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoR); 675848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoG); 676848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoB); 677848b8605Smrg init_pixelmap(&ctx->PixelMaps.ItoA); 678848b8605Smrg init_pixelmap(&ctx->PixelMaps.RtoR); 679848b8605Smrg init_pixelmap(&ctx->PixelMaps.GtoG); 680848b8605Smrg init_pixelmap(&ctx->PixelMaps.BtoB); 681848b8605Smrg init_pixelmap(&ctx->PixelMaps.AtoA); 682848b8605Smrg 683848b8605Smrg if (ctx->Visual.doubleBufferMode) { 684848b8605Smrg ctx->Pixel.ReadBuffer = GL_BACK; 685848b8605Smrg } 686848b8605Smrg else { 687848b8605Smrg ctx->Pixel.ReadBuffer = GL_FRONT; 688848b8605Smrg } 689848b8605Smrg 690848b8605Smrg /* Miscellaneous */ 691848b8605Smrg ctx->_ImageTransferState = 0; 692848b8605Smrg} 693