diff options
-rw-r--r-- | cpp/Allocation.cpp | 22 | ||||
-rw-r--r-- | cpp/RenderScript.cpp | 5 | ||||
-rw-r--r-- | cpp/rsCppStructs.h | 7 | ||||
-rw-r--r-- | cpp/rsDispatch.h | 2 | ||||
-rw-r--r-- | driver/rsdAllocation.cpp | 10 | ||||
-rw-r--r-- | rs.spec | 9 | ||||
-rw-r--r-- | rsAllocation.cpp | 27 | ||||
-rw-r--r-- | rsAllocation.h | 3 | ||||
-rw-r--r-- | tests/cppbasic-getpointer/Android.mk | 26 | ||||
-rw-r--r-- | tests/cppbasic-getpointer/compute.cpp | 100 | ||||
-rw-r--r-- | tests/cppbasic-getpointer/mono.rs | 23 |
11 files changed, 230 insertions, 4 deletions
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp index 00d207eb..de0f2291 100644 --- a/cpp/Allocation.cpp +++ b/cpp/Allocation.cpp @@ -169,8 +169,26 @@ void Allocation::ioGetInput() { #endif } -void Allocation::generateMipmaps() { - tryDispatch(mRS, RS::dispatch->AllocationGenerateMipmaps(mRS->getContext(), getID())); +void * Allocation::getPointer(size_t *stride) { + void *p = NULL; + if (!(mUsage & RS_ALLOCATION_USAGE_SHARED)) { + mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Allocation does not support USAGE_SHARED."); + return NULL; + } + + // FIXME: decide if lack of getPointer should cause compat mode + if (RS::dispatch->AllocationGetPointer == NULL) { + mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Can't use getPointer on older APIs"); + return NULL; + } + + p = RS::dispatch->AllocationGetPointer(mRS->getContext(), getIDSafe(), 0, + RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, stride); + if (mRS->getError() != RS_SUCCESS) { + mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation lock failed"); + p = NULL; + } + return p; } void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) { diff --git a/cpp/RenderScript.cpp b/cpp/RenderScript.cpp index 04f1e88e..5709f799 100644 --- a/cpp/RenderScript.cpp +++ b/cpp/RenderScript.cpp @@ -401,6 +401,11 @@ static bool loadSymbols(void* handle) { ALOGV("Couldn't initialize RS::dispatch->AllocationIoReceive"); return false; } + RS::dispatch->AllocationGetPointer = (AllocationGetPointerFnPtr)dlsym(handle, "rsAllocationGetPointer"); + if (RS::dispatch->AllocationGetPointer == NULL) { + ALOGV("Couldn't initialize RS::dispatch->AllocationGetPointer"); + //return false; + } return true; } diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h index 70931bef..6c14e8c3 100644 --- a/cpp/rsCppStructs.h +++ b/cpp/rsCppStructs.h @@ -559,6 +559,13 @@ public: uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT); + /** + * Get the backing pointer for a USAGE_SHARED allocation. + * @param[in] stride optional parameter. when non-NULL, will contain + * stride in bytes of a 2D Allocation + * @return pointer to data + */ + void * getPointer(size_t *stride = NULL); }; /** diff --git a/cpp/rsDispatch.h b/cpp/rsDispatch.h index 0bd1283f..ca708adf 100644 --- a/cpp/rsDispatch.h +++ b/cpp/rsDispatch.h @@ -85,6 +85,7 @@ typedef void (*ScriptGroupSetInputFnPtr) (RsContext, RsScriptGroup, RsScriptKern typedef void (*ScriptGroupExecuteFnPtr) (RsContext, RsScriptGroup); typedef void (*AllocationIoSendFnPtr) (RsContext, RsAllocation); typedef void (*AllocationIoReceiveFnPtr) (RsContext, RsAllocation); +typedef void * (*AllocationGetPointerFnPtr) (RsContext, RsAllocation, uint32_t lod, RsAllocationCubemapFace face, uint32_t z, uint32_t array, size_t *stride); typedef struct { // inserted by hand from rs.h @@ -156,6 +157,7 @@ typedef struct { ScriptGroupExecuteFnPtr ScriptGroupExecute; AllocationIoSendFnPtr AllocationIoSend; AllocationIoReceiveFnPtr AllocationIoReceive; + AllocationGetPointerFnPtr AllocationGetPointer; } dispatchTable; #endif diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp index 817c9d8d..0d85ebee 100644 --- a/driver/rsdAllocation.cpp +++ b/driver/rsdAllocation.cpp @@ -599,7 +599,7 @@ void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, return; } - rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT); + rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT || src == RS_ALLOCATION_USAGE_SHARED); if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) { UploadToTexture(rsc, alloc); @@ -614,7 +614,13 @@ void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc, } if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) { - // NOP in CPU driver for now + + if (src == RS_ALLOCATION_USAGE_SHARED) { + // just a memory fence for the CPU driver + // vendor drivers probably want to flush any dirty cachelines for + // this particular Allocation + __sync_synchronize(); + } } drv->uploadDeferred = false; @@ -130,6 +130,15 @@ AllocationCopyToBitmap { param void * data } +AllocationGetPointer { + param RsAllocation va + param uint32_t lod + param RsAllocationCubemapFace face + param uint32_t z + param uint32_t array + param size_t *stride + ret void *s + } Allocation1DData { param RsAllocation va diff --git a/rsAllocation.cpp b/rsAllocation.cpp index d4cecd03..fd0a49c5 100644 --- a/rsAllocation.cpp +++ b/rsAllocation.cpp @@ -94,6 +94,24 @@ void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) { rsc->mHal.funcs.allocation.syncAll(rsc, this, src); } +void * Allocation::getPointer(const Context *rsc, uint32_t lod, RsAllocationCubemapFace face, + uint32_t z, uint32_t array, size_t *stride) { + + if ((lod >= mHal.drvState.lodCount) || + (z && (z >= mHal.drvState.lod[lod].dimZ)) || + ((face != RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) && !mHal.state.hasFaces) || + (array != 0)) { + return NULL; + } + + size_t s = 0; + //void *ptr = mRSC->mHal.funcs.allocation.lock1D(rsc, this); + if ((stride != NULL) && mHal.drvState.lod[0].dimY) { + *stride = mHal.drvState.lod[lod].stride; + } + return mHal.drvState.lod[lod].mallocPtr; +} + void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod, uint32_t count, const void *data, size_t sizeBytes) { const size_t eSize = mHal.state.type->getElementSizeBytes(); @@ -716,6 +734,15 @@ void rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) { alloc->ioReceive(rsc); } +void rsi_AllocationGetPointer(Context *rsc, RsAllocation valloc, + uint32_t lod, RsAllocationCubemapFace face, + uint32_t z, uint32_t array, size_t *stride, size_t strideLen) { + Allocation *alloc = static_cast<Allocation *>(valloc); + assert(strideLen == sizeof(size_t)); + + alloc->getPointer(rsc, lod, face, z, array, stride); +} + void rsi_Allocation1DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod, uint32_t count, void *data, size_t sizeBytes) { Allocation *a = static_cast<Allocation *>(va); diff --git a/rsAllocation.h b/rsAllocation.h index b0f2f9e6..b997f9a9 100644 --- a/rsAllocation.h +++ b/rsAllocation.h @@ -163,6 +163,9 @@ public: void ioSend(const Context *rsc); void ioReceive(const Context *rsc); + void * getPointer(const Context *rsc, uint32_t lod, RsAllocationCubemapFace face, + uint32_t z, uint32_t array, size_t *stride); + protected: Vector<const Program *> mToDirtyList; ObjectBaseRef<const Type> mType; diff --git a/tests/cppbasic-getpointer/Android.mk b/tests/cppbasic-getpointer/Android.mk new file mode 100644 index 00000000..eb4ac34f --- /dev/null +++ b/tests/cppbasic-getpointer/Android.mk @@ -0,0 +1,26 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + mono.rs \ + compute.cpp + +LOCAL_SHARED_LIBRARIES := \ + libRScpp \ + libstlport + +LOCAL_MODULE:= rstest-compute-getpointer + +LOCAL_MODULE_TAGS := tests + +intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) + +LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include +LOCAL_C_INCLUDES += frameworks/rs/cpp +LOCAL_C_INCLUDES += frameworks/rs +LOCAL_C_INCLUDES += $(intermediates) + +LOCAL_CLANG := true + +include $(BUILD_EXECUTABLE) + diff --git a/tests/cppbasic-getpointer/compute.cpp b/tests/cppbasic-getpointer/compute.cpp new file mode 100644 index 00000000..033e7b39 --- /dev/null +++ b/tests/cppbasic-getpointer/compute.cpp @@ -0,0 +1,100 @@ + +#include "RenderScript.h" + +#include "ScriptC_mono.h" + +#include <stdlib.h> + +using namespace android; +using namespace RSC; + +const uint32_t DIMX = 128; +const uint32_t DIMY = 128; + +int test_compute() +{ + bool failed = false; + + sp<RS> rs = new RS(); + printf("New RS %p\n", rs.get()); + + // only legitimate because this is a standalone executable + bool r = rs->init("/system/bin"); + printf("Init returned %i\n", r); + + sp<const Element> e = Element::U32(rs); + printf("Element %p\n", e.get()); + + Type::Builder tb(rs, e); + tb.setX(DIMX); + tb.setY(DIMY); + sp<const Type> t = tb.create(); + printf("Type %p\n", t.get()); + + + sp<Allocation> a1 = Allocation::createSized(rs, e, 1000); + printf("Allocation %p\n", a1.get()); + + sp<Allocation> ain = Allocation::createTyped(rs, t, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED); + sp<Allocation> aout = Allocation::createTyped(rs, t, RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED); + printf("Allocation %p %p\n", ain.get(), aout.get()); + + size_t inputStride, outputStride; + + uint32_t *input = (uint32_t*)ain->getPointer(&inputStride); + uint32_t *output = (uint32_t*)aout->getPointer(&outputStride); + + printf("Input pointer: %p\n", input); + printf("Input stride: %u\n", inputStride); + printf("Output pointer: %p\n", output); + printf("Output stride: %u\n", outputStride); + + inputStride /= sizeof(uint32_t); + outputStride /= sizeof(uint32_t); + + for (size_t i = 0; i < DIMY; i++) { + for (size_t j = 0; j < DIMX; j++) { + input[i * inputStride + j] = rand(); + output[i * inputStride + j] = 0; + } + } + + ain->syncAll(RS_ALLOCATION_USAGE_SHARED); + aout->syncAll(RS_ALLOCATION_USAGE_SHARED); + + printf("Launching script\n"); + + sp<ScriptC_mono> sc = new ScriptC_mono(rs); + sc->forEach_copyAndNot(ain, aout); + rs->finish(); + + printf("Script completed\n"); + + ain->syncAll(RS_ALLOCATION_USAGE_SCRIPT); + aout->syncAll(RS_ALLOCATION_USAGE_SCRIPT); + + for (size_t i = 0; i < DIMY; i++) { + for (size_t j = 0; j < DIMX; j++) { + if (input[i * inputStride + j] != ~(output[i * inputStride + j])) { + printf("Mismatch at location %u, %u\n", j, i); + failed = true; + return failed; + } + } + } + + + return failed; +} + +int main() { + bool failed = test_compute(); + + if (failed) { + printf("TEST FAILED!\n"); + } else { + printf("TEST PASSED!\n"); + } + + return failed; +} diff --git a/tests/cppbasic-getpointer/mono.rs b/tests/cppbasic-getpointer/mono.rs new file mode 100644 index 00000000..25e60df3 --- /dev/null +++ b/tests/cppbasic-getpointer/mono.rs @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma version(1) +#pragma rs java_package_name(com.android.rs.cppbasic) +#pragma rs_fp_relaxed + +uint32_t __attribute__((kernel)) copyAndNot(uint32_t in) { + return ~in; +} |