libdrm/radeon: add initial libdrm_radeon
requires --enable-radeon-experimental-api for nowmain
parent
3d4bfe8c89
commit
2fa2db138b
|
@ -47,6 +47,11 @@ AC_ARG_ENABLE(nouveau-experimental-api,
|
||||||
[Enable support for nouveau's experimental API (default: disabled)]),
|
[Enable support for nouveau's experimental API (default: disabled)]),
|
||||||
[NOUVEAU=$enableval], [NOUVEAU=no])
|
[NOUVEAU=$enableval], [NOUVEAU=no])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(radeon-experimental-api,
|
||||||
|
AS_HELP_STRING([--enable-radeon-experimental-api],
|
||||||
|
[Enable support for radeon's KMS API (default: disabled)]),
|
||||||
|
[RADEON=$enableval], [RADEON=no])
|
||||||
|
|
||||||
dnl ===========================================================================
|
dnl ===========================================================================
|
||||||
dnl check compiler flags
|
dnl check compiler flags
|
||||||
AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
|
AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
|
||||||
|
@ -125,6 +130,8 @@ fi
|
||||||
|
|
||||||
AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" = xyes])
|
AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" = xyes])
|
||||||
|
|
||||||
|
AM_CONDITIONAL(HAVE_RADEON, [test "x$RADEON" = xyes])
|
||||||
|
|
||||||
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no])
|
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no])
|
||||||
if test "x$HAVE_CAIRO" = xyes; then
|
if test "x$HAVE_CAIRO" = xyes; then
|
||||||
AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support])
|
AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support])
|
||||||
|
@ -144,6 +151,8 @@ AC_OUTPUT([
|
||||||
Makefile
|
Makefile
|
||||||
libdrm/Makefile
|
libdrm/Makefile
|
||||||
libdrm/intel/Makefile
|
libdrm/intel/Makefile
|
||||||
|
libdrm/radeon/Makefile
|
||||||
|
libdrm/radeon/libdrm_radeon.pc
|
||||||
libdrm/nouveau/Makefile
|
libdrm/nouveau/Makefile
|
||||||
libdrm/nouveau/libdrm_nouveau.pc
|
libdrm/nouveau/libdrm_nouveau.pc
|
||||||
shared-core/Makefile
|
shared-core/Makefile
|
||||||
|
|
|
@ -22,7 +22,11 @@ if HAVE_NOUVEAU
|
||||||
NOUVEAU_SUBDIR = nouveau
|
NOUVEAU_SUBDIR = nouveau
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS = . intel $(NOUVEAU_SUBDIR)
|
if HAVE_RADEON
|
||||||
|
RADEON_SUBDIR = radeon
|
||||||
|
endif
|
||||||
|
|
||||||
|
SUBDIRS = . intel $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR)
|
||||||
|
|
||||||
libdrm_la_LTLIBRARIES = libdrm.la
|
libdrm_la_LTLIBRARIES = libdrm.la
|
||||||
libdrm_ladir = $(libdir)
|
libdrm_ladir = $(libdir)
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Copyright © 2008 Jérôme Glisse
|
||||||
|
#
|
||||||
|
# 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, sublicense,
|
||||||
|
# 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 above copyright notice and this permission notice (including the next
|
||||||
|
# paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
# Software.
|
||||||
|
#
|
||||||
|
# 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 NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||||
|
#
|
||||||
|
# Authors:
|
||||||
|
# Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
|
||||||
|
AM_CFLAGS = \
|
||||||
|
$(WARN_CFLAGS) \
|
||||||
|
-I$(top_srcdir)/libdrm \
|
||||||
|
-I$(top_srcdir)/libdrm/radeon \
|
||||||
|
$(PTHREADSTUBS_CFLAGS) \
|
||||||
|
-I$(top_srcdir)/shared-core
|
||||||
|
|
||||||
|
libdrm_radeon_la_LTLIBRARIES = libdrm_radeon.la
|
||||||
|
libdrm_radeon_ladir = $(libdir)
|
||||||
|
libdrm_radeon_la_LDFLAGS = -version-number 1:0:0 -no-undefined
|
||||||
|
libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
|
||||||
|
|
||||||
|
libdrm_radeon_la_SOURCES = \
|
||||||
|
radeon_bo_gem.c \
|
||||||
|
radeon_cs_gem.c \
|
||||||
|
radeon_track.c
|
||||||
|
|
||||||
|
libdrm_radeonincludedir = ${includedir}/drm
|
||||||
|
libdrm_radeoninclude_HEADERS = \
|
||||||
|
radeon_bo.h \
|
||||||
|
radeon_cs.h \
|
||||||
|
radeon_bo_gem.h \
|
||||||
|
radeon_cs_gem.h \
|
||||||
|
radeon_track.h
|
||||||
|
|
||||||
|
pkgconfigdir = @pkgconfigdir@
|
||||||
|
pkgconfig_DATA = libdrm_radeon.pc
|
||||||
|
|
||||||
|
EXTRA_DIST = libdrm_radeon.pc.in
|
|
@ -0,0 +1,10 @@
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libdrm_radeon
|
||||||
|
Description: Userspace interface to kernel DRM services for radeon
|
||||||
|
Version: 1.0.1
|
||||||
|
Libs: -L${libdir} -ldrm_radeon
|
||||||
|
Cflags: -I${includedir} -I${includedir}/drm
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#ifndef RADEON_BO_H
|
||||||
|
#define RADEON_BO_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "radeon_track.h"
|
||||||
|
|
||||||
|
/* bo object */
|
||||||
|
#define RADEON_BO_FLAGS_MACRO_TILE 1
|
||||||
|
#define RADEON_BO_FLAGS_MICRO_TILE 2
|
||||||
|
|
||||||
|
struct radeon_bo_manager;
|
||||||
|
|
||||||
|
struct radeon_bo {
|
||||||
|
uint32_t alignment;
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t domains;
|
||||||
|
uint32_t flags;
|
||||||
|
unsigned cref;
|
||||||
|
#ifdef RADEON_BO_TRACK
|
||||||
|
struct radeon_track *track;
|
||||||
|
#endif
|
||||||
|
void *ptr;
|
||||||
|
struct radeon_bo_manager *bom;
|
||||||
|
uint32_t space_accounted;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* bo functions */
|
||||||
|
struct radeon_bo_funcs {
|
||||||
|
struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom,
|
||||||
|
uint32_t handle,
|
||||||
|
uint32_t size,
|
||||||
|
uint32_t alignment,
|
||||||
|
uint32_t domains,
|
||||||
|
uint32_t flags);
|
||||||
|
void (*bo_ref)(struct radeon_bo *bo);
|
||||||
|
struct radeon_bo *(*bo_unref)(struct radeon_bo *bo);
|
||||||
|
int (*bo_map)(struct radeon_bo *bo, int write);
|
||||||
|
int (*bo_unmap)(struct radeon_bo *bo);
|
||||||
|
int (*bo_wait)(struct radeon_bo *bo);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radeon_bo_manager {
|
||||||
|
struct radeon_bo_funcs *funcs;
|
||||||
|
int fd;
|
||||||
|
struct radeon_tracker tracker;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void _radeon_bo_debug(struct radeon_bo *bo,
|
||||||
|
const char *op,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n",
|
||||||
|
op, bo, bo->handle, bo->size, bo->cref, file, func, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom,
|
||||||
|
uint32_t handle,
|
||||||
|
uint32_t size,
|
||||||
|
uint32_t alignment,
|
||||||
|
uint32_t domains,
|
||||||
|
uint32_t flags,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
struct radeon_bo *bo;
|
||||||
|
|
||||||
|
bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags);
|
||||||
|
#ifdef RADEON_BO_TRACK
|
||||||
|
if (bo) {
|
||||||
|
bo->track = radeon_tracker_add_track(&bom->tracker, bo->handle);
|
||||||
|
radeon_track_add_event(bo->track, file, func, "open", line);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return bo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _radeon_bo_ref(struct radeon_bo *bo,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
bo->cref++;
|
||||||
|
#ifdef RADEON_BO_TRACK
|
||||||
|
radeon_track_add_event(bo->track, file, func, "ref", line);
|
||||||
|
#endif
|
||||||
|
bo->bom->funcs->bo_ref(bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct radeon_bo *_radeon_bo_unref(struct radeon_bo *bo,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
bo->cref--;
|
||||||
|
#ifdef RADEON_BO_TRACK
|
||||||
|
radeon_track_add_event(bo->track, file, func, "unref", line);
|
||||||
|
if (bo->cref <= 0) {
|
||||||
|
radeon_tracker_remove_track(&bo->bom->tracker, bo->track);
|
||||||
|
bo->track = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return bo->bom->funcs->bo_unref(bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int _radeon_bo_map(struct radeon_bo *bo,
|
||||||
|
int write,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
return bo->bom->funcs->bo_map(bo, write);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int _radeon_bo_unmap(struct radeon_bo *bo,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
return bo->bom->funcs->bo_unmap(bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int _radeon_bo_wait(struct radeon_bo *bo,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
return bo->bom->funcs->bo_wait(bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define radeon_bo_open(bom, h, s, a, d, f)\
|
||||||
|
_radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#define radeon_bo_ref(bo)\
|
||||||
|
_radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#define radeon_bo_unref(bo)\
|
||||||
|
_radeon_bo_unref(bo, __FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#define radeon_bo_map(bo, w)\
|
||||||
|
_radeon_bo_map(bo, w, __FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#define radeon_bo_unmap(bo)\
|
||||||
|
_radeon_bo_unmap(bo, __FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#define radeon_bo_debug(bo, opcode)\
|
||||||
|
_radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#define radeon_bo_wait(bo) \
|
||||||
|
_radeon_bo_wait(bo, __FILE__, __func__, __LINE__)
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,254 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Dave Airlie
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Dave Airlie
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "xf86drm.h"
|
||||||
|
#include "drm.h"
|
||||||
|
#include "radeon_drm.h"
|
||||||
|
#include "radeon_bo.h"
|
||||||
|
#include "radeon_bo_gem.h"
|
||||||
|
|
||||||
|
struct radeon_bo_gem {
|
||||||
|
struct radeon_bo base;
|
||||||
|
uint32_t name;
|
||||||
|
int map_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bo_manager_gem {
|
||||||
|
struct radeon_bo_manager base;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
|
||||||
|
uint32_t handle,
|
||||||
|
uint32_t size,
|
||||||
|
uint32_t alignment,
|
||||||
|
uint32_t domains,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
struct radeon_bo_gem *bo;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem));
|
||||||
|
if (bo == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bo->base.bom = bom;
|
||||||
|
bo->base.handle = 0;
|
||||||
|
bo->base.size = size;
|
||||||
|
bo->base.alignment = alignment;
|
||||||
|
bo->base.domains = domains;
|
||||||
|
bo->base.flags = flags;
|
||||||
|
bo->base.ptr = NULL;
|
||||||
|
bo->map_count = 0;
|
||||||
|
if (handle) {
|
||||||
|
struct drm_gem_open open_arg;
|
||||||
|
|
||||||
|
memset(&open_arg, 0, sizeof(open_arg));
|
||||||
|
open_arg.name = handle;
|
||||||
|
r = ioctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
|
||||||
|
if (r != 0) {
|
||||||
|
free(bo);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
bo->base.handle = open_arg.handle;
|
||||||
|
bo->base.size = open_arg.size;
|
||||||
|
bo->name = handle;
|
||||||
|
} else {
|
||||||
|
struct drm_radeon_gem_create args;
|
||||||
|
|
||||||
|
args.size = size;
|
||||||
|
args.alignment = alignment;
|
||||||
|
args.initial_domain = bo->base.domains;
|
||||||
|
args.flags = 0;
|
||||||
|
args.handle = 0;
|
||||||
|
r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE,
|
||||||
|
&args, sizeof(args));
|
||||||
|
bo->base.handle = args.handle;
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "Failed to allocate :\n");
|
||||||
|
fprintf(stderr, " size : %d bytes\n", size);
|
||||||
|
fprintf(stderr, " alignment : %d bytes\n", alignment);
|
||||||
|
fprintf(stderr, " domains : %d\n", bo->base.domains);
|
||||||
|
free(bo);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radeon_bo_ref((struct radeon_bo*)bo);
|
||||||
|
return (struct radeon_bo*)bo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bo_ref(struct radeon_bo *bo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct radeon_bo *bo_unref(struct radeon_bo *bo)
|
||||||
|
{
|
||||||
|
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
|
||||||
|
struct drm_gem_close args;
|
||||||
|
|
||||||
|
if (bo == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (bo->cref) {
|
||||||
|
return bo;
|
||||||
|
}
|
||||||
|
if (bo_gem->map_count) {
|
||||||
|
munmap(bo->ptr, bo->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close object */
|
||||||
|
args.handle = bo->handle;
|
||||||
|
ioctl(bo->bom->fd, DRM_IOCTL_GEM_CLOSE, &args);
|
||||||
|
memset(bo_gem, 0, sizeof(struct radeon_bo_gem));
|
||||||
|
free(bo_gem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bo_map(struct radeon_bo *bo, int write)
|
||||||
|
{
|
||||||
|
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
|
||||||
|
struct drm_radeon_gem_mmap args;
|
||||||
|
int r;
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
if (bo_gem->map_count++ != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bo->ptr = NULL;
|
||||||
|
args.handle = bo->handle;
|
||||||
|
args.offset = 0;
|
||||||
|
args.size = (uint64_t)bo->size;
|
||||||
|
r = drmCommandWriteRead(bo->bom->fd,
|
||||||
|
DRM_RADEON_GEM_MMAP,
|
||||||
|
&args,
|
||||||
|
sizeof(args));
|
||||||
|
if (r) {
|
||||||
|
fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
|
||||||
|
bo, bo->handle, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, bo->bom->fd, args.addr_ptr);
|
||||||
|
if (ptr == MAP_FAILED)
|
||||||
|
return -errno;
|
||||||
|
bo->ptr = ptr;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bo_unmap(struct radeon_bo *bo)
|
||||||
|
{
|
||||||
|
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
|
||||||
|
|
||||||
|
if (--bo_gem->map_count > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
munmap(bo->ptr, bo->size);
|
||||||
|
bo->ptr = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bo_wait(struct radeon_bo *bo)
|
||||||
|
{
|
||||||
|
struct drm_radeon_gem_wait_idle args;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
args.handle = bo->handle;
|
||||||
|
do {
|
||||||
|
ret = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_WAIT_IDLE,
|
||||||
|
&args, sizeof(args));
|
||||||
|
} while (ret == -EBUSY);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct radeon_bo_funcs bo_gem_funcs = {
|
||||||
|
bo_open,
|
||||||
|
bo_ref,
|
||||||
|
bo_unref,
|
||||||
|
bo_map,
|
||||||
|
bo_unmap,
|
||||||
|
bo_wait
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
|
||||||
|
{
|
||||||
|
struct bo_manager_gem *bomg;
|
||||||
|
|
||||||
|
bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem));
|
||||||
|
if (bomg == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
bomg->base.funcs = &bo_gem_funcs;
|
||||||
|
bomg->base.fd = fd;
|
||||||
|
return (struct radeon_bo_manager*)bomg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
|
||||||
|
{
|
||||||
|
struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
|
||||||
|
|
||||||
|
if (bom == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
free(bomg);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t radeon_gem_name_bo(struct radeon_bo *bo)
|
||||||
|
{
|
||||||
|
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
|
||||||
|
return bo_gem->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
|
||||||
|
{
|
||||||
|
struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
|
||||||
|
struct drm_radeon_gem_set_domain args;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
args.handle = bo->handle;
|
||||||
|
args.read_domains = read_domains;
|
||||||
|
args.write_domain = write_domain;
|
||||||
|
|
||||||
|
r = drmCommandWriteRead(bo->bom->fd,
|
||||||
|
DRM_RADEON_GEM_SET_DOMAIN,
|
||||||
|
&args,
|
||||||
|
sizeof(args));
|
||||||
|
return r;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Dave Airlie
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Dave Airlie
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#ifndef RADEON_BO_GEM_H
|
||||||
|
#define RADEON_BO_GEM_H
|
||||||
|
|
||||||
|
#include "radeon_bo.h"
|
||||||
|
|
||||||
|
struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd);
|
||||||
|
void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom);
|
||||||
|
|
||||||
|
uint32_t radeon_gem_name_bo(struct radeon_bo *bo);
|
||||||
|
int radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain);
|
||||||
|
#endif
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Nicolai Haehnle
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Aapo Tahkola <aet@rasterburn.org>
|
||||||
|
* Nicolai Haehnle <prefect_@gmx.net>
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#ifndef RADEON_CS_H
|
||||||
|
#define RADEON_CS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "drm.h"
|
||||||
|
#include "radeon_drm.h"
|
||||||
|
#include "radeon_bo.h"
|
||||||
|
|
||||||
|
struct radeon_cs_reloc {
|
||||||
|
struct radeon_bo *bo;
|
||||||
|
uint32_t read_domain;
|
||||||
|
uint32_t write_domain;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define RADEON_CS_SPACE_OK 0
|
||||||
|
#define RADEON_CS_SPACE_OP_TO_BIG 1
|
||||||
|
#define RADEON_CS_SPACE_FLUSH 2
|
||||||
|
|
||||||
|
struct radeon_cs_space_check {
|
||||||
|
struct radeon_bo *bo;
|
||||||
|
uint32_t read_domains;
|
||||||
|
uint32_t write_domain;
|
||||||
|
uint32_t new_accounted;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radeon_cs_manager;
|
||||||
|
|
||||||
|
struct radeon_cs {
|
||||||
|
struct radeon_cs_manager *csm;
|
||||||
|
void *relocs;
|
||||||
|
uint32_t *packets;
|
||||||
|
unsigned crelocs;
|
||||||
|
unsigned relocs_total_size;
|
||||||
|
unsigned cdw;
|
||||||
|
unsigned ndw;
|
||||||
|
int section;
|
||||||
|
unsigned section_ndw;
|
||||||
|
unsigned section_cdw;
|
||||||
|
const char *section_file;
|
||||||
|
const char *section_func;
|
||||||
|
int section_line;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* cs functions */
|
||||||
|
struct radeon_cs_funcs {
|
||||||
|
struct radeon_cs *(*cs_create)(struct radeon_cs_manager *csm,
|
||||||
|
uint32_t ndw);
|
||||||
|
int (*cs_write_reloc)(struct radeon_cs *cs,
|
||||||
|
struct radeon_bo *bo,
|
||||||
|
uint32_t read_domain,
|
||||||
|
uint32_t write_domain,
|
||||||
|
uint32_t flags);
|
||||||
|
int (*cs_begin)(struct radeon_cs *cs,
|
||||||
|
uint32_t ndw,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line);
|
||||||
|
int (*cs_end)(struct radeon_cs *cs,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line);
|
||||||
|
int (*cs_emit)(struct radeon_cs *cs);
|
||||||
|
int (*cs_destroy)(struct radeon_cs *cs);
|
||||||
|
int (*cs_erase)(struct radeon_cs *cs);
|
||||||
|
int (*cs_need_flush)(struct radeon_cs *cs);
|
||||||
|
void (*cs_print)(struct radeon_cs *cs, FILE *file);
|
||||||
|
int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos,
|
||||||
|
int num_bo);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radeon_cs_manager {
|
||||||
|
struct radeon_cs_funcs *funcs;
|
||||||
|
int fd;
|
||||||
|
uint32_t vram_limit, gart_limit;
|
||||||
|
uint32_t vram_write_used, gart_write_used;
|
||||||
|
uint32_t read_used;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
|
||||||
|
uint32_t ndw)
|
||||||
|
{
|
||||||
|
return csm->funcs->cs_create(csm, ndw);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_write_reloc(struct radeon_cs *cs,
|
||||||
|
struct radeon_bo *bo,
|
||||||
|
uint32_t read_domain,
|
||||||
|
uint32_t write_domain,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_write_reloc(cs,
|
||||||
|
bo,
|
||||||
|
read_domain,
|
||||||
|
write_domain,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_begin(struct radeon_cs *cs,
|
||||||
|
uint32_t ndw,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_begin(cs, ndw, file, func, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_end(struct radeon_cs *cs,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_end(cs, file, func, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_emit(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_emit(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_destroy(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_destroy(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_erase(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_erase(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_need_flush(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_need_flush(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file)
|
||||||
|
{
|
||||||
|
cs->csm->funcs->cs_print(cs, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int radeon_cs_space_check(struct radeon_cs *cs,
|
||||||
|
struct radeon_cs_space_check *bos,
|
||||||
|
int num_bo)
|
||||||
|
{
|
||||||
|
return cs->csm->funcs->cs_space_check(cs, bos, num_bo);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (domain == RADEON_GEM_DOMAIN_VRAM)
|
||||||
|
cs->csm->vram_limit = limit;
|
||||||
|
else
|
||||||
|
cs->csm->gart_limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
|
||||||
|
{
|
||||||
|
cs->packets[cs->cdw++] = dword;
|
||||||
|
if (cs->section) {
|
||||||
|
cs->section_cdw++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
|
||||||
|
{
|
||||||
|
memcpy(cs->packets + cs->cdw, &qword, sizeof(uint64_t));
|
||||||
|
cs->cdw += 2;
|
||||||
|
if (cs->section) {
|
||||||
|
cs->section_cdw += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,544 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Aapo Tahkola <aet@rasterburn.org>
|
||||||
|
* Nicolai Haehnle <prefect_@gmx.net>
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include "radeon_cs.h"
|
||||||
|
#include "radeon_cs_gem.h"
|
||||||
|
#include "radeon_bo_gem.h"
|
||||||
|
#include "drm.h"
|
||||||
|
#include "xf86drm.h"
|
||||||
|
#include "radeon_drm.h"
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
struct cs_reloc_gem {
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t read_domain;
|
||||||
|
uint32_t write_domain;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack()
|
||||||
|
#define RELOC_SIZE (sizeof(struct cs_reloc_gem) / sizeof(uint32_t))
|
||||||
|
|
||||||
|
struct cs_gem {
|
||||||
|
struct radeon_cs base;
|
||||||
|
struct drm_radeon_cs cs;
|
||||||
|
struct drm_radeon_cs_chunk chunks[2];
|
||||||
|
unsigned nrelocs;
|
||||||
|
uint32_t *relocs;
|
||||||
|
struct radeon_bo **relocs_bo;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radeon_cs *cs_gem_create(struct radeon_cs_manager *csm,
|
||||||
|
uint32_t ndw)
|
||||||
|
{
|
||||||
|
struct cs_gem *csg;
|
||||||
|
|
||||||
|
/* max cmd buffer size is 64Kb */
|
||||||
|
if (ndw > (64 * 1024 / 4)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
csg = (struct cs_gem*)calloc(1, sizeof(struct cs_gem));
|
||||||
|
if (csg == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
csg->base.csm = csm;
|
||||||
|
csg->base.ndw = 64 * 1024 / 4;
|
||||||
|
csg->base.packets = (uint32_t*)calloc(1, 64 * 1024);
|
||||||
|
if (csg->base.packets == NULL) {
|
||||||
|
free(csg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
csg->base.relocs_total_size = 0;
|
||||||
|
csg->base.crelocs = 0;
|
||||||
|
csg->nrelocs = 4096 / (4 * 4) ;
|
||||||
|
csg->relocs_bo = (struct radeon_bo**)calloc(1,
|
||||||
|
csg->nrelocs*sizeof(void*));
|
||||||
|
if (csg->relocs_bo == NULL) {
|
||||||
|
free(csg->base.packets);
|
||||||
|
free(csg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
csg->base.relocs = csg->relocs = (uint32_t*)calloc(1, 4096);
|
||||||
|
if (csg->relocs == NULL) {
|
||||||
|
free(csg->relocs_bo);
|
||||||
|
free(csg->base.packets);
|
||||||
|
free(csg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
csg->chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
|
||||||
|
csg->chunks[0].length_dw = 0;
|
||||||
|
csg->chunks[0].chunk_data = (uint64_t)(intptr_t)csg->base.packets;
|
||||||
|
csg->chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
|
||||||
|
csg->chunks[1].length_dw = 0;
|
||||||
|
csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs;
|
||||||
|
return (struct radeon_cs*)csg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_write_reloc(struct radeon_cs *cs,
|
||||||
|
struct radeon_bo *bo,
|
||||||
|
uint32_t read_domain,
|
||||||
|
uint32_t write_domain,
|
||||||
|
uint32_t flags)
|
||||||
|
{
|
||||||
|
struct cs_gem *csg = (struct cs_gem*)cs;
|
||||||
|
struct cs_reloc_gem *reloc;
|
||||||
|
uint32_t idx;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
assert(bo->space_accounted);
|
||||||
|
|
||||||
|
/* check domains */
|
||||||
|
if ((read_domain && write_domain) || (!read_domain && !write_domain)) {
|
||||||
|
/* in one CS a bo can only be in read or write domain but not
|
||||||
|
* in read & write domain at the same sime
|
||||||
|
*/
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (read_domain == RADEON_GEM_DOMAIN_CPU) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (write_domain == RADEON_GEM_DOMAIN_CPU) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
/* check if bo is already referenced */
|
||||||
|
for(i = 0; i < cs->crelocs; i++) {
|
||||||
|
idx = i * RELOC_SIZE;
|
||||||
|
reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
|
||||||
|
if (reloc->handle == bo->handle) {
|
||||||
|
/* Check domains must be in read or write. As we check already
|
||||||
|
* checked that in argument one of the read or write domain was
|
||||||
|
* set we only need to check that if previous reloc as the read
|
||||||
|
* domain set then the read_domain should also be set for this
|
||||||
|
* new relocation.
|
||||||
|
*/
|
||||||
|
if (reloc->read_domain && !read_domain) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (reloc->write_domain && !write_domain) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
reloc->read_domain |= read_domain;
|
||||||
|
reloc->write_domain |= write_domain;
|
||||||
|
/* update flags */
|
||||||
|
reloc->flags |= (flags & reloc->flags);
|
||||||
|
/* write relocation packet */
|
||||||
|
radeon_cs_write_dword(cs, 0xc0001000);
|
||||||
|
radeon_cs_write_dword(cs, idx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* new relocation */
|
||||||
|
if (csg->base.crelocs >= csg->nrelocs) {
|
||||||
|
/* allocate more memory (TODO: should use a slab allocatore maybe) */
|
||||||
|
uint32_t *tmp, size;
|
||||||
|
size = ((csg->nrelocs + 1) * sizeof(struct radeon_bo*));
|
||||||
|
tmp = (uint32_t*)realloc(csg->relocs_bo, size);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
csg->relocs_bo = (struct radeon_bo**)tmp;
|
||||||
|
size = ((csg->nrelocs + 1) * RELOC_SIZE * 4);
|
||||||
|
tmp = (uint32_t*)realloc(csg->relocs, size);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
cs->relocs = csg->relocs = tmp;
|
||||||
|
csg->nrelocs += 1;
|
||||||
|
csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs;
|
||||||
|
}
|
||||||
|
csg->relocs_bo[csg->base.crelocs] = bo;
|
||||||
|
idx = (csg->base.crelocs++) * RELOC_SIZE;
|
||||||
|
reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
|
||||||
|
reloc->handle = bo->handle;
|
||||||
|
reloc->read_domain = read_domain;
|
||||||
|
reloc->write_domain = write_domain;
|
||||||
|
reloc->flags = flags;
|
||||||
|
csg->chunks[1].length_dw += RELOC_SIZE;
|
||||||
|
radeon_bo_ref(bo);
|
||||||
|
cs->relocs_total_size += bo->size;
|
||||||
|
radeon_cs_write_dword(cs, 0xc0001000);
|
||||||
|
radeon_cs_write_dword(cs, idx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_begin(struct radeon_cs *cs,
|
||||||
|
uint32_t ndw,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (cs->section) {
|
||||||
|
fprintf(stderr, "CS already in a section(%s,%s,%d)\n",
|
||||||
|
cs->section_file, cs->section_func, cs->section_line);
|
||||||
|
fprintf(stderr, "CS can't start section(%s,%s,%d)\n",
|
||||||
|
file, func, line);
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
cs->section = 1;
|
||||||
|
cs->section_ndw = ndw;
|
||||||
|
cs->section_cdw = 0;
|
||||||
|
cs->section_file = file;
|
||||||
|
cs->section_func = func;
|
||||||
|
cs->section_line = line;
|
||||||
|
|
||||||
|
|
||||||
|
if (cs->cdw + ndw > cs->ndw) {
|
||||||
|
uint32_t tmp, *ptr;
|
||||||
|
int num = (ndw > 0x3FF) ? ndw : 0x3FF;
|
||||||
|
|
||||||
|
tmp = (cs->cdw + 1 + num) & (~num);
|
||||||
|
ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
|
||||||
|
if (ptr == NULL) {
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
cs->packets = ptr;
|
||||||
|
cs->ndw = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_end(struct radeon_cs *cs,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
int line)
|
||||||
|
|
||||||
|
{
|
||||||
|
if (!cs->section) {
|
||||||
|
fprintf(stderr, "CS no section to end at (%s,%s,%d)\n",
|
||||||
|
file, func, line);
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
cs->section = 0;
|
||||||
|
if (cs->section_ndw != cs->section_cdw) {
|
||||||
|
fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
|
||||||
|
cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
|
||||||
|
fprintf(stderr, "CS section end at (%s,%s,%d)\n",
|
||||||
|
file, func, line);
|
||||||
|
return -EPIPE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_emit(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
struct cs_gem *csg = (struct cs_gem*)cs;
|
||||||
|
uint64_t chunk_array[2];
|
||||||
|
unsigned i;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
csg->chunks[0].length_dw = cs->cdw;
|
||||||
|
|
||||||
|
chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0];
|
||||||
|
chunk_array[1] = (uint64_t)(intptr_t)&csg->chunks[1];
|
||||||
|
|
||||||
|
csg->cs.num_chunks = 2;
|
||||||
|
csg->cs.chunks = (uint64_t)(intptr_t)chunk_array;
|
||||||
|
|
||||||
|
r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_CS,
|
||||||
|
&csg->cs, sizeof(struct drm_radeon_cs));
|
||||||
|
for (i = 0; i < csg->base.crelocs; i++) {
|
||||||
|
csg->relocs_bo[i]->space_accounted = 0;
|
||||||
|
radeon_bo_unref(csg->relocs_bo[i]);
|
||||||
|
csg->relocs_bo[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cs->csm->read_used = 0;
|
||||||
|
cs->csm->vram_write_used = 0;
|
||||||
|
cs->csm->gart_write_used = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_destroy(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
struct cs_gem *csg = (struct cs_gem*)cs;
|
||||||
|
|
||||||
|
free(csg->relocs_bo);
|
||||||
|
free(cs->relocs);
|
||||||
|
free(cs->packets);
|
||||||
|
free(cs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_erase(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
struct cs_gem *csg = (struct cs_gem*)cs;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
if (csg->relocs_bo) {
|
||||||
|
for (i = 0; i < csg->base.crelocs; i++) {
|
||||||
|
if (csg->relocs_bo[i]) {
|
||||||
|
radeon_bo_unref(csg->relocs_bo[i]);
|
||||||
|
csg->relocs_bo[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cs->relocs_total_size = 0;
|
||||||
|
cs->cdw = 0;
|
||||||
|
cs->section = 0;
|
||||||
|
cs->crelocs = 0;
|
||||||
|
csg->chunks[0].length_dw = 0;
|
||||||
|
csg->chunks[1].length_dw = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_need_flush(struct radeon_cs *cs)
|
||||||
|
{
|
||||||
|
return 0; //(cs->relocs_total_size > (32*1024*1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PACKET_TYPE0 0
|
||||||
|
#define PACKET_TYPE1 1
|
||||||
|
#define PACKET_TYPE2 2
|
||||||
|
#define PACKET_TYPE3 3
|
||||||
|
|
||||||
|
#define PACKET3_NOP 0x10
|
||||||
|
#define PACKET3_SET_SCISSORS 0x1E
|
||||||
|
#define PACKET3_3D_DRAW_VBUF 0x28
|
||||||
|
#define PACKET3_3D_DRAW_IMMD 0x29
|
||||||
|
#define PACKET3_3D_DRAW_INDX 0x2A
|
||||||
|
#define PACKET3_3D_LOAD_VBPNTR 0x2F
|
||||||
|
#define PACKET3_INDX_BUFFER 0x33
|
||||||
|
#define PACKET3_3D_DRAW_VBUF_2 0x34
|
||||||
|
#define PACKET3_3D_DRAW_IMMD_2 0x35
|
||||||
|
#define PACKET3_3D_DRAW_INDX_2 0x36
|
||||||
|
|
||||||
|
#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
|
||||||
|
#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
|
||||||
|
#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
|
||||||
|
#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
|
||||||
|
#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
|
||||||
|
|
||||||
|
static void cs_gem_print(struct radeon_cs *cs, FILE *file)
|
||||||
|
{
|
||||||
|
unsigned opcode;
|
||||||
|
unsigned reg;
|
||||||
|
unsigned cnt;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < cs->cdw;) {
|
||||||
|
cnt = CP_PACKET_GET_COUNT(cs->packets[i]);
|
||||||
|
switch (CP_PACKET_GET_TYPE(cs->packets[i])) {
|
||||||
|
case PACKET_TYPE0:
|
||||||
|
fprintf(file, "Pkt0 at %d (%d dwords):\n", i, cnt + 1);
|
||||||
|
reg = CP_PACKET0_GET_REG(cs->packets[i]);
|
||||||
|
if (CP_PACKET0_GET_ONE_REG_WR(cs->packets[i++])) {
|
||||||
|
for (j = 0; j <= cnt; j++) {
|
||||||
|
fprintf(file, " 0x%08X -> 0x%04X\n",
|
||||||
|
cs->packets[i++], reg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (j = 0; j <= cnt; j++) {
|
||||||
|
fprintf(file, " 0x%08X -> 0x%04X\n",
|
||||||
|
cs->packets[i++], reg);
|
||||||
|
reg += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PACKET_TYPE3:
|
||||||
|
fprintf(file, "Pkt3 at %d :\n", i);
|
||||||
|
opcode = CP_PACKET3_GET_OPCODE(cs->packets[i++]);
|
||||||
|
switch (opcode) {
|
||||||
|
case PACKET3_NOP:
|
||||||
|
fprintf(file, " PACKET3_NOP:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_3D_DRAW_VBUF:
|
||||||
|
fprintf(file, " PACKET3_3D_DRAW_VBUF:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_3D_DRAW_IMMD:
|
||||||
|
fprintf(file, " PACKET3_3D_DRAW_IMMD:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_3D_DRAW_INDX:
|
||||||
|
fprintf(file, " PACKET3_3D_DRAW_INDX:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_3D_LOAD_VBPNTR:
|
||||||
|
fprintf(file, " PACKET3_3D_LOAD_VBPNTR:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_INDX_BUFFER:
|
||||||
|
fprintf(file, " PACKET3_INDX_BUFFER:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_3D_DRAW_VBUF_2:
|
||||||
|
fprintf(file, " PACKET3_3D_DRAW_VBUF_2:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_3D_DRAW_IMMD_2:
|
||||||
|
fprintf(file, " PACKET3_3D_DRAW_IMMD_2:\n");
|
||||||
|
break;
|
||||||
|
case PACKET3_3D_DRAW_INDX_2:
|
||||||
|
fprintf(file, " PACKET3_3D_DRAW_INDX_2:\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(file, "Unknow opcode 0x%02X at %d\n", opcode, i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (j = 0; j <= cnt; j++) {
|
||||||
|
fprintf(file, " 0x%08X\n", cs->packets[i++]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PACKET_TYPE1:
|
||||||
|
case PACKET_TYPE2:
|
||||||
|
default:
|
||||||
|
fprintf(file, "Unknow packet 0x%08X at %d\n", cs->packets[i], i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cs_gem_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo)
|
||||||
|
{
|
||||||
|
struct radeon_cs_manager *csm = cs->csm;
|
||||||
|
int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0;
|
||||||
|
uint32_t read_domains, write_domain;
|
||||||
|
int i;
|
||||||
|
struct radeon_bo *bo;
|
||||||
|
|
||||||
|
/* check the totals for this operation */
|
||||||
|
|
||||||
|
if (num_bo == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* prepare */
|
||||||
|
for (i = 0; i < num_bo; i++) {
|
||||||
|
bo = bos[i].bo;
|
||||||
|
|
||||||
|
bos[i].new_accounted = 0;
|
||||||
|
read_domains = bos[i].read_domains;
|
||||||
|
write_domain = bos[i].write_domain;
|
||||||
|
|
||||||
|
/* already accounted this bo */
|
||||||
|
if (write_domain && (write_domain == bo->space_accounted)) {
|
||||||
|
bos[i].new_accounted = bo->space_accounted;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (read_domains && ((read_domains << 16) == bo->space_accounted)) {
|
||||||
|
bos[i].new_accounted = bo->space_accounted;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bo->space_accounted == 0) {
|
||||||
|
if (write_domain == RADEON_GEM_DOMAIN_VRAM)
|
||||||
|
this_op_vram_write += bo->size;
|
||||||
|
else if (write_domain == RADEON_GEM_DOMAIN_GTT)
|
||||||
|
this_op_gart_write += bo->size;
|
||||||
|
else
|
||||||
|
this_op_read += bo->size;
|
||||||
|
bos[i].new_accounted = (read_domains << 16) | write_domain;
|
||||||
|
} else {
|
||||||
|
uint16_t old_read, old_write;
|
||||||
|
|
||||||
|
old_read = bo->space_accounted >> 16;
|
||||||
|
old_write = bo->space_accounted & 0xffff;
|
||||||
|
|
||||||
|
if (write_domain && (old_read & write_domain)) {
|
||||||
|
bos[i].new_accounted = write_domain;
|
||||||
|
/* moving from read to a write domain */
|
||||||
|
if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
|
||||||
|
this_op_read -= bo->size;
|
||||||
|
this_op_vram_write += bo->size;
|
||||||
|
} else if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
|
||||||
|
this_op_read -= bo->size;
|
||||||
|
this_op_gart_write += bo->size;
|
||||||
|
}
|
||||||
|
} else if (read_domains & old_write) {
|
||||||
|
bos[i].new_accounted = bo->space_accounted & 0xffff;
|
||||||
|
} else {
|
||||||
|
/* rewrite the domains */
|
||||||
|
if (write_domain != old_write)
|
||||||
|
fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
|
||||||
|
if (read_domains != old_read)
|
||||||
|
fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
|
||||||
|
return RADEON_CS_SPACE_FLUSH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this_op_read < 0)
|
||||||
|
this_op_read = 0;
|
||||||
|
|
||||||
|
/* check sizes - operation first */
|
||||||
|
if ((this_op_read + this_op_gart_write > csm->gart_limit) ||
|
||||||
|
(this_op_vram_write > csm->vram_limit)) {
|
||||||
|
return RADEON_CS_SPACE_OP_TO_BIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) ||
|
||||||
|
((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) {
|
||||||
|
return RADEON_CS_SPACE_FLUSH;
|
||||||
|
}
|
||||||
|
|
||||||
|
csm->gart_write_used += this_op_gart_write;
|
||||||
|
csm->vram_write_used += this_op_vram_write;
|
||||||
|
csm->read_used += this_op_read;
|
||||||
|
/* commit */
|
||||||
|
for (i = 0; i < num_bo; i++) {
|
||||||
|
bo = bos[i].bo;
|
||||||
|
bo->space_accounted = bos[i].new_accounted;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RADEON_CS_SPACE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct radeon_cs_funcs radeon_cs_gem_funcs = {
|
||||||
|
cs_gem_create,
|
||||||
|
cs_gem_write_reloc,
|
||||||
|
cs_gem_begin,
|
||||||
|
cs_gem_end,
|
||||||
|
cs_gem_emit,
|
||||||
|
cs_gem_destroy,
|
||||||
|
cs_gem_erase,
|
||||||
|
cs_gem_need_flush,
|
||||||
|
cs_gem_print,
|
||||||
|
cs_gem_check_space,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
|
||||||
|
{
|
||||||
|
struct radeon_cs_manager *csm;
|
||||||
|
|
||||||
|
csm = (struct radeon_cs_manager*)calloc(1,
|
||||||
|
sizeof(struct radeon_cs_manager));
|
||||||
|
if (csm == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
csm->funcs = &radeon_cs_gem_funcs;
|
||||||
|
csm->fd = fd;
|
||||||
|
return csm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
|
||||||
|
{
|
||||||
|
free(csm);
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Nicolai Haehnle
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Aapo Tahkola <aet@rasterburn.org>
|
||||||
|
* Nicolai Haehnle <prefect_@gmx.net>
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#ifndef RADEON_CS_GEM_H
|
||||||
|
#define RADEON_CS_GEM_H
|
||||||
|
|
||||||
|
#include "radeon_cs.h"
|
||||||
|
|
||||||
|
struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd);
|
||||||
|
void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "radeon_track.h"
|
||||||
|
|
||||||
|
void radeon_track_add_event(struct radeon_track *track,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
const char *op,
|
||||||
|
unsigned line)
|
||||||
|
{
|
||||||
|
struct radeon_track_event *event;
|
||||||
|
|
||||||
|
if (track == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event = (void*)calloc(1,sizeof(struct radeon_track_event));
|
||||||
|
if (event == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event->line = line;
|
||||||
|
event->file = strdup(file);
|
||||||
|
event->func = strdup(func);
|
||||||
|
event->op = strdup(op);
|
||||||
|
if (event->file == NULL || event->func == NULL || event->op == NULL) {
|
||||||
|
free(event->file);
|
||||||
|
free(event->func);
|
||||||
|
free(event->op);
|
||||||
|
free(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event->next = track->events;
|
||||||
|
track->events = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct radeon_track *radeon_tracker_add_track(struct radeon_tracker *tracker,
|
||||||
|
unsigned key)
|
||||||
|
{
|
||||||
|
struct radeon_track *track;
|
||||||
|
|
||||||
|
track = (struct radeon_track*)calloc(1, sizeof(struct radeon_track));
|
||||||
|
if (track) {
|
||||||
|
track->next = tracker->tracks.next;
|
||||||
|
track->prev = &tracker->tracks;
|
||||||
|
tracker->tracks.next = track;
|
||||||
|
if (track->next) {
|
||||||
|
track->next->prev = track;
|
||||||
|
}
|
||||||
|
track->key = key;
|
||||||
|
track->events = NULL;
|
||||||
|
}
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
void radeon_tracker_remove_track(struct radeon_tracker *tracker,
|
||||||
|
struct radeon_track *track)
|
||||||
|
{
|
||||||
|
struct radeon_track_event *event;
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
if (track == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
track->prev->next = track->next;
|
||||||
|
if (track->next) {
|
||||||
|
track->next->prev = track->prev;
|
||||||
|
}
|
||||||
|
track->next = track->prev = NULL;
|
||||||
|
event = track->events;
|
||||||
|
while (event) {
|
||||||
|
tmp = event;
|
||||||
|
free(event->file);
|
||||||
|
free(event->func);
|
||||||
|
free(event->op);
|
||||||
|
event = event->next;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
track->events = NULL;
|
||||||
|
free(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
void radeon_tracker_print(struct radeon_tracker *tracker, FILE *file)
|
||||||
|
{
|
||||||
|
struct radeon_track *track;
|
||||||
|
struct radeon_track_event *event;
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
track = tracker->tracks.next;
|
||||||
|
while (track) {
|
||||||
|
event = track->events;
|
||||||
|
fprintf(file, "[0x%08X] :\n", track->key);
|
||||||
|
while (event) {
|
||||||
|
tmp = event;
|
||||||
|
fprintf(file, " [0x%08X:%s](%s:%s:%d)\n",
|
||||||
|
track->key, event->op, event->file,
|
||||||
|
event->func, event->line);
|
||||||
|
free(event->file);
|
||||||
|
free(event->func);
|
||||||
|
free(event->op);
|
||||||
|
event->file = NULL;
|
||||||
|
event->func = NULL;
|
||||||
|
event->op = NULL;
|
||||||
|
event = event->next;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
track->events = NULL;
|
||||||
|
tmp = track;
|
||||||
|
track = track->next;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2008 Jérôme Glisse
|
||||||
|
* 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:
|
||||||
|
* Jérôme Glisse <glisse@freedesktop.org>
|
||||||
|
*/
|
||||||
|
#ifndef RADEON_TRACK_H
|
||||||
|
#define RADEON_TRACK_H
|
||||||
|
|
||||||
|
struct radeon_track_event {
|
||||||
|
struct radeon_track_event *next;
|
||||||
|
char *file;
|
||||||
|
char *func;
|
||||||
|
char *op;
|
||||||
|
unsigned line;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radeon_track {
|
||||||
|
struct radeon_track *next;
|
||||||
|
struct radeon_track *prev;
|
||||||
|
unsigned key;
|
||||||
|
struct radeon_track_event *events;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radeon_tracker {
|
||||||
|
struct radeon_track tracks;
|
||||||
|
};
|
||||||
|
|
||||||
|
void radeon_track_add_event(struct radeon_track *track,
|
||||||
|
const char *file,
|
||||||
|
const char *func,
|
||||||
|
const char *op,
|
||||||
|
unsigned line);
|
||||||
|
struct radeon_track *radeon_tracker_add_track(struct radeon_tracker *tracker,
|
||||||
|
unsigned key);
|
||||||
|
void radeon_tracker_remove_track(struct radeon_tracker *tracker,
|
||||||
|
struct radeon_track *track);
|
||||||
|
void radeon_tracker_print(struct radeon_tracker *tracker,
|
||||||
|
FILE *file);
|
||||||
|
|
||||||
|
#endif
|
|
@ -492,6 +492,16 @@ typedef struct {
|
||||||
#define DRM_RADEON_SETPARAM 0x19
|
#define DRM_RADEON_SETPARAM 0x19
|
||||||
#define DRM_RADEON_SURF_ALLOC 0x1a
|
#define DRM_RADEON_SURF_ALLOC 0x1a
|
||||||
#define DRM_RADEON_SURF_FREE 0x1b
|
#define DRM_RADEON_SURF_FREE 0x1b
|
||||||
|
/* KMS ioctl */
|
||||||
|
#define DRM_RADEON_GEM_INFO 0x1c
|
||||||
|
#define DRM_RADEON_GEM_CREATE 0x1d
|
||||||
|
#define DRM_RADEON_GEM_MMAP 0x1e
|
||||||
|
#define DRM_RADEON_GEM_PREAD 0x21
|
||||||
|
#define DRM_RADEON_GEM_PWRITE 0x22
|
||||||
|
#define DRM_RADEON_GEM_SET_DOMAIN 0x23
|
||||||
|
#define DRM_RADEON_GEM_WAIT_IDLE 0x24
|
||||||
|
#define DRM_RADEON_CS 0x26
|
||||||
|
#define DRM_RADEON_INFO 0x27
|
||||||
|
|
||||||
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
|
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
|
||||||
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
|
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
|
||||||
|
@ -521,6 +531,17 @@ typedef struct {
|
||||||
#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
|
#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
|
||||||
#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
|
#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PIN, struct drm_radeon_gem_pin)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_UNPIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_UNPIN, struct drm_radeon_gem_unpin)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
|
||||||
|
#define DRM_IOCTL_RADEON_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_RENDERING, struct drm_radeon_gem_wait_rendering)
|
||||||
|
#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
|
||||||
|
|
||||||
typedef struct drm_radeon_init {
|
typedef struct drm_radeon_init {
|
||||||
enum {
|
enum {
|
||||||
RADEON_INIT_CP = 0x01,
|
RADEON_INIT_CP = 0x01,
|
||||||
|
@ -677,6 +698,7 @@ typedef struct drm_radeon_indirect {
|
||||||
#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
|
#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
|
||||||
#define RADEON_PARAM_FB_LOCATION 14 /* FB location */
|
#define RADEON_PARAM_FB_LOCATION 14 /* FB location */
|
||||||
#define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */
|
#define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */
|
||||||
|
#define RADEON_PARAM_DEVICE_ID 16
|
||||||
|
|
||||||
typedef struct drm_radeon_getparam {
|
typedef struct drm_radeon_getparam {
|
||||||
int param;
|
int param;
|
||||||
|
@ -728,7 +750,6 @@ typedef struct drm_radeon_setparam {
|
||||||
#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
|
#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
|
||||||
#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
|
#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
|
||||||
#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
|
#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
|
||||||
|
|
||||||
#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
|
#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
|
||||||
#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */
|
#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */
|
||||||
#define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */
|
#define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */
|
||||||
|
@ -747,4 +768,112 @@ typedef struct drm_radeon_surface_free {
|
||||||
#define DRM_RADEON_VBLANK_CRTC1 1
|
#define DRM_RADEON_VBLANK_CRTC1 1
|
||||||
#define DRM_RADEON_VBLANK_CRTC2 2
|
#define DRM_RADEON_VBLANK_CRTC2 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kernel modesetting world below.
|
||||||
|
*/
|
||||||
|
#define RADEON_GEM_DOMAIN_CPU 0x1
|
||||||
|
#define RADEON_GEM_DOMAIN_GTT 0x2
|
||||||
|
#define RADEON_GEM_DOMAIN_VRAM 0x4
|
||||||
|
|
||||||
|
struct drm_radeon_gem_info {
|
||||||
|
uint64_t gart_size;
|
||||||
|
uint64_t vram_size;
|
||||||
|
uint64_t vram_visible;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RADEON_GEM_NO_BACKING_STORE 1
|
||||||
|
|
||||||
|
struct drm_radeon_gem_create {
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t alignment;
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t initial_domain;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_gem_mmap {
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t pad;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t addr_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_gem_set_domain {
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t read_domains;
|
||||||
|
uint32_t write_domain;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_gem_wait_idle {
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_gem_busy {
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t busy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_gem_pread {
|
||||||
|
/** Handle for the object being read. */
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t pad;
|
||||||
|
/** Offset into the object to read from */
|
||||||
|
uint64_t offset;
|
||||||
|
/** Length of data to read */
|
||||||
|
uint64_t size;
|
||||||
|
/** Pointer to write the data into. */
|
||||||
|
/* void *, but pointers are not 32/64 compatible */
|
||||||
|
uint64_t data_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_gem_pwrite {
|
||||||
|
/** Handle for the object being written to. */
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t pad;
|
||||||
|
/** Offset into the object to write to */
|
||||||
|
uint64_t offset;
|
||||||
|
/** Length of data to write */
|
||||||
|
uint64_t size;
|
||||||
|
/** Pointer to read the data from. */
|
||||||
|
/* void *, but pointers are not 32/64 compatible */
|
||||||
|
uint64_t data_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RADEON_CHUNK_ID_RELOCS 0x01
|
||||||
|
#define RADEON_CHUNK_ID_IB 0x02
|
||||||
|
|
||||||
|
struct drm_radeon_cs_chunk {
|
||||||
|
uint32_t chunk_id;
|
||||||
|
uint32_t length_dw;
|
||||||
|
uint64_t chunk_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_cs_reloc {
|
||||||
|
uint32_t handle;
|
||||||
|
uint32_t read_domains;
|
||||||
|
uint32_t write_domain;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_radeon_cs {
|
||||||
|
uint32_t num_chunks;
|
||||||
|
uint32_t cs_id;
|
||||||
|
/* this points to uint64_t * which point to cs chunks */
|
||||||
|
uint64_t chunks;
|
||||||
|
/* updates to the limits after this CS ioctl */
|
||||||
|
uint64_t gart_limit;
|
||||||
|
uint64_t vram_limit;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RADEON_INFO_DEVICE_ID 0x00
|
||||||
|
#define RADEON_INFO_NUM_GB_PIPES 0x01
|
||||||
|
|
||||||
|
struct drm_radeon_info {
|
||||||
|
uint32_t request;
|
||||||
|
uint32_t pad;
|
||||||
|
uint64_t value;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue