Checkpoint commit. Buffer object flags and IOCTL argument list.
parent
0dedfc2cd0
commit
23f01c9fe8
135
libdrm/xf86drm.c
135
libdrm/xf86drm.c
|
@ -65,6 +65,8 @@
|
|||
# define _DRM_FREE free
|
||||
# include "drm.h"
|
||||
#endif
|
||||
#include "xf86mm.h"
|
||||
|
||||
|
||||
/* Not all systems have MAP_FAILED defined */
|
||||
#ifndef MAP_FAILED
|
||||
|
@ -2384,7 +2386,7 @@ int drmTTMCreate(int fd, drmTTM *ttm, unsigned long size, unsigned flags)
|
|||
|
||||
int drmTTMDestroy(int fd, const drmTTM *ttm)
|
||||
{
|
||||
drm_ttm_arg_t arg;
|
||||
drm_ttm_arg_t arg;
|
||||
|
||||
arg.op = drm_ttm_destroy;
|
||||
arg.handle = ttm->handle;
|
||||
|
@ -2425,4 +2427,135 @@ drm_handle_t drmTTMMapHandle(int fd, const drmTTM *ttm)
|
|||
(void) fd;
|
||||
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
|
||||
|
|
|
@ -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
|
|
@ -652,7 +652,8 @@ typedef struct drm_ref_object {
|
|||
*/
|
||||
|
||||
typedef struct drm_bo_driver{
|
||||
int cached_pages;
|
||||
int cached_tt;
|
||||
int cached_vram;
|
||||
drm_ttm_backend_t *(*create_ttm_backend_entry)
|
||||
(struct drm_device *dev, int cached);
|
||||
} drm_bo_driver_t;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
@ -531,11 +550,12 @@ static int drm_buffer_object_validate(drm_device_t *dev, drm_buffer_object_t *bo
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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)
|
||||
|
||||
{
|
||||
|
@ -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);
|
||||
ret = drm_create_ttm_region(ttm, bo->buffer_start >> PAGE_SHIFT,
|
||||
bo->num_pages,
|
||||
new_flags & DRM_BO_FLAG_CACHED,
|
||||
hint & DRM_BO_HINT_BIND_CACHED,
|
||||
&bo->ttm_region);
|
||||
if (ret) {
|
||||
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->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);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
|
|
|
@ -202,10 +202,11 @@ int drm_destroy_ttm(drm_ttm_t * ttm)
|
|||
|
||||
if (atomic_read(&ttm->vma_count) > 0) {
|
||||
ttm->destroy = 1;
|
||||
DRM_DEBUG("VMAs are still alive. Skipping destruction.\n");
|
||||
DRM_ERROR("VMAs are still alive. Skipping destruction.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
DRM_ERROR("Destroying a ttm\n");
|
||||
if (ttm->be_list) {
|
||||
list_for_each_safe(list, next, &ttm->be_list->head) {
|
||||
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;
|
||||
int i;
|
||||
|
||||
DRM_ERROR("Destroying a TTM region\n");
|
||||
list_del_init(&entry->head);
|
||||
|
||||
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)
|
||||
{
|
||||
DRM_ERROR("User deref ttm\n");
|
||||
drm_ttm_object_deref_locked(priv->head->dev,
|
||||
drm_user_object_entry(base, drm_ttm_object_t,
|
||||
base));
|
||||
|
|
|
@ -49,7 +49,8 @@ static drm_fence_driver_t i915_fence_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
|
||||
};
|
||||
|
||||
|
|
|
@ -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_flags = fm->pending_flush;
|
||||
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));
|
||||
dev_priv->flush_pending = 1;
|
||||
fm->pending_flush = 0;
|
||||
|
|
|
@ -685,7 +685,7 @@ typedef struct drm_ttm_arg {
|
|||
#define DRM_BO_FLAG_NO_MOVE 0x00000008
|
||||
#define DRM_BO_FLAG_NO_EVICT 0x00000010
|
||||
#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_SHAREABLE 0x00000100
|
||||
|
||||
|
@ -697,6 +697,7 @@ typedef struct drm_ttm_arg {
|
|||
#define DRM_BO_HINT_PREFER_VRAM 0x00000001
|
||||
#define DRM_BO_HINT_AVOID_LOCAL 0x00000002
|
||||
#define DRM_BO_HINT_DONT_BLOCK 0x00000004
|
||||
#define DRM_BO_HINT_BIND_CACHED 0x00000008
|
||||
|
||||
typedef enum {
|
||||
drm_bo_type_ttm,
|
||||
|
|
|
@ -195,9 +195,6 @@ static int i915_initialize(drm_device_t * dev,
|
|||
|
||||
I915_WRITE(0x02080, dev_priv->dma_status_page);
|
||||
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;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -275,6 +275,12 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
|
|||
|
||||
i915_enable_interrupt(dev);
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue