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 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 "nvc0/nvc0_context.h"
     24 #include "nvc0/nvc0_resource.h"
     25 #include "nvc0/gm107_texture.xml.h"
     26 #include "nvc0/nvc0_compute.xml.h"
     27 #include "nv50/g80_texture.xml.h"
     28 #include "nv50/g80_defs.xml.h"
     29 
     30 #include "util/u_format.h"
     31 
     32 #define NVE4_TIC_ENTRY_INVALID 0x000fffff
     33 #define NVE4_TSC_ENTRY_INVALID 0xfff00000
     34 
     35 static inline uint32_t
     36 nv50_tic_swizzle(const struct nvc0_format *fmt, unsigned swz, bool tex_int)
     37 {
     38    switch (swz) {
     39    case PIPE_SWIZZLE_X  : return fmt->tic.src_x;
     40    case PIPE_SWIZZLE_Y: return fmt->tic.src_y;
     41    case PIPE_SWIZZLE_Z : return fmt->tic.src_z;
     42    case PIPE_SWIZZLE_W: return fmt->tic.src_w;
     43    case PIPE_SWIZZLE_1:
     44       return tex_int ? G80_TIC_SOURCE_ONE_INT : G80_TIC_SOURCE_ONE_FLOAT;
     45    case PIPE_SWIZZLE_0:
     46    default:
     47       return G80_TIC_SOURCE_ZERO;
     48    }
     49 }
     50 
     51 struct pipe_sampler_view *
     52 nvc0_create_sampler_view(struct pipe_context *pipe,
     53                          struct pipe_resource *res,
     54                          const struct pipe_sampler_view *templ)
     55 {
     56    uint32_t flags = 0;
     57 
     58    if (templ->target == PIPE_TEXTURE_RECT || templ->target == PIPE_BUFFER)
     59       flags |= NV50_TEXVIEW_SCALED_COORDS;
     60 
     61    return nvc0_create_texture_view(pipe, res, templ, flags, templ->target);
     62 }
     63 
     64 static struct pipe_sampler_view *
     65 gm107_create_texture_view(struct pipe_context *pipe,
     66                           struct pipe_resource *texture,
     67                           const struct pipe_sampler_view *templ,
     68                           uint32_t flags,
     69                           enum pipe_texture_target target)
     70 {
     71    const struct util_format_description *desc;
     72    const struct nvc0_format *fmt;
     73    uint64_t address;
     74    uint32_t *tic;
     75    uint32_t swz[4];
     76    uint32_t width, height;
     77    uint32_t depth;
     78    struct nv50_tic_entry *view;
     79    struct nv50_miptree *mt;
     80    bool tex_int;
     81 
     82    view = MALLOC_STRUCT(nv50_tic_entry);
     83    if (!view)
     84       return NULL;
     85    mt = nv50_miptree(texture);
     86 
     87    view->pipe = *templ;
     88    view->pipe.reference.count = 1;
     89    view->pipe.texture = NULL;
     90    view->pipe.context = pipe;
     91 
     92    view->id = -1;
     93    view->bindless = 0;
     94 
     95    pipe_resource_reference(&view->pipe.texture, texture);
     96 
     97    tic = &view->tic[0];
     98 
     99    desc = util_format_description(view->pipe.format);
    100    tex_int = util_format_is_pure_integer(view->pipe.format);
    101 
    102    fmt = &nvc0_format_table[view->pipe.format];
    103    swz[0] = nv50_tic_swizzle(fmt, view->pipe.swizzle_r, tex_int);
    104    swz[1] = nv50_tic_swizzle(fmt, view->pipe.swizzle_g, tex_int);
    105    swz[2] = nv50_tic_swizzle(fmt, view->pipe.swizzle_b, tex_int);
    106    swz[3] = nv50_tic_swizzle(fmt, view->pipe.swizzle_a, tex_int);
    107 
    108    tic[0]  = fmt->tic.format << GM107_TIC2_0_COMPONENTS_SIZES__SHIFT;
    109    tic[0] |= fmt->tic.type_r << GM107_TIC2_0_R_DATA_TYPE__SHIFT;
    110    tic[0] |= fmt->tic.type_g << GM107_TIC2_0_G_DATA_TYPE__SHIFT;
    111    tic[0] |= fmt->tic.type_b << GM107_TIC2_0_B_DATA_TYPE__SHIFT;
    112    tic[0] |= fmt->tic.type_a << GM107_TIC2_0_A_DATA_TYPE__SHIFT;
    113    tic[0] |= swz[0] << GM107_TIC2_0_X_SOURCE__SHIFT;
    114    tic[0] |= swz[1] << GM107_TIC2_0_Y_SOURCE__SHIFT;
    115    tic[0] |= swz[2] << GM107_TIC2_0_Z_SOURCE__SHIFT;
    116    tic[0] |= swz[3] << GM107_TIC2_0_W_SOURCE__SHIFT;
    117 
    118    address = mt->base.address;
    119 
    120    tic[3]  = GM107_TIC2_3_LOD_ANISO_QUALITY_2;
    121    tic[4]  = GM107_TIC2_4_SECTOR_PROMOTION_PROMOTE_TO_2_V;
    122    tic[4] |= GM107_TIC2_4_BORDER_SIZE_SAMPLER_COLOR;
    123 
    124    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
    125       tic[4] |= GM107_TIC2_4_SRGB_CONVERSION;
    126 
    127    if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
    128       tic[5] = GM107_TIC2_5_NORMALIZED_COORDS;
    129    else
    130       tic[5] = 0;
    131 
    132    /* check for linear storage type */
    133    if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
    134       if (texture->target == PIPE_BUFFER) {
    135          assert(!(tic[5] & GM107_TIC2_5_NORMALIZED_COORDS));
    136          width = view->pipe.u.buf.size / (desc->block.bits / 8) - 1;
    137          address +=
    138             view->pipe.u.buf.offset;
    139          tic[2]  = GM107_TIC2_2_HEADER_VERSION_ONE_D_BUFFER;
    140          tic[3] |= width >> 16;
    141          tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_BUFFER;
    142          tic[4] |= width & 0xffff;
    143       } else {
    144          assert(!(mt->level[0].pitch & 0x1f));
    145          /* must be 2D texture without mip maps */
    146          tic[2]  = GM107_TIC2_2_HEADER_VERSION_PITCH;
    147          tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
    148          tic[3] |= mt->level[0].pitch >> 5;
    149          tic[4] |= mt->base.base.width0 - 1;
    150          tic[5] |= 0 << GM107_TIC2_5_DEPTH_MINUS_ONE__SHIFT;
    151          tic[5] |= mt->base.base.height0 - 1;
    152       }
    153       tic[1]  = address;
    154       tic[2] |= address >> 32;
    155       tic[6]  = 0;
    156       tic[7]  = 0;
    157       return &view->pipe;
    158    }
    159 
    160    tic[2]  = GM107_TIC2_2_HEADER_VERSION_BLOCKLINEAR;
    161    tic[3] |=
    162       ((mt->level[0].tile_mode & 0x0f0) >> 4 << 3) |
    163       ((mt->level[0].tile_mode & 0xf00) >> 8 << 6);
    164 
    165    depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
    166 
    167    if (mt->base.base.array_size > 1) {
    168       /* there doesn't seem to be a base layer field in TIC */
    169       address += view->pipe.u.tex.first_layer * mt->layer_stride;
    170       depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
    171    }
    172    tic[1]  = address;
    173    tic[2] |= address >> 32;
    174 
    175    switch (target) {
    176    case PIPE_TEXTURE_1D:
    177       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D;
    178       break;
    179    case PIPE_TEXTURE_2D:
    180       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D;
    181       break;
    182    case PIPE_TEXTURE_RECT:
    183       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D;
    184       break;
    185    case PIPE_TEXTURE_3D:
    186       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_THREE_D;
    187       break;
    188    case PIPE_TEXTURE_CUBE:
    189       depth /= 6;
    190       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_CUBEMAP;
    191       break;
    192    case PIPE_TEXTURE_1D_ARRAY:
    193       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_ARRAY;
    194       break;
    195    case PIPE_TEXTURE_2D_ARRAY:
    196       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D_ARRAY;
    197       break;
    198    case PIPE_TEXTURE_CUBE_ARRAY:
    199       depth /= 6;
    200       tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_CUBE_ARRAY;
    201       break;
    202    default:
    203       unreachable("unexpected/invalid texture target");
    204    }
    205 
    206    tic[3] |= (flags & NV50_TEXVIEW_FILTER_MSAA8) ?
    207              GM107_TIC2_3_USE_HEADER_OPT_CONTROL :
    208              GM107_TIC2_3_LOD_ANISO_QUALITY_HIGH |
    209              GM107_TIC2_3_LOD_ISO_QUALITY_HIGH;
    210 
    211    if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) {
    212       width = mt->base.base.width0 << mt->ms_x;
    213       height = mt->base.base.height0 << mt->ms_y;
    214    } else {
    215       width = mt->base.base.width0;
    216       height = mt->base.base.height0;
    217    }
    218 
    219    tic[4] |= width - 1;
    220 
    221    tic[5] |= (height - 1) & 0xffff;
    222    tic[5] |= (depth - 1) << GM107_TIC2_5_DEPTH_MINUS_ONE__SHIFT;
    223    tic[3] |= mt->base.base.last_level << GM107_TIC2_3_MAX_MIP_LEVEL__SHIFT;
    224 
    225    /* sampling points: (?) */
    226    if ((flags & NV50_TEXVIEW_ACCESS_RESOLVE) && mt->ms_x > 1) {
    227       tic[6]  = GM107_TIC2_6_ANISO_FINE_SPREAD_MODIFIER_CONST_TWO;
    228       tic[6] |= GM107_TIC2_6_MAX_ANISOTROPY_2_TO_1;
    229    } else {
    230       tic[6]  = GM107_TIC2_6_ANISO_FINE_SPREAD_FUNC_TWO;
    231       tic[6] |= GM107_TIC2_6_ANISO_COARSE_SPREAD_FUNC_ONE;
    232    }
    233 
    234    tic[7]  = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
    235    tic[7] |= mt->ms_mode << GM107_TIC2_7_MULTI_SAMPLE_COUNT__SHIFT;
    236 
    237    return &view->pipe;
    238 }
    239 
    240 struct pipe_sampler_view *
    241 gm107_create_texture_view_from_image(struct pipe_context *pipe,
    242                                      const struct pipe_image_view *view)
    243 {
    244    struct nv04_resource *res = nv04_resource(view->resource);
    245    struct pipe_sampler_view templ = {};
    246    enum pipe_texture_target target;
    247    uint32_t flags = 0;
    248 
    249    if (!res)
    250       return NULL;
    251    target = res->base.target;
    252 
    253    if (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY)
    254       target = PIPE_TEXTURE_2D_ARRAY;
    255 
    256    templ.format = view->format;
    257    templ.swizzle_r = PIPE_SWIZZLE_X;
    258    templ.swizzle_g = PIPE_SWIZZLE_Y;
    259    templ.swizzle_b = PIPE_SWIZZLE_Z;
    260    templ.swizzle_a = PIPE_SWIZZLE_W;
    261 
    262    if (target == PIPE_BUFFER) {
    263       templ.u.buf.offset = view->u.buf.offset;
    264       templ.u.buf.size = view->u.buf.size;
    265    } else {
    266       templ.u.tex.first_layer = view->u.tex.first_layer;
    267       templ.u.tex.last_layer = view->u.tex.last_layer;
    268       templ.u.tex.first_level = templ.u.tex.last_level = view->u.tex.level;
    269    }
    270 
    271    flags = NV50_TEXVIEW_SCALED_COORDS;
    272 
    273    return nvc0_create_texture_view(pipe, &res->base, &templ, flags, target);
    274 }
    275 
    276 static struct pipe_sampler_view *
    277 gf100_create_texture_view(struct pipe_context *pipe,
    278                           struct pipe_resource *texture,
    279                           const struct pipe_sampler_view *templ,
    280                           uint32_t flags,
    281                           enum pipe_texture_target target)
    282 {
    283    const struct util_format_description *desc;
    284    const struct nvc0_format *fmt;
    285    uint64_t address;
    286    uint32_t *tic;
    287    uint32_t swz[4];
    288    uint32_t width, height;
    289    uint32_t depth;
    290    uint32_t tex_fmt;
    291    struct nv50_tic_entry *view;
    292    struct nv50_miptree *mt;
    293    bool tex_int;
    294 
    295    view = MALLOC_STRUCT(nv50_tic_entry);
    296    if (!view)
    297       return NULL;
    298    mt = nv50_miptree(texture);
    299 
    300    view->pipe = *templ;
    301    view->pipe.reference.count = 1;
    302    view->pipe.texture = NULL;
    303    view->pipe.context = pipe;
    304 
    305    view->id = -1;
    306    view->bindless = 0;
    307 
    308    pipe_resource_reference(&view->pipe.texture, texture);
    309 
    310    tic = &view->tic[0];
    311 
    312    desc = util_format_description(view->pipe.format);
    313 
    314    fmt = &nvc0_format_table[view->pipe.format];
    315 
    316    tex_int = util_format_is_pure_integer(view->pipe.format);
    317    tex_fmt = fmt->tic.format & 0x3f;
    318 
    319    swz[0] = nv50_tic_swizzle(fmt, view->pipe.swizzle_r, tex_int);
    320    swz[1] = nv50_tic_swizzle(fmt, view->pipe.swizzle_g, tex_int);
    321    swz[2] = nv50_tic_swizzle(fmt, view->pipe.swizzle_b, tex_int);
    322    swz[3] = nv50_tic_swizzle(fmt, view->pipe.swizzle_a, tex_int);
    323    tic[0] = (tex_fmt << G80_TIC_0_COMPONENTS_SIZES__SHIFT) |
    324             (fmt->tic.type_r << G80_TIC_0_R_DATA_TYPE__SHIFT) |
    325             (fmt->tic.type_g << G80_TIC_0_G_DATA_TYPE__SHIFT) |
    326             (fmt->tic.type_b << G80_TIC_0_B_DATA_TYPE__SHIFT) |
    327             (fmt->tic.type_a << G80_TIC_0_A_DATA_TYPE__SHIFT) |
    328             (swz[0] << G80_TIC_0_X_SOURCE__SHIFT) |
    329             (swz[1] << G80_TIC_0_Y_SOURCE__SHIFT) |
    330             (swz[2] << G80_TIC_0_Z_SOURCE__SHIFT) |
    331             (swz[3] << G80_TIC_0_W_SOURCE__SHIFT) |
    332             ((fmt->tic.format & 0x40) << (GK20A_TIC_0_USE_COMPONENT_SIZES_EXTENDED__SHIFT - 6));
    333 
    334    address = mt->base.address;
    335 
    336    tic[2] = 0x10001000 | G80_TIC_2_BORDER_SOURCE_COLOR;
    337 
    338    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
    339       tic[2] |= G80_TIC_2_SRGB_CONVERSION;
    340 
    341    if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
    342       tic[2] |= G80_TIC_2_NORMALIZED_COORDS;
    343 
    344    /* check for linear storage type */
    345    if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
    346       if (texture->target == PIPE_BUFFER) {
    347          assert(!(tic[2] & G80_TIC_2_NORMALIZED_COORDS));
    348          address +=
    349             view->pipe.u.buf.offset;
    350          tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER;
    351          tic[3] = 0;
    352          tic[4] = /* width */
    353             view->pipe.u.buf.size / (desc->block.bits / 8);
    354          tic[5] = 0;
    355       } else {
    356          /* must be 2D texture without mip maps */
    357          tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
    358          tic[3] = mt->level[0].pitch;
    359          tic[4] = mt->base.base.width0;
    360          tic[5] = (1 << 16) | mt->base.base.height0;
    361       }
    362       tic[6] =
    363       tic[7] = 0;
    364       tic[1] = address;
    365       tic[2] |= address >> 32;
    366       return &view->pipe;
    367    }
    368 
    369    tic[2] |=
    370       ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
    371       ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
    372 
    373    depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
    374 
    375    if (mt->base.base.array_size > 1) {
    376       /* there doesn't seem to be a base layer field in TIC */
    377       address += view->pipe.u.tex.first_layer * mt->layer_stride;
    378       depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
    379    }
    380    tic[1] = address;
    381    tic[2] |= address >> 32;
    382 
    383    switch (target) {
    384    case PIPE_TEXTURE_1D:
    385       tic[2] |= G80_TIC_2_TEXTURE_TYPE_ONE_D;
    386       break;
    387    case PIPE_TEXTURE_2D:
    388       tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D;
    389       break;
    390    case PIPE_TEXTURE_RECT:
    391       tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D;
    392       break;
    393    case PIPE_TEXTURE_3D:
    394       tic[2] |= G80_TIC_2_TEXTURE_TYPE_THREE_D;
    395       break;
    396    case PIPE_TEXTURE_CUBE:
    397       depth /= 6;
    398       tic[2] |= G80_TIC_2_TEXTURE_TYPE_CUBEMAP;
    399       break;
    400    case PIPE_TEXTURE_1D_ARRAY:
    401       tic[2] |= G80_TIC_2_TEXTURE_TYPE_ONE_D_ARRAY;
    402       break;
    403    case PIPE_TEXTURE_2D_ARRAY:
    404       tic[2] |= G80_TIC_2_TEXTURE_TYPE_TWO_D_ARRAY;
    405       break;
    406    case PIPE_TEXTURE_CUBE_ARRAY:
    407       depth /= 6;
    408       tic[2] |= G80_TIC_2_TEXTURE_TYPE_CUBE_ARRAY;
    409       break;
    410    default:
    411       unreachable("unexpected/invalid texture target");
    412    }
    413 
    414    tic[3] = (flags & NV50_TEXVIEW_FILTER_MSAA8) ? 0x20000000 : 0x00300000;
    415 
    416    if (flags & NV50_TEXVIEW_ACCESS_RESOLVE) {
    417       width = mt->base.base.width0 << mt->ms_x;
    418       height = mt->base.base.height0 << mt->ms_y;
    419    } else {
    420       width = mt->base.base.width0;
    421       height = mt->base.base.height0;
    422    }
    423 
    424    tic[4] = (1 << 31) | width;
    425 
    426    tic[5] = height & 0xffff;
    427    tic[5] |= depth << 16;
    428    tic[5] |= mt->base.base.last_level << 28;
    429 
    430    /* sampling points: (?) */
    431    if (flags & NV50_TEXVIEW_ACCESS_RESOLVE)
    432       tic[6] = (mt->ms_x > 1) ? 0x88000000 : 0x03000000;
    433    else
    434       tic[6] = 0x03000000;
    435 
    436    tic[7] = (view->pipe.u.tex.last_level << 4) | view->pipe.u.tex.first_level;
    437    tic[7] |= mt->ms_mode << 12;
    438 
    439    return &view->pipe;
    440 }
    441 
    442 struct pipe_sampler_view *
    443 nvc0_create_texture_view(struct pipe_context *pipe,
    444                          struct pipe_resource *texture,
    445                          const struct pipe_sampler_view *templ,
    446                          uint32_t flags,
    447                          enum pipe_texture_target target)
    448 {
    449    if (nvc0_context(pipe)->screen->tic.maxwell)
    450       return gm107_create_texture_view(pipe, texture, templ, flags, target);
    451    return gf100_create_texture_view(pipe, texture, templ, flags, target);
    452 }
    453 
    454 bool
    455 nvc0_update_tic(struct nvc0_context *nvc0, struct nv50_tic_entry *tic,
    456                 struct nv04_resource *res)
    457 {
    458    uint64_t address = res->address;
    459    if (res->base.target != PIPE_BUFFER)
    460       return false;
    461    address += tic->pipe.u.buf.offset;
    462    if (tic->tic[1] == (uint32_t)address &&
    463        (tic->tic[2] & 0xff) == address >> 32)
    464       return false;
    465 
    466    tic->tic[1] = address;
    467    tic->tic[2] &= 0xffffff00;
    468    tic->tic[2] |= address >> 32;
    469 
    470    if (tic->id >= 0) {
    471       nvc0->base.push_data(&nvc0->base, nvc0->screen->txc, tic->id * 32,
    472                            NV_VRAM_DOMAIN(&nvc0->screen->base), 32,
    473                            tic->tic);
    474       return true;
    475    }
    476 
    477    return false;
    478 }
    479 
    480 bool
    481 nvc0_validate_tic(struct nvc0_context *nvc0, int s)
    482 {
    483    uint32_t commands[32];
    484    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    485    unsigned i;
    486    unsigned n = 0;
    487    bool need_flush = false;
    488 
    489    for (i = 0; i < nvc0->num_textures[s]; ++i) {
    490       struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
    491       struct nv04_resource *res;
    492       const bool dirty = !!(nvc0->textures_dirty[s] & (1 << i));
    493 
    494       if (!tic) {
    495          if (dirty)
    496             commands[n++] = (i << 1) | 0;
    497          continue;
    498       }
    499       res = nv04_resource(tic->pipe.texture);
    500       need_flush |= nvc0_update_tic(nvc0, tic, res);
    501 
    502       if (tic->id < 0) {
    503          tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
    504 
    505          nvc0->base.push_data(&nvc0->base, nvc0->screen->txc, tic->id * 32,
    506                               NV_VRAM_DOMAIN(&nvc0->screen->base), 32,
    507                               tic->tic);
    508          need_flush = true;
    509       } else
    510       if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
    511          if (unlikely(s == 5))
    512             BEGIN_NVC0(push, NVC0_CP(TEX_CACHE_CTL), 1);
    513          else
    514             BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
    515          PUSH_DATA (push, (tic->id << 4) | 1);
    516          NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_cache_flush_count, 1);
    517       }
    518       nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
    519 
    520       res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
    521       res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
    522 
    523       if (!dirty)
    524          continue;
    525       commands[n++] = (tic->id << 9) | (i << 1) | 1;
    526 
    527       if (unlikely(s == 5))
    528          BCTX_REFN(nvc0->bufctx_cp, CP_TEX(i), res, RD);
    529       else
    530          BCTX_REFN(nvc0->bufctx_3d, 3D_TEX(s, i), res, RD);
    531    }
    532    for (; i < nvc0->state.num_textures[s]; ++i)
    533       commands[n++] = (i << 1) | 0;
    534 
    535    nvc0->state.num_textures[s] = nvc0->num_textures[s];
    536 
    537    if (n) {
    538       if (unlikely(s == 5))
    539          BEGIN_NIC0(push, NVC0_CP(BIND_TIC), n);
    540       else
    541          BEGIN_NIC0(push, NVC0_3D(BIND_TIC(s)), n);
    542       PUSH_DATAp(push, commands, n);
    543    }
    544    nvc0->textures_dirty[s] = 0;
    545 
    546    return need_flush;
    547 }
    548 
    549 static bool
    550 nve4_validate_tic(struct nvc0_context *nvc0, unsigned s)
    551 {
    552    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    553    unsigned i;
    554    bool need_flush = false;
    555 
    556    for (i = 0; i < nvc0->num_textures[s]; ++i) {
    557       struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
    558       struct nv04_resource *res;
    559       const bool dirty = !!(nvc0->textures_dirty[s] & (1 << i));
    560 
    561       if (!tic) {
    562          nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
    563          continue;
    564       }
    565       res = nv04_resource(tic->pipe.texture);
    566       need_flush |= nvc0_update_tic(nvc0, tic, res);
    567 
    568       if (tic->id < 0) {
    569          tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
    570 
    571          nvc0->base.push_data(&nvc0->base, nvc0->screen->txc, tic->id * 32,
    572                               NV_VRAM_DOMAIN(&nvc0->screen->base), 32,
    573                               tic->tic);
    574          need_flush = true;
    575       } else
    576       if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
    577          BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
    578          PUSH_DATA (push, (tic->id << 4) | 1);
    579       }
    580       nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
    581 
    582       res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
    583       res->status |=  NOUVEAU_BUFFER_STATUS_GPU_READING;
    584 
    585       nvc0->tex_handles[s][i] &= ~NVE4_TIC_ENTRY_INVALID;
    586       nvc0->tex_handles[s][i] |= tic->id;
    587       if (dirty)
    588          BCTX_REFN(nvc0->bufctx_3d, 3D_TEX(s, i), res, RD);
    589    }
    590    for (; i < nvc0->state.num_textures[s]; ++i) {
    591       nvc0->tex_handles[s][i] |= NVE4_TIC_ENTRY_INVALID;
    592       nvc0->textures_dirty[s] |= 1 << i;
    593    }
    594 
    595    nvc0->state.num_textures[s] = nvc0->num_textures[s];
    596 
    597    return need_flush;
    598 }
    599 
    600 void nvc0_validate_textures(struct nvc0_context *nvc0)
    601 {
    602    bool need_flush = false;
    603    int i;
    604 
    605    for (i = 0; i < 5; i++) {
    606       if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS)
    607          need_flush |= nve4_validate_tic(nvc0, i);
    608       else
    609          need_flush |= nvc0_validate_tic(nvc0, i);
    610    }
    611 
    612    if (need_flush) {
    613       BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
    614       PUSH_DATA (nvc0->base.pushbuf, 0);
    615    }
    616 
    617    /* Invalidate all CP textures because they are aliased. */
    618    for (int i = 0; i < nvc0->num_textures[5]; i++)
    619       nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEX(i));
    620    nvc0->textures_dirty[5] = ~0;
    621    nvc0->dirty_cp |= NVC0_NEW_CP_TEXTURES;
    622 }
    623 
    624 bool
    625 nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
    626 {
    627    uint32_t commands[16];
    628    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    629    unsigned i;
    630    unsigned n = 0;
    631    bool need_flush = false;
    632 
    633    for (i = 0; i < nvc0->num_samplers[s]; ++i) {
    634       struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
    635 
    636       if (!(nvc0->samplers_dirty[s] & (1 << i)))
    637          continue;
    638       if (!tsc) {
    639          commands[n++] = (i << 4) | 0;
    640          continue;
    641       }
    642       nvc0->seamless_cube_map = tsc->seamless_cube_map;
    643       if (tsc->id < 0) {
    644          tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
    645 
    646          nvc0_m2mf_push_linear(&nvc0->base, nvc0->screen->txc,
    647                                65536 + tsc->id * 32, NV_VRAM_DOMAIN(&nvc0->screen->base),
    648                                32, tsc->tsc);
    649          need_flush = true;
    650       }
    651       nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
    652 
    653       commands[n++] = (tsc->id << 12) | (i << 4) | 1;
    654    }
    655    for (; i < nvc0->state.num_samplers[s]; ++i)
    656       commands[n++] = (i << 4) | 0;
    657 
    658    nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
    659 
    660    if (n) {
    661       if (unlikely(s == 5))
    662          BEGIN_NIC0(push, NVC0_CP(BIND_TSC), n);
    663       else
    664          BEGIN_NIC0(push, NVC0_3D(BIND_TSC(s)), n);
    665       PUSH_DATAp(push, commands, n);
    666    }
    667    nvc0->samplers_dirty[s] = 0;
    668 
    669    return need_flush;
    670 }
    671 
    672 bool
    673 nve4_validate_tsc(struct nvc0_context *nvc0, int s)
    674 {
    675    unsigned i;
    676    bool need_flush = false;
    677 
    678    for (i = 0; i < nvc0->num_samplers[s]; ++i) {
    679       struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
    680 
    681       if (!tsc) {
    682          nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
    683          continue;
    684       }
    685       if (tsc->id < 0) {
    686          tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
    687 
    688          nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc,
    689                                65536 + tsc->id * 32,
    690                                NV_VRAM_DOMAIN(&nvc0->screen->base),
    691                                32, tsc->tsc);
    692          need_flush = true;
    693       }
    694       nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
    695 
    696       nvc0->tex_handles[s][i] &= ~NVE4_TSC_ENTRY_INVALID;
    697       nvc0->tex_handles[s][i] |= tsc->id << 20;
    698    }
    699    for (; i < nvc0->state.num_samplers[s]; ++i) {
    700       nvc0->tex_handles[s][i] |= NVE4_TSC_ENTRY_INVALID;
    701       nvc0->samplers_dirty[s] |= 1 << i;
    702    }
    703 
    704    nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
    705 
    706    return need_flush;
    707 }
    708 
    709 void nvc0_validate_samplers(struct nvc0_context *nvc0)
    710 {
    711    bool need_flush = false;
    712    int i;
    713 
    714    for (i = 0; i < 5; i++) {
    715       if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS)
    716          need_flush |= nve4_validate_tsc(nvc0, i);
    717       else
    718          need_flush |= nvc0_validate_tsc(nvc0, i);
    719    }
    720 
    721    if (need_flush) {
    722       BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
    723       PUSH_DATA (nvc0->base.pushbuf, 0);
    724    }
    725 
    726    /* Invalidate all CP samplers because they are aliased. */
    727    nvc0->samplers_dirty[5] = ~0;
    728    nvc0->dirty_cp |= NVC0_NEW_CP_SAMPLERS;
    729 }
    730 
    731 /* Upload the "diagonal" entries for the possible texture sources ($t == $s).
    732  * At some point we might want to get a list of the combinations used by a
    733  * shader and fill in those entries instead of having it extract the handles.
    734  */
    735 void
    736 nve4_set_tex_handles(struct nvc0_context *nvc0)
    737 {
    738    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    739    struct nvc0_screen *screen = nvc0->screen;
    740    unsigned s;
    741 
    742    if (nvc0->screen->base.class_3d < NVE4_3D_CLASS)
    743       return;
    744 
    745    for (s = 0; s < 5; ++s) {
    746       uint32_t dirty = nvc0->textures_dirty[s] | nvc0->samplers_dirty[s];
    747       if (!dirty)
    748          continue;
    749       BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
    750       PUSH_DATA (push, NVC0_CB_AUX_SIZE);
    751       PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
    752       PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
    753       do {
    754          int i = ffs(dirty) - 1;
    755          dirty &= ~(1 << i);
    756 
    757          BEGIN_NVC0(push, NVC0_3D(CB_POS), 2);
    758          PUSH_DATA (push, (8 + i) * 4);
    759          PUSH_DATA (push, nvc0->tex_handles[s][i]);
    760       } while (dirty);
    761 
    762       nvc0->textures_dirty[s] = 0;
    763       nvc0->samplers_dirty[s] = 0;
    764    }
    765 }
    766 
    767 static uint64_t
    768 nve4_create_texture_handle(struct pipe_context *pipe,
    769                            struct pipe_sampler_view *view,
    770                            const struct pipe_sampler_state *sampler)
    771 {
    772    /* We have to create persistent handles that won't change for these objects
    773     * That means that we have to upload them into place and lock them so that
    774     * they can't be kicked out later.
    775     */
    776    struct nvc0_context *nvc0 = nvc0_context(pipe);
    777    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
    778    struct nv50_tic_entry *tic = nv50_tic_entry(view);
    779    struct nv50_tsc_entry *tsc = pipe->create_sampler_state(pipe, sampler);
    780    struct pipe_sampler_view *v = NULL;
    781 
    782    tsc->id = nvc0_screen_tsc_alloc(nvc0->screen, tsc);
    783    if (tsc->id < 0)
    784       goto fail;
    785 
    786    if (tic->id < 0) {
    787       tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
    788       if (tic->id < 0)
    789          goto fail;
    790 
    791       nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, tic->id * 32,
    792                             NV_VRAM_DOMAIN(&nvc0->screen->base), 32,
    793                             tic->tic);
    794 
    795       IMMED_NVC0(push, NVC0_3D(TIC_FLUSH), 0);
    796    }
    797 
    798    nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc,
    799                          65536 + tsc->id * 32,
    800                          NV_VRAM_DOMAIN(&nvc0->screen->base),
    801                          32, tsc->tsc);
    802 
    803    IMMED_NVC0(push, NVC0_3D(TSC_FLUSH), 0);
    804 
    805    // Add an extra reference to this sampler view effectively held by this
    806    // texture handle. This is to deal with the sampler view being dereferenced
    807    // before the handle is. However we need the view to still be live until the
    808    // handle to it is deleted.
    809    pipe_sampler_view_reference(&v, view);
    810    p_atomic_inc(&tic->bindless);
    811 
    812    nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
    813    nvc0->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
    814 
    815    return 0x100000000ULL | (tsc->id << 20) | tic->id;
    816 
    817 fail:
    818    pipe->delete_sampler_state(pipe, tsc);
    819    return 0;
    820 }
    821 
    822 static bool
    823 view_bound(struct nvc0_context *nvc0, struct pipe_sampler_view *view) {
    824    for (int s = 0; s < 6; s++) {
    825       for (int i = 0; i < nvc0->num_textures[s]; i++)
    826          if (nvc0->textures[s][i] == view)
    827             return true;
    828    }
    829    return false;
    830 }
    831 
    832 static void
    833 nve4_delete_texture_handle(struct pipe_context *pipe, uint64_t handle)
    834 {
    835    struct nvc0_context *nvc0 = nvc0_context(pipe);
    836    uint32_t tic = handle & NVE4_TIC_ENTRY_INVALID;
    837    uint32_t tsc = (handle & NVE4_TSC_ENTRY_INVALID) >> 20;
    838    struct nv50_tic_entry *entry = nvc0->screen->tic.entries[tic];
    839 
    840    if (entry) {
    841       struct pipe_sampler_view *view = &entry->pipe;
    842       assert(entry->bindless);
    843       p_atomic_dec(&entry->bindless);
    844       if (!view_bound(nvc0, view))
    845          nvc0_screen_tic_unlock(nvc0->screen, entry);
    846       pipe_sampler_view_reference(&view, NULL);
    847    }
    848 
    849    pipe->delete_sampler_state(pipe, nvc0->screen->tsc.entries[tsc]);
    850 }
    851 
    852 static void
    853 nve4_make_texture_handle_resident(struct pipe_context *pipe,
    854                                   uint64_t handle, bool resident)
    855 {
    856    struct nvc0_context *nvc0 = nvc0_context(pipe);
    857    if (resident) {
    858       struct nvc0_resident *res = calloc(1, sizeof(struct nvc0_resident));
    859       struct nv50_tic_entry *tic =
    860          nvc0->screen->tic.entries[handle & NVE4_TIC_ENTRY_INVALID];
    861       assert(tic);
    862       assert(tic->bindless);
    863 
    864       res->handle = handle;
    865       res->buf = nv04_resource(tic->pipe.texture);
    866       res->flags = NOUVEAU_BO_RD;
    867       list_add(&res->list, &nvc0->tex_head);
    868    } else {
    869       list_for_each_entry_safe(struct nvc0_resident, pos, &nvc0->tex_head, list) {
    870          if (pos->handle == handle) {
    871             list_del(&pos->list);
    872             free(pos);
    873             break;
    874          }
    875       }
    876    }
    877 }
    878 
    879 static const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT];
    880 static const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT];
    881 static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT];
    882 
    883 static void
    884 nvc0_get_surface_dims(const struct pipe_image_view *view,
    885                       int *width, int *height, int *depth)
    886 {
    887    struct nv04_resource *res = nv04_resource(view->resource);
    888    int level;
    889 
    890    *width = *height = *depth = 1;
    891    if (res->base.target == PIPE_BUFFER) {
    892       *width = view->u.buf.size / util_format_get_blocksize(view->format);
    893       return;
    894    }
    895 
    896    level = view->u.tex.level;
    897    *width = u_minify(view->resource->width0, level);
    898    *height = u_minify(view->resource->height0, level);
    899    *depth = u_minify(view->resource->depth0, level);
    900 
    901    switch (res->base.target) {
    902    case PIPE_TEXTURE_1D_ARRAY:
    903    case PIPE_TEXTURE_2D_ARRAY:
    904    case PIPE_TEXTURE_CUBE:
    905    case PIPE_TEXTURE_CUBE_ARRAY:
    906       *depth = view->u.tex.last_layer - view->u.tex.first_layer + 1;
    907       break;
    908    case PIPE_TEXTURE_1D:
    909    case PIPE_TEXTURE_2D:
    910    case PIPE_TEXTURE_RECT:
    911    case PIPE_TEXTURE_3D:
    912       break;
    913    default:
    914       assert(!"unexpected texture target");
    915       break;
    916    }
    917 }
    918 
    919 void
    920 nvc0_mark_image_range_valid(const struct pipe_image_view *view)
    921 {
    922    struct nv04_resource *res = (struct nv04_resource *)view->resource;
    923 
    924    assert(view->resource->target == PIPE_BUFFER);
    925 
    926    util_range_add(&res->valid_buffer_range,
    927                   view->u.buf.offset,
    928                   view->u.buf.offset + view->u.buf.size);
    929 }
    930 
    931 void
    932 nve4_set_surface_info(struct nouveau_pushbuf *push,
    933                       const struct pipe_image_view *view,
    934                       struct nvc0_context *nvc0)
    935 {
    936    struct nvc0_screen *screen = nvc0->screen;
    937    struct nv04_resource *res;
    938    uint64_t address;
    939    uint32_t *const info = push->cur;
    940    int width, height, depth;
    941    uint8_t log2cpp;
    942 
    943    if (view && !nve4_su_format_map[view->format])
    944       NOUVEAU_ERR("unsupported surface format, try is_format_supported() !\n");
    945 
    946    push->cur += 16;
    947 
    948    if (!view || !nve4_su_format_map[view->format]) {
    949       memset(info, 0, 16 * sizeof(*info));
    950 
    951       info[0] = 0xbadf0000;
    952       info[1] = 0x80004000;
    953       info[12] = nve4_suldp_lib_offset[PIPE_FORMAT_R32G32B32A32_UINT] +
    954          screen->lib_code->start;
    955       return;
    956    }
    957    res = nv04_resource(view->resource);
    958 
    959    address = res->address;
    960 
    961    /* get surface dimensions based on the target. */
    962    nvc0_get_surface_dims(view, &width, &height, &depth);
    963 
    964    info[8] = width;
    965    info[9] = height;
    966    info[10] = depth;
    967    switch (res->base.target) {
    968    case PIPE_TEXTURE_1D_ARRAY:
    969       info[11] = 1;
    970       break;
    971    case PIPE_TEXTURE_2D:
    972    case PIPE_TEXTURE_RECT:
    973       info[11] = 2;
    974       break;
    975    case PIPE_TEXTURE_3D:
    976       info[11] = 3;
    977       break;
    978    case PIPE_TEXTURE_2D_ARRAY:
    979    case PIPE_TEXTURE_CUBE:
    980    case PIPE_TEXTURE_CUBE_ARRAY:
    981       info[11] = 4;
    982       break;
    983    default:
    984       info[11] = 0;
    985       break;
    986    }
    987    log2cpp = (0xf000 & nve4_su_format_aux_map[view->format]) >> 12;
    988 
    989    /* Stick the blockwidth (ie. number of bytes per pixel) to check if the
    990     * format doesn't mismatch. */
    991    info[12] = util_format_get_blocksize(view->format);
    992 
    993    /* limit in bytes for raw access */
    994    info[13] = (0x06 << 22) | ((width << log2cpp) - 1);
    995 
    996    info[1] = nve4_su_format_map[view->format];
    997 
    998 #if 0
    999    switch (util_format_get_blocksizebits(view->format)) {
   1000    case  16: info[1] |= 1 << 16; break;
   1001    case  32: info[1] |= 2 << 16; break;
   1002    case  64: info[1] |= 3 << 16; break;
   1003    case 128: info[1] |= 4 << 16; break;
   1004    default:
   1005       break;
   1006    }
   1007 #else
   1008    info[1] |= log2cpp << 16;
   1009    info[1] |=  0x4000;
   1010    info[1] |= (0x0f00 & nve4_su_format_aux_map[view->format]);
   1011 #endif
   1012 
   1013    if (res->base.target == PIPE_BUFFER) {
   1014       address += view->u.buf.offset;
   1015 
   1016       info[0]  = address >> 8;
   1017       info[2]  = width - 1;
   1018       info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22;
   1019       info[3]  = 0;
   1020       info[4]  = 0;
   1021       info[5]  = 0;
   1022       info[6]  = 0;
   1023       info[7]  = 0;
   1024       info[14] = 0;
   1025       info[15] = 0;
   1026    } else {
   1027       struct nv50_miptree *mt = nv50_miptree(&res->base);
   1028       struct nv50_miptree_level *lvl = &mt->level[view->u.tex.level];
   1029       const unsigned z = view->u.tex.first_layer;
   1030 
   1031       if (z) {
   1032          if (mt->layout_3d) {
   1033             address += nvc0_mt_zslice_offset(mt, view->u.tex.level, z);
   1034             /* doesn't work if z passes z-tile boundary */
   1035             if (depth > 1) {
   1036                pipe_debug_message(&nvc0->base.debug, CONFORMANCE,
   1037                                   "3D images are not really supported!");
   1038                debug_printf("3D images are not really supported!\n");
   1039             }
   1040          } else {
   1041             address += mt->layer_stride * z;
   1042          }
   1043       }
   1044       address += lvl->offset;
   1045 
   1046       info[0]  = address >> 8;
   1047       info[2]  = (width << mt->ms_x) - 1;
   1048       /* NOTE: this is really important: */
   1049       info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22;
   1050       info[3]  = (0x88 << 24) | (lvl->pitch / 64);
   1051       info[4]  = (height << mt->ms_y) - 1;
   1052       info[4] |= (lvl->tile_mode & 0x0f0) << 25;
   1053       info[4] |= NVC0_TILE_SHIFT_Y(lvl->tile_mode) << 22;
   1054       info[5]  = mt->layer_stride >> 8;
   1055       info[6]  = depth - 1;
   1056       info[6] |= (lvl->tile_mode & 0xf00) << 21;
   1057       info[6] |= NVC0_TILE_SHIFT_Z(lvl->tile_mode) << 22;
   1058       info[7]  = 0;
   1059       info[14] = mt->ms_x;
   1060       info[15] = mt->ms_y;
   1061    }
   1062 }
   1063 
   1064 static inline void
   1065 nvc0_set_surface_info(struct nouveau_pushbuf *push,
   1066                       const struct pipe_image_view *view, uint64_t address,
   1067                       int width, int height, int depth)
   1068 {
   1069    struct nv04_resource *res;
   1070    uint32_t *const info = push->cur;
   1071 
   1072    push->cur += 16;
   1073 
   1074    /* Make sure to always initialize the surface information area because it's
   1075     * used to check if the given image is bound or not. */
   1076    memset(info, 0, 16 * sizeof(*info));
   1077 
   1078    if (!view || !view->resource)
   1079       return;
   1080    res = nv04_resource(view->resource);
   1081 
   1082    /* Stick the image dimensions for the imageSize() builtin. */
   1083    info[8] = width;
   1084    info[9] = height;
   1085    info[10] = depth;
   1086 
   1087    /* Stick the blockwidth (ie. number of bytes per pixel) to calculate pixel
   1088     * offset and to check if the format doesn't mismatch. */
   1089    info[12] = util_format_get_blocksize(view->format);
   1090 
   1091    if (res->base.target == PIPE_BUFFER) {
   1092       info[0]  = address >> 8;
   1093       info[2]  = width;
   1094    } else {
   1095       struct nv50_miptree *mt = nv50_miptree(&res->base);
   1096 
   1097       info[0]  = address >> 8;
   1098       info[2]  = width;
   1099       info[4]  = height;
   1100       info[5]  = mt->layer_stride >> 8;
   1101       info[6]  = depth;
   1102       info[14] = mt->ms_x;
   1103       info[15] = mt->ms_y;
   1104    }
   1105 }
   1106 
   1107 void
   1108 nvc0_validate_suf(struct nvc0_context *nvc0, int s)
   1109 {
   1110    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   1111    struct nvc0_screen *screen = nvc0->screen;
   1112 
   1113    for (int i = 0; i < NVC0_MAX_IMAGES; ++i) {
   1114       struct pipe_image_view *view = &nvc0->images[s][i];
   1115       int width, height, depth;
   1116       uint64_t address = 0;
   1117 
   1118       if (s == 5)
   1119          BEGIN_NVC0(push, NVC0_CP(IMAGE(i)), 6);
   1120       else
   1121          BEGIN_NVC0(push, NVC0_3D(IMAGE(i)), 6);
   1122 
   1123       if (view->resource) {
   1124          struct nv04_resource *res = nv04_resource(view->resource);
   1125          unsigned rt = nvc0_format_table[view->format].rt;
   1126 
   1127          if (util_format_is_depth_or_stencil(view->format))
   1128             rt = rt << 12;
   1129          else
   1130             rt = (rt << 4) | (0x14 << 12);
   1131 
   1132          /* get surface dimensions based on the target. */
   1133          nvc0_get_surface_dims(view, &width, &height, &depth);
   1134 
   1135          address = res->address;
   1136          if (res->base.target == PIPE_BUFFER) {
   1137             unsigned blocksize = util_format_get_blocksize(view->format);
   1138 
   1139             address += view->u.buf.offset;
   1140             assert(!(address & 0xff));
   1141 
   1142             if (view->access & PIPE_IMAGE_ACCESS_WRITE)
   1143                nvc0_mark_image_range_valid(view);
   1144 
   1145             PUSH_DATAh(push, address);
   1146             PUSH_DATA (push, address);
   1147             PUSH_DATA (push, align(width * blocksize, 0x100));
   1148             PUSH_DATA (push, NVC0_3D_IMAGE_HEIGHT_LINEAR | 1);
   1149             PUSH_DATA (push, rt);
   1150             PUSH_DATA (push, 0);
   1151          } else {
   1152             struct nv50_miptree *mt = nv50_miptree(view->resource);
   1153             struct nv50_miptree_level *lvl = &mt->level[view->u.tex.level];
   1154             const unsigned z = view->u.tex.first_layer;
   1155 
   1156             if (mt->layout_3d) {
   1157                address += nvc0_mt_zslice_offset(mt, view->u.tex.level, z);
   1158                if (depth >= 1) {
   1159                   pipe_debug_message(&nvc0->base.debug, CONFORMANCE,
   1160                                      "3D images are not supported!");
   1161                   debug_printf("3D images are not supported!\n");
   1162                }
   1163             } else {
   1164                address += mt->layer_stride * z;
   1165             }
   1166             address += lvl->offset;
   1167 
   1168             PUSH_DATAh(push, address);
   1169             PUSH_DATA (push, address);
   1170             PUSH_DATA (push, width << mt->ms_x);
   1171             PUSH_DATA (push, height << mt->ms_y);
   1172             PUSH_DATA (push, rt);
   1173             PUSH_DATA (push, lvl->tile_mode & 0xff); /* mask out z-tiling */
   1174          }
   1175 
   1176          if (s == 5)
   1177             BCTX_REFN(nvc0->bufctx_cp, CP_SUF, res, RDWR);
   1178          else
   1179             BCTX_REFN(nvc0->bufctx_3d, 3D_SUF, res, RDWR);
   1180       } else {
   1181          PUSH_DATA(push, 0);
   1182          PUSH_DATA(push, 0);
   1183          PUSH_DATA(push, 0);
   1184          PUSH_DATA(push, 0);
   1185          PUSH_DATA(push, 0x14000);
   1186          PUSH_DATA(push, 0);
   1187       }
   1188 
   1189       /* stick surface information into the driver constant buffer */
   1190       if (s == 5)
   1191          BEGIN_NVC0(push, NVC0_CP(CB_SIZE), 3);
   1192       else
   1193          BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
   1194       PUSH_DATA (push, NVC0_CB_AUX_SIZE);
   1195       PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
   1196       PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
   1197       if (s == 5)
   1198          BEGIN_1IC0(push, NVC0_CP(CB_POS), 1 + 16);
   1199       else
   1200          BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 16);
   1201       PUSH_DATA (push, NVC0_CB_AUX_SU_INFO(i));
   1202 
   1203       nvc0_set_surface_info(push, view, address, width, height, depth);
   1204    }
   1205 }
   1206 
   1207 static inline void
   1208 nvc0_update_surface_bindings(struct nvc0_context *nvc0)
   1209 {
   1210    nvc0_validate_suf(nvc0, 4);
   1211 
   1212    /* Invalidate all COMPUTE images because they are aliased with FRAGMENT. */
   1213    nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
   1214    nvc0->dirty_cp |= NVC0_NEW_CP_SURFACES;
   1215    nvc0->images_dirty[5] |= nvc0->images_valid[5];
   1216 }
   1217 
   1218 static void
   1219 gm107_validate_surfaces(struct nvc0_context *nvc0,
   1220                         struct pipe_image_view *view, int stage, int slot)
   1221 {
   1222    struct nv04_resource *res = nv04_resource(view->resource);
   1223    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   1224    struct nvc0_screen *screen = nvc0->screen;
   1225    struct nv50_tic_entry *tic;
   1226 
   1227    tic = nv50_tic_entry(nvc0->images_tic[stage][slot]);
   1228 
   1229    res = nv04_resource(tic->pipe.texture);
   1230    nvc0_update_tic(nvc0, tic, res);
   1231 
   1232    if (tic->id < 0) {
   1233       tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
   1234 
   1235       /* upload the texture view */
   1236       nve4_p2mf_push_linear(&nvc0->base, nvc0->screen->txc, tic->id * 32,
   1237                             NV_VRAM_DOMAIN(&nvc0->screen->base), 32, tic->tic);
   1238 
   1239       BEGIN_NVC0(push, NVC0_3D(TIC_FLUSH), 1);
   1240       PUSH_DATA (push, 0);
   1241    } else
   1242    if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
   1243       BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
   1244       PUSH_DATA (push, (tic->id << 4) | 1);
   1245    }
   1246    nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
   1247 
   1248    res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
   1249    res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
   1250 
   1251    BCTX_REFN(nvc0->bufctx_3d, 3D_SUF, res, RD);
   1252 
   1253    /* upload the texture handle */
   1254    BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
   1255    PUSH_DATA (push, NVC0_CB_AUX_SIZE);
   1256    PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(stage));
   1257    PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(stage));
   1258    BEGIN_NVC0(push, NVC0_3D(CB_POS), 2);
   1259    PUSH_DATA (push, NVC0_CB_AUX_TEX_INFO(slot + 32));
   1260    PUSH_DATA (push, tic->id);
   1261 }
   1262 
   1263 static inline void
   1264 nve4_update_surface_bindings(struct nvc0_context *nvc0)
   1265 {
   1266    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   1267    struct nvc0_screen *screen = nvc0->screen;
   1268    int i, j, s;
   1269 
   1270    for (s = 0; s < 5; s++) {
   1271       if (!nvc0->images_dirty[s])
   1272          continue;
   1273 
   1274       for (i = 0; i < NVC0_MAX_IMAGES; ++i) {
   1275          struct pipe_image_view *view = &nvc0->images[s][i];
   1276 
   1277          BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
   1278          PUSH_DATA (push, NVC0_CB_AUX_SIZE);
   1279          PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
   1280          PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
   1281          BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 16);
   1282          PUSH_DATA (push, NVC0_CB_AUX_SU_INFO(i));
   1283 
   1284          if (view->resource) {
   1285             struct nv04_resource *res = nv04_resource(view->resource);
   1286 
   1287             if (res->base.target == PIPE_BUFFER) {
   1288                if (view->access & PIPE_IMAGE_ACCESS_WRITE)
   1289                   nvc0_mark_image_range_valid(view);
   1290             }
   1291 
   1292             nve4_set_surface_info(push, view, nvc0);
   1293             BCTX_REFN(nvc0->bufctx_3d, 3D_SUF, res, RDWR);
   1294 
   1295             if (nvc0->screen->base.class_3d >= GM107_3D_CLASS)
   1296                gm107_validate_surfaces(nvc0, view, s, i);
   1297          } else {
   1298             for (j = 0; j < 16; j++)
   1299                PUSH_DATA(push, 0);
   1300          }
   1301       }
   1302    }
   1303 }
   1304 
   1305 void
   1306 nvc0_validate_surfaces(struct nvc0_context *nvc0)
   1307 {
   1308    if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
   1309       nve4_update_surface_bindings(nvc0);
   1310    } else {
   1311       nvc0_update_surface_bindings(nvc0);
   1312    }
   1313 }
   1314 
   1315 static uint64_t
   1316 nve4_create_image_handle(struct pipe_context *pipe,
   1317                          const struct pipe_image_view *view)
   1318 {
   1319    struct nvc0_context *nvc0 = nvc0_context(pipe);
   1320    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
   1321    struct nvc0_screen *screen = nvc0->screen;
   1322    int i = screen->img.next, s;
   1323 
   1324    while (screen->img.entries[i]) {
   1325       i = (i + 1) & (NVE4_IMG_MAX_HANDLES - 1);
   1326       if (i == screen->img.next)
   1327          return 0;
   1328    }
   1329 
   1330    screen->img.next = (i + 1) & (NVE4_IMG_MAX_HANDLES - 1);
   1331    screen->img.entries[i] = calloc(1, sizeof(struct pipe_image_view));
   1332    *screen->img.entries[i] = *view;
   1333 
   1334    for (s = 0; s < 6; s++) {
   1335       BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
   1336       PUSH_DATA (push, NVC0_CB_AUX_SIZE);
   1337       PUSH_DATAh(push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
   1338       PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(s));
   1339       BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 16);
   1340       PUSH_DATA (push, NVC0_CB_AUX_BINDLESS_INFO(i));
   1341       nve4_set_surface_info(push, view, nvc0);
   1342    }
   1343 
   1344    return 0x100000000ULL | i;
   1345 }
   1346 
   1347 static void
   1348 nve4_delete_image_handle(struct pipe_context *pipe, uint64_t handle)
   1349 {
   1350    struct nvc0_context *nvc0 = nvc0_context(pipe);
   1351    struct nvc0_screen *screen = nvc0->screen;
   1352    int i = handle & (NVE4_IMG_MAX_HANDLES - 1);
   1353 
   1354    free(screen->img.entries[i]);
   1355    screen->img.entries[i] = NULL;
   1356 }
   1357 
   1358 static void
   1359 nve4_make_image_handle_resident(struct pipe_context *pipe, uint64_t handle,
   1360                                 unsigned access, bool resident)
   1361 {
   1362    struct nvc0_context *nvc0 = nvc0_context(pipe);
   1363    struct nvc0_screen *screen = nvc0->screen;
   1364 
   1365    if (resident) {
   1366       struct nvc0_resident *res = calloc(1, sizeof(struct nvc0_resident));
   1367       struct pipe_image_view *view =
   1368          screen->img.entries[handle & (NVE4_IMG_MAX_HANDLES - 1)];
   1369       assert(view);
   1370 
   1371       if (view->resource->target == PIPE_BUFFER &&
   1372           access & PIPE_IMAGE_ACCESS_WRITE)
   1373          nvc0_mark_image_range_valid(view);
   1374       res->handle = handle;
   1375       res->buf = nv04_resource(view->resource);
   1376       res->flags = (access & 3) << 8;
   1377       list_add(&res->list, &nvc0->img_head);
   1378    } else {
   1379       list_for_each_entry_safe(struct nvc0_resident, pos, &nvc0->img_head, list) {
   1380          if (pos->handle == handle) {
   1381             list_del(&pos->list);
   1382             free(pos);
   1383             break;
   1384          }
   1385       }
   1386    }
   1387 }
   1388 
   1389 void
   1390 nvc0_init_bindless_functions(struct pipe_context *pipe) {
   1391    pipe->create_texture_handle = nve4_create_texture_handle;
   1392    pipe->delete_texture_handle = nve4_delete_texture_handle;
   1393    pipe->make_texture_handle_resident = nve4_make_texture_handle_resident;
   1394 
   1395    pipe->create_image_handle = nve4_create_image_handle;
   1396    pipe->delete_image_handle = nve4_delete_image_handle;
   1397    pipe->make_image_handle_resident = nve4_make_image_handle_resident;
   1398 }
   1399 
   1400 
   1401 static const uint8_t nve4_su_format_map[PIPE_FORMAT_COUNT] =
   1402 {
   1403    [PIPE_FORMAT_R32G32B32A32_FLOAT] = GK104_IMAGE_FORMAT_RGBA32_FLOAT,
   1404    [PIPE_FORMAT_R32G32B32A32_SINT] = GK104_IMAGE_FORMAT_RGBA32_SINT,
   1405    [PIPE_FORMAT_R32G32B32A32_UINT] = GK104_IMAGE_FORMAT_RGBA32_UINT,
   1406    [PIPE_FORMAT_R16G16B16A16_FLOAT] = GK104_IMAGE_FORMAT_RGBA16_FLOAT,
   1407    [PIPE_FORMAT_R16G16B16A16_UNORM] = GK104_IMAGE_FORMAT_RGBA16_UNORM,
   1408    [PIPE_FORMAT_R16G16B16A16_SNORM] = GK104_IMAGE_FORMAT_RGBA16_SNORM,
   1409    [PIPE_FORMAT_R16G16B16A16_SINT] = GK104_IMAGE_FORMAT_RGBA16_SINT,
   1410    [PIPE_FORMAT_R16G16B16A16_UINT] = GK104_IMAGE_FORMAT_RGBA16_UINT,
   1411    [PIPE_FORMAT_B8G8R8A8_UNORM] = GK104_IMAGE_FORMAT_BGRA8_UNORM,
   1412    [PIPE_FORMAT_R8G8B8A8_UNORM] = GK104_IMAGE_FORMAT_RGBA8_UNORM,
   1413    [PIPE_FORMAT_R8G8B8A8_SNORM] = GK104_IMAGE_FORMAT_RGBA8_SNORM,
   1414    [PIPE_FORMAT_R8G8B8A8_SINT] = GK104_IMAGE_FORMAT_RGBA8_SINT,
   1415    [PIPE_FORMAT_R8G8B8A8_UINT] = GK104_IMAGE_FORMAT_RGBA8_UINT,
   1416    [PIPE_FORMAT_R11G11B10_FLOAT] = GK104_IMAGE_FORMAT_R11G11B10_FLOAT,
   1417    [PIPE_FORMAT_R10G10B10A2_UNORM] = GK104_IMAGE_FORMAT_RGB10_A2_UNORM,
   1418    [PIPE_FORMAT_R10G10B10A2_UINT] = GK104_IMAGE_FORMAT_RGB10_A2_UINT,
   1419    [PIPE_FORMAT_R32G32_FLOAT] = GK104_IMAGE_FORMAT_RG32_FLOAT,
   1420    [PIPE_FORMAT_R32G32_SINT] = GK104_IMAGE_FORMAT_RG32_SINT,
   1421    [PIPE_FORMAT_R32G32_UINT] = GK104_IMAGE_FORMAT_RG32_UINT,
   1422    [PIPE_FORMAT_R16G16_FLOAT] = GK104_IMAGE_FORMAT_RG16_FLOAT,
   1423    [PIPE_FORMAT_R16G16_UNORM] = GK104_IMAGE_FORMAT_RG16_UNORM,
   1424    [PIPE_FORMAT_R16G16_SNORM] = GK104_IMAGE_FORMAT_RG16_SNORM,
   1425    [PIPE_FORMAT_R16G16_SINT] = GK104_IMAGE_FORMAT_RG16_SINT,
   1426    [PIPE_FORMAT_R16G16_UINT] = GK104_IMAGE_FORMAT_RG16_UINT,
   1427    [PIPE_FORMAT_R8G8_UNORM] = GK104_IMAGE_FORMAT_RG8_UNORM,
   1428    [PIPE_FORMAT_R8G8_SNORM] = GK104_IMAGE_FORMAT_RG8_SNORM,
   1429    [PIPE_FORMAT_R8G8_SINT] = GK104_IMAGE_FORMAT_RG8_SINT,
   1430    [PIPE_FORMAT_R8G8_UINT] = GK104_IMAGE_FORMAT_RG8_UINT,
   1431    [PIPE_FORMAT_R32_FLOAT] = GK104_IMAGE_FORMAT_R32_FLOAT,
   1432    [PIPE_FORMAT_R32_SINT] = GK104_IMAGE_FORMAT_R32_SINT,
   1433    [PIPE_FORMAT_R32_UINT] = GK104_IMAGE_FORMAT_R32_UINT,
   1434    [PIPE_FORMAT_R16_FLOAT] = GK104_IMAGE_FORMAT_R16_FLOAT,
   1435    [PIPE_FORMAT_R16_UNORM] = GK104_IMAGE_FORMAT_R16_UNORM,
   1436    [PIPE_FORMAT_R16_SNORM] = GK104_IMAGE_FORMAT_R16_SNORM,
   1437    [PIPE_FORMAT_R16_SINT] = GK104_IMAGE_FORMAT_R16_SINT,
   1438    [PIPE_FORMAT_R16_UINT] = GK104_IMAGE_FORMAT_R16_UINT,
   1439    [PIPE_FORMAT_R8_UNORM] = GK104_IMAGE_FORMAT_R8_UNORM,
   1440    [PIPE_FORMAT_R8_SNORM] = GK104_IMAGE_FORMAT_R8_SNORM,
   1441    [PIPE_FORMAT_R8_SINT] = GK104_IMAGE_FORMAT_R8_SINT,
   1442    [PIPE_FORMAT_R8_UINT] = GK104_IMAGE_FORMAT_R8_UINT,
   1443 };
   1444 
   1445 /* Auxiliary format description values for surface instructions.
   1446  * (log2(bytes per pixel) << 12) | (unk8 << 8) | unk22
   1447  */
   1448 static const uint16_t nve4_su_format_aux_map[PIPE_FORMAT_COUNT] =
   1449 {
   1450    [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x4842,
   1451    [PIPE_FORMAT_R32G32B32A32_SINT] = 0x4842,
   1452    [PIPE_FORMAT_R32G32B32A32_UINT] = 0x4842,
   1453 
   1454    [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x3933,
   1455    [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x3933,
   1456    [PIPE_FORMAT_R16G16B16A16_SINT] = 0x3933,
   1457    [PIPE_FORMAT_R16G16B16A16_UINT] = 0x3933,
   1458    [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3933,
   1459 
   1460    [PIPE_FORMAT_R32G32_FLOAT] = 0x3433,
   1461    [PIPE_FORMAT_R32G32_SINT] = 0x3433,
   1462    [PIPE_FORMAT_R32G32_UINT] = 0x3433,
   1463 
   1464    [PIPE_FORMAT_R10G10B10A2_UNORM] = 0x2a24,
   1465    [PIPE_FORMAT_R10G10B10A2_UINT] = 0x2a24,
   1466    [PIPE_FORMAT_B8G8R8A8_UNORM] = 0x2a24,
   1467    [PIPE_FORMAT_R8G8B8A8_UNORM] = 0x2a24,
   1468    [PIPE_FORMAT_R8G8B8A8_SNORM] = 0x2a24,
   1469    [PIPE_FORMAT_R8G8B8A8_SINT] = 0x2a24,
   1470    [PIPE_FORMAT_R8G8B8A8_UINT] = 0x2a24,
   1471    [PIPE_FORMAT_R11G11B10_FLOAT] = 0x2a24,
   1472 
   1473    [PIPE_FORMAT_R16G16_UNORM] = 0x2524,
   1474    [PIPE_FORMAT_R16G16_SNORM] = 0x2524,
   1475    [PIPE_FORMAT_R16G16_SINT] = 0x2524,
   1476    [PIPE_FORMAT_R16G16_UINT] = 0x2524,
   1477    [PIPE_FORMAT_R16G16_FLOAT] = 0x2524,
   1478 
   1479    [PIPE_FORMAT_R32_SINT] = 0x2024,
   1480    [PIPE_FORMAT_R32_UINT] = 0x2024,
   1481    [PIPE_FORMAT_R32_FLOAT] = 0x2024,
   1482 
   1483    [PIPE_FORMAT_R8G8_UNORM] = 0x1615,
   1484    [PIPE_FORMAT_R8G8_SNORM] = 0x1615,
   1485    [PIPE_FORMAT_R8G8_SINT] = 0x1615,
   1486    [PIPE_FORMAT_R8G8_UINT] = 0x1615,
   1487 
   1488    [PIPE_FORMAT_R16_UNORM] = 0x1115,
   1489    [PIPE_FORMAT_R16_SNORM] = 0x1115,
   1490    [PIPE_FORMAT_R16_SINT] = 0x1115,
   1491    [PIPE_FORMAT_R16_UINT] = 0x1115,
   1492    [PIPE_FORMAT_R16_FLOAT] = 0x1115,
   1493 
   1494    [PIPE_FORMAT_R8_UNORM] = 0x0206,
   1495    [PIPE_FORMAT_R8_SNORM] = 0x0206,
   1496    [PIPE_FORMAT_R8_SINT] = 0x0206,
   1497    [PIPE_FORMAT_R8_UINT] = 0x0206
   1498 };
   1499 
   1500 /* NOTE: These are hardcoded offsets for the shader library.
   1501  * TODO: Automate them.
   1502  */
   1503 static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT] =
   1504 {
   1505    [PIPE_FORMAT_R32G32B32A32_FLOAT] = 0x218,
   1506    [PIPE_FORMAT_R32G32B32A32_SINT]  = 0x218,
   1507    [PIPE_FORMAT_R32G32B32A32_UINT]  = 0x218,
   1508    [PIPE_FORMAT_R16G16B16A16_UNORM] = 0x248,
   1509    [PIPE_FORMAT_R16G16B16A16_SNORM] = 0x2b8,
   1510    [PIPE_FORMAT_R16G16B16A16_SINT]  = 0x330,
   1511    [PIPE_FORMAT_R16G16B16A16_UINT]  = 0x388,
   1512    [PIPE_FORMAT_R16G16B16A16_FLOAT] = 0x3d8,
   1513    [PIPE_FORMAT_R32G32_FLOAT]       = 0x428,
   1514    [PIPE_FORMAT_R32G32_SINT]        = 0x468,
   1515    [PIPE_FORMAT_R32G32_UINT]        = 0x468,
   1516    [PIPE_FORMAT_R10G10B10A2_UNORM]  = 0x4a8,
   1517    [PIPE_FORMAT_R10G10B10A2_UINT]   = 0x530,
   1518    [PIPE_FORMAT_R8G8B8A8_UNORM]     = 0x588,
   1519    [PIPE_FORMAT_R8G8B8A8_SNORM]     = 0x5f8,
   1520    [PIPE_FORMAT_R8G8B8A8_SINT]      = 0x670,
   1521    [PIPE_FORMAT_R8G8B8A8_UINT]      = 0x6c8,
   1522    [PIPE_FORMAT_B5G6R5_UNORM]       = 0x718,
   1523    [PIPE_FORMAT_B5G5R5X1_UNORM]     = 0x7a0,
   1524    [PIPE_FORMAT_R16G16_UNORM]       = 0x828,
   1525    [PIPE_FORMAT_R16G16_SNORM]       = 0x890,
   1526    [PIPE_FORMAT_R16G16_SINT]        = 0x8f0,
   1527    [PIPE_FORMAT_R16G16_UINT]        = 0x948,
   1528    [PIPE_FORMAT_R16G16_FLOAT]       = 0x998,
   1529    [PIPE_FORMAT_R32_FLOAT]          = 0x9e8,
   1530    [PIPE_FORMAT_R32_SINT]           = 0xa30,
   1531    [PIPE_FORMAT_R32_UINT]           = 0xa30,
   1532    [PIPE_FORMAT_R8G8_UNORM]         = 0xa78,
   1533    [PIPE_FORMAT_R8G8_SNORM]         = 0xae0,
   1534    [PIPE_FORMAT_R8G8_UINT]          = 0xb48,
   1535    [PIPE_FORMAT_R8G8_SINT]          = 0xb98,
   1536    [PIPE_FORMAT_R16_UNORM]          = 0xbe8,
   1537    [PIPE_FORMAT_R16_SNORM]          = 0xc48,
   1538    [PIPE_FORMAT_R16_SINT]           = 0xca0,
   1539    [PIPE_FORMAT_R16_UINT]           = 0xce8,
   1540    [PIPE_FORMAT_R16_FLOAT]          = 0xd30,
   1541    [PIPE_FORMAT_R8_UNORM]           = 0xd88,
   1542    [PIPE_FORMAT_R8_SNORM]           = 0xde0,
   1543    [PIPE_FORMAT_R8_SINT]            = 0xe38,
   1544    [PIPE_FORMAT_R8_UINT]            = 0xe88,
   1545    [PIPE_FORMAT_R11G11B10_FLOAT]    = 0xed0
   1546 };
   1547