Opened up my personal project earlier today and ran into a nasty crash when trying to load an instance of my proxy texture asset class. The crash was occurring here:

void* Data = RHILockTexture2D(DynamicResource->GetTexture2DRHI(), 0, RLM_WriteOnly, Stride, false);

DynamicResource was valid, all looked okay, until I could see further in that the result of GetTexture2DRHI was not valid, even though I'd already called to initialize the resource beforehand. What was going on?

A little bit of further digging shows that calling UTexture2DDynamic::Init eventually calls FRenderResource::BeginInitResource. This, importantly, queues a command to the render thread to update the resource, rather than doing so on-the-spot. As a result, trying to lock the resource too early gives you a nullptr instead of the resource. I'd been lucky when doing my initial work that there was enough lag between the two calls that I had a valid pointer by the time I wanted to lock it to copy some data in.

So, what to do? I want to block on the resource initialization if necessary, because I am loading the texture in dynamically and need to guarantee that the data's ready when the game uses it (and the game isn't so fast-paced that a one-frame hitch on initial load would be noticeable, if I had to wait a full frame in the worst case scenario).

Enter the FRenderCommandFence. Simply put, this is a synchronization primitive that allows you to block until the specified point in the render command queue is executed.

I added an instance to my runtime texture class:

FRenderCommandFence InitializationFence;

Then began the fence after requesting the resource be allocated:

UTexture2DDynamic::PostLoad();
InitializationFence.BeginFence();

After that all that was required was to wait for the fence to be completed before I actually populate the texture data:

InitializationFence.Wait();
// Do things with the texture resource

Now everything works just fine, my proxy asset loads on-demand as expected!