Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 TUNGSTEN GRAPHICS 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/macros.h"
  37. #include "main/pack.h"
  38. #include "main/texformat.h"
  39. #include "main/texstore.h"
  40. #include "program/program.h"
  41. #include "program/prog_print.h"
  42. #include "program/prog_instruction.h"
  43.  
  44. #include "st_atom.h"
  45. #include "st_atom_constbuf.h"
  46. #include "st_cb_drawpixels.h"
  47. #include "st_cb_readpixels.h"
  48. #include "st_cb_fbo.h"
  49. #include "st_context.h"
  50. #include "st_debug.h"
  51. #include "st_format.h"
  52. #include "st_program.h"
  53. #include "st_texture.h"
  54.  
  55. #include "pipe/p_context.h"
  56. #include "pipe/p_defines.h"
  57. #include "tgsi/tgsi_ureg.h"
  58. #include "util/u_draw_quad.h"
  59. #include "util/u_format.h"
  60. #include "util/u_inlines.h"
  61. #include "util/u_math.h"
  62. #include "util/u_tile.h"
  63. #include "cso_cache/cso_context.h"
  64.  
  65.  
  66. #if FEATURE_drawpix
  67.  
  68. /**
  69.  * Check if the given program is:
  70.  * 0: MOVE result.color, fragment.color;
  71.  * 1: END;
  72.  */
  73. static GLboolean
  74. is_passthrough_program(const struct gl_fragment_program *prog)
  75. {
  76.    if (prog->Base.NumInstructions == 2) {
  77.       const struct prog_instruction *inst = prog->Base.Instructions;
  78.       if (inst[0].Opcode == OPCODE_MOV &&
  79.           inst[1].Opcode == OPCODE_END &&
  80.           inst[0].DstReg.File == PROGRAM_OUTPUT &&
  81.           inst[0].DstReg.Index == FRAG_RESULT_COLOR &&
  82.           inst[0].DstReg.WriteMask == WRITEMASK_XYZW &&
  83.           inst[0].SrcReg[0].File == PROGRAM_INPUT &&
  84.           inst[0].SrcReg[0].Index == FRAG_ATTRIB_COL0 &&
  85.           inst[0].SrcReg[0].Swizzle == SWIZZLE_XYZW) {
  86.          return GL_TRUE;
  87.       }
  88.    }
  89.    return GL_FALSE;
  90. }
  91.  
  92.  
  93.  
  94. /**
  95.  * Make fragment shader for glDraw/CopyPixels.  This shader is made
  96.  * by combining the pixel transfer shader with the user-defined shader.
  97.  * \return pointer to Gallium driver fragment shader
  98.  */
  99. static void *
  100. combined_drawpix_fragment_program(struct gl_context *ctx)
  101. {
  102.    struct st_context *st = st_context(ctx);
  103.    struct st_fragment_program *stfp;
  104.  
  105.    if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn
  106.        && st->fp->serialNo == st->pixel_xfer.user_prog_sn) {
  107.       /* the pixel tranfer program has not changed and the user-defined
  108.        * program has not changed, so re-use the combined program.
  109.        */
  110.       stfp = st->pixel_xfer.combined_prog;
  111.    }
  112.    else {
  113.       /* Concatenate the pixel transfer program with the current user-
  114.        * defined program.
  115.        */
  116.       if (is_passthrough_program(&st->fp->Base)) {
  117.          stfp = (struct st_fragment_program *)
  118.             _mesa_clone_fragment_program(ctx, &st->pixel_xfer.program->Base);
  119.       }
  120.       else {
  121. #if 0
  122.          printf("Base program:\n");
  123.          _mesa_print_program(&st->fp->Base.Base);
  124.          printf("DrawPix program:\n");
  125.          _mesa_print_program(&st->pixel_xfer.program->Base.Base);
  126. #endif
  127.          stfp = (struct st_fragment_program *)
  128.             _mesa_combine_programs(ctx,
  129.                                    &st->pixel_xfer.program->Base.Base,
  130.                                    &st->fp->Base.Base);
  131.       }
  132.  
  133. #if 0
  134.       {
  135.          struct gl_program *p = &stfp->Base.Base;
  136.          printf("Combined DrawPixels program:\n");
  137.          _mesa_print_program(p);
  138.          printf("InputsRead: 0x%x\n", p->InputsRead);
  139.          printf("OutputsWritten: 0x%x\n", p->OutputsWritten);
  140.          _mesa_print_parameter_list(p->Parameters);
  141.       }
  142. #endif
  143.  
  144.       /* translate to TGSI tokens */
  145.       st_translate_fragment_program(st, stfp);
  146.  
  147.       /* save new program, update serial numbers */
  148.       st->pixel_xfer.xfer_prog_sn = st->pixel_xfer.program->serialNo;
  149.       st->pixel_xfer.user_prog_sn = st->fp->serialNo;
  150.       st->pixel_xfer.combined_prog_sn = stfp->serialNo;
  151.       /* can't reference new program directly, already have a reference on it */
  152.       st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
  153.       st->pixel_xfer.combined_prog = stfp;
  154.    }
  155.  
  156.    /* Ideally we'd have updated the pipe constants during the normal
  157.     * st/atom mechanism.  But we can't since this is specific to glDrawPixels.
  158.     */
  159.    st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT);
  160.  
  161.    return stfp->driver_shader;
  162. }
  163.  
  164.  
  165. /**
  166.  * Create fragment shader that does a TEX() instruction to get a Z and/or
  167.  * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL.
  168.  * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX).
  169.  * Pass fragment color through as-is.
  170.  * \return pointer to the Gallium driver fragment shader
  171.  */
  172. static void *
  173. make_fragment_shader_z_stencil(struct st_context *st, GLboolean write_depth,
  174.                                GLboolean write_stencil)
  175. {
  176.    struct gl_context *ctx = st->ctx;
  177.    struct gl_program *p;
  178.    struct st_fragment_program *stp;
  179.    GLuint ic = 0;
  180.    const GLuint shaderIndex = write_depth * 2 + write_stencil;
  181.  
  182.    assert(shaderIndex < Elements(st->drawpix.shaders));
  183.  
  184.    if (st->drawpix.shaders[shaderIndex]) {
  185.       /* already have the proper shader */
  186.       return st->drawpix.shaders[shaderIndex]->driver_shader;
  187.    }
  188.  
  189.    /*
  190.     * Create shader now
  191.     */
  192.    p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
  193.    if (!p)
  194.       return NULL;
  195.  
  196.    p->NumInstructions = write_depth ? 2 : 1;
  197.    p->NumInstructions += write_stencil ? 1 : 0;
  198.  
  199.    p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
  200.    if (!p->Instructions) {
  201.       ctx->Driver.DeleteProgram(ctx, p);
  202.       return NULL;
  203.    }
  204.    _mesa_init_instructions(p->Instructions, p->NumInstructions);
  205.  
  206.    if (write_depth) {
  207.       /* TEX result.depth, fragment.texcoord[0], texture[0], 2D; */
  208.       p->Instructions[ic].Opcode = OPCODE_TEX;
  209.       p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
  210.       p->Instructions[ic].DstReg.Index = FRAG_RESULT_DEPTH;
  211.       p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Z;
  212.       p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
  213.       p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
  214.       p->Instructions[ic].TexSrcUnit = 0;
  215.       p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
  216.       ic++;
  217.    }
  218.  
  219.    if (write_stencil) {
  220.       /* TEX result.stencil, fragment.texcoord[0], texture[0], 2D; */
  221.       p->Instructions[ic].Opcode = OPCODE_TEX;
  222.       p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
  223.       p->Instructions[ic].DstReg.Index = FRAG_RESULT_STENCIL;
  224.       p->Instructions[ic].DstReg.WriteMask = WRITEMASK_Y;
  225.       p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
  226.       p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
  227.       p->Instructions[ic].TexSrcUnit = 1;
  228.       p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
  229.       ic++;
  230.    }
  231.  
  232.    /* END; */
  233.    p->Instructions[ic++].Opcode = OPCODE_END;
  234.  
  235.    assert(ic == p->NumInstructions);
  236.  
  237.    p->InputsRead = FRAG_BIT_TEX0 | FRAG_BIT_COL0;
  238.    p->OutputsWritten = 0;
  239.    if (write_depth)
  240.       p->OutputsWritten |= (1 << FRAG_RESULT_DEPTH);
  241.    if (write_stencil)
  242.       p->OutputsWritten |= (1 << FRAG_RESULT_STENCIL);
  243.  
  244.    p->SamplersUsed =  0x1;  /* sampler 0 (bit 0) is used */
  245.    if (write_stencil)
  246.       p->SamplersUsed |= 1 << 1;
  247.  
  248.    stp = st_fragment_program((struct gl_fragment_program *) p);
  249.  
  250.    /* save the new shader */
  251.    st->drawpix.shaders[shaderIndex] = stp;
  252.  
  253.    st_translate_fragment_program(st, stp);
  254.  
  255.    return stp->driver_shader;
  256. }
  257.  
  258.  
  259.  
  260. /**
  261.  * Create a simple vertex shader that just passes through the
  262.  * vertex position and texcoord (and optionally, color).
  263.  */
  264. static void *
  265. make_passthrough_vertex_shader(struct st_context *st,
  266.                                GLboolean passColor)
  267. {
  268.    if (!st->drawpix.vert_shaders[passColor]) {
  269.       struct ureg_program *ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
  270.  
  271.       if (ureg == NULL)
  272.          return NULL;
  273.  
  274.       /* MOV result.pos, vertex.pos; */
  275.       ureg_MOV(ureg,
  276.                ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ),
  277.                ureg_DECL_vs_input( ureg, 0 ));
  278.      
  279.       /* MOV result.texcoord0, vertex.attr[1]; */
  280.       ureg_MOV(ureg,
  281.                ureg_DECL_output( ureg, TGSI_SEMANTIC_GENERIC, 0 ),
  282.                ureg_DECL_vs_input( ureg, 1 ));
  283.      
  284.       if (passColor) {
  285.          /* MOV result.color0, vertex.attr[2]; */
  286.          ureg_MOV(ureg,
  287.                   ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ),
  288.                   ureg_DECL_vs_input( ureg, 2 ));
  289.       }
  290.  
  291.       ureg_END( ureg );
  292.      
  293.       st->drawpix.vert_shaders[passColor] =
  294.          ureg_create_shader_and_destroy( ureg, st->pipe );
  295.    }
  296.  
  297.    return st->drawpix.vert_shaders[passColor];
  298. }
  299.  
  300.  
  301. /**
  302.  * Return a texture base format for drawing/copying an image
  303.  * of the given format.
  304.  */
  305. static GLenum
  306. base_format(GLenum format)
  307. {
  308.    switch (format) {
  309.    case GL_DEPTH_COMPONENT:
  310.       return GL_DEPTH_COMPONENT;
  311.    case GL_DEPTH_STENCIL:
  312.       return GL_DEPTH_STENCIL;
  313.    case GL_STENCIL_INDEX:
  314.       return GL_STENCIL_INDEX;
  315.    default:
  316.       return GL_RGBA;
  317.    }
  318. }
  319.  
  320.  
  321. /**
  322.  * Return a texture internalFormat for drawing/copying an image
  323.  * of the given format and type.
  324.  */
  325. static GLenum
  326. internal_format(GLenum format, GLenum type)
  327. {
  328.    switch (format) {
  329.    case GL_DEPTH_COMPONENT:
  330.       return GL_DEPTH_COMPONENT;
  331.    case GL_DEPTH_STENCIL:
  332.       return GL_DEPTH_STENCIL;
  333.    case GL_STENCIL_INDEX:
  334.       return GL_STENCIL_INDEX;
  335.    default:
  336.       if (_mesa_is_integer_format(format)) {
  337.          switch (type) {
  338.          case GL_BYTE:
  339.             return GL_RGBA8I;
  340.          case GL_UNSIGNED_BYTE:
  341.             return GL_RGBA8UI;
  342.          case GL_SHORT:
  343.             return GL_RGBA16I;
  344.          case GL_UNSIGNED_SHORT:
  345.             return GL_RGBA16UI;
  346.          case GL_INT:
  347.             return GL_RGBA32I;
  348.          case GL_UNSIGNED_INT:
  349.             return GL_RGBA32UI;
  350.          default:
  351.             assert(0 && "Unexpected type in internal_format()");
  352.             return GL_RGBA_INTEGER;
  353.          }
  354.       }
  355.       else {
  356.          return GL_RGBA;
  357.       }
  358.    }
  359. }
  360.  
  361.  
  362. /**
  363.  * Create a temporary texture to hold an image of the given size.
  364.  * If width, height are not POT and the driver only handles POT textures,
  365.  * allocate the next larger size of texture that is POT.
  366.  */
  367. static struct pipe_resource *
  368. alloc_texture(struct st_context *st, GLsizei width, GLsizei height,
  369.               enum pipe_format texFormat)
  370. {
  371.    struct pipe_resource *pt;
  372.  
  373.    pt = st_texture_create(st, st->internal_target, texFormat, 0,
  374.                           width, height, 1, PIPE_BIND_SAMPLER_VIEW);
  375.  
  376.    return pt;
  377. }
  378.  
  379.  
  380. /**
  381.  * Make texture containing an image for glDrawPixels image.
  382.  * If 'pixels' is NULL, leave the texture image data undefined.
  383.  */
  384. static struct pipe_resource *
  385. make_texture(struct st_context *st,
  386.              GLsizei width, GLsizei height, GLenum format, GLenum type,
  387.              const struct gl_pixelstore_attrib *unpack,
  388.              const GLvoid *pixels)
  389. {
  390.    struct gl_context *ctx = st->ctx;
  391.    struct pipe_context *pipe = st->pipe;
  392.    gl_format mformat;
  393.    struct pipe_resource *pt;
  394.    enum pipe_format pipeFormat;
  395.    GLuint cpp;
  396.    GLenum baseFormat, intFormat;
  397.  
  398.    baseFormat = base_format(format);
  399.    intFormat = internal_format(format, type);
  400.  
  401.    mformat = st_ChooseTextureFormat_renderable(ctx, intFormat,
  402.                                                format, type, GL_FALSE);
  403.    assert(mformat);
  404.  
  405.    pipeFormat = st_mesa_format_to_pipe_format(mformat);
  406.    assert(pipeFormat);
  407.    cpp = util_format_get_blocksize(pipeFormat);
  408.  
  409.    pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
  410.    if (!pixels)
  411.       return NULL;
  412.  
  413.    /* alloc temporary texture */
  414.    pt = alloc_texture(st, width, height, pipeFormat);
  415.    if (!pt) {
  416.       _mesa_unmap_pbo_source(ctx, unpack);
  417.       return NULL;
  418.    }
  419.  
  420.    {
  421.       struct pipe_transfer *transfer;
  422.       static const GLuint dstImageOffsets = 0;
  423.       GLboolean success;
  424.       GLubyte *dest;
  425.       const GLbitfield imageTransferStateSave = ctx->_ImageTransferState;
  426.  
  427.       /* we'll do pixel transfer in a fragment shader */
  428.       ctx->_ImageTransferState = 0x0;
  429.  
  430.       transfer = pipe_get_transfer(st->pipe, pt, 0, 0,
  431.                                    PIPE_TRANSFER_WRITE, 0, 0,
  432.                                    width, height);
  433.  
  434.       /* map texture transfer */
  435.       dest = pipe_transfer_map(pipe, transfer);
  436.  
  437.  
  438.       /* Put image into texture transfer.
  439.        * Note that the image is actually going to be upside down in
  440.        * the texture.  We deal with that with texcoords.
  441.        */
  442.       success = _mesa_texstore(ctx, 2,           /* dims */
  443.                                baseFormat,       /* baseInternalFormat */
  444.                                mformat,          /* gl_format */
  445.                                dest,             /* dest */
  446.                                0, 0, 0,          /* dstX/Y/Zoffset */
  447.                                transfer->stride, /* dstRowStride, bytes */
  448.                                &dstImageOffsets, /* dstImageOffsets */
  449.                                width, height, 1, /* size */
  450.                                format, type,     /* src format/type */
  451.                                pixels,           /* data source */
  452.                                unpack);
  453.  
  454.       /* unmap */
  455.       pipe_transfer_unmap(pipe, transfer);
  456.       pipe->transfer_destroy(pipe, transfer);
  457.  
  458.       assert(success);
  459.  
  460.       /* restore */
  461.       ctx->_ImageTransferState = imageTransferStateSave;
  462.    }
  463.  
  464.    _mesa_unmap_pbo_source(ctx, unpack);
  465.  
  466.    return pt;
  467. }
  468.  
  469.  
  470. /**
  471.  * Draw quad with texcoords and optional color.
  472.  * Coords are gallium window coords with y=0=top.
  473.  * \param color  may be null
  474.  * \param invertTex  if true, flip texcoords vertically
  475.  */
  476. static void
  477. draw_quad(struct gl_context *ctx, GLfloat x0, GLfloat y0, GLfloat z,
  478.           GLfloat x1, GLfloat y1, const GLfloat *color,
  479.           GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord)
  480. {
  481.    struct st_context *st = st_context(ctx);
  482.    struct pipe_context *pipe = st->pipe;
  483.    GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */
  484.  
  485.    /* setup vertex data */
  486.    {
  487.       const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
  488.       const GLfloat fb_width = (GLfloat) fb->Width;
  489.       const GLfloat fb_height = (GLfloat) fb->Height;
  490.       const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f;
  491.       const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f;
  492.       const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f;
  493.       const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f;
  494.       const GLfloat sLeft = 0.0f, sRight = maxXcoord;
  495.       const GLfloat tTop = invertTex ? maxYcoord : 0.0f;
  496.       const GLfloat tBot = invertTex ? 0.0f : maxYcoord;
  497.       GLuint i;
  498.  
  499.       /* upper-left */
  500.       verts[0][0][0] = clip_x0;    /* v[0].attr[0].x */
  501.       verts[0][0][1] = clip_y0;    /* v[0].attr[0].y */
  502.  
  503.       /* upper-right */
  504.       verts[1][0][0] = clip_x1;
  505.       verts[1][0][1] = clip_y0;
  506.  
  507.       /* lower-right */
  508.       verts[2][0][0] = clip_x1;
  509.       verts[2][0][1] = clip_y1;
  510.  
  511.       /* lower-left */
  512.       verts[3][0][0] = clip_x0;
  513.       verts[3][0][1] = clip_y1;
  514.  
  515.       verts[0][1][0] = sLeft; /* v[0].attr[1].S */
  516.       verts[0][1][1] = tTop;  /* v[0].attr[1].T */
  517.       verts[1][1][0] = sRight;
  518.       verts[1][1][1] = tTop;
  519.       verts[2][1][0] = sRight;
  520.       verts[2][1][1] = tBot;
  521.       verts[3][1][0] = sLeft;
  522.       verts[3][1][1] = tBot;
  523.  
  524.       /* same for all verts: */
  525.       if (color) {
  526.          for (i = 0; i < 4; i++) {
  527.             verts[i][0][2] = z;         /* v[i].attr[0].z */
  528.             verts[i][0][3] = 1.0f;      /* v[i].attr[0].w */
  529.             verts[i][2][0] = color[0];  /* v[i].attr[2].r */
  530.             verts[i][2][1] = color[1];  /* v[i].attr[2].g */
  531.             verts[i][2][2] = color[2];  /* v[i].attr[2].b */
  532.             verts[i][2][3] = color[3];  /* v[i].attr[2].a */
  533.             verts[i][1][2] = 0.0f;      /* v[i].attr[1].R */
  534.             verts[i][1][3] = 1.0f;      /* v[i].attr[1].Q */
  535.          }
  536.       }
  537.       else {
  538.          for (i = 0; i < 4; i++) {
  539.             verts[i][0][2] = z;    /*Z*/
  540.             verts[i][0][3] = 1.0f; /*W*/
  541.             verts[i][1][2] = 0.0f; /*R*/
  542.             verts[i][1][3] = 1.0f; /*Q*/
  543.          }
  544.       }
  545.    }
  546.  
  547.    {
  548.       struct pipe_resource *buf;
  549.  
  550.       /* allocate/load buffer object with vertex data */
  551.       buf = pipe_buffer_create(pipe->screen,
  552.                                PIPE_BIND_VERTEX_BUFFER,
  553.                                sizeof(verts));
  554.       pipe_buffer_write(st->pipe, buf, 0, sizeof(verts), verts);
  555.  
  556.       util_draw_vertex_buffer(pipe, buf, 0,
  557.                               PIPE_PRIM_QUADS,
  558.                               4,  /* verts */
  559.                               3); /* attribs/vert */
  560.       pipe_resource_reference(&buf, NULL);
  561.    }
  562. }
  563.  
  564.  
  565.  
  566. static void
  567. draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
  568.                    GLsizei width, GLsizei height,
  569.                    GLfloat zoomX, GLfloat zoomY,
  570.                    struct pipe_sampler_view **sv,
  571.                    int num_sampler_view,
  572.                    void *driver_vp,
  573.                    void *driver_fp,
  574.                    const GLfloat *color,
  575.                    GLboolean invertTex,
  576.                    GLboolean write_depth, GLboolean write_stencil)
  577. {
  578.    struct st_context *st = st_context(ctx);
  579.    struct pipe_context *pipe = st->pipe;
  580.    struct cso_context *cso = st->cso_context;
  581.    GLfloat x0, y0, x1, y1;
  582.    GLsizei maxSize;
  583.    boolean normalized = sv[0]->texture->target != PIPE_TEXTURE_RECT;
  584.  
  585.    /* limit checks */
  586.    /* XXX if DrawPixels image is larger than max texture size, break
  587.     * it up into chunks.
  588.     */
  589.    maxSize = 1 << (pipe->screen->get_param(pipe->screen,
  590.                                         PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
  591.    assert(width <= maxSize);
  592.    assert(height <= maxSize);
  593.  
  594.    cso_save_rasterizer(cso);
  595.    cso_save_viewport(cso);
  596.    cso_save_samplers(cso);
  597.    cso_save_fragment_sampler_views(cso);
  598.    cso_save_fragment_shader(cso);
  599.    cso_save_vertex_shader(cso);
  600.    cso_save_vertex_elements(cso);
  601.    if (write_stencil) {
  602.       cso_save_depth_stencil_alpha(cso);
  603.       cso_save_blend(cso);
  604.    }
  605.  
  606.    /* rasterizer state: just scissor */
  607.    {
  608.       struct pipe_rasterizer_state rasterizer;
  609.       memset(&rasterizer, 0, sizeof(rasterizer));
  610.       rasterizer.gl_rasterization_rules = 1;
  611.       rasterizer.scissor = ctx->Scissor.Enabled;
  612.       cso_set_rasterizer(cso, &rasterizer);
  613.    }
  614.  
  615.    if (write_stencil) {
  616.       /* Stencil writing bypasses the normal fragment pipeline to
  617.        * disable color writing and set stencil test to always pass.
  618.        */
  619.       struct pipe_depth_stencil_alpha_state dsa;
  620.       struct pipe_blend_state blend;
  621.  
  622.       /* depth/stencil */
  623.       memset(&dsa, 0, sizeof(dsa));
  624.       dsa.stencil[0].enabled = 1;
  625.       dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
  626.       dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff;
  627.       dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
  628.       if (write_depth) {
  629.          /* writing depth+stencil: depth test always passes */
  630.          dsa.depth.enabled = 1;
  631.          dsa.depth.writemask = ctx->Depth.Mask;
  632.          dsa.depth.func = PIPE_FUNC_ALWAYS;
  633.       }
  634.       cso_set_depth_stencil_alpha(cso, &dsa);
  635.  
  636.       /* blend (colormask) */
  637.       memset(&blend, 0, sizeof(blend));
  638.       cso_set_blend(cso, &blend);
  639.    }
  640.  
  641.    /* fragment shader state: TEX lookup program */
  642.    cso_set_fragment_shader_handle(cso, driver_fp);
  643.  
  644.    /* vertex shader state: position + texcoord pass-through */
  645.    cso_set_vertex_shader_handle(cso, driver_vp);
  646.  
  647.  
  648.    /* texture sampling state: */
  649.    {
  650.       struct pipe_sampler_state sampler;
  651.       memset(&sampler, 0, sizeof(sampler));
  652.       sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
  653.       sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
  654.       sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
  655.       sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
  656.       sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
  657.       sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
  658.       sampler.normalized_coords = normalized;
  659.  
  660.       cso_single_sampler(cso, 0, &sampler);
  661.       if (num_sampler_view > 1) {
  662.          cso_single_sampler(cso, 1, &sampler);
  663.       }
  664.       cso_single_sampler_done(cso);
  665.    }
  666.  
  667.    /* viewport state: viewport matching window dims */
  668.    {
  669.       const float w = (float) ctx->DrawBuffer->Width;
  670.       const float h = (float) ctx->DrawBuffer->Height;
  671.       struct pipe_viewport_state vp;
  672.       vp.scale[0] =  0.5f * w;
  673.       vp.scale[1] = -0.5f * h;
  674.       vp.scale[2] = 0.5f;
  675.       vp.scale[3] = 1.0f;
  676.       vp.translate[0] = 0.5f * w;
  677.       vp.translate[1] = 0.5f * h;
  678.       vp.translate[2] = 0.5f;
  679.       vp.translate[3] = 0.0f;
  680.       cso_set_viewport(cso, &vp);
  681.    }
  682.  
  683.    cso_set_vertex_elements(cso, 3, st->velems_util_draw);
  684.  
  685.    /* texture state: */
  686.    cso_set_fragment_sampler_views(cso, num_sampler_view, sv);
  687.  
  688.    /* Compute Gallium window coords (y=0=top) with pixel zoom.
  689.     * Recall that these coords are transformed by the current
  690.     * vertex shader and viewport transformation.
  691.     */
  692.    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) {
  693.       y = ctx->DrawBuffer->Height - (int) (y + height * ctx->Pixel.ZoomY);
  694.       invertTex = !invertTex;
  695.    }
  696.  
  697.    x0 = (GLfloat) x;
  698.    x1 = x + width * ctx->Pixel.ZoomX;
  699.    y0 = (GLfloat) y;
  700.    y1 = y + height * ctx->Pixel.ZoomY;
  701.  
  702.    /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */
  703.    z = z * 2.0 - 1.0;
  704.  
  705.    draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
  706.              normalized ? ((GLfloat) width / sv[0]->texture->width0) : (GLfloat)width,
  707.              normalized ? ((GLfloat) height / sv[0]->texture->height0) : (GLfloat)height);
  708.  
  709.    /* restore state */
  710.    cso_restore_rasterizer(cso);
  711.    cso_restore_viewport(cso);
  712.    cso_restore_samplers(cso);
  713.    cso_restore_fragment_sampler_views(cso);
  714.    cso_restore_fragment_shader(cso);
  715.    cso_restore_vertex_shader(cso);
  716.    cso_restore_vertex_elements(cso);
  717.    if (write_stencil) {
  718.       cso_restore_depth_stencil_alpha(cso);
  719.       cso_restore_blend(cso);
  720.    }
  721. }
  722.  
  723.  
  724. /**
  725.  * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we
  726.  * can't use a fragment shader to write stencil values.
  727.  */
  728. static void
  729. draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
  730.                     GLsizei width, GLsizei height, GLenum format, GLenum type,
  731.                     const struct gl_pixelstore_attrib *unpack,
  732.                     const GLvoid *pixels)
  733. {
  734.    struct st_context *st = st_context(ctx);
  735.    struct pipe_context *pipe = st->pipe;
  736.    struct st_renderbuffer *strb;
  737.    enum pipe_transfer_usage usage;
  738.    struct pipe_transfer *pt;
  739.    const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
  740.    GLint skipPixels;
  741.    ubyte *stmap;
  742.    struct gl_pixelstore_attrib clippedUnpack = *unpack;
  743.  
  744.    if (!zoom) {
  745.       if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
  746.                                  &clippedUnpack)) {
  747.          /* totally clipped */
  748.          return;
  749.       }
  750.    }
  751.  
  752.    strb = st_renderbuffer(ctx->DrawBuffer->
  753.                           Attachment[BUFFER_STENCIL].Renderbuffer);
  754.  
  755.    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
  756.       y = ctx->DrawBuffer->Height - y - height;
  757.    }
  758.  
  759.    if(format != GL_DEPTH_STENCIL &&
  760.       util_format_get_component_bits(strb->format,
  761.                                      UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
  762.       usage = PIPE_TRANSFER_READ_WRITE;
  763.    else
  764.       usage = PIPE_TRANSFER_WRITE;
  765.  
  766.    pt = pipe_get_transfer(st_context(ctx)->pipe, strb->texture, 0, 0,
  767.                                      usage, x, y,
  768.                                      width, height);
  769.  
  770.    stmap = pipe_transfer_map(pipe, pt);
  771.  
  772.    pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels);
  773.    assert(pixels);
  774.  
  775.    /* if width > MAX_WIDTH, have to process image in chunks */
  776.    skipPixels = 0;
  777.    while (skipPixels < width) {
  778.       const GLint spanX = skipPixels;
  779.       const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
  780.       GLint row;
  781.       for (row = 0; row < height; row++) {
  782.          GLubyte sValues[MAX_WIDTH];
  783.          GLuint zValues[MAX_WIDTH];
  784.          GLenum destType = GL_UNSIGNED_BYTE;
  785.          const GLvoid *source = _mesa_image_address2d(&clippedUnpack, pixels,
  786.                                                       width, height,
  787.                                                       format, type,
  788.                                                       row, skipPixels);
  789.          _mesa_unpack_stencil_span(ctx, spanWidth, destType, sValues,
  790.                                    type, source, &clippedUnpack,
  791.                                    ctx->_ImageTransferState);
  792.  
  793.          if (format == GL_DEPTH_STENCIL) {
  794.             _mesa_unpack_depth_span(ctx, spanWidth, GL_UNSIGNED_INT, zValues,
  795.                                     (1 << 24) - 1, type, source,
  796.                                     &clippedUnpack);
  797.          }
  798.  
  799.          if (zoom) {
  800.             _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with "
  801.                           "zoom not complete");
  802.          }
  803.  
  804.          {
  805.             GLint spanY;
  806.  
  807.             if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
  808.                spanY = height - row - 1;
  809.             }
  810.             else {
  811.                spanY = row;
  812.             }
  813.  
  814.             /* now pack the stencil (and Z) values in the dest format */
  815.             switch (pt->resource->format) {
  816.             case PIPE_FORMAT_S8_USCALED:
  817.                {
  818.                   ubyte *dest = stmap + spanY * pt->stride + spanX;
  819.                   assert(usage == PIPE_TRANSFER_WRITE);
  820.                   memcpy(dest, sValues, spanWidth);
  821.                }
  822.                break;
  823.             case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
  824.                if (format == GL_DEPTH_STENCIL) {
  825.                   uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
  826.                   GLint k;
  827.                   assert(usage == PIPE_TRANSFER_WRITE);
  828.                   for (k = 0; k < spanWidth; k++) {
  829.                      dest[k] = zValues[k] | (sValues[k] << 24);
  830.                   }
  831.                }
  832.                else {
  833.                   uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
  834.                   GLint k;
  835.                   assert(usage == PIPE_TRANSFER_READ_WRITE);
  836.                   for (k = 0; k < spanWidth; k++) {
  837.                      dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24);
  838.                   }
  839.                }
  840.                break;
  841.             case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
  842.                if (format == GL_DEPTH_STENCIL) {
  843.                   uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
  844.                   GLint k;
  845.                   assert(usage == PIPE_TRANSFER_WRITE);
  846.                   for (k = 0; k < spanWidth; k++) {
  847.                      dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff);
  848.                   }
  849.                }
  850.                else {
  851.                   uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4);
  852.                   GLint k;
  853.                   assert(usage == PIPE_TRANSFER_READ_WRITE);
  854.                   for (k = 0; k < spanWidth; k++) {
  855.                      dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff);
  856.                   }
  857.                }
  858.                break;
  859.             default:
  860.                assert(0);
  861.             }
  862.          }
  863.       }
  864.       skipPixels += spanWidth;
  865.    }
  866.  
  867.    _mesa_unmap_pbo_source(ctx, &clippedUnpack);
  868.  
  869.    /* unmap the stencil buffer */
  870.    pipe_transfer_unmap(pipe, pt);
  871.    pipe->transfer_destroy(pipe, pt);
  872. }
  873.  
  874.  
  875. /**
  876.  * Called via ctx->Driver.DrawPixels()
  877.  */
  878. static void
  879. st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
  880.               GLsizei width, GLsizei height,
  881.               GLenum format, GLenum type,
  882.               const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels)
  883. {
  884.    void *driver_vp, *driver_fp;
  885.    struct st_context *st = st_context(ctx);
  886.    const GLfloat *color;
  887.    struct pipe_context *pipe = st->pipe;
  888.    GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE;
  889.    struct pipe_sampler_view *sv[2];
  890.    int num_sampler_view = 1;
  891.    enum pipe_format stencil_format = PIPE_FORMAT_NONE;
  892.  
  893.    if (format == GL_DEPTH_STENCIL)
  894.       write_stencil = write_depth = GL_TRUE;
  895.    else if (format == GL_STENCIL_INDEX)
  896.       write_stencil = GL_TRUE;
  897.    else if (format == GL_DEPTH_COMPONENT)
  898.       write_depth = GL_TRUE;
  899.  
  900.    if (write_stencil) {
  901.       enum pipe_format tex_format;
  902.       /* can we write to stencil if not fallback */
  903.       if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT))
  904.          goto stencil_fallback;
  905.      
  906.       tex_format = st_choose_format(st->pipe->screen, base_format(format),
  907.                                     PIPE_TEXTURE_2D,
  908.                                     0, PIPE_BIND_SAMPLER_VIEW);
  909.       if (tex_format == PIPE_FORMAT_Z24_UNORM_S8_USCALED)
  910.          stencil_format = PIPE_FORMAT_X24S8_USCALED;
  911.       else if (tex_format == PIPE_FORMAT_S8_USCALED_Z24_UNORM)
  912.          stencil_format = PIPE_FORMAT_S8X24_USCALED;
  913.       else
  914.          stencil_format = PIPE_FORMAT_S8_USCALED;
  915.       if (stencil_format == PIPE_FORMAT_NONE)
  916.          goto stencil_fallback;
  917.    }
  918.  
  919.    /* Mesa state should be up to date by now */
  920.    assert(ctx->NewState == 0x0);
  921.  
  922.    st_validate_state(st);
  923.  
  924.    if (write_depth || write_stencil) {
  925.       driver_fp = make_fragment_shader_z_stencil(st, write_depth, write_stencil);
  926.       driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
  927.       color = ctx->Current.RasterColor;
  928.    }
  929.    else {
  930.       driver_fp = combined_drawpix_fragment_program(ctx);
  931.       driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
  932.       color = NULL;
  933.       if (st->pixel_xfer.pixelmap_enabled) {
  934.           sv[1] = st->pixel_xfer.pixelmap_sampler_view;
  935.           num_sampler_view++;
  936.       }
  937.    }
  938.  
  939.    /* draw with textured quad */
  940.    {
  941.       struct pipe_resource *pt
  942.          = make_texture(st, width, height, format, type, unpack, pixels);
  943.       if (pt) {
  944.          sv[0] = st_create_texture_sampler_view(st->pipe, pt);
  945.  
  946.          if (sv[0]) {
  947.             if (write_stencil) {
  948.                sv[1] = st_create_texture_sampler_view_format(st->pipe, pt,
  949.                                                              stencil_format);
  950.                num_sampler_view++;
  951.             }
  952.  
  953.             draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
  954.                                width, height,
  955.                                ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
  956.                                sv,
  957.                                num_sampler_view,
  958.                                driver_vp,
  959.                                driver_fp,
  960.                                color, GL_FALSE, write_depth, write_stencil);
  961.             pipe_sampler_view_reference(&sv[0], NULL);
  962.             if (num_sampler_view > 1)
  963.                pipe_sampler_view_reference(&sv[1], NULL);
  964.          }
  965.          pipe_resource_reference(&pt, NULL);
  966.       }
  967.    }
  968.    return;
  969.  
  970. stencil_fallback:
  971.    draw_stencil_pixels(ctx, x, y, width, height, format, type,
  972.                        unpack, pixels);
  973. }
  974.  
  975.  
  976.  
  977. /**
  978.  * Software fallback for glCopyPixels(GL_STENCIL).
  979.  */
  980. static void
  981. copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
  982.                     GLsizei width, GLsizei height,
  983.                     GLint dstx, GLint dsty)
  984. {
  985.    struct st_renderbuffer *rbDraw;
  986.    struct pipe_context *pipe = st_context(ctx)->pipe;
  987.    enum pipe_transfer_usage usage;
  988.    struct pipe_transfer *ptDraw;
  989.    ubyte *drawMap;
  990.    ubyte *buffer;
  991.    int i;
  992.  
  993.    buffer = malloc(width * height * sizeof(ubyte));
  994.    if (!buffer) {
  995.       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)");
  996.       return;
  997.    }
  998.  
  999.    /* Get the dest renderbuffer.  If there's a wrapper, use the
  1000.     * underlying renderbuffer.
  1001.     */
  1002.    rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer);
  1003.    if (rbDraw->Base.Wrapped)
  1004.       rbDraw = st_renderbuffer(rbDraw->Base.Wrapped);
  1005.  
  1006.    /* this will do stencil pixel transfer ops */
  1007.    st_read_stencil_pixels(ctx, srcx, srcy, width, height,
  1008.                           GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
  1009.                           &ctx->DefaultPacking, buffer);
  1010.  
  1011.    if (0) {
  1012.       /* debug code: dump stencil values */
  1013.       GLint row, col;
  1014.       for (row = 0; row < height; row++) {
  1015.          printf("%3d: ", row);
  1016.          for (col = 0; col < width; col++) {
  1017.             printf("%02x ", buffer[col + row * width]);
  1018.          }
  1019.          printf("\n");
  1020.       }
  1021.    }
  1022.  
  1023.    if (util_format_get_component_bits(rbDraw->format,
  1024.                                      UTIL_FORMAT_COLORSPACE_ZS, 0) != 0)
  1025.       usage = PIPE_TRANSFER_READ_WRITE;
  1026.    else
  1027.       usage = PIPE_TRANSFER_WRITE;
  1028.  
  1029.    if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
  1030.       dsty = rbDraw->Base.Height - dsty - height;
  1031.    }
  1032.  
  1033.    ptDraw = pipe_get_transfer(st_context(ctx)->pipe,
  1034.                               rbDraw->texture, 0, 0,
  1035.                               usage, dstx, dsty,
  1036.                               width, height);
  1037.  
  1038.    assert(util_format_get_blockwidth(ptDraw->resource->format) == 1);
  1039.    assert(util_format_get_blockheight(ptDraw->resource->format) == 1);
  1040.  
  1041.    /* map the stencil buffer */
  1042.    drawMap = pipe_transfer_map(pipe, ptDraw);
  1043.  
  1044.    /* draw */
  1045.    /* XXX PixelZoom not handled yet */
  1046.    for (i = 0; i < height; i++) {
  1047.       ubyte *dst;
  1048.       const ubyte *src;
  1049.       int y;
  1050.  
  1051.       y = i;
  1052.  
  1053.       if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
  1054.          y = height - y - 1;
  1055.       }
  1056.  
  1057.       dst = drawMap + y * ptDraw->stride;
  1058.       src = buffer + i * width;
  1059.  
  1060.       switch (ptDraw->resource->format) {
  1061.       case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
  1062.          {
  1063.             uint *dst4 = (uint *) dst;
  1064.             int j;
  1065.             assert(usage == PIPE_TRANSFER_READ_WRITE);
  1066.             for (j = 0; j < width; j++) {
  1067.                *dst4 = (*dst4 & 0xffffff) | (src[j] << 24);
  1068.                dst4++;
  1069.             }
  1070.          }
  1071.          break;
  1072.       case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
  1073.          {
  1074.             uint *dst4 = (uint *) dst;
  1075.             int j;
  1076.             assert(usage == PIPE_TRANSFER_READ_WRITE);
  1077.             for (j = 0; j < width; j++) {
  1078.                *dst4 = (*dst4 & 0xffffff00) | (src[j] & 0xff);
  1079.                dst4++;
  1080.             }
  1081.          }
  1082.          break;
  1083.       case PIPE_FORMAT_S8_USCALED:
  1084.          assert(usage == PIPE_TRANSFER_WRITE);
  1085.          memcpy(dst, src, width);
  1086.          break;
  1087.       default:
  1088.          assert(0);
  1089.       }
  1090.    }
  1091.  
  1092.    free(buffer);
  1093.  
  1094.    /* unmap the stencil buffer */
  1095.    pipe_transfer_unmap(pipe, ptDraw);
  1096.    pipe->transfer_destroy(pipe, ptDraw);
  1097. }
  1098.  
  1099.  
  1100. static void
  1101. st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
  1102.               GLsizei width, GLsizei height,
  1103.               GLint dstx, GLint dsty, GLenum type)
  1104. {
  1105.    struct st_context *st = st_context(ctx);
  1106.    struct pipe_context *pipe = st->pipe;
  1107.    struct pipe_screen *screen = pipe->screen;
  1108.    struct st_renderbuffer *rbRead;
  1109.    void *driver_vp, *driver_fp;
  1110.    struct pipe_resource *pt;
  1111.    struct pipe_sampler_view *sv[2];
  1112.    int num_sampler_view = 1;
  1113.    GLfloat *color;
  1114.    enum pipe_format srcFormat, texFormat;
  1115.    GLboolean invertTex = GL_FALSE;
  1116.    GLint readX, readY, readW, readH;
  1117.    GLuint sample_count;
  1118.    struct gl_pixelstore_attrib pack = ctx->DefaultPacking;
  1119.  
  1120.    st_validate_state(st);
  1121.  
  1122.    if (type == GL_STENCIL) {
  1123.       /* can't use texturing to do stencil */
  1124.       copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty);
  1125.       return;
  1126.    }
  1127.  
  1128.    if (type == GL_COLOR) {
  1129.       rbRead = st_get_color_read_renderbuffer(ctx);
  1130.       color = NULL;
  1131.       driver_fp = combined_drawpix_fragment_program(ctx);
  1132.       driver_vp = make_passthrough_vertex_shader(st, GL_FALSE);
  1133.       if (st->pixel_xfer.pixelmap_enabled) {
  1134.           sv[1] = st->pixel_xfer.pixelmap_sampler_view;
  1135.           num_sampler_view++;
  1136.       }
  1137.    }
  1138.    else {
  1139.       assert(type == GL_DEPTH);
  1140.       rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
  1141.       color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
  1142.       driver_fp = make_fragment_shader_z_stencil(st, GL_TRUE, GL_FALSE);
  1143.       driver_vp = make_passthrough_vertex_shader(st, GL_TRUE);
  1144.    }
  1145.  
  1146.    if (rbRead->Base.Wrapped)
  1147.       rbRead = st_renderbuffer(rbRead->Base.Wrapped);
  1148.  
  1149.    sample_count = rbRead->texture->nr_samples;
  1150.    /* I believe this would be legal, presumably would need to do a resolve
  1151.       for color, and for depth/stencil spec says to just use one of the
  1152.       depth/stencil samples per pixel? Need some transfer clarifications. */
  1153.    assert(sample_count < 2);
  1154.  
  1155.    srcFormat = rbRead->texture->format;
  1156.  
  1157.    if (screen->is_format_supported(screen, srcFormat, st->internal_target,
  1158.                                    sample_count,
  1159.                                    PIPE_BIND_SAMPLER_VIEW, 0)) {
  1160.       texFormat = srcFormat;
  1161.    }
  1162.    else {
  1163.       /* srcFormat can't be used as a texture format */
  1164.       if (type == GL_DEPTH) {
  1165.          texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT,
  1166.                                       st->internal_target, sample_count,
  1167.                                       PIPE_BIND_DEPTH_STENCIL);
  1168.          assert(texFormat != PIPE_FORMAT_NONE);
  1169.       }
  1170.       else {
  1171.          /* default color format */
  1172.          texFormat = st_choose_format(screen, GL_RGBA, st->internal_target,
  1173.                                       sample_count, PIPE_BIND_SAMPLER_VIEW);
  1174.          assert(texFormat != PIPE_FORMAT_NONE);
  1175.       }
  1176.    }
  1177.  
  1178.    /* Invert src region if needed */
  1179.    if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
  1180.       srcy = ctx->ReadBuffer->Height - srcy - height;
  1181.       invertTex = !invertTex;
  1182.    }
  1183.  
  1184.    /* Clip the read region against the src buffer bounds.
  1185.     * We'll still allocate a temporary buffer/texture for the original
  1186.     * src region size but we'll only read the region which is on-screen.
  1187.     * This may mean that we draw garbage pixels into the dest region, but
  1188.     * that's expected.
  1189.     */
  1190.    readX = srcx;
  1191.    readY = srcy;
  1192.    readW = width;
  1193.    readH = height;
  1194.    _mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack);
  1195.    readW = MAX2(0, readW);
  1196.    readH = MAX2(0, readH);
  1197.  
  1198.    /* alloc temporary texture */
  1199.    pt = alloc_texture(st, width, height, texFormat);
  1200.    if (!pt)
  1201.       return;
  1202.  
  1203.    sv[0] = st_create_texture_sampler_view(st->pipe, pt);
  1204.    if (!sv[0]) {
  1205.       pipe_resource_reference(&pt, NULL);
  1206.       return;
  1207.    }
  1208.  
  1209.    /* Make temporary texture which is a copy of the src region.
  1210.     */
  1211.    if (srcFormat == texFormat) {
  1212.       struct pipe_box src_box;
  1213.       u_box_2d(readX, readY, readW, readH, &src_box);
  1214.     /* copy source framebuffer surface into mipmap/texture */
  1215.       pipe->resource_copy_region(pipe,
  1216.                                  pt,                                /* dest tex */
  1217.                                  0,
  1218.                                  pack.SkipPixels, pack.SkipRows, 0, /* dest pos */
  1219.                                  rbRead->texture,                   /* src tex */
  1220.                                  0,
  1221.                                  &src_box);
  1222.  
  1223.    }
  1224.    else {
  1225.       /* CPU-based fallback/conversion */
  1226.       struct pipe_transfer *ptRead =
  1227.          pipe_get_transfer(st->pipe, rbRead->texture,
  1228.                            0, 0, /* level, layer */
  1229.                            PIPE_TRANSFER_READ,
  1230.                            readX, readY, readW, readH);
  1231.       struct pipe_transfer *ptTex;
  1232.       enum pipe_transfer_usage transfer_usage;
  1233.  
  1234.       if (ST_DEBUG & DEBUG_FALLBACK)
  1235.          debug_printf("%s: fallback processing\n", __FUNCTION__);
  1236.  
  1237.       if (type == GL_DEPTH && util_format_is_depth_and_stencil(pt->format))
  1238.          transfer_usage = PIPE_TRANSFER_READ_WRITE;
  1239.       else
  1240.          transfer_usage = PIPE_TRANSFER_WRITE;
  1241.  
  1242.       ptTex = pipe_get_transfer(st->pipe, pt, 0, 0, transfer_usage,
  1243.                                 0, 0, width, height);
  1244.  
  1245.       /* copy image from ptRead surface to ptTex surface */
  1246.       if (type == GL_COLOR) {
  1247.          /* alternate path using get/put_tile() */
  1248.          GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat));
  1249.          pipe_get_tile_rgba(pipe, ptRead, 0, 0, readW, readH, buf);
  1250.          pipe_put_tile_rgba(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
  1251.                             readW, readH, buf);
  1252.          free(buf);
  1253.       }
  1254.       else {
  1255.          /* GL_DEPTH */
  1256.          GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint));
  1257.          pipe_get_tile_z(pipe, ptRead, 0, 0, readW, readH, buf);
  1258.          pipe_put_tile_z(pipe, ptTex, pack.SkipPixels, pack.SkipRows,
  1259.                          readW, readH, buf);
  1260.          free(buf);
  1261.       }
  1262.  
  1263.       pipe->transfer_destroy(pipe, ptRead);
  1264.       pipe->transfer_destroy(pipe, ptTex);
  1265.    }
  1266.  
  1267.    /* OK, the texture 'pt' contains the src image/pixels.  Now draw a
  1268.     * textured quad with that texture.
  1269.     */
  1270.    draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2],
  1271.                       width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
  1272.                       sv,
  1273.                       num_sampler_view,
  1274.                       driver_vp,
  1275.                       driver_fp,
  1276.                       color, invertTex, GL_FALSE, GL_FALSE);
  1277.  
  1278.    pipe_resource_reference(&pt, NULL);
  1279.    pipe_sampler_view_reference(&sv[0], NULL);
  1280. }
  1281.  
  1282.  
  1283.  
  1284. void st_init_drawpixels_functions(struct dd_function_table *functions)
  1285. {
  1286.    functions->DrawPixels = st_DrawPixels;
  1287.    functions->CopyPixels = st_CopyPixels;
  1288. }
  1289.  
  1290.  
  1291. void
  1292. st_destroy_drawpix(struct st_context *st)
  1293. {
  1294.    GLuint i;
  1295.  
  1296.    for (i = 0; i < Elements(st->drawpix.shaders); i++) {
  1297.       if (st->drawpix.shaders[i])
  1298.          st_reference_fragprog(st, &st->drawpix.shaders[i], NULL);
  1299.    }
  1300.  
  1301.    st_reference_fragprog(st, &st->pixel_xfer.combined_prog, NULL);
  1302.    if (st->drawpix.vert_shaders[0])
  1303.       ureg_free_tokens(st->drawpix.vert_shaders[0]);
  1304.    if (st->drawpix.vert_shaders[1])
  1305.       ureg_free_tokens(st->drawpix.vert_shaders[1]);
  1306. }
  1307.  
  1308. #endif /* FEATURE_drawpix */
  1309.