Clone of mesa.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

drisw.c 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /**************************************************************************
  2. *
  3. * Copyright 2009, VMware, Inc.
  4. * All Rights Reserved.
  5. * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sub license, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice (including the
  16. * next paragraph) shall be included in all copies or substantial portions
  17. * of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  22. * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  23. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  24. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  25. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. *
  27. **************************************************************************/
  28. /* TODO:
  29. *
  30. * stride:
  31. *
  32. * The driver and the loaders (libGL, xserver/glx) compute the stride from the
  33. * width independently. winsys has a workaround that works for softpipe but may
  34. * explode for other drivers or platforms, rendering- or performance-wise.
  35. * Solving this issue properly requires extending the DRISW loader extension,
  36. * in order to make the stride available to the putImage callback.
  37. *
  38. * drisw_api:
  39. *
  40. * Define drisw_api similarly to dri_api and use it to call the loader. This is
  41. * predicated on support for calling the loader from the winsys, which has to
  42. * grow for DRI2 as well.
  43. *
  44. * xshm:
  45. *
  46. * Allow the loaders to use the XSHM extension. It probably requires callbacks
  47. * for createImage/destroyImage similar to DRI2 getBuffers. Probably not worth
  48. * it, given the scope of DRISW, unless it falls naturally from properly
  49. * solving the above two issues.
  50. *
  51. * swrast_create_screen:
  52. *
  53. * Allow for any software renderer to be used. Factor out the code from
  54. * targets/libgl-xlib/xlib.c, put it in targets/common or winsys/sw/common and
  55. * use it in all software targets.
  56. */
  57. #include "util/u_memory.h"
  58. #include "util/u_inlines.h"
  59. #include "pipe/p_context.h"
  60. #include "state_tracker/drm_api.h"
  61. #include "dri_screen.h"
  62. #include "dri_context.h"
  63. #include "dri_drawable.h"
  64. #include "dri_st_api.h"
  65. #include "dri1_helper.h"
  66. #include "drisw.h"
  67. static INLINE void
  68. get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
  69. {
  70. __DRIscreen *sPriv = dPriv->driScreenPriv;
  71. const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
  72. int x, y;
  73. loader->getDrawableInfo(dPriv,
  74. &x, &y, w, h,
  75. dPriv->loaderPrivate);
  76. }
  77. static INLINE void
  78. put_image(__DRIdrawable *dPriv, void *data)
  79. {
  80. __DRIscreen *sPriv = dPriv->driScreenPriv;
  81. const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
  82. loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
  83. 0, 0, dPriv->w, dPriv->h,
  84. data, dPriv->loaderPrivate);
  85. }
  86. void
  87. drisw_update_drawable_info(__DRIdrawable *dPriv)
  88. {
  89. get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
  90. }
  91. static INLINE void
  92. drisw_present_texture(__DRIdrawable *dPriv,
  93. struct pipe_texture *ptex)
  94. {
  95. struct dri_drawable *drawable = dri_drawable(dPriv);
  96. struct dri_screen *screen = dri_screen(drawable->sPriv);
  97. struct pipe_context *pipe;
  98. struct pipe_surface *psurf;
  99. struct pipe_transfer *ptrans;
  100. void *pmap;
  101. pipe = dri1_get_pipe_context(screen);
  102. psurf = dri1_get_pipe_surface(drawable, ptex);
  103. if (!pipe || !psurf)
  104. return;
  105. ptrans = pipe->get_tex_transfer(pipe, ptex, 0, 0, 0,
  106. PIPE_TRANSFER_READ,
  107. 0, 0, dPriv->w, dPriv->h);
  108. pmap = pipe->transfer_map(pipe, ptrans);
  109. assert(pmap);
  110. put_image(dPriv, pmap);
  111. pipe->transfer_unmap(pipe, ptrans);
  112. pipe->tex_transfer_destroy(pipe, ptrans);
  113. }
  114. static INLINE void
  115. drisw_invalidate_drawable(__DRIdrawable *dPriv)
  116. {
  117. struct dri_context *ctx = dri_get_current();
  118. struct dri_drawable *drawable = dri_drawable(dPriv);
  119. drawable->texture_stamp = dPriv->lastStamp - 1;
  120. /* check if swapping currently bound buffer */
  121. if (ctx && ctx->dPriv == dPriv)
  122. ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb);
  123. }
  124. static INLINE void
  125. drisw_copy_to_front(__DRIdrawable * dPriv,
  126. struct pipe_texture *ptex)
  127. {
  128. drisw_present_texture(dPriv, ptex);
  129. drisw_invalidate_drawable(dPriv);
  130. }
  131. /*
  132. * Backend functions for st_framebuffer interface and swap_buffers.
  133. */
  134. void
  135. drisw_flush_frontbuffer(struct dri_drawable *drawable,
  136. enum st_attachment_type statt)
  137. {
  138. struct dri_context *ctx = dri_get_current();
  139. struct pipe_texture *ptex;
  140. if (!ctx)
  141. return;
  142. ptex = drawable->textures[statt];
  143. if (ptex) {
  144. drisw_copy_to_front(ctx->dPriv, ptex);
  145. }
  146. }
  147. void
  148. drisw_swap_buffers(__DRIdrawable *dPriv)
  149. {
  150. struct dri_context *ctx = dri_get_current();
  151. struct dri_drawable *drawable = dri_drawable(dPriv);
  152. struct pipe_texture *ptex;
  153. if (!ctx)
  154. return;
  155. ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
  156. if (ptex) {
  157. ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
  158. drisw_copy_to_front(dPriv, ptex);
  159. }
  160. }
  161. /**
  162. * Allocate framebuffer attachments.
  163. *
  164. * During fixed-size operation, the function keeps allocating new attachments
  165. * as they are requested. Unused attachments are not removed, not until the
  166. * framebuffer is resized or destroyed.
  167. *
  168. * It should be possible for DRI1 and DRISW to share this function, but it
  169. * seems a better seperation and safer for each DRI version to provide its own
  170. * function.
  171. */
  172. void
  173. drisw_allocate_textures(struct dri_drawable *drawable,
  174. unsigned mask)
  175. {
  176. struct dri_screen *screen = dri_screen(drawable->sPriv);
  177. struct pipe_texture templ;
  178. unsigned width, height;
  179. boolean resized;
  180. int i;
  181. width = drawable->dPriv->w;
  182. height = drawable->dPriv->h;
  183. resized = (drawable->old_w != width ||
  184. drawable->old_h != height);
  185. /* remove outdated textures */
  186. if (resized) {
  187. for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
  188. pipe_texture_reference(&drawable->textures[i], NULL);
  189. }
  190. memset(&templ, 0, sizeof(templ));
  191. templ.target = PIPE_TEXTURE_2D;
  192. templ.width0 = width;
  193. templ.height0 = height;
  194. templ.depth0 = 1;
  195. templ.last_level = 0;
  196. for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
  197. enum pipe_format format;
  198. unsigned tex_usage;
  199. /* the texture already exists or not requested */
  200. if (drawable->textures[i] || !(mask & (1 << i))) {
  201. continue;
  202. }
  203. switch (i) {
  204. case ST_ATTACHMENT_FRONT_LEFT:
  205. case ST_ATTACHMENT_BACK_LEFT:
  206. case ST_ATTACHMENT_FRONT_RIGHT:
  207. case ST_ATTACHMENT_BACK_RIGHT:
  208. format = drawable->stvis.color_format;
  209. tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
  210. PIPE_TEXTURE_USAGE_RENDER_TARGET;
  211. break;
  212. case ST_ATTACHMENT_DEPTH_STENCIL:
  213. format = drawable->stvis.depth_stencil_format;
  214. tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
  215. break;
  216. default:
  217. format = PIPE_FORMAT_NONE;
  218. break;
  219. }
  220. if (format != PIPE_FORMAT_NONE) {
  221. templ.format = format;
  222. templ.tex_usage = tex_usage;
  223. drawable->textures[i] =
  224. screen->pipe_screen->texture_create(screen->pipe_screen, &templ);
  225. }
  226. }
  227. drawable->old_w = width;
  228. drawable->old_h = height;
  229. }
  230. /*
  231. * Backend function for init_screen.
  232. */
  233. static const __DRIextension *drisw_screen_extensions[] = {
  234. NULL
  235. };
  236. const __DRIconfig **
  237. drisw_init_screen(__DRIscreen * sPriv)
  238. {
  239. struct dri_screen *screen;
  240. struct drm_create_screen_arg arg;
  241. screen = CALLOC_STRUCT(dri_screen);
  242. if (!screen)
  243. return NULL;
  244. screen->api = drm_api_create();
  245. screen->sPriv = sPriv;
  246. screen->fd = -1;
  247. sPriv->private = (void *)screen;
  248. sPriv->extensions = drisw_screen_extensions;
  249. arg.mode = DRM_CREATE_DRISW;
  250. screen->pipe_screen = screen->api->create_screen(screen->api, -1, &arg);
  251. if (!screen->pipe_screen) {
  252. debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
  253. goto fail;
  254. }
  255. screen->smapi = dri_create_st_manager(screen);
  256. if (!screen->smapi)
  257. goto fail;
  258. driParseOptionInfo(&screen->optionCache,
  259. __driConfigOptions, __driNConfigOptions);
  260. return dri_fill_in_modes(screen, 32);
  261. fail:
  262. dri_destroy_screen(sPriv);
  263. return NULL;
  264. }
  265. /* This is the table of extensions that the loader will dlsym() for. */
  266. PUBLIC const __DRIextension *__driDriverExtensions[] = {
  267. &driCoreExtension.base,
  268. &driSWRastExtension.base,
  269. NULL
  270. };
  271. /* vim: set sw=3 ts=8 sts=3 expandtab: */