82fa6696e902ff232e0494f02100fa12704bcada
[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_format.h"
29 #include "core/ilo_state_3d.h"
30 #include "util/u_dynarray.h"
31 #include "util/u_helpers.h"
32 #include "util/u_resource.h"
33 #include "util/u_upload_mgr.h"
34
35 #include "ilo_context.h"
36 #include "ilo_resource.h"
37 #include "ilo_shader.h"
38 #include "ilo_state.h"
39
40 static enum gen_mip_filter
41 ilo_translate_mip_filter(unsigned filter)
42 {
43 switch (filter) {
44 case PIPE_TEX_MIPFILTER_NEAREST: return GEN6_MIPFILTER_NEAREST;
45 case PIPE_TEX_MIPFILTER_LINEAR: return GEN6_MIPFILTER_LINEAR;
46 case PIPE_TEX_MIPFILTER_NONE: return GEN6_MIPFILTER_NONE;
47 default:
48 assert(!"unknown mipfilter");
49 return GEN6_MIPFILTER_NONE;
50 }
51 }
52
53 static int
54 ilo_translate_img_filter(unsigned filter)
55 {
56 switch (filter) {
57 case PIPE_TEX_FILTER_NEAREST: return GEN6_MAPFILTER_NEAREST;
58 case PIPE_TEX_FILTER_LINEAR: return GEN6_MAPFILTER_LINEAR;
59 default:
60 assert(!"unknown sampler filter");
61 return GEN6_MAPFILTER_NEAREST;
62 }
63 }
64
65 static enum gen_texcoord_mode
66 ilo_translate_address_wrap(unsigned wrap)
67 {
68 switch (wrap) {
69 case PIPE_TEX_WRAP_CLAMP: return GEN8_TEXCOORDMODE_HALF_BORDER;
70 case PIPE_TEX_WRAP_REPEAT: return GEN6_TEXCOORDMODE_WRAP;
71 case PIPE_TEX_WRAP_CLAMP_TO_EDGE: return GEN6_TEXCOORDMODE_CLAMP;
72 case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return GEN6_TEXCOORDMODE_CLAMP_BORDER;
73 case PIPE_TEX_WRAP_MIRROR_REPEAT: return GEN6_TEXCOORDMODE_MIRROR;
74 case PIPE_TEX_WRAP_MIRROR_CLAMP:
75 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
76 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
77 default:
78 assert(!"unknown sampler wrap mode");
79 return GEN6_TEXCOORDMODE_WRAP;
80 }
81 }
82
83 static enum gen_aniso_ratio
84 ilo_translate_max_anisotropy(unsigned max_anisotropy)
85 {
86 switch (max_anisotropy) {
87 case 0: case 1: case 2: return GEN6_ANISORATIO_2;
88 case 3: case 4: return GEN6_ANISORATIO_4;
89 case 5: case 6: return GEN6_ANISORATIO_6;
90 case 7: case 8: return GEN6_ANISORATIO_8;
91 case 9: case 10: return GEN6_ANISORATIO_10;
92 case 11: case 12: return GEN6_ANISORATIO_12;
93 case 13: case 14: return GEN6_ANISORATIO_14;
94 default: return GEN6_ANISORATIO_16;
95 }
96 }
97
98 static enum gen_prefilter_op
99 ilo_translate_shadow_func(unsigned func)
100 {
101 /*
102 * For PIPE_FUNC_x, the reference value is on the left-hand side of the
103 * comparison, and 1.0 is returned when the comparison is true.
104 *
105 * For GEN6_PREFILTEROP_x, the reference value is on the right-hand side of
106 * the comparison, and 0.0 is returned when the comparison is true.
107 */
108 switch (func) {
109 case PIPE_FUNC_NEVER: return GEN6_PREFILTEROP_ALWAYS;
110 case PIPE_FUNC_LESS: return GEN6_PREFILTEROP_LEQUAL;
111 case PIPE_FUNC_EQUAL: return GEN6_PREFILTEROP_NOTEQUAL;
112 case PIPE_FUNC_LEQUAL: return GEN6_PREFILTEROP_LESS;
113 case PIPE_FUNC_GREATER: return GEN6_PREFILTEROP_GEQUAL;
114 case PIPE_FUNC_NOTEQUAL: return GEN6_PREFILTEROP_EQUAL;
115 case PIPE_FUNC_GEQUAL: return GEN6_PREFILTEROP_GREATER;
116 case PIPE_FUNC_ALWAYS: return GEN6_PREFILTEROP_NEVER;
117 default:
118 assert(!"unknown shadow compare function");
119 return GEN6_PREFILTEROP_NEVER;
120 }
121 }
122
123 static void
124 finalize_shader_states(struct ilo_state_vector *vec)
125 {
126 unsigned type;
127
128 for (type = 0; type < PIPE_SHADER_TYPES; type++) {
129 struct ilo_shader_state *shader;
130 uint32_t state;
131
132 switch (type) {
133 case PIPE_SHADER_VERTEX:
134 shader = vec->vs;
135 state = ILO_DIRTY_VS;
136 break;
137 case PIPE_SHADER_GEOMETRY:
138 shader = vec->gs;
139 state = ILO_DIRTY_GS;
140 break;
141 case PIPE_SHADER_FRAGMENT:
142 shader = vec->fs;
143 state = ILO_DIRTY_FS;
144 break;
145 default:
146 shader = NULL;
147 state = 0;
148 break;
149 }
150
151 if (!shader)
152 continue;
153
154 /* compile if the shader or the states it depends on changed */
155 if (vec->dirty & state) {
156 ilo_shader_select_kernel(shader, vec, ILO_DIRTY_ALL);
157 }
158 else if (ilo_shader_select_kernel(shader, vec, vec->dirty)) {
159 /* mark the state dirty if a new kernel is selected */
160 vec->dirty |= state;
161 }
162
163 /* need to setup SBE for FS */
164 if (type == PIPE_SHADER_FRAGMENT && vec->dirty &
165 (state | ILO_DIRTY_GS | ILO_DIRTY_VS | ILO_DIRTY_RASTERIZER)) {
166 if (ilo_shader_select_kernel_routing(shader,
167 (vec->gs) ? vec->gs : vec->vs, vec->rasterizer))
168 vec->dirty |= state;
169 }
170 }
171 }
172
173 static void
174 finalize_cbuf_state(struct ilo_context *ilo,
175 struct ilo_cbuf_state *cbuf,
176 const struct ilo_shader_state *sh)
177 {
178 uint32_t upload_mask = cbuf->enabled_mask;
179
180 /* skip CBUF0 if the kernel does not need it */
181 upload_mask &=
182 ~ilo_shader_get_kernel_param(sh, ILO_KERNEL_SKIP_CBUF0_UPLOAD);
183
184 while (upload_mask) {
185 unsigned offset, i;
186
187 i = u_bit_scan(&upload_mask);
188 /* no need to upload */
189 if (cbuf->cso[i].resource)
190 continue;
191
192 u_upload_data(ilo->uploader, 0, cbuf->cso[i].info.size,
193 cbuf->cso[i].user_buffer, &offset, &cbuf->cso[i].resource);
194
195 cbuf->cso[i].info.buf = ilo_buffer(cbuf->cso[i].resource);
196 cbuf->cso[i].info.offset = offset;
197
198 memset(&cbuf->cso[i].surface, 0, sizeof(cbuf->cso[i].surface));
199 ilo_state_surface_init_for_buffer(&cbuf->cso[i].surface,
200 ilo->dev, &cbuf->cso[i].info);
201 cbuf->cso[i].surface.bo = cbuf->cso[i].info.buf->bo;
202
203 ilo->state_vector.dirty |= ILO_DIRTY_CBUF;
204 }
205 }
206
207 static void
208 finalize_constant_buffers(struct ilo_context *ilo)
209 {
210 struct ilo_state_vector *vec = &ilo->state_vector;
211
212 if (vec->dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_VS))
213 finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_VERTEX], vec->vs);
214
215 if (ilo->state_vector.dirty & (ILO_DIRTY_CBUF | ILO_DIRTY_FS))
216 finalize_cbuf_state(ilo, &vec->cbuf[PIPE_SHADER_FRAGMENT], vec->fs);
217 }
218
219 static void
220 finalize_index_buffer(struct ilo_context *ilo)
221 {
222 struct ilo_state_vector *vec = &ilo->state_vector;
223 const bool need_upload = (vec->draw->indexed &&
224 (vec->ib.user_buffer || vec->ib.offset % vec->ib.index_size));
225 struct pipe_resource *current_hw_res = NULL;
226
227 if (!(vec->dirty & ILO_DIRTY_IB) && !need_upload)
228 return;
229
230 pipe_resource_reference(&current_hw_res, vec->ib.hw_resource);
231
232 if (need_upload) {
233 const unsigned offset = vec->ib.index_size * vec->draw->start;
234 const unsigned size = vec->ib.index_size * vec->draw->count;
235 unsigned hw_offset;
236
237 if (vec->ib.user_buffer) {
238 u_upload_data(ilo->uploader, 0, size,
239 vec->ib.user_buffer + offset, &hw_offset, &vec->ib.hw_resource);
240 }
241 else {
242 u_upload_buffer(ilo->uploader, 0, vec->ib.offset + offset, size,
243 vec->ib.buffer, &hw_offset, &vec->ib.hw_resource);
244 }
245
246 /* the HW offset should be aligned */
247 assert(hw_offset % vec->ib.index_size == 0);
248 vec->ib.draw_start_offset = hw_offset / vec->ib.index_size;
249
250 /*
251 * INDEX[vec->draw->start] in the original buffer is INDEX[0] in the HW
252 * resource
253 */
254 vec->ib.draw_start_offset -= vec->draw->start;
255 }
256 else {
257 pipe_resource_reference(&vec->ib.hw_resource, vec->ib.buffer);
258
259 /* note that index size may be zero when the draw is not indexed */
260 if (vec->draw->indexed)
261 vec->ib.draw_start_offset = vec->ib.offset / vec->ib.index_size;
262 else
263 vec->ib.draw_start_offset = 0;
264 }
265
266 /* treat the IB as clean if the HW states do not change */
267 if (vec->ib.hw_resource == current_hw_res &&
268 vec->ib.hw_index_size == vec->ib.index_size)
269 vec->dirty &= ~ILO_DIRTY_IB;
270 else
271 vec->ib.hw_index_size = vec->ib.index_size;
272
273 pipe_resource_reference(&current_hw_res, NULL);
274 }
275
276 static void
277 finalize_vertex_elements(struct ilo_context *ilo)
278 {
279 struct ilo_state_vector *vec = &ilo->state_vector;
280
281 if (!(vec->dirty & (ILO_DIRTY_VE | ILO_DIRTY_VS)))
282 return;
283
284 vec->dirty |= ILO_DIRTY_VE;
285
286 vec->ve->last_cso_edgeflag = false;
287 if (vec->ve->count && vec->vs &&
288 ilo_shader_get_kernel_param(vec->vs, ILO_KERNEL_VS_INPUT_EDGEFLAG)) {
289 vec->ve->edgeflag_cso = vec->ve->cso[vec->ve->count - 1];
290 ilo_gpe_set_ve_edgeflag(ilo->dev, &vec->ve->edgeflag_cso);
291 vec->ve->last_cso_edgeflag = true;
292 }
293
294 vec->ve->prepend_nosrc_cso = false;
295 if (vec->vs &&
296 (ilo_shader_get_kernel_param(vec->vs,
297 ILO_KERNEL_VS_INPUT_INSTANCEID) ||
298 ilo_shader_get_kernel_param(vec->vs,
299 ILO_KERNEL_VS_INPUT_VERTEXID))) {
300 ilo_gpe_init_ve_nosrc(ilo->dev,
301 GEN6_VFCOMP_STORE_VID,
302 GEN6_VFCOMP_STORE_IID,
303 GEN6_VFCOMP_NOSTORE,
304 GEN6_VFCOMP_NOSTORE,
305 &vec->ve->nosrc_cso);
306 vec->ve->prepend_nosrc_cso = true;
307 } else if (!vec->vs) {
308 /* generate VUE header */
309 ilo_gpe_init_ve_nosrc(ilo->dev,
310 GEN6_VFCOMP_STORE_0, /* Reserved */
311 GEN6_VFCOMP_STORE_0, /* Render Target Array Index */
312 GEN6_VFCOMP_STORE_0, /* Viewport Index */
313 GEN6_VFCOMP_STORE_0, /* Point Width */
314 &vec->ve->nosrc_cso);
315 vec->ve->prepend_nosrc_cso = true;
316 } else if (!vec->ve->count) {
317 /*
318 * From the Sandy Bridge PRM, volume 2 part 1, page 92:
319 *
320 * "SW must ensure that at least one vertex element is defined prior
321 * to issuing a 3DPRIMTIVE command, or operation is UNDEFINED."
322 */
323 ilo_gpe_init_ve_nosrc(ilo->dev,
324 GEN6_VFCOMP_STORE_0,
325 GEN6_VFCOMP_STORE_0,
326 GEN6_VFCOMP_STORE_0,
327 GEN6_VFCOMP_STORE_1_FP,
328 &vec->ve->nosrc_cso);
329 vec->ve->prepend_nosrc_cso = true;
330 }
331 }
332
333 /**
334 * Finalize states. Some states depend on other states and are
335 * incomplete/invalid until finalized.
336 */
337 void
338 ilo_finalize_3d_states(struct ilo_context *ilo,
339 const struct pipe_draw_info *draw)
340 {
341 ilo->state_vector.draw = draw;
342
343 finalize_shader_states(&ilo->state_vector);
344 finalize_constant_buffers(ilo);
345 finalize_index_buffer(ilo);
346 finalize_vertex_elements(ilo);
347
348 u_upload_unmap(ilo->uploader);
349 }
350
351 static void
352 finalize_global_binding(struct ilo_state_vector *vec)
353 {
354 struct ilo_shader_state *cs = vec->cs;
355 int base, count, shift;
356 int i;
357
358 count = ilo_shader_get_kernel_param(cs,
359 ILO_KERNEL_CS_SURFACE_GLOBAL_COUNT);
360 if (!count)
361 return;
362
363 base = ilo_shader_get_kernel_param(cs, ILO_KERNEL_CS_SURFACE_GLOBAL_BASE);
364 shift = 32 - util_last_bit(base + count - 1);
365
366 if (count > vec->global_binding.count)
367 count = vec->global_binding.count;
368
369 for (i = 0; i < count; i++) {
370 struct ilo_global_binding_cso *cso =
371 util_dynarray_element(&vec->global_binding.bindings,
372 struct ilo_global_binding_cso, i);
373 const uint32_t offset = *cso->handle & ((1 << shift) - 1);
374
375 *cso->handle = ((base + i) << shift) | offset;
376 }
377 }
378
379 void
380 ilo_finalize_compute_states(struct ilo_context *ilo)
381 {
382 finalize_global_binding(&ilo->state_vector);
383 }
384
385 static void *
386 ilo_create_blend_state(struct pipe_context *pipe,
387 const struct pipe_blend_state *state)
388 {
389 const struct ilo_dev *dev = ilo_context(pipe)->dev;
390 struct ilo_blend_state *blend;
391
392 blend = MALLOC_STRUCT(ilo_blend_state);
393 assert(blend);
394
395 ilo_gpe_init_blend(dev, state, blend);
396
397 return blend;
398 }
399
400 static void
401 ilo_bind_blend_state(struct pipe_context *pipe, void *state)
402 {
403 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
404
405 vec->blend = state;
406
407 vec->dirty |= ILO_DIRTY_BLEND;
408 }
409
410 static void
411 ilo_delete_blend_state(struct pipe_context *pipe, void *state)
412 {
413 FREE(state);
414 }
415
416 static void *
417 ilo_create_sampler_state(struct pipe_context *pipe,
418 const struct pipe_sampler_state *state)
419 {
420 const struct ilo_dev *dev = ilo_context(pipe)->dev;
421 struct ilo_sampler_cso *sampler;
422 struct ilo_state_sampler_info info;
423 struct ilo_state_sampler_border_info border;
424
425 sampler = CALLOC_STRUCT(ilo_sampler_cso);
426 assert(sampler);
427
428 memset(&info, 0, sizeof(info));
429
430 info.non_normalized = !state->normalized_coords;
431 if (state->normalized_coords) {
432 info.lod_bias = state->lod_bias;
433 info.min_lod = state->min_lod;
434 info.max_lod = state->max_lod;
435
436 info.mip_filter = ilo_translate_mip_filter(state->min_mip_filter);
437 } else {
438 /* work around a bug in util_blitter */
439 info.mip_filter = GEN6_MIPFILTER_NONE;
440 }
441
442 if (state->max_anisotropy) {
443 info.min_filter = GEN6_MAPFILTER_ANISOTROPIC;
444 info.mag_filter = GEN6_MAPFILTER_ANISOTROPIC;
445 } else {
446 info.min_filter = ilo_translate_img_filter(state->min_img_filter);
447 info.mag_filter = ilo_translate_img_filter(state->mag_img_filter);
448 }
449
450 info.max_anisotropy = ilo_translate_max_anisotropy(state->max_anisotropy);
451
452 /* use LOD 0 when no mipmapping (see sampler_set_gen6_SAMPLER_STATE()) */
453 if (info.mip_filter == GEN6_MIPFILTER_NONE && info.min_lod > 0.0f) {
454 info.min_lod = 0.0f;
455 info.mag_filter = info.min_filter;
456 }
457
458 if (state->seamless_cube_map) {
459 if (state->min_img_filter == PIPE_TEX_FILTER_NEAREST ||
460 state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) {
461 info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
462 info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
463 info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
464 } else {
465 info.tcx_ctrl = GEN6_TEXCOORDMODE_CUBE;
466 info.tcy_ctrl = GEN6_TEXCOORDMODE_CUBE;
467 info.tcz_ctrl = GEN6_TEXCOORDMODE_CUBE;
468 }
469 } else {
470 info.tcx_ctrl = ilo_translate_address_wrap(state->wrap_s);
471 info.tcy_ctrl = ilo_translate_address_wrap(state->wrap_t);
472 info.tcz_ctrl = ilo_translate_address_wrap(state->wrap_r);
473
474 if (ilo_dev_gen(dev) < ILO_GEN(8)) {
475 /*
476 * For nearest filtering, PIPE_TEX_WRAP_CLAMP means
477 * PIPE_TEX_WRAP_CLAMP_TO_EDGE; for linear filtering,
478 * PIPE_TEX_WRAP_CLAMP means PIPE_TEX_WRAP_CLAMP_TO_BORDER while
479 * additionally clamping the texture coordinates to [0.0, 1.0].
480 *
481 * PIPE_TEX_WRAP_CLAMP is not supported natively until Gen8. The
482 * clamping has to be taken care of in the shaders. There are two
483 * filters here, but let the minification one has a say.
484 */
485 const bool clamp_is_to_edge =
486 (state->min_img_filter == PIPE_TEX_FILTER_NEAREST);
487
488 if (clamp_is_to_edge) {
489 if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
490 info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP;
491 if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
492 info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP;
493 if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER)
494 info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP;
495 } else {
496 if (info.tcx_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
497 info.tcx_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
498 sampler->saturate_s = true;
499 }
500 if (info.tcy_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
501 info.tcy_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
502 sampler->saturate_t = true;
503 }
504 if (info.tcz_ctrl == GEN8_TEXCOORDMODE_HALF_BORDER) {
505 info.tcz_ctrl = GEN6_TEXCOORDMODE_CLAMP_BORDER;
506 sampler->saturate_r = true;
507 }
508 }
509 }
510 }
511
512 if (state->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE)
513 info.shadow_func = ilo_translate_shadow_func(state->compare_func);
514
515 ilo_state_sampler_init(&sampler->sampler, dev, &info);
516
517 memset(&border, 0, sizeof(border));
518 memcpy(border.rgba.f, state->border_color.f, sizeof(border.rgba.f));
519
520 ilo_state_sampler_border_init(&sampler->border, dev, &border);
521
522 return sampler;
523 }
524
525 static void
526 ilo_bind_sampler_states(struct pipe_context *pipe, unsigned shader,
527 unsigned start, unsigned count, void **samplers)
528 {
529 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
530 struct ilo_sampler_state *dst = &vec->sampler[shader];
531 bool changed = false;
532 unsigned i;
533
534 assert(start + count <= Elements(dst->cso));
535
536 if (samplers) {
537 for (i = 0; i < count; i++) {
538 if (dst->cso[start + i] != samplers[i]) {
539 dst->cso[start + i] = samplers[i];
540
541 /*
542 * This function is sometimes called to reduce the number of bound
543 * samplers. Do not consider that as a state change (and create a
544 * new array of SAMPLER_STATE).
545 */
546 if (samplers[i])
547 changed = true;
548 }
549 }
550 }
551 else {
552 for (i = 0; i < count; i++)
553 dst->cso[start + i] = NULL;
554 }
555
556 if (changed) {
557 switch (shader) {
558 case PIPE_SHADER_VERTEX:
559 vec->dirty |= ILO_DIRTY_SAMPLER_VS;
560 break;
561 case PIPE_SHADER_GEOMETRY:
562 vec->dirty |= ILO_DIRTY_SAMPLER_GS;
563 break;
564 case PIPE_SHADER_FRAGMENT:
565 vec->dirty |= ILO_DIRTY_SAMPLER_FS;
566 break;
567 case PIPE_SHADER_COMPUTE:
568 vec->dirty |= ILO_DIRTY_SAMPLER_CS;
569 break;
570 }
571 }
572 }
573
574 static void
575 ilo_delete_sampler_state(struct pipe_context *pipe, void *state)
576 {
577 FREE(state);
578 }
579
580 static void *
581 ilo_create_rasterizer_state(struct pipe_context *pipe,
582 const struct pipe_rasterizer_state *state)
583 {
584 const struct ilo_dev *dev = ilo_context(pipe)->dev;
585 struct ilo_rasterizer_state *rast;
586
587 rast = MALLOC_STRUCT(ilo_rasterizer_state);
588 assert(rast);
589
590 rast->state = *state;
591 ilo_gpe_init_rasterizer(dev, state, rast);
592
593 return rast;
594 }
595
596 static void
597 ilo_bind_rasterizer_state(struct pipe_context *pipe, void *state)
598 {
599 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
600
601 vec->rasterizer = state;
602
603 vec->dirty |= ILO_DIRTY_RASTERIZER;
604 }
605
606 static void
607 ilo_delete_rasterizer_state(struct pipe_context *pipe, void *state)
608 {
609 FREE(state);
610 }
611
612 static void *
613 ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe,
614 const struct pipe_depth_stencil_alpha_state *state)
615 {
616 const struct ilo_dev *dev = ilo_context(pipe)->dev;
617 struct ilo_dsa_state *dsa;
618
619 dsa = MALLOC_STRUCT(ilo_dsa_state);
620 assert(dsa);
621
622 ilo_gpe_init_dsa(dev, state, dsa);
623
624 return dsa;
625 }
626
627 static void
628 ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
629 {
630 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
631
632 vec->dsa = state;
633
634 vec->dirty |= ILO_DIRTY_DSA;
635 }
636
637 static void
638 ilo_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *state)
639 {
640 FREE(state);
641 }
642
643 static void *
644 ilo_create_fs_state(struct pipe_context *pipe,
645 const struct pipe_shader_state *state)
646 {
647 struct ilo_context *ilo = ilo_context(pipe);
648 struct ilo_shader_state *shader;
649
650 shader = ilo_shader_create_fs(ilo->dev, state, &ilo->state_vector);
651 assert(shader);
652
653 ilo_shader_cache_add(ilo->shader_cache, shader);
654
655 return shader;
656 }
657
658 static void
659 ilo_bind_fs_state(struct pipe_context *pipe, void *state)
660 {
661 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
662
663 vec->fs = state;
664
665 vec->dirty |= ILO_DIRTY_FS;
666 }
667
668 static void
669 ilo_delete_fs_state(struct pipe_context *pipe, void *state)
670 {
671 struct ilo_context *ilo = ilo_context(pipe);
672 struct ilo_shader_state *fs = (struct ilo_shader_state *) state;
673
674 ilo_shader_cache_remove(ilo->shader_cache, fs);
675 ilo_shader_destroy(fs);
676 }
677
678 static void *
679 ilo_create_vs_state(struct pipe_context *pipe,
680 const struct pipe_shader_state *state)
681 {
682 struct ilo_context *ilo = ilo_context(pipe);
683 struct ilo_shader_state *shader;
684
685 shader = ilo_shader_create_vs(ilo->dev, state, &ilo->state_vector);
686 assert(shader);
687
688 ilo_shader_cache_add(ilo->shader_cache, shader);
689
690 return shader;
691 }
692
693 static void
694 ilo_bind_vs_state(struct pipe_context *pipe, void *state)
695 {
696 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
697
698 vec->vs = state;
699
700 vec->dirty |= ILO_DIRTY_VS;
701 }
702
703 static void
704 ilo_delete_vs_state(struct pipe_context *pipe, void *state)
705 {
706 struct ilo_context *ilo = ilo_context(pipe);
707 struct ilo_shader_state *vs = (struct ilo_shader_state *) state;
708
709 ilo_shader_cache_remove(ilo->shader_cache, vs);
710 ilo_shader_destroy(vs);
711 }
712
713 static void *
714 ilo_create_gs_state(struct pipe_context *pipe,
715 const struct pipe_shader_state *state)
716 {
717 struct ilo_context *ilo = ilo_context(pipe);
718 struct ilo_shader_state *shader;
719
720 shader = ilo_shader_create_gs(ilo->dev, state, &ilo->state_vector);
721 assert(shader);
722
723 ilo_shader_cache_add(ilo->shader_cache, shader);
724
725 return shader;
726 }
727
728 static void
729 ilo_bind_gs_state(struct pipe_context *pipe, void *state)
730 {
731 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
732
733 /* util_blitter may set this unnecessarily */
734 if (vec->gs == state)
735 return;
736
737 vec->gs = state;
738
739 vec->dirty |= ILO_DIRTY_GS;
740 }
741
742 static void
743 ilo_delete_gs_state(struct pipe_context *pipe, void *state)
744 {
745 struct ilo_context *ilo = ilo_context(pipe);
746 struct ilo_shader_state *gs = (struct ilo_shader_state *) state;
747
748 ilo_shader_cache_remove(ilo->shader_cache, gs);
749 ilo_shader_destroy(gs);
750 }
751
752 static void *
753 ilo_create_vertex_elements_state(struct pipe_context *pipe,
754 unsigned num_elements,
755 const struct pipe_vertex_element *elements)
756 {
757 const struct ilo_dev *dev = ilo_context(pipe)->dev;
758 struct ilo_ve_state *ve;
759
760 ve = MALLOC_STRUCT(ilo_ve_state);
761 assert(ve);
762
763 ilo_gpe_init_ve(dev, num_elements, elements, ve);
764
765 return ve;
766 }
767
768 static void
769 ilo_bind_vertex_elements_state(struct pipe_context *pipe, void *state)
770 {
771 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
772
773 vec->ve = state;
774
775 vec->dirty |= ILO_DIRTY_VE;
776 }
777
778 static void
779 ilo_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
780 {
781 struct ilo_ve_state *ve = state;
782
783 FREE(ve);
784 }
785
786 static void
787 ilo_set_blend_color(struct pipe_context *pipe,
788 const struct pipe_blend_color *state)
789 {
790 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
791
792 vec->blend_color = *state;
793
794 vec->dirty |= ILO_DIRTY_BLEND_COLOR;
795 }
796
797 static void
798 ilo_set_stencil_ref(struct pipe_context *pipe,
799 const struct pipe_stencil_ref *state)
800 {
801 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
802
803 /* util_blitter may set this unnecessarily */
804 if (!memcmp(&vec->stencil_ref, state, sizeof(*state)))
805 return;
806
807 vec->stencil_ref = *state;
808
809 vec->dirty |= ILO_DIRTY_STENCIL_REF;
810 }
811
812 static void
813 ilo_set_sample_mask(struct pipe_context *pipe,
814 unsigned sample_mask)
815 {
816 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
817
818 /* util_blitter may set this unnecessarily */
819 if (vec->sample_mask == sample_mask)
820 return;
821
822 vec->sample_mask = sample_mask;
823
824 vec->dirty |= ILO_DIRTY_SAMPLE_MASK;
825 }
826
827 static void
828 ilo_set_clip_state(struct pipe_context *pipe,
829 const struct pipe_clip_state *state)
830 {
831 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
832
833 vec->clip = *state;
834
835 vec->dirty |= ILO_DIRTY_CLIP;
836 }
837
838 static void
839 ilo_set_constant_buffer(struct pipe_context *pipe,
840 uint shader, uint index,
841 struct pipe_constant_buffer *buf)
842 {
843 const struct ilo_dev *dev = ilo_context(pipe)->dev;
844 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
845 struct ilo_cbuf_state *cbuf = &vec->cbuf[shader];
846 const unsigned count = 1;
847 unsigned i;
848
849 assert(shader < Elements(vec->cbuf));
850 assert(index + count <= Elements(vec->cbuf[shader].cso));
851
852 if (buf) {
853 for (i = 0; i < count; i++) {
854 struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
855
856 pipe_resource_reference(&cso->resource, buf[i].buffer);
857
858 cso->info.access = ILO_STATE_SURFACE_ACCESS_DP_DATA;
859 cso->info.format = GEN6_FORMAT_R32G32B32A32_FLOAT;
860 cso->info.format_size = 16;
861 cso->info.struct_size = 16;
862 cso->info.readonly = true;
863 cso->info.size = buf[i].buffer_size;
864
865 if (buf[i].buffer) {
866 cso->info.buf = ilo_buffer(buf[i].buffer);
867 cso->info.offset = buf[i].buffer_offset;
868
869 memset(&cso->surface, 0, sizeof(cso->surface));
870 ilo_state_surface_init_for_buffer(&cso->surface, dev, &cso->info);
871 cso->surface.bo = cso->info.buf->bo;
872
873 cso->user_buffer = NULL;
874
875 cbuf->enabled_mask |= 1 << (index + i);
876 } else if (buf[i].user_buffer) {
877 cso->info.buf = NULL;
878 /* buffer_offset does not apply for user buffer */
879 cso->user_buffer = buf[i].user_buffer;
880
881 cbuf->enabled_mask |= 1 << (index + i);
882 } else {
883 cso->info.buf = NULL;
884 cso->info.size = 0;
885 cso->user_buffer = NULL;
886
887 cbuf->enabled_mask &= ~(1 << (index + i));
888 }
889 }
890 } else {
891 for (i = 0; i < count; i++) {
892 struct ilo_cbuf_cso *cso = &cbuf->cso[index + i];
893
894 pipe_resource_reference(&cso->resource, NULL);
895
896 cso->info.buf = NULL;
897 cso->info.size = 0;
898 cso->user_buffer = NULL;
899
900 cbuf->enabled_mask &= ~(1 << (index + i));
901 }
902 }
903
904 vec->dirty |= ILO_DIRTY_CBUF;
905 }
906
907 static void
908 ilo_set_framebuffer_state(struct pipe_context *pipe,
909 const struct pipe_framebuffer_state *state)
910 {
911 const struct ilo_dev *dev = ilo_context(pipe)->dev;
912 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
913
914 ilo_gpe_set_fb(dev, state, &vec->fb);
915
916 vec->dirty |= ILO_DIRTY_FB;
917 }
918
919 static void
920 ilo_set_polygon_stipple(struct pipe_context *pipe,
921 const struct pipe_poly_stipple *state)
922 {
923 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
924
925 vec->poly_stipple = *state;
926
927 vec->dirty |= ILO_DIRTY_POLY_STIPPLE;
928 }
929
930 static void
931 ilo_set_scissor_states(struct pipe_context *pipe,
932 unsigned start_slot,
933 unsigned num_scissors,
934 const struct pipe_scissor_state *scissors)
935 {
936 const struct ilo_dev *dev = ilo_context(pipe)->dev;
937 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
938
939 ilo_gpe_set_scissor(dev, start_slot, num_scissors,
940 scissors, &vec->scissor);
941
942 vec->dirty |= ILO_DIRTY_SCISSOR;
943 }
944
945 static void
946 ilo_set_viewport_states(struct pipe_context *pipe,
947 unsigned start_slot,
948 unsigned num_viewports,
949 const struct pipe_viewport_state *viewports)
950 {
951 const struct ilo_dev *dev = ilo_context(pipe)->dev;
952 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
953
954 if (viewports) {
955 unsigned i;
956
957 for (i = 0; i < num_viewports; i++) {
958 ilo_gpe_set_viewport_cso(dev, &viewports[i],
959 &vec->viewport.cso[start_slot + i]);
960 }
961
962 if (vec->viewport.count < start_slot + num_viewports)
963 vec->viewport.count = start_slot + num_viewports;
964
965 /* need to save viewport 0 for util_blitter */
966 if (!start_slot && num_viewports)
967 vec->viewport.viewport0 = viewports[0];
968 }
969 else {
970 if (vec->viewport.count <= start_slot + num_viewports &&
971 vec->viewport.count > start_slot)
972 vec->viewport.count = start_slot;
973 }
974
975 vec->dirty |= ILO_DIRTY_VIEWPORT;
976 }
977
978 static void
979 ilo_set_sampler_views(struct pipe_context *pipe, unsigned shader,
980 unsigned start, unsigned count,
981 struct pipe_sampler_view **views)
982 {
983 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
984 struct ilo_view_state *dst = &vec->view[shader];
985 unsigned i;
986
987 assert(start + count <= Elements(dst->states));
988
989 if (views) {
990 for (i = 0; i < count; i++)
991 pipe_sampler_view_reference(&dst->states[start + i], views[i]);
992 }
993 else {
994 for (i = 0; i < count; i++)
995 pipe_sampler_view_reference(&dst->states[start + i], NULL);
996 }
997
998 if (dst->count <= start + count) {
999 if (views)
1000 count += start;
1001 else
1002 count = start;
1003
1004 while (count > 0 && !dst->states[count - 1])
1005 count--;
1006
1007 dst->count = count;
1008 }
1009
1010 switch (shader) {
1011 case PIPE_SHADER_VERTEX:
1012 vec->dirty |= ILO_DIRTY_VIEW_VS;
1013 break;
1014 case PIPE_SHADER_GEOMETRY:
1015 vec->dirty |= ILO_DIRTY_VIEW_GS;
1016 break;
1017 case PIPE_SHADER_FRAGMENT:
1018 vec->dirty |= ILO_DIRTY_VIEW_FS;
1019 break;
1020 case PIPE_SHADER_COMPUTE:
1021 vec->dirty |= ILO_DIRTY_VIEW_CS;
1022 break;
1023 }
1024 }
1025
1026 static void
1027 ilo_set_shader_resources(struct pipe_context *pipe,
1028 unsigned start, unsigned count,
1029 struct pipe_surface **surfaces)
1030 {
1031 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1032 struct ilo_resource_state *dst = &vec->resource;
1033 unsigned i;
1034
1035 assert(start + count <= Elements(dst->states));
1036
1037 if (surfaces) {
1038 for (i = 0; i < count; i++)
1039 pipe_surface_reference(&dst->states[start + i], surfaces[i]);
1040 }
1041 else {
1042 for (i = 0; i < count; i++)
1043 pipe_surface_reference(&dst->states[start + i], NULL);
1044 }
1045
1046 if (dst->count <= start + count) {
1047 if (surfaces)
1048 count += start;
1049 else
1050 count = start;
1051
1052 while (count > 0 && !dst->states[count - 1])
1053 count--;
1054
1055 dst->count = count;
1056 }
1057
1058 vec->dirty |= ILO_DIRTY_RESOURCE;
1059 }
1060
1061 static void
1062 ilo_set_vertex_buffers(struct pipe_context *pipe,
1063 unsigned start_slot, unsigned num_buffers,
1064 const struct pipe_vertex_buffer *buffers)
1065 {
1066 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1067 unsigned i;
1068
1069 /* no PIPE_CAP_USER_VERTEX_BUFFERS */
1070 if (buffers) {
1071 for (i = 0; i < num_buffers; i++)
1072 assert(!buffers[i].user_buffer);
1073 }
1074
1075 util_set_vertex_buffers_mask(vec->vb.states,
1076 &vec->vb.enabled_mask, buffers, start_slot, num_buffers);
1077
1078 vec->dirty |= ILO_DIRTY_VB;
1079 }
1080
1081 static void
1082 ilo_set_index_buffer(struct pipe_context *pipe,
1083 const struct pipe_index_buffer *state)
1084 {
1085 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1086
1087 if (state) {
1088 pipe_resource_reference(&vec->ib.buffer, state->buffer);
1089 vec->ib.user_buffer = state->user_buffer;
1090 vec->ib.offset = state->offset;
1091 vec->ib.index_size = state->index_size;
1092 }
1093 else {
1094 pipe_resource_reference(&vec->ib.buffer, NULL);
1095 vec->ib.user_buffer = NULL;
1096 vec->ib.offset = 0;
1097 vec->ib.index_size = 0;
1098 }
1099
1100 vec->dirty |= ILO_DIRTY_IB;
1101 }
1102
1103 static struct pipe_stream_output_target *
1104 ilo_create_stream_output_target(struct pipe_context *pipe,
1105 struct pipe_resource *res,
1106 unsigned buffer_offset,
1107 unsigned buffer_size)
1108 {
1109 struct pipe_stream_output_target *target;
1110
1111 target = MALLOC_STRUCT(pipe_stream_output_target);
1112 assert(target);
1113
1114 pipe_reference_init(&target->reference, 1);
1115 target->buffer = NULL;
1116 pipe_resource_reference(&target->buffer, res);
1117 target->context = pipe;
1118 target->buffer_offset = buffer_offset;
1119 target->buffer_size = buffer_size;
1120
1121 return target;
1122 }
1123
1124 static void
1125 ilo_set_stream_output_targets(struct pipe_context *pipe,
1126 unsigned num_targets,
1127 struct pipe_stream_output_target **targets,
1128 const unsigned *offset)
1129 {
1130 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1131 unsigned i;
1132 unsigned append_bitmask = 0;
1133
1134 if (!targets)
1135 num_targets = 0;
1136
1137 /* util_blitter may set this unnecessarily */
1138 if (!vec->so.count && !num_targets)
1139 return;
1140
1141 for (i = 0; i < num_targets; i++) {
1142 pipe_so_target_reference(&vec->so.states[i], targets[i]);
1143 if (offset[i] == (unsigned)-1)
1144 append_bitmask |= 1 << i;
1145 }
1146
1147 for (; i < vec->so.count; i++)
1148 pipe_so_target_reference(&vec->so.states[i], NULL);
1149
1150 vec->so.count = num_targets;
1151 vec->so.append_bitmask = append_bitmask;
1152
1153 vec->so.enabled = (vec->so.count > 0);
1154
1155 vec->dirty |= ILO_DIRTY_SO;
1156 }
1157
1158 static void
1159 ilo_stream_output_target_destroy(struct pipe_context *pipe,
1160 struct pipe_stream_output_target *target)
1161 {
1162 pipe_resource_reference(&target->buffer, NULL);
1163 FREE(target);
1164 }
1165
1166 static struct pipe_sampler_view *
1167 ilo_create_sampler_view(struct pipe_context *pipe,
1168 struct pipe_resource *res,
1169 const struct pipe_sampler_view *templ)
1170 {
1171 const struct ilo_dev *dev = ilo_context(pipe)->dev;
1172 struct ilo_view_cso *view;
1173
1174 view = CALLOC_STRUCT(ilo_view_cso);
1175 assert(view);
1176
1177 view->base = *templ;
1178 pipe_reference_init(&view->base.reference, 1);
1179 view->base.texture = NULL;
1180 pipe_resource_reference(&view->base.texture, res);
1181 view->base.context = pipe;
1182
1183 if (res->target == PIPE_BUFFER) {
1184 struct ilo_state_surface_buffer_info info;
1185
1186 memset(&info, 0, sizeof(info));
1187 info.buf = ilo_buffer(res);
1188 info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
1189 info.format = ilo_format_translate_color(dev, templ->format);
1190 info.format_size = util_format_get_blocksize(templ->format);
1191 info.struct_size = info.format_size;
1192 info.readonly = true;
1193 info.offset = templ->u.buf.first_element * info.struct_size;
1194 info.size = (templ->u.buf.last_element -
1195 templ->u.buf.first_element + 1) * info.struct_size;
1196
1197 ilo_state_surface_init_for_buffer(&view->surface, dev, &info);
1198 view->surface.bo = info.buf->bo;
1199 } else {
1200 struct ilo_texture *tex = ilo_texture(res);
1201 struct ilo_state_surface_image_info info;
1202
1203 /* warn about degraded performance because of a missing binding flag */
1204 if (tex->image.tiling == GEN6_TILING_NONE &&
1205 !(tex->base.bind & PIPE_BIND_SAMPLER_VIEW)) {
1206 ilo_warn("creating sampler view for a resource "
1207 "not created for sampling\n");
1208 }
1209
1210 memset(&info, 0, sizeof(info));
1211 info.img = &tex->image;
1212
1213 info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
1214
1215 if (templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
1216 tex->image.separate_stencil) {
1217 info.format = ilo_format_translate_texture(dev,
1218 PIPE_FORMAT_Z32_FLOAT);
1219 } else {
1220 info.format = ilo_format_translate_texture(dev, templ->format);
1221 }
1222
1223 info.is_cube_map = (tex->image.target == PIPE_TEXTURE_CUBE ||
1224 tex->image.target == PIPE_TEXTURE_CUBE_ARRAY);
1225 info.is_array = util_resource_is_array_texture(&tex->base);
1226 info.readonly = true;
1227
1228 info.level_base = templ->u.tex.first_level;
1229 info.level_count = templ->u.tex.last_level -
1230 templ->u.tex.first_level + 1;
1231 info.slice_base = templ->u.tex.first_layer;
1232 info.slice_count = templ->u.tex.last_layer -
1233 templ->u.tex.first_layer + 1;
1234
1235 ilo_state_surface_init_for_image(&view->surface, dev, &info);
1236 view->surface.bo = info.img->bo;
1237 }
1238
1239 return &view->base;
1240 }
1241
1242 static void
1243 ilo_sampler_view_destroy(struct pipe_context *pipe,
1244 struct pipe_sampler_view *view)
1245 {
1246 pipe_resource_reference(&view->texture, NULL);
1247 FREE(view);
1248 }
1249
1250 static struct pipe_surface *
1251 ilo_create_surface(struct pipe_context *pipe,
1252 struct pipe_resource *res,
1253 const struct pipe_surface *templ)
1254 {
1255 const struct ilo_dev *dev = ilo_context(pipe)->dev;
1256 struct ilo_texture *tex = ilo_texture(res);
1257 struct ilo_surface_cso *surf;
1258
1259 surf = CALLOC_STRUCT(ilo_surface_cso);
1260 assert(surf);
1261
1262 surf->base = *templ;
1263 pipe_reference_init(&surf->base.reference, 1);
1264 surf->base.texture = NULL;
1265 pipe_resource_reference(&surf->base.texture, &tex->base);
1266
1267 surf->base.context = pipe;
1268 surf->base.width = u_minify(tex->base.width0, templ->u.tex.level);
1269 surf->base.height = u_minify(tex->base.height0, templ->u.tex.level);
1270
1271 surf->is_rt = !util_format_is_depth_or_stencil(templ->format);
1272
1273 if (surf->is_rt) {
1274 struct ilo_state_surface_image_info info;
1275
1276 /* relax this? */
1277 assert(tex->base.target != PIPE_BUFFER);
1278
1279 memset(&info, 0, sizeof(info));
1280 info.img = &tex->image;
1281 info.access = ILO_STATE_SURFACE_ACCESS_DP_RENDER;
1282 info.format = ilo_format_translate_render(dev, templ->format);
1283 info.is_array = util_resource_is_array_texture(&tex->base);
1284 info.level_base = templ->u.tex.level;
1285 info.level_count = 1;
1286 info.slice_base = templ->u.tex.first_layer;
1287 info.slice_count = templ->u.tex.last_layer -
1288 templ->u.tex.first_layer + 1;
1289
1290 ilo_state_surface_init_for_image(&surf->u.rt, dev, &info);
1291 surf->u.rt.bo = info.img->bo;
1292 } else {
1293 struct ilo_state_zs_info info;
1294
1295 assert(res->target != PIPE_BUFFER);
1296
1297 memset(&info, 0, sizeof(info));
1298
1299 if (templ->format == PIPE_FORMAT_S8_UINT) {
1300 info.s_img = &tex->image;
1301 } else {
1302 info.z_img = &tex->image;
1303 info.s_img = (tex->separate_s8) ? &tex->separate_s8->image : NULL;
1304
1305 info.hiz_enable =
1306 ilo_image_can_enable_aux(&tex->image, templ->u.tex.level);
1307 }
1308
1309 info.level = templ->u.tex.level;
1310 info.slice_base = templ->u.tex.first_layer;
1311 info.slice_count = templ->u.tex.last_layer -
1312 templ->u.tex.first_layer + 1;
1313
1314 ilo_state_zs_init(&surf->u.zs, dev, &info);
1315
1316 if (info.z_img) {
1317 surf->u.zs.depth_bo = info.z_img->bo;
1318 if (info.hiz_enable)
1319 surf->u.zs.hiz_bo = info.z_img->aux.bo;
1320 }
1321
1322 if (info.s_img)
1323 surf->u.zs.stencil_bo = info.s_img->bo;
1324 }
1325
1326 return &surf->base;
1327 }
1328
1329 static void
1330 ilo_surface_destroy(struct pipe_context *pipe,
1331 struct pipe_surface *surface)
1332 {
1333 pipe_resource_reference(&surface->texture, NULL);
1334 FREE(surface);
1335 }
1336
1337 static void *
1338 ilo_create_compute_state(struct pipe_context *pipe,
1339 const struct pipe_compute_state *state)
1340 {
1341 struct ilo_context *ilo = ilo_context(pipe);
1342 struct ilo_shader_state *shader;
1343
1344 shader = ilo_shader_create_cs(ilo->dev, state, &ilo->state_vector);
1345 assert(shader);
1346
1347 ilo_shader_cache_add(ilo->shader_cache, shader);
1348
1349 return shader;
1350 }
1351
1352 static void
1353 ilo_bind_compute_state(struct pipe_context *pipe, void *state)
1354 {
1355 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1356
1357 vec->cs = state;
1358
1359 vec->dirty |= ILO_DIRTY_CS;
1360 }
1361
1362 static void
1363 ilo_delete_compute_state(struct pipe_context *pipe, void *state)
1364 {
1365 struct ilo_context *ilo = ilo_context(pipe);
1366 struct ilo_shader_state *cs = (struct ilo_shader_state *) state;
1367
1368 ilo_shader_cache_remove(ilo->shader_cache, cs);
1369 ilo_shader_destroy(cs);
1370 }
1371
1372 static void
1373 ilo_set_compute_resources(struct pipe_context *pipe,
1374 unsigned start, unsigned count,
1375 struct pipe_surface **surfaces)
1376 {
1377 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1378 struct ilo_resource_state *dst = &vec->cs_resource;
1379 unsigned i;
1380
1381 assert(start + count <= Elements(dst->states));
1382
1383 if (surfaces) {
1384 for (i = 0; i < count; i++)
1385 pipe_surface_reference(&dst->states[start + i], surfaces[i]);
1386 }
1387 else {
1388 for (i = 0; i < count; i++)
1389 pipe_surface_reference(&dst->states[start + i], NULL);
1390 }
1391
1392 if (dst->count <= start + count) {
1393 if (surfaces)
1394 count += start;
1395 else
1396 count = start;
1397
1398 while (count > 0 && !dst->states[count - 1])
1399 count--;
1400
1401 dst->count = count;
1402 }
1403
1404 vec->dirty |= ILO_DIRTY_CS_RESOURCE;
1405 }
1406
1407 static void
1408 ilo_set_global_binding(struct pipe_context *pipe,
1409 unsigned start, unsigned count,
1410 struct pipe_resource **resources,
1411 uint32_t **handles)
1412 {
1413 struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector;
1414 struct ilo_global_binding_cso *dst;
1415 unsigned i;
1416
1417 /* make room */
1418 if (vec->global_binding.count < start + count) {
1419 if (resources) {
1420 const unsigned old_size = vec->global_binding.bindings.size;
1421 const unsigned new_size = sizeof(*dst) * (start + count);
1422
1423 if (old_size < new_size) {
1424 util_dynarray_resize(&vec->global_binding.bindings, new_size);
1425 memset(vec->global_binding.bindings.data + old_size, 0,
1426 new_size - old_size);
1427 }
1428 } else {
1429 count = vec->global_binding.count - start;
1430 }
1431 }
1432
1433 dst = util_dynarray_element(&vec->global_binding.bindings,
1434 struct ilo_global_binding_cso, start);
1435
1436 if (resources) {
1437 for (i = 0; i < count; i++) {
1438 pipe_resource_reference(&dst[i].resource, resources[i]);
1439 dst[i].handle = handles[i];
1440 }
1441 } else {
1442 for (i = 0; i < count; i++) {
1443 pipe_resource_reference(&dst[i].resource, NULL);
1444 dst[i].handle = NULL;
1445 }
1446 }
1447
1448 if (vec->global_binding.count <= start + count) {
1449 dst = util_dynarray_begin(&vec->global_binding.bindings);
1450
1451 if (resources)
1452 count += start;
1453 else
1454 count = start;
1455
1456 while (count > 0 && !dst[count - 1].resource)
1457 count--;
1458
1459 vec->global_binding.count = count;
1460 }
1461
1462 vec->dirty |= ILO_DIRTY_GLOBAL_BINDING;
1463 }
1464
1465 /**
1466 * Initialize state-related functions.
1467 */
1468 void
1469 ilo_init_state_functions(struct ilo_context *ilo)
1470 {
1471 STATIC_ASSERT(ILO_STATE_COUNT <= 32);
1472
1473 ilo->base.create_blend_state = ilo_create_blend_state;
1474 ilo->base.bind_blend_state = ilo_bind_blend_state;
1475 ilo->base.delete_blend_state = ilo_delete_blend_state;
1476 ilo->base.create_sampler_state = ilo_create_sampler_state;
1477 ilo->base.bind_sampler_states = ilo_bind_sampler_states;
1478 ilo->base.delete_sampler_state = ilo_delete_sampler_state;
1479 ilo->base.create_rasterizer_state = ilo_create_rasterizer_state;
1480 ilo->base.bind_rasterizer_state = ilo_bind_rasterizer_state;
1481 ilo->base.delete_rasterizer_state = ilo_delete_rasterizer_state;
1482 ilo->base.create_depth_stencil_alpha_state = ilo_create_depth_stencil_alpha_state;
1483 ilo->base.bind_depth_stencil_alpha_state = ilo_bind_depth_stencil_alpha_state;
1484 ilo->base.delete_depth_stencil_alpha_state = ilo_delete_depth_stencil_alpha_state;
1485 ilo->base.create_fs_state = ilo_create_fs_state;
1486 ilo->base.bind_fs_state = ilo_bind_fs_state;
1487 ilo->base.delete_fs_state = ilo_delete_fs_state;
1488 ilo->base.create_vs_state = ilo_create_vs_state;
1489 ilo->base.bind_vs_state = ilo_bind_vs_state;
1490 ilo->base.delete_vs_state = ilo_delete_vs_state;
1491 ilo->base.create_gs_state = ilo_create_gs_state;
1492 ilo->base.bind_gs_state = ilo_bind_gs_state;
1493 ilo->base.delete_gs_state = ilo_delete_gs_state;
1494 ilo->base.create_vertex_elements_state = ilo_create_vertex_elements_state;
1495 ilo->base.bind_vertex_elements_state = ilo_bind_vertex_elements_state;
1496 ilo->base.delete_vertex_elements_state = ilo_delete_vertex_elements_state;
1497
1498 ilo->base.set_blend_color = ilo_set_blend_color;
1499 ilo->base.set_stencil_ref = ilo_set_stencil_ref;
1500 ilo->base.set_sample_mask = ilo_set_sample_mask;
1501 ilo->base.set_clip_state = ilo_set_clip_state;
1502 ilo->base.set_constant_buffer = ilo_set_constant_buffer;
1503 ilo->base.set_framebuffer_state = ilo_set_framebuffer_state;
1504 ilo->base.set_polygon_stipple = ilo_set_polygon_stipple;
1505 ilo->base.set_scissor_states = ilo_set_scissor_states;
1506 ilo->base.set_viewport_states = ilo_set_viewport_states;
1507 ilo->base.set_sampler_views = ilo_set_sampler_views;
1508 ilo->base.set_shader_resources = ilo_set_shader_resources;
1509 ilo->base.set_vertex_buffers = ilo_set_vertex_buffers;
1510 ilo->base.set_index_buffer = ilo_set_index_buffer;
1511
1512 ilo->base.create_stream_output_target = ilo_create_stream_output_target;
1513 ilo->base.stream_output_target_destroy = ilo_stream_output_target_destroy;
1514 ilo->base.set_stream_output_targets = ilo_set_stream_output_targets;
1515
1516 ilo->base.create_sampler_view = ilo_create_sampler_view;
1517 ilo->base.sampler_view_destroy = ilo_sampler_view_destroy;
1518
1519 ilo->base.create_surface = ilo_create_surface;
1520 ilo->base.surface_destroy = ilo_surface_destroy;
1521
1522 ilo->base.create_compute_state = ilo_create_compute_state;
1523 ilo->base.bind_compute_state = ilo_bind_compute_state;
1524 ilo->base.delete_compute_state = ilo_delete_compute_state;
1525 ilo->base.set_compute_resources = ilo_set_compute_resources;
1526 ilo->base.set_global_binding = ilo_set_global_binding;
1527 }
1528
1529 void
1530 ilo_state_vector_init(const struct ilo_dev *dev,
1531 struct ilo_state_vector *vec)
1532 {
1533 ilo_gpe_set_scissor_null(dev, &vec->scissor);
1534
1535 ilo_state_surface_init_for_null(&vec->fb.null_rt, dev);
1536 ilo_state_zs_init_for_null(&vec->fb.null_zs, dev);
1537
1538 ilo_state_sampler_init_disabled(&vec->disabled_sampler, dev);
1539
1540 util_dynarray_init(&vec->global_binding.bindings);
1541
1542 vec->dirty = ILO_DIRTY_ALL;
1543 }
1544
1545 void
1546 ilo_state_vector_cleanup(struct ilo_state_vector *vec)
1547 {
1548 unsigned i, sh;
1549
1550 for (i = 0; i < Elements(vec->vb.states); i++) {
1551 if (vec->vb.enabled_mask & (1 << i))
1552 pipe_resource_reference(&vec->vb.states[i].buffer, NULL);
1553 }
1554
1555 pipe_resource_reference(&vec->ib.buffer, NULL);
1556 pipe_resource_reference(&vec->ib.hw_resource, NULL);
1557
1558 for (i = 0; i < vec->so.count; i++)
1559 pipe_so_target_reference(&vec->so.states[i], NULL);
1560
1561 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
1562 for (i = 0; i < vec->view[sh].count; i++) {
1563 struct pipe_sampler_view *view = vec->view[sh].states[i];
1564 pipe_sampler_view_reference(&view, NULL);
1565 }
1566
1567 for (i = 0; i < Elements(vec->cbuf[sh].cso); i++) {
1568 struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
1569 pipe_resource_reference(&cbuf->resource, NULL);
1570 }
1571 }
1572
1573 for (i = 0; i < vec->resource.count; i++)
1574 pipe_surface_reference(&vec->resource.states[i], NULL);
1575
1576 for (i = 0; i < vec->fb.state.nr_cbufs; i++)
1577 pipe_surface_reference(&vec->fb.state.cbufs[i], NULL);
1578
1579 if (vec->fb.state.zsbuf)
1580 pipe_surface_reference(&vec->fb.state.zsbuf, NULL);
1581
1582 for (i = 0; i < vec->cs_resource.count; i++)
1583 pipe_surface_reference(&vec->cs_resource.states[i], NULL);
1584
1585 for (i = 0; i < vec->global_binding.count; i++) {
1586 struct ilo_global_binding_cso *cso =
1587 util_dynarray_element(&vec->global_binding.bindings,
1588 struct ilo_global_binding_cso, i);
1589 pipe_resource_reference(&cso->resource, NULL);
1590 }
1591
1592 util_dynarray_fini(&vec->global_binding.bindings);
1593 }
1594
1595 /**
1596 * Mark all states that have the resource dirty.
1597 */
1598 void
1599 ilo_state_vector_resource_renamed(struct ilo_state_vector *vec,
1600 struct pipe_resource *res)
1601 {
1602 struct intel_bo *bo = ilo_resource_get_bo(res);
1603 uint32_t states = 0;
1604 unsigned sh, i;
1605
1606 if (res->target == PIPE_BUFFER) {
1607 uint32_t vb_mask = vec->vb.enabled_mask;
1608
1609 while (vb_mask) {
1610 const unsigned idx = u_bit_scan(&vb_mask);
1611
1612 if (vec->vb.states[idx].buffer == res) {
1613 states |= ILO_DIRTY_VB;
1614 break;
1615 }
1616 }
1617
1618 if (vec->ib.buffer == res) {
1619 states |= ILO_DIRTY_IB;
1620
1621 /*
1622 * finalize_index_buffer() has an optimization that clears
1623 * ILO_DIRTY_IB when the HW states do not change. However, it fails
1624 * to flush the VF cache when the HW states do not change, but the
1625 * contents of the IB has changed. Here, we set the index size to an
1626 * invalid value to avoid the optimization.
1627 */
1628 vec->ib.hw_index_size = 0;
1629 }
1630
1631 for (i = 0; i < vec->so.count; i++) {
1632 if (vec->so.states[i]->buffer == res) {
1633 states |= ILO_DIRTY_SO;
1634 break;
1635 }
1636 }
1637 }
1638
1639 for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
1640 for (i = 0; i < vec->view[sh].count; i++) {
1641 struct ilo_view_cso *cso = (struct ilo_view_cso *) vec->view[sh].states[i];
1642
1643 if (cso->base.texture == res) {
1644 static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = {
1645 [PIPE_SHADER_VERTEX] = ILO_DIRTY_VIEW_VS,
1646 [PIPE_SHADER_FRAGMENT] = ILO_DIRTY_VIEW_FS,
1647 [PIPE_SHADER_GEOMETRY] = ILO_DIRTY_VIEW_GS,
1648 [PIPE_SHADER_COMPUTE] = ILO_DIRTY_VIEW_CS,
1649 };
1650 cso->surface.bo = bo;
1651
1652 states |= view_dirty_bits[sh];
1653 break;
1654 }
1655 }
1656
1657 if (res->target == PIPE_BUFFER) {
1658 for (i = 0; i < Elements(vec->cbuf[sh].cso); i++) {
1659 struct ilo_cbuf_cso *cbuf = &vec->cbuf[sh].cso[i];
1660
1661 if (cbuf->resource == res) {
1662 cbuf->surface.bo = bo;
1663 states |= ILO_DIRTY_CBUF;
1664 break;
1665 }
1666 }
1667 }
1668 }
1669
1670 for (i = 0; i < vec->resource.count; i++) {
1671 struct ilo_surface_cso *cso =
1672 (struct ilo_surface_cso *) vec->resource.states[i];
1673
1674 if (cso->base.texture == res) {
1675 cso->u.rt.bo = bo;
1676 states |= ILO_DIRTY_RESOURCE;
1677 break;
1678 }
1679 }
1680
1681 /* for now? */
1682 if (res->target != PIPE_BUFFER) {
1683 for (i = 0; i < vec->fb.state.nr_cbufs; i++) {
1684 struct ilo_surface_cso *cso =
1685 (struct ilo_surface_cso *) vec->fb.state.cbufs[i];
1686 if (cso && cso->base.texture == res) {
1687 cso->u.rt.bo = bo;
1688 states |= ILO_DIRTY_FB;
1689 break;
1690 }
1691 }
1692
1693 if (vec->fb.state.zsbuf && vec->fb.state.zsbuf->texture == res) {
1694 struct ilo_surface_cso *cso =
1695 (struct ilo_surface_cso *) vec->fb.state.zsbuf;
1696
1697 cso->u.zs.depth_bo = bo;
1698
1699 states |= ILO_DIRTY_FB;
1700 }
1701 }
1702
1703 for (i = 0; i < vec->cs_resource.count; i++) {
1704 struct ilo_surface_cso *cso =
1705 (struct ilo_surface_cso *) vec->cs_resource.states[i];
1706 if (cso->base.texture == res) {
1707 cso->u.rt.bo = bo;
1708 states |= ILO_DIRTY_CS_RESOURCE;
1709 break;
1710 }
1711 }
1712
1713 for (i = 0; i < vec->global_binding.count; i++) {
1714 struct ilo_global_binding_cso *cso =
1715 util_dynarray_element(&vec->global_binding.bindings,
1716 struct ilo_global_binding_cso, i);
1717
1718 if (cso->resource == res) {
1719 states |= ILO_DIRTY_GLOBAL_BINDING;
1720 break;
1721 }
1722 }
1723
1724 vec->dirty |= states;
1725 }
1726
1727 void
1728 ilo_state_vector_dump_dirty(const struct ilo_state_vector *vec)
1729 {
1730 static const char *state_names[ILO_STATE_COUNT] = {
1731 [ILO_STATE_VB] = "VB",
1732 [ILO_STATE_VE] = "VE",
1733 [ILO_STATE_IB] = "IB",
1734 [ILO_STATE_VS] = "VS",
1735 [ILO_STATE_GS] = "GS",
1736 [ILO_STATE_SO] = "SO",
1737 [ILO_STATE_CLIP] = "CLIP",
1738 [ILO_STATE_VIEWPORT] = "VIEWPORT",
1739 [ILO_STATE_SCISSOR] = "SCISSOR",
1740 [ILO_STATE_RASTERIZER] = "RASTERIZER",
1741 [ILO_STATE_POLY_STIPPLE] = "POLY_STIPPLE",
1742 [ILO_STATE_SAMPLE_MASK] = "SAMPLE_MASK",
1743 [ILO_STATE_FS] = "FS",
1744 [ILO_STATE_DSA] = "DSA",
1745 [ILO_STATE_STENCIL_REF] = "STENCIL_REF",
1746 [ILO_STATE_BLEND] = "BLEND",
1747 [ILO_STATE_BLEND_COLOR] = "BLEND_COLOR",
1748 [ILO_STATE_FB] = "FB",
1749 [ILO_STATE_SAMPLER_VS] = "SAMPLER_VS",
1750 [ILO_STATE_SAMPLER_GS] = "SAMPLER_GS",
1751 [ILO_STATE_SAMPLER_FS] = "SAMPLER_FS",
1752 [ILO_STATE_SAMPLER_CS] = "SAMPLER_CS",
1753 [ILO_STATE_VIEW_VS] = "VIEW_VS",
1754 [ILO_STATE_VIEW_GS] = "VIEW_GS",
1755 [ILO_STATE_VIEW_FS] = "VIEW_FS",
1756 [ILO_STATE_VIEW_CS] = "VIEW_CS",
1757 [ILO_STATE_CBUF] = "CBUF",
1758 [ILO_STATE_RESOURCE] = "RESOURCE",
1759 [ILO_STATE_CS] = "CS",
1760 [ILO_STATE_CS_RESOURCE] = "CS_RESOURCE",
1761 [ILO_STATE_GLOBAL_BINDING] = "GLOBAL_BINDING",
1762 };
1763 uint32_t dirty = vec->dirty;
1764
1765 if (!dirty) {
1766 ilo_printf("no state is dirty\n");
1767 return;
1768 }
1769
1770 dirty &= (1U << ILO_STATE_COUNT) - 1;
1771
1772 ilo_printf("%2d states are dirty:", util_bitcount(dirty));
1773 while (dirty) {
1774 const enum ilo_state state = u_bit_scan(&dirty);
1775 ilo_printf(" %s", state_names[state]);
1776 }
1777 ilo_printf("\n");
1778 }