Merge pull request #5 from polachok/new
[pscnv.git] / test / 902d.c
blob00d7fe2a2bdbfcdccd9abc95d24be5da2f0270f6
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2010 PathScale Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <fcntl.h>
28 #include <assert.h>
29 #include <errno.h>
30 #include <xf86drm.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include "libpscnv.h"
34 #include <sys/mman.h>
36 #define IB_SIZE 0x2000
38 #define NVC0_2D_DST_FORMAT 0x00000200
39 #define NVC0_2D_DST_FORMAT_A8R8G8B8_UNORM 0x000000cf
40 #define NVC0_2D_DST_LINEAR 0x00000204
41 #define NVC0_2D_DST_TILE_MODE 0x00000208
42 #define NVC0_2D_DST_DEPTH 0x0000020c
43 #define NVC0_2D_DST_LAYER 0x00000210
44 #define NVC0_2D_DST_PITCH 0x00000214
45 #define NVC0_2D_DST_WIDTH 0x00000218
46 #define NVC0_2D_DST_HEIGHT 0x0000021c
47 #define NVC0_2D_DST_ADDRESS_HIGH 0x00000220
48 #define NVC0_2D_DST_ADDRESS_LOW 0x00000224
49 #define NVC0_2D_SRC_FORMAT 0x00000230
50 #define NVC0_2D_SRC_LINEAR 0x00000234
51 #define NVC0_2D_SRC_TILE_MODE 0x00000238
52 #define NVC0_2D_SRC_DEPTH 0x0000023c
53 #define NVC0_2D_SRC_LAYER 0x00000240
54 #define NVC0_2D_SRC_PITCH 0x00000244
55 #define NVC0_2D_SRC_WIDTH 0x00000248
56 #define NVC0_2D_SRC_HEIGHT 0x0000024c
57 #define NVC0_2D_SRC_ADDRESS_HIGH 0x00000250
58 #define NVC0_2D_SRC_ADDRESS_LOW 0x00000254
59 #define NVC0_2D_CLIP_X 0x00000280
60 #define NVC0_2D_CLIP_Y 0x00000284
61 #define NVC0_2D_CLIP_W 0x00000288
62 #define NVC0_2D_CLIP_H 0x0000028c
63 #define NVC0_2D_CLIP_ENABLE 0x00000290
64 #define NVC0_2D_COLOR_KEY_FORMAT 0x00000294
65 #define NVC0_2D_COLOR_KEY_FORMAT_16BPP 0x00000000
66 #define NVC0_2D_COLOR_KEY_FORMAT_15BPP 0x00000001
67 #define NVC0_2D_COLOR_KEY_FORMAT_24BPP 0x00000002
68 #define NVC0_2D_COLOR_KEY_FORMAT_30BPP 0x00000003
69 #define NVC0_2D_COLOR_KEY_FORMAT_8BPP 0x00000004
70 #define NVC0_2D_COLOR_KEY_FORMAT_16BPP2 0x00000005
71 #define NVC0_2D_COLOR_KEY_FORMAT_32BPP 0x00000006
72 #define NVC0_2D_COLOR_KEY 0x00000298
73 #define NVC0_2D_COLOR_KEY_ENABLE 0x0000029c
74 #define NVC0_2D_ROP 0x000002a0
75 #define NVC0_2D_OPERATION 0x000002ac
76 #define NVC0_2D_OPERATION_SRCCOPY_AND 0x00000000
77 #define NVC0_2D_OPERATION_ROP_AND 0x00000001
78 #define NVC0_2D_OPERATION_BLEND_AND 0x00000002
79 #define NVC0_2D_OPERATION_SRCCOPY 0x00000003
80 #define NVC0_2D_OPERATION_SRCCOPY_PREMULT 0x00000004
81 #define NVC0_2D_OPERATION_BLEND_PREMULT 0x00000005
82 #define NVC0_2D_PATTERN_FORMAT 0x000002e8
83 #define NVC0_2D_PATTERN_FORMAT_16BPP 0x00000000
84 #define NVC0_2D_PATTERN_FORMAT_15BPP 0x00000001
85 #define NVC0_2D_PATTERN_FORMAT_32BPP 0x00000002
86 #define NVC0_2D_PATTERN_FORMAT_8BPP 0x00000003
87 #define NVC0_2D_PATTERN_COLOR(x) (0x000002f0+((x)*4))
88 #define NVC0_2D_PATTERN_COLOR__SIZE 0x00000002
89 #define NVC0_2D_PATTERN_BITMAP(x) (0x000002f8+((x)*4))
90 #define NVC0_2D_PATTERN_BITMAP__SIZE 0x00000002
91 #define NVC0_2D_DRAW_SHAPE 0x00000580
92 #define NVC0_2D_DRAW_SHAPE_POINTS 0x00000000
93 #define NVC0_2D_DRAW_SHAPE_LINES 0x00000001
94 #define NVC0_2D_DRAW_SHAPE_LINE_STRIP 0x00000002
95 #define NVC0_2D_DRAW_SHAPE_TRIANGLES 0x00000003
96 #define NVC0_2D_DRAW_SHAPE_RECTANGLES 0x00000004
97 #define NVC0_2D_DRAW_COLOR_FORMAT 0x00000584
98 #define NVC0_2D_DRAW_COLOR_FORMAT_A8R8G8B8_UNORM 0x000000cf
99 #define NVC0_2D_DRAW_COLOR 0x00000588
100 #define NVC0_2D_DRAW_POINT16 0x000005e0
101 #define NVC0_2D_DRAW_POINT16_X_SHIFT 0
102 #define NVC0_2D_DRAW_POINT16_X_MASK 0x0000ffff
103 #define NVC0_2D_DRAW_POINT16_Y_SHIFT 16
104 #define NVC0_2D_DRAW_POINT16_Y_MASK 0xffff0000
105 #define NVC0_2D_DRAW_POINT32_X(x) (0x00000600+((x)*8))
106 #define NVC0_2D_DRAW_POINT32_X__SIZE 0x00000040
107 #define NVC0_2D_DRAW_POINT32_Y(x) (0x00000604+((x)*8))
108 #define NVC0_2D_DRAW_POINT32_Y__SIZE 0x00000040
109 #define NVC0_2D_BLIT_DST_X 0x000008b0
110 #define NVC0_2D_BLIT_DST_Y 0x000008b4
111 #define NVC0_2D_BLIT_DST_W 0x000008b8
112 #define NVC0_2D_BLIT_DST_H 0x000008bc
113 #define NVC0_2D_BLIT_DU_DX_FRACT 0x000008c0
114 #define NVC0_2D_BLIT_DU_DX_INT 0x000008c4
115 #define NVC0_2D_BLIT_DV_DY_FRACT 0x000008c8
116 #define NVC0_2D_BLIT_DV_DY_INT 0x000008cc
117 #define NVC0_2D_BLIT_SRC_X_FRACT 0x000008d0
118 #define NVC0_2D_BLIT_SRC_X_INT 0x000008d4
119 #define NVC0_2D_BLIT_SRC_Y_FRACT 0x000008d8
120 #define NVC0_2D_BLIT_SRC_Y_INT 0x000008dc
122 struct nvchan {
123 uint32_t vid;
124 uint32_t cid;
125 uint64_t ch_ofst;
126 volatile uint32_t *regs;
128 volatile uint32_t *pb;
129 uint32_t pb_gem;
130 uint64_t pb_ofst;
132 volatile uint32_t *ib;
133 uint32_t ib_gem;
134 uint64_t ib_ofst;
135 uint64_t ib_virt;
137 int pb_base;
138 int pb_pos;
139 int ib_pos;
140 } ctx;
142 struct buf {
143 uint64_t virt;
144 uint64_t ofst;
145 uint32_t *map;
146 uint32_t gem;
147 uint32_t size;
150 static int buf_new(int fd, struct buf *buf, uint32_t size)
152 static int serial = 0;
153 int ret;
155 buf->size = size;
157 ret = pscnv_gem_new(fd, 0xb0b00000 + serial++, PSCNV_GEM_CONTIG, 0xfe, size, 0,
158 &buf->gem, &buf->ofst);
159 if (ret) {
160 fprintf(stderr, "buf%i: gem_new failed: %s\n",
161 serial, strerror(-ret));
162 return ret;
165 buf->map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED,
166 fd, buf->ofst);
167 if (!buf->map) {
168 fprintf(stderr, "buf%i: failed to map\n", serial);
169 return -1;
172 ret = pscnv_vspace_map(fd, ctx.vid, buf->gem, 0x20000000, 1ULL << 32,
173 0, 0, &buf->virt);
174 if (ret) {
175 fprintf(stderr, "buf%i: vspace map failed: %s\n", serial, strerror(-ret));
176 return ret;
178 printf("buf%i: virtual address = 0x%010lx\n", serial, buf->virt);
179 return 0;
182 static inline void clflush(volatile void *p)
184 __asm__ __volatile__ ("clflush %0"
185 : : "m" ((unsigned long)p) : "memory");
188 static inline void mfence()
190 __asm__ __volatile__ ("mfence");
193 static inline void BEGIN_RING(int c, uint32_t m, int s)
195 ctx.pb[ctx.pb_pos++] = (0x2 << 28) | (s << 16) | (c << 13) | (m >> 2);
198 static inline void CONST_RING(int c, uint32_t m, int s)
200 ctx.pb[ctx.pb_pos++] = (0x6 << 28) | (s << 16) | (c << 13) | (m >> 2);
203 static inline void OUT_RING(uint32_t d)
205 ctx.pb[ctx.pb_pos++] = d;
208 static inline void OUT_RINGf(float f)
210 union {
211 float f32;
212 uint32_t u32;
213 } u;
214 u.f32 = f;
215 ctx.pb[ctx.pb_pos++] = u.u32;
218 static inline void FIRE_RING()
220 uint64_t virt = ctx.ib_virt + ctx.pb_base * 4;
221 uint32_t size = (ctx.pb_pos - ctx.pb_base) * 4;
223 printf("BFORE: 0x88/0x8c = %i/%i\n",
224 ctx.regs[0x88 / 4], ctx.regs[0x8c / 4]);
226 if (!size)
227 return;
229 ctx.ib[ctx.ib_pos * 2 + 0] = virt;
230 ctx.ib[ctx.ib_pos * 2 + 1] = (virt >> 32) | (size << 8);
231 mfence();
233 printf("FIRE_RING [%i]: 0x%08x 0x%08x\n", ctx.ib_pos + 1,
234 ctx.ib[ctx.ib_pos * 2 + 0],
235 ctx.ib[ctx.ib_pos * 2 + 1]);
237 ++ctx.ib_pos;
239 ctx.regs[0x8c / 4] = ctx.ib_pos;
241 usleep(10);
243 printf("AFTER: 0x88/0x8c = %i/%i\n",
244 ctx.regs[0x88 / 4], ctx.regs[0x8c / 4]);
246 ctx.pb_base = ctx.pb_pos;
249 int main(int argc, char **argv)
251 int fd;
252 int i, ret;
253 int fd2;
255 printf("opening drm device 1st\n");
256 fd = drmOpen("pscnv", 0);
257 printf("opening drm device 2nd\n");
258 fd2 = 0; // drmOpen("pscnv", 0);
260 if (fd == -1 || fd2 == -1) {
261 perror("failed to open device");
262 return 1;
265 ctx.pb_pos = 0x1000 / 4;
266 ctx.pb_base = ctx.pb_pos;
267 ctx.ib_pos = 0;
269 ret = pscnv_gem_new(fd, 0xf1f0c0de, PSCNV_GEM_CONTIG, 0,
270 IB_SIZE, 0, &ctx.ib_gem, &ctx.ib_ofst);
271 if (ret) {
272 fprintf(stderr, "gem_new failed: %s\n", strerror(-ret));
273 return 1;
275 printf("gem_new: h %d m %lx\n", ctx.ib_gem, ctx.ib_ofst);
277 ctx.ib = mmap(0, IB_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ctx.ib_ofst);
278 if (!ctx.ib)
279 return 1;
280 ctx.pb = ctx.ib;
281 printf("IB at %p\n", ctx.ib);
283 ret = pscnv_vspace_new(fd, &ctx.vid);
284 if (ret) {
285 fprintf(stderr, "vspace_new: %s\n", strerror(-ret));
286 return 1;
288 printf("vid %d\n", ctx.vid);
290 ret = pscnv_chan_new(fd, ctx.vid, &ctx.cid, &ctx.ch_ofst);
291 if (ret) {
292 fprintf(stderr, "chan_new failed: %s\n", strerror(-ret));
293 return 1;
295 printf("cid %d regs %lx\n", ctx.cid, ctx.ch_ofst);
298 ret = pscnv_vspace_map(fd, ctx.vid, ctx.ib_gem, 0x20000000, 1ULL << 32,
299 1, 0, &ctx.ib_virt);
300 if (ret) {
301 fprintf(stderr, "vspace_map of IB failed: %s\n", strerror(-ret));
302 return 1;
304 printf ("IB virtual %lx, doing fifo_init next\n", ctx.ib_virt);
306 ret = pscnv_fifo_init_ib(fd, ctx.cid, 0xbeef, 0, 1, ctx.ib_virt, 10);
307 if (ret) {
308 fprintf(stderr, "fifo_init failed: %s\n", strerror(-ret));
309 return 1;
311 printf("FIFO initialized\n");
313 ctx.regs = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ctx.ch_ofst);
314 if (!ctx.regs) {
315 fprintf(stderr, "ERROR: mmap of FIFO regs failed\n");
316 return 1;
318 printf("fifo regs at %p\n", ctx.regs);
320 struct buf cbuf;
321 if (buf_new(fd, &cbuf, 0x1000))
322 return -1;
323 if (buf_new(fd, &cbuf, 0x1000))
324 return -1;
325 if (buf_new(fd, &cbuf, 128 * 128 * 4))
326 return -1;
328 for (i = 0; i < 0x1000 / 4; ++i)
329 cbuf.map[i] = 0xfafafafa;
331 const int eng2d = 1;
333 BEGIN_RING(eng2d, 0x0000, 1);
334 OUT_RING (0x902d);
335 BEGIN_RING(eng2d, NVC0_2D_CLIP_ENABLE, 1);
336 OUT_RING (0);
337 BEGIN_RING(eng2d, NVC0_2D_COLOR_KEY_ENABLE, 1);
338 OUT_RING (0);
339 BEGIN_RING(eng2d, 0x0884, 1);
340 OUT_RING (0x3f);
341 BEGIN_RING(eng2d, 0x0888, 1);
342 OUT_RING (1);
343 BEGIN_RING(eng2d, NVC0_2D_ROP, 1);
344 OUT_RING (0x55);
345 BEGIN_RING(eng2d, NVC0_2D_OPERATION, 1);
346 OUT_RING (NVC0_2D_OPERATION_SRCCOPY);
347 BEGIN_RING(eng2d, NVC0_2D_BLIT_DU_DX_FRACT, 4);
348 OUT_RING (0);
349 OUT_RING (1);
350 OUT_RING (0);
351 OUT_RING (1);
352 BEGIN_RING(eng2d, NVC0_2D_DRAW_SHAPE, 2);
353 OUT_RING (4);
354 OUT_RING (NVC0_2D_DRAW_COLOR_FORMAT_A8R8G8B8_UNORM);
355 BEGIN_RING(eng2d, NVC0_2D_PATTERN_FORMAT, 2);
356 OUT_RING (NVC0_2D_PATTERN_FORMAT_32BPP);
357 OUT_RING (1);
359 FIRE_RING ();
361 BEGIN_RING(eng2d, NVC0_2D_DST_FORMAT, 5);
362 OUT_RING (NVC0_2D_DST_FORMAT_A8R8G8B8_UNORM);
363 OUT_RING (0);
364 OUT_RING (0x10);
365 OUT_RING (1);
366 OUT_RING (0);
367 BEGIN_RING(eng2d, NVC0_2D_DST_FORMAT + 0x18, 4);
368 OUT_RING (128);
369 OUT_RING (128);
370 OUT_RING (cbuf.virt >> 32);
371 OUT_RING (cbuf.virt);
373 BEGIN_RING(eng2d, NVC0_2D_DRAW_SHAPE, 3);
374 OUT_RING (NVC0_2D_DRAW_SHAPE_RECTANGLES);
375 OUT_RING (NVC0_2D_DRAW_COLOR_FORMAT_A8R8G8B8_UNORM);
376 OUT_RING (0xaca5cade);
378 BEGIN_RING(eng2d, NVC0_2D_DRAW_POINT32_X(0), 4);
379 OUT_RING (2);
380 OUT_RING (0);
381 OUT_RING (128);
382 OUT_RING (128);
384 FIRE_RING ();
386 usleep(1000000);
388 for (i = 0; i < 4; ++i)
389 printf("BUF[%i] = 0x%08x\n", i, cbuf.map[i]);
391 close(fd);
392 close(fd2);
394 return 0;