2 * Mesa 3-D graphics library
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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.
34 #include "main/glheader.h"
35 #include "main/mtypes.h"
36 #include "main/imports.h"
37 #include "main/arrayobj.h"
38 #include "main/blend.h"
39 #include "main/bufferobj.h"
40 #include "main/depth.h"
41 #include "main/enable.h"
42 #include "main/macros.h"
43 #include "main/matrix.h"
44 #include "main/polygon.h"
45 #include "main/scissor.h"
46 #include "main/shaders.h"
47 #include "main/stencil.h"
48 #include "main/texobj.h"
49 #include "main/texenv.h"
50 #include "main/teximage.h"
51 #include "main/texparam.h"
52 #include "main/texstate.h"
53 #include "main/varray.h"
54 #include "main/viewport.h"
55 #include "shader/program.h"
56 #include "swrast/swrast.h"
57 #include "drivers/common/meta.h"
61 * State which we may save/restore across meta ops.
62 * XXX this may be incomplete...
66 GLbitfield SavedState
; /**< bitmask of META_* flags */
68 /** META_ALPHA_TEST */
69 GLboolean AlphaEnabled
;
72 GLboolean BlendEnabled
;
73 GLboolean ColorLogicOpEnabled
;
75 /** META_COLOR_MASK */
78 /** META_DEPTH_TEST */
79 struct gl_depthbuffer_attrib Depth
;
81 /** META_PIXELSTORE */
84 /** META_RASTERIZATION */
85 GLenum FrontPolygonMode
, BackPolygonMode
;
86 GLboolean PolygonOffset
;
87 GLboolean PolygonSmooth
;
88 GLboolean PolygonStipple
;
89 GLboolean PolygonCull
;
92 struct gl_scissor_attrib Scissor
;
95 GLboolean VertexProgramEnabled
;
96 struct gl_vertex_program
*VertexProgram
;
97 GLboolean FragmentProgramEnabled
;
98 struct gl_fragment_program
*FragmentProgram
;
101 /** META_STENCIL_TEST */
102 struct gl_stencil_attrib Stencil
;
104 /** META_TRANSFORM */
106 GLfloat ModelviewMatrix
[16];
107 GLfloat ProjectionMatrix
[16];
108 GLbitfield ClipPlanesEnabled
;
112 GLuint ClientActiveUnit
;
113 /** for unit[0] only */
114 struct gl_texture_object
*CurrentTexture
[NUM_TEXTURE_TARGETS
];
115 /** mask of TEXTURE_2D_BIT, etc */
116 GLbitfield TexEnabled
[MAX_TEXTURE_UNITS
];
117 GLbitfield TexGenEnabled
[MAX_TEXTURE_UNITS
];
118 GLuint EnvMode
; /* unit[0] only */
121 struct gl_array_object
*ArrayObj
;
122 struct gl_buffer_object
*ArrayBufferObj
;
125 GLint ViewportX
, ViewportY
, ViewportW
, ViewportH
;
126 GLclampd DepthNear
, DepthFar
;
128 /** Miscellaneous (always disabled) */
135 * State for glBlitFramebufer()
142 GLfloat verts
[4][4]; /** four verts of X,Y,S,T */
147 * State for glClear()
153 GLfloat verts
[4][7]; /** four verts of X,Y,Z,R,G,B,A */
158 * All per-context meta state.
162 struct save_state Save
; /**< state saved during meta-ops */
164 struct blit_state Blit
; /**< For _mesa_meta_blit_framebuffer() */
165 struct clear_state Clear
; /**< For _mesa_meta_clear() */
167 /* other possible meta-ops:
176 * Initialize meta-ops for a context.
177 * To be called once during context creation.
180 _mesa_meta_init(GLcontext
*ctx
)
184 ctx
->Meta
= CALLOC_STRUCT(gl_meta_state
);
189 * Free context meta-op state.
190 * To be called once during context destruction.
193 _mesa_meta_free(GLcontext
*ctx
)
195 struct gl_meta_state
*meta
= ctx
->Meta
;
197 if (meta
->Blit
.TexObj
) {
198 _mesa_DeleteTextures(1, &meta
->Blit
.TexObj
);
199 _mesa_DeleteBuffersARB(1, & meta
->Blit
.VBO
);
200 _mesa_DeleteVertexArraysAPPLE(1, &meta
->Blit
.ArrayObj
);
203 if (meta
->Clear
.VBO
) {
204 _mesa_DeleteBuffersARB(1, & meta
->Clear
.VBO
);
205 _mesa_DeleteVertexArraysAPPLE(1, &meta
->Clear
.ArrayObj
);
208 _mesa_free(ctx
->Meta
);
214 * Enter meta state. This is like a light-weight version of glPushAttrib
215 * but it also resets most GL state back to default values.
217 * \param state bitmask of META_* flags indicating which attribute groups
218 * to save and reset to their defaults
221 _mesa_meta_begin(GLcontext
*ctx
, GLbitfield state
)
223 struct save_state
*save
= &ctx
->Meta
->Save
;
225 save
->SavedState
= state
;
227 if (state
& META_ALPHA_TEST
) {
228 save
->AlphaEnabled
= ctx
->Color
.AlphaEnabled
;
229 if (ctx
->Color
.AlphaEnabled
)
230 _mesa_Disable(GL_ALPHA_TEST
);
233 if (state
& META_BLEND
) {
234 save
->BlendEnabled
= ctx
->Color
.BlendEnabled
;
235 if (ctx
->Color
.BlendEnabled
)
236 _mesa_Disable(GL_BLEND
);
237 save
->ColorLogicOpEnabled
= ctx
->Color
.ColorLogicOpEnabled
;
238 if (ctx
->Color
.ColorLogicOpEnabled
)
239 _mesa_Disable(GL_COLOR_LOGIC_OP
);
242 if (state
& META_COLOR_MASK
) {
243 COPY_4V(save
->ColorMask
, ctx
->Color
.ColorMask
);
244 if (!ctx
->Color
.ColorMask
[0] ||
245 !ctx
->Color
.ColorMask
[1] ||
246 !ctx
->Color
.ColorMask
[2] ||
247 !ctx
->Color
.ColorMask
[3])
248 _mesa_ColorMask(GL_TRUE
, GL_TRUE
, GL_TRUE
, GL_TRUE
);
251 if (state
& META_DEPTH_TEST
) {
252 save
->Depth
= ctx
->Depth
; /* struct copy */
254 _mesa_Disable(GL_DEPTH_TEST
);
257 if (state
& META_RASTERIZATION
) {
258 save
->FrontPolygonMode
= ctx
->Polygon
.FrontMode
;
259 save
->BackPolygonMode
= ctx
->Polygon
.BackMode
;
260 save
->PolygonOffset
= ctx
->Polygon
.OffsetFill
;
261 save
->PolygonSmooth
= ctx
->Polygon
.SmoothFlag
;
262 save
->PolygonStipple
= ctx
->Polygon
.StippleFlag
;
263 save
->PolygonCull
= ctx
->Polygon
.CullFlag
;
264 _mesa_PolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
265 _mesa_set_enable(ctx
, GL_POLYGON_OFFSET_FILL
, GL_FALSE
);
266 _mesa_set_enable(ctx
, GL_POLYGON_SMOOTH
, GL_FALSE
);
267 _mesa_set_enable(ctx
, GL_POLYGON_STIPPLE
, GL_FALSE
);
268 _mesa_set_enable(ctx
, GL_CULL_FACE
, GL_FALSE
);
271 if (state
& META_SCISSOR
) {
272 save
->Scissor
= ctx
->Scissor
; /* struct copy */
275 if (state
& META_SHADER
) {
276 if (ctx
->Extensions
.ARB_vertex_program
) {
277 save
->VertexProgramEnabled
= ctx
->VertexProgram
.Enabled
;
278 save
->VertexProgram
= ctx
->VertexProgram
.Current
;
279 _mesa_set_enable(ctx
, GL_VERTEX_PROGRAM_ARB
, GL_FALSE
);
282 if (ctx
->Extensions
.ARB_fragment_program
) {
283 save
->FragmentProgramEnabled
= ctx
->FragmentProgram
.Enabled
;
284 save
->FragmentProgram
= ctx
->FragmentProgram
.Current
;
285 _mesa_set_enable(ctx
, GL_FRAGMENT_PROGRAM_ARB
, GL_FALSE
);
288 if (ctx
->Extensions
.ARB_shader_objects
) {
289 save
->Shader
= ctx
->Shader
.CurrentProgram
?
290 ctx
->Shader
.CurrentProgram
->Name
: 0;
291 _mesa_UseProgramObjectARB(0);
295 if (state
& META_STENCIL_TEST
) {
296 save
->Stencil
= ctx
->Stencil
; /* struct copy */
297 if (ctx
->Stencil
.Enabled
)
298 _mesa_Disable(GL_STENCIL_TEST
);
299 /* NOTE: other stencil state not reset */
302 if (state
& META_TEXTURE
) {
305 save
->ActiveUnit
= ctx
->Texture
.CurrentUnit
;
306 save
->ClientActiveUnit
= ctx
->Array
.ActiveTexture
;
307 save
->EnvMode
= ctx
->Texture
.Unit
[0].EnvMode
;
309 /* Disable all texture units */
310 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
311 save
->TexEnabled
[u
] = ctx
->Texture
.Unit
[u
].Enabled
;
312 save
->TexGenEnabled
[u
] = ctx
->Texture
.Unit
[u
].TexGenEnabled
;
313 _mesa_ActiveTextureARB(GL_TEXTURE0
+ u
);
314 _mesa_set_enable(ctx
, GL_TEXTURE_1D
, GL_FALSE
);
315 _mesa_set_enable(ctx
, GL_TEXTURE_2D
, GL_FALSE
);
316 _mesa_set_enable(ctx
, GL_TEXTURE_3D
, GL_FALSE
);
317 _mesa_set_enable(ctx
, GL_TEXTURE_CUBE_MAP
, GL_FALSE
);
318 _mesa_set_enable(ctx
, GL_TEXTURE_RECTANGLE
, GL_FALSE
);
319 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_S
, GL_FALSE
);
320 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_T
, GL_FALSE
);
321 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_R
, GL_FALSE
);
322 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_Q
, GL_FALSE
);
325 /* save current texture objects for unit[0] only */
326 for (tgt
= 0; tgt
< NUM_TEXTURE_TARGETS
; tgt
++) {
327 _mesa_reference_texobj(&save
->CurrentTexture
[tgt
],
328 ctx
->Texture
.Unit
[0].CurrentTex
[tgt
]);
331 /* set defaults for unit[0] */
332 _mesa_ActiveTextureARB(GL_TEXTURE0
);
333 _mesa_ClientActiveTextureARB(GL_TEXTURE0
);
334 _mesa_TexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
335 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_S
, GL_FALSE
);
336 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_T
, GL_FALSE
);
337 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_R
, GL_FALSE
);
338 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_Q
, GL_FALSE
);
341 if (state
& META_TRANSFORM
) {
342 _mesa_memcpy(save
->ModelviewMatrix
, ctx
->ModelviewMatrixStack
.Top
->m
,
343 16 * sizeof(GLfloat
));
344 _mesa_memcpy(save
->ProjectionMatrix
, ctx
->ProjectionMatrixStack
.Top
->m
,
345 16 * sizeof(GLfloat
));
346 save
->MatrixMode
= ctx
->Transform
.MatrixMode
;
347 /* set 1:1 vertex:pixel coordinate transform */
348 _mesa_MatrixMode(GL_MODELVIEW
);
349 _mesa_LoadIdentity();
350 _mesa_MatrixMode(GL_PROJECTION
);
351 _mesa_LoadIdentity();
352 _mesa_Ortho(0.0F
, ctx
->DrawBuffer
->Width
,
353 0.0F
, ctx
->DrawBuffer
->Height
,
355 save
->ClipPlanesEnabled
= ctx
->Transform
.ClipPlanesEnabled
;
356 if (ctx
->Transform
.ClipPlanesEnabled
) {
358 for (i
= 0; i
< ctx
->Const
.MaxClipPlanes
; i
++) {
359 _mesa_set_enable(ctx
, GL_CLIP_PLANE0
+ i
, GL_FALSE
);
364 if (state
& META_VERTEX
) {
365 /* save vertex array object state */
366 _mesa_reference_array_object(ctx
, &save
->ArrayObj
,
367 ctx
->Array
.ArrayObj
);
368 _mesa_reference_buffer_object(ctx
, &save
->ArrayBufferObj
,
369 ctx
->Array
.ArrayBufferObj
);
370 /* set some default state? */
373 if (state
& META_VIEWPORT
) {
374 save
->ViewportX
= ctx
->Viewport
.X
;
375 save
->ViewportY
= ctx
->Viewport
.Y
;
376 save
->ViewportW
= ctx
->Viewport
.Width
;
377 save
->ViewportH
= ctx
->Viewport
.Height
;
378 _mesa_Viewport(0, 0, ctx
->DrawBuffer
->Width
, ctx
->DrawBuffer
->Height
);
379 save
->DepthNear
= ctx
->Viewport
.Near
;
380 save
->DepthFar
= ctx
->Viewport
.Far
;
381 _mesa_DepthRange(0.0, 1.0);
386 save
->Lighting
= ctx
->Light
.Enabled
;
387 if (ctx
->Light
.Enabled
)
388 _mesa_set_enable(ctx
, GL_LIGHTING
, GL_FALSE
);
390 save
->Fog
= ctx
->Fog
.Enabled
;
391 if (ctx
->Fog
.Enabled
)
392 _mesa_set_enable(ctx
, GL_FOG
, GL_FALSE
);
398 * Leave meta state. This is like a light-weight version of glPopAttrib().
401 _mesa_meta_end(GLcontext
*ctx
)
403 struct save_state
*save
= &ctx
->Meta
->Save
;
404 const GLbitfield state
= save
->SavedState
;
406 if (state
& META_ALPHA_TEST
) {
407 if (ctx
->Color
.AlphaEnabled
!= save
->AlphaEnabled
)
408 _mesa_set_enable(ctx
, GL_ALPHA_TEST
, save
->AlphaEnabled
);
411 if (state
& META_BLEND
) {
412 if (ctx
->Color
.BlendEnabled
!= save
->BlendEnabled
)
413 _mesa_set_enable(ctx
, GL_BLEND
, save
->BlendEnabled
);
414 if (ctx
->Color
.ColorLogicOpEnabled
!= save
->ColorLogicOpEnabled
)
415 _mesa_set_enable(ctx
, GL_COLOR_LOGIC_OP
, save
->ColorLogicOpEnabled
);
418 if (state
& META_COLOR_MASK
) {
419 if (!TEST_EQ_4V(ctx
->Color
.ColorMask
, save
->ColorMask
))
420 _mesa_ColorMask(save
->ColorMask
[0], save
->ColorMask
[1],
421 save
->ColorMask
[2], save
->ColorMask
[3]);
424 if (state
& META_DEPTH_TEST
) {
425 if (ctx
->Depth
.Test
!= save
->Depth
.Test
)
426 _mesa_set_enable(ctx
, GL_DEPTH_TEST
, save
->Depth
.Test
);
427 _mesa_DepthFunc(save
->Depth
.Func
);
428 _mesa_DepthMask(save
->Depth
.Mask
);
431 if (state
& META_RASTERIZATION
) {
432 _mesa_PolygonMode(GL_FRONT
, save
->FrontPolygonMode
);
433 _mesa_PolygonMode(GL_BACK
, save
->BackPolygonMode
);
434 _mesa_set_enable(ctx
, GL_POLYGON_STIPPLE
, save
->PolygonStipple
);
435 _mesa_set_enable(ctx
, GL_POLYGON_OFFSET_FILL
, save
->PolygonOffset
);
436 _mesa_set_enable(ctx
, GL_POLYGON_SMOOTH
, save
->PolygonSmooth
);
437 _mesa_set_enable(ctx
, GL_CULL_FACE
, save
->PolygonCull
);
440 if (state
& META_SCISSOR
) {
441 _mesa_set_enable(ctx
, GL_SCISSOR_TEST
, save
->Scissor
.Enabled
);
442 _mesa_Scissor(save
->Scissor
.X
, save
->Scissor
.Y
,
443 save
->Scissor
.Width
, save
->Scissor
.Height
);
446 if (state
& META_SHADER
) {
447 if (ctx
->Extensions
.ARB_vertex_program
) {
448 _mesa_set_enable(ctx
, GL_VERTEX_PROGRAM_ARB
,
449 save
->VertexProgramEnabled
);
450 _mesa_reference_vertprog(ctx
, &ctx
->VertexProgram
.Current
,
451 save
->VertexProgram
);
454 if (ctx
->Extensions
.ARB_fragment_program
) {
455 _mesa_set_enable(ctx
, GL_FRAGMENT_PROGRAM_ARB
,
456 save
->FragmentProgramEnabled
);
457 _mesa_reference_fragprog(ctx
, &ctx
->FragmentProgram
.Current
,
458 save
->FragmentProgram
);
461 if (ctx
->Extensions
.ARB_shader_objects
) {
462 _mesa_UseProgramObjectARB(save
->Shader
);
466 if (state
& META_STENCIL_TEST
) {
467 const struct gl_stencil_attrib
*stencil
= &save
->Stencil
;
469 _mesa_set_enable(ctx
, GL_STENCIL_TEST
, stencil
->Enabled
);
470 _mesa_ClearStencil(stencil
->Clear
);
471 if (ctx
->Extensions
.EXT_stencil_two_side
) {
472 _mesa_set_enable(ctx
, GL_STENCIL_TEST_TWO_SIDE_EXT
,
473 stencil
->TestTwoSide
);
474 _mesa_ActiveStencilFaceEXT(stencil
->ActiveFace
475 ? GL_BACK
: GL_FRONT
);
478 _mesa_StencilFuncSeparate(GL_FRONT
,
479 stencil
->Function
[0],
481 stencil
->ValueMask
[0]);
482 _mesa_StencilMaskSeparate(GL_FRONT
, stencil
->WriteMask
[0]);
483 _mesa_StencilOpSeparate(GL_FRONT
, stencil
->FailFunc
[0],
484 stencil
->ZFailFunc
[0],
485 stencil
->ZPassFunc
[0]);
487 _mesa_StencilFuncSeparate(GL_BACK
,
488 stencil
->Function
[1],
490 stencil
->ValueMask
[1]);
491 _mesa_StencilMaskSeparate(GL_BACK
, stencil
->WriteMask
[1]);
492 _mesa_StencilOpSeparate(GL_BACK
, stencil
->FailFunc
[1],
493 stencil
->ZFailFunc
[1],
494 stencil
->ZPassFunc
[1]);
497 if (state
& META_TEXTURE
) {
500 ASSERT(ctx
->Texture
.CurrentUnit
== 0);
502 /* restore texenv for unit[0] */
503 _mesa_TexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, save
->EnvMode
);
505 /* restore texture objects for unit[0] only */
506 for (tgt
= 0; tgt
< NUM_TEXTURE_TARGETS
; tgt
++) {
507 _mesa_reference_texobj(&ctx
->Texture
.Unit
[0].CurrentTex
[tgt
],
508 save
->CurrentTexture
[tgt
]);
511 /* Re-enable textures, texgen */
512 for (u
= 0; u
< ctx
->Const
.MaxTextureUnits
; u
++) {
513 if (save
->TexEnabled
[u
]) {
514 _mesa_ActiveTextureARB(GL_TEXTURE0
+ u
);
516 if (save
->TexEnabled
[u
] & TEXTURE_1D_BIT
)
517 _mesa_set_enable(ctx
, GL_TEXTURE_1D
, GL_TRUE
);
518 if (save
->TexEnabled
[u
] & TEXTURE_2D_BIT
)
519 _mesa_set_enable(ctx
, GL_TEXTURE_2D
, GL_TRUE
);
520 if (save
->TexEnabled
[u
] & TEXTURE_3D_BIT
)
521 _mesa_set_enable(ctx
, GL_TEXTURE_3D
, GL_TRUE
);
522 if (save
->TexEnabled
[u
] & TEXTURE_CUBE_BIT
)
523 _mesa_set_enable(ctx
, GL_TEXTURE_CUBE_MAP
, GL_TRUE
);
524 if (save
->TexEnabled
[u
] & TEXTURE_RECT_BIT
)
525 _mesa_set_enable(ctx
, GL_TEXTURE_RECTANGLE
, GL_TRUE
);
528 if (save
->TexGenEnabled
[u
]) {
529 _mesa_ActiveTextureARB(GL_TEXTURE0
+ u
);
531 if (save
->TexGenEnabled
[u
] & S_BIT
)
532 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_S
, GL_TRUE
);
533 if (save
->TexGenEnabled
[u
] & T_BIT
)
534 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_T
, GL_TRUE
);
535 if (save
->TexGenEnabled
[u
] & R_BIT
)
536 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_R
, GL_TRUE
);
537 if (save
->TexGenEnabled
[u
] & Q_BIT
)
538 _mesa_set_enable(ctx
, GL_TEXTURE_GEN_Q
, GL_TRUE
);
542 /* restore current unit state */
543 _mesa_ActiveTextureARB(GL_TEXTURE0
+ save
->ActiveUnit
);
544 _mesa_ClientActiveTextureARB(GL_TEXTURE0
+ save
->ClientActiveUnit
);
547 if (state
& META_TRANSFORM
) {
548 _mesa_MatrixMode(GL_MODELVIEW
);
549 _mesa_LoadMatrixf(save
->ModelviewMatrix
);
550 _mesa_MatrixMode(GL_PROJECTION
);
551 _mesa_LoadMatrixf(save
->ProjectionMatrix
);
552 _mesa_MatrixMode(save
->MatrixMode
);
553 save
->ClipPlanesEnabled
= ctx
->Transform
.ClipPlanesEnabled
;
554 if (save
->ClipPlanesEnabled
) {
556 for (i
= 0; i
< ctx
->Const
.MaxClipPlanes
; i
++) {
557 if (save
->ClipPlanesEnabled
& (1 << i
)) {
558 _mesa_set_enable(ctx
, GL_CLIP_PLANE0
+ i
, GL_TRUE
);
564 if (state
& META_VERTEX
) {
565 /* restore vertex buffer object */
566 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB
, save
->ArrayBufferObj
->Name
);
567 _mesa_reference_buffer_object(ctx
, &save
->ArrayBufferObj
, NULL
);
569 /* restore vertex array object */
570 _mesa_BindVertexArray(save
->ArrayObj
->Name
);
571 _mesa_reference_array_object(ctx
, &save
->ArrayObj
, NULL
);
574 if (state
& META_VIEWPORT
) {
575 _mesa_Viewport(save
->ViewportX
, save
->ViewportY
,
576 save
->ViewportW
, save
->ViewportH
);
577 _mesa_DepthRange(save
->DepthNear
, save
->DepthFar
);
581 if (save
->Lighting
) {
582 _mesa_set_enable(ctx
, GL_LIGHTING
, GL_TRUE
);
585 _mesa_set_enable(ctx
, GL_FOG
, GL_TRUE
);
591 * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
592 * of texture mapping and polygon rendering.
593 * Note: this function requires GL_ARB_texture_rectangle support.
596 _mesa_meta_blit_framebuffer(GLcontext
*ctx
,
597 GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
598 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
,
599 GLbitfield mask
, GLenum filter
)
601 struct blit_state
*blit
= &ctx
->Meta
->Blit
;
602 const GLint srcX
= MIN2(srcX0
, srcX1
);
603 const GLint srcY
= MIN2(srcY0
, srcY1
);
604 const GLint srcW
= abs(srcX1
- srcX0
);
605 const GLint srcH
= abs(srcY1
- srcY0
);
606 GLboolean srcFlipX
= srcX1
< srcX0
;
607 GLboolean srcFlipY
= srcY1
< srcY0
;
609 ASSERT(ctx
->Extensions
.NV_texture_rectangle
);
623 /* only scissor effects blit so save/clear all other relevant state */
624 _mesa_meta_begin(ctx
, ~META_SCISSOR
);
626 if (blit
->TexObj
== 0) {
629 /* create texture object */
630 _mesa_GenTextures(1, &blit
->TexObj
);
631 _mesa_BindTexture(GL_TEXTURE_RECTANGLE
, blit
->TexObj
);
632 _mesa_TexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
635 _mesa_BindTexture(GL_TEXTURE_RECTANGLE
, blit
->TexObj
);
638 _mesa_TexParameteri(GL_TEXTURE_RECTANGLE
, GL_TEXTURE_MIN_FILTER
, filter
);
639 _mesa_TexParameteri(GL_TEXTURE_RECTANGLE
, GL_TEXTURE_MAG_FILTER
, filter
);
641 if (blit
->ArrayObj
== 0) {
644 /* create vertex array object */
645 _mesa_GenVertexArrays(1, &blit
->ArrayObj
);
646 _mesa_BindVertexArray(blit
->ArrayObj
);
648 /* create vertex array buffer */
649 _mesa_GenBuffersARB(1, &blit
->VBO
);
650 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB
, blit
->VBO
);
651 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB
, sizeof(blit
->verts
),
652 blit
->verts
, GL_STREAM_DRAW_ARB
);
654 /* setup vertex arrays */
655 _mesa_VertexPointer(2, GL_FLOAT
, 4 * sizeof(GLfloat
),
656 (void*) (0 * sizeof(GLfloat
)));
657 _mesa_TexCoordPointer(2, GL_FLOAT
, 4 * sizeof(GLfloat
),
658 (void *) (2 * sizeof(GLfloat
)));
659 _mesa_EnableClientState(GL_VERTEX_ARRAY
);
660 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY
);
663 _mesa_BindVertexArray(blit
->ArrayObj
);
664 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB
, blit
->VBO
);
667 /* vertex positions */
668 blit
->verts
[0][0] = (GLfloat
) dstX0
;
669 blit
->verts
[0][1] = (GLfloat
) dstY0
;
670 blit
->verts
[1][0] = (GLfloat
) dstX1
;
671 blit
->verts
[1][1] = (GLfloat
) dstY0
;
672 blit
->verts
[2][0] = (GLfloat
) dstX1
;
673 blit
->verts
[2][1] = (GLfloat
) dstY1
;
674 blit
->verts
[3][0] = (GLfloat
) dstX0
;
675 blit
->verts
[3][1] = (GLfloat
) dstY1
;
678 blit
->verts
[0][2] = 0.0F
;
679 blit
->verts
[0][3] = 0.0F
;
680 blit
->verts
[1][2] = (GLfloat
) srcW
;
681 blit
->verts
[1][3] = 0.0F
;
682 blit
->verts
[2][2] = (GLfloat
) srcW
;
683 blit
->verts
[2][3] = (GLfloat
) srcH
;
684 blit
->verts
[3][2] = 0.0F
;
685 blit
->verts
[3][3] = (GLfloat
) srcH
;
687 /* upload new vertex data */
688 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB
, 0,
689 sizeof(blit
->verts
), blit
->verts
);
691 /* copy framebuffer image to texture */
692 if (mask
& GL_COLOR_BUFFER_BIT
) {
693 _mesa_CopyTexImage2D(GL_TEXTURE_RECTANGLE
, 0, GL_RGBA
,
694 srcX
, srcY
, srcW
, srcH
, 0);
695 mask
&= ~GL_COLOR_BUFFER_BIT
;
698 _mesa_Enable(GL_TEXTURE_RECTANGLE
);
700 /* draw textured quad */
701 _mesa_DrawArrays(GL_TRIANGLE_FAN
, 0, 4);
703 _mesa_Disable(GL_TEXTURE_RECTANGLE
);
707 /* XXX, TO-DO: try to handle these cases above! */
708 if (mask
& (GL_DEPTH_BUFFER_BIT
| GL_STENCIL_BUFFER_BIT
)) {
709 _swrast_BlitFramebuffer(ctx
, srcX0
, srcY0
, srcX1
, srcY1
,
710 dstX0
, dstY0
, dstX1
, dstY1
, mask
, filter
);
718 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
721 _mesa_meta_clear(GLcontext
*ctx
, GLbitfield buffers
)
723 struct clear_state
*clear
= &ctx
->Meta
->Clear
;
724 GLfloat z
= 1.0 - 2.0 * ctx
->Depth
.Clear
;
727 /* only scissor and color mask effects clearing */
728 _mesa_meta_begin(ctx
, ~(META_SCISSOR
| META_COLOR_MASK
));
730 if (clear
->ArrayObj
== 0) {
733 /* create vertex array object */
734 _mesa_GenVertexArrays(1, &clear
->ArrayObj
);
735 _mesa_BindVertexArray(clear
->ArrayObj
);
737 /* create vertex array buffer */
738 _mesa_GenBuffersARB(1, &clear
->VBO
);
739 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB
, clear
->VBO
);
740 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB
, sizeof(clear
->verts
),
741 clear
->verts
, GL_STREAM_DRAW_ARB
);
743 /* setup vertex arrays */
744 _mesa_VertexPointer(3, GL_FLOAT
, 7 * sizeof(GLfloat
), (void *) 0);
745 _mesa_ColorPointer(4, GL_FLOAT
, 7 * sizeof(GLfloat
),
746 (void *) (3 * sizeof(GLfloat
)));
747 _mesa_EnableClientState(GL_VERTEX_ARRAY
);
748 _mesa_EnableClientState(GL_COLOR_ARRAY
);
751 _mesa_BindVertexArray(clear
->ArrayObj
);
752 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB
, clear
->VBO
);
755 /* GL_COLOR_BUFFER_BIT */
756 if (buffers
& BUFFER_BITS_COLOR
) {
757 /* leave colormask, glDrawBuffer state as-is */
760 _mesa_ColorMask(GL_FALSE
, GL_FALSE
, GL_FALSE
, GL_FALSE
);
763 /* GL_DEPTH_BUFFER_BIT */
764 if (buffers
& BUFFER_BIT_DEPTH
) {
765 _mesa_set_enable(ctx
, GL_DEPTH_TEST
, GL_TRUE
);
766 _mesa_DepthFunc(GL_ALWAYS
);
767 _mesa_DepthMask(GL_TRUE
);
770 assert(!ctx
->Depth
.Test
);
773 /* GL_STENCIL_BUFFER_BIT */
774 if (buffers
& BUFFER_BIT_STENCIL
) {
775 _mesa_set_enable(ctx
, GL_STENCIL_TEST
, GL_TRUE
);
776 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK
,
777 GL_REPLACE
, GL_REPLACE
, GL_REPLACE
);
778 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK
, GL_ALWAYS
,
779 ctx
->Stencil
.Clear
& 0x7fffffff,
780 ctx
->Stencil
.WriteMask
[0]);
783 assert(!ctx
->Stencil
.Enabled
);
786 /* vertex positions */
787 clear
->verts
[0][0] = (GLfloat
) ctx
->DrawBuffer
->_Xmin
;
788 clear
->verts
[0][1] = (GLfloat
) ctx
->DrawBuffer
->_Ymin
;
789 clear
->verts
[0][2] = z
;
790 clear
->verts
[1][0] = (GLfloat
) ctx
->DrawBuffer
->_Xmax
;
791 clear
->verts
[1][1] = (GLfloat
) ctx
->DrawBuffer
->_Ymin
;
792 clear
->verts
[1][2] = z
;
793 clear
->verts
[2][0] = (GLfloat
) ctx
->DrawBuffer
->_Xmax
;
794 clear
->verts
[2][1] = (GLfloat
) ctx
->DrawBuffer
->_Ymax
;
795 clear
->verts
[2][2] = z
;
796 clear
->verts
[3][0] = (GLfloat
) ctx
->DrawBuffer
->_Xmin
;
797 clear
->verts
[3][1] = (GLfloat
) ctx
->DrawBuffer
->_Ymax
;
798 clear
->verts
[3][2] = z
;
801 for (i
= 0; i
< 4; i
++) {
802 COPY_4FV(&clear
->verts
[i
][3], ctx
->Color
.ClearColor
);
805 /* upload new vertex data */
806 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB
, 0,
807 sizeof(clear
->verts
), clear
->verts
);
810 _mesa_DrawArrays(GL_TRIANGLE_FAN
, 0, 4);