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