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