我刚刚开始使用Direct3D11,我正在尝试创建一个动态纹理,我计划每秒多次使用新数据进行更新。我的问题是,每次使用新数据更新纹理时,我都会从D3D调试器中收到此错误:
D3D11:错误:ID3D11DeviceContext :: Map:此资源已映射! [RESOURCE_MANIPULATION ERROR#2097213:RESOURCE_MAP_ALREADYMAPPED]
在运行应用程序一段时间之后,最终会从Map调用变成E_OUTOFMEMORY错误。
我正在创建这样的纹理:
D3D11_TEXTURE2D_DESC td;
td.ArraySize = 1;
td.BindFlags = D3D11_BIND_SHADER_RESOURCE;
td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
td.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
td.Height = height;
td.Width = width;
td.MipLevels = 1;
td.MiscFlags = 0;
td.SampleDesc.Count = 1;
td.SampleDesc.Quality = 0;
td.Usage = D3D11_USAGE_DYNAMIC;
HR(m_device->CreateTexture2D(&td, 0, &texture));
并更新其数据:
HR(m_deviceContext->Map(texture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
BYTE* mappedData = reinterpret_cast<BYTE*>(mappedResource.pData);
for(UINT i = 0; i < height; ++i)
{
memcpy(mappedData, buffer,rowspan);
mappedData += mappedResource.RowPitch;
buffer += rowspan;
}
m_deviceContext->Unmap(texture, 0);
在创建纹理并将数据映射到它之前,我在程序中所做的就是初始化Direct3D设备。我完全被我做错了所困扰。我一直试图在msdn上尽可能多地阅读这篇文章,但没有任何东西可以帮助我弄清楚出了什么问题。根据msdn的说法,我正在采取适当的措施:
http://msdn.microsoft.com/en-us/library/ff476905(v=vs.85).aspx#Dynamic
To fill a dynamic texture (one created with D3D11_USAGE_DYNAMIC):
Get a pointer to the texture memory by passing in D3D11_MAP_WRITE_DISCARD when calling
ID3D11DeviceContext::Map.
Write data to the memory.
Call ID3D11DeviceContext::Unmap when you are finished writing data.
我相当确定我也正确地填写了纹理描述。
问题可能源于我的d3d设备的初始化?我滥用地图功能了吗?我没有提供足够的背景信息吗?关于最新情况的任何想法?
附加信息:当我尝试将数据映射到顶点着色器的常量缓冲区时,我得到了相同的“资源已映射”错误。此外,我在另一台计算机上测试了它并得到了相同的映射问题。
更新: 我为D3D11下载了一些教程代码,然后在教程代码完成初始化d3d之后,我将纹理创建和映射代码放入其中。我只想看看是否会出现映射错误。正如所料,我没有得到“资源已映射”错误。此外,当我从教程中复制d3d初始化代码并将其替换为我的时,我仍然得到资源已经映射的错误,这甚至让我更加困惑,因为我在初始化d3d之前所做的就是创建一个窗口。
答案 0 :(得分:2)
有趣的是,当你开始询问有关你所坚持的事情的问题时,找到问题会变得更容易哈哈。
我弄清楚问题是什么。这是我的HR宏,我正在围绕地图调用。
#define HR(x)
{
HRESULT hr = (x);
if(FAILED(x))
{
DXTrace(__FILE__, (DWORD)__LINE__, hr, L#x, true);
}
}
我不知道为什么它会成为问题的根源,但我肯定想知道这个宏如何与Map调用有关。