nvc0_state.c revision 293a8d1b600cd5bd89b3c4c0b6c2bb245d9bd80f
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_texture.xml.h" 34 35#include "nouveau/nouveau_gldefs.h" 36 37static INLINE uint32_t 38nvc0_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 54static INLINE uint32_t 55nvc0_blend_fac(unsigned factor) 56{ 57 static const uint16_t bf[] = { 58 NV50_3D_BLEND_FACTOR_ZERO, /* 0x00 */ 59 NV50_3D_BLEND_FACTOR_ONE, 60 NV50_3D_BLEND_FACTOR_SRC_COLOR, 61 NV50_3D_BLEND_FACTOR_SRC_ALPHA, 62 NV50_3D_BLEND_FACTOR_DST_ALPHA, 63 NV50_3D_BLEND_FACTOR_DST_COLOR, 64 NV50_3D_BLEND_FACTOR_SRC_ALPHA_SATURATE, 65 NV50_3D_BLEND_FACTOR_CONSTANT_COLOR, 66 NV50_3D_BLEND_FACTOR_CONSTANT_ALPHA, 67 NV50_3D_BLEND_FACTOR_SRC1_COLOR, 68 NV50_3D_BLEND_FACTOR_SRC1_ALPHA, 69 NV50_3D_BLEND_FACTOR_ZERO, /* 0x0b */ 70 NV50_3D_BLEND_FACTOR_ZERO, /* 0x0c */ 71 NV50_3D_BLEND_FACTOR_ZERO, /* 0x0d */ 72 NV50_3D_BLEND_FACTOR_ZERO, /* 0x0e */ 73 NV50_3D_BLEND_FACTOR_ZERO, /* 0x0f */ 74 NV50_3D_BLEND_FACTOR_ZERO, /* 0x10 */ 75 NV50_3D_BLEND_FACTOR_ZERO, /* 0x11 */ 76 NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, 77 NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, 78 NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, 79 NV50_3D_BLEND_FACTOR_ONE_MINUS_DST_COLOR, 80 NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, 81 NV50_3D_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, 82 NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, 83 NV50_3D_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA 84 }; 85 86 assert(factor < (sizeof(bf) / sizeof(bf[0]))); 87 return bf[factor]; 88} 89 90static void * 91nvc0_blend_state_create(struct pipe_context *pipe, 92 const struct pipe_blend_state *cso) 93{ 94 struct nvc0_blend_stateobj *so = CALLOC_STRUCT(nvc0_blend_stateobj); 95 int i; 96 97 so->pipe = *cso; 98 99 SB_IMMED_3D(so, BLEND_INDEPENDENT, cso->independent_blend_enable); 100 101 if (!cso->independent_blend_enable) { 102 SB_BEGIN_3D(so, BLEND_ENABLES, 1); 103 SB_DATA (so, cso->rt[0].blend_enable ? 0xff : 0); 104 105 if (cso->rt[0].blend_enable) { 106 SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); 107 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); 108 SB_DATA (so, nvc0_blend_fac(cso->rt[0].rgb_src_factor)); 109 SB_DATA (so, nvc0_blend_fac(cso->rt[0].rgb_dst_factor)); 110 SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); 111 SB_DATA (so, nvc0_blend_fac(cso->rt[0].alpha_src_factor)); 112 SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); 113 SB_DATA (so, nvc0_blend_fac(cso->rt[0].alpha_dst_factor)); 114 } 115 116 SB_BEGIN_3D(so, COLOR_MASK_BROADCAST, 1); 117 SB_DATA (so, nvc0_colormask(cso->rt[0].colormask)); 118 } else { 119 uint8_t en = 0; 120 121 for (i = 0; i < 8; ++i) { 122 if (!cso->rt[i].blend_enable) 123 continue; 124 en |= 1 << i; 125 126 SB_BEGIN_3D(so, IBLEND_EQUATION_RGB(i), 6); 127 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); 128 SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_src_factor)); 129 SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_dst_factor)); 130 SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); 131 SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_src_factor)); 132 SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_dst_factor)); 133 } 134 SB_BEGIN_3D(so, BLEND_ENABLES, 1); 135 SB_DATA (so, en); 136 137 SB_BEGIN_3D(so, COLOR_MASK(0), 8); 138 for (i = 0; i < 8; ++i) 139 SB_DATA(so, nvc0_colormask(cso->rt[i].colormask)); 140 } 141 142 if (cso->logicop_enable) { 143 SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); 144 SB_DATA (so, 1); 145 SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); 146 } else { 147 SB_IMMED_3D(so, LOGIC_OP_ENABLE, 0); 148 } 149 150 assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); 151 return so; 152} 153 154static void 155nvc0_blend_state_bind(struct pipe_context *pipe, void *hwcso) 156{ 157 struct nvc0_context *nvc0 = nvc0_context(pipe); 158 159 nvc0->blend = hwcso; 160 nvc0->dirty |= NVC0_NEW_BLEND; 161} 162 163static void 164nvc0_blend_state_delete(struct pipe_context *pipe, void *hwcso) 165{ 166 FREE(hwcso); 167} 168 169static void * 170nvc0_rasterizer_state_create(struct pipe_context *pipe, 171 const struct pipe_rasterizer_state *cso) 172{ 173 struct nvc0_rasterizer_stateobj *so; 174 175 so = CALLOC_STRUCT(nvc0_rasterizer_stateobj); 176 if (!so) 177 return NULL; 178 so->pipe = *cso; 179 180#ifndef NVC0_SCISSORS_CLIPPING 181 SB_IMMED_3D(so, SCISSOR_ENABLE(0), cso->scissor); 182#endif 183 184 SB_BEGIN_3D(so, SHADE_MODEL, 1); 185 SB_DATA (so, cso->flatshade ? NVC0_3D_SHADE_MODEL_FLAT : 186 NVC0_3D_SHADE_MODEL_SMOOTH); 187 SB_IMMED_3D(so, PROVOKING_VERTEX_LAST, !cso->flatshade_first); 188 SB_IMMED_3D(so, VERTEX_TWO_SIDE_ENABLE, cso->light_twoside); 189 190 SB_BEGIN_3D(so, LINE_WIDTH, 1); 191 SB_DATA (so, fui(cso->line_width)); 192 SB_IMMED_3D(so, LINE_SMOOTH_ENABLE, cso->line_smooth); 193 194 SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1); 195 if (cso->line_stipple_enable) { 196 SB_DATA (so, 1); 197 SB_BEGIN_3D(so, LINE_STIPPLE_PATTERN, 1); 198 SB_DATA (so, (cso->line_stipple_pattern << 8) | 199 cso->line_stipple_factor); 200 201 } else { 202 SB_DATA (so, 0); 203 } 204 205 SB_IMMED_3D(so, VP_POINT_SIZE_EN, cso->point_size_per_vertex); 206 if (!cso->point_size_per_vertex) { 207 SB_BEGIN_3D(so, POINT_SIZE, 1); 208 SB_DATA (so, fui(cso->point_size)); 209 } 210 SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization); 211 SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth); 212 213 SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 1); 214 SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); 215 SB_BEGIN_3D(so, POLYGON_MODE_BACK, 1); 216 SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); 217 SB_IMMED_3D(so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth); 218 219 SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3); 220 SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); 221 SB_DATA (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW : 222 NVC0_3D_FRONT_FACE_CW); 223 switch (cso->cull_face) { 224 case PIPE_FACE_FRONT_AND_BACK: 225 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK); 226 break; 227 case PIPE_FACE_FRONT: 228 SB_DATA(so, NVC0_3D_CULL_FACE_FRONT); 229 break; 230 case PIPE_FACE_BACK: 231 default: 232 SB_DATA(so, NVC0_3D_CULL_FACE_BACK); 233 break; 234 } 235 236 SB_IMMED_3D(so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable); 237 SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3); 238 SB_DATA (so, cso->offset_point); 239 SB_DATA (so, cso->offset_line); 240 SB_DATA (so, cso->offset_tri); 241 242 if (cso->offset_point || cso->offset_line || cso->offset_tri) { 243 SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1); 244 SB_DATA (so, fui(cso->offset_scale)); 245 SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1); 246 SB_DATA (so, fui(cso->offset_units)); /* XXX: multiply by 2 ? */ 247 } 248 249 assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); 250 return (void *)so; 251} 252 253static void 254nvc0_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) 255{ 256 struct nvc0_context *nvc0 = nvc0_context(pipe); 257 258 nvc0->rast = hwcso; 259 nvc0->dirty |= NVC0_NEW_RASTERIZER; 260} 261 262static void 263nvc0_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) 264{ 265 FREE(hwcso); 266} 267 268static void * 269nvc0_zsa_state_create(struct pipe_context *pipe, 270 const struct pipe_depth_stencil_alpha_state *cso) 271{ 272 struct nvc0_zsa_stateobj *so = CALLOC_STRUCT(nvc0_zsa_stateobj); 273 274 so->pipe = *cso; 275 276 SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask); 277 SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1); 278 if (cso->depth.enabled) { 279 SB_DATA (so, 1); 280 SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1); 281 SB_DATA (so, nvgl_comparison_op(cso->depth.func)); 282 } else { 283 SB_DATA (so, 0); 284 } 285 286 if (cso->stencil[0].enabled) { 287 SB_BEGIN_3D(so, STENCIL_ENABLE, 5); 288 SB_DATA (so, 1); 289 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op)); 290 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); 291 SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); 292 SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func)); 293 SB_BEGIN_3D(so, STENCIL_FRONT_FUNC_MASK, 2); 294 SB_DATA (so, cso->stencil[0].valuemask); 295 SB_DATA (so, cso->stencil[0].writemask); 296 } else { 297 SB_IMMED_3D(so, STENCIL_ENABLE, 0); 298 } 299 300 if (cso->stencil[1].enabled) { 301 assert(cso->stencil[0].enabled); 302 SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5); 303 SB_DATA (so, 1); 304 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op)); 305 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); 306 SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); 307 SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func)); 308 SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2); 309 SB_DATA (so, cso->stencil[1].writemask); 310 SB_DATA (so, cso->stencil[1].valuemask); 311 } else 312 if (cso->stencil[0].enabled) { 313 SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0); 314 } 315 316 SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1); 317 if (cso->alpha.enabled) { 318 SB_DATA (so, 1); 319 SB_BEGIN_3D(so, ALPHA_TEST_REF, 2); 320 SB_DATA (so, fui(cso->alpha.ref_value)); 321 SB_DATA (so, nvgl_comparison_op(cso->alpha.func)); 322 } else { 323 SB_DATA (so, 0); 324 } 325 326 assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); 327 return (void *)so; 328} 329 330static void 331nvc0_zsa_state_bind(struct pipe_context *pipe, void *hwcso) 332{ 333 struct nvc0_context *nvc0 = nvc0_context(pipe); 334 335 nvc0->zsa = hwcso; 336 nvc0->dirty |= NVC0_NEW_ZSA; 337} 338 339static void 340nvc0_zsa_state_delete(struct pipe_context *pipe, void *hwcso) 341{ 342 FREE(hwcso); 343} 344 345/* ====================== SAMPLERS AND TEXTURES ================================ 346 */ 347 348#define NV50_TSC_WRAP_CASE(n) \ 349 case PIPE_TEX_WRAP_##n: return NV50_TSC_WRAP_##n 350 351static INLINE unsigned 352nv50_tsc_wrap_mode(unsigned wrap) 353{ 354 switch (wrap) { 355 NV50_TSC_WRAP_CASE(REPEAT); 356 NV50_TSC_WRAP_CASE(MIRROR_REPEAT); 357 NV50_TSC_WRAP_CASE(CLAMP_TO_EDGE); 358 NV50_TSC_WRAP_CASE(CLAMP_TO_BORDER); 359 NV50_TSC_WRAP_CASE(CLAMP); 360 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_EDGE); 361 NV50_TSC_WRAP_CASE(MIRROR_CLAMP_TO_BORDER); 362 NV50_TSC_WRAP_CASE(MIRROR_CLAMP); 363 default: 364 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); 365 return NV50_TSC_WRAP_REPEAT; 366 } 367} 368 369static void * 370nvc0_sampler_state_create(struct pipe_context *pipe, 371 const struct pipe_sampler_state *cso) 372{ 373 struct nvc0_tsc_entry *so = CALLOC_STRUCT(nvc0_tsc_entry); 374 float f[2]; 375 376 so->id = -1; 377 378 so->tsc[0] = (0x00026000 | 379 (nv50_tsc_wrap_mode(cso->wrap_s) << 0) | 380 (nv50_tsc_wrap_mode(cso->wrap_t) << 3) | 381 (nv50_tsc_wrap_mode(cso->wrap_r) << 6)); 382 383 switch (cso->mag_img_filter) { 384 case PIPE_TEX_FILTER_LINEAR: 385 so->tsc[1] |= NV50_TSC_1_MAGF_LINEAR; 386 break; 387 case PIPE_TEX_FILTER_NEAREST: 388 default: 389 so->tsc[1] |= NV50_TSC_1_MAGF_NEAREST; 390 break; 391 } 392 393 switch (cso->min_img_filter) { 394 case PIPE_TEX_FILTER_LINEAR: 395 so->tsc[1] |= NV50_TSC_1_MINF_LINEAR; 396 break; 397 case PIPE_TEX_FILTER_NEAREST: 398 default: 399 so->tsc[1] |= NV50_TSC_1_MINF_NEAREST; 400 break; 401 } 402 403 switch (cso->min_mip_filter) { 404 case PIPE_TEX_MIPFILTER_LINEAR: 405 so->tsc[1] |= NV50_TSC_1_MIPF_LINEAR; 406 break; 407 case PIPE_TEX_MIPFILTER_NEAREST: 408 so->tsc[1] |= NV50_TSC_1_MIPF_NEAREST; 409 break; 410 case PIPE_TEX_MIPFILTER_NONE: 411 default: 412 so->tsc[1] |= NV50_TSC_1_MIPF_NONE; 413 break; 414 } 415 416 if (cso->max_anisotropy >= 16) 417 so->tsc[0] |= (7 << 20); 418 else 419 if (cso->max_anisotropy >= 12) 420 so->tsc[0] |= (6 << 20); 421 else { 422 so->tsc[0] |= (cso->max_anisotropy >> 1) << 20; 423 424 if (cso->max_anisotropy >= 4) 425 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_35; 426 else 427 if (cso->max_anisotropy >= 2) 428 so->tsc[1] |= NV50_TSC_1_UNKN_ANISO_15; 429 } 430 431 if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { 432 /* NOTE: must be deactivated for non-shadow textures */ 433 so->tsc[0] |= (1 << 9); 434 so->tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7) << 10; 435 } 436 437 f[0] = CLAMP(cso->lod_bias, -16.0f, 15.0f); 438 so->tsc[1] |= ((int)(f[0] * 256.0f) & 0x1fff) << 12; 439 440 f[0] = CLAMP(cso->min_lod, 0.0f, 15.0f); 441 f[1] = CLAMP(cso->max_lod, 0.0f, 15.0f); 442 so->tsc[2] |= 443 (((int)(f[1] * 256.0f) & 0xfff) << 12) | ((int)(f[0] * 256.0f) & 0xfff); 444 445 so->tsc[4] = fui(cso->border_color[0]); 446 so->tsc[5] = fui(cso->border_color[1]); 447 so->tsc[6] = fui(cso->border_color[2]); 448 so->tsc[7] = fui(cso->border_color[3]); 449 450 return (void *)so; 451} 452 453static void 454nvc0_sampler_state_delete(struct pipe_context *pipe, void *hwcso) 455{ 456 unsigned s, i; 457 458 for (s = 0; s < 5; ++s) 459 for (i = 0; i < nvc0_context(pipe)->num_samplers[s]; ++i) 460 if (nvc0_context(pipe)->samplers[s][i] == hwcso) 461 nvc0_context(pipe)->samplers[s][i] = NULL; 462 463 nvc0_screen_tsc_free(nvc0_context(pipe)->screen, nvc0_tsc_entry(hwcso)); 464 465 FREE(hwcso); 466} 467 468static INLINE void 469nvc0_stage_sampler_states_bind(struct nvc0_context *nvc0, int s, 470 unsigned nr, void **hwcso) 471{ 472 unsigned i; 473 474 for (i = 0; i < nr; ++i) { 475 struct nvc0_tsc_entry *old = nvc0->samplers[s][i]; 476 477 nvc0->samplers[s][i] = nvc0_tsc_entry(hwcso[i]); 478 if (old) 479 nvc0_screen_tsc_unlock(nvc0->screen, old); 480 } 481 for (; i < nvc0->num_samplers[s]; ++i) 482 if (nvc0->samplers[s][i]) 483 nvc0_screen_tsc_unlock(nvc0->screen, nvc0->samplers[s][i]); 484 485 nvc0->num_samplers[s] = nr; 486 487 nvc0->dirty |= NVC0_NEW_SAMPLERS; 488} 489 490static void 491nvc0_vp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 492{ 493 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 0, nr, s); 494} 495 496static void 497nvc0_fp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 498{ 499 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 4, nr, s); 500} 501 502static void 503nvc0_gp_sampler_states_bind(struct pipe_context *pipe, unsigned nr, void **s) 504{ 505 nvc0_stage_sampler_states_bind(nvc0_context(pipe), 3, nr, s); 506} 507 508/* NOTE: only called when not referenced anywhere, won't be bound */ 509static void 510nvc0_sampler_view_destroy(struct pipe_context *pipe, 511 struct pipe_sampler_view *view) 512{ 513 pipe_resource_reference(&view->texture, NULL); 514 515 nvc0_screen_tic_free(nvc0_context(pipe)->screen, nvc0_tic_entry(view)); 516 517 FREE(nvc0_tic_entry(view)); 518} 519 520static INLINE void 521nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s, 522 unsigned nr, 523 struct pipe_sampler_view **views) 524{ 525 unsigned i; 526 527 for (i = 0; i < nr; ++i) { 528 struct nvc0_tic_entry *old = nvc0_tic_entry(nvc0->textures[s][i]); 529 if (old) 530 nvc0_screen_tic_unlock(nvc0->screen, old); 531 532 pipe_sampler_view_reference(&nvc0->textures[s][i], views[i]); 533 } 534 535 for (i = nr; i < nvc0->num_textures[s]; ++i) { 536 struct nvc0_tic_entry *old = nvc0_tic_entry(nvc0->textures[s][i]); 537 if (!old) 538 continue; 539 nvc0_screen_tic_unlock(nvc0->screen, old); 540 541 pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); 542 } 543 544 nvc0->num_textures[s] = nr; 545 546 nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES); 547 548 nvc0->dirty |= NVC0_NEW_TEXTURES; 549} 550 551static void 552nvc0_vp_set_sampler_views(struct pipe_context *pipe, 553 unsigned nr, 554 struct pipe_sampler_view **views) 555{ 556 nvc0_stage_set_sampler_views(nvc0_context(pipe), 0, nr, views); 557} 558 559static void 560nvc0_fp_set_sampler_views(struct pipe_context *pipe, 561 unsigned nr, 562 struct pipe_sampler_view **views) 563{ 564 nvc0_stage_set_sampler_views(nvc0_context(pipe), 4, nr, views); 565} 566 567static void 568nvc0_gp_set_sampler_views(struct pipe_context *pipe, 569 unsigned nr, 570 struct pipe_sampler_view **views) 571{ 572 nvc0_stage_set_sampler_views(nvc0_context(pipe), 3, nr, views); 573} 574 575/* ============================= SHADERS ======================================= 576 */ 577 578static void * 579nvc0_sp_state_create(struct pipe_context *pipe, 580 const struct pipe_shader_state *cso, unsigned type) 581{ 582 struct nvc0_program *prog; 583 584 prog = CALLOC_STRUCT(nvc0_program); 585 if (!prog) 586 return NULL; 587 588 prog->type = type; 589 prog->pipe.tokens = tgsi_dup_tokens(cso->tokens); 590 591 return (void *)prog; 592} 593 594static void 595nvc0_sp_state_delete(struct pipe_context *pipe, void *hwcso) 596{ 597 struct nvc0_program *prog = (struct nvc0_program *)hwcso; 598 599 nvc0_program_destroy(nvc0_context(pipe), prog); 600 601 FREE((void *)prog->pipe.tokens); 602 FREE(prog); 603} 604 605static void * 606nvc0_vp_state_create(struct pipe_context *pipe, 607 const struct pipe_shader_state *cso) 608{ 609 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_VERTEX); 610} 611 612static void 613nvc0_vp_state_bind(struct pipe_context *pipe, void *hwcso) 614{ 615 struct nvc0_context *nvc0 = nvc0_context(pipe); 616 617 nvc0->vertprog = hwcso; 618 nvc0->dirty |= NVC0_NEW_VERTPROG; 619} 620 621static void * 622nvc0_fp_state_create(struct pipe_context *pipe, 623 const struct pipe_shader_state *cso) 624{ 625 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_FRAGMENT); 626} 627 628static void 629nvc0_fp_state_bind(struct pipe_context *pipe, void *hwcso) 630{ 631 struct nvc0_context *nvc0 = nvc0_context(pipe); 632 633 nvc0->fragprog = hwcso; 634 nvc0->dirty |= NVC0_NEW_FRAGPROG; 635} 636 637static void * 638nvc0_gp_state_create(struct pipe_context *pipe, 639 const struct pipe_shader_state *cso) 640{ 641 return nvc0_sp_state_create(pipe, cso, PIPE_SHADER_GEOMETRY); 642} 643 644static void 645nvc0_gp_state_bind(struct pipe_context *pipe, void *hwcso) 646{ 647 struct nvc0_context *nvc0 = nvc0_context(pipe); 648 649 nvc0->gmtyprog = hwcso; 650 nvc0->dirty |= NVC0_NEW_GMTYPROG; 651} 652 653static void 654nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, 655 struct pipe_resource *res) 656{ 657 struct nvc0_context *nvc0 = nvc0_context(pipe); 658 659 switch (shader) { 660 case PIPE_SHADER_VERTEX: shader = 0; break; 661 /* 662 case PIPE_SHADER_TESSELLATION_CONTROL: shader = 1; break; 663 case PIPE_SHADER_TESSELLATION_EVALUATION: shader = 2; break; 664 */ 665 case PIPE_SHADER_GEOMETRY: shader = 3; break; 666 case PIPE_SHADER_FRAGMENT: shader = 4; break; 667 default: 668 assert(0); 669 break; 670 } 671 672 if (nvc0->constbuf[shader][index]) 673 nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT, 674 nvc0_resource( 675 nvc0->constbuf[shader][index])); 676 677 pipe_resource_reference(&nvc0->constbuf[shader][index], res); 678 679 nvc0->constbuf_dirty[shader] |= 1 << index; 680 681 nvc0->dirty |= NVC0_NEW_CONSTBUF; 682} 683 684/* ============================================================================= 685 */ 686 687static void 688nvc0_set_blend_color(struct pipe_context *pipe, 689 const struct pipe_blend_color *bcol) 690{ 691 struct nvc0_context *nvc0 = nvc0_context(pipe); 692 693 nvc0->blend_colour = *bcol; 694 nvc0->dirty |= NVC0_NEW_BLEND_COLOUR; 695} 696 697static void 698nvc0_set_stencil_ref(struct pipe_context *pipe, 699 const struct pipe_stencil_ref *sr) 700{ 701 struct nvc0_context *nvc0 = nvc0_context(pipe); 702 703 nvc0->stencil_ref = *sr; 704 nvc0->dirty |= NVC0_NEW_STENCIL_REF; 705} 706 707static void 708nvc0_set_clip_state(struct pipe_context *pipe, 709 const struct pipe_clip_state *clip) 710{ 711 struct nvc0_context *nvc0 = nvc0_context(pipe); 712 const unsigned size = clip->nr * sizeof(clip->ucp[0]); 713 714 memcpy(&nvc0->clip.ucp[0][0], &clip->ucp[0][0], size); 715 nvc0->clip.nr = clip->nr; 716 717 nvc0->clip.depth_clamp = clip->depth_clamp; 718 719 nvc0->dirty |= NVC0_NEW_CLIP; 720} 721 722static void 723nvc0_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) 724{ 725 struct nvc0_context *nvc0 = nvc0_context(pipe); 726 727 nvc0->sample_mask = sample_mask; 728 nvc0->dirty |= NVC0_NEW_SAMPLE_MASK; 729} 730 731 732static void 733nvc0_set_framebuffer_state(struct pipe_context *pipe, 734 const struct pipe_framebuffer_state *fb) 735{ 736 struct nvc0_context *nvc0 = nvc0_context(pipe); 737 738 nvc0->framebuffer = *fb; 739 nvc0->dirty |= NVC0_NEW_FRAMEBUFFER; 740} 741 742static void 743nvc0_set_polygon_stipple(struct pipe_context *pipe, 744 const struct pipe_poly_stipple *stipple) 745{ 746 struct nvc0_context *nvc0 = nvc0_context(pipe); 747 748 nvc0->stipple = *stipple; 749 nvc0->dirty |= NVC0_NEW_STIPPLE; 750} 751 752static void 753nvc0_set_scissor_state(struct pipe_context *pipe, 754 const struct pipe_scissor_state *scissor) 755{ 756 struct nvc0_context *nvc0 = nvc0_context(pipe); 757 758 nvc0->scissor = *scissor; 759 nvc0->dirty |= NVC0_NEW_SCISSOR; 760} 761 762static void 763nvc0_set_viewport_state(struct pipe_context *pipe, 764 const struct pipe_viewport_state *vpt) 765{ 766 struct nvc0_context *nvc0 = nvc0_context(pipe); 767 768 nvc0->viewport = *vpt; 769 nvc0->dirty |= NVC0_NEW_VIEWPORT; 770} 771 772static void 773nvc0_set_vertex_buffers(struct pipe_context *pipe, 774 unsigned count, 775 const struct pipe_vertex_buffer *vb) 776{ 777 struct nvc0_context *nvc0 = nvc0_context(pipe); 778 unsigned i; 779 780 for (i = 0; i < count; ++i) 781 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, vb[i].buffer); 782 for (; i < nvc0->num_vtxbufs; ++i) 783 pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL); 784 785 memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count); 786 nvc0->num_vtxbufs = count; 787 788 nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX); 789 790 nvc0->dirty |= NVC0_NEW_ARRAYS; 791} 792 793static void 794nvc0_set_index_buffer(struct pipe_context *pipe, 795 const struct pipe_index_buffer *ib) 796{ 797 struct nvc0_context *nvc0 = nvc0_context(pipe); 798 799 if (ib) 800 memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf)); 801 else 802 nvc0->idxbuf.buffer = NULL; 803} 804 805static void 806nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso) 807{ 808 struct nvc0_context *nvc0 = nvc0_context(pipe); 809 810 nvc0->vertex = hwcso; 811 nvc0->dirty |= NVC0_NEW_VERTEX; 812} 813 814static void * 815nvc0_tfb_state_create(struct pipe_context *pipe, 816 const struct pipe_stream_output_state *pso) 817{ 818 struct nvc0_transform_feedback_state *so; 819 int n = 0; 820 int i, c, b; 821 822 so = MALLOC(sizeof(*so) + pso->num_outputs * 4 * sizeof(uint8_t)); 823 if (!so) 824 return NULL; 825 826 for (b = 0; b < 4; ++b) { 827 for (i = 0; i < pso->num_outputs; ++i) { 828 if (pso->output_buffer[i] != b) 829 continue; 830 for (c = 0; c < 4; ++c) { 831 if (!(pso->register_mask[i] & (1 << c))) 832 continue; 833 so->varying_count[b]++; 834 so->varying_index[n++] = (pso->register_index[i] << 2) | c; 835 } 836 } 837 so->stride[b] = so->varying_count[b] * 4; 838 } 839 if (pso->stride) 840 so->stride[0] = pso->stride; 841 842 return so; 843} 844 845static void 846nvc0_tfb_state_delete(struct pipe_context *pipe, void *hwcso) 847{ 848 FREE(hwcso); 849} 850 851static void 852nvc0_tfb_state_bind(struct pipe_context *pipe, void *hwcso) 853{ 854 nvc0_context(pipe)->tfb = hwcso; 855 nvc0_context(pipe)->dirty |= NVC0_NEW_TFB; 856} 857 858static void 859nvc0_set_transform_feedback_buffers(struct pipe_context *pipe, 860 struct pipe_resource **buffers, 861 int *offsets, 862 int num_buffers) 863{ 864 struct nvc0_context *nvc0 = nvc0_context(pipe); 865 int i; 866 867 assert(num_buffers >= 0 && num_buffers <= 4); /* why signed ? */ 868 869 for (i = 0; i < num_buffers; ++i) { 870 assert(offsets[i] >= 0); 871 nvc0->tfb_offset[i] = offsets[i]; 872 pipe_resource_reference(&nvc0->tfbbuf[i], buffers[i]); 873 } 874 for (; i < nvc0->num_tfbbufs; ++i) 875 pipe_resource_reference(&nvc0->tfbbuf[i], NULL); 876 877 nvc0->num_tfbbufs = num_buffers; 878 879 nvc0->dirty |= NVC0_NEW_TFB_BUFFERS; 880} 881 882void 883nvc0_init_state_functions(struct nvc0_context *nvc0) 884{ 885 nvc0->pipe.create_blend_state = nvc0_blend_state_create; 886 nvc0->pipe.bind_blend_state = nvc0_blend_state_bind; 887 nvc0->pipe.delete_blend_state = nvc0_blend_state_delete; 888 889 nvc0->pipe.create_rasterizer_state = nvc0_rasterizer_state_create; 890 nvc0->pipe.bind_rasterizer_state = nvc0_rasterizer_state_bind; 891 nvc0->pipe.delete_rasterizer_state = nvc0_rasterizer_state_delete; 892 893 nvc0->pipe.create_depth_stencil_alpha_state = nvc0_zsa_state_create; 894 nvc0->pipe.bind_depth_stencil_alpha_state = nvc0_zsa_state_bind; 895 nvc0->pipe.delete_depth_stencil_alpha_state = nvc0_zsa_state_delete; 896 897 nvc0->pipe.create_sampler_state = nvc0_sampler_state_create; 898 nvc0->pipe.delete_sampler_state = nvc0_sampler_state_delete; 899 nvc0->pipe.bind_vertex_sampler_states = nvc0_vp_sampler_states_bind; 900 nvc0->pipe.bind_fragment_sampler_states = nvc0_fp_sampler_states_bind; 901 nvc0->pipe.bind_geometry_sampler_states = nvc0_gp_sampler_states_bind; 902 903 nvc0->pipe.create_sampler_view = nvc0_create_sampler_view; 904 nvc0->pipe.sampler_view_destroy = nvc0_sampler_view_destroy; 905 nvc0->pipe.set_vertex_sampler_views = nvc0_vp_set_sampler_views; 906 nvc0->pipe.set_fragment_sampler_views = nvc0_fp_set_sampler_views; 907 nvc0->pipe.set_geometry_sampler_views = nvc0_gp_set_sampler_views; 908 909 nvc0->pipe.create_vs_state = nvc0_vp_state_create; 910 nvc0->pipe.create_fs_state = nvc0_fp_state_create; 911 nvc0->pipe.create_gs_state = nvc0_gp_state_create; 912 nvc0->pipe.bind_vs_state = nvc0_vp_state_bind; 913 nvc0->pipe.bind_fs_state = nvc0_fp_state_bind; 914 nvc0->pipe.bind_gs_state = nvc0_gp_state_bind; 915 nvc0->pipe.delete_vs_state = nvc0_sp_state_delete; 916 nvc0->pipe.delete_fs_state = nvc0_sp_state_delete; 917 nvc0->pipe.delete_gs_state = nvc0_sp_state_delete; 918 919 nvc0->pipe.set_blend_color = nvc0_set_blend_color; 920 nvc0->pipe.set_stencil_ref = nvc0_set_stencil_ref; 921 nvc0->pipe.set_clip_state = nvc0_set_clip_state; 922 nvc0->pipe.set_sample_mask = nvc0_set_sample_mask; 923 nvc0->pipe.set_constant_buffer = nvc0_set_constant_buffer; 924 nvc0->pipe.set_framebuffer_state = nvc0_set_framebuffer_state; 925 nvc0->pipe.set_polygon_stipple = nvc0_set_polygon_stipple; 926 nvc0->pipe.set_scissor_state = nvc0_set_scissor_state; 927 nvc0->pipe.set_viewport_state = nvc0_set_viewport_state; 928 929 nvc0->pipe.create_vertex_elements_state = nvc0_vertex_state_create; 930 nvc0->pipe.delete_vertex_elements_state = nvc0_vertex_state_delete; 931 nvc0->pipe.bind_vertex_elements_state = nvc0_vertex_state_bind; 932 933 nvc0->pipe.set_vertex_buffers = nvc0_set_vertex_buffers; 934 nvc0->pipe.set_index_buffer = nvc0_set_index_buffer; 935 936 nvc0->pipe.create_stream_output_state = nvc0_tfb_state_create; 937 nvc0->pipe.delete_stream_output_state = nvc0_tfb_state_delete; 938 nvc0->pipe.bind_stream_output_state = nvc0_tfb_state_bind; 939 nvc0->pipe.set_stream_output_buffers = nvc0_set_transform_feedback_buffers; 940 941 nvc0->pipe.redefine_user_buffer = u_default_redefine_user_buffer; 942} 943 944