diff options
Diffstat (limited to 'libs/rs/rsScriptC.cpp')
-rw-r--r-- | libs/rs/rsScriptC.cpp | 503 |
1 files changed, 291 insertions, 212 deletions
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp index f4d2451..7c7b037 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -17,8 +17,7 @@ #include "rsContext.h" #include "rsScriptC.h" #include "rsMatrix.h" - -#include "acc/acc.h" +#include "../../../external/llvm/libbcc/include/bcc/bcc.h" #include "utils/Timers.h" #include <GLES/gl.h> @@ -37,40 +36,74 @@ ScriptC::ScriptC(Context *rsc) : Script(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; - mAccScript = NULL; + mBccScript = NULL; memset(&mProgram, 0, sizeof(mProgram)); } ScriptC::~ScriptC() { - if (mAccScript) { - accDeleteScript(mAccScript); + if (mBccScript) { + bccDeleteScript(mBccScript); } free(mEnviroment.mScriptText); mEnviroment.mScriptText = NULL; } -void ScriptC::setupScript() +void ScriptC::setupScript(Context *rsc) { - for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) { - if (mProgram.mSlotPointers[ct]) { - *mProgram.mSlotPointers[ct] = mSlots[ct]->getPtr(); + setupGLState(rsc); + mEnviroment.mStartTimeMillis + = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); + + for (uint32_t ct=0; ct < mEnviroment.mFieldCount; ct++) { + if (!mSlots[ct].get()) + continue; + void *ptr = mSlots[ct]->getPtr(); + void **dest = ((void ***)mEnviroment.mFieldAddress)[ct]; + //LOGE("setupScript %i %p = %p %p %i", ct, dest, ptr, mSlots[ct]->getType(), mSlots[ct]->getType()->getDimX()); + + //const uint32_t *p32 = (const uint32_t *)ptr; + //for (uint32_t ct2=0; ct2 < mSlots[ct]->getType()->getDimX(); ct2++) { + //LOGE(" %i = 0x%08x ", ct2, p32[ct2]); + //} + + if (dest) { + *dest = ptr; + } else { + LOGE("ScriptC::setupScript, NULL var binding address."); } } } - -uint32_t ScriptC::run(Context *rsc, uint32_t launchIndex) +const Allocation *ScriptC::ptrToAllocation(const void *ptr) const { - if (mProgram.mScript == NULL) { - rsc->setError(RS_ERROR_BAD_SCRIPT, "Attempted to run bad script"); - return 0; + if (!ptr) { + return NULL; } + for (uint32_t ct=0; ct < mEnviroment.mFieldCount; ct++) { + if (!mSlots[ct].get()) + continue; + if (mSlots[ct]->getPtr() == ptr) { + return mSlots[ct].get(); + } + } + LOGE("ScriptC::ptrToAllocation, failed to find %p", ptr); + return NULL; +} - Context::ScriptTLSStruct * tls = - (Context::ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); +Script * ScriptC::setTLS(Script *sc) +{ + Context::ScriptTLSStruct * tls = (Context::ScriptTLSStruct *) + pthread_getspecific(Context::gThreadTLSKey); rsAssert(tls); + Script *old = tls->mScript; + tls->mScript = sc; + return old; +} + +void ScriptC::setupGLState(Context *rsc) +{ if (mEnviroment.mFragmentStore.get()) { rsc->setFragmentStore(mEnviroment.mFragmentStore.get()); } @@ -83,20 +116,214 @@ uint32_t ScriptC::run(Context *rsc, uint32_t launchIndex) if (mEnviroment.mRaster.get()) { rsc->setRaster(mEnviroment.mRaster.get()); } +} - if (launchIndex == 0) { - mEnviroment.mStartTimeMillis - = nanoseconds_to_milliseconds(systemTime(SYSTEM_TIME_MONOTONIC)); +uint32_t ScriptC::run(Context *rsc) +{ + if (mProgram.mRoot == NULL) { + rsc->setError(RS_ERROR_BAD_SCRIPT, "Attempted to run bad script"); + return 0; } - setupScript(); + + setupScript(rsc); uint32_t ret = 0; - tls->mScript = this; - ret = mProgram.mScript(launchIndex); - tls->mScript = NULL; + Script * oldTLS = setTLS(this); + //LOGE("ScriptC::run %p", mProgram.mRoot); + ret = mProgram.mRoot(); + setTLS(oldTLS); + //LOGE("ScriptC::run ret %i", ret); return ret; } + +typedef struct { + Context *rsc; + ScriptC *script; + const Allocation * ain; + Allocation * aout; + const void * usr; + + uint32_t mSliceSize; + volatile int mSliceNum; + + const uint8_t *ptrIn; + uint32_t eStrideIn; + uint8_t *ptrOut; + uint32_t eStrideOut; + + uint32_t xStart; + uint32_t xEnd; + uint32_t yStart; + uint32_t yEnd; + uint32_t zStart; + uint32_t zEnd; + uint32_t arrayStart; + uint32_t arrayEnd; + + uint32_t dimX; + uint32_t dimY; + uint32_t dimZ; + uint32_t dimArray; +} MTLaunchStruct; +typedef int (*rs_t)(const void *, void *, const void *, uint32_t, uint32_t, uint32_t, uint32_t); + +static void wc_xy(void *usr, uint32_t idx) +{ + MTLaunchStruct *mtls = (MTLaunchStruct *)usr; + + while (1) { + uint32_t slice = (uint32_t)android_atomic_inc(&mtls->mSliceNum); + uint32_t yStart = mtls->yStart + slice * mtls->mSliceSize; + uint32_t yEnd = yStart + mtls->mSliceSize; + yEnd = rsMin(yEnd, mtls->yEnd); + if (yEnd <= yStart) { + return; + } + + //LOGE("usr idx %i, x %i,%i y %i,%i", idx, mtls->xStart, mtls->xEnd, yStart, yEnd); + + for (uint32_t y = yStart; y < yEnd; y++) { + uint32_t offset = mtls->dimX * y; + uint8_t *xPtrOut = mtls->ptrOut + (mtls->eStrideOut * offset); + const uint8_t *xPtrIn = mtls->ptrIn + (mtls->eStrideIn * offset); + + for (uint32_t x = mtls->xStart; x < mtls->xEnd; x++) { + ((rs_t)mtls->script->mProgram.mRoot) (xPtrIn, xPtrOut, mtls->usr, x, y, 0, 0); + xPtrIn += mtls->eStrideIn; + xPtrOut += mtls->eStrideOut; + } + } + } + +} + +void ScriptC::runForEach(Context *rsc, + const Allocation * ain, + Allocation * aout, + const void * usr, + const RsScriptCall *sc) +{ + MTLaunchStruct mtls; + memset(&mtls, 0, sizeof(mtls)); + + if (ain) { + mtls.dimX = ain->getType()->getDimX(); + mtls.dimY = ain->getType()->getDimY(); + mtls.dimZ = ain->getType()->getDimZ(); + //mtls.dimArray = ain->getType()->getDimArray(); + } else if (aout) { + mtls.dimX = aout->getType()->getDimX(); + mtls.dimY = aout->getType()->getDimY(); + mtls.dimZ = aout->getType()->getDimZ(); + //mtls.dimArray = aout->getType()->getDimArray(); + } else { + rsc->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations"); + return; + } + + if (!sc || (sc->xEnd == 0)) { + mtls.xEnd = mtls.dimX; + } else { + rsAssert(sc->xStart < mtls.dimX); + rsAssert(sc->xEnd <= mtls.dimX); + rsAssert(sc->xStart < sc->xEnd); + mtls.xStart = rsMin(mtls.dimX, sc->xStart); + mtls.xEnd = rsMin(mtls.dimX, sc->xEnd); + if (mtls.xStart >= mtls.xEnd) return; + } + + if (!sc || (sc->yEnd == 0)) { + mtls.yEnd = mtls.dimY; + } else { + rsAssert(sc->yStart < mtls.dimY); + rsAssert(sc->yEnd <= mtls.dimY); + rsAssert(sc->yStart < sc->yEnd); + mtls.yStart = rsMin(mtls.dimY, sc->yStart); + mtls.yEnd = rsMin(mtls.dimY, sc->yEnd); + if (mtls.yStart >= mtls.yEnd) return; + } + + mtls.xEnd = rsMax((uint32_t)1, mtls.xEnd); + mtls.yEnd = rsMax((uint32_t)1, mtls.yEnd); + mtls.zEnd = rsMax((uint32_t)1, mtls.zEnd); + mtls.arrayEnd = rsMax((uint32_t)1, mtls.arrayEnd); + + rsAssert(ain->getType()->getDimZ() == 0); + + setupScript(rsc); + Script * oldTLS = setTLS(this); + + + mtls.rsc = rsc; + mtls.ain = ain; + mtls.aout = aout; + mtls.script = this; + mtls.usr = usr; + mtls.mSliceSize = 10; + mtls.mSliceNum = 0; + + mtls.ptrIn = NULL; + mtls.eStrideIn = 0; + if (ain) { + mtls.ptrIn = (const uint8_t *)ain->getPtr(); + mtls.eStrideIn = ain->getType()->getElementSizeBytes(); + } + + mtls.ptrOut = NULL; + mtls.eStrideOut = 0; + if (aout) { + mtls.ptrOut = (uint8_t *)aout->getPtr(); + mtls.eStrideOut = aout->getType()->getElementSizeBytes(); + } + + + if ((rsc->getWorkerPoolSize() > 1) && + ((mtls.dimY * mtls.dimZ * mtls.dimArray) > 1)) { + + //LOGE("launch 1"); + rsc->launchThreads(wc_xy, &mtls); + //LOGE("launch 2"); + } else { + for (uint32_t ar = mtls.arrayStart; ar < mtls.arrayEnd; ar++) { + for (uint32_t z = mtls.zStart; z < mtls.zEnd; z++) { + for (uint32_t y = mtls.yStart; y < mtls.yEnd; y++) { + uint32_t offset = mtls.dimX * mtls.dimY * mtls.dimZ * ar + + mtls.dimX * mtls.dimY * z + + mtls.dimX * y; + uint8_t *xPtrOut = mtls.ptrOut + (mtls.eStrideOut * offset); + const uint8_t *xPtrIn = mtls.ptrIn + (mtls.eStrideIn * offset); + + for (uint32_t x = mtls.xStart; x < mtls.xEnd; x++) { + ((rs_t)mProgram.mRoot) (xPtrIn, xPtrOut, usr, x, y, z, ar); + xPtrIn += mtls.eStrideIn; + xPtrOut += mtls.eStrideOut; + } + } + } + } + } + + setTLS(oldTLS); +} + +void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, uint32_t len) +{ + //LOGE("rsi_ScriptInvoke %i", slot); + if ((slot >= mEnviroment.mInvokeFunctionCount) || + (mEnviroment.mInvokeFunctions[slot] == NULL)) { + rsc->setError(RS_ERROR_BAD_SCRIPT, "Calling invoke on bad script"); + return; + } + setupScript(rsc); + Script * oldTLS = setTLS(this); + + ((void (*)(const void *, uint32_t)) + mEnviroment.mInvokeFunctions[slot])(data, len); + + setTLS(oldTLS); +} + ScriptCState::ScriptCState() { mScript = NULL; @@ -113,21 +340,25 @@ void ScriptCState::clear() { for (uint32_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) { mConstantBufferTypes[ct].clear(); - mSlotNames[ct].setTo(""); - mInvokableNames[ct].setTo(""); mSlotWritable[ct] = false; } delete mScript; mScript = new ScriptC(NULL); - - mInt32Defines.clear(); - mFloatDefines.clear(); } -static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) +static BCCvoid* symbolLookup(BCCvoid* pContext, const BCCchar* name) { - const ScriptCState::SymbolTable_t *sym = ScriptCState::lookupSymbol(name); + const ScriptCState::SymbolTable_t *sym; + sym = ScriptCState::lookupSymbol(name); + if (sym) { + return sym->mPtr; + } + sym = ScriptCState::lookupSymbolCL(name); + if (sym) { + return sym->mPtr; + } + sym = ScriptCState::lookupSymbolGL(name); if (sym) { return sym->mPtr; } @@ -137,65 +368,52 @@ static ACCvoid* symbolLookup(ACCvoid* pContext, const ACCchar* name) void ScriptCState::runCompiler(Context *rsc, ScriptC *s) { - s->mAccScript = accCreateScript(); - String8 tmp; - - rsc->appendNameDefines(&tmp); - appendDecls(&tmp); - appendVarDefines(rsc, &tmp); - appendTypes(rsc, &tmp); - tmp.append("#line 1\n"); - - const char* scriptSource[] = {tmp.string(), s->mEnviroment.mScriptText}; - int scriptLength[] = {tmp.length(), s->mEnviroment.mScriptTextLength} ; - accScriptSource(s->mAccScript, sizeof(scriptLength) / sizeof(int), scriptSource, scriptLength); - accRegisterSymbolCallback(s->mAccScript, symbolLookup, NULL); - accCompileScript(s->mAccScript); - accGetScriptLabel(s->mAccScript, "main", (ACCvoid**) &s->mProgram.mScript); - accGetScriptLabel(s->mAccScript, "init", (ACCvoid**) &s->mProgram.mInit); - rsAssert(s->mProgram.mScript); - - if (!s->mProgram.mScript) { - ACCchar buf[4096]; - ACCsizei len; - accGetScriptInfoLog(s->mAccScript, sizeof(buf), &len, buf); - LOGE("%s", buf); - rsc->setError(RS_ERROR_BAD_SCRIPT, "Error compiling user script."); - return; - } + LOGV("ScriptCState::runCompiler "); + + s->mBccScript = bccCreateScript(); + bccScriptBitcode(s->mBccScript, s->mEnviroment.mScriptText, s->mEnviroment.mScriptTextLength); + bccRegisterSymbolCallback(s->mBccScript, symbolLookup, NULL); + bccCompileScript(s->mBccScript); + bccGetScriptLabel(s->mBccScript, "root", (BCCvoid**) &s->mProgram.mRoot); + bccGetScriptLabel(s->mBccScript, "init", (BCCvoid**) &s->mProgram.mInit); + LOGV("root %p, init %p", s->mProgram.mRoot, s->mProgram.mInit); if (s->mProgram.mInit) { s->mProgram.mInit(); } - for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) { - if (mSlotNames[ct].length() > 0) { - accGetScriptLabel(s->mAccScript, - mSlotNames[ct].string(), - (ACCvoid**) &s->mProgram.mSlotPointers[ct]); - } + bccGetExportFuncs(s->mBccScript, (BCCsizei*) &s->mEnviroment.mInvokeFunctionCount, 0, NULL); + if(s->mEnviroment.mInvokeFunctionCount <= 0) + s->mEnviroment.mInvokeFunctions = NULL; + else { + s->mEnviroment.mInvokeFunctions = (Script::InvokeFunc_t*) calloc(s->mEnviroment.mInvokeFunctionCount, sizeof(Script::InvokeFunc_t)); + bccGetExportFuncs(s->mBccScript, NULL, s->mEnviroment.mInvokeFunctionCount, (BCCvoid **) s->mEnviroment.mInvokeFunctions); } - for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) { - if (mInvokableNames[ct].length() > 0) { - accGetScriptLabel(s->mAccScript, - mInvokableNames[ct].string(), - (ACCvoid**) &s->mEnviroment.mInvokables[ct]); - } + bccGetExportVars(s->mBccScript, (BCCsizei*) &s->mEnviroment.mFieldCount, 0, NULL); + if(s->mEnviroment.mFieldCount <= 0) + s->mEnviroment.mFieldAddress = NULL; + else { + s->mEnviroment.mFieldAddress = (void **) calloc(s->mEnviroment.mFieldCount, sizeof(void *)); + bccGetExportVars(s->mBccScript, NULL, s->mEnviroment.mFieldCount, (BCCvoid **) s->mEnviroment.mFieldAddress); } + //for (int ct2=0; ct2 < s->mEnviroment.mFieldCount; ct2++ ) { + //LOGE("Script field %i = %p", ct2, s->mEnviroment.mFieldAddress[ct2]); + //} s->mEnviroment.mFragment.set(rsc->getDefaultProgramFragment()); s->mEnviroment.mVertex.set(rsc->getDefaultProgramVertex()); - s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramFragmentStore()); + s->mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore()); s->mEnviroment.mRaster.set(rsc->getDefaultProgramRaster()); - if (s->mProgram.mScript) { + if (s->mProgram.mRoot) { const static int pragmaMax = 16; - ACCsizei pragmaCount; - ACCchar * str[pragmaMax]; - accGetPragmas(s->mAccScript, &pragmaCount, pragmaMax, &str[0]); + BCCsizei pragmaCount; + BCCchar * str[pragmaMax]; + bccGetPragmas(s->mBccScript, &pragmaCount, pragmaMax, &str[0]); for (int ct=0; ct < pragmaCount; ct+=2) { + //LOGE("pragme %s %s", str[ct], str[ct+1]); if (!strcmp(str[ct], "version")) { continue; } @@ -208,11 +426,6 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s) s->mEnviroment.mVertex.clear(); continue; } - ProgramVertex * pv = (ProgramVertex *)rsc->lookupName(str[ct+1]); - if (pv != NULL) { - s->mEnviroment.mVertex.set(pv); - continue; - } LOGE("Unreconized value %s passed to stateVertex", str[ct+1]); } @@ -224,11 +437,6 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s) s->mEnviroment.mRaster.clear(); continue; } - ProgramRaster * pr = (ProgramRaster *)rsc->lookupName(str[ct+1]); - if (pr != NULL) { - s->mEnviroment.mRaster.set(pr); - continue; - } LOGE("Unreconized value %s passed to stateRaster", str[ct+1]); } @@ -240,11 +448,6 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s) s->mEnviroment.mFragment.clear(); continue; } - ProgramFragment * pf = (ProgramFragment *)rsc->lookupName(str[ct+1]); - if (pf != NULL) { - s->mEnviroment.mFragment.set(pf); - continue; - } LOGE("Unreconized value %s passed to stateFragment", str[ct+1]); } @@ -256,12 +459,6 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s) s->mEnviroment.mFragmentStore.clear(); continue; } - ProgramFragmentStore * pfs = - (ProgramFragmentStore *)rsc->lookupName(str[ct+1]); - if (pfs != NULL) { - s->mEnviroment.mFragmentStore.set(pfs); - continue; - } LOGE("Unreconized value %s passed to stateStore", str[ct+1]); } @@ -273,111 +470,6 @@ void ScriptCState::runCompiler(Context *rsc, ScriptC *s) } } -static void appendElementBody(String8 *s, const Element *e) -{ - s->append(" {\n"); - for (size_t ct2=0; ct2 < e->getFieldCount(); ct2++) { - const Element *c = e->getField(ct2); - s->append(" "); - s->append(c->getCType()); - s->append(" "); - s->append(e->getFieldName(ct2)); - s->append(";\n"); - } - s->append("}"); -} - -void ScriptCState::appendVarDefines(const Context *rsc, String8 *str) -{ - char buf[256]; - if (rsc->props.mLogScripts) { - LOGD("appendVarDefines mInt32Defines.size()=%d mFloatDefines.size()=%d\n", - mInt32Defines.size(), mFloatDefines.size()); - } - for (size_t ct=0; ct < mInt32Defines.size(); ct++) { - str->append("#define "); - str->append(mInt32Defines.keyAt(ct)); - str->append(" "); - sprintf(buf, "%i\n", (int)mInt32Defines.valueAt(ct)); - str->append(buf); - } - for (size_t ct=0; ct < mFloatDefines.size(); ct++) { - str->append("#define "); - str->append(mFloatDefines.keyAt(ct)); - str->append(" "); - sprintf(buf, "%ff\n", mFloatDefines.valueAt(ct)); - str->append(buf); - } -} - - - -void ScriptCState::appendTypes(const Context *rsc, String8 *str) -{ - char buf[256]; - String8 tmp; - - str->append("struct vecF32_2_s {float x; float y;};\n"); - str->append("struct vecF32_3_s {float x; float y; float z;};\n"); - str->append("struct vecF32_4_s {float x; float y; float z; float w;};\n"); - str->append("struct vecU8_4_s {char r; char g; char b; char a;};\n"); - str->append("#define vecF32_2_t struct vecF32_2_s\n"); - str->append("#define vecF32_3_t struct vecF32_3_s\n"); - str->append("#define vecF32_4_t struct vecF32_4_s\n"); - str->append("#define vecU8_4_t struct vecU8_4_s\n"); - str->append("#define vecI8_4_t struct vecU8_4_s\n"); - - for (size_t ct=0; ct < MAX_SCRIPT_BANKS; ct++) { - const Type *t = mConstantBufferTypes[ct].get(); - if (!t) { - continue; - } - const Element *e = t->getElement(); - if (e->getName() && (e->getFieldCount() > 1)) { - String8 s("struct struct_"); - s.append(e->getName()); - s.append(e->getCStructBody()); - s.append(";\n"); - - s.append("#define "); - s.append(e->getName()); - s.append("_t struct struct_"); - s.append(e->getName()); - s.append("\n\n"); - if (rsc->props.mLogScripts) { - LOGV("%s", static_cast<const char*>(s)); - } - str->append(s); - } - - if (mSlotNames[ct].length() > 0) { - String8 s; - if (e->getName()) { - // Use the named struct - s.setTo(e->getName()); - } else { - // create an struct named from the slot. - s.setTo("struct "); - s.append(mSlotNames[ct]); - s.append("_s"); - s.append(e->getCStructBody()); - //appendElementBody(&s, e); - s.append(";\n"); - s.append("struct "); - s.append(mSlotNames[ct]); - s.append("_s"); - } - - s.append(" * "); - s.append(mSlotNames[ct]); - s.append(";\n"); - if (rsc->props.mLogScripts) { - LOGV("%s", static_cast<const char*>(s)); - } - str->append(s); - } - } -} namespace android { @@ -420,7 +512,6 @@ RsScript rsi_ScriptCCreate(Context * rsc) s->setContext(rsc); for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) { s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get()); - s->mSlotNames[ct] = ss->mSlotNames[ct]; s->mSlotWritable[ct] = ss->mSlotWritable[ct]; } @@ -428,18 +519,6 @@ RsScript rsi_ScriptCCreate(Context * rsc) return s; } -void rsi_ScriptCSetDefineF(Context *rsc, const char* name, float value) -{ - ScriptCState *ss = &rsc->mScriptC; - ss->mFloatDefines.add(String8(name), value); -} - -void rsi_ScriptCSetDefineI32(Context *rsc, const char* name, int32_t value) -{ - ScriptCState *ss = &rsc->mScriptC; - ss->mInt32Defines.add(String8(name), value); -} - } } |