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