RetroArch/ps3/gcmgl/src/include/rgl-inline.h

261 lines
7.5 KiB
C

#ifndef _RGL_INLINE_H
#define _RGL_INLINE_H
#define SUBPIXEL_BITS 12
#define SUBPIXEL_ADJUST (0.5/(1<<SUBPIXEL_BITS))
#define BLOCKSIZE_MAX_DIMENSIONS 1024
#define CL0039_MIN_PITCH -32768
#define CL0039_MAX_PITCH 32767
#define CL0039_MAX_LINES 0x3fffff
#define CL0039_MAX_ROWS 0x7ff
#define RGLGCM_UTIL_LABEL_INDEX 253
#include "rgl-gcm-cmds.h"
static inline GLuint rglPlatformGetBitsPerPixel (GLenum internalFormat)
{
switch (internalFormat)
{
case RGLGCM_ALPHA16:
case RGLGCM_HILO8:
case RGLGCM_RGB5_A1_SCE:
case RGLGCM_RGB565_SCE:
return 16;
case RGLGCM_ALPHA8:
return 8;
case RGLGCM_RGBX8:
case RGLGCM_RGBA8:
case RGLGCM_ABGR8:
case RGLGCM_ARGB8:
case RGLGCM_BGRA8:
case RGLGCM_FLOAT_R32:
case RGLGCM_HILO16:
case RGLGCM_XBGR8:
return 32;
default:
return 0;
}
}
#define rglGcmSwap16Float32(fp, f) \
{ \
union SwapF32_16 \
{ \
uint32_t ui; \
float f; \
} v; \
v.f = *f; \
v.ui = (v.ui>>16) | (v.ui<<16); \
*fp = v.f; \
}
#define rglDeallocateBuffer(bufferObject, rglBuffer) \
if (rglBuffer->pool == RGLGCM_SURFACE_POOL_LINEAR) \
gmmFree( rglBuffer->bufferId ); \
rglBuffer->pool = RGLGCM_SURFACE_POOL_NONE; \
rglBuffer->bufferId = GMM_ERROR
static void rglGcmSetDrawArraysSlow(struct CellGcmContextData *thisContext, uint8_t mode,
uint32_t first, uint32_t count)
{
uint32_t lcount, i,j, loop, rest;
--count;
lcount = count & 0xff;
count >>= 8;
loop = count / CELL_GCM_MAX_METHOD_COUNT;
rest = count % CELL_GCM_MAX_METHOD_COUNT;
(thisContext->current)[0] = (((3) << (18)) | CELL_GCM_NV4097_INVALIDATE_VERTEX_FILE | (0x40000000));
gcm_emit_at(thisContext->current, 1, 0);
gcm_emit_at(thisContext->current, 2, 0);
gcm_emit_at(thisContext->current, 3, 0);
gcm_finish_n_commands(thisContext->current, 4);
gcm_emit_method_at(thisContext->current, 0, CELL_GCM_NV4097_SET_BEGIN_END, 1);
gcm_emit_at(thisContext->current, 1, mode);
gcm_finish_n_commands(thisContext->current, 2);
gcm_emit_method_at(thisContext->current, 0, CELL_GCM_NV4097_DRAW_ARRAYS, 1);
gcm_emit_at(thisContext->current, 1, ((first) | ((lcount)<<24)));
gcm_finish_n_commands(thisContext->current, 2);
first += lcount + 1;
for(i=0;i<loop;i++)
{
thisContext->current[0] = ((((2047)) << (18)) | CELL_GCM_NV4097_DRAW_ARRAYS | (0x40000000));
gcm_finish_n_commands(thisContext->current, 1);
for(j = 0; j < CELL_GCM_MAX_METHOD_COUNT; j++)
{
gcm_emit_at(thisContext->current, 0, ((first) | ((255U)<<24)));
gcm_finish_n_commands(thisContext->current, 1);
first += 256;
}
}
if(rest)
{
thisContext->current[0] = (((rest) << (18)) | CELL_GCM_NV4097_DRAW_ARRAYS | (0x40000000));
gcm_finish_n_commands(thisContext->current, 1);
for(j = 0;j < rest; j++)
{
gcm_emit_at(thisContext->current, 0, ((first) | ((255U)<<24)));
gcm_finish_n_commands(thisContext->current, 1);
first += 256;
}
}
gcm_emit_method_at(thisContext->current, 0, CELL_GCM_NV4097_SET_BEGIN_END, 1);
gcm_emit_at(thisContext->current, 1, 0);
gcm_finish_n_commands(thisContext->current, 2);
}
static inline GLuint rglGcmMapMinTextureFilter( GLenum filter )
{
switch (filter)
{
case GL_NEAREST:
return CELL_GCM_TEXTURE_NEAREST;
break;
case GL_LINEAR:
return CELL_GCM_TEXTURE_LINEAR;
break;
case GL_NEAREST_MIPMAP_NEAREST:
return CELL_GCM_TEXTURE_NEAREST_NEAREST;
break;
case GL_NEAREST_MIPMAP_LINEAR:
return CELL_GCM_TEXTURE_NEAREST_LINEAR;
break;
case GL_LINEAR_MIPMAP_NEAREST:
return CELL_GCM_TEXTURE_LINEAR_NEAREST;
break;
case GL_LINEAR_MIPMAP_LINEAR:
return CELL_GCM_TEXTURE_LINEAR_LINEAR;
break;
default:
return 0;
}
return filter;
}
static inline GLuint rglGcmMapWrapMode( GLuint mode )
{
switch ( mode )
{
case RGLGCM_CLAMP:
return CELL_GCM_TEXTURE_CLAMP;
break;
case RGLGCM_REPEAT:
return CELL_GCM_TEXTURE_WRAP;
break;
case RGLGCM_CLAMP_TO_EDGE:
return CELL_GCM_TEXTURE_CLAMP_TO_EDGE;
break;
case RGLGCM_CLAMP_TO_BORDER:
return CELL_GCM_TEXTURE_BORDER;
break;
case RGLGCM_MIRRORED_REPEAT:
return CELL_GCM_TEXTURE_MIRROR;
break;
case RGLGCM_MIRROR_CLAMP_TO_EDGE:
return CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP_TO_EDGE;
break;
case RGLGCM_MIRROR_CLAMP_TO_BORDER:
return CELL_GCM_TEXTURE_MIRROR_ONCE_BORDER;
break;
case RGLGCM_MIRROR_CLAMP:
return CELL_GCM_TEXTURE_MIRROR_ONCE_CLAMP;
break;
default:
return 0;
break;
}
return 0;
}
// Fast conversion for values between 0.0 and 65535.0
static inline GLuint RGLGCM_QUICK_FLOAT2UINT (const GLfloat f)
{
union
{
GLfloat f;
GLuint ui;
} t;
t.f = f + RGLGCM_F0_DOT_0;
return t.ui & 0xffff;
}
// construct a packed unsigned int ARGB8 color
static inline void RGLGCM_CALC_COLOR_LE_ARGB8( GLuint *color0, const GLfloat r,
const GLfloat g, const GLfloat b, const GLfloat a )
{
GLuint r2, g2, b2, a2;
r2 = RGLGCM_QUICK_FLOAT2UINT( r * 255.0f );
g2 = RGLGCM_QUICK_FLOAT2UINT( g * 255.0f );
b2 = RGLGCM_QUICK_FLOAT2UINT( b * 255.0f );
a2 = RGLGCM_QUICK_FLOAT2UINT( a * 255.0f );
*color0 = ( a2 << 24 ) | ( r2 << 16 ) | ( g2 << 8 ) | ( b2 << 0 );
}
// Utility to let RSX wait for complete RSX pipeline idle
static inline void rglGcmUtilWaitForIdle (void)
{
CellGcmContextData *thisContext = (CellGcmContextData*)gCellGcmCurrentContext;
// set write label command in push buffer, and wait
// NOTE: this is for RSX to wailt
rglGcmSetWriteBackEndLabel(thisContext, RGLGCM_UTIL_LABEL_INDEX, rglGcmState_i.labelValue );
rglGcmSetWaitLabel(thisContext, RGLGCM_UTIL_LABEL_INDEX, rglGcmState_i.labelValue);
// increment label value for next time.
rglGcmState_i.labelValue++;
// make sure the entire pipe in clear not just the front end
// Utility function that does GPU 'finish'.
rglGcmSetWriteBackEndLabel(thisContext, RGLGCM_UTIL_LABEL_INDEX, rglGcmState_i.labelValue );
rglGcmFlush(gCellGcmCurrentContext);
while( *(cellGcmGetLabelAddress( RGLGCM_UTIL_LABEL_INDEX)) != rglGcmState_i.labelValue);
rglGcmState_i.labelValue++;
}
// Prints out an int in hexedecimal and binary, broken into bytes.
// Can be used for printing out macro and constant values.
// example: rglPrintIt( RGLGCM_3DCONST(SET_SURFACE_FORMAT, COLOR, LE_A8R8G8B8) );
// 00 00 00 08 : 00000000 00000000 00000000 00001000 */
static inline void rglPrintIt (unsigned int v)
{
// HEX (space between bytes)
printf( "%02x %02x %02x %02x : ", ( v >> 24 )&0xff, ( v >> 16 )&0xff, ( v >> 8 )&0xff, v&0xff );
// BINARY (space between bytes)
for ( unsigned int mask = ( 0x1 << 31 ), i = 1; mask != 0; mask >>= 1, i++ )
printf( "%d%s", ( v & mask ) ? 1 : 0, ( i % 8 == 0 ) ? " " : "" );
printf( "\n" );
}
// prints the last numWords of the command fifo
static inline void rglPrintFifoFromPut( unsigned int numWords )
{
for ( int i = -numWords; i <= -1; i++ )
rglPrintIt((( uint32_t* )rglGcmState_i.fifo.ctx.current )[i] );
}
// prints the last numWords of the command fifo
static inline void rglPrintFifoFromGet( unsigned int numWords )
{
for ( int i = -numWords; i <= -1; i++ )
rglPrintIt((( uint32_t* )rglGcmState_i.fifo.lastGetRead )[i] );
}
#endif