diff options
author | Ben Skeggs <[email protected]> | 2008-03-12 02:56:10 +1100 |
---|---|---|
committer | Ben Skeggs <[email protected]> | 2008-03-12 02:56:10 +1100 |
commit | 3250bacd2411d3f1af50135599380b2140238535 (patch) | |
tree | 11d07019acc1430a1bd84b54472a83c7225e6cd4 /src/gallium | |
parent | b2e48f848496d5e315e536688c8c33dfb1fab7eb (diff) |
nv50: create blend stateobj
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/nv50/nv50_context.h | 15 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state.c | 62 |
3 files changed, 86 insertions, 1 deletions
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index e2656bd539b..6096818d40d 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -22,6 +22,13 @@ #define NOUVEAU_MSG(fmt, args...) \ fprintf(stderr, "nouveau: "fmt, ##args); +#define NV50_NEW_BLEND (1 << 0) + +struct nv50_blend_stateobj { + struct pipe_blend_state pipe; + struct nouveau_stateobj *so; +}; + struct nv50_context { struct pipe_context pipe; @@ -29,8 +36,16 @@ struct nv50_context { unsigned pctx_id; struct draw_context *draw; + + unsigned dirty; + struct nv50_blend_stateobj *blend; }; +static INLINE struct nv50_context * +nv50_context(struct pipe_context *pipe) +{ + return (struct nv50_context *)pipe; +} extern void nv50_init_miptree_functions(struct nv50_context *nv50); extern void nv50_init_surface_functions(struct nv50_context *nv50); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index f8fd11dc5ff..62c23c790ca 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -103,6 +103,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen); struct nouveau_stateobj *so; unsigned tesla_class = 0, ret; + int i; if (!screen) return NULL; @@ -146,6 +147,15 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws, so = so_new(128, 0); so_method(so, screen->tesla, NV50TCL_DMA_NOTIFY, 1); so_data (so, screen->sync->handle); + so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY0(0), + NV50TCL_DMA_IN_MEMORY0__SIZE); + for (i = 0; i < NV50TCL_DMA_IN_MEMORY0__SIZE; i++) + so_data(so, nvws->channel->vram->handle); + so_method(so, screen->tesla, NV50TCL_DMA_IN_MEMORY1(0), + NV50TCL_DMA_IN_MEMORY1__SIZE); + for (i = 0; i < NV50TCL_DMA_IN_MEMORY1__SIZE; i++) + so_data(so, nvws->channel->vram->handle); + so_emit(nvws, so); so_ref(NULL, &so); nvws->push_flush(nvws->channel, 0); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 99dcab51b26..7a01100fd74 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -5,21 +5,81 @@ #include "nv50_context.h" #include "nv50_state.h" +#include "nouveau/nouveau_stateobj.h" + static void * nv50_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { - return NULL; + struct nouveau_stateobj *so = so_new(64, 0); + struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; + struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj); + unsigned cmask = 0, i; + + /*XXX ignored: + * - dither + */ + + if (cso->blend_enable == 0) { + so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + for (i = 0; i < 8; i++) + so_data(so, 0); + } else { + so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8); + for (i = 0; i < 8; i++) + so_data(so, 1); + so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5); + so_data (so, nvgl_blend_eqn(cso->rgb_func)); + so_data (so, nvgl_blend_func(cso->rgb_src_factor)); + so_data (so, nvgl_blend_func(cso->rgb_dst_factor)); + so_data (so, nvgl_blend_eqn(cso->alpha_func)); + so_data (so, nvgl_blend_func(cso->alpha_src_factor)); + so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1); + so_data (so, nvgl_blend_func(cso->alpha_dst_factor)); + } + + if (cso->logicop_enable == 0 ) { + so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 1); + so_data (so, 0); + } else { + so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 2); + so_data (so, 1); + so_data (so, nvgl_logicop_func(cso->logicop_func)); + } + + if (cso->colormask & PIPE_MASK_R) + cmask |= (1 << 0); + if (cso->colormask & PIPE_MASK_G) + cmask |= (1 << 4); + if (cso->colormask & PIPE_MASK_B) + cmask |= (1 << 8); + if (cso->colormask & PIPE_MASK_A) + cmask |= (1 << 12); + so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8); + for (i = 0; i < 8; i++) + so_data(so, cmask); + + bso->pipe = *cso; + so_ref(so, &bso->so); + return (void *)bso; } static void nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso) { + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->blend = hwcso; + nv50->dirty |= NV50_NEW_BLEND; } static void nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso) { + struct nv50_blend_stateobj *bso = hwcso; + + so_ref(NULL, &bso->so); + FREE(bso); } static void * |