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 "nvc0_stateobj.h" 30 #include "nvc0_context.h" 31 32 #include "nvc0_3d.xml.h" 33 #include "nv50/nv50_texture.xml.h" 34 35 #include "nouveau/nouveau_gldefs.h" 36 37 static INLINE uint32_t 38 nvc0_colormask(unsigned mask) 39 { 40 uint32_t ret = 0; 41 42 if (mask & PIPE_MASK_R) 43 ret |= 0x0001; 44 if (mask & PIPE_MASK_G) 45 ret |= 0x0010; 46 if (mask & PIPE_MASK_B) 47 ret |= 0x0100; 48 if (mask & PIPE_MASK_A) 49 ret |= 0x1000; 50 51 return ret; 52 } 53 54 #define NVC0_BLEND_FACTOR_CASE(a, b) \ 55 case PIPE_BLENDFACTOR_##a: return NV50_3D_BLEND_FACTOR_##b 56 57 static INLINE uint32_t 58 nvc0_blend_fac(unsigned factor) 59 { 60 switch (factor) { 61 NVC0_BLEND_FACTOR_CASE(ONE, ONE); 62 NVC0_BLEND_FACTOR_CASE(SRC_COLOR, SRC_COLOR); 63 NVC0_BLEND_FACTOR_CASE(SRC_ALPHA, SRC_ALPHA); 64 NVC0_BLEND_FACTOR_CASE(DST_ALPHA, DST_ALPHA); 65 NVC0_BLEND_FACTOR_CASE(DST_COLOR, DST_COLOR); 66 NVC0_BLEND_FACTOR_CASE(SRC_ALPHA_SATURATE, SRC_ALPHA_SATURATE); 67 NVC0_BLEND_FACTOR_CASE(CONST_COLOR, CONSTANT_COLOR); 68 NVC0_BLEND_FACTOR_CASE(CONST_ALPHA, CONSTANT_ALPHA); 69 NVC0_BLEND_FACTOR_CASE(SRC1_COLOR, SRC1_COLOR); 70 NVC0_BLEND_FACTOR_CASE(SRC1_ALPHA, SRC1_ALPHA); 71 NVC0_BLEND_FACTOR_CASE(ZERO, ZERO); 72 NVC0_BLEND_FACTOR_CASE(INV_SRC_COLOR, ONE_MINUS_SRC_COLOR); 73 NVC0_BLEND_FACTOR_CASE(INV_SRC_ALPHA, ONE_MINUS_SRC_ALPHA); 74 NVC0_BLEND_FACTOR_CASE(INV_DST_ALPHA, ONE_MINUS_DST_ALPHA); 75 NVC0_BLEND_FACTOR_CASE(INV_DST_COLOR, ONE_MINUS_DST_COLOR); 76 NVC0_BLEND_FACTOR_CASE(INV_CONST_COLOR, ONE_MINUS_CONSTANT_COLOR); 77 NVC0_BLEND_FACTOR_CASE(INV_CONST_ALPHA, ONE_MINUS_CONSTANT_ALPHA); 78 NVC0_BLEND_FACTOR_CASE(INV_SRC1_COLOR, ONE_MINUS_SRC1_COLOR); 79 NVC0_BLEND_FACTOR_CASE(INV_SRC1_ALPHA, ONE_MINUS_SRC1_ALPHA); 80 default: 81 return NV50_3D_BLEND_FACTOR_ZERO; 82 } 83 } 84 85 static void * 86 nvc0_blend_state_create(struct pipe_context *pipe, 87 const struct pipe_blend_state *cso) 88 { 89 struct nvc0_blend_stateobj *so = CALLOC_STRUCT(nvc0_blend_stateobj); 90 int i; 91 int r; /* reference */ 92 uint32_t ms; 93 uint8_t blend_en = 0; 94 boolean indep_masks = FALSE; 95 boolean indep_funcs = FALSE; 96 97 so->pipe = *cso; 98 99 /* check which states actually have differing values */ 100 if (cso->independent_blend_enable) { 101 for (r = 0; r < 8 && !cso->rt[r].blend_enable; ++r); 102 blend_en |= 1 << r; 103 for (i = r + 1; i < 8; ++i) { 104 if (!cso->rt[i].blend_enable) 105 continue; 106 blend_en |= 1 << i; 107 if (cso->rt[i].rgb_func != cso->rt[r].rgb_func || 108 cso->rt[i].rgb_src_factor != cso->rt[r].rgb_src_factor || 109 cso->rt[i].rgb_dst_factor != cso->rt[r].rgb_dst_factor || 110 cso->rt[i].alpha_func != cso->rt[r].alpha_func || 111 cso->rt[i].alpha_src_factor != cso->rt[r].alpha_src_factor || 112 cso->rt[i].alpha_dst_factor != cso->rt[r].alpha_dst_factor) { 113 indep_funcs = TRUE; 114 break; 115 } 116 } 117 for (; i < 8; ++i) 118 blend_en |= (cso->rt[i].blend_enable ? 1 : 0) << i; 119 120 for (i = 1; i < 8; ++i) { 121 if (cso->rt[i].colormask != cso->rt[0].colormask) { 122 indep_masks = TRUE; 123 break; 124 } 125 } 126 } else { 127 r = 0; 128 if (cso->rt[0].blend_enable) 129 blend_en = 0xff; 130 } 131 132 if (cso->logicop_enable) { 133 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); 134 SB_DATA (so, 1); 135 SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); 136 137 SB_IMMED_3D(so, MACRO_BLEND_ENABLES, 0); 138 } else { 139 SB_IMMED_3D(so, LOGIC_OP_ENABLE, 0); 140 141 SB_IMMED_3D(so, BLEND_INDEPENDENT, indep_funcs); 142 SB_IMMED_3D(so, MACRO_BLEND_ENABLES, blend_en); 143 if (indep_funcs) { 144 for (i = 0; i < 8; ++i) { 145 if (cso->rt[i].blend_enable) { 146 SB_BEGIN_3D(so, IBLEND_EQUATION_RGB(i), 6); 147 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); 148 SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_src_factor)); 149 SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_dst_factor)); 150 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); 151 SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_src_factor)); 152 SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_dst_factor)); 153 } 154 } 155 } else 156 if (blend_en) { 157 SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); 158 SB_DATA (so, nvgl_blend_eqn(cso->rt[r].rgb_func)); 159 SB_DATA (so, nvc0_blend_fac(cso->rt[r].rgb_src_factor)); 160 SB_DATA (so, nvc0_blend_fac(cso->rt[r].rgb_dst_factor)); 161 SB_DATA (so, nvgl_blend_eqn(cso->rt[r].alpha_func)); 162 SB_DATA (so, nvc0_blend_fac(cso->rt[r].alpha_src_factor)); 163 SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); 164 SB_DATA (so, nvc0_blend_fac(cso->rt[r].alpha_dst_factor)); 165 } 166 167 SB_IMMED_3D(so, COLOR_MASK_COMMON, !indep_masks); 168 if (indep_masks) { 169 SB_BEGIN_3D(so, COLOR_MASK(0), 8); 170 for (i = 0; i < 8; ++i) 171 SB_DATA(so, nvc0_colormask(cso->rt[i].colormask)); 172 } else { 173 SB_BEGIN_3D(so, COLOR_MASK(0), 1); 174 SB_DATA (so, nvc0_colormask(cso->rt[0].colormask)); 175 } 176 } 177 178 ms = 0; 179 if (cso->alpha_to_coverage) 180 ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE; 181 if (cso->alpha_to_one) 182 ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE; 183 184 SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1); 185 SB_DATA (so, ms); 186 187 assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); 188 return so; 189 } 190 191 static void 192 nvc0_blend_state_bind(struct pipe_context *pipe, void *hwcso) 193 { 194 struct nvc0_context *nvc0 = nvc0_context(pipe); 195 196 nvc0->blend = hwcso; 197 nvc0->dirty |= NVC0_NEW_BLEND; 198 } 199 200 static void 201 nvc0_blend_state_delete(struct pipe_context *pipe, void *hwcso) 202 { 203 FREE(hwcso); 204 } 205 206 /* NOTE: ignoring line_last_pixel, using FALSE (set on screen init) */ 207 static void * 208 nvc0_rasterizer_state_create(struct pipe_context *pipe, 209 const struct pipe_rasterizer_state *cso) 210 { 211 struct nvc0_rasterizer_stateobj *so; 212 uint32_t reg; 213 214 so = CALLOC_STRUCT(nvc0_rasterizer_stateobj); 215 if (!so) 216 return NULL; 217 so->pipe = *cso; 218 219 /* Scissor enables are handled in scissor state, we will not want to 220 * always emit 16 commands, one for each scissor rectangle, here. 221 */ 222 223 SB_BEGIN_3D(so, SHADE_MODEL, 1); 224 SB_DATA (so, cso->flatshade ? NVC0_3D_SHADE_MODEL_FLAT : 225 NVC0_3D_SHADE_MODEL_SMOOTH); 226 SB_IMMED_3D(so, PROVOKING_VERTEX_LAST, !cso->flatshade_first); 227 SB_IMMED_3D(so, VERTEX_TWO_SIDE_ENABLE, cso->light_twoside); 228 229 SB_IMMED_3D(so, VERT_COLOR_CLAMP_EN, cso->clamp_vertex_color); 230 SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1); 231 SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000); 232 233 SB_IMMED_3D(so, MULTISAMPLE_ENABLE, cso->multisample); 234 235 SB_IMMED_3D(so, LINE_SMOOTH_ENABLE, cso->line_smooth); 236 if (cso->line_smooth) 237 SB_BEGIN_3D(so, LINE_WIDTH_SMOOTH, 1); 238 else 239 SB_BEGIN_3D(so, LINE_WIDTH_ALIASED, 1); 240 SB_DATA (so, fui(cso->line_width)); 241 242 SB_IMMED_3D(so, LINE_STIPPLE_ENABLE, cso->line_stipple_enable); 243 if (cso->line_stipple_enable) { 244 SB_BEGIN_3D(so, LINE_STIPPLE_PATTERN, 1); 245 SB_DATA (so, (cso->line_stipple_pattern << 8) | 246 cso->line_stipple_factor); 247 248 } 249 250 SB_IMMED_3D(so, VP_POINT_SIZE_EN, cso->point_size_per_vertex); 251 if (!cso->point_size_per_vertex) { 252 SB_BEGIN_3D(so, POINT_SIZE, 1); 253 SB_DATA (so, fui(cso->point_size)); 254 } 255 256 reg = (cso->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) ? 257 NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT : 258 NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT; 259 260 SB_BEGIN_3D(so, POINT_COORD_REPLACE, 1); 261 SB_DATA (so, ((cso->sprite_coord_enable & 0xff) << 3) | reg); 262 SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization); 263 SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth); 264 265 SB_BEGIN_3D(so, MACRO_POLYGON_MODE_FRONT, 1); 266 SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); 267 SB_BEGIN_3D(so, MACRO_POLYGON_MODE_BACK, 1); 268 SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); 269 SB_IMMED_3D(so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth); 270 271 SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3); 272 SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); 273 SB_DATA (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW : 274 NVC0_3D_FRONT_FACE_CW); 275 switch (cso->cull_face) { 276 case PIPE_FACE_FRONT_AND_BACK: 277 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK); 278 break; 279 case PIPE_FACE_FRONT: 280 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT); 281 break; 282 case PIPE_FACE_BACK: 283 default: 284 SB_DATA(so, NVC0_3D_CULL_FACE_BACK); 285 break; 286 } 287 288 SB_IMMED_3D(so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable); 289 SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3); 290 SB_DATA (so, cso->offset_point); 291 SB_DATA (so, cso->offset_line); 292 SB_DATA (so, cso->offset_tri); 293 294 if (cso->offset_point || cso->offset_line || cso->offset_tri) { 295 SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1); 296 SB_DATA (so, fui(cso->offset_scale)); 297 SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1); 298 SB_DATA (so, fui(cso->offset_units * 2.0f)); 299 SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1); 300 SB_DATA (so, fui(cso->offset_clamp)); 301 } 302 303 if (cso->depth_clip) 304 reg = NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1; 305 else 306 reg = 307 NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1 | 308 NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR | 309 NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR | 310 NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2; 311 312 SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1); 313 SB_DATA (so, reg); 314 315 assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); 316 return (void *)so; 317 } 318 319 static void 320 nvc0_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) 321 { 322 struct nvc0_context *nvc0 = nvc0_context(pipe); 323 324 nvc0->rast = hwcso; 325 nvc0->dirty |= NVC0_NEW_RASTERIZER; 326 } 327 328 static void 329 nvc0_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) 330 { 331 FREE(hwcso); 332 } 333 334 static void * 335 nvc0_zsa_state_create(struct pipe_context *pipe, 336 const struct pipe_depth_stencil_alpha_state *cso) 337 { 338 struct nvc0_zsa_stateobj *so = CALLOC_STRUCT(nvc0_zsa_stateobj); 339 340 so->pipe = *cso; 341 342 SB_IMMED_3D(so, DEPTH_TEST_ENABLE, cso->depth.enabled); 343 if (cso->depth.enabled) { 344 SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask); 345 SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1); 346 SB_DATA (so, nvgl_comparison_op(cso->depth.func)); 347 } 348 349 if (cso->stencil[0].enabled) { 350 SB_BEGIN_3D(so, STENCIL_ENABLE, 5); 351 SB_DATA (so, 1); 352 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op)); 353 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); 354 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); 355 SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func)); 356 SB_BEGIN_3D(so, STENCIL_FRONT_FUNC_MASK, 2); 357 SB_DATA (so, cso->stencil[0].valuemask); 358 SB_DATA (so, cso->stencil[0].writemask); 359 } else { 360 SB_IMMED_3D(so, STENCIL_ENABLE, 0); 361 } 362 363 if (cso->stencil[1].enabled) { 364 assert(cso->stencil[0].enabled); 365 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5); 366 SB_DATA (so, 1); 367 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op)); 368 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); 369 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); 370 SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func)); 371 SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2); 372 SB_DATA (so, cso->stencil[1].writemask); 373 SB_DATA (so, cso->stencil[1].valuemask); 374 } else 375 if (cso->stencil[0].enabled) { 376 SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0); 377 } 378 379 SB_IMMED_3D(so, ALPHA_TEST_ENABLE, cso->alpha.enabled); 380 if (cso->alpha.enabled) { 381 SB_BEGIN_3D(so, ALPHA_TEST_REF, 2); 382 SB_DATA (so, fui(cso->alpha.ref_value)); 383 SB_DATA (so, nvgl_comparison_op(cso->alpha.func)); 384 } 385 386 assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); 387 return (void *)so; 388 } 389 390 static void 391 nvc0_zsa_state_bind(struct pipe_context *pipe, void *hwcso) 392 { 393 struct nvc0_context *nvc0 = nvc0_context(pipe); 394 395 nvc0->zsa = hwcso; 396 nvc0->dirty |= NVC0_NEW_ZSA; 397 } 398 399 static void 400 nvc0_zsa_state_delete(struct pipe_context *pipe, void *hwcso) 401 { 402 FREE(hwcso); 403 } 404 405 /* ====================== SAMPLERS AND TEXTURES ================================ 406 */ 407 408 #define NV50_TSC_WRAP_CASE(n) \ 409 case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n 410 411 static INLINE unsigned 412 nv50_tsc_wrap_mode(unsigned wrap) 413 { 414 switch (wrap) { 415 NV50_TSC_WRAP_CASE(REPEAT); 416 NV50_TSC_WRAP_CASE(MIRROR_REPEAT); 417 NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE); 418 NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER); 419 NV50_TSC_WRAP_CASE(CLAMP); 420 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE); 421 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER); 422 NV50_TSC_WRAP_CASE(MIRROR_CLAMP); 423 default: 424 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); 425 return NV50_TSC_WRAP_REPEAT; 426 } 427 } 428 429 static void 430 nvc0_sampler_state_delete(struct pipe_context *pipe, void *hwcso) 431 { 432 unsigned s, i; 433 434 for (s = 0; s < 5; ++s) 435 for (i = 0; i < nvc0_context(pipe)->num_samplers[s]; ++i) 436 if (nvc0_context(pipe)->samplers[s][i] == hwcso) 437 nvc0_context(pipe)->samplers[s][i] = NULL; 438 439 nvc0_screen_tsc_free(nvc0_context(pipe)->screen, nv50_tsc_entry(hwcso)); 440 441 FREE(hwcso); 442 } 443 444 static INLINE void 445 nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0, int s, 446 unsigned nr, void **hwcso) 447 { 448 unsigned i; 449 450 for (i = 0; i < nr; ++i) { 451 struct nv50_tsc_entry *old = nvc0->samplers[s][i]; 452 453 if (hwcso[i] == old) 454 continue; 455 nvc0->samplers_dirty[s] |= 1 << i; 456 457 nvc0->samplers[s][i] = nv50_tsc_entry(hwcso[i]); 458 if (old) 459 nvc0_screen_tsc_unlock(nvc0->screen, old); 460 } 461 for (; i < nvc0->num_samplers[s]; ++i) { 462 if (nvc0->samplers[s][i]) { 463 nvc0_screen_tsc_unlock(nvc0->screen, nvc0->samplers[s][i]); 464 nvc0->samplers[s][i] = NULL; 465 } 466 } 467 468 nvc0->num_samplers[s] = nr; 469 470 nvc0->dirty |= NVC0_NEW_SAMPLERS; 471 } 472 473 static void 474 nvc0_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 475 { 476 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 0, nr, s); 477 } 478 479 static void 480 nvc0_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 481 { 482 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 4, nr, s); 483 } 484 485 static void 486 nvc0_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 487 { 488 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 3, nr, s); 489 } 490 491 /* NOTE: only called when not referenced anywhere, won't be bound */ 492 static void 493 nvc0_sampler_view_destroy(struct pipe_context *pipe, 494 struct pipe_sampler_view *view) 495 { 496 pipe_resource_reference(&view->texture, NULL); 497 498 nvc0_screen_tic_free(nvc0_context(pipe)->screen, nv50_tic_entry(view)); 499 500 FREE(nv50_tic_entry(view)); 501 } 502 503 static INLINE void 504 nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s, 505 unsigned nr, 506 struct pipe_sampler_view **views) 507 { 508 unsigned i; 509 510 for (i = 0; i < nr; ++i) { 511 struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); 512 513 if (views[i] == nvc0->textures[s][i]) 514 continue; 515 nvc0->textures_dirty[s] |= 1 << i; 516 517 if (old) { 518 nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i)); 519 nvc0_screen_tic_unlock(nvc0->screen, old); 520 } 521 522 pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]); 523 } 524 525 for (i = nr; i < nvc0->num_textures[s]; ++i) { 526 struct nv50_tic_entry *old = nv50_tic_entry(nvc0->textures[s][i]); 527 if (old) { 528 nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(s, i)); 529 nvc0_screen_tic_unlock(nvc0->screen, old); 530 pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); 531 } 532 } 533 534 nvc0->num_textures[s] = nr; 535 536 nvc0->dirty |= NVC0_NEW_TEXTURES; 537 } 538 539 static void 540 nvc0_vp_set_sampler_views(struct pipe_context *pipe, 541 unsigned nr, 542 struct pipe_sampler_view **views) 543 { 544 nvc0_stage_set_sampler_views(nvc0_context(pipe), 0, nr, views); 545 } 546 547 static void 548 nvc0_fp_set_sampler_views(struct pipe_context *pipe, 549 unsigned nr, 550 struct pipe_sampler_view **views) 551 { 552 nvc0_stage_set_sampler_views(nvc0_context(pipe), 4, nr, views); 553 } 554 555 static void 556 nvc0_gp_set_sampler_views(struct pipe_context *pipe, 557 unsigned nr, 558 struct pipe_sampler_view **views) 559 { 560 nvc0_stage_set_sampler_views(nvc0_context(pipe), 3, nr, views); 561 } 562 563 /* ============================= SHADERS ======================================= 564 */ 565 566 static void * 567 nvc0_sp_state_create(struct pipe_context *pipe, 568 const struct pipe_shader_state *cso, unsigned type) 569 { 570 struct nvc0_program *prog; 571 572 prog = CALLOC_STRUCT(nvc0_program); 573 if (!prog) 574 return NULL; 575 576 prog->type = type; 577 578 if (cso->tokens) 579 prog->pipe.tokens = tgsi_dup_tokens(cso->tokens); 580 581 if (cso->stream_output.num_outputs) 582 prog->pipe.stream_output = cso->stream_output; 583 584 return (void *)prog; 585 } 586 587 static void 588 nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso) 589 { 590 struct nvc0_program *prog = (struct nvc0_program *)hwcso; 591 592 nvc0_program_destroy(nvc0_context(pipe), prog); 593 594 FREE((void *)prog->pipe.tokens); 595 FREE(prog); 596 } 597 598 static void * 599 nvc0_vp_state_create(struct pipe_context *pipe, 600 const struct pipe_shader_state *cso) 601 { 602 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX); 603 } 604 605 static void 606 nvc0_vp_state_bind(struct pipe_context *pipe, void *hwcso) 607 { 608 struct nvc0_context *nvc0 = nvc0_context(pipe); 609 610 nvc0->vertprog = hwcso; 611 nvc0->dirty |= NVC0_NEW_VERTPROG; 612 } 613 614 static void * 615 nvc0_fp_state_create(struct pipe_context *pipe, 616 const struct pipe_shader_state *cso) 617 { 618 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT); 619 } 620 621 static void 622 nvc0_fp_state_bind(struct pipe_context *pipe, void *hwcso) 623 { 624 struct nvc0_context *nvc0 = nvc0_context(pipe); 625 626 nvc0->fragprog = hwcso; 627 nvc0->dirty |= NVC0_NEW_FRAGPROG; 628 } 629 630 static void * 631 nvc0_gp_state_create(struct pipe_context *pipe, 632 const struct pipe_shader_state *cso) 633 { 634 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY); 635 } 636 637 static void 638 nvc0_gp_state_bind(struct pipe_context *pipe, void *hwcso) 639 { 640 struct nvc0_context *nvc0 = nvc0_context(pipe); 641 642 nvc0->gmtyprog = hwcso; 643 nvc0->dirty |= NVC0_NEW_GMTYPROG; 644 } 645 646 static void 647 nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, 648 struct pipe_constant_buffer *cb) 649 { 650 struct nvc0_context *nvc0 = nvc0_context(pipe); 651 struct pipe_resource *res = cb ? cb->buffer : NULL; 652 const unsigned s = nvc0_shader_stage(shader); 653 const unsigned i = index; 654 655 if (shader == PIPE_SHADER_COMPUTE) 656 return; 657 658 if (nvc0->constbuf[s][i].user) 659 nvc0->constbuf[s][i].u.buf = NULL; 660 else 661 if (nvc0->constbuf[s][i].u.buf) 662 nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(s, i)); 663 664 pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res); 665 666 nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? TRUE : FALSE; 667 if (nvc0->constbuf[s][i].user) { 668 nvc0->constbuf[s][i].u.data = cb->user_buffer; 669 nvc0->constbuf[s][i].size = cb->buffer_size; 670 } else 671 if (cb) { 672 nvc0->constbuf[s][i].offset = cb->buffer_offset; 673 nvc0->constbuf[s][i].size = align(cb->buffer_size, 0x100); 674 } 675 676 nvc0->constbuf_dirty[s] |= 1 << i; 677 678 nvc0->dirty |= NVC0_NEW_CONSTBUF; 679 } 680 681 /* ============================================================================= 682 */ 683 684 static void 685 nvc0_set_blend_color(struct pipe_context *pipe, 686 const struct pipe_blend_color *bcol) 687 { 688 struct nvc0_context *nvc0 = nvc0_context(pipe); 689 690 nvc0->blend_colour = *bcol; 691 nvc0->dirty |= NVC0_NEW_BLEND_COLOUR; 692 } 693 694 static void 695 nvc0_set_stencil_ref(struct pipe_context *pipe, 696 const struct pipe_stencil_ref *sr) 697 { 698 struct nvc0_context *nvc0 = nvc0_context(pipe); 699 700 nvc0->stencil_ref = *sr; 701 nvc0->dirty |= NVC0_NEW_STENCIL_REF; 702 } 703 704 static void 705 nvc0_set_clip_state(struct pipe_context *pipe, 706 const struct pipe_clip_state *clip) 707 { 708 struct nvc0_context *nvc0 = nvc0_context(pipe); 709 710 memcpy(nvc0->clip.ucp, clip->ucp, sizeof(clip->ucp)); 711 712 nvc0->dirty |= NVC0_NEW_CLIP; 713 } 714 715 static void 716 nvc0_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) 717 { 718 struct nvc0_context *nvc0 = nvc0_context(pipe); 719 720 nvc0->sample_mask = sample_mask; 721 nvc0->dirty |= NVC0_NEW_SAMPLE_MASK; 722 } 723 724 725 static void 726 nvc0_set_framebuffer_state(struct pipe_context *pipe, 727 const struct pipe_framebuffer_state *fb) 728 { 729 struct nvc0_context *nvc0 = nvc0_context(pipe); 730 unsigned i; 731 732 nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB); 733 734 for (i = 0; i < fb->nr_cbufs; ++i) 735 pipe_surface_reference(&nvc0->framebuffer.cbufs[i], fb->cbufs[i]); 736 for (; i < nvc0->framebuffer.nr_cbufs; ++i) 737 pipe_surface_reference(&nvc0->framebuffer.cbufs[i], NULL); 738 739 nvc0->framebuffer.nr_cbufs = fb->nr_cbufs; 740 741 nvc0->framebuffer.width = fb->width; 742 nvc0->framebuffer.height = fb->height; 743 744 pipe_surface_reference(&nvc0->framebuffer.zsbuf, fb->zsbuf); 745 746 nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; 747 } 748 749 static void 750 nvc0_set_polygon_stipple(struct pipe_context *pipe, 751 const struct pipe_poly_stipple *stipple) 752 { 753 struct nvc0_context *nvc0 = nvc0_context(pipe); 754 755 nvc0->stipple = *stipple; 756 nvc0->dirty |= NVC0_NEW_STIPPLE; 757 } 758 759 static void 760 nvc0_set_scissor_state(struct pipe_context *pipe, 761 const struct pipe_scissor_state *scissor) 762 { 763 struct nvc0_context *nvc0 = nvc0_context(pipe); 764 765 nvc0->scissor = *scissor; 766 nvc0->dirty |= NVC0_NEW_SCISSOR; 767 } 768 769 static void 770 nvc0_set_viewport_state(struct pipe_context *pipe, 771 const struct pipe_viewport_state *vpt) 772 { 773 struct nvc0_context *nvc0 = nvc0_context(pipe); 774 775 nvc0->viewport = *vpt; 776 nvc0->dirty |= NVC0_NEW_VIEWPORT; 777 } 778 779 static void 780 nvc0_set_vertex_buffers(struct pipe_context *pipe, 781 unsigned count, 782 const struct pipe_vertex_buffer *vb) 783 { 784 struct nvc0_context *nvc0 = nvc0_context(pipe); 785 uint32_t constant_vbos = 0; 786 unsigned i; 787 788 nvc0->vbo_user = 0; 789 790 if (count != nvc0->num_vtxbufs) { 791 for (i = 0; i < count; ++i) { 792 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, vb[i].buffer); 793 if (vb[i].user_buffer) { 794 nvc0->vbo_user |= 1 << i; 795 nvc0->vtxbuf[i].user_buffer = vb[i].user_buffer; 796 if (!vb[i].stride) 797 constant_vbos |= 1 << i; 798 } else { 799 nvc0->vtxbuf[i].buffer_offset = vb[i].buffer_offset; 800 } 801 nvc0->vtxbuf[i].stride = vb[i].stride; 802 } 803 for (; i < nvc0->num_vtxbufs; ++i) 804 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL); 805 806 nvc0->num_vtxbufs = count; 807 nvc0->dirty |= NVC0_NEW_ARRAYS; 808 } else { 809 for (i = 0; i < count; ++i) { 810 if (vb[i].user_buffer) { 811 nvc0->vtxbuf[i].user_buffer = vb[i].user_buffer; 812 nvc0->vbo_user |= 1 << i; 813 if (!vb[i].stride) 814 constant_vbos |= 1 << i; 815 assert(!vb[i].buffer); 816 } 817 if (nvc0->vtxbuf[i].buffer == vb[i].buffer && 818 nvc0->vtxbuf[i].buffer_offset == vb[i].buffer_offset && 819 nvc0->vtxbuf[i].stride == vb[i].stride) 820 continue; 821 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, vb[i].buffer); 822 nvc0->vtxbuf[i].buffer_offset = vb[i].buffer_offset; 823 nvc0->vtxbuf[i].stride = vb[i].stride; 824 nvc0->dirty |= NVC0_NEW_ARRAYS; 825 } 826 } 827 if (constant_vbos != nvc0->constant_vbos) { 828 nvc0->constant_vbos = constant_vbos; 829 nvc0->dirty |= NVC0_NEW_ARRAYS; 830 } 831 832 if (nvc0->dirty & NVC0_NEW_ARRAYS) 833 nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX); 834 } 835 836 static void 837 nvc0_set_index_buffer(struct pipe_context *pipe, 838 const struct pipe_index_buffer *ib) 839 { 840 struct nvc0_context *nvc0 = nvc0_context(pipe); 841 842 if (nvc0->idxbuf.buffer) 843 nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX); 844 845 if (ib) { 846 pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer); 847 nvc0->idxbuf.index_size = ib->index_size; 848 if (ib->buffer) { 849 nvc0->idxbuf.offset = ib->offset; 850 nvc0->dirty |= NVC0_NEW_IDXBUF; 851 } else { 852 nvc0->idxbuf.user_buffer = ib->user_buffer; 853 nvc0->dirty &= ~NVC0_NEW_IDXBUF; 854 } 855 } else { 856 nvc0->dirty &= ~NVC0_NEW_IDXBUF; 857 pipe_resource_reference(&nvc0->idxbuf.buffer, NULL); 858 } 859 } 860 861 static void 862 nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso) 863 { 864 struct nvc0_context *nvc0 = nvc0_context(pipe); 865 866 nvc0->vertex = hwcso; 867 nvc0->dirty |= NVC0_NEW_VERTEX; 868 } 869 870 static struct pipe_stream_output_target * 871 nvc0_so_target_create(struct pipe_context *pipe, 872 struct pipe_resource *res, 873 unsigned offset, unsigned size) 874 { 875 struct nvc0_so_target *targ = MALLOC_STRUCT(nvc0_so_target); 876 if (!targ) 877 return NULL; 878 879 targ->pq = pipe->create_query(pipe, NVC0_QUERY_TFB_BUFFER_OFFSET); 880 if (!targ->pq) { 881 FREE(targ); 882 return NULL; 883 } 884 targ->clean = TRUE; 885 886 targ->pipe.buffer_size = size; 887 targ->pipe.buffer_offset = offset; 888 targ->pipe.context = pipe; 889 targ->pipe.buffer = NULL; 890 pipe_resource_reference(&targ->pipe.buffer, res); 891 pipe_reference_init(&targ->pipe.reference, 1); 892 893 return &targ->pipe; 894 } 895 896 static void 897 nvc0_so_target_destroy(struct pipe_context *pipe, 898 struct pipe_stream_output_target *ptarg) 899 { 900 struct nvc0_so_target *targ = nvc0_so_target(ptarg); 901 pipe->destroy_query(pipe, targ->pq); 902 pipe_resource_reference(&targ->pipe.buffer, NULL); 903 FREE(targ); 904 } 905 906 static void 907 nvc0_set_transform_feedback_targets(struct pipe_context *pipe, 908 unsigned num_targets, 909 struct pipe_stream_output_target **targets, 910 unsigned append_mask) 911 { 912 struct nvc0_context *nvc0 = nvc0_context(pipe); 913 unsigned i; 914 boolean serialize = TRUE; 915 916 assert(num_targets <= 4); 917 918 for (i = 0; i < num_targets; ++i) { 919 if (nvc0->tfbbuf[i] == targets[i] && (append_mask & (1 << i))) 920 continue; 921 nvc0->tfbbuf_dirty |= 1 << i; 922 923 if (nvc0->tfbbuf[i] && nvc0->tfbbuf[i] != targets[i]) 924 nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize); 925 926 if (targets[i] && !(append_mask & (1 << i))) 927 nvc0_so_target(targets[i])->clean = TRUE; 928 929 pipe_so_target_reference(&nvc0->tfbbuf[i], targets[i]); 930 } 931 for (; i < nvc0->num_tfbbufs; ++i) { 932 nvc0->tfbbuf_dirty |= 1 << i; 933 nvc0_so_target_save_offset(pipe, nvc0->tfbbuf[i], i, &serialize); 934 pipe_so_target_reference(&nvc0->tfbbuf[i], NULL); 935 } 936 nvc0->num_tfbbufs = num_targets; 937 938 if (nvc0->tfbbuf_dirty) 939 nvc0->dirty |= NVC0_NEW_TFB_TARGETS; 940 } 941 942 void 943 nvc0_init_state_functions(struct nvc0_context *nvc0) 944 { 945 struct pipe_context *pipe = &nvc0->base.pipe; 946 947 pipe->create_blend_state = nvc0_blend_state_create; 948 pipe->bind_blend_state = nvc0_blend_state_bind; 949 pipe->delete_blend_state = nvc0_blend_state_delete; 950 951 pipe->create_rasterizer_state = nvc0_rasterizer_state_create; 952 pipe->bind_rasterizer_state = nvc0_rasterizer_state_bind; 953 pipe->delete_rasterizer_state = nvc0_rasterizer_state_delete; 954 955 pipe->create_depth_stencil_alpha_state = nvc0_zsa_state_create; 956 pipe->bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; 957 pipe->delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; 958 959 pipe->create_sampler_state = nv50_sampler_state_create; 960 pipe->delete_sampler_state = nvc0_sampler_state_delete; 961 pipe->bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; 962 pipe->bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; 963 pipe->bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; 964 965 pipe->create_sampler_view = nvc0_create_sampler_view; 966 pipe->sampler_view_destroy = nvc0_sampler_view_destroy; 967 pipe->set_vertex_sampler_views = nvc0_vp_set_sampler_views; 968 pipe->set_fragment_sampler_views = nvc0_fp_set_sampler_views; 969 pipe->set_geometry_sampler_views = nvc0_gp_set_sampler_views; 970 971 pipe->create_vs_state = nvc0_vp_state_create; 972 pipe->create_fs_state = nvc0_fp_state_create; 973 pipe->create_gs_state = nvc0_gp_state_create; 974 pipe->bind_vs_state = nvc0_vp_state_bind; 975 pipe->bind_fs_state = nvc0_fp_state_bind; 976 pipe->bind_gs_state = nvc0_gp_state_bind; 977 pipe->delete_vs_state = nvc0_sp_state_delete; 978 pipe->delete_fs_state = nvc0_sp_state_delete; 979 pipe->delete_gs_state = nvc0_sp_state_delete; 980 981 pipe->set_blend_color = nvc0_set_blend_color; 982 pipe->set_stencil_ref = nvc0_set_stencil_ref; 983 pipe->set_clip_state = nvc0_set_clip_state; 984 pipe->set_sample_mask = nvc0_set_sample_mask; 985 pipe->set_constant_buffer = nvc0_set_constant_buffer; 986 pipe->set_framebuffer_state = nvc0_set_framebuffer_state; 987 pipe->set_polygon_stipple = nvc0_set_polygon_stipple; 988 pipe->set_scissor_state = nvc0_set_scissor_state; 989 pipe->set_viewport_state = nvc0_set_viewport_state; 990 991 pipe->create_vertex_elements_state = nvc0_vertex_state_create; 992 pipe->delete_vertex_elements_state = nvc0_vertex_state_delete; 993 pipe->bind_vertex_elements_state = nvc0_vertex_state_bind; 994 995 pipe->set_vertex_buffers = nvc0_set_vertex_buffers; 996 pipe->set_index_buffer = nvc0_set_index_buffer; 997 998 pipe->create_stream_output_target = nvc0_so_target_create; 999 pipe->stream_output_target_destroy = nvc0_so_target_destroy; 1000 pipe->set_stream_output_targets = nvc0_set_transform_feedback_targets; 1001 } 1002 1003