nouveau: 0.0.14 + extend bo interface to support subrange mapping

Normal map() should operate as before, and map_range()/map_flush() should
give correct results but lacking any performance difference from map().

Nothing exiting being done here yet, but the interface is a good start.
main
Ben Skeggs 2009-06-03 13:54:43 +10:00
parent 2cb4c64d73
commit 3d4bfe8c89
8 changed files with 93 additions and 43 deletions

View File

@ -5,6 +5,6 @@ includedir=@includedir@
Name: libdrm_nouveau
Description: Userspace interface to nouveau kernel DRM services
Version: 0.5
Version: 0.6
Libs: -L${libdir} -ldrm_nouveau
Cflags: -I${includedir} -I${includedir}/drm -I${includedir}/nouveau

View File

@ -52,15 +52,8 @@ nouveau_bo_info(struct nouveau_bo_priv *nvbo, struct drm_nouveau_gem_info *arg)
nvbo->size = nvbo->base.size = arg->size;
nvbo->offset = arg->offset;
nvbo->map_handle = arg->map_handle;
if (nvbo->domain & NOUVEAU_GEM_DOMAIN_TILE) {
nvbo->base.tiled = 1;
if (nvbo->domain & NOUVEAU_GEM_DOMAIN_TILE_ZETA)
nvbo->base.tiled |= 2;
} else {
nvbo->base.tiled = 0;
}
nvbo->base.tile_mode = arg->tile_mode;
nvbo->base.tile_flags = arg->tile_flags;
return 0;
}
@ -215,18 +208,15 @@ nouveau_bo_kalloc(struct nouveau_bo_priv *nvbo, struct nouveau_channel *chan)
info->domain |= NOUVEAU_GEM_DOMAIN_GART;
if (!info->domain) {
info->domain |= (NOUVEAU_GEM_DOMAIN_VRAM |
NOUVEAU_GEM_DOMAIN_GART);
}
if (nvbo->flags & NOUVEAU_BO_TILED) {
info->domain |= NOUVEAU_GEM_DOMAIN_TILE;
if (nvbo->flags & NOUVEAU_BO_ZTILE)
info->domain |= NOUVEAU_GEM_DOMAIN_TILE_ZETA;
NOUVEAU_GEM_DOMAIN_GART);
}
if (nvbo->flags & NOUVEAU_BO_MAP)
info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
info->tile_mode = nvbo->base.tile_mode;
info->tile_flags = nvbo->base.tile_flags;
ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_NEW,
&req, sizeof(req));
if (ret)
@ -276,8 +266,9 @@ nouveau_bo_kmap(struct nouveau_bo_priv *nvbo)
}
int
nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
int size, struct nouveau_bo **bo)
nouveau_bo_new_tile(struct nouveau_device *dev, uint32_t flags, int align,
int size, uint32_t tile_mode, uint32_t tile_flags,
struct nouveau_bo **bo)
{
struct nouveau_bo_priv *nvbo;
int ret;
@ -290,6 +281,8 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
return -ENOMEM;
nvbo->base.device = dev;
nvbo->base.size = size;
nvbo->base.tile_mode = tile_mode;
nvbo->base.tile_flags = tile_flags;
nvbo->refcount = 1;
/* Don't set NOUVEAU_BO_PIN here, or nouveau_bo_allocated() will
@ -300,13 +293,6 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
nvbo->size = size;
nvbo->align = align;
/*XXX: murder me violently */
if (flags & NOUVEAU_BO_TILED) {
nvbo->base.tiled = 1;
if (flags & NOUVEAU_BO_ZTILE)
nvbo->base.tiled |= 2;
}
if (flags & NOUVEAU_BO_PIN) {
ret = nouveau_bo_pin((void *)nvbo, nvbo->flags);
if (ret) {
@ -319,6 +305,22 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
return 0;
}
int
nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
int size, struct nouveau_bo **bo)
{
uint32_t tile_flags = 0;
if (flags & NOUVEAU_BO_TILED) {
if (flags & NOUVEAU_BO_ZTILE)
tile_flags = 0x2800;
else
tile_flags = 0x7000;
}
return nouveau_bo_new_tile(dev, flags, align, size, 0, tile_flags, bo);
}
int
nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size,
struct nouveau_bo **bo)
@ -575,7 +577,8 @@ nouveau_bo_wait(struct nouveau_bo *bo, int cpu_write)
}
int
nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
nouveau_bo_map_range(struct nouveau_bo *bo, uint32_t delta, uint32_t size,
uint32_t flags)
{
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
int ret;
@ -598,22 +601,35 @@ nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
}
if (nvbo->sysmem) {
bo->map = nvbo->sysmem;
bo->map = (char *)nvbo->sysmem + delta;
} else {
ret = nouveau_bo_kmap(nvbo);
if (ret)
return ret;
ret = nouveau_bo_wait(bo, (flags & NOUVEAU_BO_WR));
if (ret)
return ret;
if (!(flags & NOUVEAU_BO_NOSYNC)) {
ret = nouveau_bo_wait(bo, (flags & NOUVEAU_BO_WR));
if (ret)
return ret;
}
bo->map = nvbo->map;
bo->map = (char *)nvbo->map + delta;
}
return 0;
}
void
nouveau_bo_map_flush(struct nouveau_bo *bo, uint32_t delta, uint32_t size)
{
}
int
nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
{
return nouveau_bo_map_range(bo, 0, bo->size, flags);
}
void
nouveau_bo_unmap(struct nouveau_bo *bo)
{

View File

@ -37,6 +37,10 @@
#define NOUVEAU_BO_LOCAL (1 << 9)
#define NOUVEAU_BO_TILED (1 << 10)
#define NOUVEAU_BO_ZTILE (1 << 11)
#define NOUVEAU_BO_INVAL (1 << 12)
#define NOUVEAU_BO_NOSYNC (1 << 13)
#define NOUVEAU_BO_NOWAIT (1 << 14)
#define NOUVEAU_BO_IFLUSH (1 << 15)
#define NOUVEAU_BO_DUMMY (1 << 31)
struct nouveau_bo {
@ -46,7 +50,8 @@ struct nouveau_bo {
uint64_t size;
void *map;
int tiled;
uint32_t tile_mode;
uint32_t tile_flags;
/* Available when buffer is pinned *only* */
uint32_t flags;
@ -57,6 +62,11 @@ int
nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size,
struct nouveau_bo **);
int
nouveau_bo_new_tile(struct nouveau_device *, uint32_t flags, int align,
int size, uint32_t tile_mode, uint32_t tile_flags,
struct nouveau_bo **);
int
nouveau_bo_user(struct nouveau_device *, void *ptr, int size,
struct nouveau_bo **);
@ -78,6 +88,13 @@ nouveau_bo_handle_ref(struct nouveau_device *, uint32_t handle,
int
nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
int
nouveau_bo_map_range(struct nouveau_bo *, uint32_t delta, uint32_t size,
uint32_t flags);
void
nouveau_bo_map_flush(struct nouveau_bo *, uint32_t delta, uint32_t size);
int
nouveau_bo_map(struct nouveau_bo *, uint32_t flags);

View File

@ -26,7 +26,7 @@
#include "nouveau_private.h"
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 13
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 14
#error nouveau_drm.h does not match expected patchlevel, update libdrm.
#endif

View File

@ -60,8 +60,8 @@ nouveau_pushbuf_calc_reloc(struct drm_nouveau_gem_pushbuf_bo *pbbo,
int
nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,
struct nouveau_bo *bo, uint32_t data, uint32_t flags,
uint32_t vor, uint32_t tor)
struct nouveau_bo *bo, uint32_t data, uint32_t data2,
uint32_t flags, uint32_t vor, uint32_t tor)
{
struct nouveau_device_priv *nvdev = nouveau_device(chan->device);
struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf);

View File

@ -41,8 +41,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
int
nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr,
struct nouveau_bo *, uint32_t data, uint32_t flags,
uint32_t vor, uint32_t tor);
struct nouveau_bo *, uint32_t data, uint32_t data2,
uint32_t flags, uint32_t vor, uint32_t tor);
/* Push buffer access macros */
static __inline__ void
@ -121,7 +121,16 @@ OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo,
unsigned data, unsigned flags, unsigned vor, unsigned tor)
{
nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo,
data, flags, vor, tor);
data, 0, flags, vor, tor);
}
static __inline__ void
OUT_RELOC2(struct nouveau_channel *chan, struct nouveau_bo *bo,
unsigned data, unsigned data2, unsigned flags,
unsigned vor, unsigned tor)
{
nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo,
data, data2, flags, vor, tor);
}
/* Raw data + flags depending on FB/TT buffer */
@ -149,6 +158,14 @@ OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo,
OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0);
}
/* Low 32-bits of offset + GPU linear access range info */
static __inline__ void
OUT_RELOCr(struct nouveau_channel *chan, struct nouveau_bo *bo,
unsigned delta, unsigned size, unsigned flags)
{
OUT_RELOC2(chan, bo, delta, size, flags | NOUVEAU_BO_LOW, 0, 0);
}
/* High 32-bits of offset */
static __inline__ void
OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo,

View File

@ -25,7 +25,7 @@
#ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 13
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 14
struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle;
@ -154,8 +154,6 @@ struct drm_nouveau_setparam {
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
#define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3)
#define NOUVEAU_GEM_DOMAIN_TILE (1 << 30)
#define NOUVEAU_GEM_DOMAIN_TILE_ZETA (1 << 31)
struct drm_nouveau_gem_info {
uint32_t handle;
@ -163,6 +161,8 @@ struct drm_nouveau_gem_info {
uint64_t size;
uint64_t offset;
uint64_t map_handle;
uint32_t tile_mode;
uint32_t tile_flags;
};
struct drm_nouveau_gem_new {

View File

@ -34,7 +34,7 @@
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 13
#define DRIVER_PATCHLEVEL 14
#define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000