Original Post
I am busy with a small C++ DX11 engine. I made a spritebatch and it can render ~8000 sprites in ~0.015 seconds, which is quite nice. But the actual "feel" is really sluggish. So i checked which line of code takes so much longer and it's actually the swapchain->present.
As you can see, there is no vsync enabled. Below is a copy from my console output.
"Time" means the time in seconds for my spritebatch to render (4000 sprites in this example). Most of the time its around 0.005 seconds, or 5 ms.
"Time Present" is the amount of time it takes for swapchain->Present(0,0); to finish. This is usually < 0.001 seconds, but sometimes jumps up to 0.2 or even 0.4 seconds!
"timeInSeconds" is the total amount a frame takes (WindowEvents & Update & Draw)
Note: I am only rendering one texture, in 4 different places. And the code is run in optimized release mode without debugger attached. There is no difference between 'windowed' or 'fullscreen' mode. The console print is from 'windowed' mode
Code for creating the swapchain:
swapChain->Present(0, 0);
As you can see, there is no vsync enabled. Below is a copy from my console output.
"Time" means the time in seconds for my spritebatch to render (4000 sprites in this example). Most of the time its around 0.005 seconds, or 5 ms.
"Time Present" is the amount of time it takes for swapchain->Present(0,0); to finish. This is usually < 0.001 seconds, but sometimes jumps up to 0.2 or even 0.4 seconds!
"timeInSeconds" is the total amount a frame takes (WindowEvents & Update & Draw)
Note: I am only rendering one texture, in 4 different places. And the code is run in optimized release mode without debugger attached. There is no difference between 'windowed' or 'fullscreen' mode. The console print is from 'windowed' mode
GPU Name: ATI Radeon HD 5700 Series Memory: 499
Loaded texture: Content/emmahawt.png [818 x 542]
Loaded texture: Content/test.png [2 x 2]
Time : 0.005598
Time Present : 0.000715
timeInSeconds : 0.007079
Time : 0.005138
Time Present : 0.000327
timeInSeconds : 0.005817
Time : 0.005006
Time Present : 0.000323
timeInSeconds : 0.005702
Time : 0.004893
Time Present : 0.218834
timeInSeconds : 0.224316
Time : 0.004375
Time Present : 0.436552
timeInSeconds : 0.441346
Time : 0.004092
Time Present : 0.000649
timeInSeconds : 0.442094
Time : 0.004252
Time Present : 0.000592
timeInSeconds : 0.007898
Time : 0.004191
Time Present : 0.000498
timeInSeconds : 0.005948
Time : 0.004361
Time Present : 0.199789
timeInSeconds : 0.207114
Time : 0.003872
Time Present : 0.879333
timeInSeconds : 0.884902
Time : 0.004544
Time Present : 0.001660
timeInSeconds : 0.034172
Time : 0.003994
Time Present : 0.000405
timeInSeconds : 0.006845
Time : 0.004393
Time Present : 0.000279
timeInSeconds : 0.005872
Time : 0.003892
Time Present : 0.643319
timeInSeconds : 0.649605
Time : 0.004066
Time Present : 0.000291
timeInSeconds : 0.230853
Time : 0.004023
Time Present : 0.000440
timeInSeconds : 0.007868
Time : 0.004655
Time Present : 0.000263
timeInSeconds : 0.006101
Time : 0.004221
Time Present : 0.203712
timeInSeconds : 0.208846
Time : 0.005497
Time Present : 0.655746
timeInSeconds : 0.663833
Time : 0.006069
Time Present : 0.000398
timeInSeconds : 0.236720
Time : 0.005969
Time Present : 0.000433
timeInSeconds : 0.010679
[....]
Average FPS was (rendering 4000 sprites): 68.938774
timeInSeconds : 0.227208
Time : 0.003952
Time Present : 0.000257
Press any key to continue . . .
Code for creating the swapchain:
void GraphicsDevice::InitSwapChain()
{
HRESULT result;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
// Initialize the swap chain description.
memset(&swapChainDesc,0, sizeof(swapChainDesc));
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = windowHandler->GetCurrentWidth();
swapChainDesc.BufferDesc.Height = windowHandler->GetCurrentHeight();
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = windowHandler->GetHandler();
swapChainDesc.Windowed = !windowHandler->GetFullScreen();
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
// Set the refresh rate of the back buffer.
if(vsync)
{
swapChainDesc.BufferDesc.RefreshRate.Numerator = refreshRateNum;
swapChainDesc.BufferDesc.RefreshRate.Denominator = refreshRateDenom;
}
else
{
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
}
// Set the scan line ordering and scaling to unspecified.
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// Discard the back buffer contents after presenting.
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
// Don't set the advanced flags.
swapChainDesc.Flags = 0;
// Set the feature level to DirectX 11/10.1/10
D3D_FEATURE_LEVEL featureLevel[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
// Create the swap chain, Direct3D device, and Direct3D device context.
result = D3D11CreateDeviceAndSwapChain( NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
#ifdef _DEBUG
D3D11_CREATE_DEVICE_DEBUG,
#else
0,
#endif
featureLevel,
4,
D3D11_SDK_VERSION,
&swapChainDesc,
&swapChain,
&device,
NULL,
&deviceContext);
assert(!result);
}