Import a classic DRI driver for nv0x-nv2x.
[mesa.git] / src / mesa / drivers / dri / nouveau / nv04_surface.c
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 "nouveau_class.h"
29 #include "nouveau_context.h"
30 #include "nouveau_util.h"
31 #include "nv04_driver.h"
32
33 static inline int
34 swzsurf_format(gl_format format)
35 {
36 switch (format) {
37 case MESA_FORMAT_A8:
38 case MESA_FORMAT_L8:
39 case MESA_FORMAT_I8:
40 case MESA_FORMAT_RGB332:
41 case MESA_FORMAT_CI8:
42 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8;
43
44 case MESA_FORMAT_RGB565:
45 case MESA_FORMAT_RGB565_REV:
46 case MESA_FORMAT_ARGB4444:
47 case MESA_FORMAT_ARGB4444_REV:
48 case MESA_FORMAT_ARGB1555:
49 case MESA_FORMAT_RGBA5551:
50 case MESA_FORMAT_ARGB1555_REV:
51 case MESA_FORMAT_AL88:
52 case MESA_FORMAT_AL88_REV:
53 case MESA_FORMAT_YCBCR:
54 case MESA_FORMAT_YCBCR_REV:
55 case MESA_FORMAT_Z16:
56 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5;
57
58 case MESA_FORMAT_RGBA8888:
59 case MESA_FORMAT_RGBA8888_REV:
60 case MESA_FORMAT_XRGB8888:
61 case MESA_FORMAT_ARGB8888:
62 case MESA_FORMAT_ARGB8888_REV:
63 case MESA_FORMAT_S8_Z24:
64 case MESA_FORMAT_Z24_S8:
65 case MESA_FORMAT_Z32:
66 return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8;
67
68 default:
69 assert(0);
70 }
71 }
72
73 static inline int
74 surf2d_format(gl_format format)
75 {
76 switch (format) {
77 case MESA_FORMAT_A8:
78 case MESA_FORMAT_L8:
79 case MESA_FORMAT_I8:
80 case MESA_FORMAT_RGB332:
81 case MESA_FORMAT_CI8:
82 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
83
84 case MESA_FORMAT_RGB565:
85 case MESA_FORMAT_RGB565_REV:
86 case MESA_FORMAT_ARGB4444:
87 case MESA_FORMAT_ARGB4444_REV:
88 case MESA_FORMAT_ARGB1555:
89 case MESA_FORMAT_RGBA5551:
90 case MESA_FORMAT_ARGB1555_REV:
91 case MESA_FORMAT_AL88:
92 case MESA_FORMAT_AL88_REV:
93 case MESA_FORMAT_YCBCR:
94 case MESA_FORMAT_YCBCR_REV:
95 case MESA_FORMAT_Z16:
96 return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
97
98 case MESA_FORMAT_RGBA8888:
99 case MESA_FORMAT_RGBA8888_REV:
100 case MESA_FORMAT_XRGB8888:
101 case MESA_FORMAT_ARGB8888:
102 case MESA_FORMAT_ARGB8888_REV:
103 case MESA_FORMAT_S8_Z24:
104 case MESA_FORMAT_Z24_S8:
105 case MESA_FORMAT_Z32:
106 return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
107
108 default:
109 assert(0);
110 }
111 }
112
113 static inline int
114 rect_format(gl_format format)
115 {
116 switch (format) {
117 case MESA_FORMAT_A8:
118 case MESA_FORMAT_L8:
119 case MESA_FORMAT_I8:
120 case MESA_FORMAT_RGB332:
121 case MESA_FORMAT_CI8:
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 case MESA_FORMAT_CI8:
162 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8;
163
164 case MESA_FORMAT_RGB565:
165 case MESA_FORMAT_RGB565_REV:
166 case MESA_FORMAT_ARGB4444:
167 case MESA_FORMAT_ARGB4444_REV:
168 case MESA_FORMAT_ARGB1555:
169 case MESA_FORMAT_RGBA5551:
170 case MESA_FORMAT_ARGB1555_REV:
171 case MESA_FORMAT_AL88:
172 case MESA_FORMAT_AL88_REV:
173 case MESA_FORMAT_YCBCR:
174 case MESA_FORMAT_YCBCR_REV:
175 case MESA_FORMAT_Z16:
176 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5;
177
178 case MESA_FORMAT_RGBA8888:
179 case MESA_FORMAT_RGBA8888_REV:
180 case MESA_FORMAT_XRGB8888:
181 case MESA_FORMAT_ARGB8888:
182 case MESA_FORMAT_ARGB8888_REV:
183 case MESA_FORMAT_S8_Z24:
184 case MESA_FORMAT_Z24_S8:
185 case MESA_FORMAT_Z32:
186 return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8;
187
188 default:
189 assert(0);
190 }
191 }
192
193 static void
194 nv04_surface_copy_swizzle(GLcontext *ctx,
195 struct nouveau_surface *dst,
196 struct nouveau_surface *src,
197 int dx, int dy, int sx, int sy,
198 int w, int h)
199 {
200 struct nouveau_channel *chan = context_chan(ctx);
201 struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
202 struct nouveau_grobj *swzsurf = screen->swzsurf;
203 struct nouveau_grobj *sifm = screen->sifm;
204 struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE);
205 const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART;
206 /* Max width & height may not be the same on all HW, but must be POT */
207 const unsigned max_w = 1024;
208 const unsigned max_h = 1024;
209 unsigned sub_w = w > max_w ? max_w : w;
210 unsigned sub_h = h > max_h ? max_h : h;
211 unsigned x, y;
212
213 /* Swizzled surfaces must be POT */
214 assert(_mesa_is_pow_two(dst->width) &&
215 _mesa_is_pow_two(dst->height));
216
217 /* If area is too large to copy in one shot we must copy it in
218 * POT chunks to meet alignment requirements */
219 assert(sub_w == w || _mesa_is_pow_two(sub_w));
220 assert(sub_h == h || _mesa_is_pow_two(sub_h));
221
222 nouveau_bo_marko(bctx, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE,
223 src->bo, bo_flags | NOUVEAU_BO_RD);
224 nouveau_bo_marko(bctx, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE,
225 dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
226 nouveau_bo_markl(bctx, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET,
227 dst->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
228
229 BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1);
230 OUT_RING (chan, swzsurf_format(dst->format) |
231 log2i(dst->width) << 16 |
232 log2i(dst->height) << 24);
233
234 BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1);
235 OUT_RING (chan, swzsurf->handle);
236
237 for (y = 0; y < h; y += sub_h) {
238 sub_h = MIN2(sub_h, h - y);
239
240 for (x = 0; x < w; x += sub_w) {
241 sub_w = MIN2(sub_w, w - x);
242 /* Must be 64-byte aligned */
243 assert(!(dst->offset & 63));
244
245 MARK_RING(chan, 15, 1);
246
247 BEGIN_RING(chan, sifm,
248 NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 8);
249 OUT_RING(chan, sifm_format(src->format));
250 OUT_RING(chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
251 OUT_RING(chan, (y + dy) << 16 | (x + dx));
252 OUT_RING(chan, sub_h << 16 | sub_w);
253 OUT_RING(chan, (y + dy) << 16 | (x + dx));
254 OUT_RING(chan, sub_h << 16 | sub_w);
255 OUT_RING(chan, 1 << 20);
256 OUT_RING(chan, 1 << 20);
257
258 BEGIN_RING(chan, sifm,
259 NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4);
260 OUT_RING(chan, sub_h << 16 | sub_w);
261 OUT_RING(chan, src->pitch |
262 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
263 NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
264 OUT_RELOCl(chan, src->bo, src->offset +
265 (y + sy) * src->pitch +
266 (x + sx) * src->cpp,
267 bo_flags | NOUVEAU_BO_RD);
268 OUT_RING(chan, 0);
269 }
270 }
271
272 nouveau_bo_context_reset(bctx);
273
274 if (context_chipset(ctx) < 0x10)
275 FIRE_RING(chan);
276 }
277
278 static void
279 nv04_surface_copy_m2mf(GLcontext *ctx,
280 struct nouveau_surface *dst,
281 struct nouveau_surface *src,
282 int dx, int dy, int sx, int sy,
283 int w, int h)
284 {
285 struct nouveau_channel *chan = context_chan(ctx);
286 struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
287 struct nouveau_grobj *m2mf = screen->m2mf;
288 struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE);
289 const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART;
290 unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp;
291 unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp;
292
293 nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN,
294 src->bo, bo_flags | NOUVEAU_BO_RD);
295 nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT,
296 dst->bo, bo_flags | NOUVEAU_BO_WR);
297
298 while (h) {
299 int count = (h > 2047) ? 2047 : h;
300
301 MARK_RING(chan, 9, 2);
302
303 BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
304 OUT_RELOCl(chan, src->bo, src_offset,
305 bo_flags | NOUVEAU_BO_RD);
306 OUT_RELOCl(chan, dst->bo, dst_offset,
307 bo_flags | NOUVEAU_BO_WR);
308 OUT_RING (chan, src->pitch);
309 OUT_RING (chan, dst->pitch);
310 OUT_RING (chan, w * src->cpp);
311 OUT_RING (chan, count);
312 OUT_RING (chan, 0x0101);
313 OUT_RING (chan, 0);
314
315 h -= count;
316 src_offset += src->pitch * count;
317 dst_offset += dst->pitch * count;
318 }
319
320 nouveau_bo_context_reset(bctx);
321
322 if (context_chipset(ctx) < 0x10)
323 FIRE_RING(chan);
324 }
325
326 void
327 nv04_surface_copy(GLcontext *ctx,
328 struct nouveau_surface *dst,
329 struct nouveau_surface *src,
330 int dx, int dy, int sx, int sy,
331 int w, int h)
332 {
333 /* Setup transfer to swizzle the texture to vram if needed */
334 if (src->layout != SWIZZLED &&
335 dst->layout == SWIZZLED &&
336 dst->width > 2 && dst->height > 1) {
337 nv04_surface_copy_swizzle(ctx, dst, src,
338 dx, dy, sx, sy, w, h);
339 return;
340 }
341
342 nv04_surface_copy_m2mf(ctx, dst, src, dx, dy, sx, sy, w, h);
343 }
344
345 void
346 nv04_surface_fill(GLcontext *ctx,
347 struct nouveau_surface *dst,
348 unsigned mask, unsigned value,
349 int dx, int dy, int w, int h)
350 {
351 struct nouveau_channel *chan = context_chan(ctx);
352 struct nouveau_screen *screen = to_nouveau_context(ctx)->screen;
353 struct nouveau_grobj *surf2d = screen->surf2d;
354 struct nouveau_grobj *patt = screen->patt;
355 struct nouveau_grobj *rect = screen->rect;
356 unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART;
357
358 MARK_RING (chan, 19, 4);
359
360 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
361 OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR);
362 OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR);
363 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
364 OUT_RING (chan, surf2d_format(dst->format));
365 OUT_RING (chan, (dst->pitch << 16) | dst->pitch);
366 OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR);
367 OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR);
368
369 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_COLOR_FORMAT, 1);
370 OUT_RING (chan, rect_format(dst->format));
371 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR1, 1);
372 OUT_RING (chan, mask | ~0 << (8 * dst->cpp));
373
374 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
375 OUT_RING (chan, rect_format(dst->format));
376 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
377 OUT_RING (chan, value);
378 BEGIN_RING(chan, rect,
379 NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
380 OUT_RING (chan, (dx << 16) | dy);
381 OUT_RING (chan, ( w << 16) | h);
382
383 if (context_chipset(ctx) < 0x10)
384 FIRE_RING(chan);
385 }
386
387 void
388 nv04_surface_takedown(struct nouveau_screen *screen)
389 {
390 nouveau_grobj_free(&screen->swzsurf);
391 nouveau_grobj_free(&screen->sifm);
392 nouveau_grobj_free(&screen->rect);
393 nouveau_grobj_free(&screen->rop);
394 nouveau_grobj_free(&screen->patt);
395 nouveau_grobj_free(&screen->surf2d);
396 nouveau_grobj_free(&screen->m2mf);
397 nouveau_notifier_free(&screen->ntfy);
398 }
399
400 GLboolean
401 nv04_surface_init(struct nouveau_screen *screen)
402 {
403 struct nouveau_channel *chan = screen->chan;
404 const unsigned chipset = screen->device->chipset;
405 unsigned handle = 0x88000000, class;
406 int ret;
407
408 /* Notifier object. */
409 ret = nouveau_notifier_alloc(chan, handle++, 1, &screen->ntfy);
410 if (ret)
411 goto fail;
412
413 /* Memory to memory format. */
414 ret = nouveau_grobj_alloc(chan, handle++, NV04_MEMORY_TO_MEMORY_FORMAT,
415 &screen->m2mf);
416 if (ret)
417 goto fail;
418
419 BEGIN_RING(chan, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
420 OUT_RING (chan, screen->ntfy->handle);
421
422 /* Context surfaces 2D. */
423 if (chan->device->chipset < 0x10)
424 class = NV04_CONTEXT_SURFACES_2D;
425 else
426 class = NV10_CONTEXT_SURFACES_2D;
427
428 ret = nouveau_grobj_alloc(chan, handle++, class, &screen->surf2d);
429 if (ret)
430 goto fail;
431
432 /* Raster op. */
433 ret = nouveau_grobj_alloc(chan, handle++, NV03_CONTEXT_ROP,
434 &screen->rop);
435 if (ret)
436 goto fail;
437
438 BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
439 OUT_RING (chan, screen->ntfy->handle);
440
441 BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_ROP, 1);
442 OUT_RING (chan, 0xca); /* DPSDxax in the GDI speech. */
443
444 /* Image pattern. */
445 ret = nouveau_grobj_alloc(chan, handle++, NV04_IMAGE_PATTERN,
446 &screen->patt);
447 if (ret)
448 goto fail;
449
450 BEGIN_RING(chan, screen->patt,
451 NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
452 OUT_RING (chan, screen->ntfy->handle);
453
454 BEGIN_RING(chan, screen->patt,
455 NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
456 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
457 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
458 OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
459
460 BEGIN_RING(chan, screen->patt,
461 NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4);
462 OUT_RING (chan, 0);
463 OUT_RING (chan, 0);
464 OUT_RING (chan, ~0);
465 OUT_RING (chan, ~0);
466
467 /* GDI rectangle text. */
468 ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT,
469 &screen->rect);
470 if (ret)
471 goto fail;
472
473 BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
474 OUT_RING (chan, screen->ntfy->handle);
475 BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
476 OUT_RING (chan, screen->surf2d->handle);
477 BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
478 OUT_RING (chan, screen->rop->handle);
479 BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
480 OUT_RING (chan, screen->patt->handle);
481
482 BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
483 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
484 BEGIN_RING(chan, screen->rect,
485 NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
486 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
487
488 /* Swizzled surface. */
489 switch (chan->device->chipset & 0xf0) {
490 case 0x00:
491 case 0x10:
492 class = NV04_SWIZZLED_SURFACE;
493 break;
494 case 0x20:
495 class = NV20_SWIZZLED_SURFACE;
496 break;
497 case 0x30:
498 class = NV30_SWIZZLED_SURFACE;
499 break;
500 case 0x40:
501 case 0x60:
502 class = NV40_SWIZZLED_SURFACE;
503 break;
504 default:
505 /* Famous last words: this really can't happen.. */
506 assert(0);
507 break;
508 }
509
510 ret = nouveau_grobj_alloc(chan, handle++, class, &screen->swzsurf);
511 if (ret)
512 goto fail;
513
514 /* Scaled image from memory. */
515 switch (chan->device->chipset & 0xf0) {
516 case 0x10:
517 case 0x20:
518 class = NV10_SCALED_IMAGE_FROM_MEMORY;
519 break;
520 case 0x30:
521 class = NV30_SCALED_IMAGE_FROM_MEMORY;
522 break;
523 case 0x40:
524 case 0x60:
525 class = NV40_SCALED_IMAGE_FROM_MEMORY;
526 break;
527 default:
528 class = NV04_SCALED_IMAGE_FROM_MEMORY;
529 break;
530 }
531
532 ret = nouveau_grobj_alloc(chan, handle++, class, &screen->sifm);
533 if (ret)
534 goto fail;
535
536 if (chipset >= 0x10) {
537 BEGIN_RING(chan, screen->sifm,
538 NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
539 OUT_RING(chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE);
540 }
541
542 return GL_TRUE;
543
544 fail:
545 nv04_surface_takedown(screen);
546 return GL_FALSE;
547 }