• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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
ilo_translate_draw_mode(unsigned mode)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
ilo_translate_index_size(unsigned index_size)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
ilo_translate_mip_filter(unsigned 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
ilo_translate_img_filter(unsigned filter)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
ilo_translate_address_wrap(unsigned wrap)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
ilo_translate_max_anisotropy(unsigned max_anisotropy)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
ilo_translate_shadow_func(unsigned func)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
ilo_translate_front_ccw(unsigned front_ccw)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
ilo_translate_cull_face(unsigned cull_face)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
ilo_translate_poly_mode(unsigned poly_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
ilo_translate_half_pixel_center(bool half_pixel_center)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
ilo_translate_compare_func(unsigned func)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
ilo_translate_stencil_op(unsigned 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
ilo_translate_logicop(unsigned logicop)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
ilo_translate_blend_func(unsigned blend)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
ilo_translate_blend_factor(unsigned factor)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
finalize_shader_states(struct ilo_state_vector * vec)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
finalize_cbuf_state(struct ilo_context * ilo,struct ilo_cbuf_state * cbuf,const struct ilo_shader_state * sh)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
finalize_constant_buffers(struct ilo_context * ilo)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
finalize_index_buffer(struct ilo_context * ilo)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
finalize_vertex_elements(struct ilo_context * ilo)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
finalize_vertex_buffers(struct ilo_context * ilo)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
finalize_urb(struct ilo_context * ilo)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
finalize_viewport(struct ilo_context * ilo)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
can_enable_gb_test(const struct ilo_rasterizer_state * rasterizer,const struct ilo_viewport_state * viewport,const struct ilo_fb_state * fb)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
finalize_rasterizer(struct ilo_context * ilo)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
finalize_blend_rt(struct ilo_context * ilo)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
finalize_blend(struct ilo_context * ilo)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
ilo_finalize_3d_states(struct ilo_context * ilo,const struct pipe_draw_info * draw)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
finalize_global_binding(struct ilo_state_vector * vec)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
ilo_finalize_compute_states(struct ilo_context * ilo)842 ilo_finalize_compute_states(struct ilo_context *ilo)
843 {
844    finalize_global_binding(&ilo->state_vector);
845 }
846 
847 static void *
ilo_create_blend_state(struct pipe_context * pipe,const struct pipe_blend_state * state)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
ilo_bind_blend_state(struct pipe_context * pipe,void * state)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
ilo_delete_blend_state(struct pipe_context * pipe,void * state)940 ilo_delete_blend_state(struct pipe_context *pipe, void  *state)
941 {
942    FREE(state);
943 }
944 
945 static void *
ilo_create_sampler_state(struct pipe_context * pipe,const struct pipe_sampler_state * state)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
ilo_bind_sampler_states(struct pipe_context * pipe,enum pipe_shader_type shader,unsigned start,unsigned count,void ** samplers)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
ilo_delete_sampler_state(struct pipe_context * pipe,void * state)1105 ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
1106 {
1107    FREE(state);
1108 }
1109 
1110 static void *
ilo_create_rasterizer_state(struct pipe_context * pipe,const struct pipe_rasterizer_state * state)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
ilo_bind_rasterizer_state(struct pipe_context * pipe,void * state)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
ilo_delete_rasterizer_state(struct pipe_context * pipe,void * state)1209 ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
1210 {
1211    FREE(state);
1212 }
1213 
1214 static void *
ilo_create_depth_stencil_alpha_state(struct pipe_context * pipe,const struct pipe_depth_stencil_alpha_state * state)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
ilo_bind_depth_stencil_alpha_state(struct pipe_context * pipe,void * state)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
ilo_delete_depth_stencil_alpha_state(struct pipe_context * pipe,void * state)1286 ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
1287 {
1288    FREE(state);
1289 }
1290 
1291 static void *
ilo_create_fs_state(struct pipe_context * pipe,const struct pipe_shader_state * state)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
ilo_bind_fs_state(struct pipe_context * pipe,void * state)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
ilo_delete_fs_state(struct pipe_context * pipe,void * state)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 *
ilo_create_vs_state(struct pipe_context * pipe,const struct pipe_shader_state * state)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
ilo_bind_vs_state(struct pipe_context * pipe,void * state)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
ilo_delete_vs_state(struct pipe_context * pipe,void * state)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 *
ilo_create_gs_state(struct pipe_context * pipe,const struct pipe_shader_state * state)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
ilo_bind_gs_state(struct pipe_context * pipe,void * state)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
ilo_delete_gs_state(struct pipe_context * pipe,void * state)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 *
ilo_create_vertex_elements_state(struct pipe_context * pipe,unsigned num_elements,const struct pipe_vertex_element * elements)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
ilo_bind_vertex_elements_state(struct pipe_context * pipe,void * state)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
ilo_delete_vertex_elements_state(struct pipe_context * pipe,void * state)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
ilo_set_blend_color(struct pipe_context * pipe,const struct pipe_blend_color * state)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
ilo_set_stencil_ref(struct pipe_context * pipe,const struct pipe_stencil_ref * state)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
ilo_set_sample_mask(struct pipe_context * pipe,unsigned sample_mask)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
ilo_set_clip_state(struct pipe_context * pipe,const struct pipe_clip_state * state)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
ilo_set_constant_buffer(struct pipe_context * pipe,uint shader,uint index,const struct pipe_constant_buffer * buf)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
fb_set_blend_caps(const struct ilo_dev * dev,enum pipe_format format,struct ilo_fb_blend_caps * caps)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
ilo_set_framebuffer_state(struct pipe_context * pipe,const struct pipe_framebuffer_state * state)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
ilo_set_polygon_stipple(struct pipe_context * pipe,const struct pipe_poly_stipple * state)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
ilo_set_scissor_states(struct pipe_context * pipe,unsigned start_slot,unsigned num_scissors,const struct pipe_scissor_state * scissors)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
ilo_set_viewport_states(struct pipe_context * pipe,unsigned start_slot,unsigned num_viewports,const struct pipe_viewport_state * viewports)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
ilo_set_sampler_views(struct pipe_context * pipe,enum pipe_shader_type shader,unsigned start,unsigned count,struct pipe_sampler_view ** views)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
ilo_set_shader_images(struct pipe_context * pipe,enum pipe_shader_type shader,unsigned start,unsigned count,const struct pipe_image_view * views)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
ilo_set_vertex_buffers(struct pipe_context * pipe,unsigned start_slot,unsigned num_buffers,const struct pipe_vertex_buffer * buffers)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
ilo_set_index_buffer(struct pipe_context * pipe,const struct pipe_index_buffer * state)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 *
ilo_create_stream_output_target(struct pipe_context * pipe,struct pipe_resource * res,unsigned buffer_offset,unsigned buffer_size)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
ilo_set_stream_output_targets(struct pipe_context * pipe,unsigned num_targets,struct pipe_stream_output_target ** targets,const unsigned * offset)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
ilo_stream_output_target_destroy(struct pipe_context * pipe,struct pipe_stream_output_target * target)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 *
ilo_create_sampler_view(struct pipe_context * pipe,struct pipe_resource * res,const struct pipe_sampler_view * templ)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
ilo_sampler_view_destroy(struct pipe_context * pipe,struct pipe_sampler_view * view)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 *
ilo_create_surface(struct pipe_context * pipe,struct pipe_resource * res,const struct pipe_surface * templ)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
ilo_surface_destroy(struct pipe_context * pipe,struct pipe_surface * surface)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 *
ilo_create_compute_state(struct pipe_context * pipe,const struct pipe_compute_state * state)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
ilo_bind_compute_state(struct pipe_context * pipe,void * state)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
ilo_delete_compute_state(struct pipe_context * pipe,void * state)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
ilo_set_compute_resources(struct pipe_context * pipe,unsigned start,unsigned count,struct pipe_surface ** surfaces)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
ilo_set_global_binding(struct pipe_context * pipe,unsigned start,unsigned count,struct pipe_resource ** resources,uint32_t ** handles)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
ilo_init_state_functions(struct ilo_context * ilo)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
ilo_state_vector_init(const struct ilo_dev * dev,struct ilo_state_vector * vec)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
ilo_state_vector_cleanup(struct ilo_state_vector * vec)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
ilo_state_vector_resource_renamed(struct ilo_state_vector * vec,struct pipe_resource * res)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
ilo_state_vector_dump_dirty(const struct ilo_state_vector * vec)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