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.

tu_blit.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*
  2. * Copyright © 2019 Valve Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. *
  23. * Authors:
  24. * Jonathan Marek <jonathan@marek.ca>
  25. *
  26. */
  27. #include "tu_blit.h"
  28. #include "a6xx.xml.h"
  29. #include "adreno_common.xml.h"
  30. #include "adreno_pm4.xml.h"
  31. #include "vk_format.h"
  32. #include "tu_cs.h"
  33. /* TODO:
  34. * - Avoid disabling tiling for swapped formats
  35. * (image_to_image copy doesn't deal with it)
  36. * - Fix d24_unorm_s8_uint support & aspects
  37. * - UBWC
  38. */
  39. static VkFormat
  40. blit_copy_format(VkFormat format)
  41. {
  42. switch (vk_format_get_blocksizebits(format)) {
  43. case 8: return VK_FORMAT_R8_UINT;
  44. case 16: return VK_FORMAT_R16_UINT;
  45. case 32: return VK_FORMAT_R32_UINT;
  46. case 64: return VK_FORMAT_R32G32_UINT;
  47. case 96: return VK_FORMAT_R32G32B32_UINT;
  48. case 128:return VK_FORMAT_R32G32B32A32_UINT;
  49. default:
  50. unreachable("unhandled format size");
  51. }
  52. }
  53. static uint32_t
  54. blit_image_info(const struct tu_blit_surf *img, bool src, bool stencil_read)
  55. {
  56. const struct tu_native_format *fmt = tu6_get_native_format(img->fmt);
  57. enum a6xx_color_fmt rb = fmt->rb;
  58. enum a3xx_color_swap swap = img->tiled ? WZYX : fmt->swap;
  59. if (rb == RB6_R10G10B10A2_UNORM && src)
  60. rb = RB6_R10G10B10A2_FLOAT16;
  61. if (rb == RB6_Z24_UNORM_S8_UINT)
  62. rb = RB6_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
  63. if (stencil_read)
  64. swap = XYZW;
  65. return A6XX_SP_PS_2D_SRC_INFO_COLOR_FORMAT(rb) |
  66. A6XX_SP_PS_2D_SRC_INFO_TILE_MODE(img->tile_mode) |
  67. A6XX_SP_PS_2D_SRC_INFO_COLOR_SWAP(swap) |
  68. COND(vk_format_is_srgb(img->fmt), A6XX_SP_PS_2D_SRC_INFO_SRGB) |
  69. COND(img->ubwc_size, A6XX_SP_PS_2D_SRC_INFO_FLAGS);
  70. }
  71. static void
  72. emit_blit_step(struct tu_cmd_buffer *cmdbuf, const struct tu_blit *blt)
  73. {
  74. struct tu_cs *cs = &cmdbuf->cs;
  75. tu_cs_reserve_space(cmdbuf->device, cs, 66);
  76. enum a6xx_color_fmt fmt = tu6_get_native_format(blt->dst.fmt)->rb;
  77. if (fmt == RB6_Z24_UNORM_S8_UINT)
  78. fmt = RB6_Z24_UNORM_S8_UINT_AS_R8G8B8A8;
  79. enum a6xx_2d_ifmt ifmt = tu6_rb_fmt_to_ifmt(fmt);
  80. if (vk_format_is_srgb(blt->dst.fmt)) {
  81. assert(ifmt == R2D_UNORM8);
  82. ifmt = R2D_UNORM8_SRGB;
  83. }
  84. uint32_t blit_cntl = A6XX_RB_2D_BLIT_CNTL_ROTATE(blt->rotation) |
  85. COND(blt->type == TU_BLIT_CLEAR, A6XX_RB_2D_BLIT_CNTL_SOLID_COLOR) |
  86. A6XX_RB_2D_BLIT_CNTL_COLOR_FORMAT(fmt) | /* not required? */
  87. COND(fmt == RB6_Z24_UNORM_S8_UINT_AS_R8G8B8A8, A6XX_RB_2D_BLIT_CNTL_D24S8) |
  88. A6XX_RB_2D_BLIT_CNTL_MASK(0xf) |
  89. A6XX_RB_2D_BLIT_CNTL_IFMT(ifmt);
  90. tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_RB_2D_BLIT_CNTL, 1);
  91. tu_cs_emit(&cmdbuf->cs, blit_cntl);
  92. tu_cs_emit_pkt4(&cmdbuf->cs, REG_A6XX_GRAS_2D_BLIT_CNTL, 1);
  93. tu_cs_emit(&cmdbuf->cs, blit_cntl);
  94. /*
  95. * Emit source:
  96. */
  97. if (blt->type == TU_BLIT_CLEAR) {
  98. tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_SRC_SOLID_C0, 4);
  99. tu_cs_emit(cs, blt->clear_value[0]);
  100. tu_cs_emit(cs, blt->clear_value[1]);
  101. tu_cs_emit(cs, blt->clear_value[2]);
  102. tu_cs_emit(cs, blt->clear_value[3]);
  103. } else {
  104. tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_INFO, 10);
  105. tu_cs_emit(cs, blit_image_info(&blt->src, true, blt->stencil_read) |
  106. A6XX_SP_PS_2D_SRC_INFO_SAMPLES(tu_msaa_samples(blt->src.samples)) |
  107. /* TODO: should disable this bit for integer formats ? */
  108. COND(blt->src.samples > 1, A6XX_SP_PS_2D_SRC_INFO_SAMPLES_AVERAGE) |
  109. COND(blt->filter, A6XX_SP_PS_2D_SRC_INFO_FILTER) |
  110. 0x500000);
  111. tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_SIZE_WIDTH(blt->src.x + blt->src.width) |
  112. A6XX_SP_PS_2D_SRC_SIZE_HEIGHT(blt->src.y + blt->src.height));
  113. tu_cs_emit_qw(cs, blt->src.va);
  114. tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_PITCH_PITCH(blt->src.pitch));
  115. tu_cs_emit(cs, 0x00000000);
  116. tu_cs_emit(cs, 0x00000000);
  117. tu_cs_emit(cs, 0x00000000);
  118. tu_cs_emit(cs, 0x00000000);
  119. tu_cs_emit(cs, 0x00000000);
  120. if (blt->src.ubwc_size) {
  121. tu_cs_emit_pkt4(cs, REG_A6XX_SP_PS_2D_SRC_FLAGS_LO, 6);
  122. tu_cs_emit_qw(cs, blt->src.ubwc_va);
  123. tu_cs_emit(cs, A6XX_SP_PS_2D_SRC_FLAGS_PITCH_PITCH(blt->src.ubwc_pitch) |
  124. A6XX_SP_PS_2D_SRC_FLAGS_PITCH_ARRAY_PITCH(blt->src.ubwc_size >> 2));
  125. tu_cs_emit(cs, 0x00000000);
  126. tu_cs_emit(cs, 0x00000000);
  127. tu_cs_emit(cs, 0x00000000);
  128. }
  129. }
  130. /*
  131. * Emit destination:
  132. */
  133. tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_INFO, 9);
  134. tu_cs_emit(cs, blit_image_info(&blt->dst, false, false));
  135. tu_cs_emit_qw(cs, blt->dst.va);
  136. tu_cs_emit(cs, A6XX_RB_2D_DST_SIZE_PITCH(blt->dst.pitch));
  137. tu_cs_emit(cs, 0x00000000);
  138. tu_cs_emit(cs, 0x00000000);
  139. tu_cs_emit(cs, 0x00000000);
  140. tu_cs_emit(cs, 0x00000000);
  141. tu_cs_emit(cs, 0x00000000);
  142. if (blt->dst.ubwc_size) {
  143. tu_cs_emit_pkt4(cs, REG_A6XX_RB_2D_DST_FLAGS_LO, 6);
  144. tu_cs_emit_qw(cs, blt->dst.ubwc_va);
  145. tu_cs_emit(cs, A6XX_RB_2D_DST_FLAGS_PITCH_PITCH(blt->dst.ubwc_pitch) |
  146. A6XX_RB_2D_DST_FLAGS_PITCH_ARRAY_PITCH(blt->dst.ubwc_size >> 2));
  147. tu_cs_emit(cs, 0x00000000);
  148. tu_cs_emit(cs, 0x00000000);
  149. tu_cs_emit(cs, 0x00000000);
  150. }
  151. tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_2D_SRC_TL_X, 4);
  152. tu_cs_emit(cs, A6XX_GRAS_2D_SRC_TL_X_X(blt->src.x));
  153. tu_cs_emit(cs, A6XX_GRAS_2D_SRC_BR_X_X(blt->src.x + blt->src.width - 1));
  154. tu_cs_emit(cs, A6XX_GRAS_2D_SRC_TL_Y_Y(blt->src.y));
  155. tu_cs_emit(cs, A6XX_GRAS_2D_SRC_BR_Y_Y(blt->src.y + blt->src.height - 1));
  156. tu_cs_emit_pkt4(cs, REG_A6XX_GRAS_2D_DST_TL, 2);
  157. tu_cs_emit(cs, A6XX_GRAS_2D_DST_TL_X(blt->dst.x) |
  158. A6XX_GRAS_2D_DST_TL_Y(blt->dst.y));
  159. tu_cs_emit(cs, A6XX_GRAS_2D_DST_BR_X(blt->dst.x + blt->dst.width - 1) |
  160. A6XX_GRAS_2D_DST_BR_Y(blt->dst.y + blt->dst.height - 1));
  161. tu_cs_emit_pkt7(cs, CP_EVENT_WRITE, 1);
  162. tu_cs_emit(cs, 0x3f);
  163. tu_cs_emit_wfi(cs);
  164. tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_8C01, 1);
  165. tu_cs_emit(cs, 0);
  166. if (fmt == RB6_R10G10B10A2_UNORM)
  167. fmt = RB6_R16G16B16A16_FLOAT;
  168. tu_cs_emit_pkt4(cs, REG_A6XX_SP_2D_SRC_FORMAT, 1);
  169. tu_cs_emit(cs, COND(vk_format_is_sint(blt->src.fmt), A6XX_SP_2D_SRC_FORMAT_SINT) |
  170. COND(vk_format_is_uint(blt->src.fmt), A6XX_SP_2D_SRC_FORMAT_UINT) |
  171. A6XX_SP_2D_SRC_FORMAT_COLOR_FORMAT(fmt) |
  172. COND(ifmt == R2D_UNORM8_SRGB, A6XX_SP_2D_SRC_FORMAT_SRGB) |
  173. A6XX_SP_2D_SRC_FORMAT_MASK(0xf));
  174. tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_8E04, 1);
  175. tu_cs_emit(cs, 0x01000000);
  176. tu_cs_emit_pkt7(cs, CP_BLIT, 1);
  177. tu_cs_emit(cs, CP_BLIT_0_OP(BLIT_OP_SCALE));
  178. tu_cs_emit_wfi(cs);
  179. tu_cs_emit_pkt4(cs, REG_A6XX_RB_UNKNOWN_8E04, 1);
  180. tu_cs_emit(cs, 0);
  181. }
  182. void tu_blit(struct tu_cmd_buffer *cmdbuf, struct tu_blit *blt)
  183. {
  184. switch (blt->type) {
  185. case TU_BLIT_COPY:
  186. blt->stencil_read =
  187. blt->dst.fmt == VK_FORMAT_R8_UNORM &&
  188. blt->src.fmt == VK_FORMAT_D24_UNORM_S8_UINT;
  189. assert(vk_format_get_blocksize(blt->dst.fmt) ==
  190. vk_format_get_blocksize(blt->src.fmt) || blt->stencil_read);
  191. assert(blt->src.samples == blt->dst.samples);
  192. if (vk_format_is_compressed(blt->src.fmt)) {
  193. unsigned block_width = vk_format_get_blockwidth(blt->src.fmt);
  194. unsigned block_height = vk_format_get_blockheight(blt->src.fmt);
  195. blt->src.pitch /= block_width;
  196. blt->src.x /= block_width;
  197. blt->src.y /= block_height;
  198. blt->src.fmt = blit_copy_format(blt->src.fmt);
  199. /* for image_to_image copy, width/height is on the src format */
  200. blt->dst.width = blt->src.width = DIV_ROUND_UP(blt->src.width, block_width);
  201. blt->dst.height = blt->src.height = DIV_ROUND_UP(blt->src.height, block_height);
  202. }
  203. if (vk_format_is_compressed(blt->dst.fmt)) {
  204. unsigned block_width = vk_format_get_blockwidth(blt->dst.fmt);
  205. unsigned block_height = vk_format_get_blockheight(blt->dst.fmt);
  206. blt->dst.pitch /= block_width;
  207. blt->dst.x /= block_width;
  208. blt->dst.y /= block_height;
  209. blt->dst.fmt = blit_copy_format(blt->dst.fmt);
  210. }
  211. if (blt->dst.fmt == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
  212. blt->dst.fmt = blit_copy_format(blt->dst.fmt);
  213. if (blt->src.fmt == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
  214. blt->src.fmt = blit_copy_format(blt->src.fmt);
  215. /* TODO: multisample image copy does not work correctly with tiling/UBWC */
  216. blt->src.x *= blt->src.samples;
  217. blt->dst.x *= blt->dst.samples;
  218. blt->src.width *= blt->src.samples;
  219. blt->dst.width *= blt->dst.samples;
  220. blt->src.samples = 1;
  221. blt->dst.samples = 1;
  222. break;
  223. case TU_BLIT_CLEAR:
  224. /* unsupported format cleared as UINT32 */
  225. if (blt->dst.fmt == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
  226. blt->dst.fmt = blt->src.fmt = VK_FORMAT_R32_UINT;
  227. assert(blt->dst.samples == 1); /* TODO */
  228. break;
  229. default:
  230. assert(blt->dst.samples == 1);
  231. }
  232. tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 18);
  233. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, LRZ_FLUSH, false);
  234. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, 0x1d, true);
  235. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, FACENESS_FLUSH, true);
  236. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, PC_CCU_INVALIDATE_COLOR, false);
  237. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, PC_CCU_INVALIDATE_DEPTH, false);
  238. /* buffer copy setup */
  239. tu_cs_emit_pkt7(&cmdbuf->cs, CP_SET_MARKER, 1);
  240. tu_cs_emit(&cmdbuf->cs, A6XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE));
  241. for (unsigned layer = 0; layer < blt->layers; layer++) {
  242. if (blt->buffer) {
  243. struct tu_blit line_blt = *blt;
  244. uint64_t dst_va = line_blt.dst.va, src_va = line_blt.src.va;
  245. unsigned blocksize = vk_format_get_blocksize(blt->src.fmt);
  246. uint32_t size = line_blt.src.width, tmp;
  247. while (size) {
  248. line_blt.src.x = (src_va & 63) / blocksize;
  249. line_blt.src.va = src_va & ~63;
  250. tmp = MIN2(size, 0x4000 - line_blt.src.x);
  251. line_blt.dst.x = (dst_va & 63) / blocksize;
  252. line_blt.dst.va = dst_va & ~63;
  253. tmp = MIN2(tmp, 0x4000 - line_blt.dst.x);
  254. line_blt.src.width = line_blt.dst.width = tmp;
  255. emit_blit_step(cmdbuf, &line_blt);
  256. src_va += tmp * blocksize;
  257. dst_va += tmp * blocksize;
  258. size -= tmp;
  259. }
  260. } else if ((blt->src.va & 63) || (blt->src.pitch & 63)) {
  261. /* per line copy path (buffer_to_image) */
  262. assert(blt->type == TU_BLIT_COPY && !blt->src.tiled);
  263. struct tu_blit line_blt = *blt;
  264. uint64_t src_va = line_blt.src.va + blt->src.pitch * blt->src.y;
  265. line_blt.src.y = 0;
  266. line_blt.src.pitch = 0;
  267. line_blt.src.height = 1;
  268. line_blt.dst.height = 1;
  269. for (unsigned y = 0; y < blt->src.height; y++) {
  270. line_blt.src.x = blt->src.x + (src_va & 63) / vk_format_get_blocksize(blt->src.fmt);
  271. line_blt.src.va = src_va & ~63;
  272. emit_blit_step(cmdbuf, &line_blt);
  273. line_blt.dst.y++;
  274. src_va += blt->src.pitch;
  275. }
  276. } else if ((blt->dst.va & 63) || (blt->dst.pitch & 63)) {
  277. /* per line copy path (image_to_buffer) */
  278. assert(blt->type == TU_BLIT_COPY && !blt->dst.tiled);
  279. struct tu_blit line_blt = *blt;
  280. uint64_t dst_va = line_blt.dst.va + blt->dst.pitch * blt->dst.y;
  281. line_blt.dst.y = 0;
  282. line_blt.dst.pitch = 0;
  283. line_blt.src.height = 1;
  284. line_blt.dst.height = 1;
  285. for (unsigned y = 0; y < blt->src.height; y++) {
  286. line_blt.dst.x = blt->dst.x + (dst_va & 63) / vk_format_get_blocksize(blt->dst.fmt);
  287. line_blt.dst.va = dst_va & ~63;
  288. emit_blit_step(cmdbuf, &line_blt);
  289. line_blt.src.y++;
  290. dst_va += blt->dst.pitch;
  291. }
  292. } else {
  293. emit_blit_step(cmdbuf, blt);
  294. }
  295. blt->dst.va += blt->dst.layer_size;
  296. blt->src.va += blt->src.layer_size;
  297. blt->dst.ubwc_va += blt->dst.ubwc_size;
  298. blt->src.ubwc_va += blt->src.ubwc_size;
  299. }
  300. tu_cs_reserve_space(cmdbuf->device, &cmdbuf->cs, 17);
  301. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, 0x1d, true);
  302. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, FACENESS_FLUSH, true);
  303. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, CACHE_FLUSH_TS, true);
  304. tu6_emit_event_write(cmdbuf, &cmdbuf->cs, CACHE_INVALIDATE, false);
  305. }