code:
#include "d3d10_util.h"
#include "d3d10_device.h"

#include "../d3d11/d3d11_device.h"

namespace dxvk {

  UINT ConvertD3D10ResourceFlags(UINT MiscFlags) {
    UINT result = 0;
    if (MiscFlags & D3D10_RESOURCE_MISC_GENERATE_MIPS)
      result |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
    if (MiscFlags & D3D10_RESOURCE_MISC_SHARED)
      result |= D3D11_RESOURCE_MISC_SHARED;
    if (MiscFlags & D3D10_RESOURCE_MISC_TEXTURECUBE)
      result |= D3D11_RESOURCE_MISC_TEXTURECUBE;
    if (MiscFlags & D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX)
      result |= D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
    if (MiscFlags & D3D10_RESOURCE_MISC_GDI_COMPATIBLE)
      result |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
    return result;
  }

  UINT ConvertD3D11ResourceFlags(UINT MiscFlags) {
    UINT result = 0;
    if (MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
      result |= D3D10_RESOURCE_MISC_GENERATE_MIPS;
    if (MiscFlags & D3D11_RESOURCE_MISC_SHARED)
      result |= D3D10_RESOURCE_MISC_SHARED;
    if (MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
      result |= D3D10_RESOURCE_MISC_TEXTURECUBE;
    if (MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
      result |= D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;
    if (MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
      result |= D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
    return result;
  }

  void GetD3D10ResourceFromView(
          ID3D11View*           pSrcView,
          ID3D10Resource**      ppDstResource) {
    Com<ID3D11Resource> d3d11Resource;
    pSrcView->GetResource(&d3d11Resource);
    GetD3D10Resource(d3d11Resource.ptr(), ppDstResource);
  }

  void GetD3D11ResourceFromView(
          ID3D10View*           pSrcView,
          ID3D11Resource**      ppDstResource) {
    Com<ID3D10Resource> d3d10Resource;
    pSrcView->GetResource(&d3d10Resource);
    GetD3D11Resource(d3d10Resource.ptr(), ppDstResource);
  }

  void GetD3D10Resource(
          ID3D11Resource*       pSrcResource,
          ID3D10Resource**      ppDstResource) {
    pSrcResource->QueryInterface(
      __uuidof(ID3D10Resource),
      reinterpret_cast<void**>(ppDstResource));
  }

  void GetD3D11Resource(
          ID3D10Resource*       pSrcResource,
          ID3D11Resource**      ppDstResource) {
    pSrcResource->QueryInterface(
      __uuidof(ID3D11Resource),
      reinterpret_cast<void**>(ppDstResource));
  }

  void GetD3D10Device(
          ID3D11DeviceChild*    pObject,
          ID3D10Device**        ppDevice) {
    ID3D11Device* d3d11Device = nullptr;
    pObject->GetDevice(&d3d11Device);
    *ppDevice = static_cast<D3D11Device*>(d3d11Device)->GetD3D10Interface();
  }

  void GetD3D11Device(
          ID3D11DeviceChild*    pObject,
          ID3D11Device**        ppDevice) {
    pObject->GetDevice(ppDevice);
  }

  void GetD3D11Context(
          ID3D11DeviceChild*    pObject,
          ID3D11DeviceContext** ppContext) {
    Com<ID3D11Device> d3d11Device;
    pObject->GetDevice(&d3d11Device);
    d3d11Device->GetImmediateContext(ppContext);
  }

}


code:
#pragma once

#include "d3d10_include.h"

namespace dxvk {

  /**
   * \brief Converts misc. resource flags
   *
   * Converts the D3D11 misc. resource flags to
   * their D3D10 equivalents and vice versa.
   * \param [in] MiscFlags Original bit mask
   * \returns Converted bit mask
   */
  UINT ConvertD3D10ResourceFlags(UINT MiscFlags);
  UINT ConvertD3D11ResourceFlags(UINT MiscFlags);

  /**
   * \brief Retrieves D3D10 resource from D3D11 view
   *
   * \param [in] pSrcView The D3D11 resource view
   * \param [out] ppDstResource The D3D10 resource
   */
  void GetD3D10ResourceFromView(
          ID3D11View*           pSrcView,
          ID3D10Resource**      ppDstResource);

  /**
   * \brief Retrieves D3D11 resource from D3D10 view
   *
   * \param [in] pSrcView The D3D10 resource view
   * \param [out] ppDstResource The D3D11 resource
   */
  void GetD3D11ResourceFromView(
          ID3D10View*           pSrcView,
          ID3D11Resource**      ppDstResource);

  /**
   * \brief Retrieves D3D10 resource from D3D11 resource
   *
   * \param [in] pSrcResource The D3D11 resource
   * \param [out] ppDstResource The D3D10 resource
   */
  void GetD3D10Resource(
          ID3D11Resource*       pSrcResource,
          ID3D10Resource**      ppDstResource);

  /**
   * \brief Retrieves D3D11 resource from D3D10 resource
   *
   * \param [in] pSrcResource The D3D10 resource
   * \param [out] ppDstResource The D3D11 resource
   */
  void GetD3D11Resource(
          ID3D10Resource*       pSrcResource,
          ID3D11Resource**      ppDstResource);

  /**
   * \brief Retrieves D3D10 device from D3D11 object
   *
   * \param [in] pObject The D3D11 device child
   * \param [out] ppDevice The D3D10 device pointer
   */
  void GetD3D10Device(
          ID3D11DeviceChild*    pObject,
          ID3D10Device**        ppDevice);

  /**
   * \brief Retrieves D3D11 device from D3D11 object
   *
   * \param [in] pObject The D3D11 device child
   * \param [out] ppDevice The D3D11 device pointer
   */
  void GetD3D11Device(
          ID3D11DeviceChild*    pObject,
          ID3D11Device**        ppDevice);

  /**
   * \brief Retrieves D3D11 context from D3D11 object
   *
   * \param [in] pObject The D3D11 device child
   * \param [out] ppContext The D3D11 immediate context
   */
  void GetD3D11Context(
          ID3D11DeviceChild*    pObject,
          ID3D11DeviceContext** ppContext);

}

repo_name: orochi/dxvk


code:
#include "d3d10_view_dsv.h"

#include "../d3d11/d3d11_device.h"
#include "../d3d11/d3d11_view_dsv.h"

namespace dxvk {

  HRESULT STDMETHODCALLTYPE D3D10DepthStencilView::QueryInterface(
          REFIID                    riid,
          void**                    ppvObject) {
    return m_d3d11->QueryInterface(riid, ppvObject);
  }

  ULONG STDMETHODCALLTYPE D3D10DepthStencilView::AddRef() {
    return m_d3d11->AddRef();
  }

  ULONG STDMETHODCALLTYPE D3D10DepthStencilView::Release() {
    return m_d3d11->Release();
  }

  void STDMETHODCALLTYPE D3D10DepthStencilView::GetDevice(
          ID3D10Device**            ppDevice) {
    GetD3D10Device(m_d3d11, ppDevice);
  }

  HRESULT STDMETHODCALLTYPE D3D10DepthStencilView::GetPrivateData(
          REFGUID                   guid,
          UINT*                     pDataSize,
          void*                     pData) {
    return m_d3d11->GetPrivateData(guid, pDataSize, pData);
  }

  HRESULT STDMETHODCALLTYPE D3D10DepthStencilView::SetPrivateData(
          REFGUID                   guid,
          UINT                      DataSize,
    const void*                     pData) {
    return m_d3d11->SetPrivateData(guid, DataSize, pData);
  }

  HRESULT STDMETHODCALLTYPE D3D10DepthStencilView::SetPrivateDataInterface(
          REFGUID                   guid,
    const IUnknown*                 pData) {
    return m_d3d11->SetPrivateDataInterface(guid, pData);
  }

  void STDMETHODCALLTYPE D3D10DepthStencilView::GetResource(
          ID3D10Resource**          ppResource) {
    GetD3D10ResourceFromView(m_d3d11, ppResource);
  }

  void STDMETHODCALLTYPE D3D10DepthStencilView::GetDesc(
          D3D10_DEPTH_STENCIL_VIEW_DESC* pDesc) {
    D3D11_DEPTH_STENCIL_VIEW_DESC d3d11Desc;
    m_d3d11->GetDesc(&d3d11Desc);

    pDesc->ViewDimension = D3D10_DSV_DIMENSION(d3d11Desc.ViewDimension);
    pDesc->Format        = d3d11Desc.Format;

    switch (d3d11Desc.ViewDimension) {
      case D3D11_DSV_DIMENSION_UNKNOWN:
        break;

      case D3D11_DSV_DIMENSION_TEXTURE1D:
        pDesc->Texture1D.MipSlice               = d3d11Desc.Texture1D.MipSlice;
        break;

      case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
        pDesc->Texture1DArray.MipSlice          = d3d11Desc.Texture1DArray.MipSlice;
        pDesc->Texture1DArray.FirstArraySlice   = d3d11Desc.Texture1DArray.FirstArraySlice;
        pDesc->Texture1DArray.ArraySize         = d3d11Desc.Texture1DArray.ArraySize;
        break;

      case D3D11_DSV_DIMENSION_TEXTURE2D:
        pDesc->Texture2D.MipSlice               = d3d11Desc.Texture2D.MipSlice;
        break;

      case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
        pDesc->Texture2DArray.MipSlice          = d3d11Desc.Texture2DArray.MipSlice;
        pDesc->Texture2DArray.FirstArraySlice   = d3d11Desc.Texture2DArray.FirstArraySlice;
        pDesc->Texture2DArray.ArraySize         = d3d11Desc.Texture2DArray.ArraySize;
        break;

      case D3D11_DSV_DIMENSION_TEXTURE2DMS:
        break;

      case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
        pDesc->Texture2DMSArray.FirstArraySlice = d3d11Desc.Texture2DMSArray.FirstArraySlice;
        pDesc->Texture2DMSArray.ArraySize       = d3d11Desc.Texture2DMSArray.ArraySize;
        break;
    }
  }

}


code:
#pragma once

#include "d3d10_util.h"

namespace dxvk {

  class D3D11Device;
  class D3D11DepthStencilView;

  class D3D10DepthStencilView : public ID3D10DepthStencilView {

  public:

    D3D10DepthStencilView(D3D11DepthStencilView* pParent)
    : m_d3d11(pParent) { }

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID                    riid,
            void**                    ppvObject);

    ULONG STDMETHODCALLTYPE AddRef();

    ULONG STDMETHODCALLTYPE Release();

    void STDMETHODCALLTYPE GetDevice(
            ID3D10Device**            ppDevice);

    HRESULT STDMETHODCALLTYPE GetPrivateData(
            REFGUID                   guid,
            UINT*                     pDataSize,
            void*                     pData);

    HRESULT STDMETHODCALLTYPE SetPrivateData(
            REFGUID                   guid,
            UINT                      DataSize,
      const void*                     pData);

    HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
            REFGUID                   guid,
      const IUnknown*                 pData);

    void STDMETHODCALLTYPE GetResource(
            ID3D10Resource**          ppResource);

    void STDMETHODCALLTYPE GetDesc(
            D3D10_DEPTH_STENCIL_VIEW_DESC* pDesc);

    D3D11DepthStencilView* GetD3D11Iface() {
      return m_d3d11;
    }

  private:

    D3D11DepthStencilView* m_d3d11;

  };

}


code:
#include "d3d10_view_rtv.h"

#include "../d3d11/d3d11_device.h"
#include "../d3d11/d3d11_view_rtv.h"

namespace dxvk {

  HRESULT STDMETHODCALLTYPE D3D10RenderTargetView::QueryInterface(
          REFIID                    riid,
          void**                    ppvObject) {
    return m_d3d11->QueryInterface(riid, ppvObject);
  }

  ULONG STDMETHODCALLTYPE D3D10RenderTargetView::AddRef() {
    return m_d3d11->AddRef();
  }

  ULONG STDMETHODCALLTYPE D3D10RenderTargetView::Release() {
    return m_d3d11->Release();
  }

  void STDMETHODCALLTYPE D3D10RenderTargetView::GetDevice(
          ID3D10Device**            ppDevice) {
    GetD3D10Device(m_d3d11, ppDevice);
  }

  HRESULT STDMETHODCALLTYPE D3D10RenderTargetView::GetPrivateData(
          REFGUID                   guid,
          UINT*                     pDataSize,
          void*                     pData) {
    return m_d3d11->GetPrivateData(guid, pDataSize, pData);
  }

  HRESULT STDMETHODCALLTYPE D3D10RenderTargetView::SetPrivateData(
          REFGUID                   guid,
          UINT                      DataSize,
    const void*                     pData) {
    return m_d3d11->SetPrivateData(guid, DataSize, pData);
  }

  HRESULT STDMETHODCALLTYPE D3D10RenderTargetView::SetPrivateDataInterface(
          REFGUID                   guid,
    const IUnknown*                 pData) {
    return m_d3d11->SetPrivateDataInterface(guid, pData);
  }

  void STDMETHODCALLTYPE D3D10RenderTargetView::GetResource(
          ID3D10Resource**          ppResource) {
    GetD3D10ResourceFromView(m_d3d11, ppResource);
  }

  void STDMETHODCALLTYPE D3D10RenderTargetView::GetDesc(
          D3D10_RENDER_TARGET_VIEW_DESC* pDesc) {
    static_assert(sizeof(D3D10_RENDER_TARGET_VIEW_DESC) ==
                  sizeof(D3D11_RENDER_TARGET_VIEW_DESC));

    m_d3d11->GetDesc(reinterpret_cast<D3D11_RENDER_TARGET_VIEW_DESC*>(pDesc));
  }

}


code:
#pragma once

#include "d3d10_util.h"

namespace dxvk {

  class D3D11Device;
  class D3D11RenderTargetView;

  class D3D10RenderTargetView : public ID3D10RenderTargetView {

  public:

    D3D10RenderTargetView(D3D11RenderTargetView* pParent)
    : m_d3d11(pParent) { }

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID                    riid,
            void**                    ppvObject);

    ULONG STDMETHODCALLTYPE AddRef();

    ULONG STDMETHODCALLTYPE Release();

    void STDMETHODCALLTYPE GetDevice(
            ID3D10Device**            ppDevice);

    HRESULT STDMETHODCALLTYPE GetPrivateData(
            REFGUID                   guid,
            UINT*                     pDataSize,
            void*                     pData);

    HRESULT STDMETHODCALLTYPE SetPrivateData(
            REFGUID                   guid,
            UINT                      DataSize,
      const void*                     pData);

    HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
            REFGUID                   guid,
      const IUnknown*                 pData);

    void STDMETHODCALLTYPE GetResource(
            ID3D10Resource**          ppResource);

    void STDMETHODCALLTYPE GetDesc(
            D3D10_RENDER_TARGET_VIEW_DESC* pDesc);

    D3D11RenderTargetView* GetD3D11Iface() {
      return m_d3d11;
    }

  private:

    D3D11RenderTargetView* m_d3d11;

  };

}


code:
#include "d3d10_view_srv.h"

#include "../d3d11/d3d11_device.h"
#include "../d3d11/d3d11_view_srv.h"

namespace dxvk {

  HRESULT STDMETHODCALLTYPE D3D10ShaderResourceView::QueryInterface(
          REFIID                    riid,
          void**                    ppvObject) {
    return m_d3d11->QueryInterface(riid, ppvObject);
  }

  ULONG STDMETHODCALLTYPE D3D10ShaderResourceView::AddRef() {
    return m_d3d11->AddRef();
  }

  ULONG STDMETHODCALLTYPE D3D10ShaderResourceView::Release() {
    return m_d3d11->Release();
  }

  void STDMETHODCALLTYPE D3D10ShaderResourceView::GetDevice(
          ID3D10Device**            ppDevice) {
    GetD3D10Device(m_d3d11, ppDevice);
  }

  HRESULT STDMETHODCALLTYPE D3D10ShaderResourceView::GetPrivateData(
          REFGUID                   guid,
          UINT*                     pDataSize,
          void*                     pData) {
    return m_d3d11->GetPrivateData(guid, pDataSize, pData);
  }

  HRESULT STDMETHODCALLTYPE D3D10ShaderResourceView::SetPrivateData(
          REFGUID                   guid,
          UINT                      DataSize,
    const void*                     pData) {
    return m_d3d11->SetPrivateData(guid, DataSize, pData);
  }

  HRESULT STDMETHODCALLTYPE D3D10ShaderResourceView::SetPrivateDataInterface(
          REFGUID                   guid,
    const IUnknown*                 pData) {
    return m_d3d11->SetPrivateDataInterface(guid, pData);
  }

  void STDMETHODCALLTYPE D3D10ShaderResourceView::GetResource(
          ID3D10Resource**          ppResource) {
    GetD3D10ResourceFromView(m_d3d11, ppResource);
  }

  void STDMETHODCALLTYPE D3D10ShaderResourceView::GetDesc(
          D3D10_SHADER_RESOURCE_VIEW_DESC* pDesc) {
    static_assert(sizeof(D3D10_SHADER_RESOURCE_VIEW_DESC) ==
                  sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));

    m_d3d11->GetDesc(reinterpret_cast<D3D11_SHADER_RESOURCE_VIEW_DESC*>(pDesc));

    if (pDesc->ViewDimension > D3D10_SRV_DIMENSION_TEXTURECUBE)
      pDesc->ViewDimension = D3D10_SRV_DIMENSION_UNKNOWN;
  }

  void STDMETHODCALLTYPE D3D10ShaderResourceView::GetDesc1(
          D3D10_SHADER_RESOURCE_VIEW_DESC1* pDesc) {
    static_assert(sizeof(D3D10_SHADER_RESOURCE_VIEW_DESC1) ==
                  sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));

    m_d3d11->GetDesc(reinterpret_cast<D3D11_SHADER_RESOURCE_VIEW_DESC*>(pDesc));

    if (pDesc->ViewDimension > D3D10_1_SRV_DIMENSION_TEXTURECUBEARRAY)
      pDesc->ViewDimension = D3D10_1_SRV_DIMENSION_UNKNOWN;
  }

}


code:
#pragma once

#include "d3d10_util.h"

namespace dxvk {

  class D3D11Device;
  class D3D11ShaderResourceView;

  class D3D10ShaderResourceView : public ID3D10ShaderResourceView1 {

  public:

    D3D10ShaderResourceView(D3D11ShaderResourceView* pParent)
    : m_d3d11(pParent) { }

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID                    riid,
            void**                    ppvObject);

    ULONG STDMETHODCALLTYPE AddRef();

    ULONG STDMETHODCALLTYPE Release();

    void STDMETHODCALLTYPE GetDevice(
            ID3D10Device**            ppDevice);

    HRESULT STDMETHODCALLTYPE GetPrivateData(
            REFGUID                   guid,
            UINT*                     pDataSize,
            void*                     pData);

    HRESULT STDMETHODCALLTYPE SetPrivateData(
            REFGUID                   guid,
            UINT                      DataSize,
      const void*                     pData);

    HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
            REFGUID                   guid,
      const IUnknown*                 pData);

    void STDMETHODCALLTYPE GetResource(
            ID3D10Resource**          ppResource);

    void STDMETHODCALLTYPE GetDesc(
            D3D10_SHADER_RESOURCE_VIEW_DESC* pDesc);

    void STDMETHODCALLTYPE GetDesc1(
            D3D10_SHADER_RESOURCE_VIEW_DESC1* pDesc);

    D3D11ShaderResourceView* GetD3D11Iface() {
      return m_d3d11;
    }

  private:

    D3D11ShaderResourceView* m_d3d11;

  };

}


code:
LIBRARY D3D10CORE.DLL
EXPORTS
    D3D10CoreCreateDevice
    D3D10CoreGetVersion
    D3D10CoreRegisterLayers


code:
d3d10_res      = wrc_generator.process('version10.rc')
d3d10_1_res    = wrc_generator.process('version10_1.rc')
d3d10_core_res = wrc_generator.process('version10_core.rc')

d3d10_core_src = [
  'd3d10_core.cpp',
]

d3d10_main_src = [
  'd3d10_main.cpp',
  'd3d10_reflection.cpp',
  'd3d10_state_block.cpp',
]

d3d10_core_dll = shared_library('d3d10core'+dll_ext, d3d10_core_src, d3d10_core_res,
  name_prefix         : '',
  dependencies        : [ d3d11_dep ],
  include_directories : dxvk_include_path,
  install             : true,
  vs_module_defs      : 'd3d10core'+def_spec_ext,
)

d3d10_core_dep = declare_dependency(
  link_with           : [ d3d10_core_dll ],
)

d3d10_deps = [ lib_d3dcompiler_43, lib_dxgi, dxbc_dep, dxvk_dep, d3d10_core_dep ]

d3d10_dll = shared_library('d3d10'+dll_ext, d3d10_main_src, d3d10_res,
  name_prefix         : '',
  dependencies        : [ d3d10_deps ],
  include_directories : dxvk_include_path,
  install             : true,
  vs_module_defs      : 'd3d10'+def_spec_ext,
)

d3d10_1_dll = shared_library('d3d10_1'+dll_ext, d3d10_main_src, d3d10_1_res,
  name_prefix         : '',
  dependencies        : [ d3d10_deps ],
  include_directories : dxvk_include_path,
  install             : true,
  vs_module_defs      : 'd3d10_1'+def_spec_ext,
)

d3d10_dep = declare_dependency(
  link_with           : [ d3d10_dll, d3d10_1_dll, d3d10_core_dll ],
  include_directories : [ dxvk_include_path ],
)


code:
#include <windows.h>

// DLL version information.
VS_VERSION_INFO    VERSIONINFO
FILEVERSION        10,0,17763,1
PRODUCTVERSION     10,0,17763,1
FILEFLAGSMASK      VS_FFI_FILEFLAGSMASK
FILEFLAGS          0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "080904b0"
    BEGIN
      VALUE "CompanyName",      "DXVK"
      VALUE "FileDescription",  "Direct3D 10 Runtime"
      VALUE "FileVersion",      "10.0.17763.1 (WinBuild.160101.0800)"
      VALUE "InternalName",     "D3D10.dll"
      VALUE "LegalCopyright",   "zlib/libpng license"
      VALUE "OriginalFilename", "D3D10.dll"
      VALUE "ProductName",      "DXVK"
      VALUE "ProductVersion",   "10.0.17763.1"
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x0809, 1200
  END
END


code:
#include <windows.h>

// DLL version information.
VS_VERSION_INFO    VERSIONINFO
FILEVERSION        10,0,17763,1
PRODUCTVERSION     10,0,17763,1
FILEFLAGSMASK      VS_FFI_FILEFLAGSMASK
FILEFLAGS          0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "080904b0"
    BEGIN
      VALUE "CompanyName",      "DXVK"
      VALUE "FileDescription",  "Direct3D 10.1 Runtime"
      VALUE "FileVersion",      "10.0.17763.1 (WinBuild.160101.0800)"
      VALUE "InternalName",     "D3D10_1.dll"
      VALUE "LegalCopyright",   "zlib/libpng license"
      VALUE "OriginalFilename", "D3D10_1.dll"
      VALUE "ProductName",      "DXVK"
      VALUE "ProductVersion",   "10.0.17763.1"
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x0809, 1200
  END
END


code:
#include <windows.h>

// DLL version information.
VS_VERSION_INFO    VERSIONINFO
FILEVERSION        10,0,17763,1
PRODUCTVERSION     10,0,17763,1
FILEFLAGSMASK      VS_FFI_FILEFLAGSMASK
FILEFLAGS          0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "080904b0"
    BEGIN
      VALUE "CompanyName",      "DXVK"
      VALUE "FileDescription",  "Direct3D 10 Runtime"
      VALUE "FileVersion",      "10.0.17763.1 (WinBuild.160101.0800)"
      VALUE "InternalName",     "D3D10Core.dll"
      VALUE "LegalCopyright",   "zlib/libpng license"
      VALUE "OriginalFilename", "D3D10Core.dll"
      VALUE "ProductName",      "DXVK"
      VALUE "ProductVersion",   "10.0.17763.1"
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x0809, 1200
  END
END


code:
LIBRARY D3D11.DLL
EXPORTS
    D3D11CoreCreateDevice @18
    D3D11CreateDevice @22
    D3D11CreateDeviceAndSwapChain @23
    D3D11On12CreateDevice @24


code:
#include "d3d11_annotation.h"
#include "d3d11_context.h"
#include "d3d11_device.h"

#include "../util/util_misc.h"

namespace dxvk {

  template <bool Register>
  static void RegisterUserDefinedAnnotation(IDXVKUserDefinedAnnotation* annotation) {
    using RegistrationFunctionType = void(__stdcall *)(IDXVKUserDefinedAnnotation*);
    static const int16_t RegisterOrdinal = 28257;
    static const int16_t UnregisterOrdinal = 28258;

    HMODULE d3d9Module = ::LoadLibraryA("d3d9.dll");
    if (!d3d9Module) {
      Logger::info("Unable to find d3d9, some annotations may be missed.");
      return;
    }

    const int16_t ordinal = Register ? RegisterOrdinal : UnregisterOrdinal;
    auto registrationFunction = reinterpret_cast<RegistrationFunctionType>(::GetProcAddress(d3d9Module,
      reinterpret_cast<const char*>(static_cast<uintptr_t>(ordinal))));

    if (!registrationFunction) {
      Logger::info("Unable to find DXVK_RegisterAnnotation, some annotations may be missed.");
      return;
    }

    registrationFunction(annotation);
  }

  D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation(D3D11DeviceContext* ctx)
  : m_container(ctx),
    m_eventDepth(0) {
    if (m_container->IsAnnotationEnabled())
      RegisterUserDefinedAnnotation<true>(this);
  }

  D3D11UserDefinedAnnotation::D3D11UserDefinedAnnotation(const D3D11UserDefinedAnnotation&)
  {
    if (m_container->IsAnnotationEnabled())
      RegisterUserDefinedAnnotation<true>(this);
  }

  D3D11UserDefinedAnnotation::~D3D11UserDefinedAnnotation() {
    if (m_container->IsAnnotationEnabled())
      RegisterUserDefinedAnnotation<false>(this);
  }

  ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::AddRef() {
    return m_container->AddRef();
  }

  ULONG STDMETHODCALLTYPE D3D11UserDefinedAnnotation::Release() {
    return m_container->Release();
  }

  HRESULT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::QueryInterface(
          REFIID                  riid,
          void**                  ppvObject) {
    return m_container->QueryInterface(riid, ppvObject);
  }

  INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::BeginEvent(
          D3DCOLOR                Color,
          LPCWSTR                 Name) {
    if (!m_container->IsAnnotationEnabled())
      return -1;

    D3D10DeviceLock lock = m_container->LockContext();

    m_container->EmitCs([color = Color, labelName = dxvk::str::fromws(Name)](DxvkContext *ctx) {
      VkDebugUtilsLabelEXT label;
      label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
      label.pNext = nullptr;
      label.pLabelName = labelName.c_str();
      DecodeD3DCOLOR(color, label.color);

      ctx->beginDebugLabel(&label);
    });

    return m_eventDepth++;
  }

  INT STDMETHODCALLTYPE D3D11UserDefinedAnnotation::EndEvent() {
    if (!m_container->IsAnnotationEnabled())
      return -1;

    D3D10DeviceLock lock = m_container->LockContext();

    m_container->EmitCs([](DxvkContext *ctx) {
      ctx->endDebugLabel();
    });

    return m_eventDepth--;
  }

  void STDMETHODCALLTYPE D3D11UserDefinedAnnotation::SetMarker(
          D3DCOLOR                Color,
          LPCWSTR                 Name) {
    if (!m_container->IsAnnotationEnabled())
      return;

    D3D10DeviceLock lock = m_container->LockContext();

    m_container->EmitCs([color = Color, labelName = dxvk::str::fromws(Name)](DxvkContext *ctx) {
      VkDebugUtilsLabelEXT label;
      label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
      label.pNext = nullptr;
      label.pLabelName = labelName.c_str();
      DecodeD3DCOLOR(color, label.color);

      ctx->insertDebugLabel(&label);
    });
  }

  BOOL STDMETHODCALLTYPE D3D11UserDefinedAnnotation::GetStatus() {
    return m_container->IsAnnotationEnabled();
  }

}


code:
#pragma once

#include "d3d11_include.h"
#include "../dxvk/dxvk_annotation.h"

namespace dxvk {

  class D3D11DeviceContext;

  class D3D11UserDefinedAnnotation final : public IDXVKUserDefinedAnnotation {

  public:

    D3D11UserDefinedAnnotation(D3D11DeviceContext* ctx);
    D3D11UserDefinedAnnotation(const D3D11UserDefinedAnnotation&);
    ~D3D11UserDefinedAnnotation();

    ULONG STDMETHODCALLTYPE AddRef();

    ULONG STDMETHODCALLTYPE Release();

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID                  riid,
            void**                  ppvObject);

    INT STDMETHODCALLTYPE BeginEvent(
            D3DCOLOR                Color,
            LPCWSTR                 Name);

    INT STDMETHODCALLTYPE EndEvent();

    void STDMETHODCALLTYPE SetMarker(
            D3DCOLOR                Color,
            LPCWSTR                 Name);

    BOOL STDMETHODCALLTYPE GetStatus();

  private:

    D3D11DeviceContext*  m_container;

    // Stack depth for non-finalized BeginEvent calls
    int32_t m_eventDepth;
  };

}


code:
#include "d3d11_blend.h"
#include "d3d11_device.h"

namespace dxvk {

  D3D11BlendState::D3D11BlendState(
          D3D11Device*        device,
    const D3D11_BLEND_DESC1&  desc)
  : D3D11StateObject<ID3D11BlendState1>(device),
    m_desc(desc), m_d3d10(this) {
    // If Independent Blend is disabled, we must ignore the
    // blend modes for render target 1 to 7. In Vulkan, all
    // blend modes need to be identical in that case.
    for (uint32_t i = 0; i < m_blendModes.size(); i++) {
      m_blendModes.at(i) = DecodeBlendMode(
        desc.IndependentBlendEnable
          ? desc.RenderTarget[i]
          : desc.RenderTarget[0]);
    }

    // Multisample state is part of the blend state in D3D11
    m_msState.sampleMask            = 0; // Set during bind
    m_msState.enableAlphaToCoverage = desc.AlphaToCoverageEnable;

    // Vulkan only supports a global logic op for the blend
    // state, which might be problematic in some cases.
    if (desc.IndependentBlendEnable && desc.RenderTarget[0].LogicOpEnable)
      Logger::warn("D3D11: Per-target logic ops not supported");

    m_loState.enableLogicOp         = desc.RenderTarget[0].LogicOpEnable;
    m_loState.logicOp               = DecodeLogicOp(desc.RenderTarget[0].LogicOp);
  }

  D3D11BlendState::~D3D11BlendState() {

  }

  HRESULT STDMETHODCALLTYPE D3D11BlendState::QueryInterface(REFIID riid, void** ppvObject) {
    if (ppvObject == nullptr)
      return E_POINTER;

    *ppvObject = nullptr;

    if (riid == __uuidof(IUnknown)
     || riid == __uuidof(ID3D11DeviceChild)
     || riid == __uuidof(ID3D11BlendState)
     || riid == __uuidof(ID3D11BlendState1)) {
      *ppvObject = ref(this);
      return S_OK;
    }

    if (riid == __uuidof(ID3D10DeviceChild)
     || riid == __uuidof(ID3D10BlendState)
     || riid == __uuidof(ID3D10BlendState1)) {
      *ppvObject = ref(&m_d3d10);
      return S_OK;
    }

    Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query");
    Logger::warn(str::format(riid));
    return E_NOINTERFACE;
  }

  void STDMETHODCALLTYPE D3D11BlendState::GetDesc(D3D11_BLEND_DESC* pDesc) {
    pDesc->AlphaToCoverageEnable  = m_desc.AlphaToCoverageEnable;
    pDesc->IndependentBlendEnable = m_desc.IndependentBlendEnable;

    for (uint32_t i = 0; i < 8; i++) {
      pDesc->RenderTarget[i].BlendEnable           = m_desc.RenderTarget[i].BlendEnable;
      pDesc->RenderTarget[i].SrcBlend              = m_desc.RenderTarget[i].SrcBlend;
      pDesc->RenderTarget[i].DestBlend             = m_desc.RenderTarget[i].DestBlend;
      pDesc->RenderTarget[i].BlendOp               = m_desc.RenderTarget[i].BlendOp;
      pDesc->RenderTarget[i].SrcBlendAlpha         = m_desc.RenderTarget[i].SrcBlendAlpha;
      pDesc->RenderTarget[i].DestBlendAlpha        = m_desc.RenderTarget[i].DestBlendAlpha;
      pDesc->RenderTarget[i].BlendOpAlpha          = m_desc.RenderTarget[i].BlendOpAlpha;
      pDesc->RenderTarget[i].RenderTargetWriteMask = m_desc.RenderTarget[i].RenderTargetWriteMask;
    }
  }

  void STDMETHODCALLTYPE D3D11BlendState::GetDesc1(D3D11_BLEND_DESC1* pDesc) {
    *pDesc = m_desc;
  }

  void D3D11BlendState::BindToContext(
    const Rc<DxvkContext>&  ctx,
          uint32_t          sampleMask) const {
    // We handled Independent Blend during object creation
    // already, so if it is disabled, all elements in the
    // blend mode array will be identical
    for (uint32_t i = 0; i < m_blendModes.size(); i++)
      ctx->setBlendMode(i, m_blendModes.at(i));

    // The sample mask is dynamic state in D3D11
    DxvkMultisampleState msState = m_msState;
    msState.sampleMask = sampleMask;
    ctx->setMultisampleState(msState);

    // Set up logic op state as well
    ctx->setLogicOpState(m_loState);
  }

  D3D11_BLEND_DESC1 D3D11BlendState::PromoteDesc(const D3D11_BLEND_DESC* pSrcDesc) {
    D3D11_BLEND_DESC1 dstDesc;
    dstDesc.AlphaToCoverageEnable  = pSrcDesc->AlphaToCoverageEnable;
    dstDesc.IndependentBlendEnable = pSrcDesc->IndependentBlendEnable;

    for (uint32_t i = 0; i < 8; i++) {
      dstDesc.RenderTarget[i].BlendEnable           = pSrcDesc->RenderTarget[i].BlendEnable;
      dstDesc.RenderTarget[i].LogicOpEnable         = FALSE;
      dstDesc.RenderTarget[i].SrcBlend              = pSrcDesc->RenderTarget[i].SrcBlend;
      dstDesc.RenderTarget[i].DestBlend             = pSrcDesc->RenderTarget[i].DestBlend;
      dstDesc.RenderTarget[i].BlendOp               = pSrcDesc->RenderTarget[i].BlendOp;
      dstDesc.RenderTarget[i].SrcBlendAlpha         = pSrcDesc->RenderTarget[i].SrcBlendAlpha;
      dstDesc.RenderTarget[i].DestBlendAlpha        = pSrcDesc->RenderTarget[i].DestBlendAlpha;
      dstDesc.RenderTarget[i].BlendOpAlpha          = pSrcDesc->RenderTarget[i].BlendOpAlpha;
      dstDesc.RenderTarget[i].LogicOp               = D3D11_LOGIC_OP_NOOP;
      dstDesc.RenderTarget[i].RenderTargetWriteMask = pSrcDesc->RenderTarget[i].RenderTargetWriteMask;
    }

    return dstDesc;
  }

