Subversion Repositories ps3ware

Compare Revisions

Ignore whitespace Rev 203 → Rev 204

/trunk/libps3rsx/examples/simple_fx/Makefile
New file
0,0 → 1,24
CFLAGS=-O2 -W -Wall -I/lib/modules/`uname -r`/build/include
CPPFLAGS=-O2 -lspe -W -Wall -I/lib/modules/`uname -r`/build/include
 
SRCC=../../src/fifo/dma.c ../../src/rop/rop.c ../../src/fifo/utils.c ../../src/shaders/fragment.c ../../src/shaders/vertex.c ../../src/textures/textures.c ../../src/geometry/geometry.c
OBJC = $(SRCC:%.c=%.o)
 
all:gpu
 
spu_server : spu-srv.cpp
spu-gcc -lm -Wall -O5 -finline-functions -funroll-all-loops spu-srv.cpp -o spu_server
spu_handle.o: spu_server
embedspu spu_handle spu_server spu_handle.o
 
 
objc: $(SRCC)
$(CC) $(CFLAGS) $(SRCC) -c
 
gpu: $(OBJC) ps3gpu.cpp spu_handle.o
$(CXX) $(CPPFLAGS) -o ps3gpu ps3gpu.cpp spu_handle.o $(OBJC)
 
 
clean:
$(RM) $(OBJC) ps3gpu
/trunk/libps3rsx/examples/simple_fx/structs.h
New file
0,0 → 1,27
#include <assert.h>
 
struct instance_data_t
{
float col[4];
float mat[16];
uint32_t time;
float padd[3];
};
 
struct program_data_t
{
uint32_t fx;
uint32_t dynamic;
uint32_t quads;
uint32_t atlas;
uint32_t asize;
uint32_t insts;
uint32_t isize;
uint32_t padd;
};
 
 
 
 
 
 
/trunk/libps3rsx/examples/simple_fx/spu-srv.cpp
New file
0,0 → 1,527
#include "common_spu.h"
#include "structs.h"
#include <math.h>
 
#include <float.h>
 
 
uint16 ia = 0, ib = 0, ic = 0;
 
vec_uint4 inline uint16_uload( qword address )
{
vec_uint4 qw = (vec_uint4)si_lqd( address, 0 );
vec_uint4 ao = spu_and( (vec_uint4)address, spu_splats( (unsigned int )0xf ) );
vec_uint4 am = spu_shuffle( ao, ao, (vec_uchar16)spu_splats( (unsigned int) 0x80800303 ) );
am = spu_add( am, spu_splats( (unsigned int)0x80800001 ) );
return spu_shuffle( qw, qw, (vec_uchar16)am );
}
 
vec_uint4 inline f2h( vec_uint4 h )
{
vec_uint4 s = spu_and( spu_rlmask( h, -16 ), spu_splats( (unsigned int)0x8000) );
vec_uint4 e = spu_and( spu_rlmask( h, -23 ), spu_splats( (unsigned int)0xff) );
vec_uint4 z = spu_cmpgt( e, spu_splats( (unsigned int)112 ) );
vec_uint4 m = spu_and( h, spu_splats( (unsigned int)0x7fffff) );
e = spu_sub( e, spu_splats( (unsigned int)112 ) );
e = spu_sel( spu_splats( (unsigned int)0x0 ), e, z );
e = spu_rl( e, 10 );
 
m = spu_rlmask( m, -13 );
 
return spu_or( e, spu_or( m, s ) );
 
}
 
vec_float4 inline h2f( vec_uint4 h )
{
 
vec_uint4 s = spu_and( spu_rlmask( h, -15 ), spu_splats( (unsigned int)0x1) );
vec_uint4 e = spu_and( spu_rlmask( h, -10 ), spu_splats( (unsigned int)0x1f) );
vec_uint4 m = spu_and( h, spu_splats( (unsigned int)0x3ff) );
e = spu_add( e, spu_splats( (unsigned int)112 ) );
e = spu_rl( e, 23 );
m = spu_rl( m, 13 );
s = spu_rl( s, 31 );
return (vec_float4)spu_or( e, spu_or( m, s ) );
}
 
 
struct sin_cos
{
vec_float4 scsc[257];
sin_cos()
{
vec_float4 start = (vec_float4){ +1.0f, 0.0f, -1.0f, 0.0f };
vec_float4 co = (vec_float4){ +0.999698819f, +0.999698819f, +0.999698819f, +0.999698819f };
vec_float4 si = (vec_float4){ +0.024541228f, -0.024541228f, +0.024541228f, -0.024541228f };
for( size_t i = 0; i < 257; ++i )
{
scsc[i] = start;
start = start * co + si * YXWZ( start );
}
//printf( "%f %f\n", ((float *)scsc)[1026], ((float *)scsc)[1027] );
}
vec_float4 value( vec_float4 f )
{
vec_int4 i = spu_convts( f, 8 );
vec_float4 fi = spu_convtf( i, 8 );
vec_float4 d = spu_mul( spu_sub( f, fi ), spu_splats( 256.0f ) );
 
unsigned int ind = si_to_uint( (qword)i ) & 255;
vec_float4 a = scsc[ind + 0];
vec_float4 b = scsc[ind + 1];
return spu_madd( spu_sub( b, a ), d, a );
}
};
 
 
sin_cos table;
 
