1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci/** 27bf215546Sopenharmony_ci * \file pixel.c 28bf215546Sopenharmony_ci * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer) 29bf215546Sopenharmony_ci */ 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "glheader.h" 32bf215546Sopenharmony_ci#include "bufferobj.h" 33bf215546Sopenharmony_ci#include "context.h" 34bf215546Sopenharmony_ci#include "macros.h" 35bf215546Sopenharmony_ci#include "pixel.h" 36bf215546Sopenharmony_ci#include "pbo.h" 37bf215546Sopenharmony_ci#include "mtypes.h" 38bf215546Sopenharmony_ci#include "api_exec_decl.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#include <math.h> 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci/**********************************************************************/ 43bf215546Sopenharmony_ci/***** glPixelZoom *****/ 44bf215546Sopenharmony_ci/**********************************************************************/ 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_civoid GLAPIENTRY 47bf215546Sopenharmony_ci_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ) 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci if (ctx->Pixel.ZoomX == xfactor && 52bf215546Sopenharmony_ci ctx->Pixel.ZoomY == yfactor) 53bf215546Sopenharmony_ci return; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 56bf215546Sopenharmony_ci ctx->Pixel.ZoomX = xfactor; 57bf215546Sopenharmony_ci ctx->Pixel.ZoomY = yfactor; 58bf215546Sopenharmony_ci} 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci/**********************************************************************/ 63bf215546Sopenharmony_ci/***** glPixelMap *****/ 64bf215546Sopenharmony_ci/**********************************************************************/ 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci/** 67bf215546Sopenharmony_ci * Return pointer to a pixelmap by name. 68bf215546Sopenharmony_ci */ 69bf215546Sopenharmony_cistatic struct gl_pixelmap * 70bf215546Sopenharmony_ciget_pixelmap(struct gl_context *ctx, GLenum map) 71bf215546Sopenharmony_ci{ 72bf215546Sopenharmony_ci switch (map) { 73bf215546Sopenharmony_ci case GL_PIXEL_MAP_I_TO_I: 74bf215546Sopenharmony_ci return &ctx->PixelMaps.ItoI; 75bf215546Sopenharmony_ci case GL_PIXEL_MAP_S_TO_S: 76bf215546Sopenharmony_ci return &ctx->PixelMaps.StoS; 77bf215546Sopenharmony_ci case GL_PIXEL_MAP_I_TO_R: 78bf215546Sopenharmony_ci return &ctx->PixelMaps.ItoR; 79bf215546Sopenharmony_ci case GL_PIXEL_MAP_I_TO_G: 80bf215546Sopenharmony_ci return &ctx->PixelMaps.ItoG; 81bf215546Sopenharmony_ci case GL_PIXEL_MAP_I_TO_B: 82bf215546Sopenharmony_ci return &ctx->PixelMaps.ItoB; 83bf215546Sopenharmony_ci case GL_PIXEL_MAP_I_TO_A: 84bf215546Sopenharmony_ci return &ctx->PixelMaps.ItoA; 85bf215546Sopenharmony_ci case GL_PIXEL_MAP_R_TO_R: 86bf215546Sopenharmony_ci return &ctx->PixelMaps.RtoR; 87bf215546Sopenharmony_ci case GL_PIXEL_MAP_G_TO_G: 88bf215546Sopenharmony_ci return &ctx->PixelMaps.GtoG; 89bf215546Sopenharmony_ci case GL_PIXEL_MAP_B_TO_B: 90bf215546Sopenharmony_ci return &ctx->PixelMaps.BtoB; 91bf215546Sopenharmony_ci case GL_PIXEL_MAP_A_TO_A: 92bf215546Sopenharmony_ci return &ctx->PixelMaps.AtoA; 93bf215546Sopenharmony_ci default: 94bf215546Sopenharmony_ci return NULL; 95bf215546Sopenharmony_ci } 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ci/** 100bf215546Sopenharmony_ci * Helper routine used by the other _mesa_PixelMap() functions. 101bf215546Sopenharmony_ci */ 102bf215546Sopenharmony_cistatic void 103bf215546Sopenharmony_cistore_pixelmap(struct gl_context *ctx, GLenum map, GLsizei mapsize, 104bf215546Sopenharmony_ci const GLfloat *values) 105bf215546Sopenharmony_ci{ 106bf215546Sopenharmony_ci GLint i; 107bf215546Sopenharmony_ci struct gl_pixelmap *pm = get_pixelmap(ctx, map); 108bf215546Sopenharmony_ci if (!pm) { 109bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glPixelMap(map)"); 110bf215546Sopenharmony_ci return; 111bf215546Sopenharmony_ci } 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci switch (map) { 114bf215546Sopenharmony_ci case GL_PIXEL_MAP_S_TO_S: 115bf215546Sopenharmony_ci /* special case */ 116bf215546Sopenharmony_ci ctx->PixelMaps.StoS.Size = mapsize; 117bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 118bf215546Sopenharmony_ci ctx->PixelMaps.StoS.Map[i] = roundf(values[i]); 119bf215546Sopenharmony_ci } 120bf215546Sopenharmony_ci break; 121bf215546Sopenharmony_ci case GL_PIXEL_MAP_I_TO_I: 122bf215546Sopenharmony_ci /* special case */ 123bf215546Sopenharmony_ci ctx->PixelMaps.ItoI.Size = mapsize; 124bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 125bf215546Sopenharmony_ci ctx->PixelMaps.ItoI.Map[i] = values[i]; 126bf215546Sopenharmony_ci } 127bf215546Sopenharmony_ci break; 128bf215546Sopenharmony_ci default: 129bf215546Sopenharmony_ci /* general case */ 130bf215546Sopenharmony_ci pm->Size = mapsize; 131bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 132bf215546Sopenharmony_ci GLfloat val = CLAMP(values[i], 0.0F, 1.0F); 133bf215546Sopenharmony_ci pm->Map[i] = val; 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci} 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci/** 140bf215546Sopenharmony_ci * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap(). 141bf215546Sopenharmony_ci */ 142bf215546Sopenharmony_cistatic GLboolean 143bf215546Sopenharmony_civalidate_pbo_access(struct gl_context *ctx, 144bf215546Sopenharmony_ci struct gl_pixelstore_attrib *pack, GLsizei mapsize, 145bf215546Sopenharmony_ci GLenum format, GLenum type, GLsizei clientMemSize, 146bf215546Sopenharmony_ci const GLvoid *ptr) 147bf215546Sopenharmony_ci{ 148bf215546Sopenharmony_ci GLboolean ok; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci /* Note, need to use DefaultPacking and Unpack's buffer object */ 151bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, 152bf215546Sopenharmony_ci &ctx->DefaultPacking.BufferObj, 153bf215546Sopenharmony_ci pack->BufferObj); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1, 156bf215546Sopenharmony_ci format, type, clientMemSize, ptr); 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci /* restore */ 159bf215546Sopenharmony_ci _mesa_reference_buffer_object(ctx, 160bf215546Sopenharmony_ci &ctx->DefaultPacking.BufferObj, NULL); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci if (!ok) { 163bf215546Sopenharmony_ci if (pack->BufferObj) { 164bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 165bf215546Sopenharmony_ci "gl[Get]PixelMap*v(out of bounds PBO access)"); 166bf215546Sopenharmony_ci } else { 167bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 168bf215546Sopenharmony_ci "glGetnPixelMap*vARB(out of bounds access:" 169bf215546Sopenharmony_ci " bufSize (%d) is too small)", clientMemSize); 170bf215546Sopenharmony_ci } 171bf215546Sopenharmony_ci } 172bf215546Sopenharmony_ci return ok; 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_civoid GLAPIENTRY 177bf215546Sopenharmony_ci_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ) 178bf215546Sopenharmony_ci{ 179bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci /* XXX someday, test against ctx->Const.MaxPixelMapTableSize */ 182bf215546Sopenharmony_ci if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 183bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 184bf215546Sopenharmony_ci return; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 188bf215546Sopenharmony_ci /* test that mapsize is a power of two */ 189bf215546Sopenharmony_ci if (!util_is_power_of_two_or_zero(mapsize)) { 190bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); 191bf215546Sopenharmony_ci return; 192bf215546Sopenharmony_ci } 193bf215546Sopenharmony_ci } 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, 0); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 198bf215546Sopenharmony_ci GL_FLOAT, INT_MAX, values)) { 199bf215546Sopenharmony_ci return; 200bf215546Sopenharmony_ci } 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 203bf215546Sopenharmony_ci if (!values) { 204bf215546Sopenharmony_ci if (ctx->Unpack.BufferObj) { 205bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 206bf215546Sopenharmony_ci "glPixelMapfv(PBO is mapped)"); 207bf215546Sopenharmony_ci } 208bf215546Sopenharmony_ci return; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci store_pixelmap(ctx, map, mapsize, values); 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 214bf215546Sopenharmony_ci} 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_civoid GLAPIENTRY 218bf215546Sopenharmony_ci_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ) 219bf215546Sopenharmony_ci{ 220bf215546Sopenharmony_ci GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 221bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 224bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 225bf215546Sopenharmony_ci return; 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 229bf215546Sopenharmony_ci /* test that mapsize is a power of two */ 230bf215546Sopenharmony_ci if (!util_is_power_of_two_or_zero(mapsize)) { 231bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapuiv(mapsize)" ); 232bf215546Sopenharmony_ci return; 233bf215546Sopenharmony_ci } 234bf215546Sopenharmony_ci } 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, 0); 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 239bf215546Sopenharmony_ci GL_UNSIGNED_INT, INT_MAX, values)) { 240bf215546Sopenharmony_ci return; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 244bf215546Sopenharmony_ci if (!values) { 245bf215546Sopenharmony_ci if (ctx->Unpack.BufferObj) { 246bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 247bf215546Sopenharmony_ci "glPixelMapuiv(PBO is mapped)"); 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci return; 250bf215546Sopenharmony_ci } 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci /* convert to floats */ 253bf215546Sopenharmony_ci if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 254bf215546Sopenharmony_ci GLint i; 255bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 256bf215546Sopenharmony_ci fvalues[i] = (GLfloat) values[i]; 257bf215546Sopenharmony_ci } 258bf215546Sopenharmony_ci } 259bf215546Sopenharmony_ci else { 260bf215546Sopenharmony_ci GLint i; 261bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 262bf215546Sopenharmony_ci fvalues[i] = UINT_TO_FLOAT( values[i] ); 263bf215546Sopenharmony_ci } 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci store_pixelmap(ctx, map, mapsize, fvalues); 269bf215546Sopenharmony_ci} 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_civoid GLAPIENTRY 273bf215546Sopenharmony_ci_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ) 274bf215546Sopenharmony_ci{ 275bf215546Sopenharmony_ci GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; 276bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci if (mapsize < 1 || mapsize > MAX_PIXEL_MAP_TABLE) { 279bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 280bf215546Sopenharmony_ci return; 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci if (map >= GL_PIXEL_MAP_S_TO_S && map <= GL_PIXEL_MAP_I_TO_A) { 284bf215546Sopenharmony_ci /* test that mapsize is a power of two */ 285bf215546Sopenharmony_ci if (!util_is_power_of_two_or_zero(mapsize)) { 286bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapusv(mapsize)" ); 287bf215546Sopenharmony_ci return; 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci } 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, 0); 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize, GL_INTENSITY, 294bf215546Sopenharmony_ci GL_UNSIGNED_SHORT, INT_MAX, values)) { 295bf215546Sopenharmony_ci return; 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values); 299bf215546Sopenharmony_ci if (!values) { 300bf215546Sopenharmony_ci if (ctx->Unpack.BufferObj) { 301bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 302bf215546Sopenharmony_ci "glPixelMapusv(PBO is mapped)"); 303bf215546Sopenharmony_ci } 304bf215546Sopenharmony_ci return; 305bf215546Sopenharmony_ci } 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci /* convert to floats */ 308bf215546Sopenharmony_ci if (map == GL_PIXEL_MAP_I_TO_I || map == GL_PIXEL_MAP_S_TO_S) { 309bf215546Sopenharmony_ci GLint i; 310bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 311bf215546Sopenharmony_ci fvalues[i] = (GLfloat) values[i]; 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci else { 315bf215546Sopenharmony_ci GLint i; 316bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 317bf215546Sopenharmony_ci fvalues[i] = USHORT_TO_FLOAT( values[i] ); 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci } 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci _mesa_unmap_pbo_source(ctx, &ctx->Unpack); 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci store_pixelmap(ctx, map, mapsize, fvalues); 324bf215546Sopenharmony_ci} 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_civoid GLAPIENTRY 328bf215546Sopenharmony_ci_mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values ) 329bf215546Sopenharmony_ci{ 330bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 331bf215546Sopenharmony_ci GLint mapsize, i; 332bf215546Sopenharmony_ci const struct gl_pixelmap *pm; 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci pm = get_pixelmap(ctx, map); 335bf215546Sopenharmony_ci if (!pm) { 336bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapfv(map)"); 337bf215546Sopenharmony_ci return; 338bf215546Sopenharmony_ci } 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci mapsize = pm->Size; 341bf215546Sopenharmony_ci 342bf215546Sopenharmony_ci if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 343bf215546Sopenharmony_ci GL_FLOAT, bufSize, values)) { 344bf215546Sopenharmony_ci return; 345bf215546Sopenharmony_ci } 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci if (ctx->Pack.BufferObj) 348bf215546Sopenharmony_ci ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 351bf215546Sopenharmony_ci if (!values) { 352bf215546Sopenharmony_ci if (ctx->Pack.BufferObj) { 353bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 354bf215546Sopenharmony_ci "glGetPixelMapfv(PBO is mapped)"); 355bf215546Sopenharmony_ci } 356bf215546Sopenharmony_ci return; 357bf215546Sopenharmony_ci } 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci if (map == GL_PIXEL_MAP_S_TO_S) { 360bf215546Sopenharmony_ci /* special case */ 361bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 362bf215546Sopenharmony_ci values[i] = (GLfloat) ctx->PixelMaps.StoS.Map[i]; 363bf215546Sopenharmony_ci } 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci else { 366bf215546Sopenharmony_ci memcpy(values, pm->Map, mapsize * sizeof(GLfloat)); 367bf215546Sopenharmony_ci } 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 370bf215546Sopenharmony_ci} 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_civoid GLAPIENTRY 374bf215546Sopenharmony_ci_mesa_GetPixelMapfv( GLenum map, GLfloat *values ) 375bf215546Sopenharmony_ci{ 376bf215546Sopenharmony_ci _mesa_GetnPixelMapfvARB(map, INT_MAX, values); 377bf215546Sopenharmony_ci} 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_civoid GLAPIENTRY 380bf215546Sopenharmony_ci_mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values ) 381bf215546Sopenharmony_ci{ 382bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 383bf215546Sopenharmony_ci GLint mapsize, i; 384bf215546Sopenharmony_ci const struct gl_pixelmap *pm; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci pm = get_pixelmap(ctx, map); 387bf215546Sopenharmony_ci if (!pm) { 388bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapuiv(map)"); 389bf215546Sopenharmony_ci return; 390bf215546Sopenharmony_ci } 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci mapsize = pm->Size; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 395bf215546Sopenharmony_ci GL_UNSIGNED_INT, bufSize, values)) { 396bf215546Sopenharmony_ci return; 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci if (ctx->Pack.BufferObj) 400bf215546Sopenharmony_ci ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 403bf215546Sopenharmony_ci if (!values) { 404bf215546Sopenharmony_ci if (ctx->Pack.BufferObj) { 405bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 406bf215546Sopenharmony_ci "glGetPixelMapuiv(PBO is mapped)"); 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci return; 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci if (map == GL_PIXEL_MAP_S_TO_S) { 412bf215546Sopenharmony_ci /* special case */ 413bf215546Sopenharmony_ci memcpy(values, ctx->PixelMaps.StoS.Map, mapsize * sizeof(GLint)); 414bf215546Sopenharmony_ci } 415bf215546Sopenharmony_ci else { 416bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 417bf215546Sopenharmony_ci values[i] = FLOAT_TO_UINT( pm->Map[i] ); 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci } 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 422bf215546Sopenharmony_ci} 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_civoid GLAPIENTRY 426bf215546Sopenharmony_ci_mesa_GetPixelMapuiv( GLenum map, GLuint *values ) 427bf215546Sopenharmony_ci{ 428bf215546Sopenharmony_ci _mesa_GetnPixelMapuivARB(map, INT_MAX, values); 429bf215546Sopenharmony_ci} 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_civoid GLAPIENTRY 432bf215546Sopenharmony_ci_mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values ) 433bf215546Sopenharmony_ci{ 434bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 435bf215546Sopenharmony_ci GLint mapsize, i; 436bf215546Sopenharmony_ci const struct gl_pixelmap *pm; 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci pm = get_pixelmap(ctx, map); 439bf215546Sopenharmony_ci if (!pm) { 440bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelMapusv(map)"); 441bf215546Sopenharmony_ci return; 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci mapsize = pm->Size; 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci if (!validate_pbo_access(ctx, &ctx->Pack, mapsize, GL_INTENSITY, 447bf215546Sopenharmony_ci GL_UNSIGNED_SHORT, bufSize, values)) { 448bf215546Sopenharmony_ci return; 449bf215546Sopenharmony_ci } 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci if (ctx->Pack.BufferObj) 452bf215546Sopenharmony_ci ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); 455bf215546Sopenharmony_ci if (!values) { 456bf215546Sopenharmony_ci if (ctx->Pack.BufferObj) { 457bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 458bf215546Sopenharmony_ci "glGetPixelMapusv(PBO is mapped)"); 459bf215546Sopenharmony_ci } 460bf215546Sopenharmony_ci return; 461bf215546Sopenharmony_ci } 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci switch (map) { 464bf215546Sopenharmony_ci /* special cases */ 465bf215546Sopenharmony_ci case GL_PIXEL_MAP_I_TO_I: 466bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 467bf215546Sopenharmony_ci values[i] = (GLushort) CLAMP(ctx->PixelMaps.ItoI.Map[i], 0.0F, 65535.0F); 468bf215546Sopenharmony_ci } 469bf215546Sopenharmony_ci break; 470bf215546Sopenharmony_ci case GL_PIXEL_MAP_S_TO_S: 471bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 472bf215546Sopenharmony_ci values[i] = (GLushort) CLAMP(ctx->PixelMaps.StoS.Map[i], 0.0F, 65535.0F); 473bf215546Sopenharmony_ci } 474bf215546Sopenharmony_ci break; 475bf215546Sopenharmony_ci default: 476bf215546Sopenharmony_ci for (i = 0; i < mapsize; i++) { 477bf215546Sopenharmony_ci CLAMPED_FLOAT_TO_USHORT(values[i], pm->Map[i] ); 478bf215546Sopenharmony_ci } 479bf215546Sopenharmony_ci } 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci _mesa_unmap_pbo_dest(ctx, &ctx->Pack); 482bf215546Sopenharmony_ci} 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_civoid GLAPIENTRY 486bf215546Sopenharmony_ci_mesa_GetPixelMapusv( GLenum map, GLushort *values ) 487bf215546Sopenharmony_ci{ 488bf215546Sopenharmony_ci _mesa_GetnPixelMapusvARB(map, INT_MAX, values); 489bf215546Sopenharmony_ci} 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci/**********************************************************************/ 493bf215546Sopenharmony_ci/***** glPixelTransfer *****/ 494bf215546Sopenharmony_ci/**********************************************************************/ 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci/* 498bf215546Sopenharmony_ci * Implements glPixelTransfer[fi] whether called immediately or from a 499bf215546Sopenharmony_ci * display list. 500bf215546Sopenharmony_ci */ 501bf215546Sopenharmony_civoid GLAPIENTRY 502bf215546Sopenharmony_ci_mesa_PixelTransferf( GLenum pname, GLfloat param ) 503bf215546Sopenharmony_ci{ 504bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 505bf215546Sopenharmony_ci 506bf215546Sopenharmony_ci switch (pname) { 507bf215546Sopenharmony_ci case GL_MAP_COLOR: 508bf215546Sopenharmony_ci if (ctx->Pixel.MapColorFlag == (param ? GL_TRUE : GL_FALSE)) 509bf215546Sopenharmony_ci return; 510bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 511bf215546Sopenharmony_ci ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE; 512bf215546Sopenharmony_ci break; 513bf215546Sopenharmony_ci case GL_MAP_STENCIL: 514bf215546Sopenharmony_ci if (ctx->Pixel.MapStencilFlag == (param ? GL_TRUE : GL_FALSE)) 515bf215546Sopenharmony_ci return; 516bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 517bf215546Sopenharmony_ci ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE; 518bf215546Sopenharmony_ci break; 519bf215546Sopenharmony_ci case GL_INDEX_SHIFT: 520bf215546Sopenharmony_ci if (ctx->Pixel.IndexShift == (GLint) param) 521bf215546Sopenharmony_ci return; 522bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 523bf215546Sopenharmony_ci ctx->Pixel.IndexShift = (GLint) param; 524bf215546Sopenharmony_ci break; 525bf215546Sopenharmony_ci case GL_INDEX_OFFSET: 526bf215546Sopenharmony_ci if (ctx->Pixel.IndexOffset == (GLint) param) 527bf215546Sopenharmony_ci return; 528bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 529bf215546Sopenharmony_ci ctx->Pixel.IndexOffset = (GLint) param; 530bf215546Sopenharmony_ci break; 531bf215546Sopenharmony_ci case GL_RED_SCALE: 532bf215546Sopenharmony_ci if (ctx->Pixel.RedScale == param) 533bf215546Sopenharmony_ci return; 534bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 535bf215546Sopenharmony_ci ctx->Pixel.RedScale = param; 536bf215546Sopenharmony_ci break; 537bf215546Sopenharmony_ci case GL_RED_BIAS: 538bf215546Sopenharmony_ci if (ctx->Pixel.RedBias == param) 539bf215546Sopenharmony_ci return; 540bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 541bf215546Sopenharmony_ci ctx->Pixel.RedBias = param; 542bf215546Sopenharmony_ci break; 543bf215546Sopenharmony_ci case GL_GREEN_SCALE: 544bf215546Sopenharmony_ci if (ctx->Pixel.GreenScale == param) 545bf215546Sopenharmony_ci return; 546bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 547bf215546Sopenharmony_ci ctx->Pixel.GreenScale = param; 548bf215546Sopenharmony_ci break; 549bf215546Sopenharmony_ci case GL_GREEN_BIAS: 550bf215546Sopenharmony_ci if (ctx->Pixel.GreenBias == param) 551bf215546Sopenharmony_ci return; 552bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 553bf215546Sopenharmony_ci ctx->Pixel.GreenBias = param; 554bf215546Sopenharmony_ci break; 555bf215546Sopenharmony_ci case GL_BLUE_SCALE: 556bf215546Sopenharmony_ci if (ctx->Pixel.BlueScale == param) 557bf215546Sopenharmony_ci return; 558bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 559bf215546Sopenharmony_ci ctx->Pixel.BlueScale = param; 560bf215546Sopenharmony_ci break; 561bf215546Sopenharmony_ci case GL_BLUE_BIAS: 562bf215546Sopenharmony_ci if (ctx->Pixel.BlueBias == param) 563bf215546Sopenharmony_ci return; 564bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 565bf215546Sopenharmony_ci ctx->Pixel.BlueBias = param; 566bf215546Sopenharmony_ci break; 567bf215546Sopenharmony_ci case GL_ALPHA_SCALE: 568bf215546Sopenharmony_ci if (ctx->Pixel.AlphaScale == param) 569bf215546Sopenharmony_ci return; 570bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 571bf215546Sopenharmony_ci ctx->Pixel.AlphaScale = param; 572bf215546Sopenharmony_ci break; 573bf215546Sopenharmony_ci case GL_ALPHA_BIAS: 574bf215546Sopenharmony_ci if (ctx->Pixel.AlphaBias == param) 575bf215546Sopenharmony_ci return; 576bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 577bf215546Sopenharmony_ci ctx->Pixel.AlphaBias = param; 578bf215546Sopenharmony_ci break; 579bf215546Sopenharmony_ci case GL_DEPTH_SCALE: 580bf215546Sopenharmony_ci if (ctx->Pixel.DepthScale == param) 581bf215546Sopenharmony_ci return; 582bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 583bf215546Sopenharmony_ci ctx->Pixel.DepthScale = param; 584bf215546Sopenharmony_ci break; 585bf215546Sopenharmony_ci case GL_DEPTH_BIAS: 586bf215546Sopenharmony_ci if (ctx->Pixel.DepthBias == param) 587bf215546Sopenharmony_ci return; 588bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, _NEW_PIXEL, GL_PIXEL_MODE_BIT); 589bf215546Sopenharmony_ci ctx->Pixel.DepthBias = param; 590bf215546Sopenharmony_ci break; 591bf215546Sopenharmony_ci default: 592bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); 593bf215546Sopenharmony_ci return; 594bf215546Sopenharmony_ci } 595bf215546Sopenharmony_ci} 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_civoid GLAPIENTRY 599bf215546Sopenharmony_ci_mesa_PixelTransferi( GLenum pname, GLint param ) 600bf215546Sopenharmony_ci{ 601bf215546Sopenharmony_ci _mesa_PixelTransferf( pname, (GLfloat) param ); 602bf215546Sopenharmony_ci} 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci/**********************************************************************/ 607bf215546Sopenharmony_ci/***** State Management *****/ 608bf215546Sopenharmony_ci/**********************************************************************/ 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci/** 612bf215546Sopenharmony_ci * Update mesa pixel transfer derived state to indicate which operations are 613bf215546Sopenharmony_ci * enabled. 614bf215546Sopenharmony_ci */ 615bf215546Sopenharmony_civoid 616bf215546Sopenharmony_ci_mesa_update_pixel( struct gl_context *ctx ) 617bf215546Sopenharmony_ci{ 618bf215546Sopenharmony_ci GLuint mask = 0; 619bf215546Sopenharmony_ci 620bf215546Sopenharmony_ci if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F || 621bf215546Sopenharmony_ci ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F || 622bf215546Sopenharmony_ci ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F || 623bf215546Sopenharmony_ci ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F) 624bf215546Sopenharmony_ci mask |= IMAGE_SCALE_BIAS_BIT; 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) 627bf215546Sopenharmony_ci mask |= IMAGE_SHIFT_OFFSET_BIT; 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci if (ctx->Pixel.MapColorFlag) 630bf215546Sopenharmony_ci mask |= IMAGE_MAP_COLOR_BIT; 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci ctx->_ImageTransferState = mask; 633bf215546Sopenharmony_ci} 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci 636bf215546Sopenharmony_ci/**********************************************************************/ 637bf215546Sopenharmony_ci/***** Initialization *****/ 638bf215546Sopenharmony_ci/**********************************************************************/ 639bf215546Sopenharmony_ci 640bf215546Sopenharmony_cistatic void 641bf215546Sopenharmony_ciinit_pixelmap(struct gl_pixelmap *map) 642bf215546Sopenharmony_ci{ 643bf215546Sopenharmony_ci map->Size = 1; 644bf215546Sopenharmony_ci map->Map[0] = 0.0; 645bf215546Sopenharmony_ci} 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci/** 649bf215546Sopenharmony_ci * Initialize the context's PIXEL attribute group. 650bf215546Sopenharmony_ci */ 651bf215546Sopenharmony_civoid 652bf215546Sopenharmony_ci_mesa_init_pixel( struct gl_context *ctx ) 653bf215546Sopenharmony_ci{ 654bf215546Sopenharmony_ci /* Pixel group */ 655bf215546Sopenharmony_ci ctx->Pixel.RedBias = 0.0; 656bf215546Sopenharmony_ci ctx->Pixel.RedScale = 1.0; 657bf215546Sopenharmony_ci ctx->Pixel.GreenBias = 0.0; 658bf215546Sopenharmony_ci ctx->Pixel.GreenScale = 1.0; 659bf215546Sopenharmony_ci ctx->Pixel.BlueBias = 0.0; 660bf215546Sopenharmony_ci ctx->Pixel.BlueScale = 1.0; 661bf215546Sopenharmony_ci ctx->Pixel.AlphaBias = 0.0; 662bf215546Sopenharmony_ci ctx->Pixel.AlphaScale = 1.0; 663bf215546Sopenharmony_ci ctx->Pixel.DepthBias = 0.0; 664bf215546Sopenharmony_ci ctx->Pixel.DepthScale = 1.0; 665bf215546Sopenharmony_ci ctx->Pixel.IndexOffset = 0; 666bf215546Sopenharmony_ci ctx->Pixel.IndexShift = 0; 667bf215546Sopenharmony_ci ctx->Pixel.ZoomX = 1.0; 668bf215546Sopenharmony_ci ctx->Pixel.ZoomY = 1.0; 669bf215546Sopenharmony_ci ctx->Pixel.MapColorFlag = GL_FALSE; 670bf215546Sopenharmony_ci ctx->Pixel.MapStencilFlag = GL_FALSE; 671bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.StoS); 672bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.ItoI); 673bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.ItoR); 674bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.ItoG); 675bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.ItoB); 676bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.ItoA); 677bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.RtoR); 678bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.GtoG); 679bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.BtoB); 680bf215546Sopenharmony_ci init_pixelmap(&ctx->PixelMaps.AtoA); 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci if (ctx->Visual.doubleBufferMode) { 683bf215546Sopenharmony_ci ctx->Pixel.ReadBuffer = GL_BACK; 684bf215546Sopenharmony_ci } 685bf215546Sopenharmony_ci else { 686bf215546Sopenharmony_ci ctx->Pixel.ReadBuffer = GL_FRONT; 687bf215546Sopenharmony_ci } 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci /* Miscellaneous */ 690bf215546Sopenharmony_ci ctx->_ImageTransferState = 0; 691bf215546Sopenharmony_ci} 692