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