rsovAllocation.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "rsovAllocation.h"
  17. #include "rsAllocation.h"
  18. #include "rsContext.h"
  19. #include "rsCppUtils.h"
  20. #include "rsElement.h"
  21. #include "rsType.h"
  22. #include "rsovContext.h"
  23. #include "rsovCore.h"
  24. namespace android {
  25. namespace renderscript {
  26. namespace rsov {
  27. namespace {
  28. size_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
  29. // For the flexible YCbCr format, layout is initialized during call to
  30. // Allocation::ioReceive. Return early and avoid clobberring any
  31. // pre-existing layout.
  32. if (yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
  33. return 0;
  34. }
  35. // YUV only supports basic 2d
  36. // so we can stash the plane pointers in the mipmap levels.
  37. size_t uvSize = 0;
  38. state->lod[1].dimX = state->lod[0].dimX / 2;
  39. state->lod[1].dimY = state->lod[0].dimY / 2;
  40. state->lod[2].dimX = state->lod[0].dimX / 2;
  41. state->lod[2].dimY = state->lod[0].dimY / 2;
  42. state->yuv.shift = 1;
  43. state->yuv.step = 1;
  44. state->lodCount = 3;
  45. switch (yuv) {
  46. case HAL_PIXEL_FORMAT_YV12:
  47. state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
  48. state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
  49. (state->lod[0].stride * state->lod[0].dimY);
  50. uvSize += state->lod[2].stride * state->lod[2].dimY;
  51. state->lod[1].stride = state->lod[2].stride;
  52. state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
  53. (state->lod[2].stride * state->lod[2].dimY);
  54. uvSize += state->lod[1].stride * state->lod[2].dimY;
  55. break;
  56. case HAL_PIXEL_FORMAT_YCrCb_420_SP: // NV21
  57. // state->lod[1].dimX = state->lod[0].dimX;
  58. state->lod[1].stride = state->lod[0].stride;
  59. state->lod[2].stride = state->lod[0].stride;
  60. state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
  61. (state->lod[0].stride * state->lod[0].dimY);
  62. state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) + 1;
  63. uvSize += state->lod[1].stride * state->lod[1].dimY;
  64. state->yuv.step = 2;
  65. break;
  66. default:
  67. rsAssert(0);
  68. }
  69. return uvSize;
  70. }
  71. // TODO: Dedup this with the same code under frameworks/rs/driver
  72. size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
  73. const Type *type, uint8_t *ptr,
  74. size_t requiredAlignment) {
  75. alloc->mHal.drvState.lod[0].dimX = type->getDimX();
  76. alloc->mHal.drvState.lod[0].dimY = type->getDimY();
  77. alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
  78. alloc->mHal.drvState.lod[0].mallocPtr = 0;
  79. // Stride needs to be aligned to a boundary defined by requiredAlignment!
  80. size_t stride =
  81. alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
  82. alloc->mHal.drvState.lod[0].stride = rsRound(stride, requiredAlignment);
  83. alloc->mHal.drvState.lodCount = type->getLODCount();
  84. alloc->mHal.drvState.faceCount = type->getDimFaces();
  85. size_t offsets[Allocation::MAX_LOD];
  86. memset(offsets, 0, sizeof(offsets));
  87. size_t o = alloc->mHal.drvState.lod[0].stride *
  88. rsMax(alloc->mHal.drvState.lod[0].dimY, 1u) *
  89. rsMax(alloc->mHal.drvState.lod[0].dimZ, 1u);
  90. if (alloc->mHal.state.yuv) {
  91. o += DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
  92. for (uint32_t ct = 1; ct < alloc->mHal.drvState.lodCount; ct++) {
  93. offsets[ct] = (size_t)alloc->mHal.drvState.lod[ct].mallocPtr;
  94. }
  95. } else if (alloc->mHal.drvState.lodCount > 1) {
  96. uint32_t tx = alloc->mHal.drvState.lod[0].dimX;
  97. uint32_t ty = alloc->mHal.drvState.lod[0].dimY;
  98. uint32_t tz = alloc->mHal.drvState.lod[0].dimZ;
  99. for (uint32_t lod = 1; lod < alloc->mHal.drvState.lodCount; lod++) {
  100. alloc->mHal.drvState.lod[lod].dimX = tx;
  101. alloc->mHal.drvState.lod[lod].dimY = ty;
  102. alloc->mHal.drvState.lod[lod].dimZ = tz;
  103. alloc->mHal.drvState.lod[lod].stride =
  104. rsRound(tx * type->getElementSizeBytes(), requiredAlignment);
  105. offsets[lod] = o;
  106. o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
  107. if (tx > 1) tx >>= 1;
  108. if (ty > 1) ty >>= 1;
  109. if (tz > 1) tz >>= 1;
  110. }
  111. }
  112. alloc->mHal.drvState.faceOffset = o;
  113. alloc->mHal.drvState.lod[0].mallocPtr = ptr;
  114. for (uint32_t lod = 1; lod < alloc->mHal.drvState.lodCount; lod++) {
  115. alloc->mHal.drvState.lod[lod].mallocPtr = ptr + offsets[lod];
  116. }
  117. size_t allocSize = alloc->mHal.drvState.faceOffset;
  118. if (alloc->mHal.drvState.faceCount) {
  119. allocSize *= 6;
  120. }
  121. return allocSize;
  122. }
  123. size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
  124. const Type *type, uint8_t *ptr) {
  125. return AllocationBuildPointerTable(rsc, alloc, type, ptr,
  126. Allocation::kMinimumRSAlignment);
  127. }
  128. uint8_t *GetOffsetPtr(const Allocation *alloc, uint32_t xoff, uint32_t yoff,
  129. uint32_t zoff, uint32_t lod,
  130. RsAllocationCubemapFace face) {
  131. uint8_t *ptr = (uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
  132. ptr += face * alloc->mHal.drvState.faceOffset;
  133. ptr += zoff * alloc->mHal.drvState.lod[lod].dimY *
  134. alloc->mHal.drvState.lod[lod].stride;
  135. ptr += yoff * alloc->mHal.drvState.lod[lod].stride;
  136. ptr += xoff * alloc->mHal.state.elementSizeBytes;
  137. return ptr;
  138. }
  139. void mip565(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
  140. uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
  141. uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
  142. for (uint32_t y = 0; y < h; y++) {
  143. uint16_t *oPtr = (uint16_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
  144. const uint16_t *i1 =
  145. (uint16_t *)GetOffsetPtr(alloc, 0, 0, y * 2, lod, face);
  146. const uint16_t *i2 =
  147. (uint16_t *)GetOffsetPtr(alloc, 0, 0, y * 2 + 1, lod, face);
  148. for (uint32_t x = 0; x < w; x++) {
  149. *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
  150. oPtr++;
  151. i1 += 2;
  152. i2 += 2;
  153. }
  154. }
  155. }
  156. void mip8888(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
  157. uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
  158. uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
  159. for (uint32_t y = 0; y < h; y++) {
  160. uint32_t *oPtr = (uint32_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
  161. const uint32_t *i1 =
  162. (uint32_t *)GetOffsetPtr(alloc, 0, y * 2, 0, lod, face);
  163. const uint32_t *i2 =
  164. (uint32_t *)GetOffsetPtr(alloc, 0, y * 2 + 1, 0, lod, face);
  165. for (uint32_t x = 0; x < w; x++) {
  166. *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
  167. oPtr++;
  168. i1 += 2;
  169. i2 += 2;
  170. }
  171. }
  172. }
  173. void mip8(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
  174. uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
  175. uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;
  176. for (uint32_t y = 0; y < h; y++) {
  177. uint8_t *oPtr = GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
  178. const uint8_t *i1 = GetOffsetPtr(alloc, 0, y * 2, 0, lod, face);
  179. const uint8_t *i2 = GetOffsetPtr(alloc, 0, y * 2 + 1, 0, lod, face);
  180. for (uint32_t x = 0; x < w; x++) {
  181. *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
  182. oPtr++;
  183. i1 += 2;
  184. i2 += 2;
  185. }
  186. }
  187. }
  188. } // anonymous namespace
  189. RSoVAllocation::RSoVAllocation(RSoVContext *context, const Type *type,
  190. size_t bufferSize)
  191. : mBuffer(new RSoVBuffer(context, bufferSize)),
  192. mType(type),
  193. mWidth(type->getDimX()),
  194. mHeight(type->getDimY()),
  195. mDepth(type->getDimZ()) {}
  196. RSoVBuffer::RSoVBuffer(RSoVContext *context, size_t size)
  197. : mRSoV(context), mDevice(context->getDevice()) {
  198. InitBuffer(size);
  199. }
  200. RSoVBuffer::~RSoVBuffer() {
  201. vkUnmapMemory(mDevice, mMem);
  202. vkDestroyBuffer(mDevice, mBuf, nullptr);
  203. vkFreeMemory(mDevice, mMem, nullptr);
  204. }
  205. void RSoVBuffer::InitBuffer(size_t bufferSize) {
  206. VkResult res;
  207. VkBufferCreateInfo buf_info = {
  208. .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
  209. .pNext = nullptr,
  210. .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
  211. .size = bufferSize,
  212. .queueFamilyIndexCount = 0,
  213. .pQueueFamilyIndices = nullptr,
  214. .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
  215. .flags = 0,
  216. };
  217. res = vkCreateBuffer(mDevice, &buf_info, nullptr, &mBuf);
  218. rsAssert(res == VK_SUCCESS);
  219. VkMemoryRequirements mem_reqs;
  220. vkGetBufferMemoryRequirements(mDevice, mBuf, &mem_reqs);
  221. VkMemoryAllocateInfo allocateInfo = {
  222. .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
  223. .pNext = nullptr,
  224. .memoryTypeIndex = 0,
  225. .allocationSize = mem_reqs.size,
  226. };
  227. bool pass;
  228. pass =
  229. mRSoV->MemoryTypeFromProperties(mem_reqs.memoryTypeBits,
  230. VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
  231. VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
  232. &allocateInfo.memoryTypeIndex);
  233. rsAssert(pass);
  234. // TODO: Make this aligned
  235. res = vkAllocateMemory(mDevice, &allocateInfo, nullptr, &mMem);
  236. rsAssert(res == VK_SUCCESS);
  237. res = vkBindBufferMemory(mDevice, mBuf, mMem, 0);
  238. rsAssert(res == VK_SUCCESS);
  239. mBufferInfo.buffer = mBuf;
  240. mBufferInfo.offset = 0;
  241. mBufferInfo.range = bufferSize;
  242. res = vkMapMemory(mDevice, mMem, 0, mem_reqs.size, 0, (void **)&mPtr);
  243. rsAssert(res == VK_SUCCESS);
  244. }
  245. } // namespace rsov
  246. } // namespace renderscript
  247. } // namespace android
  248. using android::renderscript::Allocation;
  249. using android::renderscript::Context;
  250. using android::renderscript::Element;
  251. using android::renderscript::Type;
  252. using android::renderscript::rs_allocation;
  253. using android::renderscript::rsMax;
  254. using namespace android::renderscript::rsov;
  255. bool rsovAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
  256. RSoVHal *hal = static_cast<RSoVHal *>(rsc->mHal.drv);
  257. RSoVContext *rsov = hal->mRSoV;
  258. const Type *type = alloc->getType();
  259. // Calculate the object size.
  260. size_t allocSize = AllocationBuildPointerTable(rsc, alloc, type, nullptr);
  261. RSoVAllocation *rsovAlloc = new RSoVAllocation(rsov, type, allocSize);
  262. alloc->mHal.drv = rsovAlloc;
  263. AllocationBuildPointerTable(rsc, alloc, type,
  264. (uint8_t *)rsovAlloc->getHostPtr());
  265. return true;
  266. }
  267. void rsovAllocationDestroy(const Context *rsc, Allocation *alloc) {
  268. RSoVAllocation *rsovAlloc = static_cast<RSoVAllocation *>(alloc->mHal.drv);
  269. delete rsovAlloc;
  270. alloc->mHal.drv = nullptr;
  271. }
  272. void rsovAllocationData1D(const Context *rsc, const Allocation *alloc,
  273. uint32_t xoff, uint32_t lod, size_t count,
  274. const void *data, size_t sizeBytes) {
  275. const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
  276. uint8_t *ptr =
  277. GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  278. size_t size = count * eSize;
  279. if (ptr != data) {
  280. // Skip the copy if we are the same allocation. This can arise from
  281. // our Bitmap optimization, where we share the same storage.
  282. if (alloc->mHal.state.hasReferences) {
  283. alloc->incRefs(data, count);
  284. alloc->decRefs(ptr, count);
  285. }
  286. memcpy(ptr, data, size);
  287. }
  288. }
  289. void rsovAllocationData2D(const Context *rsc, const Allocation *alloc,
  290. uint32_t xoff, uint32_t yoff, uint32_t lod,
  291. RsAllocationCubemapFace face, uint32_t w, uint32_t h,
  292. const void *data, size_t sizeBytes, size_t stride) {
  293. size_t eSize = alloc->mHal.state.elementSizeBytes;
  294. size_t lineSize = eSize * w;
  295. if (!stride) {
  296. stride = lineSize;
  297. }
  298. if (alloc->mHal.drvState.lod[0].mallocPtr) {
  299. const uint8_t *src = static_cast<const uint8_t *>(data);
  300. uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
  301. for (uint32_t line = yoff; line < (yoff + h); line++) {
  302. if (alloc->mHal.state.hasReferences) {
  303. alloc->incRefs(src, w);
  304. alloc->decRefs(dst, w);
  305. }
  306. memcpy(dst, src, lineSize);
  307. src += stride;
  308. dst += alloc->mHal.drvState.lod[lod].stride;
  309. }
  310. // TODO: handle YUV Allocations
  311. if (alloc->mHal.state.yuv) {
  312. size_t clineSize = lineSize;
  313. int lod = 1;
  314. int maxLod = 2;
  315. if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YV12) {
  316. maxLod = 3;
  317. clineSize >>= 1;
  318. } else if (alloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
  319. lod = 2;
  320. maxLod = 3;
  321. }
  322. while (lod < maxLod) {
  323. uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
  324. for (uint32_t line = (yoff >> 1); line < ((yoff + h) >> 1); line++) {
  325. memcpy(dst, src, clineSize);
  326. // When copying from an array to an Allocation, the src pointer
  327. // to the array should just move by the number of bytes copied.
  328. src += clineSize;
  329. dst += alloc->mHal.drvState.lod[lod].stride;
  330. }
  331. lod++;
  332. }
  333. }
  334. }
  335. }
  336. void rsovAllocationData3D(const Context *rsc, const Allocation *alloc,
  337. uint32_t xoff, uint32_t yoff, uint32_t zoff,
  338. uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
  339. const void *data, size_t sizeBytes, size_t stride) {
  340. uint32_t eSize = alloc->mHal.state.elementSizeBytes;
  341. uint32_t lineSize = eSize * w;
  342. if (!stride) {
  343. stride = lineSize;
  344. }
  345. if (alloc->mHal.drvState.lod[0].mallocPtr) {
  346. const uint8_t *src = static_cast<const uint8_t *>(data);
  347. for (uint32_t z = zoff; z < (d + zoff); z++) {
  348. uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, z, lod,
  349. RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  350. for (uint32_t line = yoff; line < (yoff + h); line++) {
  351. if (alloc->mHal.state.hasReferences) {
  352. alloc->incRefs(src, w);
  353. alloc->decRefs(dst, w);
  354. }
  355. memcpy(dst, src, lineSize);
  356. src += stride;
  357. dst += alloc->mHal.drvState.lod[lod].stride;
  358. }
  359. }
  360. }
  361. }
  362. void rsovAllocationRead1D(const Context *rsc, const Allocation *alloc,
  363. uint32_t xoff, uint32_t lod, size_t count, void *data,
  364. size_t sizeBytes) {
  365. const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
  366. const uint8_t *ptr =
  367. GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  368. if (data != ptr) {
  369. // Skip the copy if we are the same allocation. This can arise from
  370. // our Bitmap optimization, where we share the same storage.
  371. memcpy(data, ptr, count * eSize);
  372. }
  373. }
  374. void rsovAllocationRead2D(const Context *rsc, const Allocation *alloc,
  375. uint32_t xoff, uint32_t yoff, uint32_t lod,
  376. RsAllocationCubemapFace face, uint32_t w, uint32_t h,
  377. void *data, size_t sizeBytes, size_t stride) {
  378. size_t eSize = alloc->mHal.state.elementSizeBytes;
  379. size_t lineSize = eSize * w;
  380. if (!stride) {
  381. stride = lineSize;
  382. }
  383. if (alloc->mHal.drvState.lod[0].mallocPtr) {
  384. uint8_t *dst = static_cast<uint8_t *>(data);
  385. const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
  386. if (dst == src) {
  387. // Skip the copy if we are the same allocation. This can arise from
  388. // our Bitmap optimization, where we share the same storage.
  389. return;
  390. }
  391. for (uint32_t line = yoff; line < (yoff + h); line++) {
  392. memcpy(dst, src, lineSize);
  393. dst += stride;
  394. src += alloc->mHal.drvState.lod[lod].stride;
  395. }
  396. } else {
  397. ALOGE("Add code to readback from non-script memory");
  398. }
  399. }
  400. void rsovAllocationRead3D(const Context *rsc, const Allocation *alloc,
  401. uint32_t xoff, uint32_t yoff, uint32_t zoff,
  402. uint32_t lod, uint32_t w, uint32_t h, uint32_t d,
  403. void *data, size_t sizeBytes, size_t stride) {
  404. uint32_t eSize = alloc->mHal.state.elementSizeBytes;
  405. uint32_t lineSize = eSize * w;
  406. if (!stride) {
  407. stride = lineSize;
  408. }
  409. if (alloc->mHal.drvState.lod[0].mallocPtr) {
  410. uint8_t *dst = static_cast<uint8_t *>(data);
  411. for (uint32_t z = zoff; z < (d + zoff); z++) {
  412. const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, z, lod,
  413. RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  414. if (dst == src) {
  415. // Skip the copy if we are the same allocation. This can arise from
  416. // our Bitmap optimization, where we share the same storage.
  417. return;
  418. }
  419. for (uint32_t line = yoff; line < (yoff + h); line++) {
  420. memcpy(dst, src, lineSize);
  421. dst += stride;
  422. src += alloc->mHal.drvState.lod[lod].stride;
  423. }
  424. }
  425. }
  426. }
  427. void *rsovAllocationLock1D(const Context *rsc, const Allocation *alloc) {
  428. return alloc->mHal.drvState.lod[0].mallocPtr;
  429. }
  430. void rsovAllocationUnlock1D(const Context *rsc, const Allocation *alloc) {}
  431. void rsovAllocationData1D_alloc(const Context *rsc, const Allocation *dstAlloc,
  432. uint32_t dstXoff, uint32_t dstLod, size_t count,
  433. const Allocation *srcAlloc, uint32_t srcXoff,
  434. uint32_t srcLod) {}
  435. void rsovAllocationData2D_alloc_script(
  436. const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
  437. uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
  438. uint32_t w, uint32_t h, const Allocation *srcAlloc, uint32_t srcXoff,
  439. uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) {
  440. size_t elementSize = dstAlloc->getType()->getElementSizeBytes();
  441. for (uint32_t i = 0; i < h; i++) {
  442. uint8_t *dstPtr =
  443. GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, 0, dstLod, dstFace);
  444. uint8_t *srcPtr =
  445. GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, 0, srcLod, srcFace);
  446. memcpy(dstPtr, srcPtr, w * elementSize);
  447. }
  448. }
  449. void rsovAllocationData3D_alloc_script(
  450. const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
  451. uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod, uint32_t w, uint32_t h,
  452. uint32_t d, const Allocation *srcAlloc, uint32_t srcXoff, uint32_t srcYoff,
  453. uint32_t srcZoff, uint32_t srcLod) {
  454. uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
  455. for (uint32_t j = 0; j < d; j++) {
  456. for (uint32_t i = 0; i < h; i++) {
  457. uint8_t *dstPtr =
  458. GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstZoff + j, dstLod,
  459. RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  460. uint8_t *srcPtr =
  461. GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcZoff + j, srcLod,
  462. RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  463. memcpy(dstPtr, srcPtr, w * elementSize);
  464. }
  465. }
  466. }
  467. void rsovAllocationData2D_alloc(
  468. const Context *rsc, const Allocation *dstAlloc, uint32_t dstXoff,
  469. uint32_t dstYoff, uint32_t dstLod, RsAllocationCubemapFace dstFace,
  470. uint32_t w, uint32_t h, const Allocation *srcAlloc, uint32_t srcXoff,
  471. uint32_t srcYoff, uint32_t srcLod, RsAllocationCubemapFace srcFace) {
  472. if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
  473. rsc->setError(RS_ERROR_FATAL_DRIVER,
  474. "Non-script allocation copies not "
  475. "yet implemented.");
  476. return;
  477. }
  478. rsovAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstLod,
  479. dstFace, w, h, srcAlloc, srcXoff, srcYoff,
  480. srcLod, srcFace);
  481. }
  482. void rsovAllocationData3D_alloc(const Context *rsc, const Allocation *dstAlloc,
  483. uint32_t dstXoff, uint32_t dstYoff,
  484. uint32_t dstZoff, uint32_t dstLod, uint32_t w,
  485. uint32_t h, uint32_t d,
  486. const Allocation *srcAlloc, uint32_t srcXoff,
  487. uint32_t srcYoff, uint32_t srcZoff,
  488. uint32_t srcLod) {
  489. if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
  490. rsc->setError(RS_ERROR_FATAL_DRIVER,
  491. "Non-script allocation copies not "
  492. "yet implemented.");
  493. return;
  494. }
  495. rsovAllocationData3D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstZoff,
  496. dstLod, w, h, d, srcAlloc, srcXoff, srcYoff,
  497. srcZoff, srcLod);
  498. }
  499. void rsovAllocationAdapterOffset(const Context *rsc, const Allocation *alloc) {
  500. // Get a base pointer to the new LOD
  501. const Allocation *base = alloc->mHal.state.baseAlloc;
  502. const Type *type = alloc->mHal.state.type;
  503. if (base == nullptr) {
  504. return;
  505. }
  506. const int lodBias = alloc->mHal.state.originLOD;
  507. uint32_t lodCount = rsMax(alloc->mHal.drvState.lodCount, (uint32_t)1);
  508. for (uint32_t lod = 0; lod < lodCount; lod++) {
  509. alloc->mHal.drvState.lod[lod] = base->mHal.drvState.lod[lod + lodBias];
  510. alloc->mHal.drvState.lod[lod].mallocPtr = GetOffsetPtr(
  511. alloc, alloc->mHal.state.originX, alloc->mHal.state.originY,
  512. alloc->mHal.state.originZ, lodBias,
  513. (RsAllocationCubemapFace)alloc->mHal.state.originFace);
  514. }
  515. }
  516. bool rsovAllocationAdapterInit(const Context *rsc, Allocation *alloc) {
  517. // TODO: may need a RSoV Allocation here
  518. #if 0
  519. DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
  520. if (!drv) {
  521. return false;
  522. }
  523. alloc->mHal.drv = drv;
  524. #endif
  525. // We need to build an allocation that looks like a subset of the parent
  526. // allocation
  527. rsovAllocationAdapterOffset(rsc, alloc);
  528. return true;
  529. }
  530. void rsovAllocationSyncAll(const Context *rsc, const Allocation *alloc,
  531. RsAllocationUsageType src) {
  532. // TODO: anything to do here?
  533. }
  534. void rsovAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
  535. // TODO: anything to do here?
  536. }
  537. void rsovAllocationResize(const Context *rsc, const Allocation *alloc,
  538. const Type *newType, bool zeroNew) {
  539. // TODO: implement this
  540. // can this be done without copying, if the new size is greater than the
  541. // original?
  542. }
  543. void rsovAllocationGenerateMipmaps(const Context *rsc,
  544. const Allocation *alloc) {
  545. if (!alloc->mHal.drvState.lod[0].mallocPtr) {
  546. return;
  547. }
  548. uint32_t numFaces = alloc->getType()->getDimFaces() ? 6 : 1;
  549. for (uint32_t face = 0; face < numFaces; face++) {
  550. for (uint32_t lod = 0; lod < (alloc->getType()->getLODCount() - 1); lod++) {
  551. switch (alloc->getType()->getElement()->getSizeBits()) {
  552. case 32:
  553. mip8888(alloc, lod, (RsAllocationCubemapFace)face);
  554. break;
  555. case 16:
  556. mip565(alloc, lod, (RsAllocationCubemapFace)face);
  557. break;
  558. case 8:
  559. mip8(alloc, lod, (RsAllocationCubemapFace)face);
  560. break;
  561. }
  562. }
  563. }
  564. }
  565. uint32_t rsovAllocationGrallocBits(const Context *rsc, Allocation *alloc) {
  566. return 0;
  567. }
  568. void rsovAllocationUpdateCachedObject(const Context *rsc,
  569. const Allocation *alloc,
  570. rs_allocation *obj) {
  571. obj->p = alloc;
  572. #ifdef __LP64__
  573. obj->unused1 = nullptr;
  574. obj->unused2 = nullptr;
  575. obj->unused3 = nullptr;
  576. #endif
  577. }
  578. void rsovAllocationSetSurface(const Context *rsc, Allocation *alloc,
  579. ANativeWindow *nw) {
  580. // TODO: implement this
  581. }
  582. void rsovAllocationIoSend(const Context *rsc, Allocation *alloc) {
  583. // TODO: implement this
  584. }
  585. void rsovAllocationIoReceive(const Context *rsc, Allocation *alloc) {
  586. // TODO: implement this
  587. }
  588. void rsovAllocationElementData(const Context *rsc, const Allocation *alloc,
  589. uint32_t x, uint32_t y, uint32_t z,
  590. const void *data, uint32_t cIdx,
  591. size_t sizeBytes) {
  592. uint8_t *ptr =
  593. GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  594. const Element *e = alloc->mHal.state.type->getElement()->getField(cIdx);
  595. ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
  596. if (alloc->mHal.state.hasReferences) {
  597. e->incRefs(data);
  598. e->decRefs(ptr);
  599. }
  600. memcpy(ptr, data, sizeBytes);
  601. }
  602. void rsovAllocationElementRead(const Context *rsc, const Allocation *alloc,
  603. uint32_t x, uint32_t y, uint32_t z, void *data,
  604. uint32_t cIdx, size_t sizeBytes) {
  605. uint8_t *ptr =
  606. GetOffsetPtr(alloc, x, y, z, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
  607. const Element *e = alloc->mHal.state.type->getElement()->getField(cIdx);
  608. ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
  609. memcpy(data, ptr, sizeBytes);
  610. }