浏览代码

nv10.

tags/mesa_20090313
Stephane Marchesin 17 年前
父节点
当前提交
d493203045

+ 1
- 1
configs/default 查看文件

@@ -70,7 +70,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos
# Gallium directories and
GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi rtasm util sct
GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a)
GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv30 nv40 nv50 failover
GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv10 nv30 nv40 nv50 failover
GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
GALLIUM_WINSYS_DIRS = xlib


+ 1
- 1
configs/linux-dri 查看文件

@@ -65,4 +65,4 @@ GALLIUM_WINSYS_DIRS = dri

# gamma are missing because they have not been converted to use the new
# interface.
DRI_DIRS = intel
DRI_DIRS = nouveau

+ 7
- 0
src/gallium/drivers/nouveau/nouveau_winsys.h 查看文件

@@ -49,6 +49,13 @@ struct nouveau_winsys {
unsigned, unsigned, unsigned, unsigned, unsigned);
};

extern struct pipe_screen *
nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
unsigned chipset);

extern struct pipe_context *
nv10_create(struct pipe_screen *, unsigned pctx_id);

extern struct pipe_screen *
nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *,
unsigned chipset);

+ 28
- 0
src/gallium/drivers/nv10/Makefile 查看文件

@@ -0,0 +1,28 @@
TOP = ../../../..
include $(TOP)/configs/current

LIBNAME = nv10

DRIVER_SOURCES = \
nv10_clear.c \
nv10_context.c \
nv10_fragprog.c \
nv10_fragtex.c \
nv10_miptree.c \
nv10_prim_vbuf.c \
nv10_screen.c \
nv10_state.c \
nv10_state_emit.c \
nv10_surface.c \
nv10_vbo.c

C_SOURCES = \
$(COMMON_SOURCES) \
$(DRIVER_SOURCES)

ASM_SOURCES =

include ../../Makefile.template

symlinks:


+ 12
- 0
src/gallium/drivers/nv10/nv10_clear.c 查看文件

@@ -0,0 +1,12 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"

#include "nv10_context.h"

void
nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue)
{
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
}

+ 325
- 0
src/gallium/drivers/nv10/nv10_context.c 查看文件

@@ -0,0 +1,325 @@
#include "draw/draw_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"

#include "nv10_context.h"
#include "nv10_screen.h"

static void
nv10_flush(struct pipe_context *pipe, unsigned flags)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nouveau_winsys *nvws = nv10->nvws;

if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
BEGIN_RING(celsius, 0x1fd8, 1);
OUT_RING (2);
BEGIN_RING(celsius, 0x1fd8, 1);
OUT_RING (1);
}

if (flags & PIPE_FLUSH_WAIT) {
nvws->notifier_reset(nv10->sync, 0);
BEGIN_RING(celsius, 0x104, 1);
OUT_RING (0);
BEGIN_RING(celsius, 0x100, 1);
OUT_RING (0);
}

FIRE_RING();

if (flags & PIPE_FLUSH_WAIT)
nvws->notifier_wait(nv10->sync, 0, 0, 2000);
}

static void
nv10_destroy(struct pipe_context *pipe)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nouveau_winsys *nvws = nv10->nvws;

if (nv10->draw)
draw_destroy(nv10->draw);

nvws->res_free(&nv10->vertprog.exec_heap);
nvws->res_free(&nv10->vertprog.data_heap);

nvws->notifier_free(&nv10->sync);

nvws->grobj_free(&nv10->celsius);

free(nv10);
}

static boolean
nv10_init_hwctx(struct nv10_context *nv10, int celsius_class)
{
struct nouveau_winsys *nvws = nv10->nvws;
int ret;
int i;

ret = nvws->grobj_alloc(nvws, celsius_class, &nv10->celsius);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
return FALSE;
}

BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1);
OUT_RING (nv10->sync->handle);
BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2);
OUT_RING (nvws->channel->vram->handle);
OUT_RING (nvws->channel->gart->handle);
BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY2, 2);
OUT_RING (nvws->channel->vram->handle);
OUT_RING (nvws->channel->vram->handle);

BEGIN_RING(celsius, NV10TCL_NOP, 1);
OUT_RING (0);

BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 2);
OUT_RING (0);
OUT_RING (0);

BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 1);
OUT_RING ((0x7ff<<16)|0x800);
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(0), 1);
OUT_RING ((0x7ff<<16)|0x800);

for (i=1;i<8;i++) {
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(i), 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_VERT(i), 1);
OUT_RING (0);
}

BEGIN_RING(celsius, 0x290, 1);
OUT_RING ((0x10<<16)|1);
BEGIN_RING(celsius, 0x3f4, 1);
OUT_RING (0);

BEGIN_RING(celsius, NV10TCL_NOP, 1);
OUT_RING (0);

if (celsius_class != NV10TCL) {
/* For nv11, nv17 */
BEGIN_RING(celsius, 0x120, 3);
OUT_RING (0);
OUT_RING (1);
OUT_RING (2);

BEGIN_RING(celsius, NV10TCL_NOP, 1);
OUT_RING (0);
}

BEGIN_RING(celsius, NV10TCL_NOP, 1);
OUT_RING (0);

/* Set state */
BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_FUNC, 2);
OUT_RING (0x207);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_TX_ENABLE(0), 2);
OUT_RING (0);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_RC_OUT_ALPHA(0), 6);
OUT_RING (0x00000c00);
OUT_RING (0);
OUT_RING (0x00000c00);
OUT_RING (0x18000000);
OUT_RING (0x300c0000);
OUT_RING (0x00001c80);
BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 2);
OUT_RING (1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_VERTEX_WEIGHT_ENABLE, 2);
OUT_RING (0);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_SRC, 4);
OUT_RING (1);
OUT_RING (0);
OUT_RING (0);
OUT_RING (0x8006);
BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 8);
OUT_RING (0xff);
OUT_RING (0x207);
OUT_RING (0);
OUT_RING (0xff);
OUT_RING (0x1e00);
OUT_RING (0x1e00);
OUT_RING (0x1e00);
OUT_RING (0x1d01);
BEGIN_RING(celsius, NV10TCL_NORMALIZE_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_FOG_ENABLE, 2);
OUT_RING (0);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_LIGHT_MODEL, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_COLOR_CONTROL, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_ENABLED_LIGHTS, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
OUT_RING (0);
OUT_RING (0);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 1);
OUT_RING (0x201);
BEGIN_RING(celsius, NV10TCL_DEPTH_WRITE_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_DEPTH_TEST_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_POLYGON_OFFSET_FACTOR, 2);
OUT_RING (0);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1);
OUT_RING (8);
BEGIN_RING(celsius, NV10TCL_POINT_PARAMETERS_ENABLE, 2);
OUT_RING (0);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_LINE_WIDTH, 1);
OUT_RING (8);
BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
OUT_RING (0x1b02);
OUT_RING (0x1b02);
BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2);
OUT_RING (0x405);
OUT_RING (0x901);
BEGIN_RING(celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_CLIP_PLANE_ENABLE(0), 8);
for (i=0;i<8;i++) {
OUT_RING (0);
}
BEGIN_RING(celsius, NV10TCL_FOG_EQUATION_CONSTANT, 3);
OUT_RING (0x3fc00000); /* -1.50 */
OUT_RING (0xbdb8aa0a); /* -0.09 */
OUT_RING (0); /* 0.00 */

BEGIN_RING(celsius, NV10TCL_NOP, 1);
OUT_RING (0);

BEGIN_RING(celsius, NV10TCL_FOG_MODE, 2);
OUT_RING (0x802);
OUT_RING (2);
/* for some reason VIEW_MATRIX_ENABLE need to be 6 instead of 4 when
* using texturing, except when using the texture matrix
*/
BEGIN_RING(celsius, NV10TCL_VIEW_MATRIX_ENABLE, 1);
OUT_RING (6);
BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1);
OUT_RING (0x01010101);

/* Set vertex component */
BEGIN_RING(celsius, NV10TCL_VERTEX_COL_4F_R, 4);
OUT_RINGf (1.0);
OUT_RINGf (1.0);
OUT_RINGf (1.0);
OUT_RINGf (1.0);
BEGIN_RING(celsius, NV10TCL_VERTEX_COL2_3F_R, 3);
OUT_RING (0);
OUT_RING (0);
OUT_RING (0);
BEGIN_RING(celsius, NV10TCL_VERTEX_NOR_3F_X, 3);
OUT_RING (0);
OUT_RING (0);
OUT_RINGf (1.0);
BEGIN_RING(celsius, NV10TCL_VERTEX_TX0_4F_S, 4);
OUT_RINGf (0.0);
OUT_RINGf (0.0);
OUT_RINGf (0.0);
OUT_RINGf (1.0);
BEGIN_RING(celsius, NV10TCL_VERTEX_TX1_4F_S, 4);
OUT_RINGf (0.0);
OUT_RINGf (0.0);
OUT_RINGf (0.0);
OUT_RINGf (1.0);
BEGIN_RING(celsius, NV10TCL_VERTEX_FOG_1F, 1);
OUT_RINGf (0.0);
BEGIN_RING(celsius, NV10TCL_EDGEFLAG_ENABLE, 1);
OUT_RING (1);


FIRE_RING ();
return TRUE;
}

struct pipe_context *
nv10_create(struct pipe_screen *screen, unsigned pctx_id)
{
struct pipe_winsys *pipe_winsys = screen->winsys;
struct nouveau_winsys *nvws = nv10_screen(screen)->nvws;
unsigned chipset = nv10_screen(screen)->chipset;
struct nv10_context *nv10;
int celsius_class = 0, ret;

if (chipset>=0x20)
celsius_class=NV11TCL;
else if (chipset>=0x17)
celsius_class=NV17TCL;
else if (chipset>=0x11)
celsius_class=NV11TCL;
else
celsius_class=NV10TCL;

nv10 = CALLOC_STRUCT(nv10_context);
if (!nv10)
return NULL;
nv10->chipset = chipset;
nv10->nvws = nvws;

/* Notifier for sync purposes */
ret = nvws->notifier_alloc(nvws, 1, &nv10->sync);
if (ret) {
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
nv10_destroy(&nv10->pipe);
return NULL;
}

/* Vtxprog resources */
if (nvws->res_init(&nv10->vertprog.exec_heap, 0, 512) ||
nvws->res_init(&nv10->vertprog.data_heap, 0, 256)) {
nv10_destroy(&nv10->pipe);
return NULL;
}

/* Static celsius initialisation */
if (!nv10_init_hwctx(nv10, celsius_class)) {
nv10_destroy(&nv10->pipe);
return NULL;
}

/* Pipe context setup */
nv10->pipe.winsys = pipe_winsys;

nv10->pipe.destroy = nv10_destroy;

nv10->pipe.draw_arrays = nv10_draw_arrays;
nv10->pipe.draw_elements = nv10_draw_elements;
nv10->pipe.clear = nv10_clear;

nv10->pipe.flush = nv10_flush;

nv10_init_surface_functions(nv10);
nv10_init_state_functions(nv10);

nv10->draw = draw_create();
assert(nv10->draw);
draw_set_rasterize_stage(nv10->draw, nv10_draw_vbuf_stage(nv10));

return &nv10->pipe;
}


+ 127
- 0
src/gallium/drivers/nv10/nv10_context.h 查看文件

@@ -0,0 +1,127 @@
#ifndef __NV10_CONTEXT_H__
#define __NV10_CONTEXT_H__

#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"

#include "draw/draw_vertex.h"

#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_gldefs.h"

#define NOUVEAU_PUSH_CONTEXT(ctx) \
struct nv10_context *ctx = nv10
#include "nouveau/nouveau_push.h"

#include "nv10_state.h"

