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