nv50_screen.c revision 4c1e7d931dd6e5676297bee23932cc6d66c93cac
1/* 2 * Copyright 2008 Ben Skeggs 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 "util/u_format_s3tc.h" 24#include "pipe/p_screen.h" 25 26#include "nv50_context.h" 27#include "nv50_screen.h" 28#include "nv50_resource.h" 29#include "nv50_program.h" 30 31#include "nouveau/nouveau_stateobj.h" 32 33static boolean 34nv50_screen_is_format_supported(struct pipe_screen *pscreen, 35 enum pipe_format format, 36 enum pipe_texture_target target, 37 unsigned sample_count, 38 unsigned usage, unsigned geom_flags) 39{ 40 if (sample_count > 1) 41 return FALSE; 42 43 if (!util_format_s3tc_enabled) { 44 switch (format) { 45 case PIPE_FORMAT_DXT1_RGB: 46 case PIPE_FORMAT_DXT1_RGBA: 47 case PIPE_FORMAT_DXT3_RGBA: 48 case PIPE_FORMAT_DXT5_RGBA: 49 return FALSE; 50 default: 51 break; 52 } 53 } 54 55 switch (format) { 56 case PIPE_FORMAT_Z16_UNORM: 57 if ((nouveau_screen(pscreen)->device->chipset & 0xf0) != 0xa0) 58 return FALSE; 59 break; 60 default: 61 break; 62 } 63 64 /* transfers & shared are always supported */ 65 usage &= ~(PIPE_BIND_TRANSFER_READ | 66 PIPE_BIND_TRANSFER_WRITE | 67 PIPE_BIND_SHARED); 68 69 return (nv50_format_table[format].usage & usage) == usage; 70} 71 72static int 73nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 74{ 75 switch (param) { 76 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 77 return 32; 78 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: 79 return 32; 80 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 81 return 64; 82 case PIPE_CAP_NPOT_TEXTURES: 83 return 1; 84 case PIPE_CAP_TWO_SIDED_STENCIL: 85 return 1; 86 case PIPE_CAP_GLSL: 87 return 1; 88 case PIPE_CAP_ANISOTROPIC_FILTER: 89 return 1; 90 case PIPE_CAP_POINT_SPRITE: 91 return 1; 92 case PIPE_CAP_MAX_RENDER_TARGETS: 93 return 8; 94 case PIPE_CAP_OCCLUSION_QUERY: 95 return 1; 96 case PIPE_CAP_TIMER_QUERY: 97 return 0; 98 case PIPE_CAP_TEXTURE_SHADOW_MAP: 99 return 1; 100 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 101 return 13; 102 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 103 return 10; 104 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 105 return 13; 106 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 107 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: 108 return 1; 109 case PIPE_CAP_TEXTURE_SWIZZLE: 110 return 1; 111 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 112 return 1; 113 case PIPE_CAP_INDEP_BLEND_ENABLE: 114 return 1; 115 case PIPE_CAP_INDEP_BLEND_FUNC: 116 return 0; 117 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 118 return 1; 119 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 120 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 121 return 1; 122 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 123 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 124 return 0; 125 case PIPE_CAP_DEPTH_CLAMP: 126 return 1; 127 default: 128 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); 129 return 0; 130 } 131} 132 133static int 134nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 135 enum pipe_shader_cap param) 136{ 137 switch(shader) { 138 case PIPE_SHADER_FRAGMENT: 139 case PIPE_SHADER_VERTEX: 140 case PIPE_SHADER_GEOMETRY: 141 break; 142 default: 143 return 0; 144 } 145 146 switch(param) { 147 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 148 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 149 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 150 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: /* arbitrary limit */ 151 return 16384; 152 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: /* need stack bo */ 153 return 4; 154 case PIPE_SHADER_CAP_MAX_INPUTS: /* 128 / 4 with GP */ 155 if (shader == PIPE_SHADER_GEOMETRY) 156 return 128 / 4; 157 else 158 return 64 / 4; 159 case PIPE_SHADER_CAP_MAX_CONSTS: 160 return 65536 / 16; 161 case PIPE_SHADER_CAP_MAX_ADDRS: /* no spilling atm */ 162 return 1; 163 case PIPE_SHADER_CAP_MAX_PREDS: /* not yet handled */ 164 return 0; 165 case PIPE_SHADER_CAP_MAX_TEMPS: /* no spilling atm */ 166 return NV50_CAP_MAX_PROGRAM_TEMPS; 167 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 168 return 1; 169 default: 170 return 0; 171 } 172} 173 174static float 175nv50_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param) 176{ 177 switch (param) { 178 case PIPE_CAP_MAX_LINE_WIDTH: 179 case PIPE_CAP_MAX_LINE_WIDTH_AA: 180 return 10.0; 181 case PIPE_CAP_MAX_POINT_WIDTH: 182 case PIPE_CAP_MAX_POINT_WIDTH_AA: 183 return 64.0; 184 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 185 return 16.0; 186 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 187 return 4.0; 188 default: 189 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); 190 return 0.0; 191 } 192} 193 194static void 195nv50_screen_destroy(struct pipe_screen *pscreen) 196{ 197 struct nv50_screen *screen = nv50_screen(pscreen); 198 unsigned i; 199 200 for (i = 0; i < 3; i++) { 201 if (screen->constbuf_parm[i]) 202 nouveau_bo_ref(NULL, &screen->constbuf_parm[i]); 203 } 204 205 if (screen->constbuf_misc[0]) 206 nouveau_bo_ref(NULL, &screen->constbuf_misc[0]); 207 if (screen->tic) 208 nouveau_bo_ref(NULL, &screen->tic); 209 if (screen->tsc) 210 nouveau_bo_ref(NULL, &screen->tsc); 211 212 nouveau_notifier_free(&screen->sync); 213 nouveau_grobj_free(&screen->tesla); 214 nouveau_grobj_free(&screen->eng2d); 215 nouveau_grobj_free(&screen->m2mf); 216 nouveau_resource_destroy(&screen->immd_heap); 217 nouveau_screen_fini(&screen->base); 218 FREE(screen); 219} 220 221#define BGN_RELOC(ch, bo, gr, m, n, fl) \ 222 OUT_RELOC(ch, bo, (n << 18) | (gr->subc << 13) | m, fl, 0, 0) 223 224void 225nv50_screen_reloc_constbuf(struct nv50_screen *screen, unsigned cbi) 226{ 227 struct nouveau_bo *bo; 228 struct nouveau_channel *chan = screen->base.channel; 229 struct nouveau_grobj *tesla = screen->tesla; 230 unsigned size; 231 const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY; 232 233 switch (cbi) { 234 case NV50_CB_PMISC: 235 bo = screen->constbuf_misc[0]; 236 size = 0x200; 237 break; 238 case NV50_CB_PVP: 239 case NV50_CB_PFP: 240 case NV50_CB_PGP: 241 bo = screen->constbuf_parm[cbi - NV50_CB_PVP]; 242 size = 0; 243 break; 244 default: 245 return; 246 } 247 248 BGN_RELOC (chan, bo, tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl); 249 OUT_RELOCh(chan, bo, 0, rl); 250 OUT_RELOCl(chan, bo, 0, rl); 251 OUT_RELOC (chan, bo, (cbi << 16) | size, rl, 0, 0); 252} 253 254void 255nv50_screen_relocs(struct nv50_screen *screen) 256{ 257 struct nouveau_channel *chan = screen->base.channel; 258 struct nouveau_grobj *tesla = screen->tesla; 259 unsigned i; 260 const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY; 261 262 MARK_RING (chan, 28, 26); 263 264 /* cause grobj autobind */ 265 BEGIN_RING(chan, tesla, 0x0100, 1); 266 OUT_RING (chan, 0); 267 268 BGN_RELOC (chan, screen->tic, tesla, NV50TCL_TIC_ADDRESS_HIGH, 2, rl); 269 OUT_RELOCh(chan, screen->tic, 0, rl); 270 OUT_RELOCl(chan, screen->tic, 0, rl); 271 272 BGN_RELOC (chan, screen->tsc, tesla, NV50TCL_TSC_ADDRESS_HIGH, 2, rl); 273 OUT_RELOCh(chan, screen->tsc, 0, rl); 274 OUT_RELOCl(chan, screen->tsc, 0, rl); 275 276 nv50_screen_reloc_constbuf(screen, NV50_CB_PMISC); 277 278 BGN_RELOC (chan, screen->constbuf_misc[0], 279 tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3, rl); 280 OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl); 281 OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl); 282 OUT_RELOC (chan, screen->constbuf_misc[0], 283 (NV50_CB_AUX << 16) | 0x0200, rl, 0, 0); 284 285 for (i = 0; i < 3; ++i) 286 nv50_screen_reloc_constbuf(screen, NV50_CB_PVP + i); 287 288 BGN_RELOC (chan, screen->stack_bo, 289 tesla, NV50TCL_STACK_ADDRESS_HIGH, 2, rl); 290 OUT_RELOCh(chan, screen->stack_bo, 0, rl); 291 OUT_RELOCl(chan, screen->stack_bo, 0, rl); 292 293 if (!screen->cur_ctx->req_lmem) 294 return; 295 296 BGN_RELOC (chan, screen->local_bo, 297 tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 2, rl); 298 OUT_RELOCh(chan, screen->local_bo, 0, rl); 299 OUT_RELOCl(chan, screen->local_bo, 0, rl); 300} 301 302#ifndef NOUVEAU_GETPARAM_GRAPH_UNITS 303# define NOUVEAU_GETPARAM_GRAPH_UNITS 13 304#endif 305 306extern int nouveau_device_get_param(struct nouveau_device *dev, 307 uint64_t param, uint64_t *value); 308 309struct pipe_screen * 310nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) 311{ 312 struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); 313 struct nouveau_channel *chan; 314 struct pipe_screen *pscreen; 315 uint64_t value; 316 unsigned chipset = dev->chipset; 317 unsigned tesla_class = 0; 318 unsigned stack_size, local_size, max_warps; 319 int ret, i; 320 const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; 321 322 if (!screen) 323 return NULL; 324 pscreen = &screen->base.base; 325 326 ret = nouveau_screen_init(&screen->base, dev); 327 if (ret) { 328 nv50_screen_destroy(pscreen); 329 return NULL; 330 } 331 chan = screen->base.channel; 332 333 pscreen->winsys = ws; 334 pscreen->destroy = nv50_screen_destroy; 335 pscreen->get_param = nv50_screen_get_param; 336 pscreen->get_shader_param = nv50_screen_get_shader_param; 337 pscreen->get_paramf = nv50_screen_get_paramf; 338 pscreen->is_format_supported = nv50_screen_is_format_supported; 339 pscreen->context_create = nv50_create; 340 341 nv50_screen_init_resource_functions(pscreen); 342 343 /* DMA engine object */ 344 ret = nouveau_grobj_alloc(chan, 0xbeef5039, 345 NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf); 346 if (ret) { 347 NOUVEAU_ERR("Error creating M2MF object: %d\n", ret); 348 nv50_screen_destroy(pscreen); 349 return NULL; 350 } 351 352 /* 2D object */ 353 ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); 354 if (ret) { 355 NOUVEAU_ERR("Error creating 2D object: %d\n", ret); 356 nv50_screen_destroy(pscreen); 357 return NULL; 358 } 359 360 /* 3D object */ 361 switch (chipset & 0xf0) { 362 case 0x50: 363 tesla_class = NV50TCL; 364 break; 365 case 0x80: 366 case 0x90: 367 tesla_class = NV84TCL; 368 break; 369 case 0xa0: 370 switch (chipset) { 371 case 0xa0: 372 case 0xaa: 373 case 0xac: 374 tesla_class = NVA0TCL; 375 break; 376 default: 377 tesla_class = NVA8TCL; 378 break; 379 } 380 break; 381 default: 382 NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset); 383 nv50_screen_destroy(pscreen); 384 return NULL; 385 } 386 387 ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, 388 &screen->tesla); 389 if (ret) { 390 NOUVEAU_ERR("Error creating 3D object: %d\n", ret); 391 nv50_screen_destroy(pscreen); 392 return NULL; 393 } 394 395 /* this is necessary for the new RING_3D / statebuffer code */ 396 BIND_RING(chan, screen->tesla, 7); 397 398 /* Sync notifier */ 399 ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); 400 if (ret) { 401 NOUVEAU_ERR("Error creating notifier object: %d\n", ret); 402 nv50_screen_destroy(pscreen); 403 return NULL; 404 } 405 406 /* Static M2MF init */ 407 BEGIN_RING(chan, screen->m2mf, 408 NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); 409 OUT_RING (chan, screen->sync->handle); 410 OUT_RING (chan, chan->vram->handle); 411 OUT_RING (chan, chan->vram->handle); 412 413 /* Static 2D init */ 414 BEGIN_RING(chan, screen->eng2d, NV50_2D_DMA_NOTIFY, 4); 415 OUT_RING (chan, screen->sync->handle); 416 OUT_RING (chan, chan->vram->handle); 417 OUT_RING (chan, chan->vram->handle); 418 OUT_RING (chan, chan->vram->handle); 419 BEGIN_RING(chan, screen->eng2d, NV50_2D_OPERATION, 1); 420 OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY); 421 BEGIN_RING(chan, screen->eng2d, NV50_2D_CLIP_ENABLE, 1); 422 OUT_RING (chan, 0); 423 BEGIN_RING(chan, screen->eng2d, 0x0888, 1); 424 OUT_RING (chan, 1); 425 426 /* Static tesla init */ 427 BEGIN_RING(chan, screen->tesla, NV50TCL_COND_MODE, 1); 428 OUT_RING (chan, NV50TCL_COND_MODE_ALWAYS); 429 BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_NOTIFY, 1); 430 OUT_RING (chan, screen->sync->handle); 431 BEGIN_RING(chan, screen->tesla, NV50TCL_DMA_ZETA, 11); 432 for (i = 0; i < 11; i++) 433 OUT_RING (chan, chan->vram->handle); 434 BEGIN_RING(chan, screen->tesla, 435 NV50TCL_DMA_COLOR(0), NV50TCL_DMA_COLOR__SIZE); 436 for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++) 437 OUT_RING (chan, chan->vram->handle); 438 439 BEGIN_RING(chan, screen->tesla, NV50TCL_RT_CONTROL, 1); 440 OUT_RING (chan, 1); 441 442 /* activate all 32 lanes (threads) in a warp */ 443 BEGIN_RING(chan, screen->tesla, NV50TCL_REG_MODE, 1); 444 OUT_RING (chan, NV50TCL_REG_MODE_STRIPED); 445 BEGIN_RING(chan, screen->tesla, 0x1400, 1); 446 OUT_RING (chan, 0xf); 447 448 /* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */ 449 for (i = 0; i < 3; ++i) { 450 BEGIN_RING(chan, screen->tesla, NV50TCL_TEX_LIMITS(i), 1); 451 OUT_RING (chan, 0x54); 452 } 453 454 /* origin is top left (set to 1 for bottom left) */ 455 BEGIN_RING(chan, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1); 456 OUT_RING (chan, 0); 457 BEGIN_RING(chan, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); 458 OUT_RING (chan, 8); 459 460 /* constant buffers for immediates and VP/FP parameters */ 461 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4, 462 &screen->constbuf_misc[0]); 463 if (ret) { 464 nv50_screen_destroy(pscreen); 465 return NULL; 466 } 467 BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 468 OUT_RELOCh(chan, screen->constbuf_misc[0], 0, rl); 469 OUT_RELOCl(chan, screen->constbuf_misc[0], 0, rl); 470 OUT_RING (chan, (NV50_CB_PMISC << 16) | 0x0200); 471 BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 472 OUT_RELOCh(chan, screen->constbuf_misc[0], 0x200, rl); 473 OUT_RELOCl(chan, screen->constbuf_misc[0], 0x200, rl); 474 OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200); 475 476 for (i = 0; i < 3; i++) { 477 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (4096 * 4) * 4, 478 &screen->constbuf_parm[i]); 479 if (ret) { 480 nv50_screen_destroy(pscreen); 481 return NULL; 482 } 483 BEGIN_RING(chan, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 484 OUT_RELOCh(chan, screen->constbuf_parm[i], 0, rl); 485 OUT_RELOCl(chan, screen->constbuf_parm[i], 0, rl); 486 /* CB_DEF_SET_SIZE value of 0x0000 means 65536 */ 487 OUT_RING (chan, ((NV50_CB_PVP + i) << 16) | 0x0000); 488 } 489 490 if (nouveau_resource_init(&screen->immd_heap, 0, 128)) { 491 NOUVEAU_ERR("Error initialising shader immediates heap.\n"); 492 nv50_screen_destroy(pscreen); 493 return NULL; 494 } 495 496 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4), 497 &screen->tic); 498 if (ret) { 499 nv50_screen_destroy(pscreen); 500 return NULL; 501 } 502 BEGIN_RING(chan, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3); 503 OUT_RELOCh(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 504 OUT_RELOCl(chan, screen->tic, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 505 OUT_RING (chan, 3 * 32 - 1); 506 507 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4), 508 &screen->tsc); 509 if (ret) { 510 nv50_screen_destroy(pscreen); 511 return NULL; 512 } 513 BEGIN_RING(chan, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3); 514 OUT_RELOCh(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 515 OUT_RELOCl(chan, screen->tsc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 516 OUT_RING (chan, 0); /* ignored if TSC_LINKED (0x1234) == 1 */ 517 518 /* map constant buffers: 519 * B = buffer ID (maybe more than 1 byte) 520 * N = CB index used in shader instruction 521 * P = program type (0 = VP, 2 = GP, 3 = FP) 522 * SET_PROGRAM_CB = 0x000BBNP1 523 */ 524 BEGIN_RING_NI(chan, screen->tesla, NV50TCL_SET_PROGRAM_CB, 8); 525 /* bind immediate buffer */ 526 OUT_RING (chan, 0x001 | (NV50_CB_PMISC << 12)); 527 OUT_RING (chan, 0x021 | (NV50_CB_PMISC << 12)); 528 OUT_RING (chan, 0x031 | (NV50_CB_PMISC << 12)); 529 /* bind auxiliary constbuf to immediate data bo */ 530 OUT_RING (chan, 0x201 | (NV50_CB_AUX << 12)); 531 OUT_RING (chan, 0x221 | (NV50_CB_AUX << 12)); 532 /* bind parameter buffers */ 533 OUT_RING (chan, 0x101 | (NV50_CB_PVP << 12)); 534 OUT_RING (chan, 0x121 | (NV50_CB_PGP << 12)); 535 OUT_RING (chan, 0x131 | (NV50_CB_PFP << 12)); 536 537 /* shader stack */ 538 nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value); 539 540 max_warps = util_bitcount(value & 0xffff); 541 max_warps *= util_bitcount((value >> 24) & 0xf) * 32; 542 543 stack_size = max_warps * 64 * 8; 544 545 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 546 stack_size, &screen->stack_bo); 547 if (ret) { 548 nv50_screen_destroy(pscreen); 549 return NULL; 550 } 551 BEGIN_RING(chan, screen->tesla, NV50TCL_STACK_ADDRESS_HIGH, 3); 552 OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 553 OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 554 OUT_RING (chan, 4); 555 556 local_size = (NV50_CAP_MAX_PROGRAM_TEMPS * 16) * max_warps * 32; 557 558 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 559 local_size, &screen->local_bo); 560 if (ret) { 561 nv50_screen_destroy(pscreen); 562 return NULL; 563 } 564 565 local_size = NV50_CAP_MAX_PROGRAM_TEMPS * 16; 566 567 BEGIN_RING(chan, screen->tesla, NV50TCL_LOCAL_ADDRESS_HIGH, 3); 568 OUT_RELOCh(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 569 OUT_RELOCl(chan, screen->local_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 570 OUT_RING (chan, util_unsigned_logbase2(local_size / 8)); 571 572 /* Vertex array limits - max them out */ 573 for (i = 0; i < 16; i++) { 574 BEGIN_RING(chan, screen->tesla, 575 NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2); 576 OUT_RING (chan, 0x000000ff); 577 OUT_RING (chan, 0xffffffff); 578 } 579 580 BEGIN_RING(chan, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2); 581 OUT_RINGf (chan, 0.0f); 582 OUT_RINGf (chan, 1.0f); 583 584 BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1); 585 OUT_RING (chan, 1); 586 587 /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */ 588 BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1); 589 OUT_RING (chan, 1); 590 591 BEGIN_RING(chan, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1); 592 OUT_RING (chan, 1); /* default edgeflag to TRUE */ 593 594 FIRE_RING (chan); 595 596 screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE); 597 if(!screen->force_push) 598 screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART; 599 return pscreen; 600} 601 602