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(mesa_format format) 38{ 39 switch (format) { 40 case MESA_FORMAT_A_UNORM8: 41 case MESA_FORMAT_L_UNORM8: 42 case MESA_FORMAT_I_UNORM8: 43 case MESA_FORMAT_B2G3R3_UNORM: 44 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8; 45 46 case MESA_FORMAT_B5G6R5_UNORM: 47 case MESA_FORMAT_R5G6B5_UNORM: 48 case MESA_FORMAT_B4G4R4A4_UNORM: 49 case MESA_FORMAT_A4R4G4B4_UNORM: 50 case MESA_FORMAT_B5G5R5A1_UNORM: 51 case MESA_FORMAT_A1B5G5R5_UNORM: 52 case MESA_FORMAT_A1R5G5B5_UNORM: 53 case MESA_FORMAT_LA_UNORM8: 54 case MESA_FORMAT_YCBCR: 55 case MESA_FORMAT_YCBCR_REV: 56 case MESA_FORMAT_Z_UNORM16: 57 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5; 58 59 case MESA_FORMAT_A8B8G8R8_UNORM: 60 case MESA_FORMAT_R8G8B8A8_UNORM: 61 case MESA_FORMAT_B8G8R8X8_UNORM: 62 case MESA_FORMAT_B8G8R8A8_UNORM: 63 case MESA_FORMAT_A8R8G8B8_UNORM: 64 case MESA_FORMAT_Z24_UNORM_S8_UINT: 65 case MESA_FORMAT_S8_UINT_Z24_UNORM: 66 case MESA_FORMAT_Z_UNORM32: 67 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8; 68 69 default: 70 assert(0); 71 } 72} 73 74static inline int 75surf2d_format(mesa_format format) 76{ 77 switch (format) { 78 case MESA_FORMAT_A_UNORM8: 79 case MESA_FORMAT_L_UNORM8: 80 case MESA_FORMAT_I_UNORM8: 81 case MESA_FORMAT_B2G3R3_UNORM: 82 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; 83 84 case MESA_FORMAT_B5G6R5_UNORM: 85 case MESA_FORMAT_R5G6B5_UNORM: 86 case MESA_FORMAT_B4G4R4A4_UNORM: 87 case MESA_FORMAT_A4R4G4B4_UNORM: 88 case MESA_FORMAT_B5G5R5A1_UNORM: 89 case MESA_FORMAT_A1B5G5R5_UNORM: 90 case MESA_FORMAT_A1R5G5B5_UNORM: 91 case MESA_FORMAT_LA_UNORM8: 92 case MESA_FORMAT_YCBCR: 93 case MESA_FORMAT_YCBCR_REV: 94 case MESA_FORMAT_Z_UNORM16: 95 return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; 96 97 case MESA_FORMAT_A8B8G8R8_UNORM: 98 case MESA_FORMAT_R8G8B8A8_UNORM: 99 case MESA_FORMAT_B8G8R8X8_UNORM: 100 case MESA_FORMAT_B8G8R8A8_UNORM: 101 case MESA_FORMAT_A8R8G8B8_UNORM: 102 case MESA_FORMAT_Z24_UNORM_S8_UINT: 103 case MESA_FORMAT_S8_UINT_Z24_UNORM: 104 case MESA_FORMAT_Z_UNORM32: 105 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; 106 107 default: 108 assert(0); 109 } 110} 111 112static inline int 113rect_format(mesa_format format) 114{ 115 switch (format) { 116 case MESA_FORMAT_A_UNORM8: 117 case MESA_FORMAT_L_UNORM8: 118 case MESA_FORMAT_I_UNORM8: 119 case MESA_FORMAT_B2G3R3_UNORM: 120 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; 121 122 case MESA_FORMAT_B5G6R5_UNORM: 123 case MESA_FORMAT_R5G6B5_UNORM: 124 case MESA_FORMAT_B4G4R4A4_UNORM: 125 case MESA_FORMAT_A4R4G4B4_UNORM: 126 case MESA_FORMAT_B5G5R5A1_UNORM: 127 case MESA_FORMAT_A1B5G5R5_UNORM: 128 case MESA_FORMAT_A1R5G5B5_UNORM: 129 case MESA_FORMAT_LA_UNORM8: 130 case MESA_FORMAT_YCBCR: 131 case MESA_FORMAT_YCBCR_REV: 132 case MESA_FORMAT_Z_UNORM16: 133 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; 134 135 case MESA_FORMAT_A8B8G8R8_UNORM: 136 case MESA_FORMAT_R8G8B8A8_UNORM: 137 case MESA_FORMAT_B8G8R8X8_UNORM: 138 case MESA_FORMAT_B8G8R8A8_UNORM: 139 case MESA_FORMAT_A8R8G8B8_UNORM: 140 case MESA_FORMAT_Z24_UNORM_S8_UINT: 141 case MESA_FORMAT_S8_UINT_Z24_UNORM: 142 case MESA_FORMAT_Z_UNORM32: 143 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; 144 145 default: 146 assert(0); 147 } 148} 149 150static inline int 151sifm_format(mesa_format format) 152{ 153 switch (format) { 154 case MESA_FORMAT_A_UNORM8: 155 case MESA_FORMAT_L_UNORM8: 156 case MESA_FORMAT_I_UNORM8: 157 case MESA_FORMAT_B2G3R3_UNORM: 158 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8; 159 160 case MESA_FORMAT_B5G6R5_UNORM: 161 case MESA_FORMAT_R5G6B5_UNORM: 162 case MESA_FORMAT_B4G4R4A4_UNORM: 163 case MESA_FORMAT_A4R4G4B4_UNORM: 164 case MESA_FORMAT_B5G5R5A1_UNORM: 165 case MESA_FORMAT_A1B5G5R5_UNORM: 166 case MESA_FORMAT_A1R5G5B5_UNORM: 167 case MESA_FORMAT_LA_UNORM8: 168 case MESA_FORMAT_YCBCR: 169 case MESA_FORMAT_YCBCR_REV: 170 case MESA_FORMAT_Z_UNORM16: 171 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; 172 173 case MESA_FORMAT_A8B8G8R8_UNORM: 174 case MESA_FORMAT_R8G8B8A8_UNORM: 175 case MESA_FORMAT_B8G8R8X8_UNORM: 176 case MESA_FORMAT_B8G8R8A8_UNORM: 177 case MESA_FORMAT_A8R8G8B8_UNORM: 178 case MESA_FORMAT_Z24_UNORM_S8_UINT: 179 case MESA_FORMAT_S8_UINT_Z24_UNORM: 180 case MESA_FORMAT_Z_UNORM32: 181 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; 182 183 default: 184 assert(0); 185 } 186} 187 188static void 189nv04_surface_copy_swizzle(struct gl_context *ctx, 190 struct nouveau_surface *dst, 191 struct nouveau_surface *src, 192 int dx, int dy, int sx, int sy, 193 int w, int h) 194{ 195 struct nouveau_pushbuf_refn refs[] = { 196 { src->bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 197 { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM }, 198 }; 199 struct nouveau_pushbuf *push = context_push(ctx); 200 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 201 struct nouveau_object *swzsurf = hw->swzsurf; 202 struct nv04_fifo *fifo = hw->chan->data; 203 /* Max width & height may not be the same on all HW, but must be POT */ 204 const unsigned max_w = 1024; 205 const unsigned max_h = 1024; 206 unsigned sub_w = w > max_w ? max_w : w; 207 unsigned sub_h = h > max_h ? max_h : h; 208 unsigned x, y; 209 210 /* Swizzled surfaces must be POT */ 211 assert(util_is_power_of_two_or_zero(dst->width) && 212 util_is_power_of_two_or_zero(dst->height)); 213 214 if (context_chipset(ctx) < 0x10) { 215 BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1); 216 PUSH_DATA (push, swzsurf->handle); 217 } 218 219 for (y = 0; y < h; y += sub_h) { 220 sub_h = MIN2(sub_h, h - y); 221 222 for (x = 0; x < w; x += sub_w) { 223 sub_w = MIN2(sub_w, w - x); 224 225 if (nouveau_pushbuf_space(push, 64, 4, 0) || 226 nouveau_pushbuf_refn (push, refs, 2)) 227 return; 228 229 BEGIN_NV04(push, NV04_SSWZ(DMA_IMAGE), 1); 230 PUSH_DATA (push, fifo->vram); 231 BEGIN_NV04(push, NV04_SSWZ(FORMAT), 2); 232 PUSH_DATA (push, swzsurf_format(dst->format) | 233 log2i(dst->width) << 16 | 234 log2i(dst->height) << 24); 235 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 236 237 BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1); 238 PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 239 BEGIN_NV04(push, NV05_SIFM(SURFACE), 1); 240 PUSH_DATA (push, swzsurf->handle); 241 242 BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 8); 243 PUSH_DATA (push, sifm_format(src->format)); 244 PUSH_DATA (push, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); 245 PUSH_DATA (push, (y + dy) << 16 | (x + dx)); 246 PUSH_DATA (push, sub_h << 16 | sub_w); 247 PUSH_DATA (push, (y + dy) << 16 | (x + dx)); 248 PUSH_DATA (push, sub_h << 16 | sub_w); 249 PUSH_DATA (push, 1 << 20); 250 PUSH_DATA (push, 1 << 20); 251 252 BEGIN_NV04(push, NV03_SIFM(SIZE), 4); 253 PUSH_DATA (push, align(sub_h, 2) << 16 | align(sub_w, 2)); 254 PUSH_DATA (push, src->pitch | 255 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | 256 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); 257 PUSH_RELOC(push, src->bo, src->offset + (y + sy) * src->pitch + 258 (x + sx) * src->cpp, NOUVEAU_BO_LOW, 0, 0); 259 PUSH_DATA (push, 0); 260 } 261 } 262 263 if (context_chipset(ctx) < 0x10) { 264 BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1); 265 PUSH_DATA (push, hw->surf3d->handle); 266 } 267} 268 269static void 270nv04_surface_copy_m2mf(struct gl_context *ctx, 271 struct nouveau_surface *dst, 272 struct nouveau_surface *src, 273 int dx, int dy, int sx, int sy, 274 int w, int h) 275{ 276 struct nouveau_pushbuf_refn refs[] = { 277 { src->bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 278 { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 279 }; 280 struct nouveau_pushbuf *push = context_push(ctx); 281 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 282 struct nv04_fifo *fifo = hw->chan->data; 283 unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp; 284 unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp; 285 286 while (h) { 287 int count = (h > 2047) ? 2047 : h; 288 289 if (nouveau_pushbuf_space(push, 16, 4, 0) || 290 nouveau_pushbuf_refn (push, refs, 2)) 291 return; 292 293 BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2); 294 PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 295 PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 296 BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8); 297 PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0); 298 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 299 PUSH_DATA (push, src->pitch); 300 PUSH_DATA (push, dst->pitch); 301 PUSH_DATA (push, w * src->cpp); 302 PUSH_DATA (push, count); 303 PUSH_DATA (push, 0x0101); 304 PUSH_DATA (push, 0); 305 306 src_offset += src->pitch * count; 307 dst_offset += dst->pitch * count; 308 h -= count; 309 } 310} 311 312typedef unsigned (*get_offset_t)(struct nouveau_surface *s, 313 unsigned x, unsigned y); 314 315static unsigned 316get_linear_offset(struct nouveau_surface *s, unsigned x, unsigned y) 317{ 318 return x * s->cpp + y * s->pitch; 319} 320 321static unsigned 322get_swizzled_offset(struct nouveau_surface *s, unsigned x, unsigned y) 323{ 324 unsigned k = log2i(MIN2(s->width, s->height)); 325 326 unsigned u = (x & 0x001) << 0 | 327 (x & 0x002) << 1 | 328 (x & 0x004) << 2 | 329 (x & 0x008) << 3 | 330 (x & 0x010) << 4 | 331 (x & 0x020) << 5 | 332 (x & 0x040) << 6 | 333 (x & 0x080) << 7 | 334 (x & 0x100) << 8 | 335 (x & 0x200) << 9 | 336 (x & 0x400) << 10 | 337 (x & 0x800) << 11; 338 339 unsigned v = (y & 0x001) << 1 | 340 (y & 0x002) << 2 | 341 (y & 0x004) << 3 | 342 (y & 0x008) << 4 | 343 (y & 0x010) << 5 | 344 (y & 0x020) << 6 | 345 (y & 0x040) << 7 | 346 (y & 0x080) << 8 | 347 (y & 0x100) << 9 | 348 (y & 0x200) << 10 | 349 (y & 0x400) << 11 | 350 (y & 0x800) << 12; 351 352 return s->cpp * (((u | v) & ~(~0 << 2*k)) | 353 (x & (~0 << k)) << k | 354 (y & (~0 << k)) << k); 355} 356 357static void 358nv04_surface_copy_cpu(struct gl_context *ctx, 359 struct nouveau_surface *dst, 360 struct nouveau_surface *src, 361 int dx, int dy, int sx, int sy, 362 int w, int h) 363{ 364 int x, y; 365 get_offset_t get_dst = (dst->layout == SWIZZLED ? 366 get_swizzled_offset : get_linear_offset); 367 get_offset_t get_src = (src->layout == SWIZZLED ? 368 get_swizzled_offset : get_linear_offset); 369 void *dp, *sp; 370 371 nouveau_bo_map(dst->bo, NOUVEAU_BO_WR, context_client(ctx)); 372 nouveau_bo_map(src->bo, NOUVEAU_BO_RD, context_client(ctx)); 373 374 dp = dst->bo->map + dst->offset; 375 sp = src->bo->map + src->offset; 376 377 for (y = 0; y < h; y++) { 378 for (x = 0; x < w; x++) { 379 memcpy(dp + get_dst(dst, dx + x, dy + y), 380 sp + get_src(src, sx + x, sy + y), dst->cpp); 381 } 382 } 383} 384 385void 386nv04_surface_copy(struct gl_context *ctx, 387 struct nouveau_surface *dst, 388 struct nouveau_surface *src, 389 int dx, int dy, int sx, int sy, 390 int w, int h) 391{ 392 if (_mesa_is_format_compressed(src->format)) { 393 sx = get_format_blocksx(src->format, sx); 394 sy = get_format_blocksy(src->format, sy); 395 dx = get_format_blocksx(dst->format, dx); 396 dy = get_format_blocksy(dst->format, dy); 397 w = get_format_blocksx(src->format, w); 398 h = get_format_blocksy(src->format, h); 399 } 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_pushbuf_refn refs[] = { 426 { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, 427 }; 428 struct nouveau_pushbuf *push = context_push(ctx); 429 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 430 struct nv04_fifo *fifo = hw->chan->data; 431 432 if (nouveau_pushbuf_space(push, 64, 4, 0) || 433 nouveau_pushbuf_refn (push, refs, 1)) 434 return; 435 436 BEGIN_NV04(push, NV04_SF2D(DMA_IMAGE_SOURCE), 2); 437 PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 438 PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); 439 BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); 440 PUSH_DATA (push, surf2d_format(dst->format)); 441 PUSH_DATA (push, (dst->pitch << 16) | dst->pitch); 442 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 443 PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); 444 445 BEGIN_NV04(push, NV01_PATT(COLOR_FORMAT), 1); 446 PUSH_DATA (push, rect_format(dst->format)); 447 BEGIN_NV04(push, NV01_PATT(MONOCHROME_COLOR1), 1); 448 PUSH_DATA (push, mask | ~0ll << (8 * dst->cpp)); 449 450 BEGIN_NV04(push, NV04_GDI(COLOR_FORMAT), 1); 451 PUSH_DATA (push, rect_format(dst->format)); 452 BEGIN_NV04(push, NV04_GDI(COLOR1_A), 1); 453 PUSH_DATA (push, value); 454 BEGIN_NV04(push, NV04_GDI(UNCLIPPED_RECTANGLE_POINT(0)), 2); 455 PUSH_DATA (push, (dx << 16) | dy); 456 PUSH_DATA (push, ( w << 16) | h); 457} 458 459void 460nv04_surface_takedown(struct gl_context *ctx) 461{ 462 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 463 464 nouveau_object_del(&hw->swzsurf); 465 nouveau_object_del(&hw->sifm); 466 nouveau_object_del(&hw->rect); 467 nouveau_object_del(&hw->rop); 468 nouveau_object_del(&hw->patt); 469 nouveau_object_del(&hw->surf2d); 470 nouveau_object_del(&hw->m2mf); 471 nouveau_object_del(&hw->ntfy); 472} 473 474GLboolean 475nv04_surface_init(struct gl_context *ctx) 476{ 477 struct nouveau_pushbuf *push = context_push(ctx); 478 struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; 479 struct nouveau_object *chan = hw->chan; 480 unsigned handle = 0x88000000, class; 481 int ret; 482 483 /* Notifier object. */ 484 ret = nouveau_object_new(chan, handle++, NOUVEAU_NOTIFIER_CLASS, 485 &(struct nv04_notify) { 486 .length = 32, 487 }, sizeof(struct nv04_notify), &hw->ntfy); 488 if (ret) 489 goto fail; 490 491 /* Memory to memory format. */ 492 ret = nouveau_object_new(chan, handle++, NV03_M2MF_CLASS, 493 NULL, 0, &hw->m2mf); 494 if (ret) 495 goto fail; 496 497 BEGIN_NV04(push, NV01_SUBC(M2MF, OBJECT), 1); 498 PUSH_DATA (push, hw->m2mf->handle); 499 BEGIN_NV04(push, NV03_M2MF(DMA_NOTIFY), 1); 500 PUSH_DATA (push, hw->ntfy->handle); 501 502 /* Context surfaces 2D. */ 503 if (context_chipset(ctx) < 0x10) 504 class = NV04_SURFACE_2D_CLASS; 505 else 506 class = NV10_SURFACE_2D_CLASS; 507 508 ret = nouveau_object_new(chan, handle++, class, NULL, 0, &hw->surf2d); 509 if (ret) 510 goto fail; 511 512 BEGIN_NV04(push, NV01_SUBC(SF2D, OBJECT), 1); 513 PUSH_DATA (push, hw->surf2d->handle); 514 515 /* Raster op. */ 516 ret = nouveau_object_new(chan, handle++, NV03_ROP_CLASS, 517 NULL, 0, &hw->rop); 518 if (ret) 519 goto fail; 520 521 BEGIN_NV04(push, NV01_SUBC(PATT, OBJECT), 1); 522 PUSH_DATA (push, hw->rop->handle); 523 BEGIN_NV04(push, NV01_ROP(DMA_NOTIFY), 1); 524 PUSH_DATA (push, hw->ntfy->handle); 525 526 BEGIN_NV04(push, NV01_ROP(ROP), 1); 527 PUSH_DATA (push, 0xca); /* DPSDxax in the GDI speech. */ 528 529 /* Image pattern. */ 530 ret = nouveau_object_new(chan, handle++, NV04_PATTERN_CLASS, 531 NULL, 0, &hw->patt); 532 if (ret) 533 goto fail; 534 535 BEGIN_NV04(push, NV01_SUBC(PATT, OBJECT), 1); 536 PUSH_DATA (push, hw->patt->handle); 537 BEGIN_NV04(push, NV01_PATT(DMA_NOTIFY), 1); 538 PUSH_DATA (push, hw->ntfy->handle); 539 540 BEGIN_NV04(push, NV01_PATT(MONOCHROME_FORMAT), 3); 541 PUSH_DATA (push, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE); 542 PUSH_DATA (push, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8); 543 PUSH_DATA (push, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO); 544 545 BEGIN_NV04(push, NV01_PATT(MONOCHROME_COLOR0), 4); 546 PUSH_DATA (push, 0); 547 PUSH_DATA (push, 0); 548 PUSH_DATA (push, ~0); 549 PUSH_DATA (push, ~0); 550 551 /* GDI rectangle text. */ 552 ret = nouveau_object_new(chan, handle++, NV04_GDI_CLASS, 553 NULL, 0, &hw->rect); 554 if (ret) 555 goto fail; 556 557 BEGIN_NV04(push, NV01_SUBC(GDI, OBJECT), 1); 558 PUSH_DATA (push, hw->rect->handle); 559 BEGIN_NV04(push, NV04_GDI(DMA_NOTIFY), 1); 560 PUSH_DATA (push, hw->ntfy->handle); 561 BEGIN_NV04(push, NV04_GDI(SURFACE), 1); 562 PUSH_DATA (push, hw->surf2d->handle); 563 BEGIN_NV04(push, NV04_GDI(ROP), 1); 564 PUSH_DATA (push, hw->rop->handle); 565 BEGIN_NV04(push, NV04_GDI(PATTERN), 1); 566 PUSH_DATA (push, hw->patt->handle); 567 568 BEGIN_NV04(push, NV04_GDI(OPERATION), 1); 569 PUSH_DATA (push, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND); 570 BEGIN_NV04(push, NV04_GDI(MONOCHROME_FORMAT), 1); 571 PUSH_DATA (push, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); 572 573 /* Swizzled surface. */ 574 if (context_chipset(ctx) < 0x20) 575 class = NV04_SURFACE_SWZ_CLASS; 576 else if (context_chipset (ctx) < 0x30) 577 class = NV20_SURFACE_SWZ_CLASS; 578 else 579 class = NV30_SURFACE_SWZ_CLASS; 580 581 ret = nouveau_object_new(chan, handle++, class, NULL, 0, &hw->swzsurf); 582 if (ret) 583 goto fail; 584 585 BEGIN_NV04(push, NV01_SUBC(SURF, OBJECT), 1); 586 PUSH_DATA (push, hw->swzsurf->handle); 587 588 /* Scaled image from memory. */ 589 if (context_chipset(ctx) < 0x10) 590 class = NV04_SIFM_CLASS; 591 else 592 class = NV10_SIFM_CLASS; 593 594 ret = nouveau_object_new(chan, handle++, class, NULL, 0, &hw->sifm); 595 if (ret) 596 goto fail; 597 598 BEGIN_NV04(push, NV01_SUBC(SIFM, OBJECT), 1); 599 PUSH_DATA (push, hw->sifm->handle); 600 601 if (context_chipset(ctx) >= 0x10) { 602 BEGIN_NV04(push, NV05_SIFM(COLOR_CONVERSION), 1); 603 PUSH_DATA (push, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); 604 } 605 606 return GL_TRUE; 607 608fail: 609 nv04_surface_takedown(ctx); 610 return GL_FALSE; 611} 612