Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.