• Advertisement
Sign in to follow this  

Deferred context rendering

This topic is 635 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have asked this before in someone else's thread (different subject) and had no resolution.

 

I am procedurally generating planets in a solar system. I need it to generate in real-time but not cause pauses in game play. I am currently doing this using multithreading: I create the textures to be generated, map to them, then call the generation thread. When the thread completes, it throws a complete flag and the main thread unmaps the textures and sets them as "ready to use". This works fine, but when I start using high quality textures, it has a noticeable "jerk" in movement during either "map" or "unmap" or "create texture".

 

I want to create the texture, map it, generate the image, and unmap it all within the parallel thread (not in the main thread).

 

I have tried using deferred context, but I'm doing it wrong. I know this because the only approach I had any non-crash result caused a graphic "blinking".

 

Has anyone ever done something like this? If so, how is it properly implemented?

Share this post


Link to post
Share on other sites
Advertisement

I am not entirely sure what you mean by 'high quality textures' so for the sake of my explanation I will assume you mean high resolution textures.

 

My guess is that you are trying to update the texture asynchronously, but synchronized to main thread, on another thread. However if the texture becomes large enough the time it takes to complete is still too long for a frame causing the jerk, or your texture is so large that once you un-map the driver overhead is so high that it jerks there (seems more unlikely, since this is effectively a memcpy from system memory to GPU memory, but you gave limited information.)

 

In any case if you have any thread synchronization going on (be it the thread calculating the procedural stuff or the render thread waiting for the ready flag to be set) I would start splitting up the update into smaller blocks. Say you have a 4096x4096 texture you need to update with your procedural function then I would map it into chunks of say 128x128 and build a bunch of tasks each doing their own block, running on multiple helper threads (on multi core systems.) This would show intermediate results where some pieces are updated and others aren't.

 

If it is not an option to show a partially updated texture then I would build a lower resolution (low mip) that you can do within one frame and set the mipmap range to only use the lower one until the higher resolution one is filled in. Once the higher resolution is completed I would up the mipmap level it can use in the sampler desc.

 

As an alternative to a lower mip I would use the same mip map level, but calculate less samples. Say you calculate a procedural sample every 4 pixels. Then after this, you do a quick pass to 'smear' out that over the remaining pixels. So in effect for the quick version you could calculate 1 pixel in a 4x4 block... then run a post pass that either just duplicates the data or creates a bilinear filtered version or so. Then in subsequent updates you can refine the result... rendering 1 pixel in a 2x2 block, then every pixel. Then generate the lower mips of the higher res.

Edited by efolkertsma

Share this post


Link to post
Share on other sites

The "jerk" is barely noticeable on my machine, but the game is in its infancy, so the more I add, the more noticeable it will become.

I'm generating an entire solar system during game play. Each planet is generated one at a time. The initial texture resolution is 256x256, but when the player gets within orbit range, the program will begin generating a 1024x1024 texture for each face of the cubesphere (yes using a spherified cube for planets). That means there are 6 1024x1024 images being generated for that planet.

Not to be too picky (because you did help me think of something), but I didn't see anything about deferred context rendering..... Do you know how to do it right? Or do you have any place I can look (besides Microsoft) for help?

Share this post


Link to post
Share on other sites

Are these textures procedurally created or pre-defined in an image editor? Can you not pre-load all(or most) of your textures before you enter gameplay? Perhaps spatial partioning is necessary with load screens in-between large parts of the universe(to minimize load screens).

Share this post


Link to post
Share on other sites
Your question is more about how to optimally stream dynamic texture data from the CPU to the GPU, than deferred context rendering specifically :)

Can you start with what flags you use to create the resource and to map it? Also what format it is / etc.

Does the GPU only begin using the texture after the unmapped, or is it progressively updated while in use by the GPU?

Have you also considered running your texture generation algorithm on the GPU itself, which would eliminate the issue? :wink:

Share this post


Link to post
Share on other sites

Not to be too picky (because you did help me think of something), but I didn't see anything about deferred context rendering..... Do you know how to do it right? Or do you have any place I can look (besides Microsoft) for help?

 

There is no 'right' or 'wrong' way off the bat. It is depending on your context, and your question is as Hodgman pointed out... 

Your question is more about how to optimally stream dynamic texture data from the CPU to the GPU, than deferred context rendering specifically

 

 

It is unclear to me from your description where your problem is outside of that your procedural calculation takes long and you stall your rendering based on this.

 

Please clarify.

Share this post


Link to post
Share on other sites

Hodgeman: would I be able to run a parallel thread on the GPU? If I did the procedural generation on the GPU, I would have to write a very complex shader to do that.

 

As for the other questions (everyone), I'll have to wait till I get home to give you specifics on resource creation flags and so on...... I'll post those later.

Share this post


Link to post
Share on other sites

Hodgeman: would I be able to run a parallel thread on the GPU? If I did the procedural generation on the GPU, I would have to write a very complex shader to do that.

No... well, this is what "async compute" does in Dx12/Vulkan, but you still shouldn't use it for extremely long-running shaders.

Any task that can be completed by preemptive multi-threading can always be completed by co-operative multi-threading, it's often just harder to write certain problems with one model or the other... In other words, you can break up a very expensive task into a large number of very cheap tasks and run one per frame (it just might make your code uglier).

e.g. I did a dynamic GPU lightmap baker on a PS3 game, which took about 10 seconds of GPU time to run... so instead, I broke it up into 10000 chunks of work that were about 1ms each, and executed one per frame, producing a new lightmap every ~2 minutes :wink:

Share this post


Link to post
Share on other sites

As far as breaking it up into smaller tasks, I am currently doing 6 textures at once. I can break up the 6 into 6 different tasks, which could cause the "jerk" to be almost unnoticeable. This of course would simply take away the symptom; I want to try it using deferred context rendering. If what I am trying to do won't work with DX11, then I can deal with the symptom, but what Microsoft seems to imply is that I can...... I just can't seem to get it right.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement