Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2008 Ben Skeggs
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20.  * OTHER DEALINGS IN THE SOFTWARE.
  21.  */
  22.  
  23. #include <stdint.h>
  24.  
  25. #include "pipe/p_defines.h"
  26.  
  27. #include "util/u_inlines.h"
  28. #include "util/u_pack_color.h"
  29. #include "util/u_format.h"
  30. #include "util/u_surface.h"
  31.  
  32. #include "tgsi/tgsi_ureg.h"
  33.  
  34. #include "os/os_thread.h"
  35.  
  36. #include "nv50/nv50_context.h"
  37. #include "nv50/nv50_resource.h"
  38.  
  39. #include "nv50/nv50_defs.xml.h"
  40. #include "nv50/nv50_texture.xml.h"
  41.  
  42. /* these are used in nv50_blit.h */
  43. #define NV50_ENG2D_SUPPORTED_FORMATS 0xff0843e080608409ULL
  44. #define NV50_ENG2D_NOCONVERT_FORMATS 0x0008402000000000ULL
  45. #define NV50_ENG2D_LUMINANCE_FORMATS 0x0008402000000000ULL
  46. #define NV50_ENG2D_INTENSITY_FORMATS 0x0000000000000000ULL
  47. #define NV50_ENG2D_OPERATION_FORMATS 0x060001c000608000ULL
  48.  
  49. #define NOUVEAU_DRIVER 0x50
  50. #include "nv50/nv50_blit.h"
  51.  
  52. static INLINE uint8_t
  53. nv50_2d_format(enum pipe_format format, boolean dst, boolean dst_src_equal)
  54. {
  55.    uint8_t id = nv50_format_table[format].rt;
  56.  
  57.    /* Hardware values for color formats range from 0xc0 to 0xff,
  58.     * but the 2D engine doesn't support all of them.
  59.     */
  60.    if ((id >= 0xc0) && (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))))
  61.       return id;
  62.    assert(dst_src_equal);
  63.  
  64.    switch (util_format_get_blocksize(format)) {
  65.    case 1:
  66.       return NV50_SURFACE_FORMAT_R8_UNORM;
  67.    case 2:
  68.       return NV50_SURFACE_FORMAT_R16_UNORM;
  69.    case 4:
  70.       return NV50_SURFACE_FORMAT_BGRA8_UNORM;
  71.    default:
  72.       return 0;
  73.    }
  74. }
  75.  
  76. static int
  77. nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
  78.                     struct nv50_miptree *mt, unsigned level, unsigned layer,
  79.                     enum pipe_format pformat, boolean dst_src_pformat_equal)
  80. {
  81.    struct nouveau_bo *bo = mt->base.bo;
  82.    uint32_t width, height, depth;
  83.    uint32_t format;
  84.    uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
  85.    uint32_t offset = mt->level[level].offset;
  86.  
  87.    format = nv50_2d_format(pformat, dst, dst_src_pformat_equal);
  88.    if (!format) {
  89.       NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
  90.                   util_format_name(pformat));
  91.       return 1;
  92.    }
  93.  
  94.    width = u_minify(mt->base.base.width0, level) << mt->ms_x;
  95.    height = u_minify(mt->base.base.height0, level) << mt->ms_y;
  96.    depth = u_minify(mt->base.base.depth0, level);
  97.  
  98.    offset = mt->level[level].offset;
  99.    if (!mt->layout_3d) {
  100.       offset += mt->layer_stride * layer;
  101.       depth = 1;
  102.       layer = 0;
  103.    } else
  104.    if (!dst) {
  105.       offset += nv50_mt_zslice_offset(mt, level, layer);
  106.       layer = 0;
  107.    }
  108.  
  109.    if (!nouveau_bo_memtype(bo)) {
  110.       BEGIN_NV04(push, SUBC_2D(mthd), 2);
  111.       PUSH_DATA (push, format);
  112.       PUSH_DATA (push, 1);
  113.       BEGIN_NV04(push, SUBC_2D(mthd + 0x14), 5);
  114.       PUSH_DATA (push, mt->level[level].pitch);
  115.       PUSH_DATA (push, width);
  116.       PUSH_DATA (push, height);
  117.       PUSH_DATAh(push, mt->base.address + offset);
  118.       PUSH_DATA (push, mt->base.address + offset);
  119.    } else {
  120.       BEGIN_NV04(push, SUBC_2D(mthd), 5);
  121.       PUSH_DATA (push, format);
  122.       PUSH_DATA (push, 0);
  123.       PUSH_DATA (push, mt->level[level].tile_mode);
  124.       PUSH_DATA (push, depth);
  125.       PUSH_DATA (push, layer);
  126.       BEGIN_NV04(push, SUBC_2D(mthd + 0x18), 4);
  127.       PUSH_DATA (push, width);
  128.       PUSH_DATA (push, height);
  129.       PUSH_DATAh(push, mt->base.address + offset);
  130.       PUSH_DATA (push, mt->base.address + offset);
  131.    }
  132.  
  133. #if 0
  134.    if (dst) {
  135.       BEGIN_NV04(push, SUBC_2D(NV50_2D_CLIP_X), 4);
  136.       PUSH_DATA (push, 0);
  137.       PUSH_DATA (push, 0);
  138.       PUSH_DATA (push, width);
  139.       PUSH_DATA (push, height);
  140.    }
  141. #endif
  142.    return 0;
  143. }
  144.  
  145. static int
  146. nv50_2d_texture_do_copy(struct nouveau_pushbuf *push,
  147.                         struct nv50_miptree *dst, unsigned dst_level,
  148.                         unsigned dx, unsigned dy, unsigned dz,
  149.                         struct nv50_miptree *src, unsigned src_level,
  150.                         unsigned sx, unsigned sy, unsigned sz,
  151.                         unsigned w, unsigned h)
  152. {
  153.    const enum pipe_format dfmt = dst->base.base.format;
  154.    const enum pipe_format sfmt = src->base.base.format;
  155.    int ret;
  156.    boolean eqfmt = dfmt == sfmt;
  157.  
  158.    if (!PUSH_SPACE(push, 2 * 16 + 32))
  159.       return PIPE_ERROR;
  160.  
  161.    ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz, dfmt, eqfmt);
  162.    if (ret)
  163.       return ret;
  164.  
  165.    ret = nv50_2d_texture_set(push, 0, src, src_level, sz, sfmt, eqfmt);
  166.    if (ret)
  167.       return ret;
  168.  
  169.    BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
  170.    PUSH_DATA (push, NV50_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE);
  171.    BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4);
  172.    PUSH_DATA (push, dx << dst->ms_x);
  173.    PUSH_DATA (push, dy << dst->ms_y);
  174.    PUSH_DATA (push, w << dst->ms_x);
  175.    PUSH_DATA (push, h << dst->ms_y);
  176.    BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
  177.    PUSH_DATA (push, 0);
  178.    PUSH_DATA (push, 1);
  179.    PUSH_DATA (push, 0);
  180.    PUSH_DATA (push, 1);
  181.    BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4);
  182.    PUSH_DATA (push, 0);
  183.    PUSH_DATA (push, sx << src->ms_x);
  184.    PUSH_DATA (push, 0);
  185.    PUSH_DATA (push, sy << src->ms_y);
  186.  
  187.    return 0;
  188. }
  189.  
  190. static void
  191. nv50_resource_copy_region(struct pipe_context *pipe,
  192.                           struct pipe_resource *dst, unsigned dst_level,
  193.                           unsigned dstx, unsigned dsty, unsigned dstz,
  194.                           struct pipe_resource *src, unsigned src_level,
  195.                           const struct pipe_box *src_box)
  196. {
  197.    struct nv50_context *nv50 = nv50_context(pipe);
  198.    int ret;
  199.    boolean m2mf;
  200.    unsigned dst_layer = dstz, src_layer = src_box->z;
  201.  
  202.    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
  203.       nouveau_copy_buffer(&nv50->base,
  204.                           nv04_resource(dst), dstx,
  205.                           nv04_resource(src), src_box->x, src_box->width);
  206.       return;
  207.    }
  208.  
  209.    /* 0 and 1 are equal, only supporting 0/1, 2, 4 and 8 */
  210.    assert((src->nr_samples | 1) == (dst->nr_samples | 1));
  211.  
  212.    m2mf = (src->format == dst->format) ||
  213.       (util_format_get_blocksizebits(src->format) ==
  214.        util_format_get_blocksizebits(dst->format));
  215.  
  216.    nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
  217.  
  218.    if (m2mf) {
  219.       struct nv50_m2mf_rect drect, srect;
  220.       unsigned i;
  221.       unsigned nx = util_format_get_nblocksx(src->format, src_box->width);
  222.       unsigned ny = util_format_get_nblocksy(src->format, src_box->height);
  223.  
  224.       nv50_m2mf_rect_setup(&drect, dst, dst_level, dstx, dsty, dstz);
  225.       nv50_m2mf_rect_setup(&srect, src, src_level,
  226.                            src_box->x, src_box->y, src_box->z);
  227.  
  228.       for (i = 0; i < src_box->depth; ++i) {
  229.          nv50_m2mf_transfer_rect(nv50, &drect, &srect, nx, ny);
  230.  
  231.          if (nv50_miptree(dst)->layout_3d)
  232.             drect.z++;
  233.          else
  234.             drect.base += nv50_miptree(dst)->layer_stride;
  235.  
  236.          if (nv50_miptree(src)->layout_3d)
  237.             srect.z++;
  238.          else
  239.             srect.base += nv50_miptree(src)->layer_stride;
  240.       }
  241.       return;
  242.    }
  243.  
  244.    assert((src->format == dst->format) ||
  245.           (nv50_2d_src_format_faithful(src->format) &&
  246.            nv50_2d_dst_format_faithful(dst->format)));
  247.  
  248.    BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD);
  249.    BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR);
  250.    nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
  251.    nouveau_pushbuf_validate(nv50->base.pushbuf);
  252.  
  253.    for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
  254.       ret = nv50_2d_texture_do_copy(nv50->base.pushbuf,
  255.                                     nv50_miptree(dst), dst_level,
  256.                                     dstx, dsty, dst_layer,
  257.                                     nv50_miptree(src), src_level,
  258.                                     src_box->x, src_box->y, src_layer,
  259.                                     src_box->width, src_box->height);
  260.       if (ret)
  261.          break;
  262.    }
  263.    nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
  264. }
  265.  
  266. static void
  267. nv50_clear_render_target(struct pipe_context *pipe,
  268.                          struct pipe_surface *dst,
  269.                          const union pipe_color_union *color,
  270.                          unsigned dstx, unsigned dsty,
  271.                          unsigned width, unsigned height)
  272. {
  273.    struct nv50_context *nv50 = nv50_context(pipe);
  274.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  275.    struct nv50_miptree *mt = nv50_miptree(dst->texture);
  276.    struct nv50_surface *sf = nv50_surface(dst);
  277.    struct nouveau_bo *bo = mt->base.bo;
  278.    unsigned z;
  279.  
  280.    BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
  281.    PUSH_DATAf(push, color->f[0]);
  282.    PUSH_DATAf(push, color->f[1]);
  283.    PUSH_DATAf(push, color->f[2]);
  284.    PUSH_DATAf(push, color->f[3]);
  285.  
  286.    if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
  287.       return;
  288.  
  289.    PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
  290.  
  291.    BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
  292.    PUSH_DATA (push, ( width << 16) | dstx);
  293.    PUSH_DATA (push, (height << 16) | dsty);
  294.    BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
  295.    PUSH_DATA (push, 8192 << 16);
  296.    PUSH_DATA (push, 8192 << 16);
  297.    nv50->scissors_dirty |= 1;
  298.  
  299.    BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
  300.    PUSH_DATA (push, 1);
  301.    BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
  302.    PUSH_DATAh(push, mt->base.address + sf->offset);
  303.    PUSH_DATA (push, mt->base.address + sf->offset);
  304.    PUSH_DATA (push, nv50_format_table[dst->format].rt);
  305.    PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
  306.    PUSH_DATA (push, mt->layer_stride >> 2);
  307.    BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);
  308.    if (nouveau_bo_memtype(bo))
  309.       PUSH_DATA(push, sf->width);
  310.    else
  311.       PUSH_DATA(push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
  312.    PUSH_DATA (push, sf->height);
  313.    BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
  314.    if (mt->layout_3d)
  315.       PUSH_DATA(push, NV50_3D_RT_ARRAY_MODE_MODE_3D | 512);
  316.    else
  317.       PUSH_DATA(push, 512);
  318.  
  319.    if (!nouveau_bo_memtype(bo)) {
  320.       BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
  321.       PUSH_DATA (push, 0);
  322.    }
  323.  
  324.    /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
  325.  
  326.    BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
  327.    PUSH_DATA (push, (width << 16) | dstx);
  328.    PUSH_DATA (push, (height << 16) | dsty);
  329.  
  330.    BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), sf->depth);
  331.    for (z = 0; z < sf->depth; ++z) {
  332.       PUSH_DATA (push, 0x3c |
  333.                  (z << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  334.    }
  335.  
  336.    nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
  337. }
  338.  
  339. static void
  340. nv50_clear_depth_stencil(struct pipe_context *pipe,
  341.                          struct pipe_surface *dst,
  342.                          unsigned clear_flags,
  343.                          double depth,
  344.                          unsigned stencil,
  345.                          unsigned dstx, unsigned dsty,
  346.                          unsigned width, unsigned height)
  347. {
  348.    struct nv50_context *nv50 = nv50_context(pipe);
  349.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  350.    struct nv50_miptree *mt = nv50_miptree(dst->texture);
  351.    struct nv50_surface *sf = nv50_surface(dst);
  352.    struct nouveau_bo *bo = mt->base.bo;
  353.    uint32_t mode = 0;
  354.    unsigned z;
  355.  
  356.    assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
  357.  
  358.    if (clear_flags & PIPE_CLEAR_DEPTH) {
  359.       BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
  360.       PUSH_DATAf(push, depth);
  361.       mode |= NV50_3D_CLEAR_BUFFERS_Z;
  362.    }
  363.  
  364.    if (clear_flags & PIPE_CLEAR_STENCIL) {
  365.       BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
  366.       PUSH_DATA (push, stencil & 0xff);
  367.       mode |= NV50_3D_CLEAR_BUFFERS_S;
  368.    }
  369.  
  370.    if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
  371.       return;
  372.  
  373.    PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
  374.  
  375.    BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
  376.    PUSH_DATA (push, ( width << 16) | dstx);
  377.    PUSH_DATA (push, (height << 16) | dsty);
  378.    BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
  379.    PUSH_DATA (push, 8192 << 16);
  380.    PUSH_DATA (push, 8192 << 16);
  381.    nv50->scissors_dirty |= 1;
  382.  
  383.    BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
  384.    PUSH_DATAh(push, mt->base.address + sf->offset);
  385.    PUSH_DATA (push, mt->base.address + sf->offset);
  386.    PUSH_DATA (push, nv50_format_table[dst->format].rt);
  387.    PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
  388.    PUSH_DATA (push, mt->layer_stride >> 2);
  389.    BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
  390.    PUSH_DATA (push, 1);
  391.    BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
  392.    PUSH_DATA (push, sf->width);
  393.    PUSH_DATA (push, sf->height);
  394.    PUSH_DATA (push, (1 << 16) | 1);
  395.  
  396.    BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
  397.    PUSH_DATA (push, 512);
  398.  
  399.    BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
  400.    PUSH_DATA (push, (width << 16) | dstx);
  401.    PUSH_DATA (push, (height << 16) | dsty);
  402.  
  403.    BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), sf->depth);
  404.    for (z = 0; z < sf->depth; ++z) {
  405.       PUSH_DATA (push, mode |
  406.                  (z << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  407.    }
  408.  
  409.    nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
  410. }
  411.  
  412. void
  413. nv50_clear(struct pipe_context *pipe, unsigned buffers,
  414.            const union pipe_color_union *color,
  415.            double depth, unsigned stencil)
  416. {
  417.    struct nv50_context *nv50 = nv50_context(pipe);
  418.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  419.    struct pipe_framebuffer_state *fb = &nv50->framebuffer;
  420.    unsigned i, j, k;
  421.    uint32_t mode = 0;
  422.  
  423.    /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
  424.    if (!nv50_state_validate(nv50, NV50_NEW_FRAMEBUFFER, 9 + (fb->nr_cbufs * 2)))
  425.       return;
  426.  
  427.    /* We have to clear ALL of the layers, not up to the min number of layers
  428.     * of any attachment. */
  429.    BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
  430.    PUSH_DATA (push, (nv50->rt_array_mode & NV50_3D_RT_ARRAY_MODE_MODE_3D) | 512);
  431.  
  432.    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
  433.       BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
  434.       PUSH_DATAf(push, color->f[0]);
  435.       PUSH_DATAf(push, color->f[1]);
  436.       PUSH_DATAf(push, color->f[2]);
  437.       PUSH_DATAf(push, color->f[3]);
  438.       if (buffers & PIPE_CLEAR_COLOR0)
  439.          mode =
  440.             NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G |
  441.             NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A;
  442.    }
  443.  
  444.    if (buffers & PIPE_CLEAR_DEPTH) {
  445.       BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
  446.       PUSH_DATA (push, fui(depth));
  447.       mode |= NV50_3D_CLEAR_BUFFERS_Z;
  448.    }
  449.  
  450.    if (buffers & PIPE_CLEAR_STENCIL) {
  451.       BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
  452.       PUSH_DATA (push, stencil & 0xff);
  453.       mode |= NV50_3D_CLEAR_BUFFERS_S;
  454.    }
  455.  
  456.    if (mode) {
  457.       int zs_layers = 0, color0_layers = 0;
  458.       if (fb->cbufs[0] && (mode & 0x3c))
  459.          color0_layers = fb->cbufs[0]->u.tex.last_layer -
  460.             fb->cbufs[0]->u.tex.first_layer + 1;
  461.       if (fb->zsbuf && (mode & ~0x3c))
  462.          zs_layers = fb->zsbuf->u.tex.last_layer -
  463.             fb->zsbuf->u.tex.first_layer + 1;
  464.  
  465.       for (j = 0; j < MIN2(zs_layers, color0_layers); j++) {
  466.          BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
  467.          PUSH_DATA(push, mode | (j << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  468.       }
  469.       for (k = j; k < zs_layers; k++) {
  470.          BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
  471.          PUSH_DATA(push, (mode & ~0x3c) | (k << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  472.       }
  473.       for (k = j; k < color0_layers; k++) {
  474.          BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
  475.          PUSH_DATA(push, (mode & 0x3c) | (k << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  476.       }
  477.    }
  478.  
  479.    for (i = 1; i < fb->nr_cbufs; i++) {
  480.       struct pipe_surface *sf = fb->cbufs[i];
  481.       if (!sf || !(buffers & (PIPE_CLEAR_COLOR0 << i)))
  482.          continue;
  483.       for (j = 0; j <= sf->u.tex.last_layer - sf->u.tex.first_layer; j++) {
  484.          BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
  485.          PUSH_DATA (push, (i << 6) | 0x3c |
  486.                     (j << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  487.       }
  488.    }
  489.  
  490.    /* restore the array mode */
  491.    BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
  492.    PUSH_DATA (push, nv50->rt_array_mode);
  493. }
  494.  
  495. static void
  496. nv50_clear_buffer(struct pipe_context *pipe,
  497.                   struct pipe_resource *res,
  498.                   unsigned offset, unsigned size,
  499.                   const void *data, int data_size)
  500. {
  501.    struct nv50_context *nv50 = nv50_context(pipe);
  502.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  503.    struct nv04_resource *buf = (struct nv04_resource *)res;
  504.    union pipe_color_union color;
  505.    enum pipe_format dst_fmt;
  506.    unsigned width, height, elements;
  507.  
  508.    assert(res->target == PIPE_BUFFER);
  509.    assert(nouveau_bo_memtype(buf->bo) == 0);
  510.  
  511.    switch (data_size) {
  512.    case 16:
  513.       dst_fmt = PIPE_FORMAT_R32G32B32A32_UINT;
  514.       memcpy(&color.ui, data, 16);
  515.       break;
  516.    case 8:
  517.       dst_fmt = PIPE_FORMAT_R32G32_UINT;
  518.       memcpy(&color.ui, data, 8);
  519.       memset(&color.ui[2], 0, 8);
  520.       break;
  521.    case 4:
  522.       dst_fmt = PIPE_FORMAT_R32_UINT;
  523.       memcpy(&color.ui, data, 4);
  524.       memset(&color.ui[1], 0, 12);
  525.       break;
  526.    case 2:
  527.       dst_fmt = PIPE_FORMAT_R16_UINT;
  528.       color.ui[0] = util_cpu_to_le32(
  529.             util_le16_to_cpu(*(unsigned short *)data));
  530.       memset(&color.ui[1], 0, 12);
  531.       break;
  532.    case 1:
  533.       dst_fmt = PIPE_FORMAT_R8_UINT;
  534.       color.ui[0] = util_cpu_to_le32(*(unsigned char *)data);
  535.       memset(&color.ui[1], 0, 12);
  536.       break;
  537.    default:
  538.       assert(!"Unsupported element size");
  539.       return;
  540.    }
  541.  
  542.    assert(size % data_size == 0);
  543.  
  544.    elements = size / data_size;
  545.    height = (elements + 8191) / 8192;
  546.    width = elements / height;
  547.  
  548.    BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
  549.    PUSH_DATAf(push, color.f[0]);
  550.    PUSH_DATAf(push, color.f[1]);
  551.    PUSH_DATAf(push, color.f[2]);
  552.    PUSH_DATAf(push, color.f[3]);
  553.  
  554.    if (nouveau_pushbuf_space(push, 32, 1, 0))
  555.       return;
  556.  
  557.    PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
  558.  
  559.    BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
  560.    PUSH_DATA (push, width << 16);
  561.    PUSH_DATA (push, height << 16);
  562.    BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
  563.    PUSH_DATA (push, 8192 << 16);
  564.    PUSH_DATA (push, 8192 << 16);
  565.    nv50->scissors_dirty |= 1;
  566.  
  567.    BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
  568.    PUSH_DATA (push, 1);
  569.    BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
  570.    PUSH_DATAh(push, buf->bo->offset + buf->offset + offset);
  571.    PUSH_DATA (push, buf->bo->offset + buf->offset + offset);
  572.    PUSH_DATA (push, nv50_format_table[dst_fmt].rt);
  573.    PUSH_DATA (push, 0);
  574.    PUSH_DATA (push, 0);
  575.    BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);
  576.    PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | (width * data_size));
  577.    PUSH_DATA (push, height);
  578.    BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
  579.    PUSH_DATA (push, 0);
  580.  
  581.    /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
  582.  
  583.    BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
  584.    PUSH_DATA (push, (width << 16));
  585.    PUSH_DATA (push, (height << 16));
  586.  
  587.    BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), 1);
  588.    PUSH_DATA (push, 0x3c);
  589.  
  590.    if (width * height != elements) {
  591.       offset += width * height * data_size;
  592.       width = elements - width * height;
  593.       height = 1;
  594.       BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 2);
  595.       PUSH_DATAh(push, buf->bo->offset + buf->offset + offset);
  596.       PUSH_DATA (push, buf->bo->offset + buf->offset + offset);
  597.       BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);
  598.       PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | (width * data_size));
  599.       PUSH_DATA (push, height);
  600.       BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), 1);
  601.       PUSH_DATA (push, 0x3c);
  602.    }
  603.  
  604.    nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence);
  605.    nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr);
  606.  
  607.    nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;
  608. }
  609.  
  610. /* =============================== BLIT CODE ===================================
  611.  */
  612.  
  613. struct nv50_blitter
  614. {
  615.    struct nv50_program *fp[NV50_BLIT_MAX_TEXTURE_TYPES][NV50_BLIT_MODES];
  616.    struct nv50_program vp;
  617.  
  618.    struct nv50_tsc_entry sampler[2]; /* nearest, bilinear */
  619.  
  620.    pipe_mutex mutex;
  621. };
  622.  
  623. struct nv50_blitctx
  624. {
  625.    struct nv50_context *nv50;
  626.    struct nv50_program *fp;
  627.    uint8_t mode;
  628.    uint16_t color_mask;
  629.    uint8_t filter;
  630.    uint8_t render_condition_enable;
  631.    enum pipe_texture_target target;
  632.    struct {
  633.       struct pipe_framebuffer_state fb;
  634.       struct nv50_rasterizer_stateobj *rast;
  635.       struct nv50_program *vp;
  636.       struct nv50_program *gp;
  637.       struct nv50_program *fp;
  638.       unsigned num_textures[3];
  639.       unsigned num_samplers[3];
  640.       struct pipe_sampler_view *texture[2];
  641.       struct nv50_tsc_entry *sampler[2];
  642.       unsigned min_samples;
  643.       uint32_t dirty;
  644.    } saved;
  645.    struct nv50_rasterizer_stateobj rast;
  646. };
  647.  
  648. static void
  649. nv50_blitter_make_vp(struct nv50_blitter *blit)
  650. {
  651.    static const uint32_t code[] =
  652.    {
  653.       0x10000001, 0x0423c788, /* mov b32 o[0x00] s[0x00] */ /* HPOS.x */
  654.       0x10000205, 0x0423c788, /* mov b32 o[0x04] s[0x04] */ /* HPOS.y */
  655.       0x10000409, 0x0423c788, /* mov b32 o[0x08] s[0x08] */ /* TEXC.x */
  656.       0x1000060d, 0x0423c788, /* mov b32 o[0x0c] s[0x0c] */ /* TEXC.y */
  657.       0x10000811, 0x0423c789, /* mov b32 o[0x10] s[0x10] */ /* TEXC.z */
  658.    };
  659.  
  660.    blit->vp.type = PIPE_SHADER_VERTEX;
  661.    blit->vp.translated = TRUE;
  662.    blit->vp.code = (uint32_t *)code; /* const_cast */
  663.    blit->vp.code_size = sizeof(code);
  664.    blit->vp.max_gpr = 4;
  665.    blit->vp.max_out = 5;
  666.    blit->vp.out_nr = 2;
  667.    blit->vp.out[0].mask = 0x3;
  668.    blit->vp.out[0].sn = TGSI_SEMANTIC_POSITION;
  669.    blit->vp.out[1].hw = 2;
  670.    blit->vp.out[1].mask = 0x7;
  671.    blit->vp.out[1].sn = TGSI_SEMANTIC_GENERIC;
  672.    blit->vp.out[1].si = 0;
  673.    blit->vp.vp.attrs[0] = 0x73;
  674.    blit->vp.vp.psiz = 0x40;
  675.    blit->vp.vp.edgeflag = 0x40;
  676. }
  677.  
  678. void *
  679. nv50_blitter_make_fp(struct pipe_context *pipe,
  680.                      unsigned mode,
  681.                      enum pipe_texture_target ptarg)
  682. {
  683.    struct ureg_program *ureg;
  684.    struct ureg_src tc;
  685.    struct ureg_dst out;
  686.    struct ureg_dst data;
  687.  
  688.    const unsigned target = nv50_blit_get_tgsi_texture_target(ptarg);
  689.  
  690.    boolean tex_rgbaz = FALSE;
  691.    boolean tex_s = FALSE;
  692.    boolean cvt_un8 = FALSE;
  693.  
  694.    if (mode != NV50_BLIT_MODE_PASS &&
  695.        mode != NV50_BLIT_MODE_Z24X8 &&
  696.        mode != NV50_BLIT_MODE_X8Z24)
  697.       tex_s = TRUE;
  698.  
  699.    if (mode != NV50_BLIT_MODE_X24S8 &&
  700.        mode != NV50_BLIT_MODE_S8X24 &&
  701.        mode != NV50_BLIT_MODE_XS)
  702.       tex_rgbaz = TRUE;
  703.  
  704.    if (mode != NV50_BLIT_MODE_PASS &&
  705.        mode != NV50_BLIT_MODE_ZS &&
  706.        mode != NV50_BLIT_MODE_XS)
  707.       cvt_un8 = TRUE;
  708.  
  709.    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
  710.    if (!ureg)
  711.       return NULL;
  712.  
  713.    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
  714.    tc = ureg_DECL_fs_input(
  715.       ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR);
  716.  
  717.    if (ptarg == PIPE_TEXTURE_1D_ARRAY) {
  718.       /* Adjust coordinates. Depth is in z, but TEX expects it to be in y. */
  719.       tc = ureg_swizzle(tc, TGSI_SWIZZLE_X, TGSI_SWIZZLE_Z,
  720.                         TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z);
  721.    }
  722.  
  723.    data = ureg_DECL_temporary(ureg);
  724.  
  725.    if (tex_s) {
  726.       ureg_TEX(ureg, ureg_writemask(data, TGSI_WRITEMASK_X),
  727.                target, tc, ureg_DECL_sampler(ureg, 1));
  728.       ureg_MOV(ureg, ureg_writemask(data, TGSI_WRITEMASK_Y),
  729.                ureg_scalar(ureg_src(data), TGSI_SWIZZLE_X));
  730.    }
  731.    if (tex_rgbaz) {
  732.       const unsigned mask = (mode == NV50_BLIT_MODE_PASS) ?
  733.          TGSI_WRITEMASK_XYZW : TGSI_WRITEMASK_X;
  734.       ureg_TEX(ureg, ureg_writemask(data, mask),
  735.                target, tc, ureg_DECL_sampler(ureg, 0));
  736.    }
  737.  
  738.    if (cvt_un8) {
  739.       struct ureg_src mask;
  740.       struct ureg_src scale;
  741.       struct ureg_dst outz;
  742.       struct ureg_dst outs;
  743.       struct ureg_dst zdst3 = ureg_writemask(data, TGSI_WRITEMASK_XYZ);
  744.       struct ureg_dst zdst = ureg_writemask(data, TGSI_WRITEMASK_X);
  745.       struct ureg_dst sdst = ureg_writemask(data, TGSI_WRITEMASK_Y);
  746.       struct ureg_src zsrc3 = ureg_src(data);
  747.       struct ureg_src zsrc = ureg_scalar(zsrc3, TGSI_SWIZZLE_X);
  748.       struct ureg_src ssrc = ureg_scalar(zsrc3, TGSI_SWIZZLE_Y);
  749.       struct ureg_src zshuf;
  750.  
  751.       mask = ureg_imm3u(ureg, 0x0000ff, 0x00ff00, 0xff0000);
  752.       scale = ureg_imm4f(ureg,
  753.                          1.0f / 0x0000ff, 1.0f / 0x00ff00, 1.0f / 0xff0000,
  754.                          (1 << 24) - 1);
  755.  
  756.       if (mode == NV50_BLIT_MODE_Z24S8 ||
  757.           mode == NV50_BLIT_MODE_X24S8 ||
  758.           mode == NV50_BLIT_MODE_Z24X8) {
  759.          outz = ureg_writemask(out, TGSI_WRITEMASK_XYZ);
  760.          outs = ureg_writemask(out, TGSI_WRITEMASK_W);
  761.          zshuf = ureg_src(data);
  762.       } else {
  763.          outz = ureg_writemask(out, TGSI_WRITEMASK_YZW);
  764.          outs = ureg_writemask(out, TGSI_WRITEMASK_X);
  765.          zshuf = ureg_swizzle(zsrc3, TGSI_SWIZZLE_W,
  766.                               TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z);
  767.       }
  768.  
  769.       if (tex_s) {
  770.          ureg_I2F(ureg, sdst, ssrc);
  771.          ureg_MUL(ureg, outs, ssrc, ureg_scalar(scale, TGSI_SWIZZLE_X));
  772.       }
  773.  
  774.       if (tex_rgbaz) {
  775.          ureg_MUL(ureg, zdst, zsrc, ureg_scalar(scale, TGSI_SWIZZLE_W));
  776.          ureg_F2I(ureg, zdst, zsrc);
  777.          ureg_AND(ureg, zdst3, zsrc, mask);
  778.          ureg_I2F(ureg, zdst3, zsrc3);
  779.          ureg_MUL(ureg, zdst3, zsrc3, scale);
  780.          ureg_MOV(ureg, outz, zshuf);
  781.       }
  782.    } else {
  783.       unsigned mask = TGSI_WRITEMASK_XYZW;
  784.  
  785.       if (mode != NV50_BLIT_MODE_PASS) {
  786.          mask &= ~TGSI_WRITEMASK_ZW;
  787.          if (!tex_s)
  788.             mask = TGSI_WRITEMASK_X;
  789.          if (!tex_rgbaz)
  790.             mask = TGSI_WRITEMASK_Y;
  791.       }
  792.       ureg_MOV(ureg, ureg_writemask(out, mask), ureg_src(data));
  793.    }
  794.    ureg_END(ureg);
  795.  
  796.    return ureg_create_shader_and_destroy(ureg, pipe);
  797. }
  798.  
  799. static void
  800. nv50_blitter_make_sampler(struct nv50_blitter *blit)
  801. {
  802.    /* clamp to edge, min/max lod = 0, nearest filtering */
  803.  
  804.    blit->sampler[0].id = -1;
  805.  
  806.    blit->sampler[0].tsc[0] = NV50_TSC_0_SRGB_CONVERSION_ALLOWED |
  807.       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPS__SHIFT) |
  808.       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPT__SHIFT) |
  809.       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPR__SHIFT);
  810.    blit->sampler[0].tsc[1] =
  811.       NV50_TSC_1_MAGF_NEAREST | NV50_TSC_1_MINF_NEAREST | NV50_TSC_1_MIPF_NONE;
  812.  
  813.    /* clamp to edge, min/max lod = 0, bilinear filtering */
  814.  
  815.    blit->sampler[1].id = -1;
  816.  
  817.    blit->sampler[1].tsc[0] = blit->sampler[0].tsc[0];
  818.    blit->sampler[1].tsc[1] =
  819.       NV50_TSC_1_MAGF_LINEAR | NV50_TSC_1_MINF_LINEAR | NV50_TSC_1_MIPF_NONE;
  820. }
  821.  
  822. unsigned
  823. nv50_blit_select_mode(const struct pipe_blit_info *info)
  824. {
  825.    const unsigned mask = info->mask;
  826.  
  827.    switch (info->dst.resource->format) {
  828.    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
  829.    case PIPE_FORMAT_Z24X8_UNORM:
  830.    case PIPE_FORMAT_X24S8_UINT:
  831.       switch (mask & PIPE_MASK_ZS) {
  832.       case PIPE_MASK_ZS: return NV50_BLIT_MODE_Z24S8;
  833.       case PIPE_MASK_Z:  return NV50_BLIT_MODE_Z24X8;
  834.       default:
  835.          return NV50_BLIT_MODE_X24S8;
  836.       }
  837.    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
  838.    case PIPE_FORMAT_X8Z24_UNORM:
  839.    case PIPE_FORMAT_S8X24_UINT:
  840.       switch (mask & PIPE_MASK_ZS) {
  841.       case PIPE_MASK_ZS: return NV50_BLIT_MODE_S8Z24;
  842.       case PIPE_MASK_Z:  return NV50_BLIT_MODE_X8Z24;
  843.       default:
  844.          return NV50_BLIT_MODE_S8X24;
  845.       }
  846.    case PIPE_FORMAT_Z32_FLOAT:
  847.    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
  848.    case PIPE_FORMAT_X32_S8X24_UINT:
  849.       switch (mask & PIPE_MASK_ZS) {
  850.       case PIPE_MASK_ZS: return NV50_BLIT_MODE_ZS;
  851.       case PIPE_MASK_Z:  return NV50_BLIT_MODE_PASS;
  852.       default:
  853.          return NV50_BLIT_MODE_XS;
  854.       }
  855.    default:
  856.       return NV50_BLIT_MODE_PASS;
  857.    }
  858. }
  859.  
  860. static void
  861. nv50_blit_select_fp(struct nv50_blitctx *ctx, const struct pipe_blit_info *info)
  862. {
  863.    struct nv50_blitter *blitter = ctx->nv50->screen->blitter;
  864.  
  865.    const enum pipe_texture_target ptarg =
  866.       nv50_blit_reinterpret_pipe_texture_target(info->src.resource->target);
  867.  
  868.    const unsigned targ = nv50_blit_texture_type(ptarg);
  869.    const unsigned mode = ctx->mode;
  870.  
  871.    if (!blitter->fp[targ][mode]) {
  872.       pipe_mutex_lock(blitter->mutex);
  873.       if (!blitter->fp[targ][mode])
  874.          blitter->fp[targ][mode] =
  875.             nv50_blitter_make_fp(&ctx->nv50->base.pipe, mode, ptarg);
  876.       pipe_mutex_unlock(blitter->mutex);
  877.    }
  878.    ctx->fp = blitter->fp[targ][mode];
  879. }
  880.  
  881. static void
  882. nv50_blit_set_dst(struct nv50_blitctx *ctx,
  883.                   struct pipe_resource *res, unsigned level, unsigned layer,
  884.                   enum pipe_format format)
  885. {
  886.    struct nv50_context *nv50 = ctx->nv50;
  887.    struct pipe_context *pipe = &nv50->base.pipe;
  888.    struct pipe_surface templ;
  889.  
  890.    if (util_format_is_depth_or_stencil(format))
  891.       templ.format = nv50_blit_zeta_to_colour_format(format);
  892.    else
  893.       templ.format = format;
  894.  
  895.    templ.u.tex.level = level;
  896.    templ.u.tex.first_layer = templ.u.tex.last_layer = layer;
  897.  
  898.    if (layer == -1) {
  899.       templ.u.tex.first_layer = 0;
  900.       templ.u.tex.last_layer =
  901.          (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1;
  902.    }
  903.  
  904.    nv50->framebuffer.cbufs[0] = nv50_miptree_surface_new(pipe, res, &templ);
  905.    nv50->framebuffer.nr_cbufs = 1;
  906.    nv50->framebuffer.zsbuf = NULL;
  907.    nv50->framebuffer.width = nv50->framebuffer.cbufs[0]->width;
  908.    nv50->framebuffer.height = nv50->framebuffer.cbufs[0]->height;
  909. }
  910.  
  911. static void
  912. nv50_blit_set_src(struct nv50_blitctx *blit,
  913.                   struct pipe_resource *res, unsigned level, unsigned layer,
  914.                   enum pipe_format format, const uint8_t filter)
  915. {
  916.    struct nv50_context *nv50 = blit->nv50;
  917.    struct pipe_context *pipe = &nv50->base.pipe;
  918.    struct pipe_sampler_view templ;
  919.    uint32_t flags;
  920.    enum pipe_texture_target target;
  921.  
  922.    target = nv50_blit_reinterpret_pipe_texture_target(res->target);
  923.  
  924.    templ.format = format;
  925.    templ.u.tex.first_level = templ.u.tex.last_level = level;
  926.    templ.u.tex.first_layer = templ.u.tex.last_layer = layer;
  927.    templ.swizzle_r = PIPE_SWIZZLE_RED;
  928.    templ.swizzle_g = PIPE_SWIZZLE_GREEN;
  929.    templ.swizzle_b = PIPE_SWIZZLE_BLUE;
  930.    templ.swizzle_a = PIPE_SWIZZLE_ALPHA;
  931.  
  932.    if (layer == -1) {
  933.       templ.u.tex.first_layer = 0;
  934.       templ.u.tex.last_layer =
  935.          (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1;
  936.    }
  937.  
  938.    flags = res->last_level ? 0 : NV50_TEXVIEW_SCALED_COORDS;
  939.    flags |= NV50_TEXVIEW_ACCESS_RESOLVE;
  940.    if (filter && res->nr_samples == 8)
  941.       flags |= NV50_TEXVIEW_FILTER_MSAA8;
  942.  
  943.    nv50->textures[2][0] = nv50_create_texture_view(
  944.       pipe, res, &templ, flags, target);
  945.    nv50->textures[2][1] = NULL;
  946.  
  947.    nv50->num_textures[0] = nv50->num_textures[1] = 0;
  948.    nv50->num_textures[2] = 1;
  949.  
  950.    templ.format = nv50_zs_to_s_format(format);
  951.    if (templ.format != res->format) {
  952.       nv50->textures[2][1] = nv50_create_texture_view(
  953.          pipe, res, &templ, flags, target);
  954.       nv50->num_textures[2] = 2;
  955.    }
  956. }
  957.  
  958. static void
  959. nv50_blitctx_prepare_state(struct nv50_blitctx *blit)
  960. {
  961.    struct nouveau_pushbuf *push = blit->nv50->base.pushbuf;
  962.  
  963.    if (blit->nv50->cond_query && !blit->render_condition_enable) {
  964.       BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
  965.       PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
  966.    }
  967.  
  968.    /* blend state */
  969.    BEGIN_NV04(push, NV50_3D(COLOR_MASK(0)), 1);
  970.    PUSH_DATA (push, blit->color_mask);
  971.    BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1);
  972.    PUSH_DATA (push, 0);
  973.    BEGIN_NV04(push, NV50_3D(LOGIC_OP_ENABLE), 1);
  974.    PUSH_DATA (push, 0);
  975.  
  976.    /* rasterizer state */
  977. #ifndef NV50_SCISSORS_CLIPPING
  978.    BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 1);
  979.    PUSH_DATA (push, 1);
  980. #endif
  981.    BEGIN_NV04(push, NV50_3D(VERTEX_TWO_SIDE_ENABLE), 1);
  982.    PUSH_DATA (push, 0);
  983.    BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
  984.    PUSH_DATA (push, 0);
  985.    BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
  986.    PUSH_DATA (push, 0);
  987.    BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
  988.    PUSH_DATA (push, 0xffff);
  989.    PUSH_DATA (push, 0xffff);
  990.    PUSH_DATA (push, 0xffff);
  991.    PUSH_DATA (push, 0xffff);
  992.    BEGIN_NV04(push, NV50_3D(POLYGON_MODE_FRONT), 3);
  993.    PUSH_DATA (push, NV50_3D_POLYGON_MODE_FRONT_FILL);
  994.    PUSH_DATA (push, NV50_3D_POLYGON_MODE_BACK_FILL);
  995.    PUSH_DATA (push, 0);
  996.    BEGIN_NV04(push, NV50_3D(CULL_FACE_ENABLE), 1);
  997.    PUSH_DATA (push, 0);
  998.    BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_ENABLE), 1);
  999.    PUSH_DATA (push, 0);
  1000.    BEGIN_NV04(push, NV50_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
  1001.    PUSH_DATA (push, 0);
  1002.  
  1003.    /* zsa state */
  1004.    BEGIN_NV04(push, NV50_3D(DEPTH_TEST_ENABLE), 1);
  1005.    PUSH_DATA (push, 0);
  1006.    BEGIN_NV04(push, NV50_3D(STENCIL_ENABLE), 1);
  1007.    PUSH_DATA (push, 0);
  1008.    BEGIN_NV04(push, NV50_3D(ALPHA_TEST_ENABLE), 1);
  1009.    PUSH_DATA (push, 0);
  1010. }
  1011.  
  1012. static void
  1013. nv50_blitctx_pre_blit(struct nv50_blitctx *ctx)
  1014. {
  1015.    struct nv50_context *nv50 = ctx->nv50;
  1016.    struct nv50_blitter *blitter = nv50->screen->blitter;
  1017.    int s;
  1018.  
  1019.    ctx->saved.fb.width = nv50->framebuffer.width;
  1020.    ctx->saved.fb.height = nv50->framebuffer.height;
  1021.    ctx->saved.fb.nr_cbufs = nv50->framebuffer.nr_cbufs;
  1022.    ctx->saved.fb.cbufs[0] = nv50->framebuffer.cbufs[0];
  1023.    ctx->saved.fb.zsbuf = nv50->framebuffer.zsbuf;
  1024.  
  1025.    ctx->saved.rast = nv50->rast;
  1026.  
  1027.    ctx->saved.vp = nv50->vertprog;
  1028.    ctx->saved.gp = nv50->gmtyprog;
  1029.    ctx->saved.fp = nv50->fragprog;
  1030.  
  1031.    ctx->saved.min_samples = nv50->min_samples;
  1032.  
  1033.    nv50->rast = &ctx->rast;
  1034.  
  1035.    nv50->vertprog = &blitter->vp;
  1036.    nv50->gmtyprog = NULL;
  1037.    nv50->fragprog = ctx->fp;
  1038.  
  1039.    for (s = 0; s < 3; ++s) {
  1040.       ctx->saved.num_textures[s] = nv50->num_textures[s];
  1041.       ctx->saved.num_samplers[s] = nv50->num_samplers[s];
  1042.    }
  1043.    ctx->saved.texture[0] = nv50->textures[2][0];
  1044.    ctx->saved.texture[1] = nv50->textures[2][1];
  1045.    ctx->saved.sampler[0] = nv50->samplers[2][0];
  1046.    ctx->saved.sampler[1] = nv50->samplers[2][1];
  1047.  
  1048.    nv50->samplers[2][0] = &blitter->sampler[ctx->filter];
  1049.    nv50->samplers[2][1] = &blitter->sampler[ctx->filter];
  1050.  
  1051.    nv50->num_samplers[0] = nv50->num_samplers[1] = 0;
  1052.    nv50->num_samplers[2] = 2;
  1053.  
  1054.    nv50->min_samples = 1;
  1055.  
  1056.    ctx->saved.dirty = nv50->dirty;
  1057.  
  1058.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
  1059.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
  1060.  
  1061.    nv50->dirty =
  1062.       NV50_NEW_FRAMEBUFFER | NV50_NEW_MIN_SAMPLES |
  1063.       NV50_NEW_VERTPROG | NV50_NEW_FRAGPROG | NV50_NEW_GMTYPROG |
  1064.       NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS;
  1065. }
  1066.  
  1067. static void
  1068. nv50_blitctx_post_blit(struct nv50_blitctx *blit)
  1069. {
  1070.    struct nv50_context *nv50 = blit->nv50;
  1071.    int s;
  1072.  
  1073.    pipe_surface_reference(&nv50->framebuffer.cbufs[0], NULL);
  1074.  
  1075.    nv50->framebuffer.width = blit->saved.fb.width;
  1076.    nv50->framebuffer.height = blit->saved.fb.height;
  1077.    nv50->framebuffer.nr_cbufs = blit->saved.fb.nr_cbufs;
  1078.    nv50->framebuffer.cbufs[0] = blit->saved.fb.cbufs[0];
  1079.    nv50->framebuffer.zsbuf = blit->saved.fb.zsbuf;
  1080.  
  1081.    nv50->rast = blit->saved.rast;
  1082.  
  1083.    nv50->vertprog = blit->saved.vp;
  1084.    nv50->gmtyprog = blit->saved.gp;
  1085.    nv50->fragprog = blit->saved.fp;
  1086.  
  1087.    nv50->min_samples = blit->saved.min_samples;
  1088.  
  1089.    pipe_sampler_view_reference(&nv50->textures[2][0], NULL);
  1090.    pipe_sampler_view_reference(&nv50->textures[2][1], NULL);
  1091.  
  1092.    for (s = 0; s < 3; ++s) {
  1093.       nv50->num_textures[s] = blit->saved.num_textures[s];
  1094.       nv50->num_samplers[s] = blit->saved.num_samplers[s];
  1095.    }
  1096.    nv50->textures[2][0] = blit->saved.texture[0];
  1097.    nv50->textures[2][1] = blit->saved.texture[1];
  1098.    nv50->samplers[2][0] = blit->saved.sampler[0];
  1099.    nv50->samplers[2][1] = blit->saved.sampler[1];
  1100.  
  1101.    if (nv50->cond_query && !blit->render_condition_enable)
  1102.       nv50->base.pipe.render_condition(&nv50->base.pipe, nv50->cond_query,
  1103.                                        nv50->cond_cond, nv50->cond_mode);
  1104.  
  1105.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
  1106.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
  1107.  
  1108.    nv50->dirty = blit->saved.dirty |
  1109.       (NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR | NV50_NEW_SAMPLE_MASK |
  1110.        NV50_NEW_RASTERIZER | NV50_NEW_ZSA | NV50_NEW_BLEND |
  1111.        NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS |
  1112.        NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG | NV50_NEW_FRAGPROG);
  1113.    nv50->scissors_dirty |= 1;
  1114.  
  1115.    nv50->base.pipe.set_min_samples(&nv50->base.pipe, blit->saved.min_samples);
  1116. }
  1117.  
  1118.  
  1119. static void
  1120. nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
  1121. {
  1122.    struct nv50_blitctx *blit = nv50->blit;
  1123.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  1124.    struct pipe_resource *src = info->src.resource;
  1125.    struct pipe_resource *dst = info->dst.resource;
  1126.    int32_t minx, maxx, miny, maxy;
  1127.    int32_t i;
  1128.    float x0, x1, y0, y1, z;
  1129.    float dz;
  1130.    float x_range, y_range;
  1131.    float tri_x, tri_y;
  1132.  
  1133.    blit->mode = nv50_blit_select_mode(info);
  1134.    blit->color_mask = nv50_blit_derive_color_mask(info);
  1135.    blit->filter = nv50_blit_get_filter(info);
  1136.    blit->render_condition_enable = info->render_condition_enable;
  1137.  
  1138.    nv50_blit_select_fp(blit, info);
  1139.    nv50_blitctx_pre_blit(blit);
  1140.  
  1141.    nv50_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format);
  1142.    nv50_blit_set_src(blit, src, info->src.level, -1, info->src.format,
  1143.                      blit->filter);
  1144.  
  1145.    nv50_blitctx_prepare_state(blit);
  1146.  
  1147.    nv50_state_validate(nv50, ~0, 36);
  1148.  
  1149.    x_range = (float)info->src.box.width / (float)info->dst.box.width;
  1150.    y_range = (float)info->src.box.height / (float)info->dst.box.height;
  1151.  
  1152.    tri_x = 16384 << nv50_miptree(dst)->ms_x;
  1153.    tri_y = 16384 << nv50_miptree(dst)->ms_y;
  1154.  
  1155.    x0 = (float)info->src.box.x - x_range * (float)info->dst.box.x;
  1156.    y0 = (float)info->src.box.y - y_range * (float)info->dst.box.y;
  1157.  
  1158.    x1 = x0 + tri_x * x_range;
  1159.    y1 = y0 + tri_y * y_range;
  1160.  
  1161.    x0 *= (float)(1 << nv50_miptree(src)->ms_x);
  1162.    x1 *= (float)(1 << nv50_miptree(src)->ms_x);
  1163.    y0 *= (float)(1 << nv50_miptree(src)->ms_y);
  1164.    y1 *= (float)(1 << nv50_miptree(src)->ms_y);
  1165.  
  1166.    /* XXX: multiply by 6 for cube arrays ? */
  1167.    dz = (float)info->src.box.depth / (float)info->dst.box.depth;
  1168.    z = (float)info->src.box.z;
  1169.    if (nv50_miptree(src)->layout_3d)
  1170.       z += 0.5f * dz;
  1171.  
  1172.    if (src->last_level > 0) {
  1173.       /* If there are mip maps, GPU always assumes normalized coordinates. */
  1174.       const unsigned l = info->src.level;
  1175.       const float fh = u_minify(src->width0 << nv50_miptree(src)->ms_x, l);
  1176.       const float fv = u_minify(src->height0 << nv50_miptree(src)->ms_y, l);
  1177.       x0 /= fh;
  1178.       x1 /= fh;
  1179.       y0 /= fv;
  1180.       y1 /= fv;
  1181.       if (nv50_miptree(src)->layout_3d) {
  1182.          z /= u_minify(src->depth0, l);
  1183.          dz /= u_minify(src->depth0, l);
  1184.       }
  1185.    }
  1186.  
  1187.    BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
  1188.    PUSH_DATA (push, 0);
  1189.    BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
  1190.    PUSH_DATA (push, 0x1);
  1191.  
  1192.    /* Draw a large triangle in screen coordinates covering the whole
  1193.     * render target, with scissors defining the destination region.
  1194.     * The vertex is supplied with non-normalized texture coordinates
  1195.     * arranged in a way to yield the desired offset and scale.
  1196.     */
  1197.  
  1198.    minx = info->dst.box.x;
  1199.    maxx = info->dst.box.x + info->dst.box.width;
  1200.    miny = info->dst.box.y;
  1201.    maxy = info->dst.box.y + info->dst.box.height;
  1202.    if (info->scissor_enable) {
  1203.       minx = MAX2(minx, info->scissor.minx);
  1204.       maxx = MIN2(maxx, info->scissor.maxx);
  1205.       miny = MAX2(miny, info->scissor.miny);
  1206.       maxy = MIN2(maxy, info->scissor.maxy);
  1207.    }
  1208.    BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
  1209.    PUSH_DATA (push, (maxx << 16) | minx);
  1210.    PUSH_DATA (push, (maxy << 16) | miny);
  1211.  
  1212.    for (i = 0; i < info->dst.box.depth; ++i, z += dz) {
  1213.       if (info->dst.box.z + i) {
  1214.          BEGIN_NV04(push, NV50_3D(LAYER), 1);
  1215.          PUSH_DATA (push, info->dst.box.z + i);
  1216.       }
  1217.       PUSH_SPACE(push, 32);
  1218.       BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
  1219.       PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
  1220.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
  1221.       PUSH_DATAf(push, x0);
  1222.       PUSH_DATAf(push, y0);
  1223.       PUSH_DATAf(push, z);
  1224.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
  1225.       PUSH_DATAf(push, 0.0f);
  1226.       PUSH_DATAf(push, 0.0f);
  1227.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
  1228.       PUSH_DATAf(push, x1);
  1229.       PUSH_DATAf(push, y0);
  1230.       PUSH_DATAf(push, z);
  1231.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
  1232.       PUSH_DATAf(push, tri_x);
  1233.       PUSH_DATAf(push, 0.0f);
  1234.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
  1235.       PUSH_DATAf(push, x0);
  1236.       PUSH_DATAf(push, y1);
  1237.       PUSH_DATAf(push, z);
  1238.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
  1239.       PUSH_DATAf(push, 0.0f);
  1240.       PUSH_DATAf(push, tri_y);
  1241.       BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
  1242.       PUSH_DATA (push, 0);
  1243.    }
  1244.    if (info->dst.box.z + info->dst.box.depth - 1) {
  1245.       BEGIN_NV04(push, NV50_3D(LAYER), 1);
  1246.       PUSH_DATA (push, 0);
  1247.    }
  1248.  
  1249.    /* re-enable normally constant state */
  1250.  
  1251.    BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
  1252.    PUSH_DATA (push, 1);
  1253.  
  1254.    nv50_blitctx_post_blit(blit);
  1255. }
  1256.  
  1257. static void
  1258. nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
  1259. {
  1260.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  1261.    struct nv50_miptree *dst = nv50_miptree(info->dst.resource);
  1262.    struct nv50_miptree *src = nv50_miptree(info->src.resource);
  1263.    const int32_t srcx_adj = info->src.box.width < 0 ? -1 : 0;
  1264.    const int32_t srcy_adj = info->src.box.height < 0 ? -1 : 0;
  1265.    const int32_t dz = info->dst.box.z;
  1266.    const int32_t sz = info->src.box.z;
  1267.    uint32_t dstw, dsth;
  1268.    int32_t dstx, dsty;
  1269.    int64_t srcx, srcy;
  1270.    int64_t du_dx, dv_dy;
  1271.    int i;
  1272.    uint32_t mode;
  1273.    uint32_t mask = nv50_blit_eng2d_get_mask(info);
  1274.    boolean b;
  1275.  
  1276.    mode = nv50_blit_get_filter(info) ?
  1277.       NV50_2D_BLIT_CONTROL_FILTER_BILINEAR :
  1278.       NV50_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE;
  1279.    mode |= (src->base.base.nr_samples > dst->base.base.nr_samples) ?
  1280.       NV50_2D_BLIT_CONTROL_ORIGIN_CORNER : NV50_2D_BLIT_CONTROL_ORIGIN_CENTER;
  1281.  
  1282.    du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width;
  1283.    dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height;
  1284.  
  1285.    b = info->dst.format == info->src.format;
  1286.    nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b);
  1287.    nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b);
  1288.  
  1289.    if (info->scissor_enable) {
  1290.       BEGIN_NV04(push, NV50_2D(CLIP_X), 5);
  1291.       PUSH_DATA (push, info->scissor.minx << dst->ms_x);
  1292.       PUSH_DATA (push, info->scissor.miny << dst->ms_y);
  1293.       PUSH_DATA (push, (info->scissor.maxx - info->scissor.minx) << dst->ms_x);
  1294.       PUSH_DATA (push, (info->scissor.maxy - info->scissor.miny) << dst->ms_y);
  1295.       PUSH_DATA (push, 1); /* enable */
  1296.    }
  1297.  
  1298.    if (nv50->cond_query && info->render_condition_enable) {
  1299.       BEGIN_NV04(push, NV50_2D(COND_MODE), 1);
  1300.       PUSH_DATA (push, nv50->cond_condmode);
  1301.    }
  1302.  
  1303.    if (mask != 0xffffffff) {
  1304.       BEGIN_NV04(push, NV50_2D(ROP), 1);
  1305.       PUSH_DATA (push, 0xca); /* DPSDxax */
  1306.       BEGIN_NV04(push, NV50_2D(PATTERN_COLOR_FORMAT), 1);
  1307.       PUSH_DATA (push, NV50_2D_PATTERN_COLOR_FORMAT_A8R8G8B8);
  1308.       BEGIN_NV04(push, NV50_2D(PATTERN_BITMAP_COLOR(0)), 4);
  1309.       PUSH_DATA (push, 0x00000000);
  1310.       PUSH_DATA (push, mask);
  1311.       PUSH_DATA (push, 0xffffffff);
  1312.       PUSH_DATA (push, 0xffffffff);
  1313.       BEGIN_NV04(push, NV50_2D(OPERATION), 1);
  1314.       PUSH_DATA (push, NV50_2D_OPERATION_ROP);
  1315.    } else
  1316.    if (info->src.format != info->dst.format) {
  1317.       if (info->src.format == PIPE_FORMAT_R8_UNORM ||
  1318.           info->src.format == PIPE_FORMAT_R16_UNORM ||
  1319.           info->src.format == PIPE_FORMAT_R16_FLOAT ||
  1320.           info->src.format == PIPE_FORMAT_R32_FLOAT) {
  1321.          mask = 0xffff0000; /* also makes condition for OPERATION reset true */
  1322.          BEGIN_NV04(push, NV50_2D(BETA4), 2);
  1323.          PUSH_DATA (push, mask);
  1324.          PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY_PREMULT);
  1325.       }
  1326.    }
  1327.  
  1328.    if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) {
  1329.       /* ms_x is always >= ms_y */
  1330.       du_dx <<= src->ms_x - dst->ms_x;
  1331.       dv_dy <<= src->ms_y - dst->ms_y;
  1332.    } else {
  1333.       du_dx >>= dst->ms_x - src->ms_x;
  1334.       dv_dy >>= dst->ms_y - src->ms_y;
  1335.    }
  1336.  
  1337.    srcx = (int64_t)(info->src.box.x + srcx_adj) << (src->ms_x + 32);
  1338.    srcy = (int64_t)(info->src.box.y + srcy_adj) << (src->ms_y + 32);
  1339.  
  1340.    if (src->base.base.nr_samples > dst->base.base.nr_samples) {
  1341.       /* center src coorinates for proper MS resolve filtering */
  1342.       srcx += (int64_t)1 << (src->ms_x + 31);
  1343.       srcy += (int64_t)1 << (src->ms_y + 31);
  1344.    }
  1345.  
  1346.    dstx = info->dst.box.x << dst->ms_x;
  1347.    dsty = info->dst.box.y << dst->ms_y;
  1348.  
  1349.    dstw = info->dst.box.width << dst->ms_x;
  1350.    dsth = info->dst.box.height << dst->ms_y;
  1351.  
  1352.    if (dstx < 0) {
  1353.       dstw += dstx;
  1354.       srcx -= du_dx * dstx;
  1355.       dstx = 0;
  1356.    }
  1357.    if (dsty < 0) {
  1358.       dsth += dsty;
  1359.       srcy -= dv_dy * dsty;
  1360.       dsty = 0;
  1361.    }
  1362.  
  1363.    BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
  1364.    PUSH_DATA (push, mode);
  1365.    BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4);
  1366.    PUSH_DATA (push, dstx);
  1367.    PUSH_DATA (push, dsty);
  1368.    PUSH_DATA (push, dstw);
  1369.    PUSH_DATA (push, dsth);
  1370.    BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
  1371.    PUSH_DATA (push, du_dx);
  1372.    PUSH_DATA (push, du_dx >> 32);
  1373.    PUSH_DATA (push, dv_dy);
  1374.    PUSH_DATA (push, dv_dy >> 32);
  1375.  
  1376.    BCTX_REFN(nv50->bufctx, 2D, &dst->base, WR);
  1377.    BCTX_REFN(nv50->bufctx, 2D, &src->base, RD);
  1378.    nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
  1379.    if (nouveau_pushbuf_validate(nv50->base.pushbuf))
  1380.       return;
  1381.  
  1382.    for (i = 0; i < info->dst.box.depth; ++i) {
  1383.       if (i > 0) {
  1384.          /* no scaling in z-direction possible for eng2d blits */
  1385.          if (dst->layout_3d) {
  1386.             BEGIN_NV04(push, NV50_2D(DST_LAYER), 1);
  1387.             PUSH_DATA (push, info->dst.box.z + i);
  1388.          } else {
  1389.             const unsigned z = info->dst.box.z + i;
  1390.             BEGIN_NV04(push, NV50_2D(DST_ADDRESS_HIGH), 2);
  1391.             PUSH_DATAh(push, dst->base.address + z * dst->layer_stride);
  1392.             PUSH_DATA (push, dst->base.address + z * dst->layer_stride);
  1393.          }
  1394.          if (src->layout_3d) {
  1395.             /* not possible because of depth tiling */
  1396.             assert(0);
  1397.          } else {
  1398.             const unsigned z = info->src.box.z + i;
  1399.             BEGIN_NV04(push, NV50_2D(SRC_ADDRESS_HIGH), 2);
  1400.             PUSH_DATAh(push, src->base.address + z * src->layer_stride);
  1401.             PUSH_DATA (push, src->base.address + z * src->layer_stride);
  1402.          }
  1403.          BEGIN_NV04(push, NV50_2D(BLIT_SRC_Y_INT), 1); /* trigger */
  1404.          PUSH_DATA (push, srcy >> 32);
  1405.       } else {
  1406.          BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4);
  1407.          PUSH_DATA (push, srcx);
  1408.          PUSH_DATA (push, srcx >> 32);
  1409.          PUSH_DATA (push, srcy);
  1410.          PUSH_DATA (push, srcy >> 32);
  1411.       }
  1412.    }
  1413.    nv50_bufctx_fence(nv50->bufctx, FALSE);
  1414.  
  1415.    nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
  1416.  
  1417.    if (info->scissor_enable) {
  1418.       BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
  1419.       PUSH_DATA (push, 0);
  1420.    }
  1421.    if (mask != 0xffffffff) {
  1422.       BEGIN_NV04(push, NV50_2D(OPERATION), 1);
  1423.       PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
  1424.    }
  1425.    if (nv50->cond_query && info->render_condition_enable) {
  1426.       BEGIN_NV04(push, NV50_2D(COND_MODE), 1);
  1427.       PUSH_DATA (push, NV50_2D_COND_MODE_ALWAYS);
  1428.    }
  1429. }
  1430.  
  1431. static void
  1432. nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
  1433. {
  1434.    struct nv50_context *nv50 = nv50_context(pipe);
  1435.    boolean eng3d = FALSE;
  1436.  
  1437.    if (util_format_is_depth_or_stencil(info->dst.resource->format)) {
  1438.       if (!(info->mask & PIPE_MASK_ZS))
  1439.          return;
  1440.       if (info->dst.resource->format == PIPE_FORMAT_Z32_FLOAT ||
  1441.           info->dst.resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
  1442.          eng3d = TRUE;
  1443.       if (info->filter != PIPE_TEX_FILTER_NEAREST)
  1444.          eng3d = TRUE;
  1445.    } else {
  1446.       if (!(info->mask & PIPE_MASK_RGBA))
  1447.          return;
  1448.       if (info->mask != PIPE_MASK_RGBA)
  1449.          eng3d = TRUE;
  1450.    }
  1451.  
  1452.    if (nv50_miptree(info->src.resource)->layout_3d) {
  1453.       eng3d = TRUE;
  1454.    } else
  1455.    if (info->src.box.depth != info->dst.box.depth) {
  1456.       eng3d = TRUE;
  1457.       debug_printf("blit: cannot filter array or cube textures in z direction");
  1458.    }
  1459.  
  1460.    if (!eng3d && info->dst.format != info->src.format) {
  1461.       if (!nv50_2d_dst_format_faithful(info->dst.format) ||
  1462.           !nv50_2d_src_format_faithful(info->src.format)) {
  1463.          eng3d = TRUE;
  1464.       } else
  1465.       if (!nv50_2d_src_format_faithful(info->src.format)) {
  1466.          if (!util_format_is_luminance(info->src.format)) {
  1467.             if (util_format_is_intensity(info->src.format))
  1468.                eng3d = TRUE;
  1469.             else
  1470.             if (!nv50_2d_dst_format_ops_supported(info->dst.format))
  1471.                eng3d = TRUE;
  1472.             else
  1473.                eng3d = !nv50_2d_format_supported(info->src.format);
  1474.          }
  1475.       } else
  1476.       if (util_format_is_luminance_alpha(info->src.format))
  1477.          eng3d = TRUE;
  1478.    }
  1479.  
  1480.    if (info->src.resource->nr_samples == 8 &&
  1481.        info->dst.resource->nr_samples <= 1)
  1482.       eng3d = TRUE;
  1483.  
  1484.    /* FIXME: can't make this work with eng2d anymore */
  1485.    if ((info->src.resource->nr_samples | 1) !=
  1486.        (info->dst.resource->nr_samples | 1))
  1487.       eng3d = TRUE;
  1488.  
  1489.    /* FIXME: find correct src coordinate adjustments */
  1490.    if ((info->src.box.width !=  info->dst.box.width &&
  1491.         info->src.box.width != -info->dst.box.width) ||
  1492.        (info->src.box.height !=  info->dst.box.height &&
  1493.         info->src.box.height != -info->dst.box.height))
  1494.       eng3d = TRUE;
  1495.  
  1496.    if (!eng3d)
  1497.       nv50_blit_eng2d(nv50, info);
  1498.    else
  1499.       nv50_blit_3d(nv50, info);
  1500. }
  1501.  
  1502. static void
  1503. nv50_flush_resource(struct pipe_context *ctx,
  1504.                     struct pipe_resource *resource)
  1505. {
  1506. }
  1507.  
  1508. boolean
  1509. nv50_blitter_create(struct nv50_screen *screen)
  1510. {
  1511.    screen->blitter = CALLOC_STRUCT(nv50_blitter);
  1512.    if (!screen->blitter) {
  1513.       NOUVEAU_ERR("failed to allocate blitter struct\n");
  1514.       return FALSE;
  1515.    }
  1516.  
  1517.    pipe_mutex_init(screen->blitter->mutex);
  1518.  
  1519.    nv50_blitter_make_vp(screen->blitter);
  1520.    nv50_blitter_make_sampler(screen->blitter);
  1521.  
  1522.    return TRUE;
  1523. }
  1524.  
  1525. void
  1526. nv50_blitter_destroy(struct nv50_screen *screen)
  1527. {
  1528.    struct nv50_blitter *blitter = screen->blitter;
  1529.    unsigned i, m;
  1530.  
  1531.    for (i = 0; i < NV50_BLIT_MAX_TEXTURE_TYPES; ++i) {
  1532.       for (m = 0; m < NV50_BLIT_MODES; ++m) {
  1533.          struct nv50_program *prog = blitter->fp[i][m];
  1534.          if (prog) {
  1535.             nv50_program_destroy(NULL, prog);
  1536.             FREE((void *)prog->pipe.tokens);
  1537.             FREE(prog);
  1538.          }
  1539.       }
  1540.    }
  1541.  
  1542.    FREE(blitter);
  1543. }
  1544.  
  1545. boolean
  1546. nv50_blitctx_create(struct nv50_context *nv50)
  1547. {
  1548.    nv50->blit = CALLOC_STRUCT(nv50_blitctx);
  1549.    if (!nv50->blit) {
  1550.       NOUVEAU_ERR("failed to allocate blit context\n");
  1551.       return FALSE;
  1552.    }
  1553.  
  1554.    nv50->blit->nv50 = nv50;
  1555.  
  1556.    nv50->blit->rast.pipe.half_pixel_center = 1;
  1557.  
  1558.    return TRUE;
  1559. }
  1560.  
  1561. void
  1562. nv50_init_surface_functions(struct nv50_context *nv50)
  1563. {
  1564.    struct pipe_context *pipe = &nv50->base.pipe;
  1565.  
  1566.    pipe->resource_copy_region = nv50_resource_copy_region;
  1567.    pipe->blit = nv50_blit;
  1568.    pipe->flush_resource = nv50_flush_resource;
  1569.    pipe->clear_render_target = nv50_clear_render_target;
  1570.    pipe->clear_depth_stencil = nv50_clear_depth_stencil;
  1571.    pipe->clear_buffer = nv50_clear_buffer;
  1572. }
  1573.