Function map

Synopsis

#include <Source/Falcor/Core/API/Buffer.h>

void * map(MapType Type)

Description

Map the buffer.

The low-level behavior depends on MapType and the CpuAccess flags of the buffer:

  • For CPU accessible buffers, the caller should ensure CPU/GPU memory accesses do not conflict.
  • For GPU-only buffers, map for read will create an internal staging buffer that is safe to read.
  • Mapping a CPU write buffer for WriteDiscard will cause the buffer to be internally re-allocated, causing its address range to change and invalidating all previous views to the buffer.

Source

Lines 253-317 in Source/Falcor/Core/API/Buffer.cpp. Line 243 in Source/Falcor/Core/API/Buffer.h.

void* Buffer::map(MapType type)
{
    if (type == MapType::Write)
    {
        if (mCpuAccess != CpuAccess::Write)
        {
            logError("Trying to map a buffer for write, but it wasn't created with the write permissions");
            return nullptr;
        }
        return mDynamicData.pData;
    }
    else 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->getUploadHeap()->release(mDynamicData);
        }
        mpCBV = nullptr;
        mDynamicData = gpDevice->getUploadHeap()->allocate(mSize, getBufferDataAlignment(this));
        mApiHandle = mDynamicData.pResourceHandle;
        mGpuVaOffset = mDynamicData.offset;
        invalidateViews();
        return mDynamicData.pData;
    }
    else
    {
        assert(type == MapType::Read);
        if (mCpuAccess == CpuAccess::Write)
        {
            // Buffers on the upload heap are already mapped, just return the ptr.
            assert(mDynamicData.pResourceHandle);
            assert(mDynamicData.pData);
            return mDynamicData.pData;
        }
        else if (mCpuAccess == CpuAccess::Read)
        {
            assert(mBindFlags == BindFlags::None);
            return mapBufferApi(mApiHandle, mSize);
        }
        else
        {
            // For buffers without CPU access we must copy the contents to a staging buffer.
            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();
            assert(mGpuVaOffset == 0);
            pContext->copyResource(mpStagingResource.get(), this);
            pContext->flush(true);
            return mpStagingResource->map(MapType::Read);
        }
    }
}





Add Discussion as Guest

Log in to DocsForge