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