  HRESULT D3D11BlendState::NormalizeDesc(D3D11_BLEND_DESC1* pDesc) {
    if (pDesc->AlphaToCoverageEnable)
      pDesc->AlphaToCoverageEnable = TRUE;

    if (pDesc->IndependentBlendEnable)
      pDesc->IndependentBlendEnable = TRUE;

    const uint32_t numRenderTargets = pDesc->IndependentBlendEnable ? 8 : 1;

    for (uint32_t i = 0; i < numRenderTargets; i++) {
      D3D11_RENDER_TARGET_BLEND_DESC1* rt = &pDesc->RenderTarget[i];

      if (rt->BlendEnable) {
        rt->BlendEnable = TRUE;

        if (rt->LogicOpEnable)
          return E_INVALIDARG;

        if (!ValidateBlendOperations(
         rt->SrcBlend, rt->SrcBlendAlpha,
         rt->DestBlend, rt->DestBlendAlpha,
         rt->BlendOp, rt->BlendOpAlpha))
          return E_INVALIDARG;
      } else {
        rt->SrcBlend       = D3D11_BLEND_ONE;
        rt->DestBlend      = D3D11_BLEND_ZERO;
        rt->BlendOp        = D3D11_BLEND_OP_ADD;
        rt->SrcBlendAlpha  = D3D11_BLEND_ONE;
        rt->DestBlendAlpha = D3D11_BLEND_ZERO;
        rt->BlendOpAlpha   = D3D11_BLEND_OP_ADD;
      }

      if (rt->LogicOpEnable) {
        rt->LogicOpEnable = TRUE;

        // Blending must be disabled
        // if the logic op is enabled
        if (rt->BlendEnable
         || pDesc->IndependentBlendEnable
         || !ValidateLogicOp(rt->LogicOp))
          return E_INVALIDARG;
      } else {
        rt->LogicOp = D3D11_LOGIC_OP_NOOP;
      }

      if (rt->RenderTargetWriteMask > D3D11_COLOR_WRITE_ENABLE_ALL)
        return E_INVALIDARG;
    }

    for (uint32_t i = numRenderTargets; i < 8; i++) {
      // Render targets blend operations are the same
      // across all render targets when blend is enabled
      // on rendertarget[0] with independent blend disabled
      pDesc->RenderTarget[i] = pDesc->RenderTarget[0];
    }

    return S_OK;
  }

  DxvkBlendMode D3D11BlendState::DecodeBlendMode(
    const D3D11_RENDER_TARGET_BLEND_DESC1& BlendDesc) {
    DxvkBlendMode mode;
    mode.enableBlending   = BlendDesc.BlendEnable;
    mode.colorSrcFactor   = DecodeBlendFactor(BlendDesc.SrcBlend, false);
    mode.colorDstFactor   = DecodeBlendFactor(BlendDesc.DestBlend, false);
    mode.colorBlendOp     = DecodeBlendOp(BlendDesc.BlendOp);
    mode.alphaSrcFactor   = DecodeBlendFactor(BlendDesc.SrcBlendAlpha, true);
    mode.alphaDstFactor   = DecodeBlendFactor(BlendDesc.DestBlendAlpha, true);
    mode.alphaBlendOp     = DecodeBlendOp(BlendDesc.BlendOpAlpha);
    mode.writeMask        = BlendDesc.RenderTargetWriteMask;
    return mode;
  }

  VkBlendFactor D3D11BlendState::DecodeBlendFactor(D3D11_BLEND BlendFactor, bool IsAlpha) {
    switch (BlendFactor) {
      case D3D11_BLEND_ZERO:              return VK_BLEND_FACTOR_ZERO;
      case D3D11_BLEND_ONE:               return VK_BLEND_FACTOR_ONE;
      case D3D11_BLEND_SRC_COLOR:         return VK_BLEND_FACTOR_SRC_COLOR;
      case D3D11_BLEND_INV_SRC_COLOR:     return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
      case D3D11_BLEND_SRC_ALPHA:         return VK_BLEND_FACTOR_SRC_ALPHA;
      case D3D11_BLEND_INV_SRC_ALPHA:     return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
      case D3D11_BLEND_DEST_ALPHA:        return VK_BLEND_FACTOR_DST_ALPHA;
      case D3D11_BLEND_INV_DEST_ALPHA:    return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
      case D3D11_BLEND_DEST_COLOR:        return VK_BLEND_FACTOR_DST_COLOR;
      case D3D11_BLEND_INV_DEST_COLOR:    return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
      case D3D11_BLEND_SRC_ALPHA_SAT:     return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
      case D3D11_BLEND_BLEND_FACTOR:      return IsAlpha ? VK_BLEND_FACTOR_CONSTANT_ALPHA : VK_BLEND_FACTOR_CONSTANT_COLOR;
      case D3D11_BLEND_INV_BLEND_FACTOR:  return IsAlpha ? VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA : VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
      case D3D11_BLEND_SRC1_COLOR:        return VK_BLEND_FACTOR_SRC1_COLOR;
      case D3D11_BLEND_INV_SRC1_COLOR:    return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
      case D3D11_BLEND_SRC1_ALPHA:        return VK_BLEND_FACTOR_SRC1_ALPHA;
      case D3D11_BLEND_INV_SRC1_ALPHA:    return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
      default:                            return VK_BLEND_FACTOR_ZERO;
    }
  }

  VkBlendOp D3D11BlendState::DecodeBlendOp(D3D11_BLEND_OP BlendOp) {
    switch (BlendOp) {
      case D3D11_BLEND_OP_ADD:            return VK_BLEND_OP_ADD;
      case D3D11_BLEND_OP_SUBTRACT:       return VK_BLEND_OP_SUBTRACT;
      case D3D11_BLEND_OP_REV_SUBTRACT:   return VK_BLEND_OP_REVERSE_SUBTRACT;
      case D3D11_BLEND_OP_MIN:            return VK_BLEND_OP_MIN;
      case D3D11_BLEND_OP_MAX:            return VK_BLEND_OP_MAX;
      default:                            return VK_BLEND_OP_ADD;
    }
  }

  VkLogicOp D3D11BlendState::DecodeLogicOp(D3D11_LOGIC_OP LogicOp) {
    switch (LogicOp) {
      case D3D11_LOGIC_OP_CLEAR:          return VK_LOGIC_OP_CLEAR;
      case D3D11_LOGIC_OP_SET:            return VK_LOGIC_OP_SET;
      case D3D11_LOGIC_OP_COPY:           return VK_LOGIC_OP_COPY;
      case D3D11_LOGIC_OP_COPY_INVERTED:  return VK_LOGIC_OP_COPY_INVERTED;
      case D3D11_LOGIC_OP_NOOP:           return VK_LOGIC_OP_NO_OP;
      case D3D11_LOGIC_OP_INVERT:         return VK_LOGIC_OP_INVERT;
      case D3D11_LOGIC_OP_AND:            return VK_LOGIC_OP_AND;
      case D3D11_LOGIC_OP_NAND:           return VK_LOGIC_OP_NAND;
      case D3D11_LOGIC_OP_OR:             return VK_LOGIC_OP_OR;
      case D3D11_LOGIC_OP_NOR:            return VK_LOGIC_OP_NOR;
      case D3D11_LOGIC_OP_XOR:            return VK_LOGIC_OP_XOR;
      case D3D11_LOGIC_OP_EQUIV:          return VK_LOGIC_OP_EQUIVALENT;
      case D3D11_LOGIC_OP_AND_REVERSE:    return VK_LOGIC_OP_AND_REVERSE;
      case D3D11_LOGIC_OP_AND_INVERTED:   return VK_LOGIC_OP_AND_INVERTED;
      case D3D11_LOGIC_OP_OR_REVERSE:     return VK_LOGIC_OP_OR_REVERSE;
      case D3D11_LOGIC_OP_OR_INVERTED:    return VK_LOGIC_OP_OR_INVERTED;
      default:                            return VK_LOGIC_OP_NO_OP;
    }
  }

  bool D3D11BlendState::ValidateBlendFactor(D3D11_BLEND Blend) {
    return Blend >= D3D11_BLEND_ZERO
        && Blend <= D3D11_BLEND_INV_SRC1_ALPHA;
  }

  bool D3D11BlendState::ValidateBlendFactorAlpha(D3D11_BLEND BlendAlpha) {
    return BlendAlpha >= D3D11_BLEND_ZERO
        && BlendAlpha <= D3D11_BLEND_INV_SRC1_ALPHA
        && BlendAlpha != D3D11_BLEND_SRC_COLOR
        && BlendAlpha != D3D11_BLEND_INV_SRC_COLOR
        && BlendAlpha != D3D11_BLEND_DEST_COLOR
        && BlendAlpha != D3D11_BLEND_INV_DEST_COLOR
        && BlendAlpha != D3D11_BLEND_SRC1_COLOR
        && BlendAlpha != D3D11_BLEND_INV_SRC1_COLOR;
  }

  bool D3D11BlendState::ValidateBlendOp(D3D11_BLEND_OP BlendOp) {
    return BlendOp >= D3D11_BLEND_OP_ADD
        && BlendOp <= D3D11_BLEND_OP_MAX;
  }

  bool D3D11BlendState::ValidateLogicOp(D3D11_LOGIC_OP LogicOp) {
    return LogicOp >= D3D11_LOGIC_OP_CLEAR
        && LogicOp <= D3D11_LOGIC_OP_OR_INVERTED;
  }

