nv50_screen.c revision 828f545274a6da9b5d05aa23ae31959b121c38a2
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 "pipe/p_screen.h" 24 25#include "nv50_context.h" 26#include "nv50_screen.h" 27 28#include "nouveau/nouveau_stateobj.h" 29 30static boolean 31nv50_screen_is_format_supported(struct pipe_screen *pscreen, 32 enum pipe_format format, 33 enum pipe_texture_target target, 34 unsigned tex_usage, unsigned geom_flags) 35{ 36 if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { 37 switch (format) { 38 case PIPE_FORMAT_X8R8G8B8_UNORM: 39 case PIPE_FORMAT_A8R8G8B8_UNORM: 40 case PIPE_FORMAT_R5G6B5_UNORM: 41 case PIPE_FORMAT_R16G16B16A16_SNORM: 42 case PIPE_FORMAT_R16G16B16A16_UNORM: 43 case PIPE_FORMAT_R32G32B32A32_FLOAT: 44 case PIPE_FORMAT_R16G16_SNORM: 45 case PIPE_FORMAT_R16G16_UNORM: 46 return TRUE; 47 default: 48 break; 49 } 50 } else 51 if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { 52 switch (format) { 53 case PIPE_FORMAT_Z32_FLOAT: 54 case PIPE_FORMAT_Z24S8_UNORM: 55 case PIPE_FORMAT_X8Z24_UNORM: 56 case PIPE_FORMAT_S8Z24_UNORM: 57 return TRUE; 58 default: 59 break; 60 } 61 } else { 62 switch (format) { 63 case PIPE_FORMAT_A8R8G8B8_UNORM: 64 case PIPE_FORMAT_X8R8G8B8_UNORM: 65 case PIPE_FORMAT_A8R8G8B8_SRGB: 66 case PIPE_FORMAT_X8R8G8B8_SRGB: 67 case PIPE_FORMAT_A1R5G5B5_UNORM: 68 case PIPE_FORMAT_A4R4G4B4_UNORM: 69 case PIPE_FORMAT_R5G6B5_UNORM: 70 case PIPE_FORMAT_L8_UNORM: 71 case PIPE_FORMAT_A8_UNORM: 72 case PIPE_FORMAT_I8_UNORM: 73 case PIPE_FORMAT_A8L8_UNORM: 74 case PIPE_FORMAT_DXT1_RGB: 75 case PIPE_FORMAT_DXT1_RGBA: 76 case PIPE_FORMAT_DXT3_RGBA: 77 case PIPE_FORMAT_DXT5_RGBA: 78 case PIPE_FORMAT_Z24S8_UNORM: 79 case PIPE_FORMAT_S8Z24_UNORM: 80 case PIPE_FORMAT_Z32_FLOAT: 81 case PIPE_FORMAT_R16G16B16A16_SNORM: 82 case PIPE_FORMAT_R16G16B16A16_UNORM: 83 case PIPE_FORMAT_R32G32B32A32_FLOAT: 84 case PIPE_FORMAT_R16G16_SNORM: 85 case PIPE_FORMAT_R16G16_UNORM: 86 return TRUE; 87 default: 88 break; 89 } 90 } 91 92 return FALSE; 93} 94 95static int 96nv50_screen_get_param(struct pipe_screen *pscreen, int param) 97{ 98 switch (param) { 99 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 100 return 32; 101 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: 102 return 32; 103 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 104 return 64; 105 case PIPE_CAP_NPOT_TEXTURES: 106 return 1; 107 case PIPE_CAP_TWO_SIDED_STENCIL: 108 return 1; 109 case PIPE_CAP_GLSL: 110 return 0; 111 case PIPE_CAP_ANISOTROPIC_FILTER: 112 return 1; 113 case PIPE_CAP_POINT_SPRITE: 114 return 1; 115 case PIPE_CAP_MAX_RENDER_TARGETS: 116 return 8; 117 case PIPE_CAP_OCCLUSION_QUERY: 118 return 1; 119 case PIPE_CAP_TEXTURE_SHADOW_MAP: 120 return 1; 121 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 122 return 13; 123 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 124 return 10; 125 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 126 return 13; 127 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 128 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: 129 return 1; 130 case PIPE_CAP_TGSI_CONT_SUPPORTED: 131 return 1; 132 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 133 return 1; 134 case NOUVEAU_CAP_HW_VTXBUF: 135 return 1; 136 case NOUVEAU_CAP_HW_IDXBUF: 137 return 1; 138 case PIPE_CAP_INDEP_BLEND_ENABLE: 139 return 1; 140 case PIPE_CAP_INDEP_BLEND_FUNC: 141 return 0; 142 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 143 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 144 return 1; 145 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 146 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 147 return 0; 148 default: 149 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); 150 return 0; 151 } 152} 153 154static float 155nv50_screen_get_paramf(struct pipe_screen *pscreen, int param) 156{ 157 switch (param) { 158 case PIPE_CAP_MAX_LINE_WIDTH: 159 case PIPE_CAP_MAX_LINE_WIDTH_AA: 160 return 10.0; 161 case PIPE_CAP_MAX_POINT_WIDTH: 162 case PIPE_CAP_MAX_POINT_WIDTH_AA: 163 return 64.0; 164 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 165 return 16.0; 166 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 167 return 4.0; 168 default: 169 NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); 170 return 0.0; 171 } 172} 173 174static void 175nv50_screen_destroy(struct pipe_screen *pscreen) 176{ 177 struct nv50_screen *screen = nv50_screen(pscreen); 178 unsigned i; 179 180 for (i = 0; i < 3; i++) { 181 if (screen->constbuf_parm[i]) 182 nouveau_bo_ref(NULL, &screen->constbuf_parm[i]); 183 } 184 185 if (screen->constbuf_misc[0]) 186 nouveau_bo_ref(NULL, &screen->constbuf_misc[0]); 187 if (screen->tic) 188 nouveau_bo_ref(NULL, &screen->tic); 189 if (screen->tsc) 190 nouveau_bo_ref(NULL, &screen->tsc); 191 if (screen->static_init) 192 so_ref(NULL, &screen->static_init); 193 194 nouveau_notifier_free(&screen->sync); 195 nouveau_grobj_free(&screen->tesla); 196 nouveau_grobj_free(&screen->eng2d); 197 nouveau_grobj_free(&screen->m2mf); 198 nouveau_resource_destroy(&screen->immd_heap[0]); 199 nouveau_resource_destroy(&screen->parm_heap[0]); 200 nouveau_resource_destroy(&screen->parm_heap[1]); 201 nouveau_screen_fini(&screen->base); 202 FREE(screen); 203} 204 205static int 206nv50_pre_pipebuffer_map(struct pipe_screen *pscreen, struct pipe_buffer *pb, 207 unsigned usage) 208{ 209 struct nv50_screen *screen = nv50_screen(pscreen); 210 struct nv50_context *ctx = screen->cur_ctx; 211 212 if (!(pb->usage & PIPE_BUFFER_USAGE_VERTEX)) 213 return 0; 214 215 /* Our vtxbuf got mapped, it can no longer be considered part of current 216 * state, remove it to avoid emitting reloc markers. 217 */ 218 if (ctx && ctx->state.vtxbuf && so_bo_is_reloc(ctx->state.vtxbuf, 219 nouveau_bo(pb))) { 220 so_ref(NULL, &ctx->state.vtxbuf); 221 ctx->dirty |= NV50_NEW_ARRAYS; 222 } 223 224 return 0; 225} 226 227struct pipe_screen * 228nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) 229{ 230 struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); 231 struct nouveau_channel *chan; 232 struct pipe_screen *pscreen; 233 struct nouveau_stateobj *so; 234 unsigned chipset = dev->chipset; 235 unsigned tesla_class = 0; 236 int ret, i; 237 238 if (!screen) 239 return NULL; 240 pscreen = &screen->base.base; 241 242 ret = nouveau_screen_init(&screen->base, dev); 243 if (ret) { 244 nv50_screen_destroy(pscreen); 245 return NULL; 246 } 247 chan = screen->base.channel; 248 249 pscreen->winsys = ws; 250 pscreen->destroy = nv50_screen_destroy; 251 pscreen->get_param = nv50_screen_get_param; 252 pscreen->get_paramf = nv50_screen_get_paramf; 253 pscreen->is_format_supported = nv50_screen_is_format_supported; 254 pscreen->context_create = nv50_create; 255 screen->base.pre_pipebuffer_map_callback = nv50_pre_pipebuffer_map; 256 257 nv50_screen_init_miptree_functions(pscreen); 258 nv50_transfer_init_screen_functions(pscreen); 259 260 /* DMA engine object */ 261 ret = nouveau_grobj_alloc(chan, 0xbeef5039, 262 NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf); 263 if (ret) { 264 NOUVEAU_ERR("Error creating M2MF object: %d\n", ret); 265 nv50_screen_destroy(pscreen); 266 return NULL; 267 } 268 269 /* 2D object */ 270 ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d); 271 if (ret) { 272 NOUVEAU_ERR("Error creating 2D object: %d\n", ret); 273 nv50_screen_destroy(pscreen); 274 return NULL; 275 } 276 277 /* 3D object */ 278 switch (chipset & 0xf0) { 279 case 0x50: 280 tesla_class = NV50TCL; 281 break; 282 case 0x80: 283 case 0x90: 284 tesla_class = NV84TCL; 285 break; 286 case 0xa0: 287 switch (chipset) { 288 case 0xa0: 289 case 0xaa: 290 case 0xac: 291 tesla_class = NVA0TCL; 292 break; 293 default: 294 tesla_class = NVA8TCL; 295 break; 296 } 297 break; 298 default: 299 NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset); 300 nv50_screen_destroy(pscreen); 301 return NULL; 302 } 303 304 ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, 305 &screen->tesla); 306 if (ret) { 307 NOUVEAU_ERR("Error creating 3D object: %d\n", ret); 308 nv50_screen_destroy(pscreen); 309 return NULL; 310 } 311 312 /* Sync notifier */ 313 ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); 314 if (ret) { 315 NOUVEAU_ERR("Error creating notifier object: %d\n", ret); 316 nv50_screen_destroy(pscreen); 317 return NULL; 318 } 319 320 /* Static M2MF init */ 321 so = so_new(1, 3, 0); 322 so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); 323 so_data (so, screen->sync->handle); 324 so_data (so, chan->vram->handle); 325 so_data (so, chan->vram->handle); 326 so_emit(chan, so); 327 so_ref (NULL, &so); 328 329 /* Static 2D init */ 330 so = so_new(4, 7, 0); 331 so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4); 332 so_data (so, screen->sync->handle); 333 so_data (so, chan->vram->handle); 334 so_data (so, chan->vram->handle); 335 so_data (so, chan->vram->handle); 336 so_method(so, screen->eng2d, NV50_2D_OPERATION, 1); 337 so_data (so, NV50_2D_OPERATION_SRCCOPY); 338 so_method(so, screen->eng2d, NV50_2D_CLIP_ENABLE, 1); 339 so_data (so, 0); 340 so_method(so, screen->eng2d, 0x0888, 1); 341 so_data (so, 1); 342 so_emit(chan, so); 343 so_ref(NULL, &so); 344 345 /* Static tesla init */ 346 so = so_new(47, 95, 24); 347 348 so_method(so, screen->tesla, NV50TCL_COND_MODE, 1); 349 so_data (so, NV50TCL_COND_MODE_ALWAYS); 350 so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1); 351 so_data (so, screen->sync->handle); 352 so_method(so, screen->tesla, NV50TCL_DMA_ZETA, 11); 353 for (i = 0; i < 11; i++) 354 so_data(so, chan->vram->handle); 355 so_method(so, screen->tesla, NV50TCL_DMA_COLOR(0), 356 NV50TCL_DMA_COLOR__SIZE); 357 for (i = 0; i < NV50TCL_DMA_COLOR__SIZE; i++) 358 so_data(so, chan->vram->handle); 359 so_method(so, screen->tesla, NV50TCL_RT_CONTROL, 1); 360 so_data (so, 1); 361 362 /* activate all 32 lanes (threads) in a warp */ 363 so_method(so, screen->tesla, NV50TCL_WARP_HALVES, 1); 364 so_data (so, 0x2); 365 so_method(so, screen->tesla, 0x1400, 1); 366 so_data (so, 0xf); 367 368 /* max TIC (bits 4:8) & TSC (ignored) bindings, per program type */ 369 for (i = 0; i < 3; ++i) { 370 so_method(so, screen->tesla, NV50TCL_TEX_LIMITS(i), 1); 371 so_data (so, 0x54); 372 } 373 374 /* origin is top left (set to 1 for bottom left) */ 375 so_method(so, screen->tesla, NV50TCL_Y_ORIGIN_BOTTOM, 1); 376 so_data (so, 0); 377 so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1); 378 so_data (so, 8); 379 380 /* constant buffers for immediates and VP/FP parameters */ 381 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (32 * 4) * 4, 382 &screen->constbuf_misc[0]); 383 if (ret) { 384 nv50_screen_destroy(pscreen); 385 return NULL; 386 } 387 388 for (i = 0; i < 3; i++) { 389 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, (256 * 4) * 4, 390 &screen->constbuf_parm[i]); 391 if (ret) { 392 nv50_screen_destroy(pscreen); 393 return NULL; 394 } 395 } 396 397 if (nouveau_resource_init(&screen->immd_heap[0], 0, 128) || 398 nouveau_resource_init(&screen->parm_heap[0], 0, 512) || 399 nouveau_resource_init(&screen->parm_heap[1], 0, 512)) 400 { 401 NOUVEAU_ERR("Error initialising constant buffers.\n"); 402 nv50_screen_destroy(pscreen); 403 return NULL; 404 } 405 406 /* 407 // map constant buffers: 408 // B = buffer ID (maybe more than 1 byte) 409 // N = CB index used in shader instruction 410 // P = program type (0 = VP, 2 = GP, 3 = FP) 411 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 412 so_data (so, 0x000BBNP1); 413 */ 414 415 so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 416 so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM | 417 NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); 418 so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM | 419 NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); 420 so_data (so, (NV50_CB_PMISC << 16) | 0x00000200); 421 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 422 so_data (so, 0x00000001 | (NV50_CB_PMISC << 12)); 423 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 424 so_data (so, 0x00000021 | (NV50_CB_PMISC << 12)); 425 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 426 so_data (so, 0x00000031 | (NV50_CB_PMISC << 12)); 427 428 /* bind auxiliary constbuf to immediate data bo */ 429 so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 430 so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4, 431 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); 432 so_reloc (so, screen->constbuf_misc[0], (128 * 4) * 4, 433 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); 434 so_data (so, (NV50_CB_AUX << 16) | 0x00000200); 435 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 436 so_data (so, 0x00000201 | (NV50_CB_AUX << 12)); 437 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 438 so_data (so, 0x00000221 | (NV50_CB_AUX << 12)); 439 440 so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 441 so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0, 442 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); 443 so_reloc (so, screen->constbuf_parm[PIPE_SHADER_VERTEX], 0, 444 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); 445 so_data (so, (NV50_CB_PVP << 16) | 0x00000800); 446 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 447 so_data (so, 0x00000101 | (NV50_CB_PVP << 12)); 448 449 so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 450 so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0, 451 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); 452 so_reloc (so, screen->constbuf_parm[PIPE_SHADER_GEOMETRY], 0, 453 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); 454 so_data (so, (NV50_CB_PGP << 16) | 0x00000800); 455 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 456 so_data (so, 0x00000121 | (NV50_CB_PGP << 12)); 457 458 so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3); 459 so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0, 460 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); 461 so_reloc (so, screen->constbuf_parm[PIPE_SHADER_FRAGMENT], 0, 462 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); 463 so_data (so, (NV50_CB_PFP << 16) | 0x00000800); 464 so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1); 465 so_data (so, 0x00000131 | (NV50_CB_PFP << 12)); 466 467 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32, 468 &screen->tic); 469 if (ret) { 470 nv50_screen_destroy(pscreen); 471 return NULL; 472 } 473 474 so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3); 475 so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | 476 NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); 477 so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM | 478 NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); 479 so_data (so, PIPE_SHADER_TYPES * 32 - 1); 480 481 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32, 482 &screen->tsc); 483 if (ret) { 484 nv50_screen_destroy(pscreen); 485 return NULL; 486 } 487 488 so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3); 489 so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | 490 NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0); 491 so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM | 492 NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); 493 so_data (so, 0x00000000); /* ignored if TSC_LINKED (0x1234) = 1 */ 494 495 496 /* Vertex array limits - max them out */ 497 for (i = 0; i < 16; i++) { 498 so_method(so, screen->tesla, NV50TCL_VERTEX_ARRAY_LIMIT_HIGH(i), 2); 499 so_data (so, 0x000000ff); 500 so_data (so, 0xffffffff); 501 } 502 503 so_method(so, screen->tesla, NV50TCL_DEPTH_RANGE_NEAR(0), 2); 504 so_data (so, fui(0.0)); 505 so_data (so, fui(1.0)); 506 507 /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */ 508 so_method(so, screen->tesla, NV50TCL_LINKED_TSC, 1); 509 so_data (so, 1); 510 511 /* activate first scissor rectangle */ 512 so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE(0), 1); 513 so_data (so, 1); 514 515 so_method(so, screen->tesla, NV50TCL_EDGEFLAG_ENABLE, 1); 516 so_data (so, 1); /* default edgeflag to TRUE */ 517 518 so_emit(chan, so); 519 so_ref (so, &screen->static_init); 520 so_ref (NULL, &so); 521 nouveau_pushbuf_flush(chan, 0); 522 523 return pscreen; 524} 525 526