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