summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Sams <jsams@google.com>2014-02-24 17:52:32 -0800
committerTim Murray <timmurray@google.com>2014-02-26 12:56:38 -0800
commitb8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4 (patch)
treee90cf2d7d4f89e58742bb34403626cc8bcfb0f5c
parent6bc047c966d52d0246a107dbda410f218f2174eb (diff)
downloadrs-b8a94e26c0a5e8f58d5b6ed04e46b411e95b77a4.tar.gz
Add getPointer for USAGE_SHARED allocations.
Change-Id: I13a2af09bbbeec6cc6131b935979ac21c02820be
-rw-r--r--cpp/Allocation.cpp22
-rw-r--r--cpp/RenderScript.cpp5
-rw-r--r--cpp/rsCppStructs.h7
-rw-r--r--cpp/rsDispatch.h2
-rw-r--r--driver/rsdAllocation.cpp10
-rw-r--r--rs.spec9
-rw-r--r--rsAllocation.cpp27
-rw-r--r--rsAllocation.h3
-rw-r--r--tests/cppbasic-getpointer/Android.mk26
-rw-r--r--tests/cppbasic-getpointer/compute.cpp100
-rw-r--r--tests/cppbasic-getpointer/mono.rs23
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;
diff --git a/rs.spec b/rs.spec
index 6ce258aa..62a36464 100644
--- a/rs.spec
+++ b/rs.spec
@@ -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;
+}