mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 17:48:10 +02:00
nv04.
This commit is contained in:
parent
6235141fd2
commit
52a68dd9eb
17 changed files with 1967 additions and 1 deletions
|
|
@ -70,7 +70,7 @@ PROGRAM_DIRS = demos redbook samples glsl xdemos
|
|||
# Gallium directories and
|
||||
GALLIUM_AUXILIARY_DIRS = draw cso_cache pipebuffer tgsi sct translate rtasm util
|
||||
GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a)
|
||||
GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv10 nv30 nv40 nv50 failover
|
||||
GALLIUM_DRIVER_DIRS = softpipe i915simple i965simple nv04 nv10 nv30 nv40 nv50 failover
|
||||
GALLIUM_WINSYS_COMMON_DIRS =
|
||||
GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a)
|
||||
GALLIUM_WINSYS_DIRS = xlib egl_xlib
|
||||
|
|
|
|||
|
|
@ -57,6 +57,12 @@ struct nouveau_winsys {
|
|||
unsigned, unsigned, unsigned, unsigned, unsigned);
|
||||
};
|
||||
|
||||
extern struct pipe_screen *
|
||||
nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
|
||||
|
||||
extern struct pipe_context *
|
||||
nv04_create(struct pipe_screen *, unsigned pctx_id);
|
||||
|
||||
extern struct pipe_screen *
|
||||
nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
|
||||
|
||||
|
|
|
|||
28
src/gallium/drivers/nv04/Makefile
Normal file
28
src/gallium/drivers/nv04/Makefile
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = nv04
|
||||
|
||||
DRIVER_SOURCES = \
|
||||
nv04_clear.c \
|
||||
nv04_context.c \
|
||||
nv04_fragprog.c \
|
||||
nv04_fragtex.c \
|
||||
nv04_miptree.c \
|
||||
nv04_prim_vbuf.c \
|
||||
nv04_screen.c \
|
||||
nv04_state.c \
|
||||
nv04_state_emit.c \
|
||||
nv04_surface.c \
|
||||
nv04_vbo.c
|
||||
|
||||
C_SOURCES = \
|
||||
$(COMMON_SOURCES) \
|
||||
$(DRIVER_SOURCES)
|
||||
|
||||
ASM_SOURCES =
|
||||
|
||||
include ../../Makefile.template
|
||||
|
||||
symlinks:
|
||||
|
||||
12
src/gallium/drivers/nv04/nv04_clear.c
Normal file
12
src/gallium/drivers/nv04/nv04_clear.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "nv04_context.h"
|
||||
|
||||
void
|
||||
nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||
unsigned clearValue)
|
||||
{
|
||||
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, clearValue);
|
||||
}
|
||||
107
src/gallium/drivers/nv04/nv04_context.c
Normal file
107
src/gallium/drivers/nv04/nv04_context.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#include "draw/draw_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
#include "nv04_context.h"
|
||||
#include "nv04_screen.h"
|
||||
|
||||
static void
|
||||
nv04_flush(struct pipe_context *pipe, unsigned flags,
|
||||
struct pipe_fence_handle **fence)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
draw_flush(nv04->draw);
|
||||
|
||||
FIRE_RING(fence);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_destroy(struct pipe_context *pipe)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
if (nv04->draw)
|
||||
draw_destroy(nv04->draw);
|
||||
|
||||
FREE(nv04);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
|
||||
{
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv04_init_hwctx(struct nv04_context *nv04)
|
||||
{
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOTIFY, 1);
|
||||
OUT_RING(0);
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_NOP, 1);
|
||||
OUT_RING(0);
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
|
||||
OUT_RING(0x40182800);
|
||||
// OUT_RING(1<<20/*no cull*/);
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
|
||||
// OUT_RING(0x24|(1<<6)|(1<<8));
|
||||
OUT_RING(0x120001a4);
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FORMAT, 1);
|
||||
OUT_RING(0x332213a1);
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FILTER, 1);
|
||||
OUT_RING(0x11001010);
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_COLORKEY, 1);
|
||||
OUT_RING(0x0);
|
||||
// BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 1);
|
||||
// OUT_RING(SCREEN_OFFSET);
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_FOGCOLOR, 1);
|
||||
OUT_RING(0xff000000);
|
||||
|
||||
|
||||
|
||||
FIRE_RING (NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
|
||||
{
|
||||
struct nv04_screen *screen = nv04_screen(pscreen);
|
||||
struct pipe_winsys *ws = pscreen->winsys;
|
||||
struct nv04_context *nv04;
|
||||
struct nouveau_winsys *nvws = screen->nvws;
|
||||
|
||||
nv04 = CALLOC(1, sizeof(struct nv04_context));
|
||||
if (!nv04)
|
||||
return NULL;
|
||||
nv04->screen = screen;
|
||||
nv04->pctx_id = pctx_id;
|
||||
|
||||
nv04->nvws = nvws;
|
||||
|
||||
nv04->pipe.winsys = ws;
|
||||
nv04->pipe.screen = pscreen;
|
||||
nv04->pipe.destroy = nv04_destroy;
|
||||
nv04->pipe.set_edgeflags = nv04_set_edgeflags;
|
||||
nv04->pipe.draw_arrays = nv04_draw_arrays;
|
||||
nv04->pipe.draw_elements = nv04_draw_elements;
|
||||
nv04->pipe.clear = nv04_clear;
|
||||
nv04->pipe.flush = nv04_flush;
|
||||
|
||||
nv04_init_surface_functions(nv04);
|
||||
nv04_init_state_functions(nv04);
|
||||
|
||||
nv04->draw = draw_create();
|
||||
assert(nv04->draw);
|
||||
draw_wide_point_threshold(nv04->draw, 0.0);
|
||||
draw_wide_line_threshold(nv04->draw, 0.0);
|
||||
draw_enable_line_stipple(nv04->draw, FALSE);
|
||||
draw_enable_point_sprites(nv04->draw, FALSE);
|
||||
draw_set_rasterize_stage(nv04->draw, nv04_draw_vbuf_stage(nv04));
|
||||
|
||||
nv04_init_hwctx(nv04);
|
||||
|
||||
return &nv04->pipe;
|
||||
}
|
||||
|
||||
142
src/gallium/drivers/nv04/nv04_context.h
Normal file
142
src/gallium/drivers/nv04/nv04_context.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#ifndef __NV04_CONTEXT_H__
|
||||
#define __NV04_CONTEXT_H__
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "draw/draw_vertex.h"
|
||||
|
||||
#include "nouveau/nouveau_winsys.h"
|
||||
#include "nouveau/nouveau_gldefs.h"
|
||||
|
||||
#define NOUVEAU_PUSH_CONTEXT(ctx) \
|
||||
struct nv04_screen *ctx = nv04->screen
|
||||
#include "nouveau/nouveau_push.h"
|
||||
|
||||
#include "nv04_state.h"
|
||||
|
||||
#define NOUVEAU_ERR(fmt, args...) \
|
||||
fprintf(stderr, "%s:%d - "fmt, __func__, __LINE__, ##args);
|
||||
#define NOUVEAU_MSG(fmt, args...) \
|
||||
fprintf(stderr, "nouveau: "fmt, ##args);
|
||||
|
||||
#include "nv04_screen.h"
|
||||
|
||||
#define NV04_NEW_VERTPROG (1 << 1)
|
||||
#define NV04_NEW_FRAGPROG (1 << 2)
|
||||
#define NV04_NEW_BLEND (1 << 3)
|
||||
#define NV04_NEW_RAST (1 << 4)
|
||||
#define NV04_NEW_CONTROL (1 << 5)
|
||||
#define NV04_NEW_VIEWPORT (1 << 6)
|
||||
#define NV04_NEW_SAMPLER (1 << 7)
|
||||
|
||||
struct nv04_context {
|
||||
struct pipe_context pipe;
|
||||
|
||||
struct nouveau_winsys *nvws;
|
||||
struct nv04_screen *screen;
|
||||
unsigned pctx_id;
|
||||
|
||||
struct draw_context *draw;
|
||||
|
||||
int chipset;
|
||||
struct nouveau_notifier *sync;
|
||||
|
||||
uint32_t dirty;
|
||||
|
||||
struct nv04_blend_state *blend;
|
||||
struct nv04_sampler_state *sampler[PIPE_MAX_SAMPLERS];
|
||||
struct nv04_fragtex_state fragtex;
|
||||
struct nv04_rasterizer_state *rast;
|
||||
struct nv04_depth_stencil_alpha_state *dsa;
|
||||
|
||||
struct nv04_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
|
||||
unsigned dirty_samplers;
|
||||
unsigned fp_samplers;
|
||||
unsigned vp_samplers;
|
||||
|
||||
uint32_t rt_enable;
|
||||
struct pipe_buffer *rt[4];
|
||||
struct pipe_buffer *zeta;
|
||||
|
||||
struct {
|
||||
struct pipe_buffer *buffer;
|
||||
uint32_t format;
|
||||
} tex[16];
|
||||
|
||||
unsigned vb_enable;
|
||||
struct {
|
||||
struct pipe_buffer *buffer;
|
||||
unsigned delta;
|
||||
} vb[16];
|
||||
|
||||
struct vertex_info vertex_info;
|
||||
struct {
|
||||
|
||||
struct nouveau_resource *exec_heap;
|
||||
struct nouveau_resource *data_heap;
|
||||
|
||||
struct nv04_vertex_program *active;
|
||||
|
||||
struct nv04_vertex_program *current;
|
||||
struct pipe_buffer *constant_buf;
|
||||
} vertprog;
|
||||
|
||||
struct {
|
||||
struct nv04_fragment_program *active;
|
||||
|
||||
struct nv04_fragment_program *current;
|
||||
struct pipe_buffer *constant_buf;
|
||||
} fragprog;
|
||||
|
||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||
unsigned num_vertex_buffers;
|
||||
unsigned num_vertex_elements;
|
||||
|
||||
struct pipe_viewport_state viewport;
|
||||
};
|
||||
|
||||
static INLINE struct nv04_context *
|
||||
nv04_context(struct pipe_context *pipe)
|
||||
{
|
||||
return (struct nv04_context *)pipe;
|
||||
}
|
||||
|
||||
extern void nv04_init_state_functions(struct nv04_context *nv04);
|
||||
extern void nv04_init_surface_functions(struct nv04_context *nv04);
|
||||
extern void nv04_init_miptree_functions(struct pipe_screen *screen);
|
||||
|
||||
/* nv04_clear.c */
|
||||
extern void nv04_clear(struct pipe_context *pipe, struct pipe_surface *ps,
|
||||
unsigned clearValue);
|
||||
|
||||
/* nv04_draw.c */
|
||||
extern struct draw_stage *nv04_draw_render_stage(struct nv04_context *nv04);
|
||||
|
||||
/* nv04_fragprog.c */
|
||||
extern void nv04_fragprog_bind(struct nv04_context *,
|
||||
struct nv04_fragment_program *);
|
||||
extern void nv04_fragprog_destroy(struct nv04_context *,
|
||||
struct nv04_fragment_program *);
|
||||
|
||||
/* nv04_fragtex.c */
|
||||
extern void nv04_fragtex_bind(struct nv04_context *);
|
||||
|
||||
/* nv04_prim_vbuf.c */
|
||||
struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 );
|
||||
|
||||
/* nv04_state.c and friends */
|
||||
extern void nv04_emit_hw_state(struct nv04_context *nv04);
|
||||
extern void nv04_state_tex_update(struct nv04_context *nv04);
|
||||
|
||||
/* nv04_vbo.c */
|
||||
extern boolean nv04_draw_arrays(struct pipe_context *, unsigned mode,
|
||||
unsigned start, unsigned count);
|
||||
extern boolean nv04_draw_elements( struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned prim, unsigned start, unsigned count);
|
||||
|
||||
|
||||
#endif
|
||||
22
src/gallium/drivers/nv04/nv04_fragprog.c
Normal file
22
src/gallium/drivers/nv04/nv04_fragprog.c
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "tgsi/util/tgsi_parse.h"
|
||||
#include "tgsi/util/tgsi_util.h"
|
||||
|
||||
#include "nv04_context.h"
|
||||
|
||||
void
|
||||
nv04_fragprog_bind(struct nv04_context *nv04, struct nv04_fragment_program *fp)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nv04_fragprog_destroy(struct nv04_context *nv04,
|
||||
struct nv04_fragment_program *fp)
|
||||
{
|
||||
}
|
||||
|
||||
100
src/gallium/drivers/nv04/nv04_fragtex.c
Normal file
100
src/gallium/drivers/nv04/nv04_fragtex.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#include "nv04_context.h"
|
||||
|
||||
static INLINE int log2i(int i)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (i & 0xffff0000) {
|
||||
i >>= 16;
|
||||
r += 16;
|
||||
}
|
||||
if (i & 0x0000ff00) {
|
||||
i >>= 8;
|
||||
r += 8;
|
||||
}
|
||||
if (i & 0x000000f0) {
|
||||
i >>= 4;
|
||||
r += 4;
|
||||
}
|
||||
if (i & 0x0000000c) {
|
||||
i >>= 2;
|
||||
r += 2;
|
||||
}
|
||||
if (i & 0x00000002) {
|
||||
r += 1;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
#define _(m,tf) \
|
||||
{ \
|
||||
PIPE_FORMAT_##m, \
|
||||
NV04_DX5_TEXTURED_TRIANGLE_FORMAT_COLOR_##tf, \
|
||||
}
|
||||
|
||||
struct nv04_texture_format {
|
||||
uint pipe;
|
||||
int format;
|
||||
};
|
||||
|
||||
static struct nv04_texture_format
|
||||
nv04_texture_formats[] = {
|
||||
_(A8R8G8B8_UNORM, A8R8G8B8),
|
||||
_(X8R8G8B8_UNORM, X8R8G8B8),
|
||||
_(A1R5G5B5_UNORM, A1R5G5B5),
|
||||
_(A4R4G4B4_UNORM, A4R4G4B4),
|
||||
_(L8_UNORM, Y8 ),
|
||||
_(A8_UNORM, Y8 ),
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
nv04_fragtex_format(uint pipe_format)
|
||||
{
|
||||
struct nv04_texture_format *tf = nv04_texture_formats;
|
||||
char fs[128];
|
||||
int i;
|
||||
|
||||
for (i=0; i< sizeof(nv04_texture_formats)/sizeof(nv04_texture_formats[0]); i++) {
|
||||
if (tf->pipe == pipe_format)
|
||||
return tf->format;
|
||||
tf++;
|
||||
}
|
||||
|
||||
pf_sprint_name(fs, pipe_format);
|
||||
NOUVEAU_ERR("unknown texture format %s\n", fs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nv04_fragtex_build(struct nv04_context *nv04, int unit)
|
||||
{
|
||||
struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
|
||||
struct pipe_texture *pt = &nv04mt->base;
|
||||
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_2D:
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("Unknown target %d\n", pt->target);
|
||||
return;
|
||||
}
|
||||
|
||||
nv04->fragtex.format = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_ZOH_CORNER
|
||||
| NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ORIGIN_FOH_CORNER
|
||||
| nv04_fragtex_format(pt->format)
|
||||
| ( (pt->last_level + 1) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_MIPMAP_LEVELS_SHIFT )
|
||||
| ( log2i(pt->width[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_U_SHIFT )
|
||||
| ( log2i(pt->height[0]) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_BASE_SIZE_V_SHIFT )
|
||||
| NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE
|
||||
| NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_CLAMP_TO_EDGE
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nv04_fragtex_bind(struct nv04_context *nv04)
|
||||
{
|
||||
nv04_fragtex_build(nv04, 0);
|
||||
}
|
||||
|
||||
138
src/gallium/drivers/nv04/nv04_miptree.c
Normal file
138
src/gallium/drivers/nv04/nv04_miptree.c
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
|
||||
#include "nv04_context.h"
|
||||
#include "nv04_screen.h"
|
||||
|
||||
static void
|
||||
nv04_miptree_layout(struct nv04_miptree *nv04mt)
|
||||
{
|
||||
struct pipe_texture *pt = &nv04mt->base;
|
||||
uint width = pt->width[0], height = pt->height[0];
|
||||
uint offset = 0;
|
||||
int nr_faces, l, f;
|
||||
|
||||
nr_faces = 1;
|
||||
|
||||
for (l = 0; l <= pt->last_level; l++) {
|
||||
pt->width[l] = width;
|
||||
pt->height[l] = height;
|
||||
|
||||
pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
|
||||
pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
|
||||
|
||||
nv04mt->level[l].pitch = pt->width[0] * pt->block.size;
|
||||
nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63;
|
||||
|
||||
nv04mt->level[l].image_offset =
|
||||
CALLOC(nr_faces, sizeof(unsigned));
|
||||
|
||||
width = MAX2(1, width >> 1);
|
||||
height = MAX2(1, height >> 1);
|
||||
|
||||
}
|
||||
|
||||
for (f = 0; f < nr_faces; f++) {
|
||||
for (l = 0; l <= pt->last_level; l++) {
|
||||
nv04mt->level[l].image_offset[f] = offset;
|
||||
offset += nv04mt->level[l].pitch * pt->height[l];
|
||||
}
|
||||
}
|
||||
|
||||
nv04mt->total_size = offset;
|
||||
}
|
||||
|
||||
static struct pipe_texture *
|
||||
nv04_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct nv04_miptree *mt;
|
||||
|
||||
mt = MALLOC(sizeof(struct nv04_miptree));
|
||||
if (!mt)
|
||||
return NULL;
|
||||
mt->base = *pt;
|
||||
mt->base.refcount = 1;
|
||||
mt->base.screen = screen;
|
||||
|
||||
nv04_miptree_layout(mt);
|
||||
|
||||
mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL,
|
||||
mt->total_size);
|
||||
if (!mt->buffer) {
|
||||
free(mt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &mt->base;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_miptree_release(struct pipe_screen *screen, struct pipe_texture **pt)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
struct pipe_texture *mt = *pt;
|
||||
|
||||
*pt = NULL;
|
||||
if (--mt->refcount <= 0) {
|
||||
struct nv04_miptree *nv04mt = (struct nv04_miptree *)mt;
|
||||
int l;
|
||||
|
||||
pipe_buffer_reference(ws, &nv04mt->buffer, NULL);
|
||||
for (l = 0; l <= mt->last_level; l++) {
|
||||
if (nv04mt->level[l].image_offset)
|
||||
free(nv04mt->level[l].image_offset);
|
||||
}
|
||||
free(nv04mt);
|
||||
}
|
||||
}
|
||||
|
||||
static struct pipe_surface *
|
||||
nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
|
||||
unsigned face, unsigned level, unsigned zslice,
|
||||
unsigned flags)
|
||||
{
|
||||
struct pipe_winsys *ws = pscreen->winsys;
|
||||
struct nv04_miptree *nv04mt = (struct nv04_miptree *)pt;
|
||||
struct pipe_surface *ps;
|
||||
|
||||
ps = ws->surface_alloc(ws);
|
||||
if (!ps)
|
||||
return NULL;
|
||||
pipe_buffer_reference(ws, &ps->buffer, nv04mt->buffer);
|
||||
ps->format = pt->format;
|
||||
ps->width = pt->width[level];
|
||||
ps->height = pt->height[level];
|
||||
ps->block = pt->block;
|
||||
ps->width = pt->width[level];
|
||||
ps->height = pt->height[level];
|
||||
ps->nblocksx = pt->nblocksx[level];
|
||||
ps->nblocksy = pt->nblocksy[level];
|
||||
ps->stride = nv04mt->level[level].pitch;
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
||||
ps->offset = nv04mt->level[level].image_offset[face];
|
||||
} else {
|
||||
ps->offset = nv04mt->level[level].image_offset[0];
|
||||
}
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_miptree_surface_del(struct pipe_screen *pscreen,
|
||||
struct pipe_surface **psurface)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nv04_init_miptree_functions(struct pipe_screen *pscreen)
|
||||
{
|
||||
pscreen->texture_create = nv04_miptree_create;
|
||||
pscreen->texture_release = nv04_miptree_release;
|
||||
pscreen->get_tex_surface = nv04_miptree_surface_new;
|
||||
pscreen->tex_surface_release = nv04_miptree_surface_del;
|
||||
}
|
||||
|
||||
312
src/gallium/drivers/nv04/nv04_prim_vbuf.c
Normal file
312
src/gallium/drivers/nv04/nv04_prim_vbuf.c
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
|
||||
// XXX this has to go somewhere else
|
||||
#define NONINC_METHOD 0x40000000
|
||||
|
||||
|
||||
#include "draw/draw_vbuf.h"
|
||||
#include "pipe/p_debug.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
|
||||
#include "nv04_context.h"
|
||||
#include "nv04_state.h"
|
||||
|
||||
#define VERTEX_SIZE 40
|
||||
#define VERTEX_BUFFER_SIZE (4096*VERTEX_SIZE) // 4096 vertices of 40 bytes each
|
||||
|
||||
/**
|
||||
* Primitive renderer for nv04.
|
||||
*/
|
||||
struct nv04_vbuf_render {
|
||||
struct vbuf_render base;
|
||||
|
||||
struct nv04_context *nv04;
|
||||
|
||||
/** Vertex buffer */
|
||||
unsigned char* buffer;
|
||||
|
||||
/** Vertex size in bytes */
|
||||
unsigned vertex_size;
|
||||
|
||||
/** Current primitive */
|
||||
unsigned prim;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Basically a cast wrapper.
|
||||
*/
|
||||
static INLINE struct nv04_vbuf_render *
|
||||
nv04_vbuf_render( struct vbuf_render *render )
|
||||
{
|
||||
assert(render);
|
||||
return (struct nv04_vbuf_render *)render;
|
||||
}
|
||||
|
||||
|
||||
static const struct vertex_info *
|
||||
nv04_vbuf_render_get_vertex_info( struct vbuf_render *render )
|
||||
{
|
||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
||||
struct nv04_context *nv04 = nv04_render->nv04;
|
||||
return &nv04->vertex_info;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
nv04_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
||||
ushort vertex_size,
|
||||
ushort nr_vertices )
|
||||
{
|
||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
||||
|
||||
nv04_render->buffer = (unsigned char*) malloc(VERTEX_BUFFER_SIZE);
|
||||
assert(!nv04_render->buffer);
|
||||
|
||||
return nv04_render->buffer;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
nv04_vbuf_render_set_primitive( struct vbuf_render *render,
|
||||
unsigned prim )
|
||||
{
|
||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
||||
|
||||
if (prim <= PIPE_PRIM_LINE_STRIP)
|
||||
return FALSE;
|
||||
|
||||
nv04_render->prim = prim;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INLINE void nv04_2triangles(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3, ushort v4, ushort v5)
|
||||
{
|
||||
BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xA),49);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v0,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v1,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v2,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v3,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v4,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v5,8);
|
||||
OUT_RING(0xFEDCBA);
|
||||
}
|
||||
|
||||
static INLINE void nv04_1triangle(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2)
|
||||
{
|
||||
BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xD),25);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v0,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v1,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v2,8);
|
||||
OUT_RING(0xFED);
|
||||
}
|
||||
|
||||
static INLINE void nv04_1quad(struct nv04_context* nv04, unsigned char* buffer, ushort v0, ushort v1, ushort v2, ushort v3)
|
||||
{
|
||||
BEGIN_RING(fahrenheit,NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0xC),33);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v0,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v1,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v2,8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * v3,8);
|
||||
OUT_RING(0xFECEDC);
|
||||
}
|
||||
|
||||
static void nv04_vbuf_render_triangles_elts(struct nv04_vbuf_render * render, const ushort * indices, uint nr_indices)
|
||||
{
|
||||
unsigned char* buffer = render->buffer;
|
||||
struct nv04_context* nv04 = render->nv04;
|
||||
int i;
|
||||
|
||||
for( i=0; i< nr_indices-5; i+=6)
|
||||
nv04_2triangles(nv04,
|
||||
buffer,
|
||||
indices[i+0],
|
||||
indices[i+1],
|
||||
indices[i+2],
|
||||
indices[i+3],
|
||||
indices[i+4],
|
||||
indices[i+5]
|
||||
);
|
||||
if (i != nr_indices)
|
||||
{
|
||||
nv04_1triangle(nv04,
|
||||
buffer,
|
||||
indices[i+0],
|
||||
indices[i+1],
|
||||
indices[i+2]
|
||||
);
|
||||
i+=3;
|
||||
}
|
||||
if (i != nr_indices)
|
||||
NOUVEAU_ERR("Houston, we have lost some vertices\n");
|
||||
}
|
||||
|
||||
static void nv04_vbuf_render_tri_strip_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices)
|
||||
{
|
||||
const uint32_t striptbl[]={0x321210,0x543432,0x765654,0x987876,0xBA9A98,0xDCBCBA,0xFEDEDC};
|
||||
unsigned char* buffer = render->buffer;
|
||||
struct nv04_context* nv04 = render->nv04;
|
||||
int i,j;
|
||||
|
||||
for(i = 0; i<nr_indices; i+=14)
|
||||
{
|
||||
int numvert = MIN2(16, nr_indices - i);
|
||||
int numtri = numvert - 2;
|
||||
if (numvert<3)
|
||||
break;
|
||||
|
||||
BEGIN_RING( fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), numvert*8 );
|
||||
for(j = 0; j<numvert; j++)
|
||||
OUT_RINGp( buffer + VERTEX_SIZE * indices [i+j], 8 );
|
||||
|
||||
BEGIN_RING( fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE(0) | NONINC_METHOD, (numtri+1)/2 );
|
||||
for(j = 0; j<numtri/2; j++ )
|
||||
OUT_RING(striptbl[j]);
|
||||
if (numtri%2)
|
||||
OUT_RING(striptbl[numtri/2]&0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04_vbuf_render_tri_fan_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices)
|
||||
{
|
||||
const uint32_t fantbl[]={0x320210,0x540430,0x760650,0x980870,0xBA0A90,0xDC0CB0,0xFE0ED0};
|
||||
unsigned char* buffer = render->buffer;
|
||||
struct nv04_context* nv04 = render->nv04;
|
||||
int i,j;
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x0), 8);
|
||||
OUT_RINGp(buffer + VERTEX_SIZE * indices[0], 8);
|
||||
|
||||
for(i = 1; i<nr_indices; i+=14)
|
||||
{
|
||||
int numvert=MIN2(15, nr_indices - i);
|
||||
int numtri=numvert-2;
|
||||
if (numvert < 3)
|
||||
break;
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_SX(0x1), numvert*8);
|
||||
|
||||
for(j=0;j<numvert;j++)
|
||||
OUT_RINGp( buffer + VERTEX_SIZE * indices[ i+j ], 8 );
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_TLVERTEX_DRAWPRIMITIVE(0) | NONINC_METHOD, (numtri+1)/2);
|
||||
for(j = 0; j<numtri/2; j++)
|
||||
OUT_RING(fantbl[j]);
|
||||
if (numtri%2)
|
||||
OUT_RING(fantbl[numtri/2]&0xFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void nv04_vbuf_render_quads_elts(struct nv04_vbuf_render* render, const ushort* indices, uint nr_indices)
|
||||
{
|
||||
unsigned char* buffer = render->buffer;
|
||||
struct nv04_context* nv04 = render->nv04;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < nr_indices; i += 4)
|
||||
nv04_1quad(nv04,
|
||||
buffer,
|
||||
indices[i+0],
|
||||
indices[i+1],
|
||||
indices[i+2],
|
||||
indices[i+3]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nv04_vbuf_render_draw( struct vbuf_render *render,
|
||||
const ushort *indices,
|
||||
uint nr_indices)
|
||||
{
|
||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
||||
|
||||
// emit the indices
|
||||
switch( nv04_render->prim )
|
||||
{
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
nv04_vbuf_render_triangles_elts(nv04_render, indices, nr_indices);
|
||||
break;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
nv04_vbuf_render_tri_strip_elts(nv04_render, indices, nr_indices);
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
case PIPE_PRIM_POLYGON:
|
||||
nv04_vbuf_render_tri_fan_elts(nv04_render, indices, nr_indices);
|
||||
break;
|
||||
case PIPE_PRIM_QUADS:
|
||||
nv04_vbuf_render_quads_elts(nv04_render, indices, nr_indices);
|
||||
break;
|
||||
default:
|
||||
NOUVEAU_ERR("You have to implement primitive %d, young padawan\n", nv04_render->prim);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nv04_vbuf_render_release_vertices( struct vbuf_render *render,
|
||||
void *vertices,
|
||||
unsigned vertex_size,
|
||||
unsigned vertices_used )
|
||||
{
|
||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
||||
|
||||
free(nv04_render->buffer);
|
||||
nv04_render->buffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nv04_vbuf_render_destroy( struct vbuf_render *render )
|
||||
{
|
||||
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
|
||||
FREE(nv04_render);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new primitive render.
|
||||
*/
|
||||
static struct vbuf_render *
|
||||
nv04_vbuf_render_create( struct nv04_context *nv04 )
|
||||
{
|
||||
struct nv04_vbuf_render *nv04_render = CALLOC_STRUCT(nv04_vbuf_render);
|
||||
|
||||
nv04_render->nv04 = nv04;
|
||||
|
||||
nv04_render->base.max_vertex_buffer_bytes = VERTEX_BUFFER_SIZE;
|
||||
nv04_render->base.max_indices = 65536;
|
||||
nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info;
|
||||
nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices;
|
||||
nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive;
|
||||
nv04_render->base.draw = nv04_vbuf_render_draw;
|
||||
nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices;
|
||||
nv04_render->base.destroy = nv04_vbuf_render_destroy;
|
||||
|
||||
return &nv04_render->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new primitive vbuf/render stage.
|
||||
*/
|
||||
struct draw_stage *nv04_draw_vbuf_stage( struct nv04_context *nv04 )
|
||||
{
|
||||
struct vbuf_render *render;
|
||||
struct draw_stage *stage;
|
||||
|
||||
render = nv04_vbuf_render_create(nv04);
|
||||
if(!render)
|
||||
return NULL;
|
||||
|
||||
stage = draw_vbuf_stage( nv04->draw, render );
|
||||
if(!stage) {
|
||||
render->destroy(render);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stage;
|
||||
}
|
||||
216
src/gallium/drivers/nv04/nv04_screen.c
Normal file
216
src/gallium/drivers/nv04/nv04_screen.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
#include "nv04_context.h"
|
||||
#include "nv04_screen.h"
|
||||
|
||||
static const char *
|
||||
nv04_screen_get_name(struct pipe_screen *screen)
|
||||
{
|
||||
struct nv04_screen *nv04screen = nv04_screen(screen);
|
||||
struct nouveau_device *dev = nv04screen->nvws->channel->device;
|
||||
static char buffer[128];
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static const char *
|
||||
nv04_screen_get_vendor(struct pipe_screen *screen)
|
||||
{
|
||||
return "nouveau";
|
||||
}
|
||||
|
||||
static int
|
||||
nv04_screen_get_param(struct pipe_screen *screen, int param)
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
|
||||
return 1;
|
||||
case PIPE_CAP_NPOT_TEXTURES:
|
||||
return 0;
|
||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
||||
return 0;
|
||||
case PIPE_CAP_GLSL:
|
||||
return 0;
|
||||
case PIPE_CAP_S3TC:
|
||||
return 0;
|
||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
||||
return 0;
|
||||
case PIPE_CAP_POINT_SPRITE:
|
||||
return 0;
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
return 1;
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
return 0;
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
return 0;
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
return 10;
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
return 0;
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
return 0;
|
||||
default:
|
||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static float
|
||||
nv04_screen_get_paramf(struct pipe_screen *screen, int param)
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_CAP_MAX_LINE_WIDTH:
|
||||
case PIPE_CAP_MAX_LINE_WIDTH_AA:
|
||||
return 0.0;
|
||||
case PIPE_CAP_MAX_POINT_WIDTH:
|
||||
case PIPE_CAP_MAX_POINT_WIDTH_AA:
|
||||
return 0.0;
|
||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
||||
return 0.0;
|
||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
||||
return 0.0;
|
||||
default:
|
||||
NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
nv04_screen_is_format_supported(struct pipe_screen *screen,
|
||||
enum pipe_format format, uint type)
|
||||
{
|
||||
switch (type) {
|
||||
case PIPE_SURFACE:
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PIPE_TEXTURE:
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_X8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
case PIPE_FORMAT_L8_UNORM:
|
||||
case PIPE_FORMAT_A8_UNORM:
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
};
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void *
|
||||
nv04_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
|
||||
unsigned flags )
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
void *map;
|
||||
|
||||
map = ws->buffer_map(ws, surface->buffer, flags);
|
||||
if (!map)
|
||||
return NULL;
|
||||
|
||||
return map + surface->offset;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
|
||||
{
|
||||
struct pipe_winsys *ws = screen->winsys;
|
||||
|
||||
ws->buffer_unmap(ws, surface->buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_screen_destroy(struct pipe_screen *pscreen)
|
||||
{
|
||||
struct nv04_screen *screen = nv04_screen(pscreen);
|
||||
struct nouveau_winsys *nvws = screen->nvws;
|
||||
|
||||
nvws->notifier_free(&screen->sync);
|
||||
nvws->grobj_free(&screen->fahrenheit);
|
||||
|
||||
FREE(pscreen);
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
|
||||
{
|
||||
struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen);
|
||||
unsigned fahrenheit_class = 0, sub3d_class = 0;
|
||||
unsigned chipset = nvws->channel->device->chipset;
|
||||
int ret;
|
||||
|
||||
if (!screen)
|
||||
return NULL;
|
||||
screen->nvws = nvws;
|
||||
|
||||
if (chipset>=0x20) {
|
||||
fahrenheit_class = 0;
|
||||
sub3d_class = 0;
|
||||
} else if (chipset>=0x10) {
|
||||
fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE;
|
||||
sub3d_class = NV10_CONTEXT_SURFACES_3D;
|
||||
} else {
|
||||
fahrenheit_class=NV04_DX5_TEXTURED_TRIANGLE;
|
||||
sub3d_class = NV04_CONTEXT_SURFACES_3D;
|
||||
}
|
||||
|
||||
if (!fahrenheit_class) {
|
||||
NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", chipset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 3D object */
|
||||
ret = nvws->grobj_alloc(nvws, fahrenheit_class, &screen->fahrenheit);
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* 3D surface object */
|
||||
ret = nvws->grobj_alloc(nvws, sub3d_class, &screen->context_surfaces_3d);
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Notifier for sync purposes */
|
||||
ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
|
||||
if (ret) {
|
||||
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
|
||||
nv04_screen_destroy(&screen->pipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
screen->pipe.winsys = ws;
|
||||
screen->pipe.destroy = nv04_screen_destroy;
|
||||
|
||||
screen->pipe.get_name = nv04_screen_get_name;
|
||||
screen->pipe.get_vendor = nv04_screen_get_vendor;
|
||||
screen->pipe.get_param = nv04_screen_get_param;
|
||||
screen->pipe.get_paramf = nv04_screen_get_paramf;
|
||||
|
||||
screen->pipe.is_format_supported = nv04_screen_is_format_supported;
|
||||
|
||||
screen->pipe.surface_map = nv04_surface_map;
|
||||
screen->pipe.surface_unmap = nv04_surface_unmap;
|
||||
|
||||
nv04_screen_init_miptree_functions(&screen->pipe);
|
||||
|
||||
return &screen->pipe;
|
||||
}
|
||||
|
||||
25
src/gallium/drivers/nv04/nv04_screen.h
Normal file
25
src/gallium/drivers/nv04/nv04_screen.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef __NV04_SCREEN_H__
|
||||
#define __NV04_SCREEN_H__
|
||||
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
struct nv04_screen {
|
||||
struct pipe_screen pipe;
|
||||
|
||||
struct nouveau_winsys *nvws;
|
||||
unsigned chipset;
|
||||
|
||||
/* HW graphics objects */
|
||||
struct nouveau_grobj *fahrenheit;
|
||||
struct nouveau_grobj *context_surfaces_3d;
|
||||
struct nouveau_notifier *sync;
|
||||
|
||||
};
|
||||
|
||||
static INLINE struct nv04_screen *
|
||||
nv04_screen(struct pipe_screen *screen)
|
||||
{
|
||||
return (struct nv04_screen *)screen;
|
||||
}
|
||||
|
||||
#endif
|
||||
494
src/gallium/drivers/nv04/nv04_state.c
Normal file
494
src/gallium/drivers/nv04/nv04_state.c
Normal file
|
|
@ -0,0 +1,494 @@
|
|||
#include "draw/draw_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
|
||||
#include "nv04_context.h"
|
||||
#include "nv04_state.h"
|
||||
|
||||
static void *
|
||||
nv04_blend_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *cso)
|
||||
{
|
||||
struct nv04_blend_state *cb;
|
||||
|
||||
cb = malloc(sizeof(struct nv04_blend_state));
|
||||
|
||||
cb->b_enable = cso->blend_enable ? 1 : 0;
|
||||
cb->b_src = ((nvgl_blend_func(cso->alpha_src_factor)<<16) |
|
||||
(nvgl_blend_func(cso->rgb_src_factor)));
|
||||
cb->b_dst = ((nvgl_blend_func(cso->alpha_dst_factor)<<16) |
|
||||
(nvgl_blend_func(cso->rgb_dst_factor)));
|
||||
|
||||
|
||||
return (void *)cb;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_blend_state_bind(struct pipe_context *pipe, void *blend)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
nv04->blend = (struct nv04_blend_state*)blend;
|
||||
|
||||
nv04->dirty |= NV04_NEW_BLEND;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_blend_state_delete(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
free(hwcso);
|
||||
}
|
||||
|
||||
|
||||
static INLINE unsigned
|
||||
wrap_mode(unsigned wrap) {
|
||||
unsigned ret;
|
||||
|
||||
switch (wrap) {
|
||||
case PIPE_TEX_WRAP_REPEAT:
|
||||
ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT;
|
||||
break;
|
||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
||||
ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT;
|
||||
break;
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
||||
ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE;
|
||||
break;
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
||||
ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER;
|
||||
break;
|
||||
case PIPE_TEX_WRAP_CLAMP:
|
||||
ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
|
||||
break;
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
||||
default:
|
||||
NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
|
||||
ret = NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP;
|
||||
}
|
||||
return ret >> NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT;
|
||||
}
|
||||
|
||||
static void *
|
||||
nv04_sampler_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_sampler_state *cso)
|
||||
{
|
||||
|
||||
struct nv04_sampler_state *ss;
|
||||
uint32_t filter = 0;
|
||||
|
||||
ss = malloc(sizeof(struct nv04_sampler_state));
|
||||
|
||||
ss->format = ((wrap_mode(cso->wrap_s) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT) |
|
||||
(wrap_mode(cso->wrap_t) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT));
|
||||
|
||||
if (cso->max_anisotropy > 1.0) {
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE | NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE;
|
||||
}
|
||||
|
||||
switch (cso->mag_img_filter) {
|
||||
case PIPE_TEX_FILTER_LINEAR:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR;
|
||||
break;
|
||||
case PIPE_TEX_FILTER_NEAREST:
|
||||
default:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (cso->min_img_filter) {
|
||||
case PIPE_TEX_FILTER_LINEAR:
|
||||
switch (cso->min_mip_filter) {
|
||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
|
||||
break;
|
||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
|
||||
break;
|
||||
case PIPE_TEX_MIPFILTER_NONE:
|
||||
default:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PIPE_TEX_FILTER_NEAREST:
|
||||
default:
|
||||
switch (cso->min_mip_filter) {
|
||||
case PIPE_TEX_MIPFILTER_NEAREST:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
|
||||
break;
|
||||
case PIPE_TEX_MIPFILTER_LINEAR:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
|
||||
break;
|
||||
case PIPE_TEX_MIPFILTER_NONE:
|
||||
default:
|
||||
filter |= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ss->filter = filter;
|
||||
|
||||
return (void *)ss;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
unsigned unit;
|
||||
|
||||
for (unit = 0; unit < nr; unit++) {
|
||||
nv04->sampler[unit] = sampler[unit];
|
||||
nv04->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
free(hwcso);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
|
||||
struct pipe_texture **miptree)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
unsigned unit;
|
||||
|
||||
for (unit = 0; unit < nr; unit++) {
|
||||
nv04->tex_miptree[unit] = (struct nv04_miptree *)miptree[unit];
|
||||
nv04->dirty_samplers |= (1 << unit);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
nv04_rasterizer_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_rasterizer_state *cso)
|
||||
{
|
||||
struct nv04_rasterizer_state *rs;
|
||||
|
||||
/*XXX: ignored:
|
||||
* scissor
|
||||
* points/lines (no hw support, emulated with tris in gallium)
|
||||
*/
|
||||
rs = malloc(sizeof(struct nv04_rasterizer_state));
|
||||
|
||||
rs->blend = cso->flatshade ? NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT : NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD;
|
||||
|
||||
return (void *)rs;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_rasterizer_state_bind(struct pipe_context *pipe, void *rast)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
nv04->rast = (struct nv04_rasterizer_state*)rast;
|
||||
|
||||
draw_set_rasterizer_state(nv04->draw, (nv04->rast ? nv04->rast->templ : NULL));
|
||||
|
||||
nv04->dirty |= NV04_NEW_RAST | NV04_NEW_BLEND;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
free(hwcso);
|
||||
}
|
||||
|
||||
static INLINE uint32_t nv04_compare_func(uint32_t f)
|
||||
{
|
||||
switch ( f ) {
|
||||
case PIPE_FUNC_NEVER: return 1;
|
||||
case PIPE_FUNC_LESS: return 2;
|
||||
case PIPE_FUNC_EQUAL: return 3;
|
||||
case PIPE_FUNC_LEQUAL: return 4;
|
||||
case PIPE_FUNC_GREATER: return 5;
|
||||
case PIPE_FUNC_NOTEQUAL: return 6;
|
||||
case PIPE_FUNC_GEQUAL: return 7;
|
||||
case PIPE_FUNC_ALWAYS: return 8;
|
||||
}
|
||||
NOUVEAU_MSG("Unable to find the function\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
nv04_depth_stencil_alpha_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_depth_stencil_alpha_state *cso)
|
||||
{
|
||||
struct nv04_depth_stencil_alpha_state *hw;
|
||||
|
||||
hw = malloc(sizeof(struct nv04_depth_stencil_alpha_state));
|
||||
|
||||
hw->control = float_to_ubyte(cso->alpha.ref);
|
||||
hw->control |= ( nv04_compare_func(cso->alpha.func) << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT );
|
||||
hw->control |= cso->alpha.enabled ? NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_TEST_ENABLE : 0;
|
||||
hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ORIGIN;
|
||||
hw->control |= cso->depth.enabled ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_SHIFT) : 0;
|
||||
hw->control |= ( nv04_compare_func(cso->depth.func)<< NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT );
|
||||
hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT; // no culling, handled by the draw module
|
||||
hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE;
|
||||
hw->control |= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE;
|
||||
hw->control |= cso->depth.writemask ? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_SHIFT) : 0;
|
||||
hw->control |= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT; // integer zbuffer format
|
||||
|
||||
return (void *)hw;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
nv04->dsa = hwcso;
|
||||
nv04->dirty |= NV04_NEW_CONTROL;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
free(hwcso);
|
||||
}
|
||||
|
||||
static void *
|
||||
nv04_vp_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
return draw_create_vertex_shader(nv04->draw, templ);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_vp_state_bind(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
draw_bind_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader);
|
||||
|
||||
nv04->dirty |= NV04_NEW_VERTPROG;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_vp_state_delete(struct pipe_context *pipe, void *shader)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
draw_delete_vertex_shader(nv04->draw, (struct draw_vertex_shader *) shader);
|
||||
}
|
||||
|
||||
static void *
|
||||
nv04_fp_state_create(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *cso)
|
||||
{
|
||||
struct nv04_fragment_program *fp;
|
||||
|
||||
fp = CALLOC(1, sizeof(struct nv04_fragment_program));
|
||||
fp->pipe = cso;
|
||||
|
||||
return (void *)fp;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_fp_state_bind(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
struct nv04_fragment_program *fp = hwcso;
|
||||
|
||||
nv04->fragprog.current = fp;
|
||||
nv04->dirty |= NV04_NEW_FRAGPROG;
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_fp_state_delete(struct pipe_context *pipe, void *hwcso)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
struct nv04_fragment_program *fp = hwcso;
|
||||
|
||||
nv04_fragprog_destroy(nv04, fp);
|
||||
free(fp);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_blend_color(struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *bcol)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_clip_state(struct pipe_context *pipe,
|
||||
const struct pipe_clip_state *clip)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
||||
const struct pipe_constant_buffer *buf )
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
if (shader == PIPE_SHADER_VERTEX) {
|
||||
nv04->vertprog.constant_buf = buf->buffer;
|
||||
nv04->dirty |= NV04_NEW_VERTPROG;
|
||||
} else
|
||||
if (shader == PIPE_SHADER_FRAGMENT) {
|
||||
nv04->fragprog.constant_buf = buf->buffer;
|
||||
nv04->dirty |= NV04_NEW_FRAGPROG;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_framebuffer_state(struct pipe_context *pipe,
|
||||
const struct pipe_framebuffer_state *fb)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
struct pipe_surface *rt, *zeta;
|
||||
uint32_t rt_format, w, h;
|
||||
int colour_format = 0, zeta_format = 0;
|
||||
|
||||
w = fb->cbufs[0]->width;
|
||||
h = fb->cbufs[0]->height;
|
||||
colour_format = fb->cbufs[0]->format;
|
||||
rt = fb->cbufs[0];
|
||||
|
||||
if (fb->zsbuf) {
|
||||
if (colour_format) {
|
||||
assert(w == fb->zsbuf->width);
|
||||
assert(h == fb->zsbuf->height);
|
||||
} else {
|
||||
w = fb->zsbuf->width;
|
||||
h = fb->zsbuf->height;
|
||||
}
|
||||
|
||||
zeta_format = fb->zsbuf->format;
|
||||
zeta = fb->zsbuf;
|
||||
}
|
||||
|
||||
switch (colour_format) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case 0:
|
||||
rt_format = 0x108;
|
||||
break;
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
rt_format = 0x103;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_FORMAT, 1);
|
||||
OUT_RING(rt_format);
|
||||
|
||||
/* FIXME pitches have to be aligned ! */
|
||||
BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
|
||||
OUT_RING(rt->stride|(zeta->stride<<16));
|
||||
OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
if (fb->zsbuf) {
|
||||
BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
|
||||
OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_polygon_stipple(struct pipe_context *pipe,
|
||||
const struct pipe_poly_stipple *stipple)
|
||||
{
|
||||
NOUVEAU_ERR("line stipple hahaha\n");
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_scissor_state(struct pipe_context *pipe,
|
||||
const struct pipe_scissor_state *s)
|
||||
{
|
||||
/* struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
// XXX
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2);
|
||||
OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
|
||||
OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_viewport_state(struct pipe_context *pipe,
|
||||
const struct pipe_viewport_state *viewport)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
nv04->viewport = *viewport;
|
||||
|
||||
draw_set_viewport_state(nv04->draw, &nv04->viewport);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
|
||||
const struct pipe_vertex_buffer *buffers)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
draw_flush(nv04->draw);
|
||||
|
||||
memcpy(nv04->vertex_buffer, buffers, count * sizeof(buffers[0]));
|
||||
nv04->num_vertex_buffers = count;
|
||||
|
||||
draw_set_vertex_buffers(nv04->draw, count, buffers);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_set_vertex_elements(struct pipe_context *pipe, unsigned count,
|
||||
const struct pipe_vertex_element *elements)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
|
||||
draw_flush(nv04->draw);
|
||||
|
||||
nv04->num_vertex_elements = count;
|
||||
draw_set_vertex_elements(nv04->draw, count, elements);
|
||||
}
|
||||
|
||||
void
|
||||
nv04_init_state_functions(struct nv04_context *nv04)
|
||||
{
|
||||
nv04->pipe.create_blend_state = nv04_blend_state_create;
|
||||
nv04->pipe.bind_blend_state = nv04_blend_state_bind;
|
||||
nv04->pipe.delete_blend_state = nv04_blend_state_delete;
|
||||
|
||||
nv04->pipe.create_sampler_state = nv04_sampler_state_create;
|
||||
nv04->pipe.bind_sampler_states = nv04_sampler_state_bind;
|
||||
nv04->pipe.delete_sampler_state = nv04_sampler_state_delete;
|
||||
nv04->pipe.set_sampler_textures = nv04_set_sampler_texture;
|
||||
|
||||
nv04->pipe.create_rasterizer_state = nv04_rasterizer_state_create;
|
||||
nv04->pipe.bind_rasterizer_state = nv04_rasterizer_state_bind;
|
||||
nv04->pipe.delete_rasterizer_state = nv04_rasterizer_state_delete;
|
||||
|
||||
nv04->pipe.create_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_create;
|
||||
nv04->pipe.bind_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_bind;
|
||||
nv04->pipe.delete_depth_stencil_alpha_state = nv04_depth_stencil_alpha_state_delete;
|
||||
|
||||
nv04->pipe.create_vs_state = nv04_vp_state_create;
|
||||
nv04->pipe.bind_vs_state = nv04_vp_state_bind;
|
||||
nv04->pipe.delete_vs_state = nv04_vp_state_delete;
|
||||
|
||||
nv04->pipe.create_fs_state = nv04_fp_state_create;
|
||||
nv04->pipe.bind_fs_state = nv04_fp_state_bind;
|
||||
nv04->pipe.delete_fs_state = nv04_fp_state_delete;
|
||||
|
||||
nv04->pipe.set_blend_color = nv04_set_blend_color;
|
||||
nv04->pipe.set_clip_state = nv04_set_clip_state;
|
||||
nv04->pipe.set_constant_buffer = nv04_set_constant_buffer;
|
||||
nv04->pipe.set_framebuffer_state = nv04_set_framebuffer_state;
|
||||
nv04->pipe.set_polygon_stipple = nv04_set_polygon_stipple;
|
||||
nv04->pipe.set_scissor_state = nv04_set_scissor_state;
|
||||
nv04->pipe.set_viewport_state = nv04_set_viewport_state;
|
||||
|
||||
nv04->pipe.set_vertex_buffers = nv04_set_vertex_buffers;
|
||||
nv04->pipe.set_vertex_elements = nv04_set_vertex_elements;
|
||||
}
|
||||
|
||||
71
src/gallium/drivers/nv04/nv04_state.h
Normal file
71
src/gallium/drivers/nv04/nv04_state.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef __NV04_STATE_H__
|
||||
#define __NV04_STATE_H__
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "tgsi/util/tgsi_scan.h"
|
||||
|
||||
struct nv04_blend_state {
|
||||
uint32_t b_enable;
|
||||
uint32_t b_src;
|
||||
uint32_t b_dst;
|
||||
};
|
||||
|
||||
struct nv04_fragtex_state {
|
||||
uint32_t format;
|
||||
};
|
||||
|
||||
struct nv04_sampler_state {
|
||||
uint32_t filter;
|
||||
uint32_t format;
|
||||
};
|
||||
|
||||
struct nv04_depth_stencil_alpha_state {
|
||||
uint32_t control;
|
||||
};
|
||||
|
||||
struct nv04_rasterizer_state {
|
||||
uint32_t blend;
|
||||
|
||||
const struct pipe_rasterizer_state *templ;
|
||||
};
|
||||
|
||||
struct nv04_miptree {
|
||||
struct pipe_texture base;
|
||||
|
||||
struct pipe_buffer *buffer;
|
||||
uint total_size;
|
||||
|
||||
struct {
|
||||
uint pitch;
|
||||
uint *image_offset;
|
||||
} level[PIPE_MAX_TEXTURE_LEVELS];
|
||||
};
|
||||
|
||||
struct nv04_fragment_program_data {
|
||||
unsigned offset;
|
||||
unsigned index;
|
||||
};
|
||||
|
||||
struct nv04_fragment_program {
|
||||
const struct pipe_shader_state *pipe;
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
boolean translated;
|
||||
boolean on_hw;
|
||||
unsigned samplers;
|
||||
|
||||
uint32_t *insn;
|
||||
int insn_len;
|
||||
|
||||
struct nv04_fragment_program_data *consts;
|
||||
unsigned nr_consts;
|
||||
|
||||
struct pipe_buffer *buffer;
|
||||
|
||||
uint32_t fp_control;
|
||||
uint32_t fp_reg_control;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
156
src/gallium/drivers/nv04/nv04_state_emit.c
Normal file
156
src/gallium/drivers/nv04/nv04_state_emit.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
#include "nv04_context.h"
|
||||
#include "nv04_state.h"
|
||||
|
||||
static void nv04_vertex_layout(struct pipe_context* pipe)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
struct nv04_fragment_program *fp = nv04->fragprog.current;
|
||||
uint32_t src = 0;
|
||||
int i;
|
||||
struct vertex_info vinfo;
|
||||
|
||||
memset(&vinfo, 0, sizeof(vinfo));
|
||||
|
||||
for (i = 0; i < fp->info.num_inputs; i++) {
|
||||
switch (i) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
|
||||
break;
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src++);
|
||||
break;
|
||||
default:
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
|
||||
break;
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
draw_compute_vertex_size(&vinfo);
|
||||
}
|
||||
|
||||
static uint32_t nv04_blend_func(uint32_t f)
|
||||
{
|
||||
switch ( f ) {
|
||||
case PIPE_BLENDFACTOR_ZERO: return 0x1;
|
||||
case PIPE_BLENDFACTOR_ONE: return 0x2;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR: return 0x3;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR: return 0x4;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA: return 0x5;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return 0x6;
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA: return 0x7;
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA: return 0x8;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR: return 0x9;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR: return 0xA;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return 0xB;
|
||||
}
|
||||
NOUVEAU_MSG("Unable to find the blend function 0x%x\n",f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nv04_emit_control(struct nv04_context* nv04)
|
||||
{
|
||||
uint32_t control = nv04->dsa->control;
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
|
||||
OUT_RING(control);
|
||||
}
|
||||
|
||||
static void nv04_emit_blend(struct nv04_context* nv04)
|
||||
{
|
||||
uint32_t blend;
|
||||
|
||||
blend=0x4; // texture MODULATE_ALPHA
|
||||
blend|=0x20; // alpha is MSB
|
||||
blend|=(2<<6); // flat shading
|
||||
blend|=(1<<8); // persp correct
|
||||
blend|=(0<<16); // no fog
|
||||
blend|=(nv04->blend->b_enable<<20);
|
||||
blend|=(nv04_blend_func(nv04->blend->b_src)<<24);
|
||||
blend|=(nv04_blend_func(nv04->blend->b_dst)<<28);
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_BLEND, 1);
|
||||
OUT_RING(blend);
|
||||
}
|
||||
|
||||
static void nv04_emit_sampler(struct nv04_context *nv04, int unit)
|
||||
{
|
||||
struct nv04_miptree *nv04mt = nv04->tex_miptree[unit];
|
||||
struct pipe_texture *pt = &nv04mt->base;
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 3);
|
||||
OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[unit]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
|
||||
OUT_RING(nv04->sampler[unit]->filter);
|
||||
}
|
||||
|
||||
void
|
||||
nv04_emit_hw_state(struct nv04_context *nv04)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (nv04->dirty & NV04_NEW_VERTPROG) {
|
||||
//nv04_vertprog_bind(nv04, nv04->vertprog.current);
|
||||
nv04->dirty &= ~NV04_NEW_VERTPROG;
|
||||
}
|
||||
|
||||
if (nv04->dirty & NV04_NEW_FRAGPROG) {
|
||||
nv04_fragprog_bind(nv04, nv04->fragprog.current);
|
||||
/*XXX: clear NV04_NEW_FRAGPROG if no new program uploaded */
|
||||
nv04->dirty_samplers |= (1<<10);
|
||||
nv04->dirty_samplers = 0;
|
||||
}
|
||||
|
||||
if (nv04->dirty & NV04_NEW_CONTROL) {
|
||||
nv04->dirty &= ~NV04_NEW_CONTROL;
|
||||
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_CONTROL, 1);
|
||||
OUT_RING(nv04->dsa->control);
|
||||
}
|
||||
|
||||
if (nv04->dirty & NV04_NEW_BLEND) {
|
||||
nv04->dirty &= ~NV04_NEW_BLEND;
|
||||
|
||||
nv04_emit_blend(nv04);
|
||||
}
|
||||
|
||||
if (nv04->dirty & NV04_NEW_SAMPLER) {
|
||||
nv04->dirty &= ~NV04_NEW_SAMPLER;
|
||||
|
||||
nv04_emit_sampler(nv04, 0);
|
||||
}
|
||||
|
||||
if (nv04->dirty & NV04_NEW_VIEWPORT) {
|
||||
nv04->dirty &= ~NV04_NEW_VIEWPORT;
|
||||
// nv04_state_emit_viewport(nv04);
|
||||
}
|
||||
|
||||
/* Emit relocs for every referenced buffer.
|
||||
* This is to ensure the bufmgr has an accurate idea of how
|
||||
* the buffer is used. This isn't very efficient, but we don't
|
||||
* seem to take a significant performance hit. Will be improved
|
||||
* at some point. Vertex arrays are emitted by nv04_vbo.c
|
||||
*/
|
||||
|
||||
/* Render target */
|
||||
/* BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_PITCH, 2);
|
||||
OUT_RING(rt->stride|(zeta->stride<<16));
|
||||
OUT_RELOCl(rt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
if (fb->zsbuf) {
|
||||
BEGIN_RING(context_surfaces_3d, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA, 1);
|
||||
OUT_RELOCl(zeta->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
|
||||
}*/
|
||||
|
||||
/* Texture images */
|
||||
for (i = 0; i < 1; i++) {
|
||||
if (!(nv04->fp_samplers & (1 << i)))
|
||||
continue;
|
||||
struct nv04_miptree *nv04mt = nv04->tex_miptree[i];
|
||||
BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_OFFSET, 2);
|
||||
OUT_RELOCl(nv04mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
|
||||
OUT_RELOCd(nv04mt->buffer, (nv04->fragtex.format | nv04->sampler[i]->format), NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_OR | NOUVEAU_BO_RD, 1/*VRAM*/,2/*TT*/);
|
||||
}
|
||||
}
|
||||
|
||||
65
src/gallium/drivers/nv04/nv04_surface.c
Normal file
65
src/gallium/drivers/nv04/nv04_surface.c
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "nv04_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/p_tile.h"
|
||||
|
||||
static void
|
||||
nv04_surface_copy(struct pipe_context *pipe, unsigned do_flip,
|
||||
struct pipe_surface *dest, unsigned destx, unsigned desty,
|
||||
struct pipe_surface *src, unsigned srcx, unsigned srcy,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
struct nouveau_winsys *nvws = nv04->nvws;
|
||||
|
||||
nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy,
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
nv04_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
|
||||
unsigned destx, unsigned desty, unsigned width,
|
||||
unsigned height, unsigned value)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context(pipe);
|
||||
struct nouveau_winsys *nvws = nv04->nvws;
|
||||
|
||||
nvws->surface_fill(nvws, dest, destx, desty, width, height, value);
|
||||
}
|
||||
|
||||
void
|
||||
nv04_init_surface_functions(struct nv04_context *nv04)
|
||||
{
|
||||
nv04->pipe.surface_copy = nv04_surface_copy;
|
||||
nv04->pipe.surface_fill = nv04_surface_fill;
|
||||
}
|
||||
72
src/gallium/drivers/nv04/nv04_vbo.c
Normal file
72
src/gallium/drivers/nv04/nv04_vbo.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#include "draw/draw_context.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_util.h"
|
||||
|
||||
#include "nv04_context.h"
|
||||
#include "nv04_state.h"
|
||||
|
||||
#include "nouveau/nouveau_channel.h"
|
||||
#include "nouveau/nouveau_pushbuf.h"
|
||||
|
||||
boolean nv04_draw_elements( struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
struct nv04_context *nv04 = nv04_context( pipe );
|
||||
struct draw_context *draw = nv04->draw;
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* Map vertex buffers
|
||||
*/
|
||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
||||
if (nv04->vertex_buffer[i].buffer) {
|
||||
void *buf
|
||||
= pipe->winsys->buffer_map(pipe->winsys,
|
||||
nv04->vertex_buffer[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
draw_set_mapped_vertex_buffer(draw, i, buf);
|
||||
}
|
||||
}
|
||||
/* Map index buffer, if present */
|
||||
if (indexBuffer) {
|
||||
void *mapped_indexes
|
||||
= pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
|
||||
}
|
||||
else {
|
||||
/* no index/element buffer */
|
||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
||||
}
|
||||
|
||||
/* draw! */
|
||||
draw_arrays(nv04->draw, prim, start, count);
|
||||
|
||||
/*
|
||||
* unmap vertex/index buffers
|
||||
*/
|
||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
|
||||
if (nv04->vertex_buffer[i].buffer) {
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, nv04->vertex_buffer[i].buffer);
|
||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
||||
}
|
||||
}
|
||||
if (indexBuffer) {
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
|
||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
boolean nv04_draw_arrays( struct pipe_context *pipe,
|
||||
unsigned prim, unsigned start, unsigned count)
|
||||
{
|
||||
return nv04_draw_elements(pipe, NULL, 0, prim, start, count);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Reference in a new issue