|
|
//========= Copyright (c) 2010, Valve Corporation, All rights reserved. ============//
/* SCE CONFIDENTIAL */ /* PlayStation(R)3 Programmer Tool Runtime Library 350.001 */ /* Copyright (C) 2009 Sony Computer Entertainment Inc. */ /* All Rights Reserved. */ /* File: main.cpp
* Description: * simple graphics to show how to use libgcm * */ #include "errorrenderloop.h"
#include <ppu_intrinsics.h>
#define ARRAYSIZE( ARRAY ) ( sizeof( ARRAY ) / sizeof( ( ARRAY )[0] ) )
#ifdef _DEBUG
#define CELL_GCMUTIL_ASSERT(X) do{ if( !( X ) ) {printf( "Assert(%s)\n%s:%d\n", #X, __FILE__, __LINE__ ); __builtin_snpause(); } }while(0)
#define CELL_GCMUTIL_CHECK_ASSERT(X) CELL_GCMUTIL_ASSERT( X == CELL_OK )
#define CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(X) CELL_GCMUTIL_ASSERT(X != 0 )
#else
#define CELL_GCMUTIL_ASSERT(X)
#define CELL_GCMUTIL_CHECK_ASSERT(X) (X)
#define CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(X) (void)(X)
#endif
// For exit routine
static void sysutil_exit_callback(uint64_t status, uint64_t param, void* userdata);
extern uint32_t _binary_errorshader_vpo_start; extern uint32_t _binary_errorshader_vpo_end; extern uint32_t _binary_errorshader_fpo_start; extern uint32_t _binary_errorshader_fpo_end;
PS3_GcmSharedData g_gcmSharedData;
using namespace cell::Gcm;
ErrorRenderLoop::ErrorRenderLoop() { m_keepRunning = true; m_nLocalMemHeap = 0; vertex_program_ptr = (unsigned char *)&_binary_errorshader_vpo_start; fragment_program_ptr = (unsigned char *)&_binary_errorshader_fpo_start; frame_index = 0; }
/* local memory allocation */ void *ErrorRenderLoop::localMemoryAlloc(const uint32_t size) { uint32_t allocated_size = (size + 1023) & (~1023); uint32_t base = m_nLocalMemHeap; m_nLocalMemHeap += allocated_size; return (void*)base; }
void *ErrorRenderLoop::localMemoryAlign(const uint32_t alignment, const uint32_t size) { m_nLocalMemHeap = (m_nLocalMemHeap + alignment-1) & (~(alignment-1)); return (void*)localMemoryAlloc(size); }
void ErrorRenderLoop::setRenderTarget(const uint32_t Index) { CellGcmSurface sf; sf.colorFormat = CELL_GCM_SURFACE_A8R8G8B8; sf.colorTarget = CELL_GCM_SURFACE_TARGET_0; sf.colorLocation[0] = CELL_GCM_LOCATION_LOCAL; sf.colorOffset[0] = color_offset[Index]; sf.colorPitch[0] = color_pitch;
sf.colorLocation[1] = CELL_GCM_LOCATION_LOCAL; sf.colorLocation[2] = CELL_GCM_LOCATION_LOCAL; sf.colorLocation[3] = CELL_GCM_LOCATION_LOCAL; sf.colorOffset[1] = 0; sf.colorOffset[2] = 0; sf.colorOffset[3] = 0; sf.colorPitch[1] = 64; sf.colorPitch[2] = 64; sf.colorPitch[3] = 64;
sf.depthFormat = CELL_GCM_SURFACE_Z24S8; sf.depthLocation = CELL_GCM_LOCATION_LOCAL; sf.depthOffset = depth_offset; sf.depthPitch = depth_pitch;
sf.type = CELL_GCM_SURFACE_PITCH; sf.antialias = CELL_GCM_SURFACE_CENTER_1;
sf.width = display_width; sf.height = display_height; sf.x = 0; sf.y = 0; cellGcmSetSurface(&sf); //cellGcmSetAntiAliasingControl(CELL_GCM_TRUE, CELL_GCM_FALSE, CELL_GCM_FALSE, 0xffff);
}
/* wait until flip */ static void waitFlip(void) { while (cellGcmGetFlipStatus()!=0){ sys_timer_usleep(300); } cellGcmResetFlipStatus(); }
void ErrorRenderLoop::flip(void) { static int first=1;
// wait until the previous flip executed
if (first!=1) waitFlip(); else cellGcmResetFlipStatus();
if(cellGcmSetFlip(frame_index) != CELL_OK) return; cellGcmFlush();
// resend status
setDrawEnv(); setRenderState();
cellGcmSetWaitFlip();
// New render target
frame_index = (frame_index+1)%COLOR_BUFFER_NUM; setRenderTarget(frame_index);
first=0; }
void ErrorRenderLoop::initShader(void) { vertex_program = (CGprogram)vertex_program_ptr; fragment_program = (CGprogram)fragment_program_ptr;
// init
cellGcmCgInitProgram(vertex_program); cellGcmCgInitProgram(fragment_program);
uint32_t ucode_size; void *ucode; cellGcmCgGetUCode(fragment_program, &ucode, &ucode_size); // 64B alignment required
void *ret = localMemoryAlign(64, ucode_size); fragment_program_ucode = ret; memcpy(fragment_program_ucode, ucode, ucode_size);
cellGcmCgGetUCode(vertex_program, &ucode, &ucode_size); vertex_program_ucode = ucode; }
static void buildProjection(float *M, const float top, const float bottom, const float left, const float right, const float near, const float far) { memset(M, 0, 16*sizeof(float));
M[0*4+0] = (2.0f*near) / (right - left); M[1*4+1] = (2.0f*near) / (bottom - top);
float A = (right + left) / (right - left); float B = (top + bottom) / (top - bottom); float C = -(far + near) / (far - near); float D = -(2.0f*far*near) / (far - near);
M[0*4 + 2] = A; M[1*4 + 2] = B; M[2*4 + 2] = C; M[3*4 + 2] = -1.0f; M[2*4 + 3] = D; }
static void matrixMul(float *Dest, float *A, float *B) { for (int i=0; i < 4; i++) { for (int j=0; j < 4; j++) { Dest[i*4+j] = A[i*4+0]*B[0*4+j] + A[i*4+1]*B[1*4+j] + A[i*4+2]*B[2*4+j] + A[i*4+3]*B[3*4+j]; } } }
static void matrixTranslate(float *M, const float x, const float y, const float z) { memset(M, 0, sizeof(float)*16); M[0*4+3] = x; M[1*4+3] = y; M[2*4+3] = z;
M[0*4+0] = 1.0f; M[1*4+1] = 1.0f; M[2*4+2] = 1.0f; M[3*4+3] = 1.0f; }
/*
static void unitMatrix(float *M) { M[0*4+0] = 1.0f; M[0*4+1] = 0.0f; M[0*4+2] = 0.0f; M[0*4+3] = 0.0f;
M[1*4+0] = 0.0f; M[1*4+1] = 1.0f; M[1*4+2] = 0.0f; M[1*4+3] = 0.0f;
M[2*4+0] = 0.0f; M[2*4+1] = 0.0f; M[2*4+2] = 1.0f; M[2*4+3] = 0.0f;
M[3*4+0] = 0.0f; M[3*4+1] = 0.0f; M[3*4+2] = 0.0f; M[3*4+3] = 1.0f; }
*/ #define CB_SIZE (0x10000)
int32_t ErrorRenderLoop::initDisplay(void) { uint32_t color_depth=4; // ARGB8
uint32_t z_depth=4; // COMPONENT24
void *color_base_addr; void *depth_base_addr; void *color_addr[COLOR_BUFFER_NUM]; void *depth_addr; CellVideoOutResolution resolution;
// display initialize
// read the current video status
// INITIAL DISPLAY MODE HAS TO BE SET BY RUNNING SETMONITOR.SELF
CellVideoOutState videoState; CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState)); CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutGetResolution(videoState.displayMode.resolutionId, &resolution));
display_width = resolution.width; display_height = resolution.height; color_pitch = display_width*color_depth; depth_pitch = display_width*z_depth;
uint32_t color_size = color_pitch*display_height; uint32_t depth_size = depth_pitch*display_height;
CellVideoOutConfiguration videocfg; memset(&videocfg, 0, sizeof(CellVideoOutConfiguration)); videocfg.resolutionId = videoState.displayMode.resolutionId; videocfg.format = CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8; videocfg.pitch = color_pitch;
// set video out configuration with waitForEvent set to 0 (4th parameter)
CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutConfigure(CELL_VIDEO_OUT_PRIMARY, &videocfg, NULL, 0)); CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState));
switch (videoState.displayMode.aspect){ case CELL_VIDEO_OUT_ASPECT_4_3: display_aspect_ratio=4.0f/3.0f; break; case CELL_VIDEO_OUT_ASPECT_16_9: display_aspect_ratio=16.0f/9.0f; break; default: printf("unknown aspect ratio %x\n", videoState.displayMode.aspect); display_aspect_ratio=16.0f/9.0f; }
cellGcmSetFlipMode(CELL_GCM_DISPLAY_VSYNC);
// get config
CellGcmConfig config; cellGcmGetConfiguration(&config); // buffer memory allocation
m_nLocalMemHeap = (uint32_t)config.localAddress;
color_base_addr = localMemoryAlign(64, COLOR_BUFFER_NUM*color_size);
for (int i = 0; i < COLOR_BUFFER_NUM; i++) { color_addr[i]= (void *)((uint32_t)color_base_addr+ (i*color_size)); CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(color_addr[i], &color_offset[i])); }
// regist surface
for (int i = 0; i < COLOR_BUFFER_NUM; i++) { CELL_GCMUTIL_CHECK_ASSERT(cellGcmSetDisplayBuffer(i, color_offset[i], color_pitch, display_width, display_height)); }
depth_base_addr = localMemoryAlign(64, depth_size); depth_addr = depth_base_addr; CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(depth_addr, &depth_offset));
return 0; }
// 65 verts in polySurfaceShape1
ErrorRenderLoop::Vertex_t g_verts_polySurfaceShape1[65] = { {0.287,2.232,-0.144, 0.398,0.702,-0.590, 0xFFFF5FFF }, {-0.287,2.232,-0.144, -0.404,0.699,-0.590, 0xFFFF00FF }, {-1.634,-0.134,-0.134, -0.808,-0.006,-0.588, 0xFFFF00FF }, {-1.366,-0.598,-0.134, -0.413,-0.695,-0.589, 0xFFFF00FF }, {1.345,-0.635,-0.155, 0.400,-0.700,-0.592, 0xFFFF00FF }, {1.655,-0.097,-0.155, 0.806,0.001,-0.592, 0xFFFF00FF }, {0.287,2.232,0.144, 0.455,0.835,0.308, 0xFFFF5FFF }, {-0.287,2.232,0.144, -0.462,0.832,0.309, 0xFFFF5FFF }, {-1.634,-0.134,0.134, -0.937,-0.034,0.347, 0xFFFF00FF }, {-1.366,-0.598,0.134, -0.484,-0.795,0.367, 0xFFFF5FFF }, {1.345,-0.635,0.155, 0.470,-0.802,0.369, 0xFFFF5FFF }, {1.655,-0.097,0.155, 0.937,-0.027,0.348, 0xFFFF00FF }, {0.000,0.500,-0.257, -0.007,0.000,-1.000, 0xFFFF00FF }, {0.000,0.274,0.422, 0.000,0.962,0.272, 0xFF0076FF }, {0.000,-0.085,0.422, 0.000,-0.962,0.272, 0xFF0076FF }, {-0.173,0.094,0.422, -0.964,0.000,0.266, 0xFF0076FF }, {0.173,0.094,0.422, 0.964,0.000,0.266, 0xFF0076FF }, {-0.058,0.445,0.422, -0.592,-0.698,0.404, 0xFF0076FF }, {0.058,0.445,0.422, 0.591,-0.698,0.404, 0xFF0076FF }, {0.002,2.002,0.422, 0.019,0.915,0.403, 0xFF0000FF }, {0.173,1.774,0.422, 0.871,0.278,0.405, 0xFF0000FF }, {-0.172,1.789,0.422, -0.864,0.296,0.407, 0xFF0000FF }, {0.088,0.787,0.422, 0.963,-0.084,0.256, 0xFF0076FF }, {-0.088,0.787,0.422, -0.963,-0.082,0.256, 0xFF0076FF }, {0.124,1.192,0.422, 0.949,-0.082,0.304, 0xFF0000FF }, {-0.123,1.192,0.422, -0.950,-0.081,0.302, 0xFF0000FF }, {0.161,1.597,0.422, 0.935,-0.070,0.347, 0xFF0000FF }, {-0.159,1.597,0.422, -0.936,-0.071,0.345, 0xFF0000FF }, {0.000,0.274,0.349, 0.000,0.818,-0.575, 0xFFFFFFFF }, {-0.173,0.094,0.349, -0.815,0.000,-0.579, 0xFFFFFFFF }, {0.000,-0.085,0.349, 0.000,-0.818,-0.575, 0xFF0076FF }, {0.173,0.094,0.349, 0.815,0.000,-0.579, 0xFF0076FF }, {0.173,1.774,0.349, 0.739,0.219,-0.637, 0xFFFFFFFF }, {0.002,2.002,0.349, 0.018,0.825,-0.566, 0xFFFFFFFF }, {-0.172,1.789,0.349, -0.738,0.235,-0.633, 0xFFFFFFFF }, {0.058,0.445,0.349, 0.549,-0.600,-0.582, 0xFFFFFFFF }, {0.088,0.787,0.349, 0.704,-0.063,-0.707, 0xFFFFFFFF }, {-0.088,0.787,0.349, -0.704,-0.062,-0.707, 0xFFFFFFFF }, {0.124,1.192,0.349, 0.704,-0.063,-0.707, 0xFFFFFFFF }, {-0.123,1.192,0.349, -0.704,-0.062,-0.707, 0xFFFFFFFF }, {0.161,1.597,0.349, 0.708,-0.055,-0.704, 0xFFFFFFFF }, {-0.159,1.597,0.349, -0.707,-0.056,-0.705, 0xFFFFFFFF }, {-0.058,0.445,0.349, -0.549,-0.600,-0.582, 0xFFFFFFFF }, {0.280,2.195,0.188, 0.318,0.461,0.828, 0xFFFF5FFF }, {-0.279,2.195,0.188, -0.323,0.457,0.829, 0xFFFF5FFF }, {0.000,0.508,0.298, -0.007,0.000,1.000, 0xFFFF00FF }, {-1.591,-0.110,0.178, -0.535,0.082,0.841, 0xFFFF00FF }, {-1.331,-0.561,0.178, -0.213,-0.432,0.877, 0xFFFF5FFF }, {1.310,-0.597,0.199, 0.199,-0.432,0.880, 0xFFFF5FFF }, {1.612,-0.074,0.199, 0.529,0.089,0.844, 0xFFFF00FF }, {-0.150,1.762,0.445, -0.414,0.061,0.908, 0xFF0000FF }, {0.150,1.747,0.445, 0.414,0.057,0.909, 0xFF0000FF }, {0.002,1.965,0.445, 0.016,0.404,0.915, 0xFF0000FF }, {-0.076,0.808,0.445, -0.498,-0.043,0.866, 0xFF0076FF }, {0.050,0.482,0.445, 0.464,-0.229,0.856, 0xFF0076FF }, {0.077,0.808,0.445, 0.497,-0.043,0.866, 0xFF0076FF }, {-0.107,1.194,0.445, -0.459,-0.037,0.888, 0xFF0000FF }, {0.108,1.194,0.445, 0.457,-0.037,0.888, 0xFF0000FF }, {-0.138,1.580,0.445, -0.423,-0.034,0.905, 0xFF0000FF }, {0.140,1.580,0.445, 0.422,-0.034,0.906, 0xFF0000FF }, {-0.050,0.482,0.445, -0.464,-0.229,0.856, 0xFF0076FF }, {0.000,-0.067,0.447, 0.000,-0.599,0.800, 0xFF0076FF }, {0.000,0.255,0.447, 0.000,0.599,0.800, 0xFF0076FF }, {-0.155,0.094,0.447, -0.603,0.000,0.798, 0xFF0076FF }, {0.155,0.094,0.447, 0.603,0.000,0.798, 0xFF0076FF }, }; // 118 triangles
uint16_t g_tris_polySurfaceShape1[118][3] = { { 0, 1, 6 } , { 6, 1, 7 } , { 1, 2, 7 } , { 7, 2, 8 } , { 2, 3, 8 } , { 8, 3, 9 } , { 3, 4, 9 } , { 9, 4, 10 } , { 4, 5, 10 } , { 10, 5, 11 } , { 5, 0, 11 } , { 11, 0, 6 } , { 1, 0, 12 } , { 2, 1, 12 } , { 3, 2, 12 } , { 4, 3, 12 } , { 5, 4, 12 } , { 0, 5, 12 } , { 43, 44, 45 } , { 44, 46, 45 } , { 46, 47, 45 } , { 47, 48, 45 } , { 48, 49, 45 } , { 49, 43, 45 } , { 28, 30, 29 } , { 30, 28, 31 } , { 32, 34, 33 } , { 35, 37, 36 } , { 36, 39, 38 } , { 38, 41, 40 } , { 34, 40, 41 } , { 40, 34, 32 } , { 37, 35, 42 } , { 39, 36, 37 } , { 41, 38, 39 } , { 62, 63, 61 } , { 61, 64, 62 } , { 51, 52, 50 } , { 54, 55, 53 } , { 55, 57, 56 } , { 57, 59, 58 } , { 50, 58, 59 } , { 59, 51, 50 } , { 53, 60, 54 } , { 56, 53, 55 } , { 58, 56, 57 } , { 13, 28, 15 } , { 28, 29, 15 } , { 15, 29, 14 } , { 29, 30, 14 } , { 14, 30, 16 } , { 30, 31, 16 } , { 16, 31, 13 } , { 31, 28, 13 } , { 20, 32, 19 } , { 32, 33, 19 } , { 19, 33, 21 } , { 33, 34, 21 } , { 18, 35, 22 } , { 35, 36, 22 } , { 22, 36, 24 } , { 36, 38, 24 } , { 24, 38, 26 } , { 38, 40, 26 } , { 21, 34, 27 } , { 34, 41, 27 } , { 26, 40, 20 } , { 40, 32, 20 } , { 23, 37, 17 } , { 37, 42, 17 } , { 17, 42, 18 } , { 42, 35, 18 } , { 25, 39, 23 } , { 39, 37, 23 } , { 27, 41, 25 } , { 41, 39, 25 } , { 7, 44, 6 } , { 6, 44, 43 } , { 8, 46, 7 } , { 7, 46, 44 } , { 9, 47, 8 } , { 8, 47, 46 } , { 9, 10, 47 } , { 47, 10, 48 } , { 10, 11, 48 } , { 48, 11, 49 } , { 11, 6, 49 } , { 49, 6, 43 } , { 19, 21, 52 } , { 21, 50, 52 } , { 19, 52, 20 } , { 52, 51, 20 } , { 18, 22, 54 } , { 22, 55, 54 } , { 22, 24, 55 } , { 24, 57, 55 } , { 26, 59, 24 } , { 59, 57, 24 } , { 21, 27, 50 } , { 27, 58, 50 } , { 20, 51, 26 } , { 51, 59, 26 } , { 18, 54, 17 } , { 54, 60, 17 } , { 17, 60, 23 } , { 60, 53, 23 } , { 23, 53, 25 } , { 53, 56, 25 } , { 27, 25, 58 } , { 25, 56, 58 } , { 14, 61, 15 } , { 61, 63, 15 } , { 13, 15, 62 } , { 15, 63, 62 } , { 13, 62, 16 } , { 62, 64, 16 } , { 14, 16, 61 } , { 16, 64, 61 } };
void ErrorRenderLoop::setDrawEnv(void) { cellGcmSetColorMask(CELL_GCM_COLOR_MASK_B| CELL_GCM_COLOR_MASK_G| CELL_GCM_COLOR_MASK_R| CELL_GCM_COLOR_MASK_A);
cellGcmSetColorMaskMrt(0); uint16_t x,y,w,h; float min, max; float scale[4],offset[4];
x = 0; y = 0; w = display_width; h = display_height; min = 0.0f; max = 1.0f; scale[0] = w * 0.5f; scale[1] = h * -0.5f; scale[2] = (max - min) * 0.5f; scale[3] = 0.0f; offset[0] = x + scale[0]; offset[1] = y + h * 0.5f; offset[2] = (max + min) * 0.5f; offset[3] = 0.0f;
cellGcmSetViewport(x, y, w, h, min, max, scale, offset); cellGcmSetClearColor((64<<0)|(64<<8)|(64<<16)|(64<<24));
cellGcmSetDepthTestEnable(CELL_GCM_TRUE); cellGcmSetDepthFunc(CELL_GCM_LESS);
}
void ErrorRenderLoop::setRenderState(void) { cellGcmSetVertexProgram(vertex_program, vertex_program_ucode); cellGcmSetVertexDataArray(position_index, 0, sizeof(Vertex_t), 3, CELL_GCM_VERTEX_F, CELL_GCM_LOCATION_LOCAL, m_nVertPositionOffset); cellGcmSetVertexDataArray(normal_index, 0, sizeof(Vertex_t), 3, CELL_GCM_VERTEX_F, CELL_GCM_LOCATION_LOCAL, m_nVertNormalOffset); cellGcmSetVertexDataArray(color_index, 0, sizeof(Vertex_t), 4, CELL_GCM_VERTEX_UB, CELL_GCM_LOCATION_LOCAL, m_nVertColorOffset );
cellGcmSetFragmentProgram(fragment_program, fragment_offset);
}
void AngleMatrix( float yaw, float pitch, float roll, float matrix[16] ) { float sy = sinf(yaw),cy = cosf( yaw ),sp = sinf( pitch ),cp = cosf( pitch ),sr = sinf( roll ),cr = cosf( roll );
// matrix = (YAW * PITCH) * ROLL
matrix[0*4+0] = cp*cy; matrix[1*4+0] = cp*sy; matrix[2*4+0] = -sp;
// NOTE: Do not optimize this to reduce multiplies! optimizer bug will screw this up.
matrix[0*4+1] = sr*sp*cy+cr*-sy; matrix[1*4+1] = sr*sp*sy+cr*cy; matrix[2*4+1] = sr*cp; matrix[0*4+2] = (cr*sp*cy+-sr*-sy); matrix[1*4+2] = (cr*sp*sy+-sr*cy); matrix[2*4+2] = cr*cp;
matrix[0*4+3] = 0.0f; matrix[1*4+3] = 0.0f; matrix[2*4+3] = 0.0f; matrix[3*4+0] = 0; matrix[3*4+1] = 0; matrix[3*4+2] = 0; matrix[3*4+3] = 1; }
// call this AFTER setRenderState and setRenderObject
void ErrorRenderLoop::setTransforms(float *M) { // transform
float P[16]; float V[16]; float VP[16];
// projection
buildProjection(P, -1.0f, 1.0f, -1.0f, 1.0f, 1.0, 10000.0f);
// 16:9 scale or 4:3 scale
matrixTranslate(V, 0.0f, 0.0f, -4.0); V[0*4 + 0] = 1.0f / display_aspect_ratio; V[1*4 + 1] = 1.0f;
// model view
matrixMul(VP, P, V);
matrixMul(MVP, VP, M);
cellGcmSetVertexProgramParameter(model_view_projection, MVP); }
int32_t ErrorRenderLoop::setRenderObject(void) { void *ret = localMemoryAlign(128, sizeof(Vertex_t) * ARRAYSIZE( g_verts_polySurfaceShape1 ) ); m_pVertexBuffer = (Vertex_t*)ret; memcpy( m_pVertexBuffer, g_verts_polySurfaceShape1, sizeof( g_verts_polySurfaceShape1 ) ); m_pIndexBuffer = (uint16_t *)localMemoryAlign( 128, sizeof( uint16_t ) * ARRAYSIZE( g_tris_polySurfaceShape1 ) * 3 ); memcpy( m_pIndexBuffer, g_tris_polySurfaceShape1, sizeof( g_tris_polySurfaceShape1 ) );
model_view_projection = cellGcmCgGetNamedParameter(vertex_program, "modelViewProj"); CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(model_view_projection); CGparameter position = cellGcmCgGetNamedParameter(vertex_program, "position"); CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(position); CGparameter normal = cellGcmCgGetNamedParameter(vertex_program, "normal"); CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(normal); CGparameter color = cellGcmCgGetNamedParameter(vertex_program, "color"); CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(color);
// get Vertex Attribute index
position_index = cellGcmCgGetParameterResource(vertex_program, position) - CG_ATTR0; normal_index = cellGcmCgGetParameterResource(vertex_program, normal) - CG_ATTR0; color_index = cellGcmCgGetParameterResource(vertex_program, color) - CG_ATTR0;
// fragment program offset
CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(fragment_program_ucode, &fragment_offset)); CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_pVertexBuffer->x, &m_nVertPositionOffset)); CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_pVertexBuffer->nx, &m_nVertNormalOffset)); CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_pVertexBuffer->rgba, &m_nVertColorOffset)); CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(m_pIndexBuffer, &m_nIndexBufferLocalMemoryOffset)); return 0; }
const uint32_t g_nInitCmdBuffer = 0x1000;
int32_t SimpleContextCallback( struct CellGcmContextData *pData, uint32_t nSize ) { *pData->current = CELL_GCM_JUMP( g_nInitCmdBuffer ); __sync(); CellGcmControl * pControlRegister = cellGcmGetControlRegister(); pControlRegister->put = g_nInitCmdBuffer; do { sys_timer_usleep( 60 ); } while ( pControlRegister->get != g_nInitCmdBuffer ); pData->current = pData->begin; return CELL_OK; }
int ErrorRenderLoop::Run( void ) { // Exit routines
{ // register sysutil exit callback
CELL_GCMUTIL_CHECK_ASSERT( cellSysutilRegisterCallback( 0, sysutil_exit_callback, this ) ); CELL_GCMUTIL_CHECK_ASSERT( cellSysutilCheckCallback() ); if ( !m_keepRunning ) return 0; } if( g_gcmSharedData.m_pIoMemory ) { // GCM has already been initialized, no need to reinitialize it.
// But we have to drive RSX to our new command buffer
const uint32_t nCmdBufferOverfetchSlack = 1024; //printf( "Entering Error Render Loop, reusing IO memory @%p size 0x%X; initial ctx={%p,%p,%p;fn=%p}\n", g_gcmSharedData.m_pIoMemory, g_gcmSharedData.m_nIoMemorySize, gCellGcmCurrentContext->begin, gCellGcmCurrentContext->current, gCellGcmCurrentContext->end, gCellGcmCurrentContext->callback );
cellGcmSetCurrentBuffer( // start command buffer right after initialization fixed command buffer (always the first 4 k of IO memory)
( uint32_t* )( uint32_t( g_gcmSharedData.m_pIoMemory ) + g_nInitCmdBuffer ), // the size is all of IO memory, minus initialization command buffer, minus overfetch amount in the end of command buffer to avoid a crash,
// minus 4 bytes to insert a JUMP to the start of command buffer when we run out of space
g_gcmSharedData.m_nIoMemorySize - nCmdBufferOverfetchSlack - g_nInitCmdBuffer - sizeof( uint32_t ) ); CellGcmContextData *pCurrentContext = gCellGcmCurrentContext; pCurrentContext->callback = SimpleContextCallback; CellGcmControl * pControlRegister = cellGcmGetControlRegister(); uint32_t nPut = pControlRegister->put; uint32_t * pCurrentCmd = ( uint32_t* )( uint32_t( g_gcmSharedData.m_pIoMemory ) + nPut ); pCurrentContext->current = pCurrentCmd; // de facto current
// #ifndef _CERT
// if ( pControlRegister->put != g_nInitCmdBuffer || gCellGcmCurrentContext->current != ( uint32_t* )( uint32_t( g_gcmSharedData.m_pIoMemory ) + g_nInitCmdBuffer ) )
// {
// __builtin_snpause();
// }
// #endif
} else { sys_addr_t allocatedAddress = NULL; int smaResult = sys_memory_allocate( 1 * 1024 * 1024, SYS_MEMORY_PAGE_SIZE_1M, &allocatedAddress ); if( smaResult != CELL_OK ) return smaResult; void* host_addr = (void*)allocatedAddress; printf( "Entering Error Render loop, IO memory @%p...\n", host_addr ); CELL_GCMUTIL_ASSERT(host_addr != NULL); CELL_GCMUTIL_CHECK_ASSERT(cellGcmInit(CB_SIZE, HOST_SIZE, host_addr)); }
if (initDisplay()!=0) return -1;
initShader();
setDrawEnv();
if (setRenderObject()) return -1;
setRenderState();
// 1st time
setRenderTarget(frame_index);
// rendering loop
CELL_GCMUTIL_ASSERT(m_keepRunning); float flTime = 0; uint32_t nFrames = 0; while (m_keepRunning) { // check system event
CELL_GCMUTIL_CHECK_ASSERT( cellSysutilCheckCallback() );
// clear frame buffer
cellGcmSetClearSurface( CELL_GCM_CLEAR_Z | CELL_GCM_CLEAR_R | CELL_GCM_CLEAR_G | CELL_GCM_CLEAR_B | CELL_GCM_CLEAR_A ); float tm[16]; AngleMatrix(0.1f * sinf( flTime * 0.5f ), 0.5f * sinf( flTime * 0.45f ), 0.1f * sinf( flTime*0.02f ), tm); setTransforms(tm); // set draw command
if( flTime > 4.0f ) { cellGcmSetDrawIndexArray(CELL_GCM_PRIMITIVE_TRIANGLES, 3 * ARRAYSIZE( g_tris_polySurfaceShape1 ), CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16, CELL_GCM_LOCATION_LOCAL, m_nIndexBufferLocalMemoryOffset ); }
// start reading the command buffer
flip(); flTime += 1/60.0f; nFrames ++; } printf( "Exiting Error Render loop, %u frames rendered", nFrames ); cellSysutilUnregisterCallback( 0 ); // Let RSX wait for final flip
cellGcmSetWaitFlip();
// Let PPU wait for all commands done (include waitFlip)
cellGcmFinish(1); // let's just leak this memory to avoid problems due to initializing GCM in different places, it doesn't matter
//sys_memory_free( g_gcmSharedData.m_pIoMemory );
printf(".\n");
return 0; }
void sysutil_exit_callback(uint64_t status, uint64_t param, void* userdata) { (void) param; (void) userdata;
switch(status) { case CELL_SYSUTIL_REQUEST_EXITGAME: ((ErrorRenderLoop*)userdata)->m_keepRunning = false; break; case CELL_SYSUTIL_DRAWING_BEGIN: case CELL_SYSUTIL_DRAWING_END: case CELL_SYSUTIL_SYSTEM_MENU_OPEN: case CELL_SYSUTIL_SYSTEM_MENU_CLOSE: case CELL_SYSUTIL_BGMPLAYBACK_PLAY: case CELL_SYSUTIL_BGMPLAYBACK_STOP: default: break; } }
|