Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2008 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.  * @file
  30.  * Copy/blit pixel rect between surfaces
  31.  *  
  32.  * @author Brian Paul
  33.  */
  34.  
  35.  
  36. #include "pipe/p_context.h"
  37. #include "util/u_debug.h"
  38. #include "pipe/p_defines.h"
  39. #include "util/u_inlines.h"
  40. #include "pipe/p_shader_tokens.h"
  41. #include "pipe/p_state.h"
  42.  
  43. #include "util/u_blit.h"
  44. #include "util/u_draw_quad.h"
  45. #include "util/u_format.h"
  46. #include "util/u_math.h"
  47. #include "util/u_memory.h"
  48. #include "util/u_sampler.h"
  49. #include "util/u_simple_shaders.h"
  50.  
  51. #include "cso_cache/cso_context.h"
  52.  
  53.  
  54. struct blit_state
  55. {
  56.    struct pipe_context *pipe;
  57.    struct cso_context *cso;
  58.  
  59.    struct pipe_blend_state blend_write_color, blend_keep_color;
  60.    struct pipe_depth_stencil_alpha_state dsa_keep_depthstencil;
  61.    struct pipe_depth_stencil_alpha_state dsa_write_depthstencil;
  62.    struct pipe_depth_stencil_alpha_state dsa_write_depth;
  63.    struct pipe_depth_stencil_alpha_state dsa_write_stencil;
  64.    struct pipe_rasterizer_state rasterizer;
  65.    struct pipe_sampler_state sampler;
  66.    struct pipe_viewport_state viewport;
  67.    struct pipe_vertex_element velem[2];
  68.    enum pipe_texture_target internal_target;
  69.  
  70.    void *vs;
  71.    void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1];
  72.    void *fs_depthstencil[PIPE_MAX_TEXTURE_TYPES];
  73.    void *fs_depth[PIPE_MAX_TEXTURE_TYPES];
  74.    void *fs_stencil[PIPE_MAX_TEXTURE_TYPES];
  75.  
  76.    struct pipe_resource *vbuf;  /**< quad vertices */
  77.    unsigned vbuf_slot;
  78.  
  79.    float vertices[4][2][4];   /**< vertex/texcoords for quad */
  80.  
  81.    boolean has_stencil_export;
  82. };
  83.  
  84.  
  85. /**
  86.  * Create state object for blit.
  87.  * Intended to be created once and re-used for many blit() calls.
  88.  */
  89. struct blit_state *
  90. util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
  91. {
  92.    struct blit_state *ctx;
  93.    uint i;
  94.  
  95.    ctx = CALLOC_STRUCT(blit_state);
  96.    if (!ctx)
  97.       return NULL;
  98.  
  99.    ctx->pipe = pipe;
  100.    ctx->cso = cso;
  101.  
  102.    /* disabled blending/masking */
  103.    ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA;
  104.  
  105.    /* depth stencil states */
  106.    ctx->dsa_write_depth.depth.enabled = 1;
  107.    ctx->dsa_write_depth.depth.writemask = 1;
  108.    ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS;
  109.    ctx->dsa_write_stencil.stencil[0].enabled = 1;
  110.    ctx->dsa_write_stencil.stencil[0].func = PIPE_FUNC_ALWAYS;
  111.    ctx->dsa_write_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
  112.    ctx->dsa_write_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
  113.    ctx->dsa_write_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
  114.    ctx->dsa_write_stencil.stencil[0].valuemask = 0xff;
  115.    ctx->dsa_write_stencil.stencil[0].writemask = 0xff;
  116.    ctx->dsa_write_depthstencil.depth = ctx->dsa_write_depth.depth;
  117.    ctx->dsa_write_depthstencil.stencil[0] = ctx->dsa_write_stencil.stencil[0];
  118.  
  119.    /* rasterizer */
  120.    ctx->rasterizer.cull_face = PIPE_FACE_NONE;
  121.    ctx->rasterizer.half_pixel_center = 1;
  122.    ctx->rasterizer.bottom_edge_rule = 1;
  123.    ctx->rasterizer.depth_clip = 1;
  124.  
  125.    /* samplers */
  126.    ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  127.    ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  128.    ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  129.    ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
  130.    ctx->sampler.min_img_filter = 0; /* set later */
  131.    ctx->sampler.mag_img_filter = 0; /* set later */
  132.  
  133.    /* vertex elements state */
  134.    for (i = 0; i < 2; i++) {
  135.       ctx->velem[i].src_offset = i * 4 * sizeof(float);
  136.       ctx->velem[i].instance_divisor = 0;
  137.       ctx->velem[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso);
  138.       ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
  139.    }
  140.  
  141.    ctx->vbuf = NULL;
  142.  
  143.    /* init vertex data that doesn't change */
  144.    for (i = 0; i < 4; i++) {
  145.       ctx->vertices[i][0][3] = 1.0f; /* w */
  146.       ctx->vertices[i][1][2] = 0.0f; /* r */
  147.       ctx->vertices[i][1][3] = 1.0f; /* q */
  148.    }
  149.  
  150.    if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
  151.       ctx->internal_target = PIPE_TEXTURE_2D;
  152.    else
  153.       ctx->internal_target = PIPE_TEXTURE_RECT;
  154.  
  155.    ctx->has_stencil_export =
  156.       pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
  157.  
  158.    return ctx;
  159. }
  160.  
  161.  
  162. /**
  163.  * Destroy a blit context
  164.  */
  165. void
  166. util_destroy_blit(struct blit_state *ctx)
  167. {
  168.    struct pipe_context *pipe = ctx->pipe;
  169.    unsigned i, j;
  170.  
  171.    if (ctx->vs)
  172.       pipe->delete_vs_state(pipe, ctx->vs);
  173.  
  174.    for (i = 0; i < Elements(ctx->fs); i++) {
  175.       for (j = 0; j < Elements(ctx->fs[i]); j++) {
  176.          if (ctx->fs[i][j])
  177.             pipe->delete_fs_state(pipe, ctx->fs[i][j]);
  178.       }
  179.    }
  180.  
  181.    for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
  182.       if (ctx->fs_depthstencil[i]) {
  183.          pipe->delete_fs_state(pipe, ctx->fs_depthstencil[i]);
  184.       }
  185.       if (ctx->fs_depth[i]) {
  186.          pipe->delete_fs_state(pipe, ctx->fs_depth[i]);
  187.       }
  188.       if (ctx->fs_stencil[i]) {
  189.          pipe->delete_fs_state(pipe, ctx->fs_stencil[i]);
  190.       }
  191.    }
  192.  
  193.    pipe_resource_reference(&ctx->vbuf, NULL);
  194.  
  195.    FREE(ctx);
  196. }
  197.  
  198.  
  199. /**
  200.  * Helper function to set the fragment shaders.
  201.  */
  202. static INLINE void
  203. set_fragment_shader(struct blit_state *ctx, uint writemask,
  204.                     enum pipe_texture_target pipe_tex)
  205. {
  206.    if (!ctx->fs[pipe_tex][writemask]) {
  207.       unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
  208.  
  209.       ctx->fs[pipe_tex][writemask] =
  210.          util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex,
  211.                                                  TGSI_INTERPOLATE_LINEAR,
  212.                                                  writemask);
  213.    }
  214.  
  215.    cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask]);
  216. }
  217.  
  218.  
  219. /**
  220.  * Helper function to set the shader which writes depth and stencil.
  221.  */
  222. static INLINE void
  223. set_depthstencil_fragment_shader(struct blit_state *ctx,
  224.                                  enum pipe_texture_target pipe_tex)
  225. {
  226.    if (!ctx->fs_depthstencil[pipe_tex]) {
  227.       unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
  228.  
  229.       ctx->fs_depthstencil[pipe_tex] =
  230.          util_make_fragment_tex_shader_writedepthstencil(ctx->pipe, tgsi_tex,
  231.                                                   TGSI_INTERPOLATE_LINEAR);
  232.    }
  233.  
  234.    cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depthstencil[pipe_tex]);
  235. }
  236.  
  237.  
  238. /**
  239.  * Helper function to set the shader which writes depth.
  240.  */
  241. static INLINE void
  242. set_depth_fragment_shader(struct blit_state *ctx,
  243.                           enum pipe_texture_target pipe_tex)
  244. {
  245.    if (!ctx->fs_depth[pipe_tex]) {
  246.       unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
  247.  
  248.       ctx->fs_depth[pipe_tex] =
  249.          util_make_fragment_tex_shader_writedepth(ctx->pipe, tgsi_tex,
  250.                                                   TGSI_INTERPOLATE_LINEAR);
  251.    }
  252.  
  253.    cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[pipe_tex]);
  254. }
  255.  
  256.  
  257. /**
  258.  * Helper function to set the shader which writes stencil.
  259.  */
  260. static INLINE void
  261. set_stencil_fragment_shader(struct blit_state *ctx,
  262.                             enum pipe_texture_target pipe_tex)
  263. {
  264.    if (!ctx->fs_stencil[pipe_tex]) {
  265.       unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0);
  266.  
  267.       ctx->fs_stencil[pipe_tex] =
  268.          util_make_fragment_tex_shader_writestencil(ctx->pipe, tgsi_tex,
  269.                                                     TGSI_INTERPOLATE_LINEAR);
  270.    }
  271.  
  272.    cso_set_fragment_shader_handle(ctx->cso, ctx->fs_stencil[pipe_tex]);
  273. }
  274.  
  275.  
  276. /**
  277.  * Helper function to set the vertex shader.
  278.  */
  279. static INLINE void
  280. set_vertex_shader(struct blit_state *ctx)
  281. {
  282.    /* vertex shader - still required to provide the linkage between
  283.     * fragment shader input semantics and vertex_element/buffers.
  284.     */
  285.    if (!ctx->vs) {
  286.       const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
  287.                                       TGSI_SEMANTIC_GENERIC };
  288.       const uint semantic_indexes[] = { 0, 0 };
  289.       ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
  290.                                                     semantic_names,
  291.                                                     semantic_indexes);
  292.    }
  293.  
  294.    cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
  295. }
  296.  
  297.  
  298. /**
  299.  * Get offset of next free slot in vertex buffer for quad vertices.
  300.  */
  301. static unsigned
  302. get_next_slot( struct blit_state *ctx )
  303. {
  304.    const unsigned max_slots = 4096 / sizeof ctx->vertices;
  305.  
  306.    if (ctx->vbuf_slot >= max_slots) {
  307.       pipe_resource_reference(&ctx->vbuf, NULL);
  308.       ctx->vbuf_slot = 0;
  309.    }
  310.  
  311.    if (!ctx->vbuf) {
  312.       ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
  313.                                      PIPE_BIND_VERTEX_BUFFER,
  314.                                      PIPE_USAGE_STREAM,
  315.                                      max_slots * sizeof ctx->vertices);
  316.    }
  317.    
  318.    return ctx->vbuf_slot++ * sizeof ctx->vertices;
  319. }
  320.  
  321.  
  322.  
  323.  
  324. /**
  325.  * Setup vertex data for the textured quad we'll draw.
  326.  * Note: y=0=top
  327.  */
  328. static unsigned
  329. setup_vertex_data_tex(struct blit_state *ctx,
  330.                       float x0, float y0, float x1, float y1,
  331.                       float s0, float t0, float s1, float t1,
  332.                       float z)
  333. {
  334.    unsigned offset;
  335.  
  336.    ctx->vertices[0][0][0] = x0;
  337.    ctx->vertices[0][0][1] = y0;
  338.    ctx->vertices[0][0][2] = z;
  339.    ctx->vertices[0][1][0] = s0; /*s*/
  340.    ctx->vertices[0][1][1] = t0; /*t*/
  341.  
  342.    ctx->vertices[1][0][0] = x1;
  343.    ctx->vertices[1][0][1] = y0;
  344.    ctx->vertices[1][0][2] = z;
  345.    ctx->vertices[1][1][0] = s1; /*s*/
  346.    ctx->vertices[1][1][1] = t0; /*t*/
  347.  
  348.    ctx->vertices[2][0][0] = x1;
  349.    ctx->vertices[2][0][1] = y1;
  350.    ctx->vertices[2][0][2] = z;
  351.    ctx->vertices[2][1][0] = s1;
  352.    ctx->vertices[2][1][1] = t1;
  353.  
  354.    ctx->vertices[3][0][0] = x0;
  355.    ctx->vertices[3][0][1] = y1;
  356.    ctx->vertices[3][0][2] = z;
  357.    ctx->vertices[3][1][0] = s0;
  358.    ctx->vertices[3][1][1] = t1;
  359.  
  360.    offset = get_next_slot( ctx );
  361.  
  362.    if (ctx->vbuf) {
  363.       pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf,
  364.                                   offset, sizeof(ctx->vertices), ctx->vertices);
  365.    }
  366.  
  367.    return offset;
  368. }
  369.  
  370.  
  371. /**
  372.  * \return TRUE if two regions overlap, FALSE otherwise
  373.  */
  374. static boolean
  375. regions_overlap(int srcX0, int srcY0,
  376.                 int srcX1, int srcY1,
  377.                 int dstX0, int dstY0,
  378.                 int dstX1, int dstY1)
  379. {
  380.    if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1))
  381.       return FALSE; /* src completely left of dst */
  382.  
  383.    if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1))
  384.       return FALSE; /* dst completely left of src */
  385.  
  386.    if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1))
  387.       return FALSE; /* src completely above dst */
  388.  
  389.    if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1))
  390.       return FALSE; /* dst completely above src */
  391.  
  392.    return TRUE; /* some overlap */
  393. }
  394.  
  395.  
  396. /**
  397.  * Can we blit from src format to dest format with a simple copy?
  398.  */
  399. static boolean
  400. formats_compatible(enum pipe_format src_format,
  401.                    enum pipe_format dst_format)
  402. {
  403.    if (src_format == dst_format) {
  404.       return TRUE;
  405.    }
  406.    else {
  407.       const struct util_format_description *src_desc =
  408.          util_format_description(src_format);
  409.       const struct util_format_description *dst_desc =
  410.          util_format_description(dst_format);
  411.       return util_is_format_compatible(src_desc, dst_desc);
  412.    }
  413. }
  414.  
  415.  
  416. /**
  417.  * Copy pixel block from src surface to dst surface.
  418.  * Overlapping regions are acceptable.
  419.  * Flipping and stretching are supported.
  420.  * \param filter  one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR
  421.  * \param writemask  controls which channels in the dest surface are sourced
  422.  *                   from the src surface.  Disabled channels are sourced
  423.  *                   from (0,0,0,1).
  424.  */
  425. void
  426. util_blit_pixels(struct blit_state *ctx,
  427.                  struct pipe_resource *src_tex,
  428.                  unsigned src_level,
  429.                  int srcX0, int srcY0,
  430.                  int srcX1, int srcY1,
  431.                  int srcZ0,
  432.                  struct pipe_surface *dst,
  433.                  int dstX0, int dstY0,
  434.                  int dstX1, int dstY1,
  435.                  float z, uint filter,
  436.                  uint writemask, uint zs_writemask)
  437. {
  438.    struct pipe_context *pipe = ctx->pipe;
  439.    struct pipe_screen *screen = pipe->screen;
  440.    enum pipe_format src_format, dst_format;
  441.    struct pipe_sampler_view *sampler_view = NULL;
  442.    struct pipe_sampler_view sv_templ;
  443.    struct pipe_surface *dst_surface;
  444.    struct pipe_framebuffer_state fb;
  445.    const int srcW = abs(srcX1 - srcX0);
  446.    const int srcH = abs(srcY1 - srcY0);
  447.    unsigned offset;
  448.    boolean overlap;
  449.    float s0, t0, s1, t1;
  450.    boolean normalized;
  451.    boolean is_stencil, is_depth, blit_depth, blit_stencil;
  452.    const struct util_format_description *src_desc =
  453.          util_format_description(src_tex->format);
  454.  
  455.    assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
  456.           filter == PIPE_TEX_MIPFILTER_LINEAR);
  457.  
  458.    assert(src_level <= src_tex->last_level);
  459.  
  460.    /* do the regions overlap? */
  461.    overlap = src_tex == dst->texture &&
  462.              dst->u.tex.level == src_level &&
  463.              dst->u.tex.first_layer == srcZ0 &&
  464.       regions_overlap(srcX0, srcY0, srcX1, srcY1,
  465.                       dstX0, dstY0, dstX1, dstY1);
  466.  
  467.    src_format = util_format_linear(src_tex->format);
  468.    dst_format = util_format_linear(dst->texture->format);
  469.  
  470.    /* See whether we will blit depth or stencil. */
  471.    is_depth = util_format_has_depth(src_desc);
  472.    is_stencil = util_format_has_stencil(src_desc);
  473.  
  474.    blit_depth = is_depth && (zs_writemask & BLIT_WRITEMASK_Z);
  475.    blit_stencil = is_stencil && (zs_writemask & BLIT_WRITEMASK_STENCIL);
  476.  
  477.    assert((writemask && !zs_writemask && !is_depth && !is_stencil) ||
  478.           (!writemask && (blit_depth || blit_stencil)));
  479.  
  480.    /*
  481.     * Check for simple case:  no format conversion, no flipping, no stretching,
  482.     * no overlapping, same number of samples.
  483.     * Filter mode should not matter since there's no stretching.
  484.     */
  485.    if (formats_compatible(src_format, dst_format) &&
  486.        src_tex->nr_samples == dst->texture->nr_samples &&
  487.        is_stencil == blit_stencil &&
  488.        is_depth == blit_depth &&
  489.        srcX0 < srcX1 &&
  490.        dstX0 < dstX1 &&
  491.        srcY0 < srcY1 &&
  492.        dstY0 < dstY1 &&
  493.        (dstX1 - dstX0) == (srcX1 - srcX0) &&
  494.        (dstY1 - dstY0) == (srcY1 - srcY0) &&
  495.        !overlap) {
  496.       struct pipe_box src_box;
  497.       src_box.x = srcX0;
  498.       src_box.y = srcY0;
  499.       src_box.z = srcZ0;
  500.       src_box.width = srcW;
  501.       src_box.height = srcH;
  502.       src_box.depth = 1;
  503.       pipe->resource_copy_region(pipe,
  504.                                  dst->texture, dst->u.tex.level,
  505.                                  dstX0, dstY0, dst->u.tex.first_layer,/* dest */
  506.                                  src_tex, src_level,
  507.                                  &src_box);
  508.       return;
  509.    }
  510.  
  511.    /* XXX Reading multisample textures is unimplemented. */
  512.    assert(src_tex->nr_samples <= 1);
  513.    if (src_tex->nr_samples > 1) {
  514.       return;
  515.    }
  516.  
  517.    /* It's a mistake to call this function with a stencil format and
  518.     * without shader stencil export. We don't do software fallbacks here.
  519.     * Ignore stencil and only copy depth.
  520.     */
  521.    if (blit_stencil && !ctx->has_stencil_export) {
  522.       blit_stencil = FALSE;
  523.  
  524.       if (!blit_depth)
  525.          return;
  526.    }
  527.  
  528.    if (dst_format == dst->format) {
  529.       dst_surface = dst;
  530.    } else {
  531.       struct pipe_surface templ = *dst;
  532.       templ.format = dst_format;
  533.       dst_surface = pipe->create_surface(pipe, dst->texture, &templ);
  534.    }
  535.  
  536.    /* Create a temporary texture when src and dest alias.
  537.     */
  538.    if (src_tex == dst_surface->texture &&
  539.        dst_surface->u.tex.level == src_level &&
  540.        dst_surface->u.tex.first_layer == srcZ0) {
  541.       /* Make a temporary texture which contains a copy of the source pixels.
  542.        * Then we'll sample from the temporary texture.
  543.        */
  544.       struct pipe_resource texTemp;
  545.       struct pipe_resource *tex;
  546.       struct pipe_sampler_view sv_templ;
  547.       struct pipe_box src_box;
  548.       const int srcLeft = MIN2(srcX0, srcX1);
  549.       const int srcTop = MIN2(srcY0, srcY1);
  550.  
  551.       if (srcLeft != srcX0) {
  552.          /* left-right flip */
  553.          int tmp = dstX0;
  554.          dstX0 = dstX1;
  555.          dstX1 = tmp;
  556.       }
  557.  
  558.       if (srcTop != srcY0) {
  559.          /* up-down flip */
  560.          int tmp = dstY0;
  561.          dstY0 = dstY1;
  562.          dstY1 = tmp;
  563.       }
  564.  
  565.       /* create temp texture */
  566.       memset(&texTemp, 0, sizeof(texTemp));
  567.       texTemp.target = ctx->internal_target;
  568.       texTemp.format = src_format;
  569.       texTemp.last_level = 0;
  570.       texTemp.width0 = srcW;
  571.       texTemp.height0 = srcH;
  572.       texTemp.depth0 = 1;
  573.       texTemp.array_size = 1;
  574.       texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
  575.  
  576.       tex = screen->resource_create(screen, &texTemp);
  577.       if (!tex)
  578.          return;
  579.  
  580.       src_box.x = srcLeft;
  581.       src_box.y = srcTop;
  582.       src_box.z = srcZ0;
  583.       src_box.width = srcW;
  584.       src_box.height = srcH;
  585.       src_box.depth = 1;
  586.       /* load temp texture */
  587.       pipe->resource_copy_region(pipe,
  588.                                  tex, 0, 0, 0, 0,  /* dest */
  589.                                  src_tex, src_level, &src_box);
  590.  
  591.       normalized = tex->target != PIPE_TEXTURE_RECT;
  592.       if(normalized) {
  593.          s0 = 0.0f;
  594.          s1 = 1.0f;
  595.          t0 = 0.0f;
  596.          t1 = 1.0f;
  597.       }
  598.       else {
  599.          s0 = 0;
  600.          s1 = srcW;
  601.          t0 = 0;
  602.          t1 = srcH;
  603.       }
  604.  
  605.       u_sampler_view_default_template(&sv_templ, tex, tex->format);
  606.       if (!blit_depth && blit_stencil) {
  607.          /* set a stencil-only format, e.g. Z24S8 --> X24S8 */
  608.          sv_templ.format = util_format_stencil_only(tex->format);
  609.          assert(sv_templ.format != PIPE_FORMAT_NONE);
  610.       }
  611.       sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ);
  612.  
  613.       if (!sampler_view) {
  614.          pipe_resource_reference(&tex, NULL);
  615.          return;
  616.       }
  617.       pipe_resource_reference(&tex, NULL);
  618.    }
  619.    else {
  620.       /* Directly sample from the source resource/texture */
  621.       u_sampler_view_default_template(&sv_templ, src_tex, src_format);
  622.       if (!blit_depth && blit_stencil) {
  623.          /* set a stencil-only format, e.g. Z24S8 --> X24S8 */
  624.          sv_templ.format = util_format_stencil_only(src_format);
  625.          assert(sv_templ.format != PIPE_FORMAT_NONE);
  626.       }
  627.       sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ);
  628.  
  629.       if (!sampler_view) {
  630.          return;
  631.       }
  632.  
  633.       s0 = srcX0;
  634.       s1 = srcX1;
  635.       t0 = srcY0;
  636.       t1 = srcY1;
  637.       normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT;
  638.       if(normalized)
  639.       {
  640.          s0 /= (float)(u_minify(sampler_view->texture->width0, src_level));
  641.          s1 /= (float)(u_minify(sampler_view->texture->width0, src_level));
  642.          t0 /= (float)(u_minify(sampler_view->texture->height0, src_level));
  643.          t1 /= (float)(u_minify(sampler_view->texture->height0, src_level));
  644.       }
  645.    }
  646.  
  647.    assert(screen->is_format_supported(screen, sampler_view->format,
  648.                      ctx->internal_target, sampler_view->texture->nr_samples,
  649.                      PIPE_BIND_SAMPLER_VIEW));
  650.    assert(screen->is_format_supported(screen, dst_format, ctx->internal_target,
  651.                      dst_surface->texture->nr_samples,
  652.                      is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL :
  653.                                               PIPE_BIND_RENDER_TARGET));
  654.  
  655.    /* save state (restored below) */
  656.    cso_save_blend(ctx->cso);
  657.    cso_save_depth_stencil_alpha(ctx->cso);
  658.    cso_save_rasterizer(ctx->cso);
  659.    cso_save_sample_mask(ctx->cso);
  660.    cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
  661.    cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
  662.    cso_save_stream_outputs(ctx->cso);
  663.    cso_save_viewport(ctx->cso);
  664.    cso_save_framebuffer(ctx->cso);
  665.    cso_save_fragment_shader(ctx->cso);
  666.    cso_save_vertex_shader(ctx->cso);
  667.    cso_save_geometry_shader(ctx->cso);
  668.    cso_save_vertex_elements(ctx->cso);
  669.    cso_save_aux_vertex_buffer_slot(ctx->cso);
  670.    cso_save_render_condition(ctx->cso);
  671.  
  672.    /* set misc state we care about */
  673.    if (writemask)
  674.       cso_set_blend(ctx->cso, &ctx->blend_write_color);
  675.    else
  676.       cso_set_blend(ctx->cso, &ctx->blend_keep_color);
  677.  
  678.    cso_set_sample_mask(ctx->cso, ~0);
  679.    cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
  680.    cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
  681.    cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
  682.    cso_set_render_condition(ctx->cso, NULL, FALSE, 0);
  683.  
  684.    /* default sampler state */
  685.    ctx->sampler.normalized_coords = normalized;
  686.    ctx->sampler.min_img_filter = filter;
  687.    ctx->sampler.mag_img_filter = filter;
  688.    ctx->sampler.min_lod = src_level;
  689.    ctx->sampler.max_lod = src_level;
  690.  
  691.    /* Depth stencil state, fragment shader and sampler setup depending on what
  692.     * we blit.
  693.     */
  694.    if (blit_depth && blit_stencil) {
  695.       cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
  696.       /* don't filter stencil */
  697.       ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
  698.       ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
  699.       cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &ctx->sampler);
  700.  
  701.       cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depthstencil);
  702.       set_depthstencil_fragment_shader(ctx, sampler_view->texture->target);
  703.    }
  704.    else if (blit_depth) {
  705.       cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
  706.       cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depth);
  707.       set_depth_fragment_shader(ctx, sampler_view->texture->target);
  708.    }
  709.    else if (blit_stencil) {
  710.       /* don't filter stencil */
  711.       ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
  712.       ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
  713.       cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
  714.  
  715.       cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_stencil);
  716.       set_stencil_fragment_shader(ctx, sampler_view->texture->target);
  717.    }
  718.    else { /* color */
  719.       cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
  720.       cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil);
  721.       set_fragment_shader(ctx, writemask, sampler_view->texture->target);
  722.    }
  723.    cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT);
  724.  
  725.    /* textures */
  726.    if (blit_depth && blit_stencil) {
  727.       /* Setup two samplers, one for depth and the other one for stencil. */
  728.       struct pipe_sampler_view templ;
  729.       struct pipe_sampler_view *views[2];
  730.  
  731.       templ = *sampler_view;
  732.       templ.format = util_format_stencil_only(templ.format);
  733.       assert(templ.format != PIPE_FORMAT_NONE);
  734.  
  735.       views[0] = sampler_view;
  736.       views[1] = pipe->create_sampler_view(pipe, views[0]->texture, &templ);
  737.       cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 2, views);
  738.  
  739.       pipe_sampler_view_reference(&views[1], NULL);
  740.    }
  741.    else {
  742.       cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &sampler_view);
  743.    }
  744.  
  745.    /* viewport */
  746.    ctx->viewport.scale[0] = 0.5f * dst_surface->width;
  747.    ctx->viewport.scale[1] = 0.5f * dst_surface->height;
  748.    ctx->viewport.scale[2] = 0.5f;
  749.    ctx->viewport.scale[3] = 1.0f;
  750.    ctx->viewport.translate[0] = 0.5f * dst_surface->width;
  751.    ctx->viewport.translate[1] = 0.5f * dst_surface->height;
  752.    ctx->viewport.translate[2] = 0.5f;
  753.    ctx->viewport.translate[3] = 0.0f;
  754.    cso_set_viewport(ctx->cso, &ctx->viewport);
  755.  
  756.    set_vertex_shader(ctx);
  757.    cso_set_geometry_shader_handle(ctx->cso, NULL);
  758.  
  759.    /* drawing dest */
  760.    memset(&fb, 0, sizeof(fb));
  761.    fb.width = dst_surface->width;
  762.    fb.height = dst_surface->height;
  763.    if (blit_depth || blit_stencil) {
  764.       fb.zsbuf = dst_surface;
  765.    } else {
  766.       fb.nr_cbufs = 1;
  767.       fb.cbufs[0] = dst_surface;
  768.    }
  769.    cso_set_framebuffer(ctx->cso, &fb);
  770.  
  771.    /* draw quad */
  772.    offset = setup_vertex_data_tex(ctx,
  773.                                   (float) dstX0 / dst_surface->width * 2.0f - 1.0f,
  774.                                   (float) dstY0 / dst_surface->height * 2.0f - 1.0f,
  775.                                   (float) dstX1 / dst_surface->width * 2.0f - 1.0f,
  776.                                   (float) dstY1 / dst_surface->height * 2.0f - 1.0f,
  777.                                   s0, t0,
  778.                                   s1, t1,
  779.                                   z);
  780.  
  781.    if (ctx->vbuf) {
  782.       util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf,
  783.                               cso_get_aux_vertex_buffer_slot(ctx->cso),
  784.                               offset,
  785.                               PIPE_PRIM_TRIANGLE_FAN,
  786.                               4,  /* verts */
  787.                               2); /* attribs/vert */
  788.    }
  789.  
  790.    /* restore state we changed */
  791.    cso_restore_blend(ctx->cso);
  792.    cso_restore_depth_stencil_alpha(ctx->cso);
  793.    cso_restore_rasterizer(ctx->cso);
  794.    cso_restore_sample_mask(ctx->cso);
  795.    cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
  796.    cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
  797.    cso_restore_viewport(ctx->cso);
  798.    cso_restore_framebuffer(ctx->cso);
  799.    cso_restore_fragment_shader(ctx->cso);
  800.    cso_restore_vertex_shader(ctx->cso);
  801.    cso_restore_geometry_shader(ctx->cso);
  802.    cso_restore_vertex_elements(ctx->cso);
  803.    cso_restore_aux_vertex_buffer_slot(ctx->cso);
  804.    cso_restore_stream_outputs(ctx->cso);
  805.    cso_restore_render_condition(ctx->cso);
  806.  
  807.    pipe_sampler_view_reference(&sampler_view, NULL);
  808.    if (dst_surface != dst)
  809.       pipe_surface_reference(&dst_surface, NULL);
  810. }
  811.  
  812.  
  813. /**
  814.  * Copy pixel block from src texture to dst surface.
  815.  * The sampler view's first_level field indicates the source
  816.  * mipmap level to use.
  817.  * XXX need some control over blitting Z and/or stencil.
  818.  */
  819. void
  820. util_blit_pixels_tex(struct blit_state *ctx,
  821.                      struct pipe_sampler_view *src_sampler_view,
  822.                      int srcX0, int srcY0,
  823.                      int srcX1, int srcY1,
  824.                      struct pipe_surface *dst,
  825.                      int dstX0, int dstY0,
  826.                      int dstX1, int dstY1,
  827.                      float z, uint filter)
  828. {
  829.    boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT;
  830.    struct pipe_framebuffer_state fb;
  831.    float s0, t0, s1, t1;
  832.    unsigned offset;
  833.    struct pipe_resource *tex = src_sampler_view->texture;
  834.  
  835.    assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
  836.           filter == PIPE_TEX_MIPFILTER_LINEAR);
  837.  
  838.    assert(tex);
  839.    assert(tex->width0 != 0);
  840.    assert(tex->height0 != 0);
  841.  
  842.    s0 = srcX0;
  843.    s1 = srcX1;
  844.    t0 = srcY0;
  845.    t1 = srcY1;
  846.  
  847.    if(normalized)
  848.    {
  849.       /* normalize according to the mipmap level's size */
  850.       int level = src_sampler_view->u.tex.first_level;
  851.       float w = (float) u_minify(tex->width0, level);
  852.       float h = (float) u_minify(tex->height0, level);
  853.       s0 /= w;
  854.       s1 /= w;
  855.       t0 /= h;
  856.       t1 /= h;
  857.    }
  858.  
  859.    assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format,
  860.                                                  PIPE_TEXTURE_2D,
  861.                                                  dst->texture->nr_samples,
  862.                                                  PIPE_BIND_RENDER_TARGET));
  863.  
  864.    /* save state (restored below) */
  865.    cso_save_blend(ctx->cso);
  866.    cso_save_depth_stencil_alpha(ctx->cso);
  867.    cso_save_rasterizer(ctx->cso);
  868.    cso_save_sample_mask(ctx->cso);
  869.    cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
  870.    cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
  871.    cso_save_stream_outputs(ctx->cso);
  872.    cso_save_viewport(ctx->cso);
  873.    cso_save_framebuffer(ctx->cso);
  874.    cso_save_fragment_shader(ctx->cso);
  875.    cso_save_vertex_shader(ctx->cso);
  876.    cso_save_geometry_shader(ctx->cso);
  877.    cso_save_vertex_elements(ctx->cso);
  878.    cso_save_aux_vertex_buffer_slot(ctx->cso);
  879.  
  880.    /* set misc state we care about */
  881.    cso_set_blend(ctx->cso, &ctx->blend_write_color);
  882.    cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil);
  883.    cso_set_sample_mask(ctx->cso, ~0);
  884.    cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
  885.    cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
  886.    cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
  887.  
  888.    /* sampler */
  889.    ctx->sampler.normalized_coords = normalized;
  890.    ctx->sampler.min_img_filter = filter;
  891.    ctx->sampler.mag_img_filter = filter;
  892.    cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
  893.    cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT);
  894.  
  895.    /* viewport */
  896.    ctx->viewport.scale[0] = 0.5f * dst->width;
  897.    ctx->viewport.scale[1] = 0.5f * dst->height;
  898.    ctx->viewport.scale[2] = 0.5f;
  899.    ctx->viewport.scale[3] = 1.0f;
  900.    ctx->viewport.translate[0] = 0.5f * dst->width;
  901.    ctx->viewport.translate[1] = 0.5f * dst->height;
  902.    ctx->viewport.translate[2] = 0.5f;
  903.    ctx->viewport.translate[3] = 0.0f;
  904.    cso_set_viewport(ctx->cso, &ctx->viewport);
  905.  
  906.    /* texture */
  907.    cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view);
  908.  
  909.    /* shaders */
  910.    set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW,
  911.                        src_sampler_view->texture->target);
  912.    set_vertex_shader(ctx);
  913.    cso_set_geometry_shader_handle(ctx->cso, NULL);
  914.  
  915.    /* drawing dest */
  916.    memset(&fb, 0, sizeof(fb));
  917.    fb.width = dst->width;
  918.    fb.height = dst->height;
  919.    fb.nr_cbufs = 1;
  920.    fb.cbufs[0] = dst;
  921.    cso_set_framebuffer(ctx->cso, &fb);
  922.  
  923.    /* draw quad */
  924.    offset = setup_vertex_data_tex(ctx,
  925.                                   (float) dstX0 / dst->width * 2.0f - 1.0f,
  926.                                   (float) dstY0 / dst->height * 2.0f - 1.0f,
  927.                                   (float) dstX1 / dst->width * 2.0f - 1.0f,
  928.                                   (float) dstY1 / dst->height * 2.0f - 1.0f,
  929.                                   s0, t0, s1, t1,
  930.                                   z);
  931.  
  932.    util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf,
  933.                            cso_get_aux_vertex_buffer_slot(ctx->cso),
  934.                            offset,
  935.                            PIPE_PRIM_TRIANGLE_FAN,
  936.                            4,  /* verts */
  937.                            2); /* attribs/vert */
  938.  
  939.    /* restore state we changed */
  940.    cso_restore_blend(ctx->cso);
  941.    cso_restore_depth_stencil_alpha(ctx->cso);
  942.    cso_restore_rasterizer(ctx->cso);
  943.    cso_restore_sample_mask(ctx->cso);
  944.    cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
  945.    cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
  946.    cso_restore_viewport(ctx->cso);
  947.    cso_restore_framebuffer(ctx->cso);
  948.    cso_restore_fragment_shader(ctx->cso);
  949.    cso_restore_vertex_shader(ctx->cso);
  950.    cso_restore_geometry_shader(ctx->cso);
  951.    cso_restore_vertex_elements(ctx->cso);
  952.    cso_restore_aux_vertex_buffer_slot(ctx->cso);
  953.    cso_restore_stream_outputs(ctx->cso);
  954. }
  955.