code:
#include <cstring>

#include <d3d9.h>
#include <d3dcompiler.h>

#include "../test_utils.h"

using namespace dxvk;

struct Extent2D {
  uint32_t w, h;
};

const std::string g_vertexShaderCode = R"(

struct VS_INPUT {
  float3 Position : POSITION;
  float3 TexCoord : TEXCOORD0;
};

struct VS_OUTPUT {
  float4 Position : POSITION;
  float3 TexCoord : TEXCOORD0;
};

VS_OUTPUT main( VS_INPUT IN ) {
  VS_OUTPUT OUT;
  OUT.Position = float4(IN.Position, 0.6f);
  OUT.TexCoord = IN.TexCoord;

  return OUT;
}

)";

const std::string g_pixelShaderCode = R"(

struct VS_OUTPUT {
  float4 Position : POSITION;
  float3 TexCoord : TEXCOORD0;
};

struct PS_OUTPUT {
  float4 Colour   : COLOR;
};

sampler g_texDepth : register( s0 );

PS_OUTPUT main( VS_OUTPUT IN ) {
  PS_OUTPUT OUT;

  //OUT.Colour = tex2D(g_texDepth, float2(0, 0));
  //OUT.Colour = 1.0;

  OUT.Colour = float4(IN.TexCoord.xyz, 1.0);

  return OUT;
}

)";

Logger Logger::s_instance("triangle.log");

class TriangleApp {

public:

  TriangleApp(HINSTANCE instance, HWND window)
  : m_window(window) {
    HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d);

    if (FAILED(status))
      throw DxvkError("Failed to create D3D9 interface");

    UINT adapter = D3DADAPTER_DEFAULT;

    D3DADAPTER_IDENTIFIER9 adapterId;
    m_d3d->GetAdapterIdentifier(adapter, 0, &adapterId);

    Logger::info(str::format("Using adapter: ", adapterId.Description));

    auto CheckSRGBFormat = [&](D3DFORMAT fmt, const char* name) {
      HRESULT status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, fmt);
      Logger::warn(str::format("(linear) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));

      status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, fmt);
      Logger::warn(str::format("(srgb) ", name, ": ", SUCCEEDED(status) ? "ok" : "nope"));
    };

    CheckSRGBFormat(D3DFMT_R5G6B5,       "R5G6B5");
    CheckSRGBFormat(D3DFMT_X1R5G5B5,     "X1R5G5B5");
    CheckSRGBFormat(D3DFMT_A1R5G5B5,     "A1R5G5B5");
    CheckSRGBFormat(D3DFMT_A4R4G4B4,     "A4R4G4B4");
    CheckSRGBFormat(D3DFMT_X4R4G4B4,     "X4R4G4B4");
    CheckSRGBFormat(D3DFMT_G16R16,       "G16R16");
    CheckSRGBFormat(D3DFMT_A2R10G10B10,  "A2R10G10B10");
    CheckSRGBFormat(D3DFMT_A16B16G16R16, "A16B16G16R16");

    //

