From 9cd10d7618a226fe46395b08beb19e420bc14a4f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2008 17:14:41 +1100 Subject: nv40: almost there.. --- src/gallium/drivers/nv40/nv40_state_viewport.c | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/gallium/drivers/nv40/nv40_state_viewport.c (limited to 'src/gallium/drivers/nv40/nv40_state_viewport.c') diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c new file mode 100644 index 0000000000..79fcc31a8b --- /dev/null +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -0,0 +1,30 @@ +#include "nv40_context.h" + +static boolean +nv40_state_viewport_validate(struct nv40_context *nv40) +{ + struct nouveau_stateobj *so = so_new(9, 0); + struct pipe_viewport_state *vpt = &nv40->pipe_state.viewport; + + so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); + + so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_viewport = { + .validate = nv40_state_viewport_validate, + .dirty = { + .pipe = NV40_NEW_VIEWPORT, + .hw = NV40_STATE_VIEWPORT + } +}; -- cgit v1.2.3 From 7b938431d0ab5ccce1e7e2b1c38e1dcbdc6001e8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 14:46:48 +1100 Subject: nv40: stateobj start out with 0 refcount --- src/gallium/drivers/nouveau/nouveau_stateobj.h | 2 +- src/gallium/drivers/nv40/nv40_fragprog.c | 1 - src/gallium/drivers/nv40/nv40_fragtex.c | 2 -- src/gallium/drivers/nv40/nv40_state.c | 12 ++++++------ src/gallium/drivers/nv40/nv40_state_blend.c | 1 - src/gallium/drivers/nv40/nv40_state_fb.c | 1 - src/gallium/drivers/nv40/nv40_state_scissor.c | 1 - src/gallium/drivers/nv40/nv40_state_stipple.c | 1 - src/gallium/drivers/nv40/nv40_state_viewport.c | 1 - src/gallium/drivers/nv40/nv40_vbo.c | 1 - src/gallium/drivers/nv40/nv40_vertprog.c | 1 - 11 files changed, 7 insertions(+), 17 deletions(-) (limited to 'src/gallium/drivers/nv40/nv40_state_viewport.c') diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index 459cc7d77a..439c7e4734 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -32,7 +32,7 @@ so_new(unsigned push, unsigned reloc) struct nouveau_stateobj *so; so = MALLOC(sizeof(struct nouveau_stateobj)); - so->refcount = 1; + so->refcount = 0; so->push = MALLOC(sizeof(unsigned) * push); so->reloc = MALLOC(sizeof(struct nouveau_stateobj_reloc) * reloc); diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index db2613ef8b..a4a1ea01e0 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -817,7 +817,6 @@ nv40_fragprog_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); so_ref(so, &fp->so); - so_ref(NULL, &so); update_constants: if (fp->nr_consts) { diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 3d27a9bf13..c8a8120f30 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -137,7 +137,6 @@ nv40_fragtex_validate(struct nv40_context *nv40) so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - so_ref(NULL, &so); state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } @@ -148,7 +147,6 @@ nv40_fragtex_validate(struct nv40_context *nv40) so = nv40_fragtex_build(nv40, unit); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); - so_ref(NULL, &so); state->dirty |= (1 << (NV40_STATE_FRAGTEX0 + unit)); } diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 74cbabb023..107e60f179 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -11,7 +11,7 @@ nv40_blend_state_create(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct nouveau_grobj *curie = nv40->hw->curie; - struct nv40_blend_state *bso = MALLOC(sizeof(*bso)); + struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); if (cso->blend_enable) { @@ -47,7 +47,7 @@ nv40_blend_state_create(struct pipe_context *pipe, so_method(so, curie, NV40TCL_DITHER_ENABLE, 1); so_data (so, cso->dither ? 1 : 0); - bso->so = so; + so_ref(so, &bso->so); bso->pipe = *cso; return (void *)bso; } @@ -284,7 +284,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_rasterizer_state *rsso = MALLOC(sizeof(*rsso)); + struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); struct nouveau_grobj *curie = nv40->hw->curie; @@ -389,7 +389,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, 0); } - rsso->so = so; + so_ref(so, &rsso->so); rsso->pipe = *cso; return (void *)rsso; } @@ -417,7 +417,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nv40_zsa_state *zsaso = MALLOC(sizeof(*zsaso)); + struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); @@ -460,7 +460,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, 0); } - zsaso->so = so; + so_ref(so, &zsaso->so); zsaso->pipe = *cso; return (void *)zsaso; } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index b12f8b03dd..81b927a67a 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -28,7 +28,6 @@ nv40_state_blend_colour_validate(struct nv40_context *nv40) (float_to_ubyte(bcol->color[2]) << 0))); so_ref(so, &nv40->state.hw[NV40_STATE_BCOL]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index d3032f1be5..c3bf4d43a3 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -143,7 +143,6 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) so_data (so, ((h - 1) << 16) | 0); so_ref(so, &nv40->state.hw[NV40_STATE_FB]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 2871fa2516..ee797094d3 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -22,7 +22,6 @@ nv40_state_scissor_validate(struct nv40_context *nv40) } so_ref(so, &nv40->state.hw[NV40_STATE_SCISSOR]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index bd163582a3..aad4d179ac 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -27,7 +27,6 @@ nv40_state_stipple_validate(struct nv40_context *nv40) } so_ref(so, &nv40->state.hw[NV40_STATE_STIPPLE]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 79fcc31a8b..68820d3133 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -17,7 +17,6 @@ nv40_state_viewport_validate(struct nv40_context *nv40) so_data (so, fui(vpt->scale[3])); so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); - so_ref(NULL, &so); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 3bfcb264db..5abe4c9af1 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -159,7 +159,6 @@ nv40_vbo_arrays_update(struct nv40_context *nv40, struct pipe_buffer *ib, so_emit(nv40->nvws, vtxfmt); so_emit(nv40->nvws, vtxbuf); so_ref (vtxbuf, &nv40->so_vtxbuf); - so_ref (NULL, &vtxbuf); so_ref (NULL, &vtxfmt); } diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 8a2d233697..c482964adc 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -678,7 +678,6 @@ check_gpu_resources: so_data (so, vp->ir); so_data (so, vp->or); so_ref(so, &vp->so); - so_ref(NULL, &so); upload_code = TRUE; } -- cgit v1.2.3 From 026e2fd3c6eb87a010a9c90341e8a77b09376b5b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Feb 2008 13:33:08 +1100 Subject: nv40: remove pipe_state struct now. --- src/gallium/drivers/nv40/nv40_context.h | 41 +++++++++++------------- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +-- src/gallium/drivers/nv40/nv40_fragtex.c | 2 +- src/gallium/drivers/nv40/nv40_state.c | 26 +++++++-------- src/gallium/drivers/nv40/nv40_state_blend.c | 4 +-- src/gallium/drivers/nv40/nv40_state_clip.c | 2 +- src/gallium/drivers/nv40/nv40_state_fb.c | 2 +- src/gallium/drivers/nv40/nv40_state_rasterizer.c | 2 +- src/gallium/drivers/nv40/nv40_state_scissor.c | 4 +-- src/gallium/drivers/nv40/nv40_state_stipple.c | 4 +-- src/gallium/drivers/nv40/nv40_state_viewport.c | 2 +- src/gallium/drivers/nv40/nv40_state_zsa.c | 2 +- src/gallium/drivers/nv40/nv40_vbo.c | 18 +++++------ src/gallium/drivers/nv40/nv40_vertprog.c | 4 +-- 14 files changed, 57 insertions(+), 60 deletions(-) (limited to 'src/gallium/drivers/nv40/nv40_state_viewport.c') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 110d9d7ab7..16cc053ad9 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -132,32 +132,29 @@ struct nv40_context { int chipset; - unsigned dirty; + /* HW state derived from pipe states */ + struct nv40_state state; + unsigned fallback; + /* Context state */ + unsigned dirty; + struct pipe_scissor_state scissor; + unsigned stipple[32]; + struct pipe_clip_state clip; + struct nv40_vertex_program *vertprog; + struct nv40_fragment_program *fragprog; + struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; + struct nv40_rasterizer_state *rasterizer; + struct nv40_zsa_state *zsa; + struct nv40_blend_state *blend; + struct pipe_blend_color blend_colour; + struct pipe_viewport_state viewport; + struct pipe_framebuffer_state framebuffer; + struct pipe_buffer *idxbuf; + unsigned idxbuf_format; struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; unsigned dirty_samplers; - - struct { - struct pipe_scissor_state scissor; - unsigned stipple[32]; - struct pipe_clip_state clip; - struct nv40_vertex_program *vertprog; - struct nv40_fragment_program *fragprog; - struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; - struct nv40_rasterizer_state *rasterizer; - struct nv40_zsa_state *zsa; - struct nv40_blend_state *blend; - struct pipe_blend_color blend_colour; - struct pipe_viewport_state viewport; - struct pipe_framebuffer_state framebuffer; - struct pipe_buffer *idxbuf; - unsigned idxbuf_format; - } pipe_state; - - struct nv40_state state; - unsigned fallback; - struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; }; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index a4a1ea01e0..2a8abb32a3 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -790,9 +790,9 @@ nv40_fragprog_upload(struct nv40_context *nv40, static boolean nv40_fragprog_validate(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_fragment_program *fp = nv40->fragprog; struct pipe_buffer *constbuf = - nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT]; + nv40->constbuf[PIPE_SHADER_FRAGMENT]; struct pipe_winsys *ws = nv40->pipe.winsys; struct nouveau_stateobj *so; int i; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index ed47d707b2..6be8378c08 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -126,7 +126,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) static boolean nv40_fragtex_validate(struct nv40_context *nv40) { - struct nv40_fragment_program *fp = nv40->pipe_state.fragprog; + struct nv40_fragment_program *fp = nv40->fragprog; struct nv40_state *state = &nv40->state; struct nouveau_stateobj *so; unsigned samplers, unit; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index e6f2754dc5..24335fbc44 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -57,7 +57,7 @@ nv40_blend_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.blend = hwcso; + nv40->blend = hwcso; nv40->dirty |= NV40_NEW_BLEND; } @@ -399,7 +399,7 @@ nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.rasterizer = hwcso; + nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; } @@ -470,7 +470,7 @@ nv40_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.zsa = hwcso; + nv40->zsa = hwcso; nv40->dirty |= NV40_NEW_ZSA; } @@ -500,7 +500,7 @@ nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.vertprog = hwcso; + nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; } @@ -531,7 +531,7 @@ nv40_fp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.fragprog = hwcso; + nv40->fragprog = hwcso; nv40->dirty |= NV40_NEW_FRAGPROG; } @@ -551,7 +551,7 @@ nv40_set_blend_color(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.blend_colour = *bcol; + nv40->blend_colour = *bcol; nv40->dirty |= NV40_NEW_BCOL; } @@ -561,7 +561,7 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.clip = *clip; + nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; } @@ -572,11 +572,11 @@ nv40_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct nv40_context *nv40 = nv40_context(pipe); if (shader == PIPE_SHADER_VERTEX) { - nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX] = buf->buffer; + nv40->constbuf[PIPE_SHADER_VERTEX] = buf->buffer; nv40->dirty |= NV40_NEW_VERTPROG; } else if (shader == PIPE_SHADER_FRAGMENT) { - nv40->pipe_state.constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; + nv40->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer; nv40->dirty |= NV40_NEW_FRAGPROG; } } @@ -587,7 +587,7 @@ nv40_set_framebuffer_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.framebuffer = *fb; + nv40->framebuffer = *fb; nv40->dirty |= NV40_NEW_FB; } @@ -597,7 +597,7 @@ nv40_set_polygon_stipple(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - memcpy(nv40->pipe_state.stipple, stipple->stipple, 4 * 32); + memcpy(nv40->stipple, stipple->stipple, 4 * 32); nv40->dirty |= NV40_NEW_STIPPLE; } @@ -607,7 +607,7 @@ nv40_set_scissor_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.scissor = *s; + nv40->scissor = *s; nv40->dirty |= NV40_NEW_SCISSOR; } @@ -617,7 +617,7 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); - nv40->pipe_state.viewport = *vpt; + nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index 81b927a67a..dd09830aa3 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -3,7 +3,7 @@ static boolean nv40_state_blend_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.blend->so, &nv40->state.hw[NV40_STATE_BLEND]); + so_ref(nv40->blend->so, &nv40->state.hw[NV40_STATE_BLEND]); return TRUE; } @@ -19,7 +19,7 @@ static boolean nv40_state_blend_colour_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(2, 0); - struct pipe_blend_color *bcol = &nv40->pipe_state.blend_colour; + struct pipe_blend_color *bcol = &nv40->blend_colour; so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c index 19f1c3b36d..93e690161f 100644 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -3,7 +3,7 @@ static boolean nv40_state_clip_validate(struct nv40_context *nv40) { - if (nv40->pipe_state.clip.nr) + if (nv40->clip.nr) nv40->fallback |= NV40_FALLBACK_TNL; return FALSE; diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index c3bf4d43a3..3d0ab92003 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -3,7 +3,7 @@ static boolean nv40_state_framebuffer_validate(struct nv40_context *nv40) { - struct pipe_framebuffer_state *fb = &nv40->pipe_state.framebuffer; + struct pipe_framebuffer_state *fb = &nv40->framebuffer; struct pipe_surface *rt[4], *zeta; uint32_t rt_enable, rt_format, w, h; int i, colour_format = 0, zeta_format = 0; diff --git a/src/gallium/drivers/nv40/nv40_state_rasterizer.c b/src/gallium/drivers/nv40/nv40_state_rasterizer.c index 59b35d1d50..9ecda5990f 100644 --- a/src/gallium/drivers/nv40/nv40_state_rasterizer.c +++ b/src/gallium/drivers/nv40/nv40_state_rasterizer.c @@ -3,7 +3,7 @@ static boolean nv40_state_rasterizer_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.rasterizer->so, + so_ref(nv40->rasterizer->so, &nv40->state.hw[NV40_STATE_RAST]); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index ee797094d3..09ffc49f96 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -3,8 +3,8 @@ static boolean nv40_state_scissor_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; - struct pipe_scissor_state *s = &nv40->pipe_state.scissor; + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; + struct pipe_scissor_state *s = &nv40->scissor; struct nouveau_stateobj *so; if (nv40->state.hw[NV40_STATE_SCISSOR] && diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index aad4d179ac..001c396d74 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -3,7 +3,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { - struct pipe_rasterizer_state *rast = &nv40->pipe_state.rasterizer->pipe; + struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; struct nouveau_grobj *curie = nv40->hw->curie; struct nouveau_stateobj *so; @@ -19,7 +19,7 @@ nv40_state_stipple_validate(struct nv40_context *nv40) so_data (so, 1); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_PATTERN(0), 32); for (i = 0; i < 32; i++) - so_data(so, nv40->pipe_state.stipple[i]); + so_data(so, nv40->stipple[i]); } else { so = so_new(2, 0); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 68820d3133..9616be5052 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -4,7 +4,7 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(9, 0); - struct pipe_viewport_state *vpt = &nv40->pipe_state.viewport; + struct pipe_viewport_state *vpt = &nv40->viewport; so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c index 061a3555cb..fb760677c8 100644 --- a/src/gallium/drivers/nv40/nv40_state_zsa.c +++ b/src/gallium/drivers/nv40/nv40_state_zsa.c @@ -3,7 +3,7 @@ static boolean nv40_state_zsa_validate(struct nv40_context *nv40) { - so_ref(nv40->pipe_state.zsa->so, + so_ref(nv40->zsa->so, &nv40->state.hw[NV40_STATE_ZSA]); return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index b5faf06291..1653ebf2a7 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -46,8 +46,8 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, unsigned type; if (!ib) { - nv40->pipe_state.idxbuf = NULL; - nv40->pipe_state.idxbuf_format = 0xdeadbeef; + nv40->idxbuf = NULL; + nv40->idxbuf_format = 0xdeadbeef; return FALSE; } @@ -66,11 +66,11 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, return FALSE; } - if (ib != nv40->pipe_state.idxbuf || - type != nv40->pipe_state.idxbuf_format) { + if (ib != nv40->idxbuf || + type != nv40->idxbuf_format) { nv40->dirty |= NV40_NEW_ARRAYS; - nv40->pipe_state.idxbuf = ib; - nv40->pipe_state.idxbuf_format = type; + nv40->idxbuf = ib; + nv40->idxbuf_format = type; } return TRUE; @@ -348,10 +348,10 @@ nv40_draw_elements(struct pipe_context *pipe, static boolean nv40_vbo_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nv40_vertex_program *vp = nv40->vertprog; struct nouveau_stateobj *vtxbuf, *vtxfmt; - struct pipe_buffer *ib = nv40->pipe_state.idxbuf; - unsigned ib_format = nv40->pipe_state.idxbuf_format; + struct pipe_buffer *ib = nv40->idxbuf; + unsigned ib_format = nv40->idxbuf_format; unsigned inputs, hw, num_hw; unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD; diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index c482964adc..d3ed57b199 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -634,9 +634,9 @@ out_err: static boolean nv40_vertprog_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->pipe_state.vertprog; + struct nv40_vertex_program *vp = nv40->vertprog; struct pipe_buffer *constbuf = - nv40->pipe_state.constbuf[PIPE_SHADER_VERTEX]; + nv40->constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; boolean upload_code = FALSE, upload_data = FALSE; -- cgit v1.2.3 From 17f6db9d0197657cd753249ef60355c6fd983032 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 29 Feb 2008 23:08:01 +1100 Subject: nv40: move "channel context" stuff into nv40_screen --- src/gallium/drivers/nv40/nv40_context.c | 168 +------------------------ src/gallium/drivers/nv40/nv40_context.h | 29 +---- src/gallium/drivers/nv40/nv40_fragprog.c | 4 +- src/gallium/drivers/nv40/nv40_fragtex.c | 6 +- src/gallium/drivers/nv40/nv40_query.c | 10 +- src/gallium/drivers/nv40/nv40_screen.c | 128 ++++++++++++++++++- src/gallium/drivers/nv40/nv40_screen.h | 15 +++ src/gallium/drivers/nv40/nv40_state.c | 16 +-- src/gallium/drivers/nv40/nv40_state_blend.c | 2 +- src/gallium/drivers/nv40/nv40_state_emit.c | 4 +- src/gallium/drivers/nv40/nv40_state_fb.c | 34 ++--- src/gallium/drivers/nv40/nv40_state_scissor.c | 2 +- src/gallium/drivers/nv40/nv40_state_stipple.c | 2 +- src/gallium/drivers/nv40/nv40_state_viewport.c | 2 +- src/gallium/drivers/nv40/nv40_vbo.c | 10 +- src/gallium/drivers/nv40/nv40_vertprog.c | 8 +- 16 files changed, 203 insertions(+), 237 deletions(-) (limited to 'src/gallium/drivers/nv40/nv40_state_viewport.c') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 679c2ddc6b..084829ce28 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -6,10 +6,6 @@ #include "nv40_context.h" #include "nv40_screen.h" -#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf -#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 -#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 - static void nv40_flush(struct pipe_context *pipe, unsigned flags) { @@ -24,7 +20,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) } if (flags & PIPE_FLUSH_WAIT) { - nvws->notifier_reset(nv40->hw->sync, 0); + nvws->notifier_reset(nv40->screen->sync, 0); BEGIN_RING(curie, 0x104, 1); OUT_RING (0); BEGIN_RING(curie, 0x100, 1); @@ -34,149 +30,7 @@ nv40_flush(struct pipe_context *pipe, unsigned flags) FIRE_RING(); if (flags & PIPE_FLUSH_WAIT) - nvws->notifier_wait(nv40->hw->sync, 0, 0, 2000); -} - -static void -nv40_channel_takedown(struct nv40_channel_context *cnv40) -{ - struct nouveau_winsys *nvws = cnv40->nvws; - - nvws->res_free(&cnv40->vp_exec_heap); - nvws->res_free(&cnv40->vp_data_heap); - nvws->res_free(&cnv40->query_heap); - nvws->notifier_free(&cnv40->query); - nvws->notifier_free(&cnv40->sync); - nvws->grobj_free(&cnv40->curie); - free(cnv40); -} - -static struct nv40_channel_context * -nv40_channel_init(struct pipe_winsys *ws, struct nouveau_winsys *nvws, - unsigned chipset) -{ - struct nv40_channel_context *cnv40 = NULL; - struct nouveau_stateobj *so; - unsigned curie_class = 0; - int ret; - - switch (chipset & 0xf0) { - case 0x40: - if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f))) - curie_class = NV40TCL; - else - if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) - curie_class = NV44TCL; - break; - case 0x60: - if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) - curie_class = NV44TCL; - break; - default: - break; - } - - if (!curie_class) { - NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset); - return NULL; - } - - cnv40 = CALLOC(1, sizeof(struct nv40_channel_context)); - if (!cnv40) - return NULL; - cnv40->chipset = chipset; - cnv40->nvws = nvws; - - /* Notifier for sync purposes */ - ret = nvws->notifier_alloc(nvws, 1, &cnv40->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - /* Query objects */ - ret = nvws->notifier_alloc(nvws, 32, &cnv40->query); - if (ret) { - NOUVEAU_ERR("Error initialising query objects: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - ret = nvws->res_init(&cnv40->query_heap, 0, 32); - if (ret) { - NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); - nv40_channel_takedown(cnv40); - return NULL; - } - - /* Vtxprog resources */ - if (nvws->res_init(&cnv40->vp_exec_heap, 0, 512) || - nvws->res_init(&cnv40->vp_data_heap, 0, 256)) { - nv40_channel_takedown(cnv40); - return NULL; - } - - /* 3D object */ - ret = nvws->grobj_alloc(nvws, curie_class, &cnv40->curie); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - /* Static curie initialisation */ - so = so_new(128, 0); - so_method(so, cnv40->curie, NV40TCL_DMA_NOTIFY, 1); - so_data (so, cnv40->sync->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_TEXTURE0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->gart->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR1, 1); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_VTXBUF0, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->gart->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_FENCE, 2); - so_data (so, 0); - so_data (so, cnv40->query->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_UNK01AC, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - so_method(so, cnv40->curie, NV40TCL_DMA_COLOR2, 2); - so_data (so, nvws->channel->vram->handle); - so_data (so, nvws->channel->vram->handle); - - so_method(so, cnv40->curie, 0x1ea4, 3); - so_data (so, 0x00000010); - so_data (so, 0x01000100); - so_data (so, 0xff800006); - - /* vtxprog output routing */ - so_method(so, cnv40->curie, 0x1fc4, 1); - so_data (so, 0x06144321); - so_method(so, cnv40->curie, 0x1fc8, 2); - so_data (so, 0xedcba987); - so_data (so, 0x00000021); - so_method(so, cnv40->curie, 0x1fd0, 1); - so_data (so, 0x00171615); - so_method(so, cnv40->curie, 0x1fd4, 1); - so_data (so, 0x001b1a19); - - so_method(so, cnv40->curie, 0x1ef8, 1); - so_data (so, 0x0020ffff); - so_method(so, cnv40->curie, 0x1d64, 1); - so_data (so, 0x00d30000); - so_method(so, cnv40->curie, 0x1e94, 1); - so_data (so, 0x00000001); - - so_emit(nvws, so); - so_ref(NULL, &so); - nvws->push_flush(nvws->channel, 0); - - return cnv40; + nvws->notifier_wait(nv40->screen->sync, 0, 0, 2000); } static void @@ -186,32 +40,22 @@ nv40_destroy(struct pipe_context *pipe) if (nv40->draw) draw_destroy(nv40->draw); - - if (nv40->hw) { - if (--nv40->hw->refcount == 0) - nv40_channel_takedown(nv40->hw); - } - free(nv40); } struct pipe_context * nv40_create(struct pipe_screen *pscreen) { + struct nv40_screen *screen = nv40_screen(pscreen); struct pipe_winsys *ws = pscreen->winsys; struct nv40_context *nv40; - unsigned chipset = nv40_screen(pscreen)->chipset; - struct nouveau_winsys *nvws = nv40_screen(pscreen)->nvws; + unsigned chipset = screen->chipset; + struct nouveau_winsys *nvws = screen->nvws; nv40 = CALLOC(1, sizeof(struct nv40_context)); if (!nv40) return NULL; - - nv40->hw = nv40_channel_init(ws, nvws, chipset); - if (!nv40->hw) { - nv40_destroy(&nv40->pipe); - return NULL; - } + nv40->screen = screen; nv40->chipset = chipset; nv40->nvws = nvws; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 3ddfbd43f6..3b669594dc 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -11,7 +11,7 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv40_channel_context *ctx = nv40->hw + struct nv40_screen *ctx = nv40->screen #include "nouveau/nouveau_push.h" #include "nouveau/nouveau_stateobj.h" @@ -59,6 +59,8 @@ enum nv40_state_index { NV40_STATE_MAX = 33 }; +#include "nv40_screen.h" + #define NV40_NEW_BLEND (1 << 0) #define NV40_NEW_RAST (1 << 1) #define NV40_NEW_ZSA (1 << 2) @@ -76,28 +78,6 @@ enum nv40_state_index { #define NV40_FALLBACK_TNL (1 << 0) #define NV40_FALLBACK_RAST (1 << 1) -struct nv40_channel_context { - struct nouveau_winsys *nvws; - unsigned refcount; - - unsigned chipset; - - /* HW graphics objects */ - struct nouveau_grobj *curie; - struct nouveau_notifier *sync; - - /* Query object resources */ - struct nouveau_notifier *query; - struct nouveau_resource *query_heap; - - /* Vtxprog resources */ - struct nouveau_resource *vp_exec_heap; - struct nouveau_resource *vp_data_heap; - - /* Current 3D state of channel */ - struct nouveau_stateobj *state[NV40_STATE_MAX]; -}; - struct nv40_rasterizer_state { struct pipe_rasterizer_state pipe; struct nouveau_stateobj *so; @@ -125,9 +105,10 @@ struct nv40_state { struct nv40_context { struct pipe_context pipe; + struct nouveau_winsys *nvws; + struct nv40_screen *screen; - struct nv40_channel_context *hw; struct draw_context *draw; int chipset; diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 2a8abb32a3..3c4ea7e99e 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -810,11 +810,11 @@ nv40_fragprog_validate(struct nv40_context *nv40) nv40_fragprog_upload(nv40, fp); so = so_new(4, 1); - so_method(so, nv40->hw->curie, NV40TCL_FP_ADDRESS, 1); + so_method(so, nv40->screen->curie, NV40TCL_FP_ADDRESS, 1); so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR, NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1); - so_method(so, nv40->hw->curie, NV40TCL_FP_CONTROL, 1); + so_method(so, nv40->screen->curie, NV40TCL_FP_CONTROL, 1); so_data (so, fp->fp_control); so_ref(so, &fp->so); diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index 6be8378c08..436f954cec 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -106,7 +106,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) txs = tf->swizzle; so = so_new(16, 2); - so_method(so, nv40->hw->curie, NV40TCL_TEX_OFFSET(unit), 8); + so_method(so, nv40->screen->curie, NV40TCL_TEX_OFFSET(unit), 8); so_reloc (so, nv40mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0); so_reloc (so, nv40mt->buffer, txf, tex_flags | NOUVEAU_BO_OR, NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1); @@ -117,7 +117,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit) so_data (so, (pt->width[0] << NV40TCL_TEX_SIZE0_W_SHIFT) | pt->height[0]); so_data (so, ps->bcol); - so_method(so, nv40->hw->curie, NV40TCL_TEX_SIZE1(unit), 1); + so_method(so, nv40->screen->curie, NV40TCL_TEX_SIZE1(unit), 1); so_data (so, (pt->depth[0] << NV40TCL_TEX_SIZE1_DEPTH_SHIFT) | txp); return so; @@ -137,7 +137,7 @@ nv40_fragtex_validate(struct nv40_context *nv40) samplers &= ~(1 << unit); so = so_new(2, 0); - so_method(so, nv40->hw->curie, NV40TCL_TEX_ENABLE(unit), 1); + so_method(so, nv40->screen->curie, NV40TCL_TEX_ENABLE(unit), 1); so_data (so, 0); so_ref(so, &nv40->state.hw[NV40_STATE_FRAGTEX0 + unit]); state->dirty |= (1ULL << (NV40_STATE_FRAGTEX0 + unit)); diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c index 8bca2788b9..0317845624 100644 --- a/src/gallium/drivers/nv40/nv40_query.c +++ b/src/gallium/drivers/nv40/nv40_query.c @@ -45,9 +45,9 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq) assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER); - if (nv40->nvws->res_alloc(nv40->hw->query_heap, 1, NULL, &q->object)) + if (nv40->nvws->res_alloc(nv40->screen->query_heap, 1, NULL, &q->object)) assert(0); - nv40->nvws->notifier_reset(nv40->hw->query, q->object->start); + nv40->nvws->notifier_reset(nv40->screen->query, q->object->start); BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1); OUT_RING (1); @@ -82,17 +82,17 @@ nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq, if (!q->ready) { unsigned status; - status = nvws->notifier_status(nv40->hw->query, + status = nvws->notifier_status(nv40->screen->query, q->object->start); if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) { if (wait == FALSE) return FALSE; - nvws->notifier_wait(nv40->hw->query, q->object->start, + nvws->notifier_wait(nv40->screen->query, q->object->start, NV_NOTIFY_STATE_STATUS_COMPLETED, 0); } - q->result = nvws->notifier_retval(nv40->hw->query, + q->result = nvws->notifier_retval(nv40->screen->query, q->object->start); q->ready = TRUE; nvws->res_free(&q->object); diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 66e84b6890..268ca83ce0 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -4,6 +4,10 @@ #include "nv40_context.h" #include "nv40_screen.h" +#define NV4X_GRCLASS4097_CHIPSETS 0x00000baf +#define NV4X_GRCLASS4497_CHIPSETS 0x00005450 +#define NV6X_GRCLASS4497_CHIPSETS 0x00000088 + static const char * nv40_screen_get_name(struct pipe_screen *pscreen) { @@ -121,6 +125,16 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, static void nv40_screen_destroy(struct pipe_screen *pscreen) { + struct nv40_screen *screen = nv40_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->res_free(&screen->vp_exec_heap); + nvws->res_free(&screen->vp_data_heap); + nvws->res_free(&screen->query_heap); + nvws->notifier_free(&screen->query); + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->curie); + FREE(pscreen); } @@ -129,13 +143,125 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen); + struct nouveau_stateobj *so; + unsigned curie_class; + int ret; if (!screen) return NULL; - screen->chipset = chipset; screen->nvws = nvws; + /* 3D object */ + switch (chipset & 0xf0) { + case 0x40: + if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV40TCL; + else + if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + case 0x60: + if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f))) + curie_class = NV44TCL; + break; + default: + break; + } + + if (!curie_class) { + NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset); + return NULL; + } + + ret = nvws->grobj_alloc(nvws, curie_class, &screen->curie); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return FALSE; + } + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Query objects */ + ret = nvws->notifier_alloc(nvws, 32, &screen->query); + if (ret) { + NOUVEAU_ERR("Error initialising query objects: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + ret = nvws->res_init(&screen->query_heap, 0, 32); + if (ret) { + NOUVEAU_ERR("Error initialising query object heap: %d\n", ret); + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Vtxprog resources */ + if (nvws->res_init(&screen->vp_exec_heap, 0, 512) || + nvws->res_init(&screen->vp_data_heap, 0, 256)) { + nv40_screen_destroy(&screen->pipe); + return NULL; + } + + /* Static curie initialisation */ + so = so_new(128, 0); + so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1); + so_data (so, screen->sync->handle); + so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR1, 1); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_VTXBUF0, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->gart->handle); + so_method(so, screen->curie, NV40TCL_DMA_FENCE, 2); + so_data (so, 0); + so_data (so, screen->query->handle); + so_method(so, screen->curie, NV40TCL_DMA_UNK01AC, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + so_method(so, screen->curie, NV40TCL_DMA_COLOR2, 2); + so_data (so, nvws->channel->vram->handle); + so_data (so, nvws->channel->vram->handle); + + so_method(so, screen->curie, 0x1ea4, 3); + so_data (so, 0x00000010); + so_data (so, 0x01000100); + so_data (so, 0xff800006); + + /* vtxprog output routing */ + so_method(so, screen->curie, 0x1fc4, 1); + so_data (so, 0x06144321); + so_method(so, screen->curie, 0x1fc8, 2); + so_data (so, 0xedcba987); + so_data (so, 0x00000021); + so_method(so, screen->curie, 0x1fd0, 1); + so_data (so, 0x00171615); + so_method(so, screen->curie, 0x1fd4, 1); + so_data (so, 0x001b1a19); + + so_method(so, screen->curie, 0x1ef8, 1); + so_data (so, 0x0020ffff); + so_method(so, screen->curie, 0x1d64, 1); + so_data (so, 0x00d30000); + so_method(so, screen->curie, 0x1e94, 1); + so_data (so, 0x00000001); + + so_emit(nvws, so); + so_ref(NULL, &so); + nvws->push_flush(nvws->channel, 0); + screen->pipe.winsys = ws; screen->pipe.destroy = nv40_screen_destroy; diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 88b8fed26c..9f9668dbb6 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -8,6 +8,21 @@ struct nv40_screen { struct nouveau_winsys *nvws; unsigned chipset; + + /* HW graphics objects */ + struct nouveau_grobj *curie; + struct nouveau_notifier *sync; + + /* Query object resources */ + struct nouveau_notifier *query; + struct nouveau_resource *query_heap; + + /* Vtxprog resources */ + struct nouveau_resource *vp_exec_heap; + struct nouveau_resource *vp_data_heap; + + /* Current 3D state of channel */ + struct nouveau_stateobj *state[NV40_STATE_MAX]; }; static INLINE struct nv40_screen * diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 24335fbc44..caa2f9df0c 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -10,7 +10,7 @@ nv40_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); - struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; struct nv40_blend_state *bso = CALLOC(1, sizeof(*bso)); struct nouveau_stateobj *so = so_new(16, 0); @@ -286,7 +286,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); - struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; /*XXX: ignored: * light_twoside @@ -420,18 +420,18 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); struct nouveau_stateobj *so = so_new(32, 0); - so_method(so, nv40->hw->curie, NV40TCL_DEPTH_FUNC, 3); + so_method(so, nv40->screen->curie, NV40TCL_DEPTH_FUNC, 3); so_data (so, nvgl_comparison_op(cso->depth.func)); so_data (so, cso->depth.writemask ? 1 : 0); so_data (so, cso->depth.enabled ? 1 : 0); - so_method(so, nv40->hw->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); + so_method(so, nv40->screen->curie, NV40TCL_ALPHA_TEST_ENABLE, 3); so_data (so, cso->alpha.enabled ? 1 : 0); so_data (so, nvgl_comparison_op(cso->alpha.func)); so_data (so, float_to_ubyte(cso->alpha.ref)); if (cso->stencil[0].enabled) { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); so_data (so, cso->stencil[0].enabled ? 1 : 0); so_data (so, cso->stencil[0].write_mask); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); @@ -441,12 +441,12 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); } else { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_ENABLE, 1); so_data (so, 0); } if (cso->stencil[1].enabled) { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 8); so_data (so, cso->stencil[1].enabled ? 1 : 0); so_data (so, cso->stencil[1].write_mask); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); @@ -456,7 +456,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); } else { - so_method(so, nv40->hw->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_ENABLE, 1); so_data (so, 0); } diff --git a/src/gallium/drivers/nv40/nv40_state_blend.c b/src/gallium/drivers/nv40/nv40_state_blend.c index dd09830aa3..95e6d7394f 100644 --- a/src/gallium/drivers/nv40/nv40_state_blend.c +++ b/src/gallium/drivers/nv40/nv40_state_blend.c @@ -21,7 +21,7 @@ nv40_state_blend_colour_validate(struct nv40_context *nv40) struct nouveau_stateobj *so = so_new(2, 0); struct pipe_blend_color *bcol = &nv40->blend_colour; - so_method(so, nv40->hw->curie, NV40TCL_BLEND_COLOR, 1); + so_method(so, nv40->screen->curie, NV40TCL_BLEND_COLOR, 1); so_data (so, ((float_to_ubyte(bcol->color[3]) << 24) | (float_to_ubyte(bcol->color[0]) << 16) | (float_to_ubyte(bcol->color[1]) << 8) | diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index bb2ce0f722..221503617c 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -67,8 +67,8 @@ nv40_state_emit(struct nv40_context *nv40) while (state->dirty) { unsigned idx = ffsll(state->dirty) - 1; - so_ref (state->hw[idx], &nv40->hw->state[idx]); - so_emit(nv40->nvws, nv40->hw->state[idx]); + so_ref (state->hw[idx], &nv40->screen->state[idx]); + so_emit(nv40->nvws, nv40->screen->state[idx]); state->dirty &= ~(1ULL << idx); } diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c index 3d0ab92003..71795ab182 100644 --- a/src/gallium/drivers/nv40/nv40_state_fb.c +++ b/src/gallium/drivers/nv40/nv40_state_fb.c @@ -72,73 +72,73 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40) } if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR0, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR0, 1); so_reloc (so, rt[0]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR0_PITCH, 2); + so_method(so, nv40->screen->curie, NV40TCL_COLOR0_PITCH, 2); so_data (so, rt[0]->pitch * rt[0]->cpp); so_reloc (so, rt[0]->buffer, rt[0]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR1, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR1, 1); so_reloc (so, rt[1]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR1_OFFSET, 2); + so_method(so, nv40->screen->curie, NV40TCL_COLOR1_OFFSET, 2); so_reloc (so, rt[1]->buffer, rt[1]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); so_data (so, rt[1]->pitch * rt[1]->cpp); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR2, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR2, 1); so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR2_OFFSET, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR2_OFFSET, 1); so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_COLOR2_PITCH, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR2_PITCH, 1); so_data (so, rt[2]->pitch * rt[2]->cpp); } if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_COLOR3, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR3, 1); so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_COLOR3_OFFSET, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR3_OFFSET, 1); so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_COLOR3_PITCH, 1); + so_method(so, nv40->screen->curie, NV40TCL_COLOR3_PITCH, 1); so_data (so, rt[3]->pitch * rt[3]->cpp); } if (zeta_format) { - so_method(so, nv40->hw->curie, NV40TCL_DMA_ZETA, 1); + so_method(so, nv40->screen->curie, NV40TCL_DMA_ZETA, 1); so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR, nv40->nvws->channel->vram->handle, nv40->nvws->channel->gart->handle); - so_method(so, nv40->hw->curie, NV40TCL_ZETA_OFFSET, 1); + so_method(so, nv40->screen->curie, NV40TCL_ZETA_OFFSET, 1); so_reloc (so, zeta->buffer, zeta->offset, rt_flags | NOUVEAU_BO_LOW, 0, 0); - so_method(so, nv40->hw->curie, NV40TCL_ZETA_PITCH, 1); + so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1); so_data (so, zeta->pitch * zeta->cpp); } - so_method(so, nv40->hw->curie, NV40TCL_RT_ENABLE, 1); + so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1); so_data (so, rt_enable); - so_method(so, nv40->hw->curie, NV40TCL_RT_HORIZ, 3); + so_method(so, nv40->screen->curie, NV40TCL_RT_HORIZ, 3); so_data (so, (w << 16) | 0); so_data (so, (h << 16) | 0); so_data (so, rt_format); - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_HORIZ, 2); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_HORIZ, 2); so_data (so, (w << 16) | 0); so_data (so, (h << 16) | 0); - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2); so_data (so, ((w - 1) << 16) | 0); so_data (so, ((h - 1) << 16) | 0); diff --git a/src/gallium/drivers/nv40/nv40_state_scissor.c b/src/gallium/drivers/nv40/nv40_state_scissor.c index 09ffc49f96..9e9eadc511 100644 --- a/src/gallium/drivers/nv40/nv40_state_scissor.c +++ b/src/gallium/drivers/nv40/nv40_state_scissor.c @@ -12,7 +12,7 @@ nv40_state_scissor_validate(struct nv40_context *nv40) return FALSE; so = so_new(3, 0); - so_method(so, nv40->hw->curie, NV40TCL_SCISSOR_HORIZ, 2); + so_method(so, nv40->screen->curie, NV40TCL_SCISSOR_HORIZ, 2); if (rast->scissor) { so_data (so, ((s->maxx - s->minx) << 16) | s->minx); so_data (so, ((s->maxy - s->miny) << 16) | s->miny); diff --git a/src/gallium/drivers/nv40/nv40_state_stipple.c b/src/gallium/drivers/nv40/nv40_state_stipple.c index 001c396d74..b51024ad9b 100644 --- a/src/gallium/drivers/nv40/nv40_state_stipple.c +++ b/src/gallium/drivers/nv40/nv40_state_stipple.c @@ -4,7 +4,7 @@ static boolean nv40_state_stipple_validate(struct nv40_context *nv40) { struct pipe_rasterizer_state *rast = &nv40->rasterizer->pipe; - struct nouveau_grobj *curie = nv40->hw->curie; + struct nouveau_grobj *curie = nv40->screen->curie; struct nouveau_stateobj *so; if (nv40->state.hw[NV40_STATE_STIPPLE] && diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 9616be5052..3a32533907 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -6,7 +6,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) struct nouveau_stateobj *so = so_new(9, 0); struct pipe_viewport_state *vpt = &nv40->viewport; - so_method(so, nv40->hw->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); so_data (so, fui(vpt->translate[1])); so_data (so, fui(vpt->translate[2])); diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 1653ebf2a7..bedc8c6d4e 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -52,7 +52,7 @@ nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib, } /* No support for 8bit indices, no support at all on 0x4497 chips */ - if (nv40->hw->curie->grclass == NV44TCL || ib_size == 1) + if (nv40->screen->curie->grclass == NV44TCL || ib_size == 1) return FALSE; switch (ib_size) { @@ -365,9 +365,9 @@ nv40_vbo_validate(struct nv40_context *nv40) num_hw++; vtxbuf = so_new(20, 18); - so_method(vtxbuf, nv40->hw->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); + so_method(vtxbuf, nv40->screen->curie, NV40TCL_VTXBUF_ADDRESS(0), num_hw); vtxfmt = so_new(17, 0); - so_method(vtxfmt, nv40->hw->curie, NV40TCL_VTXFMT(0), num_hw); + so_method(vtxfmt, nv40->screen->curie, NV40TCL_VTXFMT(0), num_hw); inputs = vp->ir; for (hw = 0; hw < num_hw; hw++) { @@ -399,13 +399,13 @@ nv40_vbo_validate(struct nv40_context *nv40) } if (ib) { - so_method(vtxbuf, nv40->hw->curie, NV40TCL_IDXBUF_ADDRESS, 2); + so_method(vtxbuf, nv40->screen->curie, NV40TCL_IDXBUF_ADDRESS, 2); so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0); so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR, 0, NV40TCL_IDXBUF_FORMAT_DMA1); } - so_method(vtxbuf, nv40->hw->curie, 0x1710, 1); + so_method(vtxbuf, nv40->screen->curie, 0x1710, 1); so_data (vtxbuf, 0); so_ref(vtxbuf, &nv40->state.hw[NV40_STATE_VTXBUF]); diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index d3ed57b199..5b7a343e55 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -655,7 +655,7 @@ nv40_vertprog_validate(struct nv40_context *nv40) check_gpu_resources: /* Allocate hw vtxprog exec slots */ if (!vp->exec) { - struct nouveau_resource *heap = nv40->hw->vp_exec_heap; + struct nouveau_resource *heap = nv40->screen->vp_exec_heap; struct nouveau_stateobj *so; uint vplen = vp->nr_insns; @@ -672,9 +672,9 @@ check_gpu_resources: } so = so_new(5, 0); - so_method(so, nv40->hw->curie, NV40TCL_VP_START_FROM_ID, 1); + so_method(so, nv40->screen->curie, NV40TCL_VP_START_FROM_ID, 1); so_data (so, vp->exec->start); - so_method(so, nv40->hw->curie, NV40TCL_VP_ATTRIB_EN, 2); + so_method(so, nv40->screen->curie, NV40TCL_VP_ATTRIB_EN, 2); so_data (so, vp->ir); so_data (so, vp->or); so_ref(so, &vp->so); @@ -684,7 +684,7 @@ check_gpu_resources: /* Allocate hw vtxprog const slots */ if (vp->nr_consts && !vp->data) { - struct nouveau_resource *heap = nv40->hw->vp_data_heap; + struct nouveau_resource *heap = nv40->screen->vp_data_heap; if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) { while (heap->next && heap->size < vp->nr_consts) { -- cgit v1.2.3 From e1cf3f00e546f814effd25e9ccd072c941366444 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 13 Mar 2008 18:29:56 +1100 Subject: nv40: simple swtnl path (half broken, but getting there) --- src/gallium/drivers/nv40/nv40_context.c | 6 +- src/gallium/drivers/nv40/nv40_context.h | 25 +- src/gallium/drivers/nv40/nv40_draw.c | 334 +++++++++++++++++++++++-- src/gallium/drivers/nv40/nv40_fragprog.c | 3 +- src/gallium/drivers/nv40/nv40_shader.h | 2 + src/gallium/drivers/nv40/nv40_state.c | 27 +- src/gallium/drivers/nv40/nv40_state.h | 4 + src/gallium/drivers/nv40/nv40_state_clip.c | 8 +- src/gallium/drivers/nv40/nv40_state_emit.c | 130 +++++++--- src/gallium/drivers/nv40/nv40_state_viewport.c | 45 +++- src/gallium/drivers/nv40/nv40_vbo.c | 22 +- src/gallium/drivers/nv40/nv40_vertprog.c | 16 +- 12 files changed, 531 insertions(+), 91 deletions(-) (limited to 'src/gallium/drivers/nv40/nv40_state_viewport.c') diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c index 203c843a01..58627443b8 100644 --- a/src/gallium/drivers/nv40/nv40_context.c +++ b/src/gallium/drivers/nv40/nv40_context.c @@ -74,8 +74,12 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id) nv40_init_state_functions(nv40); nv40_init_miptree_functions(nv40); + /* Create, configure, and install fallback swtnl path */ nv40->draw = draw_create(); - assert(nv40->draw); + draw_wide_point_threshold(nv40->draw, 9999999.0); + draw_wide_line_threshold(nv40->draw, 9999999.0); + draw_enable_line_stipple(nv40->draw, FALSE); + draw_enable_point_sprites(nv40->draw, FALSE); draw_set_rasterize_stage(nv40->draw, nv40_draw_render_stage(nv40)); return &nv40->pipe; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 100c678187..02ca20b801 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -116,7 +116,20 @@ struct nv40_context { /* HW state derived from pipe states */ struct nv40_state state; - unsigned fallback; + struct { + struct nv40_vertex_program *vertprog; + + unsigned nr_attribs; + unsigned hw[PIPE_MAX_SHADER_INPUTS]; + unsigned draw[PIPE_MAX_SHADER_INPUTS]; + unsigned emit[PIPE_MAX_SHADER_INPUTS]; + } swtnl; + + enum { + HW, SWTNL, SWRAST + } render_mode; + unsigned fallback_swtnl; + unsigned fallback_swrast; /* Context state */ unsigned dirty; @@ -166,6 +179,10 @@ extern void nv40_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv40_draw.c */ extern struct draw_stage *nv40_draw_render_stage(struct nv40_context *nv40); +extern boolean nv40_draw_elements_swtnl(struct pipe_context *pipe, + struct pipe_buffer *idxbuf, + unsigned ib_size, unsigned mode, + unsigned start, unsigned count); /* nv40_vertprog.c */ extern void nv40_vertprog_destroy(struct nv40_context *, @@ -179,8 +196,9 @@ extern void nv40_fragprog_destroy(struct nv40_context *, extern void nv40_fragtex_bind(struct nv40_context *); /* nv40_state.c and friends */ -extern void nv40_emit_hw_state(struct nv40_context *nv40); -extern void nv40_state_tex_update(struct nv40_context *nv40); +extern boolean nv40_state_validate(struct nv40_context *nv40); +extern boolean nv40_state_validate_swtnl(struct nv40_context *nv40); +extern void nv40_state_emit(struct nv40_context *nv40); extern struct nv40_state_entry nv40_state_clip; extern struct nv40_state_entry nv40_state_rasterizer; extern struct nv40_state_entry nv40_state_scissor; @@ -194,6 +212,7 @@ extern struct nv40_state_entry nv40_state_viewport; extern struct nv40_state_entry nv40_state_framebuffer; extern struct nv40_state_entry nv40_state_fragtex; extern struct nv40_state_entry nv40_state_vbo; +extern struct nv40_state_entry nv40_state_vtxfmt; /* nv40_vbo.c */ extern boolean nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index a39bb85e99..ce0e0bc6f2 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -1,62 +1,350 @@ -#include "draw/draw_private.h" #include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + +#include "draw/draw_context.h" +#include "draw/draw_vertex.h" +#include "draw/draw_private.h" #include "nv40_context.h" +#define NV40_SHADER_NO_FUCKEDNESS +#include "nv40_shader.h" + +/* Simple, but crappy, swtnl path, hopefully we wont need to hit this very + * often at all. Uses "quadro style" vertex submission + a fixed vertex + * layout to avoid the need to generate a vertex program or vtxfmt. + */ -struct nv40_draw_stage { - struct draw_stage draw; +struct nv40_render_stage { + struct draw_stage stage; struct nv40_context *nv40; + unsigned prim; }; +static INLINE struct nv40_render_stage * +nv40_render_stage(struct draw_stage *stage) +{ + return (struct nv40_render_stage *)stage; +} + +static INLINE void +nv40_render_vertex(struct nv40_context *nv40, const struct vertex_header *v) +{ + unsigned i; + + for (i = 0; i < nv40->swtnl.nr_attribs; i++) { + unsigned idx = nv40->swtnl.draw[i]; + unsigned hw = nv40->swtnl.hw[i]; + + switch (nv40->swtnl.emit[i]) { + case EMIT_OMIT: + break; + case EMIT_1F: + BEGIN_RING(curie, 0x1e40 + (hw * 4), 1); + OUT_RING (fui(v->data[idx][0])); + break; + case EMIT_2F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_2F_X(hw), 2); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + break; + case EMIT_3F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_3F_X(hw), 3); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + OUT_RING (fui(v->data[idx][2])); + break; + case EMIT_4F: + BEGIN_RING(curie, NV40TCL_VTX_ATTR_4F_X(hw), 4); + OUT_RING (fui(v->data[idx][0])); + OUT_RING (fui(v->data[idx][1])); + OUT_RING (fui(v->data[idx][2])); + OUT_RING (fui(v->data[idx][3])); + break; + case EMIT_4UB: + BEGIN_RING(curie, 0x1940 + (hw * 4), 1); + OUT_RING (pack_ub4(float_to_ubyte(v->data[idx][0]), + float_to_ubyte(v->data[idx][1]), + float_to_ubyte(v->data[idx][2]), + float_to_ubyte(v->data[idx][3]))); + break; + default: + assert(0); + break; + } + } +} + +static INLINE void +nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, + unsigned mode, unsigned count) +{ + struct nv40_render_stage *rs = nv40_render_stage(stage); + struct nv40_context *nv40 = rs->nv40; + struct nouveau_pushbuf *pb = nv40->nvws->channel->pushbuf; + unsigned i; + + /* Ensure there's room for 4xfloat32 + potentially 3 begin/end */ + if (pb->remaining < ((count * 20) + 6)) { + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + NOUVEAU_ERR("AIII, missed flush\n"); + assert(0); + } + FIRE_RING(); + nv40_state_emit(nv40); + } + + /* Switch primitive modes if necessary */ + if (rs->prim != mode) { + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + } + + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (mode); + rs->prim = mode; + } + + /* Emit vertex data */ + for (i = 0; i < count; i++) + nv40_render_vertex(nv40, prim->v[i]); + + /* If it's likely we'll need to empty the push buffer soon, finish + * off the primitive now. + */ + if (pb->remaining < ((count * 20) + 6)) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + rs->prim = NV40TCL_BEGIN_END_STOP; + } +} + static void -nv40_draw_point(struct draw_stage *draw, struct prim_header *prim) +nv40_render_point(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_POINTS, 1); } static void -nv40_draw_line(struct draw_stage *draw, struct prim_header *prim) +nv40_render_line(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_LINES, 2); } static void -nv40_draw_tri(struct draw_stage *draw, struct prim_header *prim) +nv40_render_tri(struct draw_stage *draw, struct prim_header *prim) { - NOUVEAU_ERR("\n"); + nv40_render_prim(draw, prim, NV40TCL_BEGIN_END_TRIANGLES, 3); } static void -nv40_draw_flush(struct draw_stage *draw, unsigned flags) +nv40_render_flush(struct draw_stage *draw, unsigned flags) { + struct nv40_render_stage *rs = nv40_render_stage(draw); + struct nv40_context *nv40 = rs->nv40; + + if (rs->prim != NV40TCL_BEGIN_END_STOP) { + BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); + OUT_RING (NV40TCL_BEGIN_END_STOP); + rs->prim = NV40TCL_BEGIN_END_STOP; + } } static void -nv40_draw_reset_stipple_counter(struct draw_stage *draw) +nv40_render_reset_stipple_counter(struct draw_stage *draw) { - NOUVEAU_ERR("\n"); } static void -nv40_draw_destroy(struct draw_stage *draw) +nv40_render_destroy(struct draw_stage *draw) { free(draw); } +static INLINE void +emit_mov(struct nv40_vertex_program *vp, + unsigned dst, unsigned src, unsigned vor, unsigned mask) +{ + struct nv40_vertex_program_exec *inst; + + vp->insns = realloc(vp->insns, + sizeof(struct nv40_vertex_program_exec) * + ++vp->nr_insns); + inst = &vp->insns[vp->nr_insns - 1]; + + inst->data[0] = 0x401f9c6c; + inst->data[1] = 0x0040000d | (src << 8); + inst->data[2] = 0x8106c083; + inst->data[3] = 0x6041ff80 | (dst << 2) | (mask << 13); + inst->const_index = -1; + inst->has_branch_offset = FALSE; + + vp->ir |= (1 << src); + if (vor != ~0) + vp->or |= (1 << vor); +} + +static struct nv40_vertex_program * +create_drawvp(struct nv40_context *nv40) +{ + struct nv40_vertex_program *vp = CALLOC_STRUCT(nv40_vertex_program); + unsigned i; + + emit_mov(vp, NV40_VP_INST_DEST_POS, 0, ~0, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_COL0, 3, 0, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_COL1, 4, 1, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_BFC0, 3, 2, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_BFC1, 4, 3, 0xf); + emit_mov(vp, NV40_VP_INST_DEST_FOGC, 5, 4, 0x8); + for (i = 0; i < 8; i++) + emit_mov(vp, NV40_VP_INST_DEST_TC(i), 8 + i, 14 + i, 0xf); + + vp->insns[vp->nr_insns - 1].data[3] |= 1; + vp->translated = TRUE; + return vp; +} + struct draw_stage * nv40_draw_render_stage(struct nv40_context *nv40) { - struct nv40_draw_stage *nv40draw = CALLOC_STRUCT(nv40_draw_stage); + struct nv40_render_stage *render = CALLOC_STRUCT(nv40_render_stage); + + if (!nv40->swtnl.vertprog) + nv40->swtnl.vertprog = create_drawvp(nv40); + + render->nv40 = nv40; + render->stage.draw = nv40->draw; + render->stage.point = nv40_render_point; + render->stage.line = nv40_render_line; + render->stage.tri = nv40_render_tri; + render->stage.flush = nv40_render_flush; + render->stage.reset_stipple_counter = nv40_render_reset_stipple_counter; + render->stage.destroy = nv40_render_destroy; + + return &render->stage; +} + +boolean +nv40_draw_elements_swtnl(struct pipe_context *pipe, + struct pipe_buffer *idxbuf, unsigned idxbuf_size, + unsigned mode, unsigned start, unsigned count) +{ + struct nv40_context *nv40 = nv40_context(pipe); + struct pipe_winsys *ws = pipe->winsys; + unsigned i; + void *map; + + if (!nv40_state_validate_swtnl(nv40)) + return FALSE; + nv40_state_emit(nv40); - nv40draw->nv40 = nv40; - nv40draw->draw.draw = nv40->draw; - nv40draw->draw.point = nv40_draw_point; - nv40draw->draw.line = nv40_draw_line; - nv40draw->draw.tri = nv40_draw_tri; - nv40draw->draw.flush = nv40_draw_flush; - nv40draw->draw.reset_stipple_counter = nv40_draw_reset_stipple_counter; - nv40draw->draw.destroy = nv40_draw_destroy; + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (!nv40->vtxbuf[i].buffer) + continue; + map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(nv40->draw, i, map); + } - return &nv40draw->draw; + if (idxbuf) { + map = ws->buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(nv40->draw, idxbuf_size, map); + } else { + draw_set_mapped_element_buffer(nv40->draw, 0, NULL); + } + + if (nv40->constbuf[PIPE_SHADER_VERTEX]) { + map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX], + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_constant_buffer(nv40->draw, map); + } + + draw_arrays(nv40->draw, mode, start, count); + + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (!nv40->vtxbuf[i].buffer) + continue; + ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer); + } + + if (idxbuf) + ws->buffer_unmap(ws, idxbuf); + + if (nv40->constbuf[PIPE_SHADER_VERTEX]) + ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]); + + draw_flush(nv40->draw); + pipe->flush(pipe, 0); + + return TRUE; } +static INLINE void +emit_attrib(struct nv40_context *nv40, unsigned hw, unsigned emit, + unsigned semantic, unsigned index) +{ + unsigned draw_out = draw_find_vs_output(nv40->draw, semantic, index); + unsigned a = nv40->swtnl.nr_attribs++; + + nv40->swtnl.hw[a] = hw; + nv40->swtnl.emit[a] = emit; + nv40->swtnl.draw[a] = draw_out; +} + +static boolean +nv40_state_vtxfmt_validate(struct nv40_context *nv40) +{ + struct nv40_fragment_program *fp = nv40->fragprog; + unsigned colour = 0, texcoords = 0, fog = 0, i; + + /* Determine needed fragprog inputs */ + for (i = 0; i < fp->info.num_inputs; i++) { + switch (fp->info.input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + break; + case TGSI_SEMANTIC_COLOR: + colour |= (1 << fp->info.input_semantic_index[i]); + break; + case TGSI_SEMANTIC_GENERIC: + texcoords |= (1 << fp->info.input_semantic_index[i]); + break; + case TGSI_SEMANTIC_FOG: + fog = 1; + break; + default: + assert(0); + } + } + + nv40->swtnl.nr_attribs = 0; + + /* Map draw vtxprog output to hw attribute IDs */ + for (i = 0; i < 2; i++) { + if (!(colour & (1 << i))) + continue; + emit_attrib(nv40, 3 + i, EMIT_4UB, TGSI_SEMANTIC_COLOR, i); + } + + for (i = 0; i < 8; i++) { + if (!(texcoords & (1 << i))) + continue; + emit_attrib(nv40, 8 + i, EMIT_4F, TGSI_SEMANTIC_GENERIC, i); + } + + if (fog) { + emit_attrib(nv40, 5, EMIT_1F, TGSI_SEMANTIC_FOG, 0); + } + + emit_attrib(nv40, 0, EMIT_4F, TGSI_SEMANTIC_POSITION, 0); + + return FALSE; +} + +struct nv40_state_entry nv40_state_vtxfmt = { + .validate = nv40_state_vtxfmt_validate, + .dirty = { + .pipe = NV40_NEW_ARRAYS | NV40_NEW_FRAGPROG, + .hw = 0 + } +}; + diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c index 953f9cd908..82dbcd3eef 100644 --- a/src/gallium/drivers/nv40/nv40_fragprog.c +++ b/src/gallium/drivers/nv40/nv40_fragprog.c @@ -797,9 +797,10 @@ nv40_fragprog_validate(struct nv40_context *nv40) if (fp->translated) goto update_constants; + nv40->fallback_swrast &= ~NV40_NEW_FRAGPROG; nv40_fragprog_translate(nv40, fp); if (!fp->translated) { - nv40->fallback |= NV40_FALLBACK_RAST; + nv40->fallback_swrast |= NV40_NEW_FRAGPROG; return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_shader.h b/src/gallium/drivers/nv40/nv40_shader.h index 5909c70713..854dccf548 100644 --- a/src/gallium/drivers/nv40/nv40_shader.h +++ b/src/gallium/drivers/nv40/nv40_shader.h @@ -476,6 +476,7 @@ # define NV40_FP_SWIZZLE_W 3 #define NV40_FP_REG_NEGATE (1 << 17) +#ifndef NV40_SHADER_NO_FUCKEDNESS #define NV40SR_NONE 0 #define NV40SR_OUTPUT 1 #define NV40SR_INPUT 2 @@ -550,5 +551,6 @@ nv40_sr_scale(struct nv40_sreg src, int scale) src.dst_scale = scale; return src; } +#endif #endif diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 321d5de041..3eafbece30 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -3,6 +3,8 @@ #include "pipe/p_util.h" #include "pipe/p_inlines.h" +#include "draw/draw_context.h" + #include "nv40_context.h" #include "nv40_state.h" @@ -345,7 +347,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: - so_data(so, 0); + so_data(so, NV40TCL_CULL_FACE_BACK); break; } so_data(so, NV40TCL_FRONT_FACE_CCW); @@ -363,13 +365,13 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: - so_data(so, 0); + so_data(so, NV40TCL_CULL_FACE_BACK); break; } so_data(so, NV40TCL_FRONT_FACE_CW); } so_data(so, cso->poly_smooth ? 1 : 0); - so_data(so, cso->cull_mode != PIPE_WINDING_NONE ? 1 : 0); + so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); @@ -419,6 +421,9 @@ static void nv40_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_rasterizer_state *rsso = hwcso; + + draw_set_rasterizer_state(nv40->draw, &rsso->pipe); nv40->rasterizer = hwcso; nv40->dirty |= NV40_NEW_RAST; @@ -508,10 +513,12 @@ static void * nv40_vp_state_create(struct pipe_context *pipe, const struct pipe_shader_state *cso) { + struct nv40_context *nv40 = nv40_context(pipe); struct nv40_vertex_program *vp; vp = CALLOC(1, sizeof(struct nv40_vertex_program)); vp->pipe = *cso; + vp->draw = draw_create_vertex_shader(nv40->draw, &vp->pipe); return (void *)vp; } @@ -520,6 +527,9 @@ static void nv40_vp_state_bind(struct pipe_context *pipe, void *hwcso) { struct nv40_context *nv40 = nv40_context(pipe); + struct nv40_vertex_program *vp = hwcso; + + draw_bind_vertex_shader(nv40->draw, vp ? vp->draw : NULL); nv40->vertprog = hwcso; nv40->dirty |= NV40_NEW_VERTPROG; @@ -531,6 +541,7 @@ nv40_vp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv40_context *nv40 = nv40_context(pipe); struct nv40_vertex_program *vp = hwcso; + draw_delete_vertex_shader(nv40->draw, vp->draw); nv40_vertprog_destroy(nv40, vp); FREE(vp); } @@ -544,6 +555,8 @@ nv40_fp_state_create(struct pipe_context *pipe, fp = CALLOC(1, sizeof(struct nv40_fragment_program)); fp->pipe = *cso; + tgsi_scan_shader(fp->pipe.tokens, &fp->info); + return (void *)fp; } @@ -582,6 +595,8 @@ nv40_set_clip_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_clip_state(nv40->draw, clip); + nv40->clip = *clip; nv40->dirty |= NV40_NEW_UCP; } @@ -638,6 +653,8 @@ nv40_set_viewport_state(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_viewport_state(nv40->draw, vpt); + nv40->viewport = *vpt; nv40->dirty |= NV40_NEW_VIEWPORT; } @@ -648,6 +665,8 @@ nv40_set_vertex_buffer(struct pipe_context *pipe, unsigned index, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_vertex_buffer(nv40->draw, index, vb); + nv40->vtxbuf[index] = *vb; nv40->dirty |= NV40_NEW_ARRAYS; } @@ -658,6 +677,8 @@ nv40_set_vertex_element(struct pipe_context *pipe, unsigned index, { struct nv40_context *nv40 = nv40_context(pipe); + draw_set_vertex_element(nv40->draw, index, ve); + nv40->vtxelt[index] = *ve; nv40->dirty |= NV40_NEW_ARRAYS; } diff --git a/src/gallium/drivers/nv40/nv40_state.h b/src/gallium/drivers/nv40/nv40_state.h index a02ea0c878..ab2866eb7a 100644 --- a/src/gallium/drivers/nv40/nv40_state.h +++ b/src/gallium/drivers/nv40/nv40_state.h @@ -2,6 +2,7 @@ #define __NV40_STATE_H__ #include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" struct nv40_sampler_state { uint32_t fmt; @@ -25,6 +26,8 @@ struct nv40_vertex_program_data { struct nv40_vertex_program { struct pipe_shader_state pipe; + struct draw_vertex_shader *draw; + boolean translated; struct nv40_vertex_program_exec *insns; unsigned nr_insns; @@ -49,6 +52,7 @@ struct nv40_fragment_program_data { struct nv40_fragment_program { struct pipe_shader_state pipe; + struct tgsi_shader_info info; boolean translated; unsigned samplers; diff --git a/src/gallium/drivers/nv40/nv40_state_clip.c b/src/gallium/drivers/nv40/nv40_state_clip.c index 93e690161f..c52390f9ed 100644 --- a/src/gallium/drivers/nv40/nv40_state_clip.c +++ b/src/gallium/drivers/nv40/nv40_state_clip.c @@ -3,8 +3,12 @@ static boolean nv40_state_clip_validate(struct nv40_context *nv40) { - if (nv40->clip.nr) - nv40->fallback |= NV40_FALLBACK_TNL; + + if (nv40->render_mode == HW) { + nv40->fallback_swtnl &= ~NV40_NEW_UCP; + if (nv40->clip.nr) + nv40->fallback_swtnl |= NV40_NEW_UCP; + } return FALSE; } diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 9f268640e0..056238cc83 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -1,5 +1,6 @@ #include "nv40_context.h" #include "nv40_state.h" +#include "draw/draw_context.h" static struct nv40_state_entry *render_states[] = { &nv40_state_framebuffer, @@ -18,15 +19,27 @@ static struct nv40_state_entry *render_states[] = { NULL }; +static struct nv40_state_entry *swtnl_states[] = { + &nv40_state_framebuffer, + &nv40_state_rasterizer, + &nv40_state_clip, + &nv40_state_scissor, + &nv40_state_stipple, + &nv40_state_fragprog, + &nv40_state_fragtex, + &nv40_state_vertprog, + &nv40_state_blend, + &nv40_state_blend_colour, + &nv40_state_zsa, + &nv40_state_viewport, + &nv40_state_vtxfmt, + NULL +}; + static void -nv40_state_validate(struct nv40_context *nv40) +nv40_state_do_validate(struct nv40_context *nv40, + struct nv40_state_entry **states) { - struct nv40_state_entry **states = render_states; - unsigned last_fallback; - - last_fallback = nv40->fallback; - nv40->fallback = 0; - while (*states) { struct nv40_state_entry *e = *states; @@ -38,32 +51,15 @@ nv40_state_validate(struct nv40_context *nv40) states++; } nv40->dirty = 0; - - if (nv40->fallback & NV40_FALLBACK_TNL && - !(last_fallback & NV40_FALLBACK_TNL)) { - NOUVEAU_ERR("XXX: hwtnl->swtnl\n"); - } else - if (last_fallback & NV40_FALLBACK_TNL && - !(nv40->fallback & NV40_FALLBACK_TNL)) { - NOUVEAU_ERR("XXX: swtnl->hwtnl\n"); - } - - if (nv40->fallback & NV40_FALLBACK_RAST && - !(last_fallback & NV40_FALLBACK_RAST)) { - NOUVEAU_ERR("XXX: hwrast->swrast\n"); - } else - if (last_fallback & NV40_FALLBACK_RAST && - !(nv40->fallback & NV40_FALLBACK_RAST)) { - NOUVEAU_ERR("XXX: swrast->hwrast\n"); - } } -static void +void nv40_state_emit(struct nv40_context *nv40) { struct nv40_state *state = &nv40->state; struct nv40_screen *screen = nv40->screen; unsigned i, samplers; + uint64 states; if (nv40->pctx_id != screen->cur_pctx) { for (i = 0; i < NV40_STATE_MAX; i++) { @@ -74,14 +70,24 @@ nv40_state_emit(struct nv40_context *nv40) screen->cur_pctx = nv40->pctx_id; } - while (state->dirty) { - unsigned idx = ffsll(state->dirty) - 1; + for (i = 0, states = state->dirty; states; i++) { + if (!(states & (1ULL << i))) + continue; + so_ref (state->hw[i], &nv40->screen->state[i]); + so_emit(nv40->nvws, nv40->screen->state[i]); + states &= ~(1ULL << i); + } - so_ref (state->hw[idx], &nv40->screen->state[idx]); - so_emit(nv40->nvws, nv40->screen->state[idx]); - state->dirty &= ~(1ULL << idx); + if (state->dirty & ((1ULL << NV40_STATE_FRAGPROG) | + (1ULL << NV40_STATE_FRAGTEX0))) { + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (2); + BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); + OUT_RING (1); } + state->dirty = 0; + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]); for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) { if (!(samplers & (1 << i))) @@ -91,18 +97,62 @@ nv40_state_emit(struct nv40_context *nv40) samplers &= ~(1ULL << i); } so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]); - so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); + if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW) + so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]); } -void -nv40_emit_hw_state(struct nv40_context *nv40) +boolean +nv40_state_validate(struct nv40_context *nv40) { - nv40_state_validate(nv40); - nv40_state_emit(nv40); + boolean was_sw = nv40->fallback_swtnl ? TRUE : FALSE; + + if (nv40->render_mode != HW) { + /* Don't even bother trying to go back to hw if none + * of the states that caused swtnl previously have changed. + */ + if ((nv40->fallback_swtnl & nv40->dirty) + != nv40->fallback_swtnl) + return FALSE; + + /* Attempt to go to hwtnl again */ + nv40->pipe.flush(&nv40->pipe, 0); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS | + NV40_NEW_UCP); + nv40->render_mode = HW; + } + + nv40_state_do_validate(nv40, render_states); + if (nv40->fallback_swtnl || nv40->fallback_swrast) + return FALSE; + + if (was_sw) + NOUVEAU_ERR("swtnl->hw\n"); + + return TRUE; +} + +boolean +nv40_state_validate_swtnl(struct nv40_context *nv40) +{ + /* Setup for swtnl */ + if (nv40->render_mode == HW) { + NOUVEAU_ERR("hw->swtnl 0x%08x\n", nv40->fallback_swtnl); + nv40->pipe.flush(&nv40->pipe, 0); + nv40->dirty |= (NV40_NEW_VIEWPORT | + NV40_NEW_VERTPROG | + NV40_NEW_ARRAYS | + NV40_NEW_UCP); + nv40->render_mode = SWTNL; + } + + nv40_state_do_validate(nv40, swtnl_states); + if (nv40->fallback_swrast) { + NOUVEAU_ERR("swtnl->swrast 0x%08x\n", nv40->fallback_swrast); + return FALSE; + } - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (2); - BEGIN_RING(curie, NV40TCL_TEX_CACHE_CTL, 1); - OUT_RING (1); + return TRUE; } diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 3a32533907..9e5c7a72a7 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -3,18 +3,43 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { - struct nouveau_stateobj *so = so_new(9, 0); + struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; - so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); - so_data (so, fui(vpt->translate[0])); - so_data (so, fui(vpt->translate[1])); - so_data (so, fui(vpt->translate[2])); - so_data (so, fui(vpt->translate[3])); - so_data (so, fui(vpt->scale[0])); - so_data (so, fui(vpt->scale[1])); - so_data (so, fui(vpt->scale[2])); - so_data (so, fui(vpt->scale[3])); + if (nv40->render_mode == HW) { + so_method(so, nv40->screen->curie, + NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(vpt->translate[0])); + so_data (so, fui(vpt->translate[1])); + so_data (so, fui(vpt->translate[2])); + so_data (so, fui(vpt->translate[3])); + so_data (so, fui(vpt->scale[0])); + so_data (so, fui(vpt->scale[1])); + so_data (so, fui(vpt->scale[2])); + so_data (so, fui(vpt->scale[3])); + so_method(so, nv40->screen->curie, 0x1d78, 1); + so_data (so, 1); + } else { + so_method(so, nv40->screen->curie, + NV40TCL_VIEWPORT_TRANSLATE_X, 8); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(0.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(1.0)); + so_data (so, fui(0.0)); + /* Not entirely certain what this is yet. The DDX uses this + * value also as it fixes rendering when you pass + * pre-transformed vertices to the GPU. My best gusss is that + * this bypasses some culling/clipping stage. Might be worth + * noting that points/lines are uneffected by whatever this + * value fixes, only filled polygons are effected. + */ + so_method(so, nv40->screen->curie, 0x1d78, 1); + so_data (so, 0x110); + } so_ref(so, &nv40->state.hw[NV40_STATE_VIEWPORT]); return TRUE; diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index f16afc23b8..fad423fdf8 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -8,6 +8,8 @@ #include "nouveau/nouveau_channel.h" #include "nouveau/nouveau_pushbuf.h" +#define FORCE_SWTNL 0 + static INLINE int nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) { @@ -165,7 +167,11 @@ nv40_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned nr; nv40_vbo_set_idxbuf(nv40, NULL, 0); - nv40_emit_hw_state(nv40); + if (FORCE_SWTNL || !nv40_state_validate(nv40)) { + return nv40_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count); + } + nv40_state_emit(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -274,7 +280,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe, struct pipe_winsys *ws = pipe->winsys; void *map; - nv40_emit_hw_state(nv40); + nv40_state_emit(nv40); map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ); if (!ib) { @@ -315,7 +321,7 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, struct nv40_context *nv40 = nv40_context(pipe); unsigned nr; - nv40_emit_hw_state(nv40); + nv40_state_emit(nv40); BEGIN_RING(curie, NV40TCL_BEGIN_END, 1); OUT_RING (nvgl_primitive(mode)); @@ -352,8 +358,16 @@ nv40_draw_elements(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { struct nv40_context *nv40 = nv40_context(pipe); + boolean idxbuf; + + idxbuf = nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize); + if (FORCE_SWTNL || !nv40_state_validate(nv40)) { + return nv40_draw_elements_swtnl(pipe, NULL, 0, + mode, start, count); + } + nv40_state_emit(nv40); - if (nv40_vbo_set_idxbuf(nv40, indexBuffer, indexSize)) { + if (idxbuf) { nv40_draw_elements_vbo(pipe, mode, start, count); } else { nv40_draw_elements_inline(pipe, indexBuffer, indexSize, diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index 3d730c1a32..9f1ee575ce 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -634,21 +634,29 @@ out_err: static boolean nv40_vertprog_validate(struct nv40_context *nv40) { - struct nv40_vertex_program *vp = nv40->vertprog; - struct pipe_buffer *constbuf = - nv40->constbuf[PIPE_SHADER_VERTEX]; struct nouveau_winsys *nvws = nv40->nvws; struct pipe_winsys *ws = nv40->pipe.winsys; + struct nv40_vertex_program *vp; + struct pipe_buffer *constbuf; boolean upload_code = FALSE, upload_data = FALSE; int i; + if (nv40->render_mode == HW) { + vp = nv40->vertprog; + constbuf = nv40->constbuf[PIPE_SHADER_VERTEX]; + } else { + vp = nv40->swtnl.vertprog; + constbuf = NULL; + } + /* Translate TGSI shader into hw bytecode */ if (vp->translated) goto check_gpu_resources; + nv40->fallback_swtnl &= ~NV40_NEW_VERTPROG; nv40_vertprog_translate(nv40, vp); if (!vp->translated) { - nv40->fallback |= NV40_FALLBACK_TNL; + nv40->fallback_swtnl |= NV40_NEW_VERTPROG; return FALSE; } -- cgit v1.2.3 From 799d3bce06e998e51ad8df6bcadeb41bd061801e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 24 Mar 2008 13:41:40 +1100 Subject: nv40: respect rasterizer cso bypass_clipping flag --- src/gallium/drivers/nv40/nv40_context.h | 1 + src/gallium/drivers/nv40/nv40_state_viewport.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'src/gallium/drivers/nv40/nv40_state_viewport.c') diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 02ca20b801..b50f6f8fef 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -97,6 +97,7 @@ struct nv40_blend_state { struct nv40_state { unsigned scissor_enabled; unsigned stipple_enabled; + unsigned viewport_bypass; unsigned fp_samplers; uint64_t dirty; diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 9e5c7a72a7..1b6248e5b8 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -5,8 +5,20 @@ nv40_state_viewport_validate(struct nv40_context *nv40) { struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; + unsigned bypass; - if (nv40->render_mode == HW) { + if (nv40->render_mode == HW && !nv40->rasterizer->pipe.bypass_clipping) + bypass = 0; + else + bypass = 1; + + if (nv40->state.hw[NV40_STATE_VIEWPORT] && + (bypass || !(nv40->dirty & NV40_NEW_VIEWPORT)) && + nv40->state.viewport_bypass == bypass) + return FALSE; + nv40->state.viewport_bypass = bypass; + + if (!bypass) { so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); so_data (so, fui(vpt->translate[0])); @@ -48,7 +60,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) struct nv40_state_entry nv40_state_viewport = { .validate = nv40_state_viewport_validate, .dirty = { - .pipe = NV40_NEW_VIEWPORT, + .pipe = NV40_NEW_VIEWPORT | NV40_NEW_RAST, .hw = NV40_STATE_VIEWPORT } }; -- cgit v1.2.3 From 996b549fdbfe772ee56a51858e81e93bccaae5c5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 30 May 2008 11:04:55 +1000 Subject: nv40: a couple of memory leaks --- src/gallium/drivers/nv40/nv40_state_viewport.c | 3 ++- src/gallium/drivers/nv40/nv40_vertprog.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/nv40/nv40_state_viewport.c') diff --git a/src/gallium/drivers/nv40/nv40_state_viewport.c b/src/gallium/drivers/nv40/nv40_state_viewport.c index 1b6248e5b8..869a55b405 100644 --- a/src/gallium/drivers/nv40/nv40_state_viewport.c +++ b/src/gallium/drivers/nv40/nv40_state_viewport.c @@ -3,8 +3,8 @@ static boolean nv40_state_viewport_validate(struct nv40_context *nv40) { - struct nouveau_stateobj *so = so_new(11, 0); struct pipe_viewport_state *vpt = &nv40->viewport; + struct nouveau_stateobj *so; unsigned bypass; if (nv40->render_mode == HW && !nv40->rasterizer->pipe.bypass_clipping) @@ -18,6 +18,7 @@ nv40_state_viewport_validate(struct nv40_context *nv40) return FALSE; nv40->state.viewport_bypass = bypass; + so = so_new(11, 0); if (!bypass) { so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_TRANSLATE_X, 8); diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c index e10250528e..eb14869bfe 100644 --- a/src/gallium/drivers/nv40/nv40_vertprog.c +++ b/src/gallium/drivers/nv40/nv40_vertprog.c @@ -843,6 +843,12 @@ nv40_vertprog_translate(struct nv40_context *nv40, vp->translated = TRUE; out_err: tgsi_parse_free(&parse); + if (vpc->r_temp) + FREE(vpc->r_temp); + if (vpc->r_address) + FREE(vpc->r_address); + if (vpc->imm) + FREE(vpc->imm); FREE(vpc); } -- cgit v1.2.3