  bool D3D11BlendState::ValidateBlendOperations(
          D3D11_BLEND     SrcBlend,
          D3D11_BLEND     SrcBlendAlpha,
          D3D11_BLEND     DestBlend,
          D3D11_BLEND     DestBlendAlpha,
          D3D11_BLEND_OP  BlendOp,
          D3D11_BLEND_OP  BlendOpAlpha) {
    return ValidateBlendOp(BlendOp)
        && ValidateBlendOp(BlendOpAlpha)
        && ValidateBlendFactor(SrcBlend)
        && ValidateBlendFactor(DestBlend)
        && ValidateBlendFactorAlpha(SrcBlendAlpha)
        && ValidateBlendFactorAlpha(DestBlendAlpha);
  }

}


code:
#pragma once

#include "../dxvk/dxvk_device.h"

#include "../d3d10/d3d10_blend.h"

#include "d3d11_device_child.h"
#include "d3d11_util.h"

namespace dxvk {

  class D3D11Device;

  class D3D11BlendState : public D3D11StateObject<ID3D11BlendState1> {

  public:

    using DescType = D3D11_BLEND_DESC1;

    D3D11BlendState(
            D3D11Device*       device,
      const D3D11_BLEND_DESC1& desc);
    ~D3D11BlendState();

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID  riid,
            void**  ppvObject) final;

    void STDMETHODCALLTYPE GetDesc(
            D3D11_BLEND_DESC* pDesc) final;

    void STDMETHODCALLTYPE GetDesc1(
            D3D11_BLEND_DESC1* pDesc) final;

    void BindToContext(
      const Rc<DxvkContext>&  ctx,
            UINT              sampleMask) const;

    D3D10BlendState* GetD3D10Iface() {
      return &m_d3d10;
    }

    static D3D11_BLEND_DESC1 PromoteDesc(
      const D3D11_BLEND_DESC*   pSrcDesc);

    static HRESULT NormalizeDesc(
            D3D11_BLEND_DESC1*  pDesc);

  private:

    D3D11_BLEND_DESC1             m_desc;

    std::array<DxvkBlendMode, 8>  m_blendModes;
    DxvkMultisampleState          m_msState;
    DxvkLogicOpState              m_loState;

    D3D10BlendState               m_d3d10;

    static DxvkBlendMode DecodeBlendMode(
      const D3D11_RENDER_TARGET_BLEND_DESC1& BlendDesc);

    static VkBlendFactor DecodeBlendFactor(
            D3D11_BLEND BlendFactor,
            bool        IsAlpha);

    static VkBlendOp DecodeBlendOp(
            D3D11_BLEND_OP BlendOp);

    static VkLogicOp DecodeLogicOp(
            D3D11_LOGIC_OP LogicOp);

    static bool ValidateBlendFactor(
            D3D11_BLEND    Blend);

    static bool ValidateBlendFactorAlpha(
            D3D11_BLEND    BlendAlpha);

    static bool ValidateBlendOp(
            D3D11_BLEND_OP BlendOp);

    static bool ValidateLogicOp(
            D3D11_LOGIC_OP LogicOp);

    static bool ValidateBlendOperations(
            D3D11_BLEND    SrcBlend,
            D3D11_BLEND    SrcBlendAlpha,
            D3D11_BLEND    SestBlend,
            D3D11_BLEND    DestBlendAlpha,
            D3D11_BLEND_OP BlendOp,
            D3D11_BLEND_OP BlendOpAlpha);
  };

}


code:
#include "d3d11_buffer.h"
#include "d3d11_context.h"
#include "d3d11_device.h"

#include "../dxvk/dxvk_data.h"

namespace dxvk {

  D3D11Buffer::D3D11Buffer(
          D3D11Device*                pDevice,
    const D3D11_BUFFER_DESC*          pDesc)
  : D3D11DeviceChild<ID3D11Buffer>(pDevice),
    m_desc        (*pDesc),
    m_resource    (this),
    m_d3d10       (this) {
    DxvkBufferCreateInfo  info;
    info.size   = pDesc->ByteWidth;
    info.usage  = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
                | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
    info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
    info.access = VK_ACCESS_TRANSFER_READ_BIT
                | VK_ACCESS_TRANSFER_WRITE_BIT;

    if (pDesc->BindFlags & D3D11_BIND_VERTEX_BUFFER) {
      info.usage  |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
      info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
      info.access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
    }

    if (pDesc->BindFlags & D3D11_BIND_INDEX_BUFFER) {
      info.usage  |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
      info.stages |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
      info.access |= VK_ACCESS_INDEX_READ_BIT;
    }

    if (pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER) {
      info.usage  |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
      info.stages |= m_parent->GetEnabledShaderStages();
      info.access |= VK_ACCESS_UNIFORM_READ_BIT;

      if (m_parent->GetOptions()->constantBufferRangeCheck)
        info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
    }

    if (pDesc->BindFlags & D3D11_BIND_SHADER_RESOURCE) {
      info.usage  |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
                  |  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
      info.stages |= m_parent->GetEnabledShaderStages();
      info.access |= VK_ACCESS_SHADER_READ_BIT;
    }

    if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT) {
      info.usage  |= VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
      info.stages |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
      info.access |= VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT;
    }

    if (pDesc->BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
      info.usage  |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
                  |  VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
      info.stages |= m_parent->GetEnabledShaderStages();
      info.access |= VK_ACCESS_SHADER_READ_BIT
                  |  VK_ACCESS_SHADER_WRITE_BIT;
    }

