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.

u_inlines.h 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. /**************************************************************************
  2. *
  3. * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  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 above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial portions
  16. * of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. **************************************************************************/
  27. #ifndef U_INLINES_H
  28. #define U_INLINES_H
  29. #include "pipe/p_context.h"
  30. #include "pipe/p_defines.h"
  31. #include "pipe/p_state.h"
  32. #include "pipe/p_screen.h"
  33. #include "util/u_debug.h"
  34. #include "util/u_atomic.h"
  35. #include "util/u_box.h"
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. /*
  40. * Reference counting helper functions.
  41. */
  42. static INLINE void
  43. pipe_reference_init(struct pipe_reference *reference, unsigned count)
  44. {
  45. p_atomic_set(&reference->count, count);
  46. }
  47. static INLINE boolean
  48. pipe_is_referenced(struct pipe_reference *reference)
  49. {
  50. return p_atomic_read(&reference->count) != 0;
  51. }
  52. /**
  53. * Update reference counting.
  54. * The old thing pointed to, if any, will be unreferenced.
  55. * Both 'ptr' and 'reference' may be NULL.
  56. * \return TRUE if the object's refcount hits zero and should be destroyed.
  57. */
  58. static INLINE boolean
  59. pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference)
  60. {
  61. boolean destroy = FALSE;
  62. if(ptr != reference) {
  63. /* bump the reference.count first */
  64. if (reference) {
  65. assert(pipe_is_referenced(reference));
  66. p_atomic_inc(&reference->count);
  67. }
  68. if (ptr) {
  69. assert(pipe_is_referenced(ptr));
  70. if (p_atomic_dec_zero(&ptr->count)) {
  71. destroy = TRUE;
  72. }
  73. }
  74. }
  75. return destroy;
  76. }
  77. static INLINE void
  78. pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
  79. {
  80. struct pipe_surface *old_surf = *ptr;
  81. if (pipe_reference(&(*ptr)->reference, &surf->reference))
  82. old_surf->texture->screen->tex_surface_destroy(old_surf);
  83. *ptr = surf;
  84. }
  85. static INLINE void
  86. pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex)
  87. {
  88. struct pipe_resource *old_tex = *ptr;
  89. if (pipe_reference(&(*ptr)->reference, &tex->reference))
  90. old_tex->screen->resource_destroy(old_tex->screen, old_tex);
  91. *ptr = tex;
  92. }
  93. static INLINE void
  94. pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view)
  95. {
  96. struct pipe_sampler_view *old_view = *ptr;
  97. if (pipe_reference(&(*ptr)->reference, &view->reference))
  98. old_view->context->sampler_view_destroy(old_view->context, old_view);
  99. *ptr = view;
  100. }
  101. /*
  102. * Convenience wrappers for screen buffer functions.
  103. */
  104. static INLINE struct pipe_resource *
  105. pipe_buffer_create( struct pipe_screen *screen,
  106. unsigned bind,
  107. unsigned size )
  108. {
  109. struct pipe_resource buffer;
  110. memset(&buffer, 0, sizeof buffer);
  111. buffer.target = PIPE_BUFFER;
  112. buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
  113. buffer.bind = bind;
  114. buffer._usage = PIPE_USAGE_DEFAULT;
  115. buffer.flags = 0;
  116. buffer.width0 = size;
  117. buffer.height0 = 1;
  118. buffer.depth0 = 1;
  119. return screen->resource_create(screen, &buffer);
  120. }
  121. static INLINE struct pipe_resource *
  122. pipe_user_buffer_create( struct pipe_screen *screen, void *ptr, unsigned size,
  123. unsigned usage )
  124. {
  125. return screen->user_buffer_create(screen, ptr, size, usage);
  126. }
  127. static INLINE void *
  128. pipe_buffer_map_range(struct pipe_context *pipe,
  129. struct pipe_resource *buffer,
  130. unsigned offset,
  131. unsigned length,
  132. unsigned usage,
  133. struct pipe_transfer **transfer)
  134. {
  135. struct pipe_box box;
  136. char *map;
  137. assert(offset < buffer->width0);
  138. assert(offset + length <= buffer->width0);
  139. assert(length);
  140. u_box_1d(offset, length, &box);
  141. *transfer = pipe->get_transfer( pipe,
  142. buffer,
  143. u_subresource(0, 0),
  144. usage,
  145. &box);
  146. if (*transfer == NULL)
  147. return NULL;
  148. map = pipe->transfer_map( pipe, *transfer );
  149. if (map == NULL) {
  150. pipe->transfer_destroy( pipe, *transfer );
  151. return NULL;
  152. }
  153. /* Match old screen->buffer_map_range() behaviour, return pointer
  154. * to where the beginning of the buffer would be:
  155. */
  156. return (void *)(map - offset);
  157. }
  158. static INLINE void *
  159. pipe_buffer_map(struct pipe_context *pipe,
  160. struct pipe_resource *buffer,
  161. unsigned usage,
  162. struct pipe_transfer **transfer)
  163. {
  164. return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer);
  165. }
  166. static INLINE void
  167. pipe_buffer_unmap(struct pipe_context *pipe,
  168. struct pipe_resource *buf,
  169. struct pipe_transfer *transfer)
  170. {
  171. if (transfer) {
  172. pipe->transfer_unmap(pipe, transfer);
  173. pipe->transfer_destroy(pipe, transfer);
  174. }
  175. }
  176. static INLINE void
  177. pipe_buffer_flush_mapped_range(struct pipe_context *pipe,
  178. struct pipe_transfer *transfer,
  179. unsigned offset,
  180. unsigned length)
  181. {
  182. struct pipe_box box;
  183. int transfer_offset;
  184. assert(length);
  185. assert(transfer->box.x <= offset);
  186. assert(transfer->box.x + transfer->box.width <= offset + length);
  187. /* Match old screen->buffer_flush_mapped_range() behaviour, where
  188. * offset parameter is relative to the start of the buffer, not the
  189. * mapped range.
  190. */
  191. transfer_offset = offset - transfer->box.x;
  192. u_box_1d(transfer_offset, length, &box);
  193. pipe->transfer_flush_region(pipe, transfer, &box);
  194. }
  195. static INLINE void
  196. pipe_buffer_write(struct pipe_context *pipe,
  197. struct pipe_resource *buf,
  198. unsigned offset,
  199. unsigned size,
  200. const void *data)
  201. {
  202. struct pipe_box box;
  203. u_box_1d(offset, size, &box);
  204. pipe->transfer_inline_write( pipe,
  205. buf,
  206. u_subresource(0,0),
  207. PIPE_TRANSFER_WRITE,
  208. &box,
  209. data,
  210. size,
  211. 0);
  212. }
  213. /**
  214. * Special case for writing non-overlapping ranges.
  215. *
  216. * We can avoid GPU/CPU synchronization when writing range that has never
  217. * been written before.
  218. */
  219. static INLINE void
  220. pipe_buffer_write_nooverlap(struct pipe_context *pipe,
  221. struct pipe_resource *buf,
  222. unsigned offset, unsigned size,
  223. const void *data)
  224. {
  225. struct pipe_box box;
  226. u_box_1d(offset, size, &box);
  227. pipe->transfer_inline_write(pipe,
  228. buf,
  229. u_subresource(0,0),
  230. (PIPE_TRANSFER_WRITE |
  231. PIPE_TRANSFER_NOOVERWRITE),
  232. &box,
  233. data,
  234. 0, 0);
  235. }
  236. static INLINE void
  237. pipe_buffer_read(struct pipe_context *pipe,
  238. struct pipe_resource *buf,
  239. unsigned offset,
  240. unsigned size,
  241. void *data)
  242. {
  243. struct pipe_transfer *src_transfer;
  244. ubyte *map;
  245. map = (ubyte *) pipe_buffer_map_range(pipe,
  246. buf,
  247. offset, size,
  248. PIPE_TRANSFER_READ,
  249. &src_transfer);
  250. if (map)
  251. memcpy(data, map + offset, size);
  252. pipe_buffer_unmap(pipe, buf, src_transfer);
  253. }
  254. static INLINE struct pipe_transfer *
  255. pipe_get_transfer( struct pipe_context *context,
  256. struct pipe_resource *resource,
  257. unsigned face, unsigned level,
  258. unsigned zslice,
  259. enum pipe_transfer_usage usage,
  260. unsigned x, unsigned y,
  261. unsigned w, unsigned h)
  262. {
  263. struct pipe_box box;
  264. u_box_2d_zslice( x, y, zslice, w, h, &box );
  265. return context->get_transfer( context,
  266. resource,
  267. u_subresource(face, level),
  268. usage,
  269. &box );
  270. }
  271. static INLINE void *
  272. pipe_transfer_map( struct pipe_context *context,
  273. struct pipe_transfer *transfer )
  274. {
  275. return context->transfer_map( context, transfer );
  276. }
  277. static INLINE void
  278. pipe_transfer_unmap( struct pipe_context *context,
  279. struct pipe_transfer *transfer )
  280. {
  281. context->transfer_unmap( context, transfer );
  282. }
  283. static INLINE void
  284. pipe_transfer_destroy( struct pipe_context *context,
  285. struct pipe_transfer *transfer )
  286. {
  287. context->transfer_destroy(context, transfer);
  288. }
  289. #ifdef __cplusplus
  290. }
  291. #endif
  292. #endif /* U_INLINES_H */