summaryrefslogtreecommitdiffstats
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/nv30_miptree.c68
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c27
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.h2
-rw-r--r--src/gallium/drivers/nv30/nv30_surface.c21
-rw-r--r--src/gallium/drivers/nv30/nv30_vertprog.c2
5 files changed, 85 insertions, 35 deletions
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index c55756971b5..b11ed8c24e2 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -8,10 +8,14 @@ static void
nv30_miptree_layout(struct nv30_miptree *nv30mt)
{
struct pipe_texture *pt = &nv30mt->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, pitch;
+ int nr_faces, l, f;
+ uint wide_pitch = pt->tex_usage & (PIPE_TEXTURE_USAGE_SAMPLER |
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
+ PIPE_TEXTURE_USAGE_RENDER_TARGET |
+ PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_PRIMARY);
if (pt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
@@ -22,7 +26,6 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
nr_faces = 1;
}
- pitch = pt->width[0];
for (l = 0; l <= pt->last_level; l++) {
pt->width[l] = width;
pt->height[l] = height;
@@ -30,11 +33,11 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
- if (swizzled)
- pitch = pt->nblocksx[l];
- pitch = align(pitch, 64);
+ if (wide_pitch && (pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR))
+ nv30mt->level[l].pitch = align(pt->width[0] * pt->block.size, 64);
+ else
+ nv30mt->level[l].pitch = pt->width[l] * pt->block.size;
- nv30mt->level[l].pitch = pitch * pt->block.size;
nv30mt->level[l].image_offset =
CALLOC(nr_faces, sizeof(unsigned));
@@ -44,10 +47,18 @@ nv30_miptree_layout(struct nv30_miptree *nv30mt)
}
for (f = 0; f < nr_faces; f++) {
- for (l = 0; l <= pt->last_level; l++) {
+ for (l = 0; l < pt->last_level; l++) {
nv30mt->level[l].image_offset[f] = offset;
- offset += nv30mt->level[l].pitch * pt->height[l];
+
+ if (!(pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR) &&
+ pt->width[l + 1] > 1 && pt->height[l + 1] > 1)
+ offset += align(nv30mt->level[l].pitch * pt->height[l], 64);
+ else
+ offset += nv30mt->level[l].pitch * pt->height[l];
}
+
+ nv30mt->level[l].image_offset[f] = offset;
+ offset += nv30mt->level[l].pitch * pt->height[l];
}
nv30mt->total_size = offset;
@@ -74,7 +85,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_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL))
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
else
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC)
@@ -85,7 +97,11 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_R16_SNORM:
- break;
+ {
+ if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
+ mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
+ break;
+ }
default:
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
}
@@ -105,6 +121,31 @@ nv30_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
return &mt->base;
}
+static struct pipe_texture *
+nv30_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
+ const unsigned *stride, struct pipe_buffer *pb)
+{
+ struct nv30_miptree *mt;
+
+ /* Only supports 2D, non-mipmapped textures for the moment */
+ if (pt->target != PIPE_TEXTURE_2D || pt->last_level != 0 ||
+ pt->depth[0] != 1)
+ return NULL;
+
+ mt = CALLOC_STRUCT(nv30_miptree);
+ if (!mt)
+ return NULL;
+
+ mt->base = *pt;
+ mt->base.refcount = 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);
+ return &mt->base;
+}
+
static void
nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
{
@@ -123,8 +164,8 @@ nv30_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
}
if (mt->shadow_tex) {
- assert(mt->shadow_surface);
- pscreen->tex_surface_release(pscreen, &mt->shadow_surface);
+ if (mt->shadow_surface)
+ pscreen->tex_surface_release(pscreen, &mt->shadow_surface);
nv30_miptree_release(pscreen, &mt->shadow_tex);
}
@@ -187,6 +228,7 @@ void
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->get_tex_surface = nv30_miptree_surface_new;
pscreen->tex_surface_release = nv30_miptree_surface_del;
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index 9738436dc47..c97a73f0b1a 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -127,6 +127,14 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
return FALSE;
}
+static struct pipe_buffer *
+nv30_surface_buffer(struct pipe_surface *surf)
+{
+ struct nv30_miptree *mt = (struct nv30_miptree *)surf->texture;
+
+ return mt->buffer;
+}
+
static void *
nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
unsigned flags )
@@ -134,7 +142,6 @@ nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
struct pipe_winsys *ws = screen->winsys;
struct pipe_surface *surface_to_map;
void *map;
- struct nv30_miptree *nv30mt = (struct nv30_miptree *)surface->texture;
if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) {
struct nv30_miptree *mt = (struct nv30_miptree *)surface->texture;
@@ -163,7 +170,7 @@ nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface,
assert(surface_to_map);
- map = ws->buffer_map(ws, nv30mt->buffer, flags);
+ map = ws->buffer_map(ws, nv30_surface_buffer(surface_to_map), flags);
if (!map)
return NULL;
@@ -175,7 +182,6 @@ nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
{
struct pipe_winsys *ws = screen->winsys;
struct pipe_surface *surface_to_unmap;
- struct nv30_miptree *nv30mt = (struct nv30_miptree *)surface->texture;
/* TODO: Copy from shadow just before push buffer is flushed instead.
There are probably some programs that map/unmap excessively
@@ -192,15 +198,16 @@ nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface)
assert(surface_to_unmap);
- ws->buffer_unmap(ws, nv30mt->buffer);
+ ws->buffer_unmap(ws, nv30_surface_buffer(surface_to_unmap));
if (surface_to_unmap != surface) {
struct nv30_screen *nvscreen = nv30_screen(screen);
- nvscreen->nvws->surface_copy(nvscreen->nvws,
- surface, 0, 0,
- surface_to_unmap, 0, 0,
- surface->width, surface->height);
+ 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);
}
}
@@ -233,6 +240,10 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
return NULL;
screen->nvws = nvws;
+ /* 2D engine setup */
+ screen->eng2d = nv04_surface_2d_init(nvws);
+ screen->eng2d->buf = nv30_surface_buffer;
+
/* 3D object */
switch (chipset & 0xf0) {
case 0x30:
diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h
index b7ddc2a9594..b11e470f949 100644
--- a/src/gallium/drivers/nv30/nv30_screen.h
+++ b/src/gallium/drivers/nv30/nv30_screen.h
@@ -2,6 +2,7 @@
#define __NV30_SCREEN_H__
#include "pipe/p_screen.h"
+#include "nv04/nv04_surface_2d.h"
struct nv30_screen {
struct pipe_screen pipe;
@@ -11,6 +12,7 @@ struct nv30_screen {
unsigned cur_pctx;
/* HW graphics objects */
+ struct nv04_surface_2d *eng2d;
struct nouveau_grobj *rankine;
struct nouveau_notifier *sync;
diff --git a/src/gallium/drivers/nv30/nv30_surface.c b/src/gallium/drivers/nv30/nv30_surface.c
index 806131dcc95..0f8dc12045a 100644
--- a/src/gallium/drivers/nv30/nv30_surface.c
+++ b/src/gallium/drivers/nv30/nv30_surface.c
@@ -30,7 +30,6 @@
#include "pipe/p_defines.h"
#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_inlines.h"
-
#include "util/u_tile.h"
static void
@@ -40,22 +39,18 @@ nv30_surface_copy(struct pipe_context *pipe, boolean do_flip,
unsigned width, unsigned height)
{
struct nv30_context *nv30 = nv30_context(pipe);
- struct nouveau_winsys *nvws = nv30->nvws;
+ struct nv04_surface_2d *eng2d = nv30->screen->eng2d;
if (do_flip) {
- /*XXX: This dodgyness will do for now for correctness. But,
- * need to investigate whether the 2D engine is able to
- * manage a flip (perhaps SIFM?), if not, use the 3D engine
- */
desty += height;
while (height--) {
- nvws->surface_copy(nvws, dest, destx, desty--, src,
- srcx, srcy++, width, 1);
+ eng2d->copy(eng2d, dest, destx, desty--, src,
+ srcx, srcy++, width, 1);
}
- } else {
- nvws->surface_copy(nvws, dest, destx, desty, src, srcx, srcy,
- width, height);
+ return;
}
+
+ eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height);
}
static void
@@ -64,9 +59,9 @@ nv30_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
unsigned height, unsigned value)
{
struct nv30_context *nv30 = nv30_context(pipe);
- struct nouveau_winsys *nvws = nv30->nvws;
+ struct nv04_surface_2d *eng2d = nv30->screen->eng2d;
- nvws->surface_fill(nvws, dest, destx, desty, width, height, value);
+ eng2d->fill(eng2d, dest, destx, desty, width, height, value);
}
void
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c
index 72824559e8b..d2627250570 100644
--- a/src/gallium/drivers/nv30/nv30_vertprog.c
+++ b/src/gallium/drivers/nv30/nv30_vertprog.c
@@ -613,7 +613,7 @@ nv30_vertprog_translate(struct nv30_context *nv30,
imm = &parse.FullToken.FullImmediate;
assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32);
-// assert(imm->Immediate.Size == 4);
+ assert(imm->Immediate.NrTokens == 4 + 1);
vpc->imm[vpc->nr_imm++] =
constant(vpc, -1,
imm->u.ImmediateFloat32[0].Float,