1/* 2 * Copyright 2007 Stephane Marchesin 3 * Copyright 2007 Arthur Huillet 4 * Copyright 2007 Peter Winters 5 * Copyright 2009 Francisco Jerez 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included in 15 * all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 */ 25 26#ifdef HAVE_CONFIG_H 27#include "config.h" 28#endif 29 30#include "nv_include.h" 31 32#include "hwdefs/nv_object.xml.h" 33#include "hwdefs/nv10_3d.xml.h" 34#include "nv04_accel.h" 35 36/* Texture/Render target formats. */ 37static struct pict_format { 38 int exa; 39 int hw; 40} nv10_tex_format_pot[] = { 41 { PICT_a8, 0x80 }, 42 { PICT_r5g6b5, 0x280 }, 43 { PICT_x8r8g8b8, 0x300 }, 44 { PICT_a8r8g8b8, 0x300 }, 45 {}, 46 47}, nv10_tex_format_rect[] = { 48 { PICT_a8, 0x980 }, 49 { PICT_r5g6b5, 0x880 }, 50 { PICT_x8r8g8b8, 0x900 }, 51 { PICT_a8r8g8b8, 0x900 }, 52 {}, 53 54}, nv20_tex_format_rect[] = { 55 { PICT_a8, 0xd80 }, 56 { PICT_r5g6b5, 0x880 }, 57 { PICT_x8r8g8b8, 0x900 }, 58 { PICT_a8r8g8b8, 0x900 }, 59 {}, 60 61}, nv10_rt_format[] = { 62 { PICT_r5g6b5, 0x103 }, 63 { PICT_x8r8g8b8, 0x108 }, 64 { PICT_a8r8g8b8, 0x108 }, 65 {}, 66}; 67 68static int 69get_tex_format(NVPtr pNv, PicturePtr pict) 70{ 71 /* If repeat is set we're always handling a 1x1 texture with 72 * ARGB/XRGB destination, in that case we change the format to 73 * use the POT (swizzled) matching format. 74 */ 75 struct pict_format *format = 76 pict->repeat != RepeatNone ? nv10_tex_format_pot : 77 pNv->Architecture == NV_ARCH_20 ? nv20_tex_format_rect : 78 nv10_tex_format_rect; 79 80 for (; format->hw; format++) { 81 if (format->exa == pict->format) 82 return format->hw; 83 } 84 85 return 0; 86} 87 88static int 89get_rt_format(PicturePtr pict) 90{ 91 struct pict_format *format = nv10_rt_format; 92 93 for (; format->hw; format++) { 94 if (format->exa == pict->format) 95 return format->hw; 96 } 97 98 return 0; 99} 100 101/* Blending functions. */ 102#define SF(x) NV10_3D_BLEND_FUNC_SRC_##x 103#define DF(x) NV10_3D_BLEND_FUNC_DST_##x 104 105static struct pict_op { 106 int src; 107 int dst; 108 109} nv10_pict_op[] = { 110 { SF(ZERO), DF(ZERO) }, /* Clear */ 111 { SF(ONE), DF(ZERO) }, /* Src */ 112 { SF(ZERO), DF(ONE) }, /* Dst */ 113 { SF(ONE), DF(ONE_MINUS_SRC_ALPHA) }, /* Over */ 114 { SF(ONE_MINUS_DST_ALPHA), DF(ONE) }, /* OverReverse */ 115 { SF(DST_ALPHA), DF(ZERO) }, /* In */ 116 { SF(ZERO), DF(SRC_ALPHA) }, /* InReverse */ 117 { SF(ONE_MINUS_DST_ALPHA), DF(ZERO) }, /* Out */ 118 { SF(ZERO), DF(ONE_MINUS_SRC_ALPHA) }, /* OutReverse */ 119 { SF(DST_ALPHA), DF(ONE_MINUS_SRC_ALPHA) }, /* Atop */ 120 { SF(ONE_MINUS_DST_ALPHA), DF(SRC_ALPHA) }, /* AtopReverse */ 121 { SF(ONE_MINUS_DST_ALPHA), DF(ONE_MINUS_SRC_ALPHA) }, /* Xor */ 122 { SF(ONE), DF(ONE) }, /* Add */ 123}; 124 125static inline Bool 126needs_src_alpha(int op) 127{ 128 return nv10_pict_op[op].dst == DF(ONE_MINUS_SRC_ALPHA) 129 || nv10_pict_op[op].dst == DF(SRC_ALPHA); 130} 131 132static inline Bool 133needs_src(int op) 134{ 135 return nv10_pict_op[op].src != SF(ZERO); 136} 137 138static inline Bool 139effective_component_alpha(PicturePtr mask) 140{ 141 return mask && mask->componentAlpha && PICT_FORMAT_RGB(mask->format); 142} 143 144static Bool 145check_texture(NVPtr pNv, PicturePtr pict) 146{ 147 int w = 1, h = 1; 148 149 if (pict->pDrawable) { 150 w = pict->pDrawable->width; 151 h = pict->pDrawable->height; 152 } else { 153 if (pict->pSourcePict->type != SourcePictTypeSolidFill) 154 NOUVEAU_FALLBACK("gradient pictures unsupported\n"); 155 } 156 157 if (w > 2046 || h > 2046) 158 NOUVEAU_FALLBACK("picture too large, %dx%d\n", w, h); 159 160 if (!get_tex_format(pNv, pict)) 161 return FALSE; 162 163 if (pict->filter != PictFilterNearest && 164 pict->filter != PictFilterBilinear) 165 return FALSE; 166 167 /* We cannot repeat on NV10 because NPOT textures do not 168 * support this. unfortunately. */ 169 if (pict->repeat != RepeatNone) 170 /* we can repeat 1x1 textures */ 171 if (!(w == 1 && h == 1)) 172 return FALSE; 173 174 return TRUE; 175} 176 177static Bool 178check_render_target(PicturePtr pict) 179{ 180 int w = pict->pDrawable->width; 181 int h = pict->pDrawable->height; 182 183 if (w > 4096 || h > 4096) 184 return FALSE; 185 186 if (!get_rt_format(pict)) 187 return FALSE; 188 189 return TRUE; 190} 191 192static Bool 193check_pict_op(int op) 194{ 195 /* We do no saturate, disjoint, conjoint, though we 196 * could do e.g. DisjointClear which really is 197 * Clear. */ 198 return op < PictOpSaturate; 199} 200 201#if 0 202static void 203print_fallback_info(char *reason, int op, PicturePtr src, PicturePtr mask, 204 PicturePtr dst) 205{ 206 char out2[4096]; 207 char *out = out2; 208 209 sprintf(out, "%s ", reason); 210 out += strlen(out); 211 212 switch (op) { 213 case PictOpClear: 214 sprintf(out, "PictOpClear "); 215 break; 216 case PictOpSrc: 217 sprintf(out, "PictOpSrc "); 218 break; 219 case PictOpDst: 220 sprintf(out, "PictOpDst "); 221 break; 222 case PictOpOver: 223 sprintf(out, "PictOpOver "); 224 break; 225 case PictOpOutReverse: 226 sprintf(out, "PictOpOutReverse "); 227 break; 228 case PictOpAdd: 229 sprintf(out, "PictOpAdd "); 230 break; 231 default: 232 sprintf(out, "PictOp%d ", op); 233 } 234 out += strlen(out); 235 236 switch (src->format) { 237 case PICT_a8r8g8b8: 238 sprintf(out, "A8R8G8B8 "); 239 break; 240 case PICT_x8r8g8b8: 241 sprintf(out, "X8R8G8B8 "); 242 break; 243 case PICT_x8b8g8r8: 244 sprintf(out, "X8B8G8R8 "); 245 break; 246 case PICT_r5g6b5: 247 sprintf(out, "R5G6B5 "); 248 break; 249 case PICT_a8: 250 sprintf(out, "A8 "); 251 break; 252 case PICT_a1: 253 sprintf(out, "A1 "); 254 break; 255 default: 256 sprintf(out, "%x ", src->format); 257 } 258 out += strlen(out); 259 260 sprintf(out, "(%dx%d) ", src->pDrawable->width, 261 src->pDrawable->height); 262 if (src->repeat != RepeatNone) 263 strcat(out, "R "); 264 strcat(out, "-> "); 265 out += strlen(out); 266 267 switch (dst->format) { 268 case PICT_a8r8g8b8: 269 sprintf(out, "A8R8G8B8 "); 270 break; 271 case PICT_x8r8g8b8: 272 sprintf(out, "X8R8G8B8 "); 273 break; 274 case PICT_x8b8g8r8: 275 sprintf(out, "X8B8G8R8 "); 276 break; 277 case PICT_r5g6b5: 278 sprintf(out, "R5G6B5 "); 279 break; 280 case PICT_a8: 281 sprintf(out, "A8 "); 282 break; 283 case PICT_a1: 284 sprintf(out, "A1 "); 285 break; 286 default: 287 sprintf(out, "%x ", dst->format); 288 } 289 out += strlen(out); 290 291 sprintf(out, "(%dx%d) ", dst->pDrawable->width, 292 dst->pDrawable->height); 293 if (dst->repeat != RepeatNone) 294 strcat(out, "R "); 295 out += strlen(out); 296 297 if (!mask) 298 sprintf(out, "& NONE"); 299 else { 300 switch (mask->format) { 301 case PICT_a8r8g8b8: 302 sprintf(out, "& A8R8G8B8 "); 303 break; 304 case PICT_x8r8g8b8: 305 sprintf(out, "& X8R8G8B8 "); 306 break; 307 case PICT_x8b8g8r8: 308 sprintf(out, "& X8B8G8R8 "); 309 break; 310 case PICT_a8: 311 sprintf(out, "& A8 "); 312 break; 313 case PICT_a1: 314 sprintf(out, "& A1 "); 315 break; 316 default: 317 sprintf(out, "& %x ", mask->format); 318 } 319 out += strlen(out); 320 321 sprintf(out, "(%dx%d) ", mask->pDrawable->width, 322 mask->pDrawable->height); 323 if (mask->repeat != RepeatNone) 324 strcat(out, "R "); 325 if (mask->componentAlpha) 326 strcat(out, "C "); 327 out += strlen(out); 328 } 329 strcat(out, "\n"); 330 331 xf86DrvMsg(0, X_INFO, "%s", out2); 332} 333#else 334#define print_fallback_info(...) 335#endif 336 337Bool 338NV10EXACheckComposite(int op, PicturePtr src, PicturePtr mask, PicturePtr dst) 339{ 340 ScrnInfoPtr pScrn = xf86ScreenToScrn(dst->pDrawable->pScreen); 341 NVPtr pNv = NVPTR(pScrn); 342 343 if (!check_pict_op(op)) { 344 print_fallback_info("pictop", op, src, mask, dst); 345 return FALSE; 346 } 347 348 if (!check_render_target(dst)) { 349 print_fallback_info("dst", op, src, mask, dst); 350 return FALSE; 351 } 352 353 if (!check_texture(pNv, src)) { 354 print_fallback_info("src", op, src, mask, dst); 355 return FALSE; 356 } 357 358 if (mask) { 359 if (!check_texture(pNv, mask)) { 360 print_fallback_info("mask", op, src, 361 mask, dst); 362 return FALSE; 363 } 364 365 if (effective_component_alpha(mask) && 366 needs_src(op) && needs_src_alpha(op)) { 367 print_fallback_info("ca-mask", op, src, 368 mask, dst); 369 return FALSE; 370 } 371 } 372 373 print_fallback_info("Accelerating", op, src, mask, dst); 374 return TRUE; 375} 376 377static Bool 378setup_texture(NVPtr pNv, int unit, PicturePtr pict, PixmapPtr pixmap) 379{ 380 struct nouveau_pushbuf *push = pNv->pushbuf; 381 struct nouveau_bo *bo = nouveau_pixmap_bo(pixmap); 382 unsigned reloc = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; 383 unsigned h = pict->pDrawable->height; 384 unsigned w = pict->pDrawable->width; 385 unsigned format; 386 387 format = NV10_3D_TEX_FORMAT_WRAP_T_CLAMP_TO_EDGE | 388 NV10_3D_TEX_FORMAT_WRAP_S_CLAMP_TO_EDGE | 389 log2i(w) << 20 | log2i(h) << 16 | 390 1 << 12 | /* lod == 1 */ 391 get_tex_format(pNv, pict) | 392 0x50 /* UNK */; 393 394 /* NPOT_SIZE expects an even number for width, we can round up uneven 395 * numbers here because EXA always gives 64 byte aligned pixmaps and 396 * for all formats we support 64 bytes represents an even number of 397 * pixels 398 */ 399 w = (w + 1) & ~1; 400 401 BEGIN_NV04(push, NV10_3D(TEX_OFFSET(unit)), 1); 402 PUSH_MTHDl(push, NV10_3D(TEX_OFFSET(unit)), bo, 0, reloc); 403 BEGIN_NV04(push, NV10_3D(TEX_FORMAT(unit)), 1); 404 PUSH_MTHDs(push, NV10_3D(TEX_FORMAT(unit)), bo, format, reloc, 405 NV10_3D_TEX_FORMAT_DMA0, 406 NV10_3D_TEX_FORMAT_DMA1); 407 BEGIN_NV04(push, NV10_3D(TEX_ENABLE(unit)), 1 ); 408 PUSH_DATA (push, NV10_3D_TEX_ENABLE_ENABLE); 409 BEGIN_NV04(push, NV10_3D(TEX_NPOT_PITCH(unit)), 1); 410 PUSH_DATA (push, exaGetPixmapPitch(pixmap) << 16); 411 BEGIN_NV04(push, NV10_3D(TEX_NPOT_SIZE(unit)), 1); 412 PUSH_DATA (push, (w << 16) | h); 413 BEGIN_NV04(push, NV10_3D(TEX_FILTER(unit)), 1); 414 if (pict->filter == PictFilterNearest) 415 PUSH_DATA(push, NV10_3D_TEX_FILTER_MAGNIFY_NEAREST | 416 NV10_3D_TEX_FILTER_MINIFY_NEAREST); 417 else 418 PUSH_DATA(push, NV10_3D_TEX_FILTER_MAGNIFY_LINEAR | 419 NV10_3D_TEX_FILTER_MINIFY_LINEAR); 420 if (pict->transform) { 421 BEGIN_NV04(push, NV10_3D(TEX_MATRIX_ENABLE(unit)), 1); 422 PUSH_DATA (push, 1); 423 BEGIN_NV04(push, NV10_3D(TEX_MATRIX(unit, 0)), 16); 424 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[0][0])); 425 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[0][1])); 426 PUSH_DATAf(push, 0.f); 427 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[0][2])); 428 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[1][0])); 429 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[1][1])); 430 PUSH_DATAf(push, 0.f); 431 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[1][2])); 432 PUSH_DATAf(push, 0.0f); 433 PUSH_DATAf(push, 0.0f); 434 PUSH_DATAf(push, 0.0f); 435 PUSH_DATAf(push, 0.0f); 436 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[2][0])); 437 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[2][1])); 438 PUSH_DATAf(push, 0.0f); 439 PUSH_DATAf(push, xFixedToFloat(pict->transform->matrix[2][2])); 440 } else { 441 BEGIN_NV04(push, NV10_3D(TEX_MATRIX_ENABLE(unit)), 1); 442 PUSH_DATA (push, 0); 443 } 444 445 return TRUE; 446} 447 448static Bool 449setup_render_target(NVPtr pNv, PicturePtr pict, PixmapPtr pixmap) 450{ 451 struct nouveau_pushbuf *push = pNv->pushbuf; 452 struct nouveau_bo *bo = nouveau_pixmap_bo(pixmap); 453 454 BEGIN_NV04(push, NV10_3D(RT_FORMAT), 3); 455 PUSH_DATA (push, get_rt_format(pict)); 456 PUSH_DATA (push, (exaGetPixmapPitch(pixmap) << 16 | 457 exaGetPixmapPitch(pixmap))); 458 PUSH_MTHDl(push, NV10_3D(COLOR_OFFSET), bo, 0, 459 NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); 460 return TRUE; 461} 462 463static void 464setup_blend_function(NVPtr pNv, PicturePtr pdpict, PicturePtr pmpict, int alu) 465{ 466 struct nouveau_pushbuf *push = pNv->pushbuf; 467 struct pict_op *op = &nv10_pict_op[alu]; 468 int src_factor = op->src; 469 int dst_factor = op->dst; 470 471 if (src_factor == SF(ONE_MINUS_DST_ALPHA) && 472 !PICT_FORMAT_A(pdpict->format)) 473 /* ONE_MINUS_DST_ALPHA doesn't always do the right thing for 474 * framebuffers without alpha channel. But it's the same as 475 * ZERO in that case. 476 */ 477 src_factor = SF(ZERO); 478 479 if (effective_component_alpha(pmpict)) { 480 if (dst_factor == DF(SRC_ALPHA)) 481 dst_factor = DF(SRC_COLOR); 482 else if (dst_factor == DF(ONE_MINUS_SRC_ALPHA)) 483 dst_factor = DF(ONE_MINUS_SRC_COLOR); 484 } 485 486 BEGIN_NV04(push, NV10_3D(BLEND_FUNC_SRC), 2); 487 PUSH_DATA (push, src_factor); 488 PUSH_DATA (push, dst_factor); 489 BEGIN_NV04(push, NV10_3D(BLEND_FUNC_ENABLE), 1); 490 PUSH_DATA (push, 1); 491} 492 493#define RCSRC_COL(i) (0x01 + (unit)) 494#define RCSRC_TEX(i) (0x08 + (unit)) 495#define RCSEL_COLOR (0x00) 496#define RCSEL_ALPHA (0x10) 497#define RCINP_ZERO (0x00) 498#define RCINP_ONE (0x20) 499#define RCINP_A__SHIFT 24 500#define RCINP_B__SHIFT 16 501 502static Bool 503setup_picture(NVPtr pNv, PicturePtr pict, PixmapPtr pixmap, int unit, 504 uint32_t *color, uint32_t *alpha) 505{ 506 struct nouveau_pushbuf *push = pNv->pushbuf; 507 uint32_t shift, source; 508 509 if (pict && pict->pDrawable) { 510 if (!setup_texture(pNv, unit, pict, pixmap)) 511 return FALSE; 512 source = RCSRC_TEX(unit); 513 } else 514 if (pict) { 515 BEGIN_NV04(push, NV10_3D(RC_COLOR(unit)), 1); 516 PUSH_DATA (push, pict->pSourcePict->solidFill.color); 517 source = RCSRC_COL(unit); 518 } 519 520 if (pict && PICT_FORMAT_RGB(pict->format)) 521 *color = RCSEL_COLOR | source; 522 else 523 *color = RCSEL_COLOR | RCINP_ZERO; 524 525 if (pict && PICT_FORMAT_A(pict->format)) 526 *alpha = RCSEL_ALPHA | source; 527 else 528 *alpha = RCSEL_ALPHA | RCINP_ONE; 529 530 if (unit) 531 shift = RCINP_B__SHIFT; 532 else 533 shift = RCINP_A__SHIFT; 534 *color <<= shift; 535 *alpha <<= shift; 536 return TRUE; 537} 538 539Bool 540NV10EXAPrepareComposite(int op, 541 PicturePtr pict_src, 542 PicturePtr pict_mask, 543 PicturePtr pict_dst, 544 PixmapPtr src, 545 PixmapPtr mask, 546 PixmapPtr dst) 547{ 548 ScrnInfoPtr pScrn = xf86ScreenToScrn(dst->drawable.pScreen); 549 NVPtr pNv = NVPTR(pScrn); 550 struct nouveau_pushbuf *push = pNv->pushbuf; 551 uint32_t sc, sa, mc, ma; 552 553 if (!PUSH_SPACE(push, 128)) 554 return FALSE; 555 PUSH_RESET(push); 556 557 /* setup render target and blending */ 558 if (!setup_render_target(pNv, pict_dst, dst)) 559 return FALSE; 560 setup_blend_function(pNv, pict_dst, pict_mask, op); 561 562 /* select picture sources */ 563 if (!setup_picture(pNv, pict_src, src, 0, &sc, &sa)) 564 return FALSE; 565 if (!setup_picture(pNv, pict_mask, mask, 1, &mc, &ma)) 566 return FALSE; 567 568 /* configure register combiners */ 569 BEGIN_NV04(push, NV10_3D(RC_IN_ALPHA(0)), 1); 570 PUSH_DATA (push, sa | ma); 571 BEGIN_NV04(push, NV10_3D(RC_IN_RGB(0)), 1); 572 if (effective_component_alpha(pict_mask)) { 573 if (needs_src_alpha(op)) 574 PUSH_DATA(push, sa | mc); 575 else 576 PUSH_DATA(push, sc | mc); 577 } else { 578 PUSH_DATA(push, sc | ma); 579 } 580 581 nouveau_pushbuf_bufctx(push, pNv->bufctx); 582 if (nouveau_pushbuf_validate(push)) { 583 nouveau_pushbuf_bufctx(push, NULL); 584 return FALSE; 585 } 586 587 pNv->pspict = pict_src; 588 pNv->pmpict = pict_mask; 589 return TRUE; 590} 591 592static inline void 593PUSH_VTX2s(struct nouveau_pushbuf *push, 594 int x1, int y1, int x2, int y2, int dx, int dy) 595{ 596 BEGIN_NV04(push, NV10_3D(VERTEX_TX0_2I), 1); 597 PUSH_DATA (push, ((y1 & 0xffff) << 16) | (x1 & 0xffff)); 598 BEGIN_NV04(push, NV10_3D(VERTEX_TX1_2I), 1); 599 PUSH_DATA (push, ((y2 & 0xffff) << 16) | (x2 & 0xffff)); 600 BEGIN_NV04(push, NV10_3D(VERTEX_POS_3F_X), 3); 601 PUSH_DATAf(push, dx); 602 PUSH_DATAf(push, dy); 603 PUSH_DATAf(push, 0.0); 604} 605 606void 607NV10EXAComposite(PixmapPtr pix_dst, 608 int sx, int sy, int mx, int my, int dx, int dy, int w, int h) 609{ 610 ScrnInfoPtr pScrn = xf86ScreenToScrn(pix_dst->drawable.pScreen); 611 NVPtr pNv = NVPTR(pScrn); 612 struct nouveau_pushbuf *push = pNv->pushbuf; 613 614 if (!PUSH_SPACE(push, 64)) 615 return; 616 617 BEGIN_NV04(push, NV10_3D(VERTEX_BEGIN_END), 1); 618 PUSH_DATA (push, NV10_3D_VERTEX_BEGIN_END_QUADS); 619 PUSH_VTX2s(push, sx, sy, mx, my, dx, dy); 620 PUSH_VTX2s(push, sx + w, sy, mx + w, my, dx + w, dy); 621 PUSH_VTX2s(push, sx + w, sy + h, mx + w, my + h, dx + w, dy + h); 622 PUSH_VTX2s(push, sx, sy + h, mx, my + h, dx, dy + h); 623 BEGIN_NV04(push, NV10_3D(VERTEX_BEGIN_END), 1); 624 PUSH_DATA (push, NV10_3D_VERTEX_BEGIN_END_STOP); 625} 626 627void 628NV10EXADoneComposite(PixmapPtr dst) 629{ 630 ScrnInfoPtr pScrn = xf86ScreenToScrn(dst->drawable.pScreen); 631 nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL); 632} 633 634Bool 635NVAccelInitNV10TCL(ScrnInfoPtr pScrn) 636{ 637 NVPtr pNv = NVPTR(pScrn); 638 struct nouveau_pushbuf *push = pNv->pushbuf; 639 struct nv04_fifo *fifo = pNv->channel->data; 640 uint32_t class = 0; 641 int i; 642 643 if (((pNv->dev->chipset & 0xf0) != NV_ARCH_10) && 644 ((pNv->dev->chipset & 0xf0) != NV_ARCH_20)) 645 return FALSE; 646 647 if (pNv->dev->chipset >= 0x20 || pNv->dev->chipset == 0x1a) 648 class = NV15_3D_CLASS; 649 else if (pNv->dev->chipset >= 0x17) 650 class = NV17_3D_CLASS; 651 else if (pNv->dev->chipset >= 0x11) 652 class = NV15_3D_CLASS; 653 else 654 class = NV10_3D_CLASS; 655 656 if (nouveau_object_new(pNv->channel, Nv3D, class, NULL, 0, &pNv->Nv3D)) 657 return FALSE; 658 659 if (!PUSH_SPACE(push, 256)) 660 return FALSE; 661 662 BEGIN_NV04(push, NV01_SUBC(3D, OBJECT), 1); 663 PUSH_DATA (push, pNv->Nv3D->handle); 664 BEGIN_NV04(push, NV10_3D(DMA_NOTIFY), 1); 665 PUSH_DATA (push, pNv->NvNull->handle); 666 667 BEGIN_NV04(push, NV10_3D(DMA_TEXTURE0), 2); 668 PUSH_DATA (push, fifo->vram); 669 PUSH_DATA (push, fifo->gart); 670 671 BEGIN_NV04(push, NV10_3D(DMA_COLOR), 2); 672 PUSH_DATA (push, fifo->vram); 673 PUSH_DATA (push, fifo->vram); 674 675 BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); 676 PUSH_DATA (push, 0); 677 678 BEGIN_NV04(push, NV10_3D(RT_HORIZ), 2); 679 PUSH_DATA (push, 2048 << 16 | 0); 680 PUSH_DATA (push, 2048 << 16 | 0); 681 682 BEGIN_NV04(push, NV10_3D(ZETA_OFFSET), 1); 683 PUSH_DATA (push, 0); 684 685 BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_MODE), 1); 686 PUSH_DATA (push, 0); 687 688 BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(0)), 1); 689 PUSH_DATA (push, 0x7ff << 16 | 0x800); 690 BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(0)), 1); 691 PUSH_DATA (push, 0x7ff << 16 | 0x800); 692 693 for (i = 1; i < 8; i++) { 694 BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_HORIZ(i)), 1); 695 PUSH_DATA (push, 0); 696 BEGIN_NV04(push, NV10_3D(VIEWPORT_CLIP_VERT(i)), 1); 697 PUSH_DATA (push, 0); 698 } 699 700 BEGIN_NV04(push, NV10_3D(UNK0290), 1); 701 PUSH_DATA (push, (0x10<<16)|1); 702 BEGIN_NV04(push, NV10_3D(UNK03F4), 1); 703 PUSH_DATA (push, 0); 704 705 BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); 706 PUSH_DATA (push, 0); 707 708 if (class != NV10_3D_CLASS) { 709 /* For nv11, nv17 */ 710 BEGIN_NV04(push, SUBC_3D(NV15_3D_FLIP_SET_READ), 3); 711 PUSH_DATA (push, 0); 712 PUSH_DATA (push, 1); 713 PUSH_DATA (push, 2); 714 715 BEGIN_NV04(push, NV15_BLIT(FLIP_SET_READ), 3); 716 PUSH_DATA (push, 0); 717 PUSH_DATA (push, 1); 718 PUSH_DATA (push, 2); 719 720 BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); 721 PUSH_DATA (push, 0); 722 } 723 724 BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); 725 PUSH_DATA (push, 0); 726 727 /* Set state */ 728 BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 1); 729 PUSH_DATA (push, 0); 730 BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_ENABLE), 1); 731 PUSH_DATA (push, 0); 732 BEGIN_NV04(push, NV10_3D(ALPHA_FUNC_FUNC), 2); 733 PUSH_DATA (push, 0x207); 734 PUSH_DATA (push, 0); 735 BEGIN_NV04(push, NV10_3D(TEX_ENABLE(0)), 2); 736 PUSH_DATA (push, 0); 737 PUSH_DATA (push, 0); 738 BEGIN_NV04(push, NV10_3D(RC_IN_ALPHA(0)), 6); 739 PUSH_DATA (push, 0); 740 PUSH_DATA (push, 0); 741 PUSH_DATA (push, 0); 742 PUSH_DATA (push, 0); 743 PUSH_DATA (push, 0); 744 PUSH_DATA (push, 0); 745 BEGIN_NV04(push, NV10_3D(RC_OUT_ALPHA(0)), 6); 746 PUSH_DATA (push, 0x00000c00); 747 PUSH_DATA (push, 0); 748 PUSH_DATA (push, 0x00000c00); 749 PUSH_DATA (push, 0x18000000); 750 PUSH_DATA (push, 0x300c0000); 751 PUSH_DATA (push, 0x00001c80); 752 BEGIN_NV04(push, NV10_3D(BLEND_FUNC_ENABLE), 1); 753 PUSH_DATA (push, 0); 754 BEGIN_NV04(push, NV10_3D(DITHER_ENABLE), 2); 755 PUSH_DATA (push, 1); 756 PUSH_DATA (push, 0); 757 BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1); 758 PUSH_DATA (push, 0); 759 BEGIN_NV04(push, NV10_3D(VERTEX_WEIGHT_ENABLE), 2); 760 PUSH_DATA (push, 0); 761 PUSH_DATA (push, 0); 762 BEGIN_NV04(push, NV10_3D(BLEND_FUNC_SRC), 4); 763 PUSH_DATA (push, 1); 764 PUSH_DATA (push, 0); 765 PUSH_DATA (push, 0); 766 PUSH_DATA (push, 0x8006); 767 BEGIN_NV04(push, NV10_3D(STENCIL_MASK), 8); 768 PUSH_DATA (push, 0xff); 769 PUSH_DATA (push, 0x207); 770 PUSH_DATA (push, 0); 771 PUSH_DATA (push, 0xff); 772 PUSH_DATA (push, 0x1e00); 773 PUSH_DATA (push, 0x1e00); 774 PUSH_DATA (push, 0x1e00); 775 PUSH_DATA (push, 0x1d01); 776 BEGIN_NV04(push, NV10_3D(NORMALIZE_ENABLE), 1); 777 PUSH_DATA (push, 0); 778 BEGIN_NV04(push, NV10_3D(FOG_ENABLE), 2); 779 PUSH_DATA (push, 0); 780 PUSH_DATA (push, 0); 781 BEGIN_NV04(push, NV10_3D(LIGHT_MODEL), 1); 782 PUSH_DATA (push, 0); 783 BEGIN_NV04(push, NV10_3D(SEPARATE_SPECULAR_ENABLE), 1); 784 PUSH_DATA (push, 0); 785 BEGIN_NV04(push, NV10_3D(ENABLED_LIGHTS), 1); 786 PUSH_DATA (push, 0); 787 BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_POINT_ENABLE), 3); 788 PUSH_DATA (push, 0); 789 PUSH_DATA (push, 0); 790 PUSH_DATA (push, 0); 791 BEGIN_NV04(push, NV10_3D(DEPTH_FUNC), 1); 792 PUSH_DATA (push, 0x201); 793 BEGIN_NV04(push, NV10_3D(DEPTH_WRITE_ENABLE), 1); 794 PUSH_DATA (push, 0); 795 BEGIN_NV04(push, NV10_3D(DEPTH_TEST_ENABLE), 1); 796 PUSH_DATA (push, 0); 797 BEGIN_NV04(push, NV10_3D(POLYGON_OFFSET_FACTOR), 2); 798 PUSH_DATA (push, 0); 799 PUSH_DATA (push, 0); 800 BEGIN_NV04(push, NV10_3D(POINT_SIZE), 1); 801 PUSH_DATA (push, 8); 802 BEGIN_NV04(push, NV10_3D(POINT_PARAMETERS_ENABLE), 2); 803 PUSH_DATA (push, 0); 804 PUSH_DATA (push, 0); 805 BEGIN_NV04(push, NV10_3D(LINE_WIDTH), 1); 806 PUSH_DATA (push, 8); 807 BEGIN_NV04(push, NV10_3D(LINE_SMOOTH_ENABLE), 1); 808 PUSH_DATA (push, 0); 809 BEGIN_NV04(push, NV10_3D(POLYGON_MODE_FRONT), 2); 810 PUSH_DATA (push, 0x1b02); 811 PUSH_DATA (push, 0x1b02); 812 BEGIN_NV04(push, NV10_3D(CULL_FACE), 2); 813 PUSH_DATA (push, 0x405); 814 PUSH_DATA (push, 0x901); 815 BEGIN_NV04(push, NV10_3D(POLYGON_SMOOTH_ENABLE), 1); 816 PUSH_DATA (push, 0); 817 BEGIN_NV04(push, NV10_3D(CULL_FACE_ENABLE), 1); 818 PUSH_DATA (push, 0); 819 BEGIN_NV04(push, NV10_3D(TEX_GEN_MODE(0, 0)), 8); 820 for (i = 0; i < 8; i++) 821 PUSH_DATA (push, 0); 822 823 BEGIN_NV04(push, NV10_3D(FOG_COEFF(0)), 3); 824 PUSH_DATA (push, 0x3fc00000); /* -1.50 */ 825 PUSH_DATA (push, 0xbdb8aa0a); /* -0.09 */ 826 PUSH_DATA (push, 0); /* 0.00 */ 827 828 BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1); 829 PUSH_DATA (push, 0); 830 831 BEGIN_NV04(push, NV10_3D(FOG_MODE), 2); 832 PUSH_DATA (push, 0x802); 833 PUSH_DATA (push, 2); 834 /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when 835 * using texturing, except when using the texture matrix 836 */ 837 BEGIN_NV04(push, NV10_3D(VIEW_MATRIX_ENABLE), 1); 838 PUSH_DATA (push, 6); 839 BEGIN_NV04(push, NV10_3D(COLOR_MASK), 1); 840 PUSH_DATA (push, 0x01010101); 841 842 BEGIN_NV04(push, NV10_3D(PROJECTION_MATRIX(0)), 16); 843 for(i = 0; i < 16; i++) 844 PUSH_DATAf(push, i/4 == i%4 ? 1.0 : 0.0); 845 846 BEGIN_NV04(push, NV10_3D(DEPTH_RANGE_NEAR), 2); 847 PUSH_DATA (push, 0); 848 PUSH_DATAf(push, 65536.0); 849 850 BEGIN_NV04(push, NV10_3D(VIEWPORT_TRANSLATE_X), 4); 851 PUSH_DATAf(push, -2048.0); 852 PUSH_DATAf(push, -2048.0); 853 PUSH_DATAf(push, 0); 854 PUSH_DATA (push, 0); 855 856 /* Set vertex component */ 857 BEGIN_NV04(push, NV10_3D(VERTEX_COL_4F_R), 4); 858 PUSH_DATAf(push, 1.0); 859 PUSH_DATAf(push, 1.0); 860 PUSH_DATAf(push, 1.0); 861 PUSH_DATAf(push, 1.0); 862 BEGIN_NV04(push, NV10_3D(VERTEX_COL2_3F_R), 3); 863 PUSH_DATA (push, 0); 864 PUSH_DATA (push, 0); 865 PUSH_DATA (push, 0); 866 BEGIN_NV04(push, NV10_3D(VERTEX_NOR_3F_X), 3); 867 PUSH_DATA (push, 0); 868 PUSH_DATA (push, 0); 869 PUSH_DATAf(push, 1.0); 870 BEGIN_NV04(push, NV10_3D(VERTEX_TX0_4F_S), 4); 871 PUSH_DATAf(push, 0.0); 872 PUSH_DATAf(push, 0.0); 873 PUSH_DATAf(push, 0.0); 874 PUSH_DATAf(push, 1.0); 875 BEGIN_NV04(push, NV10_3D(VERTEX_TX1_4F_S), 4); 876 PUSH_DATAf(push, 0.0); 877 PUSH_DATAf(push, 0.0); 878 PUSH_DATAf(push, 0.0); 879 PUSH_DATAf(push, 1.0); 880 BEGIN_NV04(push, NV10_3D(VERTEX_FOG_1F), 1); 881 PUSH_DATAf(push, 0.0); 882 BEGIN_NV04(push, NV10_3D(EDGEFLAG_ENABLE), 1); 883 PUSH_DATA (push, 1); 884 885 return TRUE; 886} 887