Метод ID3D12Resource::Map (d3d12.h)

Получает указатель ЦП на указанный подресурс в ресурсе, но может не раскрывать значение указателя для приложений. Сопоставление также делает кэш ЦП недействительным при необходимости, чтобы операции чтения ЦП на этот адрес отражали любые изменения, внесенные GPU.

Синтаксис

HRESULT Map(
                  UINT              Subresource,
  [in, optional]  const D3D12_RANGE *pReadRange,
  [out, optional] void              **ppData
);

Параметры

Subresource

Тип: UINT

Задает номер индекса подресурса.

[in, optional] pReadRange

Тип: const D3D12_RANGE*

Указатель на структуру D3D12_RANGE , описывающую диапазон памяти для доступа.

Это указывает регион, который может считывать ЦП, а координаты являются относительными по субресурсам. Пустой указатель указывает, что ЦП может прочитать весь подресурс. Можно указать, что ЦП не будет считывать данные, передав диапазон, в котором значение End меньше или равно Begin.

[out, optional] ppData

Тип: void**

Указатель на блок памяти, получающий указатель на данные ресурса.

Указатель null является допустимым и полезен для кэширования диапазона виртуальных адресов ЦП для таких методов, как WriteToSubresource. Если значение ppData не равно NULL, возвращаемый указатель никогда не смещается никакими значениями в pReadRange.

Возвращаемое значение

Тип: HRESULT

Этот метод возвращает один из кодов возврата Direct3D 12.

Комментарии

Map и Unmap могут безопасно вызываться несколькими потоками. Вложенные вызовы карты поддерживаются и учитываются по ссылке. При первом вызове Map выделяется диапазон виртуальных адресов ЦП для ресурса. Последний вызов Unmap освобождает диапазон виртуальных адресов ЦП. Виртуальный адрес ЦП обычно возвращается приложению; но обработка содержимого текстур с неизвестными макетами исключает раскрытие виртуального адреса ЦП. Дополнительные сведения см. в статье WriteToSubresource . Приложения не могут полагаться на согласованность адреса, если только сопоставление не является постоянно вложенным.

Указатели, возвращаемые map , не гарантируют, что имеют все возможности обычных указателей, но большинство приложений не замечают разницы в обычном использовании. Например, указатели с WRITE_COMBINE поведением имеют более слабые гарантии упорядочения памяти ЦП, чем WRITE_BACK поведение. Память, доступная как ЦП, так и GPU, не гарантирует использование одних и тех же гарантий атомарной памяти, что и ЦП, из-за ограничений PCIe. Используйте ограждения для синхронизации.

Для map существует две категории моделей использования: простая и расширенная. Простые модели использования максимизируют производительность инструмента, поэтому приложениям рекомендуется придерживаться простых моделей до тех пор, пока расширенные модели не будут признаны обязательными для приложения.

Простые модели использования

Приложения должны придерживаться абстракций типа кучи UPLOAD, DEFAULT и READBACK, чтобы обеспечить достаточно поддержку всех архитектур адаптеров.

Приложения должны избегать операций чтения ЦП из указателей на ресурсы в кучах UPLOAD, даже в случайном случае. Операции чтения ЦП будут работать, но во многих распространенных архитектурах GPU выполняются слишком медленно, поэтому учитывайте следующее:

  • Не считывайте ЦП из ресурсов, связанных с кучами, которые D3D12_HEAP_TYPE_UPLOAD или имеют D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE.
  • Область памяти, в которую можно выделить точки pData с помощью PAGE_WRITECOMBINE, и ваше приложение должно соблюдать все ограничения, связанные с такой памятью.
  • Даже следующий код C++ может считывать из памяти и вызывать снижение производительности, так как код может расшириться до следующего кода сборки x86.

    Код C++:

    *((int*)MappedResource.pData) = 0;
    

    Код сборки x86:

    AND DWORD PTR [EAX],0
    
  • Используйте соответствующие параметры оптимизации и языковые конструкции, чтобы избежать снижения производительности. Например, можно избежать оптимизации xor, используя переменный указатель или оптимизируя скорость кода вместо размера кода.
Приложениям рекомендуется не сопоставлять ресурсы, а ЦП не будет изменять их и постоянно использовать ограниченные и точные диапазоны. Это позволяет использовать самые быстрые режимы для таких средств, как отладка графики и уровень отладки. Такие средства должны отслеживать все изменения ЦП в памяти, которые может считывать GPU.

Расширенные модели использования

Ресурсы в доступных ЦП кучах могут постоянно сопоставляться. Это означает, что сопоставление можно вызывать один раз, сразу после создания ресурса. Unmap не требуется вызывать, но адрес, возвращенный из map , больше не должен использоваться после освобождения последней ссылки на ресурс. При использовании постоянной карты приложение должно убедиться, что ЦП завершает запись данных в память, прежде чем GPU выполнит список команд, который считывает или записывает память. В распространенных сценариях приложение просто должно выполнять запись в память перед вызовом ExecuteCommandLists; но использование ограждения для задержки выполнения списка команд также работает.

Все типы памяти, доступные для ЦП, поддерживают постоянное использование сопоставления, где ресурс сопоставляется, но никогда не разархивировано, если приложение не обращается к указателю после удаления ресурса.

Примеры

В примере D3D12Bundles используется ID3D12Resource::Map следующим образом:

Скопируйте данные треугольника в буфер вершин.

// Copy the triangle data to the vertex buffer.
UINT8* pVertexDataBegin;
CD3DX12_RANGE readRange(0, 0);        // We do not intend to read from this resource on the CPU.
ThrowIfFailed(m_vertexBuffer->Map(0, &readRange, reinterpret_cast<void**>(&pVertexDataBegin)));
memcpy(pVertexDataBegin, triangleVertices, sizeof(triangleVertices));
m_vertexBuffer->Unmap(0, nullptr);

Создайте кучу отправки для буферов констант.

// Create an upload heap for the constant buffers.
ThrowIfFailed(pDevice->CreateCommittedResource(
    &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
    D3D12_HEAP_FLAG_NONE,
    &CD3DX12_RESOURCE_DESC::Buffer(sizeof(ConstantBuffer) * m_cityRowCount * m_cityColumnCount),
    D3D12_RESOURCE_STATE_GENERIC_READ,
    nullptr,
    IID_PPV_ARGS(&m_cbvUploadHeap)));

// Map the constant buffers. Note that unlike D3D11, the resource 
// does not need to be unmapped for use by the GPU. In this sample, 
// the resource stays 'permanently' mapped to avoid overhead with 
// mapping/unmapping each frame.
CD3DX12_RANGE readRange(0, 0);        // We do not intend to read from this resource on the CPU.
ThrowIfFailed(m_cbvUploadHeap->Map(0, &readRange, reinterpret_cast<void**>(&m_pConstantBuffers)));

См. пример кода в справочнике по D3D12.

Требования

Требование Значение
Целевая платформа Windows
Header d3d12.h
Библиотека D3D12.lib
DLL D3D12.dll

См. также раздел

ID3D12Resource

Подресурсы

Unmap