Advertisement
Guest User

Untitled

a guest
Nov 9th, 2015
976
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.52 KB | None | 0 0
  1. /* SCE CONFIDENTIAL
  2. * PlayStation(R)Vita Programmer Tool Runtime Library Release 02.000.081
  3. * Copyright (C) 2010 Sony Computer Entertainment Inc.
  4. * All Rights Reserved.
  5. */
  6.  
  7. // All fonts relöated stuff hs been ripped out.
  8.  
  9. /*
  10.  
  11. This sample shows how to initialize libdbgfont (and libgxm),
  12. and render debug font with triangle for clear the screen.
  13.  
  14. This sample is split into the following sections:
  15.  
  16. 1. Initialize libdbgfont
  17. 2. Initialize libgxm
  18. 3. Allocate display buffers, set up the display queue
  19. 4. Create a shader patcher and register programs
  20. 5. Create the programs and data for the clear
  21. 6. Start the main loop
  22. 7. Update step
  23. 8. Rendering step
  24. 9. Flip operation and render debug font at display callback
  25. 10. Wait for rendering to complete
  26. 11. Destroy the programs and data for the clear triangle
  27. 12. Finalize libgxm
  28. 13. Finalize libdbgfont
  29.  
  30. Please refer to the individual comment blocks for details of each section.
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <stdbool.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <sceerror.h>
  38.  
  39. #include <gxm.h>
  40. #include <kernel.h>
  41. #include <ctrl.h>
  42. #include <display.h>
  43. #include <libdbg.h>
  44.  
  45. #include <libdbgfont.h>
  46.  
  47.  
  48. /* Define the debug font pixel color format to render to. */
  49. #define DBGFONT_PIXEL_FORMAT SCE_DBGFONT_PIXELFORMAT_A8B8G8R8
  50.  
  51.  
  52. /* Define the width and height to render at the native resolution */
  53. #define DISPLAY_WIDTH 960
  54. #define DISPLAY_HEIGHT 544
  55. #define DISPLAY_STRIDE_IN_PIXELS 1024
  56.  
  57. /* Define the libgxm color format to render to.
  58. This should be kept in sync with the display format to use with the SceDisplay library.
  59. */
  60. #define DISPLAY_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8
  61. #define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
  62.  
  63. /* Define the number of back buffers to use with this sample. Most applications
  64. should use a value of 2 (double buffering) or 3 (triple buffering).
  65. */
  66. #define DISPLAY_BUFFER_COUNT 3
  67.  
  68. /* Define the maximum number of queued swaps that the display queue will allow.
  69. This limits the number of frames that the CPU can get ahead of the GPU,
  70. and is independent of the actual number of back buffers. The display
  71. queue will block during sceGxmDisplayQueueAddEntry if this number of swaps
  72. have already been queued.
  73. */
  74. #define DISPLAY_MAX_PENDING_SWAPS 2
  75.  
  76.  
  77. /* Helper macro to align a value */
  78. #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
  79.  
  80.  
  81. /* The build process for the sample embeds the shader programs directly into the
  82. executable using the symbols below. This is purely for convenience, it is
  83. equivalent to simply load the binary file into memory and cast the contents
  84. to type SceGxmProgram.
  85. */
  86. extern const SceGxmProgram binaryClearVGxpStart;
  87. extern const SceGxmProgram binaryClearFGxpStart;
  88.  
  89. /* Data structure for clear geometry */
  90. typedef struct ClearVertex
  91. {
  92. float x;
  93. float y;
  94. } ClearVertex;
  95.  
  96.  
  97. // !! Data related to rendering vertex.
  98. extern const SceGxmProgram binaryBasicVGxpStart;
  99. extern const SceGxmProgram binaryBasicFGxpStart;
  100.  
  101. /* Data structure for basic geometry */
  102. typedef struct BasicVertex
  103. {
  104. float x;
  105. float y;
  106. float z;
  107. uint32_t color; // Data gets expanded to float 4 in vertex shader.
  108. } BasicVertex;
  109.  
  110. /* Data structure to pass through the display queue. This structure is
  111. serialized during sceGxmDisplayQueueAddEntry, and is used to pass
  112. arbitrary data to the display callback function, called from an internal
  113. thread once the back buffer is ready to be displayed.
  114.  
  115. In this example, we only need to pass the base address of the buffer.
  116. */
  117. typedef struct DisplayData
  118. {
  119. void *address;
  120. } DisplayData;
  121.  
  122. static SceGxmContextParams s_contextParams; /* libgxm context parameter */
  123. static SceGxmRenderTargetParams s_renderTargetParams; /* libgxm render target parameter */
  124. static SceGxmContext *s_context = NULL; /* libgxm context */
  125. static SceGxmRenderTarget *s_renderTarget = NULL; /* libgxm render target */
  126. static SceGxmShaderPatcher *s_shaderPatcher = NULL; /* libgxm shader patcher */
  127.  
  128. /* display data */
  129. static void *s_displayBufferData[ DISPLAY_BUFFER_COUNT ];
  130. static SceGxmSyncObject *s_displayBufferSync[ DISPLAY_BUFFER_COUNT ];
  131. static int32_t s_displayBufferUId[ DISPLAY_BUFFER_COUNT ];
  132. static SceGxmColorSurface s_displaySurface[ DISPLAY_BUFFER_COUNT ];
  133. static uint32_t s_displayFrontBufferIndex = 0;
  134. static uint32_t s_displayBackBufferIndex = 0;
  135. static SceGxmDepthStencilSurface s_depthSurface;
  136.  
  137. /* shader data */
  138. static int32_t s_clearVerticesUId;
  139. static int32_t s_clearIndicesUId;
  140. static SceGxmShaderPatcherId s_clearVertexProgramId;
  141. static SceGxmShaderPatcherId s_clearFragmentProgramId;
  142. // !! Shader pactcher addded.
  143. static SceGxmShaderPatcherId s_basicVertexProgramId;
  144. static SceGxmShaderPatcherId s_basicFragmentProgramId;
  145. static SceUID s_patcherFragmentUsseUId;
  146. static SceUID s_patcherVertexUsseUId;
  147. static SceUID s_patcherBufferUId;
  148. static SceUID s_depthBufferUId;
  149. static SceUID s_vdmRingBufferUId;
  150. static SceUID s_vertexRingBufferUId;
  151. static SceUID s_fragmentRingBufferUId;
  152. static SceUID s_fragmentUsseRingBufferUId;
  153. static ClearVertex *s_clearVertices = NULL;
  154. static uint16_t *s_clearIndices = NULL;
  155. static SceGxmVertexProgram *s_clearVertexProgram = NULL;
  156. static SceGxmFragmentProgram *s_clearFragmentProgram = NULL;
  157. // !! Data added.
  158. static SceGxmVertexProgram *s_basicVertexProgram = NULL;
  159. static SceGxmFragmentProgram *s_basicFragmentProgram = NULL;
  160. static BasicVertex *s_basicVertices = NULL;
  161. static uint16_t *s_basicIndices = NULL;
  162. static int32_t s_basicVerticesUId;
  163. static int32_t s_basicIndiceUId;
  164.  
  165.  
  166. //!! The program parameter for the transformation of the triangle
  167. static float s_wvpData[16];
  168. static const SceGxmProgramParameter *s_wvpParam = NULL;
  169.  
  170.  
  171.  
  172. /* Callback function to allocate memory for the shader patcher */
  173. static void *patcherHostAlloc( void *userData, uint32_t size );
  174.  
  175. /* Callback function to allocate memory for the shader patcher */
  176. static void patcherHostFree( void *userData, void *mem );
  177.  
  178. /* Callback function for displaying a buffer */
  179. static void displayCallback( const void *callbackData );
  180.  
  181. /* Helper function to allocate memory and map it for the GPU */
  182. static void *graphicsAlloc( SceKernelMemBlockType type, uint32_t size, uint32_t alignment, uint32_t attribs, SceUID *uid );
  183.  
  184. /* Helper function to free memory mapped to the GPU */
  185. static void graphicsFree( SceUID uid );
  186.  
  187. /* Helper function to allocate memory and map it as vertex USSE code for the GPU */
  188. static void *vertexUsseAlloc( uint32_t size, SceUID *uid, uint32_t *usseOffset );
  189.  
  190. /* Helper function to free memory mapped as vertex USSE code for the GPU */
  191. static void vertexUsseFree( SceUID uid );
  192.  
  193. /* Helper function to allocate memory and map it as fragment USSE code for the GPU */
  194. static void *fragmentUsseAlloc( uint32_t size, SceUID *uid, uint32_t *usseOffset );
  195.  
  196. /* Helper function to free memory mapped as fragment USSE code for the GPU */
  197. static void fragmentUsseFree( SceUID uid );
  198.  
  199.  
  200. /* @brief Main entry point for the application
  201. @return Error code result of processing during execution: <c> SCE_OK </c> on success,
  202. or another code depending upon the error
  203. */
  204. int main( void );
  205.  
  206.  
  207. // !! Here we create the matrix.
  208. void Update(void);
  209.  
  210.  
  211.  
  212. /* @brief Initializes the graphics services and the libgxm graphics library
  213. @return Error code result of processing during execution: <c> SCE_OK </c> on success,
  214. or another code depending upon the error
  215. */
  216. static int initGxm( void );
  217.  
  218. /* @brief Creates scenes with libgxm */
  219. static void createGxmData( void );
  220.  
  221.  
  222. /* @brief Main rendering function to draw graphics to the display */
  223. static void render( void );
  224.  
  225. /* @brief render libgxm scenes */
  226. static void renderGxm( void );
  227.  
  228.  
  229.  
  230. /* @brief cycle display buffer */
  231. static void cycleDisplayBuffers( void );
  232.  
  233. /* @brief Destroy scenes with libgxm */
  234. static void destroyGxmData( void );
  235.  
  236.  
  237.  
  238.  
  239. /* @brief Function to shut down libgxm and the graphics display services
  240. @return Error code result of processing during execution: <c> SCE_OK </c> on success,
  241. or another code depending upon the error
  242. */
  243. static int shutdownGxm( void );
  244.  
  245.  
  246.  
  247. /* @brief User main thread parameters */
  248. extern const char sceUserMainThreadName[] = "simple_main_thr";
  249. extern const int sceUserMainThreadPriority = SCE_KERNEL_DEFAULT_PRIORITY_USER;
  250. extern const unsigned int sceUserMainThreadStackSize = SCE_KERNEL_STACK_SIZE_DEFAULT_USER_MAIN;
  251.  
  252. /* @brief libc parameters */
  253. unsigned int sceLibcHeapSize = 1*1024*1024;
  254.  
  255. //JOYSTICKCODE
  256. #include <iostream>
  257. #include <kernel.h>
  258. #include <string>
  259. #include <ctrl.h>
  260. #include <scebase.h>
  261.  
  262.  
  263. #include <math.h>
  264.  
  265. /* Main entry point of program */
  266. int main( void )
  267. {
  268. int returnCode = SCE_OK;
  269.  
  270. /* initialize libdbgfont and libgxm */
  271. returnCode =initGxm();
  272. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  273.  
  274. SceDbgFontConfig config;
  275. memset( &config, 0, sizeof(SceDbgFontConfig) );
  276. config.fontSize = SCE_DBGFONT_FONTSIZE_LARGE;
  277.  
  278. returnCode = sceDbgFontInit( &config );
  279. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  280.  
  281. /* Message for SDK sample auto test */
  282. printf( "## simple: INIT SUCCEEDED ##\n" );
  283.  
  284. /* create gxm graphics data */
  285. createGxmData();
  286.  
  287.  
  288. //JOYSTICKCODE
  289.  
  290. sceCtrlSetSamplingMode(SCE_CTRL_MODE_DIGITALANALOG_WIDE);
  291. SceCtrlData cd;
  292. bool going = true;
  293. bool wasXPressed = false;
  294. float angle = 0.f;
  295. /* 6. main loop */
  296. while ( going)
  297. {
  298.  
  299. sceCtrlReadBufferPositive(0, &cd, 1);
  300. SceUInt32 pressedButtons = cd.buttons;
  301. if(pressedButtons & SCE_CTRL_START)
  302. going = false;
  303. if(pressedButtons & SCE_CTRL_CROSS){// && !wasXPressed){
  304. //cout << ((float)cd.lx /255.0f)*2.f - 1.0 << " " <<((float)cd.ly /255.0f)*2.f - 1.0 << endl;
  305. angle += (((float)cd.lx /255.0f)*2.f - 1.f)*0.1f;
  306.  
  307. wasXPressed = true;
  308. }
  309. else if(!(pressedButtons & SCE_CTRL_CROSS)){
  310. wasXPressed = false;
  311. }
  312.  
  313.  
  314. float aspectRatio = (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT;
  315. s_wvpData[ 0] = cosf(angle) / aspectRatio;
  316. s_wvpData[ 1] = -sinf(angle);
  317. s_wvpData[ 2] = 0.0f;
  318. s_wvpData[ 3] = 0.0f;
  319.  
  320. s_wvpData[ 4] = sinf(angle)/aspectRatio;
  321. s_wvpData[ 5] = cosf(angle);
  322. s_wvpData[ 6] = 0.0f;
  323. s_wvpData[ 7] = 0.0f;
  324.  
  325. Update();
  326. render();
  327. sceDbgFontPrint( 20, 20, 0xffffffff, "Hello World" );
  328. cycleDisplayBuffers();
  329. }
  330.  
  331.  
  332. /*
  333. // 10. wait until rendering is done
  334. sceGxmFinish( s_context );
  335.  
  336. // destroy gxm graphics data
  337. destroyGxmData();
  338.  
  339. // shutdown libdbgfont and libgxm
  340. returnCode = shutdownGxm();
  341. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  342.  
  343. // Message for SDK sample auto test
  344. printf( "## api_libdbgfont/simple: FINISHED ##\n" );
  345.  
  346. return returnCode;
  347. */
  348. }
  349.  
  350.  
  351.  
  352. void Update (void)
  353. {
  354. // We go from -1 to 1 in rendering.
  355. //float aspectRatio = (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT;
  356.  
  357.  
  358.  
  359. s_wvpData[ 8] = 0.0f;
  360. s_wvpData[ 9] = 0.0f;
  361. s_wvpData[10] = 1.0f;
  362. s_wvpData[11] = 0.0f;
  363.  
  364. s_wvpData[12] = 0.0f;
  365. s_wvpData[13] = 0.0f;
  366. s_wvpData[14] = 0.0f;
  367. s_wvpData[15] = 1.0f;
  368. };
  369.  
  370.  
  371. /* Initialize libgxm */
  372. int initGxm( void )
  373. {
  374. /* ---------------------------------------------------------------------
  375. 2. Initialize libgxm
  376.  
  377. First we must initialize the libgxm library by calling sceGxmInitialize.
  378. The single argument to this function is the size of the parameter buffer to
  379. allocate for the GPU. We will use the default 16MiB here.
  380.  
  381. Once initialized, we need to create a rendering context to allow to us
  382. to render scenes on the GPU. We use the default initialization
  383. parameters here to set the sizes of the various context ring buffers.
  384.  
  385. Finally we create a render target to describe the geometry of the back
  386. buffers we will render to. This object is used purely to schedule
  387. rendering jobs for the given dimensions, the color surface and
  388. depth/stencil surface must be allocated separately.
  389. --------------------------------------------------------------------- */
  390.  
  391. int returnCode = SCE_OK;
  392.  
  393. /* set up parameters */
  394. SceGxmInitializeParams initializeParams;
  395. memset( &initializeParams, 0, sizeof(SceGxmInitializeParams) );
  396. initializeParams.flags = 0;
  397. initializeParams.displayQueueMaxPendingCount = DISPLAY_MAX_PENDING_SWAPS;
  398. initializeParams.displayQueueCallback = displayCallback;
  399. initializeParams.displayQueueCallbackDataSize = sizeof(DisplayData);
  400. initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE;
  401.  
  402. /* start libgxm */
  403. returnCode = sceGxmInitialize( &initializeParams );
  404. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  405.  
  406. /* allocate ring buffer memory using default sizes */
  407. void *vdmRingBuffer = graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, &s_vdmRingBufferUId );
  408.  
  409. void *vertexRingBuffer = graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, &s_vertexRingBufferUId );
  410.  
  411. void *fragmentRingBuffer = graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, 4, SCE_GXM_MEMORY_ATTRIB_READ, &s_fragmentRingBufferUId );
  412.  
  413. uint32_t fragmentUsseRingBufferOffset;
  414. void *fragmentUsseRingBuffer = fragmentUsseAlloc( SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE, &s_fragmentUsseRingBufferUId, &fragmentUsseRingBufferOffset );
  415.  
  416. /* create a rendering context */
  417. memset( &s_contextParams, 0, sizeof(SceGxmContextParams) );
  418. s_contextParams.hostMem = malloc( SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE );
  419. s_contextParams.hostMemSize = SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE;
  420. s_contextParams.vdmRingBufferMem = vdmRingBuffer;
  421. s_contextParams.vdmRingBufferMemSize = SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE;
  422. s_contextParams.vertexRingBufferMem = vertexRingBuffer;
  423. s_contextParams.vertexRingBufferMemSize = SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE;
  424. s_contextParams.fragmentRingBufferMem = fragmentRingBuffer;
  425. s_contextParams.fragmentRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE;
  426. s_contextParams.fragmentUsseRingBufferMem = fragmentUsseRingBuffer;
  427. s_contextParams.fragmentUsseRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE;
  428. s_contextParams.fragmentUsseRingBufferOffset = fragmentUsseRingBufferOffset;
  429. returnCode = sceGxmCreateContext( &s_contextParams, &s_context );
  430. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  431.  
  432. /* set buffer sizes for this sample */
  433. const uint32_t patcherBufferSize = 64*1024;
  434. const uint32_t patcherVertexUsseSize = 64*1024;
  435. const uint32_t patcherFragmentUsseSize = 64*1024;
  436.  
  437. /* allocate memory for buffers and USSE code */
  438. void *patcherBuffer = graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, patcherBufferSize, 4, SCE_GXM_MEMORY_ATTRIB_WRITE|SCE_GXM_MEMORY_ATTRIB_WRITE, &s_patcherBufferUId );
  439.  
  440. uint32_t patcherVertexUsseOffset;
  441. void *patcherVertexUsse = vertexUsseAlloc( patcherVertexUsseSize, &s_patcherVertexUsseUId, &patcherVertexUsseOffset );
  442.  
  443. uint32_t patcherFragmentUsseOffset;
  444. void *patcherFragmentUsse = fragmentUsseAlloc( patcherFragmentUsseSize, &s_patcherFragmentUsseUId, &patcherFragmentUsseOffset );
  445.  
  446. /* create a shader patcher */
  447. SceGxmShaderPatcherParams patcherParams;
  448. memset( &patcherParams, 0, sizeof(SceGxmShaderPatcherParams) );
  449. patcherParams.userData = NULL;
  450. patcherParams.hostAllocCallback = &patcherHostAlloc;
  451. patcherParams.hostFreeCallback = &patcherHostFree;
  452. patcherParams.bufferAllocCallback = NULL;
  453. patcherParams.bufferFreeCallback = NULL;
  454. patcherParams.bufferMem = patcherBuffer;
  455. patcherParams.bufferMemSize = patcherBufferSize;
  456. patcherParams.vertexUsseAllocCallback = NULL;
  457. patcherParams.vertexUsseFreeCallback = NULL;
  458. patcherParams.vertexUsseMem = patcherVertexUsse;
  459. patcherParams.vertexUsseMemSize = patcherVertexUsseSize;
  460. patcherParams.vertexUsseOffset = patcherVertexUsseOffset;
  461. patcherParams.fragmentUsseAllocCallback = NULL;
  462. patcherParams.fragmentUsseFreeCallback = NULL;
  463. patcherParams.fragmentUsseMem = patcherFragmentUsse;
  464. patcherParams.fragmentUsseMemSize = patcherFragmentUsseSize;
  465. patcherParams.fragmentUsseOffset = patcherFragmentUsseOffset;
  466. returnCode = sceGxmShaderPatcherCreate( &patcherParams, &s_shaderPatcher );
  467. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  468.  
  469. /* create a render target */
  470. memset( &s_renderTargetParams, 0, sizeof(SceGxmRenderTargetParams) );
  471. s_renderTargetParams.flags = 0;
  472. s_renderTargetParams.width = DISPLAY_WIDTH;
  473. s_renderTargetParams.height = DISPLAY_HEIGHT;
  474. s_renderTargetParams.scenesPerFrame = 1;
  475. s_renderTargetParams.multisampleMode = SCE_GXM_MULTISAMPLE_NONE;
  476. s_renderTargetParams.multisampleLocations = 0;
  477. s_renderTargetParams.driverMemBlock = SCE_UID_INVALID_UID;
  478.  
  479. returnCode = sceGxmCreateRenderTarget( &s_renderTargetParams, &s_renderTarget );
  480. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  481.  
  482.  
  483. /* ---------------------------------------------------------------------
  484. 3. Allocate display buffers, set up the display queue
  485.  
  486. We will allocate our back buffers in CDRAM, and create a color
  487. surface for each of them.
  488.  
  489. To allow display operations done by the CPU to be synchronized with
  490. rendering done by the GPU, we also create a SceGxmSyncObject for each
  491. display buffer. This sync object will be used with each scene that
  492. renders to that buffer and when queueing display flips that involve
  493. that buffer (either flipping from or to).
  494.  
  495. Finally we create a display queue object that points to our callback
  496. function.
  497. --------------------------------------------------------------------- */
  498.  
  499. /* allocate memory and sync objects for display buffers */
  500. for ( unsigned int i = 0 ; i < DISPLAY_BUFFER_COUNT ; ++i )
  501. {
  502. /* allocate memory with large size to ensure physical contiguity */
  503. s_displayBufferData[i] = graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RWDATA, ALIGN(4*DISPLAY_STRIDE_IN_PIXELS*DISPLAY_HEIGHT, 1*1024*1024), SCE_GXM_COLOR_SURFACE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ|SCE_GXM_MEMORY_ATTRIB_WRITE, &s_displayBufferUId[i] );
  504. SCE_DBG_ALWAYS_ASSERT( s_displayBufferData[i] );
  505.  
  506. /* memset the buffer to debug color */
  507. for ( unsigned int y = 0 ; y < DISPLAY_HEIGHT ; ++y )
  508. {
  509. unsigned int *row = (unsigned int *)s_displayBufferData[i] + y*DISPLAY_STRIDE_IN_PIXELS;
  510.  
  511. for ( unsigned int x = 0 ; x < DISPLAY_WIDTH ; ++x )
  512. {
  513. row[x] = 0x0;
  514. }
  515. }
  516.  
  517. /* initialize a color surface for this display buffer */
  518. returnCode = sceGxmColorSurfaceInit( &s_displaySurface[i], DISPLAY_COLOR_FORMAT, SCE_GXM_COLOR_SURFACE_LINEAR, SCE_GXM_COLOR_SURFACE_SCALE_NONE,
  519. SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_STRIDE_IN_PIXELS, s_displayBufferData[i] );
  520. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  521.  
  522. /* create a sync object that we will associate with this buffer */
  523. returnCode = sceGxmSyncObjectCreate( &s_displayBufferSync[i] );
  524. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  525. }
  526.  
  527. /* compute the memory footprint of the depth buffer */
  528. const uint32_t alignedWidth = ALIGN( DISPLAY_WIDTH, SCE_GXM_TILE_SIZEX );
  529. const uint32_t alignedHeight = ALIGN( DISPLAY_HEIGHT, SCE_GXM_TILE_SIZEY );
  530. uint32_t sampleCount = alignedWidth*alignedHeight;
  531. uint32_t depthStrideInSamples = alignedWidth;
  532.  
  533. /* allocate it */
  534. void *depthBufferData = graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, 4*sampleCount, SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ|SCE_GXM_MEMORY_ATTRIB_WRITE, &s_depthBufferUId );
  535.  
  536. /* create the SceGxmDepthStencilSurface structure */
  537. returnCode = sceGxmDepthStencilSurfaceInit( &s_depthSurface, SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24, SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, depthStrideInSamples, depthBufferData, NULL );
  538. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  539.  
  540. return returnCode;
  541. }
  542.  
  543. /* Create libgxm scenes */
  544. void createGxmData( void )
  545. {
  546. /* ---------------------------------------------------------------------
  547. 4. Create a shader patcher and register programs
  548.  
  549. A shader patcher object is required to produce vertex and fragment
  550. programs from the shader compiler output. First we create a shader
  551. patcher instance, using callback functions to allow it to allocate
  552. and free host memory for internal state.
  553.  
  554. In order to create vertex and fragment programs for a particular
  555. shader, the compiler output must first be registered to obtain an ID
  556. for that shader. Within a single ID, vertex and fragment programs
  557. are reference counted and could be shared if created with identical
  558. parameters. To maximise this sharing, programs should only be
  559. registered with the shader patcher once if possible, so we will do
  560. this now.
  561. --------------------------------------------------------------------- */
  562.  
  563. /* register programs with the patcher */
  564. int returnCode = sceGxmShaderPatcherRegisterProgram( s_shaderPatcher, &binaryClearVGxpStart, &s_clearVertexProgramId );
  565. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  566. returnCode = sceGxmShaderPatcherRegisterProgram( s_shaderPatcher, &binaryClearFGxpStart, &s_clearFragmentProgramId );
  567. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  568.  
  569.  
  570. returnCode = sceGxmShaderPatcherRegisterProgram( s_shaderPatcher, &binaryBasicVGxpStart, &s_basicVertexProgramId );
  571. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  572. returnCode = sceGxmShaderPatcherRegisterProgram( s_shaderPatcher, &binaryBasicFGxpStart, &s_basicFragmentProgramId );
  573. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  574.  
  575.  
  576. /* ---------------------------------------------------------------------
  577. 5. Create the programs and data for the clear
  578.  
  579. On SGX hardware, vertex programs must perform the unpack operations
  580. on vertex data, so we must define our vertex formats in order to
  581. create the vertex program. Similarly, fragment programs must be
  582. specialized based on how they output their pixels and MSAA mode
  583. (and texture format on ES1).
  584.  
  585. We define the clear geometry vertex format here and create the vertex
  586. and fragment program.
  587.  
  588. The clear vertex and index data is static, we allocate and write the
  589. data here.
  590. --------------------------------------------------------------------- */
  591.  
  592. /* get attributes by name to create vertex format bindings */
  593. const SceGxmProgram *clearProgram = sceGxmShaderPatcherGetProgramFromId( s_clearVertexProgramId );
  594. SCE_DBG_ALWAYS_ASSERT( clearProgram );
  595. const SceGxmProgramParameter *paramClearPositionAttribute = sceGxmProgramFindParameterByName( clearProgram, "aPosition" );
  596. SCE_DBG_ALWAYS_ASSERT( paramClearPositionAttribute && ( sceGxmProgramParameterGetCategory(paramClearPositionAttribute) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE ) );
  597.  
  598. /* create clear vertex format */
  599. SceGxmVertexAttribute clearVertexAttributes[1];
  600. SceGxmVertexStream clearVertexStreams[1];
  601. clearVertexAttributes[0].streamIndex = 0;
  602. clearVertexAttributes[0].offset = 0;
  603. clearVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
  604. clearVertexAttributes[0].componentCount = 2;
  605. clearVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex( paramClearPositionAttribute );
  606. clearVertexStreams[0].stride = sizeof(ClearVertex);
  607. clearVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
  608.  
  609. /* create clear programs */
  610. returnCode = sceGxmShaderPatcherCreateVertexProgram( s_shaderPatcher, s_clearVertexProgramId, clearVertexAttributes, 1, clearVertexStreams, 1, &s_clearVertexProgram );
  611. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  612.  
  613. returnCode = sceGxmShaderPatcherCreateFragmentProgram( s_shaderPatcher, s_clearFragmentProgramId,
  614. SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, NULL,
  615. sceGxmShaderPatcherGetProgramFromId(s_clearVertexProgramId), &s_clearFragmentProgram );
  616. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  617.  
  618. /* create the clear triangle vertex/index data */
  619. s_clearVertices = (ClearVertex *)graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, 3*sizeof(ClearVertex), 4, SCE_GXM_MEMORY_ATTRIB_READ, &s_clearVerticesUId );
  620. s_clearIndices = (uint16_t *)graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, 3*sizeof(uint16_t), 2, SCE_GXM_MEMORY_ATTRIB_READ, &s_clearIndicesUId );
  621.  
  622. s_clearVertices[0].x = -1.0f;
  623. s_clearVertices[0].y = -1.0f;
  624. s_clearVertices[1].x = 3.0f;
  625. s_clearVertices[1].y = -1.0f;
  626. s_clearVertices[2].x = -1.0f;
  627. s_clearVertices[2].y = 3.0f;
  628.  
  629. s_clearIndices[0] = 0;
  630. s_clearIndices[1] = 1;
  631. s_clearIndices[2] = 2;
  632.  
  633. // !! All related to triangle.
  634.  
  635. /* get attributes by name to create vertex format bindings */
  636. /* first retrieve the underlying program to extract binding information */
  637. const SceGxmProgram *basicProgram = sceGxmShaderPatcherGetProgramFromId( s_basicVertexProgramId );
  638. SCE_DBG_ALWAYS_ASSERT( basicProgram );
  639. const SceGxmProgramParameter *paramBasicPositionAttribute = sceGxmProgramFindParameterByName( basicProgram, "aPosition" );
  640. SCE_DBG_ALWAYS_ASSERT( paramBasicPositionAttribute && ( sceGxmProgramParameterGetCategory(paramBasicPositionAttribute) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE ) );
  641. const SceGxmProgramParameter *paramBasicColorAttribute = sceGxmProgramFindParameterByName( basicProgram, "aColor" );
  642. SCE_DBG_ALWAYS_ASSERT( paramBasicColorAttribute && ( sceGxmProgramParameterGetCategory(paramBasicColorAttribute) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE ) );
  643.  
  644. /* create shaded triangle vertex format */
  645. SceGxmVertexAttribute basicVertexAttributes[2];
  646. SceGxmVertexStream basicVertexStreams[1];
  647. basicVertexAttributes[0].streamIndex = 0;
  648. basicVertexAttributes[0].offset = 0;
  649. basicVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
  650. basicVertexAttributes[0].componentCount = 3;
  651. basicVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex( paramBasicPositionAttribute );
  652. basicVertexAttributes[1].streamIndex = 0;
  653. basicVertexAttributes[1].offset = 12;
  654. basicVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N; // Mapping relation clarified.
  655. basicVertexAttributes[1].componentCount = 4;
  656. basicVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex( paramBasicColorAttribute );
  657. basicVertexStreams[0].stride = sizeof(BasicVertex);
  658. basicVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
  659.  
  660. /* create shaded triangle shaders */
  661. returnCode = sceGxmShaderPatcherCreateVertexProgram( s_shaderPatcher, s_basicVertexProgramId, basicVertexAttributes, 2,
  662. basicVertexStreams, 1, &s_basicVertexProgram );
  663. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  664.  
  665. returnCode = sceGxmShaderPatcherCreateFragmentProgram( s_shaderPatcher, s_basicFragmentProgramId,
  666. SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_MULTISAMPLE_NONE, NULL,
  667. sceGxmShaderPatcherGetProgramFromId(s_basicVertexProgramId), &s_basicFragmentProgram );
  668. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  669.  
  670. /* find vertex uniforms by name and cache parameter information */
  671. s_wvpParam = sceGxmProgramFindParameterByName( basicProgram, "wvp" );
  672. SCE_DBG_ALWAYS_ASSERT( s_wvpParam && ( sceGxmProgramParameterGetCategory( s_wvpParam ) == SCE_GXM_PARAMETER_CATEGORY_UNIFORM ) );
  673.  
  674. /* create shaded triangle vertex/index data */
  675. s_basicVertices = (BasicVertex *)graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, 3*sizeof(BasicVertex), 4, SCE_GXM_MEMORY_ATTRIB_READ, &s_basicVerticesUId );
  676. s_basicIndices = (uint16_t *)graphicsAlloc( SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, 3*sizeof(uint16_t), 2, SCE_GXM_MEMORY_ATTRIB_READ, &s_basicIndiceUId );
  677.  
  678. s_basicVertices[0].x = -0.5f;
  679. s_basicVertices[0].y = -0.5f;
  680. s_basicVertices[0].z = 0.0f;
  681. s_basicVertices[0].color = 0xff0000ff;
  682. s_basicVertices[1].x = 0.5f;
  683. s_basicVertices[1].y = -0.5f;
  684. s_basicVertices[1].z = 0.0f;
  685. s_basicVertices[1].color = 0xff00ff00;
  686. s_basicVertices[2].x = -0.5f;
  687. s_basicVertices[2].y = 0.5f;
  688. s_basicVertices[2].z = 0.0f;
  689. s_basicVertices[2].color = 0xffff0000;
  690.  
  691. s_basicIndices[0] = 0;
  692. s_basicIndices[1] = 1;
  693. s_basicIndices[2] = 2;
  694. }
  695.  
  696.  
  697.  
  698.  
  699. /* Main render function */
  700. void render( void )
  701. {
  702. /* render libgxm scenes */
  703. renderGxm();
  704. }
  705.  
  706. /* render gxm scenes */
  707. void renderGxm( void )
  708. {
  709. /* -----------------------------------------------------------------
  710. 8. Rendering step
  711.  
  712. This sample renders a single scene containing the clear triangle.
  713. Before any drawing can take place, a scene must be started.
  714. We render to the back buffer, so it is also important to use a
  715. sync object to ensure that these rendering operations are
  716. synchronized with display operations.
  717.  
  718. The clear triangle shaders do not declare any uniform variables,
  719. so this may be rendered immediately after setting the vertex and
  720. fragment program.
  721.  
  722. Once clear triangle have been drawn the scene can be ended, which
  723. submits it for rendering on the GPU.
  724. ----------------------------------------------------------------- */
  725.  
  726. /* start rendering to the render target */
  727. sceGxmBeginScene( s_context, 0, s_renderTarget, NULL, NULL, s_displayBufferSync[s_displayBackBufferIndex], &s_displaySurface[s_displayBackBufferIndex], &s_depthSurface );
  728.  
  729. /* set clear shaders */
  730. sceGxmSetVertexProgram( s_context, s_clearVertexProgram );
  731. sceGxmSetFragmentProgram( s_context, s_clearFragmentProgram );
  732.  
  733. /* draw ther clear triangle */
  734. sceGxmSetVertexStream( s_context, 0, s_clearVertices );
  735. sceGxmDraw( s_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, s_clearIndices, 3 );
  736.  
  737.  
  738. // !! Speciality for rendering a triangle.
  739.  
  740. /* render the triangle */
  741. sceGxmSetVertexProgram( s_context, s_basicVertexProgram );
  742. sceGxmSetFragmentProgram( s_context, s_basicFragmentProgram );
  743.  
  744. /* set the vertex program constants */
  745. void *vertexDefaultBuffer;
  746. sceGxmReserveVertexDefaultUniformBuffer( s_context, &vertexDefaultBuffer );
  747. sceGxmSetUniformDataF( vertexDefaultBuffer, s_wvpParam, 0, 16, s_wvpData );
  748.  
  749. /* draw the spinning triangle */
  750. sceGxmSetVertexStream( s_context, 0, s_basicVertices );
  751. sceGxmDraw( s_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, s_basicIndices, 3 );
  752.  
  753. /* stop rendering to the render target */
  754. sceGxmEndScene( s_context, NULL, NULL );
  755. }
  756.  
  757.  
  758.  
  759. /* queue a display swap and cycle our buffers */
  760. void cycleDisplayBuffers( void )
  761. {
  762. /* -----------------------------------------------------------------
  763. 9-a. Flip operation
  764.  
  765. Now we have finished submitting rendering work for this frame it
  766. is time to submit a flip operation. As part of specifying this
  767. flip operation we must provide the sync objects for both the old
  768. buffer and the new buffer. This is to allow synchronization both
  769. ways: to not flip until rendering is complete, but also to ensure
  770. that future rendering to these buffers does not start until the
  771. flip operation is complete.
  772.  
  773. Once we have queued our flip, we manually cycle through our back
  774. buffers before starting the next frame.
  775. ----------------------------------------------------------------- */
  776.  
  777. /* PA heartbeat to notify end of frame */
  778. sceGxmPadHeartbeat( &s_displaySurface[s_displayBackBufferIndex], s_displayBufferSync[s_displayBackBufferIndex] );
  779.  
  780. /* queue the display swap for this frame */
  781. DisplayData displayData;
  782. displayData.address = s_displayBufferData[s_displayBackBufferIndex];
  783.  
  784. /* front buffer is OLD buffer, back buffer is NEW buffer */
  785. sceGxmDisplayQueueAddEntry( s_displayBufferSync[s_displayFrontBufferIndex], s_displayBufferSync[s_displayBackBufferIndex], &displayData );
  786.  
  787. /* update buffer indices */
  788. s_displayFrontBufferIndex = s_displayBackBufferIndex;
  789. s_displayBackBufferIndex = (s_displayBackBufferIndex + 1) % DISPLAY_BUFFER_COUNT;
  790. }
  791.  
  792.  
  793. /* Destroy Gxm Data */
  794. void destroyGxmData( void )
  795. {
  796. /* ---------------------------------------------------------------------
  797. 11. Destroy the programs and data for the clear and spinning triangle
  798.  
  799. Once the GPU is finished, we release all our programs.
  800. --------------------------------------------------------------------- */
  801.  
  802. /* clean up allocations */
  803. sceGxmShaderPatcherReleaseFragmentProgram( s_shaderPatcher, s_clearFragmentProgram );
  804. sceGxmShaderPatcherReleaseVertexProgram( s_shaderPatcher, s_clearVertexProgram );
  805. graphicsFree( s_clearIndicesUId );
  806. graphicsFree( s_clearVerticesUId );
  807.  
  808. /* wait until display queue is finished before deallocating display buffers */
  809. sceGxmDisplayQueueFinish();
  810.  
  811. /* unregister programs and destroy shader patcher */
  812. sceGxmShaderPatcherUnregisterProgram( s_shaderPatcher, s_clearFragmentProgramId );
  813. sceGxmShaderPatcherUnregisterProgram( s_shaderPatcher, s_clearVertexProgramId );
  814. sceGxmShaderPatcherDestroy( s_shaderPatcher );
  815. fragmentUsseFree( s_patcherFragmentUsseUId );
  816. vertexUsseFree( s_patcherVertexUsseUId );
  817. graphicsFree( s_patcherBufferUId );
  818. }
  819.  
  820.  
  821.  
  822. /* ShutDown libgxm */
  823. int shutdownGxm( void )
  824. {
  825. /* ---------------------------------------------------------------------
  826. 12. Finalize libgxm
  827.  
  828. Once the GPU is finished, we deallocate all our memory,
  829. destroy all object and finally terminate libgxm.
  830. --------------------------------------------------------------------- */
  831.  
  832. int returnCode = SCE_OK;
  833.  
  834. graphicsFree( s_depthBufferUId );
  835.  
  836. for ( unsigned int i = 0 ; i < DISPLAY_BUFFER_COUNT; ++i )
  837. {
  838. memset( s_displayBufferData[i], 0, DISPLAY_HEIGHT*DISPLAY_STRIDE_IN_PIXELS*4 );
  839. graphicsFree( s_displayBufferUId[i] );
  840. sceGxmSyncObjectDestroy( s_displayBufferSync[i] );
  841. }
  842.  
  843. /* destroy the render target */
  844. sceGxmDestroyRenderTarget( s_renderTarget );
  845.  
  846. /* destroy the context */
  847. sceGxmDestroyContext( s_context );
  848.  
  849. fragmentUsseFree( s_fragmentUsseRingBufferUId );
  850. graphicsFree( s_fragmentRingBufferUId );
  851. graphicsFree( s_vertexRingBufferUId );
  852. graphicsFree( s_vdmRingBufferUId );
  853. free( s_contextParams.hostMem );
  854.  
  855. /* terminate libgxm */
  856. sceGxmTerminate();
  857.  
  858. return returnCode;
  859. }
  860.  
  861.  
  862. /* Host alloc */
  863. static void *patcherHostAlloc( void *userData, unsigned int size )
  864. {
  865. (void)( userData );
  866.  
  867. return malloc( size );
  868. }
  869.  
  870. /* Host free */
  871. static void patcherHostFree( void *userData, void *mem )
  872. {
  873. (void)( userData );
  874.  
  875. free( mem );
  876. }
  877.  
  878. /* Display callback */
  879. void displayCallback( const void *callbackData )
  880. {
  881. /* -----------------------------------------------------------------
  882. 10-b. Flip operation
  883.  
  884. The callback function will be called from an internal thread once
  885. queued GPU operations involving the sync objects is complete.
  886. Assuming we have not reached our maximum number of queued frames,
  887. this function returns immediately.
  888. ----------------------------------------------------------------- */
  889.  
  890. SceDisplayFrameBuf framebuf;
  891.  
  892. /* cast the parameters back */
  893. const DisplayData *displayData = (const DisplayData *)callbackData;
  894.  
  895.  
  896. // Render debug text.
  897. /* set framebuffer info */
  898. SceDbgFontFrameBufInfo info;
  899. memset( &info, 0, sizeof(SceDbgFontFrameBufInfo) );
  900. info.frameBufAddr = (SceUChar8 *)displayData->address;
  901. info.frameBufPitch = DISPLAY_STRIDE_IN_PIXELS;
  902. info.frameBufWidth = DISPLAY_WIDTH;
  903. info.frameBufHeight = DISPLAY_HEIGHT;
  904. info.frameBufPixelformat = DBGFONT_PIXEL_FORMAT;
  905.  
  906. /* flush font buffer */
  907. int returnCode = sceDbgFontFlush( &info );
  908. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  909.  
  910.  
  911. /* wwap to the new buffer on the next VSYNC */
  912. memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf));
  913. framebuf.size = sizeof(SceDisplayFrameBuf);
  914. framebuf.base = displayData->address;
  915. framebuf.pitch = DISPLAY_STRIDE_IN_PIXELS;
  916. framebuf.pixelformat = DISPLAY_PIXEL_FORMAT;
  917. framebuf.width = DISPLAY_WIDTH;
  918. framebuf.height = DISPLAY_HEIGHT;
  919. returnCode = sceDisplaySetFrameBuf( &framebuf, SCE_DISPLAY_UPDATETIMING_NEXTVSYNC );
  920. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  921.  
  922. /* block this callback until the swap has occurred and the old buffer is no longer displayed */
  923. returnCode = sceDisplayWaitVblankStart();
  924. SCE_DBG_ALWAYS_ASSERT( returnCode == SCE_OK );
  925. }
  926.  
  927. /* Alloc used by libgxm */
  928. static void *graphicsAlloc( SceKernelMemBlockType type, uint32_t size, uint32_t alignment, uint32_t attribs, SceUID *uid )
  929. {
  930. /* Since we are using sceKernelAllocMemBlock directly, we cannot directly
  931. use the alignment parameter. Instead, we must allocate the size to the
  932. minimum for this memblock type, and just SCE_DBG_ALWAYS_ASSERT that this will cover
  933. our desired alignment.
  934.  
  935. Developers using their own heaps should be able to use the alignment
  936. parameter directly for more minimal padding.
  937. */
  938.  
  939. if( type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RWDATA )
  940. {
  941. /* CDRAM memblocks must be 256KiB aligned */
  942. SCE_DBG_ALWAYS_ASSERT( alignment <= 256*1024 );
  943. size = ALIGN( size, 256*1024 );
  944. }
  945. else
  946. {
  947. /* LPDDR memblocks must be 4KiB aligned */
  948. SCE_DBG_ALWAYS_ASSERT( alignment <= 4*1024 );
  949. size = ALIGN( size, 4*1024 );
  950. }
  951.  
  952. /* allocate some memory */
  953. *uid = sceKernelAllocMemBlock( "simple", type, size, NULL );
  954. SCE_DBG_ALWAYS_ASSERT( *uid >= SCE_OK );
  955.  
  956. /* grab the base address */
  957. void *mem = NULL;
  958. int err = sceKernelGetMemBlockBase( *uid, &mem );
  959. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  960.  
  961. /* map for the GPU */
  962. err = sceGxmMapMemory( mem, size, attribs );
  963. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  964.  
  965. /* done */
  966. return mem;
  967. }
  968.  
  969. /* Free used by libgxm */
  970. static void graphicsFree( SceUID uid )
  971. {
  972. /* grab the base address */
  973. void *mem = NULL;
  974. int err = sceKernelGetMemBlockBase(uid, &mem);
  975. SCE_DBG_ALWAYS_ASSERT(err == SCE_OK);
  976.  
  977. // unmap memory
  978. err = sceGxmUnmapMemory(mem);
  979. SCE_DBG_ALWAYS_ASSERT(err == SCE_OK);
  980.  
  981. // free the memory block
  982. err = sceKernelFreeMemBlock(uid);
  983. SCE_DBG_ALWAYS_ASSERT(err == SCE_OK);
  984. }
  985.  
  986. /* vertex alloc used by libgxm */
  987. static void *vertexUsseAlloc( uint32_t size, SceUID *uid, uint32_t *usseOffset )
  988. {
  989. /* align to memblock alignment for LPDDR */
  990. size = ALIGN( size, 4096 );
  991.  
  992. /* allocate some memory */
  993. *uid = sceKernelAllocMemBlock( "simple", SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, size, NULL );
  994. SCE_DBG_ALWAYS_ASSERT( *uid >= SCE_OK );
  995.  
  996. /* grab the base address */
  997. void *mem = NULL;
  998. int err = sceKernelGetMemBlockBase( *uid, &mem );
  999. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  1000.  
  1001. /* map as vertex USSE code for the GPU */
  1002. err = sceGxmMapVertexUsseMemory( mem, size, usseOffset );
  1003. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  1004.  
  1005. return mem;
  1006. }
  1007.  
  1008. /* vertex free used by libgxm */
  1009. static void vertexUsseFree( SceUID uid )
  1010. {
  1011. /* grab the base address */
  1012. void *mem = NULL;
  1013. int err = sceKernelGetMemBlockBase( uid, &mem );
  1014. SCE_DBG_ALWAYS_ASSERT(err == SCE_OK);
  1015.  
  1016. /* unmap memory */
  1017. err = sceGxmUnmapVertexUsseMemory( mem );
  1018. SCE_DBG_ALWAYS_ASSERT(err == SCE_OK);
  1019.  
  1020. /* free the memory block */
  1021. err = sceKernelFreeMemBlock( uid );
  1022. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  1023. }
  1024.  
  1025. /* fragment alloc used by libgxm */
  1026. static void *fragmentUsseAlloc( uint32_t size, SceUID *uid, uint32_t *usseOffset )
  1027. {
  1028. /* align to memblock alignment for LPDDR */
  1029. size = ALIGN( size, 4096 );
  1030.  
  1031. /* allocate some memory */
  1032. *uid = sceKernelAllocMemBlock( "simple", SCE_KERNEL_MEMBLOCK_TYPE_USER_RWDATA_UNCACHE, size, NULL );
  1033. SCE_DBG_ALWAYS_ASSERT( *uid >= SCE_OK );
  1034.  
  1035. /* grab the base address */
  1036. void *mem = NULL;
  1037. int err = sceKernelGetMemBlockBase( *uid, &mem );
  1038. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  1039.  
  1040. /* map as fragment USSE code for the GPU */
  1041. err = sceGxmMapFragmentUsseMemory( mem, size, usseOffset);
  1042. SCE_DBG_ALWAYS_ASSERT(err == SCE_OK);
  1043.  
  1044. // done
  1045. return mem;
  1046. }
  1047.  
  1048. /* fragment free used by libgxm */
  1049. static void fragmentUsseFree( SceUID uid )
  1050. {
  1051. /* grab the base address */
  1052. void *mem = NULL;
  1053. int err = sceKernelGetMemBlockBase( uid, &mem );
  1054. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  1055.  
  1056. /* unmap memory */
  1057. err = sceGxmUnmapFragmentUsseMemory( mem );
  1058. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  1059.  
  1060. /* free the memory block */
  1061. err = sceKernelFreeMemBlock( uid );
  1062. SCE_DBG_ALWAYS_ASSERT( err == SCE_OK );
  1063. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement