diff options
author | Francisco Jerez <[email protected]> | 2010-02-17 18:56:42 +0100 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2010-02-17 23:36:29 +0100 |
commit | 56dcd011b5ec33190f268cf546a4c68f81f5ebd0 (patch) | |
tree | 9d617916a5a9442435a935ea55ed2b9c9130609b /src/mesa/drivers/dri/nouveau/nv04_context.c | |
parent | 52e3f0949d47c846e3508a135afd75c439f2c49d (diff) |
dri/nouveau: Some multithreaded rendering fixes.
Diffstat (limited to 'src/mesa/drivers/dri/nouveau/nv04_context.c')
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nv04_context.c | 202 |
1 files changed, 187 insertions, 15 deletions
diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.c b/src/mesa/drivers/dri/nouveau/nv04_context.c index 5548286a73e..1056171342c 100644 --- a/src/mesa/drivers/dri/nouveau/nv04_context.c +++ b/src/mesa/drivers/dri/nouveau/nv04_context.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Francisco Jerez. + * Copyright (C) 2009-2010 Francisco Jerez. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining @@ -35,16 +35,16 @@ struct nouveau_grobj * nv04_context_engine(GLcontext *ctx) { struct nv04_context *nctx = to_nv04_context(ctx); - struct nouveau_screen *screen = nctx->base.screen; + struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; struct nouveau_grobj *fahrenheit; if (ctx->Texture.Unit[0].EnvMode == GL_COMBINE || ctx->Texture.Unit[0].EnvMode == GL_BLEND || ctx->Texture.Unit[1]._ReallyEnabled || ctx->Stencil.Enabled) - fahrenheit = screen->eng3dm; + fahrenheit = hw->eng3dm; else - fahrenheit = screen->eng3d; + fahrenheit = hw->eng3d; if (fahrenheit != nctx->eng3d) { nctx->eng3d = fahrenheit; @@ -69,6 +69,57 @@ nv04_context_engine(GLcontext *ctx) } static void +nv04_channel_flush_notify(struct nouveau_channel *chan) +{ + struct nouveau_context *nctx = chan->user_private; + GLcontext *ctx = &nctx->base; + + if (nctx->fallback < SWRAST && ctx->DrawBuffer) { + GLcontext *ctx = &nctx->base; + + /* Flushing seems to clobber the engine context. */ + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty_i(ctx, TEX_OBJ, 1); + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_ENV, 1); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + + nouveau_state_emit(ctx); + } +} + +static void +nv04_hwctx_init(GLcontext *ctx) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; + struct nouveau_grobj *surf3d = hw->surf3d; + struct nouveau_grobj *eng3d = hw->eng3d; + struct nouveau_grobj *eng3dm = hw->eng3dm; + + BIND_RING(chan, surf3d, 7); + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(chan, hw->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, eng3d, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, hw->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + BEGIN_RING(chan, eng3dm, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, hw->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + FIRE_RING(chan); +} + +static void init_dummy_texture(GLcontext *ctx) { struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture; @@ -82,37 +133,158 @@ init_dummy_texture(GLcontext *ctx) nouveau_bo_unmap(s->bo); } -GLcontext * +static void +nv04_context_destroy(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + nv04_surface_takedown(ctx); + nv04_render_destroy(ctx); + nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture); + + nouveau_grobj_free(&nctx->hw.eng3d); + nouveau_grobj_free(&nctx->hw.eng3dm); + nouveau_grobj_free(&nctx->hw.surf3d); + + nouveau_context_deinit(ctx); + FREE(ctx); +} + +static GLcontext * nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual, GLcontext *share_ctx) { struct nv04_context *nctx; + struct nouveau_hw_state *hw; GLcontext *ctx; + int ret; nctx = CALLOC_STRUCT(nv04_context); if (!nctx) return NULL; ctx = &nctx->base.base; - nouveau_context_init(ctx, screen, visual, share_ctx); + hw = &nctx->base.hw; + + if (!nouveau_context_init(ctx, screen, visual, share_ctx)) + goto fail; + hw->chan->flush_notify = nv04_channel_flush_notify; + + /* GL constants. */ ctx->Const.MaxTextureCoordUnits = NV04_TEXTURE_UNITS; ctx->Const.MaxTextureImageUnits = NV04_TEXTURE_UNITS; ctx->Const.MaxTextureUnits = NV04_TEXTURE_UNITS; ctx->Const.MaxTextureMaxAnisotropy = 2; ctx->Const.MaxTextureLodBias = 15; - init_dummy_texture(ctx); + /* 2D engine. */ + ret = nv04_surface_init(ctx); + if (!ret) + goto fail; + + /* 3D engine. */ + ret = nouveau_grobj_alloc(context_chan(ctx), 0xbeef0001, + NV04_TEXTURED_TRIANGLE, &hw->eng3d); + if (ret) + goto fail; + + ret = nouveau_grobj_alloc(context_chan(ctx), 0xbeef0002, + NV04_MULTITEX_TRIANGLE, &hw->eng3dm); + if (ret) + goto fail; + + ret = nouveau_grobj_alloc(context_chan(ctx), 0xbeef0003, + NV04_CONTEXT_SURFACES_3D, &hw->surf3d); + if (ret) + goto fail; + + nv04_hwctx_init(ctx); nv04_render_init(ctx); + init_dummy_texture(ctx); return ctx; -} - -void -nv04_context_destroy(GLcontext *ctx) -{ - nv04_render_destroy(ctx); - nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture); - FREE(ctx); +fail: + nv04_context_destroy(ctx); + return NULL; } + +const struct nouveau_driver nv04_driver = { + .context_create = nv04_context_create, + .context_destroy = nv04_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_blend, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nv04_defer_control, + nouveau_emit_nothing, + nv04_emit_framebuffer, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_scissor, + nv04_defer_blend, + nv04_defer_control, + nv04_defer_control, + nv04_defer_control, + nv04_emit_tex_env, + nv04_emit_tex_env, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_tex_obj, + nv04_emit_tex_obj, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_blend, + nv04_emit_control, + }, + .num_emit = NUM_NV04_STATE, +}; |