Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

intel_be_device.c 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. #include "intel_be_device.h"
  2. #include "pipe/internal/p_winsys_screen.h"
  3. #include "pipe/p_defines.h"
  4. #include "pipe/p_state.h"
  5. #include "pipe/p_inlines.h"
  6. #include "util/u_memory.h"
  7. #include "util/u_debug.h"
  8. #include "intel_be_fence.h"
  9. #include "i915simple/i915_winsys.h"
  10. #include "softpipe/sp_winsys.h"
  11. #include "intel_be_api.h"
  12. #include <stdio.h>
  13. /*
  14. * Buffer
  15. */
  16. static void *
  17. intel_be_buffer_map(struct pipe_winsys *winsys,
  18. struct pipe_buffer *buf,
  19. unsigned flags)
  20. {
  21. drm_intel_bo *bo = intel_bo(buf);
  22. int write = 0;
  23. int ret;
  24. if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
  25. /* Remove this when drm_intel_bo_map supports DONTBLOCK
  26. */
  27. return NULL;
  28. }
  29. if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
  30. write = 1;
  31. ret = drm_intel_bo_map(bo, write);
  32. if (ret)
  33. return NULL;
  34. return bo->virtual;
  35. }
  36. static void
  37. intel_be_buffer_unmap(struct pipe_winsys *winsys,
  38. struct pipe_buffer *buf)
  39. {
  40. drm_intel_bo_unmap(intel_bo(buf));
  41. }
  42. static void
  43. intel_be_buffer_destroy(struct pipe_buffer *buf)
  44. {
  45. drm_intel_bo_unreference(intel_bo(buf));
  46. free(buf);
  47. }
  48. static struct pipe_buffer *
  49. intel_be_buffer_create(struct pipe_winsys *winsys,
  50. unsigned alignment,
  51. unsigned usage,
  52. unsigned size)
  53. {
  54. struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
  55. struct intel_be_device *dev = intel_be_device(winsys);
  56. drm_intel_bufmgr *pool;
  57. char *name;
  58. if (!buffer)
  59. return NULL;
  60. pipe_reference_init(&buffer->base.reference, 1);
  61. buffer->base.alignment = alignment;
  62. buffer->base.usage = usage;
  63. buffer->base.size = size;
  64. buffer->flinked = FALSE;
  65. buffer->flink = 0;
  66. if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
  67. /* Local buffer */
  68. name = "gallium3d_local";
  69. pool = dev->pools.gem;
  70. } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
  71. /* For vertex buffers */
  72. name = "gallium3d_internal_vertex";
  73. pool = dev->pools.gem;
  74. } else {
  75. /* Regular buffers */
  76. name = "gallium3d_regular";
  77. pool = dev->pools.gem;
  78. }
  79. buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
  80. if (!buffer->bo)
  81. goto err;
  82. return &buffer->base;
  83. err:
  84. free(buffer);
  85. return NULL;
  86. }
  87. static struct pipe_buffer *
  88. intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
  89. {
  90. struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
  91. struct intel_be_device *dev = intel_be_device(winsys);
  92. int ret;
  93. if (!buffer)
  94. return NULL;
  95. pipe_reference_init(&buffer->base.reference, 1);
  96. buffer->base.alignment = 0;
  97. buffer->base.usage = 0;
  98. buffer->base.size = bytes;
  99. buffer->bo = drm_intel_bo_alloc(dev->pools.gem,
  100. "gallium3d_user_buffer",
  101. bytes, 0);
  102. if (!buffer->bo)
  103. goto err;
  104. ret = drm_intel_bo_subdata(buffer->bo,
  105. 0, bytes, ptr);
  106. if (ret)
  107. goto err;
  108. return &buffer->base;
  109. err:
  110. free(buffer);
  111. return NULL;
  112. }
  113. struct pipe_buffer *
  114. intel_be_buffer_from_handle(struct pipe_screen *screen,
  115. const char* name, unsigned handle)
  116. {
  117. struct intel_be_device *dev = intel_be_device(screen->winsys);
  118. struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
  119. if (!buffer)
  120. return NULL;
  121. buffer->bo = drm_intel_bo_gem_create_from_name(dev->pools.gem, name, handle);
  122. if (!buffer->bo)
  123. goto err;
  124. pipe_reference_init(&buffer->base.reference, 1);
  125. buffer->base.screen = screen;
  126. buffer->base.alignment = buffer->bo->align;
  127. buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ |
  128. PIPE_BUFFER_USAGE_GPU_WRITE |
  129. PIPE_BUFFER_USAGE_CPU_READ |
  130. PIPE_BUFFER_USAGE_CPU_WRITE;
  131. buffer->base.size = buffer->bo->size;
  132. return &buffer->base;
  133. err:
  134. free(buffer);
  135. return NULL;
  136. }
  137. boolean
  138. intel_be_handle_from_buffer(struct pipe_screen *screen,
  139. struct pipe_buffer *buffer,
  140. unsigned *handle)
  141. {
  142. if (!buffer)
  143. return FALSE;
  144. *handle = intel_bo(buffer)->handle;
  145. return TRUE;
  146. }
  147. boolean
  148. intel_be_global_handle_from_buffer(struct pipe_screen *screen,
  149. struct pipe_buffer *buffer,
  150. unsigned *handle)
  151. {
  152. struct intel_be_buffer *buf = intel_be_buffer(buffer);
  153. if (!buffer)
  154. return FALSE;
  155. if (!buf->flinked) {
  156. if (drm_intel_bo_flink(intel_bo(buffer), &buf->flink))
  157. return FALSE;
  158. buf->flinked = TRUE;
  159. }
  160. *handle = buf->flink;
  161. return TRUE;
  162. }
  163. /*
  164. * Fence
  165. */
  166. static void
  167. intel_be_fence_refunref(struct pipe_winsys *sws,
  168. struct pipe_fence_handle **ptr,
  169. struct pipe_fence_handle *fence)
  170. {
  171. struct intel_be_fence **p = (struct intel_be_fence **)ptr;
  172. struct intel_be_fence *f = (struct intel_be_fence *)fence;
  173. intel_be_fence_reference(p, f);
  174. }
  175. static int
  176. intel_be_fence_signalled(struct pipe_winsys *sws,
  177. struct pipe_fence_handle *fence,
  178. unsigned flag)
  179. {
  180. assert(0);
  181. return 0;
  182. }
  183. static int
  184. intel_be_fence_finish(struct pipe_winsys *sws,
  185. struct pipe_fence_handle *fence,
  186. unsigned flag)
  187. {
  188. struct intel_be_fence *f = (struct intel_be_fence *)fence;
  189. /* fence already expired */
  190. if (!f->bo)
  191. return 0;
  192. drm_intel_bo_wait_rendering(f->bo);
  193. drm_intel_bo_unreference(f->bo);
  194. f->bo = NULL;
  195. return 0;
  196. }
  197. /*
  198. * Misc functions
  199. */
  200. static void
  201. intel_be_destroy_winsys(struct pipe_winsys *winsys)
  202. {
  203. struct intel_be_device *dev = intel_be_device(winsys);
  204. drm_intel_bufmgr_destroy(dev->pools.gem);
  205. free(dev);
  206. }
  207. boolean
  208. intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
  209. {
  210. dev->fd = fd;
  211. dev->id = id;
  212. dev->max_batch_size = 16 * 4096;
  213. dev->max_vertex_size = 128 * 4096;
  214. dev->base.buffer_create = intel_be_buffer_create;
  215. dev->base.user_buffer_create = intel_be_user_buffer_create;
  216. dev->base.buffer_map = intel_be_buffer_map;
  217. dev->base.buffer_unmap = intel_be_buffer_unmap;
  218. dev->base.buffer_destroy = intel_be_buffer_destroy;
  219. /* Not used anymore */
  220. dev->base.surface_buffer_create = NULL;
  221. dev->base.fence_reference = intel_be_fence_refunref;
  222. dev->base.fence_signalled = intel_be_fence_signalled;
  223. dev->base.fence_finish = intel_be_fence_finish;
  224. dev->base.destroy = intel_be_destroy_winsys;
  225. dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
  226. dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE);
  227. return true;
  228. }
  229. static void
  230. intel_be_get_device_id(unsigned int *device_id)
  231. {
  232. char path[512];
  233. FILE *file;
  234. /*
  235. * FIXME: Fix this up to use a drm ioctl or whatever.
  236. */
  237. snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
  238. file = fopen(path, "r");
  239. if (!file) {
  240. return;
  241. }
  242. fgets(path, sizeof(path), file);
  243. sscanf(path, "%x", device_id);
  244. fclose(file);
  245. }
  246. struct pipe_screen *
  247. intel_be_create_screen(int drmFD, struct drm_create_screen_arg *arg)
  248. {
  249. struct intel_be_device *dev;
  250. struct pipe_screen *screen;
  251. unsigned int deviceID;
  252. if (arg != NULL) {
  253. switch(arg->mode) {
  254. case DRM_CREATE_NORMAL:
  255. break;
  256. default:
  257. return NULL;
  258. }
  259. }
  260. /* Allocate the private area */
  261. dev = malloc(sizeof(*dev));
  262. if (!dev)
  263. return NULL;
  264. memset(dev, 0, sizeof(*dev));
  265. intel_be_get_device_id(&deviceID);
  266. intel_be_init_device(dev, drmFD, deviceID);
  267. if (dev->softpipe) {
  268. screen = softpipe_create_screen(&dev->base);
  269. drm_api_hooks.buffer_from_texture = softpipe_get_texture_buffer;
  270. } else
  271. screen = i915_create_screen(&dev->base, deviceID);
  272. return screen;
  273. }