    DWORD quality;
    status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_D24S8);
    status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8);
    status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8);
    status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, FALSE, D3DMULTISAMPLE_NONE, &quality);
    status = m_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_NONE, &quality);
    status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE);
    status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE);

    // NULL
    constexpr D3DFORMAT NullFormat = D3DFORMAT(MAKEFOURCC('N', 'U', 'L', 'L'));

    status = m_d3d->CheckDepthStencilMatch(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, D3DFMT_D24S8);
    status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, NullFormat);
    status = m_d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, NullFormat);
    status = m_d3d->CheckDeviceFormatConversion(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat);
    status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, false);
    status = m_d3d->CheckDeviceType(adapter, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, NullFormat, true);
    //

    D3DPRESENT_PARAMETERS params;
    getPresentParams(params);

    status = m_d3d->CreateDeviceEx(
      adapter,
      D3DDEVTYPE_HAL,
      m_window,
      D3DCREATE_HARDWARE_VERTEXPROCESSING,
      &params,
      nullptr,
      &m_device);

    if (FAILED(status))
        throw DxvkError("Failed to create D3D9 device");

    // Funny Swapchain Refcounting
    // "One of the things COM does really well, is lifecycle management"
    // Implicit Swapchain
    {
      IDirect3DSurface9* pSurface1 = nullptr;
      IDirect3DSurface9* pSurface2 = nullptr;
      status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface1);
      D3DPRESENT_PARAMETERS newParams = params;
      newParams.BackBufferWidth  = 10;
      newParams.BackBufferHeight = 10;
      status = m_device->Reset(&newParams);
      status = m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface2);

      IDirect3DSwapChain9* pSwapChain2 = nullptr;
      IDirect3DSwapChain9* pSwapChain3 = nullptr;
      status = pSurface1->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain2));
      status = pSurface2->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));

      printf("E_NOINTERFACE! for pSwapchain2");
      status = m_device->Reset(&params);
    }
    // Additional swapchain
    {
      IDirect3DSwapChain9* pSwapChain2 = nullptr;
      IDirect3DSwapChain9* pSwapChain3 = nullptr;
      IDirect3DSwapChain9* pSwapChain4 = nullptr;
      IDirect3DSurface9* pSurface = nullptr;
      status = m_device->CreateAdditionalSwapChain(&params, &pSwapChain2);
      status = pSwapChain2->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
      status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain3));
      pSwapChain2->Release();
      UINT count = pSwapChain2->Release();
      printf("Count: %u - Should be 0 and swapchain dead!", count);
      status = pSurface->GetContainer(__uuidof(IDirect3DSwapChain9), reinterpret_cast<void**>(&pSwapChain4));
      // E_NOINTERFACE !
      printf("E_NOINTERFACE!");
    }

    m_device->AddRef();

    Com<IDirect3DSurface9> backbuffer;
    m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);

    m_device->AddRef();

    Com<IDirect3DSwapChain9> swapchain;
    m_device->GetSwapChain(0, &swapchain);

    m_device->AddRef();

    DWORD bias = 0xDEADBEEF;
    status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
    status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '4'));
    status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);
    status = m_device->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, MAKEFOURCC('G', 'E', 'T', '1'));
    status = m_device->GetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, &bias);

    // Vertex Shader
    {
      Com<ID3DBlob> blob;

      status = D3DCompile(
        g_vertexShaderCode.data(),
        g_vertexShaderCode.length(),
        nullptr, nullptr, nullptr,
        "main",
        "vs_2_0",
        0, 0, &blob,
        nullptr);

      if (FAILED(status))
        throw DxvkError("Failed to compile vertex shader");

      status = m_device->CreateVertexShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_vs);

      if (FAILED(status))
        throw DxvkError("Failed to create vertex shader");
    }

    // Pixel Shader
    {
      Com<ID3DBlob> blob;

      status = D3DCompile(
        g_pixelShaderCode.data(),
        g_pixelShaderCode.length(),
        nullptr, nullptr, nullptr,
        "main",
        "ps_2_0",
        0, 0, &blob,
        nullptr);

      if (FAILED(status))
        throw DxvkError("Failed to compile pixel shader");

      status = m_device->CreatePixelShader(reinterpret_cast<const DWORD*>(blob->GetBufferPointer()), &m_ps);

      if (FAILED(status))
        throw DxvkError("Failed to create pixel shader");
    }

    m_device->SetVertexShader(m_vs.ptr());
    m_device->SetPixelShader(m_ps.ptr());

    m_device->AddRef();
  }

  void run() {
    this->adjustBackBuffer();

    m_device->BeginScene();

    m_device->Clear(
      0,
      nullptr,
      D3DCLEAR_TARGET,
      D3DCOLOR_RGBA(44, 62, 80, 0),
      0,
      0);

    m_device->Clear(
      0,
      nullptr,
      D3DCLEAR_ZBUFFER,
      0,
      0.5f,
      0);

	m_decl = nullptr;

    std::array<D3DVERTEXELEMENT9, 3> elements;

    elements[0].Method = 0;
    elements[0].Offset = 0;
    elements[0].Stream = 0;
    elements[0].Type = D3DDECLTYPE_FLOAT3;
    elements[0].Usage = D3DDECLUSAGE_POSITION;
    elements[0].UsageIndex = 0;

    elements[1].Method = 0;
    elements[1].Offset = 12;
    elements[1].Stream = 0;
    elements[1].Type = D3DDECLTYPE_FLOAT3;
    elements[1].Usage = D3DDECLUSAGE_TEXCOORD;
    elements[1].UsageIndex = 0;

    elements[2] = D3DDECL_END();

    HRESULT result = m_device->CreateVertexDeclaration(elements.data(), &m_decl);
    if (FAILED(result))
      throw DxvkError("Failed to create vertex decl");

    m_device->SetVertexDeclaration(m_decl.ptr());

	float vertexData[] = {
		-1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, -1, 0, 1, 1, -1, -1, 0, 0, 1,

		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	};

	m_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, vertexData, 20);
	//m_device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 3, vertexData, 20);

    //m_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

    m_device->EndScene();

    m_device->PresentEx(
      nullptr,
      nullptr,
      nullptr,
      nullptr,
      0);
  }

  void adjustBackBuffer() {
    RECT windowRect = { 0, 0, 1024, 600 };
    GetClientRect(m_window, &windowRect);

    Extent2D newSize = {
      static_cast<uint32_t>(windowRect.right - windowRect.left),
      static_cast<uint32_t>(windowRect.bottom - windowRect.top),
    };

    if (m_windowSize.w != newSize.w
     || m_windowSize.h != newSize.h) {
      m_windowSize = newSize;

      D3DPRESENT_PARAMETERS params;
      getPresentParams(params);
      HRESULT status = m_device->ResetEx(&params, nullptr);

      if (FAILED(status))
        throw DxvkError("Device reset failed");
    }
  }

  void getPresentParams(D3DPRESENT_PARAMETERS& params) {
    params.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
    params.BackBufferCount = 1;
    params.BackBufferFormat = D3DFMT_X8R8G8B8;
    params.BackBufferWidth = m_windowSize.w;
    params.BackBufferHeight = m_windowSize.h;
    params.EnableAutoDepthStencil = 0;
    params.Flags = 0;
    params.FullScreen_RefreshRateInHz = 0;
    params.hDeviceWindow = m_window;
    params.MultiSampleQuality = 0;
    params.MultiSampleType = D3DMULTISAMPLE_NONE;
    params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
    params.SwapEffect = D3DSWAPEFFECT_DISCARD;
    params.Windowed = TRUE;
  }

private:

  HWND                          m_window;
  Extent2D                      m_windowSize = { 1024, 600 };

  Com<IDirect3D9Ex>             m_d3d;
  Com<IDirect3DDevice9Ex>       m_device;

  Com<IDirect3DVertexShader9>   m_vs;
  Com<IDirect3DPixelShader9>    m_ps;
  Com<IDirect3DVertexBuffer9>   m_vb;
  Com<IDirect3DVertexDeclaration9> m_decl;

};

LRESULT CALLBACK WindowProc(HWND hWnd,
                            UINT message,
                            WPARAM wParam,
                            LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow) {
  HWND hWnd;
  WNDCLASSEXW wc;
  ZeroMemory(&wc, sizeof(WNDCLASSEX));
  wc.cbSize = sizeof(WNDCLASSEX);
  wc.style = CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = WindowProc;
  wc.hInstance = hInstance;
  wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
  wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
  wc.lpszClassName = L"WindowClass1";
  RegisterClassExW(&wc);

  hWnd = CreateWindowExW(0,
    L"WindowClass1",
    L"Our First Windowed Program",
    WS_OVERLAPPEDWINDOW,
    300, 300,
    640, 480,
    nullptr,
    nullptr,
    hInstance,
    nullptr);
  ShowWindow(hWnd, nCmdShow);

  MSG msg;

  try {
    TriangleApp app(hInstance, hWnd);

    while (true) {
      if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);

        if (msg.message == WM_QUIT)
          return msg.wParam;
      } else {
        app.run();
      }
    }
  } catch (const dxvk::DxvkError& e) {
    std::cerr << e.message() << std::endl;
    return msg.wParam;
  }
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
  switch (message) {
    case WM_CLOSE:
      PostQuitMessage(0);
      return 0;
  }

  return DefWindowProc(hWnd, message, wParam, lParam);
}


