1 /* 2 * Copyright 2012 Red Hat Inc. 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 * Authors: Ben Skeggs 23 * 24 */ 25 26 #include "util/u_format_s3tc.h" 27 28 #include "nouveau/nv_object.xml.h" 29 #include "nouveau/nv_m2mf.xml.h" 30 #include "nv30-40_3d.xml.h" 31 #include "nv01_2d.xml.h" 32 33 #include "nouveau/nouveau_fence.h" 34 #include "nv30_screen.h" 35 #include "nv30_context.h" 36 #include "nv30_resource.h" 37 #include "nv30_format.h" 38 39 #define RANKINE_0397_CHIPSET 0x00000003 40 #define RANKINE_0497_CHIPSET 0x000001e0 41 #define RANKINE_0697_CHIPSET 0x00000010 42 #define CURIE_4097_CHIPSET 0x00000baf 43 #define CURIE_4497_CHIPSET 0x00005450 44 #define CURIE_4497_CHIPSET6X 0x00000088 45 46 static int 47 nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) 48 { 49 struct nv30_screen *screen = nv30_screen(pscreen); 50 struct nouveau_object *eng3d = screen->eng3d; 51 52 switch (param) { 53 /* non-boolean capabilities */ 54 case PIPE_CAP_MAX_RENDER_TARGETS: 55 return (eng3d->oclass >= NV40_3D_CLASS) ? 4 : 1; 56 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 57 return 13; 58 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 59 return 10; 60 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 61 return 13; 62 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 63 return 16; 64 case PIPE_CAP_GLSL_FEATURE_LEVEL: 65 return 120; 66 /* supported capabilities */ 67 case PIPE_CAP_TWO_SIDED_STENCIL: 68 case PIPE_CAP_ANISOTROPIC_FILTER: 69 case PIPE_CAP_POINT_SPRITE: 70 case PIPE_CAP_SCALED_RESOLVE: 71 case PIPE_CAP_OCCLUSION_QUERY: 72 case PIPE_CAP_TIMER_QUERY: 73 case PIPE_CAP_QUERY_TIMESTAMP: 74 case PIPE_CAP_TEXTURE_SHADOW_MAP: 75 case PIPE_CAP_TEXTURE_SWIZZLE: 76 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 77 case PIPE_CAP_DEPTH_CLIP_DISABLE: 78 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 79 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 80 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 81 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 82 case PIPE_CAP_USER_CONSTANT_BUFFERS: 83 case PIPE_CAP_USER_INDEX_BUFFERS: 84 return 1; 85 case PIPE_CAP_USER_VERTEX_BUFFERS: 86 return 0; 87 case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: 88 return 16; 89 /* nv4x capabilities */ 90 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 91 case PIPE_CAP_NPOT_TEXTURES: 92 case PIPE_CAP_CONDITIONAL_RENDER: 93 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 94 case PIPE_CAP_PRIMITIVE_RESTART: 95 return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0; 96 /* unsupported */ 97 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 98 case PIPE_CAP_SM3: 99 case PIPE_CAP_INDEP_BLEND_ENABLE: 100 case PIPE_CAP_INDEP_BLEND_FUNC: 101 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 102 case PIPE_CAP_SHADER_STENCIL_EXPORT: 103 case PIPE_CAP_TGSI_INSTANCEID: 104 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: /* XXX: yes? */ 105 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 106 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 107 case PIPE_CAP_MIN_TEXEL_OFFSET: 108 case PIPE_CAP_MAX_TEXEL_OFFSET: 109 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 110 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 111 case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: 112 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 113 case PIPE_CAP_TEXTURE_BARRIER: 114 case PIPE_CAP_SEAMLESS_CUBE_MAP: 115 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 116 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 117 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 118 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 119 case PIPE_CAP_START_INSTANCE: 120 return 0; 121 case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: 122 case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: 123 case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: 124 return 1; 125 default: 126 debug_printf("unknown param %d\n", param); 127 return 0; 128 } 129 } 130 131 static float 132 nv30_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param) 133 { 134 struct nv30_screen *screen = nv30_screen(pscreen); 135 struct nouveau_object *eng3d = screen->eng3d; 136 137 switch (param) { 138 case PIPE_CAPF_MAX_LINE_WIDTH: 139 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 140 return 10.0; 141 case PIPE_CAPF_MAX_POINT_WIDTH: 142 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 143 return 64.0; 144 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 145 return (eng3d->oclass >= NV40_3D_CLASS) ? 16.0 : 8.0; 146 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 147 return 15.0; 148 default: 149 debug_printf("unknown paramf %d\n", param); 150 return 0; 151 } 152 } 153 154 static int 155 nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader, 156 enum pipe_shader_cap param) 157 { 158 struct nv30_screen *screen = nv30_screen(pscreen); 159 struct nouveau_object *eng3d = screen->eng3d; 160 161 switch (shader) { 162 case PIPE_SHADER_VERTEX: 163 switch (param) { 164 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 165 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 166 return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 256; 167 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 168 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 169 return (eng3d->oclass >= NV40_3D_CLASS) ? 512 : 0; 170 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 171 return 0; 172 case PIPE_SHADER_CAP_MAX_INPUTS: 173 return 16; 174 case PIPE_SHADER_CAP_MAX_CONSTS: 175 return (eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6); 176 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 177 return 1; 178 case PIPE_SHADER_CAP_MAX_TEMPS: 179 return (eng3d->oclass >= NV40_3D_CLASS) ? 32 : 13; 180 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 181 return 0; 182 case PIPE_SHADER_CAP_MAX_ADDRS: 183 return 2; 184 case PIPE_SHADER_CAP_MAX_PREDS: 185 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 186 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 187 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 188 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 189 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 190 case PIPE_SHADER_CAP_SUBROUTINES: 191 case PIPE_SHADER_CAP_INTEGERS: 192 return 0; 193 default: 194 debug_printf("unknown vertex shader param %d\n", param); 195 return 0; 196 } 197 break; 198 case PIPE_SHADER_FRAGMENT: 199 switch (param) { 200 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 201 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 202 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 203 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 204 return 4096; 205 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 206 return 0; 207 case PIPE_SHADER_CAP_MAX_INPUTS: 208 return (eng3d->oclass >= NV40_3D_CLASS) ? 12 : 10; 209 case PIPE_SHADER_CAP_MAX_CONSTS: 210 return (eng3d->oclass >= NV40_3D_CLASS) ? 224 : 32; 211 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 212 return 1; 213 case PIPE_SHADER_CAP_MAX_TEMPS: 214 return 32; 215 case PIPE_SHADER_CAP_MAX_ADDRS: 216 return (eng3d->oclass >= NV40_3D_CLASS) ? 1 : 0; 217 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 218 return 16; 219 case PIPE_SHADER_CAP_MAX_PREDS: 220 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 221 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 222 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 223 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 224 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 225 case PIPE_SHADER_CAP_SUBROUTINES: 226 return 0; 227 default: 228 debug_printf("unknown fragment shader param %d\n", param); 229 return 0; 230 } 231 break; 232 default: 233 return 0; 234 } 235 } 236 237 static boolean 238 nv30_screen_is_format_supported(struct pipe_screen *pscreen, 239 enum pipe_format format, 240 enum pipe_texture_target target, 241 unsigned sample_count, 242 unsigned bindings) 243 { 244 if (sample_count > 4) 245 return FALSE; 246 if (!(0x00000017 & (1 << sample_count))) 247 return FALSE; 248 249 if (!util_format_s3tc_enabled) { 250 switch (format) { 251 case PIPE_FORMAT_DXT1_RGB: 252 case PIPE_FORMAT_DXT1_RGBA: 253 case PIPE_FORMAT_DXT3_RGBA: 254 case PIPE_FORMAT_DXT5_RGBA: 255 return FALSE; 256 default: 257 break; 258 } 259 } 260 261 /* transfers & shared are always supported */ 262 bindings &= ~(PIPE_BIND_TRANSFER_READ | 263 PIPE_BIND_TRANSFER_WRITE | 264 PIPE_BIND_SHARED); 265 266 return (nv30_format_info(pscreen, format)->bindings & bindings) == bindings; 267 } 268 269 static void 270 nv30_screen_fence_emit(struct pipe_screen *pscreen, uint32_t *sequence) 271 { 272 struct nv30_screen *screen = nv30_screen(pscreen); 273 struct nouveau_pushbuf *push = screen->base.pushbuf; 274 275 *sequence = ++screen->base.fence.sequence; 276 277 BEGIN_NV04(push, NV30_3D(FENCE_OFFSET), 2); 278 PUSH_DATA (push, 0); 279 PUSH_DATA (push, *sequence); 280 } 281 282 static uint32_t 283 nv30_screen_fence_update(struct pipe_screen *pscreen) 284 { 285 struct nv30_screen *screen = nv30_screen(pscreen); 286 struct nv04_notify *fence = screen->fence->data; 287 return *(uint32_t *)((char *)screen->notify->map + fence->offset); 288 } 289 290 static void 291 nv30_screen_destroy(struct pipe_screen *pscreen) 292 { 293 struct nv30_screen *screen = nv30_screen(pscreen); 294 295 if (screen->base.fence.current && 296 screen->base.fence.current->state >= NOUVEAU_FENCE_STATE_EMITTED) { 297 nouveau_fence_wait(screen->base.fence.current); 298 nouveau_fence_ref (NULL, &screen->base.fence.current); 299 } 300 301 nouveau_object_del(&screen->query); 302 nouveau_object_del(&screen->fence); 303 nouveau_object_del(&screen->ntfy); 304 305 nouveau_object_del(&screen->sifm); 306 nouveau_object_del(&screen->swzsurf); 307 nouveau_object_del(&screen->surf2d); 308 nouveau_object_del(&screen->m2mf); 309 nouveau_object_del(&screen->eng3d); 310 nouveau_object_del(&screen->null); 311 312 nouveau_screen_fini(&screen->base); 313 FREE(screen); 314 } 315 316 #define FAIL_SCREEN_INIT(str, err) \ 317 do { \ 318 NOUVEAU_ERR(str, err); \ 319 nv30_screen_destroy(pscreen); \ 320 return NULL; \ 321 } while(0) 322 323 struct pipe_screen * 324 nv30_screen_create(struct nouveau_device *dev) 325 { 326 struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen); 327 struct pipe_screen *pscreen; 328 struct nouveau_pushbuf *push; 329 struct nv04_fifo *fifo; 330 unsigned oclass = 0; 331 int ret, i; 332 333 if (!screen) 334 return NULL; 335 336 switch (dev->chipset & 0xf0) { 337 case 0x30: 338 if (RANKINE_0397_CHIPSET & (1 << (dev->chipset & 0x0f))) 339 oclass = NV30_3D_CLASS; 340 else 341 if (RANKINE_0697_CHIPSET & (1 << (dev->chipset & 0x0f))) 342 oclass = NV34_3D_CLASS; 343 else 344 if (RANKINE_0497_CHIPSET & (1 << (dev->chipset & 0x0f))) 345 oclass = NV35_3D_CLASS; 346 break; 347 case 0x40: 348 if (CURIE_4097_CHIPSET & (1 << (dev->chipset & 0x0f))) 349 oclass = NV40_3D_CLASS; 350 else 351 if (CURIE_4497_CHIPSET & (1 << (dev->chipset & 0x0f))) 352 oclass = NV44_3D_CLASS; 353 break; 354 case 0x60: 355 if (CURIE_4497_CHIPSET6X & (1 << (dev->chipset & 0x0f))) 356 oclass = NV44_3D_CLASS; 357 break; 358 default: 359 break; 360 } 361 362 if (!oclass) { 363 NOUVEAU_ERR("unknown 3d class for 0x%02x\n", dev->chipset); 364 return NULL; 365 } 366 367 pscreen = &screen->base.base; 368 pscreen->destroy = nv30_screen_destroy; 369 pscreen->get_param = nv30_screen_get_param; 370 pscreen->get_paramf = nv30_screen_get_paramf; 371 pscreen->get_shader_param = nv30_screen_get_shader_param; 372 pscreen->context_create = nv30_context_create; 373 pscreen->is_format_supported = nv30_screen_is_format_supported; 374 nv30_resource_screen_init(pscreen); 375 376 screen->base.fence.emit = nv30_screen_fence_emit; 377 screen->base.fence.update = nv30_screen_fence_update; 378 379 ret = nouveau_screen_init(&screen->base, dev); 380 if (ret) 381 FAIL_SCREEN_INIT("nv30_screen_init failed: %d\n", ret); 382 383 screen->base.vidmem_bindings |= PIPE_BIND_VERTEX_BUFFER; 384 screen->base.sysmem_bindings |= PIPE_BIND_VERTEX_BUFFER; 385 if (oclass == NV40_3D_CLASS) { 386 screen->base.vidmem_bindings |= PIPE_BIND_INDEX_BUFFER; 387 screen->base.sysmem_bindings |= PIPE_BIND_INDEX_BUFFER; 388 } 389 390 fifo = screen->base.channel->data; 391 push = screen->base.pushbuf; 392 push->rsvd_kick = 16; 393 394 ret = nouveau_object_new(screen->base.channel, 0x00000000, NV01_NULL_CLASS, 395 NULL, 0, &screen->null); 396 if (ret) 397 FAIL_SCREEN_INIT("error allocating null object: %d\n", ret); 398 399 /* DMA_FENCE refuses to accept DMA objects with "adjust" filled in, 400 * this means that the address pointed at by the DMA object must 401 * be 4KiB aligned, which means this object needs to be the first 402 * one allocated on the channel. 403 */ 404 ret = nouveau_object_new(screen->base.channel, 0xbeef1e00, 405 NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) { 406 .length = 32 }, sizeof(struct nv04_notify), 407 &screen->fence); 408 if (ret) 409 FAIL_SCREEN_INIT("error allocating fence notifier: %d\n", ret); 410 411 /* DMA_NOTIFY object, we don't actually use this but M2MF fails without */ 412 ret = nouveau_object_new(screen->base.channel, 0xbeef0301, 413 NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) { 414 .length = 32 }, sizeof(struct nv04_notify), 415 &screen->ntfy); 416 if (ret) 417 FAIL_SCREEN_INIT("error allocating sync notifier: %d\n", ret); 418 419 /* DMA_QUERY, used to implement occlusion queries, we attempt to allocate 420 * the remainder of the "notifier block" assigned by the kernel for 421 * use as query objects 422 */ 423 ret = nouveau_object_new(screen->base.channel, 0xbeef0351, 424 NOUVEAU_NOTIFIER_CLASS, &(struct nv04_notify) { 425 .length = 4096 - 128 }, sizeof(struct nv04_notify), 426 &screen->query); 427 if (ret) 428 FAIL_SCREEN_INIT("error allocating query notifier: %d\n", ret); 429 430 ret = nouveau_heap_init(&screen->query_heap, 0, 4096 - 128); 431 if (ret) 432 FAIL_SCREEN_INIT("error creating query heap: %d\n", ret); 433 434 LIST_INITHEAD(&screen->queries); 435 436 /* Vertex program resources (code/data), currently 6 of the constant 437 * slots are reserved to implement user clipping planes 438 */ 439 if (oclass < NV40_3D_CLASS) { 440 nouveau_heap_init(&screen->vp_exec_heap, 0, 256); 441 nouveau_heap_init(&screen->vp_data_heap, 6, 256 - 6); 442 } else { 443 nouveau_heap_init(&screen->vp_exec_heap, 0, 512); 444 nouveau_heap_init(&screen->vp_data_heap, 6, 468 - 6); 445 } 446 447 ret = nouveau_bo_wrap(screen->base.device, fifo->notify, &screen->notify); 448 if (ret == 0) 449 nouveau_bo_map(screen->notify, 0, screen->base.client); 450 if (ret) 451 FAIL_SCREEN_INIT("error mapping notifier memory: %d\n", ret); 452 453 ret = nouveau_object_new(screen->base.channel, 0xbeef3097, oclass, 454 NULL, 0, &screen->eng3d); 455 if (ret) 456 FAIL_SCREEN_INIT("error allocating 3d object: %d\n", ret); 457 458 BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); 459 PUSH_DATA (push, screen->eng3d->handle); 460 BEGIN_NV04(push, NV30_3D(DMA_NOTIFY), 13); 461 PUSH_DATA (push, screen->ntfy->handle); 462 PUSH_DATA (push, fifo->vram); /* TEXTURE0 */ 463 PUSH_DATA (push, fifo->gart); /* TEXTURE1 */ 464 PUSH_DATA (push, fifo->vram); /* COLOR1 */ 465 PUSH_DATA (push, screen->null->handle); /* UNK190 */ 466 PUSH_DATA (push, fifo->vram); /* COLOR0 */ 467 PUSH_DATA (push, fifo->vram); /* ZETA */ 468 PUSH_DATA (push, fifo->vram); /* VTXBUF0 */ 469 PUSH_DATA (push, fifo->gart); /* VTXBUF1 */ 470 PUSH_DATA (push, screen->fence->handle); /* FENCE */ 471 PUSH_DATA (push, screen->query->handle); /* QUERY - intr 0x80 if nullobj */ 472 PUSH_DATA (push, screen->null->handle); /* UNK1AC */ 473 PUSH_DATA (push, screen->null->handle); /* UNK1B0 */ 474 if (screen->eng3d->oclass < NV40_3D_CLASS) { 475 BEGIN_NV04(push, SUBC_3D(0x03b0), 1); 476 PUSH_DATA (push, 0x00100000); 477 BEGIN_NV04(push, SUBC_3D(0x1d80), 1); 478 PUSH_DATA (push, 3); 479 480 BEGIN_NV04(push, SUBC_3D(0x1e98), 1); 481 PUSH_DATA (push, 0); 482 BEGIN_NV04(push, SUBC_3D(0x17e0), 3); 483 PUSH_DATA (push, fui(0.0)); 484 PUSH_DATA (push, fui(0.0)); 485 PUSH_DATA (push, fui(1.0)); 486 BEGIN_NV04(push, SUBC_3D(0x1f80), 16); 487 for (i = 0; i < 16; i++) 488 PUSH_DATA (push, (i == 8) ? 0x0000ffff : 0); 489 490 BEGIN_NV04(push, NV30_3D(RC_ENABLE), 1); 491 PUSH_DATA (push, 0); 492 } else { 493 BEGIN_NV04(push, NV40_3D(DMA_COLOR2), 2); 494 PUSH_DATA (push, fifo->vram); 495 PUSH_DATA (push, fifo->vram); /* COLOR3 */ 496 497 BEGIN_NV04(push, SUBC_3D(0x1450), 1); 498 PUSH_DATA (push, 0x00000004); 499 500 BEGIN_NV04(push, SUBC_3D(0x1ea4), 3); /* ZCULL */ 501 PUSH_DATA (push, 0x00000010); 502 PUSH_DATA (push, 0x01000100); 503 PUSH_DATA (push, 0xff800006); 504 505 /* vtxprog output routing */ 506 BEGIN_NV04(push, SUBC_3D(0x1fc4), 1); 507 PUSH_DATA (push, 0x06144321); 508 BEGIN_NV04(push, SUBC_3D(0x1fc8), 2); 509 PUSH_DATA (push, 0xedcba987); 510 PUSH_DATA (push, 0x0000006f); 511 BEGIN_NV04(push, SUBC_3D(0x1fd0), 1); 512 PUSH_DATA (push, 0x00171615); 513 BEGIN_NV04(push, SUBC_3D(0x1fd4), 1); 514 PUSH_DATA (push, 0x001b1a19); 515 516 BEGIN_NV04(push, SUBC_3D(0x1ef8), 1); 517 PUSH_DATA (push, 0x0020ffff); 518 BEGIN_NV04(push, SUBC_3D(0x1d64), 1); 519 PUSH_DATA (push, 0x01d300d4); 520 521 BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1); 522 PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN); 523 } 524 525 ret = nouveau_object_new(screen->base.channel, 0xbeef3901, NV03_M2MF_CLASS, 526 NULL, 0, &screen->m2mf); 527 if (ret) 528 FAIL_SCREEN_INIT("error allocating m2mf object: %d\n", ret); 529 530 BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1); 531 PUSH_DATA (push, screen->m2mf->handle); 532 BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1); 533 PUSH_DATA (push, screen->ntfy->handle); 534 535 ret = nouveau_object_new(screen->base.channel, 0xbeef6201, 536 NV10_SURFACE_2D_CLASS, NULL, 0, &screen->surf2d); 537 if (ret) 538 FAIL_SCREEN_INIT("error allocating surf2d object: %d\n", ret); 539 540 BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1); 541 PUSH_DATA (push, screen->surf2d->handle); 542 BEGIN_NV04(push, NV04_SF2D(DMA_NOTIFY), 1); 543 PUSH_DATA (push, screen->ntfy->handle); 544 545 if (dev->chipset < 0x40) 546 oclass = NV30_SURFACE_SWZ_CLASS; 547 else 548 oclass = NV40_SURFACE_SWZ_CLASS; 549 550 ret = nouveau_object_new(screen->base.channel, 0xbeef5201, oclass, 551 NULL, 0, &screen->swzsurf); 552 if (ret) 553 FAIL_SCREEN_INIT("error allocating swizzled surface object: %d\n", ret); 554 555 BEGIN_NV04(push, NV01_SUBC(SSWZ, OBJECT), 1); 556 PUSH_DATA (push, screen->swzsurf->handle); 557 BEGIN_NV04(push, NV04_SSWZ(DMA_NOTIFY), 1); 558 PUSH_DATA (push, screen->ntfy->handle); 559 560 if (dev->chipset < 0x40) 561 oclass = NV30_SIFM_CLASS; 562 else 563 oclass = NV40_SIFM_CLASS; 564 565 ret = nouveau_object_new(screen->base.channel, 0xbeef7701, oclass, 566 NULL, 0, &screen->sifm); 567 if (ret) 568 FAIL_SCREEN_INIT("error allocating scaled image object: %d\n", ret); 569 570 BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1); 571 PUSH_DATA (push, screen->sifm->handle); 572 BEGIN_NV04(push, NV03_SIFM(DMA_NOTIFY), 1); 573 PUSH_DATA (push, screen->ntfy->handle); 574 BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1); 575 PUSH_DATA (push, NV05_SIFM_COLOR_CONVERSION_TRUNCATE); 576 577 nouveau_pushbuf_kick(push, push->channel); 578 579 nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE); 580 return pscreen; 581 } 582