nv04_surface.c revision 0c1b71665487fcaeffa8f4d7b5ad0ba425a2c169
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 36static inline int 37swzsurf_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 75static inline int 76surf2d_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 114static inline int 115rect_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 153static inline int 154sifm_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 192static void 193nv04_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_channel *chan = context_chan(ctx); 200 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 201 struct nouveau_grobj *swzsurf = hw->swzsurf; 202 struct nouveau_grobj *sifm = hw->sifm; 203 struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); 204 const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; 205 /* Max width & height may not be the same on all HW, but must be POT */ 206 const unsigned max_w = 1024; 207 const unsigned max_h = 1024; 208 unsigned sub_w = w > max_w ? max_w : w; 209 unsigned sub_h = h > max_h ? max_h : h; 210 unsigned x, y; 211 212 /* Swizzled surfaces must be POT */ 213 assert(_mesa_is_pow_two(dst->width) && 214 _mesa_is_pow_two(dst->height)); 215 216 nouveau_bo_marko(bctx, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 217 src->bo, bo_flags | NOUVEAU_BO_RD); 218 nouveau_bo_marko(bctx, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 219 dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 220 nouveau_bo_markl(bctx, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 221 dst->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); 222 223 BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); 224 OUT_RING (chan, swzsurf_format(dst->format) | 225 log2i(dst->width) << 16 | 226 log2i(dst->height) << 24); 227 228 BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); 229 OUT_RING (chan, swzsurf->handle); 230 231 for (y = 0; y < h; y += sub_h) { 232 sub_h = MIN2(sub_h, h - y); 233 234 for (x = 0; x < w; x += sub_w) { 235 sub_w = MIN2(sub_w, w - x); 236 237 MARK_RING(chan, 15, 1); 238 239 BEGIN_RING(chan, sifm, 240 NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 8); 241 OUT_RING(chan, sifm_format(src->format)); 242 OUT_RING(chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); 243 OUT_RING(chan, (y + dy) << 16 | (x + dx)); 244 OUT_RING(chan, sub_h << 16 | sub_w); 245 OUT_RING(chan, (y + dy) << 16 | (x + dx)); 246 OUT_RING(chan, sub_h << 16 | sub_w); 247 OUT_RING(chan, 1 << 20); 248 OUT_RING(chan, 1 << 20); 249 250 BEGIN_RING(chan, sifm, 251 NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); 252 OUT_RING(chan, align(sub_h, 2) << 16 | align(sub_w, 2)); 253 OUT_RING(chan, src->pitch | 254 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | 255 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); 256 OUT_RELOCl(chan, src->bo, src->offset + 257 (y + sy) * src->pitch + 258 (x + sx) * src->cpp, 259 bo_flags | NOUVEAU_BO_RD); 260 OUT_RING(chan, 0); 261 } 262 } 263 264 nouveau_bo_context_reset(bctx); 265 266 if (context_chipset(ctx) < 0x10) 267 FIRE_RING(chan); 268} 269 270static void 271nv04_surface_copy_m2mf(struct gl_context *ctx, 272 struct nouveau_surface *dst, 273 struct nouveau_surface *src, 274 int dx, int dy, int sx, int sy, 275 int w, int h) 276{ 277 struct nouveau_channel *chan = context_chan(ctx); 278 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 279 struct nouveau_grobj *m2mf = hw->m2mf; 280 struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); 281 const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; 282 unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp; 283 unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp; 284 285 nouveau_bo_marko(bctx, m2mf, NV04_M2MF_DMA_BUFFER_IN, 286 src->bo, bo_flags | NOUVEAU_BO_RD); 287 nouveau_bo_marko(bctx, m2mf, NV04_M2MF_DMA_BUFFER_OUT, 288 dst->bo, bo_flags | NOUVEAU_BO_WR); 289 290 while (h) { 291 int count = (h > 2047) ? 2047 : h; 292 293 MARK_RING(chan, 9, 2); 294 295 BEGIN_RING(chan, m2mf, NV04_M2MF_OFFSET_IN, 8); 296 OUT_RELOCl(chan, src->bo, src_offset, 297 bo_flags | NOUVEAU_BO_RD); 298 OUT_RELOCl(chan, dst->bo, dst_offset, 299 bo_flags | NOUVEAU_BO_WR); 300 OUT_RING (chan, src->pitch); 301 OUT_RING (chan, dst->pitch); 302 OUT_RING (chan, w * src->cpp); 303 OUT_RING (chan, count); 304 OUT_RING (chan, 0x0101); 305 OUT_RING (chan, 0); 306 307 h -= count; 308 src_offset += src->pitch * count; 309 dst_offset += dst->pitch * count; 310 } 311 312 nouveau_bo_context_reset(bctx); 313 314 if (context_chipset(ctx) < 0x10) 315 FIRE_RING(chan); 316} 317 318typedef unsigned (*get_offset_t)(struct nouveau_surface *s, 319 unsigned x, unsigned y); 320 321static unsigned 322get_linear_offset(struct nouveau_surface *s, unsigned x, unsigned y) 323{ 324 return x * s->cpp + y * s->pitch; 325} 326 327static unsigned 328get_swizzled_offset(struct nouveau_surface *s, unsigned x, unsigned y) 329{ 330 unsigned k = log2i(MIN2(s->width, s->height)); 331 332 unsigned u = (x & 0x001) << 0 | 333 (x & 0x002) << 1 | 334 (x & 0x004) << 2 | 335 (x & 0x008) << 3 | 336 (x & 0x010) << 4 | 337 (x & 0x020) << 5 | 338 (x & 0x040) << 6 | 339 (x & 0x080) << 7 | 340 (x & 0x100) << 8 | 341 (x & 0x200) << 9 | 342 (x & 0x400) << 10 | 343 (x & 0x800) << 11; 344 345 unsigned v = (y & 0x001) << 1 | 346 (y & 0x002) << 2 | 347 (y & 0x004) << 3 | 348 (y & 0x008) << 4 | 349 (y & 0x010) << 5 | 350 (y & 0x020) << 6 | 351 (y & 0x040) << 7 | 352 (y & 0x080) << 8 | 353 (y & 0x100) << 9 | 354 (y & 0x200) << 10 | 355 (y & 0x400) << 11 | 356 (y & 0x800) << 12; 357 358 return s->cpp * (((u | v) & ~(~0 << 2*k)) | 359 (x & (~0 << k)) << k | 360 (y & (~0 << k)) << k); 361} 362 363static void 364nv04_surface_copy_cpu(struct gl_context *ctx, 365 struct nouveau_surface *dst, 366 struct nouveau_surface *src, 367 int dx, int dy, int sx, int sy, 368 int w, int h) 369{ 370 int x, y; 371 get_offset_t get_dst = (dst->layout == SWIZZLED ? 372 get_swizzled_offset : get_linear_offset); 373 get_offset_t get_src = (src->layout == SWIZZLED ? 374 get_swizzled_offset : get_linear_offset); 375 void *dp, *sp; 376 377 nouveau_bo_map(dst->bo, NOUVEAU_BO_WR); 378 nouveau_bo_map(src->bo, NOUVEAU_BO_RD); 379 380 dp = dst->bo->map + dst->offset; 381 sp = src->bo->map + src->offset; 382 383 for (y = 0; y < h; y++) { 384 for (x = 0; x < w; x++) { 385 memcpy(dp + get_dst(dst, dx + x, dy + y), 386 sp + get_src(src, sx + x, sy + y), dst->cpp); 387 } 388 } 389 390 nouveau_bo_unmap(src->bo); 391 nouveau_bo_unmap(dst->bo); 392} 393 394void 395nv04_surface_copy(struct gl_context *ctx, 396 struct nouveau_surface *dst, 397 struct nouveau_surface *src, 398 int dx, int dy, int sx, int sy, 399 int w, int h) 400{ 401 /* Linear texture copy. */ 402 if ((src->layout == LINEAR && dst->layout == LINEAR) || 403 dst->width <= 2 || dst->height <= 1) { 404 nv04_surface_copy_m2mf(ctx, dst, src, dx, dy, sx, sy, w, h); 405 return; 406 } 407 408 /* Swizzle using sifm+swzsurf. */ 409 if (src->layout == LINEAR && dst->layout == SWIZZLED && 410 dst->cpp != 1 && !(dst->offset & 63)) { 411 nv04_surface_copy_swizzle(ctx, dst, src, dx, dy, sx, sy, w, h); 412 return; 413 } 414 415 /* Fallback to CPU copy. */ 416 nv04_surface_copy_cpu(ctx, dst, src, dx, dy, sx, sy, w, h); 417} 418 419void 420nv04_surface_fill(struct gl_context *ctx, 421 struct nouveau_surface *dst, 422 unsigned mask, unsigned value, 423 int dx, int dy, int w, int h) 424{ 425 struct nouveau_channel *chan = context_chan(ctx); 426 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 427 struct nouveau_grobj *surf2d = hw->surf2d; 428 struct nouveau_grobj *patt = hw->patt; 429 struct nouveau_grobj *rect = hw->rect; 430 unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; 431 432 MARK_RING (chan, 19, 4); 433 434 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); 435 OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); 436 OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); 437 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); 438 OUT_RING (chan, surf2d_format(dst->format)); 439 OUT_RING (chan, (dst->pitch << 16) | dst->pitch); 440 OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); 441 OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); 442 443 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_COLOR_FORMAT, 1); 444 OUT_RING (chan, rect_format(dst->format)); 445 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR1, 1); 446 OUT_RING (chan, mask | ~0ll << (8 * dst->cpp)); 447 448 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); 449 OUT_RING (chan, rect_format(dst->format)); 450 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); 451 OUT_RING (chan, value); 452 BEGIN_RING(chan, rect, 453 NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); 454 OUT_RING (chan, (dx << 16) | dy); 455 OUT_RING (chan, ( w << 16) | h); 456 457 if (context_chipset(ctx) < 0x10) 458 FIRE_RING(chan); 459} 460 461void 462nv04_surface_takedown(struct gl_context *ctx) 463{ 464 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 465 466 nouveau_grobj_free(&hw->swzsurf); 467 nouveau_grobj_free(&hw->sifm); 468 nouveau_grobj_free(&hw->rect); 469 nouveau_grobj_free(&hw->rop); 470 nouveau_grobj_free(&hw->patt); 471 nouveau_grobj_free(&hw->surf2d); 472 nouveau_grobj_free(&hw->m2mf); 473 nouveau_notifier_free(&hw->ntfy); 474} 475 476GLboolean 477nv04_surface_init(struct gl_context *ctx) 478{ 479 struct nouveau_channel *chan = context_chan(ctx); 480 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 481 unsigned handle = 0x88000000, class; 482 int ret; 483 484 /* Notifier object. */ 485 ret = nouveau_notifier_alloc(chan, handle++, 1, &hw->ntfy); 486 if (ret) 487 goto fail; 488 489 /* Memory to memory format. */ 490 ret = nouveau_grobj_alloc(chan, handle++, NV04_M2MF, &hw->m2mf); 491 if (ret) 492 goto fail; 493 494 BEGIN_RING(chan, hw->m2mf, NV04_M2MF_DMA_NOTIFY, 1); 495 OUT_RING (chan, hw->ntfy->handle); 496 497 /* Context surfaces 2D. */ 498 if (context_chipset(ctx) < 0x10) 499 class = NV04_CONTEXT_SURFACES_2D; 500 else 501 class = NV10_CONTEXT_SURFACES_2D; 502 503 ret = nouveau_grobj_alloc(chan, handle++, class, &hw->surf2d); 504 if (ret) 505 goto fail; 506 507 /* Raster op. */ 508 ret = nouveau_grobj_alloc(chan, handle++, NV03_CONTEXT_ROP, &hw->rop); 509 if (ret) 510 goto fail; 511 512 BEGIN_RING(chan, hw->rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1); 513 OUT_RING (chan, hw->ntfy->handle); 514 515 BEGIN_RING(chan, hw->rop, NV03_CONTEXT_ROP_ROP, 1); 516 OUT_RING (chan, 0xca); /* DPSDxax in the GDI speech. */ 517 518 /* Image pattern. */ 519 ret = nouveau_grobj_alloc(chan, handle++, NV04_IMAGE_PATTERN, 520 &hw->patt); 521 if (ret) 522 goto fail; 523 524 BEGIN_RING(chan, hw->patt, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1); 525 OUT_RING (chan, hw->ntfy->handle); 526 527 BEGIN_RING(chan, hw->patt, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3); 528 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE); 529 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8); 530 OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO); 531 532 BEGIN_RING(chan, hw->patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4); 533 OUT_RING (chan, 0); 534 OUT_RING (chan, 0); 535 OUT_RING (chan, ~0); 536 OUT_RING (chan, ~0); 537 538 /* GDI rectangle text. */ 539 ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT, 540 &hw->rect); 541 if (ret) 542 goto fail; 543 544 BEGIN_RING(chan, hw->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); 545 OUT_RING (chan, hw->ntfy->handle); 546 BEGIN_RING(chan, hw->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); 547 OUT_RING (chan, hw->surf2d->handle); 548 BEGIN_RING(chan, hw->rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1); 549 OUT_RING (chan, hw->rop->handle); 550 BEGIN_RING(chan, hw->rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1); 551 OUT_RING (chan, hw->patt->handle); 552 553 BEGIN_RING(chan, hw->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); 554 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND); 555 BEGIN_RING(chan, hw->rect, 556 NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); 557 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); 558 559 /* Swizzled surface. */ 560 if (context_chipset(ctx) < 0x20) 561 class = NV04_SWIZZLED_SURFACE; 562 else 563 class = NV20_SWIZZLED_SURFACE; 564 565 ret = nouveau_grobj_alloc(chan, handle++, class, &hw->swzsurf); 566 if (ret) 567 goto fail; 568 569 /* Scaled image from memory. */ 570 if (context_chipset(ctx) < 0x10) 571 class = NV04_SCALED_IMAGE_FROM_MEMORY; 572 else 573 class = NV10_SCALED_IMAGE_FROM_MEMORY; 574 575 ret = nouveau_grobj_alloc(chan, handle++, class, &hw->sifm); 576 if (ret) 577 goto fail; 578 579 if (context_chipset(ctx) >= 0x10) { 580 BEGIN_RING(chan, hw->sifm, 581 NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1); 582 OUT_RING(chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); 583 } 584 585 return GL_TRUE; 586 587fail: 588 nv04_surface_takedown(ctx); 589 return GL_FALSE; 590} 591