summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nvfx
diff options
context:
space:
mode:
authorLuca Barbieri <[email protected]>2010-04-15 06:57:20 +0200
committerLuca Barbieri <[email protected]>2010-04-15 08:13:12 +0200
commit42d9f2bb7bc21ff8c1a3fc4b4ceb4d294bccaabe (patch)
treea62954222fdc1fed6b62a391a7cbf24b28241f1b /src/gallium/drivers/nvfx
parent18dc0f0b1c9d44e07515f8a45d5292979fc6e98f (diff)
nouveau: replace vtxbuf/idxbuf caps with BO_ flags in nouveau_screen and fix uncached reads on nv3x
Faster, simpler and more flexible. Also, we set those flags properly on nv3x so that we don't allocate buffers in GART. Since on AGP GART is uncached, OpenGL doesn't distinguish between vertex and index buffers, and we don't support hardware index buffers for now, this caused uncached reads. Also check bind and not usage for PIPE_BIND_* flags, got broken in the gallium-resources transition.
Diffstat (limited to 'src/gallium/drivers/nvfx')
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c20
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.h3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_vbo.c22
3 files changed, 28 insertions, 17 deletions
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 67427594908..04b456d4087 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -69,10 +69,6 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, int param)
return 0;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return !!screen->is_nv4x;
- case NOUVEAU_CAP_HW_VTXBUF:
- return !screen->force_swtnl;
- case NOUVEAU_CAP_HW_IDXBUF:
- return !screen->force_swtnl && screen->eng3d->grclass == NV40TCL;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return 16;
case PIPE_CAP_INDEP_BLEND_ENABLE:
@@ -287,8 +283,8 @@ static void nv40_screen_init(struct nvfx_screen *screen)
OUT_RING(chan, 0x00000001);
}
-static void
-nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
+static unsigned
+nvfx_screen_get_vertex_buffer_flags(struct nvfx_screen* screen)
{
int vram_hack_default = 0;
int vram_hack;
@@ -314,7 +310,7 @@ nvfx_screen_init_buffer_functions(struct nvfx_screen* screen)
}
#endif
- screen->vertex_buffer_flags = vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
+ return vram_hack ? NOUVEAU_BO_VRAM : NOUVEAU_BO_GART;
}
struct pipe_screen *
@@ -375,8 +371,16 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
screen->force_swtnl = debug_get_bool_option("NOUVEAU_SWTNL", FALSE);
+ screen->vertex_buffer_reloc_flags = nvfx_screen_get_vertex_buffer_flags(screen);
+
+ /* surely both nv3x and nv44 support index buffers too: find out how and test that */
+ if(eng3d_class == NV40TCL)
+ screen->index_buffer_reloc_flags = screen->vertex_buffer_reloc_flags;
+
+ if(!screen->force_swtnl && screen->vertex_buffer_reloc_flags == screen->index_buffer_reloc_flags)
+ screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = screen->vertex_buffer_reloc_flags;
+
nvfx_screen_init_resource_functions(pscreen);
- nvfx_screen_init_buffer_functions(screen);
ret = nouveau_grobj_alloc(chan, 0xbeef3097, eng3d_class, &screen->eng3d);
if (ret) {
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.h b/src/gallium/drivers/nvfx/nvfx_screen.h
index aa1b0e11085..127d8919af4 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.h
+++ b/src/gallium/drivers/nvfx/nvfx_screen.h
@@ -14,8 +14,9 @@ struct nvfx_screen {
struct nvfx_context *cur_ctx;
unsigned is_nv4x; /* either 0 or ~0 */
- int vertex_buffer_flags;
boolean force_swtnl;
+ unsigned vertex_buffer_reloc_flags;
+ unsigned index_buffer_reloc_flags;
/* HW graphics objects */
struct nv04_surface_2d *eng2d;
diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c
index 8b9b5d0203c..bc87fe275c0 100644
--- a/src/gallium/drivers/nvfx/nvfx_vbo.c
+++ b/src/gallium/drivers/nvfx/nvfx_vbo.c
@@ -90,7 +90,7 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib,
return FALSE;
}
- if (nvfx->screen->eng3d->grclass != NV40TCL || ib_size == 1)
+ if (!nvfx->screen->index_buffer_reloc_flags || ib_size == 1)
return FALSE;
switch (ib_size) {
@@ -493,7 +493,7 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
int i;
int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr);
uint32_t vtxfmt[16];
- unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD;
+ unsigned vb_flags = nvfx->screen->vertex_buffer_reloc_flags | NOUVEAU_BO_RD;
if (!elements)
return TRUE;
@@ -567,11 +567,14 @@ nvfx_vbo_validate(struct nvfx_context *nvfx)
OUT_RING(chan, 0);
if (ib) {
+ unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD;
struct nouveau_bo* bo = nvfx_resource(ib)->bo;
+ assert(nvfx->screen->index_buffer_reloc_flags);
+
OUT_RING(chan, RING_3D(NV34TCL_IDXBUF_ADDRESS, 2));
- OUT_RELOC(chan, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
- OUT_RELOC(chan, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
+ OUT_RELOC(chan, bo, 0, ib_flags | NOUVEAU_BO_LOW, 0, 0);
+ OUT_RELOC(chan, bo, ib_format, ib_flags | NOUVEAU_BO_OR,
0, NV34TCL_IDXBUF_FORMAT_DMA1);
}
@@ -583,7 +586,7 @@ void
nvfx_vbo_relocate(struct nvfx_context *nvfx)
{
struct nouveau_channel* chan = nvfx->screen->base.channel;
- unsigned vb_flags = nvfx->screen->vertex_buffer_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
+ unsigned vb_flags = nvfx->screen->vertex_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
int i;
MARK_RING(chan, 2 * 16 + 3, 2 * 16 + 3);
@@ -602,14 +605,17 @@ nvfx_vbo_relocate(struct nvfx_context *nvfx)
if(nvfx->idxbuf)
{
+ unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY;
struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf)->bo;
+ assert(nvfx->screen->index_buffer_reloc_flags);
+
OUT_RELOC(chan, bo, RING_3D(NV34TCL_IDXBUF_ADDRESS, 2),
- vb_flags, 0, 0);
+ ib_flags, 0, 0);
OUT_RELOC(chan, bo, 0,
- vb_flags | NOUVEAU_BO_LOW, 0, 0);
+ ib_flags | NOUVEAU_BO_LOW, 0, 0);
OUT_RELOC(chan, bo, nvfx->idxbuf_format,
- vb_flags | NOUVEAU_BO_OR,
+ ib_flags | NOUVEAU_BO_OR,
0, NV34TCL_IDXBUF_FORMAT_DMA1);
}
}