Checkpoint commit. Buffer object flags and IOCTL argument list.

main
Thomas Hellstrom 2006-08-29 18:40:08 +02:00
parent 0dedfc2cd0
commit 23f01c9fe8
10 changed files with 283 additions and 12 deletions

View File

@ -65,6 +65,8 @@
# define _DRM_FREE free # define _DRM_FREE free
# include "drm.h" # include "drm.h"
#endif #endif
#include "xf86mm.h"
/* Not all systems have MAP_FAILED defined */ /* Not all systems have MAP_FAILED defined */
#ifndef MAP_FAILED #ifndef MAP_FAILED
@ -2425,4 +2427,135 @@ drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm)
(void) fd; (void) fd;
return ttm->user_token; return ttm->user_token;
} }
static int drmAdjustListNodes(DrmBufList *list)
{
DrmBufNode *node;
DrmMMListHead *l;
int ret = 0;
while(list->numCurrent < list->numTarget) {
node = (DrmBufNode *) malloc(sizeof(*node));
if (!node) {
ret = -ENOMEM;
break;
}
list->numCurrent++;
DRMLISTADD(&node->head, &list->free);
}
while(list->numCurrent > list->numTarget) {
l = list->free.next;
if (l == &list->free)
break;
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
free(node);
list->numCurrent--;
}
return ret;
}
static void drmFreeList(DrmBufList *list)
{
DrmBufNode *node;
DrmMMListHead *l;
int ret = 0;
l = list->list.next;
while(l != &list->list) {
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
free(node);
l = list->free.next;
list->numCurrent--;
list->numOnList--;
}
l = list->free.next;
while(l != &list->free) {
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
free(node);
l = list->free.next;
list->numCurrent--;
}
}
int drmResetList(DrmBufList *list) {
DrmMMListHead *l;
int ret;
ret = drmAdjustListNodes(list);
if (ret)
return ret;
l = list->list.next;
while(l != &list->list) {
DRMLISTDEL(l);
DRMLISTADD(l, &list->free);
list->numOnList--;
}
return drmAdjustListNodes(list);
}
static int drmAddListItem(DrmBufList *list, DrmBuf *item, drm_bo_arg_t *arg)
{
DrmBufNode *node;
DrmMMListHead *l;
l = list->free.next;
if (l == &list->free) {
node = (DrmBufNode *) malloc(sizeof(*node));
if (!node) {
return -ENOMEM;
}
list->numCurrent++;
} else {
DRMLISTDEL(l);
node = DRMLISTENTRY(DrmBufNode, l, head);
}
node->buf = item;
DRMLISTADD(&node->head, &list->list);
list->numOnList++;
return 0;
}
int drmCreateBufList(int numTarget, DrmBufList *list)
{
DRMINITLISTHEAD(&list->list);
DRMINITLISTHEAD(&list->free);
list->numTarget = numTarget;
list->numCurrent = 0;
list->numOnList = 0;
return drmAdjustListNodes(list);
}
/*
* Prepare list for IOCTL submission.
*/
static drm_bo_arg_t *drmPrepareList(DrmBufList *list)
{
DrmMMListHead *cur, *next;
DrmBufNode *first, *curNode, *nextNode;
cur = list->list.next;
if (cur == &list->list)
return NULL;
first = DRMLISTENTRY(DrmBufNode, cur, head);
curNode = DRMLISTENTRY(DrmBufNode, cur, head);
for (next = cur->next; next != &list->list;
cur = next, next = cur->next) {
nextNode = DRMLISTENTRY(DrmBufNode, next, head);
curNode->bo_arg.req.next = ((unsigned long) &nextNode->bo_arg.req);
curNode = nextNode;
}
curNode->bo_arg.req.next = 0;
return &first->bo_arg;
}
#endif #endif

105
libdrm/xf86mm.h Normal file
View File

@ -0,0 +1,105 @@
/**************************************************************************
*
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
*
**************************************************************************/
#ifndef _XF86MM_H_
#define _XF86MM_H_
#include <stddef.h>
/*
* List macros heavily inspired by the Linux kernel
* list handling. No list looping yet.
*/
typedef struct _drmMMListHead
{
struct _drmMMListHead *prev;
struct _drmMMListHead *next;
} DrmMMListHead;
#define DRMINITLISTHEAD(__item) \
do{ \
(__item)->prev = (__item); \
(__item)->next = (__item); \
} while (0)
#define DRMLISTADD(__item, __list) \
do { \
(__item)->prev = (__list); \
(__item)->next = (__list)->next; \
(__list)->next->prev = (__item); \
(__list)->next = (__item); \
} while (0)
#define DRMLISTADDTAIL(__item, __list) \
do { \
(__item)->next = (__list); \
(__item)->prev = (__list)->prev; \
(__list)->prev->next = (__item); \
(__list)->prev = (__item); \
} while(0)
#define DRMLISTDEL(__item) \
do { \
(__item)->prev->next = (__item)->next; \
(__item)->next->prev = (__item)->prev; \
} while(0)
#define DRMLISTDELINIT(__item) \
do { \
(__item)->prev->next = (__item)->next; \
(__item)->next->prev = (__item)->prev; \
(__item)->next = (__item); \
(__item)->prev = (__item); \
} while(0)
#define DRMLISTENTRY(__type, __item, __field) \
((__type *)(((char *) (__item)) - offsetof(__type, __field)))
typedef struct _DrmBuf{
unsigned handle;
} DrmBuf;
typedef struct _DrmBufNode {
DrmMMListHead head;
DrmBuf *buf;
drm_bo_arg_t bo_arg;
} DrmBufNode;
typedef struct _DrmMMBufList {
unsigned numTarget;
unsigned numCurrent;
unsigned numOnList;
DrmMMListHead list;
DrmMMListHead free;
} DrmBufList;
#endif

