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