您的位置:首页 > 其它

D3d10和D3d11中Map()函数用法一点心得总结

2011-02-13 11:12 309 查看
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: