diff options
Diffstat (limited to 'src/gallium/drivers/nvfx')
-rw-r--r-- | src/gallium/drivers/nvfx/nv30_fragtex.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nv40_fragtex.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_draw.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_fragprog.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_miptree.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_screen.c | 37 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_screen.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_state.c | 45 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_state_viewport.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_transfer.c | 22 | ||||
-rw-r--r-- | src/gallium/drivers/nvfx/nvfx_vbo.c | 2 |
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); |