diff options
Diffstat (limited to 'src/gallium/drivers/nv10')
-rw-r--r-- | src/gallium/drivers/nv10/nv10_context.c | 92 | ||||
-rw-r--r-- | src/gallium/drivers/nv10/nv10_context.h | 31 | ||||
-rw-r--r-- | src/gallium/drivers/nv10/nv10_miptree.c | 28 | ||||
-rw-r--r-- | src/gallium/drivers/nv10/nv10_prim_vbuf.c | 17 | ||||
-rw-r--r-- | src/gallium/drivers/nv10/nv10_screen.c | 70 | ||||
-rw-r--r-- | src/gallium/drivers/nv10/nv10_screen.h | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nv10/nv10_state.c | 155 | ||||
-rw-r--r-- | src/gallium/drivers/nv10/nv10_state_emit.c | 216 |
8 files changed, 377 insertions, 238 deletions
diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c index 14042fb2fbb..42c496b9590 100644 --- a/src/gallium/drivers/nv10/nv10_context.c +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -12,13 +12,6 @@ nv10_flush(struct pipe_context *pipe, unsigned flags, { struct nv10_context *nv10 = nv10_context(pipe); - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - BEGIN_RING(celsius, 0x1fd8, 1); - OUT_RING (2); - BEGIN_RING(celsius, 0x1fd8, 1); - OUT_RING (1); - } - FIRE_RING(fence); } @@ -26,36 +19,21 @@ static void nv10_destroy(struct pipe_context *pipe) { struct nv10_context *nv10 = nv10_context(pipe); - struct nouveau_winsys *nvws = nv10->nvws; if (nv10->draw) draw_destroy(nv10->draw); - nvws->res_free(&nv10->vertprog.exec_heap); - nvws->res_free(&nv10->vertprog.data_heap); - - nvws->notifier_free(&nv10->sync); - - nvws->grobj_free(&nv10->celsius); - - free(nv10); + FREE(nv10); } -static boolean -nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) +static void nv10_init_hwctx(struct nv10_context *nv10) { - struct nouveau_winsys *nvws = nv10->nvws; - int ret; + struct nv10_screen *screen = nv10->screen; + struct nouveau_winsys *nvws = screen->nvws; int i; - ret = nvws->grobj_alloc(nvws, celsius_class, &nv10->celsius); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1); - OUT_RING (nv10->sync->handle); + OUT_RING (screen->sync->handle); BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2); OUT_RING (nvws->channel->vram->handle); OUT_RING (nvws->channel->gart->handle); @@ -90,7 +68,7 @@ nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) BEGIN_RING(celsius, NV10TCL_NOP, 1); OUT_RING (0); - if (celsius_class != NV10TCL) { + if (nv10->screen->celsius->grclass != NV10TCL) { /* For nv11, nv17 */ BEGIN_RING(celsius, 0x120, 3); OUT_RING (0); @@ -243,72 +221,44 @@ nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) FIRE_RING (NULL); - return TRUE; } struct pipe_context * -nv10_create(struct pipe_screen *screen, unsigned pctx_id) +nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) { - struct pipe_winsys *pipe_winsys = screen->winsys; - struct nouveau_winsys *nvws = nv10_screen(screen)->nvws; - unsigned chipset = nv10_screen(screen)->chipset; + struct nv10_screen *screen = nv10_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; struct nv10_context *nv10; - int celsius_class = 0, ret; - - if (chipset>=0x20) - celsius_class=NV11TCL; - else if (chipset>=0x17) - celsius_class=NV17TCL; - else if (chipset>=0x11) - celsius_class=NV11TCL; - else - celsius_class=NV10TCL; - - nv10 = CALLOC_STRUCT(nv10_context); + unsigned chipset = screen->chipset; + struct nouveau_winsys *nvws = screen->nvws; + + nv10 = CALLOC(1, sizeof(struct nv10_context)); if (!nv10) return NULL; + nv10->screen = screen; + nv10->pctx_id = pctx_id; + nv10->chipset = chipset; nv10->nvws = nvws; - /* Notifier for sync purposes */ - ret = nvws->notifier_alloc(nvws, 1, &nv10->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv10_destroy(&nv10->pipe); - return NULL; - } - - /* Vtxprog resources */ - if (nvws->res_init(&nv10->vertprog.exec_heap, 0, 512) || - nvws->res_init(&nv10->vertprog.data_heap, 0, 256)) { - nv10_destroy(&nv10->pipe); - return NULL; - } - - /* Static celsius initialisation */ - if (!nv10_init_hwctx(nv10, celsius_class)) { - nv10_destroy(&nv10->pipe); - return NULL; - } - - /* Pipe context setup */ - nv10->pipe.winsys = pipe_winsys; - + nv10->pipe.winsys = ws; + nv10->pipe.screen = pscreen; nv10->pipe.destroy = nv10_destroy; - nv10->pipe.draw_arrays = nv10_draw_arrays; nv10->pipe.draw_elements = nv10_draw_elements; nv10->pipe.clear = nv10_clear; - nv10->pipe.flush = nv10_flush; nv10_init_surface_functions(nv10); nv10_init_state_functions(nv10); + nv10_init_miptree_functions(nv10); nv10->draw = draw_create(); assert(nv10->draw); draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10)); + nv10_init_hwctx(nv10); + return &nv10->pipe; } diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h index 386138556e5..61eb4e6a937 100644 --- a/src/gallium/drivers/nv10/nv10_context.h +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -11,7 +11,7 @@ #include "nouveau/nouveau_gldefs.h" #define NOUVEAU_PUSH_CONTEXT(ctx) \ - struct nv10_context *ctx = nv10 + struct nv10_screen *ctx = nv10->screen #include "nouveau/nouveau_push.h" #include "nv10_state.h" @@ -24,17 +24,27 @@ #define NV10_NEW_VERTPROG (1 << 1) #define NV10_NEW_FRAGPROG (1 << 2) #define NV10_NEW_ARRAYS (1 << 3) -#define NV10_NEW_VBO (1 << 4) +#define NV10_NEW_VTXFMT (1 << 4) +#define NV10_NEW_BLEND (1 << 5) +#define NV10_NEW_BLENDCOL (1 << 6) +#define NV10_NEW_RAST (1 << 7) +#define NV10_NEW_DSA (1 << 8) +#define NV10_NEW_VIEWPORT (1 << 9) +#define NV10_NEW_SCISSOR (1 << 9) +#define NV10_NEW_FRAMEBUFFER (1 << 10) + +#include "nv10_screen.h" struct nv10_context { struct pipe_context pipe; + struct nouveau_winsys *nvws; + struct nv10_screen *screen; + unsigned pctx_id; struct draw_context *draw; int chipset; - struct nouveau_grobj *celsius; - struct nouveau_notifier *sync; uint32_t dirty; @@ -49,6 +59,14 @@ struct nv10_context { struct pipe_buffer *zeta; uint32_t lma_offset; + struct nv10_blend_state *blend; + struct pipe_blend_color *blend_color; + struct nv10_rasterizer_state *rast; + struct nv10_depth_stencil_alpha_state *dsa; + struct pipe_viewport_state *viewport; + struct pipe_scissor_state *scissor; + struct pipe_framebuffer_state *framebuffer; + struct { struct pipe_buffer *buffer; uint32_t format; @@ -91,7 +109,9 @@ nv10_context(struct pipe_context *pipe) extern void nv10_init_state_functions(struct nv10_context *nv10); extern void nv10_init_surface_functions(struct nv10_context *nv10); -extern void nv10_init_miptree_functions(struct pipe_screen *screen); +extern void nv10_init_miptree_functions(struct nv10_context *nv10); + +extern void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen); /* nv10_clear.c */ extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, @@ -111,6 +131,7 @@ extern void nv10_fragtex_bind(struct nv10_context *); /* nv10_prim_vbuf.c */ struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ); +extern void nv10_vtxbuf_bind(struct nv10_context* nv10); /* nv10_state.c and friends */ extern void nv10_emit_hw_state(struct nv10_context *nv10); diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c index 7b7f39b80c9..4dfc675a6b9 100644 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -69,7 +69,7 @@ nv10_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt) mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, mt->total_size); if (!mt->buffer) { - free(mt); + FREE(mt); return NULL; } @@ -90,12 +90,19 @@ nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) pipe_buffer_reference(ws, &nv10mt->buffer, NULL); for (l = 0; l <= mt->last_level; l++) { if (nv10mt->level[l].image_offset) - free(nv10mt->level[l].image_offset); + FREE(nv10mt->level[l].image_offset); } - free(nv10mt); + FREE(nv10mt); } } +static void +nv10_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, + uint face, uint levels) +{ +} + + static struct pipe_surface * nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, unsigned face, unsigned level, unsigned zslice) @@ -122,13 +129,16 @@ nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, return ps; } -void -nv10_init_miptree_functions(struct pipe_screen *screen) + +void nv10_init_miptree_functions(struct nv10_context *nv10) { - struct nv10_screen *nv10screen = nv10_screen(screen); + nv10->pipe.texture_update = nv10_miptree_update; +} - nv10screen->screen.texture_create = nv10_miptree_create; - nv10screen->screen.texture_release = nv10_miptree_release; - nv10screen->screen.get_tex_surface = nv10_miptree_surface_get; +void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv10_miptree_create; + pscreen->texture_release = nv10_miptree_release; + pscreen->get_tex_surface = nv10_miptree_surface_get; } diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c index 15268912234..bbcfe1a2fdd 100644 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -67,6 +67,17 @@ struct nv10_vbuf_render { }; +void nv10_vtxbuf_bind( struct nv10_context* nv10 ) +{ + int i; + for(i = 0; i < 8; i++) { + BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_ATTRIB_OFFSET(i), 1); + OUT_RING(0/*nv10->vtxbuf*/); + BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_ATTRIB_FORMAT(i) ,1); + OUT_RING(0/*XXX*/); + } +} + /** * Basically a cast wrapper. */ @@ -100,7 +111,7 @@ nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, assert(!nv10_render->buffer); nv10_render->buffer = winsys->buffer_create(winsys, 64, PIPE_BUFFER_USAGE_VERTEX, size); - nv10->dirty |= NV10_NEW_VBO; + nv10->dirty |= NV10_NEW_ARRAYS; return winsys->buffer_map(winsys, nv10_render->buffer, @@ -139,8 +150,8 @@ nv10_vbuf_render_draw( struct vbuf_render *render, } while (nr_indices) { - // XXX too big ? - push = MIN2(nr_indices, 2047 * 2); + // XXX too big/small ? check the size + push = MIN2(nr_indices, 1200 * 2); BEGIN_RING_NI(celsius, NV10TCL_VB_ELEMENT_U16, push >> 1); for (i = 0; i < push; i+=2) diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c index 4d8e0b05ccd..80676ead1a9 100644 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -116,35 +116,71 @@ nv10_screen_is_format_supported(struct pipe_screen *screen, } static void -nv10_screen_destroy(struct pipe_screen *screen) +nv10_screen_destroy(struct pipe_screen *pscreen) { - FREE(screen); + struct nv10_screen *screen = nv10_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->celsius); + + FREE(pscreen); } struct pipe_screen * -nv10_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws, +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, unsigned chipset) { - struct nv10_screen *nv10screen = CALLOC_STRUCT(nv10_screen); + struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen); + unsigned celsius_class; + int ret; - if (!nv10screen) + if (!screen) + return NULL; + screen->chipset = chipset; + screen->nvws = nvws; + + /* 3D object */ + if (chipset>=0x20) + celsius_class=NV11TCL; + else if (chipset>=0x17) + celsius_class=NV17TCL; + else if (chipset>=0x11) + celsius_class=NV11TCL; + else + celsius_class=NV10TCL; + + if (!celsius_class) { + NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", chipset); return NULL; + } + + ret = nvws->grobj_alloc(nvws, celsius_class, &screen->celsius); + 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); + nv10_screen_destroy(&screen->pipe); + return NULL; + } - nv10screen->chipset = chipset; - nv10screen->nvws = nvws; + screen->pipe.winsys = ws; + screen->pipe.destroy = nv10_screen_destroy; - nv10screen->screen.winsys = winsys; + screen->pipe.get_name = nv10_screen_get_name; + screen->pipe.get_vendor = nv10_screen_get_vendor; + screen->pipe.get_param = nv10_screen_get_param; + screen->pipe.get_paramf = nv10_screen_get_paramf; - nv10screen->screen.destroy = nv10_screen_destroy; + screen->pipe.is_format_supported = nv10_screen_is_format_supported; - nv10screen->screen.get_name = nv10_screen_get_name; - nv10screen->screen.get_vendor = nv10_screen_get_vendor; - nv10screen->screen.get_param = nv10_screen_get_param; - nv10screen->screen.get_paramf = nv10_screen_get_paramf; - nv10screen->screen.is_format_supported = - nv10_screen_is_format_supported; + nv10_screen_init_miptree_functions(&screen->pipe); - nv10_init_miptree_functions(&nv10screen->screen); - return &nv10screen->screen; + return &screen->pipe; } diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h index ac8c04072ab..4192fe11ef4 100644 --- a/src/gallium/drivers/nv10/nv10_screen.h +++ b/src/gallium/drivers/nv10/nv10_screen.h @@ -4,10 +4,14 @@ #include "pipe/p_screen.h" struct nv10_screen { - struct pipe_screen screen; + struct pipe_screen pipe; struct nouveau_winsys *nvws; unsigned chipset; + + /* HW graphics objects */ + struct nouveau_grobj *celsius; + struct nouveau_notifier *sync; }; static INLINE struct nv10_screen * diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c index 1ff01de1060..12722709f6b 100644 --- a/src/gallium/drivers/nv10/nv10_state.c +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -35,6 +35,8 @@ static void nv10_vertex_layout(struct pipe_context* pipe) } } draw_compute_vertex_size(&vinfo); + + nv10->dirty |= NV10_NEW_VTXFMT; } static void * @@ -62,27 +64,19 @@ nv10_blend_state_create(struct pipe_context *pipe, } static void -nv10_blend_state_bind(struct pipe_context *pipe, void *hwcso) +nv10_blend_state_bind(struct pipe_context *pipe, void *blend) { struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_blend_state *cb = hwcso; - - BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1); - OUT_RING (cb->d_enable); - BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); - OUT_RING (cb->b_enable); - OUT_RING (cb->b_srcfunc); - OUT_RING (cb->b_dstfunc); + nv10->blend = (struct nv10_blend_state*)blend; - BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); - OUT_RING (cb->c_mask); + nv10->dirty |= NV10_NEW_BLEND; } static void nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } @@ -255,7 +249,7 @@ nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) static void nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void @@ -347,43 +341,19 @@ nv10_rasterizer_state_create(struct pipe_context *pipe, } static void -nv10_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +nv10_rasterizer_state_bind(struct pipe_context *pipe, void *rast) { struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_rasterizer_state *rs = hwcso; - - BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2); - OUT_RING (rs->shade_model); - OUT_RING (rs->line_width); - - - BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); - OUT_RING (rs->point_size); - - BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (rs->poly_mode_front); - OUT_RING (rs->poly_mode_back); - - BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); - OUT_RING (rs->cull_face); - OUT_RING (rs->front_face); + nv10->rast = (struct nv10_rasterizer_state*)rast; - BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); - OUT_RING (rs->line_smooth_en); - OUT_RING (rs->poly_smooth_en); - - BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); - OUT_RING (rs->cull_face_en); - -/* BEGIN_RING(celsius, NV10TCL_POINT_SPRITE, 1); - OUT_RING (rs->point_sprite);*/ + nv10->dirty |= NV10_NEW_RAST; } static void nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void * @@ -415,25 +385,19 @@ nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, } static void -nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa) { struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_depth_stencil_alpha_state *hw = hwcso; - - BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 3); - OUT_RINGp ((uint32_t *)&hw->depth, 3); - BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1); - OUT_RING (hw->stencil.enable); - BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7); - OUT_RINGp ((uint32_t *)&(hw->stencil.wmask), 7); - BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3); - OUT_RINGp ((uint32_t *)&hw->alpha.enabled, 3); + + nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa; + + nv10->dirty |= NV10_NEW_DSA; } static void nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) { - free(hwcso); + FREE(hwcso); } static void * @@ -461,11 +425,11 @@ nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso) static void nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso) { - struct nv10_context *nv10 = nv10_context(pipe); + //struct nv10_context *nv10 = nv10_context(pipe); struct nv10_vertex_program *vp = hwcso; //nv10_vertprog_destroy(nv10, vp); - free(vp); + FREE(vp); } static void * @@ -499,7 +463,7 @@ nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso) struct nv10_fragment_program *fp = hwcso; nv10_fragprog_destroy(nv10, fp); - free(fp); + FREE(fp); } static void @@ -508,11 +472,9 @@ nv10_set_blend_color(struct pipe_context *pipe, { struct nv10_context *nv10 = nv10_context(pipe); - BEGIN_RING(celsius, NV10TCL_BLEND_COLOR, 1); - OUT_RING ((float_to_ubyte(bcol->color[3]) << 24) | - (float_to_ubyte(bcol->color[0]) << 16) | - (float_to_ubyte(bcol->color[1]) << 8) | - (float_to_ubyte(bcol->color[2]) << 0)); + nv10->blend_color = (struct pipe_blend_color*)bcol; + + nv10->dirty |= NV10_NEW_BLENDCOL; } static void @@ -542,58 +504,10 @@ nv10_set_framebuffer_state(struct pipe_context *pipe, const struct pipe_framebuffer_state *fb) { struct nv10_context *nv10 = nv10_context(pipe); - struct pipe_surface *rt, *zeta; - uint32_t rt_format, w, h; - int i, colour_format = 0, zeta_format = 0; - - w = fb->cbufs[0]->width; - h = fb->cbufs[0]->height; - colour_format = fb->cbufs[0]->format; - rt = fb->cbufs[0]; - - if (fb->zsbuf) { - if (colour_format) { - assert(w == fb->zsbuf->width); - assert(h == fb->zsbuf->height); - } else { - w = fb->zsbuf->width; - h = fb->zsbuf->height; - } - - zeta_format = fb->zsbuf->format; - zeta = fb->zsbuf; - } - rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; + nv10->framebuffer = (struct pipe_framebuffer_state*)fb; - switch (colour_format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case 0: - rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8; - break; - case PIPE_FORMAT_R5G6B5_UNORM: - rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5; - break; - default: - assert(0); - } - - BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); - OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); - nv10->rt[0] = rt->buffer; - - if (zeta_format) - { - nv10->zeta = zeta->buffer; - } - - BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3); - OUT_RING ((w << 16) | 0); - OUT_RING ((h << 16) | 0); - OUT_RING (rt_format); - BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING (((w - 1) << 16) | 0); - OUT_RING (((h - 1) << 16) | 0); + nv10->dirty |= NV10_NEW_FRAMEBUFFER; } static void @@ -609,10 +523,9 @@ nv10_set_scissor_state(struct pipe_context *pipe, { struct nv10_context *nv10 = nv10_context(pipe); - // XXX -/* BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2); - OUT_RING (((s->maxx - s->minx) << 16) | s->minx); - OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ + nv10->scissor = (struct pipe_scissor_state*)s; + + nv10->dirty |= NV10_NEW_SCISSOR; } static void @@ -621,15 +534,9 @@ nv10_set_viewport_state(struct pipe_context *pipe, { struct nv10_context *nv10 = nv10_context(pipe); -/* OUT_RINGf (vpt->translate[0]); - OUT_RINGf (vpt->translate[1]); - OUT_RINGf (vpt->translate[2]); - OUT_RINGf (vpt->translate[3]);*/ - BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); - OUT_RINGf (vpt->scale[0]); - OUT_RINGf (vpt->scale[1]); - OUT_RINGf (vpt->scale[2]); - OUT_RINGf (vpt->scale[3]); + nv10->viewport = (struct pipe_viewport_state*)vpt; + + nv10->dirty |= NV10_NEW_VIEWPORT; } static void diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c index 8bf0bd2d683..0c524963896 100644 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -1,14 +1,174 @@ +#include "pipe/p_util.h" + #include "nv10_context.h" #include "nv10_state.h" +static void nv10_state_emit_blend(struct nv10_context* nv10) +{ + struct nv10_blend_state *b = nv10->blend; + + BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1); + OUT_RING (b->d_enable); + + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); + OUT_RING (b->b_enable); + OUT_RING (b->b_srcfunc); + OUT_RING (b->b_dstfunc); + + BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING (b->c_mask); +} + +static void nv10_state_emit_blend_color(struct nv10_context* nv10) +{ + struct pipe_blend_color *c = nv10->blend_color; + + BEGIN_RING(celsius, NV10TCL_BLEND_COLOR, 1); + OUT_RING ((float_to_ubyte(c->color[3]) << 24)| + (float_to_ubyte(c->color[0]) << 16)| + (float_to_ubyte(c->color[1]) << 8) | + (float_to_ubyte(c->color[2]) << 0)); +} + +static void nv10_state_emit_rast(struct nv10_context* nv10) +{ + struct nv10_rasterizer_state *r = nv10->rast; + + BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2); + OUT_RING (r->shade_model); + OUT_RING (r->line_width); + + + BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING (r->point_size); + + BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING (r->poly_mode_front); + OUT_RING (r->poly_mode_back); + + + BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); + OUT_RING (r->cull_face); + OUT_RING (r->front_face); + + BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); + OUT_RING (r->line_smooth_en); + OUT_RING (r->poly_smooth_en); + + BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING (r->cull_face_en); +} + +static void nv10_state_emit_dsa(struct nv10_context* nv10) +{ + struct nv10_depth_stencil_alpha_state *d = nv10->dsa; + + BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 3); + OUT_RINGp ((uint32_t *)&d->depth, 3); + BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1); + OUT_RING (d->stencil.enable); + BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7); + OUT_RINGp ((uint32_t *)&(d->stencil.wmask), 7); + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3); + OUT_RINGp ((uint32_t *)&d->alpha.enabled, 3); +} + +static void nv10_state_emit_viewport(struct nv10_context* nv10) +{ + struct pipe_viewport_state *vpt = nv10->viewport; + +/* OUT_RINGf (vpt->translate[0]); + OUT_RINGf (vpt->translate[1]); + OUT_RINGf (vpt->translate[2]); + OUT_RINGf (vpt->translate[3]);*/ + BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); + OUT_RINGf (vpt->scale[0]); + OUT_RINGf (vpt->scale[1]); + OUT_RINGf (vpt->scale[2]); + OUT_RINGf (vpt->scale[3]); +} + +static void nv10_state_emit_scissor(struct nv10_context* nv10) +{ + // XXX this is so not working +/* struct pipe_scissor_state *s = nv10->scissor; + BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2); + OUT_RING (((s->maxx - s->minx) << 16) | s->minx); + OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ +} + +static void nv10_state_emit_framebuffer(struct nv10_context* nv10) +{ + struct pipe_framebuffer_state* fb = nv10->framebuffer; + struct pipe_surface *rt, *zeta; + uint32_t rt_format, w, h; + int colour_format = 0, zeta_format = 0; + + w = fb->cbufs[0]->width; + h = fb->cbufs[0]->height; + colour_format = fb->cbufs[0]->format; + rt = fb->cbufs[0]; + + if (fb->zsbuf) { + if (colour_format) { + assert(w == fb->zsbuf->width); + assert(h == fb->zsbuf->height); + } else { + w = fb->zsbuf->width; + h = fb->zsbuf->height; + } + + zeta_format = fb->zsbuf->format; + zeta = fb->zsbuf; + } + + rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5; + break; + default: + assert(0); + } + + BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); + OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); + nv10->rt[0] = rt->buffer; + + if (zeta_format) + { + nv10->zeta = zeta->buffer; + } + + BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3); + OUT_RING ((w << 16) | 0); + OUT_RING ((h << 16) | 0); + OUT_RING (rt_format); + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2); + OUT_RING (((w - 1) << 16) | 0); + OUT_RING (((h - 1) << 16) | 0); +} + void nv10_emit_hw_state(struct nv10_context *nv10) { int i; + if (nv10->dirty & NV10_NEW_VERTPROG) { + //nv10_vertprog_bind(nv10, nv10->vertprog.current); + nv10->dirty &= ~NV10_NEW_VERTPROG; + } + if (nv10->dirty & NV10_NEW_FRAGPROG) { nv10_fragprog_bind(nv10, nv10->fragprog.current); /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */ + nv10->dirty_samplers |= (1<<10); + nv10->dirty_samplers = 0; } if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { @@ -16,16 +176,50 @@ nv10_emit_hw_state(struct nv10_context *nv10) nv10->dirty &= ~NV10_NEW_FRAGPROG; } - if (nv10->dirty & NV10_NEW_VERTPROG) { - //nv10_vertprog_bind(nv10, nv10->vertprog.current); - nv10->dirty &= ~NV10_NEW_VERTPROG; + if (nv10->dirty & NV10_NEW_ARRAYS) { + nv10->dirty &= ~NV10_NEW_ARRAYS; + // array state will be put here once it's not emitted at each frame } - if (nv10->dirty & NV10_NEW_VBO) { - + if (nv10->dirty & NV10_NEW_VTXFMT) { + nv10->dirty &= ~NV10_NEW_VTXFMT; + nv10_vtxbuf_bind(nv10); } - nv10->dirty_samplers = 0; + if (nv10->dirty & NV10_NEW_BLEND) { + nv10->dirty &= ~NV10_NEW_BLEND; + nv10_state_emit_blend(nv10); + } + + if (nv10->dirty & NV10_NEW_BLENDCOL) { + nv10->dirty &= ~NV10_NEW_BLENDCOL; + nv10_state_emit_blend_color(nv10); + } + + if (nv10->dirty & NV10_NEW_RAST) { + nv10->dirty &= ~NV10_NEW_RAST; + nv10_state_emit_rast(nv10); + } + + if (nv10->dirty & NV10_NEW_DSA) { + nv10->dirty &= ~NV10_NEW_DSA; + nv10_state_emit_dsa(nv10); + } + + if (nv10->dirty & NV10_NEW_VIEWPORT) { + nv10->dirty &= ~NV10_NEW_VIEWPORT; + nv10_state_emit_viewport(nv10); + } + + if (nv10->dirty & NV10_NEW_SCISSOR) { + nv10->dirty &= ~NV10_NEW_SCISSOR; + nv10_state_emit_scissor(nv10); + } + + if (nv10->dirty & NV10_NEW_FRAMEBUFFER) { + nv10->dirty &= ~NV10_NEW_FRAMEBUFFER; + nv10_state_emit_framebuffer(nv10); + } /* Emit relocs for every referenced buffer. * This is to ensure the bufmgr has an accurate idea of how @@ -48,10 +242,16 @@ nv10_emit_hw_state(struct nv10_context *nv10) BEGIN_RING(celsius, NV10TCL_ZETA_OFFSET, 1); OUT_RELOCl(nv10->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); /* XXX for when we allocate LMA on nv17 */ -/* BEGIN_RING(celsius, NV10TCL_LMA_DEPTH_OFFSET, 1); - OUT_RELOCl(nv10->zeta+lma_offset);*/ +/* BEGIN_RING(celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1); + OUT_RELOCl(nv10->zeta + lma_offset);*/ } + /* Vertex buffer */ + BEGIN_RING(celsius, NV10TCL_DMA_VTXBUF0, 1); + OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1); + OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + /* Texture images */ for (i = 0; i < 2; i++) { if (!(nv10->fp_samplers & (1 << i))) |