1/**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * 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
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29  * Authors:
30  *   Brian Paul
31  */
32
33#include "main/imports.h"
34#include "main/image.h"
35#include "main/bufferobj.h"
36#include "main/blit.h"
37#include "main/format_pack.h"
38#include "main/framebuffer.h"
39#include "main/macros.h"
40#include "main/mtypes.h"
41#include "main/pack.h"
42#include "main/pbo.h"
43#include "main/readpix.h"
44#include "main/texformat.h"
45#include "main/teximage.h"
46#include "main/texstore.h"
47#include "main/glformats.h"
48#include "program/program.h"
49#include "program/prog_print.h"
50#include "program/prog_instruction.h"
51
52#include "st_atom.h"
53#include "st_atom_constbuf.h"
54#include "st_cb_bitmap.h"
55#include "st_cb_drawpixels.h"
56#include "st_cb_readpixels.h"
57#include "st_cb_fbo.h"
58#include "st_context.h"
59#include "st_debug.h"
60#include "st_draw.h"
61#include "st_format.h"
62#include "st_program.h"
63#include "st_sampler_view.h"
64#include "st_scissor.h"
65#include "st_texture.h"
66
67#include "pipe/p_context.h"
68#include "pipe/p_defines.h"
69#include "tgsi/tgsi_ureg.h"
70#include "util/u_format.h"
71#include "util/u_inlines.h"
72#include "util/u_math.h"
73#include "util/u_tile.h"
74#include "cso_cache/cso_context.h"
75
76
77/**
78 * We have a simple glDrawPixels cache to try to optimize the case where the
79 * same image is drawn over and over again.  It basically works as follows:
80 *
81 * 1. After we construct a texture map with the image and draw it, we do
82 *    not discard the texture.  We keep it around, plus we note the
83 *    glDrawPixels width, height, format, etc. parameters and keep a copy
84 *    of the image in a malloc'd buffer.
85 *
86 * 2. On the next glDrawPixels we check if the parameters match the previous
87 *    call.  If those match, we check if the image matches the previous image
88 *    via a memcmp() call.  If everything matches, we re-use the previous
89 *    texture, thereby avoiding the cost creating a new texture and copying
90 *    the image to it.
91 *
92 * The effectiveness of this cache depends upon:
93 * 1. If the memcmp() finds a difference, it happens relatively quickly.
94      Hopefully, not just the last pixels differ!
95 * 2. If the memcmp() finds no difference, doing that check is faster than
96 *    creating and loading a texture.
97 *
98 * Notes:
99 * 1. We don't support any pixel unpacking parameters.
100 * 2. We don't try to cache images in Pixel Buffer Objects.
101 * 3. Instead of saving the whole image, perhaps some sort of reliable
102 *    checksum function could be used instead.
103 */
104#define USE_DRAWPIXELS_CACHE 1
105
106
107
108/**
109 * Create fragment program that does a TEX() instruction to get a Z and/or
110 * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
111 * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
112 * Pass fragment color through as-is.
113 *
114 * \return CSO of the fragment shader.
115 */
116static void *
117get_drawpix_z_stencil_program(struct st_context *st,
118                              GLboolean write_depth,
119                              GLboolean write_stencil)
120{
121   struct ureg_program *ureg;
122   struct ureg_src depth_sampler, stencil_sampler;
123   struct ureg_src texcoord, color;
124   struct ureg_dst out_color, out_depth, out_stencil;
125   const GLuint shaderIndex = write_depth * 2 + write_stencil;
126   void *cso;
127
128   assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders));
129
130   if (st->drawpix.zs_shaders[shaderIndex]) {
131      /* already have the proper shader */
132      return st->drawpix.zs_shaders[shaderIndex];
133   }
134
135   ureg = ureg_create(PIPE_SHADER_FRAGMENT);
136   if (ureg == NULL)
137      return NULL;
138
139   ureg_property(ureg, TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS, TRUE);
140
141   if (write_depth) {
142      color = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 0,
143                                 TGSI_INTERPOLATE_COLOR);
144      out_color = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
145
146      depth_sampler = ureg_DECL_sampler(ureg, 0);
147      ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D,
148                             TGSI_RETURN_TYPE_FLOAT,
149                             TGSI_RETURN_TYPE_FLOAT,
150                             TGSI_RETURN_TYPE_FLOAT,
151                             TGSI_RETURN_TYPE_FLOAT);
152      out_depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
153   }
154
155   if (write_stencil) {
156      stencil_sampler = ureg_DECL_sampler(ureg, 1);
157      ureg_DECL_sampler_view(ureg, 1, TGSI_TEXTURE_2D,
158                             TGSI_RETURN_TYPE_UINT,
159                             TGSI_RETURN_TYPE_UINT,
160                             TGSI_RETURN_TYPE_UINT,
161                             TGSI_RETURN_TYPE_UINT);
162      out_stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0);
163   }
164
165   texcoord = ureg_DECL_fs_input(ureg,
166                                 st->needs_texcoord_semantic ?
167                                    TGSI_SEMANTIC_TEXCOORD :
168                                    TGSI_SEMANTIC_GENERIC,
169                                 0, TGSI_INTERPOLATE_LINEAR);
170
171   if (write_depth) {
172      ureg_TEX(ureg, ureg_writemask(out_depth, TGSI_WRITEMASK_Z),
173               TGSI_TEXTURE_2D, texcoord, depth_sampler);
174      ureg_MOV(ureg, out_color, color);
175   }
176
177   if (write_stencil)
178      ureg_TEX(ureg, ureg_writemask(out_stencil, TGSI_WRITEMASK_Y),
179               TGSI_TEXTURE_2D, texcoord, stencil_sampler);
180
181   ureg_END(ureg);
182   cso = ureg_create_shader_and_destroy(ureg, st->pipe);
183
184   /* save the new shader */
185   st->drawpix.zs_shaders[shaderIndex] = cso;
186   return cso;
187}
188
189
190/**
191 * Create a simple vertex shader that just passes through the
192 * vertex position and texcoord (and optionally, color).
193 */
194static void *
195make_passthrough_vertex_shader(struct st_context *st,
196                               GLboolean passColor)
197{
198   const unsigned texcoord_semantic = st->needs_texcoord_semantic ?
199      TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC;
200
201   if (!st->drawpix.vert_shaders[passColor]) {
202      struct ureg_program *ureg = ureg_create( PIPE_SHADER_VERTEX );
203
204      if (ureg == NULL)
205         return NULL;
206
207      /* MOV result.pos, vertex.pos; */
208      ureg_MOV(ureg,
209               ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ),
210               ureg_DECL_vs_input( ureg, 0 ));
211
212      if (passColor) {
213         /* MOV result.color0, vertex.attr[1]; */
214         ureg_MOV(ureg,
215                  ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ),
216                  ureg_DECL_vs_input( ureg, 1 ));
217      }
218
219      /* MOV result.texcoord0, vertex.attr[2]; */
220      ureg_MOV(ureg,
221               ureg_DECL_output( ureg, texcoord_semantic, 0 ),
222               ureg_DECL_vs_input( ureg, 2 ));
223
224      ureg_END( ureg );
225
226      st->drawpix.vert_shaders[passColor] =
227         ureg_create_shader_and_destroy( ureg, st->pipe );
228   }
229
230   return st->drawpix.vert_shaders[passColor];
231}
232
233
234/**
235 * Return a texture internalFormat for drawing/copying an image
236 * of the given format and type.
237 */
238static GLenum
239internal_format(struct gl_context *ctx, GLenum format, GLenum type)
240{
241   switch (format) {
242   case GL_DEPTH_COMPONENT:
243      switch (type) {
244      case GL_UNSIGNED_SHORT:
245         return GL_DEPTH_COMPONENT16;
246
247      case GL_UNSIGNED_INT:
248         return GL_DEPTH_COMPONENT32;
249
250      case GL_FLOAT:
251         if (ctx->Extensions.ARB_depth_buffer_float)
252            return GL_DEPTH_COMPONENT32F;
253         else
254            return GL_DEPTH_COMPONENT;
255
256      default:
257         return GL_DEPTH_COMPONENT;
258      }
259
260   case GL_DEPTH_STENCIL:
261      switch (type) {
262      case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
263         return GL_DEPTH32F_STENCIL8;
264
265      case GL_UNSIGNED_INT_24_8:
266      default:
267         return GL_DEPTH24_STENCIL8;
268      }
269
270   case GL_STENCIL_INDEX:
271      return GL_STENCIL_INDEX;
272
273   default:
274      if (_mesa_is_enum_format_integer(format)) {
275         switch (type) {
276         case GL_BYTE:
277            return GL_RGBA8I;
278         case GL_UNSIGNED_BYTE:
279            return GL_RGBA8UI;
280         case GL_SHORT:
281            return GL_RGBA16I;
282         case GL_UNSIGNED_SHORT:
283            return GL_RGBA16UI;
284         case GL_INT:
285            return GL_RGBA32I;
286         case GL_UNSIGNED_INT:
287            return GL_RGBA32UI;
288         default:
289            assert(0 && "Unexpected type in internal_format()");
290            return GL_RGBA_INTEGER;
291         }
292      }
293      else {
294         switch (type) {
295         case GL_UNSIGNED_BYTE:
296         case GL_UNSIGNED_INT_8_8_8_8:
297         case GL_UNSIGNED_INT_8_8_8_8_REV:
298         default:
299            return GL_RGBA8;
300
301         case GL_UNSIGNED_BYTE_3_3_2:
302         case GL_UNSIGNED_BYTE_2_3_3_REV:
303            return GL_R3_G3_B2;
304
305         case GL_UNSIGNED_SHORT_4_4_4_4:
306         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
307            return GL_RGBA4;
308
309         case GL_UNSIGNED_SHORT_5_6_5:
310         case GL_UNSIGNED_SHORT_5_6_5_REV:
311            return GL_RGB565;
312
313         case GL_UNSIGNED_SHORT_5_5_5_1:
314         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
315            return GL_RGB5_A1;
316
317         case GL_UNSIGNED_INT_10_10_10_2:
318         case GL_UNSIGNED_INT_2_10_10_10_REV:
319            return GL_RGB10_A2;
320
321         case GL_UNSIGNED_SHORT:
322         case GL_UNSIGNED_INT:
323            return GL_RGBA16;
324
325         case GL_BYTE:
326            return
327               ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8;
328
329         case GL_SHORT:
330         case GL_INT:
331            return
332               ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
333
334         case GL_HALF_FLOAT_ARB:
335            return
336               ctx->Extensions.ARB_texture_float ? GL_RGBA16F :
337               ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
338
339         case GL_FLOAT:
340         case GL_DOUBLE:
341            return
342               ctx->Extensions.ARB_texture_float ? GL_RGBA32F :
343               ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16;
344
345         case GL_UNSIGNED_INT_5_9_9_9_REV:
346            assert(ctx->Extensions.EXT_texture_shared_exponent);
347            return GL_RGB9_E5;
348
349         case GL_UNSIGNED_INT_10F_11F_11F_REV:
350            assert(ctx->Extensions.EXT_packed_float);
351            return GL_R11F_G11F_B10F;
352         }
353      }
354   }
355}
356
357
358/**
359 * Create a temporary texture to hold an image of the given size.
360 * If width, height are not POT and the driver only handles POT textures,
361 * allocate the next larger size of texture that is POT.
362 */
363static struct pipe_resource *
364alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
365              enum pipe_format texFormat, unsigned bind)
366{
367   struct pipe_resource *pt;
368
369   pt = st_texture_create(st, st->internal_target, texFormat, 0,
370                          width, height, 1, 1, 0, bind);
371
372   return pt;
373}
374
375
376/**
377 * Make texture containing an image for glDrawPixels image.
378 * If 'pixels' is NULL, leave the texture image data undefined.
379 */
380static struct pipe_resource *
381make_texture(struct st_context *st,
382	     GLsizei width, GLsizei height, GLenum format, GLenum type,
383	     const struct gl_pixelstore_attrib *unpack,
384	     const void *pixels)
385{
386   struct gl_context *ctx = st->ctx;
387   struct pipe_context *pipe = st->pipe;
388   mesa_format mformat;
389   struct pipe_resource *pt = NULL;
390   enum pipe_format pipeFormat;
391   GLenum baseInternalFormat;
392
393#if USE_DRAWPIXELS_CACHE
394   const GLint bpp = _mesa_bytes_per_pixel(format, type);
395
396   /* Check if the glDrawPixels() parameters and state matches the cache */
397   if (width == st->drawpix_cache.width &&
398       height == st->drawpix_cache.height &&
399       format == st->drawpix_cache.format &&
400       type == st->drawpix_cache.type &&
401       pixels == st->drawpix_cache.user_pointer &&
402       !_mesa_is_bufferobj(unpack->BufferObj) &&
403       (unpack->RowLength == 0 || unpack->RowLength == width) &&
404       unpack->SkipPixels == 0 &&
405       unpack->SkipRows == 0 &&
406       unpack->SwapBytes == GL_FALSE &&
407       st->drawpix_cache.image) {
408      assert(st->drawpix_cache.texture);
409
410      /* check if the pixel data is the same */
411      if (memcmp(pixels, st->drawpix_cache.image, width * height * bpp) == 0) {
412         /* OK, re-use the cached texture */
413         pipe_resource_reference(&pt, st->drawpix_cache.texture);
414         /* refcount of returned texture should be at least two here.  One
415          * reference for the cache to hold on to, one for the caller (which
416          * it will release), and possibly more held by the driver.
417          */
418         assert(pt->reference.count >= 2);
419         return pt;
420      }
421   }
422
423   /* discard the cached image and texture (if there is one) */
424   st->drawpix_cache.width = 0;
425   st->drawpix_cache.height = 0;
426   st->drawpix_cache.user_pointer = NULL;
427   if (st->drawpix_cache.image) {
428      free(st->drawpix_cache.image);
429      st->drawpix_cache.image = NULL;
430   }
431   pipe_resource_reference(&st->drawpix_cache.texture, NULL);
432#endif
433
434   /* Choose a pixel format for the temp texture which will hold the
435    * image to draw.
436    */
437   pipeFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
438                                          format, type, unpack->SwapBytes);
439
440   if (pipeFormat == PIPE_FORMAT_NONE) {
441      /* Use the generic approach. */
442      GLenum intFormat = internal_format(ctx, format, type);
443
444      pipeFormat = st_choose_format(st, intFormat, format, type,
445                                    st->internal_target, 0,
446                                    PIPE_BIND_SAMPLER_VIEW, FALSE);
447      assert(pipeFormat != PIPE_FORMAT_NONE);
448   }
449
450   mformat = st_pipe_format_to_mesa_format(pipeFormat);
451   baseInternalFormat = _mesa_get_format_base_format(mformat);
452
453   pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
454   if (!pixels)
455      return NULL;
456
457   /* alloc temporary texture */
458   pt = alloc_texture(st, width, height, pipeFormat, PIPE_BIND_SAMPLER_VIEW);
459   if (!pt) {
460      _mesa_unmap_pbo_source(ctx, unpack);
461      return NULL;
462   }
463
464   {
465      struct pipe_transfer *transfer;
466      GLboolean success;
467      GLubyte *dest;
468      const GLbitfield imageTransferStateSave = ctx->_ImageTransferState;
469
470      /* we'll do pixel transfer in a fragment shader */
471      ctx->_ImageTransferState = 0x0;
472
473      /* map texture transfer */
474      dest = pipe_transfer_map(pipe, pt, 0, 0,
475                               PIPE_TRANSFER_WRITE, 0, 0,
476                               width, height, &transfer);
477
478
479      /* Put image into texture transfer.
480       * Note that the image is actually going to be upside down in
481       * the texture.  We deal with that with texcoords.
482       */
483      if ((format == GL_RGBA || format == GL_BGRA)
484          && type == GL_UNSIGNED_BYTE) {
485         /* Use a memcpy-based texstore to avoid software pixel swizzling.
486          * We'll do the necessary swizzling with the pipe_sampler_view to
487          * give much better performance.
488          * XXX in the future, expand this to accomodate more format and
489          * type combinations.
490          */
491         _mesa_memcpy_texture(ctx, 2,
492                              mformat,          /* mesa_format */
493                              transfer->stride, /* dstRowStride, bytes */
494                              &dest,            /* destSlices */
495                              width, height, 1, /* size */
496                              format, type,     /* src format/type */
497                              pixels,           /* data source */
498                              unpack);
499         success = GL_TRUE;
500      }
501      else {
502         success = _mesa_texstore(ctx, 2,           /* dims */
503                                  baseInternalFormat, /* baseInternalFormat */
504                                  mformat,          /* mesa_format */
505                                  transfer->stride, /* dstRowStride, bytes */
506                                  &dest,            /* destSlices */
507                                  width, height, 1, /* size */
508                                  format, type,     /* src format/type */
509                                  pixels,           /* data source */
510                                  unpack);
511      }
512
513      /* unmap */
514      pipe_transfer_unmap(pipe, transfer);
515
516      assert(success);
517
518      /* restore */
519      ctx->_ImageTransferState = imageTransferStateSave;
520   }
521
522   _mesa_unmap_pbo_source(ctx, unpack);
523
524#if USE_DRAWPIXELS_CACHE
525   /* Save the glDrawPixels parameter and image in the cache */
526   if ((unpack->RowLength == 0 || unpack->RowLength == width) &&
527       unpack->SkipPixels == 0 &&
528       unpack->SkipRows == 0) {
529      st->drawpix_cache.width = width;
530      st->drawpix_cache.height = height;
531      st->drawpix_cache.format = format;
532      st->drawpix_cache.type = type;
533      st->drawpix_cache.user_pointer = pixels;
534      assert(!st->drawpix_cache.image);
535      st->drawpix_cache.image = malloc(width * height * bpp);
536      if (st->drawpix_cache.image) {
537         memcpy(st->drawpix_cache.image, pixels, width * height * bpp);
538         pipe_resource_reference(&st->drawpix_cache.texture, pt);
539      }
540      else {
541         /* out of memory, free/disable cached texture */
542         st->drawpix_cache.width = 0;
543         st->drawpix_cache.height = 0;
544         pipe_resource_reference(&st->drawpix_cache.texture, NULL);
545      }
546   }
547#endif
548
549   return pt;
550}
551
552
553static void
554draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
555                   GLsizei width, GLsizei height,
556                   GLfloat zoomX, GLfloat zoomY,
557                   struct pipe_sampler_view **sv,
558                   int num_sampler_view,
559                   void *driver_vp,
560                   void *driver_fp,
561                   struct st_fp_variant *fpv,
562                   const GLfloat *color,
563                   GLboolean invertTex,
564                   GLboolean write_depth, GLboolean write_stencil)
565{
566   struct st_context *st = st_context(ctx);
567   struct pipe_context *pipe = st->pipe;
568   struct cso_context *cso = st->cso_context;
569   const unsigned fb_width = _mesa_geometric_width(ctx->DrawBuffer);
570   const unsigned fb_height = _mesa_geometric_height(ctx->DrawBuffer);
571   GLfloat x0, y0, x1, y1;
572   GLsizei maxSize;
573   boolean normalized = sv[0]->texture->target == PIPE_TEXTURE_2D;
574   unsigned cso_state_mask;
575
576   assert(sv[0]->texture->target == st->internal_target);
577
578   /* limit checks */
579   /* XXX if DrawPixels image is larger than max texture size, break
580    * it up into chunks.
581    */
582   maxSize = 1 << (pipe->screen->get_param(pipe->screen,
583                                        PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
584   assert(width <= maxSize);
585   assert(height <= maxSize);
586
587   cso_state_mask = (CSO_BIT_RASTERIZER |
588                     CSO_BIT_VIEWPORT |
589                     CSO_BIT_FRAGMENT_SAMPLERS |
590                     CSO_BIT_FRAGMENT_SAMPLER_VIEWS |
591                     CSO_BIT_STREAM_OUTPUTS |
592                     CSO_BIT_VERTEX_ELEMENTS |
593                     CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
594                     CSO_BITS_ALL_SHADERS);
595   if (write_stencil) {
596      cso_state_mask |= (CSO_BIT_DEPTH_STENCIL_ALPHA |
597                         CSO_BIT_BLEND);
598   }
599   cso_save_state(cso, cso_state_mask);
600
601   /* rasterizer state: just scissor */
602   {
603      struct pipe_rasterizer_state rasterizer;
604      memset(&rasterizer, 0, sizeof(rasterizer));
605      rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader &&
606                                        ctx->Color._ClampFragmentColor;
607      rasterizer.half_pixel_center = 1;
608      rasterizer.bottom_edge_rule = 1;
609      rasterizer.depth_clip = !ctx->Transform.DepthClamp;
610      rasterizer.scissor = ctx->Scissor.EnableFlags;
611      cso_set_rasterizer(cso, &rasterizer);
612   }
613
614   if (write_stencil) {
615      /* Stencil writing bypasses the normal fragment pipeline to
616       * disable color writing and set stencil test to always pass.
617       */
618      struct pipe_depth_stencil_alpha_state dsa;
619      struct pipe_blend_state blend;
620
621      /* depth/stencil */
622      memset(&dsa, 0, sizeof(dsa));
623      dsa.stencil[0].enabled = 1;
624      dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
625      dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
626      dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
627      if (write_depth) {
628         /* writing depth+stencil: depth test always passes */
629         dsa.depth.enabled = 1;
630         dsa.depth.writemask = ctx->Depth.Mask;
631         dsa.depth.func = PIPE_FUNC_ALWAYS;
632      }
633      cso_set_depth_stencil_alpha(cso, &dsa);
634
635      /* blend (colormask) */
636      memset(&blend, 0, sizeof(blend));
637      cso_set_blend(cso, &blend);
638   }
639
640   /* fragment shader state: TEX lookup program */
641   cso_set_fragment_shader_handle(cso, driver_fp);
642
643   /* vertex shader state: position + texcoord pass-through */
644   cso_set_vertex_shader_handle(cso, driver_vp);
645
646   /* disable other shaders */
647   cso_set_tessctrl_shader_handle(cso, NULL);
648   cso_set_tesseval_shader_handle(cso, NULL);
649   cso_set_geometry_shader_handle(cso, NULL);
650
651   /* user samplers, plus the drawpix samplers */
652   {
653      struct pipe_sampler_state sampler;
654
655      memset(&sampler, 0, sizeof(sampler));
656      sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
657      sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
658      sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
659      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
660      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
661      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
662      sampler.normalized_coords = normalized;
663
664      if (fpv) {
665         /* drawing a color image */
666         const struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
667         uint num = MAX3(fpv->drawpix_sampler + 1,
668                         fpv->pixelmap_sampler + 1,
669                         st->state.num_samplers[PIPE_SHADER_FRAGMENT]);
670         uint i;
671
672         for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++)
673            samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i];
674
675         samplers[fpv->drawpix_sampler] = &sampler;
676         if (sv[1])
677            samplers[fpv->pixelmap_sampler] = &sampler;
678
679         cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num, samplers);
680      } else {
681         /* drawing a depth/stencil image */
682         const struct pipe_sampler_state *samplers[2] = {&sampler, &sampler};
683
684         cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, samplers);
685      }
686   }
687
688   /* user textures, plus the drawpix textures */
689   if (fpv) {
690      /* drawing a color image */
691      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
692      uint num = MAX3(fpv->drawpix_sampler + 1,
693                      fpv->pixelmap_sampler + 1,
694                      st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
695
696      memcpy(sampler_views, st->state.sampler_views[PIPE_SHADER_FRAGMENT],
697             sizeof(sampler_views));
698
699      sampler_views[fpv->drawpix_sampler] = sv[0];
700      if (sv[1])
701         sampler_views[fpv->pixelmap_sampler] = sv[1];
702      cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num, sampler_views);
703   } else {
704      /* drawing a depth/stencil image */
705      cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv);
706   }
707
708   /* viewport state: viewport matching window dims */
709   cso_set_viewport_dims(cso, fb_width, fb_height, TRUE);
710
711   cso_set_vertex_elements(cso, 3, st->util_velems);
712   cso_set_stream_outputs(cso, 0, NULL, NULL);
713
714   /* Compute Gallium window coords (y=0=top) with pixel zoom.
715    * Recall that these coords are transformed by the current
716    * vertex shader and viewport transformation.
717    */
718   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
719      y = fb_height - (int) (y + height * ctx->Pixel.ZoomY);
720      invertTex = !invertTex;
721   }
722
723   x0 = (GLfloat) x;
724   x1 = x + width * ctx->Pixel.ZoomX;
725   y0 = (GLfloat) y;
726   y1 = y + height * ctx->Pixel.ZoomY;
727
728   /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
729   z = z * 2.0f - 1.0f;
730
731   {
732      const float clip_x0 = x0 / (float) fb_width * 2.0f - 1.0f;
733      const float clip_y0 = y0 / (float) fb_height * 2.0f - 1.0f;
734      const float clip_x1 = x1 / (float) fb_width * 2.0f - 1.0f;
735      const float clip_y1 = y1 / (float) fb_height * 2.0f - 1.0f;
736      const float maxXcoord = normalized ?
737         ((float) width / sv[0]->texture->width0) : (float) width;
738      const float maxYcoord = normalized
739         ? ((float) height / sv[0]->texture->height0) : (float) height;
740      const float sLeft = 0.0f, sRight = maxXcoord;
741      const float tTop = invertTex ? maxYcoord : 0.0f;
742      const float tBot = invertTex ? 0.0f : maxYcoord;
743
744      if (!st_draw_quad(st, clip_x0, clip_y0, clip_x1, clip_y1, z,
745                        sLeft, tBot, sRight, tTop, color, 0)) {
746         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
747      }
748   }
749
750   /* restore state */
751   cso_restore_state(cso);
752}
753
754
755/**
756 * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we
757 * can't use a fragment shader to write stencil values.
758 */
759static void
760draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
761                    GLsizei width, GLsizei height, GLenum format, GLenum type,
762                    const struct gl_pixelstore_attrib *unpack,
763                    const void *pixels)
764{
765   struct st_context *st = st_context(ctx);
766   struct pipe_context *pipe = st->pipe;
767   struct st_renderbuffer *strb;
768   enum pipe_transfer_usage usage;
769   struct pipe_transfer *pt;
770   const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
771   ubyte *stmap;
772   struct gl_pixelstore_attrib clippedUnpack = *unpack;
773   GLubyte *sValues;
774   GLuint *zValues;
775
776   if (!zoom) {
777      if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
778                                 &clippedUnpack)) {
779         /* totally clipped */
780         return;
781      }
782   }
783
784   strb = st_renderbuffer(ctx->DrawBuffer->
785                          Attachment[BUFFER_STENCIL].Renderbuffer);
786
787   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
788      y = ctx->DrawBuffer->Height - y - height;
789   }
790
791   if (format == GL_STENCIL_INDEX &&
792       _mesa_is_format_packed_depth_stencil(strb->Base.Format)) {
793      /* writing stencil to a combined depth+stencil buffer */
794      usage = PIPE_TRANSFER_READ_WRITE;
795   }
796   else {
797      usage = PIPE_TRANSFER_WRITE;
798   }
799
800   stmap = pipe_transfer_map(pipe, strb->texture,
801                             strb->surface->u.tex.level,
802                             strb->surface->u.tex.first_layer,
803                             usage, x, y,
804                             width, height, &pt);
805
806   pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
807   assert(pixels);
808
809   sValues = malloc(width * sizeof(GLubyte));
810   zValues = malloc(width * sizeof(GLuint));
811
812   if (sValues && zValues) {
813      GLint row;
814      for (row = 0; row < height; row++) {
815         GLfloat *zValuesFloat = (GLfloat*)zValues;
816         GLenum destType = GL_UNSIGNED_BYTE;
817         const void *source = _mesa_image_address2d(&clippedUnpack, pixels,
818                                                      width, height,
819                                                      format, type,
820                                                      row, 0);
821         _mesa_unpack_stencil_span(ctx, width, destType, sValues,
822                                   type, source, &clippedUnpack,
823                                   ctx->_ImageTransferState);
824
825         if (format == GL_DEPTH_STENCIL) {
826            GLenum ztype =
827               pt->resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ?
828               GL_FLOAT : GL_UNSIGNED_INT;
829
830            _mesa_unpack_depth_span(ctx, width, ztype, zValues,
831                                    (1 << 24) - 1, type, source,
832                                    &clippedUnpack);
833         }
834
835         if (zoom) {
836            _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with "
837                          "zoom not complete");
838         }
839
840         {
841            GLint spanY;
842
843            if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
844               spanY = height - row - 1;
845            }
846            else {
847               spanY = row;
848            }
849
850            /* now pack the stencil (and Z) values in the dest format */
851            switch (pt->resource->format) {
852            case PIPE_FORMAT_S8_UINT:
853               {
854                  ubyte *dest = stmap + spanY * pt->stride;
855                  assert(usage == PIPE_TRANSFER_WRITE);
856                  memcpy(dest, sValues, width);
857               }
858               break;
859            case PIPE_FORMAT_Z24_UNORM_S8_UINT:
860               if (format == GL_DEPTH_STENCIL) {
861                  uint *dest = (uint *) (stmap + spanY * pt->stride);
862                  GLint k;
863                  assert(usage == PIPE_TRANSFER_WRITE);
864                  for (k = 0; k < width; k++) {
865                     dest[k] = zValues[k] | (sValues[k] << 24);
866                  }
867               }
868               else {
869                  uint *dest = (uint *) (stmap + spanY * pt->stride);
870                  GLint k;
871                  assert(usage == PIPE_TRANSFER_READ_WRITE);
872                  for (k = 0; k < width; k++) {
873                     dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
874                  }
875               }
876               break;
877            case PIPE_FORMAT_S8_UINT_Z24_UNORM:
878               if (format == GL_DEPTH_STENCIL) {
879                  uint *dest = (uint *) (stmap + spanY * pt->stride);
880                  GLint k;
881                  assert(usage == PIPE_TRANSFER_WRITE);
882                  for (k = 0; k < width; k++) {
883                     dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff);
884                  }
885               }
886               else {
887                  uint *dest = (uint *) (stmap + spanY * pt->stride);
888                  GLint k;
889                  assert(usage == PIPE_TRANSFER_READ_WRITE);
890                  for (k = 0; k < width; k++) {
891                     dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
892                  }
893               }
894               break;
895            case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
896               if (format == GL_DEPTH_STENCIL) {
897                  uint *dest = (uint *) (stmap + spanY * pt->stride);
898                  GLfloat *destf = (GLfloat*)dest;
899                  GLint k;
900                  assert(usage == PIPE_TRANSFER_WRITE);
901                  for (k = 0; k < width; k++) {
902                     destf[k*2] = zValuesFloat[k];
903                     dest[k*2+1] = sValues[k] & 0xff;
904                  }
905               }
906               else {
907                  uint *dest = (uint *) (stmap + spanY * pt->stride);
908                  GLint k;
909                  assert(usage == PIPE_TRANSFER_READ_WRITE);
910                  for (k = 0; k < width; k++) {
911                     dest[k*2+1] = sValues[k] & 0xff;
912                  }
913               }
914               break;
915            default:
916               assert(0);
917            }
918         }
919      }
920   }
921   else {
922      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels()");
923   }
924
925   free(sValues);
926   free(zValues);
927
928   _mesa_unmap_pbo_source(ctx, &clippedUnpack);
929
930   /* unmap the stencil buffer */
931   pipe_transfer_unmap(pipe, pt);
932}
933
934
935/**
936 * Get fragment program variant for a glDrawPixels or glCopyPixels
937 * command for RGBA data.
938 */
939static struct st_fp_variant *
940get_color_fp_variant(struct st_context *st)
941{
942   struct gl_context *ctx = st->ctx;
943   struct st_fp_variant_key key;
944   struct st_fp_variant *fpv;
945
946   memset(&key, 0, sizeof(key));
947
948   key.st = st->has_shareable_shaders ? NULL : st;
949   key.drawpixels = 1;
950   key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 ||
951                       ctx->Pixel.RedScale != 1.0 ||
952                       ctx->Pixel.GreenBias != 0.0 ||
953                       ctx->Pixel.GreenScale != 1.0 ||
954                       ctx->Pixel.BlueBias != 0.0 ||
955                       ctx->Pixel.BlueScale != 1.0 ||
956                       ctx->Pixel.AlphaBias != 0.0 ||
957                       ctx->Pixel.AlphaScale != 1.0);
958   key.pixelMaps = ctx->Pixel.MapColorFlag;
959   key.clamp_color = st->clamp_frag_color_in_shader &&
960                     ctx->Color._ClampFragmentColor;
961
962   fpv = st_get_fp_variant(st, st->fp, &key);
963
964   return fpv;
965}
966
967
968/**
969 * Clamp glDrawPixels width and height to the maximum texture size.
970 */
971static void
972clamp_size(struct pipe_context *pipe, GLsizei *width, GLsizei *height,
973           struct gl_pixelstore_attrib *unpack)
974{
975   const int maxSize =
976      1 << (pipe->screen->get_param(pipe->screen,
977                                    PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
978
979   if (*width > maxSize) {
980      if (unpack->RowLength == 0)
981         unpack->RowLength = *width;
982      *width = maxSize;
983   }
984   if (*height > maxSize) {
985      *height = maxSize;
986   }
987}
988
989
990/**
991 * Search the array of 4 swizzle components for the named component and return
992 * its position.
993 */
994static unsigned
995search_swizzle(const unsigned char swizzle[4], unsigned component)
996{
997   unsigned i;
998   for (i = 0; i < 4; i++) {
999      if (swizzle[i] == component)
1000         return i;
1001   }
1002   assert(!"search_swizzle() failed");
1003   return 0;
1004}
1005
1006
1007/**
1008 * Set the sampler view's swizzle terms.  This is used to handle RGBA
1009 * swizzling when the incoming image format isn't an exact match for
1010 * the actual texture format.  For example, if we have glDrawPixels(
1011 * GL_RGBA, GL_UNSIGNED_BYTE) and we chose the texture format
1012 * PIPE_FORMAT_B8G8R8A8 then we can do use the sampler view swizzle to
1013 * avoid swizzling all the pixels in software in the texstore code.
1014 */
1015static void
1016setup_sampler_swizzle(struct pipe_sampler_view *sv, GLenum format, GLenum type)
1017{
1018   if ((format == GL_RGBA || format == GL_BGRA) && type == GL_UNSIGNED_BYTE) {
1019      const struct util_format_description *desc =
1020         util_format_description(sv->texture->format);
1021      unsigned c0, c1, c2, c3;
1022
1023      /* Every gallium driver supports at least one 32-bit packed RGBA format.
1024       * We must have chosen one for (GL_RGBA, GL_UNSIGNED_BYTE).
1025       */
1026      assert(desc->block.bits == 32);
1027
1028      /* invert the format's swizzle to setup the sampler's swizzle */
1029      if (format == GL_RGBA) {
1030         c0 = PIPE_SWIZZLE_X;
1031         c1 = PIPE_SWIZZLE_Y;
1032         c2 = PIPE_SWIZZLE_Z;
1033         c3 = PIPE_SWIZZLE_W;
1034      }
1035      else {
1036         assert(format == GL_BGRA);
1037         c0 = PIPE_SWIZZLE_Z;
1038         c1 = PIPE_SWIZZLE_Y;
1039         c2 = PIPE_SWIZZLE_X;
1040         c3 = PIPE_SWIZZLE_W;
1041      }
1042      sv->swizzle_r = search_swizzle(desc->swizzle, c0);
1043      sv->swizzle_g = search_swizzle(desc->swizzle, c1);
1044      sv->swizzle_b = search_swizzle(desc->swizzle, c2);
1045      sv->swizzle_a = search_swizzle(desc->swizzle, c3);
1046   }
1047   else {
1048      /* use the default sampler swizzle */
1049   }
1050}
1051
1052
1053/**
1054 * Called via ctx->Driver.DrawPixels()
1055 */
1056static void
1057st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
1058              GLsizei width, GLsizei height,
1059              GLenum format, GLenum type,
1060              const struct gl_pixelstore_attrib *unpack, const void *pixels)
1061{
1062   void *driver_vp, *driver_fp;
1063   struct st_context *st = st_context(ctx);
1064   struct pipe_context *pipe = st->pipe;
1065   GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE;
1066   struct pipe_sampler_view *sv[2] = { NULL };
1067   int num_sampler_view = 1;
1068   struct gl_pixelstore_attrib clippedUnpack;
1069   struct st_fp_variant *fpv = NULL;
1070   struct pipe_resource *pt;
1071
1072   /* Mesa state should be up to date by now */
1073   assert(ctx->NewState == 0x0);
1074
1075   st_flush_bitmap_cache(st);
1076   st_invalidate_readpix_cache(st);
1077
1078   st_validate_state(st, ST_PIPELINE_RENDER);
1079
1080   /* Limit the size of the glDrawPixels to the max texture size.
1081    * Strictly speaking, that's not correct but since we don't handle
1082    * larger images yet, this is better than crashing.
1083    */
1084   clippedUnpack = *unpack;
1085   unpack = &clippedUnpack;
1086   clamp_size(st->pipe, &width, &height, &clippedUnpack);
1087
1088   if (format == GL_DEPTH_STENCIL)
1089      write_stencil = write_depth = GL_TRUE;
1090   else if (format == GL_STENCIL_INDEX)
1091      write_stencil = GL_TRUE;
1092   else if (format == GL_DEPTH_COMPONENT)
1093      write_depth = GL_TRUE;
1094
1095   if (write_stencil &&
1096       !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) {
1097      /* software fallback */
1098      draw_stencil_pixels(ctx, x, y, width, height, format, type,
1099                          unpack, pixels);
1100      return;
1101   }
1102
1103   /*
1104    * Get vertex/fragment shaders
1105    */
1106   if (write_depth || write_stencil) {
1107      driver_fp = get_drawpix_z_stencil_program(st, write_depth,
1108                                                write_stencil);
1109      driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
1110   }
1111   else {
1112      fpv = get_color_fp_variant(st);
1113
1114      driver_fp = fpv->driver_shader;
1115      driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
1116
1117      if (ctx->Pixel.MapColorFlag) {
1118         pipe_sampler_view_reference(&sv[1],
1119                                     st->pixel_xfer.pixelmap_sampler_view);
1120         num_sampler_view++;
1121      }
1122
1123      /* compiling a new fragment shader variant added new state constants
1124       * into the constant buffer, we need to update them
1125       */
1126      st_upload_constants(st, st->fp->Base.Parameters, MESA_SHADER_FRAGMENT);
1127   }
1128
1129   /* Put glDrawPixels image into a texture */
1130   pt = make_texture(st, width, height, format, type, unpack, pixels);
1131   if (!pt) {
1132      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1133      return;
1134   }
1135
1136   /* create sampler view for the image */
1137   sv[0] = st_create_texture_sampler_view(st->pipe, pt);
1138   if (!sv[0]) {
1139      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1140      pipe_resource_reference(&pt, NULL);
1141      return;
1142   }
1143
1144   /* Set up the sampler view's swizzle */
1145   setup_sampler_swizzle(sv[0], format, type);
1146
1147   /* Create a second sampler view to read stencil.  The stencil is
1148    * written using the shader stencil export functionality.
1149    */
1150   if (write_stencil) {
1151      enum pipe_format stencil_format =
1152         util_format_stencil_only(pt->format);
1153      /* we should not be doing pixel map/transfer (see above) */
1154      assert(num_sampler_view == 1);
1155      sv[1] = st_create_texture_sampler_view_format(st->pipe, pt,
1156                                                    stencil_format);
1157      if (!sv[1]) {
1158         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
1159         pipe_resource_reference(&pt, NULL);
1160         pipe_sampler_view_reference(&sv[0], NULL);
1161         return;
1162      }
1163      num_sampler_view++;
1164   }
1165
1166   draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
1167                      width, height,
1168                      ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
1169                      sv,
1170                      num_sampler_view,
1171                      driver_vp,
1172                      driver_fp, fpv,
1173                      ctx->Current.RasterColor,
1174                      GL_FALSE, write_depth, write_stencil);
1175   pipe_sampler_view_reference(&sv[0], NULL);
1176   if (num_sampler_view > 1)
1177      pipe_sampler_view_reference(&sv[1], NULL);
1178
1179   /* free the texture (but may persist in the cache) */
1180   pipe_resource_reference(&pt, NULL);
1181}
1182
1183
1184
1185/**
1186 * Software fallback for glCopyPixels(GL_STENCIL).
1187 */
1188static void
1189copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1190                    GLsizei width, GLsizei height,
1191                    GLint dstx, GLint dsty)
1192{
1193   struct st_renderbuffer *rbDraw;
1194   struct pipe_context *pipe = st_context(ctx)->pipe;
1195   enum pipe_transfer_usage usage;
1196   struct pipe_transfer *ptDraw;
1197   ubyte *drawMap;
1198   ubyte *buffer;
1199   int i;
1200
1201   buffer = malloc(width * height * sizeof(ubyte));
1202   if (!buffer) {
1203      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
1204      return;
1205   }
1206
1207   /* Get the dest renderbuffer */
1208   rbDraw = st_renderbuffer(ctx->DrawBuffer->
1209                            Attachment[BUFFER_STENCIL].Renderbuffer);
1210
1211   /* this will do stencil pixel transfer ops */
1212   _mesa_readpixels(ctx, srcx, srcy, width, height,
1213                    GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
1214                    &ctx->DefaultPacking, buffer);
1215
1216   if (0) {
1217      /* debug code: dump stencil values */
1218      GLint row, col;
1219      for (row = 0; row < height; row++) {
1220         printf("%3d: ", row);
1221         for (col = 0; col < width; col++) {
1222            printf("%02x ", buffer[col + row * width]);
1223         }
1224         printf("\n");
1225      }
1226   }
1227
1228   if (_mesa_is_format_packed_depth_stencil(rbDraw->Base.Format))
1229      usage = PIPE_TRANSFER_READ_WRITE;
1230   else
1231      usage = PIPE_TRANSFER_WRITE;
1232
1233   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1234      dsty = rbDraw->Base.Height - dsty - height;
1235   }
1236
1237   assert(util_format_get_blockwidth(rbDraw->texture->format) == 1);
1238   assert(util_format_get_blockheight(rbDraw->texture->format) == 1);
1239
1240   /* map the stencil buffer */
1241   drawMap = pipe_transfer_map(pipe,
1242                               rbDraw->texture,
1243                               rbDraw->surface->u.tex.level,
1244                               rbDraw->surface->u.tex.first_layer,
1245                               usage, dstx, dsty,
1246                               width, height, &ptDraw);
1247
1248   /* draw */
1249   /* XXX PixelZoom not handled yet */
1250   for (i = 0; i < height; i++) {
1251      ubyte *dst;
1252      const ubyte *src;
1253      int y;
1254
1255      y = i;
1256
1257      if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1258         y = height - y - 1;
1259      }
1260
1261      dst = drawMap + y * ptDraw->stride;
1262      src = buffer + i * width;
1263
1264      _mesa_pack_ubyte_stencil_row(rbDraw->Base.Format, width, src, dst);
1265   }
1266
1267   free(buffer);
1268
1269   /* unmap the stencil buffer */
1270   pipe_transfer_unmap(pipe, ptDraw);
1271}
1272
1273
1274/**
1275 * Return renderbuffer to use for reading color pixels for glCopyPixels
1276 */
1277static struct st_renderbuffer *
1278st_get_color_read_renderbuffer(struct gl_context *ctx)
1279{
1280   struct gl_framebuffer *fb = ctx->ReadBuffer;
1281   struct st_renderbuffer *strb =
1282      st_renderbuffer(fb->_ColorReadBuffer);
1283
1284   return strb;
1285}
1286
1287
1288/**
1289 * Try to do a glCopyPixels for simple cases with a blit by calling
1290 * pipe->blit().
1291 *
1292 * We can do this when we're copying color pixels (depth/stencil
1293 * eventually) with no pixel zoom, no pixel transfer ops, no
1294 * per-fragment ops, and the src/dest regions don't overlap.
1295 */
1296static GLboolean
1297blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1298                 GLsizei width, GLsizei height,
1299                 GLint dstx, GLint dsty, GLenum type)
1300{
1301   struct st_context *st = st_context(ctx);
1302   struct pipe_context *pipe = st->pipe;
1303   struct pipe_screen *screen = pipe->screen;
1304   struct gl_pixelstore_attrib pack, unpack;
1305   GLint readX, readY, readW, readH, drawX, drawY, drawW, drawH;
1306
1307   if (type == GL_COLOR &&
1308       ctx->Pixel.ZoomX == 1.0 &&
1309       ctx->Pixel.ZoomY == 1.0 &&
1310       ctx->_ImageTransferState == 0x0 &&
1311       !ctx->Color.BlendEnabled &&
1312       !ctx->Color.AlphaEnabled &&
1313       (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) &&
1314       !ctx->Depth.Test &&
1315       !ctx->Fog.Enabled &&
1316       !ctx->Stencil.Enabled &&
1317       !ctx->FragmentProgram.Enabled &&
1318       !ctx->VertexProgram.Enabled &&
1319       !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] &&
1320       !ctx->ATIFragmentShader._Enabled &&
1321       ctx->DrawBuffer->_NumColorDrawBuffers == 1 &&
1322       !ctx->Query.CondRenderQuery &&
1323       !ctx->Query.CurrentOcclusionObject) {
1324      struct st_renderbuffer *rbRead, *rbDraw;
1325
1326      /*
1327       * Clip the read region against the src buffer bounds.
1328       * We'll still allocate a temporary buffer/texture for the original
1329       * src region size but we'll only read the region which is on-screen.
1330       * This may mean that we draw garbage pixels into the dest region, but
1331       * that's expected.
1332       */
1333      readX = srcx;
1334      readY = srcy;
1335      readW = width;
1336      readH = height;
1337      pack = ctx->DefaultPacking;
1338      if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack))
1339         return GL_TRUE; /* all done */
1340
1341      /* clip against dest buffer bounds and scissor box */
1342      drawX = dstx + pack.SkipPixels;
1343      drawY = dsty + pack.SkipRows;
1344      unpack = pack;
1345      if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack))
1346         return GL_TRUE; /* all done */
1347
1348      readX = readX - pack.SkipPixels + unpack.SkipPixels;
1349      readY = readY - pack.SkipRows + unpack.SkipRows;
1350
1351      drawW = readW;
1352      drawH = readH;
1353
1354      rbRead = st_get_color_read_renderbuffer(ctx);
1355      rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
1356
1357      /* Flip src/dst position depending on the orientation of buffers. */
1358      if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1359         readY = rbRead->Base.Height - readY;
1360         readH = -readH;
1361      }
1362
1363      if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
1364         /* We can't flip the destination for pipe->blit, so we only adjust
1365          * its position and flip the source.
1366          */
1367         drawY = rbDraw->Base.Height - drawY - drawH;
1368         readY += readH;
1369         readH = -readH;
1370      }
1371
1372      if (rbRead != rbDraw ||
1373          !_mesa_regions_overlap(readX, readY, readX + readW, readY + readH,
1374                                 drawX, drawY, drawX + drawW, drawY + drawH)) {
1375         struct pipe_blit_info blit;
1376
1377         memset(&blit, 0, sizeof(blit));
1378         blit.src.resource = rbRead->texture;
1379         blit.src.level = rbRead->surface->u.tex.level;
1380         blit.src.format = rbRead->texture->format;
1381         blit.src.box.x = readX;
1382         blit.src.box.y = readY;
1383         blit.src.box.z = rbRead->surface->u.tex.first_layer;
1384         blit.src.box.width = readW;
1385         blit.src.box.height = readH;
1386         blit.src.box.depth = 1;
1387         blit.dst.resource = rbDraw->texture;
1388         blit.dst.level = rbDraw->surface->u.tex.level;
1389         blit.dst.format = rbDraw->texture->format;
1390         blit.dst.box.x = drawX;
1391         blit.dst.box.y = drawY;
1392         blit.dst.box.z = rbDraw->surface->u.tex.first_layer;
1393         blit.dst.box.width = drawW;
1394         blit.dst.box.height = drawH;
1395         blit.dst.box.depth = 1;
1396         blit.mask = PIPE_MASK_RGBA;
1397         blit.filter = PIPE_TEX_FILTER_NEAREST;
1398
1399         if (ctx->DrawBuffer != ctx->WinSysDrawBuffer)
1400            st_window_rectangles_to_blit(ctx, &blit);
1401
1402         if (screen->is_format_supported(screen, blit.src.format,
1403                                         blit.src.resource->target,
1404                                         blit.src.resource->nr_samples,
1405                                         PIPE_BIND_SAMPLER_VIEW) &&
1406             screen->is_format_supported(screen, blit.dst.format,
1407                                         blit.dst.resource->target,
1408                                         blit.dst.resource->nr_samples,
1409                                         PIPE_BIND_RENDER_TARGET)) {
1410            pipe->blit(pipe, &blit);
1411            return GL_TRUE;
1412         }
1413      }
1414   }
1415
1416   return GL_FALSE;
1417}
1418
1419
1420static void
1421st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
1422              GLsizei width, GLsizei height,
1423              GLint dstx, GLint dsty, GLenum type)
1424{
1425   struct st_context *st = st_context(ctx);
1426   struct pipe_context *pipe = st->pipe;
1427   struct pipe_screen *screen = pipe->screen;
1428   struct st_renderbuffer *rbRead;
1429   void *driver_vp, *driver_fp;
1430   struct pipe_resource *pt;
1431   struct pipe_sampler_view *sv[2] = { NULL };
1432   struct st_fp_variant *fpv = NULL;
1433   int num_sampler_view = 1;
1434   enum pipe_format srcFormat;
1435   unsigned srcBind;
1436   GLboolean invertTex = GL_FALSE;
1437   GLint readX, readY, readW, readH;
1438   struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
1439
1440   st_flush_bitmap_cache(st);
1441   st_invalidate_readpix_cache(st);
1442
1443   st_validate_state(st, ST_PIPELINE_RENDER);
1444
1445   if (type == GL_DEPTH_STENCIL) {
1446      /* XXX make this more efficient */
1447      st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL);
1448      st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH);
1449      return;
1450   }
1451
1452   if (type == GL_STENCIL) {
1453      /* can't use texturing to do stencil */
1454      copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
1455      return;
1456   }
1457
1458   if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type))
1459      return;
1460
1461   /*
1462    * The subsequent code implements glCopyPixels by copying the source
1463    * pixels into a temporary texture that's then applied to a textured quad.
1464    * When we draw the textured quad, all the usual per-fragment operations
1465    * are handled.
1466    */
1467
1468
1469   /*
1470    * Get vertex/fragment shaders
1471    */
1472   if (type == GL_COLOR) {
1473      fpv = get_color_fp_variant(st);
1474
1475      rbRead = st_get_color_read_renderbuffer(ctx);
1476
1477      driver_fp = fpv->driver_shader;
1478      driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
1479
1480      if (ctx->Pixel.MapColorFlag) {
1481         pipe_sampler_view_reference(&sv[1],
1482                                     st->pixel_xfer.pixelmap_sampler_view);
1483         num_sampler_view++;
1484      }
1485
1486      /* compiling a new fragment shader variant added new state constants
1487       * into the constant buffer, we need to update them
1488       */
1489      st_upload_constants(st, st->fp->Base.Parameters, MESA_SHADER_FRAGMENT);
1490   }
1491   else {
1492      assert(type == GL_DEPTH);
1493      rbRead = st_renderbuffer(ctx->ReadBuffer->
1494                               Attachment[BUFFER_DEPTH].Renderbuffer);
1495
1496      driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE);
1497      driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
1498   }
1499
1500   /* Choose the format for the temporary texture. */
1501   srcFormat = rbRead->texture->format;
1502   srcBind = PIPE_BIND_SAMPLER_VIEW |
1503      (type == GL_COLOR ? PIPE_BIND_RENDER_TARGET : PIPE_BIND_DEPTH_STENCIL);
1504
1505   if (!screen->is_format_supported(screen, srcFormat, st->internal_target, 0,
1506                                    srcBind)) {
1507      /* srcFormat is non-renderable. Find a compatible renderable format. */
1508      if (type == GL_DEPTH) {
1509         srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE,
1510                                      GL_NONE, st->internal_target, 0,
1511                                      srcBind, FALSE);
1512      }
1513      else {
1514         assert(type == GL_COLOR);
1515
1516         if (util_format_is_float(srcFormat)) {
1517            srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE,
1518                                         GL_NONE, st->internal_target, 0,
1519                                         srcBind, FALSE);
1520         }
1521         else if (util_format_is_pure_sint(srcFormat)) {
1522            srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE,
1523                                         GL_NONE, st->internal_target, 0,
1524                                         srcBind, FALSE);
1525         }
1526         else if (util_format_is_pure_uint(srcFormat)) {
1527            srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE,
1528                                         GL_NONE, st->internal_target, 0,
1529                                         srcBind, FALSE);
1530         }
1531         else if (util_format_is_snorm(srcFormat)) {
1532            srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE,
1533                                         GL_NONE, st->internal_target, 0,
1534                                         srcBind, FALSE);
1535         }
1536         else {
1537            srcFormat = st_choose_format(st, GL_RGBA, GL_NONE,
1538                                         GL_NONE, st->internal_target, 0,
1539                                         srcBind, FALSE);
1540         }
1541      }
1542
1543      if (srcFormat == PIPE_FORMAT_NONE) {
1544         assert(0 && "cannot choose a format for src of CopyPixels");
1545         return;
1546      }
1547   }
1548
1549   /* Invert src region if needed */
1550   if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1551      srcy = ctx->ReadBuffer->Height - srcy - height;
1552      invertTex = !invertTex;
1553   }
1554
1555   /* Clip the read region against the src buffer bounds.
1556    * We'll still allocate a temporary buffer/texture for the original
1557    * src region size but we'll only read the region which is on-screen.
1558    * This may mean that we draw garbage pixels into the dest region, but
1559    * that's expected.
1560    */
1561   readX = srcx;
1562   readY = srcy;
1563   readW = width;
1564   readH = height;
1565   if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) {
1566      /* The source region is completely out of bounds.  Do nothing.
1567       * The GL spec says "Results of copies from outside the window,
1568       * or from regions of the window that are not exposed, are
1569       * hardware dependent and undefined."
1570       */
1571      return;
1572   }
1573
1574   readW = MAX2(0, readW);
1575   readH = MAX2(0, readH);
1576
1577   /* Allocate the temporary texture. */
1578   pt = alloc_texture(st, width, height, srcFormat, srcBind);
1579   if (!pt)
1580      return;
1581
1582   sv[0] = st_create_texture_sampler_view(st->pipe, pt);
1583   if (!sv[0]) {
1584      pipe_resource_reference(&pt, NULL);
1585      return;
1586   }
1587
1588   /* Copy the src region to the temporary texture. */
1589   {
1590      struct pipe_blit_info blit;
1591
1592      memset(&blit, 0, sizeof(blit));
1593      blit.src.resource = rbRead->texture;
1594      blit.src.level = rbRead->surface->u.tex.level;
1595      blit.src.format = rbRead->texture->format;
1596      blit.src.box.x = readX;
1597      blit.src.box.y = readY;
1598      blit.src.box.z = rbRead->surface->u.tex.first_layer;
1599      blit.src.box.width = readW;
1600      blit.src.box.height = readH;
1601      blit.src.box.depth = 1;
1602      blit.dst.resource = pt;
1603      blit.dst.level = 0;
1604      blit.dst.format = pt->format;
1605      blit.dst.box.x = pack.SkipPixels;
1606      blit.dst.box.y = pack.SkipRows;
1607      blit.dst.box.z = 0;
1608      blit.dst.box.width = readW;
1609      blit.dst.box.height = readH;
1610      blit.dst.box.depth = 1;
1611      blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S;
1612      blit.filter = PIPE_TEX_FILTER_NEAREST;
1613
1614      pipe->blit(pipe, &blit);
1615   }
1616
1617   /* OK, the texture 'pt' contains the src image/pixels.  Now draw a
1618    * textured quad with that texture.
1619    */
1620   draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
1621                      width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
1622                      sv,
1623                      num_sampler_view,
1624                      driver_vp,
1625                      driver_fp, fpv,
1626                      ctx->Current.Attrib[VERT_ATTRIB_COLOR0],
1627                      invertTex, GL_FALSE, GL_FALSE);
1628
1629   pipe_resource_reference(&pt, NULL);
1630   pipe_sampler_view_reference(&sv[0], NULL);
1631}
1632
1633
1634
1635void st_init_drawpixels_functions(struct dd_function_table *functions)
1636{
1637   functions->DrawPixels = st_DrawPixels;
1638   functions->CopyPixels = st_CopyPixels;
1639}
1640
1641
1642void
1643st_destroy_drawpix(struct st_context *st)
1644{
1645   GLuint i;
1646
1647   for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) {
1648      if (st->drawpix.zs_shaders[i])
1649         cso_delete_fragment_shader(st->cso_context,
1650                                    st->drawpix.zs_shaders[i]);
1651   }
1652
1653   if (st->drawpix.vert_shaders[0])
1654      cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[0]);
1655   if (st->drawpix.vert_shaders[1])
1656      cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[1]);
1657}
1658