code:
test_dxbc_deps = [ dxbc_dep, dxvk_dep ]

executable('dxbc-compiler'+exe_ext, files('test_dxbc_compiler.cpp'), dependencies : test_dxbc_deps, install : true, gui_app : true)
executable('dxbc-disasm'+exe_ext,   files('test_dxbc_disasm.cpp'),   dependencies : [ test_dxbc_deps, lib_d3dcompiler_47 ], install : true, gui_app : true)
executable('hlsl-compiler'+exe_ext, files('test_hlsl_compiler.cpp'), dependencies : [ test_dxbc_deps, lib_d3dcompiler_47 ], install : true, gui_app : true)

repo_name: orochi/dxvk


code:
#include <iterator>
#include <fstream>

#include "../../src/dxbc/dxbc_module.h"
#include "../../src/dxvk/dxvk_shader.h"

#include <shellapi.h>
#include <windows.h>
#include <windowsx.h>

namespace dxvk {
  Logger Logger::s_instance("dxbc-compiler.log");
}

using namespace dxvk;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow) {
  int     argc = 0;
  LPWSTR* argv = CommandLineToArgvW(
    GetCommandLineW(), &argc);

  if (argc < 3) {
    Logger::err("Usage: dxbc-compiler input.dxbc output.spv");
    return 1;
  }

  try {
    std::string ifileName = str::fromws(argv[1]);
    std::ifstream ifile(ifileName, std::ios::binary);
    ifile.ignore(std::numeric_limits<std::streamsize>::max());
    std::streamsize length = ifile.gcount();
    ifile.clear();

    ifile.seekg(0, std::ios_base::beg);
    std::vector<char> dxbcCode(length);
    ifile.read(dxbcCode.data(), length);

    DxbcReader reader(dxbcCode.data(), dxbcCode.size());
    DxbcModule module(reader);

    DxbcModuleInfo moduleInfo;
    moduleInfo.options.useSubgroupOpsForAtomicCounters = true;
    moduleInfo.options.useDemoteToHelperInvocation = true;
    moduleInfo.options.minSsboAlignment = 4;
    moduleInfo.xfb = nullptr;

    Rc<DxvkShader> shader = module.compile(moduleInfo, ifileName);
    std::ofstream ofile(str::fromws(argv[2]), std::ios::binary);
    shader->dump(ofile);
    return 0;
  } catch (const DxvkError& e) {
    Logger::err(e.message());
    return 1;
  }
}


code:
#include <iostream>
#include <string>

#include <d3dcompiler.h>

#include <shellapi.h>
#include <windows.h>
#include <windowsx.h>

#include "../../src/util/com/com_pointer.h"

