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