    if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS) {
      info.usage  |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT;
      info.stages |= VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT;
      info.access |= VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
    }

    // Create the buffer and set the entire buffer slice as mapped,
    // so that we only have to update it when invalidating th buffer
    m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, GetMemoryFlags());
    m_mapped = m_buffer->getSliceHandle();

    m_mapMode = DetermineMapMode();

    // For Stream Output buffers we need a counter
    if (pDesc->BindFlags & D3D11_BIND_STREAM_OUTPUT)
      m_soCounter = CreateSoCounterBuffer();
  }

  D3D11Buffer::~D3D11Buffer() {

  }

  HRESULT STDMETHODCALLTYPE D3D11Buffer::QueryInterface(REFIID riid, void** ppvObject) {
    if (ppvObject == nullptr)
      return E_POINTER;

    *ppvObject = nullptr;

    if (riid == __uuidof(IUnknown)
     || riid == __uuidof(ID3D11DeviceChild)
     || riid == __uuidof(ID3D11Resource)
     || riid == __uuidof(ID3D11Buffer)) {
      *ppvObject = ref(this);
      return S_OK;
    }

    if (riid == __uuidof(ID3D10DeviceChild)
     || riid == __uuidof(ID3D10Resource)
     || riid == __uuidof(ID3D10Buffer)) {
      *ppvObject = ref(&m_d3d10);
      return S_OK;
    }

    if (riid == __uuidof(IDXGIObject)
     || riid == __uuidof(IDXGIDeviceSubObject)
     || riid == __uuidof(IDXGIResource)
     || riid == __uuidof(IDXGIResource1)) {
       *ppvObject = ref(&m_resource);
       return S_OK;
    }

    Logger::warn("D3D11Buffer::QueryInterface: Unknown interface query");
    Logger::warn(str::format(riid));
    return E_NOINTERFACE;
  }

  UINT STDMETHODCALLTYPE D3D11Buffer::GetEvictionPriority() {
    return DXGI_RESOURCE_PRIORITY_NORMAL;
  }

  void STDMETHODCALLTYPE D3D11Buffer::SetEvictionPriority(UINT EvictionPriority) {
    static bool s_errorShown = false;

    if (!std::exchange(s_errorShown, true))
      Logger::warn("D3D11Buffer::SetEvictionPriority: Stub");
  }

  void STDMETHODCALLTYPE D3D11Buffer::GetType(D3D11_RESOURCE_DIMENSION* pResourceDimension) {
    *pResourceDimension = D3D11_RESOURCE_DIMENSION_BUFFER;
  }

  void STDMETHODCALLTYPE D3D11Buffer::GetDesc(D3D11_BUFFER_DESC* pDesc) {
    *pDesc = m_desc;
  }

  bool D3D11Buffer::CheckViewCompatibility(
          UINT                BindFlags,
          DXGI_FORMAT         Format) const {
    // Check whether the given bind flags are supported
    if ((m_desc.BindFlags & BindFlags) != BindFlags)
      return false;

    // Structured buffer views use no format
    if (Format == DXGI_FORMAT_UNKNOWN)
      return (m_desc.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) != 0;

    // Check whether the given combination of buffer view
    // type and view format is supported by the device
    DXGI_VK_FORMAT_INFO viewFormat = m_parent->LookupFormat(Format, DXGI_VK_FORMAT_MODE_ANY);
    VkFormatFeatureFlags features = GetBufferFormatFeatures(BindFlags);

    return CheckFormatFeatureSupport(viewFormat.Format, features);
  }

  HRESULT D3D11Buffer::NormalizeBufferProperties(D3D11_BUFFER_DESC* pDesc) {
    // Zero-sized buffers are illegal
    if (!pDesc->ByteWidth)
      return E_INVALIDARG;

    // We don't support tiled resources
    if (pDesc->MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED))
      return E_INVALIDARG;

    // Constant buffer size must be a multiple of 16
    if ((pDesc->BindFlags & D3D11_BIND_CONSTANT_BUFFER)
     && (pDesc->ByteWidth & 0xF))
      return E_INVALIDARG;

    // Basic validation for structured buffers
    if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
     && ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS)
      || (pDesc->StructureByteStride == 0)
      || (pDesc->StructureByteStride & 0x3)))
      return E_INVALIDARG;

    // Basic validation for raw buffers
    if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS)
     && (!(pDesc->BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS))))
      return E_INVALIDARG;

    // Mip generation obviously doesn't work for buffers
    if (pDesc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
      return E_INVALIDARG;

    if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED))
      pDesc->StructureByteStride = 0;

    return S_OK;
  }

  BOOL D3D11Buffer::CheckFormatFeatureSupport(
          VkFormat              Format,
          VkFormatFeatureFlags  Features) const {
    VkFormatProperties properties = m_parent->GetDXVKDevice()->adapter()->formatProperties(Format);
    return (properties.bufferFeatures & Features) == Features;
  }

  VkMemoryPropertyFlags D3D11Buffer::GetMemoryFlags() const {
    VkMemoryPropertyFlags memoryFlags = 0;

    switch (m_desc.Usage) {
      case D3D11_USAGE_IMMUTABLE:
        memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
        break;

      case D3D11_USAGE_DEFAULT:
        memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;

        if ((m_desc.BindFlags & D3D11_BIND_CONSTANT_BUFFER) || m_desc.CPUAccessFlags) {
          memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
                      |  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
        }

        if (m_desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) {
          memoryFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
          memoryFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
        }
        break;

      case D3D11_USAGE_DYNAMIC:
        memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
                    |  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;

        if (m_desc.BindFlags)
          memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
        break;

      case D3D11_USAGE_STAGING:
        memoryFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
                    |  VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
                    |  VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
        break;
    }

    bool useCached = (m_parent->GetOptions()->cachedDynamicResources == ~0u)
                  || (m_parent->GetOptions()->cachedDynamicResources & m_desc.BindFlags);

    if ((memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && useCached) {
      memoryFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
                  |  VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
    }

    return memoryFlags;
  }

  Rc<DxvkBuffer> D3D11Buffer::CreateSoCounterBuffer() {
    Rc<DxvkDevice> device = m_parent->GetDXVKDevice();

    DxvkBufferCreateInfo info;
    info.size   = sizeof(D3D11SOCounter);
    info.usage  = VK_BUFFER_USAGE_TRANSFER_DST_BIT
                | VK_BUFFER_USAGE_TRANSFER_SRC_BIT
                | VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
                | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT;
    info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
                | VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
                | VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
    info.access = VK_ACCESS_TRANSFER_READ_BIT
                | VK_ACCESS_TRANSFER_WRITE_BIT
                | VK_ACCESS_INDIRECT_COMMAND_READ_BIT
                | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT
                | VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT;
    return device->createBuffer(info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
  }

  D3D11_COMMON_BUFFER_MAP_MODE D3D11Buffer::DetermineMapMode() {
    return (m_buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
      ? D3D11_COMMON_BUFFER_MAP_MODE_DIRECT
      : D3D11_COMMON_BUFFER_MAP_MODE_NONE;
  }

  D3D11Buffer* GetCommonBuffer(ID3D11Resource* pResource) {
    D3D11_RESOURCE_DIMENSION dimension = D3D11_RESOURCE_DIMENSION_UNKNOWN;
    pResource->GetType(&dimension);

    return dimension == D3D11_RESOURCE_DIMENSION_BUFFER
      ? static_cast<D3D11Buffer*>(pResource)
      : nullptr;
  }

}


code:
#pragma once

#include "../dxvk/dxvk_cs.h"
#include "../dxvk/dxvk_device.h"

#include "../d3d10/d3d10_buffer.h"

#include "d3d11_device_child.h"
#include "d3d11_interfaces.h"
#include "d3d11_resource.h"

namespace dxvk {

  class D3D11Device;
  class D3D11DeviceContext;

  /**
   * \brief Buffer map mode
   */
  enum D3D11_COMMON_BUFFER_MAP_MODE {
    D3D11_COMMON_BUFFER_MAP_MODE_NONE,
    D3D11_COMMON_BUFFER_MAP_MODE_DIRECT,
  };

  /**
   * \brief Stream output buffer offset
   *
   * A byte offset into the buffer that
   * stores the byte offset where new
   * data will be written to.
   */
  struct D3D11SOCounter {
    uint32_t byteOffset;
  };

  class D3D11Buffer : public D3D11DeviceChild<ID3D11Buffer> {
    static constexpr VkDeviceSize BufferSliceAlignment = 64;
  public:

    D3D11Buffer(
            D3D11Device*                pDevice,
      const D3D11_BUFFER_DESC*          pDesc);
    ~D3D11Buffer();

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID  riid,
            void**  ppvObject) final;

    void STDMETHODCALLTYPE GetType(
            D3D11_RESOURCE_DIMENSION *pResourceDimension) final;

    UINT STDMETHODCALLTYPE GetEvictionPriority() final;

    void STDMETHODCALLTYPE SetEvictionPriority(UINT EvictionPriority) final;

    void STDMETHODCALLTYPE GetDesc(
            D3D11_BUFFER_DESC *pDesc) final;

    bool CheckViewCompatibility(
            UINT                BindFlags,
            DXGI_FORMAT         Format) const;

    const D3D11_BUFFER_DESC* Desc() const {
      return &m_desc;
    }

    D3D11_COMMON_BUFFER_MAP_MODE GetMapMode() const {
      return m_mapMode;
    }

    Rc<DxvkBuffer> GetBuffer() const {
      return m_buffer;
    }

    DxvkBufferSlice GetBufferSlice() const {
      return DxvkBufferSlice(m_buffer, 0, m_desc.ByteWidth);
    }

    DxvkBufferSlice GetBufferSlice(VkDeviceSize offset) const {
      VkDeviceSize size = m_desc.ByteWidth;

      return likely(offset < size)
        ? DxvkBufferSlice(m_buffer, offset, size - offset)
        : DxvkBufferSlice();
    }

    DxvkBufferSlice GetBufferSlice(VkDeviceSize offset, VkDeviceSize length) const {
      VkDeviceSize size = m_desc.ByteWidth;

      return likely(offset < size)
        ? DxvkBufferSlice(m_buffer, offset, std::min(length, size - offset))
        : DxvkBufferSlice();
    }

    DxvkBufferSlice GetSOCounter() {
      return m_soCounter != nullptr
        ? DxvkBufferSlice(m_soCounter)
        : DxvkBufferSlice();
    }

    DxvkBufferSliceHandle AllocSlice() {
      return m_buffer->allocSlice();
    }

    DxvkBufferSliceHandle DiscardSlice() {
      m_mapped = m_buffer->allocSlice();
      return m_mapped;
    }

    DxvkBufferSliceHandle GetMappedSlice() const {
      return m_mapped;
    }

    D3D10Buffer* GetD3D10Iface() {
      return &m_d3d10;
    }

    bool HasSequenceNumber() const {
      return m_mapMode != D3D11_COMMON_BUFFER_MAP_MODE_NONE
          && !(m_desc.MiscFlags & D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS)
          && !(m_desc.BindFlags);
    }

    void TrackSequenceNumber(uint64_t Seq) {
      m_seq = Seq;
    }

    uint64_t GetSequenceNumber() {
      return HasSequenceNumber() ? m_seq
        : DxvkCsThread::SynchronizeAll;
    }

    /**
     * \brief Normalizes buffer description
     *
     * \param [in] pDesc Buffer description
     * \returns \c S_OK if the parameters are valid
     */
    static HRESULT NormalizeBufferProperties(
            D3D11_BUFFER_DESC*      pDesc);

  private:

    D3D11_BUFFER_DESC             m_desc;
    D3D11_COMMON_BUFFER_MAP_MODE  m_mapMode;

    Rc<DxvkBuffer>                m_buffer;
    Rc<DxvkBuffer>                m_soCounter;
    DxvkBufferSliceHandle         m_mapped;
    uint64_t                      m_seq = 0ull;

    D3D11DXGIResource             m_resource;
    D3D10Buffer                   m_d3d10;

    BOOL CheckFormatFeatureSupport(
            VkFormat              Format,
            VkFormatFeatureFlags  Features) const;

    VkMemoryPropertyFlags GetMemoryFlags() const;

    Rc<DxvkBuffer> CreateSoCounterBuffer();

    D3D11_COMMON_BUFFER_MAP_MODE DetermineMapMode();

  };

  /**
   * \brief Retrieves buffer from resource pointer
   *
   * \param [in] pResource The resource to query
   * \returns Pointer to buffer, or \c nullptr
   */
  D3D11Buffer* GetCommonBuffer(
          ID3D11Resource*       pResource);

}


code:
#include "d3d11_class_linkage.h"
#include "d3d11_device.h"

namespace dxvk {

  D3D11ClassLinkage::D3D11ClassLinkage(
          D3D11Device*                pDevice)
  : D3D11DeviceChild<ID3D11ClassLinkage>(pDevice) {

  }

  D3D11ClassLinkage::~D3D11ClassLinkage() {

  }

  HRESULT STDMETHODCALLTYPE D3D11ClassLinkage::QueryInterface(REFIID riid, void** ppvObject) {
    if (ppvObject == nullptr)
      return E_POINTER;

    *ppvObject = nullptr;

    if (riid == __uuidof(IUnknown)
     || riid == __uuidof(ID3D11DeviceChild)
     || riid == __uuidof(ID3D11ClassLinkage)) {
      *ppvObject = ref(this);
      return S_OK;
    }

    Logger::warn("D3D11ClassLinkage::QueryInterface: Unknown interface query");
    Logger::warn(str::format(riid));
    return E_NOINTERFACE;
  }

  HRESULT STDMETHODCALLTYPE D3D11ClassLinkage::CreateClassInstance(
          LPCSTR              pClassTypeName,
          UINT                ConstantBufferOffset,
          UINT                ConstantVectorOffset,
          UINT                TextureOffset,
          UINT                SamplerOffset,
          ID3D11ClassInstance **ppInstance) {
    InitReturnPtr(ppInstance);

    Logger::err("D3D11ClassLinkage::CreateClassInstance: Not implemented yet");
    return E_NOTIMPL;
  }

  HRESULT STDMETHODCALLTYPE D3D11ClassLinkage::GetClassInstance(
          LPCSTR              pClassInstanceName,
          UINT                InstanceIndex,
          ID3D11ClassInstance **ppInstance) {
    Logger::err("D3D11ClassLinkage::GetClassInstance: Not implemented yet");
    return E_NOTIMPL;
  }

}


code:
#pragma once

#include "d3d11_device_child.h"

namespace dxvk {

  class D3D11Device;

  // TODO implement properly
  class D3D11ClassLinkage : public D3D11DeviceChild<ID3D11ClassLinkage> {

  public:

    D3D11ClassLinkage(
            D3D11Device*                pDevice);

    ~D3D11ClassLinkage();

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID  riid,
            void**  ppvObject) final;

    HRESULT STDMETHODCALLTYPE CreateClassInstance(
            LPCSTR              pClassTypeName,
            UINT                ConstantBufferOffset,
            UINT                ConstantVectorOffset,
            UINT                TextureOffset,
            UINT                SamplerOffset,
            ID3D11ClassInstance **ppInstance);

    HRESULT STDMETHODCALLTYPE GetClassInstance(
            LPCSTR              pClassInstanceName,
            UINT                InstanceIndex,
            ID3D11ClassInstance **ppInstance);

  };

}


