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