void inline process_linear_spline( qword &address, vec_float4 &value, vec_float4 time, vec_uint4 startFrame, vec_uint4 endFrame )
{
vec_uint4 num = spu_rl( uint16_uload( address ), 1 );
vec_uint4 dec = spu_sub( num, spu_splats( (unsigned int)0x2) );
vec_uint4 ptr = spu_sel( num, dec, spu_cmpgt( num, (unsigned int)0x2 ) );
vec_uint4 fptr = spu_add( (vec_uint4)address, ptr );
vec_uint4 beg = spu_splats( (unsigned int)0x0 );
vec_uint4 end = dec;
vec_uint4 ibeg = startFrame;
vec_uint4 iend = endFrame;
while( 1 )
{
vec_uint4 bega = spu_add( beg, spu_splats( (unsigned int)0x4 ) );
vec_uint4 tst = spu_cmpgt( bega, end );
unsigned int ret = si_to_uint( (qword)tst );
if( ret == 0xffffffff )
{
break;
}
vec_uint4 med = spu_rl( spu_rlmask( spu_add( beg, end ), -2 ), 1 );
vec_uint4 i = uint16_uload( (qword)spu_add( med, (vec_uint4)address ) );
vec_float4 fi = spu_convtf( i, 0 );
vec_uint4 b = spu_cmpgt( time, fi );
beg = spu_sel( beg, med, b );
end = spu_sel( med, end, b );
ibeg = spu_sel( ibeg, i, b );
iend = spu_sel( i, iend, b );
}
vec_uint4 f1 = uint16_uload( (qword)spu_add( beg, fptr) );
vec_uint4 f2 = uint16_uload( (qword)spu_add( end, fptr) );
vec_float4 f = h2f( spu_shuffle( f1, f2, SWZ{ F_X, S_X, E_4, E_4 } ) );
vec_float4 times = spu_convtf( spu_shuffle( ibeg, iend, SWZ{ S_X, F_X, E_4, E_4 } ), 0 );
vec_float4 d = spu_sub( times, time );
vec_float4 mul = spu_sub( times, YX( times ) );
mul = spu_mul( spu_re( mul ), spu_mul( f, d ) );
value = spu_add( mul, Y( mul ) );
address = (qword)spu_add( fptr, num );
}
 
vec_float4 inline conv(
vec_uint4 kbeg,
vec_uint4 kend,
vec_uint4 vbeg,
vec_uint4 vend,
vec_float4 time )
{
vec_float4 fbeg = h2f( vbeg );
vec_float4 fend = h2f( vend );
vec_float4 tbeg = spu_convtf( kbeg, 0 );
vec_float4 tend = spu_convtf( kend, 0 );
vec_float4 dtbeg = spu_sub( time, tbeg );
vec_float4 dtend = spu_sub( tend, time );
vec_float4 mul = spu_re( spu_sub( tend, tbeg ) );
vec_float4 xyzw = spu_add( spu_mul( dtbeg, fend ), spu_mul( dtend, fbeg ) );
xyzw = spu_mul( mul, xyzw );
return xyzw;
}
 
void inline process_linear_spline(
qword &address,
vec_uint4 &kbeg,
vec_uint4 &kend,
vec_uint4 &vbeg,
vec_uint4 &vend,
vec_float4 time,
vec_uint4 startFrame,
vec_uint4 endFrame )
{
vec_uint4 num = spu_rl( uint16_uload( address ), 1 );
vec_uint4 dec = spu_sub( num, spu_splats( (unsigned int)0x2) );
vec_uint4 ptr = spu_sel( num, dec, spu_cmpgt( num, (unsigned int)0x2 ) );
vec_uint4 fptr = spu_add( (vec_uint4)address, ptr );
vec_uint4 beg = spu_splats( (unsigned int)0x0 );
vec_uint4 end = dec;
vec_uint4 ibeg = startFrame;
vec_uint4 iend = endFrame;
//printf( "%d \n", si_to_uint( (qword)num ) );
while( 1 )
{
vec_uint4 bega = spu_add( beg, spu_splats( (unsigned int)0x4 ) );
vec_uint4 tst = spu_cmpgt( bega, end );
unsigned int ret = si_to_uint( (qword)tst );
if( ret == 0xffffffff )
{
break;
}
vec_uint4 med = spu_rl( spu_rlmask( spu_add( beg, end ), -2 ), 1 );
vec_uint4 i = uint16_uload( (qword)spu_add( med, (vec_uint4)address ) );
vec_float4 fi = spu_convtf( i, 0 );
vec_uint4 b = spu_cmpgt( time, fi );
beg = spu_sel( beg, med, b );
end = spu_sel( med, end, b );
ibeg = spu_sel( ibeg, i, b );
iend = spu_sel( i, iend, b );
}
 
address = (qword)spu_add( fptr, num );
vec_uint4 f1 = uint16_uload( (qword)spu_add( beg, fptr) );
vec_uint4 f2 = uint16_uload( (qword)spu_add( end, fptr) );
vbeg = spu_shuffle( vbeg, f1, SWZ{ F_Y, F_Z, F_W, S_X } );
vend = spu_shuffle( vend, f2, SWZ{ F_Y, F_Z, F_W, S_X } );
kbeg = spu_shuffle( kbeg, ibeg, SWZ{ F_Y, F_Z, F_W, S_X } );
kend = spu_shuffle( kend, iend, SWZ{ F_Y, F_Z, F_W, S_X } );
}
 
 
instance_data_t insts[256] __attribute__((aligned(128)));;
BinaryParticle particles[1024] __attribute__((aligned(128)));
char chunks[4][2048] __attribute__((aligned(128)));
char fly[4] = { 0 };
uint16 startFrames[4];
uint16 endFrames[4];
float realTimes[4];
float dst[11];
 
 
uint16 number = 0;
 
 
struct Vertex
{
float x, z, y;
short u, v;
short r,g,b,a;
};
 
 
Vertex outBuffer[512];
size_t outPtr = 0;
uint16 coords[256][8];
 
void inline DoParticle( size_t next, size_t inst )
{
 
//printf( "a4 \n" );
 
float time = realTimes[next];
char *data = chunks[next];
vec_uint4 startFrame = (vec_uint4)si_from_uint( startFrames[next] );
vec_uint4 endFrame = (vec_uint4)si_from_uint( endFrames[next] );
mfc_write_tag_mask( 1 << next );
mfc_read_tag_status_any();
float x, y, z, u, v;
short r, g, b, a;
qword dptr = si_from_ptr( data );
vec_float4 vtime = spu_splats( time );
vec_float4 vx, vy, vz, vu, vv, vp, vs;
process_linear_spline( dptr, vx, vtime, startFrame, endFrame );
process_linear_spline( dptr, vy, vtime, startFrame, endFrame );
process_linear_spline( dptr, vz, vtime, startFrame, endFrame );
vec_uint4 kbeg = spu_splats( (unsigned int)0 );
vec_uint4 kend = spu_splats( (unsigned int)0 );
vec_uint4 vbeg = spu_splats( (unsigned int)0 );
vec_uint4 vend = spu_splats( (unsigned int)0 );
//printf( "a7 \n" );
 
process_linear_spline( dptr, kbeg, kend, vbeg, vend, vtime, startFrame, endFrame );
process_linear_spline( dptr, kbeg, kend, vbeg, vend, vtime, startFrame, endFrame );
process_linear_spline( dptr, kbeg, kend, vbeg, vend, vtime, startFrame, endFrame );
process_linear_spline( dptr, kbeg, kend, vbeg, vend, vtime, startFrame, endFrame );
//printf( "a6 \n" );
 
vec_float4 rgba = conv( kbeg, kend, vbeg, vend, vtime );
rgba = spu_mul( *(vec_float4 *)insts[inst].col, rgba );
vec_uint4 colh = f2h( ( vec_uint4 ) rgba );
process_linear_spline( dptr, vu, vtime, startFrame, endFrame );
process_linear_spline( dptr, vv, vtime, startFrame, endFrame );
process_linear_spline( dptr, vp, vtime, startFrame, endFrame );
process_linear_spline( dptr, vs, vtime, startFrame, endFrame );
 
 
//printf( "a5 \n" );
 
 
static int aaa = 0;
float ix, iy, iz;
ix = *(float *)&vx;
iy = *(float *)&vy;
iz = *(float *)&vz;
x = ix * insts[inst].mat[0] + iy * insts[inst].mat[1] + iz * insts[inst].mat[2] + insts[inst].mat[3];
y = ix * insts[inst].mat[4] + iy * insts[inst].mat[5] + iz * insts[inst].mat[6] + insts[inst].mat[7];
z = ix * insts[inst].mat[8] + iy * insts[inst].mat[9] + iz * insts[inst].mat[10] + insts[inst].mat[11];
r = ((unsigned int *)&colh)[0];
g = ((unsigned int *)&colh)[1];
b = ((unsigned int *)&colh)[2];
a = ((unsigned int *)&colh)[3];
u = *(float *)&vu;
v = *(float *)&vv;
 
Vertex &a00 = outBuffer[(outPtr + 0 ) & 511];
Vertex &a01 = outBuffer[(outPtr + 1 ) & 511];
Vertex &a11 = outBuffer[(outPtr + 2 ) & 511];
Vertex &a10 = outBuffer[(outPtr + 3 ) & 511];
vec_uint4 ind = spu_convtu( vs, 0 );
uint32_t sprite = si_to_uint( (qword)ind ) & 255;
vec_float4 rot = table.value( XXXX( vp ) );
float si = ((float *)&rot)[0];
float co = ((float *)&rot)[1];
a00.x = x + co * u - si * v;
a01.x = x + co * u + si * v;
a11.x = x - co * u + si * v;
a10.x = x - co * u - si * v;
a00.y = y - si * u - co * v;
a01.y = y - si * u + co * v;
a11.y = y + si * u + co * v;
a10.y = y + si * u - co * v;
a00.z = z;
a01.z = z;
a11.z = z;
a10.z = z;
a00.u = coords[sprite][0];
a00.v = coords[sprite][1];
a01.u = coords[sprite][2];
a01.v = coords[sprite][3];
a11.u = coords[sprite][4];
a11.v = coords[sprite][5];
a10.u = coords[sprite][6];
a10.v = coords[sprite][7];
a00.r = r;
a01.r = r;
a11.r = r;
a10.r = r;
a00.g = g;
a01.g = g;
a11.g = g;
a10.g = g;
a00.b = b;
a01.b = b;
a11.b = b;
a10.b = b;
a00.a = a;
a01.a = a;
a11.a = a;
a10.a = a;
outPtr += 4;
++number;
}
 
 
 
void SampleParticles( float _time, uint32 num, unsigned long long base, uint16 loopFrame, size_t inst )
{
size_t j = 0;
for( size_t i = 0; i < num; ++i )
{
uint16 startFrame = particles[i].startFrame;
uint16 endFrame = particles[i].endFrame;
float realTime = 0.0f;
bool calc = false;
float time = _time;
if( time >= startFrame && time <= endFrame )
{
realTime = time;
calc = true;
}
else
{
time += loopFrame;
if( time >= startFrame && time <= endFrame )
{
realTime = time;
calc = true;
}
}
if( calc )
{
mfc_get( &chunks[j][0], base + particles[i].qwordOffset * 16, particles[i].qwordSize * 16, j, 0, 0 );
fly[j] = 1;
//printf( "%d \n", particles[i].qwordSize * 16 );
startFrames[j] = startFrame;
endFrames[j] = endFrame;
realTimes[j] = realTime;
size_t next = ( j + 1 ) & 3;
if( fly[next] == 1 )
{
fly[next] = 0;
DoParticle( next, inst );
}
j = next;
}
}
for( size_t i = 0; i < 4; ++i )
{
if( fly[i] == 1 )
{
fly[i] = 0;
DoParticle( i, inst );
}
}
}
 
 
 
 
int main(unsigned long long spe_id, unsigned long long program_data_ea, unsigned long long env)
{
//unsigned long long te;
spu_write_decrementer( 0xffffffff );
while( 1 )
{
 
spu_read_in_mbox();
ParticleHeader header;
program_data_t data;
mfc_get( &data, program_data_ea, sizeof( data ), 0, 0, 0 );
mfc_write_tag_mask( 1 );
mfc_read_tag_status_any();
//printf( "%x %x \n", data.atlas, data.asize );
mfc_get( &coords[0], data.atlas, data.asize, 0, 0, 0 );
mfc_get( &insts[0], data.insts, data.isize * sizeof( instance_data_t ), 0, 0, 0 );
mfc_get( &header, data.fx, sizeof( header ), 0, 0, 0 );
mfc_write_tag_mask( 1 );
mfc_read_tag_status_any();
 
int particleSize = header.trackOffset - header.particleOffset;
mfc_get( &particles[0], data.fx + header.particleOffset, particleSize, 0, 0, 0 );
mfc_write_tag_mask( 1 );
mfc_read_tag_status_any();
//printf( "a1\n" );
 
data.quads = 0;
for( size_t i = 0; i < data.isize; ++i )
{
outPtr = 0;
uint32_t t = insts[i].time;
float ftime = ( t >> 8 ) % ( header.loopFrame ) + ( t & 255 ) / 256.0f;
SampleParticles( ftime, header.particles, data.fx + header.trackOffset, header.loopFrame, i );
mfc_put( outBuffer, data.dynamic, 24 * outPtr, 0, 0, 0 );
mfc_write_tag_mask( 1 );
mfc_read_tag_status_any();
data.quads += outPtr / 4;
data.dynamic += 24 * outPtr;
}
 
mfc_put( &data, program_data_ea, sizeof( data ), 0, 0, 0 );
mfc_write_tag_mask( 1 );
mfc_read_tag_status_any();
spu_write_out_mbox( 3 );
}
return 0;
}
/trunk/libps3rsx/examples/simple_fx/ps3gpu.cpp
New file
0,0 → 1,680
/*
* PS3 GPU blitting test program
*
* Copyright 2007 Vivien Chappelier <vivien.chappelier@free.fr>
* Copyright 2007 Peter Popov <IronSPeter@gmail.com>
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <math.h>
#include <time.h>
#include <assert.h>
#include <libspe.h>
 
 
extern "C"
{
#include "../../include/matrix.h"
#include "../../src/types.h"
#include "../../include/nouveau_class.h"
#include "../../src/fifo/utils.h"
#include "../../src/fifo/dma.h"
#include "../../src/textures/textures.h"
#include "../../src/geometry/geometry.h"
#include "../../src/geometry/model.h"
#include "../../src/shaders/vertex.h"
#include "../../src/rop/rop.h"
#include "../../src/shaders/fragment.h"
};
 
#include "structs.h"
 
#define Nv3D 7
 
 
uint32_t width;
uint32_t height;
uint32_t pitch;
 
#define BB 64
 
 
int set_mvp( uint32_t *fifo, float angle )
{
float matrix[16];
identity( matrix );
float w = 0.4f;
float h = 0.3f;
frustrum( -w, +w, -h, +h, 1.0f, 100.0f, matrix );
translatef( 0.0f, 0.0f, -4.0f, matrix );
rotatef( angle, 0.0f, 1.0f, 0.0f, matrix );
rotatef( 90.0f, 1.0f, 0.0f, 0.0f, matrix );
 
return set_vertex_shader_constants( matrix, 0, 16, fifo, Nv3D );
}
 
 
int set_cnst( uint32_t *fifo )
{
float coeff[8] = { 1.0f / 4096.0f, 1.0f / 4096.0f, 0.0f, 1.0f };
return set_vertex_shader_constants( coeff, 4, 4, fifo, Nv3D );
}
 
void *map_file( const char *file, int *fd, int *size )
{
*size = 0;
*fd = open( file, O_RDONLY );
if( (*fd) != -1 )
{
int status;
struct stat buffer;
status = fstat( *fd, &buffer );
*size = buffer.st_size;
printf( "mmaped %10d bytes from %s \n", (uint32_t)buffer.st_size, file );
return mmap( 0, buffer.st_size, PROT_READ, MAP_PRIVATE, *fd, 0 );
}
return 0;
 
}
 
void unmap_file( void *data, int fd, int size )
{
if( data != 0 )
{
munmap( data, size );
}
if( fd != -1 )
{
close( fd );
}
}
 
 
template<class T> struct file_map
{
 
int fd;
int size;
void *data;
public:
int get_size() const
{
return size;
}
T *get_object() const
{
return (T *)data;
}
file_map( const char *file )
{
data = map_file( file, &fd, &size );
}
~file_map()
{
unmap_file( data, fd, size );
}
};
 
 
class memory_pool
{
uint8 *data;
size_t ptr;
size_t size;
size_t align;
public:
size_t get_offset() const
{
return ptr;
}
memory_pool sub_pool( size_t _size, size_t _align )
{
memory_pool pool = *this;
pool.size = pool.ptr + size;
pool.align = _align;
alloc( _size );
return pool;
}
memory_pool() : data( 0 ), ptr( 0 ), size( 0 ), align( 0 ){};
memory_pool( uint8 *_data, size_t _size, size_t _align ) : data( _data ), ptr( 0 ), size( _size ), align( _align ) {};
void *alloc( size_t _size )
{
size_t off = _size & ( align - 1 );
if( off )
{
_size += align - off;
}
assert( ptr + _size < size );
void *result = data + ptr;
ptr += _size;
return result;
}
};
 
 
class gpu_ring
{
protected:
size_t *fifo;
size_t cmd_size;
public:
gpu_ring() : fifo( 0 ), cmd_size( 0 ){};
size_t set( uint32_t *_fifo )
{
memcpy( _fifo, fifo, cmd_size * 4 );
return cmd_size;
}
 
};
 
class vertex_shader_t : public gpu_ring
{
public:
bool init( const char *file, memory_pool &xdr_pool )
{
file_map<vertex_shader_desc_t> f( file );
if( vertex_shader_desc_t *desc = f.get_object() )
{
fifo = (size_t *)xdr_pool.alloc( 0 );
cmd_size = set_vertex_shader( desc, &desc->aux[1], fifo, Nv3D );
xdr_pool.alloc( cmd_size * 4 );
return true;
}
return false;
}
};
 
class pixel_shader_t : public gpu_ring
{
public:
bool init( const char *file, memory_pool &xdr_pool, memory_pool &ddr_pool )
{
file_map<fragment_shader_desc_t> f( file );
if( fragment_shader_desc_t *desc = f.get_object() )
{
size_t off = ddr_pool.get_offset();
size_t length = desc->dword_length * 4;
memcpy( ddr_pool.alloc( 0 ), &desc->aux[1], length );
ddr_pool.alloc( length );
fifo = (size_t *)xdr_pool.alloc( 0 );
cmd_size = set_fragment_shader( desc, off, fifo, Nv3D );
xdr_pool.alloc( cmd_size * 4 );
return true;
}
return false;
}
};
 
class texture_t : public gpu_ring
{
public:
bool init( const char *file, memory_pool &xdr_pool, memory_pool &ddr_pool )
{
file_map<texture_desc_t> f( file );
if( texture_desc_t *desc = f.get_object() )
{
size_t off = ddr_pool.get_offset();
size_t length = desc->length;
memcpy( ddr_pool.alloc( length ), sizeof( *desc ) + (uint8_t *)desc, desc->length );
fifo = (size_t *)xdr_pool.alloc( 0 );
cmd_size = set_texture_2D( desc, off, 0, REPEAT, LINEAR, LINEAR_MIPMAP_LINEAR, fifo, Nv3D );
xdr_pool.alloc( cmd_size * 4 );
return true;
}
return false;
}
};
 
 
class raw_data_t
{
size_t offset;
size_t size;
void *data;
public:
 
void *get_data() const
{
return data;
}
size_t get_offset() const
{
return offset;
}
size_t get_size() const
{
return size;
}
raw_data_t() : offset( 0 ){};
bool init( const char *file, memory_pool &pool )
{
file_map<uint8_t> f( file );
if( uint8_t *desc = f.get_object() )
{
offset = pool.get_offset();
size_t length = f.get_size();
memcpy( data = pool.alloc( length ), desc, length );
size = length;
return true;
}
return false;
}
};
 
class geometry_t : public gpu_ring
{
public:
bool init( const char *file, memory_pool &xdr_pool, size_t vb_offset, size_t ib_offset )
{
file_map<model_desc_t> f( file );
if( model_desc_t *desc = f.get_object() )
{
uint32_t *ptr = (uint32_t *)xdr_pool.alloc( 0 );
fifo = ptr;
ptr += blend_enable( 0, ptr, Nv3D );
ptr += depth_enable( 1, 1, ptr, Nv3D );
ptr += set_geometry_source( &desc->position, DDR, vb_offset, ptr, Nv3D );
ptr += set_geometry_source( &desc->texcoord, DDR, vb_offset, ptr, Nv3D );
ptr += set_index_source( DDR, ib_offset, ptr, Nv3D );
ptr += draw_primitives( 1, TRIANGLES, 0, desc->indices_num, ptr, Nv3D );
cmd_size = ptr - fifo;
xdr_pool.alloc( cmd_size * 4 );
return true;
}
return false;
 
}
 
};
 
 
class quad_geometry_t : public gpu_ring
{
public:
bool init( memory_pool &xdr_pool, size_t vb_offset )
{
uint32_t *ptr = (uint32_t *)xdr_pool.alloc( 0 );
fifo = ptr;
geom_desc_t pos, tx0, col;
pos.stride = 24;
pos.components = 3;
pos.format = FLOAT;
pos.type = POS0;
pos.offset = 0;
col.stride = 24;
col.components = 4;
col.format = HALF;
col.type = COL0;
col.offset = 16;
tx0.stride = 24;
tx0.components = 2;
tx0.format = HALF;
tx0.type = TEX0;
tx0.offset = 12;
ptr += blend_enable( 1, ptr, Nv3D );
blend_desc_t blend;
blend.src_color_blend = ONE;
blend.src_alpha_blend = ONE;
blend.dst_color_blend = ONE;
blend.dst_alpha_blend = ONE;
ptr += set_blend_mode( &blend, ptr, Nv3D );
ptr += depth_enable( 0, 1, ptr, Nv3D );
ptr += set_geometry_source( &pos, DDR, vb_offset, ptr, Nv3D );
ptr += set_geometry_source( &col, DDR, vb_offset, ptr, Nv3D );
ptr += set_geometry_source( &tx0, DDR, vb_offset, ptr, Nv3D );
cmd_size = ptr - fifo;
xdr_pool.alloc( cmd_size * 4 );
return true;
}
};
 
vertex_shader_t mvp;
pixel_shader_t custom;
texture_t troll_texture;
texture_t particle_texture;
 
geometry_t troll;
quad_geometry_t particles;
 
 
 
int setup_surfaces_with_offset( uint32_t *fifo, int off )
{
uint32_t *ptr = fifo;
setup_buffer_t setup;
setup.pitchDepth = pitch;
setup.pitchColor = pitch;
setup.offsetDepth = width * height * 4 * 3;
setup.offsetColor = width * height * 4 * off;
setup.typeDepth = Z16;
setup.width = width;
setup.height = height;
ptr += setup_buffers( &setup, ptr, Nv3D );
return ptr - fifo;
}
 
 
uint8 data[1024 * 1024] __attribute__((aligned( 128 ) ));
memory_pool xdr_pool( data, sizeof( data ), 128 );
memory_pool fp_pool;
memory_pool tx_pool;
memory_pool vr_pool;
raw_data_t fx;
raw_data_t atlas;
void *dynamic;
 
int bind3d( uint32_t *fifo, uint32_t *fbmem, uint8_t *xdrmem, uint32_t obj, uint32_t jmp )
{
 
uint32_t *ptr = fifo;
xdrmem = xdrmem;
mvp.init( "../../data/particle.vertex", xdr_pool );
memory_pool gfx_pool( (uint8_t *)fbmem, 252 * 1024 * 1024, 1024 * 1024 );
gfx_pool.alloc( 1024 * 1024 * 32 );
fp_pool = gfx_pool.sub_pool( 1024 * 1024, 128 );
custom.init( "../../data/particle.pixel", xdr_pool, fp_pool );
tx_pool = gfx_pool.sub_pool( 1024 * 1024, 1024 );
troll_texture.init( "../../data/troll.dxt3", xdr_pool, tx_pool );
particle_texture.init( "../../data/spell.dxt3", xdr_pool, tx_pool );
vr_pool = gfx_pool.sub_pool( 1024 * 1024 * 16, 1024 );
raw_data_t vb;
raw_data_t ib;
 
vb.init( "../../data/troll.0.vb", vr_pool );
ib.init( "../../data/troll.0.ib", vr_pool );
troll.init( "../../data/troll.0.model", xdr_pool, vb.get_offset(), ib.get_offset() );
fx.init( "../../data/spell", xdr_pool );
atlas.init( "../../data/spell.dxt3.atlas", xdr_pool );
particles.init( xdr_pool, vr_pool.get_offset() );
dynamic = vr_pool.alloc( 1024 * 1024 );
ptr += setup_and_voodoo( 0x66604200, 0xfeed0000, obj, ptr, Nv3D );
ptr += setup_surfaces_with_offset( ptr, 1 );
ptr += troll_texture.set( ptr );
ptr += mvp.set( ptr );
ptr += set_mvp( ptr, 180.0f );
ptr += set_cnst( ptr );
ptr += custom.set( ptr );
ptr += set_geometry_pipe( 0xfeed0000, 0xfeed0001, ptr, Nv3D );
ptr += troll.set( ptr );
ptr += jump_to_address( ptr, jmp );
return ptr - fifo;
}
 
 
 
extern spe_program_handle_t spu_handle;
 
struct job_t
{
speid_t spe_id;
program_data_t pd __attribute__((aligned(128)));
job_t() : spe_id( 0 ){};
 
void kick_job( )
{
if( spe_id == 0 )
{
spe_id = spe_create_thread( 0, &spu_handle, &pd, NULL, -1, 0 );
}
 
while( spe_stat_in_mbox(spe_id) == 0 );
spe_write_in_mbox( spe_id, 1 );
}
 
void join()
{
while( spe_read_out_mbox( spe_id ) == (unsigned int)-1 );
}
 
};
 
#define INUMBER 32
instance_data_t insts[INUMBER] __attribute__((aligned( 128 ) ));
uint32_t dt[INUMBER];
float rnds[INUMBER][3];
 
 
float rnd( float beg, float end )
{
return ( rand() / (float) RAND_MAX ) * ( end - beg ) + beg;
}
 
int gfx_step( uint32_t *fifo, uint32_t jmp, int off )
{
 
static bool init_particles = false;
if( !init_particles )
{
init_particles = true;
for( size_t i = 0; i < INUMBER; ++i )
{
dt[i] = ( rand() & 63 ) + 32;
rnds[i][0] = 360.0f * i / (float)( INUMBER );//rnd( 0.0f, 360.0f );
rnds[i][1] = rnd( -0.5f, +0.5f );
rnds[i][2] = rnd( -0.5f, +0.5f );
insts[i].time = rand();
insts[i].col[0] = rnd( 0.8f, 1.0f );
insts[i].col[1] = rnd( 0.8f, 1.0f );
insts[i].col[2] = rnd( 0.8f, 1.0f );
insts[i].col[3] = 1.0f;
}
}
for( size_t i = 0; i < INUMBER; ++i )
{
insts[i].time += dt[i];
identity( insts[i].mat );
rotatef( 80.0f, 1.0f, 0.0f, 0.0f, insts[i].mat );
rotatef( off * 0.5f + rnds[i][0], 0.0f, 0.0f, 1.0f, insts[i].mat );
translatef( 1.6f, rnds[i][1], rnds[i][2], insts[i].mat );
float d = insts[i].mat[11];
d = ( 1.0f - 0.6f * d );
insts[i].col[0] = d;
insts[i].col[1] = 0.5f + d;
insts[i].col[2] = d;
//translatef( 1.0f * sin( t * rnds[i][0] ), 1.0f * cos( t * rnds[i][0] ), 1.0f * sin( t * rnds[i][2] ), insts[i].mat );
}
clear_buffer_t clear;
clear.clearR = clear.clearG = clear.clearB = clear.clearA = clear.clearD = 1;
clear.rgba = 50 + ( 10 << 8 ) + ( 5 << 16 );
clear.depth = 0xffff;
 
static job_t job;
static size_t curr = 0x0;
 
job.pd.insts = (uint32_t)insts;
job.pd.isize = INUMBER;
job.pd.dynamic = (uint32_t)( dynamic ) + curr * 24;
job.pd.fx = (uint32_t)fx.get_data();
job.pd.atlas = (uint32_t)atlas.get_data();
job.pd.asize = atlas.get_size();
job.kick_job( );
job.join();
 
uint32_t *ptr = fifo;
static float angle = 180.0f;
ptr += setup_surfaces_with_offset( ptr, off % 3 );
ptr += clear_buffers( &clear, ptr, Nv3D );
ptr += set_mvp( ptr, angle );
ptr += set_cnst( ptr );
//ptr += troll_texture.set( ptr );
//ptr += troll.set( ptr );
//ptr += custom.set( ptr );
ptr += particles.set( ptr );
ptr += particle_texture.set( ptr );
ptr += draw_primitives( 0, QUADS, curr, job.pd.quads * 4, ptr, Nv3D );
curr += job.pd.quads * 4;// + 128;
curr = ( curr + 16 ) & 2047;
//printf( "%d \n", job.pd.quads );
ptr += jump_to_address( ptr, jmp );
return ptr - fifo;
}
 
 
static volatile int cnt;
 
void wait( volatile uint32_t *volatile ctrl, uint32_t jmp )
{
ctrl[0x10] = jmp;
while( ctrl[0x11] != jmp )
{
++cnt;
}
 
}
 
 
static void gfx_test(struct gpu *gpu, unsigned int obj )
{
uint32_t *fifo = (uint32_t *)gpu->fifo.virt;
uint32_t *ctrl = (uint32_t *)gpu->ctrl.virt;
uint32_t *vram = (uint32_t *)gpu->vram.virt;
uint8_t *xram = (uint8_t *)gpu->xram.virt;
uint32_t i;
 
memset( fifo, 0, gpu->fifo.len );
int wptr;
int ret;
uint32 jmp = ctrl[0x10] & ~(gpu->fifo.len - 1 );
 
wptr = (ctrl[0x10] & (gpu->fifo.len - 1)) / 4;
printf( "%x %x %x\n", wptr, ctrl[0x10], gpu->xram.len );
 
ret = bind3d( &fifo[wptr], vram, xram, obj, jmp );
wait( ctrl, jmp );
uint32 old_jump = jmp;
for( i = 0; i < 2000; ++i )
{
//printf( "asd \n" );
memset( fifo, 0, gpu->fifo.len );
uint32_t jmpt = jmp + 4 + 4 * ( i & 1 );
fifo[ ( old_jump - jmp ) / 4 ] = 0x20000000 | ( jmp + 0x10 );
old_jump = jmpt;
gfx_step( &fifo[0x10], jmpt, i );
wait( ctrl, jmpt );
flip_scrn( gpu, ( ( i + 2 ) % 3 ) * width * height * 4 );
sync_gpu( gpu );
//flip_scrn( gpu, ( ( i + 1 ) & 1 ) * width * height * 4 );
}
printf( "done...\n" );
}
 
struct gpu gpu;
 
void sigint_handler(int sig)
{
(void) sig;
gpu_cleanup(&gpu);
}
 
 
 
int main(void)
{
if (gpu_init(&gpu) < 0)
{
fprintf(stderr, "Failed to initialize GPU\n");
return -1;
}
 
width = gpu.res.xres;
height = gpu.res.yres;
pitch = width * 4;
signal(SIGINT, sigint_handler);
 
gfx_test( &gpu, 0xfeed0007 );
 
//sleep( 3 );
 
gpu_cleanup(&gpu);
 
return 0;
}
/trunk/libps3rsx/examples/simple_fx/fx.h
New file
0,0 → 1,17
struct BinaryParticle
{
uint16 startFrame;
uint16 endFrame;
uint16 qwordOffset;
uint8 qwordSize;
uint8 flags;
};
 
struct ParticleHeader
{
uint16 particles;
uint16 loopFrame;
uint32 trackSize;
uint32 particleOffset;
uint32 trackOffset;
};
/trunk/libps3rsx/examples/simple_fx/common_spu.h
New file
0,0 → 1,171
#include <spu_mfcio.h>
#include <stdlib.h>
#include <stdio.h>
#include "../../src/types.h"
#include "fx.h"
 
#define F_(X) 0x##X, 0x##X, 0x##X, 0x##X
 
 
#define F_X 0x00, 0x01, 0x02, 0x03
#define F_Y 0x04, 0x05, 0x06, 0x07
#define F_Z 0x08, 0x09, 0x0A, 0x0B
#define F_W 0x0C, 0x0D, 0x0E, 0x0F
 
#define S_X 0x10, 0x11, 0x12, 0x13
#define S_Y 0x14, 0x15, 0x16, 0x17
#define S_Z 0x18, 0x19, 0x1A, 0x1B
#define S_W 0x1C, 0x1D, 0x1E, 0x1F
 
 
#define C16_0 0x80, 0x80, 0x00, 0x01
#define C16_1 0x80, 0x80, 0x02, 0x03
#define C16_2 0x80, 0x80, 0x04, 0x05
#define C16_3 0x80, 0x80, 0x06, 0x07
#define C16_4 0x80, 0x80, 0x08, 0x09
#define C16_5 0x80, 0x80, 0x0A, 0x0B
#define C16_6 0x80, 0x80, 0x0C, 0x0D
#define C16_7 0x80, 0x80, 0x0E, 0x0F
 
#define N16_0 0x80, 0x80, 0x10, 0x11
#define N16_1 0x80, 0x80, 0x12, 0x13
#define N16_2 0x80, 0x80, 0x14, 0x15
#define N16_3 0x80, 0x80, 0x16, 0x17
#define N16_4 0x80, 0x80, 0x18, 0x19
#define N16_5 0x80, 0x80, 0x1A, 0x1B
#define N16_6 0x80, 0x80, 0x1C, 0x1D
#define N16_7 0x80, 0x80, 0x1E, 0x1F
 
 
#define C8_0 0x80, 0x80, 0x80, 0x00
#define C8_1 0x80, 0x80, 0x80, 0x01
#define C8_2 0x80, 0x80, 0x80, 0x02
#define C8_3 0x80, 0x80, 0x80, 0x03
#define C8_4 0x80, 0x80, 0x80, 0x04
#define C8_5 0x80, 0x80, 0x80, 0x05
#define C8_6 0x80, 0x80, 0x80, 0x06
#define C8_7 0x80, 0x80, 0x80, 0x07
#define C8_8 0x80, 0x80, 0x80, 0x08
#define C8_9 0x80, 0x80, 0x80, 0x09
#define C8_A 0x80, 0x80, 0x80, 0x0A
#define C8_B 0x80, 0x80, 0x80, 0x0B
#define C8_C 0x80, 0x80, 0x80, 0x0C
#define C8_D 0x80, 0x80, 0x80, 0x0D
#define C8_E 0x80, 0x80, 0x80, 0x0E
#define C8_F 0x80, 0x80, 0x80, 0x0F
 
#define N8_0 0x80, 0x80, 0x80, 0x10
#define N8_1 0x80, 0x80, 0x80, 0x11
#define N8_2 0x80, 0x80, 0x80, 0x12
#define N8_3 0x80, 0x80, 0x80, 0x13
#define N8_4 0x80, 0x80, 0x80, 0x14
#define N8_5 0x80, 0x80, 0x80, 0x15
#define N8_6 0x80, 0x80, 0x80, 0x16
#define N8_7 0x80, 0x80, 0x80, 0x17
#define N8_8 0x80, 0x80, 0x80, 0x18
#define N8_9 0x80, 0x80, 0x80, 0x19
#define N8_A 0x80, 0x80, 0x80, 0x1A
#define N8_B 0x80, 0x80, 0x80, 0x1B
#define N8_C 0x80, 0x80, 0x80, 0x1C
#define N8_D 0x80, 0x80, 0x80, 0x1D
#define N8_E 0x80, 0x80, 0x80, 0x1E
#define N8_F 0x80, 0x80, 0x80, 0x1F
 
#define E_2 0x80, 0x80
#define E_3 0x80, 0x80, 0x80
#define E_4 0x80, 0x80, 0x80, 0x80
#define E_5 0x80, 0x80, 0x80, 0x80, 0x80
#define E_6 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_7 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_8 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_9 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_10 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_11 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_12 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_13 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
#define E_14 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
 
#define SHUFFLE_MERGE4(A, B, C, D) (vector unsigned char)(A, B, C, D)
 
#define SWZ (vector unsigned char)
 
#define X( A ) spu_shuffle( A, A, SWZ{ F_X, E_12 } )
#define Y( A ) spu_shuffle( A, A, SWZ{ F_Y, E_12 } )
#define Z( A ) spu_shuffle( A, A, SWZ{ F_Z, E_12 } )
#define W( A ) spu_shuffle( A, A, SWZ{ F_W, E_12 } )
 
#define XY( A ) spu_shuffle( A, A, SWZ{ F_X, F_Y, E_8 } )
#define YX( A ) spu_shuffle( A, A, SWZ{ F_Y, F_X, E_8 } )
 
 
#define XXXX( A ) spu_shuffle( A, A, SWZ{ F_X, F_X, F_X, F_X } )
#define YYYY( A ) spu_shuffle( A, A, SWZ{ F_Y, F_Y, F_Y, F_Y } )
#define ZZZZ( A ) spu_shuffle( A, A, SWZ{ F_Z, F_Z, F_Z, F_Z } )
#define WWWW( A ) spu_shuffle( A, A, SWZ{ F_W, F_W, F_W, F_W } )
#define YZWX( A ) spu_shuffle( A, A, SWZ{ F_Y, F_Z, F_W, F_X } )
#define ZWXY( A ) spu_shuffle( A, A, SWZ{ F_Z, F_W, F_X, F_Y } )
#define WXYZ( A ) spu_shuffle( A, A, SWZ{ F_W, F_X, F_Y, F_Z } )
#define YXWZ( A ) spu_shuffle( A, A, SWZ{ F_Y, F_X, F_W, F_Z } )
 
#define YZXW( A ) spu_shuffle( A, A, SWZ{ F_Y, F_Z, F_X, F_W } )
#define ZXYW( A ) spu_shuffle( A, A, SWZ{ F_Z, F_X, F_Y, F_W } )
 
#define Q16_0( A ) spu_shuffle( A, A, SWZ{ C16_0, E12 } )
#define Q16_1( A ) spu_shuffle( A, A, SWZ{ C16_1, E12 } )
#define Q16_2( A ) spu_shuffle( A, A, SWZ{ C16_2, E12 } )
#define Q16_3( A ) spu_shuffle( A, A, SWZ{ C16_3, E12 } )
#define Q16_4( A ) spu_shuffle( A, A, SWZ{ C16_4, E12 } )
#define Q16_5( A ) spu_shuffle( A, A, SWZ{ C16_5, E12 } )
#define Q16_6( A ) spu_shuffle( A, A, SWZ{ C16_6, E12 } )
#define Q16_7( A ) spu_shuffle( A, A, SWZ{ C16_7, E12 } )
 
#define NANF (vec_float4){ 1.0f/ 0.0f, 1.0f/ 0.0f, 1.0f/ 0.0f, 1.0f/ 0.0f }
 
#define ZEROF (vec_float4){ 0.0f, 0.0f, 0.0f, 0.0f }
#define F1111 (vec_float4){ 1.0f, 1.0f, 1.0f, 1.0f }
#define F1000 (vec_float4){ 1.0f, 0.0f, 0.0f, 0.0f }
#define F0100 (vec_float4){ 0.0f, 1.0f, 0.0f, 0.0f }
#define F0010 (vec_float4){ 0.0f, 0.0f, 1.0f, 0.0f }
#define F0001 (vec_float4){ 0.0f, 0.0f, 0.0f, 1.0f }
 
#define EPSF (vec_float4){ 0.0001f, 0.0001f, 0.0001f, 0.0001f }
#define EPNF (vec_float4){ -0.0001f, -0.0001f, -0.0001f, -0.0001f }
 
#define V16I (vec_uint4){ 16, 16, 16, 16 }
 
float inline GetTime( unsigned long long &te )
{
unsigned long long v = spu_read_decrementer();
float time = ( te - v ) / ( 3193000.0f * 25.0f );
te = v;
return time;
}
 
 
void inline _D( const vec_int4 & t, const char *str = "", const char *term = "\n" )
{
for( int i = 0; i < 4; ++i )
{
printf( "%8x%s", ( (int *)&t)[i], i == 3 ? "":str );
}
printf( "%s", term );
};
 
 
void inline _D( const vec_uint4 & t, const char *str = "", const char *term = "\n" )
{
for( int i = 0; i < 4; ++i )
{
printf( "%d%s", ( (unsigned int *)&t)[i], i == 3 ? "":str );
}
printf( "%s", term );
};
 
void inline _D( const vec_float4 & t, const char *str = "", const char *term = "\n" )
{
for( int i = 0; i < 4; ++i )
{
printf( "%f%s", ( (float *)&t)[i], i == 3 ? "":str );
}
printf( "%s", term );
};
/trunk/libps3rsx/examples/simple_dxt/ps3gpu
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/libps3rsx/examples/simple_dxt/ps3gpu.c
67,6 → 67,7
{
float matrix[16];
int i;
identity( matrix );
float w = 0.4f;
83,6 → 84,18
}
 
 
int set_cnst( uint32_t *fifo )
{
//static float v = 0.0f;
//v += 0.01f;
float coeff[8] = { 1.0f / 4096.0f, 1.0f / 4096.0f, 0.0f, 1.0, 10.0f, 0.0f, 0.0f, 0.0f };
 
return set_vertex_shader_constants( coeff, 4, 8, fifo, Nv3D );
}
 
void *map_file( const char *file, int *fd, int *size )
{
*size = 0;
252,15 → 265,18
ptr += load_texture( ptr, (uint8_t *)fbmem );
ptr += load_vertex_shader( ptr );
ptr += set_mvp( ptr, 180.0f );
ptr += set_cnst( ptr );
ptr += load_pixel_shader( ptr, (uint8_t *)fbmem );
ptr += load_geometry( ptr, (uint8_t *)fbmem );
ptr += jump_to_address( ptr, jmp );
 
//analyze_fifo( fifo, ptr - fifo );
return ptr - fifo;
}
 
int gfx_step( uint32_t *fifo, uint32_t jmp, int off )
{
int i;
clear_buffer_t clear;
clear.clearR = clear.clearG = clear.clearB = clear.clearA = clear.clearD = 1;
clear.rgba = 250 + ( 120 << 8 ) + ( 50 << 16 );
272,11 → 288,15
static float angle = 180.0f;
ptr += setup_surfaces_with_offset( ptr, off );
ptr += clear_buffers( &clear, ptr, Nv3D );
ptr += set_mvp( ptr, angle += 0.4f );
ptr += draw_indexed_primitives( indices, 0, indices_num, ptr, Nv3D );
ptr += set_cnst( ptr );
ptr += draw_primitives( 1, indices, 0, indices_num, ptr, Nv3D );
ptr += jump_to_address( ptr, jmp );
 
 
//analyze_fifo( fifo, ptr - fifo );
return ptr - fifo;
}
 
316,7 → 336,7
uint32 old_jump = jmp;
for( i = 0; i < 1000; ++i )
for( i = 0; i < 100; ++i )
{
memset( fifo, 0, gpu->fifo.len );