Path: blob/21.2-virgl/src/gallium/drivers/crocus/crocus_bufmgr.h
4570 views
/*1* Copyright © 2017 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#ifndef CROCUS_BUFMGR_H24#define CROCUS_BUFMGR_H2526#include <stdbool.h>27#include <stdint.h>28#include <stdio.h>29#include <sys/types.h>30#include "util/macros.h"31#include "util/u_atomic.h"32#include "util/list.h"33#include "pipe/p_defines.h"3435struct crocus_batch;36struct intel_device_info;37struct pipe_debug_callback;3839#define CROCUS_BINDER_SIZE (64 * 1024)40#define CROCUS_MAX_BINDERS 1004142struct crocus_bo {43/**44* Size in bytes of the buffer object.45*46* The size may be larger than the size originally requested for the47* allocation, such as being aligned to page size.48*/49uint64_t size;5051/** Buffer manager context associated with this buffer object */52struct crocus_bufmgr *bufmgr;5354/** The GEM handle for this buffer object. */55uint32_t gem_handle;5657/**58* Virtual address of the buffer inside the PPGTT (Per-Process Graphics59* Translation Table).60*61* Although each hardware context has its own VMA, we assign BO's to the62* same address in all contexts, for simplicity.63*/64uint64_t gtt_offset;6566/**67* The validation list index for this buffer, or -1 when not in a batch.68* Note that a single buffer may be in multiple batches (contexts), and69* this is a global field, which refers to the last batch using the BO.70* It should not be considered authoritative, but can be used to avoid a71* linear walk of the validation list in the common case by guessing that72* exec_bos[bo->index] == bo and confirming whether that's the case.73*74* XXX: this is not ideal now that we have more than one batch per context,75* XXX: as the index will flop back and forth between the render index and76* XXX: compute index...77*/78unsigned index;7980/**81* Boolean of whether the GPU is definitely not accessing the buffer.82*83* This is only valid when reusable, since non-reusable84* buffers are those that have been shared with other85* processes, so we don't know their state.86*/87bool idle;8889int refcount;90const char *name;9192uint64_t kflags;9394/**95* Kenel-assigned global name for this object96*97* List contains both flink named and prime fd'd objects98*/99unsigned global_name;100101/**102* Current tiling mode103*/104uint32_t tiling_mode;105uint32_t swizzle_mode;106uint32_t stride;107108time_t free_time;109110/** Mapped address for the buffer, saved across map/unmap cycles */111void *map_cpu;112/** GTT virtual address for the buffer, saved across map/unmap cycles */113void *map_gtt;114/** WC CPU address for the buffer, saved across map/unmap cycles */115void *map_wc;116117/** BO cache list */118struct list_head head;119120/** List of GEM handle exports of this buffer (bo_export) */121struct list_head exports;122123/**124* Boolean of whether this buffer can be re-used125*/126bool reusable;127128/**129* Boolean of whether this buffer has been shared with an external client.130*/131bool external;132133/**134* Boolean of whether this buffer is cache coherent135*/136bool cache_coherent;137138/**139* Boolean of whether this buffer points into user memory140*/141bool userptr;142143/** Pre-computed hash using _mesa_hash_pointer for cache tracking sets */144uint32_t hash;145};146147#define BO_ALLOC_ZEROED (1 << 0)148#define BO_ALLOC_COHERENT (1 << 1)149150/**151* Allocate a buffer object.152*153* Buffer objects are not necessarily initially mapped into CPU virtual154* address space or graphics device aperture. They must be mapped155* using crocus_bo_map() to be used by the CPU.156*/157struct crocus_bo *crocus_bo_alloc(struct crocus_bufmgr *bufmgr,158const char *name, uint64_t size);159160/**161* Allocate a tiled buffer object.162*163* Alignment for tiled objects is set automatically; the 'flags'164* argument provides a hint about how the object will be used initially.165*166* Valid tiling formats are:167* I915_TILING_NONE168* I915_TILING_X169* I915_TILING_Y170*/171struct crocus_bo *crocus_bo_alloc_tiled(struct crocus_bufmgr *bufmgr,172const char *name, uint64_t size,173uint32_t alignment,174uint32_t tiling_mode, uint32_t pitch,175unsigned flags);176177struct crocus_bo *crocus_bo_create_userptr(struct crocus_bufmgr *bufmgr,178const char *name, void *ptr,179size_t size);180181/** Takes a reference on a buffer object */182static inline void183crocus_bo_reference(struct crocus_bo *bo)184{185p_atomic_inc(&bo->refcount);186}187188static inline int189atomic_add_unless(int *v, int add, int unless)190{191int c, old;192c = p_atomic_read(v);193while (c != unless && (old = p_atomic_cmpxchg(v, c, c + add)) != c)194c = old;195return c == unless;196}197198void __crocus_bo_unreference(struct crocus_bo *bo);199200/**201* Releases a reference on a buffer object, freeing the data if202* no references remain.203*/204static inline void crocus_bo_unreference(struct crocus_bo *bo)205{206if (bo == NULL)207return;208209assert(p_atomic_read(&bo->refcount) > 0);210211if (atomic_add_unless(&bo->refcount, -1, 1)) {212__crocus_bo_unreference(bo);213}214}215216#define MAP_READ PIPE_MAP_READ217#define MAP_WRITE PIPE_MAP_WRITE218#define MAP_ASYNC PIPE_MAP_UNSYNCHRONIZED219#define MAP_PERSISTENT PIPE_MAP_PERSISTENT220#define MAP_COHERENT PIPE_MAP_COHERENT221/* internal */222#define MAP_INTERNAL_MASK (0xff << 24)223#define MAP_RAW (0x01 << 24)224225#define MAP_FLAGS (MAP_READ | MAP_WRITE | MAP_ASYNC | \226MAP_PERSISTENT | MAP_COHERENT | MAP_INTERNAL_MASK)227228/**229* Maps the buffer into userspace.230*231* This function will block waiting for any existing execution on the232* buffer to complete, first. The resulting mapping is returned.233*/234MUST_CHECK void *crocus_bo_map(struct pipe_debug_callback *dbg,235struct crocus_bo *bo, unsigned flags);236237/**238* Reduces the refcount on the userspace mapping of the buffer239* object.240*/241static inline int crocus_bo_unmap(struct crocus_bo *bo) { return 0; }242243/**244* Waits for rendering to an object by the GPU to have completed.245*246* This is not required for any access to the BO by bo_map,247* bo_subdata, etc. It is merely a way for the driver to implement248* glFinish.249*/250void crocus_bo_wait_rendering(struct crocus_bo *bo);251252/**253* Unref a buffer manager instance.254*/255void crocus_bufmgr_unref(struct crocus_bufmgr *bufmgr);256257/**258* Get the current tiling (and resulting swizzling) mode for the bo.259*260* \param buf Buffer to get tiling mode for261* \param tiling_mode returned tiling mode262* \param swizzle_mode returned swizzling mode263*/264int crocus_bo_get_tiling(struct crocus_bo *bo, uint32_t *tiling_mode,265uint32_t *swizzle_mode);266267/**268* Create a visible name for a buffer which can be used by other apps269*270* \param buf Buffer to create a name for271* \param name Returned name272*/273int crocus_bo_flink(struct crocus_bo *bo, uint32_t *name);274275/**276* Is this buffer shared with external clients (exported)?277*/278static inline bool279crocus_bo_is_external(const struct crocus_bo *bo)280{281return bo->external;282}283284/**285* Returns 1 if mapping the buffer for write could cause the process286* to block, due to the object being active in the GPU.287*/288int crocus_bo_busy(struct crocus_bo *bo);289290/**291* Specify the volatility of the buffer.292* \param bo Buffer to create a name for293* \param madv The purgeable status294*295* Use I915_MADV_DONTNEED to mark the buffer as purgeable, and it will be296* reclaimed under memory pressure. If you subsequently require the buffer,297* then you must pass I915_MADV_WILLNEED to mark the buffer as required.298*299* Returns 1 if the buffer was retained, or 0 if it was discarded whilst300* marked as I915_MADV_DONTNEED.301*/302int crocus_bo_madvise(struct crocus_bo *bo, int madv);303304/* drm_bacon_bufmgr_gem.c */305struct crocus_bufmgr *306crocus_bufmgr_get_for_fd(struct intel_device_info *devinfo, int fd,307bool bo_reuse);308int crocus_bufmgr_get_fd(struct crocus_bufmgr *bufmgr);309310struct crocus_bo *crocus_bo_gem_create_from_name(struct crocus_bufmgr *bufmgr,311const char *name,312unsigned handle);313314int crocus_bo_wait(struct crocus_bo *bo, int64_t timeout_ns);315316uint32_t crocus_create_hw_context(struct crocus_bufmgr *bufmgr);317uint32_t crocus_clone_hw_context(struct crocus_bufmgr *bufmgr, uint32_t ctx_id);318319#define CROCUS_CONTEXT_LOW_PRIORITY ((I915_CONTEXT_MIN_USER_PRIORITY - 1) / 2)320#define CROCUS_CONTEXT_MEDIUM_PRIORITY (I915_CONTEXT_DEFAULT_PRIORITY)321#define CROCUS_CONTEXT_HIGH_PRIORITY ((I915_CONTEXT_MAX_USER_PRIORITY + 1) / 2)322323int crocus_hw_context_set_priority(struct crocus_bufmgr *bufmgr,324uint32_t ctx_id, int priority);325326void crocus_destroy_hw_context(struct crocus_bufmgr *bufmgr, uint32_t ctx_id);327328int crocus_bo_export_dmabuf(struct crocus_bo *bo, int *prime_fd);329struct crocus_bo *crocus_bo_import_dmabuf(struct crocus_bufmgr *bufmgr,330int prime_fd, uint64_t modifier);331struct crocus_bo *crocus_bo_import_dmabuf_no_mods(struct crocus_bufmgr *bufmgr,332int prime_fd);333334/**335* Exports a bo as a GEM handle into a given DRM file descriptor336* \param bo Buffer to export337* \param drm_fd File descriptor where the new handle is created338* \param out_handle Pointer to store the new handle339*340* Returns 0 if the buffer was successfully exported, a non zero error code341* otherwise.342*/343int crocus_bo_export_gem_handle_for_device(struct crocus_bo *bo, int drm_fd,344uint32_t *out_handle);345346uint32_t crocus_bo_export_gem_handle(struct crocus_bo *bo);347348int crocus_reg_read(struct crocus_bufmgr *bufmgr, uint32_t offset,349uint64_t *out);350351int drm_ioctl(int fd, unsigned long request, void *arg);352353#endif /* CROCUS_BUFMGR_H */354355356