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