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