diff options
Diffstat (limited to 'src/gallium/drivers/nvc0')
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_3d.xml.h | 41 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_context.c | 147 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_context.h | 60 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_miptree.c | 81 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_program.c | 30 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_program.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_push.c | 76 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_query.c | 188 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_screen.c | 504 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_screen.h | 20 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_shader_state.c | 216 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state.c | 20 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state_validate.c | 322 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_stateobj.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_surface.c | 400 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_tex.c | 100 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_transfer.c | 257 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_vbo.c | 302 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_winsys.h | 157 |
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__ */ |