@@ -70,7 +70,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos | |||
# Gallium directories and | |||
GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util sct | |||
GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) | |||
GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv30 nv40 nv50 failover | |||
GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv10 nv30 nv40 nv50 failover | |||
GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) | |||
GALLIUM_WINSYS_DIRS = xlib | |||
@@ -65,4 +65,4 @@ GALLIUM_WINSYS_DIRS = dri | |||
# gamma are missing because they have not been converted to use the new | |||
# interface. | |||
DRI_DIRS = intel | |||
DRI_DIRS = nouveau |
@@ -49,6 +49,13 @@ struct nouveau_winsys { | |||
unsigned, unsigned, unsigned, unsigned, unsigned); | |||
}; | |||
extern struct pipe_screen * | |||
nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, | |||
unsigned chipset); | |||
extern struct pipe_context * | |||
nv10_create(struct pipe_screen *, unsigned pctx_id); | |||
extern struct pipe_screen * | |||
nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *, | |||
unsigned chipset); |
@@ -0,0 +1,28 @@ | |||
TOP = ../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = nv10 | |||
DRIVER_SOURCES = \ | |||
nv10_clear.c \ | |||
nv10_context.c \ | |||
nv10_fragprog.c \ | |||
nv10_fragtex.c \ | |||
nv10_miptree.c \ | |||
nv10_prim_vbuf.c \ | |||
nv10_screen.c \ | |||
nv10_state.c \ | |||
nv10_state_emit.c \ | |||
nv10_surface.c \ | |||
nv10_vbo.c | |||
C_SOURCES = \ | |||
$(COMMON_SOURCES) \ | |||
$(DRIVER_SOURCES) | |||
ASM_SOURCES = | |||
include ../../Makefile.template | |||
symlinks: | |||
@@ -0,0 +1,12 @@ | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_state.h" | |||
#include "nv10_context.h" | |||
void | |||
nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, | |||
unsigned clearValue) | |||
{ | |||
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue); | |||
} |
@@ -0,0 +1,325 @@ | |||
#include "draw/draw_context.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_winsys.h" | |||
#include "pipe/p_util.h" | |||
#include "nv10_context.h" | |||
#include "nv10_screen.h" | |||
static void | |||
nv10_flush(struct pipe_context *pipe, unsigned flags) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nouveau_winsys *nvws = nv10->nvws; | |||
if (flags & PIPE_FLUSH_TEXTURE_CACHE) { | |||
BEGIN_RING(celsius, 0x1fd8, 1); | |||
OUT_RING (2); | |||
BEGIN_RING(celsius, 0x1fd8, 1); | |||
OUT_RING (1); | |||
} | |||
if (flags & PIPE_FLUSH_WAIT) { | |||
nvws->notifier_reset(nv10->sync, 0); | |||
BEGIN_RING(celsius, 0x104, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, 0x100, 1); | |||
OUT_RING (0); | |||
} | |||
FIRE_RING(); | |||
if (flags & PIPE_FLUSH_WAIT) | |||
nvws->notifier_wait(nv10->sync, 0, 0, 2000); | |||
} | |||
static void | |||
nv10_destroy(struct pipe_context *pipe) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nouveau_winsys *nvws = nv10->nvws; | |||
if (nv10->draw) | |||
draw_destroy(nv10->draw); | |||
nvws->res_free(&nv10->vertprog.exec_heap); | |||
nvws->res_free(&nv10->vertprog.data_heap); | |||
nvws->notifier_free(&nv10->sync); | |||
nvws->grobj_free(&nv10->celsius); | |||
free(nv10); | |||
} | |||
static boolean | |||
nv10_init_hwctx(struct nv10_context *nv10, int celsius_class) | |||
{ | |||
struct nouveau_winsys *nvws = nv10->nvws; | |||
int ret; | |||
int i; | |||
ret = nvws->grobj_alloc(nvws, celsius_class, &nv10->celsius); | |||
if (ret) { | |||
NOUVEAU_ERR("Error creating 3D object: %d\n", ret); | |||
return FALSE; | |||
} | |||
BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1); | |||
OUT_RING (nv10->sync->handle); | |||
BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2); | |||
OUT_RING (nvws->channel->vram->handle); | |||
OUT_RING (nvws->channel->gart->handle); | |||
BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY2, 2); | |||
OUT_RING (nvws->channel->vram->handle); | |||
OUT_RING (nvws->channel->vram->handle); | |||
BEGIN_RING(celsius, NV10TCL_NOP, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 2); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1); | |||
OUT_RING ((0x7ff<<16)|0x800); | |||
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1); | |||
OUT_RING ((0x7ff<<16)|0x800); | |||
for (i=1;i<8;i++) { | |||
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1); | |||
OUT_RING (0); | |||
} | |||
BEGIN_RING(celsius, 0x290, 1); | |||
OUT_RING ((0x10<<16)|1); | |||
BEGIN_RING(celsius, 0x3f4, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_NOP, 1); | |||
OUT_RING (0); | |||
if (celsius_class != NV10TCL) { | |||
/* For nv11, nv17 */ | |||
BEGIN_RING(celsius, 0x120, 3); | |||
OUT_RING (0); | |||
OUT_RING (1); | |||
OUT_RING (2); | |||
BEGIN_RING(celsius, NV10TCL_NOP, 1); | |||
OUT_RING (0); | |||
} | |||
BEGIN_RING(celsius, NV10TCL_NOP, 1); | |||
OUT_RING (0); | |||
/* Set state */ | |||
BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 2); | |||
OUT_RING (0x207); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_RC_OUT_ALPHA(0), 6); | |||
OUT_RING (0x00000c00); | |||
OUT_RING (0); | |||
OUT_RING (0x00000c00); | |||
OUT_RING (0x18000000); | |||
OUT_RING (0x300c0000); | |||
OUT_RING (0x00001c80); | |||
BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2); | |||
OUT_RING (1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_SRC, 4); | |||
OUT_RING (1); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
OUT_RING (0x8006); | |||
BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 8); | |||
OUT_RING (0xff); | |||
OUT_RING (0x207); | |||
OUT_RING (0); | |||
OUT_RING (0xff); | |||
OUT_RING (0x1e00); | |||
OUT_RING (0x1e00); | |||
OUT_RING (0x1e00); | |||
OUT_RING (0x1d01); | |||
BEGIN_RING(celsius, NV10TCL_NORMALIZE_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 2); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_LIGHT_MODEL, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_COLOR_CONTROL, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_ENABLED_LIGHTS, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1); | |||
OUT_RING (0x201); | |||
BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); | |||
OUT_RING (8); | |||
BEGIN_RING(celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_LINE_WIDTH, 1); | |||
OUT_RING (8); | |||
BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); | |||
OUT_RING (0x1b02); | |||
OUT_RING (0x1b02); | |||
BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); | |||
OUT_RING (0x405); | |||
OUT_RING (0x901); | |||
BEGIN_RING(celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_CLIP_PLANE_ENABLE(0), 8); | |||
for (i=0;i<8;i++) { | |||
OUT_RING (0); | |||
} | |||
BEGIN_RING(celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3); | |||
OUT_RING (0x3fc00000); /* -1.50 */ | |||
OUT_RING (0xbdb8aa0a); /* -0.09 */ | |||
OUT_RING (0); /* 0.00 */ | |||
BEGIN_RING(celsius, NV10TCL_NOP, 1); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_FOG_MODE, 2); | |||
OUT_RING (0x802); | |||
OUT_RING (2); | |||
/* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when | |||
* using texturing, except when using the texture matrix | |||
*/ | |||
BEGIN_RING(celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1); | |||
OUT_RING (6); | |||
BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); | |||
OUT_RING (0x01010101); | |||
/* Set vertex component */ | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_COL_4F_R, 4); | |||
OUT_RINGf (1.0); | |||
OUT_RINGf (1.0); | |||
OUT_RINGf (1.0); | |||
OUT_RINGf (1.0); | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_COL2_3F_R, 3); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_NOR_3F_X, 3); | |||
OUT_RING (0); | |||
OUT_RING (0); | |||
OUT_RINGf (1.0); | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_TX0_4F_S, 4); | |||
OUT_RINGf (0.0); | |||
OUT_RINGf (0.0); | |||
OUT_RINGf (0.0); | |||
OUT_RINGf (1.0); | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_TX1_4F_S, 4); | |||
OUT_RINGf (0.0); | |||
OUT_RINGf (0.0); | |||
OUT_RINGf (0.0); | |||
OUT_RINGf (1.0); | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_FOG_1F, 1); | |||
OUT_RINGf (0.0); | |||
BEGIN_RING(celsius, NV10TCL_EDGEFLAG_ENABLE, 1); | |||
OUT_RING (1); | |||
FIRE_RING (); | |||
return TRUE; | |||
} | |||
struct pipe_context * | |||
nv10_create(struct pipe_screen *screen, unsigned pctx_id) | |||
{ | |||
struct pipe_winsys *pipe_winsys = screen->winsys; | |||
struct nouveau_winsys *nvws = nv10_screen(screen)->nvws; | |||
unsigned chipset = nv10_screen(screen)->chipset; | |||
struct nv10_context *nv10; | |||
int celsius_class = 0, ret; | |||
if (chipset>=0x20) | |||
celsius_class=NV11TCL; | |||
else if (chipset>=0x17) | |||
celsius_class=NV17TCL; | |||
else if (chipset>=0x11) | |||
celsius_class=NV11TCL; | |||
else | |||
celsius_class=NV10TCL; | |||
nv10 = CALLOC_STRUCT(nv10_context); | |||
if (!nv10) | |||
return NULL; | |||
nv10->chipset = chipset; | |||
nv10->nvws = nvws; | |||
/* Notifier for sync purposes */ | |||
ret = nvws->notifier_alloc(nvws, 1, &nv10->sync); | |||
if (ret) { | |||
NOUVEAU_ERR("Error creating notifier object: %d\n", ret); | |||
nv10_destroy(&nv10->pipe); | |||
return NULL; | |||
} | |||
/* Vtxprog resources */ | |||
if (nvws->res_init(&nv10->vertprog.exec_heap, 0, 512) || | |||
nvws->res_init(&nv10->vertprog.data_heap, 0, 256)) { | |||
nv10_destroy(&nv10->pipe); | |||
return NULL; | |||
} | |||
/* Static celsius initialisation */ | |||
if (!nv10_init_hwctx(nv10, celsius_class)) { | |||
nv10_destroy(&nv10->pipe); | |||
return NULL; | |||
} | |||
/* Pipe context setup */ | |||
nv10->pipe.winsys = pipe_winsys; | |||
nv10->pipe.destroy = nv10_destroy; | |||
nv10->pipe.draw_arrays = nv10_draw_arrays; | |||
nv10->pipe.draw_elements = nv10_draw_elements; | |||
nv10->pipe.clear = nv10_clear; | |||
nv10->pipe.flush = nv10_flush; | |||
nv10_init_surface_functions(nv10); | |||
nv10_init_state_functions(nv10); | |||
nv10->draw = draw_create(); | |||
assert(nv10->draw); | |||
draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10)); | |||
return &nv10->pipe; | |||
} | |||
@@ -0,0 +1,127 @@ | |||
#ifndef __NV10_CONTEXT_H__ | |||
#define __NV10_CONTEXT_H__ | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_state.h" | |||
#include "draw/draw_vertex.h" | |||
#include "nouveau/nouveau_winsys.h" | |||
#include "nouveau/nouveau_gldefs.h" | |||
#define NOUVEAU_PUSH_CONTEXT(ctx) \ | |||
struct nv10_context *ctx = nv10 | |||
#include "nouveau/nouveau_push.h" | |||
#include "nv10_state.h" | |||
#define NOUVEAU_ERR(fmt, args...) \ | |||
fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args); | |||
#define NOUVEAU_MSG(fmt, args...) \ | |||
fprintf(stderr, "nouveau: "fmt, ##args); | |||
#define NV10_NEW_VERTPROG (1 << 1) | |||
#define NV10_NEW_FRAGPROG (1 << 2) | |||
#define NV10_NEW_ARRAYS (1 << 3) | |||
#define NV10_NEW_VBO (1 << 4) | |||
struct nv10_context { | |||
struct pipe_context pipe; | |||
struct nouveau_winsys *nvws; | |||
struct draw_context *draw; | |||
int chipset; | |||
struct nouveau_grobj *celsius; | |||
struct nouveau_notifier *sync; | |||
uint32_t dirty; | |||
struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; | |||
struct nv10_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; | |||
unsigned dirty_samplers; | |||
unsigned fp_samplers; | |||
unsigned vp_samplers; | |||
uint32_t rt_enable; | |||
struct pipe_buffer *rt[4]; | |||
struct pipe_buffer *zeta; | |||
struct { | |||
struct pipe_buffer *buffer; | |||
uint32_t format; | |||
} tex[16]; | |||
unsigned vb_enable; | |||
struct { | |||
struct pipe_buffer *buffer; | |||
unsigned delta; | |||
} vb[16]; | |||
struct vertex_info vertex_info; | |||
struct { | |||
struct nouveau_resource *exec_heap; | |||
struct nouveau_resource *data_heap; | |||
struct nv10_vertex_program *active; | |||
struct nv10_vertex_program *current; | |||
struct pipe_buffer *constant_buf; | |||
} vertprog; | |||
struct { | |||
struct nv10_fragment_program *active; | |||
struct nv10_fragment_program *current; | |||
struct pipe_buffer *constant_buf; | |||
} fragprog; | |||
struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX]; | |||
struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX]; | |||
}; | |||
static INLINE struct nv10_context * | |||
nv10_context(struct pipe_context *pipe) | |||
{ | |||
return (struct nv10_context *)pipe; | |||
} | |||
extern void nv10_init_state_functions(struct nv10_context *nv10); | |||
extern void nv10_init_surface_functions(struct nv10_context *nv10); | |||
extern void nv10_init_miptree_functions(struct pipe_screen *screen); | |||
/* nv10_clear.c */ | |||
extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps, | |||
unsigned clearValue); | |||
/* nv10_draw.c */ | |||
extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10); | |||
/* nv10_fragprog.c */ | |||
extern void nv10_fragprog_bind(struct nv10_context *, | |||
struct nv10_fragment_program *); | |||
extern void nv10_fragprog_destroy(struct nv10_context *, | |||
struct nv10_fragment_program *); | |||
/* nv10_fragtex.c */ | |||
extern void nv10_fragtex_bind(struct nv10_context *); | |||
/* nv10_prim_vbuf.c */ | |||
struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ); | |||
/* nv10_state.c and friends */ | |||
extern void nv10_emit_hw_state(struct nv10_context *nv10); | |||
extern void nv10_state_tex_update(struct nv10_context *nv10); | |||
/* nv10_vbo.c */ | |||
extern boolean nv10_draw_arrays(struct pipe_context *, unsigned mode, | |||
unsigned start, unsigned count); | |||
extern boolean nv10_draw_elements( struct pipe_context *pipe, | |||
struct pipe_buffer *indexBuffer, | |||
unsigned indexSize, | |||
unsigned prim, unsigned start, unsigned count); | |||
#endif |
@@ -0,0 +1,22 @@ | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "tgsi/util/tgsi_parse.h" | |||
#include "tgsi/util/tgsi_util.h" | |||
#include "nv10_context.h" | |||
void | |||
nv10_fragprog_bind(struct nv10_context *nv10, struct nv10_fragment_program *fp) | |||
{ | |||
} | |||
void | |||
nv10_fragprog_destroy(struct nv10_context *nv10, | |||
struct nv10_fragment_program *fp) | |||
{ | |||
} | |||
@@ -0,0 +1,145 @@ | |||
#include "nv10_context.h" | |||
static INLINE int log2i(int i) | |||
{ | |||
int r = 0; | |||
if (i & 0xffff0000) { | |||
i >>= 16; | |||
r += 16; | |||
} | |||
if (i & 0x0000ff00) { | |||
i >>= 8; | |||
r += 8; | |||
} | |||
if (i & 0x000000f0) { | |||
i >>= 4; | |||
r += 4; | |||
} | |||
if (i & 0x0000000c) { | |||
i >>= 2; | |||
r += 2; | |||
} | |||
if (i & 0x00000002) { | |||
r += 1; | |||
} | |||
return r; | |||
} | |||
#define _(m,tf) \ | |||
{ \ | |||
TRUE, \ | |||
PIPE_FORMAT_##m, \ | |||
NV10TCL_TX_FORMAT_FORMAT_##tf, \ | |||
} | |||
struct nv10_texture_format { | |||
boolean defined; | |||
uint pipe; | |||
int format; | |||
}; | |||
static struct nv10_texture_format | |||
nv10_texture_formats[] = { | |||
_(A8R8G8B8_UNORM, A8R8G8B8), | |||
_(A1R5G5B5_UNORM, A1R5G5B5), | |||
_(A4R4G4B4_UNORM, A4R4G4B4), | |||
_(U_L8 , L8 ), | |||
_(U_A8 , A8 ), | |||
_(U_A8_L8 , A8L8 ), | |||
// _(RGB_DXT1 , DXT1, ), | |||
// _(RGBA_DXT1 , DXT1, ), | |||
// _(RGBA_DXT3 , DXT3, ), | |||
// _(RGBA_DXT5 , DXT5, ), | |||
{}, | |||
}; | |||
static struct nv10_texture_format * | |||
nv10_fragtex_format(uint pipe_format) | |||
{ | |||
struct nv10_texture_format *tf = nv10_texture_formats; | |||
while (tf->defined) { | |||
if (tf->pipe == pipe_format) | |||
return tf; | |||
tf++; | |||
} | |||
return NULL; | |||
} | |||
static void | |||
nv10_fragtex_build(struct nv10_context *nv10, int unit) | |||
{ | |||
struct nv10_sampler_state *ps = nv10->tex_sampler[unit]; | |||
struct nv10_miptree *nv10mt = nv10->tex_miptree[unit]; | |||
struct pipe_texture *pt = &nv10mt->base; | |||
struct nv10_texture_format *tf; | |||
uint32_t txf, txs, txp; | |||
tf = nv10_fragtex_format(pt->format); | |||
if (!tf || !tf->defined) { | |||
NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format); | |||
return; | |||
} | |||
txf = tf->format << 8; | |||
txf |= (pt->last_level + 1) << 16; | |||
txf |= log2i(pt->width[0]) << 20; | |||
txf |= log2i(pt->height[0]) << 24; | |||
txf |= log2i(pt->depth[0]) << 28; | |||
txf |= 8; | |||
switch (pt->target) { | |||
case PIPE_TEXTURE_CUBE: | |||
txf |= NV10TCL_TX_FORMAT_CUBE_MAP; | |||
/* fall-through */ | |||
case PIPE_TEXTURE_2D: | |||
txf |= (2<<4); | |||
break; | |||
case PIPE_TEXTURE_1D: | |||
txf |= (1<<4); | |||
break; | |||
default: | |||
NOUVEAU_ERR("Unknown target %d\n", pt->target); | |||
return; | |||
} | |||
BEGIN_RING(celsius, NV10TCL_TX_OFFSET(unit), 8); | |||
OUT_RELOCl(nv10mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); | |||
OUT_RELOCd(nv10mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/); | |||
OUT_RING (ps->wrap); | |||
OUT_RING (0x40000000); /* enable */ | |||
OUT_RING (txs); | |||
OUT_RING (ps->filt | 0x2000 /* magic */); | |||
OUT_RING ((pt->width[0] << 16) | pt->height[0]); | |||
OUT_RING (ps->bcol); | |||
} | |||
void | |||
nv10_fragtex_bind(struct nv10_context *nv10) | |||
{ | |||
struct nv10_fragment_program *fp = nv10->fragprog.active; | |||
unsigned samplers, unit; | |||
samplers = nv10->fp_samplers & ~fp->samplers; | |||
while (samplers) { | |||
unit = ffs(samplers) - 1; | |||
samplers &= ~(1 << unit); | |||
BEGIN_RING(celsius, NV10TCL_TX_ENABLE(unit), 1); | |||
OUT_RING (0); | |||
} | |||
samplers = nv10->dirty_samplers & fp->samplers; | |||
while (samplers) { | |||
unit = ffs(samplers) - 1; | |||
samplers &= ~(1 << unit); | |||
nv10_fragtex_build(nv10, unit); | |||
} | |||
nv10->fp_samplers = fp->samplers; | |||
} | |||
@@ -0,0 +1,134 @@ | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_inlines.h" | |||
#include "nv10_context.h" | |||
#include "nv10_screen.h" | |||
static void | |||
nv10_miptree_layout(struct nv10_miptree *nv10mt) | |||
{ | |||
struct pipe_texture *pt = &nv10mt->base; | |||
boolean swizzled = FALSE; | |||
uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0]; | |||
uint offset = 0; | |||
int nr_faces, l, f; | |||
if (pt->target == PIPE_TEXTURE_CUBE) { | |||
nr_faces = 6; | |||
} else { | |||
nr_faces = 1; | |||
} | |||
for (l = 0; l <= pt->last_level; l++) { | |||
pt->width[l] = width; | |||
pt->height[l] = height; | |||
pt->depth[l] = depth; | |||
if (swizzled) | |||
nv10mt->level[l].pitch = pt->width[l] * pt->cpp; | |||
else | |||
nv10mt->level[l].pitch = pt->width[0] * pt->cpp; | |||
nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63; | |||
nv10mt->level[l].image_offset = | |||
CALLOC(nr_faces, sizeof(unsigned)); | |||
width = MAX2(1, width >> 1); | |||
height = MAX2(1, height >> 1); | |||
depth = MAX2(1, depth >> 1); | |||
} | |||
for (f = 0; f < nr_faces; f++) { | |||
for (l = 0; l <= pt->last_level; l++) { | |||
nv10mt->level[l].image_offset[f] = offset; | |||
offset += nv10mt->level[l].pitch * pt->height[l]; | |||
} | |||
} | |||
nv10mt->total_size = offset; | |||
} | |||
static struct pipe_texture * | |||
nv10_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt) | |||
{ | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct nv10_miptree *mt; | |||
mt = MALLOC(sizeof(struct nv10_miptree)); | |||
if (!mt) | |||
return NULL; | |||
mt->base = *pt; | |||
mt->base.refcount = 1; | |||
mt->base.screen = screen; | |||
nv10_miptree_layout(mt); | |||
mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, | |||
mt->total_size); | |||
if (!mt->buffer) { | |||
free(mt); | |||
return NULL; | |||
} | |||
return &mt->base; | |||
} | |||
static void | |||
nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt) | |||
{ | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct pipe_texture *mt = *pt; | |||
*pt = NULL; | |||
if (--mt->refcount <= 0) { | |||
struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt; | |||
int l; | |||
pipe_buffer_reference(ws, &nv10mt->buffer, NULL); | |||
for (l = 0; l <= mt->last_level; l++) { | |||
if (nv10mt->level[l].image_offset) | |||
free(nv10mt->level[l].image_offset); | |||
} | |||
free(nv10mt); | |||
} | |||
} | |||
static struct pipe_surface * | |||
nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt, | |||
unsigned face, unsigned level, unsigned zslice) | |||
{ | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt; | |||
struct pipe_surface *ps; | |||
ps = ws->surface_alloc(ws); | |||
if (!ps) | |||
return NULL; | |||
pipe_buffer_reference(ws, &ps->buffer, nv10mt->buffer); | |||
ps->format = pt->format; | |||
ps->cpp = pt->cpp; | |||
ps->width = pt->width[level]; | |||
ps->height = pt->height[level]; | |||
ps->pitch = nv10mt->level[level].pitch / ps->cpp; | |||
if (pt->target == PIPE_TEXTURE_CUBE) { | |||
ps->offset = nv10mt->level[level].image_offset[face]; | |||
} else { | |||
ps->offset = nv10mt->level[level].image_offset[0]; | |||
} | |||
return ps; | |||
} | |||
void | |||
nv10_init_miptree_functions(struct pipe_screen *screen) | |||
{ | |||
struct nv10_screen *nv10screen = nv10_screen(screen); | |||
nv10screen->screen.texture_create = nv10_miptree_create; | |||
nv10screen->screen.texture_release = nv10_miptree_release; | |||
nv10screen->screen.get_tex_surface = nv10_miptree_surface_get; | |||
} | |||
@@ -0,0 +1,224 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
/** | |||
* \file | |||
* Build post-transformation, post-clipping vertex buffers and element | |||
* lists by hooking into the end of the primitive pipeline and | |||
* manipulating the vertex_id field in the vertex headers. | |||
* | |||
* XXX: work in progress | |||
* | |||
* \author José Fonseca <jrfonseca@tungstengraphics.com> | |||
* \author Keith Whitwell <keith@tungstengraphics.com> | |||
*/ | |||
#include "draw/draw_vbuf.h" | |||
#include "pipe/p_debug.h" | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_inlines.h" | |||
#include "pipe/p_winsys.h" | |||
#include "nv10_context.h" | |||
#include "nv10_state.h" | |||
/** | |||
* Primitive renderer for nv10. | |||
*/ | |||
struct nv10_vbuf_render { | |||
struct vbuf_render base; | |||
struct nv10_context *nv10; | |||
/** Vertex buffer */ | |||
struct pipe_buffer* buffer; | |||
/** Vertex size in bytes */ | |||
unsigned vertex_size; | |||
/** Hardware primitive */ | |||
unsigned hwprim; | |||
}; | |||
/** | |||
* Basically a cast wrapper. | |||
*/ | |||
static INLINE struct nv10_vbuf_render * | |||
nv10_vbuf_render( struct vbuf_render *render ) | |||
{ | |||
assert(render); | |||
return (struct nv10_vbuf_render *)render; | |||
} | |||
static const struct vertex_info * | |||
nv10_vbuf_render_get_vertex_info( struct vbuf_render *render ) | |||
{ | |||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); | |||
struct nv10_context *nv10 = nv10_render->nv10; | |||
return &nv10->vertex_info; | |||
} | |||
static void * | |||
nv10_vbuf_render_allocate_vertices( struct vbuf_render *render, | |||
ushort vertex_size, | |||
ushort nr_vertices ) | |||
{ | |||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); | |||
struct nv10_context *nv10 = nv10_render->nv10; | |||
struct pipe_winsys *winsys = nv10->pipe.winsys; | |||
size_t size = (size_t)vertex_size * (size_t)nr_vertices; | |||
assert(!nv10_render->buffer); | |||
nv10_render->buffer = winsys->buffer_create(winsys, 64, PIPE_BUFFER_USAGE_VERTEX, size); | |||
nv10->dirty |= NV10_NEW_VBO; | |||
return winsys->buffer_map(winsys, | |||
nv10_render->buffer, | |||
PIPE_BUFFER_USAGE_CPU_WRITE); | |||
} | |||
static void | |||
nv10_vbuf_render_set_primitive( struct vbuf_render *render, | |||
unsigned prim ) | |||
{ | |||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); | |||
nv10_render->hwprim = prim + 1; | |||
} | |||
static void | |||
nv10_vbuf_render_draw( struct vbuf_render *render, | |||
const ushort *indices, | |||
uint nr_indices) | |||
{ | |||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); | |||
struct nv10_context *nv10 = nv10_render->nv10; | |||
int push, i; | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_ARRAY_OFFSET_POS, 1); | |||
OUT_RELOCl(nv10_render->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD); | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); | |||
OUT_RING(nv10_render->hwprim); | |||
if (nr_indices & 1) { | |||
BEGIN_RING(celsius, NV10TCL_VB_ELEMENT_U32, 1); | |||
OUT_RING (indices[0]); | |||
indices++; nr_indices--; | |||
} | |||
while (nr_indices) { | |||
// XXX too big ? | |||
push = MIN2(nr_indices, 2047 * 2); | |||
BEGIN_RING_NI(celsius, NV10TCL_VB_ELEMENT_U16, push >> 1); | |||
for (i = 0; i < push; i+=2) | |||
OUT_RING((indices[i+1] << 16) | indices[i]); | |||
nr_indices -= push; | |||
indices += push; | |||
} | |||
BEGIN_RING(celsius, NV10TCL_VERTEX_BUFFER_BEGIN_END, 1); | |||
OUT_RING (0); | |||
} | |||
static void | |||
nv10_vbuf_render_release_vertices( struct vbuf_render *render, | |||
void *vertices, | |||
unsigned vertex_size, | |||
unsigned vertices_used ) | |||
{ | |||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); | |||
struct nv10_context *nv10 = nv10_render->nv10; | |||
struct pipe_winsys *winsys = nv10->pipe.winsys; | |||
assert(nv10_render->buffer); | |||
winsys->buffer_unmap(winsys, nv10_render->buffer); | |||
pipe_buffer_reference(winsys, &nv10_render->buffer, NULL); | |||
} | |||
static void | |||
nv10_vbuf_render_destroy( struct vbuf_render *render ) | |||
{ | |||
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render); | |||
FREE(nv10_render); | |||
} | |||
/** | |||
* Create a new primitive render. | |||
*/ | |||
static struct vbuf_render * | |||
nv10_vbuf_render_create( struct nv10_context *nv10 ) | |||
{ | |||
struct nv10_vbuf_render *nv10_render = CALLOC_STRUCT(nv10_vbuf_render); | |||
nv10_render->nv10 = nv10; | |||
nv10_render->base.max_vertex_buffer_bytes = 1024*1024; | |||
nv10_render->base.max_indices = 64*1024; | |||
nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info; | |||
nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices; | |||
nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive; | |||
nv10_render->base.draw = nv10_vbuf_render_draw; | |||
nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices; | |||
nv10_render->base.destroy = nv10_vbuf_render_destroy; | |||
return &nv10_render->base; | |||
} | |||
/** | |||
* Create a new primitive vbuf/render stage. | |||
*/ | |||
struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 ) | |||
{ | |||
struct vbuf_render *render; | |||
struct draw_stage *stage; | |||
render = nv10_vbuf_render_create(nv10); | |||
if(!render) | |||
return NULL; | |||
stage = draw_vbuf_stage( nv10->draw, render ); | |||
if(!stage) { | |||
render->destroy(render); | |||
return NULL; | |||
} | |||
return stage; | |||
} |
@@ -0,0 +1,150 @@ | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_util.h" | |||
#include "nv10_context.h" | |||
#include "nv10_screen.h" | |||
static const char * | |||
nv10_screen_get_name(struct pipe_screen *screen) | |||
{ | |||
struct nv10_screen *nv10screen = nv10_screen(screen); | |||
static char buffer[128]; | |||
snprintf(buffer, sizeof(buffer), "NV%02X", nv10screen->chipset); | |||
return buffer; | |||
} | |||
static const char * | |||
nv10_screen_get_vendor(struct pipe_screen *screen) | |||
{ | |||
return "nouveau"; | |||
} | |||
static int | |||
nv10_screen_get_param(struct pipe_screen *screen, int param) | |||
{ | |||
switch (param) { | |||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: | |||
return 2; | |||
case PIPE_CAP_NPOT_TEXTURES: | |||
return 0; | |||
case PIPE_CAP_TWO_SIDED_STENCIL: | |||
return 0; | |||
case PIPE_CAP_GLSL: | |||
return 0; | |||
case PIPE_CAP_S3TC: | |||
return 0; | |||
case PIPE_CAP_ANISOTROPIC_FILTER: | |||
return 1; | |||
case PIPE_CAP_POINT_SPRITE: | |||
return 0; | |||
case PIPE_CAP_MAX_RENDER_TARGETS: | |||
return 1; | |||
case PIPE_CAP_OCCLUSION_QUERY: | |||
return 0; | |||
case PIPE_CAP_TEXTURE_SHADOW_MAP: | |||
return 0; | |||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: | |||
return 12; | |||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: | |||
return 0; | |||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: | |||
return 12; | |||
default: | |||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); | |||
return 0; | |||
} | |||
} | |||
static float | |||
nv10_screen_get_paramf(struct pipe_screen *screen, int param) | |||
{ | |||
switch (param) { | |||
case PIPE_CAP_MAX_LINE_WIDTH: | |||
case PIPE_CAP_MAX_LINE_WIDTH_AA: | |||
return 10.0; | |||
case PIPE_CAP_MAX_POINT_WIDTH: | |||
case PIPE_CAP_MAX_POINT_WIDTH_AA: | |||
return 64.0; | |||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: | |||
return 2.0; | |||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: | |||
return 4.0; | |||
case PIPE_CAP_BITMAP_TEXCOORD_BIAS: | |||
return 0.0; | |||
default: | |||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); | |||
return 0.0; | |||
} | |||
} | |||
static boolean | |||
nv10_screen_is_format_supported(struct pipe_screen *screen, | |||
enum pipe_format format, uint type) | |||
{ | |||
switch (type) { | |||
case PIPE_SURFACE: | |||
switch (format) { | |||
case PIPE_FORMAT_A8R8G8B8_UNORM: | |||
case PIPE_FORMAT_R5G6B5_UNORM: | |||
case PIPE_FORMAT_Z24S8_UNORM: | |||
case PIPE_FORMAT_Z16_UNORM: | |||
return TRUE; | |||
default: | |||
break; | |||
} | |||
break; | |||
case PIPE_TEXTURE: | |||
switch (format) { | |||
case PIPE_FORMAT_A8R8G8B8_UNORM: | |||
case PIPE_FORMAT_A1R5G5B5_UNORM: | |||
case PIPE_FORMAT_A4R4G4B4_UNORM: | |||
case PIPE_FORMAT_R5G6B5_UNORM: | |||
case PIPE_FORMAT_U_L8: | |||
case PIPE_FORMAT_U_A8: | |||
case PIPE_FORMAT_U_I8: | |||
return TRUE; | |||
default: | |||
break; | |||
} | |||
break; | |||
default: | |||
assert(0); | |||
}; | |||
return FALSE; | |||
} | |||
static void | |||
nv10_screen_destroy(struct pipe_screen *screen) | |||
{ | |||
FREE(screen); | |||
} | |||
struct pipe_screen * | |||
nv10_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws, | |||
unsigned chipset) | |||
{ | |||
struct nv10_screen *nv10screen = CALLOC_STRUCT(nv10_screen); | |||
if (!nv10screen) | |||
return NULL; | |||
nv10screen->chipset = chipset; | |||
nv10screen->nvws = nvws; | |||
nv10screen->screen.winsys = winsys; | |||
nv10screen->screen.destroy = nv10_screen_destroy; | |||
nv10screen->screen.get_name = nv10_screen_get_name; | |||
nv10screen->screen.get_vendor = nv10_screen_get_vendor; | |||
nv10screen->screen.get_param = nv10_screen_get_param; | |||
nv10screen->screen.get_paramf = nv10_screen_get_paramf; | |||
nv10screen->screen.is_format_supported = | |||
nv10_screen_is_format_supported; | |||
nv10_init_miptree_functions(&nv10screen->screen); | |||
return &nv10screen->screen; | |||
} | |||
@@ -0,0 +1,19 @@ | |||
#ifndef __NV10_SCREEN_H__ | |||
#define __NV10_SCREEN_H__ | |||
#include "pipe/p_screen.h" | |||
struct nv10_screen { | |||
struct pipe_screen screen; | |||
struct nouveau_winsys *nvws; | |||
unsigned chipset; | |||
}; | |||
static INLINE struct nv10_screen * | |||
nv10_screen(struct pipe_screen *screen) | |||
{ | |||
return (struct nv10_screen *)screen; | |||
} | |||
#endif |
@@ -0,0 +1,697 @@ | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_shader_tokens.h" | |||
#include "nv10_context.h" | |||
#include "nv10_state.h" | |||
static void nv10_vertex_layout(struct pipe_context* pipe) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
const struct pipe_shader_state *fs = nv10->fragprog.current->pipe; | |||
uint32_t src = 0; | |||
int i; | |||
struct vertex_info vinfo; | |||
memset(&vinfo, 0, sizeof(vinfo)); | |||
for (i = 0; i < fs->num_inputs; i++) { | |||
switch (fs->input_semantic_name[i]) { | |||
case TGSI_SEMANTIC_POSITION: | |||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); | |||
break; | |||
case TGSI_SEMANTIC_COLOR: | |||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++); | |||
break; | |||
default: | |||
case TGSI_SEMANTIC_GENERIC: | |||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); | |||
break; | |||
case TGSI_SEMANTIC_FOG: | |||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++); | |||
break; | |||
} | |||
} | |||
draw_compute_vertex_size(&vinfo); | |||
} | |||
static void * | |||
nv10_blend_state_create(struct pipe_context *pipe, | |||
const struct pipe_blend_state *cso) | |||
{ | |||
struct nv10_blend_state *cb; | |||
cb = malloc(sizeof(struct nv10_blend_state)); | |||
cb->b_enable = cso->blend_enable ? 1 : 0; | |||
cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) | | |||
(nvgl_blend_func(cso->rgb_src_factor))); | |||
cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) | | |||
(nvgl_blend_func(cso->rgb_dst_factor))); | |||
cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) | | |||
((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) | | |||
((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) | | |||
((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0)); | |||
cb->d_enable = cso->dither ? 1 : 0; | |||
return (void *)cb; | |||
} | |||
static void | |||
nv10_blend_state_bind(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nv10_blend_state *cb = hwcso; | |||
BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1); | |||
OUT_RING (cb->d_enable); | |||
BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3); | |||
OUT_RING (cb->b_enable); | |||
OUT_RING (cb->b_srcfunc); | |||
OUT_RING (cb->b_dstfunc); | |||
BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1); | |||
OUT_RING (cb->c_mask); | |||
} | |||
static void | |||
nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
free(hwcso); | |||
} | |||
static INLINE unsigned | |||
wrap_mode(unsigned wrap) { | |||
unsigned ret; | |||
switch (wrap) { | |||
case PIPE_TEX_WRAP_REPEAT: | |||
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT; | |||
break; | |||
case PIPE_TEX_WRAP_MIRROR_REPEAT: | |||
ret = NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT; | |||
break; | |||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE: | |||
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE; | |||
break; | |||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER: | |||
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER; | |||
break; | |||
case PIPE_TEX_WRAP_CLAMP: | |||
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP; | |||
break; | |||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: | |||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: | |||
case PIPE_TEX_WRAP_MIRROR_CLAMP: | |||
default: | |||
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap); | |||
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT; | |||
break; | |||
} | |||
return ret >> NV10TCL_TX_FORMAT_WRAP_S_SHIFT; | |||
} | |||
static void * | |||
nv10_sampler_state_create(struct pipe_context *pipe, | |||
const struct pipe_sampler_state *cso) | |||
{ | |||
struct nv10_sampler_state *ps; | |||
uint32_t filter = 0; | |||
ps = malloc(sizeof(struct nv10_sampler_state)); | |||
ps->wrap = ((wrap_mode(cso->wrap_s) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT) | | |||
(wrap_mode(cso->wrap_t) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT)); | |||
ps->en = 0; | |||
if (cso->max_anisotropy > 1.0) { | |||
/* no idea, binary driver sets it, works without it.. meh.. */ | |||
ps->wrap |= (1 << 5); | |||
/* if (cso->max_anisotropy >= 16.0) { | |||
ps->en |= NV10TCL_TX_ENABLE_ANISO_16X; | |||
} else | |||
if (cso->max_anisotropy >= 12.0) { | |||
ps->en |= NV10TCL_TX_ENABLE_ANISO_12X; | |||
} else | |||
if (cso->max_anisotropy >= 10.0) { | |||
ps->en |= NV10TCL_TX_ENABLE_ANISO_10X; | |||
} else | |||
if (cso->max_anisotropy >= 8.0) { | |||
ps->en |= NV10TCL_TX_ENABLE_ANISO_8X; | |||
} else | |||
if (cso->max_anisotropy >= 6.0) { | |||
ps->en |= NV10TCL_TX_ENABLE_ANISO_6X; | |||
} else | |||
if (cso->max_anisotropy >= 4.0) { | |||
ps->en |= NV10TCL_TX_ENABLE_ANISO_4X; | |||
} else { | |||
ps->en |= NV10TCL_TX_ENABLE_ANISO_2X; | |||
}*/ | |||
} | |||
switch (cso->mag_img_filter) { | |||
case PIPE_TEX_FILTER_LINEAR: | |||
filter |= NV10TCL_TX_FILTER_MAGNIFY_LINEAR; | |||
break; | |||
case PIPE_TEX_FILTER_NEAREST: | |||
default: | |||
filter |= NV10TCL_TX_FILTER_MAGNIFY_NEAREST; | |||
break; | |||
} | |||
switch (cso->min_img_filter) { | |||
case PIPE_TEX_FILTER_LINEAR: | |||
switch (cso->min_mip_filter) { | |||
case PIPE_TEX_MIPFILTER_NEAREST: | |||
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST; | |||
break; | |||
case PIPE_TEX_MIPFILTER_LINEAR: | |||
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR; | |||
break; | |||
case PIPE_TEX_MIPFILTER_NONE: | |||
default: | |||
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR; | |||
break; | |||
} | |||
break; | |||
case PIPE_TEX_FILTER_NEAREST: | |||
default: | |||
switch (cso->min_mip_filter) { | |||
case PIPE_TEX_MIPFILTER_NEAREST: | |||
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST; | |||
break; | |||
case PIPE_TEX_MIPFILTER_LINEAR: | |||
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR; | |||
break; | |||
case PIPE_TEX_MIPFILTER_NONE: | |||
default: | |||
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST; | |||
break; | |||
} | |||
break; | |||
} | |||
ps->filt = filter; | |||
/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) { | |||
switch (cso->compare_func) { | |||
case PIPE_FUNC_NEVER: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER; | |||
break; | |||
case PIPE_FUNC_GREATER: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER; | |||
break; | |||
case PIPE_FUNC_EQUAL: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL; | |||
break; | |||
case PIPE_FUNC_GEQUAL: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL; | |||
break; | |||
case PIPE_FUNC_LESS: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS; | |||
break; | |||
case PIPE_FUNC_NOTEQUAL: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL; | |||
break; | |||
case PIPE_FUNC_LEQUAL: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL; | |||
break; | |||
case PIPE_FUNC_ALWAYS: | |||
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS; | |||
break; | |||
default: | |||
break; | |||
} | |||
}*/ | |||
ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) | | |||
(float_to_ubyte(cso->border_color[0]) << 16) | | |||
(float_to_ubyte(cso->border_color[1]) << 8) | | |||
(float_to_ubyte(cso->border_color[2]) << 0)); | |||
return (void *)ps; | |||
} | |||
static void | |||
nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
unsigned unit; | |||
for (unit = 0; unit < nr; unit++) { | |||
nv10->tex_sampler[unit] = sampler[unit]; | |||
nv10->dirty_samplers |= (1 << unit); | |||
} | |||
} | |||
static void | |||
nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
free(hwcso); | |||
} | |||
static void | |||
nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr, | |||
struct pipe_texture **miptree) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
unsigned unit; | |||
for (unit = 0; unit < nr; unit++) { | |||
nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit]; | |||
nv10->dirty_samplers |= (1 << unit); | |||
} | |||
} | |||
static void * | |||
nv10_rasterizer_state_create(struct pipe_context *pipe, | |||
const struct pipe_rasterizer_state *cso) | |||
{ | |||
struct nv10_rasterizer_state *rs; | |||
int i; | |||
/*XXX: ignored: | |||
* light_twoside | |||
* offset_cw/ccw -nohw | |||
* scissor | |||
* point_smooth -nohw | |||
* multisample | |||
* offset_units / offset_scale | |||
*/ | |||
rs = malloc(sizeof(struct nv10_rasterizer_state)); | |||
rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01; | |||
rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff; | |||
rs->line_smooth_en = cso->line_smooth ? 1 : 0; | |||
rs->point_size = *(uint32_t*)&cso->point_size; | |||
rs->poly_smooth_en = cso->poly_smooth ? 1 : 0; | |||
if (cso->front_winding == PIPE_WINDING_CCW) { | |||
rs->front_face = NV10TCL_FRONT_FACE_CCW; | |||
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw); | |||
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw); | |||
} else { | |||
rs->front_face = NV10TCL_FRONT_FACE_CW; | |||
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw); | |||
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw); | |||
} | |||
switch (cso->cull_mode) { | |||
case PIPE_WINDING_CCW: | |||
rs->cull_face_en = 1; | |||
if (cso->front_winding == PIPE_WINDING_CCW) | |||
rs->cull_face = NV10TCL_CULL_FACE_FRONT; | |||
else | |||
rs->cull_face = NV10TCL_CULL_FACE_BACK; | |||
break; | |||
case PIPE_WINDING_CW: | |||
rs->cull_face_en = 1; | |||
if (cso->front_winding == PIPE_WINDING_CW) | |||
rs->cull_face = NV10TCL_CULL_FACE_FRONT; | |||
else | |||
rs->cull_face = NV10TCL_CULL_FACE_BACK; | |||
break; | |||
case PIPE_WINDING_BOTH: | |||
rs->cull_face_en = 1; | |||
rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK; | |||
break; | |||
case PIPE_WINDING_NONE: | |||
default: | |||
rs->cull_face_en = 0; | |||
rs->cull_face = 0; | |||
break; | |||
} | |||
if (cso->point_sprite) { | |||
rs->point_sprite = (1 << 0); | |||
for (i = 0; i < 8; i++) { | |||
if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) | |||
rs->point_sprite |= (1 << (8 + i)); | |||
} | |||
} else { | |||
rs->point_sprite = 0; | |||
} | |||
return (void *)rs; | |||
} | |||
static void | |||
nv10_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nv10_rasterizer_state *rs = hwcso; | |||
BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2); | |||
OUT_RING (rs->shade_model); | |||
OUT_RING (rs->line_width); | |||
BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1); | |||
OUT_RING (rs->point_size); | |||
BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2); | |||
OUT_RING (rs->poly_mode_front); | |||
OUT_RING (rs->poly_mode_back); | |||
BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2); | |||
OUT_RING (rs->cull_face); | |||
OUT_RING (rs->front_face); | |||
BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2); | |||
OUT_RING (rs->line_smooth_en); | |||
OUT_RING (rs->poly_smooth_en); | |||
BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1); | |||
OUT_RING (rs->cull_face_en); | |||
/* BEGIN_RING(celsius, NV10TCL_POINT_SPRITE, 1); | |||
OUT_RING (rs->point_sprite);*/ | |||
} | |||
static void | |||
nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
free(hwcso); | |||
} | |||
static void * | |||
nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe, | |||
const struct pipe_depth_stencil_alpha_state *cso) | |||
{ | |||
struct nv10_depth_stencil_alpha_state *hw; | |||
hw = malloc(sizeof(struct nv10_depth_stencil_alpha_state)); | |||
hw->depth.func = nvgl_comparison_op(cso->depth.func); | |||
hw->depth.write_enable = cso->depth.writemask ? 1 : 0; | |||
hw->depth.test_enable = cso->depth.enabled ? 1 : 0; | |||
hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0; | |||
hw->stencil.wmask = cso->stencil[0].write_mask; | |||
hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func); | |||
hw->stencil.ref = cso->stencil[0].ref_value; | |||
hw->stencil.vmask = cso->stencil[0].value_mask; | |||
hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op); | |||
hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op); | |||
hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op); | |||
hw->alpha.enabled = cso->alpha.enabled ? 1 : 0; | |||
hw->alpha.func = nvgl_comparison_op(cso->alpha.func); | |||
hw->alpha.ref = float_to_ubyte(cso->alpha.ref); | |||
return (void *)hw; | |||
} | |||
static void | |||
nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nv10_depth_stencil_alpha_state *hw = hwcso; | |||
BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 3); | |||
OUT_RINGp ((uint32_t *)&hw->depth, 3); | |||
BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1); | |||
OUT_RING (hw->stencil.enable); | |||
BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7); | |||
OUT_RINGp ((uint32_t *)&(hw->stencil.wmask), 7); | |||
BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3); | |||
OUT_RINGp ((uint32_t *)&hw->alpha.enabled, 3); | |||
} | |||
static void | |||
nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
free(hwcso); | |||
} | |||
static void * | |||
nv10_vp_state_create(struct pipe_context *pipe, | |||
const struct pipe_shader_state *cso) | |||
{ | |||
struct nv10_vertex_program *vp; | |||
vp = CALLOC(1, sizeof(struct nv10_vertex_program)); | |||
vp->pipe = cso; | |||
return (void *)vp; | |||
} | |||
static void | |||
nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nv10_vertex_program *vp = hwcso; | |||
nv10->vertprog.current = vp; | |||
nv10->dirty |= NV10_NEW_VERTPROG; | |||
} | |||
static void | |||
nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nv10_vertex_program *vp = hwcso; | |||
//nv10_vertprog_destroy(nv10, vp); | |||
free(vp); | |||
} | |||
static void * | |||
nv10_fp_state_create(struct pipe_context *pipe, | |||
const struct pipe_shader_state *cso) | |||
{ | |||
struct nv10_fragment_program *fp; | |||
fp = CALLOC(1, sizeof(struct nv10_fragment_program)); | |||
fp->pipe = cso; | |||
return (void *)fp; | |||
} | |||
static void | |||
nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nv10_fragment_program *fp = hwcso; | |||
nv10->fragprog.current = fp; | |||
nv10->dirty |= NV10_NEW_FRAGPROG; | |||
} | |||
static void | |||
nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nv10_fragment_program *fp = hwcso; | |||
nv10_fragprog_destroy(nv10, fp); | |||
free(fp); | |||
} | |||
static void | |||
nv10_set_blend_color(struct pipe_context *pipe, | |||
const struct pipe_blend_color *bcol) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
BEGIN_RING(celsius, NV10TCL_BLEND_COLOR, 1); | |||
OUT_RING ((float_to_ubyte(bcol->color[3]) << 24) | | |||
(float_to_ubyte(bcol->color[0]) << 16) | | |||
(float_to_ubyte(bcol->color[1]) << 8) | | |||
(float_to_ubyte(bcol->color[2]) << 0)); | |||
} | |||
static void | |||
nv10_set_clip_state(struct pipe_context *pipe, | |||
const struct pipe_clip_state *clip) | |||
{ | |||
} | |||
static void | |||
nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, | |||
const struct pipe_constant_buffer *buf ) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
if (shader == PIPE_SHADER_VERTEX) { | |||
nv10->vertprog.constant_buf = buf->buffer; | |||
nv10->dirty |= NV10_NEW_VERTPROG; | |||
} else | |||
if (shader == PIPE_SHADER_FRAGMENT) { | |||
nv10->fragprog.constant_buf = buf->buffer; | |||
nv10->dirty |= NV10_NEW_FRAGPROG; | |||
} | |||
} | |||
static void | |||
nv10_set_framebuffer_state(struct pipe_context *pipe, | |||
const struct pipe_framebuffer_state *fb) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct pipe_surface *rt, *zeta; | |||
uint32_t rt_format, w, h; | |||
int i, colour_format = 0, zeta_format = 0; | |||
w = fb->cbufs[0]->width; | |||
h = fb->cbufs[0]->height; | |||
colour_format = fb->cbufs[0]->format; | |||
rt = fb->cbufs[0]; | |||
if (fb->zsbuf) { | |||
if (colour_format) { | |||
assert(w == fb->zsbuf->width); | |||
assert(h == fb->zsbuf->height); | |||
} else { | |||
w = fb->zsbuf->width; | |||
h = fb->zsbuf->height; | |||
} | |||
zeta_format = fb->zsbuf->format; | |||
zeta = fb->zsbuf; | |||
} | |||
rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR; | |||
switch (colour_format) { | |||
case PIPE_FORMAT_A8R8G8B8_UNORM: | |||
case 0: | |||
rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8; | |||
break; | |||
case PIPE_FORMAT_R5G6B5_UNORM: | |||
rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5; | |||
break; | |||
default: | |||
assert(0); | |||
} | |||
BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1); | |||
OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) ); | |||
nv10->rt[0] = rt->buffer; | |||
if (zeta_format) | |||
{ | |||
nv10->zeta = zeta->buffer; | |||
} | |||
BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3); | |||
OUT_RING ((w << 16) | 0); | |||
OUT_RING ((h << 16) | 0); | |||
OUT_RING (rt_format); | |||
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2); | |||
OUT_RING (((w - 1) << 16) | 0); | |||
OUT_RING (((h - 1) << 16) | 0); | |||
} | |||
static void | |||
nv10_set_polygon_stipple(struct pipe_context *pipe, | |||
const struct pipe_poly_stipple *stipple) | |||
{ | |||
NOUVEAU_ERR("line stipple hahaha\n"); | |||
} | |||
static void | |||
nv10_set_scissor_state(struct pipe_context *pipe, | |||
const struct pipe_scissor_state *s) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
// XXX | |||
/* BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2); | |||
OUT_RING (((s->maxx - s->minx) << 16) | s->minx); | |||
OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/ | |||
} | |||
static void | |||
nv10_set_viewport_state(struct pipe_context *pipe, | |||
const struct pipe_viewport_state *vpt) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
/* OUT_RINGf (vpt->translate[0]); | |||
OUT_RINGf (vpt->translate[1]); | |||
OUT_RINGf (vpt->translate[2]); | |||
OUT_RINGf (vpt->translate[3]);*/ | |||
BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4); | |||
OUT_RINGf (vpt->scale[0]); | |||
OUT_RINGf (vpt->scale[1]); | |||
OUT_RINGf (vpt->scale[2]); | |||
OUT_RINGf (vpt->scale[3]); | |||
} | |||
static void | |||
nv10_set_vertex_buffer(struct pipe_context *pipe, unsigned index, | |||
const struct pipe_vertex_buffer *vb) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
nv10->vtxbuf[index] = *vb; | |||
nv10->dirty |= NV10_NEW_ARRAYS; | |||
} | |||
static void | |||
nv10_set_vertex_element(struct pipe_context *pipe, unsigned index, | |||
const struct pipe_vertex_element *ve) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
nv10->vtxelt[index] = *ve; | |||
nv10->dirty |= NV10_NEW_ARRAYS; | |||
} | |||
void | |||
nv10_init_state_functions(struct nv10_context *nv10) | |||
{ | |||
nv10->pipe.create_blend_state = nv10_blend_state_create; | |||
nv10->pipe.bind_blend_state = nv10_blend_state_bind; | |||
nv10->pipe.delete_blend_state = nv10_blend_state_delete; | |||
nv10->pipe.create_sampler_state = nv10_sampler_state_create; | |||
nv10->pipe.bind_sampler_states = nv10_sampler_state_bind; | |||
nv10->pipe.delete_sampler_state = nv10_sampler_state_delete; | |||
nv10->pipe.set_sampler_textures = nv10_set_sampler_texture; | |||
nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create; | |||
nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind; | |||
nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete; | |||
nv10->pipe.create_depth_stencil_alpha_state = | |||
nv10_depth_stencil_alpha_state_create; | |||
nv10->pipe.bind_depth_stencil_alpha_state = | |||
nv10_depth_stencil_alpha_state_bind; | |||
nv10->pipe.delete_depth_stencil_alpha_state = | |||
nv10_depth_stencil_alpha_state_delete; | |||
nv10->pipe.create_vs_state = nv10_vp_state_create; | |||
nv10->pipe.bind_vs_state = nv10_vp_state_bind; | |||
nv10->pipe.delete_vs_state = nv10_vp_state_delete; | |||
nv10->pipe.create_fs_state = nv10_fp_state_create; | |||
nv10->pipe.bind_fs_state = nv10_fp_state_bind; | |||
nv10->pipe.delete_fs_state = nv10_fp_state_delete; | |||
nv10->pipe.set_blend_color = nv10_set_blend_color; | |||
nv10->pipe.set_clip_state = nv10_set_clip_state; | |||
nv10->pipe.set_constant_buffer = nv10_set_constant_buffer; | |||
nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state; | |||
nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple; | |||
nv10->pipe.set_scissor_state = nv10_set_scissor_state; | |||
nv10->pipe.set_viewport_state = nv10_set_viewport_state; | |||
nv10->pipe.set_vertex_buffer = nv10_set_vertex_buffer; | |||
nv10->pipe.set_vertex_element = nv10_set_vertex_element; | |||
} | |||
@@ -0,0 +1,135 @@ | |||
#ifndef __NV10_STATE_H__ | |||
#define __NV10_STATE_H__ | |||
#include "pipe/p_state.h" | |||
struct nv10_blend_state { | |||
uint32_t b_enable; | |||
uint32_t b_srcfunc; | |||
uint32_t b_dstfunc; | |||
uint32_t c_mask; | |||
uint32_t d_enable; | |||
}; | |||
struct nv10_sampler_state { | |||
uint32_t wrap; | |||
uint32_t en; | |||
uint32_t filt; | |||
uint32_t bcol; | |||
}; | |||
struct nv10_rasterizer_state { | |||
uint32_t shade_model; | |||
uint32_t line_width; | |||
uint32_t line_smooth_en; | |||
uint32_t point_size; | |||
uint32_t poly_smooth_en; | |||
uint32_t poly_mode_front; | |||
uint32_t poly_mode_back; | |||
uint32_t front_face; | |||
uint32_t cull_face; | |||
uint32_t cull_face_en; | |||
uint32_t point_sprite; | |||
}; | |||
struct nv10_vertex_program_exec { | |||
uint32_t data[4]; | |||
boolean has_branch_offset; | |||
int const_index; | |||
}; | |||
struct nv10_vertex_program_data { | |||
int index; /* immediates == -1 */ | |||
float value[4]; | |||
}; | |||
struct nv10_vertex_program { | |||
const struct pipe_shader_state *pipe; | |||
boolean translated; | |||
struct nv10_vertex_program_exec *insns; | |||
unsigned nr_insns; | |||
struct nv10_vertex_program_data *consts; | |||
unsigned nr_consts; | |||
struct nouveau_resource *exec; | |||
unsigned exec_start; | |||
struct nouveau_resource *data; | |||
unsigned data_start; | |||
unsigned data_start_min; | |||
uint32_t ir; | |||
uint32_t or; | |||
}; | |||
struct nv10_fragment_program_data { | |||
unsigned offset; | |||
unsigned index; | |||
}; | |||
struct nv10_fragment_program { | |||
const struct pipe_shader_state *pipe; | |||
boolean translated; | |||
boolean on_hw; | |||
unsigned samplers; | |||
uint32_t *insn; | |||
int insn_len; | |||
struct nv10_fragment_program_data *consts; | |||
unsigned nr_consts; | |||
struct pipe_buffer *buffer; | |||
uint32_t fp_control; | |||
uint32_t fp_reg_control; | |||
}; | |||
struct nv10_depth_stencil_alpha_state { | |||
struct { | |||
uint32_t func; | |||
uint32_t write_enable; | |||
uint32_t test_enable; | |||
} depth; | |||
struct { | |||
uint32_t enable; | |||
uint32_t wmask; | |||
uint32_t func; | |||
uint32_t ref; | |||
uint32_t vmask; | |||
uint32_t fail; | |||
uint32_t zfail; | |||
uint32_t zpass; | |||
} stencil; | |||
struct { | |||
uint32_t enabled; | |||
uint32_t func; | |||
uint32_t ref; | |||
} alpha; | |||
}; | |||
struct nv10_miptree { | |||
struct pipe_texture base; | |||
struct pipe_buffer *buffer; | |||
uint total_size; | |||
struct { | |||
uint pitch; | |||
uint *image_offset; | |||
} level[PIPE_MAX_TEXTURE_LEVELS]; | |||
}; | |||
#endif |
@@ -0,0 +1,69 @@ | |||
#include "nv10_context.h" | |||
#include "nv10_state.h" | |||
void | |||
nv10_emit_hw_state(struct nv10_context *nv10) | |||
{ | |||
int i; | |||
if (nv10->dirty & NV10_NEW_FRAGPROG) { | |||
nv10_fragprog_bind(nv10, nv10->fragprog.current); | |||
/*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */ | |||
} | |||
if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) { | |||
nv10_fragtex_bind(nv10); | |||
nv10->dirty &= ~NV10_NEW_FRAGPROG; | |||
} | |||
if (nv10->dirty & NV10_NEW_VERTPROG) { | |||
//nv10_vertprog_bind(nv10, nv10->vertprog.current); | |||
nv10->dirty &= ~NV10_NEW_VERTPROG; | |||
} | |||
if (nv10->dirty & NV10_NEW_VBO) { | |||
} | |||
nv10->dirty_samplers = 0; | |||
/* Emit relocs for every referenced buffer. | |||
* This is to ensure the bufmgr has an accurate idea of how | |||
* the buffer is used. This isn't very efficient, but we don't | |||
* seem to take a significant performance hit. Will be improved | |||
* at some point. Vertex arrays are emitted by nv10_vbo.c | |||
*/ | |||
/* Render target */ | |||
// XXX figre out who's who for NV10TCL_DMA_* and fill accordingly | |||
// BEGIN_RING(celsius, NV10TCL_DMA_COLOR0, 1); | |||
// OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); | |||
BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1); | |||
OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); | |||
if (nv10->zeta) { | |||
// XXX | |||
// BEGIN_RING(celsius, NV10TCL_DMA_ZETA, 1); | |||
// OUT_RELOCo(nv10->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); | |||
BEGIN_RING(celsius, NV10TCL_ZETA_OFFSET, 1); | |||
OUT_RELOCl(nv10->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); | |||
/* XXX for when we allocate LMA on nv17 */ | |||
/* BEGIN_RING(celsius, NV10TCL_LMA_DEPTH_OFFSET, 1); | |||
OUT_RELOCl(nv10->zeta+...);*/ | |||
} | |||
/* Texture images */ | |||
for (i = 0; i < 2; i++) { | |||
if (!(nv10->fp_samplers & (1 << i))) | |||
continue; | |||
BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 2); | |||
OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM | | |||
NOUVEAU_BO_GART | NOUVEAU_BO_RD); | |||
// XXX | |||
/* OUT_RELOCd(nv10->tex[i].buffer, nv10->tex[i].format, | |||
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD | | |||
NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0, | |||
NV10TCL_TX_FORMAT_DMA1);*/ | |||
} | |||
} | |||
@@ -0,0 +1,65 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. | |||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR | |||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
**************************************************************************/ | |||
#include "nv10_context.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_util.h" | |||
#include "pipe/p_winsys.h" | |||
#include "pipe/p_inlines.h" | |||
#include "util/p_tile.h" | |||
static void | |||
nv10_surface_copy(struct pipe_context *pipe, unsigned do_flip, | |||
struct pipe_surface *dest, unsigned destx, unsigned desty, | |||
struct pipe_surface *src, unsigned srcx, unsigned srcy, | |||
unsigned width, unsigned height) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nouveau_winsys *nvws = nv10->nvws; | |||
nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy, | |||
width, height); | |||
} | |||
static void | |||
nv10_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, | |||
unsigned destx, unsigned desty, unsigned width, | |||
unsigned height, unsigned value) | |||
{ | |||
struct nv10_context *nv10 = nv10_context(pipe); | |||
struct nouveau_winsys *nvws = nv10->nvws; | |||
nvws->surface_fill(nvws, dest, destx, desty, width, height, value); | |||
} | |||
void | |||
nv10_init_surface_functions(struct nv10_context *nv10) | |||
{ | |||
nv10->pipe.surface_copy = nv10_surface_copy; | |||
nv10->pipe.surface_fill = nv10_surface_fill; | |||
} |
@@ -0,0 +1,72 @@ | |||
#include "draw/draw_context.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_util.h" | |||
#include "nv10_context.h" | |||
#include "nv10_state.h" | |||
#include "nouveau/nouveau_channel.h" | |||
#include "nouveau/nouveau_pushbuf.h" | |||
boolean nv10_draw_elements( struct pipe_context *pipe, | |||
struct pipe_buffer *indexBuffer, | |||
unsigned indexSize, | |||
unsigned prim, unsigned start, unsigned count) | |||
{ | |||
struct nv10_context *nv10 = nv10_context( pipe ); | |||
struct draw_context *draw = nv10->draw; | |||
unsigned i; | |||
/* | |||
* Map vertex buffers | |||
*/ | |||
for (i = 0; i < PIPE_ATTRIB_MAX; i++) { | |||
if (nv10->vtxbuf[i].buffer) { | |||
void *buf | |||
= pipe->winsys->buffer_map(pipe->winsys, | |||
nv10->vtxbuf[i].buffer, | |||
PIPE_BUFFER_USAGE_CPU_READ); | |||
draw_set_mapped_vertex_buffer(draw, i, buf); | |||
} | |||
} | |||
/* Map index buffer, if present */ | |||
if (indexBuffer) { | |||
void *mapped_indexes | |||
= pipe->winsys->buffer_map(pipe->winsys, indexBuffer, | |||
PIPE_BUFFER_USAGE_CPU_READ); | |||
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes); | |||
} | |||
else { | |||
/* no index/element buffer */ | |||
draw_set_mapped_element_buffer(draw, 0, NULL); | |||
} | |||
/* draw! */ | |||
draw_arrays(nv10->draw, prim, start, count); | |||
/* | |||
* unmap vertex/index buffers | |||
*/ | |||
for (i = 0; i < PIPE_ATTRIB_MAX; i++) { | |||
if (nv10->vtxbuf[i].buffer) { | |||
pipe->winsys->buffer_unmap(pipe->winsys, nv10->vtxbuf[i].buffer); | |||
draw_set_mapped_vertex_buffer(draw, i, NULL); | |||
} | |||
} | |||
if (indexBuffer) { | |||
pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer); | |||
draw_set_mapped_element_buffer(draw, 0, NULL); | |||
} | |||
return TRUE; | |||
} | |||
boolean nv10_draw_arrays( struct pipe_context *pipe, | |||
unsigned prim, unsigned start, unsigned count) | |||
{ | |||
return nv10_draw_elements(pipe, NULL, 0, prim, start, count); | |||
} | |||
@@ -8,6 +8,7 @@ MINIGLX_SOURCES = | |||
PIPE_DRIVERS = \ | |||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ | |||
$(TOP)/src/gallium/drivers/nv10/libnv10.a \ | |||
$(TOP)/src/gallium/drivers/nv30/libnv30.a \ | |||
$(TOP)/src/gallium/drivers/nv40/libnv40.a \ | |||
$(TOP)/src/gallium/drivers/nv50/libnv50.a |
@@ -119,6 +119,9 @@ nouveau_context_create(const __GLcontextModes *glVis, | |||
} | |||
switch (nv->chipset & 0xf0) { | |||
case 0x10: | |||
case 0x20: | |||
/* NV10 */ | |||
case 0x30: | |||
/* NV30 */ | |||
case 0x40: |
@@ -82,6 +82,11 @@ nouveau_pipe_create(struct nouveau_context *nv) | |||
return NULL; | |||
switch (nv->chipset & 0xf0) { | |||
case 0x10: | |||
case 0x20: | |||
hws_create = nv10_screen_create; | |||
hw_create = nv10_create; | |||
break; | |||
case 0x30: | |||
hws_create = nv30_screen_create; | |||
hw_create = nv30_create; |