nvc0_surface.c revision 1b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4
14c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller/*
24c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * Copyright 2008 Ben Skeggs
34c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller *
44c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * Permission is hereby granted, free of charge, to any person obtaining a
54c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * copy of this software and associated documentation files (the "Software"),
64c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * to deal in the Software without restriction, including without limitation
74c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * and/or sell copies of the Software, and to permit persons to whom the
94c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * Software is furnished to do so, subject to the following conditions:
104c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller *
114c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * The above copyright notice and this permission notice shall be included in
124c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * all copies or substantial portions of the Software.
134c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller *
144c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
174c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
184c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
194c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
204c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller * SOFTWARE.
214c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller */
224c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
234c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include <stdint.h>
244c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
254c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "pipe/p_defines.h"
264c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
274c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "util/u_inlines.h"
284c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "util/u_pack_color.h"
294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "util/u_format.h"
304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "nvc0_context.h"
324c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "nvc0_resource.h"
334c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
344c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "nv50_defs.xml.h"
354c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
361b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller#define NVC0_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL
371b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller
384c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller/* return TRUE for formats that can be converted among each other by NVC0_2D */
394c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstatic INLINE boolean
404c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_2d_format_faithful(enum pipe_format format)
414c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
421b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller   uint8_t id = nvc0_format_table[format].rt;
431b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller
441b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller   return (id >= 0xc0) && (NVC0_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
454c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
464c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
474c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstatic INLINE uint8_t
484c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_2d_format(enum pipe_format format)
494c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
504c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint8_t id = nvc0_format_table[format].rt;
514c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
524c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   /* Hardware values for color formats range from 0xc0 to 0xff,
534c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller    * but the 2D engine doesn't support all of them.
544c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller    */
551b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller   if (nvc0_2d_format_faithful(format))
564c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return id;
574c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
584c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   switch (util_format_get_blocksize(format)) {
594c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   case 1:
604c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return NV50_SURFACE_FORMAT_R8_UNORM;
614c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   case 2:
624c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return NV50_SURFACE_FORMAT_R16_UNORM;
634c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   case 4:
644c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return NV50_SURFACE_FORMAT_A8R8G8B8_UNORM;
651b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller   case 8:
661b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller      return NV50_SURFACE_FORMAT_R16G16B16A16_UNORM;
671b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller   case 16:
681b4c0c8ea0b4e6065f23f9f2bbb954a7bd2549e4Christoph Bumiller      return NV50_SURFACE_FORMAT_R32G32B32A32_FLOAT;
694c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   default:
704c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return 0;
714c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
724c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
734c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
744c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstatic int
75ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumillernvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
76ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                    struct nvc0_miptree *mt, unsigned level, unsigned layer)
774c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
78ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   struct nouveau_bo *bo = mt->base.bo;
79ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   uint32_t width, height, depth;
80ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   uint32_t format;
81ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
82ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
83ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   uint32_t offset = mt->level[level].offset;
84ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller
85ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   format = nvc0_2d_format(mt->base.base.format);
864c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (!format) {
874c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
88ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                  util_format_name(mt->base.base.format));
894c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return 1;
904c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
914c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
92ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   width = u_minify(mt->base.base.width0, level);
93ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   height = u_minify(mt->base.base.height0, level);
94ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller
95ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   offset = mt->level[level].offset;
96ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   if (!mt->layout_3d) {
97ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      offset += mt->layer_stride * layer;
98ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      depth = 1;
99ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      layer = 0;
100ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   } else {
101ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      depth = u_minify(mt->base.base.depth0, level);
102ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   }
103ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller
104ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
1054c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_2D_(mthd), 2);
1064c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, format);
1074c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, 1);
1084c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
109ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, mt->level[level].pitch);
110ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, width);
111ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, height);
112ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RELOCh(chan, bo, offset, flags);
113ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RELOCl(chan, bo, offset, flags);
1144c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   } else {
1154c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_2D_(mthd), 5);
1164c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, format);
1174c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, 0);
118ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, mt->level[level].tile_mode);
119ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, depth);
120ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, layer);
1214c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
122ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, width);
123ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, height);
124ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RELOCh(chan, bo, offset, flags);
125ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RELOCl(chan, bo, offset, flags);
1264c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
127ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller
1284c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#if 0
1294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (dst) {
1304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_2D_(NVC0_2D_CLIP_X), 4);
1314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, 0);
1324c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, 0);
133ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, width);
134ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      OUT_RING  (chan, height);
1354c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
1364c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#endif
1374c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   return 0;
1384c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
1394c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1404c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstatic int
141ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumillernvc0_2d_texture_do_copy(struct nouveau_channel *chan,
142ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                        struct nvc0_miptree *dst, unsigned dst_level,
143ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                        unsigned dx, unsigned dy, unsigned dz,
144ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                        struct nvc0_miptree *src, unsigned src_level,
145ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                        unsigned sx, unsigned sy, unsigned sz,
146ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                        unsigned w, unsigned h)
1474c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
1484c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   int ret;
1494c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
150ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   ret = MARK_RING(chan, 2 * 16 + 32, 4);
1514c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (ret)
1524c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return ret;
1534c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
154ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   ret = nvc0_2d_texture_set(chan, 1, dst, dst_level, dz);
1554c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (ret)
1564c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return ret;
1574c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
158ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   ret = nvc0_2d_texture_set(chan, 0, src, src_level, sz);
1594c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (ret)
1604c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return ret;
1614c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1624c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   /* 0/1 = CENTER/CORNER, 10/00 = POINT/BILINEAR */
1634c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1);
1644c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, 0);
1654c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4);
1664c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, dx);
1674c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, dy);
1684c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, w);
1694c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, h);
1704c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4);
1714c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, 0);
1724c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, 1);
1734c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, 0);
1744c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, 1);
1754c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4);
1764c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, 0);
1774c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, sx);
1784c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, 0);
1794c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, sy);
1804c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1814c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   return 0;
1824c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
1834c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1844c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstatic void
185ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumillernvc0_resource_copy_region(struct pipe_context *pipe,
186ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                          struct pipe_resource *dst, unsigned dst_level,
187ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                          unsigned dstx, unsigned dsty, unsigned dstz,
188ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                          struct pipe_resource *src, unsigned src_level,
189ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                          const struct pipe_box *src_box)
1904c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
191ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   struct nvc0_screen *screen = nvc0_context(pipe)->screen;
192ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   int ret;
193ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   unsigned dst_layer = dstz, src_layer = src_box->z;
1944c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
195ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   assert((src->format == dst->format) ||
1964c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller          (nvc0_2d_format_faithful(src->format) &&
197ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller           nvc0_2d_format_faithful(dst->format)));
198ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller
199ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
200ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      ret = nvc0_2d_texture_do_copy(screen->base.channel,
201ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                                    nvc0_miptree(dst), dst_level,
202ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                                    dstx, dsty, dst_layer,
203ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                                    nvc0_miptree(src), src_level,
204ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                                    src_box->x, src_box->y, src_layer,
205ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                                    src_box->width, src_box->height);
206ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      if (ret)
207ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller         return;
208ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   }
2094c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
2104c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2114c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstatic void
2124c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_clear_render_target(struct pipe_context *pipe,
213ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                         struct pipe_surface *dst,
214ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                         const float *rgba,
215ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                         unsigned dstx, unsigned dsty,
216ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                         unsigned width, unsigned height)
2174c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
2184c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nvc0_context *nv50 = nvc0_context(pipe);
2194c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nvc0_screen *screen = nv50->screen;
2204c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nouveau_channel *chan = screen->base.channel;
2214c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nvc0_miptree *mt = nvc0_miptree(dst->texture);
222ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	struct nvc0_surface *sf = nvc0_surface(dst);
2234c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nouveau_bo *bo = mt->base.bo;
2244c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2254c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
2264c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RINGf (chan, rgba[0]);
2274c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RINGf (chan, rgba[1]);
2284c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RINGf (chan, rgba[2]);
2294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RINGf (chan, rgba[3]);
2304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	if (MARK_RING(chan, 18, 2))
2324c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		return;
2334c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2344c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
2354c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, 1);
2364c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 8);
237ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
238ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
239ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RING  (chan, sf->width);
240ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RING  (chan, sf->height);
2414c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, nvc0_format_table[dst->format].rt);
242ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode);
2434c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, 1);
2444c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, 0);
2454c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2464c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	/* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
2474c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2484c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
2494c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, (width << 16) | dstx);
2504c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, (height << 16) | dsty);
2514c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2524c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
2534c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, 0x3c);
2544c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2554c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
2564c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
2574c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2584c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstatic void
2594c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_clear_depth_stencil(struct pipe_context *pipe,
2604c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                         struct pipe_surface *dst,
2614c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                         unsigned clear_flags,
2624c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                         double depth,
2634c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                         unsigned stencil,
2644c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                         unsigned dstx, unsigned dsty,
2654c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                         unsigned width, unsigned height)
2664c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
2674c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nvc0_context *nv50 = nvc0_context(pipe);
2684c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nvc0_screen *screen = nv50->screen;
2694c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nouveau_channel *chan = screen->base.channel;
2704c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nvc0_miptree *mt = nvc0_miptree(dst->texture);
271ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	struct nvc0_surface *sf = nvc0_surface(dst);
2724c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	struct nouveau_bo *bo = mt->base.bo;
2734c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	uint32_t mode = 0;
2744c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2754c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	if (clear_flags & PIPE_CLEAR_DEPTH) {
2764c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
2774c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		OUT_RINGf (chan, depth);
2784c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		mode |= NVC0_3D_CLEAR_BUFFERS_Z;
2794c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	}
2804c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2814c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	if (clear_flags & PIPE_CLEAR_STENCIL) {
2824c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
2834c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		OUT_RING  (chan, stencil & 0xff);
2844c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		mode |= NVC0_3D_CLEAR_BUFFERS_S;
2854c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	}
2864c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2874c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	if (MARK_RING(chan, 17, 2))
2884c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller		return;
2894c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2904c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
291ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
292ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
2934c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, nvc0_format_table[dst->format].rt);
294ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RING  (chan, mt->level[sf->base.u.tex.level].tile_mode);
2954c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, 0);
2964c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
2974c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, 1);
2984c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
299ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RING  (chan, sf->width);
300ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	OUT_RING  (chan, sf->height);
3014c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, (1 << 16) | 1);
3024c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3034c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
3044c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, (width << 16) | dstx);
3054c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, (height << 16) | dsty);
3064c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3074c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
3084c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	OUT_RING  (chan, mode);
3094c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3104c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
3114c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
3124c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3134c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
3144c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_clear(struct pipe_context *pipe, unsigned buffers,
3154c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller           const float *rgba, double depth, unsigned stencil)
3164c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
3174c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_context *nvc0 = nvc0_context(pipe);
3184c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nouveau_channel *chan = nvc0->screen->base.channel;
3194c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
3204c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   unsigned i;
3214c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   const unsigned dirty = nvc0->dirty;
3224c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t mode = 0;
3234c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3244c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
3254c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   nvc0->dirty &= NVC0_NEW_FRAMEBUFFER;
3264c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (!nvc0_state_validate(nvc0))
3274c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return;
3284c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
3304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
3314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RINGf (chan, rgba[0]);
3324c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RINGf (chan, rgba[1]);
3334c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RINGf (chan, rgba[2]);
3344c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RINGf (chan, rgba[3]);
3354c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      mode =
3364c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller         NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G |
3374c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller         NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A;
3384c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
3394c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3404c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (buffers & PIPE_CLEAR_DEPTH) {
3414c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
3424c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, fui(depth));
3434c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      mode |= NVC0_3D_CLEAR_BUFFERS_Z;
3444c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
3454c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3464c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (buffers & PIPE_CLEAR_STENCIL) {
3474c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
3484c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, stencil & 0xff);
3494c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      mode |= NVC0_3D_CLEAR_BUFFERS_S;
3504c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
3514c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3524c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
3534c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   OUT_RING  (chan, mode);
3544c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3554c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   for (i = 1; i < fb->nr_cbufs; i++) {
3564c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
3574c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      OUT_RING  (chan, (i << 6) | 0x3c);
3584c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
3594c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3604c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   nvc0->dirty = dirty & ~NVC0_NEW_FRAMEBUFFER;
3614c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
3624c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3634c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
3644c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_init_surface_functions(struct nvc0_context *nvc0)
3654c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
366ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller	nvc0->pipe.resource_copy_region = nvc0_resource_copy_region;
3674c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	nvc0->pipe.clear_render_target = nvc0_clear_render_target;
3684c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller	nvc0->pipe.clear_depth_stencil = nvc0_clear_depth_stencil;
3694c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
3704c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3714c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
372