View File

@ -652,7 +652,8 @@ typedef struct drm_ref_object {
*/ */
typedef struct drm_bo_driver{ typedef struct drm_bo_driver{
int cached_pages; int cached_tt;
int cached_vram;
drm_ttm_backend_t *(*create_ttm_backend_entry) drm_ttm_backend_t *(*create_ttm_backend_entry)
(struct drm_device *dev, int cached); (struct drm_device *dev, int cached);
} drm_bo_driver_t; } drm_bo_driver_t;

View File

@ -214,7 +214,8 @@ static void drm_bo_base_deref_locked(drm_file_t *priv, drm_user_object_t *uo)
} }
static int drm_bo_new_flags(uint32_t flags, uint32_t new_mask, uint32_t hint, static int drm_bo_new_flags(drm_bo_driver_t *driver,
uint32_t flags, uint32_t new_mask, uint32_t hint,
int init, uint32_t *n_flags) int init, uint32_t *n_flags)
{ {
uint32_t new_flags; uint32_t new_flags;
@ -263,6 +264,24 @@ static int drm_bo_new_flags(uint32_t flags, uint32_t new_mask, uint32_t hint,
} }
new_flags |= new_mask & ~DRM_BO_MASK_MEM; new_flags |= new_mask & ~DRM_BO_MASK_MEM;
if (hint & DRM_BO_HINT_BIND_CACHED) {
new_flags |= DRM_BO_FLAG_CACHED;
if (((new_flags & DRM_BO_FLAG_MEM_TT) && !driver->cached_tt) ||
((new_flags & DRM_BO_FLAG_MEM_VRAM) && !driver->cached_vram))
new_flags &= ~DRM_BO_FLAG_CACHED;
}
if ((new_flags & DRM_BO_FLAG_NO_EVICT) &&
((flags ^ new_flags) & DRM_BO_FLAG_CACHED)) {
if (flags & DRM_BO_FLAG_CACHED) {
DRM_ERROR("Cannot change caching policy of pinned buffer\n");
return -EINVAL;
} else {
new_flags &= ~DRM_BO_FLAG_CACHED;
}
}
*n_flags = new_flags; *n_flags = new_flags;
return 0; return 0;
} }
@ -531,11 +550,12 @@ static int drm_buffer_object_validate(drm_device_t *dev, drm_buffer_object_t *bo
return 0; return 0;
} }
/* /*
* Call bo->mutex locked. * Call bo->mutex locked.
*/ */
static int drm_bo_add_ttm(drm_file_t *priv, drm_buffer_object_t *bo, uint32_t new_flags, static int drm_bo_add_ttm(drm_file_t *priv, drm_buffer_object_t *bo, uint32_t hint,
uint32_t ttm_handle) uint32_t ttm_handle)
{ {
@ -578,7 +598,7 @@ static int drm_bo_add_ttm(drm_file_t *priv, drm_buffer_object_t *bo, uint32_t ne
ttm = drm_ttm_from_object(to); ttm = drm_ttm_from_object(to);
ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT, ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT,
bo->num_pages, bo->num_pages,
new_flags & DRM_BO_FLAG_CACHED, hint & DRM_BO_HINT_BIND_CACHED,
&bo->ttm_region); &bo->ttm_region);
if (ret) { if (ret) {
drm_ttm_object_deref_unlocked(dev, to); drm_ttm_object_deref_unlocked(dev, to);
@ -631,6 +651,10 @@ int drm_buffer_object_create(drm_file_t *priv,
bo->num_pages = num_pages; bo->num_pages = num_pages;
bo->buffer_start = buffer_start; bo->buffer_start = buffer_start;
ret = drm_bo_new_flags(dev->driver->bo_driver, bo->flags, mask, hint,
1, &new_flags);
if (ret)
goto out_err;
ret = drm_bo_add_ttm(priv, bo, new_flags, ttm_handle); ret = drm_bo_add_ttm(priv, bo, new_flags, ttm_handle);
if (ret) if (ret)
goto out_err; goto out_err;

View File

@ -202,10 +202,11 @@ int drm_destroy_ttm(drm_ttm_t * ttm)
if (atomic_read(&ttm->vma_count) > 0) { if (atomic_read(&ttm->vma_count) > 0) {
ttm->destroy = 1; ttm->destroy = 1;
DRM_DEBUG("VMAs are still alive. Skipping destruction.\n"); DRM_ERROR("VMAs are still alive. Skipping destruction.\n");
return -EBUSY; return -EBUSY;
} }
DRM_ERROR("Destroying a ttm\n");
if (ttm->be_list) { if (ttm->be_list) {
list_for_each_safe(list, next, &ttm->be_list->head) { list_for_each_safe(list, next, &ttm->be_list->head) {
drm_ttm_backend_list_t *entry = drm_ttm_backend_list_t *entry =
@ -479,6 +480,7 @@ void drm_destroy_ttm_region(drm_ttm_backend_list_t * entry)
uint32_t *cur_page_flags; uint32_t *cur_page_flags;
int i; int i;
DRM_ERROR("Destroying a TTM region\n");
list_del_init(&entry->head); list_del_init(&entry->head);
drm_unbind_ttm_region(entry); drm_unbind_ttm_region(entry);
@ -800,7 +802,6 @@ void drm_ttm_object_deref_unlocked(drm_device_t *dev, drm_ttm_object_t *to)
*/ */
static void drm_ttm_user_deref_locked(drm_file_t *priv, drm_user_object_t *base) static void drm_ttm_user_deref_locked(drm_file_t *priv, drm_user_object_t *base)
{ {
DRM_ERROR("User deref ttm\n");
drm_ttm_object_deref_locked(priv->head->dev, drm_ttm_object_deref_locked(priv->head->dev,
drm_user_object_entry(base, drm_ttm_object_t, drm_user_object_entry(base, drm_ttm_object_t,
base)); base));

View File

@ -49,7 +49,8 @@ static drm_fence_driver_t i915_fence_driver = {
}; };
static drm_bo_driver_t i915_bo_driver = { static drm_bo_driver_t i915_bo_driver = {
.cached_pages = 1, .cached_vram = 0,
.cached_tt = 1,
.create_ttm_backend_entry = i915_create_ttm_backend_entry .create_ttm_backend_entry = i915_create_ttm_backend_entry
}; };

View File

@ -86,6 +86,8 @@ static void i915_perform_flush(drm_device_t * dev)
dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv); dev_priv->flush_sequence = (uint32_t) READ_BREADCRUMB(dev_priv);
dev_priv->flush_flags = fm->pending_flush; dev_priv->flush_flags = fm->pending_flush;
dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0); dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0);
DRM_ERROR("Saved flush status is 0x%08x\n",
dev_priv->saved_flush_status);
I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21)); I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
dev_priv->flush_pending = 1; dev_priv->flush_pending = 1;
fm->pending_flush = 0; fm->pending_flush = 0;

View File

@ -685,7 +685,7 @@ typedef struct drm_ttm_arg {
#define DRM_BO_FLAG_NO_MOVE 0x00000008 #define DRM_BO_FLAG_NO_MOVE 0x00000008
#define DRM_BO_FLAG_NO_EVICT 0x00000010 #define DRM_BO_FLAG_NO_EVICT 0x00000010
#define DRM_BO_FLAG_SHADOW_VRAM 0x00000020 #define DRM_BO_FLAG_SHADOW_VRAM 0x00000020
#define DRM_BO_FLAG_READ_LOCAL 0x00000040 #define DRM_BO_FLAG_READ_CACHED 0x00000040
#define DRM_BO_FLAG_CACHED 0x00000080 #define DRM_BO_FLAG_CACHED 0x00000080
#define DRM_BO_FLAG_SHAREABLE 0x00000100 #define DRM_BO_FLAG_SHAREABLE 0x00000100
@ -697,6 +697,7 @@ typedef struct drm_ttm_arg {
#define DRM_BO_HINT_PREFER_VRAM 0x00000001 #define DRM_BO_HINT_PREFER_VRAM 0x00000001
#define DRM_BO_HINT_AVOID_LOCAL 0x00000002 #define DRM_BO_HINT_AVOID_LOCAL 0x00000002
#define DRM_BO_HINT_DONT_BLOCK 0x00000004 #define DRM_BO_HINT_DONT_BLOCK 0x00000004
#define DRM_BO_HINT_BIND_CACHED 0x00000008
typedef enum { typedef enum {
drm_bo_type_ttm, drm_bo_type_ttm,

View File

@ -195,9 +195,6 @@ static int i915_initialize(drm_device_t * dev,
I915_WRITE(0x02080, dev_priv->dma_status_page); I915_WRITE(0x02080, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n"); DRM_DEBUG("Enabled hardware status page\n");
#ifdef I915_HAVE_FENCE
dev_priv->saved_flush_status = READ_HWSP(dev_priv, 0);
#endif
dev->dev_private = (void *)dev_priv; dev->dev_private = (void *)dev_priv;
return 0; return 0;

View File

@ -275,6 +275,12 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
i915_enable_interrupt(dev); i915_enable_interrupt(dev);
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
/*
* Initialize the hardware status page IRQ location.
*/
I915_WRITE(I915REG_INSTPM, ( 1 << 5) | ( 1 << 21));
} }
void i915_driver_irq_uninstall(drm_device_t * dev) void i915_driver_irq_uninstall(drm_device_t * dev)