#define NOUVEAU_ERR(fmt, args...) \
fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
#define NOUVEAU_MSG(fmt, args...) \
fprintf(stderr, "nouveau: "fmt, ##args);

#define NV10_NEW_VERTPROG (1 << 1)
#define NV10_NEW_FRAGPROG (1 << 2)
#define NV10_NEW_ARRAYS (1 << 3)
#define NV10_NEW_VBO (1 << 4)

struct nv10_context {
struct pipe_context pipe;
struct nouveau_winsys *nvws;

struct draw_context *draw;

int chipset;
struct nouveau_grobj *celsius;
struct nouveau_notifier *sync;

uint32_t dirty;

struct nv10_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
struct nv10_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
unsigned dirty_samplers;
unsigned fp_samplers;
unsigned vp_samplers;

uint32_t rt_enable;
struct pipe_buffer *rt[4];
struct pipe_buffer *zeta;

struct {
struct pipe_buffer *buffer;
uint32_t format;
} tex[16];

unsigned vb_enable;
struct {
struct pipe_buffer *buffer;
unsigned delta;
} vb[16];

struct vertex_info vertex_info;
struct {
struct nouveau_resource *exec_heap;
struct nouveau_resource *data_heap;

struct nv10_vertex_program *active;

struct nv10_vertex_program *current;
struct pipe_buffer *constant_buf;
} vertprog;

struct {
struct nv10_fragment_program *active;

struct nv10_fragment_program *current;
struct pipe_buffer *constant_buf;
} fragprog;

struct pipe_vertex_buffer vtxbuf[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vtxelt[PIPE_ATTRIB_MAX];
};

static INLINE struct nv10_context *
nv10_context(struct pipe_context *pipe)
{
return (struct nv10_context *)pipe;
}

extern void nv10_init_state_functions(struct nv10_context *nv10);
extern void nv10_init_surface_functions(struct nv10_context *nv10);
extern void nv10_init_miptree_functions(struct pipe_screen *screen);

/* nv10_clear.c */
extern void nv10_clear(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue);

/* nv10_draw.c */
extern struct draw_stage *nv10_draw_render_stage(struct nv10_context *nv10);

/* nv10_fragprog.c */
extern void nv10_fragprog_bind(struct nv10_context *,
struct nv10_fragment_program *);
extern void nv10_fragprog_destroy(struct nv10_context *,
struct nv10_fragment_program *);

/* nv10_fragtex.c */
extern void nv10_fragtex_bind(struct nv10_context *);

/* nv10_prim_vbuf.c */
struct draw_stage *nv10_draw_vbuf_stage( struct nv10_context *nv10 );

/* nv10_state.c and friends */
extern void nv10_emit_hw_state(struct nv10_context *nv10);
extern void nv10_state_tex_update(struct nv10_context *nv10);

/* nv10_vbo.c */
extern boolean nv10_draw_arrays(struct pipe_context *, unsigned mode,
unsigned start, unsigned count);
extern boolean nv10_draw_elements( struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned prim, unsigned start, unsigned count);


#endif

+ 22
- 0
src/gallium/drivers/nv10/nv10_fragprog.c 查看文件

@@ -0,0 +1,22 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "pipe/p_util.h"

#include "pipe/p_shader_tokens.h"
#include "tgsi/util/tgsi_parse.h"
#include "tgsi/util/tgsi_util.h"

#include "nv10_context.h"

void
nv10_fragprog_bind(struct nv10_context *nv10, struct nv10_fragment_program *fp)
{
}

void
nv10_fragprog_destroy(struct nv10_context *nv10,
struct nv10_fragment_program *fp)
{
}


+ 145
- 0
src/gallium/drivers/nv10/nv10_fragtex.c 查看文件

@@ -0,0 +1,145 @@
#include "nv10_context.h"

static INLINE int log2i(int i)
{
int r = 0;

if (i & 0xffff0000) {
i >>= 16;
r += 16;
}
if (i & 0x0000ff00) {
i >>= 8;
r += 8;
}
if (i & 0x000000f0) {
i >>= 4;
r += 4;
}
if (i & 0x0000000c) {
i >>= 2;
r += 2;
}
if (i & 0x00000002) {
r += 1;
}
return r;
}

#define _(m,tf) \
{ \
TRUE, \
PIPE_FORMAT_##m, \
NV10TCL_TX_FORMAT_FORMAT_##tf, \
}

struct nv10_texture_format {
boolean defined;
uint pipe;
int format;
};

static struct nv10_texture_format
nv10_texture_formats[] = {
_(A8R8G8B8_UNORM, A8R8G8B8),
_(A1R5G5B5_UNORM, A1R5G5B5),
_(A4R4G4B4_UNORM, A4R4G4B4),
_(U_L8 , L8 ),
_(U_A8 , A8 ),
_(U_A8_L8 , A8L8 ),
// _(RGB_DXT1 , DXT1, ),
// _(RGBA_DXT1 , DXT1, ),
// _(RGBA_DXT3 , DXT3, ),
// _(RGBA_DXT5 , DXT5, ),
{},
};

static struct nv10_texture_format *
nv10_fragtex_format(uint pipe_format)
{
struct nv10_texture_format *tf = nv10_texture_formats;

while (tf->defined) {
if (tf->pipe == pipe_format)
return tf;
tf++;
}

return NULL;
}


static void
nv10_fragtex_build(struct nv10_context *nv10, int unit)
{
struct nv10_sampler_state *ps = nv10->tex_sampler[unit];
struct nv10_miptree *nv10mt = nv10->tex_miptree[unit];
struct pipe_texture *pt = &nv10mt->base;
struct nv10_texture_format *tf;
uint32_t txf, txs, txp;

tf = nv10_fragtex_format(pt->format);
if (!tf || !tf->defined) {
NOUVEAU_ERR("Unsupported texture format: 0x%x\n", pt->format);
return;
}

txf = tf->format << 8;
txf |= (pt->last_level + 1) << 16;
txf |= log2i(pt->width[0]) << 20;
txf |= log2i(pt->height[0]) << 24;
txf |= log2i(pt->depth[0]) << 28;
txf |= 8;

switch (pt->target) {
case PIPE_TEXTURE_CUBE:
txf |= NV10TCL_TX_FORMAT_CUBE_MAP;
/* fall-through */
case PIPE_TEXTURE_2D:
txf |= (2<<4);
break;
case PIPE_TEXTURE_1D:
txf |= (1<<4);
break;
default:
NOUVEAU_ERR("Unknown target %d\n", pt->target);
return;
}

BEGIN_RING(celsius, NV10TCL_TX_OFFSET(unit), 8);
OUT_RELOCl(nv10mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
OUT_RELOCd(nv10mt->buffer,txf,NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
OUT_RING (ps->wrap);
OUT_RING (0x40000000); /* enable */
OUT_RING (txs);
OUT_RING (ps->filt | 0x2000 /* magic */);
OUT_RING ((pt->width[0] << 16) | pt->height[0]);
OUT_RING (ps->bcol);
}

void
nv10_fragtex_bind(struct nv10_context *nv10)
{
struct nv10_fragment_program *fp = nv10->fragprog.active;
unsigned samplers, unit;

samplers = nv10->fp_samplers & ~fp->samplers;
while (samplers) {
unit = ffs(samplers) - 1;
samplers &= ~(1 << unit);

BEGIN_RING(celsius, NV10TCL_TX_ENABLE(unit), 1);
OUT_RING (0);
}

samplers = nv10->dirty_samplers & fp->samplers;
while (samplers) {
unit = ffs(samplers) - 1;
samplers &= ~(1 << unit);

nv10_fragtex_build(nv10, unit);
}

nv10->fp_samplers = fp->samplers;
}


+ 134
- 0
src/gallium/drivers/nv10/nv10_miptree.c 查看文件

@@ -0,0 +1,134 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
#include "pipe/p_inlines.h"

#include "nv10_context.h"
#include "nv10_screen.h"

static void
nv10_miptree_layout(struct nv10_miptree *nv10mt)
{
struct pipe_texture *pt = &nv10mt->base;
boolean swizzled = FALSE;
uint width = pt->width[0], height = pt->height[0], depth = pt->depth[0];
uint offset = 0;
int nr_faces, l, f;

if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
} else {
nr_faces = 1;
}
for (l = 0; l <= pt->last_level; l++) {
pt->width[l] = width;
pt->height[l] = height;
pt->depth[l] = depth;

if (swizzled)
nv10mt->level[l].pitch = pt->width[l] * pt->cpp;
else
nv10mt->level[l].pitch = pt->width[0] * pt->cpp;
nv10mt->level[l].pitch = (nv10mt->level[l].pitch + 63) & ~63;

nv10mt->level[l].image_offset =
CALLOC(nr_faces, sizeof(unsigned));

width = MAX2(1, width >> 1);
height = MAX2(1, height >> 1);
depth = MAX2(1, depth >> 1);

}

for (f = 0; f < nr_faces; f++) {
for (l = 0; l <= pt->last_level; l++) {
nv10mt->level[l].image_offset[f] = offset;
offset += nv10mt->level[l].pitch * pt->height[l];
}
}

nv10mt->total_size = offset;
}

static struct pipe_texture *
nv10_miptree_create(struct pipe_screen *screen, struct pipe_texture *pt)
{
struct pipe_winsys *ws = screen->winsys;
struct nv10_miptree *mt;

mt = MALLOC(sizeof(struct nv10_miptree));
if (!mt)
return NULL;
mt->base = *pt;
mt->base.refcount = 1;
mt->base.screen = screen;

nv10_miptree_layout(mt);

mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL,
mt->total_size);
if (!mt->buffer) {
free(mt);
return NULL;
}
return &mt->base;
}

static void
nv10_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt)
{
struct pipe_winsys *ws = screen->winsys;
struct pipe_texture *mt = *pt;

*pt = NULL;
if (--mt->refcount <= 0) {
struct nv10_miptree *nv10mt = (struct nv10_miptree *)mt;
int l;

pipe_buffer_reference(ws, &nv10mt->buffer, NULL);
for (l = 0; l <= mt->last_level; l++) {
if (nv10mt->level[l].image_offset)
free(nv10mt->level[l].image_offset);
}
free(nv10mt);
}
}

static struct pipe_surface *
nv10_miptree_surface_get(struct pipe_screen *screen, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice)
{
struct pipe_winsys *ws = screen->winsys;
struct nv10_miptree *nv10mt = (struct nv10_miptree *)pt;
struct pipe_surface *ps;

ps = ws->surface_alloc(ws);
if (!ps)
return NULL;
pipe_buffer_reference(ws, &ps->buffer, nv10mt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];
ps->pitch = nv10mt->level[level].pitch / ps->cpp;

if (pt->target == PIPE_TEXTURE_CUBE) {
ps->offset = nv10mt->level[level].image_offset[face];
} else {
ps->offset = nv10mt->level[level].image_offset[0];
}

return ps;
}
void
nv10_init_miptree_functions(struct pipe_screen *screen)
{
struct nv10_screen *nv10screen = nv10_screen(screen);

nv10screen->screen.texture_create = nv10_miptree_create;
nv10screen->screen.texture_release = nv10_miptree_release;
nv10screen->screen.get_tex_surface = nv10_miptree_surface_get;
}


+ 224
- 0
src/gallium/drivers/nv10/nv10_prim_vbuf.c 查看文件

@@ -0,0 +1,224 @@
/**************************************************************************
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/

/**
* \file
* Build post-transformation, post-clipping vertex buffers and element
* lists by hooking into the end of the primitive pipeline and
* manipulating the vertex_id field in the vertex headers.
*
* XXX: work in progress
*
* \author José Fonseca <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;
}

+ 150
- 0
src/gallium/drivers/nv10/nv10_screen.c 查看文件

@@ -0,0 +1,150 @@
#include "pipe/p_screen.h"
#include "pipe/p_util.h"

#include "nv10_context.h"
#include "nv10_screen.h"

static const char *
nv10_screen_get_name(struct pipe_screen *screen)
{
struct nv10_screen *nv10screen = nv10_screen(screen);
static char buffer[128];

snprintf(buffer, sizeof(buffer), "NV%02X", nv10screen->chipset);
return buffer;
}

static const char *
nv10_screen_get_vendor(struct pipe_screen *screen)
{
return "nouveau";
}

static int
nv10_screen_get_param(struct pipe_screen *screen, int param)
{
switch (param) {
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 2;
case PIPE_CAP_NPOT_TEXTURES:
return 0;
case PIPE_CAP_TWO_SIDED_STENCIL:
return 0;
case PIPE_CAP_GLSL:
return 0;
case PIPE_CAP_S3TC:
return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
return 0;
case PIPE_CAP_MAX_RENDER_TARGETS:
return 1;
case PIPE_CAP_OCCLUSION_QUERY:
return 0;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 0;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return 12;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
return 0;
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 12;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0;
}
}

static float
nv10_screen_get_paramf(struct pipe_screen *screen, int param)
{
switch (param) {
case PIPE_CAP_MAX_LINE_WIDTH:
case PIPE_CAP_MAX_LINE_WIDTH_AA:
return 10.0;
case PIPE_CAP_MAX_POINT_WIDTH:
case PIPE_CAP_MAX_POINT_WIDTH_AA:
return 64.0;
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
return 2.0;
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
return 4.0;
case PIPE_CAP_BITMAP_TEXCOORD_BIAS:
return 0.0;
default:
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
return 0.0;
}
}

static boolean
nv10_screen_is_format_supported(struct pipe_screen *screen,
enum pipe_format format, uint type)
{
switch (type) {
case PIPE_SURFACE:
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_R5G6B5_UNORM:
case PIPE_FORMAT_Z24S8_UNORM:
case PIPE_FORMAT_Z16_UNORM:
return TRUE;
default:
break;
}
break;
case PIPE_TEXTURE:
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_A1R5G5B5_UNORM:
case PIPE_FORMAT_A4R4G4B4_UNORM:
case PIPE_FORMAT_R5G6B5_UNORM:
case PIPE_FORMAT_U_L8:
case PIPE_FORMAT_U_A8:
case PIPE_FORMAT_U_I8:
return TRUE;
default:
break;
}
break;
default:
assert(0);
};

return FALSE;
}

static void
nv10_screen_destroy(struct pipe_screen *screen)
{
FREE(screen);
}

struct pipe_screen *
nv10_screen_create(struct pipe_winsys *winsys, struct nouveau_winsys *nvws,
unsigned chipset)
{
struct nv10_screen *nv10screen = CALLOC_STRUCT(nv10_screen);

if (!nv10screen)
return NULL;

nv10screen->chipset = chipset;
nv10screen->nvws = nvws;

nv10screen->screen.winsys = winsys;

nv10screen->screen.destroy = nv10_screen_destroy;

nv10screen->screen.get_name = nv10_screen_get_name;
nv10screen->screen.get_vendor = nv10_screen_get_vendor;
nv10screen->screen.get_param = nv10_screen_get_param;
nv10screen->screen.get_paramf = nv10_screen_get_paramf;
nv10screen->screen.is_format_supported =
nv10_screen_is_format_supported;

nv10_init_miptree_functions(&nv10screen->screen);
return &nv10screen->screen;
}


+ 19
- 0
src/gallium/drivers/nv10/nv10_screen.h 查看文件

@@ -0,0 +1,19 @@
#ifndef __NV10_SCREEN_H__
#define __NV10_SCREEN_H__

#include "pipe/p_screen.h"

struct nv10_screen {
struct pipe_screen screen;

struct nouveau_winsys *nvws;
unsigned chipset;
};

static INLINE struct nv10_screen *
nv10_screen(struct pipe_screen *screen)
{
return (struct nv10_screen *)screen;
}

#endif

+ 697
- 0
src/gallium/drivers/nv10/nv10_state.c 查看文件

@@ -0,0 +1,697 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"


#include "nv10_context.h"
#include "nv10_state.h"

static void nv10_vertex_layout(struct pipe_context* pipe)
{
struct nv10_context *nv10 = nv10_context(pipe);
const struct pipe_shader_state *fs = nv10->fragprog.current->pipe;
uint32_t src = 0;
int i;
struct vertex_info vinfo;

memset(&vinfo, 0, sizeof(vinfo));

for (i = 0; i < fs->num_inputs; i++) {
switch (fs->input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
break;
case TGSI_SEMANTIC_COLOR:
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
break;
default:
case TGSI_SEMANTIC_GENERIC:
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
break;
case TGSI_SEMANTIC_FOG:
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
break;
}
}
draw_compute_vertex_size(&vinfo);
}

static void *
nv10_blend_state_create(struct pipe_context *pipe,
const struct pipe_blend_state *cso)
{
struct nv10_blend_state *cb;

cb = malloc(sizeof(struct nv10_blend_state));

cb->b_enable = cso->blend_enable ? 1 : 0;
cb->b_srcfunc = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
(nvgl_blend_func(cso->rgb_src_factor)));
cb->b_dstfunc = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
(nvgl_blend_func(cso->rgb_dst_factor)));

cb->c_mask = (((cso->colormask & PIPE_MASK_A) ? (0x01<<24) : 0) |
((cso->colormask & PIPE_MASK_R) ? (0x01<<16) : 0) |
((cso->colormask & PIPE_MASK_G) ? (0x01<< 8) : 0) |
((cso->colormask & PIPE_MASK_B) ? (0x01<< 0) : 0));

cb->d_enable = cso->dither ? 1 : 0;

return (void *)cb;
}

static void
nv10_blend_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_blend_state *cb = hwcso;

BEGIN_RING(celsius, NV10TCL_DITHER_ENABLE, 1);
OUT_RING (cb->d_enable);

BEGIN_RING(celsius, NV10TCL_BLEND_FUNC_ENABLE, 3);
OUT_RING (cb->b_enable);
OUT_RING (cb->b_srcfunc);
OUT_RING (cb->b_dstfunc);

BEGIN_RING(celsius, NV10TCL_COLOR_MASK, 1);
OUT_RING (cb->c_mask);
}

static void
nv10_blend_state_delete(struct pipe_context *pipe, void *hwcso)
{
free(hwcso);
}


static INLINE unsigned
wrap_mode(unsigned wrap) {
unsigned ret;

switch (wrap) {
case PIPE_TEX_WRAP_REPEAT:
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
ret = NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT;
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE;
break;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER;
break;
case PIPE_TEX_WRAP_CLAMP:
ret = NV10TCL_TX_FORMAT_WRAP_S_CLAMP;
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
case PIPE_TEX_WRAP_MIRROR_CLAMP:
default:
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
ret = NV10TCL_TX_FORMAT_WRAP_S_REPEAT;
break;
}

return ret >> NV10TCL_TX_FORMAT_WRAP_S_SHIFT;
}

static void *
nv10_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso)
{
struct nv10_sampler_state *ps;
uint32_t filter = 0;

ps = malloc(sizeof(struct nv10_sampler_state));

ps->wrap = ((wrap_mode(cso->wrap_s) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT) |
(wrap_mode(cso->wrap_t) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT));

ps->en = 0;
if (cso->max_anisotropy > 1.0) {
/* no idea, binary driver sets it, works without it.. meh.. */
ps->wrap |= (1 << 5);

/* if (cso->max_anisotropy >= 16.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_16X;
} else
if (cso->max_anisotropy >= 12.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_12X;
} else
if (cso->max_anisotropy >= 10.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_10X;
} else
if (cso->max_anisotropy >= 8.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_8X;
} else
if (cso->max_anisotropy >= 6.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_6X;
} else
if (cso->max_anisotropy >= 4.0) {
ps->en |= NV10TCL_TX_ENABLE_ANISO_4X;
} else {
ps->en |= NV10TCL_TX_ENABLE_ANISO_2X;
}*/
}

