Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

818 lines
23 KiB

  1. //========= Copyright (c) 2010, Valve Corporation, All rights reserved. ============//
  2. /* SCE CONFIDENTIAL */
  3. /* PlayStation(R)3 Programmer Tool Runtime Library 350.001 */
  4. /* Copyright (C) 2009 Sony Computer Entertainment Inc. */
  5. /* All Rights Reserved. */
  6. /* File: main.cpp
  7. * Description:
  8. * simple graphics to show how to use libgcm
  9. *
  10. */
  11. #include "errorrenderloop.h"
  12. #include <ppu_intrinsics.h>
  13. #define ARRAYSIZE( ARRAY ) ( sizeof( ARRAY ) / sizeof( ( ARRAY )[0] ) )
  14. #ifdef _DEBUG
  15. #define CELL_GCMUTIL_ASSERT(X) do{ if( !( X ) ) {printf( "Assert(%s)\n%s:%d\n", #X, __FILE__, __LINE__ ); __builtin_snpause(); } }while(0)
  16. #define CELL_GCMUTIL_CHECK_ASSERT(X) CELL_GCMUTIL_ASSERT( X == CELL_OK )
  17. #define CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(X) CELL_GCMUTIL_ASSERT(X != 0 )
  18. #else
  19. #define CELL_GCMUTIL_ASSERT(X)
  20. #define CELL_GCMUTIL_CHECK_ASSERT(X) (X)
  21. #define CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(X) (void)(X)
  22. #endif
  23. // For exit routine
  24. static void sysutil_exit_callback(uint64_t status, uint64_t param, void* userdata);
  25. extern uint32_t _binary_errorshader_vpo_start;
  26. extern uint32_t _binary_errorshader_vpo_end;
  27. extern uint32_t _binary_errorshader_fpo_start;
  28. extern uint32_t _binary_errorshader_fpo_end;
  29. PS3_GcmSharedData g_gcmSharedData;
  30. using namespace cell::Gcm;
  31. ErrorRenderLoop::ErrorRenderLoop()
  32. {
  33. m_keepRunning = true;
  34. m_nLocalMemHeap = 0;
  35. vertex_program_ptr =
  36. (unsigned char *)&_binary_errorshader_vpo_start;
  37. fragment_program_ptr =
  38. (unsigned char *)&_binary_errorshader_fpo_start;
  39. frame_index = 0;
  40. }
  41. /* local memory allocation */
  42. void *ErrorRenderLoop::localMemoryAlloc(const uint32_t size)
  43. {
  44. uint32_t allocated_size = (size + 1023) & (~1023);
  45. uint32_t base = m_nLocalMemHeap;
  46. m_nLocalMemHeap += allocated_size;
  47. return (void*)base;
  48. }
  49. void *ErrorRenderLoop::localMemoryAlign(const uint32_t alignment,
  50. const uint32_t size)
  51. {
  52. m_nLocalMemHeap = (m_nLocalMemHeap + alignment-1) & (~(alignment-1));
  53. return (void*)localMemoryAlloc(size);
  54. }
  55. void ErrorRenderLoop::setRenderTarget(const uint32_t Index)
  56. {
  57. CellGcmSurface sf;
  58. sf.colorFormat = CELL_GCM_SURFACE_A8R8G8B8;
  59. sf.colorTarget = CELL_GCM_SURFACE_TARGET_0;
  60. sf.colorLocation[0] = CELL_GCM_LOCATION_LOCAL;
  61. sf.colorOffset[0] = color_offset[Index];
  62. sf.colorPitch[0] = color_pitch;
  63. sf.colorLocation[1] = CELL_GCM_LOCATION_LOCAL;
  64. sf.colorLocation[2] = CELL_GCM_LOCATION_LOCAL;
  65. sf.colorLocation[3] = CELL_GCM_LOCATION_LOCAL;
  66. sf.colorOffset[1] = 0;
  67. sf.colorOffset[2] = 0;
  68. sf.colorOffset[3] = 0;
  69. sf.colorPitch[1] = 64;
  70. sf.colorPitch[2] = 64;
  71. sf.colorPitch[3] = 64;
  72. sf.depthFormat = CELL_GCM_SURFACE_Z24S8;
  73. sf.depthLocation = CELL_GCM_LOCATION_LOCAL;
  74. sf.depthOffset = depth_offset;
  75. sf.depthPitch = depth_pitch;
  76. sf.type = CELL_GCM_SURFACE_PITCH;
  77. sf.antialias = CELL_GCM_SURFACE_CENTER_1;
  78. sf.width = display_width;
  79. sf.height = display_height;
  80. sf.x = 0;
  81. sf.y = 0;
  82. cellGcmSetSurface(&sf);
  83. //cellGcmSetAntiAliasingControl(CELL_GCM_TRUE, CELL_GCM_FALSE, CELL_GCM_FALSE, 0xffff);
  84. }
  85. /* wait until flip */
  86. static void waitFlip(void)
  87. {
  88. while (cellGcmGetFlipStatus()!=0){
  89. sys_timer_usleep(300);
  90. }
  91. cellGcmResetFlipStatus();
  92. }
  93. void ErrorRenderLoop::flip(void)
  94. {
  95. static int first=1;
  96. // wait until the previous flip executed
  97. if (first!=1) waitFlip();
  98. else cellGcmResetFlipStatus();
  99. if(cellGcmSetFlip(frame_index) != CELL_OK) return;
  100. cellGcmFlush();
  101. // resend status
  102. setDrawEnv();
  103. setRenderState();
  104. cellGcmSetWaitFlip();
  105. // New render target
  106. frame_index = (frame_index+1)%COLOR_BUFFER_NUM;
  107. setRenderTarget(frame_index);
  108. first=0;
  109. }
  110. void ErrorRenderLoop::initShader(void)
  111. {
  112. vertex_program = (CGprogram)vertex_program_ptr;
  113. fragment_program = (CGprogram)fragment_program_ptr;
  114. // init
  115. cellGcmCgInitProgram(vertex_program);
  116. cellGcmCgInitProgram(fragment_program);
  117. uint32_t ucode_size;
  118. void *ucode;
  119. cellGcmCgGetUCode(fragment_program, &ucode, &ucode_size);
  120. // 64B alignment required
  121. void *ret = localMemoryAlign(64, ucode_size);
  122. fragment_program_ucode = ret;
  123. memcpy(fragment_program_ucode, ucode, ucode_size);
  124. cellGcmCgGetUCode(vertex_program, &ucode, &ucode_size);
  125. vertex_program_ucode = ucode;
  126. }
  127. static void buildProjection(float *M,
  128. const float top,
  129. const float bottom,
  130. const float left,
  131. const float right,
  132. const float near,
  133. const float far)
  134. {
  135. memset(M, 0, 16*sizeof(float));
  136. M[0*4+0] = (2.0f*near) / (right - left);
  137. M[1*4+1] = (2.0f*near) / (bottom - top);
  138. float A = (right + left) / (right - left);
  139. float B = (top + bottom) / (top - bottom);
  140. float C = -(far + near) / (far - near);
  141. float D = -(2.0f*far*near) / (far - near);
  142. M[0*4 + 2] = A;
  143. M[1*4 + 2] = B;
  144. M[2*4 + 2] = C;
  145. M[3*4 + 2] = -1.0f;
  146. M[2*4 + 3] = D;
  147. }
  148. static void matrixMul(float *Dest, float *A, float *B)
  149. {
  150. for (int i=0; i < 4; i++) {
  151. for (int j=0; j < 4; j++) {
  152. Dest[i*4+j]
  153. = A[i*4+0]*B[0*4+j]
  154. + A[i*4+1]*B[1*4+j]
  155. + A[i*4+2]*B[2*4+j]
  156. + A[i*4+3]*B[3*4+j];
  157. }
  158. }
  159. }
  160. static void matrixTranslate(float *M,
  161. const float x,
  162. const float y,
  163. const float z)
  164. {
  165. memset(M, 0, sizeof(float)*16);
  166. M[0*4+3] = x;
  167. M[1*4+3] = y;
  168. M[2*4+3] = z;
  169. M[0*4+0] = 1.0f;
  170. M[1*4+1] = 1.0f;
  171. M[2*4+2] = 1.0f;
  172. M[3*4+3] = 1.0f;
  173. }
  174. /*
  175. static void unitMatrix(float *M)
  176. {
  177. M[0*4+0] = 1.0f;
  178. M[0*4+1] = 0.0f;
  179. M[0*4+2] = 0.0f;
  180. M[0*4+3] = 0.0f;
  181. M[1*4+0] = 0.0f;
  182. M[1*4+1] = 1.0f;
  183. M[1*4+2] = 0.0f;
  184. M[1*4+3] = 0.0f;
  185. M[2*4+0] = 0.0f;
  186. M[2*4+1] = 0.0f;
  187. M[2*4+2] = 1.0f;
  188. M[2*4+3] = 0.0f;
  189. M[3*4+0] = 0.0f;
  190. M[3*4+1] = 0.0f;
  191. M[3*4+2] = 0.0f;
  192. M[3*4+3] = 1.0f;
  193. }
  194. */
  195. #define CB_SIZE (0x10000)
  196. int32_t ErrorRenderLoop::initDisplay(void)
  197. {
  198. uint32_t color_depth=4; // ARGB8
  199. uint32_t z_depth=4; // COMPONENT24
  200. void *color_base_addr;
  201. void *depth_base_addr;
  202. void *color_addr[COLOR_BUFFER_NUM];
  203. void *depth_addr;
  204. CellVideoOutResolution resolution;
  205. // display initialize
  206. // read the current video status
  207. // INITIAL DISPLAY MODE HAS TO BE SET BY RUNNING SETMONITOR.SELF
  208. CellVideoOutState videoState;
  209. CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState));
  210. CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutGetResolution(videoState.displayMode.resolutionId, &resolution));
  211. display_width = resolution.width;
  212. display_height = resolution.height;
  213. color_pitch = display_width*color_depth;
  214. depth_pitch = display_width*z_depth;
  215. uint32_t color_size = color_pitch*display_height;
  216. uint32_t depth_size = depth_pitch*display_height;
  217. CellVideoOutConfiguration videocfg;
  218. memset(&videocfg, 0, sizeof(CellVideoOutConfiguration));
  219. videocfg.resolutionId = videoState.displayMode.resolutionId;
  220. videocfg.format = CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8;
  221. videocfg.pitch = color_pitch;
  222. // set video out configuration with waitForEvent set to 0 (4th parameter)
  223. CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutConfigure(CELL_VIDEO_OUT_PRIMARY, &videocfg, NULL, 0));
  224. CELL_GCMUTIL_CHECK_ASSERT(cellVideoOutGetState(CELL_VIDEO_OUT_PRIMARY, 0, &videoState));
  225. switch (videoState.displayMode.aspect){
  226. case CELL_VIDEO_OUT_ASPECT_4_3:
  227. display_aspect_ratio=4.0f/3.0f;
  228. break;
  229. case CELL_VIDEO_OUT_ASPECT_16_9:
  230. display_aspect_ratio=16.0f/9.0f;
  231. break;
  232. default:
  233. printf("unknown aspect ratio %x\n", videoState.displayMode.aspect);
  234. display_aspect_ratio=16.0f/9.0f;
  235. }
  236. cellGcmSetFlipMode(CELL_GCM_DISPLAY_VSYNC);
  237. // get config
  238. CellGcmConfig config;
  239. cellGcmGetConfiguration(&config);
  240. // buffer memory allocation
  241. m_nLocalMemHeap = (uint32_t)config.localAddress;
  242. color_base_addr = localMemoryAlign(64, COLOR_BUFFER_NUM*color_size);
  243. for (int i = 0; i < COLOR_BUFFER_NUM; i++) {
  244. color_addr[i]= (void *)((uint32_t)color_base_addr+ (i*color_size));
  245. CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(color_addr[i], &color_offset[i]));
  246. }
  247. // regist surface
  248. for (int i = 0; i < COLOR_BUFFER_NUM; i++) {
  249. CELL_GCMUTIL_CHECK_ASSERT(cellGcmSetDisplayBuffer(i, color_offset[i], color_pitch, display_width, display_height));
  250. }
  251. depth_base_addr = localMemoryAlign(64, depth_size);
  252. depth_addr = depth_base_addr;
  253. CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(depth_addr, &depth_offset));
  254. return 0;
  255. }
  256. // 65 verts in polySurfaceShape1
  257. ErrorRenderLoop::Vertex_t g_verts_polySurfaceShape1[65] = {
  258. {0.287,2.232,-0.144, 0.398,0.702,-0.590, 0xFFFF5FFF },
  259. {-0.287,2.232,-0.144, -0.404,0.699,-0.590, 0xFFFF00FF },
  260. {-1.634,-0.134,-0.134, -0.808,-0.006,-0.588, 0xFFFF00FF },
  261. {-1.366,-0.598,-0.134, -0.413,-0.695,-0.589, 0xFFFF00FF },
  262. {1.345,-0.635,-0.155, 0.400,-0.700,-0.592, 0xFFFF00FF },
  263. {1.655,-0.097,-0.155, 0.806,0.001,-0.592, 0xFFFF00FF },
  264. {0.287,2.232,0.144, 0.455,0.835,0.308, 0xFFFF5FFF },
  265. {-0.287,2.232,0.144, -0.462,0.832,0.309, 0xFFFF5FFF },
  266. {-1.634,-0.134,0.134, -0.937,-0.034,0.347, 0xFFFF00FF },
  267. {-1.366,-0.598,0.134, -0.484,-0.795,0.367, 0xFFFF5FFF },
  268. {1.345,-0.635,0.155, 0.470,-0.802,0.369, 0xFFFF5FFF },
  269. {1.655,-0.097,0.155, 0.937,-0.027,0.348, 0xFFFF00FF },
  270. {0.000,0.500,-0.257, -0.007,0.000,-1.000, 0xFFFF00FF },
  271. {0.000,0.274,0.422, 0.000,0.962,0.272, 0xFF0076FF },
  272. {0.000,-0.085,0.422, 0.000,-0.962,0.272, 0xFF0076FF },
  273. {-0.173,0.094,0.422, -0.964,0.000,0.266, 0xFF0076FF },
  274. {0.173,0.094,0.422, 0.964,0.000,0.266, 0xFF0076FF },
  275. {-0.058,0.445,0.422, -0.592,-0.698,0.404, 0xFF0076FF },
  276. {0.058,0.445,0.422, 0.591,-0.698,0.404, 0xFF0076FF },
  277. {0.002,2.002,0.422, 0.019,0.915,0.403, 0xFF0000FF },
  278. {0.173,1.774,0.422, 0.871,0.278,0.405, 0xFF0000FF },
  279. {-0.172,1.789,0.422, -0.864,0.296,0.407, 0xFF0000FF },
  280. {0.088,0.787,0.422, 0.963,-0.084,0.256, 0xFF0076FF },
  281. {-0.088,0.787,0.422, -0.963,-0.082,0.256, 0xFF0076FF },
  282. {0.124,1.192,0.422, 0.949,-0.082,0.304, 0xFF0000FF },
  283. {-0.123,1.192,0.422, -0.950,-0.081,0.302, 0xFF0000FF },
  284. {0.161,1.597,0.422, 0.935,-0.070,0.347, 0xFF0000FF },
  285. {-0.159,1.597,0.422, -0.936,-0.071,0.345, 0xFF0000FF },
  286. {0.000,0.274,0.349, 0.000,0.818,-0.575, 0xFFFFFFFF },
  287. {-0.173,0.094,0.349, -0.815,0.000,-0.579, 0xFFFFFFFF },
  288. {0.000,-0.085,0.349, 0.000,-0.818,-0.575, 0xFF0076FF },
  289. {0.173,0.094,0.349, 0.815,0.000,-0.579, 0xFF0076FF },
  290. {0.173,1.774,0.349, 0.739,0.219,-0.637, 0xFFFFFFFF },
  291. {0.002,2.002,0.349, 0.018,0.825,-0.566, 0xFFFFFFFF },
  292. {-0.172,1.789,0.349, -0.738,0.235,-0.633, 0xFFFFFFFF },
  293. {0.058,0.445,0.349, 0.549,-0.600,-0.582, 0xFFFFFFFF },
  294. {0.088,0.787,0.349, 0.704,-0.063,-0.707, 0xFFFFFFFF },
  295. {-0.088,0.787,0.349, -0.704,-0.062,-0.707, 0xFFFFFFFF },
  296. {0.124,1.192,0.349, 0.704,-0.063,-0.707, 0xFFFFFFFF },
  297. {-0.123,1.192,0.349, -0.704,-0.062,-0.707, 0xFFFFFFFF },
  298. {0.161,1.597,0.349, 0.708,-0.055,-0.704, 0xFFFFFFFF },
  299. {-0.159,1.597,0.349, -0.707,-0.056,-0.705, 0xFFFFFFFF },
  300. {-0.058,0.445,0.349, -0.549,-0.600,-0.582, 0xFFFFFFFF },
  301. {0.280,2.195,0.188, 0.318,0.461,0.828, 0xFFFF5FFF },
  302. {-0.279,2.195,0.188, -0.323,0.457,0.829, 0xFFFF5FFF },
  303. {0.000,0.508,0.298, -0.007,0.000,1.000, 0xFFFF00FF },
  304. {-1.591,-0.110,0.178, -0.535,0.082,0.841, 0xFFFF00FF },
  305. {-1.331,-0.561,0.178, -0.213,-0.432,0.877, 0xFFFF5FFF },
  306. {1.310,-0.597,0.199, 0.199,-0.432,0.880, 0xFFFF5FFF },
  307. {1.612,-0.074,0.199, 0.529,0.089,0.844, 0xFFFF00FF },
  308. {-0.150,1.762,0.445, -0.414,0.061,0.908, 0xFF0000FF },
  309. {0.150,1.747,0.445, 0.414,0.057,0.909, 0xFF0000FF },
  310. {0.002,1.965,0.445, 0.016,0.404,0.915, 0xFF0000FF },
  311. {-0.076,0.808,0.445, -0.498,-0.043,0.866, 0xFF0076FF },
  312. {0.050,0.482,0.445, 0.464,-0.229,0.856, 0xFF0076FF },
  313. {0.077,0.808,0.445, 0.497,-0.043,0.866, 0xFF0076FF },
  314. {-0.107,1.194,0.445, -0.459,-0.037,0.888, 0xFF0000FF },
  315. {0.108,1.194,0.445, 0.457,-0.037,0.888, 0xFF0000FF },
  316. {-0.138,1.580,0.445, -0.423,-0.034,0.905, 0xFF0000FF },
  317. {0.140,1.580,0.445, 0.422,-0.034,0.906, 0xFF0000FF },
  318. {-0.050,0.482,0.445, -0.464,-0.229,0.856, 0xFF0076FF },
  319. {0.000,-0.067,0.447, 0.000,-0.599,0.800, 0xFF0076FF },
  320. {0.000,0.255,0.447, 0.000,0.599,0.800, 0xFF0076FF },
  321. {-0.155,0.094,0.447, -0.603,0.000,0.798, 0xFF0076FF },
  322. {0.155,0.094,0.447, 0.603,0.000,0.798, 0xFF0076FF },
  323. };
  324. // 118 triangles
  325. uint16_t g_tris_polySurfaceShape1[118][3] = {
  326. { 0, 1, 6 }
  327. , { 6, 1, 7 }
  328. , { 1, 2, 7 }
  329. , { 7, 2, 8 }
  330. , { 2, 3, 8 }
  331. , { 8, 3, 9 }
  332. , { 3, 4, 9 }
  333. , { 9, 4, 10 }
  334. , { 4, 5, 10 }
  335. , { 10, 5, 11 }
  336. , { 5, 0, 11 }
  337. , { 11, 0, 6 }
  338. , { 1, 0, 12 }
  339. , { 2, 1, 12 }
  340. , { 3, 2, 12 }
  341. , { 4, 3, 12 }
  342. , { 5, 4, 12 }
  343. , { 0, 5, 12 }
  344. , { 43, 44, 45 }
  345. , { 44, 46, 45 }
  346. , { 46, 47, 45 }
  347. , { 47, 48, 45 }
  348. , { 48, 49, 45 }
  349. , { 49, 43, 45 }
  350. , { 28, 30, 29 }
  351. , { 30, 28, 31 }
  352. , { 32, 34, 33 }
  353. , { 35, 37, 36 }
  354. , { 36, 39, 38 }
  355. , { 38, 41, 40 }
  356. , { 34, 40, 41 }
  357. , { 40, 34, 32 }
  358. , { 37, 35, 42 }
  359. , { 39, 36, 37 }
  360. , { 41, 38, 39 }
  361. , { 62, 63, 61 }
  362. , { 61, 64, 62 }
  363. , { 51, 52, 50 }
  364. , { 54, 55, 53 }
  365. , { 55, 57, 56 }
  366. , { 57, 59, 58 }
  367. , { 50, 58, 59 }
  368. , { 59, 51, 50 }
  369. , { 53, 60, 54 }
  370. , { 56, 53, 55 }
  371. , { 58, 56, 57 }
  372. , { 13, 28, 15 }
  373. , { 28, 29, 15 }
  374. , { 15, 29, 14 }
  375. , { 29, 30, 14 }
  376. , { 14, 30, 16 }
  377. , { 30, 31, 16 }
  378. , { 16, 31, 13 }
  379. , { 31, 28, 13 }
  380. , { 20, 32, 19 }
  381. , { 32, 33, 19 }
  382. , { 19, 33, 21 }
  383. , { 33, 34, 21 }
  384. , { 18, 35, 22 }
  385. , { 35, 36, 22 }
  386. , { 22, 36, 24 }
  387. , { 36, 38, 24 }
  388. , { 24, 38, 26 }
  389. , { 38, 40, 26 }
  390. , { 21, 34, 27 }
  391. , { 34, 41, 27 }
  392. , { 26, 40, 20 }
  393. , { 40, 32, 20 }
  394. , { 23, 37, 17 }
  395. , { 37, 42, 17 }
  396. , { 17, 42, 18 }
  397. , { 42, 35, 18 }
  398. , { 25, 39, 23 }
  399. , { 39, 37, 23 }
  400. , { 27, 41, 25 }
  401. , { 41, 39, 25 }
  402. , { 7, 44, 6 }
  403. , { 6, 44, 43 }
  404. , { 8, 46, 7 }
  405. , { 7, 46, 44 }
  406. , { 9, 47, 8 }
  407. , { 8, 47, 46 }
  408. , { 9, 10, 47 }
  409. , { 47, 10, 48 }
  410. , { 10, 11, 48 }
  411. , { 48, 11, 49 }
  412. , { 11, 6, 49 }
  413. , { 49, 6, 43 }
  414. , { 19, 21, 52 }
  415. , { 21, 50, 52 }
  416. , { 19, 52, 20 }
  417. , { 52, 51, 20 }
  418. , { 18, 22, 54 }
  419. , { 22, 55, 54 }
  420. , { 22, 24, 55 }
  421. , { 24, 57, 55 }
  422. , { 26, 59, 24 }
  423. , { 59, 57, 24 }
  424. , { 21, 27, 50 }
  425. , { 27, 58, 50 }
  426. , { 20, 51, 26 }
  427. , { 51, 59, 26 }
  428. , { 18, 54, 17 }
  429. , { 54, 60, 17 }
  430. , { 17, 60, 23 }
  431. , { 60, 53, 23 }
  432. , { 23, 53, 25 }
  433. , { 53, 56, 25 }
  434. , { 27, 25, 58 }
  435. , { 25, 56, 58 }
  436. , { 14, 61, 15 }
  437. , { 61, 63, 15 }
  438. , { 13, 15, 62 }
  439. , { 15, 63, 62 }
  440. , { 13, 62, 16 }
  441. , { 62, 64, 16 }
  442. , { 14, 16, 61 }
  443. , { 16, 64, 61 }
  444. };
  445. void ErrorRenderLoop::setDrawEnv(void)
  446. {
  447. cellGcmSetColorMask(CELL_GCM_COLOR_MASK_B|
  448. CELL_GCM_COLOR_MASK_G|
  449. CELL_GCM_COLOR_MASK_R|
  450. CELL_GCM_COLOR_MASK_A);
  451. cellGcmSetColorMaskMrt(0);
  452. uint16_t x,y,w,h;
  453. float min, max;
  454. float scale[4],offset[4];
  455. x = 0;
  456. y = 0;
  457. w = display_width;
  458. h = display_height;
  459. min = 0.0f;
  460. max = 1.0f;
  461. scale[0] = w * 0.5f;
  462. scale[1] = h * -0.5f;
  463. scale[2] = (max - min) * 0.5f;
  464. scale[3] = 0.0f;
  465. offset[0] = x + scale[0];
  466. offset[1] = y + h * 0.5f;
  467. offset[2] = (max + min) * 0.5f;
  468. offset[3] = 0.0f;
  469. cellGcmSetViewport(x, y, w, h, min, max, scale, offset);
  470. cellGcmSetClearColor((64<<0)|(64<<8)|(64<<16)|(64<<24));
  471. cellGcmSetDepthTestEnable(CELL_GCM_TRUE);
  472. cellGcmSetDepthFunc(CELL_GCM_LESS);
  473. }
  474. void ErrorRenderLoop::setRenderState(void)
  475. {
  476. cellGcmSetVertexProgram(vertex_program, vertex_program_ucode);
  477. cellGcmSetVertexDataArray(position_index,
  478. 0,
  479. sizeof(Vertex_t),
  480. 3,
  481. CELL_GCM_VERTEX_F,
  482. CELL_GCM_LOCATION_LOCAL,
  483. m_nVertPositionOffset);
  484. cellGcmSetVertexDataArray(normal_index,
  485. 0,
  486. sizeof(Vertex_t),
  487. 3,
  488. CELL_GCM_VERTEX_F,
  489. CELL_GCM_LOCATION_LOCAL,
  490. m_nVertNormalOffset);
  491. cellGcmSetVertexDataArray(color_index,
  492. 0,
  493. sizeof(Vertex_t),
  494. 4,
  495. CELL_GCM_VERTEX_UB,
  496. CELL_GCM_LOCATION_LOCAL,
  497. m_nVertColorOffset );
  498. cellGcmSetFragmentProgram(fragment_program, fragment_offset);
  499. }
  500. void AngleMatrix( float yaw, float pitch, float roll, float matrix[16] )
  501. {
  502. float sy = sinf(yaw),cy = cosf( yaw ),sp = sinf( pitch ),cp = cosf( pitch ),sr = sinf( roll ),cr = cosf( roll );
  503. // matrix = (YAW * PITCH) * ROLL
  504. matrix[0*4+0] = cp*cy;
  505. matrix[1*4+0] = cp*sy;
  506. matrix[2*4+0] = -sp;
  507. // NOTE: Do not optimize this to reduce multiplies! optimizer bug will screw this up.
  508. matrix[0*4+1] = sr*sp*cy+cr*-sy;
  509. matrix[1*4+1] = sr*sp*sy+cr*cy;
  510. matrix[2*4+1] = sr*cp;
  511. matrix[0*4+2] = (cr*sp*cy+-sr*-sy);
  512. matrix[1*4+2] = (cr*sp*sy+-sr*cy);
  513. matrix[2*4+2] = cr*cp;
  514. matrix[0*4+3] = 0.0f;
  515. matrix[1*4+3] = 0.0f;
  516. matrix[2*4+3] = 0.0f;
  517. matrix[3*4+0] = 0;
  518. matrix[3*4+1] = 0;
  519. matrix[3*4+2] = 0;
  520. matrix[3*4+3] = 1;
  521. }
  522. // call this AFTER setRenderState and setRenderObject
  523. void ErrorRenderLoop::setTransforms(float *M)
  524. {
  525. // transform
  526. float P[16];
  527. float V[16];
  528. float VP[16];
  529. // projection
  530. buildProjection(P, -1.0f, 1.0f, -1.0f, 1.0f, 1.0, 10000.0f);
  531. // 16:9 scale or 4:3 scale
  532. matrixTranslate(V, 0.0f, 0.0f, -4.0);
  533. V[0*4 + 0] = 1.0f / display_aspect_ratio;
  534. V[1*4 + 1] = 1.0f;
  535. // model view
  536. matrixMul(VP, P, V);
  537. matrixMul(MVP, VP, M);
  538. cellGcmSetVertexProgramParameter(model_view_projection, MVP);
  539. }
  540. int32_t ErrorRenderLoop::setRenderObject(void)
  541. {
  542. void *ret = localMemoryAlign(128, sizeof(Vertex_t) * ARRAYSIZE( g_verts_polySurfaceShape1 ) );
  543. m_pVertexBuffer = (Vertex_t*)ret;
  544. memcpy( m_pVertexBuffer, g_verts_polySurfaceShape1, sizeof( g_verts_polySurfaceShape1 ) );
  545. m_pIndexBuffer = (uint16_t *)localMemoryAlign( 128, sizeof( uint16_t ) * ARRAYSIZE( g_tris_polySurfaceShape1 ) * 3 );
  546. memcpy( m_pIndexBuffer, g_tris_polySurfaceShape1, sizeof( g_tris_polySurfaceShape1 ) );
  547. model_view_projection = cellGcmCgGetNamedParameter(vertex_program, "modelViewProj");
  548. CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(model_view_projection);
  549. CGparameter position = cellGcmCgGetNamedParameter(vertex_program, "position");
  550. CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(position);
  551. CGparameter normal = cellGcmCgGetNamedParameter(vertex_program, "normal");
  552. CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(normal);
  553. CGparameter color = cellGcmCgGetNamedParameter(vertex_program, "color");
  554. CELL_GCMUTIL_CG_PARAMETER_CHECK_ASSERT(color);
  555. // get Vertex Attribute index
  556. position_index = cellGcmCgGetParameterResource(vertex_program, position) - CG_ATTR0;
  557. normal_index = cellGcmCgGetParameterResource(vertex_program, normal) - CG_ATTR0;
  558. color_index = cellGcmCgGetParameterResource(vertex_program, color) - CG_ATTR0;
  559. // fragment program offset
  560. CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(fragment_program_ucode, &fragment_offset));
  561. CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_pVertexBuffer->x, &m_nVertPositionOffset));
  562. CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_pVertexBuffer->nx, &m_nVertNormalOffset));
  563. CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(&m_pVertexBuffer->rgba, &m_nVertColorOffset));
  564. CELL_GCMUTIL_CHECK_ASSERT(cellGcmAddressToOffset(m_pIndexBuffer, &m_nIndexBufferLocalMemoryOffset));
  565. return 0;
  566. }
  567. const uint32_t g_nInitCmdBuffer = 0x1000;
  568. int32_t SimpleContextCallback( struct CellGcmContextData *pData, uint32_t nSize )
  569. {
  570. *pData->current = CELL_GCM_JUMP( g_nInitCmdBuffer );
  571. __sync();
  572. CellGcmControl * pControlRegister = cellGcmGetControlRegister();
  573. pControlRegister->put = g_nInitCmdBuffer;
  574. do
  575. {
  576. sys_timer_usleep( 60 );
  577. } while ( pControlRegister->get != g_nInitCmdBuffer );
  578. pData->current = pData->begin;
  579. return CELL_OK;
  580. }
  581. int ErrorRenderLoop::Run( void )
  582. {
  583. // Exit routines
  584. {
  585. // register sysutil exit callback
  586. CELL_GCMUTIL_CHECK_ASSERT( cellSysutilRegisterCallback( 0, sysutil_exit_callback, this ) );
  587. CELL_GCMUTIL_CHECK_ASSERT( cellSysutilCheckCallback() );
  588. if ( !m_keepRunning )
  589. return 0;
  590. }
  591. if( g_gcmSharedData.m_pIoMemory )
  592. {
  593. // GCM has already been initialized, no need to reinitialize it.
  594. // But we have to drive RSX to our new command buffer
  595. const uint32_t nCmdBufferOverfetchSlack = 1024;
  596. //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 );
  597. cellGcmSetCurrentBuffer(
  598. // start command buffer right after initialization fixed command buffer (always the first 4 k of IO memory)
  599. ( uint32_t* )( uint32_t( g_gcmSharedData.m_pIoMemory ) + g_nInitCmdBuffer ),
  600. // the size is all of IO memory, minus initialization command buffer, minus overfetch amount in the end of command buffer to avoid a crash,
  601. // minus 4 bytes to insert a JUMP to the start of command buffer when we run out of space
  602. g_gcmSharedData.m_nIoMemorySize - nCmdBufferOverfetchSlack - g_nInitCmdBuffer - sizeof( uint32_t ) );
  603. CellGcmContextData *pCurrentContext = gCellGcmCurrentContext;
  604. pCurrentContext->callback = SimpleContextCallback;
  605. CellGcmControl * pControlRegister = cellGcmGetControlRegister();
  606. uint32_t nPut = pControlRegister->put;
  607. uint32_t * pCurrentCmd = ( uint32_t* )( uint32_t( g_gcmSharedData.m_pIoMemory ) + nPut );
  608. pCurrentContext->current = pCurrentCmd; // de facto current
  609. // #ifndef _CERT
  610. // if ( pControlRegister->put != g_nInitCmdBuffer || gCellGcmCurrentContext->current != ( uint32_t* )( uint32_t( g_gcmSharedData.m_pIoMemory ) + g_nInitCmdBuffer ) )
  611. // {
  612. // __builtin_snpause();
  613. // }
  614. // #endif
  615. }
  616. else
  617. {
  618. sys_addr_t allocatedAddress = NULL;
  619. int smaResult = sys_memory_allocate( 1 * 1024 * 1024, SYS_MEMORY_PAGE_SIZE_1M, &allocatedAddress );
  620. if( smaResult != CELL_OK )
  621. return smaResult;
  622. void* host_addr = (void*)allocatedAddress;
  623. printf( "Entering Error Render loop, IO memory @%p...\n", host_addr );
  624. CELL_GCMUTIL_ASSERT(host_addr != NULL);
  625. CELL_GCMUTIL_CHECK_ASSERT(cellGcmInit(CB_SIZE, HOST_SIZE, host_addr));
  626. }
  627. if (initDisplay()!=0) return -1;
  628. initShader();
  629. setDrawEnv();
  630. if (setRenderObject())
  631. return -1;
  632. setRenderState();
  633. // 1st time
  634. setRenderTarget(frame_index);
  635. // rendering loop
  636. CELL_GCMUTIL_ASSERT(m_keepRunning);
  637. float flTime = 0;
  638. uint32_t nFrames = 0;
  639. while (m_keepRunning) {
  640. // check system event
  641. CELL_GCMUTIL_CHECK_ASSERT( cellSysutilCheckCallback() );
  642. // clear frame buffer
  643. cellGcmSetClearSurface(
  644. CELL_GCM_CLEAR_Z |
  645. CELL_GCM_CLEAR_R |
  646. CELL_GCM_CLEAR_G |
  647. CELL_GCM_CLEAR_B |
  648. CELL_GCM_CLEAR_A
  649. );
  650. float tm[16];
  651. AngleMatrix(0.1f * sinf( flTime * 0.5f ), 0.5f * sinf( flTime * 0.45f ), 0.1f * sinf( flTime*0.02f ), tm);
  652. setTransforms(tm);
  653. // set draw command
  654. if( flTime > 4.0f )
  655. {
  656. cellGcmSetDrawIndexArray(CELL_GCM_PRIMITIVE_TRIANGLES, 3 * ARRAYSIZE( g_tris_polySurfaceShape1 ), CELL_GCM_DRAW_INDEX_ARRAY_TYPE_16, CELL_GCM_LOCATION_LOCAL, m_nIndexBufferLocalMemoryOffset );
  657. }
  658. // start reading the command buffer
  659. flip();
  660. flTime += 1/60.0f;
  661. nFrames ++;
  662. }
  663. printf( "Exiting Error Render loop, %u frames rendered", nFrames );
  664. cellSysutilUnregisterCallback( 0 );
  665. // Let RSX wait for final flip
  666. cellGcmSetWaitFlip();
  667. // Let PPU wait for all commands done (include waitFlip)
  668. cellGcmFinish(1);
  669. // let's just leak this memory to avoid problems due to initializing GCM in different places, it doesn't matter
  670. //sys_memory_free( g_gcmSharedData.m_pIoMemory );
  671. printf(".\n");
  672. return 0;
  673. }
  674. void sysutil_exit_callback(uint64_t status, uint64_t param, void* userdata)
  675. {
  676. (void) param;
  677. (void) userdata;
  678. switch(status) {
  679. case CELL_SYSUTIL_REQUEST_EXITGAME:
  680. ((ErrorRenderLoop*)userdata)->m_keepRunning = false;
  681. break;
  682. case CELL_SYSUTIL_DRAWING_BEGIN:
  683. case CELL_SYSUTIL_DRAWING_END:
  684. case CELL_SYSUTIL_SYSTEM_MENU_OPEN:
  685. case CELL_SYSUTIL_SYSTEM_MENU_CLOSE:
  686. case CELL_SYSUTIL_BGMPLAYBACK_PLAY:
  687. case CELL_SYSUTIL_BGMPLAYBACK_STOP:
  688. default:
  689. break;
  690. }
  691. }