static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
    if (!alloc->getIsScript()) {
        return; // nothing to sync
    }

    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
    RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;

    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
    if (!drv->textureID && !drv->renderTargetID) {
        return; // nothing was rendered here yet, so nothing to sync
    }
    if (drv->readBackFBO == NULL) {
        drv->readBackFBO = new RsdFrameBufferObj();
        drv->readBackFBO->setColorTarget(drv, 0);
        drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
                                        alloc->getType()->getDimY());
    }

    // Bind the framebuffer object so we can read back from it
    drv->readBackFBO->setActive(rsc);

    // Do the readback
    RSD_CALL_GL(glReadPixels, 0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(),
                 drv->glFormat, drv->glType, alloc->getPtr());

    // Revert framebuffer to its original
    lastFbo->setActive(rsc);
}
void setDepthAttachment(const Context *rsc, const FBOCache *fb) {
    RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv;

    DrvAllocation *depth = nullptr;
    if (fb->mHal.state.depthTarget != nullptr) {
        depth = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv;

        if (depth->uploadDeferred) {
            rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget,
                                 RS_ALLOCATION_USAGE_SCRIPT);
        }
    }
    fbo->setDepthTarget(depth);
}
void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) {
    setDepthAttachment(rsc, fb);
    setColorAttachment(rsc, fb);

    RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv;
    if (fb->mHal.state.colorTargets[0]) {
        fbo->setDimensions(fb->mHal.state.colorTargets[0]->getType()->getDimX(),
                           fb->mHal.state.colorTargets[0]->getType()->getDimY());
    } else if (fb->mHal.state.depthTarget) {
        fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(),
                           fb->mHal.state.depthTarget->getType()->getDimY());
    }

    fbo->setActive(rsc);
}
void setColorAttachment(const Context *rsc, const FBOCache *fb) {
    RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv;
    // Now attach color targets
    for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
        DrvAllocation *color = nullptr;
        if (fb->mHal.state.colorTargets[i] != nullptr) {
            color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv;

            if (color->uploadDeferred) {
                rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i],
                                     RS_ALLOCATION_USAGE_SCRIPT);
            }
        }
        fbo->setColorTarget(color, i);
    }
}