mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-20 09:20:09 +01:00
intel: Protect bufmgr objects with a pthread mutex.
We want to be able to use the bufmgr from multiple threads for GL, and thus we need to protect the internal structures. The pthread-stubs package is used so that programs not linked against pthreads get weak symbols to stubs and don't eat most of the cost.
This commit is contained in:
parent
26076bf24a
commit
6df7b0719f
5 changed files with 155 additions and 31 deletions
|
|
@ -32,6 +32,10 @@ AC_PROG_CC
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES(PTHREADSTUBS, pthread-stubs)
|
||||||
|
AC_SUBST(PTHREADSTUBS_CFLAGS)
|
||||||
|
AC_SUBST(PTHREADSTUBS_LIBS)
|
||||||
|
|
||||||
pkgconfigdir=${libdir}/pkgconfig
|
pkgconfigdir=${libdir}/pkgconfig
|
||||||
AC_SUBST(pkgconfigdir)
|
AC_SUBST(pkgconfigdir)
|
||||||
AC_ARG_ENABLE(udev, AS_HELP_STRING([--enable-udev],
|
AC_ARG_ENABLE(udev, AS_HELP_STRING([--enable-udev],
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ libdrm_la_LDFLAGS = -version-number 2:3:0 -no-undefined
|
||||||
|
|
||||||
AM_CFLAGS = -I$(top_srcdir)/shared-core
|
AM_CFLAGS = -I$(top_srcdir)/shared-core
|
||||||
libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \
|
libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \
|
||||||
xf86drmMode.c
|
xf86drmMode.c libdrm_lists.h
|
||||||
libdrm_la_LIBADD = intel/libdrm_intel.la
|
libdrm_la_LIBADD = intel/libdrm_intel.la @PTHREADSTUBS_LIBS@
|
||||||
|
|
||||||
libdrmincludedir = ${includedir}
|
libdrmincludedir = ${includedir}
|
||||||
libdrminclude_HEADERS = xf86drm.h xf86drmMode.h
|
libdrminclude_HEADERS = xf86drm.h xf86drmMode.h
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ AM_CFLAGS = \
|
||||||
$(WARN_CFLAGS) \
|
$(WARN_CFLAGS) \
|
||||||
-I$(top_srcdir)/libdrm \
|
-I$(top_srcdir)/libdrm \
|
||||||
-I$(top_srcdir)/libdrm/intel \
|
-I$(top_srcdir)/libdrm/intel \
|
||||||
|
$(PTHREADSTUBS_CFLAGS) \
|
||||||
-I$(top_srcdir)/shared-core
|
-I$(top_srcdir)/shared-core
|
||||||
|
|
||||||
libdrm_intel_la_LTLIBRARIES = libdrm_intel.la
|
libdrm_intel_la_LTLIBRARIES = libdrm_intel.la
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include "intel_bufmgr.h"
|
#include "intel_bufmgr.h"
|
||||||
#include "intel_bufmgr_priv.h"
|
#include "intel_bufmgr_priv.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
|
@ -112,6 +113,8 @@ struct block {
|
||||||
typedef struct _bufmgr_fake {
|
typedef struct _bufmgr_fake {
|
||||||
dri_bufmgr bufmgr;
|
dri_bufmgr bufmgr;
|
||||||
|
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
|
||||||
unsigned long low_offset;
|
unsigned long low_offset;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
void *virtual;
|
void *virtual;
|
||||||
|
|
@ -716,10 +719,16 @@ dri_fake_bo_wait_rendering(dri_bo *bo)
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
|
||||||
if (bo_fake->block == NULL || !bo_fake->block->fenced)
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
|
if (bo_fake->block == NULL || !bo_fake->block->fenced) {
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_fence_wait_internal(bufmgr_fake, bo_fake->block->fence);
|
_fence_wait_internal(bufmgr_fake, bo_fake->block->fence);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Specifically ignore texture memory sharing.
|
/* Specifically ignore texture memory sharing.
|
||||||
|
|
@ -732,6 +741,8 @@ intel_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr)
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr;
|
||||||
struct block *block, *tmp;
|
struct block *block, *tmp;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
bufmgr_fake->need_fence = 1;
|
bufmgr_fake->need_fence = 1;
|
||||||
bufmgr_fake->fail = 0;
|
bufmgr_fake->fail = 0;
|
||||||
|
|
||||||
|
|
@ -751,6 +762,8 @@ intel_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr)
|
||||||
assert(_fence_test(bufmgr_fake, block->fence));
|
assert(_fence_test(bufmgr_fake, block->fence));
|
||||||
set_dirty(block->bo);
|
set_dirty(block->bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static dri_bo *
|
static dri_bo *
|
||||||
|
|
@ -824,6 +837,17 @@ intel_bo_fake_alloc_static(dri_bufmgr *bufmgr, const char *name,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dri_fake_bo_reference(dri_bo *bo)
|
dri_fake_bo_reference(dri_bo *bo)
|
||||||
|
{
|
||||||
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
bo_fake->refcount++;
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri_fake_bo_reference_locked(dri_bo *bo)
|
||||||
{
|
{
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
|
||||||
|
|
@ -831,15 +855,12 @@ dri_fake_bo_reference(dri_bo *bo)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dri_fake_bo_unreference(dri_bo *bo)
|
dri_fake_bo_unreference_locked(dri_bo *bo)
|
||||||
{
|
{
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!bo)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (--bo_fake->refcount == 0) {
|
if (--bo_fake->refcount == 0) {
|
||||||
assert(bo_fake->map_count == 0);
|
assert(bo_fake->map_count == 0);
|
||||||
/* No remaining references, so free it */
|
/* No remaining references, so free it */
|
||||||
|
|
@ -848,17 +869,25 @@ dri_fake_bo_unreference(dri_bo *bo)
|
||||||
free_backing_store(bo);
|
free_backing_store(bo);
|
||||||
|
|
||||||
for (i = 0; i < bo_fake->nr_relocs; i++)
|
for (i = 0; i < bo_fake->nr_relocs; i++)
|
||||||
dri_bo_unreference(bo_fake->relocs[i].target_buf);
|
dri_fake_bo_unreference_locked(bo_fake->relocs[i].target_buf);
|
||||||
|
|
||||||
DBG("drm_bo_unreference: free buf %d %s\n", bo_fake->id, bo_fake->name);
|
DBG("drm_bo_unreference: free buf %d %s\n", bo_fake->id, bo_fake->name);
|
||||||
|
|
||||||
free(bo_fake->relocs);
|
free(bo_fake->relocs);
|
||||||
free(bo);
|
free(bo);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri_fake_bo_unreference(dri_bo *bo)
|
||||||
|
{
|
||||||
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
dri_fake_bo_unreference_locked(bo);
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the buffer as not requiring backing store, and instead get the callback
|
* Set the buffer as not requiring backing store, and instead get the callback
|
||||||
* invoked whenever it would be set dirty.
|
* invoked whenever it would be set dirty.
|
||||||
|
|
@ -871,6 +900,8 @@ void intel_bo_fake_disable_backing_store(dri_bo *bo,
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
if (bo_fake->backing_store)
|
if (bo_fake->backing_store)
|
||||||
free_backing_store(bo);
|
free_backing_store(bo);
|
||||||
|
|
||||||
|
|
@ -887,6 +918,8 @@ void intel_bo_fake_disable_backing_store(dri_bo *bo,
|
||||||
*/
|
*/
|
||||||
if (invalidate_cb != NULL)
|
if (invalidate_cb != NULL)
|
||||||
invalidate_cb(bo, ptr);
|
invalidate_cb(bo, ptr);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -894,7 +927,7 @@ void intel_bo_fake_disable_backing_store(dri_bo *bo,
|
||||||
* BM_NO_BACKING_STORE or BM_PINNED) or backing store, as necessary.
|
* BM_NO_BACKING_STORE or BM_PINNED) or backing store, as necessary.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
dri_fake_bo_map(dri_bo *bo, int write_enable)
|
dri_fake_bo_map_locked(dri_bo *bo, int write_enable)
|
||||||
{
|
{
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
|
@ -952,7 +985,20 @@ dri_fake_bo_map(dri_bo *bo, int write_enable)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dri_fake_bo_unmap(dri_bo *bo)
|
dri_fake_bo_map(dri_bo *bo, int write_enable)
|
||||||
|
{
|
||||||
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
ret = dri_fake_bo_map_locked(bo, write_enable);
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dri_fake_bo_unmap_locked(dri_bo *bo)
|
||||||
{
|
{
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
|
@ -973,11 +1019,26 @@ dri_fake_bo_unmap(dri_bo *bo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
dri_fake_bo_unmap(dri_bo *bo)
|
||||||
|
{
|
||||||
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
ret = dri_fake_bo_unmap_locked(bo);
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dri_fake_kick_all(dri_bufmgr_fake *bufmgr_fake)
|
dri_fake_kick_all(dri_bufmgr_fake *bufmgr_fake)
|
||||||
{
|
{
|
||||||
struct block *block, *tmp;
|
struct block *block, *tmp;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
bufmgr_fake->performed_rendering = 0;
|
bufmgr_fake->performed_rendering = 0;
|
||||||
/* okay for ever BO that is on the HW kick it off.
|
/* okay for ever BO that is on the HW kick it off.
|
||||||
seriously not afraid of the POLICE right now */
|
seriously not afraid of the POLICE right now */
|
||||||
|
|
@ -991,6 +1052,8 @@ dri_fake_kick_all(dri_bufmgr_fake *bufmgr_fake)
|
||||||
if (!(bo_fake->flags & BM_NO_BACKING_STORE))
|
if (!(bo_fake->flags & BM_NO_BACKING_STORE))
|
||||||
bo_fake->dirty = 1;
|
bo_fake->dirty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -999,9 +1062,6 @@ dri_fake_bo_validate(dri_bo *bo)
|
||||||
dri_bufmgr_fake *bufmgr_fake;
|
dri_bufmgr_fake *bufmgr_fake;
|
||||||
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
dri_bo_fake *bo_fake = (dri_bo_fake *)bo;
|
||||||
|
|
||||||
/* XXX: Sanity-check whether we've already validated this one under
|
|
||||||
* different flags. See drmAddValidateItem().
|
|
||||||
*/
|
|
||||||
bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr;
|
||||||
|
|
||||||
DBG("drm_bo_validate: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name,
|
DBG("drm_bo_validate: (buf %d: %s, %d kb)\n", bo_fake->id, bo_fake->name,
|
||||||
|
|
@ -1084,6 +1144,7 @@ dri_fake_destroy(dri_bufmgr *bufmgr)
|
||||||
{
|
{
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr;
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&bufmgr_fake->lock);
|
||||||
mmDestroy(bufmgr_fake->heap);
|
mmDestroy(bufmgr_fake->heap);
|
||||||
free(bufmgr);
|
free(bufmgr);
|
||||||
}
|
}
|
||||||
|
|
@ -1099,6 +1160,8 @@ dri_fake_emit_reloc(dri_bo *reloc_buf,
|
||||||
dri_bo_fake *target_fake = (dri_bo_fake *)target_buf;
|
dri_bo_fake *target_fake = (dri_bo_fake *)target_buf;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
assert(reloc_buf);
|
assert(reloc_buf);
|
||||||
assert(target_buf);
|
assert(target_buf);
|
||||||
|
|
||||||
|
|
@ -1111,7 +1174,7 @@ dri_fake_emit_reloc(dri_bo *reloc_buf,
|
||||||
|
|
||||||
assert(reloc_fake->nr_relocs <= MAX_RELOCS);
|
assert(reloc_fake->nr_relocs <= MAX_RELOCS);
|
||||||
|
|
||||||
dri_bo_reference(target_buf);
|
dri_fake_bo_reference_locked(target_buf);
|
||||||
|
|
||||||
if (!target_fake->is_static)
|
if (!target_fake->is_static)
|
||||||
reloc_fake->child_size += ALIGN(target_buf->size, target_fake->alignment);
|
reloc_fake->child_size += ALIGN(target_buf->size, target_fake->alignment);
|
||||||
|
|
@ -1132,6 +1195,8 @@ dri_fake_emit_reloc(dri_bo *reloc_buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1178,7 +1243,7 @@ dri_fake_reloc_and_validate_buffer(dri_bo *bo)
|
||||||
ret = dri_fake_reloc_and_validate_buffer(r->target_buf);
|
ret = dri_fake_reloc_and_validate_buffer(r->target_buf);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
if (bo->virtual != NULL)
|
if (bo->virtual != NULL)
|
||||||
dri_bo_unmap(bo);
|
dri_fake_bo_unmap_locked(bo);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1188,7 +1253,7 @@ dri_fake_reloc_and_validate_buffer(dri_bo *bo)
|
||||||
reloc_data = r->target_buf->offset + r->delta;
|
reloc_data = r->target_buf->offset + r->delta;
|
||||||
|
|
||||||
if (bo->virtual == NULL)
|
if (bo->virtual == NULL)
|
||||||
dri_bo_map(bo, 1);
|
dri_fake_bo_map_locked(bo, 1);
|
||||||
|
|
||||||
*(uint32_t *)((uint8_t *)bo->virtual + r->offset) = reloc_data;
|
*(uint32_t *)((uint8_t *)bo->virtual + r->offset) = reloc_data;
|
||||||
|
|
||||||
|
|
@ -1197,7 +1262,7 @@ dri_fake_reloc_and_validate_buffer(dri_bo *bo)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bo->virtual != NULL)
|
if (bo->virtual != NULL)
|
||||||
dri_bo_unmap(bo);
|
dri_fake_bo_unmap_locked(bo);
|
||||||
|
|
||||||
if (bo_fake->write_domain != 0) {
|
if (bo_fake->write_domain != 0) {
|
||||||
if (!(bo_fake->flags & (BM_NO_BACKING_STORE|BM_PINNED))) {
|
if (!(bo_fake->flags & (BM_NO_BACKING_STORE|BM_PINNED))) {
|
||||||
|
|
@ -1261,6 +1326,8 @@ dri_fake_bo_exec(dri_bo *bo, int used,
|
||||||
int ret;
|
int ret;
|
||||||
int retry_count = 0;
|
int retry_count = 0;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
bufmgr_fake->performed_rendering = 0;
|
bufmgr_fake->performed_rendering = 0;
|
||||||
|
|
||||||
dri_fake_calculate_domains(bo);
|
dri_fake_calculate_domains(bo);
|
||||||
|
|
@ -1305,6 +1372,8 @@ dri_fake_bo_exec(dri_bo *bo, int used,
|
||||||
|
|
||||||
dri_bo_fake_post_submit(bo);
|
dri_bo_fake_post_submit(bo);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1357,6 +1426,8 @@ intel_bufmgr_fake_evict_all(dri_bufmgr *bufmgr)
|
||||||
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr;
|
dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr;
|
||||||
struct block *block, *tmp;
|
struct block *block, *tmp;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_fake->lock);
|
||||||
|
|
||||||
bufmgr_fake->need_fence = 1;
|
bufmgr_fake->need_fence = 1;
|
||||||
bufmgr_fake->fail = 0;
|
bufmgr_fake->fail = 0;
|
||||||
|
|
||||||
|
|
@ -1376,6 +1447,8 @@ intel_bufmgr_fake_evict_all(dri_bufmgr *bufmgr)
|
||||||
/* Releases the memory, and memcpys dirty contents out if necessary. */
|
/* Releases the memory, and memcpys dirty contents out if necessary. */
|
||||||
free_block(bufmgr_fake, block);
|
free_block(bufmgr_fake, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_fake->lock);
|
||||||
}
|
}
|
||||||
void intel_bufmgr_fake_set_last_dispatch(dri_bufmgr *bufmgr,
|
void intel_bufmgr_fake_set_last_dispatch(dri_bufmgr *bufmgr,
|
||||||
volatile unsigned int *last_dispatch)
|
volatile unsigned int *last_dispatch)
|
||||||
|
|
@ -1395,6 +1468,11 @@ intel_bufmgr_fake_init(int fd,
|
||||||
|
|
||||||
bufmgr_fake = calloc(1, sizeof(*bufmgr_fake));
|
bufmgr_fake = calloc(1, sizeof(*bufmgr_fake));
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&bufmgr_fake->lock, NULL) != 0) {
|
||||||
|
free(bufmgr_fake);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize allocator */
|
/* Initialize allocator */
|
||||||
DRMINITLISTHEAD(&bufmgr_fake->fenced);
|
DRMINITLISTHEAD(&bufmgr_fake->fenced);
|
||||||
DRMINITLISTHEAD(&bufmgr_fake->on_hardware);
|
DRMINITLISTHEAD(&bufmgr_fake->on_hardware);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
|
||||||
|
|
@ -84,6 +85,8 @@ typedef struct _dri_bufmgr_gem {
|
||||||
|
|
||||||
int max_relocs;
|
int max_relocs;
|
||||||
|
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
|
||||||
struct drm_i915_gem_exec_object *exec_objects;
|
struct drm_i915_gem_exec_object *exec_objects;
|
||||||
dri_bo **exec_bos;
|
dri_bo **exec_bos;
|
||||||
int exec_size;
|
int exec_size;
|
||||||
|
|
@ -133,6 +136,8 @@ struct _dri_bo_gem {
|
||||||
dri_bo_gem *next;
|
dri_bo_gem *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void dri_gem_bo_reference_locked(dri_bo *bo);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
logbase2(int n)
|
logbase2(int n)
|
||||||
{
|
{
|
||||||
|
|
@ -237,7 +242,7 @@ intel_add_validate_buffer(dri_bo *bo)
|
||||||
bufmgr_gem->exec_objects[index].alignment = 0;
|
bufmgr_gem->exec_objects[index].alignment = 0;
|
||||||
bufmgr_gem->exec_objects[index].offset = 0;
|
bufmgr_gem->exec_objects[index].offset = 0;
|
||||||
bufmgr_gem->exec_bos[index] = bo;
|
bufmgr_gem->exec_bos[index] = bo;
|
||||||
dri_bo_reference(bo);
|
dri_gem_bo_reference_locked(bo);
|
||||||
bufmgr_gem->exec_count++;
|
bufmgr_gem->exec_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -285,6 +290,7 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
|
||||||
bo_size = page_size;
|
bo_size = page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_gem->lock);
|
||||||
/* Get a buffer out of the cache if available */
|
/* Get a buffer out of the cache if available */
|
||||||
if (bucket != NULL && bucket->num_entries > 0) {
|
if (bucket != NULL && bucket->num_entries > 0) {
|
||||||
struct drm_i915_gem_busy busy;
|
struct drm_i915_gem_busy busy;
|
||||||
|
|
@ -302,6 +308,7 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
|
||||||
bucket->num_entries--;
|
bucket->num_entries--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&bufmgr_gem->lock);
|
||||||
|
|
||||||
if (!alloc_from_cache) {
|
if (!alloc_from_cache) {
|
||||||
struct drm_i915_gem_create create;
|
struct drm_i915_gem_create create;
|
||||||
|
|
@ -379,6 +386,17 @@ intel_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dri_gem_bo_reference(dri_bo *bo)
|
dri_gem_bo_reference(dri_bo *bo)
|
||||||
|
{
|
||||||
|
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
|
||||||
|
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_gem->lock);
|
||||||
|
bo_gem->refcount++;
|
||||||
|
pthread_mutex_unlock(&bufmgr_gem->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri_gem_bo_reference_locked(dri_bo *bo)
|
||||||
{
|
{
|
||||||
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
||||||
|
|
||||||
|
|
@ -408,14 +426,11 @@ dri_gem_bo_free(dri_bo *bo)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dri_gem_bo_unreference(dri_bo *bo)
|
dri_gem_bo_unreference_locked(dri_bo *bo)
|
||||||
{
|
{
|
||||||
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
|
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
|
||||||
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
||||||
|
|
||||||
if (!bo)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (--bo_gem->refcount == 0) {
|
if (--bo_gem->refcount == 0) {
|
||||||
struct dri_gem_bo_bucket *bucket;
|
struct dri_gem_bo_bucket *bucket;
|
||||||
|
|
||||||
|
|
@ -424,7 +439,7 @@ dri_gem_bo_unreference(dri_bo *bo)
|
||||||
|
|
||||||
/* Unreference all the target buffers */
|
/* Unreference all the target buffers */
|
||||||
for (i = 0; i < bo_gem->reloc_count; i++)
|
for (i = 0; i < bo_gem->reloc_count; i++)
|
||||||
dri_bo_unreference(bo_gem->reloc_target_bo[i]);
|
dri_gem_bo_unreference_locked(bo_gem->reloc_target_bo[i]);
|
||||||
free(bo_gem->reloc_target_bo);
|
free(bo_gem->reloc_target_bo);
|
||||||
free(bo_gem->relocs);
|
free(bo_gem->relocs);
|
||||||
}
|
}
|
||||||
|
|
@ -452,20 +467,28 @@ dri_gem_bo_unreference(dri_bo *bo)
|
||||||
} else {
|
} else {
|
||||||
dri_gem_bo_free(bo);
|
dri_gem_bo_free(bo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dri_gem_bo_unreference(dri_bo *bo)
|
||||||
|
{
|
||||||
|
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_gem->lock);
|
||||||
|
dri_gem_bo_unreference_locked(bo);
|
||||||
|
pthread_mutex_unlock(&bufmgr_gem->lock);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dri_gem_bo_map(dri_bo *bo, int write_enable)
|
dri_gem_bo_map(dri_bo *bo, int write_enable)
|
||||||
{
|
{
|
||||||
dri_bufmgr_gem *bufmgr_gem;
|
dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
|
||||||
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
||||||
struct drm_i915_gem_set_domain set_domain;
|
struct drm_i915_gem_set_domain set_domain;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
|
pthread_mutex_lock(&bufmgr_gem->lock);
|
||||||
|
|
||||||
/* Allow recursive mapping. Mesa may recursively map buffers with
|
/* Allow recursive mapping. Mesa may recursively map buffers with
|
||||||
* nested display loops.
|
* nested display loops.
|
||||||
|
|
@ -515,6 +538,8 @@ dri_gem_bo_map(dri_bo *bo, int write_enable)
|
||||||
bo_gem->swrast = 1;
|
bo_gem->swrast = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_gem->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -531,6 +556,7 @@ dri_gem_bo_unmap(dri_bo *bo)
|
||||||
|
|
||||||
assert(bo_gem->mapped);
|
assert(bo_gem->mapped);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_gem->lock);
|
||||||
if (bo_gem->swrast) {
|
if (bo_gem->swrast) {
|
||||||
sw_finish.handle = bo_gem->gem_handle;
|
sw_finish.handle = bo_gem->gem_handle;
|
||||||
do {
|
do {
|
||||||
|
|
@ -539,6 +565,7 @@ dri_gem_bo_unmap(dri_bo *bo)
|
||||||
} while (ret == -1 && errno == EINTR);
|
} while (ret == -1 && errno == EINTR);
|
||||||
bo_gem->swrast = 0;
|
bo_gem->swrast = 0;
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&bufmgr_gem->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -623,6 +650,8 @@ dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
|
||||||
free(bufmgr_gem->exec_objects);
|
free(bufmgr_gem->exec_objects);
|
||||||
free(bufmgr_gem->exec_bos);
|
free(bufmgr_gem->exec_bos);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&bufmgr_gem->lock);
|
||||||
|
|
||||||
/* Free any cached buffer objects we were going to reuse */
|
/* Free any cached buffer objects we were going to reuse */
|
||||||
for (i = 0; i < INTEL_GEM_BO_BUCKETS; i++) {
|
for (i = 0; i < INTEL_GEM_BO_BUCKETS; i++) {
|
||||||
struct dri_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i];
|
struct dri_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i];
|
||||||
|
|
@ -658,6 +687,8 @@ dri_gem_bo_emit_reloc(dri_bo *bo, uint32_t read_domains, uint32_t write_domain,
|
||||||
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
dri_bo_gem *bo_gem = (dri_bo_gem *)bo;
|
||||||
dri_bo_gem *target_bo_gem = (dri_bo_gem *)target_bo;
|
dri_bo_gem *target_bo_gem = (dri_bo_gem *)target_bo;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_gem->lock);
|
||||||
|
|
||||||
/* Create a new relocation list if needed */
|
/* Create a new relocation list if needed */
|
||||||
if (bo_gem->relocs == NULL)
|
if (bo_gem->relocs == NULL)
|
||||||
intel_setup_reloc_list(bo);
|
intel_setup_reloc_list(bo);
|
||||||
|
|
@ -678,9 +709,12 @@ dri_gem_bo_emit_reloc(dri_bo *bo, uint32_t read_domains, uint32_t write_domain,
|
||||||
bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset;
|
bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset;
|
||||||
|
|
||||||
bo_gem->reloc_target_bo[bo_gem->reloc_count] = target_bo;
|
bo_gem->reloc_target_bo[bo_gem->reloc_count] = target_bo;
|
||||||
dri_bo_reference(target_bo);
|
dri_gem_bo_reference_locked(target_bo);
|
||||||
|
|
||||||
bo_gem->reloc_count++;
|
bo_gem->reloc_count++;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&bufmgr_gem->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -737,6 +771,7 @@ dri_gem_bo_exec(dri_bo *bo, int used,
|
||||||
struct drm_i915_gem_execbuffer execbuf;
|
struct drm_i915_gem_execbuffer execbuf;
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&bufmgr_gem->lock);
|
||||||
/* Update indices and set up the validate list. */
|
/* Update indices and set up the validate list. */
|
||||||
dri_gem_bo_process_reloc(bo);
|
dri_gem_bo_process_reloc(bo);
|
||||||
|
|
||||||
|
|
@ -772,10 +807,11 @@ dri_gem_bo_exec(dri_bo *bo, int used,
|
||||||
|
|
||||||
/* Disconnect the buffer from the validate list */
|
/* Disconnect the buffer from the validate list */
|
||||||
bo_gem->validate_index = -1;
|
bo_gem->validate_index = -1;
|
||||||
dri_bo_unreference(bo);
|
dri_gem_bo_unreference_locked(bo);
|
||||||
bufmgr_gem->exec_bos[i] = NULL;
|
bufmgr_gem->exec_bos[i] = NULL;
|
||||||
}
|
}
|
||||||
bufmgr_gem->exec_count = 0;
|
bufmgr_gem->exec_count = 0;
|
||||||
|
pthread_mutex_unlock(&bufmgr_gem->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -900,6 +936,11 @@ intel_bufmgr_gem_init(int fd, int batch_size)
|
||||||
bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
|
bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
|
||||||
bufmgr_gem->fd = fd;
|
bufmgr_gem->fd = fd;
|
||||||
|
|
||||||
|
if (pthread_mutex_init(&bufmgr_gem->lock, NULL) != 0) {
|
||||||
|
free(bufmgr_gem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Let's go with one relocation per every 2 dwords (but round down a bit
|
/* Let's go with one relocation per every 2 dwords (but round down a bit
|
||||||
* since a power of two will mean an extra page allocation for the reloc
|
* since a power of two will mean an extra page allocation for the reloc
|
||||||
* buffer).
|
* buffer).
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue