2 * Copyright (C) 2014-2015 Etnaviv Project
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:
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
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
24 * Christian Gmeiner <christian.gmeiner@gmail.com>
33 #include "etnaviv_drmif.h"
34 #include "etnaviv_drm.h"
36 #include "state.xml.h"
37 #include "state_2d.xml.h"
38 #include "cmdstream.xml.h"
40 #include "write_bmp.h"
42 static inline void etna_emit_load_state(struct etna_cmd_stream
*stream
,
43 const uint16_t offset
, const uint16_t count
)
47 v
= (VIV_FE_LOAD_STATE_HEADER_OP_LOAD_STATE
| VIV_FE_LOAD_STATE_HEADER_OFFSET(offset
) |
48 (VIV_FE_LOAD_STATE_HEADER_COUNT(count
) & VIV_FE_LOAD_STATE_HEADER_COUNT__MASK
));
50 etna_cmd_stream_emit(stream
, v
);
53 static inline void etna_set_state(struct etna_cmd_stream
*stream
, uint32_t address
, uint32_t value
)
55 etna_cmd_stream_reserve(stream
, 2);
56 etna_emit_load_state(stream
, address
>> 2, 1);
57 etna_cmd_stream_emit(stream
, value
);
60 static inline void etna_set_state_from_bo(struct etna_cmd_stream
*stream
,
61 uint32_t address
, struct etna_bo
*bo
)
63 etna_cmd_stream_reserve(stream
, 2);
64 etna_emit_load_state(stream
, address
>> 2, 1);
66 etna_cmd_stream_reloc(stream
, &(struct etna_reloc
){
68 .flags
= ETNA_RELOC_READ
,
73 static void gen_cmd_stream(struct etna_cmd_stream
*stream
, struct etna_bo
*bmp
, const int width
, const int height
)
76 static int num_rects
= 256;
78 etna_set_state(stream
, VIVS_DE_SRC_STRIDE
, 0);
79 etna_set_state(stream
, VIVS_DE_SRC_ROTATION_CONFIG
, 0);
80 etna_set_state(stream
, VIVS_DE_SRC_CONFIG
, 0);
81 etna_set_state(stream
, VIVS_DE_SRC_ORIGIN
, 0);
82 etna_set_state(stream
, VIVS_DE_SRC_SIZE
, 0);
83 etna_set_state(stream
, VIVS_DE_SRC_COLOR_BG
, 0);
84 etna_set_state(stream
, VIVS_DE_SRC_COLOR_FG
, 0);
85 etna_set_state(stream
, VIVS_DE_STRETCH_FACTOR_LOW
, 0);
86 etna_set_state(stream
, VIVS_DE_STRETCH_FACTOR_HIGH
, 0);
87 etna_set_state_from_bo(stream
, VIVS_DE_DEST_ADDRESS
, bmp
);
88 etna_set_state(stream
, VIVS_DE_DEST_STRIDE
, width
*4);
89 etna_set_state(stream
, VIVS_DE_DEST_ROTATION_CONFIG
, 0);
90 etna_set_state(stream
, VIVS_DE_DEST_CONFIG
,
91 VIVS_DE_DEST_CONFIG_FORMAT(DE_FORMAT_A8R8G8B8
) |
92 VIVS_DE_DEST_CONFIG_COMMAND_CLEAR
|
93 VIVS_DE_DEST_CONFIG_SWIZZLE(DE_SWIZZLE_ARGB
) |
94 VIVS_DE_DEST_CONFIG_TILED_DISABLE
|
95 VIVS_DE_DEST_CONFIG_MINOR_TILED_DISABLE
97 etna_set_state(stream
, VIVS_DE_ROP
,
98 VIVS_DE_ROP_ROP_FG(0xcc) | VIVS_DE_ROP_ROP_BG(0xcc) | VIVS_DE_ROP_TYPE_ROP4
);
99 etna_set_state(stream
, VIVS_DE_CLIP_TOP_LEFT
,
100 VIVS_DE_CLIP_TOP_LEFT_X(0) |
101 VIVS_DE_CLIP_TOP_LEFT_Y(0)
103 etna_set_state(stream
, VIVS_DE_CLIP_BOTTOM_RIGHT
,
104 VIVS_DE_CLIP_BOTTOM_RIGHT_X(width
) |
105 VIVS_DE_CLIP_BOTTOM_RIGHT_Y(height
)
107 etna_set_state(stream
, VIVS_DE_CONFIG
, 0); /* TODO */
108 etna_set_state(stream
, VIVS_DE_SRC_ORIGIN_FRACTION
, 0);
109 etna_set_state(stream
, VIVS_DE_ALPHA_CONTROL
, 0);
110 etna_set_state(stream
, VIVS_DE_ALPHA_MODES
, 0);
111 etna_set_state(stream
, VIVS_DE_DEST_ROTATION_HEIGHT
, 0);
112 etna_set_state(stream
, VIVS_DE_SRC_ROTATION_HEIGHT
, 0);
113 etna_set_state(stream
, VIVS_DE_ROT_ANGLE
, 0);
115 /* Clear color PE20 */
116 etna_set_state(stream
, VIVS_DE_CLEAR_PIXEL_VALUE32
, 0xff40ff40);
117 /* Clear color PE10 */
118 etna_set_state(stream
, VIVS_DE_CLEAR_BYTE_MASK
, 0xff);
119 etna_set_state(stream
, VIVS_DE_CLEAR_PIXEL_VALUE_LOW
, 0xff40ff40);
120 etna_set_state(stream
, VIVS_DE_CLEAR_PIXEL_VALUE_HIGH
, 0xff40ff40);
122 etna_set_state(stream
, VIVS_DE_DEST_COLOR_KEY
, 0);
123 etna_set_state(stream
, VIVS_DE_GLOBAL_SRC_COLOR
, 0);
124 etna_set_state(stream
, VIVS_DE_GLOBAL_DEST_COLOR
, 0);
125 etna_set_state(stream
, VIVS_DE_COLOR_MULTIPLY_MODES
, 0);
126 etna_set_state(stream
, VIVS_DE_PE_TRANSPARENCY
, 0);
127 etna_set_state(stream
, VIVS_DE_PE_CONTROL
, 0);
128 etna_set_state(stream
, VIVS_DE_PE_DITHER_LOW
, 0xffffffff);
129 etna_set_state(stream
, VIVS_DE_PE_DITHER_HIGH
, 0xffffffff);
131 /* Queue DE command */
132 etna_cmd_stream_emit(stream
,
133 VIV_FE_DRAW_2D_HEADER_OP_DRAW_2D
| VIV_FE_DRAW_2D_HEADER_COUNT(num_rects
) /* render one rectangle */
135 etna_cmd_stream_emit(stream
, 0x0); /* rectangles start aligned */
137 for(rec
=0; rec
< num_rects
; ++rec
) {
140 etna_cmd_stream_emit(stream
, VIV_FE_DRAW_2D_TOP_LEFT_X(x
*8) | VIV_FE_DRAW_2D_TOP_LEFT_Y(y
*8));
141 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));
143 etna_set_state(stream
, 1, 0);
144 etna_set_state(stream
, 1, 0);
145 etna_set_state(stream
, 1, 0);
147 etna_set_state(stream
, VIVS_GL_FLUSH_CACHE
, VIVS_GL_FLUSH_CACHE_PE2D
);
150 int etna_check_image(uint32_t *p
, int width
, int height
)
155 for (i
= 0; i
< width
* height
; i
++) {
156 if (i
%8 < 4 && i
%(width
*8) < width
*4 && i
%width
< 8*16 && i
< width
*8*16)
157 expected
= 0xff40ff40;
159 expected
= 0x00000000;
161 if (p
[i
] != expected
) {
162 fprintf(stderr
, "Offset %d: expected: 0x%08x, got: 0x%08x\n",
171 int main(int argc
, char *argv
[])
173 const int width
= 256;
174 const int height
= 256;
175 const size_t bmp_size
= width
* height
* 4;
177 struct etna_device
*dev
;
178 struct etna_gpu
*gpu
;
179 struct etna_pipe
*pipe
;
181 struct etna_cmd_stream
*stream
;
183 drmVersionPtr version
;
189 fprintf(stderr
, "Usage: %s /dev/dri/<device> [<etna.bmp>]\n", argv
[0]);
193 fd
= open(argv
[1], O_RDWR
);
199 version
= drmGetVersion(fd
);
201 printf("Version: %d.%d.%d\n", version
->version_major
,
202 version
->version_minor
, version
->version_patchlevel
);
203 printf(" Name: %s\n", version
->name
);
204 printf(" Date: %s\n", version
->date
);
205 printf(" Description: %s\n", version
->desc
);
206 drmFreeVersion(version
);
209 dev
= etna_device_new(fd
);
211 perror("etna_device_new");
217 gpu
= etna_gpu_new(dev
, core
);
219 perror("etna_gpu_new");
224 if (etna_gpu_get_param(gpu
, ETNA_GPU_FEATURES_0
, &feat
)) {
225 perror("etna_gpu_get_param");
230 if ((feat
& (1 << 9)) == 0) {
231 /* GPU not 2D capable. */
239 pipe
= etna_pipe_new(gpu
, ETNA_PIPE_2D
);
241 perror("etna_pipe_new");
246 bmp
= etna_bo_new(dev
, bmp_size
, ETNA_BO_UNCACHED
);
248 perror("etna_bo_new");
252 memset(etna_bo_map(bmp
), 0, bmp_size
);
254 stream
= etna_cmd_stream_new(pipe
, 0x300, NULL
, NULL
);
256 perror("etna_cmd_stream_new");
261 /* generate command sequence */
262 gen_cmd_stream(stream
, bmp
, width
, height
);
264 etna_cmd_stream_finish(stream
);
267 bmp_dump32(etna_bo_map(bmp
), width
, height
, false, argv
[2]);
269 if (etna_check_image(etna_bo_map(bmp
), width
, height
))
272 etna_cmd_stream_del(stream
);
284 etna_device_del(dev
);