Merge remote branch 'origin/master' into pipe-video
[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/arbprogram.h"
38 #include "main/arrayobj.h"
39 #include "main/blend.h"
40 #include "main/bufferobj.h"
41 #include "main/buffers.h"
42 #include "main/colortab.h"
43 #include "main/depth.h"
44 #include "main/enable.h"
45 #include "main/fbobject.h"
46 #include "main/formats.h"
47 #include "main/image.h"
48 #include "main/macros.h"
49 #include "main/matrix.h"
50 #include "main/mipmap.h"
51 #include "main/pbo.h"
52 #include "main/polygon.h"
53 #include "main/readpix.h"
54 #include "main/scissor.h"
55 #include "main/shaderapi.h"
56 #include "main/shaderobj.h"
57 #include "main/state.h"
58 #include "main/stencil.h"
59 #include "main/texobj.h"
60 #include "main/texenv.h"
61 #include "main/teximage.h"
62 #include "main/texparam.h"
63 #include "main/texstate.h"
64 #include "main/varray.h"
65 #include "main/viewport.h"
66 #include "program/program.h"
67 #include "swrast/swrast.h"
68 #include "drivers/common/meta.h"
69
70
71 /** Return offset in bytes of the field within a vertex struct */
72 #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
73
74
75 /**
76 * Flags passed to _mesa_meta_begin().
77 */
78 /*@{*/
79 #define META_ALL ~0x0
80 #define META_ALPHA_TEST 0x1
81 #define META_BLEND 0x2 /**< includes logicop */
82 #define META_COLOR_MASK 0x4
83 #define META_DEPTH_TEST 0x8
84 #define META_FOG 0x10
85 #define META_PIXEL_STORE 0x20
86 #define META_PIXEL_TRANSFER 0x40
87 #define META_RASTERIZATION 0x80
88 #define META_SCISSOR 0x100
89 #define META_SHADER 0x200
90 #define META_STENCIL_TEST 0x400
91 #define META_TRANSFORM 0x800 /**< modelview, projection, clip planes */
92 #define META_TEXTURE 0x1000
93 #define META_VERTEX 0x2000
94 #define META_VIEWPORT 0x4000
95 #define META_CLAMP_FRAGMENT_COLOR 0x8000
96 #define META_CLAMP_VERTEX_COLOR 0x10000
97 /*@}*/
98
99
100 /**
101 * State which we may save/restore across meta ops.
102 * XXX this may be incomplete...
103 */
104 struct save_state
105 {
106 GLbitfield SavedState; /**< bitmask of META_* flags */
107
108 /** META_ALPHA_TEST */
109 GLboolean AlphaEnabled;
110 GLenum AlphaFunc;
111 GLclampf AlphaRef;
112
113 /** META_BLEND */
114 GLbitfield BlendEnabled;
115 GLboolean ColorLogicOpEnabled;
116
117 /** META_COLOR_MASK */
118 GLubyte ColorMask[MAX_DRAW_BUFFERS][4];
119
120 /** META_DEPTH_TEST */
121 struct gl_depthbuffer_attrib Depth;
122
123 /** META_FOG */
124 GLboolean Fog;
125
126 /** META_PIXEL_STORE */
127 struct gl_pixelstore_attrib Pack, Unpack;
128
129 /** META_PIXEL_TRANSFER */
130 GLfloat RedBias, RedScale;
131 GLfloat GreenBias, GreenScale;
132 GLfloat BlueBias, BlueScale;
133 GLfloat AlphaBias, AlphaScale;
134 GLfloat DepthBias, DepthScale;
135 GLboolean MapColorFlag;
136
137 /** META_RASTERIZATION */
138 GLenum FrontPolygonMode, BackPolygonMode;
139 GLboolean PolygonOffset;
140 GLboolean PolygonSmooth;
141 GLboolean PolygonStipple;
142 GLboolean PolygonCull;
143
144 /** META_SCISSOR */
145 struct gl_scissor_attrib Scissor;
146
147 /** META_SHADER */
148 GLboolean VertexProgramEnabled;
149 struct gl_vertex_program *VertexProgram;
150 GLboolean FragmentProgramEnabled;
151 struct gl_fragment_program *FragmentProgram;
152 struct gl_shader_program *VertexShader;
153 struct gl_shader_program *GeometryShader;
154 struct gl_shader_program *FragmentShader;
155 struct gl_shader_program *ActiveShader;
156
157 /** META_STENCIL_TEST */
158 struct gl_stencil_attrib Stencil;
159
160 /** META_TRANSFORM */
161 GLenum MatrixMode;
162 GLfloat ModelviewMatrix[16];
163 GLfloat ProjectionMatrix[16];
164 GLfloat TextureMatrix[16];
165 GLbitfield ClipPlanesEnabled;
166
167 /** META_TEXTURE */
168 GLuint ActiveUnit;
169 GLuint ClientActiveUnit;
170 /** for unit[0] only */
171 struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
172 /** mask of TEXTURE_2D_BIT, etc */
173 GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
174 GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
175 GLuint EnvMode; /* unit[0] only */
176
177 /** META_VERTEX */
178 struct gl_array_object *ArrayObj;
179 struct gl_buffer_object *ArrayBufferObj;
180
181 /** META_VIEWPORT */
182 GLint ViewportX, ViewportY, ViewportW, ViewportH;
183 GLclampd DepthNear, DepthFar;
184
185 /** META_CLAMP_FRAGMENT_COLOR */
186 GLenum ClampFragmentColor;
187
188 /** META_CLAMP_VERTEX_COLOR */
189 GLenum ClampVertexColor;
190
191 /** Miscellaneous (always disabled) */
192 GLboolean Lighting;
193 };
194
195
196 /**
197 * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
198 * This is currently shared by all the meta ops. But we could create a
199 * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
200 */
201 struct temp_texture
202 {
203 GLuint TexObj;
204 GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
205 GLsizei MinSize; /**< Min texture size to allocate */
206 GLsizei MaxSize; /**< Max possible texture size */
207 GLboolean NPOT; /**< Non-power of two size OK? */
208 GLsizei Width, Height; /**< Current texture size */
209 GLenum IntFormat;
210 GLfloat Sright, Ttop; /**< right, top texcoords */
211 };
212
213
214 /**
215 * State for glBlitFramebufer()
216 */
217 struct blit_state
218 {
219 GLuint ArrayObj;
220 GLuint VBO;
221 GLuint DepthFP;
222 };
223
224
225 /**
226 * State for glClear()
227 */
228 struct clear_state
229 {
230 GLuint ArrayObj;
231 GLuint VBO;
232 };
233
234
235 /**
236 * State for glCopyPixels()
237 */
238 struct copypix_state
239 {
240 GLuint ArrayObj;
241 GLuint VBO;
242 };
243
244
245 /**
246 * State for glDrawPixels()
247 */
248 struct drawpix_state
249 {
250 GLuint ArrayObj;
251
252 GLuint StencilFP; /**< Fragment program for drawing stencil images */
253 GLuint DepthFP; /**< Fragment program for drawing depth images */
254 };
255
256
257 /**
258 * State for glBitmap()
259 */
260 struct bitmap_state
261 {
262 GLuint ArrayObj;
263 GLuint VBO;
264 struct temp_texture Tex; /**< separate texture from other meta ops */
265 };
266
267
268 /**
269 * State for _mesa_meta_generate_mipmap()
270 */
271 struct gen_mipmap_state
272 {
273 GLuint ArrayObj;
274 GLuint VBO;
275 GLuint FBO;
276 };
277
278 #define MAX_META_OPS_DEPTH 2
279 /**
280 * All per-context meta state.
281 */
282 struct gl_meta_state
283 {
284 /** Stack of state saved during meta-ops */
285 struct save_state Save[MAX_META_OPS_DEPTH];
286 /** Save stack depth */
287 GLuint SaveStackDepth;
288
289 struct temp_texture TempTex;
290
291 struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */
292 struct clear_state Clear; /**< For _mesa_meta_Clear() */
293 struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */
294 struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */
295 struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */
296 struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */
297 };
298
299
300 /**
301 * Initialize meta-ops for a context.
302 * To be called once during context creation.
303 */
304 void
305 _mesa_meta_init(struct gl_context *ctx)
306 {
307 ASSERT(!ctx->Meta);
308
309 ctx->Meta = CALLOC_STRUCT(gl_meta_state);
310 }
311
312
313 /**
314 * Free context meta-op state.
315 * To be called once during context destruction.
316 */
317 void
318 _mesa_meta_free(struct gl_context *ctx)
319 {
320 /* Note: Any textures, VBOs, etc, that we allocate should get
321 * freed by the normal context destruction code. But this would be
322 * the place to free other meta data someday.
323 */
324 free(ctx->Meta);
325 ctx->Meta = NULL;
326 }
327
328
329 /**
330 * Enter meta state. This is like a light-weight version of glPushAttrib
331 * but it also resets most GL state back to default values.
332 *
333 * \param state bitmask of META_* flags indicating which attribute groups
334 * to save and reset to their defaults
335 */
336 static void
337 _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
338 {
339 struct save_state *save;
340
341 /* hope MAX_META_OPS_DEPTH is large enough */
342 assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH);
343
344 save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++];
345 memset(save, 0, sizeof(*save));
346 save->SavedState = state;
347
348 if (state & META_ALPHA_TEST) {
349 save->AlphaEnabled = ctx->Color.AlphaEnabled;
350 save->AlphaFunc = ctx->Color.AlphaFunc;
351 save->AlphaRef = ctx->Color.AlphaRef;
352 if (ctx->Color.AlphaEnabled)
353 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
354 }
355
356 if (state & META_BLEND) {
357 save->BlendEnabled = ctx->Color.BlendEnabled;
358 if (ctx->Color.BlendEnabled) {
359 if (ctx->Extensions.EXT_draw_buffers2) {
360 GLuint i;
361 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
362 _mesa_set_enablei(ctx, GL_BLEND, i, GL_FALSE);
363 }
364 }
365 else {
366 _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
367 }
368 }
369 save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
370 if (ctx->Color.ColorLogicOpEnabled)
371 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
372 }
373
374 if (state & META_COLOR_MASK) {
375 memcpy(save->ColorMask, ctx->Color.ColorMask,
376 sizeof(ctx->Color.ColorMask));
377 if (!ctx->Color.ColorMask[0][0] ||
378 !ctx->Color.ColorMask[0][1] ||
379 !ctx->Color.ColorMask[0][2] ||
380 !ctx->Color.ColorMask[0][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 ctx->Pixel.RedScale = 1.0F;
414 ctx->Pixel.RedBias = 0.0F;
415 ctx->Pixel.GreenScale = 1.0F;
416 ctx->Pixel.GreenBias = 0.0F;
417 ctx->Pixel.BlueScale = 1.0F;
418 ctx->Pixel.BlueBias = 0.0F;
419 ctx->Pixel.AlphaScale = 1.0F;
420 ctx->Pixel.AlphaBias = 0.0F;
421 ctx->Pixel.MapColorFlag = GL_FALSE;
422 /* XXX more state */
423 ctx->NewState |=_NEW_PIXEL;
424 }
425
426 if (state & META_RASTERIZATION) {
427 save->FrontPolygonMode = ctx->Polygon.FrontMode;
428 save->BackPolygonMode = ctx->Polygon.BackMode;
429 save->PolygonOffset = ctx->Polygon.OffsetFill;
430 save->PolygonSmooth = ctx->Polygon.SmoothFlag;
431 save->PolygonStipple = ctx->Polygon.StippleFlag;
432 save->PolygonCull = ctx->Polygon.CullFlag;
433 _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
434 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
435 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
436 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
437 _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
438 }
439
440 if (state & META_SCISSOR) {
441 save->Scissor = ctx->Scissor; /* struct copy */
442 _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE);
443 }
444
445 if (state & META_SHADER) {
446 if (ctx->Extensions.ARB_vertex_program) {
447 save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
448 _mesa_reference_vertprog(ctx, &save->VertexProgram,
449 ctx->VertexProgram.Current);
450 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
451 }
452
453 if (ctx->Extensions.ARB_fragment_program) {
454 save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
455 _mesa_reference_fragprog(ctx, &save->FragmentProgram,
456 ctx->FragmentProgram.Current);
457 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
458 }
459
460 if (ctx->Extensions.ARB_shader_objects) {
461 _mesa_reference_shader_program(ctx, &save->VertexShader,
462 ctx->Shader.CurrentVertexProgram);
463 _mesa_reference_shader_program(ctx, &save->GeometryShader,
464 ctx->Shader.CurrentGeometryProgram);
465 _mesa_reference_shader_program(ctx, &save->FragmentShader,
466 ctx->Shader.CurrentFragmentProgram);
467 _mesa_reference_shader_program(ctx, &save->ActiveShader,
468 ctx->Shader.CurrentFragmentProgram);
469
470 _mesa_UseProgramObjectARB(0);
471 }
472 }
473
474 if (state & META_STENCIL_TEST) {
475 save->Stencil = ctx->Stencil; /* struct copy */
476 if (ctx->Stencil.Enabled)
477 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
478 /* NOTE: other stencil state not reset */
479 }
480
481 if (state & META_TEXTURE) {
482 GLuint u, tgt;
483
484 save->ActiveUnit = ctx->Texture.CurrentUnit;
485 save->ClientActiveUnit = ctx->Array.ActiveTexture;
486 save->EnvMode = ctx->Texture.Unit[0].EnvMode;
487
488 /* Disable all texture units */
489 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
490 save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
491 save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
492 if (ctx->Texture.Unit[u].Enabled ||
493 ctx->Texture.Unit[u].TexGenEnabled) {
494 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
495 _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
496 _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
497 _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
498 if (ctx->Extensions.ARB_texture_cube_map)
499 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
500 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
501 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
502 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
503 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
504 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
505 }
506 }
507
508 /* save current texture objects for unit[0] only */
509 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
510 _mesa_reference_texobj(&save->CurrentTexture[tgt],
511 ctx->Texture.Unit[0].CurrentTex[tgt]);
512 }
513
514 /* set defaults for unit[0] */
515 _mesa_ActiveTextureARB(GL_TEXTURE0);
516 _mesa_ClientActiveTextureARB(GL_TEXTURE0);
517 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
518 }
519
520 if (state & META_TRANSFORM) {
521 GLuint activeTexture = ctx->Texture.CurrentUnit;
522 memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
523 16 * sizeof(GLfloat));
524 memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
525 16 * sizeof(GLfloat));
526 memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
527 16 * sizeof(GLfloat));
528 save->MatrixMode = ctx->Transform.MatrixMode;
529 /* set 1:1 vertex:pixel coordinate transform */
530 _mesa_ActiveTextureARB(GL_TEXTURE0);
531 _mesa_MatrixMode(GL_TEXTURE);
532 _mesa_LoadIdentity();
533 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
534 _mesa_MatrixMode(GL_MODELVIEW);
535 _mesa_LoadIdentity();
536 _mesa_MatrixMode(GL_PROJECTION);
537 _mesa_LoadIdentity();
538 _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
539 0.0, ctx->DrawBuffer->Height,
540 -1.0, 1.0);
541 save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
542 if (ctx->Transform.ClipPlanesEnabled) {
543 GLuint i;
544 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
545 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
546 }
547 }
548 }
549
550 if (state & META_VERTEX) {
551 /* save vertex array object state */
552 _mesa_reference_array_object(ctx, &save->ArrayObj,
553 ctx->Array.ArrayObj);
554 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
555 ctx->Array.ArrayBufferObj);
556 /* set some default state? */
557 }
558
559 if (state & META_VIEWPORT) {
560 /* save viewport state */
561 save->ViewportX = ctx->Viewport.X;
562 save->ViewportY = ctx->Viewport.Y;
563 save->ViewportW = ctx->Viewport.Width;
564 save->ViewportH = ctx->Viewport.Height;
565 /* set viewport to match window size */
566 if (ctx->Viewport.X != 0 ||
567 ctx->Viewport.Y != 0 ||
568 ctx->Viewport.Width != ctx->DrawBuffer->Width ||
569 ctx->Viewport.Height != ctx->DrawBuffer->Height) {
570 _mesa_set_viewport(ctx, 0, 0,
571 ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
572 }
573 /* save depth range state */
574 save->DepthNear = ctx->Viewport.Near;
575 save->DepthFar = ctx->Viewport.Far;
576 /* set depth range to default */
577 _mesa_DepthRange(0.0, 1.0);
578 }
579
580 if (state & META_CLAMP_FRAGMENT_COLOR) {
581 save->ClampFragmentColor = ctx->Color.ClampFragmentColor;
582
583 /* Generally in here we want to do clamping according to whether
584 * it's for the pixel path (ClampFragmentColor is GL_TRUE),
585 * regardless of the internal implementation of the metaops.
586 */
587 if (ctx->Color.ClampFragmentColor != GL_TRUE)
588 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
589 }
590
591 if (state & META_CLAMP_VERTEX_COLOR) {
592 save->ClampVertexColor = ctx->Light.ClampVertexColor;
593
594 /* Generally in here we never want vertex color clamping --
595 * result clamping is only dependent on fragment clamping.
596 */
597 _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
598 }
599
600 /* misc */
601 {
602 save->Lighting = ctx->Light.Enabled;
603 if (ctx->Light.Enabled)
604 _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
605 }
606 }
607
608
609 /**
610 * Leave meta state. This is like a light-weight version of glPopAttrib().
611 */
612 static void
613 _mesa_meta_end(struct gl_context *ctx)
614 {
615 struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth];
616 const GLbitfield state = save->SavedState;
617
618 if (state & META_ALPHA_TEST) {
619 if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
620 _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
621 _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef);
622 }
623
624 if (state & META_BLEND) {
625 if (ctx->Color.BlendEnabled != save->BlendEnabled) {
626 if (ctx->Extensions.EXT_draw_buffers2) {
627 GLuint i;
628 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
629 _mesa_set_enablei(ctx, GL_BLEND, i, (save->BlendEnabled >> i) & 1);
630 }
631 }
632 else {
633 _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1));
634 }
635 }
636 if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
637 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
638 }
639
640 if (state & META_COLOR_MASK) {
641 GLuint i;
642 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
643 if (!TEST_EQ_4V(ctx->Color.ColorMask[i], save->ColorMask[i])) {
644 if (i == 0) {
645 _mesa_ColorMask(save->ColorMask[i][0], save->ColorMask[i][1],
646 save->ColorMask[i][2], save->ColorMask[i][3]);
647 }
648 else {
649 _mesa_ColorMaskIndexed(i,
650 save->ColorMask[i][0],
651 save->ColorMask[i][1],
652 save->ColorMask[i][2],
653 save->ColorMask[i][3]);
654 }
655 }
656 }
657 }
658
659 if (state & META_DEPTH_TEST) {
660 if (ctx->Depth.Test != save->Depth.Test)
661 _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
662 _mesa_DepthFunc(save->Depth.Func);
663 _mesa_DepthMask(save->Depth.Mask);
664 }
665
666 if (state & META_FOG) {
667 _mesa_set_enable(ctx, GL_FOG, save->Fog);
668 }
669
670 if (state & META_PIXEL_STORE) {
671 ctx->Pack = save->Pack;
672 ctx->Unpack = save->Unpack;
673 }
674
675 if (state & META_PIXEL_TRANSFER) {
676 ctx->Pixel.RedScale = save->RedScale;
677 ctx->Pixel.RedBias = save->RedBias;
678 ctx->Pixel.GreenScale = save->GreenScale;
679 ctx->Pixel.GreenBias = save->GreenBias;
680 ctx->Pixel.BlueScale = save->BlueScale;
681 ctx->Pixel.BlueBias = save->BlueBias;
682 ctx->Pixel.AlphaScale = save->AlphaScale;
683 ctx->Pixel.AlphaBias = save->AlphaBias;
684 ctx->Pixel.MapColorFlag = save->MapColorFlag;
685 /* XXX more state */
686 ctx->NewState |=_NEW_PIXEL;
687 }
688
689 if (state & META_RASTERIZATION) {
690 _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
691 _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
692 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
693 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
694 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
695 _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
696 }
697
698 if (state & META_SCISSOR) {
699 _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
700 _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
701 save->Scissor.Width, save->Scissor.Height);
702 }
703
704 if (state & META_SHADER) {
705 if (ctx->Extensions.ARB_vertex_program) {
706 _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
707 save->VertexProgramEnabled);
708 _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
709 save->VertexProgram);
710 _mesa_reference_vertprog(ctx, &save->VertexProgram, NULL);
711 }
712
713 if (ctx->Extensions.ARB_fragment_program) {
714 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
715 save->FragmentProgramEnabled);
716 _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
717 save->FragmentProgram);
718 _mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL);
719 }
720
721 if (ctx->Extensions.ARB_vertex_shader)
722 _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, save->VertexShader);
723
724 if (ctx->Extensions.ARB_geometry_shader4)
725 _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB,
726 save->GeometryShader);
727
728 if (ctx->Extensions.ARB_fragment_shader)
729 _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER,
730 save->FragmentShader);
731
732 _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram,
733 save->ActiveShader);
734 }
735
736 if (state & META_STENCIL_TEST) {
737 const struct gl_stencil_attrib *stencil = &save->Stencil;
738
739 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
740 _mesa_ClearStencil(stencil->Clear);
741 if (ctx->Extensions.EXT_stencil_two_side) {
742 _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
743 stencil->TestTwoSide);
744 _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
745 ? GL_BACK : GL_FRONT);
746 }
747 /* front state */
748 _mesa_StencilFuncSeparate(GL_FRONT,
749 stencil->Function[0],
750 stencil->Ref[0],
751 stencil->ValueMask[0]);
752 _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
753 _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
754 stencil->ZFailFunc[0],
755 stencil->ZPassFunc[0]);
756 /* back state */
757 _mesa_StencilFuncSeparate(GL_BACK,
758 stencil->Function[1],
759 stencil->Ref[1],
760 stencil->ValueMask[1]);
761 _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
762 _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
763 stencil->ZFailFunc[1],
764 stencil->ZPassFunc[1]);
765 }
766
767 if (state & META_TEXTURE) {
768 GLuint u, tgt;
769
770 ASSERT(ctx->Texture.CurrentUnit == 0);
771
772 /* restore texenv for unit[0] */
773 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
774
775 /* restore texture objects for unit[0] only */
776 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
777 _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
778 save->CurrentTexture[tgt]);
779 _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL);
780 }
781
782 /* Re-enable textures, texgen */
783 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
784 if (save->TexEnabled[u]) {
785 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
786
787 if (save->TexEnabled[u] & TEXTURE_1D_BIT)
788 _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
789 if (save->TexEnabled[u] & TEXTURE_2D_BIT)
790 _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
791 if (save->TexEnabled[u] & TEXTURE_3D_BIT)
792 _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
793 if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
794 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
795 if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
796 _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
797 }
798
799 if (save->TexGenEnabled[u]) {
800 _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
801
802 if (save->TexGenEnabled[u] & S_BIT)
803 _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
804 if (save->TexGenEnabled[u] & T_BIT)
805 _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
806 if (save->TexGenEnabled[u] & R_BIT)
807 _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
808 if (save->TexGenEnabled[u] & Q_BIT)
809 _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
810 }
811 }
812
813 /* restore current unit state */
814 _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
815 _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
816 }
817
818 if (state & META_TRANSFORM) {
819 GLuint activeTexture = ctx->Texture.CurrentUnit;
820 _mesa_ActiveTextureARB(GL_TEXTURE0);
821 _mesa_MatrixMode(GL_TEXTURE);
822 _mesa_LoadMatrixf(save->TextureMatrix);
823 _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
824
825 _mesa_MatrixMode(GL_MODELVIEW);
826 _mesa_LoadMatrixf(save->ModelviewMatrix);
827
828 _mesa_MatrixMode(GL_PROJECTION);
829 _mesa_LoadMatrixf(save->ProjectionMatrix);
830
831 _mesa_MatrixMode(save->MatrixMode);
832
833 if (save->ClipPlanesEnabled) {
834 GLuint i;
835 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
836 if (save->ClipPlanesEnabled & (1 << i)) {
837 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
838 }
839 }
840 }
841 }
842
843 if (state & META_VERTEX) {
844 /* restore vertex buffer object */
845 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
846 _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
847
848 /* restore vertex array object */
849 _mesa_BindVertexArray(save->ArrayObj->Name);
850 _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
851 }
852
853 if (state & META_VIEWPORT) {
854 if (save->ViewportX != ctx->Viewport.X ||
855 save->ViewportY != ctx->Viewport.Y ||
856 save->ViewportW != ctx->Viewport.Width ||
857 save->ViewportH != ctx->Viewport.Height) {
858 _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
859 save->ViewportW, save->ViewportH);
860 }
861 _mesa_DepthRange(save->DepthNear, save->DepthFar);
862 }
863
864 if (state & META_CLAMP_FRAGMENT_COLOR) {
865 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, save->ClampFragmentColor);
866 }
867
868 if (state & META_CLAMP_VERTEX_COLOR) {
869 _mesa_ClampColorARB(GL_CLAMP_VERTEX_COLOR, save->ClampVertexColor);
870 }
871
872 /* misc */
873 if (save->Lighting) {
874 _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
875 }
876 }
877
878
879 /**
880 * Convert Z from a normalized value in the range [0, 1] to an object-space
881 * Z coordinate in [-1, +1] so that drawing at the new Z position with the
882 * default/identity ortho projection results in the original Z value.
883 * Used by the meta-Clear, Draw/CopyPixels and Bitmap functions where the Z
884 * value comes from the clear value or raster position.
885 */
886 static INLINE GLfloat
887 invert_z(GLfloat normZ)
888 {
889 GLfloat objZ = 1.0 - 2.0 * normZ;
890 return objZ;
891 }
892
893
894 /**
895 * One-time init for a temp_texture object.
896 * Choose tex target, compute max tex size, etc.
897 */
898 static void
899 init_temp_texture(struct gl_context *ctx, struct temp_texture *tex)
900 {
901 /* prefer texture rectangle */
902 if (ctx->Extensions.NV_texture_rectangle) {
903 tex->Target = GL_TEXTURE_RECTANGLE;
904 tex->MaxSize = ctx->Const.MaxTextureRectSize;
905 tex->NPOT = GL_TRUE;
906 }
907 else {
908 /* use 2D texture, NPOT if possible */
909 tex->Target = GL_TEXTURE_2D;
910 tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
911 tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
912 }
913 tex->MinSize = 16; /* 16 x 16 at least */
914 assert(tex->MaxSize > 0);
915
916 _mesa_GenTextures(1, &tex->TexObj);
917 }
918
919
920 /**
921 * Return pointer to temp_texture info for non-bitmap ops.
922 * This does some one-time init if needed.
923 */
924 static struct temp_texture *
925 get_temp_texture(struct gl_context *ctx)
926 {
927 struct temp_texture *tex = &ctx->Meta->TempTex;
928
929 if (!tex->TexObj) {
930 init_temp_texture(ctx, tex);
931 }
932
933 return tex;
934 }
935
936
937 /**
938 * Return pointer to temp_texture info for _mesa_meta_bitmap().
939 * We use a separate texture for bitmaps to reduce texture
940 * allocation/deallocation.
941 */
942 static struct temp_texture *
943 get_bitmap_temp_texture(struct gl_context *ctx)
944 {
945 struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
946
947 if (!tex->TexObj) {
948 init_temp_texture(ctx, tex);
949 }
950
951 return tex;
952 }
953
954
955 /**
956 * Compute the width/height of texture needed to draw an image of the
957 * given size. Return a flag indicating whether the current texture
958 * can be re-used (glTexSubImage2D) or if a new texture needs to be
959 * allocated (glTexImage2D).
960 * Also, compute s/t texcoords for drawing.
961 *
962 * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
963 */
964 static GLboolean
965 alloc_texture(struct temp_texture *tex,
966 GLsizei width, GLsizei height, GLenum intFormat)
967 {
968 GLboolean newTex = GL_FALSE;
969
970 ASSERT(width <= tex->MaxSize);
971 ASSERT(height <= tex->MaxSize);
972
973 if (width > tex->Width ||
974 height > tex->Height ||
975 intFormat != tex->IntFormat) {
976 /* alloc new texture (larger or different format) */
977
978 if (tex->NPOT) {
979 /* use non-power of two size */
980 tex->Width = MAX2(tex->MinSize, width);
981 tex->Height = MAX2(tex->MinSize, height);
982 }
983 else {
984 /* find power of two size */
985 GLsizei w, h;
986 w = h = tex->MinSize;
987 while (w < width)
988 w *= 2;
989 while (h < height)
990 h *= 2;
991 tex->Width = w;
992 tex->Height = h;
993 }
994
995 tex->IntFormat = intFormat;
996
997 newTex = GL_TRUE;
998 }
999
1000 /* compute texcoords */
1001 if (tex->Target == GL_TEXTURE_RECTANGLE) {
1002 tex->Sright = (GLfloat) width;
1003 tex->Ttop = (GLfloat) height;
1004 }
1005 else {
1006 tex->Sright = (GLfloat) width / tex->Width;
1007 tex->Ttop = (GLfloat) height / tex->Height;
1008 }
1009
1010 return newTex;
1011 }
1012
1013
1014 /**
1015 * Setup/load texture for glCopyPixels or glBlitFramebuffer.
1016 */
1017 static void
1018 setup_copypix_texture(struct temp_texture *tex,
1019 GLboolean newTex,
1020 GLint srcX, GLint srcY,
1021 GLsizei width, GLsizei height, GLenum intFormat,
1022 GLenum filter)
1023 {
1024 _mesa_BindTexture(tex->Target, tex->TexObj);
1025 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
1026 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
1027 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1028
1029 /* copy framebuffer image to texture */
1030 if (newTex) {
1031 /* create new tex image */
1032 if (tex->Width == width && tex->Height == height) {
1033 /* create new tex with framebuffer data */
1034 _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
1035 srcX, srcY, width, height, 0);
1036 }
1037 else {
1038 /* create empty texture */
1039 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
1040 tex->Width, tex->Height, 0,
1041 intFormat, GL_UNSIGNED_BYTE, NULL);
1042 /* load image */
1043 _mesa_CopyTexSubImage2D(tex->Target, 0,
1044 0, 0, srcX, srcY, width, height);
1045 }
1046 }
1047 else {
1048 /* replace existing tex image */
1049 _mesa_CopyTexSubImage2D(tex->Target, 0,
1050 0, 0, srcX, srcY, width, height);
1051 }
1052 }
1053
1054
1055 /**
1056 * Setup/load texture for glDrawPixels.
1057 */
1058 static void
1059 setup_drawpix_texture(struct gl_context *ctx,
1060 struct temp_texture *tex,
1061 GLboolean newTex,
1062 GLenum texIntFormat,
1063 GLsizei width, GLsizei height,
1064 GLenum format, GLenum type,
1065 const GLvoid *pixels)
1066 {
1067 _mesa_BindTexture(tex->Target, tex->TexObj);
1068 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1069 _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1070 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1071
1072 /* copy pixel data to texture */
1073 if (newTex) {
1074 /* create new tex image */
1075 if (tex->Width == width && tex->Height == height) {
1076 /* create new tex and load image data */
1077 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
1078 tex->Width, tex->Height, 0, format, type, pixels);
1079 }
1080 else {
1081 struct gl_buffer_object *save_unpack_obj = NULL;
1082
1083 _mesa_reference_buffer_object(ctx, &save_unpack_obj,
1084 ctx->Unpack.BufferObj);
1085 _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
1086 /* create empty texture */
1087 _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
1088 tex->Width, tex->Height, 0, format, type, NULL);
1089 if (save_unpack_obj != NULL)
1090 _mesa_BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB,
1091 save_unpack_obj->Name);
1092 /* load image */
1093 _mesa_TexSubImage2D(tex->Target, 0,
1094 0, 0, width, height, format, type, pixels);
1095 }
1096 }
1097 else {
1098 /* replace existing tex image */
1099 _mesa_TexSubImage2D(tex->Target, 0,
1100 0, 0, width, height, format, type, pixels);
1101 }
1102 }
1103
1104
1105
1106 /**
1107 * One-time init for drawing depth pixels.
1108 */
1109 static void
1110 init_blit_depth_pixels(struct gl_context *ctx)
1111 {
1112 static const char *program =
1113 "!!ARBfp1.0\n"
1114 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1115 "END \n";
1116 char program2[200];
1117 struct blit_state *blit = &ctx->Meta->Blit;
1118 struct temp_texture *tex = get_temp_texture(ctx);
1119 const char *texTarget;
1120
1121 assert(blit->DepthFP == 0);
1122
1123 /* replace %s with "RECT" or "2D" */
1124 assert(strlen(program) + 4 < sizeof(program2));
1125 if (tex->Target == GL_TEXTURE_RECTANGLE)
1126 texTarget = "RECT";
1127 else
1128 texTarget = "2D";
1129 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1130
1131 _mesa_GenPrograms(1, &blit->DepthFP);
1132 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1133 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1134 strlen(program2), (const GLubyte *) program2);
1135 }
1136
1137
1138 /**
1139 * Try to do a glBlitFramebuffer using no-copy texturing.
1140 * We can do this when the src renderbuffer is actually a texture.
1141 * But if the src buffer == dst buffer we cannot do this.
1142 *
1143 * \return new buffer mask indicating the buffers left to blit using the
1144 * normal path.
1145 */
1146 static GLbitfield
1147 blitframebuffer_texture(struct gl_context *ctx,
1148 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1149 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1150 GLbitfield mask, GLenum filter)
1151 {
1152 if (mask & GL_COLOR_BUFFER_BIT) {
1153 const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
1154 const struct gl_framebuffer *readFb = ctx->ReadBuffer;
1155 const struct gl_renderbuffer_attachment *drawAtt =
1156 &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]];
1157 const struct gl_renderbuffer_attachment *readAtt =
1158 &readFb->Attachment[readFb->_ColorReadBufferIndex];
1159
1160 if (readAtt && readAtt->Texture) {
1161 const struct gl_texture_object *texObj = readAtt->Texture;
1162 const GLuint srcLevel = readAtt->TextureLevel;
1163 const GLenum minFilterSave = texObj->Sampler.MinFilter;
1164 const GLenum magFilterSave = texObj->Sampler.MagFilter;
1165 const GLint baseLevelSave = texObj->BaseLevel;
1166 const GLint maxLevelSave = texObj->MaxLevel;
1167 const GLenum wrapSSave = texObj->Sampler.WrapS;
1168 const GLenum wrapTSave = texObj->Sampler.WrapT;
1169 const GLenum target = texObj->Target;
1170
1171 if (drawAtt->Texture == readAtt->Texture) {
1172 /* Can't use same texture as both the source and dest. We need
1173 * to handle overlapping blits and besides, some hw may not
1174 * support this.
1175 */
1176 return mask;
1177 }
1178
1179 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_ARB) {
1180 /* Can't handle other texture types at this time */
1181 return mask;
1182 }
1183
1184 /*
1185 printf("Blit from texture!\n");
1186 printf(" srcAtt %p dstAtt %p\n", readAtt, drawAtt);
1187 printf(" srcTex %p dstText %p\n", texObj, drawAtt->Texture);
1188 */
1189
1190 /* Prepare src texture state */
1191 _mesa_BindTexture(target, texObj->Name);
1192 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
1193 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
1194 if (target != GL_TEXTURE_RECTANGLE_ARB) {
1195 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
1196 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
1197 }
1198 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1199 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1200 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1201 _mesa_set_enable(ctx, target, GL_TRUE);
1202
1203 /* Prepare vertex data (the VBO was previously created and bound) */
1204 {
1205 struct vertex {
1206 GLfloat x, y, s, t;
1207 };
1208 struct vertex verts[4];
1209 GLfloat s0, t0, s1, t1;
1210
1211 if (target == GL_TEXTURE_2D) {
1212 const struct gl_texture_image *texImage
1213 = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
1214 s0 = srcX0 / (float) texImage->Width;
1215 s1 = srcX1 / (float) texImage->Width;
1216 t0 = srcY0 / (float) texImage->Height;
1217 t1 = srcY1 / (float) texImage->Height;
1218 }
1219 else {
1220 assert(target == GL_TEXTURE_RECTANGLE_ARB);
1221 s0 = srcX0;
1222 s1 = srcX1;
1223 t0 = srcY0;
1224 t1 = srcY1;
1225 }
1226
1227 verts[0].x = (GLfloat) dstX0;
1228 verts[0].y = (GLfloat) dstY0;
1229 verts[1].x = (GLfloat) dstX1;
1230 verts[1].y = (GLfloat) dstY0;
1231 verts[2].x = (GLfloat) dstX1;
1232 verts[2].y = (GLfloat) dstY1;
1233 verts[3].x = (GLfloat) dstX0;
1234 verts[3].y = (GLfloat) dstY1;
1235
1236 verts[0].s = s0;
1237 verts[0].t = t0;
1238 verts[1].s = s1;
1239 verts[1].t = t0;
1240 verts[2].s = s1;
1241 verts[2].t = t1;
1242 verts[3].s = s0;
1243 verts[3].t = t1;
1244
1245 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1246 }
1247
1248 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1249
1250 /* Restore texture object state, the texture binding will
1251 * be restored by _mesa_meta_end().
1252 */
1253 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
1254 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
1255 if (target != GL_TEXTURE_RECTANGLE_ARB) {
1256 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
1257 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
1258 }
1259 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
1260 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
1261
1262 /* Done with color buffer */
1263 mask &= ~GL_COLOR_BUFFER_BIT;
1264 }
1265 }
1266
1267 return mask;
1268 }
1269
1270
1271 /**
1272 * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
1273 * of texture mapping and polygon rendering.
1274 */
1275 void
1276 _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
1277 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1278 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1279 GLbitfield mask, GLenum filter)
1280 {
1281 struct blit_state *blit = &ctx->Meta->Blit;
1282 struct temp_texture *tex = get_temp_texture(ctx);
1283 const GLsizei maxTexSize = tex->MaxSize;
1284 const GLint srcX = MIN2(srcX0, srcX1);
1285 const GLint srcY = MIN2(srcY0, srcY1);
1286 const GLint srcW = abs(srcX1 - srcX0);
1287 const GLint srcH = abs(srcY1 - srcY0);
1288 const GLboolean srcFlipX = srcX1 < srcX0;
1289 const GLboolean srcFlipY = srcY1 < srcY0;
1290 struct vertex {
1291 GLfloat x, y, s, t;
1292 };
1293 struct vertex verts[4];
1294 GLboolean newTex;
1295
1296 if (srcW > maxTexSize || srcH > maxTexSize) {
1297 /* XXX avoid this fallback */
1298 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1299 dstX0, dstY0, dstX1, dstY1, mask, filter);
1300 return;
1301 }
1302
1303 if (srcFlipX) {
1304 GLint tmp = dstX0;
1305 dstX0 = dstX1;
1306 dstX1 = tmp;
1307 }
1308
1309 if (srcFlipY) {
1310 GLint tmp = dstY0;
1311 dstY0 = dstY1;
1312 dstY1 = tmp;
1313 }
1314
1315 /* only scissor effects blit so save/clear all other relevant state */
1316 _mesa_meta_begin(ctx, ~META_SCISSOR);
1317
1318 if (blit->ArrayObj == 0) {
1319 /* one-time setup */
1320
1321 /* create vertex array object */
1322 _mesa_GenVertexArrays(1, &blit->ArrayObj);
1323 _mesa_BindVertexArray(blit->ArrayObj);
1324
1325 /* create vertex array buffer */
1326 _mesa_GenBuffersARB(1, &blit->VBO);
1327 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1328 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1329 NULL, GL_DYNAMIC_DRAW_ARB);
1330
1331 /* setup vertex arrays */
1332 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1333 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1334 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1335 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1336 }
1337 else {
1338 _mesa_BindVertexArray(blit->ArrayObj);
1339 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
1340 }
1341
1342 /* Try faster, direct texture approach first */
1343 mask = blitframebuffer_texture(ctx, srcX0, srcY0, srcX1, srcY1,
1344 dstX0, dstY0, dstX1, dstY1, mask, filter);
1345 if (mask == 0x0) {
1346 _mesa_meta_end(ctx);
1347 return;
1348 }
1349
1350 /* Continue with "normal" approach which involves copying the src rect
1351 * into a temporary texture and is "blitted" by drawing a textured quad.
1352 */
1353
1354 newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
1355
1356 /* vertex positions/texcoords (after texture allocation!) */
1357 {
1358 verts[0].x = (GLfloat) dstX0;
1359 verts[0].y = (GLfloat) dstY0;
1360 verts[1].x = (GLfloat) dstX1;
1361 verts[1].y = (GLfloat) dstY0;
1362 verts[2].x = (GLfloat) dstX1;
1363 verts[2].y = (GLfloat) dstY1;
1364 verts[3].x = (GLfloat) dstX0;
1365 verts[3].y = (GLfloat) dstY1;
1366
1367 verts[0].s = 0.0F;
1368 verts[0].t = 0.0F;
1369 verts[1].s = tex->Sright;
1370 verts[1].t = 0.0F;
1371 verts[2].s = tex->Sright;
1372 verts[2].t = tex->Ttop;
1373 verts[3].s = 0.0F;
1374 verts[3].t = tex->Ttop;
1375
1376 /* upload new vertex data */
1377 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1378 }
1379
1380 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1381
1382 if (mask & GL_COLOR_BUFFER_BIT) {
1383 setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
1384 GL_RGBA, filter);
1385 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1386 mask &= ~GL_COLOR_BUFFER_BIT;
1387 }
1388
1389 if (mask & GL_DEPTH_BUFFER_BIT) {
1390 GLuint *tmp = (GLuint *) malloc(srcW * srcH * sizeof(GLuint));
1391 if (tmp) {
1392 if (!blit->DepthFP)
1393 init_blit_depth_pixels(ctx);
1394
1395 /* maybe change tex format here */
1396 newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
1397
1398 _mesa_ReadPixels(srcX, srcY, srcW, srcH,
1399 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1400
1401 setup_drawpix_texture(ctx, tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
1402 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
1403
1404 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
1405 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1406 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1407 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1408 _mesa_DepthFunc(GL_ALWAYS);
1409 _mesa_DepthMask(GL_TRUE);
1410
1411 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1412 mask &= ~GL_DEPTH_BUFFER_BIT;
1413
1414 free(tmp);
1415 }
1416 }
1417
1418 if (mask & GL_STENCIL_BUFFER_BIT) {
1419 /* XXX can't easily do stencil */
1420 }
1421
1422 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1423
1424 _mesa_meta_end(ctx);
1425
1426 if (mask) {
1427 _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
1428 dstX0, dstY0, dstX1, dstY1, mask, filter);
1429 }
1430 }
1431
1432
1433 /**
1434 * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
1435 */
1436 void
1437 _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)
1438 {
1439 struct clear_state *clear = &ctx->Meta->Clear;
1440 struct vertex {
1441 GLfloat x, y, z, r, g, b, a;
1442 };
1443 struct vertex verts[4];
1444 /* save all state but scissor, pixel pack/unpack */
1445 GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;
1446 const GLuint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
1447
1448 if (buffers & BUFFER_BITS_COLOR) {
1449 /* if clearing color buffers, don't save/restore colormask */
1450 metaSave -= META_COLOR_MASK;
1451 }
1452
1453 _mesa_meta_begin(ctx, metaSave);
1454
1455 if (clear->ArrayObj == 0) {
1456 /* one-time setup */
1457
1458 /* create vertex array object */
1459 _mesa_GenVertexArrays(1, &clear->ArrayObj);
1460 _mesa_BindVertexArray(clear->ArrayObj);
1461
1462 /* create vertex array buffer */
1463 _mesa_GenBuffersARB(1, &clear->VBO);
1464 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1465
1466 /* setup vertex arrays */
1467 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1468 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
1469 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1470 _mesa_EnableClientState(GL_COLOR_ARRAY);
1471 }
1472 else {
1473 _mesa_BindVertexArray(clear->ArrayObj);
1474 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
1475 }
1476
1477 /* GL_COLOR_BUFFER_BIT */
1478 if (buffers & BUFFER_BITS_COLOR) {
1479 /* leave colormask, glDrawBuffer state as-is */
1480
1481 /* Clears never have the color clamped. */
1482 _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
1483 }
1484 else {
1485 ASSERT(metaSave & META_COLOR_MASK);
1486 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1487 }
1488
1489 /* GL_DEPTH_BUFFER_BIT */
1490 if (buffers & BUFFER_BIT_DEPTH) {
1491 _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1492 _mesa_DepthFunc(GL_ALWAYS);
1493 _mesa_DepthMask(GL_TRUE);
1494 }
1495 else {
1496 assert(!ctx->Depth.Test);
1497 }
1498
1499 /* GL_STENCIL_BUFFER_BIT */
1500 if (buffers & BUFFER_BIT_STENCIL) {
1501 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1502 _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
1503 GL_REPLACE, GL_REPLACE, GL_REPLACE);
1504 _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
1505 ctx->Stencil.Clear & stencilMax,
1506 ctx->Stencil.WriteMask[0]);
1507 }
1508 else {
1509 assert(!ctx->Stencil.Enabled);
1510 }
1511
1512 /* vertex positions/colors */
1513 {
1514 const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
1515 const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
1516 const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
1517 const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
1518 const GLfloat z = invert_z(ctx->Depth.Clear);
1519 GLuint i;
1520
1521 verts[0].x = x0;
1522 verts[0].y = y0;
1523 verts[0].z = z;
1524 verts[1].x = x1;
1525 verts[1].y = y0;
1526 verts[1].z = z;
1527 verts[2].x = x1;
1528 verts[2].y = y1;
1529 verts[2].z = z;
1530 verts[3].x = x0;
1531 verts[3].y = y1;
1532 verts[3].z = z;
1533
1534 /* vertex colors */
1535 for (i = 0; i < 4; i++) {
1536 verts[i].r = ctx->Color.ClearColorUnclamped[0];
1537 verts[i].g = ctx->Color.ClearColorUnclamped[1];
1538 verts[i].b = ctx->Color.ClearColorUnclamped[2];
1539 verts[i].a = ctx->Color.ClearColorUnclamped[3];
1540 }
1541
1542 /* upload new vertex data */
1543 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
1544 GL_DYNAMIC_DRAW_ARB);
1545 }
1546
1547 /* draw quad */
1548 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1549
1550 _mesa_meta_end(ctx);
1551 }
1552
1553
1554 /**
1555 * Meta implementation of ctx->Driver.CopyPixels() in terms
1556 * of texture mapping and polygon rendering.
1557 */
1558 void
1559 _mesa_meta_CopyPixels(struct gl_context *ctx, GLint srcX, GLint srcY,
1560 GLsizei width, GLsizei height,
1561 GLint dstX, GLint dstY, GLenum type)
1562 {
1563 struct copypix_state *copypix = &ctx->Meta->CopyPix;
1564 struct temp_texture *tex = get_temp_texture(ctx);
1565 struct vertex {
1566 GLfloat x, y, z, s, t;
1567 };
1568 struct vertex verts[4];
1569 GLboolean newTex;
1570 GLenum intFormat = GL_RGBA;
1571
1572 if (type != GL_COLOR ||
1573 ctx->_ImageTransferState ||
1574 ctx->Fog.Enabled ||
1575 width > tex->MaxSize ||
1576 height > tex->MaxSize) {
1577 /* XXX avoid this fallback */
1578 _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
1579 return;
1580 }
1581
1582 /* Most GL state applies to glCopyPixels, but a there's a few things
1583 * we need to override:
1584 */
1585 _mesa_meta_begin(ctx, (META_RASTERIZATION |
1586 META_SHADER |
1587 META_TEXTURE |
1588 META_TRANSFORM |
1589 META_VERTEX |
1590 META_VIEWPORT));
1591
1592 if (copypix->ArrayObj == 0) {
1593 /* one-time setup */
1594
1595 /* create vertex array object */
1596 _mesa_GenVertexArrays(1, &copypix->ArrayObj);
1597 _mesa_BindVertexArray(copypix->ArrayObj);
1598
1599 /* create vertex array buffer */
1600 _mesa_GenBuffersARB(1, &copypix->VBO);
1601 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1602 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1603 NULL, GL_DYNAMIC_DRAW_ARB);
1604
1605 /* setup vertex arrays */
1606 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1607 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1608 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1609 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1610 }
1611 else {
1612 _mesa_BindVertexArray(copypix->ArrayObj);
1613 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
1614 }
1615
1616 newTex = alloc_texture(tex, width, height, intFormat);
1617
1618 /* vertex positions, texcoords (after texture allocation!) */
1619 {
1620 const GLfloat dstX0 = (GLfloat) dstX;
1621 const GLfloat dstY0 = (GLfloat) dstY;
1622 const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
1623 const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
1624 const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
1625
1626 verts[0].x = dstX0;
1627 verts[0].y = dstY0;
1628 verts[0].z = z;
1629 verts[0].s = 0.0F;
1630 verts[0].t = 0.0F;
1631 verts[1].x = dstX1;
1632 verts[1].y = dstY0;
1633 verts[1].z = z;
1634 verts[1].s = tex->Sright;
1635 verts[1].t = 0.0F;
1636 verts[2].x = dstX1;
1637 verts[2].y = dstY1;
1638 verts[2].z = z;
1639 verts[2].s = tex->Sright;
1640 verts[2].t = tex->Ttop;
1641 verts[3].x = dstX0;
1642 verts[3].y = dstY1;
1643 verts[3].z = z;
1644 verts[3].s = 0.0F;
1645 verts[3].t = tex->Ttop;
1646
1647 /* upload new vertex data */
1648 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
1649 }
1650
1651 /* Alloc/setup texture */
1652 setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
1653 GL_RGBA, GL_NEAREST);
1654
1655 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1656
1657 /* draw textured quad */
1658 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1659
1660 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
1661
1662 _mesa_meta_end(ctx);
1663 }
1664
1665
1666
1667 /**
1668 * When the glDrawPixels() image size is greater than the max rectangle
1669 * texture size we use this function to break the glDrawPixels() image
1670 * into tiles which fit into the max texture size.
1671 */
1672 static void
1673 tiled_draw_pixels(struct gl_context *ctx,
1674 GLint tileSize,
1675 GLint x, GLint y, GLsizei width, GLsizei height,
1676 GLenum format, GLenum type,
1677 const struct gl_pixelstore_attrib *unpack,
1678 const GLvoid *pixels)
1679 {
1680 struct gl_pixelstore_attrib tileUnpack = *unpack;
1681 GLint i, j;
1682
1683 if (tileUnpack.RowLength == 0)
1684 tileUnpack.RowLength = width;
1685
1686 for (i = 0; i < width; i += tileSize) {
1687 const GLint tileWidth = MIN2(tileSize, width - i);
1688 const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
1689
1690 tileUnpack.SkipPixels = unpack->SkipPixels + i;
1691
1692 for (j = 0; j < height; j += tileSize) {
1693 const GLint tileHeight = MIN2(tileSize, height - j);
1694 const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
1695
1696 tileUnpack.SkipRows = unpack->SkipRows + j;
1697
1698 _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
1699 format, type, &tileUnpack, pixels);
1700 }
1701 }
1702 }
1703
1704
1705 /**
1706 * One-time init for drawing stencil pixels.
1707 */
1708 static void
1709 init_draw_stencil_pixels(struct gl_context *ctx)
1710 {
1711 /* This program is run eight times, once for each stencil bit.
1712 * The stencil values to draw are found in an 8-bit alpha texture.
1713 * We read the texture/stencil value and test if bit 'b' is set.
1714 * If the bit is not set, use KIL to kill the fragment.
1715 * Finally, we use the stencil test to update the stencil buffer.
1716 *
1717 * The basic algorithm for checking if a bit is set is:
1718 * if (is_odd(value / (1 << bit)))
1719 * result is one (or non-zero).
1720 * else
1721 * result is zero.
1722 * The program parameter contains three values:
1723 * parm.x = 255 / (1 << bit)
1724 * parm.y = 0.5
1725 * parm.z = 0.0
1726 */
1727 static const char *program =
1728 "!!ARBfp1.0\n"
1729 "PARAM parm = program.local[0]; \n"
1730 "TEMP t; \n"
1731 "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */
1732 "# t = t * 255 / bit \n"
1733 "MUL t.x, t.a, parm.x; \n"
1734 "# t = (int) t \n"
1735 "FRC t.y, t.x; \n"
1736 "SUB t.x, t.x, t.y; \n"
1737 "# t = t * 0.5 \n"
1738 "MUL t.x, t.x, parm.y; \n"
1739 "# t = fract(t.x) \n"
1740 "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
1741 "# t.x = (t.x == 0 ? 1 : 0) \n"
1742 "SGE t.x, -t.x, parm.z; \n"
1743 "KIL -t.x; \n"
1744 "# for debug only \n"
1745 "#MOV result.color, t.x; \n"
1746 "END \n";
1747 char program2[1000];
1748 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1749 struct temp_texture *tex = get_temp_texture(ctx);
1750 const char *texTarget;
1751
1752 assert(drawpix->StencilFP == 0);
1753
1754 /* replace %s with "RECT" or "2D" */
1755 assert(strlen(program) + 4 < sizeof(program2));
1756 if (tex->Target == GL_TEXTURE_RECTANGLE)
1757 texTarget = "RECT";
1758 else
1759 texTarget = "2D";
1760 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1761
1762 _mesa_GenPrograms(1, &drawpix->StencilFP);
1763 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1764 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1765 strlen(program2), (const GLubyte *) program2);
1766 }
1767
1768
1769 /**
1770 * One-time init for drawing depth pixels.
1771 */
1772 static void
1773 init_draw_depth_pixels(struct gl_context *ctx)
1774 {
1775 static const char *program =
1776 "!!ARBfp1.0\n"
1777 "PARAM color = program.local[0]; \n"
1778 "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
1779 "MOV result.color, color; \n"
1780 "END \n";
1781 char program2[200];
1782 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1783 struct temp_texture *tex = get_temp_texture(ctx);
1784 const char *texTarget;
1785
1786 assert(drawpix->DepthFP == 0);
1787
1788 /* replace %s with "RECT" or "2D" */
1789 assert(strlen(program) + 4 < sizeof(program2));
1790 if (tex->Target == GL_TEXTURE_RECTANGLE)
1791 texTarget = "RECT";
1792 else
1793 texTarget = "2D";
1794 _mesa_snprintf(program2, sizeof(program2), program, texTarget);
1795
1796 _mesa_GenPrograms(1, &drawpix->DepthFP);
1797 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
1798 _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
1799 strlen(program2), (const GLubyte *) program2);
1800 }
1801
1802
1803 /**
1804 * Meta implementation of ctx->Driver.DrawPixels() in terms
1805 * of texture mapping and polygon rendering.
1806 */
1807 void
1808 _mesa_meta_DrawPixels(struct gl_context *ctx,
1809 GLint x, GLint y, GLsizei width, GLsizei height,
1810 GLenum format, GLenum type,
1811 const struct gl_pixelstore_attrib *unpack,
1812 const GLvoid *pixels)
1813 {
1814 struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
1815 struct temp_texture *tex = get_temp_texture(ctx);
1816 const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
1817 const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
1818 struct vertex {
1819 GLfloat x, y, z, s, t;
1820 };
1821 struct vertex verts[4];
1822 GLenum texIntFormat;
1823 GLboolean fallback, newTex;
1824 GLbitfield metaExtraSave = 0x0;
1825 GLuint vbo;
1826
1827 /*
1828 * Determine if we can do the glDrawPixels with texture mapping.
1829 */
1830 fallback = GL_FALSE;
1831 if (ctx->_ImageTransferState ||
1832 ctx->Fog.Enabled) {
1833 fallback = GL_TRUE;
1834 }
1835
1836 if (_mesa_is_color_format(format)) {
1837 /* use more compact format when possible */
1838 /* XXX disable special case for GL_LUMINANCE for now to work around
1839 * apparent i965 driver bug (see bug #23670).
1840 */
1841 if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
1842 texIntFormat = format;
1843 else
1844 texIntFormat = GL_RGBA;
1845
1846 /* If we're not supposed to clamp the resulting color, then just
1847 * promote our texture to fully float. We could do better by
1848 * just going for the matching set of channels, in floating
1849 * point.
1850 */
1851 if (ctx->Color.ClampFragmentColor != GL_TRUE)
1852 texIntFormat = GL_RGBA32F;
1853 }
1854 else if (_mesa_is_stencil_format(format)) {
1855 if (ctx->Extensions.ARB_fragment_program &&
1856 ctx->Pixel.IndexShift == 0 &&
1857 ctx->Pixel.IndexOffset == 0 &&
1858 type == GL_UNSIGNED_BYTE) {
1859 /* We'll store stencil as alpha. This only works for GLubyte
1860 * image data because of how incoming values are mapped to alpha
1861 * in [0,1].
1862 */
1863 texIntFormat = GL_ALPHA;
1864 metaExtraSave = (META_COLOR_MASK |
1865 META_DEPTH_TEST |
1866 META_SHADER |
1867 META_STENCIL_TEST);
1868 }
1869 else {
1870 fallback = GL_TRUE;
1871 }
1872 }
1873 else if (_mesa_is_depth_format(format)) {
1874 if (ctx->Extensions.ARB_depth_texture &&
1875 ctx->Extensions.ARB_fragment_program) {
1876 texIntFormat = GL_DEPTH_COMPONENT;
1877 metaExtraSave = (META_SHADER);
1878 }
1879 else {
1880 fallback = GL_TRUE;
1881 }
1882 }
1883 else {
1884 fallback = GL_TRUE;
1885 }
1886
1887 if (fallback) {
1888 _swrast_DrawPixels(ctx, x, y, width, height,
1889 format, type, unpack, pixels);
1890 return;
1891 }
1892
1893 /*
1894 * Check image size against max texture size, draw as tiles if needed.
1895 */
1896 if (width > tex->MaxSize || height > tex->MaxSize) {
1897 tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
1898 format, type, unpack, pixels);
1899 return;
1900 }
1901
1902 /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
1903 * but a there's a few things we need to override:
1904 */
1905 _mesa_meta_begin(ctx, (META_RASTERIZATION |
1906 META_SHADER |
1907 META_TEXTURE |
1908 META_TRANSFORM |
1909 META_VERTEX |
1910 META_VIEWPORT |
1911 META_CLAMP_FRAGMENT_COLOR |
1912 metaExtraSave));
1913
1914 newTex = alloc_texture(tex, width, height, texIntFormat);
1915
1916 /* vertex positions, texcoords (after texture allocation!) */
1917 {
1918 const GLfloat x0 = (GLfloat) x;
1919 const GLfloat y0 = (GLfloat) y;
1920 const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
1921 const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
1922 const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
1923
1924 verts[0].x = x0;
1925 verts[0].y = y0;
1926 verts[0].z = z;
1927 verts[0].s = 0.0F;
1928 verts[0].t = 0.0F;
1929 verts[1].x = x1;
1930 verts[1].y = y0;
1931 verts[1].z = z;
1932 verts[1].s = tex->Sright;
1933 verts[1].t = 0.0F;
1934 verts[2].x = x1;
1935 verts[2].y = y1;
1936 verts[2].z = z;
1937 verts[2].s = tex->Sright;
1938 verts[2].t = tex->Ttop;
1939 verts[3].x = x0;
1940 verts[3].y = y1;
1941 verts[3].z = z;
1942 verts[3].s = 0.0F;
1943 verts[3].t = tex->Ttop;
1944 }
1945
1946 if (drawpix->ArrayObj == 0) {
1947 /* one-time setup: create vertex array object */
1948 _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
1949 }
1950 _mesa_BindVertexArray(drawpix->ArrayObj);
1951
1952 /* create vertex array buffer */
1953 _mesa_GenBuffersARB(1, &vbo);
1954 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
1955 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
1956 verts, GL_DYNAMIC_DRAW_ARB);
1957
1958 /* setup vertex arrays */
1959 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
1960 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
1961 _mesa_EnableClientState(GL_VERTEX_ARRAY);
1962 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
1963
1964 /* set given unpack params */
1965 ctx->Unpack = *unpack;
1966
1967 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
1968
1969 if (_mesa_is_stencil_format(format)) {
1970 /* Drawing stencil */
1971 GLint bit;
1972
1973 if (!drawpix->StencilFP)
1974 init_draw_stencil_pixels(ctx);
1975
1976 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
1977 GL_ALPHA, type, pixels);
1978
1979 _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1980
1981 _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
1982
1983 /* set all stencil bits to 0 */
1984 _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1985 _mesa_StencilFunc(GL_ALWAYS, 0, 255);
1986 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
1987
1988 /* set stencil bits to 1 where needed */
1989 _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
1990
1991 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
1992 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
1993
1994 for (bit = 0; bit < ctx->DrawBuffer->Visual.stencilBits; bit++) {
1995 const GLuint mask = 1 << bit;
1996 if (mask & origStencilMask) {
1997 _mesa_StencilFunc(GL_ALWAYS, mask, mask);
1998 _mesa_StencilMask(mask);
1999
2000 _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
2001 255.0 / mask, 0.5, 0.0, 0.0);
2002
2003 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2004 }
2005 }
2006 }
2007 else if (_mesa_is_depth_format(format)) {
2008 /* Drawing depth */
2009 if (!drawpix->DepthFP)
2010 init_draw_depth_pixels(ctx);
2011
2012 _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
2013 _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
2014
2015 /* polygon color = current raster color */
2016 _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
2017 ctx->Current.RasterColor);
2018
2019 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
2020 format, type, pixels);
2021
2022 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2023 }
2024 else {
2025 /* Drawing RGBA */
2026 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
2027 format, type, pixels);
2028 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2029 }
2030
2031 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
2032
2033 _mesa_DeleteBuffersARB(1, &vbo);
2034
2035 /* restore unpack params */
2036 ctx->Unpack = unpackSave;
2037
2038 _mesa_meta_end(ctx);
2039 }
2040
2041 static GLboolean
2042 alpha_test_raster_color(struct gl_context *ctx)
2043 {
2044 GLfloat alpha = ctx->Current.RasterColor[ACOMP];
2045 GLfloat ref = ctx->Color.AlphaRef;
2046
2047 switch (ctx->Color.AlphaFunc) {
2048 case GL_NEVER:
2049 return GL_FALSE;
2050 case GL_LESS:
2051 return alpha < ref;
2052 case GL_EQUAL:
2053 return alpha == ref;
2054 case GL_LEQUAL:
2055 return alpha <= ref;
2056 case GL_GREATER:
2057 return alpha > ref;
2058 case GL_NOTEQUAL:
2059 return alpha != ref;
2060 case GL_GEQUAL:
2061 return alpha >= ref;
2062 case GL_ALWAYS:
2063 return GL_TRUE;
2064 default:
2065 assert(0);
2066 return GL_FALSE;
2067 }
2068 }
2069
2070 /**
2071 * Do glBitmap with a alpha texture quad. Use the alpha test to cull
2072 * the 'off' bits. A bitmap cache as in the gallium/mesa state
2073 * tracker would improve performance a lot.
2074 */
2075 void
2076 _mesa_meta_Bitmap(struct gl_context *ctx,
2077 GLint x, GLint y, GLsizei width, GLsizei height,
2078 const struct gl_pixelstore_attrib *unpack,
2079 const GLubyte *bitmap1)
2080 {
2081 struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
2082 struct temp_texture *tex = get_bitmap_temp_texture(ctx);
2083 const GLenum texIntFormat = GL_ALPHA;
2084 const struct gl_pixelstore_attrib unpackSave = *unpack;
2085 GLubyte fg, bg;
2086 struct vertex {
2087 GLfloat x, y, z, s, t, r, g, b, a;
2088 };
2089 struct vertex verts[4];
2090 GLboolean newTex;
2091 GLubyte *bitmap8;
2092
2093 /*
2094 * Check if swrast fallback is needed.
2095 */
2096 if (ctx->_ImageTransferState ||
2097 ctx->FragmentProgram._Enabled ||
2098 ctx->Fog.Enabled ||
2099 ctx->Texture._EnabledUnits ||
2100 width > tex->MaxSize ||
2101 height > tex->MaxSize) {
2102 _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
2103 return;
2104 }
2105
2106 if (ctx->Color.AlphaEnabled && !alpha_test_raster_color(ctx))
2107 return;
2108
2109 /* Most GL state applies to glBitmap (like blending, stencil, etc),
2110 * but a there's a few things we need to override:
2111 */
2112 _mesa_meta_begin(ctx, (META_ALPHA_TEST |
2113 META_PIXEL_STORE |
2114 META_RASTERIZATION |
2115 META_SHADER |
2116 META_TEXTURE |
2117 META_TRANSFORM |
2118 META_VERTEX |
2119 META_VIEWPORT));
2120
2121 if (bitmap->ArrayObj == 0) {
2122 /* one-time setup */
2123
2124 /* create vertex array object */
2125 _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
2126 _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
2127
2128 /* create vertex array buffer */
2129 _mesa_GenBuffersARB(1, &bitmap->VBO);
2130 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
2131 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
2132 NULL, GL_DYNAMIC_DRAW_ARB);
2133
2134 /* setup vertex arrays */
2135 _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2136 _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
2137 _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
2138 _mesa_EnableClientState(GL_VERTEX_ARRAY);
2139 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2140 _mesa_EnableClientState(GL_COLOR_ARRAY);
2141 }
2142 else {
2143 _mesa_BindVertexArray(bitmap->ArrayObj);
2144 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
2145 }
2146
2147 newTex = alloc_texture(tex, width, height, texIntFormat);
2148
2149 /* vertex positions, texcoords, colors (after texture allocation!) */
2150 {
2151 const GLfloat x0 = (GLfloat) x;
2152 const GLfloat y0 = (GLfloat) y;
2153 const GLfloat x1 = (GLfloat) (x + width);
2154 const GLfloat y1 = (GLfloat) (y + height);
2155 const GLfloat z = invert_z(ctx->Current.RasterPos[2]);
2156 GLuint i;
2157
2158 verts[0].x = x0;
2159 verts[0].y = y0;
2160 verts[0].z = z;
2161 verts[0].s = 0.0F;
2162 verts[0].t = 0.0F;
2163 verts[1].x = x1;
2164 verts[1].y = y0;
2165 verts[1].z = z;
2166 verts[1].s = tex->Sright;
2167 verts[1].t = 0.0F;
2168 verts[2].x = x1;
2169 verts[2].y = y1;
2170 verts[2].z = z;
2171 verts[2].s = tex->Sright;
2172 verts[2].t = tex->Ttop;
2173 verts[3].x = x0;
2174 verts[3].y = y1;
2175 verts[3].z = z;
2176 verts[3].s = 0.0F;
2177 verts[3].t = tex->Ttop;
2178
2179 for (i = 0; i < 4; i++) {
2180 verts[i].r = ctx->Current.RasterColor[0];
2181 verts[i].g = ctx->Current.RasterColor[1];
2182 verts[i].b = ctx->Current.RasterColor[2];
2183 verts[i].a = ctx->Current.RasterColor[3];
2184 }
2185
2186 /* upload new vertex data */
2187 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2188 }
2189
2190 /* choose different foreground/background alpha values */
2191 CLAMPED_FLOAT_TO_UBYTE(fg, ctx->Current.RasterColor[ACOMP]);
2192 bg = (fg > 127 ? 0 : 255);
2193
2194 bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
2195 if (!bitmap1) {
2196 _mesa_meta_end(ctx);
2197 return;
2198 }
2199
2200 bitmap8 = (GLubyte *) malloc(width * height);
2201 if (bitmap8) {
2202 memset(bitmap8, bg, width * height);
2203 _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
2204 bitmap8, width, fg);
2205
2206 _mesa_set_enable(ctx, tex->Target, GL_TRUE);
2207
2208 _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
2209 _mesa_AlphaFunc(GL_NOTEQUAL, UBYTE_TO_FLOAT(bg));
2210
2211 setup_drawpix_texture(ctx, tex, newTex, texIntFormat, width, height,
2212 GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
2213
2214 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2215
2216 _mesa_set_enable(ctx, tex->Target, GL_FALSE);
2217
2218 free(bitmap8);
2219 }
2220
2221 _mesa_unmap_pbo_source(ctx, &unpackSave);
2222
2223 _mesa_meta_end(ctx);
2224 }
2225
2226
2227 /**
2228 * Check if the call to _mesa_meta_GenerateMipmap() will require a
2229 * software fallback. The fallback path will require that the texture
2230 * images are mapped.
2231 * \return GL_TRUE if a fallback is needed, GL_FALSE otherwise
2232 */
2233 GLboolean
2234 _mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
2235 struct gl_texture_object *texObj)
2236 {
2237 const GLuint fboSave = ctx->DrawBuffer->Name;
2238 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
2239 struct gl_texture_image *baseImage;
2240 GLuint srcLevel;
2241 GLenum status;
2242
2243 /* check for fallbacks */
2244 if (!ctx->Extensions.EXT_framebuffer_object ||
2245 target == GL_TEXTURE_3D) {
2246 return GL_TRUE;
2247 }
2248
2249 srcLevel = texObj->BaseLevel;
2250 baseImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
2251 if (!baseImage || _mesa_is_format_compressed(baseImage->TexFormat)) {
2252 return GL_TRUE;
2253 }
2254
2255 /*
2256 * Test that we can actually render in the texture's format.
2257 */
2258 if (!mipmap->FBO)
2259 _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
2260 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
2261
2262 if (target == GL_TEXTURE_1D) {
2263 _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
2264 GL_COLOR_ATTACHMENT0_EXT,
2265 target, texObj->Name, srcLevel);
2266 }
2267 #if 0
2268 /* other work is needed to enable 3D mipmap generation */
2269 else if (target == GL_TEXTURE_3D) {
2270 GLint zoffset = 0;
2271 _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
2272 GL_COLOR_ATTACHMENT0_EXT,
2273 target, texObj->Name, srcLevel, zoffset);
2274 }
2275 #endif
2276 else {
2277 /* 2D / cube */
2278 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2279 GL_COLOR_ATTACHMENT0_EXT,
2280 target, texObj->Name, srcLevel);
2281 }
2282
2283 status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
2284
2285 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
2286
2287 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2288 return GL_TRUE;
2289 }
2290
2291 return GL_FALSE;
2292 }
2293
2294
2295 /**
2296 * Called via ctx->Driver.GenerateMipmap()
2297 * Note: texture borders and 3D texture support not yet complete.
2298 */
2299 void
2300 _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
2301 struct gl_texture_object *texObj)
2302 {
2303 struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
2304 struct vertex {
2305 GLfloat x, y, s, t, r;
2306 };
2307 struct vertex verts[4];
2308 const GLuint baseLevel = texObj->BaseLevel;
2309 const GLuint maxLevel = texObj->MaxLevel;
2310 const GLenum minFilterSave = texObj->Sampler.MinFilter;
2311 const GLenum magFilterSave = texObj->Sampler.MagFilter;
2312 const GLint maxLevelSave = texObj->MaxLevel;
2313 const GLboolean genMipmapSave = texObj->GenerateMipmap;
2314 const GLenum wrapSSave = texObj->Sampler.WrapS;
2315 const GLenum wrapTSave = texObj->Sampler.WrapT;
2316 const GLenum wrapRSave = texObj->Sampler.WrapR;
2317 const GLuint fboSave = ctx->DrawBuffer->Name;
2318 const GLuint original_active_unit = ctx->Texture.CurrentUnit;
2319 GLenum faceTarget;
2320 GLuint dstLevel;
2321 GLuint border = 0;
2322
2323 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
2324 _mesa_generate_mipmap(ctx, target, texObj);
2325 return;
2326 }
2327
2328 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
2329 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
2330 faceTarget = target;
2331 target = GL_TEXTURE_CUBE_MAP;
2332 }
2333 else {
2334 faceTarget = target;
2335 }
2336
2337 _mesa_meta_begin(ctx, META_ALL);
2338
2339 if (original_active_unit != 0)
2340 _mesa_BindTexture(target, texObj->Name);
2341
2342 if (mipmap->ArrayObj == 0) {
2343 /* one-time setup */
2344
2345 /* create vertex array object */
2346 _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
2347 _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
2348
2349 /* create vertex array buffer */
2350 _mesa_GenBuffersARB(1, &mipmap->VBO);
2351 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
2352 _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
2353 NULL, GL_DYNAMIC_DRAW_ARB);
2354
2355 /* setup vertex arrays */
2356 _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
2357 _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
2358 _mesa_EnableClientState(GL_VERTEX_ARRAY);
2359 _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
2360 }
2361 else {
2362 _mesa_BindVertexArray(mipmap->ArrayObj);
2363 _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
2364 }
2365
2366 if (!mipmap->FBO) {
2367 _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
2368 }
2369 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
2370
2371 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2372 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2373 _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE);
2374 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2375 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2376 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
2377
2378 _mesa_set_enable(ctx, target, GL_TRUE);
2379
2380 /* setup texcoords once (XXX what about border?) */
2381 switch (faceTarget) {
2382 case GL_TEXTURE_1D:
2383 case GL_TEXTURE_2D:
2384 verts[0].s = 0.0F;
2385 verts[0].t = 0.0F;
2386 verts[0].r = 0.0F;
2387 verts[1].s = 1.0F;
2388 verts[1].t = 0.0F;
2389 verts[1].r = 0.0F;
2390 verts[2].s = 1.0F;
2391 verts[2].t = 1.0F;
2392 verts[2].r = 0.0F;
2393 verts[3].s = 0.0F;
2394 verts[3].t = 1.0F;
2395 verts[3].r = 0.0F;
2396 break;
2397 case GL_TEXTURE_3D:
2398 abort();
2399 break;
2400 default:
2401 /* cube face */
2402 {
2403 static const GLfloat st[4][2] = {
2404 {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
2405 };
2406 GLuint i;
2407
2408 /* loop over quad verts */
2409 for (i = 0; i < 4; i++) {
2410 /* Compute sc = +/-scale and tc = +/-scale.
2411 * Not +/-1 to avoid cube face selection ambiguity near the edges,
2412 * though that can still sometimes happen with this scale factor...
2413 */
2414 const GLfloat scale = 0.9999f;
2415 const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale;
2416 const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale;
2417
2418 switch (faceTarget) {
2419 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2420 verts[i].s = 1.0f;
2421 verts[i].t = -tc;
2422 verts[i].r = -sc;
2423 break;
2424 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2425 verts[i].s = -1.0f;
2426 verts[i].t = -tc;
2427 verts[i].r = sc;
2428 break;
2429 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2430 verts[i].s = sc;
2431 verts[i].t = 1.0f;
2432 verts[i].r = tc;
2433 break;
2434 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2435 verts[i].s = sc;
2436 verts[i].t = -1.0f;
2437 verts[i].r = -tc;
2438 break;
2439 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2440 verts[i].s = sc;
2441 verts[i].t = -tc;
2442 verts[i].r = 1.0f;
2443 break;
2444 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2445 verts[i].s = -sc;
2446 verts[i].t = -tc;
2447 verts[i].r = -1.0f;
2448 break;
2449 default:
2450 assert(0);
2451 }
2452 }
2453 }
2454 }
2455
2456 _mesa_set_enable(ctx, target, GL_TRUE);
2457
2458 /* setup vertex positions */
2459 {
2460 verts[0].x = 0.0F;
2461 verts[0].y = 0.0F;
2462 verts[1].x = 1.0F;
2463 verts[1].y = 0.0F;
2464 verts[2].x = 1.0F;
2465 verts[2].y = 1.0F;
2466 verts[3].x = 0.0F;
2467 verts[3].y = 1.0F;
2468
2469 /* upload new vertex data */
2470 _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
2471 }
2472
2473 /* setup projection matrix */
2474 _mesa_MatrixMode(GL_PROJECTION);
2475 _mesa_LoadIdentity();
2476 _mesa_Ortho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
2477
2478 /* texture is already locked, unlock now */
2479 _mesa_unlock_texture(ctx, texObj);
2480
2481 for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) {
2482 const struct gl_texture_image *srcImage;
2483 const GLuint srcLevel = dstLevel - 1;
2484 GLsizei srcWidth, srcHeight, srcDepth;
2485 GLsizei dstWidth, dstHeight, dstDepth;
2486 GLenum status;
2487
2488 srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel);
2489 assert(srcImage->Border == 0); /* XXX we can fix this */
2490
2491 /* src size w/out border */
2492 srcWidth = srcImage->Width - 2 * border;
2493 srcHeight = srcImage->Height - 2 * border;
2494 srcDepth = srcImage->Depth - 2 * border;
2495
2496 /* new dst size w/ border */
2497 dstWidth = MAX2(1, srcWidth / 2) + 2 * border;
2498 dstHeight = MAX2(1, srcHeight / 2) + 2 * border;
2499 dstDepth = MAX2(1, srcDepth / 2) + 2 * border;
2500
2501 if (dstWidth == srcImage->Width &&
2502 dstHeight == srcImage->Height &&
2503 dstDepth == srcImage->Depth) {
2504 /* all done */
2505 break;
2506 }
2507
2508 /* Set MaxLevel large enough to hold the new level when we allocate it */
2509 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, dstLevel);
2510
2511 /* Create empty dest image */
2512 if (target == GL_TEXTURE_1D) {
2513 _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat,
2514 dstWidth, border,
2515 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2516 }
2517 else if (target == GL_TEXTURE_3D) {
2518 _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat,
2519 dstWidth, dstHeight, dstDepth, border,
2520 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2521 }
2522 else {
2523 /* 2D or cube */
2524 _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat,
2525 dstWidth, dstHeight, border,
2526 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2527
2528 if (target == GL_TEXTURE_CUBE_MAP) {
2529 /* If texturing from a cube, we need to make sure all src faces
2530 * have been defined (even if we're not sampling from them.)
2531 * Otherwise the texture object will be 'incomplete' and
2532 * texturing from it will not be allowed.
2533 */
2534 GLuint face;
2535 for (face = 0; face < 6; face++) {
2536 if (!texObj->Image[face][srcLevel] ||
2537 texObj->Image[face][srcLevel]->Width != srcWidth) {
2538 _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
2539 srcLevel, srcImage->InternalFormat,
2540 srcWidth, srcHeight, border,
2541 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
2542 }
2543 }
2544 }
2545 }
2546
2547 /* limit minification to src level */
2548 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
2549
2550 /* Set to draw into the current dstLevel */
2551 if (target == GL_TEXTURE_1D) {
2552 _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
2553 GL_COLOR_ATTACHMENT0_EXT,
2554 target,
2555 texObj->Name,
2556 dstLevel);
2557 }
2558 else if (target == GL_TEXTURE_3D) {
2559 GLint zoffset = 0; /* XXX unfinished */
2560 _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
2561 GL_COLOR_ATTACHMENT0_EXT,
2562 target,
2563 texObj->Name,
2564 dstLevel, zoffset);
2565 }
2566 else {
2567 /* 2D / cube */
2568 _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
2569 GL_COLOR_ATTACHMENT0_EXT,
2570 faceTarget,
2571 texObj->Name,
2572 dstLevel);
2573 }
2574
2575 _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
2576
2577 /* sanity check */
2578 status = _mesa_CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
2579 if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2580 abort();
2581 break;
2582 }
2583
2584 assert(dstWidth == ctx->DrawBuffer->Width);
2585 assert(dstHeight == ctx->DrawBuffer->Height);
2586
2587 /* setup viewport */
2588 _mesa_set_viewport(ctx, 0, 0, dstWidth, dstHeight);
2589
2590 _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
2591 }
2592
2593 _mesa_lock_texture(ctx, texObj); /* relock */
2594
2595 _mesa_meta_end(ctx);
2596
2597 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
2598 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
2599 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
2600 _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave);
2601 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
2602 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
2603 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, wrapRSave);
2604
2605 _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
2606 }
2607
2608
2609 /**
2610 * Determine the GL data type to use for the temporary image read with
2611 * ReadPixels() and passed to Tex[Sub]Image().
2612 */
2613 static GLenum
2614 get_temp_image_type(struct gl_context *ctx, GLenum baseFormat)
2615 {
2616 switch (baseFormat) {
2617 case GL_RGBA:
2618 case GL_RGB:
2619 case GL_ALPHA:
2620 case GL_LUMINANCE:
2621 case GL_LUMINANCE_ALPHA:
2622 case GL_INTENSITY:
2623 if (ctx->DrawBuffer->Visual.redBits <= 8)
2624 return GL_UNSIGNED_BYTE;
2625 else if (ctx->DrawBuffer->Visual.redBits <= 8)
2626 return GL_UNSIGNED_SHORT;
2627 else
2628 return GL_FLOAT;
2629 case GL_DEPTH_COMPONENT:
2630 return GL_UNSIGNED_INT;
2631 case GL_DEPTH_STENCIL:
2632 return GL_UNSIGNED_INT_24_8;
2633 default:
2634 _mesa_problem(ctx, "Unexpected format in get_temp_image_type()");
2635 return 0;
2636 }
2637 }
2638
2639
2640 /**
2641 * Helper for _mesa_meta_CopyTexImage1/2D() functions.
2642 * Have to be careful with locking and meta state for pixel transfer.
2643 */
2644 static void
2645 copy_tex_image(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
2646 GLenum internalFormat, GLint x, GLint y,
2647 GLsizei width, GLsizei height, GLint border)
2648 {
2649 struct gl_texture_object *texObj;
2650 struct gl_texture_image *texImage;
2651 GLenum format, type;
2652 GLint bpp;
2653 void *buf;
2654
2655 texObj = _mesa_get_current_tex_object(ctx, target);
2656 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
2657
2658 /* Choose format/type for temporary image buffer */
2659 format = _mesa_base_tex_format(ctx, internalFormat);
2660 type = get_temp_image_type(ctx, format);
2661 bpp = _mesa_bytes_per_pixel(format, type);
2662 if (bpp <= 0) {
2663 _mesa_problem(ctx, "Bad bpp in meta copy_tex_image()");
2664 return;
2665 }
2666
2667 /*
2668 * Alloc image buffer (XXX could use a PBO)
2669 */
2670 buf = malloc(width * height * bpp);
2671 if (!buf) {
2672 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2673 return;
2674 }
2675
2676 _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
2677
2678 /*
2679 * Read image from framebuffer (disable pixel transfer ops)
2680 */
2681 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2682 ctx->Driver.ReadPixels(ctx, x, y, width, height,
2683 format, type, &ctx->Pack, buf);
2684 _mesa_meta_end(ctx);
2685
2686 if (texImage->Data) {
2687 ctx->Driver.FreeTexImageData(ctx, texImage);
2688 }
2689
2690 /* The texture's format was already chosen in _mesa_CopyTexImage() */
2691 ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
2692
2693 /*
2694 * Store texture data (with pixel transfer ops)
2695 */
2696 _mesa_meta_begin(ctx, META_PIXEL_STORE);
2697
2698 _mesa_update_state(ctx); /* to update pixel transfer state */
2699
2700 if (target == GL_TEXTURE_1D) {
2701 ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
2702 width, border, format, type,
2703 buf, &ctx->Unpack, texObj, texImage);
2704 }
2705 else {
2706 ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
2707 width, height, border, format, type,
2708 buf, &ctx->Unpack, texObj, texImage);
2709 }
2710 _mesa_meta_end(ctx);
2711
2712 _mesa_lock_texture(ctx, texObj); /* re-lock */
2713
2714 free(buf);
2715 }
2716
2717
2718 void
2719 _mesa_meta_CopyTexImage1D(struct gl_context *ctx, GLenum target, GLint level,
2720 GLenum internalFormat, GLint x, GLint y,
2721 GLsizei width, GLint border)
2722 {
2723 copy_tex_image(ctx, 1, target, level, internalFormat, x, y,
2724 width, 1, border);
2725 }
2726
2727
2728 void
2729 _mesa_meta_CopyTexImage2D(struct gl_context *ctx, GLenum target, GLint level,
2730 GLenum internalFormat, GLint x, GLint y,
2731 GLsizei width, GLsizei height, GLint border)
2732 {
2733 copy_tex_image(ctx, 2, target, level, internalFormat, x, y,
2734 width, height, border);
2735 }
2736
2737
2738
2739 /**
2740 * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
2741 * Have to be careful with locking and meta state for pixel transfer.
2742 */
2743 static void
2744 copy_tex_sub_image(struct gl_context *ctx,
2745 GLuint dims, GLenum target, GLint level,
2746 GLint xoffset, GLint yoffset, GLint zoffset,
2747 GLint x, GLint y,
2748 GLsizei width, GLsizei height)
2749 {
2750 struct gl_texture_object *texObj;
2751 struct gl_texture_image *texImage;
2752 GLenum format, type;
2753 GLint bpp;
2754 void *buf;
2755
2756 texObj = _mesa_get_current_tex_object(ctx, target);
2757 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2758
2759 /* Choose format/type for temporary image buffer */
2760 format = _mesa_get_format_base_format(texImage->TexFormat);
2761 type = get_temp_image_type(ctx, format);
2762 bpp = _mesa_bytes_per_pixel(format, type);
2763 if (bpp <= 0) {
2764 _mesa_problem(ctx, "Bad bpp in meta copy_tex_sub_image()");
2765 return;
2766 }
2767
2768 /*
2769 * Alloc image buffer (XXX could use a PBO)
2770 */
2771 buf = malloc(width * height * bpp);
2772 if (!buf) {
2773 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims);
2774 return;
2775 }
2776
2777 _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
2778
2779 /*
2780 * Read image from framebuffer (disable pixel transfer ops)
2781 */
2782 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2783 ctx->Driver.ReadPixels(ctx, x, y, width, height,
2784 format, type, &ctx->Pack, buf);
2785 _mesa_meta_end(ctx);
2786
2787 _mesa_update_state(ctx); /* to update pixel transfer state */
2788
2789 /*
2790 * Store texture data (with pixel transfer ops)
2791 */
2792 _mesa_meta_begin(ctx, META_PIXEL_STORE);
2793 if (target == GL_TEXTURE_1D) {
2794 ctx->Driver.TexSubImage1D(ctx, target, level, xoffset,
2795 width, format, type, buf,
2796 &ctx->Unpack, texObj, texImage);
2797 }
2798 else if (target == GL_TEXTURE_3D) {
2799 ctx->Driver.TexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset,
2800 width, height, 1, format, type, buf,
2801 &ctx->Unpack, texObj, texImage);
2802 }
2803 else {
2804 ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
2805 width, height, format, type, buf,
2806 &ctx->Unpack, texObj, texImage);
2807 }
2808 _mesa_meta_end(ctx);
2809
2810 _mesa_lock_texture(ctx, texObj); /* re-lock */
2811
2812 free(buf);
2813 }
2814
2815
2816 void
2817 _mesa_meta_CopyTexSubImage1D(struct gl_context *ctx, GLenum target, GLint level,
2818 GLint xoffset,
2819 GLint x, GLint y, GLsizei width)
2820 {
2821 copy_tex_sub_image(ctx, 1, target, level, xoffset, 0, 0,
2822 x, y, width, 1);
2823 }
2824
2825
2826 void
2827 _mesa_meta_CopyTexSubImage2D(struct gl_context *ctx, GLenum target, GLint level,
2828 GLint xoffset, GLint yoffset,
2829 GLint x, GLint y,
2830 GLsizei width, GLsizei height)
2831 {
2832 copy_tex_sub_image(ctx, 2, target, level, xoffset, yoffset, 0,
2833 x, y, width, height);
2834 }
2835
2836
2837 void
2838 _mesa_meta_CopyTexSubImage3D(struct gl_context *ctx, GLenum target, GLint level,
2839 GLint xoffset, GLint yoffset, GLint zoffset,
2840 GLint x, GLint y,
2841 GLsizei width, GLsizei height)
2842 {
2843 copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset,
2844 x, y, width, height);
2845 }
2846
2847
2848 void
2849 _mesa_meta_CopyColorTable(struct gl_context *ctx,
2850 GLenum target, GLenum internalformat,
2851 GLint x, GLint y, GLsizei width)
2852 {
2853 GLfloat *buf;
2854
2855 buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
2856 if (!buf) {
2857 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorTable");
2858 return;
2859 }
2860
2861 /*
2862 * Read image from framebuffer (disable pixel transfer ops)
2863 */
2864 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2865 ctx->Driver.ReadPixels(ctx, x, y, width, 1,
2866 GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
2867
2868 _mesa_ColorTable(target, internalformat, width, GL_RGBA, GL_FLOAT, buf);
2869
2870 _mesa_meta_end(ctx);
2871
2872 free(buf);
2873 }
2874
2875
2876 void
2877 _mesa_meta_CopyColorSubTable(struct gl_context *ctx,GLenum target, GLsizei start,
2878 GLint x, GLint y, GLsizei width)
2879 {
2880 GLfloat *buf;
2881
2882 buf = (GLfloat *) malloc(width * 4 * sizeof(GLfloat));
2883 if (!buf) {
2884 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorSubTable");
2885 return;
2886 }
2887
2888 /*
2889 * Read image from framebuffer (disable pixel transfer ops)
2890 */
2891 _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
2892 ctx->Driver.ReadPixels(ctx, x, y, width, 1,
2893 GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
2894
2895 _mesa_ColorSubTable(target, start, width, GL_RGBA, GL_FLOAT, buf);
2896
2897 _mesa_meta_end(ctx);
2898
2899 free(buf);
2900 }