etnaviv_2d_test.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /*
  2. * Copyright (C) 2014-2015 Etnaviv Project
  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 FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. * SOFTWARE.
  22. *
  23. * Authors:
  24. * Christian Gmeiner <christian.gmeiner@gmail.com>
  25. */
  26. #include <fcntl.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30. #include "xf86drm.h"
  31. #include "etnaviv_drmif.h"
  32. #include "etnaviv_drm.h"
  33. #include "state.xml.h"
  34. #include "state_2d.xml.h"
  35. #include "cmdstream.xml.h"
  36. #include "write_bmp.h"
  37. static inline void etna_emit_load_state(struct etna_cmd_stream *stream,
  38. const uint16_t offset, const uint16_t count)
  39. {
  40. uint32_t v;
  41. v = (VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE | VIV_FE_LOAD_STATE_HEADER_OFFSET(offset) |
  42. (VIV_FE_LOAD_STATE_HEADER_COUNT(count) & VIV_FE_LOAD_STATE_HEADER_COUNT__MASK));
  43. etna_cmd_stream_emit(stream, v);
  44. }
  45. static inline void etna_set_state(struct etna_cmd_stream *stream, uint32_t address, uint32_t value)
  46. {
  47. etna_cmd_stream_reserve(stream, 2);
  48. etna_emit_load_state(stream, address >> 2, 1);
  49. etna_cmd_stream_emit(stream, value);
  50. }
  51. static inline void etna_set_state_from_bo(struct etna_cmd_stream *stream,
  52. uint32_t address, struct etna_bo *bo)
  53. {
  54. etna_cmd_stream_reserve(stream, 2);
  55. etna_emit_load_state(stream, address >> 2, 1);
  56. etna_cmd_stream_reloc(stream, &(struct etna_reloc){
  57. .bo = bo,
  58. .flags = ETNA_RELOC_READ,
  59. .offset = 0,
  60. });
  61. }
  62. static void gen_cmd_stream(struct etna_cmd_stream *stream, struct etna_bo *bmp, const int width, const int height)
  63. {
  64. int rec;
  65. static int num_rects = 256;
  66. etna_set_state(stream, VIVS_DE_SRC_STRIDE, 0);
  67. etna_set_state(stream, VIVS_DE_SRC_ROTATION_CONFIG, 0);
  68. etna_set_state(stream, VIVS_DE_SRC_CONFIG, 0);
  69. etna_set_state(stream, VIVS_DE_SRC_ORIGIN, 0);
  70. etna_set_state(stream, VIVS_DE_SRC_SIZE, 0);
  71. etna_set_state(stream, VIVS_DE_SRC_COLOR_BG, 0);
  72. etna_set_state(stream, VIVS_DE_SRC_COLOR_FG, 0);
  73. etna_set_state(stream, VIVS_DE_STRETCH_FACTOR_LOW, 0);
  74. etna_set_state(stream, VIVS_DE_STRETCH_FACTOR_HIGH, 0);
  75. etna_set_state_from_bo(stream, VIVS_DE_DEST_ADDRESS, bmp);
  76. etna_set_state(stream, VIVS_DE_DEST_STRIDE, width*4);
  77. etna_set_state(stream, VIVS_DE_DEST_ROTATION_CONFIG, 0);
  78. etna_set_state(stream, VIVS_DE_DEST_CONFIG,
  79. VIVS_DE_DEST_CONFIG_FORMAT(DE_FORMAT_A8R8G8B8) |
  80. VIVS_DE_DEST_CONFIG_COMMAND_CLEAR |
  81. VIVS_DE_DEST_CONFIG_SWIZZLE(DE_SWIZZLE_ARGB) |
  82. VIVS_DE_DEST_CONFIG_TILED_DISABLE |
  83. VIVS_DE_DEST_CONFIG_MINOR_TILED_DISABLE
  84. );
  85. etna_set_state(stream, VIVS_DE_ROP,
  86. VIVS_DE_ROP_ROP_FG(0xcc) | VIVS_DE_ROP_ROP_BG(0xcc) | VIVS_DE_ROP_TYPE_ROP4);
  87. etna_set_state(stream, VIVS_DE_CLIP_TOP_LEFT,
  88. VIVS_DE_CLIP_TOP_LEFT_X(0) |
  89. VIVS_DE_CLIP_TOP_LEFT_Y(0)
  90. );
  91. etna_set_state(stream, VIVS_DE_CLIP_BOTTOM_RIGHT,
  92. VIVS_DE_CLIP_BOTTOM_RIGHT_X(width) |
  93. VIVS_DE_CLIP_BOTTOM_RIGHT_Y(height)
  94. );
  95. etna_set_state(stream, VIVS_DE_CONFIG, 0); /* TODO */
  96. etna_set_state(stream, VIVS_DE_SRC_ORIGIN_FRACTION, 0);
  97. etna_set_state(stream, VIVS_DE_ALPHA_CONTROL, 0);
  98. etna_set_state(stream, VIVS_DE_ALPHA_MODES, 0);
  99. etna_set_state(stream, VIVS_DE_DEST_ROTATION_HEIGHT, 0);
  100. etna_set_state(stream, VIVS_DE_SRC_ROTATION_HEIGHT, 0);
  101. etna_set_state(stream, VIVS_DE_ROT_ANGLE, 0);
  102. /* Clear color PE20 */
  103. etna_set_state(stream, VIVS_DE_CLEAR_PIXEL_VALUE32, 0xff40ff40);
  104. /* Clear color PE10 */
  105. etna_set_state(stream, VIVS_DE_CLEAR_BYTE_MASK, 0xff);
  106. etna_set_state(stream, VIVS_DE_CLEAR_PIXEL_VALUE_LOW, 0xff40ff40);
  107. etna_set_state(stream, VIVS_DE_CLEAR_PIXEL_VALUE_HIGH, 0xff40ff40);
  108. etna_set_state(stream, VIVS_DE_DEST_COLOR_KEY, 0);
  109. etna_set_state(stream, VIVS_DE_GLOBAL_SRC_COLOR, 0);
  110. etna_set_state(stream, VIVS_DE_GLOBAL_DEST_COLOR, 0);
  111. etna_set_state(stream, VIVS_DE_COLOR_MULTIPLY_MODES, 0);
  112. etna_set_state(stream, VIVS_DE_PE_TRANSPARENCY, 0);
  113. etna_set_state(stream, VIVS_DE_PE_CONTROL, 0);
  114. etna_set_state(stream, VIVS_DE_PE_DITHER_LOW, 0xffffffff);
  115. etna_set_state(stream, VIVS_DE_PE_DITHER_HIGH, 0xffffffff);
  116. /* Queue DE command */
  117. etna_cmd_stream_emit(stream,
  118. VIV_FE_DRAW_2D_HEADER_OP_DRAW_2D | VIV_FE_DRAW_2D_HEADER_COUNT(num_rects) /* render one rectangle */
  119. );
  120. etna_cmd_stream_emit(stream, 0x0); /* rectangles start aligned */
  121. for(rec=0; rec < num_rects; ++rec) {
  122. int x = rec%16;
  123. int y = rec/16;
  124. etna_cmd_stream_emit(stream, VIV_FE_DRAW_2D_TOP_LEFT_X(x*8) | VIV_FE_DRAW_2D_TOP_LEFT_Y(y*8));
  125. etna_cmd_stream_emit(stream, VIV_FE_DRAW_2D_BOTTOM_RIGHT_X(x*8+4) | VIV_FE_DRAW_2D_BOTTOM_RIGHT_Y(y*8+4));
  126. }
  127. etna_set_state(stream, 1, 0);
  128. etna_set_state(stream, 1, 0);
  129. etna_set_state(stream, 1, 0);
  130. etna_set_state(stream, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_PE2D);
  131. }
  132. int etna_check_image(uint32_t *p, int width, int height)
  133. {
  134. int i;
  135. uint32_t expected;
  136. for (i = 0; i < width * height; i++) {
  137. if (i%8 < 4 && i%(width*8) < width*4 && i%width < 8*16 && i < width*8*16)
  138. expected = 0xff40ff40;
  139. else
  140. expected = 0x00000000;
  141. if (p[i] != expected) {
  142. fprintf(stderr, "Offset %d: expected: 0x%08x, got: 0x%08x\n",
  143. i, expected, p[i]);
  144. return -1;
  145. }
  146. }
  147. return 0;
  148. }
  149. int main(int argc, char *argv[])
  150. {
  151. const int width = 256;
  152. const int height = 256;
  153. const size_t bmp_size = width * height * 4;
  154. struct etna_device *dev;
  155. struct etna_gpu *gpu;
  156. struct etna_pipe *pipe;
  157. struct etna_bo *bmp;
  158. struct etna_cmd_stream *stream;
  159. drmVersionPtr version;
  160. int fd, ret = 0;
  161. uint64_t feat;
  162. int core = 0;
  163. if (argc < 2) {
  164. fprintf(stderr, "Usage: %s /dev/dri/<device> [<etna.bmp>]\n", argv[0]);
  165. return 1;
  166. }
  167. fd = open(argv[1], O_RDWR);
  168. if (fd < 0) {
  169. perror(argv[1]);
  170. return 1;
  171. }
  172. version = drmGetVersion(fd);
  173. if (version) {
  174. printf("Version: %d.%d.%d\n", version->version_major,
  175. version->version_minor, version->version_patchlevel);
  176. printf(" Name: %s\n", version->name);
  177. printf(" Date: %s\n", version->date);
  178. printf(" Description: %s\n", version->desc);
  179. drmFreeVersion(version);
  180. }
  181. dev = etna_device_new(fd);
  182. if (!dev) {
  183. perror("etna_device_new");
  184. ret = 2;
  185. goto out;
  186. }
  187. do {
  188. gpu = etna_gpu_new(dev, core);
  189. if (!gpu) {
  190. perror("etna_gpu_new");
  191. ret = 3;
  192. goto out_device;
  193. }
  194. if (etna_gpu_get_param(gpu, ETNA_GPU_FEATURES_0, &feat)) {
  195. perror("etna_gpu_get_param");
  196. ret = 4;
  197. goto out_device;
  198. }
  199. if ((feat & (1 << 9)) == 0) {
  200. /* GPU not 2D capable. */
  201. etna_gpu_del(gpu);
  202. gpu = NULL;
  203. }
  204. core++;
  205. } while (!gpu);
  206. pipe = etna_pipe_new(gpu, ETNA_PIPE_2D);
  207. if (!pipe) {
  208. perror("etna_pipe_new");
  209. ret = 4;
  210. goto out_gpu;
  211. }
  212. bmp = etna_bo_new(dev, bmp_size, ETNA_BO_UNCACHED);
  213. if (!bmp) {
  214. perror("etna_bo_new");
  215. ret = 5;
  216. goto out_pipe;
  217. }
  218. memset(etna_bo_map(bmp), 0, bmp_size);
  219. stream = etna_cmd_stream_new(pipe, 0x300, NULL, NULL);
  220. if (!stream) {
  221. perror("etna_cmd_stream_new");
  222. ret = 6;
  223. goto out_bo;
  224. }
  225. /* generate command sequence */
  226. gen_cmd_stream(stream, bmp, width, height);
  227. etna_cmd_stream_finish(stream);
  228. if (argc > 2)
  229. bmp_dump32(etna_bo_map(bmp), width, height, false, argv[2]);
  230. if (etna_check_image(etna_bo_map(bmp), width, height))
  231. ret = 7;
  232. etna_cmd_stream_del(stream);
  233. out_bo:
  234. etna_bo_del(bmp);
  235. out_pipe:
  236. etna_pipe_del(pipe);
  237. out_gpu:
  238. etna_gpu_del(gpu);
  239. out_device:
  240. etna_device_del(dev);
  241. out:
  242. close(fd);
  243. return ret;
  244. }