meta.c revision 2abf555496b8f5a7319542756508dd2f2e8ed07c
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.6 4 * 5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6 * 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: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 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. 23 */ 24 25/** 26 * Meta operations. Some GL operations can be expressed in terms of 27 * other GL operations. For example, glBlitFramebuffer() can be done 28 * with texture mapping and glClear() can be done with polygon rendering. 29 * 30 * \author Brian Paul 31 */ 32 33 34#include "main/glheader.h" 35#include "main/mtypes.h" 36#include "main/imports.h" 37#include "main/arbprogram.h" 38#include "main/arrayobj.h" 39#include "main/blend.h" 40#include "main/bufferobj.h" 41#include "main/buffers.h" 42#include "main/colortab.h" 43#include "main/condrender.h" 44#include "main/depth.h" 45#include "main/enable.h" 46#include "main/fbobject.h" 47#include "main/feedback.h" 48#include "main/formats.h" 49#include "main/glformats.h" 50#include "main/image.h" 51#include "main/macros.h" 52#include "main/matrix.h" 53#include "main/mipmap.h" 54#include "main/pixel.h" 55#include "main/pbo.h" 56#include "main/polygon.h" 57#include "main/readpix.h" 58#include "main/scissor.h" 59#include "main/shaderapi.h" 60#include "main/shaderobj.h" 61#include "main/state.h" 62#include "main/stencil.h" 63#include "main/texobj.h" 64#include "main/texenv.h" 65#include "main/texgetimage.h" 66#include "main/teximage.h" 67#include "main/texparam.h" 68#include "main/texstate.h" 69#include "main/transformfeedback.h" 70#include "main/uniforms.h" 71#include "main/varray.h" 72#include "main/viewport.h" 73#include "main/samplerobj.h" 74#include "program/program.h" 75#include "swrast/swrast.h" 76#include "drivers/common/meta.h" 77#include "main/enums.h" 78#include "main/glformats.h" 79 80 81/** Return offset in bytes of the field within a vertex struct */ 82#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD)) 83 84/** 85 * State which we may save/restore across meta ops. 86 * XXX this may be incomplete... 87 */ 88struct save_state 89{ 90 GLbitfield SavedState; /**< bitmask of MESA_META_* flags */ 91 92 /** MESA_META_ALPHA_TEST */ 93 GLboolean AlphaEnabled; 94 GLenum AlphaFunc; 95 GLclampf AlphaRef; 96 97 /** MESA_META_BLEND */ 98 GLbitfield BlendEnabled; 99 GLboolean ColorLogicOpEnabled; 100 101 /** MESA_META_COLOR_MASK */ 102 GLubyte ColorMask[MAX_DRAW_BUFFERS][4]; 103 104 /** MESA_META_DEPTH_TEST */ 105 struct gl_depthbuffer_attrib Depth; 106 107 /** MESA_META_FOG */ 108 GLboolean Fog; 109 110 /** MESA_META_PIXEL_STORE */ 111 struct gl_pixelstore_attrib Pack, Unpack; 112 113 /** MESA_META_PIXEL_TRANSFER */ 114 GLfloat RedBias, RedScale; 115 GLfloat GreenBias, GreenScale; 116 GLfloat BlueBias, BlueScale; 117 GLfloat AlphaBias, AlphaScale; 118 GLfloat DepthBias, DepthScale; 119 GLboolean MapColorFlag; 120 121 /** MESA_META_RASTERIZATION */ 122 GLenum FrontPolygonMode, BackPolygonMode; 123 GLboolean PolygonOffset; 124 GLboolean PolygonSmooth; 125 GLboolean PolygonStipple; 126 GLboolean PolygonCull; 127 128 /** MESA_META_SCISSOR */ 129 struct gl_scissor_attrib Scissor; 130 131 /** MESA_META_SHADER */ 132 GLboolean VertexProgramEnabled; 133 struct gl_vertex_program *VertexProgram; 134 GLboolean FragmentProgramEnabled; 135 struct gl_fragment_program *FragmentProgram; 136 struct gl_shader_program *VertexShader; 137 struct gl_shader_program *GeometryShader; 138 struct gl_shader_program *FragmentShader; 139 struct gl_shader_program *ActiveShader; 140 141 /** MESA_META_STENCIL_TEST */ 142 struct gl_stencil_attrib Stencil; 143 144 /** MESA_META_TRANSFORM */ 145 GLenum MatrixMode; 146 GLfloat ModelviewMatrix[16]; 147 GLfloat ProjectionMatrix[16]; 148 GLfloat TextureMatrix[16]; 149 150 /** MESA_META_CLIP */ 151 GLbitfield ClipPlanesEnabled; 152 153 /** MESA_META_TEXTURE */ 154 GLuint ActiveUnit; 155 GLuint ClientActiveUnit; 156 /** for unit[0] only */ 157 struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS]; 158 /** mask of TEXTURE_2D_BIT, etc */ 159 GLbitfield TexEnabled[MAX_TEXTURE_UNITS]; 160 GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS]; 161 GLuint EnvMode; /* unit[0] only */ 162 163 /** MESA_META_VERTEX */ 164 struct gl_array_object *ArrayObj; 165 struct gl_buffer_object *ArrayBufferObj; 166 167 /** MESA_META_VIEWPORT */ 168 GLint ViewportX, ViewportY, ViewportW, ViewportH; 169 GLclampd DepthNear, DepthFar; 170 171 /** MESA_META_CLAMP_FRAGMENT_COLOR */ 172 GLenum ClampFragmentColor; 173 174 /** MESA_META_CLAMP_VERTEX_COLOR */ 175 GLenum ClampVertexColor; 176 177 /** MESA_META_CONDITIONAL_RENDER */ 178 struct gl_query_object *CondRenderQuery; 179 GLenum CondRenderMode; 180 181#if FEATURE_feedback 182 /** MESA_META_SELECT_FEEDBACK */ 183 GLenum RenderMode; 184 struct gl_selection Select; 185 struct gl_feedback Feedback; 186#endif 187 188 /** MESA_META_MULTISAMPLE */ 189 GLboolean MultisampleEnabled; 190 191 /** Miscellaneous (always disabled) */ 192 GLboolean Lighting; 193 GLboolean RasterDiscard; 194#if FEATURE_EXT_transform_feedback 195 GLboolean TransformFeedbackNeedsResume; 196#endif 197}; 198 199/** 200 * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc. 201 * This is currently shared by all the meta ops. But we could create a 202 * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc. 203 */ 204struct temp_texture 205{ 206 GLuint TexObj; 207 GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */ 208 GLsizei MinSize; /**< Min texture size to allocate */ 209 GLsizei MaxSize; /**< Max possible texture size */ 210 GLboolean NPOT; /**< Non-power of two size OK? */ 211 GLsizei Width, Height; /**< Current texture size */ 212 GLenum IntFormat; 213 GLfloat Sright, Ttop; /**< right, top texcoords */ 214}; 215 216 217/** 218 * State for glBlitFramebufer() 219 */ 220struct blit_state 221{ 222 GLuint ArrayObj; 223 GLuint VBO; 224 GLuint DepthFP; 225}; 226 227 228/** 229 * State for glClear() 230 */ 231struct clear_state 232{ 233 GLuint ArrayObj; 234 GLuint VBO; 235 GLuint ShaderProg; 236 GLint ColorLocation; 237 238 GLuint IntegerShaderProg; 239 GLint IntegerColorLocation; 240}; 241 242 243/** 244 * State for glCopyPixels() 245 */ 246struct copypix_state 247{ 248 GLuint ArrayObj; 249 GLuint VBO; 250}; 251 252 253/** 254 * State for glDrawPixels() 255 */ 256struct drawpix_state 257{ 258 GLuint ArrayObj; 259 260 GLuint StencilFP; /**< Fragment program for drawing stencil images */ 261 GLuint DepthFP; /**< Fragment program for drawing depth images */ 262}; 263 264 265/** 266 * State for glBitmap() 267 */ 268struct bitmap_state 269{ 270 GLuint ArrayObj; 271 GLuint VBO; 272 struct temp_texture Tex; /**< separate texture from other meta ops */ 273}; 274 275 276/** 277 * State for _mesa_meta_generate_mipmap() 278 */ 279struct gen_mipmap_state 280{ 281 GLuint ArrayObj; 282 GLuint VBO; 283 GLuint FBO; 284 GLuint Sampler; 285}; 286 287 288/** 289 * State for texture decompression 290 */ 291struct decompress_state 292{ 293 GLuint ArrayObj; 294 GLuint VBO, FBO, RBO, Sampler; 295 GLint Width, Height; 296}; 297 298/** 299 * State for glDrawTex() 300 */ 301struct drawtex_state 302{ 303 GLuint ArrayObj; 304 GLuint VBO; 305}; 306 307#define MAX_META_OPS_DEPTH 8 308/** 309 * All per-context meta state. 310 */ 311struct gl_meta_state 312{ 313 /** Stack of state saved during meta-ops */ 314 struct save_state Save[MAX_META_OPS_DEPTH]; 315 /** Save stack depth */ 316 GLuint SaveStackDepth; 317 318 struct temp_texture TempTex; 319 320 struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */ 321 struct clear_state Clear; /**< For _mesa_meta_Clear() */ 322 struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */ 323 struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */ 324 struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */ 325 struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */ 326 struct decompress_state Decompress; /**< For texture decompression */ 327 struct drawtex_state DrawTex; /**< For _mesa_meta_DrawTex() */ 328}; 329 330static void meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit); 331static void cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex); 332static void meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear); 333 334static GLuint 335compile_shader_with_debug(struct gl_context *ctx, GLenum target, const GLcharARB *source) 336{ 337 GLuint shader; 338 GLint ok, size; 339 GLchar *info; 340 341 shader = _mesa_CreateShaderObjectARB(target); 342 _mesa_ShaderSourceARB(shader, 1, &source, NULL); 343 _mesa_CompileShaderARB(shader); 344 345 _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &ok); 346 if (ok) 347 return shader; 348 349 _mesa_GetShaderiv(shader, GL_INFO_LOG_LENGTH, &size); 350 if (size == 0) { 351 _mesa_DeleteObjectARB(shader); 352 return 0; 353 } 354 355 info = malloc(size); 356 if (!info) { 357 _mesa_DeleteObjectARB(shader); 358 return 0; 359 } 360 361 _mesa_GetProgramInfoLog(shader, size, NULL, info); 362 _mesa_problem(ctx, 363 "meta program compile failed:\n%s\n" 364 "source:\n%s\n", 365 info, source); 366 367 free(info); 368 _mesa_DeleteObjectARB(shader); 369 370 return 0; 371} 372 373static GLuint 374link_program_with_debug(struct gl_context *ctx, GLuint program) 375{ 376 GLint ok, size; 377 GLchar *info; 378 379 _mesa_LinkProgramARB(program); 380 381 _mesa_GetProgramiv(program, GL_LINK_STATUS, &ok); 382 if (ok) 383 return program; 384 385 _mesa_GetProgramiv(program, GL_INFO_LOG_LENGTH, &size); 386 if (size == 0) 387 return 0; 388 389 info = malloc(size); 390 if (!info) 391 return 0; 392 393 _mesa_GetProgramInfoLog(program, size, NULL, info); 394 _mesa_problem(ctx, "meta program link failed:\n%s", info); 395 396 free(info); 397 398 return 0; 399} 400 401/** 402 * Initialize meta-ops for a context. 403 * To be called once during context creation. 404 */ 405void 406_mesa_meta_init(struct gl_context *ctx) 407{ 408 ASSERT(!ctx->Meta); 409 410 ctx->Meta = CALLOC_STRUCT(gl_meta_state); 411} 412 413 414/** 415 * Free context meta-op state. 416 * To be called once during context destruction. 417 */ 418void 419_mesa_meta_free(struct gl_context *ctx) 420{ 421 GET_CURRENT_CONTEXT(old_context); 422 _mesa_make_current(ctx, NULL, NULL); 423 meta_glsl_blit_cleanup(ctx, &ctx->Meta->Blit); 424 meta_glsl_clear_cleanup(ctx, &ctx->Meta->Clear); 425 cleanup_temp_texture(ctx, &ctx->Meta->TempTex); 426 if (old_context) 427 _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer); 428 else 429 _mesa_make_current(NULL, NULL, NULL); 430 free(ctx->Meta); 431 ctx->Meta = NULL; 432} 433 434 435/** 436 * Enter meta state. This is like a light-weight version of glPushAttrib 437 * but it also resets most GL state back to default values. 438 * 439 * \param state bitmask of MESA_META_* flags indicating which attribute groups 440 * to save and reset to their defaults 441 */ 442void 443_mesa_meta_begin(struct gl_context *ctx, GLbitfield state) 444{ 445 struct save_state *save; 446 447 /* hope MAX_META_OPS_DEPTH is large enough */ 448 assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH); 449 450 save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++]; 451 memset(save, 0, sizeof(*save)); 452 save->SavedState = state; 453 454#if FEATURE_EXT_transform_feedback 455 /* Pausing transform feedback needs to be done early, or else we won't be 456 * able to change other state. 457 */ 458 save->TransformFeedbackNeedsResume = 459 ctx->TransformFeedback.CurrentObject->Active && 460 !ctx->TransformFeedback.CurrentObject->Paused; 461 if (save->TransformFeedbackNeedsResume) 462 _mesa_PauseTransformFeedback(); 463#endif 464 465 if (state & MESA_META_ALPHA_TEST) { 466 save->AlphaEnabled = ctx->Color.AlphaEnabled; 467 save->AlphaFunc = ctx->Color.AlphaFunc; 468 save->AlphaRef = ctx->Color.AlphaRef; 469 if (ctx->Color.AlphaEnabled) 470 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE); 471 } 472 473 if (state & MESA_META_BLEND) { 474 save->BlendEnabled = ctx->Color.BlendEnabled; 475 if (ctx->Color.BlendEnabled) { 476 if (ctx->Extensions.EXT_draw_buffers2) { 477 GLuint i; 478 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 479 _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE); 480 } 481 } 482 else { 483 _mesa_set_enable(ctx, GL_BLEND, GL_FALSE); 484 } 485 } 486 save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled; 487 if (ctx->Color.ColorLogicOpEnabled) 488 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE); 489 } 490 491 if (state & MESA_META_COLOR_MASK) { 492 memcpy(save->ColorMask, ctx->Color.ColorMask, 493 sizeof(ctx->Color.ColorMask)); 494 if (!ctx->Color.ColorMask[0][0] || 495 !ctx->Color.ColorMask[0][1] || 496 !ctx->Color.ColorMask[0][2] || 497 !ctx->Color.ColorMask[0][3]) 498 _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 499 } 500 501 if (state & MESA_META_DEPTH_TEST) { 502 save->Depth = ctx->Depth; /* struct copy */ 503 if (ctx->Depth.Test) 504 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE); 505 } 506 507 if (state & MESA_META_FOG) { 508 save->Fog = ctx->Fog.Enabled; 509 if (ctx->Fog.Enabled) 510 _mesa_set_enable(ctx, GL_FOG, GL_FALSE); 511 } 512 513 if (state & MESA_META_PIXEL_STORE) { 514 save->Pack = ctx->Pack; 515 save->Unpack = ctx->Unpack; 516 ctx->Pack = ctx->DefaultPacking; 517 ctx->Unpack = ctx->DefaultPacking; 518 } 519 520 if (state & MESA_META_PIXEL_TRANSFER) { 521 save->RedScale = ctx->Pixel.RedScale; 522 save->RedBias = ctx->Pixel.RedBias; 523 save->GreenScale = ctx->Pixel.GreenScale; 524 save->GreenBias = ctx->Pixel.GreenBias; 525 save->BlueScale = ctx->Pixel.BlueScale; 526 save->BlueBias = ctx->Pixel.BlueBias; 527 save->AlphaScale = ctx->Pixel.AlphaScale; 528 save->AlphaBias = ctx->Pixel.AlphaBias; 529 save->MapColorFlag = ctx->Pixel.MapColorFlag; 530 ctx->Pixel.RedScale = 1.0F; 531 ctx->Pixel.RedBias = 0.0F; 532 ctx->Pixel.GreenScale = 1.0F; 533 ctx->Pixel.GreenBias = 0.0F; 534 ctx->Pixel.BlueScale = 1.0F; 535 ctx->Pixel.BlueBias = 0.0F; 536 ctx->Pixel.AlphaScale = 1.0F; 537 ctx->Pixel.AlphaBias = 0.0F; 538 ctx->Pixel.MapColorFlag = GL_FALSE; 539 /* XXX more state */ 540 ctx->NewState |=_NEW_PIXEL; 541 } 542 543 if (state & MESA_META_RASTERIZATION) { 544 save->FrontPolygonMode = ctx->Polygon.FrontMode; 545 save->BackPolygonMode = ctx->Polygon.BackMode; 546 save->PolygonOffset = ctx->Polygon.OffsetFill; 547 save->PolygonSmooth = ctx->Polygon.SmoothFlag; 548 save->PolygonStipple = ctx->Polygon.StippleFlag; 549 save->PolygonCull = ctx->Polygon.CullFlag; 550 _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); 551 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE); 552 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE); 553 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE); 554 _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE); 555 } 556 557 if (state & MESA_META_SCISSOR) { 558 save->Scissor = ctx->Scissor; /* struct copy */ 559 _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE); 560 } 561 562 if (state & MESA_META_SHADER) { 563 if (ctx->Extensions.ARB_vertex_program) { 564 save->VertexProgramEnabled = ctx->VertexProgram.Enabled; 565 _mesa_reference_vertprog(ctx, &save->VertexProgram, 566 ctx->VertexProgram.Current); 567 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE); 568 } 569 570 if (ctx->Extensions.ARB_fragment_program) { 571 save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled; 572 _mesa_reference_fragprog(ctx, &save->FragmentProgram, 573 ctx->FragmentProgram.Current); 574 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE); 575 } 576 577 if (ctx->Extensions.ARB_shader_objects) { 578 _mesa_reference_shader_program(ctx, &save->VertexShader, 579 ctx->Shader.CurrentVertexProgram); 580 _mesa_reference_shader_program(ctx, &save->GeometryShader, 581 ctx->Shader.CurrentGeometryProgram); 582 _mesa_reference_shader_program(ctx, &save->FragmentShader, 583 ctx->Shader.CurrentFragmentProgram); 584 _mesa_reference_shader_program(ctx, &save->ActiveShader, 585 ctx->Shader.ActiveProgram); 586 587 _mesa_UseProgramObjectARB(0); 588 } 589 } 590 591 if (state & MESA_META_STENCIL_TEST) { 592 save->Stencil = ctx->Stencil; /* struct copy */ 593 if (ctx->Stencil.Enabled) 594 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE); 595 /* NOTE: other stencil state not reset */ 596 } 597 598 if (state & MESA_META_TEXTURE) { 599 GLuint u, tgt; 600 601 save->ActiveUnit = ctx->Texture.CurrentUnit; 602 save->ClientActiveUnit = ctx->Array.ActiveTexture; 603 save->EnvMode = ctx->Texture.Unit[0].EnvMode; 604 605 /* Disable all texture units */ 606 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 607 save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled; 608 save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled; 609 if (ctx->Texture.Unit[u].Enabled || 610 ctx->Texture.Unit[u].TexGenEnabled) { 611 _mesa_ActiveTextureARB(GL_TEXTURE0 + u); 612 _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE); 613 _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE); 614 _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE); 615 if (ctx->Extensions.ARB_texture_cube_map) 616 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); 617 if (ctx->Extensions.NV_texture_rectangle) 618 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE); 619 if (ctx->Extensions.OES_EGL_image_external) 620 _mesa_set_enable(ctx, GL_TEXTURE_EXTERNAL_OES, GL_FALSE); 621 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE); 622 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE); 623 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE); 624 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE); 625 } 626 } 627 628 /* save current texture objects for unit[0] only */ 629 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 630 _mesa_reference_texobj(&save->CurrentTexture[tgt], 631 ctx->Texture.Unit[0].CurrentTex[tgt]); 632 } 633 634 /* set defaults for unit[0] */ 635 _mesa_ActiveTextureARB(GL_TEXTURE0); 636 _mesa_ClientActiveTextureARB(GL_TEXTURE0); 637 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 638 } 639 640 if (state & MESA_META_TRANSFORM) { 641 GLuint activeTexture = ctx->Texture.CurrentUnit; 642 memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m, 643 16 * sizeof(GLfloat)); 644 memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m, 645 16 * sizeof(GLfloat)); 646 memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m, 647 16 * sizeof(GLfloat)); 648 save->MatrixMode = ctx->Transform.MatrixMode; 649 /* set 1:1 vertex:pixel coordinate transform */ 650 _mesa_ActiveTextureARB(GL_TEXTURE0); 651 _mesa_MatrixMode(GL_TEXTURE); 652 _mesa_LoadIdentity(); 653 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture); 654 _mesa_MatrixMode(GL_MODELVIEW); 655 _mesa_LoadIdentity(); 656 _mesa_MatrixMode(GL_PROJECTION); 657 _mesa_LoadIdentity(); 658 _mesa_Ortho(0.0, ctx->DrawBuffer->Width, 659 0.0, ctx->DrawBuffer->Height, 660 -1.0, 1.0); 661 } 662 663 if (state & MESA_META_CLIP) { 664 save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled; 665 if (ctx->Transform.ClipPlanesEnabled) { 666 GLuint i; 667 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { 668 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE); 669 } 670 } 671 } 672 673 if (state & MESA_META_VERTEX) { 674 /* save vertex array object state */ 675 _mesa_reference_array_object(ctx, &save->ArrayObj, 676 ctx->Array.ArrayObj); 677 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, 678 ctx->Array.ArrayBufferObj); 679 /* set some default state? */ 680 } 681 682 if (state & MESA_META_VIEWPORT) { 683 /* save viewport state */ 684 save->ViewportX = ctx->Viewport.X; 685 save->ViewportY = ctx->Viewport.Y; 686 save->ViewportW = ctx->Viewport.Width; 687 save->ViewportH = ctx->Viewport.Height; 688 /* set viewport to match window size */ 689 if (ctx->Viewport.X != 0 || 690 ctx->Viewport.Y != 0 || 691 ctx->Viewport.Width != ctx->DrawBuffer->Width || 692 ctx->Viewport.Height != ctx->DrawBuffer->Height) { 693 _mesa_set_viewport(ctx, 0, 0, 694 ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); 695 } 696 /* save depth range state */ 697 save->DepthNear = ctx->Viewport.Near; 698 save->DepthFar = ctx->Viewport.Far; 699 /* set depth range to default */ 700 _mesa_DepthRange(0.0, 1.0); 701 } 702 703 if (state & MESA_META_CLAMP_FRAGMENT_COLOR) { 704 save->ClampFragmentColor = ctx->Color.ClampFragmentColor; 705 706 /* Generally in here we want to do clamping according to whether 707 * it's for the pixel path (ClampFragmentColor is GL_TRUE), 708 * regardless of the internal implementation of the metaops. 709 */ 710 if (ctx->Color.ClampFragmentColor != GL_TRUE) 711 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 712 } 713 714 if (state & MESA_META_CLAMP_VERTEX_COLOR) { 715 save->ClampVertexColor = ctx->Light.ClampVertexColor; 716 717 /* Generally in here we never want vertex color clamping -- 718 * result clamping is only dependent on fragment clamping. 719 */ 720 _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, GL_FALSE); 721 } 722 723 if (state & MESA_META_CONDITIONAL_RENDER) { 724 save->CondRenderQuery = ctx->Query.CondRenderQuery; 725 save->CondRenderMode = ctx->Query.CondRenderMode; 726 727 if (ctx->Query.CondRenderQuery) 728 _mesa_EndConditionalRender(); 729 } 730 731#if FEATURE_feedback 732 if (state & MESA_META_SELECT_FEEDBACK) { 733 save->RenderMode = ctx->RenderMode; 734 if (ctx->RenderMode == GL_SELECT) { 735 save->Select = ctx->Select; /* struct copy */ 736 _mesa_RenderMode(GL_RENDER); 737 } else if (ctx->RenderMode == GL_FEEDBACK) { 738 save->Feedback = ctx->Feedback; /* struct copy */ 739 _mesa_RenderMode(GL_RENDER); 740 } 741 } 742#endif 743 744 if (state & MESA_META_MULTISAMPLE) { 745 save->MultisampleEnabled = ctx->Multisample.Enabled; 746 if (ctx->Multisample.Enabled) 747 _mesa_set_enable(ctx, GL_MULTISAMPLE, GL_FALSE); 748 } 749 750 /* misc */ 751 { 752 save->Lighting = ctx->Light.Enabled; 753 if (ctx->Light.Enabled) 754 _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE); 755 save->RasterDiscard = ctx->RasterDiscard; 756 if (ctx->RasterDiscard) 757 _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_FALSE); 758 } 759} 760 761 762/** 763 * Leave meta state. This is like a light-weight version of glPopAttrib(). 764 */ 765void 766_mesa_meta_end(struct gl_context *ctx) 767{ 768 struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth]; 769 const GLbitfield state = save->SavedState; 770 771 if (state & MESA_META_ALPHA_TEST) { 772 if (ctx->Color.AlphaEnabled != save->AlphaEnabled) 773 _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled); 774 _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef); 775 } 776 777 if (state & MESA_META_BLEND) { 778 if (ctx->Color.BlendEnabled != save->BlendEnabled) { 779 if (ctx->Extensions.EXT_draw_buffers2) { 780 GLuint i; 781 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 782 _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1); 783 } 784 } 785 else { 786 _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1)); 787 } 788 } 789 if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled) 790 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); 791 } 792 793 if (state & MESA_META_COLOR_MASK) { 794 GLuint i; 795 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 796 if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) { 797 if (i == 0) { 798 _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1], 799 save->ColorMask[i][2], save->ColorMask[i][3]); 800 } 801 else { 802 _mesa_ColorMaskIndexed(i, 803 save->ColorMask[i][0], 804 save->ColorMask[i][1], 805 save->ColorMask[i][2], 806 save->ColorMask[i][3]); 807 } 808 } 809 } 810 } 811 812 if (state & MESA_META_DEPTH_TEST) { 813 if (ctx->Depth.Test != save->Depth.Test) 814 _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test); 815 _mesa_DepthFunc(save->Depth.Func); 816 _mesa_DepthMask(save->Depth.Mask); 817 } 818 819 if (state & MESA_META_FOG) { 820 _mesa_set_enable(ctx, GL_FOG, save->Fog); 821 } 822 823 if (state & MESA_META_PIXEL_STORE) { 824 ctx->Pack = save->Pack; 825 ctx->Unpack = save->Unpack; 826 } 827 828 if (state & MESA_META_PIXEL_TRANSFER) { 829 ctx->Pixel.RedScale = save->RedScale; 830 ctx->Pixel.RedBias = save->RedBias; 831 ctx->Pixel.GreenScale = save->GreenScale; 832 ctx->Pixel.GreenBias = save->GreenBias; 833 ctx->Pixel.BlueScale = save->BlueScale; 834 ctx->Pixel.BlueBias = save->BlueBias; 835 ctx->Pixel.AlphaScale = save->AlphaScale; 836 ctx->Pixel.AlphaBias = save->AlphaBias; 837 ctx->Pixel.MapColorFlag = save->MapColorFlag; 838 /* XXX more state */ 839 ctx->NewState |=_NEW_PIXEL; 840 } 841 842 if (state & MESA_META_RASTERIZATION) { 843 _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode); 844 _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); 845 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple); 846 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset); 847 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth); 848 _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull); 849 } 850 851 if (state & MESA_META_SCISSOR) { 852 _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled); 853 _mesa_Scissor(save->Scissor.X, save->Scissor.Y, 854 save->Scissor.Width, save->Scissor.Height); 855 } 856 857 if (state & MESA_META_SHADER) { 858 if (ctx->Extensions.ARB_vertex_program) { 859 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, 860 save->VertexProgramEnabled); 861 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, 862 save->VertexProgram); 863 _mesa_reference_vertprog(ctx, &save->VertexProgram, NULL); 864 } 865 866 if (ctx->Extensions.ARB_fragment_program) { 867 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, 868 save->FragmentProgramEnabled); 869 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, 870 save->FragmentProgram); 871 _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL); 872 } 873 874 if (ctx->Extensions.ARB_vertex_shader) 875 _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader); 876 877 if (ctx->Extensions.ARB_geometry_shader4) 878 _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, 879 save->GeometryShader); 880 881 if (ctx->Extensions.ARB_fragment_shader) 882 _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, 883 save->FragmentShader); 884 885 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, 886 save->ActiveShader); 887 888 _mesa_reference_shader_program(ctx, &save->VertexShader, NULL); 889 _mesa_reference_shader_program(ctx, &save->GeometryShader, NULL); 890 _mesa_reference_shader_program(ctx, &save->FragmentShader, NULL); 891 _mesa_reference_shader_program(ctx, &save->ActiveShader, NULL); 892 } 893 894 if (state & MESA_META_STENCIL_TEST) { 895 const struct gl_stencil_attrib *stencil = &save->Stencil; 896 897 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); 898 _mesa_ClearStencil(stencil->Clear); 899 if (ctx->Extensions.EXT_stencil_two_side) { 900 _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, 901 stencil->TestTwoSide); 902 _mesa_ActiveStencilFaceEXT(stencil->ActiveFace 903 ? GL_BACK : GL_FRONT); 904 } 905 /* front state */ 906 _mesa_StencilFuncSeparate(GL_FRONT, 907 stencil->Function[0], 908 stencil->Ref[0], 909 stencil->ValueMask[0]); 910 _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]); 911 _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0], 912 stencil->ZFailFunc[0], 913 stencil->ZPassFunc[0]); 914 /* back state */ 915 _mesa_StencilFuncSeparate(GL_BACK, 916 stencil->Function[1], 917 stencil->Ref[1], 918 stencil->ValueMask[1]); 919 _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]); 920 _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1], 921 stencil->ZFailFunc[1], 922 stencil->ZPassFunc[1]); 923 } 924 925 if (state & MESA_META_TEXTURE) { 926 GLuint u, tgt; 927 928 ASSERT(ctx->Texture.CurrentUnit == 0); 929 930 /* restore texenv for unit[0] */ 931 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode); 932 933 /* restore texture objects for unit[0] only */ 934 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 935 if (ctx->Texture.Unit[0].CurrentTex[tgt] != save->CurrentTexture[tgt]) { 936 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 937 _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt], 938 save->CurrentTexture[tgt]); 939 } 940 _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL); 941 } 942 943 /* Restore fixed function texture enables, texgen */ 944 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 945 if (ctx->Texture.Unit[u].Enabled != save->TexEnabled[u]) { 946 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 947 ctx->Texture.Unit[u].Enabled = save->TexEnabled[u]; 948 } 949 950 if (ctx->Texture.Unit[u].TexGenEnabled != save->TexGenEnabled[u]) { 951 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 952 ctx->Texture.Unit[u].TexGenEnabled = save->TexGenEnabled[u]; 953 } 954 } 955 956 /* restore current unit state */ 957 _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit); 958 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit); 959 } 960 961 if (state & MESA_META_TRANSFORM) { 962 GLuint activeTexture = ctx->Texture.CurrentUnit; 963 _mesa_ActiveTextureARB(GL_TEXTURE0); 964 _mesa_MatrixMode(GL_TEXTURE); 965 _mesa_LoadMatrixf(save->TextureMatrix); 966 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture); 967 968 _mesa_MatrixMode(GL_MODELVIEW); 969 _mesa_LoadMatrixf(save->ModelviewMatrix); 970 971 _mesa_MatrixMode(GL_PROJECTION); 972 _mesa_LoadMatrixf(save->ProjectionMatrix); 973 974 _mesa_MatrixMode(save->MatrixMode); 975 } 976 977 if (state & MESA_META_CLIP) { 978 if (save->ClipPlanesEnabled) { 979 GLuint i; 980 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { 981 if (save->ClipPlanesEnabled & (1 << i)) { 982 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); 983 } 984 } 985 } 986 } 987 988 if (state & MESA_META_VERTEX) { 989 /* restore vertex buffer object */ 990 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name); 991 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL); 992 993 /* restore vertex array object */ 994 _mesa_BindVertexArray(save->ArrayObj->Name); 995 _mesa_reference_array_object(ctx, &save->ArrayObj, NULL); 996 } 997 998 if (state & MESA_META_VIEWPORT) { 999 if (save->ViewportX != ctx->Viewport.X || 1000 save->ViewportY != ctx->Viewport.Y || 1001 save->ViewportW != ctx->Viewport.Width || 1002 save->ViewportH != ctx->Viewport.Height) { 1003 _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY, 1004 save->ViewportW, save->ViewportH); 1005 } 1006 _mesa_DepthRange(save->DepthNear, save->DepthFar); 1007 } 1008 1009 if (state & MESA_META_CLAMP_FRAGMENT_COLOR) { 1010 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor); 1011 } 1012 1013 if (state & MESA_META_CLAMP_VERTEX_COLOR) { 1014 _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor); 1015 } 1016 1017 if (state & MESA_META_CONDITIONAL_RENDER) { 1018 if (save->CondRenderQuery) 1019 _mesa_BeginConditionalRender(save->CondRenderQuery->Id, 1020 save->CondRenderMode); 1021 } 1022 1023#if FEATURE_feedback 1024 if (state & MESA_META_SELECT_FEEDBACK) { 1025 if (save->RenderMode == GL_SELECT) { 1026 _mesa_RenderMode(GL_SELECT); 1027 ctx->Select = save->Select; 1028 } else if (save->RenderMode == GL_FEEDBACK) { 1029 _mesa_RenderMode(GL_FEEDBACK); 1030 ctx->Feedback = save->Feedback; 1031 } 1032 } 1033#endif 1034 1035 if (state & MESA_META_MULTISAMPLE) { 1036 if (ctx->Multisample.Enabled != save->MultisampleEnabled) 1037 _mesa_set_enable(ctx, GL_MULTISAMPLE, save->MultisampleEnabled); 1038 } 1039 1040 /* misc */ 1041 if (save->Lighting) { 1042 _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE); 1043 } 1044 if (save->RasterDiscard) { 1045 _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE); 1046 } 1047#if FEATURE_EXT_transform_feedback 1048 if (save->TransformFeedbackNeedsResume) 1049 _mesa_ResumeTransformFeedback(); 1050#endif 1051} 1052 1053 1054/** 1055 * Determine whether Mesa is currently in a meta state. 1056 */ 1057GLboolean 1058_mesa_meta_in_progress(struct gl_context *ctx) 1059{ 1060 return ctx->Meta->SaveStackDepth != 0; 1061} 1062 1063 1064/** 1065 * Convert Z from a normalized value in the range [0, 1] to an object-space 1066 * Z coordinate in [-1, +1] so that drawing at the new Z position with the 1067 * default/identity ortho projection results in the original Z value. 1068 * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z 1069 * value comes from the clear value or raster position. 1070 */ 1071static INLINE GLfloat 1072invert_z(GLfloat normZ) 1073{ 1074 GLfloat objZ = 1.0f - 2.0f * normZ; 1075 return objZ; 1076} 1077 1078 1079/** 1080 * One-time init for a temp_texture object. 1081 * Choose tex target, compute max tex size, etc. 1082 */ 1083static void 1084init_temp_texture(struct gl_context *ctx, struct temp_texture *tex) 1085{ 1086 /* prefer texture rectangle */ 1087 if (ctx->Extensions.NV_texture_rectangle) { 1088 tex->Target = GL_TEXTURE_RECTANGLE; 1089 tex->MaxSize = ctx->Const.MaxTextureRectSize; 1090 tex->NPOT = GL_TRUE; 1091 } 1092 else { 1093 /* use 2D texture, NPOT if possible */ 1094 tex->Target = GL_TEXTURE_2D; 1095 tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1096 tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two; 1097 } 1098 tex->MinSize = 16; /* 16 x 16 at least */ 1099 assert(tex->MaxSize > 0); 1100 1101 _mesa_GenTextures(1, &tex->TexObj); 1102} 1103 1104static void 1105cleanup_temp_texture(struct gl_context *ctx, struct temp_texture *tex) 1106{ 1107 if (!tex->TexObj) 1108 return; 1109 _mesa_DeleteTextures(1, &tex->TexObj); 1110 tex->TexObj = 0; 1111} 1112 1113 1114/** 1115 * Return pointer to temp_texture info for non-bitmap ops. 1116 * This does some one-time init if needed. 1117 */ 1118static struct temp_texture * 1119get_temp_texture(struct gl_context *ctx) 1120{ 1121 struct temp_texture *tex = &ctx->Meta->TempTex; 1122 1123 if (!tex->TexObj) { 1124 init_temp_texture(ctx, tex); 1125 } 1126 1127 return tex; 1128} 1129 1130 1131/** 1132 * Return pointer to temp_texture info for _mesa_meta_bitmap(). 1133 * We use a separate texture for bitmaps to reduce texture 1134 * allocation/deallocation. 1135 */ 1136static struct temp_texture * 1137get_bitmap_temp_texture(struct gl_context *ctx) 1138{ 1139 struct temp_texture *tex = &ctx->Meta->Bitmap.Tex; 1140 1141 if (!tex->TexObj) { 1142 init_temp_texture(ctx, tex); 1143 } 1144 1145 return tex; 1146} 1147 1148 1149/** 1150 * Compute the width/height of texture needed to draw an image of the 1151 * given size. Return a flag indicating whether the current texture 1152 * can be re-used (glTexSubImage2D) or if a new texture needs to be 1153 * allocated (glTexImage2D). 1154 * Also, compute s/t texcoords for drawing. 1155 * 1156 * \return GL_TRUE if new texture is needed, GL_FALSE otherwise 1157 */ 1158static GLboolean 1159alloc_texture(struct temp_texture *tex, 1160 GLsizei width, GLsizei height, GLenum intFormat) 1161{ 1162 GLboolean newTex = GL_FALSE; 1163 1164 ASSERT(width <= tex->MaxSize); 1165 ASSERT(height <= tex->MaxSize); 1166 1167 if (width > tex->Width || 1168 height > tex->Height || 1169 intFormat != tex->IntFormat) { 1170 /* alloc new texture (larger or different format) */ 1171 1172 if (tex->NPOT) { 1173 /* use non-power of two size */ 1174 tex->Width = MAX2(tex->MinSize, width); 1175 tex->Height = MAX2(tex->MinSize, height); 1176 } 1177 else { 1178 /* find power of two size */ 1179 GLsizei w, h; 1180 w = h = tex->MinSize; 1181 while (w < width) 1182 w *= 2; 1183 while (h < height) 1184 h *= 2; 1185 tex->Width = w; 1186 tex->Height = h; 1187 } 1188 1189 tex->IntFormat = intFormat; 1190 1191 newTex = GL_TRUE; 1192 } 1193 1194 /* compute texcoords */ 1195 if (tex->Target == GL_TEXTURE_RECTANGLE) { 1196 tex->Sright = (GLfloat) width; 1197 tex->Ttop = (GLfloat) height; 1198 } 1199 else { 1200 tex->Sright = (GLfloat) width / tex->Width; 1201 tex->Ttop = (GLfloat) height / tex->Height; 1202 } 1203 1204 return newTex; 1205} 1206 1207 1208/** 1209 * Setup/load texture for glCopyPixels or glBlitFramebuffer. 1210 */ 1211static void 1212setup_copypix_texture(struct temp_texture *tex, 1213 GLboolean newTex, 1214 GLint srcX, GLint srcY, 1215 GLsizei width, GLsizei height, GLenum intFormat, 1216 GLenum filter) 1217{ 1218 _mesa_BindTexture(tex->Target, tex->TexObj); 1219 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter); 1220 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter); 1221 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1222 1223 /* copy framebuffer image to texture */ 1224 if (newTex) { 1225 /* create new tex image */ 1226 if (tex->Width == width && tex->Height == height) { 1227 /* create new tex with framebuffer data */ 1228 _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat, 1229 srcX, srcY, width, height, 0); 1230 } 1231 else { 1232 /* create empty texture */ 1233 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, 1234 tex->Width, tex->Height, 0, 1235 intFormat, GL_UNSIGNED_BYTE, NULL); 1236 /* load image */ 1237 _mesa_CopyTexSubImage2D(tex->Target, 0, 1238 0, 0, srcX, srcY, width, height); 1239 } 1240 } 1241 else { 1242 /* replace existing tex image */ 1243 _mesa_CopyTexSubImage2D(tex->Target, 0, 1244 0, 0, srcX, srcY, width, height); 1245 } 1246} 1247 1248 1249/** 1250 * Setup/load texture for glDrawPixels. 1251 */ 1252static void 1253setup_drawpix_texture(struct gl_context *ctx, 1254 struct temp_texture *tex, 1255 GLboolean newTex, 1256 GLenum texIntFormat, 1257 GLsizei width, GLsizei height, 1258 GLenum format, GLenum type, 1259 const GLvoid *pixels) 1260{ 1261 _mesa_BindTexture(tex->Target, tex->TexObj); 1262 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1263 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1264 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1265 1266 /* copy pixel data to texture */ 1267 if (newTex) { 1268 /* create new tex image */ 1269 if (tex->Width == width && tex->Height == height) { 1270 /* create new tex and load image data */ 1271 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, 1272 tex->Width, tex->Height, 0, format, type, pixels); 1273 } 1274 else { 1275 struct gl_buffer_object *save_unpack_obj = NULL; 1276 1277 _mesa_reference_buffer_object(ctx, &save_unpack_obj, 1278 ctx->Unpack.BufferObj); 1279 _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); 1280 /* create empty texture */ 1281 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, 1282 tex->Width, tex->Height, 0, format, type, NULL); 1283 if (save_unpack_obj != NULL) 1284 _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 1285 save_unpack_obj->Name); 1286 /* load image */ 1287 _mesa_TexSubImage2D(tex->Target, 0, 1288 0, 0, width, height, format, type, pixels); 1289 } 1290 } 1291 else { 1292 /* replace existing tex image */ 1293 _mesa_TexSubImage2D(tex->Target, 0, 1294 0, 0, width, height, format, type, pixels); 1295 } 1296} 1297 1298 1299 1300/** 1301 * One-time init for drawing depth pixels. 1302 */ 1303static void 1304init_blit_depth_pixels(struct gl_context *ctx) 1305{ 1306 static const char *program = 1307 "!!ARBfp1.0\n" 1308 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" 1309 "END \n"; 1310 char program2[200]; 1311 struct blit_state *blit = &ctx->Meta->Blit; 1312 struct temp_texture *tex = get_temp_texture(ctx); 1313 const char *texTarget; 1314 1315 assert(blit->DepthFP == 0); 1316 1317 /* replace %s with "RECT" or "2D" */ 1318 assert(strlen(program) + 4 < sizeof(program2)); 1319 if (tex->Target == GL_TEXTURE_RECTANGLE) 1320 texTarget = "RECT"; 1321 else 1322 texTarget = "2D"; 1323 _mesa_snprintf(program2, sizeof(program2), program, texTarget); 1324 1325 _mesa_GenPrograms(1, &blit->DepthFP); 1326 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); 1327 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 1328 strlen(program2), (const GLubyte *) program2); 1329} 1330 1331 1332/** 1333 * Try to do a glBlitFramebuffer using no-copy texturing. 1334 * We can do this when the src renderbuffer is actually a texture. 1335 * But if the src buffer == dst buffer we cannot do this. 1336 * 1337 * \return new buffer mask indicating the buffers left to blit using the 1338 * normal path. 1339 */ 1340static GLbitfield 1341blitframebuffer_texture(struct gl_context *ctx, 1342 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1343 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1344 GLbitfield mask, GLenum filter) 1345{ 1346 if (mask & GL_COLOR_BUFFER_BIT) { 1347 const struct gl_framebuffer *drawFb = ctx->DrawBuffer; 1348 const struct gl_framebuffer *readFb = ctx->ReadBuffer; 1349 const struct gl_renderbuffer_attachment *drawAtt = 1350 &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]]; 1351 const struct gl_renderbuffer_attachment *readAtt = 1352 &readFb->Attachment[readFb->_ColorReadBufferIndex]; 1353 1354 if (readAtt && readAtt->Texture) { 1355 const struct gl_texture_object *texObj = readAtt->Texture; 1356 const GLuint srcLevel = readAtt->TextureLevel; 1357 const GLint baseLevelSave = texObj->BaseLevel; 1358 const GLint maxLevelSave = texObj->MaxLevel; 1359 const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled; 1360 const GLenum target = texObj->Target; 1361 GLuint sampler, samplerSave = 1362 ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? 1363 ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; 1364 1365 if (drawAtt->Texture == readAtt->Texture) { 1366 /* Can't use same texture as both the source and dest. We need 1367 * to handle overlapping blits and besides, some hw may not 1368 * support this. 1369 */ 1370 return mask; 1371 } 1372 1373 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) { 1374 /* Can't handle other texture types at this time */ 1375 return mask; 1376 } 1377 1378 _mesa_GenSamplers(1, &sampler); 1379 _mesa_BindSampler(ctx->Texture.CurrentUnit, sampler); 1380 1381 /* 1382 printf("Blit from texture!\n"); 1383 printf(" srcAtt %p dstAtt %p\n", readAtt, drawAtt); 1384 printf(" srcTex %p dstText %p\n", texObj, drawAtt->Texture); 1385 */ 1386 1387 /* Prepare src texture state */ 1388 _mesa_BindTexture(target, texObj->Name); 1389 _mesa_SamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, filter); 1390 _mesa_SamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, filter); 1391 if (target != GL_TEXTURE_RECTANGLE_ARB) { 1392 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel); 1393 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); 1394 } 1395 _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1396 _mesa_SamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1397 1398 /* Always do our blits with no sRGB decode or encode.*/ 1399 if (ctx->Extensions.EXT_texture_sRGB_decode) { 1400 _mesa_SamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, 1401 GL_SKIP_DECODE_EXT); 1402 } 1403 if (ctx->Extensions.EXT_framebuffer_sRGB) { 1404 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE); 1405 } 1406 1407 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1408 _mesa_set_enable(ctx, target, GL_TRUE); 1409 1410 /* Prepare vertex data (the VBO was previously created and bound) */ 1411 { 1412 struct vertex { 1413 GLfloat x, y, s, t; 1414 }; 1415 struct vertex verts[4]; 1416 GLfloat s0, t0, s1, t1; 1417 1418 if (target == GL_TEXTURE_2D) { 1419 const struct gl_texture_image *texImage 1420 = _mesa_select_tex_image(ctx, texObj, target, srcLevel); 1421 s0 = srcX0 / (float) texImage->Width; 1422 s1 = srcX1 / (float) texImage->Width; 1423 t0 = srcY0 / (float) texImage->Height; 1424 t1 = srcY1 / (float) texImage->Height; 1425 } 1426 else { 1427 assert(target == GL_TEXTURE_RECTANGLE_ARB); 1428 s0 = srcX0; 1429 s1 = srcX1; 1430 t0 = srcY0; 1431 t1 = srcY1; 1432 } 1433 1434 verts[0].x = (GLfloat) dstX0; 1435 verts[0].y = (GLfloat) dstY0; 1436 verts[1].x = (GLfloat) dstX1; 1437 verts[1].y = (GLfloat) dstY0; 1438 verts[2].x = (GLfloat) dstX1; 1439 verts[2].y = (GLfloat) dstY1; 1440 verts[3].x = (GLfloat) dstX0; 1441 verts[3].y = (GLfloat) dstY1; 1442 1443 verts[0].s = s0; 1444 verts[0].t = t0; 1445 verts[1].s = s1; 1446 verts[1].t = t0; 1447 verts[2].s = s1; 1448 verts[2].t = t1; 1449 verts[3].s = s0; 1450 verts[3].t = t1; 1451 1452 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 1453 } 1454 1455 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1456 1457 /* Restore texture object state, the texture binding will 1458 * be restored by _mesa_meta_end(). 1459 */ 1460 if (target != GL_TEXTURE_RECTANGLE_ARB) { 1461 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave); 1462 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); 1463 } 1464 if (ctx->Extensions.EXT_framebuffer_sRGB && fbo_srgb_save) { 1465 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE); 1466 } 1467 1468 _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); 1469 _mesa_DeleteSamplers(1, &sampler); 1470 1471 /* Done with color buffer */ 1472 mask &= ~GL_COLOR_BUFFER_BIT; 1473 } 1474 } 1475 1476 return mask; 1477} 1478 1479 1480/** 1481 * Meta implementation of ctx->Driver.BlitFramebuffer() in terms 1482 * of texture mapping and polygon rendering. 1483 */ 1484void 1485_mesa_meta_BlitFramebuffer(struct gl_context *ctx, 1486 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1487 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1488 GLbitfield mask, GLenum filter) 1489{ 1490 struct blit_state *blit = &ctx->Meta->Blit; 1491 struct temp_texture *tex = get_temp_texture(ctx); 1492 const GLsizei maxTexSize = tex->MaxSize; 1493 const GLint srcX = MIN2(srcX0, srcX1); 1494 const GLint srcY = MIN2(srcY0, srcY1); 1495 const GLint srcW = abs(srcX1 - srcX0); 1496 const GLint srcH = abs(srcY1 - srcY0); 1497 const GLboolean srcFlipX = srcX1 < srcX0; 1498 const GLboolean srcFlipY = srcY1 < srcY0; 1499 struct vertex { 1500 GLfloat x, y, s, t; 1501 }; 1502 struct vertex verts[4]; 1503 GLboolean newTex; 1504 1505 /* In addition to falling back if the blit size is larger than the maximum 1506 * texture size, fallback if the source is multisampled. This fallback can 1507 * be removed once Mesa gets support ARB_texture_multisample. 1508 */ 1509 if (srcW > maxTexSize || srcH > maxTexSize 1510 || ctx->ReadBuffer->Visual.samples > 0) { 1511 /* XXX avoid this fallback */ 1512 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, 1513 dstX0, dstY0, dstX1, dstY1, mask, filter); 1514 return; 1515 } 1516 1517 if (srcFlipX) { 1518 GLint tmp = dstX0; 1519 dstX0 = dstX1; 1520 dstX1 = tmp; 1521 } 1522 1523 if (srcFlipY) { 1524 GLint tmp = dstY0; 1525 dstY0 = dstY1; 1526 dstY1 = tmp; 1527 } 1528 1529 /* only scissor effects blit so save/clear all other relevant state */ 1530 _mesa_meta_begin(ctx, ~MESA_META_SCISSOR); 1531 1532 if (blit->ArrayObj == 0) { 1533 /* one-time setup */ 1534 1535 /* create vertex array object */ 1536 _mesa_GenVertexArrays(1, &blit->ArrayObj); 1537 _mesa_BindVertexArray(blit->ArrayObj); 1538 1539 /* create vertex array buffer */ 1540 _mesa_GenBuffersARB(1, &blit->VBO); 1541 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO); 1542 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 1543 NULL, GL_DYNAMIC_DRAW_ARB); 1544 1545 /* setup vertex arrays */ 1546 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 1547 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 1548 _mesa_EnableClientState(GL_VERTEX_ARRAY); 1549 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 1550 } 1551 else { 1552 _mesa_BindVertexArray(blit->ArrayObj); 1553 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO); 1554 } 1555 1556 /* Try faster, direct texture approach first */ 1557 mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1, 1558 dstX0, dstY0, dstX1, dstY1, mask, filter); 1559 if (mask == 0x0) { 1560 _mesa_meta_end(ctx); 1561 return; 1562 } 1563 1564 /* Continue with "normal" approach which involves copying the src rect 1565 * into a temporary texture and is "blitted" by drawing a textured quad. 1566 */ 1567 1568 newTex = alloc_texture(tex, srcW, srcH, GL_RGBA); 1569 1570 /* vertex positions/texcoords (after texture allocation!) */ 1571 { 1572 verts[0].x = (GLfloat) dstX0; 1573 verts[0].y = (GLfloat) dstY0; 1574 verts[1].x = (GLfloat) dstX1; 1575 verts[1].y = (GLfloat) dstY0; 1576 verts[2].x = (GLfloat) dstX1; 1577 verts[2].y = (GLfloat) dstY1; 1578 verts[3].x = (GLfloat) dstX0; 1579 verts[3].y = (GLfloat) dstY1; 1580 1581 verts[0].s = 0.0F; 1582 verts[0].t = 0.0F; 1583 verts[1].s = tex->Sright; 1584 verts[1].t = 0.0F; 1585 verts[2].s = tex->Sright; 1586 verts[2].t = tex->Ttop; 1587 verts[3].s = 0.0F; 1588 verts[3].t = tex->Ttop; 1589 1590 /* upload new vertex data */ 1591 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 1592 } 1593 1594 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 1595 1596 if (mask & GL_COLOR_BUFFER_BIT) { 1597 setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH, 1598 GL_RGBA, filter); 1599 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1600 mask &= ~GL_COLOR_BUFFER_BIT; 1601 } 1602 1603 if (mask & GL_DEPTH_BUFFER_BIT) { 1604 GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint)); 1605 if (tmp) { 1606 if (!blit->DepthFP) 1607 init_blit_depth_pixels(ctx); 1608 1609 /* maybe change tex format here */ 1610 newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT); 1611 1612 _mesa_ReadPixels(srcX, srcY, srcW, srcH, 1613 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); 1614 1615 setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH, 1616 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); 1617 1618 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); 1619 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); 1620 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1621 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); 1622 _mesa_DepthFunc(GL_ALWAYS); 1623 _mesa_DepthMask(GL_TRUE); 1624 1625 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1626 mask &= ~GL_DEPTH_BUFFER_BIT; 1627 1628 free(tmp); 1629 } 1630 } 1631 1632 if (mask & GL_STENCIL_BUFFER_BIT) { 1633 /* XXX can't easily do stencil */ 1634 } 1635 1636 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 1637 1638 _mesa_meta_end(ctx); 1639 1640 if (mask) { 1641 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, 1642 dstX0, dstY0, dstX1, dstY1, mask, filter); 1643 } 1644} 1645 1646static void 1647meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit) 1648{ 1649 if (blit->ArrayObj) { 1650 _mesa_DeleteVertexArraysAPPLE(1, &blit->ArrayObj); 1651 blit->ArrayObj = 0; 1652 _mesa_DeleteBuffersARB(1, &blit->VBO); 1653 blit->VBO = 0; 1654 } 1655 if (blit->DepthFP) { 1656 _mesa_DeletePrograms(1, &blit->DepthFP); 1657 blit->DepthFP = 0; 1658 } 1659} 1660 1661 1662/** 1663 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. 1664 */ 1665void 1666_mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers) 1667{ 1668 struct clear_state *clear = &ctx->Meta->Clear; 1669 struct vertex { 1670 GLfloat x, y, z, r, g, b, a; 1671 }; 1672 struct vertex verts[4]; 1673 /* save all state but scissor, pixel pack/unpack */ 1674 GLbitfield metaSave = (MESA_META_ALL - 1675 MESA_META_SCISSOR - 1676 MESA_META_PIXEL_STORE - 1677 MESA_META_CONDITIONAL_RENDER); 1678 const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 1679 1680 if (buffers & BUFFER_BITS_COLOR) { 1681 /* if clearing color buffers, don't save/restore colormask */ 1682 metaSave -= MESA_META_COLOR_MASK; 1683 } 1684 1685 _mesa_meta_begin(ctx, metaSave); 1686 1687 if (clear->ArrayObj == 0) { 1688 /* one-time setup */ 1689 1690 /* create vertex array object */ 1691 _mesa_GenVertexArrays(1, &clear->ArrayObj); 1692 _mesa_BindVertexArray(clear->ArrayObj); 1693 1694 /* create vertex array buffer */ 1695 _mesa_GenBuffersARB(1, &clear->VBO); 1696 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1697 1698 /* setup vertex arrays */ 1699 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 1700 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); 1701 _mesa_EnableClientState(GL_VERTEX_ARRAY); 1702 _mesa_EnableClientState(GL_COLOR_ARRAY); 1703 } 1704 else { 1705 _mesa_BindVertexArray(clear->ArrayObj); 1706 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1707 } 1708 1709 /* GL_COLOR_BUFFER_BIT */ 1710 if (buffers & BUFFER_BITS_COLOR) { 1711 /* leave colormask, glDrawBuffer state as-is */ 1712 1713 /* Clears never have the color clamped. */ 1714 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 1715 } 1716 else { 1717 ASSERT(metaSave & MESA_META_COLOR_MASK); 1718 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1719 } 1720 1721 /* GL_DEPTH_BUFFER_BIT */ 1722 if (buffers & BUFFER_BIT_DEPTH) { 1723 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); 1724 _mesa_DepthFunc(GL_ALWAYS); 1725 _mesa_DepthMask(GL_TRUE); 1726 } 1727 else { 1728 assert(!ctx->Depth.Test); 1729 } 1730 1731 /* GL_STENCIL_BUFFER_BIT */ 1732 if (buffers & BUFFER_BIT_STENCIL) { 1733 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); 1734 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, 1735 GL_REPLACE, GL_REPLACE, GL_REPLACE); 1736 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 1737 ctx->Stencil.Clear & stencilMax, 1738 ctx->Stencil.WriteMask[0]); 1739 } 1740 else { 1741 assert(!ctx->Stencil.Enabled); 1742 } 1743 1744 /* vertex positions/colors */ 1745 { 1746 const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin; 1747 const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin; 1748 const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax; 1749 const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax; 1750 const GLfloat z = invert_z(ctx->Depth.Clear); 1751 GLuint i; 1752 1753 verts[0].x = x0; 1754 verts[0].y = y0; 1755 verts[0].z = z; 1756 verts[1].x = x1; 1757 verts[1].y = y0; 1758 verts[1].z = z; 1759 verts[2].x = x1; 1760 verts[2].y = y1; 1761 verts[2].z = z; 1762 verts[3].x = x0; 1763 verts[3].y = y1; 1764 verts[3].z = z; 1765 1766 /* vertex colors */ 1767 for (i = 0; i < 4; i++) { 1768 verts[i].r = ctx->Color.ClearColor.f[0]; 1769 verts[i].g = ctx->Color.ClearColor.f[1]; 1770 verts[i].b = ctx->Color.ClearColor.f[2]; 1771 verts[i].a = ctx->Color.ClearColor.f[3]; 1772 } 1773 1774 /* upload new vertex data */ 1775 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, 1776 GL_DYNAMIC_DRAW_ARB); 1777 } 1778 1779 /* draw quad */ 1780 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 1781 1782 _mesa_meta_end(ctx); 1783} 1784 1785static void 1786meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) 1787{ 1788 const char *vs_source = 1789 "attribute vec4 position;\n" 1790 "void main()\n" 1791 "{\n" 1792 " gl_Position = position;\n" 1793 "}\n"; 1794 const char *fs_source = 1795 "uniform vec4 color;\n" 1796 "void main()\n" 1797 "{\n" 1798 " gl_FragColor = color;\n" 1799 "}\n"; 1800 const char *vs_int_source = 1801 "#version 130\n" 1802 "attribute vec4 position;\n" 1803 "void main()\n" 1804 "{\n" 1805 " gl_Position = position;\n" 1806 "}\n"; 1807 const char *fs_int_source = 1808 "#version 130\n" 1809 "uniform ivec4 color;\n" 1810 "out ivec4 out_color;\n" 1811 "\n" 1812 "void main()\n" 1813 "{\n" 1814 " out_color = color;\n" 1815 "}\n"; 1816 GLuint vs, fs; 1817 1818 if (clear->ArrayObj != 0) 1819 return; 1820 1821 /* create vertex array object */ 1822 _mesa_GenVertexArrays(1, &clear->ArrayObj); 1823 _mesa_BindVertexArray(clear->ArrayObj); 1824 1825 /* create vertex array buffer */ 1826 _mesa_GenBuffersARB(1, &clear->VBO); 1827 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1828 1829 /* setup vertex arrays */ 1830 _mesa_VertexAttribPointerARB(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); 1831 _mesa_EnableVertexAttribArrayARB(0); 1832 1833 vs = _mesa_CreateShaderObjectARB(GL_VERTEX_SHADER); 1834 _mesa_ShaderSourceARB(vs, 1, &vs_source, NULL); 1835 _mesa_CompileShaderARB(vs); 1836 1837 fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER); 1838 _mesa_ShaderSourceARB(fs, 1, &fs_source, NULL); 1839 _mesa_CompileShaderARB(fs); 1840 1841 clear->ShaderProg = _mesa_CreateProgramObjectARB(); 1842 _mesa_AttachShader(clear->ShaderProg, fs); 1843 _mesa_DeleteObjectARB(fs); 1844 _mesa_AttachShader(clear->ShaderProg, vs); 1845 _mesa_DeleteObjectARB(vs); 1846 _mesa_BindAttribLocationARB(clear->ShaderProg, 0, "position"); 1847 _mesa_LinkProgramARB(clear->ShaderProg); 1848 1849 clear->ColorLocation = _mesa_GetUniformLocationARB(clear->ShaderProg, 1850 "color"); 1851 1852 if (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130) { 1853 vs = compile_shader_with_debug(ctx, GL_VERTEX_SHADER, vs_int_source); 1854 fs = compile_shader_with_debug(ctx, GL_FRAGMENT_SHADER, fs_int_source); 1855 1856 clear->IntegerShaderProg = _mesa_CreateProgramObjectARB(); 1857 _mesa_AttachShader(clear->IntegerShaderProg, fs); 1858 _mesa_DeleteObjectARB(fs); 1859 _mesa_AttachShader(clear->IntegerShaderProg, vs); 1860 _mesa_DeleteObjectARB(vs); 1861 _mesa_BindAttribLocationARB(clear->IntegerShaderProg, 0, "position"); 1862 1863 /* Note that user-defined out attributes get automatically assigned 1864 * locations starting from 0, so we don't need to explicitly 1865 * BindFragDataLocation to 0. 1866 */ 1867 1868 link_program_with_debug(ctx, clear->IntegerShaderProg); 1869 1870 clear->IntegerColorLocation = 1871 _mesa_GetUniformLocationARB(clear->IntegerShaderProg, "color"); 1872 } 1873} 1874 1875static void 1876meta_glsl_clear_cleanup(struct gl_context *ctx, struct clear_state *clear) 1877{ 1878 if (clear->ArrayObj == 0) 1879 return; 1880 _mesa_DeleteVertexArraysAPPLE(1, &clear->ArrayObj); 1881 clear->ArrayObj = 0; 1882 _mesa_DeleteBuffersARB(1, &clear->VBO); 1883 clear->VBO = 0; 1884 _mesa_DeleteObjectARB(clear->ShaderProg); 1885 clear->ShaderProg = 0; 1886 1887 if (clear->IntegerShaderProg) { 1888 _mesa_DeleteObjectARB(clear->IntegerShaderProg); 1889 clear->IntegerShaderProg = 0; 1890 } 1891} 1892 1893/** 1894 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. 1895 */ 1896void 1897_mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) 1898{ 1899 struct clear_state *clear = &ctx->Meta->Clear; 1900 GLbitfield metaSave; 1901 const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 1902 struct gl_framebuffer *fb = ctx->DrawBuffer; 1903 const float x0 = ((float)fb->_Xmin / fb->Width) * 2.0f - 1.0f; 1904 const float y0 = ((float)fb->_Ymin / fb->Height) * 2.0f - 1.0f; 1905 const float x1 = ((float)fb->_Xmax / fb->Width) * 2.0f - 1.0f; 1906 const float y1 = ((float)fb->_Ymax / fb->Height) * 2.0f - 1.0f; 1907 const float z = -invert_z(ctx->Depth.Clear); 1908 struct vertex { 1909 GLfloat x, y, z; 1910 } verts[4]; 1911 1912 metaSave = (MESA_META_ALPHA_TEST | 1913 MESA_META_BLEND | 1914 MESA_META_DEPTH_TEST | 1915 MESA_META_RASTERIZATION | 1916 MESA_META_SHADER | 1917 MESA_META_STENCIL_TEST | 1918 MESA_META_VERTEX | 1919 MESA_META_VIEWPORT | 1920 MESA_META_CLIP | 1921 MESA_META_CLAMP_FRAGMENT_COLOR | 1922 MESA_META_MULTISAMPLE); 1923 1924 if (!(buffers & BUFFER_BITS_COLOR)) { 1925 /* We'll use colormask to disable color writes. Otherwise, 1926 * respect color mask 1927 */ 1928 metaSave |= MESA_META_COLOR_MASK; 1929 } 1930 1931 _mesa_meta_begin(ctx, metaSave); 1932 1933 meta_glsl_clear_init(ctx, clear); 1934 1935 if (fb->_IntegerColor) { 1936 _mesa_UseProgramObjectARB(clear->IntegerShaderProg); 1937 _mesa_Uniform4ivARB(clear->IntegerColorLocation, 1, 1938 ctx->Color.ClearColor.i); 1939 } else { 1940 _mesa_UseProgramObjectARB(clear->ShaderProg); 1941 _mesa_Uniform4fvARB(clear->ColorLocation, 1, 1942 ctx->Color.ClearColor.f); 1943 } 1944 1945 _mesa_BindVertexArray(clear->ArrayObj); 1946 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); 1947 1948 /* GL_COLOR_BUFFER_BIT */ 1949 if (buffers & BUFFER_BITS_COLOR) { 1950 /* leave colormask, glDrawBuffer state as-is */ 1951 1952 /* Clears never have the color clamped. */ 1953 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE); 1954 } 1955 else { 1956 ASSERT(metaSave & MESA_META_COLOR_MASK); 1957 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 1958 } 1959 1960 /* GL_DEPTH_BUFFER_BIT */ 1961 if (buffers & BUFFER_BIT_DEPTH) { 1962 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); 1963 _mesa_DepthFunc(GL_ALWAYS); 1964 _mesa_DepthMask(GL_TRUE); 1965 } 1966 else { 1967 assert(!ctx->Depth.Test); 1968 } 1969 1970 /* GL_STENCIL_BUFFER_BIT */ 1971 if (buffers & BUFFER_BIT_STENCIL) { 1972 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); 1973 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, 1974 GL_REPLACE, GL_REPLACE, GL_REPLACE); 1975 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, 1976 ctx->Stencil.Clear & stencilMax, 1977 ctx->Stencil.WriteMask[0]); 1978 } 1979 else { 1980 assert(!ctx->Stencil.Enabled); 1981 } 1982 1983 /* vertex positions */ 1984 verts[0].x = x0; 1985 verts[0].y = y0; 1986 verts[0].z = z; 1987 verts[1].x = x1; 1988 verts[1].y = y0; 1989 verts[1].z = z; 1990 verts[2].x = x1; 1991 verts[2].y = y1; 1992 verts[2].z = z; 1993 verts[3].x = x0; 1994 verts[3].y = y1; 1995 verts[3].z = z; 1996 1997 /* upload new vertex data */ 1998 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, 1999 GL_DYNAMIC_DRAW_ARB); 2000 2001 /* draw quad */ 2002 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2003 2004 _mesa_meta_end(ctx); 2005} 2006 2007/** 2008 * Meta implementation of ctx->Driver.CopyPixels() in terms 2009 * of texture mapping and polygon rendering and GLSL shaders. 2010 */ 2011void 2012_mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY, 2013 GLsizei width, GLsizei height, 2014 GLint dstX, GLint dstY, GLenum type) 2015{ 2016 struct copypix_state *copypix = &ctx->Meta->CopyPix; 2017 struct temp_texture *tex = get_temp_texture(ctx); 2018 struct vertex { 2019 GLfloat x, y, z, s, t; 2020 }; 2021 struct vertex verts[4]; 2022 GLboolean newTex; 2023 GLenum intFormat = GL_RGBA; 2024 2025 if (type != GL_COLOR || 2026 ctx->_ImageTransferState || 2027 ctx->Fog.Enabled || 2028 width > tex->MaxSize || 2029 height > tex->MaxSize) { 2030 /* XXX avoid this fallback */ 2031 _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type); 2032 return; 2033 } 2034 2035 /* Most GL state applies to glCopyPixels, but a there's a few things 2036 * we need to override: 2037 */ 2038 _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | 2039 MESA_META_SHADER | 2040 MESA_META_TEXTURE | 2041 MESA_META_TRANSFORM | 2042 MESA_META_CLIP | 2043 MESA_META_VERTEX | 2044 MESA_META_VIEWPORT)); 2045 2046 if (copypix->ArrayObj == 0) { 2047 /* one-time setup */ 2048 2049 /* create vertex array object */ 2050 _mesa_GenVertexArrays(1, ©pix->ArrayObj); 2051 _mesa_BindVertexArray(copypix->ArrayObj); 2052 2053 /* create vertex array buffer */ 2054 _mesa_GenBuffersARB(1, ©pix->VBO); 2055 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO); 2056 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 2057 NULL, GL_DYNAMIC_DRAW_ARB); 2058 2059 /* setup vertex arrays */ 2060 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2061 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 2062 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2063 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2064 } 2065 else { 2066 _mesa_BindVertexArray(copypix->ArrayObj); 2067 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO); 2068 } 2069 2070 newTex = alloc_texture(tex, width, height, intFormat); 2071 2072 /* vertex positions, texcoords (after texture allocation!) */ 2073 { 2074 const GLfloat dstX0 = (GLfloat) dstX; 2075 const GLfloat dstY0 = (GLfloat) dstY; 2076 const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX; 2077 const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY; 2078 const GLfloat z = invert_z(ctx->Current.RasterPos[2]); 2079 2080 verts[0].x = dstX0; 2081 verts[0].y = dstY0; 2082 verts[0].z = z; 2083 verts[0].s = 0.0F; 2084 verts[0].t = 0.0F; 2085 verts[1].x = dstX1; 2086 verts[1].y = dstY0; 2087 verts[1].z = z; 2088 verts[1].s = tex->Sright; 2089 verts[1].t = 0.0F; 2090 verts[2].x = dstX1; 2091 verts[2].y = dstY1; 2092 verts[2].z = z; 2093 verts[2].s = tex->Sright; 2094 verts[2].t = tex->Ttop; 2095 verts[3].x = dstX0; 2096 verts[3].y = dstY1; 2097 verts[3].z = z; 2098 verts[3].s = 0.0F; 2099 verts[3].t = tex->Ttop; 2100 2101 /* upload new vertex data */ 2102 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 2103 } 2104 2105 /* Alloc/setup texture */ 2106 setup_copypix_texture(tex, newTex, srcX, srcY, width, height, 2107 GL_RGBA, GL_NEAREST); 2108 2109 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 2110 2111 /* draw textured quad */ 2112 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2113 2114 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 2115 2116 _mesa_meta_end(ctx); 2117} 2118 2119 2120 2121/** 2122 * When the glDrawPixels() image size is greater than the max rectangle 2123 * texture size we use this function to break the glDrawPixels() image 2124 * into tiles which fit into the max texture size. 2125 */ 2126static void 2127tiled_draw_pixels(struct gl_context *ctx, 2128 GLint tileSize, 2129 GLint x, GLint y, GLsizei width, GLsizei height, 2130 GLenum format, GLenum type, 2131 const struct gl_pixelstore_attrib *unpack, 2132 const GLvoid *pixels) 2133{ 2134 struct gl_pixelstore_attrib tileUnpack = *unpack; 2135 GLint i, j; 2136 2137 if (tileUnpack.RowLength == 0) 2138 tileUnpack.RowLength = width; 2139 2140 for (i = 0; i < width; i += tileSize) { 2141 const GLint tileWidth = MIN2(tileSize, width - i); 2142 const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX); 2143 2144 tileUnpack.SkipPixels = unpack->SkipPixels + i; 2145 2146 for (j = 0; j < height; j += tileSize) { 2147 const GLint tileHeight = MIN2(tileSize, height - j); 2148 const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY); 2149 2150 tileUnpack.SkipRows = unpack->SkipRows + j; 2151 2152 _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight, 2153 format, type, &tileUnpack, pixels); 2154 } 2155 } 2156} 2157 2158 2159/** 2160 * One-time init for drawing stencil pixels. 2161 */ 2162static void 2163init_draw_stencil_pixels(struct gl_context *ctx) 2164{ 2165 /* This program is run eight times, once for each stencil bit. 2166 * The stencil values to draw are found in an 8-bit alpha texture. 2167 * We read the texture/stencil value and test if bit 'b' is set. 2168 * If the bit is not set, use KIL to kill the fragment. 2169 * Finally, we use the stencil test to update the stencil buffer. 2170 * 2171 * The basic algorithm for checking if a bit is set is: 2172 * if (is_odd(value / (1 << bit))) 2173 * result is one (or non-zero). 2174 * else 2175 * result is zero. 2176 * The program parameter contains three values: 2177 * parm.x = 255 / (1 << bit) 2178 * parm.y = 0.5 2179 * parm.z = 0.0 2180 */ 2181 static const char *program = 2182 "!!ARBfp1.0\n" 2183 "PARAM parm = program.local[0]; \n" 2184 "TEMP t; \n" 2185 "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */ 2186 "# t = t * 255 / bit \n" 2187 "MUL t.x, t.a, parm.x; \n" 2188 "# t = (int) t \n" 2189 "FRC t.y, t.x; \n" 2190 "SUB t.x, t.x, t.y; \n" 2191 "# t = t * 0.5 \n" 2192 "MUL t.x, t.x, parm.y; \n" 2193 "# t = fract(t.x) \n" 2194 "FRC t.x, t.x; # if t.x != 0, then the bit is set \n" 2195 "# t.x = (t.x == 0 ? 1 : 0) \n" 2196 "SGE t.x, -t.x, parm.z; \n" 2197 "KIL -t.x; \n" 2198 "# for debug only \n" 2199 "#MOV result.color, t.x; \n" 2200 "END \n"; 2201 char program2[1000]; 2202 struct drawpix_state *drawpix = &ctx->Meta->DrawPix; 2203 struct temp_texture *tex = get_temp_texture(ctx); 2204 const char *texTarget; 2205 2206 assert(drawpix->StencilFP == 0); 2207 2208 /* replace %s with "RECT" or "2D" */ 2209 assert(strlen(program) + 4 < sizeof(program2)); 2210 if (tex->Target == GL_TEXTURE_RECTANGLE) 2211 texTarget = "RECT"; 2212 else 2213 texTarget = "2D"; 2214 _mesa_snprintf(program2, sizeof(program2), program, texTarget); 2215 2216 _mesa_GenPrograms(1, &drawpix->StencilFP); 2217 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); 2218 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 2219 strlen(program2), (const GLubyte *) program2); 2220} 2221 2222 2223/** 2224 * One-time init for drawing depth pixels. 2225 */ 2226static void 2227init_draw_depth_pixels(struct gl_context *ctx) 2228{ 2229 static const char *program = 2230 "!!ARBfp1.0\n" 2231 "PARAM color = program.local[0]; \n" 2232 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" 2233 "MOV result.color, color; \n" 2234 "END \n"; 2235 char program2[200]; 2236 struct drawpix_state *drawpix = &ctx->Meta->DrawPix; 2237 struct temp_texture *tex = get_temp_texture(ctx); 2238 const char *texTarget; 2239 2240 assert(drawpix->DepthFP == 0); 2241 2242 /* replace %s with "RECT" or "2D" */ 2243 assert(strlen(program) + 4 < sizeof(program2)); 2244 if (tex->Target == GL_TEXTURE_RECTANGLE) 2245 texTarget = "RECT"; 2246 else 2247 texTarget = "2D"; 2248 _mesa_snprintf(program2, sizeof(program2), program, texTarget); 2249 2250 _mesa_GenPrograms(1, &drawpix->DepthFP); 2251 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); 2252 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 2253 strlen(program2), (const GLubyte *) program2); 2254} 2255 2256 2257/** 2258 * Meta implementation of ctx->Driver.DrawPixels() in terms 2259 * of texture mapping and polygon rendering. 2260 */ 2261void 2262_mesa_meta_DrawPixels(struct gl_context *ctx, 2263 GLint x, GLint y, GLsizei width, GLsizei height, 2264 GLenum format, GLenum type, 2265 const struct gl_pixelstore_attrib *unpack, 2266 const GLvoid *pixels) 2267{ 2268 struct drawpix_state *drawpix = &ctx->Meta->DrawPix; 2269 struct temp_texture *tex = get_temp_texture(ctx); 2270 const struct gl_pixelstore_attrib unpackSave = ctx->Unpack; 2271 const GLuint origStencilMask = ctx->Stencil.WriteMask[0]; 2272 struct vertex { 2273 GLfloat x, y, z, s, t; 2274 }; 2275 struct vertex verts[4]; 2276 GLenum texIntFormat; 2277 GLboolean fallback, newTex; 2278 GLbitfield metaExtraSave = 0x0; 2279 GLuint vbo; 2280 2281 /* 2282 * Determine if we can do the glDrawPixels with texture mapping. 2283 */ 2284 fallback = GL_FALSE; 2285 if (ctx->Fog.Enabled) { 2286 fallback = GL_TRUE; 2287 } 2288 2289 if (_mesa_is_color_format(format)) { 2290 /* use more compact format when possible */ 2291 /* XXX disable special case for GL_LUMINANCE for now to work around 2292 * apparent i965 driver bug (see bug #23670). 2293 */ 2294 if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA) 2295 texIntFormat = format; 2296 else 2297 texIntFormat = GL_RGBA; 2298 2299 /* If we're not supposed to clamp the resulting color, then just 2300 * promote our texture to fully float. We could do better by 2301 * just going for the matching set of channels, in floating 2302 * point. 2303 */ 2304 if (ctx->Color.ClampFragmentColor != GL_TRUE && 2305 ctx->Extensions.ARB_texture_float) 2306 texIntFormat = GL_RGBA32F; 2307 } 2308 else if (_mesa_is_stencil_format(format)) { 2309 if (ctx->Extensions.ARB_fragment_program && 2310 ctx->Pixel.IndexShift == 0 && 2311 ctx->Pixel.IndexOffset == 0 && 2312 type == GL_UNSIGNED_BYTE) { 2313 /* We'll store stencil as alpha. This only works for GLubyte 2314 * image data because of how incoming values are mapped to alpha 2315 * in [0,1]. 2316 */ 2317 texIntFormat = GL_ALPHA; 2318 metaExtraSave = (MESA_META_COLOR_MASK | 2319 MESA_META_DEPTH_TEST | 2320 MESA_META_PIXEL_TRANSFER | 2321 MESA_META_SHADER | 2322 MESA_META_STENCIL_TEST); 2323 } 2324 else { 2325 fallback = GL_TRUE; 2326 } 2327 } 2328 else if (_mesa_is_depth_format(format)) { 2329 if (ctx->Extensions.ARB_depth_texture && 2330 ctx->Extensions.ARB_fragment_program) { 2331 texIntFormat = GL_DEPTH_COMPONENT; 2332 metaExtraSave = (MESA_META_SHADER); 2333 } 2334 else { 2335 fallback = GL_TRUE; 2336 } 2337 } 2338 else { 2339 fallback = GL_TRUE; 2340 } 2341 2342 if (fallback) { 2343 _swrast_DrawPixels(ctx, x, y, width, height, 2344 format, type, unpack, pixels); 2345 return; 2346 } 2347 2348 /* 2349 * Check image size against max texture size, draw as tiles if needed. 2350 */ 2351 if (width > tex->MaxSize || height > tex->MaxSize) { 2352 tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height, 2353 format, type, unpack, pixels); 2354 return; 2355 } 2356 2357 /* Most GL state applies to glDrawPixels (like blending, stencil, etc), 2358 * but a there's a few things we need to override: 2359 */ 2360 _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | 2361 MESA_META_SHADER | 2362 MESA_META_TEXTURE | 2363 MESA_META_TRANSFORM | 2364 MESA_META_CLIP | 2365 MESA_META_VERTEX | 2366 MESA_META_VIEWPORT | 2367 metaExtraSave)); 2368 2369 newTex = alloc_texture(tex, width, height, texIntFormat); 2370 2371 /* vertex positions, texcoords (after texture allocation!) */ 2372 { 2373 const GLfloat x0 = (GLfloat) x; 2374 const GLfloat y0 = (GLfloat) y; 2375 const GLfloat x1 = x + width * ctx->Pixel.ZoomX; 2376 const GLfloat y1 = y + height * ctx->Pixel.ZoomY; 2377 const GLfloat z = invert_z(ctx->Current.RasterPos[2]); 2378 2379 verts[0].x = x0; 2380 verts[0].y = y0; 2381 verts[0].z = z; 2382 verts[0].s = 0.0F; 2383 verts[0].t = 0.0F; 2384 verts[1].x = x1; 2385 verts[1].y = y0; 2386 verts[1].z = z; 2387 verts[1].s = tex->Sright; 2388 verts[1].t = 0.0F; 2389 verts[2].x = x1; 2390 verts[2].y = y1; 2391 verts[2].z = z; 2392 verts[2].s = tex->Sright; 2393 verts[2].t = tex->Ttop; 2394 verts[3].x = x0; 2395 verts[3].y = y1; 2396 verts[3].z = z; 2397 verts[3].s = 0.0F; 2398 verts[3].t = tex->Ttop; 2399 } 2400 2401 if (drawpix->ArrayObj == 0) { 2402 /* one-time setup: create vertex array object */ 2403 _mesa_GenVertexArrays(1, &drawpix->ArrayObj); 2404 } 2405 _mesa_BindVertexArray(drawpix->ArrayObj); 2406 2407 /* create vertex array buffer */ 2408 _mesa_GenBuffersARB(1, &vbo); 2409 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); 2410 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 2411 verts, GL_DYNAMIC_DRAW_ARB); 2412 2413 /* setup vertex arrays */ 2414 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2415 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 2416 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2417 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2418 2419 /* set given unpack params */ 2420 ctx->Unpack = *unpack; 2421 2422 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 2423 2424 if (_mesa_is_stencil_format(format)) { 2425 /* Drawing stencil */ 2426 GLint bit; 2427 2428 if (!drawpix->StencilFP) 2429 init_draw_stencil_pixels(ctx); 2430 2431 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2432 GL_ALPHA, type, pixels); 2433 2434 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 2435 2436 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); 2437 2438 /* set all stencil bits to 0 */ 2439 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 2440 _mesa_StencilFunc(GL_ALWAYS, 0, 255); 2441 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2442 2443 /* set stencil bits to 1 where needed */ 2444 _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); 2445 2446 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); 2447 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); 2448 2449 for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) { 2450 const GLuint mask = 1 << bit; 2451 if (mask & origStencilMask) { 2452 _mesa_StencilFunc(GL_ALWAYS, mask, mask); 2453 _mesa_StencilMask(mask); 2454 2455 _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 2456 255.0 / mask, 0.5, 0.0, 0.0); 2457 2458 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2459 } 2460 } 2461 } 2462 else if (_mesa_is_depth_format(format)) { 2463 /* Drawing depth */ 2464 if (!drawpix->DepthFP) 2465 init_draw_depth_pixels(ctx); 2466 2467 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); 2468 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); 2469 2470 /* polygon color = current raster color */ 2471 _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, 2472 ctx->Current.RasterColor); 2473 2474 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2475 format, type, pixels); 2476 2477 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2478 } 2479 else { 2480 /* Drawing RGBA */ 2481 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2482 format, type, pixels); 2483 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2484 } 2485 2486 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 2487 2488 _mesa_DeleteBuffersARB(1, &vbo); 2489 2490 /* restore unpack params */ 2491 ctx->Unpack = unpackSave; 2492 2493 _mesa_meta_end(ctx); 2494} 2495 2496static GLboolean 2497alpha_test_raster_color(struct gl_context *ctx) 2498{ 2499 GLfloat alpha = ctx->Current.RasterColor[ACOMP]; 2500 GLfloat ref = ctx->Color.AlphaRef; 2501 2502 switch (ctx->Color.AlphaFunc) { 2503 case GL_NEVER: 2504 return GL_FALSE; 2505 case GL_LESS: 2506 return alpha < ref; 2507 case GL_EQUAL: 2508 return alpha == ref; 2509 case GL_LEQUAL: 2510 return alpha <= ref; 2511 case GL_GREATER: 2512 return alpha > ref; 2513 case GL_NOTEQUAL: 2514 return alpha != ref; 2515 case GL_GEQUAL: 2516 return alpha >= ref; 2517 case GL_ALWAYS: 2518 return GL_TRUE; 2519 default: 2520 assert(0); 2521 return GL_FALSE; 2522 } 2523} 2524 2525/** 2526 * Do glBitmap with a alpha texture quad. Use the alpha test to cull 2527 * the 'off' bits. A bitmap cache as in the gallium/mesa state 2528 * tracker would improve performance a lot. 2529 */ 2530void 2531_mesa_meta_Bitmap(struct gl_context *ctx, 2532 GLint x, GLint y, GLsizei width, GLsizei height, 2533 const struct gl_pixelstore_attrib *unpack, 2534 const GLubyte *bitmap1) 2535{ 2536 struct bitmap_state *bitmap = &ctx->Meta->Bitmap; 2537 struct temp_texture *tex = get_bitmap_temp_texture(ctx); 2538 const GLenum texIntFormat = GL_ALPHA; 2539 const struct gl_pixelstore_attrib unpackSave = *unpack; 2540 GLubyte fg, bg; 2541 struct vertex { 2542 GLfloat x, y, z, s, t, r, g, b, a; 2543 }; 2544 struct vertex verts[4]; 2545 GLboolean newTex; 2546 GLubyte *bitmap8; 2547 2548 /* 2549 * Check if swrast fallback is needed. 2550 */ 2551 if (ctx->_ImageTransferState || 2552 ctx->FragmentProgram._Enabled || 2553 ctx->Fog.Enabled || 2554 ctx->Texture._EnabledUnits || 2555 width > tex->MaxSize || 2556 height > tex->MaxSize) { 2557 _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1); 2558 return; 2559 } 2560 2561 if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx)) 2562 return; 2563 2564 /* Most GL state applies to glBitmap (like blending, stencil, etc), 2565 * but a there's a few things we need to override: 2566 */ 2567 _mesa_meta_begin(ctx, (MESA_META_ALPHA_TEST | 2568 MESA_META_PIXEL_STORE | 2569 MESA_META_RASTERIZATION | 2570 MESA_META_SHADER | 2571 MESA_META_TEXTURE | 2572 MESA_META_TRANSFORM | 2573 MESA_META_CLIP | 2574 MESA_META_VERTEX | 2575 MESA_META_VIEWPORT)); 2576 2577 if (bitmap->ArrayObj == 0) { 2578 /* one-time setup */ 2579 2580 /* create vertex array object */ 2581 _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj); 2582 _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj); 2583 2584 /* create vertex array buffer */ 2585 _mesa_GenBuffersARB(1, &bitmap->VBO); 2586 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO); 2587 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 2588 NULL, GL_DYNAMIC_DRAW_ARB); 2589 2590 /* setup vertex arrays */ 2591 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2592 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s)); 2593 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r)); 2594 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2595 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2596 _mesa_EnableClientState(GL_COLOR_ARRAY); 2597 } 2598 else { 2599 _mesa_BindVertexArray(bitmap->ArrayObj); 2600 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO); 2601 } 2602 2603 newTex = alloc_texture(tex, width, height, texIntFormat); 2604 2605 /* vertex positions, texcoords, colors (after texture allocation!) */ 2606 { 2607 const GLfloat x0 = (GLfloat) x; 2608 const GLfloat y0 = (GLfloat) y; 2609 const GLfloat x1 = (GLfloat) (x + width); 2610 const GLfloat y1 = (GLfloat) (y + height); 2611 const GLfloat z = invert_z(ctx->Current.RasterPos[2]); 2612 GLuint i; 2613 2614 verts[0].x = x0; 2615 verts[0].y = y0; 2616 verts[0].z = z; 2617 verts[0].s = 0.0F; 2618 verts[0].t = 0.0F; 2619 verts[1].x = x1; 2620 verts[1].y = y0; 2621 verts[1].z = z; 2622 verts[1].s = tex->Sright; 2623 verts[1].t = 0.0F; 2624 verts[2].x = x1; 2625 verts[2].y = y1; 2626 verts[2].z = z; 2627 verts[2].s = tex->Sright; 2628 verts[2].t = tex->Ttop; 2629 verts[3].x = x0; 2630 verts[3].y = y1; 2631 verts[3].z = z; 2632 verts[3].s = 0.0F; 2633 verts[3].t = tex->Ttop; 2634 2635 for (i = 0; i < 4; i++) { 2636 verts[i].r = ctx->Current.RasterColor[0]; 2637 verts[i].g = ctx->Current.RasterColor[1]; 2638 verts[i].b = ctx->Current.RasterColor[2]; 2639 verts[i].a = ctx->Current.RasterColor[3]; 2640 } 2641 2642 /* upload new vertex data */ 2643 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 2644 } 2645 2646 /* choose different foreground/background alpha values */ 2647 CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]); 2648 bg = (fg > 127 ? 0 : 255); 2649 2650 bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1); 2651 if (!bitmap1) { 2652 _mesa_meta_end(ctx); 2653 return; 2654 } 2655 2656 bitmap8 = (GLubyte *) malloc(width * height); 2657 if (bitmap8) { 2658 memset(bitmap8, bg, width * height); 2659 _mesa_expand_bitmap(width, height, &unpackSave, bitmap1, 2660 bitmap8, width, fg); 2661 2662 _mesa_set_enable(ctx, tex->Target, GL_TRUE); 2663 2664 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE); 2665 _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg)); 2666 2667 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height, 2668 GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8); 2669 2670 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 2671 2672 _mesa_set_enable(ctx, tex->Target, GL_FALSE); 2673 2674 free(bitmap8); 2675 } 2676 2677 _mesa_unmap_pbo_source(ctx, &unpackSave); 2678 2679 _mesa_meta_end(ctx); 2680} 2681 2682 2683/** 2684 * Check if the call to _mesa_meta_GenerateMipmap() will require a 2685 * software fallback. The fallback path will require that the texture 2686 * images are mapped. 2687 * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise 2688 */ 2689GLboolean 2690_mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target, 2691 struct gl_texture_object *texObj) 2692{ 2693 const GLuint fboSave = ctx->DrawBuffer->Name; 2694 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; 2695 struct gl_texture_image *baseImage; 2696 GLuint srcLevel; 2697 GLenum status; 2698 2699 /* check for fallbacks */ 2700 if (!ctx->Extensions.EXT_framebuffer_object || 2701 target == GL_TEXTURE_3D || 2702 target == GL_TEXTURE_1D_ARRAY || 2703 target == GL_TEXTURE_2D_ARRAY) { 2704 return GL_TRUE; 2705 } 2706 2707 srcLevel = texObj->BaseLevel; 2708 baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel); 2709 if (!baseImage || _mesa_is_format_compressed(baseImage->TexFormat)) { 2710 return GL_TRUE; 2711 } 2712 2713 if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB && 2714 !ctx->Extensions.EXT_texture_sRGB_decode) { 2715 /* The texture format is sRGB but we can't turn off sRGB->linear 2716 * texture sample conversion. So we won't be able to generate the 2717 * right colors when rendering. Need to use a fallback. 2718 */ 2719 return GL_TRUE; 2720 } 2721 2722 /* 2723 * Test that we can actually render in the texture's format. 2724 */ 2725 if (!mipmap->FBO) 2726 _mesa_GenFramebuffersEXT(1, &mipmap->FBO); 2727 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO); 2728 2729 if (target == GL_TEXTURE_1D) { 2730 _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, 2731 GL_COLOR_ATTACHMENT0_EXT, 2732 target, texObj->Name, srcLevel); 2733 } 2734#if 0 2735 /* other work is needed to enable 3D mipmap generation */ 2736 else if (target == GL_TEXTURE_3D) { 2737 GLint zoffset = 0; 2738 _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, 2739 GL_COLOR_ATTACHMENT0_EXT, 2740 target, texObj->Name, srcLevel, zoffset); 2741 } 2742#endif 2743 else { 2744 /* 2D / cube */ 2745 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 2746 GL_COLOR_ATTACHMENT0_EXT, 2747 target, texObj->Name, srcLevel); 2748 } 2749 2750 status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 2751 2752 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave); 2753 2754 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2755 return GL_TRUE; 2756 } 2757 2758 return GL_FALSE; 2759} 2760 2761 2762/** 2763 * Compute the texture coordinates for the four vertices of a quad for 2764 * drawing a 2D texture image or slice of a cube/3D texture. 2765 * \param faceTarget GL_TEXTURE_1D/2D/3D or cube face name 2766 * \param slice slice of a 1D/2D array texture or 3D texture 2767 * \param width width of the texture image 2768 * \param height height of the texture image 2769 * \param coords0/1/2/3 returns the computed texcoords 2770 */ 2771static void 2772setup_texture_coords(GLenum faceTarget, 2773 GLint slice, 2774 GLint width, 2775 GLint height, 2776 GLfloat coords0[3], 2777 GLfloat coords1[3], 2778 GLfloat coords2[3], 2779 GLfloat coords3[3]) 2780{ 2781 static const GLfloat st[4][2] = { 2782 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} 2783 }; 2784 GLuint i; 2785 GLfloat r; 2786 2787 switch (faceTarget) { 2788 case GL_TEXTURE_1D: 2789 case GL_TEXTURE_2D: 2790 case GL_TEXTURE_3D: 2791 case GL_TEXTURE_2D_ARRAY: 2792 if (faceTarget == GL_TEXTURE_3D) 2793 r = 1.0F / slice; 2794 else if (faceTarget == GL_TEXTURE_2D_ARRAY) 2795 r = slice; 2796 else 2797 r = 0.0F; 2798 coords0[0] = 0.0F; /* s */ 2799 coords0[1] = 0.0F; /* t */ 2800 coords0[2] = r; /* r */ 2801 coords1[0] = 1.0F; 2802 coords1[1] = 0.0F; 2803 coords1[2] = r; 2804 coords2[0] = 1.0F; 2805 coords2[1] = 1.0F; 2806 coords2[2] = r; 2807 coords3[0] = 0.0F; 2808 coords3[1] = 1.0F; 2809 coords3[2] = r; 2810 break; 2811 case GL_TEXTURE_RECTANGLE_ARB: 2812 coords0[0] = 0.0F; /* s */ 2813 coords0[1] = 0.0F; /* t */ 2814 coords0[2] = 0.0F; /* r */ 2815 coords1[0] = width; 2816 coords1[1] = 0.0F; 2817 coords1[2] = 0.0F; 2818 coords2[0] = width; 2819 coords2[1] = height; 2820 coords2[2] = 0.0F; 2821 coords3[0] = 0.0F; 2822 coords3[1] = height; 2823 coords3[2] = 0.0F; 2824 break; 2825 case GL_TEXTURE_1D_ARRAY: 2826 coords0[0] = 0.0F; /* s */ 2827 coords0[1] = slice; /* t */ 2828 coords0[2] = 0.0F; /* r */ 2829 coords1[0] = 1.0f; 2830 coords1[1] = slice; 2831 coords1[2] = 0.0F; 2832 coords2[0] = 1.0F; 2833 coords2[1] = slice; 2834 coords2[2] = 0.0F; 2835 coords3[0] = 0.0F; 2836 coords3[1] = slice; 2837 coords3[2] = 0.0F; 2838 break; 2839 2840 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2841 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2842 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2843 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2844 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2845 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2846 /* loop over quad verts */ 2847 for (i = 0; i < 4; i++) { 2848 /* Compute sc = +/-scale and tc = +/-scale. 2849 * Not +/-1 to avoid cube face selection ambiguity near the edges, 2850 * though that can still sometimes happen with this scale factor... 2851 */ 2852 const GLfloat scale = 0.9999f; 2853 const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale; 2854 const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale; 2855 GLfloat *coord; 2856 2857 switch (i) { 2858 case 0: 2859 coord = coords0; 2860 break; 2861 case 1: 2862 coord = coords1; 2863 break; 2864 case 2: 2865 coord = coords2; 2866 break; 2867 case 3: 2868 coord = coords3; 2869 break; 2870 default: 2871 assert(0); 2872 } 2873 2874 switch (faceTarget) { 2875 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2876 coord[0] = 1.0f; 2877 coord[1] = -tc; 2878 coord[2] = -sc; 2879 break; 2880 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2881 coord[0] = -1.0f; 2882 coord[1] = -tc; 2883 coord[2] = sc; 2884 break; 2885 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2886 coord[0] = sc; 2887 coord[1] = 1.0f; 2888 coord[2] = tc; 2889 break; 2890 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2891 coord[0] = sc; 2892 coord[1] = -1.0f; 2893 coord[2] = -tc; 2894 break; 2895 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2896 coord[0] = sc; 2897 coord[1] = -tc; 2898 coord[2] = 1.0f; 2899 break; 2900 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2901 coord[0] = -sc; 2902 coord[1] = -tc; 2903 coord[2] = -1.0f; 2904 break; 2905 default: 2906 assert(0); 2907 } 2908 } 2909 break; 2910 default: 2911 assert(0 && "unexpected target in meta setup_texture_coords()"); 2912 } 2913} 2914 2915 2916/** 2917 * Called via ctx->Driver.GenerateMipmap() 2918 * Note: We don't yet support 3D textures, 1D/2D array textures or texture 2919 * borders. 2920 */ 2921void 2922_mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, 2923 struct gl_texture_object *texObj) 2924{ 2925 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap; 2926 struct vertex { 2927 GLfloat x, y, tex[3]; 2928 }; 2929 struct vertex verts[4]; 2930 const GLuint baseLevel = texObj->BaseLevel; 2931 const GLuint maxLevel = texObj->MaxLevel; 2932 const GLint maxLevelSave = texObj->MaxLevel; 2933 const GLboolean genMipmapSave = texObj->GenerateMipmap; 2934 const GLenum srgbBufferSave = ctx->Color.sRGBEnabled; 2935 const GLuint fboSave = ctx->DrawBuffer->Name; 2936 const GLuint original_active_unit = ctx->Texture.CurrentUnit; 2937 GLenum faceTarget; 2938 GLuint dstLevel; 2939 const GLuint border = 0; 2940 const GLint slice = 0; 2941 GLuint samplerSave; 2942 2943 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { 2944 _mesa_generate_mipmap(ctx, target, texObj); 2945 return; 2946 } 2947 2948 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && 2949 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { 2950 faceTarget = target; 2951 target = GL_TEXTURE_CUBE_MAP; 2952 } 2953 else { 2954 faceTarget = target; 2955 } 2956 2957 _mesa_meta_begin(ctx, MESA_META_ALL); 2958 2959 samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? 2960 ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; 2961 2962 if (original_active_unit != 0) 2963 _mesa_BindTexture(target, texObj->Name); 2964 2965 if (mipmap->ArrayObj == 0) { 2966 /* one-time setup */ 2967 2968 /* create vertex array object */ 2969 _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj); 2970 _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj); 2971 2972 /* create vertex array buffer */ 2973 _mesa_GenBuffersARB(1, &mipmap->VBO); 2974 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO); 2975 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 2976 NULL, GL_DYNAMIC_DRAW_ARB); 2977 2978 /* setup vertex arrays */ 2979 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 2980 _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); 2981 _mesa_EnableClientState(GL_VERTEX_ARRAY); 2982 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 2983 } 2984 else { 2985 _mesa_BindVertexArray(mipmap->ArrayObj); 2986 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO); 2987 } 2988 2989 if (!mipmap->FBO) { 2990 _mesa_GenFramebuffersEXT(1, &mipmap->FBO); 2991 } 2992 2993 if (!mipmap->Sampler) { 2994 _mesa_GenSamplers(1, &mipmap->Sampler); 2995 _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); 2996 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 2997 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 2998 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 2999 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 3000 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 3001 /* We don't want to encode or decode sRGB values; treat them as linear */ 3002 if (ctx->Extensions.EXT_texture_sRGB_decode) { 3003 _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, 3004 GL_SKIP_DECODE_EXT); 3005 } 3006 3007 } else { 3008 _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); 3009 } 3010 3011 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO); 3012 3013 if (ctx->API == API_OPENGL || ctx->API == API_OPENGLES) 3014 _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); 3015 else 3016 assert(!genMipmapSave); 3017 3018 if (ctx->Extensions.EXT_framebuffer_sRGB) { 3019 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE); 3020 } 3021 3022 _mesa_set_enable(ctx, target, GL_TRUE); 3023 3024 /* setup texcoords (XXX what about border?) */ 3025 setup_texture_coords(faceTarget, 3026 slice, 3027 0, 0, /* width, height never used here */ 3028 verts[0].tex, 3029 verts[1].tex, 3030 verts[2].tex, 3031 verts[3].tex); 3032 3033 /* setup vertex positions */ 3034 verts[0].x = 0.0F; 3035 verts[0].y = 0.0F; 3036 verts[1].x = 1.0F; 3037 verts[1].y = 0.0F; 3038 verts[2].x = 1.0F; 3039 verts[2].y = 1.0F; 3040 verts[3].x = 0.0F; 3041 verts[3].y = 1.0F; 3042 3043 /* upload new vertex data */ 3044 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 3045 3046 /* setup projection matrix */ 3047 _mesa_MatrixMode(GL_PROJECTION); 3048 _mesa_LoadIdentity(); 3049 _mesa_Ortho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); 3050 3051 /* texture is already locked, unlock now */ 3052 _mesa_unlock_texture(ctx, texObj); 3053 3054 for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) { 3055 const struct gl_texture_image *srcImage; 3056 const GLuint srcLevel = dstLevel - 1; 3057 GLsizei srcWidth, srcHeight, srcDepth; 3058 GLsizei dstWidth, dstHeight, dstDepth; 3059 GLenum status; 3060 3061 srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel); 3062 assert(srcImage->Border == 0); /* XXX we can fix this */ 3063 3064 /* src size w/out border */ 3065 srcWidth = srcImage->Width - 2 * border; 3066 srcHeight = srcImage->Height - 2 * border; 3067 srcDepth = srcImage->Depth - 2 * border; 3068 3069 /* new dst size w/ border */ 3070 dstWidth = MAX2(1, srcWidth / 2) + 2 * border; 3071 dstHeight = MAX2(1, srcHeight / 2) + 2 * border; 3072 dstDepth = MAX2(1, srcDepth / 2) + 2 * border; 3073 3074 if (dstWidth == srcImage->Width && 3075 dstHeight == srcImage->Height && 3076 dstDepth == srcImage->Depth) { 3077 /* all done */ 3078 break; 3079 } 3080 3081 /* Allocate storage for the destination mipmap image(s) */ 3082 3083 /* Set MaxLevel large enough to hold the new level when we allocate it */ 3084 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel); 3085 3086 if (!_mesa_prepare_mipmap_level(ctx, texObj, dstLevel, 3087 dstWidth, dstHeight, dstDepth, 3088 srcImage->Border, 3089 srcImage->InternalFormat, 3090 srcImage->TexFormat)) { 3091 /* All done. We either ran out of memory or we would go beyond the 3092 * last valid level of an immutable texture if we continued. 3093 */ 3094 break; 3095 } 3096 3097 /* limit minification to src level */ 3098 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel); 3099 3100 /* Set to draw into the current dstLevel */ 3101 if (target == GL_TEXTURE_1D) { 3102 _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, 3103 GL_COLOR_ATTACHMENT0_EXT, 3104 target, 3105 texObj->Name, 3106 dstLevel); 3107 } 3108 else if (target == GL_TEXTURE_3D) { 3109 GLint zoffset = 0; /* XXX unfinished */ 3110 _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, 3111 GL_COLOR_ATTACHMENT0_EXT, 3112 target, 3113 texObj->Name, 3114 dstLevel, zoffset); 3115 } 3116 else { 3117 /* 2D / cube */ 3118 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, 3119 GL_COLOR_ATTACHMENT0_EXT, 3120 faceTarget, 3121 texObj->Name, 3122 dstLevel); 3123 } 3124 3125 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT); 3126 3127 /* sanity check */ 3128 status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); 3129 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { 3130 _mesa_problem(ctx, "Unexpected incomplete framebuffer in " 3131 "_mesa_meta_GenerateMipmap()"); 3132 break; 3133 } 3134 3135 assert(dstWidth == ctx->DrawBuffer->Width); 3136 assert(dstHeight == ctx->DrawBuffer->Height); 3137 3138 /* setup viewport */ 3139 _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight); 3140 3141 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 3142 } 3143 3144 if (ctx->Extensions.EXT_framebuffer_sRGB && srgbBufferSave) { 3145 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE); 3146 } 3147 3148 _mesa_lock_texture(ctx, texObj); /* relock */ 3149 3150 _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); 3151 3152 _mesa_meta_end(ctx); 3153 3154 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); 3155 if (genMipmapSave) 3156 _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); 3157 3158 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave); 3159} 3160 3161 3162/** 3163 * Determine the GL data type to use for the temporary image read with 3164 * ReadPixels() and passed to Tex[Sub]Image(). 3165 */ 3166static GLenum 3167get_temp_image_type(struct gl_context *ctx, gl_format format) 3168{ 3169 GLenum baseFormat; 3170 3171 baseFormat = _mesa_get_format_base_format(format); 3172 3173 switch (baseFormat) { 3174 case GL_RGBA: 3175 case GL_RGB: 3176 case GL_RG: 3177 case GL_RED: 3178 case GL_ALPHA: 3179 case GL_LUMINANCE: 3180 case GL_LUMINANCE_ALPHA: 3181 case GL_INTENSITY: 3182 if (ctx->DrawBuffer->Visual.redBits <= 8) 3183 return GL_UNSIGNED_BYTE; 3184 else if (ctx->DrawBuffer->Visual.redBits <= 16) 3185 return GL_UNSIGNED_SHORT; 3186 else 3187 return _mesa_get_format_datatype(format); 3188 case GL_DEPTH_COMPONENT: 3189 return GL_UNSIGNED_INT; 3190 case GL_DEPTH_STENCIL: 3191 return GL_UNSIGNED_INT_24_8; 3192 default: 3193 _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()", 3194 baseFormat); 3195 return 0; 3196 } 3197} 3198 3199 3200/** 3201 * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions. 3202 * Have to be careful with locking and meta state for pixel transfer. 3203 */ 3204void 3205_mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims, 3206 struct gl_texture_image *texImage, 3207 GLint xoffset, GLint yoffset, GLint zoffset, 3208 struct gl_renderbuffer *rb, 3209 GLint x, GLint y, 3210 GLsizei width, GLsizei height) 3211{ 3212 struct gl_texture_object *texObj = texImage->TexObject; 3213 GLenum format, type; 3214 GLint bpp; 3215 void *buf; 3216 3217 /* Choose format/type for temporary image buffer */ 3218 format = _mesa_get_format_base_format(texImage->TexFormat); 3219 if (format == GL_LUMINANCE || 3220 format == GL_LUMINANCE_ALPHA || 3221 format == GL_INTENSITY) { 3222 /* We don't want to use GL_LUMINANCE, GL_INTENSITY, etc. for the 3223 * temp image buffer because glReadPixels will do L=R+G+B which is 3224 * not what we want (should be L=R). 3225 */ 3226 format = GL_RGBA; 3227 } 3228 3229 type = get_temp_image_type(ctx, texImage->TexFormat); 3230 if (_mesa_is_format_integer_color(texImage->TexFormat)) { 3231 format = _mesa_base_format_to_integer_format(format); 3232 } 3233 bpp = _mesa_bytes_per_pixel(format, type); 3234 if (bpp <= 0) { 3235 _mesa_problem(ctx, "Bad bpp in _mesa_meta_CopyTexSubImage()"); 3236 return; 3237 } 3238 3239 /* 3240 * Alloc image buffer (XXX could use a PBO) 3241 */ 3242 buf = malloc(width * height * bpp); 3243 if (!buf) { 3244 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims); 3245 return; 3246 } 3247 3248 _mesa_unlock_texture(ctx, texObj); /* need to unlock first */ 3249 3250 /* 3251 * Read image from framebuffer (disable pixel transfer ops) 3252 */ 3253 _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE | MESA_META_PIXEL_TRANSFER); 3254 ctx->Driver.ReadPixels(ctx, x, y, width, height, 3255 format, type, &ctx->Pack, buf); 3256 _mesa_meta_end(ctx); 3257 3258 _mesa_update_state(ctx); /* to update pixel transfer state */ 3259 3260 /* 3261 * Store texture data (with pixel transfer ops) 3262 */ 3263 _mesa_meta_begin(ctx, MESA_META_PIXEL_STORE); 3264 3265 ctx->Driver.TexSubImage(ctx, dims, texImage, 3266 xoffset, yoffset, zoffset, width, height, 1, 3267 format, type, buf, &ctx->Unpack); 3268 3269 _mesa_meta_end(ctx); 3270 3271 _mesa_lock_texture(ctx, texObj); /* re-lock */ 3272 3273 free(buf); 3274} 3275 3276 3277/** 3278 * Decompress a texture image by drawing a quad with the compressed 3279 * texture and reading the pixels out of the color buffer. 3280 * \param slice which slice of a 3D texture or layer of a 1D/2D texture 3281 * \param destFormat format, ala glReadPixels 3282 * \param destType type, ala glReadPixels 3283 * \param dest destination buffer 3284 * \param destRowLength dest image rowLength (ala GL_PACK_ROW_LENGTH) 3285 */ 3286static void 3287decompress_texture_image(struct gl_context *ctx, 3288 struct gl_texture_image *texImage, 3289 GLuint slice, 3290 GLenum destFormat, GLenum destType, 3291 GLvoid *dest) 3292{ 3293 struct decompress_state *decompress = &ctx->Meta->Decompress; 3294 struct gl_texture_object *texObj = texImage->TexObject; 3295 const GLint width = texImage->Width; 3296 const GLint height = texImage->Height; 3297 const GLenum target = texObj->Target; 3298 GLenum faceTarget; 3299 struct vertex { 3300 GLfloat x, y, tex[3]; 3301 }; 3302 struct vertex verts[4]; 3303 GLuint fboDrawSave, fboReadSave; 3304 GLuint rbSave; 3305 GLuint samplerSave; 3306 3307 if (slice > 0) { 3308 assert(target == GL_TEXTURE_3D || 3309 target == GL_TEXTURE_2D_ARRAY); 3310 } 3311 3312 if (target == GL_TEXTURE_CUBE_MAP) { 3313 faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face; 3314 } 3315 else { 3316 faceTarget = target; 3317 } 3318 3319 /* save fbo bindings (not saved by _mesa_meta_begin()) */ 3320 fboDrawSave = ctx->DrawBuffer->Name; 3321 fboReadSave = ctx->ReadBuffer->Name; 3322 rbSave = ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0; 3323 3324 _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_PIXEL_STORE); 3325 3326 samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? 3327 ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; 3328 3329 /* Create/bind FBO/renderbuffer */ 3330 if (decompress->FBO == 0) { 3331 _mesa_GenFramebuffersEXT(1, &decompress->FBO); 3332 _mesa_GenRenderbuffersEXT(1, &decompress->RBO); 3333 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO); 3334 _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, decompress->RBO); 3335 _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, 3336 GL_COLOR_ATTACHMENT0_EXT, 3337 GL_RENDERBUFFER_EXT, 3338 decompress->RBO); 3339 } 3340 else { 3341 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO); 3342 } 3343 3344 /* alloc dest surface */ 3345 if (width > decompress->Width || height > decompress->Height) { 3346 _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, decompress->RBO); 3347 _mesa_RenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, 3348 width, height); 3349 decompress->Width = width; 3350 decompress->Height = height; 3351 } 3352 3353 /* setup VBO data */ 3354 if (decompress->ArrayObj == 0) { 3355 /* create vertex array object */ 3356 _mesa_GenVertexArrays(1, &decompress->ArrayObj); 3357 _mesa_BindVertexArray(decompress->ArrayObj); 3358 3359 /* create vertex array buffer */ 3360 _mesa_GenBuffersARB(1, &decompress->VBO); 3361 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, decompress->VBO); 3362 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 3363 NULL, GL_DYNAMIC_DRAW_ARB); 3364 3365 /* setup vertex arrays */ 3366 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 3367 _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(tex)); 3368 _mesa_EnableClientState(GL_VERTEX_ARRAY); 3369 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 3370 } 3371 else { 3372 _mesa_BindVertexArray(decompress->ArrayObj); 3373 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, decompress->VBO); 3374 } 3375 3376 if (!decompress->Sampler) { 3377 _mesa_GenSamplers(1, &decompress->Sampler); 3378 _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); 3379 /* nearest filtering */ 3380 _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3381 _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3382 /* No sRGB decode or encode.*/ 3383 if (ctx->Extensions.EXT_texture_sRGB_decode) { 3384 _mesa_SamplerParameteri(decompress->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, 3385 GL_SKIP_DECODE_EXT); 3386 } 3387 3388 } else { 3389 _mesa_BindSampler(ctx->Texture.CurrentUnit, decompress->Sampler); 3390 } 3391 3392 setup_texture_coords(faceTarget, slice, width, height, 3393 verts[0].tex, 3394 verts[1].tex, 3395 verts[2].tex, 3396 verts[3].tex); 3397 3398 /* setup vertex positions */ 3399 verts[0].x = 0.0F; 3400 verts[0].y = 0.0F; 3401 verts[1].x = width; 3402 verts[1].y = 0.0F; 3403 verts[2].x = width; 3404 verts[2].y = height; 3405 verts[3].x = 0.0F; 3406 verts[3].y = height; 3407 3408 /* upload new vertex data */ 3409 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 3410 3411 /* setup texture state */ 3412 _mesa_BindTexture(target, texObj->Name); 3413 _mesa_set_enable(ctx, target, GL_TRUE); 3414 3415 { 3416 /* save texture object state */ 3417 const GLint baseLevelSave = texObj->BaseLevel; 3418 const GLint maxLevelSave = texObj->MaxLevel; 3419 3420 /* restrict sampling to the texture level of interest */ 3421 if (target != GL_TEXTURE_RECTANGLE_ARB) { 3422 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, texImage->Level); 3423 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level); 3424 } 3425 3426 /* No sRGB decode or encode.*/ 3427 if (ctx->Extensions.EXT_framebuffer_sRGB) { 3428 _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE); 3429 } 3430 3431 /* render quad w/ texture into renderbuffer */ 3432 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 3433 3434 /* Restore texture object state, the texture binding will 3435 * be restored by _mesa_meta_end(). 3436 */ 3437 if (target != GL_TEXTURE_RECTANGLE_ARB) { 3438 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave); 3439 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); 3440 } 3441 3442 } 3443 3444 /* read pixels from renderbuffer */ 3445 { 3446 GLenum baseTexFormat = texImage->_BaseFormat; 3447 3448 /* The pixel transfer state will be set to default values at this point 3449 * (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively 3450 * turned off (as required by glGetTexImage) but we need to handle some 3451 * special cases. In particular, single-channel texture values are 3452 * returned as red and two-channel texture values are returned as 3453 * red/alpha. 3454 */ 3455 if (baseTexFormat == GL_LUMINANCE || 3456 baseTexFormat == GL_LUMINANCE_ALPHA || 3457 baseTexFormat == GL_INTENSITY) { 3458 /* Green and blue must be zero */ 3459 _mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f); 3460 _mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f); 3461 } 3462 3463 _mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest); 3464 } 3465 3466 /* disable texture unit */ 3467 _mesa_set_enable(ctx, target, GL_FALSE); 3468 3469 _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); 3470 3471 _mesa_meta_end(ctx); 3472 3473 /* restore fbo bindings */ 3474 if (fboDrawSave == fboReadSave) { 3475 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboDrawSave); 3476 } 3477 else { 3478 _mesa_BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fboDrawSave); 3479 _mesa_BindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fboReadSave); 3480 } 3481 _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbSave); 3482} 3483 3484 3485/** 3486 * This is just a wrapper around _mesa_get_tex_image() and 3487 * decompress_texture_image(). Meta functions should not be directly called 3488 * from core Mesa. 3489 */ 3490void 3491_mesa_meta_GetTexImage(struct gl_context *ctx, 3492 GLenum format, GLenum type, GLvoid *pixels, 3493 struct gl_texture_image *texImage) 3494{ 3495 /* We can only use the decompress-with-blit method here if the texels are 3496 * unsigned, normalized values. We could handle signed and unnormalized 3497 * with floating point renderbuffers... 3498 */ 3499 if (_mesa_is_format_compressed(texImage->TexFormat) && 3500 _mesa_get_format_datatype(texImage->TexFormat) 3501 == GL_UNSIGNED_NORMALIZED) { 3502 struct gl_texture_object *texObj = texImage->TexObject; 3503 const GLuint slice = 0; /* only 2D compressed textures for now */ 3504 /* Need to unlock the texture here to prevent deadlock... */ 3505 _mesa_unlock_texture(ctx, texObj); 3506 decompress_texture_image(ctx, texImage, slice, format, type, pixels); 3507 /* ... and relock it */ 3508 _mesa_lock_texture(ctx, texObj); 3509 } 3510 else { 3511 _mesa_get_teximage(ctx, format, type, pixels, texImage); 3512 } 3513} 3514 3515 3516/** 3517 * Meta implementation of ctx->Driver.DrawTex() in terms 3518 * of polygon rendering. 3519 */ 3520void 3521_mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, 3522 GLfloat width, GLfloat height) 3523{ 3524#if FEATURE_OES_draw_texture 3525 struct drawtex_state *drawtex = &ctx->Meta->DrawTex; 3526 struct vertex { 3527 GLfloat x, y, z, st[MAX_TEXTURE_UNITS][2]; 3528 }; 3529 struct vertex verts[4]; 3530 GLuint i; 3531 3532 _mesa_meta_begin(ctx, (MESA_META_RASTERIZATION | 3533 MESA_META_SHADER | 3534 MESA_META_TRANSFORM | 3535 MESA_META_VERTEX | 3536 MESA_META_VIEWPORT)); 3537 3538 if (drawtex->ArrayObj == 0) { 3539 /* one-time setup */ 3540 GLint active_texture; 3541 3542 /* create vertex array object */ 3543 _mesa_GenVertexArrays(1, &drawtex->ArrayObj); 3544 _mesa_BindVertexArray(drawtex->ArrayObj); 3545 3546 /* create vertex array buffer */ 3547 _mesa_GenBuffersARB(1, &drawtex->VBO); 3548 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO); 3549 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), 3550 NULL, GL_DYNAMIC_DRAW_ARB); 3551 3552 /* client active texture is not part of the array object */ 3553 active_texture = ctx->Array.ActiveTexture; 3554 3555 /* setup vertex arrays */ 3556 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x)); 3557 _mesa_EnableClientState(GL_VERTEX_ARRAY); 3558 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 3559 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + i); 3560 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(st[i])); 3561 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); 3562 } 3563 3564 /* restore client active texture */ 3565 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + active_texture); 3566 } 3567 else { 3568 _mesa_BindVertexArray(drawtex->ArrayObj); 3569 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawtex->VBO); 3570 } 3571 3572 /* vertex positions, texcoords */ 3573 { 3574 const GLfloat x1 = x + width; 3575 const GLfloat y1 = y + height; 3576 3577 z = CLAMP(z, 0.0, 1.0); 3578 z = invert_z(z); 3579 3580 verts[0].x = x; 3581 verts[0].y = y; 3582 verts[0].z = z; 3583 3584 verts[1].x = x1; 3585 verts[1].y = y; 3586 verts[1].z = z; 3587 3588 verts[2].x = x1; 3589 verts[2].y = y1; 3590 verts[2].z = z; 3591 3592 verts[3].x = x; 3593 verts[3].y = y1; 3594 verts[3].z = z; 3595 3596 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 3597 const struct gl_texture_object *texObj; 3598 const struct gl_texture_image *texImage; 3599 GLfloat s, t, s1, t1; 3600 GLuint tw, th; 3601 3602 if (!ctx->Texture.Unit[i]._ReallyEnabled) { 3603 GLuint j; 3604 for (j = 0; j < 4; j++) { 3605 verts[j].st[i][0] = 0.0f; 3606 verts[j].st[i][1] = 0.0f; 3607 } 3608 continue; 3609 } 3610 3611 texObj = ctx->Texture.Unit[i]._Current; 3612 texImage = texObj->Image[0][texObj->BaseLevel]; 3613 tw = texImage->Width2; 3614 th = texImage->Height2; 3615 3616 s = (GLfloat) texObj->CropRect[0] / tw; 3617 t = (GLfloat) texObj->CropRect[1] / th; 3618 s1 = (GLfloat) (texObj->CropRect[0] + texObj->CropRect[2]) / tw; 3619 t1 = (GLfloat) (texObj->CropRect[1] + texObj->CropRect[3]) / th; 3620 3621 verts[0].st[i][0] = s; 3622 verts[0].st[i][1] = t; 3623 3624 verts[1].st[i][0] = s1; 3625 verts[1].st[i][1] = t; 3626 3627 verts[2].st[i][0] = s1; 3628 verts[2].st[i][1] = t1; 3629 3630 verts[3].st[i][0] = s; 3631 verts[3].st[i][1] = t1; 3632 } 3633 3634 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); 3635 } 3636 3637 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); 3638 3639 _mesa_meta_end(ctx); 3640#endif /* FEATURE_OES_draw_texture */ 3641} 3642