Skip to content

Commit d74db81

Browse files
committed
Merge branch 'bfi-wip' into bfi
2 parents e62bb5a + 6ba48eb commit d74db81

File tree

11 files changed

+381
-112
lines changed

11 files changed

+381
-112
lines changed

ShaderGlass/CaptureManager.cpp

Lines changed: 99 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ using namespace std;
2222
using namespace util;
2323
using namespace util::uwp;
2424

25-
CaptureManager::CaptureManager(HINSTANCE instance) : m_options(), m_deviceName(L"Default"), m_lastPreset(-1), m_instance {instance} { }
25+
CaptureManager::CaptureManager(HINSTANCE instance) : m_options(), m_lastPreset(-1), m_instance {instance} { }
2626

2727
bool CaptureManager::Initialize()
2828
{
@@ -93,10 +93,12 @@ const std::vector<GraphicsAdapter>& CaptureManager::GraphicsAdapters()
9393
if((desc.VendorId == 0x1414) && (desc.DeviceId == 0x8c))
9494
continue; // Microsoft Basic Render Driver
9595

96-
wchar_t id[24];
97-
_snwprintf_s(id, 24, L"%lx:%lx", desc.AdapterLuid.HighPart, desc.AdapterLuid.LowPart);
98-
m_graphicsAdapters.emplace_back(no++, std::wstring(desc.Description), std::wstring(id), adapter);
96+
m_graphicsAdapters.emplace_back(no++, std::wstring(desc.Description), adapter, desc.AdapterLuid, false, false);
9997
}
98+
99+
// max GPUs
100+
if(m_graphicsAdapters.size() == 3)
101+
break;
100102
}
101103
}
102104
return m_graphicsAdapters;
@@ -120,35 +122,38 @@ DWORD WINAPI ThreadFuncProxy(LPVOID lpParam)
120122

121123
bool CaptureManager::StartSession()
122124
{
123-
bool hybrid = false;
125+
bool cross = false;
124126

125127
if(!m_captureDevice)
126128
{
127-
m_captureDevice = CreateD3DDevice(m_captureAdapter);
128-
if(m_captureAdapter != m_renderAdapter)
129+
IDXGIAdapter *captureAdapter = nullptr, *renderAdapter = nullptr;
130+
if(m_graphicsAdapters.size() > 1)
131+
{
132+
for(const auto& ga : m_graphicsAdapters)
133+
{
134+
if(ga.capture)
135+
captureAdapter = ga.adapter.get();
136+
if(ga.render)
137+
renderAdapter = ga.adapter.get();
138+
}
139+
}
140+
141+
m_captureDevice = CreateD3DDevice(captureAdapter);
142+
if(captureAdapter != nullptr && renderAdapter != nullptr && captureAdapter != renderAdapter)
129143
{
130-
m_renderDevice = CreateD3DDevice(m_renderAdapter);
131-
hybrid = true;
144+
m_renderDevice = CreateD3DDevice(renderAdapter);
145+
cross = true;
132146
}
133147
else
134148
{
135149
m_renderDevice = m_captureDevice;
136150
}
137151
m_renderDevice->GetImmediateContext(m_renderContext.put());
138152

139-
// get actual GPU name
140-
{
141-
auto dxgiDevice = m_renderDevice.as<IDXGIDevice>();
142-
winrt::com_ptr<IDXGIAdapter> adapter;
143-
if(SUCCEEDED(dxgiDevice->GetAdapter(adapter.put())))
144-
{
145-
DXGI_ADAPTER_DESC desc;
146-
if(SUCCEEDED(adapter->GetDesc(&desc)))
147-
{
148-
m_deviceName = std::wstring(desc.Description);
149-
}
150-
}
151-
}
153+
// mark GPUs
154+
LUID captureId = GetAdapterLuid(m_captureDevice);
155+
LUID renderId = GetAdapterLuid(m_renderDevice);
156+
SetGraphicsAdapters(captureId, renderId);
152157
}
153158

154159
#ifdef _DEBUG
@@ -185,6 +190,8 @@ bool CaptureManager::StartSession()
185190
UpdatePixelSize();
186191
UpdateOutputSize();
187192
UpdateOutputFlip();
193+
UpdateSyncSubFrame();
194+
UpdateInternalVSync();
188195
UpdateShaderPreset();
189196
UpdateFrameSkip();
190197
UpdateLockedArea();
@@ -242,12 +249,12 @@ bool CaptureManager::StartSession()
242249
: winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized;
243250

244251
m_session =
245-
make_unique<CaptureSession>(m_captureDevice, hybrid ? m_renderDevice : nullptr, captureItem, pixelFormat, *m_shaderGlass, m_options.maxCaptureRate, m_frameEvent);
252+
make_unique<CaptureSession>(m_captureDevice, cross ? m_renderDevice : nullptr, captureItem, pixelFormat, *m_shaderGlass, m_options.maxCaptureRate, m_frameEvent);
246253
}
247254

248-
m_active = true;
249-
auto thread = CreateThread(NULL, 0, ThreadFuncProxy, this, 0, NULL);
250-
SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL);
255+
m_active = true;
256+
m_thread = CreateThread(NULL, 0, ThreadFuncProxy, this, 0, NULL);
257+
SetThreadPriority(m_thread, THREAD_PRIORITY_TIME_CRITICAL);
251258

252259
UpdateCursor();
253260
return true;
@@ -379,6 +386,9 @@ void CaptureManager::Exit()
379386
m_shaderGlass->Stop();
380387
delete m_shaderGlass.release();
381388

389+
m_renderContext->ClearState();
390+
m_renderContext->Flush();
391+
382392
if(m_debug)
383393
{
384394
m_debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL | D3D11_RLDO_IGNORE_INTERNAL);
@@ -415,6 +425,22 @@ void CaptureManager::UpdateOutputFlip()
415425
}
416426
}
417427

428+
void CaptureManager::UpdateSyncSubFrame()
429+
{
430+
if(m_shaderGlass)
431+
{
432+
m_shaderGlass->SetSyncSubFrame(m_options.syncSubFrame);
433+
}
434+
}
435+
436+
void CaptureManager::UpdateInternalVSync()
437+
{
438+
if(m_shaderGlass)
439+
{
440+
m_shaderGlass->SetInternalVSync(m_options.internalVSync);
441+
}
442+
}
443+
418444
void CaptureManager::UpdateShaderPreset()
419445
{
420446
if(m_shaderGlass)
@@ -573,19 +599,56 @@ bool CaptureManager::FindDeviceFormat(int deviceFormatNo, std::vector<CaptureDev
573599
return false;
574600
}
575601

576-
void CaptureManager::SetCaptureAdapters(const std::wstring& captureId, const std::wstring& renderId)
602+
void CaptureManager::SetGraphicsAdapters(LUID captureId, LUID renderId)
603+
{
604+
for(auto& ga : m_graphicsAdapters)
605+
{
606+
ga.capture = (ga.luid.HighPart == captureId.HighPart && ga.luid.LowPart == captureId.LowPart);
607+
ga.render = (ga.luid.HighPart == renderId.HighPart && ga.luid.LowPart == renderId.LowPart);
608+
}
609+
}
610+
611+
void CaptureManager::SetGraphicsAdapters(int captureNo, int renderNo, LUID& captureId, LUID& renderId)
612+
{
613+
bool active = m_active;
614+
if(active)
615+
StopSession();
616+
captureId.LowPart = 0;
617+
captureId.HighPart = 0;
618+
renderId.LowPart = 0;
619+
renderId.HighPart = 0;
620+
for(auto& ga : m_graphicsAdapters)
621+
{
622+
if(captureNo == ga.no)
623+
{
624+
captureId = ga.luid;
625+
}
626+
if(renderNo == ga.no)
627+
{
628+
renderId = ga.luid;
629+
}
630+
}
631+
SetGraphicsAdapters(captureId, renderId);
632+
m_defaultAdapter = (captureNo == 0 && renderNo == 0);
633+
m_captureDevice = nullptr;
634+
m_renderDevice = nullptr;
635+
636+
Sleep(1000);
637+
if(active)
638+
StartSession();
639+
}
640+
641+
LUID CaptureManager::GetAdapterLuid(winrt::com_ptr<ID3D11Device> device)
577642
{
578-
m_captureAdapter = nullptr;
579-
m_renderAdapter = nullptr;
580-
if(captureId.size() || renderId.size())
643+
auto dxgiDevice = device.as<IDXGIDevice>();
644+
winrt::com_ptr<IDXGIAdapter> adapter;
645+
if(SUCCEEDED(dxgiDevice->GetAdapter(adapter.put())))
581646
{
582-
const auto& graphicsAdapters = GraphicsAdapters();
583-
for(const auto& ga : graphicsAdapters)
647+
DXGI_ADAPTER_DESC desc;
648+
if(SUCCEEDED(adapter->GetDesc(&desc)))
584649
{
585-
if(ga.id == captureId)
586-
m_captureAdapter = ga.adapter;
587-
if(ga.id == renderId)
588-
m_renderAdapter = ga.adapter;
650+
return desc.AdapterLuid;
589651
}
590652
}
653+
return LUID();
591654
}

ShaderGlass/CaptureManager.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ struct CaptureOptions
4343
RECT croppedArea {0, 0, 0, 0};
4444
bool vertical {false};
4545
unsigned subFrames {0};
46+
bool syncSubFrame {true};
47+
bool internalVSync {false};
4648
};
4749

