Home | History | Annotate | Download | only in nvc0
      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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20  * 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 "nvc0_context.h"
     33 #include "nvc0_resource.h"
     34 
     35 #include "nv50/nv50_defs.xml.h"
     36 #include "nv50/nv50_texture.xml.h"
     37 
     38 #define NVC0_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL
     39 
     40 /* return TRUE for formats that can be converted among each other by NVC0_2D */
     41 static INLINE boolean
     42 nvc0_2d_format_faithful(enum pipe_format format)
     43 {
     44    uint8_t id = nvc0_format_table[format].rt;
     45 
     46    return (id >= 0xc0) && (NVC0_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
     47 }
     48 
     49 static INLINE uint8_t
     50 nvc0_2d_format(enum pipe_format format)
     51 {
     52    uint8_t id = nvc0_format_table[format].rt;
     53 
     54    /* Hardware values for color formats range from 0xc0 to 0xff,
     55     * but the 2D engine doesn't support all of them.
     56     */
     57    if (nvc0_2d_format_faithful(format))
     58       return id;
     59 
     60    switch (util_format_get_blocksize(format)) {
     61    case 1:
     62       return NV50_SURFACE_FORMAT_R8_UNORM;
     63    case 2:
     64       return NV50_SURFACE_FORMAT_R16_UNORM;
     65    case 4:
     66       return NV50_SURFACE_FORMAT_BGRA8_UNORM;
     67    case 8:
     68       return NV50_SURFACE_FORMAT_RGBA16_UNORM;
     69    case 16:
     70       return NV50_SURFACE_FORMAT_RGBA32_FLOAT;
     71    default:
     72       return 0;
     73    }
     74 }
     75 
     76 static int
     77 nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst,
     78                     struct nv50_miptree *mt, unsigned level, unsigned layer)
     79 {
     80    struct nouveau_bo *bo = mt->base.bo;
     81    uint32_t width, height, depth;
     82    uint32_t format;
     83    uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
     84    uint32_t offset = mt->level[level].offset;
     85 
     86    format = nvc0_2d_format(mt->base.base.format);
     87    if (!format) {
     88       NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
     89                   util_format_name(mt->base.base.format));
     90       return 1;
     91    }
     92 
     93    width = u_minify(mt->base.base.width0, level) << mt->ms_x;
     94    height = u_minify(mt->base.base.height0, level) << mt->ms_y;
     95    depth = u_minify(mt->base.base.depth0, level);
     96 
     97    /* layer has to be < depth, and depth > tile depth / 2 */
     98 
     99    if (!mt->layout_3d) {
    100       offset += mt->layer_stride * layer;
    101       layer = 0;
    102       depth = 1;
    103    } else
    104    if (!dst) {
    105       offset += nvc0_mt_zslice_offset(mt, level, layer);
    106       layer = 0;
    107    }
    108 
    109    if (nouveau_bo_memtype(bo)) {
    110       BEGIN_NVC0(push, SUBC_2D(mthd), 2);
    111       PUSH_DATA (push, format);
    112       PUSH_DATA (push, 1);
    113       BEGIN_NVC0(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_NVC0(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_NVC0(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_NVC0(push, SUBC_2D(NVC0_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 nvc0_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    static const uint32_t duvdxy[5] =
    154    {
    155       0x40000000, 0x80000000, 0x00000001, 0x00000002, 0x00000004
    156    };
    157 
    158    int ret;
    159    uint32_t ctrl = 0x00;
    160 
    161    ret = PUSH_SPACE(push, 2 * 16 + 32);
    162    if (ret)
    163       return ret;
    164 
    165    ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz);
    166    if (ret)
    167       return ret;
    168 
    169    ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz);
    170    if (ret)
    171       return ret;
    172 
    173    /* NOTE: 2D engine doesn't work for MS8 */
    174    if (src->ms_x)
    175       ctrl = 0x11;
    176 
    177    /* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */
    178    BEGIN_NVC0(push, NVC0_2D(BLIT_CONTROL), 1);
    179    PUSH_DATA (push, ctrl);
    180    BEGIN_NVC0(push, NVC0_2D(BLIT_DST_X), 4);
    181    PUSH_DATA (push, dx << dst->ms_x);
    182    PUSH_DATA (push, dy << dst->ms_y);
    183    PUSH_DATA (push, w << dst->ms_x);
    184    PUSH_DATA (push, h << dst->ms_y);
    185    BEGIN_NVC0(push, NVC0_2D(BLIT_DU_DX_FRACT), 4);
    186    PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
    187    PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
    188    PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
    189    PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
    190    BEGIN_NVC0(push, NVC0_2D(BLIT_SRC_X_FRACT), 4);
    191    PUSH_DATA (push, 0);
    192    PUSH_DATA (push, sx << src->ms_x);
    193    PUSH_DATA (push, 0);
    194    PUSH_DATA (push, sy << src->ms_x);
    195 
    196    return 0;
    197 }
    198 
    199 static void
    200 nvc0_resource_copy_region(struct pipe_context *pipe,
    201                           struct pipe_resource *dst, unsigned dst_level,
    202                           unsigned dstx, unsigned dsty, unsigned dstz,
    203                           struct pipe_resource *src, unsigned src_level,
    204                           const struct pipe_box *src_box)
    205 {
    206    struct nvc0_context *nvc0 = nvc0_context(pipe);
    207    int ret;
    208    boolean m2mf;
    209    unsigned dst_layer = dstz, src_layer = src_box->z;
    210 
    211    /* Fallback for buffers. */
    212    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
    213       util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
    214                                 src, src_level, src_box);
    215       return;
    216    }
    217 
    218    /* 0 and 1 are equal, only supporting 0/1, 2, 4 and 8 */
    219    assert((src->nr_samples | 1) == (dst->nr_samples | 1));
    220 
    221    m2mf = (src->format == dst->format) ||
    222       (util_format_get_blocksizebits(src->format) ==
    223        util_format_get_blocksizebits(dst->format));
    224 
    225    nv04_resource(dst)->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
    226 
    227    if (m2mf) {
    228       struct nv50_m2mf_rect drect, srect;
    229       unsigned i;
    230       unsigned nx = util_format_get_nblocksx(src->format, src_box->width);
    231       unsigned ny = util_format_get_nblocksy(src->format, src_box->height);
    232 
    233       nv50_m2mf_rect_setup(&drect, dst, dst_level, dstx, dsty, dstz);
    234       nv50_m2mf_rect_setup(&srect, src, src_level,
    235                            src_box->x, src_box->y, src_box->z);
    236 
    237       for (i = 0; i < src_box->depth; ++i) {
    238          nvc0->m2mf_copy_rect(nvc0, &drect, &srect, nx, ny);
    239 
    240          if (nv50_miptree(dst)->layout_3d)
    241             drect.z++;
    242          else
    243             drect.base += nv50_miptree(dst)->layer_stride;
    244 
    245          if (nv50_miptree(src)->layout_3d)
    246             srect.z++;
    247          else
    248             srect.base += nv50_miptree(src)->layer_stride;
    249       }
    250       return;
    251    }
    252 
    253    assert(nvc0_2d_format_faithful(src->format));
    254    assert(nvc0_2d_format_faithful(dst->format));
    255 
    256    BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
    257    BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
    258    nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
    259    nouveau_pushbuf_validate(nvc0->base.pushbuf);
    260 
    261    for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
    262       ret = nvc0_2d_texture_do_copy(nvc0->base.pushbuf,
    263                                     nv50_miptree(dst), dst_level,
    264                                     dstx, dsty, dst_layer,
    265                                     nv50_miptree(src), src_level,
    266                                     src_box->x, src_box->y, src_layer,
    267                                     src_box->width, src_box->height);
    268       if (ret)
    269          break;
    270    }
    271    nouveau_bufctx_reset(nvc0->bufctx, 0);
    272 }
    273 
    274 static void
    275 nvc0_clear_render_target(struct pipe_context *pipe,
    276                          struct pipe_surface *dst,
    277                          const union pipe_color_union *color,
    278                          unsigned dstx, unsigned dsty,
    279                          unsigned width, unsigned height)
    280 {
    281    struct nvc0_context *nvc0 = nvc0_context(pipe);
    282    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    283    struct nv50_surface *sf = nv50_surface(dst);
    284    struct nv04_resource *res = nv04_resource(sf->base.texture);
    285    unsigned z;
    286 
    287    BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
    288    PUSH_DATAf(push, color->f[0]);
    289    PUSH_DATAf(push, color->f[1]);
    290    PUSH_DATAf(push, color->f[2]);
    291    PUSH_DATAf(push, color->f[3]);
    292 
    293    BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
    294    PUSH_DATA (push, ( width << 16) | dstx);
    295    PUSH_DATA (push, (height << 16) | dsty);
    296 
    297    BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
    298    PUSH_DATA (push, 1);
    299    BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9);
    300    PUSH_DATAh(push, res->address + sf->offset);
    301    PUSH_DATA (push, res->address + sf->offset);
    302    if (likely(nouveau_bo_memtype(res->bo))) {
    303       struct nv50_miptree *mt = nv50_miptree(dst->texture);
    304 
    305       PUSH_DATA(push, sf->width);
    306       PUSH_DATA(push, sf->height);
    307       PUSH_DATA(push, nvc0_format_table[dst->format].rt);
    308       PUSH_DATA(push, (mt->layout_3d << 16) |
    309                mt->level[sf->base.u.tex.level].tile_mode);
    310       PUSH_DATA(push, dst->u.tex.first_layer + sf->depth);
    311       PUSH_DATA(push, mt->layer_stride >> 2);
    312       PUSH_DATA(push, dst->u.tex.first_layer);
    313    } else {
    314       if (res->base.target == PIPE_BUFFER) {
    315          PUSH_DATA(push, 262144);
    316          PUSH_DATA(push, 1);
    317       } else {
    318          PUSH_DATA(push, nv50_miptree(&res->base)->level[0].pitch);
    319          PUSH_DATA(push, sf->height);
    320       }
    321       PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
    322       PUSH_DATA(push, 1 << 12);
    323       PUSH_DATA(push, 1);
    324       PUSH_DATA(push, 0);
    325       PUSH_DATA(push, 0);
    326 
    327       IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);
    328 
    329       /* tiled textures don't have to be fenced, they're not mapped directly */
    330       nvc0_resource_fence(res, NOUVEAU_BO_WR);
    331    }
    332 
    333    for (z = 0; z < sf->depth; ++z) {
    334       BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
    335       PUSH_DATA (push, 0x3c |
    336                  (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
    337    }
    338 
    339    nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
    340 }
    341 
    342 static void
    343 nvc0_clear_depth_stencil(struct pipe_context *pipe,
    344                          struct pipe_surface *dst,
    345                          unsigned clear_flags,
    346                          double depth,
    347                          unsigned stencil,
    348                          unsigned dstx, unsigned dsty,
    349                          unsigned width, unsigned height)
    350 {
    351 	struct nvc0_context *nvc0 = nvc0_context(pipe);
    352 	struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    353 	struct nv50_miptree *mt = nv50_miptree(dst->texture);
    354 	struct nv50_surface *sf = nv50_surface(dst);
    355 	uint32_t mode = 0;
    356 	int unk = mt->base.base.target == PIPE_TEXTURE_2D;
    357 	unsigned z;
    358 
    359 	if (clear_flags & PIPE_CLEAR_DEPTH) {
    360 		BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
    361 		PUSH_DATAf(push, depth);
    362 		mode |= NVC0_3D_CLEAR_BUFFERS_Z;
    363 	}
    364 
    365 	if (clear_flags & PIPE_CLEAR_STENCIL) {
    366 		BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
    367 		PUSH_DATA (push, stencil & 0xff);
    368 		mode |= NVC0_3D_CLEAR_BUFFERS_S;
    369 	}
    370 
    371 	BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
    372 	PUSH_DATA (push, ( width << 16) | dstx);
    373 	PUSH_DATA (push, (height << 16) | dsty);
    374 
    375 	BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
    376 	PUSH_DATAh(push, mt->base.address + sf->offset);
    377 	PUSH_DATA (push, mt->base.address + sf->offset);
    378 	PUSH_DATA (push, nvc0_format_table[dst->format].rt);
    379 	PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
    380 	PUSH_DATA (push, mt->layer_stride >> 2);
    381 	BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
    382 	PUSH_DATA (push, 1);
    383 	BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
    384 	PUSH_DATA (push, sf->width);
    385 	PUSH_DATA (push, sf->height);
    386 	PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
    387 	BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
    388 	PUSH_DATA (push, dst->u.tex.first_layer);
    389 
    390 	for (z = 0; z < sf->depth; ++z) {
    391 		BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
    392 		PUSH_DATA (push, mode |
    393 			   (z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
    394 	}
    395 
    396 	nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
    397 }
    398 
    399 void
    400 nvc0_clear(struct pipe_context *pipe, unsigned buffers,
    401            const union pipe_color_union *color,
    402            double depth, unsigned stencil)
    403 {
    404    struct nvc0_context *nvc0 = nvc0_context(pipe);
    405    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    406    struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
    407    unsigned i;
    408    uint32_t mode = 0;
    409 
    410    /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
    411    if (!nvc0_state_validate(nvc0, NVC0_NEW_FRAMEBUFFER, 9 + (fb->nr_cbufs * 2)))
    412       return;
    413 
    414    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
    415       BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
    416       PUSH_DATAf(push, color->f[0]);
    417       PUSH_DATAf(push, color->f[1]);
    418       PUSH_DATAf(push, color->f[2]);
    419       PUSH_DATAf(push, color->f[3]);
    420       mode =
    421          NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G |
    422          NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A;
    423    }
    424 
    425    if (buffers & PIPE_CLEAR_DEPTH) {
    426       BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
    427       PUSH_DATA (push, fui(depth));
    428       mode |= NVC0_3D_CLEAR_BUFFERS_Z;
    429    }
    430 
    431    if (buffers & PIPE_CLEAR_STENCIL) {
    432       BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
    433       PUSH_DATA (push, stencil & 0xff);
    434       mode |= NVC0_3D_CLEAR_BUFFERS_S;
    435    }
    436 
    437    BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
    438    PUSH_DATA (push, mode);
    439 
    440    for (i = 1; i < fb->nr_cbufs; i++) {
    441       BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
    442       PUSH_DATA (push, (i << 6) | 0x3c);
    443    }
    444 }
    445 
    446 
    447 struct nvc0_blitctx
    448 {
    449    struct nvc0_screen *screen;
    450    struct {
    451       struct pipe_framebuffer_state fb;
    452       struct nvc0_program *vp;
    453       struct nvc0_program *tcp;
    454       struct nvc0_program *tep;
    455       struct nvc0_program *gp;
    456       struct nvc0_program *fp;
    457       unsigned num_textures[5];
    458       unsigned num_samplers[5];
    459       struct pipe_sampler_view *texture[2];
    460       struct nv50_tsc_entry *sampler[2];
    461       unsigned dirty;
    462    } saved;
    463    struct nvc0_program vp;
    464    struct nvc0_program fp;
    465    struct nv50_tsc_entry sampler[2]; /* nearest, bilinear */
    466    uint32_t fp_offset;
    467    uint16_t color_mask;
    468    uint8_t filter;
    469 };
    470 
    471 static void
    472 nvc0_blitctx_make_vp(struct nvc0_blitctx *blit)
    473 {
    474    static const uint32_t code[] =
    475    {
    476       0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */
    477       0xfff11c26, 0x06000090, /* vfetch b64 { $r4 $r5 } a[0x90]*/
    478       0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */
    479       0x13f01c26, 0x0a7e0080, /* export b64 o[0x80] { $r4 $r5 } */
    480       0x00001de7, 0x80000000, /* exit */
    481    };
    482 
    483    blit->vp.type = PIPE_SHADER_VERTEX;
    484    blit->vp.translated = TRUE;
    485    blit->vp.code = (uint32_t *)code; /* no relocations -> no modification */
    486    blit->vp.code_size = sizeof(code);
    487    blit->vp.max_gpr = 6;
    488    blit->vp.vp.edgeflag = PIPE_MAX_ATTRIBS;
    489 
    490    blit->vp.hdr[0]  = 0x00020461; /* vertprog magic */
    491    blit->vp.hdr[4]  = 0x000ff000; /* no outputs read */
    492    blit->vp.hdr[6]  = 0x0000003f; /* a[0x80], a[0x90] */
    493    blit->vp.hdr[13] = 0x0003f000; /* o[0x70], o[0x80] */
    494 }
    495 
    496 static void
    497 nvc0_blitctx_make_fp(struct nvc0_blitctx *blit)
    498 {
    499    static const uint32_t code_nvc0[] = /* use nvc0dis */
    500    {
    501       /* 2 coords RGBA in, RGBA out, also for Z32_FLOAT(_S8X24_UINT)
    502        * NOTE:
    503        * NVC0 doesn't like tex 3d on non-3d textures, but there should
    504        * only be 2d and 2d-array MS resources anyway.
    505        */
    506       0xfff01c00, 0xc07e0080,
    507       0xfff05c00, 0xc07e0084,
    508       0x00001e86, 0x8013c000,
    509       0x00001de7, 0x80000000,
    510       /* size: 0x70 + padding  */
    511       0, 0, 0, 0,
    512 
    513       /* 2 coords ZS in, S encoded in R, Z encoded in GBA (8_UNORM)
    514        * Setup float outputs in a way that conversion to UNORM yields the
    515        * desired byte value.
    516        */
    517       /* NOTE: need to repeat header */
    518       0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    519       0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000,
    520       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    521       0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000,
    522       0xfff09c00, 0xc07e0080,
    523       0xfff0dc00, 0xc07e0084,
    524       0x00201e86, 0x80104000,
    525       0x00205f06, 0x80104101,
    526       0xfc009c02, 0x312dffff,
    527       0x05001c88,
    528       0x09009e88,
    529       0x04001c02, 0x30ee0202,
    530       0xfc205c02, 0x38000003,
    531       0x0020dc02, 0x3803fc00,
    532       0x00209c02, 0x380003fc,
    533       0x05005c88,
    534       0x0d00dc88,
    535       0x09209e04, 0x18000000,
    536       0x04105c02, 0x30ee0202,
    537       0x0430dc02, 0x30ce0202,
    538       0x04209c02, 0x30de0202,
    539       0x00001de7, 0x80000000,
    540       /* size: 0xd0 + padding */
    541       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    542 
    543       /* 2 coords ZS in, Z encoded in RGB, S encoded in A (U8_UNORM) */
    544       0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    545       0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000,
    546       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    547       0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000,
    548       0xfff09c00, 0xc07e0080,
    549       0xfff0dc00, 0xc07e0084,
    550       0x00201e86, 0x80104000,
    551       0x00205f06, 0x80104101,
    552       0xfc009c02, 0x312dffff,
    553       0x0500dc88,
    554       0x09009e88,
    555       0x0430dc02, 0x30ee0202,
    556       0xfc201c02, 0x38000003,
    557       0x00205c02, 0x380003fc,
    558       0x00209c02, 0x3803fc00,
    559       0x01001c88,
    560       0x05005c88,
    561       0x09209e04, 0x18000000,
    562       0x04001c02, 0x30ee0202,
    563       0x04105c02, 0x30de0202,
    564       0x04209c02, 0x30ce0202,
    565       0x00001de7, 0x80000000,
    566    };
    567    static const uint32_t code_nve4[] = /* use nvc0dis */
    568    {
    569       /* 2 coords RGBA in, RGBA out, also for Z32_FLOAT(_S8X24_UINT)
    570        * NOTE:
    571        * NVC0 doesn't like tex 3d on non-3d textures, but there should
    572        * only be 2d and 2d-array MS resources anyway.
    573        */
    574       0x2202e237, 0x200002ec,
    575       0xfff01c00, 0xc07e0080,
    576       0xfff05c00, 0xc07e0084,
    577       0x00001e86, 0x8013c000,
    578       0x00001de6, 0xf0000000,
    579       0x00001de7, 0x80000000,
    580       /* size: 0x80 */
    581 
    582       /* 2 coords ZS in, S encoded in R, Z encoded in GBA (8_UNORM)
    583        * Setup float outputs in a way that conversion to UNORM yields the
    584        * desired byte value.
    585        */
    586       /* NOTE: need to repeat header */
    587       0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    588       0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000,
    589       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    590       0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000,
    591       0x0202e237, 0x22804c22,
    592       0xfff09c00, 0xc07e0080,
    593       0xfff0dc00, 0xc07e0084,
    594       0x00201e86, 0x80104008,
    595       0x00205f06, 0x80104009,
    596       0x00001de6, 0xf0000000,
    597       0xfc009c02, 0x312dffff,
    598       0x05201e04, 0x18000000,
    599       0x00428047, 0x22020272,
    600       0x09209c84, 0x14000000,
    601       0x04001c02, 0x30ee0202,
    602       0xfc205c02, 0x38000003,
    603       0x0020dc02, 0x3803fc00,
    604       0x00209c02, 0x380003fc,
    605       0x05205e04, 0x18000000,
    606       0x0d20de04, 0x18000000,
    607       0x42004277, 0x200002e0,
    608       0x09209e04, 0x18000000,
    609       0x04105c02, 0x30ee0202,
    610       0x0430dc02, 0x30ce0202,
    611       0x04209c02, 0x30de0202,
    612       0x00001de7, 0x80000000,
    613       /* size: 0x100 */
    614 
    615       /* 2 coords ZS in, Z encoded in RGB, S encoded in A (U8_UNORM) */
    616       0x00021462, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    617       0x80000000, 0x0000000f, 0x00000000, 0x00000000, 0x00000000,
    618       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    619       0x00000000, 0x00000000, 0x00000000, 0x0000000f, 0x00000000,
    620       0x0202e237, 0x22804c22,
    621       0xfff09c00, 0xc07e0080,
    622       0xfff0dc00, 0xc07e0084,
    623       0x00201e86, 0x80104008,
    624       0x00205f06, 0x80104009,
    625       0x00001de6, 0xf0000000,
    626       0xfc009c02, 0x312dffff,
    627       0x0520de04, 0x18000000,
    628       0x00428047, 0x22020272,
    629       0x09209c84, 0x14000000,
    630       0x0430dc02, 0x30ee0202,
    631       0xfc201c02, 0x38000003,
    632       0x00205c02, 0x380003fc,
    633       0x00209c02, 0x3803fc00,
    634       0x01201e04, 0x18000000,
    635       0x05205e04, 0x18000000,
    636       0x42004277, 0x200002e0,
    637       0x09209e04, 0x18000000,
    638       0x04001c02, 0x30ee0202,
    639       0x04105c02, 0x30de0202,
    640       0x04209c02, 0x30ce0202,
    641       0x00001de7, 0x80000000,
    642    };
    643 
    644    blit->fp.type = PIPE_SHADER_FRAGMENT;
    645    blit->fp.translated = TRUE;
    646    if (blit->screen->base.class_3d >= NVE4_3D_CLASS) {
    647       blit->fp.code = (uint32_t *)code_nve4; /* const_cast */
    648       blit->fp.code_size = sizeof(code_nve4);
    649    } else {
    650       blit->fp.code = (uint32_t *)code_nvc0; /* const_cast */
    651       blit->fp.code_size = sizeof(code_nvc0);
    652    }
    653    blit->fp.max_gpr = 4;
    654 
    655    blit->fp.hdr[0]  = 0x00021462; /* fragprog magic */
    656    blit->fp.hdr[5]  = 0x80000000;
    657    blit->fp.hdr[6]  = 0x0000000f; /* 2 linear */
    658    blit->fp.hdr[18] = 0x0000000f; /* 1 colour output */
    659 }
    660 
    661 static void
    662 nvc0_blitctx_make_sampler(struct nvc0_blitctx *blit)
    663 {
    664    /* clamp to edge, min/max lod = 0, nearest filtering */
    665 
    666    blit->sampler[0].id = -1;
    667 
    668    blit->sampler[0].tsc[0] = NV50_TSC_0_SRGB_CONVERSION_ALLOWED |
    669       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPS__SHIFT) |
    670       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPT__SHIFT) |
    671       (NV50_TSC_WRAP_CLAMP_TO_EDGE << NV50_TSC_0_WRAPR__SHIFT);
    672    blit->sampler[0].tsc[1] =
    673       NV50_TSC_1_MAGF_NEAREST | NV50_TSC_1_MINF_NEAREST | NV50_TSC_1_MIPF_NONE;
    674 
    675    /* clamp to edge, min/max lod = 0, bilinear filtering */
    676 
    677    blit->sampler[1].id = -1;
    678 
    679    blit->sampler[1].tsc[0] = blit->sampler[0].tsc[0];
    680    blit->sampler[1].tsc[1] =
    681       NV50_TSC_1_MAGF_LINEAR | NV50_TSC_1_MINF_LINEAR | NV50_TSC_1_MIPF_NONE;
    682 }
    683 
    684 /* Since shaders cannot export stencil, we cannot copy stencil values when
    685  * rendering to ZETA, so we attach the ZS surface to a colour render target.
    686  */
    687 static INLINE enum pipe_format
    688 nvc0_blit_zeta_to_colour_format(enum pipe_format format)
    689 {
    690    switch (format) {
    691    case PIPE_FORMAT_Z16_UNORM:               return PIPE_FORMAT_R16_UNORM;
    692    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    693    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    694    case PIPE_FORMAT_Z24X8_UNORM:             return PIPE_FORMAT_R8G8B8A8_UNORM;
    695    case PIPE_FORMAT_Z32_FLOAT:               return PIPE_FORMAT_R32_FLOAT;
    696    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:    return PIPE_FORMAT_R32G32_FLOAT;
    697    default:
    698       assert(0);
    699       return PIPE_FORMAT_NONE;
    700    }
    701 }
    702 
    703 static void
    704 nvc0_blitctx_get_color_mask_and_fp(struct nvc0_blitctx *blit,
    705                                    enum pipe_format format, uint8_t mask)
    706 {
    707    blit->color_mask = 0;
    708 
    709    switch (format) {
    710    case PIPE_FORMAT_Z24X8_UNORM:
    711    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
    712       blit->fp_offset = 0x180;
    713       if (mask & PIPE_MASK_Z)
    714          blit->color_mask |= 0x0111;
    715       if (mask & PIPE_MASK_S)
    716          blit->color_mask |= 0x1000;
    717       break;
    718    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
    719       blit->fp_offset = 0x80;
    720       if (mask & PIPE_MASK_Z)
    721          blit->color_mask |= 0x1110;
    722       if (mask & PIPE_MASK_S)
    723          blit->color_mask |= 0x0001;
    724       break;
    725    default:
    726       blit->fp_offset = 0;
    727       if (mask & (PIPE_MASK_R | PIPE_MASK_Z)) blit->color_mask |= 0x0001;
    728       if (mask & (PIPE_MASK_G | PIPE_MASK_S)) blit->color_mask |= 0x0010;
    729       if (mask & PIPE_MASK_B) blit->color_mask |= 0x0100;
    730       if (mask & PIPE_MASK_A) blit->color_mask |= 0x1000;
    731       break;
    732    }
    733 }
    734 
    735 static void
    736 nvc0_blit_set_dst(struct nvc0_context *nvc0,
    737                   struct pipe_resource *res, unsigned level, unsigned layer)
    738 {
    739    struct pipe_context *pipe = &nvc0->base.pipe;
    740    struct pipe_surface templ;
    741 
    742    if (util_format_is_depth_or_stencil(res->format))
    743       templ.format = nvc0_blit_zeta_to_colour_format(res->format);
    744    else
    745       templ.format = res->format;
    746 
    747    templ.usage = PIPE_USAGE_STREAM;
    748    templ.u.tex.level = level;
    749    templ.u.tex.first_layer = templ.u.tex.last_layer = layer;
    750 
    751    nvc0->framebuffer.cbufs[0] = nvc0_miptree_surface_new(pipe, res, &templ);
    752    nvc0->framebuffer.nr_cbufs = 1;
    753    nvc0->framebuffer.zsbuf = NULL;
    754    nvc0->framebuffer.width = nvc0->framebuffer.cbufs[0]->width;
    755    nvc0->framebuffer.height = nvc0->framebuffer.cbufs[0]->height;
    756 }
    757 
    758 static INLINE void
    759 nvc0_blit_fixup_tic_entry(struct pipe_sampler_view *view, const boolean filter)
    760 {
    761    struct nv50_tic_entry *ent = nv50_tic_entry(view);
    762 
    763    ent->tic[2] &= ~(1 << 31); /* scaled coordinates, ok with 3d textures ? */
    764 
    765    /* magic: */
    766 
    767    if (filter) {
    768       /* affects quality of near vertical edges in MS8: */
    769       ent->tic[3] = 0x20000000;
    770    } else {
    771       ent->tic[3] = 0;
    772       ent->tic[6] = 0;
    773    }
    774 }
    775 
    776 static void
    777 nvc0_blit_set_src(struct nvc0_context *nvc0,
    778                   struct pipe_resource *res, unsigned level, unsigned layer,
    779                   const boolean filter)
    780 {
    781    struct pipe_context *pipe = &nvc0->base.pipe;
    782    struct pipe_sampler_view templ;
    783    int s;
    784 
    785    templ.format = res->format;
    786    templ.u.tex.first_layer = templ.u.tex.last_layer = layer;
    787    templ.u.tex.first_level = templ.u.tex.last_level = level;
    788    templ.swizzle_r = PIPE_SWIZZLE_RED;
    789    templ.swizzle_g = PIPE_SWIZZLE_GREEN;
    790    templ.swizzle_b = PIPE_SWIZZLE_BLUE;
    791    templ.swizzle_a = PIPE_SWIZZLE_ALPHA;
    792 
    793    nvc0->textures[4][0] = nvc0_create_sampler_view(pipe, res, &templ);
    794    nvc0->textures[4][1] = NULL;
    795 
    796    nvc0_blit_fixup_tic_entry(nvc0->textures[4][0], filter);
    797 
    798    for (s = 0; s <= 3; ++s)
    799       nvc0->num_textures[s] = 0;
    800    nvc0->num_textures[4] = 1;
    801 
    802    templ.format = nv50_zs_to_s_format(res->format);
    803    if (templ.format != res->format) {
    804       nvc0->textures[4][1] = nvc0_create_sampler_view(pipe, res, &templ);
    805       nvc0_blit_fixup_tic_entry(nvc0->textures[4][1], filter);
    806       nvc0->num_textures[4] = 2;
    807    }
    808 }
    809 
    810 static void
    811 nvc0_blitctx_prepare_state(struct nvc0_blitctx *blit)
    812 {
    813    struct nouveau_pushbuf *push = blit->screen->base.pushbuf;
    814 
    815    /* TODO: maybe make this a MACRO (if we need more logic) ? */
    816 
    817    /* blend state */
    818    BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 1);
    819    PUSH_DATA (push, blit->color_mask);
    820    BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1);
    821    PUSH_DATA (push, 0);
    822    IMMED_NVC0(push, NVC0_3D(LOGIC_OP_ENABLE), 0);
    823 
    824    /* rasterizer state */
    825    BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1);
    826    PUSH_DATA (push, 0);
    827    IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 0);
    828    BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4);
    829    PUSH_DATA (push, 0xffff);
    830    PUSH_DATA (push, 0xffff);
    831    PUSH_DATA (push, 0xffff);
    832    PUSH_DATA (push, 0xffff);
    833    BEGIN_NVC0(push, NVC0_3D(MACRO_POLYGON_MODE_FRONT), 1);
    834    PUSH_DATA (push, NVC0_3D_MACRO_POLYGON_MODE_FRONT_FILL);
    835    BEGIN_NVC0(push, NVC0_3D(MACRO_POLYGON_MODE_BACK), 1);
    836    PUSH_DATA (push, NVC0_3D_MACRO_POLYGON_MODE_BACK_FILL);
    837    IMMED_NVC0(push, NVC0_3D(POLYGON_SMOOTH_ENABLE), 0);
    838    IMMED_NVC0(push, NVC0_3D(POLYGON_OFFSET_FILL_ENABLE), 0);
    839    IMMED_NVC0(push, NVC0_3D(POLYGON_STIPPLE_ENABLE), 0);
    840    IMMED_NVC0(push, NVC0_3D(CULL_FACE_ENABLE), 0);
    841 
    842    /* zsa state */
    843    IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0);
    844    IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0);
    845    IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0);
    846 
    847    /* disable transform feedback */
    848    IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), 0);
    849 }
    850 
    851 static void
    852 nvc0_blitctx_pre_blit(struct nvc0_blitctx *blit, struct nvc0_context *nvc0)
    853 {
    854    int s;
    855 
    856    blit->saved.fb.width = nvc0->framebuffer.width;
    857    blit->saved.fb.height = nvc0->framebuffer.height;
    858    blit->saved.fb.nr_cbufs = nvc0->framebuffer.nr_cbufs;
    859    blit->saved.fb.cbufs[0] = nvc0->framebuffer.cbufs[0];
    860    blit->saved.fb.zsbuf = nvc0->framebuffer.zsbuf;
    861 
    862    blit->saved.vp = nvc0->vertprog;
    863    blit->saved.tcp = nvc0->tctlprog;
    864    blit->saved.tep = nvc0->tevlprog;
    865    blit->saved.gp = nvc0->gmtyprog;
    866    blit->saved.fp = nvc0->fragprog;
    867 
    868    nvc0->vertprog = &blit->vp;
    869    nvc0->fragprog = &blit->fp;
    870    nvc0->tctlprog = NULL;
    871    nvc0->tevlprog = NULL;
    872    nvc0->gmtyprog = NULL;
    873 
    874    for (s = 0; s <= 4; ++s) {
    875       blit->saved.num_textures[s] = nvc0->num_textures[s];
    876       blit->saved.num_samplers[s] = nvc0->num_samplers[s];
    877       nvc0->textures_dirty[s] = (1 << nvc0->num_textures[s]) - 1;
    878       nvc0->samplers_dirty[s] = (1 << nvc0->num_samplers[s]) - 1;
    879    }
    880    blit->saved.texture[0] = nvc0->textures[4][0];
    881    blit->saved.texture[1] = nvc0->textures[4][1];
    882    blit->saved.sampler[0] = nvc0->samplers[4][0];
    883    blit->saved.sampler[1] = nvc0->samplers[4][1];
    884 
    885    nvc0->samplers[4][0] = &blit->sampler[blit->filter];
    886    nvc0->samplers[4][1] = &blit->sampler[blit->filter];
    887 
    888    for (s = 0; s <= 3; ++s)
    889       nvc0->num_samplers[s] = 0;
    890    nvc0->num_samplers[4] = 2;
    891 
    892    blit->saved.dirty = nvc0->dirty;
    893 
    894    nvc0->textures_dirty[4] |= 3;
    895    nvc0->samplers_dirty[4] |= 3;
    896 
    897    nvc0->dirty = NVC0_NEW_FRAMEBUFFER |
    898       NVC0_NEW_VERTPROG | NVC0_NEW_FRAGPROG |
    899       NVC0_NEW_TCTLPROG | NVC0_NEW_TEVLPROG | NVC0_NEW_GMTYPROG |
    900       NVC0_NEW_TEXTURES | NVC0_NEW_SAMPLERS;
    901 }
    902 
    903 static void
    904 nvc0_blitctx_post_blit(struct nvc0_context *nvc0, struct nvc0_blitctx *blit)
    905 {
    906    int s;
    907 
    908    pipe_surface_reference(&nvc0->framebuffer.cbufs[0], NULL);
    909 
    910    nvc0->framebuffer.width = blit->saved.fb.width;
    911    nvc0->framebuffer.height = blit->saved.fb.height;
    912    nvc0->framebuffer.nr_cbufs = blit->saved.fb.nr_cbufs;
    913    nvc0->framebuffer.cbufs[0] = blit->saved.fb.cbufs[0];
    914    nvc0->framebuffer.zsbuf = blit->saved.fb.zsbuf;
    915 
    916    nvc0->vertprog = blit->saved.vp;
    917    nvc0->tctlprog = blit->saved.tcp;
    918    nvc0->tevlprog = blit->saved.tep;
    919    nvc0->gmtyprog = blit->saved.gp;
    920    nvc0->fragprog = blit->saved.fp;
    921 
    922    pipe_sampler_view_reference(&nvc0->textures[4][0], NULL);
    923    pipe_sampler_view_reference(&nvc0->textures[4][1], NULL);
    924 
    925    for (s = 0; s <= 4; ++s) {
    926       nvc0->num_textures[s] = blit->saved.num_textures[s];
    927       nvc0->num_samplers[s] = blit->saved.num_samplers[s];
    928       nvc0->textures_dirty[s] = (1 << nvc0->num_textures[s]) - 1;
    929       nvc0->samplers_dirty[s] = (1 << nvc0->num_samplers[s]) - 1;
    930    }
    931    nvc0->textures[4][0] = blit->saved.texture[0];
    932    nvc0->textures[4][1] = blit->saved.texture[1];
    933    nvc0->samplers[4][0] = blit->saved.sampler[0];
    934    nvc0->samplers[4][1] = blit->saved.sampler[1];
    935 
    936    nvc0->textures_dirty[4] |= 3;
    937    nvc0->samplers_dirty[4] |= 3;
    938 
    939    nvc0->dirty = blit->saved.dirty |
    940       (NVC0_NEW_FRAMEBUFFER | NVC0_NEW_SCISSOR | NVC0_NEW_SAMPLE_MASK |
    941        NVC0_NEW_RASTERIZER | NVC0_NEW_ZSA | NVC0_NEW_BLEND |
    942        NVC0_NEW_TEXTURES | NVC0_NEW_SAMPLERS |
    943        NVC0_NEW_VERTPROG | NVC0_NEW_FRAGPROG |
    944        NVC0_NEW_TCTLPROG | NVC0_NEW_TEVLPROG | NVC0_NEW_GMTYPROG |
    945        NVC0_NEW_TFB_TARGETS);
    946 }
    947 
    948 static void
    949 nvc0_resource_resolve(struct pipe_context *pipe,
    950                       const struct pipe_resolve_info *info)
    951 {
    952    struct nvc0_context *nvc0 = nvc0_context(pipe);
    953    struct nvc0_screen *screen = nvc0->screen;
    954    struct nvc0_blitctx *blit = screen->blitctx;
    955    struct nouveau_pushbuf *push = screen->base.pushbuf;
    956    struct pipe_resource *src = info->src.res;
    957    struct pipe_resource *dst = info->dst.res;
    958    float x0, x1, y0, y1;
    959    float x_range, y_range;
    960 
    961    /* Would need more shader variants or, better, just change the TIC target.
    962     * But no API creates 3D MS textures ...
    963     */
    964    if (src->target == PIPE_TEXTURE_3D)
    965       return;
    966 
    967    nvc0_blitctx_get_color_mask_and_fp(blit, dst->format, info->mask);
    968 
    969    blit->filter = util_format_is_depth_or_stencil(dst->format) ? 0 : 1;
    970 
    971    nvc0_blitctx_pre_blit(blit, nvc0);
    972 
    973    nvc0_blit_set_dst(nvc0, dst, info->dst.level, info->dst.layer);
    974    nvc0_blit_set_src(nvc0, src, 0,               info->src.layer, blit->filter);
    975 
    976    nvc0_blitctx_prepare_state(blit);
    977 
    978    nvc0_state_validate(nvc0, ~0, 36);
    979 
    980    x_range =
    981       (float)(info->src.x1 - info->src.x0) /
    982       (float)(info->dst.x1 - info->dst.x0);
    983    y_range =
    984       (float)(info->src.y1 - info->src.y0) /
    985       (float)(info->dst.y1 - info->dst.y0);
    986 
    987    x0 = (float)info->src.x0 - x_range * (float)info->dst.x0;
    988    y0 = (float)info->src.y0 - y_range * (float)info->dst.y0;
    989 
    990    x1 = x0 + 16384.0f * x_range;
    991    y1 = y0 + 16384.0f * y_range;
    992 
    993    x0 *= (float)(1 << nv50_miptree(src)->ms_x);
    994    x1 *= (float)(1 << nv50_miptree(src)->ms_x);
    995    y0 *= (float)(1 << nv50_miptree(src)->ms_y);
    996    y1 *= (float)(1 << nv50_miptree(src)->ms_y);
    997 
    998    BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1);
    999    PUSH_DATA (push,
   1000               blit->fp.code_base + blit->fp_offset);
   1001 
   1002    IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0);
   1003 
   1004    /* Draw a large triangle in screen coordinates covering the whole
   1005     * render target, with scissors defining the destination region.
   1006     * The vertex is supplied with non-normalized texture coordinates
   1007     * arranged in a way to yield the desired offset and scale.
   1008     */
   1009 
   1010    BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2);
   1011    PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0);
   1012    PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0);
   1013 
   1014    IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL),
   1015               NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
   1016 
   1017    BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
   1018    PUSH_DATA (push, 0x74201);
   1019    PUSH_DATAf(push, x0);
   1020    PUSH_DATAf(push, y0);
   1021    BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
   1022    PUSH_DATA (push, 0x74200);
   1023    PUSH_DATAf(push, 0.0f);
   1024    PUSH_DATAf(push, 0.0f);
   1025    BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
   1026    PUSH_DATA (push, 0x74201);
   1027    PUSH_DATAf(push, x1);
   1028    PUSH_DATAf(push, y0);
   1029    BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
   1030    PUSH_DATA (push, 0x74200);
   1031    PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
   1032    PUSH_DATAf(push, 0.0f);
   1033    BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
   1034    PUSH_DATA (push, 0x74201);
   1035    PUSH_DATAf(push, x0);
   1036    PUSH_DATAf(push, y1);
   1037    BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
   1038    PUSH_DATA (push, 0x74200);
   1039    PUSH_DATAf(push, 0.0f);
   1040    PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
   1041 
   1042    IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
   1043 
   1044    /* re-enable normally constant state */
   1045 
   1046    IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
   1047 
   1048    nvc0_blitctx_post_blit(nvc0, blit);
   1049 }
   1050 
   1051 boolean
   1052 nvc0_blitctx_create(struct nvc0_screen *screen)
   1053 {
   1054    screen->blitctx = CALLOC_STRUCT(nvc0_blitctx);
   1055    if (!screen->blitctx) {
   1056       NOUVEAU_ERR("failed to allocate blit context\n");
   1057       return FALSE;
   1058    }
   1059 
   1060    screen->blitctx->screen = screen;
   1061 
   1062    nvc0_blitctx_make_vp(screen->blitctx);
   1063    nvc0_blitctx_make_fp(screen->blitctx);
   1064 
   1065    nvc0_blitctx_make_sampler(screen->blitctx);
   1066 
   1067    screen->blitctx->color_mask = 0x1111;
   1068 
   1069    return TRUE;
   1070 }
   1071 
   1072 
   1073 void
   1074 nvc0_init_surface_functions(struct nvc0_context *nvc0)
   1075 {
   1076    struct pipe_context *pipe = &nvc0->base.pipe;
   1077 
   1078    pipe->resource_copy_region = nvc0_resource_copy_region;
   1079    pipe->resource_resolve = nvc0_resource_resolve;
   1080    pipe->clear_render_target = nvc0_clear_render_target;
   1081    pipe->clear_depth_stencil = nvc0_clear_depth_stencil;
   1082 }
   1083 
   1084