svga3d_surfacedefs.h 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. /**************************************************************************
  2. *
  3. * Copyright © 2008-2012 VMware, Inc., Palo Alto, CA., USA
  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 OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  21. * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  22. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  23. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  24. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. **************************************************************************/
  27. #ifdef __KERNEL__
  28. #include <drm/vmwgfx_drm.h>
  29. #define surf_size_struct struct drm_vmw_size
  30. #else /* __KERNEL__ */
  31. #ifndef ARRAY_SIZE
  32. #define ARRAY_SIZE(_A) (sizeof(_A) / sizeof((_A)[0]))
  33. #endif /* ARRAY_SIZE */
  34. #define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y))
  35. #define max_t(type, x, y) ((x) > (y) ? (x) : (y))
  36. #define min_t(type, x, y) ((x) < (y) ? (x) : (y))
  37. #define surf_size_struct SVGA3dSize
  38. #define u32 uint32
  39. #define u64 uint64_t
  40. #define U32_MAX ((u32)~0U)
  41. #endif /* __KERNEL__ */
  42. #include "svga3d_reg.h"
  43. /*
  44. * enum svga3d_block_desc describes the active data channels in a block.
  45. *
  46. * There can be at-most four active channels in a block:
  47. * 1. Red, bump W, luminance and depth are stored in the first channel.
  48. * 2. Green, bump V and stencil are stored in the second channel.
  49. * 3. Blue and bump U are stored in the third channel.
  50. * 4. Alpha and bump Q are stored in the fourth channel.
  51. *
  52. * Block channels can be used to store compressed and buffer data:
  53. * 1. For compressed formats, only the data channel is used and its size
  54. * is equal to that of a singular block in the compression scheme.
  55. * 2. For buffer formats, only the data channel is used and its size is
  56. * exactly one byte in length.
  57. * 3. In each case the bit depth represent the size of a singular block.
  58. *
  59. * Note: Compressed and IEEE formats do not use the bitMask structure.
  60. */
  61. enum svga3d_block_desc {
  62. SVGA3DBLOCKDESC_NONE = 0, /* No channels are active */
  63. SVGA3DBLOCKDESC_BLUE = 1 << 0, /* Block with red channel
  64. data */
  65. SVGA3DBLOCKDESC_U = 1 << 0, /* Block with bump U channel
  66. data */
  67. SVGA3DBLOCKDESC_UV_VIDEO = 1 << 7, /* Block with alternating video
  68. U and V */
  69. SVGA3DBLOCKDESC_GREEN = 1 << 1, /* Block with green channel
  70. data */
  71. SVGA3DBLOCKDESC_V = 1 << 1, /* Block with bump V channel
  72. data */
  73. SVGA3DBLOCKDESC_STENCIL = 1 << 1, /* Block with a stencil
  74. channel */
  75. SVGA3DBLOCKDESC_RED = 1 << 2, /* Block with blue channel
  76. data */
  77. SVGA3DBLOCKDESC_W = 1 << 2, /* Block with bump W channel
  78. data */
  79. SVGA3DBLOCKDESC_LUMINANCE = 1 << 2, /* Block with luminance channel
  80. data */
  81. SVGA3DBLOCKDESC_Y = 1 << 2, /* Block with video luminance
  82. data */
  83. SVGA3DBLOCKDESC_DEPTH = 1 << 2, /* Block with depth channel */
  84. SVGA3DBLOCKDESC_ALPHA = 1 << 3, /* Block with an alpha
  85. channel */
  86. SVGA3DBLOCKDESC_Q = 1 << 3, /* Block with bump Q channel
  87. data */
  88. SVGA3DBLOCKDESC_BUFFER = 1 << 4, /* Block stores 1 byte of
  89. data */
  90. SVGA3DBLOCKDESC_COMPRESSED = 1 << 5, /* Block stores n bytes of
  91. data depending on the
  92. compression method used */
  93. SVGA3DBLOCKDESC_IEEE_FP = 1 << 6, /* Block stores data in an IEEE
  94. floating point
  95. representation in
  96. all channels */
  97. SVGA3DBLOCKDESC_PLANAR_YUV = 1 << 8, /* Three separate blocks store
  98. data. */
  99. SVGA3DBLOCKDESC_U_VIDEO = 1 << 9, /* Block with U video data */
  100. SVGA3DBLOCKDESC_V_VIDEO = 1 << 10, /* Block with V video data */
  101. SVGA3DBLOCKDESC_EXP = 1 << 11, /* Shared exponent */
  102. SVGA3DBLOCKDESC_SRGB = 1 << 12, /* Data is in sRGB format */
  103. SVGA3DBLOCKDESC_2PLANAR_YUV = 1 << 13, /* 2 planes of Y, UV,
  104. e.g., NV12. */
  105. SVGA3DBLOCKDESC_3PLANAR_YUV = 1 << 14, /* 3 planes of separate
  106. Y, U, V, e.g., YV12. */
  107. SVGA3DBLOCKDESC_RG = SVGA3DBLOCKDESC_RED |
  108. SVGA3DBLOCKDESC_GREEN,
  109. SVGA3DBLOCKDESC_RGB = SVGA3DBLOCKDESC_RG |
  110. SVGA3DBLOCKDESC_BLUE,
  111. SVGA3DBLOCKDESC_RGB_SRGB = SVGA3DBLOCKDESC_RGB |
  112. SVGA3DBLOCKDESC_SRGB,
  113. SVGA3DBLOCKDESC_RGBA = SVGA3DBLOCKDESC_RGB |
  114. SVGA3DBLOCKDESC_ALPHA,
  115. SVGA3DBLOCKDESC_RGBA_SRGB = SVGA3DBLOCKDESC_RGBA |
  116. SVGA3DBLOCKDESC_SRGB,
  117. SVGA3DBLOCKDESC_UV = SVGA3DBLOCKDESC_U |
  118. SVGA3DBLOCKDESC_V,
  119. SVGA3DBLOCKDESC_UVL = SVGA3DBLOCKDESC_UV |
  120. SVGA3DBLOCKDESC_LUMINANCE,
  121. SVGA3DBLOCKDESC_UVW = SVGA3DBLOCKDESC_UV |
  122. SVGA3DBLOCKDESC_W,
  123. SVGA3DBLOCKDESC_UVWA = SVGA3DBLOCKDESC_UVW |
  124. SVGA3DBLOCKDESC_ALPHA,
  125. SVGA3DBLOCKDESC_UVWQ = SVGA3DBLOCKDESC_U |
  126. SVGA3DBLOCKDESC_V |
  127. SVGA3DBLOCKDESC_W |
  128. SVGA3DBLOCKDESC_Q,
  129. SVGA3DBLOCKDESC_LA = SVGA3DBLOCKDESC_LUMINANCE |
  130. SVGA3DBLOCKDESC_ALPHA,
  131. SVGA3DBLOCKDESC_R_FP = SVGA3DBLOCKDESC_RED |
  132. SVGA3DBLOCKDESC_IEEE_FP,
  133. SVGA3DBLOCKDESC_RG_FP = SVGA3DBLOCKDESC_R_FP |
  134. SVGA3DBLOCKDESC_GREEN,
  135. SVGA3DBLOCKDESC_RGB_FP = SVGA3DBLOCKDESC_RG_FP |
  136. SVGA3DBLOCKDESC_BLUE,
  137. SVGA3DBLOCKDESC_RGBA_FP = SVGA3DBLOCKDESC_RGB_FP |
  138. SVGA3DBLOCKDESC_ALPHA,
  139. SVGA3DBLOCKDESC_DS = SVGA3DBLOCKDESC_DEPTH |
  140. SVGA3DBLOCKDESC_STENCIL,
  141. SVGA3DBLOCKDESC_YUV = SVGA3DBLOCKDESC_UV_VIDEO |
  142. SVGA3DBLOCKDESC_Y,
  143. SVGA3DBLOCKDESC_AYUV = SVGA3DBLOCKDESC_ALPHA |
  144. SVGA3DBLOCKDESC_Y |
  145. SVGA3DBLOCKDESC_U_VIDEO |
  146. SVGA3DBLOCKDESC_V_VIDEO,
  147. SVGA3DBLOCKDESC_RGBE = SVGA3DBLOCKDESC_RGB |
  148. SVGA3DBLOCKDESC_EXP,
  149. SVGA3DBLOCKDESC_COMPRESSED_SRGB = SVGA3DBLOCKDESC_COMPRESSED |
  150. SVGA3DBLOCKDESC_SRGB,
  151. SVGA3DBLOCKDESC_NV12 = SVGA3DBLOCKDESC_PLANAR_YUV |
  152. SVGA3DBLOCKDESC_2PLANAR_YUV,
  153. SVGA3DBLOCKDESC_YV12 = SVGA3DBLOCKDESC_PLANAR_YUV |
  154. SVGA3DBLOCKDESC_3PLANAR_YUV,
  155. };
  156. /*
  157. * SVGA3dSurfaceDesc describes the actual pixel data.
  158. *
  159. * This structure provides the following information:
  160. * 1. Block description.
  161. * 2. Dimensions of a block in the surface.
  162. * 3. Size of block in bytes.
  163. * 4. Bit depth of the pixel data.
  164. * 5. Channel bit depths and masks (if applicable).
  165. */
  166. #define SVGA3D_CHANNEL_DEF(type) \
  167. struct { \
  168. union { \
  169. type blue; \
  170. type u; \
  171. type uv_video; \
  172. type u_video; \
  173. }; \
  174. union { \
  175. type green; \
  176. type v; \
  177. type stencil; \
  178. type v_video; \
  179. }; \
  180. union { \
  181. type red; \
  182. type w; \
  183. type luminance; \
  184. type y; \
  185. type depth; \
  186. type data; \
  187. }; \
  188. union { \
  189. type alpha; \
  190. type q; \
  191. type exp; \
  192. }; \
  193. }
  194. struct svga3d_surface_desc {
  195. enum svga3d_block_desc block_desc;
  196. surf_size_struct block_size;
  197. u32 bytes_per_block;
  198. u32 pitch_bytes_per_block;
  199. struct {
  200. u32 total;
  201. SVGA3D_CHANNEL_DEF(uint8);
  202. } bit_depth;
  203. struct {
  204. SVGA3D_CHANNEL_DEF(uint8);
  205. } bit_offset;
  206. };
  207. static const struct svga3d_surface_desc svga3d_surface_descs[] = {
  208. {SVGA3DBLOCKDESC_NONE,
  209. {1, 1, 1}, 0, 0, {0, {{0}, {0}, {0}, {0} } },
  210. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_FORMAT_INVALID */
  211. {SVGA3DBLOCKDESC_RGB,
  212. {1, 1, 1}, 4, 4, {24, {{8}, {8}, {8}, {0} } },
  213. {{{0}, {8}, {16}, {24} } } }, /* SVGA3D_X8R8G8B8 */
  214. {SVGA3DBLOCKDESC_RGBA,
  215. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  216. {{{0}, {8}, {16}, {24} } } }, /* SVGA3D_A8R8G8B8 */
  217. {SVGA3DBLOCKDESC_RGB,
  218. {1, 1, 1}, 2, 2, {16, {{5}, {6}, {5}, {0} } },
  219. {{{0}, {5}, {11}, {0} } } }, /* SVGA3D_R5G6B5 */
  220. {SVGA3DBLOCKDESC_RGB,
  221. {1, 1, 1}, 2, 2, {15, {{5}, {5}, {5}, {0} } },
  222. {{{0}, {5}, {10}, {0} } } }, /* SVGA3D_X1R5G5B5 */
  223. {SVGA3DBLOCKDESC_RGBA,
  224. {1, 1, 1}, 2, 2, {16, {{5}, {5}, {5}, {1} } },
  225. {{{0}, {5}, {10}, {15} } } }, /* SVGA3D_A1R5G5B5 */
  226. {SVGA3DBLOCKDESC_RGBA,
  227. {1, 1, 1}, 2, 2, {16, {{4}, {4}, {4}, {4} } },
  228. {{{0}, {4}, {8}, {12} } } }, /* SVGA3D_A4R4G4B4 */
  229. {SVGA3DBLOCKDESC_DEPTH,
  230. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {32}, {0} } },
  231. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_Z_D32 */
  232. {SVGA3DBLOCKDESC_DEPTH,
  233. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  234. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_Z_D16 */
  235. {SVGA3DBLOCKDESC_DS,
  236. {1, 1, 1}, 4, 4, {32, {{0}, {8}, {24}, {0} } },
  237. {{{0}, {24}, {0}, {0} } } }, /* SVGA3D_Z_D24S8 */
  238. {SVGA3DBLOCKDESC_DS,
  239. {1, 1, 1}, 2, 2, {16, {{0}, {1}, {15}, {0} } },
  240. {{{0}, {15}, {0}, {0} } } }, /* SVGA3D_Z_D15S1 */
  241. {SVGA3DBLOCKDESC_LUMINANCE,
  242. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  243. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_LUMINANCE8 */
  244. {SVGA3DBLOCKDESC_LA,
  245. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {4}, {4} } },
  246. {{{0}, {0}, {0}, {4} } } }, /* SVGA3D_LUMINANCE4_ALPHA4 */
  247. {SVGA3DBLOCKDESC_LUMINANCE,
  248. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  249. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_LUMINANCE16 */
  250. {SVGA3DBLOCKDESC_LA,
  251. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {8}, {8} } },
  252. {{{0}, {0}, {0}, {8} } } }, /* SVGA3D_LUMINANCE8_ALPHA8 */
  253. {SVGA3DBLOCKDESC_COMPRESSED,
  254. {4, 4, 1}, 8, 8, {64, {{0}, {0}, {64}, {0} } },
  255. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_DXT1 */
  256. {SVGA3DBLOCKDESC_COMPRESSED,
  257. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  258. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_DXT2 */
  259. {SVGA3DBLOCKDESC_COMPRESSED,
  260. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  261. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_DXT3 */
  262. {SVGA3DBLOCKDESC_COMPRESSED,
  263. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  264. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_DXT4 */
  265. {SVGA3DBLOCKDESC_COMPRESSED,
  266. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  267. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_DXT5 */
  268. {SVGA3DBLOCKDESC_UV,
  269. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {8}, {8} } },
  270. {{{0}, {0}, {0}, {8} } } }, /* SVGA3D_BUMPU8V8 */
  271. {SVGA3DBLOCKDESC_UVL,
  272. {1, 1, 1}, 2, 2, {16, {{5}, {5}, {6}, {0} } },
  273. {{{11}, {6}, {0}, {0} } } }, /* SVGA3D_BUMPL6V5U5 */
  274. {SVGA3DBLOCKDESC_UVL,
  275. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {0} } },
  276. {{{16}, {8}, {0}, {0} } } }, /* SVGA3D_BUMPX8L8V8U8 */
  277. {SVGA3DBLOCKDESC_UVL,
  278. {1, 1, 1}, 3, 3, {24, {{8}, {8}, {8}, {0} } },
  279. {{{16}, {8}, {0}, {0} } } }, /* SVGA3D_BUMPL8V8U8 */
  280. {SVGA3DBLOCKDESC_RGBA_FP,
  281. {1, 1, 1}, 8, 8, {64, {{16}, {16}, {16}, {16} } },
  282. {{{32}, {16}, {0}, {48} } } }, /* SVGA3D_ARGB_S10E5 */
  283. {SVGA3DBLOCKDESC_RGBA_FP,
  284. {1, 1, 1}, 16, 16, {128, {{32}, {32}, {32}, {32} } },
  285. {{{64}, {32}, {0}, {96} } } }, /* SVGA3D_ARGB_S23E8 */
  286. {SVGA3DBLOCKDESC_RGBA,
  287. {1, 1, 1}, 4, 4, {32, {{10}, {10}, {10}, {2} } },
  288. {{{0}, {10}, {20}, {30} } } }, /* SVGA3D_A2R10G10B10 */
  289. {SVGA3DBLOCKDESC_UV,
  290. {1, 1, 1}, 2, 2, {16, {{8}, {8}, {0}, {0} } },
  291. {{{8}, {0}, {0}, {0} } } }, /* SVGA3D_V8U8 */
  292. {SVGA3DBLOCKDESC_UVWQ,
  293. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  294. {{{24}, {16}, {8}, {0} } } }, /* SVGA3D_Q8W8V8U8 */
  295. {SVGA3DBLOCKDESC_UV,
  296. {1, 1, 1}, 2, 2, {16, {{8}, {8}, {0}, {0} } },
  297. {{{8}, {0}, {0}, {0} } } }, /* SVGA3D_CxV8U8 */
  298. {SVGA3DBLOCKDESC_UVL,
  299. {1, 1, 1}, 4, 4, {24, {{8}, {8}, {8}, {0} } },
  300. {{{16}, {8}, {0}, {0} } } }, /* SVGA3D_X8L8V8U8 */
  301. {SVGA3DBLOCKDESC_UVWA,
  302. {1, 1, 1}, 4, 4, {32, {{10}, {10}, {10}, {2} } },
  303. {{{0}, {10}, {20}, {30} } } }, /* SVGA3D_A2W10V10U10 */
  304. {SVGA3DBLOCKDESC_ALPHA,
  305. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {0}, {8} } },
  306. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_ALPHA8 */
  307. {SVGA3DBLOCKDESC_R_FP,
  308. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  309. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R_S10E5 */
  310. {SVGA3DBLOCKDESC_R_FP,
  311. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {32}, {0} } },
  312. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R_S23E8 */
  313. {SVGA3DBLOCKDESC_RG_FP,
  314. {1, 1, 1}, 4, 4, {32, {{0}, {16}, {16}, {0} } },
  315. {{{0}, {16}, {0}, {0} } } }, /* SVGA3D_RG_S10E5 */
  316. {SVGA3DBLOCKDESC_RG_FP,
  317. {1, 1, 1}, 8, 8, {64, {{0}, {32}, {32}, {0} } },
  318. {{{0}, {32}, {0}, {0} } } }, /* SVGA3D_RG_S23E8 */
  319. {SVGA3DBLOCKDESC_BUFFER,
  320. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  321. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BUFFER */
  322. {SVGA3DBLOCKDESC_DEPTH,
  323. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {24}, {0} } },
  324. {{{0}, {24}, {0}, {0} } } }, /* SVGA3D_Z_D24X8 */
  325. {SVGA3DBLOCKDESC_UV,
  326. {1, 1, 1}, 4, 4, {32, {{16}, {16}, {0}, {0} } },
  327. {{{16}, {0}, {0}, {0} } } }, /* SVGA3D_V16U16 */
  328. {SVGA3DBLOCKDESC_RG,
  329. {1, 1, 1}, 4, 4, {32, {{0}, {16}, {16}, {0} } },
  330. {{{0}, {0}, {16}, {0} } } }, /* SVGA3D_G16R16 */
  331. {SVGA3DBLOCKDESC_RGBA,
  332. {1, 1, 1}, 8, 8, {64, {{16}, {16}, {16}, {16} } },
  333. {{{32}, {16}, {0}, {48} } } }, /* SVGA3D_A16B16G16R16 */
  334. {SVGA3DBLOCKDESC_YUV,
  335. {1, 1, 1}, 2, 2, {16, {{8}, {0}, {8}, {0} } },
  336. {{{0}, {0}, {8}, {0} } } }, /* SVGA3D_UYVY */
  337. {SVGA3DBLOCKDESC_YUV,
  338. {1, 1, 1}, 2, 2, {16, {{8}, {0}, {8}, {0} } },
  339. {{{8}, {0}, {0}, {0} } } }, /* SVGA3D_YUY2 */
  340. {SVGA3DBLOCKDESC_NV12,
  341. {2, 2, 1}, 6, 2, {48, {{0}, {0}, {48}, {0} } },
  342. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_NV12 */
  343. {SVGA3DBLOCKDESC_AYUV,
  344. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  345. {{{0}, {8}, {16}, {24} } } }, /* SVGA3D_AYUV */
  346. {SVGA3DBLOCKDESC_RGBA,
  347. {1, 1, 1}, 16, 16, {128, {{32}, {32}, {32}, {32} } },
  348. {{{64}, {32}, {0}, {96} } } }, /* SVGA3D_R32G32B32A32_TYPELESS */
  349. {SVGA3DBLOCKDESC_RGBA,
  350. {1, 1, 1}, 16, 16, {128, {{32}, {32}, {32}, {32} } },
  351. {{{64}, {32}, {0}, {96} } } }, /* SVGA3D_R32G32B32A32_UINT */
  352. {SVGA3DBLOCKDESC_UVWQ,
  353. {1, 1, 1}, 16, 16, {128, {{32}, {32}, {32}, {32} } },
  354. {{{64}, {32}, {0}, {96} } } }, /* SVGA3D_R32G32B32A32_SINT */
  355. {SVGA3DBLOCKDESC_RGB,
  356. {1, 1, 1}, 12, 12, {96, {{32}, {32}, {32}, {0} } },
  357. {{{64}, {32}, {0}, {0} } } }, /* SVGA3D_R32G32B32_TYPELESS */
  358. {SVGA3DBLOCKDESC_RGB_FP,
  359. {1, 1, 1}, 12, 12, {96, {{32}, {32}, {32}, {0} } },
  360. {{{64}, {32}, {0}, {0} } } }, /* SVGA3D_R32G32B32_FLOAT */
  361. {SVGA3DBLOCKDESC_RGB,
  362. {1, 1, 1}, 12, 12, {96, {{32}, {32}, {32}, {0} } },
  363. {{{64}, {32}, {0}, {0} } } }, /* SVGA3D_R32G32B32_UINT */
  364. {SVGA3DBLOCKDESC_UVW,
  365. {1, 1, 1}, 12, 12, {96, {{32}, {32}, {32}, {0} } },
  366. {{{64}, {32}, {0}, {0} } } }, /* SVGA3D_R32G32B32_SINT */
  367. {SVGA3DBLOCKDESC_RGBA,
  368. {1, 1, 1}, 8, 8, {64, {{16}, {16}, {16}, {16} } },
  369. {{{32}, {16}, {0}, {48} } } }, /* SVGA3D_R16G16B16A16_TYPELESS */
  370. {SVGA3DBLOCKDESC_RGBA,
  371. {1, 1, 1}, 8, 8, {64, {{16}, {16}, {16}, {16} } },
  372. {{{32}, {16}, {0}, {48} } } }, /* SVGA3D_R16G16B16A16_UINT */
  373. {SVGA3DBLOCKDESC_UVWQ,
  374. {1, 1, 1}, 8, 8, {64, {{16}, {16}, {16}, {16} } },
  375. {{{32}, {16}, {0}, {48} } } }, /* SVGA3D_R16G16B16A16_SNORM */
  376. {SVGA3DBLOCKDESC_UVWQ,
  377. {1, 1, 1}, 8, 8, {64, {{16}, {16}, {16}, {16} } },
  378. {{{32}, {16}, {0}, {48} } } }, /* SVGA3D_R16G16B16A16_SINT */
  379. {SVGA3DBLOCKDESC_RG,
  380. {1, 1, 1}, 8, 8, {64, {{0}, {32}, {32}, {0} } },
  381. {{{0}, {32}, {0}, {0} } } }, /* SVGA3D_R32G32_TYPELESS */
  382. {SVGA3DBLOCKDESC_RG,
  383. {1, 1, 1}, 8, 8, {64, {{0}, {32}, {32}, {0} } },
  384. {{{0}, {32}, {0}, {0} } } }, /* SVGA3D_R32G32_UINT */
  385. {SVGA3DBLOCKDESC_UV,
  386. {1, 1, 1}, 8, 8, {64, {{0}, {32}, {32}, {0} } },
  387. {{{0}, {32}, {0}, {0} } } }, /* SVGA3D_R32G32_SINT */
  388. {SVGA3DBLOCKDESC_RG,
  389. {1, 1, 1}, 8, 8, {64, {{0}, {8}, {32}, {0} } },
  390. {{{0}, {32}, {0}, {0} } } }, /* SVGA3D_R32G8X24_TYPELESS */
  391. {SVGA3DBLOCKDESC_DS,
  392. {1, 1, 1}, 8, 8, {64, {{0}, {8}, {32}, {0} } },
  393. {{{0}, {32}, {0}, {0} } } }, /* SVGA3D_D32_FLOAT_S8X24_UINT */
  394. {SVGA3DBLOCKDESC_R_FP,
  395. {1, 1, 1}, 8, 8, {64, {{0}, {0}, {32}, {0} } },
  396. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R32_FLOAT_X8_X24_TYPELESS */
  397. {SVGA3DBLOCKDESC_GREEN,
  398. {1, 1, 1}, 8, 8, {64, {{0}, {8}, {0}, {0} } },
  399. {{{0}, {32}, {0}, {0} } } }, /* SVGA3D_X32_TYPELESS_G8X24_UINT */
  400. {SVGA3DBLOCKDESC_RGBA,
  401. {1, 1, 1}, 4, 4, {32, {{10}, {10}, {10}, {2} } },
  402. {{{0}, {10}, {20}, {30} } } }, /* SVGA3D_R10G10B10A2_TYPELESS */
  403. {SVGA3DBLOCKDESC_RGBA,
  404. {1, 1, 1}, 4, 4, {32, {{10}, {10}, {10}, {2} } },
  405. {{{0}, {10}, {20}, {30} } } }, /* SVGA3D_R10G10B10A2_UINT */
  406. {SVGA3DBLOCKDESC_RGB_FP,
  407. {1, 1, 1}, 4, 4, {32, {{10}, {11}, {11}, {0} } },
  408. {{{0}, {10}, {21}, {0} } } }, /* SVGA3D_R11G11B10_FLOAT */
  409. {SVGA3DBLOCKDESC_RGBA,
  410. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  411. {{{16}, {8}, {0}, {24} } } }, /* SVGA3D_R8G8B8A8_TYPELESS */
  412. {SVGA3DBLOCKDESC_RGBA,
  413. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  414. {{{16}, {8}, {0}, {24} } } }, /* SVGA3D_R8G8B8A8_UNORM */
  415. {SVGA3DBLOCKDESC_RGBA_SRGB,
  416. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  417. {{{16}, {8}, {0}, {24} } } }, /* SVGA3D_R8G8B8A8_UNORM_SRGB */
  418. {SVGA3DBLOCKDESC_RGBA,
  419. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  420. {{{16}, {8}, {0}, {24} } } }, /* SVGA3D_R8G8B8A8_UINT */
  421. {SVGA3DBLOCKDESC_RGBA,
  422. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  423. {{{16}, {8}, {0}, {24} } } }, /* SVGA3D_R8G8B8A8_SINT */
  424. {SVGA3DBLOCKDESC_RG,
  425. {1, 1, 1}, 4, 4, {32, {{0}, {16}, {16}, {0} } },
  426. {{{0}, {16}, {0}, {0} } } }, /* SVGA3D_R16G16_TYPELESS */
  427. {SVGA3DBLOCKDESC_RG_FP,
  428. {1, 1, 1}, 4, 4, {32, {{0}, {16}, {16}, {0} } },
  429. {{{0}, {16}, {0}, {0} } } }, /* SVGA3D_R16G16_UINT */
  430. {SVGA3DBLOCKDESC_UV,
  431. {1, 1, 1}, 4, 4, {32, {{0}, {16}, {16}, {0} } },
  432. {{{0}, {16}, {0}, {0} } } }, /* SVGA3D_R16G16_SINT */
  433. {SVGA3DBLOCKDESC_RED,
  434. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {32}, {0} } },
  435. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R32_TYPELESS */
  436. {SVGA3DBLOCKDESC_DEPTH,
  437. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {32}, {0} } },
  438. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_D32_FLOAT */
  439. {SVGA3DBLOCKDESC_RED,
  440. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {32}, {0} } },
  441. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R32_UINT */
  442. {SVGA3DBLOCKDESC_RED,
  443. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {32}, {0} } },
  444. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R32_SINT */
  445. {SVGA3DBLOCKDESC_RG,
  446. {1, 1, 1}, 4, 4, {32, {{0}, {8}, {24}, {0} } },
  447. {{{0}, {24}, {0}, {0} } } }, /* SVGA3D_R24G8_TYPELESS */
  448. {SVGA3DBLOCKDESC_DS,
  449. {1, 1, 1}, 4, 4, {32, {{0}, {8}, {24}, {0} } },
  450. {{{0}, {24}, {0}, {0} } } }, /* SVGA3D_D24_UNORM_S8_UINT */
  451. {SVGA3DBLOCKDESC_RED,
  452. {1, 1, 1}, 4, 4, {32, {{0}, {0}, {24}, {0} } },
  453. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R24_UNORM_X8_TYPELESS */
  454. {SVGA3DBLOCKDESC_GREEN,
  455. {1, 1, 1}, 4, 4, {32, {{0}, {8}, {0}, {0} } },
  456. {{{0}, {24}, {0}, {0} } } }, /* SVGA3D_X24_TYPELESS_G8_UINT */
  457. {SVGA3DBLOCKDESC_RG,
  458. {1, 1, 1}, 2, 2, {16, {{0}, {8}, {8}, {0} } },
  459. {{{0}, {8}, {0}, {0} } } }, /* SVGA3D_R8G8_TYPELESS */
  460. {SVGA3DBLOCKDESC_RG,
  461. {1, 1, 1}, 2, 2, {16, {{0}, {8}, {8}, {0} } },
  462. {{{0}, {8}, {0}, {0} } } }, /* SVGA3D_R8G8_UNORM */
  463. {SVGA3DBLOCKDESC_RG,
  464. {1, 1, 1}, 2, 2, {16, {{0}, {8}, {8}, {0} } },
  465. {{{0}, {8}, {0}, {0} } } }, /* SVGA3D_R8G8_UINT */
  466. {SVGA3DBLOCKDESC_UV,
  467. {1, 1, 1}, 2, 2, {16, {{0}, {8}, {8}, {0} } },
  468. {{{0}, {8}, {0}, {0} } } }, /* SVGA3D_R8G8_SINT */
  469. {SVGA3DBLOCKDESC_RED,
  470. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  471. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R16_TYPELESS */
  472. {SVGA3DBLOCKDESC_RED,
  473. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  474. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R16_UNORM */
  475. {SVGA3DBLOCKDESC_RED,
  476. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  477. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R16_UINT */
  478. {SVGA3DBLOCKDESC_U,
  479. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  480. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R16_SNORM */
  481. {SVGA3DBLOCKDESC_U,
  482. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  483. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R16_SINT */
  484. {SVGA3DBLOCKDESC_RED,
  485. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  486. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R8_TYPELESS */
  487. {SVGA3DBLOCKDESC_RED,
  488. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  489. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R8_UNORM */
  490. {SVGA3DBLOCKDESC_RED,
  491. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  492. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R8_UINT */
  493. {SVGA3DBLOCKDESC_U,
  494. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  495. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R8_SNORM */
  496. {SVGA3DBLOCKDESC_U,
  497. {1, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  498. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R8_SINT */
  499. {SVGA3DBLOCKDESC_RED,
  500. {8, 1, 1}, 1, 1, {8, {{0}, {0}, {8}, {0} } },
  501. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_R1_UNORM */
  502. {SVGA3DBLOCKDESC_RGBE,
  503. {1, 1, 1}, 4, 4, {32, {{9}, {9}, {9}, {5} } },
  504. {{{18}, {9}, {0}, {27} } } }, /* SVGA3D_R9G9B9E5_SHAREDEXP */
  505. {SVGA3DBLOCKDESC_RG,
  506. {1, 1, 1}, 2, 2, {16, {{0}, {8}, {8}, {0} } },
  507. {{{0}, {8}, {0}, {0} } } }, /* SVGA3D_R8G8_B8G8_UNORM */
  508. {SVGA3DBLOCKDESC_RG,
  509. {1, 1, 1}, 2, 2, {16, {{0}, {8}, {8}, {0} } },
  510. {{{0}, {8}, {0}, {0} } } }, /* SVGA3D_G8R8_G8B8_UNORM */
  511. {SVGA3DBLOCKDESC_COMPRESSED,
  512. {4, 4, 1}, 8, 8, {64, {{0}, {0}, {64}, {0} } },
  513. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC1_TYPELESS */
  514. {SVGA3DBLOCKDESC_COMPRESSED_SRGB,
  515. {4, 4, 1}, 8, 8, {64, {{0}, {0}, {64}, {0} } },
  516. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC1_UNORM_SRGB */
  517. {SVGA3DBLOCKDESC_COMPRESSED,
  518. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  519. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC2_TYPELESS */
  520. {SVGA3DBLOCKDESC_COMPRESSED_SRGB,
  521. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  522. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC2_UNORM_SRGB */
  523. {SVGA3DBLOCKDESC_COMPRESSED,
  524. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  525. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC3_TYPELESS */
  526. {SVGA3DBLOCKDESC_COMPRESSED_SRGB,
  527. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  528. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC3_UNORM_SRGB */
  529. {SVGA3DBLOCKDESC_COMPRESSED,
  530. {4, 4, 1}, 8, 8, {64, {{0}, {0}, {64}, {0} } },
  531. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC4_TYPELESS */
  532. {SVGA3DBLOCKDESC_COMPRESSED,
  533. {4, 4, 1}, 8, 8, {64, {{0}, {0}, {64}, {0} } },
  534. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC4_UNORM */
  535. {SVGA3DBLOCKDESC_COMPRESSED,
  536. {4, 4, 1}, 8, 8, {64, {{0}, {0}, {64}, {0} } },
  537. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC4_SNORM */
  538. {SVGA3DBLOCKDESC_COMPRESSED,
  539. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  540. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC5_TYPELESS */
  541. {SVGA3DBLOCKDESC_COMPRESSED,
  542. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  543. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC5_UNORM */
  544. {SVGA3DBLOCKDESC_COMPRESSED,
  545. {4, 4, 1}, 16, 16, {128, {{0}, {0}, {128}, {0} } },
  546. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_BC5_SNORM */
  547. {SVGA3DBLOCKDESC_RGBA,
  548. {1, 1, 1}, 4, 4, {32, {{10}, {10}, {10}, {2} } },
  549. {{{0}, {10}, {20}, {30} } } }, /* SVGA3D_R10G10B10_XR_BIAS_A2_UNORM */
  550. {SVGA3DBLOCKDESC_RGBA,
  551. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  552. {{{0}, {8}, {16}, {24} } } }, /* SVGA3D_B8G8R8A8_TYPELESS */
  553. {SVGA3DBLOCKDESC_RGBA_SRGB,
  554. {1, 1, 1}, 4, 4, {32, {{8}, {8}, {8}, {8} } },
  555. {{{0}, {8}, {16}, {24} } } }, /* SVGA3D_B8G8R8A8_UNORM_SRGB */
  556. {SVGA3DBLOCKDESC_RGB,
  557. {1, 1, 1}, 4, 4, {24, {{8}, {8}, {8}, {0} } },
  558. {{{0}, {8}, {16}, {24} } } }, /* SVGA3D_B8G8R8X8_TYPELESS */
  559. {SVGA3DBLOCKDESC_RGB_SRGB,
  560. {1, 1, 1}, 4, 4, {24, {{8}, {8}, {8}, {0} } },
  561. {{{0}, {8}, {16}, {24} } } }, /* SVGA3D_B8G8R8X8_UNORM_SRGB */
  562. {SVGA3DBLOCKDESC_DEPTH,
  563. {1, 1, 1}, 2, 2, {16, {{0}, {0}, {16}, {0} } },
  564. {{{0}, {0}, {0}, {0} } } }, /* SVGA3D_Z_DF16 */
  565. {SVGA3DBLOCKDESC_DS,
  566. {1, 1, 1}, 4, 4, {32, {{0}, {8}, {24}, {0} } },
  567. {{{0}, {24}, {0}, {0} } } }, /* SVGA3D_Z_DF24 */
  568. {SVGA3DBLOCKDESC_DS,
  569. {1, 1, 1}, 4, 4, {32, {{0}, {8}, {24}, {0} } },
  570. {{{0}, {24}, {0}, {0} } } }, /* SVGA3D_Z_D24S8_INT */
  571. };
  572. static inline u32 clamped_umul32(u32 a, u32 b)
  573. {
  574. u64 tmp = (u64) a*b;
  575. return (tmp > (u64) U32_MAX) ? U32_MAX : tmp;
  576. }
  577. static inline const struct svga3d_surface_desc *
  578. svga3dsurface_get_desc(SVGA3dSurfaceFormat format)
  579. {
  580. if (format < ARRAY_SIZE(svga3d_surface_descs))
  581. return &svga3d_surface_descs[format];
  582. return &svga3d_surface_descs[SVGA3D_FORMAT_INVALID];
  583. }
  584. /*
  585. *----------------------------------------------------------------------
  586. *
  587. * svga3dsurface_get_mip_size --
  588. *
  589. * Given a base level size and the mip level, compute the size of
  590. * the mip level.
  591. *
  592. * Results:
  593. * See above.
  594. *
  595. * Side effects:
  596. * None.
  597. *
  598. *----------------------------------------------------------------------
  599. */
  600. static inline surf_size_struct
  601. svga3dsurface_get_mip_size(surf_size_struct base_level, u32 mip_level)
  602. {
  603. surf_size_struct size;
  604. size.width = max_t(u32, base_level.width >> mip_level, 1);
  605. size.height = max_t(u32, base_level.height >> mip_level, 1);
  606. size.depth = max_t(u32, base_level.depth >> mip_level, 1);
  607. return size;
  608. }
  609. static inline void
  610. svga3dsurface_get_size_in_blocks(const struct svga3d_surface_desc *desc,
  611. const surf_size_struct *pixel_size,
  612. surf_size_struct *block_size)
  613. {
  614. block_size->width = DIV_ROUND_UP(pixel_size->width,
  615. desc->block_size.width);
  616. block_size->height = DIV_ROUND_UP(pixel_size->height,
  617. desc->block_size.height);
  618. block_size->depth = DIV_ROUND_UP(pixel_size->depth,
  619. desc->block_size.depth);
  620. }
  621. static inline bool
  622. svga3dsurface_is_planar_surface(const struct svga3d_surface_desc *desc)
  623. {
  624. return (desc->block_desc & SVGA3DBLOCKDESC_PLANAR_YUV) != 0;
  625. }
  626. static inline u32
  627. svga3dsurface_calculate_pitch(const struct svga3d_surface_desc *desc,
  628. const surf_size_struct *size)
  629. {
  630. u32 pitch;
  631. surf_size_struct blocks;
  632. svga3dsurface_get_size_in_blocks(desc, size, &blocks);
  633. pitch = blocks.width * desc->pitch_bytes_per_block;
  634. return pitch;
  635. }
  636. /*
  637. *-----------------------------------------------------------------------------
  638. *
  639. * svga3dsurface_get_image_buffer_size --
  640. *
  641. * Return the number of bytes of buffer space required to store
  642. * one image of a surface, optionally using the specified pitch.
  643. *
  644. * If pitch is zero, it is assumed that rows are tightly packed.
  645. *
  646. * This function is overflow-safe. If the result would have
  647. * overflowed, instead we return MAX_UINT32.
  648. *
  649. * Results:
  650. * Byte count.
  651. *
  652. * Side effects:
  653. * None.
  654. *
  655. *-----------------------------------------------------------------------------
  656. */
  657. static inline u32
  658. svga3dsurface_get_image_buffer_size(const struct svga3d_surface_desc *desc,
  659. const surf_size_struct *size,
  660. u32 pitch)
  661. {
  662. surf_size_struct image_blocks;
  663. u32 slice_size, total_size;
  664. svga3dsurface_get_size_in_blocks(desc, size, &image_blocks);
  665. if (svga3dsurface_is_planar_surface(desc)) {
  666. total_size = clamped_umul32(image_blocks.width,
  667. image_blocks.height);
  668. total_size = clamped_umul32(total_size, image_blocks.depth);
  669. total_size = clamped_umul32(total_size, desc->bytes_per_block);
  670. return total_size;
  671. }
  672. if (pitch == 0)
  673. pitch = svga3dsurface_calculate_pitch(desc, size);
  674. slice_size = clamped_umul32(image_blocks.height, pitch);
  675. total_size = clamped_umul32(slice_size, image_blocks.depth);
  676. return total_size;
  677. }
  678. static inline u32
  679. svga3dsurface_get_serialized_size(SVGA3dSurfaceFormat format,
  680. surf_size_struct base_level_size,
  681. u32 num_mip_levels,
  682. bool cubemap)
  683. {
  684. const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format);
  685. u64 total_size = 0;
  686. u32 mip;
  687. for (mip = 0; mip < num_mip_levels; mip++) {
  688. surf_size_struct size =
  689. svga3dsurface_get_mip_size(base_level_size, mip);
  690. total_size += svga3dsurface_get_image_buffer_size(desc,
  691. &size, 0);
  692. }
  693. if (cubemap)
  694. total_size *= SVGA3D_MAX_SURFACE_FACES;
  695. return (u32) min_t(u64, total_size, (u64) U32_MAX);
  696. }
  697. /**
  698. * svga3dsurface_get_pixel_offset - Compute the offset (in bytes) to a pixel
  699. * in an image (or volume).
  700. *
  701. * @width: The image width in pixels.
  702. * @height: The image height in pixels
  703. */
  704. static inline u32
  705. svga3dsurface_get_pixel_offset(SVGA3dSurfaceFormat format,
  706. u32 width, u32 height,
  707. u32 x, u32 y, u32 z)
  708. {
  709. const struct svga3d_surface_desc *desc = svga3dsurface_get_desc(format);
  710. const u32 bw = desc->block_size.width, bh = desc->block_size.height;
  711. const u32 bd = desc->block_size.depth;
  712. const u32 rowstride = DIV_ROUND_UP(width, bw) * desc->bytes_per_block;
  713. const u32 imgstride = DIV_ROUND_UP(height, bh) * rowstride;
  714. const u32 offset = (z / bd * imgstride +
  715. y / bh * rowstride +
  716. x / bw * desc->bytes_per_block);
  717. return offset;
  718. }
  719. static inline u32
  720. svga3dsurface_get_image_offset(SVGA3dSurfaceFormat format,
  721. surf_size_struct baseLevelSize,
  722. u32 numMipLevels,
  723. u32 face,
  724. u32 mip)
  725. {
  726. u32 offset;
  727. u32 mipChainBytes;
  728. u32 mipChainBytesToLevel;
  729. u32 i;
  730. const struct svga3d_surface_desc *desc;
  731. surf_size_struct mipSize;
  732. u32 bytes;
  733. desc = svga3dsurface_get_desc(format);
  734. mipChainBytes = 0;
  735. mipChainBytesToLevel = 0;
  736. for (i = 0; i < numMipLevels; i++) {
  737. mipSize = svga3dsurface_get_mip_size(baseLevelSize, i);
  738. bytes = svga3dsurface_get_image_buffer_size(desc, &mipSize, 0);
  739. mipChainBytes += bytes;
  740. if (i < mip)
  741. mipChainBytesToLevel += bytes;
  742. }
  743. offset = mipChainBytes * face + mipChainBytesToLevel;
  744. return offset;
  745. }