1 /* 2 * Copyright 2010 Christoph Bumiller 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 */ 22 23 #include "pipe/p_defines.h" 24 #include "util/u_inlines.h" 25 #include "util/u_transfer.h" 26 27 #include "tgsi/tgsi_parse.h" 28 29 #include "nv50_stateobj.h" 30 #include "nv50_context.h" 31 32 #include "nv50_3d.xml.h" 33 #include "nv50_texture.xml.h" 34 35 #include "nouveau/nouveau_gldefs.h" 36 37 /* Caveats: 38 * ! pipe_sampler_state.normalized_coords is ignored - rectangle textures will 39 * use non-normalized coordinates, everything else won't 40 * (The relevant bit is in the TIC entry and not the TSC entry.) 41 * 42 * ! pipe_sampler_state.seamless_cube_map is ignored - seamless filtering is 43 * always activated on NVA0 + 44 * (Give me the global bit, otherwise it's not worth the CPU work.) 45 * 46 * ! pipe_sampler_state.border_color is not swizzled according to the texture 47 * swizzle in pipe_sampler_view 48 * (This will be ugly with indirect independent texture/sampler access, 49 * we'd have to emulate the logic in the shader. GL doesn't have that, 50 * D3D doesn't have swizzle, if we knew what we were implementing we'd be 51 * good.) 52 * 53 * ! pipe_rasterizer_state.line_last_pixel is ignored - it is never drawn 54 * 55 * ! pipe_rasterizer_state.flatshade_first also applies to QUADS 56 * (There's a GL query for that, forcing an exception is just ridiculous.) 57 * 58 * ! pipe_rasterizer_state.gl_rasterization_rules is ignored - pixel centers 59 * are always at half integer coordinates and the top-left rule applies 60 * (There does not seem to be a hardware switch for this.) 61 * 62 * ! pipe_rasterizer_state.sprite_coord_enable is masked with 0xff on NVC0 63 * (The hardware only has 8 slots meant for TexCoord and we have to assign 64 * in advance to maintain elegant separate shader objects.) 65 */ 66 67 static INLINE uint32_t 68 nv50_colormask(unsigned mask) 69 { 70 uint32_t ret = 0; 71 72 if (mask & PIPE_MASK_R) 73 ret |= 0x0001; 74 if (mask & PIPE_MASK_G) 75 ret |= 0x0010; 76 if (mask & PIPE_MASK_B) 77 ret |= 0x0100; 78 if (mask & PIPE_MASK_A) 79 ret |= 0x1000; 80 81 return ret; 82 } 83 84 #define NV50_BLEND_FACTOR_CASE(a, b) \ 85 case PIPE_BLENDFACTOR_##a: return NV50_3D_BLEND_FACTOR_##b 86 87 static INLINE uint32_t 88 nv50_blend_fac(unsigned factor) 89 { 90 switch (factor) { 91 NV50_BLEND_FACTOR_CASE(ONE, ONE); 92 NV50_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR); 93 NV50_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA); 94 NV50_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA); 95 NV50_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR); 96 NV50_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE); 97 NV50_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR); 98 NV50_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA); 99 NV50_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR); 100 NV50_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA); 101 NV50_BLEND_FACTOR_CASE(ZERO, ZERO); 102 NV50_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR); 103 NV50_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA); 104 NV50_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA); 105 NV50_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR); 106 NV50_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR); 107 NV50_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA); 108 NV50_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR); 109 NV50_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA); 110 default: 111 return NV50_3D_BLEND_FACTOR_ZERO; 112 } 113 } 114 115 static void * 116 nv50_blend_state_create(struct pipe_context *pipe, 117 const struct pipe_blend_state *cso) 118 { 119 struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj); 120 int i; 121 boolean emit_common_func = cso->rt[0].blend_enable; 122 uint32_t ms; 123 124 if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { 125 SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1); 126 SB_DATA (so, cso->independent_blend_enable); 127 } 128 129 so->pipe = *cso; 130 131 SB_BEGIN_3D(so, COLOR_MASK_COMMON, 1); 132 SB_DATA (so, !cso->independent_blend_enable); 133 134 SB_BEGIN_3D(so, BLEND_ENABLE_COMMON, 1); 135 SB_DATA (so, !cso->independent_blend_enable); 136 137 if (cso->independent_blend_enable) { 138 SB_BEGIN_3D(so, BLEND_ENABLE(0), 8); 139 for (i = 0; i < 8; ++i) { 140 SB_DATA(so, cso->rt[i].blend_enable); 141 if (cso->rt[i].blend_enable) 142 emit_common_func = TRUE; 143 } 144 145 if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { 146 emit_common_func = FALSE; 147 148 for (i = 0; i < 8; ++i) { 149 if (!cso->rt[i].blend_enable) 150 continue; 151 SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6); 152 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); 153 SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor)); 154 SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor)); 155 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); 156 SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor)); 157 SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor)); 158 } 159 } 160 } else { 161 SB_BEGIN_3D(so, BLEND_ENABLE(0), 1); 162 SB_DATA (so, cso->rt[0].blend_enable); 163 } 164 165 if (emit_common_func) { 166 SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); 167 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); 168 SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor)); 169 SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor)); 170 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); 171 SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_src_factor)); 172 SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); 173 SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor)); 174 } 175 176 if (cso->logicop_enable) { 177 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); 178 SB_DATA (so, 1); 179 SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); 180 } else { 181 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1); 182 SB_DATA (so, 0); 183 } 184 185 if (cso->independent_blend_enable) { 186 SB_BEGIN_3D(so, COLOR_MASK(0), 8); 187 for (i = 0; i < 8; ++i) 188 SB_DATA(so, nv50_colormask(cso->rt[i].colormask)); 189 } else { 190 SB_BEGIN_3D(so, COLOR_MASK(0), 1); 191 SB_DATA (so, nv50_colormask(cso->rt[0].colormask)); 192 } 193 194 ms = 0; 195 if (cso->alpha_to_coverage) 196 ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE; 197 if (cso->alpha_to_one) 198 ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE; 199 200 SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1); 201 SB_DATA (so, ms); 202 203 assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); 204 return so; 205 } 206 207 static void 208 nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso) 209 { 210 struct nv50_context *nv50 = nv50_context(pipe); 211 212 nv50->blend = hwcso; 213 nv50->dirty |= NV50_NEW_BLEND; 214 } 215 216 static void 217 nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso) 218 { 219 FREE(hwcso); 220 } 221 222 /* NOTE: ignoring line_last_pixel, using FALSE (set on screen init) */ 223 static void * 224 nv50_rasterizer_state_create(struct pipe_context *pipe, 225 const struct pipe_rasterizer_state *cso) 226 { 227 struct nv50_rasterizer_stateobj *so; 228 uint32_t reg; 229 230 so = CALLOC_STRUCT(nv50_rasterizer_stateobj); 231 if (!so) 232 return NULL; 233 so->pipe = *cso; 234 235 #ifndef NV50_SCISSORS_CLIPPING 236 SB_BEGIN_3D(so, SCISSOR_ENABLE(0), 1); 237 SB_DATA (so, cso->scissor); 238 #endif 239 240 SB_BEGIN_3D(so, SHADE_MODEL, 1); 241 SB_DATA (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT : 242 NV50_3D_SHADE_MODEL_SMOOTH); 243 SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1); 244 SB_DATA (so, !cso->flatshade_first); 245 SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1); 246 SB_DATA (so, cso->light_twoside); 247 248 SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1); 249 SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000); 250 251 SB_BEGIN_3D(so, MULTISAMPLE_ENABLE, 1); 252 SB_DATA (so, cso->multisample); 253 254 SB_BEGIN_3D(so, LINE_WIDTH, 1); 255 SB_DATA (so, fui(cso->line_width)); 256 SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1); 257 SB_DATA (so, cso->line_smooth); 258 259 SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1); 260 if (cso->line_stipple_enable) { 261 SB_DATA (so, 1); 262 SB_BEGIN_3D(so, LINE_STIPPLE, 1); 263 SB_DATA (so, (cso->line_stipple_pattern << 8) | 264 cso->line_stipple_factor); 265 } else { 266 SB_DATA (so, 0); 267 } 268 269 if (!cso->point_size_per_vertex) { 270 SB_BEGIN_3D(so, POINT_SIZE, 1); 271 SB_DATA (so, fui(cso->point_size)); 272 } 273 SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1); 274 SB_DATA (so, cso->point_quad_rasterization); 275 SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1); 276 SB_DATA (so, cso->point_smooth); 277 278 SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3); 279 SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); 280 SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); 281 SB_DATA (so, cso->poly_smooth); 282 283 SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3); 284 SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); 285 SB_DATA (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW : 286 NV50_3D_FRONT_FACE_CW); 287 switch (cso->cull_face) { 288 case PIPE_FACE_FRONT_AND_BACK: 289 SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK); 290 break; 291 case PIPE_FACE_FRONT: 292 SB_DATA(so, NV50_3D_CULL_FACE_FRONT); 293 break; 294 case PIPE_FACE_BACK: 295 default: 296 SB_DATA(so, NV50_3D_CULL_FACE_BACK); 297 break; 298 } 299 300 SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1); 301 SB_DATA (so, cso->poly_stipple_enable); 302 SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3); 303 SB_DATA (so, cso->offset_point); 304 SB_DATA (so, cso->offset_line); 305 SB_DATA (so, cso->offset_tri); 306 307 if (cso->offset_point || cso->offset_line || cso->offset_tri) { 308 SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1); 309 SB_DATA (so, fui(cso->offset_scale)); 310 SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1); 311 SB_DATA (so, fui(cso->offset_units * 2.0f)); 312 SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1); 313 SB_DATA (so, fui(cso->offset_clamp)); 314 } 315 316 if (cso->depth_clip) { 317 reg = 0; 318 } else { 319 reg = 320 NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR | 321 NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR | 322 NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; 323 } 324 #ifndef NV50_SCISSORS_CLIPPING 325 reg |= 326 NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 | 327 NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; 328 #endif 329 SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1); 330 SB_DATA (so, reg); 331 332 assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); 333 return (void *)so; 334 } 335 336 static void 337 nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) 338 { 339 struct nv50_context *nv50 = nv50_context(pipe); 340 341 nv50->rast = hwcso; 342 nv50->dirty |= NV50_NEW_RASTERIZER; 343 } 344 345 static void 346 nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) 347 { 348 FREE(hwcso); 349 } 350 351 static void * 352 nv50_zsa_state_create(struct pipe_context *pipe, 353 const struct pipe_depth_stencil_alpha_state *cso) 354 { 355 struct nv50_zsa_stateobj *so = CALLOC_STRUCT(nv50_zsa_stateobj); 356 357 so->pipe = *cso; 358 359 SB_BEGIN_3D(so, DEPTH_WRITE_ENABLE, 1); 360 SB_DATA (so, cso->depth.writemask); 361 SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1); 362 if (cso->depth.enabled) { 363 SB_DATA (so, 1); 364 SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1); 365 SB_DATA (so, nvgl_comparison_op(cso->depth.func)); 366 } else { 367 SB_DATA (so, 0); 368 } 369 370 if (cso->stencil[0].enabled) { 371 SB_BEGIN_3D(so, STENCIL_ENABLE, 5); 372 SB_DATA (so, 1); 373 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op)); 374 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); 375 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); 376 SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func)); 377 SB_BEGIN_3D(so, STENCIL_FRONT_MASK, 2); 378 SB_DATA (so, cso->stencil[0].writemask); 379 SB_DATA (so, cso->stencil[0].valuemask); 380 } else { 381 SB_BEGIN_3D(so, STENCIL_ENABLE, 1); 382 SB_DATA (so, 0); 383 } 384 385 if (cso->stencil[1].enabled) { 386 assert(cso->stencil[0].enabled); 387 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5); 388 SB_DATA (so, 1); 389 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op)); 390 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); 391 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); 392 SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func)); 393 SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2); 394 SB_DATA (so, cso->stencil[1].writemask); 395 SB_DATA (so, cso->stencil[1].valuemask); 396 } else { 397 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 1); 398 SB_DATA (so, 0); 399 } 400 401 SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1); 402 if (cso->alpha.enabled) { 403 SB_DATA (so, 1); 404 SB_BEGIN_3D(so, ALPHA_TEST_REF, 2); 405 SB_DATA (so, fui(cso->alpha.ref_value)); 406 SB_DATA (so, nvgl_comparison_op(cso->alpha.func)); 407 } else { 408 SB_DATA (so, 0); 409 } 410 411 assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); 412 return (void *)so; 413 } 414 415 static void 416 nv50_zsa_state_bind(struct pipe_context *pipe, void *hwcso) 417 { 418 struct nv50_context *nv50 = nv50_context(pipe); 419 420 nv50->zsa = hwcso; 421 nv50->dirty |= NV50_NEW_ZSA; 422 } 423 424 static void 425 nv50_zsa_state_delete(struct pipe_context *pipe, void *hwcso) 426 { 427 FREE(hwcso); 428 } 429 430 /* ====================== SAMPLERS AND TEXTURES ================================ 431 */ 432 433 #define NV50_TSC_WRAP_CASE(n) \ 434 case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n 435 436 static INLINE unsigned 437 nv50_tsc_wrap_mode(unsigned wrap) 438 { 439 switch (wrap) { 440 NV50_TSC_WRAP_CASE(REPEAT); 441 NV50_TSC_WRAP_CASE(MIRROR_REPEAT); 442 NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE); 443 NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER); 444 NV50_TSC_WRAP_CASE(CLAMP); 445 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE); 446 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER); 447 NV50_TSC_WRAP_CASE(MIRROR_CLAMP); 448 default: 449 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); 450 return NV50_TSC_WRAP_REPEAT; 451 } 452 } 453 454 void * 455 nv50_sampler_state_create(struct pipe_context *pipe, 456 const struct pipe_sampler_state *cso) 457 { 458 struct nv50_tsc_entry *so = CALLOC_STRUCT(nv50_tsc_entry); 459 float f[2]; 460 461 so->id = -1; 462 463 so->tsc[0] = (0x00026000 | 464 (nv50_tsc_wrap_mode(cso->wrap_s) << 0) | 465 (nv50_tsc_wrap_mode(cso->wrap_t) << 3) | 466 (nv50_tsc_wrap_mode(cso->wrap_r) << 6)); 467 468 if (nouveau_screen(pipe->screen)->class_3d >= NVE4_3D_CLASS) { 469 if (cso->seamless_cube_map) 470 so->tsc[1] |= NVE4_TSC_1_CUBE_SEAMLESS; 471 if (!cso->normalized_coords) 472 so->tsc[1] |= NVE4_TSC_1_FORCE_NONNORMALIZED_COORDS; 473 } 474 475 switch (cso->mag_img_filter) { 476 case PIPE_TEX_FILTER_LINEAR: 477 so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR; 478 break; 479 case PIPE_TEX_FILTER_NEAREST: 480 default: 481 so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST; 482 break; 483 } 484 485 switch (cso->min_img_filter) { 486 case PIPE_TEX_FILTER_LINEAR: 487 so->tsc[1] |= NV50_TSC_1_MINF_LINEAR; 488 break; 489 case PIPE_TEX_FILTER_NEAREST: 490 default: 491 so->tsc[1] |= NV50_TSC_1_MINF_NEAREST; 492 break; 493 } 494 495 switch (cso->min_mip_filter) { 496 case PIPE_TEX_MIPFILTER_LINEAR: 497 so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR; 498 break; 499 case PIPE_TEX_MIPFILTER_NEAREST: 500 so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST; 501 break; 502 case PIPE_TEX_MIPFILTER_NONE: 503 default: 504 so->tsc[1] |= NV50_TSC_1_MIPF_NONE; 505 break; 506 } 507 508 if (cso->max_anisotropy >= 16) 509 so->tsc[0] |= (7 << 20); 510 else 511 if (cso->max_anisotropy >= 12) 512 so->tsc[0] |= (6 << 20); 513 else { 514 so->tsc[0] |= (cso->max_anisotropy >> 1) << 20; 515 516 if (cso->max_anisotropy >= 4) 517 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35; 518 else 519 if (cso->max_anisotropy >= 2) 520 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15; 521 } 522 523 if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 524 /* NOTE: must be deactivated for non-shadow textures */ 525 so->tsc[0] |= (1 << 9); 526 so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10; 527 } 528 529 f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f); 530 so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12; 531 532 f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f); 533 f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f); 534 so->tsc[2] |= 535 (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff); 536 537 so->tsc[4] = fui(cso->border_color.f[0]); 538 so->tsc[5] = fui(cso->border_color.f[1]); 539 so->tsc[6] = fui(cso->border_color.f[2]); 540 so->tsc[7] = fui(cso->border_color.f[3]); 541 542 return (void *)so; 543 } 544 545 static void 546 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso) 547 { 548 unsigned s, i; 549 550 for (s = 0; s < 3; ++s) 551 for (i = 0; i < nv50_context(pipe)->num_samplers[s]; ++i) 552 if (nv50_context(pipe)->samplers[s][i] == hwcso) 553 nv50_context(pipe)->samplers[s][i] = NULL; 554 555 nv50_screen_tsc_free(nv50_context(pipe)->screen, nv50_tsc_entry(hwcso)); 556 557 FREE(hwcso); 558 } 559 560 static INLINE void 561 nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s, 562 unsigned nr, void **hwcso) 563 { 564 unsigned i; 565 566 for (i = 0; i < nr; ++i) { 567 struct nv50_tsc_entry *old = nv50->samplers[s][i]; 568 569 nv50->samplers[s][i] = nv50_tsc_entry(hwcso[i]); 570 if (old) 571 nv50_screen_tsc_unlock(nv50->screen, old); 572 } 573 for (; i < nv50->num_samplers[s]; ++i) 574 if (nv50->samplers[s][i]) 575 nv50_screen_tsc_unlock(nv50->screen, nv50->samplers[s][i]); 576 577 nv50->num_samplers[s] = nr; 578 579 nv50->dirty |= NV50_NEW_SAMPLERS; 580 } 581 582 static void 583 nv50_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 584 { 585 nv50_stage_sampler_states_bind(nv50_context(pipe), 0, nr, s); 586 } 587 588 static void 589 nv50_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 590 { 591 nv50_stage_sampler_states_bind(nv50_context(pipe), 2, nr, s); 592 } 593 594 static void 595 nv50_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 596 { 597 nv50_stage_sampler_states_bind(nv50_context(pipe), 1, nr, s); 598 } 599 600 /* NOTE: only called when not referenced anywhere, won't be bound */ 601 static void 602 nv50_sampler_view_destroy(struct pipe_context *pipe, 603 struct pipe_sampler_view *view) 604 { 605 pipe_resource_reference(&view->texture, NULL); 606 607 nv50_screen_tic_free(nv50_context(pipe)->screen, nv50_tic_entry(view)); 608 609 FREE(nv50_tic_entry(view)); 610 } 611 612 static INLINE void 613 nv50_stage_set_sampler_views(struct nv50_context *nv50, int s, 614 unsigned nr, 615 struct pipe_sampler_view **views) 616 { 617 unsigned i; 618 619 for (i = 0; i < nr; ++i) { 620 struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]); 621 if (old) 622 nv50_screen_tic_unlock(nv50->screen, old); 623 624 pipe_sampler_view_reference(&nv50->textures[s][i], views[i]); 625 } 626 627 for (i = nr; i < nv50->num_textures[s]; ++i) { 628 struct nv50_tic_entry *old = nv50_tic_entry(nv50->textures[s][i]); 629 if (!old) 630 continue; 631 nv50_screen_tic_unlock(nv50->screen, old); 632 633 pipe_sampler_view_reference(&nv50->textures[s][i], NULL); 634 } 635 636 nv50->num_textures[s] = nr; 637 638 nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES); 639 640 nv50->dirty |= NV50_NEW_TEXTURES; 641 } 642 643 static void 644 nv50_vp_set_sampler_views(struct pipe_context *pipe, 645 unsigned nr, 646 struct pipe_sampler_view **views) 647 { 648 nv50_stage_set_sampler_views(nv50_context(pipe), 0, nr, views); 649 } 650 651 static void 652 nv50_fp_set_sampler_views(struct pipe_context *pipe, 653 unsigned nr, 654 struct pipe_sampler_view **views) 655 { 656 nv50_stage_set_sampler_views(nv50_context(pipe), 2, nr, views); 657 } 658 659 static void 660 nv50_gp_set_sampler_views(struct pipe_context *pipe, 661 unsigned nr, 662 struct pipe_sampler_view **views) 663 { 664 nv50_stage_set_sampler_views(nv50_context(pipe), 1, nr, views); 665 } 666 667 /* ============================= SHADERS ======================================= 668 */ 669 670 static void * 671 nv50_sp_state_create(struct pipe_context *pipe, 672 const struct pipe_shader_state *cso, unsigned type) 673 { 674 struct nv50_program *prog; 675 676 prog = CALLOC_STRUCT(nv50_program); 677 if (!prog) 678 return NULL; 679 680 prog->type = type; 681 prog->pipe.tokens = tgsi_dup_tokens(cso->tokens); 682 683 if (cso->stream_output.num_outputs) 684 prog->pipe.stream_output = cso->stream_output; 685 686 return (void *)prog; 687 } 688 689 static void 690 nv50_sp_state_delete(struct pipe_context *pipe, void *hwcso) 691 { 692 struct nv50_program *prog = (struct nv50_program *)hwcso; 693 694 nv50_program_destroy(nv50_context(pipe), prog); 695 696 FREE((void *)prog->pipe.tokens); 697 FREE(prog); 698 } 699 700 static void * 701 nv50_vp_state_create(struct pipe_context *pipe, 702 const struct pipe_shader_state *cso) 703 { 704 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX); 705 } 706 707 static void 708 nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso) 709 { 710 struct nv50_context *nv50 = nv50_context(pipe); 711 712 nv50->vertprog = hwcso; 713 nv50->dirty |= NV50_NEW_VERTPROG; 714 } 715 716 static void * 717 nv50_fp_state_create(struct pipe_context *pipe, 718 const struct pipe_shader_state *cso) 719 { 720 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT); 721 } 722 723 static void 724 nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso) 725 { 726 struct nv50_context *nv50 = nv50_context(pipe); 727 728 nv50->fragprog = hwcso; 729 nv50->dirty |= NV50_NEW_FRAGPROG; 730 } 731 732 static void * 733 nv50_gp_state_create(struct pipe_context *pipe, 734 const struct pipe_shader_state *cso) 735 { 736 return nv50_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY); 737 } 738 739 static void 740 nv50_gp_state_bind(struct pipe_context *pipe, void *hwcso) 741 { 742 struct nv50_context *nv50 = nv50_context(pipe); 743 744 nv50->gmtyprog = hwcso; 745 nv50->dirty |= NV50_NEW_GMTYPROG; 746 } 747 748 static void 749 nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, 750 struct pipe_constant_buffer *cb) 751 { 752 struct nv50_context *nv50 = nv50_context(pipe); 753 struct pipe_resource *res = cb ? cb->buffer : NULL; 754 const unsigned s = nv50_context_shader_stage(shader); 755 const unsigned i = index; 756 757 if (shader == PIPE_SHADER_COMPUTE) 758 return; 759 760 if (nv50->constbuf[s][i].user) 761 nv50->constbuf[s][i].u.buf = NULL; 762 else 763 if (nv50->constbuf[s][i].u.buf) 764 nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(s, i)); 765 766 pipe_resource_reference(&nv50->constbuf[s][i].u.buf, res); 767 768 nv50->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE; 769 if (nv50->constbuf[s][i].user) { 770 nv50->constbuf[s][i].u.data = cb->user_buffer; 771 nv50->constbuf[s][i].size = cb->buffer_size; 772 nv50->constbuf_valid[s] |= 1 << i; 773 } else 774 if (res) { 775 nv50->constbuf[s][i].offset = cb->buffer_offset; 776 nv50->constbuf[s][i].size = align(cb->buffer_size, 0x100); 777 nv50->constbuf_valid[s] |= 1 << i; 778 } else { 779 nv50->constbuf_valid[s] &= ~(1 << i); 780 } 781 nv50->constbuf_dirty[s] |= 1 << i; 782 783 nv50->dirty |= NV50_NEW_CONSTBUF; 784 } 785 786 /* ============================================================================= 787 */ 788 789 static void 790 nv50_set_blend_color(struct pipe_context *pipe, 791 const struct pipe_blend_color *bcol) 792 { 793 struct nv50_context *nv50 = nv50_context(pipe); 794 795 nv50->blend_colour = *bcol; 796 nv50->dirty |= NV50_NEW_BLEND_COLOUR; 797 } 798 799 static void 800 nv50_set_stencil_ref(struct pipe_context *pipe, 801 const struct pipe_stencil_ref *sr) 802 { 803 struct nv50_context *nv50 = nv50_context(pipe); 804 805 nv50->stencil_ref = *sr; 806 nv50->dirty |= NV50_NEW_STENCIL_REF; 807 } 808 809 static void 810 nv50_set_clip_state(struct pipe_context *pipe, 811 const struct pipe_clip_state *clip) 812 { 813 struct nv50_context *nv50 = nv50_context(pipe); 814 815 memcpy(nv50->clip.ucp, clip->ucp, sizeof(clip->ucp)); 816 817 nv50->dirty |= NV50_NEW_CLIP; 818 } 819 820 static void 821 nv50_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) 822 { 823 struct nv50_context *nv50 = nv50_context(pipe); 824 825 nv50->sample_mask = sample_mask; 826 nv50->dirty |= NV50_NEW_SAMPLE_MASK; 827 } 828 829 830 static void 831 nv50_set_framebuffer_state(struct pipe_context *pipe, 832 const struct pipe_framebuffer_state *fb) 833 { 834 struct nv50_context *nv50 = nv50_context(pipe); 835 unsigned i; 836 837 nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB); 838 839 for (i = 0; i < fb->nr_cbufs; ++i) 840 pipe_surface_reference(&nv50->framebuffer.cbufs[i], fb->cbufs[i]); 841 for (; i < nv50->framebuffer.nr_cbufs; ++i) 842 pipe_surface_reference(&nv50->framebuffer.cbufs[i], NULL); 843 844 nv50->framebuffer.nr_cbufs = fb->nr_cbufs; 845 846 nv50->framebuffer.width = fb->width; 847 nv50->framebuffer.height = fb->height; 848 849 pipe_surface_reference(&nv50->framebuffer.zsbuf, fb->zsbuf); 850 851 nv50->dirty |= NV50_NEW_FRAMEBUFFER; 852 } 853 854 static void 855 nv50_set_polygon_stipple(struct pipe_context *pipe, 856 const struct pipe_poly_stipple *stipple) 857 { 858 struct nv50_context *nv50 = nv50_context(pipe); 859 860 nv50->stipple = *stipple; 861 nv50->dirty |= NV50_NEW_STIPPLE; 862 } 863 864 static void 865 nv50_set_scissor_state(struct pipe_context *pipe, 866 const struct pipe_scissor_state *scissor) 867 { 868 struct nv50_context *nv50 = nv50_context(pipe); 869 870 nv50->scissor = *scissor; 871 nv50->dirty |= NV50_NEW_SCISSOR; 872 } 873 874 static void 875 nv50_set_viewport_state(struct pipe_context *pipe, 876 const struct pipe_viewport_state *vpt) 877 { 878 struct nv50_context *nv50 = nv50_context(pipe); 879 880 nv50->viewport = *vpt; 881 nv50->dirty |= NV50_NEW_VIEWPORT; 882 } 883 884 static void 885 nv50_set_vertex_buffers(struct pipe_context *pipe, 886 unsigned count, 887 const struct pipe_vertex_buffer *vb) 888 { 889 struct nv50_context *nv50 = nv50_context(pipe); 890 unsigned i; 891 892 nv50->vbo_user = nv50->vbo_constant = 0; 893 894 for (i = 0; i < count; ++i) { 895 nv50->vtxbuf[i].stride = vb[i].stride; 896 pipe_resource_reference(&nv50->vtxbuf[i].buffer, vb[i].buffer); 897 if (!vb[i].buffer && vb[i].user_buffer) { 898 nv50->vtxbuf[i].user_buffer = vb[i].user_buffer; 899 nv50->vbo_user |= 1 << i; 900 if (!vb[i].stride) 901 nv50->vbo_constant |= 1 << i; 902 } else { 903 nv50->vtxbuf[i].buffer_offset = vb[i].buffer_offset; 904 } 905 } 906 for (; i < nv50->num_vtxbufs; ++i) 907 pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL); 908 909 nv50->num_vtxbufs = count; 910 911 nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX); 912 913 nv50->dirty |= NV50_NEW_ARRAYS; 914 } 915 916 static void 917 nv50_set_index_buffer(struct pipe_context *pipe, 918 const struct pipe_index_buffer *ib) 919 { 920 struct nv50_context *nv50 = nv50_context(pipe); 921 922 if (nv50->idxbuf.buffer) 923 nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX); 924 925 if (ib) { 926 pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer); 927 nv50->idxbuf.index_size = ib->index_size; 928 if (ib->buffer) { 929 nv50->idxbuf.offset = ib->offset; 930 BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(ib->buffer), RD); 931 } else { 932 nv50->idxbuf.user_buffer = ib->user_buffer; 933 } 934 } else { 935 pipe_resource_reference(&nv50->idxbuf.buffer, NULL); 936 } 937 } 938 939 static void 940 nv50_vertex_state_bind(struct pipe_context *pipe, void *hwcso) 941 { 942 struct nv50_context *nv50 = nv50_context(pipe); 943 944 nv50->vertex = hwcso; 945 nv50->dirty |= NV50_NEW_VERTEX; 946 } 947 948 static struct pipe_stream_output_target * 949 nv50_so_target_create(struct pipe_context *pipe, 950 struct pipe_resource *res, 951 unsigned offset, unsigned size) 952 { 953 struct nv50_so_target *targ = MALLOC_STRUCT(nv50_so_target); 954 if (!targ) 955 return NULL; 956 957 if (nouveau_context(pipe)->screen->class_3d >= NVA0_3D_CLASS) { 958 targ->pq = pipe->create_query(pipe, 959 NVA0_QUERY_STREAM_OUTPUT_BUFFER_OFFSET); 960 if (!targ->pq) { 961 FREE(targ); 962 return NULL; 963 } 964 } else { 965 targ->pq = NULL; 966 } 967 targ->clean = TRUE; 968 969 targ->pipe.buffer_size = size; 970 targ->pipe.buffer_offset = offset; 971 targ->pipe.context = pipe; 972 targ->pipe.buffer = NULL; 973 pipe_resource_reference(&targ->pipe.buffer, res); 974 pipe_reference_init(&targ->pipe.reference, 1); 975 976 return &targ->pipe; 977 } 978 979 static void 980 nv50_so_target_destroy(struct pipe_context *pipe, 981 struct pipe_stream_output_target *ptarg) 982 { 983 struct nv50_so_target *targ = nv50_so_target(ptarg); 984 if (targ->pq) 985 pipe->destroy_query(pipe, targ->pq); 986 pipe_resource_reference(&targ->pipe.buffer, NULL); 987 FREE(targ); 988 } 989 990 static void 991 nv50_set_stream_output_targets(struct pipe_context *pipe, 992 unsigned num_targets, 993 struct pipe_stream_output_target **targets, 994 unsigned append_mask) 995 { 996 struct nv50_context *nv50 = nv50_context(pipe); 997 unsigned i; 998 boolean serialize = TRUE; 999 const boolean can_resume = nv50->screen->base.class_3d >= NVA0_3D_CLASS; 1000 1001 assert(num_targets <= 4); 1002 1003 for (i = 0; i < num_targets; ++i) { 1004 const boolean changed = nv50->so_target[i] != targets[i]; 1005 if (!changed && (append_mask & (1 << i))) 1006 continue; 1007 nv50->so_targets_dirty |= 1 << i; 1008 1009 if (can_resume && changed && nv50->so_target[i]) { 1010 nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize); 1011 serialize = FALSE; 1012 } 1013 1014 if (targets[i] && !(append_mask & (1 << i))) 1015 nv50_so_target(targets[i])->clean = TRUE; 1016 1017 pipe_so_target_reference(&nv50->so_target[i], targets[i]); 1018 } 1019 for (; i < nv50->num_so_targets; ++i) { 1020 if (can_resume && nv50->so_target[i]) { 1021 nva0_so_target_save_offset(pipe, nv50->so_target[i], i, serialize); 1022 serialize = FALSE; 1023 } 1024 pipe_so_target_reference(&nv50->so_target[i], NULL); 1025 nv50->so_targets_dirty |= 1 << i; 1026 } 1027 nv50->num_so_targets = num_targets; 1028 1029 if (nv50->so_targets_dirty) 1030 nv50->dirty |= NV50_NEW_STRMOUT; 1031 } 1032 1033 void 1034 nv50_init_state_functions(struct nv50_context *nv50) 1035 { 1036 struct pipe_context *pipe = &nv50->base.pipe; 1037 1038 pipe->create_blend_state = nv50_blend_state_create; 1039 pipe->bind_blend_state = nv50_blend_state_bind; 1040 pipe->delete_blend_state = nv50_blend_state_delete; 1041 1042 pipe->create_rasterizer_state = nv50_rasterizer_state_create; 1043 pipe->bind_rasterizer_state = nv50_rasterizer_state_bind; 1044 pipe->delete_rasterizer_state = nv50_rasterizer_state_delete; 1045 1046 pipe->create_depth_stencil_alpha_state = nv50_zsa_state_create; 1047 pipe->bind_depth_stencil_alpha_state = nv50_zsa_state_bind; 1048 pipe->delete_depth_stencil_alpha_state = nv50_zsa_state_delete; 1049 1050 pipe->create_sampler_state = nv50_sampler_state_create; 1051 pipe->delete_sampler_state = nv50_sampler_state_delete; 1052 pipe->bind_vertex_sampler_states = nv50_vp_sampler_states_bind; 1053 pipe->bind_fragment_sampler_states = nv50_fp_sampler_states_bind; 1054 pipe->bind_geometry_sampler_states = nv50_gp_sampler_states_bind; 1055 1056 pipe->create_sampler_view = nv50_create_sampler_view; 1057 pipe->sampler_view_destroy = nv50_sampler_view_destroy; 1058 pipe->set_vertex_sampler_views = nv50_vp_set_sampler_views; 1059 pipe->set_fragment_sampler_views = nv50_fp_set_sampler_views; 1060 pipe->set_geometry_sampler_views = nv50_gp_set_sampler_views; 1061 1062 pipe->create_vs_state = nv50_vp_state_create; 1063 pipe->create_fs_state = nv50_fp_state_create; 1064 pipe->create_gs_state = nv50_gp_state_create; 1065 pipe->bind_vs_state = nv50_vp_state_bind; 1066 pipe->bind_fs_state = nv50_fp_state_bind; 1067 pipe->bind_gs_state = nv50_gp_state_bind; 1068 pipe->delete_vs_state = nv50_sp_state_delete; 1069 pipe->delete_fs_state = nv50_sp_state_delete; 1070 pipe->delete_gs_state = nv50_sp_state_delete; 1071 1072 pipe->set_blend_color = nv50_set_blend_color; 1073 pipe->set_stencil_ref = nv50_set_stencil_ref; 1074 pipe->set_clip_state = nv50_set_clip_state; 1075 pipe->set_sample_mask = nv50_set_sample_mask; 1076 pipe->set_constant_buffer = nv50_set_constant_buffer; 1077 pipe->set_framebuffer_state = nv50_set_framebuffer_state; 1078 pipe->set_polygon_stipple = nv50_set_polygon_stipple; 1079 pipe->set_scissor_state = nv50_set_scissor_state; 1080 pipe->set_viewport_state = nv50_set_viewport_state; 1081 1082 pipe->create_vertex_elements_state = nv50_vertex_state_create; 1083 pipe->delete_vertex_elements_state = nv50_vertex_state_delete; 1084 pipe->bind_vertex_elements_state = nv50_vertex_state_bind; 1085 1086 pipe->set_vertex_buffers = nv50_set_vertex_buffers; 1087 pipe->set_index_buffer = nv50_set_index_buffer; 1088 1089 pipe->create_stream_output_target = nv50_so_target_create; 1090 pipe->stream_output_target_destroy = nv50_so_target_destroy; 1091 pipe->set_stream_output_targets = nv50_set_stream_output_targets; 1092 } 1093