switch (cso->mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
filter |= NV10TCL_TX_FILTER_MAGNIFY_LINEAR;
break;
case PIPE_TEX_FILTER_NEAREST:
default:
filter |= NV10TCL_TX_FILTER_MAGNIFY_NEAREST;
break;
}

switch (cso->min_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV10TCL_TX_FILTER_MINIFY_LINEAR;
break;
}
break;
case PIPE_TEX_FILTER_NEAREST:
default:
switch (cso->min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
break;
case PIPE_TEX_MIPFILTER_LINEAR:
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
break;
case PIPE_TEX_MIPFILTER_NONE:
default:
filter |= NV10TCL_TX_FILTER_MINIFY_NEAREST;
break;
}
break;
}

ps->filt = filter;

/* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
switch (cso->compare_func) {
case PIPE_FUNC_NEVER:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
break;
case PIPE_FUNC_GREATER:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
break;
case PIPE_FUNC_EQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
break;
case PIPE_FUNC_GEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
break;
case PIPE_FUNC_LESS:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
break;
case PIPE_FUNC_NOTEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
break;
case PIPE_FUNC_LEQUAL:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
break;
case PIPE_FUNC_ALWAYS:
ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
break;
default:
break;
}
}*/

ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
(float_to_ubyte(cso->border_color[0]) << 16) |
(float_to_ubyte(cso->border_color[1]) << 8) |
(float_to_ubyte(cso->border_color[2]) << 0));

