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.

r300_texture.c 33KB

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