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_winsys_pipe.c 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /**************************************************************************
  2. *
  3. * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sub license, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  18. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * The above copyright notice and this permission notice (including the
  23. * next paragraph) shall be included in all copies or substantial portions
  24. * of the Software.
  25. *
  26. *
  27. **************************************************************************/
  28. /*
  29. * Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
  30. */
  31. #include <stdlib.h>
  32. #include <xf86drm.h>
  33. //#include "dri_bufpool.h"
  34. //#include "dri_bufmgr.h"
  35. #include "intel_context.h"
  36. #include "intel_winsys.h"
  37. #include "intel_swapbuffers.h"
  38. #include "intel_batchbuffer.h"
  39. #include "pipe/p_winsys.h"
  40. #include "pipe/p_defines.h"
  41. #include "pipe/p_state.h"
  42. #include "pipe/p_util.h"
  43. #include "pipe/p_inlines.h"
  44. struct intel_pipe_winsys {
  45. struct pipe_winsys winsys;
  46. struct _DriBufferPool *regionPool;
  47. struct _DriBufferPool *mallocPool;
  48. struct _DriBufferPool *vertexPool;
  49. struct _DriFreeSlabManager *fMan; /** shared between all pipes */
  50. };
  51. /* Turn a pipe winsys into an intel/pipe winsys:
  52. */
  53. static inline struct intel_pipe_winsys *
  54. intel_pipe_winsys( struct pipe_winsys *winsys )
  55. {
  56. return (struct intel_pipe_winsys *)winsys;
  57. }
  58. /* Most callbacks map direcly onto dri_bufmgr operations:
  59. */
  60. static void *intel_buffer_map(struct pipe_winsys *winsys,
  61. struct pipe_buffer *buf,
  62. unsigned flags )
  63. {
  64. unsigned drm_flags = 0;
  65. if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
  66. drm_flags |= DRM_BO_FLAG_WRITE;
  67. if (flags & PIPE_BUFFER_USAGE_CPU_READ)
  68. drm_flags |= DRM_BO_FLAG_READ;
  69. return driBOMap( dri_bo(buf), drm_flags, 0 );
  70. }
  71. static void intel_buffer_unmap(struct pipe_winsys *winsys,
  72. struct pipe_buffer *buf)
  73. {
  74. driBOUnmap( dri_bo(buf) );
  75. }
  76. static void
  77. intel_buffer_destroy(struct pipe_winsys *winsys,
  78. struct pipe_buffer *buf)
  79. {
  80. driBOUnReference( dri_bo(buf) );
  81. FREE(buf);
  82. }
  83. /* Pipe has no concept of pools. We choose the tex/region pool
  84. * for all buffers.
  85. * Grabs the hardware lock!
  86. */
  87. static struct pipe_buffer *
  88. intel_buffer_create(struct pipe_winsys *winsys,
  89. unsigned alignment,
  90. unsigned usage,
  91. unsigned size )
  92. {
  93. struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
  94. struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
  95. unsigned flags = 0;
  96. struct _DriBufferPool *pool;
  97. buffer->base.refcount = 1;
  98. buffer->base.alignment = alignment;
  99. buffer->base.usage = usage;
  100. buffer->base.size = size;
  101. if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
  102. flags |= DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED;
  103. pool = iws->mallocPool;
  104. } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
  105. /* For vertex buffers */
  106. flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
  107. pool = iws->vertexPool;
  108. } else {
  109. flags |= DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT;
  110. pool = iws->regionPool;
  111. }
  112. if (usage & PIPE_BUFFER_USAGE_GPU_READ)
  113. flags |= DRM_BO_FLAG_READ;
  114. if (usage & PIPE_BUFFER_USAGE_GPU_WRITE)
  115. flags |= DRM_BO_FLAG_WRITE;
  116. /* drm complains if we don't set any read/write flags.
  117. */
  118. if ((flags & (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE)) == 0)
  119. flags |= DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE;
  120. #if 0
  121. if (flags & IWS_BUFFER_USAGE_EXE)
  122. flags |= DRM_BO_FLAG_EXE;
  123. if (usage & IWS_BUFFER_USAGE_CACHED)
  124. flags |= DRM_BO_FLAG_CACHED;
  125. #endif
  126. buffer->pool = pool;
  127. driGenBuffers( buffer->pool,
  128. "pipe buffer", 1, &buffer->driBO, alignment, flags, 0 );
  129. driBOData( buffer->driBO, size, NULL, buffer->pool, 0 );
  130. return &buffer->base;
  131. }
  132. static struct pipe_buffer *
  133. intel_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
  134. {
  135. struct intel_buffer *buffer = CALLOC_STRUCT( intel_buffer );
  136. struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
  137. driGenUserBuffer( iws->regionPool,
  138. "pipe user buffer", &buffer->driBO, ptr, bytes );
  139. buffer->base.refcount = 1;
  140. return &buffer->base;
  141. }
  142. /* The state tracker (should!) keep track of whether the fake
  143. * frontbuffer has been touched by any rendering since the last time
  144. * we copied its contents to the real frontbuffer. Our task is easy:
  145. */
  146. static void
  147. intel_flush_frontbuffer( struct pipe_winsys *winsys,
  148. struct pipe_surface *surf,
  149. void *context_private)
  150. {
  151. struct intel_context *intel = (struct intel_context *) context_private;
  152. __DRIdrawablePrivate *dPriv = intel->driDrawable;
  153. intelDisplaySurface(dPriv, surf, NULL);
  154. }
  155. static struct pipe_surface *
  156. intel_i915_surface_alloc(struct pipe_winsys *winsys)
  157. {
  158. struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
  159. if (surf) {
  160. surf->refcount = 1;
  161. surf->winsys = winsys;
  162. }
  163. return surf;
  164. }
  165. /**
  166. * Round n up to next multiple.
  167. */
  168. static INLINE unsigned
  169. round_up(unsigned n, unsigned multiple)
  170. {
  171. return (n + multiple - 1) & ~(multiple - 1);
  172. }
  173. /**
  174. * Copied from xm_winsys.c
  175. */
  176. static int
  177. intel_i915_surface_alloc_storage(struct pipe_winsys *winsys,
  178. struct pipe_surface *surf,
  179. unsigned width, unsigned height,
  180. enum pipe_format format,
  181. unsigned flags,
  182. unsigned tex_usage)
  183. {
  184. const unsigned alignment = 64;
  185. //int ret;
  186. surf->width = width;
  187. surf->height = height;
  188. surf->format = format;
  189. surf->cpp = pf_get_size(format);
  190. surf->pitch = round_up(width, alignment / surf->cpp);
  191. assert(!surf->buffer);
  192. surf->buffer = winsys->buffer_create(winsys, alignment,
  193. PIPE_BUFFER_USAGE_PIXEL,
  194. surf->pitch * surf->cpp * height);
  195. if(!surf->buffer)
  196. return -1;
  197. return 0;
  198. }
  199. static void
  200. intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
  201. {
  202. struct pipe_surface *surf = *s;
  203. surf->refcount--;
  204. if (surf->refcount == 0) {
  205. if (surf->buffer)
  206. pipe_buffer_reference(winsys, &surf->buffer, NULL);
  207. free(surf);
  208. }
  209. *s = NULL;
  210. }
  211. static const char *
  212. intel_get_name( struct pipe_winsys *winsys )
  213. {
  214. return "Intel/DRI/ttm";
  215. }
  216. static void
  217. intel_fence_reference( struct pipe_winsys *sws,
  218. struct pipe_fence_handle **ptr,
  219. struct pipe_fence_handle *fence )
  220. {
  221. if (*ptr)
  222. driFenceUnReference((struct _DriFenceObject **)ptr);
  223. if (fence)
  224. *ptr = (struct pipe_fence_handle *)driFenceReference((struct _DriFenceObject *)fence);
  225. }
  226. static int
  227. intel_fence_signalled( struct pipe_winsys *sws,
  228. struct pipe_fence_handle *fence,
  229. unsigned flag )
  230. {
  231. return driFenceSignaled((struct _DriFenceObject *)fence, flag);
  232. }
  233. static int
  234. intel_fence_finish( struct pipe_winsys *sws,
  235. struct pipe_fence_handle *fence,
  236. unsigned flag )
  237. {
  238. return driFenceFinish((struct _DriFenceObject *)fence, flag, 0);
  239. }
  240. struct pipe_winsys *
  241. intel_create_pipe_winsys( int fd, struct _DriFreeSlabManager *fMan )
  242. {
  243. struct intel_pipe_winsys *iws = CALLOC_STRUCT( intel_pipe_winsys );
  244. /* Fill in this struct with callbacks that pipe will need to
  245. * communicate with the window system, buffer manager, etc.
  246. *
  247. * Pipe would be happy with a malloc based memory manager, but
  248. * the SwapBuffers implementation in this winsys driver requires
  249. * that rendering be done to an appropriate _DriBufferObject.
  250. */
  251. iws->winsys.buffer_create = intel_buffer_create;
  252. iws->winsys.user_buffer_create = intel_user_buffer_create;
  253. iws->winsys.buffer_map = intel_buffer_map;
  254. iws->winsys.buffer_unmap = intel_buffer_unmap;
  255. iws->winsys.buffer_destroy = intel_buffer_destroy;
  256. iws->winsys.flush_frontbuffer = intel_flush_frontbuffer;
  257. iws->winsys.get_name = intel_get_name;
  258. iws->winsys.surface_alloc = intel_i915_surface_alloc;
  259. iws->winsys.surface_alloc_storage = intel_i915_surface_alloc_storage;
  260. iws->winsys.surface_release = intel_i915_surface_release;
  261. iws->winsys.fence_reference = intel_fence_reference;
  262. iws->winsys.fence_signalled = intel_fence_signalled;
  263. iws->winsys.fence_finish = intel_fence_finish;
  264. if (fd) {
  265. iws->regionPool = driDRMPoolInit(fd);
  266. iws->vertexPool = driSlabPoolInit(fd,
  267. DRM_BO_FLAG_READ |
  268. DRM_BO_FLAG_WRITE |
  269. DRM_BO_FLAG_MEM_TT,
  270. DRM_BO_FLAG_READ |
  271. DRM_BO_FLAG_WRITE |
  272. DRM_BO_FLAG_MEM_TT,
  273. 128,
  274. 6, 120, 32 * 4096, 0,
  275. fMan);
  276. }
  277. iws->mallocPool = driMallocPoolInit();
  278. return &iws->winsys;
  279. }
  280. void
  281. intel_destroy_pipe_winsys( struct pipe_winsys *winsys )
  282. {
  283. struct intel_pipe_winsys *iws = intel_pipe_winsys(winsys);
  284. if (iws->regionPool) {
  285. driPoolTakeDown(iws->regionPool);
  286. }
  287. if (iws->mallocPool) {
  288. driPoolTakeDown(iws->mallocPool);
  289. }
  290. free(iws);
  291. }