Add alignment requirements with USAGE_SHARED.
Change-Id: I844e37ad29a893b6e35834588a5d80e52d8bf61b
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index aacdac3..b618536 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -288,6 +288,18 @@
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);
+ if (!ptr) {
+ return NULL;
+ }
+ if (forceZero) {
+ memset(ptr, 0, allocSize);
+ }
+ return ptr;
+}
+
bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
if (!drv) {
@@ -311,18 +323,31 @@
ALOGE("User-allocated buffers must not have multiple faces or LODs");
return false;
}
- ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
+
+ // rows must be 16-byte aligned
+ // validate that here, otherwise fall back to not use the user-backed allocation
+ if (((alloc->getType()->getDimX() * alloc->getType()->getElement()->getSizeBytes()) % 16) != 0) {
+ ALOGV("User-backed allocation failed stride requirement, falling back to separate allocation");
+ drv->useUserProvidedPtr = false;
+
+ ptr = allocAlignedMemory(allocSize, forceZero);
+ if (!ptr) {
+ alloc->mHal.drv = NULL;
+ free(drv);
+ return false;
+ }
+
+ } else {
+ drv->useUserProvidedPtr = true;
+ ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
+ }
} else {
- // We align all allocations to a 16-byte boundary.
- ptr = (uint8_t *)memalign(16, allocSize);
+ ptr = allocAlignedMemory(allocSize, forceZero);
if (!ptr) {
alloc->mHal.drv = NULL;
free(drv);
return false;
}
- if (forceZero) {
- memset(ptr, 0, allocSize);
- }
}
// Build the pointer tables
size_t verifySize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), ptr);
@@ -358,6 +383,11 @@
drv->readBackFBO = NULL;
+ // fill out the initial state of the buffer if we couldn't use the user-provided ptr and USAGE_SHARED was accepted
+ if ((alloc->mHal.state.userProvidedPtr != 0) && (drv->useUserProvidedPtr == false)) {
+ rsdAllocationData2D(rsc, alloc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, alloc->getType()->getDimX(), alloc->getType()->getDimY(), alloc->mHal.state.userProvidedPtr, allocSize, 0);
+ }
+
return true;
}
@@ -383,7 +413,7 @@
if (alloc->mHal.drvState.lod[0].mallocPtr) {
// don't free user-allocated ptrs
- if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED)) {
+ if (!(drv->useUserProvidedPtr)) {
free(alloc->mHal.drvState.lod[0].mallocPtr);
}
alloc->mHal.drvState.lod[0].mallocPtr = NULL;