332 lines
10 KiB
C
332 lines
10 KiB
C
/*
|
|
* Copyright © 2017 Intel Corporation
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef CROCUS_BUFMGR_H
|
|
#define CROCUS_BUFMGR_H
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include "util/macros.h"
|
|
#include "util/u_atomic.h"
|
|
#include "util/list.h"
|
|
#include "pipe/p_defines.h"
|
|
|
|
struct crocus_batch;
|
|
struct intel_device_info;
|
|
struct pipe_debug_callback;
|
|
|
|
#define CROCUS_BINDER_SIZE (64 * 1024)
|
|
#define CROCUS_MAX_BINDERS 100
|
|
|
|
struct crocus_bo {
|
|
/**
|
|
* Size in bytes of the buffer object.
|
|
*
|
|
* The size may be larger than the size originally requested for the
|
|
* allocation, such as being aligned to page size.
|
|
*/
|
|
uint64_t size;
|
|
|
|
/** Buffer manager context associated with this buffer object */
|
|
struct crocus_bufmgr *bufmgr;
|
|
|
|
/** The GEM handle for this buffer object. */
|
|
uint32_t gem_handle;
|
|
|
|
/**
|
|
* Virtual address of the buffer inside the PPGTT (Per-Process Graphics
|
|
* Translation Table).
|
|
*
|
|
* Although each hardware context has its own VMA, we assign BO's to the
|
|
* same address in all contexts, for simplicity.
|
|
*/
|
|
uint64_t gtt_offset;
|
|
|
|
/**
|
|
* The validation list index for this buffer, or -1 when not in a batch.
|
|
* Note that a single buffer may be in multiple batches (contexts), and
|
|
* this is a global field, which refers to the last batch using the BO.
|
|
* It should not be considered authoritative, but can be used to avoid a
|
|
* linear walk of the validation list in the common case by guessing that
|
|
* exec_bos[bo->index] == bo and confirming whether that's the case.
|
|
*
|
|
* XXX: this is not ideal now that we have more than one batch per context,
|
|
* XXX: as the index will flop back and forth between the render index and
|
|
* XXX: compute index...
|
|
*/
|
|
unsigned index;
|
|
|
|
/**
|
|
* Boolean of whether the GPU is definitely not accessing the buffer.
|
|
*
|
|
* This is only valid when reusable, since non-reusable
|
|
* buffers are those that have been shared with other
|
|
* processes, so we don't know their state.
|
|
*/
|
|
bool idle;
|
|
|
|
int refcount;
|
|
const char *name;
|
|
|
|
uint64_t kflags;
|
|
|
|
/**
|
|
* Kenel-assigned global name for this object
|
|
*
|
|
* List contains both flink named and prime fd'd objects
|
|
*/
|
|
unsigned global_name;
|
|
|
|
/**
|
|
* Current tiling mode
|
|
*/
|
|
uint32_t tiling_mode;
|
|
uint32_t swizzle_mode;
|
|
uint32_t stride;
|
|
|
|
time_t free_time;
|
|
|
|
/** Mapped address for the buffer, saved across map/unmap cycles */
|
|
void *map_cpu;
|
|
/** GTT virtual address for the buffer, saved across map/unmap cycles */
|
|
void *map_gtt;
|
|
/** WC CPU address for the buffer, saved across map/unmap cycles */
|
|
void *map_wc;
|
|
|
|
/** BO cache list */
|
|
struct list_head head;
|
|
|
|
/** List of GEM handle exports of this buffer (bo_export) */
|
|
struct list_head exports;
|
|
|
|
/**
|
|
* Boolean of whether this buffer can be re-used
|
|
*/
|
|
bool reusable;
|
|
|
|
/**
|
|
* Boolean of whether this buffer has been shared with an external client.
|
|
*/
|
|
bool external;
|
|
|
|
/**
|
|
* Boolean of whether this buffer is cache coherent
|
|
*/
|
|
bool cache_coherent;
|
|
|
|
/**
|
|
* Boolean of whether this buffer points into user memory
|
|
*/
|
|
bool userptr;
|
|
|
|
/** Pre-computed hash using _mesa_hash_pointer for cache tracking sets */
|
|
uint32_t hash;
|
|
};
|
|
|
|
#define BO_ALLOC_ZEROED (1 << 0)
|
|
#define BO_ALLOC_COHERENT (1 << 1)
|
|
|
|
/**
|
|
* Allocate a buffer object.
|
|
*
|
|
* Buffer objects are not necessarily initially mapped into CPU virtual
|
|
* address space or graphics device aperture. They must be mapped
|
|
* using crocus_bo_map() to be used by the CPU.
|
|
*/
|
|
struct crocus_bo *crocus_bo_alloc(struct crocus_bufmgr *bufmgr,
|
|
const char *name, uint64_t size);
|
|
|
|
/**
|
|
* Allocate a tiled buffer object.
|
|
*
|
|
* Alignment for tiled objects is set automatically; the 'flags'
|
|
* argument provides a hint about how the object will be used initially.
|
|
*
|
|
* Valid tiling formats are:
|
|
* I915_TILING_NONE
|
|
* I915_TILING_X
|
|
* I915_TILING_Y
|
|
*/
|
|
struct crocus_bo *crocus_bo_alloc_tiled(struct crocus_bufmgr *bufmgr,
|
|
const char *name, uint64_t size,
|
|
uint32_t alignment,
|
|
uint32_t tiling_mode, uint32_t pitch,
|
|
unsigned flags);
|
|
|
|
struct crocus_bo *crocus_bo_create_userptr(struct crocus_bufmgr *bufmgr,
|
|
const char *name, void *ptr,
|
|
size_t size);
|
|
|
|
/** Takes a reference on a buffer object */
|
|
static inline void
|
|
crocus_bo_reference(struct crocus_bo *bo)
|
|
{
|
|
p_atomic_inc(&bo->refcount);
|
|
}
|
|
|
|
/**
|
|
* Releases a reference on a buffer object, freeing the data if
|
|
* no references remain.
|
|
*/
|
|
void crocus_bo_unreference(struct crocus_bo *bo);
|
|
|
|
#define MAP_READ PIPE_MAP_READ
|
|
#define MAP_WRITE PIPE_MAP_WRITE
|
|
#define MAP_ASYNC PIPE_MAP_UNSYNCHRONIZED
|
|
#define MAP_PERSISTENT PIPE_MAP_PERSISTENT
|
|
#define MAP_COHERENT PIPE_MAP_COHERENT
|
|
/* internal */
|
|
#define MAP_INTERNAL_MASK (0xff << 24)
|
|
#define MAP_RAW (0x01 << 24)
|
|
|
|
#define MAP_FLAGS (MAP_READ | MAP_WRITE | MAP_ASYNC | \
|
|
MAP_PERSISTENT | MAP_COHERENT | MAP_INTERNAL_MASK)
|
|
|
|
/**
|
|
* Maps the buffer into userspace.
|
|
*
|
|
* This function will block waiting for any existing execution on the
|
|
* buffer to complete, first. The resulting mapping is returned.
|
|
*/
|
|
MUST_CHECK void *crocus_bo_map(struct pipe_debug_callback *dbg,
|
|
struct crocus_bo *bo, unsigned flags);
|
|
|
|
/**
|
|
* Reduces the refcount on the userspace mapping of the buffer
|
|
* object.
|
|
*/
|
|
static inline int crocus_bo_unmap(struct crocus_bo *bo) { return 0; }
|
|
|
|
/**
|
|
* Waits for rendering to an object by the GPU to have completed.
|
|
*
|
|
* This is not required for any access to the BO by bo_map,
|
|
* bo_subdata, etc. It is merely a way for the driver to implement
|
|
* glFinish.
|
|
*/
|
|
void crocus_bo_wait_rendering(struct crocus_bo *bo);
|
|
|
|
/**
|
|
* Unref a buffer manager instance.
|
|
*/
|
|
void crocus_bufmgr_unref(struct crocus_bufmgr *bufmgr);
|
|
|
|
/**
|
|
* Get the current tiling (and resulting swizzling) mode for the bo.
|
|
*
|
|
* \param buf Buffer to get tiling mode for
|
|
* \param tiling_mode returned tiling mode
|
|
* \param swizzle_mode returned swizzling mode
|
|
*/
|
|
int crocus_bo_get_tiling(struct crocus_bo *bo, uint32_t *tiling_mode,
|
|
uint32_t *swizzle_mode);
|
|
|
|
/**
|
|
* Create a visible name for a buffer which can be used by other apps
|
|
*
|
|
* \param buf Buffer to create a name for
|
|
* \param name Returned name
|
|
*/
|
|
int crocus_bo_flink(struct crocus_bo *bo, uint32_t *name);
|
|
|
|
/**
|
|
* Is this buffer shared with external clients (exported)?
|
|
*/
|
|
static inline bool
|
|
crocus_bo_is_external(const struct crocus_bo *bo)
|
|
{
|
|
return bo->external;
|
|
}
|
|
|
|
/**
|
|
* Returns 1 if mapping the buffer for write could cause the process
|
|
* to block, due to the object being active in the GPU.
|
|
*/
|
|
int crocus_bo_busy(struct crocus_bo *bo);
|
|
|
|
/**
|
|
* Specify the volatility of the buffer.
|
|
* \param bo Buffer to create a name for
|
|
* \param madv The purgeable status
|
|
*
|
|
* Use I915_MADV_DONTNEED to mark the buffer as purgeable, and it will be
|
|
* reclaimed under memory pressure. If you subsequently require the buffer,
|
|
* then you must pass I915_MADV_WILLNEED to mark the buffer as required.
|
|
*
|
|
* Returns 1 if the buffer was retained, or 0 if it was discarded whilst
|
|
* marked as I915_MADV_DONTNEED.
|
|
*/
|
|
int crocus_bo_madvise(struct crocus_bo *bo, int madv);
|
|
|
|
/* drm_bacon_bufmgr_gem.c */
|
|
struct crocus_bufmgr *
|
|
crocus_bufmgr_get_for_fd(struct intel_device_info *devinfo, int fd,
|
|
bool bo_reuse);
|
|
int crocus_bufmgr_get_fd(struct crocus_bufmgr *bufmgr);
|
|
|
|
struct crocus_bo *crocus_bo_gem_create_from_name(struct crocus_bufmgr *bufmgr,
|
|
const char *name,
|
|
unsigned handle);
|
|
|
|
int crocus_bo_wait(struct crocus_bo *bo, int64_t timeout_ns);
|
|
|
|
uint32_t crocus_create_hw_context(struct crocus_bufmgr *bufmgr);
|
|
uint32_t crocus_clone_hw_context(struct crocus_bufmgr *bufmgr, uint32_t ctx_id);
|
|
|
|
#define CROCUS_CONTEXT_LOW_PRIORITY ((I915_CONTEXT_MIN_USER_PRIORITY - 1) / 2)
|
|
#define CROCUS_CONTEXT_MEDIUM_PRIORITY (I915_CONTEXT_DEFAULT_PRIORITY)
|
|
#define CROCUS_CONTEXT_HIGH_PRIORITY ((I915_CONTEXT_MAX_USER_PRIORITY + 1) / 2)
|
|
|
|
int crocus_hw_context_set_priority(struct crocus_bufmgr *bufmgr,
|
|
uint32_t ctx_id, int priority);
|
|
|
|
void crocus_destroy_hw_context(struct crocus_bufmgr *bufmgr, uint32_t ctx_id);
|
|
|
|
int crocus_bo_export_dmabuf(struct crocus_bo *bo, int *prime_fd);
|
|
struct crocus_bo *crocus_bo_import_dmabuf(struct crocus_bufmgr *bufmgr,
|
|
int prime_fd, uint32_t tiling,
|
|
uint32_t stride);
|
|
|
|
/**
|
|
* Exports a bo as a GEM handle into a given DRM file descriptor
|
|
* \param bo Buffer to export
|
|
* \param drm_fd File descriptor where the new handle is created
|
|
* \param out_handle Pointer to store the new handle
|
|
*
|
|
* Returns 0 if the buffer was successfully exported, a non zero error code
|
|
* otherwise.
|
|
*/
|
|
int crocus_bo_export_gem_handle_for_device(struct crocus_bo *bo, int drm_fd,
|
|
uint32_t *out_handle);
|
|
|
|
uint32_t crocus_bo_export_gem_handle(struct crocus_bo *bo);
|
|
|
|
int crocus_reg_read(struct crocus_bufmgr *bufmgr, uint32_t offset,
|
|
uint64_t *out);
|
|
|
|
int drm_ioctl(int fd, unsigned long request, void *arg);
|
|
|
|
#endif /* CROCUS_BUFMGR_H */
|