<div dir="ltr"><div>Fixes the test on Kepler<br><br></div>Tested-by: Nick Sarnie <<a href="mailto:commendsarnex@gmail.com">commendsarnex@gmail.com</a>></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 30, 2016 at 10:10 AM, Ilia Mirkin <span dir="ltr"><<a href="mailto:imirkin@alum.mit.edu" target="_blank">imirkin@alum.mit.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">It appears that the nvidia render engine is quite picky when it comes to<br>
linear surfaces. It doesn't like non-256-byte aligned offsets, and<br>
apparently doesn't even do non-256-byte strides.<br>
<br>
This makes arb_clear_buffer_object-unaligned pass on both nv50 and nvc0.<br>
<br>
As a side-effect this also allows RGB32 clears to work via GPU data<br>
upload instead of synchronizing the buffer to the CPU (nvc0 only).<br>
<br>
Signed-off-by: Ilia Mirkin <<a href="mailto:imirkin@alum.mit.edu">imirkin@alum.mit.edu</a>><br>
Cc: <a href="mailto:mesa-stable@lists.freedesktop.org">mesa-stable@lists.freedesktop.org</a><br>
---<br>
src/gallium/drivers/nouveau/nv50/nv50_surface.c | 190 ++++++++++++++------<br>
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 229 ++++++++++++++++++------<br>
2 files changed, 307 insertions(+), 112 deletions(-)<br>
<br>
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c<br>
index 86be1b4..618c39c 100644<br>
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c<br>
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c<br>
@@ -595,6 +595,82 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,<br>
}<br>
<br>
static void<br>
+nv50_clear_buffer_push(struct pipe_context *pipe,<br>
+ struct pipe_resource *res,<br>
+ unsigned offset, unsigned size,<br>
+ const void *data, int data_size)<br>
+{<br>
+ struct nv50_context *nv50 = nv50_context(pipe);<br>
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;<br>
+ struct nv04_resource *buf = nv04_resource(res);<br>
+ unsigned count = (size + 3) / 4;<br>
+ unsigned xcoord = offset & 0xff;<br>
+ unsigned tmp, i;<br>
+<br>
+ if (data_size == 1) {<br>
+ tmp = *(unsigned char *)data;<br>
+ tmp = (tmp << 24) | (tmp << 16) | (tmp << 8) | tmp;<br>
+ data = &tmp;<br>
+ data_size = 4;<br>
+ } else if (data_size == 2) {<br>
+ tmp = *(unsigned short *)data;<br>
+ tmp = (tmp << 16) | tmp;<br>
+ data = &tmp;<br>
+ data_size = 4;<br>
+ }<br>
+<br>
+ unsigned data_words = data_size / 4;<br>
+<br>
+ nouveau_bufctx_refn(nv50->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR);<br>
+ nouveau_pushbuf_bufctx(push, nv50->bufctx);<br>
+ nouveau_pushbuf_validate(push);<br>
+<br>
+ offset &= ~0xff;<br>
+<br>
+ BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);<br>
+ PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);<br>
+ PUSH_DATA (push, 1);<br>
+ BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);<br>
+ PUSH_DATA (push, 262144);<br>
+ PUSH_DATA (push, 65536);<br>
+ PUSH_DATA (push, 1);<br>
+ PUSH_DATAh(push, buf->address + offset);<br>
+ PUSH_DATA (push, buf->address + offset);<br>
+ BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);<br>
+ PUSH_DATA (push, 0);<br>
+ PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);<br>
+ BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);<br>
+ PUSH_DATA (push, size);<br>
+ PUSH_DATA (push, 1);<br>
+ PUSH_DATA (push, 0);<br>
+ PUSH_DATA (push, 1);<br>
+ PUSH_DATA (push, 0);<br>
+ PUSH_DATA (push, 1);<br>
+ PUSH_DATA (push, 0);<br>
+ PUSH_DATA (push, xcoord);<br>
+ PUSH_DATA (push, 0);<br>
+ PUSH_DATA (push, 0);<br>
+<br>
+ while (count) {<br>
+ unsigned nr_data = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN) / data_words;<br>
+ unsigned nr = nr_data * data_words;<br>
+<br>
+ BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr);<br>
+ for (i = 0; i < nr_data; i++)<br>
+ PUSH_DATAp(push, data, data_words);<br>
+<br>
+ count -= nr;<br>
+ }<br>
+<br>
+ if (buf->mm) {<br>
+ nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence);<br>
+ nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr);<br>
+ }<br>
+<br>
+ nouveau_bufctx_reset(nv50->bufctx, 0);<br>
+}<br>
+<br>
+static void<br>
nv50_clear_buffer(struct pipe_context *pipe,<br>
struct pipe_resource *res,<br>
unsigned offset, unsigned size,<br>
@@ -643,77 +719,85 @@ nv50_clear_buffer(struct pipe_context *pipe,<br>
<br>
assert(size % data_size == 0);<br>
<br>
+ if (offset & 0xff) {<br>
+ unsigned fixup_size = MIN2(size, align(offset, 0x100) - offset);<br>
+ assert(fixup_size % data_size == 0);<br>
+ nv50_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size);<br>
+ offset += fixup_size;<br>
+ size -= fixup_size;<br>
+ if (!size)<br>
+ return;<br>
+ }<br>
+<br>
elements = size / data_size;<br>
height = (elements + 8191) / 8192;<br>
width = elements / height;<br>
+ width &= ~0xff;<br>
<br>
- BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);<br>
- PUSH_DATAf(push, color.f[0]);<br>
- PUSH_DATAf(push, color.f[1]);<br>
- PUSH_DATAf(push, color.f[2]);<br>
- PUSH_DATAf(push, color.f[3]);<br>
+ if (width) {<br>
+ BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);<br>
+ PUSH_DATAf(push, color.f[0]);<br>
+ PUSH_DATAf(push, color.f[1]);<br>
+ PUSH_DATAf(push, color.f[2]);<br>
+ PUSH_DATAf(push, color.f[3]);<br>
<br>
- if (nouveau_pushbuf_space(push, 32, 1, 0))<br>
- return;<br>
+ if (nouveau_pushbuf_space(push, 32, 1, 0))<br>
+ return;<br>
<br>
- PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);<br>
+ PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);<br>
<br>
- BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);<br>
- PUSH_DATA (push, width << 16);<br>
- PUSH_DATA (push, height << 16);<br>
- BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);<br>
- PUSH_DATA (push, 8192 << 16);<br>
- PUSH_DATA (push, 8192 << 16);<br>
- nv50->scissors_dirty |= 1;<br>
+ BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);<br>
+ PUSH_DATA (push, width << 16);<br>
+ PUSH_DATA (push, height << 16);<br>
+ BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);<br>
+ PUSH_DATA (push, 8192 << 16);<br>
+ PUSH_DATA (push, 8192 << 16);<br>
+ nv50->scissors_dirty |= 1;<br>
<br>
- BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);<br>
- PUSH_DATA (push, 1);<br>
- BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);<br>
- PUSH_DATAh(push, buf->bo->offset + buf->offset + offset);<br>
- PUSH_DATA (push, buf->bo->offset + buf->offset + offset);<br>
- PUSH_DATA (push, nv50_format_table[dst_fmt].rt);<br>
- PUSH_DATA (push, 0);<br>
- PUSH_DATA (push, 0);<br>
- BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);<br>
- PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | (width * data_size));<br>
- PUSH_DATA (push, height);<br>
- BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);<br>
- PUSH_DATA (push, 0);<br>
- BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);<br>
- PUSH_DATA (push, 0);<br>
+ BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);<br>
+ PUSH_DATA (push, 1);<br>
+ BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);<br>
+ PUSH_DATAh(push, buf->address + offset);<br>
+ PUSH_DATA (push, buf->address + offset);<br>
+ PUSH_DATA (push, nv50_format_table[dst_fmt].rt);<br>
+ PUSH_DATA (push, 0);<br>
+ PUSH_DATA (push, 0);<br>
+ BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);<br>
+ PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | (width * data_size));<br>
+ PUSH_DATA (push, height);<br>
+ BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);<br>
+ PUSH_DATA (push, 0);<br>
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);<br>
+ PUSH_DATA (push, 0);<br>
<br>
- /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */<br>
+ /* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */<br>
<br>
- BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);<br>
- PUSH_DATA (push, (width << 16));<br>
- PUSH_DATA (push, (height << 16));<br>
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);<br>
+ PUSH_DATA (push, (width << 16));<br>
+ PUSH_DATA (push, (height << 16));<br>
<br>
- BEGIN_NV04(push, NV50_3D(COND_MODE), 1);<br>
- PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);<br>
+ BEGIN_NV04(push, NV50_3D(COND_MODE), 1);<br>
+ PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);<br>
+<br>
+ BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), 1);<br>
+ PUSH_DATA (push, 0x3c);<br>
<br>
- BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), 1);<br>
- PUSH_DATA (push, 0x3c);<br>
+ BEGIN_NV04(push, NV50_3D(COND_MODE), 1);<br>
+ PUSH_DATA (push, nv50->cond_condmode);<br>
+<br>
+ if (buf->mm) {<br>
+ nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence);<br>
+ nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr);<br>
+ }<br>
+ }<br>
<br>
if (width * height != elements) {<br>
offset += width * height * data_size;<br>
width = elements - width * height;<br>
- height = 1;<br>
- BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 2);<br>
- PUSH_DATAh(push, buf->bo->offset + buf->offset + offset);<br>
- PUSH_DATA (push, buf->bo->offset + buf->offset + offset);<br>
- BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);<br>
- PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | (width * data_size));<br>
- PUSH_DATA (push, height);<br>
- BEGIN_NI04(push, NV50_3D(CLEAR_BUFFERS), 1);<br>
- PUSH_DATA (push, 0x3c);<br>
+ nv50_clear_buffer_push(pipe, res, offset, width * data_size,<br>
+ data, data_size);<br>
}<br>
<br>
- BEGIN_NV04(push, NV50_3D(COND_MODE), 1);<br>
- PUSH_DATA (push, nv50->cond_condmode);<br>
-<br>
- nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence);<br>
- nouveau_fence_ref(nv50->screen->base.fence.current, &buf->fence_wr);<br>
-<br>
nv50->dirty |= NV50_NEW_FRAMEBUFFER | NV50_NEW_SCISSOR;<br>
}<br>
<br>
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c<br>
index 4e43c4e..be4c531 100644<br>
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c<br>
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c<br>
@@ -357,27 +357,132 @@ nvc0_clear_render_target(struct pipe_context *pipe,<br>
}<br>
<br>
static void<br>
-nvc0_clear_buffer_cpu(struct pipe_context *pipe,<br>
- struct pipe_resource *res,<br>
- unsigned offset, unsigned size,<br>
- const void *data, int data_size)<br>
+nvc0_clear_buffer_push_nvc0(struct pipe_context *pipe,<br>
+ struct pipe_resource *res,<br>
+ unsigned offset, unsigned size,<br>
+ const void *data, int data_size)<br>
{<br>
+ struct nvc0_context *nvc0 = nvc0_context(pipe);<br>
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;<br>
struct nv04_resource *buf = nv04_resource(res);<br>
- struct pipe_transfer *pt;<br>
- struct pipe_box box;<br>
- unsigned elements, i;<br>
+ unsigned i;<br>
<br>
- elements = size / data_size;<br>
+ nouveau_bufctx_refn(nvc0->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR);<br>
+ nouveau_pushbuf_bufctx(push, nvc0->bufctx);<br>
+ nouveau_pushbuf_validate(push);<br>
+<br>
+ unsigned count = (size + 3) / 4;<br>
+ unsigned data_words = data_size / 4;<br>
+<br>
+ while (count) {<br>
+ unsigned nr_data = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN) / data_words;<br>
+ unsigned nr = nr_data * data_words;<br>
<br>
- u_box_1d(offset, size, &box);<br>
+ if (!PUSH_SPACE(push, nr + 9))<br>
+ break;<br>
+<br>
+ BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);<br>
+ PUSH_DATAh(push, buf->address + offset);<br>
+ PUSH_DATA (push, buf->address + offset);<br>
+ BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);<br>
+ PUSH_DATA (push, MIN2(size, nr * 4));<br>
+ PUSH_DATA (push, 1);<br>
+ BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);<br>
+ PUSH_DATA (push, 0x100111);<br>
<br>
- uint8_t *map = buf->vtbl->transfer_map(pipe, res, 0, PIPE_TRANSFER_WRITE,<br>
- &box, &pt);<br>
+ /* must not be interrupted (trap on QUERY fence, 0x50 works however) */<br>
+ BEGIN_NIC0(push, NVC0_M2MF(DATA), nr);<br>
+ for (i = 0; i < nr_data; i++)<br>
+ PUSH_DATAp(push, data, data_words);<br>
<br>
- for (i = 0; i < elements; ++i)<br>
- memcpy(&map[i*data_size], data, data_size);<br>
+ count -= nr;<br>
+ offset += nr * 4;<br>
+ size -= nr * 4;<br>
+ }<br>
+<br>
+ if (buf->mm) {<br>
+ nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);<br>
+ nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);<br>
+ }<br>
+<br>
+ nouveau_bufctx_reset(nvc0->bufctx, 0);<br>
+}<br>
+<br>
+static void<br>
+nvc0_clear_buffer_push_nve4(struct pipe_context *pipe,<br>
+ struct pipe_resource *res,<br>
+ unsigned offset, unsigned size,<br>
+ const void *data, int data_size)<br>
+{<br>
+ struct nvc0_context *nvc0 = nvc0_context(pipe);<br>
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;<br>
+ struct nv04_resource *buf = nv04_resource(res);<br>
+ unsigned i;<br>
+<br>
+ nouveau_bufctx_refn(nvc0->bufctx, 0, buf->bo, buf->domain | NOUVEAU_BO_WR);<br>
+ nouveau_pushbuf_bufctx(push, nvc0->bufctx);<br>
+ nouveau_pushbuf_validate(push);<br>
+<br>
+ unsigned count = (size + 3) / 4;<br>
+ unsigned data_words = data_size / 4;<br>
+<br>
+ while (count) {<br>
+ unsigned nr_data = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN) / data_words;<br>
+ unsigned nr = nr_data * data_words;<br>
+<br>
+ if (!PUSH_SPACE(push, nr + 10))<br>
+ break;<br>
+<br>
+ BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_DST_ADDRESS_HIGH), 2);<br>
+ PUSH_DATAh(push, buf->address + offset);<br>
+ PUSH_DATA (push, buf->address + offset);<br>
+ BEGIN_NVC0(push, NVE4_P2MF(UPLOAD_LINE_LENGTH_IN), 2);<br>
+ PUSH_DATA (push, MIN2(size, nr * 4));<br>
+ PUSH_DATA (push, 1);<br>
+ /* must not be interrupted (trap on QUERY fence, 0x50 works however) */<br>
+ BEGIN_1IC0(push, NVE4_P2MF(UPLOAD_EXEC), nr + 1);<br>
+ PUSH_DATA (push, 0x1001);<br>
+ for (i = 0; i < nr_data; i++)<br>
+ PUSH_DATAp(push, data, data_words);<br>
+<br>
+ count -= nr;<br>
+ offset += nr * 4;<br>
+ size -= nr * 4;<br>
+ }<br>
+<br>
+ if (buf->mm) {<br>
+ nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);<br>
+ nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);<br>
+ }<br>
+<br>
+ nouveau_bufctx_reset(nvc0->bufctx, 0);<br>
+}<br>
+<br>
+static void<br>
+nvc0_clear_buffer_push(struct pipe_context *pipe,<br>
+ struct pipe_resource *res,<br>
+ unsigned offset, unsigned size,<br>
+ const void *data, int data_size)<br>
+{<br>
+ struct nvc0_context *nvc0 = nvc0_context(pipe);<br>
+ unsigned tmp;<br>
+<br>
+ if (data_size == 1) {<br>
+ tmp = *(unsigned char *)data;<br>
+ tmp = (tmp << 24) | (tmp << 16) | (tmp << 8) | tmp;<br>
+ data = &tmp;<br>
+ data_size = 4;<br>
+ } else if (data_size == 2) {<br>
+ tmp = *(unsigned short *)data;<br>
+ tmp = (tmp << 16) | tmp;<br>
+ data = &tmp;<br>
+ data_size = 4;<br>
+ }<br>
<br>
- buf->vtbl->transfer_unmap(pipe, pt);<br>
+ if (nvc0->screen->base.class_3d < NVE4_3D_CLASS)<br>
+ nvc0_clear_buffer_push_nvc0(pipe, res, offset, size, data, data_size);<br>
+ else<br>
+ nvc0_clear_buffer_push_nve4(pipe, res, offset, size, data, data_size);<br>
}<br>
<br>
static void<br>
@@ -402,10 +507,8 @@ nvc0_clear_buffer(struct pipe_context *pipe,<br>
memcpy(&color.ui, data, 16);<br>
break;<br>
case 12:<br>
- /* This doesn't work, RGB32 is not a valid RT format.<br>
- * dst_fmt = PIPE_FORMAT_R32G32B32_UINT;<br>
- * memcpy(&color.ui, data, 12);<br>
- * memset(&color.ui[3], 0, 4);<br>
+ /* RGB32 is not a valid RT format. This will be handled by the pushbuf<br>
+ * uploader.<br>
*/<br>
break;<br>
case 8:<br>
@@ -437,67 +540,75 @@ nvc0_clear_buffer(struct pipe_context *pipe,<br>
assert(size % data_size == 0);<br>
<br>
if (data_size == 12) {<br>
- /* TODO: Find a way to do this with the GPU! */<br>
- nvc0_clear_buffer_cpu(pipe, res, offset, size, data, data_size);<br>
+ nvc0_clear_buffer_push(pipe, res, offset, size, data, data_size);<br>
return;<br>
}<br>
<br>
+ if (offset & 0xff) {<br>
+ unsigned fixup_size = MIN2(size, align(offset, 0x100) - offset);<br>
+ assert(fixup_size % data_size == 0);<br>
+ nvc0_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size);<br>
+ offset += fixup_size;<br>
+ size -= fixup_size;<br>
+ if (!size)<br>
+ return;<br>
+ }<br>
+<br>
elements = size / data_size;<br>
height = (elements + 16383) / 16384;<br>
width = elements / height;<br>
+ width &= ~0xff;<br>
<br>
- if (!PUSH_SPACE(push, 40))<br>
- return;<br>
-<br>
- PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR);<br>
-<br>
- BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);<br>
- PUSH_DATAf(push, color.f[0]);<br>
- PUSH_DATAf(push, color.f[1]);<br>
- PUSH_DATAf(push, color.f[2]);<br>
- PUSH_DATAf(push, color.f[3]);<br>
- BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);<br>
- PUSH_DATA (push, width << 16);<br>
- PUSH_DATA (push, height << 16);<br>
-<br>
- IMMED_NVC0(push, NVC0_3D(RT_CONTROL), 1);<br>
-<br>
- BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9);<br>
- PUSH_DATAh(push, buf->address + offset);<br>
- PUSH_DATA (push, buf->address + offset);<br>
- PUSH_DATA (push, width * data_size);<br>
- PUSH_DATA (push, height);<br>
- PUSH_DATA (push, nvc0_format_table[dst_fmt].rt);<br>
- PUSH_DATA (push, NVC0_3D_RT_TILE_MODE_LINEAR);<br>
- PUSH_DATA (push, 1);<br>
- PUSH_DATA (push, 0);<br>
- PUSH_DATA (push, 0);<br>
-<br>
- IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);<br>
- IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0);<br>
+ if (width) {<br>
+ if (!PUSH_SPACE(push, 40))<br>
+ return;<br>
<br>
- IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);<br>
+ PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR);<br>
<br>
- IMMED_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 0x3c);<br>
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);<br>
+ PUSH_DATAf(push, color.f[0]);<br>
+ PUSH_DATAf(push, color.f[1]);<br>
+ PUSH_DATAf(push, color.f[2]);<br>
+ PUSH_DATAf(push, color.f[3]);<br>
+ BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);<br>
+ PUSH_DATA (push, width << 16);<br>
+ PUSH_DATA (push, height << 16);<br>
<br>
- if (width * height != elements) {<br>
- offset += width * height * data_size;<br>
- width = elements - width * height;<br>
- height = 1;<br>
+ IMMED_NVC0(push, NVC0_3D(RT_CONTROL), 1);<br>
<br>
- BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 4);<br>
+ BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9);<br>
PUSH_DATAh(push, buf->address + offset);<br>
PUSH_DATA (push, buf->address + offset);<br>
PUSH_DATA (push, width * data_size);<br>
PUSH_DATA (push, height);<br>
+ PUSH_DATA (push, nvc0_format_table[dst_fmt].rt);<br>
+ PUSH_DATA (push, NVC0_3D_RT_TILE_MODE_LINEAR);<br>
+ PUSH_DATA (push, 1);<br>
+ PUSH_DATA (push, 0);<br>
+ PUSH_DATA (push, 0);<br>
+<br>
+ IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);<br>
+ IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 0);<br>
+<br>
+ IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);<br>
<br>
IMMED_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 0x3c);<br>
+<br>
+ IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);<br>
+<br>
+ if (buf->mm) {<br>
+ nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);<br>
+ nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);<br>
+ }<br>
}<br>
<br>
- IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);<br>
+ if (width * height != elements) {<br>
+ offset += width * height * data_size;<br>
+ width = elements - width * height;<br>
+ nvc0_clear_buffer_push(pipe, res, offset, width * data_size,<br>
+ data, data_size);<br>
+ }<br>
<br>
- nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);<br>
- nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);<br>
nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;<br>
}<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.4.10<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>