using namespace dxvk;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow) {
  int     argc = 0;
  LPWSTR* argv = CommandLineToArgvW(
    GetCommandLineW(), &argc);

  if (argc < 2 || argc > 3) {
    std::cerr << "Usage: dxbc-disasm input.dxbc [output]" << std::endl;
    return 1;
  }

  Com<ID3DBlob> assembly;
  Com<ID3DBlob> binary;

  // input file
  if (FAILED(D3DReadFileToBlob(argv[1], &binary))) {
    std::cerr << "Failed to read shader" << std::endl;
    return 1;
  }

  HRESULT hr = D3DDisassemble(
    binary->GetBufferPointer(),
    binary->GetBufferSize(),
    D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING, nullptr,
    &assembly);

  if (FAILED(hr)) {
    std::cerr << "Failed to disassemble shader" << std::endl;
    return 1;
  }

  // output file variant
  if (argc == 3 && FAILED(D3DWriteBlobToFile(assembly.ptr(), argv[2], 1))) {
    std::cerr << "Failed to write shader" << std::endl;
    return 1;
  }

  // stdout variant
  if (argc == 2) {
    std::string data((const char *)assembly->GetBufferPointer(), assembly->GetBufferSize());
    std::cout << data;
  }

  return 0;
}


code:
#include <cstring>
#include <fstream>
#include <vector>

#include <d3dcompiler.h>

#include <shellapi.h>
#include <windows.h>
#include <windowsx.h>

#include "../test_utils.h"

using namespace dxvk;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow) {
  int     argc = 0;
  LPWSTR* argv = CommandLineToArgvW(
    GetCommandLineW(), &argc);

  if (argc < 5) {
    std::cerr << "Usage: hlsl-compiler target entrypoint input.hlsl output.dxbc [--strip] [--text]" << std::endl;
    return 1;
  }

  bool strip = false;
  bool text = false;

  for (int i = 5; i < argc; i++) {
    strip |= str::fromws(argv[i]) == "--strip";
    text  |= str::fromws(argv[i]) == "--text";
  }

  const LPWSTR target       = argv[1];
  const LPWSTR entryPoint   = argv[2];
  const LPWSTR inputFile    = argv[3];
  const LPWSTR outputFile   = argv[4];

  std::ifstream ifile(str::fromws(inputFile), std::ios::binary);
  ifile.ignore(std::numeric_limits<std::streamsize>::max());
  std::streamsize length = ifile.gcount();
  ifile.clear();

  ifile.seekg(0, std::ios_base::beg);
  std::vector<char> hlslCode(length);
  ifile.read(hlslCode.data(), length);

  Com<ID3DBlob> binary;
  Com<ID3DBlob> errors;

  HRESULT hr = D3DCompile(
    hlslCode.data(),
    hlslCode.size(),
    "Shader", nullptr,
    D3D_COMPILE_STANDARD_FILE_INCLUDE,
    str::fromws(entryPoint).c_str(),
    str::fromws(target).c_str(),
    D3DCOMPILE_OPTIMIZATION_LEVEL3 |
    D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES,
    0, &binary, &errors);

  if (FAILED(hr)) {
    if (errors != nullptr)
      std::cerr << reinterpret_cast<const char*>(errors->GetBufferPointer()) << std::endl;
    return 1;
  }

  if (strip) {
    Com<ID3DBlob> strippedBlob;

    hr = D3DStripShader(binary->GetBufferPointer(), binary->GetBufferSize(),
      D3DCOMPILER_STRIP_REFLECTION_DATA | D3DCOMPILER_STRIP_DEBUG_INFO,
      &strippedBlob);

    if (FAILED(hr)) {
      std::cerr << "Failed to strip shader" << std::endl;
      return 1;
    }

    binary = strippedBlob;
  }

  std::ofstream file;

  if (str::fromws(outputFile) != "-")
    file = std::ofstream(str::fromws(outputFile), std::ios::binary | std::ios::trunc);

  std::ostream& outputStream = file.is_open() ? file : std::cout;

  if (text) {
    auto data = reinterpret_cast<const uint32_t*>(binary->GetBufferPointer());
    auto size = binary->GetBufferSize() / sizeof(uint32_t);

    outputStream << std::hex;

    for (uint32_t i = 0; i < size; i++) {
      if (i && !(i & 0x7))
        outputStream << std::endl;
      outputStream << "0x" << std::setfill('0') << std::setw(8) << data[i] << ", ";
    }

    outputStream << std::endl;
  } else {
    outputStream.write(reinterpret_cast<const char*>(binary->GetBufferPointer()), binary->GetBufferSize());
  }

  return 0;
}


code:
test_dxgi_deps = [ util_dep, lib_dxgi ]

executable('dxgi-factory'+exe_ext, files('test_dxgi_factory.cpp'), dependencies : test_dxgi_deps, install: true, gui_app : true)


code:
#include <vector>

#include <dxgi.h>

#include <windows.h>
#include <windowsx.h>

#include "../test_utils.h"

using namespace dxvk;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow) {
  Com<IDXGIFactory> factory;

  if (CreateDXGIFactory(__uuidof(IDXGIFactory),
      reinterpret_cast<void**>(&factory)) != S_OK) {
    std::cerr << "Failed to create DXGI factory" << std::endl;
    return 1;
  }

  Com<IDXGIAdapter> adapter;

  for (UINT i = 0; factory->EnumAdapters(i, &adapter) == S_OK; i++) {
    DXGI_ADAPTER_DESC adapterDesc;

    if (adapter->GetDesc(&adapterDesc) != S_OK) {
      std::cerr << "Failed to get DXGI adapter info" << std::endl;
      return 1;
    }

    DXGI_ADAPTER_DESC desc;

    if (adapter->GetDesc(&desc) != S_OK) {
      std::cerr << "Failed to get DXGI adapter info" << std::endl;
      return 1;
    }

    std::cout << str::format("Adapter ", i, ":") << std::endl;
    std::cout << str::format(" ", desc.Description) << std::endl;
    std::cout << str::format(" Vendor: ", desc.VendorId) << std::endl;
    std::cout << str::format(" Device: ", desc.DeviceId) << std::endl;
    std::cout << str::format(" Dedicated RAM: ", desc.DedicatedVideoMemory) << std::endl;
    std::cout << str::format(" Shared RAM: ", desc.SharedSystemMemory) << std::endl;

    Com<IDXGIOutput> output;

    for (UINT j = 0; adapter->EnumOutputs(j, &output) == S_OK; j++) {
      std::vector<DXGI_MODE_DESC> modes;

      DXGI_OUTPUT_DESC desc;

      if (output->GetDesc(&desc) != S_OK) {
        std::cerr << "Failed to get DXGI output info" << std::endl;
        return 1;
      }

      std::cout << str::format(" Output ", j, ":") << std::endl;
      std::cout << str::format("  ", desc.DeviceName) << std::endl;
      std::cout << str::format("  Coordinates: ",
        desc.DesktopCoordinates.left, ",",
        desc.DesktopCoordinates.top, ":",
        desc.DesktopCoordinates.right - desc.DesktopCoordinates.left, "x",
        desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top) << std::endl;

      HRESULT status = S_OK;
      UINT    displayModeCount = 0;

      do {
        if (output->GetDisplayModeList(
          DXGI_FORMAT_R8G8B8A8_UNORM,
          DXGI_ENUM_MODES_SCALING,
          &displayModeCount, nullptr) != S_OK) {
          std::cerr << "Failed to get DXGI output display mode count" << std::endl;
          return 1;
        }

        modes.resize(displayModeCount);

        status = output->GetDisplayModeList(
          DXGI_FORMAT_R8G8B8A8_UNORM,
          DXGI_ENUM_MODES_SCALING,
          &displayModeCount, modes.data());
      } while (status == DXGI_ERROR_MORE_DATA);

      if (status != S_OK) {
        std::cerr << "Failed to get DXGI output display mode list" << std::endl;
        return 1;
      }

      for (auto mode : modes) {
        std::cout << str::format("  ",
          mode.Width, "x", mode.Height, " @ ",
          mode.RefreshRate.Numerator / mode.RefreshRate.Denominator,
          mode.Scaling == DXGI_MODE_SCALING_CENTERED ? " (native)" : "") << std::endl;

        //test matching modes
        DXGI_MODE_DESC matched_mode{ 0 };
        status = output->FindClosestMatchingMode(&mode, &matched_mode, nullptr);

        if (status != S_OK) {
            std::cerr << "Failed to get matching mode" << std::endl;
            return 1;
        }

        if (matched_mode.Width != mode.Width ||
            matched_mode.Height != mode.Height ||
            matched_mode.RefreshRate.Numerator != mode.RefreshRate.Numerator ||
            matched_mode.RefreshRate.Denominator != mode.RefreshRate.Denominator ||
            matched_mode.Format != mode.Format)
        {
            std::cerr << "Matched mode is incorrect" << std::endl;
            return 1;
        }
      }
    }
  }

  return 0;
}


code:
subdir('d3d9')
subdir('d3d11')
subdir('dxbc')
subdir('dxgi')


code:
#pragma once

#include <iostream>

#include "../src/util/com/com_guid.h"
#include "../src/util/com/com_object.h"
#include "../src/util/com/com_pointer.h"

#include "../src/util/log/log.h"
#include "../src/util/log/log_debug.h"

#include "../src/util/rc/util_rc.h"
#include "../src/util/rc/util_rc_ptr.h"

#include "../src/util/util_enum.h"
#include "../src/util/util_error.h"
#include "../src/util/util_string.h"


code:
#pragma once

#define DXVK_VERSION "@VCS_TAG@"


code:
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs     diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln       merge=binary
#*.csproj    merge=binary
#*.vbproj    merge=binary
#*.vcxproj   merge=binary
#*.vcproj    merge=binary
#*.dbproj    merge=binary
#*.fsproj    merge=binary
#*.lsproj    merge=binary
#*.wixproj   merge=binary
#*.modelproj merge=binary
#*.sqlproj   merge=binary
#*.wwaproj   merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg   binary
#*.png   binary
#*.gif   binary

###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc   diff=astextplain
#*.DOC   diff=astextplain
#*.docx  diff=astextplain
#*.DOCX  diff=astextplain
#*.dot   diff=astextplain
#*.DOT   diff=astextplain
#*.pdf   diff=astextplain
#*.PDF   diff=astextplain
#*.rtf   diff=astextplain
#*.RTF   diff=astextplain

path: .gitattributes

license: unknown


code:
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore

# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# Visual Studio 2017 auto generated files
Generated\ Files/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# Benchmark Results
BenchmarkDotNet.Artifacts/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/

# StyleCop
StyleCopReport.xml

# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# Visual Studio Trace Files
*.e2e

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json

# Visual Studio code coverage results
*.coverage
*.coveragexml

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak

# SQL Server files
*.mdf
*.ldf
*.ndf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# CodeRush personal settings
.cr/personal

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config

# Tabs Studio
*.tss

# Telerik's JustMock configuration file
*.jmconfig

# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
*.binlog

# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
.mfractor/

# Local History for Visual Studio
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb
/Source/Patches/PawnAnimationPatches/HarmonyPatch_Pawn_DrawTracker.cs
/Source/Patches/PawnAnimationPatches/HarmonyPatch_PawnRotation.cs
/Source/Patches/PawnAnimationPatches/HarmonyPatch_PawnRenderer.cs
/Source/Patches/OtherModPatches/HarmonyPatch_ShowHairWithHats.cs
/Source/Patches/OtherModPatches/HarmonyPatch_FacialAnimation.cs
/Source/Patches/OtherModPatches/HarmonyPatch_DontShaveYourHead.cs
/Source/Patches/OtherModPatches/HarmonyPatch_CSL.cs
/Source/Patches/OtherModPatches/HarmonyPatch_AlienRace.cs
/Source/Patches/ThingAnimationPatches/HarmonyPatch_ThingDrawAt.cs
/Defs/AnimationDefs/Animations_SexToys.xml

path: .gitignore