4850
class CaptureManager
@@ -51,7 +53,7 @@ class CaptureManager
5153
CaptureManager(HINSTANCE instance);
5254

5355
CaptureOptions m_options;
54-
std::wstring m_deviceName;
56+
bool m_defaultAdapter {true};
5557

5658
const std::vector<std::unique_ptr<PresetDef>>& Presets();
5759
std::vector<std::tuple<int, ShaderParam*>> Params();
@@ -70,6 +72,8 @@ class CaptureManager
7072
void UpdatePixelSize();
7173
void UpdateOutputSize();
7274
void UpdateOutputFlip();
75+
void UpdateSyncSubFrame();
76+
void UpdateInternalVSync();
7377
void UpdateShaderPreset();
7478
void UpdateFrameSkip();
7579
bool UpdateInput();
@@ -94,7 +98,9 @@ class CaptureManager
9498
float OutFPS();
9599
int FindByName(const char* presetName);
96100
bool FindDeviceFormat(int deviceFormatNo, std::vector<CaptureDevice>::const_iterator& device, std::vector<CaptureFormat>::const_iterator& format);
97-
void SetCaptureAdapters(const std::wstring& captureId, const std::wstring& renderId);
101+
void SetGraphicsAdapters(int captureNo, int renderNo, LUID& captureId, LUID& renderId);
102+
void SetGraphicsAdapters(LUID captureId, LUID renderId);
103+
LUID GetAdapterLuid(winrt::com_ptr<ID3D11Device> device);
98104

99105
private:
100106
volatile bool m_active {false};
@@ -110,12 +116,11 @@ class CaptureManager
110116
std::vector<std::tuple<int, std::string, double>> m_lastParams;
111117
std::vector<CaptureDevice> m_captureDevices;
112118
std::vector<GraphicsAdapter> m_graphicsAdapters;
113-
IDXGIAdapter* m_captureAdapter {nullptr};
114-
IDXGIAdapter* m_renderAdapter {nullptr};
115119
ShaderCache m_shaderCache;
116120
DeviceCapture m_deviceCapture;
117121
CursorEmulator m_cursorEmulator;
118122
HANDLE m_frameEvent {nullptr};
123+
HANDLE m_thread {0};
119124
HINSTANCE m_instance {0};
120125
unsigned int m_lastPreset;
121126
};

ShaderGlass/CaptureSession.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ CaptureSession::CaptureSession(winrt::com_ptr<ID3D11Device> captureDevice,
3737
m_device = CreateDirect3DDevice(dxgiDevice.get());
3838

3939
m_contentSize = m_item.Size();
40-
m_framePool = winrt::Direct3D11CaptureFramePool::CreateFreeThreaded(m_device, pixelFormat, 2, m_contentSize);
40+
//m_framePool = winrt::Direct3D11CaptureFramePool::CreateFreeThreaded(m_device, pixelFormat, 2, m_contentSize);
41+
m_framePool = winrt::Direct3D11CaptureFramePool::Create(m_device, pixelFormat, 2, m_contentSize);
4142
m_session = m_framePool.CreateCaptureSession(m_item);
4243

4344
// try to disable yellow border
@@ -56,15 +57,15 @@ CaptureSession::CaptureSession(winrt::com_ptr<ID3D11Device> captureDevice,
5657
try
5758
{
5859
// max 250Hz?
59-
const auto minInterval = maxCaptureRate ? std::chrono::milliseconds(4) : std::chrono::milliseconds(15);
60+
const auto minInterval = maxCaptureRate ? std::chrono::milliseconds(1) : std::chrono::milliseconds(15);
6061
m_session.MinUpdateInterval(winrt::Windows::Foundation::TimeSpan(minInterval));
6162
}
6263
catch(...)
6364
{ }
6465
}
6566

6667
Reset();
67-
m_framePool.FrameArrived({this, &CaptureSession::OnFrameArrived});
68+
//m_framePool.FrameArrived({this, &CaptureSession::OnFrameArrived});
6869
m_session.StartCapture();
6970

7071
WINRT_ASSERT(m_session != nullptr);
@@ -93,7 +94,12 @@ void CaptureSession::UpdateCursor(bool captureCursor)
9394

9495
void CaptureSession::OnFrameArrived(winrt::Direct3D11CaptureFramePool const& sender, winrt::IInspectable const&)
9596
{
97+
if(!m_session)
98+
return;
99+
96100
auto frame = sender.TryGetNextFrame();
101+
if(!frame)
102+
return;
97103
auto inputFrame = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
98104

99105
auto contentSize = frame.ContentSize();
@@ -108,7 +114,7 @@ void CaptureSession::OnFrameArrived(winrt::Direct3D11CaptureFramePool const& sen
108114

109115
m_textureBridge.PutInputFrame(inputFrame, resized);
110116

111-
SetEvent(m_frameEvent);
117+
//SetEvent(m_frameEvent);
112118
OnInputFrame();
113119
}
114120

@@ -134,6 +140,7 @@ void CaptureSession::ProcessInput()
134140
}
135141
else
136142
{
143+
OnFrameArrived(m_framePool, nullptr);
137144
m_shaderGlass.Process(m_textureBridge.GetInputFrame(), m_frameTicks, m_numInputFrames);
138145
}
139146
}
@@ -162,6 +169,8 @@ TextureBridge::TextureBridge(winrt::com_ptr<ID3D11Device> captureDevice, winrt::
162169

163170
TextureBridge::~TextureBridge()
164171
{
172+
std::unique_lock lock(m_inputMutex);
173+
165174
if(m_inputData)
166175
{
167176
free(m_inputData);
@@ -203,7 +212,7 @@ void TextureBridge::PutInputFrame(winrt::com_ptr<ID3D11Texture2D> inputFrame, bo
203212
m_inputResized = true;
204213
}
205214

206-
if(sourceResource.DepthPitch != m_inputSize)
215+
if(sourceResource.DepthPitch != m_inputSize || !m_inputData)
207216
{
208217
if(m_inputData)
209218
free(m_inputData);

ShaderGlass/Options.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ GNU General Public License v3.0
1818
#define MAX_RECENT_PROFILES 20U
1919
#define MAX_RECENT_IMPORTS 20U
2020
#define MAX_SUBFRAMES 10U
21+
#define MAX_GPU 4U
22+
#define MAX_GPUS 17U
2123

2224
#define WM_PIXEL_SIZE(i) (static_cast<UINT>(WM_USER) + i)
2325
#define WM_ASPECT_RATIO(i) (static_cast<UINT> WM_PIXEL_SIZE(MAX_PIXEL_SIZES) + i)
@@ -30,9 +32,12 @@ GNU General Public License v3.0
3032
#define WM_RECENT_IMPORT(i) (static_cast<UINT> WM_RECENT_PROFILE(MAX_RECENT_PROFILES) + i)
3133
#define WM_CAPTURE_DEVICE_FORMAT(i) (static_cast<UINT> WM_RECENT_IMPORT(MAX_RECENT_IMPORTS) + i)
3234
#define WM_SUBFRAMES(i) (static_cast<UINT> WM_CAPTURE_DEVICE_FORMAT(MAX_CAPTURE_DEVICE_FORMATS) + i)
35+
#define WM_GPU(ci, ri) (static_cast<UINT> WM_SUBFRAMES(MAX_SUBFRAMES) + (ci << 2) + ri)
3336

3437
#define CUSTOM_MNEMONIC "Custom"
3538

39+
#define FORCE_FLIPMODE
40+
3641
struct PixelSizeInfo
3742
{
3843
float w;
@@ -117,10 +122,13 @@ struct CaptureDevice
117122

118123
struct GraphicsAdapter
119124
{
120-
unsigned no;
121-
std::wstring name;
122-
std::wstring id;
123-
IDXGIAdapter* adapter;
125+
unsigned no;
126+
std::wstring name;
127+
winrt::com_ptr<IDXGIAdapter> adapter;
128+
LUID luid;
129+
130+
bool capture;
131+
bool render;
124132
};
125133

126134
struct HotkeyInfo

0 commit comments

Comments
 (0)