1 /* 2 * Copyright (C) 2007-2010 The Nouveau Project. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27 #include "nouveau_driver.h" 28 #include "nv_object.xml.h" 29 #include "nv_m2mf.xml.h" 30 #include "nv01_2d.xml.h" 31 #include "nv04_3d.xml.h" 32 #include "nouveau_context.h" 33 #include "nouveau_util.h" 34 #include "nv04_driver.h" 35 36 static inline int 37 swzsurf_format(gl_format format) 38 { 39 switch (format) { 40 case MESA_FORMAT_A8: 41 case MESA_FORMAT_L8: 42 case MESA_FORMAT_I8: 43 case MESA_FORMAT_RGB332: 44 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8; 45 46 case MESA_FORMAT_RGB565: 47 case MESA_FORMAT_RGB565_REV: 48 case MESA_FORMAT_ARGB4444: 49 case MESA_FORMAT_ARGB4444_REV: 50 case MESA_FORMAT_ARGB1555: 51 case MESA_FORMAT_RGBA5551: 52 case MESA_FORMAT_ARGB1555_REV: 53 case MESA_FORMAT_AL88: 54 case MESA_FORMAT_AL88_REV: 55 case MESA_FORMAT_YCBCR: 56 case MESA_FORMAT_YCBCR_REV: 57 case MESA_FORMAT_Z16: 58 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5; 59 60 case MESA_FORMAT_RGBA8888: 61 case MESA_FORMAT_RGBA8888_REV: 62 case MESA_FORMAT_XRGB8888: 63 case MESA_FORMAT_ARGB8888: 64 case MESA_FORMAT_ARGB8888_REV: 65 case MESA_FORMAT_S8_Z24: 66 case MESA_FORMAT_Z24_S8: 67 case MESA_FORMAT_Z32: 68 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8; 69 70 default: 71 assert(0); 72 } 73 } 74 75 static inline int 76 surf2d_format(gl_format format) 77 { 78 switch (format) { 79 case MESA_FORMAT_A8: 80 case MESA_FORMAT_L8: 81 case MESA_FORMAT_I8: 82 case MESA_FORMAT_RGB332: 83 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; 84 85 case MESA_FORMAT_RGB565: 86 case MESA_FORMAT_RGB565_REV: 87 case MESA_FORMAT_ARGB4444: 88 case MESA_FORMAT_ARGB4444_REV: 89 case MESA_FORMAT_ARGB1555: 90 case MESA_FORMAT_RGBA5551: 91 case MESA_FORMAT_ARGB1555_REV: 92 case MESA_FORMAT_AL88: 93 case MESA_FORMAT_AL88_REV: 94 case MESA_FORMAT_YCBCR: 95 case MESA_FORMAT_YCBCR_REV: 96 case MESA_FORMAT_Z16: 97 return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; 98 99 case MESA_FORMAT_RGBA8888: 100 case MESA_FORMAT_RGBA8888_REV: 101 case MESA_FORMAT_XRGB8888: 102 case MESA_FORMAT_ARGB8888: 103 case MESA_FORMAT_ARGB8888_REV: 104 case MESA_FORMAT_S8_Z24: 105 case MESA_FORMAT_Z24_S8: 106 case MESA_FORMAT_Z32: 107 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; 108 109 default: 110 assert(0); 111 } 112 } 113 114 static inline int 115 rect_format(gl_format format) 116 { 117 switch (format) { 118 case MESA_FORMAT_A8: 119 case MESA_FORMAT_L8: 120 case MESA_FORMAT_I8: 121 case MESA_FORMAT_RGB332: 122 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; 123 124 case MESA_FORMAT_RGB565: 125 case MESA_FORMAT_RGB565_REV: 126 case MESA_FORMAT_ARGB4444: 127 case MESA_FORMAT_ARGB4444_REV: 128 case MESA_FORMAT_ARGB1555: 129 case MESA_FORMAT_RGBA5551: 130 case MESA_FORMAT_ARGB1555_REV: 131 case MESA_FORMAT_AL88: 132 case MESA_FORMAT_AL88_REV: 133 case MESA_FORMAT_YCBCR: 134 case MESA_FORMAT_YCBCR_REV: 135 case MESA_FORMAT_Z16: 136 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; 137 138 case MESA_FORMAT_RGBA8888: 139 case MESA_FORMAT_RGBA8888_REV: 140 case MESA_FORMAT_XRGB8888: 141 case MESA_FORMAT_ARGB8888: 142 case MESA_FORMAT_ARGB8888_REV: 143 case MESA_FORMAT_S8_Z24: 144 case MESA_FORMAT_Z24_S8: 145 case MESA_FORMAT_Z32: 146 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; 147 148 default: 149 assert(0); 150 } 151 } 152 153 static inline int 154 sifm_format(gl_format format) 155 { 156 switch (format) { 157 case MESA_FORMAT_A8: 158 case MESA_FORMAT_L8: 159 case MESA_FORMAT_I8: 160 case MESA_FORMAT_RGB332: 161 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8; 162 163 case MESA_FORMAT_RGB565: 164 case MESA_FORMAT_RGB565_REV: 165 case MESA_FORMAT_ARGB4444: 166 case MESA_FORMAT_ARGB4444_REV: 167 case MESA_FORMAT_ARGB1555: 168 case MESA_FORMAT_RGBA5551: 169 case MESA_FORMAT_ARGB1555_REV: 170 case MESA_FORMAT_AL88: 171 case MESA_FORMAT_AL88_REV: 172 case MESA_FORMAT_YCBCR: 173 case MESA_FORMAT_YCBCR_REV: 174 case MESA_FORMAT_Z16: 175 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; 176 177 case MESA_FORMAT_RGBA8888: 178 case MESA_FORMAT_RGBA8888_REV: 179 case MESA_FORMAT_XRGB8888: 180 case MESA_FORMAT_ARGB8888: 181 case MESA_FORMAT_ARGB8888_REV: 182 case MESA_FORMAT_S8_Z24: 183 case MESA_FORMAT_Z24_S8: 184 case MESA_FORMAT_Z32: 185 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; 186 187 default: 188 assert(0); 189 } 190 } 191 192 static void 193 nv04_surface_copy_swizzle(struct gl_context *ctx, 194 struct nouveau_surface *dst, 195 struct nouveau_surface *src, 196 int dx, int dy, int sx, int sy, 197 int w, int h) 198 { 199 struct nouveau_pushbuf_refn refs[] = { 200 { src->bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 201 { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM }, 202 }; 203 struct nouveau_pushbuf *push = context_push(ctx); 204 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 205 struct nouveau_object *swzsurf = hw->swzsurf; 206 struct nv04_fifo *fifo = hw->chan->data; 207 /* Max width & height may not be the same on all HW, but must be POT */ 208 const unsigned max_w = 1024; 209 const unsigned max_h = 1024; 210 unsigned sub_w = w > max_w ? max_w : w; 211 unsigned sub_h = h > max_h ? max_h : h; 212 unsigned x, y; 213 214 /* Swizzled surfaces must be POT */ 215 assert(_mesa_is_pow_two(dst->width) && 216 _mesa_is_pow_two(dst->height)); 217 218 if (context_chipset(ctx) < 0x10) { 219 BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1); 220 PUSH_DATA (push, swzsurf->handle); 221 } 222 223 for (y = 0; y < h; y += sub_h) { 224 sub_h = MIN2(sub_h, h - y); 225 226 for (x = 0; x < w; x += sub_w) { 227 sub_w = MIN2(sub_w, w - x); 228 229 if (nouveau_pushbuf_space(push, 64, 4, 0) || 230 nouveau_pushbuf_refn (push, refs, 2)) 231 return; 232 233 BEGIN_NV04(push, NV04_SSWZ(DMA_IMAGE), 1); 234 PUSH_DATA (push, fifo->vram); 235 BEGIN_NV04(push, NV04_SSWZ(FORMAT), 2); 236 PUSH_DATA (push, swzsurf_format(dst->format) | 237 log2i(dst->width) << 16 | 238 log2i(dst->height) << 24); 239 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 240 241 BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1); 242 PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 243 BEGIN_NV04(push, NV05_SIFM(SURFACE), 1); 244 PUSH_DATA (push, swzsurf->handle); 245 246 BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 8); 247 PUSH_DATA (push, sifm_format(src->format)); 248 PUSH_DATA (push, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); 249 PUSH_DATA (push, (y + dy) << 16 | (x + dx)); 250 PUSH_DATA (push, sub_h << 16 | sub_w); 251 PUSH_DATA (push, (y + dy) << 16 | (x + dx)); 252 PUSH_DATA (push, sub_h << 16 | sub_w); 253 PUSH_DATA (push, 1 << 20); 254 PUSH_DATA (push, 1 << 20); 255 256 BEGIN_NV04(push, NV03_SIFM(SIZE), 4); 257 PUSH_DATA (push, align(sub_h, 2) << 16 | align(sub_w, 2)); 258 PUSH_DATA (push, src->pitch | 259 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | 260 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); 261 PUSH_RELOC(push, src->bo, src->offset + (y + sy) * src->pitch + 262 (x + sx) * src->cpp, NOUVEAU_BO_LOW, 0, 0); 263 PUSH_DATA (push, 0); 264 } 265 } 266 267 if (context_chipset(ctx) < 0x10) { 268 BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1); 269 PUSH_DATA (push, hw->surf3d->handle); 270 } 271 } 272 273 static void 274 nv04_surface_copy_m2mf(struct gl_context *ctx, 275 struct nouveau_surface *dst, 276 struct nouveau_surface *src, 277 int dx, int dy, int sx, int sy, 278 int w, int h) 279 { 280 struct nouveau_pushbuf_refn refs[] = { 281 { src->bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 282 { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 283 }; 284 struct nouveau_pushbuf *push = context_push(ctx); 285 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 286 struct nv04_fifo *fifo = hw->chan->data; 287 unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp; 288 unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp; 289 290 while (h) { 291 int count = (h > 2047) ? 2047 : h; 292 293 if (nouveau_pushbuf_space(push, 16, 4, 0) || 294 nouveau_pushbuf_refn (push, refs, 2)) 295 return; 296 297 BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2); 298 PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 299 PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 300 BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8); 301 PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0); 302 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 303 PUSH_DATA (push, src->pitch); 304 PUSH_DATA (push, dst->pitch); 305 PUSH_DATA (push, w * src->cpp); 306 PUSH_DATA (push, count); 307 PUSH_DATA (push, 0x0101); 308 PUSH_DATA (push, 0); 309 310 src_offset += src->pitch * count; 311 dst_offset += dst->pitch * count; 312 h -= count; 313 } 314 } 315 316 typedef unsigned (*get_offset_t)(struct nouveau_surface *s, 317 unsigned x, unsigned y); 318 319 static unsigned 320 get_linear_offset(struct nouveau_surface *s, unsigned x, unsigned y) 321 { 322 return x * s->cpp + y * s->pitch; 323 } 324 325 static unsigned 326 get_swizzled_offset(struct nouveau_surface *s, unsigned x, unsigned y) 327 { 328 unsigned k = log2i(MIN2(s->width, s->height)); 329 330 unsigned u = (x & 0x001) << 0 | 331 (x & 0x002) << 1 | 332 (x & 0x004) << 2 | 333 (x & 0x008) << 3 | 334 (x & 0x010) << 4 | 335 (x & 0x020) << 5 | 336 (x & 0x040) << 6 | 337 (x & 0x080) << 7 | 338 (x & 0x100) << 8 | 339 (x & 0x200) << 9 | 340 (x & 0x400) << 10 | 341 (x & 0x800) << 11; 342 343 unsigned v = (y & 0x001) << 1 | 344 (y & 0x002) << 2 | 345 (y & 0x004) << 3 | 346 (y & 0x008) << 4 | 347 (y & 0x010) << 5 | 348 (y & 0x020) << 6 | 349 (y & 0x040) << 7 | 350 (y & 0x080) << 8 | 351 (y & 0x100) << 9 | 352 (y & 0x200) << 10 | 353 (y & 0x400) << 11 | 354 (y & 0x800) << 12; 355 356 return s->cpp * (((u | v) & ~(~0 << 2*k)) | 357 (x & (~0 << k)) << k | 358 (y & (~0 << k)) << k); 359 } 360 361 static void 362 nv04_surface_copy_cpu(struct gl_context *ctx, 363 struct nouveau_surface *dst, 364 struct nouveau_surface *src, 365 int dx, int dy, int sx, int sy, 366 int w, int h) 367 { 368 int x, y; 369 get_offset_t get_dst = (dst->layout == SWIZZLED ? 370 get_swizzled_offset : get_linear_offset); 371 get_offset_t get_src = (src->layout == SWIZZLED ? 372 get_swizzled_offset : get_linear_offset); 373 void *dp, *sp; 374 375 nouveau_bo_map(dst->bo, NOUVEAU_BO_WR, context_client(ctx)); 376 nouveau_bo_map(src->bo, NOUVEAU_BO_RD, context_client(ctx)); 377 378 dp = dst->bo->map + dst->offset; 379 sp = src->bo->map + src->offset; 380 381 for (y = 0; y < h; y++) { 382 for (x = 0; x < w; x++) { 383 memcpy(dp + get_dst(dst, dx + x, dy + y), 384 sp + get_src(src, sx + x, sy + y), dst->cpp); 385 } 386 } 387 } 388 389 void 390 nv04_surface_copy(struct gl_context *ctx, 391 struct nouveau_surface *dst, 392 struct nouveau_surface *src, 393 int dx, int dy, int sx, int sy, 394 int w, int h) 395 { 396 if (_mesa_is_format_compressed(src->format)) { 397 sx = get_format_blocksx(src->format, sx); 398 sy = get_format_blocksy(src->format, sy); 399 dx = get_format_blocksx(dst->format, dx); 400 dy = get_format_blocksy(dst->format, dy); 401 w = get_format_blocksx(src->format, w); 402 h = get_format_blocksy(src->format, h); 403 } 404 405 /* Linear texture copy. */ 406 if ((src->layout == LINEAR && dst->layout == LINEAR) || 407 dst->width <= 2 || dst->height <= 1) { 408 nv04_surface_copy_m2mf(ctx, dst, src, dx, dy, sx, sy, w, h); 409 return; 410 } 411 412 /* Swizzle using sifm+swzsurf. */ 413 if (src->layout == LINEAR && dst->layout == SWIZZLED && 414 dst->cpp != 1 && !(dst->offset & 63)) { 415 nv04_surface_copy_swizzle(ctx, dst, src, dx, dy, sx, sy, w, h); 416 return; 417 } 418 419 /* Fallback to CPU copy. */ 420 nv04_surface_copy_cpu(ctx, dst, src, dx, dy, sx, sy, w, h); 421 } 422 423 void 424 nv04_surface_fill(struct gl_context *ctx, 425 struct nouveau_surface *dst, 426 unsigned mask, unsigned value, 427 int dx, int dy, int w, int h) 428 { 429 struct nouveau_pushbuf_refn refs[] = { 430 { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 431 }; 432 struct nouveau_pushbuf *push = context_push(ctx); 433 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 434 struct nv04_fifo *fifo = hw->chan->data; 435 436 if (nouveau_pushbuf_space(push, 64, 4, 0) || 437 nouveau_pushbuf_refn (push, refs, 1)) 438 return; 439 440 BEGIN_NV04(push, NV04_SF2D(DMA_IMAGE_SOURCE), 2); 441 PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 442 PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 443 BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); 444 PUSH_DATA (push, surf2d_format(dst->format)); 445 PUSH_DATA (push, (dst->pitch << 16) | dst->pitch); 446 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 447 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 448 449 BEGIN_NV04(push, NV01_PATT(COLOR_FORMAT), 1); 450 PUSH_DATA (push, rect_format(dst->format)); 451 BEGIN_NV04(push, NV01_PATT(MONOCHROME_COLOR1), 1); 452 PUSH_DATA (push, mask | ~0ll << (8 * dst->cpp)); 453 454 BEGIN_NV04(push, NV04_GDI(COLOR_FORMAT), 1); 455 PUSH_DATA (push, rect_format(dst->format)); 456 BEGIN_NV04(push, NV04_GDI(COLOR1_A), 1); 457 PUSH_DATA (push, value); 458 BEGIN_NV04(push, NV04_GDI(UNCLIPPED_RECTANGLE_POINT(0)), 2); 459 PUSH_DATA (push, (dx << 16) | dy); 460 PUSH_DATA (push, ( w << 16) | h); 461 } 462 463 void 464 nv04_surface_takedown(struct gl_context *ctx) 465 { 466 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 467 468 nouveau_object_del(&hw->swzsurf); 469 nouveau_object_del(&hw->sifm); 470 nouveau_object_del(&hw->rect); 471 nouveau_object_del(&hw->rop); 472 nouveau_object_del(&hw->patt); 473 nouveau_object_del(&hw->surf2d); 474 nouveau_object_del(&hw->m2mf); 475 nouveau_object_del(&hw->ntfy); 476 } 477 478 GLboolean 479 nv04_surface_init(struct gl_context *ctx) 480 { 481 struct nouveau_pushbuf *push = context_push(ctx); 482 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 483 struct nouveau_object *chan = hw->chan; 484 unsigned handle = 0x88000000, class; 485 int ret; 486 487 /* Notifier object. */ 488 ret = nouveau_object_new(chan, handle++, NOUVEAU_NOTIFIER_CLASS, 489 &(struct nv04_notify) { 490 .length = 32, 491 }, sizeof(struct nv04_notify), &hw->ntfy); 492 if (ret) 493 goto fail; 494 495 /* Memory to memory format. */ 496 ret = nouveau_object_new(chan, handle++, NV03_M2MF_CLASS, 497 NULL, 0, &hw->m2mf); 498 if (ret) 499 goto fail; 500 501 BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1); 502 PUSH_DATA (push, hw->m2mf->handle); 503 BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1); 504 PUSH_DATA (push, hw->ntfy->handle); 505 506 /* Context surfaces 2D. */ 507 if (context_chipset(ctx) < 0x10) 508 class = NV04_SURFACE_2D_CLASS; 509 else 510 class = NV10_SURFACE_2D_CLASS; 511 512 ret = nouveau_object_new(chan, handle++, class, NULL, 0, &hw->surf2d); 513 if (ret) 514 goto fail; 515 516 BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1); 517 PUSH_DATA (push, hw->surf2d->handle); 518 519 /* Raster op. */ 520 ret = nouveau_object_new(chan, handle++, NV03_ROP_CLASS, 521 NULL, 0, &hw->rop); 522 if (ret) 523 goto fail; 524 525 BEGIN_NV04(push, NV01_SUBC(PATT, OBJECT), 1); 526 PUSH_DATA (push, hw->rop->handle); 527 BEGIN_NV04(push, NV01_ROP(DMA_NOTIFY), 1); 528 PUSH_DATA (push, hw->ntfy->handle); 529 530 BEGIN_NV04(push, NV01_ROP(ROP), 1); 531 PUSH_DATA (push, 0xca); /* DPSDxax in the GDI speech. */ 532 533 /* Image pattern. */ 534 ret = nouveau_object_new(chan, handle++, NV04_PATTERN_CLASS, 535 NULL, 0, &hw->patt); 536 if (ret) 537 goto fail; 538 539 BEGIN_NV04(push, NV01_SUBC(PATT, OBJECT), 1); 540 PUSH_DATA (push, hw->patt->handle); 541 BEGIN_NV04(push, NV01_PATT(DMA_NOTIFY), 1); 542 PUSH_DATA (push, hw->ntfy->handle); 543 544 BEGIN_NV04(push, NV01_PATT(MONOCHROME_FORMAT), 3); 545 PUSH_DATA (push, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE); 546 PUSH_DATA (push, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8); 547 PUSH_DATA (push, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO); 548 549 BEGIN_NV04(push, NV01_PATT(MONOCHROME_COLOR0), 4); 550 PUSH_DATA (push, 0); 551 PUSH_DATA (push, 0); 552 PUSH_DATA (push, ~0); 553 PUSH_DATA (push, ~0); 554 555 /* GDI rectangle text. */ 556 ret = nouveau_object_new(chan, handle++, NV04_GDI_CLASS, 557 NULL, 0, &hw->rect); 558 if (ret) 559 goto fail; 560 561 BEGIN_NV04(push, NV01_SUBC(GDI, OBJECT), 1); 562 PUSH_DATA (push, hw->rect->handle); 563 BEGIN_NV04(push, NV04_GDI(DMA_NOTIFY), 1); 564 PUSH_DATA (push, hw->ntfy->handle); 565 BEGIN_NV04(push, NV04_GDI(SURFACE), 1); 566 PUSH_DATA (push, hw->surf2d->handle); 567 BEGIN_NV04(push, NV04_GDI(ROP), 1); 568 PUSH_DATA (push, hw->rop->handle); 569 BEGIN_NV04(push, NV04_GDI(PATTERN), 1); 570 PUSH_DATA (push, hw->patt->handle); 571 572 BEGIN_NV04(push, NV04_GDI(OPERATION), 1); 573 PUSH_DATA (push, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND); 574 BEGIN_NV04(push, NV04_GDI(MONOCHROME_FORMAT), 1); 575 PUSH_DATA (push, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); 576 577 /* Swizzled surface. */ 578 if (context_chipset(ctx) < 0x20) 579 class = NV04_SURFACE_SWZ_CLASS; 580 else 581 class = NV20_SURFACE_SWZ_CLASS; 582 583 ret = nouveau_object_new(chan, handle++, class, NULL, 0, &hw->swzsurf); 584 if (ret) 585 goto fail; 586 587 BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1); 588 PUSH_DATA (push, hw->swzsurf->handle); 589 590 /* Scaled image from memory. */ 591 if (context_chipset(ctx) < 0x10) 592 class = NV04_SIFM_CLASS; 593 else 594 class = NV10_SIFM_CLASS; 595 596 ret = nouveau_object_new(chan, handle++, class, NULL, 0, &hw->sifm); 597 if (ret) 598 goto fail; 599 600 BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1); 601 PUSH_DATA (push, hw->sifm->handle); 602 603 if (context_chipset(ctx) >= 0x10) { 604 BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1); 605 PUSH_DATA (push, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); 606 } 607 608 return GL_TRUE; 609 610 fail: 611 nv04_surface_takedown(ctx); 612 return GL_FALSE; 613 } 614