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