nvc0_screen.c revision 0c1db2feb9c2f5c9a2ef486053b6e9dcd9860b3e
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 "util/u_format_s3tc.h" 24#include "pipe/p_screen.h" 25 26#include "nvc0_fence.h" 27#include "nvc0_context.h" 28#include "nvc0_screen.h" 29 30#include "nouveau/nv_object.xml.h" 31#include "nvc0_graph_macros.h" 32 33static boolean 34nvc0_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 bindings, 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 /* transfers & shared are always supported */ 56 bindings &= ~(PIPE_BIND_TRANSFER_READ | 57 PIPE_BIND_TRANSFER_WRITE | 58 PIPE_BIND_SHARED); 59 60 return (nvc0_format_table[format].usage & bindings) == bindings; 61} 62 63static int 64nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 65{ 66 switch (param) { 67 case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: 68 case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: 69 return 32; 70 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 71 return 64; 72 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 73 return 13; 74 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 75 return 10; 76 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 77 return 13; 78 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 79 case PIPE_CAP_TEXTURE_MIRROR_REPEAT: 80 case PIPE_CAP_TEXTURE_SWIZZLE: 81 case PIPE_CAP_TEXTURE_SHADOW_MAP: 82 case PIPE_CAP_NPOT_TEXTURES: 83 case PIPE_CAP_ANISOTROPIC_FILTER: 84 return 1; 85 case PIPE_CAP_TWO_SIDED_STENCIL: 86 case PIPE_CAP_DEPTH_CLAMP: 87 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 88 case PIPE_CAP_POINT_SPRITE: 89 return 1; 90 case PIPE_CAP_GLSL: 91 case PIPE_CAP_SM3: 92 return 1; 93 case PIPE_CAP_MAX_RENDER_TARGETS: 94 return 8; 95 case PIPE_CAP_TIMER_QUERY: 96 case PIPE_CAP_OCCLUSION_QUERY: 97 return 1; 98 case PIPE_CAP_STREAM_OUTPUT: 99 return 0; 100 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 101 case PIPE_CAP_INDEP_BLEND_ENABLE: 102 case PIPE_CAP_INDEP_BLEND_FUNC: 103 return 1; 104 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 105 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 106 return 1; 107 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 108 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 109 return 0; 110 case PIPE_CAP_SHADER_STENCIL_EXPORT: 111 return 0; 112 case PIPE_CAP_PRIMITIVE_RESTART: 113 return 1; 114 default: 115 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); 116 return 0; 117 } 118} 119 120static int 121nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 122 enum pipe_shader_cap param) 123{ 124 switch (shader) { 125 case PIPE_SHADER_VERTEX: 126 /* 127 case PIPE_SHADER_TESSELLATION_CONTROL: 128 case PIPE_SHADER_TESSELLATION_EVALUATION: 129 */ 130 case PIPE_SHADER_GEOMETRY: 131 case PIPE_SHADER_FRAGMENT: 132 break; 133 default: 134 return 0; 135 } 136 137 switch (param) { 138 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 139 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 140 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 141 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 142 return 16384; 143 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 144 return 4; 145 case PIPE_SHADER_CAP_MAX_INPUTS: 146 if (shader == PIPE_SHADER_VERTEX) 147 return 32; 148 return 0x300 / 16; 149 case PIPE_SHADER_CAP_MAX_CONSTS: 150 return 65536 / 16; 151 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 152 return 14; 153 case PIPE_SHADER_CAP_MAX_ADDRS: 154 return 1; 155 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 156 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 157 return shader != PIPE_SHADER_FRAGMENT; 158 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 159 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 160 return 1; 161 case PIPE_SHADER_CAP_MAX_PREDS: 162 return 0; 163 case PIPE_SHADER_CAP_MAX_TEMPS: 164 return NVC0_CAP_MAX_PROGRAM_TEMPS; 165 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 166 return 1; 167 case PIPE_SHADER_CAP_SUBROUTINES: 168 return 0; /* please inline, or provide function declarations */ 169 default: 170 NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param); 171 return 0; 172 } 173} 174 175static float 176nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param) 177{ 178 switch (param) { 179 case PIPE_CAP_MAX_LINE_WIDTH: 180 case PIPE_CAP_MAX_LINE_WIDTH_AA: 181 return 10.0f; 182 case PIPE_CAP_MAX_POINT_WIDTH: 183 case PIPE_CAP_MAX_POINT_WIDTH_AA: 184 return 64.0f; 185 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 186 return 16.0f; 187 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 188 return 4.0f; 189 default: 190 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); 191 return 0.0f; 192 } 193} 194 195static void 196nvc0_screen_destroy(struct pipe_screen *pscreen) 197{ 198 struct nvc0_screen *screen = nvc0_screen(pscreen); 199 200 nvc0_fence_wait(screen->fence.current); 201 nvc0_fence_reference(&screen->fence.current, NULL); 202 203 nouveau_bo_ref(NULL, &screen->text); 204 nouveau_bo_ref(NULL, &screen->tls); 205 nouveau_bo_ref(NULL, &screen->txc); 206 nouveau_bo_ref(NULL, &screen->fence.bo); 207 nouveau_bo_ref(NULL, &screen->mp_stack_bo); 208 209 nouveau_resource_destroy(&screen->text_heap); 210 211 if (screen->tic.entries) 212 FREE(screen->tic.entries); 213 214 nvc0_mm_destroy(screen->mm_GART); 215 nvc0_mm_destroy(screen->mm_VRAM); 216 nvc0_mm_destroy(screen->mm_VRAM_fe0); 217 218 nouveau_grobj_free(&screen->fermi); 219 nouveau_grobj_free(&screen->eng2d); 220 nouveau_grobj_free(&screen->m2mf); 221 222 nouveau_screen_fini(&screen->base); 223 224 FREE(screen); 225} 226 227static int 228nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos, 229 unsigned size, const uint32_t *data) 230{ 231 struct nouveau_channel *chan = screen->base.channel; 232 233 size /= 4; 234 235 BEGIN_RING(chan, RING_3D_(NVC0_GRAPH_MACRO_ID), 2); 236 OUT_RING (chan, (m - 0x3800) / 8); 237 OUT_RING (chan, pos); 238 BEGIN_RING_1I(chan, RING_3D_(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1); 239 OUT_RING (chan, pos); 240 OUT_RINGp (chan, data, size); 241 242 return pos + size; 243} 244 245static void 246nvc0_screen_fence_reference(struct pipe_screen *pscreen, 247 struct pipe_fence_handle **ptr, 248 struct pipe_fence_handle *fence) 249{ 250 nvc0_fence_reference((struct nvc0_fence **)ptr, nvc0_fence(fence)); 251} 252 253static int 254nvc0_screen_fence_signalled(struct pipe_screen *pscreen, 255 struct pipe_fence_handle *fence, 256 unsigned flags) 257{ 258 return !(nvc0_fence_signalled(nvc0_fence(fence))); 259} 260 261static int 262nvc0_screen_fence_finish(struct pipe_screen *pscreen, 263 struct pipe_fence_handle *fence, 264 unsigned flags) 265{ 266 return nvc0_fence_wait((struct nvc0_fence *)fence) != TRUE; 267} 268 269static void 270nvc0_magic_3d_init(struct nouveau_channel *chan) 271{ 272 BEGIN_RING(chan, RING_3D_(0x10cc), 1); 273 OUT_RING (chan, 0xff); 274 BEGIN_RING(chan, RING_3D_(0x10e0), 2); 275 OUT_RING(chan, 0xff); 276 OUT_RING(chan, 0xff); 277 BEGIN_RING(chan, RING_3D_(0x10ec), 2); 278 OUT_RING(chan, 0xff); 279 OUT_RING(chan, 0xff); 280 BEGIN_RING(chan, RING_3D_(0x074c), 1); 281 OUT_RING (chan, 0x3f); 282 283 BEGIN_RING(chan, RING_3D_(0x10f8), 1); 284 OUT_RING (chan, 0x0101); 285 286 BEGIN_RING(chan, RING_3D_(0x16a8), 1); 287 OUT_RING (chan, (3 << 16) | 3); 288 BEGIN_RING(chan, RING_3D_(0x1794), 1); 289 OUT_RING (chan, (2 << 16) | 2); 290 BEGIN_RING(chan, RING_3D_(0x0de8), 1); 291 OUT_RING (chan, 1); 292 BEGIN_RING(chan, RING_3D_(0x165c), 1); 293 OUT_RING (chan, 0); 294 295 BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */ 296 OUT_RING (chan, 0); 297 298 BEGIN_RING(chan, RING_3D_(0x12ac), 1); 299 OUT_RING (chan, 0); 300 BEGIN_RING(chan, RING_3D_(0x0218), 1); 301 OUT_RING (chan, 0x10); 302 BEGIN_RING(chan, RING_3D_(0x10fc), 1); 303 OUT_RING (chan, 0x10); 304 BEGIN_RING(chan, RING_3D_(0x1290), 1); 305 OUT_RING (chan, 0x10); 306 BEGIN_RING(chan, RING_3D_(0x12d8), 2); 307 OUT_RING (chan, 0x10); 308 OUT_RING (chan, 0x10); 309 BEGIN_RING(chan, RING_3D_(0x06d4), 1); 310 OUT_RING (chan, 8); 311 BEGIN_RING(chan, RING_3D_(0x1140), 1); 312 OUT_RING (chan, 0x10); 313 BEGIN_RING(chan, RING_3D_(0x1610), 1); 314 OUT_RING (chan, 0xe); 315 316 BEGIN_RING(chan, RING_3D_(0x164c), 1); 317 OUT_RING (chan, 1 << 12); 318 BEGIN_RING(chan, RING_3D_(0x151c), 1); 319 OUT_RING (chan, 1); 320 BEGIN_RING(chan, RING_3D_(0x020c), 1); 321 OUT_RING (chan, 1); 322 BEGIN_RING(chan, RING_3D_(0x030c), 1); 323 OUT_RING (chan, 0); 324 BEGIN_RING(chan, RING_3D_(0x0300), 1); 325 OUT_RING (chan, 3); 326 BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */ 327 OUT_RING (chan, 0); 328 BEGIN_RING(chan, RING_3D_(0x02d0), 1); 329 OUT_RING (chan, 0x1f40); 330 BEGIN_RING(chan, RING_3D_(0x00fdc), 1); 331 OUT_RING (chan, 1); 332 BEGIN_RING(chan, RING_3D_(0x19c0), 1); 333 OUT_RING (chan, 1); 334 BEGIN_RING(chan, RING_3D_(0x075c), 1); 335 OUT_RING (chan, 3); 336 337 BEGIN_RING(chan, RING_3D_(0x0fac), 1); 338 OUT_RING (chan, 0); 339 BEGIN_RING(chan, RING_3D_(0x0f90), 1); 340 OUT_RING (chan, 0); 341} 342 343#define FAIL_SCREEN_INIT(str, err) \ 344 do { \ 345 NOUVEAU_ERR(str, err); \ 346 nvc0_screen_destroy(pscreen); \ 347 return NULL; \ 348 } while(0) 349 350struct pipe_screen * 351nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) 352{ 353 struct nvc0_screen *screen; 354 struct nouveau_channel *chan; 355 struct pipe_screen *pscreen; 356 int ret; 357 unsigned i; 358 359 screen = CALLOC_STRUCT(nvc0_screen); 360 if (!screen) 361 return NULL; 362 pscreen = &screen->base.base; 363 364 ret = nouveau_screen_init(&screen->base, dev); 365 if (ret) { 366 nvc0_screen_destroy(pscreen); 367 return NULL; 368 } 369 chan = screen->base.channel; 370 371 pscreen->winsys = ws; 372 pscreen->destroy = nvc0_screen_destroy; 373 pscreen->context_create = nvc0_create; 374 pscreen->is_format_supported = nvc0_screen_is_format_supported; 375 pscreen->get_param = nvc0_screen_get_param; 376 pscreen->get_shader_param = nvc0_screen_get_shader_param; 377 pscreen->get_paramf = nvc0_screen_get_paramf; 378 pscreen->fence_reference = nvc0_screen_fence_reference; 379 pscreen->fence_signalled = nvc0_screen_fence_signalled; 380 pscreen->fence_finish = nvc0_screen_fence_finish; 381 382 nvc0_screen_init_resource_functions(pscreen); 383 384 screen->base.vertex_buffer_flags = NOUVEAU_BO_GART; 385 screen->base.index_buffer_flags = 0; 386 387 ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, 388 &screen->fence.bo); 389 if (ret) 390 goto fail; 391 nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); 392 screen->fence.map = screen->fence.bo->map; 393 nouveau_bo_unmap(screen->fence.bo); 394 395 for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) { 396 ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, 397 &screen->scratch.bo[i]); 398 if (ret) 399 goto fail; 400 } 401 402 ret = nouveau_grobj_alloc(chan, 0xbeef9039, NVC0_M2MF, &screen->m2mf); 403 if (ret) 404 FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret); 405 406 BIND_RING (chan, screen->m2mf, NVC0_SUBCH_MF); 407 BEGIN_RING(chan, RING_MF(NOTIFY_ADDRESS_HIGH), 3); 408 OUT_RELOCh(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 409 OUT_RELOCl(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 410 OUT_RING (chan, 0); 411 412 ret = nouveau_grobj_alloc(chan, 0xbeef902d, NVC0_2D, &screen->eng2d); 413 if (ret) 414 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret); 415 416 BIND_RING (chan, screen->eng2d, NVC0_SUBCH_2D); 417 BEGIN_RING(chan, RING_2D(OPERATION), 1); 418 OUT_RING (chan, NVC0_2D_OPERATION_SRCCOPY); 419 BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1); 420 OUT_RING (chan, 0); 421 BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1); 422 OUT_RING (chan, 0); 423 BEGIN_RING(chan, RING_2D_(0x0884), 1); 424 OUT_RING (chan, 0x3f); 425 BEGIN_RING(chan, RING_2D_(0x0888), 1); 426 OUT_RING (chan, 1); 427 428 ret = nouveau_grobj_alloc(chan, 0xbeef9097, NVC0_3D, &screen->fermi); 429 if (ret) 430 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret); 431 432 BIND_RING (chan, screen->fermi, NVC0_SUBCH_3D); 433 BEGIN_RING(chan, RING_3D(NOTIFY_ADDRESS_HIGH), 3); 434 OUT_RELOCh(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 435 OUT_RELOCl(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 436 OUT_RING (chan, 0); 437 438 BEGIN_RING(chan, RING_3D(COND_MODE), 1); 439 OUT_RING (chan, NVC0_3D_COND_MODE_ALWAYS); 440 441 BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); 442 OUT_RING (chan, 1); 443 444 BEGIN_RING(chan, RING_3D(MULTISAMPLE_ZETA_ENABLE), 1); 445 OUT_RING (chan, 0); 446 BEGIN_RING(chan, RING_3D(MULTISAMPLE_COLOR_ENABLE), 1); 447 OUT_RING (chan, 0); 448 BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); 449 OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_1X); 450 BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1); 451 OUT_RING (chan, 0); 452 453 nvc0_magic_3d_init(chan); 454 455 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, &screen->text); 456 if (ret) 457 goto fail; 458 459 nouveau_resource_init(&screen->text_heap, 0, 1 << 20); 460 461 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, 462 &screen->uniforms); 463 if (ret) 464 goto fail; 465 466 /* auxiliary constants (6 user clip planes, base instance id) */ 467 BEGIN_RING(chan, RING_3D(CB_SIZE), 3); 468 OUT_RING (chan, 256); 469 OUT_RELOCh(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 470 OUT_RELOCl(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 471 for (i = 0; i < 5; ++i) { 472 BEGIN_RING(chan, RING_3D(CB_BIND(i)), 1); 473 OUT_RING (chan, (15 << 4) | 1); 474 } 475 476 screen->tls_size = 4 * 4 * 32 * 128 * 4; 477 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 478 screen->tls_size, &screen->tls); 479 if (ret) 480 goto fail; 481 482 BEGIN_RING(chan, RING_3D(CODE_ADDRESS_HIGH), 2); 483 OUT_RELOCh(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 484 OUT_RELOCl(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 485 BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 4); 486 OUT_RELOCh(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 487 OUT_RELOCl(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 488 OUT_RING (chan, screen->tls_size >> 32); 489 OUT_RING (chan, screen->tls_size); 490 BEGIN_RING(chan, RING_3D(LOCAL_BASE), 1); 491 OUT_RING (chan, 0); 492 493 for (i = 0; i < 5; ++i) { 494 BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1); 495 OUT_RING (chan, 0x54); 496 } 497 BEGIN_RING(chan, RING_3D(LINKED_TSC), 1); 498 OUT_RING (chan, 0); 499 500 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, 501 &screen->mp_stack_bo); 502 if (ret) 503 goto fail; 504 505 BEGIN_RING(chan, RING_3D_(0x17bc), 3); 506 OUT_RELOCh(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 507 OUT_RELOCl(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 508 OUT_RING (chan, 1); 509 510 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc); 511 if (ret) 512 goto fail; 513 514 BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3); 515 OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 516 OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 517 OUT_RING (chan, NVC0_TIC_MAX_ENTRIES - 1); 518 519 BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3); 520 OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 521 OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 522 OUT_RING (chan, NVC0_TSC_MAX_ENTRIES - 1); 523 524 BEGIN_RING(chan, RING_3D(Y_ORIGIN_BOTTOM), 1); 525 OUT_RING (chan, 0); 526 BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); 527 OUT_RING (chan, 0); 528 OUT_RING (chan, 0); 529 BEGIN_RING(chan, RING_3D_(0x1590), 1); /* deactivate ZCULL */ 530 OUT_RING (chan, 0x3f); 531 532 BEGIN_RING(chan, RING_3D(VIEWPORT_CLIP_RECTS_EN), 1); 533 OUT_RING (chan, 0); 534 BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1); 535 OUT_RING (chan, 0); 536 537 BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); 538 OUT_RING (chan, 1); 539 BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); 540 OUT_RINGf (chan, 0.0f); 541 OUT_RINGf (chan, 1.0f); 542 543 /* We use scissors instead of exact view volume clipping, 544 * so they're always enabled. 545 */ 546 BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3); 547 OUT_RING (chan, 1); 548 OUT_RING (chan, 8192 << 16); 549 OUT_RING (chan, 8192 << 16); 550 551 BEGIN_RING(chan, RING_3D_(0x0fac), 1); 552 OUT_RING (chan, 0); 553 BEGIN_RING(chan, RING_3D_(0x3484), 1); 554 OUT_RING (chan, 0); 555 BEGIN_RING(chan, RING_3D_(0x0dbc), 1); 556 OUT_RING (chan, 0x00010000); 557 BEGIN_RING(chan, RING_3D_(0x0dd8), 1); 558 OUT_RING (chan, 0xff800006); 559 BEGIN_RING(chan, RING_3D_(0x3488), 1); 560 OUT_RING (chan, 0); 561 562#define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n); 563 564 i = 0; 565 MK_MACRO(NVC0_3D_BLEND_ENABLES, nvc0_9097_blend_enables); 566 MK_MACRO(NVC0_3D_VERTEX_ARRAY_SELECT, nvc0_9097_vertex_array_select); 567 MK_MACRO(NVC0_3D_TEP_SELECT, nvc0_9097_tep_select); 568 MK_MACRO(NVC0_3D_GP_SELECT, nvc0_9097_gp_select); 569 MK_MACRO(NVC0_3D_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front); 570 MK_MACRO(NVC0_3D_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back); 571 MK_MACRO(NVC0_3D_COLOR_MASK_BROADCAST, nvc0_9097_color_mask_brdc); 572 573 BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1); 574 OUT_RING (chan, 1); 575 BEGIN_RING(chan, RING_3D(GP_SELECT), 1); 576 OUT_RING (chan, 0x40); 577 BEGIN_RING(chan, RING_3D(GP_BUILTIN_RESULT_EN), 1); 578 OUT_RING (chan, 0); 579 BEGIN_RING(chan, RING_3D(TEP_SELECT), 1); 580 OUT_RING (chan, 0x30); 581 BEGIN_RING(chan, RING_3D(PATCH_VERTICES), 1); 582 OUT_RING (chan, 3); 583 BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1); 584 OUT_RING (chan, 0x20); 585 BEGIN_RING(chan, RING_3D(SP_SELECT(0)), 1); 586 OUT_RING (chan, 0x00); 587 588 BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1); 589 OUT_RING (chan, 0); 590 591 BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1); 592 OUT_RING (chan, 0x11111111); 593 BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1); 594 OUT_RING (chan, 1); 595 596 BEGIN_RING(chan, RING_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); 597 OUT_RING (chan, 0xab); 598 OUT_RING (chan, 0x00000000); 599 600 FIRE_RING (chan); 601 602 screen->tic.entries = CALLOC(4096, sizeof(void *)); 603 screen->tsc.entries = screen->tic.entries + 2048; 604 605 screen->mm_GART = nvc0_mm_create(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 606 0x000); 607 screen->mm_VRAM = nvc0_mm_create(dev, NOUVEAU_BO_VRAM, 0x000); 608 screen->mm_VRAM_fe0 = nvc0_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); 609 610 nvc0_screen_fence_new(screen, &screen->fence.current, FALSE); 611 612 return pscreen; 613 614fail: 615 nvc0_screen_destroy(pscreen); 616 return NULL; 617} 618 619void 620nvc0_screen_make_buffers_resident(struct nvc0_screen *screen) 621{ 622 struct nouveau_channel *chan = screen->base.channel; 623 624 const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; 625 626 nouveau_bo_validate(chan, screen->text, flags); 627 nouveau_bo_validate(chan, screen->uniforms, flags); 628 nouveau_bo_validate(chan, screen->txc, flags); 629 nouveau_bo_validate(chan, screen->tls, flags); 630 nouveau_bo_validate(chan, screen->mp_stack_bo, flags); 631} 632 633int 634nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry) 635{ 636 int i = screen->tic.next; 637 638 while (screen->tic.lock[i / 32] & (1 << (i % 32))) 639 i = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1); 640 641 screen->tic.next = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1); 642 643 if (screen->tic.entries[i]) 644 nvc0_tic_entry(screen->tic.entries[i])->id = -1; 645 646 screen->tic.entries[i] = entry; 647 return i; 648} 649 650int 651nvc0_screen_tsc_alloc(struct nvc0_screen *screen, void *entry) 652{ 653 int i = screen->tsc.next; 654 655 while (screen->tsc.lock[i / 32] & (1 << (i % 32))) 656 i = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1); 657 658 screen->tsc.next = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1); 659 660 if (screen->tsc.entries[i]) 661 nvc0_tsc_entry(screen->tsc.entries[i])->id = -1; 662 663 screen->tsc.entries[i] = entry; 664 return i; 665} 666