Reputation: 125
I have a few questions about DirectX 11.
When I create texture via CreateTexture2D and I specify DEFAULT usage I should be able to use UpdateSubresource, right?
a) Does the memory update must be in the same format as the original texture? I mean when I CreateTexture with DDS DXT1, does the UpdateSubresource data have to be DDS DXT1 too?
b) When is it possible to update resource? In DX12 you can update resoruce before you finish command list. Otherwise nothing happens.
c) I should update each mip with update where each index of subresource is index*miplevels, right?
Or should I use map unmap instead? Is there any good example with all the rules that are necessary for sucessful update?
Upvotes: 1
Views: 4058
Reputation: 125
So what I found including my solution:
If the texture is created as DYNAMIC
you can't Map
it if it has more than one mips. (I had more mips in my textures so I had to do it other way)
So I had to go with DEFAULT
textures on creation. Then UpdateSubresource
and D3D11CalcSubresource
in for loop where I updated all mips in the texture. So in my case with simple multi mip-map 2D textures: D3D11CalcSubresource( i, 0, totalMipsInTexture)
. I managed to update the textures before Present
was called (beware of multithreading).
My final recommendation: if you struggle, enable debug layer in DirectX (when you create device pass). It will tell you what are you doing wrong.
Upvotes: 1
Reputation: 41087
This most efficient method for loading a texture is to use initData
when you create it. You can make it DEFAULT
or IMMUTABLE
.
The other approach is to use DEFAULT
textures and a smaller set of STAGING
textures. You load your data into the STAGING
textures via Map
and then copy via CopyResource
. Ideally you reuse STAGING
textures (same size, mips, format, etc.). UpdateSubresource
works, but is not as efficient--it's most often used for Constant Buffers.
Dynamic textures are really only for things you plan to update every frame or every few frames. Depending on the hardware, they are put into slightly less efficient (for rendering) memory that the GPU and CPU can both access.
Use the helper D3D11CalcSubresource
defined in d3d11.h
to figure out the subresource:
UINT D3D11CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT MipLevels )
{
return MipSlice + ArraySlice * MipLevels;
}
This is covered on MSDN in the Programming Guide:
How to: Initialize a Texture Programmatically
How to: Use dynamic resources
See also DDSTextureLoader and WICTextureLoader
Note that you can get some sense of how inefficient
UpdateSubresource
is by taking a look at the DirectX 12 helper that implements that functionality here.
Upvotes: 4