DirectX11 - 纹理和动态变化

时间:2017-10-09 17:19:53

标签: dynamic textures directx-11

我对DirectX 11有几个问题。

当我通过CreateTexture2D创建纹理并指定DEFAULT用法时,我应该可以使用UpdateSubresource,对吗?

a)内存更新是否必须与原始纹理的格式相同?我的意思是当我使用DDS DXT1创建TextTexture时,UpdateSubresource数据是否也必须是DDS DXT1?

b)什么时候可以更新资源?在DX12中,您可以在完成命令列表之前更新resoruce。否则没有任何反应。

c)我应该更新每个mip更新,其中每个子资源索引是索引* miplevels,对吗?

或者我应该使用地图unmap代替?是否有成功更新所需的所有规则的好例子?

2 个答案:

答案 0 :(得分:1)

这种加载纹理的最有效方法是在创建纹理时使用initData。您可以将其设为DEFAULTIMMUTABLE

另一种方法是使用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

另请参阅DDSTextureLoaderWICTextureLoader

  

请注意,通过查看实现该功能here的DirectX 12帮助程序,您可以了解效率低UpdateSubresource

答案 1 :(得分:0)

所以我发现包括我的解决方案:

如果纹理创建为DYNAMIC,如果纹理有多个mips,则无法Map。 (我的纹理中有更多的mips,所以我必须以其他方式做到这一点)

所以我必须在创作时使用DEFAULT纹理。然后在{for循环中UpdateSubresourceD3D11CalcSubresource我更新了纹理中的所有mips。所以在我的情况下使用简单的多mip-map 2D纹理:D3D11CalcSubresource( i, 0, totalMipsInTexture)。我设法在调用Present之前更新纹理(小心多线程)。

我的最终建议:如果您挣扎,请在DirectX中启用调试层(当您创建设备传递时)。它会告诉你你做错了什么。