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