`

DX11渲染管道:数据的修改(Map和Unmap)

 
阅读更多

在C++与Hlsl绑定Cbuffer数据的时候,非常容易出错,出错的根本原因是C++对数据结构内存的分配与hlsl不同。

重要:HLSL的结构体struct其实并不管你是一个变量还是几个变量,它就是按照一次放满一个float4的内存长度,多少变量都往一个float4里面塞,塞满了再接着塞下一个float4。测试结果显示:cbuffer的长度必须是float4的整数倍才行,不知道float+float3的这种组合是否可以正常获取数据,也不清楚float+float+float3+float3这种组合能不能正常分配到数据,关键取决于GPU的内存分配规则。

 

在进入渲染管道后,如果CPU出现了要修改buffer或者其它类型数据的时候,不可能重新new一个buffer塞进去。这个时候需要一种机制能够修改已经进入管道的数据,这种机制就是Map和Unmap机制。其本质就是对数据加锁导致GPU不能修改,然后CPU对其进行修改,修改完后还原。

 

Map:获取的数据中包含一个子资源的指针,并拒绝该子资源的访问GPU。

HRESULT Map(
  ID3D11Resource *pResource,  // 需要修改的源,类型不是buffer,这说明map还可以修改状态值。
  UINT Subresource,  // 子资源的位置
  D3D11_MAP MapType, // 这是一个枚举类型:D3D11_MAP_WRITE_DISCARD,D3D11_MAP_WRITE_NO_OVERWRITE
  UINT MapFlags, // 一个可选标准,不懂
  D3D11_MAPPED_SUBRESOURCE *pMappedResource // 返回的内容
);

typedef struct D3D11_MAPPED_SUBRESOURCE { 
  void *pData; // 传说中我们可以修改的东东
  UINT RowPitch; // 对某一行的某个像素
  UINT DepthPitch; // 对应某一行,这两个参数最好不用
} D3D11_MAPPED_SUBRESOURCE;

Unmap:无效的指针指向的资源,并重新启用GPU的访问该资源。

 

void Unmap(
  ID3D11Resource *pResource,
  UINT Subresource
);

例子:

 

        m_immediateContext->Map(matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);

	// 得到const buffer指针.
	dataPtr = (TransitionMatrix*)mappedResource.pData;

	// 设置transform矩阵.
	D3DXMATRIX worldMatrix;
	D3DXMatrixIdentity(&worldMatrix);
	Matrix4 transform = D3DXMatrix2Matrix4(worldMatrix) * cameraManager->getView() * cameraManager->getPerspective();//D3DXMatrix2Matrix4(viewMatrix)  cameraManager->getView()
	dataPtr->transform = transform.Transpose(); // 矩阵需要转置

	m_immediateContext->Unmap(matrixBuffer, 0);

 此文主要是想演示一下如何修改资源。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics