Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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_context.h"
  37. #include "nv50_resource.h"
  38.  
  39. #include "nv50_defs.xml.h"
  40. #include "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_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, bo->offset + offset);
  118.       PUSH_DATA (push, bo->offset + 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, bo->offset + offset);
  130.       PUSH_DATA (push, bo->offset + 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(RT_CONTROL), 1);
  292.    PUSH_DATA (push, 1);
  293.    BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
  294.    PUSH_DATAh(push, bo->offset + sf->offset);
  295.    PUSH_DATA (push, bo->offset + sf->offset);
  296.    PUSH_DATA (push, nv50_format_table[dst->format].rt);
  297.    PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
  298.    PUSH_DATA (push, 0);
  299.    BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);
  300.    if (nouveau_bo_memtype(bo))
  301.       PUSH_DATA(push, sf->width);
  302.    else
  303.       PUSH_DATA(push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
  304.    PUSH_DATA (push, sf->height);
  305.    BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
  306.    PUSH_DATA (push, 1);
  307.  
  308.    if (!nouveau_bo_memtype(bo)) {
  309.       BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
  310.       PUSH_DATA (push, 0);
  311.    }
  312.  
  313.    /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
  314.  
  315.    BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
  316.    PUSH_DATA (push, (width << 16) | dstx);
  317.    PUSH_DATA (push, (height << 16) | dsty);
  318.  
  319.    BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), sf->depth);
  320.    for (z = 0; z < sf->depth; ++z) {
  321.       PUSH_DATA (push, 0x3c |
  322.                  (z << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  323.    }
  324.  
  325.    nv50->dirty |= NV50_NEW_FRAMEBUFFER;
  326. }
  327.  
  328. static void
  329. nv50_clear_depth_stencil(struct pipe_context *pipe,
  330.                          struct pipe_surface *dst,
  331.                          unsigned clear_flags,
  332.                          double depth,
  333.                          unsigned stencil,
  334.                          unsigned dstx, unsigned dsty,
  335.                          unsigned width, unsigned height)
  336. {
  337.    struct nv50_context *nv50 = nv50_context(pipe);
  338.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  339.    struct nv50_miptree *mt = nv50_miptree(dst->texture);
  340.    struct nv50_surface *sf = nv50_surface(dst);
  341.    struct nouveau_bo *bo = mt->base.bo;
  342.    uint32_t mode = 0;
  343.    unsigned z;
  344.  
  345.    assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
  346.  
  347.    if (clear_flags & PIPE_CLEAR_DEPTH) {
  348.       BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
  349.       PUSH_DATAf(push, depth);
  350.       mode |= NV50_3D_CLEAR_BUFFERS_Z;
  351.    }
  352.  
  353.    if (clear_flags & PIPE_CLEAR_STENCIL) {
  354.       BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
  355.       PUSH_DATA (push, stencil & 0xff);
  356.       mode |= NV50_3D_CLEAR_BUFFERS_S;
  357.    }
  358.  
  359.    if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
  360.       return;
  361.  
  362.    PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
  363.  
  364.    BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
  365.    PUSH_DATAh(push, bo->offset + sf->offset);
  366.    PUSH_DATA (push, bo->offset + sf->offset);
  367.    PUSH_DATA (push, nv50_format_table[dst->format].rt);
  368.    PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
  369.    PUSH_DATA (push, 0);
  370.    BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
  371.    PUSH_DATA (push, 1);
  372.    BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
  373.    PUSH_DATA (push, sf->width);
  374.    PUSH_DATA (push, sf->height);
  375.    PUSH_DATA (push, (1 << 16) | 1);
  376.  
  377.    BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
  378.    PUSH_DATA (push, (width << 16) | dstx);
  379.    PUSH_DATA (push, (height << 16) | dsty);
  380.  
  381.    BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), sf->depth);
  382.    for (z = 0; z < sf->depth; ++z) {
  383.       PUSH_DATA (push, mode |
  384.                  (z << NV50_3D_CLEAR_BUFFERS_LAYER__SHIFT));
  385.    }
  386.  
  387.    nv50->dirty |= NV50_NEW_FRAMEBUFFER;
  388. }
  389.  
  390. void
  391. nv50_clear(struct pipe_context *pipe, unsigned buffers,
  392.            const union pipe_color_union *color,
  393.            double depth, unsigned stencil)
  394. {
  395.    struct nv50_context *nv50 = nv50_context(pipe);
  396.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  397.    struct pipe_framebuffer_state *fb = &nv50->framebuffer;
  398.    unsigned i;
  399.    uint32_t mode = 0;
  400.  
  401.    /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
  402.    if (!nv50_state_validate(nv50, NV50_NEW_FRAMEBUFFER, 9 + (fb->nr_cbufs * 2)))
  403.       return;
  404.  
  405.    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
  406.       BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
  407.       PUSH_DATAf(push, color->f[0]);
  408.       PUSH_DATAf(push, color->f[1]);
  409.       PUSH_DATAf(push, color->f[2]);
  410.       PUSH_DATAf(push, color->f[3]);
  411.       mode =
  412.          NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G |
  413.          NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A;
  414.    }
  415.  
  416.    if (buffers & PIPE_CLEAR_DEPTH) {
  417.       BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
  418.       PUSH_DATA (push, fui(depth));
  419.       mode |= NV50_3D_CLEAR_BUFFERS_Z;
  420.    }
  421.  
  422.    if (buffers & PIPE_CLEAR_STENCIL) {
  423.       BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
  424.       PUSH_DATA (push, stencil & 0xff);
  425.       mode |= NV50_3D_CLEAR_BUFFERS_S;
  426.    }
  427.  
  428.    BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
  429.    PUSH_DATA (push, mode);
  430.  
  431.    for (i = 1; i < fb->nr_cbufs; i++) {
  432.       BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
  433.       PUSH_DATA (push, (i << 6) | 0x3c);
  434.    }
  435. }
  436.  
  437.  
  438. /* =============================== BLIT CODE ===================================
  439.  */
  440.  
  441. struct nv50_blitter
  442. {
  443.    struct nv50_program *fp[NV50_BLIT_MAX_TEXTURE_TYPES][NV50_BLIT_MODES];
  444.    struct nv50_program vp;
  445.  
  446.    struct nv50_tsc_entry sampler[2]; /* nearest, bilinear */
  447.  
  448.    pipe_mutex mutex;
  449. };
  450.  
  451. struct nv50_blitctx
  452. {
  453.    struct nv50_context *nv50;
  454.    struct nv50_program *fp;
  455.    uint8_t mode;
  456.    uint16_t color_mask;
  457.    uint8_t filter;
  458.    enum pipe_texture_target target;
  459.    struct {
  460.       struct pipe_framebuffer_state fb;
  461.       struct nv50_rasterizer_stateobj *rast;
  462.       struct nv50_program *vp;
  463.       struct nv50_program *gp;
  464.       struct nv50_program *fp;
  465.       unsigned num_textures[3];
  466.       unsigned num_samplers[3];
  467.       struct pipe_sampler_view *texture[2];
  468.       struct nv50_tsc_entry *sampler[2];
  469.       uint32_t dirty;
  470.    } saved;
  471.    struct nv50_rasterizer_stateobj rast;
  472. };
  473.  
  474. static void
  475. nv50_blitter_make_vp(struct nv50_blitter *blit)
  476. {
  477.    static const uint32_t code[] =
  478.    {
  479.       0x10000001, 0x0423c788, /* mov b32 o[0x00] s[0x00] */ /* HPOS.x */
  480.       0x10000205, 0x0423c788, /* mov b32 o[0x04] s[0x04] */ /* HPOS.y */
  481.       0x10000409, 0x0423c788, /* mov b32 o[0x08] s[0x08] */ /* TEXC.x */
  482.       0x1000060d, 0x0423c788, /* mov b32 o[0x0c] s[0x0c] */ /* TEXC.y */
  483.       0x10000811, 0x0423c789, /* mov b32 o[0x10] s[0x10] */ /* TEXC.z */
  484.    };
  485.  
  486.    blit->vp.type = PIPE_SHADER_VERTEX;
  487.    blit->vp.translated = TRUE;
  488.    blit->vp.code = (uint32_t *)code; /* const_cast */
  489.    blit->vp.code_size = sizeof(code);
  490.    blit->vp.max_gpr = 4;
  491.    blit->vp.max_out = 5;
  492.    blit->vp.out_nr = 2;
  493.    blit->vp.out[0].mask = 0x3;
  494.    blit->vp.out[0].sn = TGSI_SEMANTIC_POSITION;
  495.    blit->vp.out[1].hw = 2;
  496.    blit->vp.out[1].mask = 0x7;
  497.    blit->vp.out[1].sn = TGSI_SEMANTIC_GENERIC;
  498.    blit->vp.out[1].si = 0;
  499.    blit->vp.vp.attrs[0] = 0x73;
  500.    blit->vp.vp.psiz = 0x40;
  501.    blit->vp.vp.edgeflag = 0x40;
  502. }
  503.  
  504. void *
  505. nv50_blitter_make_fp(struct pipe_context *pipe,
  506.                      unsigned mode,
  507.                      enum pipe_texture_target ptarg)
  508. {
  509.    struct ureg_program *ureg;
  510.    struct ureg_src tc;
  511.    struct ureg_dst out;
  512.    struct ureg_dst data;
  513.  
  514.    const unsigned target = nv50_blit_get_tgsi_texture_target(ptarg);
  515.  
  516.    boolean tex_rgbaz = FALSE;
  517.    boolean tex_s = FALSE;
  518.    boolean cvt_un8 = FALSE;
  519.  
  520.    if (mode != NV50_BLIT_MODE_PASS &&
  521.        mode != NV50_BLIT_MODE_Z24X8 &&
  522.        mode != NV50_BLIT_MODE_X8Z24)
  523.       tex_s = TRUE;
  524.  
  525.    if (mode != NV50_BLIT_MODE_X24S8 &&
  526.        mode != NV50_BLIT_MODE_S8X24 &&
  527.        mode != NV50_BLIT_MODE_XS)
  528.       tex_rgbaz = TRUE;
  529.  
  530.    if (mode != NV50_BLIT_MODE_PASS &&
  531.        mode != NV50_BLIT_MODE_ZS &&
  532.        mode != NV50_BLIT_MODE_XS)
  533.       cvt_un8 = TRUE;
  534.  
  535.    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
  536.    if (!ureg)
  537.       return NULL;
  538.  
  539.    out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
  540.    tc = ureg_DECL_fs_input(
  541.       ureg, TGSI_SEMANTIC_GENERIC, 0, TGSI_INTERPOLATE_LINEAR);
  542.  
  543.    data = ureg_DECL_temporary(ureg);
  544.  
  545.    if (tex_s) {
  546.       ureg_TEX(ureg, ureg_writemask(data, TGSI_WRITEMASK_X),
  547.                target, tc, ureg_DECL_sampler(ureg, 1));
  548.       ureg_MOV(ureg, ureg_writemask(data, TGSI_WRITEMASK_Y),
  549.                ureg_scalar(ureg_src(data), TGSI_SWIZZLE_X));
  550.    }
  551.    if (tex_rgbaz) {
  552.       const unsigned mask = (mode == NV50_BLIT_MODE_PASS) ?
  553.          TGSI_WRITEMASK_XYZW : TGSI_WRITEMASK_X;
  554.       ureg_TEX(ureg, ureg_writemask(data, mask),
  555.                target, tc, ureg_DECL_sampler(ureg, 0));
  556.    }
  557.  
  558.    if (cvt_un8) {
  559.       struct ureg_src mask;
  560.       struct ureg_src scale;
  561.       struct ureg_dst outz;
  562.       struct ureg_dst outs;
  563.       struct ureg_dst zdst3 = ureg_writemask(data, TGSI_WRITEMASK_XYZ);
  564.       struct ureg_dst zdst = ureg_writemask(data, TGSI_WRITEMASK_X);
  565.       struct ureg_dst sdst = ureg_writemask(data, TGSI_WRITEMASK_Y);
  566.       struct ureg_src zsrc3 = ureg_src(data);
  567.       struct ureg_src zsrc = ureg_scalar(zsrc3, TGSI_SWIZZLE_X);
  568.       struct ureg_src ssrc = ureg_scalar(zsrc3, TGSI_SWIZZLE_Y);
  569.       struct ureg_src zshuf;
  570.  
  571.       mask = ureg_imm3u(ureg, 0x0000ff, 0x00ff00, 0xff0000);
  572.       scale = ureg_imm4f(ureg,
  573.                          1.0f / 0x0000ff, 1.0f / 0x00ff00, 1.0f / 0xff0000,
  574.                          (1 << 24) - 1);
  575.  
  576.       if (mode == NV50_BLIT_MODE_Z24S8 ||
  577.           mode == NV50_BLIT_MODE_X24S8 ||
  578.           mode == NV50_BLIT_MODE_Z24X8) {
  579.          outz = ureg_writemask(out, TGSI_WRITEMASK_XYZ);
  580.          outs = ureg_writemask(out, TGSI_WRITEMASK_W);
  581.          zshuf = ureg_src(data);
  582.       } else {
  583.          outz = ureg_writemask(out, TGSI_WRITEMASK_YZW);
  584.          outs = ureg_writemask(out, TGSI_WRITEMASK_X);
  585.          zshuf = ureg_swizzle(zsrc3, TGSI_SWIZZLE_W,
  586.                               TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z);
  587.       }
  588.  
  589.       if (tex_s) {
  590.          ureg_I2F(ureg, sdst, ssrc);
  591.          ureg_MUL(ureg, outs, ssrc, ureg_scalar(scale, TGSI_SWIZZLE_X));
  592.       }
  593.  
  594.       if (tex_rgbaz) {
  595.          ureg_MUL(ureg, zdst, zsrc, ureg_scalar(scale, TGSI_SWIZZLE_W));
  596.          ureg_F2I(ureg, zdst, zsrc);
  597.          ureg_AND(ureg, zdst3, zsrc, mask);
  598.          ureg_I2F(ureg, zdst3, zsrc3);
  599.          ureg_MUL(ureg, zdst3, zsrc3, scale);
  600.          ureg_MOV(ureg, outz, zshuf);
  601.       }
  602.    } else {
  603.       unsigned mask = TGSI_WRITEMASK_XYZW;
  604.  
  605.       if (mode != NV50_BLIT_MODE_PASS) {
  606.          mask &= ~TGSI_WRITEMASK_ZW;
  607.          if (!tex_s)
  608.             mask = TGSI_WRITEMASK_X;
  609.          if (!tex_rgbaz)
  610.             mask = TGSI_WRITEMASK_Y;
  611.       }
  612.       ureg_MOV(ureg, ureg_writemask(out, mask), ureg_src(data));
  613.    }
  614.    ureg_END(ureg);
  615.  
  616.    return ureg_create_shader_and_destroy(ureg, pipe);
  617. }
  618.  
  619. static void
  620. nv50_blitter_make_sampler(struct nv50_blitter *blit)
  621. {
  622.    /* clamp to edge, min/max lod = 0, nearest filtering */
  623.  
  624.    blit->sampler[0].id = -1;
  625.  
  626.    blit->sampler[0].tsc[0] = NV50_TSC_0_SRGB_CONVERSION_ALLOWED |
  627.       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPS__SHIFT) |
  628.       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPT__SHIFT) |
  629.       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPR__SHIFT);
  630.    blit->sampler[0].tsc[1] =
  631.       NV50_TSC_1_MAGF_NEAREST | NV50_TSC_1_MINF_NEAREST | NV50_TSC_1_MIPF_NONE;
  632.  
  633.    /* clamp to edge, min/max lod = 0, bilinear filtering */
  634.  
  635.    blit->sampler[1].id = -1;
  636.  
  637.    blit->sampler[1].tsc[0] = blit->sampler[0].tsc[0];
  638.    blit->sampler[1].tsc[1] =
  639.       NV50_TSC_1_MAGF_LINEAR | NV50_TSC_1_MINF_LINEAR | NV50_TSC_1_MIPF_NONE;
  640. }
  641.  
  642. unsigned
  643. nv50_blit_select_mode(const struct pipe_blit_info *info)
  644. {
  645.    const unsigned mask = info->mask;
  646.  
  647.    switch (info->dst.resource->format) {
  648.    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
  649.    case PIPE_FORMAT_Z24X8_UNORM:
  650.       switch (mask & PIPE_MASK_ZS) {
  651.       case PIPE_MASK_ZS: return NV50_BLIT_MODE_Z24S8;
  652.       case PIPE_MASK_Z:  return NV50_BLIT_MODE_Z24X8;
  653.       default:
  654.          return NV50_BLIT_MODE_X24S8;
  655.       }
  656.    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
  657.       switch (mask & PIPE_MASK_ZS) {
  658.       case PIPE_MASK_ZS: return NV50_BLIT_MODE_S8Z24;
  659.       case PIPE_MASK_Z:  return NV50_BLIT_MODE_X8Z24;
  660.       default:
  661.          return NV50_BLIT_MODE_S8X24;
  662.       }
  663.    case PIPE_FORMAT_Z32_FLOAT:
  664.    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
  665.       switch (mask & PIPE_MASK_ZS) {
  666.       case PIPE_MASK_ZS: return NV50_BLIT_MODE_ZS;
  667.       case PIPE_MASK_Z:  return NV50_BLIT_MODE_PASS;
  668.       default:
  669.          return NV50_BLIT_MODE_XS;
  670.       }
  671.    default:
  672.       return NV50_BLIT_MODE_PASS;
  673.    }
  674. }
  675.  
  676. static void
  677. nv50_blit_select_fp(struct nv50_blitctx *ctx, const struct pipe_blit_info *info)
  678. {
  679.    struct nv50_blitter *blitter = ctx->nv50->screen->blitter;
  680.  
  681.    const enum pipe_texture_target ptarg =
  682.       nv50_blit_reinterpret_pipe_texture_target(info->src.resource->target);
  683.  
  684.    const unsigned targ = nv50_blit_texture_type(ptarg);
  685.    const unsigned mode = ctx->mode;
  686.  
  687.    if (!blitter->fp[targ][mode]) {
  688.       pipe_mutex_lock(blitter->mutex);
  689.       if (!blitter->fp[targ][mode])
  690.          blitter->fp[targ][mode] =
  691.             nv50_blitter_make_fp(&ctx->nv50->base.pipe, mode, ptarg);
  692.       pipe_mutex_unlock(blitter->mutex);
  693.    }
  694.    ctx->fp = blitter->fp[targ][mode];
  695. }
  696.  
  697. static void
  698. nv50_blit_set_dst(struct nv50_blitctx *ctx,
  699.                   struct pipe_resource *res, unsigned level, unsigned layer,
  700.                   enum pipe_format format)
  701. {
  702.    struct nv50_context *nv50 = ctx->nv50;
  703.    struct pipe_context *pipe = &nv50->base.pipe;
  704.    struct pipe_surface templ;
  705.  
  706.    if (util_format_is_depth_or_stencil(format))
  707.       templ.format = nv50_blit_zeta_to_colour_format(format);
  708.    else
  709.       templ.format = format;
  710.  
  711.    templ.u.tex.level = level;
  712.    templ.u.tex.first_layer = templ.u.tex.last_layer = layer;
  713.  
  714.    if (layer == -1) {
  715.       templ.u.tex.first_layer = 0;
  716.       templ.u.tex.last_layer =
  717.          (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1;
  718.    }
  719.  
  720.    nv50->framebuffer.cbufs[0] = nv50_miptree_surface_new(pipe, res, &templ);
  721.    nv50->framebuffer.nr_cbufs = 1;
  722.    nv50->framebuffer.zsbuf = NULL;
  723.    nv50->framebuffer.width = nv50->framebuffer.cbufs[0]->width;
  724.    nv50->framebuffer.height = nv50->framebuffer.cbufs[0]->height;
  725. }
  726.  
  727. static void
  728. nv50_blit_set_src(struct nv50_blitctx *blit,
  729.                   struct pipe_resource *res, unsigned level, unsigned layer,
  730.                   enum pipe_format format, const uint8_t filter)
  731. {
  732.    struct nv50_context *nv50 = blit->nv50;
  733.    struct pipe_context *pipe = &nv50->base.pipe;
  734.    struct pipe_sampler_view templ;
  735.    uint32_t flags;
  736.    enum pipe_texture_target target;
  737.  
  738.    target = nv50_blit_reinterpret_pipe_texture_target(res->target);
  739.  
  740.    templ.format = format;
  741.    templ.u.tex.first_level = templ.u.tex.last_level = level;
  742.    templ.u.tex.first_layer = templ.u.tex.last_layer = layer;
  743.    templ.swizzle_r = PIPE_SWIZZLE_RED;
  744.    templ.swizzle_g = PIPE_SWIZZLE_GREEN;
  745.    templ.swizzle_b = PIPE_SWIZZLE_BLUE;
  746.    templ.swizzle_a = PIPE_SWIZZLE_ALPHA;
  747.  
  748.    if (layer == -1) {
  749.       templ.u.tex.first_layer = 0;
  750.       templ.u.tex.last_layer =
  751.          (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1;
  752.    }
  753.  
  754.    flags = res->last_level ? 0 : NV50_TEXVIEW_SCALED_COORDS;
  755.    flags |= NV50_TEXVIEW_ACCESS_RESOLVE;
  756.    if (filter && res->nr_samples == 8)
  757.       flags |= NV50_TEXVIEW_FILTER_MSAA8;
  758.  
  759.    nv50->textures[2][0] = nv50_create_texture_view(
  760.       pipe, res, &templ, flags, target);
  761.    nv50->textures[2][1] = NULL;
  762.  
  763.    nv50->num_textures[0] = nv50->num_textures[1] = 0;
  764.    nv50->num_textures[2] = 1;
  765.  
  766.    templ.format = nv50_zs_to_s_format(format);
  767.    if (templ.format != res->format) {
  768.       nv50->textures[2][1] = nv50_create_texture_view(
  769.          pipe, res, &templ, flags, target);
  770.       nv50->num_textures[2] = 2;
  771.    }
  772. }
  773.  
  774. static void
  775. nv50_blitctx_prepare_state(struct nv50_blitctx *blit)
  776. {
  777.    struct nouveau_pushbuf *push = blit->nv50->base.pushbuf;
  778.  
  779.    if (blit->nv50->cond_query) {
  780.       BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
  781.       PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
  782.    }
  783.  
  784.    /* blend state */
  785.    BEGIN_NV04(push, NV50_3D(COLOR_MASK(0)), 1);
  786.    PUSH_DATA (push, blit->color_mask);
  787.    BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1);
  788.    PUSH_DATA (push, 0);
  789.    BEGIN_NV04(push, NV50_3D(LOGIC_OP_ENABLE), 1);
  790.    PUSH_DATA (push, 0);
  791.  
  792.    /* rasterizer state */
  793. #ifndef NV50_SCISSORS_CLIPPING
  794.    BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 1);
  795.    PUSH_DATA (push, 1);
  796. #endif
  797.    BEGIN_NV04(push, NV50_3D(VERTEX_TWO_SIDE_ENABLE), 1);
  798.    PUSH_DATA (push, 0);
  799.    BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
  800.    PUSH_DATA (push, 0);
  801.    BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
  802.    PUSH_DATA (push, 0);
  803.    BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
  804.    PUSH_DATA (push, 0xffff);
  805.    PUSH_DATA (push, 0xffff);
  806.    PUSH_DATA (push, 0xffff);
  807.    PUSH_DATA (push, 0xffff);
  808.    BEGIN_NV04(push, NV50_3D(POLYGON_MODE_FRONT), 3);
  809.    PUSH_DATA (push, NV50_3D_POLYGON_MODE_FRONT_FILL);
  810.    PUSH_DATA (push, NV50_3D_POLYGON_MODE_BACK_FILL);
  811.    PUSH_DATA (push, 0);
  812.    BEGIN_NV04(push, NV50_3D(CULL_FACE_ENABLE), 1);
  813.    PUSH_DATA (push, 0);
  814.    BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_ENABLE), 1);
  815.    PUSH_DATA (push, 0);
  816.    BEGIN_NV04(push, NV50_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
  817.    PUSH_DATA (push, 0);
  818.  
  819.    /* zsa state */
  820.    BEGIN_NV04(push, NV50_3D(DEPTH_TEST_ENABLE), 1);
  821.    PUSH_DATA (push, 0);
  822.    BEGIN_NV04(push, NV50_3D(STENCIL_ENABLE), 1);
  823.    PUSH_DATA (push, 0);
  824.    BEGIN_NV04(push, NV50_3D(ALPHA_TEST_ENABLE), 1);
  825.    PUSH_DATA (push, 0);
  826. }
  827.  
  828. static void
  829. nv50_blitctx_pre_blit(struct nv50_blitctx *ctx)
  830. {
  831.    struct nv50_context *nv50 = ctx->nv50;
  832.    struct nv50_blitter *blitter = nv50->screen->blitter;
  833.    int s;
  834.  
  835.    ctx->saved.fb.width = nv50->framebuffer.width;
  836.    ctx->saved.fb.height = nv50->framebuffer.height;
  837.    ctx->saved.fb.nr_cbufs = nv50->framebuffer.nr_cbufs;
  838.    ctx->saved.fb.cbufs[0] = nv50->framebuffer.cbufs[0];
  839.    ctx->saved.fb.zsbuf = nv50->framebuffer.zsbuf;
  840.  
  841.    ctx->saved.rast = nv50->rast;
  842.  
  843.    ctx->saved.vp = nv50->vertprog;
  844.    ctx->saved.gp = nv50->gmtyprog;
  845.    ctx->saved.fp = nv50->fragprog;
  846.  
  847.    nv50->rast = &ctx->rast;
  848.  
  849.    nv50->vertprog = &blitter->vp;
  850.    nv50->gmtyprog = NULL;
  851.    nv50->fragprog = ctx->fp;
  852.  
  853.    for (s = 0; s < 3; ++s) {
  854.       ctx->saved.num_textures[s] = nv50->num_textures[s];
  855.       ctx->saved.num_samplers[s] = nv50->num_samplers[s];
  856.    }
  857.    ctx->saved.texture[0] = nv50->textures[2][0];
  858.    ctx->saved.texture[1] = nv50->textures[2][1];
  859.    ctx->saved.sampler[0] = nv50->samplers[2][0];
  860.    ctx->saved.sampler[1] = nv50->samplers[2][1];
  861.  
  862.    nv50->samplers[2][0] = &blitter->sampler[ctx->filter];
  863.    nv50->samplers[2][1] = &blitter->sampler[ctx->filter];
  864.  
  865.    nv50->num_samplers[0] = nv50->num_samplers[1] = 0;
  866.    nv50->num_samplers[2] = 2;
  867.  
  868.    ctx->saved.dirty = nv50->dirty;
  869.  
  870.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
  871.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
  872.  
  873.    nv50->dirty =
  874.       NV50_NEW_FRAMEBUFFER |
  875.       NV50_NEW_VERTPROG | NV50_NEW_FRAGPROG | NV50_NEW_GMTYPROG |
  876.       NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS;
  877. }
  878.  
  879. static void
  880. nv50_blitctx_post_blit(struct nv50_blitctx *blit)
  881. {
  882.    struct nv50_context *nv50 = blit->nv50;
  883.    int s;
  884.  
  885.    pipe_surface_reference(&nv50->framebuffer.cbufs[0], NULL);
  886.  
  887.    nv50->framebuffer.width = blit->saved.fb.width;
  888.    nv50->framebuffer.height = blit->saved.fb.height;
  889.    nv50->framebuffer.nr_cbufs = blit->saved.fb.nr_cbufs;
  890.    nv50->framebuffer.cbufs[0] = blit->saved.fb.cbufs[0];
  891.    nv50->framebuffer.zsbuf = blit->saved.fb.zsbuf;
  892.  
  893.    nv50->rast = blit->saved.rast;
  894.  
  895.    nv50->vertprog = blit->saved.vp;
  896.    nv50->gmtyprog = blit->saved.gp;
  897.    nv50->fragprog = blit->saved.fp;
  898.  
  899.    pipe_sampler_view_reference(&nv50->textures[2][0], NULL);
  900.    pipe_sampler_view_reference(&nv50->textures[2][1], NULL);
  901.  
  902.    for (s = 0; s < 3; ++s) {
  903.       nv50->num_textures[s] = blit->saved.num_textures[s];
  904.       nv50->num_samplers[s] = blit->saved.num_samplers[s];
  905.    }
  906.    nv50->textures[2][0] = blit->saved.texture[0];
  907.    nv50->textures[2][1] = blit->saved.texture[1];
  908.    nv50->samplers[2][0] = blit->saved.sampler[0];
  909.    nv50->samplers[2][1] = blit->saved.sampler[1];
  910.  
  911.    if (nv50->cond_query)
  912.       nv50->base.pipe.render_condition(&nv50->base.pipe, nv50->cond_query,
  913.                                        nv50->cond_cond, nv50->cond_mode);
  914.  
  915.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
  916.    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
  917.  
  918.    nv50->dirty = blit->saved.dirty |
  919.       (NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR | NV50_NEW_SAMPLE_MASK |
  920.        NV50_NEW_RASTERIZER | NV50_NEW_ZSA | NV50_NEW_BLEND |
  921.        NV50_NEW_TEXTURES | NV50_NEW_SAMPLERS |
  922.        NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG | NV50_NEW_FRAGPROG);
  923. }
  924.  
  925.  
  926. static void
  927. nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
  928. {
  929.    struct nv50_blitctx *blit = nv50->blit;
  930.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  931.    struct pipe_resource *src = info->src.resource;
  932.    struct pipe_resource *dst = info->dst.resource;
  933.    int32_t minx, maxx, miny, maxy;
  934.    int32_t i;
  935.    float x0, x1, y0, y1, z;
  936.    float dz;
  937.    float x_range, y_range;
  938.  
  939.    blit->mode = nv50_blit_select_mode(info);
  940.    blit->color_mask = nv50_blit_derive_color_mask(info);
  941.    blit->filter = nv50_blit_get_filter(info);
  942.  
  943.    nv50_blit_select_fp(blit, info);
  944.    nv50_blitctx_pre_blit(blit);
  945.  
  946.    nv50_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format);
  947.    nv50_blit_set_src(blit, src, info->src.level, -1, info->src.format,
  948.                      blit->filter);
  949.  
  950.    nv50_blitctx_prepare_state(blit);
  951.  
  952.    nv50_state_validate(nv50, ~0, 36);
  953.  
  954.    x_range = (float)info->src.box.width / (float)info->dst.box.width;
  955.    y_range = (float)info->src.box.height / (float)info->dst.box.height;
  956.  
  957.    x0 = (float)info->src.box.x - x_range * (float)info->dst.box.x;
  958.    y0 = (float)info->src.box.y - y_range * (float)info->dst.box.y;
  959.  
  960.    x1 = x0 + 16384.0f * x_range;
  961.    y1 = y0 + 16384.0f * y_range;
  962.  
  963.    x0 *= (float)(1 << nv50_miptree(src)->ms_x);
  964.    x1 *= (float)(1 << nv50_miptree(src)->ms_x);
  965.    y0 *= (float)(1 << nv50_miptree(src)->ms_y);
  966.    y1 *= (float)(1 << nv50_miptree(src)->ms_y);
  967.  
  968.    if (src->last_level > 0) {
  969.       /* If there are mip maps, GPU always assumes normalized coordinates. */
  970.       const unsigned l = info->src.level;
  971.       const float fh = u_minify(src->width0 << nv50_miptree(src)->ms_x, l);
  972.       const float fv = u_minify(src->height0 << nv50_miptree(src)->ms_y, l);
  973.       x0 /= fh;
  974.       x1 /= fh;
  975.       y0 /= fv;
  976.       y1 /= fv;
  977.    }
  978.  
  979.    /* XXX: multiply by 6 for cube arrays ? */
  980.    dz = (float)info->src.box.depth / (float)info->dst.box.depth;
  981.    z = (float)info->src.box.z;
  982.    if (nv50_miptree(src)->layout_3d)
  983.       z += 0.5f * dz;
  984.  
  985.    BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
  986.    PUSH_DATA (push, 0);
  987.    BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
  988.    PUSH_DATA (push, 0x1);
  989.  
  990.    /* Draw a large triangle in screen coordinates covering the whole
  991.     * render target, with scissors defining the destination region.
  992.     * The vertex is supplied with non-normalized texture coordinates
  993.     * arranged in a way to yield the desired offset and scale.
  994.     */
  995.  
  996.    minx = info->dst.box.x;
  997.    maxx = info->dst.box.x + info->dst.box.width;
  998.    miny = info->dst.box.y;
  999.    maxy = info->dst.box.y + info->dst.box.height;
  1000.    if (info->scissor_enable) {
  1001.       minx = MAX2(minx, info->scissor.minx);
  1002.       maxx = MIN2(maxx, info->scissor.maxx);
  1003.       miny = MAX2(miny, info->scissor.miny);
  1004.       maxy = MIN2(maxy, info->scissor.maxy);
  1005.    }
  1006.    BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
  1007.    PUSH_DATA (push, (maxx << 16) | minx);
  1008.    PUSH_DATA (push, (maxy << 16) | miny);
  1009.  
  1010.    for (i = 0; i < info->dst.box.depth; ++i, z += dz) {
  1011.       if (info->dst.box.z + i) {
  1012.          BEGIN_NV04(push, NV50_3D(LAYER), 1);
  1013.          PUSH_DATA (push, info->dst.box.z + i);
  1014.       }
  1015.       PUSH_SPACE(push, 32);
  1016.       BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
  1017.       PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
  1018.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
  1019.       PUSH_DATAf(push, x0);
  1020.       PUSH_DATAf(push, y0);
  1021.       PUSH_DATAf(push, z);
  1022.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
  1023.       PUSH_DATAf(push, 0.0f);
  1024.       PUSH_DATAf(push, 0.0f);
  1025.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
  1026.       PUSH_DATAf(push, x1);
  1027.       PUSH_DATAf(push, y0);
  1028.       PUSH_DATAf(push, z);
  1029.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
  1030.       PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
  1031.       PUSH_DATAf(push, 0.0f);
  1032.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
  1033.       PUSH_DATAf(push, x0);
  1034.       PUSH_DATAf(push, y1);
  1035.       PUSH_DATAf(push, z);
  1036.       BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
  1037.       PUSH_DATAf(push, 0.0f);
  1038.       PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
  1039.       BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
  1040.       PUSH_DATA (push, 0);
  1041.    }
  1042.    if (info->dst.box.z + info->dst.box.depth - 1) {
  1043.       BEGIN_NV04(push, NV50_3D(LAYER), 1);
  1044.       PUSH_DATA (push, 0);
  1045.    }
  1046.  
  1047.    /* re-enable normally constant state */
  1048.  
  1049.    BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
  1050.    PUSH_DATA (push, 1);
  1051.  
  1052.    nv50_blitctx_post_blit(blit);
  1053. }
  1054.  
  1055. static void
  1056. nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
  1057. {
  1058.    struct nouveau_pushbuf *push = nv50->base.pushbuf;
  1059.    struct nv50_miptree *dst = nv50_miptree(info->dst.resource);
  1060.    struct nv50_miptree *src = nv50_miptree(info->src.resource);
  1061.    const int32_t srcx_adj = info->src.box.width < 0 ? -1 : 0;
  1062.    const int32_t srcy_adj = info->src.box.height < 0 ? -1 : 0;
  1063.    const int32_t dz = info->dst.box.z;
  1064.    const int32_t sz = info->src.box.z;
  1065.    uint32_t dstw, dsth;
  1066.    int32_t dstx, dsty;
  1067.    int64_t srcx, srcy;
  1068.    int64_t du_dx, dv_dy;
  1069.    int i;
  1070.    uint32_t mode;
  1071.    uint32_t mask = nv50_blit_eng2d_get_mask(info);
  1072.    boolean b;
  1073.  
  1074.    mode = nv50_blit_get_filter(info) ?
  1075.       NV50_2D_BLIT_CONTROL_FILTER_BILINEAR :
  1076.       NV50_2D_BLIT_CONTROL_FILTER_POINT_SAMPLE;
  1077.    mode |= (src->base.base.nr_samples > dst->base.base.nr_samples) ?
  1078.       NV50_2D_BLIT_CONTROL_ORIGIN_CORNER : NV50_2D_BLIT_CONTROL_ORIGIN_CENTER;
  1079.  
  1080.    du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width;
  1081.    dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height;
  1082.  
  1083.    b = info->dst.format == info->src.format;
  1084.    nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b);
  1085.    nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b);
  1086.  
  1087.    if (info->scissor_enable) {
  1088.       BEGIN_NV04(push, NV50_2D(CLIP_X), 5);
  1089.       PUSH_DATA (push, info->scissor.minx << dst->ms_x);
  1090.       PUSH_DATA (push, info->scissor.miny << dst->ms_y);
  1091.       PUSH_DATA (push, (info->scissor.maxx - info->scissor.minx) << dst->ms_x);
  1092.       PUSH_DATA (push, (info->scissor.maxy - info->scissor.miny) << dst->ms_y);
  1093.       PUSH_DATA (push, 1); /* enable */
  1094.    }
  1095.  
  1096.    if (mask != 0xffffffff) {
  1097.       BEGIN_NV04(push, NV50_2D(ROP), 1);
  1098.       PUSH_DATA (push, 0xca); /* DPSDxax */
  1099.       BEGIN_NV04(push, NV50_2D(PATTERN_COLOR_FORMAT), 1);
  1100.       PUSH_DATA (push, NV50_2D_PATTERN_COLOR_FORMAT_32BPP);
  1101.       BEGIN_NV04(push, NV50_2D(PATTERN_COLOR(0)), 4);
  1102.       PUSH_DATA (push, 0x00000000);
  1103.       PUSH_DATA (push, mask);
  1104.       PUSH_DATA (push, 0xffffffff);
  1105.       PUSH_DATA (push, 0xffffffff);
  1106.       BEGIN_NV04(push, NV50_2D(OPERATION), 1);
  1107.       PUSH_DATA (push, NV50_2D_OPERATION_ROP);
  1108.    } else
  1109.    if (info->src.format != info->dst.format) {
  1110.       if (info->src.format == PIPE_FORMAT_R8_UNORM ||
  1111.           info->src.format == PIPE_FORMAT_R16_UNORM ||
  1112.           info->src.format == PIPE_FORMAT_R16_FLOAT ||
  1113.           info->src.format == PIPE_FORMAT_R32_FLOAT) {
  1114.          mask = 0xffff0000; /* also makes condition for OPERATION reset true */
  1115.          BEGIN_NV04(push, NV50_2D(BETA4), 2);
  1116.          PUSH_DATA (push, mask);
  1117.          PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY_PREMULT);
  1118.       }
  1119.    }
  1120.  
  1121.    if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) {
  1122.       /* ms_x is always >= ms_y */
  1123.       du_dx <<= src->ms_x - dst->ms_x;
  1124.       dv_dy <<= src->ms_y - dst->ms_y;
  1125.    } else {
  1126.       du_dx >>= dst->ms_x - src->ms_x;
  1127.       dv_dy >>= dst->ms_y - src->ms_y;
  1128.    }
  1129.  
  1130.    srcx = (int64_t)(info->src.box.x + srcx_adj) << (src->ms_x + 32);
  1131.    srcy = (int64_t)(info->src.box.y + srcy_adj) << (src->ms_y + 32);
  1132.  
  1133.    if (src->base.base.nr_samples > dst->base.base.nr_samples) {
  1134.       /* center src coorinates for proper MS resolve filtering */
  1135.       srcx += (int64_t)src->ms_x << 32;
  1136.       srcy += (int64_t)src->ms_y << 32;
  1137.    }
  1138.  
  1139.    dstx = info->dst.box.x << dst->ms_x;
  1140.    dsty = info->dst.box.y << dst->ms_y;
  1141.  
  1142.    dstw = info->dst.box.width << dst->ms_x;
  1143.    dsth = info->dst.box.height << dst->ms_y;
  1144.  
  1145.    if (dstx < 0) {
  1146.       dstw += dstx;
  1147.       srcx -= du_dx * dstx;
  1148.       dstx = 0;
  1149.    }
  1150.    if (dsty < 0) {
  1151.       dsth += dsty;
  1152.       srcy -= dv_dy * dsty;
  1153.       dsty = 0;
  1154.    }
  1155.  
  1156.    BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
  1157.    PUSH_DATA (push, mode);
  1158.    BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4);
  1159.    PUSH_DATA (push, dstx);
  1160.    PUSH_DATA (push, dsty);
  1161.    PUSH_DATA (push, dstw);
  1162.    PUSH_DATA (push, dsth);
  1163.    BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
  1164.    PUSH_DATA (push, du_dx);
  1165.    PUSH_DATA (push, du_dx >> 32);
  1166.    PUSH_DATA (push, dv_dy);
  1167.    PUSH_DATA (push, dv_dy >> 32);
  1168.  
  1169.    BCTX_REFN(nv50->bufctx, 2D, &dst->base, WR);
  1170.    BCTX_REFN(nv50->bufctx, 2D, &src->base, RD);
  1171.    nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
  1172.    if (nouveau_pushbuf_validate(nv50->base.pushbuf))
  1173.       return;
  1174.  
  1175.    for (i = 0; i < info->dst.box.depth; ++i) {
  1176.       if (i > 0) {
  1177.          /* no scaling in z-direction possible for eng2d blits */
  1178.          if (dst->layout_3d) {
  1179.             BEGIN_NV04(push, NV50_2D(DST_LAYER), 1);
  1180.             PUSH_DATA (push, info->dst.box.z + i);
  1181.          } else {
  1182.             const unsigned z = info->dst.box.z + i;
  1183.             BEGIN_NV04(push, NV50_2D(DST_ADDRESS_HIGH), 2);
  1184.             PUSH_DATAh(push, dst->base.address + z * dst->layer_stride);
  1185.             PUSH_DATA (push, dst->base.address + z * dst->layer_stride);
  1186.          }
  1187.          if (src->layout_3d) {
  1188.             /* not possible because of depth tiling */
  1189.             assert(0);
  1190.          } else {
  1191.             const unsigned z = info->src.box.z + i;
  1192.             BEGIN_NV04(push, NV50_2D(SRC_ADDRESS_HIGH), 2);
  1193.             PUSH_DATAh(push, src->base.address + z * src->layer_stride);
  1194.             PUSH_DATA (push, src->base.address + z * src->layer_stride);
  1195.          }
  1196.          BEGIN_NV04(push, NV50_2D(BLIT_SRC_Y_INT), 1); /* trigger */
  1197.          PUSH_DATA (push, srcy >> 32);
  1198.       } else {
  1199.          BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4);
  1200.          PUSH_DATA (push, srcx);
  1201.          PUSH_DATA (push, srcx >> 32);
  1202.          PUSH_DATA (push, srcy);
  1203.          PUSH_DATA (push, srcy >> 32);
  1204.       }
  1205.    }
  1206.    nv50_bufctx_fence(nv50->bufctx, FALSE);
  1207.  
  1208.    nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
  1209.  
  1210.    if (info->scissor_enable) {
  1211.       BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
  1212.       PUSH_DATA (push, 0);
  1213.    }
  1214.    if (mask != 0xffffffff) {
  1215.       BEGIN_NV04(push, NV50_2D(OPERATION), 1);
  1216.       PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
  1217.    }
  1218. }
  1219.  
  1220. static void
  1221. nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
  1222. {
  1223.    struct nv50_context *nv50 = nv50_context(pipe);
  1224.    boolean eng3d = FALSE;
  1225.  
  1226.    if (util_format_is_depth_or_stencil(info->dst.resource->format)) {
  1227.       if (!(info->mask & PIPE_MASK_ZS))
  1228.          return;
  1229.       if (info->dst.resource->format == PIPE_FORMAT_Z32_FLOAT ||
  1230.           info->dst.resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
  1231.          eng3d = TRUE;
  1232.       if (info->filter != PIPE_TEX_FILTER_NEAREST)
  1233.          eng3d = TRUE;
  1234.    } else {
  1235.       if (!(info->mask & PIPE_MASK_RGBA))
  1236.          return;
  1237.       if (info->mask != PIPE_MASK_RGBA)
  1238.          eng3d = TRUE;
  1239.    }
  1240.  
  1241.    if (nv50_miptree(info->src.resource)->layout_3d) {
  1242.       eng3d = TRUE;
  1243.    } else
  1244.    if (info->src.box.depth != info->dst.box.depth) {
  1245.       eng3d = TRUE;
  1246.       debug_printf("blit: cannot filter array or cube textures in z direction");
  1247.    }
  1248.  
  1249.    if (!eng3d && info->dst.format != info->src.format) {
  1250.       if (!nv50_2d_dst_format_faithful(info->dst.format) ||
  1251.           !nv50_2d_src_format_faithful(info->src.format)) {
  1252.          eng3d = TRUE;
  1253.       } else
  1254.       if (!nv50_2d_src_format_faithful(info->src.format)) {
  1255.          if (!util_format_is_luminance(info->src.format)) {
  1256.             if (util_format_is_intensity(info->src.format))
  1257.                eng3d = TRUE;
  1258.             else
  1259.             if (!nv50_2d_dst_format_ops_supported(info->dst.format))
  1260.                eng3d = TRUE;
  1261.             else
  1262.                eng3d = !nv50_2d_format_supported(info->src.format);
  1263.          }
  1264.       } else
  1265.       if (util_format_is_luminance_alpha(info->src.format))
  1266.          eng3d = TRUE;
  1267.    }
  1268.  
  1269.    if (info->src.resource->nr_samples == 8 &&
  1270.        info->dst.resource->nr_samples <= 1)
  1271.       eng3d = TRUE;
  1272.  
  1273.    /* FIXME: can't make this work with eng2d anymore */
  1274.    if (info->src.resource->nr_samples > 1 ||
  1275.        info->dst.resource->nr_samples > 1)
  1276.       eng3d = TRUE;
  1277.  
  1278.    /* FIXME: find correct src coordinate adjustments */
  1279.    if ((info->src.box.width !=  info->dst.box.width &&
  1280.         info->src.box.width != -info->dst.box.width) ||
  1281.        (info->src.box.height !=  info->dst.box.height &&
  1282.         info->src.box.height != -info->dst.box.height))
  1283.       eng3d = TRUE;
  1284.  
  1285.    if (!eng3d)
  1286.       nv50_blit_eng2d(nv50, info);
  1287.    else
  1288.       nv50_blit_3d(nv50, info);
  1289. }
  1290.  
  1291. boolean
  1292. nv50_blitter_create(struct nv50_screen *screen)
  1293. {
  1294.    screen->blitter = CALLOC_STRUCT(nv50_blitter);
  1295.    if (!screen->blitter) {
  1296.       NOUVEAU_ERR("failed to allocate blitter struct\n");
  1297.       return FALSE;
  1298.    }
  1299.  
  1300.    pipe_mutex_init(screen->blitter->mutex);
  1301.  
  1302.    nv50_blitter_make_vp(screen->blitter);
  1303.    nv50_blitter_make_sampler(screen->blitter);
  1304.  
  1305.    return TRUE;
  1306. }
  1307.  
  1308. void
  1309. nv50_blitter_destroy(struct nv50_screen *screen)
  1310. {
  1311.    struct nv50_blitter *blitter = screen->blitter;
  1312.    unsigned i, m;
  1313.  
  1314.    for (i = 0; i < NV50_BLIT_MAX_TEXTURE_TYPES; ++i) {
  1315.       for (m = 0; m < NV50_BLIT_MODES; ++m) {
  1316.          struct nv50_program *prog = blitter->fp[i][m];
  1317.          if (prog) {
  1318.             nv50_program_destroy(NULL, prog);
  1319.             FREE((void *)prog->pipe.tokens);
  1320.             FREE(prog);
  1321.          }
  1322.       }
  1323.    }
  1324.  
  1325.    FREE(blitter);
  1326. }
  1327.  
  1328. boolean
  1329. nv50_blitctx_create(struct nv50_context *nv50)
  1330. {
  1331.    nv50->blit = CALLOC_STRUCT(nv50_blitctx);
  1332.    if (!nv50->blit) {
  1333.       NOUVEAU_ERR("failed to allocate blit context\n");
  1334.       return FALSE;
  1335.    }
  1336.  
  1337.    nv50->blit->nv50 = nv50;
  1338.  
  1339.    nv50->blit->rast.pipe.half_pixel_center = 1;
  1340.  
  1341.    return TRUE;
  1342. }
  1343.  
  1344. void
  1345. nv50_init_surface_functions(struct nv50_context *nv50)
  1346. {
  1347.    struct pipe_context *pipe = &nv50->base.pipe;
  1348.  
  1349.    pipe->resource_copy_region = nv50_resource_copy_region;
  1350.    pipe->blit = nv50_blit;
  1351.    pipe->clear_render_target = nv50_clear_render_target;
  1352.    pipe->clear_depth_stencil = nv50_clear_depth_stencil;
  1353. }
  1354.  
  1355.  
  1356.