ソースを参照

Adds support for device cycle and help to HLSL Host window. (#100)

Adds support for device cycle and help to HLSL Host window.
Marcelo Lopez Ruiz 8 年 前
コミット
8ec6fb32d1
1 ファイル変更70 行追加7 行削除
  1. 70 7
      tools/clang/unittests/HLSLHost/HLSLHost.cpp

+ 70 - 7
tools/clang/unittests/HLSLHost/HLSLHost.cpp

@@ -218,6 +218,7 @@ private:
   CComPtr<ID3D12CommandQueue> m_commandQueue;
   CComPtr<IDXGISwapChain3> m_swapChain;
   UINT FrameCount = 2;
+  UINT m_TargetDeviceIndex = 0;
   UINT m_frameIndex;
   UINT m_renderCount = 0;
   HMODULE m_TestDLL = NULL;
@@ -267,6 +268,22 @@ private:
     MessageBox(m_hwnd, OpMessage, "Resource Copy", MessageType);
   }
 
+  void HandleDeviceCycle() {
+    ReleaseD3DResources();
+    ++m_TargetDeviceIndex;
+    SetupD3D();
+  }
+
+  void HandleHelp() {
+    MessageBoxW(m_hwnd, L"Commands:\r\n"
+      L"(C)opy Results\r\n"
+      L"(D)evice Cycle\r\n"
+      L"(H)elp (show this message)\r\n"
+      L"(R)un\r\n"
+      L"(Q)uit",
+      L"HLSL Host Help", MB_OK);
+  }
+
   HRESULT HandlePayload() {
     CComPtr<ID3D12Resource> pRT;
     m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
@@ -296,6 +313,13 @@ private:
     }
     return S_OK;
   }
+
+  void ReleaseD3DResources() {
+    m_device.Release();
+    m_commandQueue.Release();
+    m_swapChain.Release();
+  }
+
   HRESULT SetupD3D() {
     IFR(LoadTestDll());
 
@@ -307,11 +331,25 @@ private:
     CComPtr<IDXGIFactory4> factory;
     IFR(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));
 
-    // TODO: make this configurable, don't just use WARP all the time.
-    CComPtr<IDXGIAdapter> warpAdapter;
-    IFR(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));
+    CComPtr<IDXGIAdapter> adapter;
+    if (m_TargetDeviceIndex > 0) {
+      UINT hardwareIndex = m_TargetDeviceIndex - 1;
+      HRESULT hrEnum = factory->EnumAdapters(hardwareIndex, &adapter);
+      if (hrEnum == DXGI_ERROR_NOT_FOUND) {
+        m_TargetDeviceIndex = 0; // cycle to WARP
+      }
+      else {
+        IFR(hrEnum);
+      }
+    }
+    if (m_TargetDeviceIndex == 0) {
+      IFR(factory->EnumWarpAdapter(IID_PPV_ARGS(&adapter)));
+    }
 
-    IFR(D3D12CreateDevice(warpAdapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&m_device)));
+    HRESULT hrCreate = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0,
+                                         IID_PPV_ARGS(&m_device));
+    IFR(SetWindowTextToDevice(hrCreate, m_hwnd, adapter, m_device));
+    IFR(hrCreate);
 
     // Describe and create the command queue.
     D3D12_COMMAND_QUEUE_DESC queueDesc = {};
@@ -342,6 +380,27 @@ private:
 
     return S_OK;
   }
+
+  HRESULT SetWindowTextToDevice(HRESULT hrCreate, HWND hwnd, IDXGIAdapter *pAdapter, ID3D12Device *pDevice) {
+    DXGI_ADAPTER_DESC AdapterDesc;
+    D3D12_FEATURE_DATA_D3D12_OPTIONS1 DeviceOptions;
+    D3D12_FEATURE_DATA_SHADER_MODEL DeviceSM;
+    wchar_t title[200];
+    IFR(pAdapter->GetDesc(&AdapterDesc));
+    IFR(pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1, &DeviceOptions, sizeof(DeviceOptions)));
+    DeviceSM.HighestShaderModel = D3D_SHADER_MODEL_6_0;
+    IFR(pDevice->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &DeviceSM, sizeof(DeviceSM)));
+    IFR(StringCchPrintfW(
+        title, _countof(title),
+        L"%s%s - caps:%s%s%s",
+        SUCCEEDED(hrCreate) ? L"" : L"(cannot create D3D12 device)",
+        AdapterDesc.Description,
+        (DeviceSM.HighestShaderModel >= D3D_SHADER_MODEL_6_0) ? L" SM6" : L"",
+        DeviceOptions.WaveOps ? L" WaveOps" : L"",
+        DeviceOptions.Int64ShaderOps ? L" I64" : L""));
+    SetWindowTextW(hwnd, title);
+    return S_OK;
+  }
 public:
   HRESULT Start(void *pLogCtx, OutputStringFn pLog) {
     if (SUCCEEDED(m_threadStartResult)) {
@@ -468,6 +527,12 @@ public:
       if (wParam == 'C') {
         HandleCopy();
       }
+      if (wParam == 'H') {
+        HandleHelp();
+      }
+      if (wParam == 'D') {
+        HandleDeviceCycle();
+      }
       if (wParam == '2') {
         DXGI_MODE_DESC d;
         ZeroMemory(&d, sizeof(d));
@@ -477,9 +542,7 @@ public:
       }
       break;
     case WM_DESTROY:
-      m_device.Release();
-      m_commandQueue.Release();
-      m_swapChain.Release();
+      ReleaseD3DResources();
       PostQuitMessage(0);
       break;
     case WM_RENDERER_SETPAYLOAD: