mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 16:08:04 +02:00
dri: remove ttm common code since superioctl is device specific
This commit is contained in:
parent
7fc5c0307a
commit
ea2278bc79
1 changed files with 0 additions and 598 deletions
|
|
@ -1,598 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright © 2007 Intel Corporation
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
/*
|
||||
* Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
|
||||
* Keith Whitwell <keithw-at-tungstengraphics-dot-com>
|
||||
* Eric Anholt <eric@anholt.net>
|
||||
*/
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "glthread.h"
|
||||
#include "errno.h"
|
||||
#include "mtypes.h"
|
||||
#include "dri_bufmgr.h"
|
||||
#include "string.h"
|
||||
#include "imports.h"
|
||||
|
||||
#define BUFMGR_DEBUG 0
|
||||
#define MAX_RELOCS 4096
|
||||
|
||||
struct ttm_buffer_reloc
|
||||
{
|
||||
dri_bo *buf;
|
||||
GLuint offset;
|
||||
GLuint delta; /* not needed? */
|
||||
GLuint validate_flags;
|
||||
};
|
||||
|
||||
typedef struct _dri_bufmgr_ttm {
|
||||
dri_bufmgr bufmgr;
|
||||
|
||||
int fd;
|
||||
_glthread_Mutex mutex;
|
||||
unsigned int fence_type;
|
||||
unsigned int fence_type_flush;
|
||||
|
||||
/** ttm relocation list */
|
||||
struct ttm_buffer_reloc reloc[MAX_RELOCS];
|
||||
GLuint nr_relocs;
|
||||
GLboolean performed_rendering;
|
||||
|
||||
} dri_bufmgr_ttm;
|
||||
|
||||
typedef struct _dri_bo_ttm {
|
||||
dri_bo bo;
|
||||
|
||||
int refcount; /* Protected by bufmgr->mutex */
|
||||
drmBO drm_bo;
|
||||
const char *name;
|
||||
/**
|
||||
* Note whether we are the owner of the buffer, to determine if we must
|
||||
* drmBODestroy or drmBOUnreference to unreference the buffer.
|
||||
*/
|
||||
GLboolean owner;
|
||||
} dri_bo_ttm;
|
||||
|
||||
typedef struct _dri_fence_ttm
|
||||
{
|
||||
dri_fence fence;
|
||||
|
||||
int refcount; /* Protected by bufmgr->mutex */
|
||||
const char *name;
|
||||
drmFence drm_fence;
|
||||
} dri_fence_ttm;
|
||||
|
||||
#if 0
|
||||
int
|
||||
driFenceSignaled(DriFenceObject * fence, unsigned type)
|
||||
{
|
||||
int signaled;
|
||||
int ret;
|
||||
|
||||
if (fence == NULL)
|
||||
return GL_TRUE;
|
||||
|
||||
_glthread_LOCK_MUTEX(fence->mutex);
|
||||
ret = drmFenceSignaled(bufmgr_ttm->fd, &fence->fence, type, &signaled);
|
||||
_glthread_UNLOCK_MUTEX(fence->mutex);
|
||||
BM_CKFATAL(ret);
|
||||
return signaled;
|
||||
}
|
||||
#endif
|
||||
|
||||
static dri_bo *
|
||||
dri_ttm_alloc(dri_bufmgr *bufmgr, const char *name,
|
||||
unsigned long size, unsigned int alignment,
|
||||
unsigned int location_mask)
|
||||
{
|
||||
dri_bufmgr_ttm *ttm_bufmgr;
|
||||
dri_bo_ttm *ttm_buf;
|
||||
unsigned int pageSize = getpagesize();
|
||||
int ret;
|
||||
unsigned int flags, hint;
|
||||
|
||||
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
|
||||
|
||||
ttm_buf = malloc(sizeof(*ttm_buf));
|
||||
if (!ttm_buf)
|
||||
return NULL;
|
||||
|
||||
/* The mask argument doesn't do anything for us that we want other than
|
||||
* determine which pool (TTM or local) the buffer is allocated into, so just
|
||||
* pass all of the allocation class flags.
|
||||
*/
|
||||
flags = location_mask | DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
|
||||
DRM_BO_FLAG_EXE;
|
||||
/* No hints we want to use. */
|
||||
hint = 0;
|
||||
|
||||
ret = drmBOCreate(ttm_bufmgr->fd, 0, size, alignment / pageSize,
|
||||
NULL, drm_bo_type_dc,
|
||||
flags, hint, &ttm_buf->drm_bo);
|
||||
if (ret != 0) {
|
||||
free(ttm_buf);
|
||||
return NULL;
|
||||
}
|
||||
ttm_buf->bo.size = ttm_buf->drm_bo.size;
|
||||
ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
|
||||
ttm_buf->bo.virtual = NULL;
|
||||
ttm_buf->bo.bufmgr = bufmgr;
|
||||
ttm_buf->name = name;
|
||||
ttm_buf->refcount = 1;
|
||||
ttm_buf->owner = GL_TRUE;
|
||||
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "bo_create: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
|
||||
#endif
|
||||
|
||||
return &ttm_buf->bo;
|
||||
}
|
||||
|
||||
/* Our TTM backend doesn't allow creation of static buffers, as that requires
|
||||
* privelege for the non-fake case, and the lock in the fake case where we were
|
||||
* working around the X Server not creating buffers and passing handles to us.
|
||||
*/
|
||||
static dri_bo *
|
||||
dri_ttm_alloc_static(dri_bufmgr *bufmgr, const char *name,
|
||||
unsigned long offset, unsigned long size, void *virtual,
|
||||
unsigned int location_mask)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Returns a dri_bo wrapping the given buffer object handle.
|
||||
*
|
||||
* This can be used when one application needs to pass a buffer object
|
||||
* to another.
|
||||
*/
|
||||
dri_bo *
|
||||
dri_ttm_bo_create_from_handle(dri_bufmgr *bufmgr, const char *name,
|
||||
unsigned int handle)
|
||||
{
|
||||
dri_bufmgr_ttm *ttm_bufmgr;
|
||||
dri_bo_ttm *ttm_buf;
|
||||
int ret;
|
||||
|
||||
ttm_bufmgr = (dri_bufmgr_ttm *)bufmgr;
|
||||
|
||||
ttm_buf = malloc(sizeof(*ttm_buf));
|
||||
if (!ttm_buf)
|
||||
return NULL;
|
||||
|
||||
ret = drmBOReference(ttm_bufmgr->fd, handle, &ttm_buf->drm_bo);
|
||||
if (ret != 0) {
|
||||
free(ttm_buf);
|
||||
return NULL;
|
||||
}
|
||||
ttm_buf->bo.size = ttm_buf->drm_bo.size;
|
||||
ttm_buf->bo.offset = ttm_buf->drm_bo.offset;
|
||||
ttm_buf->bo.virtual = NULL;
|
||||
ttm_buf->bo.bufmgr = bufmgr;
|
||||
ttm_buf->name = name;
|
||||
ttm_buf->refcount = 1;
|
||||
ttm_buf->owner = GL_FALSE;
|
||||
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "bo_create_from_handle: %p (%s)\n", &ttm_buf->bo,
|
||||
ttm_buf->name);
|
||||
#endif
|
||||
|
||||
return &ttm_buf->bo;
|
||||
}
|
||||
|
||||
static void
|
||||
dri_ttm_bo_reference(dri_bo *buf)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
|
||||
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
|
||||
|
||||
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
ttm_buf->refcount++;
|
||||
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
dri_ttm_bo_unreference(dri_bo *buf)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
|
||||
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
|
||||
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
if (--ttm_buf->refcount == 0) {
|
||||
int ret;
|
||||
|
||||
/* XXX Having to use drmBODestroy as the opposite of drmBOCreate instead
|
||||
* of simply unreferencing is madness, and leads to behaviors we may not
|
||||
* want (making the buffer unsharable).
|
||||
*/
|
||||
if (ttm_buf->owner)
|
||||
ret = drmBODestroy(bufmgr_ttm->fd, &ttm_buf->drm_bo);
|
||||
else
|
||||
ret = drmBOUnReference(bufmgr_ttm->fd, &ttm_buf->drm_bo);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "drmBOUnReference failed (%s): %s\n", ttm_buf->name,
|
||||
strerror(-ret));
|
||||
}
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "bo_unreference final: %p (%s)\n",
|
||||
&ttm_buf->bo, ttm_buf->name);
|
||||
#endif
|
||||
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
}
|
||||
|
||||
static int
|
||||
dri_ttm_bo_map(dri_bo *buf, GLboolean write_enable)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm;
|
||||
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
|
||||
unsigned int flags;
|
||||
|
||||
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
|
||||
|
||||
flags = DRM_BO_FLAG_READ;
|
||||
if (write_enable)
|
||||
flags |= DRM_BO_FLAG_WRITE;
|
||||
|
||||
assert(buf->virtual == NULL);
|
||||
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "bo_map: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
|
||||
#endif
|
||||
|
||||
return drmBOMap(bufmgr_ttm->fd, &ttm_buf->drm_bo, flags, 0, &buf->virtual);
|
||||
}
|
||||
|
||||
static int
|
||||
dri_ttm_bo_unmap(dri_bo *buf)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm;
|
||||
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
|
||||
|
||||
if (buf == NULL)
|
||||
return 0;
|
||||
|
||||
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
|
||||
|
||||
assert(buf->virtual != NULL);
|
||||
|
||||
buf->virtual = NULL;
|
||||
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "bo_unmap: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
|
||||
#endif
|
||||
|
||||
return drmBOUnmap(bufmgr_ttm->fd, &ttm_buf->drm_bo);
|
||||
}
|
||||
|
||||
static int
|
||||
dri_ttm_validate(dri_bo *buf, unsigned int flags)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm;
|
||||
dri_bo_ttm *ttm_buf = (dri_bo_ttm *)buf;
|
||||
unsigned int mask;
|
||||
int err;
|
||||
|
||||
/* XXX: Sanity-check whether we've already validated this one under
|
||||
* different flags. See drmAddValidateItem().
|
||||
*/
|
||||
|
||||
bufmgr_ttm = (dri_bufmgr_ttm *)buf->bufmgr;
|
||||
|
||||
/* Calculate the appropriate mask to pass to the DRM. There appears to be
|
||||
* be a direct relationship to flags, so it's unnecessary to have it passed
|
||||
* in as an argument.
|
||||
*/
|
||||
mask = DRM_BO_MASK_MEM;
|
||||
mask |= flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE);
|
||||
|
||||
err = drmBOValidate(bufmgr_ttm->fd, &ttm_buf->drm_bo, 0, flags, mask, 0);
|
||||
|
||||
if (err == 0) {
|
||||
/* XXX: add to fence list for sanity checking */
|
||||
} else {
|
||||
fprintf(stderr, "failed to validate buffer (%s): %s\n",
|
||||
ttm_buf->name, strerror(-err));
|
||||
}
|
||||
|
||||
buf->offset = ttm_buf->drm_bo.offset;
|
||||
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "bo_validate: %p (%s)\n", &ttm_buf->bo, ttm_buf->name);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static dri_fence *
|
||||
dri_ttm_fence_validated(dri_bufmgr *bufmgr, const char *name,
|
||||
GLboolean flushed)
|
||||
{
|
||||
dri_fence_ttm *fence_ttm = malloc(sizeof(*fence_ttm));
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
|
||||
int ret;
|
||||
unsigned int type;
|
||||
|
||||
if (!fence_ttm)
|
||||
return NULL;
|
||||
|
||||
if (flushed)
|
||||
type = bufmgr_ttm->fence_type_flush;
|
||||
else
|
||||
type = bufmgr_ttm->fence_type;
|
||||
|
||||
fence_ttm->refcount = 1;
|
||||
fence_ttm->name = name;
|
||||
fence_ttm->fence.bufmgr = bufmgr;
|
||||
ret = drmFenceBuffers(bufmgr_ttm->fd, type, 0, &fence_ttm->drm_fence);
|
||||
if (ret) {
|
||||
fprintf(stderr, "failed to fence (%s): %s\n", name, strerror(-ret));
|
||||
free(fence_ttm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "fence_validated: %p (%s)\n", &fence_ttm->fence,
|
||||
fence_ttm->name);
|
||||
#endif
|
||||
|
||||
return &fence_ttm->fence;
|
||||
}
|
||||
|
||||
static void
|
||||
dri_ttm_fence_reference(dri_fence *fence)
|
||||
{
|
||||
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
|
||||
|
||||
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
++fence_ttm->refcount;
|
||||
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
dri_ttm_fence_unreference(dri_fence *fence)
|
||||
{
|
||||
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
|
||||
|
||||
if (!fence)
|
||||
return;
|
||||
|
||||
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
if (--fence_ttm->refcount == 0) {
|
||||
int ret;
|
||||
|
||||
/* XXX Having to use drmFenceDestroy as the opposite of drmFenceBuffers
|
||||
* instead of simply unreferencing is madness, and leads to behaviors we
|
||||
* may not want (making the fence unsharable). This behavior by the DRM
|
||||
* ioctls should be fixed, and drmFenceDestroy eliminated.
|
||||
*/
|
||||
ret = drmFenceDestroy(bufmgr_ttm->fd, &fence_ttm->drm_fence);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "drmFenceDestroy failed (%s): %s\n",
|
||||
fence_ttm->name, strerror(-ret));
|
||||
}
|
||||
|
||||
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
free(fence);
|
||||
return;
|
||||
}
|
||||
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
dri_ttm_fence_wait(dri_fence *fence)
|
||||
{
|
||||
dri_fence_ttm *fence_ttm = (dri_fence_ttm *)fence;
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)fence->bufmgr;
|
||||
int ret;
|
||||
|
||||
_glthread_LOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
ret = drmFenceWait(bufmgr_ttm->fd, 0, &fence_ttm->drm_fence, 0);
|
||||
_glthread_UNLOCK_MUTEX(bufmgr_ttm->mutex);
|
||||
if (ret != 0) {
|
||||
_mesa_printf("%s:%d: Error %d waiting for fence %s.\n",
|
||||
__FILE__, __LINE__, ret, fence_ttm->name);
|
||||
abort();
|
||||
}
|
||||
|
||||
#if BUFMGR_DEBUG
|
||||
fprintf(stderr, "fence_wait: %p (%s)\n", &fence_ttm->fence,
|
||||
fence_ttm->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
dri_bufmgr_ttm_destroy(dri_bufmgr *bufmgr)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)bufmgr;
|
||||
|
||||
_glthread_DESTROY_MUTEX(bufmgr_ttm->mutex);
|
||||
free(bufmgr);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dri_ttm_emit_reloc(dri_bo *batch_buf, GLuint flags, GLuint delta, GLuint offset,
|
||||
dri_bo *relocatee)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
|
||||
struct ttm_buffer_reloc *r = &bufmgr_ttm->reloc[bufmgr_ttm->nr_relocs++];
|
||||
|
||||
assert(bufmgr_ttm->nr_relocs <= MAX_RELOCS);
|
||||
|
||||
dri_bo_reference(relocatee);
|
||||
|
||||
r->buf = relocatee;
|
||||
r->offset = offset;
|
||||
r->delta = delta;
|
||||
r->validate_flags = flags;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
relocation_sort(const void *a_in, const void *b_in) {
|
||||
const struct ttm_buffer_reloc *a = a_in, *b = b_in;
|
||||
|
||||
return (intptr_t)a->buf < (intptr_t)b->buf ? -1 : 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
dri_ttm_process_reloc(dri_bo *batch_buf)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
|
||||
GLuint i;
|
||||
GLuint *ptr;
|
||||
|
||||
assert(batch_buf->virtual != NULL);
|
||||
ptr = batch_buf->virtual;
|
||||
|
||||
bufmgr_ttm->performed_rendering = GL_FALSE;
|
||||
|
||||
/* Sort our relocation list in terms of referenced buffer pointer.
|
||||
* This lets us uniquely validate the buffers with the sum of all the flags,
|
||||
* while avoiding O(n^2) on number of relocations.
|
||||
*/
|
||||
qsort(bufmgr_ttm->reloc, bufmgr_ttm->nr_relocs, sizeof(bufmgr_ttm->reloc[0]),
|
||||
relocation_sort);
|
||||
|
||||
/* Perform the necessary validations of buffers, and enter the relocations
|
||||
* in the batchbuffer.
|
||||
*/
|
||||
for (i = 0; i < bufmgr_ttm->nr_relocs; i++) {
|
||||
struct ttm_buffer_reloc *r = &bufmgr_ttm->reloc[i];
|
||||
|
||||
if (r->validate_flags & DRM_BO_FLAG_WRITE)
|
||||
bufmgr_ttm->performed_rendering = GL_TRUE;
|
||||
|
||||
/* If this is the first time we've seen this buffer in the relocation
|
||||
* list, figure out our flags and validate it.
|
||||
*/
|
||||
if (i == 0 || bufmgr_ttm->reloc[i - 1].buf != r->buf) {
|
||||
uint32_t validate_flags;
|
||||
int j, ret;
|
||||
|
||||
/* Accumulate the flags we need for validating this buffer. */
|
||||
validate_flags = r->validate_flags;
|
||||
for (j = i + 1; j < bufmgr_ttm->nr_relocs; j++) {
|
||||
if (bufmgr_ttm->reloc[j].buf != r->buf)
|
||||
break;
|
||||
validate_flags |= bufmgr_ttm->reloc[j].validate_flags;
|
||||
}
|
||||
|
||||
/* Validate. If we fail, fence to clear the unfenced list and bail
|
||||
* out.
|
||||
*/
|
||||
ret = dri_bo_validate(r->buf, validate_flags);
|
||||
if (ret != 0) {
|
||||
dri_fence *fo;
|
||||
dri_bo_unmap(batch_buf);
|
||||
fo = dri_fence_validated(batch_buf->bufmgr,
|
||||
"batchbuffer failure fence", GL_TRUE);
|
||||
dri_fence_unreference(fo);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
ptr[r->offset / 4] = r->buf->offset + r->delta;
|
||||
dri_bo_unreference(r->buf);
|
||||
}
|
||||
dri_bo_unmap(batch_buf);
|
||||
|
||||
dri_bo_validate(batch_buf, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_EXE);
|
||||
|
||||
bufmgr_ttm->nr_relocs = 0;
|
||||
done:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
dri_ttm_post_submit(dri_bo *batch_buf, dri_fence **last_fence)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm = (dri_bufmgr_ttm *)batch_buf->bufmgr;
|
||||
dri_fence *fo;
|
||||
|
||||
fo = dri_fence_validated(batch_buf->bufmgr, "Batch fence", GL_TRUE);
|
||||
|
||||
if (bufmgr_ttm->performed_rendering) {
|
||||
dri_fence_unreference(*last_fence);
|
||||
*last_fence = fo;
|
||||
} else {
|
||||
dri_fence_unreference(fo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the TTM buffer manager, which uses the kernel to allocate, map,
|
||||
* and manage map buffer objections.
|
||||
*
|
||||
* \param fd File descriptor of the opened DRM device.
|
||||
* \param fence_type Driver-specific fence type used for fences with no flush.
|
||||
* \param fence_type_flush Driver-specific fence type used for fences with a
|
||||
* flush.
|
||||
*/
|
||||
dri_bufmgr *
|
||||
dri_bufmgr_ttm_init(int fd, unsigned int fence_type,
|
||||
unsigned int fence_type_flush)
|
||||
{
|
||||
dri_bufmgr_ttm *bufmgr_ttm;
|
||||
|
||||
bufmgr_ttm = malloc(sizeof(*bufmgr_ttm));
|
||||
bufmgr_ttm->fd = fd;
|
||||
bufmgr_ttm->fence_type = fence_type;
|
||||
bufmgr_ttm->fence_type_flush = fence_type_flush;
|
||||
_glthread_INIT_MUTEX(bufmgr_ttm->mutex);
|
||||
|
||||
bufmgr_ttm->bufmgr.bo_alloc = dri_ttm_alloc;
|
||||
bufmgr_ttm->bufmgr.bo_alloc_static = dri_ttm_alloc_static;
|
||||
bufmgr_ttm->bufmgr.bo_reference = dri_ttm_bo_reference;
|
||||
bufmgr_ttm->bufmgr.bo_unreference = dri_ttm_bo_unreference;
|
||||
bufmgr_ttm->bufmgr.bo_map = dri_ttm_bo_map;
|
||||
bufmgr_ttm->bufmgr.bo_unmap = dri_ttm_bo_unmap;
|
||||
bufmgr_ttm->bufmgr.bo_validate = dri_ttm_validate;
|
||||
bufmgr_ttm->bufmgr.fence_validated = dri_ttm_fence_validated;
|
||||
bufmgr_ttm->bufmgr.fence_reference = dri_ttm_fence_reference;
|
||||
bufmgr_ttm->bufmgr.fence_unreference = dri_ttm_fence_unreference;
|
||||
bufmgr_ttm->bufmgr.fence_wait = dri_ttm_fence_wait;
|
||||
bufmgr_ttm->bufmgr.destroy = dri_bufmgr_ttm_destroy;
|
||||
bufmgr_ttm->bufmgr.emit_reloc = dri_ttm_emit_reloc;
|
||||
bufmgr_ttm->bufmgr.process_relocs = dri_ttm_process_reloc;
|
||||
bufmgr_ttm->bufmgr.post_submit = dri_ttm_post_submit;
|
||||
return &bufmgr_ttm->bufmgr;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue