我对DirectX 11有几个问题。
当我通过CreateTexture2D创建纹理并指定DEFAULT用法时,我应该可以使用UpdateSubresource,对吗?
a)内存更新是否必须与原始纹理的格式相同?我的意思是当我使用DDS DXT1创建TextTexture时,UpdateSubresource数据是否也必须是DDS DXT1?
b)什么时候可以更新资源?在DX12中,您可以在完成命令列表之前更新resoruce。否则没有任何反应。
c)我应该更新每个mip更新,其中每个子资源索引是索引* miplevels,对吗?
或者我应该使用地图unmap代替?是否有成功更新所需的所有规则的好例子?
答案 0 :(得分:1)
这种加载纹理的最有效方法是在创建纹理时使用initData
。您可以将其设为DEFAULT
或IMMUTABLE
。
另一种方法是使用DEFAULT
纹理和一组较小的STAGING
纹理。您可以通过STAGING
将数据加载到Map
纹理中,然后通过CopyResource
进行复制。理想情况下,您可以重复使用STAGING
纹理(相同大小,mips,格式等)。 UpdateSubresource
有效,但效率不高 - 它最常用于Constant Buffers。
动态纹理实际上仅适用于您计划每帧或每几帧更新的内容。根据硬件的不同,GPU和CPU都可以访问的内存效率稍低(用于渲染)。
使用D3D11CalcSubresource
中定义的助手d3d11.h
来找出子资源:
UINT D3D11CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT MipLevels )
{
return MipSlice + ArraySlice * MipLevels;
}
这在编程指南:
中的MSDN中有所介绍 How to: Initialize a Texture Programmatically
How to: Use dynamic resources
另请参阅DDSTextureLoader和WICTextureLoader
请注意,通过查看实现该功能here的DirectX 12帮助程序,您可以了解效率低
UpdateSubresource
。
答案 1 :(得分:0)
所以我发现包括我的解决方案:
如果纹理创建为DYNAMIC
,如果纹理有多个mips,则无法Map
。 (我的纹理中有更多的mips,所以我必须以其他方式做到这一点)
所以我必须在创作时使用DEFAULT
纹理。然后在{for循环中UpdateSubresource
和D3D11CalcSubresource
我更新了纹理中的所有mips。所以在我的情况下使用简单的多mip-map 2D纹理:D3D11CalcSubresource( i, 0, totalMipsInTexture)
。我设法在调用Present
之前更新纹理(小心多线程)。
我的最终建议:如果您挣扎,请在DirectX中启用调试层(当您创建设备传递时)。它会告诉你你做错了什么。