i915_drm_buffer.c revision c62f5c7e7bc3ed84677805b3800fbcfa93c419ea
1 2#include "state_tracker/drm_driver.h" 3#include "i915_drm_winsys.h" 4#include "util/u_memory.h" 5 6#include "i915_drm.h" 7 8static struct i915_winsys_buffer * 9i915_drm_buffer_create(struct i915_winsys *iws, 10 unsigned size, 11 enum i915_winsys_buffer_type type) 12{ 13 struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); 14 struct i915_drm_winsys *idws = i915_drm_winsys(iws); 15 char *name; 16 17 if (!buf) 18 return NULL; 19 20 buf->magic = 0xDEAD1337; 21 buf->flinked = FALSE; 22 buf->flink = 0; 23 24 if (type == I915_NEW_TEXTURE) { 25 name = "gallium3d_texture"; 26 } else if (type == I915_NEW_VERTEX) { 27 name = "gallium3d_vertex"; 28 } else if (type == I915_NEW_SCANOUT) { 29 name = "gallium3d_scanout"; 30 } else { 31 assert(0); 32 name = "gallium3d_unknown"; 33 } 34 35 buf->bo = drm_intel_bo_alloc(idws->gem_manager, name, size, 0); 36 37 if (!buf->bo) 38 goto err; 39 40 return (struct i915_winsys_buffer *)buf; 41 42err: 43 assert(0); 44 FREE(buf); 45 return NULL; 46} 47 48static struct i915_winsys_buffer * 49i915_drm_buffer_from_handle(struct i915_winsys *iws, 50 struct winsys_handle *whandle, 51 unsigned *stride) 52{ 53 struct i915_drm_winsys *idws = i915_drm_winsys(iws); 54 struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer); 55 uint32_t tile = 0, swizzle = 0; 56 57 if (!buf) 58 return NULL; 59 60 buf->magic = 0xDEAD1337; 61 buf->bo = drm_intel_bo_gem_create_from_name(idws->gem_manager, "gallium3d_from_handle", whandle->handle); 62 buf->flinked = TRUE; 63 buf->flink = whandle->handle; 64 65 if (!buf->bo) 66 goto err; 67 68 drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle); 69 70 *stride = whandle->stride; 71 72 return (struct i915_winsys_buffer *)buf; 73 74err: 75 FREE(buf); 76 return NULL; 77} 78 79static boolean 80i915_drm_buffer_get_handle(struct i915_winsys *iws, 81 struct i915_winsys_buffer *buffer, 82 struct winsys_handle *whandle, 83 unsigned stride) 84{ 85 struct i915_drm_buffer *buf = i915_drm_buffer(buffer); 86 87 if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { 88 if (!buf->flinked) { 89 if (drm_intel_bo_flink(buf->bo, &buf->flink)) 90 return FALSE; 91 buf->flinked = TRUE; 92 } 93 94 whandle->handle = buf->flink; 95 } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) { 96 whandle->handle = buf->bo->handle; 97 } else { 98 assert(!"unknown usage"); 99 return FALSE; 100 } 101 102 whandle->stride = stride; 103 return TRUE; 104} 105 106static int 107i915_drm_buffer_set_fence_reg(struct i915_winsys *iws, 108 struct i915_winsys_buffer *buffer, 109 unsigned stride, 110 enum i915_winsys_buffer_tile tile) 111{ 112 struct i915_drm_buffer *buf = i915_drm_buffer(buffer); 113 assert(I915_TILING_NONE == I915_TILE_NONE); 114 assert(I915_TILING_X == I915_TILE_X); 115 assert(I915_TILING_Y == I915_TILE_Y); 116 117 if (tile != I915_TILE_NONE) { 118 assert(buf->map_count == 0); 119 } 120 121 return drm_intel_bo_set_tiling(buf->bo, &tile, stride); 122} 123 124static void * 125i915_drm_buffer_map(struct i915_winsys *iws, 126 struct i915_winsys_buffer *buffer, 127 boolean write) 128{ 129 struct i915_drm_buffer *buf = i915_drm_buffer(buffer); 130 drm_intel_bo *bo = intel_bo(buffer); 131 int ret = 0; 132 133 assert(bo); 134 135 if (buf->map_count) 136 goto out; 137 138 ret = drm_intel_gem_bo_map_gtt(bo); 139 140 buf->ptr = bo->virtual; 141 142 assert(ret == 0); 143out: 144 if (ret) 145 return NULL; 146 147 buf->map_count++; 148 return buf->ptr; 149} 150 151static void 152i915_drm_buffer_unmap(struct i915_winsys *iws, 153 struct i915_winsys_buffer *buffer) 154{ 155 struct i915_drm_buffer *buf = i915_drm_buffer(buffer); 156 157 if (--buf->map_count) 158 return; 159 160 drm_intel_gem_bo_unmap_gtt(intel_bo(buffer)); 161} 162 163static int 164i915_drm_buffer_write(struct i915_winsys *iws, 165 struct i915_winsys_buffer *buffer, 166 size_t offset, 167 size_t size, 168 const void *data) 169{ 170 struct i915_drm_buffer *buf = i915_drm_buffer(buffer); 171 172 return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data); 173} 174 175static void 176i915_drm_buffer_destroy(struct i915_winsys *iws, 177 struct i915_winsys_buffer *buffer) 178{ 179 drm_intel_bo_unreference(intel_bo(buffer)); 180 181#ifdef DEBUG 182 i915_drm_buffer(buffer)->magic = 0; 183 i915_drm_buffer(buffer)->bo = NULL; 184#endif 185 186 FREE(buffer); 187} 188 189void 190i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws) 191{ 192 idws->base.buffer_create = i915_drm_buffer_create; 193 idws->base.buffer_from_handle = i915_drm_buffer_from_handle; 194 idws->base.buffer_get_handle = i915_drm_buffer_get_handle; 195 idws->base.buffer_set_fence_reg = i915_drm_buffer_set_fence_reg; 196 idws->base.buffer_map = i915_drm_buffer_map; 197 idws->base.buffer_unmap = i915_drm_buffer_unmap; 198 idws->base.buffer_write = i915_drm_buffer_write; 199 idws->base.buffer_destroy = i915_drm_buffer_destroy; 200} 201