svga3d_surfacedefs.h 29 KB

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