zoukankan      html  css  js  c++  java
  • 【转】dx11 devicecontext>map

     Directx10和Directx11很多resource类都有个Map()函数,个人感觉它是一个蛮重要的CPU和GPU沟通桥梁。下面以ID3D11DeviceContext::Map()为例讲下。

      ID3D11DeviceContext::Map官方解释是:ID3D11DeviceContext::Map Method
      Get a pointer to the data contained in a subresource, and deny the GPU access to that subresource.

      Syntax
    HRESULT Map(
        ID3D11Resource *pResource,
        UINT Subresource,
        D3D11_MAP MapType,
        UINT MapFlags,
        D3D11_MAPPED_SUBRESOURCE *pMappedResource
    );


      个人理解总结是当需要用CPU读写(GPU的)subresouce(最常用如buffer)时,就用Map()得到该subresource的pointer(D3D11_MAPPED_SUBRESOURCE*),然后将D3D11_MAPPED_SUBRESOURCE::pData强制转换成CPU理解的类型(struct,class),CPU就可以对得到的struct*或class*读写了。

    附录D3D11_MAPPED_SUBRESOURCE结构体
    typedef struct D3D11_MAPPED_SUBRESOURCE
        {
        void *pData;
        UINT RowPitch;
        UINT DepthPitch;
        }  D3D11_MAPPED_SUBRESOURCE;

    Map函数使用的几个经典场景1:debug时用CPU读写GPU之前读写的buffer(比如GPU计算输出的结果),然后再通过CPU输出来检验对错。
    //将GPU读或读写的buffer *pGBuffer拷贝到可给CPU读的buffer并返回,以便调试
    ID3D11Buffer* GPUBaseApp::CreateAndCopyToDebugBuf(ID3D11Buffer* pGBuffer)
    {
     D3D11_BUFFER_DESC bufferDesc;
     ZeroMemory(&bufferDesc,sizeof(bufferDesc));
     pGBuffer->GetDesc(&bufferDesc);
     bufferDesc.CPUAccessFlags=D3D11_CPU_ACCESS_READ;
     bufferDesc.Usage=D3D11_USAGE_STAGING;
     bufferDesc.BindFlags=0;
     bufferDesc.MiscFlags=0;
     
     ID3D11Buffer* pDebugBuffer=NULL;

     if( SUCCEEDED(m_pDevice->CreateBuffer(&bufferDesc,NULL,&pDebugBuffer)) )
     {
      m_pDeviceContext->CopyResource(pDebugBuffer,pGBuffer);
     }
     return pDebugBuffer;
    }

    HRESULT Function()
    {
           ////////////////////////////////////////////////
           //==============================================
          /////////////////////////////////////////////////

     //===============================================
     //看Direct Compute的计算结果
     ID3D11Buffer* debugOutBuffer=NULL;
     ID3D11Buffer* debugInBuffer=NULL;

     debugOutBuffer=CreateAndCopyToDebugBuf(m_pOutBuffer);
     debugInBuffer=CreateAndCopyToDebugBuf(m_pInputBuffer);


     VoronoiOutBufType* pOut=NULL;
     VoronoiInBufType* pIn=NULL;

     D3D11_MAPPED_SUBRESOURCE mappedOutResource;
     D3D11_MAPPED_SUBRESOURCE mappedInResource;

     m_pDeviceContext->Map(debugOutBuffer,0,D3D11_MAP_READ,0,&mappedOutResource);
     pOut=(VoronoiOutBufType*)mappedOutResource.pData;

     m_pDeviceContext->Map(debugInBuffer,0,D3D11_MAP_READ,0,&mappedInResource);
     pIn=(VoronoiInBufType*)mappedInResource.pData;

     //printf("OutBuffer的结果如下:/n");
     //for(int i=0;i<30;i++)
     // printf("%d %f/n",pOut[i].index,pOut[i].dist);

     m_pDeviceContext->Unmap(debugOutBuffer,0);
     SAFE_RELEASE(debugOutBuffer);

     m_pDeviceContext->Unmap(debugInBuffer,0);
     SAFE_RELEASE(debugInBuffer);

     //===============================================

           ////////////////////////////////////////////////
           //==============================================
          /////////////////////////////////////////////////

    }


    Map函数使用的几个经典场景2:更新GPU Shader中Constant buffer,把CPU中新的数据struct CB_MouseInfo mouseInfo写入GPU中Constant Buffer。
    struct CB_MouseInfo
    {
     UINT x;
     UINT y;
     UINT btDown;
    };

    CB_MouseInfo mouseInfo;

    HRESULT GPUBaseApp::UpDateMouseInfoCB()
    {
     HRESULT hr=S_OK;

     D3D11_MAPPED_SUBRESOURCE subData;

     ZeroMemory(&subData,sizeof(subData));

     m_pDeviceContext->Map(m_pConstantBuffer,0,D3D11_MAP_WRITE_DISCARD,0,&subData);

     memcpy(subData.pData,&mouseInfo,sizeof(CB_MouseInfo));

     m_pDeviceContext->Unmap(&subData,0);

     return hr;
    }

    注意点,当调用了Map(),最后记得调用ID3D11DeviceContext::Unmap Method使得GPU重新获取对该resouce的读写权。
    Invalidate the pointer to a resource and re-enable the GPU's access to that resource.

    Syntax
    void Unmap(
        ID3D11Resource *pResource,
        UINT Subresource
    );

    Parameters:

    pResource 
    ID3D11Resource 
    A pointer to a ID3D11Resource interface.

    Subresource 
    UINT 
    A subresource to be unmapped.

     

     

  • 相关阅读:
    <QT学习>串口QSerialPort类同步与异步接收和发送数据
    <QT学习>QT生成与调用共享库
    《Pinctrl和GPIO子系统的使用》
    《查询方式的按键驱动程序》
    《C库 — sprintf字符串格式化命令,把格式化的数据写入某个字符串中》
    《C库 — 字符串合并函数strcat 字符串常量导致程序崩溃》
    Ex 5_22 在此我们基于以下性质给出一个新的最小生成树算法..._第九次作业
    Ex 5_21 无向图G=(V,E)的反馈边集..._第九次作业
    Ex 5_33 实现一个关于公式长度(其中所有文字总的出现次数)为线性时间的Horn公式可满足性问题_第十次作业
    Ex 5_28 Alice想要举办一个舞会..._第十次作业
  • 原文地址:https://www.cnblogs.com/RenderLife/p/2703583.html
Copyright © 2011-2022 走看看