diff options
118 files changed, 10855 insertions, 8682 deletions
diff --git a/configure.ac b/configure.ac index b6f71f90430..af5a5fdc4b7 100644 --- a/configure.ac +++ b/configure.ac @@ -1324,7 +1324,7 @@ AC_ARG_ENABLE([gallium-nouveau], [enable_gallium_nouveau=no]) if test "x$enable_gallium_nouveau" = xyes; then GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS nouveau" - GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv04 nv10 nv20 nv30 nv40 nv50" + GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nv30 nv40 nv50" fi dnl diff --git a/src/gallium/docs/source/distro.rst b/src/gallium/docs/source/distro.rst index 0fabb639ad3..100afe33972 100644 --- a/src/gallium/docs/source/distro.rst +++ b/src/gallium/docs/source/distro.rst @@ -31,21 +31,6 @@ Wrapper driver. LLVM Softpipe ^^^^^^^^^^^^^ -nVidia nv04 -^^^^^^^^^^^ - -Deprecated. - -nVidia nv10 -^^^^^^^^^^^ - -Deprecated. - -nVidia nv20 -^^^^^^^^^^^ - -Deprecated. - nVidia nv30 ^^^^^^^^^^^ diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile index 0cb66041d50..0e02680bc63 100644 --- a/src/gallium/drivers/nouveau/Makefile +++ b/src/gallium/drivers/nouveau/Makefile @@ -4,6 +4,7 @@ include $(TOP)/configs/current LIBNAME = nouveau C_SOURCES = nouveau_screen.c \ - nouveau_context.c + nouveau_context.c \ + nv04_surface_2d.c include ../../Makefile.template diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index d81c5be51f2..4c5d2f8b1c1 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -27,24 +27,6 @@ #define NOUVEAU_BUFFER_USAGE_NO_RENDER (1 << 19) extern struct pipe_screen * -nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *); - -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_device *); - -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_device *); - -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_device *); extern struct pipe_context * diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nouveau/nv04_surface_2d.c index 42c2ca932d8..42c2ca932d8 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.c +++ b/src/gallium/drivers/nouveau/nv04_surface_2d.c diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.h b/src/gallium/drivers/nouveau/nv04_surface_2d.h index ce696a11a39..ce696a11a39 100644 --- a/src/gallium/drivers/nv04/nv04_surface_2d.h +++ b/src/gallium/drivers/nouveau/nv04_surface_2d.h diff --git a/src/gallium/drivers/nv04/Makefile b/src/gallium/drivers/nv04/Makefile deleted file mode 100644 index 7c14bacb1de..00000000000 --- a/src/gallium/drivers/nv04/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = nv04 - -C_SOURCES = \ - nv04_surface_2d.c \ - 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_transfer.c \ - nv04_vbo.c - -include ../../Makefile.template diff --git a/src/gallium/drivers/nv04/nv04_clear.c b/src/gallium/drivers/nv04/nv04_clear.c deleted file mode 100644 index 01cacd36fe1..00000000000 --- a/src/gallium/drivers/nv04/nv04_clear.c +++ /dev/null @@ -1,12 +0,0 @@ -#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 deleted file mode 100644 index e91ffe0f5de..00000000000 --- a/src/gallium/drivers/nv04/nv04_context.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "util/u_simple_screen.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); - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - - draw_flush(nv04->draw); - - FIRE_RING(chan); - if (fence) - *fence = NULL; -} - -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 boolean -nv04_init_hwctx(struct nv04_context *nv04) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - // requires a valid handle -// BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOTIFY, 1); -// OUT_RING(0); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_NOP, 1); - OUT_RING(chan, 0); - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); - OUT_RING(chan, 0x40182800); -// OUT_RING(1<<20/*no cull*/); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1); -// OUT_RING(0x24|(1<<6)|(1<<8)); - OUT_RING(chan, 0x120001a4); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FORMAT, 1); - OUT_RING(chan, 0x332213a1); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1); - OUT_RING(chan, 0x11001010); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1); - OUT_RING(chan, 0x0); -// BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 1); -// OUT_RING(SCREEN_OFFSET); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1); - OUT_RING(chan, 0xff000000); - - - - FIRE_RING (chan); - 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.draw_arrays = nv04_draw_arrays; - nv04->pipe.draw_elements = nv04_draw_elements; - nv04->pipe.clear = nv04_clear; - nv04->pipe.flush = nv04_flush; - - nv04->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nv04->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; - - 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 deleted file mode 100644 index 83acb591878..00000000000 --- a/src/gallium/drivers/nv04/nv04_context.h +++ /dev/null @@ -1,151 +0,0 @@ -#ifndef __NV04_CONTEXT_H__ -#define __NV04_CONTEXT_H__ - -#include <stdio.h> - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_compiler.h" - -#include "util/u_memory.h" -#include "util/u_math.h" -#include "util/u_inlines.h" - -#include "draw/draw_vertex.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_context.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) -#define NV04_NEW_FRAMEBUFFER (1 << 8) -#define NV04_NEW_VTXARRAYS (1 << 9) - -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_framebuffer_state *framebuffer; - struct pipe_surface *rt; - struct pipe_surface *zeta; - - struct { - struct pipe_buffer *buffer; - uint32_t format; - } tex[16]; - - unsigned vb_enable; - struct { - struct pipe_buffer *buffer; - unsigned delta; - } vb[16]; - - float *constbuf[PIPE_SHADER_TYPES][32][4]; - unsigned constbuf_nr[PIPE_SHADER_TYPES]; - - 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 vtxbuf[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; - - 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_screen_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 void nv04_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void 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 deleted file mode 100644 index 8a2af41fe06..00000000000 --- a/src/gallium/drivers/nv04/nv04_fragprog.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/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 deleted file mode 100644 index c152b52119a..00000000000 --- a/src/gallium/drivers/nv04/nv04_fragtex.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "nv04_context.h" -#include "nouveau/nouveau_util.h" - -#define _(m,tf) \ -{ \ - PIPE_FORMAT_##m, \ - NV04_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; - 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++; - } - - NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); - 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_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER - | NV04_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER - | nv04_fragtex_format(pt->format) - | ( (pt->last_level + 1) << NV04_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT ) - | ( log2i(pt->width0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT ) - | ( log2i(pt->height0) << NV04_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT ) - | NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE - | NV04_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 deleted file mode 100644 index e4c38ac98e2..00000000000 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "util/u_inlines.h" -#include "util/u_math.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 offset = 0; - int nr_faces, l; - - nr_faces = 1; - - for (l = 0; l <= pt->last_level; l++) { - nv04mt->level[l].pitch = pt->width0; - nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63; - } - - for (l = 0; l <= pt->last_level; l++) { - nv04mt->level[l].image_offset = - CALLOC(nr_faces, sizeof(unsigned)); - /* XXX guess was obviously missing */ - nv04mt->level[l].image_offset[0] = offset; - offset += nv04mt->level[l].pitch * u_minify(pt->height0, l); - } - - nv04mt->total_size = offset; -} - -static struct pipe_texture * -nv04_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt) -{ - struct nv04_miptree *mt; - - mt = MALLOC(sizeof(struct nv04_miptree)); - if (!mt) - return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - - //mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - - nv04_miptree_layout(mt); - - mt->buffer = pscreen->buffer_create(pscreen, 256, PIPE_BUFFER_USAGE_PIXEL | - NOUVEAU_BUFFER_USAGE_TEXTURE, - mt->total_size); - if (!mt->buffer) { - printf("failed %d byte alloc\n",mt->total_size); - FREE(mt); - return NULL; - } - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static struct pipe_texture * -nv04_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) -{ - struct nv04_miptree *mt; - - /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) - return NULL; - - mt = CALLOC_STRUCT(nv04_miptree); - if (!mt) - return NULL; - - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - mt->level[0].pitch = stride[0]; - mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - - pipe_buffer_reference(&mt->buffer, pb); - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static void -nv04_miptree_destroy(struct pipe_texture *pt) -{ - struct nv04_miptree *mt = (struct nv04_miptree *)pt; - int l; - - pipe_buffer_reference(&mt->buffer, NULL); - for (l = 0; l <= pt->last_level; l++) { - if (mt->level[l].image_offset) - FREE(mt->level[l].image_offset); - } - - FREE(mt); -} - -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 nv04_miptree *nv04mt = (struct nv04_miptree *)pt; - struct nv04_surface *ns; - - ns = CALLOC_STRUCT(nv04_surface); - if (!ns) - return NULL; - pipe_texture_reference(&ns->base.texture, pt); - ns->base.format = pt->format; - ns->base.width = u_minify(pt->width0, level); - ns->base.height = u_minify(pt->height0, level); - ns->base.usage = flags; - pipe_reference_init(&ns->base.reference, 1); - ns->base.face = face; - ns->base.level = level; - ns->base.zslice = zslice; - ns->pitch = nv04mt->level[level].pitch; - - ns->base.offset = nv04mt->level[level].image_offset[0]; - - return &ns->base; -} - -static void -nv04_miptree_surface_del(struct pipe_surface *ps) -{ - pipe_texture_reference(&ps->texture, NULL); - FREE(ps); -} - -void -nv04_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nv04_miptree_create; - pscreen->texture_blanket = nv04_miptree_blanket; - pscreen->texture_destroy = nv04_miptree_destroy; - pscreen->get_tex_surface = nv04_miptree_surface_new; - pscreen->tex_surface_destroy = nv04_miptree_surface_del; -} - diff --git a/src/gallium/drivers/nv04/nv04_prim_vbuf.c b/src/gallium/drivers/nv04/nv04_prim_vbuf.c deleted file mode 100644 index 03438c7fcb9..00000000000 --- a/src/gallium/drivers/nv04/nv04_prim_vbuf.c +++ /dev/null @@ -1,339 +0,0 @@ - -#include "util/u_debug.h" -#include "util/u_inlines.h" -#include "util/u_simple_screen.h" -#include "pipe/p_compiler.h" - -#include "draw/draw_vbuf.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 boolean -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 ? TRUE : FALSE; -} - -static void * -nv04_vbuf_render_map_vertices( struct vbuf_render *render ) -{ - struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render); - return nv04_render->buffer; -} - -static void -nv04_vbuf_render_unmap_vertices( struct vbuf_render *render, - ushort min_index, - ushort max_index ) -{ -} - -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) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA), 49); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v4,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v5,8); - OUT_RING(chan, 0xFEDCBA); -} - -static INLINE void nv04_1triangle(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD), 25); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8); - OUT_RING(chan, 0xFED); -} - -static INLINE void nv04_1quad(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC), 33); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v0,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v1,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v2,8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * v3,8); - OUT_RING(chan, 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; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - int i,j; - - for(i = 0; i<nr_indices; i+=14) - { - int numvert = MIN2(16, nr_indices - i); - int numtri = numvert - 2; - if (numvert<3) - break; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), numvert*8); - for(j = 0; j<numvert; j++) - OUT_RINGp(chan, buffer + VERTEX_SIZE * indices [i+j], 8 ); - - BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2 ); - for(j = 0; j<numtri/2; j++ ) - OUT_RING(chan, striptbl[j]); - if (numtri%2) - OUT_RING(chan, striptbl[numtri/2]&0xFFF); - } -} - -static void nv04_vbuf_render_tri_fan_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices) -{ - const uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0}; - unsigned char* buffer = render->buffer; - struct nv04_context *nv04 = render->nv04; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - int i,j; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8); - OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[0], 8); - - for(i = 1; i<nr_indices; i+=14) - { - int numvert=MIN2(15, nr_indices - i); - int numtri=numvert-2; - if (numvert < 3) - break; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1), numvert*8); - - for(j=0;j<numvert;j++) - OUT_RINGp(chan, buffer + VERTEX_SIZE * indices[ i+j ], 8 ); - - BEGIN_RING_NI(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), (numtri+1)/2); - for(j = 0; j<numtri/2; j++) - OUT_RING(chan, fantbl[j]); - if (numtri%2) - OUT_RING(chan, fantbl[numtri/2]&0xFFF); - } -} - -static void nv04_vbuf_render_quads_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; 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 ) -{ - 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.map_vertices = nv04_vbuf_render_map_vertices; - nv04_render->base.unmap_vertices = nv04_vbuf_render_unmap_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 deleted file mode 100644 index 212b47bc3d2..00000000000 --- a/src/gallium/drivers/nv04/nv04_screen.c +++ /dev/null @@ -1,222 +0,0 @@ -#include "pipe/p_screen.h" -#include "util/u_inlines.h" - -#include "nv04_context.h" -#include "nv04_screen.h" - -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_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; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; - case PIPE_CAP_TEXTURE_MIRROR_CLAMP: - return 0; - case PIPE_CAP_TEXTURE_MIRROR_REPEAT: - return 1; - case PIPE_CAP_TGSI_CONT_SUPPORTED: - return 0; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 0; - case NOUVEAU_CAP_HW_VTXBUF: - case NOUVEAU_CAP_HW_IDXBUF: - return 0; - case PIPE_CAP_INDEP_BLEND_ENABLE: - return 0; - case PIPE_CAP_INDEP_BLEND_FUNC: - return 0; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - 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, - enum pipe_texture_target target, - unsigned tex_usage, unsigned geom_flags) -{ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return TRUE; - default: - break; - } - } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { - switch (format) { - case PIPE_FORMAT_Z16_UNORM: - return TRUE; - default: - break; - } - } else { - 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; - } - } - - return FALSE; -} - -static void -nv04_screen_destroy(struct pipe_screen *pscreen) -{ - struct nv04_screen *screen = nv04_screen(pscreen); - - nouveau_notifier_free(&screen->sync); - nouveau_grobj_free(&screen->fahrenheit); - nv04_surface_2d_takedown(&screen->eng2d); - - nouveau_screen_fini(&screen->base); - - FREE(pscreen); -} - -static struct pipe_buffer * -nv04_surface_buffer(struct pipe_surface *surf) -{ - struct nv04_miptree *mt = (struct nv04_miptree *)surf->texture; - - return mt->buffer; -} - -struct pipe_screen * -nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) -{ - struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen); - struct nouveau_channel *chan; - struct pipe_screen *pscreen; - unsigned fahrenheit_class = 0, sub3d_class = 0; - int ret; - - if (!screen) - return NULL; - pscreen = &screen->base.base; - - ret = nouveau_screen_init(&screen->base, dev); - if (ret) { - nv04_screen_destroy(pscreen); - return NULL; - } - chan = screen->base.channel; - - pscreen->winsys = ws; - pscreen->destroy = nv04_screen_destroy; - pscreen->get_param = nv04_screen_get_param; - pscreen->get_paramf = nv04_screen_get_paramf; - pscreen->is_format_supported = nv04_screen_is_format_supported; - - nv04_screen_init_miptree_functions(pscreen); - nv04_screen_init_transfer_functions(pscreen); - - if (dev->chipset >= 0x20) { - fahrenheit_class = 0; - sub3d_class = 0; - } else if (dev->chipset >= 0x10) { - fahrenheit_class = NV10_TEXTURED_TRIANGLE; - sub3d_class = NV10_CONTEXT_SURFACES_3D; - } else { - fahrenheit_class=NV04_TEXTURED_TRIANGLE; - sub3d_class = NV04_CONTEXT_SURFACES_3D; - } - - if (!fahrenheit_class) { - NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", dev->chipset); - return NULL; - } - - /* 3D object */ - ret = nouveau_grobj_alloc(chan, 0xbeef0001, fahrenheit_class, - &screen->fahrenheit); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return NULL; - } - BIND_RING(chan, screen->fahrenheit, 7); - - /* 3D surface object */ - ret = nouveau_grobj_alloc(chan, 0xbeef0002, sub3d_class, - &screen->context_surfaces_3d); - if (ret) { - NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret); - return NULL; - } - BIND_RING(chan, screen->context_surfaces_3d, 6); - - /* 2D engine setup */ - screen->eng2d = nv04_surface_2d_init(&screen->base); - screen->eng2d->buf = nv04_surface_buffer; - - /* Notifier for sync purposes */ - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv04_screen_destroy(pscreen); - return NULL; - } - - return pscreen; -} - diff --git a/src/gallium/drivers/nv04/nv04_screen.h b/src/gallium/drivers/nv04/nv04_screen.h deleted file mode 100644 index 11466b9442c..00000000000 --- a/src/gallium/drivers/nv04/nv04_screen.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __NV04_SCREEN_H__ -#define __NV04_SCREEN_H__ - -#include "nouveau/nouveau_screen.h" -#include "nv04_surface_2d.h" - -struct nv04_screen { - struct nouveau_screen base; - - struct nouveau_winsys *nvws; - unsigned chipset; - - /* HW graphics objects */ - struct nv04_surface_2d *eng2d; - 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; -} - -void -nv04_screen_init_transfer_functions(struct pipe_screen *pscreen); - -#endif diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c deleted file mode 100644 index 226aae35659..00000000000 --- a/src/gallium/drivers/nv04/nv04_state.c +++ /dev/null @@ -1,459 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "util/u_inlines.h" - -#include "tgsi/tgsi_parse.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->rt[0].blend_enable ? 1 : 0; - cb->b_src = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) | - (nvgl_blend_func(cso->rt[0].rgb_src_factor))); - cb->b_dst = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) | - (nvgl_blend_func(cso->rt[0].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_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT; - break; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT; - break; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE; - break; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - ret = NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER; - break; - case PIPE_TEX_WRAP_CLAMP: - ret = NV04_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_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP; - } - return ret >> NV04_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_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) | - (wrap_mode(cso->wrap_t) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT)); - - if (cso->max_anisotropy > 1.0) { - filter |= NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE; - } - - switch (cso->mag_img_filter) { - case PIPE_TEX_FILTER_LINEAR: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR; - break; - case PIPE_TEX_FILTER_NEAREST: - default: - filter |= NV04_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_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; - break; - case PIPE_TEX_MIPFILTER_LINEAR: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; - break; - case PIPE_TEX_MIPFILTER_NONE: - default: - filter |= NV04_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_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; - break; - case PIPE_TEX_MIPFILTER_LINEAR: - filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; - break; - case PIPE_TEX_MIPFILTER_NONE: - default: - filter |= NV04_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_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_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_value); - hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT ); - hw->control |= cso->alpha.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE : 0; - hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN; - hw->control |= cso->depth.enabled ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE : 0; - hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT ); - hw->control |= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module - hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; - hw->control |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE; - hw->control |= cso->depth.writemask ? NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE : 0; - hw->control |= 1 << NV04_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.tokens = tgsi_dup_tokens(cso->tokens); - - 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((void*)fp->pipe.tokens); - 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, - struct pipe_buffer *buf ) -{ - struct nv04_context *nv04 = nv04_context(pipe); - struct pipe_screen *pscreen = pipe->screen; - - assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); - - if (buf) { - void *mapped; - if (buf && buf->size && - (mapped = pipe_buffer_map(pscreen, buf, PIPE_BUFFER_USAGE_CPU_READ))) - { - memcpy(nv04->constbuf[shader], mapped, buf->size); - nv04->constbuf_nr[shader] = - buf->size / (4 * sizeof(float)); - pipe_buffer_unmap(pscreen, buf); - } - } -} - -static void -nv04_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct nv04_context *nv04 = nv04_context(pipe); - - nv04->framebuffer = (struct pipe_framebuffer_state*)fb; - - nv04->dirty |= NV04_NEW_FRAMEBUFFER; -} -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_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); - - memcpy(nv04->vtxbuf, buffers, count * sizeof(buffers[0])); - nv04->dirty |= NV04_NEW_VTXARRAYS; - - 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); - - memcpy(nv04->vtxelt, elements, sizeof(*elements) * count); - nv04->dirty |= NV04_NEW_VTXARRAYS; - - 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_fragment_sampler_states = nv04_sampler_state_bind; - nv04->pipe.delete_sampler_state = nv04_sampler_state_delete; - nv04->pipe.set_fragment_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 deleted file mode 100644 index 81d1d2ebaa9..00000000000 --- a/src/gallium/drivers/nv04/nv04_state.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __NV04_STATE_H__ -#define __NV04_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/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 nouveau_bo *bo; - - 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 { - 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 deleted file mode 100644 index b8d6dc560f0..00000000000 --- a/src/gallium/drivers/nv04/nv04_state_emit.c +++ /dev/null @@ -1,246 +0,0 @@ -#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++) { - int isn = fp->info.input_semantic_name[i]; - int isi = fp->info.input_semantic_index[i]; - switch (isn) { - 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; - } - } - - printf("%d vertex input\n",fp->info.num_inputs); - 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; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); - OUT_RING(chan, control); -} - -static void nv04_emit_blend(struct nv04_context* nv04) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - 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(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1); - OUT_RING(chan, 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; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer); - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 3); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, bo, (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(chan, nv04->sampler[unit]->filter); -} - -static void nv04_state_emit_framebuffer(struct nv04_context* nv04) -{ - struct pipe_framebuffer_state* fb = nv04->framebuffer; - struct nv04_surface *rt, *zeta; - uint32_t rt_format, w, h; - int colour_format = 0, zeta_format = 0; - struct nv04_miptree *nv04mt = 0; - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d; - struct nouveau_bo *bo; - - w = fb->cbufs[0]->width; - h = fb->cbufs[0]->height; - colour_format = fb->cbufs[0]->format; - rt = (struct nv04_surface *)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 = (struct nv04_surface *)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(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); - OUT_RING(chan, rt_format); - - nv04mt = (struct nv04_miptree *)rt->base.texture; - bo = nouveau_bo(nv04mt->buffer); - /* FIXME pitches have to be aligned ! */ - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); - OUT_RING(chan, rt->pitch|(zeta->pitch<<16)); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - if (fb->zsbuf) { - nv04mt = (struct nv04_miptree *)zeta->base.texture; - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - } -} - -void -nv04_emit_hw_state(struct nv04_context *nv04) -{ - struct nv04_screen *screen = nv04->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *fahrenheit = screen->fahrenheit; - struct nouveau_grobj *context_surfaces_3d = screen->context_surfaces_3d; - 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); - nv04->dirty &= ~NV04_NEW_FRAGPROG; - nv04->dirty_samplers |= (1<<10); - nv04->dirty_samplers = 0; - } - - if (nv04->dirty & NV04_NEW_CONTROL) { - nv04->dirty &= ~NV04_NEW_CONTROL; - - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); - OUT_RING(chan, nv04->dsa->control); - } - - if (nv04->dirty & NV04_NEW_BLEND) { - nv04->dirty &= ~NV04_NEW_BLEND; - - nv04_emit_blend(nv04); - } - - if (nv04->dirty & NV04_NEW_VTXARRAYS) { - nv04->dirty &= ~NV04_NEW_VTXARRAYS; - nv04_vertex_layout(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); - } - - if (nv04->dirty & NV04_NEW_FRAMEBUFFER) { - nv04->dirty &= ~NV04_NEW_FRAMEBUFFER; - nv04_state_emit_framebuffer(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 */ - unsigned rt_pitch = ((struct nv04_surface *)nv04->rt)->pitch; - unsigned zeta_pitch = ((struct nv04_surface *)nv04->zeta)->pitch; - - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2); - OUT_RING(chan, rt_pitch|(zeta_pitch<<16)); - OUT_RELOCl(chan, nouveau_bo(nv04->rt), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - if (nv04->zeta) { - BEGIN_RING(chan, context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1); - OUT_RELOCl(chan, nouveau_bo(nv04->zeta), 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]; - struct nouveau_bo *bo = nouveau_bo(nv04mt->buffer); - BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_OFFSET, 2); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, bo, (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 deleted file mode 100644 index c5f8927c058..00000000000 --- a/src/gallium/drivers/nv04/nv04_surface.c +++ /dev/null @@ -1,63 +0,0 @@ - -/************************************************************************** - * - * 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 "util/u_simple_screen.h" -#include "util/u_inlines.h" -#include "util/u_tile.h" - -static void -nv04_surface_copy(struct pipe_context *pipe, - 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 nv04_surface_2d *eng2d = nv04->screen->eng2d; - - eng2d->copy(eng2d, 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 nv04_surface_2d *eng2d = nv04->screen->eng2d; - - eng2d->fill(eng2d, 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_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c deleted file mode 100644 index 2e151483851..00000000000 --- a/src/gallium/drivers/nv04/nv04_transfer.c +++ /dev/null @@ -1,178 +0,0 @@ -#include <pipe/p_state.h> -#include <pipe/p_defines.h> -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include <util/u_math.h> -#include <nouveau/nouveau_winsys.h> -#include "nv04_context.h" -#include "nv04_screen.h" -#include "nv04_state.h" - -struct nv04_transfer { - struct pipe_transfer base; - struct pipe_surface *surface; - boolean direct; -}; - -static void -nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) -{ - memset(template, 0, sizeof(struct pipe_texture)); - template->target = pt->target; - template->format = pt->format; - template->width0 = width; - template->height0 = height; - template->depth0 = 1; - template->last_level = 0; - template->nr_samples = pt->nr_samples; - - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; -} - -static struct pipe_transfer * -nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - struct nv04_miptree *mt = (struct nv04_miptree *)pt; - struct nv04_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; - - tx = CALLOC_STRUCT(nv04_transfer); - if (!tx) - return NULL; - - pipe_texture_reference(&tx->base.texture, pt); - tx->base.x = x; - tx->base.y = y; - tx->base.width = w; - tx->base.height = h; - tx->base.stride = mt->level[level].pitch; - tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; - - /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || - debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) - { - tx->direct = true; - tx->surface = pscreen->get_tex_surface(pscreen, pt, - 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); - return &tx->base; - } - - tx->direct = false; - - nv04_compatible_transfer_tex(pt, w, h, &tx_tex_template); - - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); - if (!tx_tex) - { - FREE(tx); - return NULL; - } - - tx->base.stride = ((struct nv04_miptree*)tx_tex)->level[0].pitch; - - tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); - - pipe_texture_reference(&tx_tex, NULL); - - if (!tx->surface) - { - pipe_surface_reference(&tx->surface, NULL); - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - struct nv04_screen *nvscreen = nv04_screen(pscreen); - struct pipe_surface *src; - - src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - /* TODO: Check if SIFM can un-swizzle */ - nvscreen->eng2d->copy(nvscreen->eng2d, - tx->surface, 0, 0, - src, x, y, - w, h); - - pipe_surface_reference(&src, NULL); - } - - return &tx->base; -} - -static void -nv04_transfer_del(struct pipe_transfer *ptx) -{ - struct nv04_transfer *tx = (struct nv04_transfer *)ptx; - - if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { - struct pipe_screen *pscreen = ptx->texture->screen; - struct nv04_screen *nvscreen = nv04_screen(pscreen); - struct pipe_surface *dst; - - dst = pscreen->get_tex_surface(pscreen, ptx->texture, - ptx->face, ptx->level, ptx->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - nvscreen->eng2d->copy(nvscreen->eng2d, - dst, tx->base.x, tx->base.y, - tx->surface, 0, 0, - tx->base.width, tx->base.height); - - pipe_surface_reference(&dst, NULL); - } - - pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); - FREE(ptx); -} - -static void * -nv04_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv04_transfer *tx = (struct nv04_transfer *)ptx; - struct nv04_surface *ns = (struct nv04_surface *)tx->surface; - struct nv04_miptree *mt = (struct nv04_miptree *)tx->surface->texture; - void *map = pipe_buffer_map(pscreen, mt->buffer, - pipe_transfer_buffer_flags(ptx)); - - if(!tx->direct) - return map + ns->base.offset; - else - return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); -} - -static void -nv04_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv04_transfer *tx = (struct nv04_transfer *)ptx; - struct nv04_miptree *mt = (struct nv04_miptree *)tx->surface->texture; - - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nv04_screen_init_transfer_functions(struct pipe_screen *pscreen) -{ - pscreen->get_tex_transfer = nv04_transfer_new; - pscreen->tex_transfer_destroy = nv04_transfer_del; - pscreen->transfer_map = nv04_transfer_map; - pscreen->transfer_unmap = nv04_transfer_unmap; -} diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c deleted file mode 100644 index 606ce65fabd..00000000000 --- a/src/gallium/drivers/nv04/nv04_vbo.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "util/u_inlines.h" - -#include "nv04_context.h" -#include "nv04_state.h" - -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_pushbuf.h" - -void nv04_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count) -{ - struct pipe_screen *pscreen = pipe->screen; - struct nv04_context *nv04 = nv04_context( pipe ); - struct draw_context *draw = nv04->draw; - unsigned i; - - nv04_emit_hw_state(nv04); - - /* - * Map vertex buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv04->vtxbuf[i].buffer) { - void *buf - = pipe_buffer_map(pscreen, - nv04->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_buffer_map(pscreen, 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_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, - nv04->constbuf[PIPE_SHADER_VERTEX], - nv04->constbuf_nr[PIPE_SHADER_VERTEX]); - - /* draw! */ - draw_arrays(nv04->draw, prim, start, count); - - /* - * unmap vertex/index buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv04->vtxbuf[i].buffer) { - pipe_buffer_unmap(pscreen, nv04->vtxbuf[i].buffer); - draw_set_mapped_vertex_buffer(draw, i, NULL); - } - } - if (indexBuffer) { - pipe_buffer_unmap(pscreen, indexBuffer); - draw_set_mapped_element_buffer(draw, 0, NULL); - } -} - -void nv04_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - printf("coucou in draw arrays\n"); - nv04_draw_elements(pipe, NULL, 0, prim, start, count); -} - - - diff --git a/src/gallium/drivers/nv10/Makefile b/src/gallium/drivers/nv10/Makefile deleted file mode 100644 index 62677f5194a..00000000000 --- a/src/gallium/drivers/nv10/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = nv10 - -C_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_transfer.c \ - nv10_vbo.c - -include ../../Makefile.template diff --git a/src/gallium/drivers/nv10/nv10_clear.c b/src/gallium/drivers/nv10/nv10_clear.c deleted file mode 100644 index a39a2b5f525..00000000000 --- a/src/gallium/drivers/nv10/nv10_clear.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "util/u_clear.h" - -#include "nv10_context.h" - -void -nv10_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil) -{ - util_clear(pipe, nv10_context(pipe)->framebuffer, buffers, rgba, depth, - stencil); -} diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c deleted file mode 100644 index a3ceb1da948..00000000000 --- a/src/gallium/drivers/nv10/nv10_context.c +++ /dev/null @@ -1,298 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "util/u_simple_screen.h" - -#include "nv10_context.h" -#include "nv10_screen.h" - -static void -nv10_flush(struct pipe_context *pipe, unsigned flags, - struct pipe_fence_handle **fence) -{ - struct nv10_context *nv10 = nv10_context(pipe); - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - - draw_flush(nv10->draw); - - FIRE_RING(chan); - if (fence) - *fence = NULL; -} - -static void -nv10_destroy(struct pipe_context *pipe) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - if (nv10->draw) - draw_destroy(nv10->draw); - - FREE(nv10); -} - -static void nv10_init_hwctx(struct nv10_context *nv10) -{ - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - int i; - float projectionmatrix[16]; - - BEGIN_RING(chan, celsius, NV10TCL_DMA_NOTIFY, 1); - OUT_RING (chan, screen->sync->handle); - BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY0, 2); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->gart->handle); - BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY2, 2); - OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); - OUT_RING (chan, (0x7ff<<16)|0x800); - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); - OUT_RING (chan, (0x7ff<<16)|0x800); - - for (i=1;i<8;i++) { - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); - OUT_RING (chan, 0); - } - - BEGIN_RING(chan, celsius, 0x290, 1); - OUT_RING (chan, (0x10<<16)|1); - BEGIN_RING(chan, celsius, 0x3f4, 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - if (nv10->screen->celsius->grclass != NV10TCL) { - /* For nv11, nv17 */ - BEGIN_RING(chan, celsius, 0x120, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 1); - OUT_RING (chan, 2); - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - } - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - /* Set state */ - BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); - OUT_RING (chan, 0x207); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(0), 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(0), 12); - OUT_RING (chan, 0x30141010); - OUT_RING (chan, 0); - OUT_RING (chan, 0x20040000); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0x00000c00); - OUT_RING (chan, 0); - OUT_RING (chan, 0x00000c00); - OUT_RING (chan, 0x18000000); - OUT_RING (chan, 0x300e0300); - OUT_RING (chan, 0x0c091c80); - - BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 2); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 4); - OUT_RING (chan, 1); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0x8006); - BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 8); - OUT_RING (chan, 0xff); - OUT_RING (chan, 0x207); - OUT_RING (chan, 0); - OUT_RING (chan, 0xff); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1e00); - OUT_RING (chan, 0x1d01); - BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); - OUT_RING (chan, 0x201); - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); - OUT_RING (chan, 8); - BEGIN_RING(chan, celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); - OUT_RING (chan, 8); - BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (chan, 0x1b02); - OUT_RING (chan, 0x1b02); - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2); - OUT_RING (chan, 0x405); - OUT_RING (chan, 0x901); - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8); - for (i=0;i<8;i++) { - OUT_RING (chan, 0); - } - BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); - OUT_RING (chan, 0x3fc00000); /* -1.50 */ - OUT_RING (chan, 0xbdb8aa0a); /* -0.09 */ - OUT_RING (chan, 0); /* 0.00 */ - - BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); - OUT_RING (chan, 0); - - BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 2); - OUT_RING (chan, 0x802); - OUT_RING (chan, 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(chan, celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); - OUT_RING (chan, 6); - BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); - OUT_RING (chan, 0x01010101); - - /* Set vertex component */ - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL_4F_R, 4); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL2_3F_R, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_NOR_3F_X, 3); - OUT_RING (chan, 0); - OUT_RING (chan, 0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX0_4F_S, 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX1_4F_S, 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 1.0); - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_FOG_1F, 1); - OUT_RINGf (chan, 0.0); - BEGIN_RING(chan, celsius, NV10TCL_EDGEFLAG_ENABLE, 1); - OUT_RING (chan, 1); - - memset(projectionmatrix, 0, sizeof(projectionmatrix)); - BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16); - projectionmatrix[0*4+0] = 1.0; - projectionmatrix[1*4+1] = 1.0; - projectionmatrix[2*4+2] = 1.0; - projectionmatrix[3*4+3] = 1.0; - for (i=0;i<16;i++) { - OUT_RINGf (chan, projectionmatrix[i]); - } - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_RANGE_NEAR, 2); - OUT_RING (chan, 0.0); - OUT_RINGf (chan, 16777216.0); - - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_TRANSLATE_X, 4); - OUT_RINGf (chan, -2048.0); - OUT_RINGf (chan, -2048.0); - OUT_RINGf (chan, 16777215.0 * 0.5); - OUT_RING (chan, 0); - - FIRE_RING (chan); -} - -struct pipe_context * -nv10_create(struct pipe_screen *pscreen, unsigned pctx_id) -{ - struct nv10_screen *screen = nv10_screen(pscreen); - struct pipe_winsys *ws = pscreen->winsys; - struct nv10_context *nv10; - struct nouveau_winsys *nvws = screen->nvws; - - nv10 = CALLOC(1, sizeof(struct nv10_context)); - if (!nv10) - return NULL; - nv10->screen = screen; - nv10->pctx_id = pctx_id; - - nv10->nvws = nvws; - - nv10->pipe.winsys = ws; - nv10->pipe.screen = pscreen; - nv10->pipe.destroy = nv10_destroy; - nv10->pipe.draw_arrays = nv10_draw_arrays; - nv10->pipe.draw_elements = nv10_draw_elements; - nv10->pipe.clear = nv10_clear; - nv10->pipe.flush = nv10_flush; - - nv10->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nv10->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; - - 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)); - - nv10_init_hwctx(nv10); - - return &nv10->pipe; -} - diff --git a/src/gallium/drivers/nv10/nv10_context.h b/src/gallium/drivers/nv10/nv10_context.h deleted file mode 100644 index f0dcbe3fefd..00000000000 --- a/src/gallium/drivers/nv10/nv10_context.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef __NV10_CONTEXT_H__ -#define __NV10_CONTEXT_H__ - -#include <stdio.h> - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_compiler.h" - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "draw/draw_vertex.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_context.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 << 0) -#define NV10_NEW_FRAGPROG (1 << 1) -#define NV10_NEW_VTXARRAYS (1 << 2) -#define NV10_NEW_BLEND (1 << 3) -#define NV10_NEW_BLENDCOL (1 << 4) -#define NV10_NEW_RAST (1 << 5) -#define NV10_NEW_DSA (1 << 6) -#define NV10_NEW_VIEWPORT (1 << 7) -#define NV10_NEW_SCISSOR (1 << 8) -#define NV10_NEW_FRAMEBUFFER (1 << 9) - -#include "nv10_screen.h" - -struct nv10_context { - struct pipe_context pipe; - - struct nouveau_winsys *nvws; - struct nv10_screen *screen; - unsigned pctx_id; - - struct draw_context *draw; - - 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; - uint32_t lma_offset; - - struct nv10_blend_state *blend; - struct pipe_blend_color *blend_color; - struct nv10_rasterizer_state *rast; - struct nv10_depth_stencil_alpha_state *dsa; - struct pipe_viewport_state *viewport; - struct pipe_scissor_state *scissor; - struct pipe_framebuffer_state *framebuffer; - - //struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; - float *constbuf[PIPE_SHADER_TYPES][32][4]; - unsigned constbuf_nr[PIPE_SHADER_TYPES]; - - struct vertex_info vertex_info; - - struct { - struct pipe_buffer *buffer; - uint32_t format; - } tex[2]; - - unsigned vb_enable; - struct { - struct pipe_buffer *buffer; - unsigned delta; - } vb[16]; - -/* struct { - - struct nouveau_resource *exec_heap; - struct nouveau_resource *data_heap; - - struct nv10_vertex_program *active; - - struct nv10_vertex_program *current; - } vertprog; -*/ - struct { - struct nv10_fragment_program *active; - - struct nv10_fragment_program *current; - struct pipe_buffer *constant_buf; - } fragprog; - - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; -}; - -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_screen_init_miptree_functions(struct pipe_screen *pscreen); - -/* nv10_clear.c */ -extern void nv10_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil); - - -/* 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 ); -extern void nv10_vtxbuf_bind(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 void nv10_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void 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 deleted file mode 100644 index 698db5a16a9..00000000000 --- a/src/gallium/drivers/nv10/nv10_fragprog.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/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 deleted file mode 100644 index c1f7ccb9ab6..00000000000 --- a/src/gallium/drivers/nv10/nv10_fragtex.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "nv10_context.h" -#include "nouveau/nouveau_util.h" - -#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), - _(L8_UNORM , L8 ), - _(A8_UNORM , A8 ), - _(A8L8_UNORM , 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) -{ -#if 0 - 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; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - 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->width0) << 20; - txf |= log2i(pt->height0) << 24; - txf |= log2i(pt->depth0) << 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(chan, celsius, NV10TCL_TX_OFFSET(unit), 8); - OUT_RELOCl(chan, nouveau_bo(nv10mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, nouveau_bo(nv10mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); - OUT_RING (chan, ps->wrap); - OUT_RING (chan, 0x40000000); /* enable */ - OUT_RING (chan, txs); - OUT_RING (chan, ps->filt | 0x2000 /* magic */); - OUT_RING (chan, (pt->width0 << 16) | pt->height0); - OUT_RING (chan, ps->bcol); -#endif -} - -void -nv10_fragtex_bind(struct nv10_context *nv10) -{ -#if 0 - struct nv10_fragment_program *fp = nv10->fragprog.active; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - unsigned samplers, unit; - - samplers = nv10->fp_samplers & ~fp->samplers; - while (samplers) { - unit = ffs(samplers) - 1; - samplers &= ~(1 << unit); - - BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(unit), 1); - OUT_RING (chan, 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; -#endif -} - diff --git a/src/gallium/drivers/nv10/nv10_miptree.c b/src/gallium/drivers/nv10/nv10_miptree.c deleted file mode 100644 index 55bd6f76b3e..00000000000 --- a/src/gallium/drivers/nv10/nv10_miptree.c +++ /dev/null @@ -1,165 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_math.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->width0; - 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++) { - if (swizzled) - nv10mt->level[l].pitch = util_format_get_stride(pt->format, width); - else - nv10mt->level[l].pitch = util_format_get_stride(pt->format, pt->width0); - nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63; - - nv10mt->level[l].image_offset = - CALLOC(nr_faces, sizeof(unsigned)); - - width = u_minify(width, 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 * u_minify(pt->height0, l); - } - } - - nv10mt->total_size = offset; -} - -static struct pipe_texture * -nv10_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) -{ - struct nv10_miptree *mt; - - /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) - return NULL; - - mt = CALLOC_STRUCT(nv10_miptree); - if (!mt) - return NULL; - - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - mt->level[0].pitch = stride[0]; - mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - - pipe_buffer_reference(&mt->buffer, pb); - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static struct pipe_texture * -nv10_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) -{ - struct nv10_miptree *mt; - - mt = MALLOC(sizeof(struct nv10_miptree)); - if (!mt) - return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = screen; - - nv10_miptree_layout(mt); - - mt->buffer = screen->buffer_create(screen, 256, PIPE_BUFFER_USAGE_PIXEL, - mt->total_size); - if (!mt->buffer) { - FREE(mt); - return NULL; - } - mt->bo = nouveau_bo(mt->buffer); - - return &mt->base; -} - -static void -nv10_miptree_destroy(struct pipe_texture *pt) -{ - struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; - int l; - - pipe_buffer_reference(&nv10mt->buffer, NULL); - for (l = 0; l <= pt->last_level; l++) { - if (nv10mt->level[l].image_offset) - FREE(nv10mt->level[l].image_offset); - } - FREE(nv10mt); -} - -static void -nv10_miptree_update(struct pipe_context *pipe, struct pipe_texture *mt, - uint face, uint levels) -{ -} - - -static struct pipe_surface * -nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) -{ - struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; - struct nv04_surface *ns; - - ns = CALLOC_STRUCT(nv04_surface); - if (!ns) - return NULL; - pipe_texture_reference(&ns->base.texture, pt); - ns->base.format = pt->format; - ns->base.width = u_minify(pt->width0, level); - ns->base.height = u_minify(pt->height0, level); - ns->base.usage = flags; - pipe_reference_init(&ns->base.reference, 1); - ns->base.face = face; - ns->base.level = level; - ns->base.zslice = zslice; - ns->pitch = nv10mt->level[level].pitch; - - if (pt->target == PIPE_TEXTURE_CUBE) { - ns->base.offset = nv10mt->level[level].image_offset[face]; - } else { - ns->base.offset = nv10mt->level[level].image_offset[0]; - } - - return &ns->base; -} - -static void -nv10_miptree_surface_destroy(struct pipe_surface *surface) -{ -} - -void nv10_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nv10_miptree_create; - pscreen->texture_blanket = nv10_miptree_blanket; - pscreen->texture_destroy = nv10_miptree_destroy; - pscreen->get_tex_surface = nv10_miptree_surface_get; - pscreen->tex_surface_destroy = nv10_miptree_surface_destroy; -} - diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c deleted file mode 100644 index 0309465ab8d..00000000000 --- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c +++ /dev/null @@ -1,267 +0,0 @@ -/************************************************************************** - * - * 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 <[email protected]> - * \author Keith Whitwell <[email protected]> - */ - - -#include "util/u_debug.h" -#include "util/u_inlines.h" - -#include "nv10_context.h" -#include "nv10_state.h" - -#include "draw/draw_vbuf.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; -}; - - -void nv10_vtxbuf_bind( struct nv10_context* nv10 ) -{ - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - int i; - for(i = 0; i < 8; i++) { - BEGIN_RING(chan, celsius, NV10TCL_VTXBUF_ADDRESS(i), 1); - OUT_RING(chan, 0/*nv10->vtxbuf*/); - BEGIN_RING(chan, celsius, NV10TCL_VTXFMT(i), 1); - OUT_RING(chan, 0/*XXX*/); - } -} - -/** - * 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; - - nv10_emit_hw_state(nv10); - - return &nv10->vertex_info; -} - -static boolean -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_screen *screen = nv10->pipe.screen; - size_t size = (size_t)vertex_size * (size_t)nr_vertices; - - assert(!nv10_render->buffer); - nv10_render->buffer = screen->buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX, size); - - nv10->dirty |= NV10_NEW_VTXARRAYS; - - if (nv10_render->buffer) - return FALSE; - return TRUE; -} - -static void * -nv10_vbuf_render_map_vertices( struct vbuf_render *render ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - struct nv10_context *nv10 = nv10_render->nv10; - struct pipe_screen *pscreen = nv10->pipe.screen; - - return pipe_buffer_map(pscreen, nv10_render->buffer, - PIPE_BUFFER_USAGE_CPU_WRITE); -} - -static void -nv10_vbuf_render_unmap_vertices( struct vbuf_render *render, - ushort min_index, - ushort max_index ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - struct nv10_context *nv10 = nv10_render->nv10; - struct pipe_screen *pscreen = nv10->pipe.screen; - - assert(!nv10_render->buffer); - pipe_buffer_unmap(pscreen, nv10_render->buffer); -} - -static boolean -nv10_vbuf_render_set_primitive( struct vbuf_render *render, - unsigned prim ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - unsigned hwp = nvgl_primitive(prim); - if (hwp == 0) - return FALSE; - - nv10_render->hwprim = hwp; - return TRUE; -} - - -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; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - int push, i; - - nv10_emit_hw_state(nv10); - - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); - OUT_RELOCl(chan, nouveau_bo(nv10_render->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING(chan, nv10_render->hwprim); - - if (nr_indices & 1) { - BEGIN_RING(chan, celsius, NV10TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, indices[0]); - indices++; nr_indices--; - } - - while (nr_indices) { - // XXX too big/small ? check the size - push = MIN2(nr_indices, 1200 * 2); - - BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U16, push >> 1); - for (i = 0; i < push; i+=2) - OUT_RING(chan, (indices[i+1] << 16) | indices[i]); - - nr_indices -= push; - indices += push; - } - - BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING (chan, 0); -} - - -static void -nv10_vbuf_render_release_vertices( struct vbuf_render *render ) -{ - struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); - - assert(nv10_render->buffer); - pipe_buffer_reference(&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 = 16*1024; - nv10_render->base.max_indices = 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.map_vertices = nv10_vbuf_render_map_vertices; - nv10_render->base.unmap_vertices = nv10_vbuf_render_unmap_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 deleted file mode 100644 index 4e6bc129943..00000000000 --- a/src/gallium/drivers/nv10/nv10_screen.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "pipe/p_screen.h" - -#include "nv10_context.h" -#include "nv10_screen.h" - -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_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; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; - case PIPE_CAP_TGSI_CONT_SUPPORTED: - return 0; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 0; - case NOUVEAU_CAP_HW_VTXBUF: - case NOUVEAU_CAP_HW_IDXBUF: - return 0; - case PIPE_CAP_INDEP_BLEND_ENABLE: - return 0; - case PIPE_CAP_INDEP_BLEND_FUNC: - return 0; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; - 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; - 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, - enum pipe_texture_target target, - unsigned tex_usage, unsigned geom_flags) -{ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return TRUE; - default: - break; - } - } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { - switch (format) { - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - return TRUE; - default: - break; - } - } else { - 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_L8_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static void -nv10_screen_destroy(struct pipe_screen *pscreen) -{ - struct nv10_screen *screen = nv10_screen(pscreen); - - nouveau_notifier_free(&screen->sync); - nouveau_grobj_free(&screen->celsius); - nv04_surface_2d_takedown(&screen->eng2d); - - nouveau_screen_fini(&screen->base); - - FREE(pscreen); -} - -static struct pipe_buffer * -nv10_surface_buffer(struct pipe_surface *surf) -{ - struct nv10_miptree *mt = (struct nv10_miptree *)surf->texture; - - return mt->buffer; -} - -struct pipe_screen * -nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) -{ - struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen); - struct nouveau_channel *chan; - struct pipe_screen *pscreen; - unsigned celsius_class; - int ret; - - if (!screen) - return NULL; - pscreen = &screen->base.base; - - ret = nouveau_screen_init(&screen->base, dev); - if (ret) { - nv10_screen_destroy(pscreen); - return NULL; - } - chan = screen->base.channel; - - pscreen->winsys = ws; - pscreen->destroy = nv10_screen_destroy; - pscreen->get_param = nv10_screen_get_param; - pscreen->get_paramf = nv10_screen_get_paramf; - pscreen->is_format_supported = nv10_screen_is_format_supported; - - nv10_screen_init_miptree_functions(pscreen); - nv10_screen_init_transfer_functions(pscreen); - - /* 3D object */ - if (dev->chipset >= 0x20) - celsius_class = NV11TCL; - else if (dev->chipset >= 0x17) - celsius_class = NV17TCL; - else if (dev->chipset >= 0x11) - celsius_class = NV11TCL; - else - celsius_class = NV10TCL; - - if (!celsius_class) { - NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", dev->chipset); - return NULL; - } - - ret = nouveau_grobj_alloc(chan, 0xbeef0001, celsius_class, - &screen->celsius); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - /* 2D engine setup */ - screen->eng2d = nv04_surface_2d_init(&screen->base); - screen->eng2d->buf = nv10_surface_buffer; - - /* Notifier for sync purposes */ - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv10_screen_destroy(pscreen); - return NULL; - } - - return pscreen; -} - diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h deleted file mode 100644 index 86b6d8def54..00000000000 --- a/src/gallium/drivers/nv10/nv10_screen.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __NV10_SCREEN_H__ -#define __NV10_SCREEN_H__ - -#include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" - -struct nv10_screen { - struct nouveau_screen base; - - struct nouveau_winsys *nvws; - - /* HW graphics objects */ - struct nv04_surface_2d *eng2d; - struct nouveau_grobj *celsius; - struct nouveau_notifier *sync; -}; - -static INLINE struct nv10_screen * -nv10_screen(struct pipe_screen *screen) -{ - return (struct nv10_screen *)screen; -} - - -void -nv10_screen_init_transfer_functions(struct pipe_screen *pscreen); - -#endif diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c deleted file mode 100644 index 11e23b21c5c..00000000000 --- a/src/gallium/drivers/nv10/nv10_state.c +++ /dev/null @@ -1,590 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "util/u_inlines.h" - -#include "tgsi/tgsi_parse.h" - -#include "nv10_context.h" -#include "nv10_state.h" - -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->rt[0].blend_enable ? 1 : 0; - cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) | - (nvgl_blend_func(cso->rt[0].rgb_src_factor))); - cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) | - (nvgl_blend_func(cso->rt[0].rgb_dst_factor))); - - cb->c_mask = (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | - ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | - ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | - ((cso->rt[0].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 *blend) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - nv10->blend = (struct nv10_blend_state*)blend; - - nv10->dirty |= NV10_NEW_BLEND; -} - -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->templ = cso; - - 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 *rast) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - nv10->rast = (struct nv10_rasterizer_state*)rast; - - draw_set_rasterizer_state(nv10->draw, (nv10->rast ? nv10->rast->templ : NULL)); - - nv10->dirty |= NV10_NEW_RAST; -} - -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].writemask; - hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func); - hw->stencil.ref = cso->stencil[0].ref_value; - hw->stencil.vmask = cso->stencil[0].valuemask; - 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_value); - - return (void *)hw; -} - -static void -nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - nv10->dsa = (struct nv10_depth_stencil_alpha_state*)dsa; - - nv10->dirty |= NV10_NEW_DSA; -} - -static void -nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) -{ - FREE(hwcso); -} - -static void * -nv10_vp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *templ) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - return draw_create_vertex_shader(nv10->draw, templ); -} - -static void -nv10_vp_state_bind(struct pipe_context *pipe, void *shader) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - draw_bind_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader); - - nv10->dirty |= NV10_NEW_VERTPROG; -} - -static void -nv10_vp_state_delete(struct pipe_context *pipe, void *shader) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - draw_delete_vertex_shader(nv10->draw, (struct draw_vertex_shader *) shader); -} - -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.tokens = tgsi_dup_tokens(cso->tokens); - - tgsi_scan_shader(cso->tokens, &fp->info); - - 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((void*)fp->pipe.tokens); - 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); - - nv10->blend_color = (struct pipe_blend_color*)bcol; - - nv10->dirty |= NV10_NEW_BLENDCOL; -} - -static void -nv10_set_clip_state(struct pipe_context *pipe, - const struct pipe_clip_state *clip) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - draw_set_clip_state(nv10->draw, clip); -} - -static void -nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf ) -{ - struct nv10_context *nv10 = nv10_context(pipe); - struct pipe_screen *pscreen = pipe->screen; - - assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); - - if (buf) { - void *mapped; - if (buf->size && - (mapped = pipe_buffer_map(pscreen, buf, PIPE_BUFFER_USAGE_CPU_READ))) - { - memcpy(nv10->constbuf[shader], mapped, buf->size); - nv10->constbuf_nr[shader] = - buf->size / (4 * sizeof(float)); - pipe_buffer_unmap(pscreen, buf); - } - } -} - -static void -nv10_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - nv10->framebuffer = (struct pipe_framebuffer_state*)fb; - - nv10->dirty |= NV10_NEW_FRAMEBUFFER; -} - -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); - - nv10->scissor = (struct pipe_scissor_state*)s; - - nv10->dirty |= NV10_NEW_SCISSOR; -} - -static void -nv10_set_viewport_state(struct pipe_context *pipe, - const struct pipe_viewport_state *vpt) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - nv10->viewport = (struct pipe_viewport_state*)vpt; - - draw_set_viewport_state(nv10->draw, nv10->viewport); - - nv10->dirty |= NV10_NEW_VIEWPORT; -} - -static void -nv10_set_vertex_buffers(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_buffer *vb) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - memcpy(nv10->vtxbuf, vb, sizeof(*vb) * count); - nv10->dirty |= NV10_NEW_VTXARRAYS; - - draw_set_vertex_buffers(nv10->draw, count, vb); -} - -static void -nv10_set_vertex_elements(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_element *ve) -{ - struct nv10_context *nv10 = nv10_context(pipe); - - memcpy(nv10->vtxelt, ve, sizeof(*ve) * count); - nv10->dirty |= NV10_NEW_VTXARRAYS; - - draw_set_vertex_elements(nv10->draw, count, ve); -} - -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_fragment_sampler_states = nv10_sampler_state_bind; - nv10->pipe.delete_sampler_state = nv10_sampler_state_delete; - nv10->pipe.set_fragment_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_buffers = nv10_set_vertex_buffers; - nv10->pipe.set_vertex_elements = nv10_set_vertex_elements; -} - diff --git a/src/gallium/drivers/nv10/nv10_state.h b/src/gallium/drivers/nv10/nv10_state.h deleted file mode 100644 index 2524ac02e29..00000000000 --- a/src/gallium/drivers/nv10/nv10_state.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef __NV10_STATE_H__ -#define __NV10_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/tgsi_scan.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; - - const struct pipe_rasterizer_state *templ; -}; - -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 { - struct pipe_shader_state pipe; - struct tgsi_shader_info info; - - 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 nouveau_bo *bo; - - 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 deleted file mode 100644 index 30a596ca604..00000000000 --- a/src/gallium/drivers/nv10/nv10_state_emit.c +++ /dev/null @@ -1,333 +0,0 @@ -#include "nv10_context.h" -#include "nv10_state.h" - -static void nv10_state_emit_blend(struct nv10_context* nv10) -{ - struct nv10_blend_state *b = nv10->blend; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1); - OUT_RING (chan, b->d_enable); - - BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); - OUT_RING (chan, b->b_enable); - OUT_RING (chan, b->b_srcfunc); - OUT_RING (chan, b->b_dstfunc); - - BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); - OUT_RING (chan, b->c_mask); -} - -static void nv10_state_emit_blend_color(struct nv10_context* nv10) -{ - struct pipe_blend_color *c = nv10->blend_color; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1); - OUT_RING (chan, - (float_to_ubyte(c->color[3]) << 24)| - (float_to_ubyte(c->color[0]) << 16)| - (float_to_ubyte(c->color[1]) << 8) | - (float_to_ubyte(c->color[2]) << 0)); -} - -static void nv10_state_emit_rast(struct nv10_context* nv10) -{ - struct nv10_rasterizer_state *r = nv10->rast; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 2); - OUT_RING (chan, r->shade_model); - OUT_RING (chan, r->line_width); - - - BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); - OUT_RING (chan, r->point_size); - - BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (chan, r->poly_mode_front); - OUT_RING (chan, r->poly_mode_back); - - - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2); - OUT_RING (chan, r->cull_face); - OUT_RING (chan, r->front_face); - - BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); - OUT_RING (chan, r->line_smooth_en); - OUT_RING (chan, r->poly_smooth_en); - - BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); - OUT_RING (chan, r->cull_face_en); -} - -static void nv10_state_emit_dsa(struct nv10_context* nv10) -{ - struct nv10_depth_stencil_alpha_state *d = nv10->dsa; - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); - OUT_RING (chan, d->depth.func); - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); - OUT_RING (chan, d->depth.write_enable); - - BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); - OUT_RING (chan, d->depth.test_enable); - -#if 0 - BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1); - OUT_RING (chan, d->stencil.enable); - BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 7); - OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7); -#endif - - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); - OUT_RING (chan, d->alpha.enabled); - - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 1); - OUT_RING (chan, d->alpha.func); - - BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_REF, 1); - OUT_RING (chan, d->alpha.ref); -} - -static void nv10_state_emit_viewport(struct nv10_context* nv10) -{ -} - -static void nv10_state_emit_scissor(struct nv10_context* nv10) -{ - // XXX this is so not working -/* struct pipe_scissor_state *s = nv10->scissor; - BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2); - OUT_RING (((s->maxx - s->minx) << 16) | s->minx); - OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ -} - -static void nv10_state_emit_framebuffer(struct nv10_context* nv10) -{ - struct pipe_framebuffer_state* fb = nv10->framebuffer; - struct nv04_surface *rt, *zeta = NULL; - uint32_t rt_format, w, h; - int colour_format = 0, zeta_format = 0; - struct nv10_miptree *nv10mt = 0; - - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - - w = fb->cbufs[0]->width; - h = fb->cbufs[0]->height; - colour_format = fb->cbufs[0]->format; - rt = (struct nv04_surface *)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 = (struct nv04_surface *)fb->zsbuf; - } - - rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; - - switch (colour_format) { - case PIPE_FORMAT_X8R8G8B8_UNORM: - rt_format |= NV10TCL_RT_FORMAT_COLOR_X8R8G8B8; - break; - 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); - } - - if (zeta) { - BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (zeta->pitch << 16)); - } else { - BEGIN_RING(chan, celsius, NV10TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (rt->pitch << 16)); - } - - nv10mt = (struct nv10_miptree *)rt->base.texture; - nv10->rt[0] = nv10mt->buffer; - - if (zeta_format) - { - nv10mt = (struct nv10_miptree *)zeta->base.texture; - nv10->zeta = nv10mt->buffer; - } - - BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 3); - OUT_RING (chan, (w << 16) | 0); - OUT_RING (chan, (h << 16) | 0); - OUT_RING (chan, rt_format); - BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING (chan, ((w - 1) << 16) | 0 | 0x08000800); - OUT_RING (chan, ((h - 1) << 16) | 0 | 0x08000800); -} - -static void nv10_vertex_layout(struct nv10_context *nv10) -{ - struct nv10_fragment_program *fp = nv10->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 (fp->info.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); -} - -void -nv10_emit_hw_state(struct nv10_context *nv10) -{ - struct nv10_screen *screen = nv10->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *celsius = screen->celsius; - struct nouveau_bo *rt_bo; - int i; - - if (nv10->dirty & NV10_NEW_VERTPROG) { - //nv10_vertprog_bind(nv10, nv10->vertprog.current); - nv10->dirty &= ~NV10_NEW_VERTPROG; - } - - if (nv10->dirty & NV10_NEW_FRAGPROG) { - nv10_fragprog_bind(nv10, nv10->fragprog.current); - /*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */ - nv10->dirty_samplers |= (1<<10); - nv10->dirty_samplers = 0; - } - - if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { - nv10_fragtex_bind(nv10); - nv10->dirty &= ~NV10_NEW_FRAGPROG; - } - - if (nv10->dirty & NV10_NEW_VTXARRAYS) { - nv10->dirty &= ~NV10_NEW_VTXARRAYS; - nv10_vertex_layout(nv10); - nv10_vtxbuf_bind(nv10); - } - - if (nv10->dirty & NV10_NEW_BLEND) { - nv10->dirty &= ~NV10_NEW_BLEND; - nv10_state_emit_blend(nv10); - } - - if (nv10->dirty & NV10_NEW_BLENDCOL) { - nv10->dirty &= ~NV10_NEW_BLENDCOL; - nv10_state_emit_blend_color(nv10); - } - - if (nv10->dirty & NV10_NEW_RAST) { - nv10->dirty &= ~NV10_NEW_RAST; - nv10_state_emit_rast(nv10); - } - - if (nv10->dirty & NV10_NEW_DSA) { - nv10->dirty &= ~NV10_NEW_DSA; - nv10_state_emit_dsa(nv10); - } - - if (nv10->dirty & NV10_NEW_VIEWPORT) { - nv10->dirty &= ~NV10_NEW_VIEWPORT; - nv10_state_emit_viewport(nv10); - } - - if (nv10->dirty & NV10_NEW_SCISSOR) { - nv10->dirty &= ~NV10_NEW_SCISSOR; - nv10_state_emit_scissor(nv10); - } - - if (nv10->dirty & NV10_NEW_FRAMEBUFFER) { - nv10->dirty &= ~NV10_NEW_FRAMEBUFFER; - nv10_state_emit_framebuffer(nv10); - } - - /* Emit relocs for every referenced buffer. - * This is to ensure the bufmgr has an accurate idea of how - * 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 */ - rt_bo = nouveau_bo(nv10->rt[0]); -// XXX figre out who's who for NV10TCL_DMA_* and fill accordingly -// BEGIN_RING(chan, celsius, NV10TCL_DMA_COLOR0, 1); -// OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - if (nv10->zeta) { - struct nouveau_bo *zeta_bo = nouveau_bo(nv10->zeta); -// XXX -// BEGIN_RING(chan, celsius, NV10TCL_DMA_ZETA, 1); -// OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, celsius, NV10TCL_ZETA_OFFSET, 1); - OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - /* XXX for when we allocate LMA on nv17 */ -/* BEGIN_RING(chan, celsius, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1); - OUT_RELOCl(chan, nouveau_bo(nv10->zeta + lma_offset));*/ - } - - /* Vertex buffer */ - BEGIN_RING(chan, celsius, NV10TCL_DMA_VTXBUF0, 1); - OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, celsius, NV10TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - /* Texture images */ - for (i = 0; i < 2; i++) { - if (!(nv10->fp_samplers & (1 << i))) - continue; - struct nouveau_bo *bo = nouveau_bo(nv10->tex[i].buffer); - BEGIN_RING(chan, celsius, NV10TCL_TX_OFFSET(i), 1); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD); - BEGIN_RING(chan, celsius, NV10TCL_TX_FORMAT(i), 1); - OUT_RELOCd(chan, bo, 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 deleted file mode 100644 index 6db0164dbe5..00000000000 --- a/src/gallium/drivers/nv10/nv10_surface.c +++ /dev/null @@ -1,63 +0,0 @@ - -/************************************************************************** - * - * 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 "util/u_simple_screen.h" -#include "util/u_inlines.h" -#include "util/u_tile.h" - -static void -nv10_surface_copy(struct pipe_context *pipe, - 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 nv04_surface_2d *eng2d = nv10->screen->eng2d; - - eng2d->copy(eng2d, 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 nv04_surface_2d *eng2d = nv10->screen->eng2d; - - eng2d->fill(eng2d, 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_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c deleted file mode 100644 index e554a587301..00000000000 --- a/src/gallium/drivers/nv10/nv10_transfer.c +++ /dev/null @@ -1,178 +0,0 @@ -#include <pipe/p_state.h> -#include <pipe/p_defines.h> -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include <util/u_math.h> -#include <nouveau/nouveau_winsys.h> -#include "nv10_context.h" -#include "nv10_screen.h" -#include "nv10_state.h" - -struct nv10_transfer { - struct pipe_transfer base; - struct pipe_surface *surface; - boolean direct; -}; - -static void -nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) -{ - memset(template, 0, sizeof(struct pipe_texture)); - template->target = pt->target; - template->format = pt->format; - template->width0 = width; - template->height0 = height; - template->depth0 = 1; - template->last_level = 0; - template->nr_samples = pt->nr_samples; - - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; -} - -static struct pipe_transfer * -nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - struct nv10_miptree *mt = (struct nv10_miptree *)pt; - struct nv10_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; - - tx = CALLOC_STRUCT(nv10_transfer); - if (!tx) - return NULL; - - pipe_texture_reference(&tx->base.texture, pt); - tx->base.x = x; - tx->base.y = y; - tx->base.width = w; - tx->base.height = h; - tx->base.stride = mt->level[level].pitch; - tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; - - /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || - debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) - { - tx->direct = true; - tx->surface = pscreen->get_tex_surface(pscreen, pt, - 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); - return &tx->base; - } - - tx->direct = false; - - nv10_compatible_transfer_tex(pt, w, h, &tx_tex_template); - - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); - if (!tx_tex) - { - FREE(tx); - return NULL; - } - - tx->base.stride = ((struct nv10_miptree*)tx_tex)->level[0].pitch; - - tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); - - pipe_texture_reference(&tx_tex, NULL); - - if (!tx->surface) - { - pipe_surface_reference(&tx->surface, NULL); - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - struct nv10_screen *nvscreen = nv10_screen(pscreen); - struct pipe_surface *src; - - src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - /* TODO: Check if SIFM can un-swizzle */ - nvscreen->eng2d->copy(nvscreen->eng2d, - tx->surface, 0, 0, - src, x, y, - w, h); - - pipe_surface_reference(&src, NULL); - } - - return &tx->base; -} - -static void -nv10_transfer_del(struct pipe_transfer *ptx) -{ - struct nv10_transfer *tx = (struct nv10_transfer *)ptx; - - if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) { - struct pipe_screen *pscreen = ptx->texture->screen; - struct nv10_screen *nvscreen = nv10_screen(pscreen); - struct pipe_surface *dst; - - dst = pscreen->get_tex_surface(pscreen, ptx->texture, - ptx->face, ptx->level, ptx->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - nvscreen->eng2d->copy(nvscreen->eng2d, - dst, tx->base.x, tx->base.y, - tx->surface, 0, 0, - tx->base.width, tx->base.height); - - pipe_surface_reference(&dst, NULL); - } - - pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); - FREE(ptx); -} - -static void * -nv10_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv10_transfer *tx = (struct nv10_transfer *)ptx; - struct nv04_surface *ns = (struct nv04_surface *)tx->surface; - struct nv10_miptree *mt = (struct nv10_miptree *)tx->surface->texture; - void *map = pipe_buffer_map(pscreen, mt->buffer, - pipe_transfer_buffer_flags(ptx)); - - if(!tx->direct) - return map + ns->base.offset; - else - return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); -} - -static void -nv10_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv10_transfer *tx = (struct nv10_transfer *)ptx; - struct nv10_miptree *mt = (struct nv10_miptree *)tx->surface->texture; - - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nv10_screen_init_transfer_functions(struct pipe_screen *pscreen) -{ - pscreen->get_tex_transfer = nv10_transfer_new; - pscreen->tex_transfer_destroy = nv10_transfer_del; - pscreen->transfer_map = nv10_transfer_map; - pscreen->transfer_unmap = nv10_transfer_unmap; -} diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c deleted file mode 100644 index 31b34b5c0a8..00000000000 --- a/src/gallium/drivers/nv10/nv10_vbo.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "util/u_inlines.h" - -#include "nv10_context.h" -#include "nv10_state.h" - -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_pushbuf.h" - -void 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; - struct pipe_screen *pscreen = pipe->screen; - unsigned i; - - nv10_emit_hw_state(nv10); - - /* - * Map vertex buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv10->vtxbuf[i].buffer) { - void *buf = - pipe_buffer_map(pscreen, 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_buffer_map(pscreen, 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_set_mapped_constant_buffer(draw, - PIPE_SHADER_VERTEX, - 0, - nv10->constbuf[PIPE_SHADER_VERTEX], - nv10->constbuf_nr[PIPE_SHADER_VERTEX]); - - /* draw! */ - draw_arrays(nv10->draw, prim, start, count); - - /* - * unmap vertex/index buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv10->vtxbuf[i].buffer) { - pipe_buffer_unmap(pscreen, nv10->vtxbuf[i].buffer); - draw_set_mapped_vertex_buffer(draw, i, NULL); - } - } - if (indexBuffer) { - pipe_buffer_unmap(pscreen, indexBuffer); - draw_set_mapped_element_buffer(draw, 0, NULL); - } -} - -void nv10_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - nv10_draw_elements(pipe, NULL, 0, prim, start, count); -} - - - diff --git a/src/gallium/drivers/nv20/Makefile b/src/gallium/drivers/nv20/Makefile deleted file mode 100644 index 1305f26c591..00000000000 --- a/src/gallium/drivers/nv20/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -TOP = ../../../.. -include $(TOP)/configs/current - -LIBNAME = nv20 - -C_SOURCES = \ - nv20_clear.c \ - nv20_context.c \ - nv20_fragprog.c \ - nv20_fragtex.c \ - nv20_miptree.c \ - nv20_prim_vbuf.c \ - nv20_screen.c \ - nv20_state.c \ - nv20_state_emit.c \ - nv20_surface.c \ - nv20_transfer.c \ - nv20_vbo.c -# nv20_vertprog.c - -include ../../Makefile.template diff --git a/src/gallium/drivers/nv20/nv20_clear.c b/src/gallium/drivers/nv20/nv20_clear.c deleted file mode 100644 index 2b4490fa5e1..00000000000 --- a/src/gallium/drivers/nv20/nv20_clear.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "util/u_clear.h" - -#include "nv20_context.h" - -void -nv20_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil) -{ - util_clear(pipe, nv20_context(pipe)->framebuffer, buffers, rgba, depth, - stencil); -} diff --git a/src/gallium/drivers/nv20/nv20_context.h b/src/gallium/drivers/nv20/nv20_context.h deleted file mode 100644 index 270f6488e8a..00000000000 --- a/src/gallium/drivers/nv20/nv20_context.h +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef __NV20_CONTEXT_H__ -#define __NV20_CONTEXT_H__ - -#include <stdio.h> - -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "pipe/p_compiler.h" - -#include "util/u_memory.h" -#include "util/u_math.h" - -#include "draw/draw_vertex.h" - -#include "nouveau/nouveau_winsys.h" -#include "nouveau/nouveau_gldefs.h" -#include "nouveau/nouveau_context.h" - -#include "nv20_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 NV20_NEW_VERTPROG (1 << 0) -#define NV20_NEW_FRAGPROG (1 << 1) -#define NV20_NEW_VTXARRAYS (1 << 2) -#define NV20_NEW_BLEND (1 << 3) -#define NV20_NEW_BLENDCOL (1 << 4) -#define NV20_NEW_RAST (1 << 5) -#define NV20_NEW_DSA (1 << 6) -#define NV20_NEW_VIEWPORT (1 << 7) -#define NV20_NEW_SCISSOR (1 << 8) -#define NV20_NEW_FRAMEBUFFER (1 << 9) - -#include "nv20_screen.h" - -struct nv20_context { - struct pipe_context pipe; - - struct nouveau_winsys *nvws; - struct nv20_screen *screen; - unsigned pctx_id; - - struct draw_context *draw; - - uint32_t dirty; - - struct nv20_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; - struct nv20_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; - uint32_t lma_offset; - - struct nv20_blend_state *blend; - struct pipe_blend_color *blend_color; - struct nv20_rasterizer_state *rast; - struct nv20_depth_stencil_alpha_state *dsa; - struct pipe_viewport_state *viewport; - struct pipe_scissor_state *scissor; - struct pipe_framebuffer_state *framebuffer; - - //struct pipe_buffer *constbuf[PIPE_SHADER_TYPES]; - float *constbuf[PIPE_SHADER_TYPES][32][4]; - unsigned constbuf_nr[PIPE_SHADER_TYPES]; - - struct vertex_info vertex_info; - - struct { - struct pipe_buffer *buffer; - uint32_t format; - } tex[2]; - - unsigned vb_enable; - struct { - struct pipe_buffer *buffer; - unsigned delta; - } vb[16]; - -/* struct { - - struct nouveau_resource *exec_heap; - struct nouveau_resource *data_heap; - - struct nv20_vertex_program *active; - - struct nv20_vertex_program *current; - } vertprog; -*/ - struct { - struct nv20_fragment_program *active; - - struct nv20_fragment_program *current; - struct pipe_buffer *constant_buf; - } fragprog; - - struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; - struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS]; -}; - -static INLINE struct nv20_context * -nv20_context(struct pipe_context *pipe) -{ - return (struct nv20_context *)pipe; -} - -extern void nv20_init_state_functions(struct nv20_context *nv20); -extern void nv20_init_surface_functions(struct nv20_context *nv20); - -extern void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen); - -/* nv20_clear.c */ -extern void nv20_clear(struct pipe_context *pipe, unsigned buffers, - const float *rgba, double depth, unsigned stencil); - -/* nv20_draw.c */ -extern struct draw_stage *nv20_draw_render_stage(struct nv20_context *nv20); - -/* nv20_fragprog.c */ -extern void nv20_fragprog_bind(struct nv20_context *, - struct nv20_fragment_program *); -extern void nv20_fragprog_destroy(struct nv20_context *, - struct nv20_fragment_program *); - -/* nv20_fragtex.c */ -extern void nv20_fragtex_bind(struct nv20_context *); - -/* nv20_prim_vbuf.c */ -struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 ); -extern void nv20_vtxbuf_bind(struct nv20_context* nv20); - -/* nv20_state.c and friends */ -extern void nv20_emit_hw_state(struct nv20_context *nv20); -extern void nv20_state_tex_update(struct nv20_context *nv20); - -/* nv20_vbo.c */ -extern void nv20_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nv20_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/nv20/nv20_fragprog.c b/src/gallium/drivers/nv20/nv20_fragprog.c deleted file mode 100644 index 4f496369dd3..00000000000 --- a/src/gallium/drivers/nv20/nv20_fragprog.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_util.h" - -#include "nv20_context.h" - -void -nv20_fragprog_bind(struct nv20_context *nv20, struct nv20_fragment_program *fp) -{ -} - -void -nv20_fragprog_destroy(struct nv20_context *nv20, - struct nv20_fragment_program *fp) -{ -} - diff --git a/src/gallium/drivers/nv20/nv20_fragtex.c b/src/gallium/drivers/nv20/nv20_fragtex.c deleted file mode 100644 index dedbec73f39..00000000000 --- a/src/gallium/drivers/nv20/nv20_fragtex.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "nv20_context.h" -#include "nouveau/nouveau_util.h" - -#define _(m,tf) \ -{ \ - TRUE, \ - PIPE_FORMAT_##m, \ - NV20TCL_TX_FORMAT_FORMAT_##tf, \ -} - -struct nv20_texture_format { - boolean defined; - uint pipe; - int format; -}; - -static struct nv20_texture_format -nv20_texture_formats[] = { - _(A8R8G8B8_UNORM, A8R8G8B8), - _(A1R5G5B5_UNORM, A1R5G5B5), - _(A4R4G4B4_UNORM, A4R4G4B4), - _(L8_UNORM , L8 ), - _(A8_UNORM , A8 ), - _(A8L8_UNORM , A8L8 ), -/* _(RGB_DXT1 , DXT1, ), */ -/* _(RGBA_DXT1 , DXT1, ), */ -/* _(RGBA_DXT3 , DXT3, ), */ -/* _(RGBA_DXT5 , DXT5, ), */ - {}, -}; - -static struct nv20_texture_format * -nv20_fragtex_format(uint pipe_format) -{ - struct nv20_texture_format *tf = nv20_texture_formats; - - while (tf->defined) { - if (tf->pipe == pipe_format) - return tf; - tf++; - } - - return NULL; -} - - -static void -nv20_fragtex_build(struct nv20_context *nv20, int unit) -{ -#if 0 - struct nv20_sampler_state *ps = nv20->tex_sampler[unit]; - struct nv20_miptree *nv20mt = nv20->tex_miptree[unit]; - struct pipe_texture *pt = &nv20mt->base; - struct nv20_texture_format *tf; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - uint32_t txf, txs, txp; - - tf = nv20_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->width0) << 20; - txf |= log2i(pt->height0) << 24; - txf |= log2i(pt->depth0) << 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(chan, kelvin, NV10TCL_TX_OFFSET(unit), 8); - OUT_RELOCl(chan, nouveau_bo(nv20mt->buffer), 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - OUT_RELOCd(chan, nouveau_bo(nv20mt->buffer),txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); - OUT_RING (chan, ps->wrap); - OUT_RING (chan, 0x40000000); /* enable */ - OUT_RING (chan, txs); - OUT_RING (chan, ps->filt | 0x2000 /* magic */); - OUT_RING (chan, (pt->width0 << 16) | pt->height0); - OUT_RING (chan, ps->bcol); -#endif -} - -void -nv20_fragtex_bind(struct nv20_context *nv20) -{ -#if 0 - struct nv20_fragment_program *fp = nv20->fragprog.active; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - unsigned samplers, unit; - - samplers = nv20->fp_samplers & ~fp->samplers; - while (samplers) { - unit = ffs(samplers) - 1; - samplers &= ~(1 << unit); - - BEGIN_RING(chan, kelvin, NV10TCL_TX_ENABLE(unit), 1); - OUT_RING (chan, 0); - } - - samplers = nv20->dirty_samplers & fp->samplers; - while (samplers) { - unit = ffs(samplers) - 1; - samplers &= ~(1 << unit); - - nv20_fragtex_build(nv20, unit); - } - - nv20->fp_samplers = fp->samplers; -#endif -} - diff --git a/src/gallium/drivers/nv20/nv20_miptree.c b/src/gallium/drivers/nv20/nv20_miptree.c deleted file mode 100644 index 2d3473b0869..00000000000 --- a/src/gallium/drivers/nv20/nv20_miptree.c +++ /dev/null @@ -1,226 +0,0 @@ -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "util/u_inlines.h" -#include "util/u_format.h" -#include "util/u_math.h" - -#include "nv20_context.h" -#include "nv20_screen.h" -#include "../nv04/nv04_surface_2d.h" - -static void -nv20_miptree_layout(struct nv20_miptree *nv20mt) -{ - struct pipe_texture *pt = &nv20mt->base; - uint width = pt->width0; - uint offset = 0; - int nr_faces, l, f; - uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL | - PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_PRIMARY); - - if (pt->target == PIPE_TEXTURE_CUBE) { - nr_faces = 6; - } else { - nr_faces = 1; - } - - for (l = 0; l <= pt->last_level; l++) { - if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) - nv20mt->level[l].pitch = align(util_format_get_stride(pt->format, pt->width0), 64); - else - nv20mt->level[l].pitch = util_format_get_stride(pt->format, width); - - nv20mt->level[l].image_offset = - CALLOC(nr_faces, sizeof(unsigned)); - - width = u_minify(width, 1); - } - - for (f = 0; f < nr_faces; f++) { - for (l = 0; l < pt->last_level; l++) { - nv20mt->level[l].image_offset[f] = offset; - - if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) && - u_minify(pt->width0, l + 1) > 1 && u_minify(pt->height0, l + 1) > 1) - offset += align(nv20mt->level[l].pitch * u_minify(pt->height0, l), 64); - else - offset += nv20mt->level[l].pitch * u_minify(pt->height0, l); - } - - nv20mt->level[l].image_offset[f] = offset; - offset += nv20mt->level[l].pitch * u_minify(pt->height0, l); - } - - nv20mt->total_size = offset; -} - -static struct pipe_texture * -nv20_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, - const unsigned *stride, struct pipe_buffer *pb) -{ - struct nv20_miptree *mt; - - /* Only supports 2D, non-mipmapped textures for the moment */ - if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 || - pt->depth0 != 1) - return NULL; - - mt = CALLOC_STRUCT(nv20_miptree); - if (!mt) - return NULL; - - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = pscreen; - mt->level[0].pitch = stride[0]; - mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); - - pipe_buffer_reference(&mt->buffer, pb); - mt->bo = nouveau_bo(mt->buffer); - return &mt->base; -} - -static struct pipe_texture * -nv20_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) -{ - struct nv20_miptree *mt; - unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL | - NOUVEAU_BUFFER_USAGE_TEXTURE; - - mt = MALLOC(sizeof(struct nv20_miptree)); - if (!mt) - return NULL; - mt->base = *pt; - pipe_reference_init(&mt->base.reference, 1); - mt->base.screen = screen; - - /* Swizzled textures must be POT */ - if (pt->width0 & (pt->width0 - 1) || - pt->height0 & (pt->height0 - 1)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - else - if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | - PIPE_TEXTURE_USAGE_DISPLAY_TARGET | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - else - if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - else { - switch (pt->format) { - /* TODO: Figure out which formats can be swizzled */ - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_R16_SNORM: - { - if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE)) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - break; - } - default: - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - } - } - - if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) - buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE; - - /* apparently we can't render to swizzled surfaces smaller than 64 bytes, so make them linear. - * If the user did not ask for a render target, they can still render to it, but it will cost them an extra copy. - * This also happens for small mipmaps of large textures. */ - if (pt->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET && util_format_get_stride(pt->format, pt->width0) < 64) - mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; - - nv20_miptree_layout(mt); - - mt->buffer = screen->buffer_create(screen, 256, buf_usage, mt->total_size); - if (!mt->buffer) { - FREE(mt); - return NULL; - } - mt->bo = nouveau_bo(mt->buffer); - - return &mt->base; -} - -static void -nv20_miptree_destroy(struct pipe_texture *pt) -{ - struct nv20_miptree *nv20mt = (struct nv20_miptree *)pt; - int l; - - pipe_buffer_reference(&nv20mt->buffer, NULL); - for (l = 0; l <= pt->last_level; l++) { - if (nv20mt->level[l].image_offset) - FREE(nv20mt->level[l].image_offset); - } -} - -static struct pipe_surface * -nv20_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - unsigned flags) -{ - struct nv20_miptree *nv20mt = (struct nv20_miptree *)pt; - struct nv04_surface *ns; - - ns = CALLOC_STRUCT(nv04_surface); - if (!ns) - return NULL; - pipe_texture_reference(&ns->base.texture, pt); - ns->base.format = pt->format; - ns->base.width = u_minify(pt->width0, level); - ns->base.height = u_minify(pt->height0, level); - ns->base.usage = flags; - pipe_reference_init(&ns->base.reference, 1); - ns->base.face = face; - ns->base.level = level; - ns->base.zslice = zslice; - ns->pitch = nv20mt->level[level].pitch; - - if (pt->target == PIPE_TEXTURE_CUBE) { - ns->base.offset = nv20mt->level[level].image_offset[face]; - } else - if (pt->target == PIPE_TEXTURE_3D) { - ns->base.offset = nv20mt->level[level].image_offset[zslice]; - } else { - ns->base.offset = nv20mt->level[level].image_offset[0]; - } - - /* create a linear temporary that we can render into if necessary. - * Note that ns->pitch is always a multiple of 64 for linear surfaces and swizzled surfaces are POT, so - * ns->pitch & 63 is equivalent to (ns->pitch < 64 && swizzled)*/ - if((ns->pitch & 63) && (ns->base.usage & (PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER)) == PIPE_BUFFER_USAGE_GPU_WRITE) - return &nv04_surface_wrap_for_render(screen, ((struct nv20_screen*)screen)->eng2d, ns)->base; - - return &ns->base; -} - -static void -nv20_miptree_surface_destroy(struct pipe_surface *ps) -{ - struct nv04_surface* ns = (struct nv04_surface*)ps; - if(ns->backing) - { - struct nv20_screen* screen = (struct nv20_screen*)ps->texture->screen; - if(ns->backing->base.usage & PIPE_BUFFER_USAGE_GPU_WRITE) - screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height); - nv20_miptree_surface_destroy(&ns->backing->base); - } - - pipe_texture_reference(&ps->texture, NULL); - FREE(ps); -} - -void nv20_screen_init_miptree_functions(struct pipe_screen *pscreen) -{ - pscreen->texture_create = nv20_miptree_create; - pscreen->texture_blanket = nv20_miptree_blanket; - pscreen->texture_destroy = nv20_miptree_destroy; - pscreen->get_tex_surface = nv20_miptree_surface_get; - pscreen->tex_surface_destroy = nv20_miptree_surface_destroy; -} - diff --git a/src/gallium/drivers/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c deleted file mode 100644 index 581276ba22e..00000000000 --- a/src/gallium/drivers/nv20/nv20_prim_vbuf.c +++ /dev/null @@ -1,440 +0,0 @@ -/************************************************************************** - * - * 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 <[email protected]> - * \author Keith Whitwell <[email protected]> - */ - - -#include "util/u_debug.h" -#include "util/u_inlines.h" -#include "util/u_simple_screen.h" - -#include "nv20_context.h" -#include "nv20_state.h" - -#include "draw/draw_vbuf.h" - -/** - * Primitive renderer for nv20. - */ -struct nv20_vbuf_render { - struct vbuf_render base; - - struct nv20_context *nv20; - - /** Vertex buffer in VRAM */ - struct pipe_buffer *pbuffer; - - /** Vertex buffer in normal memory */ - void *mbuffer; - - /** Vertex size in bytes */ - /*unsigned vertex_size;*/ - - /** Hardware primitive */ - unsigned hwprim; -}; - -/** - * Basically a cast wrapper. - */ -static INLINE struct nv20_vbuf_render * -nv20_vbuf_render(struct vbuf_render *render) -{ - assert(render); - return (struct nv20_vbuf_render *)render; -} - -void nv20_vtxbuf_bind( struct nv20_context* nv20 ) -{ -#if 0 - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - int i; - for(i = 0; i < NV20TCL_VTXBUF_ADDRESS__SIZE; i++) { - BEGIN_RING(chan, kelvin, NV20TCL_VTXBUF_ADDRESS(i), 1); - OUT_RING(chan, 0/*nv20->vtxbuf*/); - BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(i) ,1); - OUT_RING(chan, 0/*XXX*/); - } -#endif -} - -static const struct vertex_info * -nv20_vbuf_render_get_vertex_info( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct nv20_context *nv20 = nv20_render->nv20; - - nv20_emit_hw_state(nv20); - - return &nv20->vertex_info; -} - -static void * -nv20__allocate_mbuffer(struct nv20_vbuf_render *nv20_render, size_t size) -{ - nv20_render->mbuffer = MALLOC(size); - return nv20_render->mbuffer; -} - -static void -nv20__allocate_pbuffer(struct nv20_vbuf_render *nv20_render, size_t size) -{ - struct pipe_screen *screen = nv20_render->nv20->pipe.screen; - nv20_render->pbuffer = screen->buffer_create(screen, 64, - PIPE_BUFFER_USAGE_VERTEX, size); -} - -static boolean -nv20_vbuf_render_allocate_vertices( struct vbuf_render *render, - ushort vertex_size, - ushort nr_vertices ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - size_t size = (size_t)vertex_size * (size_t)nr_vertices; - void *buf; - - assert(!nv20_render->pbuffer); - assert(!nv20_render->mbuffer); - - /* - * For small amount of vertices, don't bother with pipe vertex - * buffer, the data will be passed directly via the fifo. - */ - /* XXX: Pipe vertex buffers don't work. */ - if (0 && size > 16 * 1024) { - nv20__allocate_pbuffer(nv20_render, size); - /* umm yeah so this is ugly */ - buf = nv20_render->pbuffer; - } else { - buf = nv20__allocate_mbuffer(nv20_render, size); - } - - if (buf) - nv20_render->nv20->dirty |= NV20_NEW_VTXARRAYS; - - return buf ? TRUE : FALSE; -} - -static void * -nv20_vbuf_render_map_vertices( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen; - - if (nv20_render->pbuffer) { - return pipe_buffer_map(pscreen, nv20_render->pbuffer, - PIPE_BUFFER_USAGE_CPU_WRITE); - } else if (nv20_render->mbuffer) { - return nv20_render->mbuffer; - } else - assert(0); - - /* warnings be gone */ - return NULL; -} - -static void -nv20_vbuf_render_unmap_vertices( struct vbuf_render *render, - ushort min_index, - ushort max_index ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen; - - if (nv20_render->pbuffer) - pipe_buffer_unmap(pscreen, nv20_render->pbuffer); -} - -static boolean -nv20_vbuf_render_set_primitive( struct vbuf_render *render, - unsigned prim ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - unsigned hwp = nvgl_primitive(prim); - if (hwp == 0) - return FALSE; - - nv20_render->hwprim = hwp; - return TRUE; -} - -static uint32_t -nv20__vtxhwformat(unsigned stride, unsigned fields, unsigned type) -{ - return (stride << NV20TCL_VTXFMT_STRIDE_SHIFT) | - (fields << NV20TCL_VTXFMT_SIZE_SHIFT) | - (type << NV20TCL_VTXFMT_TYPE_SHIFT); -} - -static unsigned -nv20__emit_format(struct nv20_context *nv20, enum attrib_emit type, int hwattr) -{ - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - uint32_t hwfmt = 0; - unsigned fields; - - switch (type) { - case EMIT_OMIT: - hwfmt = nv20__vtxhwformat(0, 0, 2); - fields = 0; - break; - case EMIT_1F: - hwfmt = nv20__vtxhwformat(4, 1, 2); - fields = 1; - break; - case EMIT_2F: - hwfmt = nv20__vtxhwformat(8, 2, 2); - fields = 2; - break; - case EMIT_3F: - hwfmt = nv20__vtxhwformat(12, 3, 2); - fields = 3; - break; - case EMIT_4F: - hwfmt = nv20__vtxhwformat(16, 4, 2); - fields = 4; - break; - default: - NOUVEAU_ERR("unhandled attrib_emit %d\n", type); - return 0; - } - - BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(hwattr), 1); - OUT_RING(chan, hwfmt); - return fields; -} - -static unsigned -nv20__emit_vertex_array_format(struct nv20_context *nv20) -{ - struct vertex_info *vinfo = &nv20->vertex_info; - int hwattr = NV20TCL_VTXFMT__SIZE; - int attr = 0; - unsigned nr_fields = 0; - - while (hwattr-- > 0) { - if (vinfo->hwfmt[0] & (1 << hwattr)) { - nr_fields += nv20__emit_format(nv20, - vinfo->attrib[attr].emit, hwattr); - attr++; - } else - nv20__emit_format(nv20, EMIT_OMIT, hwattr); - } - - return nr_fields; -} - -static void -nv20__draw_mbuffer(struct nv20_vbuf_render *nv20_render, - const ushort *indices, - uint nr_indices) -{ - struct nv20_context *nv20 = nv20_render->nv20; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - struct vertex_info *vinfo = &nv20->vertex_info; - unsigned nr_fields; - int max_push; - ubyte *data = nv20_render->mbuffer; - int vsz = 4 * vinfo->size; - - nr_fields = nv20__emit_vertex_array_format(nv20); - - BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); - OUT_RING(chan, nv20_render->hwprim); - - max_push = 1200 / nr_fields; - while (nr_indices) { - int i; - int push = MIN2(nr_indices, max_push); - - BEGIN_RING_NI(chan, kelvin, NV20TCL_VERTEX_DATA, push * nr_fields); - for (i = 0; i < push; i++) { - /* XXX: fixme to handle other than floats? */ - int f = nr_fields; - float *attrv = (float*)&data[indices[i] * vsz]; - while (f-- > 0) - OUT_RINGf(chan, *attrv++); - } - - nr_indices -= push; - indices += push; - } - - BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); - OUT_RING(chan, NV20TCL_VERTEX_BEGIN_END_STOP); -} - -static void -nv20__draw_pbuffer(struct nv20_vbuf_render *nv20_render, - const ushort *indices, - uint nr_indices) -{ - struct nv20_context *nv20 = nv20_render->nv20; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - int push, i; - - NOUVEAU_ERR("nv20__draw_pbuffer: this path is broken.\n"); - - BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); - OUT_RELOCl(chan, nouveau_bo(nv20_render->pbuffer), 0, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); - - BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING(chan, nv20_render->hwprim); - - if (nr_indices & 1) { - BEGIN_RING(chan, kelvin, NV10TCL_VB_ELEMENT_U32, 1); - OUT_RING (chan, indices[0]); - indices++; nr_indices--; - } - - while (nr_indices) { - // XXX too big/small ? check the size - push = MIN2(nr_indices, 1200 * 2); - - BEGIN_RING_NI(chan, kelvin, NV10TCL_VB_ELEMENT_U16, push >> 1); - for (i = 0; i < push; i+=2) - OUT_RING(chan, (indices[i+1] << 16) | indices[i]); - - nr_indices -= push; - indices += push; - } - - BEGIN_RING(chan, kelvin, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); - OUT_RING (chan, 0); -} - -static void -nv20_vbuf_render_draw( struct vbuf_render *render, - const ushort *indices, - uint nr_indices) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - - nv20_emit_hw_state(nv20_render->nv20); - - if (nv20_render->pbuffer) - nv20__draw_pbuffer(nv20_render, indices, nr_indices); - else if (nv20_render->mbuffer) - nv20__draw_mbuffer(nv20_render, indices, nr_indices); - else - assert(0); -} - - -static void -nv20_vbuf_render_release_vertices( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - struct nv20_context *nv20 = nv20_render->nv20; - - if (nv20_render->pbuffer) { - pipe_buffer_reference(&nv20_render->pbuffer, NULL); - } else if (nv20_render->mbuffer) { - FREE(nv20_render->mbuffer); - nv20_render->mbuffer = NULL; - } else - assert(0); -} - - -static void -nv20_vbuf_render_destroy( struct vbuf_render *render ) -{ - struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render); - - assert(!nv20_render->pbuffer); - assert(!nv20_render->mbuffer); - - FREE(nv20_render); -} - - -/** - * Create a new primitive render. - */ -static struct vbuf_render * -nv20_vbuf_render_create( struct nv20_context *nv20 ) -{ - struct nv20_vbuf_render *nv20_render = CALLOC_STRUCT(nv20_vbuf_render); - - nv20_render->nv20 = nv20; - - nv20_render->base.max_vertex_buffer_bytes = 16*1024; - nv20_render->base.max_indices = 1024; - nv20_render->base.get_vertex_info = nv20_vbuf_render_get_vertex_info; - nv20_render->base.allocate_vertices = - nv20_vbuf_render_allocate_vertices; - nv20_render->base.map_vertices = nv20_vbuf_render_map_vertices; - nv20_render->base.unmap_vertices = nv20_vbuf_render_unmap_vertices; - nv20_render->base.set_primitive = nv20_vbuf_render_set_primitive; - nv20_render->base.draw = nv20_vbuf_render_draw; - nv20_render->base.release_vertices = nv20_vbuf_render_release_vertices; - nv20_render->base.destroy = nv20_vbuf_render_destroy; - - return &nv20_render->base; -} - - -/** - * Create a new primitive vbuf/render stage. - */ -struct draw_stage *nv20_draw_vbuf_stage( struct nv20_context *nv20 ) -{ - struct vbuf_render *render; - struct draw_stage *stage; - - render = nv20_vbuf_render_create(nv20); - if(!render) - return NULL; - - stage = draw_vbuf_stage( nv20->draw, render ); - if(!stage) { - render->destroy(render); - return NULL; - } - - return stage; -} diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c deleted file mode 100644 index df9401bcce0..00000000000 --- a/src/gallium/drivers/nv20/nv20_screen.c +++ /dev/null @@ -1,204 +0,0 @@ -#include "pipe/p_screen.h" - -#include "nv20_context.h" -#include "nv20_screen.h" - -static int -nv20_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_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; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; - case PIPE_CAP_TGSI_CONT_SUPPORTED: - return 0; - case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 0; - case NOUVEAU_CAP_HW_VTXBUF: - case NOUVEAU_CAP_HW_IDXBUF: - return 0; - case PIPE_CAP_INDEP_BLEND_ENABLE: - return 0; - case PIPE_CAP_INDEP_BLEND_FUNC: - return 0; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0; - } -} - -static float -nv20_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; - default: - NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); - return 0.0; - } -} - -static boolean -nv20_screen_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, - enum pipe_texture_target target, - unsigned tex_usage, unsigned geom_flags) -{ - if (tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) { - switch (format) { - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - return TRUE; - default: - break; - } - } else - if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) { - switch (format) { - case PIPE_FORMAT_Z24S8_UNORM: - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - return TRUE; - default: - break; - } - } else { - 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_L8_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - return TRUE; - default: - break; - } - } - - return FALSE; -} - -static void -nv20_screen_destroy(struct pipe_screen *pscreen) -{ - struct nv20_screen *screen = nv20_screen(pscreen); - - nouveau_notifier_free(&screen->sync); - nouveau_grobj_free(&screen->kelvin); - nv04_surface_2d_takedown(&screen->eng2d); - - nouveau_screen_fini(&screen->base); - - FREE(pscreen); -} - -static struct pipe_buffer * -nv20_surface_buffer(struct pipe_surface *surf) -{ - struct nv20_miptree *mt = (struct nv20_miptree *)surf->texture; - - return mt->buffer; -} - -struct pipe_screen * -nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) -{ - struct nv20_screen *screen = CALLOC_STRUCT(nv20_screen); - struct nouveau_channel *chan; - struct pipe_screen *pscreen; - unsigned kelvin_class = 0; - int ret; - - if (!screen) - return NULL; - pscreen = &screen->base.base; - - ret = nouveau_screen_init(&screen->base, dev); - if (ret) { - nv20_screen_destroy(pscreen); - return NULL; - } - chan = screen->base.channel; - - pscreen->winsys = ws; - pscreen->destroy = nv20_screen_destroy; - pscreen->get_param = nv20_screen_get_param; - pscreen->get_paramf = nv20_screen_get_paramf; - pscreen->is_format_supported = nv20_screen_is_format_supported; - - nv20_screen_init_miptree_functions(pscreen); - nv20_screen_init_transfer_functions(pscreen); - - /* 3D object */ - if (dev->chipset >= 0x25) - kelvin_class = NV25TCL; - else if (dev->chipset >= 0x20) - kelvin_class = NV20TCL; - - if (!kelvin_class || dev->chipset >= 0x30) { - NOUVEAU_ERR("Unknown nv2x chipset: nv%02x\n", dev->chipset); - return NULL; - } - - ret = nouveau_grobj_alloc(chan, 0xbeef0097, kelvin_class, - &screen->kelvin); - if (ret) { - NOUVEAU_ERR("Error creating 3D object: %d\n", ret); - return FALSE; - } - - /* 2D engine setup */ - screen->eng2d = nv04_surface_2d_init(&screen->base); - screen->eng2d->buf = nv20_surface_buffer; - - /* Notifier for sync purposes */ - ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync); - if (ret) { - NOUVEAU_ERR("Error creating notifier object: %d\n", ret); - nv20_screen_destroy(pscreen); - return NULL; - } - - return pscreen; -} - diff --git a/src/gallium/drivers/nv20/nv20_screen.h b/src/gallium/drivers/nv20/nv20_screen.h deleted file mode 100644 index fc7bb050334..00000000000 --- a/src/gallium/drivers/nv20/nv20_screen.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __NV20_SCREEN_H__ -#define __NV20_SCREEN_H__ - -#include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" - -struct nv20_screen { - struct nouveau_screen base; - - struct nouveau_winsys *nvws; - - /* HW graphics objects */ - struct nv04_surface_2d *eng2d; - struct nouveau_grobj *kelvin; - struct nouveau_notifier *sync; -}; - -static INLINE struct nv20_screen * -nv20_screen(struct pipe_screen *screen) -{ - return (struct nv20_screen *)screen; -} - - -void -nv20_screen_init_transfer_functions(struct pipe_screen *pscreen); - -#endif diff --git a/src/gallium/drivers/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c deleted file mode 100644 index 923dc61cfb2..00000000000 --- a/src/gallium/drivers/nv20/nv20_state.c +++ /dev/null @@ -1,583 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_state.h" -#include "pipe/p_defines.h" -#include "pipe/p_shader_tokens.h" -#include "util/u_inlines.h" - -#include "tgsi/tgsi_parse.h" - -#include "nv20_context.h" -#include "nv20_state.h" - -static void * -nv20_blend_state_create(struct pipe_context *pipe, - const struct pipe_blend_state *cso) -{ - struct nv20_blend_state *cb; - - cb = MALLOC(sizeof(struct nv20_blend_state)); - - cb->b_enable = cso->rt[0].blend_enable ? 1 : 0; - cb->b_srcfunc = ((nvgl_blend_func(cso->rt[0].alpha_src_factor)<<16) | - (nvgl_blend_func(cso->rt[0].rgb_src_factor))); - cb->b_dstfunc = ((nvgl_blend_func(cso->rt[0].alpha_dst_factor)<<16) | - (nvgl_blend_func(cso->rt[0].rgb_dst_factor))); - - cb->c_mask = (((cso->rt[0].colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | - ((cso->rt[0].colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | - ((cso->rt[0].colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | - ((cso->rt[0].colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); - - cb->d_enable = cso->dither ? 1 : 0; - - return (void *)cb; -} - -static void -nv20_blend_state_bind(struct pipe_context *pipe, void *blend) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - nv20->blend = (struct nv20_blend_state*)blend; - - nv20->dirty |= NV20_NEW_BLEND; -} - -static void -nv20_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 = NV20TCL_TX_WRAP_S_REPEAT; - break; - case PIPE_TEX_WRAP_MIRROR_REPEAT: - ret = NV20TCL_TX_WRAP_S_MIRRORED_REPEAT; - break; - case PIPE_TEX_WRAP_CLAMP_TO_EDGE: - ret = NV20TCL_TX_WRAP_S_CLAMP_TO_EDGE; - break; - case PIPE_TEX_WRAP_CLAMP_TO_BORDER: - ret = NV20TCL_TX_WRAP_S_CLAMP_TO_BORDER; - break; - case PIPE_TEX_WRAP_CLAMP: - ret = NV20TCL_TX_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 = NV20TCL_TX_WRAP_S_REPEAT; - break; - } - - return (ret >> NV20TCL_TX_WRAP_S_SHIFT); -} - -static void * -nv20_sampler_state_create(struct pipe_context *pipe, - const struct pipe_sampler_state *cso) -{ - struct nv20_sampler_state *ps; - uint32_t filter = 0; - - ps = MALLOC(sizeof(struct nv20_sampler_state)); - - ps->wrap = ((wrap_mode(cso->wrap_s) << NV20TCL_TX_WRAP_S_SHIFT) | - (wrap_mode(cso->wrap_t) << NV20TCL_TX_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 >= 8.0) { - ps->en |= NV20TCL_TX_ENABLE_ANISO_8X; - } else - if (cso->max_anisotropy >= 4.0) { - ps->en |= NV20TCL_TX_ENABLE_ANISO_4X; - } else { - ps->en |= NV20TCL_TX_ENABLE_ANISO_2X; - }*/ - } - - switch (cso->mag_img_filter) { - case PIPE_TEX_FILTER_LINEAR: - filter |= NV20TCL_TX_FILTER_MAGNIFY_LINEAR; - break; - case PIPE_TEX_FILTER_NEAREST: - default: - filter |= NV20TCL_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 |= - NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; - break; - case PIPE_TEX_MIPFILTER_LINEAR: - filter |= NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; - break; - case PIPE_TEX_MIPFILTER_NONE: - default: - filter |= NV20TCL_TX_FILTER_MINIFY_LINEAR; - break; - } - break; - case PIPE_TEX_FILTER_NEAREST: - default: - switch (cso->min_mip_filter) { - case PIPE_TEX_MIPFILTER_NEAREST: - filter |= - NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; - break; - case PIPE_TEX_MIPFILTER_LINEAR: - filter |= - NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; - break; - case PIPE_TEX_MIPFILTER_NONE: - default: - filter |= NV20TCL_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 -nv20_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) -{ - struct nv20_context *nv20 = nv20_context(pipe); - unsigned unit; - - for (unit = 0; unit < nr; unit++) { - nv20->tex_sampler[unit] = sampler[unit]; - nv20->dirty_samplers |= (1 << unit); - } -} - -static void -nv20_sampler_state_delete(struct pipe_context *pipe, void *hwcso) -{ - FREE(hwcso); -} - -static void -nv20_set_sampler_texture(struct pipe_context *pipe, unsigned nr, - struct pipe_texture **miptree) -{ - struct nv20_context *nv20 = nv20_context(pipe); - unsigned unit; - - for (unit = 0; unit < nr; unit++) { - nv20->tex_miptree[unit] = (struct nv20_miptree *)miptree[unit]; - nv20->dirty_samplers |= (1 << unit); - } -} - -static void * -nv20_rasterizer_state_create(struct pipe_context *pipe, - const struct pipe_rasterizer_state *cso) -{ - struct nv20_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 nv20_rasterizer_state)); - - rs->templ = cso; - - rs->shade_model = cso->flatshade ? NV20TCL_SHADE_MODEL_FLAT : - NV20TCL_SHADE_MODEL_SMOOTH; - - rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff; - rs->line_smooth_en = cso->line_smooth ? 1 : 0; - - /* XXX: nv20 and nv25 different! */ - 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 = NV20TCL_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 = NV20TCL_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 = NV20TCL_CULL_FACE_FRONT; - else - rs->cull_face = NV20TCL_CULL_FACE_BACK; - break; - case PIPE_WINDING_CW: - rs->cull_face_en = 1; - if (cso->front_winding == PIPE_WINDING_CW) - rs->cull_face = NV20TCL_CULL_FACE_FRONT; - else - rs->cull_face = NV20TCL_CULL_FACE_BACK; - break; - case PIPE_WINDING_BOTH: - rs->cull_face_en = 1; - rs->cull_face = NV20TCL_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 -nv20_rasterizer_state_bind(struct pipe_context *pipe, void *rast) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - nv20->rast = (struct nv20_rasterizer_state*)rast; - - draw_set_rasterizer_state(nv20->draw, (nv20->rast ? nv20->rast->templ : NULL)); - - nv20->dirty |= NV20_NEW_RAST; -} - -static void -nv20_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) -{ - FREE(hwcso); -} - -static void * -nv20_depth_stencil_alpha_state_create(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *cso) -{ - struct nv20_depth_stencil_alpha_state *hw; - - hw = MALLOC(sizeof(struct nv20_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].writemask; - hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func); - hw->stencil.ref = cso->stencil[0].ref_value; - hw->stencil.vmask = cso->stencil[0].valuemask; - 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_value); - - return (void *)hw; -} - -static void -nv20_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *dsa) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - nv20->dsa = (struct nv20_depth_stencil_alpha_state*)dsa; - - nv20->dirty |= NV20_NEW_DSA; -} - -static void -nv20_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) -{ - FREE(hwcso); -} - -static void * -nv20_vp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *templ) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - return draw_create_vertex_shader(nv20->draw, templ); -} - -static void -nv20_vp_state_bind(struct pipe_context *pipe, void *shader) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - draw_bind_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader); - - nv20->dirty |= NV20_NEW_VERTPROG; -} - -static void -nv20_vp_state_delete(struct pipe_context *pipe, void *shader) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - draw_delete_vertex_shader(nv20->draw, (struct draw_vertex_shader *) shader); -} - -static void * -nv20_fp_state_create(struct pipe_context *pipe, - const struct pipe_shader_state *cso) -{ - struct nv20_fragment_program *fp; - - fp = CALLOC(1, sizeof(struct nv20_fragment_program)); - fp->pipe.tokens = tgsi_dup_tokens(cso->tokens); - - tgsi_scan_shader(cso->tokens, &fp->info); - - return (void *)fp; -} - -static void -nv20_fp_state_bind(struct pipe_context *pipe, void *hwcso) -{ - struct nv20_context *nv20 = nv20_context(pipe); - struct nv20_fragment_program *fp = hwcso; - - nv20->fragprog.current = fp; - nv20->dirty |= NV20_NEW_FRAGPROG; -} - -static void -nv20_fp_state_delete(struct pipe_context *pipe, void *hwcso) -{ - struct nv20_context *nv20 = nv20_context(pipe); - struct nv20_fragment_program *fp = hwcso; - - nv20_fragprog_destroy(nv20, fp); - FREE((void*)fp->pipe.tokens); - FREE(fp); -} - -static void -nv20_set_blend_color(struct pipe_context *pipe, - const struct pipe_blend_color *bcol) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - nv20->blend_color = (struct pipe_blend_color*)bcol; - - nv20->dirty |= NV20_NEW_BLENDCOL; -} - -static void -nv20_set_clip_state(struct pipe_context *pipe, - const struct pipe_clip_state *clip) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - draw_set_clip_state(nv20->draw, clip); -} - -static void -nv20_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_buffer *buf ) -{ - struct nv20_context *nv20 = nv20_context(pipe); - struct pipe_screen *pscreen = pipe->screen; - - assert(shader < PIPE_SHADER_TYPES); - assert(index == 0); - - if (buf) { - void *mapped; - if (buf->size && - (mapped = pipe_buffer_map(pscreen, buf, PIPE_BUFFER_USAGE_CPU_READ))) - { - memcpy(nv20->constbuf[shader], mapped, buf->size); - nv20->constbuf_nr[shader] = - buf->size / (4 * sizeof(float)); - pipe_buffer_unmap(pscreen, buf); - } - } -} - -static void -nv20_set_framebuffer_state(struct pipe_context *pipe, - const struct pipe_framebuffer_state *fb) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - nv20->framebuffer = (struct pipe_framebuffer_state*)fb; - - nv20->dirty |= NV20_NEW_FRAMEBUFFER; -} - -static void -nv20_set_polygon_stipple(struct pipe_context *pipe, - const struct pipe_poly_stipple *stipple) -{ - NOUVEAU_ERR("line stipple hahaha\n"); -} - -static void -nv20_set_scissor_state(struct pipe_context *pipe, - const struct pipe_scissor_state *s) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - nv20->scissor = (struct pipe_scissor_state*)s; - - nv20->dirty |= NV20_NEW_SCISSOR; -} - -static void -nv20_set_viewport_state(struct pipe_context *pipe, - const struct pipe_viewport_state *vpt) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - nv20->viewport = (struct pipe_viewport_state*)vpt; - - draw_set_viewport_state(nv20->draw, nv20->viewport); - - nv20->dirty |= NV20_NEW_VIEWPORT; -} - -static void -nv20_set_vertex_buffers(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_buffer *vb) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - memcpy(nv20->vtxbuf, vb, sizeof(*vb) * count); - nv20->dirty |= NV20_NEW_VTXARRAYS; - - draw_set_vertex_buffers(nv20->draw, count, vb); -} - -static void -nv20_set_vertex_elements(struct pipe_context *pipe, unsigned count, - const struct pipe_vertex_element *ve) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - memcpy(nv20->vtxelt, ve, sizeof(*ve) * count); - nv20->dirty |= NV20_NEW_VTXARRAYS; - - draw_set_vertex_elements(nv20->draw, count, ve); -} - -void -nv20_init_state_functions(struct nv20_context *nv20) -{ - nv20->pipe.create_blend_state = nv20_blend_state_create; - nv20->pipe.bind_blend_state = nv20_blend_state_bind; - nv20->pipe.delete_blend_state = nv20_blend_state_delete; - - nv20->pipe.create_sampler_state = nv20_sampler_state_create; - nv20->pipe.bind_fragment_sampler_states = nv20_sampler_state_bind; - nv20->pipe.delete_sampler_state = nv20_sampler_state_delete; - nv20->pipe.set_fragment_sampler_textures = nv20_set_sampler_texture; - - nv20->pipe.create_rasterizer_state = nv20_rasterizer_state_create; - nv20->pipe.bind_rasterizer_state = nv20_rasterizer_state_bind; - nv20->pipe.delete_rasterizer_state = nv20_rasterizer_state_delete; - - nv20->pipe.create_depth_stencil_alpha_state = - nv20_depth_stencil_alpha_state_create; - nv20->pipe.bind_depth_stencil_alpha_state = - nv20_depth_stencil_alpha_state_bind; - nv20->pipe.delete_depth_stencil_alpha_state = - nv20_depth_stencil_alpha_state_delete; - - nv20->pipe.create_vs_state = nv20_vp_state_create; - nv20->pipe.bind_vs_state = nv20_vp_state_bind; - nv20->pipe.delete_vs_state = nv20_vp_state_delete; - - nv20->pipe.create_fs_state = nv20_fp_state_create; - nv20->pipe.bind_fs_state = nv20_fp_state_bind; - nv20->pipe.delete_fs_state = nv20_fp_state_delete; - - nv20->pipe.set_blend_color = nv20_set_blend_color; - nv20->pipe.set_clip_state = nv20_set_clip_state; - nv20->pipe.set_constant_buffer = nv20_set_constant_buffer; - nv20->pipe.set_framebuffer_state = nv20_set_framebuffer_state; - nv20->pipe.set_polygon_stipple = nv20_set_polygon_stipple; - nv20->pipe.set_scissor_state = nv20_set_scissor_state; - nv20->pipe.set_viewport_state = nv20_set_viewport_state; - - nv20->pipe.set_vertex_buffers = nv20_set_vertex_buffers; - nv20->pipe.set_vertex_elements = nv20_set_vertex_elements; -} - diff --git a/src/gallium/drivers/nv20/nv20_state.h b/src/gallium/drivers/nv20/nv20_state.h deleted file mode 100644 index dde41065685..00000000000 --- a/src/gallium/drivers/nv20/nv20_state.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef __NV20_STATE_H__ -#define __NV20_STATE_H__ - -#include "pipe/p_state.h" -#include "tgsi/tgsi_scan.h" - -struct nv20_blend_state { - uint32_t b_enable; - uint32_t b_srcfunc; - uint32_t b_dstfunc; - - uint32_t c_mask; - - uint32_t d_enable; -}; - -struct nv20_sampler_state { - uint32_t wrap; - uint32_t en; - uint32_t filt; - uint32_t bcol; -}; - -struct nv20_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; - - const struct pipe_rasterizer_state *templ; -}; - -struct nv20_vertex_program_exec { - uint32_t data[4]; - boolean has_branch_offset; - int const_index; -}; - -struct nv20_vertex_program_data { - int index; /* immediates == -1 */ - float value[4]; -}; - -struct nv20_vertex_program { - const struct pipe_shader_state *pipe; - - boolean translated; - struct nv20_vertex_program_exec *insns; - unsigned nr_insns; - struct nv20_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 nv20_fragment_program_data { - unsigned offset; - unsigned index; -}; - -struct nv20_fragment_program { - struct pipe_shader_state pipe; - struct tgsi_shader_info info; - - boolean translated; - boolean on_hw; - unsigned samplers; - - uint32_t *insn; - int insn_len; - - struct nv20_fragment_program_data *consts; - unsigned nr_consts; - - struct pipe_buffer *buffer; - - uint32_t fp_control; - uint32_t fp_reg_control; -}; - - -struct nv20_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 nv20_miptree { - struct pipe_texture base; - struct nouveau_bo *bo; - - 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/nv20/nv20_state_emit.c b/src/gallium/drivers/nv20/nv20_state_emit.c deleted file mode 100644 index 6bbd1fdae9d..00000000000 --- a/src/gallium/drivers/nv20/nv20_state_emit.c +++ /dev/null @@ -1,426 +0,0 @@ -#include "nv20_context.h" -#include "nv20_state.h" -#include "draw/draw_context.h" - -static void nv20_state_emit_blend(struct nv20_context* nv20) -{ - struct nv20_blend_state *b = nv20->blend; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1); - OUT_RING (chan, b->d_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1); - OUT_RING (chan, b->b_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 2); - OUT_RING (chan, b->b_srcfunc); - OUT_RING (chan, b->b_dstfunc); - - BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MASK, 1); - OUT_RING (chan, b->c_mask); -} - -static void nv20_state_emit_blend_color(struct nv20_context* nv20) -{ - struct pipe_blend_color *c = nv20->blend_color; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_COLOR, 1); - OUT_RING (chan, - (float_to_ubyte(c->color[3]) << 24)| - (float_to_ubyte(c->color[0]) << 16)| - (float_to_ubyte(c->color[1]) << 8) | - (float_to_ubyte(c->color[2]) << 0)); -} - -static void nv20_state_emit_rast(struct nv20_context* nv20) -{ - struct nv20_rasterizer_state *r = nv20->rast; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_SHADE_MODEL, 2); - OUT_RING (chan, r->shade_model); - OUT_RING (chan, r->line_width); - - - BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); - OUT_RING (chan, r->point_size); - - BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_MODE_FRONT, 2); - OUT_RING (chan, r->poly_mode_front); - OUT_RING (chan, r->poly_mode_back); - - - BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE, 2); - OUT_RING (chan, r->cull_face); - OUT_RING (chan, r->front_face); - - BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 2); - OUT_RING (chan, r->line_smooth_en); - OUT_RING (chan, r->poly_smooth_en); - - BEGIN_RING(chan, kelvin, NV20TCL_CULL_FACE_ENABLE, 1); - OUT_RING (chan, r->cull_face_en); -} - -static void nv20_state_emit_dsa(struct nv20_context* nv20) -{ - struct nv20_depth_stencil_alpha_state *d = nv20->dsa; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1); - OUT_RING (chan, d->depth.func); - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1); - OUT_RING (chan, d->depth.write_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_TEST_ENABLE, 1); - OUT_RING (chan, d->depth.test_enable); - - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1); - OUT_RING (chan, 1); - -#if 0 - BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_ENABLE, 1); - OUT_RING (chan, d->stencil.enable); - BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7); - OUT_RINGp (chan, (uint32_t *)&(d->stencil.wmask), 7); -#endif - - BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1); - OUT_RING (chan, d->alpha.enabled); - - BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 1); - OUT_RING (chan, d->alpha.func); - - BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_REF, 1); - OUT_RING (chan, d->alpha.ref); -} - -static void nv20_state_emit_viewport(struct nv20_context* nv20) -{ -} - -static void nv20_state_emit_scissor(struct nv20_context* nv20) -{ - /* NV20TCL_SCISSOR_* is probably a software method */ -/* struct pipe_scissor_state *s = nv20->scissor; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - BEGIN_RING(chan, kelvin, NV20TCL_SCISSOR_HORIZ, 2); - OUT_RING (chan, ((s->maxx - s->minx) << 16) | s->minx); - OUT_RING (chan, ((s->maxy - s->miny) << 16) | s->miny);*/ -} - -static void nv20_state_emit_framebuffer(struct nv20_context* nv20) -{ - struct pipe_framebuffer_state* fb = nv20->framebuffer; - struct nv04_surface *rt, *zeta = NULL; - uint32_t rt_format, w, h; - int colour_format = 0, zeta_format = 0; - struct nv20_miptree *nv20mt = 0; - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - - w = fb->cbufs[0]->width; - h = fb->cbufs[0]->height; - colour_format = fb->cbufs[0]->format; - rt = (struct nv04_surface *)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 = (struct nv04_surface *)fb->zsbuf; - } - - rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR | 0x20; - - switch (colour_format) { - case PIPE_FORMAT_X8R8G8B8_UNORM: - rt_format |= NV20TCL_RT_FORMAT_COLOR_X8R8G8B8; - break; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case 0: - rt_format |= NV20TCL_RT_FORMAT_COLOR_A8R8G8B8; - break; - case PIPE_FORMAT_R5G6B5_UNORM: - rt_format |= NV20TCL_RT_FORMAT_COLOR_R5G6B5; - break; - default: - assert(0); - } - - if (zeta) { - BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (zeta->pitch << 16)); - } else { - BEGIN_RING(chan, kelvin, NV20TCL_RT_PITCH, 1); - OUT_RING (chan, rt->pitch | (rt->pitch << 16)); - } - - nv20mt = (struct nv20_miptree *)rt->base.texture; - nv20->rt[0] = nv20mt->buffer; - - if (zeta_format) - { - nv20mt = (struct nv20_miptree *)zeta->base.texture; - nv20->zeta = nv20mt->buffer; - } - - BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 3); - OUT_RING (chan, (w << 16) | 0); - OUT_RING (chan, (h << 16) | 0); /*NV20TCL_RT_VERT */ - OUT_RING (chan, rt_format); /* NV20TCL_RT_FORMAT */ - BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 2); - OUT_RING (chan, ((w - 1) << 16) | 0); - OUT_RING (chan, ((h - 1) << 16) | 0); -} - -static void nv20_vertex_layout(struct nv20_context *nv20) -{ - struct nv20_fragment_program *fp = nv20->fragprog.current; - struct draw_context *dc = nv20->draw; - int src; - int i; - struct vertex_info *vinfo = &nv20->vertex_info; - const enum interp_mode colorInterp = INTERP_LINEAR; - boolean colors[2] = { FALSE }; - boolean generics[12] = { FALSE }; - boolean fog = FALSE; - - memset(vinfo, 0, sizeof(*vinfo)); - - /* - * Assumed NV20 hardware vertex attribute order: - * 0 position, 1 ?, 2 ?, 3 col0, - * 4 col1?, 5 ?, 6 ?, 7 ?, - * 8 ?, 9 tex0, 10 tex1, 11 tex2, - * 12 tex3, 13 ?, 14 ?, 15 ? - * unaccounted: wgh, nor, fog - * There are total 16 attrs. - * vinfo->hwfmt[0] has a used-bit corresponding to each of these. - * relation to TGSI_SEMANTIC_*: - * - POSITION: position (always used) - * - COLOR: col1, col0 - * - GENERIC: tex3, tex2, tex1, tex0, normal, weight - * - FOG: fog - */ - - for (i = 0; i < fp->info.num_inputs; i++) { - int isn = fp->info.input_semantic_name[i]; - int isi = fp->info.input_semantic_index[i]; - switch (isn) { - case TGSI_SEMANTIC_POSITION: - break; - case TGSI_SEMANTIC_COLOR: - assert(isi < 2); - colors[isi] = TRUE; - break; - case TGSI_SEMANTIC_GENERIC: - assert(isi < 12); - generics[isi] = TRUE; - break; - case TGSI_SEMANTIC_FOG: - fog = TRUE; - break; - default: - assert(0 && "unknown input_semantic_name"); - } - } - - /* always do position */ { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_POSITION, 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src); - vinfo->hwfmt[0] |= (1 << 0); - } - - /* two unnamed generics */ - for (i = 4; i < 6; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i - 3)); - } - - if (colors[0]) { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 0); - draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); - vinfo->hwfmt[0] |= (1 << 3); - } - - if (colors[1]) { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 1); - draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src); - vinfo->hwfmt[0] |= (1 << 4); - } - - /* four unnamed generics */ - for (i = 6; i < 10; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i - 1)); - } - - /* tex0, tex1, tex2, tex3 */ - for (i = 0; i < 4; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i + 9)); - } - - /* two unnamed generics */ - for (i = 10; i < 12; i++) { - if (!generics[i]) - continue; - src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i); - draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << (i + 3)); - } - - if (fog) { - src = draw_find_shader_output(dc, TGSI_SEMANTIC_FOG, 0); - draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); - vinfo->hwfmt[0] |= (1 << 15); - } - - draw_compute_vertex_size(vinfo); -} - -void -nv20_emit_hw_state(struct nv20_context *nv20) -{ - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; - struct nouveau_bo *rt_bo; - int i; - - if (nv20->dirty & NV20_NEW_VERTPROG) { - //nv20_vertprog_bind(nv20, nv20->vertprog.current); - nv20->dirty &= ~NV20_NEW_VERTPROG; - } - - if (nv20->dirty & NV20_NEW_FRAGPROG) { - nv20_fragprog_bind(nv20, nv20->fragprog.current); - /*XXX: clear NV20_NEW_FRAGPROG if no new program uploaded */ - nv20->dirty_samplers |= (1<<10); - nv20->dirty_samplers = 0; - } - - if (nv20->dirty_samplers || (nv20->dirty & NV20_NEW_FRAGPROG)) { - nv20_fragtex_bind(nv20); - nv20->dirty &= ~NV20_NEW_FRAGPROG; - } - - if (nv20->dirty & NV20_NEW_VTXARRAYS) { - nv20->dirty &= ~NV20_NEW_VTXARRAYS; - nv20_vertex_layout(nv20); - nv20_vtxbuf_bind(nv20); - } - - if (nv20->dirty & NV20_NEW_BLEND) { - nv20->dirty &= ~NV20_NEW_BLEND; - nv20_state_emit_blend(nv20); - } - - if (nv20->dirty & NV20_NEW_BLENDCOL) { - nv20->dirty &= ~NV20_NEW_BLENDCOL; - nv20_state_emit_blend_color(nv20); - } - - if (nv20->dirty & NV20_NEW_RAST) { - nv20->dirty &= ~NV20_NEW_RAST; - nv20_state_emit_rast(nv20); - } - - if (nv20->dirty & NV20_NEW_DSA) { - nv20->dirty &= ~NV20_NEW_DSA; - nv20_state_emit_dsa(nv20); - } - - if (nv20->dirty & NV20_NEW_VIEWPORT) { - nv20->dirty &= ~NV20_NEW_VIEWPORT; - nv20_state_emit_viewport(nv20); - } - - if (nv20->dirty & NV20_NEW_SCISSOR) { - nv20->dirty &= ~NV20_NEW_SCISSOR; - nv20_state_emit_scissor(nv20); - } - - if (nv20->dirty & NV20_NEW_FRAMEBUFFER) { - nv20->dirty &= ~NV20_NEW_FRAMEBUFFER; - nv20_state_emit_framebuffer(nv20); - } - - /* 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 nv20_vbo.c - */ - - /* Render target */ - rt_bo = nouveau_bo(nv20->rt[0]); - BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 1); - OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - if (nv20->zeta) { - struct nouveau_bo *zeta_bo = nouveau_bo(nv20->zeta); - BEGIN_RING(chan, kelvin, NV20TCL_DMA_ZETA, 1); - OUT_RELOCo(chan, zeta_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, kelvin, NV20TCL_ZETA_OFFSET, 1); - OUT_RELOCl(chan, zeta_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - /* XXX for when we allocate LMA on nv17 */ -/* BEGIN_RING(chan, kelvin, NV10TCL_LMA_DEPTH_BUFFER_OFFSET, 1); - OUT_RELOCl(chan, nouveau_bo(nv20->zeta + lma_offset));*/ - } - - /* Vertex buffer */ - BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 1); - OUT_RELOCo(chan, rt_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - BEGIN_RING(chan, kelvin, NV20TCL_COLOR_OFFSET, 1); - OUT_RELOCl(chan, rt_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); - - /* Texture images */ - for (i = 0; i < 2; i++) { - if (!(nv20->fp_samplers & (1 << i))) - continue; - struct nouveau_bo *bo = nouveau_bo(nv20->tex[i].buffer); - BEGIN_RING(chan, kelvin, NV20TCL_TX_OFFSET(i), 1); - OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD); - BEGIN_RING(chan, kelvin, NV20TCL_TX_FORMAT(i), 1); - OUT_RELOCd(chan, bo, nv20->tex[i].format, - NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | - NOUVEAU_BO_OR, NV20TCL_TX_FORMAT_DMA0, - NV20TCL_TX_FORMAT_DMA1); - } -} - diff --git a/src/gallium/drivers/nv20/nv20_surface.c b/src/gallium/drivers/nv20/nv20_surface.c deleted file mode 100644 index 5deb8cc6f1a..00000000000 --- a/src/gallium/drivers/nv20/nv20_surface.c +++ /dev/null @@ -1,63 +0,0 @@ - -/************************************************************************** - * - * 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 "nv20_context.h" -#include "pipe/p_defines.h" -#include "util/u_simple_screen.h" -#include "util/u_inlines.h" -#include "util/u_tile.h" - -static void -nv20_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - struct nv20_context *nv20 = nv20_context(pipe); - struct nv04_surface_2d *eng2d = nv20->screen->eng2d; - - eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); -} - -static void -nv20_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, - unsigned destx, unsigned desty, unsigned width, - unsigned height, unsigned value) -{ - struct nv20_context *nv20 = nv20_context(pipe); - struct nv04_surface_2d *eng2d = nv20->screen->eng2d; - - eng2d->fill(eng2d, dest, destx, desty, width, height, value); -} - -void -nv20_init_surface_functions(struct nv20_context *nv20) -{ - nv20->pipe.surface_copy = nv20_surface_copy; - nv20->pipe.surface_fill = nv20_surface_fill; -} diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c deleted file mode 100644 index c91f8b12cc2..00000000000 --- a/src/gallium/drivers/nv20/nv20_transfer.c +++ /dev/null @@ -1,178 +0,0 @@ -#include <pipe/p_state.h> -#include <pipe/p_defines.h> -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include <util/u_math.h> -#include <nouveau/nouveau_winsys.h> -#include "nv20_context.h" -#include "nv20_screen.h" -#include "nv20_state.h" - -struct nv20_transfer { - struct pipe_transfer base; - struct pipe_surface *surface; - boolean direct; -}; - -static void -nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned height, - struct pipe_texture *template) -{ - memset(template, 0, sizeof(struct pipe_texture)); - template->target = pt->target; - template->format = pt->format; - template->width0 = width; - template->height0 = height; - template->depth0 = 1; - template->last_level = 0; - template->nr_samples = pt->nr_samples; - - template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC | - NOUVEAU_TEXTURE_USAGE_LINEAR; -} - -static struct pipe_transfer * -nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt, - unsigned face, unsigned level, unsigned zslice, - enum pipe_transfer_usage usage, - unsigned x, unsigned y, unsigned w, unsigned h) -{ - struct nv20_miptree *mt = (struct nv20_miptree *)pt; - struct nv20_transfer *tx; - struct pipe_texture tx_tex_template, *tx_tex; - - tx = CALLOC_STRUCT(nv20_transfer); - if (!tx) - return NULL; - - pipe_texture_reference(&tx->base.texture, pt); - tx->base.x = x; - tx->base.y = y; - tx->base.width = w; - tx->base.height = h; - tx->base.stride = mt->level[level].pitch; - tx->base.usage = usage; - tx->base.face = face; - tx->base.level = level; - tx->base.zslice = zslice; - - /* Direct access to texture */ - if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || - debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) && - pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) - { - tx->direct = true; - tx->surface = pscreen->get_tex_surface(pscreen, pt, - 0, 0, 0, - pipe_transfer_buffer_flags(&tx->base)); - return &tx->base; - } - - tx->direct = false; - - nv20_compatible_transfer_tex(pt, w, h, &tx_tex_template); - - tx_tex = pscreen->texture_create(pscreen, &tx_tex_template); - if (!tx_tex) - { - FREE(tx); - return NULL; - } - - tx->base.stride = ((struct nv20_miptree*)tx_tex)->level[0].pitch; - - tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, - face, level, zslice, - pipe_transfer_buffer_flags(&tx->base)); - - pipe_texture_reference(&tx_tex, NULL); - - if (!tx->surface) - { - pipe_surface_reference(&tx->surface, NULL); - FREE(tx); - return NULL; - } - - if (usage & PIPE_TRANSFER_READ) { - struct nv20_screen *nvscreen = nv20_screen(pscreen); - struct pipe_surface *src; - - src = pscreen->get_tex_surface(pscreen, pt, - face, level, zslice, - PIPE_BUFFER_USAGE_GPU_READ); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - /* TODO: Check if SIFM can un-swizzle */ - nvscreen->eng2d->copy(nvscreen->eng2d, - tx->surface, 0, 0, - src, x, y, - w, h); - - pipe_surface_reference(&src, NULL); - } - - return &tx->base; -} - -static void -nv20_transfer_del(struct pipe_transfer *ptx) -{ - struct nv20_transfer *tx = (struct nv20_transfer *)ptx; - - if (!tx->direct && (ptx->usage = PIPE_TRANSFER_WRITE)) { - struct pipe_screen *pscreen = ptx->texture->screen; - struct nv20_screen *nvscreen = nv20_screen(pscreen); - struct pipe_surface *dst; - - dst = pscreen->get_tex_surface(pscreen, ptx->texture, - ptx->face, ptx->level, ptx->zslice, - PIPE_BUFFER_USAGE_GPU_WRITE | NOUVEAU_BUFFER_USAGE_NO_RENDER); - - /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ - nvscreen->eng2d->copy(nvscreen->eng2d, - dst, tx->base.x, tx->base.y, - tx->surface, 0, 0, - tx->base.width, tx->base.height); - - pipe_surface_reference(&dst, NULL); - } - - pipe_surface_reference(&tx->surface, NULL); - pipe_texture_reference(&ptx->texture, NULL); - FREE(ptx); -} - -static void * -nv20_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv20_transfer *tx = (struct nv20_transfer *)ptx; - struct nv04_surface *ns = (struct nv04_surface *)tx->surface; - struct nv20_miptree *mt = (struct nv20_miptree *)tx->surface->texture; - void *map = pipe_buffer_map(pscreen, mt->buffer, - pipe_transfer_buffer_flags(ptx)); - - if(!tx->direct) - return map + ns->base.offset; - else - return map + ns->base.offset + ptx->y * ns->pitch + ptx->x * util_format_get_blocksize(ptx->texture->format); -} - -static void -nv20_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx) -{ - struct nv20_transfer *tx = (struct nv20_transfer *)ptx; - struct nv20_miptree *mt = (struct nv20_miptree *)tx->surface->texture; - - pipe_buffer_unmap(pscreen, mt->buffer); -} - -void -nv20_screen_init_transfer_functions(struct pipe_screen *pscreen) -{ - pscreen->get_tex_transfer = nv20_transfer_new; - pscreen->tex_transfer_destroy = nv20_transfer_del; - pscreen->transfer_map = nv20_transfer_map; - pscreen->transfer_unmap = nv20_transfer_unmap; -} diff --git a/src/gallium/drivers/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c deleted file mode 100644 index 263f18706a5..00000000000 --- a/src/gallium/drivers/nv20/nv20_vbo.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "draw/draw_context.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "util/u_inlines.h" - -#include "nv20_context.h" -#include "nv20_state.h" - -#include "nouveau/nouveau_channel.h" -#include "nouveau/nouveau_pushbuf.h" - -void nv20_draw_elements( struct pipe_context *pipe, - struct pipe_buffer *indexBuffer, - unsigned indexSize, - unsigned prim, unsigned start, unsigned count) -{ - struct pipe_screen *pscreen = pipe->screen; - struct nv20_context *nv20 = nv20_context( pipe ); - struct draw_context *draw = nv20->draw; - unsigned i; - - nv20_emit_hw_state(nv20); - - /* - * Map vertex buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv20->vtxbuf[i].buffer) { - void *buf - = pipe_buffer_map(pscreen, - nv20->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_buffer_map(pscreen, 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_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, - nv20->constbuf[PIPE_SHADER_VERTEX], - nv20->constbuf_nr[PIPE_SHADER_VERTEX]); - - /* draw! */ - draw_arrays(nv20->draw, prim, start, count); - - /* - * unmap vertex/index buffers - */ - for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { - if (nv20->vtxbuf[i].buffer) { - pipe_buffer_unmap(pscreen, nv20->vtxbuf[i].buffer); - draw_set_mapped_vertex_buffer(draw, i, NULL); - } - } - if (indexBuffer) { - pipe_buffer_unmap(pscreen, indexBuffer); - draw_set_mapped_element_buffer(draw, 0, NULL); - } - - draw_flush(nv20->draw); -} - -void nv20_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - nv20_draw_elements(pipe, NULL, 0, prim, start, count); -} - - - diff --git a/src/gallium/drivers/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c deleted file mode 100644 index 7283ed4d005..00000000000 --- a/src/gallium/drivers/nv20/nv20_vertprog.c +++ /dev/null @@ -1,841 +0,0 @@ -#include "pipe/p_context.h" -#include "pipe/p_defines.h" -#include "pipe/p_state.h" -#include "util/u_inlines.h" - -#include "pipe/p_shader_tokens.h" -#include "tgsi/tgsi_parse.h" -#include "tgsi/tgsi_dump.h" - -#include "nv20_context.h" -#include "nv20_state.h" - -/* TODO (at least...): - * 1. Indexed consts + ARL - * 2. Arb. swz/negation - * 3. NV_vp11, NV_vp2, NV_vp3 features - * - extra arith opcodes - * - branching - * - texture sampling - * - indexed attribs - * - indexed results - * 4. bugs - */ - -#define SWZ_X 0 -#define SWZ_Y 1 -#define SWZ_Z 2 -#define SWZ_W 3 -#define MASK_X 8 -#define MASK_Y 4 -#define MASK_Z 2 -#define MASK_W 1 -#define MASK_ALL (MASK_X|MASK_Y|MASK_Z|MASK_W) -#define DEF_SCALE 0 -#define DEF_CTEST 0 -#include "nv20_shader.h" - -#define swz(s,x,y,z,w) nv20_sr_swz((s), SWZ_##x, SWZ_##y, SWZ_##z, SWZ_##w) -#define neg(s) nv20_sr_neg((s)) -#define abs(s) nv20_sr_abs((s)) - -struct nv20_vpc { - struct nv20_vertex_program *vp; - - struct nv20_vertex_program_exec *vpi; - - unsigned output_map[PIPE_MAX_SHADER_OUTPUTS]; - - int high_temp; - int temp_temp_count; - - struct nv20_sreg *imm; - unsigned nr_imm; -}; - -static struct nv20_sreg -temp(struct nv20_vpc *vpc) -{ - int idx; - - idx = vpc->temp_temp_count++; - idx += vpc->high_temp + 1; - return nv20_sr(NV30SR_TEMP, idx); -} - -static struct nv20_sreg -constant(struct nv20_vpc *vpc, int pipe, float x, float y, float z, float w) -{ - struct nv20_vertex_program *vp = vpc->vp; - struct nv20_vertex_program_data *vpd; - int idx; - - if (pipe >= 0) { - for (idx = 0; idx < vp->nr_consts; idx++) { - if (vp->consts[idx].index == pipe) - return nv20_sr(NV30SR_CONST, idx); - } - } - - idx = vp->nr_consts++; - vp->consts = realloc(vp->consts, sizeof(*vpd) * vp->nr_consts); - vpd = &vp->consts[idx]; - - vpd->index = pipe; - vpd->value[0] = x; - vpd->value[1] = y; - vpd->value[2] = z; - vpd->value[3] = w; - return nv20_sr(NV30SR_CONST, idx); -} - -#define arith(cc,s,o,d,m,s0,s1,s2) \ - nv20_vp_arith((cc), (s), NV30_VP_INST_##o, (d), (m), (s0), (s1), (s2)) - -static void -emit_src(struct nv20_vpc *vpc, uint32_t *hw, int pos, struct nv20_sreg src) -{ - struct nv20_vertex_program *vp = vpc->vp; - uint32_t sr = 0; - - switch (src.type) { - case NV30SR_TEMP: - sr |= (NV30_VP_SRC_REG_TYPE_TEMP << NV30_VP_SRC_REG_TYPE_SHIFT); - sr |= (src.index << NV30_VP_SRC_TEMP_SRC_SHIFT); - break; - case NV30SR_INPUT: - sr |= (NV30_VP_SRC_REG_TYPE_INPUT << - NV30_VP_SRC_REG_TYPE_SHIFT); - vp->ir |= (1 << src.index); - hw[1] |= (src.index << NV30_VP_INST_INPUT_SRC_SHIFT); - break; - case NV30SR_CONST: - sr |= (NV30_VP_SRC_REG_TYPE_CONST << - NV30_VP_SRC_REG_TYPE_SHIFT); - assert(vpc->vpi->const_index == -1 || - vpc->vpi->const_index == src.index); - vpc->vpi->const_index = src.index; - break; - case NV30SR_NONE: - sr |= (NV30_VP_SRC_REG_TYPE_INPUT << - NV30_VP_SRC_REG_TYPE_SHIFT); - break; - default: - assert(0); - } - - if (src.negate) - sr |= NV30_VP_SRC_NEGATE; - - if (src.abs) - hw[0] |= (1 << (21 + pos)); - - sr |= ((src.swz[0] << NV30_VP_SRC_SWZ_X_SHIFT) | - (src.swz[1] << NV30_VP_SRC_SWZ_Y_SHIFT) | - (src.swz[2] << NV30_VP_SRC_SWZ_Z_SHIFT) | - (src.swz[3] << NV30_VP_SRC_SWZ_W_SHIFT)); - -/* - * |VVV| - * d�.�b - * \u/ - * - */ - - switch (pos) { - case 0: - hw[1] |= ((sr & NV30_VP_SRC0_HIGH_MASK) >> - NV30_VP_SRC0_HIGH_SHIFT) << NV30_VP_INST_SRC0H_SHIFT; - hw[2] |= (sr & NV30_VP_SRC0_LOW_MASK) << - NV30_VP_INST_SRC0L_SHIFT; - break; - case 1: - hw[2] |= sr << NV30_VP_INST_SRC1_SHIFT; - break; - case 2: - hw[2] |= ((sr & NV30_VP_SRC2_HIGH_MASK) >> - NV30_VP_SRC2_HIGH_SHIFT) << NV30_VP_INST_SRC2H_SHIFT; - hw[3] |= (sr & NV30_VP_SRC2_LOW_MASK) << - NV30_VP_INST_SRC2L_SHIFT; - break; - default: - assert(0); - } -} - -static void -emit_dst(struct nv20_vpc *vpc, uint32_t *hw, int slot, struct nv20_sreg dst) -{ - struct nv20_vertex_program *vp = vpc->vp; - - switch (dst.type) { - case NV30SR_TEMP: - hw[0] |= (dst.index << NV30_VP_INST_DEST_TEMP_ID_SHIFT); - break; - case NV30SR_OUTPUT: - switch (dst.index) { - case NV30_VP_INST_DEST_COL0 : vp->or |= (1 << 0); break; - case NV30_VP_INST_DEST_COL1 : vp->or |= (1 << 1); break; - case NV30_VP_INST_DEST_BFC0 : vp->or |= (1 << 2); break; - case NV30_VP_INST_DEST_BFC1 : vp->or |= (1 << 3); break; - case NV30_VP_INST_DEST_FOGC : vp->or |= (1 << 4); break; - case NV30_VP_INST_DEST_PSZ : vp->or |= (1 << 5); break; - case NV30_VP_INST_DEST_TC(0): vp->or |= (1 << 14); break; - case NV30_VP_INST_DEST_TC(1): vp->or |= (1 << 15); break; - case NV30_VP_INST_DEST_TC(2): vp->or |= (1 << 16); break; - case NV30_VP_INST_DEST_TC(3): vp->or |= (1 << 17); break; - case NV30_VP_INST_DEST_TC(4): vp->or |= (1 << 18); break; - case NV30_VP_INST_DEST_TC(5): vp->or |= (1 << 19); break; - case NV30_VP_INST_DEST_TC(6): vp->or |= (1 << 20); break; - case NV30_VP_INST_DEST_TC(7): vp->or |= (1 << 21); break; - default: - break; - } - - hw[3] |= (dst.index << NV30_VP_INST_DEST_SHIFT); - hw[0] |= NV30_VP_INST_VEC_DEST_TEMP_MASK | (1<<20); - - /*XXX: no way this is entirely correct, someone needs to - * figure out what exactly it is. - */ - hw[3] |= 0x800; - break; - default: - assert(0); - } -} - -static void -nv20_vp_arith(struct nv20_vpc *vpc, int slot, int op, - struct nv20_sreg dst, int mask, - struct nv20_sreg s0, struct nv20_sreg s1, - struct nv20_sreg s2) -{ - struct nv20_vertex_program *vp = vpc->vp; - uint32_t *hw; - - vp->insns = realloc(vp->insns, ++vp->nr_insns * sizeof(*vpc->vpi)); - vpc->vpi = &vp->insns[vp->nr_insns - 1]; - memset(vpc->vpi, 0, sizeof(*vpc->vpi)); - vpc->vpi->const_index = -1; - - hw = vpc->vpi->data; - - hw[0] |= (NV30_VP_INST_COND_TR << NV30_VP_INST_COND_SHIFT); - hw[0] |= ((0 << NV30_VP_INST_COND_SWZ_X_SHIFT) | - (1 << NV30_VP_INST_COND_SWZ_Y_SHIFT) | - (2 << NV30_VP_INST_COND_SWZ_Z_SHIFT) | - (3 << NV30_VP_INST_COND_SWZ_W_SHIFT)); - - hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT); -// hw[3] |= NV30_VP_INST_SCA_DEST_TEMP_MASK; -// hw[3] |= (mask << NV30_VP_INST_VEC_WRITEMASK_SHIFT); - - if (dst.type == NV30SR_OUTPUT) { - if (slot) - hw[3] |= (mask << NV30_VP_INST_SDEST_WRITEMASK_SHIFT); - else - hw[3] |= (mask << NV30_VP_INST_VDEST_WRITEMASK_SHIFT); - } else { - if (slot) - hw[3] |= (mask << NV30_VP_INST_STEMP_WRITEMASK_SHIFT); - else - hw[3] |= (mask << NV30_VP_INST_VTEMP_WRITEMASK_SHIFT); - } - - emit_dst(vpc, hw, slot, dst); - emit_src(vpc, hw, 0, s0); - emit_src(vpc, hw, 1, s1); - emit_src(vpc, hw, 2, s2); -} - -static INLINE struct nv20_sreg -tgsi_src(struct nv20_vpc *vpc, const struct tgsi_full_src_register *fsrc) { - struct nv20_sreg src; - - switch (fsrc->Register.File) { - case TGSI_FILE_INPUT: - src = nv20_sr(NV30SR_INPUT, fsrc->Register.Index); - break; - case TGSI_FILE_CONSTANT: - src = constant(vpc, fsrc->Register.Index, 0, 0, 0, 0); - break; - case TGSI_FILE_IMMEDIATE: - src = vpc->imm[fsrc->Register.Index]; - break; - case TGSI_FILE_TEMPORARY: - if (vpc->high_temp < fsrc->Register.Index) - vpc->high_temp = fsrc->Register.Index; - src = nv20_sr(NV30SR_TEMP, fsrc->Register.Index); - break; - default: - NOUVEAU_ERR("bad src file\n"); - break; - } - - src.abs = fsrc->Register.Absolute; - src.negate = fsrc->Register.Negate; - src.swz[0] = fsrc->Register.SwizzleX; - src.swz[1] = fsrc->Register.SwizzleY; - src.swz[2] = fsrc->Register.SwizzleZ; - src.swz[3] = fsrc->Register.SwizzleW; - return src; -} - -static INLINE struct nv20_sreg -tgsi_dst(struct nv20_vpc *vpc, const struct tgsi_full_dst_register *fdst) { - struct nv20_sreg dst; - - switch (fdst->Register.File) { - case TGSI_FILE_OUTPUT: - dst = nv20_sr(NV30SR_OUTPUT, - vpc->output_map[fdst->Register.Index]); - - break; - case TGSI_FILE_TEMPORARY: - dst = nv20_sr(NV30SR_TEMP, fdst->Register.Index); - if (vpc->high_temp < dst.index) - vpc->high_temp = dst.index; - break; - default: - NOUVEAU_ERR("bad dst file\n"); - break; - } - - return dst; -} - -static INLINE int -tgsi_mask(uint tgsi) -{ - int mask = 0; - - if (tgsi & TGSI_WRITEMASK_X) mask |= MASK_X; - if (tgsi & TGSI_WRITEMASK_Y) mask |= MASK_Y; - if (tgsi & TGSI_WRITEMASK_Z) mask |= MASK_Z; - if (tgsi & TGSI_WRITEMASK_W) mask |= MASK_W; - return mask; -} - -static boolean -nv20_vertprog_parse_instruction(struct nv20_vpc *vpc, - const struct tgsi_full_instruction *finst) -{ - struct nv20_sreg src[3], dst, tmp; - struct nv20_sreg none = nv20_sr(NV30SR_NONE, 0); - int mask; - int ai = -1, ci = -1; - int i; - - if (finst->Instruction.Opcode == TGSI_OPCODE_END) - return TRUE; - - vpc->temp_temp_count = 0; - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { - const struct tgsi_full_src_register *fsrc; - - fsrc = &finst->Src[i]; - if (fsrc->Register.File == TGSI_FILE_TEMPORARY) { - src[i] = tgsi_src(vpc, fsrc); - } - } - - for (i = 0; i < finst->Instruction.NumSrcRegs; i++) { - const struct tgsi_full_src_register *fsrc; - - fsrc = &finst->Src[i]; - switch (fsrc->Register.File) { - case TGSI_FILE_INPUT: - if (ai == -1 || ai == fsrc->Register.Index) { - ai = fsrc->Register.Index; - src[i] = tgsi_src(vpc, fsrc); - } else { - src[i] = temp(vpc); - arith(vpc, 0, OP_MOV, src[i], MASK_ALL, - tgsi_src(vpc, fsrc), none, none); - } - break; - /*XXX: index comparison is broken now that consts come from - * two different register files. - */ - case TGSI_FILE_CONSTANT: - case TGSI_FILE_IMMEDIATE: - if (ci == -1 || ci == fsrc->Register.Index) { - ci = fsrc->Register.Index; - src[i] = tgsi_src(vpc, fsrc); - } else { - src[i] = temp(vpc); - arith(vpc, 0, OP_MOV, src[i], MASK_ALL, - tgsi_src(vpc, fsrc), none, none); - } - break; - case TGSI_FILE_TEMPORARY: - /* handled above */ - break; - default: - NOUVEAU_ERR("bad src file\n"); - return FALSE; - } - } - - dst = tgsi_dst(vpc, &finst->Dst[0]); - mask = tgsi_mask(finst->Dst[0].Register.WriteMask); - - switch (finst->Instruction.Opcode) { - case TGSI_OPCODE_ABS: - arith(vpc, 0, OP_MOV, dst, mask, abs(src[0]), none, none); - break; - case TGSI_OPCODE_ADD: - arith(vpc, 0, OP_ADD, dst, mask, src[0], none, src[1]); - break; - case TGSI_OPCODE_ARL: - arith(vpc, 0, OP_ARL, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_DP3: - arith(vpc, 0, OP_DP3, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_DP4: - arith(vpc, 0, OP_DP4, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_DPH: - arith(vpc, 0, OP_DPH, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_DST: - arith(vpc, 0, OP_DST, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_EX2: - arith(vpc, 1, OP_EX2, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_EXP: - arith(vpc, 1, OP_EXP, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_FLR: - arith(vpc, 0, OP_FLR, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_FRC: - arith(vpc, 0, OP_FRC, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_LG2: - arith(vpc, 1, OP_LG2, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_LIT: - arith(vpc, 1, OP_LIT, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_LOG: - arith(vpc, 1, OP_LOG, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_MAD: - arith(vpc, 0, OP_MAD, dst, mask, src[0], src[1], src[2]); - break; - case TGSI_OPCODE_MAX: - arith(vpc, 0, OP_MAX, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_MIN: - arith(vpc, 0, OP_MIN, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_MOV: - arith(vpc, 0, OP_MOV, dst, mask, src[0], none, none); - break; - case TGSI_OPCODE_MUL: - arith(vpc, 0, OP_MUL, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_POW: - tmp = temp(vpc); - arith(vpc, 1, OP_LG2, tmp, MASK_X, none, none, - swz(src[0], X, X, X, X)); - arith(vpc, 0, OP_MUL, tmp, MASK_X, swz(tmp, X, X, X, X), - swz(src[1], X, X, X, X), none); - arith(vpc, 1, OP_EX2, dst, mask, none, none, - swz(tmp, X, X, X, X)); - break; - case TGSI_OPCODE_RCP: - arith(vpc, 1, OP_RCP, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_RET: - break; - case TGSI_OPCODE_RSQ: - arith(vpc, 1, OP_RSQ, dst, mask, none, none, src[0]); - break; - case TGSI_OPCODE_SGE: - arith(vpc, 0, OP_SGE, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_SGT: - arith(vpc, 0, OP_SGT, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_SLT: - arith(vpc, 0, OP_SLT, dst, mask, src[0], src[1], none); - break; - case TGSI_OPCODE_SUB: - arith(vpc, 0, OP_ADD, dst, mask, src[0], none, neg(src[1])); - break; - case TGSI_OPCODE_XPD: - tmp = temp(vpc); - arith(vpc, 0, OP_MUL, tmp, mask, - swz(src[0], Z, X, Y, Y), swz(src[1], Y, Z, X, X), none); - arith(vpc, 0, OP_MAD, dst, (mask & ~MASK_W), - swz(src[0], Y, Z, X, X), swz(src[1], Z, X, Y, Y), - neg(tmp)); - break; - default: - NOUVEAU_ERR("invalid opcode %d\n", finst->Instruction.Opcode); - return FALSE; - } - - return TRUE; -} - -static boolean -nv20_vertprog_parse_decl_output(struct nv20_vpc *vpc, - const struct tgsi_full_declaration *fdec) -{ - int hw; - - switch (fdec->Semantic.Name) { - case TGSI_SEMANTIC_POSITION: - hw = NV30_VP_INST_DEST_POS; - break; - case TGSI_SEMANTIC_COLOR: - if (fdec->Semantic.Index == 0) { - hw = NV30_VP_INST_DEST_COL0; - } else - if (fdec->Semantic.Index == 1) { - hw = NV30_VP_INST_DEST_COL1; - } else { - NOUVEAU_ERR("bad colour semantic index\n"); - return FALSE; - } - break; - case TGSI_SEMANTIC_BCOLOR: - if (fdec->Semantic.Index == 0) { - hw = NV30_VP_INST_DEST_BFC0; - } else - if (fdec->Semantic.Index == 1) { - hw = NV30_VP_INST_DEST_BFC1; - } else { - NOUVEAU_ERR("bad bcolour semantic index\n"); - return FALSE; - } - break; - case TGSI_SEMANTIC_FOG: - hw = NV30_VP_INST_DEST_FOGC; - break; - case TGSI_SEMANTIC_PSIZE: - hw = NV30_VP_INST_DEST_PSZ; - break; - case TGSI_SEMANTIC_GENERIC: - if (fdec->Semantic.Index <= 7) { - hw = NV30_VP_INST_DEST_TC(fdec->Semantic.Index); - } else { - NOUVEAU_ERR("bad generic semantic index\n"); - return FALSE; - } - break; - case TGSI_SEMANTIC_EDGEFLAG: - NOUVEAU_ERR("cannot handle edgeflag output\n"); - return FALSE; - default: - NOUVEAU_ERR("bad output semantic\n"); - return FALSE; - } - - vpc->output_map[fdec->Range.First] = hw; - return TRUE; -} - -static boolean -nv20_vertprog_prepare(struct nv20_vpc *vpc) -{ - struct tgsi_parse_context p; - int nr_imm = 0; - - tgsi_parse_init(&p, vpc->vp->pipe.tokens); - while (!tgsi_parse_end_of_tokens(&p)) { - const union tgsi_full_token *tok = &p.FullToken; - - tgsi_parse_token(&p); - switch(tok->Token.Type) { - case TGSI_TOKEN_TYPE_IMMEDIATE: - nr_imm++; - break; - default: - break; - } - } - tgsi_parse_free(&p); - - if (nr_imm) { - vpc->imm = CALLOC(nr_imm, sizeof(struct nv20_sreg)); - assert(vpc->imm); - } - - return TRUE; -} - -static void -nv20_vertprog_translate(struct nv20_context *nv20, - struct nv20_vertex_program *vp) -{ - struct tgsi_parse_context parse; - struct nv20_vpc *vpc = NULL; - - tgsi_dump(vp->pipe.tokens,0); - - vpc = CALLOC(1, sizeof(struct nv20_vpc)); - if (!vpc) - return; - vpc->vp = vp; - vpc->high_temp = -1; - - if (!nv20_vertprog_prepare(vpc)) { - FREE(vpc); - return; - } - - tgsi_parse_init(&parse, vp->pipe.tokens); - - while (!tgsi_parse_end_of_tokens(&parse)) { - tgsi_parse_token(&parse); - - switch (parse.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_DECLARATION: - { - const struct tgsi_full_declaration *fdec; - fdec = &parse.FullToken.FullDeclaration; - switch (fdec->Declaration.File) { - case TGSI_FILE_OUTPUT: - if (!nv20_vertprog_parse_decl_output(vpc, fdec)) - goto out_err; - break; - default: - break; - } - } - break; - case TGSI_TOKEN_TYPE_IMMEDIATE: - { - const struct tgsi_full_immediate *imm; - - imm = &parse.FullToken.FullImmediate; - assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); - assert(imm->Immediate.NrTokens == 4 + 1); - vpc->imm[vpc->nr_imm++] = - constant(vpc, -1, - imm->u[0].Float, - imm->u[1].Float, - imm->u[2].Float, - imm->u[3].Float); - } - break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - { - const struct tgsi_full_instruction *finst; - finst = &parse.FullToken.FullInstruction; - if (!nv20_vertprog_parse_instruction(vpc, finst)) - goto out_err; - } - break; - default: - break; - } - } - - vp->insns[vp->nr_insns - 1].data[3] |= NV30_VP_INST_LAST; - vp->translated = TRUE; -out_err: - tgsi_parse_free(&parse); - FREE(vpc); -} - -static boolean -nv20_vertprog_validate(struct nv20_context *nv20) -{ - struct pipe_screen *pscreen = nv20->pipe.screen; - struct nouveau_winsys *nvws = nv20->nvws; - struct nouveau_grobj *rankine = nv20->screen->rankine; - struct nv20_vertex_program *vp; - struct pipe_buffer *constbuf; - boolean upload_code = FALSE, upload_data = FALSE; - int i; - - vp = nv20->vertprog; - constbuf = nv20->constbuf[PIPE_SHADER_VERTEX]; - - /* Translate TGSI shader into hw bytecode */ - if (!vp->translated) { - nv20_vertprog_translate(nv20, vp); - if (!vp->translated) - return FALSE; - } - - /* Allocate hw vtxprog exec slots */ - if (!vp->exec) { - struct nouveau_resource *heap = nv20->screen->vp_exec_heap; - struct nouveau_stateobj *so; - uint vplen = vp->nr_insns; - - if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) { - while (heap->next && heap->size < vplen) { - struct nv20_vertex_program *evict; - - evict = heap->next->priv; - nvws->res_free(&evict->exec); - } - - if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) - assert(0); - } - - so = so_new(2, 0); - so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1); - so_data (so, vp->exec->start); - so_ref(so, &vp->so); - - upload_code = TRUE; - } - - /* Allocate hw vtxprog const slots */ - if (vp->nr_consts && !vp->data) { - struct nouveau_resource *heap = nv20->screen->vp_data_heap; - - if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) { - while (heap->next && heap->size < vp->nr_consts) { - struct nv20_vertex_program *evict; - - evict = heap->next->priv; - nvws->res_free(&evict->data); - } - - if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) - assert(0); - } - - /*XXX: handle this some day */ - assert(vp->data->start >= vp->data_start_min); - - upload_data = TRUE; - if (vp->data_start != vp->data->start) - upload_code = TRUE; - } - - /* If exec or data segments moved we need to patch the program to - * fixup offsets and register IDs. - */ - if (vp->exec_start != vp->exec->start) { - for (i = 0; i < vp->nr_insns; i++) { - struct nv20_vertex_program_exec *vpi = &vp->insns[i]; - - if (vpi->has_branch_offset) { - assert(0); - } - } - - vp->exec_start = vp->exec->start; - } - - if (vp->nr_consts && vp->data_start != vp->data->start) { - for (i = 0; i < vp->nr_insns; i++) { - struct nv20_vertex_program_exec *vpi = &vp->insns[i]; - - if (vpi->const_index >= 0) { - vpi->data[1] &= ~NV30_VP_INST_CONST_SRC_MASK; - vpi->data[1] |= - (vpi->const_index + vp->data->start) << - NV30_VP_INST_CONST_SRC_SHIFT; - - } - } - - vp->data_start = vp->data->start; - } - - /* Update + Upload constant values */ - if (vp->nr_consts) { - float *map = NULL; - - if (constbuf) { - map = pipe_buffer_map(pscreen, constbuf, - PIPE_BUFFER_USAGE_CPU_READ); - } - - for (i = 0; i < vp->nr_consts; i++) { - struct nv20_vertex_program_data *vpd = &vp->consts[i]; - - if (vpd->index >= 0) { - if (!upload_data && - !memcmp(vpd->value, &map[vpd->index * 4], - 4 * sizeof(float))) - continue; - memcpy(vpd->value, &map[vpd->index * 4], - 4 * sizeof(float)); - } - - BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_CONST_ID, 5); - OUT_RING (i + vp->data->start); - OUT_RINGp ((uint32_t *)vpd->value, 4); - } - - if (constbuf) - pipe_buffer_unmap(pscreen, constbuf); - } - - /* Upload vtxprog */ - if (upload_code) { -#if 0 - for (i = 0; i < vp->nr_insns; i++) { - NOUVEAU_MSG("VP inst %d: 0x%08x 0x%08x 0x%08x 0x%08x\n", - i, vp->insns[i].data[0], vp->insns[i].data[1], - vp->insns[i].data[2], vp->insns[i].data[3]); - } -#endif - BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_FROM_ID, 1); - OUT_RING (vp->exec->start); - for (i = 0; i < vp->nr_insns; i++) { - BEGIN_RING(rankine, NV34TCL_VP_UPLOAD_INST(0), 4); - OUT_RINGp (vp->insns[i].data, 4); - } - } - - if (vp->so != nv20->state.hw[NV30_STATE_VERTPROG]) { - so_ref(vp->so, &nv20->state.hw[NV30_STATE_VERTPROG]); - return TRUE; - } - - return FALSE; -} - -void -nv20_vertprog_destroy(struct nv20_context *nv20, struct nv20_vertex_program *vp) -{ - struct nouveau_winsys *nvws = nv20->screen->nvws; - - vp->translated = FALSE; - - if (vp->nr_insns) { - FREE(vp->insns); - vp->insns = NULL; - vp->nr_insns = 0; - } - - if (vp->nr_consts) { - FREE(vp->consts); - vp->consts = NULL; - vp->nr_consts = 0; - } - - nvws->res_free(&vp->exec); - vp->exec_start = 0; - nvws->res_free(&vp->data); - vp->data_start = 0; - vp->data_start_min = 0; - - vp->ir = vp->or = 0; - so_ref(NULL, &vp->so); -} - -struct nv20_state_entry nv20_state_vertprog = { - .validate = nv20_vertprog_validate, - .dirty = { - .pipe = NV30_NEW_VERTPROG /*| NV30_NEW_UCP*/, - .hw = NV30_STATE_VERTPROG, - } -}; diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c index ea8a610fe69..c29c36e20aa 100644 --- a/src/gallium/drivers/nv30/nv30_miptree.c +++ b/src/gallium/drivers/nv30/nv30_miptree.c @@ -5,7 +5,7 @@ #include "util/u_math.h" #include "nv30_context.h" -#include "../nv04/nv04_surface_2d.h" +#include "../nouveau/nv04_surface_2d.h" static void nv30_miptree_layout(struct nv30_miptree *nv30mt) diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h index 5fbd998b539..744a72de91a 100644 --- a/src/gallium/drivers/nv30/nv30_screen.h +++ b/src/gallium/drivers/nv30/nv30_screen.h @@ -3,7 +3,7 @@ #include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" +#include "nouveau/nv04_surface_2d.h" struct nv30_screen { struct nouveau_screen base; diff --git a/src/gallium/drivers/nv40/nv40_miptree.c b/src/gallium/drivers/nv40/nv40_miptree.c index d62627daa55..ad1a9a51952 100644 --- a/src/gallium/drivers/nv40/nv40_miptree.c +++ b/src/gallium/drivers/nv40/nv40_miptree.c @@ -5,7 +5,7 @@ #include "util/u_math.h" #include "nv40_context.h" -#include "../nv04/nv04_surface_2d.h" +#include "../nouveau/nv04_surface_2d.h" diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h index 57b4c8fc46c..98fde8755b9 100644 --- a/src/gallium/drivers/nv40/nv40_screen.h +++ b/src/gallium/drivers/nv40/nv40_screen.h @@ -2,7 +2,7 @@ #define __NV40_SCREEN_H__ #include "nouveau/nouveau_screen.h" -#include "nv04/nv04_surface_2d.h" +#include "nouveau/nv04_surface_2d.h" struct nv40_screen { struct nouveau_screen base; diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile index 0937f68c34b..7e95f79d03c 100644 --- a/src/gallium/winsys/drm/nouveau/dri/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -6,9 +6,6 @@ LIBNAME = nouveau_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.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/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index 75cd1e2902b..3f41e5d0ceb 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -81,15 +81,6 @@ nouveau_drm_create_screen(struct drm_api *api, int fd, return NULL; switch (dev->chipset & 0xf0) { - case 0x00: - init = nv04_screen_create; - break; - case 0x10: - init = nv10_screen_create; - break; - case 0x20: - init = nv20_screen_create; - break; case 0x30: init = nv30_screen_create; break; @@ -160,15 +151,6 @@ nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen) int i; switch (chipset & 0xf0) { - case 0x00: - init = nv04_create; - break; - case 0x10: - init = nv10_create; - break; - case 0x20: - init = nv20_create; - break; case 0x30: init = nv30_create; break; diff --git a/src/gallium/winsys/drm/nouveau/egl/Makefile b/src/gallium/winsys/drm/nouveau/egl/Makefile index 8e812acc86b..2c352603320 100644 --- a/src/gallium/winsys/drm/nouveau/egl/Makefile +++ b/src/gallium/winsys/drm/nouveau/egl/Makefile @@ -7,9 +7,6 @@ EGL_DRIVER_LIBS = -ldrm_nouveau EGL_DRIVER_PIPES = \ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.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/xorg/Makefile b/src/gallium/winsys/drm/nouveau/xorg/Makefile index f0d3b337e83..179b50230b5 100644 --- a/src/gallium/winsys/drm/nouveau/xorg/Makefile +++ b/src/gallium/winsys/drm/nouveau/xorg/Makefile @@ -18,9 +18,6 @@ INCLUDES = \ LIBS = \ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.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/g3dvl/nouveau/Makefile b/src/gallium/winsys/g3dvl/nouveau/Makefile index 3965bd949f4..f07a7926d63 100644 --- a/src/gallium/winsys/g3dvl/nouveau/Makefile +++ b/src/gallium/winsys/g3dvl/nouveau/Makefile @@ -20,14 +20,11 @@ LDFLAGS += -L${DRMDIR}/lib \ -L${DRIDIR}/lib \ -L${GALLIUMDIR}/winsys/drm/nouveau/common \ -L${GALLIUMDIR}/auxiliary \ - -L${GALLIUMDIR}/drivers/nv04 \ - -L${GALLIUMDIR}/drivers/nv10 \ - -L${GALLIUMDIR}/drivers/nv20 \ -L${GALLIUMDIR}/drivers/nv30 \ -L${GALLIUMDIR}/drivers/nv40 \ -L${GALLIUMDIR}/drivers/nv50 -LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -lgallium -lm +LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv30 -lnv40 -lnv50 -lgallium -lm ############################################# diff --git a/src/mesa/drivers/dri/nouveau/Makefile b/src/mesa/drivers/dri/nouveau/Makefile new file mode 100644 index 00000000000..7c895a2e4b9 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/Makefile @@ -0,0 +1,59 @@ +# src/mesa/drivers/dri/nouveau/Makefile + +TOP = ../../../../.. +include $(TOP)/configs/current + +CFLAGS += $(shell pkg-config libdrm libdrm_nouveau --cflags) +DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) + +LIBNAME = nouveau_vieux_dri.so + +MINIGLX_SOURCES = + +DRIVER_SOURCES = \ + nouveau_screen.c \ + nouveau_context.c \ + nouveau_fbo.c \ + nouveau_driver.c \ + nouveau_state.c \ + nouveau_bufferobj.c \ + nouveau_span.c \ + nouveau_bo_state.c \ + nouveau_texture.c \ + nouveau_surface.c \ + nv04_context.c \ + nv04_screen.c \ + nv04_render.c \ + nv04_state_fb.c \ + nv04_state_raster.c \ + nv04_state_tex.c \ + nv04_state_frag.c \ + nv04_surface.c \ + nv10_context.c \ + nv10_screen.c \ + nv10_render.c \ + nv10_state_fb.c \ + nv10_state_polygon.c \ + nv10_state_raster.c \ + nv10_state_tex.c \ + nv10_state_frag.c \ + nv10_state_tnl.c \ + nv20_context.c \ + nv20_screen.c \ + nv20_render.c \ + nv20_state_fb.c \ + nv20_state_polygon.c \ + nv20_state_raster.c \ + nv20_state_tex.c \ + nv20_state_tnl.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + + +include ../Makefile.template + +symlinks: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c new file mode 100644 index 00000000000..664632f407d --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" + +static GLboolean +nouveau_bo_marker_emit(GLcontext *ctx, struct nouveau_bo_marker *m, + uint32_t flags) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_pushbuf *push = chan->pushbuf; + uint32_t packet; + + if (m->gr->bound == NOUVEAU_GROBJ_UNBOUND) + nouveau_grobj_autobind(m->gr); + + if (MARK_RING(chan, 2, 2)) + return GL_FALSE; + + push->remaining -= 2; + packet = (m->gr->subc << 13) | (1 << 18) | m->mthd; + + if (flags) { + if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, + packet, 0, flags | + (m->flags & (NOUVEAU_BO_VRAM | + NOUVEAU_BO_GART | + NOUVEAU_BO_RDWR)), + 0, 0)) + goto fail; + } else { + *(push->cur++) = packet; + } + + if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, m->data, + m->data2, flags | m->flags, + m->vor, m->tor)) + goto fail; + + return GL_TRUE; + +fail: + MARK_UNDO(chan); + return GL_FALSE; +} + +static GLboolean +nouveau_bo_context_grow(struct nouveau_bo_context *bctx) +{ + struct nouveau_bo_marker *marker = bctx->marker; + int allocated = bctx->allocated + 1; + + marker = realloc(marker, allocated * sizeof(struct nouveau_bo_marker)); + if (!marker) + return GL_FALSE; + + bctx->marker = marker; + bctx->allocated = allocated; + + return GL_TRUE; +} + +GLboolean +nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr, + uint32_t mthd, struct nouveau_bo *bo, + uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor, + uint32_t flags) +{ + struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo; + struct nouveau_bo_marker *m; + + if (bctx->count == bctx->allocated) { + if (!nouveau_bo_context_grow(bctx)) + goto fail; + } + + m = &bctx->marker[bctx->count]; + + *m = (struct nouveau_bo_marker) { + .gr = gr, + .mthd = mthd, + .data = data, + .data2 = data2, + .vor = vor, + .tor = tor, + .flags = flags, + }; + nouveau_bo_ref(bo, &m->bo); + + s->count++; + bctx->count++; + + if (!nouveau_bo_marker_emit(bctx->ctx, m, 0)) + goto fail; + + return GL_TRUE; + +fail: + nouveau_bo_context_reset(bctx); + return GL_FALSE; +} + +void +nouveau_bo_context_reset(struct nouveau_bo_context *bctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(bctx->ctx)->bo; + int i; + + for (i = 0; i < bctx->count; i++) + nouveau_bo_ref(NULL, &bctx->marker[i].bo); + + s->count -= bctx->count; + bctx->count = 0; +} + +GLboolean +nouveau_bo_state_emit(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i, j; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) { + struct nouveau_bo_context *bctx = &s->context[i]; + + for (j = 0; j < bctx->count; j++) { + if (!nouveau_bo_marker_emit(ctx, &bctx->marker[j], + NOUVEAU_BO_DUMMY)) + return GL_FALSE; + } + } + + return GL_TRUE; +} + +void +nouveau_bo_state_init(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) + s->context[i].ctx = ctx; +} + +void +nouveau_bo_state_destroy(GLcontext *ctx) +{ + struct nouveau_bo_state *s = &to_nouveau_context(ctx)->bo; + int i, j; + + for (i = 0; i < NUM_NOUVEAU_BO_CONTEXT; i++) { + struct nouveau_bo_context *bctx = &s->context[i]; + + for (j = 0; j < bctx->count; j++) + nouveau_bo_ref(NULL, &bctx->marker[j].bo); + + if (bctx->marker) + free(bctx->marker); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h new file mode 100644 index 00000000000..da0a3a5c6fe --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_BO_STATE_H__ +#define __NOUVEAU_BO_STATE_H__ + +enum { + NOUVEAU_BO_CONTEXT_FRAMEBUFFER = 0, + NOUVEAU_BO_CONTEXT_LMA_DEPTH, + NOUVEAU_BO_CONTEXT_SURFACE, + NOUVEAU_BO_CONTEXT_TEXTURE0, + NOUVEAU_BO_CONTEXT_TEXTURE1, + NOUVEAU_BO_CONTEXT_TEXTURE2, + NOUVEAU_BO_CONTEXT_TEXTURE3, + NOUVEAU_BO_CONTEXT_VERTEX, + NUM_NOUVEAU_BO_CONTEXT +}; + +struct nouveau_bo_marker { + struct nouveau_grobj *gr; + uint32_t mthd; + + struct nouveau_bo *bo; + uint32_t data; + uint32_t data2; + uint32_t vor; + uint32_t tor; + uint32_t flags; +}; + +struct nouveau_bo_context { + GLcontext *ctx; + + struct nouveau_bo_marker *marker; + int allocated; + int count; +}; + +struct nouveau_bo_state { + struct nouveau_bo_context context[NUM_NOUVEAU_BO_CONTEXT]; + int count; +}; + +GLboolean +nouveau_bo_mark(struct nouveau_bo_context *bctx, struct nouveau_grobj *gr, + uint32_t mthd, struct nouveau_bo *bo, + uint32_t data, uint32_t data2, uint32_t vor, uint32_t tor, + uint32_t flags); + +#define nouveau_bo_markl(bctx, gr, mthd, bo, data, flags) \ + nouveau_bo_mark(bctx, gr, mthd, bo, data, 0, 0, 0, \ + flags | NOUVEAU_BO_LOW); + +#define nouveau_bo_marko(bctx, gr, mthd, bo, flags) \ + nouveau_bo_mark(bctx, gr, mthd, bo, 0, 0, \ + context_chan(ctx)->vram->handle, \ + context_chan(ctx)->gart->handle, \ + flags | NOUVEAU_BO_OR); + +void +nouveau_bo_context_reset(struct nouveau_bo_context *bctx); + +GLboolean +nouveau_bo_state_emit(GLcontext *ctx); + +void +nouveau_bo_state_init(GLcontext *ctx); + +void +nouveau_bo_state_destroy(GLcontext *ctx); + +#define __context_bctx(ctx, i) \ + ({ \ + struct nouveau_context *nctx = to_nouveau_context(ctx); \ + struct nouveau_bo_context *bctx = &nctx->bo.context[i]; \ + nouveau_bo_context_reset(bctx); \ + bctx; \ + }) +#define context_bctx(ctx, s) \ + __context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s) +#define context_bctx_i(ctx, s, i) \ + __context_bctx(ctx, NOUVEAU_BO_CONTEXT_##s##0 + (i)) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c new file mode 100644 index 00000000000..1118b96de12 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_bufferobj.h" +#include "nouveau_context.h" + +#include "main/bufferobj.h" + +static struct gl_buffer_object * +nouveau_bufferobj_new(GLcontext *ctx, GLuint buffer, GLenum target) +{ + struct nouveau_bufferobj *nbo; + + nbo = CALLOC_STRUCT(nouveau_bufferobj); + if (!nbo) + return NULL; + + _mesa_initialize_buffer_object(&nbo->base, buffer, target); + + return &nbo->base; +} + +static void +nouveau_bufferobj_del(GLcontext *ctx, struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_ref(NULL, &nbo->bo); + FREE(nbo); +} + +static GLboolean +nouveau_bufferobj_data(GLcontext *ctx, GLenum target, GLsizeiptrARB size, + const GLvoid *data, GLenum usage, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + int ret; + + obj->Size = size; + obj->Usage = usage; + + nouveau_bo_ref(NULL, &nbo->bo); + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0, + size, &nbo->bo); + assert(!ret); + + if (data) { + nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR); + _mesa_memcpy(nbo->bo->map, data, size); + nouveau_bo_unmap(nbo->bo); + } + + return GL_TRUE; +} + +static void +nouveau_bufferobj_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, const GLvoid *data, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_map(nbo->bo, NOUVEAU_BO_WR); + _mesa_memcpy(nbo->bo->map + offset, data, size); + nouveau_bo_unmap(nbo->bo); +} + +static void +nouveau_bufferobj_get_subdata(GLcontext *ctx, GLenum target, GLintptrARB offset, + GLsizeiptrARB size, GLvoid *data, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + nouveau_bo_map(nbo->bo, NOUVEAU_BO_RD); + _mesa_memcpy(data, nbo->bo->map + offset, size); + nouveau_bo_unmap(nbo->bo); +} + +static void * +nouveau_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access, + struct gl_buffer_object *obj) +{ + return ctx->Driver.MapBufferRange(ctx, target, 0, obj->Size, access, + obj); +} + +static void * +nouveau_bufferobj_map_range(GLcontext *ctx, GLenum target, GLintptr offset, + GLsizeiptr length, GLenum access, + struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + uint32_t flags = 0; + + assert(!obj->Pointer); + + if (!nbo->bo) + return NULL; + + if (access == GL_READ_ONLY_ARB || + access == GL_READ_WRITE_ARB) + flags |= NOUVEAU_BO_RD; + if (access == GL_WRITE_ONLY_ARB || + access == GL_READ_WRITE_ARB) + flags |= NOUVEAU_BO_WR; + + nouveau_bo_map_range(nbo->bo, offset, length, flags); + + obj->Pointer = nbo->bo->map; + obj->Offset = offset; + obj->Length = length; + obj->AccessFlags = access; + + return obj->Pointer; +} + +static GLboolean +nouveau_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) +{ + struct nouveau_bufferobj *nbo = to_nouveau_bufferobj(obj); + + assert(obj->Pointer); + + nouveau_bo_unmap(nbo->bo); + + obj->Pointer = NULL; + obj->Offset = 0; + obj->Length = 0; + obj->AccessFlags = 0; + + return GL_TRUE; +} + +void +nouveau_bufferobj_functions_init(struct dd_function_table *functions) +{ + functions->NewBufferObject = nouveau_bufferobj_new; + functions->DeleteBuffer = nouveau_bufferobj_del; + functions->BufferData = nouveau_bufferobj_data; + functions->BufferSubData = nouveau_bufferobj_subdata; + functions->GetBufferSubData = nouveau_bufferobj_get_subdata; + functions->MapBuffer = nouveau_bufferobj_map; + functions->MapBufferRange = nouveau_bufferobj_map_range; + functions->UnmapBuffer = nouveau_bufferobj_unmap; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h new file mode 100644 index 00000000000..acfc4cb9a90 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_BUFFEROBJ_H__ +#define __NOUVEAU_BUFFEROBJ_H__ + +struct nouveau_bufferobj { + struct gl_buffer_object base; + struct nouveau_bo *bo; +}; +#define to_nouveau_bufferobj(x) ((struct nouveau_bufferobj *)(x)) + +void +nouveau_bufferobj_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c new file mode 100644 index 00000000000..b87b8dbdd02 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_bufferobj.h" +#include "nouveau_fbo.h" + +#include "main/dd.h" +#include "main/framebuffer.h" +#include "main/light.h" +#include "main/state.h" +#include "drivers/common/meta.h" +#include "drivers/common/driverfuncs.h" +#include "swrast/swrast.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" + +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_fog_coord + +#include "main/remap_helper.h" + +static const struct dri_extension nouveau_extensions[] = { + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { "GL_ARB_multitexture", NULL }, + { "GL_EXT_texture_lod_bias", NULL }, + { "GL_SGIS_generate_mipmap", NULL }, + { "GL_ARB_texture_env_combine", NULL }, + { "GL_ARB_texture_env_dot3", NULL }, + { "GL_ARB_texture_env_add", NULL }, + { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, + { NULL, NULL } +}; + +GLboolean +nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx, + void *share_ctx) +{ + __DRIscreen *dri_screen = dri_ctx->driScreenPriv; + struct nouveau_screen *screen = dri_screen->private; + struct nouveau_context *nctx; + GLcontext *ctx; + + ctx = screen->driver->context_create(screen, visual, share_ctx); + if (!ctx) + return GL_FALSE; + + nctx = to_nouveau_context(ctx); + nctx->dri_context = dri_ctx; + dri_ctx->driverPrivate = ctx; + + return GL_TRUE; +} + +GLboolean +nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen, + const GLvisual *visual, GLcontext *share_ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct dd_function_table functions; + + nctx->screen = screen; + nctx->fallback = HWTNL; + + /* Initialize the function pointers */ + _mesa_init_driver_functions(&functions); + nouveau_driver_functions_init(&functions); + nouveau_bufferobj_functions_init(&functions); + nouveau_texture_functions_init(&functions); + nouveau_fbo_functions_init(&functions); + + /* Initialize the mesa context */ + _mesa_initialize_context(ctx, visual, share_ctx, &functions, NULL); + + nouveau_state_init(ctx); + nouveau_bo_state_init(ctx); + _mesa_meta_init(ctx); + _swrast_CreateContext(ctx); + _vbo_CreateContext(ctx); + _tnl_CreateContext(ctx); + nouveau_span_functions_init(ctx); + _mesa_allow_light_in_model(ctx, GL_FALSE); + + /* Enable any supported extensions */ + driInitExtensions(ctx, nouveau_extensions, GL_TRUE); + + return GL_TRUE; +} + +void +nouveau_context_destroy(__DRIcontext *dri_ctx) +{ + struct nouveau_context *nctx = dri_ctx->driverPrivate; + GLcontext *ctx = &nctx->base; + + if (nctx->screen->context == nctx) + nctx->screen->context = NULL; + + _tnl_DestroyContext(ctx); + _vbo_DestroyContext(ctx); + _swrast_DestroyContext(ctx); + _mesa_meta_free(ctx); + nouveau_bo_state_destroy(ctx); + context_drv(ctx)->context_destroy(ctx); +} + +static void +nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, + unsigned int *stamp) +{ + struct nouveau_context *nctx = context->driverPrivate; + GLcontext *ctx = &nctx->base; + __DRIscreen *screen = context->driScreenPriv; + struct gl_framebuffer *fb = drawable->driverPrivate; + unsigned int attachments[10]; + __DRIbuffer *buffers = NULL; + int i = 0, count, ret; + + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (fb->Visual.doubleBufferMode) + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (fb->Visual.haveDepthBuffer && fb->Visual.haveStencilBuffer) + attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + else if (fb->Visual.haveDepthBuffer) + attachments[i++] = __DRI_BUFFER_DEPTH; + else if (fb->Visual.haveStencilBuffer) + attachments[i++] = __DRI_BUFFER_STENCIL; + + buffers = (*screen->dri2.loader->getBuffers)(drawable, + &drawable->w, &drawable->h, + attachments, i, &count, + drawable->loaderPrivate); + if (buffers == NULL) + return; + + for (i = 0; i < count; i++) { + struct gl_renderbuffer *rb; + struct nouveau_surface *s; + uint32_t old_handle; + int index; + + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + case __DRI_BUFFER_FAKE_FRONT_LEFT: + index = BUFFER_FRONT_LEFT; + break; + case __DRI_BUFFER_BACK_LEFT: + index = BUFFER_BACK_LEFT; + break; + case __DRI_BUFFER_DEPTH: + case __DRI_BUFFER_DEPTH_STENCIL: + index = BUFFER_DEPTH; + break; + case __DRI_BUFFER_STENCIL: + index = BUFFER_STENCIL; + break; + default: + assert(0); + } + + rb = fb->Attachment[index].Renderbuffer; + s = &to_nouveau_renderbuffer(rb)->surface; + + s->width = drawable->w; + s->height = drawable->h; + s->pitch = buffers[i].pitch; + s->cpp = buffers[i].cpp; + + /* Don't bother to reopen the bo if it happens to be + * the same. */ + if (s->bo) { + ret = nouveau_bo_handle_get(s->bo, &old_handle); + assert(!ret); + } + + if (!s->bo || old_handle != buffers[i].name) { + nouveau_bo_ref(NULL, &s->bo); + ret = nouveau_bo_handle_ref(context_dev(ctx), + buffers[i].name, &s->bo); + assert(!ret); + + context_dirty(ctx, FRAMEBUFFER); + } + } + + _mesa_resize_framebuffer(ctx, fb, drawable->w, drawable->h); +} + +GLboolean +nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw, + __DRIdrawable *dri_read) +{ + if (dri_ctx) { + struct nouveau_context *nctx = dri_ctx->driverPrivate; + GLcontext *ctx = &nctx->base; + + if (nctx->screen->context != nctx) { + nctx->screen->context = nctx; + BITSET_ONES(nctx->dirty); + } + + /* Ask the X server for new renderbuffers. */ + nouveau_update_renderbuffers(dri_ctx, dri_draw, + &nctx->drawable.d_stamp); + if (dri_draw != dri_read) + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->drawable.r_stamp); + + /* Pass it down to mesa. */ + _mesa_make_current(ctx, dri_draw->driverPrivate, + dri_read->driverPrivate); + _mesa_update_state(ctx); + + FIRE_RING(context_chan(ctx)); + + } else { + _mesa_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +GLboolean +nouveau_context_unbind(__DRIcontext *dri_ctx) +{ + return GL_TRUE; +} + +void +nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + nctx->fallback = MAX2(HWTNL, mode); + + if (mode < SWRAST) + nouveau_state_emit(ctx); + else + FIRE_RING(context_chan(ctx)); +} + +void +nouveau_validate_framebuffer(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + /* Someone's planning to draw something really soon. */ + nctx->drawable.dirty = GL_TRUE; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.h b/src/mesa/drivers/dri/nouveau/nouveau_context.h new file mode 100644 index 00000000000..9812963e1a8 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_CONTEXT_H__ +#define __NOUVEAU_CONTEXT_H__ + +#include "nouveau_screen.h" +#include "nouveau_state.h" +#include "nouveau_bo_state.h" +#include "nouveau_render.h" + +#include "main/bitset.h" + +enum nouveau_fallback { + HWTNL = 0, + SWTNL, + SWRAST, +}; + +struct nouveau_drawable_state { + GLboolean dirty; + unsigned int d_stamp; + unsigned int r_stamp; +}; + +struct nouveau_context { + GLcontext base; + __DRIcontext *dri_context; + struct nouveau_screen *screen; + + BITSET_DECLARE(dirty, MAX_NOUVEAU_STATE); + enum nouveau_fallback fallback; + + struct nouveau_bo_state bo; + struct nouveau_render_state render; + struct nouveau_drawable_state drawable; +}; + +#define to_nouveau_context(ctx) ((struct nouveau_context *)(ctx)) + +#define context_dev(ctx) \ + (to_nouveau_context(ctx)->screen->device) +#define context_chipset(ctx) \ + (context_dev(ctx)->chipset) +#define context_chan(ctx) \ + (to_nouveau_context(ctx)->screen->chan) +#define context_eng3d(ctx) \ + (to_nouveau_context(ctx)->screen->eng3d) +#define context_drv(ctx) \ + (to_nouveau_context(ctx)->screen->driver) +#define context_dirty(ctx, s) \ + BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s) +#define context_dirty_i(ctx, s, i) \ + BITSET_SET(to_nouveau_context(ctx)->dirty, NOUVEAU_STATE_##s##0 + i) + +GLboolean +nouveau_context_create(const __GLcontextModes *visual, __DRIcontext *dri_ctx, + void *share_ctx); + +GLboolean +nouveau_context_init(GLcontext *ctx, struct nouveau_screen *screen, + const GLvisual *visual, GLcontext *share_ctx); + +void +nouveau_context_destroy(__DRIcontext *dri_ctx); + +GLboolean +nouveau_context_make_current(__DRIcontext *dri_ctx, + __DRIdrawable *ddraw, + __DRIdrawable *rdraw); + +GLboolean +nouveau_context_unbind(__DRIcontext *dri_ctx); + +void +nouveau_fallback(GLcontext *ctx, enum nouveau_fallback mode); + +void +nouveau_validate_framebuffer(GLcontext *ctx); + +#endif + diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.c b/src/mesa/drivers/dri/nouveau/nouveau_driver.c new file mode 100644 index 00000000000..bf0e20ca81c --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" + +#include "drivers/common/meta.h" + +static const GLubyte * +nouveau_get_string(GLcontext *ctx, GLenum name) +{ + static char buffer[128]; + char hardware_name[32]; + + switch (name) { + case GL_VENDOR: + return (GLubyte *)"Nouveau"; + + case GL_RENDERER: + sprintf(hardware_name, "nv%02X", context_chipset(ctx)); + driGetRendererString(buffer, hardware_name, DRIVER_DATE, 0); + + return (GLubyte *)buffer; + default: + return NULL; + } +} + +static void +nouveau_flush(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + + FIRE_RING(chan); + + if (ctx->DrawBuffer->Name == 0 && + ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { + __DRIscreen *screen = nctx->screen->dri_screen; + __DRIdri2LoaderExtension *dri2 = screen->dri2.loader; + __DRIdrawable *drawable = nctx->dri_context->driDrawablePriv; + + dri2->flushFrontBuffer(drawable, drawable->loaderPrivate); + } + + nctx->drawable.dirty = GL_FALSE; +} + +static void +nouveau_finish(GLcontext *ctx) +{ + nouveau_flush(ctx); +} + +void +nouveau_clear(GLcontext *ctx, GLbitfield buffers) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + int x, y, w, h; + int i, buf; + + nouveau_validate_framebuffer(ctx); + get_scissors(fb, &x, &y, &w, &h); + + for (i = 0; i < BUFFER_COUNT; i++) { + struct nouveau_surface *s; + unsigned mask, value; + + buf = buffers & (1 << i); + if (!buf) + continue; + + s = &to_nouveau_renderbuffer( + fb->Attachment[i].Renderbuffer->Wrapped)->surface; + + if (buf & BUFFER_BITS_COLOR) { + mask = pack_rgba_i(s->format, ctx->Color.ColorMask[0]); + value = pack_rgba_f(s->format, ctx->Color.ClearColor); + + if (mask) + context_drv(ctx)->surface_fill( + ctx, s, mask, value, x, y, w, h); + + buffers &= ~buf; + + } else if (buf & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { + mask = pack_zs_i(s->format, + (buffers & BUFFER_BIT_DEPTH && + ctx->Depth.Mask) ? ~0 : 0, + (buffers & BUFFER_BIT_STENCIL && + ctx->Stencil.WriteMask[0]) ? ~0 : 0); + value = pack_zs_f(s->format, + ctx->Depth.Clear, + ctx->Stencil.Clear); + + if (mask) + context_drv(ctx)->surface_fill( + ctx, s, mask, value, x, y, w, h); + + buffers &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + } + } + + if (buffers) + _mesa_meta_Clear(ctx, buffers); +} + +void +nouveau_driver_functions_init(struct dd_function_table *functions) +{ + functions->GetString = nouveau_get_string; + functions->Flush = nouveau_flush; + functions->Finish = nouveau_finish; + functions->Clear = nouveau_clear; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_driver.h b/src/mesa/drivers/dri/nouveau/nouveau_driver.h new file mode 100644 index 00000000000..3b4d332d749 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_driver.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_DRIVER_H__ +#define __NOUVEAU_DRIVER_H__ + +#include "main/imports.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/formats.h" +#include "utils.h" +#include "dri_util.h" + +#undef NDEBUG +#include <assert.h> + +#include "nouveau_device.h" +#include "nouveau_pushbuf.h" +#include "nouveau_grobj.h" +#include "nouveau_channel.h" +#include "nouveau_bo.h" +#include "nouveau_notifier.h" +#include "nouveau_screen.h" +#include "nouveau_state.h" +#include "nouveau_surface.h" + +#define DRIVER_DATE "20091015" +#define DRIVER_AUTHOR "Nouveau" + +struct nouveau_driver { + void (*screen_destroy)(struct nouveau_screen *screen); + + GLcontext *(*context_create)(struct nouveau_screen *screen, + const GLvisual *visual, + GLcontext *share_ctx); + void (*context_destroy)(GLcontext *ctx); + + void (*surface_copy)(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, int w, int h); + void (*surface_fill)(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h); + + nouveau_state_func *emit; + int num_emit; +}; + +#define nouveau_error(format, ...) \ + _mesa_fprintf(stderr, "%s: " format, __func__, ## __VA_ARGS__) + +void +nouveau_clear(GLcontext *ctx, GLbitfield buffers); + +void +nouveau_span_functions_init(GLcontext *ctx); + +void +nouveau_driver_functions_init(struct dd_function_table *functions); + +void +nouveau_texture_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c new file mode 100644 index 00000000000..91eade8d633 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_fbo.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" + +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/fbobject.h" + +static GLboolean +set_renderbuffer_format(struct gl_renderbuffer *rb, GLenum internalFormat) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + rb->InternalFormat = internalFormat; + + switch (internalFormat) { + case GL_RGB: + case GL_RGB8: + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_XRGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; + break; + case GL_RGBA: + case GL_RGBA8: + rb->_BaseFormat = GL_RGBA; + rb->Format = MESA_FORMAT_ARGB8888; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 4; + break; + case GL_RGB5: + rb->_BaseFormat = GL_RGB; + rb->Format = MESA_FORMAT_RGB565; + rb->DataType = GL_UNSIGNED_BYTE; + s->cpp = 2; + break; + case GL_DEPTH_COMPONENT16: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->Format = MESA_FORMAT_Z16; + rb->DataType = GL_UNSIGNED_SHORT; + s->cpp = 2; + break; + case GL_DEPTH_COMPONENT24: + case GL_STENCIL_INDEX8_EXT: + case GL_DEPTH24_STENCIL8_EXT: + rb->_BaseFormat = GL_DEPTH_COMPONENT; + rb->Format = MESA_FORMAT_Z24_S8; + rb->DataType = GL_UNSIGNED_INT; + s->cpp = 4; + break; + default: + return GL_FALSE; + } + + s->format = rb->Format; + + return GL_TRUE; +} + +static GLboolean +nouveau_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + if (!set_renderbuffer_format(rb, internalFormat)) + return GL_FALSE; + + rb->Width = width; + rb->Height = height; + + nouveau_surface_alloc(ctx, s, TILED, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, + rb->Format, width, height); + + context_dirty(ctx, FRAMEBUFFER); + return GL_TRUE; +} + +static void +nouveau_renderbuffer_del(struct gl_renderbuffer *rb) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + nouveau_surface_ref(NULL, s); + FREE(rb); +} + +static struct gl_renderbuffer * +nouveau_renderbuffer_new(GLcontext *ctx, GLuint name) +{ + struct gl_renderbuffer *rb; + + rb = (struct gl_renderbuffer *) + CALLOC_STRUCT(nouveau_renderbuffer); + if (!rb) + return NULL; + + _mesa_init_renderbuffer(rb, name); + + rb->AllocStorage = nouveau_renderbuffer_storage; + rb->Delete = nouveau_renderbuffer_del; + + return rb; +} + +static GLboolean +nouveau_renderbuffer_dri_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + if (!set_renderbuffer_format(rb, internalFormat)) + return GL_FALSE; + + rb->Width = width; + rb->Height = height; + + context_dirty(ctx, FRAMEBUFFER); + return GL_TRUE; +} + +struct gl_renderbuffer * +nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable) +{ + struct gl_renderbuffer *rb; + + rb = nouveau_renderbuffer_new(NULL, 0); + if (!rb) + return NULL; + + rb->AllocStorage = nouveau_renderbuffer_dri_storage; + + if (!set_renderbuffer_format(rb, format)) { + nouveau_renderbuffer_del(rb); + return NULL; + } + + return rb; +} + +static struct gl_framebuffer * +nouveau_framebuffer_new(GLcontext *ctx, GLuint name) +{ + struct nouveau_framebuffer *nfb; + + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) + return NULL; + + _mesa_initialize_user_framebuffer(&nfb->base, name); + + return &nfb->base; +} + +struct gl_framebuffer * +nouveau_framebuffer_dri_new(const GLvisual *visual) +{ + struct nouveau_framebuffer *nfb; + + nfb = CALLOC_STRUCT(nouveau_framebuffer); + if (!nfb) + return NULL; + + _mesa_initialize_window_framebuffer(&nfb->base, visual); + + return &nfb->base; +} + +static void +nouveau_bind_framebuffer(GLcontext *ctx, GLenum target, + struct gl_framebuffer *dfb, + struct gl_framebuffer *rfb) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb, + GLenum attachment, struct gl_renderbuffer *rb) +{ + _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); + + context_dirty(ctx, FRAMEBUFFER); +} + +static GLenum +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return GL_RGBA8; + case MESA_FORMAT_RGB565: + return GL_RGB5; + default: + assert(0); + } +} + +static void +nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct gl_renderbuffer *rb = att->Renderbuffer; + struct gl_texture_image *ti = + att->Texture->Image[att->CubeMapFace][att->TextureLevel]; + int ret; + + /* Allocate a renderbuffer object for the texture if we + * haven't already done so. */ + if (!rb) { + rb = nouveau_renderbuffer_new(ctx, 0); + assert(rb); + + rb->AllocStorage = NULL; + _mesa_reference_renderbuffer(&att->Renderbuffer, rb); + } + + /* Update the renderbuffer fields from the texture. */ + ret = set_renderbuffer_format(rb, get_tex_format(ti)); + assert(ret); + + rb->Width = ti->Width; + rb->Height = ti->Height; + nouveau_surface_ref(&to_nouveau_teximage(ti)->surface, + &to_nouveau_renderbuffer(rb)->surface); + + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_finish_render_texture(GLcontext *ctx, + struct gl_renderbuffer_attachment *att) +{ + struct nouveau_renderbuffer *nrb + = to_nouveau_renderbuffer(att->Renderbuffer); + + texture_dirty(att->Texture); + nouveau_surface_ref(NULL, &nrb->surface); +} + +void +nouveau_fbo_functions_init(struct dd_function_table *functions) +{ + functions->NewFramebuffer = nouveau_framebuffer_new; + functions->NewRenderbuffer = nouveau_renderbuffer_new; + functions->BindFramebuffer = nouveau_bind_framebuffer; + functions->FramebufferRenderbuffer = nouveau_framebuffer_renderbuffer; + functions->RenderTexture = nouveau_render_texture; + functions->FinishRenderTexture = nouveau_finish_render_texture; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.h b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h new file mode 100644 index 00000000000..5ae984bbff4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_FBO_H__ +#define __NOUVEAU_FBO_H__ + +struct nouveau_framebuffer { + struct gl_framebuffer base; + struct nouveau_bo *lma_bo; +}; +#define to_nouveau_framebuffer(x) ((struct nouveau_framebuffer *)(x)) + +struct nouveau_renderbuffer { + struct gl_renderbuffer base; + struct nouveau_surface surface; +}; +#define to_nouveau_renderbuffer(x) ((struct nouveau_renderbuffer *)(x)) + +struct gl_framebuffer * +nouveau_framebuffer_dri_new(const GLvisual *visual); + +struct gl_renderbuffer * +nouveau_renderbuffer_dri_new(GLenum format, __DRIdrawable *drawable); + +void +nouveau_fbo_functions_init(struct dd_function_table *functions); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h new file mode 100644 index 00000000000..00007a9a351 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_gldefs.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2007-2010 The Nouveau Project. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_GLDEFS_H__ +#define __NOUVEAU_GLDEFS_H__ + +static inline unsigned +nvgl_blend_func(unsigned func) +{ + switch (func) { + case GL_ZERO: + return 0x0000; + case GL_ONE: + return 0x0001; + case GL_SRC_COLOR: + return 0x0300; + case GL_ONE_MINUS_SRC_COLOR: + return 0x0301; + case GL_SRC_ALPHA: + return 0x0302; + case GL_ONE_MINUS_SRC_ALPHA: + return 0x0303; + case GL_DST_ALPHA: + return 0x0304; + case GL_ONE_MINUS_DST_ALPHA: + return 0x0305; + case GL_DST_COLOR: + return 0x0306; + case GL_ONE_MINUS_DST_COLOR: + return 0x0307; + case GL_SRC_ALPHA_SATURATE: + return 0x0308; + case GL_CONSTANT_COLOR: + return 0x8001; + case GL_ONE_MINUS_CONSTANT_COLOR: + return 0x8002; + case GL_CONSTANT_ALPHA: + return 0x8003; + case GL_ONE_MINUS_CONSTANT_ALPHA: + return 0x8004; + default: + assert(0); + } +} + +static inline unsigned +nvgl_blend_eqn(unsigned eqn) +{ + switch (eqn) { + case GL_FUNC_ADD: + return 0x8006; + case GL_MIN: + return 0x8007; + case GL_MAX: + return 0x8008; + case GL_FUNC_SUBTRACT: + return 0x800a; + case GL_FUNC_REVERSE_SUBTRACT: + return 0x800b; + default: + assert(0); + } +} + +static inline unsigned +nvgl_logicop_func(unsigned func) +{ + switch (func) { + case GL_CLEAR: + return 0x1500; + case GL_NOR: + return 0x1508; + case GL_AND_INVERTED: + return 0x1504; + case GL_COPY_INVERTED: + return 0x150c; + case GL_AND_REVERSE: + return 0x1502; + case GL_INVERT: + return 0x150a; + case GL_XOR: + return 0x1506; + case GL_NAND: + return 0x150e; + case GL_AND: + return 0x1501; + case GL_EQUIV: + return 0x1509; + case GL_NOOP: + return 0x1505; + case GL_OR_INVERTED: + return 0x150d; + case GL_COPY: + return 0x1503; + case GL_OR_REVERSE: + return 0x150b; + case GL_OR: + return 0x1507; + case GL_SET: + return 0x150f; + default: + assert(0); + } +} + +static inline unsigned +nvgl_comparison_op(unsigned op) +{ + switch (op) { + case GL_NEVER: + return 0x0200; + case GL_LESS: + return 0x0201; + case GL_EQUAL: + return 0x0202; + case GL_LEQUAL: + return 0x0203; + case GL_GREATER: + return 0x0204; + case GL_NOTEQUAL: + return 0x0205; + case GL_GEQUAL: + return 0x0206; + case GL_ALWAYS: + return 0x0207; + default: + assert(0); + } +} + +static inline unsigned +nvgl_polygon_mode(unsigned mode) +{ + switch (mode) { + case GL_POINT: + return 0x1b00; + case GL_LINE: + return 0x1b01; + case GL_FILL: + return 0x1b02; + default: + assert(0); + } +} + +static inline unsigned +nvgl_stencil_op(unsigned op) +{ + switch (op) { + case GL_ZERO: + return 0x0000; + case GL_INVERT: + return 0x150a; + case GL_KEEP: + return 0x1e00; + case GL_REPLACE: + return 0x1e01; + case GL_INCR: + return 0x1e02; + case GL_DECR: + return 0x1e03; + case GL_INCR_WRAP_EXT: + return 0x8507; + case GL_DECR_WRAP_EXT: + return 0x8508; + default: + assert(0); + } +} + +static inline unsigned +nvgl_primitive(unsigned prim) +{ + switch (prim) { + case GL_POINTS: + return 0x0001; + case GL_LINES: + return 0x0002; + case GL_LINE_LOOP: + return 0x0003; + case GL_LINE_STRIP: + return 0x0004; + case GL_TRIANGLES: + return 0x0005; + case GL_TRIANGLE_STRIP: + return 0x0006; + case GL_TRIANGLE_FAN: + return 0x0007; + case GL_QUADS: + return 0x0008; + case GL_QUAD_STRIP: + return 0x0009; + case GL_POLYGON: + return 0x000a; + default: + assert(0); + } +} + +static inline unsigned +nvgl_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case GL_REPEAT: + return 0x1; + case GL_MIRRORED_REPEAT: + return 0x2; + case GL_CLAMP_TO_EDGE: + return 0x3; + case GL_CLAMP_TO_BORDER: + return 0x4; + case GL_CLAMP: + return 0x5; + default: + assert(0); + } +} + +static inline unsigned +nvgl_filter_mode(unsigned filter) +{ + switch (filter) { + case GL_NEAREST: + return 0x1; + case GL_LINEAR: + return 0x2; + case GL_NEAREST_MIPMAP_NEAREST: + return 0x3; + case GL_LINEAR_MIPMAP_NEAREST: + return 0x4; + case GL_NEAREST_MIPMAP_LINEAR: + return 0x5; + case GL_LINEAR_MIPMAP_LINEAR: + return 0x6; + default: + assert(0); + } +} + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_render.h b/src/mesa/drivers/dri/nouveau/nouveau_render.h new file mode 100644 index 00000000000..bff0ccfd762 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_render.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_RENDER_H__ +#define __NOUVEAU_RENDER_H__ + +#include "vbo/vbo_context.h" + +struct nouveau_array_state; + +typedef void (*dispatch_t)(GLcontext *, unsigned int, int, unsigned int); +typedef unsigned (*extract_u_t)(struct nouveau_array_state *a, int i, int j); +typedef float (*extract_f_t)(struct nouveau_array_state *a, int i, int j); + +struct nouveau_attr_info { + int vbo_index; + int imm_method; + int imm_fields; + + void (*emit)(GLcontext *, struct nouveau_array_state *, const void *); +}; + +struct nouveau_array_state { + int attr; + int stride, fields, type; + + struct nouveau_bo *bo; + unsigned offset; + const void *buf; + + extract_u_t extract_u; + extract_f_t extract_f; +}; + +#define RENDER_SCRATCH_COUNT 32 +#define RENDER_SCRATCH_SIZE 64*1024 + +struct nouveau_scratch_state { + struct nouveau_bo *bo[RENDER_SCRATCH_COUNT]; + + int index; + int offset; + void *buf; +}; + +struct nouveau_swtnl_state { + struct nouveau_bo *vbo; + void *buf; + unsigned vertex_count; + GLenum primitive; +}; + +struct nouveau_render_state { + enum { + VBO, + IMM + } mode; + + struct nouveau_array_state ib; + struct nouveau_array_state attrs[VERT_ATTRIB_MAX]; + + /* Maps a HW VBO index or IMM emission order to an index in + * the attrs array above (or -1 if unused). */ + int map[VERT_ATTRIB_MAX]; + + int attr_count; + int vertex_size; + + struct nouveau_scratch_state scratch; + struct nouveau_swtnl_state swtnl; +}; + +#define to_render_state(ctx) (&to_nouveau_context(ctx)->render) + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_render_t.c b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c new file mode 100644 index 00000000000..c0505781cfe --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_render_t.c @@ -0,0 +1,361 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +/* + * Vertex submission helper definitions shared among the software and + * hardware TnL paths. + */ + +#include "nouveau_gldefs.h" + +#include "main/light.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" + +#define OUT_INDICES_L(r, i, d, n) \ + BATCH_OUT_L(i + d, n); \ + (void)r +#define OUT_INDICES_I16(r, i, d, n) \ + BATCH_OUT_I16(r->ib.extract_u(&r->ib, 0, i) + d, \ + r->ib.extract_u(&r->ib, 0, i + 1) + d) +#define OUT_INDICES_I32(r, i, d, n) \ + BATCH_OUT_I32(r->ib.extract_u(&r->ib, 0, i) + d) + +/* + * Emit <n> vertices using BATCH_OUT_<out>, MAX_OUT_<out> at a time, + * grouping them in packets of length MAX_PACKET. + * + * out: hardware index data type. + * ctx: GL context. + * start: element within the index buffer to begin with. + * delta: integer correction that will be added to each index found in + * the index buffer. + */ +#define EMIT_VBO(out, ctx, start, delta, n) do { \ + struct nouveau_render_state *render = to_render_state(ctx); \ + int npush = n; \ + \ + while (npush) { \ + int npack = MIN2(npush, MAX_PACKET * MAX_OUT_##out); \ + npush -= npack; \ + \ + BATCH_PACKET_##out((npack + MAX_OUT_##out - 1) \ + / MAX_OUT_##out); \ + while (npack) { \ + int nout = MIN2(npack, MAX_OUT_##out); \ + npack -= nout; \ + \ + OUT_INDICES_##out(render, start, delta, \ + nout); \ + start += nout; \ + } \ + } \ + } while (0) + +/* + * Emit the <n>-th element of the array <a>, using IMM_OUT. + */ +#define EMIT_IMM(ctx, a, n) do { \ + struct nouveau_attr_info *info = \ + &TAG(vertex_attrs)[(a)->attr]; \ + int m; \ + \ + if (!info->emit) { \ + IMM_PACKET(info->imm_method, info->imm_fields); \ + \ + for (m = 0; m < (a)->fields; m++) \ + IMM_OUT((a)->extract_f(a, n, m)); \ + \ + for (m = (a)->fields; m < info->imm_fields; m++) \ + IMM_OUT(((float []){0, 0, 0, 1})[m]); \ + \ + } else { \ + info->emit(ctx, a, (a)->buf + n * (a)->stride); \ + } \ + } while (0) + +/* + * Select an appropriate dispatch function for the given index buffer. + */ +static void +get_array_dispatch(struct nouveau_array_state *a, dispatch_t *dispatch) +{ + if (!a->fields) { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(L, ctx, start, delta, n); + }; + + *dispatch = f; + + } else if (a->type == GL_UNSIGNED_INT) { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(I32, ctx, start, delta, n); + }; + + *dispatch = f; + + } else { + auto void f(GLcontext *, unsigned int, int, unsigned int); + + void f(GLcontext *ctx, unsigned int start, int delta, + unsigned int n) { + struct nouveau_channel *chan = context_chan(ctx); + RENDER_LOCALS(ctx); + + EMIT_VBO(I32, ctx, start, delta, n & 1); + EMIT_VBO(I16, ctx, start, delta, n & ~1); + }; + + *dispatch = f; + } +} + +/* + * Select appropriate element extraction functions for the given + * array. + */ +static void +get_array_extract(struct nouveau_array_state *a, + extract_u_t *extract_u, extract_f_t *extract_f) +{ +#define EXTRACT(in_t, out_t, k) \ + ({ \ + auto out_t f(struct nouveau_array_state *, int, int); \ + out_t f(struct nouveau_array_state *a, int i, int j) { \ + in_t x = ((in_t *)(a->buf + i * a->stride))[j]; \ + \ + return (out_t)x / (k); \ + }; \ + f; \ + }); + + switch (a->type) { + case GL_BYTE: + *extract_u = EXTRACT(char, unsigned, 1); + *extract_f = EXTRACT(char, float, SCHAR_MAX); + break; + case GL_UNSIGNED_BYTE: + *extract_u = EXTRACT(unsigned char, unsigned, 1); + *extract_f = EXTRACT(unsigned char, float, UCHAR_MAX); + break; + case GL_SHORT: + *extract_u = EXTRACT(short, unsigned, 1); + *extract_f = EXTRACT(short, float, SHRT_MAX); + break; + case GL_UNSIGNED_SHORT: + *extract_u = EXTRACT(unsigned short, unsigned, 1); + *extract_f = EXTRACT(unsigned short, float, USHRT_MAX); + break; + case GL_INT: + *extract_u = EXTRACT(int, unsigned, 1); + *extract_f = EXTRACT(int, float, INT_MAX); + break; + case GL_UNSIGNED_INT: + *extract_u = EXTRACT(unsigned int, unsigned, 1); + *extract_f = EXTRACT(unsigned int, float, UINT_MAX); + break; + case GL_FLOAT: + *extract_u = EXTRACT(float, unsigned, 1.0 / UINT_MAX); + *extract_f = EXTRACT(float, float, 1); + break; + + default: + assert(0); + } +} + +/* + * Returns a pointer to a chunk of <size> bytes long GART memory. <bo> + * will be updated with the buffer object the memory is located in. + * + * If <offset> is provided, it will be updated with the offset within + * <bo> of the allocated memory. Otherwise the returned memory will + * always be located right at the beginning of <bo>. + */ +static inline void * +get_scratch_vbo(GLcontext *ctx, unsigned size, struct nouveau_bo **bo, + unsigned *offset) +{ + struct nouveau_scratch_state *scratch = &to_render_state(ctx)->scratch; + void *buf; + + if (scratch->buf && offset && + size <= RENDER_SCRATCH_SIZE - scratch->offset) { + nouveau_bo_ref(scratch->bo[scratch->index], bo); + + buf = scratch->buf + scratch->offset; + *offset = scratch->offset; + scratch->offset += size; + + } else if (size <= RENDER_SCRATCH_SIZE) { + scratch->index = (scratch->index + 1) % RENDER_SCRATCH_COUNT; + nouveau_bo_ref(scratch->bo[scratch->index], bo); + + nouveau_bo_map(*bo, NOUVEAU_BO_WR); + buf = scratch->buf = (*bo)->map; + nouveau_bo_unmap(*bo); + + if (offset) + *offset = 0; + scratch->offset = size; + + } else { + nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_MAP | NOUVEAU_BO_GART, 0, size, bo); + + nouveau_bo_map(*bo, NOUVEAU_BO_WR); + buf = (*bo)->map; + nouveau_bo_unmap(*bo); + + if (offset) + *offset = 0; + } + + return buf; +} + +/* + * Returns how many vertices you can draw using <n> pushbuf dwords. + */ +static inline unsigned +get_max_vertices(GLcontext *ctx, const struct _mesa_index_buffer *ib, + unsigned n) +{ + struct nouveau_render_state *render = to_render_state(ctx); + + if (render->mode == IMM) { + return MAX2(0, n - 4) / (render->vertex_size / 4 + + render->attr_count); + } else { + unsigned max_out; + + if (ib) { + switch (ib->type) { + case GL_UNSIGNED_INT: + max_out = MAX_OUT_I32; + break; + + case GL_UNSIGNED_SHORT: + max_out = MAX_OUT_I16; + break; + + case GL_UNSIGNED_BYTE: + max_out = MAX_OUT_I16; + break; + } + } else { + max_out = MAX_OUT_L; + } + + return MAX2(0, n - 7) * max_out * MAX_PACKET / (1 + MAX_PACKET); + } +} + +#include "nouveau_vbo_t.c" +#include "nouveau_swtnl_t.c" + +static void +TAG(emit_material)(GLcontext *ctx, struct nouveau_array_state *a, + const void *v) +{ + const int attr = a->attr - VERT_ATTRIB_GENERIC0; + const int state = ((int []) { + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE, + NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE, + NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR, + NOUVEAU_STATE_MATERIAL_BACK_SPECULAR, + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_SHININESS, + NOUVEAU_STATE_MATERIAL_BACK_SHININESS + }) [attr]; + + COPY_4V(ctx->Light.Material.Attrib[attr], (float *)v); + _mesa_update_material(ctx, 1 << attr); + + context_drv(ctx)->emit[state](ctx, state); +} + +static void +TAG(render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + nouveau_validate_framebuffer(ctx); + + if (nctx->fallback == HWTNL) + TAG(vbo_render_prims)(ctx, arrays, prims, nr_prims, ib, + index_bounds_valid, min_index, max_index); + + if (nctx->fallback == SWTNL) + _tnl_vbo_draw_prims(ctx, arrays, prims, nr_prims, ib, + index_bounds_valid, min_index, max_index); +} + +void +TAG(render_init)(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_scratch_state *scratch = &render->scratch; + int ret, i; + + for (i = 0; i < RENDER_SCRATCH_COUNT; i++) { + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_MAP | NOUVEAU_BO_GART, + 0, RENDER_SCRATCH_SIZE, &scratch->bo[i]); + assert(!ret); + } + + for (i = 0; i < VERT_ATTRIB_MAX; i++) + render->map[i] = -1; + + TAG(swtnl_init)(ctx); + vbo_set_draw_func(ctx, TAG(render_prims)); +} + +void +TAG(render_destroy)(GLcontext *ctx) +{ + TAG(swtnl_destroy)(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c new file mode 100644 index 00000000000..de6328251ea --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_drmif.h" +#include "nv04_driver.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +#include "main/framebuffer.h" +#include "main/renderbuffer.h" + +static const __DRIextension *nouveau_screen_extensions[]; + +static void +nouveau_destroy_screen(__DRIscreen *dri_screen); + +static void +nouveau_channel_flush_notify(struct nouveau_channel *chan) +{ + struct nouveau_screen *screen = chan->user_private; + struct nouveau_context *nctx = screen->context; + + if (nctx && nctx->fallback < SWRAST) + nouveau_state_emit(&nctx->base); +} + +static const __DRIconfig ** +nouveau_get_configs(void) +{ + __DRIconfig **configs = NULL; + int i; + + const uint8_t depth_bits[] = { 0, 16, 24, 24 }; + const uint8_t stencil_bits[] = { 0, 0, 0, 8 }; + const uint8_t msaa_samples[] = { 0 }; + + const struct { + GLenum format; + GLenum type; + } fb_formats[] = { + { GL_RGB , GL_UNSIGNED_SHORT_5_6_5 }, + { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV }, + { GL_BGR , GL_UNSIGNED_INT_8_8_8_8_REV }, + }; + + const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML + }; + + for (i = 0; i < Elements(fb_formats); i++) { + __DRIconfig **config; + + config = driCreateConfigs(fb_formats[i].format, + fb_formats[i].type, + depth_bits, stencil_bits, + Elements(depth_bits), + back_buffer_modes, + Elements(back_buffer_modes), + msaa_samples, + Elements(msaa_samples)); + assert(config); + + configs = configs ? driConcatConfigs(configs, config) + : config; + } + + return (const __DRIconfig **)configs; +} + +static const __DRIconfig ** +nouveau_init_screen2(__DRIscreen *dri_screen) +{ + const __DRIconfig **configs; + struct nouveau_screen *screen; + int ret; + + /* Allocate the screen. */ + screen = CALLOC_STRUCT(nouveau_screen); + if (!screen) + return NULL; + + dri_screen->private = screen; + dri_screen->extensions = nouveau_screen_extensions; + screen->dri_screen = dri_screen; + + /* Open the DRM device. */ + ret = nouveau_device_open_existing(&screen->device, 0, dri_screen->fd, + 0); + if (ret) { + nouveau_error("Error opening the DRM device.\n"); + goto fail; + } + + ret = nouveau_channel_alloc(screen->device, 0xbeef0201, 0xbeef0202, + &screen->chan); + if (ret) { + nouveau_error("Error initializing the FIFO.\n"); + goto fail; + } + screen->chan->flush_notify = nouveau_channel_flush_notify; + screen->chan->user_private = screen; + + /* Do the card specific initialization */ + switch (screen->device->chipset & 0xf0) { + case 0x00: + ret = nv04_screen_init(screen); + break; + case 0x10: + ret = nv10_screen_init(screen); + break; + case 0x20: + ret = nv20_screen_init(screen); + break; + default: + assert(0); + } + if (!ret) { + nouveau_error("Error initializing the hardware.\n"); + goto fail; + } + + configs = nouveau_get_configs(); + if (!configs) { + nouveau_error("Error creating the framebuffer configs.\n"); + goto fail; + } + + return configs; +fail: + nouveau_destroy_screen(dri_screen); + return NULL; + +} + +static void +nouveau_destroy_screen(__DRIscreen *dri_screen) +{ + struct nouveau_screen *screen = dri_screen->private; + + if (!screen) + return; + + screen->driver->screen_destroy(screen); + + if (screen->chan) { + screen->chan->flush_notify = NULL; + nouveau_channel_free(&screen->chan); + } + + if (screen->device) + nouveau_device_close(&screen->device); + + FREE(screen); + dri_screen->private = NULL; +} + +static GLboolean +nouveau_create_buffer(__DRIscreen *dri_screen, + __DRIdrawable *drawable, + const __GLcontextModes *visual, + GLboolean is_pixmap) +{ + struct gl_renderbuffer *rb; + struct gl_framebuffer *fb; + GLenum color_format; + + if (is_pixmap) + return GL_FALSE; /* not implemented */ + + if (visual->redBits == 5) + color_format = GL_RGB5; + else if (visual->alphaBits == 0) + color_format = GL_RGB8; + else + color_format = GL_RGBA8; + + fb = nouveau_framebuffer_dri_new(visual); + if (!fb) + return GL_FALSE; + + /* Front buffer. */ + rb = nouveau_renderbuffer_dri_new(color_format, drawable); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, rb); + + /* Back buffer */ + if (visual->doubleBufferMode) { + rb = nouveau_renderbuffer_dri_new(color_format, drawable); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, rb); + } + + /* Depth/stencil buffer. */ + if (visual->depthBits == 24 && visual->stencilBits == 8) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH24_STENCIL8_EXT, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb); + + } else if (visual->depthBits == 24) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT24, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + + } else if (visual->depthBits == 16) { + rb = nouveau_renderbuffer_dri_new(GL_DEPTH_COMPONENT16, drawable); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb); + } + + /* Software renderbuffers. */ + _mesa_add_soft_renderbuffers(fb, GL_FALSE, GL_FALSE, GL_FALSE, + visual->accumRedBits > 0, + GL_FALSE, GL_FALSE); + + drawable->driverPrivate = fb; + + return GL_TRUE; +} + +static void +nouveau_destroy_buffer(__DRIdrawable *drawable) +{ + _mesa_reference_framebuffer( + (struct gl_framebuffer **)&drawable->driverPrivate, NULL); +} + +static const __DRIextension *nouveau_screen_extensions[] = { + NULL +}; + +const struct __DriverAPIRec driDriverAPI = { + .InitScreen2 = nouveau_init_screen2, + .DestroyScreen = nouveau_destroy_screen, + .CreateBuffer = nouveau_create_buffer, + .DestroyBuffer = nouveau_destroy_buffer, + .CreateContext = nouveau_context_create, + .DestroyContext = nouveau_context_destroy, + .MakeCurrent = nouveau_context_make_current, + .UnbindContext = nouveau_context_unbind, +}; + +/* This is the table of extensions that the loader will dlsym() for. */ +PUBLIC const __DRIextension *__driDriverExtensions[] = { + &driCoreExtension.base, + &driDRI2Extension.base, + NULL +}; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.h b/src/mesa/drivers/dri/nouveau/nouveau_screen.h new file mode 100644 index 00000000000..5d45039b9ed --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_SCREEN_H__ +#define __NOUVEAU_SCREEN_H__ + +struct nouveau_context; + +struct nouveau_screen { + __DRIscreen *dri_screen; + + struct nouveau_device *device; + struct nouveau_channel *chan; + + struct nouveau_notifier *ntfy; + struct nouveau_grobj *eng3d; + struct nouveau_grobj *eng3dm; + struct nouveau_grobj *surf3d; + struct nouveau_grobj *m2mf; + struct nouveau_grobj *surf2d; + struct nouveau_grobj *rop; + struct nouveau_grobj *patt; + struct nouveau_grobj *rect; + struct nouveau_grobj *swzsurf; + struct nouveau_grobj *sifm; + + const struct nouveau_driver *driver; + struct nouveau_context *context; +}; + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_span.c b/src/mesa/drivers/dri/nouveau/nouveau_span.c new file mode 100644 index 00000000000..dbbbf15b096 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_span.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_fbo.h" +#include "nouveau_context.h" +#include "nouveau_bo.h" + +#include "swrast/swrast.h" + +#define LOCAL_VARS \ + struct gl_framebuffer *fb = ctx->DrawBuffer; \ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; \ + GLuint p; \ + (void)p; + +#define LOCAL_DEPTH_VARS LOCAL_VARS + +#define HW_LOCK() +#define HW_UNLOCK() + +#define HW_CLIPLOOP() { \ + int minx = 0; \ + int miny = 0; \ + int maxx = fb->Width; \ + int maxy = fb->Height; + +#define HW_ENDCLIPLOOP() } + +#define Y_FLIP(y) (fb->Name ? (y) : rb->Height - 1 - (y)) + +/* RGB565 span functions */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 +#define TAG(x) nouveau_##x##_rgb565 +#define TAG2(x, y) nouveau_##x##_rgb565##y +#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp) + +#include "spantmp2.h" + +/* ARGB8888 span functions */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV +#define TAG(x) nouveau_##x##_argb8888 +#define TAG2(x, y) nouveau_##x##_argb8888##y +#define GET_PTR(x, y) (s->bo->map + (y)*s->pitch + (x)*s->cpp) + +#include "spantmp2.h" + +/* Z16 span functions */ +#define VALUE_TYPE uint16_t +#define READ_DEPTH(v, x, y) \ + v = *(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp); +#define WRITE_DEPTH(x, y, v) \ + *(uint16_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v +#define TAG(x) nouveau_##x##_z16 + +#include "depthtmp.h" + +/* Z24S8 span functions */ +#define VALUE_TYPE uint32_t +#define READ_DEPTH(v, x, y) \ + v = *(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp); +#define WRITE_DEPTH(x, y, v) \ + *(uint32_t *)(s->bo->map + (y)*s->pitch + (x)*s->cpp) = v +#define TAG(x) nouveau_##x##_z24s8 + +#include "depthtmp.h" + +static void +renderbuffer_map_unmap(struct gl_renderbuffer *rb, GLboolean map) +{ + struct nouveau_surface *s = &to_nouveau_renderbuffer(rb)->surface; + + if (map) { + switch (rb->Format) { + case MESA_FORMAT_RGB565: + nouveau_InitPointers_rgb565(rb); + break; + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + nouveau_InitPointers_argb8888(rb); + break; + case MESA_FORMAT_Z16: + nouveau_InitDepthPointers_z16(rb); + break; + case MESA_FORMAT_Z24_S8: + nouveau_InitDepthPointers_z24s8(rb); + break; + default: + assert(0); + } + + nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR); + } else { + nouveau_bo_unmap(s->bo); + } +} + +static void +texture_unit_map_unmap(GLcontext *ctx, struct gl_texture_unit *u, GLboolean map) +{ + if (!u->_ReallyEnabled) + return; + + if (map) + ctx->Driver.MapTexture(ctx, u->_Current); + else + ctx->Driver.UnmapTexture(ctx, u->_Current); +} + +static void +span_map_unmap(GLcontext *ctx, GLboolean map) +{ + int i; + + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) + renderbuffer_map_unmap(ctx->DrawBuffer->_ColorDrawBuffers[i], map); + + renderbuffer_map_unmap(ctx->DrawBuffer->_ColorReadBuffer, map); + + if (ctx->DrawBuffer->_DepthBuffer) + renderbuffer_map_unmap(ctx->DrawBuffer->_DepthBuffer->Wrapped, map); + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + texture_unit_map_unmap(ctx, &ctx->Texture.Unit[i], map); +} + +static void +nouveau_span_start(GLcontext *ctx) +{ + nouveau_fallback(ctx, SWRAST); + span_map_unmap(ctx, GL_TRUE); +} + +static void +nouveau_span_finish(GLcontext *ctx) +{ + span_map_unmap(ctx, GL_FALSE); + nouveau_fallback(ctx, HWTNL); +} + +void +nouveau_span_functions_init(GLcontext *ctx) +{ + struct swrast_device_driver *swdd = + _swrast_GetDeviceDriverReference(ctx); + + swdd->SpanRenderStart = nouveau_span_start; + swdd->SpanRenderFinish = nouveau_span_finish; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c new file mode 100644 index 00000000000..d7278221754 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -0,0 +1,532 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" + +#include "swrast/swrast.h" +#include "tnl/tnl.h" + +static void +nouveau_alpha_func(GLcontext *ctx, GLenum func, GLfloat ref) +{ + context_dirty(ctx, ALPHA_FUNC); +} + +static void +nouveau_blend_color(GLcontext *ctx, const GLfloat color[4]) +{ + context_dirty(ctx, BLEND_COLOR); +} + +static void +nouveau_blend_equation_separate(GLcontext *ctx, GLenum modeRGB, GLenum modeA) +{ + context_dirty(ctx, BLEND_EQUATION); +} + +static void +nouveau_blend_func_separate(GLcontext *ctx, GLenum sfactorRGB, + GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) +{ + context_dirty(ctx, BLEND_FUNC); +} + +static void +nouveau_clip_plane(GLcontext *ctx, GLenum plane, const GLfloat *equation) +{ + context_dirty_i(ctx, CLIP_PLANE, plane - GL_CLIP_PLANE0); +} + +static void +nouveau_color_mask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask) +{ + context_dirty(ctx, COLOR_MASK); +} + +static void +nouveau_color_material(GLcontext *ctx, GLenum face, GLenum mode) +{ + context_dirty(ctx, COLOR_MATERIAL); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); +} + +static void +nouveau_cull_face(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, CULL_FACE); +} + +static void +nouveau_front_face(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, FRONT_FACE); +} + +static void +nouveau_depth_func(GLcontext *ctx, GLenum func) +{ + context_dirty(ctx, DEPTH); +} + +static void +nouveau_depth_mask(GLcontext *ctx, GLboolean flag) +{ + context_dirty(ctx, DEPTH); +} + +static void +nouveau_depth_range(GLcontext *ctx, GLclampd nearval, GLclampd farval) +{ + context_dirty(ctx, VIEWPORT); +} + +static void +nouveau_draw_buffer(GLcontext *ctx, GLenum buffer) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_draw_buffers(GLcontext *ctx, GLsizei n, const GLenum *buffers) +{ + context_dirty(ctx, FRAMEBUFFER); +} + +static void +nouveau_enable(GLcontext *ctx, GLenum cap, GLboolean state) +{ + int i; + + switch (cap) { + case GL_ALPHA_TEST: + context_dirty(ctx, ALPHA_FUNC); + break; + case GL_BLEND: + context_dirty(ctx, BLEND_EQUATION); + break; + case GL_COLOR_LOGIC_OP: + context_dirty(ctx, LOGIC_OPCODE); + break; + case GL_COLOR_MATERIAL: + context_dirty(ctx, COLOR_MATERIAL); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + break; + case GL_COLOR_SUM_EXT: + context_dirty(ctx, FRAG); + break; + case GL_CULL_FACE: + context_dirty(ctx, CULL_FACE); + break; + case GL_DEPTH_TEST: + context_dirty(ctx, DEPTH); + break; + case GL_DITHER: + context_dirty(ctx, DITHER); + break; + case GL_FOG: + context_dirty(ctx, FOG); + context_dirty(ctx, FRAG); + context_dirty(ctx, MODELVIEW); + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + context_dirty_i(ctx, LIGHT_SOURCE, cap - GL_LIGHT0); + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + break; + case GL_LIGHTING: + context_dirty(ctx, FRAG); + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + + for (i = 0; i < MAX_LIGHTS; i++) { + if (ctx->Light.Light[i].Enabled) + context_dirty_i(ctx, LIGHT_SOURCE, i); + } + + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + break; + case GL_LINE_SMOOTH: + context_dirty(ctx, LINE_MODE); + break; + case GL_NORMALIZE: + context_dirty(ctx, LIGHT_ENABLE); + break; + case GL_POINT_SMOOTH: + context_dirty(ctx, POINT_MODE); + break; + case GL_POLYGON_OFFSET_POINT: + case GL_POLYGON_OFFSET_LINE: + case GL_POLYGON_OFFSET_FILL: + context_dirty(ctx, POLYGON_OFFSET); + break; + case GL_POLYGON_SMOOTH: + context_dirty(ctx, POLYGON_MODE); + break; + case GL_SCISSOR_TEST: + context_dirty(ctx, SCISSOR); + break; + case GL_STENCIL_TEST: + context_dirty(ctx, STENCIL_FUNC); + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_fog(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, FOG); +} + +static void +nouveau_index_mask(GLcontext *ctx, GLuint mask) +{ + context_dirty(ctx, INDEX_MASK); +} + +static void +nouveau_light(GLcontext *ctx, GLenum light, GLenum pname, const GLfloat *params) +{ + switch (pname) { + case GL_AMBIENT: + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + break; + case GL_DIFFUSE: + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + break; + case GL_SPECULAR: + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + break; + case GL_SPOT_CUTOFF: + case GL_POSITION: + context_dirty(ctx, MODELVIEW); + context_dirty(ctx, LIGHT_ENABLE); + context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0); + break; + default: + context_dirty_i(ctx, LIGHT_SOURCE, light - GL_LIGHT0); + break; + } +} + +static void +nouveau_light_model(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, LIGHT_MODEL); + context_dirty(ctx, MODELVIEW); +} + +static void +nouveau_line_stipple(GLcontext *ctx, GLint factor, GLushort pattern ) +{ + context_dirty(ctx, LINE_STIPPLE); +} + +static void +nouveau_line_width(GLcontext *ctx, GLfloat width) +{ + context_dirty(ctx, LINE_MODE); +} + +static void +nouveau_logic_opcode(GLcontext *ctx, GLenum opcode) +{ + context_dirty(ctx, LOGIC_OPCODE); +} + +static void +nouveau_point_parameter(GLcontext *ctx, GLenum pname, const GLfloat *params) +{ + context_dirty(ctx, POINT_PARAMETER); +} + +static void +nouveau_point_size(GLcontext *ctx, GLfloat size) +{ + context_dirty(ctx, POINT_MODE); +} + +static void +nouveau_polygon_mode(GLcontext *ctx, GLenum face, GLenum mode) +{ + context_dirty(ctx, POLYGON_MODE); +} + +static void +nouveau_polygon_offset(GLcontext *ctx, GLfloat factor, GLfloat units) +{ + context_dirty(ctx, POLYGON_OFFSET); +} + +static void +nouveau_polygon_stipple(GLcontext *ctx, const GLubyte *mask) +{ + context_dirty(ctx, POLYGON_STIPPLE); +} + +static void +nouveau_render_mode(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, RENDER_MODE); +} + +static void +nouveau_scissor(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + context_dirty(ctx, SCISSOR); +} + +static void +nouveau_shade_model(GLcontext *ctx, GLenum mode) +{ + context_dirty(ctx, SHADE_MODEL); +} + +static void +nouveau_stencil_func_separate(GLcontext *ctx, GLenum face, GLenum func, + GLint ref, GLuint mask) +{ + context_dirty(ctx, STENCIL_FUNC); +} + +static void +nouveau_stencil_mask_separate(GLcontext *ctx, GLenum face, GLuint mask) +{ + context_dirty(ctx, STENCIL_MASK); +} + +static void +nouveau_stencil_op_separate(GLcontext *ctx, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) +{ + context_dirty(ctx, STENCIL_OP); +} + +static void +nouveau_tex_gen(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params) +{ + context_dirty_i(ctx, TEX_GEN, ctx->Texture.CurrentUnit); +} + +static void +nouveau_tex_env(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param) +{ + switch (target) { + case GL_TEXTURE_FILTER_CONTROL_EXT: + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + default: + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_tex_parameter(GLcontext *ctx, GLenum target, + struct gl_texture_object *t, GLenum pname, + const GLfloat *params) +{ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + case GL_TEXTURE_WRAP_R: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + case GL_TEXTURE_LOD_BIAS: + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + texture_dirty(t); + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + break; + } +} + +static void +nouveau_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + context_dirty(ctx, VIEWPORT); +} + +void +nouveau_emit_nothing(GLcontext *ctx, int emit) +{ +} + +int +nouveau_next_dirty_state(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + int i = BITSET_FFS(nctx->dirty) - 1; + + if (i < 0 || i >= context_drv(ctx)->num_emit) + return -1; + + return i; +} + +void +nouveau_state_emit(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + const struct nouveau_driver *drv = context_drv(ctx); + int i; + + while ((i = nouveau_next_dirty_state(ctx)) >= 0) { + BITSET_CLEAR(nctx->dirty, i); + drv->emit[i](ctx, i); + } + + BITSET_ZERO(nctx->dirty); + + nouveau_bo_state_emit(ctx); +} + +static void +nouveau_update_state(GLcontext *ctx, GLbitfield new_state) +{ + if (new_state & (_NEW_PROJECTION | _NEW_MODELVIEW)) + context_dirty(ctx, PROJECTION); + + if (new_state & _NEW_MODELVIEW) + context_dirty(ctx, MODELVIEW); + + if (new_state & _NEW_CURRENT_ATTRIB && + new_state & _NEW_LIGHT) { + context_dirty(ctx, MATERIAL_FRONT_AMBIENT); + context_dirty(ctx, MATERIAL_BACK_AMBIENT); + context_dirty(ctx, MATERIAL_FRONT_DIFFUSE); + context_dirty(ctx, MATERIAL_BACK_DIFFUSE); + context_dirty(ctx, MATERIAL_FRONT_SPECULAR); + context_dirty(ctx, MATERIAL_BACK_SPECULAR); + context_dirty(ctx, MATERIAL_FRONT_SHININESS); + context_dirty(ctx, MATERIAL_BACK_SHININESS); + } + + _swrast_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + + nouveau_state_emit(ctx); +} + +void +nouveau_state_init(GLcontext *ctx) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + + ctx->Driver.AlphaFunc = nouveau_alpha_func; + ctx->Driver.BlendColor = nouveau_blend_color; + ctx->Driver.BlendEquationSeparate = nouveau_blend_equation_separate; + ctx->Driver.BlendFuncSeparate = nouveau_blend_func_separate; + ctx->Driver.ClipPlane = nouveau_clip_plane; + ctx->Driver.ColorMask = nouveau_color_mask; + ctx->Driver.ColorMaterial = nouveau_color_material; + ctx->Driver.CullFace = nouveau_cull_face; + ctx->Driver.FrontFace = nouveau_front_face; + ctx->Driver.DepthFunc = nouveau_depth_func; + ctx->Driver.DepthMask = nouveau_depth_mask; + ctx->Driver.DepthRange = nouveau_depth_range; + ctx->Driver.DrawBuffer = nouveau_draw_buffer; + ctx->Driver.DrawBuffers = nouveau_draw_buffers; + ctx->Driver.Enable = nouveau_enable; + ctx->Driver.Fogfv = nouveau_fog; + ctx->Driver.IndexMask = nouveau_index_mask; + ctx->Driver.Lightfv = nouveau_light; + ctx->Driver.LightModelfv = nouveau_light_model; + ctx->Driver.LineStipple = nouveau_line_stipple; + ctx->Driver.LineWidth = nouveau_line_width; + ctx->Driver.LogicOpcode = nouveau_logic_opcode; + ctx->Driver.PointParameterfv = nouveau_point_parameter; + ctx->Driver.PointSize = nouveau_point_size; + ctx->Driver.PolygonMode = nouveau_polygon_mode; + ctx->Driver.PolygonOffset = nouveau_polygon_offset; + ctx->Driver.PolygonStipple = nouveau_polygon_stipple; + ctx->Driver.RenderMode = nouveau_render_mode; + ctx->Driver.Scissor = nouveau_scissor; + ctx->Driver.ShadeModel = nouveau_shade_model; + ctx->Driver.StencilFuncSeparate = nouveau_stencil_func_separate; + ctx->Driver.StencilMaskSeparate = nouveau_stencil_mask_separate; + ctx->Driver.StencilOpSeparate = nouveau_stencil_op_separate; + ctx->Driver.TexGen = nouveau_tex_gen; + ctx->Driver.TexEnv = nouveau_tex_env; + ctx->Driver.TexParameter = nouveau_tex_parameter; + ctx->Driver.Viewport = nouveau_viewport; + + ctx->Driver.UpdateState = nouveau_update_state; + + BITSET_ONES(nctx->dirty); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.h b/src/mesa/drivers/dri/nouveau/nouveau_state.h new file mode 100644 index 00000000000..d001fa259aa --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_STATE_H__ +#define __NOUVEAU_STATE_H__ + +enum { + NOUVEAU_STATE_ALPHA_FUNC, + NOUVEAU_STATE_BLEND_COLOR, + NOUVEAU_STATE_BLEND_EQUATION, + NOUVEAU_STATE_BLEND_FUNC, + NOUVEAU_STATE_CLIP_PLANE0, + NOUVEAU_STATE_CLIP_PLANE1, + NOUVEAU_STATE_CLIP_PLANE2, + NOUVEAU_STATE_CLIP_PLANE3, + NOUVEAU_STATE_CLIP_PLANE4, + NOUVEAU_STATE_CLIP_PLANE5, + NOUVEAU_STATE_COLOR_MASK, + NOUVEAU_STATE_COLOR_MATERIAL, + NOUVEAU_STATE_CULL_FACE, + NOUVEAU_STATE_FRONT_FACE, + NOUVEAU_STATE_DEPTH, + NOUVEAU_STATE_DITHER, + NOUVEAU_STATE_FRAG, + NOUVEAU_STATE_FRAMEBUFFER, + NOUVEAU_STATE_FOG, + NOUVEAU_STATE_INDEX_MASK, + NOUVEAU_STATE_LIGHT_ENABLE, + NOUVEAU_STATE_LIGHT_MODEL, + NOUVEAU_STATE_LIGHT_SOURCE0, + NOUVEAU_STATE_LIGHT_SOURCE1, + NOUVEAU_STATE_LIGHT_SOURCE2, + NOUVEAU_STATE_LIGHT_SOURCE3, + NOUVEAU_STATE_LIGHT_SOURCE4, + NOUVEAU_STATE_LIGHT_SOURCE5, + NOUVEAU_STATE_LIGHT_SOURCE6, + NOUVEAU_STATE_LIGHT_SOURCE7, + NOUVEAU_STATE_LINE_STIPPLE, + NOUVEAU_STATE_LINE_MODE, + NOUVEAU_STATE_LOGIC_OPCODE, + NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT, + NOUVEAU_STATE_MATERIAL_BACK_AMBIENT, + NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE, + NOUVEAU_STATE_MATERIAL_BACK_DIFFUSE, + NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR, + NOUVEAU_STATE_MATERIAL_BACK_SPECULAR, + NOUVEAU_STATE_MATERIAL_FRONT_SHININESS, + NOUVEAU_STATE_MATERIAL_BACK_SHININESS, + NOUVEAU_STATE_MODELVIEW, + NOUVEAU_STATE_POINT_MODE, + NOUVEAU_STATE_POINT_PARAMETER, + NOUVEAU_STATE_POLYGON_MODE, + NOUVEAU_STATE_POLYGON_OFFSET, + NOUVEAU_STATE_POLYGON_STIPPLE, + NOUVEAU_STATE_PROJECTION, + NOUVEAU_STATE_RENDER_MODE, + NOUVEAU_STATE_SCISSOR, + NOUVEAU_STATE_SHADE_MODEL, + NOUVEAU_STATE_STENCIL_FUNC, + NOUVEAU_STATE_STENCIL_MASK, + NOUVEAU_STATE_STENCIL_OP, + NOUVEAU_STATE_TEX_ENV0, + NOUVEAU_STATE_TEX_ENV1, + NOUVEAU_STATE_TEX_ENV2, + NOUVEAU_STATE_TEX_ENV3, + NOUVEAU_STATE_TEX_GEN0, + NOUVEAU_STATE_TEX_GEN1, + NOUVEAU_STATE_TEX_GEN2, + NOUVEAU_STATE_TEX_GEN3, + NOUVEAU_STATE_TEX_OBJ0, + NOUVEAU_STATE_TEX_OBJ1, + NOUVEAU_STATE_TEX_OBJ2, + NOUVEAU_STATE_TEX_OBJ3, + NOUVEAU_STATE_VIEWPORT, + NUM_NOUVEAU_STATE, + + /* Room for card-specific states. */ + + MAX_NOUVEAU_STATE = NUM_NOUVEAU_STATE + 16, +}; + +typedef void (*nouveau_state_func)(GLcontext *ctx, int emit); + +void +nouveau_state_init(GLcontext *ctx); + +void +nouveau_emit_nothing(GLcontext *ctx, int emit); + +int +nouveau_next_dirty_state(GLcontext *ctx); + +void +nouveau_state_emit(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_surface.c b/src/mesa/drivers/dri/nouveau/nouveau_surface.c new file mode 100644 index 00000000000..33393970a07 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_surface.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" + +void +nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s, + enum nouveau_surface_layout layout, + unsigned flags, unsigned format, + unsigned width, unsigned height) +{ + unsigned tile_mode, cpp = _mesa_get_format_bytes(format); + int ret; + + nouveau_bo_ref(NULL, &s->bo); + + *s = (struct nouveau_surface) { + .layout = layout, + .format = format, + .width = width, + .height = height, + .cpp = cpp, + .pitch = width * cpp, + }; + + if (layout == TILED) { + s->pitch = align(s->pitch, 256); + tile_mode = s->pitch; + } else { + s->pitch = align(s->pitch, 64); + tile_mode = 0; + } + + ret = nouveau_bo_new_tile(context_dev(ctx), flags, 0, s->pitch * height, + tile_mode, 0, &s->bo); + assert(!ret); +} + +void +nouveau_surface_ref(struct nouveau_surface *src, + struct nouveau_surface *dst) +{ + if (src) { + dst->offset = src->offset; + dst->layout = src->layout; + dst->format = src->format; + dst->width = src->width; + dst->height = src->height; + dst->cpp = src->cpp; + dst->pitch = src->pitch; + nouveau_bo_ref(src->bo, &dst->bo); + + } else { + nouveau_bo_ref(NULL, &dst->bo); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_surface.h b/src/mesa/drivers/dri/nouveau/nouveau_surface.h new file mode 100644 index 00000000000..ebdc89afb4e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_surface.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_SURFACE_H__ +#define __NOUVEAU_SURFACE_H__ + +enum nouveau_surface_layout { + LINEAR = 0, + TILED, + SWIZZLED, +}; + +struct nouveau_surface { + struct nouveau_bo *bo; + unsigned offset; + + enum nouveau_surface_layout layout; + + gl_format format; + unsigned cpp, pitch; + + unsigned width, height; +}; + +void +nouveau_surface_alloc(GLcontext *ctx, struct nouveau_surface *s, + enum nouveau_surface_layout layout, + unsigned flags, unsigned format, + unsigned width, unsigned height); + +void +nouveau_surface_ref(struct nouveau_surface *src, + struct nouveau_surface *dst); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c new file mode 100644 index 00000000000..8fa922f422e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +static enum tnl_attr_format +swtnl_get_format(int type, int fields) { + switch (type) { + case GL_FLOAT: + switch (fields){ + case 1: + return EMIT_1F; + case 2: + return EMIT_2F; + case 3: + return EMIT_3F; + case 4: + return EMIT_4F; + default: + assert(0); + } + case GL_UNSIGNED_BYTE: + switch (fields) { + case 4: + return EMIT_4UB_4F_RGBA; + default: + assert(0); + } + default: + assert(0); + } +} + +static struct swtnl_attr_info { + int type; + int fields; +} swtnl_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .type = GL_FLOAT, + .fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_COLOR0] = { + .type = GL_UNSIGNED_BYTE, + .fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .type = GL_UNSIGNED_BYTE, + .fields = 4, + }, + [VERT_ATTRIB_FOG] = { + .type = GL_FLOAT, + .fields = 1, + }, + [VERT_ATTRIB_TEX0] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX1] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX2] = { + .type = GL_FLOAT, + .fields = -1, + }, + [VERT_ATTRIB_TEX3] = { + .type = GL_FLOAT, + .fields = -1, + }, +}; + +static void +swtnl_choose_attrs(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct tnl_clipspace *vtx = &tnl->clipspace; + static struct tnl_attr_map map[NUM_VERTEX_ATTRS]; + int fields, i, n = 0; + + render->mode = VBO; + render->attr_count = NUM_VERTEX_ATTRS; + + /* We always want non Ndc coords format */ + tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.ClipPtr; + + for (i = 0; i < VERT_ATTRIB_MAX; i++) { + struct nouveau_attr_info *ha = &TAG(vertex_attrs)[i]; + struct swtnl_attr_info *sa = &swtnl_attrs[i]; + struct nouveau_array_state *a = &render->attrs[i]; + + if (!sa->fields) + continue; /* Unsupported attribute. */ + + if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, i)) { + if (sa->fields > 0) + fields = sa->fields; + else + fields = tnl->vb.AttribPtr[i]->size; + + map[n++] = (struct tnl_attr_map) { + .attrib = i, + .format = swtnl_get_format(sa->type, fields), + }; + + render->map[ha->vbo_index] = i; + a->attr = i; + a->fields = fields; + a->type = sa->type; + } + } + + _tnl_install_attrs(ctx, map, n, NULL, 0); + + for (i = 0; i < vtx->attr_count; i++) { + struct tnl_clipspace_attr *ta = &vtx->attr[i]; + struct nouveau_array_state *a = &render->attrs[ta->attrib]; + + a->stride = vtx->vertex_size; + a->offset = ta->vertoffset; + } + + TAG(render_set_format)(ctx); +} + +static void +swtnl_alloc_vertices(GLcontext *ctx) +{ + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; + + nouveau_bo_ref(NULL, &swtnl->vbo); + swtnl->buf = get_scratch_vbo(ctx, RENDER_SCRATCH_SIZE, + &swtnl->vbo, NULL); + swtnl->vertex_count = 0; +} + +static void +swtnl_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_swtnl_state *swtnl = &render->swtnl; + int i; + + for (i = 0; i < render->attr_count; i++) { + int attr = render->map[i]; + + if (attr >= 0) + nouveau_bo_ref(swtnl->vbo, + &render->attrs[attr].bo); + } + + TAG(render_bind_vertices)(ctx); +} + +static void +swtnl_unbind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + for (i = 0; i < render->attr_count; i++) { + int *attr = &render->map[i]; + + if (*attr >= 0) { + nouveau_bo_ref(NULL, &render->attrs[*attr].bo); + *attr = -1; + } + } + + render->attr_count = 0; +} + +static void +swtnl_flush_vertices(GLcontext *ctx) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; + unsigned push, start = 0, count = swtnl->vertex_count; + RENDER_LOCALS(ctx); + + swtnl_bind_vertices(ctx); + + while (count) { + push = get_max_vertices(ctx, NULL, chan->pushbuf->remaining); + push = MIN2(push / 12 * 12, count); + count -= push; + + if (!push) { + FIRE_RING(chan); + continue; + } + + BATCH_BEGIN(nvgl_primitive(swtnl->primitive)); + EMIT_VBO(L, ctx, start, 0, push); + BATCH_END(); + + FIRE_RING(chan); + } + + swtnl_alloc_vertices(ctx); +} + +/* TnL renderer entry points */ + +static void +swtnl_start(GLcontext *ctx) +{ + swtnl_choose_attrs(ctx); +} + +static void +swtnl_finish(GLcontext *ctx) +{ + swtnl_flush_vertices(ctx); + swtnl_unbind_vertices(ctx); +} + +static void +swtnl_primitive(GLcontext *ctx, GLenum mode) +{ +} + +static void +swtnl_reset_stipple(GLcontext *ctx) +{ +} + +/* Primitive rendering */ + +#define BEGIN_PRIMITIVE(p, n) \ + struct nouveau_swtnl_state *swtnl = &to_render_state(ctx)->swtnl; \ + int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size; \ + \ + if (swtnl->vertex_count + (n) > swtnl->vbo->size/vertex_len \ + || (swtnl->vertex_count && swtnl->primitive != p)) \ + swtnl_flush_vertices(ctx); \ + \ + swtnl->primitive = p; + +#define OUT_VERTEX(i) do { \ + memcpy(swtnl->buf + swtnl->vertex_count * vertex_len, \ + _tnl_get_vertex(ctx, (i)), vertex_len); \ + swtnl->vertex_count++; \ + } while (0) + +static void +swtnl_points(GLcontext *ctx, GLuint first, GLuint last) +{ + int i, count; + + while (first < last) { + BEGIN_PRIMITIVE(GL_POINTS, last - first); + + count = MIN2(swtnl->vbo->size / vertex_len, last - first); + for (i = 0; i < count; i++) + OUT_VERTEX(first + i); + + first += count; + } +} + +static void +swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2) +{ + BEGIN_PRIMITIVE(GL_LINES, 2); + OUT_VERTEX(v1); + OUT_VERTEX(v2); +} + +static void +swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3) +{ + BEGIN_PRIMITIVE(GL_TRIANGLES, 3); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); +} + +static void +swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4) +{ + BEGIN_PRIMITIVE(GL_QUADS, 4); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + OUT_VERTEX(v4); +} + +/* TnL initialization. */ +static void +TAG(swtnl_init)(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.Interp = _tnl_interp; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + + tnl->Driver.Render.Start = swtnl_start; + tnl->Driver.Render.Finish = swtnl_finish; + tnl->Driver.Render.PrimitiveNotify = swtnl_primitive; + tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple; + + tnl->Driver.Render.Points = swtnl_points; + tnl->Driver.Render.Line = swtnl_line; + tnl->Driver.Render.Triangle = swtnl_triangle; + tnl->Driver.Render.Quad = swtnl_quad; + + _tnl_init_vertices(ctx, tnl->vb.Size, + NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat)); + _tnl_need_projected_coords(ctx, GL_FALSE); + _tnl_allow_vertex_fog(ctx, GL_FALSE); + _tnl_wakeup(ctx); + + swtnl_alloc_vertices(ctx); +} + +static void +TAG(swtnl_destroy)(GLcontext *ctx) +{ + nouveau_bo_ref(NULL, &to_render_state(ctx)->swtnl.vbo); +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c new file mode 100644 index 00000000000..ab6e93cceb4 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" + +#include "main/texobj.h" +#include "main/texstore.h" +#include "main/texformat.h" +#include "main/texcompress.h" +#include "main/texgetimage.h" +#include "main/mipmap.h" +#include "main/texfetch.h" + +static struct gl_texture_object * +nouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target) +{ + struct nouveau_texture *nt = CALLOC_STRUCT(nouveau_texture); + + _mesa_initialize_texture_object(&nt->base, name, target); + + return &nt->base; +} + +static void +nouveau_texture_free(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_texture *nt = to_nouveau_texture(t); + int i; + + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + nouveau_surface_ref(NULL, &nt->surfaces[i]); + + _mesa_delete_texture_object(ctx, t); +} + +static struct gl_texture_image * +nouveau_teximage_new(GLcontext *ctx) +{ + struct nouveau_teximage *nti = CALLOC_STRUCT(nouveau_teximage); + + return &nti->base; +} + +static void +nouveau_teximage_free(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_teximage *nti = to_nouveau_teximage(ti); + + nouveau_surface_ref(NULL, &nti->surface); +} + +static void +nouveau_teximage_map(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + int ret; + + ret = nouveau_bo_map(s->bo, NOUVEAU_BO_RDWR); + assert(!ret); + + ti->Data = s->bo->map; +} + +static void +nouveau_teximage_unmap(GLcontext *ctx, struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + + nouveau_bo_unmap(s->bo); + ti->Data = NULL; +} + +static gl_format +nouveau_choose_tex_format(GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType) +{ + switch (internalFormat) { + case 4: + case GL_RGBA: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + case GL_RGBA8: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return MESA_FORMAT_ARGB8888; + case GL_RGB5_A1: + return MESA_FORMAT_ARGB1555; + case GL_RGBA2: + case GL_RGBA4: + return MESA_FORMAT_ARGB4444; + + case 3: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + return MESA_FORMAT_RGB565; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_ALPHA8: + return MESA_FORMAT_A8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_LUMINANCE8: + return MESA_FORMAT_L8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_LUMINANCE8_ALPHA8: + return MESA_FORMAT_ARGB8888; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_INTENSITY8: + return MESA_FORMAT_ARGB8888; + + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + case GL_COLOR_INDEX8_EXT: + return MESA_FORMAT_CI8; + + default: + assert(0); + } +} + +static void +nouveau_teximage(GLcontext *ctx, GLint dims, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + unsigned bo_flags = NOUVEAU_BO_GART | NOUVEAU_BO_RDWR | NOUVEAU_BO_MAP; + int ret; + + /* Allocate a new bo for the image. */ + nouveau_surface_alloc(ctx, s, LINEAR, bo_flags, ti->TexFormat, + width, height); + ti->RowStride = s->pitch / s->cpp; + + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, + format, type, pixels, packing, + "glTexImage"); + if (!pixels) + return; + + /* Store the pixel data. */ + nouveau_teximage_map(ctx, ti); + + ret = _mesa_texstore(ctx, dims, ti->_BaseFormat, + ti->TexFormat, ti->Data, + 0, 0, 0, s->pitch, + ti->ImageOffsets, + width, height, depth, + format, type, pixels, packing); + assert(ret); + + nouveau_teximage_unmap(ctx, ti); + _mesa_unmap_teximage_pbo(ctx, packing); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_teximage_1d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 1, target, level, internalFormat, + width, 1, 1, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_teximage_2d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 2, target, level, internalFormat, + width, height, 1, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_teximage_3d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage(ctx, 3, target, level, internalFormat, + width, height, depth, border, format, type, pixels, + packing, t, ti); +} + +static void +nouveau_texsubimage_3d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_texsubimage_2d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, + width, height, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_texsubimage_1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint width, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_store_texsubimage1d(ctx, target, level, xoffset, + width, format, type, pixels, + packing, t, ti); + nouveau_teximage_unmap(ctx, ti); + + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + texture_dirty(t); +} + +static void +nouveau_get_teximage(GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + struct gl_texture_object *t, + struct gl_texture_image *ti) +{ + nouveau_teximage_map(ctx, ti); + _mesa_get_teximage(ctx, target, level, format, type, pixels, + t, ti); + nouveau_teximage_unmap(ctx, ti); +} + +static void +nouveau_bind_texture(GLcontext *ctx, GLenum target, + struct gl_texture_object *t) +{ + context_dirty_i(ctx, TEX_OBJ, ctx->Texture.CurrentUnit); + context_dirty_i(ctx, TEX_ENV, ctx->Texture.CurrentUnit); +} + +static void +nouveau_texture_map(GLcontext *ctx, struct gl_texture_object *t) +{ + int i; + + for (i = t->BaseLevel; i < t->_MaxLevel; i++) { + if (t->Image[0][i]) + nouveau_teximage_map(ctx, t->Image[0][i]); + } +} + +static void +nouveau_texture_unmap(GLcontext *ctx, struct gl_texture_object *t) +{ + int i; + + for (i = t->BaseLevel; i < t->_MaxLevel; i++) { + if (t->Image[0][i]) + nouveau_teximage_unmap(ctx, t->Image[0][i]); + } +} + +static void +relayout_miptree(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_surface *ss = to_nouveau_texture(t)->surfaces; + unsigned last_level, offset = 0; + unsigned size; + int i, ret; + + if (t->MinFilter == GL_NEAREST || + t->MinFilter == GL_LINEAR) + last_level = t->BaseLevel; + else + last_level = t->_MaxLevel; + + /* Deallocate the old storage. */ + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) + nouveau_bo_ref(NULL, &ss[i].bo); + + /* Relayout the mipmap tree. */ + for (i = t->BaseLevel; i <= last_level; i++) { + struct nouveau_surface *s = + &to_nouveau_teximage(t->Image[0][i])->surface; + + size = s->width * s->height * s->cpp; + + /* Images larger than 16B have to be aligned. */ + if (size > 16) + offset = align(offset, 64); + + ss[i] = (struct nouveau_surface) { + .offset = offset, + .layout = SWIZZLED, + .format = s->format, + .width = s->width, + .height = s->height, + .cpp = s->cpp, + .pitch = s->width * s->cpp, + }; + + offset += size; + } + + /* Get new storage. */ + size = align(offset, 64); + + ret = nouveau_bo_new(context_dev(ctx), + NOUVEAU_BO_GART | NOUVEAU_BO_VRAM, + 0, size, &ss[last_level].bo); + assert(!ret); + + for (i = t->BaseLevel; i < last_level; i++) + nouveau_bo_ref(ss[last_level].bo, &ss[i].bo); +} + +void +nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t) +{ + struct nouveau_texture *nt = to_nouveau_texture(t); + int i; + + if (!nt->dirty) + return; + + nt->dirty = GL_FALSE; + + relayout_miptree(ctx, t); + + /* Copy the teximages to the actual swizzled miptree. */ + for (i = t->BaseLevel; i < MAX_TEXTURE_LEVELS; i++) { + struct gl_texture_image *ti = t->Image[0][i]; + struct nouveau_surface *s = &to_nouveau_teximage(ti)->surface; + + if (!nt->surfaces[i].bo) + break; + + context_drv(ctx)->surface_copy(ctx, &nt->surfaces[i], s, + 0, 0, 0, 0, + s->width, s->height); + } +} + +void +nouveau_texture_functions_init(struct dd_function_table *functions) +{ + functions->NewTextureObject = nouveau_texture_new; + functions->DeleteTexture = nouveau_texture_free; + functions->NewTextureImage = nouveau_teximage_new; + functions->FreeTexImageData = nouveau_teximage_free; + functions->ChooseTextureFormat = nouveau_choose_tex_format; + functions->TexImage1D = nouveau_teximage_1d; + functions->TexImage2D = nouveau_teximage_2d; + functions->TexImage3D = nouveau_teximage_3d; + functions->TexSubImage1D = nouveau_texsubimage_1d; + functions->TexSubImage2D = nouveau_texsubimage_2d; + functions->TexSubImage3D = nouveau_texsubimage_3d; + functions->GetTexImage = nouveau_get_teximage; + functions->BindTexture = nouveau_bind_texture; + functions->MapTexture = nouveau_texture_map; + functions->UnmapTexture = nouveau_texture_unmap; +} diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.h b/src/mesa/drivers/dri/nouveau/nouveau_texture.h new file mode 100644 index 00000000000..695c0897b59 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_TEXTURE_H__ +#define __NOUVEAU_TEXTURE_H__ + +struct nouveau_teximage { + struct gl_texture_image base; + struct nouveau_surface surface; +}; +#define to_nouveau_teximage(x) ((struct nouveau_teximage *)(x)) + +struct nouveau_texture { + struct gl_texture_object base; + struct nouveau_surface surfaces[MAX_TEXTURE_LEVELS]; + GLboolean dirty; +}; +#define to_nouveau_texture(x) ((struct nouveau_texture *)(x)) + +#define texture_dirty(t) \ + to_nouveau_texture(t)->dirty = GL_TRUE; + +void +nouveau_texture_validate(GLcontext *ctx, struct gl_texture_object *t); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_util.h b/src/mesa/drivers/dri/nouveau/nouveau_util.h new file mode 100644 index 00000000000..076f225fedc --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_util.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NOUVEAU_UTIL_H__ +#define __NOUVEAU_UTIL_H__ + +#include "main/formats.h" +#include "main/colormac.h" + +static inline unsigned +pack_rgba_i(gl_format f, uint8_t c[]) +{ + switch (f) { + case MESA_FORMAT_ARGB8888: + return PACK_COLOR_8888(c[ACOMP], c[RCOMP], c[GCOMP], c[BCOMP]); + case MESA_FORMAT_ARGB8888_REV: + return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], c[ACOMP]); + case MESA_FORMAT_XRGB8888: + return PACK_COLOR_8888(0, c[RCOMP], c[GCOMP], c[BCOMP]); + case MESA_FORMAT_XRGB8888_REV: + return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], 0); + case MESA_FORMAT_RGBA8888: + return PACK_COLOR_8888(c[RCOMP], c[GCOMP], c[BCOMP], c[ACOMP]); + case MESA_FORMAT_RGBA8888_REV: + return PACK_COLOR_8888(c[ACOMP], c[BCOMP], c[GCOMP], c[RCOMP]); + case MESA_FORMAT_RGB565: + return PACK_COLOR_565(c[RCOMP], c[GCOMP], c[BCOMP]); + default: + assert(0); + } +} + +static inline unsigned +pack_zs_i(gl_format f, uint32_t z, uint8_t s) +{ + switch (f) { + case MESA_FORMAT_Z24_S8: + return (z & 0xffffff00) | (s & 0xff); + case MESA_FORMAT_Z24_X8: + return (z & 0xffffff00); + case MESA_FORMAT_Z16: + return (z & 0xffff0000) >> 16; + default: + assert(0); + } +} + +static inline unsigned +pack_rgba_f(gl_format f, float c[]) +{ + return pack_rgba_i(f, (uint8_t []) { + FLOAT_TO_UBYTE(c[RCOMP]), + FLOAT_TO_UBYTE(c[GCOMP]), + FLOAT_TO_UBYTE(c[BCOMP]), + FLOAT_TO_UBYTE(c[ACOMP]) }); +} + +static inline unsigned +pack_zs_f(gl_format f, float z, uint8_t s) +{ + return pack_zs_i(f, FLOAT_TO_UINT(z), s); +} + +/* Integer base-2 logarithm, rounded towards zero. */ +static inline unsigned +log2i(unsigned i) +{ + unsigned 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; +} + +static inline unsigned +align(unsigned x, unsigned m) +{ + return (x + m - 1) & ~(m - 1); +} + +static inline void +get_scissors(struct gl_framebuffer *fb, int *x, int *y, int *w, int *h) +{ + *w = fb->_Xmax - fb->_Xmin; + *h = fb->_Ymax - fb->_Ymin; + *x = fb->_Xmin; + *y = (fb->Name ? fb->_Ymin : + /* Window system FBO: Flip the Y coordinate. */ + fb->Height - fb->_Ymax); +} + +static inline void +get_viewport_scale(GLcontext *ctx, float a[16]) +{ + struct gl_viewport_attrib *vp = &ctx->Viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + a[MAT_SX] = (float)vp->Width / 2; + + if (fb->Name) + a[MAT_SY] = (float)vp->Height / 2; + else + /* Window system FBO: Flip the Y coordinate. */ + a[MAT_SY] = - (float)vp->Height / 2; + + a[MAT_SZ] = fb->_DepthMaxF * (vp->Far - vp->Near) / 2; +} + +static inline void +get_viewport_translate(GLcontext *ctx, float a[4]) +{ + struct gl_viewport_attrib *vp = &ctx->Viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + a[0] = (float)vp->Width / 2 + vp->X; + + if (fb->Name) + a[1] = (float)vp->Height / 2 + vp->Y; + else + /* Window system FBO: Flip the Y coordinate. */ + a[1] = fb->Height - (float)vp->Height / 2 - vp->Y; + + a[2] = fb->_DepthMaxF * (vp->Far + vp->Near) / 2; +} + +static inline void +OUT_RINGm(struct nouveau_channel *chan, float m[16]) +{ + int i, j; + + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m[4*j + i]); +} + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c new file mode 100644 index 00000000000..ba1192a1704 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "main/bufferobj.h" +#include "nouveau_bufferobj.h" + +/* Arbitrary pushbuf length we can assume we can get with a single + * WAIT_RING. */ +#define PUSHBUF_DWORDS 2048 + +/* Functions to set up struct nouveau_array_state from something like + * a GL array or index buffer. */ + +static void +vbo_init_array(struct nouveau_array_state *a, int attr, int stride, + int fields, int type, struct gl_buffer_object *obj, + const void *ptr, GLboolean map) +{ + a->attr = attr; + a->stride = stride; + a->fields = fields; + a->type = type; + + if (_mesa_is_bufferobj(obj)) { + nouveau_bo_ref(to_nouveau_bufferobj(obj)->bo, &a->bo); + a->offset = (intptr_t)ptr; + + if (map) { + nouveau_bo_map(a->bo, NOUVEAU_BO_RD); + a->buf = a->bo->map + a->offset; + } else { + a->buf = NULL; + } + + } else { + nouveau_bo_ref(NULL, &a->bo); + a->offset = 0; + a->buf = ptr; + } + + if (a->buf) + get_array_extract(a, &a->extract_u, &a->extract_f); +} + +static void +vbo_deinit_array(struct nouveau_array_state *a) +{ + if (a->bo) { + if (a->bo->map) + nouveau_bo_unmap(a->bo); + nouveau_bo_ref(NULL, &a->bo); + } + + a->buf = NULL; + a->fields = 0; +} + +static void +vbo_init_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib, + const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + if (ib) + vbo_init_array(&render->ib, 0, 0, ib->count, ib->type, + ib->obj, ib->ptr, GL_TRUE); + + for (i = 0; i < render->attr_count; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + const struct gl_client_array *array = arrays[attr]; + + vbo_init_array(&render->attrs[attr], attr, + array->StrideB, array->Size, + array->Type, array->BufferObj, + array->Ptr, render->mode == IMM); + } + } +} + +static void +vbo_deinit_arrays(GLcontext *ctx, const struct _mesa_index_buffer *ib, + const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + if (ib) + vbo_deinit_array(&render->ib); + + for (i = 0; i < render->attr_count; i++) { + int *attr = &render->map[i]; + + if (*attr >= 0) { + vbo_deinit_array(&render->attrs[*attr]); + *attr = -1; + } + } + + render->attr_count = 0; +} + +/* Make some rendering decisions from the GL context. */ + +static void +vbo_choose_render_mode(GLcontext *ctx, const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + render->mode = VBO; + + if (ctx->Light.Enabled) { + for (i = 0; i < MAT_ATTRIB_MAX; i++) { + if (arrays[VERT_ATTRIB_GENERIC0 + i]->StrideB) { + render->mode = IMM; + break; + } + } + } + + if (render->mode == VBO) + render->attr_count = NUM_VERTEX_ATTRS; + else + render->attr_count = 0; +} + +static void +vbo_emit_attr(GLcontext *ctx, const struct gl_client_array **arrays, int attr) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_render_state *render = to_render_state(ctx); + const struct gl_client_array *array = arrays[attr]; + struct nouveau_array_state *a = &render->attrs[attr]; + RENDER_LOCALS(ctx); + + if (!array->StrideB) { + if (attr >= VERT_ATTRIB_GENERIC0) + /* nouveau_update_state takes care of materials. */ + return; + + /* Constant attribute. */ + vbo_init_array(a, attr, array->StrideB, array->Size, + array->Type, array->BufferObj, array->Ptr, + GL_TRUE); + EMIT_IMM(ctx, a, 0); + vbo_deinit_array(a); + + } else { + /* Varying attribute. */ + struct nouveau_attr_info *info = &TAG(vertex_attrs)[attr]; + + if (render->mode == VBO) { + render->map[info->vbo_index] = attr; + render->vertex_size += array->_ElementSize; + } else { + render->map[render->attr_count++] = attr; + render->vertex_size += 4 * info->imm_fields; + } + } +} + +#define MAT(a) (VERT_ATTRIB_GENERIC0 + MAT_ATTRIB_##a) + +static void +vbo_choose_attrs(GLcontext *ctx, const struct gl_client_array **arrays) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + /* Reset the vertex size. */ + render->vertex_size = 0; + + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR0); + if (ctx->Fog.ColorSumEnabled && !ctx->Light.Enabled) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_COLOR1); + + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + if (ctx->Texture._EnabledCoordUnits & (1 << i)) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_TEX0 + i); + } + + if (ctx->Fog.Enabled && ctx->Fog.FogCoordinateSource == GL_FOG_COORD) + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_FOG); + + if (ctx->Light.Enabled) { + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_NORMAL); + + vbo_emit_attr(ctx, arrays, MAT(FRONT_AMBIENT)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_DIFFUSE)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_SPECULAR)); + vbo_emit_attr(ctx, arrays, MAT(FRONT_SHININESS)); + + if (ctx->Light.Model.TwoSide) { + vbo_emit_attr(ctx, arrays, MAT(BACK_AMBIENT)); + vbo_emit_attr(ctx, arrays, MAT(BACK_DIFFUSE)); + vbo_emit_attr(ctx, arrays, MAT(BACK_SPECULAR)); + vbo_emit_attr(ctx, arrays, MAT(BACK_SHININESS)); + } + } + + vbo_emit_attr(ctx, arrays, VERT_ATTRIB_POS); +} + +static void +TAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index); + +static GLboolean +vbo_maybe_split(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLuint min_index, GLuint max_index) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + unsigned pushbuf_avail = PUSHBUF_DWORDS - 2 * nctx->bo.count, + vert_avail = get_max_vertices(ctx, NULL, pushbuf_avail), + idx_avail = get_max_vertices(ctx, ib, pushbuf_avail); + + if ((ib && ib->count > idx_avail) || + (!ib && max_index - min_index > vert_avail)) { + struct split_limits limits = { + .max_verts = vert_avail, + .max_indices = idx_avail, + .max_vb_size = ~0, + }; + + vbo_split_prims(ctx, arrays, prims, nr_prims, ib, min_index, + max_index, TAG(vbo_render_prims), &limits); + return GL_TRUE; + } + + return GL_FALSE; +} + +/* VBO rendering path. */ + +static void +vbo_bind_vertices(GLcontext *ctx, const struct gl_client_array **arrays, + GLint basevertex, GLuint min_index, GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + const struct gl_client_array *array = arrays[attr]; + struct nouveau_array_state *a = &render->attrs[attr]; + unsigned delta = (basevertex + min_index) * a->stride, + size = (max_index - min_index + 1) * a->stride; + + if (a->bo) { + a->offset = (intptr_t)array->Ptr + delta; + } else { + void *scratch = get_scratch_vbo(ctx, size, + &a->bo, + &a->offset); + + memcpy(scratch, a->buf + delta, size); + } + } + } + + TAG(render_bind_vertices)(ctx); +} + +static void +vbo_draw_vbo(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, GLuint min_index, + GLuint max_index) +{ + struct nouveau_channel *chan = context_chan(ctx); + dispatch_t dispatch; + int delta = -min_index, basevertex = 0, i; + RENDER_LOCALS(ctx); + + get_array_dispatch(&to_render_state(ctx)->ib, &dispatch); + + TAG(render_set_format)(ctx); + + for (i = 0; i < nr_prims; i++) { + unsigned start = prims[i].start, + count = prims[i].count; + + if (i == 0 || basevertex != prims[i].basevertex) { + basevertex = prims[i].basevertex; + vbo_bind_vertices(ctx, arrays, basevertex, + min_index, max_index); + } + + if (count > get_max_vertices(ctx, ib, chan->pushbuf->remaining)) + WAIT_RING(chan, PUSHBUF_DWORDS); + + BATCH_BEGIN(nvgl_primitive(prims[i].mode)); + dispatch(ctx, start, delta, count); + BATCH_END(); + } + + FIRE_RING(chan); +} + +/* Immediate rendering path. */ + +static unsigned +extract_id(struct nouveau_array_state *a, int i, int j) +{ + return j; +} + +static void +vbo_draw_imm(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, GLuint min_index, + GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + extract_u_t extract = ib ? render->ib.extract_u : extract_id; + int i, j, k; + RENDER_LOCALS(ctx); + + for (i = 0; i < nr_prims; i++) { + unsigned start = prims[i].start, + end = start + prims[i].count; + + if (prims[i].count > get_max_vertices(ctx, ib, + chan->pushbuf->remaining)) + WAIT_RING(chan, PUSHBUF_DWORDS); + + BATCH_BEGIN(nvgl_primitive(prims[i].mode)); + + for (; start < end; start++) { + j = prims[i].basevertex + + extract(&render->ib, 0, start); + + for (k = 0; k < render->attr_count; k++) + EMIT_IMM(ctx, &render->attrs[render->map[k]], + j); + } + + BATCH_END(); + } + + FIRE_RING(chan); +} + +/* draw_prims entry point when we're doing hw-tnl. */ + +static void +TAG(vbo_render_prims)(GLcontext *ctx, const struct gl_client_array **arrays, + const struct _mesa_prim *prims, GLuint nr_prims, + const struct _mesa_index_buffer *ib, + GLboolean index_bounds_valid, + GLuint min_index, GLuint max_index) +{ + struct nouveau_render_state *render = to_render_state(ctx); + + if (!index_bounds_valid) + vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index); + + vbo_choose_render_mode(ctx, arrays); + vbo_choose_attrs(ctx, arrays); + + if (vbo_maybe_split(ctx, arrays, prims, nr_prims, ib, min_index, + max_index)) + return; + + vbo_init_arrays(ctx, ib, arrays); + + if (render->mode == VBO) + vbo_draw_vbo(ctx, arrays, prims, nr_prims, ib, min_index, + max_index); + else + vbo_draw_imm(ctx, arrays, prims, nr_prims, ib, min_index, + max_index); + + vbo_deinit_arrays(ctx, ib, arrays); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.c b/src/mesa/drivers/dri/nouveau/nv04_context.c new file mode 100644 index 00000000000..5548286a73e --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_context.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +struct nouveau_grobj * +nv04_context_engine(GLcontext *ctx) +{ + struct nv04_context *nctx = to_nv04_context(ctx); + struct nouveau_screen *screen = nctx->base.screen; + struct nouveau_grobj *fahrenheit; + + if (ctx->Texture.Unit[0].EnvMode == GL_COMBINE || + ctx->Texture.Unit[0].EnvMode == GL_BLEND || + ctx->Texture.Unit[1]._ReallyEnabled || + ctx->Stencil.Enabled) + fahrenheit = screen->eng3dm; + else + fahrenheit = screen->eng3d; + + if (fahrenheit != nctx->eng3d) { + nctx->eng3d = fahrenheit; + + if (nv04_mtex_engine(fahrenheit)) { + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_ENV, 1); + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty_i(ctx, TEX_OBJ, 1); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + } else { + context_bctx_i(ctx, TEXTURE, 1); + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + } + } + + return fahrenheit; +} + +static void +init_dummy_texture(GLcontext *ctx) +{ + struct nouveau_surface *s = &to_nv04_context(ctx)->dummy_texture; + + nouveau_surface_alloc(ctx, s, SWIZZLED, + NOUVEAU_BO_MAP | NOUVEAU_BO_VRAM, + MESA_FORMAT_ARGB8888, 1, 1); + + nouveau_bo_map(s->bo, NOUVEAU_BO_WR); + *(uint32_t *)s->bo->map = 0xffffffff; + nouveau_bo_unmap(s->bo); +} + +GLcontext * +nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nv04_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nv04_context); + if (!nctx) + return NULL; + + ctx = &nctx->base.base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureCoordUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV04_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 2; + ctx->Const.MaxTextureLodBias = 15; + + init_dummy_texture(ctx); + nv04_render_init(ctx); + + return ctx; +} + +void +nv04_context_destroy(GLcontext *ctx) +{ + nv04_render_destroy(ctx); + nouveau_surface_ref(NULL, &to_nv04_context(ctx)->dummy_texture); + + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_context.h b/src/mesa/drivers/dri/nouveau/nv04_context.h new file mode 100644 index 00000000000..ed4eec9865f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_context.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV04_CONTEXT_H__ +#define __NV04_CONTEXT_H__ + +#include "nouveau_context.h" + +struct nv04_context { + struct nouveau_context base; + struct nouveau_grobj *eng3d; + struct nouveau_surface dummy_texture; + float viewport[16]; +}; +#define to_nv04_context(ctx) ((struct nv04_context *)(ctx)) + +#define nv04_mtex_engine(obj) ((obj)->grclass == NV04_MULTITEX_TRIANGLE) + +struct nouveau_grobj * +nv04_context_engine(GLcontext *ctx); + +GLcontext * +nv04_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv04_context_destroy(GLcontext *ctx); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv04_driver.h b/src/mesa/drivers/dri/nouveau/nv04_driver.h new file mode 100644 index 00000000000..00668710acc --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_driver.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV04_DRIVER_H__ +#define __NV04_DRIVER_H__ + +#include "nv04_context.h" + +enum { + NOUVEAU_STATE_BLEND = NUM_NOUVEAU_STATE, + NOUVEAU_STATE_CONTROL, + NUM_NV04_STATE +}; + +#define NV04_TEXTURE_UNITS 2 + +/* nv04_screen.c */ +GLboolean +nv04_screen_init(struct nouveau_screen *screen); + +/* nv04_render.c */ +void +nv04_render_init(GLcontext *ctx); + +void +nv04_render_destroy(GLcontext *ctx); + +/* nv04_surface.c */ +GLboolean +nv04_surface_init(struct nouveau_screen *screen); + +void +nv04_surface_takedown(struct nouveau_screen *screen); + +void +nv04_surface_copy(GLcontext *ctx, + struct nouveau_surface *dst, struct nouveau_surface *src, + int dx, int dy, int sx, int sy, int w, int h); + +void +nv04_surface_fill(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h); + +/* nv04_state_fb.c */ +void +nv04_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv04_emit_scissor(GLcontext *ctx, int emit); + +/* nv04_state_raster.c */ +void +nv04_defer_control(GLcontext *ctx, int emit); + +void +nv04_emit_control(GLcontext *ctx, int emit); + +void +nv04_defer_blend(GLcontext *ctx, int emit); + +void +nv04_emit_blend(GLcontext *ctx, int emit); + +/* nv04_state_frag.c */ +void +nv04_emit_tex_env(GLcontext *ctx, int emit); + +/* nv04_state_tex.c */ +void +nv04_emit_tex_obj(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv04_render.c b/src/mesa/drivers/dri/nouveau/nv04_render.c new file mode 100644 index 00000000000..b5943d99871 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_render.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" +#include "tnl/t_vertex.h" + +#define NUM_VERTEX_ATTRS 6 + +static void +swtnl_update_viewport(GLcontext *ctx) +{ + float *viewport = to_nv04_context(ctx)->viewport; + struct gl_framebuffer *fb = ctx->DrawBuffer; + + get_viewport_scale(ctx, viewport); + get_viewport_translate(ctx, &viewport[MAT_TX]); + + /* It wants normalized Z coordinates. */ + viewport[MAT_SZ] /= fb->_DepthMaxF; + viewport[MAT_TZ] /= fb->_DepthMaxF; +} + +static void +swtnl_emit_attr(GLcontext *ctx, struct tnl_attr_map *m, int attr, int emit) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, attr)) + *m = (struct tnl_attr_map) { + .attrib = attr, + .format = emit, + }; + else + *m = (struct tnl_attr_map) { + .format = EMIT_PAD, + .offset = _tnl_format_info[emit].attrsize, + }; +} + +static void +swtnl_choose_attrs(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct nv04_context *nctx = to_nv04_context(ctx); + static struct tnl_attr_map map[NUM_VERTEX_ATTRS]; + int n = 0; + + tnl->vb.AttribPtr[VERT_ATTRIB_POS] = tnl->vb.NdcPtr; + + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_FOG, EMIT_1UB_1F); + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX0, EMIT_2F); + if (nv04_mtex_engine(fahrenheit)) + swtnl_emit_attr(ctx, &map[n++], _TNL_ATTRIB_TEX1, EMIT_2F); + + swtnl_update_viewport(ctx); + + _tnl_install_attrs(ctx, map, n, nctx->viewport, 0); +} + +/* TnL renderer entry points */ + +static void +swtnl_start(GLcontext *ctx) +{ + swtnl_choose_attrs(ctx); +} + +static void +swtnl_finish(GLcontext *ctx) +{ + FIRE_RING(context_chan(ctx)); +} + +static void +swtnl_primitive(GLcontext *ctx, GLenum mode) +{ +} + +static void +swtnl_reset_stipple(GLcontext *ctx) +{ +} + +/* Primitive rendering */ + +#define BEGIN_PRIMITIVE(n) \ + struct nouveau_channel *chan = context_chan(ctx); \ + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); \ + int vertex_len = TNL_CONTEXT(ctx)->clipspace.vertex_size / 4; \ + \ + if (nv04_mtex_engine(fahrenheit)) \ + BEGIN_RING(chan, fahrenheit, \ + NV04_MULTITEX_TRIANGLE_TLMTVERTEX_SX(0), \ + n * vertex_len); \ + else \ + BEGIN_RING(chan, fahrenheit, \ + NV04_TEXTURED_TRIANGLE_TLVERTEX_SX(0), \ + n * vertex_len); \ + +#define OUT_VERTEX(i) \ + OUT_RINGp(chan, _tnl_get_vertex(ctx, i), vertex_len); + +#define END_PRIMITIVE(draw) \ + if (nv04_mtex_engine(fahrenheit)) { \ + BEGIN_RING(chan, fahrenheit, \ + NV04_MULTITEX_TRIANGLE_DRAWPRIMITIVE(0), 1); \ + OUT_RING(chan, draw); \ + } else { \ + BEGIN_RING(chan, fahrenheit, \ + NV04_TEXTURED_TRIANGLE_DRAWPRIMITIVE(0), 1); \ + OUT_RING(chan, draw); \ + } + +static void +swtnl_points(GLcontext *ctx, GLuint first, GLuint last) +{ +} + +static void +swtnl_line(GLcontext *ctx, GLuint v1, GLuint v2) +{ +} + +static void +swtnl_triangle(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3) +{ + BEGIN_PRIMITIVE(3); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + END_PRIMITIVE(0x210); +} + +static void +swtnl_quad(GLcontext *ctx, GLuint v1, GLuint v2, GLuint v3, GLuint v4) +{ + BEGIN_PRIMITIVE(4); + OUT_VERTEX(v1); + OUT_VERTEX(v2); + OUT_VERTEX(v3); + OUT_VERTEX(v4); + END_PRIMITIVE(0x320210); +} + +/* TnL initialization. */ +void +nv04_render_init(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.Render.Interp = _tnl_interp; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + tnl->Driver.Render.ClippedLine = _tnl_RenderClippedLine; + tnl->Driver.Render.BuildVertices = _tnl_build_vertices; + + tnl->Driver.Render.Start = swtnl_start; + tnl->Driver.Render.Finish = swtnl_finish; + tnl->Driver.Render.PrimitiveNotify = swtnl_primitive; + tnl->Driver.Render.ResetLineStipple = swtnl_reset_stipple; + + tnl->Driver.Render.Points = swtnl_points; + tnl->Driver.Render.Line = swtnl_line; + tnl->Driver.Render.Triangle = swtnl_triangle; + tnl->Driver.Render.Quad = swtnl_quad; + + _tnl_need_projected_coords(ctx, GL_TRUE); + _tnl_init_vertices(ctx, tnl->vb.Size, + NUM_VERTEX_ATTRS * 4 * sizeof(GLfloat)); + _tnl_allow_pixel_fog(ctx, GL_FALSE); + _tnl_wakeup(ctx); +} + +void +nv04_render_destroy(GLcontext *ctx) +{ +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_screen.c b/src/mesa/drivers/dri/nouveau/nv04_screen.c new file mode 100644 index 00000000000..0fc0f4c3911 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_screen.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static const struct nouveau_driver nv04_driver; + +static void +nv04_hwctx_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *surf3d = screen->surf3d; + struct nouveau_grobj *eng3d = screen->eng3d; + struct nouveau_grobj *eng3dm = screen->eng3dm; + + BIND_RING(chan, surf3d, 7); + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_DMA_NOTIFY, 3); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, eng3d, NV04_TEXTURED_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + BEGIN_RING(chan, eng3dm, NV04_MULTITEX_TRIANGLE_DMA_NOTIFY, 4); + OUT_RING(chan, screen->ntfy->handle); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, surf3d->handle); + + FIRE_RING(chan); +} + +static void +nv04_channel_flush_notify(struct nouveau_channel *chan) +{ + struct nouveau_screen *screen = chan->user_private; + struct nouveau_context *nctx = screen->context; + + if (nctx && nctx->fallback < SWRAST) { + GLcontext *ctx = &nctx->base; + + /* Flushing seems to clobber the engine context. */ + context_dirty_i(ctx, TEX_OBJ, 0); + context_dirty_i(ctx, TEX_OBJ, 1); + context_dirty_i(ctx, TEX_ENV, 0); + context_dirty_i(ctx, TEX_ENV, 1); + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); + + nouveau_state_emit(ctx); + } +} + +GLboolean +nv04_screen_init(struct nouveau_screen *screen) +{ + int ret; + + screen->driver = &nv04_driver; + screen->chan->flush_notify = nv04_channel_flush_notify; + + /* 2D engine. */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; + + /* 3D engine. */ + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, + NV04_TEXTURED_TRIANGLE, &screen->eng3d); + if (ret) + return GL_FALSE; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0002, + NV04_MULTITEX_TRIANGLE, &screen->eng3dm); + if (ret) + return GL_FALSE; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0003, + NV04_CONTEXT_SURFACES_3D, &screen->surf3d); + if (ret) + return GL_FALSE; + + nv04_hwctx_init(screen); + + return GL_TRUE; +} + +static void +nv04_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); + + if (screen->eng3dm) + nouveau_grobj_free(&screen->eng3dm); + + if (screen->surf3d) + nouveau_grobj_free(&screen->surf3d); + + nv04_surface_takedown(screen); +} + +static const struct nouveau_driver nv04_driver = { + .screen_destroy = nv04_screen_destroy, + .context_create = nv04_context_create, + .context_destroy = nv04_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_blend, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nouveau_emit_nothing, + nv04_defer_control, + nv04_defer_control, + nouveau_emit_nothing, + nv04_emit_framebuffer, + nv04_defer_blend, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_scissor, + nv04_defer_blend, + nv04_defer_control, + nv04_defer_control, + nv04_defer_control, + nv04_emit_tex_env, + nv04_emit_tex_env, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_tex_obj, + nv04_emit_tex_obj, + nouveau_emit_nothing, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv04_emit_blend, + nv04_emit_control, + }, + .num_emit = NUM_NV04_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_fb.c b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c new file mode 100644 index 00000000000..e97eb2a03b9 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_fb.c @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + default: + assert(0); + } +} + +void +nv04_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf3d = screen->surf3d; + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + uint32_t rt_format = NV04_CONTEXT_SURFACES_3D_FORMAT_TYPE_PITCH; + uint32_t rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, surf3d, + NV04_CONTEXT_SURFACES_3D_OFFSET_COLOR, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, surf3d, + NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, + s->bo, 0, bo_flags); + } + + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1); + OUT_RING(chan, rt_format); + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_PITCH, 1); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + /* Recompute the scissor state. */ + context_dirty(ctx, SCISSOR); +} + +void +nv04_emit_scissor(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf3d = screen->surf3d; + int x, y, w, h; + + get_scissors(ctx->DrawBuffer, &x, &y, &w, &h); + + BEGIN_RING(chan, surf3d, NV04_CONTEXT_SURFACES_3D_CLIP_HORIZONTAL, 2); + OUT_RING(chan, w << 16 | x); + OUT_RING(chan, h << 16 | y); + + /* Messing with surf3d invalidates some engine state. */ + context_dirty(ctx, CONTROL); + context_dirty(ctx, BLEND); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_frag.c b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c new file mode 100644 index 00000000000..34ee2962023 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_frag.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +#define COMBINER_SHIFT(in) \ + (NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT##in##_SHIFT \ + - NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_SHIFT) +#define COMBINER_SOURCE(reg) \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ARGUMENT0_##reg +#define COMBINER_INVERT \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_INVERSE0 +#define COMBINER_ALPHA \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_ALPHA0 + +struct combiner_state { + int unit; + GLboolean alpha; + + /* GL state */ + GLenum mode; + GLenum *source; + GLenum *operand; + GLuint logscale; + + /* Derived HW state */ + uint32_t hw; +}; + +#define __INIT_COMBINER_ALPHA_A GL_TRUE +#define __INIT_COMBINER_ALPHA_RGB GL_FALSE + +/* Initialize a combiner_state struct from the texture unit + * context. */ +#define INIT_COMBINER(chan, rc, i) do { \ + struct gl_tex_env_combine_state *c = \ + ctx->Texture.Unit[i]._CurrentCombine; \ + (rc)->alpha = __INIT_COMBINER_ALPHA_##chan; \ + (rc)->unit = i; \ + (rc)->mode = c->Mode##chan; \ + (rc)->source = c->Source##chan; \ + (rc)->operand = c->Operand##chan; \ + (rc)->logscale = c->ScaleShift##chan; \ + (rc)->hw = 0; \ + } while (0) + +/* Get the combiner source for the specified EXT_texture_env_combine + * argument. */ +static uint32_t +get_arg_source(struct combiner_state *rc, int arg) +{ + switch (rc->source[arg]) { + case GL_TEXTURE: + return rc->unit ? COMBINER_SOURCE(TEXTURE1) : + COMBINER_SOURCE(TEXTURE0); + + case GL_TEXTURE0: + return COMBINER_SOURCE(TEXTURE0); + + case GL_TEXTURE1: + return COMBINER_SOURCE(TEXTURE1); + + case GL_CONSTANT: + return COMBINER_SOURCE(CONSTANT); + + case GL_PRIMARY_COLOR: + return COMBINER_SOURCE(PRIMARY_COLOR); + + case GL_PREVIOUS: + return rc->unit ? COMBINER_SOURCE(PREVIOUS) : + COMBINER_SOURCE(PRIMARY_COLOR); + + default: + assert(0); + } +} + +/* Get the (possibly inverted) combiner input mapping for the + * specified argument. */ +#define INVERT 0x1 + +static uint32_t +get_arg_mapping(struct combiner_state *rc, int arg, int flags) +{ + int map = 0; + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + break; + + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + map |= rc->alpha ? 0 : COMBINER_ALPHA; + break; + } + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + map |= flags & INVERT ? COMBINER_INVERT : 0; + break; + + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + map |= flags & INVERT ? 0 : COMBINER_INVERT; + break; + } + + return map; +} + +/* Bind the combiner input <in> to the combiner source <src>, + * possibly inverted. */ +#define INPUT_SRC(rc, in, src, flags) \ + (rc)->hw |= ((flags & INVERT ? COMBINER_INVERT : 0) | \ + COMBINER_SOURCE(src)) << COMBINER_SHIFT(in) + +/* Bind the combiner input <in> to the EXT_texture_env_combine + * argument <arg>, possibly inverted. */ +#define INPUT_ARG(rc, in, arg, flags) \ + (rc)->hw |= (get_arg_source(rc, arg) | \ + get_arg_mapping(rc, arg, flags)) << COMBINER_SHIFT(in) + +#define UNSIGNED_OP(rc) \ + (rc)->hw |= ((rc)->logscale ? \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_SCALE2 : \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_IDENTITY) +#define SIGNED_OP(rc) \ + (rc)->hw |= ((rc)->logscale ? \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS_SCALE2 : \ + NV04_MULTITEX_TRIANGLE_COMBINE_COLOR_MAP_BIAS) + +static void +setup_combiner(struct combiner_state *rc) +{ + switch (rc->mode) { + case GL_REPLACE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_SRC(rc, 2, ZERO, 0); + INPUT_SRC(rc, 3, ZERO, 0); + UNSIGNED_OP(rc); + break; + + case GL_MODULATE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_ARG(rc, 1, 1, 0); + INPUT_SRC(rc, 2, ZERO, 0); + INPUT_SRC(rc, 3, ZERO, 0); + UNSIGNED_OP(rc); + break; + + case GL_ADD: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_ARG(rc, 2, 1, 0); + INPUT_SRC(rc, 3, ZERO, INVERT); + UNSIGNED_OP(rc); + break; + + case GL_INTERPOLATE: + INPUT_ARG(rc, 0, 0, 0); + INPUT_ARG(rc, 1, 2, 0); + INPUT_ARG(rc, 2, 1, 0); + INPUT_ARG(rc, 3, 2, INVERT); + UNSIGNED_OP(rc); + break; + + case GL_ADD_SIGNED: + INPUT_ARG(rc, 0, 0, 0); + INPUT_SRC(rc, 1, ZERO, INVERT); + INPUT_ARG(rc, 2, 1, 0); + INPUT_SRC(rc, 3, ZERO, INVERT); + SIGNED_OP(rc); + break; + + default: + assert(0); + } +} + +void +nv04_emit_tex_env(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_ENV0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct combiner_state rc_a = {}, rc_c = {}; + + if (!nv04_mtex_engine(fahrenheit)) { + context_dirty(ctx, BLEND); + return; + } + + /* Compute the new combiner state. */ + if (ctx->Texture.Unit[i]._ReallyEnabled) { + INIT_COMBINER(A, &rc_a, i); + setup_combiner(&rc_a); + + INIT_COMBINER(RGB, &rc_c, i); + setup_combiner(&rc_c); + + } else { + if (i == 0) { + INPUT_SRC(&rc_a, 0, PRIMARY_COLOR, 0); + INPUT_SRC(&rc_c, 0, PRIMARY_COLOR, 0); + } else { + INPUT_SRC(&rc_a, 0, PREVIOUS, 0); + INPUT_SRC(&rc_c, 0, PREVIOUS, 0); + } + + INPUT_SRC(&rc_a, 1, ZERO, INVERT); + INPUT_SRC(&rc_c, 1, ZERO, INVERT); + INPUT_SRC(&rc_a, 2, ZERO, 0); + INPUT_SRC(&rc_c, 2, ZERO, 0); + INPUT_SRC(&rc_a, 3, ZERO, 0); + INPUT_SRC(&rc_c, 3, ZERO, 0); + + UNSIGNED_OP(&rc_a); + UNSIGNED_OP(&rc_c); + } + + /* Write the register combiner state out to the hardware. */ + BEGIN_RING(chan, fahrenheit, + NV04_MULTITEX_TRIANGLE_COMBINE_ALPHA(i), 2); + OUT_RING(chan, rc_a.hw); + OUT_RING(chan, rc_c.hw); + + BEGIN_RING(chan, fahrenheit, + NV04_MULTITEX_TRIANGLE_COMBINE_FACTOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Texture.Unit[0].EnvColor)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_raster.c b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c new file mode 100644 index 00000000000..5e3788d1854 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_raster.c @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static unsigned +get_comparison_op(unsigned op) +{ + switch (op) { + case GL_NEVER: + return 0x1; + case GL_LESS: + return 0x2; + case GL_EQUAL: + return 0x3; + case GL_LEQUAL: + return 0x4; + case GL_GREATER: + return 0x5; + case GL_NOTEQUAL: + return 0x6; + case GL_GEQUAL: + return 0x7; + case GL_ALWAYS: + return 0x8; + default: + assert(0); + } +} + +static unsigned +get_stencil_op(unsigned op) +{ + switch (op) { + case GL_KEEP: + return 0x1; + case GL_INCR: + return 0x4; + case GL_DECR: + return 0x5; + case GL_INVERT: + return 0x6; + default: + assert(0); + } +} + +static unsigned +get_texenv_mode(unsigned mode) +{ + switch (mode) { + case GL_REPLACE: + return 0x1; + case GL_ADD: + return 0x2; + case GL_DECAL: + return 0x3; + case GL_MODULATE: + return 0x4; + default: + assert(0); + } +} + +static unsigned +get_blend_func(unsigned func) +{ + switch (func) { + case GL_ZERO: + return 0x1; + case GL_ONE: + return 0x2; + case GL_SRC_COLOR: + return 0x3; + case GL_ONE_MINUS_SRC_COLOR: + return 0x4; + case GL_SRC_ALPHA: + return 0x5; + case GL_ONE_MINUS_SRC_ALPHA: + return 0x6; + case GL_DST_ALPHA: + return 0x7; + case GL_ONE_MINUS_DST_ALPHA: + return 0x8; + case GL_DST_COLOR: + return 0x9; + case GL_ONE_MINUS_DST_COLOR: + return 0xa; + case GL_SRC_ALPHA_SATURATE: + return 0xb; + default: + assert(0); + } +} + +void +nv04_defer_control(GLcontext *ctx, int emit) +{ + context_dirty(ctx, CONTROL); +} + +void +nv04_emit_control(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + + if (nv04_mtex_engine(fahrenheit)) { + int cull_mode = ctx->Polygon.CullFaceMode; + int front_face = ctx->Polygon.FrontFace; + uint32_t ctrl0 = 1 << 30 | + NV04_MULTITEX_TRIANGLE_CONTROL0_ORIGIN; + uint32_t ctrl1 = 0, ctrl2 = 0; + + /* Color mask. */ + if (ctx->Color.ColorMask[0][RCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_RED_WRITE; + if (ctx->Color.ColorMask[0][GCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_GREEN_WRITE; + if (ctx->Color.ColorMask[0][BCOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_BLUE_WRITE; + if (ctx->Color.ColorMask[0][ACOMP]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_WRITE; + + /* Dithering. */ + if (ctx->Color.DitherFlag) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_DITHER_ENABLE; + + /* Cull mode. */ + if (!ctx->Polygon.CullFlag) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_NONE; + else if (cull_mode == GL_FRONT_AND_BACK) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_BOTH; + else + ctrl0 |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ? + NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CW : + NV04_MULTITEX_TRIANGLE_CONTROL0_CULL_MODE_CCW; + + /* Depth test. */ + if (ctx->Depth.Test) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_ENABLE; + + if (ctx->Depth.Mask) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_Z_WRITE; + + ctrl0 |= get_comparison_op(ctx->Depth.Func) << 16; + + /* Alpha test. */ + if (ctx->Color.AlphaEnabled) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_ALPHA_ENABLE; + + ctrl0 |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | + FLOAT_TO_UBYTE(ctx->Color.AlphaRef); + + /* Stencil test. */ + if (ctx->Stencil.WriteMask[0]) + ctrl0 |= NV04_MULTITEX_TRIANGLE_CONTROL0_STENCIL_WRITE; + + if (ctx->Stencil.Enabled) + ctrl1 |= NV04_MULTITEX_TRIANGLE_CONTROL1_STENCIL_ENABLE; + + ctrl1 |= get_comparison_op(ctx->Stencil.Function[0]) << 4 | + ctx->Stencil.Ref[0] << 8 | + ctx->Stencil.ValueMask[0] << 16 | + ctx->Stencil.WriteMask[0] << 24; + + ctrl2 |= get_stencil_op(ctx->Stencil.ZPassFunc[0]) << 8 | + get_stencil_op(ctx->Stencil.ZFailFunc[0]) << 4 | + get_stencil_op(ctx->Stencil.FailFunc[0]); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_CONTROL0, 3); + OUT_RING(chan, ctrl0); + OUT_RING(chan, ctrl1); + OUT_RING(chan, ctrl2); + + } else { + int cull_mode = ctx->Polygon.CullFaceMode; + int front_face = ctx->Polygon.FrontFace; + uint32_t ctrl = 1 << 30 | + NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN; + + /* Dithering. */ + if (ctx->Color.DitherFlag) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE; + + /* Cull mode. */ + if (!ctx->Polygon.CullFlag) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_NONE; + else if (cull_mode == GL_FRONT_AND_BACK) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_BOTH; + else + ctrl |= (cull_mode == GL_FRONT) ^ (front_face == GL_CCW) ? + NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CW : + NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_CCW; + + /* Depth test. */ + if (ctx->Depth.Test) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE; + if (ctx->Depth.Mask) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE; + + ctrl |= get_comparison_op(ctx->Depth.Func) << 16; + + /* Alpha test. */ + if (ctx->Color.AlphaEnabled) + ctrl |= NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE; + + ctrl |= get_comparison_op(ctx->Color.AlphaFunc) << 8 | + FLOAT_TO_UBYTE(ctx->Color.AlphaRef); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_CONTROL, 1); + OUT_RING(chan, ctrl); + } +} + +void +nv04_defer_blend(GLcontext *ctx, int emit) +{ + context_dirty(ctx, BLEND); +} + +void +nv04_emit_blend(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + + if (nv04_mtex_engine(fahrenheit)) { + uint32_t blend = 0x2 << 4 | + NV04_MULTITEX_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; + + /* Alpha blending. */ + blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 | + get_blend_func(ctx->Color.BlendSrcRGB) << 24; + + if (ctx->Color.BlendEnabled) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_BLEND_ENABLE; + + /* Shade model. */ + if (ctx->Light.ShadeModel == GL_SMOOTH) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + else + blend |= NV04_MULTITEX_TRIANGLE_BLEND_SHADE_MODE_FLAT; + + /* Fog. */ + if (ctx->Fog.Enabled) + blend |= NV04_MULTITEX_TRIANGLE_BLEND_FOG_ENABLE; + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_BLEND, 1); + OUT_RING(chan, blend); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FOGCOLOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Fog.Color)); + + } else { + uint32_t blend = 0x2 << 4 | + NV04_TEXTURED_TRIANGLE_BLEND_TEXTURE_PERSPECTIVE_ENABLE; + + /* Alpha blending. */ + blend |= get_blend_func(ctx->Color.BlendDstRGB) << 28 | + get_blend_func(ctx->Color.BlendSrcRGB) << 24; + + if (ctx->Color.BlendEnabled) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_BLEND_ENABLE; + + /* Shade model. */ + if (ctx->Light.ShadeModel == GL_SMOOTH) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD; + else + blend |= NV04_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT; + + /* Texture environment. */ + blend |= get_texenv_mode(ctx->Texture.Unit[0].EnvMode); + + /* Fog. */ + if (ctx->Fog.Enabled) + blend |= NV04_TEXTURED_TRIANGLE_BLEND_FOG_ENABLE; + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_BLEND, 1); + OUT_RING(chan, blend); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FOGCOLOR, 1); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Fog.Color)); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_state_tex.c b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c new file mode 100644 index 00000000000..99ea310c65f --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_state_tex.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_texture.h" +#include "nouveau_util.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv04_driver.h" + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_Y8; + case MESA_FORMAT_ARGB1555: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A1R5G5B5; + case MESA_FORMAT_ARGB4444: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A4R4G4B4; + case MESA_FORMAT_RGB565: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_R5G6B5; + case MESA_FORMAT_ARGB8888: + return NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; + default: + assert(0); + } +} + +static inline unsigned +get_wrap_mode(unsigned wrap) +{ + switch (wrap) { + case GL_REPEAT: + return 0x1; + case GL_MIRRORED_REPEAT: + return 0x2; + case GL_CLAMP: + case GL_CLAMP_TO_EDGE: + return 0x3; + case GL_CLAMP_TO_BORDER: + return 0x4; + default: + assert(0); + } +} + +void +nv04_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *fahrenheit = nv04_context_engine(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct nouveau_surface *s; + uint32_t format = 0xa0, filter = 0x1010; + + if (i && !nv04_mtex_engine(fahrenheit)) + return; + + if (ctx->Texture.Unit[i]._ReallyEnabled) { + struct gl_texture_object *t = ctx->Texture.Unit[i]._Current; + struct gl_texture_image *ti = t->Image[0][t->BaseLevel]; + int lod_max = 1, lod_bias = 0; + + nouveau_texture_validate(ctx, t); + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + lod_max = CLAMP(MIN2(t->MaxLod, t->_MaxLambda), + 0, 15) + 1; + + lod_bias = CLAMP(ctx->Texture.Unit[i].LodBias + + t->LodBias, 0, 15); + } + + format |= get_wrap_mode(t->WrapT) << 28 | + get_wrap_mode(t->WrapS) << 24 | + ti->HeightLog2 << 20 | + ti->WidthLog2 << 16 | + lod_max << 12 | + get_tex_format(ti); + + filter |= log2i(t->MaxAnisotropy) << 31 | + nvgl_filter_mode(t->MagFilter) << 28 | + log2i(t->MaxAnisotropy) << 27 | + nvgl_filter_mode(t->MinFilter) << 24 | + lod_bias << 16; + + } else { + s = &to_nv04_context(ctx)->dummy_texture; + + format |= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT | + NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_REPEAT | + 1 << 12 | + NV04_TEXTURED_TRIANGLE_FORMAT_COLOR_A8R8G8B8; + + filter |= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST | + NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST; + } + + if (nv04_mtex_engine(fahrenheit)) { + nouveau_bo_markl(bctx, fahrenheit, + NV04_MULTITEX_TRIANGLE_OFFSET(i), + s->bo, 0, bo_flags); + + nouveau_bo_mark(bctx, fahrenheit, + NV04_MULTITEX_TRIANGLE_FORMAT(i), + s->bo, format, 0, + NV04_MULTITEX_TRIANGLE_FORMAT_DMA_A, + NV04_MULTITEX_TRIANGLE_FORMAT_DMA_B, + bo_flags | NOUVEAU_BO_OR); + + BEGIN_RING(chan, fahrenheit, NV04_MULTITEX_TRIANGLE_FILTER(i), 1); + OUT_RING(chan, filter); + + } else { + nouveau_bo_markl(bctx, fahrenheit, + NV04_TEXTURED_TRIANGLE_OFFSET, + s->bo, 0, bo_flags); + + nouveau_bo_mark(bctx, fahrenheit, + NV04_TEXTURED_TRIANGLE_FORMAT, + s->bo, format, 0, + NV04_TEXTURED_TRIANGLE_FORMAT_DMA_A, + NV04_TEXTURED_TRIANGLE_FORMAT_DMA_B, + bo_flags | NOUVEAU_BO_OR); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_COLORKEY, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, fahrenheit, NV04_TEXTURED_TRIANGLE_FILTER, 1); + OUT_RING(chan, filter); + } +} diff --git a/src/mesa/drivers/dri/nouveau/nv04_surface.c b/src/mesa/drivers/dri/nouveau/nv04_surface.c new file mode 100644 index 00000000000..0d403493452 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv04_surface.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) 2007-2010 The Nouveau Project. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_class.h" +#include "nouveau_context.h" +#include "nouveau_util.h" +#include "nv04_driver.h" + +static inline int +swzsurf_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_Y8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_SWIZZLED_SURFACE_FORMAT_COLOR_A8R8G8B8; + + default: + assert(0); + } +} + +static inline int +surf2d_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32; + + default: + assert(0); + } +} + +static inline int +rect_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8; + + default: + assert(0); + } +} + +static inline int +sifm_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_RGB332: + case MESA_FORMAT_CI8: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_AY8; + + case MESA_FORMAT_RGB565: + case MESA_FORMAT_RGB565_REV: + case MESA_FORMAT_ARGB4444: + case MESA_FORMAT_ARGB4444_REV: + case MESA_FORMAT_ARGB1555: + case MESA_FORMAT_RGBA5551: + case MESA_FORMAT_ARGB1555_REV: + case MESA_FORMAT_AL88: + case MESA_FORMAT_AL88_REV: + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + case MESA_FORMAT_Z16: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_R5G6B5; + + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_RGBA8888_REV: + case MESA_FORMAT_XRGB8888: + case MESA_FORMAT_ARGB8888: + case MESA_FORMAT_ARGB8888_REV: + case MESA_FORMAT_S8_Z24: + case MESA_FORMAT_Z24_S8: + case MESA_FORMAT_Z32: + return NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT_A8R8G8B8; + + default: + assert(0); + } +} + +static void +nv04_surface_copy_swizzle(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *swzsurf = screen->swzsurf; + struct nouveau_grobj *sifm = screen->sifm; + struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); + const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + /* Max width & height may not be the same on all HW, but must be POT */ + const unsigned max_w = 1024; + const unsigned max_h = 1024; + unsigned sub_w = w > max_w ? max_w : w; + unsigned sub_h = h > max_h ? max_h : h; + unsigned x, y; + + /* Swizzled surfaces must be POT */ + assert(_mesa_is_pow_two(dst->width) && + _mesa_is_pow_two(dst->height)); + + /* If area is too large to copy in one shot we must copy it in + * POT chunks to meet alignment requirements */ + assert(sub_w == w || _mesa_is_pow_two(sub_w)); + assert(sub_h == h || _mesa_is_pow_two(sub_h)); + + nouveau_bo_marko(bctx, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, + src->bo, bo_flags | NOUVEAU_BO_RD); + nouveau_bo_marko(bctx, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, + dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + nouveau_bo_markl(bctx, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, + dst->bo, dst->offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); + + BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); + OUT_RING (chan, swzsurf_format(dst->format) | + log2i(dst->width) << 16 | + log2i(dst->height) << 24); + + BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); + OUT_RING (chan, swzsurf->handle); + + for (y = 0; y < h; y += sub_h) { + sub_h = MIN2(sub_h, h - y); + + for (x = 0; x < w; x += sub_w) { + sub_w = MIN2(sub_w, w - x); + /* Must be 64-byte aligned */ + assert(!(dst->offset & 63)); + + MARK_RING(chan, 15, 1); + + BEGIN_RING(chan, sifm, + NV03_SCALED_IMAGE_FROM_MEMORY_COLOR_FORMAT, 8); + OUT_RING(chan, sifm_format(src->format)); + OUT_RING(chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); + OUT_RING(chan, (y + dy) << 16 | (x + dx)); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, (y + dy) << 16 | (x + dx)); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, 1 << 20); + OUT_RING(chan, 1 << 20); + + BEGIN_RING(chan, sifm, + NV03_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); + OUT_RING(chan, sub_h << 16 | sub_w); + OUT_RING(chan, src->pitch | + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | + NV03_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); + OUT_RELOCl(chan, src->bo, src->offset + + (y + sy) * src->pitch + + (x + sx) * src->cpp, + bo_flags | NOUVEAU_BO_RD); + OUT_RING(chan, 0); + } + } + + nouveau_bo_context_reset(bctx); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +static void +nv04_surface_copy_m2mf(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *m2mf = screen->m2mf; + struct nouveau_bo_context *bctx = context_bctx(ctx, SURFACE); + const unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp; + unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp; + + nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, + src->bo, bo_flags | NOUVEAU_BO_RD); + nouveau_bo_marko(bctx, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_OUT, + dst->bo, bo_flags | NOUVEAU_BO_WR); + + while (h) { + int count = (h > 2047) ? 2047 : h; + + MARK_RING(chan, 9, 2); + + BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + OUT_RELOCl(chan, src->bo, src_offset, + bo_flags | NOUVEAU_BO_RD); + OUT_RELOCl(chan, dst->bo, dst_offset, + bo_flags | NOUVEAU_BO_WR); + OUT_RING (chan, src->pitch); + OUT_RING (chan, dst->pitch); + OUT_RING (chan, w * src->cpp); + OUT_RING (chan, count); + OUT_RING (chan, 0x0101); + OUT_RING (chan, 0); + + h -= count; + src_offset += src->pitch * count; + dst_offset += dst->pitch * count; + } + + nouveau_bo_context_reset(bctx); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +void +nv04_surface_copy(GLcontext *ctx, + struct nouveau_surface *dst, + struct nouveau_surface *src, + int dx, int dy, int sx, int sy, + int w, int h) +{ + /* Setup transfer to swizzle the texture to vram if needed */ + if (src->layout != SWIZZLED && + dst->layout == SWIZZLED && + dst->width > 2 && dst->height > 1) { + nv04_surface_copy_swizzle(ctx, dst, src, + dx, dy, sx, sy, w, h); + return; + } + + nv04_surface_copy_m2mf(ctx, dst, src, dx, dy, sx, sy, w, h); +} + +void +nv04_surface_fill(GLcontext *ctx, + struct nouveau_surface *dst, + unsigned mask, unsigned value, + int dx, int dy, int w, int h) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_screen *screen = to_nouveau_context(ctx)->screen; + struct nouveau_grobj *surf2d = screen->surf2d; + struct nouveau_grobj *patt = screen->patt; + struct nouveau_grobj *rect = screen->rect; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART; + + MARK_RING (chan, 19, 4); + + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2); + OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); + OUT_RELOCo(chan, dst->bo, bo_flags | NOUVEAU_BO_WR); + BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4); + OUT_RING (chan, surf2d_format(dst->format)); + OUT_RING (chan, (dst->pitch << 16) | dst->pitch); + OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst->bo, dst->offset, bo_flags | NOUVEAU_BO_WR); + + BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_COLOR_FORMAT, 1); + OUT_RING (chan, rect_format(dst->format)); + BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR1, 1); + OUT_RING (chan, mask | ~0 << (8 * dst->cpp)); + + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1); + OUT_RING (chan, rect_format(dst->format)); + BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1); + OUT_RING (chan, value); + BEGIN_RING(chan, rect, + NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2); + OUT_RING (chan, (dx << 16) | dy); + OUT_RING (chan, ( w << 16) | h); + + if (context_chipset(ctx) < 0x10) + FIRE_RING(chan); +} + +void +nv04_surface_takedown(struct nouveau_screen *screen) +{ + nouveau_grobj_free(&screen->swzsurf); + nouveau_grobj_free(&screen->sifm); + nouveau_grobj_free(&screen->rect); + nouveau_grobj_free(&screen->rop); + nouveau_grobj_free(&screen->patt); + nouveau_grobj_free(&screen->surf2d); + nouveau_grobj_free(&screen->m2mf); + nouveau_notifier_free(&screen->ntfy); +} + +GLboolean +nv04_surface_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + const unsigned chipset = screen->device->chipset; + unsigned handle = 0x88000000, class; + int ret; + + /* Notifier object. */ + ret = nouveau_notifier_alloc(chan, handle++, 1, &screen->ntfy); + if (ret) + goto fail; + + /* Memory to memory format. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_MEMORY_TO_MEMORY_FORMAT, + &screen->m2mf); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + /* Context surfaces 2D. */ + if (chan->device->chipset < 0x10) + class = NV04_CONTEXT_SURFACES_2D; + else + class = NV10_CONTEXT_SURFACES_2D; + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->surf2d); + if (ret) + goto fail; + + /* Raster op. */ + ret = nouveau_grobj_alloc(chan, handle++, NV03_CONTEXT_ROP, + &screen->rop); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + BEGIN_RING(chan, screen->rop, NV03_CONTEXT_ROP_ROP, 1); + OUT_RING (chan, 0xca); /* DPSDxax in the GDI speech. */ + + /* Image pattern. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_IMAGE_PATTERN, + &screen->patt); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3); + OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE); + OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8); + OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO); + + BEGIN_RING(chan, screen->patt, + NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, ~0); + OUT_RING (chan, ~0); + + /* GDI rectangle text. */ + ret = nouveau_grobj_alloc(chan, handle++, NV04_GDI_RECTANGLE_TEXT, + &screen->rect); + if (ret) + goto fail; + + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); + OUT_RING (chan, screen->ntfy->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + OUT_RING (chan, screen->surf2d->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1); + OUT_RING (chan, screen->rop->handle); + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1); + OUT_RING (chan, screen->patt->handle); + + BEGIN_RING(chan, screen->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND); + BEGIN_RING(chan, screen->rect, + NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1); + OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE); + + /* Swizzled surface. */ + switch (chan->device->chipset & 0xf0) { + case 0x00: + case 0x10: + class = NV04_SWIZZLED_SURFACE; + break; + case 0x20: + class = NV20_SWIZZLED_SURFACE; + break; + case 0x30: + class = NV30_SWIZZLED_SURFACE; + break; + case 0x40: + case 0x60: + class = NV40_SWIZZLED_SURFACE; + break; + default: + /* Famous last words: this really can't happen.. */ + assert(0); + break; + } + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->swzsurf); + if (ret) + goto fail; + + /* Scaled image from memory. */ + switch (chan->device->chipset & 0xf0) { + case 0x10: + case 0x20: + class = NV10_SCALED_IMAGE_FROM_MEMORY; + break; + case 0x30: + class = NV30_SCALED_IMAGE_FROM_MEMORY; + break; + case 0x40: + case 0x60: + class = NV40_SCALED_IMAGE_FROM_MEMORY; + break; + default: + class = NV04_SCALED_IMAGE_FROM_MEMORY; + break; + } + + ret = nouveau_grobj_alloc(chan, handle++, class, &screen->sifm); + if (ret) + goto fail; + + if (chipset >= 0x10) { + BEGIN_RING(chan, screen->sifm, + NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1); + OUT_RING(chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); + } + + return GL_TRUE; + +fail: + nv04_surface_takedown(screen); + return GL_FALSE; +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_context.c b/src/mesa/drivers/dri/nouveau/nv10_context.c new file mode 100644 index 00000000000..d1afa87c8aa --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_context.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +static void +nv10_clear(GLcontext *ctx, GLbitfield buffers) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_framebuffer *nfb = to_nouveau_framebuffer( + ctx->DrawBuffer); + + nouveau_validate_framebuffer(ctx); + + /* Clear the LMA depth buffer, if present. */ + if ((buffers & BUFFER_BIT_DEPTH) && ctx->Depth.Mask && + nfb->lma_bo) { + struct nouveau_surface *s = &to_nouveau_renderbuffer( + nfb->base._DepthBuffer->Wrapped)->surface; + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_FILL_VALUE, 1); + OUT_RING(chan, pack_zs_f(s->format, ctx->Depth.Clear, 0)); + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_BUFFER_CLEAR, 1); + OUT_RING(chan, 1); + } + + nouveau_clear(ctx, buffers); +} + +GLcontext * +nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nouveau_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nouveau_context); + if (!nctx) + return NULL; + + ctx = &nctx->base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureLevels = 12; + ctx->Const.MaxTextureCoordUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV10_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 2; + ctx->Const.MaxTextureLodBias = 15; + ctx->Driver.Clear = nv10_clear; + + nv10_render_init(ctx); + + return ctx; +} + +void +nv10_context_destroy(GLcontext *ctx) +{ + nv10_render_destroy(ctx); + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_driver.h b/src/mesa/drivers/dri/nouveau/nv10_driver.h new file mode 100644 index 00000000000..2a1ef7b08e9 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_driver.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV10_DRIVER_H__ +#define __NV10_DRIVER_H__ + +#define NV10_TEXTURE_UNITS 2 + +/* nv10_screen.c */ +GLboolean +nv10_screen_init(struct nouveau_screen *screen); + +/* nv10_context.c */ +GLcontext * +nv10_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv10_context_destroy(GLcontext *ctx); + +/* nv10_render.c */ +void +nv10_render_init(GLcontext *ctx); + +void +nv10_render_destroy(GLcontext *ctx); + +/* nv10_state_fb.c */ +void +nv10_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv10_emit_render_mode(GLcontext *ctx, int emit); + +void +nv10_emit_scissor(GLcontext *ctx, int emit); + +void +nv10_emit_viewport(GLcontext *ctx, int emit); + +/* nv10_state_polygon.c */ +void +nv10_emit_cull_face(GLcontext *ctx, int emit); + +void +nv10_emit_front_face(GLcontext *ctx, int emit); + +void +nv10_emit_line_mode(GLcontext *ctx, int emit); + +void +nv10_emit_line_stipple(GLcontext *ctx, int emit); + +void +nv10_emit_point_mode(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_mode(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_offset(GLcontext *ctx, int emit); + +void +nv10_emit_polygon_stipple(GLcontext *ctx, int emit); + +/* nv10_state_raster.c */ +void +nv10_emit_alpha_func(GLcontext *ctx, int emit); + +void +nv10_emit_blend_color(GLcontext *ctx, int emit); + +void +nv10_emit_blend_equation(GLcontext *ctx, int emit); + +void +nv10_emit_blend_func(GLcontext *ctx, int emit); + +void +nv10_emit_color_mask(GLcontext *ctx, int emit); + +void +nv10_emit_depth(GLcontext *ctx, int emit); + +void +nv10_emit_dither(GLcontext *ctx, int emit); + +void +nv10_emit_index_mask(GLcontext *ctx, int emit); + +void +nv10_emit_logic_opcode(GLcontext *ctx, int emit); + +void +nv10_emit_shade_model(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_func(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_mask(GLcontext *ctx, int emit); + +void +nv10_emit_stencil_op(GLcontext *ctx, int emit); + +/* nv10_state_frag.c */ +void +nv10_emit_tex_env(GLcontext *ctx, int emit); + +void +nv10_emit_frag(GLcontext *ctx, int emit); + +/* nv10_state_tex.c */ +void +nv10_emit_tex_gen(GLcontext *ctx, int emit); + +void +nv10_emit_tex_obj(GLcontext *ctx, int emit); + +/* nv10_state_tnl.c */ +void +nv10_get_fog_coeff(GLcontext *ctx, float k[3]); + +void +nv10_get_spot_coeff(struct gl_light *l, float k[7]); + +void +nv10_get_shininess_coeff(float s, float k[6]); + +void +nv10_emit_clip_plane(GLcontext *ctx, int emit); + +void +nv10_emit_color_material(GLcontext *ctx, int emit); + +void +nv10_emit_fog(GLcontext *ctx, int emit); + +void +nv10_emit_light_enable(GLcontext *ctx, int emit); + +void +nv10_emit_light_model(GLcontext *ctx, int emit); + +void +nv10_emit_light_source(GLcontext *ctx, int emit); + +void +nv10_emit_material_ambient(GLcontext *ctx, int emit); + +void +nv10_emit_material_diffuse(GLcontext *ctx, int emit); + +void +nv10_emit_material_specular(GLcontext *ctx, int emit); + +void +nv10_emit_material_shininess(GLcontext *ctx, int emit); + +void +nv10_emit_modelview(GLcontext *ctx, int emit); + +void +nv10_emit_point_parameter(GLcontext *ctx, int emit); + +void +nv10_emit_projection(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv10_render.c b/src/mesa/drivers/dri/nouveau/nv10_render.c new file mode 100644 index 00000000000..54245ea6bab --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_render.c @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +#define NUM_VERTEX_ATTRS 8 + +static void +nv10_emit_material(GLcontext *ctx, struct nouveau_array_state *a, + const void *v); + +/* Vertex attribute format. */ +static struct nouveau_attr_info nv10_vertex_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .vbo_index = 0, + .imm_method = NV10TCL_VERTEX_POS_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR0] = { + .vbo_index = 1, + .imm_method = NV10TCL_VERTEX_COL_4F_R, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .vbo_index = 2, + .imm_method = NV10TCL_VERTEX_COL2_3F_R, + .imm_fields = 3, + }, + [VERT_ATTRIB_TEX0] = { + .vbo_index = 3, + .imm_method = NV10TCL_VERTEX_TX0_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX1] = { + .vbo_index = 4, + .imm_method = NV10TCL_VERTEX_TX1_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .vbo_index = 5, + .imm_method = NV10TCL_VERTEX_NOR_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_FOG] = { + .vbo_index = 7, + .imm_method = NV10TCL_VERTEX_FOG_1F, + .imm_fields = 1, + }, + [VERT_ATTRIB_GENERIC0] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC2] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC4] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC6] = { + .emit = nv10_emit_material, + }, + [VERT_ATTRIB_GENERIC8] = { + .emit = nv10_emit_material, + }, +}; + +static int +get_hw_format(int type) +{ + switch (type) { + case GL_FLOAT: + return NV10TCL_VTXFMT_TYPE_FLOAT; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return NV10TCL_VTXFMT_TYPE_SHORT; + case GL_UNSIGNED_BYTE: + return NV10TCL_VTXFMT_TYPE_BYTE_RGBA; + default: + assert(0); + } +} + +static void +nv10_render_set_format(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int i, hw_format; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + hw_format = a->stride << 8 | + a->fields << 4 | + get_hw_format(a->type); + + if (attr == VERT_ATTRIB_POS && a->fields == 4) + hw_format |= NV10TCL_VTXFMT_POS_HOMOGENEOUS; + } else { + /* Unused attribute. */ + hw_format = NV10TCL_VTXFMT_TYPE_FLOAT; + } + + BEGIN_RING(chan, celsius, NV10TCL_VTXFMT(i), 1); + OUT_RING(chan, hw_format); + } +} + +static void +nv10_render_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + nouveau_bo_markl(bctx, celsius, + NV10TCL_VTXBUF_ADDRESS(i), + a->bo, a->offset, + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + } + } + + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_ARRAY_VALIDATE, 1); + OUT_RING(chan, 0); +} + +/* Vertex array rendering defs. */ +#define RENDER_LOCALS(ctx) \ + struct nouveau_grobj *celsius = context_eng3d(ctx) + +#define BATCH_BEGIN(prim) \ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); \ + OUT_RING(chan, prim); +#define BATCH_END() \ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); \ + OUT_RING(chan, 0); + +#define MAX_PACKET 0x400 + +#define MAX_OUT_L 0x100 +#define BATCH_PACKET_L(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VERTEX_BUFFER_DRAW_ARRAYS, n); +#define BATCH_OUT_L(i, n) \ + OUT_RING(chan, ((n) - 1) << 24 | (i)); + +#define MAX_OUT_I16 0x2 +#define BATCH_PACKET_I16(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U16, n); +#define BATCH_OUT_I16(i0, i1) \ + OUT_RING(chan, (i1) << 16 | (i0)); + +#define MAX_OUT_I32 0x1 +#define BATCH_PACKET_I32(n) \ + BEGIN_RING_NI(chan, celsius, NV10TCL_VB_ELEMENT_U32, n); +#define BATCH_OUT_I32(i) \ + OUT_RING(chan, i); + +#define IMM_PACKET(m, n) \ + BEGIN_RING(chan, celsius, m, n); +#define IMM_OUT(x) \ + OUT_RINGf(chan, x); + +#define TAG(x) nv10_##x +#include "nouveau_render_t.c" diff --git a/src/mesa/drivers/dri/nouveau/nv10_screen.c b/src/mesa/drivers/dri/nouveau/nv10_screen.c new file mode 100644 index 00000000000..8665ad14107 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_screen.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" +#include "nv10_driver.h" + +static const struct nouveau_driver nv10_driver; + +static void +nv10_hwctx_init(struct nouveau_screen *screen) +{ + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *celsius = screen->eng3d; + const unsigned chipset = screen->device->chipset; + int i; + + BEGIN_RING(chan, celsius, NV10TCL_DMA_NOTIFY, 1); + OUT_RING(chan, screen->ntfy->handle); + + BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY0, 3); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); + OUT_RING(chan, chan->gart->handle); + BEGIN_RING(chan, celsius, NV10TCL_DMA_IN_MEMORY2, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, 0x7ff << 16 | 0x800); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, 0x7ff << 16 | 0x800); + + for (i = 1; i < 8; i++) { + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); + OUT_RING(chan, 0); + } + + BEGIN_RING(chan, celsius, 0x290, 1); + OUT_RING(chan, 0x10 << 16 | 1); + BEGIN_RING(chan, celsius, 0x3f4, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + if (chipset >= 0x17) { + BEGIN_RING(chan, celsius, NV17TCL_DMA_IN_MEMORY4, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->vram->handle); + + BEGIN_RING(chan, celsius, 0xd84, 1); + OUT_RING(chan, 0x3); + + BEGIN_RING(chan, celsius, NV17TCL_COLOR_MASK_ENABLE, 1); + OUT_RING(chan, 1); + } + + if (chipset >= 0x11) { + BEGIN_RING(chan, celsius, 0x120, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 1); + OUT_RING(chan, 2); + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + } + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + /* Set state */ + BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING(chan, 0x207); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(0), 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 2); + OUT_RING(chan, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 4); + OUT_RING(chan, 1); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0x8006); + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 8); + OUT_RING(chan, 0xff); + OUT_RING(chan, 0x207); + OUT_RING(chan, 0); + OUT_RING(chan, 0xff); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1e00); + OUT_RING(chan, 0x1d01); + BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_FOG_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING(chan, 0x201); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING(chan, 8); + BEGIN_RING(chan, celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING(chan, 8); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING(chan, 0x1b02); + OUT_RING(chan, 0x1b02); + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 2); + OUT_RING(chan, 0x405); + OUT_RING(chan, 0x901); + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_TX_GEN_S(0), 8); + for (i = 0; i < 8; i++) + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_TX_MATRIX_ENABLE(0), 2); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RING(chan, 0x3fc00000); /* -1.50 */ + OUT_RING(chan, 0xbdb8aa0a); /* -0.09 */ + OUT_RING(chan, 0); /* 0.00 */ + + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 2); + OUT_RING(chan, 0x802); + OUT_RING(chan, 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(chan, celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); + OUT_RING(chan, 6); + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING(chan, 0x01010101); + + /* Set vertex component */ + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL_4F_R, 4); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_COL2_3F_R, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_NOR_3F_X, 3); + OUT_RING(chan, 0); + OUT_RING(chan, 0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX0_4F_S, 4); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_TX1_4F_S, 4); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + BEGIN_RING(chan, celsius, NV10TCL_VERTEX_FOG_1F, 1); + OUT_RINGf(chan, 0.0); + BEGIN_RING(chan, celsius, NV10TCL_EDGEFLAG_ENABLE, 1); + OUT_RING(chan, 1); + + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_RANGE_NEAR, 2); + OUT_RING(chan, 0.0); + OUT_RINGf(chan, 16777216.0); + + FIRE_RING(chan); +} + +GLboolean +nv10_screen_init(struct nouveau_screen *screen) +{ + unsigned chipset = screen->device->chipset; + unsigned celsius_class; + int ret; + + screen->driver = &nv10_driver; + + /* 2D engine. */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; + + /* 3D engine. */ + if (chipset >= 0x17) + celsius_class = NV17TCL; + else if (chipset >= 0x11) + celsius_class = NV11TCL; + else + celsius_class = NV10TCL; + + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, celsius_class, + &screen->eng3d); + if (ret) + return GL_FALSE; + + nv10_hwctx_init(screen); + + return GL_TRUE; +} + +static void +nv10_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); + + nv04_surface_takedown(screen); +} + +static const struct nouveau_driver nv10_driver = { + .screen_destroy = nv10_screen_destroy, + .context_create = nv10_context_create, + .context_destroy = nv10_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv10_emit_alpha_func, + nv10_emit_blend_color, + nv10_emit_blend_equation, + nv10_emit_blend_func, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_clip_plane, + nv10_emit_color_mask, + nv10_emit_color_material, + nv10_emit_cull_face, + nv10_emit_front_face, + nv10_emit_depth, + nv10_emit_dither, + nv10_emit_frag, + nv10_emit_framebuffer, + nv10_emit_fog, + nv10_emit_index_mask, + nv10_emit_light_enable, + nv10_emit_light_model, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_light_source, + nv10_emit_line_stipple, + nv10_emit_line_mode, + nv10_emit_logic_opcode, + nv10_emit_material_ambient, + nouveau_emit_nothing, + nv10_emit_material_diffuse, + nouveau_emit_nothing, + nv10_emit_material_specular, + nouveau_emit_nothing, + nv10_emit_material_shininess, + nouveau_emit_nothing, + nv10_emit_modelview, + nv10_emit_point_mode, + nv10_emit_point_parameter, + nv10_emit_polygon_mode, + nv10_emit_polygon_offset, + nv10_emit_polygon_stipple, + nv10_emit_projection, + nv10_emit_render_mode, + nv10_emit_scissor, + nv10_emit_shade_model, + nv10_emit_stencil_func, + nv10_emit_stencil_mask, + nv10_emit_stencil_op, + nv10_emit_tex_env, + nv10_emit_tex_env, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_tex_obj, + nv10_emit_tex_obj, + nouveau_emit_nothing, + nouveau_emit_nothing, + nv10_emit_viewport + }, + .num_emit = NUM_NOUVEAU_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_fb.c b/src/mesa/drivers/dri/nouveau/nv10_state_fb.c new file mode 100644 index 00000000000..05c36b4f8f5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_fb.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + case MESA_FORMAT_Z16: + return 0x10; + case MESA_FORMAT_Z24_S8: + return 0x0; + default: + assert(0); + } +} + +static void +setup_lma_buffer(GLcontext *ctx) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, LMA_DEPTH); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_framebuffer *nfb = to_nouveau_framebuffer(fb); + unsigned pitch = align(fb->Width, 128), + height = align(fb->Height, 2), + size = pitch * height; + + if (!nfb->lma_bo || nfb->lma_bo->size != size) { + nouveau_bo_ref(NULL, &nfb->lma_bo); + nouveau_bo_new(context_dev(ctx), NOUVEAU_BO_VRAM, 0, size, + &nfb->lma_bo); + } + + nouveau_bo_markl(bctx, celsius, NV17TCL_LMA_DEPTH_BUFFER_OFFSET, + nfb->lma_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_WINDOW_X, 4); + OUT_RINGf(chan, - 1792); + OUT_RINGf(chan, - 2304 + fb->Height); + OUT_RINGf(chan, fb->_DepthMaxF / 2); + OUT_RINGf(chan, 0); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_BUFFER_PITCH, 1); + OUT_RING(chan, pitch); + + BEGIN_RING(chan, celsius, NV17TCL_LMA_DEPTH_ENABLE, 1); + OUT_RING(chan, 1); +} + +void +nv10_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + unsigned rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; + unsigned rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* At least nv11 seems to get sad if we don't do this before + * swapping RTs.*/ + if (context_chipset(ctx) < 0x17) { + int i; + + for (i = 0; i < 6; i++) { + BEGIN_RING(chan, celsius, NV10TCL_NOP, 1); + OUT_RING(chan, 0); + } + } + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, celsius, NV10TCL_COLOR_OFFSET, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, celsius, NV10TCL_ZETA_OFFSET, + s->bo, 0, bo_flags); + + if (context_chipset(ctx) >= 0x17) + setup_lma_buffer(ctx); + } + + BEGIN_RING(chan, celsius, NV10TCL_RT_FORMAT, 2); + OUT_RING(chan, rt_format); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + context_dirty(ctx, VIEWPORT); + context_dirty(ctx, SCISSOR); +} + +void +nv10_emit_render_mode(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_scissor(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + int x, y, w, h; + + get_scissors(ctx->DrawBuffer, &x, &y, &w, &h); + + BEGIN_RING(chan, celsius, NV10TCL_RT_HORIZ, 2); + OUT_RING(chan, w << 16 | x); + OUT_RING(chan, h << 16 | y); +} + +void +nv10_emit_viewport(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + float a[4] = {}; + int i; + + get_viewport_translate(ctx, a); + a[0] -= 2048; + a[1] -= 2048; + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_TRANSLATE_X, 4); + for (i = 0; i < 4; i++) + OUT_RINGf(chan, a[i]); + + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, (fb->Width - 1) << 16 | 0x08000800); + BEGIN_RING(chan, celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, (fb->Height - 1) << 16 | 0x08000800); + + context_dirty(ctx, PROJECTION); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_frag.c b/src/mesa/drivers/dri/nouveau/nv10_state_frag.c new file mode 100644 index 00000000000..c1df26ecce6 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_frag.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +#define RC_IN_SHIFT_A 24 +#define RC_IN_SHIFT_B 16 +#define RC_IN_SHIFT_C 8 +#define RC_IN_SHIFT_D 0 +#define RC_IN_SHIFT_E 56 +#define RC_IN_SHIFT_F 48 +#define RC_IN_SHIFT_G 40 + +#define RC_IN_SOURCE(source) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_INPUT_##source) +#define RC_IN_USAGE(usage) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_COMPONENT_USAGE_##usage) +#define RC_IN_MAPPING(mapping) \ + ((uint64_t)NV10TCL_RC_IN_RGB_D_MAPPING_##mapping) + +#define RC_OUT_BIAS NV10TCL_RC_OUT_RGB_BIAS_BIAS_BY_NEGATIVE_ONE_HALF +#define RC_OUT_SCALE_1 NV10TCL_RC_OUT_RGB_SCALE_NONE +#define RC_OUT_SCALE_2 NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_TWO +#define RC_OUT_SCALE_4 NV10TCL_RC_OUT_RGB_SCALE_SCALE_BY_FOUR + +/* Make the combiner do: spare0_i = A_i * B_i */ +#define RC_OUT_AB NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0 +/* spare0_i = dot3(A, B) */ +#define RC_OUT_DOT_AB (NV10TCL_RC_OUT_RGB_AB_OUTPUT_SPARE0 | \ + NV10TCL_RC_OUT_RGB_AB_DOT_PRODUCT) +/* spare0_i = A_i * B_i + C_i * D_i */ +#define RC_OUT_SUM NV10TCL_RC_OUT_RGB_SUM_OUTPUT_SPARE0 + +struct combiner_state { + GLcontext *ctx; + int unit; + + /* GL state */ + GLenum mode; + GLenum *source; + GLenum *operand; + GLuint logscale; + + /* Derived HW state */ + uint64_t in; + uint32_t out; +}; + +/* Initialize a combiner_state struct from the texture unit + * context. */ +#define INIT_COMBINER(chan, ctx, rc, i) do { \ + struct gl_tex_env_combine_state *c = \ + ctx->Texture.Unit[i]._CurrentCombine; \ + (rc)->ctx = ctx; \ + (rc)->unit = i; \ + (rc)->mode = c->Mode##chan; \ + (rc)->source = c->Source##chan; \ + (rc)->operand = c->Operand##chan; \ + (rc)->logscale = c->ScaleShift##chan; \ + (rc)->in = (rc)->out = 0; \ + } while (0) + +/* Get the RC input source for the specified EXT_texture_env_combine + * argument. */ +static uint32_t +get_input_source(struct combiner_state *rc, int arg) +{ + switch (rc->source[arg]) { + case GL_TEXTURE: + return RC_IN_SOURCE(TEXTURE0) + rc->unit; + + case GL_TEXTURE0: + return RC_IN_SOURCE(TEXTURE0); + + case GL_TEXTURE1: + return RC_IN_SOURCE(TEXTURE1); + + case GL_TEXTURE2: + return RC_IN_SOURCE(TEXTURE2); + + case GL_TEXTURE3: + return RC_IN_SOURCE(TEXTURE3); + + case GL_CONSTANT: + return context_chipset(rc->ctx) >= 0x20 ? + RC_IN_SOURCE(CONSTANT_COLOR0) : + RC_IN_SOURCE(CONSTANT_COLOR0) + rc->unit; + + case GL_PRIMARY_COLOR: + return RC_IN_SOURCE(PRIMARY_COLOR); + + case GL_PREVIOUS: + return rc->unit ? RC_IN_SOURCE(SPARE0) + : RC_IN_SOURCE(PRIMARY_COLOR); + + default: + assert(0); + } +} + +/* Get the RC input mapping for the specified argument, possibly + * inverted or biased. */ +#define INVERT 0x1 +#define HALF_BIAS 0x2 + +static uint32_t +get_input_mapping(struct combiner_state *rc, int arg, int flags) +{ + int map = 0; + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + map |= RC_IN_USAGE(RGB); + break; + + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + map |= RC_IN_USAGE(ALPHA); + break; + } + + switch (rc->operand[arg]) { + case GL_SRC_COLOR: + case GL_SRC_ALPHA: + map |= (flags & INVERT ? RC_IN_MAPPING(UNSIGNED_INVERT) : + flags & HALF_BIAS ? RC_IN_MAPPING(HALF_BIAS_NORMAL) : + RC_IN_MAPPING(UNSIGNED_IDENTITY)); + break; + + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + map |= (flags & INVERT ? RC_IN_MAPPING(UNSIGNED_IDENTITY) : + flags & HALF_BIAS ? RC_IN_MAPPING(HALF_BIAS_NEGATE) : + RC_IN_MAPPING(UNSIGNED_INVERT)); + break; + } + + return map; +} + +/* Bind the RC input variable <var> to the EXT_texture_env_combine + * argument <arg>, possibly inverted or biased. */ +#define INPUT_ARG(rc, var, arg, flags) \ + (rc)->in |= (get_input_mapping(rc, arg, flags) | \ + get_input_source(rc, arg)) << RC_IN_SHIFT_##var + +/* Bind the RC input variable <var> to the RC source <src>. */ +#define INPUT_SRC(rc, var, src, chan) \ + (rc)->in |= (RC_IN_SOURCE(src) | \ + RC_IN_USAGE(chan)) << RC_IN_SHIFT_##var + +/* Bind the RC input variable <var> to a constant +/-1 */ +#define INPUT_ONE(rc, var, flags) \ + (rc)->in |= (RC_IN_SOURCE(ZERO) | \ + (flags & INVERT ? RC_IN_MAPPING(EXPAND_NORMAL) : \ + RC_IN_MAPPING(UNSIGNED_INVERT))) << RC_IN_SHIFT_##var + +static void +setup_combiner(struct combiner_state *rc) +{ + switch (rc->mode) { + case GL_REPLACE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + + rc->out = RC_OUT_AB; + break; + + case GL_MODULATE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ARG(rc, B, 1, 0); + + rc->out = RC_OUT_AB; + break; + + case GL_ADD: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, 0); + + rc->out = RC_OUT_SUM; + break; + + case GL_ADD_SIGNED: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, 0); + + rc->out = RC_OUT_SUM | RC_OUT_BIAS; + break; + + case GL_INTERPOLATE: + INPUT_ARG(rc, A, 0, 0); + INPUT_ARG(rc, B, 2, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ARG(rc, D, 2, INVERT); + + rc->out = RC_OUT_SUM; + break; + + case GL_SUBTRACT: + INPUT_ARG(rc, A, 0, 0); + INPUT_ONE(rc, B, 0); + INPUT_ARG(rc, C, 1, 0); + INPUT_ONE(rc, D, INVERT); + + rc->out = RC_OUT_SUM; + break; + + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + INPUT_ARG(rc, A, 0, HALF_BIAS); + INPUT_ARG(rc, B, 1, HALF_BIAS); + + rc->out = RC_OUT_DOT_AB | RC_OUT_SCALE_4; + + assert(!rc->logscale); + break; + + default: + assert(0); + } + + switch (rc->logscale) { + case 0: + rc->out |= RC_OUT_SCALE_1; + break; + case 1: + rc->out |= RC_OUT_SCALE_2; + break; + case 2: + rc->out |= RC_OUT_SCALE_4; + break; + default: + assert(0); + } +} + +/* Write the register combiner state out to the hardware. */ +static void +nv10_load_combiner(GLcontext *ctx, int i, struct combiner_state *rc_a, + struct combiner_state *rc_c, uint32_t rc_const) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + /* Enable the combiners we're going to need. */ + if (i == 1) { + if (rc_c->out || rc_a->out) + rc_c->out |= 0x5 << 27; + else + rc_c->out |= 0x3 << 27; + } + + BEGIN_RING(chan, celsius, NV10TCL_RC_IN_ALPHA(i), 1); + OUT_RING(chan, rc_a->in); + BEGIN_RING(chan, celsius, NV10TCL_RC_IN_RGB(i), 1); + OUT_RING(chan, rc_c->in); + BEGIN_RING(chan, celsius, NV10TCL_RC_COLOR(i), 1); + OUT_RING(chan, rc_const); + BEGIN_RING(chan, celsius, NV10TCL_RC_OUT_ALPHA(i), 1); + OUT_RING(chan, rc_a->out); + BEGIN_RING(chan, celsius, NV10TCL_RC_OUT_RGB(i), 1); + OUT_RING(chan, rc_c->out); +} + +static void +nv10_load_final(GLcontext *ctx, struct combiner_state *rc, int n) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_RC_FINAL0, 2); + OUT_RING(chan, rc->in); + OUT_RING(chan, rc->in >> 32); +} + +static void +nv20_load_combiner(GLcontext *ctx, int i, struct combiner_state *rc_a, + struct combiner_state *rc_c, uint32_t rc_const) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_ALPHA(i), 1); + OUT_RING(chan, rc_a->in); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_ALPHA(i), 1); + OUT_RING(chan, rc_a->out); + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_RGB(i), 1); + OUT_RING(chan, rc_c->in); + BEGIN_RING(chan, kelvin, NV20TCL_RC_OUT_RGB(i), 1); + OUT_RING(chan, rc_c->out); + BEGIN_RING(chan, kelvin, NV20TCL_RC_CONSTANT_COLOR0(i), 1); + OUT_RING(chan, rc_const); +} + +static void +nv20_load_final(GLcontext *ctx, struct combiner_state *rc, int n) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_FINAL0, 2); + OUT_RING(chan, rc->in); + OUT_RING(chan, rc->in >> 32); + + BEGIN_RING(chan, kelvin, NV20TCL_RC_ENABLE, 1); + OUT_RING(chan, n); +} + +void +nv10_emit_tex_env(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_ENV0; + struct combiner_state rc_a, rc_c; + uint32_t rc_const; + + /* Compute the new combiner state. */ + if (ctx->Texture.Unit[i]._ReallyEnabled) { + INIT_COMBINER(RGB, ctx, &rc_c, i); + + if (rc_c.mode == GL_DOT3_RGBA) + rc_a = rc_c; + else + INIT_COMBINER(A, ctx, &rc_a, i); + + setup_combiner(&rc_c); + setup_combiner(&rc_a); + + rc_const = pack_rgba_f(MESA_FORMAT_ARGB8888, + ctx->Texture.Unit[i].EnvColor); + + } else { + rc_a.in = rc_a.out = rc_c.in = rc_c.out = rc_const = 0; + } + + if (context_chipset(ctx) >= 0x20) + nv20_load_combiner(ctx, i, &rc_a, &rc_c, rc_const); + else + nv10_load_combiner(ctx, i, &rc_a, &rc_c, rc_const); + + context_dirty(ctx, FRAG); +} + +void +nv10_emit_frag(GLcontext *ctx, int emit) +{ + struct combiner_state rc = {}; + int n = log2i(ctx->Texture._EnabledUnits) + 1; + + /* + * The final fragment value equation is something like: + * x_i = A_i * B_i + (1 - A_i) * C_i + D_i + * x_alpha = G_alpha + * where D_i = E_i * F_i, i one of {red, green, blue}. + */ + if (ctx->Fog.ColorSumEnabled || ctx->Light.Enabled) { + INPUT_SRC(&rc, D, E_TIMES_F, RGB); + INPUT_SRC(&rc, F, SECONDARY_COLOR, RGB); + } + + if (ctx->Fog.Enabled) { + INPUT_SRC(&rc, A, FOG, ALPHA); + INPUT_SRC(&rc, C, FOG, RGB); + INPUT_SRC(&rc, E, FOG, ALPHA); + } else { + INPUT_ONE(&rc, A, 0); + INPUT_ONE(&rc, C, 0); + INPUT_ONE(&rc, E, 0); + } + + if (ctx->Texture._EnabledUnits) { + INPUT_SRC(&rc, B, SPARE0, RGB); + INPUT_SRC(&rc, G, SPARE0, ALPHA); + } else { + INPUT_SRC(&rc, B, PRIMARY_COLOR, RGB); + INPUT_SRC(&rc, G, PRIMARY_COLOR, ALPHA); + } + + if (context_chipset(ctx) >= 0x20) + nv20_load_final(ctx, &rc, n); + else + nv10_load_final(ctx, &rc, n); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c b/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c new file mode 100644 index 00000000000..deddca10118 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_polygon.c @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_cull_face(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLenum mode = ctx->Polygon.CullFaceMode; + + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE_ENABLE, 1); + OUT_RING(chan, ctx->Polygon.CullFlag ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_CULL_FACE, 1); + OUT_RING(chan, (mode == GL_FRONT ? NV10TCL_CULL_FACE_FRONT : + mode == GL_BACK ? NV10TCL_CULL_FACE_BACK : + NV10TCL_CULL_FACE_FRONT_AND_BACK)); +} + +void +nv10_emit_front_face(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_FRONT_FACE, 1); + OUT_RING(chan, ctx->Polygon.FrontFace == GL_CW ? + NV10TCL_FRONT_FACE_CW : NV10TCL_FRONT_FACE_CCW); +} + +void +nv10_emit_line_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLboolean smooth = ctx->Line.SmoothFlag && + ctx->Hint.LineSmooth == GL_NICEST; + + BEGIN_RING(chan, celsius, NV10TCL_LINE_WIDTH, 1); + OUT_RING(chan, MAX2(smooth ? 0 : 1, + ctx->Line.Width) * 8); + BEGIN_RING(chan, celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); + OUT_RING(chan, smooth ? 1 : 0); +} + +void +nv10_emit_line_stipple(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_point_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POINT_SIZE, 1); + OUT_RING(chan, (uint32_t)(ctx->Point.Size * 8)); + + BEGIN_RING(chan, celsius, NV10TCL_POINT_SMOOTH_ENABLE, 1); + OUT_RING(chan, ctx->Point.SmoothFlag ? 1 : 0); +} + +void +nv10_emit_polygon_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); + OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.FrontMode)); + OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.BackMode)); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); + OUT_RING(chan, ctx->Polygon.SmoothFlag ? 1 : 0); +} + +void +nv10_emit_polygon_offset(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); + OUT_RING(chan, ctx->Polygon.OffsetPoint ? 1 : 0); + OUT_RING(chan, ctx->Polygon.OffsetLine ? 1 : 0); + OUT_RING(chan, ctx->Polygon.OffsetFill ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); + OUT_RINGf(chan, ctx->Polygon.OffsetFactor); + OUT_RINGf(chan, ctx->Polygon.OffsetUnits); +} + +void +nv10_emit_polygon_stipple(GLcontext *ctx, int emit) +{ +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_raster.c b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c new file mode 100644 index 00000000000..68882ef05f2 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_raster.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_alpha_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); + OUT_RING(chan, ctx->Color.AlphaEnabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); + OUT_RING(chan, nvgl_comparison_op(ctx->Color.AlphaFunc)); + OUT_RING(chan, FLOAT_TO_UBYTE(ctx->Color.AlphaRef)); +} + +void +nv10_emit_blend_color(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_COLOR, 1); + OUT_RING(chan, FLOAT_TO_UBYTE(ctx->Color.BlendColor[3]) << 24 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[0]) << 16 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[1]) << 8 | + FLOAT_TO_UBYTE(ctx->Color.BlendColor[2]) << 0); +} + +void +nv10_emit_blend_equation(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); + OUT_RING(chan, ctx->Color.BlendEnabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_EQUATION, 1); + OUT_RING(chan, nvgl_blend_eqn(ctx->Color.BlendEquationRGB)); +} + +void +nv10_emit_blend_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_BLEND_FUNC_SRC, 2); + OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendSrcRGB)); + OUT_RING(chan, nvgl_blend_func(ctx->Color.BlendDstRGB)); +} + +void +nv10_emit_color_mask(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MASK, 1); + OUT_RING(chan, ((ctx->Color.ColorMask[0][3] ? 1 << 24 : 0) | + (ctx->Color.ColorMask[0][0] ? 1 << 16 : 0) | + (ctx->Color.ColorMask[0][1] ? 1 << 8 : 0) | + (ctx->Color.ColorMask[0][2] ? 1 << 0 : 0))); +} + +void +nv10_emit_depth(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); + OUT_RING(chan, ctx->Depth.Test ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); + OUT_RING(chan, ctx->Depth.Mask ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_DEPTH_FUNC, 1); + OUT_RING(chan, nvgl_comparison_op(ctx->Depth.Func)); +} + +void +nv10_emit_dither(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_DITHER_ENABLE, 1); + OUT_RING(chan, ctx->Color.DitherFlag ? 1 : 0); +} + +void +nv10_emit_index_mask(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_logic_opcode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + assert(!ctx->Color.ColorLogicOpEnabled + || context_chipset(ctx) >= 0x11); + + BEGIN_RING(chan, celsius, NV11TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING(chan, ctx->Color.ColorLogicOpEnabled ? 1 : 0); + OUT_RING(chan, nvgl_logicop_func(ctx->Color.LogicOp)); +} + +void +nv10_emit_shade_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_SHADE_MODEL, 1); + OUT_RING(chan, ctx->Light.ShadeModel == GL_SMOOTH ? + NV10TCL_SHADE_MODEL_SMOOTH : NV10TCL_SHADE_MODEL_FLAT); +} + +void +nv10_emit_stencil_func(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_ENABLE, 1); + OUT_RING(chan, ctx->Stencil.Enabled ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_FUNC_FUNC, 3); + OUT_RING(chan, nvgl_comparison_op(ctx->Stencil.Function[0])); + OUT_RING(chan, ctx->Stencil.Ref[0]); + OUT_RING(chan, ctx->Stencil.ValueMask[0]); +} + +void +nv10_emit_stencil_mask(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_MASK, 1); + OUT_RING(chan, ctx->Stencil.WriteMask[0]); +} + +void +nv10_emit_stencil_op(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + + BEGIN_RING(chan, celsius, NV10TCL_STENCIL_OP_FAIL, 3); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.FailFunc[0])); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.ZFailFunc[0])); + OUT_RING(chan, nvgl_stencil_op(ctx->Stencil.ZPassFunc[0])); +} diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tex.c b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c new file mode 100644 index 00000000000..e5d4f3d18d8 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tex.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_texture.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv10_driver.h" + +void +nv10_emit_tex_gen(GLcontext *ctx, int emit) +{ +} + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return NV10TCL_TX_FORMAT_FORMAT_A8R8G8B8; + + case MESA_FORMAT_ARGB1555: + return NV10TCL_TX_FORMAT_FORMAT_A1R5G5B5; + + case MESA_FORMAT_ARGB4444: + return NV10TCL_TX_FORMAT_FORMAT_A4R4G4B4; + + case MESA_FORMAT_RGB565: + return NV10TCL_TX_FORMAT_FORMAT_R5G6B5; + + case MESA_FORMAT_A8: + return NV10TCL_TX_FORMAT_FORMAT_A8; + + case MESA_FORMAT_L8: + return NV10TCL_TX_FORMAT_FORMAT_L8; + + case MESA_FORMAT_CI8: + return NV10TCL_TX_FORMAT_FORMAT_INDEX8; + + default: + assert(0); + } +} + +void +nv10_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct gl_texture_object *t; + struct nouveau_surface *s; + struct gl_texture_image *ti; + uint32_t tx_format, tx_filter, tx_enable; + + if (!ctx->Texture.Unit[i]._ReallyEnabled) { + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(i), 1); + OUT_RING(chan, 0); + return; + } + + t = ctx->Texture.Unit[i]._Current; + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + ti = t->Image[0][t->BaseLevel]; + + nouveau_texture_validate(ctx, t); + + /* Recompute the texturing registers. */ + tx_format = nvgl_wrap_mode(t->WrapT) << 28 + | nvgl_wrap_mode(t->WrapS) << 24 + | ti->HeightLog2 << 20 + | ti->WidthLog2 << 16 + | get_tex_format(ti) + | 5 << 4 | 1 << 12; + + tx_filter = nvgl_filter_mode(t->MagFilter) << 28 + | nvgl_filter_mode(t->MinFilter) << 24; + + tx_enable = NV10TCL_TX_ENABLE_ENABLE + | log2i(t->MaxAnisotropy) << 4; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + int lod_min = t->MinLod; + int lod_max = MIN2(t->MaxLod, t->_MaxLambda); + int lod_bias = t->LodBias + + ctx->Texture.Unit[i].LodBias; + + lod_max = CLAMP(lod_max, 0, 15); + lod_min = CLAMP(lod_min, 0, 15); + lod_bias = CLAMP(lod_bias, 0, 15); + + tx_format |= NV10TCL_TX_FORMAT_MIPMAP; + tx_filter |= lod_bias << 8; + tx_enable |= lod_min << 26 + | lod_max << 14; + } + + /* Write it to the hardware. */ + nouveau_bo_mark(bctx, celsius, NV10TCL_TX_FORMAT(i), + s->bo, tx_format, 0, + NV10TCL_TX_FORMAT_DMA0, + NV10TCL_TX_FORMAT_DMA1, + bo_flags | NOUVEAU_BO_OR); + + nouveau_bo_markl(bctx, celsius, NV10TCL_TX_OFFSET(i), + s->bo, 0, bo_flags); + + BEGIN_RING(chan, celsius, NV10TCL_TX_FILTER(i), 1); + OUT_RING(chan, tx_filter); + + BEGIN_RING(chan, celsius, NV10TCL_TX_ENABLE(i), 1); + OUT_RING(chan, tx_enable); +} + diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c new file mode 100644 index 00000000000..6db14d83b83 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c @@ -0,0 +1,514 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" + +void +nv10_emit_clip_plane(GLcontext *ctx, int emit) +{ +} + +static inline unsigned +get_material_bitmask(unsigned m) +{ + unsigned ret = 0; + + if (m & MAT_BIT_FRONT_EMISSION) + ret |= NV10TCL_COLOR_MATERIAL_EMISSION; + if (m & MAT_BIT_FRONT_AMBIENT) + ret |= NV10TCL_COLOR_MATERIAL_AMBIENT; + if (m & MAT_BIT_FRONT_DIFFUSE) + ret |= NV10TCL_COLOR_MATERIAL_DIFFUSE; + if (m & MAT_BIT_FRONT_SPECULAR) + ret |= NV10TCL_COLOR_MATERIAL_SPECULAR; + + return ret; +} + +void +nv10_emit_color_material(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + unsigned mask = get_material_bitmask(ctx->Light.ColorMaterialBitmask); + + BEGIN_RING(chan, celsius, NV10TCL_COLOR_MATERIAL, 1); + OUT_RING(chan, ctx->Light.ColorMaterialEnabled ? mask : 0); +} + +static unsigned +get_fog_mode(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV10TCL_FOG_MODE_LINEAR; + case GL_EXP: + return NV10TCL_FOG_MODE_EXP; + case GL_EXP2: + return NV10TCL_FOG_MODE_EXP2; + default: + assert(0); + } +} + +static unsigned +get_fog_source(unsigned source) +{ + switch (source) { + case GL_FOG_COORDINATE_EXT: + return NV10TCL_FOG_COORD_FOG; + case GL_FRAGMENT_DEPTH_EXT: + return NV10TCL_FOG_COORD_DIST_ORTHOGONAL_ABS; + default: + assert(0); + } +} + +void +nv10_get_fog_coeff(GLcontext *ctx, float k[3]) +{ + struct gl_fog_attrib *f = &ctx->Fog; + + switch (f->Mode) { + case GL_LINEAR: + k[0] = 2 + f->Start / (f->End - f->Start); + k[1] = -1 / (f->End - f->Start); + break; + + case GL_EXP: + k[0] = 1.5; + k[1] = -0.09 * f->Density; + break; + + case GL_EXP2: + k[0] = 1.5; + k[1] = -0.21 * f->Density; + break; + + default: + assert(0); + } + + k[2] = 0; +} + +void +nv10_emit_fog(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_fog_attrib *f = &ctx->Fog; + unsigned source = nctx->fallback == HWTNL ? + f->FogCoordinateSource : GL_FOG_COORDINATE_EXT; + float k[3]; + + nv10_get_fog_coeff(ctx, k); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_MODE, 4); + OUT_RING(chan, get_fog_mode(f->Mode)); + OUT_RING(chan, get_fog_source(source)); + OUT_RING(chan, f->Enabled ? 1 : 0); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color)); + + BEGIN_RING(chan, celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + + context_dirty(ctx, FRAG); +} + +static inline unsigned +get_light_mode(struct gl_light *l) +{ + if (l->Enabled) { + if (l->_Flags & LIGHT_SPOT) + return NV10TCL_ENABLED_LIGHTS_0_DIRECTIONAL; + else if (l->_Flags & LIGHT_POSITIONAL) + return NV10TCL_ENABLED_LIGHTS_0_POSITIONAL; + else + return NV10TCL_ENABLED_LIGHTS_0_NONPOSITIONAL; + } else { + return NV10TCL_ENABLED_LIGHTS_0_DISABLED; + } +} + +void +nv10_emit_light_enable(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + uint32_t en_lights = 0; + int i; + + if (nctx->fallback != HWTNL) { + BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1); + OUT_RING(chan, 0); + return; + } + + for (i = 0; i < MAX_LIGHTS; i++) + en_lights |= get_light_mode(&ctx->Light.Light[i]) << 2 * i; + + BEGIN_RING(chan, celsius, NV10TCL_ENABLED_LIGHTS, 1); + OUT_RING(chan, en_lights); + BEGIN_RING(chan, celsius, NV10TCL_LIGHTING_ENABLE, 1); + OUT_RING(chan, ctx->Light.Enabled ? 1 : 0); + BEGIN_RING(chan, celsius, NV10TCL_NORMALIZE_ENABLE, 1); + OUT_RING(chan, ctx->Transform.Normalize ? 1 : 0); +} + +void +nv10_emit_light_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_lightmodel *m = &ctx->Light.Model; + + BEGIN_RING(chan, celsius, NV10TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? 1 : 0); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL, 1); + OUT_RING(chan, ((m->LocalViewer ? + NV10TCL_LIGHT_MODEL_LOCAL_VIEWER : 0) | + (m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? + NV10TCL_LIGHT_MODEL_SEPARATE_SPECULAR : 0))); +} + +static float +get_shine(const float p[], float x) +{ + const int n = 15; + const float *y = &p[1]; + float f = (n - 1) * (1 - 1 / (1 + p[0] * x)) + / (1 - 1 / (1 + p[0] * 1024)); + int i = f; + + /* Linear interpolation in f-space (Faster and somewhat more + * accurate than x-space). */ + if (x == 0) + return y[0]; + else if (i > n - 2) + return y[n - 1]; + else + return y[i] + (y[i + 1] - y[i]) * (f - i); +} + +static const float nv10_spot_params[2][16] = { + { 0.02, -3.80e-05, -1.77, -2.41, -2.71, -2.88, -2.98, -3.06, + -3.11, -3.17, -3.23, -3.28, -3.37, -3.47, -3.83, -5.11 }, + { 0.02, -0.01, 1.77, 2.39, 2.70, 2.87, 2.98, 3.06, + 3.10, 3.16, 3.23, 3.27, 3.37, 3.47, 3.83, 5.11 }, +}; + +void +nv10_get_spot_coeff(struct gl_light *l, float k[7]) +{ + float e = l->SpotExponent; + float a0, b0, a1, a2, b2, a3; + + if (e > 0) + a0 = -1 - 5.36e-3 / sqrt(e); + else + a0 = -1; + b0 = 1 / (1 + 0.273 * e); + + a1 = get_shine(nv10_spot_params[0], e); + + a2 = get_shine(nv10_spot_params[1], e); + b2 = 1 / (1 + 0.273 * e); + + a3 = 0.9 + 0.278 * e; + + if (l->SpotCutoff > 0) { + float cutoff = MAX2(a3, 1 / (1 - l->_CosCutoff)); + + k[0] = MAX2(0, a0 + b0 * cutoff); + k[1] = a1; + k[2] = a2 + b2 * cutoff; + k[3] = - cutoff * l->_NormSpotDirection[0]; + k[4] = - cutoff * l->_NormSpotDirection[1]; + k[5] = - cutoff * l->_NormSpotDirection[2]; + k[6] = 1 - cutoff; + + } else { + k[0] = b0; + k[1] = a1; + k[2] = a2 + b2; + k[3] = - l->_NormSpotDirection[0]; + k[4] = - l->_NormSpotDirection[1]; + k[5] = - l->_NormSpotDirection[2]; + k[6] = -1; + } +} + +void +nv10_emit_light_source(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_light *l = &ctx->Light.Light[i]; + + if (l->_Flags & LIGHT_POSITIONAL) { + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_POSITION_X(i), 3); + OUT_RINGf(chan, l->_Position[0]); + OUT_RINGf(chan, l->_Position[1]); + OUT_RINGf(chan, l->_Position[2]); + + BEGIN_RING(chan, celsius, + NV10TCL_LIGHT_ATTENUATION_CONSTANT(i), 3); + OUT_RINGf(chan, l->ConstantAttenuation); + OUT_RINGf(chan, l->LinearAttenuation); + OUT_RINGf(chan, l->QuadraticAttenuation); + + } else { + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIRECTION_X(i), 3); + OUT_RINGf(chan, l->_VP_inf_norm[0]); + OUT_RINGf(chan, l->_VP_inf_norm[1]); + OUT_RINGf(chan, l->_VP_inf_norm[2]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_HALF_VECTOR_X(i), 3); + OUT_RINGf(chan, l->_h_inf_norm[0]); + OUT_RINGf(chan, l->_h_inf_norm[1]); + OUT_RINGf(chan, l->_h_inf_norm[2]); + } + + if (l->_Flags & LIGHT_SPOT) { + float k[7]; + + nv10_get_spot_coeff(l, k); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPOT_CUTOFF_A(i), 7); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); + OUT_RINGf(chan, k[6]); + } +} + +#define USE_COLOR_MATERIAL(attr) \ + (ctx->Light.ColorMaterialEnabled && \ + ctx->Light.ColorMaterialBitmask & (1 << MAT_ATTRIB_FRONT_##attr)) + +void +nv10_emit_material_ambient(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + float c_scene[3], c_factor[3]; + struct gl_light *l; + + if (USE_COLOR_MATERIAL(AMBIENT)) { + COPY_3V(c_scene, ctx->Light.Model.Ambient); + COPY_3V(c_factor, mat[MAT_ATTRIB_FRONT_EMISSION]); + + } else if (USE_COLOR_MATERIAL(EMISSION)) { + SCALE_3V(c_scene, mat[MAT_ATTRIB_FRONT_AMBIENT], + ctx->Light.Model.Ambient); + ZERO_3V(c_factor); + + } else { + COPY_3V(c_scene, ctx->Light._BaseColor[0]); + ZERO_3V(c_factor); + } + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_MODEL_AMBIENT_R, 3); + OUT_RINGf(chan, c_scene[0]); + OUT_RINGf(chan, c_scene[1]); + OUT_RINGf(chan, c_scene[2]); + + if (ctx->Light.ColorMaterialEnabled) { + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_R, 3); + OUT_RINGf(chan, c_factor[0]); + OUT_RINGf(chan, c_factor[1]); + OUT_RINGf(chan, c_factor[2]); + } + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ? + l->Ambient : + l->_MatAmbient[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_AMBIENT_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv10_emit_material_diffuse(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLfloat (*mat)[4] = ctx->Light.Material.Attrib; + struct gl_light *l; + + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_FACTOR_A, 1); + OUT_RINGf(chan, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]); + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ? + l->Diffuse : + l->_MatDiffuse[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_DIFFUSE_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv10_emit_material_specular(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + struct gl_light *l; + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ? + l->Specular : + l->_MatSpecular[0]); + + BEGIN_RING(chan, celsius, NV10TCL_LIGHT_SPECULAR_R(i), 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +static const float nv10_shininess_param[6][16] = { + { 0.70, 0.00, 0.06, 0.06, 0.05, 0.04, 0.02, 0.00, + -0.06, -0.13, -0.24, -0.36, -0.51, -0.66, -0.82, -1.00 }, + { 0.01, 1.00, -2.29, -2.77, -2.96, -3.06, -3.12, -3.18, + -3.24, -3.29, -3.36, -3.43, -3.51, -3.75, -4.33, -5.11 }, + { 0.02, 0.00, 2.28, 2.75, 2.94, 3.04, 3.1, 3.15, + 3.18, 3.22, 3.27, 3.32, 3.39, 3.48, 3.84, 5.11 }, + { 0.70, 0.00, 0.05, 0.06, 0.06, 0.06, 0.05, 0.04, + 0.02, 0.01, -0.03, -0.12, -0.25, -0.43, -0.68, -0.99 }, + { 0.01, 1.00, -1.61, -2.35, -2.67, -2.84, -2.96, -3.05, + -3.08, -3.14, -3.2, -3.26, -3.32, -3.42, -3.54, -4.21 }, + { 0.01, 0.00, 2.25, 2.73, 2.92, 3.03, 3.09, 3.15, + 3.16, 3.21, 3.25, 3.29, 3.35, 3.43, 3.56, 4.22 }, +}; + +void +nv10_get_shininess_coeff(float s, float k[6]) +{ + int i; + + for (i = 0; i < 6; i++) + k[i] = get_shine(nv10_shininess_param[i], s); +} + +void +nv10_emit_material_shininess(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + float k[6]; + + nv10_get_shininess_coeff( + CLAMP(mat[MAT_ATTRIB_FRONT_SHININESS][0], 0, 1024), + k); + + BEGIN_RING(chan, celsius, NV10TCL_MATERIAL_SHININESS(0), 6); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); +} + +void +nv10_emit_modelview(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLmatrix *m = ctx->ModelviewMatrixStack.Top; + + if (nctx->fallback != HWTNL) + return; + + if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) { + BEGIN_RING(chan, celsius, NV10TCL_MODELVIEW0_MATRIX(0), 16); + OUT_RINGm(chan, m->m); + } + + if (ctx->Light.Enabled) { + int i, j; + + BEGIN_RING(chan, celsius, + NV10TCL_INVERSE_MODELVIEW0_MATRIX(0), 12); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m->inv[4*i + j]); + } +} + +void +nv10_emit_point_parameter(GLcontext *ctx, int emit) +{ +} + +void +nv10_emit_projection(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *celsius = context_eng3d(ctx); + GLmatrix m; + + _math_matrix_ctr(&m); + get_viewport_scale(ctx, m.m); + + if (nctx->fallback == HWTNL) + _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix); + + BEGIN_RING(chan, celsius, NV10TCL_PROJECTION_MATRIX(0), 16); + OUT_RINGm(chan, m.m); + + _math_matrix_dtr(&m); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_context.c new file mode 100644 index 00000000000..698b83431be --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_context.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nv20_driver.h" + +GLcontext * +nv20_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx) +{ + struct nouveau_context *nctx; + GLcontext *ctx; + + nctx = CALLOC_STRUCT(nouveau_context); + if (!nctx) + return NULL; + + ctx = &nctx->base; + nouveau_context_init(ctx, screen, visual, share_ctx); + + ctx->Const.MaxTextureCoordUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureImageUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureUnits = NV20_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = 8; + ctx->Const.MaxTextureLodBias = 15; + + nv20_render_init(ctx); + + return ctx; +} + +void +nv20_context_destroy(GLcontext *ctx) +{ + nv20_render_destroy(ctx); + FREE(ctx); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_driver.h b/src/mesa/drivers/dri/nouveau/nv20_driver.h new file mode 100644 index 00000000000..2de18ee4af1 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_driver.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. + * + */ + +#ifndef __NV20_DRIVER_H__ +#define __NV20_DRIVER_H__ + +enum { + NOUVEAU_STATE_TEX_SHADER = NUM_NOUVEAU_STATE, + NUM_NV20_STATE +}; + +#define NV20_TEXTURE_UNITS 4 + +/* nv20_screen.c */ +GLboolean +nv20_screen_init(struct nouveau_screen *screen); + +/* nv20_context.c */ +GLcontext * +nv20_context_create(struct nouveau_screen *screen, const GLvisual *visual, + GLcontext *share_ctx); + +void +nv20_context_destroy(GLcontext *ctx); + +/* nv20_render.c */ +void +nv20_render_init(GLcontext *ctx); + +void +nv20_render_destroy(GLcontext *ctx); + +/* nv20_state_fb.c */ +void +nv20_emit_framebuffer(GLcontext *ctx, int emit); + +void +nv20_emit_viewport(GLcontext *ctx, int emit); + +/* nv20_state_polygon.c */ +void +nv20_emit_point_mode(GLcontext *ctx, int emit); + +/* nv20_state_raster.c */ +void +nv20_emit_logic_opcode(GLcontext *ctx, int emit); + +/* nv20_state_tex.c */ +void +nv20_emit_tex_obj(GLcontext *ctx, int emit); + +void +nv20_emit_tex_shader(GLcontext *ctx, int emit); + +/* nv20_state_tnl.c */ +void +nv20_emit_clip_plane(GLcontext *ctx, int emit); + +void +nv20_emit_color_material(GLcontext *ctx, int emit); + +void +nv20_emit_fog(GLcontext *ctx, int emit); + +void +nv20_emit_light_model(GLcontext *ctx, int emit); + +void +nv20_emit_light_source(GLcontext *ctx, int emit); + +void +nv20_emit_material_ambient(GLcontext *ctx, int emit); + +void +nv20_emit_material_diffuse(GLcontext *ctx, int emit); + +void +nv20_emit_material_specular(GLcontext *ctx, int emit); + +void +nv20_emit_material_shininess(GLcontext *ctx, int emit); + +void +nv20_emit_modelview(GLcontext *ctx, int emit); + +void +nv20_emit_projection(GLcontext *ctx, int emit); + +#endif diff --git a/src/mesa/drivers/dri/nouveau/nv20_render.c b/src/mesa/drivers/dri/nouveau/nv20_render.c new file mode 100644 index 00000000000..a696ac107f5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_render.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +#define NUM_VERTEX_ATTRS 16 + +static void +nv20_emit_material(GLcontext *ctx, struct nouveau_array_state *a, + const void *v); + +/* Vertex attribute format. */ +static struct nouveau_attr_info nv20_vertex_attrs[VERT_ATTRIB_MAX] = { + [VERT_ATTRIB_POS] = { + .vbo_index = 0, + .imm_method = NV20TCL_VERTEX_POS_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_NORMAL] = { + .vbo_index = 2, + .imm_method = NV20TCL_VERTEX_NOR_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_COLOR0] = { + .vbo_index = 3, + .imm_method = NV20TCL_VERTEX_COL_4F_X, + .imm_fields = 4, + }, + [VERT_ATTRIB_COLOR1] = { + .vbo_index = 4, + .imm_method = NV20TCL_VERTEX_COL2_3F_X, + .imm_fields = 3, + }, + [VERT_ATTRIB_FOG] = { + .vbo_index = 5, + .imm_method = NV20TCL_VERTEX_FOG_1F, + .imm_fields = 1, + }, + [VERT_ATTRIB_TEX0] = { + .vbo_index = 9, + .imm_method = NV20TCL_VERTEX_TX0_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX1] = { + .vbo_index = 10, + .imm_method = NV20TCL_VERTEX_TX1_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX2] = { + .vbo_index = 11, + .imm_method = NV20TCL_VERTEX_TX2_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_TEX3] = { + .vbo_index = 12, + .imm_method = NV20TCL_VERTEX_TX3_4F_S, + .imm_fields = 4, + }, + [VERT_ATTRIB_GENERIC0] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC1] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC2] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC3] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC4] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC5] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC6] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC7] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC8] = { + .emit = nv20_emit_material, + }, + [VERT_ATTRIB_GENERIC9] = { + .emit = nv20_emit_material, + }, +}; + +static int +get_hw_format(int type) +{ + switch (type) { + case GL_FLOAT: + return NV20TCL_VTXFMT_TYPE_FLOAT; + case GL_UNSIGNED_SHORT: + return NV20TCL_VTXFMT_TYPE_USHORT; + case GL_UNSIGNED_BYTE: + return NV20TCL_VTXFMT_TYPE_UBYTE; + default: + assert(0); + } +} + +static void +nv20_render_set_format(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + int i, hw_format; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + hw_format = a->stride << 8 | + a->fields << 4 | + get_hw_format(a->type); + + } else { + /* Unused attribute. */ + hw_format = NV10TCL_VTXFMT_TYPE_FLOAT; + } + + BEGIN_RING(chan, kelvin, NV20TCL_VTXFMT(i), 1); + OUT_RING(chan, hw_format); + } +} + +static void +nv20_render_bind_vertices(GLcontext *ctx) +{ + struct nouveau_render_state *render = to_render_state(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, VERTEX); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + int i; + + for (i = 0; i < NUM_VERTEX_ATTRS; i++) { + int attr = render->map[i]; + + if (attr >= 0) { + struct nouveau_array_state *a = &render->attrs[attr]; + + nouveau_bo_mark(bctx, kelvin, + NV20TCL_VTXBUF_ADDRESS(i), + a->bo, a->offset, 0, + 0, NV20TCL_VTXBUF_ADDRESS_DMA1, + NOUVEAU_BO_LOW | NOUVEAU_BO_OR | + NOUVEAU_BO_GART | NOUVEAU_BO_RD); + } + } + + BEGIN_RING(chan, kelvin, NV20TCL_VTX_CACHE_INVALIDATE, 1); + OUT_RING(chan, 0); +} + +/* Vertex array rendering defs. */ +#define RENDER_LOCALS(ctx) \ + struct nouveau_grobj *kelvin = context_eng3d(ctx) + +#define BATCH_BEGIN(prim) \ + BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); \ + OUT_RING(chan, prim); +#define BATCH_END() \ + BEGIN_RING(chan, kelvin, NV20TCL_VERTEX_BEGIN_END, 1); \ + OUT_RING(chan, 0); + +#define MAX_PACKET 0x400 + +#define MAX_OUT_L 0x100 +#define BATCH_PACKET_L(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_VERTEX_BATCH, n); +#define BATCH_OUT_L(i, n) \ + OUT_RING(chan, ((n) - 1) << 24 | (i)); + +#define MAX_OUT_I16 0x2 +#define BATCH_PACKET_I16(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_ELEMENT_U16, n); +#define BATCH_OUT_I16(i0, i1) \ + OUT_RING(chan, (i1) << 16 | (i0)); + +#define MAX_OUT_I32 0x1 +#define BATCH_PACKET_I32(n) \ + BEGIN_RING_NI(chan, kelvin, NV20TCL_VB_ELEMENT_U32, n); +#define BATCH_OUT_I32(i) \ + OUT_RING(chan, i); + +#define IMM_PACKET(m, n) \ + BEGIN_RING(chan, kelvin, m, n); +#define IMM_OUT(x) \ + OUT_RINGf(chan, x); + +#define TAG(x) nv20_##x +#include "nouveau_render_t.c" diff --git a/src/gallium/drivers/nv20/nv20_context.c b/src/mesa/drivers/dri/nouveau/nv20_screen.c index f0c0d8a4b3b..1d29fc9976c 100644 --- a/src/gallium/drivers/nv20/nv20_context.c +++ b/src/mesa/drivers/dri/nouveau/nv20_screen.c @@ -1,65 +1,69 @@ -#include "draw/draw_context.h" -#include "pipe/p_defines.h" -#include "util/u_simple_screen.h" - -#include "nv20_context.h" -#include "nv20_screen.h" +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_screen.h" +#include "nouveau_class.h" +#include "nv04_driver.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +static const struct nouveau_driver nv20_driver; static void -nv20_flush(struct pipe_context *pipe, unsigned flags, - struct pipe_fence_handle **fence) +nv20_hwctx_init(struct nouveau_screen *screen) { - struct nv20_context *nv20 = nv20_context(pipe); - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - - draw_flush(nv20->draw); - - FIRE_RING(chan); - if (fence) - *fence = NULL; -} - -static void -nv20_destroy(struct pipe_context *pipe) -{ - struct nv20_context *nv20 = nv20_context(pipe); - - if (nv20->draw) - draw_destroy(nv20->draw); - - FREE(nv20); -} - -static void nv20_init_hwctx(struct nv20_context *nv20) -{ - struct nv20_screen *screen = nv20->screen; - struct nouveau_channel *chan = screen->base.channel; - struct nouveau_grobj *kelvin = screen->kelvin; + struct nouveau_channel *chan = screen->chan; + struct nouveau_grobj *kelvin = screen->eng3d; + const unsigned chipset = screen->device->chipset; int i; - float projectionmatrix[16]; - const boolean is_nv25tcl = (kelvin->grclass == NV25TCL); BEGIN_RING(chan, kelvin, NV20TCL_DMA_NOTIFY, 1); - OUT_RING (chan, screen->sync->handle); + OUT_RING (chan, screen->ntfy->handle); BEGIN_RING(chan, kelvin, NV20TCL_DMA_TEXTURE0, 2); OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->gart->handle); /* TEXTURE1 */ + OUT_RING (chan, chan->gart->handle); BEGIN_RING(chan, kelvin, NV20TCL_DMA_COLOR, 2); OUT_RING (chan, chan->vram->handle); - OUT_RING (chan, chan->vram->handle); /* ZETA */ + OUT_RING (chan, chan->vram->handle); + BEGIN_RING(chan, kelvin, NV20TCL_DMA_VTXBUF0, 2); + OUT_RING(chan, chan->vram->handle); + OUT_RING(chan, chan->gart->handle); BEGIN_RING(chan, kelvin, NV20TCL_DMA_QUERY, 1); - OUT_RING (chan, 0); /* renouveau: beef0351, unique */ + OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2); OUT_RING (chan, 0); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1); - OUT_RING (chan, (0xfff << 16) | 0x0); + OUT_RING (chan, 0xfff << 16 | 0x0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1); - OUT_RING (chan, (0xfff << 16) | 0x0); + OUT_RING (chan, 0xfff << 16 | 0x0); for (i = 1; i < NV20TCL_VIEWPORT_CLIP_HORIZ__SIZE; i++) { BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(i), 1); @@ -76,7 +80,7 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 1.0); - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, NV20TCL_TX_RCOMP, 1); OUT_RING (chan, NV20TCL_TX_RCOMP_LEQUAL | 0xdb0); } else { @@ -87,7 +91,7 @@ static void nv20_init_hwctx(struct nv20_context *nv20) } BEGIN_RING(chan, kelvin, 0x290, 1); - OUT_RING (chan, (0x10 << 16) | 1); + OUT_RING (chan, 0x10 << 16 | 1); BEGIN_RING(chan, kelvin, 0x9fc, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, 0x1d80, 1); @@ -99,7 +103,7 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RINGf (chan, 1.0); OUT_RINGf (chan, 0.0); - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, 0x1d88, 1); OUT_RING (chan, 3); @@ -108,21 +112,13 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV25TCL_DMA_IN_MEMORY8, 1); OUT_RING (chan, chan->vram->handle); } + BEGIN_RING(chan, kelvin, NV20TCL_DMA_FENCE, 1); - OUT_RING (chan, 0); /* renouveau: beef1e10 */ + OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, 0x1e98, 1); OUT_RING (chan, 0); -#if 0 - if (is_nv25tcl) { - BEGIN_RING(chan, NvSub3D, NV25TCL_DMA_IN_MEMORY4, 2); - OUT_RING (chan, NvDmaTT); /* renouveau: beef0202 */ - OUT_RING (chan, NvDmaFB); /* renouveau: beef0201 */ - BEGIN_RING(chan, NvSub3D, NV20TCL_DMA_TEXTURE1, 1); - OUT_RING (chan, NvDmaTT); /* renouveau: beef0202 */ - } -#endif BEGIN_RING(chan, kelvin, NV20TCL_NOTIFY, 1); OUT_RING (chan, 0); @@ -131,53 +127,35 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, 1); OUT_RING (chan, 2); -/* error: ILLEGAL_MTHD, PROTECTION_FAULT - BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 512.0); - OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); -*/ - - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, 0x022c, 2); OUT_RING (chan, 0x280); OUT_RING (chan, 0x07d28000); - } -/* * illegal method, protection fault - BEGIN_RING(chan, NvSub3D, 0x1c2c, 1); - OUT_RING (chan, 0); */ - - if (is_nv25tcl) { BEGIN_RING(chan, kelvin, 0x1da4, 1); OUT_RING (chan, 0); } -/* * crashes with illegal method, protection fault - BEGIN_RING(chan, NvSub3D, 0x1c18, 1); - OUT_RING (chan, 0x200); */ - BEGIN_RING(chan, kelvin, NV20TCL_RT_HORIZ, 2); - OUT_RING (chan, (0 << 16) | 0); - OUT_RING (chan, (0 << 16) | 0); - - /* *** Set state *** */ + OUT_RING (chan, 0 << 16 | 0); + OUT_RING (chan, 0 << 16 | 0); BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_ALPHA_FUNC_FUNC, 2); OUT_RING (chan, NV20TCL_ALPHA_FUNC_FUNC_ALWAYS); - OUT_RING (chan, 0); /* NV20TCL_ALPHA_FUNC_REF */ + OUT_RING (chan, 0); - for (i = 0; i < NV20TCL_TX_ENABLE__SIZE; ++i) { + for (i = 0; i < NV20TCL_TX_ENABLE__SIZE; i++) { BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); OUT_RING (chan, 0); } + BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_OP, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_CULL_MODE, 1); OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_RC_IN_ALPHA(0), 4); OUT_RING (chan, 0x30d410d0); OUT_RING (chan, 0); @@ -211,9 +189,9 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, 0); OUT_RING (chan, 0x40002000); OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_MULTISAMPLE_CONTROL, 1); OUT_RING (chan, 0xffff0000); - BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_DITHER_ENABLE, 1); @@ -223,13 +201,13 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV20TCL_BLEND_FUNC_SRC, 4); OUT_RING (chan, NV20TCL_BLEND_FUNC_SRC_ONE); OUT_RING (chan, NV20TCL_BLEND_FUNC_DST_ZERO); - OUT_RING (chan, 0); /* NV20TCL_BLEND_COLOR */ + OUT_RING (chan, 0); OUT_RING (chan, NV20TCL_BLEND_EQUATION_FUNC_ADD); BEGIN_RING(chan, kelvin, NV20TCL_STENCIL_MASK, 7); OUT_RING (chan, 0xff); OUT_RING (chan, NV20TCL_STENCIL_FUNC_FUNC_ALWAYS); - OUT_RING (chan, 0); /* NV20TCL_STENCIL_FUNC_REF */ - OUT_RING (chan, 0xff); /* NV20TCL_STENCIL_FUNC_MASK */ + OUT_RING (chan, 0); + OUT_RING (chan, 0xff); OUT_RING (chan, NV20TCL_STENCIL_OP_FAIL_KEEP); OUT_RING (chan, NV20TCL_STENCIL_OP_ZFAIL_KEEP); OUT_RING (chan, NV20TCL_STENCIL_OP_ZPASS_KEEP); @@ -239,14 +217,14 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, NV20TCL_COLOR_LOGIC_OP_OP_COPY); BEGIN_RING(chan, kelvin, 0x17cc, 1); OUT_RING (chan, 0); - if (is_nv25tcl) { + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, 0x1d84, 1); OUT_RING (chan, 1); } BEGIN_RING(chan, kelvin, NV20TCL_LIGHTING_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL, 1); - OUT_RING (chan, 0x00020000); + OUT_RING (chan, NV20TCL_LIGHT_MODEL_VIEWER_NONLOCAL); BEGIN_RING(chan, kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1); @@ -256,15 +234,15 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV20TCL_NORMALIZE_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_PATTERN(0), - NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE); - for (i = 0; i < NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE; ++i) { + NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE); + for (i = 0; i < NV20TCL_POLYGON_STIPPLE_PATTERN__SIZE; i++) { OUT_RING(chan, 0xffffffff); } BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_POINT_ENABLE, 3); OUT_RING (chan, 0); - OUT_RING (chan, 0); /* NV20TCL.POLYGON_OFFSET_LINE_ENABLE */ - OUT_RING (chan, 0); /* NV20TCL.POLYGON_OFFSET_FILL_ENABLE */ + OUT_RING (chan, 0); + OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_FUNC, 1); OUT_RING (chan, NV20TCL_DEPTH_FUNC_LESS); BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_WRITE_ENABLE, 1); @@ -273,29 +251,30 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_OFFSET_FACTOR, 2); OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 0.0); /* NV20TCL.POLYGON_OFFSET_UNITS */ + OUT_RINGf (chan, 0.0); BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_UNK17D8, 1); OUT_RING (chan, 1); - if (!is_nv25tcl) { + if (chipset < 0x25) { BEGIN_RING(chan, kelvin, 0x1d84, 1); OUT_RING (chan, 3); } BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); - if (!is_nv25tcl) { - OUT_RING (chan, 8); - } else { + if (chipset >= 0x25) OUT_RINGf (chan, 1.0); - } - if (!is_nv25tcl) { - BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2); - OUT_RING (chan, 0); - OUT_RING (chan, 0); /* NV20TCL.POINT_SMOOTH_ENABLE */ - } else { + else + OUT_RING (chan, 8); + + if (chipset >= 0x25) { BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 1); OUT_RING (chan, 0); BEGIN_RING(chan, kelvin, 0x0a1c, 1); OUT_RING (chan, 0x800); + } else { + BEGIN_RING(chan, kelvin, NV20TCL_POINT_PARAMETERS_ENABLE, 2); + OUT_RING (chan, 0); + OUT_RING (chan, 0); } + BEGIN_RING(chan, kelvin, NV20TCL_LINE_WIDTH, 1); OUT_RING (chan, 8); BEGIN_RING(chan, kelvin, NV20TCL_LINE_SMOOTH_ENABLE, 1); @@ -314,33 +293,45 @@ static void nv20_init_hwctx(struct nv20_context *nv20) OUT_RING (chan, NV20TCL_SHADE_MODEL_SMOOTH); BEGIN_RING(chan, kelvin, NV20TCL_POLYGON_STIPPLE_ENABLE, 1); OUT_RING (chan, 0); - BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_S(0), 4 * NV20TCL_TX_GEN_S__SIZE); - for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; ++i) { + + BEGIN_RING(chan, kelvin, NV20TCL_TX_GEN_S(0), + 4 * NV20TCL_TX_GEN_S__SIZE); + for (i=0; i < 4 * NV20TCL_TX_GEN_S__SIZE; i++) OUT_RING(chan, 0); - } + BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3); OUT_RINGf (chan, 1.5); - OUT_RINGf (chan, -0.090168); /* NV20TCL.FOG_EQUATION_LINEAR */ - OUT_RINGf (chan, 0.0); /* NV20TCL.FOG_EQUATION_QUADRATIC */ + OUT_RINGf (chan, -0.090168); + OUT_RINGf (chan, 0.0); BEGIN_RING(chan, kelvin, NV20TCL_FOG_MODE, 2); OUT_RING (chan, NV20TCL_FOG_MODE_EXP_SIGNED); OUT_RING (chan, NV20TCL_FOG_COORD_FOG); BEGIN_RING(chan, kelvin, NV20TCL_FOG_ENABLE, 2); OUT_RING (chan, 0); - OUT_RING (chan, 0); /* NV20TCL.FOG_COLOR */ + OUT_RING (chan, 0); + BEGIN_RING(chan, kelvin, NV20TCL_ENGINE, 1); OUT_RING (chan, NV20TCL_ENGINE_FIXED); - for (i = 0; i < NV20TCL_TX_MATRIX_ENABLE__SIZE; ++i) { + for (i = 0; i < NV20TCL_TX_MATRIX_ENABLE__SIZE; i++) { BEGIN_RING(chan, kelvin, NV20TCL_TX_MATRIX_ENABLE(i), 1); OUT_RING (chan, 0); } BEGIN_RING(chan, kelvin, NV20TCL_VTX_ATTR_4F_X(1), 4 * 15); - OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 1.0); - OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); - OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); OUT_RINGf(chan, 1.0); - for (i = 4; i < 16; ++i) { + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 0.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + OUT_RINGf(chan, 1.0); + for (i = 0; i < 12; i++) { OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); OUT_RINGf(chan, 0.0); @@ -354,71 +345,139 @@ static void nv20_init_hwctx(struct nv20_context *nv20) BEGIN_RING(chan, kelvin, NV20TCL_CLEAR_VALUE, 1); OUT_RING (chan, 0); - memset(projectionmatrix, 0, sizeof(projectionmatrix)); - projectionmatrix[0*4+0] = 1.0; - projectionmatrix[1*4+1] = 1.0; - projectionmatrix[2*4+2] = 16777215.0; - projectionmatrix[3*4+3] = 1.0; - BEGIN_RING(chan, kelvin, NV20TCL_PROJECTION_MATRIX(0), 16); - for (i = 0; i < 16; i++) { - OUT_RINGf (chan, projectionmatrix[i]); - } - BEGIN_RING(chan, kelvin, NV20TCL_DEPTH_RANGE_NEAR, 2); OUT_RINGf (chan, 0.0); - OUT_RINGf (chan, 16777216.0); /* [0, 1] scaled approx to [0, 2^24] */ + OUT_RINGf (chan, 16777216.0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); - OUT_RINGf (chan, 0.0); /* x-offset, w/2 + 1.031250 */ - OUT_RINGf (chan, 0.0); /* y-offset, h/2 + 0.030762 */ + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 16777215.0); BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_SCALE_X, 4); - OUT_RINGf (chan, 0.0); /* no effect?, w/2 */ - OUT_RINGf (chan, 0.0); /* no effect?, h/2 */ + OUT_RINGf (chan, 0.0); + OUT_RINGf (chan, 0.0); OUT_RINGf (chan, 16777215.0 * 0.5); OUT_RINGf (chan, 65535.0); - FIRE_RING (chan); + FIRE_RING(chan); } -struct pipe_context * -nv20_create(struct pipe_screen *pscreen, unsigned pctx_id) +GLboolean +nv20_screen_init(struct nouveau_screen *screen) { - struct nv20_screen *screen = nv20_screen(pscreen); - struct pipe_winsys *ws = pscreen->winsys; - struct nv20_context *nv20; - struct nouveau_winsys *nvws = screen->nvws; + unsigned chipset = screen->device->chipset; + unsigned kelvin_class; + int ret; - nv20 = CALLOC(1, sizeof(struct nv20_context)); - if (!nv20) - return NULL; - nv20->screen = screen; - nv20->pctx_id = pctx_id; + screen->driver = &nv20_driver; - nv20->nvws = nvws; + /* 2D engine */ + ret = nv04_surface_init(screen); + if (!ret) + return GL_FALSE; - nv20->pipe.winsys = ws; - nv20->pipe.screen = pscreen; - nv20->pipe.destroy = nv20_destroy; - nv20->pipe.draw_arrays = nv20_draw_arrays; - nv20->pipe.draw_elements = nv20_draw_elements; - nv20->pipe.clear = nv20_clear; - nv20->pipe.flush = nv20_flush; + /* 3D engine. */ + if (chipset >= 0x25) + kelvin_class = NV25TCL; + else + kelvin_class = NV20TCL; - nv20->pipe.is_texture_referenced = nouveau_is_texture_referenced; - nv20->pipe.is_buffer_referenced = nouveau_is_buffer_referenced; + ret = nouveau_grobj_alloc(screen->chan, 0xbeef0001, kelvin_class, + &screen->eng3d); + if (ret) + return GL_FALSE; - nv20_init_surface_functions(nv20); - nv20_init_state_functions(nv20); + nv20_hwctx_init(screen); - nv20->draw = draw_create(); - assert(nv20->draw); - draw_set_rasterize_stage(nv20->draw, nv20_draw_vbuf_stage(nv20)); + return GL_TRUE; +} - nv20_init_hwctx(nv20); +static void +nv20_screen_destroy(struct nouveau_screen *screen) +{ + if (screen->eng3d) + nouveau_grobj_free(&screen->eng3d); - return &nv20->pipe; + nv04_surface_takedown(screen); } +static const struct nouveau_driver nv20_driver = { + .screen_destroy = nv20_screen_destroy, + .context_create = nv20_context_create, + .context_destroy = nv20_context_destroy, + .surface_copy = nv04_surface_copy, + .surface_fill = nv04_surface_fill, + .emit = (nouveau_state_func[]) { + nv10_emit_alpha_func, + nv10_emit_blend_color, + nv10_emit_blend_equation, + nv10_emit_blend_func, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv20_emit_clip_plane, + nv10_emit_color_mask, + nv20_emit_color_material, + nv10_emit_cull_face, + nv10_emit_front_face, + nv10_emit_depth, + nv10_emit_dither, + nv10_emit_frag, + nv20_emit_framebuffer, + nv20_emit_fog, + nv10_emit_index_mask, + nv10_emit_light_enable, + nv20_emit_light_model, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv20_emit_light_source, + nv10_emit_line_stipple, + nv10_emit_line_mode, + nv20_emit_logic_opcode, + nv20_emit_material_ambient, + nv20_emit_material_ambient, + nv20_emit_material_diffuse, + nv20_emit_material_diffuse, + nv20_emit_material_specular, + nv20_emit_material_specular, + nv20_emit_material_shininess, + nv20_emit_material_shininess, + nv20_emit_modelview, + nv20_emit_point_mode, + nv10_emit_point_parameter, + nv10_emit_polygon_mode, + nv10_emit_polygon_offset, + nv10_emit_polygon_stipple, + nv20_emit_projection, + nv10_emit_render_mode, + nv10_emit_scissor, + nv10_emit_shade_model, + nv10_emit_stencil_func, + nv10_emit_stencil_mask, + nv10_emit_stencil_op, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_env, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv10_emit_tex_gen, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_tex_obj, + nv20_emit_viewport, + nv20_emit_tex_shader + }, + .num_emit = NUM_NV20_STATE, +}; diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_fb.c b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c new file mode 100644 index 00000000000..869acd6e317 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_fbo.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +static inline unsigned +get_rt_format(gl_format format) +{ + switch (format) { + case MESA_FORMAT_XRGB8888: + return 0x05; + case MESA_FORMAT_ARGB8888: + return 0x08; + case MESA_FORMAT_RGB565: + return 0x03; + case MESA_FORMAT_Z16: + return 0x10; + case MESA_FORMAT_Z24_S8: + return 0x20; + default: + assert(0); + } +} + +void +nv20_emit_framebuffer(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx(ctx, FRAMEBUFFER); + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct nouveau_surface *s; + unsigned rt_format = NV20TCL_RT_FORMAT_TYPE_LINEAR; + unsigned rt_pitch = 0, zeta_pitch = 0; + unsigned bo_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR; + + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) + return; + + /* Render target */ + if (fb->_NumColorDrawBuffers) { + s = &to_nouveau_renderbuffer( + fb->_ColorDrawBuffers[0])->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = rt_pitch = s->pitch; + + nouveau_bo_markl(bctx, kelvin, NV20TCL_COLOR_OFFSET, + s->bo, 0, bo_flags); + } + + /* depth/stencil */ + if (fb->_DepthBuffer) { + s = &to_nouveau_renderbuffer( + fb->_DepthBuffer->Wrapped)->surface; + + rt_format |= get_rt_format(s->format); + zeta_pitch = s->pitch; + + nouveau_bo_markl(bctx, kelvin, NV20TCL_ZETA_OFFSET, + s->bo, 0, bo_flags); + } + + BEGIN_RING(chan, kelvin, NV20TCL_RT_FORMAT, 2); + OUT_RING(chan, rt_format); + OUT_RING(chan, zeta_pitch << 16 | rt_pitch); + + /* Recompute the viewport/scissor state. */ + context_dirty(ctx, VIEWPORT); + context_dirty(ctx, SCISSOR); +} + +void +nv20_emit_viewport(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_framebuffer *fb = ctx->DrawBuffer; + float a[4] = {}; + int i; + + get_viewport_translate(ctx, a); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_TRANSLATE_X, 4); + for (i = 0; i < 4; i++) + OUT_RINGf(chan, a[i]); + + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_HORIZ(0), 1); + OUT_RING(chan, (fb->Width - 1) << 16); + BEGIN_RING(chan, kelvin, NV20TCL_VIEWPORT_CLIP_VERT(0), 1); + OUT_RING(chan, (fb->Height - 1) << 16); + + context_dirty(ctx, PROJECTION); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c b/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c new file mode 100644 index 00000000000..3a320e2dac5 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_polygon.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +void +nv20_emit_point_mode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_POINT_SIZE, 1); + if (context_chipset(ctx) >= 0x25) + OUT_RINGf(chan, ctx->Point.Size); + else + OUT_RING(chan, (uint32_t)(ctx->Point.Size * 8)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_raster.c b/src/mesa/drivers/dri/nouveau/nv20_state_raster.c new file mode 100644 index 00000000000..b43b29bb23b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_raster.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_class.h" +#include "nv20_driver.h" + +void +nv20_emit_logic_opcode(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_LOGIC_OP_ENABLE, 2); + OUT_RING(chan, ctx->Color.ColorLogicOpEnabled ? 1 : 0); + OUT_RING(chan, nvgl_logicop_func(ctx->Color.LogicOp)); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c new file mode 100644 index 00000000000..d01e91f8ee1 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2009 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_texture.h" +#include "nouveau_class.h" +#include "nouveau_util.h" +#include "nv20_driver.h" + +static uint32_t +get_tex_format(struct gl_texture_image *ti) +{ + switch (ti->TexFormat) { + case MESA_FORMAT_ARGB8888: + return NV20TCL_TX_FORMAT_FORMAT_A8R8G8B8; + + case MESA_FORMAT_ARGB1555: + return NV20TCL_TX_FORMAT_FORMAT_A1R5G5B5; + + case MESA_FORMAT_ARGB4444: + return NV20TCL_TX_FORMAT_FORMAT_A4R4G4B4; + + case MESA_FORMAT_RGB565: + return NV20TCL_TX_FORMAT_FORMAT_R5G6B5; + + case MESA_FORMAT_A8: + return NV20TCL_TX_FORMAT_FORMAT_A8; + + case MESA_FORMAT_L8: + return NV20TCL_TX_FORMAT_FORMAT_L8; + + case MESA_FORMAT_CI8: + return NV20TCL_TX_FORMAT_FORMAT_INDEX8; + + default: + assert(0); + } +} + +void +nv20_emit_tex_obj(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_TEX_OBJ0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct nouveau_bo_context *bctx = context_bctx_i(ctx, TEXTURE, i); + const int bo_flags = NOUVEAU_BO_RD | NOUVEAU_BO_GART | NOUVEAU_BO_VRAM; + struct gl_texture_object *t; + struct nouveau_surface *s; + struct gl_texture_image *ti; + uint32_t tx_format, tx_filter, tx_wrap, tx_enable; + + if (!ctx->Texture.Unit[i]._ReallyEnabled) { + BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); + OUT_RING(chan, 0); + + context_dirty(ctx, TEX_SHADER); + return; + } + + t = ctx->Texture.Unit[i]._Current; + s = &to_nouveau_texture(t)->surfaces[t->BaseLevel]; + ti = t->Image[0][t->BaseLevel]; + + nouveau_texture_validate(ctx, t); + + /* Recompute the texturing registers. */ + tx_format = ti->DepthLog2 << 28 + | ti->HeightLog2 << 24 + | ti->WidthLog2 << 20 + | get_tex_format(ti) + | NV20TCL_TX_FORMAT_DIMS_2D + | NV20TCL_TX_FORMAT_NO_BORDER + | 1 << 16; + + tx_wrap = nvgl_wrap_mode(t->WrapR) << 16 + | nvgl_wrap_mode(t->WrapT) << 8 + | nvgl_wrap_mode(t->WrapS) << 0; + + tx_filter = nvgl_filter_mode(t->MagFilter) << 24 + | nvgl_filter_mode(t->MinFilter) << 16; + + tx_enable = NV20TCL_TX_ENABLE_ENABLE + | log2i(t->MaxAnisotropy) << 4; + + if (t->MinFilter != GL_NEAREST && + t->MinFilter != GL_LINEAR) { + int lod_min = t->MinLod; + int lod_max = MIN2(t->MaxLod, t->_MaxLambda); + int lod_bias = t->LodBias + + ctx->Texture.Unit[i].LodBias; + + lod_max = CLAMP(lod_max, 0, 15); + lod_min = CLAMP(lod_min, 0, 15); + lod_bias = CLAMP(lod_bias, 0, 15); + + tx_format |= NV20TCL_TX_FORMAT_MIPMAP; + tx_filter |= lod_bias << 8; + tx_enable |= lod_min << 26 + | lod_max << 14; + } + + /* Write it to the hardware. */ + nouveau_bo_mark(bctx, kelvin, NV20TCL_TX_FORMAT(i), + s->bo, tx_format, 0, + NV20TCL_TX_FORMAT_DMA0, + NV20TCL_TX_FORMAT_DMA1, + bo_flags | NOUVEAU_BO_OR); + + nouveau_bo_markl(bctx, kelvin, NV20TCL_TX_OFFSET(i), + s->bo, 0, bo_flags); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_WRAP(i), 1); + OUT_RING(chan, tx_wrap); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_FILTER(i), 1); + OUT_RING(chan, tx_filter); + + BEGIN_RING(chan, kelvin, NV20TCL_TX_ENABLE(i), 1); + OUT_RING(chan, tx_enable); + + context_dirty(ctx, TEX_SHADER); +} + +void +nv20_emit_tex_shader(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + uint32_t tx_shader_op = 0; + int i; + + for (i = 0; i < NV20_TEXTURE_UNITS; i++) { + if (!ctx->Texture.Unit[i]._ReallyEnabled) + continue; + + tx_shader_op |= NV20TCL_TX_SHADER_OP_TX0_TEXTURE_2D << 5 * i; + } + + BEGIN_RING(chan, kelvin, NV20TCL_TX_SHADER_OP, 1); + OUT_RING(chan, tx_shader_op); +} diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c new file mode 100644 index 00000000000..0d566064f67 --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2009-2010 Francisco Jerez. + * 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, sublicense, 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 NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "nouveau_driver.h" +#include "nouveau_context.h" +#include "nouveau_gldefs.h" +#include "nouveau_util.h" +#include "nouveau_class.h" +#include "nv10_driver.h" +#include "nv20_driver.h" + +void +nv20_emit_clip_plane(GLcontext *ctx, int emit) +{ +} + +static inline unsigned +get_material_bitmask(unsigned m) +{ + unsigned ret = 0; + + if (m & MAT_BIT_FRONT_EMISSION) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_EMISSION_COL1; + if (m & MAT_BIT_FRONT_AMBIENT) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_AMBIENT_COL1; + if (m & MAT_BIT_FRONT_DIFFUSE) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_DIFFUSE_COL1; + if (m & MAT_BIT_FRONT_SPECULAR) + ret |= NV20TCL_COLOR_MATERIAL_FRONT_SPECULAR_COL1; + + if (m & MAT_BIT_BACK_EMISSION) + ret |= NV20TCL_COLOR_MATERIAL_BACK_EMISSION_COL1; + if (m & MAT_BIT_BACK_AMBIENT) + ret |= NV20TCL_COLOR_MATERIAL_BACK_AMBIENT_COL1; + if (m & MAT_BIT_BACK_DIFFUSE) + ret |= NV20TCL_COLOR_MATERIAL_BACK_DIFFUSE_COL1; + if (m & MAT_BIT_BACK_SPECULAR) + ret |= NV20TCL_COLOR_MATERIAL_BACK_SPECULAR_COL1; + + return ret; +} + +void +nv20_emit_color_material(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + unsigned mask = get_material_bitmask(ctx->Light.ColorMaterialBitmask); + + BEGIN_RING(chan, kelvin, NV20TCL_COLOR_MATERIAL, 1); + OUT_RING(chan, ctx->Light.ColorMaterialEnabled ? mask : 0); +} + +static unsigned +get_fog_mode_signed(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV20TCL_FOG_MODE_LINEAR_SIGNED; + case GL_EXP: + return NV20TCL_FOG_MODE_EXP_SIGNED; + case GL_EXP2: + return NV20TCL_FOG_MODE_EXP2_SIGNED; + default: + assert(0); + } +} + +static unsigned +get_fog_mode_unsigned(unsigned mode) +{ + switch (mode) { + case GL_LINEAR: + return NV20TCL_FOG_MODE_LINEAR_UNSIGNED; + case GL_EXP: + return NV20TCL_FOG_MODE_EXP_UNSIGNED; + case GL_EXP2: + return NV20TCL_FOG_MODE_EXP2_UNSIGNED; + default: + assert(0); + } +} + +static unsigned +get_fog_source(unsigned source) +{ + switch (source) { + case GL_FOG_COORDINATE_EXT: + return NV20TCL_FOG_COORD_FOG; + case GL_FRAGMENT_DEPTH_EXT: + return NV20TCL_FOG_COORD_DIST_ORTHOGONAL_ABS; + default: + assert(0); + } +} + +void +nv20_emit_fog(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_fog_attrib *f = &ctx->Fog; + unsigned source = nctx->fallback == HWTNL ? + f->FogCoordinateSource : GL_FOG_COORDINATE_EXT; + float k[3]; + + nv10_get_fog_coeff(ctx, k); + + BEGIN_RING(chan, kelvin, NV20TCL_FOG_MODE, 4); + OUT_RING(chan, (source == GL_FOG_COORDINATE_EXT ? + get_fog_mode_signed(f->Mode) : + get_fog_mode_unsigned(f->Mode))); + OUT_RING(chan, get_fog_source(source)); + OUT_RING(chan, f->Enabled ? 1 : 0); + OUT_RING(chan, pack_rgba_f(MESA_FORMAT_RGBA8888_REV, f->Color)); + + BEGIN_RING(chan, kelvin, NV20TCL_FOG_EQUATION_CONSTANT, 3); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); +} + +void +nv20_emit_light_model(GLcontext *ctx, int emit) +{ + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_lightmodel *m = &ctx->Light.Model; + + BEGIN_RING(chan, kelvin, NV20TCL_SEPARATE_SPECULAR_ENABLE, 1); + OUT_RING(chan, m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? 1 : 0); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL, 1); + OUT_RING(chan, ((m->LocalViewer ? + NV20TCL_LIGHT_MODEL_VIEWER_LOCAL : + NV20TCL_LIGHT_MODEL_VIEWER_NONLOCAL) | + (m->ColorControl == GL_SEPARATE_SPECULAR_COLOR ? + NV20TCL_LIGHT_MODEL_SEPARATE_SPECULAR : + 0))); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_MODEL_TWO_SIDE_ENABLE, 1); + OUT_RING(chan, ctx->Light.Model.TwoSide ? 1 : 0); +} + +void +nv20_emit_light_source(GLcontext *ctx, int emit) +{ + const int i = emit - NOUVEAU_STATE_LIGHT_SOURCE0; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_light *l = &ctx->Light.Light[i]; + + if (l->_Flags & LIGHT_POSITIONAL) { + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_POSITION_X(i), 3); + OUT_RINGf(chan, l->_Position[0]); + OUT_RINGf(chan, l->_Position[1]); + OUT_RINGf(chan, l->_Position[2]); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_ATTENUATION_CONSTANT(i), 3); + OUT_RINGf(chan, l->ConstantAttenuation); + OUT_RINGf(chan, l->LinearAttenuation); + OUT_RINGf(chan, l->QuadraticAttenuation); + + } else { + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_DIRECTION_X(i), 3); + OUT_RINGf(chan, l->_VP_inf_norm[0]); + OUT_RINGf(chan, l->_VP_inf_norm[1]); + OUT_RINGf(chan, l->_VP_inf_norm[2]); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_HALF_VECTOR_X(i), 3); + OUT_RINGf(chan, l->_h_inf_norm[0]); + OUT_RINGf(chan, l->_h_inf_norm[1]); + OUT_RINGf(chan, l->_h_inf_norm[2]); + } + + if (l->_Flags & LIGHT_SPOT) { + float k[7]; + + nv10_get_spot_coeff(l, k); + + BEGIN_RING(chan, kelvin, NV20TCL_LIGHT_SPOT_CUTOFF_A(i), 7); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); + OUT_RINGf(chan, k[6]); + } +} + +#define USE_COLOR_MATERIAL(attr, side) \ + (ctx->Light.ColorMaterialEnabled && \ + ctx->Light.ColorMaterialBitmask & (1 << MAT_ATTRIB_##attr(side))) + +void +nv20_emit_material_ambient(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_AMBIENT; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t m_scene[] = { NV20TCL_LIGHT_MODEL_FRONT_AMBIENT_R, + NV20TCL_LIGHT_MODEL_BACK_AMBIENT_R }; + uint32_t m_factor[] = { NV20TCL_MATERIAL_FACTOR_FRONT_R, + NV20TCL_MATERIAL_FACTOR_BACK_R }; + float c_scene[3], c_factor[3]; + struct gl_light *l; + + if (USE_COLOR_MATERIAL(AMBIENT, side)) { + COPY_3V(c_scene, mat[MAT_ATTRIB_EMISSION(side)]); + COPY_3V(c_factor, ctx->Light.Model.Ambient); + + } else if (USE_COLOR_MATERIAL(EMISSION, side)) { + SCALE_3V(c_scene, mat[MAT_ATTRIB_AMBIENT(side)], + ctx->Light.Model.Ambient); + ASSIGN_3V(c_factor, 1, 1, 1); + + } else { + COPY_3V(c_scene, ctx->Light._BaseColor[side]); + ZERO_3V(c_factor); + } + + BEGIN_RING(chan, kelvin, m_scene[side], 3); + OUT_RINGf(chan, c_scene[0]); + OUT_RINGf(chan, c_scene[1]); + OUT_RINGf(chan, c_scene[2]); + + if (ctx->Light.ColorMaterialEnabled) { + BEGIN_RING(chan, kelvin, m_factor[side], 3); + OUT_RINGf(chan, c_factor[0]); + OUT_RINGf(chan, c_factor[1]); + OUT_RINGf(chan, c_factor[2]); + } + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_AMBIENT_R(i), + NV20TCL_LIGHT_BACK_AMBIENT_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(AMBIENT, side) ? + l->Ambient : + l->_MatAmbient[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_diffuse(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_DIFFUSE; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLfloat (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t m_factor[] = { NV20TCL_MATERIAL_FACTOR_FRONT_A, + NV20TCL_MATERIAL_FACTOR_BACK_A }; + struct gl_light *l; + + BEGIN_RING(chan, kelvin, m_factor[side], 1); + OUT_RINGf(chan, mat[MAT_ATTRIB_DIFFUSE(side)][3]); + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_DIFFUSE_R(i), + NV20TCL_LIGHT_BACK_DIFFUSE_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(DIFFUSE, side) ? + l->Diffuse : + l->_MatDiffuse[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_specular(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SPECULAR; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + struct gl_light *l; + + foreach(l, &ctx->Light.EnabledList) { + const int i = l - ctx->Light.Light; + uint32_t m_light[] = { NV20TCL_LIGHT_FRONT_SPECULAR_R(i), + NV20TCL_LIGHT_BACK_SPECULAR_R(i) }; + float *c_light = (USE_COLOR_MATERIAL(SPECULAR, side) ? + l->Specular : + l->_MatSpecular[side]); + + BEGIN_RING(chan, kelvin, m_light[side], 3); + OUT_RINGf(chan, c_light[0]); + OUT_RINGf(chan, c_light[1]); + OUT_RINGf(chan, c_light[2]); + } +} + +void +nv20_emit_material_shininess(GLcontext *ctx, int emit) +{ + const int side = emit - NOUVEAU_STATE_MATERIAL_FRONT_SHININESS; + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + float (*mat)[4] = ctx->Light.Material.Attrib; + uint32_t mthd[] = { NV20TCL_FRONT_MATERIAL_SHININESS(0), + NV20TCL_BACK_MATERIAL_SHININESS(0) }; + float k[6]; + + nv10_get_shininess_coeff( + CLAMP(mat[MAT_ATTRIB_SHININESS(side)][0], 0, 1024), + k); + + BEGIN_RING(chan, kelvin, mthd[side], 6); + OUT_RINGf(chan, k[0]); + OUT_RINGf(chan, k[1]); + OUT_RINGf(chan, k[2]); + OUT_RINGf(chan, k[3]); + OUT_RINGf(chan, k[4]); + OUT_RINGf(chan, k[5]); +} + +void +nv20_emit_modelview(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLmatrix *m = ctx->ModelviewMatrixStack.Top; + + if (nctx->fallback != HWTNL) + return; + + if (ctx->Light._NeedEyeCoords || ctx->Fog.Enabled) { + BEGIN_RING(chan, kelvin, NV20TCL_MODELVIEW0_MATRIX(0), 16); + OUT_RINGm(chan, m->m); + } + + if (ctx->Light.Enabled) { + int i, j; + + BEGIN_RING(chan, kelvin, + NV20TCL_INVERSE_MODELVIEW0_MATRIX(0), 12); + for (i = 0; i < 3; i++) + for (j = 0; j < 4; j++) + OUT_RINGf(chan, m->inv[4*i + j]); + } +} + +void +nv20_emit_projection(GLcontext *ctx, int emit) +{ + struct nouveau_context *nctx = to_nouveau_context(ctx); + struct nouveau_channel *chan = context_chan(ctx); + struct nouveau_grobj *kelvin = context_eng3d(ctx); + GLmatrix m; + + _math_matrix_ctr(&m); + get_viewport_scale(ctx, m.m); + + if (nctx->fallback == HWTNL) + _math_matrix_mul_matrix(&m, &m, &ctx->_ModelProjectMatrix); + + BEGIN_RING(chan, kelvin, NV20TCL_PROJECTION_MATRIX(0), 16); + OUT_RINGm(chan, m.m); + + _math_matrix_dtr(&m); +} |