Add AllocationCreateStrided to support lib CPU driver
- Able to create Allocations with arbitrary alignment requirement,
making Incremental Intrinsic Support able to run with different
native GPU RS runtime.
- Make compat mode CPU driver using an additional rs_compat.spec.
- Add a compat mode only USAGE_INCREMENTAL_SUPPORT.
- Add AllocationCreateStrided() to take an Alignment requirement (power
of 2). Only enbled when detect USAGE_INCREMENTAL_SUPPORT.
Change-Id: I66f913c3a2474f93af5a244c0c84460a7a395e71
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 790005d..a3203a7 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -302,16 +302,15 @@
return uvSize;
}
-
static size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
- const Type *type, uint8_t *ptr) {
+ const Type *type, uint8_t *ptr, size_t requiredAlignment) {
alloc->mHal.drvState.lod[0].dimX = type->getDimX();
alloc->mHal.drvState.lod[0].dimY = type->getDimY();
alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
alloc->mHal.drvState.lod[0].mallocPtr = 0;
- // Stride needs to be 16-byte aligned too!
+ // Stride needs to be aligned to a boundary defined by requiredAlignment!
size_t stride = alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
- alloc->mHal.drvState.lod[0].stride = rsRound(stride, 16);
+ alloc->mHal.drvState.lod[0].stride = rsRound(stride, requiredAlignment);
alloc->mHal.drvState.lodCount = type->getLODCount();
alloc->mHal.drvState.faceCount = type->getDimFaces();
@@ -335,7 +334,7 @@
alloc->mHal.drvState.lod[lod].dimY = ty;
alloc->mHal.drvState.lod[lod].dimZ = tz;
alloc->mHal.drvState.lod[lod].stride =
- rsRound(tx * type->getElementSizeBytes(), 16);
+ rsRound(tx * type->getElementSizeBytes(), requiredAlignment);
offsets[lod] = o;
o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
if (tx > 1) tx >>= 1;
@@ -359,9 +358,14 @@
return allocSize;
}
-static uint8_t* allocAlignedMemory(size_t allocSize, bool forceZero) {
- // We align all allocations to a 16-byte boundary.
- uint8_t* ptr = (uint8_t *)memalign(16, allocSize);
+static size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
+ const Type *type, uint8_t *ptr) {
+ return AllocationBuildPointerTable(rsc, alloc, type, ptr, Allocation::kMinimumRSAlignment);
+}
+
+static uint8_t* allocAlignedMemory(size_t allocSize, bool forceZero, size_t requiredAlignment) {
+ // We align all allocations to a boundary defined by requiredAlignment.
+ uint8_t* ptr = (uint8_t *)memalign(requiredAlignment, allocSize);
if (!ptr) {
return nullptr;
}
@@ -371,15 +375,20 @@
return ptr;
}
-bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
+bool rsdAllocationInitStrided(const Context *rsc, Allocation *alloc, bool forceZero, size_t requiredAlignment) {
DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
if (!drv) {
return false;
}
alloc->mHal.drv = drv;
+ // Check if requiredAlignment is power of 2, also requiredAlignment should be larger or equal than kMinimumRSAlignment.
+ if ((requiredAlignment & (requiredAlignment-1)) != 0 || requiredAlignment < Allocation::kMinimumRSAlignment) {
+ ALOGE("requiredAlignment must be power of 2");
+ return false;
+ }
// Calculate the object size.
- size_t allocSize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), nullptr);
+ size_t allocSize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), nullptr, requiredAlignment);
uint8_t * ptr = nullptr;
if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
@@ -387,6 +396,20 @@
} else if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
// Allocation is allocated when the surface is created
// in getSurface
+#ifdef RS_COMPATIBILITY_LIB
+ } else if (alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_INCREMENTAL_SUPPORT | RS_ALLOCATION_USAGE_SHARED)) {
+ if (alloc->mHal.state.userProvidedPtr == nullptr) {
+ ALOGE("User-backed buffer pointer cannot be null");
+ return false;
+ }
+ if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
+ ALOGE("User-allocated buffers must not have multiple faces or LODs");
+ return false;
+ }
+
+ drv->useUserProvidedPtr = true;
+ ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
+#endif
} else if (alloc->mHal.state.userProvidedPtr != nullptr) {
// user-provided allocation
// limitations: no faces, no LOD, USAGE_SCRIPT or SCRIPT+TEXTURE only
@@ -400,13 +423,13 @@
return false;
}
- // rows must be 16-byte aligned
+ // rows must be aligned based on requiredAlignment.
// validate that here, otherwise fall back to not use the user-backed allocation
- if (((alloc->getType()->getDimX() * alloc->getType()->getElement()->getSizeBytes()) % 16) != 0) {
+ if (((alloc->getType()->getDimX() * alloc->getType()->getElement()->getSizeBytes()) % requiredAlignment) != 0) {
ALOGV("User-backed allocation failed stride requirement, falling back to separate allocation");
drv->useUserProvidedPtr = false;
- ptr = allocAlignedMemory(allocSize, forceZero);
+ ptr = allocAlignedMemory(allocSize, forceZero, requiredAlignment);
if (!ptr) {
alloc->mHal.drv = nullptr;
free(drv);
@@ -418,7 +441,7 @@
ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
}
} else {
- ptr = allocAlignedMemory(allocSize, forceZero);
+ ptr = allocAlignedMemory(allocSize, forceZero, requiredAlignment);
if (!ptr) {
alloc->mHal.drv = nullptr;
free(drv);
@@ -426,7 +449,7 @@
}
}
// Build the pointer tables
- size_t verifySize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), ptr);
+ size_t verifySize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), ptr, requiredAlignment);
if(allocSize != verifySize) {
rsAssert(!"Size mismatch");
}
@@ -476,6 +499,10 @@
return true;
}
+bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
+ return rsdAllocationInitStrided(rsc, alloc, forceZero, Allocation::kMinimumRSAlignment);
+}
+
void rsdAllocationAdapterOffset(const Context *rsc, const Allocation *alloc) {
//ALOGE("rsdAllocationAdapterOffset");