transfer FP and vertices to VRAM only once; fix vertex array format parameters
[ps3freebsd_ps3gpu_test.git] / cursor.c
blob885472d4f91c048fad879faebd7af782ed9f73d4
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 static const uint64_t cursor_bitmap[64] = {
49 0x000000ffff000000,
50 0x0000ff0000ff0000,
51 0x00ff00000000ff00,
52 0xff000000000000ff,
53 0xff000000000000ff,
54 0xff000000000000ff,
55 0xff000000000000ff,
56 0xff000000000000ff,
57 0xff000000000000ff,
58 0xff000000000000ff,
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 0x00ff00000000ff00,
111 0x0000ff0000ff0000,
112 0x000000ffff000000,
116 static int
117 update_cursor(int fd, int context_id, int head, unsigned long offset,
118 int x, int y, int enable)
120 struct ps3gpu_ctl_cursor_enable cursor_enable;
121 struct ps3gpu_ctl_cursor_set_image cursor_set_image;
122 struct ps3gpu_ctl_cursor_set_position cursor_set_position;
123 int err;
125 /* Disable cursor */
127 cursor_enable.context_id = context_id;
128 cursor_enable.head = head;
129 cursor_enable.enable = 0;
131 err = ioctl(fd, PS3GPU_CTL_CURSOR_ENABLE, &cursor_enable);
132 if (err < 0) {
133 perror("ioctl");
134 return (err);
137 /* Set cursor image */
139 cursor_set_image.context_id = context_id;
140 cursor_set_image.head = head;
141 cursor_set_image.offset = offset;
143 err = ioctl(fd, PS3GPU_CTL_CURSOR_SET_IMAGE, &cursor_set_image);
144 if (err < 0) {
145 perror("ioctl");
146 return (err);
149 /* Set cursor position */
151 cursor_set_position.context_id = context_id;
152 cursor_set_position.head = head;
153 cursor_set_position.x = x;
154 cursor_set_position.y = y;
156 err = ioctl(fd, PS3GPU_CTL_CURSOR_SET_POSITION, &cursor_set_position);
157 if (err < 0) {
158 perror("ioctl");
159 return (err);
162 /* Enable cursor */
164 cursor_enable.context_id = context_id;
165 cursor_enable.head = head;
166 cursor_enable.enable = enable;
168 err = ioctl(fd, PS3GPU_CTL_CURSOR_ENABLE, &cursor_enable);
169 if (err < 0) {
170 perror("ioctl");
171 return (err);
174 return (0);
178 main(int argc, char **argv)
180 struct ps3gpu_ctl_context_allocate context_allocate;
181 struct ps3gpu_ctl_context_free context_free;
182 struct ps3gpu_ctl_memory_allocate memory_allocate;
183 struct ps3gpu_ctl_flip flip;
184 int context_id;
185 volatile uint32_t *control;
186 uint32_t *vram, *cursor;
187 unsigned long vram_handle, cursor_handle;
188 unsigned int vram_gaddr;
189 int fd = -1;
190 int x, y;
191 int err;
193 /* Open GPU device */
195 fd = open(PS3GPU_DEV_PATH, O_RDWR);
196 if (fd < 0) {
197 perror("open");
198 goto done;
201 /* Create GPU context */
203 context_allocate.vram_size = 64; /* MB */
205 err = ioctl(fd, PS3GPU_CTL_CONTEXT_ALLOCATE, &context_allocate);
206 if (err < 0) {
207 perror("ioctl");
208 goto done;
211 context_id = context_allocate.context_id;
213 printf("context id %d\n", context_id);
214 printf("control handle 0x%lx size %d\n",
215 context_allocate.control_handle, context_allocate.control_size);
217 /* Map control registers */
219 control = mmap(NULL, context_allocate.control_size,
220 PROT_READ | PROT_WRITE, MAP_SHARED, fd, context_allocate.control_handle);
221 if (control == (void *) MAP_FAILED) {
222 perror("mmap");
223 goto done;
226 /* Allocate VRAM */
228 memory_allocate.context_id = context_id;
229 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO;
230 memory_allocate.size = ROUNDUP(DISPLAY_HEIGHT * DISPLAY_PITCH, 4 * 1024);
231 memory_allocate.align = 12;
233 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
234 if (err < 0) {
235 perror("ioctl");
236 goto done;
239 vram_handle = memory_allocate.handle;
240 vram_gaddr = memory_allocate.gpu_addr;
242 printf("VRAM handle 0x%lx gpu addr 0x%08x\n",
243 vram_handle, vram_gaddr);
245 /* Map VRAM */
247 vram = mmap(NULL, memory_allocate.size,
248 PROT_READ | PROT_WRITE, MAP_SHARED, fd, vram_handle);
249 if (vram == (void *) MAP_FAILED) {
250 perror("mmap");
251 goto done;
254 memset32(vram, 0xff404040, DISPLAY_HEIGHT * DISPLAY_WIDTH);
256 /* Allocate cursor */
258 memory_allocate.context_id = context_id;
259 memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO;
260 memory_allocate.size = 16 * 1024;
261 memory_allocate.align = 20;
263 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
264 if (err < 0) {
265 perror("ioctl");
266 goto done;
269 cursor_handle = memory_allocate.handle;
271 printf("cursor handle 0x%lx gpu addr 0x%08x\n",
272 cursor_handle, memory_allocate.gpu_addr);
274 /* Map cursor */
276 cursor = mmap(NULL, memory_allocate.size,
277 PROT_READ | PROT_WRITE, MAP_SHARED, fd, cursor_handle);
278 if (cursor == (void *) MAP_FAILED) {
279 perror("mmap");
280 goto done;
283 /* Create cursor image */
285 for (y = 0; y < 64; y++) {
286 for (x = 0; x < 64; x++)
287 if (cursor_bitmap[(y * 64 + x) >> 6] &
288 (1ul << ((63 - (y * 64 + x)) & 0x3f)))
289 cursor[y * 64 + x] = 0xffffff00;
290 else
291 cursor[y * 64 + x] = 0x00000000;
294 /* Update cursor */
296 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_A,
297 cursor_handle, 100, 100, 1);
298 if (err)
299 goto done;
301 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_B,
302 cursor_handle, 100, 100, 1);
303 if (err)
304 goto done;
306 /* Flip */
308 flip.context_id = context_id;
309 flip.head = PS3GPU_CTL_HEAD_A;
310 flip.offset = vram_handle;
312 err = ioctl(fd, PS3GPU_CTL_FLIP, &flip);
313 if (err < 0) {
314 perror("ioctl");
315 goto done;
318 flip.context_id = context_id;
319 flip.head = PS3GPU_CTL_HEAD_B;
320 flip.offset = vram_handle;
322 err = ioctl(fd, PS3GPU_CTL_FLIP, &flip);
323 if (err < 0) {
324 perror("ioctl");
325 goto done;
328 usleep(2000000);
330 /* Update cursor */
332 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_A,
333 cursor_handle, 300, 300, 1);
334 if (err) {
335 fprintf(stderr, "could not update cursor\n");
336 goto done;
339 err = update_cursor(fd, context_id, PS3GPU_CTL_HEAD_B,
340 cursor_handle, 300, 300, 1);
341 if (err) {
342 fprintf(stderr, "could not update cursor\n");
343 goto done;
346 usleep(2000000);
348 /* Destroy GPU context */
350 context_free.context_id = context_id;
352 err = ioctl(fd, PS3GPU_CTL_CONTEXT_FREE, &context_free);
353 if (err < 0) {
354 perror("ioctl");
355 goto done;
358 done:
360 if (fd >= 0)
361 close(fd);
363 /* Restore console */
365 ioctl(0, SW_TEXT_80x25, NULL);
367 exit(0);