From cf8571da1c1a76edd9ca2ab1420f644801ae724a Mon Sep 17 00:00:00 2001 From: glevand Date: Mon, 19 Nov 2012 19:35:29 +0000 Subject: [PATCH] add various FIFO helper functions --- util.c | 468 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- util.h | 104 +++++++++++++++ 2 files changed, 564 insertions(+), 8 deletions(-) diff --git a/util.c b/util.c index e994f6a..9939eb5 100644 --- a/util.c +++ b/util.c @@ -30,19 +30,13 @@ #include #include #include +#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include "ps3gpu_ctl.h" #include "ps3gpu_mth.h" +#include "util.h" int save_image(const char *filename, const char *buf, int len) @@ -64,6 +58,17 @@ save_image(const char *filename, const char *buf, int len) return (err); } +void +dump_fifo(FILE *fp, const uint32_t *fifo, unsigned int word_count) +{ + int i = 0; + + while (word_count--) { + fprintf(fp, "%08x: %08x\n", i * 4, fifo[i]); + i++; + } +} + int transfer_data(uint32_t *fifo, uint32_t src, uint32_t dst, uint32_t dst_offset, int32_t dst_pitch, uint32_t src_offset, int32_t src_pitch, @@ -141,14 +146,461 @@ flip_display_buffer(uint32_t *fifo, uint8_t channel_id, uint8_t buffer_id, { int i = 0; + /* reset flip label */ + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x64); fifo[i++]= (head << 4); fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x6c); fifo[i++] = 0x00000001; + /* 0xcafebabe flip method */ + fifo[i++] = PS3GPU_MTH_HDR(1, 7, 0x920 + (head << 2)); fifo[i++] = 0x80000000 | (channel_id << 8) | buffer_id; return (i); } + +int +set_depth_mask(uint32_t *fifo, uint32_t mask) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_DEPTH_MASK); + fifo[i++] = mask; + + return (i); +} + +int +set_color_mask(uint32_t *fifo, uint32_t mask) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_COLOR_MASK); + fifo[i++] = mask; + + return (i); +} + +int +set_color_mask_mrt(uint32_t *fifo, uint32_t mask) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_COLOR_MASK_MRT); + fifo[i++] = mask; + + return (i); +} + +int +set_clear_color(uint32_t *fifo, uint32_t color) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, PS3GPU_MTH_ADDR_CLEAR_COLOR); + fifo[i++] = color; + + return (i); +} + +int +set_scissor(uint32_t *fifo, uint16_t x, uint16_t y, uint16_t w, uint16_t h) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(2, 0, PS3GPU_MTH_ADDR_SCISSOR); + fifo[i++] = (w << 16) | x; + fifo[i++] = (h << 16) | y; + + return (i); +} + +int +set_front_poly_mode(uint32_t *fifo, uint32_t mode) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1828); + fifo[i++] = mode; + + return (i); +} + +int +set_shade_mode(uint32_t *fifo, uint32_t mode) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x368); + fifo[i++] = mode; + + return (i); +} + +int +clear_surface(uint32_t *fifo, uint32_t mask) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d94); + fifo[i++] = mask; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x100); + fifo[i++] = 0x00000000; + + return (i); +} + +int +set_surface(uint32_t *fifo, const struct surface_desc *sd) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x194); + fifo[i++] = sd->sd_color_loc[0]; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x18c); + fifo[i++] = sd->sd_color_loc[1]; + + fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x1b4); + fifo[i++] = sd->sd_color_loc[2]; + fifo[i++] = sd->sd_color_loc[3]; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x198); + fifo[i++] = sd->sd_depth_loc; + + fifo[i++] = PS3GPU_MTH_HDR(6, 0, 0x208); + fifo[i++] = ((uint8_t) log2(sd->sd_h) << 24) | ((uint8_t) log2(sd->sd_w) << 16) | + (0x0 << 12) | (0x1 << 8) | + (sd->sd_depth_fmt << 5) | sd->sd_color_fmt; + fifo[i++] = sd->sd_color_pitch[0]; + fifo[i++] = sd->sd_color_off[0]; + fifo[i++] = sd->sd_depth_off; + fifo[i++] = sd->sd_color_off[1]; + fifo[i++] = sd->sd_color_pitch[1]; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x22c); + fifo[i++] = sd->sd_depth_pitch; + + fifo[i++] = PS3GPU_MTH_HDR(4, 0, 0x280); + fifo[i++] = sd->sd_color_pitch[2]; + fifo[i++] = sd->sd_color_pitch[3]; + fifo[i++] = sd->sd_color_off[2]; + fifo[i++] = sd->sd_color_off[3]; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x220); + fifo[i++] = sd->sd_color_target; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x2b8); + fifo[i++] = (sd->sd_y << 16) | sd->sd_x; + + fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x200); + fifo[i++] = (sd->sd_w << 16) | sd->sd_x; + fifo[i++] = (sd->sd_h << 16) | sd->sd_y; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d88); + fifo[i++] = (0x0 << 16) | (0x1 << 12) | + (sd->sd_h - ((sd->sd_h >> 12) & 0x1)); + + return (i); +} + +int +wait_label(uint32_t *fifo, uint32_t index, uint32_t val) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x64); + fifo[i++] = index << 4; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x68); + fifo[i++] = val; + + return (i); +} + +int +set_label(uint32_t *fifo, uint32_t index, uint32_t val) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x64); + fifo[i++] = index << 4; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x6c); + fifo[i++] = val; + + return (i); +} + +int +set_viewport(uint32_t *fifo, uint16_t x, uint16_t y, uint16_t w, uint16_t h, + float zmin, float zmax, const float offset[4], const float scale[4]) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0xa00); + fifo[i++] = (w << 16) | x; + fifo[i++] = (h << 16) | y; + + fifo[i++] = PS3GPU_MTH_HDR(2, 0, 0x394); + fifo[i++] = *(uint32_t *) &zmin; + fifo[i++] = *(uint32_t *) &zmax; + + fifo[i++] = PS3GPU_MTH_HDR(8, 0, 0xa20); + fifo[i++] = *(uint32_t *) &offset[0]; + fifo[i++] = *(uint32_t *) &offset[1]; + fifo[i++] = *(uint32_t *) &offset[2]; + fifo[i++] = *(uint32_t *) &offset[3]; + fifo[i++] = *(uint32_t *) &scale[0]; + fifo[i++] = *(uint32_t *) &scale[1]; + fifo[i++] = *(uint32_t *) &scale[2]; + fifo[i++] = *(uint32_t *) &scale[3]; + + fifo[i++] = PS3GPU_MTH_HDR(8, 0, 0xa20); + fifo[i++] = *(uint32_t *) &offset[0]; + fifo[i++] = *(uint32_t *) &offset[1]; + fifo[i++] = *(uint32_t *) &offset[2]; + fifo[i++] = *(uint32_t *) &offset[3]; + fifo[i++] = *(uint32_t *) &scale[0]; + fifo[i++] = *(uint32_t *) &scale[1]; + fifo[i++] = *(uint32_t *) &scale[2]; + fifo[i++] = *(uint32_t *) &scale[3]; + + return (i); +} + +int +load_vertex_prg(uint32_t *fifo, uint16_t slot, const uint32_t *prg, int instr_count) +{ + int i = 0; + int j; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1e9c); + fifo[i++] = slot; + + while (instr_count >= 32) { + fifo[i++] = PS3GPU_MTH_HDR(32, 0, 0xb80); + + for (j = 0; j < 32; j++) { + fifo[i++] = *prg; + fifo[i++] = *prg; + fifo[i++] = *prg; + fifo[i++] = *prg; + } + + instr_count -= 32; + } + + if (instr_count > 0) { + fifo[i++] = PS3GPU_MTH_HDR(instr_count << 2, 0, 0xb80); + + for (j = 0; j < instr_count; j++) { + fifo[i++] = *prg; + fifo[i++] = *prg; + fifo[i++] = *prg; + fifo[i++] = *prg; + } + } + + return (i); +} + +int +set_vertex_prg_reg_count(uint32_t *fifo, unsigned int count) +{ + int i = 0; + uint32_t val; + + val = (count <= 32) ? 0x0020ffff : 0x0030ffff; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ef8); + fifo[i++] = val; + + return (i); +} + +int +set_vertex_prg_start_slot(uint32_t *fifo, uint16_t slot) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ea0); + fifo[i++] = slot; + + return (i); +} + +int +set_vertex_attr_inmask(uint32_t *fifo, uint32_t mask) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ff0); + fifo[i++] = mask; + + return (i); +} + +int +set_vertex_attr_outmask(uint32_t *fifo, uint32_t mask) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1ff4); + fifo[i++] = mask; + + return (i); +} + +int +set_frag_prg(uint32_t *fifo, uint8_t location, uint32_t offset) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x8e4); + fifo[i++] = offset | location; + + return (i); +} + +int +frag_prg_ctrl(uint32_t *fifo, uint8_t reg_count, uint8_t replace_txp_with_tex, + uint8_t pixel_kill, uint8_t output_from_h0, uint8_t depth_replace) +{ + int i = 0; + + if (reg_count <= 1) + reg_count = 2; + + if (depth_replace) + depth_replace = 0x7; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1d60); + fifo[i++] = (reg_count << 24) | (replace_txp_with_tex << 15) | 0x00000400 | + (pixel_kill << 7) | (!output_from_h0 << 6) | (depth_replace << 1); + + return (i); +} + +int +draw_begin(uint32_t *fifo, uint32_t mode) +{ + int i = 0; + + fifo[i++] = 0x40000000 | PS3GPU_MTH_HDR(3, 0, 0x1714); + fifo[i++] = 0x00000000; + fifo[i++] = 0x00000000; + fifo[i++] = 0x00000000; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808); + fifo[i++] = mode; + + return (i); +} + +int +draw_end(uint32_t *fifo) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808); + fifo[i++] = 0x00000000; + + return (i); +} + +int +set_vertex_data_arrfmt(uint32_t *fifo, uint8_t reg, uint16_t freq, + uint8_t stride, uint8_t size, uint8_t type) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1740 + (reg << 4)); + fifo[i++] = (freq << 16) | (stride << 8) | (size << 4) | type; + + return (i); +} + +int +set_vertex_data_4f(uint32_t *fifo, uint8_t reg, const float val[4]) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(4, 0, 0x1c00 + (reg << 4)); + fifo[i++] = *(uint32_t *) &val[0]; + fifo[i++] = *(uint32_t *) &val[1]; + fifo[i++] = *(uint32_t *) &val[2]; + fifo[i++] = *(uint32_t *) &val[3]; + + return (i); +} + +int +set_vertex_data_arr(uint32_t *fifo, uint8_t reg, + uint16_t freq, uint8_t stride, uint8_t size, uint8_t type, + uint8_t location, uint32_t offset) +{ + int i = 0; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1740 + (reg << 2)); + fifo[i++] = (freq << 16) | (stride << 8) | (size << 4) | type; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1680 + (reg << 2)); + fifo[i++] = (location << 31) | offset; + + return (i); +} + +int +draw_arrays(uint32_t *fifo, uint32_t mode, uint32_t first, uint32_t count) +{ + int i = 0; + int j; + + /* draw begin */ + + fifo[i++] = 0x40000000 | PS3GPU_MTH_HDR(3, 0, 0x1714); + fifo[i++] = 0x00000000; + fifo[i++] = 0x00000000; + fifo[i++] = 0x00000000; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808); + fifo[i++] = mode; + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1814); + fifo[i++] = (((count - 1) & 0xff) << 24) | first; + + first += ((count - 1) & 0xff) + 1; + count -= ((count - 1) & 0xff) + 1; + + while (count >= (0x7ff * 0x100)) { + fifo[i++] = 0x40000000 | PS3GPU_MTH_HDR(0x7ff, 0, 0x1814); + + for (j = 0; j < 0x7ff; j++) { + fifo[i++] = ((0x100 - 1) << 24) | first; + first += 0x100; + } + + count -= 0x7ff * 0x100; + } + + if (count) { + fifo[i++] = 0x40000000 | PS3GPU_MTH_HDR(count, 0, 0x1814); + + for (j = 0; j < count; j++) { + fifo[i++] = ((0x100 - 1) << 24) | first; + first += 0x100; + } + } + + /* draw end */ + + fifo[i++] = PS3GPU_MTH_HDR(1, 0, 0x1808); + fifo[i++] = 0x00000000; + + return (i); +} diff --git a/util.h b/util.h index e0138b2..faadf39 100644 --- a/util.h +++ b/util.h @@ -29,6 +29,25 @@ #ifndef _UTIL_H #define _UTIL_H +#define ARRAY_SIZE(_a) (sizeof(_a) / sizeof((_a)[0])) +#define ROUNDUP(_x, _y) ((((_x) + ((_y) - 1)) / (_y)) * (_y)) + +struct surface_desc { + uint32_t sd_color_loc[4]; + uint32_t sd_color_off[4]; + uint32_t sd_color_pitch[4]; + uint8_t sd_color_fmt; + uint8_t sd_color_target; + uint32_t sd_depth_loc; + uint32_t sd_depth_off; + uint32_t sd_depth_pitch; + uint8_t sd_depth_fmt; + uint16_t sd_x; + uint16_t sd_y; + uint16_t sd_w; + uint16_t sd_h; +}; + static inline void memset32(void *buf, uint32_t val, int word_count) { @@ -44,6 +63,34 @@ get_channel_id(const volatile void *driver_info) return (*(uint32_t *) ((uint8_t *) driver_info + 0xc)); } +static inline int +get_flip_status(const volatile void *driver_info, uint8_t head) +{ + uint32_t val; + + val = *(uint32_t *) ((uint8_t *) driver_info + 0x10c0 + head * 0x40); + + return !(val >> 31); +} + +static inline int +wait_fifo_idle(volatile uint32_t *control) +{ + int count = 10000; + + while (count--) { + if (control[0x10] == control[0x11]) + break; + + usleep(100); + } + + if (control[0x10] != control[0x11]) + return (-1); + + return (0); +} + /* * How to convert image to JPG format: * @@ -53,6 +100,8 @@ get_channel_id(const volatile void *driver_info) */ int save_image(const char *filename, const char *buf, int len); +void dump_fifo(FILE *fp, const uint32_t *fifo, unsigned int word_count); + int transfer_data(uint32_t *fifo, uint32_t src, uint32_t dst, uint32_t dst_offset, int32_t dst_pitch, uint32_t src_offset, int32_t src_pitch, @@ -64,4 +113,59 @@ int transfer_inline(uint32_t *fifo, uint32_t dst, uint32_t dst_offset, int flip_display_buffer(uint32_t *fifo, uint8_t channel_id, uint8_t buffer_id, uint8_t head); +int set_depth_mask(uint32_t *fifo, uint32_t mask); + +int set_color_mask(uint32_t *fifo, uint32_t mask); + +int set_color_mask_mrt(uint32_t *fifo, uint32_t mask); + +int set_clear_color(uint32_t *fifo, uint32_t color); + +int set_scissor(uint32_t *fifo, uint16_t x, uint16_t y, uint16_t w, uint16_t h); + +int set_front_poly_mode(uint32_t *fifo, uint32_t mode); + +int set_shade_mode(uint32_t *fifo, uint32_t mode); + +int clear_surface(uint32_t *fifo, uint32_t mask); + +int set_surface(uint32_t *fifo, const struct surface_desc *sd); + +int wait_label(uint32_t *fifo, uint32_t index, uint32_t val); + +int set_label(uint32_t *fifo, uint32_t index, uint32_t val); + +int set_viewport(uint32_t *fifo, uint16_t x, uint16_t y, uint16_t w, uint16_t h, + float zmin, float zmax, const float offset[4], const float scale[4]); + +int load_vertex_prg(uint32_t *fifo, uint16_t slot, const uint32_t *prg, int instr_count); + +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_attr_inmask(uint32_t *fifo, uint32_t mask); + +int set_vertex_attr_outmask(uint32_t *fifo, uint32_t mask); + +int set_frag_prg(uint32_t *fifo, uint8_t location, uint32_t offset); + +int frag_prg_ctrl(uint32_t *fifo, uint8_t reg_count, uint8_t replace_txp_with_tex, + uint8_t pixel_kill, uint8_t output_from_h0, uint8_t depth_replace); + +int draw_begin(uint32_t *fifo, uint32_t mode); + +int draw_end(uint32_t *fifo); + +int set_vertex_data_arrfmt(uint32_t *fifo, uint8_t reg, uint16_t freq, + uint8_t stride, uint8_t size, uint8_t type); + +int set_vertex_data_4f(uint32_t *fifo, uint8_t reg, const float val[4]); + +int set_vertex_data_arr(uint32_t *fifo, uint8_t reg, + uint16_t freq, uint8_t stride, uint8_t size, uint8_t type, + uint8_t location, uint32_t offset); + +int draw_arrays(uint32_t *fifo, uint32_t mode, uint32_t first, uint32_t count); + #endif -- 2.11.4.GIT