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