summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv50
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv50')
-rw-r--r--src/gallium/drivers/nv50/nv50_3d.xml.h158
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c150
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h52
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c69
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c7
-rw-r--r--src/gallium/drivers/nv50/nv50_program.h2
-rw-r--r--src/gallium/drivers/nv50/nv50_push.c58
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c128
-rw-r--r--src/gallium/drivers/nv50/nv50_resource.h11
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c501
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h27
-rw-r--r--src/gallium/drivers/nv50/nv50_shader_state.c255
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c31
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c244
-rw-r--r--src/gallium/drivers/nv50/nv50_stateobj.h10
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c405
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c129
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c252
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c334
-rw-r--r--src/gallium/drivers/nv50/nv50_winsys.h142
20 files changed, 1510 insertions, 1455 deletions
diff --git a/src/gallium/drivers/nv50/nv50_3d.xml.h b/src/gallium/drivers/nv50/nv50_3d.xml.h
index 0f5a77de9a1..9dff8b2dd13 100644
--- a/src/gallium/drivers/nv50/nv50_3d.xml.h
+++ b/src/gallium/drivers/nv50/nv50_3d.xml.h
@@ -1,5 +1,5 @@
-#ifndef NV50_3D_XML
-#define NV50_3D_XML
+#ifndef RNNDB_NV50_3D_XML
+#define RNNDB_NV50_3D_XML
/* Autogenerated file, DO NOT EDIT manually!
@@ -8,15 +8,15 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng
git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are:
-- nv50_3d.xml ( 64479 bytes, from 2011-02-27 17:58:08)
-- copyright.xml ( 6452 bytes, from 2010-12-15 23:45:18)
-- nv_defs.xml ( 4437 bytes, from 2010-12-15 23:45:18)
-- nv50_defs.xml ( 4487 bytes, from 2010-12-15 23:45:18)
-- nv_3ddefs.xml ( 16394 bytes, from 2010-12-15 23:45:18)
-- nv_object.xml ( 12191 bytes, from 2011-02-27 17:58:08)
-- nvchipsets.xml ( 3074 bytes, from 2011-02-27 17:58:08)
-
-Copyright (C) 2006-2011 by the following authors:
+- rnndb/nv50_3d.xml ( 65226 bytes, from 2012-01-28 13:46:30)
+- ./rnndb/copyright.xml ( 6452 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv_defs.xml ( 4437 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv50_defs.xml ( 5468 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nvchipsets.xml ( 3617 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv_3ddefs.xml ( 16394 bytes, from 2011-08-11 18:25:12)
+- ./rnndb/nv_object.xml ( 12672 bytes, from 2011-08-11 18:25:12)
+
+Copyright (C) 2006-2012 by the following authors:
- Artur Huillet <[email protected]> (ahuillet)
- Ben Skeggs (darktama, darktama_)
- B. R. <[email protected]> (koala_br)
@@ -74,7 +74,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#define NV50_3D_SERIALIZE 0x00000110
+
#define NV50_3D_DMA_NOTIFY 0x00000180
@@ -592,9 +592,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_CLIPID_ADDRESS_LOW 0x00000fd0
-#define NV50_3D_MAP_SEMANTIC_5 0x00000fd4
-#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__MASK 0x000000ff
-#define NV50_3D_MAP_SEMANTIC_5_VIEWPORT_ID__SHIFT 0
+#define NV50_3D_SEMANTIC_VIEWPORT 0x00000fd4
+#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__MASK 0x000000ff
+#define NV50_3D_SEMANTIC_VIEWPORT_VIEWPORT_ID__SHIFT 0
#define NV50_3D_UNK0FD8 0x00000fd8
#define NV50_3D_UNK0FD8_UNK0 0x00000001
@@ -1184,7 +1184,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_BIND_TSC2__ESIZE 0x00000008
#define NV50_3D_BIND_TSC2__LEN 0x00000003
#define NV50_3D_BIND_TSC2_VALID 0x00000001
-#define NV50_3D_BIND_TSC2_SAMPLER__MASK 0x000000f0
+#define NV50_3D_BIND_TSC2_SAMPLER__MASK 0x00000010
#define NV50_3D_BIND_TSC2_SAMPLER__SHIFT 4
#define NV50_3D_BIND_TSC2_TSC__MASK 0x001ff000
#define NV50_3D_BIND_TSC2_TSC__SHIFT 12
@@ -1193,7 +1193,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_BIND_TIC2__ESIZE 0x00000008
#define NV50_3D_BIND_TIC2__LEN 0x00000003
#define NV50_3D_BIND_TIC2_VALID 0x00000001
-#define NV50_3D_BIND_TIC2_TEXTURE__MASK 0x000001fe
+#define NV50_3D_BIND_TIC2_TEXTURE__MASK 0x00000002
#define NV50_3D_BIND_TIC2_TEXTURE__SHIFT 1
#define NV50_3D_BIND_TIC2_TIC__MASK 0x7ffffe00
#define NV50_3D_BIND_TIC2_TIC__SHIFT 9
@@ -1217,15 +1217,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__MASK 0xffff0000
#define NV50_3D_CLIPID_FILL_RECT_VERT_HIGH__SHIFT 16
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE 0x00001510
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_0 0x00000001
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_1 0x00000002
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_2 0x00000004
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_3 0x00000008
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_4 0x00000010
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_5 0x00000020
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_6 0x00000040
-#define NV50_3D_VP_CLIP_DISTANCE_ENABLE_7 0x00000080
+#define NV50_3D_CLIP_DISTANCE_ENABLE 0x00001510
+#define NV50_3D_CLIP_DISTANCE_ENABLE_0 0x00000001
+#define NV50_3D_CLIP_DISTANCE_ENABLE_1 0x00000002
+#define NV50_3D_CLIP_DISTANCE_ENABLE_2 0x00000004
+#define NV50_3D_CLIP_DISTANCE_ENABLE_3 0x00000008
+#define NV50_3D_CLIP_DISTANCE_ENABLE_4 0x00000010
+#define NV50_3D_CLIP_DISTANCE_ENABLE_5 0x00000020
+#define NV50_3D_CLIP_DISTANCE_ENABLE_6 0x00000040
+#define NV50_3D_CLIP_DISTANCE_ENABLE_7 0x00000080
#define NV50_3D_SAMPLECNT_ENABLE 0x00001514
@@ -1391,9 +1391,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_MULTISAMPLE_MODE_MS8 0x00000003
#define NV50_3D_MULTISAMPLE_MODE_MS8_ALT 0x00000004
#define NV50_3D_MULTISAMPLE_MODE_MS2_ALT 0x00000005
+#define NV50_3D_MULTISAMPLE_MODE_UNK6 0x00000006
#define NV50_3D_MULTISAMPLE_MODE_MS4_CS4 0x00000008
#define NV50_3D_MULTISAMPLE_MODE_MS4_CS12 0x00000009
#define NV50_3D_MULTISAMPLE_MODE_MS8_CS8 0x0000000a
+#define NV50_3D_MULTISAMPLE_MODE_MS8_CS24 0x0000000b
#define NV50_3D_VERTEX_BEGIN_D3D 0x000015d4
#define NV50_3D_VERTEX_BEGIN_D3D_PRIMITIVE__MASK 0x0fffffff
@@ -1440,7 +1442,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_VERTEX_END_GL_UNK0 0x00000001
#define NVA0_3D_VERTEX_END_GL_UNK1 0x00000002
-#define NV50_3D_EDGEFLAG_ENABLE 0x000015e4
+#define NV50_3D_EDGEFLAG 0x000015e4
#define NV50_3D_VB_ELEMENT_U32 0x000015e8
@@ -1666,34 +1668,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_GP_VIEWPORT_ID_ENABLE 0x00001900
-#define NV50_3D_MAP_SEMANTIC_0 0x00001904
-#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__MASK 0x000000ff
-#define NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT 0
-#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__MASK 0x0000ff00
-#define NV50_3D_MAP_SEMANTIC_0_BFC0_ID__SHIFT 8
-#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__MASK 0x00ff0000
-#define NV50_3D_MAP_SEMANTIC_0_COLR_NR__SHIFT 16
-#define NV50_3D_MAP_SEMANTIC_0_CLMP_EN 0x01000000
-
-#define NV50_3D_MAP_SEMANTIC_1 0x00001908
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__MASK 0x000000ff
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_START__SHIFT 0
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__MASK 0x00000f00
-#define NV50_3D_MAP_SEMANTIC_1_CLIP_NUM__SHIFT 8
-
-#define NV50_3D_MAP_SEMANTIC_2 0x0000190c
-#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__MASK 0x000000ff
-#define NV50_3D_MAP_SEMANTIC_2_LAYER_ID__SHIFT 0
-
-#define NV50_3D_MAP_SEMANTIC_3 0x00001910
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK 0x00000001
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__SHIFT 0
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__MASK 0x00000ff0
-#define NV50_3D_MAP_SEMANTIC_3_PTSZ_ID__SHIFT 4
-
-#define NV50_3D_MAP_SEMANTIC_4 0x00001914
-#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__MASK 0x000000ff
-#define NV50_3D_MAP_SEMANTIC_4_PRIM_ID__SHIFT 0
+#define NV50_3D_SEMANTIC_COLOR 0x00001904
+#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__MASK 0x000000ff
+#define NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT 0
+#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__MASK 0x0000ff00
+#define NV50_3D_SEMANTIC_COLOR_BFC0_ID__SHIFT 8
+#define NV50_3D_SEMANTIC_COLOR_COLR_NR__MASK 0x00ff0000
+#define NV50_3D_SEMANTIC_COLOR_COLR_NR__SHIFT 16
+#define NV50_3D_SEMANTIC_COLOR_CLMP_EN 0x01000000
+
+#define NV50_3D_SEMANTIC_CLIP 0x00001908
+#define NV50_3D_SEMANTIC_CLIP_CLIP_START__MASK 0x000000ff
+#define NV50_3D_SEMANTIC_CLIP_CLIP_START__SHIFT 0
+#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__MASK 0x00000f00
+#define NV50_3D_SEMANTIC_CLIP_CLIP_NUM__SHIFT 8
+
+#define NV50_3D_SEMANTIC_LAYER 0x0000190c
+#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__MASK 0x000000ff
+#define NV50_3D_SEMANTIC_LAYER_LAYER_ID__SHIFT 0
+
+#define NV50_3D_SEMANTIC_PTSZ 0x00001910
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK 0x00000001
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__SHIFT 0
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__MASK 0x00000ff0
+#define NV50_3D_SEMANTIC_PTSZ_PTSZ_ID__SHIFT 4
+
+#define NV50_3D_SEMANTIC_PRIM_ID 0x00001914
+#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__MASK 0x000000ff
+#define NV50_3D_SEMANTIC_PRIM_ID_PRIM_ID__SHIFT 0
#define NV50_3D_CULL_FACE_ENABLE 0x00001918
@@ -1729,15 +1731,39 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1 0x00001000
#define NV84_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2 0x00002000
-#define NV50_3D_UNK1940 0x00001940
-#define NV50_3D_UNK1940_0 0x00000001
-#define NV50_3D_UNK1940_1 0x00000010
-#define NV50_3D_UNK1940_2 0x00000100
-#define NV50_3D_UNK1940_3 0x00001000
-#define NV50_3D_UNK1940_4 0x00010000
-#define NV50_3D_UNK1940_5 0x00100000
-#define NV50_3D_UNK1940_6 0x01000000
-#define NV50_3D_UNK1940_7 0x10000000
+#define NV50_3D_CLIP_DISTANCE_MODE 0x00001940
+#define NV50_3D_CLIP_DISTANCE_MODE_0__MASK 0x00000001
+#define NV50_3D_CLIP_DISTANCE_MODE_0__SHIFT 0
+#define NV50_3D_CLIP_DISTANCE_MODE_0_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_0_CULL 0x00000001
+#define NV50_3D_CLIP_DISTANCE_MODE_1__MASK 0x00000010
+#define NV50_3D_CLIP_DISTANCE_MODE_1__SHIFT 4
+#define NV50_3D_CLIP_DISTANCE_MODE_1_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_1_CULL 0x00000010
+#define NV50_3D_CLIP_DISTANCE_MODE_2__MASK 0x00000100
+#define NV50_3D_CLIP_DISTANCE_MODE_2__SHIFT 8
+#define NV50_3D_CLIP_DISTANCE_MODE_2_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_2_CULL 0x00000100
+#define NV50_3D_CLIP_DISTANCE_MODE_3__MASK 0x00001000
+#define NV50_3D_CLIP_DISTANCE_MODE_3__SHIFT 12
+#define NV50_3D_CLIP_DISTANCE_MODE_3_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_3_CULL 0x00001000
+#define NV50_3D_CLIP_DISTANCE_MODE_4__MASK 0x00010000
+#define NV50_3D_CLIP_DISTANCE_MODE_4__SHIFT 16
+#define NV50_3D_CLIP_DISTANCE_MODE_4_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_4_CULL 0x00010000
+#define NV50_3D_CLIP_DISTANCE_MODE_5__MASK 0x00100000
+#define NV50_3D_CLIP_DISTANCE_MODE_5__SHIFT 20
+#define NV50_3D_CLIP_DISTANCE_MODE_5_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_5_CULL 0x00100000
+#define NV50_3D_CLIP_DISTANCE_MODE_6__MASK 0x01000000
+#define NV50_3D_CLIP_DISTANCE_MODE_6__SHIFT 24
+#define NV50_3D_CLIP_DISTANCE_MODE_6_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_6_CULL 0x01000000
+#define NV50_3D_CLIP_DISTANCE_MODE_7__MASK 0x10000000
+#define NV50_3D_CLIP_DISTANCE_MODE_7__SHIFT 28
+#define NV50_3D_CLIP_DISTANCE_MODE_7_CLIP 0x00000000
+#define NV50_3D_CLIP_DISTANCE_MODE_7_CULL 0x10000000
#define NVA3_3D_UNK1944 0x00001944
@@ -2048,7 +2074,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVA3_3D_IBLEND__ESIZE 0x00000020
#define NVA3_3D_IBLEND__LEN 0x00000008
-#define NVA3_3D_IBLEND_UNK00(i0) (0x00001e00 + 0x20*(i0))
+#define NVA3_3D_IBLEND_SEPARATE_ALPHA(i0) (0x00001e00 + 0x20*(i0))
#define NVA3_3D_IBLEND_EQUATION_RGB(i0) (0x00001e04 + 0x20*(i0))
#define NVA3_3D_IBLEND_EQUATION_RGB_FUNC_ADD 0x00008006
@@ -2081,4 +2107,4 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVA3_3D_VERTEX_ARRAY_LIMIT_LOW_ALT__LEN 0x00000020
-#endif /* NV50_3D_XML */
+#endif /* RNNDB_NV50_3D_XML */
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 3b0f8f07d1c..88eb4bb246c 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -33,40 +33,36 @@ static void
nv50_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence)
{
- struct nouveau_screen *screen = &nv50_context(pipe)->screen->base;
+ struct nouveau_screen *screen = nouveau_screen(pipe->screen);
if (fence)
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
- /* Try to emit before firing to avoid having to flush again right after
- * in case we have to wait on this fence.
- */
- nouveau_fence_emit(screen->fence.current);
-
- FIRE_RING(screen->channel);
+ PUSH_KICK(screen->pushbuf);
}
static void
nv50_texture_barrier(struct pipe_context *pipe)
{
- struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf;
- BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
- OUT_RING (chan, 0x20);
+ BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
+ PUSH_DATA (push, 0x20);
}
void
-nv50_default_flush_notify(struct nouveau_channel *chan)
+nv50_default_kick_notify(struct nouveau_pushbuf *push)
{
- struct nv50_screen *screen = chan->user_private;
-
- if (!screen)
- return;
+ struct nv50_screen *screen = push->user_priv;
- nouveau_fence_update(&screen->base, TRUE);
- nouveau_fence_next(&screen->base);
+ if (screen) {
+ nouveau_fence_next(&screen->base);
+ nouveau_fence_update(&screen->base, TRUE);
+ if (screen->cur_ctx)
+ screen->cur_ctx->state.flushed = TRUE;
+ }
}
static void
@@ -74,8 +70,8 @@ nv50_context_unreference_resources(struct nv50_context *nv50)
{
unsigned s, i;
- for (i = 0; i < NV50_BUFCTX_COUNT; ++i)
- nv50_bufctx_reset(nv50, i);
+ nouveau_bufctx_del(&nv50->bufctx_3d);
+ nouveau_bufctx_del(&nv50->bufctx);
for (i = 0; i < nv50->num_vtxbufs; ++i)
pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL);
@@ -96,13 +92,18 @@ nv50_destroy(struct pipe_context *pipe)
{
struct nv50_context *nv50 = nv50_context(pipe);
+ if (nv50_context_screen(nv50)->cur_ctx == nv50) {
+ nv50->base.pushbuf->kick_notify = NULL;
+ nv50_context_screen(nv50)->cur_ctx = NULL;
+ nouveau_pushbuf_bufctx(nv50->base.pushbuf, NULL);
+ }
+ /* need to flush before destroying the bufctx */
+ nouveau_pushbuf_kick(nv50->base.pushbuf, nv50->base.pushbuf->channel);
+
nv50_context_unreference_resources(nv50);
draw_destroy(nv50->draw);
- if (nv50->screen->cur_ctx == nv50)
- nv50->screen->cur_ctx = NULL;
-
FREE(nv50);
}
@@ -112,17 +113,28 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
struct nv50_screen *screen = nv50_screen(pscreen);
struct nv50_context *nv50;
struct pipe_context *pipe;
+ int ret;
+ uint32_t flags;
nv50 = CALLOC_STRUCT(nv50_context);
if (!nv50)
return NULL;
pipe = &nv50->base.pipe;
- nv50->screen = screen;
+ nv50->base.pushbuf = screen->base.pushbuf;
+
+ ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_COUNT,
+ &nv50->bufctx_3d);
+ if (!ret)
+ ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
+ if (ret)
+ goto out_err;
+
nv50->base.screen = &screen->base;
nv50->base.copy_data = nv50_m2mf_copy_linear;
nv50->base.push_data = nv50_sifc_linear_u8;
+ nv50->screen = screen;
pipe->screen = pscreen;
pipe->priv = priv;
@@ -134,9 +146,10 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
pipe->flush = nv50_flush;
pipe->texture_barrier = nv50_texture_barrier;
- if (!screen->cur_ctx)
+ if (!screen->cur_ctx) {
screen->cur_ctx = nv50;
- screen->base.channel->flush_notify = nv50_default_flush_notify;
+ nouveau_pushbuf_bufctx(screen->base.pushbuf, nv50->bufctx);
+ }
nv50_init_query_functions(nv50);
nv50_init_surface_functions(nv50);
@@ -149,72 +162,41 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
nouveau_context_init_vdec(&nv50->base);
- return pipe;
-}
+ flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-struct resident {
- struct nv04_resource *res;
- uint32_t flags;
-};
+ BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->code);
+ BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->uniforms);
+ BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->txc);
+ BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->stack_bo);
-void
-nv50_bufctx_add_resident(struct nv50_context *nv50, int ctx,
- struct nv04_resource *resource, uint32_t flags)
-{
- struct resident rsd = { resource, flags };
+ flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
- if (!resource->bo)
- return;
- nv50->residents_size += sizeof(struct resident);
+ BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->fence.bo);
+ BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);
- /* We don't need to reference the resource here, it will be referenced
- * in the context/state, and bufctx will be reset when state changes.
- */
- util_dynarray_append(&nv50->residents[ctx], struct resident, rsd);
-}
+ return pipe;
-void
-nv50_bufctx_del_resident(struct nv50_context *nv50, int ctx,
- struct nv04_resource *resource)
-{
- struct resident *rsd, *top;
- unsigned i;
-
- for (i = 0; i < nv50->residents[ctx].size / sizeof(struct resident); ++i) {
- rsd = util_dynarray_element(&nv50->residents[ctx], struct resident, i);
-
- if (rsd->res == resource) {
- top = util_dynarray_pop_ptr(&nv50->residents[ctx], struct resident);
- if (rsd != top)
- *rsd = *top;
- nv50->residents_size -= sizeof(struct resident);
- break;
- }
+out_err:
+ if (nv50) {
+ if (nv50->bufctx_3d)
+ nouveau_bufctx_del(&nv50->bufctx_3d);
+ if (nv50->bufctx)
+ nouveau_bufctx_del(&nv50->bufctx);
+ FREE(nv50);
}
+ return NULL;
}
void
-nv50_bufctx_emit_relocs(struct nv50_context *nv50)
+nv50_bufctx_fence(struct nouveau_bufctx *bufctx, boolean on_flush)
{
- struct resident *rsd;
- struct util_dynarray *array;
- unsigned ctx, i, n;
-
- n = nv50->residents_size / sizeof(struct resident);
- n += NV50_SCREEN_RESIDENT_BO_COUNT;
-
- MARK_RING(nv50->screen->base.channel, 0, n);
-
- for (ctx = 0; ctx < NV50_BUFCTX_COUNT; ++ctx) {
- array = &nv50->residents[ctx];
-
- n = array->size / sizeof(struct resident);
- for (i = 0; i < n; ++i) {
- rsd = util_dynarray_element(array, struct resident, i);
-
- nv50_resource_validate(rsd->res, rsd->flags);
- }
+ struct nouveau_list *list = on_flush ? &bufctx->current : &bufctx->pending;
+ struct nouveau_list *it;
+
+ for (it = list->next; it != list; it = it->next) {
+ struct nouveau_bufref *ref = (struct nouveau_bufref *)it;
+ struct nv04_resource *res = ref->priv;
+ if (res)
+ nv50_resource_validate(res, (unsigned)ref->priv_data);
}
-
- nv50_screen_make_buffers_resident(nv50->screen);
}
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 2bf634a8237..0dd6c16bb48 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -46,12 +46,20 @@
#define NV50_NEW_CONSTBUF (1 << 18)
#define NV50_NEW_TEXTURES (1 << 19)
#define NV50_NEW_SAMPLERS (1 << 20)
-
-#define NV50_BUFCTX_CONSTANT 0
-#define NV50_BUFCTX_FRAME 1
-#define NV50_BUFCTX_VERTEX 2
-#define NV50_BUFCTX_TEXTURES 3
-#define NV50_BUFCTX_COUNT 4
+#define NV50_NEW_CONTEXT (1 << 31)
+
+#define NV50_BIND_FB 0
+#define NV50_BIND_VERTEX 1
+#define NV50_BIND_VERTEX_TMP 2
+#define NV50_BIND_INDEX 3
+#define NV50_BIND_TEXTURES 4
+#define NV50_BIND_CB(s, i) (5 + 16 * (s) + (i))
+#define NV50_BIND_SCREEN 53
+#define NV50_BIND_TLS 54
+#define NV50_BIND_COUNT 55
+#define NV50_BIND_2D 0
+#define NV50_BIND_M2MF 0
+#define NV50_BIND_FENCE 1
#define NV50_CB_TMP 123
/* fixed constant buffer binding points - low indices for user's constbufs */
@@ -60,13 +68,14 @@
#define NV50_CB_PFP 125
#define NV50_CB_AUX 127
+
struct nv50_context {
struct nouveau_context base;
struct nv50_screen *screen;
- struct util_dynarray residents[NV50_BUFCTX_COUNT];
- unsigned residents_size;
+ struct nouveau_bufctx *bufctx_3d;
+ struct nouveau_bufctx *bufctx;
uint32_t dirty;
@@ -79,6 +88,9 @@ struct nv50_context {
int32_t index_bias;
boolean prim_restart;
boolean point_sprite;
+ boolean rt_serialize;
+ boolean flushed;
+ uint8_t tls_required;
uint8_t num_vtxbufs;
uint8_t num_vtxelts;
uint8_t num_textures[3];
@@ -97,6 +109,7 @@ struct nv50_context {
struct pipe_resource *constbuf[3][16];
uint16_t constbuf_dirty[3];
+ uint16_t constbuf_valid[3];
struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS];
unsigned num_vtxbufs;
@@ -132,22 +145,19 @@ nv50_context(struct pipe_context *pipe)
return (struct nv50_context *)pipe;
}
+static INLINE struct nv50_screen *
+nv50_context_screen(struct nv50_context *nv50)
+{
+ return nv50_screen(&nv50->base.screen->base);
+}
+
+
/* nv50_context.c */
struct pipe_context *nv50_create(struct pipe_screen *, void *);
-void nv50_default_flush_notify(struct nouveau_channel *);
+void nv50_bufctx_fence(struct nouveau_bufctx *, boolean on_flush);
-void nv50_bufctx_emit_relocs(struct nv50_context *);
-void nv50_bufctx_add_resident(struct nv50_context *, int ctx,
- struct nv04_resource *, uint32_t flags);
-void nv50_bufctx_del_resident(struct nv50_context *, int ctx,
- struct nv04_resource *);
-static INLINE void
-nv50_bufctx_reset(struct nv50_context *nv50, int ctx)
-{
- nv50->residents_size -= nv50->residents[ctx].size;
- util_dynarray_resize(&nv50->residents[ctx], 0);
-}
+void nv50_default_kick_notify(struct nouveau_pushbuf *);
/* nv50_draw.c */
extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
@@ -194,7 +204,7 @@ nv50_create_sampler_view(struct pipe_context *,
/* nv50_transfer.c */
void
-nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nv50_m2mf_transfer_rect(struct nv50_context *,
const struct nv50_m2mf_rect *dst,
const struct nv50_m2mf_rect *src,
uint32_t nblocksx, uint32_t nblocksy);
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 76b60592bfb..bfadbc5ab28 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -31,7 +31,7 @@
static INLINE uint32_t
nv50_tex_choose_tile_dims(unsigned nx, unsigned ny, unsigned nz)
{
- return nvc0_tex_choose_tile_dims(nx, ny * 2, nz) >> 4;
+ return nvc0_tex_choose_tile_dims(nx, ny * 2, nz);
}
static uint32_t
@@ -41,58 +41,60 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
uint32_t tile_flags;
- if (mt->base.base.bind & PIPE_BIND_CURSOR)
- return NOUVEAU_BO_TILE_SCANOUT;
+ if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
+ return 0;
+ if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
+ return 0;
switch (mt->base.base.format) {
case PIPE_FORMAT_Z16_UNORM:
- tile_flags = 0x6c00 + (ms << 8);
+ tile_flags = 0x6c + (ms << 8);
break;
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
- tile_flags = 0x1800 + (ms << 8);
+ tile_flags = 0x18 + (ms << 8);
break;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
- tile_flags = 0x22800 + (ms << 8);
+ tile_flags = 0x128 + (ms << 8);
break;
case PIPE_FORMAT_Z32_FLOAT:
- tile_flags = 0x4000 + (ms << 8);
+ tile_flags = 0x40 + (ms << 8);
break;
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
- tile_flags = 0x6000 + (ms << 8);
+ tile_flags = 0x60 + (ms << 8);
break;
default:
switch (util_format_get_blocksizebits(mt->base.base.format)) {
case 128:
assert(ms < 3);
- tile_flags = 0x7400;
+ tile_flags = 0x74;
break;
case 64:
switch (ms) {
- case 2: tile_flags = 0x17c00; break;
- case 3: tile_flags = 0x17d00; break;
+ case 2: tile_flags = 0xfc; break;
+ case 3: tile_flags = 0xfd; break;
default:
- tile_flags = 0x7000;
+ tile_flags = 0x70;
break;
}
break;
case 32:
if (mt->base.base.bind & PIPE_BIND_SCANOUT) {
assert(ms == 0);
- tile_flags = 0x7a00;
+ tile_flags = 0x7a;
} else {
switch (ms) {
- case 2: tile_flags = 0x17800; break;
- case 3: tile_flags = 0x17900; break;
+ case 2: tile_flags = 0xf8; break;
+ case 3: tile_flags = 0xf9; break;
default:
- tile_flags = 0x7000;
+ tile_flags = 0x70;
break;
}
}
break;
case 16:
case 8:
- tile_flags = 0x7000;
+ tile_flags = 0x70;
break;
default:
return 0;
@@ -101,14 +103,8 @@ nv50_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
tile_flags = 0;
}
- if (mt->base.base.bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR))
- tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
-
if (!compressed)
- tile_flags &= ~0x30000;
-
- if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
- tile_flags &= ~0x3ff00;
+ tile_flags &= ~0x180;
return tile_flags;
}
@@ -118,7 +114,7 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
- nouveau_screen_bo_release(pscreen, mt->base.bo);
+ nouveau_bo_ref(NULL, &mt->base.bo);
FREE(mt);
}
@@ -260,7 +256,8 @@ nv50_miptree_create(struct pipe_screen *pscreen,
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
struct pipe_resource *pt = &mt->base.base;
int ret;
- uint32_t tile_flags;
+ union nouveau_bo_config bo_config;
+ uint32_t bo_flags;
if (!mt)
return NULL;
@@ -270,30 +267,34 @@ nv50_miptree_create(struct pipe_screen *pscreen,
pipe_reference_init(&pt->reference, 1);
pt->screen = pscreen;
- tile_flags = nv50_mt_choose_storage_type(mt, TRUE);
+ bo_config.nv50.memtype = nv50_mt_choose_storage_type(mt, TRUE);
if (!nv50_miptree_init_ms_mode(mt)) {
FREE(mt);
return NULL;
}
- if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+ if (bo_config.nv50.memtype != 0) {
nv50_miptree_init_layout_tiled(mt);
} else
if (!nv50_miptree_init_layout_linear(mt)) {
FREE(mt);
return NULL;
}
+ bo_config.nv50.tile_mode = mt->level[0].tile_mode;
+
+ bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_NOSNOOP;
+ if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET))
+ bo_flags |= NOUVEAU_BO_CONTIG;
- ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
- mt->total_size,
- mt->level[0].tile_mode, tile_flags,
- &mt->base.bo);
+ ret = nouveau_bo_new(dev, bo_flags, 4096, mt->total_size, &bo_config,
+ &mt->base.bo);
if (ret) {
FREE(mt);
return NULL;
}
mt->base.domain = NOUVEAU_BO_VRAM;
+ mt->base.address = mt->base.bo->offset;
return pt;
}
@@ -323,6 +324,8 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
FREE(mt);
return NULL;
}
+ mt->base.domain = NOUVEAU_BO_VRAM;
+ mt->base.address = mt->base.bo->offset;
mt->base.base = *templ;
mt->base.vtbl = &nv50_miptree_vtbl;
@@ -330,7 +333,7 @@ nv50_miptree_from_handle(struct pipe_screen *pscreen,
mt->base.base.screen = pscreen;
mt->level[0].pitch = stride;
mt->level[0].offset = 0;
- mt->level[0].tile_mode = mt->base.bo->tile_mode;
+ mt->level[0].tile_mode = mt->base.bo->config.nv50.tile_mode;
/* no need to adjust bo reference count */
return &mt->base.base;
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index c141a91eec2..776cecaeb7e 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -489,7 +489,8 @@ nv50_fragprog_prepare(struct nv50_translation_info *ti)
++nintp;
}
- p->fp.colors = 4 << NV50_3D_MAP_SEMANTIC_0_FFC0_ID__SHIFT; /* after HPOS */
+ /* after HPOS */
+ p->fp.colors = 4 << NV50_3D_SEMANTIC_COLOR_FFC0_ID__SHIFT;
for (i = 0; i < p->in_nr; ++i) {
int j = p->in[i].id;
@@ -680,8 +681,8 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
const struct pipe_shader_state pipe = p->pipe;
const ubyte type = p->type;
- if (p->res)
- nouveau_resource_free(&p->res);
+ if (p->mem)
+ nouveau_heap_free(&p->mem);
if (p->code)
FREE(p->code);
diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h
index 993e1691ab7..17aee97a024 100644
--- a/src/gallium/drivers/nv50/nv50_program.h
+++ b/src/gallium/drivers/nv50/nv50_program.h
@@ -87,7 +87,7 @@ struct nv50_program {
void *fixups;
unsigned num_fixups;
- struct nouveau_resource *res;
+ struct nouveau_heap *mem;
};
#define NV50_INTERP_LINEAR (1 << 0)
diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c
index e8ad1ddd38a..04e32b7e8b9 100644
--- a/src/gallium/drivers/nv50/nv50_push.c
+++ b/src/gallium/drivers/nv50/nv50_push.c
@@ -11,7 +11,7 @@
#include "nv50_3d.xml.h"
struct push_context {
- struct nouveau_channel *chan;
+ struct nouveau_pushbuf *push;
void *idxbuf;
@@ -74,20 +74,20 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
size = ctx->vertex_words * nr;
- BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+ BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
- ctx->chan->cur);
+ ctx->push->cur);
- ctx->chan->cur += size;
+ ctx->push->cur += size;
count -= nr;
elts += nr;
if (nr != push) {
count--;
elts++;
- BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
- OUT_RING (ctx->chan, ctx->restart_index);
+ BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
+ PUSH_DATA (ctx->push, ctx->restart_index);
}
}
}
@@ -107,20 +107,20 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
size = ctx->vertex_words * nr;
- BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+ BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
- ctx->chan->cur);
+ ctx->push->cur);
- ctx->chan->cur += size;
+ ctx->push->cur += size;
count -= nr;
elts += nr;
if (nr != push) {
count--;
elts++;
- BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
- OUT_RING (ctx->chan, ctx->restart_index);
+ BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
+ PUSH_DATA (ctx->push, ctx->restart_index);
}
}
}
@@ -140,20 +140,20 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
size = ctx->vertex_words * nr;
- BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+ BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
- ctx->chan->cur);
+ ctx->push->cur);
- ctx->chan->cur += size;
+ ctx->push->cur += size;
count -= nr;
elts += nr;
if (nr != push) {
count--;
elts++;
- BEGIN_RING(ctx->chan, RING_3D(VB_ELEMENT_U32), 1);
- OUT_RING (ctx->chan, ctx->restart_index);
+ BEGIN_NV04(ctx->push, NV50_3D(VB_ELEMENT_U32), 1);
+ PUSH_DATA (ctx->push, ctx->restart_index);
}
}
}
@@ -165,11 +165,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
unsigned push = MIN2(count, ctx->packet_vertex_limit);
unsigned size = ctx->vertex_words * push;
- BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+ BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run(ctx->translate, start, push, ctx->instance_id,
- ctx->chan->cur);
- ctx->chan->cur += size;
+ ctx->push->cur);
+ ctx->push->cur += size;
count -= push;
start += push;
}
@@ -213,7 +213,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
unsigned inst = info->instance_count;
boolean apply_bias = info->indexed && info->index_bias;
- ctx.chan = nv50->screen->base.channel;
+ ctx.push = nv50->base.pushbuf;
ctx.translate = nv50->vertex->translate;
ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit;
ctx.vertex_words = nv50->vertex->vertex_size;
@@ -252,19 +252,19 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
ctx.prim = nv50_prim_gl(info->mode);
if (info->primitive_restart) {
- BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 2);
- OUT_RING (ctx.chan, 1);
- OUT_RING (ctx.chan, info->restart_index);
+ BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 2);
+ PUSH_DATA (ctx.push, 1);
+ PUSH_DATA (ctx.push, info->restart_index);
} else
if (nv50->state.prim_restart) {
- BEGIN_RING(ctx.chan, RING_3D(PRIM_RESTART_ENABLE), 1);
- OUT_RING (ctx.chan, 0);
+ BEGIN_NV04(ctx.push, NV50_3D(PRIM_RESTART_ENABLE), 1);
+ PUSH_DATA (ctx.push, 0);
}
nv50->state.prim_restart = info->primitive_restart;
while (inst--) {
- BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (ctx.chan, ctx.prim);
+ BEGIN_NV04(ctx.push, NV50_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (ctx.push, ctx.prim);
switch (index_size) {
case 0:
emit_vertices_seq(&ctx, info->start, info->count);
@@ -282,8 +282,8 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
assert(0);
break;
}
- BEGIN_RING(ctx.chan, RING_3D(VERTEX_END_GL), 1);
- OUT_RING (ctx.chan, 0);
+ BEGIN_NV04(ctx.push, NV50_3D(VERTEX_END_GL), 1);
+ PUSH_DATA (ctx.push, 0);
ctx.instance_id++;
ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 59d315aa475..220b166f985 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -22,6 +22,8 @@
* Authors: Christoph Bumiller
*/
+#define NV50_PUSH_EXPLICIT_SPACE_CHECKING
+
#include "nv50_context.h"
#include "nouveau/nv_object.xml.h"
@@ -64,7 +66,8 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
if (q->ready)
nouveau_mm_free(q->mm);
else
- nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, q->mm);
+ nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work,
+ q->mm);
}
}
if (size) {
@@ -73,14 +76,12 @@ nv50_query_allocate(struct nv50_context *nv50, struct nv50_query *q, int size)
return FALSE;
q->offset = q->base;
- ret = nouveau_bo_map_range(q->bo, q->base, size, NOUVEAU_BO_RD |
- NOUVEAU_BO_NOSYNC);
+ ret = nouveau_bo_map(q->bo, 0, screen->base.client);
if (ret) {
nv50_query_allocate(nv50, q, 0);
return FALSE;
}
- q->data = q->bo->map;
- nouveau_bo_unmap(q->bo);
+ q->data = (uint32_t *)((uint8_t *)q->bo->map + q->base);
}
return TRUE;
}
@@ -121,24 +122,25 @@ nv50_query_create(struct pipe_context *pipe, unsigned type)
}
static void
-nv50_query_get(struct nouveau_channel *chan, struct nv50_query *q,
+nv50_query_get(struct nouveau_pushbuf *push, struct nv50_query *q,
unsigned offset, uint32_t get)
{
offset += q->offset;
- MARK_RING (chan, 5, 2);
- BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
- OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
- OUT_RING (chan, q->sequence);
- OUT_RING (chan, get);
+ PUSH_SPACE(push, 5);
+ PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+ BEGIN_NV04(push, NV50_3D(QUERY_ADDRESS_HIGH), 4);
+ PUSH_DATAh(push, q->bo->offset + offset);
+ PUSH_DATA (push, q->bo->offset + offset);
+ PUSH_DATA (push, q->sequence);
+ PUSH_DATA (push, get);
}
static void
nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_query *q = nv50_query(pq);
/* For occlusion queries we have to change the storage, because a previous
@@ -161,27 +163,31 @@ nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
- BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
- OUT_RING (chan, NV50_3D_COUNTER_RESET_SAMPLECNT);
- BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
- OUT_RING (chan, 1);
+ PUSH_SPACE(push, 4);
+ BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
+ PUSH_DATA (push, NV50_3D_COUNTER_RESET_SAMPLECNT);
+ BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
+ PUSH_DATA (push, 1);
break;
case PIPE_QUERY_PRIMITIVES_GENERATED: /* store before & after instead ? */
- BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
- OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
+ PUSH_SPACE(push, 2);
+ BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
+ PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
break;
case PIPE_QUERY_PRIMITIVES_EMITTED:
- BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
- OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
+ PUSH_SPACE(push, 2);
+ BEGIN_NV04(push, NV50_3D(COUNTER_RESET), 1);
+ PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
break;
case PIPE_QUERY_SO_STATISTICS:
- BEGIN_RING_NI(chan, RING_3D(COUNTER_RESET), 2);
- OUT_RING (chan, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
- OUT_RING (chan, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
+ PUSH_SPACE(push, 3);
+ BEGIN_NI04(push, NV50_3D(COUNTER_RESET), 2);
+ PUSH_DATA (push, NV50_3D_COUNTER_RESET_TRANSFORM_FEEDBACK);
+ PUSH_DATA (push, NV50_3D_COUNTER_RESET_GENERATED_PRIMITIVES);
break;
case PIPE_QUERY_TIMESTAMP_DISJOINT:
case PIPE_QUERY_TIME_ELAPSED:
- nv50_query_get(chan, q, 0x10, 0x00005002);
+ nv50_query_get(push, q, 0x10, 0x00005002);
break;
default:
break;
@@ -193,31 +199,32 @@ static void
nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_query *q = nv50_query(pq);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
- nv50_query_get(chan, q, 0, 0x0100f002);
- BEGIN_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
- OUT_RING (chan, 0);
+ nv50_query_get(push, q, 0, 0x0100f002);
+ PUSH_SPACE(push, 2);
+ BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
+ PUSH_DATA (push, 0);
break;
case PIPE_QUERY_PRIMITIVES_GENERATED:
- nv50_query_get(chan, q, 0, 0x06805002);
+ nv50_query_get(push, q, 0, 0x06805002);
break;
case PIPE_QUERY_PRIMITIVES_EMITTED:
- nv50_query_get(chan, q, 0, 0x05805002);
+ nv50_query_get(push, q, 0, 0x05805002);
break;
case PIPE_QUERY_SO_STATISTICS:
- nv50_query_get(chan, q, 0x00, 0x05805002);
- nv50_query_get(chan, q, 0x10, 0x06805002);
+ nv50_query_get(push, q, 0x00, 0x05805002);
+ nv50_query_get(push, q, 0x10, 0x06805002);
break;
case PIPE_QUERY_TIMESTAMP_DISJOINT:
case PIPE_QUERY_TIME_ELAPSED:
- nv50_query_get(chan, q, 0, 0x00005002);
+ nv50_query_get(push, q, 0, 0x00005002);
break;
case PIPE_QUERY_GPU_FINISHED:
- nv50_query_get(chan, q, 0, 0x1000f010);
+ nv50_query_get(push, q, 0, 0x1000f010);
break;
default:
assert(0);
@@ -231,45 +238,33 @@ nv50_query_ready(struct nv50_query *q)
return q->ready || (!q->is64bit && (q->data[0] == q->sequence));
}
-static INLINE boolean
-nv50_query_wait(struct nv50_query *q)
-{
- int ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
- if (ret)
- return FALSE;
- nouveau_bo_unmap(q->bo);
- return TRUE;
-}
-
static boolean
nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
boolean wait, union pipe_query_result *result)
{
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_query *q = nv50_query(pq);
- uint64_t *res64 = (uint64_t*)result;
- boolean *res8 = (boolean*)result;
+ uint64_t *res64 = (uint64_t *)result;
+ boolean *res8 = (boolean *)result;
uint64_t *data64 = (uint64_t *)q->data;
- if (q->type == PIPE_QUERY_GPU_FINISHED) {
- res8[0] = nv50_query_ready(q);
- return TRUE;
- }
-
if (!q->ready) /* update ? */
q->ready = nv50_query_ready(q);
if (!q->ready) {
- struct nouveau_channel *chan = nv50_context(pipe)->screen->base.channel;
if (!wait) {
- if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */
- FIRE_RING(chan);
+ /* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
+ PUSH_KICK(nv50->base.pushbuf);
return FALSE;
}
- if (!nv50_query_wait(q))
+ if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
return FALSE;
}
q->ready = TRUE;
switch (q->type) {
+ case PIPE_QUERY_GPU_FINISHED:
+ res8[0] = TRUE;
+ break;
case PIPE_QUERY_OCCLUSION_COUNTER: /* u32 sequence, u32 count, u64 time */
res64[0] = q->data[1];
break;
@@ -300,27 +295,28 @@ nv50_render_condition(struct pipe_context *pipe,
struct pipe_query *pq, uint mode)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_query *q;
+ PUSH_SPACE(push, 6);
+
if (!pq) {
- BEGIN_RING(chan, RING_3D(COND_MODE), 1);
- OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS);
+ BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
+ PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
return;
}
q = nv50_query(pq);
if (mode == PIPE_RENDER_COND_WAIT ||
mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
- BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+ PUSH_DATA (push, 0);
}
- MARK_RING (chan, 4, 2);
- BEGIN_RING(chan, RING_3D(COND_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, q->bo, q->offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
- OUT_RING (chan, NV50_3D_COND_MODE_RES_NON_ZERO);
+ BEGIN_NV04(push, NV50_3D(COND_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, q->bo->offset + q->offset);
+ PUSH_DATA (push, q->bo->offset + q->offset);
+ PUSH_DATA (push, NV50_3D_COND_MODE_RES_NON_ZERO);
}
void
diff --git a/src/gallium/drivers/nv50/nv50_resource.h b/src/gallium/drivers/nv50/nv50_resource.h
index 50cc2afdbe1..5d5596ea6e3 100644
--- a/src/gallium/drivers/nv50/nv50_resource.h
+++ b/src/gallium/drivers/nv50/nv50_resource.h
@@ -4,10 +4,9 @@
#include "util/u_transfer.h"
#include "util/u_double_list.h"
-#define NOUVEAU_NVC0
+
#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_buffer.h"
-#undef NOUVEAU_NVC0
#ifndef __NVC0_RESOURCE_H__ /* make sure we don't use these in nvc0: */
@@ -19,12 +18,12 @@ nv50_screen_init_resource_functions(struct pipe_screen *pscreen);
#define NV50_TILE_SHIFT_X(m) 6
-#define NV50_TILE_SHIFT_Y(m) ((((m) >> 0) & 0xf) + 2)
-#define NV50_TILE_SHIFT_Z(m) ((((m) >> 4) & 0xf) + 0)
+#define NV50_TILE_SHIFT_Y(m) ((((m) >> 4) & 0xf) + 2)
+#define NV50_TILE_SHIFT_Z(m) ((((m) >> 8) & 0xf) + 0)
#define NV50_TILE_SIZE_X(m) 64
-#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 0) & 0xf))
-#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 4) & 0xf))
+#define NV50_TILE_SIZE_Y(m) ( 4 << (((m) >> 4) & 0xf))
+#define NV50_TILE_SIZE_Z(m) ( 1 << (((m) >> 8) & 0xf))
#define NV50_TILE_SIZE_2D(m) (NV50_TILE_SIZE_X(m) << NV50_TILE_SHIFT_Y(m))
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 27566e24108..8a3c552784f 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -33,9 +33,6 @@
# define NOUVEAU_GETPARAM_GRAPH_UNITS 13
#endif
-extern int nouveau_device_get_param(struct nouveau_device *dev,
- uint64_t param, uint64_t *value);
-
static boolean
nv50_screen_is_format_supported(struct pipe_screen *pscreen,
enum pipe_format format,
@@ -53,7 +50,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
- if (nv50_screen(pscreen)->tesla->grclass < NVA0_3D)
+ if (nv50_screen(pscreen)->tesla->oclass < NVA0_3D_CLASS)
return FALSE;
break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
@@ -100,7 +97,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 1;
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
case PIPE_CAP_SEAMLESS_CUBE_MAP:
- return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D;
+ return nv50_screen(pscreen)->tesla->oclass >= NVA0_3D_CLASS;
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
return 0;
case PIPE_CAP_TWO_SIDED_STENCIL:
@@ -131,7 +128,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_INDEP_BLEND_ENABLE:
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
- return nv50_screen(pscreen)->tesla->grclass >= NVA3_3D;
+ return nv50_screen(pscreen)->tesla->oclass >= NVA3_3D_CLASS;
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
return 1;
@@ -241,8 +238,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
nouveau_fence_wait(screen->base.fence.current);
nouveau_fence_ref (NULL, &screen->base.fence.current);
}
- if (screen->base.channel)
- screen->base.channel->user_private = NULL;
+ if (screen->base.pushbuf)
+ screen->base.pushbuf->user_priv = NULL;
+
if (screen->blitctx)
FREE(screen->blitctx);
@@ -253,20 +251,17 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
nouveau_bo_ref(NULL, &screen->uniforms);
nouveau_bo_ref(NULL, &screen->fence.bo);
- nouveau_resource_destroy(&screen->vp_code_heap);
- nouveau_resource_destroy(&screen->gp_code_heap);
- nouveau_resource_destroy(&screen->fp_code_heap);
+ nouveau_heap_destroy(&screen->vp_code_heap);
+ nouveau_heap_destroy(&screen->gp_code_heap);
+ nouveau_heap_destroy(&screen->fp_code_heap);
if (screen->tic.entries)
FREE(screen->tic.entries);
- nouveau_mm_destroy(screen->mm_VRAM_fe0);
-
- nouveau_grobj_free(&screen->tesla);
- nouveau_grobj_free(&screen->eng2d);
- nouveau_grobj_free(&screen->m2mf);
-
- nouveau_notifier_free(&screen->sync);
+ nouveau_object_del(&screen->tesla);
+ nouveau_object_del(&screen->eng2d);
+ nouveau_object_del(&screen->m2mf);
+ nouveau_object_del(&screen->sync);
nouveau_screen_fini(&screen->base);
@@ -277,18 +272,16 @@ static void
nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
{
struct nv50_screen *screen = nv50_screen(pscreen);
- struct nouveau_channel *chan = screen->base.channel;
-
- MARK_RING (chan, 5, 2);
+ struct nouveau_pushbuf *push = screen->base.pushbuf;
/* we need to do it after possible flush in MARK_RING */
*sequence = ++screen->base.fence.sequence;
- BEGIN_RING(chan, RING_3D(QUERY_ADDRESS_HIGH), 4);
- OUT_RELOCh(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
- OUT_RELOCl(chan, screen->fence.bo, 0, NOUVEAU_BO_WR);
- OUT_RING (chan, *sequence);
- OUT_RING (chan, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
+ PUSH_DATA (push, NV50_FIFO_PKHDR(NV50_3D(QUERY_ADDRESS_HIGH), 4));
+ PUSH_DATAh(push, screen->fence.bo->offset);
+ PUSH_DATA (push, screen->fence.bo->offset);
+ PUSH_DATA (push, *sequence);
+ PUSH_DATA (push, NV50_3D_QUERY_GET_MODE_WRITE_UNK0 |
NV50_3D_QUERY_GET_UNK4 |
NV50_3D_QUERY_GET_UNIT_CROP |
NV50_3D_QUERY_GET_TYPE_QUERY |
@@ -299,8 +292,205 @@ nv50_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
static u32
nv50_screen_fence_update(struct pipe_screen *pscreen)
{
- struct nv50_screen *screen = nv50_screen(pscreen);
- return screen->fence.map[0];
+ return nv50_screen(pscreen)->fence.map[0];
+}
+
+static int
+nv50_screen_init_hwctx(struct nv50_screen *screen, unsigned tls_space)
+{
+ struct nouveau_pushbuf *push = screen->base.pushbuf;
+ struct nv04_fifo *fifo;
+ unsigned i;
+
+ fifo = (struct nv04_fifo *)screen->base.channel->data;
+
+ BEGIN_NV04(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->m2mf->handle);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_DMA_NOTIFY), 3);
+ PUSH_DATA (push, screen->sync->handle);
+ PUSH_DATA (push, fifo->vram);
+ PUSH_DATA (push, fifo->vram);
+
+ BEGIN_NV04(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->eng2d->handle);
+ BEGIN_NV04(push, NV50_2D(DMA_NOTIFY), 4);
+ PUSH_DATA (push, screen->sync->handle);
+ PUSH_DATA (push, fifo->vram);
+ PUSH_DATA (push, fifo->vram);
+ PUSH_DATA (push, fifo->vram);
+ BEGIN_NV04(push, NV50_2D(OPERATION), 1);
+ PUSH_DATA (push, NV50_2D_OPERATION_SRCCOPY);
+ BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, SUBC_2D(0x0888), 1);
+ PUSH_DATA (push, 1);
+
+ BEGIN_NV04(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->tesla->handle);
+
+ BEGIN_NV04(push, NV50_3D(COND_MODE), 1);
+ PUSH_DATA (push, NV50_3D_COND_MODE_ALWAYS);
+
+ BEGIN_NV04(push, NV50_3D(DMA_NOTIFY), 1);
+ PUSH_DATA (push, screen->sync->handle);
+ BEGIN_NV04(push, NV50_3D(DMA_ZETA), 11);
+ for (i = 0; i < 11; ++i)
+ PUSH_DATA(push, fifo->vram);
+ BEGIN_NV04(push, NV50_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
+ for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
+ PUSH_DATA(push, fifo->vram);
+
+ BEGIN_NV04(push, NV50_3D(REG_MODE), 1);
+ PUSH_DATA (push, NV50_3D_REG_MODE_STRIPED);
+ BEGIN_NV04(push, NV50_3D(UNK1400_LANES), 1);
+ PUSH_DATA (push, 0xf);
+
+ BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, 1);
+
+ BEGIN_NV04(push, NV50_3D(CSAA_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+ PUSH_DATA (push, NV50_3D_MULTISAMPLE_MODE_MS1);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_CTRL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(LINE_LAST_PIXEL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(BLEND_SEPARATE_ALPHA), 1);
+ PUSH_DATA (push, 1);
+
+ if (screen->tesla->oclass >= NVA0_3D_CLASS) {
+ BEGIN_NV04(push, SUBC_3D(NVA0_3D_TEX_MISC), 1);
+ PUSH_DATA (push, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
+ }
+
+ BEGIN_NV04(push, NV50_3D(SCREEN_Y_CONTROL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(WINDOW_OFFSET_X), 2);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(ZCULL_REGION), 1);
+ PUSH_DATA (push, 0x3f);
+
+ BEGIN_NV04(push, NV50_3D(VP_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
+ PUSH_DATA (push, screen->code->offset + (0 << NV50_CODE_BO_SIZE_LOG2));
+
+ BEGIN_NV04(push, NV50_3D(FP_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
+ PUSH_DATA (push, screen->code->offset + (1 << NV50_CODE_BO_SIZE_LOG2));
+
+ BEGIN_NV04(push, NV50_3D(GP_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
+ PUSH_DATA (push, screen->code->offset + (2 << NV50_CODE_BO_SIZE_LOG2));
+
+ BEGIN_NV04(push, NV50_3D(LOCAL_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->tls_bo->offset);
+ PUSH_DATA (push, screen->tls_bo->offset);
+ PUSH_DATA (push, util_logbase2(tls_space / 8));
+
+ BEGIN_NV04(push, NV50_3D(STACK_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->stack_bo->offset);
+ PUSH_DATA (push, screen->stack_bo->offset);
+ PUSH_DATA (push, 4);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (0 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (0 << 16));
+ PUSH_DATA (push, (NV50_CB_PVP << 16) | 0x0000);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (1 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (1 << 16));
+ PUSH_DATA (push, (NV50_CB_PGP << 16) | 0x0000);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (2 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (2 << 16));
+ PUSH_DATA (push, (NV50_CB_PFP << 16) | 0x0000);
+
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->uniforms->offset + (3 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (3 << 16));
+ PUSH_DATA (push, (NV50_CB_AUX << 16) | 0x0200);
+
+ BEGIN_NI04(push, NV50_3D(SET_PROGRAM_CB), 6);
+ PUSH_DATA (push, (NV50_CB_PVP << 12) | 0x001);
+ PUSH_DATA (push, (NV50_CB_PGP << 12) | 0x021);
+ PUSH_DATA (push, (NV50_CB_PFP << 12) | 0x031);
+ PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf01);
+ PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf21);
+ PUSH_DATA (push, (NV50_CB_AUX << 12) | 0xf31);
+
+ /* max TIC (bits 4:8) & TSC bindings, per program type */
+ for (i = 0; i < 3; ++i) {
+ BEGIN_NV04(push, NV50_3D(TEX_LIMITS(i)), 1);
+ PUSH_DATA (push, 0x54);
+ }
+
+ BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->txc->offset);
+ PUSH_DATA (push, screen->txc->offset);
+ PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);
+
+ BEGIN_NV04(push, NV50_3D(TSC_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->txc->offset + 65536);
+ PUSH_DATA (push, screen->txc->offset + 65536);
+ PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);
+
+ BEGIN_NV04(push, NV50_3D(LINKED_TSC), 1);
+ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV50_3D(CLIP_RECTS_EN), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(CLIP_RECTS_MODE), 1);
+ PUSH_DATA (push, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
+ BEGIN_NV04(push, NV50_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
+ for (i = 0; i < 8 * 2; ++i)
+ PUSH_DATA(push, 0);
+ BEGIN_NV04(push, NV50_3D(CLIPID_ENABLE), 1);
+ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 1.0f);
+
+ BEGIN_NV04(push, NV50_3D(VIEW_VOLUME_CLIP_CTRL), 1);
+#ifdef NV50_SCISSORS_CLIPPING
+ PUSH_DATA (push, 0x0000);
+#else
+ PUSH_DATA (push, 0x1080);
+#endif
+
+ BEGIN_NV04(push, NV50_3D(CLEAR_FLAGS), 1);
+ PUSH_DATA (push, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
+
+ /* We use scissors instead of exact view volume clipping,
+ * so they're always enabled.
+ */
+ BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 3);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 8192 << 16);
+ PUSH_DATA (push, 8192 << 16);
+
+ BEGIN_NV04(push, NV50_3D(RASTERIZE_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_3D(POINT_RASTER_RULES), 1);
+ PUSH_DATA (push, NV50_3D_POINT_RASTER_RULES_OGL);
+ BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
+ PUSH_DATA (push, 0x11111111);
+ BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
+ PUSH_DATA (push, 1);
+
+ PUSH_KICK (push);
+
+ return 0;
}
#define FAIL_SCREEN_INIT(str, err) \
@@ -314,13 +504,12 @@ struct pipe_screen *
nv50_screen_create(struct nouveau_device *dev)
{
struct nv50_screen *screen;
- struct nouveau_channel *chan;
struct pipe_screen *pscreen;
+ struct nouveau_object *chan;
uint64_t value;
uint32_t tesla_class;
unsigned stack_size, max_warps, tls_space;
int ret;
- unsigned i, base;
screen = CALLOC_STRUCT(nv50_screen);
if (!screen)
@@ -333,8 +522,10 @@ nv50_screen_create(struct nouveau_device *dev)
if (ret)
FAIL_SCREEN_INIT("nouveau_screen_init failed: %d\n", ret);
+ screen->base.pushbuf->user_priv = screen;
+ screen->base.pushbuf->rsvd_kick = 5;
+
chan = screen->base.channel;
- chan->user_private = screen;
pscreen->destroy = nv50_screen_destroy;
pscreen->context_create = nv50_create;
@@ -348,68 +539,52 @@ nv50_screen_create(struct nouveau_device *dev)
nouveau_screen_init_vdec(&screen->base);
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096,
- &screen->fence.bo);
+ NULL, &screen->fence.bo);
if (ret)
goto fail;
- nouveau_bo_map(screen->fence.bo, NOUVEAU_BO_RDWR);
+ nouveau_bo_map(screen->fence.bo, 0, NULL);
screen->fence.map = screen->fence.bo->map;
- nouveau_bo_unmap(screen->fence.bo);
screen->base.fence.emit = nv50_screen_fence_emit;
screen->base.fence.update = nv50_screen_fence_update;
- ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
+ ret = nouveau_object_new(chan, 0xbeef0301, NOUVEAU_NOTIFIER_CLASS,
+ &(struct nv04_notify){ .length = 32 },
+ sizeof(struct nv04_notify), &screen->sync);
if (ret)
FAIL_SCREEN_INIT("Error allocating notifier: %d\n", ret);
- ret = nouveau_grobj_alloc(chan, 0xbeef5039, NV50_M2MF, &screen->m2mf);
+
+ ret = nouveau_object_new(chan, 0xbeef5039, NV50_M2MF_CLASS,
+ NULL, 0, &screen->m2mf);
if (ret)
FAIL_SCREEN_INIT("Error allocating PGRAPH context for M2MF: %d\n", ret);
- BIND_RING (chan, screen->m2mf, NV50_SUBCH_MF);
- BEGIN_RING(chan, RING_MF_(NV04_M2MF_DMA_NOTIFY), 3);
- OUT_RING (chan, screen->sync->handle);
- OUT_RING (chan, chan->vram->handle);
- OUT_RING (chan, chan->vram->handle);
- ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
+ ret = nouveau_object_new(chan, 0xbeef502d, NV50_2D_CLASS,
+ NULL, 0, &screen->eng2d);
if (ret)
FAIL_SCREEN_INIT("Error allocating PGRAPH context for 2D: %d\n", ret);
- BIND_RING (chan, screen->eng2d, NV50_SUBCH_2D);
- BEGIN_RING(chan, RING_2D(DMA_NOTIFY), 4);
- OUT_RING (chan, screen->sync->handle);
- OUT_RING (chan, chan->vram->handle);
- OUT_RING (chan, chan->vram->handle);
- OUT_RING (chan, chan->vram->handle);
- BEGIN_RING(chan, RING_2D(OPERATION), 1);
- OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
- BEGIN_RING(chan, RING_2D(CLIP_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_2D(COLOR_KEY_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_2D_(0x0888), 1);
- OUT_RING (chan, 1);
-
switch (dev->chipset & 0xf0) {
case 0x50:
- tesla_class = NV50_3D;
+ tesla_class = NV50_3D_CLASS;
break;
case 0x80:
case 0x90:
- tesla_class = NV84_3D;
+ tesla_class = NV84_3D_CLASS;
break;
case 0xa0:
switch (dev->chipset) {
case 0xa0:
case 0xaa:
case 0xac:
- tesla_class = NVA0_3D;
+ tesla_class = NVA0_3D_CLASS;
break;
case 0xaf:
- tesla_class = NVAF_3D;
+ tesla_class = NVAF_3D_CLASS;
break;
default:
- tesla_class = NVA3_3D;
+ tesla_class = NVA3_3D_CLASS;
break;
}
break;
@@ -418,98 +593,33 @@ nv50_screen_create(struct nouveau_device *dev)
break;
}
- ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla);
+ ret = nouveau_object_new(chan, 0xbeef5097, tesla_class,
+ NULL, 0, &screen->tesla);
if (ret)
FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
- BIND_RING (chan, screen->tesla, NV50_SUBCH_3D);
-
- BEGIN_RING(chan, RING_3D(COND_MODE), 1);
- OUT_RING (chan, NV50_3D_COND_MODE_ALWAYS);
-
- BEGIN_RING(chan, RING_3D(DMA_NOTIFY), 1);
- OUT_RING (chan, screen->sync->handle);
- BEGIN_RING(chan, RING_3D(DMA_ZETA), 11);
- for (i = 0; i < 11; ++i)
- OUT_RING(chan, chan->vram->handle);
- BEGIN_RING(chan, RING_3D(DMA_COLOR(0)), NV50_3D_DMA_COLOR__LEN);
- for (i = 0; i < NV50_3D_DMA_COLOR__LEN; ++i)
- OUT_RING(chan, chan->vram->handle);
-
- BEGIN_RING(chan, RING_3D(REG_MODE), 1);
- OUT_RING (chan, NV50_3D_REG_MODE_STRIPED);
- BEGIN_RING(chan, RING_3D(UNK1400_LANES), 1);
- OUT_RING (chan, 0xf);
-
- BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
- OUT_RING (chan, 1);
-
- BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
- OUT_RING (chan, NV50_3D_MULTISAMPLE_MODE_MS1);
- BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(LINE_LAST_PIXEL), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1);
- OUT_RING (chan, 1);
-
- if (tesla_class >= NVA0_3D) {
- BEGIN_RING(chan, RING_3D_(NVA0_3D_TEX_MISC), 1);
- OUT_RING (chan, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
- }
-
- BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2);
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
- OUT_RING (chan, 0x3f);
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16,
- 3 << NV50_CODE_BO_SIZE_LOG2, &screen->code);
+ 3 << NV50_CODE_BO_SIZE_LOG2, NULL, &screen->code);
if (ret)
goto fail;
- nouveau_resource_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
- nouveau_resource_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
- nouveau_resource_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
-
- base = 1 << NV50_CODE_BO_SIZE_LOG2;
-
- BEGIN_RING(chan, RING_3D(VP_ADDRESS_HIGH), 2);
- OUT_RELOCh(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->code, base * 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-
- BEGIN_RING(chan, RING_3D(FP_ADDRESS_HIGH), 2);
- OUT_RELOCh(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->code, base * 1, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
-
- BEGIN_RING(chan, RING_3D(GP_ADDRESS_HIGH), 2);
- OUT_RELOCh(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->code, base * 2, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ nouveau_heap_init(&screen->vp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
+ nouveau_heap_init(&screen->gp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
+ nouveau_heap_init(&screen->fp_code_heap, 0, 1 << NV50_CODE_BO_SIZE_LOG2);
- nouveau_device_get_param(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
+ nouveau_getparam(dev, NOUVEAU_GETPARAM_GRAPH_UNITS, &value);
max_warps = util_bitcount(value & 0xffff);
max_warps *= util_bitcount((value >> 24) & 0xf) * 32;
stack_size = max_warps * 64 * 8;
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, stack_size, NULL,
&screen->stack_bo);
if (ret)
FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
- BEGIN_RING(chan, RING_3D(STACK_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, screen->stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RING (chan, 4);
-
tls_space = NV50_CAP_MAX_PROGRAM_TEMPS * 16;
screen->tls_size = tls_space * max_warps * 32;
@@ -518,126 +628,32 @@ nv50_screen_create(struct nouveau_device *dev)
debug_printf("max_warps = %i, tls_size = %"PRIu64" KiB\n",
max_warps, screen->tls_size >> 10);
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, NULL,
&screen->tls_bo);
if (ret)
FAIL_SCREEN_INIT("Failed to allocate stack bo: %d\n", ret);
- BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, screen->tls_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RING (chan, util_logbase2(tls_space / 8));
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 4 << 16, NULL,
&screen->uniforms);
if (ret)
goto fail;
- BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->uniforms, 0 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RING (chan, (NV50_CB_PVP << 16) | 0x0000);
-
- BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->uniforms, 1 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RING (chan, (NV50_CB_PGP << 16) | 0x0000);
-
- BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->uniforms, 2 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RING (chan, (NV50_CB_PFP << 16) | 0x0000);
-
- BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->uniforms, 3 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RING (chan, (NV50_CB_AUX << 16) | 0x0200);
-
- BEGIN_RING_NI(chan, RING_3D(SET_PROGRAM_CB), 6);
- OUT_RING (chan, (NV50_CB_PVP << 12) | 0x001);
- OUT_RING (chan, (NV50_CB_PGP << 12) | 0x021);
- OUT_RING (chan, (NV50_CB_PFP << 12) | 0x031);
- OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf01);
- OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf21);
- OUT_RING (chan, (NV50_CB_AUX << 12) | 0xf31);
-
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, 3 << 16, NULL,
&screen->txc);
if (ret)
FAIL_SCREEN_INIT("Could not allocate TIC/TSC bo: %d\n", ret);
- /* max TIC (bits 4:8) & TSC bindings, per program type */
- for (i = 0; i < 3; ++i) {
- BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1);
- OUT_RING (chan, 0x54);
- }
-
- BEGIN_RING(chan, RING_3D(TIC_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RING (chan, NV50_TIC_MAX_ENTRIES - 1);
-
- BEGIN_RING(chan, RING_3D(TSC_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RING (chan, NV50_TSC_MAX_ENTRIES - 1);
-
- BEGIN_RING(chan, RING_3D(LINKED_TSC), 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1);
- OUT_RING (chan, NV50_3D_CLIP_RECTS_MODE_INSIDE_ANY);
- BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
- for (i = 0; i < 8 * 2; ++i)
- OUT_RING(chan, 0);
- BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1);
- OUT_RING (chan, 0);
-
- BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
- OUT_RINGf (chan, 0.0f);
- OUT_RINGf (chan, 1.0f);
-
- BEGIN_RING(chan, RING_3D(VIEW_VOLUME_CLIP_CTRL), 1);
-#ifdef NV50_SCISSORS_CLIPPING
- OUT_RING (chan, 0x0000);
-#else
- OUT_RING (chan, 0x1080);
-#endif
-
- BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1);
- OUT_RING (chan, NV50_3D_CLEAR_FLAGS_CLEAR_RECT_VIEWPORT);
-
- /* We use scissors instead of exact view volume clipping,
- * so they're always enabled.
- */
- BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 3);
- OUT_RING (chan, 1);
- OUT_RING (chan, 8192 << 16);
- OUT_RING (chan, 8192 << 16);
-
- BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1);
- OUT_RING (chan, NV50_3D_POINT_RASTER_RULES_OGL);
- BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
- OUT_RING (chan, 0x11111111);
- BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
- OUT_RING (chan, 1);
-
- FIRE_RING (chan);
-
screen->tic.entries = CALLOC(4096, sizeof(void *));
screen->tsc.entries = screen->tic.entries + 2048;
- screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, 0xfe0);
if (!nv50_blitctx_create(screen))
goto fail;
+ if (nv50_screen_init_hwctx(screen, tls_space))
+ goto fail;
+
nouveau_fence_new(&screen->base, &screen->base.fence.current, FALSE);
return pscreen;
@@ -647,21 +663,6 @@ fail:
return NULL;
}
-void
-nv50_screen_make_buffers_resident(struct nv50_screen *screen)
-{
- struct nouveau_channel *chan = screen->base.channel;
-
- const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-
- MARK_RING(chan, 0, 5);
- nouveau_bo_validate(chan, screen->code, flags);
- nouveau_bo_validate(chan, screen->uniforms, flags);
- nouveau_bo_validate(chan, screen->txc, flags);
- nouveau_bo_validate(chan, screen->tls_bo, flags);
- nouveau_bo_validate(chan, screen->stack_bo, flags);
-}
-
int
nv50_screen_tic_alloc(struct nv50_screen *screen, void *entry)
{
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index cb7e956cd84..b7803cfed80 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -1,11 +1,11 @@
#ifndef __NV50_SCREEN_H__
#define __NV50_SCREEN_H__
-#define NOUVEAU_NVC0
#include "nouveau/nouveau_screen.h"
#include "nouveau/nouveau_fence.h"
#include "nouveau/nouveau_mm.h"
-#undef NOUVEAU_NVC0
+#include "nouveau/nouveau_heap.h"
+
#include "nv50_winsys.h"
#include "nv50_stateobj.h"
@@ -36,9 +36,9 @@ struct nv50_screen {
uint64_t tls_size;
- struct nouveau_resource *vp_code_heap;
- struct nouveau_resource *gp_code_heap;
- struct nouveau_resource *fp_code_heap;
+ struct nouveau_heap *vp_code_heap;
+ struct nouveau_heap *gp_code_heap;
+ struct nouveau_heap *fp_code_heap;
struct nv50_blitctx *blitctx;
@@ -59,13 +59,11 @@ struct nv50_screen {
struct nouveau_bo *bo;
} fence;
- struct nouveau_notifier *sync;
-
- struct nouveau_mman *mm_VRAM_fe0;
+ struct nouveau_object *sync;
- struct nouveau_grobj *tesla;
- struct nouveau_grobj *eng2d;
- struct nouveau_grobj *m2mf;
+ struct nouveau_object *tesla;
+ struct nouveau_object *eng2d;
+ struct nouveau_object *m2mf;
};
static INLINE struct nv50_screen *
@@ -76,8 +74,6 @@ nv50_screen(struct pipe_screen *screen)
boolean nv50_blitctx_create(struct nv50_screen *);
-void nv50_screen_make_buffers_resident(struct nv50_screen *);
-
int nv50_screen_tic_alloc(struct nv50_screen *, void *);
int nv50_screen_tsc_alloc(struct nv50_screen *, void *);
@@ -88,7 +84,6 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
if (res->mm) {
nouveau_fence_ref(screen->base.fence.current, &res->fence);
-
if (flags & NOUVEAU_BO_WR)
nouveau_fence_ref(screen->base.fence.current, &res->fence_wr);
}
@@ -97,11 +92,7 @@ nv50_resource_fence(struct nv04_resource *res, uint32_t flags)
static INLINE void
nv50_resource_validate(struct nv04_resource *res, uint32_t flags)
{
- struct nv50_screen *screen = nv50_screen(res->base.screen);
-
if (likely(res->bo)) {
- nouveau_bo_validate(screen->base.channel, res->bo, flags);
-
if (flags & NOUVEAU_BO_WR)
res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
if (flags & NOUVEAU_BO_RD)
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c
index d3cdb697960..07d4e6bb0c5 100644
--- a/src/gallium/drivers/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nv50/nv50_shader_state.c
@@ -31,7 +31,7 @@
void
nv50_constbufs_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
unsigned s;
for (s = 0; s < 3; ++s) {
@@ -58,8 +58,8 @@ nv50_constbufs_validate(struct nv50_context *nv50)
res = nv04_resource(nv50->constbuf[s][i]);
if (!res) {
if (i != 0) {
- BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
- OUT_RING (chan, (i << 8) | p | 0);
+ BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+ PUSH_DATA (push, (i << 8) | p | 0);
}
continue;
}
@@ -78,43 +78,35 @@ nv50_constbufs_validate(struct nv50_context *nv50)
if (!nouveau_resource_mapped_by_gpu(&res->base)) {
nouveau_buffer_migrate(&nv50->base, res, NOUVEAU_BO_VRAM);
- BEGIN_RING(chan, RING_3D(CODE_CB_FLUSH), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(CODE_CB_FLUSH), 1);
+ PUSH_DATA (push, 0);
}
- MARK_RING (chan, 6, 2);
- BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
- OUT_RESRCh(chan, res, 0, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, res, 0, NOUVEAU_BO_RD);
- OUT_RING (chan, (b << 16) | (res->base.width0 & 0xffff));
- BEGIN_RING(chan, RING_3D(SET_PROGRAM_CB), 1);
- OUT_RING (chan, (b << 12) | (i << 8) | p | 1);
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, res->address);
+ PUSH_DATA (push, res->address);
+ PUSH_DATA (push, (b << 16) | (res->base.width0 & 0xffff));
+ BEGIN_NV04(push, NV50_3D(SET_PROGRAM_CB), 1);
+ PUSH_DATA (push, (b << 12) | (i << 8) | p | 1);
bo = res->bo;
-
- nv50_bufctx_add_resident(nv50, NV50_BUFCTX_CONSTANT, res,
- res->domain | NOUVEAU_BO_RD);
}
- if (words) {
- MARK_RING(chan, 8, 1);
-
- nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
- }
+ if (bo != nv50->screen->uniforms)
+ BCTX_REFN(nv50->bufctx_3d, CB(s, i), res, RD);
while (words) {
- unsigned nr = AVAIL_RING(chan);
+ unsigned nr;
- if (nr < 16) {
- FIRE_RING(chan);
- nouveau_bo_validate(chan, bo, res->domain | NOUVEAU_BO_WR);
- continue;
- }
+ if (!PUSH_SPACE(push, 16))
+ break;
+ nr = PUSH_AVAIL(push);
+ assert(nr >= 16);
nr = MIN2(MIN2(nr - 3, words), NV04_PFIFO_MAX_PACKET_LEN);
- BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
- OUT_RING (chan, (start << 8) | b);
- BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr);
- OUT_RINGp (chan, &res->data[start * 4], nr);
+ BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+ PUSH_DATA (push, (start << 8) | b);
+ BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
+ PUSH_DATAp(push, &res->data[start * 4], nr);
start += nr;
words -= nr;
@@ -126,7 +118,7 @@ nv50_constbufs_validate(struct nv50_context *nv50)
static boolean
nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
{
- struct nouveau_resource *heap;
+ struct nouveau_heap *heap;
int ret;
unsigned size;
@@ -135,7 +127,7 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
if (!prog->translated)
return FALSE;
} else
- if (prog->res)
+ if (prog->mem)
return TRUE;
if (prog->type == PIPE_SHADER_FRAGMENT) heap = nv50->screen->fp_code_heap;
@@ -146,12 +138,12 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
size = align(prog->code_size, 0x100);
- ret = nouveau_resource_alloc(heap, size, prog, &prog->res);
+ ret = nouveau_heap_alloc(heap, size, prog, &prog->mem);
if (ret) {
NOUVEAU_ERR("out of code space for shader type %i\n", prog->type);
return FALSE;
}
- prog->code_base = prog->res->start;
+ prog->code_base = prog->mem->start;
nv50_relocate_program(prog, prog->code_base, 0);
@@ -159,80 +151,99 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *prog)
(prog->type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base,
NOUVEAU_BO_VRAM, prog->code_size, prog->code);
- BEGIN_RING(nv50->screen->base.channel, RING_3D(CODE_CB_FLUSH), 1);
- OUT_RING (nv50->screen->base.channel, 0);
+ BEGIN_NV04(nv50->base.pushbuf, NV50_3D(CODE_CB_FLUSH), 1);
+ PUSH_DATA (nv50->base.pushbuf, 0);
return TRUE;
}
+static INLINE void
+nv50_program_update_context_state(struct nv50_context *nv50,
+ struct nv50_program *prog, int stage)
+{
+ const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
+
+ if (prog && prog->uses_lmem) {
+ if (!nv50->state.tls_required)
+ BCTX_REFN_bo(nv50->bufctx_3d, TLS, flags, nv50->screen->tls_bo);
+ nv50->state.tls_required |= 1 << stage;
+ } else {
+ if (nv50->state.tls_required == (1 << stage))
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TLS);
+ nv50->state.tls_required &= ~(1 << stage);
+ }
+}
+
void
nv50_vertprog_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_program *vp = nv50->vertprog;
if (!nv50_program_validate(nv50, vp))
return;
-
- BEGIN_RING(chan, RING_3D(VP_ATTR_EN(0)), 2);
- OUT_RING (chan, vp->vp.attrs[0]);
- OUT_RING (chan, vp->vp.attrs[1]);
- BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_RESULT), 1);
- OUT_RING (chan, vp->max_out);
- BEGIN_RING(chan, RING_3D(VP_REG_ALLOC_TEMP), 1);
- OUT_RING (chan, vp->max_gpr);
- BEGIN_RING(chan, RING_3D(VP_START_ID), 1);
- OUT_RING (chan, vp->code_base);
+ nv50_program_update_context_state(nv50, vp, 0);
+
+ BEGIN_NV04(push, NV50_3D(VP_ATTR_EN(0)), 2);
+ PUSH_DATA (push, vp->vp.attrs[0]);
+ PUSH_DATA (push, vp->vp.attrs[1]);
+ BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_RESULT), 1);
+ PUSH_DATA (push, vp->max_out);
+ BEGIN_NV04(push, NV50_3D(VP_REG_ALLOC_TEMP), 1);
+ PUSH_DATA (push, vp->max_gpr);
+ BEGIN_NV04(push, NV50_3D(VP_START_ID), 1);
+ PUSH_DATA (push, vp->code_base);
}
void
nv50_fragprog_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_program *fp = nv50->fragprog;
if (!nv50_program_validate(nv50, fp))
return;
-
- BEGIN_RING(chan, RING_3D(FP_REG_ALLOC_TEMP), 1);
- OUT_RING (chan, fp->max_gpr);
- BEGIN_RING(chan, RING_3D(FP_RESULT_COUNT), 1);
- OUT_RING (chan, fp->max_out);
- BEGIN_RING(chan, RING_3D(FP_CONTROL), 1);
- OUT_RING (chan, fp->fp.flags[0]);
- BEGIN_RING(chan, RING_3D(FP_CTRL_UNK196C), 1);
- OUT_RING (chan, fp->fp.flags[1]);
- BEGIN_RING(chan, RING_3D(FP_START_ID), 1);
- OUT_RING (chan, fp->code_base);
+ nv50_program_update_context_state(nv50, fp, 1);
+
+ BEGIN_NV04(push, NV50_3D(FP_REG_ALLOC_TEMP), 1);
+ PUSH_DATA (push, fp->max_gpr);
+ BEGIN_NV04(push, NV50_3D(FP_RESULT_COUNT), 1);
+ PUSH_DATA (push, fp->max_out);
+ BEGIN_NV04(push, NV50_3D(FP_CONTROL), 1);
+ PUSH_DATA (push, fp->fp.flags[0]);
+ BEGIN_NV04(push, NV50_3D(FP_CTRL_UNK196C), 1);
+ PUSH_DATA (push, fp->fp.flags[1]);
+ BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
+ PUSH_DATA (push, fp->code_base);
}
void
nv50_gmtyprog_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_program *gp = nv50->gmtyprog;
- if (!gp) /* GP_ENABLE is updated in linkage validation */
- return;
- if (!nv50_program_validate(nv50, gp))
- return;
+ if (gp) {
+ BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_TEMP), 1);
+ PUSH_DATA (push, gp->max_gpr);
+ BEGIN_NV04(push, NV50_3D(GP_REG_ALLOC_RESULT), 1);
+ PUSH_DATA (push, gp->max_out);
+ BEGIN_NV04(push, NV50_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1);
+ PUSH_DATA (push, gp->gp.prim_type);
+ BEGIN_NV04(push, NV50_3D(GP_VERTEX_OUTPUT_COUNT), 1);
+ PUSH_DATA (push, gp->gp.vert_count);
+ BEGIN_NV04(push, NV50_3D(GP_START_ID), 1);
+ PUSH_DATA (push, gp->code_base);
+ }
+ nv50_program_update_context_state(nv50, gp, 2);
- BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_TEMP), 1);
- OUT_RING (chan, gp->max_gpr);
- BEGIN_RING(chan, RING_3D(GP_REG_ALLOC_RESULT), 1);
- OUT_RING (chan, gp->max_out);
- BEGIN_RING(chan, RING_3D(GP_OUTPUT_PRIMITIVE_TYPE), 1);
- OUT_RING (chan, gp->gp.prim_type);
- BEGIN_RING(chan, RING_3D(GP_VERTEX_OUTPUT_COUNT), 1);
- OUT_RING (chan, gp->gp.vert_count);
- BEGIN_RING(chan, RING_3D(GP_START_ID), 1);
- OUT_RING (chan, gp->code_base);
+ /* GP_ENABLE is updated in linkage validation */
}
static void
nv50_sprite_coords_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
uint32_t pntc[8], mode;
struct nv50_program *fp = nv50->fragprog;
unsigned i, c;
@@ -240,9 +251,9 @@ nv50_sprite_coords_validate(struct nv50_context *nv50)
if (!nv50->rast->pipe.point_quad_rasterization) {
if (nv50->state.point_sprite) {
- BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
+ BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8);
for (i = 0; i < 8; ++i)
- OUT_RING(chan, 0);
+ PUSH_DATA(push, 0);
nv50->state.point_sprite = FALSE;
}
@@ -278,43 +289,43 @@ nv50_sprite_coords_validate(struct nv50_context *nv50)
else
mode = 0x10;
- BEGIN_RING(chan, RING_3D(POINT_SPRITE_CTRL), 1);
- OUT_RING (chan, mode);
+ BEGIN_NV04(push, NV50_3D(POINT_SPRITE_CTRL), 1);
+ PUSH_DATA (push, mode);
- BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE_MAP(0)), 8);
- OUT_RINGp (chan, pntc, 8);
+ BEGIN_NV04(push, NV50_3D(POINT_COORD_REPLACE_MAP(0)), 8);
+ PUSH_DATAp(push, pntc, 8);
}
/* Validate state derived from shaders and the rasterizer cso. */
void
nv50_validate_derived_rs(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
uint32_t color, psize;
nv50_sprite_coords_validate(nv50);
if (nv50->dirty & NV50_NEW_FRAGPROG)
return;
- psize = nv50->state.semantic_psize & ~NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
- color = nv50->state.semantic_color & ~NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+ psize = nv50->state.semantic_psize & ~NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK;
+ color = nv50->state.semantic_color & ~NV50_3D_SEMANTIC_COLOR_CLMP_EN;
if (nv50->rast->pipe.clamp_vertex_color)
- color |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+ color |= NV50_3D_SEMANTIC_COLOR_CLMP_EN;
if (color != nv50->state.semantic_color) {
nv50->state.semantic_color = color;
- BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 1);
- OUT_RING (chan, color);
+ BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 1);
+ PUSH_DATA (push, color);
}
if (nv50->rast->pipe.point_size_per_vertex)
- psize |= NV50_3D_MAP_SEMANTIC_3_PTSZ_EN__MASK;
+ psize |= NV50_3D_SEMANTIC_PTSZ_PTSZ_EN__MASK;
if (psize != nv50->state.semantic_psize) {
nv50->state.semantic_psize = psize;
- BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_3), 1);
- OUT_RING (chan, psize);
+ BEGIN_NV04(push, NV50_3D(SEMANTIC_PTSZ), 1);
+ PUSH_DATA (push, psize);
}
}
@@ -348,7 +359,7 @@ nv50_vec4_map(uint8_t *map, int mid, uint32_t lin[4],
void
nv50_fp_linkage_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_program *vp = nv50->gmtyprog ? nv50->gmtyprog : nv50->vertprog;
struct nv50_program *fp = nv50->fragprog;
struct nv50_varying dummy;
@@ -409,48 +420,48 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
}
if (nv50->rast->pipe.clamp_vertex_color)
- colors |= NV50_3D_MAP_SEMANTIC_0_CLMP_EN;
+ colors |= NV50_3D_SEMANTIC_COLOR_CLMP_EN;
n = (m + 3) / 4;
assert(m <= 64);
if (unlikely(nv50->gmtyprog)) {
- BEGIN_RING(chan, RING_3D(GP_RESULT_MAP_SIZE), 1);
- OUT_RING (chan, m);
- BEGIN_RING(chan, RING_3D(GP_RESULT_MAP(0)), n);
- OUT_RINGp (chan, map, n);
+ BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP_SIZE), 1);
+ PUSH_DATA (push, m);
+ BEGIN_NV04(push, NV50_3D(GP_RESULT_MAP(0)), n);
+ PUSH_DATAp(push, map, n);
} else {
- BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
- OUT_RING (chan, vp->vp.attrs[2]);
+ BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
+ PUSH_DATA (push, vp->vp.attrs[2]);
- BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_4), 1);
- OUT_RING (chan, primid);
+ BEGIN_NV04(push, NV50_3D(SEMANTIC_PRIM_ID), 1);
+ PUSH_DATA (push, primid);
- BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
- OUT_RING (chan, m);
- BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
- OUT_RINGp (chan, map, n);
+ BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
+ PUSH_DATA (push, m);
+ BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);
+ PUSH_DATAp(push, map, n);
}
- BEGIN_RING(chan, RING_3D(MAP_SEMANTIC_0), 4);
- OUT_RING (chan, colors);
- OUT_RING (chan, (vp->vp.clpd_nr << 8) | 4);
- OUT_RING (chan, 0);
- OUT_RING (chan, psiz);
+ BEGIN_NV04(push, NV50_3D(SEMANTIC_COLOR), 4);
+ PUSH_DATA (push, colors);
+ PUSH_DATA (push, (vp->vp.clpd_nr << 8) | 4);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, psiz);
- BEGIN_RING(chan, RING_3D(FP_INTERPOLANT_CTRL), 1);
- OUT_RING (chan, interp);
+ BEGIN_NV04(push, NV50_3D(FP_INTERPOLANT_CTRL), 1);
+ PUSH_DATA (push, interp);
nv50->state.interpolant_ctrl = interp;
nv50->state.semantic_color = colors;
nv50->state.semantic_psize = psiz;
- BEGIN_RING(chan, RING_3D(NOPERSPECTIVE_BITMAP(0)), 4);
- OUT_RINGp (chan, lin, 4);
+ BEGIN_NV04(push, NV50_3D(NOPERSPECTIVE_BITMAP(0)), 4);
+ PUSH_DATAp(push, lin, 4);
- BEGIN_RING(chan, RING_3D(GP_ENABLE), 1);
- OUT_RING (chan, nv50->gmtyprog ? 1 : 0);
+ BEGIN_NV04(push, NV50_3D(GP_ENABLE), 1);
+ PUSH_DATA (push, nv50->gmtyprog ? 1 : 0);
}
static int
@@ -486,7 +497,7 @@ nv50_vp_gp_mapping(uint8_t *map, int m,
void
nv50_gp_linkage_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_program *vp = nv50->vertprog;
struct nv50_program *gp = nv50->gmtyprog;
int m = 0;
@@ -501,11 +512,11 @@ nv50_gp_linkage_validate(struct nv50_context *nv50)
n = (m + 3) / 4;
- BEGIN_RING(chan, RING_3D(VP_GP_BUILTIN_ATTR_EN), 1);
- OUT_RING (chan, vp->vp.attrs[2] | gp->vp.attrs[2]);
+ BEGIN_NV04(push, NV50_3D(VP_GP_BUILTIN_ATTR_EN), 1);
+ PUSH_DATA (push, vp->vp.attrs[2] | gp->vp.attrs[2]);
- BEGIN_RING(chan, RING_3D(VP_RESULT_MAP_SIZE), 1);
- OUT_RING (chan, m);
- BEGIN_RING(chan, RING_3D(VP_RESULT_MAP(0)), n);
- OUT_RINGp (chan, map, n);
+ BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP_SIZE), 1);
+ PUSH_DATA (push, m);
+ BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), n);
+ PUSH_DATAp(push, map, n);
}
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 0f46afb882b..e1e1af039bb 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -121,7 +121,7 @@ nv50_blend_state_create(struct pipe_context *pipe,
boolean emit_common_func = cso->rt[0].blend_enable;
uint32_t ms;
- if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
+ if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1);
SB_DATA (so, cso->independent_blend_enable);
}
@@ -142,7 +142,7 @@ nv50_blend_state_create(struct pipe_context *pipe,
emit_common_func = TRUE;
}
- if (nv50_context(pipe)->screen->tesla->grclass >= NVA3_3D) {
+ if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) {
emit_common_func = FALSE;
for (i = 0; i < 8; ++i) {
@@ -628,7 +628,7 @@ nv50_stage_set_sampler_views(struct nv50_context *nv50, int s,
nv50->num_textures[s] = nr;
- nv50_bufctx_reset(nv50, NV50_BUFCTX_TEXTURES);
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
nv50->dirty |= NV50_NEW_TEXTURES;
}
@@ -741,13 +741,15 @@ nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
{
struct nv50_context *nv50 = nv50_context(pipe);
- if (nv50->constbuf[shader][index])
- nv50_bufctx_del_resident(nv50, NV50_BUFCTX_CONSTANT,
- nv04_resource(nv50->constbuf[shader][index]));
-
pipe_resource_reference(&nv50->constbuf[shader][index], res);
nv50->constbuf_dirty[shader] |= 1 << index;
+ if (res)
+ nv50->constbuf_valid[shader] |= 1 << index;
+ else
+ nv50->constbuf_valid[shader] &= ~(1 << index);
+
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_CB(shader, index));
nv50->dirty |= NV50_NEW_CONSTBUF;
}
@@ -802,6 +804,8 @@ nv50_set_framebuffer_state(struct pipe_context *pipe,
{
struct nv50_context *nv50 = nv50_context(pipe);
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
+
nv50->framebuffer = *fb;
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
}
@@ -852,7 +856,7 @@ nv50_set_vertex_buffers(struct pipe_context *pipe,
memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
nv50->num_vtxbufs = count;
- nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
nv50->dirty |= NV50_NEW_ARRAYS;
}
@@ -863,10 +867,15 @@ nv50_set_index_buffer(struct pipe_context *pipe,
{
struct nv50_context *nv50 = nv50_context(pipe);
- if (ib) {
- pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+ if (nv50->idxbuf.buffer)
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX);
- memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf));
+ if (ib && ib->buffer) {
+ pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer);
+ nv50->idxbuf.offset = ib->offset;
+ nv50->idxbuf.index_size = ib->index_size;
+ if (nouveau_resource_mapped_by_gpu(ib->buffer))
+ BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(ib->buffer), RD);
} else {
pipe_resource_reference(&nv50->idxbuf.buffer, NULL);
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index c8a1c4ecb37..7af992076c7 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -5,48 +5,44 @@
static void
nv50_validate_fb(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned i;
unsigned ms_mode = NV50_3D_MULTISAMPLE_MODE_MS1;
- boolean serialize = FALSE;
- nv50_bufctx_reset(nv50, NV50_BUFCTX_FRAME);
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
- BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
- OUT_RING (chan, (076543210 << 4) | fb->nr_cbufs);
- BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
- OUT_RING (chan, fb->width << 16);
- OUT_RING (chan, fb->height << 16);
-
- MARK_RING(chan, 9 * fb->nr_cbufs, 2 * fb->nr_cbufs);
+ BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
+ BEGIN_NV04(push, NV50_3D(SCREEN_SCISSOR_HORIZ), 2);
+ PUSH_DATA (push, fb->width << 16);
+ PUSH_DATA (push, fb->height << 16);
for (i = 0; i < fb->nr_cbufs; ++i) {
struct nv50_miptree *mt = nv50_miptree(fb->cbufs[i]->texture);
struct nv50_surface *sf = nv50_surface(fb->cbufs[i]);
struct nouveau_bo *bo = mt->base.bo;
- uint32_t offset = sf->offset;
-
- BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 5);
- OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RING (chan, nv50_format_table[sf->base.format].rt);
- if (likely(nouveau_bo_tile_layout(bo))) {
- OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
- OUT_RING (chan, mt->layer_stride >> 2);
- BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
- OUT_RING (chan, sf->width);
- OUT_RING (chan, sf->height);
- BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
- OUT_RING (chan, sf->depth);
+
+ BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5);
+ PUSH_DATAh(push, bo->offset + sf->offset);
+ PUSH_DATA (push, bo->offset + sf->offset);
+ PUSH_DATA (push, nv50_format_table[sf->base.format].rt);
+ if (likely(nouveau_bo_memtype(bo))) {
+ PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+ PUSH_DATA (push, mt->layer_stride >> 2);
+ BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
+ PUSH_DATA (push, sf->width);
+ PUSH_DATA (push, sf->height);
+ BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+ PUSH_DATA (push, sf->depth);
} else {
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(RT_HORIZ(i)), 2);
- OUT_RING (chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
- OUT_RING (chan, sf->height);
- BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
- OUT_RING (chan, 0);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(RT_HORIZ(i)), 2);
+ PUSH_DATA (push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
+ PUSH_DATA (push, sf->height);
+ BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+ PUSH_DATA (push, 0);
assert(!fb->zsbuf);
assert(!mt->ms_mode);
@@ -55,13 +51,12 @@ nv50_validate_fb(struct nv50_context *nv50)
ms_mode = mt->ms_mode;
if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
- serialize = TRUE;
+ nv50->state.rt_serialize = TRUE;
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
/* only register for writing, otherwise we'd always serialize here */
- nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
}
if (fb->zsbuf) {
@@ -69,87 +64,79 @@ nv50_validate_fb(struct nv50_context *nv50)
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
struct nouveau_bo *bo = mt->base.bo;
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
- uint32_t offset = sf->offset;
-
- MARK_RING (chan, 12, 2);
- BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
- OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RING (chan, nv50_format_table[fb->zsbuf->format].rt);
- OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
- OUT_RING (chan, mt->layer_stride >> 2);
- BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
- OUT_RING (chan, sf->width);
- OUT_RING (chan, sf->height);
- OUT_RING (chan, (unk << 16) | sf->depth);
+
+ BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
+ PUSH_DATAh(push, bo->offset + sf->offset);
+ PUSH_DATA (push, bo->offset + sf->offset);
+ PUSH_DATA (push, nv50_format_table[fb->zsbuf->format].rt);
+ PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+ PUSH_DATA (push, mt->layer_stride >> 2);
+ BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
+ PUSH_DATA (push, sf->width);
+ PUSH_DATA (push, sf->height);
+ PUSH_DATA (push, (unk << 16) | sf->depth);
ms_mode = mt->ms_mode;
if (mt->base.status & NOUVEAU_BUFFER_STATUS_GPU_READING)
- serialize = TRUE;
+ nv50->state.rt_serialize = TRUE;
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING;
- nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BCTX_REFN(nv50->bufctx_3d, FB, &mt->base, WR);
} else {
- BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+ PUSH_DATA (push, 0);
}
- BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1);
- OUT_RING (chan, ms_mode);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_MODE), 1);
+ PUSH_DATA (push, ms_mode);
- BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
- OUT_RING (chan, fb->width << 16);
- OUT_RING (chan, fb->height << 16);
-
- if (serialize) {
- BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
- OUT_RING (chan, 0);
- }
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
+ PUSH_DATA (push, fb->width << 16);
+ PUSH_DATA (push, fb->height << 16);
}
static void
nv50_validate_blend_colour(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
- BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
- OUT_RINGf (chan, nv50->blend_colour.color[0]);
- OUT_RINGf (chan, nv50->blend_colour.color[1]);
- OUT_RINGf (chan, nv50->blend_colour.color[2]);
- OUT_RINGf (chan, nv50->blend_colour.color[3]);
+ BEGIN_NV04(push, NV50_3D(BLEND_COLOR(0)), 4);
+ PUSH_DATAf(push, nv50->blend_colour.color[0]);
+ PUSH_DATAf(push, nv50->blend_colour.color[1]);
+ PUSH_DATAf(push, nv50->blend_colour.color[2]);
+ PUSH_DATAf(push, nv50->blend_colour.color[3]);
}
static void
nv50_validate_stencil_ref(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
- BEGIN_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), 1);
- OUT_RING (chan, nv50->stencil_ref.ref_value[0]);
- BEGIN_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), 1);
- OUT_RING (chan, nv50->stencil_ref.ref_value[1]);
+ BEGIN_NV04(push, NV50_3D(STENCIL_FRONT_FUNC_REF), 1);
+ PUSH_DATA (push, nv50->stencil_ref.ref_value[0]);
+ BEGIN_NV04(push, NV50_3D(STENCIL_BACK_FUNC_REF), 1);
+ PUSH_DATA (push, nv50->stencil_ref.ref_value[1]);
}
static void
nv50_validate_stipple(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
unsigned i;
- BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
+ BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
for (i = 0; i < 32; ++i)
- OUT_RING(chan, util_bswap32(nv50->stipple.stipple[i]));
+ PUSH_DATA(push, util_bswap32(nv50->stipple.stipple[i]));
}
static void
nv50_validate_scissor(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct pipe_scissor_state *s = &nv50->scissor;
#ifdef NV50_SCISSORS_CLIPPING
struct pipe_viewport_state *vp = &nv50->viewport;
@@ -178,38 +165,38 @@ nv50_validate_scissor(struct nv50_context *nv50)
miny = MAX2(miny, (int)(vp->translate[1] - fabsf(vp->scale[1])));
maxy = MIN2(maxy, (int)(vp->translate[1] + fabsf(vp->scale[1])));
- BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
- OUT_RING (chan, (maxx << 16) | minx);
- OUT_RING (chan, (maxy << 16) | miny);
+ BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
+ PUSH_DATA (push, (maxx << 16) | minx);
+ PUSH_DATA (push, (maxy << 16) | miny);
#else
- BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
- OUT_RING (chan, (s->maxx << 16) | s->minx);
- OUT_RING (chan, (s->maxy << 16) | s->miny);
+ BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
+ PUSH_DATA (push, (s->maxx << 16) | s->minx);
+ PUSH_DATA (push, (s->maxy << 16) | s->miny);
#endif
}
static void
nv50_validate_viewport(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
float zmin, zmax;
- BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
- OUT_RINGf (chan, nv50->viewport.translate[0]);
- OUT_RINGf (chan, nv50->viewport.translate[1]);
- OUT_RINGf (chan, nv50->viewport.translate[2]);
- BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
- OUT_RINGf (chan, nv50->viewport.scale[0]);
- OUT_RINGf (chan, nv50->viewport.scale[1]);
- OUT_RINGf (chan, nv50->viewport.scale[2]);
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSLATE_X(0)), 3);
+ PUSH_DATAf(push, nv50->viewport.translate[0]);
+ PUSH_DATAf(push, nv50->viewport.translate[1]);
+ PUSH_DATAf(push, nv50->viewport.translate[2]);
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_SCALE_X(0)), 3);
+ PUSH_DATAf(push, nv50->viewport.scale[0]);
+ PUSH_DATAf(push, nv50->viewport.scale[1]);
+ PUSH_DATAf(push, nv50->viewport.scale[2]);
zmin = nv50->viewport.translate[2] - fabsf(nv50->viewport.scale[2]);
zmax = nv50->viewport.translate[2] + fabsf(nv50->viewport.scale[2]);
#ifdef NV50_SCISSORS_CLIPPING
- BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
- OUT_RINGf (chan, zmin);
- OUT_RINGf (chan, zmax);
+ BEGIN_NV04(push, NV50_3D(DEPTH_RANGE_NEAR(0)), 2);
+ PUSH_DATAf(push, zmin);
+ PUSH_DATAf(push, zmax);
#endif
}
@@ -234,15 +221,15 @@ nv50_check_program_ucps(struct nv50_context *nv50,
static void
nv50_validate_clip(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_program *vp;
uint8_t clip_enable;
if (nv50->dirty & NV50_NEW_CLIP) {
- BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
- OUT_RING (chan, (0 << 8) | NV50_CB_AUX);
- BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
- OUT_RINGp (chan, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
+ BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+ PUSH_DATA (push, (0 << 8) | NV50_CB_AUX);
+ BEGIN_NI04(push, NV50_3D(CB_DATA(0)), PIPE_MAX_CLIP_PLANES * 4);
+ PUSH_DATAp(push, &nv50->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
}
vp = nv50->gmtyprog;
@@ -251,8 +238,8 @@ nv50_validate_clip(struct nv50_context *nv50)
clip_enable = nv50->rast->pipe.clip_plane_enable;
- BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
- OUT_RING (chan, clip_enable);
+ BEGIN_NV04(push, NV50_3D(CLIP_DISTANCE_ENABLE), 1);
+ PUSH_DATA (push, clip_enable);
if (clip_enable)
nv50_check_program_ucps(nv50, vp, clip_enable);
@@ -261,34 +248,34 @@ nv50_validate_clip(struct nv50_context *nv50)
static void
nv50_validate_blend(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
- WAIT_RING(chan, nv50->blend->size);
- OUT_RINGp(chan, nv50->blend->state, nv50->blend->size);
+ PUSH_SPACE(push, nv50->blend->size);
+ PUSH_DATAp(push, nv50->blend->state, nv50->blend->size);
}
static void
nv50_validate_zsa(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
- WAIT_RING(chan, nv50->zsa->size);
- OUT_RINGp(chan, nv50->zsa->state, nv50->zsa->size);
+ PUSH_SPACE(push, nv50->zsa->size);
+ PUSH_DATAp(push, nv50->zsa->state, nv50->zsa->size);
}
static void
nv50_validate_rasterizer(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
- WAIT_RING(chan, nv50->rast->size);
- OUT_RINGp(chan, nv50->rast->state, nv50->rast->size);
+ PUSH_SPACE(push, nv50->rast->size);
+ PUSH_DATAp(push, nv50->rast->state, nv50->rast->size);
}
static void
nv50_validate_sample_mask(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
unsigned mask[4] =
{
@@ -298,11 +285,11 @@ nv50_validate_sample_mask(struct nv50_context *nv50)
nv50->sample_mask & 0xffff
};
- BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
- OUT_RING (chan, mask[0]);
- OUT_RING (chan, mask[1]);
- OUT_RING (chan, mask[2]);
- OUT_RING (chan, mask[3]);
+ BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
+ PUSH_DATA (push, mask[0]);
+ PUSH_DATA (push, mask[1]);
+ PUSH_DATA (push, mask[2]);
+ PUSH_DATA (push, mask[3]);
}
static void
@@ -378,6 +365,7 @@ boolean
nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
{
uint32_t state_mask;
+ int ret;
unsigned i;
if (nv50->screen->cur_ctx != nv50)
@@ -393,11 +381,21 @@ nv50_state_validate(struct nv50_context *nv50, uint32_t mask, unsigned words)
validate->func(nv50);
}
nv50->dirty &= ~state_mask;
- }
- MARK_RING(nv50->screen->base.channel, words, 0);
+ if (nv50->state.rt_serialize) {
+ nv50->state.rt_serialize = FALSE;
+ BEGIN_NV04(nv50->base.pushbuf, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+ PUSH_DATA (nv50->base.pushbuf, 0);
+ }
- nv50_bufctx_emit_relocs(nv50);
+ nv50_bufctx_fence(nv50->bufctx_3d, FALSE);
+ }
+ nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_3d);
+ ret = nouveau_pushbuf_validate(nv50->base.pushbuf);
- return TRUE;
+ if (unlikely(nv50->state.flushed)) {
+ nv50->state.flushed = FALSE;
+ nv50_bufctx_fence(nv50->bufctx_3d, TRUE);
+ }
+ return !ret;
}
diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h
index c443dfbfec6..b056e19ea50 100644
--- a/src/gallium/drivers/nv50/nv50_stateobj.h
+++ b/src/gallium/drivers/nv50/nv50_stateobj.h
@@ -6,13 +6,11 @@
#define NV50_SCISSORS_CLIPPING
-#define SB_BEGIN_3D(so, m, s) \
- (so)->state[(so)->size++] = \
- ((s) << 18) | (NV50_SUBCH_3D << 13) | NV50_3D_##m
+#define SB_BEGIN_3D(so, m, s) \
+ (so)->state[(so)->size++] = NV50_FIFO_PKHDR(NV50_3D(m), s)
-#define SB_BEGIN_3D_(so, m, s) \
- (so)->state[(so)->size++] = \
- ((s) << 18) | (NV50_SUBCH_3D << 13) | m
+#define SB_BEGIN_3D_(so, m, s) \
+ (so)->state[(so)->size++] = NV50_FIFO_PKHDR(SUBC_3D(m), s)
#define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 28e34bd9ef6..0d29dcc8a2a 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -70,14 +70,13 @@ nv50_2d_format(enum pipe_format format)
}
static int
-nv50_2d_texture_set(struct nouveau_channel *chan, int dst,
+nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
struct nv50_miptree *mt, unsigned level, unsigned layer)
{
struct nouveau_bo *bo = mt->base.bo;
uint32_t width, height, depth;
uint32_t format;
uint32_t mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
- uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
uint32_t offset = mt->level[level].offset;
format = nv50_2d_format(mt->base.base.format);
@@ -99,44 +98,44 @@ nv50_2d_texture_set(struct nouveau_channel *chan, int dst,
depth = u_minify(mt->base.base.depth0, level);
}
- if (!(bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK)) {
- BEGIN_RING(chan, RING_2D_(mthd), 2);
- OUT_RING (chan, format);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_2D_(mthd + 0x14), 5);
- OUT_RING (chan, mt->level[level].pitch);
- OUT_RING (chan, width);
- OUT_RING (chan, height);
- OUT_RELOCh(chan, bo, offset, flags);
- OUT_RELOCl(chan, bo, offset, flags);
+ if (!nouveau_bo_memtype(bo)) {
+ BEGIN_NV04(push, SUBC_2D(mthd), 2);
+ PUSH_DATA (push, format);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, SUBC_2D(mthd + 0x14), 5);
+ PUSH_DATA (push, mt->level[level].pitch);
+ PUSH_DATA (push, width);
+ PUSH_DATA (push, height);
+ PUSH_DATAh(push, bo->offset + offset);
+ PUSH_DATA (push, bo->offset + offset);
} else {
- BEGIN_RING(chan, RING_2D_(mthd), 5);
- OUT_RING (chan, format);
- OUT_RING (chan, 0);
- OUT_RING (chan, mt->level[level].tile_mode << 4);
- OUT_RING (chan, depth);
- OUT_RING (chan, layer);
- BEGIN_RING(chan, RING_2D_(mthd + 0x18), 4);
- OUT_RING (chan, width);
- OUT_RING (chan, height);
- OUT_RELOCh(chan, bo, offset, flags);
- OUT_RELOCl(chan, bo, offset, flags);
+ BEGIN_NV04(push, SUBC_2D(mthd), 5);
+ PUSH_DATA (push, format);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, mt->level[level].tile_mode);
+ PUSH_DATA (push, depth);
+ PUSH_DATA (push, layer);
+ BEGIN_NV04(push, SUBC_2D(mthd + 0x18), 4);
+ PUSH_DATA (push, width);
+ PUSH_DATA (push, height);
+ PUSH_DATAh(push, bo->offset + offset);
+ PUSH_DATA (push, bo->offset + offset);
}
#if 0
if (dst) {
- BEGIN_RING(chan, RING_2D_(NV50_2D_CLIP_X), 4);
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
- OUT_RING (chan, width);
- OUT_RING (chan, height);
+ BEGIN_NV04(push, SUBC_2D(NV50_2D_CLIP_X), 4);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, width);
+ PUSH_DATA (push, height);
}
#endif
return 0;
}
static int
-nv50_2d_texture_do_copy(struct nouveau_channel *chan,
+nv50_2d_texture_do_copy(struct nouveau_pushbuf *push,
struct nv50_miptree *dst, unsigned dst_level,
unsigned dx, unsigned dy, unsigned dz,
struct nv50_miptree *src, unsigned src_level,
@@ -150,16 +149,16 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan,
int ret;
uint32_t ctrl;
-
+#if 0
ret = MARK_RING(chan, 2 * 16 + 32, 4);
if (ret)
return ret;
-
- ret = nv50_2d_texture_set(chan, 1, dst, dst_level, dz);
+#endif
+ ret = nv50_2d_texture_set(push, 1, dst, dst_level, dz);
if (ret)
return ret;
- ret = nv50_2d_texture_set(chan, 0, src, src_level, sz);
+ ret = nv50_2d_texture_set(push, 0, src, src_level, sz);
if (ret)
return ret;
@@ -168,23 +167,23 @@ nv50_2d_texture_do_copy(struct nouveau_channel *chan,
ctrl = 0x11;
/* 0/1 = CENTER/CORNER, 00/10 = POINT/BILINEAR */
- BEGIN_RING(chan, RING_2D(BLIT_CONTROL), 1);
- OUT_RING (chan, ctrl);
- BEGIN_RING(chan, RING_2D(BLIT_DST_X), 4);
- OUT_RING (chan, dx << dst->ms_x);
- OUT_RING (chan, dy << dst->ms_y);
- OUT_RING (chan, w << dst->ms_x);
- OUT_RING (chan, h << dst->ms_y);
- BEGIN_RING(chan, RING_2D(BLIT_DU_DX_FRACT), 4);
- OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
- OUT_RING (chan, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
- OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
- OUT_RING (chan, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
- BEGIN_RING(chan, RING_2D(BLIT_SRC_X_FRACT), 4);
- OUT_RING (chan, 0);
- OUT_RING (chan, sx << src->ms_x);
- OUT_RING (chan, 0);
- OUT_RING (chan, sy << src->ms_y);
+ BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
+ PUSH_DATA (push, ctrl);
+ BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 4);
+ PUSH_DATA (push, dx << dst->ms_x);
+ PUSH_DATA (push, dy << dst->ms_y);
+ PUSH_DATA (push, w << dst->ms_x);
+ PUSH_DATA (push, h << dst->ms_y);
+ BEGIN_NV04(push, NV50_2D(BLIT_DU_DX_FRACT), 4);
+ PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0xf0000000);
+ PUSH_DATA (push, duvdxy[2 + ((int)src->ms_x - (int)dst->ms_x)] & 0x0000000f);
+ PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0xf0000000);
+ PUSH_DATA (push, duvdxy[2 + ((int)src->ms_y - (int)dst->ms_y)] & 0x0000000f);
+ BEGIN_NV04(push, NV50_2D(BLIT_SRC_X_FRACT), 4);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, sx << src->ms_x);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, sy << src->ms_y);
return 0;
}
@@ -196,7 +195,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
struct pipe_resource *src, unsigned src_level,
const struct pipe_box *src_box)
{
- struct nv50_screen *screen = nv50_context(pipe)->screen;
+ struct nv50_context *nv50 = nv50_context(pipe);
int ret;
boolean m2mf;
unsigned dst_layer = dstz, src_layer = src_box->z;
@@ -227,7 +226,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
src_box->x, src_box->y, src_box->z);
for (i = 0; i < src_box->depth; ++i) {
- nv50_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny);
+ nv50_m2mf_transfer_rect(nv50, &drect, &srect, nx, ny);
if (nv50_miptree(dst)->layout_3d)
drect.z++;
@@ -246,16 +245,22 @@ nv50_resource_copy_region(struct pipe_context *pipe,
(nv50_2d_format_faithful(src->format) &&
nv50_2d_format_faithful(dst->format)));
+ BCTX_REFN(nv50->bufctx, 2D, nv04_resource(src), RD);
+ BCTX_REFN(nv50->bufctx, 2D, nv04_resource(dst), WR);
+ nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx);
+ nouveau_pushbuf_validate(nv50->base.pushbuf);
+
for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
- ret = nv50_2d_texture_do_copy(screen->base.channel,
+ ret = nv50_2d_texture_do_copy(nv50->base.pushbuf,
nv50_miptree(dst), dst_level,
dstx, dsty, dst_layer,
nv50_miptree(src), src_level,
src_box->x, src_box->y, src_layer,
src_box->width, src_box->height);
if (ret)
- return;
+ break;
}
+ nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
}
static void
@@ -266,51 +271,50 @@ nv50_clear_render_target(struct pipe_context *pipe,
unsigned width, unsigned height)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nv50_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_miptree *mt = nv50_miptree(dst->texture);
struct nv50_surface *sf = nv50_surface(dst);
struct nouveau_bo *bo = mt->base.bo;
- BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
- OUT_RINGf (chan, color->f[0]);
- OUT_RINGf (chan, color->f[1]);
- OUT_RINGf (chan, color->f[2]);
- OUT_RINGf (chan, color->f[3]);
-
+ BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
+ PUSH_DATAf(push, color->f[0]);
+ PUSH_DATAf(push, color->f[1]);
+ PUSH_DATAf(push, color->f[2]);
+ PUSH_DATAf(push, color->f[3]);
+#if 0
if (MARK_RING(chan, 18, 2))
return;
-
- BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 5);
- OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RING (chan, nv50_format_table[dst->format].rt);
- OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(RT_HORIZ(0)), 2);
- if (nouveau_bo_tile_layout(bo))
- OUT_RING(chan, sf->width);
+#endif
+ BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
+ PUSH_DATAh(push, bo->offset + sf->offset);
+ PUSH_DATA (push, bo->offset + sf->offset);
+ PUSH_DATA (push, nv50_format_table[dst->format].rt);
+ PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(RT_HORIZ(0)), 2);
+ if (nouveau_bo_memtype(bo))
+ PUSH_DATA(push, sf->width);
else
- OUT_RING(chan, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
- OUT_RING (chan, sf->height);
- BEGIN_RING(chan, RING_3D(RT_ARRAY_MODE), 1);
- OUT_RING (chan, 1);
-
- if (!nouveau_bo_tile_layout(bo)) {
- BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
- OUT_RING (chan, 0);
+ PUSH_DATA(push, NV50_3D_RT_HORIZ_LINEAR | mt->level[0].pitch);
+ PUSH_DATA (push, sf->height);
+ BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+ PUSH_DATA (push, 1);
+
+ if (!nouveau_bo_memtype(bo)) {
+ BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+ PUSH_DATA (push, 0);
}
/* NOTE: only works with D3D clear flag (5097/0x143c bit 4) */
- BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
- OUT_RING (chan, (width << 16) | dstx);
- OUT_RING (chan, (height << 16) | dsty);
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
+ PUSH_DATA (push, (width << 16) | dstx);
+ PUSH_DATA (push, (height << 16) | dsty);
- BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
- OUT_RING (chan, 0x3c);
+ BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+ PUSH_DATA (push, 0x3c);
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
}
@@ -325,49 +329,48 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
unsigned width, unsigned height)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nv50_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_miptree *mt = nv50_miptree(dst->texture);
struct nv50_surface *sf = nv50_surface(dst);
struct nouveau_bo *bo = mt->base.bo;
uint32_t mode = 0;
- assert(nouveau_bo_tile_layout(bo)); /* ZETA cannot be linear */
+ assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
if (clear_flags & PIPE_CLEAR_DEPTH) {
- BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
- OUT_RINGf (chan, depth);
+ BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
+ PUSH_DATAf(push, depth);
mode |= NV50_3D_CLEAR_BUFFERS_Z;
}
if (clear_flags & PIPE_CLEAR_STENCIL) {
- BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
- OUT_RING (chan, stencil & 0xff);
+ BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
+ PUSH_DATA (push, stencil & 0xff);
mode |= NV50_3D_CLEAR_BUFFERS_S;
}
-
+#if 0
if (MARK_RING(chan, 17, 2))
return;
-
- BEGIN_RING(chan, RING_3D(ZETA_ADDRESS_HIGH), 5);
- OUT_RELOCh(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, bo, sf->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RING (chan, nv50_format_table[dst->format].rt);
- OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode << 4);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(ZETA_HORIZ), 3);
- OUT_RING (chan, sf->width);
- OUT_RING (chan, sf->height);
- OUT_RING (chan, (1 << 16) | 1);
-
- BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
- OUT_RING (chan, (width << 16) | dstx);
- OUT_RING (chan, (height << 16) | dsty);
-
- BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
- OUT_RING (chan, mode);
+#endif
+ BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
+ PUSH_DATAh(push, bo->offset + sf->offset);
+ PUSH_DATA (push, bo->offset + sf->offset);
+ PUSH_DATA (push, nv50_format_table[dst->format].rt);
+ PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_3D(ZETA_HORIZ), 3);
+ PUSH_DATA (push, sf->width);
+ PUSH_DATA (push, sf->height);
+ PUSH_DATA (push, (1 << 16) | 1);
+
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_HORIZ(0)), 2);
+ PUSH_DATA (push, (width << 16) | dstx);
+ PUSH_DATA (push, (height << 16) | dsty);
+
+ BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+ PUSH_DATA (push, mode);
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
}
@@ -378,7 +381,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
double depth, unsigned stencil)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct pipe_framebuffer_state *fb = &nv50->framebuffer;
unsigned i;
uint32_t mode = 0;
@@ -388,34 +391,34 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
return;
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
- BEGIN_RING(chan, RING_3D(CLEAR_COLOR(0)), 4);
- OUT_RINGf (chan, color->f[0]);
- OUT_RINGf (chan, color->f[1]);
- OUT_RINGf (chan, color->f[2]);
- OUT_RINGf (chan, color->f[3]);
+ BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
+ PUSH_DATAf(push, color->f[0]);
+ PUSH_DATAf(push, color->f[1]);
+ PUSH_DATAf(push, color->f[2]);
+ PUSH_DATAf(push, color->f[3]);
mode =
NV50_3D_CLEAR_BUFFERS_R | NV50_3D_CLEAR_BUFFERS_G |
NV50_3D_CLEAR_BUFFERS_B | NV50_3D_CLEAR_BUFFERS_A;
}
if (buffers & PIPE_CLEAR_DEPTH) {
- BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
- OUT_RING (chan, fui(depth));
+ BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
+ PUSH_DATA (push, fui(depth));
mode |= NV50_3D_CLEAR_BUFFERS_Z;
}
if (buffers & PIPE_CLEAR_STENCIL) {
- BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
- OUT_RING (chan, stencil & 0xff);
+ BEGIN_NV04(push, NV50_3D(CLEAR_STENCIL), 1);
+ PUSH_DATA (push, stencil & 0xff);
mode |= NV50_3D_CLEAR_BUFFERS_S;
}
- BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
- OUT_RING (chan, mode);
+ BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+ PUSH_DATA (push, mode);
for (i = 1; i < fb->nr_cbufs; i++) {
- BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
- OUT_RING (chan, (i << 6) | 0x3c);
+ BEGIN_NV04(push, NV50_3D(CLEAR_BUFFERS), 1);
+ PUSH_DATA (push, (i << 6) | 0x3c);
}
}
@@ -709,50 +712,50 @@ nv50_blit_set_src(struct nv50_context *nv50,
static void
nv50_blitctx_prepare_state(struct nv50_blitctx *blit)
{
- struct nouveau_channel *chan = blit->screen->base.channel;
+ struct nouveau_pushbuf *push = blit->screen->base.pushbuf;
/* blend state */
- BEGIN_RING(chan, RING_3D(COLOR_MASK(0)), 1);
- OUT_RING (chan, blit->color_mask);
- BEGIN_RING(chan, RING_3D(BLEND_ENABLE(0)), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(LOGIC_OP_ENABLE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(COLOR_MASK(0)), 1);
+ PUSH_DATA (push, blit->color_mask);
+ BEGIN_NV04(push, NV50_3D(BLEND_ENABLE(0)), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(LOGIC_OP_ENABLE), 1);
+ PUSH_DATA (push, 0);
/* rasterizer state */
#ifndef NV50_SCISSORS_CLIPPING
- BEGIN_RING(chan, RING_3D(SCISSOR_ENABLE(0)), 1);
- OUT_RING (chan, 1);
+ BEGIN_NV04(push, NV50_3D(SCISSOR_ENABLE(0)), 1);
+ PUSH_DATA (push, 1);
#endif
- BEGIN_RING(chan, RING_3D(VERTEX_TWO_SIDE_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(MSAA_MASK(0)), 4);
- OUT_RING (chan, 0xffff);
- OUT_RING (chan, 0xffff);
- OUT_RING (chan, 0xffff);
- OUT_RING (chan, 0xffff);
- BEGIN_RING(chan, RING_3D(POLYGON_MODE_FRONT), 3);
- OUT_RING (chan, NV50_3D_POLYGON_MODE_FRONT_FILL);
- OUT_RING (chan, NV50_3D_POLYGON_MODE_BACK_FILL);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(CULL_FACE_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_TWO_SIDE_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(FRAG_COLOR_CLAMP_EN), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(MULTISAMPLE_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(MSAA_MASK(0)), 4);
+ PUSH_DATA (push, 0xffff);
+ PUSH_DATA (push, 0xffff);
+ PUSH_DATA (push, 0xffff);
+ PUSH_DATA (push, 0xffff);
+ BEGIN_NV04(push, NV50_3D(POLYGON_MODE_FRONT), 3);
+ PUSH_DATA (push, NV50_3D_POLYGON_MODE_FRONT_FILL);
+ PUSH_DATA (push, NV50_3D_POLYGON_MODE_BACK_FILL);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(CULL_FACE_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(POLYGON_STIPPLE_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
+ PUSH_DATA (push, 0);
/* zsa state */
- BEGIN_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(STENCIL_ENABLE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(DEPTH_TEST_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(STENCIL_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_3D(ALPHA_TEST_ENABLE), 1);
+ PUSH_DATA (push, 0);
}
static void
@@ -834,7 +837,7 @@ nv50_resource_resolve(struct pipe_context *pipe,
struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_screen *screen = nv50->screen;
struct nv50_blitctx *blit = screen->blitctx;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct pipe_resource *src = info->src.res;
struct pipe_resource *dst = info->dst.res;
float x0, x1, y0, y1, z;
@@ -873,12 +876,12 @@ nv50_resource_resolve(struct pipe_context *pipe,
z = (float)info->src.layer;
- BEGIN_RING(chan, RING_3D(FP_START_ID), 1);
- OUT_RING (chan,
+ BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
+ PUSH_DATA (push,
blit->fp.code_base + blit->fp_offset);
- BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+ PUSH_DATA (push, 0);
/* Draw a large triangle in screen coordinates covering the whole
* render target, with scissors defining the destination region.
@@ -886,40 +889,40 @@ nv50_resource_resolve(struct pipe_context *pipe,
* arranged in a way to yield the desired offset and scale.
*/
- BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
- OUT_RING (chan, (info->dst.x1 << 16) | info->dst.x0);
- OUT_RING (chan, (info->dst.y1 << 16) | info->dst.y0);
-
- BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (chan, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
- OUT_RINGf (chan, x0);
- OUT_RINGf (chan, y0);
- OUT_RINGf (chan, z);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
- OUT_RINGf (chan, 0.0f);
- OUT_RINGf (chan, 0.0f);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
- OUT_RINGf (chan, x1);
- OUT_RINGf (chan, y0);
- OUT_RINGf (chan, z);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
- OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x);
- OUT_RINGf (chan, 0.0f);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(1)), 3);
- OUT_RINGf (chan, x0);
- OUT_RINGf (chan, y1);
- OUT_RINGf (chan, z);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(0)), 2);
- OUT_RINGf (chan, 0.0f);
- OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y);
- BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(SCISSOR_HORIZ(0)), 2);
+ PUSH_DATA (push, (info->dst.x1 << 16) | info->dst.x0);
+ PUSH_DATA (push, (info->dst.y1 << 16) | info->dst.y0);
+
+ BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (push, NV50_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
+ PUSH_DATAf(push, x0);
+ PUSH_DATAf(push, y0);
+ PUSH_DATAf(push, z);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 0.0f);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
+ PUSH_DATAf(push, x1);
+ PUSH_DATAf(push, y0);
+ PUSH_DATAf(push, z);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
+ PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
+ PUSH_DATAf(push, 0.0f);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(1)), 3);
+ PUSH_DATAf(push, x0);
+ PUSH_DATAf(push, y1);
+ PUSH_DATAf(push, z);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(0)), 2);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
+ BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+ PUSH_DATA (push, 0);
/* re-enable normally constant state */
- BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
- OUT_RING (chan, 1);
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+ PUSH_DATA (push, 1);
nv50_blitctx_post_blit(nv50, blit);
}
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 1be4e9aff19..4a769d5b810 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -75,6 +75,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
const struct pipe_sampler_view *templ)
{
const struct util_format_description *desc;
+ uint64_t addr;
uint32_t *tic;
uint32_t swz[4];
uint32_t depth;
@@ -115,15 +116,25 @@ nv50_create_sampler_view(struct pipe_context *pipe,
(swz[2] << NV50_TIC_0_MAPB__SHIFT) |
(swz[3] << NV50_TIC_0_MAPA__SHIFT);
- tic[1] = /* mt->base.bo->offset; */ 0;
- tic[2] = /* mt->base.bo->offset >> 32 */ 0;
+ addr = mt->base.address;
+
+ if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY ||
+ mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) {
+ addr += view->pipe.u.tex.first_layer * mt->layer_stride;
+ depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
+ } else {
+ depth = mt->base.base.depth0;
+ }
+
+ tic[1] = addr;
+ tic[2] = (addr >> 32) & 0xff;
tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER;
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
- if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) {
+ if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
nv50_init_tic_entry_linear(tic, texture);
return &view->pipe;
}
@@ -132,16 +143,8 @@ nv50_create_sampler_view(struct pipe_context *pipe,
tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
tic[2] |=
- ((mt->base.bo->tile_mode & 0x0f) << (22 - 0)) |
- ((mt->base.bo->tile_mode & 0xf0) << (25 - 4));
-
- depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
-
- if (mt->base.base.target == PIPE_TEXTURE_1D_ARRAY ||
- mt->base.base.target == PIPE_TEXTURE_2D_ARRAY) {
- tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride;
- depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
- }
+ ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
+ ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
switch (mt->base.base.target) {
case PIPE_TEXTURE_1D:
@@ -196,7 +199,7 @@ nv50_create_sampler_view(struct pipe_context *pipe,
static boolean
nv50_validate_tic(struct nv50_context *nv50, int s)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nouveau_bo *txc = nv50->screen->txc;
unsigned i;
boolean need_flush = FALSE;
@@ -206,53 +209,46 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
struct nv04_resource *res;
if (!tic) {
- BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
- OUT_RING (chan, (i << 1) | 0);
+ BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
+ PUSH_DATA (push, (i << 1) | 0);
continue;
}
res = &nv50_miptree(tic->pipe.texture)->base;
if (tic->id < 0) {
- uint32_t offset = tic->tic[1];
-
tic->id = nv50_screen_tic_alloc(nv50->screen, tic);
- MARK_RING (chan, 24 + 8, 4);
- BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
- OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
- OUT_RING (chan, 262144);
- OUT_RING (chan, 65536);
- OUT_RING (chan, 1);
- OUT_RELOCh(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, txc, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
- OUT_RING (chan, 0);
- OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
- BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
- OUT_RING (chan, 32);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- OUT_RING (chan, tic->id * 32);
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
- BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), 8);
- OUT_RING (chan, tic->tic[0]);
- OUT_RELOCl(chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOC (chan, res->bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
- NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]);
- OUT_RINGp (chan, &tic->tic[3], 5);
+ BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
+ PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
+ PUSH_DATA (push, 262144);
+ PUSH_DATA (push, 65536);
+ PUSH_DATA (push, 1);
+ PUSH_DATAh(push, txc->offset);
+ PUSH_DATA (push, txc->offset);
+ BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+ BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);
+ PUSH_DATA (push, 32);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, tic->id * 32);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+ BEGIN_NI04(push, NV50_2D(SIFC_DATA), 8);
+ PUSH_DATAp(push, &tic->tic[0], 8);
need_flush = TRUE;
} else
if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
- BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1);
- OUT_RING (chan, 0x20); //(tic->id << 4) | 1);
+ BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
+ PUSH_DATA (push, 0x20);
}
nv50->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
@@ -260,15 +256,14 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
res->status &= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
- nv50_bufctx_add_resident(nv50, NV50_BUFCTX_TEXTURES, res,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ BCTX_REFN(nv50->bufctx_3d, TEXTURES, res, RD);
- BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
- OUT_RING (chan, (tic->id << 9) | (i << 1) | 1);
+ BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
+ PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
}
for (; i < nv50->state.num_textures[s]; ++i) {
- BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
- OUT_RING (chan, (i << 1) | 0);
+ BEGIN_NV04(push, NV50_3D(BIND_TIC(s)), 1);
+ PUSH_DATA (push, (i << 1) | 0);
}
nv50->state.num_textures[s] = nv50->num_textures[s];
@@ -283,15 +278,15 @@ void nv50_validate_textures(struct nv50_context *nv50)
need_flush |= nv50_validate_tic(nv50, 2);
if (need_flush) {
- BEGIN_RING(nv50->screen->base.channel, RING_3D(TIC_FLUSH), 1);
- OUT_RING (nv50->screen->base.channel, 0);
+ BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TIC_FLUSH), 1);
+ PUSH_DATA (nv50->base.pushbuf, 0);
}
}
static boolean
nv50_validate_tsc(struct nv50_context *nv50, int s)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
unsigned i;
boolean need_flush = FALSE;
@@ -299,8 +294,8 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
struct nv50_tsc_entry *tsc = nv50_tsc_entry(nv50->samplers[s][i]);
if (!tsc) {
- BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
- OUT_RING (chan, (i << 4) | 0);
+ BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
+ PUSH_DATA (push, (i << 4) | 0);
continue;
}
if (tsc->id < 0) {
@@ -313,12 +308,12 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
}
nv50->screen->tsc.lock[tsc->id / 32] |= 1 << (tsc->id % 32);
- BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
- OUT_RING (chan, (tsc->id << 12) | (i << 4) | 1);
+ BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
+ PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1);
}
for (; i < nv50->state.num_samplers[s]; ++i) {
- BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
- OUT_RING (chan, (i << 4) | 0);
+ BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
+ PUSH_DATA (push, (i << 4) | 0);
}
nv50->state.num_samplers[s] = nv50->num_samplers[s];
@@ -333,7 +328,7 @@ void nv50_validate_samplers(struct nv50_context *nv50)
need_flush |= nv50_validate_tsc(nv50, 2);
if (need_flush) {
- BEGIN_RING(nv50->screen->base.channel, RING_3D(TSC_FLUSH), 1);
- OUT_RING (nv50->screen->base.channel, 0);
+ BEGIN_NV04(nv50->base.pushbuf, NV50_3D(TSC_FLUSH), 1);
+ PUSH_DATA (nv50->base.pushbuf, 0);
}
}
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index 6f860e73348..b960dc0d191 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -50,12 +50,13 @@ nv50_m2mf_rect_setup(struct nv50_m2mf_rect *rect,
}
void
-nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nv50_m2mf_transfer_rect(struct nv50_context *nv50,
const struct nv50_m2mf_rect *dst,
const struct nv50_m2mf_rect *src,
uint32_t nblocksx, uint32_t nblocksy)
{
- struct nouveau_channel *chan = nouveau_screen(pscreen)->channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
+ struct nouveau_bufctx *bctx = nv50->bufctx;
const int cpp = dst->cpp;
uint32_t src_ofst = src->base;
uint32_t dst_ofst = dst->base;
@@ -65,76 +66,81 @@ nv50_m2mf_transfer_rect(struct pipe_screen *pscreen,
assert(dst->cpp == src->cpp);
- if (nouveau_bo_tile_layout(src->bo)) {
- BEGIN_RING(chan, RING_MF(LINEAR_IN), 6);
- OUT_RING (chan, 0);
- OUT_RING (chan, src->tile_mode << 4);
- OUT_RING (chan, src->width * cpp);
- OUT_RING (chan, src->height);
- OUT_RING (chan, src->depth);
- OUT_RING (chan, src->z);
+ nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
+ nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
+ nouveau_pushbuf_bufctx(push, bctx);
+ nouveau_pushbuf_validate(push);
+
+ if (nouveau_bo_memtype(src->bo)) {
+ BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 6);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, src->tile_mode);
+ PUSH_DATA (push, src->width * cpp);
+ PUSH_DATA (push, src->height);
+ PUSH_DATA (push, src->depth);
+ PUSH_DATA (push, src->z);
} else {
src_ofst += src->y * src->pitch + src->x * cpp;
- BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_IN), 1);
- OUT_RING (chan, src->pitch);
+ BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_IN), 1);
+ PUSH_DATA (push, src->pitch);
}
- if (nouveau_bo_tile_layout(dst->bo)) {
- BEGIN_RING(chan, RING_MF(LINEAR_OUT), 6);
- OUT_RING (chan, 0);
- OUT_RING (chan, dst->tile_mode << 4);
- OUT_RING (chan, dst->width * cpp);
- OUT_RING (chan, dst->height);
- OUT_RING (chan, dst->depth);
- OUT_RING (chan, dst->z);
+ if (nouveau_bo_memtype(dst->bo)) {
+ BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 6);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, dst->tile_mode);
+ PUSH_DATA (push, dst->width * cpp);
+ PUSH_DATA (push, dst->height);
+ PUSH_DATA (push, dst->depth);
+ PUSH_DATA (push, dst->z);
} else {
dst_ofst += dst->y * dst->pitch + dst->x * cpp;
- BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_MF_(NV04_M2MF_PITCH_OUT), 1);
- OUT_RING (chan, dst->pitch);
+ BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_PITCH_OUT), 1);
+ PUSH_DATA (push, dst->pitch);
}
while (height) {
int line_count = height > 2047 ? 2047 : height;
- MARK_RING (chan, 17, 4);
+ BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2);
+ PUSH_DATAh(push, src->bo->offset + src_ofst);
+ PUSH_DATAh(push, dst->bo->offset + dst_ofst);
- BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
- OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
- OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2);
+ PUSH_DATA (push, src->bo->offset + src_ofst);
+ PUSH_DATA (push, dst->bo->offset + dst_ofst);
- BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
- OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
-
- if (nouveau_bo_tile_layout(src->bo)) {
- BEGIN_RING(chan, RING_MF(TILING_POSITION_IN), 1);
- OUT_RING (chan, (sy << 16) | (src->x * cpp));
+ if (nouveau_bo_memtype(src->bo)) {
+ BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_IN), 1);
+ PUSH_DATA (push, (sy << 16) | (src->x * cpp));
} else {
src_ofst += line_count * src->pitch;
}
- if (nouveau_bo_tile_layout(dst->bo)) {
- BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT), 1);
- OUT_RING (chan, (dy << 16) | (dst->x * cpp));
+ if (nouveau_bo_memtype(dst->bo)) {
+ BEGIN_NV04(push, NV50_M2MF(TILING_POSITION_OUT), 1);
+ PUSH_DATA (push, (dy << 16) | (dst->x * cpp));
} else {
dst_ofst += line_count * dst->pitch;
}
- BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
- OUT_RING (chan, nblocksx * cpp);
- OUT_RING (chan, line_count);
- OUT_RING (chan, (1 << 8) | (1 << 0));
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4);
+ PUSH_DATA (push, nblocksx * cpp);
+ PUSH_DATA (push, line_count);
+ PUSH_DATA (push, (1 << 8) | (1 << 0));
+ PUSH_DATA (push, 0);
height -= line_count;
sy += line_count;
dy += line_count;
}
+
+ nouveau_bufctx_reset(bctx, 0);
}
void
@@ -142,55 +148,60 @@ nv50_sifc_linear_u8(struct nouveau_context *nv,
struct nouveau_bo *dst, unsigned offset, unsigned domain,
unsigned size, const void *data)
{
- struct nouveau_channel *chan = nv->screen->channel;
+ struct nv50_context *nv50 = nv50_context(&nv->pipe);
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
uint32_t *src = (uint32_t *)data;
unsigned count = (size + 3) / 4;
unsigned xcoord = offset & 0xff;
+ nouveau_bufctx_refn(nv50->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
+ nouveau_pushbuf_bufctx(push, nv50->bufctx);
+ nouveau_pushbuf_validate(push);
+
offset &= ~0xff;
- MARK_RING (chan, 23, 4);
- BEGIN_RING(chan, RING_2D(DST_FORMAT), 2);
- OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_2D(DST_PITCH), 5);
- OUT_RING (chan, 262144);
- OUT_RING (chan, 65536);
- OUT_RING (chan, 1);
- OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR);
- BEGIN_RING(chan, RING_2D(SIFC_BITMAP_ENABLE), 2);
- OUT_RING (chan, 0);
- OUT_RING (chan, NV50_SURFACE_FORMAT_R8_UNORM);
- BEGIN_RING(chan, RING_2D(SIFC_WIDTH), 10);
- OUT_RING (chan, size);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- OUT_RING (chan, xcoord);
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2);
+ PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_2D(DST_PITCH), 5);
+ PUSH_DATA (push, 262144);
+ PUSH_DATA (push, 65536);
+ PUSH_DATA (push, 1);
+ PUSH_DATAh(push, dst->offset + offset);
+ PUSH_DATA (push, dst->offset + offset);
+ BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, NV50_SURFACE_FORMAT_R8_UNORM);
+ BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10);
+ PUSH_DATA (push, size);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, xcoord);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
while (count) {
- unsigned nr = AVAIL_RING(chan);
+ unsigned nr;
- if (nr < 9) {
- FIRE_RING(chan);
- nouveau_bo_validate(chan, dst, NOUVEAU_BO_WR);
- continue;
- }
+ if (!PUSH_SPACE(push, 16))
+ break;
+ nr = PUSH_AVAIL(push);
+ assert(nr >= 16);
nr = MIN2(count, nr - 1);
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
- BEGIN_RING_NI(chan, RING_2D(SIFC_DATA), nr);
- OUT_RINGp (chan, src, nr);
+ BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr);
+ PUSH_DATAp(push, src, nr);
src += nr;
count -= nr;
}
+
+ nouveau_bufctx_reset(nv50->bufctx, 0);
}
void
@@ -199,33 +210,40 @@ nv50_m2mf_copy_linear(struct nouveau_context *nv,
struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
unsigned size)
{
- struct nouveau_channel *chan = nv->screen->channel;
+ struct nouveau_pushbuf *push = nv->pushbuf;
+ struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx;
+
+ nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
+ nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
+ nouveau_pushbuf_bufctx(push, bctx);
+ nouveau_pushbuf_validate(push);
- BEGIN_RING(chan, RING_MF(LINEAR_IN), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_MF(LINEAR_OUT), 1);
- OUT_RING (chan, 1);
+ BEGIN_NV04(push, NV50_M2MF(LINEAR_IN), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_M2MF(LINEAR_OUT), 1);
+ PUSH_DATA (push, 1);
while (size) {
unsigned bytes = MIN2(size, 1 << 17);
- MARK_RING (chan, 11, 4);
- BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
- OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
- OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
- BEGIN_RING(chan, RING_MF_(NV04_M2MF_OFFSET_IN), 2);
- OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
- BEGIN_RING(chan, RING_MF_(NV04_M2MF_LINE_LENGTH_IN), 4);
- OUT_RING (chan, bytes);
- OUT_RING (chan, 1);
- OUT_RING (chan, (1 << 8) | (1 << 0));
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_M2MF(OFFSET_IN_HIGH), 2);
+ PUSH_DATAh(push, src->offset + srcoff);
+ PUSH_DATAh(push, dst->offset + dstoff);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_OFFSET_IN), 2);
+ PUSH_DATA (push, src->offset + srcoff);
+ PUSH_DATA (push, dst->offset + dstoff);
+ BEGIN_NV04(push, SUBC_M2MF(NV03_M2MF_LINE_LENGTH_IN), 4);
+ PUSH_DATA (push, bytes);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, (1 << 8) | (1 << 0));
+ PUSH_DATA (push, 0);
srcoff += bytes;
dstoff += bytes;
size -= bytes;
}
+
+ nouveau_bufctx_reset(bctx, 0);
}
struct pipe_transfer *
@@ -236,7 +254,6 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
const struct pipe_box *box)
{
struct nv50_context *nv50 = nv50_context(pctx);
- struct pipe_screen *pscreen = pctx->screen;
struct nouveau_device *dev = nv50->screen->base.device;
const struct nv50_miptree *mt = nv50_miptree(res);
struct nv50_transfer *tx;
@@ -272,7 +289,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
size = tx->base.layer_stride;
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
- size * tx->base.box.depth, &tx->rect[1].bo);
+ size * tx->base.box.depth, NULL, &tx->rect[1].bo);
if (ret) {
FREE(tx);
return NULL;
@@ -290,7 +307,7 @@ nv50_miptree_transfer_new(struct pipe_context *pctx,
unsigned z = tx->rect[0].z;
unsigned i;
for (i = 0; i < box->depth; ++i) {
- nv50_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
+ nv50_m2mf_transfer_rect(nv50, &tx->rect[1], &tx->rect[0],
tx->nblocksx, tx->nblocksy);
if (mt->layout_3d)
tx->rect[0].z++;
@@ -310,14 +327,14 @@ void
nv50_miptree_transfer_del(struct pipe_context *pctx,
struct pipe_transfer *transfer)
{
- struct pipe_screen *pscreen = pctx->screen;
+ struct nv50_context *nv50 = nv50_context(pctx);
struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
unsigned i;
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
for (i = 0; i < tx->base.box.depth; ++i) {
- nv50_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
+ nv50_m2mf_transfer_rect(nv50, &tx->rect[0], &tx->rect[1],
tx->nblocksx, tx->nblocksy);
if (mt->layout_3d)
tx->rect[0].z++;
@@ -337,6 +354,7 @@ void *
nv50_miptree_transfer_map(struct pipe_context *pctx,
struct pipe_transfer *transfer)
{
+ struct nv50_screen *screen = nv50_screen(pctx->screen);
struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
int ret;
unsigned flags = 0;
@@ -349,7 +367,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
if (transfer->usage & PIPE_TRANSFER_WRITE)
flags |= NOUVEAU_BO_WR;
- ret = nouveau_bo_map(tx->rect[1].bo, flags);
+ ret = nouveau_bo_map(tx->rect[1].bo, flags, screen->base.client);
if (ret)
return NULL;
return tx->rect[1].bo->map;
@@ -359,9 +377,7 @@ void
nv50_miptree_transfer_unmap(struct pipe_context *pctx,
struct pipe_transfer *transfer)
{
- struct nv50_transfer *tx = (struct nv50_transfer *)transfer;
-
- nouveau_bo_unmap(tx->rect[1].bo);
+ /* nothing to do */
}
void
@@ -370,30 +386,36 @@ nv50_cb_push(struct nouveau_context *nv,
unsigned base, unsigned size,
unsigned offset, unsigned words, const uint32_t *data)
{
- struct nouveau_channel *chan = nv->screen->channel;
+ struct nouveau_pushbuf *push = nv->pushbuf;
+ struct nouveau_bufctx *bctx = nv50_context(&nv->pipe)->bufctx;
assert(!(offset & 3));
size = align(size, 0x100);
+ nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
+ nouveau_pushbuf_bufctx(push, bctx);
+ nouveau_pushbuf_validate(push);
+
while (words) {
unsigned nr;
- MARK_RING(chan, 24, 2);
- nr = AVAIL_RING(chan);
+ nr = PUSH_AVAIL(push);
nr = MIN2(nr - 7, words);
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
- BEGIN_RING(chan, RING_3D(CB_DEF_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR);
- OUT_RING (chan, (NV50_CB_TMP << 16) | (size & 0xffff));
- BEGIN_RING(chan, RING_3D(CB_ADDR), 1);
- OUT_RING (chan, (offset << 6) | NV50_CB_TMP);
- BEGIN_RING_NI(chan, RING_3D(CB_DATA(0)), nr);
- OUT_RINGp (chan, data, nr);
+ BEGIN_NV04(push, NV50_3D(CB_DEF_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, bo->offset + base);
+ PUSH_DATA (push, bo->offset + base);
+ PUSH_DATA (push, (NV50_CB_TMP << 16) | (size & 0xffff));
+ BEGIN_NV04(push, NV50_3D(CB_ADDR), 1);
+ PUSH_DATA (push, (offset << 6) | NV50_CB_TMP);
+ BEGIN_NI04(push, NV50_3D(CB_DATA(0)), nr);
+ PUSH_DATAp(push, data, nr);
words -= nr;
data += nr;
offset += nr * 4;
}
+
+ nouveau_bufctx_reset(bctx, 0);
}
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index cb3ea382f3d..9be43ef15d4 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -124,7 +124,7 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
struct pipe_vertex_element *ve, unsigned attr)
{
const void *data;
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv04_resource *res = nv04_resource(vb->buffer);
float v[4];
const unsigned nc = util_format_get_nr_components(ve->src_format);
@@ -136,30 +136,30 @@ nv50_emit_vtxattr(struct nv50_context *nv50, struct pipe_vertex_buffer *vb,
switch (nc) {
case 4:
- BEGIN_RING(chan, RING_3D(VTX_ATTR_4F_X(attr)), 4);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
- OUT_RINGf (chan, v[3]);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_4F_X(attr)), 4);
+ PUSH_DATAf(push, v[0]);
+ PUSH_DATAf(push, v[1]);
+ PUSH_DATAf(push, v[2]);
+ PUSH_DATAf(push, v[3]);
break;
case 3:
- BEGIN_RING(chan, RING_3D(VTX_ATTR_3F_X(attr)), 3);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
- OUT_RINGf (chan, v[2]);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_3F_X(attr)), 3);
+ PUSH_DATAf(push, v[0]);
+ PUSH_DATAf(push, v[1]);
+ PUSH_DATAf(push, v[2]);
break;
case 2:
- BEGIN_RING(chan, RING_3D(VTX_ATTR_2F_X(attr)), 2);
- OUT_RINGf (chan, v[0]);
- OUT_RINGf (chan, v[1]);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_2F_X(attr)), 2);
+ PUSH_DATAf(push, v[0]);
+ PUSH_DATAf(push, v[1]);
break;
case 1:
if (attr == nv50->vertprog->vp.edgeflag) {
- BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
- OUT_RING (chan, v[0] ? 1 : 0);
+ BEGIN_NV04(push, NV50_3D(EDGEFLAG), 1);
+ PUSH_DATA (push, v[0] ? 1 : 0);
}
- BEGIN_RING(chan, RING_3D(VTX_ATTR_1F(attr)), 1);
- OUT_RINGf (chan, v[0]);
+ BEGIN_NV04(push, NV50_3D(VTX_ATTR_1F(attr)), 1);
+ PUSH_DATAf(push, v[0]);
break;
default:
assert(0);
@@ -193,7 +193,7 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50)
nv50->vbo_fifo = nv50->vbo_user = 0;
- nv50_bufctx_reset(nv50, NV50_BUFCTX_VERTEX);
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
for (i = 0; i < nv50->num_vtxbufs; ++i) {
vb = &nv50->vtxbuf[i];
@@ -211,33 +211,37 @@ nv50_prevalidate_vbufs(struct nv50_context *nv50)
nv50->vbo_user |= 1 << i;
assert(vb->stride > vb->buffer_offset);
nv50_vbuf_range(nv50, i, &base, &size);
- nouveau_user_buffer_upload(buf, base, size);
+ nouveau_user_buffer_upload(&nv50->base, buf, base, size);
} else {
nouveau_buffer_migrate(&nv50->base, buf, NOUVEAU_BO_GART);
}
nv50->base.vbo_dirty = TRUE;
}
}
- nv50_bufctx_add_resident(nv50, NV50_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
+ BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
}
}
static void
nv50_update_user_vbufs(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
uint32_t base, offset, size;
int i;
uint32_t written = 0;
+ nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_VERTEX);
+
for (i = 0; i < nv50->vertex->num_elements; ++i) {
struct pipe_vertex_element *ve = &nv50->vertex->element[i].pipe;
const int b = ve->vertex_buffer_index;
struct pipe_vertex_buffer *vb = &nv50->vtxbuf[b];
struct nv04_resource *buf = nv04_resource(vb->buffer);
- if (!(nv50->vbo_user & (1 << b)))
+ if (!(nv50->vbo_user & (1 << b))) {
+ BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
continue;
+ }
if (!vb->stride) {
nv50_emit_vtxattr(nv50, vb, ve, i);
@@ -247,17 +251,18 @@ nv50_update_user_vbufs(struct nv50_context *nv50)
if (!(written & (1 << b))) {
written |= 1 << b;
- nouveau_user_buffer_upload(buf, base, size);
+ nouveau_user_buffer_upload(&nv50->base, buf, base, size);
}
offset = vb->buffer_offset + ve->src_offset;
- MARK_RING (chan, 6, 4);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
- OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
- OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
+ PUSH_DATAh(push, buf->address + base + size - 1);
+ PUSH_DATA (push, buf->address + base + size - 1);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
+ PUSH_DATAh(push, buf->address + offset);
+ PUSH_DATA (push, buf->address + offset);
+
+ BCTX_REFN(nv50->bufctx_3d, VERTEX, buf, RD);
}
nv50->base.vbo_dirty = TRUE;
}
@@ -278,7 +283,7 @@ nv50_release_user_vbufs(struct nv50_context *nv50)
void
nv50_vertex_arrays_validate(struct nv50_context *nv50)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_vertex_stateobj *vertex = nv50->vertex;
struct pipe_vertex_buffer *vb;
struct nv50_vertex_element *ve;
@@ -291,15 +296,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
nv50_prevalidate_vbufs(nv50);
}
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(0)), vertex->num_elements);
for (i = 0; i < vertex->num_elements; ++i) {
ve = &vertex->element[i];
vb = &nv50->vtxbuf[ve->pipe.vertex_buffer_index];
if (likely(vb->stride) || nv50->vbo_fifo) {
- OUT_RING(chan, ve->state);
+ PUSH_DATA(push, ve->state);
} else {
- OUT_RING(chan, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
+ PUSH_DATA(push, ve->state | NV50_3D_VERTEX_ARRAY_ATTRIB_CONST);
nv50->vbo_fifo &= ~(1 << i);
}
}
@@ -313,15 +318,15 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
if (unlikely(ve->pipe.instance_divisor)) {
if (!(nv50->state.instance_elts & (1 << i))) {
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
- OUT_RING (chan, 1);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+ PUSH_DATA (push, 1);
}
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
- OUT_RING (chan, ve->pipe.instance_divisor);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
+ PUSH_DATA (push, ve->pipe.instance_divisor);
} else
if (unlikely(nv50->state.instance_elts & (1 << i))) {
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+ PUSH_DATA (push, 0);
}
res = nv04_resource(vb->buffer);
@@ -329,33 +334,32 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
if (nv50->vbo_fifo || unlikely(vb->stride == 0)) {
if (!nv50->vbo_fifo)
nv50_emit_vtxattr(nv50, vb, &ve->pipe, i);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
+ PUSH_DATA (push, 0);
continue;
}
size = vb->buffer->width0;
offset = ve->pipe.src_offset + vb->buffer_offset;
- MARK_RING (chan, 8, 4);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
- OUT_RING (chan, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
- OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
- OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
+ PUSH_DATA (push, NV50_3D_VERTEX_ARRAY_FETCH_ENABLE | vb->stride);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_LIMIT_HIGH(i)), 2);
+ PUSH_DATAh(push, res->address + size - 1);
+ PUSH_DATA (push, res->address + size - 1);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_START_HIGH(i)), 2);
+ PUSH_DATAh(push, res->address + offset);
+ PUSH_DATA (push, res->address + offset);
}
for (; i < nv50->state.num_vtxelts; ++i) {
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_ATTRIB(i)), 1);
- OUT_RING (chan, NV50_3D_VERTEX_ATTRIB_INACTIVE);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_ATTRIB(i)), 1);
+ PUSH_DATA (push, NV50_3D_VERTEX_ATTRIB_INACTIVE);
if (unlikely(nv50->state.instance_elts & (1 << i))) {
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+ PUSH_DATA (push, 0);
}
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FETCH(i)), 1);
+ PUSH_DATA (push, 0);
}
nv50->state.num_vtxelts = vertex->num_elements;
@@ -390,64 +394,54 @@ nv50_prim_gl(unsigned prim)
}
static void
-nv50_draw_vbo_flush_notify(struct nouveau_channel *chan)
-{
- struct nv50_screen *screen = chan->user_private;
-
- nouveau_fence_update(&screen->base, TRUE);
-
- nv50_bufctx_emit_relocs(screen->cur_ctx);
-}
-
-static void
nv50_draw_arrays(struct nv50_context *nv50,
unsigned mode, unsigned start, unsigned count,
unsigned instance_count)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
unsigned prim;
if (nv50->state.index_bias) {
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
+ PUSH_DATA (push, 0);
nv50->state.index_bias = 0;
}
prim = nv50_prim_gl(mode);
while (instance_count--) {
- BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (chan, prim);
- BEGIN_RING(chan, RING_3D(VERTEX_BUFFER_FIRST), 2);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (push, prim);
+ BEGIN_NV04(push, NV50_3D(VERTEX_BUFFER_FIRST), 2);
+ PUSH_DATA (push, start);
+ PUSH_DATA (push, count);
+ BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+ PUSH_DATA (push, 0);
prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
}
static void
-nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
+nv50_draw_elements_inline_u08(struct nouveau_pushbuf *push, uint8_t *map,
unsigned start, unsigned count)
{
map += start;
if (count & 3) {
unsigned i;
- BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), count & 3);
+ BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), count & 3);
for (i = 0; i < (count & 3); ++i)
- OUT_RING(chan, *map++);
+ PUSH_DATA(push, *map++);
count &= ~3;
}
while (count) {
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 4) / 4;
- BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U8), nr);
+ BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U8), nr);
for (i = 0; i < nr; ++i) {
- OUT_RING(chan,
- (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
+ PUSH_DATA(push,
+ (map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
map += 4;
}
count -= nr * 4;
@@ -455,22 +449,22 @@ nv50_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
}
static void
-nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
+nv50_draw_elements_inline_u16(struct nouveau_pushbuf *push, uint16_t *map,
unsigned start, unsigned count)
{
map += start;
if (count & 1) {
count &= ~1;
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
- OUT_RING (chan, *map++);
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
+ PUSH_DATA (push, *map++);
}
while (count) {
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
- BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+ BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
for (i = 0; i < nr; ++i) {
- OUT_RING(chan, (map[1] << 16) | map[0]);
+ PUSH_DATA(push, (map[1] << 16) | map[0]);
map += 2;
}
count -= nr * 2;
@@ -478,7 +472,7 @@ nv50_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
}
static void
-nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
+nv50_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
unsigned start, unsigned count)
{
map += start;
@@ -486,8 +480,8 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
while (count) {
const unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN);
- BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U32), nr);
- OUT_RINGp (chan, map, nr);
+ BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U32), nr);
+ PUSH_DATAp(push, map, nr);
map += nr;
count -= nr;
@@ -495,22 +489,22 @@ nv50_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
}
static void
-nv50_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map,
+nv50_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, uint32_t *map,
unsigned start, unsigned count)
{
map += start;
if (count & 1) {
count--;
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32), 1);
- OUT_RING (chan, *map++);
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U32), 1);
+ PUSH_DATA (push, *map++);
}
while (count) {
unsigned i, nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN * 2) / 2;
- BEGIN_RING_NI(chan, RING_3D(VB_ELEMENT_U16), nr);
+ BEGIN_NI04(push, NV50_3D(VB_ELEMENT_U16), nr);
for (i = 0; i < nr; ++i) {
- OUT_RING(chan, (map[1] << 16) | map[0]);
+ PUSH_DATA(push, (map[1] << 16) | map[0]);
map += 2;
}
count -= nr * 2;
@@ -522,121 +516,116 @@ nv50_draw_elements(struct nv50_context *nv50, boolean shorten,
unsigned mode, unsigned start, unsigned count,
unsigned instance_count, int32_t index_bias)
{
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
void *data;
+ struct nv04_resource *buf = nv04_resource(nv50->idxbuf.buffer);
unsigned prim;
const unsigned index_size = nv50->idxbuf.index_size;
prim = nv50_prim_gl(mode);
if (index_bias != nv50->state.index_bias) {
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
- OUT_RING (chan, index_bias);
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_BASE), 1);
+ PUSH_DATA (push, index_bias);
nv50->state.index_bias = index_bias;
}
if (nouveau_resource_mapped_by_gpu(nv50->idxbuf.buffer)) {
- struct nv04_resource *res = nv04_resource(nv50->idxbuf.buffer);
+ unsigned pb_start;
+ unsigned pb_bytes;
+ const unsigned base = buf->offset;
start += nv50->idxbuf.offset >> (index_size >> 1);
while (instance_count--) {
- BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (chan, mode);
+ BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (push, prim);
+
+ nouveau_pushbuf_space(push, 8, 0, 1);
switch (index_size) {
case 4:
- {
- WAIT_RING (chan, 2);
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U32) | 0x30000, 0);
- OUT_RING (chan, count);
- nouveau_pushbuf_submit(chan, res->bo, res->offset + start * 4,
- count * 4);
- }
+ BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U32), count);
+ nouveau_pushbuf_data(push, buf->bo, base + start * 4, count * 4);
break;
case 2:
- {
- unsigned pb_start = (start & ~1);
- unsigned pb_words = (((start + count + 1) & ~1) - pb_start) >> 1;
-
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
- OUT_RING (chan, (start << 31) | count);
- WAIT_RING (chan, 2);
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16) | 0x30000, 0);
- OUT_RING (chan, pb_words);
- nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start * 2,
- pb_words * 4);
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U16_SETUP), 1);
- OUT_RING (chan, 0);
- break;
- }
- case 1:
- {
- unsigned pb_start = (start & ~3);
- unsigned pb_words = (((start + count + 3) & ~3) - pb_start) >> 1;
-
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
- OUT_RING (chan, (start << 30) | count);
- WAIT_RING (chan, 2);
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8) | 0x30000, 0);
- OUT_RING (chan, pb_words);
- nouveau_pushbuf_submit(chan, res->bo, res->offset + pb_start,
- pb_words * 4);
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_U8_SETUP), 1);
- OUT_RING (chan, 0);
+ pb_start = (start & ~1) * 2;
+ pb_bytes = ((start + count + 1) & ~1) * 2 - pb_start;
+
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
+ PUSH_DATA (push, (start << 31) | count);
+ BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U16), pb_bytes / 4);
+ nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U16_SETUP), 1);
+ PUSH_DATA (push, 0);
break;
- }
default:
- assert(0);
- return;
+ assert(index_size == 1);
+ pb_start = start & ~3;
+ pb_bytes = ((start + count + 3) & ~3) - pb_start;
+
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
+ PUSH_DATA (push, (start << 30) | count);
+ BEGIN_NL50(push, NV50_3D(VB_ELEMENT_U8), pb_bytes / 4);
+ nouveau_pushbuf_data(push, buf->bo, base + pb_start, pb_bytes);
+ BEGIN_NV04(push, NV50_3D(VB_ELEMENT_U8_SETUP), 1);
+ PUSH_DATA (push, 0);
+ break;
}
- BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+ PUSH_DATA (push, 0);
- nv50_resource_fence(res, NOUVEAU_BO_RD);
-
- mode |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
+ prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
} else {
- data = nouveau_resource_map_offset(&nv50->base,
- nv04_resource(nv50->idxbuf.buffer),
+ data = nouveau_resource_map_offset(&nv50->base, buf,
nv50->idxbuf.offset, NOUVEAU_BO_RD);
if (!data)
return;
while (instance_count--) {
- BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (chan, prim);
+ BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (push, prim);
switch (index_size) {
case 1:
- nv50_draw_elements_inline_u08(chan, data, start, count);
+ nv50_draw_elements_inline_u08(push, data, start, count);
break;
case 2:
- nv50_draw_elements_inline_u16(chan, data, start, count);
+ nv50_draw_elements_inline_u16(push, data, start, count);
break;
case 4:
if (shorten)
- nv50_draw_elements_inline_u32_short(chan, data, start, count);
+ nv50_draw_elements_inline_u32_short(push, data, start, count);
else
- nv50_draw_elements_inline_u32(chan, data, start, count);
+ nv50_draw_elements_inline_u32(push, data, start, count);
break;
default:
assert(0);
return;
}
- BEGIN_RING(chan, RING_3D(VERTEX_END_GL), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
+ PUSH_DATA (push, 0);
prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
}
}
+static void
+nv50_draw_vbo_kick_notify(struct nouveau_pushbuf *chan)
+{
+ struct nv50_screen *screen = chan->user_priv;
+
+ nouveau_fence_update(&screen->base, TRUE);
+
+ nv50_bufctx_fence(screen->cur_ctx->bufctx_3d, TRUE);
+}
+
void
nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_pushbuf *push = nv50->base.pushbuf;
/* For picking only a few vertices from a large user buffer, push is better,
* if index count is larger and we expect repeated vertices, suggest upload.
@@ -656,24 +645,25 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv50_state_validate(nv50, ~0, 8); /* 8 as minimum, we use flush_notify */
- chan->flush_notify = nv50_draw_vbo_flush_notify;
+ push->kick_notify = nv50_draw_vbo_kick_notify;
if (nv50->vbo_fifo) {
nv50_push_vbo(nv50, info);
- chan->flush_notify = nv50_default_flush_notify;
+ push->kick_notify = nv50_default_kick_notify;
+ nouveau_pushbuf_bufctx(push, NULL);
return;
}
if (nv50->state.instance_base != info->start_instance) {
nv50->state.instance_base = info->start_instance;
/* NOTE: this does not affect the shader input, should it ? */
- BEGIN_RING(chan, RING_3D(VB_INSTANCE_BASE), 1);
- OUT_RING (chan, info->start_instance);
+ BEGIN_NV04(push, NV50_3D(VB_INSTANCE_BASE), 1);
+ PUSH_DATA (push, info->start_instance);
}
if (nv50->base.vbo_dirty) {
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FLUSH), 1);
+ PUSH_DATA (push, 0);
nv50->base.vbo_dirty = FALSE;
}
@@ -688,21 +678,21 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (info->primitive_restart != nv50->state.prim_restart) {
if (info->primitive_restart) {
- BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 2);
- OUT_RING (chan, 1);
- OUT_RING (chan, info->restart_index);
+ BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 2);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, info->restart_index);
if (info->restart_index > 65535)
shorten = FALSE;
} else {
- BEGIN_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NV04(push, NV50_3D(PRIM_RESTART_ENABLE), 1);
+ PUSH_DATA (push, 0);
}
nv50->state.prim_restart = info->primitive_restart;
} else
if (info->primitive_restart) {
- BEGIN_RING(chan, RING_3D(PRIM_RESTART_INDEX), 1);
- OUT_RING (chan, info->restart_index);
+ BEGIN_NV04(push, NV50_3D(PRIM_RESTART_INDEX), 1);
+ PUSH_DATA (push, info->restart_index);
if (info->restart_index > 65535)
shorten = FALSE;
@@ -712,7 +702,9 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
info->mode, info->start, info->count,
info->instance_count, info->index_bias);
}
- chan->flush_notify = nv50_default_flush_notify;
+ push->kick_notify = nv50_default_kick_notify;
nv50_release_user_vbufs(nv50);
+
+ nouveau_pushbuf_bufctx(push, NULL);
}
diff --git a/src/gallium/drivers/nv50/nv50_winsys.h b/src/gallium/drivers/nv50/nv50_winsys.h
index 694c78a2fbd..b36898dabe6 100644
--- a/src/gallium/drivers/nv50/nv50_winsys.h
+++ b/src/gallium/drivers/nv50/nv50_winsys.h
@@ -7,100 +7,118 @@
#include "pipe/p_defines.h"
-#include "nouveau/nouveau_bo.h"
-#include "nouveau/nouveau_channel.h"
-#include "nouveau/nouveau_grobj.h"
-#include "nouveau/nouveau_device.h"
-#include "nouveau/nouveau_resource.h"
-#include "nouveau/nouveau_pushbuf.h"
-#include "nouveau/nouveau_reloc.h"
-#include "nouveau/nouveau_notifier.h"
-
+#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_buffer.h"
+
#ifndef NV04_PFIFO_MAX_PACKET_LEN
#define NV04_PFIFO_MAX_PACKET_LEN 2047
#endif
-#define NV50_SUBCH_3D 5
-#define NV50_SUBCH_2D 6
-#define NV50_SUBCH_MF 7
-#define NV50_MF_(n) NV50_M2MF_##n
+static INLINE void
+nv50_add_bufctx_resident_bo(struct nouveau_bufctx *bufctx, int bin,
+ unsigned flags, struct nouveau_bo *bo)
+{
+ nouveau_bufctx_refn(bufctx, bin, bo, flags)->priv = NULL;
+}
+
+static INLINE void
+nv50_add_bufctx_resident(struct nouveau_bufctx *bufctx, int bin,
+ struct nv04_resource *res, unsigned flags)
+{
+ struct nouveau_bufref *ref =
+ nouveau_bufctx_refn(bufctx, bin, res->bo, flags | res->domain);
+ ref->priv = res;
+ ref->priv_data = flags;
+}
+
+#define BCTX_REFN_bo(ctx, bin, fl, bo) \
+ nv50_add_bufctx_resident_bo(ctx, NV50_BIND_##bin, fl, bo);
+
+#define BCTX_REFN(bctx, bin, res, acc) \
+ nv50_add_bufctx_resident(bctx, NV50_BIND_##bin, res, NOUVEAU_BO_##acc)
+
+static INLINE void
+PUSH_REFN(struct nouveau_pushbuf *push, struct nouveau_bo *bo, uint32_t flags)
+{
+ struct nouveau_pushbuf_refn ref = { bo, flags };
+ nouveau_pushbuf_refn(push, &ref, 1);
+}
+
+
+#define SUBC_3D(m) 3, (m)
+#define NV50_3D(n) SUBC_3D(NV50_3D_##n)
-#define RING_3D(n) ((NV50_SUBCH_3D << 13) | NV50_3D_##n)
-#define RING_2D(n) ((NV50_SUBCH_2D << 13) | NV50_2D_##n)
-#define RING_MF(n) ((NV50_SUBCH_MF << 13) | NV50_MF_(n))
+#define SUBC_2D(m) 4, (m)
+#define NV50_2D(n) SUBC_2D(NV50_2D_##n)
-#define RING_3D_(m) ((NV50_SUBCH_3D << 13) | (m))
-#define RING_2D_(m) ((NV50_SUBCH_2D << 13) | (m))
-#define RING_MF_(m) ((NV50_SUBCH_MF << 13) | (m))
+#define SUBC_M2MF(m) 5, (m)
+#define NV50_M2MF(n) SUBC_M2MF(NV50_M2MF_##n)
-#define RING_GR(gr, m) (((gr)->subc << 13) | (m))
+#define SUBC_COMPUTE(m) 6, (m)
+#define NV50_COMPUTE(n) SUBC_COMPUTE(NV50_COMPUTE_##n)
-int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
-static inline uint32_t
-nouveau_bo_tile_layout(const struct nouveau_bo *bo)
+static INLINE uint32_t
+NV50_FIFO_PKHDR(int subc, int mthd, unsigned size)
{
- return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
+ return 0x00000000 | (size << 18) | (subc << 13) | mthd;
}
-static INLINE void
-nouveau_bo_validate(struct nouveau_channel *chan,
- struct nouveau_bo *bo, unsigned flags)
+static INLINE uint32_t
+NV50_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
{
- nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0);
+ return 0x40000000 | (size << 18) | (subc << 13) | mthd;
}
-/* incremental methods */
-static INLINE void
-BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+static INLINE uint32_t
+NV50_FIFO_PKHDR_L(int subc, int mthd)
{
- WAIT_RING(chan, size + 1);
- OUT_RING (chan, (size << 18) | mthd);
+ return 0x00030000 | (subc << 13) | mthd;
}
-/* non-incremental */
-static INLINE void
-BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+
+static INLINE uint32_t
+nouveau_bo_memtype(const struct nouveau_bo *bo)
{
- WAIT_RING(chan, size + 1);
- OUT_RING (chan, (0x2 << 29) | (size << 18) | mthd);
+ return bo->config.nv50.memtype;
}
-static INLINE int
-OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res,
- unsigned delta, unsigned flags)
+
+static INLINE void
+PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data)
{
- return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
+ *push->cur++ = (uint32_t)(data >> 32);
}
-static INLINE int
-OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
- unsigned delta, unsigned flags)
+static INLINE void
+BEGIN_NV04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
{
- if (flags & NOUVEAU_BO_WR)
- res->status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
- return OUT_RELOCl(chan, res->bo, res->offset + delta, res->domain | flags);
+#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
+ PUSH_SPACE(push, size + 1);
+#endif
+ PUSH_DATA (push, NV50_FIFO_PKHDR(subc, mthd, size));
}
static INLINE void
-BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s)
+BEGIN_NI04(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
{
- struct nouveau_subchannel *subc = &gr->channel->subc[s];
-
- assert(s < 8);
- if (subc->gr) {
- assert(subc->gr->bound != NOUVEAU_GROBJ_BOUND_EXPLICIT);
- subc->gr->bound = NOUVEAU_GROBJ_UNBOUND;
- }
- subc->gr = gr;
- subc->gr->subc = s;
- subc->gr->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
-
- BEGIN_RING(chan, RING_GR(gr, 0x0000), 1);
- OUT_RING (chan, gr->handle);
+#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
+ PUSH_SPACE(push, size + 1);
+#endif
+ PUSH_DATA (push, NV50_FIFO_PKHDR_NI(subc, mthd, size));
}
+/* long, non-incremental, nv50-only */
+static INLINE void
+BEGIN_NL50(struct nouveau_pushbuf *push, int subc, int mthd, uint32_t size)
+{
+#ifndef NV50_PUSH_EXPLICIT_SPACE_CHECKING
+ PUSH_SPACE(push, 2);
#endif
+ PUSH_DATA (push, NV50_FIFO_PKHDR_L(subc, mthd));
+ PUSH_DATA (push, size);
+}
+
+#endif /* __NV50_WINSYS_H__ */