Home | History | Annotate | Download | only in ilo
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2012-2013 LunarG, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included
     14  * in all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     22  * DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors:
     25  *    Chia-I Wu <olv (at) lunarg.com>
     26  */
     27 
     28 #include "util/u_dual_blend.h"
     29 #include "util/u_dynarray.h"
     30 #include "util/u_framebuffer.h"
     31 #include "util/u_helpers.h"
     32 #include "util/u_resource.h"
     33 #include "util/u_upload_mgr.h"
     34 
     35 #include "ilo_context.h"
     36 #include "ilo_format.h"
     37 #include "ilo_resource.h"
     38 #include "ilo_shader.h"
     39 #include "ilo_state.h"
     40 
     41 /**
     42  * Translate a pipe primitive type to the matching hardware primitive type.
     43  */
     44 static enum gen_3dprim_type
     45 ilo_translate_draw_mode(unsigned mode)
     46 {
     47    static const enum gen_3dprim_type prim_mapping[PIPE_PRIM_MAX] = {
     48       [PIPE_PRIM_POINTS]                     = GEN6_3DPRIM_POINTLIST,
     49       [PIPE_PRIM_LINES]                      = GEN6_3DPRIM_LINELIST,
     50       [PIPE_PRIM_LINE_LOOP]                  = GEN6_3DPRIM_LINELOOP,
     51       [PIPE_PRIM_LINE_STRIP]                 = GEN6_3DPRIM_LINESTRIP,
     52       [PIPE_PRIM_TRIANGLES]                  = GEN6_3DPRIM_TRILIST,
     53       [PIPE_PRIM_TRIANGLE_STRIP]             = GEN6_3DPRIM_TRISTRIP,
     54       [PIPE_PRIM_TRIANGLE_FAN]               = GEN6_3DPRIM_TRIFAN,
     55       [PIPE_PRIM_QUADS]                      = GEN6_3DPRIM_QUADLIST,
     56       [PIPE_PRIM_QUAD_STRIP]                 = GEN6_3DPRIM_QUADSTRIP,
     57       [PIPE_PRIM_POLYGON]                    = GEN6_3DPRIM_POLYGON,
     58       [PIPE_PRIM_LINES_ADJACENCY]            = GEN6_3DPRIM_LINELIST_ADJ,
     59       [PIPE_PRIM_LINE_STRIP_ADJACENCY]       = GEN6_3DPRIM_LINESTRIP_ADJ,
     60       [PIPE_PRIM_TRIANGLES_ADJACENCY]        = GEN6_3DPRIM_TRILIST_ADJ,
     61       [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]   = GEN6_3DPRIM_TRISTRIP_ADJ,
     62    };
     63 
     64    assert(prim_mapping[mode]);
     65 
     66    return prim_mapping[mode];
     67 }
     68 
     69 static enum gen_index_format
     70 ilo_translate_index_size(unsigned index_size)
     71 {
     72    switch (index_size) {
     73    case 1:                             return GEN6_INDEX_BYTE;
     74    case 2:                             return GEN6_INDEX_WORD;
     75    case 4:                             return GEN6_INDEX_DWORD;
     76    default:
     77       assert(!"unknown index size");
     78       return GEN6_INDEX_BYTE;
     79    }
     80 }
     81 
     82 static enum gen_mip_filter
     83 ilo_translate_mip_filter(unsigned filter)
     84 {
     85    switch (filter) {
     86    case PIPE_TEX_MIPFILTER_NEAREST:    return GEN6_MIPFILTER_NEAREST;
     87    case PIPE_TEX_MIPFILTER_LINEAR:     return GEN6_MIPFILTER_LINEAR;
     88    case PIPE_TEX_MIPFILTER_NONE:       return GEN6_MIPFILTER_NONE;
     89    default:
     90       assert(!"unknown mipfilter");
     91       return GEN6_MIPFILTER_NONE;
     92    }
     93 }
     94 
     95 static int
     96 ilo_translate_img_filter(unsigned filter)
     97 {
     98    switch (filter) {
     99    case PIPE_TEX_FILTER_NEAREST:       return GEN6_MAPFILTER_NEAREST;
    100    case PIPE_TEX_FILTER_LINEAR:        return GEN6_MAPFILTER_LINEAR;
    101    default:
    102       assert(!"unknown sampler filter");
    103       return GEN6_MAPFILTER_NEAREST;
    104    }
    105 }
    106 
    107 static enum gen_texcoord_mode
    108 ilo_translate_address_wrap(unsigned wrap)
    109 {
    110    switch (wrap) {
    111    case PIPE_TEX_WRAP_CLAMP:           return GEN8_TEXCOORDMODE_HALF_BORDER;
    112    case PIPE_TEX_WRAP_REPEAT:          return GEN6_TEXCOORDMODE_WRAP;
    113    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:   return GEN6_TEXCOORDMODE_CLAMP;
    114    case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return GEN6_TEXCOORDMODE_CLAMP_BORDER;
    115    case PIPE_TEX_WRAP_MIRROR_REPEAT:   return GEN6_TEXCOORDMODE_MIRROR;
    116    case PIPE_TEX_WRAP_MIRROR_CLAMP:
    117    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
    118    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
    119    default:
    120       assert(!"unknown sampler wrap mode");
    121       return GEN6_TEXCOORDMODE_WRAP;
    122    }
    123 }
    124 
    125 static enum gen_aniso_ratio
    126 ilo_translate_max_anisotropy(unsigned max_anisotropy)
    127 {
    128    switch (max_anisotropy) {
    129    case 0: case 1: case 2:             return GEN6_ANISORATIO_2;
    130    case 3: case 4:                     return GEN6_ANISORATIO_4;
    131    case 5: case 6:                     return GEN6_ANISORATIO_6;
    132    case 7: case 8:                     return GEN6_ANISORATIO_8;
    133    case 9: case 10:                    return GEN6_ANISORATIO_10;
    134    case 11: case 12:                   return GEN6_ANISORATIO_12;
    135    case 13: case 14:                   return GEN6_ANISORATIO_14;
    136    default:                            return GEN6_ANISORATIO_16;
    137    }
    138 }
    139 
    140 static enum gen_prefilter_op
    141 ilo_translate_shadow_func(unsigned func)
    142 {
    143    /*
    144     * For PIPE_FUNC_x, the reference value is on the left-hand side of the
    145     * comparison, and 1.0 is returned when the comparison is true.
    146     *
    147     * For GEN6_PREFILTEROP_x, the reference value is on the right-hand side of
    148     * the comparison, and 0.0 is returned when the comparison is true.
    149     */
    150    switch (func) {
    151    case PIPE_FUNC_NEVER:               return GEN6_PREFILTEROP_ALWAYS;
    152    case PIPE_FUNC_LESS:                return GEN6_PREFILTEROP_LEQUAL;
    153    case PIPE_FUNC_EQUAL:               return GEN6_PREFILTEROP_NOTEQUAL;
    154    case PIPE_FUNC_LEQUAL:              return GEN6_PREFILTEROP_LESS;
    155    case PIPE_FUNC_GREATER:             return GEN6_PREFILTEROP_GEQUAL;
    156    case PIPE_FUNC_NOTEQUAL:            return GEN6_PREFILTEROP_EQUAL;
    157    case PIPE_FUNC_GEQUAL:              return GEN6_PREFILTEROP_GREATER;
    158    case PIPE_FUNC_ALWAYS:              return GEN6_PREFILTEROP_NEVER;
    159    default:
    160       assert(!"unknown shadow compare function");
    161       return GEN6_PREFILTEROP_NEVER;
    162    }
    163 }
    164 
    165 static enum gen_front_winding
    166 ilo_translate_front_ccw(unsigned front_ccw)
    167 {
    168    return (front_ccw) ? GEN6_FRONTWINDING_CCW : GEN6_FRONTWINDING_CW;
    169 }
    170 
    171 static enum gen_cull_mode
    172 ilo_translate_cull_face(unsigned cull_face)
    173 {
    174    switch (cull_face) {
    175    case PIPE_FACE_NONE:                return GEN6_CULLMODE_NONE;
    176    case PIPE_FACE_FRONT:               return GEN6_CULLMODE_FRONT;
    177    case PIPE_FACE_BACK:                return GEN6_CULLMODE_BACK;
    178    case PIPE_FACE_FRONT_AND_BACK:      return GEN6_CULLMODE_BOTH;
    179    default:
    180       assert(!"unknown face culling");
    181       return GEN6_CULLMODE_NONE;
    182    }
    183 }
    184 
    185 static enum gen_fill_mode
    186 ilo_translate_poly_mode(unsigned poly_mode)
    187 {
    188    switch (poly_mode) {
    189    case PIPE_POLYGON_MODE_FILL:        return GEN6_FILLMODE_SOLID;
    190    case PIPE_POLYGON_MODE_LINE:        return GEN6_FILLMODE_WIREFRAME;
    191    case PIPE_POLYGON_MODE_POINT:       return GEN6_FILLMODE_POINT;
    192    default:
    193       assert(!"unknown polygon mode");
    194       return GEN6_FILLMODE_SOLID;
    195    }
    196 }
    197 
    198 static enum gen_pixel_location
    199 ilo_translate_half_pixel_center(bool half_pixel_center)
    200 {
    201    return (half_pixel_center) ? GEN6_PIXLOC_CENTER : GEN6_PIXLOC_UL_CORNER;
    202 }
    203 
    204 static enum gen_compare_function
    205 ilo_translate_compare_func(unsigned func)
    206 {
    207    switch (func) {
    208    case PIPE_FUNC_NEVER:               return GEN6_COMPAREFUNCTION_NEVER;
    209    case PIPE_FUNC_LESS:                return GEN6_COMPAREFUNCTION_LESS;
    210    case PIPE_FUNC_EQUAL:               return GEN6_COMPAREFUNCTION_EQUAL;
    211    case PIPE_FUNC_LEQUAL:              return GEN6_COMPAREFUNCTION_LEQUAL;
    212    case PIPE_FUNC_GREATER:             return GEN6_COMPAREFUNCTION_GREATER;
    213    case PIPE_FUNC_NOTEQUAL:            return GEN6_COMPAREFUNCTION_NOTEQUAL;
    214    case PIPE_FUNC_GEQUAL:              return GEN6_COMPAREFUNCTION_GEQUAL;
    215    case PIPE_FUNC_ALWAYS:              return GEN6_COMPAREFUNCTION_ALWAYS;
    216    default:
    217       assert(!"unknown compare function");
    218       return GEN6_COMPAREFUNCTION_NEVER;
    219    }
    220 }
    221 
    222 static enum gen_stencil_op
    223 ilo_translate_stencil_op(unsigned stencil_op)
    224 {
    225    switch (stencil_op) {
    226    case PIPE_STENCIL_OP_KEEP:          return GEN6_STENCILOP_KEEP;
    227    case PIPE_STENCIL_OP_ZERO:          return GEN6_STENCILOP_ZERO;
    228    case PIPE_STENCIL_OP_REPLACE:       return GEN6_STENCILOP_REPLACE;
    229    case PIPE_STENCIL_OP_INCR:          return GEN6_STENCILOP_INCRSAT;
    230    case PIPE_STENCIL_OP_DECR:          return GEN6_STENCILOP_DECRSAT;
    231    case PIPE_STENCIL_OP_INCR_WRAP:     return GEN6_STENCILOP_INCR;
    232    case PIPE_STENCIL_OP_DECR_WRAP:     return GEN6_STENCILOP_DECR;
    233    case PIPE_STENCIL_OP_INVERT:        return GEN6_STENCILOP_INVERT;
    234    default:
    235       assert(!"unknown stencil op");
    236       return GEN6_STENCILOP_KEEP;
    237    }
    238 }
    239 
    240 static enum gen_logic_op
    241 ilo_translate_logicop(unsigned logicop)
    242 {
    243    switch (logicop) {
    244    case PIPE_LOGICOP_CLEAR:            return GEN6_LOGICOP_CLEAR;
    245    case PIPE_LOGICOP_NOR:              return GEN6_LOGICOP_NOR;
    246    case PIPE_LOGICOP_AND_INVERTED:     return GEN6_LOGICOP_AND_INVERTED;
    247    case PIPE_LOGICOP_COPY_INVERTED:    return GEN6_LOGICOP_COPY_INVERTED;
    248    case PIPE_LOGICOP_AND_REVERSE:      return GEN6_LOGICOP_AND_REVERSE;
    249    case PIPE_LOGICOP_INVERT:           return GEN6_LOGICOP_INVERT;
    250    case PIPE_LOGICOP_XOR:              return GEN6_LOGICOP_XOR;
    251    case PIPE_LOGICOP_NAND:             return GEN6_LOGICOP_NAND;
    252    case PIPE_LOGICOP_AND:              return GEN6_LOGICOP_AND;
    253    case PIPE_LOGICOP_EQUIV:            return GEN6_LOGICOP_EQUIV;
    254    case PIPE_LOGICOP_NOOP:             return GEN6_LOGICOP_NOOP;
    255    case PIPE_LOGICOP_OR_INVERTED:      return GEN6_LOGICOP_OR_INVERTED;
    256    case PIPE_LOGICOP_COPY:             return GEN6_LOGICOP_COPY;
    257    case PIPE_LOGICOP_OR_REVERSE:       return GEN6_LOGICOP_OR_REVERSE;
    258    case PIPE_LOGICOP_OR:               return GEN6_LOGICOP_OR;
    259    case PIPE_LOGICOP_SET:              return GEN6_LOGICOP_SET;
    260    default:
    261       assert(!"unknown logicop function");
    262       return GEN6_LOGICOP_CLEAR;
    263    }
    264 }
    265 
    266 static int
    267 ilo_translate_blend_func(unsigned blend)
    268 {
    269    switch (blend) {
    270    case PIPE_BLEND_ADD:                return GEN6_BLENDFUNCTION_ADD;
    271    case PIPE_BLEND_SUBTRACT:           return GEN6_BLENDFUNCTION_SUBTRACT;
    272    case PIPE_BLEND_REVERSE_SUBTRACT:   return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT;
    273    case PIPE_BLEND_MIN:                return GEN6_BLENDFUNCTION_MIN;
    274    case PIPE_BLEND_MAX:                return GEN6_BLENDFUNCTION_MAX;
    275    default:
    276       assert(!"unknown blend function");
    277       return GEN6_BLENDFUNCTION_ADD;
    278    }
    279 }
    280 
    281 static int
    282 ilo_translate_blend_factor(unsigned factor)
    283 {
    284    switch (factor) {
    285    case PIPE_BLENDFACTOR_ONE:                return GEN6_BLENDFACTOR_ONE;
    286    case PIPE_BLENDFACTOR_SRC_COLOR:          return GEN6_BLENDFACTOR_SRC_COLOR;
    287    case PIPE_BLENDFACTOR_SRC_ALPHA:          return GEN6_BLENDFACTOR_SRC_ALPHA;
    288    case PIPE_BLENDFACTOR_DST_ALPHA:          return GEN6_BLENDFACTOR_DST_ALPHA;
    289    case PIPE_BLENDFACTOR_DST_COLOR:          return GEN6_BLENDFACTOR_DST_COLOR;
    290    case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE;
    291    case PIPE_BLENDFACTOR_CONST_COLOR:        return GEN6_BLENDFACTOR_CONST_COLOR;
    292    case PIPE_BLENDFACTOR_CONST_ALPHA:        return GEN6_BLENDFACTOR_CONST_ALPHA;
    293    case PIPE_BLENDFACTOR_SRC1_COLOR:         return GEN6_BLENDFACTOR_SRC1_COLOR;
    294    case PIPE_BLENDFACTOR_SRC1_ALPHA:         return GEN6_BLENDFACTOR_SRC1_ALPHA;
    295    case PIPE_BLENDFACTOR_ZERO:               return GEN6_BLENDFACTOR_ZERO;
    296    case PIPE_BLENDFACTOR_INV_SRC_COLOR:      return GEN6_BLENDFACTOR_INV_SRC_COLOR;
    297    case PIPE_BLENDFACTOR_INV_SRC_ALPHA:      return GEN6_BLENDFACTOR_INV_SRC_ALPHA;
    298    case PIPE_BLENDFACTOR_INV_DST_ALPHA:      return GEN6_BLENDFACTOR_INV_DST_ALPHA;
    299    case PIPE_BLENDFACTOR_INV_DST_COLOR:      return GEN6_BLENDFACTOR_INV_DST_COLOR;
    300    case PIPE_BLENDFACTOR_INV_CONST_COLOR:    return GEN6_BLENDFACTOR_INV_CONST_COLOR;
    301    case PIPE_BLENDFACTOR_INV_CONST_ALPHA:    return GEN6_BLENDFACTOR_INV_CONST_ALPHA;
    302    case PIPE_BLENDFACTOR_INV_SRC1_COLOR:     return GEN6_BLENDFACTOR_INV_SRC1_COLOR;
    303    case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:     return GEN6_BLENDFACTOR_INV_SRC1_ALPHA;
    304    default:
    305       assert(!"unknown blend factor");
    306       return GEN6_BLENDFACTOR_ONE;
    307    }
    308 }
    309 
    310 static void
    311 finalize_shader_states(struct ilo_state_vector *vec)
    312 {
    313    unsigned type;
    314 
    315    for (type = 0; type < PIPE_SHADER_TYPES; type++) {
    316       struct ilo_shader_state *shader;
    317       uint32_t state;
    318 
    319       switch (type) {
    320       case PIPE_SHADER_VERTEX:
    321          shader = vec->vs;
    322          state = ILO_DIRTY_VS;
    323          break;
    324       case PIPE_SHADER_GEOMETRY:
    325          shader = vec->gs;
    326          state = ILO_DIRTY_GS;
    327          break;
    328       case PIPE_SHADER_FRAGMENT:
    329          shader = vec->fs;
    330          state = ILO_DIRTY_FS;
    331          break;
    332       default:
    333          shader = NULL;
    334          state = 0;
    335          break;
    336       }
    337 
    338       if (!shader)
    339          continue;
    340 
    341       /* compile if the shader or the states it depends on changed */
    342       if (vec->dirty & state) {
    343          ilo_shader_select_kernel(shader, vec, ILO_DIRTY_ALL);
    344       }
    345       else if (ilo_shader_select_kernel(shader, vec, vec->dirty)) {
    346          /* mark the state dirty if a new kernel is selected */
    347          vec->dirty |= state;
    348       }
    349 
    350       /* need to setup SBE for FS */
    351       if (type == PIPE_SHADER_FRAGMENT && vec->dirty &
    352             (state | ILO_DIRTY_GS | ILO_DIRTY_VS | ILO_DIRTY_RASTERIZER)) {
    353          if (ilo_shader_select_kernel_sbe(shader,
    354                (vec->gs) ? vec->gs : vec->vs, vec->rasterizer))
    355             vec->dirty |= state;
    356       }
    357    }
    358 }
    359 
    360 static void
    361 finalize_cbuf_state(struct ilo_context *ilo,
    362                     struct ilo_cbuf_state *cbuf,
    363                     const struct ilo_shader_state *sh)
    364 {
    365    uint32_t upload_mask = cbuf->enabled_mask;
    366 
    367    /* skip CBUF0 if the kernel does not need it */
    368    upload_mask &=
    369       ~ilo_shader_get_kernel_param(sh, ILO_KERNEL_SKIP_CBUF0_UPLOAD);
    370 
    371    while (upload_mask) {
    372       unsigned offset, i;
    373 
    374       i = u_bit_scan(&upload_mask);
    375       /* no need to upload */
    376       if (cbuf->cso[i].resource)
    377          continue;
    378 
    379       u_upload_data(ilo->uploader, 0, cbuf->cso[i].info.size, 16,
    380             cbuf->cso[i].user_buffer, &offset, &cbuf->cso[i].resource);
    381 
    382       cbuf->cso[i].info.vma = ilo_resource_get_vma(cbuf->cso[i].resource);
    383       cbuf->cso[i].info.offset = offset;
    384 
    385       memset(&cbuf->cso[i].surface, 0, sizeof(cbuf->cso[i].surface));
    386       ilo_state_surface_init_for_buffer(&cbuf->cso[i].surface,
    387             ilo->dev, &cbuf->cso[i].info);
    388 
    389       ilo->state_vector.dirty |= ILO_DIRTY_CBUF;
    390    }
    391 }
    392 
    393 static void
    394 finalize_constant_buffers(struct ilo_context *ilo)
    395 {
    396    struct ilo_state_vector *vec = &ilo->state_vector;
    397 
    398    if (vec->dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_VS))
    399       finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_VERTEX], vec->vs);
    400 
    401    if (ilo->state_vector.dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_FS))
    402       finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_FRAGMENT], vec->fs);
    403 }
    404 
    405 static void
    406 finalize_index_buffer(struct ilo_context *ilo)
    407 {
    408    const struct ilo_dev *dev = ilo->dev;
    409    struct ilo_state_vector *vec = &ilo->state_vector;
    410    const bool need_upload = (vec->draw->indexed &&
    411          (vec->ib.state.user_buffer ||
    412           vec->ib.state.offset % vec->ib.state.index_size));
    413    struct pipe_resource *current_hw_res = NULL;
    414    struct ilo_state_index_buffer_info info;
    415    int64_t vertex_start_bias = 0;
    416 
    417    if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload)
    418       return;
    419 
    420    /* make sure vec->ib.hw_resource changes when reallocated */
    421    pipe_resource_reference(&current_hw_res, vec->ib.hw_resource);
    422 
    423    if (need_upload) {
    424       const unsigned offset = vec->ib.state.index_size * vec->draw->start;
    425       const unsigned size = vec->ib.state.index_size * vec->draw->count;
    426       unsigned hw_offset;
    427 
    428       if (vec->ib.state.user_buffer) {
    429          u_upload_data(ilo->uploader, 0, size, 16,
    430                vec->ib.state.user_buffer + offset,
    431                &hw_offset, &vec->ib.hw_resource);
    432       } else {
    433          u_upload_buffer(ilo->uploader, 0,
    434                vec->ib.state.offset + offset, size, 16, vec->ib.state.buffer,
    435                &hw_offset, &vec->ib.hw_resource);
    436       }
    437 
    438       /* the HW offset should be aligned */
    439       assert(hw_offset % vec->ib.state.index_size == 0);
    440       vertex_start_bias = hw_offset / vec->ib.state.index_size;
    441 
    442       /*
    443        * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
    444        * resource
    445        */
    446       vertex_start_bias -= vec->draw->start;
    447    } else {
    448       pipe_resource_reference(&vec->ib.hw_resource, vec->ib.state.buffer);
    449 
    450       /* note that index size may be zero when the draw is not indexed */
    451       if (vec->draw->indexed)
    452          vertex_start_bias = vec->ib.state.offset / vec->ib.state.index_size;
    453    }
    454 
    455    vec->draw_info.vertex_start += vertex_start_bias;
    456 
    457    /* treat the IB as clean if the HW states do not change */
    458    if (vec->ib.hw_resource == current_hw_res &&
    459        vec->ib.hw_index_size == vec->ib.state.index_size)
    460       vec->dirty &= ~ILO_DIRTY_IB;
    461    else
    462       vec->ib.hw_index_size = vec->ib.state.index_size;
    463 
    464    pipe_resource_reference(&current_hw_res, NULL);
    465 
    466    memset(&info, 0, sizeof(info));
    467    if (vec->ib.hw_resource) {
    468       info.vma = ilo_resource_get_vma(vec->ib.hw_resource);
    469       info.size = info.vma->vm_size;
    470       info.format = ilo_translate_index_size(vec->ib.hw_index_size);
    471    }
    472 
    473    ilo_state_index_buffer_set_info(&vec->ib.ib, dev, &info);
    474 }
    475 
    476 static void
    477 finalize_vertex_elements(struct ilo_context *ilo)
    478 {
    479    const struct ilo_dev *dev = ilo->dev;
    480    struct ilo_state_vector *vec = &ilo->state_vector;
    481    struct ilo_ve_state *ve = vec->ve;
    482    const bool last_element_edge_flag = (vec->vs &&
    483          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG));
    484    const bool prepend_vertexid = (vec->vs &&
    485          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_VERTEXID));
    486    const bool prepend_instanceid = (vec->vs &&
    487          ilo_shader_get_kernel_param(vec->vs,
    488             ILO_KERNEL_VS_INPUT_INSTANCEID));
    489    const enum gen_index_format index_format = (vec->draw->indexed) ?
    490       ilo_translate_index_size(vec->ib.state.index_size) : GEN6_INDEX_DWORD;
    491 
    492    /* check for non-orthogonal states */
    493    if (ve->vf_params.cv_topology != vec->draw_info.topology ||
    494        ve->vf_params.prepend_vertexid != prepend_vertexid ||
    495        ve->vf_params.prepend_instanceid != prepend_instanceid ||
    496        ve->vf_params.last_element_edge_flag != last_element_edge_flag ||
    497        ve->vf_params.cv_index_format != index_format ||
    498        ve->vf_params.cut_index_enable != vec->draw->primitive_restart ||
    499        ve->vf_params.cut_index != vec->draw->restart_index) {
    500       ve->vf_params.cv_topology = vec->draw_info.topology;
    501       ve->vf_params.prepend_vertexid = prepend_vertexid;
    502       ve->vf_params.prepend_instanceid = prepend_instanceid;
    503       ve->vf_params.last_element_edge_flag = last_element_edge_flag;
    504       ve->vf_params.cv_index_format = index_format;
    505       ve->vf_params.cut_index_enable = vec->draw->primitive_restart;
    506       ve->vf_params.cut_index = vec->draw->restart_index;
    507 
    508       ilo_state_vf_set_params(&ve->vf, dev, &ve->vf_params);
    509 
    510       vec->dirty |= ILO_DIRTY_VE;
    511    }
    512 }
    513 
    514 static void
    515 finalize_vertex_buffers(struct ilo_context *ilo)
    516 {
    517    const struct ilo_dev *dev = ilo->dev;
    518    struct ilo_state_vector *vec = &ilo->state_vector;
    519    struct ilo_state_vertex_buffer_info info;
    520    unsigned i;
    521 
    522    if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VB)))
    523       return;
    524 
    525    memset(&info, 0, sizeof(info));
    526 
    527    for (i = 0; i < vec->ve->vb_count; i++) {
    528       const unsigned pipe_idx = vec->ve->vb_mapping[i];
    529       const struct pipe_vertex_buffer *cso = &vec->vb.states[pipe_idx];
    530 
    531       if (cso->buffer) {
    532          info.vma = ilo_resource_get_vma(cso->buffer);
    533          info.offset = cso->buffer_offset;
    534          info.size = info.vma->vm_size - cso->buffer_offset;
    535 
    536          info.stride = cso->stride;
    537       } else {
    538          memset(&info, 0, sizeof(info));
    539       }
    540 
    541       ilo_state_vertex_buffer_set_info(&vec->vb.vb[i], dev, &info);
    542    }
    543 }
    544 
    545 static void
    546 finalize_urb(struct ilo_context *ilo)
    547 {
    548    const uint16_t attr_size = sizeof(uint32_t) * 4;
    549    const struct ilo_dev *dev = ilo->dev;
    550    struct ilo_state_vector *vec = &ilo->state_vector;
    551    struct ilo_state_urb_info info;
    552 
    553    if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS |
    554                        ILO_DIRTY_GS | ILO_DIRTY_FS)))
    555       return;
    556 
    557    memset(&info, 0, sizeof(info));
    558 
    559    info.ve_entry_size = attr_size * ilo_state_vf_get_attr_count(&vec->ve->vf);
    560 
    561    if (vec->vs) {
    562       info.vs_const_data = (bool)
    563          (ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_PCB_CBUF0_SIZE) +
    564           ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_PCB_UCP_SIZE));
    565       info.vs_entry_size = attr_size *
    566          ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_OUTPUT_COUNT);
    567    }
    568 
    569    if (vec->gs) {
    570       info.gs_const_data = (bool)
    571          ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_PCB_CBUF0_SIZE);
    572 
    573       /*
    574        * From the Ivy Bridge PRM, volume 2 part 1, page 189:
    575        *
    576        *     "All outputs of a GS thread will be stored in the single GS
    577        *      thread output URB entry."
    578        *
    579        * TODO
    580        */
    581       info.gs_entry_size = attr_size *
    582          ilo_shader_get_kernel_param(vec->gs, ILO_KERNEL_OUTPUT_COUNT);
    583    }
    584 
    585    if (vec->fs) {
    586       info.ps_const_data = (bool)
    587          ilo_shader_get_kernel_param(vec->fs, ILO_KERNEL_PCB_CBUF0_SIZE);
    588    }
    589 
    590    ilo_state_urb_set_info(&vec->urb, dev, &info);
    591 }
    592 
    593 static void
    594 finalize_viewport(struct ilo_context *ilo)
    595 {
    596    const struct ilo_dev *dev = ilo->dev;
    597    struct ilo_state_vector *vec = &ilo->state_vector;
    598 
    599    if (vec->dirty & ILO_DIRTY_VIEWPORT) {
    600       ilo_state_viewport_set_params(&vec->viewport.vp,
    601             dev, &vec->viewport.params, false);
    602    } else if (vec->dirty & ILO_DIRTY_SCISSOR) {
    603       ilo_state_viewport_set_params(&vec->viewport.vp,
    604             dev, &vec->viewport.params, true);
    605       vec->dirty |= ILO_DIRTY_VIEWPORT;
    606    }
    607 }
    608 
    609 static bool
    610 can_enable_gb_test(const struct ilo_rasterizer_state *rasterizer,
    611                    const struct ilo_viewport_state *viewport,
    612                    const struct ilo_fb_state *fb)
    613 {
    614    unsigned i;
    615 
    616    /*
    617     * There are several reasons that guard band test should be disabled
    618     *
    619     *  - GL wide points (to avoid partially visibie object)
    620     *  - GL wide or AA lines (to avoid partially visibie object)
    621     *  - missing 2D clipping
    622     */
    623    if (rasterizer->state.point_size_per_vertex ||
    624        rasterizer->state.point_size > 1.0f ||
    625        rasterizer->state.line_width > 1.0f ||
    626        rasterizer->state.line_smooth)
    627       return false;
    628 
    629    for (i = 0; i < viewport->params.count; i++) {
    630       const struct ilo_state_viewport_matrix_info *mat =
    631          &viewport->matrices[i];
    632       float min_x, max_x, min_y, max_y;
    633 
    634       min_x = -1.0f * fabsf(mat->scale[0]) + mat->translate[0];
    635       max_x =  1.0f * fabsf(mat->scale[0]) + mat->translate[0];
    636       min_y = -1.0f * fabsf(mat->scale[1]) + mat->translate[1];
    637       max_y =  1.0f * fabsf(mat->scale[1]) + mat->translate[1];
    638 
    639       if (min_x > 0.0f || max_x < fb->state.width ||
    640           min_y > 0.0f || max_y < fb->state.height)
    641          return false;
    642    }
    643 
    644    return true;
    645 }
    646 
    647 static void
    648 finalize_rasterizer(struct ilo_context *ilo)
    649 {
    650    const struct ilo_dev *dev = ilo->dev;
    651    struct ilo_state_vector *vec = &ilo->state_vector;
    652    struct ilo_rasterizer_state *rasterizer = vec->rasterizer;
    653    struct ilo_state_raster_info *info = &vec->rasterizer->info;
    654    const bool gb_test_enable =
    655       can_enable_gb_test(rasterizer, &vec->viewport, &vec->fb);
    656    const bool multisample =
    657       (rasterizer->state.multisample && vec->fb.num_samples > 1);
    658    const uint8_t barycentric_interps = ilo_shader_get_kernel_param(vec->fs,
    659          ILO_KERNEL_FS_BARYCENTRIC_INTERPOLATIONS);
    660 
    661    /* check for non-orthogonal states */
    662    if (info->clip.viewport_count != vec->viewport.params.count ||
    663        info->clip.gb_test_enable != gb_test_enable ||
    664        info->setup.msaa_enable != multisample ||
    665        info->setup.line_msaa_enable != multisample ||
    666        info->tri.depth_offset_format != vec->fb.depth_offset_format ||
    667        info->scan.sample_count != vec->fb.num_samples ||
    668        info->scan.sample_mask != vec->sample_mask ||
    669        info->scan.barycentric_interps != barycentric_interps ||
    670        info->params.any_integer_rt != vec->fb.has_integer_rt ||
    671        info->params.hiz_enable != vec->fb.has_hiz) {
    672       info->clip.viewport_count = vec->viewport.params.count;
    673       info->clip.gb_test_enable = gb_test_enable;
    674       info->setup.msaa_enable = multisample;
    675       info->setup.line_msaa_enable = multisample;
    676       info->tri.depth_offset_format = vec->fb.depth_offset_format;
    677       info->scan.sample_count = vec->fb.num_samples;
    678       info->scan.sample_mask = vec->sample_mask;
    679       info->scan.barycentric_interps = barycentric_interps;
    680       info->params.any_integer_rt = vec->fb.has_integer_rt;
    681       info->params.hiz_enable = vec->fb.has_hiz;
    682 
    683       ilo_state_raster_set_info(&rasterizer->rs, dev, &rasterizer->info);
    684 
    685       vec->dirty |= ILO_DIRTY_RASTERIZER;
    686    }
    687 }
    688 
    689 static bool
    690 finalize_blend_rt(struct ilo_context *ilo)
    691 {
    692    struct ilo_state_vector *vec = &ilo->state_vector;
    693    const struct ilo_fb_state *fb = &vec->fb;
    694    struct ilo_blend_state *blend = vec->blend;
    695    struct ilo_state_cc_blend_info *info = &vec->blend->info.blend;
    696    bool changed = false;
    697    unsigned i;
    698 
    699    if (!(vec->dirty & (ILO_DIRTY_FB | ILO_DIRTY_BLEND)))
    700       return false;
    701 
    702    /* set up one for dummy RT writes */
    703    if (!fb->state.nr_cbufs) {
    704       if (info->rt != &blend->dummy_rt) {
    705          info->rt = &blend->dummy_rt;
    706          info->rt_count = 1;
    707          changed = true;
    708       }
    709 
    710       return changed;
    711    }
    712 
    713    if (info->rt != blend->effective_rt ||
    714        info->rt_count != fb->state.nr_cbufs) {
    715       info->rt = blend->effective_rt;
    716       info->rt_count = fb->state.nr_cbufs;
    717       changed = true;
    718    }
    719 
    720    for (i = 0; i < fb->state.nr_cbufs; i++) {
    721       const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i];
    722       struct ilo_state_cc_blend_rt_info *rt = &blend->effective_rt[i];
    723       /* ignore logicop when not UNORM */
    724       const bool logicop_enable =
    725          (blend->rt[i].logicop_enable && caps->is_unorm);
    726 
    727       if (rt->cv_is_unorm != caps->is_unorm ||
    728           rt->cv_is_integer != caps->is_integer ||
    729           rt->logicop_enable != logicop_enable ||
    730           rt->force_dst_alpha_one != caps->force_dst_alpha_one) {
    731          rt->cv_is_unorm = caps->is_unorm;
    732          rt->cv_is_integer = caps->is_integer;
    733          rt->logicop_enable = logicop_enable;
    734          rt->force_dst_alpha_one = caps->force_dst_alpha_one;
    735 
    736          changed = true;
    737       }
    738    }
    739 
    740    return changed;
    741 }
    742 
    743 static void
    744 finalize_blend(struct ilo_context *ilo)
    745 {
    746    const struct ilo_dev *dev = ilo->dev;
    747    struct ilo_state_vector *vec = &ilo->state_vector;
    748    struct ilo_blend_state *blend = vec->blend;
    749    struct ilo_state_cc_info *info = &blend->info;
    750    const bool sample_count_one = (vec->fb.num_samples <= 1);
    751    const bool float_source0_alpha =
    752       (!vec->fb.state.nr_cbufs || !vec->fb.state.cbufs[0] ||
    753        !util_format_is_pure_integer(vec->fb.state.cbufs[0]->format));
    754 
    755    /* check for non-orthogonal states */
    756    if (finalize_blend_rt(ilo) ||
    757        info->alpha.cv_sample_count_one != sample_count_one ||
    758        info->alpha.cv_float_source0_alpha != float_source0_alpha ||
    759        info->alpha.test_enable != vec->dsa->alpha_test ||
    760        info->alpha.test_func != vec->dsa->alpha_func ||
    761        memcmp(&info->stencil, &vec->dsa->stencil, sizeof(info->stencil)) ||
    762        memcmp(&info->depth, &vec->dsa->depth, sizeof(info->depth)) ||
    763        memcmp(&info->params, &vec->cc_params, sizeof(info->params))) {
    764       info->alpha.cv_sample_count_one = sample_count_one;
    765       info->alpha.cv_float_source0_alpha = float_source0_alpha;
    766       info->alpha.test_enable = vec->dsa->alpha_test;
    767       info->alpha.test_func = vec->dsa->alpha_func;
    768       info->stencil = vec->dsa->stencil;
    769       info->depth = vec->dsa->depth;
    770       info->params = vec->cc_params;
    771 
    772       ilo_state_cc_set_info(&blend->cc, dev, info);
    773 
    774       blend->alpha_may_kill = (info->alpha.alpha_to_coverage ||
    775                                info->alpha.test_enable);
    776 
    777       vec->dirty |= ILO_DIRTY_BLEND;
    778    }
    779 }
    780 
    781 /**
    782  * Finalize states.  Some states depend on other states and are
    783  * incomplete/invalid until finalized.
    784  */
    785 void
    786 ilo_finalize_3d_states(struct ilo_context *ilo,
    787                        const struct pipe_draw_info *draw)
    788 {
    789    ilo->state_vector.draw = draw;
    790 
    791    ilo->state_vector.draw_info.topology = ilo_translate_draw_mode(draw->mode);
    792    ilo->state_vector.draw_info.indexed = draw->indexed;
    793    ilo->state_vector.draw_info.vertex_count = draw->count;
    794    ilo->state_vector.draw_info.vertex_start = draw->start;
    795    ilo->state_vector.draw_info.instance_count = draw->instance_count;
    796    ilo->state_vector.draw_info.instance_start = draw->start_instance;
    797    ilo->state_vector.draw_info.vertex_base = draw->index_bias;
    798 
    799    finalize_blend(ilo);
    800    finalize_shader_states(&ilo->state_vector);
    801    finalize_constant_buffers(ilo);
    802    finalize_index_buffer(ilo);
    803    finalize_vertex_elements(ilo);
    804    finalize_vertex_buffers(ilo);
    805 
    806    finalize_urb(ilo);
    807    finalize_rasterizer(ilo);
    808    finalize_viewport(ilo);
    809 
    810    u_upload_unmap(ilo->uploader);
    811 }
    812 
    813 static void
    814 finalize_global_binding(struct ilo_state_vector *vec)
    815 {
    816    struct ilo_shader_state *cs = vec->cs;
    817    int base, count, shift;
    818    int i;
    819 
    820    count = ilo_shader_get_kernel_param(cs,
    821          ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);
    822    if (!count)
    823       return;
    824 
    825    base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
    826    shift = 32 - util_last_bit(base + count - 1);
    827 
    828    if (count > vec->global_binding.count)
    829       count = vec->global_binding.count;
    830 
    831    for (i = 0; i < count; i++) {
    832       struct ilo_global_binding_cso *cso =
    833          util_dynarray_element(&vec->global_binding.bindings,
    834                struct ilo_global_binding_cso, i);
    835       const uint32_t offset = *cso->handle & ((1 << shift) - 1);
    836 
    837       *cso->handle = ((base + i) << shift) | offset;
    838    }
    839 }
    840 
    841 void
    842 ilo_finalize_compute_states(struct ilo_context *ilo)
    843 {
    844    finalize_global_binding(&ilo->state_vector);
    845 }
    846 
    847 static void *
    848 ilo_create_blend_state(struct pipe_context *pipe,
    849                        const struct pipe_blend_state *state)
    850 {
    851    const struct ilo_dev *dev = ilo_context(pipe)->dev;
    852    struct ilo_state_cc_info *info;
    853    struct ilo_blend_state *blend;
    854    int i;
    855 
    856    blend = CALLOC_STRUCT(ilo_blend_state);
    857    assert(blend);
    858 
    859    info = &blend->info;
    860 
    861    info->alpha.cv_float_source0_alpha = true;
    862    info->alpha.cv_sample_count_one = true;
    863    info->alpha.alpha_to_one = state->alpha_to_one;
    864    info->alpha.alpha_to_coverage = state->alpha_to_coverage;
    865    info->alpha.test_enable = false;
    866    info->alpha.test_func = GEN6_COMPAREFUNCTION_ALWAYS;
    867 
    868    info->stencil.cv_has_buffer = true;
    869    info->depth.cv_has_buffer= true;
    870 
    871    info->blend.rt = blend->effective_rt;
    872    info->blend.rt_count = 1;
    873    info->blend.dither_enable = state->dither;
    874 
    875    for (i = 0; i < ARRAY_SIZE(blend->rt); i++) {
    876       const struct pipe_rt_blend_state *rt = &state->rt[i];
    877       struct ilo_state_cc_blend_rt_info *rt_info = &blend->rt[i];
    878 
    879       rt_info->cv_has_buffer = true;
    880       rt_info->cv_is_unorm = true;
    881       rt_info->cv_is_integer = false;
    882 
    883       /* logic op takes precedence over blending */
    884       if (state->logicop_enable) {
    885          rt_info->logicop_enable = true;
    886          rt_info->logicop_func = ilo_translate_logicop(state->logicop_func);
    887       } else if (rt->blend_enable) {
    888          rt_info->blend_enable = true;
    889 
    890          rt_info->rgb_src = ilo_translate_blend_factor(rt->rgb_src_factor);
    891          rt_info->rgb_dst = ilo_translate_blend_factor(rt->rgb_dst_factor);
    892          rt_info->rgb_func = ilo_translate_blend_func(rt->rgb_func);
    893 
    894          rt_info->a_src = ilo_translate_blend_factor(rt->alpha_src_factor);
    895          rt_info->a_dst = ilo_translate_blend_factor(rt->alpha_dst_factor);
    896          rt_info->a_func = ilo_translate_blend_func(rt->alpha_func);
    897       }
    898 
    899       if (!(rt->colormask & PIPE_MASK_A))
    900          rt_info->argb_write_disables |= (1 << 3);
    901       if (!(rt->colormask & PIPE_MASK_R))
    902          rt_info->argb_write_disables |= (1 << 2);
    903       if (!(rt->colormask & PIPE_MASK_G))
    904          rt_info->argb_write_disables |= (1 << 1);
    905       if (!(rt->colormask & PIPE_MASK_B))
    906          rt_info->argb_write_disables |= (1 << 0);
    907 
    908       if (!state->independent_blend_enable) {
    909          for (i = 1; i < ARRAY_SIZE(blend->rt); i++)
    910             blend->rt[i] = *rt_info;
    911          break;
    912       }
    913    }
    914 
    915    memcpy(blend->effective_rt, blend->rt, sizeof(blend->rt));
    916 
    917    blend->dummy_rt.argb_write_disables = 0xf;
    918 
    919    if (!ilo_state_cc_init(&blend->cc, dev, &blend->info)) {
    920       FREE(blend);
    921       return NULL;
    922    }
    923 
    924    blend->dual_blend = util_blend_state_is_dual(state, 0);
    925 
    926    return blend;
    927 }
    928 
    929 static void
    930 ilo_bind_blend_state(struct pipe_context *pipe, void *state)
    931 {
    932    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
    933 
    934    vec->blend = state;
    935 
    936    vec->dirty |= ILO_DIRTY_BLEND;
    937 }
    938 
    939 static void
    940 ilo_delete_blend_state(struct pipe_context *pipe, void  *state)
    941 {
    942    FREE(state);
    943 }
    944 
    945 static void *
    946 ilo_create_sampler_state(struct pipe_context *pipe,
    947                          const struct pipe_sampler_state *state)
    948 {
    949    const struct ilo_dev *dev = ilo_context(pipe)->dev;
    950    struct ilo_sampler_cso *sampler;
    951    struct ilo_state_sampler_info info;
    952    struct ilo_state_sampler_border_info border;
    953 
    954    sampler = CALLOC_STRUCT(ilo_sampler_cso);
    955    assert(sampler);
    956 
    957    memset(&info, 0, sizeof(info));
    958 
    959    info.non_normalized = !state->normalized_coords;
    960    if (state->normalized_coords) {
    961       info.lod_bias = state->lod_bias;
    962       info.min_lod = state->min_lod;
    963       info.max_lod = state->max_lod;
    964 
    965       info.mip_filter = ilo_translate_mip_filter(state->min_mip_filter);
    966    } else {
    967       /* work around a bug in util_blitter */
    968       info.mip_filter = GEN6_MIPFILTER_NONE;
    969    }
    970 
    971    if (state->max_anisotropy) {
    972       info.min_filter = GEN6_MAPFILTER_ANISOTROPIC;
    973       info.mag_filter = GEN6_MAPFILTER_ANISOTROPIC;
    974    } else {
    975       info.min_filter = ilo_translate_img_filter(state->min_img_filter);
    976       info.mag_filter = ilo_translate_img_filter(state->mag_img_filter);
    977    }
    978 
    979    info.max_anisotropy = ilo_translate_max_anisotropy(state->max_anisotropy);
    980 
    981    /* use LOD 0 when no mipmapping (see sampler_set_gen6_SAMPLER_STATE()) */
    982    if (info.mip_filter == GEN6_MIPFILTER_NONE && info.min_lod > 0.0f) {
    983       info.min_lod = 0.0f;
    984       info.mag_filter = info.min_filter;
    985    }
    986 
    987    if (state->seamless_cube_map) {
    988       if (state->min_img_filter == PIPE_TEX_FILTER_NEAREST ||
    989           state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) {
    990          info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
    991          info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
    992          info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
    993       } else {
    994          info.tcx_ctrl = GEN6_TEXCOORDMODE_CUBE;
    995          info.tcy_ctrl = GEN6_TEXCOORDMODE_CUBE;
    996          info.tcz_ctrl = GEN6_TEXCOORDMODE_CUBE;
    997       }
    998    } else {
    999       info.tcx_ctrl = ilo_translate_address_wrap(state->wrap_s);
   1000       info.tcy_ctrl = ilo_translate_address_wrap(state->wrap_t);
   1001       info.tcz_ctrl = ilo_translate_address_wrap(state->wrap_r);
   1002 
   1003       if (ilo_dev_gen(dev) < ILO_GEN(8)) {
   1004          /*
   1005           * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
   1006           * PIPE_TEX_WRAP_CLAMP_TO_EDGE;  for linear filtering,
   1007           * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
   1008           * additionally clamping the texture coordinates to [0.0, 1.0].
   1009           *
   1010           * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8.  The
   1011           * clamping has to be taken care of in the shaders.  There are two
   1012           * filters here, but let the minification one has a say.
   1013           */
   1014          const bool clamp_is_to_edge =
   1015             (state->min_img_filter == PIPE_TEX_FILTER_NEAREST);
   1016 
   1017          if (clamp_is_to_edge) {
   1018             if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
   1019                info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
   1020             if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
   1021                info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
   1022             if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
   1023                info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
   1024          } else {
   1025             if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
   1026                info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
   1027                sampler->saturate_s = true;
   1028             }
   1029             if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
   1030                info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
   1031                sampler->saturate_t = true;
   1032             }
   1033             if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
   1034                info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
   1035                sampler->saturate_r = true;
   1036             }
   1037          }
   1038       }
   1039    }
   1040 
   1041    if (state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
   1042       info.shadow_func = ilo_translate_shadow_func(state->compare_func);
   1043 
   1044    ilo_state_sampler_init(&sampler->sampler, dev, &info);
   1045 
   1046    memset(&border, 0, sizeof(border));
   1047    memcpy(border.rgba.f, state->border_color.f, sizeof(border.rgba.f));
   1048 
   1049    ilo_state_sampler_border_init(&sampler->border, dev, &border);
   1050 
   1051    return sampler;
   1052 }
   1053 
   1054 static void
   1055 ilo_bind_sampler_states(struct pipe_context *pipe,
   1056                         enum pipe_shader_type shader,
   1057                         unsigned start, unsigned count, void **samplers)
   1058 {
   1059    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1060    struct ilo_sampler_state *dst = &vec->sampler[shader];
   1061    bool changed = false;
   1062    unsigned i;
   1063 
   1064    assert(start + count <= ARRAY_SIZE(dst->cso));
   1065 
   1066    if (samplers) {
   1067       for (i = 0; i < count; i++) {
   1068          if (dst->cso[start + i] != samplers[i]) {
   1069             dst->cso[start + i] = samplers[i];
   1070 
   1071             /*
   1072              * This function is sometimes called to reduce the number of bound
   1073              * samplers.  Do not consider that as a state change (and create a
   1074              * new array of SAMPLER_STATE).
   1075              */
   1076             if (samplers[i])
   1077                changed = true;
   1078          }
   1079       }
   1080    }
   1081    else {
   1082       for (i = 0; i < count; i++)
   1083          dst->cso[start + i] = NULL;
   1084    }
   1085 
   1086    if (changed) {
   1087       switch (shader) {
   1088       case PIPE_SHADER_VERTEX:
   1089          vec->dirty |= ILO_DIRTY_SAMPLER_VS;
   1090          break;
   1091       case PIPE_SHADER_GEOMETRY:
   1092          vec->dirty |= ILO_DIRTY_SAMPLER_GS;
   1093          break;
   1094       case PIPE_SHADER_FRAGMENT:
   1095          vec->dirty |= ILO_DIRTY_SAMPLER_FS;
   1096          break;
   1097       case PIPE_SHADER_COMPUTE:
   1098          vec->dirty |= ILO_DIRTY_SAMPLER_CS;
   1099          break;
   1100       }
   1101    }
   1102 }
   1103 
   1104 static void
   1105 ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
   1106 {
   1107    FREE(state);
   1108 }
   1109 
   1110 static void *
   1111 ilo_create_rasterizer_state(struct pipe_context *pipe,
   1112                             const struct pipe_rasterizer_state *state)
   1113 {
   1114    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   1115    struct ilo_rasterizer_state *rast;
   1116    struct ilo_state_raster_info *info;
   1117 
   1118    rast = CALLOC_STRUCT(ilo_rasterizer_state);
   1119    assert(rast);
   1120 
   1121    rast->state = *state;
   1122 
   1123    info = &rast->info;
   1124 
   1125    info->clip.clip_enable = true;
   1126    info->clip.stats_enable = true;
   1127    info->clip.viewport_count = 1;
   1128    info->clip.force_rtaindex_zero = true;
   1129    info->clip.user_clip_enables = state->clip_plane_enable;
   1130    info->clip.gb_test_enable = true;
   1131    info->clip.xy_test_enable = true;
   1132    info->clip.z_far_enable = state->depth_clip;
   1133    info->clip.z_near_enable = state->depth_clip;
   1134    info->clip.z_near_zero = state->clip_halfz;
   1135 
   1136    info->setup.first_vertex_provoking = state->flatshade_first;
   1137    info->setup.viewport_transform = true;
   1138    info->setup.scissor_enable = state->scissor;
   1139    info->setup.msaa_enable = false;
   1140    info->setup.line_msaa_enable = false;
   1141    info->point.aa_enable = state->point_smooth;
   1142    info->point.programmable_width = state->point_size_per_vertex;
   1143    info->line.aa_enable = state->line_smooth;
   1144    info->line.stipple_enable = state->line_stipple_enable;
   1145    info->line.giq_enable = true;
   1146    info->line.giq_last_pixel = state->line_last_pixel;
   1147    info->tri.front_winding = ilo_translate_front_ccw(state->front_ccw);
   1148    info->tri.cull_mode = ilo_translate_cull_face(state->cull_face);
   1149    info->tri.fill_mode_front = ilo_translate_poly_mode(state->fill_front);
   1150    info->tri.fill_mode_back = ilo_translate_poly_mode(state->fill_back);
   1151    info->tri.depth_offset_format = GEN6_ZFORMAT_D24_UNORM_X8_UINT;
   1152    info->tri.depth_offset_solid = state->offset_tri;
   1153    info->tri.depth_offset_wireframe = state->offset_line;
   1154    info->tri.depth_offset_point = state->offset_point;
   1155    info->tri.poly_stipple_enable = state->poly_stipple_enable;
   1156 
   1157    info->scan.stats_enable = true;
   1158    info->scan.sample_count = 1;
   1159    info->scan.pixloc =
   1160       ilo_translate_half_pixel_center(state->half_pixel_center);
   1161    info->scan.sample_mask = ~0u;
   1162    info->scan.zw_interp = GEN6_ZW_INTERP_PIXEL;
   1163    info->scan.barycentric_interps = GEN6_INTERP_PERSPECTIVE_PIXEL;
   1164    info->scan.earlyz_control = GEN7_EDSC_NORMAL;
   1165    info->scan.earlyz_op = ILO_STATE_RASTER_EARLYZ_NORMAL;
   1166    info->scan.earlyz_stencil_clear = false;
   1167 
   1168    info->params.any_integer_rt = false;
   1169    info->params.hiz_enable = true;
   1170    info->params.point_width =
   1171       (state->point_size == 0.0f) ? 1.0f : state->point_size;
   1172    info->params.line_width =
   1173       (state->line_width == 0.0f) ? 1.0f : state->line_width;
   1174 
   1175    info->params.depth_offset_scale = state->offset_scale;
   1176    /*
   1177     * Scale the constant term.  The minimum representable value used by the HW
   1178     * is not large enouch to be the minimum resolvable difference.
   1179     */
   1180    info->params.depth_offset_const = state->offset_units * 2.0f;
   1181    info->params.depth_offset_clamp = state->offset_clamp;
   1182 
   1183    ilo_state_raster_init(&rast->rs, dev, info);
   1184 
   1185    return rast;
   1186 }
   1187 
   1188 static void
   1189 ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
   1190 {
   1191    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   1192    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1193 
   1194    vec->rasterizer = state;
   1195 
   1196    if (vec->rasterizer) {
   1197       struct ilo_state_line_stipple_info info;
   1198 
   1199       info.pattern = vec->rasterizer->state.line_stipple_pattern;
   1200       info.repeat_count = vec->rasterizer->state.line_stipple_factor + 1;
   1201 
   1202       ilo_state_line_stipple_set_info(&vec->line_stipple, dev, &info);
   1203    }
   1204 
   1205    vec->dirty |= ILO_DIRTY_RASTERIZER;
   1206 }
   1207 
   1208 static void
   1209 ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
   1210 {
   1211    FREE(state);
   1212 }
   1213 
   1214 static void *
   1215 ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
   1216                                      const struct pipe_depth_stencil_alpha_state *state)
   1217 {
   1218    struct ilo_dsa_state *dsa;
   1219    int i;
   1220 
   1221    dsa = CALLOC_STRUCT(ilo_dsa_state);
   1222    assert(dsa);
   1223 
   1224    dsa->depth.cv_has_buffer = true;
   1225    dsa->depth.test_enable = state->depth.enabled;
   1226    dsa->depth.write_enable = state->depth.writemask;
   1227    dsa->depth.test_func = ilo_translate_compare_func(state->depth.func);
   1228 
   1229    dsa->stencil.cv_has_buffer = true;
   1230    for (i = 0; i < ARRAY_SIZE(state->stencil); i++) {
   1231       const struct pipe_stencil_state *stencil = &state->stencil[i];
   1232       struct ilo_state_cc_stencil_op_info *op;
   1233 
   1234       if (!stencil->enabled)
   1235          break;
   1236 
   1237       if (i == 0) {
   1238          dsa->stencil.test_enable = true;
   1239          dsa->stencil_front.test_mask = stencil->valuemask;
   1240          dsa->stencil_front.write_mask = stencil->writemask;
   1241 
   1242          op = &dsa->stencil.front;
   1243       } else {
   1244          dsa->stencil.twosided_enable = true;
   1245          dsa->stencil_back.test_mask = stencil->valuemask;
   1246          dsa->stencil_back.write_mask = stencil->writemask;
   1247 
   1248          op = &dsa->stencil.back;
   1249       }
   1250 
   1251       op->test_func = ilo_translate_compare_func(stencil->func);
   1252       op->fail_op = ilo_translate_stencil_op(stencil->fail_op);
   1253       op->zfail_op = ilo_translate_stencil_op(stencil->zfail_op);
   1254       op->zpass_op = ilo_translate_stencil_op(stencil->zpass_op);
   1255    }
   1256 
   1257    dsa->alpha_test = state->alpha.enabled;
   1258    dsa->alpha_ref = state->alpha.ref_value;
   1259    dsa->alpha_func = ilo_translate_compare_func(state->alpha.func);
   1260 
   1261    return dsa;
   1262 }
   1263 
   1264 static void
   1265 ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
   1266 {
   1267    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1268 
   1269    vec->dsa = state;
   1270    if (vec->dsa) {
   1271       vec->cc_params.alpha_ref = vec->dsa->alpha_ref;
   1272       vec->cc_params.stencil_front.test_mask =
   1273          vec->dsa->stencil_front.test_mask;
   1274       vec->cc_params.stencil_front.write_mask =
   1275          vec->dsa->stencil_front.write_mask;
   1276       vec->cc_params.stencil_back.test_mask =
   1277          vec->dsa->stencil_back.test_mask;
   1278       vec->cc_params.stencil_back.write_mask =
   1279          vec->dsa->stencil_back.write_mask;
   1280    }
   1281 
   1282    vec->dirty |= ILO_DIRTY_DSA;
   1283 }
   1284 
   1285 static void
   1286 ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
   1287 {
   1288    FREE(state);
   1289 }
   1290 
   1291 static void *
   1292 ilo_create_fs_state(struct pipe_context *pipe,
   1293                     const struct pipe_shader_state *state)
   1294 {
   1295    struct ilo_context *ilo = ilo_context(pipe);
   1296    struct ilo_shader_state *shader;
   1297 
   1298    shader = ilo_shader_create_fs(ilo->dev, state, &ilo->state_vector);
   1299    assert(shader);
   1300 
   1301    ilo_shader_cache_add(ilo->shader_cache, shader);
   1302 
   1303    return shader;
   1304 }
   1305 
   1306 static void
   1307 ilo_bind_fs_state(struct pipe_context *pipe, void *state)
   1308 {
   1309    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1310 
   1311    vec->fs = state;
   1312 
   1313    vec->dirty |= ILO_DIRTY_FS;
   1314 }
   1315 
   1316 static void
   1317 ilo_delete_fs_state(struct pipe_context *pipe, void *state)
   1318 {
   1319    struct ilo_context *ilo = ilo_context(pipe);
   1320    struct ilo_shader_state *fs = (struct ilo_shader_state *) state;
   1321 
   1322    ilo_shader_cache_remove(ilo->shader_cache, fs);
   1323    ilo_shader_destroy(fs);
   1324 }
   1325 
   1326 static void *
   1327 ilo_create_vs_state(struct pipe_context *pipe,
   1328                     const struct pipe_shader_state *state)
   1329 {
   1330    struct ilo_context *ilo = ilo_context(pipe);
   1331    struct ilo_shader_state *shader;
   1332 
   1333    shader = ilo_shader_create_vs(ilo->dev, state, &ilo->state_vector);
   1334    assert(shader);
   1335 
   1336    ilo_shader_cache_add(ilo->shader_cache, shader);
   1337 
   1338    return shader;
   1339 }
   1340 
   1341 static void
   1342 ilo_bind_vs_state(struct pipe_context *pipe, void *state)
   1343 {
   1344    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1345 
   1346    vec->vs = state;
   1347 
   1348    vec->dirty |= ILO_DIRTY_VS;
   1349 }
   1350 
   1351 static void
   1352 ilo_delete_vs_state(struct pipe_context *pipe, void *state)
   1353 {
   1354    struct ilo_context *ilo = ilo_context(pipe);
   1355    struct ilo_shader_state *vs = (struct ilo_shader_state *) state;
   1356 
   1357    ilo_shader_cache_remove(ilo->shader_cache, vs);
   1358    ilo_shader_destroy(vs);
   1359 }
   1360 
   1361 static void *
   1362 ilo_create_gs_state(struct pipe_context *pipe,
   1363                     const struct pipe_shader_state *state)
   1364 {
   1365    struct ilo_context *ilo = ilo_context(pipe);
   1366    struct ilo_shader_state *shader;
   1367 
   1368    shader = ilo_shader_create_gs(ilo->dev, state, &ilo->state_vector);
   1369    assert(shader);
   1370 
   1371    ilo_shader_cache_add(ilo->shader_cache, shader);
   1372 
   1373    return shader;
   1374 }
   1375 
   1376 static void
   1377 ilo_bind_gs_state(struct pipe_context *pipe, void *state)
   1378 {
   1379    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1380 
   1381    /* util_blitter may set this unnecessarily */
   1382    if (vec->gs == state)
   1383       return;
   1384 
   1385    vec->gs = state;
   1386 
   1387    vec->dirty |= ILO_DIRTY_GS;
   1388 }
   1389 
   1390 static void
   1391 ilo_delete_gs_state(struct pipe_context *pipe, void *state)
   1392 {
   1393    struct ilo_context *ilo = ilo_context(pipe);
   1394    struct ilo_shader_state *gs = (struct ilo_shader_state *) state;
   1395 
   1396    ilo_shader_cache_remove(ilo->shader_cache, gs);
   1397    ilo_shader_destroy(gs);
   1398 }
   1399 
   1400 static void *
   1401 ilo_create_vertex_elements_state(struct pipe_context *pipe,
   1402                                  unsigned num_elements,
   1403                                  const struct pipe_vertex_element *elements)
   1404 {
   1405    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   1406    struct ilo_state_vf_element_info vf_elements[PIPE_MAX_ATTRIBS];
   1407    unsigned instance_divisors[PIPE_MAX_ATTRIBS];
   1408    struct ilo_state_vf_info vf_info;
   1409    struct ilo_ve_state *ve;
   1410    unsigned i;
   1411 
   1412    ve = CALLOC_STRUCT(ilo_ve_state);
   1413    assert(ve);
   1414 
   1415    for (i = 0; i < num_elements; i++) {
   1416       const struct pipe_vertex_element *elem = &elements[i];
   1417       struct ilo_state_vf_element_info *attr = &vf_elements[i];
   1418       unsigned hw_idx;
   1419 
   1420       /*
   1421        * map the pipe vb to the hardware vb, which has a fixed instance
   1422        * divisor
   1423        */
   1424       for (hw_idx = 0; hw_idx < ve->vb_count; hw_idx++) {
   1425          if (ve->vb_mapping[hw_idx] == elem->vertex_buffer_index &&
   1426              instance_divisors[hw_idx] == elem->instance_divisor)
   1427             break;
   1428       }
   1429 
   1430       /* create one if there is no matching hardware vb */
   1431       if (hw_idx >= ve->vb_count) {
   1432          hw_idx = ve->vb_count++;
   1433 
   1434          ve->vb_mapping[hw_idx] = elem->vertex_buffer_index;
   1435          instance_divisors[hw_idx] = elem->instance_divisor;
   1436       }
   1437 
   1438       attr->buffer = hw_idx;
   1439       attr->vertex_offset = elem->src_offset;
   1440       attr->format = ilo_format_translate_vertex(dev, elem->src_format);
   1441       attr->format_size = util_format_get_blocksize(elem->src_format);
   1442       attr->component_count = util_format_get_nr_components(elem->src_format);
   1443       attr->is_integer = util_format_is_pure_integer(elem->src_format);
   1444 
   1445       attr->instancing_enable = (elem->instance_divisor != 0);
   1446       attr->instancing_step_rate = elem->instance_divisor;
   1447    }
   1448 
   1449    memset(&vf_info, 0, sizeof(vf_info));
   1450    vf_info.data = ve->vf_data;
   1451    vf_info.data_size = sizeof(ve->vf_data);
   1452    vf_info.elements = vf_elements;
   1453    vf_info.element_count = num_elements;
   1454    /* vf_info.params and ve->vf_params are both zeroed */
   1455 
   1456    if (!ilo_state_vf_init(&ve->vf, dev, &vf_info)) {
   1457       FREE(ve);
   1458       return NULL;
   1459    }
   1460 
   1461    return ve;
   1462 }
   1463 
   1464 static void
   1465 ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
   1466 {
   1467    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1468 
   1469    vec->ve = state;
   1470 
   1471    vec->dirty |= ILO_DIRTY_VE;
   1472 }
   1473 
   1474 static void
   1475 ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
   1476 {
   1477    struct ilo_ve_state *ve = state;
   1478 
   1479    FREE(ve);
   1480 }
   1481 
   1482 static void
   1483 ilo_set_blend_color(struct pipe_context *pipe,
   1484                     const struct pipe_blend_color *state)
   1485 {
   1486    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1487 
   1488    memcpy(vec->cc_params.blend_rgba, state->color, sizeof(state->color));
   1489 
   1490    vec->dirty |= ILO_DIRTY_BLEND_COLOR;
   1491 }
   1492 
   1493 static void
   1494 ilo_set_stencil_ref(struct pipe_context *pipe,
   1495                     const struct pipe_stencil_ref *state)
   1496 {
   1497    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1498 
   1499    /* util_blitter may set this unnecessarily */
   1500    if (!memcmp(&vec->stencil_ref, state, sizeof(*state)))
   1501       return;
   1502 
   1503    vec->stencil_ref = *state;
   1504 
   1505    vec->cc_params.stencil_front.test_ref = state->ref_value[0];
   1506    vec->cc_params.stencil_back.test_ref = state->ref_value[1];
   1507 
   1508    vec->dirty |= ILO_DIRTY_STENCIL_REF;
   1509 }
   1510 
   1511 static void
   1512 ilo_set_sample_mask(struct pipe_context *pipe,
   1513                     unsigned sample_mask)
   1514 {
   1515    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1516 
   1517    /* util_blitter may set this unnecessarily */
   1518    if (vec->sample_mask == sample_mask)
   1519       return;
   1520 
   1521    vec->sample_mask = sample_mask;
   1522 
   1523    vec->dirty |= ILO_DIRTY_SAMPLE_MASK;
   1524 }
   1525 
   1526 static void
   1527 ilo_set_clip_state(struct pipe_context *pipe,
   1528                    const struct pipe_clip_state *state)
   1529 {
   1530    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1531 
   1532    vec->clip = *state;
   1533 
   1534    vec->dirty |= ILO_DIRTY_CLIP;
   1535 }
   1536 
   1537 static void
   1538 ilo_set_constant_buffer(struct pipe_context *pipe,
   1539                         uint shader, uint index,
   1540                         const struct pipe_constant_buffer *buf)
   1541 {
   1542    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   1543    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1544    struct ilo_cbuf_state *cbuf = &vec->cbuf[shader];
   1545    const unsigned count = 1;
   1546    unsigned i;
   1547 
   1548    assert(shader < ARRAY_SIZE(vec->cbuf));
   1549    assert(index + count <= ARRAY_SIZE(vec->cbuf[shader].cso));
   1550 
   1551    if (buf) {
   1552       for (i = 0; i < count; i++) {
   1553          struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
   1554 
   1555          pipe_resource_reference(&cso->resource, buf[i].buffer);
   1556 
   1557          cso->info.access = ILO_STATE_SURFACE_ACCESS_DP_DATA;
   1558          cso->info.format = GEN6_FORMAT_R32G32B32A32_FLOAT;
   1559          cso->info.format_size = 16;
   1560          cso->info.struct_size = 16;
   1561          cso->info.readonly = true;
   1562          cso->info.size = buf[i].buffer_size;
   1563 
   1564          if (buf[i].buffer) {
   1565             cso->info.vma = ilo_resource_get_vma(buf[i].buffer);
   1566             cso->info.offset = buf[i].buffer_offset;
   1567 
   1568             memset(&cso->surface, 0, sizeof(cso->surface));
   1569             ilo_state_surface_init_for_buffer(&cso->surface, dev, &cso->info);
   1570 
   1571             cso->user_buffer = NULL;
   1572 
   1573             cbuf->enabled_mask |= 1 << (index + i);
   1574          } else if (buf[i].user_buffer) {
   1575             cso->info.vma = NULL;
   1576             /* buffer_offset does not apply for user buffer */
   1577             cso->user_buffer = buf[i].user_buffer;
   1578 
   1579             cbuf->enabled_mask |= 1 << (index + i);
   1580          } else {
   1581             cso->info.vma = NULL;
   1582             cso->info.size = 0;
   1583             cso->user_buffer = NULL;
   1584 
   1585             cbuf->enabled_mask &= ~(1 << (index + i));
   1586          }
   1587       }
   1588    } else {
   1589       for (i = 0; i < count; i++) {
   1590          struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
   1591 
   1592          pipe_resource_reference(&cso->resource, NULL);
   1593 
   1594          cso->info.vma = NULL;
   1595          cso->info.size = 0;
   1596          cso->user_buffer = NULL;
   1597 
   1598          cbuf->enabled_mask &= ~(1 << (index + i));
   1599       }
   1600    }
   1601 
   1602    vec->dirty |= ILO_DIRTY_CBUF;
   1603 }
   1604 
   1605 static void
   1606 fb_set_blend_caps(const struct ilo_dev *dev,
   1607                   enum pipe_format format,
   1608                   struct ilo_fb_blend_caps *caps)
   1609 {
   1610    const struct util_format_description *desc =
   1611       util_format_description(format);
   1612    const int ch = util_format_get_first_non_void_channel(format);
   1613 
   1614    memset(caps, 0, sizeof(*caps));
   1615 
   1616    if (format == PIPE_FORMAT_NONE || desc->is_mixed)
   1617       return;
   1618 
   1619    caps->is_unorm = (ch >= 0 && desc->channel[ch].normalized &&
   1620          desc->channel[ch].type == UTIL_FORMAT_TYPE_UNSIGNED &&
   1621          desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB);
   1622    caps->is_integer = util_format_is_pure_integer(format);
   1623 
   1624    /*
   1625     * From the Sandy Bridge PRM, volume 2 part 1, page 365:
   1626     *
   1627     *     "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
   1628     *      variants), otherwise Logic Ops must be DISABLED."
   1629     *
   1630     * According to the classic driver, this is lifted on Gen8+.
   1631     */
   1632    caps->can_logicop = (ilo_dev_gen(dev) >= ILO_GEN(8) || caps->is_unorm);
   1633 
   1634    /* no blending for pure integer formats */
   1635    caps->can_blend = !caps->is_integer;
   1636 
   1637    /*
   1638     * From the Sandy Bridge PRM, volume 2 part 1, page 382:
   1639     *
   1640     *     "Alpha Test can only be enabled if Pixel Shader outputs a float
   1641     *      alpha value."
   1642     */
   1643    caps->can_alpha_test = !caps->is_integer;
   1644 
   1645    caps->force_dst_alpha_one =
   1646       (ilo_format_translate_render(dev, format) !=
   1647        ilo_format_translate_color(dev, format));
   1648 
   1649    /* sanity check */
   1650    if (caps->force_dst_alpha_one) {
   1651       enum pipe_format render_format;
   1652 
   1653       switch (format) {
   1654       case PIPE_FORMAT_B8G8R8X8_UNORM:
   1655          render_format = PIPE_FORMAT_B8G8R8A8_UNORM;
   1656          break;
   1657       default:
   1658          render_format = PIPE_FORMAT_NONE;
   1659          break;
   1660       }
   1661 
   1662       assert(ilo_format_translate_render(dev, format) ==
   1663              ilo_format_translate_color(dev, render_format));
   1664    }
   1665 }
   1666 
   1667 static void
   1668 ilo_set_framebuffer_state(struct pipe_context *pipe,
   1669                           const struct pipe_framebuffer_state *state)
   1670 {
   1671    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   1672    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1673    struct ilo_fb_state *fb = &vec->fb;
   1674    const struct pipe_surface *first_surf = NULL;
   1675    int i;
   1676 
   1677    util_copy_framebuffer_state(&fb->state, state);
   1678 
   1679    fb->has_integer_rt = false;
   1680    for (i = 0; i < state->nr_cbufs; i++) {
   1681       if (state->cbufs[i]) {
   1682          fb_set_blend_caps(dev, state->cbufs[i]->format, &fb->blend_caps[i]);
   1683 
   1684          fb->has_integer_rt |= fb->blend_caps[i].is_integer;
   1685 
   1686          if (!first_surf)
   1687             first_surf = state->cbufs[i];
   1688       } else {
   1689          fb_set_blend_caps(dev, PIPE_FORMAT_NONE, &fb->blend_caps[i]);
   1690       }
   1691    }
   1692 
   1693    if (!first_surf && state->zsbuf)
   1694       first_surf = state->zsbuf;
   1695 
   1696    fb->num_samples = (first_surf) ? first_surf->texture->nr_samples : 1;
   1697    if (!fb->num_samples)
   1698       fb->num_samples = 1;
   1699 
   1700    if (state->zsbuf) {
   1701       const struct ilo_surface_cso *cso =
   1702          (const struct ilo_surface_cso *) state->zsbuf;
   1703       const struct ilo_texture *tex = ilo_texture(cso->base.texture);
   1704 
   1705       fb->has_hiz = cso->u.zs.hiz_vma;
   1706       fb->depth_offset_format =
   1707          ilo_format_translate_depth(dev, tex->image_format);
   1708    } else {
   1709       fb->has_hiz = false;
   1710       fb->depth_offset_format = GEN6_ZFORMAT_D32_FLOAT;
   1711    }
   1712 
   1713    /*
   1714     * The PRMs list several restrictions when the framebuffer has more than
   1715     * one surface.  It seems they are actually lifted on GEN6+.
   1716     */
   1717 
   1718    vec->dirty |= ILO_DIRTY_FB;
   1719 }
   1720 
   1721 static void
   1722 ilo_set_polygon_stipple(struct pipe_context *pipe,
   1723                         const struct pipe_poly_stipple *state)
   1724 {
   1725    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   1726    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1727    struct ilo_state_poly_stipple_info info;
   1728    int i;
   1729 
   1730    for (i = 0; i < 32; i++)
   1731       info.pattern[i] = state->stipple[i];
   1732 
   1733    ilo_state_poly_stipple_set_info(&vec->poly_stipple, dev, &info);
   1734 
   1735    vec->dirty |= ILO_DIRTY_POLY_STIPPLE;
   1736 }
   1737 
   1738 static void
   1739 ilo_set_scissor_states(struct pipe_context *pipe,
   1740                        unsigned start_slot,
   1741                        unsigned num_scissors,
   1742                        const struct pipe_scissor_state *scissors)
   1743 {
   1744    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1745    unsigned i;
   1746 
   1747    for (i = 0; i < num_scissors; i++) {
   1748       struct ilo_state_viewport_scissor_info *info =
   1749          &vec->viewport.scissors[start_slot + i];
   1750 
   1751       if (scissors[i].minx < scissors[i].maxx &&
   1752           scissors[i].miny < scissors[i].maxy) {
   1753          info->min_x = scissors[i].minx;
   1754          info->min_y = scissors[i].miny;
   1755          info->max_x = scissors[i].maxx - 1;
   1756          info->max_y = scissors[i].maxy - 1;
   1757       } else {
   1758          info->min_x = 1;
   1759          info->min_y = 1;
   1760          info->max_x = 0;
   1761          info->max_y = 0;
   1762       }
   1763    }
   1764 
   1765    vec->dirty |= ILO_DIRTY_SCISSOR;
   1766 }
   1767 
   1768 static void
   1769 ilo_set_viewport_states(struct pipe_context *pipe,
   1770                         unsigned start_slot,
   1771                         unsigned num_viewports,
   1772                         const struct pipe_viewport_state *viewports)
   1773 {
   1774    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1775 
   1776    if (viewports) {
   1777       unsigned i;
   1778 
   1779       for (i = 0; i < num_viewports; i++) {
   1780          struct ilo_state_viewport_matrix_info *info =
   1781             &vec->viewport.matrices[start_slot + i];
   1782 
   1783          memcpy(info->scale, viewports[i].scale, sizeof(info->scale));
   1784          memcpy(info->translate, viewports[i].translate,
   1785                sizeof(info->translate));
   1786       }
   1787 
   1788       if (vec->viewport.params.count < start_slot + num_viewports)
   1789          vec->viewport.params.count = start_slot + num_viewports;
   1790 
   1791       /* need to save viewport 0 for util_blitter */
   1792       if (!start_slot && num_viewports)
   1793          vec->viewport.viewport0 = viewports[0];
   1794    }
   1795    else {
   1796       if (vec->viewport.params.count <= start_slot + num_viewports &&
   1797           vec->viewport.params.count > start_slot)
   1798          vec->viewport.params.count = start_slot;
   1799    }
   1800 
   1801    vec->dirty |= ILO_DIRTY_VIEWPORT;
   1802 }
   1803 
   1804 static void
   1805 ilo_set_sampler_views(struct pipe_context *pipe, enum pipe_shader_type shader,
   1806                       unsigned start, unsigned count,
   1807                       struct pipe_sampler_view **views)
   1808 {
   1809    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1810    struct ilo_view_state *dst = &vec->view[shader];
   1811    unsigned i;
   1812 
   1813    assert(start + count <= ARRAY_SIZE(dst->states));
   1814 
   1815    if (views) {
   1816       for (i = 0; i < count; i++)
   1817          pipe_sampler_view_reference(&dst->states[start + i], views[i]);
   1818    }
   1819    else {
   1820       for (i = 0; i < count; i++)
   1821          pipe_sampler_view_reference(&dst->states[start + i], NULL);
   1822    }
   1823 
   1824    if (dst->count <= start + count) {
   1825       if (views)
   1826          count += start;
   1827       else
   1828          count = start;
   1829 
   1830       while (count > 0 && !dst->states[count - 1])
   1831          count--;
   1832 
   1833       dst->count = count;
   1834    }
   1835 
   1836    switch (shader) {
   1837    case PIPE_SHADER_VERTEX:
   1838       vec->dirty |= ILO_DIRTY_VIEW_VS;
   1839       break;
   1840    case PIPE_SHADER_GEOMETRY:
   1841       vec->dirty |= ILO_DIRTY_VIEW_GS;
   1842       break;
   1843    case PIPE_SHADER_FRAGMENT:
   1844       vec->dirty |= ILO_DIRTY_VIEW_FS;
   1845       break;
   1846    case PIPE_SHADER_COMPUTE:
   1847       vec->dirty |= ILO_DIRTY_VIEW_CS;
   1848       break;
   1849    default:
   1850       assert(!"unexpected shader type");
   1851       break;
   1852    }
   1853 }
   1854 
   1855 static void
   1856 ilo_set_shader_images(struct pipe_context *pipe, enum pipe_shader_type shader,
   1857                       unsigned start, unsigned count,
   1858                       const struct pipe_image_view *views)
   1859 {
   1860 #if 0
   1861    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1862    struct ilo_resource_state *dst = &vec->resource;
   1863    unsigned i;
   1864 
   1865    assert(start + count <= ARRAY_SIZE(dst->states));
   1866 
   1867    if (surfaces) {
   1868       for (i = 0; i < count; i++)
   1869          pipe_surface_reference(&dst->states[start + i], surfaces[i]);
   1870    }
   1871    else {
   1872       for (i = 0; i < count; i++)
   1873          pipe_surface_reference(&dst->states[start + i], NULL);
   1874    }
   1875 
   1876    if (dst->count <= start + count) {
   1877       if (surfaces)
   1878          count += start;
   1879       else
   1880          count = start;
   1881 
   1882       while (count > 0 && !dst->states[count - 1])
   1883          count--;
   1884 
   1885       dst->count = count;
   1886    }
   1887 
   1888    vec->dirty |= ILO_DIRTY_RESOURCE;
   1889 #endif
   1890 }
   1891 
   1892 static void
   1893 ilo_set_vertex_buffers(struct pipe_context *pipe,
   1894                        unsigned start_slot, unsigned num_buffers,
   1895                        const struct pipe_vertex_buffer *buffers)
   1896 {
   1897    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1898    unsigned i;
   1899 
   1900    /* no PIPE_CAP_USER_VERTEX_BUFFERS */
   1901    if (buffers) {
   1902       for (i = 0; i < num_buffers; i++)
   1903          assert(!buffers[i].user_buffer);
   1904    }
   1905 
   1906    util_set_vertex_buffers_mask(vec->vb.states,
   1907          &vec->vb.enabled_mask, buffers, start_slot, num_buffers);
   1908 
   1909    vec->dirty |= ILO_DIRTY_VB;
   1910 }
   1911 
   1912 static void
   1913 ilo_set_index_buffer(struct pipe_context *pipe,
   1914                      const struct pipe_index_buffer *state)
   1915 {
   1916    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1917 
   1918    if (state) {
   1919       pipe_resource_reference(&vec->ib.state.buffer, state->buffer);
   1920       vec->ib.state = *state;
   1921    } else {
   1922       pipe_resource_reference(&vec->ib.state.buffer, NULL);
   1923       memset(&vec->ib.state, 0, sizeof(vec->ib.state));
   1924    }
   1925 
   1926    vec->dirty |= ILO_DIRTY_IB;
   1927 }
   1928 
   1929 static struct pipe_stream_output_target *
   1930 ilo_create_stream_output_target(struct pipe_context *pipe,
   1931                                 struct pipe_resource *res,
   1932                                 unsigned buffer_offset,
   1933                                 unsigned buffer_size)
   1934 {
   1935    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   1936    struct ilo_stream_output_target *target;
   1937    struct ilo_state_sol_buffer_info info;
   1938 
   1939    target = CALLOC_STRUCT(ilo_stream_output_target);
   1940    assert(target);
   1941 
   1942    pipe_reference_init(&target->base.reference, 1);
   1943    pipe_resource_reference(&target->base.buffer, res);
   1944    target->base.context = pipe;
   1945    target->base.buffer_offset = buffer_offset;
   1946    target->base.buffer_size = buffer_size;
   1947 
   1948    memset(&info, 0, sizeof(info));
   1949    info.vma = ilo_resource_get_vma(res);
   1950    info.offset = buffer_offset;
   1951    info.size = buffer_size;
   1952 
   1953    ilo_state_sol_buffer_init(&target->sb, dev, &info);
   1954 
   1955    return &target->base;
   1956 }
   1957 
   1958 static void
   1959 ilo_set_stream_output_targets(struct pipe_context *pipe,
   1960                               unsigned num_targets,
   1961                               struct pipe_stream_output_target **targets,
   1962                               const unsigned *offset)
   1963 {
   1964    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   1965    unsigned i;
   1966    unsigned append_bitmask = 0;
   1967 
   1968    if (!targets)
   1969       num_targets = 0;
   1970 
   1971    /* util_blitter may set this unnecessarily */
   1972    if (!vec->so.count && !num_targets)
   1973       return;
   1974 
   1975    for (i = 0; i < num_targets; i++) {
   1976       pipe_so_target_reference(&vec->so.states[i], targets[i]);
   1977       if (offset[i] == (unsigned)-1)
   1978          append_bitmask |= 1 << i;
   1979    }
   1980 
   1981    for (; i < vec->so.count; i++)
   1982       pipe_so_target_reference(&vec->so.states[i], NULL);
   1983 
   1984    vec->so.count = num_targets;
   1985    vec->so.append_bitmask = append_bitmask;
   1986 
   1987    vec->so.enabled = (vec->so.count > 0);
   1988 
   1989    vec->dirty |= ILO_DIRTY_SO;
   1990 }
   1991 
   1992 static void
   1993 ilo_stream_output_target_destroy(struct pipe_context *pipe,
   1994                                  struct pipe_stream_output_target *target)
   1995 {
   1996    pipe_resource_reference(&target->buffer, NULL);
   1997    FREE(target);
   1998 }
   1999 
   2000 static struct pipe_sampler_view *
   2001 ilo_create_sampler_view(struct pipe_context *pipe,
   2002                         struct pipe_resource *res,
   2003                         const struct pipe_sampler_view *templ)
   2004 {
   2005    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   2006    struct ilo_view_cso *view;
   2007 
   2008    view = CALLOC_STRUCT(ilo_view_cso);
   2009    assert(view);
   2010 
   2011    view->base = *templ;
   2012    pipe_reference_init(&view->base.reference, 1);
   2013    view->base.texture = NULL;
   2014    pipe_resource_reference(&view->base.texture, res);
   2015    view->base.context = pipe;
   2016 
   2017    if (res->target == PIPE_BUFFER) {
   2018       struct ilo_state_surface_buffer_info info;
   2019 
   2020       memset(&info, 0, sizeof(info));
   2021       info.vma = ilo_resource_get_vma(res);
   2022       info.offset = templ->u.buf.offset;
   2023       info.size = templ->u.buf.size;
   2024       info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
   2025       info.format = ilo_format_translate_color(dev, templ->format);
   2026       info.format_size = util_format_get_blocksize(templ->format);
   2027       info.struct_size = info.format_size;
   2028       info.readonly = true;
   2029 
   2030       ilo_state_surface_init_for_buffer(&view->surface, dev, &info);
   2031    } else {
   2032       struct ilo_texture *tex = ilo_texture(res);
   2033       struct ilo_state_surface_image_info info;
   2034 
   2035       /* warn about degraded performance because of a missing binding flag */
   2036       if (tex->image.tiling == GEN6_TILING_NONE &&
   2037           !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) {
   2038          ilo_warn("creating sampler view for a resource "
   2039                   "not created for sampling\n");
   2040       }
   2041 
   2042       memset(&info, 0, sizeof(info));
   2043 
   2044       info.img = &tex->image;
   2045       info.level_base = templ->u.tex.first_level;
   2046       info.level_count = templ->u.tex.last_level -
   2047          templ->u.tex.first_level + 1;
   2048       info.slice_base = templ->u.tex.first_layer;
   2049       info.slice_count = templ->u.tex.last_layer -
   2050          templ->u.tex.first_layer + 1;
   2051 
   2052       info.vma = &tex->vma;
   2053       info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
   2054       info.type = tex->image.type;
   2055 
   2056       if (templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
   2057           tex->separate_s8) {
   2058          info.format = ilo_format_translate_texture(dev,
   2059                PIPE_FORMAT_Z32_FLOAT);
   2060       } else {
   2061          info.format = ilo_format_translate_texture(dev, templ->format);
   2062       }
   2063 
   2064       info.is_array = util_resource_is_array_texture(&tex->base);
   2065       info.readonly = true;
   2066 
   2067       ilo_state_surface_init_for_image(&view->surface, dev, &info);
   2068    }
   2069 
   2070    return &view->base;
   2071 }
   2072 
   2073 static void
   2074 ilo_sampler_view_destroy(struct pipe_context *pipe,
   2075                          struct pipe_sampler_view *view)
   2076 {
   2077    pipe_resource_reference(&view->texture, NULL);
   2078    FREE(view);
   2079 }
   2080 
   2081 static struct pipe_surface *
   2082 ilo_create_surface(struct pipe_context *pipe,
   2083                    struct pipe_resource *res,
   2084                    const struct pipe_surface *templ)
   2085 {
   2086    const struct ilo_dev *dev = ilo_context(pipe)->dev;
   2087    struct ilo_texture *tex = ilo_texture(res);
   2088    struct ilo_surface_cso *surf;
   2089 
   2090    surf = CALLOC_STRUCT(ilo_surface_cso);
   2091    assert(surf);
   2092 
   2093    surf->base = *templ;
   2094    pipe_reference_init(&surf->base.reference, 1);
   2095    surf->base.texture = NULL;
   2096    pipe_resource_reference(&surf->base.texture, &tex->base);
   2097 
   2098    surf->base.context = pipe;
   2099    surf->base.width = u_minify(tex->base.width0, templ->u.tex.level);
   2100    surf->base.height = u_minify(tex->base.height0, templ->u.tex.level);
   2101 
   2102    surf->is_rt = !util_format_is_depth_or_stencil(templ->format);
   2103 
   2104    if (surf->is_rt) {
   2105       struct ilo_state_surface_image_info info;
   2106 
   2107       /* relax this? */
   2108       assert(tex->base.target != PIPE_BUFFER);
   2109 
   2110       memset(&info, 0, sizeof(info));
   2111 
   2112       info.img = &tex->image;
   2113       info.level_base = templ->u.tex.level;
   2114       info.level_count = 1;
   2115       info.slice_base = templ->u.tex.first_layer;
   2116       info.slice_count = templ->u.tex.last_layer -
   2117          templ->u.tex.first_layer + 1;
   2118 
   2119       info.vma = &tex->vma;
   2120       if (ilo_image_can_enable_aux(&tex->image, templ->u.tex.level))
   2121          info.aux_vma = &tex->aux_vma;
   2122 
   2123       info.access = ILO_STATE_SURFACE_ACCESS_DP_RENDER;
   2124 
   2125       info.type = (tex->image.type == GEN6_SURFTYPE_CUBE) ?
   2126          GEN6_SURFTYPE_2D : tex->image.type;
   2127 
   2128       info.format = ilo_format_translate_render(dev, templ->format);
   2129       info.is_array = util_resource_is_array_texture(&tex->base);
   2130 
   2131       ilo_state_surface_init_for_image(&surf->u.rt, dev, &info);
   2132    } else {
   2133       struct ilo_state_zs_info info;
   2134 
   2135       assert(res->target != PIPE_BUFFER);
   2136 
   2137       memset(&info, 0, sizeof(info));
   2138 
   2139       if (templ->format == PIPE_FORMAT_S8_UINT) {
   2140          info.s_vma = &tex->vma;
   2141          info.s_img = &tex->image;
   2142       } else {
   2143          info.z_vma = &tex->vma;
   2144          info.z_img = &tex->image;
   2145 
   2146          if (tex->separate_s8) {
   2147             info.s_vma = &tex->separate_s8->vma;
   2148             info.s_img = &tex->separate_s8->image;
   2149          }
   2150 
   2151          if (ilo_image_can_enable_aux(&tex->image, templ->u.tex.level))
   2152             info.hiz_vma = &tex->aux_vma;
   2153       }
   2154 
   2155       info.level = templ->u.tex.level;
   2156       info.slice_base = templ->u.tex.first_layer;
   2157       info.slice_count = templ->u.tex.last_layer -
   2158          templ->u.tex.first_layer + 1;
   2159 
   2160       info.type = (tex->image.type == GEN6_SURFTYPE_CUBE) ?
   2161          GEN6_SURFTYPE_2D : tex->image.type;
   2162 
   2163       info.format = ilo_format_translate_depth(dev, tex->image_format);
   2164       if (ilo_dev_gen(dev) == ILO_GEN(6) && !info.hiz_vma &&
   2165           tex->image_format == PIPE_FORMAT_Z24X8_UNORM)
   2166          info.format = GEN6_ZFORMAT_D24_UNORM_S8_UINT;
   2167 
   2168       ilo_state_zs_init(&surf->u.zs, dev, &info);
   2169    }
   2170 
   2171    return &surf->base;
   2172 }
   2173 
   2174 static void
   2175 ilo_surface_destroy(struct pipe_context *pipe,
   2176                     struct pipe_surface *surface)
   2177 {
   2178    pipe_resource_reference(&surface->texture, NULL);
   2179    FREE(surface);
   2180 }
   2181 
   2182 static void *
   2183 ilo_create_compute_state(struct pipe_context *pipe,
   2184                          const struct pipe_compute_state *state)
   2185 {
   2186    struct ilo_context *ilo = ilo_context(pipe);
   2187    struct ilo_shader_state *shader;
   2188 
   2189    shader = ilo_shader_create_cs(ilo->dev, state, &ilo->state_vector);
   2190    assert(shader);
   2191 
   2192    ilo_shader_cache_add(ilo->shader_cache, shader);
   2193 
   2194    return shader;
   2195 }
   2196 
   2197 static void
   2198 ilo_bind_compute_state(struct pipe_context *pipe, void *state)
   2199 {
   2200    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   2201 
   2202    vec->cs = state;
   2203 
   2204    vec->dirty |= ILO_DIRTY_CS;
   2205 }
   2206 
   2207 static void
   2208 ilo_delete_compute_state(struct pipe_context *pipe, void *state)
   2209 {
   2210    struct ilo_context *ilo = ilo_context(pipe);
   2211    struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
   2212 
   2213    ilo_shader_cache_remove(ilo->shader_cache, cs);
   2214    ilo_shader_destroy(cs);
   2215 }
   2216 
   2217 static void
   2218 ilo_set_compute_resources(struct pipe_context *pipe,
   2219                           unsigned start, unsigned count,
   2220                           struct pipe_surface **surfaces)
   2221 {
   2222    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   2223    struct ilo_resource_state *dst = &vec->cs_resource;
   2224    unsigned i;
   2225 
   2226    assert(start + count <= ARRAY_SIZE(dst->states));
   2227 
   2228    if (surfaces) {
   2229       for (i = 0; i < count; i++)
   2230          pipe_surface_reference(&dst->states[start + i], surfaces[i]);
   2231    }
   2232    else {
   2233       for (i = 0; i < count; i++)
   2234          pipe_surface_reference(&dst->states[start + i], NULL);
   2235    }
   2236 
   2237    if (dst->count <= start + count) {
   2238       if (surfaces)
   2239          count += start;
   2240       else
   2241          count = start;
   2242 
   2243       while (count > 0 && !dst->states[count - 1])
   2244          count--;
   2245 
   2246       dst->count = count;
   2247    }
   2248 
   2249    vec->dirty |= ILO_DIRTY_CS_RESOURCE;
   2250 }
   2251 
   2252 static void
   2253 ilo_set_global_binding(struct pipe_context *pipe,
   2254                        unsigned start, unsigned count,
   2255                        struct pipe_resource **resources,
   2256                        uint32_t **handles)
   2257 {
   2258    struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
   2259    struct ilo_global_binding_cso *dst;
   2260    unsigned i;
   2261 
   2262    /* make room */
   2263    if (vec->global_binding.count < start + count) {
   2264       if (resources) {
   2265          const unsigned old_size = vec->global_binding.bindings.size;
   2266          const unsigned new_size = sizeof(*dst) * (start + count);
   2267 
   2268          if (old_size < new_size) {
   2269             util_dynarray_resize(&vec->global_binding.bindings, new_size);
   2270             memset(vec->global_binding.bindings.data + old_size, 0,
   2271                   new_size - old_size);
   2272          }
   2273       } else {
   2274          count = vec->global_binding.count - start;
   2275       }
   2276    }
   2277 
   2278    dst = util_dynarray_element(&vec->global_binding.bindings,
   2279          struct ilo_global_binding_cso, start);
   2280 
   2281    if (resources) {
   2282       for (i = 0; i < count; i++) {
   2283          pipe_resource_reference(&dst[i].resource, resources[i]);
   2284          dst[i].handle = handles[i];
   2285       }
   2286    } else {
   2287       for (i = 0; i < count; i++) {
   2288          pipe_resource_reference(&dst[i].resource, NULL);
   2289          dst[i].handle = NULL;
   2290       }
   2291    }
   2292 
   2293    if (vec->global_binding.count <= start + count) {
   2294       dst = util_dynarray_begin(&vec->global_binding.bindings);
   2295 
   2296       if (resources)
   2297          count += start;
   2298       else
   2299          count = start;
   2300 
   2301       while (count > 0 && !dst[count - 1].resource)
   2302          count--;
   2303 
   2304       vec->global_binding.count = count;
   2305    }
   2306 
   2307    vec->dirty |= ILO_DIRTY_GLOBAL_BINDING;
   2308 }
   2309 
   2310 /**
   2311  * Initialize state-related functions.
   2312  */
   2313 void
   2314 ilo_init_state_functions(struct ilo_context *ilo)
   2315 {
   2316    STATIC_ASSERT(ILO_STATE_COUNT <= 32);
   2317 
   2318    ilo->base.create_blend_state = ilo_create_blend_state;
   2319    ilo->base.bind_blend_state = ilo_bind_blend_state;
   2320    ilo->base.delete_blend_state = ilo_delete_blend_state;
   2321    ilo->base.create_sampler_state = ilo_create_sampler_state;
   2322    ilo->base.bind_sampler_states = ilo_bind_sampler_states;
   2323    ilo->base.delete_sampler_state = ilo_delete_sampler_state;
   2324    ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
   2325    ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
   2326    ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
   2327    ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
   2328    ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
   2329    ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
   2330    ilo->base.create_fs_state = ilo_create_fs_state;
   2331    ilo->base.bind_fs_state = ilo_bind_fs_state;
   2332    ilo->base.delete_fs_state = ilo_delete_fs_state;
   2333    ilo->base.create_vs_state = ilo_create_vs_state;
   2334    ilo->base.bind_vs_state = ilo_bind_vs_state;
   2335    ilo->base.delete_vs_state = ilo_delete_vs_state;
   2336    ilo->base.create_gs_state = ilo_create_gs_state;
   2337    ilo->base.bind_gs_state = ilo_bind_gs_state;
   2338    ilo->base.delete_gs_state = ilo_delete_gs_state;
   2339    ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
   2340    ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
   2341    ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
   2342 
   2343    ilo->base.set_blend_color = ilo_set_blend_color;
   2344    ilo->base.set_stencil_ref = ilo_set_stencil_ref;
   2345    ilo->base.set_sample_mask = ilo_set_sample_mask;
   2346    ilo->base.set_clip_state = ilo_set_clip_state;
   2347    ilo->base.set_constant_buffer = ilo_set_constant_buffer;
   2348    ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
   2349    ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
   2350    ilo->base.set_scissor_states = ilo_set_scissor_states;
   2351    ilo->base.set_viewport_states = ilo_set_viewport_states;
   2352    ilo->base.set_sampler_views = ilo_set_sampler_views;
   2353    ilo->base.set_shader_images = ilo_set_shader_images;
   2354    ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
   2355    ilo->base.set_index_buffer = ilo_set_index_buffer;
   2356 
   2357    ilo->base.create_stream_output_target = ilo_create_stream_output_target;
   2358    ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
   2359    ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
   2360 
   2361    ilo->base.create_sampler_view = ilo_create_sampler_view;
   2362    ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
   2363 
   2364    ilo->base.create_surface = ilo_create_surface;
   2365    ilo->base.surface_destroy = ilo_surface_destroy;
   2366 
   2367    ilo->base.create_compute_state = ilo_create_compute_state;
   2368    ilo->base.bind_compute_state = ilo_bind_compute_state;
   2369    ilo->base.delete_compute_state = ilo_delete_compute_state;
   2370    ilo->base.set_compute_resources = ilo_set_compute_resources;
   2371    ilo->base.set_global_binding = ilo_set_global_binding;
   2372 }
   2373 
   2374 void
   2375 ilo_state_vector_init(const struct ilo_dev *dev,
   2376                       struct ilo_state_vector *vec)
   2377 {
   2378    struct ilo_state_urb_info urb_info;
   2379 
   2380    vec->sample_mask = ~0u;
   2381 
   2382    ilo_state_viewport_init_data_only(&vec->viewport.vp, dev,
   2383          vec->viewport.vp_data, sizeof(vec->viewport.vp_data));
   2384    assert(vec->viewport.vp.array_size >= ILO_MAX_VIEWPORTS);
   2385 
   2386    vec->viewport.params.matrices = vec->viewport.matrices;
   2387    vec->viewport.params.scissors = vec->viewport.scissors;
   2388 
   2389    ilo_state_hs_init_disabled(&vec->disabled_hs, dev);
   2390    ilo_state_ds_init_disabled(&vec->disabled_ds, dev);
   2391    ilo_state_gs_init_disabled(&vec->disabled_gs, dev);
   2392 
   2393    ilo_state_sol_buffer_init_disabled(&vec->so.dummy_sb, dev);
   2394 
   2395    ilo_state_surface_init_for_null(&vec->fb.null_rt, dev);
   2396    ilo_state_zs_init_for_null(&vec->fb.null_zs, dev);
   2397 
   2398    ilo_state_sampler_init_disabled(&vec->disabled_sampler, dev);
   2399 
   2400    memset(&urb_info, 0, sizeof(urb_info));
   2401    ilo_state_urb_init(&vec->urb, dev, &urb_info);
   2402 
   2403    util_dynarray_init(&vec->global_binding.bindings);
   2404 
   2405    vec->dirty = ILO_DIRTY_ALL;
   2406 }
   2407 
   2408 void
   2409 ilo_state_vector_cleanup(struct ilo_state_vector *vec)
   2410 {
   2411    unsigned i, sh;
   2412 
   2413    for (i = 0; i < ARRAY_SIZE(vec->vb.states); i++) {
   2414       if (vec->vb.enabled_mask & (1 << i))
   2415          pipe_resource_reference(&vec->vb.states[i].buffer, NULL);
   2416    }
   2417 
   2418    pipe_resource_reference(&vec->ib.state.buffer, NULL);
   2419    pipe_resource_reference(&vec->ib.hw_resource, NULL);
   2420 
   2421    for (i = 0; i < vec->so.count; i++)
   2422       pipe_so_target_reference(&vec->so.states[i], NULL);
   2423 
   2424    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
   2425       for (i = 0; i < vec->view[sh].count; i++) {
   2426          struct pipe_sampler_view *view = vec->view[sh].states[i];
   2427          pipe_sampler_view_reference(&view, NULL);
   2428       }
   2429 
   2430       for (i = 0; i < ARRAY_SIZE(vec->cbuf[sh].cso); i++) {
   2431          struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
   2432          pipe_resource_reference(&cbuf->resource, NULL);
   2433       }
   2434    }
   2435 
   2436    for (i = 0; i < vec->resource.count; i++)
   2437       pipe_surface_reference(&vec->resource.states[i], NULL);
   2438 
   2439    for (i = 0; i < vec->fb.state.nr_cbufs; i++)
   2440       pipe_surface_reference(&vec->fb.state.cbufs[i], NULL);
   2441 
   2442    if (vec->fb.state.zsbuf)
   2443       pipe_surface_reference(&vec->fb.state.zsbuf, NULL);
   2444 
   2445    for (i = 0; i < vec->cs_resource.count; i++)
   2446       pipe_surface_reference(&vec->cs_resource.states[i], NULL);
   2447 
   2448    for (i = 0; i < vec->global_binding.count; i++) {
   2449       struct ilo_global_binding_cso *cso =
   2450          util_dynarray_element(&vec->global_binding.bindings,
   2451                struct ilo_global_binding_cso, i);
   2452       pipe_resource_reference(&cso->resource, NULL);
   2453    }
   2454 
   2455    util_dynarray_fini(&vec->global_binding.bindings);
   2456 }
   2457 
   2458 /**
   2459  * Mark all states that have the resource dirty.
   2460  */
   2461 void
   2462 ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
   2463                                   struct pipe_resource *res)
   2464 {
   2465    uint32_t states = 0;
   2466    unsigned sh, i;
   2467 
   2468    if (res->target == PIPE_BUFFER) {
   2469       uint32_t vb_mask = vec->vb.enabled_mask;
   2470 
   2471       while (vb_mask) {
   2472          const unsigned idx = u_bit_scan(&vb_mask);
   2473 
   2474          if (vec->vb.states[idx].buffer == res) {
   2475             states |= ILO_DIRTY_VB;
   2476             break;
   2477          }
   2478       }
   2479 
   2480       if (vec->ib.state.buffer == res) {
   2481          states |= ILO_DIRTY_IB;
   2482 
   2483          /*
   2484           * finalize_index_buffer() has an optimization that clears
   2485           * ILO_DIRTY_IB when the HW states do not change.  However, it fails
   2486           * to flush the VF cache when the HW states do not change, but the
   2487           * contents of the IB has changed.  Here, we set the index size to an
   2488           * invalid value to avoid the optimization.
   2489           */
   2490          vec->ib.hw_index_size = 0;
   2491       }
   2492 
   2493       for (i = 0; i < vec->so.count; i++) {
   2494          if (vec->so.states[i]->buffer == res) {
   2495             states |= ILO_DIRTY_SO;
   2496             break;
   2497          }
   2498       }
   2499    }
   2500 
   2501    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
   2502       for (i = 0; i < vec->view[sh].count; i++) {
   2503          struct ilo_view_cso *cso = (struct ilo_view_cso *) vec->view[sh].states[i];
   2504 
   2505          if (cso->base.texture == res) {
   2506             static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = {
   2507                [PIPE_SHADER_VERTEX]    = ILO_DIRTY_VIEW_VS,
   2508                [PIPE_SHADER_FRAGMENT]  = ILO_DIRTY_VIEW_FS,
   2509                [PIPE_SHADER_GEOMETRY]  = ILO_DIRTY_VIEW_GS,
   2510                [PIPE_SHADER_COMPUTE]   = ILO_DIRTY_VIEW_CS,
   2511             };
   2512 
   2513             states |= view_dirty_bits[sh];
   2514             break;
   2515          }
   2516       }
   2517 
   2518       if (res->target == PIPE_BUFFER) {
   2519          for (i = 0; i < ARRAY_SIZE(vec->cbuf[sh].cso); i++) {
   2520             struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
   2521 
   2522             if (cbuf->resource == res) {
   2523                states |= ILO_DIRTY_CBUF;
   2524                break;
   2525             }
   2526          }
   2527       }
   2528    }
   2529 
   2530    for (i = 0; i < vec->resource.count; i++) {
   2531       struct ilo_surface_cso *cso =
   2532          (struct ilo_surface_cso *) vec->resource.states[i];
   2533 
   2534       if (cso->base.texture == res) {
   2535          states |= ILO_DIRTY_RESOURCE;
   2536          break;
   2537       }
   2538    }
   2539 
   2540    /* for now? */
   2541    if (res->target != PIPE_BUFFER) {
   2542       for (i = 0; i < vec->fb.state.nr_cbufs; i++) {
   2543          struct ilo_surface_cso *cso =
   2544             (struct ilo_surface_cso *) vec->fb.state.cbufs[i];
   2545          if (cso && cso->base.texture == res) {
   2546             states |= ILO_DIRTY_FB;
   2547             break;
   2548          }
   2549       }
   2550 
   2551       if (vec->fb.state.zsbuf && vec->fb.state.zsbuf->texture == res)
   2552          states |= ILO_DIRTY_FB;
   2553    }
   2554 
   2555    for (i = 0; i < vec->cs_resource.count; i++) {
   2556       struct ilo_surface_cso *cso =
   2557          (struct ilo_surface_cso *) vec->cs_resource.states[i];
   2558       if (cso->base.texture == res) {
   2559          states |= ILO_DIRTY_CS_RESOURCE;
   2560          break;
   2561       }
   2562    }
   2563 
   2564    for (i = 0; i < vec->global_binding.count; i++) {
   2565       struct ilo_global_binding_cso *cso =
   2566          util_dynarray_element(&vec->global_binding.bindings,
   2567                struct ilo_global_binding_cso, i);
   2568 
   2569       if (cso->resource == res) {
   2570          states |= ILO_DIRTY_GLOBAL_BINDING;
   2571          break;
   2572       }
   2573    }
   2574 
   2575    vec->dirty |= states;
   2576 }
   2577 
   2578 void
   2579 ilo_state_vector_dump_dirty(const struct ilo_state_vector *vec)
   2580 {
   2581    static const char *state_names[ILO_STATE_COUNT] = {
   2582       [ILO_STATE_VB]              = "VB",
   2583       [ILO_STATE_VE]              = "VE",
   2584       [ILO_STATE_IB]              = "IB",
   2585       [ILO_STATE_VS]              = "VS",
   2586       [ILO_STATE_GS]              = "GS",
   2587       [ILO_STATE_SO]              = "SO",
   2588       [ILO_STATE_CLIP]            = "CLIP",
   2589       [ILO_STATE_VIEWPORT]        = "VIEWPORT",
   2590       [ILO_STATE_SCISSOR]         = "SCISSOR",
   2591       [ILO_STATE_RASTERIZER]      = "RASTERIZER",
   2592       [ILO_STATE_POLY_STIPPLE]    = "POLY_STIPPLE",
   2593       [ILO_STATE_SAMPLE_MASK]     = "SAMPLE_MASK",
   2594       [ILO_STATE_FS]              = "FS",
   2595       [ILO_STATE_DSA]             = "DSA",
   2596       [ILO_STATE_STENCIL_REF]     = "STENCIL_REF",
   2597       [ILO_STATE_BLEND]           = "BLEND",
   2598       [ILO_STATE_BLEND_COLOR]     = "BLEND_COLOR",
   2599       [ILO_STATE_FB]              = "FB",
   2600       [ILO_STATE_SAMPLER_VS]      = "SAMPLER_VS",
   2601       [ILO_STATE_SAMPLER_GS]      = "SAMPLER_GS",
   2602       [ILO_STATE_SAMPLER_FS]      = "SAMPLER_FS",
   2603       [ILO_STATE_SAMPLER_CS]      = "SAMPLER_CS",
   2604       [ILO_STATE_VIEW_VS]         = "VIEW_VS",
   2605       [ILO_STATE_VIEW_GS]         = "VIEW_GS",
   2606       [ILO_STATE_VIEW_FS]         = "VIEW_FS",
   2607       [ILO_STATE_VIEW_CS]         = "VIEW_CS",
   2608       [ILO_STATE_CBUF]            = "CBUF",
   2609       [ILO_STATE_RESOURCE]        = "RESOURCE",
   2610       [ILO_STATE_CS]              = "CS",
   2611       [ILO_STATE_CS_RESOURCE]     = "CS_RESOURCE",
   2612       [ILO_STATE_GLOBAL_BINDING]  = "GLOBAL_BINDING",
   2613    };
   2614    uint32_t dirty = vec->dirty;
   2615 
   2616    if (!dirty) {
   2617       ilo_printf("no state is dirty\n");
   2618       return;
   2619    }
   2620 
   2621    dirty &= (1U << ILO_STATE_COUNT) - 1;
   2622 
   2623    ilo_printf("%2d states are dirty:", util_bitcount(dirty));
   2624    while (dirty) {
   2625       const enum ilo_state state = u_bit_scan(&dirty);
   2626       ilo_printf(" %s", state_names[state]);
   2627    }
   2628    ilo_printf("\n");
   2629 }
   2630