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