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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. /**************************************************************************
  2. *
  3. * Copyright 2006 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. /*
  28. * Authors:
  29. * Keith Whitwell <keith@tungstengraphics.com>
  30. * Michel Dänzer <michel@tungstengraphics.com>
  31. */
  32. #include "pipe/p_state.h"
  33. #include "pipe/p_context.h"
  34. #include "pipe/p_defines.h"
  35. #include "util/u_inlines.h"
  36. #include "util/u_format.h"
  37. #include "util/u_math.h"
  38. #include "util/u_memory.h"
  39. #include "i915_context.h"
  40. #include "i915_texture.h"
  41. #include "i915_screen.h"
  42. #include "intel_winsys.h"
  43. /*
  44. * Helper function and arrays
  45. */
  46. /**
  47. * Initial offset for Cube map.
  48. */
  49. static const int initial_offsets[6][2] = {
  50. {0, 0},
  51. {0, 2},
  52. {1, 0},
  53. {1, 2},
  54. {1, 1},
  55. {1, 3}
  56. };
  57. /**
  58. * Step offsets for Cube map.
  59. */
  60. static const int step_offsets[6][2] = {
  61. {0, 2},
  62. {0, 2},
  63. {-1, 2},
  64. {-1, 2},
  65. {-1, 1},
  66. {-1, 1}
  67. };
  68. /* XXX really need twice the size if x is already pot?
  69. Otherwise just use util_next_power_of_two?
  70. */
  71. static unsigned
  72. power_of_two(unsigned x)
  73. {
  74. unsigned value = 1;
  75. while (value < x)
  76. value = value << 1;
  77. return value;
  78. }
  79. /*
  80. * More advanced helper funcs
  81. */
  82. static void
  83. i915_miptree_set_level_info(struct i915_texture *tex,
  84. unsigned level,
  85. unsigned nr_images,
  86. unsigned w, unsigned h, unsigned d)
  87. {
  88. assert(level < Elements(tex->nr_images));
  89. tex->nr_images[level] = nr_images;
  90. /*
  91. DBG("%s level %d size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
  92. level, w, h, d, x, y, tex->level_offset[level]);
  93. */
  94. /* Not sure when this would happen, but anyway:
  95. */
  96. if (tex->image_offset[level]) {
  97. FREE(tex->image_offset[level]);
  98. tex->image_offset[level] = NULL;
  99. }
  100. assert(nr_images);
  101. assert(!tex->image_offset[level]);
  102. tex->image_offset[level] = (unsigned *) MALLOC(nr_images * sizeof(unsigned));
  103. tex->image_offset[level][0] = 0;
  104. }
  105. static void
  106. i915_miptree_set_image_offset(struct i915_texture *tex,
  107. unsigned level, unsigned img, unsigned x, unsigned y)
  108. {
  109. if (img == 0 && level == 0)
  110. assert(x == 0 && y == 0);
  111. assert(img < tex->nr_images[level]);
  112. tex->image_offset[level][img] = y * tex->stride + x * util_format_get_blocksize(tex->base.format);
  113. /*
  114. printf("%s level %d img %d pos %d,%d image_offset %x\n",
  115. __FUNCTION__, level, img, x, y, tex->image_offset[level][img]);
  116. */
  117. }
  118. /*
  119. * i915 layout functions, some used by i945
  120. */
  121. /**
  122. * Special case to deal with scanout textures.
  123. */
  124. static boolean
  125. i915_scanout_layout(struct i915_texture *tex)
  126. {
  127. struct pipe_texture *pt = &tex->base;
  128. if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4)
  129. return FALSE;
  130. i915_miptree_set_level_info(tex, 0, 1,
  131. pt->width0,
  132. pt->height0,
  133. 1);
  134. i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
  135. if (pt->width0 >= 240) {
  136. tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
  137. tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
  138. tex->hw_tiled = INTEL_TILE_X;
  139. } else if (pt->width0 == 64 && pt->height0 == 64) {
  140. tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
  141. tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
  142. } else {
  143. return FALSE;
  144. }
  145. debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
  146. pt->width0, pt->height0, util_format_get_blocksize(pt->format),
  147. tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
  148. return TRUE;
  149. }
  150. /**
  151. * Special case to deal with shared textures.
  152. */
  153. static boolean
  154. i915_display_target_layout(struct i915_texture *tex)
  155. {
  156. struct pipe_texture *pt = &tex->base;
  157. if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4)
  158. return FALSE;
  159. /* fallback to normal textures for small textures */
  160. if (pt->width0 < 240)
  161. return FALSE;
  162. i915_miptree_set_level_info(tex, 0, 1,
  163. pt->width0,
  164. pt->height0,
  165. 1);
  166. i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
  167. tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
  168. tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
  169. tex->hw_tiled = INTEL_TILE_X;
  170. debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
  171. pt->width0, pt->height0, util_format_get_blocksize(pt->format),
  172. tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
  173. return TRUE;
  174. }
  175. static void
  176. i915_miptree_layout_2d(struct i915_texture *tex)
  177. {
  178. struct pipe_texture *pt = &tex->base;
  179. unsigned level;
  180. unsigned width = pt->width0;
  181. unsigned height = pt->height0;
  182. unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
  183. /* used for scanouts that need special layouts */
  184. if (pt->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
  185. if (i915_scanout_layout(tex))
  186. return;
  187. /* shared buffers needs to be compatible with X servers */
  188. if (pt->tex_usage & PIPE_TEXTURE_USAGE_SHARED)
  189. if (i915_display_target_layout(tex))
  190. return;
  191. tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
  192. tex->total_nblocksy = 0;
  193. for (level = 0; level <= pt->last_level; level++) {
  194. i915_miptree_set_level_info(tex, level, 1, width, height, 1);
  195. i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);
  196. nblocksy = align(MAX2(2, nblocksy), 2);
  197. tex->total_nblocksy += nblocksy;
  198. width = u_minify(width, 1);
  199. height = u_minify(height, 1);
  200. nblocksy = util_format_get_nblocksy(pt->format, height);
  201. }
  202. }
  203. static void
  204. i915_miptree_layout_3d(struct i915_texture *tex)
  205. {
  206. struct pipe_texture *pt = &tex->base;
  207. unsigned level;
  208. unsigned width = pt->width0;
  209. unsigned height = pt->height0;
  210. unsigned depth = pt->depth0;
  211. unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
  212. unsigned stack_nblocksy = 0;
  213. /* Calculate the size of a single slice.
  214. */
  215. tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
  216. /* XXX: hardware expects/requires 9 levels at minimum.
  217. */
  218. for (level = 0; level <= MAX2(8, pt->last_level); level++) {
  219. i915_miptree_set_level_info(tex, level, depth, width, height, depth);
  220. stack_nblocksy += MAX2(2, nblocksy);
  221. width = u_minify(width, 1);
  222. height = u_minify(height, 1);
  223. nblocksy = util_format_get_nblocksy(pt->format, height);
  224. }
  225. /* Fixup depth image_offsets:
  226. */
  227. for (level = 0; level <= pt->last_level; level++) {
  228. unsigned i;
  229. for (i = 0; i < depth; i++)
  230. i915_miptree_set_image_offset(tex, level, i, 0, i * stack_nblocksy);
  231. depth = u_minify(depth, 1);
  232. }
  233. /* Multiply slice size by texture depth for total size. It's
  234. * remarkable how wasteful of memory the i915 texture layouts
  235. * are. They are largely fixed in the i945.
  236. */
  237. tex->total_nblocksy = stack_nblocksy * pt->depth0;
  238. }
  239. static void
  240. i915_miptree_layout_cube(struct i915_texture *tex)
  241. {
  242. struct pipe_texture *pt = &tex->base;
  243. unsigned width = pt->width0, height = pt->height0;
  244. const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0);
  245. unsigned level;
  246. unsigned face;
  247. assert(width == height); /* cubemap images are square */
  248. /* double pitch for cube layouts */
  249. tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4);
  250. tex->total_nblocksy = nblocks * 4;
  251. for (level = 0; level <= pt->last_level; level++) {
  252. i915_miptree_set_level_info(tex, level, 6, width, height, 1);
  253. width /= 2;
  254. height /= 2;
  255. }
  256. for (face = 0; face < 6; face++) {
  257. unsigned x = initial_offsets[face][0] * nblocks;
  258. unsigned y = initial_offsets[face][1] * nblocks;
  259. unsigned d = nblocks;
  260. for (level = 0; level <= pt->last_level; level++) {
  261. i915_miptree_set_image_offset(tex, level, face, x, y);
  262. d >>= 1;
  263. x += step_offsets[face][0] * d;
  264. y += step_offsets[face][1] * d;
  265. }
  266. }
  267. }
  268. static boolean
  269. i915_miptree_layout(struct i915_texture * tex)
  270. {
  271. struct pipe_texture *pt = &tex->base;
  272. switch (pt->target) {
  273. case PIPE_TEXTURE_1D:
  274. case PIPE_TEXTURE_2D:
  275. i915_miptree_layout_2d(tex);
  276. break;
  277. case PIPE_TEXTURE_3D:
  278. i915_miptree_layout_3d(tex);
  279. break;
  280. case PIPE_TEXTURE_CUBE:
  281. i915_miptree_layout_cube(tex);
  282. break;
  283. default:
  284. assert(0);
  285. return FALSE;
  286. }
  287. return TRUE;
  288. }
  289. /*
  290. * i945 layout functions
  291. */
  292. static void
  293. i945_miptree_layout_2d(struct i915_texture *tex)
  294. {
  295. struct pipe_texture *pt = &tex->base;
  296. const int align_x = 2, align_y = 4;
  297. unsigned level;
  298. unsigned x = 0;
  299. unsigned y = 0;
  300. unsigned width = pt->width0;
  301. unsigned height = pt->height0;
  302. unsigned nblocksx = util_format_get_nblocksx(pt->format, pt->width0);
  303. unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->height0);
  304. /* used for scanouts that need special layouts */
  305. if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SCANOUT)
  306. if (i915_scanout_layout(tex))
  307. return;
  308. /* shared buffers needs to be compatible with X servers */
  309. if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_SHARED)
  310. if (i915_display_target_layout(tex))
  311. return;
  312. tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
  313. /* May need to adjust pitch to accomodate the placement of
  314. * the 2nd mipmap level. This occurs when the alignment
  315. * constraints of mipmap placement push the right edge of the
  316. * 2nd mipmap level out past the width of its parent.
  317. */
  318. if (pt->last_level > 0) {
  319. unsigned mip1_nblocksx
  320. = align(util_format_get_nblocksx(pt->format, u_minify(width, 1)), align_x)
  321. + util_format_get_nblocksx(pt->format, u_minify(width, 2));
  322. if (mip1_nblocksx > nblocksx)
  323. tex->stride = mip1_nblocksx * util_format_get_blocksize(pt->format);
  324. }
  325. /* Pitch must be a whole number of dwords
  326. */
  327. tex->stride = align(tex->stride, 64);
  328. tex->total_nblocksy = 0;
  329. for (level = 0; level <= pt->last_level; level++) {
  330. i915_miptree_set_level_info(tex, level, 1, width, height, 1);
  331. i915_miptree_set_image_offset(tex, level, 0, x, y);
  332. nblocksy = align(nblocksy, align_y);
  333. /* Because the images are packed better, the final offset
  334. * might not be the maximal one:
  335. */
  336. tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy);
  337. /* Layout_below: step right after second mipmap level.
  338. */
  339. if (level == 1) {
  340. x += align(nblocksx, align_x);
  341. }
  342. else {
  343. y += nblocksy;
  344. }
  345. width = u_minify(width, 1);
  346. height = u_minify(height, 1);
  347. nblocksx = util_format_get_nblocksx(pt->format, width);
  348. nblocksy = util_format_get_nblocksy(pt->format, height);
  349. }
  350. }
  351. static void
  352. i945_miptree_layout_3d(struct i915_texture *tex)
  353. {
  354. struct pipe_texture *pt = &tex->base;
  355. unsigned width = pt->width0;
  356. unsigned height = pt->height0;
  357. unsigned depth = pt->depth0;
  358. unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);
  359. unsigned pack_x_pitch, pack_x_nr;
  360. unsigned pack_y_pitch;
  361. unsigned level;
  362. tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
  363. tex->total_nblocksy = 0;
  364. pack_y_pitch = MAX2(nblocksy, 2);
  365. pack_x_pitch = tex->stride / util_format_get_blocksize(pt->format);
  366. pack_x_nr = 1;
  367. for (level = 0; level <= pt->last_level; level++) {
  368. int x = 0;
  369. int y = 0;
  370. unsigned q, j;
  371. i915_miptree_set_level_info(tex, level, depth, width, height, depth);
  372. for (q = 0; q < depth;) {
  373. for (j = 0; j < pack_x_nr && q < depth; j++, q++) {
  374. i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
  375. x += pack_x_pitch;
  376. }
  377. x = 0;
  378. y += pack_y_pitch;
  379. }
  380. tex->total_nblocksy += y;
  381. if (pack_x_pitch > 4) {
  382. pack_x_pitch >>= 1;
  383. pack_x_nr <<= 1;
  384. assert(pack_x_pitch * pack_x_nr * util_format_get_blocksize(pt->format) <= tex->stride);
  385. }
  386. if (pack_y_pitch > 2) {
  387. pack_y_pitch >>= 1;
  388. }
  389. width = u_minify(width, 1);
  390. height = u_minify(height, 1);
  391. depth = u_minify(depth, 1);
  392. nblocksy = util_format_get_nblocksy(pt->format, height);
  393. }
  394. }
  395. static void
  396. i945_miptree_layout_cube(struct i915_texture *tex)
  397. {
  398. struct pipe_texture *pt = &tex->base;
  399. unsigned level;
  400. const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0);
  401. unsigned face;
  402. unsigned width = pt->width0;
  403. unsigned height = pt->height0;
  404. /*
  405. printf("%s %i, %i\n", __FUNCTION__, pt->width0, pt->height0);
  406. */
  407. assert(width == height); /* cubemap images are square */
  408. /*
  409. * XXX Should only be used for compressed formats. But lets
  410. * keep this code active just in case.
  411. *
  412. * Depending on the size of the largest images, pitch can be
  413. * determined either by the old-style packing of cubemap faces,
  414. * or the final row of 4x4, 2x2 and 1x1 faces below this.
  415. */
  416. if (nblocks > 32)
  417. tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4);
  418. else
  419. tex->stride = 14 * 8 * util_format_get_blocksize(pt->format);
  420. tex->total_nblocksy = nblocks * 4;
  421. /* Set all the levels to effectively occupy the whole rectangular region.
  422. */
  423. for (level = 0; level <= pt->last_level; level++) {
  424. i915_miptree_set_level_info(tex, level, 6, width, height, 1);
  425. width /= 2;
  426. height /= 2;
  427. }
  428. for (face = 0; face < 6; face++) {
  429. unsigned x = initial_offsets[face][0] * nblocks;
  430. unsigned y = initial_offsets[face][1] * nblocks;
  431. unsigned d = nblocks;
  432. #if 0 /* Fix and enable this code for compressed formats */
  433. if (nblocks == 4 && face >= 4) {
  434. y = tex->total_height - 4;
  435. x = (face - 4) * 8;
  436. }
  437. else if (nblocks < 4 && (face > 0)) {
  438. y = tex->total_height - 4;
  439. x = face * 8;
  440. }
  441. #endif
  442. for (level = 0; level <= pt->last_level; level++) {
  443. i915_miptree_set_image_offset(tex, level, face, x, y);
  444. d >>= 1;
  445. #if 0 /* Fix and enable this code for compressed formats */
  446. switch (d) {
  447. case 4:
  448. switch (face) {
  449. case PIPE_TEX_FACE_POS_X:
  450. case PIPE_TEX_FACE_NEG_X:
  451. x += step_offsets[face][0] * d;
  452. y += step_offsets[face][1] * d;
  453. break;
  454. case PIPE_TEX_FACE_POS_Y:
  455. case PIPE_TEX_FACE_NEG_Y:
  456. y += 12;
  457. x -= 8;
  458. break;
  459. case PIPE_TEX_FACE_POS_Z:
  460. case PIPE_TEX_FACE_NEG_Z:
  461. y = tex->total_height - 4;
  462. x = (face - 4) * 8;
  463. break;
  464. }
  465. case 2:
  466. y = tex->total_height - 4;
  467. x = 16 + face * 8;
  468. break;
  469. case 1:
  470. x += 48;
  471. break;
  472. default:
  473. #endif
  474. x += step_offsets[face][0] * d;
  475. y += step_offsets[face][1] * d;
  476. #if 0
  477. break;
  478. }
  479. #endif
  480. }
  481. }
  482. }
  483. static boolean
  484. i945_miptree_layout(struct i915_texture * tex)
  485. {
  486. struct pipe_texture *pt = &tex->base;
  487. switch (pt->target) {
  488. case PIPE_TEXTURE_1D:
  489. case PIPE_TEXTURE_2D:
  490. i945_miptree_layout_2d(tex);
  491. break;
  492. case PIPE_TEXTURE_3D:
  493. i945_miptree_layout_3d(tex);
  494. break;
  495. case PIPE_TEXTURE_CUBE:
  496. i945_miptree_layout_cube(tex);
  497. break;
  498. default:
  499. assert(0);
  500. return FALSE;
  501. }
  502. return TRUE;
  503. }
  504. /*
  505. * Screen texture functions
  506. */
  507. static struct pipe_texture *
  508. i915_texture_create(struct pipe_screen *screen,
  509. const struct pipe_texture *templat)
  510. {
  511. struct i915_screen *is = i915_screen(screen);
  512. struct intel_winsys *iws = is->iws;
  513. struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
  514. size_t tex_size;
  515. unsigned buf_usage = 0;
  516. if (!tex)
  517. return NULL;
  518. tex->base = *templat;
  519. pipe_reference_init(&tex->base.reference, 1);
  520. tex->base.screen = screen;
  521. if (is->is_i945) {
  522. if (!i945_miptree_layout(tex))
  523. goto fail;
  524. } else {
  525. if (!i915_miptree_layout(tex))
  526. goto fail;
  527. }
  528. tex_size = tex->stride * tex->total_nblocksy;
  529. /* for scanouts and cursors, cursors arn't scanouts */
  530. if (templat->tex_usage & PIPE_TEXTURE_USAGE_SCANOUT && templat->width0 != 64)
  531. buf_usage = INTEL_NEW_SCANOUT;
  532. else
  533. buf_usage = INTEL_NEW_TEXTURE;
  534. tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
  535. if (!tex->buffer)
  536. goto fail;
  537. /* setup any hw fences */
  538. if (tex->hw_tiled) {
  539. assert(tex->sw_tiled == INTEL_TILE_NONE);
  540. iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->hw_tiled);
  541. }
  542. #if 0
  543. void *ptr = ws->buffer_map(ws, tex->buffer,
  544. PIPE_BUFFER_USAGE_CPU_WRITE);
  545. memset(ptr, 0x80, tex_size);
  546. ws->buffer_unmap(ws, tex->buffer);
  547. #endif
  548. return &tex->base;
  549. fail:
  550. FREE(tex);
  551. return NULL;
  552. }
  553. static struct pipe_texture *
  554. i915_texture_from_handle(struct pipe_screen * screen,
  555. const struct pipe_texture *templat,
  556. struct winsys_handle *whandle)
  557. {
  558. struct i915_screen *is = i915_screen(screen);
  559. struct i915_texture *tex;
  560. struct intel_winsys *iws = is->iws;
  561. struct intel_buffer *buffer;
  562. unsigned stride;
  563. assert(screen);
  564. buffer = iws->buffer_from_handle(iws, whandle, &stride);
  565. /* Only supports one type */
  566. if (templat->target != PIPE_TEXTURE_2D ||
  567. templat->last_level != 0 ||
  568. templat->depth0 != 1) {
  569. return NULL;
  570. }
  571. tex = CALLOC_STRUCT(i915_texture);
  572. if (!tex)
  573. return NULL;
  574. tex->base = *templat;
  575. pipe_reference_init(&tex->base.reference, 1);
  576. tex->base.screen = screen;
  577. tex->stride = stride;
  578. i915_miptree_set_level_info(tex, 0, 1, templat->width0, templat->height0, 1);
  579. i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
  580. tex->buffer = buffer;
  581. return &tex->base;
  582. }
  583. static boolean
  584. i915_texture_get_handle(struct pipe_screen * screen,
  585. struct pipe_texture *texture,
  586. struct winsys_handle *whandle)
  587. {
  588. struct i915_screen *is = i915_screen(screen);
  589. struct i915_texture *tex = (struct i915_texture *)texture;
  590. struct intel_winsys *iws = is->iws;
  591. return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride);
  592. }
  593. static void
  594. i915_texture_destroy(struct pipe_texture *pt)
  595. {
  596. struct i915_texture *tex = (struct i915_texture *)pt;
  597. struct intel_winsys *iws = i915_screen(pt->screen)->iws;
  598. uint i;
  599. /*
  600. DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
  601. */
  602. iws->buffer_destroy(iws, tex->buffer);
  603. for (i = 0; i < Elements(tex->image_offset); i++)
  604. if (tex->image_offset[i])
  605. FREE(tex->image_offset[i]);
  606. FREE(tex);
  607. }
  608. /*
  609. * Screen surface functions
  610. */
  611. static struct pipe_surface *
  612. i915_get_tex_surface(struct pipe_screen *screen,
  613. struct pipe_texture *pt,
  614. unsigned face, unsigned level, unsigned zslice,
  615. unsigned flags)
  616. {
  617. struct i915_texture *tex = (struct i915_texture *)pt;
  618. struct pipe_surface *ps;
  619. unsigned offset; /* in bytes */
  620. if (pt->target == PIPE_TEXTURE_CUBE) {
  621. offset = tex->image_offset[level][face];
  622. }
  623. else if (pt->target == PIPE_TEXTURE_3D) {
  624. offset = tex->image_offset[level][zslice];
  625. }
  626. else {
  627. offset = tex->image_offset[level][0];
  628. assert(face == 0);
  629. assert(zslice == 0);
  630. }
  631. ps = CALLOC_STRUCT(pipe_surface);
  632. if (ps) {
  633. pipe_reference_init(&ps->reference, 1);
  634. pipe_texture_reference(&ps->texture, pt);
  635. ps->format = pt->format;
  636. ps->width = u_minify(pt->width0, level);
  637. ps->height = u_minify(pt->height0, level);
  638. ps->offset = offset;
  639. ps->usage = flags;
  640. }
  641. return ps;
  642. }
  643. static void
  644. i915_tex_surface_destroy(struct pipe_surface *surf)
  645. {
  646. pipe_texture_reference(&surf->texture, NULL);
  647. FREE(surf);
  648. }
  649. /*
  650. * Texture transfer functions
  651. */
  652. static struct pipe_transfer *
  653. i915_get_tex_transfer(struct pipe_context *pipe,
  654. struct pipe_texture *texture,
  655. unsigned face, unsigned level, unsigned zslice,
  656. enum pipe_transfer_usage usage, unsigned x, unsigned y,
  657. unsigned w, unsigned h)
  658. {
  659. struct i915_texture *tex = (struct i915_texture *)texture;
  660. struct i915_transfer *trans;
  661. unsigned offset; /* in bytes */
  662. if (texture->target == PIPE_TEXTURE_CUBE) {
  663. offset = tex->image_offset[level][face];
  664. }
  665. else if (texture->target == PIPE_TEXTURE_3D) {
  666. offset = tex->image_offset[level][zslice];
  667. }
  668. else {
  669. offset = tex->image_offset[level][0];
  670. assert(face == 0);
  671. assert(zslice == 0);
  672. }
  673. trans = CALLOC_STRUCT(i915_transfer);
  674. if (trans) {
  675. pipe_texture_reference(&trans->base.texture, texture);
  676. trans->base.x = x;
  677. trans->base.y = y;
  678. trans->base.width = w;
  679. trans->base.height = h;
  680. trans->base.stride = tex->stride;
  681. trans->offset = offset;
  682. trans->base.usage = usage;
  683. }
  684. return &trans->base;
  685. }
  686. static void *
  687. i915_transfer_map(struct pipe_context *pipe,
  688. struct pipe_transfer *transfer)
  689. {
  690. struct i915_texture *tex = (struct i915_texture *)transfer->texture;
  691. struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
  692. char *map;
  693. boolean write = FALSE;
  694. enum pipe_format format = tex->base.format;
  695. if (transfer->usage & PIPE_TRANSFER_WRITE)
  696. write = TRUE;
  697. map = iws->buffer_map(iws, tex->buffer, write);
  698. if (map == NULL)
  699. return NULL;
  700. return map + i915_transfer(transfer)->offset +
  701. transfer->y / util_format_get_blockheight(format) * transfer->stride +
  702. transfer->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
  703. }
  704. static void
  705. i915_transfer_unmap(struct pipe_context *pipe,
  706. struct pipe_transfer *transfer)
  707. {
  708. struct i915_texture *tex = (struct i915_texture *)transfer->texture;
  709. struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
  710. iws->buffer_unmap(iws, tex->buffer);
  711. }
  712. static void
  713. i915_tex_transfer_destroy(struct pipe_context *pipe,
  714. struct pipe_transfer *trans)
  715. {
  716. pipe_texture_reference(&trans->texture, NULL);
  717. FREE(trans);
  718. }
  719. /*
  720. * Other texture functions
  721. */
  722. void
  723. i915_init_texture_functions(struct i915_context *i915 )
  724. {
  725. i915->base.get_tex_transfer = i915_get_tex_transfer;
  726. i915->base.transfer_map = i915_transfer_map;
  727. i915->base.transfer_unmap = i915_transfer_unmap;
  728. i915->base.tex_transfer_destroy = i915_tex_transfer_destroy;
  729. }
  730. void
  731. i915_init_screen_texture_functions(struct i915_screen *is)
  732. {
  733. is->base.texture_create = i915_texture_create;
  734. is->base.texture_from_handle = i915_texture_from_handle;
  735. is->base.texture_get_handle = i915_texture_get_handle;
  736. is->base.texture_destroy = i915_texture_destroy;
  737. is->base.get_tex_surface = i915_get_tex_surface;
  738. is->base.tex_surface_destroy = i915_tex_surface_destroy;
  739. }