code:
#pragma once

#include "d3d11_include.h"

namespace dxvk {

  /**
   * \brief D3D11 command type
   *
   * Used to identify the type of command
   * data most recently added to a CS chunk.
   */
  enum class D3D11CmdType {
    DrawIndirect,
    DrawIndirectIndexed,
  };

  /**
   * \brief Command data header
   *
   * Stores the command type. All command
   * data structs must inherit this struct.
   */
  struct D3D11CmdData {
    D3D11CmdType        type;
  };

  /**
   * \brief Indirect draw command data
   *
   * Stores the offset into the draw buffer for
   * the first draw, as well as the number of
   * draws to execute.
   */
  struct D3D11CmdDrawIndirectData : public D3D11CmdData {
    uint32_t            offset;
    uint32_t            count;
    uint32_t            stride;
  };

}


code:
#include "d3d11_cmdlist.h"
#include "d3d11_device.h"
#include "d3d11_buffer.h"
#include "d3d11_texture.h"

namespace dxvk {

  D3D11CommandList::D3D11CommandList(
          D3D11Device*  pDevice,
          UINT          ContextFlags)
  : D3D11DeviceChild<ID3D11CommandList>(pDevice),
    m_contextFlags(ContextFlags) { }

  D3D11CommandList::~D3D11CommandList() {

  }

  HRESULT STDMETHODCALLTYPE D3D11CommandList::QueryInterface(REFIID riid, void** ppvObject) {
    if (ppvObject == nullptr)
      return E_POINTER;

    *ppvObject = nullptr;

    if (riid == __uuidof(IUnknown)
     || riid == __uuidof(ID3D11DeviceChild)
     || riid == __uuidof(ID3D11CommandList)) {
      *ppvObject = ref(this);
      return S_OK;
    }

    Logger::warn("D3D11CommandList::QueryInterface: Unknown interface query");
    Logger::warn(str::format(riid));
    return E_NOINTERFACE;
  }

  UINT STDMETHODCALLTYPE D3D11CommandList::GetContextFlags() {
    return m_contextFlags;
  }

  void D3D11CommandList::AddChunk(DxvkCsChunkRef&& Chunk) {
    m_chunks.push_back(std::move(Chunk));
  }

  void D3D11CommandList::AddQuery(D3D11Query* pQuery) {
    m_queries.emplace_back(pQuery);
  }

  void D3D11CommandList::EmitToCommandList(ID3D11CommandList* pCommandList) {
    auto cmdList = static_cast<D3D11CommandList*>(pCommandList);

    for (const auto& chunk : m_chunks)
      cmdList->m_chunks.push_back(chunk);

    for (const auto& query : m_queries)
      cmdList->m_queries.push_back(query);

    for (const auto& resource : m_resources)
      cmdList->m_resources.push_back(resource);

    MarkSubmitted();
  }

  uint64_t D3D11CommandList::EmitToCsThread(DxvkCsThread* CsThread) {
    uint64_t seq = 0;

    for (const auto& query : m_queries)
      query->DoDeferredEnd();

    for (const auto& chunk : m_chunks)
      seq = CsThread->dispatchChunk(DxvkCsChunkRef(chunk));

    for (const auto& resource : m_resources)
      TrackResourceSequenceNumber(resource, seq);

    MarkSubmitted();
    return seq;
  }

  void D3D11CommandList::TrackResourceUsage(
          ID3D11Resource*     pResource,
          D3D11_RESOURCE_DIMENSION ResourceType,
          UINT                Subresource) {
    m_resources.emplace_back(pResource, Subresource, ResourceType);
  }

  void D3D11CommandList::TrackResourceSequenceNumber(
    const D3D11ResourceRef&   Resource,
          uint64_t            Seq) {
    ID3D11Resource* iface = Resource.Get();
    UINT subresource = Resource.GetSubresource();

    switch (Resource.GetType()) {
      case D3D11_RESOURCE_DIMENSION_UNKNOWN:
        break;

      case D3D11_RESOURCE_DIMENSION_BUFFER: {
        auto impl = static_cast<D3D11Buffer*>(iface);
        impl->TrackSequenceNumber(Seq);
      } break;

      case D3D11_RESOURCE_DIMENSION_TEXTURE1D: {
        auto impl = static_cast<D3D11Texture1D*>(iface)->GetCommonTexture();
        impl->TrackSequenceNumber(subresource, Seq);
      } break;

      case D3D11_RESOURCE_DIMENSION_TEXTURE2D: {
        auto impl = static_cast<D3D11Texture2D*>(iface)->GetCommonTexture();
        impl->TrackSequenceNumber(subresource, Seq);
      } break;

      case D3D11_RESOURCE_DIMENSION_TEXTURE3D: {
        auto impl = static_cast<D3D11Texture3D*>(iface)->GetCommonTexture();
        impl->TrackSequenceNumber(subresource, Seq);
      } break;
    }
  }

  void D3D11CommandList::MarkSubmitted() {
    if (m_submitted.exchange(true) && !m_warned.exchange(true)
     && m_parent->GetOptions()->dcSingleUseMode) {
      Logger::warn(
        "D3D11: Command list submitted multiple times,\n"
        "       but d3d11.dcSingleUseMode is enabled");
    }
  }

}


code:
#pragma once

#include "d3d11_context.h"

namespace dxvk {

  class D3D11CommandList : public D3D11DeviceChild<ID3D11CommandList> {

  public:

    D3D11CommandList(
            D3D11Device*  pDevice,
            UINT          ContextFlags);

    ~D3D11CommandList();

    HRESULT STDMETHODCALLTYPE QueryInterface(
            REFIID  riid,
            void**  ppvObject) final;

    UINT STDMETHODCALLTYPE GetContextFlags() final;

    void AddChunk(
            DxvkCsChunkRef&&    Chunk);

    void AddQuery(
            D3D11Query*         pQuery);

    void EmitToCommandList(
            ID3D11CommandList*  pCommandList);

    uint64_t EmitToCsThread(
            DxvkCsThread*       CsThread);

    void TrackResourceUsage(
            ID3D11Resource*     pResource,
            D3D11_RESOURCE_DIMENSION ResourceType,
            UINT                Subresource);

  private:

    UINT         const m_contextFlags;

    std::vector<DxvkCsChunkRef>         m_chunks;
    std::vector<Com<D3D11Query, false>> m_queries;
    std::vector<D3D11ResourceRef>       m_resources;

    std::atomic<bool> m_submitted = { false };
    std::atomic<bool> m_warned    = { false };

    void TrackResourceSequenceNumber(
      const D3D11ResourceRef&   Resource,
            uint64_t            Seq);

    void MarkSubmitted();

  };

}