fix draw_arrays
[ps3freebsd_ps3gpu_test.git] / util.c
blobf60d1b09343c3f1de4d7094504f3296656578f38
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>
33 #include <math.h>
34 #include <errno.h>
36 #include <sys/ioctl.h>
37 #include <sys/mman.h>
38 #include <unistd.h>
40 #include "ps3gpu_ctl.h"
41 #include "ps3gpu_mth.h"
42 #include "util.h"
44 int
45 setup_control(int fd, int context_id, unsigned long put, unsigned long get,
46 unsigned int ref)
48 struct ps3gpu_ctl_setup_control setup_control;
50 setup_control.context_id = context_id;
51 setup_control.put = put;
52 setup_control.get = get;
53 setup_control.ref = ref;
55 return (ioctl(fd, PS3GPU_CTL_SETUP_CONTROL, &setup_control));
58 int
59 memory_allocate(int fd, int context_id, int type, int size, int align,
60 unsigned long *handle, unsigned int *gpu_addr, void **map)
62 struct ps3gpu_ctl_memory_allocate memory_allocate;
63 struct ps3gpu_ctl_memory_free memory_free;
64 int err;
66 memory_allocate.context_id = context_id;
67 memory_allocate.type = type;
68 memory_allocate.size = size;
69 memory_allocate.align = align;
71 err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate);
72 if (err < 0)
73 return (err);
75 if (handle)
76 *handle = memory_allocate.handle;
78 if (gpu_addr)
79 *gpu_addr = memory_allocate.gpu_addr;
81 if (map) {
82 *map = mmap(NULL, memory_allocate.size,
83 PROT_READ | PROT_WRITE, MAP_SHARED, fd, memory_allocate.handle);
84 if (*map == (void *) MAP_FAILED) {
85 memory_free.context_id = context_id;
86 memory_free.handle = memory_allocate.handle;
87 err = errno;
88 ioctl(fd, PS3GPU_CTL_MEMORY_FREE, &memory_free);
89 errno = err;
90 return (-1);
94 return (0);
97 int
98 display_buffer_set(int fd, int context_id, int buffer_id, int width, int height,
99 int pitch, unsigned long offset)
101 struct ps3gpu_ctl_display_buffer_set display_buffer_set;
103 display_buffer_set.context_id = context_id;
104 display_buffer_set.buffer_id = buffer_id;
105 display_buffer_set.width = width;
106 display_buffer_set.height = height;
107 display_buffer_set.pitch = pitch;
108 display_buffer_set.offset = offset;
110 return (ioctl(fd, PS3GPU_CTL_DISPLAY_BUFFER_SET, &display_buffer_set));
114 set_flip_mode(int fd, int context_id, int head, int mode)
116 struct ps3gpu_ctl_set_flip_mode set_flip_mode;
118 set_flip_mode.context_id = context_id;
119 set_flip_mode.head = head;
120 set_flip_mode.mode = mode;
122 return (ioctl(fd, PS3GPU_CTL_SET_FLIP_MODE, &set_flip_mode));
126 reset_flip_status(int fd, int context_id, int head)
128 struct ps3gpu_ctl_reset_flip_status reset_flip_status;
130 reset_flip_status.context_id = context_id;
131 reset_flip_status.head = head;
133 return (ioctl(fd, PS3GPU_CTL_RESET_FLIP_STATUS, &reset_flip_status));
137 flip(int fd, int context_id, int head, unsigned long offset)
139 struct ps3gpu_ctl_flip flip;
141 flip.context_id = context_id;
142 flip.head = head;
143 flip.offset = offset;
145 return (ioctl(fd, PS3GPU_CTL_FLIP, &flip));
149 get_tiled_pitch_size(int pitch)
151 static const int tile_pitches[] = {
152 0x00000000, 0x00000200, 0x00000300, 0x00000400,
153 0x00000500, 0x00000600, 0x00000700, 0x00000800,
154 0x00000a00, 0x00000c00, 0x00000d00, 0x00000e00,
155 0x00001000, 0x00001400, 0x00001800, 0x00001a00,
156 0x00001c00, 0x00002000, 0x00002800, 0x00003000,
157 0x00003400, 0x00003800, 0x00004000, 0x00005000,
158 0x00006000, 0x00006800, 0x00007000, 0x00008000,
159 0x0000a000, 0x0000c000, 0x0000d000, 0x0000e000,
160 0x00010000,
163 int i;
165 for (i = 0; i < ARRAY_SIZE(tile_pitches) - 1; i++) {
166 if ((tile_pitches[i] < pitch) && (pitch <= tile_pitches[i + 1]))
167 return (tile_pitches[i + 1]);
170 return (0);
174 tile_set(int fd, int context_id, int tile_id, int size, int pitch,
175 int cmp_mode, int bank, int base, unsigned long offset)
177 struct ps3gpu_ctl_tile_set tile_set;
179 tile_set.context_id = context_id;
180 tile_set.tile_id = tile_id;
181 tile_set.size = size;
182 tile_set.pitch = pitch;
183 tile_set.cmp_mode = cmp_mode;
184 tile_set.bank = bank;
185 tile_set.base = base;
186 tile_set.offset = offset;
188 return (ioctl(fd, PS3GPU_CTL_TILE_SET, &tile_set));
192 tile_unset(int fd, int context_id, int tile_id, int bank,
193 unsigned long offset)
195 struct ps3gpu_ctl_tile_unset tile_unset;
197 tile_unset.context_id = context_id;
198 tile_unset.tile_id = tile_id;
199 tile_unset.bank = bank;
200 tile_unset.offset = offset;
202 return (ioctl(fd, PS3GPU_CTL_TILE_UNSET, &tile_unset));
206 save_image(const char *filename, const char *buf, int len)
208 FILE *fp;
209 int nwritten;
210 int err = 0;
212 fp = fopen(filename, "w");
213 if (!fp)
214 return (-1);
216 nwritten = fwrite(buf, 1, len, fp);
217 if (nwritten != len)
218 err = -1;
220 fclose(fp);
222 return (err);
225 void
226 dump_fifo(FILE *fp, const uint32_t *fifo, unsigned int word_count)
228 int i = 0;
230 while (word_count--) {
231 fprintf(fp, "%08x: %08x\n", i * 4, fifo[i]);
232 i++;
237 set_reference(uint32_t *fifo, uint32_t val)
239 int i = 0;
241 fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_REF);
242 fifo[i++] = val;
244 return (i);
248 transfer_data(uint32_t *fifo, uint32_t src, uint32_t dst,
249 uint32_t dst_offset, int32_t dst_pitch, uint32_t src_offset, int32_t src_pitch,
250 uint32_t row_length, uint32_t row_count)
252 int i = 0;
253 int h;
255 fifo[i++] = PS3GPU_MTH_HDR(2, 1, 0x184);
256 fifo[i++] = src;
257 fifo[i++] = dst;
259 while (row_count) {
260 h = row_count;
261 if (h > 2047)
262 h = 2047;
264 fifo[i++] = PS3GPU_MTH_HDR(8, 1, 0x30c);
265 fifo[i++] = src_offset;
266 fifo[i++] = dst_offset;
267 fifo[i++] = src_pitch;
268 fifo[i++] = dst_pitch;
269 fifo[i++] = row_length;
270 fifo[i++] = h;
271 fifo[i++] = 0x00000101;
272 fifo[i++] = 0x00000000;
274 src_offset += h * src_pitch;
275 dst_offset += h * dst_pitch;
276 row_count -= h;
279 fifo[i++] = PS3GPU_MTH_HDR(1, 1, 0x310);
280 fifo[i++] = 0x00000000;
282 return (i);
286 transfer_inline(uint32_t *fifo, uint32_t dst, uint32_t dst_offset,
287 const uint32_t *data, uint32_t word_count)
289 int odd = word_count & 1;
290 int i = 0;
292 fifo[i++] = PS3GPU_MTH_HDR(1, 3, 0x188);
293 fifo[i++] = dst;
295 fifo[i++] = PS3GPU_MTH_HDR(1, 3, 0x30c);
296 fifo[i++] = dst_offset & ~0x3f;
298 fifo[i++] = PS3GPU_MTH_HDR(2, 3, 0x300);
299 fifo[i++] = 0x0000000b;
300 fifo[i++] = 0x10001000;
302 fifo[i++] = PS3GPU_MTH_HDR(3, 5, 0x304);
303 fifo[i++] = (dst_offset >> 2) & 0xf;
304 fifo[i++] = 0x00010000 | word_count;
305 fifo[i++] = 0x00010000 | word_count;
307 fifo[i++] = PS3GPU_MTH_HDR((word_count + 1) & ~1, 5, 0x400);
309 while (word_count--)
310 fifo[i++] = *data++;
312 if (odd)
313 fifo[i++] = 0x00000000;
315 return (i);
319 flip_display_buffer(uint32_t *fifo, uint8_t channel_id, uint8_t buffer_id,
320 uint8_t head)
322 int i = 0;
324 /* reset flip label */
326 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x64);
327 fifo[i++]= (head << 4);
329 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x6c);
330 fifo[i++] = 0x00000001;
332 /* 0xcafebabe flip method */
334 fifo[i++] = PS3GPU_MTH_HDR(1, 7, 0x920 + (head << 2));
335 fifo[i++] = 0x80000000 | (channel_id << 8) | buffer_id;
337 return (i);
341 set_depth_mask(uint32_t *fifo, uint32_t mask)
343 int i = 0;
345 fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_DEPTH_MASK);
346 fifo[i++] = mask;
348 return (i);
352 set_color_mask(uint32_t *fifo, uint32_t mask)
354 int i = 0;
356 fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_COLOR_MASK);
357 fifo[i++] = mask;
359 return (i);
363 set_color_mask_mrt(uint32_t *fifo, uint32_t mask)
365 int i = 0;
367 fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_COLOR_MASK_MRT);
368 fifo[i++] = mask;
370 return (i);
374 set_clear_color(uint32_t *fifo, uint32_t color)
376 int i = 0;
378 fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_CLEAR_COLOR);
379 fifo[i++] = color;
381 return (i);
385 set_scissor(uint32_t *fifo, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
387 int i = 0;
389 fifo[i++] = PS3GPU_MTH_HDR(2, 0, PS3GPU_MTH_ADDR_SCISSOR);
390 fifo[i++] = (w << 16) | x;
391 fifo[i++] = (h << 16) | y;
393 return (i);
397 set_front_poly_mode(uint32_t *fifo, uint32_t mode)
399 int i = 0;
401 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1828);
402 fifo[i++] = mode;
404 return (i);
408 set_shade_mode(uint32_t *fifo, uint32_t mode)
410 int i = 0;
412 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x368);
413 fifo[i++] = mode;
415 return (i);
419 blend_enable(uint32_t *fifo, uint32_t enable)
421 int i = 0;
423 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x310);
424 fifo[i++] = enable;
426 return (i);
430 clear_surface(uint32_t *fifo, uint32_t mask)
432 int i = 0;
434 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d94);
435 fifo[i++] = mask;
437 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x100);
438 fifo[i++] = 0x00000000;
440 return (i);
444 set_surface(uint32_t *fifo, const struct surface_desc *sd)
446 int i = 0;
448 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x194);
449 fifo[i++] = sd->sd_color_loc[0];
451 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x18c);
452 fifo[i++] = sd->sd_color_loc[1];
454 fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x1b4);
455 fifo[i++] = sd->sd_color_loc[2];
456 fifo[i++] = sd->sd_color_loc[3];
458 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x198);
459 fifo[i++] = sd->sd_depth_loc;
461 fifo[i++] = PS3GPU_MTH_HDR(6, 0, 0x208);
462 fifo[i++] = ((uint8_t) log2(sd->sd_h) << 24) | ((uint8_t) log2(sd->sd_w) << 16) |
463 (0x0 << 12) | (0x1 << 8) |
464 (sd->sd_depth_fmt << 5) | sd->sd_color_fmt;
465 fifo[i++] = sd->sd_color_pitch[0];
466 fifo[i++] = sd->sd_color_off[0];
467 fifo[i++] = sd->sd_depth_off;
468 fifo[i++] = sd->sd_color_off[1];
469 fifo[i++] = sd->sd_color_pitch[1];
471 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x22c);
472 fifo[i++] = sd->sd_depth_pitch;
474 fifo[i++] = PS3GPU_MTH_HDR(4, 0, 0x280);
475 fifo[i++] = sd->sd_color_pitch[2];
476 fifo[i++] = sd->sd_color_pitch[3];
477 fifo[i++] = sd->sd_color_off[2];
478 fifo[i++] = sd->sd_color_off[3];
480 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x220);
481 fifo[i++] = sd->sd_color_target;
483 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x2b8);
484 fifo[i++] = (sd->sd_y << 16) | sd->sd_x;
486 fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x200);
487 fifo[i++] = (sd->sd_w << 16) | sd->sd_x;
488 fifo[i++] = (sd->sd_h << 16) | sd->sd_y;
490 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d88);
491 fifo[i++] = (0x0 << 16) | (0x1 << 12) |
492 (sd->sd_h - ((sd->sd_h >> 12) & 0x1));
494 return (i);
498 wait_label(uint32_t *fifo, uint32_t index, uint32_t val)
500 int i = 0;
502 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x64);
503 fifo[i++] = index << 4;
505 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x68);
506 fifo[i++] = val;
508 return (i);
512 write_label(uint32_t *fifo, uint32_t index, uint32_t val)
514 int i = 0;
516 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x64);
517 fifo[i++] = index << 4;
519 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x6c);
520 fifo[i++] = val;
522 return (i);
526 write_backend_label(uint32_t *fifo, uint32_t index, uint32_t val)
528 int i = 0;
530 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d6c);
531 fifo[i++] = index << 4;
533 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d70);
534 fifo[i++] = (val & 0xff00ff00) | ((val & 0xff) << 16) | ((val >> 16) & 0xff);
536 return (i);
540 write_texture_label(uint32_t *fifo, uint32_t index, uint32_t val)
542 int i = 0;
544 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d6c);
545 fifo[i++] = index << 4;
547 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d74);
548 fifo[i++] = val;
550 return (i);
554 set_viewport(uint32_t *fifo, uint16_t x, uint16_t y, uint16_t w, uint16_t h,
555 float zmin, float zmax, const float offset[4], const float scale[4])
557 int i = 0;
559 fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0xa00);
560 fifo[i++] = (w << 16) | x;
561 fifo[i++] = (h << 16) | y;
563 fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x394);
564 fifo[i++] = *(uint32_t *) &zmin;
565 fifo[i++] = *(uint32_t *) &zmax;
567 fifo[i++] = PS3GPU_MTH_HDR(8, 0, 0xa20);
568 fifo[i++] = *(uint32_t *) &offset[0];
569 fifo[i++] = *(uint32_t *) &offset[1];
570 fifo[i++] = *(uint32_t *) &offset[2];
571 fifo[i++] = *(uint32_t *) &offset[3];
572 fifo[i++] = *(uint32_t *) &scale[0];
573 fifo[i++] = *(uint32_t *) &scale[1];
574 fifo[i++] = *(uint32_t *) &scale[2];
575 fifo[i++] = *(uint32_t *) &scale[3];
577 fifo[i++] = PS3GPU_MTH_HDR(8, 0, 0xa20);
578 fifo[i++] = *(uint32_t *) &offset[0];
579 fifo[i++] = *(uint32_t *) &offset[1];
580 fifo[i++] = *(uint32_t *) &offset[2];
581 fifo[i++] = *(uint32_t *) &offset[3];
582 fifo[i++] = *(uint32_t *) &scale[0];
583 fifo[i++] = *(uint32_t *) &scale[1];
584 fifo[i++] = *(uint32_t *) &scale[2];
585 fifo[i++] = *(uint32_t *) &scale[3];
587 return (i);
591 load_vertex_prg(uint32_t *fifo, uint16_t slot, const uint32_t *prg, int instr_count)
593 int i = 0;
594 int j;
596 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1e9c);
597 fifo[i++] = slot;
599 while (instr_count >= 32) {
600 fifo[i++] = PS3GPU_MTH_HDR(32, 0, 0xb80);
602 for (j = 0; j < 32; j++) {
603 fifo[i++] = *prg++;
604 fifo[i++] = *prg++;
605 fifo[i++] = *prg++;
606 fifo[i++] = *prg++;
609 instr_count -= 32;
612 if (instr_count > 0) {
613 fifo[i++] = PS3GPU_MTH_HDR(instr_count << 2, 0, 0xb80);
615 for (j = 0; j < instr_count; j++) {
616 fifo[i++] = *prg++;
617 fifo[i++] = *prg++;
618 fifo[i++] = *prg++;
619 fifo[i++] = *prg++;
623 return (i);
627 set_vertex_prg_reg_count(uint32_t *fifo, unsigned int count)
629 int i = 0;
630 uint32_t val;
632 val = (count <= 32) ? 0x0020ffff : 0x0030ffff;
634 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ef8);
635 fifo[i++] = val;
637 return (i);
641 set_vertex_prg_start_slot(uint32_t *fifo, uint16_t slot)
643 int i = 0;
645 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ea0);
646 fifo[i++] = slot;
648 return (i);
652 set_vertex_prg_const(uint32_t *fifo, uint32_t start, uint32_t count,
653 const float *val)
655 int i = 0;
656 int j;
658 while (count >= 32) {
659 fifo[i++] = PS3GPU_MTH_HDR(33, 0, 0x1efc);
660 fifo[i++] = start;
662 for (j = 0; j < 32; j++)
663 fifo[i++] = *(uint32_t *) val++;
665 count -= 32;
666 start += 8;
669 if (count > 0) {
670 fifo[i++] = PS3GPU_MTH_HDR(count + 1, 0, 0x1efc);
671 fifo[i++] = start;
673 for (j = 0; j < count; j++)
674 fifo[i++] = *(uint32_t *) val++;
677 return (i);
681 set_vertex_attr_inmask(uint32_t *fifo, uint32_t mask)
683 int i = 0;
685 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ff0);
686 fifo[i++] = mask;
688 return (i);
692 set_vertex_attr_outmask(uint32_t *fifo, uint32_t mask)
694 int i = 0;
696 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ff4);
697 fifo[i++] = mask;
699 return (i);
703 set_frag_prg(uint32_t *fifo, uint8_t location, uint32_t offset)
705 int i = 0;
707 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x8e4);
708 fifo[i++] = offset | location;
710 return (i);
714 frag_prg_ctrl(uint32_t *fifo, uint8_t reg_count, uint8_t replace_txp_with_tex,
715 uint8_t pixel_kill, uint8_t output_from_h0, uint8_t depth_replace)
717 int i = 0;
719 if (reg_count <= 1)
720 reg_count = 2;
722 if (depth_replace)
723 depth_replace = 0x7;
725 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d60);
726 fifo[i++] = (reg_count << 24) | (replace_txp_with_tex << 15) | 0x00000400 |
727 (pixel_kill << 7) | (!output_from_h0 << 6) | (depth_replace << 1);
729 return (i);
733 draw_begin(uint32_t *fifo, uint32_t mode)
735 int i = 0;
737 fifo[i++] = 0x40000000 | PS3GPU_MTH_HDR(3, 0, 0x1714);
738 fifo[i++] = 0x00000000;
739 fifo[i++] = 0x00000000;
740 fifo[i++] = 0x00000000;
742 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808);
743 fifo[i++] = mode;
745 return (i);
749 draw_end(uint32_t *fifo)
751 int i = 0;
753 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808);
754 fifo[i++] = 0x00000000;
756 return (i);
760 set_vertex_data_arrfmt(uint32_t *fifo, uint8_t reg, uint16_t freq,
761 uint8_t stride, uint8_t size, uint8_t type)
763 int i = 0;
765 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1740 + (reg << 4));
766 fifo[i++] = (freq << 16) | (stride << 8) | (size << 4) | type;
768 return (i);
772 set_vertex_data_2f(uint32_t *fifo, uint8_t reg, const float val[2])
774 int i = 0;
776 fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x1880 + (reg << 3));
777 fifo[i++] = *(uint32_t *) &val[0];
778 fifo[i++] = *(uint32_t *) &val[1];
780 return (i);
784 set_vertex_data_4f(uint32_t *fifo, uint8_t reg, const float val[4])
786 int i = 0;
788 fifo[i++] = PS3GPU_MTH_HDR(4, 0, 0x1c00 + (reg << 4));
789 fifo[i++] = *(uint32_t *) &val[0];
790 fifo[i++] = *(uint32_t *) &val[1];
791 fifo[i++] = *(uint32_t *) &val[2];
792 fifo[i++] = *(uint32_t *) &val[3];
794 return (i);
798 set_vertex_data_arr(uint32_t *fifo, uint8_t reg,
799 uint16_t freq, uint8_t stride, uint8_t size, uint8_t type,
800 uint8_t location, uint32_t offset)
802 int i = 0;
804 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1740 + (reg << 2));
805 fifo[i++] = (freq << 16) | (stride << 8) | (size << 4) | type;
807 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1680 + (reg << 2));
808 fifo[i++] = (location << 31) | offset;
810 return (i);
814 draw_arrays(uint32_t *fifo, uint32_t mode, uint32_t first, uint32_t count)
816 int i = 0;
817 int n, m, j;
819 /* draw begin */
821 fifo[i++] = 0x40000000 | PS3GPU_MTH_HDR(3, 0, 0x1714);
822 fifo[i++] = 0x00000000;
823 fifo[i++] = 0x00000000;
824 fifo[i++] = 0x00000000;
826 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808);
827 fifo[i++] = mode;
829 while (count > 0) {
830 n = (count + 0x100 - 1) / 0x100;
831 if (n > 0x7ff)
832 n = 0x7ff;
834 fifo[i++] = 0x40000000 | PS3GPU_MTH_HDR(n, 0, 0x1814);
836 for (j = 0; j < n; j++) {
837 m = count;
838 if (m > 0x100)
839 m = 0x100;
841 fifo[i++] = ((m - 1) << 24) | first;
843 first += m;
844 count -= m;
848 /* draw end */
850 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808);
851 fifo[i++] = 0x00000000;
853 return (i);
857 invalidate_vertex_cache(uint32_t *fifo)
859 int i = 0;
861 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1710);
862 fifo[i++] = 0x00000000;
864 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1714);
865 fifo[i++] = 0x00000000;
867 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1714);
868 fifo[i++] = 0x00000000;
870 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1714);
871 fifo[i++] = 0x00000000;
873 return (i);
877 set_texture(uint32_t *fifo, uint8_t index, const struct texture_desc *td)
879 int i = 0;
881 fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x1a00 + (index << 5));
882 fifo[i++] = td->td_off;
883 fifo[i++] = (td->td_mipmap << 16) | (td->td_fmt << 8) |
884 (td->td_dimension << 4) | (td->td_border << 3) |
885 (td->td_cubemap << 2) | td->td_loc;
887 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1a18 + (index << 5));
888 fifo[i++] = (td->td_w << 16) | td->td_h;
890 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1840 + (index << 2));
891 fifo[i++] = (td->td_depth << 20) | td->td_pitch;
893 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1a10 + (index << 5));
894 fifo[i++] = td->td_remap;
896 return (i);
900 texture_ctrl(uint32_t *fifo, uint8_t index, uint8_t enable,
901 uint16_t min_lod, uint16_t max_lod, uint8_t max_aniso)
903 int i = 0;
905 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1a0c + (index << 5));
906 fifo[i++] = (enable << 31) | ((min_lod & 0xfff) << 19) |
907 ((max_lod & 0xfff) << 7) | (max_aniso << 4);
909 return (i);
913 set_texture_addr(uint32_t *fifo, uint8_t index,
914 uint8_t wrap_s, uint8_t wrap_t, uint8_t wrap_r, uint8_t unsigned_remap,
915 uint8_t zfunc, uint8_t gamma)
917 int i = 0;
919 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1a08 + (index << 5));
920 fifo[i++] = (zfunc << 28) | (gamma << 20) | (wrap_r << 16) |
921 (unsigned_remap << 12) | (wrap_t << 8) | wrap_s;
923 return (i);
927 set_texture_filter(uint32_t *fifo, uint8_t index,
928 uint16_t bias, uint8_t min, uint8_t mag, uint8_t conv)
930 int i = 0;
932 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1a14 + (index << 5));
933 fifo[i++] = (mag << 24) | (min << 16) | (conv << 13) | (bias & 0x1fff);
935 return (i);
939 invalidate_texture_cache(uint32_t *fifo, uint32_t val)
941 int i = 0;
943 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1fd8);
944 fifo[i++] = val;
946 return (i);
950 set_timestamp(uint32_t *fifo, uint32_t index)
952 int i = 0;
954 fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1800);
955 fifo[i++] = 0x01000000 | index << 4;
957 return (i);