Clone of mesa.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004
  1. /*
  2. * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
  3. * Copyright 2010 Marek Olšák <maraeo@gmail.com>
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * on the rights to use, copy, modify, merge, publish, distribute, sub
  9. * license, and/or sell copies of the Software, and to permit persons to whom
  10. * the Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice (including the next
  13. * paragraph) shall be included in all copies or substantial portions of the
  14. * Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22. * USE OR OTHER DEALINGS IN THE SOFTWARE. */
  23. #include "pipe/p_screen.h"
  24. #include "util/u_format.h"
  25. #include "util/u_math.h"
  26. #include "util/u_memory.h"
  27. #include "r300_context.h"
  28. #include "r300_texture.h"
  29. #include "r300_transfer.h"
  30. #include "r300_screen.h"
  31. #include "r300_state_inlines.h"
  32. #include "r300_winsys.h"
  33. #define TILE_WIDTH 0
  34. #define TILE_HEIGHT 1
  35. static const unsigned microblock_table[5][3][2] = {
  36. /*linear tiled square-tiled */
  37. {{32, 1}, {8, 4}, {0, 0}}, /* 8 bits per pixel */
  38. {{16, 1}, {8, 2}, {4, 4}}, /* 16 bits per pixel */
  39. {{ 8, 1}, {4, 2}, {0, 0}}, /* 32 bits per pixel */
  40. {{ 4, 1}, {0, 0}, {2, 2}}, /* 64 bits per pixel */
  41. {{ 2, 1}, {0, 0}, {0, 0}} /* 128 bits per pixel */
  42. };
  43. /* Return true for non-compressed and non-YUV formats. */
  44. static boolean r300_format_is_plain(enum pipe_format format)
  45. {
  46. const struct util_format_description *desc = util_format_description(format);
  47. if (!format) {
  48. return FALSE;
  49. }
  50. return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN;
  51. }
  52. /* Translate a pipe_format into a useful texture format for sampling.
  53. *
  54. * Some special formats are translated directly using R300_EASY_TX_FORMAT,
  55. * but the majority of them is translated in a generic way, automatically
  56. * supporting all the formats hw can support.
  57. *
  58. * R300_EASY_TX_FORMAT swizzles the texture.
  59. * Note the signature of R300_EASY_TX_FORMAT:
  60. * R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
  61. *
  62. * The FORMAT specifies how the texture sampler will treat the texture, and
  63. * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
  64. static uint32_t r300_translate_texformat(enum pipe_format format)
  65. {
  66. uint32_t result = 0;
  67. const struct util_format_description *desc;
  68. unsigned components = 0, i;
  69. boolean uniform = TRUE;
  70. const uint32_t swizzle_shift[4] = {
  71. R300_TX_FORMAT_R_SHIFT,
  72. R300_TX_FORMAT_G_SHIFT,
  73. R300_TX_FORMAT_B_SHIFT,
  74. R300_TX_FORMAT_A_SHIFT
  75. };
  76. const uint32_t swizzle[4] = {
  77. R300_TX_FORMAT_X,
  78. R300_TX_FORMAT_Y,
  79. R300_TX_FORMAT_Z,
  80. R300_TX_FORMAT_W
  81. };
  82. const uint32_t sign_bit[4] = {
  83. R300_TX_FORMAT_SIGNED_X,
  84. R300_TX_FORMAT_SIGNED_Y,
  85. R300_TX_FORMAT_SIGNED_Z,
  86. R300_TX_FORMAT_SIGNED_W,
  87. };
  88. desc = util_format_description(format);
  89. /* Colorspace (return non-RGB formats directly). */
  90. switch (desc->colorspace) {
  91. /* Depth stencil formats. */
  92. case UTIL_FORMAT_COLORSPACE_ZS:
  93. switch (format) {
  94. case PIPE_FORMAT_Z16_UNORM:
  95. return R300_EASY_TX_FORMAT(X, X, X, X, X16);
  96. case PIPE_FORMAT_X8Z24_UNORM:
  97. case PIPE_FORMAT_S8Z24_UNORM:
  98. return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
  99. default:
  100. return ~0; /* Unsupported. */
  101. }
  102. /* YUV formats. */
  103. case UTIL_FORMAT_COLORSPACE_YUV:
  104. result |= R300_TX_FORMAT_YUV_TO_RGB;
  105. switch (format) {
  106. case PIPE_FORMAT_UYVY:
  107. return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
  108. case PIPE_FORMAT_YUYV:
  109. return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
  110. default:
  111. return ~0; /* Unsupported/unknown. */
  112. }
  113. /* Add gamma correction. */
  114. case UTIL_FORMAT_COLORSPACE_SRGB:
  115. result |= R300_TX_FORMAT_GAMMA;
  116. break;
  117. default:;
  118. }
  119. /* Add swizzle. */
  120. for (i = 0; i < 4; i++) {
  121. switch (desc->swizzle[i]) {
  122. case UTIL_FORMAT_SWIZZLE_X:
  123. case UTIL_FORMAT_SWIZZLE_NONE:
  124. result |= swizzle[0] << swizzle_shift[i];
  125. break;
  126. case UTIL_FORMAT_SWIZZLE_Y:
  127. result |= swizzle[1] << swizzle_shift[i];
  128. break;
  129. case UTIL_FORMAT_SWIZZLE_Z:
  130. result |= swizzle[2] << swizzle_shift[i];
  131. break;
  132. case UTIL_FORMAT_SWIZZLE_W:
  133. result |= swizzle[3] << swizzle_shift[i];
  134. break;
  135. case UTIL_FORMAT_SWIZZLE_0:
  136. result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
  137. break;
  138. case UTIL_FORMAT_SWIZZLE_1:
  139. result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
  140. break;
  141. default:
  142. return ~0; /* Unsupported. */
  143. }
  144. }
  145. /* Compressed formats. */
  146. if (desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED) {
  147. switch (format) {
  148. case PIPE_FORMAT_DXT1_RGB:
  149. case PIPE_FORMAT_DXT1_RGBA:
  150. case PIPE_FORMAT_DXT1_SRGB:
  151. case PIPE_FORMAT_DXT1_SRGBA:
  152. return R300_TX_FORMAT_DXT1 | result;
  153. case PIPE_FORMAT_DXT3_RGBA:
  154. case PIPE_FORMAT_DXT3_SRGBA:
  155. return R300_TX_FORMAT_DXT3 | result;
  156. case PIPE_FORMAT_DXT5_RGBA:
  157. case PIPE_FORMAT_DXT5_SRGBA:
  158. return R300_TX_FORMAT_DXT5 | result;
  159. default:
  160. return ~0; /* Unsupported/unknown. */
  161. }
  162. }
  163. /* Get the number of components. */
  164. for (i = 0; i < 4; i++) {
  165. if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
  166. ++components;
  167. }
  168. }
  169. /* Add sign. */
  170. for (i = 0; i < components; i++) {
  171. if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
  172. result |= sign_bit[i];
  173. }
  174. }
  175. /* See whether the components are of the same size. */
  176. for (i = 1; i < components; i++) {
  177. uniform = uniform && desc->channel[0].size == desc->channel[i].size;
  178. }
  179. /* Non-uniform formats. */
  180. if (!uniform) {
  181. switch (components) {
  182. case 3:
  183. if (desc->channel[0].size == 5 &&
  184. desc->channel[1].size == 6 &&
  185. desc->channel[2].size == 5) {
  186. return R300_TX_FORMAT_Z5Y6X5 | result;
  187. }
  188. if (desc->channel[0].size == 5 &&
  189. desc->channel[1].size == 5 &&
  190. desc->channel[2].size == 6) {
  191. return R300_TX_FORMAT_Z6Y5X5 | result;
  192. }
  193. return ~0; /* Unsupported/unknown. */
  194. case 4:
  195. if (desc->channel[0].size == 5 &&
  196. desc->channel[1].size == 5 &&
  197. desc->channel[2].size == 5 &&
  198. desc->channel[3].size == 1) {
  199. return R300_TX_FORMAT_W1Z5Y5X5 | result;
  200. }
  201. if (desc->channel[0].size == 10 &&
  202. desc->channel[1].size == 10 &&
  203. desc->channel[2].size == 10 &&
  204. desc->channel[3].size == 2) {
  205. return R300_TX_FORMAT_W2Z10Y10X10 | result;
  206. }
  207. }
  208. return ~0; /* Unsupported/unknown. */
  209. }
  210. /* And finally, uniform formats. */
  211. switch (desc->channel[0].type) {
  212. case UTIL_FORMAT_TYPE_UNSIGNED:
  213. case UTIL_FORMAT_TYPE_SIGNED:
  214. if (!desc->channel[0].normalized &&
  215. desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
  216. return ~0;
  217. }
  218. switch (desc->channel[0].size) {
  219. case 4:
  220. switch (components) {
  221. case 2:
  222. return R300_TX_FORMAT_Y4X4 | result;
  223. case 4:
  224. return R300_TX_FORMAT_W4Z4Y4X4 | result;
  225. }
  226. return ~0;
  227. case 8:
  228. switch (components) {
  229. case 1:
  230. return R300_TX_FORMAT_X8 | result;
  231. case 2:
  232. return R300_TX_FORMAT_Y8X8 | result;
  233. case 4:
  234. return R300_TX_FORMAT_W8Z8Y8X8 | result;
  235. }
  236. return ~0;
  237. case 16:
  238. switch (components) {
  239. case 1:
  240. return R300_TX_FORMAT_X16 | result;
  241. case 2:
  242. return R300_TX_FORMAT_Y16X16 | result;
  243. case 4:
  244. return R300_TX_FORMAT_W16Z16Y16X16 | result;
  245. }
  246. }
  247. return ~0;
  248. /* XXX Enable float textures here. */
  249. #if 0
  250. case UTIL_FORMAT_TYPE_FLOAT:
  251. switch (desc->channel[0].size) {
  252. case 16:
  253. switch (components) {
  254. case 1:
  255. return R300_TX_FORMAT_16F | result;
  256. case 2:
  257. return R300_TX_FORMAT_16F_16F | result;
  258. case 4:
  259. return R300_TX_FORMAT_16F_16F_16F_16F | result;
  260. }
  261. return ~0;
  262. case 32:
  263. switch (components) {
  264. case 1:
  265. return R300_TX_FORMAT_32F | result;
  266. case 2:
  267. return R300_TX_FORMAT_32F_32F | result;
  268. case 4:
  269. return R300_TX_FORMAT_32F_32F_32F_32F | result;
  270. }
  271. }
  272. #endif
  273. }
  274. return ~0; /* Unsupported/unknown. */
  275. }
  276. /* Buffer formats. */
  277. /* Colorbuffer formats. This is the unswizzled format of the RB3D block's
  278. * output. For the swizzling of the targets, check the shader's format. */
  279. static uint32_t r300_translate_colorformat(enum pipe_format format)
  280. {
  281. switch (format) {
  282. /* 8-bit buffers. */
  283. case PIPE_FORMAT_A8_UNORM:
  284. case PIPE_FORMAT_I8_UNORM:
  285. case PIPE_FORMAT_L8_UNORM:
  286. case PIPE_FORMAT_R8_UNORM:
  287. case PIPE_FORMAT_R8_SNORM:
  288. return R300_COLOR_FORMAT_I8;
  289. /* 16-bit buffers. */
  290. case PIPE_FORMAT_B5G6R5_UNORM:
  291. return R300_COLOR_FORMAT_RGB565;
  292. case PIPE_FORMAT_B5G5R5A1_UNORM:
  293. case PIPE_FORMAT_B5G5R5X1_UNORM:
  294. return R300_COLOR_FORMAT_ARGB1555;
  295. case PIPE_FORMAT_B4G4R4A4_UNORM:
  296. return R300_COLOR_FORMAT_ARGB4444;
  297. /* 32-bit buffers. */
  298. case PIPE_FORMAT_B8G8R8A8_UNORM:
  299. case PIPE_FORMAT_B8G8R8X8_UNORM:
  300. case PIPE_FORMAT_A8R8G8B8_UNORM:
  301. case PIPE_FORMAT_X8R8G8B8_UNORM:
  302. case PIPE_FORMAT_A8B8G8R8_UNORM:
  303. case PIPE_FORMAT_R8G8B8A8_SNORM:
  304. case PIPE_FORMAT_X8B8G8R8_UNORM:
  305. case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
  306. return R300_COLOR_FORMAT_ARGB8888;
  307. case PIPE_FORMAT_R10G10B10A2_UNORM:
  308. return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */
  309. /* 64-bit buffers. */
  310. case PIPE_FORMAT_R16G16B16A16_UNORM:
  311. case PIPE_FORMAT_R16G16B16A16_SNORM:
  312. //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
  313. return R300_COLOR_FORMAT_ARGB16161616;
  314. /* XXX Enable float textures here. */
  315. #if 0
  316. /* 128-bit buffers. */
  317. case PIPE_FORMAT_R32G32B32A32_FLOAT:
  318. return R300_COLOR_FORMAT_ARGB32323232;
  319. #endif
  320. /* YUV buffers. */
  321. case PIPE_FORMAT_UYVY:
  322. return R300_COLOR_FORMAT_YVYU;
  323. case PIPE_FORMAT_YUYV:
  324. return R300_COLOR_FORMAT_VYUY;
  325. default:
  326. return ~0; /* Unsupported. */
  327. }
  328. }
  329. /* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */
  330. static uint32_t r300_translate_zsformat(enum pipe_format format)
  331. {
  332. switch (format) {
  333. /* 16-bit depth, no stencil */
  334. case PIPE_FORMAT_Z16_UNORM:
  335. return R300_DEPTHFORMAT_16BIT_INT_Z;
  336. /* 24-bit depth, ignored stencil */
  337. case PIPE_FORMAT_X8Z24_UNORM:
  338. /* 24-bit depth, 8-bit stencil */
  339. case PIPE_FORMAT_S8Z24_UNORM:
  340. return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
  341. default:
  342. return ~0; /* Unsupported. */
  343. }
  344. }
  345. /* Shader output formats. This is essentially the swizzle from the shader
  346. * to the RB3D block.
  347. *
  348. * Note that formats are stored from C3 to C0. */
  349. static uint32_t r300_translate_out_fmt(enum pipe_format format)
  350. {
  351. uint32_t modifier = 0;
  352. unsigned i;
  353. const struct util_format_description *desc;
  354. static const uint32_t sign_bit[4] = {
  355. R300_OUT_SIGN(0x1),
  356. R300_OUT_SIGN(0x2),
  357. R300_OUT_SIGN(0x4),
  358. R300_OUT_SIGN(0x8),
  359. };
  360. desc = util_format_description(format);
  361. /* Specifies how the shader output is written to the fog unit. */
  362. if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
  363. if (desc->channel[0].size == 32) {
  364. modifier |= R300_US_OUT_FMT_C4_32_FP;
  365. } else {
  366. modifier |= R300_US_OUT_FMT_C4_16_FP;
  367. }
  368. } else {
  369. if (desc->channel[0].size == 16) {
  370. modifier |= R300_US_OUT_FMT_C4_16;
  371. } else {
  372. /* C4_8 seems to be used for the formats whose pixel size
  373. * is <= 32 bits. */
  374. modifier |= R300_US_OUT_FMT_C4_8;
  375. }
  376. }
  377. /* Add sign. */
  378. for (i = 0; i < 4; i++)
  379. if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
  380. modifier |= sign_bit[i];
  381. }
  382. /* Add swizzles and return. */
  383. switch (format) {
  384. /* 8-bit outputs.
  385. * COLORFORMAT_I8 stores the C2 component. */
  386. case PIPE_FORMAT_A8_UNORM:
  387. return modifier | R300_C2_SEL_A;
  388. case PIPE_FORMAT_I8_UNORM:
  389. case PIPE_FORMAT_L8_UNORM:
  390. case PIPE_FORMAT_R8_UNORM:
  391. case PIPE_FORMAT_R8_SNORM:
  392. return modifier | R300_C2_SEL_R;
  393. /* BGRA outputs. */
  394. case PIPE_FORMAT_B5G6R5_UNORM:
  395. case PIPE_FORMAT_B5G5R5A1_UNORM:
  396. case PIPE_FORMAT_B5G5R5X1_UNORM:
  397. case PIPE_FORMAT_B4G4R4A4_UNORM:
  398. case PIPE_FORMAT_B8G8R8A8_UNORM:
  399. case PIPE_FORMAT_B8G8R8X8_UNORM:
  400. return modifier |
  401. R300_C0_SEL_B | R300_C1_SEL_G |
  402. R300_C2_SEL_R | R300_C3_SEL_A;
  403. /* ARGB outputs. */
  404. case PIPE_FORMAT_A8R8G8B8_UNORM:
  405. case PIPE_FORMAT_X8R8G8B8_UNORM:
  406. return modifier |
  407. R300_C0_SEL_A | R300_C1_SEL_R |
  408. R300_C2_SEL_G | R300_C3_SEL_B;
  409. /* ABGR outputs. */
  410. case PIPE_FORMAT_A8B8G8R8_UNORM:
  411. case PIPE_FORMAT_X8B8G8R8_UNORM:
  412. return modifier |
  413. R300_C0_SEL_A | R300_C1_SEL_B |
  414. R300_C2_SEL_G | R300_C3_SEL_R;
  415. /* RGBA outputs. */
  416. case PIPE_FORMAT_R8G8B8A8_SNORM:
  417. case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
  418. case PIPE_FORMAT_R10G10B10A2_UNORM:
  419. case PIPE_FORMAT_R16G16B16A16_UNORM:
  420. case PIPE_FORMAT_R16G16B16A16_SNORM:
  421. //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
  422. case PIPE_FORMAT_R32G32B32A32_FLOAT:
  423. return modifier |
  424. R300_C0_SEL_R | R300_C1_SEL_G |
  425. R300_C2_SEL_B | R300_C3_SEL_A;
  426. default:
  427. return ~0; /* Unsupported. */
  428. }
  429. }
  430. boolean r300_is_colorbuffer_format_supported(enum pipe_format format)
  431. {
  432. return r300_translate_colorformat(format) != ~0 &&
  433. r300_translate_out_fmt(format) != ~0;
  434. }
  435. boolean r300_is_zs_format_supported(enum pipe_format format)
  436. {
  437. return r300_translate_zsformat(format) != ~0;
  438. }
  439. boolean r300_is_sampler_format_supported(enum pipe_format format)
  440. {
  441. return r300_translate_texformat(format) != ~0;
  442. }
  443. static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex)
  444. {
  445. struct r300_texture_format_state* state = &tex->state;
  446. struct pipe_resource *pt = &tex->b.b;
  447. unsigned i;
  448. boolean is_r500 = screen->caps->is_r500;
  449. /* Set sampler state. */
  450. state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
  451. R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
  452. if (tex->is_npot) {
  453. /* rectangles love this */
  454. state->format0 |= R300_TX_PITCH_EN;
  455. state->format2 = (tex->pitch[0] - 1) & 0x1fff;
  456. } else {
  457. /* power of two textures (3D, mipmaps, and no pitch) */
  458. state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
  459. }
  460. state->format1 = r300_translate_texformat(pt->format);
  461. if (pt->target == PIPE_TEXTURE_CUBE) {
  462. state->format1 |= R300_TX_FORMAT_CUBIC_MAP;
  463. }
  464. if (pt->target == PIPE_TEXTURE_3D) {
  465. state->format1 |= R300_TX_FORMAT_3D;
  466. }
  467. /* large textures on r500 */
  468. if (is_r500)
  469. {
  470. if (pt->width0 > 2048) {
  471. state->format2 |= R500_TXWIDTH_BIT11;
  472. }
  473. if (pt->height0 > 2048) {
  474. state->format2 |= R500_TXHEIGHT_BIT11;
  475. }
  476. }
  477. SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
  478. pt->width0, pt->height0, pt->last_level);
  479. /* Set framebuffer state. */
  480. if (util_format_is_depth_or_stencil(tex->b.b.format)) {
  481. for (i = 0; i <= tex->b.b.last_level; i++) {
  482. tex->fb_state.depthpitch[i] =
  483. tex->pitch[i] |
  484. R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
  485. R300_DEPTHMICROTILE(tex->microtile);
  486. }
  487. tex->fb_state.zb_format = r300_translate_zsformat(tex->b.b.format);
  488. } else {
  489. for (i = 0; i <= tex->b.b.last_level; i++) {
  490. tex->fb_state.colorpitch[i] =
  491. tex->pitch[i] |
  492. r300_translate_colorformat(tex->b.b.format) |
  493. R300_COLOR_TILE(tex->mip_macrotile[i]) |
  494. R300_COLOR_MICROTILE(tex->microtile);
  495. }
  496. tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->b.b.format);
  497. }
  498. }
  499. void r300_texture_reinterpret_format(struct pipe_screen *screen,
  500. struct pipe_resource *tex,
  501. enum pipe_format new_format)
  502. {
  503. struct r300_screen *r300screen = r300_screen(screen);
  504. SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
  505. util_format_name(tex->format), util_format_name(new_format));
  506. tex->format = new_format;
  507. r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex);
  508. }
  509. unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
  510. unsigned zslice, unsigned face)
  511. {
  512. unsigned offset = tex->offset[level];
  513. switch (tex->b.b.target) {
  514. case PIPE_TEXTURE_3D:
  515. assert(face == 0);
  516. return offset + zslice * tex->layer_size[level];
  517. case PIPE_TEXTURE_CUBE:
  518. assert(zslice == 0);
  519. return offset + face * tex->layer_size[level];
  520. default:
  521. assert(zslice == 0 && face == 0);
  522. return offset;
  523. }
  524. }
  525. /**
  526. * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile
  527. * of the given texture.
  528. */
  529. static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
  530. int dim, boolean macrotile)
  531. {
  532. unsigned pixsize, tile_size;
  533. pixsize = util_format_get_blocksize(tex->b.b.format);
  534. tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim];
  535. if (macrotile) {
  536. tile_size *= 8;
  537. }
  538. assert(tile_size);
  539. return tile_size;
  540. }
  541. /* Return true if macrotiling should be enabled on the miplevel. */
  542. static boolean r300_texture_macro_switch(struct r300_texture *tex,
  543. unsigned level,
  544. boolean rv350_mode,
  545. int dim)
  546. {
  547. unsigned tile, texdim;
  548. tile = r300_texture_get_tile_size(tex, dim, TRUE);
  549. if (dim == TILE_WIDTH) {
  550. texdim = u_minify(tex->b.b.width0, level);
  551. } else {
  552. texdim = u_minify(tex->b.b.height0, level);
  553. }
  554. /* See TX_FILTER1_n.MACRO_SWITCH. */
  555. if (rv350_mode) {
  556. return texdim >= tile;
  557. } else {
  558. return texdim > tile;
  559. }
  560. }
  561. /**
  562. * Return the stride, in bytes, of the texture images of the given texture
  563. * at the given level.
  564. */
  565. unsigned r300_texture_get_stride(struct r300_screen* screen,
  566. struct r300_texture* tex, unsigned level)
  567. {
  568. unsigned tile_width, width;
  569. if (tex->stride_override)
  570. return tex->stride_override;
  571. /* Check the level. */
  572. if (level > tex->b.b.last_level) {
  573. SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
  574. __FUNCTION__, level, tex->b.b.last_level);
  575. return 0;
  576. }
  577. width = u_minify(tex->b.b.width0, level);
  578. if (r300_format_is_plain(tex->b.b.format)) {
  579. tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
  580. tex->mip_macrotile[level]);
  581. width = align(width, tile_width);
  582. return util_format_get_stride(tex->b.b.format, width);
  583. } else {
  584. return align(util_format_get_stride(tex->b.b.format, width), 32);
  585. }
  586. }
  587. static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
  588. unsigned level)
  589. {
  590. unsigned height, tile_height;
  591. height = u_minify(tex->b.b.height0, level);
  592. if (r300_format_is_plain(tex->b.b.format)) {
  593. tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
  594. tex->mip_macrotile[level]);
  595. height = align(height, tile_height);
  596. }
  597. return util_format_get_nblocksy(tex->b.b.format, height);
  598. }
  599. static void r300_setup_miptree(struct r300_screen* screen,
  600. struct r300_texture* tex)
  601. {
  602. struct pipe_resource* base = &tex->b.b;
  603. unsigned stride, size, layer_size, nblocksy, i;
  604. boolean rv350_mode = screen->caps->family >= CHIP_FAMILY_RV350;
  605. SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
  606. util_format_name(base->format));
  607. for (i = 0; i <= base->last_level; i++) {
  608. /* Let's see if this miplevel can be macrotiled. */
  609. tex->mip_macrotile[i] =
  610. (tex->macrotile == R300_BUFFER_TILED &&
  611. r300_texture_macro_switch(tex, i, rv350_mode, TILE_WIDTH)) ?
  612. R300_BUFFER_TILED : R300_BUFFER_LINEAR;
  613. stride = r300_texture_get_stride(screen, tex, i);
  614. nblocksy = r300_texture_get_nblocksy(tex, i);
  615. layer_size = stride * nblocksy;
  616. if (base->target == PIPE_TEXTURE_CUBE)
  617. size = layer_size * 6;
  618. else
  619. size = layer_size * u_minify(base->depth0, i);
  620. tex->offset[i] = tex->size;
  621. tex->size = tex->offset[i] + size;
  622. tex->layer_size[i] = layer_size;
  623. tex->pitch[i] = stride / util_format_get_blocksize(base->format);
  624. SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
  625. "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
  626. i, u_minify(base->width0, i), u_minify(base->height0, i),
  627. u_minify(base->depth0, i), stride, tex->size,
  628. tex->mip_macrotile[i] ? "TRUE" : "FALSE");
  629. }
  630. }
  631. static void r300_setup_flags(struct r300_texture* tex)
  632. {
  633. tex->is_npot = !util_is_power_of_two(tex->b.b.width0) ||
  634. !util_is_power_of_two(tex->b.b.height0);
  635. }
  636. static void r300_setup_tiling(struct pipe_screen *screen,
  637. struct r300_texture *tex)
  638. {
  639. struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
  640. enum pipe_format format = tex->b.b.format;
  641. boolean rv350_mode = r300_screen(screen)->caps->family >= CHIP_FAMILY_RV350;
  642. if (!r300_format_is_plain(format)) {
  643. return;
  644. }
  645. if (tex->b.b.width0 == 1 ||
  646. tex->b.b.height0 == 1) {
  647. return;
  648. }
  649. /* Set microtiling. */
  650. switch (util_format_get_blocksize(format)) {
  651. case 1:
  652. case 4:
  653. tex->microtile = R300_BUFFER_TILED;
  654. break;
  655. case 2:
  656. case 8:
  657. if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
  658. tex->microtile = R300_BUFFER_SQUARETILED;
  659. }
  660. break;
  661. }
  662. /* Set macrotiling. */
  663. if (r300_texture_macro_switch(tex, 0, rv350_mode, TILE_WIDTH) &&
  664. r300_texture_macro_switch(tex, 0, rv350_mode, TILE_HEIGHT)) {
  665. tex->macrotile = R300_BUFFER_TILED;
  666. }
  667. }
  668. static unsigned r300_texture_is_referenced(struct pipe_context *context,
  669. struct pipe_resource *texture,
  670. unsigned face, unsigned level)
  671. {
  672. struct r300_context *r300 = r300_context(context);
  673. struct r300_texture *rtex = (struct r300_texture *)texture;
  674. if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer))
  675. return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
  676. return PIPE_UNREFERENCED;
  677. }
  678. static void r300_texture_destroy(struct pipe_screen *screen,
  679. struct pipe_resource* texture)
  680. {
  681. struct r300_texture* tex = (struct r300_texture*)texture;
  682. struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
  683. rws->buffer_reference(rws, &tex->buffer, NULL);
  684. FREE(tex);
  685. }
  686. static boolean
  687. r300_texture_get_handle(struct pipe_screen* screen,
  688. struct pipe_resource *texture,
  689. struct winsys_handle *whandle)
  690. {
  691. struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
  692. struct r300_texture* tex = (struct r300_texture*)texture;
  693. unsigned stride;
  694. if (!tex) {
  695. return FALSE;
  696. }
  697. stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
  698. rws->buffer_get_handle(rws, tex->buffer, stride, whandle);
  699. return TRUE;
  700. }
  701. struct u_resource_vtbl r300_texture_vtbl =
  702. {
  703. r300_texture_get_handle, /* get_handle */
  704. r300_texture_destroy, /* resource_destroy */
  705. r300_texture_is_referenced, /* is_resource_referenced */
  706. r300_texture_get_transfer, /* get_transfer */
  707. r300_texture_transfer_destroy, /* transfer_destroy */
  708. r300_texture_transfer_map, /* transfer_map */
  709. u_default_transfer_flush_region, /* transfer_flush_region */
  710. r300_texture_transfer_unmap, /* transfer_unmap */
  711. u_default_transfer_inline_write /* transfer_inline_write */
  712. };
  713. /* Create a new texture. */
  714. struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
  715. const struct pipe_resource* template)
  716. {
  717. struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
  718. struct r300_screen* rscreen = r300_screen(screen);
  719. struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
  720. if (!tex) {
  721. return NULL;
  722. }
  723. tex->b.b = *template;
  724. tex->b.vtbl = &r300_texture_vtbl;
  725. pipe_reference_init(&tex->b.b.reference, 1);
  726. tex->b.b.screen = screen;
  727. r300_setup_flags(tex);
  728. if (!(template->tex_usage & R300_TEXTURE_USAGE_TRANSFER)) {
  729. r300_setup_tiling(screen, tex);
  730. }
  731. r300_setup_miptree(rscreen, tex);
  732. r300_setup_texture_state(rscreen, tex);
  733. tex->buffer = rws->buffer_create(rws, 2048,
  734. PIPE_BUFFER_USAGE_PIXEL,
  735. tex->size);
  736. rws->buffer_set_tiling(rws, tex->buffer,
  737. tex->pitch[0],
  738. tex->microtile,
  739. tex->macrotile);
  740. if (!tex->buffer) {
  741. FREE(tex);
  742. return NULL;
  743. }
  744. return (struct pipe_resource*)tex;
  745. }
  746. /* Not required to implement u_resource_vtbl, consider moving to another file:
  747. */
  748. struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
  749. struct pipe_resource* texture,
  750. unsigned face,
  751. unsigned level,
  752. unsigned zslice,
  753. unsigned flags)
  754. {
  755. struct r300_texture* tex = (struct r300_texture*)texture;
  756. struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface);
  757. unsigned offset;
  758. offset = r300_texture_get_offset(tex, level, zslice, face);
  759. if (surface) {
  760. pipe_reference_init(&surface->reference, 1);
  761. pipe_resource_reference(&surface->texture, texture);
  762. surface->format = texture->format;
  763. surface->width = u_minify(texture->width0, level);
  764. surface->height = u_minify(texture->height0, level);
  765. surface->offset = offset;
  766. surface->usage = flags;
  767. surface->zslice = zslice;
  768. surface->texture = texture;
  769. surface->face = face;
  770. surface->level = level;
  771. }
  772. return surface;
  773. }
  774. /* Not required to implement u_resource_vtbl, consider moving to another file:
  775. */
  776. void r300_tex_surface_destroy(struct pipe_surface* s)
  777. {
  778. pipe_resource_reference(&s->texture, NULL);
  779. FREE(s);
  780. }
  781. struct pipe_resource*
  782. r300_texture_from_handle(struct pipe_screen* screen,
  783. const struct pipe_resource* base,
  784. struct winsys_handle *whandle)
  785. {
  786. struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
  787. struct r300_screen* rscreen = r300_screen(screen);
  788. struct r300_winsys_buffer *buffer;
  789. struct r300_texture* tex;
  790. unsigned stride;
  791. /* Support only 2D textures without mipmaps */
  792. if (base->target != PIPE_TEXTURE_2D ||
  793. base->depth0 != 1 ||
  794. base->last_level != 0) {
  795. return NULL;
  796. }
  797. buffer = rws->buffer_from_handle(rws, screen, whandle, &stride);
  798. if (!buffer) {
  799. return NULL;
  800. }
  801. tex = CALLOC_STRUCT(r300_texture);
  802. if (!tex) {
  803. return NULL;
  804. }
  805. tex->b.b = *base;
  806. pipe_reference_init(&tex->b.b.reference, 1);
  807. tex->b.b.screen = screen;
  808. tex->stride_override = stride;
  809. tex->pitch[0] = stride / util_format_get_blocksize(base->format);
  810. r300_setup_flags(tex);
  811. r300_setup_texture_state(rscreen, tex);
  812. /* one ref already taken */
  813. tex->buffer = buffer;
  814. return (struct pipe_resource*)tex;
  815. }
  816. struct pipe_video_surface *
  817. r300_video_surface_create(struct pipe_screen *screen,
  818. enum pipe_video_chroma_format chroma_format,
  819. unsigned width, unsigned height)
  820. {
  821. struct r300_video_surface *r300_vsfc;
  822. struct pipe_resource template;
  823. assert(screen);
  824. assert(width && height);
  825. r300_vsfc = CALLOC_STRUCT(r300_video_surface);
  826. if (!r300_vsfc)
  827. return NULL;
  828. pipe_reference_init(&r300_vsfc->base.reference, 1);
  829. r300_vsfc->base.screen = screen;
  830. r300_vsfc->base.chroma_format = chroma_format;
  831. r300_vsfc->base.width = width;
  832. r300_vsfc->base.height = height;
  833. memset(&template, 0, sizeof template);
  834. template.target = PIPE_TEXTURE_2D;
  835. template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
  836. template.last_level = 0;
  837. template.width0 = util_next_power_of_two(width);
  838. template.height0 = util_next_power_of_two(height);
  839. template.depth0 = 1;
  840. template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER |
  841. PIPE_TEXTURE_USAGE_RENDER_TARGET;
  842. r300_vsfc->tex = screen->resource_create(screen, &template);
  843. if (!r300_vsfc->tex)
  844. {
  845. FREE(r300_vsfc);
  846. return NULL;
  847. }
  848. return &r300_vsfc->base;
  849. }
  850. void r300_video_surface_destroy(struct pipe_video_surface *vsfc)
  851. {
  852. struct r300_video_surface *r300_vsfc = r300_video_surface(vsfc);
  853. pipe_resource_reference(&r300_vsfc->tex, NULL);
  854. FREE(r300_vsfc);
  855. }