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