return (void *)ps;
}

static void
nv10_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
{
struct nv10_context *nv10 = nv10_context(pipe);
unsigned unit;

for (unit = 0; unit < nr; unit++) {
nv10->tex_sampler[unit] = sampler[unit];
nv10->dirty_samplers |= (1 << unit);
}
}

static void
nv10_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
{
free(hwcso);
}

static void
nv10_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
struct pipe_texture **miptree)
{
struct nv10_context *nv10 = nv10_context(pipe);
unsigned unit;

for (unit = 0; unit < nr; unit++) {
nv10->tex_miptree[unit] = (struct nv10_miptree *)miptree[unit];
nv10->dirty_samplers |= (1 << unit);
}
}

static void *
nv10_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
{
struct nv10_rasterizer_state *rs;
int i;

/*XXX: ignored:
* light_twoside
* offset_cw/ccw -nohw
* scissor
* point_smooth -nohw
* multisample
* offset_units / offset_scale
*/
rs = malloc(sizeof(struct nv10_rasterizer_state));

rs->shade_model = cso->flatshade ? 0x1d00 : 0x1d01;

rs->line_width = (unsigned char)(cso->line_width * 8.0) & 0xff;
rs->line_smooth_en = cso->line_smooth ? 1 : 0;

rs->point_size = *(uint32_t*)&cso->point_size;

rs->poly_smooth_en = cso->poly_smooth ? 1 : 0;

if (cso->front_winding == PIPE_WINDING_CCW) {
rs->front_face = NV10TCL_FRONT_FACE_CCW;
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_ccw);
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_cw);
} else {
rs->front_face = NV10TCL_FRONT_FACE_CW;
rs->poly_mode_front = nvgl_polygon_mode(cso->fill_cw);
rs->poly_mode_back = nvgl_polygon_mode(cso->fill_ccw);
}

switch (cso->cull_mode) {
case PIPE_WINDING_CCW:
rs->cull_face_en = 1;
if (cso->front_winding == PIPE_WINDING_CCW)
rs->cull_face = NV10TCL_CULL_FACE_FRONT;
else
rs->cull_face = NV10TCL_CULL_FACE_BACK;
break;
case PIPE_WINDING_CW:
rs->cull_face_en = 1;
if (cso->front_winding == PIPE_WINDING_CW)
rs->cull_face = NV10TCL_CULL_FACE_FRONT;
else
rs->cull_face = NV10TCL_CULL_FACE_BACK;
break;
case PIPE_WINDING_BOTH:
rs->cull_face_en = 1;
rs->cull_face = NV10TCL_CULL_FACE_FRONT_AND_BACK;
break;
case PIPE_WINDING_NONE:
default:
rs->cull_face_en = 0;
rs->cull_face = 0;
break;
}

