summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvfx
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nvfx')
-rw-r--r--src/gallium/drivers/nvfx/nv30_fragtex.c2
-rw-r--r--src/gallium/drivers/nvfx/nv40_fragtex.c2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_context.h2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_draw.c6
-rw-r--r--src/gallium/drivers/nvfx/nvfx_fragprog.c3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_miptree.c5
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c37
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.h1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.c45
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state_viewport.c11
-rw-r--r--src/gallium/drivers/nvfx/nvfx_transfer.c22
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vbo.c2
12 files changed, 106 insertions, 32 deletions
diff --git a/src/gallium/drivers/nvfx/nv30_fragtex.c b/src/gallium/drivers/nvfx/nv30_fragtex.c
index 2b56f454921..54e47574c4d 100644
--- a/src/gallium/drivers/nvfx/nv30_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv30_fragtex.c
@@ -91,7 +91,7 @@ struct nouveau_stateobj *
nv30_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
- struct nvfx_miptree *nv30mt = nvfx->tex_miptree[unit];
+ struct nvfx_miptree *nv30mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
struct pipe_texture *pt = &nv30mt->base;
struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer);
struct nv30_texture_format *tf;
diff --git a/src/gallium/drivers/nvfx/nv40_fragtex.c b/src/gallium/drivers/nvfx/nv40_fragtex.c
index 5889b5e40d5..05506e28099 100644
--- a/src/gallium/drivers/nvfx/nv40_fragtex.c
+++ b/src/gallium/drivers/nvfx/nv40_fragtex.c
@@ -109,7 +109,7 @@ struct nouveau_stateobj *
nv40_fragtex_build(struct nvfx_context *nvfx, int unit)
{
struct nvfx_sampler_state *ps = nvfx->tex_sampler[unit];
- struct nvfx_miptree *nv40mt = nvfx->tex_miptree[unit];
+ struct nvfx_miptree *nv40mt = (struct nvfx_miptree *)nvfx->fragment_sampler_views[unit]->texture;
struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer);
struct pipe_texture *pt = &nv40mt->base;
struct nv40_texture_format *tf;
diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h
index 5eed8a560e5..ab7225cf6c3 100644
--- a/src/gallium/drivers/nvfx/nvfx_context.h
+++ b/src/gallium/drivers/nvfx/nvfx_context.h
@@ -158,7 +158,7 @@ struct nvfx_context {
struct pipe_buffer *idxbuf;
unsigned idxbuf_format;
struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];
- struct nvfx_miptree *tex_miptree[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
unsigned nr_samplers;
unsigned nr_textures;
unsigned dirty_samplers;
diff --git a/src/gallium/drivers/nvfx/nvfx_draw.c b/src/gallium/drivers/nvfx/nvfx_draw.c
index 5379b29efd1..68e50a36479 100644
--- a/src/gallium/drivers/nvfx/nvfx_draw.c
+++ b/src/gallium/drivers/nvfx/nvfx_draw.c
@@ -79,6 +79,12 @@ nvfx_render_vertex(struct nvfx_context *nvfx, const struct vertex_header *v)
float_to_ubyte(v->data[idx][1]),
float_to_ubyte(v->data[idx][2]),
float_to_ubyte(v->data[idx][3])));
+ case EMIT_4UB_BGRA:
+ BEGIN_RING(chan, eng3d, NV34TCL_VTX_ATTR_4UB(hw), 1);
+ OUT_RING (chan, pack_ub4(float_to_ubyte(v->data[idx][2]),
+ float_to_ubyte(v->data[idx][1]),
+ float_to_ubyte(v->data[idx][0]),
+ float_to_ubyte(v->data[idx][3])));
break;
default:
assert(0);
diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c
index 76351430f44..b9c91cec8ce 100644
--- a/src/gallium/drivers/nvfx/nvfx_fragprog.c
+++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c
@@ -803,7 +803,8 @@ nvfx_fragprog_translate(struct nvfx_context *nvfx,
fp->fp_control |= fpc->num_regs << NV40TCL_FP_CONTROL_TEMP_COUNT_SHIFT;
/* Terminate final instruction */
- fp->insn[fpc->inst_offset] |= 0x00000001;
+ if(fp->insn)
+ fp->insn[fpc->inst_offset] |= 0x00000001;
/* Append NOP + END instruction, may or may not be necessary. */
fpc->inst_offset = fp->insn_len;
diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 0f5ed61aab7..9de25175e78 100644
--- a/src/gallium/drivers/nvfx/nvfx_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -67,6 +67,9 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
struct nvfx_miptree *mt;
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL |
NOUVEAU_BUFFER_USAGE_TEXTURE;
+ static int no_swizzle = -1;
+ if(no_swizzle < 0)
+ no_swizzle = debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE);
mt = MALLOC(sizeof(struct nvfx_miptree));
if (!mt)
@@ -106,7 +109,7 @@ nvfx_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_R16_SNORM:
{
- if (debug_get_bool_option("NOUVEAU_NO_SWIZZLE", FALSE))
+ if (no_swizzle)
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR;
break;
}
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 8138715cc7d..f7f39218944 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -68,11 +68,9 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return !!screen->is_nv4x;
case NOUVEAU_CAP_HW_VTXBUF:
- /* TODO: this is almost surely wrong */
- return !!screen->is_nv4x;
+ return 0;
case NOUVEAU_CAP_HW_IDXBUF:
- /* TODO: this is also almost surely wrong */
- return screen->is_nv4x && screen->eng3d->grclass == NV40TCL;
+ return 0;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return 16;
case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -295,6 +293,36 @@ static void nv40_screen_init(struct nvfx_screen *screen, struct nouveau_stateobj
so_data (so, 0x00000001);
}
+static void
+nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
+{
+ int vram_hack_default = 0;
+ int vram_hack;
+ // TODO: this is a bit of a guess; also add other cards that may need this hack.
+ // It may also depend on the specific card or the AGP/PCIe chipset.
+ if(screen->base.device->chipset == 0x47 /* G70 */
+ || screen->base.device->chipset == 0x49 /* G71 */
+ || screen->base.device->chipset == 0x46 /* G72 */
+ )
+ vram_hack_default = 1;
+ vram_hack = debug_get_bool_option("NOUVEAU_VTXIDX_IN_VRAM", vram_hack_default);
+
+#ifdef DEBUG
+ if(!vram_hack)
+ {
+ fprintf(stderr, "Some systems may experience graphics corruption due to randomly misplaced vertices.\n"
+ "If this is happening, export NOUVEAU_VTXIDX_IN_VRAM=1 may reduce or eliminate the problem\n");
+ }
+ else
+ {
+ fprintf(stderr, "A performance reducing hack is being used to help avoid graphics corruption.\n"
+ "You can try export NOUVEAU_VTXIDX_IN_VRAM=0 to disable it.\n");
+ }
+#endif
+
+ screen->vertex_buffer_flags = vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
+}
+
struct pipe_screen *
nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
@@ -352,6 +380,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
+ nvfx_screen_init_buffer_functions(screen);
nvfx_screen_init_miptree_functions(pscreen);
ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h
index c0b4b9899dd..baa848c47aa 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.h
+++ b/src/gallium/drivers/nvfx/nvfx_screen.h
@@ -12,6 +12,7 @@ struct nvfx_screen {
struct nvfx_context *cur_ctx;
unsigned is_nv4x; /* either 0 or ~0 */
+ int vertex_buffer_flags;
/* HW graphics objects */
struct nv04_surface_2d *eng2d;
diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c
index 88a9d01c509..ecaa0dcb16a 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.c
+++ b/src/gallium/drivers/nvfx/nvfx_state.c
@@ -137,21 +137,22 @@ nvfx_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
}
static void
-nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
- struct pipe_texture **miptree)
+nvfx_set_fragment_sampler_views(struct pipe_context *pipe,
+ unsigned nr,
+ struct pipe_sampler_view **views)
{
struct nvfx_context *nvfx = nvfx_context(pipe);
unsigned unit;
for (unit = 0; unit < nr; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nvfx->tex_miptree[unit], miptree[unit]);
+ pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+ views[unit]);
nvfx->dirty_samplers |= (1 << unit);
}
for (unit = nr; unit < nvfx->nr_textures; unit++) {
- pipe_texture_reference((struct pipe_texture **)
- &nvfx->tex_miptree[unit], NULL);
+ pipe_sampler_view_reference(&nvfx->fragment_sampler_views[unit],
+ NULL);
nvfx->dirty_samplers |= (1 << unit);
}
@@ -159,6 +160,34 @@ nvfx_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
nvfx->dirty |= NVFX_NEW_SAMPLER;
}
+
+static struct pipe_sampler_view *
+nvfx_create_sampler_view(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ if (view) {
+ *view = *templ;
+ view->reference.count = 1;
+ view->texture = NULL;
+ pipe_texture_reference(&view->texture, texture);
+ view->context = pipe;
+ }
+
+ return view;
+}
+
+
+static void
+nvfx_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view)
+{
+ pipe_texture_reference(&view->texture, NULL);
+ FREE(view);
+}
+
static void *
nvfx_rasterizer_state_create(struct pipe_context *pipe,
const struct pipe_rasterizer_state *cso)
@@ -581,7 +610,9 @@ nvfx_init_state_functions(struct nvfx_context *nvfx)
nvfx->pipe.create_sampler_state = nvfx_sampler_state_create;
nvfx->pipe.bind_fragment_sampler_states = nvfx_sampler_state_bind;
nvfx->pipe.delete_sampler_state = nvfx_sampler_state_delete;
- nvfx->pipe.set_fragment_sampler_textures = nvfx_set_sampler_texture;
+ nvfx->pipe.set_fragment_sampler_views = nvfx_set_fragment_sampler_views;
+ nvfx->pipe.create_sampler_view = nvfx_create_sampler_view;
+ nvfx->pipe.sampler_view_destroy = nvfx_sampler_view_destroy;
nvfx->pipe.create_rasterizer_state = nvfx_rasterizer_state_create;
nvfx->pipe.bind_rasterizer_state = nvfx_rasterizer_state_bind;
diff --git a/src/gallium/drivers/nvfx/nvfx_state_viewport.c b/src/gallium/drivers/nvfx/nvfx_state_viewport.c
index 82e0e9220b0..ec730e3a9e9 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_viewport.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_viewport.c
@@ -1,15 +1,16 @@
#include "nvfx_context.h"
+/* Having this depend on FB and RAST looks wrong, but it seems
+ necessary to make this work on nv3x
+ TODO: find the right fix
+*/
+
static boolean
nvfx_state_viewport_validate(struct nvfx_context *nvfx)
{
struct pipe_viewport_state *vpt = &nvfx->viewport;
struct nouveau_stateobj *so;
- if (nvfx->state.hw[NVFX_STATE_VIEWPORT] &&
- !(nvfx->dirty & NVFX_NEW_VIEWPORT))
- return FALSE;
-
so = so_new(2, 9, 0);
so_method(so, nvfx->screen->eng3d,
NV34TCL_VIEWPORT_TRANSLATE_X, 8);
@@ -45,7 +46,7 @@ nvfx_state_viewport_validate(struct nvfx_context *nvfx)
struct nvfx_state_entry nvfx_state_viewport = {
.validate = nvfx_state_viewport_validate,
.dirty = {
- .pipe = NVFX_NEW_VIEWPORT,
+ .pipe = NVFX_NEW_VIEWPORT | NVFX_NEW_FB | NVFX_NEW_RAST,
.hw = NVFX_STATE_VIEWPORT
}
};
diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c
index 409b354d582..1c250e9fe44 100644
--- a/src/gallium/drivers/nvfx/nvfx_transfer.c
+++ b/src/gallium/drivers/nvfx/nvfx_transfer.c
@@ -33,15 +33,18 @@ nvfx_compatible_transfer_tex(struct pipe_texture *pt, unsigned width, unsigned h
}
static struct pipe_transfer *
-nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
+nvfx_transfer_new(struct pipe_context *pipe, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_miptree *mt = (struct nvfx_miptree *)pt;
struct nvfx_transfer *tx;
struct pipe_texture tx_tex_template, *tx_tex;
+ static int no_transfer = -1;
+ if(no_transfer < 0)
+ no_transfer = debug_get_bool_option("NOUVEAU_NO_TRANSFER", TRUE/*XXX:FALSE*/);
tx = CALLOC_STRUCT(nvfx_transfer);
if (!tx)
@@ -59,8 +62,7 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
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*/)) &&
+ if ((pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC || no_transfer) &&
pt->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)
{
tx->direct = true;
@@ -118,13 +120,13 @@ nvfx_transfer_new(struct pipe_context *pcontext, struct pipe_texture *pt,
}
static void
-nvfx_transfer_del(struct pipe_context *pcontext,
+nvfx_transfer_del(struct pipe_context *pipe,
struct pipe_transfer *ptx)
{
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
if (!tx->direct && (ptx->usage & PIPE_TRANSFER_WRITE)) {
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_screen *nvscreen = nvfx_screen(pscreen);
struct pipe_surface *dst;
@@ -147,9 +149,9 @@ nvfx_transfer_del(struct pipe_context *pcontext,
}
static void *
-nvfx_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+nvfx_transfer_map(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nv04_surface *ns = (struct nv04_surface *)tx->surface;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
@@ -163,9 +165,9 @@ nvfx_transfer_map(struct pipe_context *pcontext, struct pipe_transfer *ptx)
}
static void
-nvfx_transfer_unmap(struct pipe_context *pcontext, struct pipe_transfer *ptx)
+nvfx_transfer_unmap(struct pipe_context *pipe, struct pipe_transfer *ptx)
{
- struct pipe_screen *pscreen = pcontext->screen;
+ struct pipe_screen *pscreen = pipe->screen;
struct nvfx_transfer *tx = (struct nvfx_transfer *)ptx;
struct nvfx_miptree *mt = (struct nvfx_miptree *)tx->surface->texture;
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index 257087f8f63..c26536b0e77 100644
--- a/src/gallium/drivers/nvfx/nvfx_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -495,7 +495,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
struct nouveau_grobj *eng3d = nvfx->screen->eng3d;
struct pipe_buffer *ib = nvfx->idxbuf;
unsigned ib_format = nvfx->idxbuf_format;
- unsigned vb_flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD;
+ unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD;
int hw;
vtxbuf = so_new(3, 17, 18);