summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv10
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv10')
-rw-r--r--src/gallium/drivers/nv10/nv10_context.c92
-rw-r--r--src/gallium/drivers/nv10/nv10_context.h31
-rw-r--r--src/gallium/drivers/nv10/nv10_miptree.c28
-rw-r--r--src/gallium/drivers/nv10/nv10_prim_vbuf.c17
-rw-r--r--src/gallium/drivers/nv10/nv10_screen.c70
-rw-r--r--src/gallium/drivers/nv10/nv10_screen.h6
-rw-r--r--src/gallium/drivers/nv10/nv10_state.c155
-rw-r--r--src/gallium/drivers/nv10/nv10_state_emit.c216
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)))