if (cso->point_sprite) {
rs->point_sprite = (1 << 0);
for (i = 0; i < 8; i++) {
if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
rs->point_sprite |= (1 << (8 + i));
}
} else {
rs->point_sprite = 0;
}

return (void *)rs;
}

static void
nv10_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_rasterizer_state *rs = hwcso;

BEGIN_RING(celsius, NV10TCL_SHADE_MODEL, 2);
OUT_RING (rs->shade_model);
OUT_RING (rs->line_width);


BEGIN_RING(celsius, NV10TCL_POINT_SIZE, 1);
OUT_RING (rs->point_size);

BEGIN_RING(celsius, NV10TCL_POLYGON_MODE_FRONT, 2);
OUT_RING (rs->poly_mode_front);
OUT_RING (rs->poly_mode_back);


BEGIN_RING(celsius, NV10TCL_CULL_FACE, 2);
OUT_RING (rs->cull_face);
OUT_RING (rs->front_face);

BEGIN_RING(celsius, NV10TCL_LINE_SMOOTH_ENABLE, 2);
OUT_RING (rs->line_smooth_en);
OUT_RING (rs->poly_smooth_en);

BEGIN_RING(celsius, NV10TCL_CULL_FACE_ENABLE, 1);
OUT_RING (rs->cull_face_en);

/* BEGIN_RING(celsius, NV10TCL_POINT_SPRITE, 1);
OUT_RING (rs->point_sprite);*/
}

static void
nv10_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
{
free(hwcso);
}

static void *
nv10_depth_stencil_alpha_state_create(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *cso)
{
struct nv10_depth_stencil_alpha_state *hw;

hw = malloc(sizeof(struct nv10_depth_stencil_alpha_state));

hw->depth.func = nvgl_comparison_op(cso->depth.func);
hw->depth.write_enable = cso->depth.writemask ? 1 : 0;
hw->depth.test_enable = cso->depth.enabled ? 1 : 0;

hw->stencil.enable = cso->stencil[0].enabled ? 1 : 0;
hw->stencil.wmask = cso->stencil[0].write_mask;
hw->stencil.func = nvgl_comparison_op(cso->stencil[0].func);
hw->stencil.ref = cso->stencil[0].ref_value;
hw->stencil.vmask = cso->stencil[0].value_mask;
hw->stencil.fail = nvgl_stencil_op(cso->stencil[0].fail_op);
hw->stencil.zfail = nvgl_stencil_op(cso->stencil[0].zfail_op);
hw->stencil.zpass = nvgl_stencil_op(cso->stencil[0].zpass_op);

hw->alpha.enabled = cso->alpha.enabled ? 1 : 0;
hw->alpha.func = nvgl_comparison_op(cso->alpha.func);
hw->alpha.ref = float_to_ubyte(cso->alpha.ref);

return (void *)hw;
}

static void
nv10_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_depth_stencil_alpha_state *hw = hwcso;

BEGIN_RING(celsius, NV10TCL_DEPTH_FUNC, 3);
OUT_RINGp ((uint32_t *)&hw->depth, 3);
BEGIN_RING(celsius, NV10TCL_STENCIL_ENABLE, 1);
OUT_RING (hw->stencil.enable);
BEGIN_RING(celsius, NV10TCL_STENCIL_MASK, 7);
OUT_RINGp ((uint32_t *)&(hw->stencil.wmask), 7);
BEGIN_RING(celsius, NV10TCL_ALPHA_FUNC_ENABLE, 3);
OUT_RINGp ((uint32_t *)&hw->alpha.enabled, 3);
}

static void
nv10_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
{
free(hwcso);
}

static void *
nv10_vp_state_create(struct pipe_context *pipe,
const struct pipe_shader_state *cso)
{
struct nv10_vertex_program *vp;

vp = CALLOC(1, sizeof(struct nv10_vertex_program));
vp->pipe = cso;

return (void *)vp;
}

static void
nv10_vp_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_vertex_program *vp = hwcso;

nv10->vertprog.current = vp;
nv10->dirty |= NV10_NEW_VERTPROG;
}

static void
nv10_vp_state_delete(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_vertex_program *vp = hwcso;

//nv10_vertprog_destroy(nv10, vp);
free(vp);
}

static void *
nv10_fp_state_create(struct pipe_context *pipe,
const struct pipe_shader_state *cso)
{
struct nv10_fragment_program *fp;

fp = CALLOC(1, sizeof(struct nv10_fragment_program));
fp->pipe = cso;

return (void *)fp;
}

static void
nv10_fp_state_bind(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_fragment_program *fp = hwcso;

nv10->fragprog.current = fp;
nv10->dirty |= NV10_NEW_FRAGPROG;
}

static void
nv10_fp_state_delete(struct pipe_context *pipe, void *hwcso)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nv10_fragment_program *fp = hwcso;

nv10_fragprog_destroy(nv10, fp);
free(fp);
}

static void
nv10_set_blend_color(struct pipe_context *pipe,
const struct pipe_blend_color *bcol)
{
struct nv10_context *nv10 = nv10_context(pipe);

BEGIN_RING(celsius, NV10TCL_BLEND_COLOR, 1);
OUT_RING ((float_to_ubyte(bcol->color[3]) << 24) |
(float_to_ubyte(bcol->color[0]) << 16) |
(float_to_ubyte(bcol->color[1]) << 8) |
(float_to_ubyte(bcol->color[2]) << 0));
}

static void
nv10_set_clip_state(struct pipe_context *pipe,
const struct pipe_clip_state *clip)
{
}

static void
nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
const struct pipe_constant_buffer *buf )
{
struct nv10_context *nv10 = nv10_context(pipe);

if (shader == PIPE_SHADER_VERTEX) {
nv10->vertprog.constant_buf = buf->buffer;
nv10->dirty |= NV10_NEW_VERTPROG;
} else
if (shader == PIPE_SHADER_FRAGMENT) {
nv10->fragprog.constant_buf = buf->buffer;
nv10->dirty |= NV10_NEW_FRAGPROG;
}
}

static void
nv10_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct pipe_surface *rt, *zeta;
uint32_t rt_format, w, h;
int i, colour_format = 0, zeta_format = 0;

w = fb->cbufs[0]->width;
h = fb->cbufs[0]->height;
colour_format = fb->cbufs[0]->format;
rt = fb->cbufs[0];

if (fb->zsbuf) {
if (colour_format) {
assert(w == fb->zsbuf->width);
assert(h == fb->zsbuf->height);
} else {
w = fb->zsbuf->width;
h = fb->zsbuf->height;
}

zeta_format = fb->zsbuf->format;
zeta = fb->zsbuf;
}

rt_format = NV10TCL_RT_FORMAT_TYPE_LINEAR;

