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