📄 fgl.c
字号:
break;
}
*(offset + 12) = 0;
*(offset + 13) = i;
}
FGLAPI fgl_texture ( const uint32 unit, void * texinfo )
{
struct texture_info tex;
uint32 buf[18];
memcpy((void *)&tex, texinfo, sizeof(struct texture_info));
ASSERT(unit <= 7);
ASSERT((tex.usize < 2048) && (tex.vsize < 2048) && (tex.psize < 2048));
buf[0] = ((tex.mipmap_filter) |
((tex.use_minfilter ? 1:0) << 2) |
((tex.use_magfilter ? 1:0) << 3) |
((tex.non_parametric ? 1:0) << 4) |
(tex.wmode << 6) |
(tex.vmode << 8) |
(tex.umode << 10) |
(tex.texmfmt << 12) |
(tex.palfmt << 17) |
((tex.rgba_order ? 1:0) << 19) |
((tex.use_expansion ? 1:0) << 20) |
(tex.ckey << 21) |
(tex.textype << 27));
buf[1] = tex.usize;
buf[2] = tex.vsize;
buf[3] = tex.psize;
if(tex.mipmap_filter) {
_gen_mipmap_offset(tex.texmfmt, tex.usize, tex.vsize, &buf[4]);
memcpy((void *)(FGTU_TSTA0 + unit * 0x50), (void *)buf, sizeof(buf));
}
else {
WRITEREG((FGTU_TSTA0 + unit * 0x50), buf[0]);
WRITEREG((FGTU_USIZE0 + unit * 0x50), buf[1]);
WRITEREG((FGTU_VSIZE0 + unit * 0x50), buf[2]);
WRITEREG((FGTU_WSIZE0 + unit * 0x50), buf[3]);
WRITEREG((FGTU_TBADD0 + unit * 0x50), tex.address);
}
}
FGLAPI fgl_mipmap_level ( const uint32 unit, const uint32 min, const uint32 max)
{
ASSERT( unit > 7 );
ASSERT( (max < 12) && (min < 12) && (min > max) );
WRITEREG((FGTU_T_MIN_L0 + unit * 0x50), min);
WRITEREG((FGTU_T_MAX_L0 + unit * 0x50), max);
}
FGLAPI fgl_ckey ( const uint32 unit, const uint32 r, const uint32 g, const uint32 b )
{
ASSERT(unit <= 1);
WRITEREG((FGTU_CKEY1 + unit * 4), (b | (g << 8) | (r << 16)));
}
FGLAPI fgl_ckey_yuv ( const uint32 u /*cb*/, const uint32 v/*cr*/ )
{
WRITEREG(FGTU_CKYUV, (v | (u << 8)));
}
FGLAPI fgl_ckey_mask ( const uint32 mask )
{
WRITEREG(FGTU_CKMASK, (mask & 0x7));
}
FGLAPI fgl_load_palettet ( const void * palette, const fglenum format, const uint32 size )
{
uint32 i = 0;
ushort * uspal = 0;
uint32 * uipal = 0;
ASSERT(size <= 256);
switch(format)
{
case PAL_ARGB1555 :
case PAL_RGB565 :
case PAL_ARGB4444 :
{
uspal = (ushort *)palette;
for( i = size; i > 0; i-- ) {
WRITEREG(FGTU_PALETTE_ADDR, i);
WRITEREGS(FGTU_PALETTE_IN, uspal[i]);
}
}
break;
case PAL_ARGB8888 :
{
uipal = (uint32 *)palette;
for( i = size; i > 0; i-- ) {
WRITEREG(FGTU_PALETTE_ADDR, i);
WRITEREG(FGTU_PALETTE_IN, uipal[i]);
}
}
break;
default :
ASSERT(0);
break;
}
}
static bool _power_of_two ( uint32 value )
{
if (!value)
return true;
while (!(value & 1))
value >>= 1;
value >>= 1;
return value == 0;
}
static uint32 _log ( uint32 value )
{
uint32 result = 0;
while (value > 1) {
++result;
value >>= 1;
}
return result;
}
FGLAPI fgl_vtxtex ( const uint32 unit, void * vtxtex )
{
struct vtxtex_info * p = (struct vtxtex_info *)vtxtex;
ASSERT( unit < 4 );
ASSERT( _power_of_two(p->usize) );
ASSERT( _power_of_two(p->vsize) );
ASSERT( _log(p->usize) <= 11 );
ASSERT( _log(p->vsize) <= 11 );
WRITEREG((FGTU_VTSTA + unit * 8), ((_log(p->vsize)) | ((_log(p->usize)) << 4) | (p->vmode << 8) | (p->umode << 10)));
WRITEREG((FGTU_VTBADDR + unit * 8), p->base);
}
/*****************************************************************************
*
* Per-fragment Unit Register-level API
*
*****************************************************************************/
FGLAPI fgl_scissor ( const int32 x, const int32 y, const int32 width, const int32 height )
{
ASSERT(x < 4096 && y < 4095 && width < 4096 && height < 4096);
WRITEREG(FGPF_SCISSOR_X, (uint32)((1 << 31) | ((x + width) << 16) | x ));
WRITEREG(FGPF_SCISSOR_Y, (uint32)((y << 16) | (y - height)));
}
FGLAPI fgl_disable_scissor ( void )
{
WRITEREG(FGPF_SCISSOR_X, 0);
}
FGLAPI fgl_alpha ( const fglenum func, const uint32 ref )
{
ASSERT(ref < 256);
WRITEREG(FGPF_ALPHAT, ((ref << 4) | (func << 1) | 1));
}
FGLAPI fgl_disable_alpha ( void )
{
WRITEREG(FGPF_ALPHAT, 0);
}
FGLAPI fgl_stencil ( void * stencilinfo )
{
struct stencil_info sinfo;
memcpy((void *)&sinfo, stencilinfo, sizeof(struct stencil_info));
ASSERT( sinfo.ref <= 256 );
// Thomas, Kim : software workaround
#ifdef WORKAROUND_STENCIL_FUNC_SWAP
switch(sinfo.func)
{
case CF_LESS:
sinfo.func = CF_GREATER;
break;
case CF_LEQUAL:
sinfo.func = CF_GEQUAL;
break;
case CF_GREATER:
sinfo.func = CF_LESS;
break;
case CF_GEQUAL:
sinfo.func = CF_LEQUAL;
break;
}
#endif
switch (sinfo.face)
{
case BACKFACE:
WRITEREG(FGPF_FRONTST, ((sinfo.zpass << 29) | (sinfo.zfail << 26) | (sinfo.sfail << 23) |
(sinfo.mask << 12) | (sinfo.ref << 4) | (sinfo.func << 1) | 1));
break;
case FRONTFACE:
WRITEREG(FGPF_BACKST, ((sinfo.zpass << 29) | (sinfo.zfail << 26) | (sinfo.sfail << 23) |
(sinfo.mask << 12) | (sinfo.ref << 4) | (sinfo.func << 1)));
break;
case FRONTBACK:
WRITEREG(FGPF_FRONTST, ((sinfo.zpass << 29) | (sinfo.zfail << 26) | (sinfo.sfail << 23) |
(sinfo.mask << 12) | (sinfo.ref << 4) | (sinfo.func << 1) | 1));
WRITEREG(FGPF_BACKST, ((sinfo.zpass << 29) | (sinfo.zfail << 26) | (sinfo.sfail << 23) |
(sinfo.mask << 12) | (sinfo.ref << 4) | (sinfo.func << 1)));
break;
default :
ASSERT(0);
break;
}
}
FGLAPI fgl_disable_stencil ( void )
{
WRITEREG(FGPF_FRONTST, 0);
}
FGLAPI fgl_depth ( const fglenum func)
{
WRITEREG(FGPF_DEPTHT, ((func << 1) | 1));
}
FGLAPI fgl_disable_depth ( void )
{
WRITEREG(FGPF_DEPTHT, 0);
}
FGLAPI fgl_blend ( void * blendinfo )
{
struct blend_info * p = (struct blend_info *)blendinfo;
WRITEREG(FGPF_BLEND, (1 | (p->color << 1) | (p->salpha << 5) | (p->dcolor << 9) |
(p->dalpha << 13) | (p->cequa << 17) | (p->aequa << 20)));
WRITEREG(FGPF_CCLR, p->color);
}
FGLAPI fgl_disable_blend ( void )
{
WRITEREG(FGPF_BLEND, 0);
}
FGLAPI fgl_blend_color ( const uint32 r, const uint32 g, const uint32 b, const uint32 a )
{
WRITEREG(FGPF_CCLR, (((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)));
}
FGLAPI fgl_logicop ( const fglenum opcode )
{
WRITEREG(FGPF_LOGOP, ((opcode << 5) | (opcode << 1) | 1));
}
FGLAPI fgl_disable_logicop ( void )
{
WRITEREG(FGPF_LOGOP, 0);
}
FGLAPI fgl_color_mask ( const bool r, const bool g, const bool b, const bool a )
{
WRITEREG(FGPF_CBMSK, (((r)?8:0) | ((g)?4:0) | ((b)?2:0) | ((a)?1:0)));
}
FGLAPI fgl_stencil_depth_mask ( const uint32 fsmask, const uint32 bsmask, const bool dmask )
{
ASSERT( fsmask <= 256 && bsmask <= 256 );
WRITEREG(FGPF_DBMSK, ((fsmask << 24) | (bsmask << 16) | (dmask)?1:0));
}
FGLAPI fgl_colorbuf ( void * fbinfo )
{
struct fbctrl_info * p = (struct fbctrl_info *)fbinfo;
ASSERT( p->threshold <= 256 && p->alpha <= 256 );
WRITEREG(FGPF_FBCTL, ((p->opaque << 20) | (p->threshold << 12) | (p->alpha << 4) |
(p->dither << 3) | p->format));
}
FGLAPI fgl_depthbuf_base ( const uint32 base )
{
WRITEREG(FGPF_DBADDR, base);
}
FGLAPI fgl_colorbuf_base ( const uint32 base )
{
WRITEREG(FGPF_CBADDR, base);
}
FGLAPI fgl_framebuf_stride ( const uint32 stride )
{
WRITEREG(FGPF_FBW, stride);
}
/*****************************************************************************
*
* Vertex/Fragment Shader Register-level API
*
*****************************************************************************/
int32 fgl_execute_mode ( fglenum mode )
{
uint32 regval = 0;
READREGP(FGPS_EXEMODE, regval);
//if(regval == mode) return 0;
if(mode) {
if( rFGPS_IBSTATUS & 0x1 ) return 1;
WRITEREG(FGPS_EXEMODE, 1);
} else {
if( rFGGB_PIPESTATE & PSF_FS ) return 1;
WRITEREG(FGPS_EXEMODE, 0);
}
return 0;
}
FGLAPI fgl_vs_pc ( const uint32 start, const uint32 end, const bool endignore )
{
ASSERT((start < 512) && (end < 512) && (end > start));
WRITEREG(FGVS_PCRANGE, (start | (end << 16) | ((endignore)?1:0 << 31)));
// TODO need a verification : copy pc into vs inside
WRITEREG(FGVS_CONFIG, 1);
}
FGLAPI fgl_vs_inattrib ( const uint32 size )
{
// Max attribute sizes are 10 in vertex shader
ASSERT(size <= 10);
WRITEREG(FGVS_ATTRIBNUM, size);
}
#if 0
uint32 fgl_write_cfmem ( uint32 offset, uint32 size, float *data )
{
uint32 i;
uint32 * dst = (uint32 *)(FGVS_CFLOAT + (offset * 4));
for ( i = 0; i < size; i++ )
{
WRITEREGF(dst++, *data++);
offset++;
}
return offset;
}
#endif
#define VSMAGIC 0x20205356
#define FSMAGIC 0x20205350
#define SHADERVER 0xFFFF0003
int32 fgl_load_vs ( const uint32 *program )
{
uint32 * pmem = 0;
uint32 * pbody = 0;
uint32 size = 0;
uint32 tmp = 0;
struct shader_hdr * phdr = (struct shader_hdr *)program;
pbody = (uint32 *)&phdr[1];
if ((phdr->magic != VSMAGIC) || (phdr->version != SHADERVER))
{
return 1;
}
if(phdr->in_tbl) {
fgl_vs_inattrib(phdr->in_tbl);
tmp += phdr->in_tbl;
}
if(phdr->out_tbl) tmp += phdr->out_tbl;
if(phdr->sampler) tmp += phdr->sampler;
size = phdr->instruct;
if(size < 512) {
fgl_vs_pc(0, ((size >> 2) - 1), false);
pmem = (uint32 *)FGVS_INSTMEM;
pbody += tmp;
do {
WRITEREG(pmem++, *pbody++);
} while(--size != 0);
}
if(phdr->const_float) {
size = phdr->const_float;
pmem = (uint32 *)FGVS_CFLOAT;
do {
WRITEREG(pmem++, *pbody++);
} while(--size != 0);
}
if(phdr->const_int) {
size = phdr->const_int;
pmem = (uint32 *)FGVS_CINT;
do {
WRITEREG(pmem++, *pbody++);
} while(--size != 0);
}
if(phdr->const_bool) {
WRITEREG(FGVS_CBOOL, *pbody);
}
return 0;
}
FGLAPI fgl_fs_pc ( const uint32 start, const uint32 end, const bool endignore )
{
ASSERT((start < 512) && (end < 512) && (end > start));
if (fgl_execute_mode(ACCSSIBLE)) {
ASSERT(0);
return;
} else {
WRITEREG(FGPS_PCSTART, start);
WRITEREG(FGPS_PCEND, (end | ((endignore)?1:0 << 9)));
WRITEREG(FGPS_PCCOPY, 0x1);
}
while(rFGPS_IBSTATUS);
if (fgl_execute_mode(EXECUTE))
{
ASSERT(0);
return;
}
}
FGLAPI fgl_fs_inattrib ( const uint32 size )
{
ASSERT( size < 10 );
if (fgl_execute_mode(ACCSSIBLE)) {
ASSERT(0);
return;
} else {
WRITEREG(FGPS_ATTRIBNUM, size);
}
while(rFGPS_IBSTATUS & 0x1);
if (fgl_execute_mode(EXECUTE))
{
ASSERT(0);
return;
}
}
int32 fgl_load_fs ( const uint32 * program )
{
uint32 * pmem = 0;
uint32 * pbody = 0;
uint32 size = 0;
uint32 tmp = 0;
struct shader_hdr * phdr = (struct shader_hdr *)program;
pbody = (uint32 *)&phdr[1];
if ((phdr->magic != FSMAGIC) || (phdr->version != SHADERVER))
{
return 1;
}
if(phdr->in_tbl) {
fgl_fs_inattrib(phdr->in_tbl);
tmp += phdr->in_tbl;
}
if(phdr->out_tbl) tmp += phdr->out_tbl;
if(phdr->sampler) tmp += phdr->sampler;
size = phdr->instruct;
if(size < 512) {
fgl_fs_pc(0, ((size >> 2) - 1), false);
pmem = (uint32 *)FGPS_INSTMEM;
pbody += tmp;
do {
WRITEREG(pmem++, *pbody++);
} while(--size != 0);
}
if(phdr->const_float) {
size = phdr->const_float;
pmem = (uint32 *)FGPS_CFLOAT;
do {
WRITEREG(pmem++, *pbody++);
} while(--size != 0);
}
if(phdr->const_int) {
size = phdr->const_int;
pmem = (uint32 *)FGPS_CINT;
do {
WRITEREG(pmem++, *pbody++);
} while(--size != 0);
}
if(phdr->const_bool) {
WRITEREG(FGPS_CBOOL, *pbody);
}
return 0;
}
int32 fgl_load_binary ( void * binary )
{
uint32 size = 0;
uint32 * pshader = NULL;
uint32 * pdata = NULL;
struct shader_bin_hdr hdr;
memcpy((void *)&hdr, binary, sizeof(struct shader_bin_hdr));
size += (hdr.instruct * 4 * 4);
size += (hdr.const_float * 4 * 4);
size += (hdr.const_int * 4 * 4);
size += (hdr.const_bool * 4);
size += ((hdr.dcl_btype_tbl[0] + hdr.dcl_array_tbl[0]) * 4);
pshader = (uint32 *)malloc(sizeof(struct shader_hdr) + size);
pdata = pshader;
if ( hdr.magic == VSMAGIC ) {
*pdata++ = 0x20205356;
*pdata++ = 0xFFFF0003;
*pdata++ = 0x00000040;
*pdata++ = (hdr.dcl_btype_tbl[0] + hdr.dcl_array_tbl[0]);
*pdata++ = 0;
*pdata++ = 0;
*pdata++ = (4 * hdr.instruct);
*pdata++ = (4 * hdr.const_float);
*pdata++ = (4 * hdr.const_int);
*pdata++ = (4 * hdr.const_bool);
// TODO: make the input attribute table
pdata += (6 + (hdr.dcl_btype_tbl[0] + hdr.dcl_array_tbl[0]));
memcpy((void *)pdata, (void *)((uint32 *)binary+(sizeof(struct shader_bin_hdr) >> 2)), size);
fgl_load_vs(pshader);
} else if ( hdr.magic == FSMAGIC ) {
*pdata++ = 0x20205350;
*pdata++ = 0xFFFF0003;
*pdata++ = 0x00000040;
*pdata++ = (hdr.dcl_btype_tbl[0] + hdr.dcl_array_tbl[0]);
*pdata++ = 0;
*pdata++ = 0;
*pdata++ = (4 * hdr.instruct);
*pdata++ = (4 * hdr.const_float);
*pdata++ = (4 * hdr.const_int);
*pdata++ = (4 * hdr.const_bool);
// TODO: make the input attribute table
pdata += (6 + (hdr.dcl_btype_tbl[0] + hdr.dcl_array_tbl[0]));
memcpy((void *)pdata, (void *)((uint32 *)binary+(sizeof(struct shader_bin_hdr) >> 2)), size);
fgl_load_fs(pshader);
} else {
ASSERT(0);
return 1;
}
return 0;
}
#undef VSMAGIC
#undef FSMAGIC
#undef SHADERVER
/* -----------------------< End of file >----------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -