aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nv30
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nv30')
-rw-r--r--src/gallium/drivers/nv30/Makefile12
-rw-r--r--src/gallium/drivers/nv30/nv30_fragprog.c4
-rw-r--r--src/gallium/drivers/nv30/nv30_fragtex.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_miptree.c89
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c80
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.h3
-rw-r--r--src/gallium/drivers/nv30/nv30_state.c3
-rw-r--r--src/gallium/drivers/nv30/nv30_state.h3
-rw-r--r--src/gallium/drivers/nv30/nv30_state_blend.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_state_fb.c29
-rw-r--r--src/gallium/drivers/nv30/nv30_state_scissor.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_state_stipple.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_state_viewport.c4
-rw-r--r--src/gallium/drivers/nv30/nv30_surface.c11
-rw-r--r--src/gallium/drivers/nv30/nv30_transfer.c196
-rw-r--r--src/gallium/drivers/nv30/nv30_vbo.c3
-rw-r--r--src/gallium/drivers/nv30/nv30_vertprog.c1
17 files changed, 270 insertions, 173 deletions
diff --git a/src/gallium/drivers/nv30/Makefile b/src/gallium/drivers/nv30/Makefile
index 69f2790dfe2..364c80d8f3e 100644
--- a/src/gallium/drivers/nv30/Makefile
+++ b/src/gallium/drivers/nv30/Makefile
@@ -3,7 +3,7 @@ include $(TOP)/configs/current
LIBNAME = nv30
-DRIVER_SOURCES = \
+C_SOURCES = \
nv30_clear.c \
nv30_context.c \
nv30_draw.c \
@@ -22,16 +22,8 @@ DRIVER_SOURCES = \
nv30_state_viewport.c \
nv30_state_zsa.c \
nv30_surface.c \
+ nv30_transfer.c \
nv30_vbo.c \
nv30_vertprog.c
-C_SOURCES = \
- $(COMMON_SOURCES) \
- $(DRIVER_SOURCES)
-
-ASM_SOURCES =
-
include ../../Makefile.template
-
-symlinks:
-
diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c
index 320ba3f4bf4..bdfe1425d24 100644
--- a/src/gallium/drivers/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nv30/nv30_fragprog.c
@@ -834,6 +834,7 @@ nv30_fragprog_validate(struct nv30_context *nv30)
struct nv30_fragment_program *fp = nv30->fragprog;
struct pipe_buffer *constbuf =
nv30->constbuf[PIPE_SHADER_FRAGMENT];
+ struct pipe_screen *screen = nv30->pipe.screen;
struct pipe_winsys *ws = nv30->pipe.winsys;
struct nouveau_stateobj *so;
boolean new_consts = FALSE;
@@ -849,7 +850,7 @@ nv30_fragprog_validate(struct nv30_context *nv30)
return FALSE;
}
- fp->buffer = ws->buffer_create(ws, 0x100, 0, fp->insn_len * 4);
+ fp->buffer = screen->buffer_create(screen, 0x100, 0, fp->insn_len * 4);
nv30_fragprog_upload(nv30, fp);
so = so_new(8, 1);
@@ -864,6 +865,7 @@ nv30_fragprog_validate(struct nv30_context *nv30)
so_method(so, nv30->screen->rankine, NV34TCL_TX_UNITS_ENABLE, 1);
so_data (so, fp->samplers);
so_ref(so, &fp->so);
+ so_ref(NULL, &so);
update_constants:
if (fp->nr_consts) {
diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c
index b1d2663af38..8b6ab992d16 100644
--- a/src/gallium/drivers/nv30/nv30_fragtex.c
+++ b/src/gallium/drivers/nv30/nv30_fragtex.c
@@ -137,6 +137,7 @@ nv30_fragtex_validate(struct nv30_context *nv30)
so_method(so, nv30->screen->rankine, NV34TCL_TX_ENABLE(unit), 1);
so_data (so, 0);
so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
+ so_ref(NULL, &so);
state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
}
@@ -147,6 +148,7 @@ nv30_fragtex_validate(struct nv30_context *nv30)
so = nv30_fragtex_build(nv30, unit);
so_ref(so, &nv30->state.hw[NV30_STATE_FRAGTEX0 + unit]);
+ so_ref(NULL, &so);
state->dirty |= (1ULL << (NV30_STATE_FRAGTEX0 + unit));
}
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index 510c94d4e64..d6dc621c9ee 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -67,17 +67,16 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
static struct pipe_texture *
nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
{
- struct pipe_winsys *ws = pscreen->winsys;
struct nv30_miptree *mt;
+ unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
+ NOUVEAU_BUFFER_USAGE_TEXTURE;
mt = MALLOC(sizeof(struct nv30_miptree));
if (!mt)
return NULL;
mt->base = *pt;
- mt->base.refcount = 1;
+ pipe_reference_init(&mt->base.reference, 1);
mt->base.screen = pscreen;
- mt->shadow_tex = NULL;
- mt->shadow_surface = NULL;
/* Swizzled textures must be POT */
if (pt->width[0] & (pt->width[0] - 1) ||
@@ -85,8 +84,8 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY |
-+ PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
-+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
+ PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
@@ -107,11 +106,12 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
}
}
+ if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
+ buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+
nv30_miptree_layout(mt);
- mt->buffer = ws->buffer_create(ws, 256,
- PIPE_BUFFER_USAGE_PIXEL |
- NOUVEAU_BUFFER_USAGE_TEXTURE,
+ mt->buffer = pscreen->buffer_create(pscreen, 256, buf_usage,
mt->total_size);
if (!mt->buffer) {
FREE(mt);
@@ -137,38 +137,27 @@ nv30_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
return NULL;
mt->base = *pt;
- mt->base.refcount = 1;
+ pipe_reference_init(&mt->base.reference, 1);
mt->base.screen = pscreen;
mt->level[0].pitch = stride[0];
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
- pipe_buffer_reference(pscreen, &mt->buffer, pb);
+ pipe_buffer_reference(&mt->buffer, pb);
return &mt->base;
}
static void
-nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
+nv30_miptree_destroy(struct pipe_texture *pt)
{
- struct pipe_texture *pt = *ppt;
struct nv30_miptree *mt = (struct nv30_miptree *)pt;
int l;
- *ppt = NULL;
- if (--pt->refcount)
- return;
-
- pipe_buffer_reference(pscreen, &mt->buffer, NULL);
+ pipe_buffer_reference(&mt->buffer, NULL);
for (l = 0; l <= pt->last_level; l++) {
if (mt->level[l].image_offset)
FREE(mt->level[l].image_offset);
}
- if (mt->shadow_tex) {
- if (mt->shadow_surface)
- pscreen->tex_surface_release(pscreen, &mt->shadow_surface);
- nv30_miptree_release(pscreen, &mt->shadow_tex);
- }
-
FREE(mt);
}
@@ -178,48 +167,38 @@ nv30_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
unsigned flags)
{
struct nv30_miptree *nv30mt = (struct nv30_miptree *)pt;
- struct pipe_surface *ps;
+ struct nv04_surface *ns;
- ps = CALLOC_STRUCT(pipe_surface);
- if (!ps)
+ ns = CALLOC_STRUCT(nv04_surface);
+ if (!ns)
return NULL;
- pipe_texture_reference(&ps->texture, pt);
- ps->format = pt->format;
- ps->width = pt->width[level];
- ps->height = pt->height[level];
- ps->block = pt->block;
- ps->nblocksx = pt->nblocksx[level];
- ps->nblocksy = pt->nblocksy[level];
- ps->stride = nv30mt->level[level].pitch;
- ps->usage = flags;
- ps->status = PIPE_SURFACE_STATUS_DEFINED;
- ps->refcount = 1;
- ps->face = face;
- ps->level = level;
- ps->zslice = zslice;
+ pipe_texture_reference(&ns->base.texture, pt);
+ ns->base.format = pt->format;
+ ns->base.width = pt->width[level];
+ ns->base.height = pt->height[level];
+ ns->base.usage = flags;
+ ns->base.status = PIPE_SURFACE_STATUS_DEFINED;
+ pipe_reference_init(&ns->base.reference, 1);
+ ns->base.face = face;
+ ns->base.level = level;
+ ns->base.zslice = zslice;
+ ns->pitch = nv30mt->level[level].pitch;
if (pt->target == PIPE_TEXTURE_CUBE) {
- ps->offset = nv30mt->level[level].image_offset[face];
+ ns->base.offset = nv30mt->level[level].image_offset[face];
} else
if (pt->target == PIPE_TEXTURE_3D) {
- ps->offset = nv30mt->level[level].image_offset[zslice];
+ ns->base.offset = nv30mt->level[level].image_offset[zslice];
} else {
- ps->offset = nv30mt->level[level].image_offset[0];
+ ns->base.offset = nv30mt->level[level].image_offset[0];
}
- return ps;
+ return &ns->base;
}
static void
-nv30_miptree_surface_del(struct pipe_screen *pscreen,
- struct pipe_surface **psurface)
+nv30_miptree_surface_del(struct pipe_surface *ps)
{
- struct pipe_surface *ps = *psurface;
-
- *psurface = NULL;
- if (--ps->refcount > 0)
- return;
-
pipe_texture_reference(&ps->texture, NULL);
FREE(ps);
}
@@ -229,7 +208,7 @@ nv30_screen_init_miptree_functions(struct pipe_screen *pscreen)
{
pscreen->texture_create = nv30_miptree_create;
pscreen->texture_blanket = nv30_miptree_blanket;
- pscreen->texture_release = nv30_miptree_release;
+ pscreen->texture_destroy = nv30_miptree_destroy;
pscreen->get_tex_surface = nv30_miptree_surface_new;
- pscreen->tex_surface_release = nv30_miptree_surface_del;
+ pscreen->tex_surface_destroy = nv30_miptree_surface_del;
}
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index c97a73f0b1a..d395c5e1b7f 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -135,82 +135,6 @@ nv30_surface_buffer(struct pipe_surface *surf)
return mt->buffer;
}
-static void *
-nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
- unsigned flags )
-{
- struct pipe_winsys *ws = screen->winsys;
- struct pipe_surface *surface_to_map;
- void *map;
-
- if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
- struct nv30_miptree *mt = (struct nv30_miptree *)surface->texture;
-
- if (!mt->shadow_tex) {
- unsigned old_tex_usage = surface->texture->tex_usage;
- surface->texture->tex_usage = NOUVEAU_TEXTURE_USAGE_LINEAR |
- PIPE_TEXTURE_USAGE_DYNAMIC;
- mt->shadow_tex = screen->texture_create(screen, surface->texture);
- surface->texture->tex_usage = old_tex_usage;
-
- assert(mt->shadow_tex->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR);
- }
-
- mt->shadow_surface = screen->get_tex_surface
- (
- screen, mt->shadow_tex,
- surface->face, surface->level, surface->zslice,
- surface->usage
- );
-
- surface_to_map = mt->shadow_surface;
- }
- else
- surface_to_map = surface;
-
- assert(surface_to_map);
-
- map = ws->buffer_map(ws, nv30_surface_buffer(surface_to_map), flags);
- if (!map)
- return NULL;
-
- return map + surface_to_map->offset;
-}
-
-static void
-nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
-{
- struct pipe_winsys *ws = screen->winsys;
- struct pipe_surface *surface_to_unmap;
-
- /* TODO: Copy from shadow just before push buffer is flushed instead.
- There are probably some programs that map/unmap excessively
- before rendering. */
- if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
- struct nv30_miptree *mt = (struct nv30_miptree *)surface->texture;
-
- assert(mt->shadow_tex);
-
- surface_to_unmap = mt->shadow_surface;
- }
- else
- surface_to_unmap = surface;
-
- assert(surface_to_unmap);
-
- ws->buffer_unmap(ws, nv30_surface_buffer(surface_to_unmap));
-
- if (surface_to_unmap != surface) {
- struct nv30_screen *nvscreen = nv30_screen(screen);
-
- nvscreen->eng2d->copy(nvscreen->eng2d, surface, 0, 0,
- surface_to_unmap, 0, 0,
- surface->width, surface->height);
-
- screen->tex_surface_release(screen, &surface_to_unmap);
- }
-}
-
static void
nv30_screen_destroy(struct pipe_screen *pscreen)
{
@@ -391,10 +315,8 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
screen->pipe.is_format_supported = nv30_screen_surface_format_supported;
- screen->pipe.surface_map = nv30_surface_map;
- screen->pipe.surface_unmap = nv30_surface_unmap;
-
nv30_screen_init_miptree_functions(&screen->pipe);
+ nv30_screen_init_transfer_functions(&screen->pipe);
u_simple_screen_init(&screen->pipe);
return &screen->pipe;
diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h
index b11e470f949..8e368839759 100644
--- a/src/gallium/drivers/nv30/nv30_screen.h
+++ b/src/gallium/drivers/nv30/nv30_screen.h
@@ -34,4 +34,7 @@ nv30_screen(struct pipe_screen *screen)
return (struct nv30_screen *)screen;
}
+void
+nv30_screen_init_transfer_functions(struct pipe_screen *pscreen);
+
#endif
diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c
index 26147565a53..b91e972c123 100644
--- a/src/gallium/drivers/nv30/nv30_state.c
+++ b/src/gallium/drivers/nv30/nv30_state.c
@@ -51,6 +51,7 @@ nv30_blend_state_create(struct pipe_context *pipe,
so_data (so, cso->dither ? 1 : 0);
so_ref(so, &bso->so);
+ so_ref(NULL, &so);
bso->pipe = *cso;
return (void *)bso;
}
@@ -404,6 +405,7 @@ nv30_rasterizer_state_create(struct pipe_context *pipe,
}
so_ref(so, &rsso->so);
+ so_ref(NULL, &so);
rsso->pipe = *cso;
return (void *)rsso;
}
@@ -477,6 +479,7 @@ nv30_depth_stencil_alpha_state_create(struct pipe_context *pipe,
}
so_ref(so, &zsaso->so);
+ so_ref(NULL, &so);
zsaso->pipe = *cso;
return (void *)zsaso;
}
diff --git a/src/gallium/drivers/nv30/nv30_state.h b/src/gallium/drivers/nv30/nv30_state.h
index 2023278e377..e6f23bf1667 100644
--- a/src/gallium/drivers/nv30/nv30_state.h
+++ b/src/gallium/drivers/nv30/nv30_state.h
@@ -76,9 +76,6 @@ struct nv30_miptree {
struct pipe_buffer *buffer;
uint total_size;
- struct pipe_texture *shadow_tex;
- struct pipe_surface *shadow_surface;
-
struct {
uint pitch;
uint *image_offset;
diff --git a/src/gallium/drivers/nv30/nv30_state_blend.c b/src/gallium/drivers/nv30/nv30_state_blend.c
index 44d43e132a5..64cf9ae93a0 100644
--- a/src/gallium/drivers/nv30/nv30_state_blend.c
+++ b/src/gallium/drivers/nv30/nv30_state_blend.c
@@ -28,6 +28,7 @@ nv30_state_blend_colour_validate(struct nv30_context *nv30)
(float_to_ubyte(bcol->color[2]) << 0)));
so_ref(so, &nv30->state.hw[NV30_STATE_BCOL]);
+ so_ref(NULL, &so);
return TRUE;
}
diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c
index 77368cb2055..fdc1cade905 100644
--- a/src/gallium/drivers/nv30/nv30_state_fb.c
+++ b/src/gallium/drivers/nv30/nv30_state_fb.c
@@ -5,7 +5,7 @@ static boolean
nv30_state_framebuffer_validate(struct nv30_context *nv30)
{
struct pipe_framebuffer_state *fb = &nv30->framebuffer;
- struct pipe_surface *rt[2], *zeta = NULL;
+ struct nv04_surface *rt[2], *zeta = NULL;
uint32_t rt_enable, rt_format;
int i, colour_format = 0, zeta_format = 0;
struct nouveau_stateobj *so = so_new(64, 10);
@@ -21,7 +21,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
} else {
colour_format = fb->cbufs[i]->format;
rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
- rt[i] = fb->cbufs[i];
+ rt[i] = (struct nv04_surface *)fb->cbufs[i];
}
}
@@ -30,13 +30,13 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
if (fb->zsbuf) {
zeta_format = fb->zsbuf->format;
- zeta = fb->zsbuf;
+ zeta = (struct nv04_surface *)fb->zsbuf;
}
- if (!(rt[0]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
+ if (!(rt[0]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
assert(!(fb->width & (fb->width - 1)) && !(fb->height & (fb->height - 1)));
for (i = 1; i < fb->nr_cbufs; i++)
- assert(!(rt[i]->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR));
+ assert(!(rt[i]->base.texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR));
/* FIXME: NV34TCL_RT_FORMAT_LOG2_[WIDTH/HEIGHT] */
rt_format = NV34TCL_RT_FORMAT_TYPE_SWIZZLED |
@@ -71,44 +71,44 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
}
if (rt_enable & NV34TCL_RT_ENABLE_COLOR0) {
- uint32_t pitch = rt[0]->stride;
+ uint32_t pitch = rt[0]->pitch;
if (zeta) {
- pitch |= (zeta->stride << 16);
+ pitch |= (zeta->pitch << 16);
} else {
pitch |= (pitch << 16);
}
- nv30mt = (struct nv30_miptree *)rt[0]->texture;
+ nv30mt = (struct nv30_miptree *)rt[0]->base.texture;
so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR0, 1);
so_reloc (so, nv30mt->buffer, 0, rt_flags | NOUVEAU_BO_OR,
nv30->nvws->channel->vram->handle,
nv30->nvws->channel->gart->handle);
so_method(so, nv30->screen->rankine, NV34TCL_COLOR0_PITCH, 2);
so_data (so, pitch);
- so_reloc (so, nv30mt->buffer, rt[0]->offset, rt_flags |
+ so_reloc (so, nv30mt->buffer, rt[0]->base.offset, rt_flags |
NOUVEAU_BO_LOW, 0, 0);
}
if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) {
- nv30mt = (struct nv30_miptree *)rt[1]->texture;
+ nv30mt = (struct nv30_miptree *)rt[1]->base.texture;
so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR1, 1);
so_reloc (so, nv30mt->buffer, 0, rt_flags | NOUVEAU_BO_OR,
nv30->nvws->channel->vram->handle,
nv30->nvws->channel->gart->handle);
so_method(so, nv30->screen->rankine, NV34TCL_COLOR1_OFFSET, 2);
- so_reloc (so, nv30mt->buffer, rt[1]->offset, rt_flags |
+ so_reloc (so, nv30mt->buffer, rt[1]->base.offset, rt_flags |
NOUVEAU_BO_LOW, 0, 0);
- so_data (so, rt[1]->stride);
+ so_data (so, rt[1]->pitch);
}
if (zeta_format) {
- nv30mt = (struct nv30_miptree *)zeta->texture;
+ nv30mt = (struct nv30_miptree *)zeta->base.texture;
so_method(so, nv30->screen->rankine, NV34TCL_DMA_ZETA, 1);
so_reloc (so, nv30mt->buffer, 0, rt_flags | NOUVEAU_BO_OR,
nv30->nvws->channel->vram->handle,
nv30->nvws->channel->gart->handle);
so_method(so, nv30->screen->rankine, NV34TCL_ZETA_OFFSET, 1);
- so_reloc (so, nv30mt->buffer, zeta->offset, rt_flags |
+ so_reloc (so, nv30mt->buffer, zeta->base.offset, rt_flags |
NOUVEAU_BO_LOW, 0, 0);
/* TODO: allocate LMA depth buffer */
}
@@ -132,6 +132,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
so_data (so, 0);
so_ref(so, &nv30->state.hw[NV30_STATE_FB]);
+ so_ref(NULL, &so);
return TRUE;
}
diff --git a/src/gallium/drivers/nv30/nv30_state_scissor.c b/src/gallium/drivers/nv30/nv30_state_scissor.c
index 1db9bc17955..3ac7a8471ea 100644
--- a/src/gallium/drivers/nv30/nv30_state_scissor.c
+++ b/src/gallium/drivers/nv30/nv30_state_scissor.c
@@ -23,6 +23,7 @@ nv30_state_scissor_validate(struct nv30_context *nv30)
}
so_ref(so, &nv30->state.hw[NV30_STATE_SCISSOR]);
+ so_ref(NULL, &so);
return TRUE;
}
diff --git a/src/gallium/drivers/nv30/nv30_state_stipple.c b/src/gallium/drivers/nv30/nv30_state_stipple.c
index 41b42813b49..d0c791ac082 100644
--- a/src/gallium/drivers/nv30/nv30_state_stipple.c
+++ b/src/gallium/drivers/nv30/nv30_state_stipple.c
@@ -27,6 +27,7 @@ nv30_state_stipple_validate(struct nv30_context *nv30)
}
so_ref(so, &nv30->state.hw[NV30_STATE_STIPPLE]);
+ so_ref(NULL, &so);
return TRUE;
}
diff --git a/src/gallium/drivers/nv30/nv30_state_viewport.c b/src/gallium/drivers/nv30/nv30_state_viewport.c
index 951d40ebfdd..c3eb413dac6 100644
--- a/src/gallium/drivers/nv30/nv30_state_viewport.c
+++ b/src/gallium/drivers/nv30/nv30_state_viewport.c
@@ -7,7 +7,8 @@ nv30_state_viewport_validate(struct nv30_context *nv30)
struct nouveau_stateobj *so;
unsigned bypass;
- if (/*nv30->render_mode == HW &&*/ !nv30->rasterizer->pipe.bypass_clipping)
+ if (/*nv30->render_mode == HW &&*/
+ !nv30->rasterizer->pipe.bypass_vs_clip_and_viewport)
bypass = 0;
else
bypass = 1;
@@ -58,6 +59,7 @@ nv30_state_viewport_validate(struct nv30_context *nv30)
so_data (so, 1);
so_ref(so, &nv30->state.hw[NV30_STATE_VIEWPORT]);
+ so_ref(NULL, &so);
return TRUE;
}
diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c
index 0f8dc12045a..5e237e13eb5 100644
--- a/src/gallium/drivers/nv30/nv30_surface.c
+++ b/src/gallium/drivers/nv30/nv30_surface.c
@@ -33,7 +33,7 @@
#include "util/u_tile.h"
static void
-nv30_surface_copy(struct pipe_context *pipe, boolean do_flip,
+nv30_surface_copy(struct pipe_context *pipe,
struct pipe_surface *dest, unsigned destx, unsigned desty,
struct pipe_surface *src, unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
@@ -41,15 +41,6 @@ nv30_surface_copy(struct pipe_context *pipe, boolean do_flip,
struct nv30_context *nv30 = nv30_context(pipe);
struct nv04_surface_2d *eng2d = nv30->screen->eng2d;
- if (do_flip) {
- desty += height;
- while (height--) {
- eng2d->copy(eng2d, dest, destx, desty--, src,
- srcx, srcy++, width, 1);
- }
- return;
- }
-
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height);
}
diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c
new file mode 100644
index 00000000000..8b915b35bd4
--- /dev/null
+++ b/src/gallium/drivers/nv30/nv30_transfer.c
@@ -0,0 +1,196 @@
+#include <pipe/p_state.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_inlines.h>
+#include <util/u_memory.h>
+#include <nouveau/nouveau_winsys.h>
+#include "nv30_context.h"
+#include "nv30_screen.h"
+#include "nv30_state.h"
+
+struct nv30_transfer {
+ struct pipe_transfer base;
+ struct pipe_surface *surface;
+ bool direct;
+};
+
+static unsigned nv30_usage_tx_to_buf(unsigned tx_usage)
+{
+ switch (tx_usage) {
+ case PIPE_TRANSFER_READ:
+ return PIPE_BUFFER_USAGE_CPU_READ;
+ case PIPE_TRANSFER_WRITE:
+ return PIPE_BUFFER_USAGE_CPU_WRITE;
+ case PIPE_TRANSFER_READ_WRITE:
+ return PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ default:
+ assert(0);
+ }
+
+ return -1;
+}
+
+static void
+nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
+ struct pipe_texture *template)
+{
+ memset(template, 0, sizeof(struct pipe_texture));
+ template->target = pt->target;
+ template->format = pt->format;
+ template->width[0] = pt->width[level];
+ template->height[0] = pt->height[level];
+ template->depth[0] = 1;
+ template->block = pt->block;
+ template->nblocksx[0] = pt->nblocksx[level];
+ template->nblocksy[0] = pt->nblocksx[level];
+ template->last_level = 0;
+ template->compressed = pt->compressed;
+ template->nr_samples = pt->nr_samples;
+
+ template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
+ NOUVEAU_TEXTURE_USAGE_LINEAR;
+}
+
+static struct pipe_transfer *
+nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ struct nv30_miptree *mt = (struct nv30_miptree *)pt;
+ struct nv30_transfer *tx;
+ struct pipe_texture tx_tex_template, *tx_tex;
+
+ tx = CALLOC_STRUCT(nv30_transfer);
+ if (!tx)
+ return NULL;
+
+ pipe_texture_reference(&tx->base.texture, pt);
+ tx->base.format = pt->format;
+ tx->base.x = x;
+ tx->base.y = y;
+ tx->base.width = w;
+ tx->base.height = h;
+ tx->base.block = pt->block;
+ tx->base.nblocksx = pt->nblocksx[level];
+ tx->base.nblocksy = pt->nblocksy[level];
+ tx->base.stride = mt->level[level].pitch;
+ tx->base.usage = usage;
+ tx->base.face = face;
+ tx->base.level = level;
+ tx->base.zslice = zslice;
+
+ /* Direct access to texture */
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC ||
+ debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/)) &&
+ pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
+ {
+ tx->direct = true;
+ tx->surface = pscreen->get_tex_surface(pscreen, pt,
+ face, level, zslice,
+ nv30_usage_tx_to_buf(usage));
+ return &tx->base;
+ }
+
+ tx->direct = false;
+
+ nv30_compatible_transfer_tex(pt, level, &tx_tex_template);
+
+ tx_tex = pscreen->texture_create(pscreen, &tx_tex_template);
+ if (!tx_tex)
+ {
+ FREE(tx);
+ return NULL;
+ }
+
+ tx->surface = pscreen->get_tex_surface(pscreen, tx_tex,
+ 0, 0, 0,
+ nv30_usage_tx_to_buf(usage));
+
+ pipe_texture_reference(&tx_tex, NULL);
+
+ if (!tx->surface)
+ {
+ pipe_surface_reference(&tx->surface, NULL);
+ FREE(tx);
+ return NULL;
+ }
+
+ if (usage != PIPE_TRANSFER_WRITE) {
+ struct nv30_screen *nvscreen = nv30_screen(pscreen);
+ struct pipe_surface *src;
+
+ src = pscreen->get_tex_surface(pscreen, pt,
+ face, level, zslice,
+ PIPE_BUFFER_USAGE_GPU_READ);
+
+ /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
+ /* TODO: Check if SIFM can un-swizzle */
+ nvscreen->eng2d->copy(nvscreen->eng2d,
+ tx->surface, 0, 0,
+ src, 0, 0,
+ src->width, src->height);
+
+ pipe_surface_reference(&src, NULL);
+ }
+
+ return &tx->base;
+}
+
+static void
+nv30_transfer_del(struct pipe_transfer *ptx)
+{
+ struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
+
+ if (!tx->direct && ptx->usage != PIPE_TRANSFER_READ) {
+ struct pipe_screen *pscreen = ptx->texture->screen;
+ struct nv30_screen *nvscreen = nv30_screen(pscreen);
+ struct pipe_surface *dst;
+
+ dst = pscreen->get_tex_surface(pscreen, ptx->texture,
+ ptx->face, ptx->level, ptx->zslice,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */
+ nvscreen->eng2d->copy(nvscreen->eng2d,
+ dst, 0, 0,
+ tx->surface, 0, 0,
+ dst->width, dst->height);
+
+ pipe_surface_reference(&dst, NULL);
+ }
+
+ pipe_surface_reference(&tx->surface, NULL);
+ pipe_texture_reference(&ptx->texture, NULL);
+ FREE(ptx);
+}
+
+static void *
+nv30_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+{
+ struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
+ struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
+ struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
+ void *map = pipe_buffer_map(pscreen, mt->buffer,
+ nv30_usage_tx_to_buf(ptx->usage));
+
+ return map + ns->base.offset +
+ ptx->y * ns->pitch + ptx->x * ptx->block.size;
+}
+
+static void
+nv30_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
+{
+ struct nv30_transfer *tx = (struct nv30_transfer *)ptx;
+ struct nv30_miptree *mt = (struct nv30_miptree *)tx->surface->texture;
+
+ pipe_buffer_unmap(pscreen, mt->buffer);
+}
+
+void
+nv30_screen_init_transfer_functions(struct pipe_screen *pscreen)
+{
+ pscreen->get_tex_transfer = nv30_transfer_new;
+ pscreen->tex_transfer_destroy = nv30_transfer_del;
+ pscreen->transfer_map = nv30_transfer_map;
+ pscreen->transfer_unmap = nv30_transfer_unmap;
+}
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
index 2d6d48ac161..990a8763824 100644
--- a/src/gallium/drivers/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nv30/nv30_vbo.c
@@ -539,10 +539,13 @@ nv30_vbo_validate(struct nv30_context *nv30)
so_data (vtxbuf, 0);
so_ref(vtxbuf, &nv30->state.hw[NV30_STATE_VTXBUF]);
+ so_ref(NULL, &vtxbuf);
nv30->state.dirty |= (1ULL << NV30_STATE_VTXBUF);
so_ref(vtxfmt, &nv30->state.hw[NV30_STATE_VTXFMT]);
+ so_ref(NULL, &vtxfmt);
nv30->state.dirty |= (1ULL << NV30_STATE_VTXFMT);
so_ref(sattr, &nv30->state.hw[NV30_STATE_VTXATTR]);
+ so_ref(NULL, &sattr);
nv30->state.dirty |= (1ULL << NV30_STATE_VTXATTR);
return FALSE;
}
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c
index d2627250570..eaf543b8f79 100644
--- a/src/gallium/drivers/nv30/nv30_vertprog.c
+++ b/src/gallium/drivers/nv30/nv30_vertprog.c
@@ -685,6 +685,7 @@ nv30_vertprog_validate(struct nv30_context *nv30)
so_method(so, rankine, NV34TCL_VP_START_FROM_ID, 1);
so_data (so, vp->exec->start);
so_ref(so, &vp->so);
+ so_ref(NULL, &so);
upload_code = TRUE;
}