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.
uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0;
int ret;
- if (bind & PIPE_BIND_VERTEX_BUFFER) {
- if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
- flags |= NOUVEAU_BO_GART;
- } else
- if (usage & PIPE_BIND_INDEX_BUFFER) {
- if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
- flags |= NOUVEAU_BO_GART;
- }
+ if (bind & PIPE_BIND_VERTEX_BUFFER)
+ flags |= nouveau_screen(pscreen)->vertex_buffer_flags;
+ else if (bind & PIPE_BIND_INDEX_BUFFER)
+ flags |= nouveau_screen(pscreen)->index_buffer_flags;
if (bind & (PIPE_BIND_RENDER_TARGET |
PIPE_BIND_DEPTH_STENCIL |
struct pipe_screen base;
struct nouveau_device *device;
struct nouveau_channel *channel;
+
+ /* note that OpenGL doesn't distinguish between these, so
+ * these almost always should be set to the same value */
+ unsigned vertex_buffer_flags;
+ unsigned index_buffer_flags;
};
static inline struct nouveau_screen *
#include "nouveau/nouveau_resource.h"
#include "nouveau/nouveau_pushbuf.h"
-#define NOUVEAU_CAP_HW_VTXBUF (0xbeef0000)
-#define NOUVEAU_CAP_HW_IDXBUF (0xbeef0001)
-
static inline uint32_t
nouveau_screen_transfer_flags(unsigned pipe)
{
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
- case NOUVEAU_CAP_HW_VTXBUF:
- return screen->force_push ? 0 : 1;
- case NOUVEAU_CAP_HW_IDXBUF:
- return screen->force_push ? 0 : 1;
case PIPE_CAP_INDEP_BLEND_ENABLE:
return 1;
case PIPE_CAP_INDEP_BLEND_FUNC:
FIRE_RING (chan);
screen->force_push = debug_get_bool_option("NV50_ALWAYS_PUSH", FALSE);
+ if(!screen->force_push)
+ screen->base.vertex_buffer_flags = screen->base.index_buffer_flags = NOUVEAU_BO_GART;
return pscreen;
}
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:
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;
}
#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 *
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) {
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;
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) {
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;
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);
}
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);
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);
}
}