vic41.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. * Copyright © 2018 NVIDIA 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 shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. */
  22. #include <errno.h>
  23. #include <string.h>
  24. #include "private.h"
  25. #include "tegra.h"
  26. #include "vic.h"
  27. #include "vic41.h"
  28. struct vic41 {
  29. struct vic base;
  30. struct {
  31. struct drm_tegra_mapping *map;
  32. struct drm_tegra_bo *bo;
  33. } config;
  34. struct {
  35. struct drm_tegra_mapping *map;
  36. struct drm_tegra_bo *bo;
  37. } filter;
  38. };
  39. static int vic41_fill(struct vic *v, struct vic_image *output,
  40. unsigned int left, unsigned int top,
  41. unsigned int right, unsigned int bottom,
  42. unsigned int alpha, unsigned int red,
  43. unsigned int green, unsigned int blue)
  44. {
  45. struct vic41 *vic = container_of(v, struct vic41, base);
  46. ConfigStruct *c;
  47. int err;
  48. err = drm_tegra_bo_map(vic->config.bo, (void **)&c);
  49. if (err < 0) {
  50. fprintf(stderr, "failed to map configuration structure: %s\n",
  51. strerror(-err));
  52. return err;
  53. }
  54. memset(c, 0, sizeof(*c));
  55. c->outputConfig.TargetRectTop = top;
  56. c->outputConfig.TargetRectLeft = left;
  57. c->outputConfig.TargetRectRight = right;
  58. c->outputConfig.TargetRectBottom = bottom;
  59. c->outputConfig.BackgroundAlpha = alpha;
  60. c->outputConfig.BackgroundR = red;
  61. c->outputConfig.BackgroundG = green;
  62. c->outputConfig.BackgroundB = blue;
  63. c->outputSurfaceConfig.OutPixelFormat = output->format;
  64. c->outputSurfaceConfig.OutBlkKind = output->kind;
  65. c->outputSurfaceConfig.OutBlkHeight = 0;
  66. c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1;
  67. c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1;
  68. c->outputSurfaceConfig.OutLumaWidth = output->stride - 1;
  69. c->outputSurfaceConfig.OutLumaHeight = output->height - 1;
  70. c->outputSurfaceConfig.OutChromaWidth = 16383;
  71. c->outputSurfaceConfig.OutChromaHeight = 16383;
  72. drm_tegra_bo_unmap(vic->config.bo);
  73. return 0;
  74. }
  75. static int vic41_blit(struct vic *v, struct vic_image *output,
  76. struct vic_image *input)
  77. {
  78. struct vic41 *vic = container_of(v, struct vic41, base);
  79. SlotSurfaceConfig *surface;
  80. SlotConfig *slot;
  81. ConfigStruct *c;
  82. int err;
  83. err = drm_tegra_bo_map(vic->config.bo, (void **)&c);
  84. if (err < 0) {
  85. fprintf(stderr, "failed to map configuration structure: %s\n",
  86. strerror(-err));
  87. return err;
  88. }
  89. memset(c, 0, sizeof(*c));
  90. c->outputConfig.TargetRectTop = 0;
  91. c->outputConfig.TargetRectLeft = 0;
  92. c->outputConfig.TargetRectRight = output->width - 1;
  93. c->outputConfig.TargetRectBottom = output->height - 1;
  94. c->outputConfig.BackgroundAlpha = 255;
  95. c->outputConfig.BackgroundR = 1023;
  96. c->outputConfig.BackgroundG = 1023;
  97. c->outputConfig.BackgroundB = 1023;
  98. c->outputSurfaceConfig.OutPixelFormat = output->format;
  99. c->outputSurfaceConfig.OutBlkKind = output->kind;
  100. c->outputSurfaceConfig.OutBlkHeight = 0;
  101. c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1;
  102. c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1;
  103. c->outputSurfaceConfig.OutLumaWidth = output->stride - 1;
  104. c->outputSurfaceConfig.OutLumaHeight = output->height - 1;
  105. c->outputSurfaceConfig.OutChromaWidth = 16383;
  106. c->outputSurfaceConfig.OutChromaHeight = 16383;
  107. slot = &c->slotStruct[0].slotConfig;
  108. slot->SlotEnable = 1;
  109. slot->CurrentFieldEnable = 1;
  110. slot->PlanarAlpha = 255;
  111. slot->ConstantAlpha = 1;
  112. slot->SourceRectLeft = 0 << 16;
  113. slot->SourceRectRight = (input->width - 1) << 16;
  114. slot->SourceRectTop = 0 << 16;
  115. slot->SourceRectBottom = (input->height - 1) << 16;
  116. slot->DestRectLeft = 0;
  117. slot->DestRectRight = output->width - 1;
  118. slot->DestRectTop = 0;
  119. slot->DestRectBottom = output->height - 1;
  120. slot->SoftClampHigh = 1023;
  121. surface = &c->slotStruct[0].slotSurfaceConfig;
  122. surface->SlotPixelFormat = input->format;
  123. surface->SlotBlkKind = input->kind;
  124. surface->SlotBlkHeight = 0; /* XXX */
  125. surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */
  126. surface->SlotSurfaceWidth = input->width - 1;
  127. surface->SlotSurfaceHeight = input->height - 1;
  128. surface->SlotLumaWidth = input->stride - 1;
  129. surface->SlotLumaHeight = input->height - 1;
  130. surface->SlotChromaWidth = 16383;
  131. surface->SlotChromaHeight = 16383;
  132. drm_tegra_bo_unmap(vic->config.bo);
  133. return 0;
  134. }
  135. static int vic41_flip(struct vic *v, struct vic_image *output,
  136. struct vic_image *input)
  137. {
  138. struct vic41 *vic = container_of(v, struct vic41, base);
  139. SlotSurfaceConfig *surface;
  140. SlotConfig *slot;
  141. ConfigStruct *c;
  142. int err;
  143. err = drm_tegra_bo_map(vic->config.bo, (void **)&c);
  144. if (err < 0) {
  145. fprintf(stderr, "failed to map configuration structure: %s\n",
  146. strerror(-err));
  147. return err;
  148. }
  149. memset(c, 0, sizeof(*c));
  150. c->outputConfig.TargetRectTop = 0;
  151. c->outputConfig.TargetRectLeft = 0;
  152. c->outputConfig.TargetRectRight = output->width - 1;
  153. c->outputConfig.TargetRectBottom = output->height - 1;
  154. c->outputConfig.BackgroundAlpha = 255;
  155. c->outputConfig.BackgroundR = 1023;
  156. c->outputConfig.BackgroundG = 1023;
  157. c->outputConfig.BackgroundB = 1023;
  158. c->outputConfig.OutputFlipY = 1;
  159. c->outputSurfaceConfig.OutPixelFormat = output->format;
  160. c->outputSurfaceConfig.OutBlkKind = output->kind;
  161. c->outputSurfaceConfig.OutBlkHeight = 0;
  162. c->outputSurfaceConfig.OutSurfaceWidth = output->width - 1;
  163. c->outputSurfaceConfig.OutSurfaceHeight = output->height - 1;
  164. c->outputSurfaceConfig.OutLumaWidth = output->stride - 1;
  165. c->outputSurfaceConfig.OutLumaHeight = output->height - 1;
  166. c->outputSurfaceConfig.OutChromaWidth = 16383;
  167. c->outputSurfaceConfig.OutChromaHeight = 16383;
  168. slot = &c->slotStruct[0].slotConfig;
  169. slot->SlotEnable = 1;
  170. slot->CurrentFieldEnable = 1;
  171. slot->PlanarAlpha = 255;
  172. slot->ConstantAlpha = 1;
  173. slot->SourceRectLeft = 0 << 16;
  174. slot->SourceRectRight = (input->width - 1) << 16;
  175. slot->SourceRectTop = 0 << 16;
  176. slot->SourceRectBottom = (input->height - 1) << 16;
  177. slot->DestRectLeft = 0;
  178. slot->DestRectRight = output->width - 1;
  179. slot->DestRectTop = 0;
  180. slot->DestRectBottom = output->height - 1;
  181. slot->SoftClampHigh = 1023;
  182. surface = &c->slotStruct[0].slotSurfaceConfig;
  183. surface->SlotPixelFormat = input->format;
  184. surface->SlotBlkKind = input->kind;
  185. surface->SlotBlkHeight = 0; /* XXX */
  186. surface->SlotCacheWidth = VIC_CACHE_WIDTH_64Bx4; /* XXX */
  187. surface->SlotSurfaceWidth = input->width - 1;
  188. surface->SlotSurfaceHeight = input->height - 1;
  189. surface->SlotLumaWidth = input->stride - 1;
  190. surface->SlotLumaHeight = input->height - 1;
  191. surface->SlotChromaWidth = 16383;
  192. surface->SlotChromaHeight = 16383;
  193. drm_tegra_bo_unmap(vic->config.bo);
  194. return 0;
  195. }
  196. static int vic41_execute(struct vic *v, struct drm_tegra_pushbuf *pushbuf,
  197. uint32_t **ptrp, struct vic_image *output,
  198. struct vic_image **inputs, unsigned int num_inputs)
  199. {
  200. struct vic41 *vic = container_of(v, struct vic41, base);
  201. unsigned int i;
  202. if (num_inputs > 1)
  203. return -EINVAL;
  204. VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1);
  205. VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16);
  206. VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0);
  207. VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_FILTER_STRUCT_OFFSET, vic->filter.map, 0, 0);
  208. VIC_PUSH_BUFFER(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0);
  209. for (i = 0; i < num_inputs; i++) {
  210. uint32_t method = NVB1B6_VIDEO_COMPOSITOR_SET_SURFACE0_LUMA_OFFSET(0) + (i * 3) * 4;
  211. VIC_PUSH_BUFFER(pushbuf, ptrp, method, inputs[i]->map, 0, 0);
  212. }
  213. VIC_PUSH_METHOD(pushbuf, ptrp, NVB1B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8);
  214. return 0;
  215. }
  216. static void vic41_free(struct vic *v)
  217. {
  218. struct vic41 *vic = container_of(v, struct vic41, base);
  219. drm_tegra_channel_unmap(vic->filter.map);
  220. drm_tegra_bo_unref(vic->filter.bo);
  221. drm_tegra_channel_unmap(vic->config.map);
  222. drm_tegra_bo_unref(vic->config.bo);
  223. drm_tegra_syncpoint_free(v->syncpt);
  224. free(vic);
  225. }
  226. static const struct vic_ops vic41_ops = {
  227. .fill = vic41_fill,
  228. .blit = vic41_blit,
  229. .flip = vic41_flip,
  230. .execute = vic41_execute,
  231. .free = vic41_free,
  232. };
  233. int vic41_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
  234. struct vic **vicp)
  235. {
  236. struct vic41 *vic;
  237. void *ptr;
  238. int err;
  239. vic = calloc(1, sizeof(*vic));
  240. if (!vic)
  241. return -ENOMEM;
  242. vic->base.drm = drm;
  243. vic->base.channel = channel;
  244. vic->base.ops = &vic41_ops;
  245. vic->base.version = 0x18;
  246. err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt);
  247. if (err < 0) {
  248. fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err));
  249. return err;
  250. }
  251. err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo);
  252. if (err < 0) {
  253. fprintf(stderr, "failed to allocate configuration structurer: %s\n",
  254. strerror(-err));
  255. return err;
  256. }
  257. err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ,
  258. &vic->config.map);
  259. if (err < 0) {
  260. fprintf(stderr, "failed to map configuration structure: %s\n",
  261. strerror(-err));
  262. return err;
  263. }
  264. err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo);
  265. if (err < 0) {
  266. fprintf(stderr, "failed to allocate filter buffer: %s\n",
  267. strerror(-err));
  268. return err;
  269. }
  270. err = drm_tegra_bo_map(vic->filter.bo, &ptr);
  271. if (err < 0) {
  272. fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err));
  273. return err;
  274. }
  275. memset(ptr, 0, 16384);
  276. drm_tegra_bo_unmap(vic->filter.bo);
  277. err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ,
  278. &vic->filter.map);
  279. if (err < 0) {
  280. fprintf(stderr, "failed to map filter buffer: %s\n",
  281. strerror(-err));
  282. return err;
  283. }
  284. if (vicp)
  285. *vicp = &vic->base;
  286. return 0;
  287. }