diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp
index 12fedd3a7..662a61f3f 100644
--- a/src/dxgi/dxgi_adapter.cpp
+++ b/src/dxgi/dxgi_adapter.cpp
@@ -36,6 +36,7 @@ namespace dxvk {
      || riid == __uuidof(IDXGIAdapter)
      || riid == __uuidof(IDXGIAdapter1)
      || riid == __uuidof(IDXGIAdapter2)
+     || riid == __uuidof(IDXGIAdapter3)
      || riid == __uuidof(IDXGIVkAdapter)) {
       *ppvObject = ref(this);
       return S_OK;
@@ -208,6 +209,95 @@ namespace dxvk {
   }
   
   
+  HRESULT STDMETHODCALLTYPE DxgiAdapter::QueryVideoMemoryInfo(
+          UINT                          NodeIndex,
+          DXGI_MEMORY_SEGMENT_GROUP     MemorySegmentGroup,
+          DXGI_QUERY_VIDEO_MEMORY_INFO* pVideoMemoryInfo) {
+    if (NodeIndex > 0 || !pVideoMemoryInfo)
+      return DXGI_ERROR_INVALID_CALL;
+    
+    if (MemorySegmentGroup != DXGI_MEMORY_SEGMENT_GROUP_LOCAL
+     && MemorySegmentGroup != DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL)
+      return DXGI_ERROR_INVALID_CALL;
+    
+    DxvkAdapterMemoryInfo memInfo = m_adapter->getMemoryHeapInfo();
+
+    VkMemoryHeapFlags heapFlagMask = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
+    VkMemoryHeapFlags heapFlags    = 0;
+
+    if (MemorySegmentGroup == DXGI_MEMORY_SEGMENT_GROUP_LOCAL)
+      heapFlags |= VK_MEMORY_HEAP_DEVICE_LOCAL_BIT;
+    
+    pVideoMemoryInfo->Budget       = 0;
+    pVideoMemoryInfo->CurrentUsage = 0;
+
+    for (uint32_t i = 0; i < memInfo.heapCount; i++) {
+      if ((memInfo.heaps[i].heapFlags & heapFlagMask) != heapFlags)
+        continue;
+      
+      pVideoMemoryInfo->Budget       += memInfo.heaps[i].memoryAvailable;
+      pVideoMemoryInfo->CurrentUsage += memInfo.heaps[i].memoryAllocated;
+    }
+
+    // We don't implement reservation, but the observable
+    // behaviour should match that of Windows drivers
+    uint32_t segmentId = uint32_t(MemorySegmentGroup);
+
+    pVideoMemoryInfo->AvailableForReservation = pVideoMemoryInfo->Budget / 2;
+    pVideoMemoryInfo->CurrentReservation      = m_memReservation[segmentId];
+    return S_OK;
+  }
+
+
+  HRESULT STDMETHODCALLTYPE DxgiAdapter::SetVideoMemoryReservation(
+          UINT                          NodeIndex,
+          DXGI_MEMORY_SEGMENT_GROUP     MemorySegmentGroup,
+          UINT64                        Reservation) {
+    DXGI_QUERY_VIDEO_MEMORY_INFO info;
+
+    HRESULT hr = QueryVideoMemoryInfo(
+      NodeIndex, MemorySegmentGroup, &info);
+    
+    if (FAILED(hr))
+      return hr;
+    
+    if (Reservation > info.AvailableForReservation)
+      return DXGI_ERROR_INVALID_CALL;
+    
+    uint32_t segmentId = uint32_t(MemorySegmentGroup);
+    m_memReservation[segmentId] = Reservation;
+    return S_OK;
+  }
+
+  
+  HRESULT STDMETHODCALLTYPE DxgiAdapter::RegisterHardwareContentProtectionTeardownStatusEvent(
+          HANDLE                        hEvent,
+          DWORD*                        pdwCookie) {
+    Logger::err("DxgiAdapter::RegisterHardwareContentProtectionTeardownStatusEvent: Not implemented");
+    return E_NOTIMPL;
+  }
+
+
+  HRESULT STDMETHODCALLTYPE DxgiAdapter::RegisterVideoMemoryBudgetChangeNotificationEvent(
+          HANDLE                        hEvent,
+          DWORD*                        pdwCookie) {
+    Logger::err("DxgiAdapter::RegisterVideoMemoryBudgetChangeNotificationEvent: Not implemented");
+    return E_NOTIMPL;
+  }
+  
+
+  void STDMETHODCALLTYPE DxgiAdapter::UnregisterHardwareContentProtectionTeardownStatus(
+          DWORD                         dwCookie) {
+    Logger::err("DxgiAdapter::UnregisterHardwareContentProtectionTeardownStatus: Not implemented");
+  }
+
+
+  void STDMETHODCALLTYPE DxgiAdapter::UnregisterVideoMemoryBudgetChangeNotification(
+          DWORD                         dwCookie) {
+    Logger::err("DxgiAdapter::UnregisterVideoMemoryBudgetChangeNotification: Not implemented");
+  }
+
+
   Rc<DxvkAdapter> STDMETHODCALLTYPE DxgiAdapter::GetDXVKAdapter() {
     return m_adapter;
   }
diff --git a/src/dxgi/dxgi_adapter.h b/src/dxgi/dxgi_adapter.h
index 9ca692bb0..d204b8a53 100644
--- a/src/dxgi/dxgi_adapter.h
+++ b/src/dxgi/dxgi_adapter.h
@@ -46,6 +46,30 @@ namespace dxvk {
     HRESULT STDMETHODCALLTYPE GetDesc2(
             DXGI_ADAPTER_DESC2*       pDesc) final;
     
+    HRESULT STDMETHODCALLTYPE QueryVideoMemoryInfo(
+            UINT                          NodeIndex,
+            DXGI_MEMORY_SEGMENT_GROUP     MemorySegmentGroup,
+            DXGI_QUERY_VIDEO_MEMORY_INFO* pVideoMemoryInfo) final;
+
+    HRESULT STDMETHODCALLTYPE SetVideoMemoryReservation(
+            UINT                          NodeIndex,
+            DXGI_MEMORY_SEGMENT_GROUP     MemorySegmentGroup,
+            UINT64                        Reservation) final;
+    
+    HRESULT STDMETHODCALLTYPE RegisterHardwareContentProtectionTeardownStatusEvent(
+            HANDLE                        hEvent,
+            DWORD*                        pdwCookie) final;
+
+    HRESULT STDMETHODCALLTYPE RegisterVideoMemoryBudgetChangeNotificationEvent(
+            HANDLE                        hEvent,
+            DWORD*                        pdwCookie) final;
+    
+    void STDMETHODCALLTYPE UnregisterHardwareContentProtectionTeardownStatus(
+            DWORD                         dwCookie) final;
+
+    void STDMETHODCALLTYPE UnregisterVideoMemoryBudgetChangeNotification(
+            DWORD                         dwCookie) final;
+
     Rc<DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() final;
     
     HRESULT STDMETHODCALLTYPE CreateDevice(
@@ -81,6 +105,7 @@ namespace dxvk {
     Rc<DxvkAdapter>   m_adapter;
     
     DXGIVkFormatTable m_formats;
+    UINT64            m_memReservation[2] = { 0, 0 };
     
     std::mutex        m_outputMutex;
     OutputMap         m_outputData;
diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h
index 4405949b9..c63262bb9 100644
--- a/src/dxgi/dxgi_interfaces.h
+++ b/src/dxgi/dxgi_interfaces.h
@@ -89,7 +89,7 @@ IDXGIVkDevice : public IDXGIDevice3 {
  * this interface.
  */
 MIDL_INTERFACE("907bf281-ea3c-43b4-a8e4-9f231107b4ff")
-IDXGIVkAdapter : public IDXGIAdapter2 {
+IDXGIVkAdapter : public IDXGIAdapter3 {
   static const GUID guid;
   
   virtual dxvk::Rc<dxvk::DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() = 0;