title: DXGI Waitable SwapChain not waiting
body: <p>I setup a DX12 application that only clears the backbuffer every frame.</p>
  
  <p>It really is barebone : no PSO, no root...
  The only particularity is that it waits on the swapChain to be done with Present() before starting a new frame (<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dn268309(v=vs.85).aspx" rel="noreferrer">msdn waitable swap chain</a>) (I set the frame latency to 1 as well and on only have 2 buffers).</p>
  
  <p>The first frame works well but it immediately starts drawing the second frame, and of course, the command allocator complains that it is being reset while commands are still being executed on the GPU.</p>
  
  <p>I could of course setup a fence to wait for the gpu to be done before moving to a new frame, but I thought this was the job of the waitable swap chain object.</p>
  
  <p>Here is the render routine :</p>
  
  
  
  <pre class="lang-c++ prettyprint-override"><code>if (m_command_allocator-&gt;Reset() == E_FAIL) { throw; }
  
  HRESULT res = S_OK;
  res = m_command_list-&gt;Reset(m_command_allocator.Get(), nullptr);
  if (res == E_FAIL || res == E_OUTOFMEMORY) { throw; }
  
  m_command_list-&gt;ResourceBarrier(1, 
  &amp;CD3DX12_RESOURCE_BARRIER::Transition(m_render_targets[m_frame_index].Get(), 
  D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));
  
  m_command_list-&gt;RSSetViewports(1, &amp;m_screen_viewport);
  m_command_list-&gt;RSSetScissorRects(1, &amp;m_scissor_rect);
  m_command_list-&gt;ClearRenderTargetView(get_rtv_handle(), 
  DirectX::Colors::BlueViolet, 0, nullptr);
  m_command_list-&gt;OMSetRenderTargets(1, &amp;get_rtv_handle(), true, nullptr);
  
  m_command_list-&gt;ResourceBarrier(1, 
  &amp;CD3DX12_RESOURCE_BARRIER::Transition(m_render_targets[m_frame_index].Get(), 
  D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));
  
  tools::throw_if_failed(m_command_list-&gt;Close());
  ID3D12CommandList* ppCommandLists[] = { m_command_list.Get() };
  m_command_queue-&gt;ExecuteCommandLists(_countof(ppCommandLists), 
  ppCommandLists);
  
  if (m_swap_chain-&gt;Present(1, 0) != S_OK) { throw; }
  m_frame_index = m_swap_chain-&gt;GetCurrentBackBufferIndex();
  </code></pre>
  
  <p>I loop on this routine with a waitable object wich I got from the swapchain :</p>
  
  <pre class="lang-c++ prettyprint-override"><code>while (WAIT_OBJECT_0 == WaitForSingleObjectEx(waitable_renderer, INFINITE, TRUE) &amp;&amp; m_alive == true)
  {
      m_graphics.render();
  }
  </code></pre>
  
  <p>and I initialized the swapchain with the waitable flag :</p>
  
  <pre class="lang-c++ prettyprint-override"><code>DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
  swap_chain_desc.BufferCount = s_frame_count;
  swap_chain_desc.Width = window_width;
  swap_chain_desc.Height = window_height;
  swap_chain_desc.Format = m_back_buffer_format;
  swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
  swap_chain_desc.SampleDesc.Count = 1;
  swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
  
  ComPtr&lt;IDXGISwapChain1&gt; swap_chain;
  tools::throw_if_failed(
      factory-&gt;CreateSwapChainForHwnd(m_command_queue.Get(), window_handle, &amp;swap_chain_desc, nullptr, nullptr, &amp;swap_chain));
  </code></pre>
  
  <p>I call the SetFrameLatency right after creating the swapChain :</p>
  
  <pre class="lang-c++ prettyprint-override"><code>ComPtr&lt;IDXGISwapChain2&gt; swap_chain2;
  tools::throw_if_failed(m_swap_chain.As(&amp;swap_chain2));
  
  tools::throw_if_failed(swap_chain2-&gt;SetMaximumFrameLatency(1));
  
  m_waitable_renderer = swap_chain2-&gt;GetFrameLatencyWaitableObject();
  </code></pre>
  
  <p>And the swapChain resize that goes with it :</p>
  
  <pre class="lang-c++ prettyprint-override"><code>tools::throw_if_failed(
      m_swap_chain-&gt;ResizeBuffers(s_frame_count, window_width, window_height, m_back_buffer_format, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT));
  </code></pre>
  
  <p>My question is : Am I setting something up incorrectly ? or is this the way waitable swap chain works (ie you also need to sync with gpu with fences before waiting for the swap chain to become available) ?</p>
  
  <p><strong>EDIT:</strong> Adding SetFrameLatency call + C++ coloring</p>