Hi,
I need an update rate for computations that is happening faster than the draw rate.
Google is being the opposite with me, and won’t help me out.
To explain the concept;
I need an update rate, 1000 fps, or more, and a number of draw frames 60 - 90 per second;
in a previous engine i was able to perform this solution and run some background logic at a faster rate, while keeping my controls and inputs, physics and draw on the same rate.
I have somewhat set the situation up in Mono, as i did before, by just counting the frames. But of course it works, but i am not aligned with the actual refresh frame. So i am having strobe like effects. And other graphical anomally.
But there is a way to get the actual frame, or to know if we just had a monitor update, or are about to have one.
it is likely knowledge that is covetted to high heavens.
Now, google today this evening, this morning i should say refuses to understand my question and wants to supply the inverse of the question as the result. Though i know it is possible as i had achieved it before in Unity Engine of all engines. they had a queiry for the current frame being a monitor refresh frame. Though that one was a covetted solution aswell i did manage to get it working how i liked.
Though i left that engine due to ediitor perfomance, lack of transparency, community, and lack of respect for their implementation of euler angles ( ).
Any thoughts or suggestions?
Its a difficult topic to google, it does seem nobody wants to discuss the technique.
But anyhow, what i want it for here, is i intend to build up some complex draw over a number of frames before the draw is actually ocurring. Or at least explore these regions for perfomance gains.
1 Like
Thanks but i am at the same conclusion Shawn Hargreaves reached on the final paragraph he wrote on it.
The concept is to implment my own V-sync without having to use VerticalRetrace
here is an example using DateTime. I know Date Time is nieve; but for the sakes of approximately figuring out the actual time of screen refresh. it is farily close
if (TIME >= DRAW_TIME)
{
DRAW_TIME = System.DateTime.Now + TimeSpan.FromSeconds(0.01);
DRAW_FRAME = true;
}
if (TIME >= AWAIT_TIME)
{
AWAIT_TIME = DRAW_TIME + TimeSpan.FromSeconds(0.02);
}
protected override void Draw(GameTime gameTime)
{
if (DRAW_TIME < AWAIT_TIME)
{
GraphicsDevice.Clear(Color.Black);
// DO DRAW
}
}
The above code removes flickering on my machine. But of course we are not perfectly aligned. here is the example, Top left screen first value is the Update Rate, second Value is the Draw Rate.
if its too small to see, the frame rate is +1000 and the draw rate is below 300 of those frames.
It would be faster to render such few objects. but i have some experimental draw stuff going on which is the ultimate purpose of making such optimization attempt. Drawing Bloom in intervals.between frames.
Here is some extra context; at 2200 fps update, i draw 642 times, which is a saving, of 29% vs drawing 60 times for 60 updates. which is the equiavelent saving of 0%.
Updating at 60 frames for 60 logic updates, conceals available resources. I feel it is good to have all of the resources available to update, while the draw is tightly controlled to a custom v-sync.
I’d may be able to squeeze the frames out to a lower accuracy maybe 50%, but without the actual flag i couldn’t do V-Sync only draw, and have my frames to shuffle some crazy optimal array and texture draw management. To get some of the contents for the buffer ready before the draw frame, and in smaller chunks than for (int)'ing all of my render queue, some of the render queue could be drawn. All the way to 60 dps.
60 Draw Per Second
Unlimited Frames per Second.
60 Draw Per Second
Unlimited Frame per Second.
although limited by the content of that update for sure. Just not restricted. It isn’t restricted, but it would be decent to have it accurate.
Anyways if i can figure this out, or i do find the solution i will come back and post.
The technique is interesting allows for the drawing of 2762 objects probably some more, and the framerate remains useable.
While normally, frame rate is unusable when it tanks below the draw rate.
in the below video, the frame rate has been pushed to less than 20 frames per second, less 20 draw per second. with the introduction of i would describe reasonably complex geometry on space bar. in total 2700 obj contain multiple sub mesh.
What you are seeing is that the frame rate and the draw rate are still aligned when the engine is tanked with too much geometry objects. Every object here is also iterated and told to rotate seperately at the same rate as the draw rate.
Remember you are watching a low frame rate video. It suprise me as it is still playable comfortably. Though i have limited camera control implemented as i had been phasing out camera behaviour into a gameloop script. As each game potentially has different camera controls.
if (TIME >= DRAW_TIME)
{
DRAW_TIME = System.DateTime.Now + TimeSpan.FromSeconds(0.01);
DRAW_FRAME = true;
}
if (TIME >= AWAIT_TIME)
{
AWAIT_TIME = DRAW_TIME + TimeSpan.FromSeconds(0.008999999);
}
from the start u see the frames.
this is happening in a basic effect that gets told its material parameters for each mesh in the object coming from txt file data. Drawing to RenderTarget2D. There is no instance drawing everything is an iteration.
switching over to C++/WinRT to better understand why this type of device info is not available.
I have traced i believe the cultprit
QueryPerformanceFrequency
QueryPerformanceFrequency function - Win32 apps | Microsoft Learn
A pointer to a variable that receives the current performance-counter frequency, in counts per second. If the installed hardware doesn’t support a high-resolution performance counter, this parameter can be zero (this will not occur on systems that run Windows XP or later).
GameTimer::GameTimer():
m_active(false)
{
LARGE_INTEGER frequency;
if (!QueryPerformanceFrequency(&frequency))
{
throw ref new Platform::FailureException();
}
m_secondsPerCount = 1.0f / static_cast<float>(frequency.QuadPart);
Reset();
}
perhaps i am wrong.
it states
" Retrieves the frequency of the performance counter. The frequency of the performance counter is fixed at system boot and is consistent across all processors. Therefore, the frequency need only be queried upon application initialization, and the result can be cached. "
SO
why isn’t it available?
Well if the doc is stating that its only queried on application startup, and then the timer maintains that frequency. Then it seems that theres no point constantly checking it. So that must be why
see my producer consumer pattern. Why do you have to fix your timestep instead of having a SetFPS function? - #4 by Jack-Ji
you can get your 8000 fps and just draaw the last good frame, and smooth the frameraete… i use 300fps… for windows… on android i do rull throttle… i dont use locks i cant. android will stutter… if its skiips framess thats fine… its you are running physics or ai, touch is faster thant seeintg… 60 fps is tgood enoug… thad or if you touch your screen it might go to 120 or more…
chapt gpt wil tell you all this… using System;
using System.Collections.Generic;
using System.Threading;
struct FrameData
{
public List Vertices;
public Color Color;
public Vector2D Position;
// Other data as needed
}
class LocklessProducerConsumerRenderer
{
private FrameData frameBuffer;
private int bufferSize;
private volatile int writeIndex = 0;
private volatile int readIndex = 0;
public LocklessProducerConsumerRenderer(int bufferSize)
{
this.bufferSize = bufferSize;
frameBuffer = new FrameData[bufferSize];
}
public void UpdateFrame(FrameData newFrame)
{
int nextWriteIndex = (writeIndex + 1) % bufferSize;
// Check if the buffer is full
if (nextWriteIndex != readIndex)
{
frameBuffer[writeIndex] = newFrame;
writeIndex = nextWriteIndex;
}
else
{
// Handle buffer full situation (e.g., drop frames or wait)
}
}
public void RenderFrames()
{
while (true)
{
if (readIndex != writeIndex)
{
FrameData frameToRender = frameBuffer[readIndex];
readIndex = (readIndex + 1) % bufferSize;
// Render the frame using frameToRender data
// ...
}
else
{
// Handle no frames to render (e.g., wait or continue)
}
}
}
}
“it is likely knowledge that is covetted to high heavens.” i felt the same because its hard to google up because people think its a sort of secret discovery. it was often found that games ran smoothly when chrome was running becuase it had called the system wide . now it only to each application so you can fiddle with it…it will use battery more
dllimport:
public void SetTimerResolution(uint resolutionInMilliseconds)
{
dllimport
(windows only) , set to 4 -ms… to smooth the framerate if you must…16 ms erro is a whole frame… that iwill not stabilize your framerate at all. its frustrating … the bot told me… its nicer than google becuase that doest turn up
i have a game loop on a worker thread…
took me 3 months to figure this how… tried on android with locks i was stuck for a week. the game loop needs to be on another thread. the Hargreaves is talking single thread, and the timestamps for file system. I put nothing in Update. the whole game class is documented to be antiquated. hread box on earth in use… i load 8 cores spawn fro the worker not hte UI thread… i dont konw fi you can use gpu from bk tread i would not… you can tesselate with SIMD now. so you can look at Bepuphysic3… his probably doing similar. t
see the other quiestion about ring buffer… or swap… locks are terrible… cpy in net8 is super fast… probalby let the GC just deal with it… or reuse the bufffers… not sure if its great for 3d… but you could also try compute shader. in bepu he is doing complex collsion detection so his are tesselated on cpu. you mght rather do it more gpu , using ray tracing even… but for mobile you righ now have opengl… if they can put metal in stride with has too much ECS and too much stutf… hopefully MG can allow Vulkan or use the other transpiler that bepu uses, shader conductor… he can just use hlsl files… or fx files