From cdcb35e17569c1480c63b25a0b2ebf0efc4ba8b4 Mon Sep 17 00:00:00 2001 From: glevand Date: Mon, 19 Nov 2012 19:36:05 +0000 Subject: [PATCH] move display resolution and device path to Makefile; dump FIFO content to console in case it hangs; use surfaces; reset flip status --- display_buffer.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 148 insertions(+), 21 deletions(-) diff --git a/display_buffer.c b/display_buffer.c index cbdb09f..661d236 100644 --- a/display_buffer.c +++ b/display_buffer.c @@ -46,18 +46,13 @@ #include "reset_gpu_state.h" #include "util.h" -#define PS3GPU_DEV_PATH "/dev/ps3gpu" - -#define DISPLAY_WIDTH 1920 -#define DISPLAY_HEIGHT 1080 -#define DISPLAY_BPP 4 -#define DISPLAY_PITCH (DISPLAY_WIDTH * DISPLAY_BPP) - int main(int argc, char **argv) { struct ps3gpu_ctl_context_allocate context_allocate; struct ps3gpu_ctl_context_free context_free; + struct ps3gpu_ctl_set_flip_mode set_flip_mode; + struct ps3gpu_ctl_reset_flip_status reset_flip_status; struct ps3gpu_ctl_memory_allocate memory_allocate; struct ps3gpu_ctl_setup_control setup_control; struct ps3gpu_ctl_display_buffer_set display_buffer_set; @@ -115,6 +110,49 @@ main(int argc, char **argv) } printf("channel id %d\n", get_channel_id(driver_info)); + printf("flip status %d %d\n", get_flip_status(driver_info, 0), get_flip_status(driver_info, 1)); + + /* Set flip mode */ + + set_flip_mode.context_id = context_id; + set_flip_mode.head = PS3GPU_CTL_HEAD_A; + set_flip_mode.mode = PS3GPU_CTL_FLIP_MODE_VSYNC; + + err = ioctl(fd, PS3GPU_CTL_SET_FLIP_MODE, &set_flip_mode); + if (err < 0) { + perror("ioctl"); + goto done; + } + + set_flip_mode.context_id = context_id; + set_flip_mode.head = PS3GPU_CTL_HEAD_B; + set_flip_mode.mode = PS3GPU_CTL_FLIP_MODE_VSYNC; + + err = ioctl(fd, PS3GPU_CTL_SET_FLIP_MODE, &set_flip_mode); + if (err < 0) { + perror("ioctl"); + goto done; + } + + /* Reset flip status */ + + reset_flip_status.context_id = context_id; + reset_flip_status.head = PS3GPU_CTL_HEAD_A; + + err = ioctl(fd, PS3GPU_CTL_RESET_FLIP_STATUS, &reset_flip_status); + if (err < 0) { + perror("ioctl"); + goto done; + } + + reset_flip_status.context_id = context_id; + reset_flip_status.head = PS3GPU_CTL_HEAD_B; + + err = ioctl(fd, PS3GPU_CTL_RESET_FLIP_STATUS, &reset_flip_status); + if (err < 0) { + perror("ioctl"); + goto done; + } /* Allocate FIFO */ @@ -197,8 +235,13 @@ main(int argc, char **argv) control[0x10] = fifo_gaddr + 3 * sizeof(uint32_t); - while (control[0x10] != control[0x11]) - usleep(1000); + 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]); @@ -207,7 +250,7 @@ main(int argc, char **argv) memory_allocate.context_id = context_id; memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO; - memory_allocate.size = 9 * 1024 * 1024; + memory_allocate.size = ROUNDUP(DISPLAY_HEIGHT * DISPLAY_PITCH, 4 * 1024); memory_allocate.align = 12; err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate); @@ -229,11 +272,9 @@ main(int argc, char **argv) goto done; } - memset32(db[0], 0xff00ff00, DISPLAY_HEIGHT * DISPLAY_WIDTH); - memory_allocate.context_id = context_id; memory_allocate.type = PS3GPU_CTL_MEMORY_TYPE_VIDEO; - memory_allocate.size = 9 * 1024 * 1024; + memory_allocate.size = ROUNDUP(DISPLAY_HEIGHT * DISPLAY_PITCH, 4 * 1024); memory_allocate.align = 12; err = ioctl(fd, PS3GPU_CTL_MEMORY_ALLOCATE, &memory_allocate); @@ -255,8 +296,6 @@ main(int argc, char **argv) goto done; } - memset32(db[1], 0xffffff00, DISPLAY_HEIGHT * DISPLAY_WIDTH); - /* Set display buffers */ display_buffer_set.context_id = context_id; @@ -285,6 +324,41 @@ main(int argc, char **argv) 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 = 0, + .sd_depth_pitch = 64, + .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 = 0, + .sd_depth_pitch = 64, + .sd_depth_fmt = 0x2, + .sd_x = 0, + .sd_y = 0, + .sd_w = DISPLAY_WIDTH, + .sd_h = DISPLAY_HEIGHT, + }, + }; + /* Flip display buffer 0 */ setup_control.context_id = context_id; @@ -298,12 +372,32 @@ main(int argc, char **argv) goto done; } - err = flip_display_buffer(fifo, get_channel_id(driver_info), 0, 0); + err += set_surface(fifo + err, &surf_desc[0]); + 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, 0xffffff00); + err += set_scissor(fifo + err, 0, 0, 4095, 4095); + err += clear_surface(fifo + err, 0x000000f1); + + err += flip_display_buffer(fifo + err, get_channel_id(driver_info), 0, 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); - while (control[0x10] != control[0x11]) - usleep(1000); + 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]); @@ -312,6 +406,26 @@ main(int argc, char **argv) /* Flip display buffer 1 */ + /* Reset flip status */ + + reset_flip_status.context_id = context_id; + reset_flip_status.head = PS3GPU_CTL_HEAD_A; + + err = ioctl(fd, PS3GPU_CTL_RESET_FLIP_STATUS, &reset_flip_status); + if (err < 0) { + perror("ioctl"); + goto done; + } + + reset_flip_status.context_id = context_id; + reset_flip_status.head = PS3GPU_CTL_HEAD_B; + + err = ioctl(fd, PS3GPU_CTL_RESET_FLIP_STATUS, &reset_flip_status); + if (err < 0) { + perror("ioctl"); + goto done; + } + setup_control.context_id = context_id; setup_control.put = fifo_handle; setup_control.get = fifo_handle; @@ -323,12 +437,25 @@ main(int argc, char **argv) goto done; } - err = flip_display_buffer(fifo, get_channel_id(driver_info), 1, 0); + err += set_surface(fifo + err, &surf_desc[1]); + 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, 0xff00ff00); + err += set_scissor(fifo + err, 0, 0, 4095, 4095); + err += clear_surface(fifo + err, 0x000000f1); + err += flip_display_buffer(fifo + err, get_channel_id(driver_info), 1, 0); + err += wait_label(fifo + err, 0, 0x00000000); control[0x10] = fifo_gaddr + err * sizeof(uint32_t); - while (control[0x10] != control[0x11]) - usleep(1000); + 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]); -- 2.11.4.GIT