switch (colour_format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
case 0:
rt_format |= NV10TCL_RT_FORMAT_COLOR_A8R8G8B8;
break;
case PIPE_FORMAT_R5G6B5_UNORM:
rt_format |= NV10TCL_RT_FORMAT_COLOR_R5G6B5;
break;
default:
assert(0);
}

BEGIN_RING(celsius, NV10TCL_RT_PITCH, 1);
OUT_RING ( (rt->pitch * rt->cpp) | ( (zeta->pitch * zeta->cpp) << 16) );
nv10->rt[0] = rt->buffer;

if (zeta_format)
{
nv10->zeta = zeta->buffer;
}

BEGIN_RING(celsius, NV10TCL_RT_HORIZ, 3);
OUT_RING ((w << 16) | 0);
OUT_RING ((h << 16) | 0);
OUT_RING (rt_format);
BEGIN_RING(celsius, NV10TCL_VIEWPORT_CLIP_HORIZ(0), 2);
OUT_RING (((w - 1) << 16) | 0);
OUT_RING (((h - 1) << 16) | 0);
}

static void
nv10_set_polygon_stipple(struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple)
{
NOUVEAU_ERR("line stipple hahaha\n");
}

static void
nv10_set_scissor_state(struct pipe_context *pipe,
const struct pipe_scissor_state *s)
{
struct nv10_context *nv10 = nv10_context(pipe);

// XXX
/* BEGIN_RING(celsius, NV10TCL_SCISSOR_HORIZ, 2);
OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
}

static void
nv10_set_viewport_state(struct pipe_context *pipe,
const struct pipe_viewport_state *vpt)
{
struct nv10_context *nv10 = nv10_context(pipe);

/* OUT_RINGf (vpt->translate[0]);
OUT_RINGf (vpt->translate[1]);
OUT_RINGf (vpt->translate[2]);
OUT_RINGf (vpt->translate[3]);*/
BEGIN_RING(celsius, NV10TCL_VIEWPORT_SCALE_X, 4);
OUT_RINGf (vpt->scale[0]);
OUT_RINGf (vpt->scale[1]);
OUT_RINGf (vpt->scale[2]);
OUT_RINGf (vpt->scale[3]);
}

static void
nv10_set_vertex_buffer(struct pipe_context *pipe, unsigned index,
const struct pipe_vertex_buffer *vb)
{
struct nv10_context *nv10 = nv10_context(pipe);

nv10->vtxbuf[index] = *vb;

nv10->dirty |= NV10_NEW_ARRAYS;
}

static void
nv10_set_vertex_element(struct pipe_context *pipe, unsigned index,
const struct pipe_vertex_element *ve)
{
struct nv10_context *nv10 = nv10_context(pipe);

nv10->vtxelt[index] = *ve;

nv10->dirty |= NV10_NEW_ARRAYS;
}

void
nv10_init_state_functions(struct nv10_context *nv10)
{
nv10->pipe.create_blend_state = nv10_blend_state_create;
nv10->pipe.bind_blend_state = nv10_blend_state_bind;
nv10->pipe.delete_blend_state = nv10_blend_state_delete;

nv10->pipe.create_sampler_state = nv10_sampler_state_create;
nv10->pipe.bind_sampler_states = nv10_sampler_state_bind;
nv10->pipe.delete_sampler_state = nv10_sampler_state_delete;
nv10->pipe.set_sampler_textures = nv10_set_sampler_texture;

nv10->pipe.create_rasterizer_state = nv10_rasterizer_state_create;
nv10->pipe.bind_rasterizer_state = nv10_rasterizer_state_bind;
nv10->pipe.delete_rasterizer_state = nv10_rasterizer_state_delete;

nv10->pipe.create_depth_stencil_alpha_state =
nv10_depth_stencil_alpha_state_create;
nv10->pipe.bind_depth_stencil_alpha_state =
nv10_depth_stencil_alpha_state_bind;
nv10->pipe.delete_depth_stencil_alpha_state =
nv10_depth_stencil_alpha_state_delete;

nv10->pipe.create_vs_state = nv10_vp_state_create;
nv10->pipe.bind_vs_state = nv10_vp_state_bind;
nv10->pipe.delete_vs_state = nv10_vp_state_delete;

nv10->pipe.create_fs_state = nv10_fp_state_create;
nv10->pipe.bind_fs_state = nv10_fp_state_bind;
nv10->pipe.delete_fs_state = nv10_fp_state_delete;

nv10->pipe.set_blend_color = nv10_set_blend_color;
nv10->pipe.set_clip_state = nv10_set_clip_state;
nv10->pipe.set_constant_buffer = nv10_set_constant_buffer;
nv10->pipe.set_framebuffer_state = nv10_set_framebuffer_state;
nv10->pipe.set_polygon_stipple = nv10_set_polygon_stipple;
nv10->pipe.set_scissor_state = nv10_set_scissor_state;
nv10->pipe.set_viewport_state = nv10_set_viewport_state;

nv10->pipe.set_vertex_buffer = nv10_set_vertex_buffer;
nv10->pipe.set_vertex_element = nv10_set_vertex_element;
}


+ 135
- 0
src/gallium/drivers/nv10/nv10_state.h 查看文件

@@ -0,0 +1,135 @@
#ifndef __NV10_STATE_H__
#define __NV10_STATE_H__

#include "pipe/p_state.h"

struct nv10_blend_state {
uint32_t b_enable;
uint32_t b_srcfunc;
uint32_t b_dstfunc;

uint32_t c_mask;

uint32_t d_enable;
};

struct nv10_sampler_state {
uint32_t wrap;
uint32_t en;
uint32_t filt;
uint32_t bcol;
};

struct nv10_rasterizer_state {
uint32_t shade_model;

uint32_t line_width;
uint32_t line_smooth_en;

uint32_t point_size;

uint32_t poly_smooth_en;
uint32_t poly_mode_front;
uint32_t poly_mode_back;

uint32_t front_face;
uint32_t cull_face;
uint32_t cull_face_en;

uint32_t point_sprite;
};

struct nv10_vertex_program_exec {
uint32_t data[4];
boolean has_branch_offset;
int const_index;
};

struct nv10_vertex_program_data {
int index; /* immediates == -1 */
float value[4];
};

struct nv10_vertex_program {
const struct pipe_shader_state *pipe;

boolean translated;
struct nv10_vertex_program_exec *insns;
unsigned nr_insns;
struct nv10_vertex_program_data *consts;
unsigned nr_consts;

struct nouveau_resource *exec;
unsigned exec_start;
struct nouveau_resource *data;
unsigned data_start;
unsigned data_start_min;

uint32_t ir;
uint32_t or;
};

struct nv10_fragment_program_data {
unsigned offset;
unsigned index;
};

struct nv10_fragment_program {
const struct pipe_shader_state *pipe;

boolean translated;
boolean on_hw;
unsigned samplers;

uint32_t *insn;
int insn_len;

struct nv10_fragment_program_data *consts;
unsigned nr_consts;

struct pipe_buffer *buffer;

uint32_t fp_control;
uint32_t fp_reg_control;
};


