summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvc0
diff options
context:
space:
mode:
authorChristoph Bumiller <[email protected]>2012-04-06 15:41:55 +0200
committerBen Skeggs <[email protected]>2012-04-14 02:56:33 +1000
commit6d1cdec3ba151168bfc3aef222fba6265dfb41fb (patch)
treec8c013eaa14e1b7463b6b3f39221524d901370f6 /src/gallium/drivers/nvc0
parent3c7872f35f4ae439082d413ab31333cf99be7e91 (diff)
nouveau: switch to libdrm_nouveau-2.0
Diffstat (limited to 'src/gallium/drivers/nvc0')
-rw-r--r--src/gallium/drivers/nvc0/nvc0_3d.xml.h41
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.c147
-rw-r--r--src/gallium/drivers/nvc0/nvc0_context.h60
-rw-r--r--src/gallium/drivers/nvc0/nvc0_miptree.c81
-rw-r--r--src/gallium/drivers/nvc0/nvc0_program.c30
-rw-r--r--src/gallium/drivers/nvc0/nvc0_program.h3
-rw-r--r--src/gallium/drivers/nvc0/nvc0_push.c76
-rw-r--r--src/gallium/drivers/nvc0/nvc0_query.c188
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c504
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.h20
-rw-r--r--src/gallium/drivers/nvc0/nvc0_shader_state.c216
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c20
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state_validate.c322
-rw-r--r--src/gallium/drivers/nvc0/nvc0_stateobj.h6
-rw-r--r--src/gallium/drivers/nvc0/nvc0_surface.c400
-rw-r--r--src/gallium/drivers/nvc0/nvc0_tex.c100
-rw-r--r--src/gallium/drivers/nvc0/nvc0_transfer.c257
-rw-r--r--src/gallium/drivers/nvc0/nvc0_vbo.c302
-rw-r--r--src/gallium/drivers/nvc0/nvc0_winsys.h157
19 files changed, 1469 insertions, 1461 deletions
diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
index 6a1dff70f76..18d27865d71 100644
--- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h
+++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h
@@ -153,13 +153,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_LOCAL_BASE 0x0000077c
-#define NVC0_3D_LOCAL_ADDRESS_HIGH 0x00000790
+#define NVC0_3D_TEMP_ADDRESS_HIGH 0x00000790
-#define NVC0_3D_LOCAL_ADDRESS_LOW 0x00000794
+#define NVC0_3D_TEMP_ADDRESS_LOW 0x00000794
-#define NVC0_3D_LOCAL_SIZE_HIGH 0x00000798
+#define NVC0_3D_TEMP_SIZE_HIGH 0x00000798
-#define NVC0_3D_LOCAL_SIZE_LOW 0x0000079c
+#define NVC0_3D_TEMP_SIZE_LOW 0x0000079c
+
+#define NVC0_3D_WARP_TEMP_ALLOC 0x000007a0
+
+#define NVC0_3D_ZCULL_WIDTH 0x000007c0
+
+#define NVC0_3D_ZCULL_HEIGHT 0x000007c4
+
+#define NVC0_3D_ZCULL_ADDRESS_HIGH 0x000007e8
+
+#define NVC0_3D_ZCULL_ADDRESS_LOW 0x000007ec
+
+#define NVC0_3D_ZCULL_LIMIT_HIGH 0x000007f0
+
+#define NVC0_3D_ZCULL_LIMIT_LOW 0x000007f4
#define NVC0_3D_RT(i0) (0x00000800 + 0x40*(i0))
#define NVC0_3D_RT__ESIZE 0x00000040
@@ -772,6 +786,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_TIC_LIMIT 0x0000157c
+#define NVC0_3D_ZCULL_REGION 0x00001590
+
#define NVC0_3D_STENCIL_TWO_SIDE_ENABLE 0x00001594
#define NVC0_3D_STENCIL_BACK_OP_FAIL 0x00001598
@@ -856,7 +872,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_VERTEX_END_D3D_UNK0 0x00000001
#define NVC0_3D_VERTEX_END_D3D_UNK1 0x00000002
-#define NVC0_3D_EDGEFLAG_ENABLE 0x000015e4
+#define NVC0_3D_EDGEFLAG 0x000015e4
#define NVC0_3D_VB_ELEMENT_U32 0x000015e8
@@ -876,6 +892,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_VERTEX_BASE_LOW 0x000015f8
+#define NVC0_3D_ZCULL_WINDOW_OFFSET_X 0x000015fc
+
+#define NVC0_3D_ZCULL_WINDOW_OFFSET_Y 0x00001600
+
#define NVC0_3D_POINT_COORD_REPLACE 0x00001604
#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__MASK 0x00000004
#define NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN__SHIFT 2
@@ -1070,6 +1090,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_CLIP_RECTS_MODE_OUTSIDE_ALL 0x00000001
#define NVC0_3D_CLIP_RECTS_MODE_NEVER 0x00000002
+#define NVC0_3D_ZCULL_INVALIDATE 0x00001958
+
+#define NVC0_3D_ZCULL_TEST_MASK 0x0000196c
+#define NVC0_3D_ZCULL_TEST_MASK_FAIL_GT_PASS_LT 0x00000001
+#define NVC0_3D_ZCULL_TEST_MASK_PASS_GT_FAIL_LT 0x00000010
+
#define NVC0_3D_FP_ZORDER_CTRL 0x0000196c
#define NVC0_3D_FP_ZORDER_CTRL_0 0x00000001
#define NVC0_3D_FP_ZORDER_CTRL_1 0x00000010
@@ -1082,11 +1108,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define NVC0_3D_CLIPID_ID 0x00001984
-#define NVC0_3D_FP_CONTROL 0x000019a8
-#define NVC0_3D_FP_CONTROL_MULTIPLE_RESULTS 0x00000001
-#define NVC0_3D_FP_CONTROL_EXPORTS_Z 0x00000100
-#define NVC0_3D_FP_CONTROL_USES_KIL 0x00100000
-
#define NVC0_3D_DEPTH_BOUNDS_EN 0x000019bc
#define NVC0_3D_LOGIC_OP_ENABLE 0x000019c4
diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c
index 1b3a06dfa33..c15d0256c60 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nvc0/nvc0_context.c
@@ -33,26 +33,22 @@ static void
nvc0_flush(struct pipe_context *pipe,
struct pipe_fence_handle **fence)
{
- struct nouveau_screen *screen = &nvc0_context(pipe)->screen->base;
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
+ struct nouveau_screen *screen = &nvc0->screen->base;
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(nvc0->base.pushbuf); /* fencing handled in kick_notify */
}
static void
nvc0_texture_barrier(struct pipe_context *pipe)
{
- struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf;
- IMMED_RING(chan, RING_3D(SERIALIZE), 0);
- IMMED_RING(chan, RING_3D(TEX_CACHE_CTL), 0);
+ IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+ IMMED_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 0);
}
static void
@@ -60,8 +56,8 @@ nvc0_context_unreference_resources(struct nvc0_context *nvc0)
{
unsigned s, i;
- for (i = 0; i < NVC0_BUFCTX_COUNT; ++i)
- nvc0_bufctx_reset(nvc0, i);
+ nouveau_bufctx_del(&nvc0->bufctx_3d);
+ nouveau_bufctx_del(&nvc0->bufctx);
for (i = 0; i < nvc0->num_vtxbufs; ++i)
pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL);
@@ -85,26 +81,31 @@ nvc0_destroy(struct pipe_context *pipe)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
+ if (nvc0->screen->cur_ctx == nvc0) {
+ nvc0->base.pushbuf->kick_notify = NULL;
+ nvc0->screen->cur_ctx = NULL;
+ nouveau_pushbuf_bufctx(nvc0->base.pushbuf, NULL);
+ }
+ nouveau_pushbuf_kick(nvc0->base.pushbuf, nvc0->base.pushbuf->channel);
+
nvc0_context_unreference_resources(nvc0);
draw_destroy(nvc0->draw);
- if (nvc0->screen->cur_ctx == nvc0)
- nvc0->screen->cur_ctx = NULL;
-
FREE(nvc0);
}
void
-nvc0_default_flush_notify(struct nouveau_channel *chan)
+nvc0_default_kick_notify(struct nouveau_pushbuf *push)
{
- struct nvc0_screen *screen = chan->user_private;
-
- if (!screen)
- return;
+ struct nvc0_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;
+ }
}
struct pipe_context *
@@ -113,12 +114,23 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
struct nvc0_screen *screen = nvc0_screen(pscreen);
struct nvc0_context *nvc0;
struct pipe_context *pipe;
+ int ret;
+ uint32_t flags;
nvc0 = CALLOC_STRUCT(nvc0_context);
if (!nvc0)
return NULL;
pipe = &nvc0->base.pipe;
+ nvc0->base.pushbuf = screen->base.pushbuf;
+
+ ret = nouveau_bufctx_new(screen->base.client, NVC0_BIND_COUNT,
+ &nvc0->bufctx_3d);
+ if (!ret)
+ nouveau_bufctx_new(screen->base.client, 2, &nvc0->bufctx);
+ if (ret)
+ goto out_err;
+
nvc0->screen = screen;
nvc0->base.screen = &screen->base;
nvc0->base.copy_data = nvc0_m2mf_copy_linear;
@@ -136,9 +148,11 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
pipe->flush = nvc0_flush;
pipe->texture_barrier = nvc0_texture_barrier;
- if (!screen->cur_ctx)
+ if (!screen->cur_ctx) {
screen->cur_ctx = nvc0;
- screen->base.channel->flush_notify = nvc0_default_flush_notify;
+ nouveau_pushbuf_bufctx(screen->base.pushbuf, nvc0->bufctx);
+ }
+ screen->base.pushbuf->kick_notify = nvc0_default_kick_notify;
nvc0_init_query_functions(nvc0);
nvc0_init_surface_functions(nvc0);
@@ -154,72 +168,43 @@ nvc0_create(struct pipe_screen *pscreen, void *priv)
/* shader builtin library is per-screen, but we need a context for m2mf */
nvc0_program_library_upload(nvc0);
- return pipe;
-}
+ /* add permanently resident buffers to bufctxts */
-struct resident {
- struct nv04_resource *res;
- uint32_t flags;
-};
+ flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-void
-nvc0_bufctx_add_resident(struct nvc0_context *nvc0, int ctx,
- struct nv04_resource *resource, uint32_t flags)
-{
- struct resident rsd = { resource, flags };
+ BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->text);
+ BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->uniforms);
+ BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->txc);
- if (!resource->bo)
- return;
- nvc0->residents_size += sizeof(struct resident);
+ flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
- /* 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(&nvc0->residents[ctx], struct resident, rsd);
-}
+ BCTX_REFN_bo(nvc0->bufctx_3d, SCREEN, flags, screen->fence.bo);
+ BCTX_REFN_bo(nvc0->bufctx, FENCE, flags, screen->fence.bo);
-void
-nvc0_bufctx_del_resident(struct nvc0_context *nvc0, int ctx,
- struct nv04_resource *resource)
-{
- struct resident *rsd, *top;
- unsigned i;
-
- for (i = 0; i < nvc0->residents[ctx].size / sizeof(struct resident); ++i) {
- rsd = util_dynarray_element(&nvc0->residents[ctx], struct resident, i);
-
- if (rsd->res == resource) {
- top = util_dynarray_pop_ptr(&nvc0->residents[ctx], struct resident);
- if (rsd != top)
- *rsd = *top;
- nvc0->residents_size -= sizeof(struct resident);
- break;
- }
+ return pipe;
+
+out_err:
+ if (nvc0) {
+ if (nvc0->bufctx_3d)
+ nouveau_bufctx_del(&nvc0->bufctx_3d);
+ if (nvc0->bufctx)
+ nouveau_bufctx_del(&nvc0->bufctx);
+ FREE(nvc0);
}
+ return NULL;
}
void
-nvc0_bufctx_emit_relocs(struct nvc0_context *nvc0)
+nvc0_bufctx_fence(struct nvc0_context *nvc0, struct nouveau_bufctx *bufctx,
+ boolean on_flush)
{
- struct resident *rsd;
- struct util_dynarray *array;
- unsigned ctx, i, n;
-
- n = nvc0->residents_size / sizeof(struct resident);
- n += NVC0_SCREEN_RESIDENT_BO_COUNT;
-
- MARK_RING(nvc0->screen->base.channel, 0, n);
-
- for (ctx = 0; ctx < NVC0_BUFCTX_COUNT; ++ctx) {
- array = &nvc0->residents[ctx];
-
- n = array->size / sizeof(struct resident);
- for (i = 0; i < n; ++i) {
- rsd = util_dynarray_element(array, struct resident, i);
-
- nvc0_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)
+ nvc0_resource_validate(res, (unsigned)ref->priv_data);
}
-
- nvc0_screen_make_buffers_resident(nvc0->screen);
}
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index b8f0d92b6b4..4b35330ef8a 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -50,32 +50,40 @@
#define NVC0_NEW_TEXTURES (1 << 19)
#define NVC0_NEW_SAMPLERS (1 << 20)
#define NVC0_NEW_TFB_TARGETS (1 << 21)
-
-#define NVC0_BUFCTX_CONSTANT 0
-#define NVC0_BUFCTX_FRAME 1
-#define NVC0_BUFCTX_VERTEX 2
-#define NVC0_BUFCTX_TEXTURES 3
-#define NVC0_BUFCTX_TFB 4
-#define NVC0_BUFCTX_COUNT 5
+#define NVC0_NEW_IDXBUF (1 << 22)
+
+#define NVC0_BIND_FB 0
+#define NVC0_BIND_VTX 1
+#define NVC0_BIND_IDX 2
+#define NVC0_BIND_TEX 3
+#define NVC0_BIND_CB(s, i) (4 + 16 * (s) + (i))
+#define NVC0_BIND_TFB 84
+#define NVC0_BIND_SCREEN 85
+#define NVC0_BIND_TLS 86
+#define NVC0_BIND_COUNT 87
+#define NVC0_BIND_2D 0
+#define NVC0_BIND_M2MF 0
+#define NVC0_BIND_FENCE 1
struct nvc0_context {
struct nouveau_context base;
- struct nvc0_screen *screen;
+ struct nouveau_bufctx *bufctx_3d;
+ struct nouveau_bufctx *bufctx;
- struct util_dynarray residents[NVC0_BUFCTX_COUNT];
- unsigned residents_size;
+ struct nvc0_screen *screen;
uint32_t dirty;
struct {
+ boolean flushed;
+ boolean rasterizer_discard;
+ boolean early_z;
+ boolean prim_restart;
uint32_t instance_elts; /* bitmask of per-instance elements */
uint32_t instance_base;
int32_t index_bias;
- boolean prim_restart;
- boolean early_z;
uint16_t scissor;
- boolean rasterizer_discard;
uint8_t num_vtxbufs;
uint8_t num_vtxelts;
uint8_t num_textures[5];
@@ -142,20 +150,9 @@ nvc0_context(struct pipe_context *pipe)
/* nvc0_context.c */
struct pipe_context *nvc0_create(struct pipe_screen *, void *);
-
-void nvc0_default_flush_notify(struct nouveau_channel *);
-
-void nvc0_bufctx_emit_relocs(struct nvc0_context *);
-void nvc0_bufctx_add_resident(struct nvc0_context *, int ctx,
- struct nv04_resource *, uint32_t flags);
-void nvc0_bufctx_del_resident(struct nvc0_context *, int ctx,
- struct nv04_resource *);
-static INLINE void
-nvc0_bufctx_reset(struct nvc0_context *nvc0, int ctx)
-{
- nvc0->residents_size -= nvc0->residents[ctx].size;
- util_dynarray_resize(&nvc0->residents[ctx], 0);
-}
+void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *,
+ boolean on_flush);
+void nvc0_default_kick_notify(struct nouveau_pushbuf *);
/* nvc0_draw.c */
extern struct draw_stage *nvc0_draw_render_stage(struct nvc0_context *);
@@ -168,9 +165,9 @@ void nvc0_program_library_upload(struct nvc0_context *);
/* nvc0_query.c */
void nvc0_init_query_functions(struct nvc0_context *);
-void nvc0_query_pushbuf_submit(struct nouveau_channel *,
+void nvc0_query_pushbuf_submit(struct nouveau_pushbuf *,
struct pipe_query *, unsigned result_offset);
-void nvc0_query_fifo_wait(struct nouveau_channel *, struct pipe_query *);
+void nvc0_query_fifo_wait(struct nouveau_pushbuf *, struct pipe_query *);
void nvc0_so_target_save_offset(struct pipe_context *,
struct pipe_stream_output_target *, unsigned i,
boolean *serialize);
@@ -210,7 +207,7 @@ nvc0_create_sampler_view(struct pipe_context *,
/* nvc0_transfer.c */
void
-nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nvc0_m2mf_transfer_rect(struct nvc0_context *,
const struct nv50_m2mf_rect *dst,
const struct nv50_m2mf_rect *src,
uint32_t nblocksx, uint32_t nblocksy);
@@ -241,8 +238,9 @@ nvc0_vertex_state_delete(struct pipe_context *pipe, void *hwcso);
void nvc0_vertex_arrays_validate(struct nvc0_context *nvc0);
+void nvc0_idxbuf_validate(struct nvc0_context *);
+
/* nvc0_push.c */
void nvc0_push_vbo(struct nvc0_context *, const struct pipe_draw_info *);
-void nvc0_push_vbo2(struct nvc0_context *, const struct pipe_draw_info *);
#endif
diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c
index b180fc8db37..591ac4402db 100644
--- a/src/gallium/drivers/nvc0/nvc0_miptree.c
+++ b/src/gallium/drivers/nvc0/nvc0_miptree.c
@@ -65,80 +65,82 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
compressed = FALSE; /* not yet supported */
- if (mt->base.base.bind & PIPE_BIND_CURSOR)
- return NOUVEAU_BO_TILE_SCANOUT;
+ if (unlikely(mt->base.base.bind & PIPE_BIND_CURSOR))
+ return 0;
+ if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
+ return 0;
switch (mt->base.base.format) {
case PIPE_FORMAT_Z16_UNORM:
if (compressed)
- tile_flags = 0x0200 + (ms << 8);
+ tile_flags = 0x02 + ms;
else
- tile_flags = 0x0100;
+ tile_flags = 0x01;
break;
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
if (compressed)
- tile_flags = 0x5100 + (ms << 8);
+ tile_flags = 0x51 + ms;
else
- tile_flags = 0x4600;
+ tile_flags = 0x46;
break;
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
if (compressed)
- tile_flags = 0x1700 + (ms << 8);
+ tile_flags = 0x17 + ms;
else
- tile_flags = 0x1100;
+ tile_flags = 0x11;
break;
case PIPE_FORMAT_Z32_FLOAT:
if (compressed)
- tile_flags = 0x8600 + (ms << 8);
+ tile_flags = 0x86 + ms;
else
- tile_flags = 0x7b00;
+ tile_flags = 0x7b;
break;
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
if (compressed)
- tile_flags = 0xce00 + (ms << 8);
+ tile_flags = 0xce + ms;
else
- tile_flags = 0xc300;
+ tile_flags = 0xc3;
break;
default:
switch (util_format_get_blocksizebits(mt->base.base.format)) {
case 128:
if (compressed)
- tile_flags = 0xf400 + (ms << 9);
+ tile_flags = 0xf4 + ms;
else
- tile_flags = 0xfe00;
+ tile_flags = 0xfe;
break;
case 64:
if (compressed) {
switch (ms) {
- case 0: tile_flags = 0xe600; break;
- case 1: tile_flags = 0xeb00; break;
- case 2: tile_flags = 0xed00; break;
- case 3: tile_flags = 0xf200; break;
+ case 0: tile_flags = 0xe6; break;
+ case 1: tile_flags = 0xeb; break;
+ case 2: tile_flags = 0xed; break;
+ case 3: tile_flags = 0xf2; break;
default:
return 0;
}
} else {
- tile_flags = 0xfe00;
+ tile_flags = 0xfe;
}
break;
case 32:
if (compressed) {
switch (ms) {
- case 0: tile_flags = 0xdb00; break;
- case 1: tile_flags = 0xdd00; break;
- case 2: tile_flags = 0xdf00; break;
- case 3: tile_flags = 0xe400; break;
+ case 0: tile_flags = 0xdb; break;
+ case 1: tile_flags = 0xdd; break;
+ case 2: tile_flags = 0xdf; break;
+ case 3: tile_flags = 0xe4; break;
default:
return 0;
}
} else {
- tile_flags = 0xfe00;
+ tile_flags = 0xfe;
}
break;
case 16:
case 8:
- tile_flags = 0xfe00;
+ tile_flags = 0xfe;
break;
default:
return 0;
@@ -146,12 +148,6 @@ nvc0_mt_choose_storage_type(struct nv50_miptree *mt, boolean compressed)
break;
}
- if (mt->base.base.bind & PIPE_BIND_SCANOUT)
- tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
-
- if (unlikely(mt->base.base.flags & NOUVEAU_RESOURCE_FLAG_LINEAR))
- tile_flags &= ~0xff00;
-
return tile_flags;
}
@@ -279,7 +275,8 @@ nvc0_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;
@@ -289,7 +286,7 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
pipe_reference_init(&pt->reference, 1);
pt->screen = pscreen;
- tile_flags = nvc0_mt_choose_storage_type(mt, TRUE);
+ bo_config.nvc0.memtype = nvc0_mt_choose_storage_type(mt, TRUE);
if (!nvc0_miptree_init_ms_mode(mt)) {
FREE(mt);
@@ -299,23 +296,29 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
if (unlikely(pt->flags & NVC0_RESOURCE_FLAG_VIDEO)) {
nvc0_miptree_init_layout_video(mt);
} else
- if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+ if (likely(bo_config.nvc0.memtype)) {
nvc0_miptree_init_layout_tiled(mt);
} else
if (!nv50_miptree_init_layout_linear(mt)) {
FREE(mt);
return NULL;
}
+ bo_config.nvc0.tile_mode = mt->level[0].tile_mode;
- ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 4096,
- mt->total_size,
- mt->level[0].tile_mode, tile_flags,
- &mt->base.bo);
+ mt->base.domain = NOUVEAU_BO_VRAM;
+
+ bo_flags = mt->base.domain | NOUVEAU_BO_NOSNOOP;
+
+ if (mt->base.base.bind & (PIPE_BIND_CURSOR | PIPE_BIND_DISPLAY_TARGET))
+ bo_flags |= NOUVEAU_BO_CONTIG;
+
+ 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;
}
diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c
index 44c7a65e3c9..b403e2ee9f2 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.c
+++ b/src/gallium/drivers/nvc0/nvc0_program.c
@@ -618,7 +618,17 @@ nvc0_program_translate(struct nvc0_program *prog)
assert(info->bin.tlsSpace < (1 << 24));
prog->hdr[0] |= 1 << 26;
prog->hdr[1] |= info->bin.tlsSpace; /* l[] size */
+ prog->need_tls = TRUE;
}
+ /* TODO: factor 2 only needed where joinat/precont is used,
+ * and we only have to count non-uniform branches
+ */
+ /*
+ if ((info->maxCFDepth * 2) > 16) {
+ prog->hdr[2] |= (((info->maxCFDepth * 2) + 47) / 48) * 0x200;
+ prog->need_tls = TRUE;
+ }
+ */
if (info->io.globalAccess)
prog->hdr[0] |= 1 << 16;
@@ -649,15 +659,15 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
}
size = align(size, 0x40); /* required by SP_START_ID */
- ret = nouveau_resource_alloc(screen->text_heap, size, prog, &prog->res);
+ ret = nouveau_heap_alloc(screen->text_heap, size, prog, &prog->mem);
if (ret) {
NOUVEAU_ERR("out of code space\n");
return FALSE;
}
- prog->code_base = prog->res->start;
- prog->immd_base = align(prog->res->start + prog->immd_base, 0x100);
+ prog->code_base = prog->mem->start;
+ prog->immd_base = align(prog->mem->start + prog->immd_base, 0x100);
assert((prog->immd_size == 0) || (prog->immd_base + prog->immd_size <=
- prog->res->start + prog->res->size));
+ prog->mem->start + prog->mem->size));
code_pos = prog->code_base + NVC0_SHADER_HEADER_SIZE;
@@ -679,8 +689,8 @@ nvc0_program_upload_code(struct nvc0_context *nvc0, struct nvc0_program *prog)
screen->text, prog->immd_base, NOUVEAU_BO_VRAM,
prog->immd_size, prog->immd_data);
- BEGIN_RING(screen->base.channel, RING_3D(MEM_BARRIER), 1);
- OUT_RING (screen->base.channel, 0x1111);
+ BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(MEM_BARRIER), 1);
+ PUSH_DATA (nvc0->base.pushbuf, 0x1111);
return TRUE;
}
@@ -701,8 +711,8 @@ nvc0_program_library_upload(struct nvc0_context *nvc0)
if (!size)
return;
- ret = nouveau_resource_alloc(screen->text_heap, align(size, 0x100), NULL,
- &screen->lib_code);
+ ret = nouveau_heap_alloc(screen->text_heap, align(size, 0x100), NULL,
+ &screen->lib_code);
if (ret)
return;
@@ -718,8 +728,8 @@ nvc0_program_destroy(struct nvc0_context *nvc0, struct nvc0_program *prog)
const struct pipe_shader_state pipe = prog->pipe;
const ubyte type = prog->type;
- if (prog->res)
- nouveau_resource_free(&prog->res);
+ if (prog->mem)
+ nouveau_heap_free(&prog->mem);
if (prog->code)
FREE(prog->code);
diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h
index c90f364ab9f..f6d1121c6dd 100644
--- a/src/gallium/drivers/nvc0/nvc0_program.h
+++ b/src/gallium/drivers/nvc0/nvc0_program.h
@@ -21,6 +21,7 @@ struct nvc0_program {
ubyte type;
boolean translated;
+ boolean need_tls;
uint8_t max_gpr;
uint32_t *code;
@@ -54,7 +55,7 @@ struct nvc0_program {
struct nvc0_transform_feedback_state *tfb;
- struct nouveau_resource *res;
+ struct nouveau_heap *mem;
};
#endif
diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c
index cea58b447a2..78cc5c20641 100644
--- a/src/gallium/drivers/nvc0/nvc0_push.c
+++ b/src/gallium/drivers/nvc0/nvc0_push.c
@@ -11,7 +11,7 @@
#include "nvc0_3d.xml.h"
struct push_context {
- struct nouveau_channel *chan;
+ struct nouveau_pushbuf *push;
void *idxbuf;
@@ -40,7 +40,7 @@ init_push_context(struct nvc0_context *nvc0, struct push_context *ctx)
{
struct pipe_vertex_element *ve;
- ctx->chan = nvc0->screen->base.channel;
+ ctx->push = nvc0->base.pushbuf;
ctx->translate = nvc0->vertex->translate;
if (likely(nvc0->vertex->num_elements < 32))
@@ -72,7 +72,7 @@ set_edgeflag(struct push_context *ctx, unsigned vtx_id)
if (ctx->edgeflag.value != f) {
ctx->edgeflag.value = f;
- IMMED_RING(ctx->chan, RING_3D(EDGEFLAG_ENABLE), f ? 1 : 0);
+ IMMED_NVC0(ctx->push, NVC0_3D(EDGEFLAG), f ? 1 : 0);
}
}
@@ -80,11 +80,11 @@ static INLINE void
set_vertexid(struct push_context *ctx, uint32_t vtx_id)
{
#if 0
- BEGIN_RING(ctx->chan, RING_3D(VERTEX_ID), 1); /* broken on nvc0 */
+ BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_ID), 1); /* broken on nvc0 */
#else
- BEGIN_RING(ctx->chan, RING_3D(VERTEX_DATA), 1); /* as last attribute */
+ BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_DATA), 1); /* as last attribute */
#endif
- OUT_RING (ctx->chan, vtx_id);
+ PUSH_DATA (ctx->push, vtx_id);
}
static INLINE unsigned
@@ -135,11 +135,11 @@ 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_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
ctx->translate->run_elts8(ctx->translate, elts, nr, ctx->instance_id,
- ctx->chan->cur);
- ctx->chan->cur += size;
+ ctx->push->cur);
+ ctx->push->cur += size;
if (unlikely(ctx->need_vertex_id) && likely(size))
set_vertexid(ctx, elts[0]);
@@ -150,9 +150,9 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
if (nr != push) {
count--;
elts++;
- BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
- OUT_RING (ctx->chan, 0);
- OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+ BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
+ PUSH_DATA (ctx->push, 0);
+ PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
(ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
}
}
@@ -176,11 +176,11 @@ 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_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
ctx->translate->run_elts16(ctx->translate, elts, nr, ctx->instance_id,
- ctx->chan->cur);
- ctx->chan->cur += size;
+ ctx->push->cur);
+ ctx->push->cur += size;
if (unlikely(ctx->need_vertex_id))
set_vertexid(ctx, elts[0]);
@@ -191,9 +191,9 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
if (nr != push) {
count--;
elts++;
- BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
- OUT_RING (ctx->chan, 0);
- OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+ BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
+ PUSH_DATA (ctx->push, 0);
+ PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
(ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
}
}
@@ -217,11 +217,11 @@ 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_NIC0(ctx->push, NVC0_3D(VERTEX_DATA), size);
ctx->translate->run_elts(ctx->translate, elts, nr, ctx->instance_id,
- ctx->chan->cur);
- ctx->chan->cur += size;
+ ctx->push->cur);
+ ctx->push->cur += size;
if (unlikely(ctx->need_vertex_id))
set_vertexid(ctx, elts[0]);
@@ -232,9 +232,9 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
if (nr != push) {
count--;
elts++;
- BEGIN_RING(ctx->chan, RING_3D(VERTEX_END_GL), 2);
- OUT_RING (ctx->chan, 0);
- OUT_RING (ctx->chan, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
+ BEGIN_NVC0(ctx->push, NVC0_3D(VERTEX_END_GL), 2);
+ PUSH_DATA (ctx->push, 0);
+ PUSH_DATA (ctx->push, NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_CONT |
(ctx->prim & ~NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT));
}
}
@@ -250,11 +250,11 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
if (unlikely(ctx->edgeflag.buffer >= 0))
set_edgeflag(ctx, start);
- BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size);
+ BEGIN_NIC0(ctx->push, NVC0_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;
if (unlikely(ctx->need_vertex_id))
set_vertexid(ctx, start);
@@ -354,17 +354,17 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
if (unlikely(ctx.need_vertex_id)) {
const unsigned a = nvc0->vertex->num_elements;
- BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
- OUT_RING (ctx.chan, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
+ BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
+ PUSH_DATA (ctx.push, (a << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
- BEGIN_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 1);
- OUT_RING (ctx.chan, (((0x80 + a * 0x10) / 4) << 4) | 1);
+ BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 1);
+ PUSH_DATA (ctx.push, (((0x80 + a * 0x10) / 4) << 4) | 1);
}
while (inst_count--) {
- BEGIN_RING(ctx.chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (ctx.chan, ctx.prim);
+ BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (ctx.push, ctx.prim);
switch (index_size) {
case 0:
emit_vertices_seq(&ctx, info->start, vert_count);
@@ -382,20 +382,20 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
assert(0);
break;
}
- IMMED_RING(ctx.chan, RING_3D(VERTEX_END_GL), 0);
+ IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_END_GL), 0);
ctx.instance_id++;
ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
if (unlikely(ctx.edgeflag.value == 0.0f))
- IMMED_RING(ctx.chan, RING_3D(EDGEFLAG_ENABLE), 1);
+ IMMED_NVC0(ctx.push, NVC0_3D(EDGEFLAG), 1);
if (unlikely(ctx.need_vertex_id)) {
const unsigned a = nvc0->vertex->num_elements;
- IMMED_RING(ctx.chan, RING_3D(VERTEX_ID_REPLACE), 0);
- BEGIN_RING(ctx.chan, RING_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
- OUT_RING (ctx.chan,
+ IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ID_REPLACE), 0);
+ BEGIN_NVC0(ctx.push, NVC0_3D(VERTEX_ATTRIB_FORMAT(a)), 1);
+ PUSH_DATA (ctx.push,
NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST |
NVC0_3D_VERTEX_ATTRIB_FORMAT_TYPE_FLOAT |
NVC0_3D_VERTEX_ATTRIB_FORMAT_SIZE_32);
diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c
index 699d582fe3d..b0ef83a1df2 100644
--- a/src/gallium/drivers/nvc0/nvc0_query.c
+++ b/src/gallium/drivers/nvc0/nvc0_query.c
@@ -22,6 +22,8 @@
* Authors: Christoph Bumiller
*/
+#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+
#include "nvc0_context.h"
#include "nouveau/nv_object.xml.h"
@@ -71,14 +73,12 @@ nvc0_query_allocate(struct nvc0_context *nvc0, struct nvc0_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) {
nvc0_query_allocate(nvc0, 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;
}
@@ -150,17 +150,18 @@ nvc0_query_create(struct pipe_context *pipe, unsigned type)
}
static void
-nvc0_query_get(struct nouveau_channel *chan, struct nvc0_query *q,
+nvc0_query_get(struct nouveau_pushbuf *push, struct nvc0_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_NVC0(push, NVC0_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
@@ -176,7 +177,7 @@ static void
nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_query *q = nvc0_query(pq);
/* For occlusion queries we have to change the storage, because a previous
@@ -201,41 +202,42 @@ nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
case PIPE_QUERY_OCCLUSION_PREDICATE:
q->nesting = nvc0->screen->num_occlusion_queries_active++;
if (q->nesting) {
- nvc0_query_get(chan, q, 0x10, 0x0100f002);
+ nvc0_query_get(push, q, 0x10, 0x0100f002);
} else {
- BEGIN_RING(chan, RING_3D(COUNTER_RESET), 1);
- OUT_RING (chan, NVC0_3D_COUNTER_RESET_SAMPLECNT);
- IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 1);
+ PUSH_SPACE(push, 3);
+ BEGIN_NVC0(push, NVC0_3D(COUNTER_RESET), 1);
+ PUSH_DATA (push, NVC0_3D_COUNTER_RESET_SAMPLECNT);
+ IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1);
}
break;
case PIPE_QUERY_PRIMITIVES_GENERATED:
- nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5));
break;
case PIPE_QUERY_PRIMITIVES_EMITTED:
- nvc0_query_get(chan, q, 0x10, 0x05805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x10, 0x05805002 | (q->index << 5));
break;
case PIPE_QUERY_SO_STATISTICS:
- nvc0_query_get(chan, q, 0x20, 0x05805002 | (q->index << 5));
- nvc0_query_get(chan, q, 0x30, 0x06805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x20, 0x05805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x30, 0x06805002 | (q->index << 5));
break;
case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
- nvc0_query_get(chan, q, 0x10, 0x03005002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x10, 0x03005002 | (q->index << 5));
break;
case PIPE_QUERY_TIMESTAMP_DISJOINT:
case PIPE_QUERY_TIME_ELAPSED:
- nvc0_query_get(chan, q, 0x10, 0x00005002);
+ nvc0_query_get(push, q, 0x10, 0x00005002);
break;
case PIPE_QUERY_PIPELINE_STATISTICS:
- nvc0_query_get(chan, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */
- nvc0_query_get(chan, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */
- nvc0_query_get(chan, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */
- nvc0_query_get(chan, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */
- nvc0_query_get(chan, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */
- nvc0_query_get(chan, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */
- nvc0_query_get(chan, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */
- nvc0_query_get(chan, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */
- nvc0_query_get(chan, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */
- nvc0_query_get(chan, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */
+ nvc0_query_get(push, q, 0xc0 + 0x00, 0x00801002); /* VFETCH, VERTICES */
+ nvc0_query_get(push, q, 0xc0 + 0x10, 0x01801002); /* VFETCH, PRIMS */
+ nvc0_query_get(push, q, 0xc0 + 0x20, 0x02802002); /* VP, LAUNCHES */
+ nvc0_query_get(push, q, 0xc0 + 0x30, 0x03806002); /* GP, LAUNCHES */
+ nvc0_query_get(push, q, 0xc0 + 0x40, 0x04806002); /* GP, PRIMS_OUT */
+ nvc0_query_get(push, q, 0xc0 + 0x50, 0x07804002); /* RAST, PRIMS_IN */
+ nvc0_query_get(push, q, 0xc0 + 0x60, 0x08804002); /* RAST, PRIMS_OUT */
+ nvc0_query_get(push, q, 0xc0 + 0x70, 0x0980a002); /* ROP, PIXELS */
+ nvc0_query_get(push, q, 0xc0 + 0x80, 0x0d808002); /* TCP, LAUNCHES */
+ nvc0_query_get(push, q, 0xc0 + 0x90, 0x0e809002); /* TEP, LAUNCHES */
break;
default:
break;
@@ -248,7 +250,7 @@ static void
nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_query *q = nvc0_query(pq);
if (!q->active) {
@@ -263,49 +265,51 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
- nvc0_query_get(chan, q, 0, 0x0100f002);
- if (--nvc0->screen->num_occlusion_queries_active == 0)
- IMMED_RING(chan, RING_3D(SAMPLECNT_ENABLE), 0);
+ nvc0_query_get(push, q, 0, 0x0100f002);
+ if (--nvc0->screen->num_occlusion_queries_active == 0) {
+ PUSH_SPACE(push, 1);
+ IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0);
+ }
break;
case PIPE_QUERY_PRIMITIVES_GENERATED:
- nvc0_query_get(chan, q, 0, 0x06805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0, 0x06805002 | (q->index << 5));
break;
case PIPE_QUERY_PRIMITIVES_EMITTED:
- nvc0_query_get(chan, q, 0, 0x05805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0, 0x05805002 | (q->index << 5));
break;
case PIPE_QUERY_SO_STATISTICS:
- nvc0_query_get(chan, q, 0x00, 0x05805002 | (q->index << 5));
- nvc0_query_get(chan, q, 0x10, 0x06805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x00, 0x05805002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x10, 0x06805002 | (q->index << 5));
break;
case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
/* TODO: How do we sum over all streams for render condition ? */
/* PRIMS_DROPPED doesn't write sequence, use a ZERO query to sync on */
- nvc0_query_get(chan, q, 0x00, 0x03005002 | (q->index << 5));
- nvc0_query_get(chan, q, 0x20, 0x00005002);
+ nvc0_query_get(push, q, 0x00, 0x03005002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x20, 0x00005002);
break;
case PIPE_QUERY_TIMESTAMP:
case PIPE_QUERY_TIMESTAMP_DISJOINT:
case PIPE_QUERY_TIME_ELAPSED:
- nvc0_query_get(chan, q, 0, 0x00005002);
+ nvc0_query_get(push, q, 0, 0x00005002);
break;
case PIPE_QUERY_GPU_FINISHED:
- nvc0_query_get(chan, q, 0, 0x1000f010);
+ nvc0_query_get(push, q, 0, 0x1000f010);
break;
case PIPE_QUERY_PIPELINE_STATISTICS:
- nvc0_query_get(chan, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
- nvc0_query_get(chan, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
- nvc0_query_get(chan, q, 0x20, 0x02802002); /* VP, LAUNCHES */
- nvc0_query_get(chan, q, 0x30, 0x03806002); /* GP, LAUNCHES */
- nvc0_query_get(chan, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
- nvc0_query_get(chan, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
- nvc0_query_get(chan, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
- nvc0_query_get(chan, q, 0x70, 0x0980a002); /* ROP, PIXELS */
- nvc0_query_get(chan, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */
- nvc0_query_get(chan, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */
+ nvc0_query_get(push, q, 0x00, 0x00801002); /* VFETCH, VERTICES */
+ nvc0_query_get(push, q, 0x10, 0x01801002); /* VFETCH, PRIMS */
+ nvc0_query_get(push, q, 0x20, 0x02802002); /* VP, LAUNCHES */
+ nvc0_query_get(push, q, 0x30, 0x03806002); /* GP, LAUNCHES */
+ nvc0_query_get(push, q, 0x40, 0x04806002); /* GP, PRIMS_OUT */
+ nvc0_query_get(push, q, 0x50, 0x07804002); /* RAST, PRIMS_IN */
+ nvc0_query_get(push, q, 0x60, 0x08804002); /* RAST, PRIMS_OUT */
+ nvc0_query_get(push, q, 0x70, 0x0980a002); /* ROP, PIXELS */
+ nvc0_query_get(push, q, 0x80, 0x0d808002); /* TCP, LAUNCHES */
+ nvc0_query_get(push, q, 0x90, 0x0e809002); /* TEP, LAUNCHES */
break;
case NVC0_QUERY_TFB_BUFFER_OFFSET:
/* indexed by TFB buffer instead of by vertex stream */
- nvc0_query_get(chan, q, 0x00, 0x0d005002 | (q->index << 5));
+ nvc0_query_get(push, q, 0x00, 0x0d005002 | (q->index << 5));
break;
default:
assert(0);
@@ -314,32 +318,20 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
}
static INLINE boolean
-nvc0_query_ready(struct nvc0_query *q)
+nvc0_query_ready(struct nouveau_client *cli, struct nvc0_query *q)
{
if (q->is64bit) {
- if (nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOWAIT))
- return FALSE;
- nouveau_bo_unmap(q->bo);
- return TRUE;
+ return !nouveau_bo_map(q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_NOBLOCK, cli);
} else {
return q->data[0] == q->sequence;
}
}
-static INLINE boolean
-nvc0_query_wait(struct nvc0_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
nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
boolean wait, union pipe_query_result *result)
{
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nvc0_query *q = nvc0_query(pq);
uint64_t *res64 = (uint64_t*)result;
uint32_t *res32 = (uint32_t*)result;
@@ -348,15 +340,15 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
unsigned i;
if (!q->ready) /* update ? */
- q->ready = nvc0_query_ready(q);
+ q->ready = nvc0_query_ready(nvc0->screen->base.client, q);
if (!q->ready) {
- struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
if (!wait) {
- if (nouveau_bo_pending(q->bo) & NOUVEAU_BO_WR) /* for daft apps */
- FIRE_RING(chan);
+ /* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */
+ if (nouveau_pushbuf_refd(nvc0->base.pushbuf, q->bo) & NOUVEAU_BO_WR)
+ PUSH_KICK(nvc0->base.pushbuf);
return FALSE;
}
- if (!nvc0_query_wait(q))
+ if (nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, nvc0->screen->base.client))
return FALSE;
}
q->ready = TRUE;
@@ -407,19 +399,20 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
}
void
-nvc0_query_fifo_wait(struct nouveau_channel *chan, struct pipe_query *pq)
+nvc0_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq)
{
struct nvc0_query *q = nvc0_query(pq);
unsigned offset = q->offset;
if (q->type == PIPE_QUERY_SO_OVERFLOW_PREDICATE) offset += 0x20;
- MARK_RING (chan, 5, 2);
- BEGIN_RING(chan, RING_3D_(NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH), 4);
- OUT_RELOCh(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, q->bo, offset, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
- OUT_RING (chan, q->sequence);
- OUT_RING (chan, (1 << 12) |
+ PUSH_SPACE(push, 5);
+ PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ BEGIN_NVC0(push, SUBC_3D(NV84_SUBCHAN_SEMAPHORE_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, (1 << 12) |
NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
}
@@ -428,7 +421,7 @@ nvc0_render_condition(struct pipe_context *pipe,
struct pipe_query *pq, uint mode)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_query *q;
uint32_t cond;
boolean negated = FALSE;
@@ -437,7 +430,8 @@ nvc0_render_condition(struct pipe_context *pipe,
mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
if (!pq) {
- IMMED_RING(chan, RING_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
+ PUSH_SPACE(push, 1);
+ IMMED_NVC0(push, NVC0_3D(COND_MODE), NVC0_3D_COND_MODE_ALWAYS);
return;
}
q = nvc0_query(pq);
@@ -468,25 +462,27 @@ nvc0_render_condition(struct pipe_context *pipe,
}
if (wait)
- nvc0_query_fifo_wait(chan, pq);
-
- 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, cond);
+ nvc0_query_fifo_wait(push, pq);
+
+ PUSH_SPACE(push, 4);
+ PUSH_REFN (push, q->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ BEGIN_NVC0(push, NVC0_3D(COND_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, q->bo->offset + q->offset);
+ PUSH_DATA (push, q->bo->offset + q->offset);
+ PUSH_DATA (push, cond);
}
void
-nvc0_query_pushbuf_submit(struct nouveau_channel *chan,
+nvc0_query_pushbuf_submit(struct nouveau_pushbuf *push,
struct pipe_query *pq, unsigned result_offset)
{
struct nvc0_query *q = nvc0_query(pq);
#define NVC0_IB_ENTRY_1_NO_PREFETCH (1 << (31 - 8))
- nouveau_pushbuf_submit(chan, q->bo, q->offset + result_offset, 4 |
- NVC0_IB_ENTRY_1_NO_PREFETCH);
+ nouveau_pushbuf_space(push, 0, 0, 1);
+ nouveau_pushbuf_data(push, q->bo, q->offset + result_offset, 4 |
+ NVC0_IB_ENTRY_1_NO_PREFETCH);
}
void
@@ -497,9 +493,9 @@ nvc0_so_target_save_offset(struct pipe_context *pipe,
struct nvc0_so_target *targ = nvc0_so_target(ptarg);
if (*serialize) {
- struct nouveau_channel *chan = nvc0_context(pipe)->screen->base.channel;
*serialize = FALSE;
- IMMED_RING(chan, RING_3D(SERIALIZE), 0);
+ PUSH_SPACE(nvc0_context(pipe)->base.pushbuf, 1);
+ IMMED_NVC0(nvc0_context(pipe)->base.pushbuf, NVC0_3D(SERIALIZE), 0);
}
nvc0_query(targ->pq)->index = index;
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index f7637eedc43..f314cb631f2 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -238,8 +238,8 @@ nvc0_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);
@@ -250,17 +250,17 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
nouveau_bo_ref(NULL, &screen->fence.bo);
nouveau_bo_ref(NULL, &screen->vfetch_cache);
- nouveau_resource_destroy(&screen->lib_code);
- nouveau_resource_destroy(&screen->text_heap);
+ nouveau_heap_destroy(&screen->lib_code);
+ nouveau_heap_destroy(&screen->text_heap);
if (screen->tic.entries)
FREE(screen->tic.entries);
nouveau_mm_destroy(screen->mm_VRAM_fe0);
- nouveau_grobj_free(&screen->fermi);
- nouveau_grobj_free(&screen->eng2d);
- nouveau_grobj_free(&screen->m2mf);
+ nouveau_object_del(&screen->fermi);
+ nouveau_object_del(&screen->eng2d);
+ nouveau_object_del(&screen->m2mf);
nouveau_screen_fini(&screen->base);
@@ -271,102 +271,100 @@ static int
nvc0_graph_set_macro(struct nvc0_screen *screen, uint32_t m, unsigned pos,
unsigned size, const uint32_t *data)
{
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_pushbuf *push = screen->base.pushbuf;
size /= 4;
- BEGIN_RING(chan, RING_3D_(NVC0_GRAPH_MACRO_ID), 2);
- OUT_RING (chan, (m - 0x3800) / 8);
- OUT_RING (chan, pos);
- BEGIN_RING_1I(chan, RING_3D_(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
- OUT_RING (chan, pos);
- OUT_RINGp (chan, data, size);
+ BEGIN_NVC0(push, SUBC_3D(NVC0_GRAPH_MACRO_ID), 2);
+ PUSH_DATA (push, (m - 0x3800) / 8);
+ PUSH_DATA (push, pos);
+ BEGIN_1IC0(push, SUBC_3D(NVC0_GRAPH_MACRO_UPLOAD_POS), size + 1);
+ PUSH_DATA (push, pos);
+ PUSH_DATAp(push, data, size);
return pos + size;
}
static void
-nvc0_magic_3d_init(struct nouveau_channel *chan)
+nvc0_magic_3d_init(struct nouveau_pushbuf *push)
{
- BEGIN_RING(chan, RING_3D_(0x10cc), 1);
- OUT_RING (chan, 0xff);
- BEGIN_RING(chan, RING_3D_(0x10e0), 2);
- OUT_RING(chan, 0xff);
- OUT_RING(chan, 0xff);
- BEGIN_RING(chan, RING_3D_(0x10ec), 2);
- OUT_RING(chan, 0xff);
- OUT_RING(chan, 0xff);
- BEGIN_RING(chan, RING_3D_(0x074c), 1);
- OUT_RING (chan, 0x3f);
-
- BEGIN_RING(chan, RING_3D_(0x16a8), 1);
- OUT_RING (chan, (3 << 16) | 3);
- BEGIN_RING(chan, RING_3D_(0x1794), 1);
- OUT_RING (chan, (2 << 16) | 2);
- BEGIN_RING(chan, RING_3D_(0x0de8), 1);
- OUT_RING (chan, 1);
+ BEGIN_NVC0(push, SUBC_3D(0x10cc), 1);
+ PUSH_DATA (push, 0xff);
+ BEGIN_NVC0(push, SUBC_3D(0x10e0), 2);
+ PUSH_DATA(push, 0xff);
+ PUSH_DATA(push, 0xff);
+ BEGIN_NVC0(push, SUBC_3D(0x10ec), 2);
+ PUSH_DATA(push, 0xff);
+ PUSH_DATA(push, 0xff);
+ BEGIN_NVC0(push, SUBC_3D(0x074c), 1);
+ PUSH_DATA (push, 0x3f);
+
+ BEGIN_NVC0(push, SUBC_3D(0x16a8), 1);
+ PUSH_DATA (push, (3 << 16) | 3);
+ BEGIN_NVC0(push, SUBC_3D(0x1794), 1);
+ PUSH_DATA (push, (2 << 16) | 2);
+ BEGIN_NVC0(push, SUBC_3D(0x0de8), 1);
+ PUSH_DATA (push, 1);
#if 0 /* software method */
- BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, SUBC_3D(0x1528), 1); /* MP poke */
+ PUSH_DATA (push, 0);
#endif
- BEGIN_RING(chan, RING_3D_(0x12ac), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D_(0x0218), 1);
- OUT_RING (chan, 0x10);
- BEGIN_RING(chan, RING_3D_(0x10fc), 1);
- OUT_RING (chan, 0x10);
- BEGIN_RING(chan, RING_3D_(0x1290), 1);
- OUT_RING (chan, 0x10);
- BEGIN_RING(chan, RING_3D_(0x12d8), 2);
- OUT_RING (chan, 0x10);
- OUT_RING (chan, 0x10);
- BEGIN_RING(chan, RING_3D_(0x06d4), 1);
- OUT_RING (chan, 8);
- BEGIN_RING(chan, RING_3D_(0x1140), 1);
- OUT_RING (chan, 0x10);
- BEGIN_RING(chan, RING_3D_(0x1610), 1);
- OUT_RING (chan, 0xe);
-
- BEGIN_RING(chan, RING_3D_(0x164c), 1);
- OUT_RING (chan, 1 << 12);
- BEGIN_RING(chan, RING_3D_(0x151c), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D_(0x030c), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D_(0x0300), 1);
- OUT_RING (chan, 3);
+ BEGIN_NVC0(push, SUBC_3D(0x12ac), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, SUBC_3D(0x0218), 1);
+ PUSH_DATA (push, 0x10);
+ BEGIN_NVC0(push, SUBC_3D(0x10fc), 1);
+ PUSH_DATA (push, 0x10);
+ BEGIN_NVC0(push, SUBC_3D(0x1290), 1);
+ PUSH_DATA (push, 0x10);
+ BEGIN_NVC0(push, SUBC_3D(0x12d8), 2);
+ PUSH_DATA (push, 0x10);
+ PUSH_DATA (push, 0x10);
+ BEGIN_NVC0(push, SUBC_3D(0x06d4), 1);
+ PUSH_DATA (push, 8);
+ BEGIN_NVC0(push, SUBC_3D(0x1140), 1);
+ PUSH_DATA (push, 0x10);
+ BEGIN_NVC0(push, SUBC_3D(0x1610), 1);
+ PUSH_DATA (push, 0xe);
+
+ BEGIN_NVC0(push, SUBC_3D(0x164c), 1);
+ PUSH_DATA (push, 1 << 12);
+ BEGIN_NVC0(push, SUBC_3D(0x151c), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, SUBC_3D(0x030c), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, SUBC_3D(0x0300), 1);
+ PUSH_DATA (push, 3);
#if 0 /* software method */
- BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, SUBC_3D(0x1280), 1); /* PGRAPH poke */
+ PUSH_DATA (push, 0);
#endif
- BEGIN_RING(chan, RING_3D_(0x02d0), 1);
- OUT_RING (chan, 0x1f40);
- BEGIN_RING(chan, RING_3D_(0x00fdc), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D_(0x19c0), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D_(0x075c), 1);
- OUT_RING (chan, 3);
+ BEGIN_NVC0(push, SUBC_3D(0x02d0), 1);
+ PUSH_DATA (push, 0x1f40);
+ BEGIN_NVC0(push, SUBC_3D(0x0fdc), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, SUBC_3D(0x19c0), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, SUBC_3D(0x075c), 1);
+ PUSH_DATA (push, 3);
}
static void
nvc0_screen_fence_emit(struct pipe_screen *pscreen, u32 *sequence)
{
struct nvc0_screen *screen = nvc0_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, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
+ BEGIN_NVC0(push, NVC0_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, NVC0_3D_QUERY_GET_FENCE | NVC0_3D_QUERY_GET_SHORT |
(0xf << NVC0_3D_QUERY_GET_UNIT__SHIFT));
}
@@ -388,10 +386,12 @@ struct pipe_screen *
nvc0_screen_create(struct nouveau_device *dev)
{
struct nvc0_screen *screen;
- struct nouveau_channel *chan;
struct pipe_screen *pscreen;
+ struct nouveau_object *chan;
+ struct nouveau_pushbuf *push;
int ret;
unsigned i;
+ union nouveau_bo_config mm_config;
screen = CALLOC_STRUCT(nvc0_screen);
if (!screen)
@@ -406,7 +406,8 @@ nvc0_screen_create(struct nouveau_device *dev)
return NULL;
}
chan = screen->base.channel;
- chan->user_private = screen;
+ push = screen->base.pushbuf;
+ push->user_priv = screen;
pscreen->destroy = nvc0_screen_destroy;
pscreen->context_create = nvc0_create;
@@ -419,203 +420,210 @@ nvc0_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,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, 4096, 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 = nvc0_screen_fence_emit;
screen->base.fence.update = nvc0_screen_fence_update;
for (i = 0; i < NVC0_SCRATCH_NR_BUFFERS; ++i) {
- ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_GART, 0, NVC0_SCRATCH_SIZE, NULL,
&screen->scratch.bo[i]);
if (ret)
goto fail;
}
- ret = nouveau_grobj_alloc(chan, 0xbeef9039, NVC0_M2MF, &screen->m2mf);
+ ret = nouveau_object_new(chan, 0xbeef9039, NVC0_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, NVC0_SUBCH_MF);
- BEGIN_RING(chan, RING_MF(NOTIFY_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, screen->fence.bo, 16, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, SUBC_M2MF(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->m2mf->oclass);
+ BEGIN_NVC0(push, NVC0_M2MF(NOTIFY_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->fence.bo->offset + 16);
+ PUSH_DATA (push, screen->fence.bo->offset + 16);
+ PUSH_DATA (push, 0);
- ret = nouveau_grobj_alloc(chan, 0xbeef902d, NVC0_2D, &screen->eng2d);
+ ret = nouveau_object_new(chan, 0xbeef902d, NVC0_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, NVC0_SUBCH_2D);
- BEGIN_RING(chan, RING_2D(OPERATION), 1);
- OUT_RING (chan, NVC0_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_(0x0884), 1);
- OUT_RING (chan, 0x3f);
- BEGIN_RING(chan, RING_2D_(0x0888), 1);
- OUT_RING (chan, 1);
-
- ret = nouveau_grobj_alloc(chan, 0xbeef9097, NVC0_3D, &screen->fermi);
+ BEGIN_NVC0(push, SUBC_2D(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->eng2d->oclass);
+ BEGIN_NVC0(push, NVC0_2D(OPERATION), 1);
+ PUSH_DATA (push, NVC0_2D_OPERATION_SRCCOPY);
+ BEGIN_NVC0(push, NVC0_2D(CLIP_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_2D(COLOR_KEY_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, SUBC_2D(0x0884), 1);
+ PUSH_DATA (push, 0x3f);
+ BEGIN_NVC0(push, SUBC_2D(0x0888), 1);
+ PUSH_DATA (push, 1);
+
+ ret = nouveau_object_new(chan, 0xbeef9097, NVC0_3D_CLASS, NULL, 0,
+ &screen->fermi);
if (ret)
FAIL_SCREEN_INIT("Error allocating PGRAPH context for 3D: %d\n", ret);
- BIND_RING (chan, screen->fermi, NVC0_SUBCH_3D);
- BEGIN_RING(chan, RING_3D(NOTIFY_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, screen->fence.bo, 32, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, SUBC_3D(NV01_SUBCHAN_OBJECT), 1);
+ PUSH_DATA (push, screen->fermi->oclass);
+ BEGIN_NVC0(push, NVC0_3D(NOTIFY_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->fence.bo->offset + 32);
+ PUSH_DATA (push, screen->fence.bo->offset + 32);
+ PUSH_DATA (push, 0);
- BEGIN_RING(chan, RING_3D(COND_MODE), 1);
- OUT_RING (chan, NVC0_3D_COND_MODE_ALWAYS);
+ BEGIN_NVC0(push, NVC0_3D(COND_MODE), 1);
+ PUSH_DATA (push, NVC0_3D_COND_MODE_ALWAYS);
if (debug_get_bool_option("NOUVEAU_SHADER_WATCHDOG", TRUE)) {
/* kill shaders after about 1 second (at 100 MHz) */
- BEGIN_RING(chan, RING_3D(WATCHDOG_TIMER), 1);
- OUT_RING (chan, 0x17);
+ BEGIN_NVC0(push, NVC0_3D(WATCHDOG_TIMER), 1);
+ PUSH_DATA (push, 0x17);
}
- 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, NVC0_3D_MULTISAMPLE_MODE_MS1);
- BEGIN_RING(chan, RING_3D(MULTISAMPLE_CTRL), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(LINE_WIDTH_SEPARATE), 1);
- OUT_RING (chan, 1);
- 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);
- BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(TEX_MISC), 1);
- OUT_RING (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
-
- nvc0_magic_3d_init(chan);
-
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, &screen->text);
+ BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, 1);
+
+ BEGIN_NVC0(push, NVC0_3D(CSAA_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), 1);
+ PUSH_DATA (push, NVC0_3D_MULTISAMPLE_MODE_MS1);
+ BEGIN_NVC0(push, NVC0_3D(MULTISAMPLE_CTRL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(LINE_WIDTH_SEPARATE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(LINE_LAST_PIXEL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(BLEND_SEPARATE_ALPHA), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE_COMMON), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(TEX_MISC), 1);
+ PUSH_DATA (push, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP);
+
+ nvc0_magic_3d_init(push);
+
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
+ &screen->text);
if (ret)
goto fail;
/* XXX: getting a page fault at the end of the code buffer every few
* launches, don't use the last 256 bytes to work around them - prefetch ?
*/
- nouveau_resource_init(&screen->text_heap, 0, (1 << 20) - 0x100);
+ nouveau_heap_init(&screen->text_heap, 0, (1 << 20) - 0x100);
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 12, 6 << 16, NULL,
&screen->uniforms);
if (ret)
goto fail;
/* auxiliary constants (6 user clip planes, base instance id) */
- BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
- OUT_RING (chan, 256);
- OUT_RELOCh(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->uniforms, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+ PUSH_DATA (push, 256);
+ PUSH_DATAh(push, screen->uniforms->offset + (5 << 16));
+ PUSH_DATA (push, screen->uniforms->offset + (5 << 16));
for (i = 0; i < 5; ++i) {
- BEGIN_RING(chan, RING_3D(CB_BIND(i)), 1);
- OUT_RING (chan, (15 << 4) | 1);
+ BEGIN_NVC0(push, NVC0_3D(CB_BIND(i)), 1);
+ PUSH_DATA (push, (15 << 4) | 1);
}
screen->tls_size = (16 * 32) * (NVC0_CAP_MAX_PROGRAM_TEMPS * 16);
ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17,
- screen->tls_size, &screen->tls);
+ screen->tls_size, NULL, &screen->tls);
if (ret)
goto fail;
- BEGIN_RING(chan, RING_3D(CODE_ADDRESS_HIGH), 2);
- OUT_RELOCh(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, screen->text, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- BEGIN_RING(chan, RING_3D(LOCAL_ADDRESS_HIGH), 4);
- OUT_RELOCh(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, screen->tls, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RING (chan, screen->tls_size >> 32);
- OUT_RING (chan, screen->tls_size);
- BEGIN_RING(chan, RING_3D_(0x07a0), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(LOCAL_BASE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, NVC0_3D(CODE_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, screen->text->offset);
+ PUSH_DATA (push, screen->text->offset);
+ BEGIN_NVC0(push, NVC0_3D(TEMP_ADDRESS_HIGH), 4);
+ PUSH_DATAh(push, screen->tls->offset);
+ PUSH_DATA (push, screen->tls->offset);
+ PUSH_DATA (push, screen->tls_size >> 32);
+ PUSH_DATA (push, screen->tls_size);
+ BEGIN_NVC0(push, NVC0_3D(WARP_TEMP_ALLOC), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(LOCAL_BASE), 1);
+ PUSH_DATA (push, 0);
for (i = 0; i < 5; ++i) {
- BEGIN_RING(chan, RING_3D(TEX_LIMITS(i)), 1);
- OUT_RING (chan, 0x54);
+ BEGIN_NVC0(push, NVC0_3D(TEX_LIMITS(i)), 1);
+ PUSH_DATA (push, 0x54);
}
- BEGIN_RING(chan, RING_3D(LINKED_TSC), 1);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, NVC0_3D(LINKED_TSC), 1);
+ PUSH_DATA (push, 0);
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20,
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, NULL,
&screen->vfetch_cache);
if (ret)
goto fail;
- BEGIN_RING(chan, RING_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
- OUT_RELOCh(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RING (chan, 3);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->vfetch_cache->offset);
+ PUSH_DATA (push, screen->vfetch_cache->offset);
+ PUSH_DATA (push, 3);
- ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc);
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, NULL,
+ &screen->txc);
if (ret)
goto fail;
- 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, NVC0_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, NVC0_TSC_MAX_ENTRIES - 1);
-
- 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_(0x1590), 1); /* deactivate ZCULL */
- OUT_RING (chan, 0x3f);
-
- BEGIN_RING(chan, RING_3D(CLIP_RECTS_MODE), 1);
- OUT_RING (chan, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
- BEGIN_RING(chan, RING_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
+ BEGIN_NVC0(push, NVC0_3D(TIC_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->txc->offset);
+ PUSH_DATA (push, screen->txc->offset);
+ PUSH_DATA (push, NVC0_TIC_MAX_ENTRIES - 1);
+
+ BEGIN_NVC0(push, NVC0_3D(TSC_ADDRESS_HIGH), 3);
+ PUSH_DATAh(push, screen->txc->offset + 65536);
+ PUSH_DATA (push, screen->txc->offset + 65536);
+ PUSH_DATA (push, NVC0_TSC_MAX_ENTRIES - 1);
+
+ BEGIN_NVC0(push, NVC0_3D(SCREEN_Y_CONTROL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(WINDOW_OFFSET_X), 2);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1); /* deactivate ZCULL */
+ PUSH_DATA (push, 0x3f);
+
+ BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_MODE), 1);
+ PUSH_DATA (push, NVC0_3D_CLIP_RECTS_MODE_INSIDE_ANY);
+ BEGIN_NVC0(push, NVC0_3D(CLIP_RECT_HORIZ(0)), 8 * 2);
for (i = 0; i < 8 * 2; ++i)
- OUT_RING(chan, 0);
- BEGIN_RING(chan, RING_3D(CLIP_RECTS_EN), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(CLIPID_ENABLE), 1);
- OUT_RING (chan, 0);
+ PUSH_DATA(push, 0);
+ BEGIN_NVC0(push, NVC0_3D(CLIP_RECTS_EN), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(CLIPID_ENABLE), 1);
+ PUSH_DATA (push, 0);
/* neither scissors, viewport nor stencil mask should affect clears */
- BEGIN_RING(chan, RING_3D(CLEAR_FLAGS), 1);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_FLAGS), 1);
+ PUSH_DATA (push, 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);
- OUT_RING (chan, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 1.0f);
+ BEGIN_NVC0(push, NVC0_3D(VIEW_VOLUME_CLIP_CTRL), 1);
+ PUSH_DATA (push, NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1);
/* 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_NVC0(push, NVC0_3D(SCISSOR_ENABLE(0)), 3);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 8192 << 16);
+ PUSH_DATA (push, 8192 << 16);
#define MK_MACRO(m, n) i = nvc0_graph_set_macro(screen, m, i, sizeof(n), n);
@@ -627,41 +635,42 @@ nvc0_screen_create(struct nouveau_device *dev)
MK_MACRO(NVC0_3D_POLYGON_MODE_FRONT, nvc0_9097_poly_mode_front);
MK_MACRO(NVC0_3D_POLYGON_MODE_BACK, nvc0_9097_poly_mode_back);
- BEGIN_RING(chan, RING_3D(RASTERIZE_ENABLE), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(RT_SEPARATE_FRAG_DATA), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
- OUT_RING (chan, 0x40);
- BEGIN_RING(chan, RING_3D(LAYER), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
- OUT_RING (chan, 0x30);
- BEGIN_RING(chan, RING_3D(PATCH_VERTICES), 1);
- OUT_RING (chan, 3);
- BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1);
- OUT_RING (chan, 0x20);
- BEGIN_RING(chan, RING_3D(SP_SELECT(0)), 1);
- OUT_RING (chan, 0x00);
-
- BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1);
- OUT_RING (chan, NVC0_3D_POINT_RASTER_RULES_OGL);
-
- BEGIN_RING(chan, RING_3D(EDGEFLAG_ENABLE), 1);
- OUT_RING (chan, 1);
-
- BEGIN_RING(chan, RING_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
- OUT_RING (chan, 0xab);
- OUT_RING (chan, 0x00000000);
-
- FIRE_RING (chan);
+ BEGIN_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(RT_SEPARATE_FRAG_DATA), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
+ PUSH_DATA (push, 0x40);
+ BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
+ PUSH_DATA (push, 0x30);
+ BEGIN_NVC0(push, NVC0_3D(PATCH_VERTICES), 1);
+ PUSH_DATA (push, 3);
+ BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
+ PUSH_DATA (push, 0x20);
+ BEGIN_NVC0(push, NVC0_3D(SP_SELECT(0)), 1);
+ PUSH_DATA (push, 0x00);
+
+ BEGIN_NVC0(push, NVC0_3D(POINT_COORD_REPLACE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(POINT_RASTER_RULES), 1);
+ PUSH_DATA (push, NVC0_3D_POINT_RASTER_RULES_OGL);
+
+ IMMED_NVC0(push, NVC0_3D(EDGEFLAG), 1);
+
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_RUNOUT_ADDRESS_HIGH), 2);
+ PUSH_DATA (push, 0xab);
+ PUSH_DATA (push, 0x00000000);
+
+ PUSH_KICK (push);
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);
+ mm_config.nvc0.tile_mode = 0;
+ mm_config.nvc0.memtype = 0xfe0;
+ screen->mm_VRAM_fe0 = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
if (!nvc0_blitctx_create(screen))
goto fail;
@@ -675,23 +684,6 @@ fail:
return NULL;
}
-void
-nvc0_screen_make_buffers_resident(struct nvc0_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->text, flags);
- nouveau_bo_validate(chan, screen->uniforms, flags);
- nouveau_bo_validate(chan, screen->txc, flags);
- nouveau_bo_validate(chan, screen->vfetch_cache, flags);
-
- if (screen->cur_ctx && screen->cur_ctx->state.tls_required)
- nouveau_bo_validate(chan, screen->tls, flags);
-}
-
int
nvc0_screen_tic_alloc(struct nvc0_screen *screen, void *entry)
{
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h
index be42970ca39..9abf4b1fd3d 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.h
+++ b/src/gallium/drivers/nvc0/nvc0_screen.h
@@ -1,11 +1,11 @@
#ifndef __NVC0_SCREEN_H__
#define __NVC0_SCREEN_H__
-#define NOUVEAU_NVC0
#include "nouveau/nouveau_screen.h"
#include "nouveau/nouveau_mm.h"
#include "nouveau/nouveau_fence.h"
-#undef NOUVEAU_NVC0
+#include "nouveau/nouveau_heap.h"
+
#include "nvc0_winsys.h"
#include "nvc0_stateobj.h"
@@ -36,8 +36,8 @@ struct nvc0_screen {
uint64_t tls_size;
- struct nouveau_resource *text_heap;
- struct nouveau_resource *lib_code; /* allocated from text_heap */
+ struct nouveau_heap *text_heap;
+ struct nouveau_heap *lib_code; /* allocated from text_heap */
struct nvc0_blitctx *blitctx;
@@ -67,9 +67,10 @@ struct nvc0_screen {
struct nouveau_mman *mm_VRAM_fe0;
- struct nouveau_grobj *fermi;
- struct nouveau_grobj *eng2d;
- struct nouveau_grobj *m2mf;
+ struct nouveau_object *fermi;
+ struct nouveau_object *eng2d;
+ struct nouveau_object *m2mf;
+ struct nouveau_object *dijkstra;
};
static INLINE struct nvc0_screen *
@@ -92,7 +93,6 @@ nvc0_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);
}
@@ -101,11 +101,7 @@ nvc0_resource_fence(struct nv04_resource *res, uint32_t flags)
static INLINE void
nvc0_resource_validate(struct nv04_resource *res, uint32_t flags)
{
- struct nvc0_screen *screen = nvc0_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/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c
index 9945b8e7b1f..9d688843473 100644
--- a/src/gallium/drivers/nvc0/nvc0_shader_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c
@@ -31,29 +31,33 @@ static INLINE void
nvc0_program_update_context_state(struct nvc0_context *nvc0,
struct nvc0_program *prog, int stage)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- if (prog->hdr[1])
+ if (prog && prog->need_tls) {
+ const uint32_t flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR;
+ if (!nvc0->state.tls_required)
+ BCTX_REFN_bo(nvc0->bufctx_3d, TLS, flags, nvc0->screen->tls);
nvc0->state.tls_required |= 1 << stage;
- else
+ } else {
+ if (nvc0->state.tls_required == (1 << stage))
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TLS);
nvc0->state.tls_required &= ~(1 << stage);
+ }
- if (prog->immd_size) {
- const unsigned rl = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD;
-
- BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
+ if (prog && prog->immd_size) {
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
/* NOTE: may overlap code of a different shader */
- OUT_RING (chan, align(prog->immd_size, 0x100));
- OUT_RELOCh(chan, nvc0->screen->text, prog->immd_base, rl);
- OUT_RELOCl(chan, nvc0->screen->text, prog->immd_base, rl);
- BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
- OUT_RING (chan, (14 << 4) | 1);
+ PUSH_DATA (push, align(prog->immd_size, 0x100));
+ PUSH_DATAh(push, nvc0->screen->text->offset + prog->immd_base);
+ PUSH_DATA (push, nvc0->screen->text->offset + prog->immd_base);
+ BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
+ PUSH_DATA (push, (14 << 4) | 1);
nvc0->state.c14_bound |= 1 << stage;
} else
if (nvc0->state.c14_bound & (1 << stage)) {
- BEGIN_RING(chan, RING_3D(CB_BIND(stage)), 1);
- OUT_RING (chan, (14 << 4) | 0);
+ BEGIN_NVC0(push, NVC0_3D(CB_BIND(stage)), 1);
+ PUSH_DATA (push, (14 << 4) | 0);
nvc0->state.c14_bound &= ~(1 << stage);
}
@@ -62,7 +66,7 @@ nvc0_program_update_context_state(struct nvc0_context *nvc0,
static INLINE boolean
nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
{
- if (prog->res)
+ if (prog->mem)
return TRUE;
if (!prog->translated) {
@@ -79,133 +83,129 @@ nvc0_program_validate(struct nvc0_context *nvc0, struct nvc0_program *prog)
void
nvc0_vertprog_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *vp = nvc0->vertprog;
if (!nvc0_program_validate(nvc0, vp))
return;
nvc0_program_update_context_state(nvc0, vp, 0);
- BEGIN_RING(chan, RING_3D(SP_SELECT(1)), 2);
- OUT_RING (chan, 0x11);
- OUT_RING (chan, vp->code_base);
- BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(1)), 1);
- OUT_RING (chan, vp->max_gpr);
+ BEGIN_NVC0(push, NVC0_3D(SP_SELECT(1)), 2);
+ PUSH_DATA (push, 0x11);
+ PUSH_DATA (push, vp->code_base);
+ BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(1)), 1);
+ PUSH_DATA (push, vp->max_gpr);
- // BEGIN_RING(chan, RING_3D_(0x163c), 1);
- // OUT_RING (chan, 0);
+ // BEGIN_NVC0(push, NVC0_3D_(0x163c), 1);
+ // PUSH_DATA (push, 0);
}
void
nvc0_fragprog_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *fp = nvc0->fragprog;
if (!nvc0_program_validate(nvc0, fp))
return;
nvc0_program_update_context_state(nvc0, fp, 4);
- BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2);
- OUT_RING (chan, 0x51);
- OUT_RING (chan, fp->code_base);
- BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(5)), 1);
- OUT_RING (chan, fp->max_gpr);
-
- BEGIN_RING(chan, RING_3D_(0x0360), 2);
- OUT_RING (chan, 0x20164010);
- OUT_RING (chan, 0x20);
- BEGIN_RING(chan, RING_3D_(0x196c), 1);
- OUT_RING (chan, fp->flags[0]);
+ BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2);
+ PUSH_DATA (push, 0x51);
+ PUSH_DATA (push, fp->code_base);
+ BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(5)), 1);
+ PUSH_DATA (push, fp->max_gpr);
+
+ BEGIN_NVC0(push, SUBC_3D(0x0360), 2);
+ PUSH_DATA (push, 0x20164010);
+ PUSH_DATA (push, 0x20);
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_TEST_MASK), 1);
+ PUSH_DATA (push, fp->flags[0]);
}
void
nvc0_tctlprog_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *tp = nvc0->tctlprog;
- if (!tp) {
- BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 1);
- OUT_RING (chan, 0x20);
- return;
+ if (tp && nvc0_program_validate(nvc0, tp)) {
+ if (tp->tp.tess_mode != ~0) {
+ BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
+ PUSH_DATA (push, tp->tp.tess_mode);
+ }
+ BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 2);
+ PUSH_DATA (push, 0x21);
+ PUSH_DATA (push, tp->code_base);
+ BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(2)), 1);
+ PUSH_DATA (push, tp->max_gpr);
+
+ if (tp->tp.input_patch_size <= 32)
+ IMMED_NVC0(push, NVC0_3D(PATCH_VERTICES), tp->tp.input_patch_size);
+ } else {
+ BEGIN_NVC0(push, NVC0_3D(SP_SELECT(2)), 1);
+ PUSH_DATA (push, 0x20);
}
- if (!nvc0_program_validate(nvc0, tp))
- return;
nvc0_program_update_context_state(nvc0, tp, 1);
-
- if (tp->tp.tess_mode != ~0) {
- BEGIN_RING(chan, RING_3D(TESS_MODE), 1);
- OUT_RING (chan, tp->tp.tess_mode);
- }
- BEGIN_RING(chan, RING_3D(SP_SELECT(2)), 2);
- OUT_RING (chan, 0x21);
- OUT_RING (chan, tp->code_base);
- BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(2)), 1);
- OUT_RING (chan, tp->max_gpr);
-
- if (tp->tp.input_patch_size <= 32)
- IMMED_RING(chan, RING_3D(PATCH_VERTICES), tp->tp.input_patch_size);
}
void
nvc0_tevlprog_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *tp = nvc0->tevlprog;
- if (!tp) {
- BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
- OUT_RING (chan, 0x30);
- return;
+ if (tp && nvc0_program_validate(nvc0, tp)) {
+ if (tp->tp.tess_mode != ~0) {
+ BEGIN_NVC0(push, NVC0_3D(TESS_MODE), 1);
+ PUSH_DATA (push, tp->tp.tess_mode);
+ }
+ BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
+ PUSH_DATA (push, 0x31);
+ BEGIN_NVC0(push, NVC0_3D(SP_START_ID(3)), 1);
+ PUSH_DATA (push, tp->code_base);
+ BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(3)), 1);
+ PUSH_DATA (push, tp->max_gpr);
+ } else {
+ BEGIN_NVC0(push, NVC0_3D(TEP_SELECT), 1);
+ PUSH_DATA (push, 0x30);
}
- if (!nvc0_program_validate(nvc0, tp))
- return;
nvc0_program_update_context_state(nvc0, tp, 2);
-
- if (tp->tp.tess_mode != ~0) {
- BEGIN_RING(chan, RING_3D(TESS_MODE), 1);
- OUT_RING (chan, tp->tp.tess_mode);
- }
- BEGIN_RING(chan, RING_3D(TEP_SELECT), 1);
- OUT_RING (chan, 0x31);
- BEGIN_RING(chan, RING_3D(SP_START_ID(3)), 1);
- OUT_RING (chan, tp->code_base);
- BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(3)), 1);
- OUT_RING (chan, tp->max_gpr);
}
void
nvc0_gmtyprog_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *gp = nvc0->gmtyprog;
if (gp)
nvc0_program_validate(nvc0, gp);
+
/* we allow GPs with no code for specifying stream output state only */
- if (!gp || !gp->code_size) {
- BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
- OUT_RING (chan, 0x40);
- IMMED_RING(chan, RING_3D(LAYER), 0);
- return;
+ if (gp && gp->code_size) {
+ const boolean gp_selects_layer = gp->hdr[13] & (1 << 9);
+
+ BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
+ PUSH_DATA (push, 0x41);
+ BEGIN_NVC0(push, NVC0_3D(SP_START_ID(4)), 1);
+ PUSH_DATA (push, gp->code_base);
+ BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(4)), 1);
+ PUSH_DATA (push, gp->max_gpr);
+ BEGIN_NVC0(push, NVC0_3D(LAYER), 1);
+ PUSH_DATA (push, gp_selects_layer ? NVC0_3D_LAYER_USE_GP : 0);
+ } else {
+ IMMED_NVC0(push, NVC0_3D(LAYER), 0);
+ BEGIN_NVC0(push, NVC0_3D(GP_SELECT), 1);
+ PUSH_DATA (push, 0x40);
}
nvc0_program_update_context_state(nvc0, gp, 3);
-
- BEGIN_RING(chan, RING_3D(GP_SELECT), 1);
- OUT_RING (chan, 0x41);
- BEGIN_RING(chan, RING_3D(SP_START_ID(4)), 1);
- OUT_RING (chan, gp->code_base);
- BEGIN_RING(chan, RING_3D(SP_GPR_ALLOC(4)), 1);
- OUT_RING (chan, gp->max_gpr);
- BEGIN_RING(chan, RING_3D(LAYER), 1);
- OUT_RING (chan, (gp->hdr[13] & (1 << 9)) ? NVC0_3D_LAYER_USE_GP : 0);
}
void
nvc0_tfb_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_transform_feedback_state *tfb;
unsigned b;
@@ -215,24 +215,24 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
else
tfb = nvc0->vertprog->tfb;
- IMMED_RING(chan, RING_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
+ IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), (tfb && nvc0->num_tfbbufs) ? 1 : 0);
if (tfb && tfb != nvc0->state.tfb) {
for (b = 0; b < 4; ++b) {
if (tfb->varying_count[b]) {
unsigned n = (tfb->varying_count[b] + 3) / 4;
- BEGIN_RING(chan, RING_3D(TFB_STREAM(b)), 3);
- OUT_RING (chan, 0);
- OUT_RING (chan, tfb->varying_count[b]);
- OUT_RING (chan, tfb->stride[b]);
- BEGIN_RING(chan, RING_3D(TFB_VARYING_LOCS(b, 0)), n);
- OUT_RINGp (chan, tfb->varying_index[b], n);
+ BEGIN_NVC0(push, NVC0_3D(TFB_STREAM(b)), 3);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, tfb->varying_count[b]);
+ PUSH_DATA (push, tfb->stride[b]);
+ BEGIN_NVC0(push, NVC0_3D(TFB_VARYING_LOCS(b, 0)), n);
+ PUSH_DATAp(push, tfb->varying_index[b], n);
if (nvc0->tfbbuf[b])
nvc0_so_target(nvc0->tfbbuf[b])->stride = tfb->stride[b];
} else {
- IMMED_RING(chan, RING_3D(TFB_VARYING_COUNT(b)), 0);
+ IMMED_NVC0(push, NVC0_3D(TFB_VARYING_COUNT(b)), 0);
}
}
}
@@ -240,7 +240,7 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
if (!(nvc0->dirty & NVC0_NEW_TFB_TARGETS))
return;
- nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TFB);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TFB);
for (b = 0; b < nvc0->num_tfbbufs; ++b) {
struct nvc0_so_target *targ = nvc0_so_target(nvc0->tfbbuf[b]);
@@ -253,20 +253,20 @@ nvc0_tfb_validate(struct nvc0_context *nvc0)
continue;
if (!targ->clean)
- nvc0_query_fifo_wait(chan, targ->pq);
- BEGIN_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 5);
- OUT_RING (chan, 1);
- OUT_RESRCh(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR);
- OUT_RESRCl(chan, buf, targ->pipe.buffer_offset, NOUVEAU_BO_WR);
- OUT_RING (chan, targ->pipe.buffer_size);
+ nvc0_query_fifo_wait(push, targ->pq);
+ BEGIN_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 5);
+ PUSH_DATA (push, 1);
+ PUSH_DATAh(push, buf->address + targ->pipe.buffer_offset);
+ PUSH_DATA (push, buf->address + targ->pipe.buffer_offset);
+ PUSH_DATA (push, targ->pipe.buffer_size);
if (!targ->clean) {
- nvc0_query_pushbuf_submit(chan, targ->pq, 0x4);
+ nvc0_query_pushbuf_submit(push, targ->pq, 0x4);
} else {
- OUT_RING(chan, 0); /* TFB_BUFFER_OFFSET */
+ PUSH_DATA(push, 0); /* TFB_BUFFER_OFFSET */
targ->clean = FALSE;
}
- nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TFB, buf, NOUVEAU_BO_WR);
+ BCTX_REFN(nvc0->bufctx_3d, TFB, buf, WR);
}
for (; b < 4; ++b)
- IMMED_RING(chan, RING_3D(TFB_BUFFER_ENABLE(b)), 0);
+ IMMED_NVC0(push, NVC0_3D(TFB_BUFFER_ENABLE(b)), 0);
}
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index 32b7a8a8ecf..e349491b66e 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -489,7 +489,7 @@ nvc0_stage_set_sampler_views(struct nvc0_context *nvc0, int s,
nvc0->num_textures[s] = nr;
- nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_TEXTURES);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX);
nvc0->dirty |= NVC0_NEW_TEXTURES;
}
@@ -621,8 +621,7 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
}
if (nvc0->constbuf[shader][index])
- nvc0_bufctx_del_resident(nvc0, NVC0_BUFCTX_CONSTANT,
- nv04_resource(nvc0->constbuf[shader][index]));
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_CB(shader, index));
pipe_resource_reference(&nvc0->constbuf[shader][index], res);
@@ -681,6 +680,8 @@ nvc0_set_framebuffer_state(struct pipe_context *pipe,
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
+
nvc0->framebuffer = *fb;
nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
}
@@ -731,7 +732,7 @@ nvc0_set_vertex_buffers(struct pipe_context *pipe,
memcpy(nvc0->vtxbuf, vb, sizeof(*vb) * count);
nvc0->num_vtxbufs = count;
- nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
nvc0->dirty |= NVC0_NEW_ARRAYS;
}
@@ -742,11 +743,16 @@ nvc0_set_index_buffer(struct pipe_context *pipe,
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- if (ib) {
- pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
+ if (nvc0->idxbuf.buffer)
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_IDX);
- memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf));
+ if (ib && ib->buffer) {
+ nvc0->dirty |= NVC0_NEW_IDXBUF;
+ pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer);
+ nvc0->idxbuf.offset = ib->offset;
+ nvc0->idxbuf.index_size = ib->index_size;
} else {
+ nvc0->dirty &= ~NVC0_NEW_IDXBUF;
pipe_resource_reference(&nvc0->idxbuf.buffer, NULL);
}
}
diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c
index 6307b3a3de6..f235ba57e36 100644
--- a/src/gallium/drivers/nvc0/nvc0_state_validate.c
+++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c
@@ -6,7 +6,7 @@
static void
nvc0_validate_zcull(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
struct nv50_miptree *mt = nv50_miptree(sf->base.texture);
@@ -26,89 +26,85 @@ nvc0_validate_zcull(struct nvc0_context *nvc0)
else
width = fb->width;
- MARK_RING (chan, 23, 4);
- BEGIN_RING(chan, RING_3D_(0x1590), 1); /* ZCULL_REGION_INDEX (bits 0x3f) */
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D_(0x07e8), 2); /* ZCULL_ADDRESS_A_HIGH */
- OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_REGION), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_ADDRESS_HIGH), 2);
+ PUSH_DATAh(push, bo->offset + offset);
+ PUSH_DATA (push, bo->offset + offset);
offset += 1 << 17;
- BEGIN_RING(chan, RING_3D_(0x07f0), 2); /* ZCULL_ADDRESS_B_HIGH */
- OUT_RELOCh(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, bo, offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
- BEGIN_RING(chan, RING_3D_(0x07e0), 2);
- OUT_RING (chan, size);
- OUT_RING (chan, size >> 16);
- BEGIN_RING(chan, RING_3D_(0x15c8), 1); /* bits 0x3 */
- OUT_RING (chan, 2);
- BEGIN_RING(chan, RING_3D_(0x07c0), 4); /* ZCULL dimensions */
- OUT_RING (chan, width);
- OUT_RING (chan, height);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D_(0x15fc), 2);
- OUT_RING (chan, 0); /* bits 0xffff */
- OUT_RING (chan, 0); /* bits 0xffff */
- BEGIN_RING(chan, RING_3D_(0x1958), 1);
- OUT_RING (chan, 0); /* bits ~0 */
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_LIMIT_HIGH), 2);
+ PUSH_DATAh(push, bo->offset + offset);
+ PUSH_DATA (push, bo->offset + offset);
+ BEGIN_NVC0(push, SUBC_3D(0x07e0), 2);
+ PUSH_DATA (push, size);
+ PUSH_DATA (push, size >> 16);
+ BEGIN_NVC0(push, SUBC_3D(0x15c8), 1); /* bits 0x3 */
+ PUSH_DATA (push, 2);
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_WIDTH), 4);
+ PUSH_DATA (push, width);
+ PUSH_DATA (push, height);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_WINDOW_OFFSET_X), 2);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(ZCULL_INVALIDATE), 1);
+ PUSH_DATA (push, 0);
}
static void
nvc0_validate_fb(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
unsigned i;
unsigned ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS1;
boolean serialize = FALSE;
- nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_FRAME);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_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_NVC0(push, NVC0_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, (076543210 << 4) | fb->nr_cbufs);
+ BEGIN_NVC0(push, NVC0_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_surface *sf = nv50_surface(fb->cbufs[i]);
struct nv04_resource *res = nv04_resource(sf->base.texture);
struct nouveau_bo *bo = res->bo;
- uint32_t offset = sf->offset + res->offset;
- BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(i)), 9);
- OUT_RELOCh(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR);
- OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RDWR);
- if (likely(nouveau_bo_tile_layout(bo))) {
+ BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(i)), 9);
+ PUSH_DATAh(push, res->address + sf->offset);
+ PUSH_DATA (push, res->address + sf->offset);
+ if (likely(nouveau_bo_memtype(bo))) {
struct nv50_miptree *mt = nv50_miptree(sf->base.texture);
assert(sf->base.texture->target != PIPE_BUFFER);
- OUT_RING(chan, sf->width);
- OUT_RING(chan, sf->height);
- OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
- OUT_RING(chan, (mt->layout_3d << 16) |
+ PUSH_DATA(push, sf->width);
+ PUSH_DATA(push, sf->height);
+ PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
+ PUSH_DATA(push, (mt->layout_3d << 16) |
mt->level[sf->base.u.tex.level].tile_mode);
- OUT_RING(chan, sf->base.u.tex.first_layer + sf->depth);
- OUT_RING(chan, mt->layer_stride >> 2);
- OUT_RING(chan, sf->base.u.tex.first_layer);
+ PUSH_DATA(push, sf->base.u.tex.first_layer + sf->depth);
+ PUSH_DATA(push, mt->layer_stride >> 2);
+ PUSH_DATA(push, sf->base.u.tex.first_layer);
ms_mode = mt->ms_mode;
} else {
if (res->base.target == PIPE_BUFFER) {
- OUT_RING(chan, 262144);
- OUT_RING(chan, 1);
+ PUSH_DATA(push, 262144);
+ PUSH_DATA(push, 1);
} else {
- OUT_RING(chan, nv50_miptree(sf->base.texture)->level[0].pitch);
- OUT_RING(chan, sf->height);
+ PUSH_DATA(push, nv50_miptree(sf->base.texture)->level[0].pitch);
+ PUSH_DATA(push, sf->height);
}
- OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
- OUT_RING(chan, 1 << 12);
- OUT_RING(chan, 1);
- OUT_RING(chan, 0);
- OUT_RING(chan, 0);
+ PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
+ PUSH_DATA(push, 1 << 12);
+ PUSH_DATA(push, 1);
+ PUSH_DATA(push, 0);
+ PUSH_DATA(push, 0);
nvc0_resource_fence(res, NOUVEAU_BO_WR);
@@ -121,33 +117,29 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
/* only register for writing, otherwise we'd always serialize here */
- nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, res,
- res->domain | NOUVEAU_BO_WR);
+ BCTX_REFN(nvc0->bufctx_3d, FB, res, WR);
}
if (fb->zsbuf) {
struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
- struct nouveau_bo *bo = mt->base.bo;
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
- 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, nvc0_format_table[fb->zsbuf->format].rt);
- OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode);
- 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) |
+
+ BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
+ PUSH_DATAh(push, mt->base.address + sf->offset);
+ PUSH_DATA (push, mt->base.address + sf->offset);
+ PUSH_DATA (push, nvc0_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_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
+ PUSH_DATA (push, sf->width);
+ PUSH_DATA (push, sf->height);
+ PUSH_DATA (push, (unk << 16) |
(sf->base.u.tex.first_layer + sf->depth));
- BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1);
- OUT_RING (chan, sf->base.u.tex.first_layer);
+ BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
+ PUSH_DATA (push, sf->base.u.tex.first_layer);
ms_mode = mt->ms_mode;
@@ -156,58 +148,55 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING;
mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING;
- nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BCTX_REFN(nvc0->bufctx_3d, FB, &mt->base, WR);
} else {
- BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
+ PUSH_DATA (push, 0);
}
- IMMED_RING(chan, RING_3D(MULTISAMPLE_MODE), ms_mode);
+ IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_MODE), ms_mode);
- if (serialize) {
- BEGIN_RING(chan, RING_3D(SERIALIZE), 1);
- OUT_RING (chan, 0);
- }
+ if (serialize)
+ IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
}
static void
nvc0_validate_blend_colour(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- BEGIN_RING(chan, RING_3D(BLEND_COLOR(0)), 4);
- OUT_RINGf (chan, nvc0->blend_colour.color[0]);
- OUT_RINGf (chan, nvc0->blend_colour.color[1]);
- OUT_RINGf (chan, nvc0->blend_colour.color[2]);
- OUT_RINGf (chan, nvc0->blend_colour.color[3]);
+ BEGIN_NVC0(push, NVC0_3D(BLEND_COLOR(0)), 4);
+ PUSH_DATAf(push, nvc0->blend_colour.color[0]);
+ PUSH_DATAf(push, nvc0->blend_colour.color[1]);
+ PUSH_DATAf(push, nvc0->blend_colour.color[2]);
+ PUSH_DATAf(push, nvc0->blend_colour.color[3]);
}
static void
nvc0_validate_stencil_ref(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
const ubyte *ref = &nvc0->stencil_ref.ref_value[0];
- IMMED_RING(chan, RING_3D(STENCIL_FRONT_FUNC_REF), ref[0]);
- IMMED_RING(chan, RING_3D(STENCIL_BACK_FUNC_REF), ref[1]);
+ IMMED_NVC0(push, NVC0_3D(STENCIL_FRONT_FUNC_REF), ref[0]);
+ IMMED_NVC0(push, NVC0_3D(STENCIL_BACK_FUNC_REF), ref[1]);
}
static void
nvc0_validate_stipple(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
unsigned i;
- BEGIN_RING(chan, RING_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
+ BEGIN_NVC0(push, NVC0_3D(POLYGON_STIPPLE_PATTERN(0)), 32);
for (i = 0; i < 32; ++i)
- OUT_RING(chan, util_bswap32(nvc0->stipple.stipple[i]));
+ PUSH_DATA(push, util_bswap32(nvc0->stipple.stipple[i]));
}
static void
nvc0_validate_scissor(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct pipe_scissor_state *s = &nvc0->scissor;
if (!(nvc0->dirty & NVC0_NEW_SCISSOR) &&
@@ -215,32 +204,32 @@ nvc0_validate_scissor(struct nvc0_context *nvc0)
return;
nvc0->state.scissor = nvc0->rast->pipe.scissor;
- BEGIN_RING(chan, RING_3D(SCISSOR_HORIZ(0)), 2);
+ BEGIN_NVC0(push, NVC0_3D(SCISSOR_HORIZ(0)), 2);
if (nvc0->rast->pipe.scissor) {
- OUT_RING(chan, (s->maxx << 16) | s->minx);
- OUT_RING(chan, (s->maxy << 16) | s->miny);
+ PUSH_DATA(push, (s->maxx << 16) | s->minx);
+ PUSH_DATA(push, (s->maxy << 16) | s->miny);
} else {
- OUT_RING(chan, (0xffff << 16) | 0);
- OUT_RING(chan, (0xffff << 16) | 0);
+ PUSH_DATA(push, (0xffff << 16) | 0);
+ PUSH_DATA(push, (0xffff << 16) | 0);
}
}
static void
nvc0_validate_viewport(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct pipe_viewport_state *vp = &nvc0->viewport;
int x, y, w, h;
float zmin, zmax;
- BEGIN_RING(chan, RING_3D(VIEWPORT_TRANSLATE_X(0)), 3);
- OUT_RINGf (chan, vp->translate[0]);
- OUT_RINGf (chan, vp->translate[1]);
- OUT_RINGf (chan, vp->translate[2]);
- BEGIN_RING(chan, RING_3D(VIEWPORT_SCALE_X(0)), 3);
- OUT_RINGf (chan, vp->scale[0]);
- OUT_RINGf (chan, vp->scale[1]);
- OUT_RINGf (chan, vp->scale[2]);
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_TRANSLATE_X(0)), 3);
+ PUSH_DATAf(push, vp->translate[0]);
+ PUSH_DATAf(push, vp->translate[1]);
+ PUSH_DATAf(push, vp->translate[2]);
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_SCALE_X(0)), 3);
+ PUSH_DATAf(push, vp->scale[0]);
+ PUSH_DATAf(push, vp->scale[1]);
+ PUSH_DATAf(push, vp->scale[2]);
/* now set the viewport rectangle to viewport dimensions for clipping */
@@ -252,28 +241,27 @@ nvc0_validate_viewport(struct nvc0_context *nvc0)
zmin = vp->translate[2] - fabsf(vp->scale[2]);
zmax = vp->translate[2] + fabsf(vp->scale[2]);
- BEGIN_RING(chan, RING_3D(VIEWPORT_HORIZ(0)), 2);
- OUT_RING (chan, (w << 16) | x);
- OUT_RING (chan, (h << 16) | y);
- BEGIN_RING(chan, RING_3D(DEPTH_RANGE_NEAR(0)), 2);
- OUT_RINGf (chan, zmin);
- OUT_RINGf (chan, zmax);
+ BEGIN_NVC0(push, NVC0_3D(VIEWPORT_HORIZ(0)), 2);
+ PUSH_DATA (push, (w << 16) | x);
+ PUSH_DATA (push, (h << 16) | y);
+ BEGIN_NVC0(push, NVC0_3D(DEPTH_RANGE_NEAR(0)), 2);
+ PUSH_DATAf(push, zmin);
+ PUSH_DATAf(push, zmax);
}
static INLINE void
nvc0_upload_uclip_planes(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nouveau_bo *bo = nvc0->screen->uniforms;
- MARK_RING (chan, 6 + PIPE_MAX_CLIP_PLANES * 4, 2);
- BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
- OUT_RING (chan, 256);
- OUT_RELOCh(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, bo, 5 << 16, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- BEGIN_RING_1I(chan, RING_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1);
- OUT_RING (chan, 0);
- OUT_RINGp (chan, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+ PUSH_DATA (push, 256);
+ PUSH_DATAh(push, bo->offset + (5 << 16));
+ PUSH_DATA (push, bo->offset + (5 << 16));
+ BEGIN_1IC0(push, NVC0_3D(CB_POS), PIPE_MAX_CLIP_PLANES * 4 + 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATAp(push, &nvc0->clip.ucp[0][0], PIPE_MAX_CLIP_PLANES * 4);
}
static INLINE void
@@ -299,7 +287,7 @@ nvc0_check_program_ucps(struct nvc0_context *nvc0,
static void
nvc0_validate_clip(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *vp;
uint8_t clip_enable = nvc0->rast->pipe.clip_plane_enable;
@@ -320,46 +308,46 @@ nvc0_validate_clip(struct nvc0_context *nvc0)
if (nvc0->state.clip_enable != clip_enable) {
nvc0->state.clip_enable = clip_enable;
- IMMED_RING(chan, RING_3D(CLIP_DISTANCE_ENABLE), clip_enable);
+ IMMED_NVC0(push, NVC0_3D(CLIP_DISTANCE_ENABLE), clip_enable);
}
if (nvc0->state.clip_mode != vp->vp.clip_mode) {
nvc0->state.clip_mode = vp->vp.clip_mode;
- BEGIN_RING(chan, RING_3D(CLIP_DISTANCE_MODE), 1);
- OUT_RING (chan, vp->vp.clip_mode);
+ BEGIN_NVC0(push, NVC0_3D(CLIP_DISTANCE_MODE), 1);
+ PUSH_DATA (push, vp->vp.clip_mode);
}
}
static void
nvc0_validate_blend(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- WAIT_RING(chan, nvc0->blend->size);
- OUT_RINGp(chan, nvc0->blend->state, nvc0->blend->size);
+ PUSH_SPACE(push, nvc0->blend->size);
+ PUSH_DATAp(push, nvc0->blend->state, nvc0->blend->size);
}
static void
nvc0_validate_zsa(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- WAIT_RING(chan, nvc0->zsa->size);
- OUT_RINGp(chan, nvc0->zsa->state, nvc0->zsa->size);
+ PUSH_SPACE(push, nvc0->zsa->size);
+ PUSH_DATAp(push, nvc0->zsa->state, nvc0->zsa->size);
}
static void
nvc0_validate_rasterizer(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
- WAIT_RING(chan, nvc0->rast->size);
- OUT_RINGp(chan, nvc0->rast->state, nvc0->rast->size);
+ PUSH_SPACE(push, nvc0->rast->size);
+ PUSH_DATAp(push, nvc0->rast->state, nvc0->rast->size);
}
static void
nvc0_constbufs_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nouveau_bo *bo;
unsigned s;
@@ -377,8 +365,8 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
res = nv04_resource(nvc0->constbuf[s][i]);
if (!res) {
- BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
- OUT_RING (chan, (i << 4) | 0);
+ BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+ PUSH_DATA (push, (i << 4) | 0);
if (i == 0)
nvc0->state.uniform_buffer_bound[s] = 0;
continue;
@@ -409,17 +397,15 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
}
if (bo != nvc0->screen->uniforms)
- nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_CONSTANT, res,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
if (rebind) {
- MARK_RING (chan, 4, 2);
- BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
- OUT_RING (chan, align(res->base.width0, 0x100));
- OUT_RELOCh(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, bo, base, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- BEGIN_RING(chan, RING_3D(CB_BIND(s)), 1);
- OUT_RING (chan, (i << 4) | 1);
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+ PUSH_DATA (push, align(res->base.width0, 0x100));
+ PUSH_DATAh(push, bo->offset + base);
+ PUSH_DATA (push, bo->offset + base);
+ BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
+ PUSH_DATA (push, (i << 4) | 1);
}
if (words)
@@ -433,7 +419,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
static void
nvc0_validate_sample_mask(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
unsigned mask[4] =
{
@@ -443,19 +429,19 @@ nvc0_validate_sample_mask(struct nvc0_context *nvc0)
nvc0->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_RING(chan, RING_3D(SAMPLE_SHADING), 1);
- OUT_RING (chan, 0x01);
+ BEGIN_NVC0(push, NVC0_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]);
+ BEGIN_NVC0(push, NVC0_3D(SAMPLE_SHADING), 1);
+ PUSH_DATA (push, 0x01);
}
static void
nvc0_validate_derived_1(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
boolean early_z;
boolean rasterizer_discard;
@@ -463,7 +449,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0)
if (early_z != nvc0->state.early_z) {
nvc0->state.early_z = early_z;
- IMMED_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), early_z);
+ IMMED_NVC0(push, NVC0_3D(EARLY_FRAGMENT_TESTS), early_z);
}
rasterizer_discard = (!nvc0->fragprog || !nvc0->fragprog->hdr[18]) &&
@@ -473,7 +459,7 @@ nvc0_validate_derived_1(struct nvc0_context *nvc0)
if (rasterizer_discard != nvc0->state.rasterizer_discard) {
nvc0->state.rasterizer_discard = rasterizer_discard;
- IMMED_RING(chan, RING_3D(RASTERIZE_ENABLE), !rasterizer_discard);
+ IMMED_NVC0(push, NVC0_3D(RASTERIZE_ENABLE), !rasterizer_discard);
}
}
@@ -534,6 +520,7 @@ static struct state_validate {
{ nvc0_validate_textures, NVC0_NEW_TEXTURES },
{ nvc0_validate_samplers, NVC0_NEW_SAMPLERS },
{ nvc0_vertex_arrays_validate, NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS },
+ { nvc0_idxbuf_validate, NVC0_NEW_IDXBUF },
{ nvc0_tfb_validate, NVC0_NEW_TFB_TARGETS | NVC0_NEW_GMTYPROG }
};
#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
@@ -542,6 +529,7 @@ boolean
nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
{
uint32_t state_mask;
+ int ret;
unsigned i;
if (nvc0->screen->cur_ctx != nvc0)
@@ -557,11 +545,17 @@ nvc0_state_validate(struct nvc0_context *nvc0, uint32_t mask, unsigned words)
validate->func(nvc0);
}
nvc0->dirty &= ~state_mask;
+
+ nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, FALSE);
}
- MARK_RING(nvc0->screen->base.channel, words, 0);
+ nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx_3d);
+ ret = nouveau_pushbuf_validate(nvc0->base.pushbuf);
+ if (unlikely(ret))
+ return FALSE;
- nvc0_bufctx_emit_relocs(nvc0);
+ if (unlikely(nvc0->state.flushed))
+ nvc0_bufctx_fence(nvc0, nvc0->bufctx_3d, TRUE);
return TRUE;
}
diff --git a/src/gallium/drivers/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nvc0/nvc0_stateobj.h
index dc5771a03aa..bd543029705 100644
--- a/src/gallium/drivers/nvc0/nvc0_stateobj.h
+++ b/src/gallium/drivers/nvc0/nvc0_stateobj.h
@@ -5,12 +5,10 @@
#include "pipe/p_state.h"
#define SB_BEGIN_3D(so, m, s) \
- (so)->state[(so)->size++] = \
- (0x2 << 28) | ((s) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2)
+ (so)->state[(so)->size++] = NVC0_FIFO_PKHDR_SQ(NVC0_3D(m), s)
#define SB_IMMED_3D(so, m, d) \
- (so)->state[(so)->size++] = \
- (0x8 << 28) | ((d) << 16) | (NVC0_SUBCH_3D << 13) | ((NVC0_3D_##m) >> 2)
+ (so)->state[(so)->size++] = NVC0_FIFO_PKHDR_IL(NVC0_3D(m), d)
#define SB_DATA(so, u) (so)->state[(so)->size++] = (u)
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
index 46b5da551db..cb5091ae376 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -73,14 +73,13 @@ nvc0_2d_format(enum pipe_format format)
}
static int
-nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
+nvc0_2d_texture_set(struct nouveau_pushbuf *push, boolean 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 ? NVC0_2D_DST_FORMAT : NVC0_2D_SRC_FORMAT;
- uint32_t flags = mt->base.domain | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
uint32_t offset = mt->level[level].offset;
format = nvc0_2d_format(mt->base.base.format);
@@ -106,44 +105,44 @@ nvc0_2d_texture_set(struct nouveau_channel *chan, int dst,
layer = 0;
}
- 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_NVC0(push, SUBC_2D(mthd), 2);
+ PUSH_DATA (push, format);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(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);
- 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_NVC0(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_NVC0(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_(NVC0_2D_CLIP_X), 4);
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
- OUT_RING (chan, width);
- OUT_RING (chan, height);
+ BEGIN_NVC0(push, SUBC_2D(NVC0_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
-nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
+nvc0_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,
@@ -158,15 +157,15 @@ nvc0_2d_texture_do_copy(struct nouveau_channel *chan,
int ret;
uint32_t ctrl = 0x00;
- ret = MARK_RING(chan, 2 * 16 + 32, 4);
+ ret = PUSH_SPACE(push, 2 * 16 + 32);
if (ret)
return ret;
- ret = nvc0_2d_texture_set(chan, 1, dst, dst_level, dz);
+ ret = nvc0_2d_texture_set(push, TRUE, dst, dst_level, dz);
if (ret)
return ret;
- ret = nvc0_2d_texture_set(chan, 0, src, src_level, sz);
+ ret = nvc0_2d_texture_set(push, FALSE, src, src_level, sz);
if (ret)
return ret;
@@ -175,23 +174,23 @@ nvc0_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_x);
+ BEGIN_NVC0(push, NVC0_2D(BLIT_CONTROL), 1);
+ PUSH_DATA (push, ctrl);
+ BEGIN_NVC0(push, NVC0_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_NVC0(push, NVC0_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_NVC0(push, NVC0_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_x);
return 0;
}
@@ -203,7 +202,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
struct pipe_resource *src, unsigned src_level,
const struct pipe_box *src_box)
{
- struct nvc0_screen *screen = nvc0_context(pipe)->screen;
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
int ret;
boolean m2mf;
unsigned dst_layer = dstz, src_layer = src_box->z;
@@ -234,7 +233,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
src_box->x, src_box->y, src_box->z);
for (i = 0; i < src_box->depth; ++i) {
- nvc0_m2mf_transfer_rect(&screen->base.base, &drect, &srect, nx, ny);
+ nvc0_m2mf_transfer_rect(nvc0, &drect, &srect, nx, ny);
if (nv50_miptree(dst)->layout_3d)
drect.z++;
@@ -252,16 +251,22 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
assert(nvc0_2d_format_faithful(src->format));
assert(nvc0_2d_format_faithful(dst->format));
+ BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(src), RD);
+ BCTX_REFN(nvc0->bufctx, 2D, nv04_resource(dst), WR);
+ nouveau_pushbuf_bufctx(nvc0->base.pushbuf, nvc0->bufctx);
+ nouveau_pushbuf_validate(nvc0->base.pushbuf);
+
for (; dst_layer < dstz + src_box->depth; ++dst_layer, ++src_layer) {
- ret = nvc0_2d_texture_do_copy(screen->base.channel,
+ ret = nvc0_2d_texture_do_copy(nvc0->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(nvc0->bufctx, 0);
}
static void
@@ -271,69 +276,65 @@ nvc0_clear_render_target(struct pipe_context *pipe,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
- struct nvc0_context *nv50 = nvc0_context(pipe);
- struct nvc0_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nv50_surface *sf = nv50_surface(dst);
struct nv04_resource *res = nv04_resource(sf->base.texture);
unsigned z;
- 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]);
-
- if (MARK_RING(chan, 18, 2))
- return;
-
- BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
- OUT_RING (chan, ( width << 16) | dstx);
- OUT_RING (chan, (height << 16) | dsty);
-
- BEGIN_RING(chan, RING_3D(RT_CONTROL), 1);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_3D(RT_ADDRESS_HIGH(0)), 9);
- OUT_RESRCh(chan, res, sf->offset, NOUVEAU_BO_WR);
- OUT_RESRCl(chan, res, sf->offset, NOUVEAU_BO_WR);
- if (likely(nouveau_bo_tile_layout(res->bo))) {
+ BEGIN_NVC0(push, NVC0_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]);
+
+ BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
+ PUSH_DATA (push, ( width << 16) | dstx);
+ PUSH_DATA (push, (height << 16) | dsty);
+
+ BEGIN_NVC0(push, NVC0_3D(RT_CONTROL), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(RT_ADDRESS_HIGH(0)), 9);
+ PUSH_DATAh(push, res->address + sf->offset);
+ PUSH_DATA (push, res->address + sf->offset);
+ if (likely(nouveau_bo_memtype(res->bo))) {
struct nv50_miptree *mt = nv50_miptree(dst->texture);
- OUT_RING(chan, sf->width);
- OUT_RING(chan, sf->height);
- OUT_RING(chan, nvc0_format_table[dst->format].rt);
- OUT_RING(chan, (mt->layout_3d << 16) |
+ PUSH_DATA(push, sf->width);
+ PUSH_DATA(push, sf->height);
+ PUSH_DATA(push, nvc0_format_table[dst->format].rt);
+ PUSH_DATA(push, (mt->layout_3d << 16) |
mt->level[sf->base.u.tex.level].tile_mode);
- OUT_RING(chan, dst->u.tex.first_layer + sf->depth);
- OUT_RING(chan, mt->layer_stride >> 2);
- OUT_RING(chan, dst->u.tex.first_layer);
+ PUSH_DATA(push, dst->u.tex.first_layer + sf->depth);
+ PUSH_DATA(push, mt->layer_stride >> 2);
+ PUSH_DATA(push, dst->u.tex.first_layer);
} else {
if (res->base.target == PIPE_BUFFER) {
- OUT_RING(chan, 262144);
- OUT_RING(chan, 1);
+ PUSH_DATA(push, 262144);
+ PUSH_DATA(push, 1);
} else {
- OUT_RING(chan, nv50_miptree(&res->base)->level[0].pitch);
- OUT_RING(chan, sf->height);
+ PUSH_DATA(push, nv50_miptree(&res->base)->level[0].pitch);
+ PUSH_DATA(push, sf->height);
}
- OUT_RING(chan, nvc0_format_table[sf->base.format].rt);
- OUT_RING(chan, 1 << 12);
- OUT_RING(chan, 1);
- OUT_RING(chan, 0);
- OUT_RING(chan, 0);
+ PUSH_DATA(push, nvc0_format_table[sf->base.format].rt);
+ PUSH_DATA(push, 1 << 12);
+ PUSH_DATA(push, 1);
+ PUSH_DATA(push, 0);
+ PUSH_DATA(push, 0);
- IMMED_RING(chan, RING_3D(ZETA_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(ZETA_ENABLE), 0);
/* tiled textures don't have to be fenced, they're not mapped directly */
nvc0_resource_fence(res, NOUVEAU_BO_WR);
}
for (z = 0; z < sf->depth; ++z) {
- BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
- OUT_RING (chan, 0x3c |
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
+ PUSH_DATA (push, 0x3c |
(z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
}
- nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
+ nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
}
static void
@@ -345,57 +346,52 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height)
{
- struct nvc0_context *nv50 = nvc0_context(pipe);
- struct nvc0_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nvc0_context *nvc0 = nvc0_context(pipe);
+ struct nouveau_pushbuf *push = nvc0->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;
int unk = mt->base.base.target == PIPE_TEXTURE_2D;
unsigned z;
if (clear_flags & PIPE_CLEAR_DEPTH) {
- BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
- OUT_RINGf (chan, depth);
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
+ PUSH_DATAf(push, depth);
mode |= NVC0_3D_CLEAR_BUFFERS_Z;
}
if (clear_flags & PIPE_CLEAR_STENCIL) {
- BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
- OUT_RING (chan, stencil & 0xff);
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
+ PUSH_DATA (push, stencil & 0xff);
mode |= NVC0_3D_CLEAR_BUFFERS_S;
}
- if (MARK_RING(chan, 20, 2))
- return;
-
- BEGIN_RING(chan, RING_3D(SCREEN_SCISSOR_HORIZ), 2);
- OUT_RING (chan, ( width << 16) | dstx);
- OUT_RING (chan, (height << 16) | dsty);
-
- 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, nvc0_format_table[dst->format].rt);
- OUT_RING (chan, mt->level[sf->base.u.tex.level].tile_mode);
- 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) | (dst->u.tex.first_layer + sf->depth));
- BEGIN_RING(chan, RING_3D(ZETA_BASE_LAYER), 1);
- OUT_RING (chan, dst->u.tex.first_layer);
+ BEGIN_NVC0(push, NVC0_3D(SCREEN_SCISSOR_HORIZ), 2);
+ PUSH_DATA (push, ( width << 16) | dstx);
+ PUSH_DATA (push, (height << 16) | dsty);
+
+ BEGIN_NVC0(push, NVC0_3D(ZETA_ADDRESS_HIGH), 5);
+ PUSH_DATAh(push, mt->base.address + sf->offset);
+ PUSH_DATA (push, mt->base.address + sf->offset);
+ PUSH_DATA (push, nvc0_format_table[dst->format].rt);
+ PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
+ PUSH_DATA (push, mt->layer_stride >> 2);
+ BEGIN_NVC0(push, NVC0_3D(ZETA_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_3D(ZETA_HORIZ), 3);
+ PUSH_DATA (push, sf->width);
+ PUSH_DATA (push, sf->height);
+ PUSH_DATA (push, (unk << 16) | (dst->u.tex.first_layer + sf->depth));
+ BEGIN_NVC0(push, NVC0_3D(ZETA_BASE_LAYER), 1);
+ PUSH_DATA (push, dst->u.tex.first_layer);
for (z = 0; z < sf->depth; ++z) {
- BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
- OUT_RING (chan, mode |
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
+ PUSH_DATA (push, mode |
(z << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
}
- nv50->dirty |= NVC0_NEW_FRAMEBUFFER;
+ nvc0->dirty |= NVC0_NEW_FRAMEBUFFER;
}
void
@@ -404,7 +400,7 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
double depth, unsigned stencil)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct pipe_framebuffer_state *fb = &nvc0->framebuffer;
unsigned i;
uint32_t mode = 0;
@@ -414,34 +410,34 @@ nvc0_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_NVC0(push, NVC0_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 =
NVC0_3D_CLEAR_BUFFERS_R | NVC0_3D_CLEAR_BUFFERS_G |
NVC0_3D_CLEAR_BUFFERS_B | NVC0_3D_CLEAR_BUFFERS_A;
}
if (buffers & PIPE_CLEAR_DEPTH) {
- BEGIN_RING(chan, RING_3D(CLEAR_DEPTH), 1);
- OUT_RING (chan, fui(depth));
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_DEPTH), 1);
+ PUSH_DATA (push, fui(depth));
mode |= NVC0_3D_CLEAR_BUFFERS_Z;
}
if (buffers & PIPE_CLEAR_STENCIL) {
- BEGIN_RING(chan, RING_3D(CLEAR_STENCIL), 1);
- OUT_RING (chan, stencil & 0xff);
+ BEGIN_NVC0(push, NVC0_3D(CLEAR_STENCIL), 1);
+ PUSH_DATA (push, stencil & 0xff);
mode |= NVC0_3D_CLEAR_BUFFERS_S;
}
- BEGIN_RING(chan, RING_3D(CLEAR_BUFFERS), 1);
- OUT_RING (chan, mode);
+ BEGIN_NVC0(push, NVC0_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_NVC0(push, NVC0_3D(CLEAR_BUFFERS), 1);
+ PUSH_DATA (push, (i << 6) | 0x3c);
}
}
@@ -709,42 +705,42 @@ nvc0_blit_set_src(struct nvc0_context *nvc0,
static void
nvc0_blitctx_prepare_state(struct nvc0_blitctx *blit)
{
- struct nouveau_channel *chan = blit->screen->base.channel;
+ struct nouveau_pushbuf *push = blit->screen->base.pushbuf;
/* TODO: maybe make this a MACRO (if we need more logic) ? */
/* 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);
- IMMED_RING(chan, RING_3D(LOGIC_OP_ENABLE), 0);
+ BEGIN_NVC0(push, NVC0_3D(COLOR_MASK(0)), 1);
+ PUSH_DATA (push, blit->color_mask);
+ BEGIN_NVC0(push, NVC0_3D(BLEND_ENABLE(0)), 1);
+ PUSH_DATA (push, 0);
+ IMMED_NVC0(push, NVC0_3D(LOGIC_OP_ENABLE), 0);
/* rasterizer state */
- BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1);
- OUT_RING (chan, 0);
- IMMED_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 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), 1);
- OUT_RING (chan, NVC0_3D_POLYGON_MODE_FRONT_FILL);
- BEGIN_RING(chan, RING_3D(POLYGON_MODE_BACK), 1);
- OUT_RING (chan, NVC0_3D_POLYGON_MODE_BACK_FILL);
- IMMED_RING(chan, RING_3D(POLYGON_SMOOTH_ENABLE), 0);
- IMMED_RING(chan, RING_3D(POLYGON_OFFSET_FILL_ENABLE), 0);
- IMMED_RING(chan, RING_3D(POLYGON_STIPPLE_ENABLE), 0);
- IMMED_RING(chan, RING_3D(CULL_FACE_ENABLE), 0);
+ BEGIN_NVC0(push, NVC0_3D(FRAG_COLOR_CLAMP_EN), 1);
+ PUSH_DATA (push, 0);
+ IMMED_NVC0(push, NVC0_3D(MULTISAMPLE_ENABLE), 0);
+ BEGIN_NVC0(push, NVC0_3D(MSAA_MASK(0)), 4);
+ PUSH_DATA (push, 0xffff);
+ PUSH_DATA (push, 0xffff);
+ PUSH_DATA (push, 0xffff);
+ PUSH_DATA (push, 0xffff);
+ BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_FRONT), 1);
+ PUSH_DATA (push, NVC0_3D_POLYGON_MODE_FRONT_FILL);
+ BEGIN_NVC0(push, NVC0_3D(POLYGON_MODE_BACK), 1);
+ PUSH_DATA (push, NVC0_3D_POLYGON_MODE_BACK_FILL);
+ IMMED_NVC0(push, NVC0_3D(POLYGON_SMOOTH_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(POLYGON_OFFSET_FILL_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(POLYGON_STIPPLE_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(CULL_FACE_ENABLE), 0);
/* zsa state */
- IMMED_RING(chan, RING_3D(DEPTH_TEST_ENABLE), 0);
- IMMED_RING(chan, RING_3D(STENCIL_ENABLE), 0);
- IMMED_RING(chan, RING_3D(ALPHA_TEST_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(DEPTH_TEST_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(STENCIL_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(ALPHA_TEST_ENABLE), 0);
/* disable transform feedback */
- IMMED_RING(chan, RING_3D(TFB_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(TFB_ENABLE), 0);
}
static void
@@ -835,7 +831,7 @@ nvc0_resource_resolve(struct pipe_context *pipe,
struct nvc0_context *nvc0 = nvc0_context(pipe);
struct nvc0_screen *screen = nvc0->screen;
struct nvc0_blitctx *blit = screen->blitctx;
- struct nouveau_channel *chan = screen->base.channel;
+ struct nouveau_pushbuf *push = screen->base.pushbuf;
struct pipe_resource *src = info->src.res;
struct pipe_resource *dst = info->dst.res;
float x0, x1, y0, y1;
@@ -878,11 +874,11 @@ nvc0_resource_resolve(struct pipe_context *pipe,
y0 *= (float)(1 << nv50_miptree(src)->ms_y);
y1 *= (float)(1 << nv50_miptree(src)->ms_y);
- BEGIN_RING(chan, RING_3D(SP_START_ID(5)), 1);
- OUT_RING (chan,
+ BEGIN_NVC0(push, NVC0_3D(SP_START_ID(5)), 1);
+ PUSH_DATA (push,
blit->fp.code_base + blit->fp_offset);
- IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 0);
+ IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 0);
/* Draw a large triangle in screen coordinates covering the whole
* render target, with scissors defining the destination region.
@@ -890,43 +886,43 @@ nvc0_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_NVC0(push, NVC0_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);
- IMMED_RING(chan, RING_3D(VERTEX_BEGIN_GL),
+ IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL),
NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_TRIANGLES);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
- OUT_RING (chan, 0x74201);
- OUT_RINGf (chan, x0);
- OUT_RINGf (chan, y0);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
- OUT_RING (chan, 0x74200);
- OUT_RINGf (chan, 0.0f);
- OUT_RINGf (chan, 0.0f);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
- OUT_RING (chan, 0x74201);
- OUT_RINGf (chan, x1);
- OUT_RINGf (chan, y0);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
- OUT_RING (chan, 0x74200);
- OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_x);
- OUT_RINGf (chan, 0.0f);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
- OUT_RING (chan, 0x74201);
- OUT_RINGf (chan, x0);
- OUT_RINGf (chan, y1);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), 3);
- OUT_RING (chan, 0x74200);
- OUT_RINGf (chan, 0.0f);
- OUT_RINGf (chan, 16384 << nv50_miptree(dst)->ms_y);
-
- IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+ BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+ PUSH_DATA (push, 0x74201);
+ PUSH_DATAf(push, x0);
+ PUSH_DATAf(push, y0);
+ BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+ PUSH_DATA (push, 0x74200);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 0.0f);
+ BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+ PUSH_DATA (push, 0x74201);
+ PUSH_DATAf(push, x1);
+ PUSH_DATAf(push, y0);
+ BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+ PUSH_DATA (push, 0x74200);
+ PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_x);
+ PUSH_DATAf(push, 0.0f);
+ BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+ PUSH_DATA (push, 0x74201);
+ PUSH_DATAf(push, x0);
+ PUSH_DATAf(push, y1);
+ BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), 3);
+ PUSH_DATA (push, 0x74200);
+ PUSH_DATAf(push, 0.0f);
+ PUSH_DATAf(push, 16384 << nv50_miptree(dst)->ms_y);
+
+ IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
/* re-enable normally constant state */
- IMMED_RING(chan, RING_3D(VIEWPORT_TRANSFORM_EN), 1);
+ IMMED_NVC0(push, NVC0_3D(VIEWPORT_TRANSFORM_EN), 1);
nvc0_blitctx_post_blit(nvc0, blit);
}
diff --git a/src/gallium/drivers/nvc0/nvc0_tex.c b/src/gallium/drivers/nvc0/nvc0_tex.c
index 0a1bc379868..fd58f80ab97 100644
--- a/src/gallium/drivers/nvc0/nvc0_tex.c
+++ b/src/gallium/drivers/nvc0/nvc0_tex.c
@@ -56,6 +56,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
const struct pipe_sampler_view *templ)
{
const struct util_format_description *desc;
+ uint64_t address;
uint32_t *tic;
uint32_t swz[4];
uint32_t depth;
@@ -66,6 +67,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
view = MALLOC_STRUCT(nv50_tic_entry);
if (!view)
return NULL;
+ mt = nv50_miptree(texture);
view->pipe = *templ;
view->pipe.reference.count = 1;
@@ -80,8 +82,6 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
desc = util_format_description(view->pipe.format);
- /* TIC[0] */
-
tic[0] = nvc0_format_table[view->pipe.format].tic;
tex_int = util_format_is_pure_integer(view->pipe.format);
@@ -96,26 +96,24 @@ nvc0_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;
+ address = mt->base.address;
- tic[2] |= 0x10001000 | NV50_TIC_2_NO_BORDER;
+ tic[2] = 0x10001000 | NV50_TIC_2_NO_BORDER;
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
tic[2] |= NV50_TIC_2_COLORSPACE_SRGB;
/* check for linear storage type */
- if (unlikely(!nouveau_bo_tile_layout(nv04_resource(texture)->bo))) {
+ if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
if (texture->target == PIPE_BUFFER) {
- tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
- tic[1] = /* address offset */
+ address +=
view->pipe.u.buf.first_element * desc->block.bits / 8;
+ tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_BUFFER;
tic[3] = 0;
tic[4] = /* width */
view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
- tic[5] = 0;
+ tic[5] = 0;
} else {
- mt = nv50_miptree(texture);
/* must be 2D texture without mip maps */
tic[2] |= NV50_TIC_2_LINEAR | NV50_TIC_2_TARGET_RECT;
if (texture->target != PIPE_TEXTURE_RECT)
@@ -126,24 +124,27 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
}
tic[6] =
tic[7] = 0;
+ tic[1] = address;
+ tic[2] |= address >> 32;
return &view->pipe;
}
- mt = nv50_miptree(texture);
if (mt->base.base.target != PIPE_TEXTURE_RECT)
tic[2] |= NV50_TIC_2_NORMALIZED_COORDS;
tic[2] |=
- ((mt->base.bo->tile_mode & 0x0f0) << (22 - 4)) |
- ((mt->base.bo->tile_mode & 0xf00) << (25 - 8));
+ ((mt->level[0].tile_mode & 0x0f0) << (22 - 4)) |
+ ((mt->level[0].tile_mode & 0xf00) << (25 - 8));
depth = MAX2(mt->base.base.array_size, mt->base.base.depth0);
if (mt->base.base.array_size > 1) {
/* there doesn't seem to be a base layer field in TIC */
- tic[1] = view->pipe.u.tex.first_layer * mt->layer_stride;
+ address += view->pipe.u.tex.first_layer * mt->layer_stride;
depth = view->pipe.u.tex.last_layer - view->pipe.u.tex.first_layer + 1;
}
+ tic[1] = address;
+ tic[2] |= address >> 32;
switch (mt->base.base.target) {
case PIPE_TEXTURE_1D:
@@ -205,7 +206,7 @@ nvc0_create_sampler_view(struct pipe_context *pipe,
static boolean
nvc0_validate_tic(struct nvc0_context *nvc0, int s)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nouveau_bo *txc = nvc0->screen->txc;
unsigned i;
boolean need_flush = FALSE;
@@ -215,53 +216,46 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
struct nv04_resource *res;
if (!tic) {
- BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
- OUT_RING (chan, (i << 1) | 0);
+ BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
+ PUSH_DATA (push, (i << 1) | 0);
continue;
}
res = nv04_resource(tic->pipe.texture);
if (tic->id < 0) {
- uint32_t offset = res->offset + tic->tic[1];
-
tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
- MARK_RING (chan, 9 + 8, 4);
- BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
- OUT_RELOCh(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, txc, tic->id * 32, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
- OUT_RING (chan, 32);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_MF(EXEC), 1);
- OUT_RING (chan, 0x100111);
- BEGIN_RING_NI(chan, RING_MF(DATA), 8);
- OUT_RING (chan, tic->tic[0]);
- OUT_RELOCl(chan, res->bo, offset, res->domain | NOUVEAU_BO_RD);
- OUT_RELOC (chan, res->bo, offset, res->domain | NOUVEAU_BO_RD |
- NOUVEAU_BO_HIGH | NOUVEAU_BO_OR, tic->tic[2], tic->tic[2]);
- OUT_RINGp (chan, &tic->tic[3], 5);
+ PUSH_SPACE(push, 17);
+ BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+ PUSH_DATAh(push, txc->offset + (tic->id * 32));
+ PUSH_DATA (push, txc->offset + (tic->id * 32));
+ BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+ PUSH_DATA (push, 32);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+ PUSH_DATA (push, 0x100111);
+ BEGIN_NIC0(push, NVC0_M2MF(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, (tic->id << 4) | 1);
+ BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
+ PUSH_DATA (push, (tic->id << 4) | 1);
}
nvc0->screen->tic.lock[tic->id / 32] |= 1 << (tic->id % 32);
res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
res->status |= NOUVEAU_BUFFER_STATUS_GPU_READING;
- nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_TEXTURES, res,
- res->domain | NOUVEAU_BO_RD);
+ BCTX_REFN(nvc0->bufctx_3d, TEX, res, RD);
- BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
- OUT_RING (chan, (tic->id << 9) | (i << 1) | 1);
+ BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
+ PUSH_DATA (push, (tic->id << 9) | (i << 1) | 1);
}
for (; i < nvc0->state.num_textures[s]; ++i) {
- BEGIN_RING(chan, RING_3D(BIND_TIC(s)), 1);
- OUT_RING (chan, (i << 1) | 0);
+ BEGIN_NVC0(push, NVC0_3D(BIND_TIC(s)), 1);
+ PUSH_DATA (push, (i << 1) | 0);
}
nvc0->state.num_textures[s] = nvc0->num_textures[s];
@@ -277,15 +271,15 @@ void nvc0_validate_textures(struct nvc0_context *nvc0)
need_flush |= nvc0_validate_tic(nvc0, 4);
if (need_flush) {
- BEGIN_RING(nvc0->screen->base.channel, RING_3D(TIC_FLUSH), 1);
- OUT_RING (nvc0->screen->base.channel, 0);
+ BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TIC_FLUSH), 1);
+ PUSH_DATA (nvc0->base.pushbuf, 0);
}
}
static boolean
nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
unsigned i;
boolean need_flush = FALSE;
@@ -293,8 +287,8 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
struct nv50_tsc_entry *tsc = nv50_tsc_entry(nvc0->samplers[s][i]);
if (!tsc) {
- BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
- OUT_RING (chan, (i << 4) | 0);
+ BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
+ PUSH_DATA (push, (i << 4) | 0);
continue;
}
if (tsc->id < 0) {
@@ -307,12 +301,12 @@ nvc0_validate_tsc(struct nvc0_context *nvc0, int s)
}
nvc0->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_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
+ PUSH_DATA (push, (tsc->id << 12) | (i << 4) | 1);
}
for (; i < nvc0->state.num_samplers[s]; ++i) {
- BEGIN_RING(chan, RING_3D(BIND_TSC(s)), 1);
- OUT_RING (chan, (i << 4) | 0);
+ BEGIN_NVC0(push, NVC0_3D(BIND_TSC(s)), 1);
+ PUSH_DATA (push, (i << 4) | 0);
}
nvc0->state.num_samplers[s] = nvc0->num_samplers[s];
@@ -328,7 +322,7 @@ void nvc0_validate_samplers(struct nvc0_context *nvc0)
need_flush |= nvc0_validate_tsc(nvc0, 4);
if (need_flush) {
- BEGIN_RING(nvc0->screen->base.channel, RING_3D(TSC_FLUSH), 1);
- OUT_RING (nvc0->screen->base.channel, 0);
+ BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(TSC_FLUSH), 1);
+ PUSH_DATA (nvc0->base.pushbuf, 0);
}
}
diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c
index f16863733b7..774793d8d02 100644
--- a/src/gallium/drivers/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nvc0/nvc0_transfer.c
@@ -14,12 +14,13 @@ struct nvc0_transfer {
};
void
-nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
+nvc0_m2mf_transfer_rect(struct nvc0_context *nvc0,
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 = nvc0->base.pushbuf;
+ struct nouveau_bufctx *bctx = nvc0->bufctx;
const int cpp = dst->cpp;
uint32_t src_ofst = src->base;
uint32_t dst_ofst = dst->base;
@@ -30,34 +31,39 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
assert(dst->cpp == src->cpp);
- if (nouveau_bo_tile_layout(src->bo)) {
- BEGIN_RING(chan, RING_MF(TILING_MODE_IN), 5);
- OUT_RING (chan, src->tile_mode);
- 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_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5);
+ 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(PITCH_IN), 1);
- OUT_RING (chan, src->width * cpp);
+ BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1);
+ PUSH_DATA (push, src->width * cpp);
exec |= NVC0_M2MF_EXEC_LINEAR_IN;
}
- if (nouveau_bo_tile_layout(dst->bo)) {
- BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5);
- OUT_RING (chan, dst->tile_mode);
- 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_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5);
+ 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(PITCH_OUT), 1);
- OUT_RING (chan, dst->width * cpp);
+ BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1);
+ PUSH_DATA (push, dst->width * cpp);
exec |= NVC0_M2MF_EXEC_LINEAR_OUT;
}
@@ -65,41 +71,41 @@ nvc0_m2mf_transfer_rect(struct pipe_screen *pscreen,
while (height) {
int line_count = height > 2047 ? 2047 : height;
- MARK_RING (chan, 17, 4);
+ BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
+ PUSH_DATAh(push, src->bo->offset + src_ofst);
+ PUSH_DATA (push, src->bo->offset + src_ofst);
- BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
- OUT_RELOCh(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, src->bo, src_ofst, src->domain | NOUVEAU_BO_RD);
-
- BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
- OUT_RELOCh(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, dst->bo, dst_ofst, dst->domain | NOUVEAU_BO_WR);
+ BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+ PUSH_DATAh(push, dst->bo->offset + dst_ofst);
+ PUSH_DATA (push, dst->bo->offset + dst_ofst);
if (!(exec & NVC0_M2MF_EXEC_LINEAR_IN)) {
- BEGIN_RING(chan, RING_MF(TILING_POSITION_IN_X), 2);
- OUT_RING (chan, src->x * cpp);
- OUT_RING (chan, sy);
+ BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2);
+ PUSH_DATA (push, src->x * cpp);
+ PUSH_DATA (push, sy);
} else {
src_ofst += line_count * src->pitch;
}
if (!(exec & NVC0_M2MF_EXEC_LINEAR_OUT)) {
- BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2);
- OUT_RING (chan, dst->x * cpp);
- OUT_RING (chan, dy);
+ BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2);
+ PUSH_DATA (push, dst->x * cpp);
+ PUSH_DATA (push, dy);
} else {
dst_ofst += line_count * dst->pitch;
}
- BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
- OUT_RING (chan, nblocksx * cpp);
- OUT_RING (chan, line_count);
- BEGIN_RING(chan, RING_MF(EXEC), 1);
- OUT_RING (chan, exec);
+ BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+ PUSH_DATA (push, nblocksx * cpp);
+ PUSH_DATA (push, line_count);
+ BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+ PUSH_DATA (push, exec);
height -= line_count;
sy += line_count;
dy += line_count;
}
+
+ nouveau_bufctx_reset(bctx, 0);
}
void
@@ -107,36 +113,44 @@ nvc0_m2mf_push_linear(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 nvc0_context *nvc0 = nvc0_context(&nv->pipe);
+ struct nouveau_pushbuf *push = nv->pushbuf;
uint32_t *src = (uint32_t *)data;
unsigned count = (size + 3) / 4;
+ nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
+ nouveau_pushbuf_bufctx(push, nvc0->bufctx);
+ nouveau_pushbuf_validate(push);
+
while (count) {
unsigned nr;
- MARK_RING (chan, 16, 2);
-
- nr = AVAIL_RING(chan) - 9;
- nr = MIN2(count, nr);
+ if (!PUSH_SPACE(push, 16))
+ break;
+ nr = PUSH_AVAIL(push);
+ assert(nr >= 16);
+ nr = MIN2(count, nr - 9);
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
- BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
- OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR);
- BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
- OUT_RING (chan, nr * 4);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_MF(EXEC), 1);
- OUT_RING (chan, 0x100111);
+ BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+ PUSH_DATAh(push, dst->offset + offset);
+ PUSH_DATA (push, dst->offset + offset);
+ BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+ PUSH_DATA (push, nr * 4);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+ PUSH_DATA (push, 0x100111);
/* must not be interrupted (trap on QUERY fence, 0x50 works however) */
- BEGIN_RING_NI(chan, RING_MF(DATA), nr);
- OUT_RINGp (chan, src, nr);
+ BEGIN_NIC0(push, NVC0_M2MF(DATA), nr);
+ PUSH_DATAp(push, src, nr);
count -= nr;
src += nr;
offset += nr * 4;
}
+
+ nouveau_bufctx_reset(nvc0->bufctx, 0);
}
void
@@ -145,88 +159,37 @@ nvc0_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 = nvc0_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);
while (size) {
unsigned bytes = MIN2(size, 1 << 17);
- MARK_RING (chan, 11, 4);
-
- BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
- OUT_RELOCh(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, dst, dstoff, dstdom | NOUVEAU_BO_WR);
- BEGIN_RING(chan, RING_MF(OFFSET_IN_HIGH), 2);
- OUT_RELOCh(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, src, srcoff, srcdom | NOUVEAU_BO_RD);
- BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
- OUT_RING (chan, bytes);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, RING_MF(EXEC), 1);
- OUT_RING (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
+ BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
+ PUSH_DATAh(push, dst->offset + dstoff);
+ PUSH_DATA (push, dst->offset + dstoff);
+ BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
+ PUSH_DATAh(push, src->offset + srcoff);
+ PUSH_DATA (push, src->offset + srcoff);
+ BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
+ PUSH_DATA (push, bytes);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
+ PUSH_DATA (push, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
NVC0_M2MF_EXEC_LINEAR_IN | NVC0_M2MF_EXEC_LINEAR_OUT);
srcoff += bytes;
dstoff += bytes;
size -= bytes;
}
-}
-
-#if 0
-static void
-nvc0_m2mf_push_rect(struct pipe_screen *pscreen,
- const struct nv50_m2mf_rect *dst,
- const void *data,
- unsigned nblocksx, unsigned nblocksy)
-{
- struct nouveau_channel *chan;
- const uint8_t *src = (const uint8_t *)data;
- const int cpp = dst->cpp;
- const int line_len = nblocksx * cpp;
- int dy = dst->y;
-
- assert(nouveau_bo_tile_layout(dst->bo));
-
- BEGIN_RING(chan, RING_MF(TILING_MODE_OUT), 5);
- OUT_RING (chan, dst->tile_mode);
- OUT_RING (chan, dst->width * cpp);
- OUT_RING (chan, dst->height);
- OUT_RING (chan, dst->depth);
- OUT_RING (chan, dst->z);
-
- while (nblocksy) {
- int line_count, words;
- int size = MIN2(AVAIL_RING(chan), NV04_PFIFO_MAX_PACKET_LEN);
- if (size < (12 + words)) {
- FIRE_RING(chan);
- continue;
- }
- line_count = (size * 4) / line_len;
- words = (line_count * line_len + 3) / 4;
-
- BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2);
- OUT_RELOCh(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, dst->bo, dst->base, dst->domain | NOUVEAU_BO_WR);
-
- BEGIN_RING(chan, RING_MF(TILING_POSITION_OUT_X), 2);
- OUT_RING (chan, dst->x * cpp);
- OUT_RING (chan, dy);
- BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2);
- OUT_RING (chan, line_len);
- OUT_RING (chan, line_count);
- BEGIN_RING(chan, RING_MF(EXEC), 1);
- OUT_RING (chan, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
- NVC0_M2MF_EXEC_PUSH | NVC0_M2MF_EXEC_LINEAR_IN);
-
- BEGIN_RING_NI(chan, RING_MF(DATA), words);
- OUT_RINGp (chan, src, words);
-
- dy += line_count;
- src += line_len * line_count;
- nblocksy -= line_count;
- }
+ nouveau_bufctx_reset(bctx, 0);
}
-#endif
struct pipe_transfer *
nvc0_miptree_transfer_new(struct pipe_context *pctx,
@@ -236,7 +199,6 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
const struct pipe_box *box)
{
struct nvc0_context *nvc0 = nvc0_context(pctx);
- struct pipe_screen *pscreen = pctx->screen;
struct nouveau_device *dev = nvc0->screen->base.device;
struct nv50_miptree *mt = nv50_miptree(res);
struct nvc0_transfer *tx;
@@ -273,7 +235,7 @@ nvc0_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->nlayers, &tx->rect[1].bo);
+ size * tx->nlayers, NULL, &tx->rect[1].bo);
if (ret) {
FREE(tx);
return NULL;
@@ -291,7 +253,7 @@ nvc0_miptree_transfer_new(struct pipe_context *pctx,
unsigned z = tx->rect[0].z;
unsigned i;
for (i = 0; i < tx->nlayers; ++i) {
- nvc0_m2mf_transfer_rect(pscreen, &tx->rect[1], &tx->rect[0],
+ nvc0_m2mf_transfer_rect(nvc0, &tx->rect[1], &tx->rect[0],
tx->nblocksx, tx->nblocksy);
if (mt->layout_3d)
tx->rect[0].z++;
@@ -311,14 +273,14 @@ void
nvc0_miptree_transfer_del(struct pipe_context *pctx,
struct pipe_transfer *transfer)
{
- struct pipe_screen *pscreen = pctx->screen;
+ struct nvc0_context *nvc0 = nvc0_context(pctx);
struct nvc0_transfer *tx = (struct nvc0_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->nlayers; ++i) {
- nvc0_m2mf_transfer_rect(pscreen, &tx->rect[0], &tx->rect[1],
+ nvc0_m2mf_transfer_rect(nvc0, &tx->rect[0], &tx->rect[1],
tx->nblocksx, tx->nblocksy);
if (mt->layout_3d)
tx->rect[0].z++;
@@ -338,6 +300,7 @@ void *
nvc0_miptree_transfer_map(struct pipe_context *pctx,
struct pipe_transfer *transfer)
{
+ struct nvc0_context *nvc0 = nvc0_context(pctx);
struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
int ret;
unsigned flags = 0;
@@ -350,7 +313,7 @@ nvc0_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, nvc0->screen->base.client);
if (ret)
return NULL;
return tx->rect[1].bo->map;
@@ -360,9 +323,6 @@ void
nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
struct pipe_transfer *transfer)
{
- struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
-
- nouveau_bo_unmap(tx->rect[1].bo);
}
void
@@ -371,33 +331,34 @@ nvc0_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_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
+ struct nouveau_pushbuf *push = nv->pushbuf;
assert(!(offset & 3));
size = align(size, 0x100);
- MARK_RING (chan, 16, 2);
- BEGIN_RING(chan, RING_3D(CB_SIZE), 3);
- OUT_RING (chan, size);
- OUT_RELOCh(chan, bo, base, domain | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, bo, base, domain | NOUVEAU_BO_WR);
+ nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
+ nouveau_pushbuf_bufctx(push, bctx);
+ nouveau_pushbuf_validate(push);
+
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+ PUSH_DATA (push, size);
+ PUSH_DATAh(push, bo->offset + base);
+ PUSH_DATA (push, bo->offset + base);
while (words) {
- unsigned nr = AVAIL_RING(chan);
+ unsigned nr = PUSH_AVAIL(push);
nr = MIN2(nr, words);
nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
- BEGIN_RING_1I(chan, RING_3D(CB_POS), nr + 1);
- OUT_RING (chan, offset);
- OUT_RINGp (chan, data, nr);
+ BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1);
+ PUSH_DATA (push, offset);
+ PUSH_DATAp(push, data, nr);
words -= nr;
data += nr;
offset += nr * 4;
-
- if (words) {
- MARK_RING(chan, 6, 1);
- nouveau_bo_validate(chan, bo, domain | NOUVEAU_BO_WR);
- }
}
+
+ nouveau_bufctx_reset(bctx, 0);
}
diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c
index de456b91945..fbdc5d25d58 100644
--- a/src/gallium/drivers/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nvc0/nvc0_vbo.c
@@ -20,6 +20,8 @@
* SOFTWARE.
*/
+#define NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "util/u_inlines.h"
@@ -128,7 +130,7 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb,
struct pipe_vertex_element *ve, unsigned attr)
{
const void *data;
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nv04_resource *res = nv04_resource(vb->buffer);
float v[4];
int i;
@@ -139,10 +141,11 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb,
util_format_read_4f(ve->src_format, v, 0, data, 0, 0, 0, 1, 1);
- BEGIN_RING(chan, RING_3D(VTX_ATTR_DEFINE), nc + 1);
- OUT_RING (chan, VTX_ATTR(attr, nc, FLOAT, 32));
+ PUSH_SPACE(push, 6);
+ BEGIN_NVC0(push, NVC0_3D(VTX_ATTR_DEFINE), nc + 1);
+ PUSH_DATA (push, VTX_ATTR(attr, nc, FLOAT, 32));
for (i = 0; i < nc; ++i)
- OUT_RINGf(chan, v[i]);
+ PUSH_DATAf(push, v[i]);
}
static INLINE void
@@ -171,7 +174,7 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0)
nvc0->vbo_fifo = nvc0->vbo_user = 0;
- nvc0_bufctx_reset(nvc0, NVC0_BUFCTX_VERTEX);
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
for (i = 0; i < nvc0->num_vtxbufs; ++i) {
vb = &nvc0->vtxbuf[i];
@@ -189,33 +192,41 @@ nvc0_prevalidate_vbufs(struct nvc0_context *nvc0)
nvc0->vbo_user |= 1 << i;
assert(vb->stride > vb->buffer_offset);
nvc0_vbuf_range(nvc0, i, &base, &size);
- nouveau_user_buffer_upload(buf, base, size);
+ nouveau_user_buffer_upload(&nvc0->base, buf, base, size);
} else {
nouveau_buffer_migrate(&nvc0->base, buf, NOUVEAU_BO_GART);
}
nvc0->base.vbo_dirty = TRUE;
}
}
- nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD);
+ BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
}
}
static void
nvc0_update_user_vbufs(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
uint32_t base, offset, size;
int i;
uint32_t written = 0;
+ /* TODO: use separate bufctx bin for user buffers
+ */
+ nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_VTX);
+
+ PUSH_SPACE(push, nvc0->vertex->num_elements * 8);
+
for (i = 0; i < nvc0->vertex->num_elements; ++i) {
struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe;
const int b = ve->vertex_buffer_index;
struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b];
struct nv04_resource *buf = nv04_resource(vb->buffer);
- if (!(nvc0->vbo_user & (1 << b)))
+ if (!(nvc0->vbo_user & (1 << b))) {
+ BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
continue;
+ }
if (!vb->stride) {
nvc0_emit_vtxattr(nvc0, vb, ve, i);
@@ -225,17 +236,18 @@ nvc0_update_user_vbufs(struct nvc0_context *nvc0)
if (!(written & (1 << b))) {
written |= 1 << b;
- nouveau_user_buffer_upload(buf, base, size);
+ nouveau_user_buffer_upload(&nvc0->base, buf, base, size);
}
offset = vb->buffer_offset + ve->src_offset;
- MARK_RING (chan, 6, 4);
- BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
- OUT_RING (chan, i);
- OUT_RESRCh(chan, buf, base + size - 1, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, buf, base + size - 1, NOUVEAU_BO_RD);
- OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD);
+ BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5);
+ PUSH_DATA (push, i);
+ PUSH_DATAh(push, buf->address + base + size - 1);
+ PUSH_DATA (push, buf->address + base + size - 1);
+ PUSH_DATAh(push, buf->address + offset);
+ PUSH_DATA (push, buf->address + offset);
+
+ BCTX_REFN(nvc0->bufctx_3d, VTX, buf, RD);
}
nvc0->base.vbo_dirty = TRUE;
}
@@ -256,7 +268,7 @@ nvc0_release_user_vbufs(struct nvc0_context *nvc0)
void
nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_vertex_stateobj *vertex = nvc0->vertex;
struct pipe_vertex_buffer *vb;
struct nvc0_vertex_element *ve;
@@ -270,19 +282,21 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
nvc0_prevalidate_vbufs(nvc0);
}
- BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements);
+ PUSH_SPACE(push, vertex->num_elements + 1);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements);
for (i = 0; i < vertex->num_elements; ++i) {
ve = &vertex->element[i];
vb = &nvc0->vtxbuf[ve->pipe.vertex_buffer_index];
if (likely(vb->stride) || nvc0->vbo_fifo) {
- OUT_RING(chan, ve->state);
+ PUSH_DATA(push, ve->state);
} else {
- OUT_RING(chan, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST);
+ PUSH_DATA(push, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST);
nvc0->vbo_fifo &= ~(1 << i);
}
}
+ PUSH_SPACE(push, vertex->num_elements * 16);
for (i = 0; i < vertex->num_elements; ++i) {
struct nv04_resource *res;
unsigned size, offset;
@@ -292,13 +306,13 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
if (unlikely(ve->pipe.instance_divisor)) {
if (!(nvc0->state.instance_elts & (1 << i))) {
- IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 1);
}
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
- OUT_RING (chan, ve->pipe.instance_divisor);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_DIVISOR(i)), 1);
+ PUSH_DATA (push, ve->pipe.instance_divisor);
} else
if (unlikely(nvc0->state.instance_elts & (1 << i))) {
- IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
}
res = nv04_resource(vb->buffer);
@@ -306,37 +320,58 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0)
if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) {
if (!nvc0->vbo_fifo)
nvc0_emit_vtxattr(nvc0, vb, &ve->pipe, i);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, NVC0_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, (1 << 12) | vb->stride);
- BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5);
- OUT_RING (chan, i);
- OUT_RESRCh(chan, res, size - 1, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, res, size - 1, NOUVEAU_BO_RD);
- OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
+ PUSH_DATA (push, (1 << 12) | vb->stride);
+ BEGIN_1IC0(push, NVC0_3D(VERTEX_ARRAY_SELECT), 5);
+ PUSH_DATA (push, i);
+ PUSH_DATAh(push, res->address + size - 1);
+ PUSH_DATA (push, res->address + size - 1);
+ PUSH_DATAh(push, res->address + offset);
+ PUSH_DATA (push, res->address + offset);
}
for (; i < nvc0->state.num_vtxelts; ++i) {
- BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(i)), 1);
- OUT_RING (chan, NVC0_3D_VERTEX_ATTRIB_INACTIVE);
+ PUSH_SPACE(push, 5);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_ATTRIB_FORMAT(i)), 1);
+ PUSH_DATA (push, NVC0_3D_VERTEX_ATTRIB_INACTIVE);
if (unlikely(nvc0->state.instance_elts & (1 << i)))
- IMMED_RING(chan, RING_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1);
- OUT_RING (chan, 0);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_PER_INSTANCE(i)), 0);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FETCH(i)), 1);
+ PUSH_DATA (push, 0);
}
nvc0->state.num_vtxelts = vertex->num_elements;
nvc0->state.instance_elts = vertex->instance_elts;
}
+void
+nvc0_idxbuf_validate(struct nvc0_context *nvc0)
+{
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+ struct nv04_resource *buf = nv04_resource(nvc0->idxbuf.buffer);
+
+ assert(buf);
+ if (!nouveau_resource_mapped_by_gpu(&buf->base))
+ return;
+
+ PUSH_SPACE(push, 6);
+ BEGIN_NVC0(push, NVC0_3D(INDEX_ARRAY_START_HIGH), 5);
+ PUSH_DATAh(push, buf->address + nvc0->idxbuf.offset);
+ PUSH_DATA (push, buf->address + nvc0->idxbuf.offset);
+ PUSH_DATAh(push, buf->address + buf->base.width0 - 1);
+ PUSH_DATA (push, buf->address + buf->base.width0 - 1);
+ PUSH_DATA (push, nvc0->idxbuf.index_size >> 1);
+
+ BCTX_REFN(nvc0->bufctx_3d, IDX, buf, RD);
+}
+
#define NVC0_PRIM_GL_CASE(n) \
case PIPE_PRIM_##n: return NVC0_3D_VERTEX_BEGIN_GL_PRIMITIVE_##n
@@ -367,13 +402,11 @@ nvc0_prim_gl(unsigned prim)
}
static void
-nvc0_draw_vbo_flush_notify(struct nouveau_channel *chan)
+nvc0_draw_vbo_kick_notify(struct nouveau_pushbuf *push)
{
- struct nvc0_screen *screen = chan->user_private;
+ struct nvc0_screen *screen = push->user_priv;
nouveau_fence_update(&screen->base, TRUE);
-
- nvc0_bufctx_emit_relocs(screen->cur_ctx);
}
static void
@@ -381,47 +414,51 @@ nvc0_draw_arrays(struct nvc0_context *nvc0,
unsigned mode, unsigned start, unsigned count,
unsigned instance_count)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
unsigned prim;
if (nvc0->state.index_bias) {
- IMMED_RING(chan, RING_3D(VB_ELEMENT_BASE), 0);
+ PUSH_SPACE(push, 1);
+ IMMED_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 0);
nvc0->state.index_bias = 0;
}
prim = nvc0_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);
- IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+ PUSH_SPACE(push, 6);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (push, prim);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_BUFFER_FIRST), 2);
+ PUSH_DATA (push, start);
+ PUSH_DATA (push, count);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
}
static void
-nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
+nvc0_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);
+ PUSH_SPACE(push, 4);
+ BEGIN_NIC0(push, NVC0_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);
+ PUSH_SPACE(push, nr + 1);
+ BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U8), nr);
for (i = 0; i < nr; ++i) {
- OUT_RING(chan,
+ PUSH_DATA(push,
(map[3] << 24) | (map[2] << 16) | (map[1] << 8) | map[0]);
map += 4;
}
@@ -430,22 +467,24 @@ nvc0_draw_elements_inline_u08(struct nouveau_channel *chan, uint8_t *map,
}
static void
-nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
+nvc0_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++);
+ PUSH_SPACE(push, 2);
+ BEGIN_NVC0(push, NVC0_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);
+ PUSH_SPACE(push, nr + 1);
+ BEGIN_NIC0(push, NVC0_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;
@@ -453,7 +492,7 @@ nvc0_draw_elements_inline_u16(struct nouveau_channel *chan, uint16_t *map,
}
static void
-nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
+nvc0_draw_elements_inline_u32(struct nouveau_pushbuf *push, uint32_t *map,
unsigned start, unsigned count)
{
map += start;
@@ -461,8 +500,9 @@ nvc0_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);
+ PUSH_SPACE(push, nr + 1);
+ BEGIN_NIC0(push, NVC0_3D(VB_ELEMENT_U32), nr);
+ PUSH_DATAp(push, map, nr);
map += nr;
count -= nr;
@@ -470,22 +510,24 @@ nvc0_draw_elements_inline_u32(struct nouveau_channel *chan, uint32_t *map,
}
static void
-nvc0_draw_elements_inline_u32_short(struct nouveau_channel *chan, uint32_t *map,
+nvc0_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++);
+ PUSH_SPACE(push, 1);
+ BEGIN_NVC0(push, NVC0_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);
+ PUSH_SPACE(push, nr + 1);
+ BEGIN_NIC0(push, NVC0_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;
@@ -497,7 +539,7 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
unsigned mode, unsigned start, unsigned count,
unsigned instance_count, int32_t index_bias)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
void *data;
unsigned prim;
const unsigned index_size = nvc0->idxbuf.index_size;
@@ -505,34 +547,27 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
prim = nvc0_prim_gl(mode);
if (index_bias != nvc0->state.index_bias) {
- BEGIN_RING(chan, RING_3D(VB_ELEMENT_BASE), 1);
- OUT_RING (chan, index_bias);
+ PUSH_SPACE(push, 2);
+ BEGIN_NVC0(push, NVC0_3D(VB_ELEMENT_BASE), 1);
+ PUSH_DATA (push, index_bias);
nvc0->state.index_bias = index_bias;
}
if (nouveau_resource_mapped_by_gpu(nvc0->idxbuf.buffer)) {
- struct nv04_resource *res = nv04_resource(nvc0->idxbuf.buffer);
- unsigned offset = nvc0->idxbuf.offset;
- unsigned limit = nvc0->idxbuf.buffer->width0 - 1;
-
- while (instance_count--) {
- MARK_RING (chan, 11, 4);
- BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (chan, mode);
- BEGIN_RING(chan, RING_3D(INDEX_ARRAY_START_HIGH), 7);
- OUT_RESRCh(chan, res, offset, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, res, offset, NOUVEAU_BO_RD);
- OUT_RESRCh(chan, res, limit, NOUVEAU_BO_RD);
- OUT_RESRCl(chan, res, limit, NOUVEAU_BO_RD);
- OUT_RING (chan, index_size >> 1);
- OUT_RING (chan, start);
- OUT_RING (chan, count);
- IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
-
- nvc0_resource_fence(res, NOUVEAU_BO_RD);
-
- mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
- }
+ PUSH_SPACE(push, 1);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), prim);
+ do {
+ PUSH_SPACE(push, 7);
+ BEGIN_NVC0(push, NVC0_3D(INDEX_BATCH_FIRST), 2);
+ PUSH_DATA (push, start);
+ PUSH_DATA (push, count);
+ if (--instance_count) {
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_END_GL), 2);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, prim | NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT);
+ }
+ } while (instance_count);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
} else {
data = nouveau_resource_map_offset(&nvc0->base,
nv04_resource(nvc0->idxbuf.buffer),
@@ -541,26 +576,28 @@ nvc0_draw_elements(struct nvc0_context *nvc0, boolean shorten,
return;
while (instance_count--) {
- BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (chan, prim);
+ PUSH_SPACE(push, 2);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (push, prim);
switch (index_size) {
case 1:
- nvc0_draw_elements_inline_u08(chan, data, start, count);
+ nvc0_draw_elements_inline_u08(push, data, start, count);
break;
case 2:
- nvc0_draw_elements_inline_u16(chan, data, start, count);
+ nvc0_draw_elements_inline_u16(push, data, start, count);
break;
case 4:
if (shorten)
- nvc0_draw_elements_inline_u32_short(chan, data, start, count);
+ nvc0_draw_elements_inline_u32_short(push, data, start, count);
else
- nvc0_draw_elements_inline_u32(chan, data, start, count);
+ nvc0_draw_elements_inline_u32(push, data, start, count);
break;
default:
assert(0);
return;
}
- IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+ PUSH_SPACE(push, 1);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
@@ -571,7 +608,7 @@ static void
nvc0_draw_stream_output(struct nvc0_context *nvc0,
const struct pipe_draw_info *info)
{
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_so_target *so = nvc0_so_target(info->count_from_stream_output);
struct nv04_resource *res = nv04_resource(so->pipe.buffer);
unsigned mode = nvc0_prim_gl(info->mode);
@@ -579,21 +616,23 @@ nvc0_draw_stream_output(struct nvc0_context *nvc0,
if (res->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
res->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
- IMMED_RING(chan, RING_3D(SERIALIZE), 0);
- nvc0_query_fifo_wait(chan, so->pq);
- IMMED_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 0);
+ PUSH_SPACE(push, 2);
+ IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+ nvc0_query_fifo_wait(push, so->pq);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 0);
}
while (num_instances--) {
- BEGIN_RING(chan, RING_3D(VERTEX_BEGIN_GL), 1);
- OUT_RING (chan, mode);
- BEGIN_RING(chan, RING_3D(DRAW_TFB_BASE), 1);
- OUT_RING (chan, 0);
- BEGIN_RING(chan, RING_3D(DRAW_TFB_STRIDE), 1);
- OUT_RING (chan, so->stride);
- BEGIN_RING(chan, RING_3D(DRAW_TFB_BYTES), 1);
- nvc0_query_pushbuf_submit(chan, so->pq, 0x4);
- IMMED_RING(chan, RING_3D(VERTEX_END_GL), 0);
+ PUSH_SPACE(push, 8);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_BEGIN_GL), 1);
+ PUSH_DATA (push, mode);
+ BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BASE), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_STRIDE), 1);
+ PUSH_DATA (push, so->stride);
+ BEGIN_NVC0(push, NVC0_3D(DRAW_TFB_BYTES), 1);
+ nvc0_query_pushbuf_submit(push, so->pq, 0x4);
+ IMMED_NVC0(push, NVC0_3D(VERTEX_END_GL), 0);
mode |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
@@ -603,7 +642,7 @@ void
nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
- struct nouveau_channel *chan = nvc0->screen->base.channel;
+ struct nouveau_pushbuf *push = nvc0->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.
@@ -624,24 +663,27 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
/* 8 as minimum to avoid immediate double validation of new buffers */
nvc0_state_validate(nvc0, ~0, 8);
- chan->flush_notify = nvc0_draw_vbo_flush_notify;
+ push->kick_notify = nvc0_draw_vbo_kick_notify;
if (nvc0->vbo_fifo) {
nvc0_push_vbo(nvc0, info);
- chan->flush_notify = nvc0_default_flush_notify;
+ push->kick_notify = nvc0_default_kick_notify;
return;
}
+ /* space for base instance, flush, and prim restart */
+ PUSH_SPACE(push, 8);
+
if (nvc0->state.instance_base != info->start_instance) {
nvc0->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_NVC0(push, NVC0_3D(VB_INSTANCE_BASE), 1);
+ PUSH_DATA (push, info->start_instance);
}
if (nvc0->base.vbo_dirty) {
- BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1);
- OUT_RING (chan, 0);
+ BEGIN_NVC0(push, NVC0_3D(VERTEX_ARRAY_FLUSH), 1);
+ PUSH_DATA (push, 0);
nvc0->base.vbo_dirty = FALSE;
}
@@ -659,20 +701,20 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (info->primitive_restart != nvc0->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_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 2);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, info->restart_index);
if (info->restart_index > 65535)
shorten = FALSE;
} else {
- IMMED_RING(chan, RING_3D(PRIM_RESTART_ENABLE), 0);
+ IMMED_NVC0(push, NVC0_3D(PRIM_RESTART_ENABLE), 0);
}
nvc0->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_NVC0(push, NVC0_3D(PRIM_RESTART_INDEX), 1);
+ PUSH_DATA (push, info->restart_index);
if (info->restart_index > 65535)
shorten = FALSE;
@@ -682,7 +724,7 @@ nvc0_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 = nvc0_default_flush_notify;
+ push->kick_notify = nvc0_default_kick_notify;
nvc0_release_user_vbufs(nvc0);
}
diff --git a/src/gallium/drivers/nvc0/nvc0_winsys.h b/src/gallium/drivers/nvc0/nvc0_winsys.h
index 0fcf9944c14..c3ab1c93644 100644
--- a/src/gallium/drivers/nvc0/nvc0_winsys.h
+++ b/src/gallium/drivers/nvc0/nvc0_winsys.h
@@ -4,117 +4,132 @@
#include <stdint.h>
#include <unistd.h>
-#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 "pipe/p_defines.h"
-#include "nvc0_resource.h" /* OUT_RESRC */
+#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 NVC0_SUBCH_3D 1
-#define NVC0_SUBCH_2D 2
-#define NVC0_SUBCH_MF 3
-#define NVC0_MF_(n) NVC0_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
+nvc0_add_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, NVC0_BIND_##bin, fl, bo);
+
+#define BCTX_REFN(bctx, bin, res, acc) \
+ nvc0_add_resident(bctx, NVC0_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 RING_3D(n) ((NVC0_SUBCH_3D << 13) | (NVC0_3D_##n >> 2))
-#define RING_2D(n) ((NVC0_SUBCH_2D << 13) | (NVC0_2D_##n >> 2))
-#define RING_MF(n) ((NVC0_SUBCH_MF << 13) | (NVC0_MF_(n) >> 2))
+#define SUBC_3D(m) 1, (m)
+#define NVC0_3D(n) SUBC_3D(NVC0_3D_##n)
-#define RING_3D_(m) ((NVC0_SUBCH_3D << 13) | ((m) >> 2))
-#define RING_2D_(m) ((NVC0_SUBCH_2D << 13) | ((m) >> 2))
-#define RING_MF_(m) ((NVC0_SUBCH_MF << 13) | ((m) >> 2))
+#define SUBC_2D(m) 2, (m)
+#define NVC0_2D(n) SUBC_2D(NVC0_2D_##n)
-#define RING_GR(gr, m) (((gr)->subc << 13) | ((m) >> 2))
+#define SUBC_M2MF(m) 3, (m)
+#define NVC0_M2MF(n) SUBC_M2MF(NVC0_M2MF_##n)
-int nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
+#define SUBC_COMPUTE(m) 4, (m)
+#define NVC0_COMPUTE(n) SUBC_COMPUTE(NVC0_COMPUTE_##n)
-static inline uint32_t
-nouveau_bo_tile_layout(const struct nouveau_bo *bo)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_SQ(int subc, int mthd, unsigned size)
{
- return bo->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK;
+ return 0x20000000 | (size << 16) | (subc << 13) | (mthd >> 2);
}
-static INLINE void
-nouveau_bo_validate(struct nouveau_channel *chan,
- struct nouveau_bo *bo, unsigned flags)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_NI(int subc, int mthd, unsigned size)
{
- nouveau_reloc_emit(chan, NULL, 0, NULL, bo, 0, 0, flags, 0, 0);
+ return 0x60000000 | (size << 16) | (subc << 13) | (mthd >> 2);
}
-/* incremental methods */
-static INLINE void
-BEGIN_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_IL(int subc, int mthd, uint8_t data)
{
- WAIT_RING(chan, size + 1);
- OUT_RING (chan, (0x2 << 28) | (size << 16) | mthd);
+ return 0x80000000 | (data << 16) | (subc << 13) | (mthd >> 2);
}
-/* non-incremental */
-static INLINE void
-BEGIN_RING_NI(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+static INLINE uint32_t
+NVC0_FIFO_PKHDR_1I(int subc, int mthd, unsigned size)
{
- WAIT_RING(chan, size + 1);
- OUT_RING (chan, (0x6 << 28) | (size << 16) | mthd);
+ return 0xa0000000 | (size << 16) | (subc << 13) | (mthd >> 2);
}
-/* increment-once */
-static INLINE void
-BEGIN_RING_1I(struct nouveau_channel *chan, uint32_t mthd, unsigned size)
+
+static INLINE uint8_t
+nouveau_bo_memtype(const struct nouveau_bo *bo)
{
- WAIT_RING(chan, size + 1);
- OUT_RING (chan, (0xa << 28) | (size << 16) | mthd);
+ return bo->config.nvc0.memtype;
}
-/* inline-data */
+
static INLINE void
-IMMED_RING(struct nouveau_channel *chan, uint32_t mthd, unsigned data)
+PUSH_DATAh(struct nouveau_pushbuf *push, uint64_t data)
{
- WAIT_RING(chan, 1);
- OUT_RING (chan, (0x8 << 28) | (data << 16) | mthd);
+ *push->cur++ = (uint32_t)(data >> 32);
}
-static INLINE int
-OUT_RESRCh(struct nouveau_channel *chan, struct nv04_resource *res,
- unsigned delta, unsigned flags)
+static INLINE void
+BEGIN_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, unsigned size)
{
- return OUT_RELOCh(chan, res->bo, res->offset + delta, res->domain | flags);
+#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+ PUSH_SPACE(push, size + 1);
+#endif
+ PUSH_DATA (push, NVC0_FIFO_PKHDR_SQ(subc, mthd, size));
}
-static INLINE int
-OUT_RESRCl(struct nouveau_channel *chan, struct nv04_resource *res,
- unsigned delta, unsigned flags)
+static INLINE void
+BEGIN_NIC0(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 NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+ PUSH_SPACE(push, size + 1);
+#endif
+ PUSH_DATA (push, NVC0_FIFO_PKHDR_NI(subc, mthd, size));
}
static INLINE void
-BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned s)
+BEGIN_1IC0(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->grclass);
+#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+ PUSH_SPACE(push, size + 1);
+#endif
+ PUSH_DATA (push, NVC0_FIFO_PKHDR_1I(subc, mthd, size));
}
+static INLINE void
+IMMED_NVC0(struct nouveau_pushbuf *push, int subc, int mthd, uint8_t data)
+{
+#ifndef NVC0_PUSH_EXPLICIT_SPACE_CHECKING
+ PUSH_SPACE(push, 1);
#endif
+ PUSH_DATA (push, NVC0_FIFO_PKHDR_IL(subc, mthd, data));
+}
+
+#endif /* __NVC0_WINSYS_H__ */