Merge branch 'mesa_7_6_branch'
[mesa.git] / src / mesa / drivers / common / meta.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.6
4 *
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * Meta operations. Some GL operations can be expressed in terms of
27 * other GL operations. For example, glBlitFramebuffer() can be done
28 * with texture mapping and glClear() can be done with polygon rendering.
29 *
30 * \author Brian Paul
31 */
32
33
34 #include "main/glheader.h"
35 #include "main/mtypes.h"
36 #include "main/imports.h"
37 #include "main/arrayobj.h"
38 #include "main/blend.h"
39 #include "main/bufferobj.h"
40 #include "main/buffers.h"
41 #include "main/colortab.h"
42 #include "main/convolve.h"
43 #include "main/depth.h"
44 #include "main/enable.h"
45 #include "main/fbobject.h"
46 #include "main/image.h"
47 #include "main/macros.h"
48 #include "main/matrix.h"
49 #include "main/mipmap.h"
50 #include "main/polygon.h"
51 #include "main/readpix.h"
52 #include "main/scissor.h"
53 #include "main/shaders.h"
54 #include "main/state.h"
55 #include "main/stencil.h"
56 #include "main/texobj.h"
57 #include "main/texenv.h"
58 #include "main/teximage.h"
59 #include "main/texparam.h"
60 #include "main/texstate.h"
61 #include "main/varray.h"
62 #include "main/viewport.h"
63 #include "shader/program.h"
64 #include "shader/arbprogram.h"
65 #include "swrast/swrast.h"
66 #include "drivers/common/meta.h"
67
68
69 /** Return offset in bytes of the field within a vertex struct */
70 #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
71
72
73 /**
74 * Flags passed to _mesa_meta_begin().
75 */
76 /*@{*/
77 #define META_ALL ~0x0
78 #define META_ALPHA_TEST 0x1
79 #define META_BLEND 0x2 /**< includes logicop */
80 #define META_COLOR_MASK 0x4
81 #define META_DEPTH_TEST 0x8
82 #define META_FOG 0x10
83 #define META_PIXEL_STORE 0x20
84 #define META_PIXEL_TRANSFER 0x40
85 #define META_RASTERIZATION 0x80
86 #define META_SCISSOR 0x100
87 #define META_SHADER 0x200
88 #define META_STENCIL_TEST 0x400
89 #define META_TRANSFORM 0x800 /**< modelview, projection, clip planes */
90 #define META_TEXTURE 0x1000
91 #define META_VERTEX 0x2000
92 #define META_VIEWPORT 0x4000
93 /*@}*/
94
95
96 /**
97 * State which we may save/restore across meta ops.
98 * XXX this may be incomplete...
99 */
100 struct save_state
101 {
102 GLbitfield SavedState; /**< bitmask of META_* flags */
103
104 /** META_ALPHA_TEST */
105 GLboolean AlphaEnabled;
106
107 /** META_BLEND */
108 GLboolean BlendEnabled;
109 GLboolean ColorLogicOpEnabled;
110
111 /** META_COLOR_MASK */
112 GLubyte ColorMask[4];
113
114 /** META_DEPTH_TEST */
115 struct gl_depthbuffer_attrib Depth;
116
117 /** META_FOG */
118 GLboolean Fog;
119
120 /** META_PIXEL_STORE */
121 struct gl_pixelstore_attrib Pack, Unpack;
122
123 /** META_PIXEL_TRANSFER */
124 GLfloat RedBias, RedScale;
125 GLfloat GreenBias, GreenScale;
126 GLfloat BlueBias, BlueScale;
127 GLfloat AlphaBias, AlphaScale;
128 GLfloat DepthBias, DepthScale;
129 GLboolean MapColorFlag;
130 GLboolean Convolution1DEnabled;
131 GLboolean Convolution2DEnabled;
132 GLboolean Separable2DEnabled;
133
134 /** META_RASTERIZATION */
135 GLenum FrontPolygonMode, BackPolygonMode;
136 GLboolean PolygonOffset;
137 GLboolean PolygonSmooth;
138 GLboolean PolygonStipple;
139 GLboolean PolygonCull;
140
141 /** META_SCISSOR */
142 struct gl_scissor_attrib Scissor;
143
144 /** META_SHADER */
145 GLboolean VertexProgramEnabled;
146 struct gl_vertex_program *VertexProgram;
147 GLboolean FragmentProgramEnabled;
148 struct gl_fragment_program *FragmentProgram;
149 GLuint Shader;
150
151 /** META_STENCIL_TEST */
152 struct gl_stencil_attrib Stencil;
153
154 /** META_TRANSFORM */
155 GLenum MatrixMode;
156 GLfloat ModelviewMatrix[16];
157 GLfloat ProjectionMatrix[16];
158 GLfloat TextureMatrix[16];
159 GLbitfield ClipPlanesEnabled;
160
161 /** META_TEXTURE */
162 GLuint ActiveUnit;
163 GLuint ClientActiveUnit;
164 /** for unit[0] only */
165 struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
166 /** mask of TEXTURE_2D_BIT, etc */
167 GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
168 GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
169 GLuint EnvMode; /* unit[0] only */
170
171 /** META_VERTEX */
172 struct gl_array_object *ArrayObj;
173 struct gl_buffer_object *ArrayBufferObj;
174
175 /** META_VIEWPORT */
176 GLint ViewportX, ViewportY, ViewportW, ViewportH;
177 GLclampd DepthNear, DepthFar;
178
179 /** Miscellaneous (always disabled) */
180 GLboolean Lighting;
181 };
182
183
184 /**
185 * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
186 * This is currently shared by all the meta ops. But we could create a
187 * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
188 */
189 struct temp_texture
190 {
191 GLuint TexObj;
192 GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
193 GLsizei MinSize; /**< Min texture size to allocate */
194 GLsizei MaxSize; /**< Max possible texture size */
195 GLboolean NPOT; /**< Non-power of two size OK? */
196 GLsizei Width, Height; /**< Current texture size */
197 GLenum IntFormat;
198 GLfloat Sright, Ttop; /**< right, top texcoords */
199 };
200
201
202 /**
203 * State for glBlitFramebufer()
204 */
205 struct blit_state
206 {
207 GLuint ArrayObj;
208 GLuint VBO;
209 GLuint DepthFP;
210 };
211
212
213 /**
214 * State for glClear()
215 */
216 struct clear_state
217 {
218 GLuint ArrayObj;
219 GLuint VBO;
220 };
221
222
223 /**
224 * State for glCopyPixels()
225 */
226 struct copypix_state
227 {
228 GLuint ArrayObj;
229 GLuint VBO;
230 };
231
232
233 /**
234 * State for glDrawPixels()
235 */
236 struct drawpix_state
237 {
238 GLuint ArrayObj;
239 GLuint VBO;
240
241 GLuint StencilFP; /**< Fragment program for drawing stencil images */
242 GLuint DepthFP; /**< Fragment program for drawing depth images */
243 };
244
245
246 /**
247 * State for glBitmap()
248 */
249 struct bitmap_state
250 {
251 GLuint ArrayObj;
252 GLuint VBO;
253 struct temp_texture Tex; /**< separate texture from other meta ops */
254 };
255
256
257 /**
258 * State for _mesa_meta_generate_mipmap()
259 */
260 struct gen_mipmap_state
261 {
262 GLuint ArrayObj;
263 GLuint VBO;
264 GLuint FBO;
265 };
266
267
268 /**
269 * All per-context meta state.
270 */
271 struct gl_meta_state
272 {
273 struct save_state Save; /**< state saved during meta-ops */
274
275 struct temp_texture TempTex;
276
277 struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */
278 struct clear_state Clear; /**< For _mesa_meta_Clear() */
279 struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */
280 struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */
281 struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */
282 struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */
283 };
284
285
286 /**
287 * Initialize meta-ops for a context.
288 * To be called once during context creation.
289 */
290 void
291 _mesa_meta_init(GLcontext *ctx)
292 {
293 ASSERT(!ctx->Meta);
294
295 ctx->Meta = CALLOC_STRUCT(gl_meta_state);
296 }
297
298
299 /**
300 * Free context meta-op state.
301 * To be called once during context destruction.
302 */
303 void
304 _mesa_meta_free(GLcontext *ctx)
305 {
306 struct gl_meta_state *meta = ctx->Meta;
307
308 if (_mesa_get_current_context()) {
309 /* if there's no current context, these textures, buffers, etc should
310 * still get freed by _mesa_free_context_data().
311 */
312
313 /* the temporary texture */
314 _mesa_DeleteTextures(1, &meta->TempTex.TexObj);
315
316 /* glBlitFramebuffer */
317 _mesa_DeleteBuffersARB(1, & meta->Blit.VBO);
318 _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj);
319 _mesa_DeletePrograms(1, &meta->Blit.DepthFP);
320
321 /* glClear */
322 _mesa_DeleteBuffersARB(1, & meta->Clear.VBO);
323 _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj);
324
325 /* glCopyPixels */
326 _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO);
327 _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj);
328
329 /* glDrawPixels */
330 _mesa_DeleteBuffersARB(1, & meta->DrawPix.VBO);
331 _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj);
332 _mesa_DeletePrograms(1, &meta->DrawPix.DepthFP);
333 _mesa_DeletePrograms(1, &meta->DrawPix.StencilFP);
334
335 /* glBitmap */
336 _mesa_DeleteBuffersARB(1, & meta->Bitmap.VBO);
337 _mesa_DeleteVertexArraysAPPLE(1, &meta->Bitmap.ArrayObj);
338 _mesa_DeleteTextures(1, &meta->Bitmap.Tex.TexObj);
339 }
340
341 _mesa_free(ctx->Meta);
342 ctx->Meta = NULL;
343 }
344
345
346 /**
347 * Enter meta state. This is like a light-weight version of glPushAttrib
348 * but it also resets most GL state back to default values.
349 *
350 * \param state bitmask of META_* flags indicating which attribute groups
351 * to save and reset to their defaults
352 */
353 static void
354 _mesa_meta_begin(GLcontext *ctx, GLbitfield state)
355 {
356 struct save_state *save = &ctx->Meta->Save;
357
358 save->SavedState = state;
359
360 if (state & META_ALPHA_TEST) {
361 save->AlphaEnabled = ctx->Color.AlphaEnabled;
362 if (ctx->Color.AlphaEnabled)
363 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
364 }
365
366 if (state & META_BLEND) {
367 save->BlendEnabled = ctx->Color.BlendEnabled;
368 if (ctx->Color.BlendEnabled)
369 _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
370 save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
371 if (ctx->Color.ColorLogicOpEnabled)
372 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
373 }
374
375 if (state & META_COLOR_MASK) {
376 COPY_4V(save->ColorMask, ctx->Color.ColorMask);
377 if (!ctx->Color.ColorMask[0] ||
378 !ctx->Color.ColorMask[1] ||
379 !ctx->Color.ColorMask[2] ||
380 !ctx->Color.ColorMask[3])
381 _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
382 }
383
384 if (state & META_DEPTH_TEST) {
385 save->Depth = ctx->Depth; /* struct copy */
386 if (ctx->Depth.Test)
387 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
388 }
389
390 if (state & META_FOG) {
391 save->Fog = ctx->Fog.Enabled;
392 if (ctx->Fog.Enabled)
393 _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
394 }
395
396 if (state & META_PIXEL_STORE) {
397 save->Pack = ctx->Pack;
398 save->Unpack = ctx->Unpack;
399 ctx->Pack = ctx->DefaultPacking;
400 ctx->Unpack = ctx->DefaultPacking;
401 }
402
403 if (state & META_PIXEL_TRANSFER) {
404 save->RedScale = ctx->Pixel.RedScale;
405 save->RedBias = ctx->Pixel.RedBias;
406 save->GreenScale = ctx->Pixel.GreenScale;
407 save->GreenBias = ctx->Pixel.GreenBias;
408 save->BlueScale = ctx->Pixel.BlueScale;
409 save->BlueBias = ctx->Pixel.BlueBias;
410 save->AlphaScale = ctx->Pixel.AlphaScale;
411 save->AlphaBias = ctx->Pixel.AlphaBias;
412 save->MapColorFlag = ctx->Pixel.MapColorFlag;
413 save->Convolution1DEnabled = ctx->Pixel.Convolution1DEnabled;
414 save->Convolution2DEnabled = ctx->Pixel.Convolution2DEnabled;
415 save->Separable2DEnabled = ctx->Pixel.Separable2DEnabled;
416 ctx->Pixel.RedScale = 1.0F;
417 ctx->Pixel.RedBias = 0.0F;
418 ctx->Pixel.GreenScale = 1.0F;
419 ctx->Pixel.GreenBias = 0.0F;
420 ctx->Pixel.BlueScale = 1.0F;
421 ctx->Pixel.BlueBias = 0.0F;
422 ctx->Pixel.AlphaScale = 1.0F;
423 ctx->Pixel.AlphaBias = 0.0F;
424 ctx->Pixel.MapColorFlag = GL_FALSE;
425 ctx->Pixel.Convolution1DEnabled = GL_FALSE;
426 ctx->Pixel.Convolution2DEnabled = GL_FALSE;
427 ctx->Pixel.Separable2DEnabled = GL_FALSE;
428 /* XXX more state */
429 ctx->NewState |=_NEW_PIXEL;
430 }
431
432 if (state & META_RASTERIZATION) {
433 save->FrontPolygonMode = ctx->Polygon.FrontMode;
434 save->BackPolygonMode = ctx->Polygon.BackMode;
435 save->PolygonOffset = ctx->Polygon.OffsetFill;
436 save->PolygonSmooth = ctx->Polygon.SmoothFlag;
437 save->PolygonStipple = ctx->Polygon.StippleFlag;
438 save->PolygonCull = ctx->Polygon.CullFlag;
439 _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
440 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
441 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
442 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
443 _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
444 }
445
446 if (state & META_SCISSOR) {
447 save->Scissor = ctx->Scissor; /* struct copy */
448 }
449
450 if (state & META_SHADER) {
451 if (ctx->Extensions.ARB_vertex_program) {
452 save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
453 save->VertexProgram = ctx->VertexProgram.Current;
454 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
455 }
456
457 if (ctx->Extensions.ARB_fragment_program) {
458 save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
459 save->FragmentProgram = ctx->FragmentProgram.Current;
460 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
461 }
462
463 if (ctx->Extensions.ARB_shader_objects) {
464 save->Shader = ctx->Shader.CurrentProgram ?
465 ctx->Shader.CurrentProgram->Name : 0;
466 _mesa_UseProgramObjectARB(0);
467 }
468 }
469
470 if (state & META_STENCIL_TEST) {
471 save->Stencil = ctx->Stencil; /* struct copy */
472 if (ctx->Stencil.Enabled)
473 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
474 /* NOTE: other stencil state not reset */
475 }
476
477 if (state & META_TEXTURE) {
478 GLuint u, tgt;
479
480 save->ActiveUnit = ctx->Texture.CurrentUnit;
481 save->ClientActiveUnit = ctx->Array.ActiveTexture;
482 save->EnvMode = ctx->Texture.Unit[0].EnvMode;
483
484 /* Disable all texture units */
485 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
486 save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
487 save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
488 if (ctx->Texture.Unit[u].Enabled ||
489 ctx->Texture.Unit[u].TexGenEnabled) {
490 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
491 _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
492 _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
493 _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
494 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
495 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
496 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
497 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
498 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
499 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
500 }
501 }
502
503 /* save current texture objects for unit[0] only */
504 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
505 _mesa_reference_texobj(&save->CurrentTexture[tgt],
506 ctx->Texture.Unit[0].CurrentTex[tgt]);
507 }
508
509 /* set defaults for unit[0] */
510 _mesa_ActiveTextureARB(GL_TEXTURE0);
511 _mesa_ClientActiveTextureARB(GL_TEXTURE0);
512 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
513 }
514
515 if (state & META_TRANSFORM) {
516 GLuint activeTexture = ctx->Texture.CurrentUnit;
517 _mesa_memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
518 16 * sizeof(GLfloat));
519 _mesa_memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
520 16 * sizeof(GLfloat));
521 _mesa_memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
522 16 * sizeof(GLfloat));
523 save->MatrixMode = ctx->Transform.MatrixMode;
524 /* set 1:1 vertex:pixel coordinate transform */
525 _mesa_ActiveTextureARB(GL_TEXTURE0);
526 _mesa_MatrixMode(GL_TEXTURE);
527 _mesa_LoadIdentity();
528 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
529 _mesa_MatrixMode(GL_MODELVIEW);
530 _mesa_LoadIdentity();
531 _mesa_MatrixMode(GL_PROJECTION);
532 _mesa_LoadIdentity();
533 _mesa_Ortho(0.0F, ctx->DrawBuffer->Width,
534 0.0F, ctx->DrawBuffer->Height,
535 -1.0F, 1.0F);
536 save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
537 if (ctx->Transform.ClipPlanesEnabled) {
538 GLuint i;
539 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
540 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
541 }
542 }
543 }
544
545 if (state & META_VERTEX) {
546 /* save vertex array object state */
547 _mesa_reference_array_object(ctx, &save->ArrayObj,
548 ctx->Array.ArrayObj);
549 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
550 ctx->Array.ArrayBufferObj);
551 /* set some default state? */
552 }
553
554 if (state & META_VIEWPORT) {
555 /* save viewport state */
556 save->ViewportX = ctx->Viewport.X;
557 save->ViewportY = ctx->Viewport.Y;
558 save->ViewportW = ctx->Viewport.Width;
559 save->ViewportH = ctx->Viewport.Height;
560 /* set viewport to match window size */
561 if (ctx->Viewport.X != 0 ||
562 ctx->Viewport.Y != 0 ||
563 ctx->Viewport.Width != ctx->DrawBuffer->Width ||
564 ctx->Viewport.Height != ctx->DrawBuffer->Height) {
565 _mesa_set_viewport(ctx, 0, 0,
566 ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
567 }
568 /* save depth range state */
569 save->DepthNear = ctx->Viewport.Near;
570 save->DepthFar = ctx->Viewport.Far;
571 /* set depth range to default */
572 _mesa_DepthRange(0.0, 1.0);
573 }
574
575 /* misc */
576 {
577 save->Lighting = ctx->Light.Enabled;
578 if (ctx->Light.Enabled)
579 _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
580 }
581 }
582
583
584 /**
585 * Leave meta state. This is like a light-weight version of glPopAttrib().
586 */
587 static void
588 _mesa_meta_end(GLcontext *ctx)
589 {
590 struct save_state *save = &ctx->Meta->Save;
591 const GLbitfield state = save->SavedState;
592
593 if (state & META_ALPHA_TEST) {
594 if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
595 _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
596 }
597
598 if (state & META_BLEND) {
599 if (ctx->Color.BlendEnabled != save->BlendEnabled)
600 _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled);
601 if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
602 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
603 }
604
605 if (state & META_COLOR_MASK) {
606 if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask))
607 _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
608 save->ColorMask[2], save->ColorMask[3]);
609 }
610
611 if (state & META_DEPTH_TEST) {
612 if (ctx->Depth.Test != save->Depth.Test)
613 _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
614 _mesa_DepthFunc(save->Depth.Func);
615 _mesa_DepthMask(save->Depth.Mask);
616 }
617
618 if (state & META_FOG) {
619 _mesa_set_enable(ctx, GL_FOG, save->Fog);
620 }
621
622 if (state & META_PIXEL_STORE) {
623 ctx->Pack = save->Pack;
624 ctx->Unpack = save->Unpack;
625 }
626
627 if (state & META_PIXEL_TRANSFER) {
628 ctx->Pixel.RedScale = save->RedScale;
629 ctx->Pixel.RedBias = save->RedBias;
630 ctx->Pixel.GreenScale = save->GreenScale;
631 ctx->Pixel.GreenBias = save->GreenBias;
632 ctx->Pixel.BlueScale = save->BlueScale;
633 ctx->Pixel.BlueBias = save->BlueBias;
634 ctx->Pixel.AlphaScale = save->AlphaScale;
635 ctx->Pixel.AlphaBias = save->AlphaBias;
636 ctx->Pixel.MapColorFlag = save->MapColorFlag;
637 ctx->Pixel.Convolution1DEnabled = save->Convolution1DEnabled;
638 ctx->Pixel.Convolution2DEnabled = save->Convolution2DEnabled;
639 ctx->Pixel.Separable2DEnabled = save->Separable2DEnabled;
640 /* XXX more state */
641 ctx->NewState |=_NEW_PIXEL;
642 }
643
644 if (state & META_RASTERIZATION) {
645 _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
646 _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
647 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
648 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
649 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
650 _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
651 }
652
653 if (state & META_SCISSOR) {
654 _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
655 _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
656 save->Scissor.Width, save->Scissor.Height);
657 }
658
659 if (state & META_SHADER) {
660 if (ctx->Extensions.ARB_vertex_program) {
661 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
662 save->VertexProgramEnabled);
663 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
664 save->VertexProgram);
665 }
666
667 if (ctx->Extensions.ARB_fragment_program) {
668 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
669 save->FragmentProgramEnabled);
670 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
671 save->FragmentProgram);
672 }
673
674 if (ctx->Extensions.ARB_shader_objects) {
675 _mesa_UseProgramObjectARB(save->Shader);
676 }
677 }
678
679 if (state & META_STENCIL_TEST) {
680 const struct gl_stencil_attrib *stencil = &save->Stencil;
681
682 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
683 _mesa_ClearStencil(stencil->Clear);
684 if (ctx->Extensions.EXT_stencil_two_side) {
685 _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
686 stencil->TestTwoSide);
687 _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
688 ? GL_BACK : GL_FRONT);
689 }
690 /* front state */
691 _mesa_StencilFuncSeparate(GL_FRONT,
692 stencil->Function[0],
693 stencil->Ref[0],
694 stencil->ValueMask[0]);
695 _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
696 _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
697 stencil->ZFailFunc[0],
698 stencil->ZPassFunc[0]);
699 /* back state */
700 _mesa_StencilFuncSeparate(GL_BACK,
701 stencil->Function[1],
702 stencil->Ref[1],
703 stencil->ValueMask[1]);
704 _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
705 _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
706 stencil->ZFailFunc[1],
707 stencil->ZPassFunc[1]);
708 }
709
710 if (state & META_TEXTURE) {
711 GLuint u, tgt;
712
713 ASSERT(ctx->Texture.CurrentUnit == 0);
714
715 /* restore texenv for unit[0] */
716 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
717
718 /* restore texture objects for unit[0] only */
719 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
720 _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
721 save->CurrentTexture[tgt]);
722 }
723
724 /* Re-enable textures, texgen */
725 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
726 if (save->TexEnabled[u]) {
727 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
728
729 if (save->TexEnabled[u] & TEXTURE_1D_BIT)
730 _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
731 if (save->TexEnabled[u] & TEXTURE_2D_BIT)
732 _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
733 if (save->TexEnabled[u] & TEXTURE_3D_BIT)
734 _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
735 if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
736 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
737 if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
738 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
739 }
740
741 if (save->TexGenEnabled[u]) {
742 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
743
744 if (save->TexGenEnabled[u] & S_BIT)
745 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
746 if (save->TexGenEnabled[u] & T_BIT)
747 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
748 if (save->TexGenEnabled[u] & R_BIT)
749 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
750 if (save->TexGenEnabled[u] & Q_BIT)
751 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
752 }
753 }
754
755 /* restore current unit state */
756 _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
757 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
758 }
759
760 if (state & META_TRANSFORM) {
761 GLuint activeTexture = ctx->Texture.CurrentUnit;
762 _mesa_ActiveTextureARB(GL_TEXTURE0);
763 _mesa_MatrixMode(GL_TEXTURE);
764 _mesa_LoadMatrixf(save->TextureMatrix);
765 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
766
767 _mesa_MatrixMode(GL_MODELVIEW);
768 _mesa_LoadMatrixf(save->ModelviewMatrix);
769
770 _mesa_MatrixMode(GL_PROJECTION);
771 _mesa_LoadMatrixf(save->ProjectionMatrix);
772
773 _mesa_MatrixMode(save->MatrixMode);
774
775 if (save->ClipPlanesEnabled) {
776 GLuint i;
777 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
778 if (save->ClipPlanesEnabled & (1 << i)) {
779 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
780 }
781 }
782 }
783 }
784
785 if (state & META_VERTEX) {
786 /* restore vertex buffer object */
787 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
788 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
789
790 /* restore vertex array object */
791 _mesa_BindVertexArray(save->ArrayObj->Name);
792 _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
793 }
794
795 if (state & META_VIEWPORT) {
796 if (save->ViewportX != ctx->Viewport.X ||
797 save->ViewportY != ctx->Viewport.Y ||
798 save->ViewportW != ctx->Viewport.Width ||
799 save->ViewportH != ctx->Viewport.Height) {
800 _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
801 save->ViewportW, save->ViewportH);
802 }
803 _mesa_DepthRange(save->DepthNear, save->DepthFar);
804 }
805
806 /* misc */
807 if (save->Lighting) {
808 _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
809 }
810 }
811
812
813 /**
814 * One-time init for a temp_texture object.
815 * Choose tex target, compute max tex size, etc.
816 */
817 static void
818 init_temp_texture(GLcontext *ctx, struct temp_texture *tex)
819 {
820 /* prefer texture rectangle */
821 if (ctx->Extensions.NV_texture_rectangle) {
822 tex->Target = GL_TEXTURE_RECTANGLE;
823 tex->MaxSize = ctx->Const.MaxTextureRectSize;
824 tex->NPOT = GL_TRUE;
825 }
826 else {
827 /* use 2D texture, NPOT if possible */
828 tex->Target = GL_TEXTURE_2D;
829 tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
830 tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
831 }
832 tex->MinSize = 16; /* 16 x 16 at least */
833 assert(tex->MaxSize > 0);
834
835 _mesa_GenTextures(1, &tex->TexObj);
836 _mesa_BindTexture(tex->Target, tex->TexObj);
837 }
838
839
840 /**
841 * Return pointer to temp_texture info for non-bitmap ops.
842 * This does some one-time init if needed.
843 */
844 static struct temp_texture *
845 get_temp_texture(GLcontext *ctx)
846 {
847 struct temp_texture *tex = &ctx->Meta->TempTex;
848
849 if (!tex->TexObj) {
850 init_temp_texture(ctx, tex);
851 }
852
853 return tex;
854 }
855
856
857 /**
858 * Return pointer to temp_texture info for _mesa_meta_bitmap().
859 * We use a separate texture for bitmaps to reduce texture
860 * allocation/deallocation.
861 */
862 static struct temp_texture *
863 get_bitmap_temp_texture(GLcontext *ctx)
864 {
865 struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
866
867 if (!tex->TexObj) {
868 init_temp_texture(ctx, tex);
869 }
870
871 return tex;
872 }
873
874
875 /**
876 * Compute the width/height of texture needed to draw an image of the
877 * given size. Return a flag indicating whether the current texture
878 * can be re-used (glTexSubImage2D) or if a new texture needs to be
879 * allocated (glTexImage2D).
880 * Also, compute s/t texcoords for drawing.
881 *
882 * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
883 */
884 static GLboolean
885 alloc_texture(struct temp_texture *tex,
886 GLsizei width, GLsizei height, GLenum intFormat)
887 {
888 GLboolean newTex = GL_FALSE;
889
890 ASSERT(width <= tex->MaxSize);
891 ASSERT(height <= tex->MaxSize);
892
893 if (width > tex->Width ||
894 height > tex->Height ||
895 intFormat != tex->IntFormat) {
896 /* alloc new texture (larger or different format) */
897
898 if (tex->NPOT) {
899 /* use non-power of two size */
900 tex->Width = MAX2(tex->MinSize, width);
901 tex->Height = MAX2(tex->MinSize, height);
902 }
903 else {
904 /* find power of two size */
905 GLsizei w, h;
906 w = h = tex->MinSize;
907 while (w < width)
908 w *= 2;
909 while (h < height)
910 h *= 2;
911 tex->Width = w;
912 tex->Height = h;
913 }
914
915 tex->IntFormat = intFormat;
916
917 newTex = GL_TRUE;
918 }
919
920 /* compute texcoords */
921 if (tex->Target == GL_TEXTURE_RECTANGLE) {
922 tex->Sright = (GLfloat) width;
923 tex->Ttop = (GLfloat) height;
924 }
925 else {
926 tex->Sright = (GLfloat) width / tex->Width;
927 tex->Ttop = (GLfloat) height / tex->Height;
928 }
929
930 return newTex;
931 }
932
933
934 /**
935 * Setup/load texture for glCopyPixels or glBlitFramebuffer.
936 */
937 static void
938 setup_copypix_texture(struct temp_texture *tex,
939 GLboolean newTex,
940 GLint srcX, GLint srcY,
941 GLsizei width, GLsizei height, GLenum intFormat,
942 GLenum filter)
943 {
944 _mesa_BindTexture(tex->Target, tex->TexObj);
945 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
946 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
947 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
948
949 /* copy framebuffer image to texture */
950 if (newTex) {
951 /* create new tex image */
952 if (tex->Width == width && tex->Height == height) {
953 /* create new tex with framebuffer data */
954 _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
955 srcX, srcY, width, height, 0);
956 }
957 else {
958 /* create empty texture */
959 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
960 tex->Width, tex->Height, 0,
961 intFormat, GL_UNSIGNED_BYTE, NULL);
962 /* load image */
963 _mesa_CopyTexSubImage2D(tex->Target, 0,
964 0, 0, srcX, srcY, width, height);
965 }
966 }
967 else {
968 /* replace existing tex image */
969 _mesa_CopyTexSubImage2D(tex->Target, 0,
970 0, 0, srcX, srcY, width, height);
971 }
972 }
973
974
975 /**
976 * Setup/load texture for glDrawPixels.
977 */
978 static void
979 setup_drawpix_texture(struct temp_texture *tex,
980 GLboolean newTex,
981 GLenum texIntFormat,
982 GLsizei width, GLsizei height,
983 GLenum format, GLenum type,
984 const GLvoid *pixels)
985 {
986 _mesa_BindTexture(tex->Target, tex->TexObj);
987 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
988 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
989 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
990
991 /* copy pixel data to texture */
992 if (newTex) {
993 /* create new tex image */
994 if (tex->Width == width && tex->Height == height) {
995 /* create new tex and load image data */
996 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
997 tex->Width, tex->Height, 0, format, type, pixels);
998 }
999 else {
1000 /* create empty texture */
1001 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
1002 tex->Width, tex->Height, 0, format, type, NULL);
1003 /* load image */
1004 _mesa_TexSubImage2D(tex->Target, 0,
1005 0, 0, width, height, format, type, pixels);
1006 }
1007 }
1008 else {
1009 /* replace existing tex image */
1010 _mesa_TexSubImage2D(tex->Target, 0,
1011 0, 0, width, height, format, type, pixels);
1012 }
1013 }
1014
1015
1016
1017 /**
1018 * One-time init for drawing depth pixels.
1019 */
1020 static void
1021 init_blit_depth_pixels(GLcontext *ctx)
1022 {
1023 static const char *program =
1024 "!!ARBfp1.0\n"
1025 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1026 "END \n";
1027 char program2[200];
1028 struct blit_state *blit = &ctx->Meta->Blit;
1029 struct temp_texture *tex = get_temp_texture(ctx);
1030 const char *texTarget;
1031
1032 assert(blit->DepthFP == 0);
1033
1034 /* replace %s with "RECT" or "2D" */
1035 assert(strlen(program) + 4 < sizeof(program2));
1036 if (tex->Target == GL_TEXTURE_RECTANGLE)
1037 texTarget = "RECT";
1038 else
1039 texTarget = "2D";
1040 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1041
1042 _mesa_GenPrograms(1, &blit->DepthFP);
1043 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1044 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1045 strlen(program2), (const GLubyte *) program2);
1046 }
1047
1048
1049 /**
1050 * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
1051 * of texture mapping and polygon rendering.
1052 */
1053 void
1054 _mesa_meta_BlitFramebuffer(GLcontext *ctx,
1055 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1056 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1057 GLbitfield mask, GLenum filter)
1058 {
1059 struct blit_state *blit = &ctx->Meta->Blit;
1060 struct temp_texture *tex = get_temp_texture(ctx);
1061 const GLsizei maxTexSize = tex->MaxSize;
1062 const GLint srcX = MIN2(srcX0, srcX1);
1063 const GLint srcY = MIN2(srcY0, srcY1);
1064 const GLint srcW = abs(srcX1 - srcX0);
1065 const GLint srcH = abs(srcY1 - srcY0);
1066 const GLboolean srcFlipX = srcX1 < srcX0;
1067 const GLboolean srcFlipY = srcY1 < srcY0;
1068 struct vertex {
1069 GLfloat x, y, s, t;
1070 };
1071 struct vertex verts[4];
1072 GLboolean newTex;
1073
1074 if (srcW > maxTexSize || srcH > maxTexSize) {
1075 /* XXX avoid this fallback */
1076 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1077 dstX0, dstY0, dstX1, dstY1, mask, filter);
1078 return;
1079 }
1080
1081 if (srcFlipX) {
1082 GLint tmp = dstX0;
1083 dstX0 = dstX1;
1084 dstX1 = tmp;
1085 }
1086
1087 if (srcFlipY) {
1088 GLint tmp = dstY0;
1089 dstY0 = dstY1;
1090 dstY1 = tmp;
1091 }
1092
1093 /* only scissor effects blit so save/clear all other relevant state */
1094 _mesa_meta_begin(ctx, ~META_SCISSOR);
1095
1096 if (blit->ArrayObj == 0) {
1097 /* one-time setup */
1098
1099 /* create vertex array object */
1100 _mesa_GenVertexArrays(1, &blit->ArrayObj);
1101 _mesa_BindVertexArray(blit->ArrayObj);
1102
1103 /* create vertex array buffer */
1104 _mesa_GenBuffersARB(1, &blit->VBO);
1105 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1106 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1107 NULL, GL_DYNAMIC_DRAW_ARB);
1108
1109 /* setup vertex arrays */
1110 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1111 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1112 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1113 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1114 }
1115 else {
1116 _mesa_BindVertexArray(blit->ArrayObj);
1117 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1118 }
1119
1120 newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
1121
1122 /* vertex positions/texcoords (after texture allocation!) */
1123 {
1124 verts[0].x = (GLfloat) dstX0;
1125 verts[0].y = (GLfloat) dstY0;
1126 verts[1].x = (GLfloat) dstX1;
1127 verts[1].y = (GLfloat) dstY0;
1128 verts[2].x = (GLfloat) dstX1;
1129 verts[2].y = (GLfloat) dstY1;
1130 verts[3].x = (GLfloat) dstX0;
1131 verts[3].y = (GLfloat) dstY1;
1132
1133 verts[0].s = 0.0F;
1134 verts[0].t = 0.0F;
1135 verts[1].s = tex->Sright;
1136 verts[1].t = 0.0F;
1137 verts[2].s = tex->Sright;
1138 verts[2].t = tex->Ttop;
1139 verts[3].s = 0.0F;
1140 verts[3].t = tex->Ttop;
1141
1142 /* upload new vertex data */
1143 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1144 }
1145
1146 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1147
1148 if (mask & GL_COLOR_BUFFER_BIT) {
1149 setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
1150 GL_RGBA, filter);
1151 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1152 mask &= ~GL_COLOR_BUFFER_BIT;
1153 }
1154
1155 if (mask & GL_DEPTH_BUFFER_BIT) {
1156 GLuint *tmp = (GLuint *) _mesa_malloc(srcW * srcH * sizeof(GLuint));
1157 if (tmp) {
1158 if (!blit->DepthFP)
1159 init_blit_depth_pixels(ctx);
1160
1161 /* maybe change tex format here */
1162 newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
1163
1164 _mesa_ReadPixels(srcX, srcY, srcW, srcH,
1165 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1166
1167 setup_drawpix_texture(tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
1168 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1169
1170 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1171 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1172 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1173 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1174 _mesa_DepthFunc(GL_ALWAYS);
1175 _mesa_DepthMask(GL_TRUE);
1176
1177 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1178 mask &= ~GL_DEPTH_BUFFER_BIT;
1179
1180 _mesa_free(tmp);
1181 }
1182 }
1183
1184 if (mask & GL_STENCIL_BUFFER_BIT) {
1185 /* XXX can't easily do stencil */
1186 }
1187
1188 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1189
1190 _mesa_meta_end(ctx);
1191
1192 if (mask) {
1193 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1194 dstX0, dstY0, dstX1, dstY1, mask, filter);
1195 }
1196 }
1197
1198
1199 /**
1200 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
1201 */
1202 void
1203 _mesa_meta_Clear(GLcontext *ctx, GLbitfield buffers)
1204 {
1205 struct clear_state *clear = &ctx->Meta->Clear;
1206 struct vertex {
1207 GLfloat x, y, z, r, g, b, a;
1208 };
1209 struct vertex verts[4];
1210 /* save all state but scissor, pixel pack/unpack */
1211 GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;
1212
1213 if (buffers & BUFFER_BITS_COLOR) {
1214 /* if clearing color buffers, don't save/restore colormask */
1215 metaSave -= META_COLOR_MASK;
1216 }
1217
1218 _mesa_meta_begin(ctx, metaSave);
1219
1220 if (clear->ArrayObj == 0) {
1221 /* one-time setup */
1222
1223 /* create vertex array object */
1224 _mesa_GenVertexArrays(1, &clear->ArrayObj);
1225 _mesa_BindVertexArray(clear->ArrayObj);
1226
1227 /* create vertex array buffer */
1228 _mesa_GenBuffersARB(1, &clear->VBO);
1229 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1230 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1231 NULL, GL_DYNAMIC_DRAW_ARB);
1232
1233 /* setup vertex arrays */
1234 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1235 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1236 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1237 _mesa_EnableClientState(GL_COLOR_ARRAY);
1238 }
1239 else {
1240 _mesa_BindVertexArray(clear->ArrayObj);
1241 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1242 }
1243
1244 /* GL_COLOR_BUFFER_BIT */
1245 if (buffers & BUFFER_BITS_COLOR) {
1246 /* leave colormask, glDrawBuffer state as-is */
1247 }
1248 else {
1249 ASSERT(metaSave & META_COLOR_MASK);
1250 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1251 }
1252
1253 /* GL_DEPTH_BUFFER_BIT */
1254 if (buffers & BUFFER_BIT_DEPTH) {
1255 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1256 _mesa_DepthFunc(GL_ALWAYS);
1257 _mesa_DepthMask(GL_TRUE);
1258 }
1259 else {
1260 assert(!ctx->Depth.Test);
1261 }
1262
1263 /* GL_STENCIL_BUFFER_BIT */
1264 if (buffers & BUFFER_BIT_STENCIL) {
1265 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1266 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
1267 GL_REPLACE, GL_REPLACE, GL_REPLACE);
1268 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
1269 ctx->Stencil.Clear & 0x7fffffff,
1270 ctx->Stencil.WriteMask[0]);
1271 }
1272 else {
1273 assert(!ctx->Stencil.Enabled);
1274 }
1275
1276 /* vertex positions/colors */
1277 {
1278 const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
1279 const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
1280 const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
1281 const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
1282 const GLfloat z = 1.0 - 2.0 * ctx->Depth.Clear;
1283 GLuint i;
1284
1285 verts[0].x = x0;
1286 verts[0].y = y0;
1287 verts[0].z = z;
1288 verts[1].x = x1;
1289 verts[1].y = y0;
1290 verts[1].z = z;
1291 verts[2].x = x1;
1292 verts[2].y = y1;
1293 verts[2].z = z;
1294 verts[3].x = x0;
1295 verts[3].y = y1;
1296 verts[3].z = z;
1297
1298 /* vertex colors */
1299 for (i = 0; i < 4; i++) {
1300 verts[i].r = ctx->Color.ClearColor[0];
1301 verts[i].g = ctx->Color.ClearColor[1];
1302 verts[i].b = ctx->Color.ClearColor[2];
1303 verts[i].a = ctx->Color.ClearColor[3];
1304 }
1305
1306 /* upload new vertex data */
1307 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1308 }
1309
1310 /* draw quad */
1311 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1312
1313 _mesa_meta_end(ctx);
1314 }
1315
1316
1317 /**
1318 * Meta implementation of ctx->Driver.CopyPixels() in terms
1319 * of texture mapping and polygon rendering.
1320 */
1321 void
1322 _mesa_meta_CopyPixels(GLcontext *ctx, GLint srcX, GLint srcY,
1323 GLsizei width, GLsizei height,
1324 GLint dstX, GLint dstY, GLenum type)
1325 {
1326 struct copypix_state *copypix = &ctx->Meta->CopyPix;
1327 struct temp_texture *tex = get_temp_texture(ctx);
1328 struct vertex {
1329 GLfloat x, y, z, s, t;
1330 };
1331 struct vertex verts[4];
1332 GLboolean newTex;
1333 GLenum intFormat = GL_RGBA;
1334
1335 if (type != GL_COLOR ||
1336 ctx->_ImageTransferState ||
1337 ctx->Fog.Enabled ||
1338 width > tex->MaxSize ||
1339 height > tex->MaxSize) {
1340 /* XXX avoid this fallback */
1341 _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
1342 return;
1343 }
1344
1345 /* Most GL state applies to glCopyPixels, but a there's a few things
1346 * we need to override:
1347 */
1348 _mesa_meta_begin(ctx, (META_RASTERIZATION |
1349 META_SHADER |
1350 META_TEXTURE |
1351 META_TRANSFORM |
1352 META_VERTEX |
1353 META_VIEWPORT));
1354
1355 if (copypix->ArrayObj == 0) {
1356 /* one-time setup */
1357
1358 /* create vertex array object */
1359 _mesa_GenVertexArrays(1, &copypix->ArrayObj);
1360 _mesa_BindVertexArray(copypix->ArrayObj);
1361
1362 /* create vertex array buffer */
1363 _mesa_GenBuffersARB(1, &copypix->VBO);
1364 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1365 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1366 NULL, GL_DYNAMIC_DRAW_ARB);
1367
1368 /* setup vertex arrays */
1369 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1370 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1371 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1372 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1373 }
1374 else {
1375 _mesa_BindVertexArray(copypix->ArrayObj);
1376 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1377 }
1378
1379 newTex = alloc_texture(tex, width, height, intFormat);
1380
1381 /* vertex positions, texcoords (after texture allocation!) */
1382 {
1383 const GLfloat dstX0 = (GLfloat) dstX;
1384 const GLfloat dstY0 = (GLfloat) dstY;
1385 const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
1386 const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
1387 const GLfloat z = ctx->Current.RasterPos[2];
1388
1389 verts[0].x = dstX0;
1390 verts[0].y = dstY0;
1391 verts[0].z = z;
1392 verts[0].s = 0.0F;
1393 verts[0].t = 0.0F;
1394 verts[1].x = dstX1;
1395 verts[1].y = dstY0;
1396 verts[1].z = z;
1397 verts[1].s = tex->Sright;
1398 verts[1].t = 0.0F;
1399 verts[2].x = dstX1;
1400 verts[2].y = dstY1;
1401 verts[2].z = z;
1402 verts[2].s = tex->Sright;
1403 verts[2].t = tex->Ttop;
1404 verts[3].x = dstX0;
1405 verts[3].y = dstY1;
1406 verts[3].z = z;
1407 verts[3].s = 0.0F;
1408 verts[3].t = tex->Ttop;
1409
1410 /* upload new vertex data */
1411 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1412 }
1413
1414 /* Alloc/setup texture */
1415 setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
1416 GL_RGBA, GL_NEAREST);
1417
1418 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1419
1420 /* draw textured quad */
1421 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1422
1423 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1424
1425 _mesa_meta_end(ctx);
1426 }
1427
1428
1429
1430 /**
1431 * When the glDrawPixels() image size is greater than the max rectangle
1432 * texture size we use this function to break the glDrawPixels() image
1433 * into tiles which fit into the max texture size.
1434 */
1435 static void
1436 tiled_draw_pixels(GLcontext *ctx,
1437 GLint tileSize,
1438 GLint x, GLint y, GLsizei width, GLsizei height,
1439 GLenum format, GLenum type,
1440 const struct gl_pixelstore_attrib *unpack,
1441 const GLvoid *pixels)
1442 {
1443 struct gl_pixelstore_attrib tileUnpack = *unpack;
1444 GLint i, j;
1445
1446 if (tileUnpack.RowLength == 0)
1447 tileUnpack.RowLength = width;
1448
1449 for (i = 0; i < width; i += tileSize) {
1450 const GLint tileWidth = MIN2(tileSize, width - i);
1451 const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
1452
1453 tileUnpack.SkipPixels = unpack->SkipPixels + i;
1454
1455 for (j = 0; j < height; j += tileSize) {
1456 const GLint tileHeight = MIN2(tileSize, height - j);
1457 const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
1458
1459 tileUnpack.SkipRows = unpack->SkipRows + j;
1460
1461 _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
1462 format, type, &tileUnpack, pixels);
1463 }
1464 }
1465 }
1466
1467
1468 /**
1469 * One-time init for drawing stencil pixels.
1470 */
1471 static void
1472 init_draw_stencil_pixels(GLcontext *ctx)
1473 {
1474 /* This program is run eight times, once for each stencil bit.
1475 * The stencil values to draw are found in an 8-bit alpha texture.
1476 * We read the texture/stencil value and test if bit 'b' is set.
1477 * If the bit is not set, use KIL to kill the fragment.
1478 * Finally, we use the stencil test to update the stencil buffer.
1479 *
1480 * The basic algorithm for checking if a bit is set is:
1481 * if (is_odd(value / (1 << bit)))
1482 * result is one (or non-zero).
1483 * else
1484 * result is zero.
1485 * The program parameter contains three values:
1486 * parm.x = 255 / (1 << bit)
1487 * parm.y = 0.5
1488 * parm.z = 0.0
1489 */
1490 static const char *program =
1491 "!!ARBfp1.0\n"
1492 "PARAM parm = program.local[0]; \n"
1493 "TEMP t; \n"
1494 "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */
1495 "# t = t * 255 / bit \n"
1496 "MUL t.x, t.a, parm.x; \n"
1497 "# t = (int) t \n"
1498 "FRC t.y, t.x; \n"
1499 "SUB t.x, t.x, t.y; \n"
1500 "# t = t * 0.5 \n"
1501 "MUL t.x, t.x, parm.y; \n"
1502 "# t = fract(t.x) \n"
1503 "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
1504 "# t.x = (t.x == 0 ? 1 : 0) \n"
1505 "SGE t.x, -t.x, parm.z; \n"
1506 "KIL -t.x; \n"
1507 "# for debug only \n"
1508 "#MOV result.color, t.x; \n"
1509 "END \n";
1510 char program2[1000];
1511 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1512 struct temp_texture *tex = get_temp_texture(ctx);
1513 const char *texTarget;
1514
1515 assert(drawpix->StencilFP == 0);
1516
1517 /* replace %s with "RECT" or "2D" */
1518 assert(strlen(program) + 4 < sizeof(program2));
1519 if (tex->Target == GL_TEXTURE_RECTANGLE)
1520 texTarget = "RECT";
1521 else
1522 texTarget = "2D";
1523 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1524
1525 _mesa_GenPrograms(1, &drawpix->StencilFP);
1526 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1527 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1528 strlen(program2), (const GLubyte *) program2);
1529 }
1530
1531
1532 /**
1533 * One-time init for drawing depth pixels.
1534 */
1535 static void
1536 init_draw_depth_pixels(GLcontext *ctx)
1537 {
1538 static const char *program =
1539 "!!ARBfp1.0\n"
1540 "PARAM color = program.local[0]; \n"
1541 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1542 "MOV result.color, color; \n"
1543 "END \n";
1544 char program2[200];
1545 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1546 struct temp_texture *tex = get_temp_texture(ctx);
1547 const char *texTarget;
1548
1549 assert(drawpix->DepthFP == 0);
1550
1551 /* replace %s with "RECT" or "2D" */
1552 assert(strlen(program) + 4 < sizeof(program2));
1553 if (tex->Target == GL_TEXTURE_RECTANGLE)
1554 texTarget = "RECT";
1555 else
1556 texTarget = "2D";
1557 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1558
1559 _mesa_GenPrograms(1, &drawpix->DepthFP);
1560 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
1561 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1562 strlen(program2), (const GLubyte *) program2);
1563 }
1564
1565
1566 /**
1567 * Meta implementation of ctx->Driver.DrawPixels() in terms
1568 * of texture mapping and polygon rendering.
1569 */
1570 void
1571 _mesa_meta_DrawPixels(GLcontext *ctx,
1572 GLint x, GLint y, GLsizei width, GLsizei height,
1573 GLenum format, GLenum type,
1574 const struct gl_pixelstore_attrib *unpack,
1575 const GLvoid *pixels)
1576 {
1577 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1578 struct temp_texture *tex = get_temp_texture(ctx);
1579 const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
1580 const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
1581 struct vertex {
1582 GLfloat x, y, z, s, t;
1583 };
1584 struct vertex verts[4];
1585 GLenum texIntFormat;
1586 GLboolean fallback, newTex;
1587 GLbitfield metaExtraSave = 0x0;
1588
1589 /*
1590 * Determine if we can do the glDrawPixels with texture mapping.
1591 */
1592 fallback = GL_FALSE;
1593 if (ctx->_ImageTransferState ||
1594 ctx->Fog.Enabled) {
1595 fallback = GL_TRUE;
1596 }
1597
1598 if (_mesa_is_color_format(format)) {
1599 /* use more compact format when possible */
1600 /* XXX disable special case for GL_LUMINANCE for now to work around
1601 * apparent i965 driver bug (see bug #23670).
1602 */
1603 if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
1604 texIntFormat = format;
1605 else
1606 texIntFormat = GL_RGBA;
1607 }
1608 else if (_mesa_is_stencil_format(format)) {
1609 if (ctx->Extensions.ARB_fragment_program &&
1610 ctx->Pixel.IndexShift == 0 &&
1611 ctx->Pixel.IndexOffset == 0 &&
1612 type == GL_UNSIGNED_BYTE) {
1613 /* We'll store stencil as alpha. This only works for GLubyte
1614 * image data because of how incoming values are mapped to alpha
1615 * in [0,1].
1616 */
1617 texIntFormat = GL_ALPHA;
1618 metaExtraSave = (META_COLOR_MASK |
1619 META_DEPTH_TEST |
1620 META_SHADER |
1621 META_STENCIL_TEST);
1622 }
1623 else {
1624 fallback = GL_TRUE;
1625 }
1626 }
1627 else if (_mesa_is_depth_format(format)) {
1628 if (ctx->Extensions.ARB_depth_texture &&
1629 ctx->Extensions.ARB_fragment_program) {
1630 texIntFormat = GL_DEPTH_COMPONENT;
1631 metaExtraSave = (META_SHADER);
1632 }
1633 else {
1634 fallback = GL_TRUE;
1635 }
1636 }
1637 else {
1638 fallback = GL_TRUE;
1639 }
1640
1641 if (fallback) {
1642 _swrast_DrawPixels(ctx, x, y, width, height,
1643 format, type, unpack, pixels);
1644 return;
1645 }
1646
1647 /*
1648 * Check image size against max texture size, draw as tiles if needed.
1649 */
1650 if (width > tex->MaxSize || height > tex->MaxSize) {
1651 tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
1652 format, type, unpack, pixels);
1653 return;
1654 }
1655
1656 /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
1657 * but a there's a few things we need to override:
1658 */
1659 _mesa_meta_begin(ctx, (META_RASTERIZATION |
1660 META_SHADER |
1661 META_TEXTURE |
1662 META_TRANSFORM |
1663 META_VERTEX |
1664 META_VIEWPORT |
1665 metaExtraSave));
1666
1667 if (drawpix->ArrayObj == 0) {
1668 /* one-time setup */
1669
1670 /* create vertex array object */
1671 _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
1672 _mesa_BindVertexArray(drawpix->ArrayObj);
1673
1674 /* create vertex array buffer */
1675 _mesa_GenBuffersARB(1, &drawpix->VBO);
1676 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
1677 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1678 NULL, GL_DYNAMIC_DRAW_ARB);
1679
1680 /* setup vertex arrays */
1681 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1682 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1683 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1684 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1685 }
1686 else {
1687 _mesa_BindVertexArray(drawpix->ArrayObj);
1688 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
1689 }
1690
1691 newTex = alloc_texture(tex, width, height, texIntFormat);
1692
1693 /* vertex positions, texcoords (after texture allocation!) */
1694 {
1695 const GLfloat x0 = (GLfloat) x;
1696 const GLfloat y0 = (GLfloat) y;
1697 const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
1698 const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
1699 const GLfloat z = ctx->Current.RasterPos[2];
1700
1701 verts[0].x = x0;
1702 verts[0].y = y0;
1703 verts[0].z = z;
1704 verts[0].s = 0.0F;
1705 verts[0].t = 0.0F;
1706 verts[1].x = x1;
1707 verts[1].y = y0;
1708 verts[1].z = z;
1709 verts[1].s = tex->Sright;
1710 verts[1].t = 0.0F;
1711 verts[2].x = x1;
1712 verts[2].y = y1;
1713 verts[2].z = z;
1714 verts[2].s = tex->Sright;
1715 verts[2].t = tex->Ttop;
1716 verts[3].x = x0;
1717 verts[3].y = y1;
1718 verts[3].z = z;
1719 verts[3].s = 0.0F;
1720 verts[3].t = tex->Ttop;
1721
1722 /* upload new vertex data */
1723 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1724 }
1725
1726 /* set given unpack params */
1727 ctx->Unpack = *unpack;
1728
1729 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1730
1731 if (_mesa_is_stencil_format(format)) {
1732 /* Drawing stencil */
1733 GLint bit;
1734
1735 if (!drawpix->StencilFP)
1736 init_draw_stencil_pixels(ctx);
1737
1738 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1739 GL_ALPHA, type, pixels);
1740
1741 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1742
1743 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1744
1745 /* set all stencil bits to 0 */
1746 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1747 _mesa_StencilFunc(GL_ALWAYS, 0, 255);
1748 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1749
1750 /* set stencil bits to 1 where needed */
1751 _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1752
1753 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1754 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1755
1756 for (bit = 0; bit < ctx->Visual.stencilBits; bit++) {
1757 const GLuint mask = 1 << bit;
1758 if (mask & origStencilMask) {
1759 _mesa_StencilFunc(GL_ALWAYS, mask, mask);
1760 _mesa_StencilMask(mask);
1761
1762 _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
1763 255.0 / mask, 0.5, 0.0, 0.0);
1764
1765 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1766 }
1767 }
1768 }
1769 else if (_mesa_is_depth_format(format)) {
1770 /* Drawing depth */
1771 if (!drawpix->DepthFP)
1772 init_draw_depth_pixels(ctx);
1773
1774 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
1775 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1776
1777 /* polygon color = current raster color */
1778 _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
1779 ctx->Current.RasterColor);
1780
1781 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1782 format, type, pixels);
1783
1784 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1785 }
1786 else {
1787 /* Drawing RGBA */
1788 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1789 format, type, pixels);
1790 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1791 }
1792
1793 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1794
1795 /* restore unpack params */
1796 ctx->Unpack = unpackSave;
1797
1798 _mesa_meta_end(ctx);
1799 }
1800
1801
1802 /**
1803 * Do glBitmap with a alpha texture quad. Use the alpha test to
1804 * cull the 'off' bits. If alpha test is already enabled, fall back
1805 * to swrast (should be a rare case).
1806 * A bitmap cache as in the gallium/mesa state tracker would
1807 * improve performance a lot.
1808 */
1809 void
1810 _mesa_meta_Bitmap(GLcontext *ctx,
1811 GLint x, GLint y, GLsizei width, GLsizei height,
1812 const struct gl_pixelstore_attrib *unpack,
1813 const GLubyte *bitmap1)
1814 {
1815 struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
1816 struct temp_texture *tex = get_bitmap_temp_texture(ctx);
1817 const GLenum texIntFormat = GL_ALPHA;
1818 const struct gl_pixelstore_attrib unpackSave = *unpack;
1819 struct vertex {
1820 GLfloat x, y, z, s, t, r, g, b, a;
1821 };
1822 struct vertex verts[4];
1823 GLboolean newTex;
1824 GLubyte *bitmap8;
1825
1826 /*
1827 * Check if swrast fallback is needed.
1828 */
1829 if (ctx->_ImageTransferState ||
1830 ctx->Color.AlphaEnabled ||
1831 ctx->Fog.Enabled ||
1832 ctx->Texture._EnabledUnits ||
1833 width > tex->MaxSize ||
1834 height > tex->MaxSize) {
1835 _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
1836 return;
1837 }
1838
1839 /* Most GL state applies to glBitmap (like blending, stencil, etc),
1840 * but a there's a few things we need to override:
1841 */
1842 _mesa_meta_begin(ctx, (META_ALPHA_TEST |
1843 META_PIXEL_STORE |
1844 META_RASTERIZATION |
1845 META_SHADER |
1846 META_TEXTURE |
1847 META_TRANSFORM |
1848 META_VERTEX |
1849 META_VIEWPORT));
1850
1851 if (bitmap->ArrayObj == 0) {
1852 /* one-time setup */
1853
1854 /* create vertex array object */
1855 _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
1856 _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
1857
1858 /* create vertex array buffer */
1859 _mesa_GenBuffersARB(1, &bitmap->VBO);
1860 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
1861 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1862 NULL, GL_DYNAMIC_DRAW_ARB);
1863
1864 /* setup vertex arrays */
1865 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1866 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1867 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1868 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1869 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1870 _mesa_EnableClientState(GL_COLOR_ARRAY);
1871 }
1872 else {
1873 _mesa_BindVertexArray(bitmap->ArrayObj);
1874 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
1875 }
1876
1877 newTex = alloc_texture(tex, width, height, texIntFormat);
1878
1879 /* vertex positions, texcoords, colors (after texture allocation!) */
1880 {
1881 const GLfloat x0 = (GLfloat) x;
1882 const GLfloat y0 = (GLfloat) y;
1883 const GLfloat x1 = (GLfloat) (x + width);
1884 const GLfloat y1 = (GLfloat) (y + height);
1885 const GLfloat z = ctx->Current.RasterPos[2];
1886 GLuint i;
1887
1888 verts[0].x = x0;
1889 verts[0].y = y0;
1890 verts[0].z = z;
1891 verts[0].s = 0.0F;
1892 verts[0].t = 0.0F;
1893 verts[1].x = x1;
1894 verts[1].y = y0;
1895 verts[1].z = z;
1896 verts[1].s = tex->Sright;
1897 verts[1].t = 0.0F;
1898 verts[2].x = x1;
1899 verts[2].y = y1;
1900 verts[2].z = z;
1901 verts[2].s = tex->Sright;
1902 verts[2].t = tex->Ttop;
1903 verts[3].x = x0;
1904 verts[3].y = y1;
1905 verts[3].z = z;
1906 verts[3].s = 0.0F;
1907 verts[3].t = tex->Ttop;
1908
1909 for (i = 0; i < 4; i++) {
1910 verts[i].r = ctx->Current.RasterColor[0];
1911 verts[i].g = ctx->Current.RasterColor[1];
1912 verts[i].b = ctx->Current.RasterColor[2];
1913 verts[i].a = ctx->Current.RasterColor[3];
1914 }
1915
1916 /* upload new vertex data */
1917 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1918 }
1919
1920 bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
1921 if (!bitmap1)
1922 return;
1923
1924 bitmap8 = (GLubyte *) _mesa_calloc(width * height);
1925 if (bitmap8) {
1926 _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
1927 bitmap8, width, 0xff);
1928
1929 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1930
1931 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
1932 _mesa_AlphaFunc(GL_GREATER, 0.0);
1933
1934 setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
1935 GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
1936
1937 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1938
1939 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1940
1941 _mesa_free(bitmap8);
1942 }
1943
1944 _mesa_unmap_pbo_source(ctx, &unpackSave);
1945
1946 _mesa_meta_end(ctx);
1947 }
1948
1949
1950 void
1951 _mesa_meta_GenerateMipmap(GLcontext *ctx, GLenum target,
1952 struct gl_texture_object *texObj)
1953 {
1954 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
1955 struct vertex {
1956 GLfloat x, y, s, t, r;
1957 };
1958 struct vertex verts[4];
1959 const GLuint baseLevel = texObj->BaseLevel;
1960 const GLuint maxLevel = texObj->MaxLevel;
1961 const GLenum minFilterSave = texObj->MinFilter;
1962 const GLenum magFilterSave = texObj->MagFilter;
1963 const GLuint fboSave = ctx->DrawBuffer->Name;
1964 GLenum faceTarget;
1965 GLuint level;
1966 GLuint border = 0;
1967
1968 /* check for fallbacks */
1969 if (!ctx->Extensions.EXT_framebuffer_object) {
1970 _mesa_generate_mipmap(ctx, target, texObj);
1971 return;
1972 }
1973
1974 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
1975 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
1976 faceTarget = target;
1977 target = GL_TEXTURE_CUBE_MAP;
1978 }
1979 else {
1980 faceTarget = target;
1981 }
1982
1983 _mesa_meta_begin(ctx, META_ALL);
1984
1985 if (mipmap->ArrayObj == 0) {
1986 /* one-time setup */
1987
1988 /* create vertex array object */
1989 _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
1990 _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
1991
1992 /* create vertex array buffer */
1993 _mesa_GenBuffersARB(1, &mipmap->VBO);
1994 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
1995 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1996 NULL, GL_DYNAMIC_DRAW_ARB);
1997
1998 /* setup vertex arrays */
1999 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2000 _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
2001 _mesa_EnableClientState(GL_VERTEX_ARRAY);
2002 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2003 }
2004 else {
2005 _mesa_BindVertexArray(mipmap->ArrayObj);
2006 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
2007 }
2008
2009 if (!mipmap->FBO) {
2010 /* Bind the new renderbuffer to the color attachment point. */
2011 _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
2012 }
2013
2014 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
2015
2016 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2017 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2018 _mesa_set_enable(ctx, target, GL_TRUE);
2019
2020 /* setup texcoords once (XXX what about border?) */
2021 switch (faceTarget) {
2022 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2023 break;
2024 case GL_TEXTURE_2D:
2025 verts[0].s = 0.0F;
2026 verts[0].t = 0.0F;
2027 verts[0].r = 0.0F;
2028 verts[1].s = 1.0F;
2029 verts[1].t = 0.0F;
2030 verts[1].r = 0.0F;
2031 verts[2].s = 1.0F;
2032 verts[2].t = 1.0F;
2033 verts[2].r = 0.0F;
2034 verts[3].s = 0.0F;
2035 verts[3].t = 1.0F;
2036 verts[3].r = 0.0F;
2037 break;
2038 }
2039
2040
2041 for (level = baseLevel + 1; level <= maxLevel; level++) {
2042 const struct gl_texture_image *srcImage;
2043 const GLuint srcLevel = level - 1;
2044 GLsizei srcWidth, srcHeight;
2045 GLsizei newWidth, newHeight;
2046 GLenum status;
2047
2048 srcImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
2049 assert(srcImage->Border == 0); /* XXX we can fix this */
2050
2051 srcWidth = srcImage->Width - 2 * border;
2052 srcHeight = srcImage->Height - 2 * border;
2053
2054 newWidth = MAX2(1, srcWidth / 2) + 2 * border;
2055 newHeight = MAX2(1, srcHeight / 2) + 2 * border;
2056
2057 if (newWidth == srcImage->Width && newHeight == srcImage->Height) {
2058 break;
2059 }
2060
2061 /* Create empty image */
2062 _mesa_TexImage2D(GL_TEXTURE_2D, level, srcImage->InternalFormat,
2063 newWidth, newHeight, border,
2064 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2065
2066 /* vertex positions */
2067 {
2068 verts[0].x = 0.0F;
2069 verts[0].y = 0.0F;
2070 verts[1].x = (GLfloat) newWidth;
2071 verts[1].y = 0.0F;
2072 verts[2].x = (GLfloat) newWidth;
2073 verts[2].y = (GLfloat) newHeight;
2074 verts[3].x = 0.0F;
2075 verts[3].y = (GLfloat) newHeight;
2076
2077 /* upload new vertex data */
2078 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2079 }
2080
2081 /* limit sampling to src level */
2082 _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, srcLevel);
2083 _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, srcLevel);
2084
2085 /* Set to draw into the current level */
2086 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2087 GL_COLOR_ATTACHMENT0_EXT,
2088 target,
2089 texObj->Name,
2090 level);
2091
2092 /* Choose to render to the color attachment. */
2093 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
2094
2095 status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
2096 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2097 abort();
2098 break;
2099 }
2100
2101 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2102 }
2103
2104 _mesa_meta_end(ctx);
2105
2106 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
2107 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
2108
2109 /* restore (XXX add to meta_begin/end()? */
2110 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
2111 }
2112
2113
2114 /**
2115 * Determine the GL data type to use for the temporary image read with
2116 * ReadPixels() and passed to Tex[Sub]Image().
2117 */
2118 static GLenum
2119 get_temp_image_type(GLcontext *ctx, GLenum baseFormat)
2120 {
2121 switch (baseFormat) {
2122 case GL_RGBA:
2123 case GL_RGB:
2124 case GL_ALPHA:
2125 case GL_LUMINANCE:
2126 case GL_LUMINANCE_ALPHA:
2127 case GL_INTENSITY:
2128 if (ctx->DrawBuffer->Visual.redBits <= 8)
2129 return GL_UNSIGNED_BYTE;
2130 else if (ctx->DrawBuffer->Visual.redBits <= 8)
2131 return GL_UNSIGNED_SHORT;
2132 else
2133 return GL_FLOAT;
2134 case GL_DEPTH_COMPONENT:
2135 return GL_UNSIGNED_INT;
2136 case GL_DEPTH_STENCIL:
2137 return GL_UNSIGNED_INT_24_8;
2138 default:
2139 _mesa_problem(ctx, "Unexpected format in get_temp_image_type()");
2140 return 0;
2141 }
2142 }
2143
2144
2145 /**
2146 * Helper for _mesa_meta_CopyTexImage1/2D() functions.
2147 * Have to be careful with locking and meta state for pixel transfer.
2148 */
2149 static void
2150 copy_tex_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level,
2151 GLenum internalFormat, GLint x, GLint y,
2152 GLsizei width, GLsizei height, GLint border)
2153 {
2154 struct gl_texture_unit *texUnit;
2155 struct gl_texture_object *texObj;
2156 struct gl_texture_image *texImage;
2157 GLsizei postConvWidth = width, postConvHeight = height;
2158 GLenum format, type;
2159 GLint bpp;
2160 void *buf;
2161
2162 texUnit = _mesa_get_current_tex_unit(ctx);
2163 texObj = _mesa_select_tex_object(ctx, texUnit, target);
2164 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
2165
2166 format = _mesa_base_tex_format(ctx, internalFormat);
2167 type = get_temp_image_type(ctx, format);
2168 bpp = _mesa_bytes_per_pixel(format, type);
2169 if (bpp <= 0) {
2170 _mesa_problem(ctx, "Bad bpp in meta copy_tex_image()");
2171 return;
2172 }
2173
2174 /*
2175 * Alloc image buffer (XXX could use a PBO)
2176 */
2177 buf = _mesa_malloc(width * height * bpp);
2178 if (!buf) {
2179 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2180 return;
2181 }
2182
2183 _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
2184
2185 /*
2186 * Read image from framebuffer (disable pixel transfer ops)
2187 */
2188 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2189 ctx->Driver.ReadPixels(ctx, x, y, width, height,
2190 format, type, &ctx->Pack, buf);
2191 _mesa_meta_end(ctx);
2192
2193 /*
2194 * Prepare for new texture image size/data
2195 */
2196 #if FEATURE_convolve
2197 if (_mesa_is_color_format(internalFormat)) {
2198 _mesa_adjust_image_for_convolution(ctx, 2,
2199 &postConvWidth, &postConvHeight);
2200 }
2201 #endif
2202
2203 if (texImage->Data) {
2204 ctx->Driver.FreeTexImageData(ctx, texImage);
2205 }
2206
2207 _mesa_init_teximage_fields(ctx, target, texImage,
2208 postConvWidth, postConvHeight, 1,
2209 border, internalFormat);
2210
2211 /*
2212 * Store texture data (with pixel transfer ops)
2213 */
2214 _mesa_meta_begin(ctx, META_PIXEL_STORE);
2215
2216 _mesa_update_state(ctx); /* to update pixel transfer state */
2217
2218 if (target == GL_TEXTURE_1D) {
2219 ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
2220 width, border, format, type,
2221 buf, &ctx->Unpack, texObj, texImage);
2222 }
2223 else {
2224 ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
2225 width, height, border, format, type,
2226 buf, &ctx->Unpack, texObj, texImage);
2227 }
2228 _mesa_meta_end(ctx);
2229
2230 _mesa_lock_texture(ctx, texObj); /* re-lock */
2231
2232 _mesa_free(buf);
2233 }
2234
2235
2236 void
2237 _mesa_meta_CopyTexImage1D(GLcontext *ctx, GLenum target, GLint level,
2238 GLenum internalFormat, GLint x, GLint y,
2239 GLsizei width, GLint border)
2240 {
2241 copy_tex_image(ctx, 1, target, level, internalFormat, x, y,
2242 width, 1, border);
2243 }
2244
2245
2246 void
2247 _mesa_meta_CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level,
2248 GLenum internalFormat, GLint x, GLint y,
2249 GLsizei width, GLsizei height, GLint border)
2250 {
2251 copy_tex_image(ctx, 2, target, level, internalFormat, x, y,
2252 width, height, border);
2253 }
2254
2255
2256
2257 /**
2258 * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
2259 * Have to be careful with locking and meta state for pixel transfer.
2260 */
2261 static void
2262 copy_tex_sub_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level,
2263 GLint xoffset, GLint yoffset, GLint zoffset,
2264 GLint x, GLint y,
2265 GLsizei width, GLsizei height)
2266 {
2267 struct gl_texture_unit *texUnit;
2268 struct gl_texture_object *texObj;
2269 struct gl_texture_image *texImage;
2270 GLenum format, type;
2271 GLint bpp;
2272 void *buf;
2273
2274 texUnit = _mesa_get_current_tex_unit(ctx);
2275 texObj = _mesa_select_tex_object(ctx, texUnit, target);
2276 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2277
2278 format = texImage->TexFormat->BaseFormat;
2279 type = get_temp_image_type(ctx, format);
2280 bpp = _mesa_bytes_per_pixel(format, type);
2281 if (bpp <= 0) {
2282 _mesa_problem(ctx, "Bad bpp in meta copy_tex_sub_image()");
2283 return;
2284 }
2285
2286 /*
2287 * Alloc image buffer (XXX could use a PBO)
2288 */
2289 buf = _mesa_malloc(width * height * bpp);
2290 if (!buf) {
2291 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims);
2292 return;
2293 }
2294
2295 _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
2296
2297 /*
2298 * Read image from framebuffer (disable pixel transfer ops)
2299 */
2300 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2301 ctx->Driver.ReadPixels(ctx, x, y, width, height,
2302 format, type, &ctx->Pack, buf);
2303 _mesa_meta_end(ctx);
2304
2305 _mesa_update_state(ctx); /* to update pixel transfer state */
2306
2307 /*
2308 * Store texture data (with pixel transfer ops)
2309 */
2310 _mesa_meta_begin(ctx, META_PIXEL_STORE);
2311 if (target == GL_TEXTURE_1D) {
2312 ctx->Driver.TexSubImage1D(ctx, target, level, xoffset,
2313 width, format, type, buf,
2314 &ctx->Unpack, texObj, texImage);
2315 }
2316 else if (target == GL_TEXTURE_3D) {
2317 ctx->Driver.TexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset,
2318 width, height, 1, format, type, buf,
2319 &ctx->Unpack, texObj, texImage);
2320 }
2321 else {
2322 ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
2323 width, height, format, type, buf,
2324 &ctx->Unpack, texObj, texImage);
2325 }
2326 _mesa_meta_end(ctx);
2327
2328 _mesa_lock_texture(ctx, texObj); /* re-lock */
2329
2330 _mesa_free(buf);
2331 }
2332
2333
2334 void
2335 _mesa_meta_CopyTexSubImage1D(GLcontext *ctx, GLenum target, GLint level,
2336 GLint xoffset,
2337 GLint x, GLint y, GLsizei width)
2338 {
2339 copy_tex_sub_image(ctx, 1, target, level, xoffset, 0, 0,
2340 x, y, width, 1);
2341 }
2342
2343
2344 void
2345 _mesa_meta_CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
2346 GLint xoffset, GLint yoffset,
2347 GLint x, GLint y,
2348 GLsizei width, GLsizei height)
2349 {
2350 copy_tex_sub_image(ctx, 2, target, level, xoffset, yoffset, 0,
2351 x, y, width, height);
2352 }
2353
2354
2355 void
2356 _mesa_meta_CopyTexSubImage3D(GLcontext *ctx, GLenum target, GLint level,
2357 GLint xoffset, GLint yoffset, GLint zoffset,
2358 GLint x, GLint y,
2359 GLsizei width, GLsizei height)
2360 {
2361 copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset,
2362 x, y, width, height);
2363 }
2364
2365
2366 void
2367 _mesa_meta_CopyColorTable(GLcontext *ctx,
2368 GLenum target, GLenum internalformat,
2369 GLint x, GLint y, GLsizei width)
2370 {
2371 GLfloat *buf;
2372
2373 buf = (GLfloat *) _mesa_malloc(width * 4 * sizeof(GLfloat));
2374 if (!buf) {
2375 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorTable");
2376 return;
2377 }
2378
2379 /*
2380 * Read image from framebuffer (disable pixel transfer ops)
2381 */
2382 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2383 ctx->Driver.ReadPixels(ctx, x, y, width, 1,
2384 GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
2385
2386 _mesa_ColorTable(target, internalformat, width, GL_RGBA, GL_FLOAT, buf);
2387
2388 _mesa_meta_end(ctx);
2389
2390 _mesa_free(buf);
2391 }
2392
2393
2394 void
2395 _mesa_meta_CopyColorSubTable(GLcontext *ctx,GLenum target, GLsizei start,
2396 GLint x, GLint y, GLsizei width)
2397 {
2398 GLfloat *buf;
2399
2400 buf = (GLfloat *) _mesa_malloc(width * 4 * sizeof(GLfloat));
2401 if (!buf) {
2402 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorSubTable");
2403 return;
2404 }
2405
2406 /*
2407 * Read image from framebuffer (disable pixel transfer ops)
2408 */
2409 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2410 ctx->Driver.ReadPixels(ctx, x, y, width, 1,
2411 GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
2412
2413 _mesa_ColorSubTable(target, start, width, GL_RGBA, GL_FLOAT, buf);
2414
2415 _mesa_meta_end(ctx);
2416
2417 _mesa_free(buf);
2418 }
2419
2420
2421 void
2422 _mesa_meta_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
2423 GLenum internalFormat,
2424 GLint x, GLint y, GLsizei width)
2425 {
2426 GLfloat *buf;
2427
2428 buf = (GLfloat *) _mesa_malloc(width * 4 * sizeof(GLfloat));
2429 if (!buf) {
2430 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyConvolutionFilter2D");
2431 return;
2432 }
2433
2434 /*
2435 * Read image from framebuffer (disable pixel transfer ops)
2436 */
2437 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2438 _mesa_update_state(ctx);
2439 ctx->Driver.ReadPixels(ctx, x, y, width, 1,
2440 GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
2441
2442 _mesa_ConvolutionFilter1D(target, internalFormat, width,
2443 GL_RGBA, GL_FLOAT, buf);
2444
2445 _mesa_meta_end(ctx);
2446
2447 _mesa_free(buf);
2448 }
2449
2450
2451 void
2452 _mesa_meta_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
2453 GLenum internalFormat, GLint x, GLint y,
2454 GLsizei width, GLsizei height)
2455 {
2456 GLfloat *buf;
2457
2458 buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
2459 if (!buf) {
2460 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyConvolutionFilter2D");
2461 return;
2462 }
2463
2464 /*
2465 * Read image from framebuffer (disable pixel transfer ops)
2466 */
2467 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2468 _mesa_update_state(ctx);
2469
2470 ctx->Driver.ReadPixels(ctx, x, y, width, height,
2471 GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
2472
2473 _mesa_ConvolutionFilter2D(target, internalFormat, width, height,
2474 GL_RGBA, GL_FLOAT, buf);
2475
2476 _mesa_meta_end(ctx);
2477
2478 _mesa_free(buf);
2479 }