1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/* [SCE CONFIDENTIAL DOCUMENT]
* PLAYSTATION(R)3 SPU Optimized Bullet Physics Library (http://bulletphysics.com)
* Copyright (C) 2007 Sony Computer Entertainment Inc.
* All Rights Reserved.
*/
#ifndef __SPURS_SUPPORT_INTERFACE_H
#define __SPURS_SUPPORT_INTERFACE_H
#include <cell/spurs/queue.h>
#include "spursUtilityMacros.h"
#include "spursThreadSupportInterface.h"
#ifdef __SPU__
#include <simd>
#include <sdk_version.h>
#if CELL_SDK_VERSION < 0x081000
#define CELL_SPURS_TASK_ERROR_AGAIN CELL_SPURS_EAGAIN
#define CELL_SPURS_TASK_ERROR_BUSY CELL_SPURS_EBUSY
#endif // CELL_SDK_VERSION < 0x081000
#else // __SPU__
#include <cell/spurs/task.h>
#endif // __SPU__
#define CELL_SPURS_RESPONSE_QUEUE_SIZE 128
/**
* Note:
* The order of elements in this enum are important, that's why each one is explicitly
* given a value. They will correspond to the .elf names/addresses that will be
* loaded into SPURS.
* Mixing up these values will cause the wrong code to execute, for instance, the
* solver may be asked to do a collision detection job.
*/
//////////////////////////////////////////////////////////////////////////
// only one type of SPURS Task ELF
// typedef enum {
// // SPU_ELF_MID_PHASE=0,
// // SPU_ELF_SOLVER,
// SPU_ELF_SPEEX,
// SPU_ELF_LAST,
// } CellSpursElfId_t;
typedef union CellSPURSArgument
{
struct
{
CELL_PPU_POINTER(CellSpursQueue) ppuResponseQueue;
uint32_t uiCommand;
uint32_t uiArgument0;
uint32_t uiArgument1;
};
#if __PPU__
CellSpursTaskArgument spursArgument;
#elif __SPU__
vec_uint4 uiQWord;
#endif
} CellSPURSArgument __attribute__((aligned(16)));
#if __SPU__
#include "SPUAssert.h"
#include <cell/spurs/task.h>
static inline void sendResponseToPPU(uint32_t ppuQueueEA, uint32_t uiArgument0,
uint32_t uiArgument1, int iTag=1) {
CellSPURSArgument response
__attribute__ ((aligned(16)));
response.uiArgument0=uiArgument0;
response.uiArgument1=uiArgument1;
int iReturn;
do {
iReturn=cellSpursQueueTryPushBegin(ppuQueueEA, &response, iTag);
} while (iReturn == CELL_SPURS_TASK_ERROR_AGAIN ||
iReturn == CELL_SPURS_TASK_ERROR_BUSY);
SPU_ASSERT((iReturn == CELL_OK) && "Error writing to SPURS queue.");
cellSpursQueuePushEnd(ppuQueueEA, iTag);
}
static inline void sendResponseToPPUAndExit(uint32_t ppuQueueEA, uint32_t uiArgument0,
uint32_t uiArgument1, int iTag=1) {
CellSPURSArgument response
__attribute__ ((aligned(16)));
response.uiArgument0=uiArgument0;
response.uiArgument1=uiArgument1;
int iReturn;
do {
iReturn=cellSpursQueueTryPushBegin(ppuQueueEA, &response, iTag);
} while (iReturn == CELL_SPURS_TASK_ERROR_AGAIN ||
iReturn == CELL_SPURS_TASK_ERROR_BUSY);
SPU_ASSERT((iReturn == CELL_OK) && "Error writing to SPURS queue.");
cellSpursQueuePushEnd(ppuQueueEA, iTag);
cellSpursExit();
}
#elif __PPU__ // not __SPU__
class SpursSupportInterface : public spursThreadSupportInterface
{
public:
SpursSupportInterface();
~SpursSupportInterface();
int sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1=0);
int waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
int startSPU();
int stopSPU();
protected:
//CellSpursElfId_t m_elfId;
void *m_spursTaskAddress;
CellSpursQueue m_responseQueue __attribute__((aligned(128)));
CellSPURSArgument m_aResponseBuffer[CELL_SPURS_RESPONSE_QUEUE_SIZE] __attribute__((aligned(16)));
bool m_bQueueInitialized;
};
#endif // __SPU__ / __PPU__
#endif // CELL_SPURS_SUPPORT_H
|