Path: blob/21.2-virgl/src/gallium/winsys/i915/drm/i915_drm_buffer.c
4566 views
#include "frontend/drm_driver.h"1#include "i915_drm_winsys.h"2#include "util/u_memory.h"34#include "drm-uapi/i915_drm.h"56static char *i915_drm_type_to_name(enum i915_winsys_buffer_type type)7{8char *name;910if (type == I915_NEW_TEXTURE) {11name = "gallium3d_texture";12} else if (type == I915_NEW_VERTEX) {13name = "gallium3d_vertex";14} else if (type == I915_NEW_SCANOUT) {15name = "gallium3d_scanout";16} else {17assert(0);18name = "gallium3d_unknown";19}2021return name;22}2324static struct i915_winsys_buffer *25i915_drm_buffer_create(struct i915_winsys *iws,26unsigned size,27enum i915_winsys_buffer_type type)28{29struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);30struct i915_drm_winsys *idws = i915_drm_winsys(iws);3132if (!buf)33return NULL;3435buf->magic = 0xDEAD1337;36buf->flinked = false;37buf->flink = 0;3839buf->bo = drm_intel_bo_alloc(idws->gem_manager,40i915_drm_type_to_name(type), size, 0);4142if (!buf->bo)43goto err;4445return (struct i915_winsys_buffer *)buf;4647err:48assert(0);49FREE(buf);50return NULL;51}5253static struct i915_winsys_buffer *54i915_drm_buffer_create_tiled(struct i915_winsys *iws,55unsigned *stride, unsigned height,56enum i915_winsys_buffer_tile *tiling,57enum i915_winsys_buffer_type type)58{59struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);60struct i915_drm_winsys *idws = i915_drm_winsys(iws);61unsigned long pitch = 0;62uint32_t tiling_mode = *tiling;6364if (!buf)65return NULL;6667buf->magic = 0xDEAD1337;68buf->flinked = false;69buf->flink = 0;7071buf->bo = drm_intel_bo_alloc_tiled(idws->gem_manager,72i915_drm_type_to_name(type),73*stride, height, 1,74&tiling_mode, &pitch, 0);7576if (!buf->bo)77goto err;7879*stride = pitch;80*tiling = tiling_mode;81return (struct i915_winsys_buffer *)buf;8283err:84assert(0);85FREE(buf);86return NULL;87}8889static struct i915_winsys_buffer *90i915_drm_buffer_from_handle(struct i915_winsys *iws,91struct winsys_handle *whandle,92unsigned height,93enum i915_winsys_buffer_tile *tiling,94unsigned *stride)95{96struct i915_drm_winsys *idws = i915_drm_winsys(iws);97struct i915_drm_buffer *buf;98uint32_t tile = 0, swizzle = 0;99100if ((whandle->type != WINSYS_HANDLE_TYPE_SHARED) && (whandle->type != WINSYS_HANDLE_TYPE_FD))101return NULL;102103if (whandle->offset != 0)104return NULL;105106buf = CALLOC_STRUCT(i915_drm_buffer);107if (!buf)108return NULL;109110buf->magic = 0xDEAD1337;111112if (whandle->type == WINSYS_HANDLE_TYPE_SHARED)113buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle);114else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {115int fd = (int) whandle->handle;116buf->bo = drm_intel_bo_gem_create_from_prime(idws->gem_manager, fd, height * whandle->stride);117}118119buf->flinked = true;120buf->flink = whandle->handle;121122if (!buf->bo)123goto err;124125drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);126127*stride = whandle->stride;128*tiling = tile;129130return (struct i915_winsys_buffer *)buf;131132err:133FREE(buf);134return NULL;135}136137static bool138i915_drm_buffer_get_handle(struct i915_winsys *iws,139struct i915_winsys_buffer *buffer,140struct winsys_handle *whandle,141unsigned stride)142{143struct i915_drm_buffer *buf = i915_drm_buffer(buffer);144145if (whandle->type == WINSYS_HANDLE_TYPE_SHARED) {146if (!buf->flinked) {147if (drm_intel_bo_flink(buf->bo, &buf->flink))148return false;149buf->flinked = true;150}151152whandle->handle = buf->flink;153} else if (whandle->type == WINSYS_HANDLE_TYPE_KMS) {154whandle->handle = buf->bo->handle;155} else if (whandle->type == WINSYS_HANDLE_TYPE_FD) {156int fd;157158if (drm_intel_bo_gem_export_to_prime(buf->bo, &fd))159return false;160whandle->handle = fd;161} else {162assert(!"unknown usage");163return false;164}165166whandle->stride = stride;167return true;168}169170static void *171i915_drm_buffer_map(struct i915_winsys *iws,172struct i915_winsys_buffer *buffer,173bool write)174{175struct i915_drm_buffer *buf = i915_drm_buffer(buffer);176drm_intel_bo *bo = intel_bo(buffer);177int ret = 0;178179assert(bo);180181if (buf->map_count)182goto out;183184ret = drm_intel_gem_bo_map_gtt(bo);185186buf->ptr = bo->virtual;187188assert(ret == 0);189out:190if (ret)191return NULL;192193buf->map_count++;194return buf->ptr;195}196197static void198i915_drm_buffer_unmap(struct i915_winsys *iws,199struct i915_winsys_buffer *buffer)200{201struct i915_drm_buffer *buf = i915_drm_buffer(buffer);202203if (--buf->map_count)204return;205206drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));207}208209static int210i915_drm_buffer_write(struct i915_winsys *iws,211struct i915_winsys_buffer *buffer,212size_t offset,213size_t size,214const void *data)215{216struct i915_drm_buffer *buf = i915_drm_buffer(buffer);217218return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);219}220221static void222i915_drm_buffer_destroy(struct i915_winsys *iws,223struct i915_winsys_buffer *buffer)224{225drm_intel_bo_unreference(intel_bo(buffer));226227#ifdef DEBUG228i915_drm_buffer(buffer)->magic = 0;229i915_drm_buffer(buffer)->bo = NULL;230#endif231232FREE(buffer);233}234235static bool236i915_drm_buffer_is_busy(struct i915_winsys *iws,237struct i915_winsys_buffer *buffer)238{239struct i915_drm_buffer* i915_buffer = i915_drm_buffer(buffer);240if (!i915_buffer)241return false;242return drm_intel_bo_busy(i915_buffer->bo);243}244245246void247i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)248{249idws->base.buffer_create = i915_drm_buffer_create;250idws->base.buffer_create_tiled = i915_drm_buffer_create_tiled;251idws->base.buffer_from_handle = i915_drm_buffer_from_handle;252idws->base.buffer_get_handle = i915_drm_buffer_get_handle;253idws->base.buffer_map = i915_drm_buffer_map;254idws->base.buffer_unmap = i915_drm_buffer_unmap;255idws->base.buffer_write = i915_drm_buffer_write;256idws->base.buffer_destroy = i915_drm_buffer_destroy;257idws->base.buffer_is_busy = i915_drm_buffer_is_busy;258}259260261