From 903521a6c031757d63b48129d08ba043d183dbdc Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 15 Feb 2008 02:41:34 +0100 Subject: nouveau: oops and make nouveau winsys build by default --- configs/linux-dri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'configs') diff --git a/configs/linux-dri b/configs/linux-dri index 936fce9982..494b0aab8e 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -66,4 +66,4 @@ WINDOW_SYSTEM=dri # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = intel_winsys +DRI_DIRS = intel_winsys nouveau_winsys -- cgit v1.2.3 From 1c65928d8400a350993687d7039e5e47371ae8b8 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 28 Jan 2008 18:17:55 -0700 Subject: Cell: add OPT_FLAGS var --- configs/linux-cell | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'configs') diff --git a/configs/linux-cell b/configs/linux-cell index 4f0086cc1f..3d874491e4 100644 --- a/configs/linux-cell +++ b/configs/linux-cell @@ -10,11 +10,13 @@ CC = ppu32-gcc CXX = ppu32-g++ HOST_CC = gcc +OPT_FLAGS = -g + # Cell SDK location SDK = /opt/ibm/cell-sdk/prototype/sysroot/usr -CFLAGS = -g -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec -I. -I$(SDK)/include -DGALLIUM_CELL +CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec -I. -I$(SDK)/include -DGALLIUM_CELL CXXFLAGS = $(CFLAGS) @@ -34,7 +36,7 @@ GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread \ SPU_CC = spu-gcc -SPU_CFLAGS = -g -W -Wall -Winline -Wmissing-prototypes -Wno-main -I. -I $(SDK)/spu/include -include spu_intrinsics.h -I $(TOP)/src/mesa/ +SPU_CFLAGS = $(OPT_FLAGS) -W -Wall -Winline -Wmissing-prototypes -Wno-main -I. -I $(SDK)/spu/include -include spu_intrinsics.h -I $(TOP)/src/mesa/ SPU_LFLAGS = -L$(SDK)/spu/lib -Wl,-N -lmisc -- cgit v1.2.3 From 0a653bef05fb3627fdd1857bfa8c3a1ebe08a4b7 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Fri, 15 Feb 2008 04:23:46 +0100 Subject: nouveau: more nv30 fixes, still doesn't work as well as before. --- configs/linux-dri | 2 +- src/mesa/pipe/nv30/nv30_context.c | 2 ++ src/mesa/pipe/nv30/nv30_state.c | 8 ++------ src/mesa/pipe/nv30/nv30_vbo.c | 8 ++++---- 4 files changed, 9 insertions(+), 11 deletions(-) (limited to 'configs') diff --git a/configs/linux-dri b/configs/linux-dri index 494b0aab8e..c7eb7112c0 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -66,4 +66,4 @@ WINDOW_SYSTEM=dri # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = intel_winsys nouveau_winsys +DRI_DIRS = nouveau_winsys diff --git a/src/mesa/pipe/nv30/nv30_context.c b/src/mesa/pipe/nv30/nv30_context.c index eef49fbcc2..d12aab85d8 100644 --- a/src/mesa/pipe/nv30/nv30_context.c +++ b/src/mesa/pipe/nv30/nv30_context.c @@ -71,6 +71,8 @@ nv30_get_paramf(struct pipe_context *pipe, int param) return 16.0; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 4.0; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0.0; diff --git a/src/mesa/pipe/nv30/nv30_state.c b/src/mesa/pipe/nv30/nv30_state.c index abc22eacae..992afe033e 100644 --- a/src/mesa/pipe/nv30/nv30_state.c +++ b/src/mesa/pipe/nv30/nv30_state.c @@ -614,12 +614,8 @@ nv30_set_framebuffer_state(struct pipe_context *pipe, nv30->rt[1] = rt[1]->buffer; } - if (zeta_format) { - /* XXX allocate LMA */ -/* BEGIN_RING(rankine, NV34TCL_LMA_DEPTH_OFFSET, 1); - OUT_RING(0);*/ - BEGIN_RING(rankine, NV34TCL_ZETA_PITCH, 1); - OUT_RING (zeta->pitch * zeta->cpp); + if (zeta_format) + { nv30->zeta = zeta->buffer; } diff --git a/src/mesa/pipe/nv30/nv30_vbo.c b/src/mesa/pipe/nv30/nv30_vbo.c index e6c50d3820..173a6e8fd7 100644 --- a/src/mesa/pipe/nv30/nv30_vbo.c +++ b/src/mesa/pipe/nv30/nv30_vbo.c @@ -241,9 +241,9 @@ nv30_draw_elements_u08(struct nv30_context *nv30, void *ib, } while (count) { - push = MIN2(count, 2046); + push = MIN2(count, 2047 * 2); - BEGIN_RING_NI(rankine, NV40TCL_VB_ELEMENT_U16, push); + BEGIN_RING_NI(rankine, NV40TCL_VB_ELEMENT_U16, push >> 1); for (i = 0; i < push; i+=2) OUT_RING((elts[i+1] << 16) | elts[i]); @@ -266,9 +266,9 @@ nv30_draw_elements_u16(struct nv30_context *nv30, void *ib, } while (count) { - push = MIN2(count, 2046); + push = MIN2(count, 2047 * 2); - BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U16, push); + BEGIN_RING_NI(rankine, NV34TCL_VB_ELEMENT_U16, push >> 1); for (i = 0; i < push; i+=2) OUT_RING((elts[i+1] << 16) | elts[i]); -- cgit v1.2.3 From 73e0e567dea3cf4e1591acb3e894eecef812f367 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Feb 2008 12:36:48 +1100 Subject: nouveau: fix build --- configs/default | 2 +- src/gallium/drivers/nv40/nv40_miptree.c | 38 +++++++++++++++++++++++++++++++++ src/gallium/drivers/nv40/nv40_surface.c | 31 --------------------------- 3 files changed, 39 insertions(+), 32 deletions(-) (limited to 'configs') diff --git a/configs/default b/configs/default index 48ddd29282..af9ff6f426 100644 --- a/configs/default +++ b/configs/default @@ -70,7 +70,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos # Gallium directories and GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv30 nv40 nv50 failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index 92e6b3a43d..5e1c7ade31 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -63,6 +63,7 @@ nv40_miptree_create(struct pipe_context *pipe, const struct pipe_texture *pt) if (!mt) return NULL; mt->base = *pt; + mt->base.refcount = 1; nv40_miptree_layout(mt); mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, @@ -95,10 +96,47 @@ nv40_miptree_release(struct pipe_context *pipe, struct pipe_texture **pt) } } +static void +nv40_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt) +{ +} + +static struct pipe_surface * +nv40_miptree_surface(struct pipe_context *pipe, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = pipe->winsys; + struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = nv40mt->level[level].pitch / ps->cpp; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv40mt->level[level].image_offset[face]; + } else + if (pt->target == PIPE_TEXTURE_3D) { + ps->offset = nv40mt->level[level].image_offset[zslice]; + } else { + ps->offset = nv40mt->level[level].image_offset[0]; + } + + return ps; +} + void nv40_init_miptree_functions(struct nv40_context *nv40) { nv40->pipe.texture_create = nv40_miptree_create; nv40->pipe.texture_release = nv40_miptree_release; + nv40->pipe.texture_update = nv40_miptree_update; + nv40->pipe.get_tex_surface = nv40_miptree_surface; } diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c index 9726ab4e4d..df5d7abdbf 100644 --- a/src/gallium/drivers/nv40/nv40_surface.c +++ b/src/gallium/drivers/nv40/nv40_surface.c @@ -73,36 +73,6 @@ nv40_surface_format_supported(struct pipe_context *pipe, return FALSE; } -static struct pipe_surface * -nv40_get_tex_surface(struct pipe_context *pipe, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice) -{ - struct pipe_winsys *ws = pipe->winsys; - struct nv40_miptree *nv40mt = (struct nv40_miptree *)pt; - struct pipe_surface *ps; - - ps = ws->surface_alloc(ws); - if (!ps) - return NULL; - pipe_buffer_reference(ws, &ps->buffer, nv40mt->buffer); - ps->format = pt->format; - ps->cpp = pt->cpp; - ps->width = pt->width[level]; - ps->height = pt->height[level]; - ps->pitch = nv40mt->level[level].pitch / ps->cpp; - - if (pt->target == PIPE_TEXTURE_CUBE) { - ps->offset = nv40mt->level[level].image_offset[face]; - } else - if (pt->target == PIPE_TEXTURE_3D) { - ps->offset = nv40mt->level[level].image_offset[zslice]; - } else { - ps->offset = nv40mt->level[level].image_offset[0]; - } - - return ps; -} - static void nv40_surface_copy(struct pipe_context *pipe, unsigned do_flip, struct pipe_surface *dest, unsigned destx, unsigned desty, @@ -131,7 +101,6 @@ void nv40_init_surface_functions(struct nv40_context *nv40) { nv40->pipe.is_format_supported = nv40_surface_format_supported; - nv40->pipe.get_tex_surface = nv40_get_tex_surface; nv40->pipe.surface_copy = nv40_surface_copy; nv40->pipe.surface_fill = nv40_surface_fill; } -- cgit v1.2.3 From d493203045b214770473f8afeaa610542fe42c2a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Sat, 15 Mar 2008 05:37:57 +0100 Subject: nv10. --- configs/default | 2 +- configs/linux-dri | 2 +- src/gallium/drivers/nouveau/nouveau_winsys.h | 7 + src/gallium/drivers/nv10/Makefile | 28 + src/gallium/drivers/nv10/nv10_clear.c | 12 + src/gallium/drivers/nv10/nv10_context.c | 325 +++++++++++ src/gallium/drivers/nv10/nv10_context.h | 127 +++++ src/gallium/drivers/nv10/nv10_fragprog.c | 22 + src/gallium/drivers/nv10/nv10_fragtex.c | 145 +++++ src/gallium/drivers/nv10/nv10_miptree.c | 134 +++++ src/gallium/drivers/nv10/nv10_prim_vbuf.c | 224 ++++++++ src/gallium/drivers/nv10/nv10_screen.c | 150 +++++ src/gallium/drivers/nv10/nv10_screen.h | 19 + src/gallium/drivers/nv10/nv10_state.c | 697 +++++++++++++++++++++++ src/gallium/drivers/nv10/nv10_state.h | 135 +++++ src/gallium/drivers/nv10/nv10_state_emit.c | 69 +++ src/gallium/drivers/nv10/nv10_surface.c | 65 +++ src/gallium/drivers/nv10/nv10_vbo.c | 72 +++ src/gallium/winsys/dri/nouveau/Makefile | 1 + src/gallium/winsys/dri/nouveau/nouveau_context.c | 3 + src/gallium/winsys/dri/nouveau/nouveau_winsys.c | 5 + 21 files changed, 2242 insertions(+), 2 deletions(-) create mode 100644 src/gallium/drivers/nv10/Makefile create mode 100644 src/gallium/drivers/nv10/nv10_clear.c create mode 100644 src/gallium/drivers/nv10/nv10_context.c create mode 100644 src/gallium/drivers/nv10/nv10_context.h create mode 100644 src/gallium/drivers/nv10/nv10_fragprog.c create mode 100644 src/gallium/drivers/nv10/nv10_fragtex.c create mode 100644 src/gallium/drivers/nv10/nv10_miptree.c create mode 100644 src/gallium/drivers/nv10/nv10_prim_vbuf.c create mode 100644 src/gallium/drivers/nv10/nv10_screen.c create mode 100644 src/gallium/drivers/nv10/nv10_screen.h create mode 100644 src/gallium/drivers/nv10/nv10_state.c create mode 100644 src/gallium/drivers/nv10/nv10_state.h create mode 100644 src/gallium/drivers/nv10/nv10_state_emit.c create mode 100644 src/gallium/drivers/nv10/nv10_surface.c create mode 100644 src/gallium/drivers/nv10/nv10_vbo.c (limited to 'configs') diff --git a/configs/default b/configs/default index 49d3737ec7..d010721a10 100644 --- a/configs/default +++ b/configs/default @@ -70,7 +70,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos # Gallium directories and GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util sct GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv30 nv40 nv50 failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv10 nv30 nv40 nv50 failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib diff --git a/configs/linux-dri b/configs/linux-dri index 67e60cbd4c..bf7881937e 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -65,4 +65,4 @@ GALLIUM_WINSYS_DIRS = dri # gamma are missing because they have not been converted to use the new # interface. -DRI_DIRS = intel +DRI_DIRS = nouveau diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 44c8bb919b..e4b20478a0 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -49,6 +49,13 @@ struct nouveau_winsys { unsigned, unsigned, unsigned, unsigned, unsigned); }; +extern struct pipe_screen * +nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, + unsigned chipset); + +extern struct pipe_context * +nv10_create(struct pipe_screen *, unsigned pctx_id); + extern struct pipe_screen * nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, unsigned chipset); diff --git a/src/gallium/drivers/nv10/Makefile b/src/gallium/drivers/nv10/Makefile new file mode 100644 index 0000000000..4ba7ce586d --- /dev/null +++ b/src/gallium/drivers/nv10/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv10 + +DRIVER_SOURCES = \ + nv10_clear.c \ + nv10_context.c \ + nv10_fragprog.c \ + nv10_fragtex.c \ + nv10_miptree.c \ + nv10_prim_vbuf.c \ + nv10_screen.c \ + nv10_state.c \ + nv10_state_emit.c \ + nv10_surface.c \ + nv10_vbo.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c new file mode 100644 index 0000000000..be7e09cf4b --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_clear.c @@ -0,0 +1,12 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "nv10_context.h" + +void +nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); +} diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c new file mode 100644 index 0000000000..2599acf286 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_context.c @@ -0,0 +1,325 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv10_context.h" +#include "nv10_screen.h" + +static void +nv10_flush(struct pipe_context *pipe, unsigned flags) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nouveau_winsys *nvws = nv10->nvws; + + if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + BEGIN_RING(celsius, 0x1fd8, 1); + OUT_RING (2); + BEGIN_RING(celsius, 0x1fd8, 1); + OUT_RING (1); + } + + if (flags & PIPE_FLUSH_WAIT) { + nvws->notifier_reset(nv10->sync, 0); + BEGIN_RING(celsius, 0x104, 1); + OUT_RING (0); + BEGIN_RING(celsius, 0x100, 1); + OUT_RING (0); + } + + FIRE_RING(); + + if (flags & PIPE_FLUSH_WAIT) + nvws->notifier_wait(nv10->sync, 0, 0, 2000); +} + +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); +} + +static boolean +nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) +{ + struct nouveau_winsys *nvws = nv10->nvws; + int ret; + 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); + BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2); + OUT_RING (nvws->channel->vram->handle); + OUT_RING (nvws->channel->gart->handle); + BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY2, 2); + OUT_RING (nvws->channel->vram->handle); + OUT_RING (nvws->channel->vram->handle); + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING (0); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING ((0x7ff<<16)|0x800); + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING ((0x7ff<<16)|0x800); + + for (i=1;i<8;i++) { + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING (0); + } + + BEGIN_RING(celsius, 0x290, 1); + OUT_RING ((0x10<<16)|1); + BEGIN_RING(celsius, 0x3f4, 1); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + if (celsius_class != NV10TCL) { + /* For nv11, nv17 */ + BEGIN_RING(celsius, 0x120, 3); + OUT_RING (0); + OUT_RING (1); + OUT_RING (2); + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + } + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + /* Set state */ + BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING (0x207); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_RC_OUT_ALPHA(0), 6); + OUT_RING (0x00000c00); + OUT_RING (0); + OUT_RING (0x00000c00); + OUT_RING (0x18000000); + OUT_RING (0x300c0000); + OUT_RING (0x00001c80); + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2); + OUT_RING (1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_SRC, 4); + OUT_RING (1); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0x8006); + BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 8); + OUT_RING (0xff); + OUT_RING (0x207); + OUT_RING (0); + OUT_RING (0xff); + OUT_RING (0x1e00); + OUT_RING (0x1e00); + OUT_RING (0x1e00); + OUT_RING (0x1d01); + BEGIN_RING(celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_COLOR_CONTROL, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING (0x201); + BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING (8); + BEGIN_RING(celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING (8); + BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING (0x1b02); + OUT_RING (0x1b02); + BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); + OUT_RING (0x405); + OUT_RING (0x901); + BEGIN_RING(celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_CLIP_PLANE_ENABLE(0), 8); + for (i=0;i<8;i++) { + OUT_RING (0); + } + BEGIN_RING(celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RING (0x3fc00000); /* -1.50 */ + OUT_RING (0xbdb8aa0a); /* -0.09 */ + OUT_RING (0); /* 0.00 */ + + BEGIN_RING(celsius, NV10TCL_NOP, 1); + OUT_RING (0); + + BEGIN_RING(celsius, NV10TCL_FOG_MODE, 2); + OUT_RING (0x802); + OUT_RING (2); + /* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when + * using texturing, except when using the texture matrix + */ + BEGIN_RING(celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); + OUT_RING (6); + BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING (0x01010101); + + /* Set vertex component */ + BEGIN_RING(celsius, NV10TCL_VERTEX_COL_4F_R, 4); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_COL2_3F_R, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RING (0); + BEGIN_RING(celsius, NV10TCL_VERTEX_NOR_3F_X, 3); + OUT_RING (0); + OUT_RING (0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_TX0_4F_S, 4); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_TX1_4F_S, 4); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (0.0); + OUT_RINGf (1.0); + BEGIN_RING(celsius, NV10TCL_VERTEX_FOG_1F, 1); + OUT_RINGf (0.0); + BEGIN_RING(celsius, NV10TCL_EDGEFLAG_ENABLE, 1); + OUT_RING (1); + + + FIRE_RING (); + return TRUE; +} + +struct pipe_context * +nv10_create(struct pipe_screen *screen, 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_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); + if (!nv10) + return NULL; + 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.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->draw = draw_create(); + assert(nv10->draw); + draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10)); + + return &nv10->pipe; +} + diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h new file mode 100644 index 0000000000..8269d6121f --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_context.h @@ -0,0 +1,127 @@ +#ifndef __NV10_CONTEXT_H__ +#define __NV10_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_gldefs.h" + +#define NOUVEAU_PUSH_CONTEXT(ctx) \ + struct nv10_context *ctx = nv10 +#include "nouveau/nouveau_push.h" + +#include "nv10_state.h" + +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); +#define NOUVEAU_MSG(fmt, args...) \ + fprintf(stderr, "nouveau: "fmt, ##args); + +#define NV10_NEW_VERTPROG (1 << 1) +#define NV10_NEW_FRAGPROG (1 << 2) +#define NV10_NEW_ARRAYS (1 << 3) +#define NV10_NEW_VBO (1 << 4) + +struct nv10_context { + struct pipe_context pipe; + struct nouveau_winsys *nvws; + + struct draw_context *draw; + + int chipset; + struct nouveau_grobj *celsius; + struct nouveau_notifier *sync; + + uint32_t dirty; + + struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; + struct nv10_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned dirty_samplers; + unsigned fp_samplers; + unsigned vp_samplers; + + uint32_t rt_enable; + struct pipe_buffer *rt[4]; + struct pipe_buffer *zeta; + + struct { + struct pipe_buffer *buffer; + uint32_t format; + } tex[16]; + + unsigned vb_enable; + struct { + struct pipe_buffer *buffer; + unsigned delta; + } vb[16]; + + struct vertex_info vertex_info; + struct { + + struct nouveau_resource *exec_heap; + struct nouveau_resource *data_heap; + + struct nv10_vertex_program *active; + + struct nv10_vertex_program *current; + struct pipe_buffer *constant_buf; + } vertprog; + + struct { + struct nv10_fragment_program *active; + + struct nv10_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; + struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; +}; + +static INLINE struct nv10_context * +nv10_context(struct pipe_context *pipe) +{ + return (struct nv10_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); + +/* nv10_clear.c */ +extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +/* nv10_draw.c */ +extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10); + +/* nv10_fragprog.c */ +extern void nv10_fragprog_bind(struct nv10_context *, + struct nv10_fragment_program *); +extern void nv10_fragprog_destroy(struct nv10_context *, + struct nv10_fragment_program *); + +/* nv10_fragtex.c */ +extern void nv10_fragtex_bind(struct nv10_context *); + +/* nv10_prim_vbuf.c */ +struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ); + +/* nv10_state.c and friends */ +extern void nv10_emit_hw_state(struct nv10_context *nv10); +extern void nv10_state_tex_update(struct nv10_context *nv10); + +/* nv10_vbo.c */ +extern boolean nv10_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv10_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count); + + +#endif diff --git a/src/gallium/drivers/nv10/nv10_fragprog.c b/src/gallium/drivers/nv10/nv10_fragprog.c new file mode 100644 index 0000000000..2a63c8a704 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_fragprog.c @@ -0,0 +1,22 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv10_context.h" + +void +nv10_fragprog_bind(struct nv10_context *nv10, struct nv10_fragment_program *fp) +{ +} + +void +nv10_fragprog_destroy(struct nv10_context *nv10, + struct nv10_fragment_program *fp) +{ +} + diff --git a/src/gallium/drivers/nv10/nv10_fragtex.c b/src/gallium/drivers/nv10/nv10_fragtex.c new file mode 100644 index 0000000000..a4bf108284 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_fragtex.c @@ -0,0 +1,145 @@ +#include "nv10_context.h" + +static INLINE int log2i(int i) +{ + int r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + +#define _(m,tf) \ +{ \ + TRUE, \ + PIPE_FORMAT_##m, \ + NV10TCL_TX_FORMAT_FORMAT_##tf, \ +} + +struct nv10_texture_format { + boolean defined; + uint pipe; + int format; +}; + +static struct nv10_texture_format +nv10_texture_formats[] = { + _(A8R8G8B8_UNORM, A8R8G8B8), + _(A1R5G5B5_UNORM, A1R5G5B5), + _(A4R4G4B4_UNORM, A4R4G4B4), + _(U_L8 , L8 ), + _(U_A8 , A8 ), + _(U_A8_L8 , A8L8 ), +// _(RGB_DXT1 , DXT1, ), +// _(RGBA_DXT1 , DXT1, ), +// _(RGBA_DXT3 , DXT3, ), +// _(RGBA_DXT5 , DXT5, ), + {}, +}; + +static struct nv10_texture_format * +nv10_fragtex_format(uint pipe_format) +{ + struct nv10_texture_format *tf = nv10_texture_formats; + + while (tf->defined) { + if (tf->pipe == pipe_format) + return tf; + tf++; + } + + return NULL; +} + + +static void +nv10_fragtex_build(struct nv10_context *nv10, int unit) +{ + struct nv10_sampler_state *ps = nv10->tex_sampler[unit]; + struct nv10_miptree *nv10mt = nv10->tex_miptree[unit]; + struct pipe_texture *pt = &nv10mt->base; + struct nv10_texture_format *tf; + uint32_t txf, txs, txp; + + tf = nv10_fragtex_format(pt->format); + if (!tf || !tf->defined) { + NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); + return; + } + + txf = tf->format << 8; + txf |= (pt->last_level + 1) << 16; + txf |= log2i(pt->width[0]) << 20; + txf |= log2i(pt->height[0]) << 24; + txf |= log2i(pt->depth[0]) << 28; + txf |= 8; + + switch (pt->target) { + case PIPE_TEXTURE_CUBE: + txf |= NV10TCL_TX_FORMAT_CUBE_MAP; + /* fall-through */ + case PIPE_TEXTURE_2D: + txf |= (2<<4); + break; + case PIPE_TEXTURE_1D: + txf |= (1<<4); + break; + default: + NOUVEAU_ERR("Unknown target %d\n", pt->target); + return; + } + + BEGIN_RING(celsius, NV10TCL_TX_OFFSET(unit), 8); + OUT_RELOCl(nv10mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv10mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); + OUT_RING (ps->wrap); + OUT_RING (0x40000000); /* enable */ + OUT_RING (txs); + OUT_RING (ps->filt | 0x2000 /* magic */); + OUT_RING ((pt->width[0] << 16) | pt->height[0]); + OUT_RING (ps->bcol); +} + +void +nv10_fragtex_bind(struct nv10_context *nv10) +{ + struct nv10_fragment_program *fp = nv10->fragprog.active; + unsigned samplers, unit; + + samplers = nv10->fp_samplers & ~fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + BEGIN_RING(celsius, NV10TCL_TX_ENABLE(unit), 1); + OUT_RING (0); + } + + samplers = nv10->dirty_samplers & fp->samplers; + while (samplers) { + unit = ffs(samplers) - 1; + samplers &= ~(1 << unit); + + nv10_fragtex_build(nv10, unit); + } + + nv10->fp_samplers = fp->samplers; +} + diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c new file mode 100644 index 0000000000..7b7f39b80c --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_miptree.c @@ -0,0 +1,134 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv10_context.h" +#include "nv10_screen.h" + +static void +nv10_miptree_layout(struct nv10_miptree *nv10mt) +{ + struct pipe_texture *pt = &nv10mt->base; + boolean swizzled = FALSE; + uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; + uint offset = 0; + int nr_faces, l, f; + + if (pt->target == PIPE_TEXTURE_CUBE) { + nr_faces = 6; + } else { + nr_faces = 1; + } + + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + pt->depth[l] = depth; + + if (swizzled) + nv10mt->level[l].pitch = pt->width[l] * pt->cpp; + else + nv10mt->level[l].pitch = pt->width[0] * pt->cpp; + nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63; + + nv10mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + depth = MAX2(1, depth >> 1); + + } + + for (f = 0; f < nr_faces; f++) { + for (l = 0; l <= pt->last_level; l++) { + nv10mt->level[l].image_offset[f] = offset; + offset += nv10mt->level[l].pitch * pt->height[l]; + } + } + + nv10mt->total_size = offset; +} + +static struct pipe_texture * +nv10_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt) +{ + struct pipe_winsys *ws = screen->winsys; + struct nv10_miptree *mt; + + mt = MALLOC(sizeof(struct nv10_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = screen; + + nv10_miptree_layout(mt); + + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + mt->total_size); + if (!mt->buffer) { + free(mt); + return NULL; + } + + return &mt->base; +} + +static void +nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; + int l; + + 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); + } +} + +static struct pipe_surface * +nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice) +{ + struct pipe_winsys *ws = screen->winsys; + struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv10mt->buffer); + ps->format = pt->format; + ps->cpp = pt->cpp; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->pitch = nv10mt->level[level].pitch / ps->cpp; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv10mt->level[level].image_offset[face]; + } else { + ps->offset = nv10mt->level[level].image_offset[0]; + } + + return ps; +} +void +nv10_init_miptree_functions(struct pipe_screen *screen) +{ + struct nv10_screen *nv10screen = nv10_screen(screen); + + nv10screen->screen.texture_create = nv10_miptree_create; + nv10screen->screen.texture_release = nv10_miptree_release; + nv10screen->screen.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 new file mode 100644 index 0000000000..1526891223 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c @@ -0,0 +1,224 @@ +/************************************************************************** + * + * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * \file + * Build post-transformation, post-clipping vertex buffers and element + * lists by hooking into the end of the primitive pipeline and + * manipulating the vertex_id field in the vertex headers. + * + * XXX: work in progress + * + * \author José Fonseca + * \author Keith Whitwell + */ + + +#include "draw/draw_vbuf.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" + +#include "nv10_context.h" +#include "nv10_state.h" + + +/** + * Primitive renderer for nv10. + */ +struct nv10_vbuf_render { + struct vbuf_render base; + + struct nv10_context *nv10; + + /** Vertex buffer */ + struct pipe_buffer* buffer; + + /** Vertex size in bytes */ + unsigned vertex_size; + + /** Hardware primitive */ + unsigned hwprim; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct nv10_vbuf_render * +nv10_vbuf_render( struct vbuf_render *render ) +{ + assert(render); + return (struct nv10_vbuf_render *)render; +} + + +static const struct vertex_info * +nv10_vbuf_render_get_vertex_info( struct vbuf_render *render ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + return &nv10->vertex_info; +} + + +static void * +nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, + ushort vertex_size, + ushort nr_vertices ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + struct pipe_winsys *winsys = nv10->pipe.winsys; + size_t size = (size_t)vertex_size * (size_t)nr_vertices; + + assert(!nv10_render->buffer); + nv10_render->buffer = winsys->buffer_create(winsys, 64, PIPE_BUFFER_USAGE_VERTEX, size); + + nv10->dirty |= NV10_NEW_VBO; + + return winsys->buffer_map(winsys, + nv10_render->buffer, + PIPE_BUFFER_USAGE_CPU_WRITE); +} + + +static void +nv10_vbuf_render_set_primitive( struct vbuf_render *render, + unsigned prim ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + nv10_render->hwprim = prim + 1; +} + + +static void +nv10_vbuf_render_draw( struct vbuf_render *render, + const ushort *indices, + uint nr_indices) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + int push, i; + + BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); + OUT_RELOCl(nv10_render->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + + BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); + OUT_RING(nv10_render->hwprim); + + if (nr_indices & 1) { + BEGIN_RING(celsius, NV10TCL_VB_ELEMENT_U32, 1); + OUT_RING (indices[0]); + indices++; nr_indices--; + } + + while (nr_indices) { + // XXX too big ? + push = MIN2(nr_indices, 2047 * 2); + + BEGIN_RING_NI(celsius, NV10TCL_VB_ELEMENT_U16, push >> 1); + for (i = 0; i < push; i+=2) + OUT_RING((indices[i+1] << 16) | indices[i]); + + nr_indices -= push; + indices += push; + } + + BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); + OUT_RING (0); +} + + +static void +nv10_vbuf_render_release_vertices( struct vbuf_render *render, + void *vertices, + unsigned vertex_size, + unsigned vertices_used ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + struct nv10_context *nv10 = nv10_render->nv10; + struct pipe_winsys *winsys = nv10->pipe.winsys; + + assert(nv10_render->buffer); + winsys->buffer_unmap(winsys, nv10_render->buffer); + pipe_buffer_reference(winsys, &nv10_render->buffer, NULL); +} + + +static void +nv10_vbuf_render_destroy( struct vbuf_render *render ) +{ + struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); + FREE(nv10_render); +} + + +/** + * Create a new primitive render. + */ +static struct vbuf_render * +nv10_vbuf_render_create( struct nv10_context *nv10 ) +{ + struct nv10_vbuf_render *nv10_render = CALLOC_STRUCT(nv10_vbuf_render); + + nv10_render->nv10 = nv10; + + nv10_render->base.max_vertex_buffer_bytes = 1024*1024; + nv10_render->base.max_indices = 64*1024; + nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info; + nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices; + nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive; + nv10_render->base.draw = nv10_vbuf_render_draw; + nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices; + nv10_render->base.destroy = nv10_vbuf_render_destroy; + + return &nv10_render->base; +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ) +{ + struct vbuf_render *render; + struct draw_stage *stage; + + render = nv10_vbuf_render_create(nv10); + if(!render) + return NULL; + + stage = draw_vbuf_stage( nv10->draw, render ); + if(!stage) { + render->destroy(render); + return NULL; + } + + return stage; +} diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c new file mode 100644 index 0000000000..4d8e0b05cc --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_screen.c @@ -0,0 +1,150 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv10_context.h" +#include "nv10_screen.h" + +static const char * +nv10_screen_get_name(struct pipe_screen *screen) +{ + struct nv10_screen *nv10screen = nv10_screen(screen); + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", nv10screen->chipset); + return buffer; +} + +static const char * +nv10_screen_get_vendor(struct pipe_screen *screen) +{ + return "nouveau"; +} + +static int +nv10_screen_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 2; + case PIPE_CAP_NPOT_TEXTURES: + return 0; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 0; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 1; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 0; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 12; + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 0; + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 12; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv10_screen_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 10.0; + case PIPE_CAP_MAX_POINT_WIDTH: + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 64.0; + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 2.0; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 4.0; + case PIPE_CAP_BITMAP_TEXCOORD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static boolean +nv10_screen_is_format_supported(struct pipe_screen *screen, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z24S8_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_U_L8: + case PIPE_FORMAT_U_A8: + case PIPE_FORMAT_U_I8: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void +nv10_screen_destroy(struct pipe_screen *screen) +{ + FREE(screen); +} + +struct pipe_screen * +nv10_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws, + unsigned chipset) +{ + struct nv10_screen *nv10screen = CALLOC_STRUCT(nv10_screen); + + if (!nv10screen) + return NULL; + + nv10screen->chipset = chipset; + nv10screen->nvws = nvws; + + nv10screen->screen.winsys = winsys; + + nv10screen->screen.destroy = nv10_screen_destroy; + + 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_init_miptree_functions(&nv10screen->screen); + return &nv10screen->screen; +} + diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h new file mode 100644 index 0000000000..ac8c04072a --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_screen.h @@ -0,0 +1,19 @@ +#ifndef __NV10_SCREEN_H__ +#define __NV10_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv10_screen { + struct pipe_screen screen; + + struct nouveau_winsys *nvws; + unsigned chipset; +}; + +static INLINE struct nv10_screen * +nv10_screen(struct pipe_screen *screen) +{ + return (struct nv10_screen *)screen; +} + +#endif diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c new file mode 100644 index 0000000000..313230fe88 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state.c @@ -0,0 +1,697 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + + +#include "nv10_context.h" +#include "nv10_state.h" + +static void nv10_vertex_layout(struct pipe_context* pipe) +{ + struct nv10_context *nv10 = nv10_context(pipe); + const struct pipe_shader_state *fs = nv10->fragprog.current->pipe; + uint32_t src = 0; + int i; + struct vertex_info vinfo; + + memset(&vinfo, 0, sizeof(vinfo)); + + for (i = 0; i < fs->num_inputs; i++) { + switch (fs->input_semantic_name[i]) { + case TGSI_SEMANTIC_POSITION: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + case TGSI_SEMANTIC_COLOR: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + default: + case TGSI_SEMANTIC_GENERIC: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + case TGSI_SEMANTIC_FOG: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + } + } + draw_compute_vertex_size(&vinfo); +} + +static void * +nv10_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nv10_blend_state *cb; + + cb = malloc(sizeof(struct nv10_blend_state)); + + cb->b_enable = cso->blend_enable ? 1 : 0; + cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rgb_src_factor))); + cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rgb_dst_factor))); + + cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | + ((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | + ((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | + ((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); + + cb->d_enable = cso->dither ? 1 : 0; + + return (void *)cb; +} + +static void +nv10_blend_state_bind(struct pipe_context *pipe, void *hwcso) +{ + 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); + + BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING (cb->c_mask); +} + +static void +nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + + +static INLINE unsigned +wrap_mode(unsigned wrap) { + unsigned ret; + + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT; + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + ret = NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_CLAMP: + ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + case PIPE_TEX_WRAP_MIRROR_CLAMP: + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT; + break; + } + + return ret >> NV10TCL_TX_FORMAT_WRAP_S_SHIFT; +} + +static void * +nv10_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + struct nv10_sampler_state *ps; + uint32_t filter = 0; + + ps = malloc(sizeof(struct nv10_sampler_state)); + + ps->wrap = ((wrap_mode(cso->wrap_s) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT) | + (wrap_mode(cso->wrap_t) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT)); + + ps->en = 0; + if (cso->max_anisotropy > 1.0) { + /* no idea, binary driver sets it, works without it.. meh.. */ + ps->wrap |= (1 << 5); + +/* if (cso->max_anisotropy >= 16.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_16X; + } else + if (cso->max_anisotropy >= 12.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_12X; + } else + if (cso->max_anisotropy >= 10.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_10X; + } else + if (cso->max_anisotropy >= 8.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_8X; + } else + if (cso->max_anisotropy >= 6.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_6X; + } else + if (cso->max_anisotropy >= 4.0) { + ps->en |= NV10TCL_TX_ENABLE_ANISO_4X; + } else { + ps->en |= NV10TCL_TX_ENABLE_ANISO_2X; + }*/ + } + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + filter |= NV10TCL_TX_FILTER_MAGNIFY_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + filter |= NV10TCL_TX_FILTER_MAGNIFY_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR; + break; + } + break; + case PIPE_TEX_FILTER_NEAREST: + default: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST; + break; + } + break; + } + + ps->filt = filter; + +/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { + switch (cso->compare_func) { + case PIPE_FUNC_NEVER: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER; + break; + case PIPE_FUNC_GREATER: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER; + break; + case PIPE_FUNC_EQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL; + break; + case PIPE_FUNC_GEQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL; + break; + case PIPE_FUNC_LESS: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS; + break; + case PIPE_FUNC_NOTEQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL; + break; + case PIPE_FUNC_LEQUAL: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL; + break; + case PIPE_FUNC_ALWAYS: + ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS; + break; + default: + break; + } + }*/ + + ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) | + (float_to_ubyte(cso->border_color[0]) << 16) | + (float_to_ubyte(cso->border_color[1]) << 8) | + (float_to_ubyte(cso->border_color[2]) << 0)); + + return (void *)ps; +} + +static void +nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +{ + struct nv10_context *nv10 = nv10_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv10->tex_sampler[unit] = sampler[unit]; + nv10->dirty_samplers |= (1 << unit); + } +} + +static void +nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void +nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) +{ + struct nv10_context *nv10 = nv10_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit]; + nv10->dirty_samplers |= (1 << unit); + } +} + +static void * +nv10_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv10_rasterizer_state *rs; + int i; + + /*XXX: ignored: + * light_twoside + * offset_cw/ccw -nohw + * scissor + * point_smooth -nohw + * multisample + * offset_units / offset_scale + */ + rs = malloc(sizeof(struct nv10_rasterizer_state)); + + rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01; + + rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff; + rs->line_smooth_en = cso->line_smooth ? 1 : 0; + + rs->point_size = *(uint32_t*)&cso->point_size; + + rs->poly_smooth_en = cso->poly_smooth ? 1 : 0; + + if (cso->front_winding == PIPE_WINDING_CCW) { + rs->front_face = NV10TCL_FRONT_FACE_CCW; + rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw); + rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw); + } else { + rs->front_face = NV10TCL_FRONT_FACE_CW; + rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw); + rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw); + } + + switch (cso->cull_mode) { + case PIPE_WINDING_CCW: + rs->cull_face_en = 1; + if (cso->front_winding == PIPE_WINDING_CCW) + rs->cull_face = NV10TCL_CULL_FACE_FRONT; + else + rs->cull_face = NV10TCL_CULL_FACE_BACK; + break; + case PIPE_WINDING_CW: + rs->cull_face_en = 1; + if (cso->front_winding == PIPE_WINDING_CW) + rs->cull_face = NV10TCL_CULL_FACE_FRONT; + else + rs->cull_face = NV10TCL_CULL_FACE_BACK; + break; + case PIPE_WINDING_BOTH: + rs->cull_face_en = 1; + rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK; + break; + case PIPE_WINDING_NONE: + default: + rs->cull_face_en = 0; + rs->cull_face = 0; + break; + } + + if (cso->point_sprite) { + rs->point_sprite = (1 << 0); + for (i = 0; i < 8; i++) { + if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) + rs->point_sprite |= (1 << (8 + i)); + } + } else { + rs->point_sprite = 0; + } + + return (void *)rs; +} + +static void +nv10_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) +{ + 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); + + 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);*/ +} + +static void +nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void * +nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv10_depth_stencil_alpha_state *hw; + + hw = malloc(sizeof(struct nv10_depth_stencil_alpha_state)); + + hw->depth.func = nvgl_comparison_op(cso->depth.func); + hw->depth.write_enable = cso->depth.writemask ? 1 : 0; + hw->depth.test_enable = cso->depth.enabled ? 1 : 0; + + hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0; + hw->stencil.wmask = cso->stencil[0].write_mask; + hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func); + hw->stencil.ref = cso->stencil[0].ref_value; + hw->stencil.vmask = cso->stencil[0].value_mask; + hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op); + hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op); + hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op); + + hw->alpha.enabled = cso->alpha.enabled ? 1 : 0; + hw->alpha.func = nvgl_comparison_op(cso->alpha.func); + hw->alpha.ref = float_to_ubyte(cso->alpha.ref); + + return (void *)hw; +} + +static void +nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + 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); +} + +static void +nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void * +nv10_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv10_vertex_program *vp; + + vp = CALLOC(1, sizeof(struct nv10_vertex_program)); + vp->pipe = cso; + + return (void *)vp; +} + +static void +nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_vertex_program *vp = hwcso; + + nv10->vertprog.current = vp; + nv10->dirty |= NV10_NEW_VERTPROG; +} + +static void +nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_vertex_program *vp = hwcso; + + //nv10_vertprog_destroy(nv10, vp); + free(vp); +} + +static void * +nv10_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv10_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nv10_fragment_program)); + fp->pipe = cso; + + return (void *)fp; +} + +static void +nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_fragment_program *fp = hwcso; + + nv10->fragprog.current = fp; + nv10->dirty |= NV10_NEW_FRAGPROG; +} + +static void +nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nv10_fragment_program *fp = hwcso; + + nv10_fragprog_destroy(nv10, fp); + free(fp); +} + +static void +nv10_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) +{ + 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)); +} + +static void +nv10_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ +} + +static void +nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + if (shader == PIPE_SHADER_VERTEX) { + nv10->vertprog.constant_buf = buf->buffer; + nv10->dirty |= NV10_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv10->fragprog.constant_buf = buf->buffer; + nv10->dirty |= NV10_NEW_FRAGPROG; + } +} + +static void +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; + + 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); +} + +static void +nv10_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + NOUVEAU_ERR("line stipple hahaha\n"); +} + +static void +nv10_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ + 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);*/ +} + +static void +nv10_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *vpt) +{ + 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]); +} + +static void +nv10_set_vertex_buffer(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_buffer *vb) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->vtxbuf[index] = *vb; + + nv10->dirty |= NV10_NEW_ARRAYS; +} + +static void +nv10_set_vertex_element(struct pipe_context *pipe, unsigned index, + const struct pipe_vertex_element *ve) +{ + struct nv10_context *nv10 = nv10_context(pipe); + + nv10->vtxelt[index] = *ve; + + nv10->dirty |= NV10_NEW_ARRAYS; +} + +void +nv10_init_state_functions(struct nv10_context *nv10) +{ + nv10->pipe.create_blend_state = nv10_blend_state_create; + nv10->pipe.bind_blend_state = nv10_blend_state_bind; + nv10->pipe.delete_blend_state = nv10_blend_state_delete; + + nv10->pipe.create_sampler_state = nv10_sampler_state_create; + nv10->pipe.bind_sampler_states = nv10_sampler_state_bind; + nv10->pipe.delete_sampler_state = nv10_sampler_state_delete; + nv10->pipe.set_sampler_textures = nv10_set_sampler_texture; + + nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create; + nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind; + nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete; + + nv10->pipe.create_depth_stencil_alpha_state = + nv10_depth_stencil_alpha_state_create; + nv10->pipe.bind_depth_stencil_alpha_state = + nv10_depth_stencil_alpha_state_bind; + nv10->pipe.delete_depth_stencil_alpha_state = + nv10_depth_stencil_alpha_state_delete; + + nv10->pipe.create_vs_state = nv10_vp_state_create; + nv10->pipe.bind_vs_state = nv10_vp_state_bind; + nv10->pipe.delete_vs_state = nv10_vp_state_delete; + + nv10->pipe.create_fs_state = nv10_fp_state_create; + nv10->pipe.bind_fs_state = nv10_fp_state_bind; + nv10->pipe.delete_fs_state = nv10_fp_state_delete; + + nv10->pipe.set_blend_color = nv10_set_blend_color; + nv10->pipe.set_clip_state = nv10_set_clip_state; + nv10->pipe.set_constant_buffer = nv10_set_constant_buffer; + nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state; + nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple; + nv10->pipe.set_scissor_state = nv10_set_scissor_state; + nv10->pipe.set_viewport_state = nv10_set_viewport_state; + + nv10->pipe.set_vertex_buffer = nv10_set_vertex_buffer; + nv10->pipe.set_vertex_element = nv10_set_vertex_element; +} + diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h new file mode 100644 index 0000000000..d4b703c7ad --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state.h @@ -0,0 +1,135 @@ +#ifndef __NV10_STATE_H__ +#define __NV10_STATE_H__ + +#include "pipe/p_state.h" + +struct nv10_blend_state { + uint32_t b_enable; + uint32_t b_srcfunc; + uint32_t b_dstfunc; + + uint32_t c_mask; + + uint32_t d_enable; +}; + +struct nv10_sampler_state { + uint32_t wrap; + uint32_t en; + uint32_t filt; + uint32_t bcol; +}; + +struct nv10_rasterizer_state { + uint32_t shade_model; + + uint32_t line_width; + uint32_t line_smooth_en; + + uint32_t point_size; + + uint32_t poly_smooth_en; + + uint32_t poly_mode_front; + uint32_t poly_mode_back; + + uint32_t front_face; + uint32_t cull_face; + uint32_t cull_face_en; + + uint32_t point_sprite; +}; + +struct nv10_vertex_program_exec { + uint32_t data[4]; + boolean has_branch_offset; + int const_index; +}; + +struct nv10_vertex_program_data { + int index; /* immediates == -1 */ + float value[4]; +}; + +struct nv10_vertex_program { + const struct pipe_shader_state *pipe; + + boolean translated; + struct nv10_vertex_program_exec *insns; + unsigned nr_insns; + struct nv10_vertex_program_data *consts; + unsigned nr_consts; + + struct nouveau_resource *exec; + unsigned exec_start; + struct nouveau_resource *data; + unsigned data_start; + unsigned data_start_min; + + uint32_t ir; + uint32_t or; +}; + +struct nv10_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv10_fragment_program { + const struct pipe_shader_state *pipe; + + boolean translated; + boolean on_hw; + unsigned samplers; + + uint32_t *insn; + int insn_len; + + struct nv10_fragment_program_data *consts; + unsigned nr_consts; + + struct pipe_buffer *buffer; + + uint32_t fp_control; + uint32_t fp_reg_control; +}; + + +struct nv10_depth_stencil_alpha_state { + struct { + uint32_t func; + uint32_t write_enable; + uint32_t test_enable; + } depth; + + struct { + uint32_t enable; + uint32_t wmask; + uint32_t func; + uint32_t ref; + uint32_t vmask; + uint32_t fail; + uint32_t zfail; + uint32_t zpass; + } stencil; + + struct { + uint32_t enabled; + uint32_t func; + uint32_t ref; + } alpha; +}; + +struct nv10_miptree { + struct pipe_texture base; + + struct pipe_buffer *buffer; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[PIPE_MAX_TEXTURE_LEVELS]; +}; + +#endif diff --git a/src/gallium/drivers/nv10/nv10_state_emit.c b/src/gallium/drivers/nv10/nv10_state_emit.c new file mode 100644 index 0000000000..1d104e2f91 --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_state_emit.c @@ -0,0 +1,69 @@ +#include "nv10_context.h" +#include "nv10_state.h" + +void +nv10_emit_hw_state(struct nv10_context *nv10) +{ + int i; + + if (nv10->dirty & NV10_NEW_FRAGPROG) { + nv10_fragprog_bind(nv10, nv10->fragprog.current); + /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */ + } + + if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { + nv10_fragtex_bind(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_VBO) { + + } + + nv10->dirty_samplers = 0; + + /* Emit relocs for every referenced buffer. + * This is to ensure the bufmgr has an accurate idea of how + * the buffer is used. This isn't very efficient, but we don't + * seem to take a significant performance hit. Will be improved + * at some point. Vertex arrays are emitted by nv10_vbo.c + */ + + /* Render target */ +// XXX figre out who's who for NV10TCL_DMA_* and fill accordingly +// BEGIN_RING(celsius, NV10TCL_DMA_COLOR0, 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); + + if (nv10->zeta) { +// XXX +// BEGIN_RING(celsius, NV10TCL_DMA_ZETA, 1); +// OUT_RELOCo(nv10->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + 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+...);*/ + } + + /* Texture images */ + for (i = 0; i < 2; i++) { + if (!(nv10->fp_samplers & (1 << i))) + continue; + BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 2); + OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + // XXX +/* OUT_RELOCd(nv10->tex[i].buffer, nv10->tex[i].format, + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | + NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0, + NV10TCL_TX_FORMAT_DMA1);*/ + } +} + diff --git a/src/gallium/drivers/nv10/nv10_surface.c b/src/gallium/drivers/nv10/nv10_surface.c new file mode 100644 index 0000000000..2e230ebbec --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_surface.c @@ -0,0 +1,65 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "nv10_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +static void +nv10_surface_copy(struct pipe_context *pipe, unsigned do_flip, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nouveau_winsys *nvws = nv10->nvws; + + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); +} + +static void +nv10_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv10_context *nv10 = nv10_context(pipe); + struct nouveau_winsys *nvws = nv10->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv10_init_surface_functions(struct nv10_context *nv10) +{ + nv10->pipe.surface_copy = nv10_surface_copy; + nv10->pipe.surface_fill = nv10_surface_fill; +} diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c new file mode 100644 index 0000000000..025ad6de4b --- /dev/null +++ b/src/gallium/drivers/nv10/nv10_vbo.c @@ -0,0 +1,72 @@ +#include "draw/draw_context.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv10_context.h" +#include "nv10_state.h" + +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_pushbuf.h" + +boolean nv10_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count) +{ + struct nv10_context *nv10 = nv10_context( pipe ); + struct draw_context *draw = nv10->draw; + unsigned i; + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (nv10->vtxbuf[i].buffer) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + nv10->vtxbuf[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + } + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes + = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + /* draw! */ + draw_arrays(nv10->draw, prim, start, count); + + /* + * unmap vertex/index buffers + */ + for (i = 0; i < PIPE_ATTRIB_MAX; i++) { + if (nv10->vtxbuf[i].buffer) { + pipe->winsys->buffer_unmap(pipe->winsys, nv10->vtxbuf[i].buffer); + draw_set_mapped_vertex_buffer(draw, i, NULL); + } + } + if (indexBuffer) { + pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + return TRUE; +} + +boolean nv10_draw_arrays( struct pipe_context *pipe, + unsigned prim, unsigned start, unsigned count) +{ + return nv10_draw_elements(pipe, NULL, 0, prim, start, count); +} + + + diff --git a/src/gallium/winsys/dri/nouveau/Makefile b/src/gallium/winsys/dri/nouveau/Makefile index b463f218fd..f637b2cebf 100644 --- a/src/gallium/winsys/dri/nouveau/Makefile +++ b/src/gallium/winsys/dri/nouveau/Makefile @@ -8,6 +8,7 @@ MINIGLX_SOURCES = PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/nv10/libnv10.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a diff --git a/src/gallium/winsys/dri/nouveau/nouveau_context.c b/src/gallium/winsys/dri/nouveau/nouveau_context.c index 8b20b3689c..336dd65847 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_context.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_context.c @@ -119,6 +119,9 @@ nouveau_context_create(const __GLcontextModes *glVis, } switch (nv->chipset & 0xf0) { + case 0x10: + case 0x20: + /* NV10 */ case 0x30: /* NV30 */ case 0x40: diff --git a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c index 64e84fb68e..6c85aab9f5 100644 --- a/src/gallium/winsys/dri/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/dri/nouveau/nouveau_winsys.c @@ -82,6 +82,11 @@ nouveau_pipe_create(struct nouveau_context *nv) return NULL; switch (nv->chipset & 0xf0) { + case 0x10: + case 0x20: + hws_create = nv10_screen_create; + hw_create = nv10_create; + break; case 0x30: hws_create = nv30_screen_create; hw_create = nv30_create; -- cgit v1.2.3 From 52a68dd9eb1d347aa01ce09db9375793d0d0ceaf Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 8 Jul 2008 01:06:18 +0200 Subject: nv04. --- configs/default | 2 +- src/gallium/drivers/nouveau/nouveau_winsys.h | 6 + src/gallium/drivers/nv04/Makefile | 28 ++ src/gallium/drivers/nv04/nv04_clear.c | 12 + src/gallium/drivers/nv04/nv04_context.c | 107 ++++++ src/gallium/drivers/nv04/nv04_context.h | 142 ++++++++ src/gallium/drivers/nv04/nv04_fragprog.c | 22 ++ src/gallium/drivers/nv04/nv04_fragtex.c | 100 ++++++ src/gallium/drivers/nv04/nv04_miptree.c | 138 ++++++++ src/gallium/drivers/nv04/nv04_prim_vbuf.c | 312 +++++++++++++++++ src/gallium/drivers/nv04/nv04_screen.c | 216 ++++++++++++ src/gallium/drivers/nv04/nv04_screen.h | 25 ++ src/gallium/drivers/nv04/nv04_state.c | 494 +++++++++++++++++++++++++++ src/gallium/drivers/nv04/nv04_state.h | 71 ++++ src/gallium/drivers/nv04/nv04_state_emit.c | 156 +++++++++ src/gallium/drivers/nv04/nv04_surface.c | 65 ++++ src/gallium/drivers/nv04/nv04_vbo.c | 72 ++++ 17 files changed, 1967 insertions(+), 1 deletion(-) create mode 100644 src/gallium/drivers/nv04/Makefile create mode 100644 src/gallium/drivers/nv04/nv04_clear.c create mode 100644 src/gallium/drivers/nv04/nv04_context.c create mode 100644 src/gallium/drivers/nv04/nv04_context.h create mode 100644 src/gallium/drivers/nv04/nv04_fragprog.c create mode 100644 src/gallium/drivers/nv04/nv04_fragtex.c create mode 100644 src/gallium/drivers/nv04/nv04_miptree.c create mode 100644 src/gallium/drivers/nv04/nv04_prim_vbuf.c create mode 100644 src/gallium/drivers/nv04/nv04_screen.c create mode 100644 src/gallium/drivers/nv04/nv04_screen.h create mode 100644 src/gallium/drivers/nv04/nv04_state.c create mode 100644 src/gallium/drivers/nv04/nv04_state.h create mode 100644 src/gallium/drivers/nv04/nv04_state_emit.c create mode 100644 src/gallium/drivers/nv04/nv04_surface.c create mode 100644 src/gallium/drivers/nv04/nv04_vbo.c (limited to 'configs') diff --git a/configs/default b/configs/default index a8d1fe6bec..c1bc5fb01d 100644 --- a/configs/default +++ b/configs/default @@ -70,7 +70,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos # Gallium directories and GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi sct translate rtasm util GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv10 nv30 nv40 nv50 failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 nv10 nv30 nv40 nv50 failover GALLIUM_WINSYS_COMMON_DIRS = GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib egl_xlib diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 13810460bf..48feeba309 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -57,6 +57,12 @@ struct nouveau_winsys { unsigned, unsigned, unsigned, unsigned, unsigned); }; +extern struct pipe_screen * +nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv04_create(struct pipe_screen *, unsigned pctx_id); + extern struct pipe_screen * nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); diff --git a/src/gallium/drivers/nv04/Makefile b/src/gallium/drivers/nv04/Makefile new file mode 100644 index 0000000000..5ea51a2f42 --- /dev/null +++ b/src/gallium/drivers/nv04/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = nv04 + +DRIVER_SOURCES = \ + nv04_clear.c \ + nv04_context.c \ + nv04_fragprog.c \ + nv04_fragtex.c \ + nv04_miptree.c \ + nv04_prim_vbuf.c \ + nv04_screen.c \ + nv04_state.c \ + nv04_state_emit.c \ + nv04_surface.c \ + nv04_vbo.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../../Makefile.template + +symlinks: + diff --git a/src/gallium/drivers/nv04/nv04_clear.c b/src/gallium/drivers/nv04/nv04_clear.c new file mode 100644 index 0000000000..01cacd36fe --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_clear.c @@ -0,0 +1,12 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "nv04_context.h" + +void +nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue) +{ + pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); +} diff --git a/src/gallium/drivers/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c new file mode 100644 index 0000000000..852a8edf5f --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_context.c @@ -0,0 +1,107 @@ +#include "draw/draw_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_winsys.h" +#include "pipe/p_util.h" + +#include "nv04_context.h" +#include "nv04_screen.h" + +static void +nv04_flush(struct pipe_context *pipe, unsigned flags, + struct pipe_fence_handle **fence) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_flush(nv04->draw); + + FIRE_RING(fence); +} + +static void +nv04_destroy(struct pipe_context *pipe) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + if (nv04->draw) + draw_destroy(nv04->draw); + + FREE(nv04); +} + +static void +nv04_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield) +{ +} + +static boolean +nv04_init_hwctx(struct nv04_context *nv04) +{ + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOTIFY, 1); + OUT_RING(0); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOP, 1); + OUT_RING(0); + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(0x40182800); +// OUT_RING(1<<20/*no cull*/); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); +// OUT_RING(0x24|(1<<6)|(1<<8)); + OUT_RING(0x120001a4); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FORMAT, 1); + OUT_RING(0x332213a1); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FILTER, 1); + OUT_RING(0x11001010); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_COLORKEY, 1); + OUT_RING(0x0); +// BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 1); +// OUT_RING(SCREEN_OFFSET); + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR, 1); + OUT_RING(0xff000000); + + + + FIRE_RING (NULL); + return TRUE; +} + +struct pipe_context * +nv04_create(struct pipe_screen *pscreen, unsigned pctx_id) +{ + struct nv04_screen *screen = nv04_screen(pscreen); + struct pipe_winsys *ws = pscreen->winsys; + struct nv04_context *nv04; + struct nouveau_winsys *nvws = screen->nvws; + + nv04 = CALLOC(1, sizeof(struct nv04_context)); + if (!nv04) + return NULL; + nv04->screen = screen; + nv04->pctx_id = pctx_id; + + nv04->nvws = nvws; + + nv04->pipe.winsys = ws; + nv04->pipe.screen = pscreen; + nv04->pipe.destroy = nv04_destroy; + nv04->pipe.set_edgeflags = nv04_set_edgeflags; + nv04->pipe.draw_arrays = nv04_draw_arrays; + nv04->pipe.draw_elements = nv04_draw_elements; + nv04->pipe.clear = nv04_clear; + nv04->pipe.flush = nv04_flush; + + nv04_init_surface_functions(nv04); + nv04_init_state_functions(nv04); + + nv04->draw = draw_create(); + assert(nv04->draw); + draw_wide_point_threshold(nv04->draw, 0.0); + draw_wide_line_threshold(nv04->draw, 0.0); + draw_enable_line_stipple(nv04->draw, FALSE); + draw_enable_point_sprites(nv04->draw, FALSE); + draw_set_rasterize_stage(nv04->draw, nv04_draw_vbuf_stage(nv04)); + + nv04_init_hwctx(nv04); + + return &nv04->pipe; +} + diff --git a/src/gallium/drivers/nv04/nv04_context.h b/src/gallium/drivers/nv04/nv04_context.h new file mode 100644 index 0000000000..5ba1d4ecdc --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_context.h @@ -0,0 +1,142 @@ +#ifndef __NV04_CONTEXT_H__ +#define __NV04_CONTEXT_H__ + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" + +#include "draw/draw_vertex.h" + +#include "nouveau/nouveau_winsys.h" +#include "nouveau/nouveau_gldefs.h" + +#define NOUVEAU_PUSH_CONTEXT(ctx) \ + struct nv04_screen *ctx = nv04->screen +#include "nouveau/nouveau_push.h" + +#include "nv04_state.h" + +#define NOUVEAU_ERR(fmt, args...) \ + fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); +#define NOUVEAU_MSG(fmt, args...) \ + fprintf(stderr, "nouveau: "fmt, ##args); + +#include "nv04_screen.h" + +#define NV04_NEW_VERTPROG (1 << 1) +#define NV04_NEW_FRAGPROG (1 << 2) +#define NV04_NEW_BLEND (1 << 3) +#define NV04_NEW_RAST (1 << 4) +#define NV04_NEW_CONTROL (1 << 5) +#define NV04_NEW_VIEWPORT (1 << 6) +#define NV04_NEW_SAMPLER (1 << 7) + +struct nv04_context { + struct pipe_context pipe; + + struct nouveau_winsys *nvws; + struct nv04_screen *screen; + unsigned pctx_id; + + struct draw_context *draw; + + int chipset; + struct nouveau_notifier *sync; + + uint32_t dirty; + + struct nv04_blend_state *blend; + struct nv04_sampler_state *sampler[PIPE_MAX_SAMPLERS]; + struct nv04_fragtex_state fragtex; + struct nv04_rasterizer_state *rast; + struct nv04_depth_stencil_alpha_state *dsa; + + struct nv04_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; + unsigned dirty_samplers; + unsigned fp_samplers; + unsigned vp_samplers; + + uint32_t rt_enable; + struct pipe_buffer *rt[4]; + struct pipe_buffer *zeta; + + struct { + struct pipe_buffer *buffer; + uint32_t format; + } tex[16]; + + unsigned vb_enable; + struct { + struct pipe_buffer *buffer; + unsigned delta; + } vb[16]; + + struct vertex_info vertex_info; + struct { + + struct nouveau_resource *exec_heap; + struct nouveau_resource *data_heap; + + struct nv04_vertex_program *active; + + struct nv04_vertex_program *current; + struct pipe_buffer *constant_buf; + } vertprog; + + struct { + struct nv04_fragment_program *active; + + struct nv04_fragment_program *current; + struct pipe_buffer *constant_buf; + } fragprog; + + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned num_vertex_buffers; + unsigned num_vertex_elements; + + struct pipe_viewport_state viewport; +}; + +static INLINE struct nv04_context * +nv04_context(struct pipe_context *pipe) +{ + return (struct nv04_context *)pipe; +} + +extern void nv04_init_state_functions(struct nv04_context *nv04); +extern void nv04_init_surface_functions(struct nv04_context *nv04); +extern void nv04_init_miptree_functions(struct pipe_screen *screen); + +/* nv04_clear.c */ +extern void nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps, + unsigned clearValue); + +/* nv04_draw.c */ +extern struct draw_stage *nv04_draw_render_stage(struct nv04_context *nv04); + +/* nv04_fragprog.c */ +extern void nv04_fragprog_bind(struct nv04_context *, + struct nv04_fragment_program *); +extern void nv04_fragprog_destroy(struct nv04_context *, + struct nv04_fragment_program *); + +/* nv04_fragtex.c */ +extern void nv04_fragtex_bind(struct nv04_context *); + +/* nv04_prim_vbuf.c */ +struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 ); + +/* nv04_state.c and friends */ +extern void nv04_emit_hw_state(struct nv04_context *nv04); +extern void nv04_state_tex_update(struct nv04_context *nv04); + +/* nv04_vbo.c */ +extern boolean nv04_draw_arrays(struct pipe_context *, unsigned mode, + unsigned start, unsigned count); +extern boolean nv04_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count); + + +#endif diff --git a/src/gallium/drivers/nv04/nv04_fragprog.c b/src/gallium/drivers/nv04/nv04_fragprog.c new file mode 100644 index 0000000000..11f4360ed8 --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_fragprog.c @@ -0,0 +1,22 @@ +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "pipe/p_shader_tokens.h" +#include "tgsi/util/tgsi_parse.h" +#include "tgsi/util/tgsi_util.h" + +#include "nv04_context.h" + +void +nv04_fragprog_bind(struct nv04_context *nv04, struct nv04_fragment_program *fp) +{ +} + +void +nv04_fragprog_destroy(struct nv04_context *nv04, + struct nv04_fragment_program *fp) +{ +} + diff --git a/src/gallium/drivers/nv04/nv04_fragtex.c b/src/gallium/drivers/nv04/nv04_fragtex.c new file mode 100644 index 0000000000..3db673cd2c --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_fragtex.c @@ -0,0 +1,100 @@ +#include "nv04_context.h" + +static INLINE int log2i(int i) +{ + int r = 0; + + if (i & 0xffff0000) { + i >>= 16; + r += 16; + } + if (i & 0x0000ff00) { + i >>= 8; + r += 8; + } + if (i & 0x000000f0) { + i >>= 4; + r += 4; + } + if (i & 0x0000000c) { + i >>= 2; + r += 2; + } + if (i & 0x00000002) { + r += 1; + } + return r; +} + +#define _(m,tf) \ +{ \ + PIPE_FORMAT_##m, \ + NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_##tf, \ +} + +struct nv04_texture_format { + uint pipe; + int format; +}; + +static struct nv04_texture_format +nv04_texture_formats[] = { + _(A8R8G8B8_UNORM, A8R8G8B8), + _(X8R8G8B8_UNORM, X8R8G8B8), + _(A1R5G5B5_UNORM, A1R5G5B5), + _(A4R4G4B4_UNORM, A4R4G4B4), + _(L8_UNORM, Y8 ), + _(A8_UNORM, Y8 ), +}; + +static uint32_t +nv04_fragtex_format(uint pipe_format) +{ + struct nv04_texture_format *tf = nv04_texture_formats; + char fs[128]; + int i; + + for (i=0; i< sizeof(nv04_texture_formats)/sizeof(nv04_texture_formats[0]); i++) { + if (tf->pipe == pipe_format) + return tf->format; + tf++; + } + + pf_sprint_name(fs, pipe_format); + NOUVEAU_ERR("unknown texture format %s\n", fs); + return 0; +} + + +static void +nv04_fragtex_build(struct nv04_context *nv04, int unit) +{ + struct nv04_miptree *nv04mt = nv04->tex_miptree[unit]; + struct pipe_texture *pt = &nv04mt->base; + + switch (pt->target) { + case PIPE_TEXTURE_2D: + break; + default: + NOUVEAU_ERR("Unknown target %d\n", pt->target); + return; + } + + nv04->fragtex.format = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER + | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER + | nv04_fragtex_format(pt->format) + | ( (pt->last_level + 1) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT ) + | ( log2i(pt->width[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT ) + | ( log2i(pt->height[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT ) + | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE + | NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE + ; +} + + +void +nv04_fragtex_bind(struct nv04_context *nv04) +{ + nv04_fragtex_build(nv04, 0); +} + diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c new file mode 100644 index 0000000000..ab2d2386be --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -0,0 +1,138 @@ +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" + +#include "nv04_context.h" +#include "nv04_screen.h" + +static void +nv04_miptree_layout(struct nv04_miptree *nv04mt) +{ + struct pipe_texture *pt = &nv04mt->base; + uint width = pt->width[0], height = pt->height[0]; + uint offset = 0; + int nr_faces, l, f; + + nr_faces = 1; + + for (l = 0; l <= pt->last_level; l++) { + pt->width[l] = width; + pt->height[l] = height; + + pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width); + pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height); + + nv04mt->level[l].pitch = pt->width[0] * pt->block.size; + nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63; + + nv04mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); + + width = MAX2(1, width >> 1); + height = MAX2(1, height >> 1); + + } + + for (f = 0; f < nr_faces; f++) { + for (l = 0; l <= pt->last_level; l++) { + nv04mt->level[l].image_offset[f] = offset; + offset += nv04mt->level[l].pitch * pt->height[l]; + } + } + + nv04mt->total_size = offset; +} + +static struct pipe_texture * +nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) +{ + struct pipe_winsys *ws = screen->winsys; + struct nv04_miptree *mt; + + mt = MALLOC(sizeof(struct nv04_miptree)); + if (!mt) + return NULL; + mt->base = *pt; + mt->base.refcount = 1; + mt->base.screen = screen; + + nv04_miptree_layout(mt); + + mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, + mt->total_size); + if (!mt->buffer) { + free(mt); + return NULL; + } + + return &mt->base; +} + +static void +nv04_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) +{ + struct pipe_winsys *ws = screen->winsys; + struct pipe_texture *mt = *pt; + + *pt = NULL; + if (--mt->refcount <= 0) { + struct nv04_miptree *nv04mt = (struct nv04_miptree *)mt; + int l; + + pipe_buffer_reference(ws, &nv04mt->buffer, NULL); + for (l = 0; l <= mt->last_level; l++) { + if (nv04mt->level[l].image_offset) + free(nv04mt->level[l].image_offset); + } + free(nv04mt); + } +} + +static struct pipe_surface * +nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt, + unsigned face, unsigned level, unsigned zslice, + unsigned flags) +{ + struct pipe_winsys *ws = pscreen->winsys; + struct nv04_miptree *nv04mt = (struct nv04_miptree *)pt; + struct pipe_surface *ps; + + ps = ws->surface_alloc(ws); + if (!ps) + return NULL; + pipe_buffer_reference(ws, &ps->buffer, nv04mt->buffer); + ps->format = pt->format; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->block = pt->block; + ps->width = pt->width[level]; + ps->height = pt->height[level]; + ps->nblocksx = pt->nblocksx[level]; + ps->nblocksy = pt->nblocksy[level]; + ps->stride = nv04mt->level[level].pitch; + + if (pt->target == PIPE_TEXTURE_CUBE) { + ps->offset = nv04mt->level[level].image_offset[face]; + } else { + ps->offset = nv04mt->level[level].image_offset[0]; + } + + return ps; +} + +static void +nv04_miptree_surface_del(struct pipe_screen *pscreen, + struct pipe_surface **psurface) +{ +} + +void +nv04_init_miptree_functions(struct pipe_screen *pscreen) +{ + pscreen->texture_create = nv04_miptree_create; + pscreen->texture_release = nv04_miptree_release; + pscreen->get_tex_surface = nv04_miptree_surface_new; + pscreen->tex_surface_release = nv04_miptree_surface_del; +} + diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c new file mode 100644 index 0000000000..daf28e81f5 --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_prim_vbuf.c @@ -0,0 +1,312 @@ + +// XXX this has to go somewhere else +#define NONINC_METHOD 0x40000000 + + +#include "draw/draw_vbuf.h" +#include "pipe/p_debug.h" +#include "pipe/p_util.h" +#include "pipe/p_inlines.h" +#include "pipe/p_winsys.h" + +#include "nv04_context.h" +#include "nv04_state.h" + +#define VERTEX_SIZE 40 +#define VERTEX_BUFFER_SIZE (4096*VERTEX_SIZE) // 4096 vertices of 40 bytes each + +/** + * Primitive renderer for nv04. + */ +struct nv04_vbuf_render { + struct vbuf_render base; + + struct nv04_context *nv04; + + /** Vertex buffer */ + unsigned char* buffer; + + /** Vertex size in bytes */ + unsigned vertex_size; + + /** Current primitive */ + unsigned prim; +}; + + +/** + * Basically a cast wrapper. + */ +static INLINE struct nv04_vbuf_render * +nv04_vbuf_render( struct vbuf_render *render ) +{ + assert(render); + return (struct nv04_vbuf_render *)render; +} + + +static const struct vertex_info * +nv04_vbuf_render_get_vertex_info( struct vbuf_render *render ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + struct nv04_context *nv04 = nv04_render->nv04; + return &nv04->vertex_info; +} + + +static void * +nv04_vbuf_render_allocate_vertices( struct vbuf_render *render, + ushort vertex_size, + ushort nr_vertices ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + nv04_render->buffer = (unsigned char*) malloc(VERTEX_BUFFER_SIZE); + assert(!nv04_render->buffer); + + return nv04_render->buffer; +} + + +static boolean +nv04_vbuf_render_set_primitive( struct vbuf_render *render, + unsigned prim ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + if (prim <= PIPE_PRIM_LINE_STRIP) + return FALSE; + + nv04_render->prim = prim; + return TRUE; +} + +static INLINE void nv04_2triangles(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5) +{ + BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49); + OUT_RINGp(buffer + VERTEX_SIZE * v0,8); + OUT_RINGp(buffer + VERTEX_SIZE * v1,8); + OUT_RINGp(buffer + VERTEX_SIZE * v2,8); + OUT_RINGp(buffer + VERTEX_SIZE * v3,8); + OUT_RINGp(buffer + VERTEX_SIZE * v4,8); + OUT_RINGp(buffer + VERTEX_SIZE * v5,8); + OUT_RING(0xFEDCBA); +} + +static INLINE void nv04_1triangle(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2) +{ + BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25); + OUT_RINGp(buffer + VERTEX_SIZE * v0,8); + OUT_RINGp(buffer + VERTEX_SIZE * v1,8); + OUT_RINGp(buffer + VERTEX_SIZE * v2,8); + OUT_RING(0xFED); +} + +static INLINE void nv04_1quad(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3) +{ + BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33); + OUT_RINGp(buffer + VERTEX_SIZE * v0,8); + OUT_RINGp(buffer + VERTEX_SIZE * v1,8); + OUT_RINGp(buffer + VERTEX_SIZE * v2,8); + OUT_RINGp(buffer + VERTEX_SIZE * v3,8); + OUT_RING(0xFECEDC); +} + +static void nv04_vbuf_render_triangles_elts(struct nv04_vbuf_render * render, const ushort * indices, uint nr_indices) +{ + unsigned char* buffer = render->buffer; + struct nv04_context* nv04 = render->nv04; + int i; + + for( i=0; i< nr_indices-5; i+=6) + nv04_2triangles(nv04, + buffer, + indices[i+0], + indices[i+1], + indices[i+2], + indices[i+3], + indices[i+4], + indices[i+5] + ); + if (i != nr_indices) + { + nv04_1triangle(nv04, + buffer, + indices[i+0], + indices[i+1], + indices[i+2] + ); + i+=3; + } + if (i != nr_indices) + NOUVEAU_ERR("Houston, we have lost some vertices\n"); +} + +static void nv04_vbuf_render_tri_strip_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices) +{ + const uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC}; + unsigned char* buffer = render->buffer; + struct nv04_context* nv04 = render->nv04; + int i,j; + + for(i = 0; ibuffer; + struct nv04_context* nv04 = render->nv04; + int i,j; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8); + OUT_RINGp(buffer + VERTEX_SIZE * indices[0], 8); + + for(i = 1; ibuffer; + struct nv04_context* nv04 = render->nv04; + int i; + + for(i = 0; i < nr_indices; i += 4) + nv04_1quad(nv04, + buffer, + indices[i+0], + indices[i+1], + indices[i+2], + indices[i+3] + ); +} + + +static void +nv04_vbuf_render_draw( struct vbuf_render *render, + const ushort *indices, + uint nr_indices) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + // emit the indices + switch( nv04_render->prim ) + { + case PIPE_PRIM_TRIANGLES: + nv04_vbuf_render_triangles_elts(nv04_render, indices, nr_indices); + break; + case PIPE_PRIM_QUAD_STRIP: + case PIPE_PRIM_TRIANGLE_STRIP: + nv04_vbuf_render_tri_strip_elts(nv04_render, indices, nr_indices); + break; + case PIPE_PRIM_TRIANGLE_FAN: + case PIPE_PRIM_POLYGON: + nv04_vbuf_render_tri_fan_elts(nv04_render, indices, nr_indices); + break; + case PIPE_PRIM_QUADS: + nv04_vbuf_render_quads_elts(nv04_render, indices, nr_indices); + break; + default: + NOUVEAU_ERR("You have to implement primitive %d, young padawan\n", nv04_render->prim); + break; + } +} + + +static void +nv04_vbuf_render_release_vertices( struct vbuf_render *render, + void *vertices, + unsigned vertex_size, + unsigned vertices_used ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + + free(nv04_render->buffer); + nv04_render->buffer = NULL; +} + + +static void +nv04_vbuf_render_destroy( struct vbuf_render *render ) +{ + struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); + FREE(nv04_render); +} + + +/** + * Create a new primitive render. + */ +static struct vbuf_render * +nv04_vbuf_render_create( struct nv04_context *nv04 ) +{ + struct nv04_vbuf_render *nv04_render = CALLOC_STRUCT(nv04_vbuf_render); + + nv04_render->nv04 = nv04; + + nv04_render->base.max_vertex_buffer_bytes = VERTEX_BUFFER_SIZE; + nv04_render->base.max_indices = 65536; + nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info; + nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices; + nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive; + nv04_render->base.draw = nv04_vbuf_render_draw; + nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices; + nv04_render->base.destroy = nv04_vbuf_render_destroy; + + return &nv04_render->base; +} + + +/** + * Create a new primitive vbuf/render stage. + */ +struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 ) +{ + struct vbuf_render *render; + struct draw_stage *stage; + + render = nv04_vbuf_render_create(nv04); + if(!render) + return NULL; + + stage = draw_vbuf_stage( nv04->draw, render ); + if(!stage) { + render->destroy(render); + return NULL; + } + + return stage; +} diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c new file mode 100644 index 0000000000..9f34117b8c --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_screen.c @@ -0,0 +1,216 @@ +#include "pipe/p_screen.h" +#include "pipe/p_util.h" + +#include "nv04_context.h" +#include "nv04_screen.h" + +static const char * +nv04_screen_get_name(struct pipe_screen *screen) +{ + struct nv04_screen *nv04screen = nv04_screen(screen); + struct nouveau_device *dev = nv04screen->nvws->channel->device; + static char buffer[128]; + + snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset); + return buffer; +} + +static const char * +nv04_screen_get_vendor(struct pipe_screen *screen) +{ + return "nouveau"; +} + +static int +nv04_screen_get_param(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + return 1; + case PIPE_CAP_NPOT_TEXTURES: + return 0; + case PIPE_CAP_TWO_SIDED_STENCIL: + return 0; + case PIPE_CAP_GLSL: + return 0; + case PIPE_CAP_S3TC: + return 0; + case PIPE_CAP_ANISOTROPIC_FILTER: + return 0; + case PIPE_CAP_POINT_SPRITE: + return 0; + case PIPE_CAP_MAX_RENDER_TARGETS: + return 1; + case PIPE_CAP_OCCLUSION_QUERY: + return 0; + case PIPE_CAP_TEXTURE_SHADOW_MAP: + return 0; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + return 10; + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + return 0; + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0; + } +} + +static float +nv04_screen_get_paramf(struct pipe_screen *screen, int param) +{ + switch (param) { + case PIPE_CAP_MAX_LINE_WIDTH: + case PIPE_CAP_MAX_LINE_WIDTH_AA: + return 0.0; + case PIPE_CAP_MAX_POINT_WIDTH: + case PIPE_CAP_MAX_POINT_WIDTH_AA: + return 0.0; + case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: + return 0.0; + case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: + return 0.0; + default: + NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); + return 0.0; + } +} + +static boolean +nv04_screen_is_format_supported(struct pipe_screen *screen, + enum pipe_format format, uint type) +{ + switch (type) { + case PIPE_SURFACE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_Z16_UNORM: + return TRUE; + default: + break; + } + break; + case PIPE_TEXTURE: + switch (format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_A8_UNORM: + return TRUE; + default: + break; + } + break; + default: + assert(0); + }; + + return FALSE; +} + +static void * +nv04_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, + unsigned flags ) +{ + struct pipe_winsys *ws = screen->winsys; + void *map; + + map = ws->buffer_map(ws, surface->buffer, flags); + if (!map) + return NULL; + + return map + surface->offset; +} + +static void +nv04_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) +{ + struct pipe_winsys *ws = screen->winsys; + + ws->buffer_unmap(ws, surface->buffer); +} + +static void +nv04_screen_destroy(struct pipe_screen *pscreen) +{ + struct nv04_screen *screen = nv04_screen(pscreen); + struct nouveau_winsys *nvws = screen->nvws; + + nvws->notifier_free(&screen->sync); + nvws->grobj_free(&screen->fahrenheit); + + FREE(pscreen); +} + +struct pipe_screen * +nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) +{ + struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen); + unsigned fahrenheit_class = 0, sub3d_class = 0; + unsigned chipset = nvws->channel->device->chipset; + int ret; + + if (!screen) + return NULL; + screen->nvws = nvws; + + if (chipset>=0x20) { + fahrenheit_class = 0; + sub3d_class = 0; + } else if (chipset>=0x10) { + fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE; + sub3d_class = NV10_CONTEXT_SURFACES_3D; + } else { + fahrenheit_class=NV04_DX5_TEXTURED_TRIANGLE; + sub3d_class = NV04_CONTEXT_SURFACES_3D; + } + + if (!fahrenheit_class) { + NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", chipset); + return NULL; + } + + /* 3D object */ + ret = nvws->grobj_alloc(nvws, fahrenheit_class, &screen->fahrenheit); + if (ret) { + NOUVEAU_ERR("Error creating 3D object: %d\n", ret); + return NULL; + } + + /* 3D surface object */ + ret = nvws->grobj_alloc(nvws, sub3d_class, &screen->context_surfaces_3d); + if (ret) { + NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret); + return NULL; + } + + /* Notifier for sync purposes */ + ret = nvws->notifier_alloc(nvws, 1, &screen->sync); + if (ret) { + NOUVEAU_ERR("Error creating notifier object: %d\n", ret); + nv04_screen_destroy(&screen->pipe); + return NULL; + } + + screen->pipe.winsys = ws; + screen->pipe.destroy = nv04_screen_destroy; + + screen->pipe.get_name = nv04_screen_get_name; + screen->pipe.get_vendor = nv04_screen_get_vendor; + screen->pipe.get_param = nv04_screen_get_param; + screen->pipe.get_paramf = nv04_screen_get_paramf; + + screen->pipe.is_format_supported = nv04_screen_is_format_supported; + + screen->pipe.surface_map = nv04_surface_map; + screen->pipe.surface_unmap = nv04_surface_unmap; + + nv04_screen_init_miptree_functions(&screen->pipe); + + return &screen->pipe; +} + diff --git a/src/gallium/drivers/nv04/nv04_screen.h b/src/gallium/drivers/nv04/nv04_screen.h new file mode 100644 index 0000000000..99a49cdf7a --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_screen.h @@ -0,0 +1,25 @@ +#ifndef __NV04_SCREEN_H__ +#define __NV04_SCREEN_H__ + +#include "pipe/p_screen.h" + +struct nv04_screen { + struct pipe_screen pipe; + + struct nouveau_winsys *nvws; + unsigned chipset; + + /* HW graphics objects */ + struct nouveau_grobj *fahrenheit; + struct nouveau_grobj *context_surfaces_3d; + struct nouveau_notifier *sync; + +}; + +static INLINE struct nv04_screen * +nv04_screen(struct pipe_screen *screen) +{ + return (struct nv04_screen *)screen; +} + +#endif diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c new file mode 100644 index 0000000000..39d7e8b42d --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_state.c @@ -0,0 +1,494 @@ +#include "draw/draw_context.h" +#include "pipe/p_state.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_shader_tokens.h" + + +#include "nv04_context.h" +#include "nv04_state.h" + +static void * +nv04_blend_state_create(struct pipe_context *pipe, + const struct pipe_blend_state *cso) +{ + struct nv04_blend_state *cb; + + cb = malloc(sizeof(struct nv04_blend_state)); + + cb->b_enable = cso->blend_enable ? 1 : 0; + cb->b_src = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | + (nvgl_blend_func(cso->rgb_src_factor))); + cb->b_dst = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | + (nvgl_blend_func(cso->rgb_dst_factor))); + + + return (void *)cb; +} + +static void +nv04_blend_state_bind(struct pipe_context *pipe, void *blend) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->blend = (struct nv04_blend_state*)blend; + + nv04->dirty |= NV04_NEW_BLEND; +} + +static void +nv04_blend_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + + +static INLINE unsigned +wrap_mode(unsigned wrap) { + unsigned ret; + + switch (wrap) { + case PIPE_TEX_WRAP_REPEAT: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT; + break; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT; + break; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE; + break; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER; + break; + case PIPE_TEX_WRAP_CLAMP: + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP; + break; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + case PIPE_TEX_WRAP_MIRROR_CLAMP: + default: + NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); + ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP; + } + return ret >> NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT; +} + +static void * +nv04_sampler_state_create(struct pipe_context *pipe, + const struct pipe_sampler_state *cso) +{ + + struct nv04_sampler_state *ss; + uint32_t filter = 0; + + ss = malloc(sizeof(struct nv04_sampler_state)); + + ss->format = ((wrap_mode(cso->wrap_s) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) | + (wrap_mode(cso->wrap_t) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT)); + + if (cso->max_anisotropy > 1.0) { + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE; + } + + switch (cso->mag_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR; + break; + case PIPE_TEX_FILTER_NEAREST: + default: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST; + break; + } + + switch (cso->min_img_filter) { + case PIPE_TEX_FILTER_LINEAR: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR; + break; + } + break; + case PIPE_TEX_FILTER_NEAREST: + default: + switch (cso->min_mip_filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; + break; + case PIPE_TEX_MIPFILTER_LINEAR: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; + break; + case PIPE_TEX_MIPFILTER_NONE: + default: + filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST; + break; + } + break; + } + + ss->filter = filter; + + return (void *)ss; +} + +static void +nv04_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) +{ + struct nv04_context *nv04 = nv04_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv04->sampler[unit] = sampler[unit]; + nv04->dirty_samplers |= (1 << unit); + } +} + +static void +nv04_sampler_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void +nv04_set_sampler_texture(struct pipe_context *pipe, unsigned nr, + struct pipe_texture **miptree) +{ + struct nv04_context *nv04 = nv04_context(pipe); + unsigned unit; + + for (unit = 0; unit < nr; unit++) { + nv04->tex_miptree[unit] = (struct nv04_miptree *)miptree[unit]; + nv04->dirty_samplers |= (1 << unit); + } +} + +static void * +nv04_rasterizer_state_create(struct pipe_context *pipe, + const struct pipe_rasterizer_state *cso) +{ + struct nv04_rasterizer_state *rs; + + /*XXX: ignored: + * scissor + * points/lines (no hw support, emulated with tris in gallium) + */ + rs = malloc(sizeof(struct nv04_rasterizer_state)); + + rs->blend = cso->flatshade ? NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + + return (void *)rs; +} + +static void +nv04_rasterizer_state_bind(struct pipe_context *pipe, void *rast) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->rast = (struct nv04_rasterizer_state*)rast; + + draw_set_rasterizer_state(nv04->draw, (nv04->rast ? nv04->rast->templ : NULL)); + + nv04->dirty |= NV04_NEW_RAST | NV04_NEW_BLEND; +} + +static void +nv04_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static INLINE uint32_t nv04_compare_func(uint32_t f) +{ + switch ( f ) { + case PIPE_FUNC_NEVER: return 1; + case PIPE_FUNC_LESS: return 2; + case PIPE_FUNC_EQUAL: return 3; + case PIPE_FUNC_LEQUAL: return 4; + case PIPE_FUNC_GREATER: return 5; + case PIPE_FUNC_NOTEQUAL: return 6; + case PIPE_FUNC_GEQUAL: return 7; + case PIPE_FUNC_ALWAYS: return 8; + } + NOUVEAU_MSG("Unable to find the function\n"); + return 0; +} + +static void * +nv04_depth_stencil_alpha_state_create(struct pipe_context *pipe, + const struct pipe_depth_stencil_alpha_state *cso) +{ + struct nv04_depth_stencil_alpha_state *hw; + + hw = malloc(sizeof(struct nv04_depth_stencil_alpha_state)); + + hw->control = float_to_ubyte(cso->alpha.ref); + hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT ); + hw->control |= cso->alpha.enabled ? NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_TEST_ENABLE : 0; + hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ORIGIN; + hw->control |= cso->depth.enabled ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_SHIFT) : 0; + hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT ); + hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module + hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; + hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE; + hw->control |= cso->depth.writemask ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_SHIFT) : 0; + hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT; // integer zbuffer format + + return (void *)hw; +} + +static void +nv04_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->dsa = hwcso; + nv04->dirty |= NV04_NEW_CONTROL; +} + +static void +nv04_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) +{ + free(hwcso); +} + +static void * +nv04_vp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *templ) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + return draw_create_vertex_shader(nv04->draw, templ); +} + +static void +nv04_vp_state_bind(struct pipe_context *pipe, void *shader) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_bind_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader); + + nv04->dirty |= NV04_NEW_VERTPROG; +} + +static void +nv04_vp_state_delete(struct pipe_context *pipe, void *shader) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_delete_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader); +} + +static void * +nv04_fp_state_create(struct pipe_context *pipe, + const struct pipe_shader_state *cso) +{ + struct nv04_fragment_program *fp; + + fp = CALLOC(1, sizeof(struct nv04_fragment_program)); + fp->pipe = cso; + + return (void *)fp; +} + +static void +nv04_fp_state_bind(struct pipe_context *pipe, void *hwcso) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nv04_fragment_program *fp = hwcso; + + nv04->fragprog.current = fp; + nv04->dirty |= NV04_NEW_FRAGPROG; +} + +static void +nv04_fp_state_delete(struct pipe_context *pipe, void *hwcso) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nv04_fragment_program *fp = hwcso; + + nv04_fragprog_destroy(nv04, fp); + free(fp); +} + +static void +nv04_set_blend_color(struct pipe_context *pipe, + const struct pipe_blend_color *bcol) +{ +} + +static void +nv04_set_clip_state(struct pipe_context *pipe, + const struct pipe_clip_state *clip) +{ +} + +static void +nv04_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, + const struct pipe_constant_buffer *buf ) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + if (shader == PIPE_SHADER_VERTEX) { + nv04->vertprog.constant_buf = buf->buffer; + nv04->dirty |= NV04_NEW_VERTPROG; + } else + if (shader == PIPE_SHADER_FRAGMENT) { + nv04->fragprog.constant_buf = buf->buffer; + nv04->dirty |= NV04_NEW_FRAGPROG; + } +} + +static void +nv04_set_framebuffer_state(struct pipe_context *pipe, + const struct pipe_framebuffer_state *fb) +{ + struct nv04_context *nv04 = nv04_context(pipe); + 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; + } + + switch (colour_format) { + case PIPE_FORMAT_A8R8G8B8_UNORM: + case 0: + rt_format = 0x108; + break; + case PIPE_FORMAT_R5G6B5_UNORM: + rt_format = 0x103; + break; + default: + assert(0); + } + + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + OUT_RING(rt_format); + + /* FIXME pitches have to be aligned ! */ + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(rt->stride|(zeta->stride<<16)); + OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + if (fb->zsbuf) { + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + } +} + +static void +nv04_set_polygon_stipple(struct pipe_context *pipe, + const struct pipe_poly_stipple *stipple) +{ + NOUVEAU_ERR("line stipple hahaha\n"); +} + +static void +nv04_set_scissor_state(struct pipe_context *pipe, + const struct pipe_scissor_state *s) +{ +/* struct nv04_context *nv04 = nv04_context(pipe); + + // XXX + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2); + OUT_RING (((s->maxx - s->minx) << 16) | s->minx); + OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ +} + +static void +nv04_set_viewport_state(struct pipe_context *pipe, + const struct pipe_viewport_state *viewport) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + nv04->viewport = *viewport; + + draw_set_viewport_state(nv04->draw, &nv04->viewport); +} + +static void +nv04_set_vertex_buffers(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_flush(nv04->draw); + + memcpy(nv04->vertex_buffer, buffers, count * sizeof(buffers[0])); + nv04->num_vertex_buffers = count; + + draw_set_vertex_buffers(nv04->draw, count, buffers); +} + +static void +nv04_set_vertex_elements(struct pipe_context *pipe, unsigned count, + const struct pipe_vertex_element *elements) +{ + struct nv04_context *nv04 = nv04_context(pipe); + + draw_flush(nv04->draw); + + nv04->num_vertex_elements = count; + draw_set_vertex_elements(nv04->draw, count, elements); +} + +void +nv04_init_state_functions(struct nv04_context *nv04) +{ + nv04->pipe.create_blend_state = nv04_blend_state_create; + nv04->pipe.bind_blend_state = nv04_blend_state_bind; + nv04->pipe.delete_blend_state = nv04_blend_state_delete; + + nv04->pipe.create_sampler_state = nv04_sampler_state_create; + nv04->pipe.bind_sampler_states = nv04_sampler_state_bind; + nv04->pipe.delete_sampler_state = nv04_sampler_state_delete; + nv04->pipe.set_sampler_textures = nv04_set_sampler_texture; + + nv04->pipe.create_rasterizer_state = nv04_rasterizer_state_create; + nv04->pipe.bind_rasterizer_state = nv04_rasterizer_state_bind; + nv04->pipe.delete_rasterizer_state = nv04_rasterizer_state_delete; + + nv04->pipe.create_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_create; + nv04->pipe.bind_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_bind; + nv04->pipe.delete_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_delete; + + nv04->pipe.create_vs_state = nv04_vp_state_create; + nv04->pipe.bind_vs_state = nv04_vp_state_bind; + nv04->pipe.delete_vs_state = nv04_vp_state_delete; + + nv04->pipe.create_fs_state = nv04_fp_state_create; + nv04->pipe.bind_fs_state = nv04_fp_state_bind; + nv04->pipe.delete_fs_state = nv04_fp_state_delete; + + nv04->pipe.set_blend_color = nv04_set_blend_color; + nv04->pipe.set_clip_state = nv04_set_clip_state; + nv04->pipe.set_constant_buffer = nv04_set_constant_buffer; + nv04->pipe.set_framebuffer_state = nv04_set_framebuffer_state; + nv04->pipe.set_polygon_stipple = nv04_set_polygon_stipple; + nv04->pipe.set_scissor_state = nv04_set_scissor_state; + nv04->pipe.set_viewport_state = nv04_set_viewport_state; + + nv04->pipe.set_vertex_buffers = nv04_set_vertex_buffers; + nv04->pipe.set_vertex_elements = nv04_set_vertex_elements; +} + diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h new file mode 100644 index 0000000000..7487819c3a --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_state.h @@ -0,0 +1,71 @@ +#ifndef __NV04_STATE_H__ +#define __NV04_STATE_H__ + +#include "pipe/p_state.h" +#include "tgsi/util/tgsi_scan.h" + +struct nv04_blend_state { + uint32_t b_enable; + uint32_t b_src; + uint32_t b_dst; +}; + +struct nv04_fragtex_state { + uint32_t format; +}; + +struct nv04_sampler_state { + uint32_t filter; + uint32_t format; +}; + +struct nv04_depth_stencil_alpha_state { + uint32_t control; +}; + +struct nv04_rasterizer_state { + uint32_t blend; + + const struct pipe_rasterizer_state *templ; +}; + +struct nv04_miptree { + struct pipe_texture base; + + struct pipe_buffer *buffer; + uint total_size; + + struct { + uint pitch; + uint *image_offset; + } level[PIPE_MAX_TEXTURE_LEVELS]; +}; + +struct nv04_fragment_program_data { + unsigned offset; + unsigned index; +}; + +struct nv04_fragment_program { + const struct pipe_shader_state *pipe; + struct tgsi_shader_info info; + + boolean translated; + boolean on_hw; + unsigned samplers; + + uint32_t *insn; + int insn_len; + + struct nv04_fragment_program_data *consts; + unsigned nr_consts; + + struct pipe_buffer *buffer; + + uint32_t fp_control; + uint32_t fp_reg_control; +}; + + + +#endif diff --git a/src/gallium/drivers/nv04/nv04_state_emit.c b/src/gallium/drivers/nv04/nv04_state_emit.c new file mode 100644 index 0000000000..0ad40a092e --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_state_emit.c @@ -0,0 +1,156 @@ +#include "nv04_context.h" +#include "nv04_state.h" + +static void nv04_vertex_layout(struct pipe_context* pipe) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nv04_fragment_program *fp = nv04->fragprog.current; + uint32_t src = 0; + int i; + struct vertex_info vinfo; + + memset(&vinfo, 0, sizeof(vinfo)); + + for (i = 0; i < fp->info.num_inputs; i++) { + switch (i) { + case TGSI_SEMANTIC_POSITION: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + case TGSI_SEMANTIC_COLOR: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); + break; + default: + case TGSI_SEMANTIC_GENERIC: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + case TGSI_SEMANTIC_FOG: + draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); + break; + } + } + draw_compute_vertex_size(&vinfo); +} + +static uint32_t nv04_blend_func(uint32_t f) +{ + switch ( f ) { + case PIPE_BLENDFACTOR_ZERO: return 0x1; + case PIPE_BLENDFACTOR_ONE: return 0x2; + case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4; + case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6; + case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8; + case PIPE_BLENDFACTOR_DST_COLOR: return 0x9; + case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB; + } + NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f); + return 0; +} + +static void nv04_emit_control(struct nv04_context* nv04) +{ + uint32_t control = nv04->dsa->control; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(control); +} + +static void nv04_emit_blend(struct nv04_context* nv04) +{ + uint32_t blend; + + blend=0x4; // texture MODULATE_ALPHA + blend|=0x20; // alpha is MSB + blend|=(2<<6); // flat shading + blend|=(1<<8); // persp correct + blend|=(0<<16); // no fog + blend|=(nv04->blend->b_enable<<20); + blend|=(nv04_blend_func(nv04->blend->b_src)<<24); + blend|=(nv04_blend_func(nv04->blend->b_dst)<<28); + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING(blend); +} + +static void nv04_emit_sampler(struct nv04_context *nv04, int unit) +{ + struct nv04_miptree *nv04mt = nv04->tex_miptree[unit]; + struct pipe_texture *pt = &nv04mt->base; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 3); + OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); + OUT_RING(nv04->sampler[unit]->filter); +} + +void +nv04_emit_hw_state(struct nv04_context *nv04) +{ + int i; + + if (nv04->dirty & NV04_NEW_VERTPROG) { + //nv04_vertprog_bind(nv04, nv04->vertprog.current); + nv04->dirty &= ~NV04_NEW_VERTPROG; + } + + if (nv04->dirty & NV04_NEW_FRAGPROG) { + nv04_fragprog_bind(nv04, nv04->fragprog.current); + /*XXX: clear NV04_NEW_FRAGPROG if no new program uploaded */ + nv04->dirty_samplers |= (1<<10); + nv04->dirty_samplers = 0; + } + + if (nv04->dirty & NV04_NEW_CONTROL) { + nv04->dirty &= ~NV04_NEW_CONTROL; + + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(nv04->dsa->control); + } + + if (nv04->dirty & NV04_NEW_BLEND) { + nv04->dirty &= ~NV04_NEW_BLEND; + + nv04_emit_blend(nv04); + } + + if (nv04->dirty & NV04_NEW_SAMPLER) { + nv04->dirty &= ~NV04_NEW_SAMPLER; + + nv04_emit_sampler(nv04, 0); + } + + if (nv04->dirty & NV04_NEW_VIEWPORT) { + nv04->dirty &= ~NV04_NEW_VIEWPORT; +// nv04_state_emit_viewport(nv04); + } + + /* Emit relocs for every referenced buffer. + * This is to ensure the bufmgr has an accurate idea of how + * the buffer is used. This isn't very efficient, but we don't + * seem to take a significant performance hit. Will be improved + * at some point. Vertex arrays are emitted by nv04_vbo.c + */ + + /* Render target */ +/* BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); + OUT_RING(rt->stride|(zeta->stride<<16)); + OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + if (fb->zsbuf) { + BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); + OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + }*/ + + /* Texture images */ + for (i = 0; i < 1; i++) { + if (!(nv04->fp_samplers & (1 << i))) + continue; + struct nv04_miptree *nv04mt = nv04->tex_miptree[i]; + BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2); + OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); + OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); + } +} + diff --git a/src/gallium/drivers/nv04/nv04_surface.c b/src/gallium/drivers/nv04/nv04_surface.c new file mode 100644 index 0000000000..b13ebf9f9b --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_surface.c @@ -0,0 +1,65 @@ + +/************************************************************************** + * + * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "nv04_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_util.h" +#include "pipe/p_winsys.h" +#include "pipe/p_inlines.h" +#include "util/p_tile.h" + +static void +nv04_surface_copy(struct pipe_context *pipe, unsigned do_flip, + struct pipe_surface *dest, unsigned destx, unsigned desty, + struct pipe_surface *src, unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nouveau_winsys *nvws = nv04->nvws; + + nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, + width, height); +} + +static void +nv04_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, + unsigned destx, unsigned desty, unsigned width, + unsigned height, unsigned value) +{ + struct nv04_context *nv04 = nv04_context(pipe); + struct nouveau_winsys *nvws = nv04->nvws; + + nvws->surface_fill(nvws, dest, destx, desty, width, height, value); +} + +void +nv04_init_surface_functions(struct nv04_context *nv04) +{ + nv04->pipe.surface_copy = nv04_surface_copy; + nv04->pipe.surface_fill = nv04_surface_fill; +} diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c new file mode 100644 index 0000000000..fbfe0cf406 --- /dev/null +++ b/src/gallium/drivers/nv04/nv04_vbo.c @@ -0,0 +1,72 @@ +#include "draw/draw_context.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_util.h" + +#include "nv04_context.h" +#include "nv04_state.h" + +#include "nouveau/nouveau_channel.h" +#include "nouveau/nouveau_pushbuf.h" + +boolean nv04_draw_elements( struct pipe_context *pipe, + struct pipe_buffer *indexBuffer, + unsigned indexSize, + unsigned prim, unsigned start, unsigned count) +{ + struct nv04_context *nv04 = nv04_context( pipe ); + struct draw_context *draw = nv04->draw; + unsigned i; + + /* + * Map vertex buffers + */ + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { + if (nv04->vertex_buffer[i].buffer) { + void *buf + = pipe->winsys->buffer_map(pipe->winsys, + nv04->vertex_buffer[i].buffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_vertex_buffer(draw, i, buf); + } + } + /* Map index buffer, if present */ + if (indexBuffer) { + void *mapped_indexes + = pipe->winsys->buffer_map(pipe->winsys, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); + } + else { + /* no index/element buffer */ + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + /* draw! */ + draw_arrays(nv04->draw, prim, start, count); + + /* + * unmap vertex/index buffers + */ + for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { + if (nv04->vertex_buffer[i].buffer) { + pipe->winsys->buffer_unmap(pipe->winsys, nv04->vertex_buffer[i].buffer); + draw_set_mapped_vertex_buffer(draw, i, NULL); + } + } + if (indexBuffer) { + pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); + draw_set_mapped_element_buffer(draw, 0, NULL); + } + + return TRUE; +} + +boolean nv04_draw_arrays( struct pipe_context *pipe, + unsigned prim, unsigned start, unsigned count) +{ + return nv04_draw_elements(pipe, NULL, 0, prim, start, count); +} + + + -- cgit v1.2.3 From 0da43322bbc6ead4eeb1b9fe079a33e0d57bece5 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Sat, 8 Nov 2008 18:32:33 +0200 Subject: Nouveau: build, link and use nv20. Signed-off-by: Pekka Paalanen --- configs/default | 2 +- src/gallium/drivers/nouveau/nouveau_winsys.h | 6 ++++++ src/gallium/winsys/drm/nouveau/Makefile | 1 + src/gallium/winsys/drm/nouveau/nouveau_winsys.c | 5 ++++- src/gallium/winsys/g3dvl/nouveau/Makefile | 3 ++- 5 files changed, 14 insertions(+), 3 deletions(-) (limited to 'configs') diff --git a/configs/default b/configs/default index 6c123cc3c5..7ea27b48ce 100644 --- a/configs/default +++ b/configs/default @@ -76,7 +76,7 @@ EGL_DRIVERS_DIRS = demo # Gallium directories and GALLIUM_AUXILIARY_DIRS = draw translate cso_cache pipebuffer tgsi sct rtasm util GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) -GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 nv10 nv30 nv40 nv50 failover +GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 nv10 nv20 nv30 nv40 nv50 failover GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) GALLIUM_WINSYS_DIRS = xlib egl_xlib diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index 48feeba309..a89b056244 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -69,6 +69,12 @@ nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); extern struct pipe_context * nv10_create(struct pipe_screen *, unsigned pctx_id); +extern struct pipe_screen * +nv20_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); + +extern struct pipe_context * +nv20_create(struct pipe_screen *, unsigned pctx_id); + extern struct pipe_screen * nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *); diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index be630ff6d1..81562ca78d 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -10,6 +10,7 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ $(TOP)/src/gallium/drivers/nv04/libnv04.a \ $(TOP)/src/gallium/drivers/nv10/libnv10.a \ + $(TOP)/src/gallium/drivers/nv20/libnv20.a \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a diff --git a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c index 0878840dcc..364340e1d3 100644 --- a/src/gallium/winsys/drm/nouveau/nouveau_winsys.c +++ b/src/gallium/winsys/drm/nouveau/nouveau_winsys.c @@ -101,10 +101,13 @@ nouveau_pipe_create(struct nouveau_context *nv) switch (chipset & 0xf0) { case 0x10: - case 0x20: hws_create = nv10_screen_create; hw_create = nv10_create; break; + case 0x20: + hws_create = nv20_screen_create; + hw_create = nv20_create; + break; case 0x30: hws_create = nv30_screen_create; hw_create = nv30_create; diff --git a/src/gallium/winsys/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 5d11bde322..ff43327778 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -26,11 +26,12 @@ LDFLAGS += -L${DRMDIR}/lib \ -L${GALLIUMDIR}/auxiliary/rtasm \ -L${GALLIUMDIR}/auxiliary/cso_cache \ -L${GALLIUMDIR}/drivers/nv10 \ + -L${GALLIUMDIR}/drivers/nv20 \ -L${GALLIUMDIR}/drivers/nv30 \ -L${GALLIUMDIR}/drivers/nv40 \ -L${GALLIUMDIR}/drivers/nv50 -LIBS += -ldriclient -ldrm -lnv10 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm +LIBS += -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm ############################################# -- cgit v1.2.3