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