Asynchronous Texture Creation DX11

Started by
7 comments, last by AndreyVK_D3D 6 years, 2 months ago

Is it possible to asynchronously create a Texture2D using DirectX11?

I have a native Unity plugin that downloads 8K textures from a server and displays them to the user for a VR application. This works well, but there's a large frame drop when calling CreateTexture2D. To remedy this, I've tried creating a separate thread that creates the texture, but the frame drop is still present.

Is there anything else that I could do to prevent that frame drop from occuring?

Advertisement

You can use this code to ask the driver whether it supports multi-threaded resource creation.


	D3D11_FEATURE_DATA_THREADING threadingCaps = {};
	device.CheckFeatureSupport(D3D11_FEATURE_THREADING, &threadingCaps, sizeof(threadingCaps));
	check if true ---> threadingCaps.DriverConcurrentCreates <---

If so, calling CreateTexture2D another thread should help you. I do it in my game (not unity) and it helps me a lot.

Do you upload the data using the "initial data" parameter of CreateTexture2D? Maybe the driver is doing this transfer using the GPUs 3D engine, which could stall it for many milliseconds with a block of data that size... 

If so, you could create the texture with no contents, and also create a smaller staging texture. Then use your extra thread to, over time, copy different rectangles of your texture into the staging texture, then ask the GPU to move the staging data into the right part of your 8k texture using CopySubresourceRegion. Doing this would help you split the work over multiple frames and avoid a single spike. 

Thanks for the suggestions!

I think the main reason why the threaded CreateTexture2D wasn't working is because Unity be default uses D3D11_CREATE_DEVICE_SINGLETHREADED for whatever reason. I added -force-d3d11-no-singlethreaded to the command parameters and it seems to be working now, albeit with a ~60ms spike. I'll try doing the upload in parts as you suggest to fix that.

 

Thanks again!

14 hours ago, mc_wiggly_fingers said:

I think the main reason why the threaded CreateTexture2D wasn't working is because Unity be default uses D3D11_CREATE_DEVICE_SINGLETHREADED

You can use D3D11_CREATE_DEVICE_SINGLETHREADED for creating textures from other thread, because ID3D11Device object is thread-safe, but you should synchronize manualy of creating and setting of Unity Textures.

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

D3D11_CREATE_DEVICE_SINGLETHREADED removes the device's thread-safety. You cannot use a singlethreaded device from multiple threads without manually locking it.

When you create the texture, do you provide initial data, or you keep that later with some update sub resrouces ?

 

Without initialData, usually the driver does not dare to reserve and commit memory. And you hitch at first use, with initial data, even if it takes a long time because of tiling and allocation, the driver does not have the choice but to do it, and so be hitch free at first use.

1 hour ago, SoldierOfLight said:

D3D11_CREATE_DEVICE_SINGLETHREADED removes the device's thread-safety. You cannot use a singlethreaded device from multiple threads without manually locking it.

Yes, you are right. It is my mistake.

3DGraphics,Direct3D12,Vulkan,OpenCL,Algorithms

This topic is closed to new replies.

Advertisement