struct nv10_depth_stencil_alpha_state {
struct {
uint32_t func;
uint32_t write_enable;
uint32_t test_enable;
} depth;

struct {
uint32_t enable;
uint32_t wmask;
uint32_t func;
uint32_t ref;
uint32_t vmask;
uint32_t fail;
uint32_t zfail;
uint32_t zpass;
} stencil;

struct {
uint32_t enabled;
uint32_t func;
uint32_t ref;
} alpha;
};

struct nv10_miptree {
struct pipe_texture base;

struct pipe_buffer *buffer;
uint total_size;

struct {
uint pitch;
uint *image_offset;
} level[PIPE_MAX_TEXTURE_LEVELS];
};

#endif

+ 69
- 0
src/gallium/drivers/nv10/nv10_state_emit.c 查看文件

@@ -0,0 +1,69 @@
#include "nv10_context.h"
#include "nv10_state.h"

void
nv10_emit_hw_state(struct nv10_context *nv10)
{
int i;

if (nv10->dirty & NV10_NEW_FRAGPROG) {
nv10_fragprog_bind(nv10, nv10->fragprog.current);
/*XXX: clear NV10_NEW_FRAGPROG if no new program uploaded */
}

if (nv10->dirty_samplers || (nv10->dirty & NV10_NEW_FRAGPROG)) {
nv10_fragtex_bind(nv10);
nv10->dirty &= ~NV10_NEW_FRAGPROG;
}

if (nv10->dirty & NV10_NEW_VERTPROG) {
//nv10_vertprog_bind(nv10, nv10->vertprog.current);
nv10->dirty &= ~NV10_NEW_VERTPROG;
}

if (nv10->dirty & NV10_NEW_VBO) {
}

nv10->dirty_samplers = 0;

/* Emit relocs for every referenced buffer.
* This is to ensure the bufmgr has an accurate idea of how
* the buffer is used. This isn't very efficient, but we don't
* seem to take a significant performance hit. Will be improved
* at some point. Vertex arrays are emitted by nv10_vbo.c
*/

/* Render target */
// XXX figre out who's who for NV10TCL_DMA_* and fill accordingly
// BEGIN_RING(celsius, NV10TCL_DMA_COLOR0, 1);
// OUT_RELOCo(nv10->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
BEGIN_RING(celsius, NV10TCL_COLOR_OFFSET, 1);
OUT_RELOCl(nv10->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);

if (nv10->zeta) {
// XXX
// BEGIN_RING(celsius, NV10TCL_DMA_ZETA, 1);
// OUT_RELOCo(nv10->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
BEGIN_RING(celsius, NV10TCL_ZETA_OFFSET, 1);
OUT_RELOCl(nv10->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
/* XXX for when we allocate LMA on nv17 */
/* BEGIN_RING(celsius, NV10TCL_LMA_DEPTH_OFFSET, 1);
OUT_RELOCl(nv10->zeta+...);*/
}

/* Texture images */
for (i = 0; i < 2; i++) {
if (!(nv10->fp_samplers & (1 << i)))
continue;
BEGIN_RING(celsius, NV10TCL_TX_OFFSET(i), 2);
OUT_RELOCl(nv10->tex[i].buffer, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART | NOUVEAU_BO_RD);
// XXX
/* OUT_RELOCd(nv10->tex[i].buffer, nv10->tex[i].format,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
NOUVEAU_BO_OR, NV10TCL_TX_FORMAT_DMA0,
NV10TCL_TX_FORMAT_DMA1);*/
}
}


+ 65
- 0
src/gallium/drivers/nv10/nv10_surface.c 查看文件

@@ -0,0 +1,65 @@

/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/

#include "nv10_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
#include "pipe/p_winsys.h"
#include "pipe/p_inlines.h"
#include "util/p_tile.h"

static void
nv10_surface_copy(struct pipe_context *pipe, unsigned do_flip,
struct pipe_surface *dest, unsigned destx, unsigned desty,
struct pipe_surface *src, unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nouveau_winsys *nvws = nv10->nvws;

nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy,
width, height);
}

static void
nv10_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
unsigned destx, unsigned desty, unsigned width,
unsigned height, unsigned value)
{
struct nv10_context *nv10 = nv10_context(pipe);
struct nouveau_winsys *nvws = nv10->nvws;

nvws->surface_fill(nvws, dest, destx, desty, width, height, value);
}

void
nv10_init_surface_functions(struct nv10_context *nv10)
{
nv10->pipe.surface_copy = nv10_surface_copy;
nv10->pipe.surface_fill = nv10_surface_fill;
}

+ 72
- 0
src/gallium/drivers/nv10/nv10_vbo.c 查看文件

@@ -0,0 +1,72 @@
#include "draw/draw_context.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "pipe/p_util.h"

#include "nv10_context.h"
#include "nv10_state.h"

#include "nouveau/nouveau_channel.h"
#include "nouveau/nouveau_pushbuf.h"

boolean nv10_draw_elements( struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned prim, unsigned start, unsigned count)
{
struct nv10_context *nv10 = nv10_context( pipe );
struct draw_context *draw = nv10->draw;
unsigned i;

/*
* Map vertex buffers
*/
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
if (nv10->vtxbuf[i].buffer) {
void *buf
= pipe->winsys->buffer_map(pipe->winsys,
nv10->vtxbuf[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
/* Map index buffer, if present */
if (indexBuffer) {
void *mapped_indexes
= pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
/* no index/element buffer */
draw_set_mapped_element_buffer(draw, 0, NULL);
}

/* draw! */
draw_arrays(nv10->draw, prim, start, count);

/*
* unmap vertex/index buffers
*/
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
if (nv10->vtxbuf[i].buffer) {
pipe->winsys->buffer_unmap(pipe->winsys, nv10->vtxbuf[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
if (indexBuffer) {
pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
draw_set_mapped_element_buffer(draw, 0, NULL);
}

return TRUE;
}

boolean nv10_draw_arrays( struct pipe_context *pipe,
unsigned prim, unsigned start, unsigned count)
{
return nv10_draw_elements(pipe, NULL, 0, prim, start, count);
}




+ 1
- 0
src/gallium/winsys/dri/nouveau/Makefile 查看文件

@@ -8,6 +8,7 @@ MINIGLX_SOURCES =

PIPE_DRIVERS = \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
$(TOP)/src/gallium/drivers/nv50/libnv50.a

+ 3
- 0
src/gallium/winsys/dri/nouveau/nouveau_context.c 查看文件

@@ -119,6 +119,9 @@ nouveau_context_create(const __GLcontextModes *glVis,
}

switch (nv->chipset & 0xf0) {
case 0x10:
case 0x20:
/* NV10 */
case 0x30:
/* NV30 */
case 0x40:

+ 5
- 0
src/gallium/winsys/dri/nouveau/nouveau_winsys.c 查看文件

@@ -82,6 +82,11 @@ nouveau_pipe_create(struct nouveau_context *nv)
return NULL;

switch (nv->chipset & 0xf0) {
case 0x10:
case 0x20:
hws_create = nv10_screen_create;
hw_create = nv10_create;
break;
case 0x30:
hws_create = nv30_screen_create;
hw_create = nv30_create;

正在加载...
取消
保存