nvc0_screen.c revision 2a0126932b320806e030c1c085791e257516e0cd
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.h" 24#include "util/u_format_s3tc.h" 25#include "pipe/p_screen.h" 26 27#include "vl/vl_decoder.h" 28#include "vl/vl_video_buffer.h" 29 30#include "nvc0_context.h" 31#include "nvc0_screen.h" 32 33#include "nouveau/nv_object.xml.h" 34#include "nvc0_graph_macros.h" 35 36static boolean 37nvc0_screen_is_format_supported(struct pipe_screen *pscreen, 38 enum pipe_format format, 39 enum pipe_texture_target target, 40 unsigned sample_count, 41 unsigned bindings) 42{ 43 if (!(0x117 & (1 << sample_count))) /* 0, 1, 2, 4 or 8 */ 44 return FALSE; 45 46 if (!util_format_is_supported(format, bindings)) 47 return FALSE; 48 49 switch (format) { 50 case PIPE_FORMAT_R8G8B8A8_UNORM: 51 case PIPE_FORMAT_R8G8B8X8_UNORM: 52 /* HACK: GL requires equal formats for MS resolve and window is BGRA */ 53 if (bindings & PIPE_BIND_RENDER_TARGET) 54 return FALSE; 55 default: 56 break; 57 } 58 59 /* transfers & shared are always supported */ 60 bindings &= ~(PIPE_BIND_TRANSFER_READ | 61 PIPE_BIND_TRANSFER_WRITE | 62 PIPE_BIND_SHARED); 63 64 return (nvc0_format_table[format].usage & bindings) == bindings; 65} 66 67static int 68nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 69{ 70 switch (param) { 71 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 72 return 64; 73 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 74 return 13; 75 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 76 return 10; 77 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 78 return 13; 79 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 80 return 8192; 81 case PIPE_CAP_MIN_TEXEL_OFFSET: 82 return -8; 83 case PIPE_CAP_MAX_TEXEL_OFFSET: 84 return 7; 85 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 86 case PIPE_CAP_TEXTURE_SWIZZLE: 87 case PIPE_CAP_TEXTURE_SHADOW_MAP: 88 case PIPE_CAP_NPOT_TEXTURES: 89 case PIPE_CAP_ANISOTROPIC_FILTER: 90 case PIPE_CAP_SEAMLESS_CUBE_MAP: 91 return 1; 92 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 93 return 0; 94 case PIPE_CAP_TWO_SIDED_STENCIL: 95 case PIPE_CAP_DEPTH_CLAMP: 96 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 97 case PIPE_CAP_POINT_SPRITE: 98 return 1; 99 case PIPE_CAP_SM3: 100 return 1; 101 case PIPE_CAP_MAX_RENDER_TARGETS: 102 return 8; 103 case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: 104 return 1; 105 case PIPE_CAP_TIMER_QUERY: 106 case PIPE_CAP_OCCLUSION_QUERY: 107 return 1; 108 case PIPE_CAP_STREAM_OUTPUT: 109 return 0; 110 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 111 case PIPE_CAP_INDEP_BLEND_ENABLE: 112 case PIPE_CAP_INDEP_BLEND_FUNC: 113 return 1; 114 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 115 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 116 return 1; 117 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 118 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 119 return 0; 120 case PIPE_CAP_SHADER_STENCIL_EXPORT: 121 return 0; 122 case PIPE_CAP_PRIMITIVE_RESTART: 123 case PIPE_CAP_TGSI_INSTANCEID: 124 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 125 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 126 case PIPE_CAP_CONDITIONAL_RENDER: 127 case PIPE_CAP_TEXTURE_BARRIER: 128 return 1; 129 default: 130 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); 131 return 0; 132 } 133} 134 135static int 136nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 137 enum pipe_shader_cap param) 138{ 139 switch (shader) { 140 case PIPE_SHADER_VERTEX: 141 /* 142 case PIPE_SHADER_TESSELLATION_CONTROL: 143 case PIPE_SHADER_TESSELLATION_EVALUATION: 144 */ 145 case PIPE_SHADER_GEOMETRY: 146 case PIPE_SHADER_FRAGMENT: 147 break; 148 default: 149 return 0; 150 } 151 152 switch (param) { 153 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 154 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 155 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 156 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 157 return 16384; 158 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 159 return 16; 160 case PIPE_SHADER_CAP_MAX_INPUTS: 161 if (shader == PIPE_SHADER_VERTEX) 162 return 32; 163 return 0x300 / 16; 164 case PIPE_SHADER_CAP_MAX_CONSTS: 165 return 65536 / 16; 166 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 167 return 14; 168 case PIPE_SHADER_CAP_MAX_ADDRS: 169 return 1; 170 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 171 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 172 return shader != PIPE_SHADER_FRAGMENT; 173 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 174 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 175 return 1; 176 case PIPE_SHADER_CAP_MAX_PREDS: 177 return 0; 178 case PIPE_SHADER_CAP_MAX_TEMPS: 179 return NVC0_CAP_MAX_PROGRAM_TEMPS; 180 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 181 return 1; 182 case PIPE_SHADER_CAP_SUBROUTINES: 183 return 1; /* but inlining everything, we need function declarations */ 184 case PIPE_SHADER_CAP_INTEGERS: 185 return 1; 186 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 187 return 32; 188 default: 189 NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param); 190 return 0; 191 } 192} 193 194static float 195nvc0_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_cap param) 196{ 197 switch (param) { 198 case PIPE_CAP_MAX_LINE_WIDTH: 199 case PIPE_CAP_MAX_LINE_WIDTH_AA: 200 return 10.0f; 201 case PIPE_CAP_MAX_POINT_WIDTH: 202 case PIPE_CAP_MAX_POINT_WIDTH_AA: 203 return 64.0f; 204 case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: 205 return 16.0f; 206 case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: 207 return 4.0f; 208 default: 209 NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); 210 return 0.0f; 211 } 212} 213 214static void 215nvc0_screen_destroy(struct pipe_screen *pscreen) 216{ 217 struct nvc0_screen *screen = nvc0_screen(pscreen); 218 219 if (screen->base.fence.current) { 220 nouveau_fence_wait(screen->base.fence.current); 221 nouveau_fence_ref(NULL, &screen->base.fence.current); 222 } 223 screen->base.channel->user_private = NULL; 224 225 if (screen->blitctx) 226 FREE(screen->blitctx); 227 228 nouveau_bo_ref(NULL, &screen->text); 229 nouveau_bo_ref(NULL, &screen->tls); 230 nouveau_bo_ref(NULL, &screen->txc); 231 nouveau_bo_ref(NULL, &screen->fence.bo); 232 nouveau_bo_ref(NULL, &screen->vfetch_cache); 233 234 nouveau_resource_destroy(&screen->lib_code); 235 nouveau_resource_destroy(&screen->text_heap); 236 237 if (screen->tic.entries) 238 FREE(screen->tic.entries); 239 240 nouveau_mm_destroy(screen->mm_VRAM_fe0); 241 242 nouveau_grobj_free(&screen->fermi); 243 nouveau_grobj_free(&screen->eng2d); 244 nouveau_grobj_free(&screen->m2mf); 245 246 nouveau_screen_fini(&screen->base); 247 248 FREE(screen); 249} 250 251static int 252nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos, 253 unsigned size, const uint32_t *data) 254{ 255 struct nouveau_channel *chan = screen->base.channel; 256 257 size /= 4; 258 259 BEGIN_RING(chan, RING_3D_(NVC0_GRAPH_MACRO_ID), 2); 260 OUT_RING (chan, (m - 0x3800) / 8); 261 OUT_RING (chan, pos); 262 BEGIN_RING_1I(chan, RING_3D_(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1); 263 OUT_RING (chan, pos); 264 OUT_RINGp (chan, data, size); 265 266 return pos + size; 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_(0x16a8), 1); 284 OUT_RING (chan, (3 << 16) | 3); 285 BEGIN_RING(chan, RING_3D_(0x1794), 1); 286 OUT_RING (chan, (2 << 16) | 2); 287 BEGIN_RING(chan, RING_3D_(0x0de8), 1); 288 OUT_RING (chan, 1); 289 290#if 0 /* software method */ 291 BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */ 292 OUT_RING (chan, 0); 293#endif 294 295 BEGIN_RING(chan, RING_3D_(0x12ac), 1); 296 OUT_RING (chan, 0); 297 BEGIN_RING(chan, RING_3D_(0x0218), 1); 298 OUT_RING (chan, 0x10); 299 BEGIN_RING(chan, RING_3D_(0x10fc), 1); 300 OUT_RING (chan, 0x10); 301 BEGIN_RING(chan, RING_3D_(0x1290), 1); 302 OUT_RING (chan, 0x10); 303 BEGIN_RING(chan, RING_3D_(0x12d8), 2); 304 OUT_RING (chan, 0x10); 305 OUT_RING (chan, 0x10); 306 BEGIN_RING(chan, RING_3D_(0x06d4), 1); 307 OUT_RING (chan, 8); 308 BEGIN_RING(chan, RING_3D_(0x1140), 1); 309 OUT_RING (chan, 0x10); 310 BEGIN_RING(chan, RING_3D_(0x1610), 1); 311 OUT_RING (chan, 0xe); 312 313 BEGIN_RING(chan, RING_3D_(0x164c), 1); 314 OUT_RING (chan, 1 << 12); 315 BEGIN_RING(chan, RING_3D_(0x151c), 1); 316 OUT_RING (chan, 1); 317 BEGIN_RING(chan, RING_3D_(0x030c), 1); 318 OUT_RING (chan, 0); 319 BEGIN_RING(chan, RING_3D_(0x0300), 1); 320 OUT_RING (chan, 3); 321#if 0 /* software method */ 322 BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */ 323 OUT_RING (chan, 0); 324#endif 325 BEGIN_RING(chan, RING_3D_(0x02d0), 1); 326 OUT_RING (chan, 0x1f40); 327 BEGIN_RING(chan, RING_3D_(0x00fdc), 1); 328 OUT_RING (chan, 1); 329 BEGIN_RING(chan, RING_3D_(0x19c0), 1); 330 OUT_RING (chan, 1); 331 BEGIN_RING(chan, RING_3D_(0x075c), 1); 332 OUT_RING (chan, 3); 333} 334 335static void 336nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence) 337{ 338 struct nvc0_screen *screen = nvc0_screen(pscreen); 339 struct nouveau_channel *chan = screen->base.channel; 340 341 MARK_RING (chan, 5, 2); 342 343 /* we need to do it after possible flush in MARK_RING */ 344 *sequence = ++screen->base.fence.sequence; 345 346 BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4); 347 OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); 348 OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR); 349 OUT_RING (chan, *sequence); 350 OUT_RING (chan, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT | 351 (0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT)); 352} 353 354static u32 355nvc0_screen_fence_update(struct pipe_screen *pscreen) 356{ 357 struct nvc0_screen *screen = nvc0_screen(pscreen); 358 return screen->fence.map[0]; 359} 360 361#define FAIL_SCREEN_INIT(str, err) \ 362 do { \ 363 NOUVEAU_ERR(str, err); \ 364 nvc0_screen_destroy(pscreen); \ 365 return NULL; \ 366 } while(0) 367 368struct pipe_screen * 369nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) 370{ 371 struct nvc0_screen *screen; 372 struct nouveau_channel *chan; 373 struct pipe_screen *pscreen; 374 int ret; 375 unsigned i; 376 377 screen = CALLOC_STRUCT(nvc0_screen); 378 if (!screen) 379 return NULL; 380 pscreen = &screen->base.base; 381 382 screen->base.sysmem_bindings = PIPE_BIND_CONSTANT_BUFFER; 383 384 ret = nouveau_screen_init(&screen->base, dev); 385 if (ret) { 386 nvc0_screen_destroy(pscreen); 387 return NULL; 388 } 389 chan = screen->base.channel; 390 chan->user_private = screen; 391 392 pscreen->winsys = ws; 393 pscreen->destroy = nvc0_screen_destroy; 394 pscreen->context_create = nvc0_create; 395 pscreen->is_format_supported = nvc0_screen_is_format_supported; 396 pscreen->get_param = nvc0_screen_get_param; 397 pscreen->get_shader_param = nvc0_screen_get_shader_param; 398 pscreen->get_paramf = nvc0_screen_get_paramf; 399 400 nvc0_screen_init_resource_functions(pscreen); 401 402 nouveau_screen_init_vdec(&screen->base); 403 404 ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, 405 &screen->fence.bo); 406 if (ret) 407 goto fail; 408 nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR); 409 screen->fence.map = screen->fence.bo->map; 410 nouveau_bo_unmap(screen->fence.bo); 411 screen->base.fence.emit = nvc0_screen_fence_emit; 412 screen->base.fence.update = nvc0_screen_fence_update; 413 414 for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) { 415 ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, 416 &screen->scratch.bo[i]); 417 if (ret) 418 goto fail; 419 } 420 421 ret = nouveau_grobj_alloc(chan, 0xbeef9039, NVC0_M2MF, &screen->m2mf); 422 if (ret) 423 FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret); 424 425 BIND_RING (chan, screen->m2mf, NVC0_SUBCH_MF); 426 BEGIN_RING(chan, RING_MF(NOTIFY_ADDRESS_HIGH), 3); 427 OUT_RELOCh(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 428 OUT_RELOCl(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 429 OUT_RING (chan, 0); 430 431 ret = nouveau_grobj_alloc(chan, 0xbeef902d, NVC0_2D, &screen->eng2d); 432 if (ret) 433 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret); 434 435 BIND_RING (chan, screen->eng2d, NVC0_SUBCH_2D); 436 BEGIN_RING(chan, RING_2D(OPERATION), 1); 437 OUT_RING (chan, NVC0_2D_OPERATION_SRCCOPY); 438 BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1); 439 OUT_RING (chan, 0); 440 BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1); 441 OUT_RING (chan, 0); 442 BEGIN_RING(chan, RING_2D_(0x0884), 1); 443 OUT_RING (chan, 0x3f); 444 BEGIN_RING(chan, RING_2D_(0x0888), 1); 445 OUT_RING (chan, 1); 446 447 ret = nouveau_grobj_alloc(chan, 0xbeef9097, NVC0_3D, &screen->fermi); 448 if (ret) 449 FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret); 450 451 BIND_RING (chan, screen->fermi, NVC0_SUBCH_3D); 452 BEGIN_RING(chan, RING_3D(NOTIFY_ADDRESS_HIGH), 3); 453 OUT_RELOCh(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 454 OUT_RELOCl(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); 455 OUT_RING (chan, 0); 456 457 BEGIN_RING(chan, RING_3D(COND_MODE), 1); 458 OUT_RING (chan, NVC0_3D_COND_MODE_ALWAYS); 459 460 BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); 461 OUT_RING (chan, 1); 462 463 BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1); 464 OUT_RING (chan, 0); 465 BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1); 466 OUT_RING (chan, 0); 467 BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); 468 OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_MS1); 469 BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1); 470 OUT_RING (chan, 0); 471 BEGIN_RING(chan, RING_3D(LINE_WIDTH_SEPARATE), 1); 472 OUT_RING (chan, 1); 473 BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1); 474 OUT_RING (chan, 0); 475 BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1); 476 OUT_RING (chan, 1); 477 BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1); 478 OUT_RING (chan, 0); 479 BEGIN_RING(chan, RING_3D(TEX_MISC), 1); 480 OUT_RING (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); 481 482 nvc0_magic_3d_init(chan); 483 484 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, &screen->text); 485 if (ret) 486 goto fail; 487 488 /* XXX: getting a page fault at the end of the code buffer every few 489 * launches, don't use the last 256 bytes to work around them - prefetch ? 490 */ 491 nouveau_resource_init(&screen->text_heap, 0, (1 << 20) - 0x100); 492 493 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, 494 &screen->uniforms); 495 if (ret) 496 goto fail; 497 498 /* auxiliary constants (6 user clip planes, base instance id) */ 499 BEGIN_RING(chan, RING_3D(CB_SIZE), 3); 500 OUT_RING (chan, 256); 501 OUT_RELOCh(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 502 OUT_RELOCl(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 503 for (i = 0; i < 5; ++i) { 504 BEGIN_RING(chan, RING_3D(CB_BIND(i)), 1); 505 OUT_RING (chan, (15 << 4) | 1); 506 } 507 508 screen->tls_size = (16 * 32) * (NVC0_CAP_MAX_PROGRAM_TEMPS * 16); 509 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 510 screen->tls_size, &screen->tls); 511 if (ret) 512 goto fail; 513 514 BEGIN_RING(chan, RING_3D(CODE_ADDRESS_HIGH), 2); 515 OUT_RELOCh(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 516 OUT_RELOCl(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 517 BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 4); 518 OUT_RELOCh(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 519 OUT_RELOCl(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 520 OUT_RING (chan, screen->tls_size >> 32); 521 OUT_RING (chan, screen->tls_size); 522 BEGIN_RING(chan, RING_3D_(0x07a0), 1); 523 OUT_RING (chan, 0); 524 BEGIN_RING(chan, RING_3D(LOCAL_BASE), 1); 525 OUT_RING (chan, 0); 526 527 for (i = 0; i < 5; ++i) { 528 BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1); 529 OUT_RING (chan, 0x54); 530 } 531 BEGIN_RING(chan, RING_3D(LINKED_TSC), 1); 532 OUT_RING (chan, 0); 533 534 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, 535 &screen->vfetch_cache); 536 if (ret) 537 goto fail; 538 539 BEGIN_RING(chan, RING_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3); 540 OUT_RELOCh(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 541 OUT_RELOCl(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 542 OUT_RING (chan, 3); 543 544 ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc); 545 if (ret) 546 goto fail; 547 548 BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3); 549 OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 550 OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 551 OUT_RING (chan, NVC0_TIC_MAX_ENTRIES - 1); 552 553 BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3); 554 OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 555 OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); 556 OUT_RING (chan, NVC0_TSC_MAX_ENTRIES - 1); 557 558 BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); 559 OUT_RING (chan, 0); 560 BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); 561 OUT_RING (chan, 0); 562 OUT_RING (chan, 0); 563 BEGIN_RING(chan, RING_3D_(0x1590), 1); /* deactivate ZCULL */ 564 OUT_RING (chan, 0x3f); 565 566 BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1); 567 OUT_RING (chan, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY); 568 BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2); 569 for (i = 0; i < 8 * 2; ++i) 570 OUT_RING(chan, 0); 571 BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1); 572 OUT_RING (chan, 0); 573 BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1); 574 OUT_RING (chan, 0); 575 576 /* neither scissors, viewport nor stencil mask should affect clears */ 577 BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1); 578 OUT_RING (chan, 0); 579 580 BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1); 581 OUT_RING (chan, 1); 582 BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2); 583 OUT_RINGf (chan, 0.0f); 584 OUT_RINGf (chan, 1.0f); 585 BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1); 586 OUT_RING (chan, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1); 587 588 /* We use scissors instead of exact view volume clipping, 589 * so they're always enabled. 590 */ 591 BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3); 592 OUT_RING (chan, 1); 593 OUT_RING (chan, 8192 << 16); 594 OUT_RING (chan, 8192 << 16); 595 596#define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n); 597 598 i = 0; 599 MK_MACRO(NVC0_3D_BLEND_ENABLES, nvc0_9097_blend_enables); 600 MK_MACRO(NVC0_3D_VERTEX_ARRAY_SELECT, nvc0_9097_vertex_array_select); 601 MK_MACRO(NVC0_3D_TEP_SELECT, nvc0_9097_tep_select); 602 MK_MACRO(NVC0_3D_GP_SELECT, nvc0_9097_gp_select); 603 MK_MACRO(NVC0_3D_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front); 604 MK_MACRO(NVC0_3D_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back); 605 606 BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1); 607 OUT_RING (chan, 1); 608 BEGIN_RING(chan, RING_3D(RT_SEPARATE_FRAG_DATA), 1); 609 OUT_RING (chan, 1); 610 BEGIN_RING(chan, RING_3D(GP_SELECT), 1); 611 OUT_RING (chan, 0x40); 612 BEGIN_RING(chan, RING_3D(LAYER), 1); 613 OUT_RING (chan, 0); 614 BEGIN_RING(chan, RING_3D(TEP_SELECT), 1); 615 OUT_RING (chan, 0x30); 616 BEGIN_RING(chan, RING_3D(PATCH_VERTICES), 1); 617 OUT_RING (chan, 3); 618 BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1); 619 OUT_RING (chan, 0x20); 620 BEGIN_RING(chan, RING_3D(SP_SELECT(0)), 1); 621 OUT_RING (chan, 0x00); 622 623 BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1); 624 OUT_RING (chan, 0); 625 BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1); 626 OUT_RING (chan, NVC0_3D_POINT_RASTER_RULES_OGL); 627 628 BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1); 629 OUT_RING (chan, 1); 630 631 BEGIN_RING(chan, RING_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2); 632 OUT_RING (chan, 0xab); 633 OUT_RING (chan, 0x00000000); 634 635 FIRE_RING (chan); 636 637 screen->tic.entries = CALLOC(4096, sizeof(void *)); 638 screen->tsc.entries = screen->tic.entries + 2048; 639 640 screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0); 641 642 if (!nvc0_blitctx_create(screen)) 643 goto fail; 644 645 nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); 646 647 return pscreen; 648 649fail: 650 nvc0_screen_destroy(pscreen); 651 return NULL; 652} 653 654void 655nvc0_screen_make_buffers_resident(struct nvc0_screen *screen) 656{ 657 struct nouveau_channel *chan = screen->base.channel; 658 659 const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD; 660 661 MARK_RING(chan, 0, 5); 662 nouveau_bo_validate(chan, screen->text, flags); 663 nouveau_bo_validate(chan, screen->uniforms, flags); 664 nouveau_bo_validate(chan, screen->txc, flags); 665 nouveau_bo_validate(chan, screen->vfetch_cache, flags); 666 667 if (screen->cur_ctx && screen->cur_ctx->state.tls_required) 668 nouveau_bo_validate(chan, screen->tls, flags); 669} 670 671int 672nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry) 673{ 674 int i = screen->tic.next; 675 676 while (screen->tic.lock[i / 32] & (1 << (i % 32))) 677 i = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1); 678 679 screen->tic.next = (i + 1) & (NVC0_TIC_MAX_ENTRIES - 1); 680 681 if (screen->tic.entries[i]) 682 nv50_tic_entry(screen->tic.entries[i])->id = -1; 683 684 screen->tic.entries[i] = entry; 685 return i; 686} 687 688int 689nvc0_screen_tsc_alloc(struct nvc0_screen *screen, void *entry) 690{ 691 int i = screen->tsc.next; 692 693 while (screen->tsc.lock[i / 32] & (1 << (i % 32))) 694 i = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1); 695 696 screen->tsc.next = (i + 1) & (NVC0_TSC_MAX_ENTRIES - 1); 697 698 if (screen->tsc.entries[i]) 699 nv50_tsc_entry(screen->tsc.entries[i])->id = -1; 700 701 screen->tsc.entries[i] = entry; 702 return i; 703} 704