draw 2 lines
[ps3freebsd_ps3gpu_test.git] / cursor.c
blob2b2553d4b1fdbda553c8948fa699e95b735a9db9
1 /*-
2 * Copyright (C) 2011, 2012 glevand <geoffrey.levand@mail.ru>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * $FreeBSD$
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/uio.h>
37 #include <sys/ioctl.h>
38 #include <sys/mman.h>
39 #include <sys/fbio.h>
40 #include <sys/consio.h>
41 #include <fcntl.h>
42 #include <unistd.h>
44 #include "ps3gpu_ctl.h"
45 #include "ps3gpu_mth.h"
46 #include "util.h"
48 #define PS3GPU_DEV_PATH "/dev/ps3gpu"
50 #define DISPLAY_WIDTH 1920
51 #define DISPLAY_HEIGHT 1080
52 #define DISPLAY_BPP 4
53 #define DISPLAY_PITCH (DISPLAY_WIDTH * DISPLAY_BPP)
55 static const uint64_t cursor_bitmap[64] = {
56 0x000000ffff000000,
57 0x0000ff0000ff0000,
58 0x00ff00000000ff00,
59 0xff000000000000ff,
60 0xff000000000000ff,
61 0xff000000000000ff,
62 0xff000000000000ff,
63 0xff000000000000ff,
64 0xff000000000000ff,
65 0xff000000000000ff,
66 0xff000000000000ff,
67 0xff000000000000ff,
68 0xff000000000000ff,
69 0xff000000000000ff,
70 0xff000000000000ff,
71 0xff000000000000ff,
72 0xff000000000000ff,
73 0xff000000000000ff,
74 0xff000000000000ff,
75 0xff000000000000ff,
76 0xff000000000000ff,
77 0xff000000000000ff,
78 0xff000000000000ff,
79 0xff000000000000ff,
80 0xff000000000000ff,
81 0xff000000000000ff,
82 0xff000000000000ff,
83 0xff000000000000ff,
84 0xff000000000000ff,
85 0xff000000000000ff,
86 0xff000000000000ff,
87 0xff000000000000ff,
88 0xff000000000000ff,
89 0xff000000000000ff,
90 0xff000000000000ff,
91 0xff000000000000ff,
92 0xff000000000000ff,
93 0xff000000000000ff,
94 0xff000000000000ff,
95 0xff000000000000ff,
96 0xff000000000000ff,
97 0xff000000000000ff,
98 0xff000000000000ff,
99 0xff000000000000ff,
100 0xff000000000000ff,
101 0xff000000000000ff,
102 0xff000000000000ff,
103 0xff000000000000ff,
104 0xff000000000000ff,
105 0xff000000000000ff,
106 0xff000000000000ff,
107 0xff000000000000ff,
108 0xff000000000000ff,
109 0xff000000000000ff,
110 0xff000000000000ff,
111 0xff000000000000ff,
112 0xff000000000000ff,
113 0xff000000000000ff,
114 0xff000000000000ff,
115 0xff000000000000ff,
116 0xff000000000000ff,
117 0x00ff00000000ff00,
118 0x0000ff0000ff0000,
119 0x000000ffff000000,
123 static int
124 update_cursor(int fd, int context_id, int head, unsigned long offset,
125 int x, int y, int enable)
127 struct ps3gpu_ctl_cursor_enable cursor_enable;
128 struct ps3gpu_ctl_cursor_set_image cursor_set_image;
129 struct ps3gpu_ctl_cursor_set_position cursor_set_position;
130 int err;
132 /* Disable cursor */
134 cursor_enable.context_id = context_id;
135 cursor_enable.head = head;
136 cursor_enable.enable = 0;
138 err = ioctl(fd, PS3GPU_CTL_CURSOR_ENABLE, &cursor_enable);
139 if (err < 0) {
140 perror("ioctl");
141 return (err);
144 /* Set cursor image */
146 cursor_set_image.context_id = context_id;
147 cursor_set_image.head = head;
148 cursor_set_image.offset = offset;
150 err = ioctl(fd, PS3GPU_CTL_CURSOR_SET_IMAGE, &cursor_set_image);
151 if (err < 0) {
152 perror("ioctl");
153 return (err);
156 /* Set cursor position */
158 cursor_set_position.context_id = context_id;
159 cursor_set_position.head = head;
160 cursor_set_position.x = x;
161 cursor_set_position.y = y;
163 err = ioctl(fd, PS3GPU_CTL_CURSOR_SET_POSITION, &cursor_set_position);
164 if (err < 0) {
165 perror("ioctl");
166 return (err);
169 /* Enable cursor */
171 cursor_enable.context_id = context_id;
172 cursor_enable.head = head;
173 cursor_enable.enable = enable;
175 err = ioctl(fd, PS3GPU_CTL_CURSOR_ENABLE, &cursor_enable);
176 if (err < 0) {
177 perror("ioctl");
178 return (err);
181 return (0);
185 main(int argc, char **argv)
187 struct ps3gpu_ctl_context_allocate context_allocate;
188 struct ps3gpu_ctl_context_free context_free;
189 struct ps3gpu_ctl_memory_allocate memory_allocate;
190 struct ps3gpu_ctl_flip flip;
191 int context_id;
192 volatile uint32_t *control;
193 uint32_t *vram, *cursor;
194 unsigned long vram_handle, cursor_handle;
195 unsigned int vram_gaddr;
196 int fd = -1;
197 int x, y;
198 int err;
200 /* Open GPU device */
202 fd = open(PS3GPU_DEV_PATH, O_RDWR);
203 if (fd < 0) {
204 perror("open");
205 goto done;
208 /* Create GPU context */
210 context_allocate.vram_size = 64; /* MB */
212 err = ioctl(fd, PS3GPU_CTL_CONTEXT_ALLOCATE, &context_allocate);
213 if (err < 0) {
214 perror("ioctl");
215 goto done;
218 context_id = context_allocate.context_id;
220 printf("context id %d\n", context_id);
221 printf("control handle 0x%lx size %d\n",
222 context_allocate.control_handle, context_allocate.control_size);
224 /* Map control registers */
226 control = mmap(NULL, context_allocate.control_size,
227 PROT_READ | PROT_WRITE, MAP_SHARED, fd, context_allocate.control_handle);
228 if (control == (void *) MAP_FAILED) {
229 perror("mmap");
230 goto done;
233 /* Allocate VRAM */
235 memory_allocate.context_id = context_id;
236 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO;
237 memory_allocate.size = 9 * 1024 * 1024;
238 memory_allocate.align = 12;
240 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
241 if (err < 0) {
242 perror("ioctl");
243 goto done;
246 vram_handle = memory_allocate.handle;
247 vram_gaddr = memory_allocate.gpu_addr;
249 printf("VRAM handle 0x%lx gpu addr 0x%08x\n",
250 vram_handle, vram_gaddr);
252 /* Map VRAM */
254 vram = mmap(NULL, memory_allocate.size,
255 PROT_READ | PROT_WRITE, MAP_SHARED, fd, vram_handle);
256 if (vram == (void *) MAP_FAILED) {
257 perror("mmap");
258 goto done;
261 memset(vram, 0x40, memory_allocate.size);
263 /* Allocate cursor */
265 memory_allocate.context_id = context_id;
266 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO;
267 memory_allocate.size = 16 * 1024;
268 memory_allocate.align = 20;
270 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
271 if (err < 0) {
272 perror("ioctl");
273 goto done;
276 cursor_handle = memory_allocate.handle;
278 printf("cursor handle 0x%lx gpu addr 0x%08x\n",
279 cursor_handle, memory_allocate.gpu_addr);
281 /* Map cursor */
283 cursor = mmap(NULL, memory_allocate.size,
284 PROT_READ | PROT_WRITE, MAP_SHARED, fd, cursor_handle);
285 if (cursor == (void *) MAP_FAILED) {
286 perror("mmap");
287 goto done;
290 /* Create cursor image */
292 for (y = 0; y < 64; y++) {
293 for (x = 0; x < 64; x++)
294 if (cursor_bitmap[(y * 64 + x) >> 6] &
295 (1ul << ((63 - (y * 64 + x)) & 0x3f)))
296 cursor[y * 64 + x] = 0xffffff00;
297 else
298 cursor[y * 64 + x] = 0x00000000;
301 /* Update cursor */
303 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_A,
304 cursor_handle, 100, 100, 1);
305 if (err)
306 goto done;
308 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_B,
309 cursor_handle, 100, 100, 1);
310 if (err)
311 goto done;
313 /* Flip */
315 flip.context_id = context_id;
316 flip.head = PS3GPU_CTL_HEAD_A;
317 flip.offset = vram_handle;
319 err = ioctl(fd, PS3GPU_CTL_FLIP, &flip);
320 if (err < 0) {
321 perror("ioctl");
322 goto done;
325 flip.context_id = context_id;
326 flip.head = PS3GPU_CTL_HEAD_B;
327 flip.offset = vram_handle;
329 err = ioctl(fd, PS3GPU_CTL_FLIP, &flip);
330 if (err < 0) {
331 perror("ioctl");
332 goto done;
335 usleep(2000000);
337 /* Update cursor */
339 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_A,
340 cursor_handle, 300, 300, 1);
341 if (err) {
342 fprintf(stderr, "could not update cursor\n");
343 goto done;
346 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_B,
347 cursor_handle, 300, 300, 1);
348 if (err) {
349 fprintf(stderr, "could not update cursor\n");
350 goto done;
353 usleep(2000000);
355 /* Destroy GPU context */
357 context_free.context_id = context_id;
359 err = ioctl(fd, PS3GPU_CTL_CONTEXT_FREE, &context_free);
360 if (err < 0) {
361 perror("ioctl");
362 goto done;
365 done:
367 if (fd >= 0)
368 close(fd);
370 /* Restore console */
372 ioctl(0, SW_TEXT_80x25, NULL);
374 exit(0);