mesa: Changes to 'ubuntu+1'
debian/changelog | 3
debian/patches/0001-nv50-fix-3D-render-target-setup.patch | 56 +
debian/patches/0002-nv50-nvc0-disable-DEPTH_RANGE_NEAR-FAR-clipping-duri.patch | 56 +
debian/patches/0003-nv50-nvc0-fix-3d-blits-restore-viewport-after-blit.patch | 139 +++
debian/patches/0004-nvc0-fix-for-2d-engine-R-source-formats-writing-RRR1.patch | 407 ++++++++++
debian/patches/series | 4
6 files changed, 665 insertions(+)
New commits:
commit d3292d2163cc959cfa750c5fa72f5181f29046f3
Author: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Date: Thu Apr 4 18:52:36 2013 +0200
Add some more patches to fix image copy regressions on nouveau.
diff --git a/debian/changelog b/debian/changelog
index 26a916b..c0f735e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,9 @@ mesa (9.1.1-0ubuntu1) UNRELEASED; urgency=low
- new upstream release (LP: #1112147)
* Added a bunch of patches to fix slow blur on intel.
+ [ Maarten Lankhorst ]
+ * Add some more patches to fix image copy regressions on nouveau.
+
-- Timo Aaltonen <tjaalton@ubuntu.com> Wed, 27 Feb 2013 11:12:43 +0200
mesa (9.1.1-1) UNRELEASED; urgency=low
diff --git a/debian/patches/0001-nv50-fix-3D-render-target-setup.patch b/debian/patches/0001-nv50-fix-3D-render-target-setup.patch
new file mode 100644
index 0000000..a02be67
--- /dev/null
+++ b/debian/patches/0001-nv50-fix-3D-render-target-setup.patch
@@ -0,0 +1,56 @@
+From 7410ba12657fa3652d05c99d44eda68231b9c100 Mon Sep 17 00:00:00 2001
+From: Christoph Bumiller <e0425955@student.tuwien.ac.at>
+Date: Mon, 25 Mar 2013 19:41:18 +0100
+Subject: [PATCH 1/4] nv50: fix 3D render target setup
+
+---
+ src/gallium/drivers/nv50/nv50_state_validate.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
+index a95e96d..f5e7b36 100644
+--- a/src/gallium/drivers/nv50/nv50_state_validate.c
++++ b/src/gallium/drivers/nv50/nv50_state_validate.c
+@@ -9,6 +9,7 @@ nv50_validate_fb(struct nv50_context *nv50)
+ struct pipe_framebuffer_state *fb = &nv50->framebuffer;
+ unsigned i;
+ unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
++ uint32_t array_size = 0xffff, array_mode = 0;
+
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
+
+@@ -23,6 +24,13 @@ nv50_validate_fb(struct nv50_context *nv50)
+ struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
+ struct nouveau_bo *bo = mt->base.bo;
+
++ array_size = MIN2(array_size, sf->depth);
++ if (mt->layout_3d)
++ array_mode = NV50_3D_RT_ARRAY_MODE_MODE_3D; /* 1 << 16 */
++
++ /* can't mix 3D with ARRAY or have RTs of different depth/array_size */
++ assert(mt->layout_3d || !array_mode || array_size == 1);
++
+ BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5);
+ PUSH_DATAh(push, bo->offset + sf->offset);
+ PUSH_DATA (push, bo->offset + sf->offset);
+@@ -34,7 +42,7 @@ nv50_validate_fb(struct nv50_context *nv50)
+ PUSH_DATA (push, sf->width);
+ PUSH_DATA (push, sf->height);
+ BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+- PUSH_DATA (push, sf->depth);
++ PUSH_DATA (push, array_mode | array_size);
+ } else {
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+@@ -63,7 +71,7 @@ nv50_validate_fb(struct nv50_context *nv50)
+ struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
+ struct nv50_surface *sf = nv50_surface(fb->zsbuf);
+ struct nouveau_bo *bo = mt->base.bo;
+- int unk = mt->base.base.target == PIPE_TEXTURE_2D;
++ int unk = mt->base.base.target == PIPE_TEXTURE_3D || sf->depth == 1;
+
+ BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
+ PUSH_DATAh(push, bo->offset + sf->offset);
+--
+1.8.2
+
diff --git a/debian/patches/0002-nv50-nvc0-disable-DEPTH_RANGE_NEAR-FAR-clipping-duri.patch b/debian/patches/0002-nv50-nvc0-disable-DEPTH_RANGE_NEAR-FAR-clipping-duri.patch
new file mode 100644
index 0000000..3b04386
--- /dev/null
+++ b/debian/patches/0002-nv50-nvc0-disable-DEPTH_RANGE_NEAR-FAR-clipping-duri.patch
@@ -0,0 +1,56 @@
+From 5ba62ee2011b44e8a40bab6435a8edaf03cda612 Mon Sep 17 00:00:00 2001
+From: Christoph Bumiller <e0425955@student.tuwien.ac.at>
+Date: Sun, 31 Mar 2013 22:10:02 +0200
+Subject: [PATCH 2/4] nv50,nvc0: disable DEPTH_RANGE_NEAR/FAR clipping during
+ blit
+
+We send position.z == 0, DEPTH_RANGE may be some arbitrary range
+not including 0 (for exmaple in piglit's hiz tests).
+---
+ src/gallium/drivers/nv50/nv50_surface.c | 2 ++
+ src/gallium/drivers/nvc0/nvc0_3d.xml.h | 2 +-
+ src/gallium/drivers/nvc0/nvc0_surface.c | 2 ++
+ 3 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
+index 7a0470c..b1b5cb3 100644
+--- a/src/gallium/drivers/nv50/nv50_surface.c
++++ b/src/gallium/drivers/nv50/nv50_surface.c
+@@ -977,6 +977,8 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+ PUSH_DATA (push, 0);
++ BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
++ PUSH_DATA (push, 0x1);
+
+ /* Draw a large triangle in screen coordinates covering the whole
+ * render target, with scissors defining the destination region.
+diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
+index 1cf1f96..bd3de58 100644
+--- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h
++++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
+@@ -1041,7 +1041,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ #define NVC0_3D_VIEWPORT_TRANSFORM_EN 0x0000192c
+
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL 0x0000193c
+-#define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK0 0x00000001
++#define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_RANGE_0_1 0x00000001
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1__MASK 0x00000006
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1__SHIFT 1
+ #define NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK0 0x00000000
+diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
+index 281d740..94ac241 100644
+--- a/src/gallium/drivers/nvc0/nvc0_surface.c
++++ b/src/gallium/drivers/nvc0/nvc0_surface.c
+@@ -859,6 +859,8 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+ z += 0.5f * dz;
+
+ IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0);
++ IMMED_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 0x2 |
++ NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_RANGE_0_1);
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
+ PUSH_DATA (push, nvc0->framebuffer.width << 16);
+ PUSH_DATA (push, nvc0->framebuffer.height << 16);
+--
+1.8.2
+
diff --git a/debian/patches/0003-nv50-nvc0-fix-3d-blits-restore-viewport-after-blit.patch b/debian/patches/0003-nv50-nvc0-fix-3d-blits-restore-viewport-after-blit.patch
new file mode 100644
index 0000000..fcf2118
--- /dev/null
+++ b/debian/patches/0003-nv50-nvc0-fix-3d-blits-restore-viewport-after-blit.patch
@@ -0,0 +1,139 @@
+From ac4be462795590019c262161f6147f6108e796ff Mon Sep 17 00:00:00 2001
+From: Christoph Bumiller <e0425955@student.tuwien.ac.at>
+Date: Fri, 22 Mar 2013 13:49:40 +0100
+Subject: [PATCH 3/4] nv50,nvc0: fix 3d blits, restore viewport after blit
+
+Conflicts:
+ src/gallium/drivers/nvc0/nvc0_surface.c
+---
+ src/gallium/drivers/nv50/nv50_surface.c | 8 +++++--
+ src/gallium/drivers/nvc0/nvc0_surface.c | 42 ++++++++++++++++++++-------------
+ 2 files changed, 32 insertions(+), 18 deletions(-)
+
+diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
+index b1b5cb3..16f77cd 100644
+--- a/src/gallium/drivers/nv50/nv50_surface.c
++++ b/src/gallium/drivers/nv50/nv50_surface.c
+@@ -936,7 +936,7 @@ nv50_blit_3d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+ nv50_blit_select_fp(blit, info);
+ nv50_blitctx_pre_blit(blit);
+
+- nv50_blit_set_dst(blit, dst, info->dst.level, 0, info->dst.format);
++ nv50_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format);
+ nv50_blit_set_src(blit, src, info->src.level, -1, info->src.format,
+ blit->filter);
+
+@@ -1226,10 +1226,14 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
+ debug_printf("blit: cannot filter array or cube textures in z direction");
+ }
+
+- if (!eng3d && info->dst.format != info->src.format)
++ if (!eng3d && info->dst.format != info->src.format) {
+ if (!nv50_2d_format_faithful(info->dst.format) ||
+ !nv50_2d_format_faithful(info->src.format))
+ eng3d = TRUE;
++ if (info->dst.format == PIPE_FORMAT_R8_UNORM ||
++ info->dst.format == PIPE_FORMAT_R16_UNORM)
++ eng3d = TRUE;
++ }
+
+ if (info->src.resource->nr_samples == 8 &&
+ info->dst.resource->nr_samples <= 1)
+diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
+index 94ac241..80f6f6f 100644
+--- a/src/gallium/drivers/nvc0/nvc0_surface.c
++++ b/src/gallium/drivers/nvc0/nvc0_surface.c
+@@ -490,19 +490,19 @@ nvc0_blitter_make_vp(struct nvc0_blitter *blit)
+ {
+ static const uint32_t code_nvc0[] =
+ {
+- 0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */
+- 0xfff11c26, 0x06000090, /* vfetch b96 { $r4 $r5 $r6 } a[0x90]*/
+- 0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */
+- 0x13f01c26, 0x0a7e0080, /* export b96 o[0x80] { $r4 $r5 $r6 } */
++ 0xfff11c26, 0x06000080, /* vfetch b64 $r4:$r5 a[0x80] */
++ 0xfff01c46, 0x06000090, /* vfetch b96 $r0:$r1:$r2 a[0x90] */
++ 0x13f01c26, 0x0a7e0070, /* export b64 o[0x70] $r4:$r5 */
++ 0x03f01c46, 0x0a7e0080, /* export b96 o[0x80] $r0:$r1:$r2 */
+ 0x00001de7, 0x80000000, /* exit */
+ };
+ static const uint32_t code_nve4[] =
+ {
+ 0x00000007, 0x20000000, /* sched */
+- 0xfff01c66, 0x06000080, /* vfetch b128 { $r0 $r1 $r2 $r3 } a[0x80] */
+- 0xfff11c46, 0x06000090, /* vfetch b96 { $r4 $r5 $r6 } a[0x90]*/
+- 0x03f01c66, 0x0a7e0070, /* export b128 o[0x70] { $r0 $r1 $r2 $r3 } */
+- 0x13f01c46, 0x0a7e0080, /* export b96 o[0x80] { $r4 $r5 $r6 } */
++ 0xfff11c26, 0x06000080, /* vfetch b64 $r4:$r5 a[0x80] */
++ 0xfff01c46, 0x06000090, /* vfetch b96 $r0:$r1:$r2 a[0x90] */
++ 0x13f01c26, 0x0a7e0070, /* export b64 o[0x70] $r4:$r5 */
++ 0x03f01c46, 0x0a7e0080, /* export b96 o[0x80] $r0:$r1:$r2 */
+ 0x00001de7, 0x80000000, /* exit */
+ };
+
+@@ -515,13 +515,13 @@ nvc0_blitter_make_vp(struct nvc0_blitter *blit)
+ blit->vp.code = (uint32_t *)code_nvc0; /* const_cast */
+ blit->vp.code_size = sizeof(code_nvc0);
+ }
+- blit->vp.max_gpr = 7;
++ blit->vp.max_gpr = 6;
+ blit->vp.vp.edgeflag = PIPE_MAX_ATTRIBS;
+
+ blit->vp.hdr[0] = 0x00020461; /* vertprog magic */
+ blit->vp.hdr[4] = 0x000ff000; /* no outputs read */
+- blit->vp.hdr[6] = 0x0000003f; /* a[0x80], a[0x90] */
+- blit->vp.hdr[13] = 0x0003f000; /* o[0x70], o[0x80] */
++ blit->vp.hdr[6] = 0x00000073; /* a[0x80].xy, a[0x90].xyz */
++ blit->vp.hdr[13] = 0x00073000; /* o[0x70].xy, o[0x80].xyz */
+ }
+
+ static void
+@@ -820,7 +820,7 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+ nvc0_blit_select_fp(blit, info);
+ nvc0_blitctx_pre_blit(blit);
+
+- nvc0_blit_set_dst(blit, dst, info->dst.level, 0, info->dst.format);
++ nvc0_blit_set_dst(blit, dst, info->dst.level, -1, info->dst.format);
+ nvc0_blit_set_src(blit, src, info->src.level, -1, info->src.format,
+ blit->filter);
+
+@@ -927,11 +927,14 @@ nvc0_blit_3d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+ if (info->dst.box.z + info->dst.box.depth - 1)
+ IMMED_NVC0(push, NVC0_3D(LAYER), 0);
+
+- /* re-enable normally constant state */
++ nvc0_blitctx_post_blit(blit);
+
+- IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
++ /* restore viewport */
+
+- nvc0_blitctx_post_blit(blit);
++ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
++ PUSH_DATA (push, nvc0->framebuffer.width << 16);
++ PUSH_DATA (push, nvc0->framebuffer.height << 16);
++ IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
+ }
+
+ static void
+@@ -1108,10 +1111,17 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
+ debug_printf("blit: cannot filter array or cube textures in z direction");
+ }
+
+- if (!eng3d && info->dst.format != info->src.format)
++ if (!eng3d && info->dst.format != info->src.format) {
+ if (!nvc0_2d_format_faithful(info->dst.format) ||
+ !nvc0_2d_format_faithful(info->src.format))
+ eng3d = TRUE;
++ /* For some retarded reason, if dst is R8/16_UNORM, the 2d engine doesn't
++ * like to do any format conversion (DATA_ERROR 0x34 on trigger).
++ */
++ if (info->dst.format == PIPE_FORMAT_R8_UNORM ||
++ info->dst.format == PIPE_FORMAT_R16_UNORM)
++ eng3d = TRUE;
++ }
+
+ if (info->src.resource->nr_samples == 8 &&
+ info->dst.resource->nr_samples <= 1)
+--
+1.8.2
+
diff --git a/debian/patches/0004-nvc0-fix-for-2d-engine-R-source-formats-writing-RRR1.patch b/debian/patches/0004-nvc0-fix-for-2d-engine-R-source-formats-writing-RRR1.patch
new file mode 100644
index 0000000..09e3ce9
--- /dev/null
+++ b/debian/patches/0004-nvc0-fix-for-2d-engine-R-source-formats-writing-RRR1.patch
@@ -0,0 +1,407 @@
+From 923bb2d8edbcda9f4a293a0efd04d533382978e0 Mon Sep 17 00:00:00 2001
+From: Christoph Bumiller <e0425955@student.tuwien.ac.at>
+Date: Sat, 30 Mar 2013 21:28:30 +0100
+Subject: [PATCH 4/4] nvc0: fix for 2d engine R source formats writing RRR1 and
+ not R001
+
+---
+ src/gallium/drivers/nv50/nv50_blit.h | 40 +++++++++++++++
+ src/gallium/drivers/nv50/nv50_surface.c | 71 +++++++++++++++++---------
+ src/gallium/drivers/nvc0/nvc0_surface.c | 89 ++++++++++++++++++++++-----------
+ 3 files changed, 148 insertions(+), 52 deletions(-)
+
+diff --git a/src/gallium/drivers/nv50/nv50_blit.h b/src/gallium/drivers/nv50/nv50_blit.h
+index d409f21..bdd6a63 100644
+--- a/src/gallium/drivers/nv50/nv50_blit.h
++++ b/src/gallium/drivers/nv50/nv50_blit.h
+@@ -180,4 +180,44 @@ nv50_blit_eng2d_get_mask(const struct pipe_blit_info *info)
+ return mask;
+ }
+
++#if NOUVEAU_DRIVER == 0xc0
++# define nv50_format_table nvc0_format_table
++#endif
++
++/* return TRUE for formats that can be converted among each other by NVC0_2D */
++static INLINE boolean
++nv50_2d_dst_format_faithful(enum pipe_format format)
++{
++ const uint64_t mask =
++ NV50_ENG2D_SUPPORTED_FORMATS &
++ ~NV50_ENG2D_NOCONVERT_FORMATS;
++ uint8_t id = nv50_format_table[format].rt;
++ return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0)));
++}
++static INLINE boolean
++nv50_2d_src_format_faithful(enum pipe_format format)
++{
++ const uint64_t mask =
++ NV50_ENG2D_SUPPORTED_FORMATS &
++ ~(NV50_ENG2D_LUMINANCE_FORMATS | NV50_ENG2D_INTENSITY_FORMATS);
++ uint8_t id = nv50_format_table[format].rt;
++ return (id >= 0xc0) && (mask & (1ULL << (id - 0xc0)));
++}
++
++static INLINE boolean
++nv50_2d_format_supported(enum pipe_format format)
++{
++ uint8_t id = nv50_format_table[format].rt;
++ return (id >= 0xc0) &&
++ (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
++}
++
++static INLINE boolean
++nv50_2d_dst_format_ops_supported(enum pipe_format format)
++{
++ uint8_t id = nv50_format_table[format].rt;
++ return (id >= 0xc0) &&
++ (NV50_ENG2D_OPERATION_FORMATS & (1ULL << (id - 0xc0)));
++}
++
+ #endif /* __NV50_BLIT_H__ */
+diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
+index 16f77cd..3a780f6 100644
+--- a/src/gallium/drivers/nv50/nv50_surface.c
++++ b/src/gallium/drivers/nv50/nv50_surface.c
+@@ -35,25 +35,22 @@
+
+ #include "nv50_context.h"
+ #include "nv50_resource.h"
+-#include "nv50_blit.h"
+
+ #include "nv50_defs.xml.h"
+ #include "nv50_texture.xml.h"
+
++/* these are used in nv50_blit.h */
+ #define NV50_ENG2D_SUPPORTED_FORMATS 0xff0843e080608409ULL
++#define NV50_ENG2D_NOCONVERT_FORMATS 0x0008402000000000ULL
++#define NV50_ENG2D_LUMINANCE_FORMATS 0x0008402000000000ULL
++#define NV50_ENG2D_INTENSITY_FORMATS 0x0000000000000000ULL
++#define NV50_ENG2D_OPERATION_FORMATS 0x060001c000608000ULL
+
+-/* return TRUE for formats that can be converted among each other by NV50_2D */
+-static INLINE boolean
+-nv50_2d_format_faithful(enum pipe_format format)
+-{
+- uint8_t id = nv50_format_table[format].rt;
+-
+- return (id >= 0xc0) &&
+- (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
+-}
++#define NOUVEAU_DRIVER 0x50
++#include "nv50_blit.h"
+
+ static INLINE uint8_t
+-nv50_2d_format(enum pipe_format format)
++nv50_2d_format(enum pipe_format format, boolean dst, boolean dst_src_equal)
+ {
+ uint8_t id = nv50_format_table[format].rt;
+
+@@ -62,6 +59,7 @@ nv50_2d_format(enum pipe_format format)
+ */
+ if ((id >= 0xc0) && (NV50_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0))))
+ return id;
++ assert(dst_src_equal);
+
+ switch (util_format_get_blocksize(format)) {
+ case 1:
+@@ -78,7 +76,7 @@ nv50_2d_format(enum pipe_format format)
+ static int
+ nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
+ struct nv50_miptree *mt, unsigned level, unsigned layer,
+- enum pipe_format pformat)
++ enum pipe_format pformat, boolean dst_src_pformat_equal)
+ {
+ struct nouveau_bo *bo = mt->base.bo;
+ uint32_t width, height, depth;
+@@ -86,7 +84,7 @@ nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
+ uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
+ uint32_t offset = mt->level[level].offset;
+
+- format = nv50_2d_format(pformat);
++ format = nv50_2d_format(pformat, dst, dst_src_pformat_equal);
+ if (!format) {
+ NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
+ util_format_name(pformat));
+@@ -155,15 +153,16 @@ nv50_2d_texture_do_copy(struct nouveau_pushbuf *push,
+ const enum pipe_format dfmt = dst->base.base.format;
+ const enum pipe_format sfmt = src->base.base.format;
+ int ret;
++ boolean eqfmt = dfmt == sfmt;
+
+ if (!PUSH_SPACE(push, 2 * 16 + 32))
+ return PIPE_ERROR;
+
+- ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz, dfmt);
++ ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz, dfmt, eqfmt);
+ if (ret)
+ return ret;
+
+- ret = nv50_2d_texture_set(push, 0, src, src_level, sz, sfmt);
++ ret = nv50_2d_texture_set(push, 0, src, src_level, sz, sfmt, eqfmt);
+ if (ret)
+ return ret;
+
+@@ -243,8 +242,8 @@ nv50_resource_copy_region(struct pipe_context *pipe,
+ }
+
+ assert((src->format == dst->format) ||
+- (nv50_2d_format_faithful(src->format) &&
+- nv50_2d_format_faithful(dst->format)));
++ (nv50_2d_src_format_faithful(src->format) &&
++ nv50_2d_dst_format_faithful(dst->format)));
+
+ BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD);
+ BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR);
+@@ -1061,7 +1060,8 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+ int64_t du_dx, dv_dy;
+ int i;
+ uint32_t mode;
+- const uint32_t mask = nv50_blit_eng2d_get_mask(info);
++ uint32_t mask = nv50_blit_eng2d_get_mask(info);
++ boolean b;
+
+ mode = nv50_blit_get_filter(info) ?
+ NV50_2D_BLIT_CONTROL_FILTER_BILINEAR :
+@@ -1072,8 +1072,9 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+ du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width;
+ dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height;
+
+- nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format);
+- nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format);
++ b = info->dst.format == info->src.format;
++ nv50_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b);
++ nv50_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b);
+
+ if (info->scissor_enable) {
+ BEGIN_NV04(push, NV50_2D(CLIP_X), 5);
+@@ -1096,6 +1097,17 @@ nv50_blit_eng2d(struct nv50_context *nv50, const struct pipe_blit_info *info)
+ PUSH_DATA (push, 0xffffffff);
+ BEGIN_NV04(push, NV50_2D(OPERATION), 1);
+ PUSH_DATA (push, NV50_2D_OPERATION_ROP);
++ } else
++ if (info->src.format != info->dst.format) {
++ if (info->src.format == PIPE_FORMAT_R8_UNORM ||
++ info->src.format == PIPE_FORMAT_R16_UNORM ||
++ info->src.format == PIPE_FORMAT_R16_FLOAT ||
++ info->src.format == PIPE_FORMAT_R32_FLOAT) {
++ mask = 0xffff0000; /* also makes condition for OPERATION reset true */
++ BEGIN_NV04(push, NV50_2D(BETA4), 2);
++ PUSH_DATA (push, mask);
++ PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY_PREMULT);
++ }
+ }
+
+ if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) {
+@@ -1227,11 +1239,22 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
+ }
+
+ if (!eng3d && info->dst.format != info->src.format) {
+- if (!nv50_2d_format_faithful(info->dst.format) ||
+- !nv50_2d_format_faithful(info->src.format))
++ if (!nv50_2d_dst_format_faithful(info->dst.format) ||
++ !nv50_2d_src_format_faithful(info->src.format)) {
+ eng3d = TRUE;
+- if (info->dst.format == PIPE_FORMAT_R8_UNORM ||
+- info->dst.format == PIPE_FORMAT_R16_UNORM)
++ } else
++ if (!nv50_2d_src_format_faithful(info->src.format)) {
++ if (!util_format_is_luminance(info->src.format)) {
++ if (util_format_is_intensity(info->src.format))
++ eng3d = TRUE;
++ else
++ if (!nv50_2d_dst_format_ops_supported(info->dst.format))
++ eng3d = TRUE;
++ else
++ eng3d = !nv50_2d_format_supported(info->src.format);
++ }
++ } else
++ if (util_format_is_luminance_alpha(info->src.format))
+ eng3d = TRUE;
+ }
+
+diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
+index 80f6f6f..66154a4 100644
+--- a/src/gallium/drivers/nvc0/nvc0_surface.c
++++ b/src/gallium/drivers/nvc0/nvc0_surface.c
+@@ -36,29 +36,32 @@
+
+ #include "nv50/nv50_defs.xml.h"
+ #include "nv50/nv50_texture.xml.h"
+-#include "nv50/nv50_blit.h"
+
+-#define NVC0_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL
++/* these are used in nv50_blit.h */
++#define NV50_ENG2D_SUPPORTED_FORMATS 0xff9ccfe1cce3ccc9ULL
++#define NV50_ENG2D_NOCONVERT_FORMATS 0x009cc02000000000ULL
++#define NV50_ENG2D_LUMINANCE_FORMATS 0x001cc02000000000ULL
++#define NV50_ENG2D_INTENSITY_FORMATS 0x0080000000000000ULL
++#define NV50_ENG2D_OPERATION_FORMATS 0x060001c000638000ULL
+
+-/* return TRUE for formats that can be converted among each other by NVC0_2D */
+-static INLINE boolean
+-nvc0_2d_format_faithful(enum pipe_format format)
+-{
+- uint8_t id = nvc0_format_table[format].rt;
+-
+- return (id >= 0xc0) && (NVC0_ENG2D_SUPPORTED_FORMATS & (1ULL << (id - 0xc0)));
+-}
++#define NOUVEAU_DRIVER 0xc0
++#include "nv50/nv50_blit.h"
+
+ static INLINE uint8_t
+-nvc0_2d_format(enum pipe_format format)
++nvc0_2d_format(enum pipe_format format, boolean dst, boolean dst_src_equal)
+ {
+ uint8_t id = nvc0_format_table[format].rt;
+
++ /* A8_UNORM is treated as I8_UNORM as far as the 2D engine is concerned. */
++ if (!dst && unlikely(format == PIPE_FORMAT_I8_UNORM) && !dst_src_equal)
++ return NV50_SURFACE_FORMAT_A8_UNORM;
++
+ /* Hardware values for color formats range from 0xc0 to 0xff,
+ * but the 2D engine doesn't support all of them.
+ */
+- if (nvc0_2d_format_faithful(format))
++ if (nv50_2d_format_supported(format))
+ return id;
++ assert(dst_src_equal);
+
+ switch (util_format_get_blocksize(format)) {
+ case 1:
+@@ -72,6 +75,7 @@ nvc0_2d_format(enum pipe_format format)
+ case 16:
+ return NV50_SURFACE_FORMAT_RGBA32_FLOAT;
+ default:
++ assert(0);
+ return 0;
+ }
+ }
+@@ -79,7 +83,7 @@ nvc0_2d_format(enum pipe_format format)
+ static int
+ nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst,
+ struct nv50_miptree *mt, unsigned level, unsigned layer,
+- enum pipe_format pformat)
++ enum pipe_format pformat, boolean dst_src_pformat_equal)
+ {
+ struct nouveau_bo *bo = mt->base.bo;
+ uint32_t width, height, depth;
+@@ -87,7 +91,7 @@ nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean dst,
+ uint32_t mthd = dst ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
+ uint32_t offset = mt->level[level].offset;
+
+- format = nvc0_2d_format(pformat);
++ format = nvc0_2d_format(pformat, dst, dst_src_pformat_equal);
+ if (!format) {
+ NOUVEAU_ERR("invalid/unsupported surface format: %s\n",
+ util_format_name(pformat));
+@@ -157,15 +161,16 @@ nvc0_2d_texture_do_copy(struct nouveau_pushbuf *push,
+ const enum pipe_format dfmt = dst->base.base.format;
+ const enum pipe_format sfmt = src->base.base.format;
+ int ret;
++ boolean eqfmt = dfmt == sfmt;
+
+ if (!PUSH_SPACE(push, 2 * 16 + 32))
+ return PIPE_ERROR;
+
+- ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz, dfmt);
++ ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz, dfmt, eqfmt);
+ if (ret)
+ return ret;
+
+- ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz, sfmt);
++ ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz, sfmt, eqfmt);
+ if (ret)
+ return ret;
+
+@@ -243,8 +248,8 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
+ return;
+ }
+
+- assert(nvc0_2d_format_faithful(src->format));
+- assert(nvc0_2d_format_faithful(dst->format));
++ assert(nv50_2d_dst_format_faithful(dst->format));
++ assert(nv50_2d_src_format_faithful(src->format));
+
+ BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
+ BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
+@@ -953,7 +958,8 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+ int64_t du_dx, dv_dy;
+ int i;
+ uint32_t mode;
+- const uint32_t mask = nv50_blit_eng2d_get_mask(info);
++ uint32_t mask = nv50_blit_eng2d_get_mask(info);
++ boolean b;
+
+ mode = nv50_blit_get_filter(info) ?
+ NVC0_2D_BLIT_CONTROL_FILTER_BILINEAR :
+@@ -964,8 +970,9 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+ du_dx = ((int64_t)info->src.box.width << 32) / info->dst.box.width;
+ dv_dy = ((int64_t)info->src.box.height << 32) / info->dst.box.height;
+
+- nvc0_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format);
+- nvc0_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format);
++ b = info->dst.format == info->src.format;
++ nvc0_2d_texture_set(push, 1, dst, info->dst.level, dz, info->dst.format, b);
++ nvc0_2d_texture_set(push, 0, src, info->src.level, sz, info->src.format, b);
+
+ if (info->scissor_enable) {
+ BEGIN_NVC0(push, NVC0_2D(CLIP_X), 5);
+@@ -986,6 +993,25 @@ nvc0_blit_eng2d(struct nvc0_context *nvc0, const struct pipe_blit_info *info)
+ PUSH_DATA (push, 0xffffffff);
+ PUSH_DATA (push, 0xffffffff);
+ IMMED_NVC0(push, NVC0_2D(OPERATION), NVC0_2D_OPERATION_ROP);
++ } else
++ if (info->src.format != info->dst.format) {
++ if (info->src.format == PIPE_FORMAT_R8_UNORM ||
++ info->src.format == PIPE_FORMAT_R8_SNORM ||
++ info->src.format == PIPE_FORMAT_R16_UNORM ||
++ info->src.format == PIPE_FORMAT_R16_SNORM ||
++ info->src.format == PIPE_FORMAT_R16_FLOAT ||
++ info->src.format == PIPE_FORMAT_R32_FLOAT) {
++ mask = 0xffff0000; /* also makes condition for OPERATION reset true */
++ BEGIN_NVC0(push, NVC0_2D(BETA4), 2);
++ PUSH_DATA (push, mask);
++ PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY_PREMULT);
++ } else
++ if (info->src.format == PIPE_FORMAT_A8_UNORM) {
++ mask = 0xff000000;
++ BEGIN_NVC0(push, NVC0_2D(BETA4), 2);
++ PUSH_DATA (push, mask);
++ PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY_PREMULT);
++ }
+ }
+
+ if (src->ms_x > dst->ms_x || src->ms_y > dst->ms_y) {
+@@ -1112,14 +1138,21 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
+ }
+
+ if (!eng3d && info->dst.format != info->src.format) {
+- if (!nvc0_2d_format_faithful(info->dst.format) ||
+- !nvc0_2d_format_faithful(info->src.format))
++ if (!nv50_2d_dst_format_faithful(info->dst.format)) {
+ eng3d = TRUE;
+- /* For some retarded reason, if dst is R8/16_UNORM, the 2d engine doesn't
+- * like to do any format conversion (DATA_ERROR 0x34 on trigger).
+- */
+- if (info->dst.format == PIPE_FORMAT_R8_UNORM ||
+- info->dst.format == PIPE_FORMAT_R16_UNORM)
++ } else
++ if (!nv50_2d_src_format_faithful(info->src.format)) {
++ if (!util_format_is_luminance(info->src.format)) {
++ if (util_format_is_intensity(info->src.format))
++ eng3d = info->src.format != PIPE_FORMAT_I8_UNORM;
++ else
++ if (!nv50_2d_dst_format_ops_supported(info->dst.format))
++ eng3d = TRUE;
++ else
++ eng3d = !nv50_2d_format_supported(info->src.format);
++ }
++ } else
++ if (util_format_is_luminance_alpha(info->src.format))
+ eng3d = TRUE;
+ }
+
+--
+1.8.2
+
diff --git a/debian/patches/series b/debian/patches/series
index 1907fb0..f2a4e13 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -35,3 +35,7 @@ i965-specialize-surface_state-creation.diff
0010-i965-fs-Don-t-double-emit-SEND-dependency-workaround.patch
0011-i965-fs-Use-LD-messages-for-pre-gen7-varying-index-u.patch
0012-i965-fs-Allow-CSE-on-pre-gen7-varying-index-uniform-.patch
+0001-nv50-fix-3D-render-target-setup.patch
+0002-nv50-nvc0-disable-DEPTH_RANGE_NEAR-FAR-clipping-duri.patch
+0003-nv50-nvc0-fix-3d-blits-restore-viewport-after-blit.patch
+0004-nvc0-fix-for-2d-engine-R-source-formats-writing-RRR1.patch
Reply to: