From b389c9ea1f6ec7c36fd4a6f3a9831b1c7c753d24 Mon Sep 17 00:00:00 2001
From: Philip Rebohle <philip.rebohle@tu-dortmund.de>
Date: Wed, 29 Nov 2017 20:19:40 +0100
Subject: [PATCH] [d3d11] Experimental implementation of OMSetRenderTargets and
 ClearRenderTargetView

---
 src/d3d11/d3d11_context.cpp     |  96 ++++++++++++++++++++-
 src/d3d11/d3d11_context.h       |   5 +-
 src/d3d11/d3d11_context_state.h |  18 ++++
 src/d3d11/d3d11_device.cpp      | 146 +++++++++++++++++++++++++++++---
 src/d3d11/d3d11_interfaces.h    |  45 ++++++++++
 src/d3d11/d3d11_texture.cpp     |   6 ++
 src/d3d11/d3d11_texture.h       |   4 +-
 src/d3d11/d3d11_view.cpp        |  16 +++-
 src/d3d11/d3d11_view.h          |  11 ++-
 src/dxvk/dxvk_context.cpp       |   2 +
 src/dxvk/dxvk_device.cpp        |   1 +
 src/util/com/com_guid.cpp       |  16 ++--
 12 files changed, 336 insertions(+), 30 deletions(-)
 create mode 100644 src/d3d11/d3d11_context_state.h

diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp
index ab9df7be2..23c403598 100644
--- a/src/d3d11/d3d11_context.cpp
+++ b/src/d3d11/d3d11_context.cpp
@@ -1,3 +1,5 @@
+#include <cstring>
+
 #include "d3d11_context.h"
 #include "d3d11_device.h"
 
@@ -168,7 +170,53 @@ namespace dxvk {
   void D3D11DeviceContext::ClearRenderTargetView(
           ID3D11RenderTargetView*           pRenderTargetView,
     const FLOAT                             ColorRGBA[4]) {
-    Logger::err("D3D11DeviceContext::ClearRenderTargetView: Not implemented");
+    Com<ID3D11RenderTargetViewPrivate> rtv;
+    pRenderTargetView->QueryInterface(
+      __uuidof(ID3D11RenderTargetViewPrivate),
+      reinterpret_cast<void**>(&rtv));
+    
+    // Find out whether the given attachment is currently bound
+    // or not, and if it is, which attachment index it has.
+    int32_t attachmentIndex = -1;
+    
+    for (uint32_t i = 0; i < m_state.omRenderTargetViews.size(); i++) {
+      if (rtv.ptr() == m_state.omRenderTargetViews.at(i).ptr())
+        attachmentIndex = static_cast<int32_t>(i);
+    }
+    
+    if (attachmentIndex < 0) {
+      // FIXME bind render target, then restore framebuffer or mark dirty
+      Logger::err("D3D11DeviceContext::ClearRenderTargetView: Render target not bound. This is currently not supported.");
+      return;
+    }
+    
+    // Retrieve image info, which we will need in
+    // order to determine the size of the clear area
+    const Rc<DxvkImage> image = rtv->GetDXVKImageView()->image();
+    
+    // Set up attachment info and copy the clear color
+    VkClearAttachment clearInfo;
+    clearInfo.aspectMask      = VK_IMAGE_ASPECT_COLOR_BIT;
+    clearInfo.colorAttachment = static_cast<uint32_t>(attachmentIndex);
+    
+    std::memcpy(clearInfo.clearValue.color.float32, ColorRGBA,
+      sizeof(clearInfo.clearValue.color.float32));
+    
+    // Clear the full area. On FL 9.x, only the first array
+    // layer will be cleared, rather than all array layers.
+    VkClearRect clearRect;
+    clearRect.rect.offset.x       = 0;
+    clearRect.rect.offset.y       = 0;
+    clearRect.rect.extent.width   = image->info().extent.width;
+    clearRect.rect.extent.height  = image->info().extent.height;
+    clearRect.baseArrayLayer      = 0;
+    clearRect.layerCount          = image->info().numLayers;
+    
+    if (m_parent->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0)
+      clearRect.layerCount        = 1;
+    
+    // Record the clear operation
+    m_context->clearRenderTarget(clearInfo, clearRect);
   }
   
   
@@ -780,7 +828,37 @@ namespace dxvk {
           UINT                              NumViews,
           ID3D11RenderTargetView* const*    ppRenderTargetViews,
           ID3D11DepthStencilView*           pDepthStencilView) {
-    Logger::err("D3D11DeviceContext::OMSetRenderTargets: Not implemented");
+    // Update state vector for OMGetRenderTargets
+    for (UINT i = 0; i < m_state.omRenderTargetViews.size(); i++) {
+      Com<ID3D11RenderTargetViewPrivate> view = nullptr;
+      
+      if ((i < NumViews) && (ppRenderTargetViews[i] != nullptr)) {
+        ppRenderTargetViews[i]->QueryInterface(
+          __uuidof(ID3D11RenderTargetViewPrivate),
+          reinterpret_cast<void**>(&view));
+      }
+      
+      m_state.omRenderTargetViews.at(i) = view;
+    }
+    
+    // TODO unbind overlapping shader resource views
+    
+    // D3D11 doesn't have the concept of a framebuffer object,
+    // so we'll just create a new one every time the render
+    // target bindings are updated. Set up the attachments.
+    DxvkRenderTargets attachments;
+    
+    for (UINT i = 0; i < m_state.omRenderTargetViews.size(); i++) {
+      if (m_state.omRenderTargetViews.at(i) != nullptr)
+        attachments.setColorTarget(i, m_state.omRenderTargetViews.at(i)->GetDXVKImageView());
+    }
+    
+    // TODO implement depth-stencil views
+    if (pDepthStencilView != nullptr)
+      Logger::err("D3D11DeviceContext::OMSetRenderTargets: Depth-stencil view not supported");
+    
+    // Create and bind the framebuffer object using the given attachments
+    m_context->bindFramebuffer(m_device->createFramebuffer(attachments));
   }
   
   
@@ -791,7 +869,7 @@ namespace dxvk {
           UINT                              UAVStartSlot,
           UINT                              NumUAVs,
           ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
-    const UINT* pUAVInitialCounts) {
+    const UINT*                             pUAVInitialCounts) {
     Logger::err("D3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews: Not implemented");
   }
   
@@ -815,7 +893,17 @@ namespace dxvk {
           UINT                              NumViews,
           ID3D11RenderTargetView**          ppRenderTargetViews,
           ID3D11DepthStencilView**          ppDepthStencilView) {
-    Logger::err("D3D11DeviceContext::OMGetRenderTargets: Not implemented");
+    if (ppRenderTargetViews != nullptr) {
+      for (UINT i = 0; i < NumViews; i++)
+        ppRenderTargetViews[i] = i < m_state.omRenderTargetViews.size()
+          ? m_state.omRenderTargetViews.at(i).ref()
+          : nullptr;
+    }
+    
+    if (ppDepthStencilView != nullptr) {
+      Logger::err("D3D11DeviceContext::OMGetRenderTargets: Stencil view not supported");
+      *ppDepthStencilView = nullptr;
+    }
   }
   
   
diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h
index 1c52d5ff1..778f233ee 100644
--- a/src/d3d11/d3d11_context.h
+++ b/src/d3d11/d3d11_context.h
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "d3d11_context_state.h"
 #include "d3d11_device_child.h"
 
 #include <dxvk_adapter.h>
@@ -471,7 +472,7 @@ namespace dxvk {
             UINT                              UAVStartSlot,
             UINT                              NumUAVs,
             ID3D11UnorderedAccessView* const* ppUnorderedAccessViews,
-      const UINT* pUAVInitialCounts) final;
+      const UINT*                             pUAVInitialCounts) final;
     
     void OMSetBlendState(
             ID3D11BlendState*                 pBlendState,
@@ -546,6 +547,8 @@ namespace dxvk {
     Rc<DxvkContext>     m_context;
     Rc<DxvkCommandList> m_cmdList;
     
+    D3D11ContextState   m_state;
+    
   };
   
 }
diff --git a/src/d3d11/d3d11_context_state.h b/src/d3d11/d3d11_context_state.h
new file mode 100644
index 000000000..e81546c51
--- /dev/null
+++ b/src/d3d11/d3d11_context_state.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <array>
+
+#include "d3d11_interfaces.h"
+
+namespace dxvk {
+  
+  /**
+   * \brief Context state
+   */
+  struct D3D11ContextState {
+    std::array<
+      Com<ID3D11RenderTargetViewPrivate>,
+      D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> omRenderTargetViews;
+  };
+  
+}
\ No newline at end of file
diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp
index aae531260..7bd3322b0 100644
--- a/src/d3d11/d3d11_device.cpp
+++ b/src/d3d11/d3d11_device.cpp
@@ -106,19 +106,6 @@ namespace dxvk {
           ID3D11Resource*                   pResource,
     const D3D11_RENDER_TARGET_VIEW_DESC*    pDesc,
           ID3D11RenderTargetView**          ppRTView) {
-    // TODO fill desc
-    // TODO create view
-    D3D11_RENDER_TARGET_VIEW_DESC desc;
-    
-    *ppRTView = ref(new D3D11RenderTargetView(this, desc));
-    return S_OK;
-  }
-  
-  
-  HRESULT D3D11Device::CreateDepthStencilView(
-          ID3D11Resource*                   pResource,
-    const D3D11_DEPTH_STENCIL_VIEW_DESC*    pDesc,
-          ID3D11DepthStencilView**          ppDepthStencilView) {
     D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
     pResource->GetType(&resourceDim);
     
@@ -128,9 +115,140 @@ namespace dxvk {
       return E_INVALIDARG;
     }
     
+    // Make sure we can retrieve the image object
+    Com<ID3D11Texture2DPrivate> texture = nullptr;
     
+    if (FAILED(pResource->QueryInterface(__uuidof(ID3D11Texture2DPrivate),
+          reinterpret_cast<void**>(&texture)))) {
+      Logger::err("D3D11Device::CreateRenderTargetView: Invalid texture");
+      return E_INVALIDARG;
+    }
     
-    Logger::err("D3D11Device::CreateRenderTargetView: Not implemented");
+    // Image that we are going to create the view for
+    const Rc<DxvkImage> image = texture->GetDXVKImage();
+    
+    // The view description is optional. If not defined, it
+    // will use the resource's format and all subresources.
+    D3D11_RENDER_TARGET_VIEW_DESC desc;
+    
+    if (pDesc != nullptr) {
+      desc = *pDesc;
+    } else {
+      D3D11_TEXTURE2D_DESC texDesc;
+      texture->GetDesc(&texDesc);
+      
+      // Select the view dimension based on the
+      // texture's array size and sample count.
+      const std::array<D3D11_RTV_DIMENSION, 4> viewDims = {
+        D3D11_RTV_DIMENSION_TEXTURE2D,
+        D3D11_RTV_DIMENSION_TEXTURE2DARRAY,
+        D3D11_RTV_DIMENSION_TEXTURE2DMS,
+        D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY,
+      };
+      
+      uint32_t viewDimIndex = 0;
+      
+      if (texDesc.ArraySize > 1)
+        viewDimIndex |= 0x1;
+      
+      if (texDesc.SampleDesc.Count > 1)
+        viewDimIndex |= 0x2;
+      
+      // Fill the correct union member
+      desc.ViewDimension = viewDims.at(viewDimIndex);
+      desc.Format = texDesc.Format;
+      
+      switch (desc.ViewDimension) {
+        case D3D11_RTV_DIMENSION_TEXTURE2D:
+          desc.Texture2D.MipSlice = 0;
+          break;
+          
+        case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
+          desc.Texture2DArray.MipSlice        = 0;
+          desc.Texture2DArray.FirstArraySlice = 0;
+          desc.Texture2DArray.ArraySize       = texDesc.ArraySize;
+          break;
+        
+        case D3D11_RTV_DIMENSION_TEXTURE2DMS:
+          break;
+          
+        case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
+          desc.Texture2DMSArray.FirstArraySlice = 0;
+          desc.Texture2DMSArray.ArraySize       = texDesc.ArraySize;
+          break;
+        
+        default: 
+          Logger::err("D3D11Device::CreateRenderTargetView: Internal error");
+          return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
+      }
+    }
+    
+    // Fill in Vulkan image view info
+    DxvkImageViewCreateInfo viewInfo;
+    // FIXME look up Vulkan format for DXGI format
+    viewInfo.format     = image->info().format;
+    viewInfo.aspect     = VK_IMAGE_ASPECT_COLOR_BIT;
+    
+    switch (desc.ViewDimension) {
+      case D3D11_RTV_DIMENSION_TEXTURE2D:
+        viewInfo.type       = VK_IMAGE_VIEW_TYPE_2D;
+        viewInfo.minLevel   = desc.Texture2D.MipSlice;
+        viewInfo.numLevels  = 1;
+        viewInfo.minLayer   = 0;
+        viewInfo.numLayers  = 1;
+        break;
+        
+      case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
+        viewInfo.type       = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
+        viewInfo.minLevel   = desc.Texture2DArray.MipSlice;
+        viewInfo.numLevels  = 1;
+        viewInfo.minLayer   = desc.Texture2DArray.FirstArraySlice;
+        viewInfo.numLayers  = desc.Texture2DArray.ArraySize;
+        break;
+        
+      case D3D11_RTV_DIMENSION_TEXTURE2DMS:
+        viewInfo.type       = VK_IMAGE_VIEW_TYPE_2D;
+        viewInfo.minLevel   = 0;
+        viewInfo.numLevels  = 1;
+        viewInfo.minLayer   = 0;
+        viewInfo.numLayers  = 1;
+        break;
+      
+      case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
+        viewInfo.type       = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
+        viewInfo.minLevel   = 0;
+        viewInfo.numLevels  = 1;
+        viewInfo.minLayer   = desc.Texture2DArray.FirstArraySlice;
+        viewInfo.numLayers  = desc.Texture2DArray.ArraySize;
+        break;
+      
+      default:
+        Logger::err(str::format(
+          "D3D11Device::CreateRenderTargetView: pDesc->ViewDimension not supported: ",
+          desc.ViewDimension));
+        return E_INVALIDARG;
+    }
+    
+    // Create the actual image view if requested
+    if (ppRTView == nullptr)
+      return S_OK;
+    
+    try {
+      Rc<DxvkImageView> view = m_dxvkDevice->createImageView(image, viewInfo);
+      *ppRTView = ref(new D3D11RenderTargetView(this, pResource, desc, view));
+      return S_OK;
+    } catch (const DxvkError& e) {
+      Logger::err(e.message());
+      return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
+    }
+  }
+  
+  
+  HRESULT D3D11Device::CreateDepthStencilView(
+          ID3D11Resource*                   pResource,
+    const D3D11_DEPTH_STENCIL_VIEW_DESC*    pDesc,
+          ID3D11DepthStencilView**          ppDepthStencilView) {
+    Logger::err("D3D11Device::CreateDepthStencilView: Not implemented");
     return E_NOTIMPL;
   }
   
diff --git a/src/d3d11/d3d11_interfaces.h b/src/d3d11/d3d11_interfaces.h
index 82ccb797b..445bfefca 100644
--- a/src/d3d11/d3d11_interfaces.h
+++ b/src/d3d11/d3d11_interfaces.h
@@ -6,3 +6,48 @@
 
 #include "../dxvk/dxvk_device.h"
 
+MIDL_INTERFACE("776fc4de-9cd9-4a4d-936a-7837d20ec5d9")
+ID3D11BufferPrivate : public ID3D11Buffer {
+  static const GUID guid;
+  
+  virtual dxvk::Rc<dxvk::DxvkBuffer> GetDXVKBuffer() = 0;
+};
+
+
+MIDL_INTERFACE("cc62022f-eb7c-473c-b58c-c621bc27b405")
+ID3D11Texture1DPrivate : public ID3D11Texture1D {
+  static const GUID guid;
+  
+  virtual dxvk::Rc<dxvk::DxvkImage> GetDXVKImage() = 0;
+};
+
+
+MIDL_INTERFACE("0ca9d5af-96e6-41f2-a2c0-6b43d4dc837d")
+ID3D11Texture2DPrivate : public ID3D11Texture2D {
+  static const GUID guid;
+  
+  virtual dxvk::Rc<dxvk::DxvkImage> GetDXVKImage() = 0;
+};
+
+
+MIDL_INTERFACE("b0f7d56e-761e-46c0-8fca-d465b742b2f8")
+ID3D11Texture3DPrivate : public ID3D11Texture3D {
+  static const GUID guid;
+  
+  virtual dxvk::Rc<dxvk::DxvkImage> GetDXVKImage() = 0;
+};
+
+
+MIDL_INTERFACE("175a9e94-115c-416a-967d-afabadfa0ea8")
+ID3D11RenderTargetViewPrivate : public ID3D11RenderTargetView {
+  static const GUID guid;
+  
+  virtual dxvk::Rc<dxvk::DxvkImageView> GetDXVKImageView() = 0;
+};
+
+
+DXVK_DEFINE_GUID(ID3D11BufferPrivate);
+DXVK_DEFINE_GUID(ID3D11Texture1DPrivate);
+DXVK_DEFINE_GUID(ID3D11Texture2DPrivate);
+DXVK_DEFINE_GUID(ID3D11Texture3DPrivate);
+DXVK_DEFINE_GUID(ID3D11RenderTargetViewPrivate);
\ No newline at end of file
diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp
index 2ff51837f..d4f38d992 100644
--- a/src/d3d11/d3d11_texture.cpp
+++ b/src/d3d11/d3d11_texture.cpp
@@ -24,6 +24,7 @@ namespace dxvk {
     COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
     COM_QUERY_IFACE(riid, ppvObject, ID3D11Resource);
     COM_QUERY_IFACE(riid, ppvObject, ID3D11Texture2D);
+    COM_QUERY_IFACE(riid, ppvObject, ID3D11Texture2DPrivate);
     
     if (riid == __uuidof(IDXGIResource)
      || riid == __uuidof(IDXGIImageResourcePrivate))
@@ -60,4 +61,9 @@ namespace dxvk {
     *pDesc = m_desc;
   }
   
+  
+  Rc<DxvkImage> D3D11Texture2D::GetDXVKImage() {
+    return m_resource->GetDXVKImage();
+  }
+  
 }
diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h
index e323b8587..e253f6cdc 100644
--- a/src/d3d11/d3d11_texture.h
+++ b/src/d3d11/d3d11_texture.h
@@ -10,7 +10,7 @@ namespace dxvk {
   class D3D11Device;
   
   
-  class D3D11Texture2D : public D3D11DeviceChild<ID3D11Texture2D> {
+  class D3D11Texture2D : public D3D11DeviceChild<ID3D11Texture2DPrivate> {
     
   public:
     
@@ -37,6 +37,8 @@ namespace dxvk {
     void GetDesc(
             D3D11_TEXTURE2D_DESC *pDesc) final;
     
+    Rc<DxvkImage> GetDXVKImage() final;
+    
   private:
     
     Com<D3D11Device>                m_device;
diff --git a/src/d3d11/d3d11_view.cpp b/src/d3d11/d3d11_view.cpp
index 7b1fabe8b..7c5778d16 100644
--- a/src/d3d11/d3d11_view.cpp
+++ b/src/d3d11/d3d11_view.cpp
@@ -5,9 +5,13 @@ namespace dxvk {
   
   D3D11RenderTargetView::D3D11RenderTargetView(
           D3D11Device*                    device,
-    const D3D11_RENDER_TARGET_VIEW_DESC&  desc)
+          ID3D11Resource*                 resource,
+    const D3D11_RENDER_TARGET_VIEW_DESC&  desc,
+          Rc<DxvkImageView>               view)
   : m_device  (device),
-    m_desc    (desc) {
+    m_resource(resource),
+    m_desc    (desc),
+    m_view    (view) {
     
   }
   
@@ -22,6 +26,7 @@ namespace dxvk {
     COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild);
     COM_QUERY_IFACE(riid, ppvObject, ID3D11View);
     COM_QUERY_IFACE(riid, ppvObject, ID3D11RenderTargetView);
+    COM_QUERY_IFACE(riid, ppvObject, ID3D11RenderTargetViewPrivate);
     
     Logger::warn("D3D11RenderTargetView::QueryInterface: Unknown interface query");
     return E_NOINTERFACE;
@@ -34,7 +39,7 @@ namespace dxvk {
   
   
   void D3D11RenderTargetView::GetResource(ID3D11Resource **ppResource) {
-    
+    *ppResource = m_resource.ref();
   }
   
   
@@ -42,4 +47,9 @@ namespace dxvk {
     *pDesc = m_desc;
   }
   
+  
+  Rc<DxvkImageView> D3D11RenderTargetView::GetDXVKImageView() {
+    return m_view;
+  }
+  
 }
diff --git a/src/d3d11/d3d11_view.h b/src/d3d11/d3d11_view.h
index b9b84d190..30dcc46e7 100644
--- a/src/d3d11/d3d11_view.h
+++ b/src/d3d11/d3d11_view.h
@@ -8,13 +8,15 @@ namespace dxvk {
   
   class D3D11Device;
   
-  class D3D11RenderTargetView : public D3D11DeviceChild<ID3D11RenderTargetView> {
+  class D3D11RenderTargetView : public D3D11DeviceChild<ID3D11RenderTargetViewPrivate> {
     
   public:
     
     D3D11RenderTargetView(
             D3D11Device*                    device,
-      const D3D11_RENDER_TARGET_VIEW_DESC&  desc);
+            ID3D11Resource*                 resource,
+      const D3D11_RENDER_TARGET_VIEW_DESC&  desc,
+            Rc<DxvkImageView>               view);
     ~D3D11RenderTargetView();
     
     HRESULT QueryInterface(
@@ -30,10 +32,15 @@ namespace dxvk {
     void GetDesc(
             D3D11_RENDER_TARGET_VIEW_DESC* pDesc) final;
     
+    Rc<DxvkImageView> GetDXVKImageView() final;
+    
   private:
     
     Com<D3D11Device>              m_device;
+    Com<ID3D11Resource>           m_resource;
+    
     D3D11_RENDER_TARGET_VIEW_DESC m_desc;
+    Rc<DxvkImageView>             m_view;
     
   };
   
diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp
index ed65c4926..15c066b11 100644
--- a/src/dxvk/dxvk_context.cpp
+++ b/src/dxvk/dxvk_context.cpp
@@ -282,6 +282,8 @@ namespace dxvk {
       
       m_cmd->cmdBeginRenderPass(&info,
         VK_SUBPASS_CONTENTS_INLINE);
+      m_cmd->trackResource(
+        m_state.om.framebuffer);
     }
   }
   
diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp
index 60923d21a..ed606fa23 100644
--- a/src/dxvk/dxvk_device.cpp
+++ b/src/dxvk/dxvk_device.cpp
@@ -67,6 +67,7 @@ namespace dxvk {
   Rc<DxvkImage> DxvkDevice::createImage(
     const DxvkImageCreateInfo&  createInfo,
           VkMemoryPropertyFlags memoryType) {
+    // TODO record image initialization commands
     return new DxvkImage(m_vkd,
       createInfo, *m_memory, memoryType);
   }
diff --git a/src/util/com/com_guid.cpp b/src/util/com/com_guid.cpp
index d2145f9e8..476b308f9 100644
--- a/src/util/com/com_guid.cpp
+++ b/src/util/com/com_guid.cpp
@@ -4,11 +4,17 @@
 
 #include "../../dxgi/dxgi_interfaces.h"
 
-const GUID IDXGIAdapterPrivate::guid        = {0x907bf281,0xea3c,0x43b4,{0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff}};
-const GUID IDXGIDevicePrivate::guid         = {0x7a622cf6,0x627a,0x46b2,{0xb5,0x2f,0x36,0x0e,0xf3,0xda,0x83,0x1c}};
-const GUID IDXGIPresentDevicePrivate::guid  = {0x79352328,0x16f2,0x4f81,{0x97,0x46,0x9c,0x2e,0x2c,0xcd,0x43,0xcf}};
-const GUID IDXGIBufferResourcePrivate::guid = {0x5679becd,0x8547,0x4d93,{0x96,0xa1,0xe6,0x1a,0x1c,0xe7,0xef,0x37}};
-const GUID IDXGIImageResourcePrivate::guid  = {0x1cfe6592,0x7de0,0x4a07,{0x8d,0xcb,0x45,0x43,0xcb,0xbc,0x6a,0x7d}};
+const GUID IDXGIAdapterPrivate::guid           = {0x907bf281,0xea3c,0x43b4,{0xa8,0xe4,0x9f,0x23,0x11,0x07,0xb4,0xff}};
+const GUID IDXGIDevicePrivate::guid            = {0x7a622cf6,0x627a,0x46b2,{0xb5,0x2f,0x36,0x0e,0xf3,0xda,0x83,0x1c}};
+const GUID IDXGIPresentDevicePrivate::guid     = {0x79352328,0x16f2,0x4f81,{0x97,0x46,0x9c,0x2e,0x2c,0xcd,0x43,0xcf}};
+const GUID IDXGIBufferResourcePrivate::guid    = {0x5679becd,0x8547,0x4d93,{0x96,0xa1,0xe6,0x1a,0x1c,0xe7,0xef,0x37}};
+const GUID IDXGIImageResourcePrivate::guid     = {0x1cfe6592,0x7de0,0x4a07,{0x8d,0xcb,0x45,0x43,0xcb,0xbc,0x6a,0x7d}};
+
+const GUID ID3D11BufferPrivate::guid           = {0x776fc4de,0x9cd9,0x4a4d,{0x93,0x6a,0x78,0x37,0xd2,0x0e,0xc5,0xd9}};
+const GUID ID3D11Texture1DPrivate::guid        = {0xcc62022f,0xeb7c,0x473c,{0xb5,0x8c,0xc6,0x21,0xbc,0x27,0xb4,0x05}};
+const GUID ID3D11Texture2DPrivate::guid        = {0x0ca9d5af,0x96e6,0x41f2,{0xa2,0xc0,0x6b,0x43,0xd4,0xdc,0x83,0x7d}};
+const GUID ID3D11Texture3DPrivate::guid        = {0xb0f7d56e,0x761e,0x46c0,{0x8f,0xca,0xd4,0x65,0xb7,0x42,0xb2,0xf8}};
+const GUID ID3D11RenderTargetViewPrivate::guid = {0x175a9e94,0x115c,0x416a,{0x96,0x7d,0xaf,0xab,0xad,0xfa,0x0e,0xa8}};
 
 std::ostream& operator << (std::ostream& os, REFIID guid) {
   os.width(8);