From f8f7fa51e9e423cb0ff0a84bb80204f4c2fcc502 Mon Sep 17 00:00:00 2001 From: glevand Date: Fri, 23 Nov 2012 21:15:15 +0000 Subject: [PATCH] add test model_view_proj --- Makefile | 104 +++++++------ matrix.c | 80 ++++++++++ matrix.h | 45 ++++++ model_view_proj.c | 454 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ util.c | 29 ++++ util.h | 3 + 6 files changed, 666 insertions(+), 49 deletions(-) rewrite Makefile (62%) create mode 100644 matrix.c create mode 100644 matrix.h create mode 100644 model_view_proj.c diff --git a/Makefile b/Makefile dissimilarity index 62% index 7db2a5b..4162c43 100644 --- a/Makefile +++ b/Makefile @@ -1,49 +1,55 @@ - -CC=gcc -CFLAGS=-Wall -O2 -g -fno-strict-aliasing -CFLAGS+=-DPS3GPU_DEV_PATH=\"/dev/ps3gpu\" -CFLAGS+=-DDISPLAY_WIDTH=1920 -DDISPLAY_HEIGHT=1080 -DDISPLAY_BPP=4 -CFLAGS+=-DDISPLAY_PITCH=\(DISPLAY_WIDTH*DISPLAY_BPP\) -LDFLAGS= -LIB=-lm - -all: cursor vram_dma gart_dma inline display_buffer solid triangle \ - vertex_buffer - -cursor: util.o reset_gpu_state.o cursor.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o cursor.o $(LIB) - -vram_dma: util.o reset_gpu_state.o vram_dma.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o vram_dma.o $(LIB) - -gart_dma: util.o reset_gpu_state.o gart_dma.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o gart_dma.o $(LIB) - -inline: util.o reset_gpu_state.o inline.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o inline.o $(LIB) - -display_buffer: util.o reset_gpu_state.o display_buffer.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o display_buffer.o $(LIB) - -solid: util.o reset_gpu_state.o solid.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o solid.o $(LIB) - -triangle: util.o reset_gpu_state.o triangle.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o triangle.o $(LIB) - -vertex_buffer: util.o reset_gpu_state.o vertex_buffer.o - $(CC) $(LDFLAGS) -o $@ util.o reset_gpu_state.o vertex_buffer.o $(LIB) - -%.o: %.c - $(CC) $(CFLAGS) -c $< - -clean: - rm -f util.o reset_gpu_state.o - rm -f cursor.o cursor - rm -f vram_dma.o vram_dma - rm -f gart_dma.o gart_dma - rm -f inline.o inline - rm -f display_buffer.o display_buffer - rm -f solid.o solid - rm -f triangle.o triangle - rm -f vertex_buffer.o vertex_buffer + +CC=gcc +CFLAGS=-Wall -O2 -g -fno-strict-aliasing +CFLAGS+=-DPS3GPU_DEV_PATH=\"/dev/ps3gpu\" +CFLAGS+=-DDISPLAY_WIDTH=1920 -DDISPLAY_HEIGHT=1080 -DDISPLAY_BPP=4 +CFLAGS+=-DDISPLAY_PITCH=\(DISPLAY_WIDTH*DISPLAY_BPP\) +LDFLAGS= +SRC=util.c matrix.c reset_gpu_state.c +OBJ=$(SRC:.c=.o) +LIB=-lm + +all: cursor vram_dma gart_dma inline display_buffer solid triangle \ + vertex_buffer model_view_proj + +cursor: $(OBJ) cursor.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) cursor.o $(LIB) + +vram_dma: $(OBJ) vram_dma.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) vram_dma.o $(LIB) + +gart_dma: $(OBJ) gart_dma.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) gart_dma.o $(LIB) + +inline: $(OBJ) inline.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) inline.o $(LIB) + +display_buffer: $(OBJ) display_buffer.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) display_buffer.o $(LIB) + +solid: $(OBJ) solid.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) solid.o $(LIB) + +triangle: $(OBJ) triangle.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) triangle.o $(LIB) + +vertex_buffer: $(OBJ) vertex_buffer.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) vertex_buffer.o $(LIB) + +model_view_proj: $(OBJ) model_view_proj.o + $(CC) $(LDFLAGS) -o $@ $(OBJ) model_view_proj.o $(LIB) + +%.o: %.c + $(CC) $(CFLAGS) -c $< + +clean: + rm -f $(OBJ) + rm -f cursor.o cursor + rm -f vram_dma.o vram_dma + rm -f gart_dma.o gart_dma + rm -f inline.o inline + rm -f display_buffer.o display_buffer + rm -f solid.o solid + rm -f triangle.o triangle + rm -f vertex_buffer.o vertex_buffer + rm -f model_view_proj.o model_view_proj diff --git a/matrix.c b/matrix.c new file mode 100644 index 0000000..9e3e332 --- /dev/null +++ b/matrix.c @@ -0,0 +1,80 @@ +/*- + * Copyright (C) 2011, 2012 glevand + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#include "matrix.h" + +void +matrix_ident(matrix_t m) +{ + memset(m, 0, sizeof(m)); + MATRIX_ELEM(m, 0, 0) = 1.0f; + MATRIX_ELEM(m, 1, 1) = 1.0f; + MATRIX_ELEM(m, 2, 2) = 1.0f; + MATRIX_ELEM(m, 3, 3) = 1.0f; +} + +void +matrix_trans(matrix_t m, float x, float y, float z) +{ + matrix_ident(m); + MATRIX_ELEM(m, 0, 3) = x; + MATRIX_ELEM(m, 1, 3) = y; + MATRIX_ELEM(m, 2, 3) = z; +} + +void +matrix_mult(matrix_t m, const matrix_t m1, const matrix_t m2) +{ + int i, j; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + MATRIX_ELEM(m, i, j) = + MATRIX_ELEM(m1, i, 0) * MATRIX_ELEM(m2, 0, j) + + MATRIX_ELEM(m1, i, 1) * MATRIX_ELEM(m2, 1, j) + + MATRIX_ELEM(m1, i, 2) * MATRIX_ELEM(m2, 2, j) + + MATRIX_ELEM(m1, i, 3) * MATRIX_ELEM(m2, 3, j); + } + } +} + +void +matrix_proj(matrix_t m, float top, float bottom, float left, float right, + float near, float far) +{ + memset(m, 0, sizeof(m)); + MATRIX_ELEM(m, 0, 0) = (2.0f * near) / (right - left); + MATRIX_ELEM(m, 0, 2) = (right + left) / (right - left); + MATRIX_ELEM(m, 1, 1) = (2.0f * near) / (bottom - top); + MATRIX_ELEM(m, 1, 2) = (top + bottom) / (top - bottom); + MATRIX_ELEM(m, 2, 2) = -(far + near) / (far - near); + MATRIX_ELEM(m, 2, 3) = -(2.0f *far * near) / (far - near); + MATRIX_ELEM(m, 3, 2) = -1.0f; +} diff --git a/matrix.h b/matrix.h new file mode 100644 index 0000000..0641b27 --- /dev/null +++ b/matrix.h @@ -0,0 +1,45 @@ +/*- + * Copyright (C) 2011, 2012 glevand + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MATRIX_H +#define _MATRIX_H + +#define MATRIX_ELEM(_m, _i, _j) ((_m)[(_i) * 4 + (_j)]) + +typedef float matrix_t[16]; + +void matrix_ident(matrix_t m); + +void matrix_trans(matrix_t m, float x, float y, float z); + +void matrix_mult(matrix_t m, const matrix_t m1, const matrix_t m2); + +void matrix_proj(matrix_t m, float top, float bottom, float left, float right, + float near, float far); + +#endif diff --git a/model_view_proj.c b/model_view_proj.c new file mode 100644 index 0000000..f33f74b --- /dev/null +++ b/model_view_proj.c @@ -0,0 +1,454 @@ +/*- + * Copyright (C) 2011, 2012 glevand + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ps3gpu_ctl.h" +#include "ps3gpu_mth.h" +#include "reset_gpu_state.h" +#include "util.h" +#include "matrix.h" + +int +main(int argc, char **argv) +{ + struct ps3gpu_ctl_context_allocate context_allocate; + struct ps3gpu_ctl_context_free context_free; + int context_id; + volatile uint32_t *control; + volatile uint8_t *driver_info; + uint32_t *fifo, *reset_gpu, *db[2], *zb, *fp; + unsigned long fifo_handle, reset_gpu_handle, db_handle[2], zb_handle, fp_handle; + unsigned int fifo_gaddr, reset_gpu_gaddr, db_gaddr[2], zb_gaddr, fp_gaddr; + matrix_t mat_proj, mat_view, mat; + int fd = -1; + int i, err; + + /* Open GPU device */ + + fd = open(PS3GPU_DEV_PATH, O_RDWR); + if (fd < 0) { + perror("open"); + goto done; + } + + /* Create GPU context */ + + context_allocate.vram_size = 64; /* MB */ + + err = ioctl(fd, PS3GPU_CTL_CONTEXT_ALLOCATE, &context_allocate); + if (err < 0) { + perror("ioctl"); + goto done; + } + + context_id = context_allocate.context_id; + + printf("context id %d\n", context_id); + printf("control handle 0x%lx size %d\n", + context_allocate.control_handle, context_allocate.control_size); + printf("driver_info handle 0x%lx size %d\n", + context_allocate.driver_info_handle, context_allocate.driver_info_size); + + /* Map control registers */ + + control = mmap(NULL, context_allocate.control_size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, context_allocate.control_handle); + if (control == (void *) MAP_FAILED) { + perror("mmap"); + goto done; + } + + /* Map driver info */ + + driver_info = mmap(NULL, context_allocate.driver_info_size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, context_allocate.driver_info_handle); + if (driver_info == (void *) MAP_FAILED) { + perror("mmap"); + goto done; + } + + printf("channel id %d\n", get_channel_id(driver_info)); + + /* Allocate FIFO */ + + err = memory_allocate(fd, context_id, PS3GPU_CTL_MEMORY_TYPE_GART, + 64 * 1024, 12, &fifo_handle, &fifo_gaddr, (void **) &fifo); + if (err < 0) { + perror("memory_allocate"); + goto done; + } + + printf("FIFO handle 0x%lx gpu addr 0x%08x\n", + fifo_handle, fifo_gaddr); + + /* Setup FIFO */ + + err = setup_control(fd, context_id, fifo_handle, fifo_handle, 0xdeadbabe); + if (err < 0) { + perror("setup_control"); + goto done; + } + + printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + + /* Allocate FIFO for resetting GPU state */ + + err = memory_allocate(fd, context_id, PS3GPU_CTL_MEMORY_TYPE_GART, + 4 * 1024, 12, &reset_gpu_handle, &reset_gpu_gaddr, (void **)&reset_gpu); + if (err < 0) { + perror("memory_allocate"); + goto done; + } + + printf("reset GPU state handle 0x%lx gpu addr 0x%08x\n", + reset_gpu_handle, reset_gpu_gaddr); + + memcpy(reset_gpu, reset_gpu_state_3d, reset_gpu_state_3d_size); + + /* Kick FIFO */ + + fifo[0] = PS3GPU_MTH_HDR(0, 0, reset_gpu_gaddr | PS3GPU_MTH_ADDR_CALL); + fifo[1] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_REF); + fifo[2] = 0xcafef00d; + + control[0x10] = fifo_gaddr + 3 * sizeof(uint32_t); + + err = wait_fifo_idle(control); + if (err < 0) { + fprintf(stderr, "FIFO timeout: put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + dump_fifo(stderr, fifo, 0x400); + goto done; + } + + printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + + /* Allocate display buffers */ + + err = memory_allocate(fd, context_id, PS3GPU_CTL_MEMORY_TYPE_VIDEO, + ROUNDUP(DISPLAY_HEIGHT * DISPLAY_PITCH, 4 * 1024), 12, + &db_handle[0], &db_gaddr[0], (void **) &db[0]); + if (err < 0) { + perror("memory_allocate"); + goto done; + } + + printf("DB0 handle 0x%lx gpu addr 0x%08x\n", + db_handle[0], db_gaddr[0]); + + err = memory_allocate(fd, context_id, PS3GPU_CTL_MEMORY_TYPE_VIDEO, + ROUNDUP(DISPLAY_HEIGHT * DISPLAY_PITCH, 4 * 1024), 12, + &db_handle[1], &db_gaddr[1], (void **) &db[1]); + if (err < 0) { + perror("memory_allocate"); + goto done; + } + + printf("DB1 handle 0x%lx gpu addr 0x%08x\n", + db_handle[1], db_gaddr[1]); + + /* Allocate depth buffer */ + + err = memory_allocate(fd, context_id, PS3GPU_CTL_MEMORY_TYPE_VIDEO, + ROUNDUP(DISPLAY_HEIGHT * DISPLAY_PITCH, 4 * 1024), 12, + &zb_handle, &zb_gaddr, (void **) &zb); + if (err < 0) { + perror("memory_allocate"); + goto done; + } + + printf("ZB handle 0x%lx gpu addr 0x%08x\n", + zb_handle, zb_gaddr); + + /* Allocate fragment program */ + + err = memory_allocate(fd, context_id, PS3GPU_CTL_MEMORY_TYPE_VIDEO, + 4 * 1024, 12, &fp_handle, &fp_gaddr, (void **) &fp); + if (err < 0) { + perror("memory_allocate"); + goto done; + } + + printf("FP handle 0x%lx gpu addr 0x%08x\n", + fp_handle, fp_gaddr); + + /* Set display buffers */ + + err = display_buffer_set(fd, context_id, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, + DISPLAY_PITCH, db_handle[0]); + if (err < 0) { + perror("display_buffer_set"); + goto done; + } + + err = display_buffer_set(fd, context_id, 1, DISPLAY_WIDTH, DISPLAY_HEIGHT, + DISPLAY_PITCH, db_handle[1]); + if (err < 0) { + perror("display_buffer_set"); + goto done; + } + + const struct surface_desc surf_desc[] = { + /* display buffer 0 */ + { + .sd_color_loc = { 0xfeed0000, 0xfeed0000, 0xfeed0000, 0xfeed0000 }, + .sd_color_off = { db_gaddr[0], 0, 0, 0 }, + .sd_color_pitch = { DISPLAY_PITCH, 64, 64, 64 }, + .sd_color_fmt = 0x8, + .sd_color_target = 0x1, + .sd_depth_loc = 0xfeed0000, + .sd_depth_off = zb_gaddr, + .sd_depth_pitch = DISPLAY_PITCH, + .sd_depth_fmt = 0x2, + .sd_x = 0, + .sd_y = 0, + .sd_w = DISPLAY_WIDTH, + .sd_h = DISPLAY_HEIGHT, + }, + /* display buffer 1 */ + { + .sd_color_loc = { 0xfeed0000, 0xfeed0000, 0xfeed0000, 0xfeed0000 }, + .sd_color_off = { db_gaddr[1], 0, 0, 0 }, + .sd_color_pitch = { DISPLAY_PITCH, 64, 64, 64 }, + .sd_color_fmt = 0x8, + .sd_color_target = 0x1, + .sd_depth_loc = 0xfeed0000, + .sd_depth_off = zb_gaddr, + .sd_depth_pitch = DISPLAY_PITCH, + .sd_depth_fmt = 0x2, + .sd_x = 0, + .sd_y = 0, + .sd_w = DISPLAY_WIDTH, + .sd_h = DISPLAY_HEIGHT, + }, + }; + + const uint32_t clear_color[] = { + 0xff404040, + 0xffffffff, + }; + + const float vp_offset[] = { DISPLAY_WIDTH * 0.5f, DISPLAY_HEIGHT * 0.5f, 0.5f, 0.0f }; + const float vp_scale[] = { DISPLAY_WIDTH * 0.5f, DISPLAY_HEIGHT * 0.5f, 0.5f, 0.0f }; + + const uint32_t vertex_prg[] = { + /* MOV o[1], v[3] */ + 0x401f9c6c, 0x0040030d, 0x8106c083, 0x6041ff84, + /* DP4 o[0].w, v[0], c[259] */ + 0x401f9c6c, 0x01d0300d, 0x8106c0c3, 0x60403f80, + /* DP4 o[0].z, v[0], c[258] */ + 0x401f9c6c, 0x01d0200d, 0x8106c0c3, 0x60405f80, + /* DP4 o[0].y, v[0], c[257] */ + 0x401f9c6c, 0x01d0100d, 0x8106c0c3, 0x60409f80, + /* DP4 o[0].x, v[0], c[256] */ + 0x401f9c6c, 0x01d0000d, 0x8106c0c3, 0x60411f81, + }; + + uint32_t frag_prg[] = { + /* MOVR R0, f[1] */ + 0x01003e01, 0x1c9dc801, 0x0001c800, 0x3fe1c800, + }; + + /* + * (0.0, -0.5) + * /\ + * / \ + * / \ + * / \ + * (-0.5, 0.5) /________\ (0.5, 0.5) + * + */ + + const float triangle_pos[][4] = { + /* xyzw */ + { 0.0f, -0.5f, -1.0f, 1.0f }, + { -0.5f, 0.5f, -1.0f, 1.0f }, + { 0.5f, 0.5f, -1.0f, 1.0f }, + }; + const float triangle_color[][4] = { + /* rgba */ + { 1.0f, 0.0f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f }, + }; + + /* Swap half-words in fragment program */ + + for (i = 0; i < ARRAY_SIZE(frag_prg); i++) + frag_prg[i] = (frag_prg[i] << 16) | (frag_prg[i] >> 16); + + err = setup_control(fd, context_id, fifo_handle, fifo_handle, 0xdeadbabe); + if (err < 0) { + perror("setup_control"); + goto done; + } + + printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + + /* Transfer fragment program to VRAM */ + + err += transfer_inline(fifo + err, 0xfeed0000, fp_gaddr, + frag_prg, ARRAY_SIZE(frag_prg)); + + control[0x10] = fifo_gaddr + err * sizeof(uint32_t); + + err = wait_fifo_idle(control); + if (err < 0) { + fprintf(stderr, "FIFO timeout: put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + dump_fifo(stderr, fifo, 0x400); + goto done; + } + + printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + + for (i = 0; i < ARRAY_SIZE(surf_desc); i++) { + err = setup_control(fd, context_id, fifo_handle, fifo_handle, 0xdeadbabe); + if (err < 0) { + perror("setup_control"); + goto done; + } + + printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + + err += set_surface(fifo + err, &surf_desc[i]); + err += set_depth_mask(fifo + err, 0x00000000); + err += set_color_mask(fifo + err, 0x01010101); + err += set_color_mask_mrt(fifo + err, 0x00000000); + err += set_clear_color(fifo + err, clear_color[i]); + err += set_scissor(fifo + err, 0, 0, 4095, 4095); + err += clear_surface(fifo + err, 0x000000f1); + + err += set_viewport(fifo + err, 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, + 0.0f, 1.0f, vp_offset, vp_scale); + + /* Compute MVP matrix */ + + matrix_proj(mat_proj, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 10000.0f); + matrix_trans(mat_view, 0.0f, 0.0f, -4.0f); + MATRIX_ELEM(mat_view, 0, 0) = 1.0f / (16.0f / 9.0f); + matrix_mult(mat, mat_proj, mat_view); + + /* Set vertex shader */ + + err += load_vertex_prg(fifo + err, 0, vertex_prg, ARRAY_SIZE(vertex_prg) / 4); + err += set_vertex_prg_start_slot(fifo + err, 0); + err += set_vertex_prg_reg_count(fifo + err, 2); + err += set_vertex_prg_const(fifo + err, 256, 16, mat); + err += set_vertex_attr_inmask(fifo + err, (1 << 3) | (1 << 0)); + err += set_vertex_attr_outmask(fifo + err, (1 << 2) | (1 << 0)); + + /* Set fragment shader */ + + err += set_frag_prg(fifo + err, 0x1, fp_gaddr); + err += frag_prg_ctrl(fifo + err, 2, 0, 0, 0, 0); + + err += set_front_poly_mode(fifo + err, 0x1b02); + err += set_shade_mode(fifo + err, 0x1d01); + + /* register 0 - position */ + err += set_vertex_data_arrfmt(fifo + err, 0, 0, 0, 0, 2); + /* register 3 - color */ + err += set_vertex_data_arrfmt(fifo + err, 3, 0, 0, 0, 2); + + err += draw_begin(fifo + err, 0x5); + err += set_vertex_data_4f(fifo + err, 3, triangle_color[0]); + err += set_vertex_data_4f(fifo + err, 0, triangle_pos[0]); + err += set_vertex_data_4f(fifo + err, 3, triangle_color[1]); + err += set_vertex_data_4f(fifo + err, 0, triangle_pos[1]); + err += set_vertex_data_4f(fifo + err, 3, triangle_color[2]); + err += set_vertex_data_4f(fifo + err, 0, triangle_pos[2]); + err += draw_end(fifo + err); + + err += flip_display_buffer(fifo + err, get_channel_id(driver_info), i, 0); + + /* + * Label with index 0 (head 0) is set by LV1 to 0x00000000 when flip is complete. + * Let GPU wait for it. + */ + + err += wait_label(fifo + err, 0, 0x00000000); + + control[0x10] = fifo_gaddr + err * sizeof(uint32_t); + + err = wait_fifo_idle(control); + if (err < 0) { + fprintf(stderr, "FIFO timeout: put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + dump_fifo(stderr, fifo, 0x400); + goto done; + } + + printf("FIFO put 0x%08x get 0x%08x ref 0x%08x\n", + control[0x10], control[0x11], control[0x12]); + + usleep(1000000); + } + + save_image("image.argb", (const char *) db[0], DISPLAY_PITCH * DISPLAY_HEIGHT); + + /* Destroy GPU context */ + + context_free.context_id = context_id; + + err = ioctl(fd, PS3GPU_CTL_CONTEXT_FREE, &context_free); + if (err < 0) { + perror("ioctl"); + goto done; + } + +done: + + if (fd >= 0) + close(fd); + + /* Restore console */ + + ioctl(0, SW_TEXT_80x25, NULL); + + exit(0); +} diff --git a/util.c b/util.c index a70e5b3..3b3983d 100644 --- a/util.c +++ b/util.c @@ -556,6 +556,35 @@ set_vertex_prg_start_slot(uint32_t *fifo, uint16_t slot) } int +set_vertex_prg_const(uint32_t *fifo, uint32_t start, uint32_t count, + const float *val) +{ + int i = 0; + int j; + + while (count >= 32) { + fifo[i++] = PS3GPU_MTH_HDR(33, 0, 0x1efc); + fifo[i++] = start; + + for (j = 0; j < 32; j++) + fifo[i++] = *(uint32_t *) val++; + + count -= 32; + start += 8; + } + + if (count > 0) { + fifo[i++] = PS3GPU_MTH_HDR(count + 1, 0, 0x1efc); + fifo[i++] = start; + + for (j = 0; j < count; j++) + fifo[i++] = *(uint32_t *) val++; + } + + return (i); +} + +int set_vertex_attr_inmask(uint32_t *fifo, uint32_t mask) { int i = 0; diff --git a/util.h b/util.h index ccd0730..2d6598b 100644 --- a/util.h +++ b/util.h @@ -163,6 +163,9 @@ int set_vertex_prg_reg_count(uint32_t *fifo, unsigned int count); int set_vertex_prg_start_slot(uint32_t *fifo, uint16_t slot); +int set_vertex_prg_const(uint32_t *fifo, uint32_t start, uint32_t count, + const float *val); + int set_vertex_attr_inmask(uint32_t *fifo, uint32_t mask); int set_vertex_attr_outmask(uint32_t *fifo, uint32_t mask); -- 2.11.4.GIT