void* Buffer::map(MapType type) { if (type == MapType::WriteDiscard) { if (mCpuAccess != CpuAccess::Write) { logError("Trying to map a buffer for write, but it wasn't created with the write permissions"); return nullptr; } // Allocate a new buffer if (mDynamicData.pResourceHandle) { gpDevice->getResourceAllocator()->release(mDynamicData); } mDynamicData = gpDevice->getResourceAllocator()->allocate(mSize, getBufferDataAlignment(this)); mApiHandle = mDynamicData.pResourceHandle; invalidateViews(); return mDynamicData.pData; } else { assert(type == MapType::Read); if (mBindFlags == BindFlags::None) { return mapBufferApi(mApiHandle, mSize); } else { logWarning("Buffer::map() performance warning - using staging resource which require us to flush the pipeline and wait for the GPU to finish its work"); if (mpStagingResource == nullptr) { mpStagingResource = Buffer::create(mSize, Buffer::BindFlags::None, Buffer::CpuAccess::Read, nullptr); } // Copy the buffer and flush the pipeline RenderContext* pContext = gpDevice->getRenderContext().get(); pContext->copyResource(mpStagingResource.get(), this); pContext->flush(true); return mpStagingResource->map(MapType::Read); } } }