mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 23:00:42 +00:00
More work. Audio driver works enough to play music now.
This commit is contained in:
@@ -1,290 +1,294 @@
|
||||
#include "GpDisplayDriverD3D11.h"
|
||||
#include "GpWindows.h"
|
||||
#include "GpFiber_Win32.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma comment (lib, "d3d11.lib")
|
||||
|
||||
void DebugPrintf(const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
vsnprintf_s(buf, 255, fmt, argp);
|
||||
OutputDebugString(buf);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void StartD3DForWindow(HWND hWnd, IDXGISwapChain1*& swapChain)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
|
||||
|
||||
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
|
||||
|
||||
swapChainDesc.BufferCount = 2;
|
||||
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullscreenDesc;
|
||||
|
||||
ZeroMemory(&swapChainFullscreenDesc, sizeof(swapChainFullscreenDesc));
|
||||
|
||||
swapChainFullscreenDesc.Windowed = TRUE;
|
||||
swapChainFullscreenDesc.RefreshRate.Numerator = 60;
|
||||
swapChainFullscreenDesc.RefreshRate.Denominator = 1;
|
||||
|
||||
UINT flags = 0;
|
||||
const D3D_FEATURE_LEVEL featureLevels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_9_1
|
||||
};
|
||||
|
||||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
ID3D11DeviceContext *context = NULL;
|
||||
|
||||
D3D_FEATURE_LEVEL selectedFeatureLevel;
|
||||
|
||||
HRESULT result = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevels, sizeof(featureLevels) / sizeof(featureLevels[0]),
|
||||
D3D11_SDK_VERSION, &device, &selectedFeatureLevel, &context);
|
||||
|
||||
IDXGIDevice2 *dxgiDevice = nullptr;
|
||||
result = device->QueryInterface(__uuidof(IDXGIDevice2), reinterpret_cast<void**>(&dxgiDevice));
|
||||
|
||||
IDXGIAdapter *dxgiAdapter = nullptr;
|
||||
result = dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||
|
||||
IDXGIFactory2 *dxgiFactory = nullptr;
|
||||
result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory));
|
||||
|
||||
result = dxgiFactory->CreateSwapChainForHwnd(device, hWnd, &swapChainDesc, nullptr, nullptr, &swapChain);
|
||||
}
|
||||
|
||||
bool GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
{
|
||||
DXGI_PRESENT_PARAMETERS presentParams;
|
||||
|
||||
ZeroMemory(&presentParams, sizeof(presentParams));
|
||||
|
||||
UINT lastPresentCount = 0;
|
||||
|
||||
if (FAILED(m_SwapChain->GetLastPresentCount(&lastPresentCount)))
|
||||
return false;
|
||||
|
||||
if (FAILED(m_SwapChain->Present1(1, 0, &presentParams)))
|
||||
return false;
|
||||
|
||||
//DebugPrintf("r: %i\n", static_cast<int>(r));
|
||||
|
||||
DXGI_FRAME_STATISTICS stats;
|
||||
if (FAILED(m_SwapChain->GetFrameStatistics(&stats)))
|
||||
return false;
|
||||
|
||||
if (stats.SyncQPCTime.QuadPart != 0)
|
||||
{
|
||||
if (m_SyncTimeBase.QuadPart == 0)
|
||||
m_SyncTimeBase = stats.SyncQPCTime;
|
||||
|
||||
LARGE_INTEGER timestamp;
|
||||
timestamp.QuadPart = stats.SyncQPCTime.QuadPart - m_SyncTimeBase.QuadPart;
|
||||
|
||||
bool compacted = false;
|
||||
if (m_PresentHistory.Size() > 0)
|
||||
{
|
||||
CompactedPresentHistoryItem &lastItem = m_PresentHistory[m_PresentHistory.Size() - 1];
|
||||
LONGLONG timeDelta = timestamp.QuadPart - lastItem.m_Timestamp.QuadPart;
|
||||
|
||||
if (timeDelta < 0)
|
||||
timeDelta = 0; // This should never happen
|
||||
|
||||
if (timeDelta * static_cast<LONGLONG>(m_Properties.m_FrameTimeLockDenominator) < m_QPFrequency.QuadPart * static_cast<LONGLONG>(m_Properties.m_FrameTimeLockNumerator))
|
||||
{
|
||||
lastItem.m_NumFrames++;
|
||||
compacted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!compacted)
|
||||
{
|
||||
if (m_PresentHistory.Size() == m_PresentHistory.CAPACITY)
|
||||
m_PresentHistory.RemoveFromStart();
|
||||
|
||||
CompactedPresentHistoryItem *newItem = m_PresentHistory.Append();
|
||||
newItem->m_Timestamp = timestamp;
|
||||
newItem->m_NumFrames = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_PresentHistory.Size() >= 2)
|
||||
{
|
||||
const size_t presentHistorySizeMinusOne = m_PresentHistory.Size() - 1;
|
||||
unsigned int numFrames = 0;
|
||||
for (size_t i = 0; i < presentHistorySizeMinusOne; i++)
|
||||
numFrames += m_PresentHistory[i].m_NumFrames;
|
||||
|
||||
LONGLONG timeFrame = m_PresentHistory[presentHistorySizeMinusOne].m_Timestamp.QuadPart - m_PresentHistory[0].m_Timestamp.QuadPart;
|
||||
|
||||
unsigned int cancelledFrames = 0;
|
||||
LONGLONG cancelledTime = 0;
|
||||
|
||||
const int overshootTolerance = 2;
|
||||
|
||||
for (size_t i = 0; i < presentHistorySizeMinusOne; i++)
|
||||
{
|
||||
LONGLONG blockTimeframe = m_PresentHistory[i + 1].m_Timestamp.QuadPart - m_PresentHistory[i].m_Timestamp.QuadPart;
|
||||
unsigned int blockNumFrames = m_PresentHistory[i].m_NumFrames;
|
||||
|
||||
if (blockTimeframe * static_cast<LONGLONG>(numFrames) >= timeFrame * static_cast<LONGLONG>(blockNumFrames) * overshootTolerance)
|
||||
{
|
||||
cancelledTime += blockTimeframe;
|
||||
cancelledFrames += blockNumFrames;
|
||||
}
|
||||
}
|
||||
|
||||
numFrames -= cancelledFrames;
|
||||
timeFrame -= cancelledTime;
|
||||
|
||||
// timeFrame / numFrames = Frame timestep
|
||||
// Unless Frame timestep is within the frame lock range, a.k.a.
|
||||
// timeFrame / numFrames / qpFreq >= minFrameTimeNum / minFrameTimeDenom
|
||||
|
||||
bool isInFrameTimeLock = false;
|
||||
if (timeFrame * static_cast<LONGLONG>(m_Properties.m_FrameTimeLockMinDenominator) >= static_cast<LONGLONG>(numFrames) * static_cast<LONGLONG>(m_Properties.m_FrameTimeLockMinNumerator) * m_QPFrequency.QuadPart
|
||||
&& timeFrame * static_cast<LONGLONG>(m_Properties.m_FrameTimeLockMaxDenominator) <= static_cast<LONGLONG>(numFrames) * static_cast<LONGLONG>(m_Properties.m_FrameTimeLockMaxNumerator) * m_QPFrequency.QuadPart)
|
||||
{
|
||||
isInFrameTimeLock = true;
|
||||
}
|
||||
|
||||
LONGLONG frameTimeStep = m_FrameTimeSliceSize;
|
||||
if (!isInFrameTimeLock)
|
||||
{
|
||||
const int MAX_FRAMES_PER_STEP = 4;
|
||||
|
||||
frameTimeStep = timeFrame / numFrames;
|
||||
if (frameTimeStep > m_FrameTimeSliceSize * MAX_FRAMES_PER_STEP)
|
||||
frameTimeStep = m_FrameTimeSliceSize * MAX_FRAMES_PER_STEP;
|
||||
}
|
||||
|
||||
m_FrameTimeAccumulated += frameTimeStep;
|
||||
while (m_FrameTimeAccumulated >= m_FrameTimeSliceSize)
|
||||
{
|
||||
m_Properties.m_TickFunc(m_Properties.m_TickFuncContext, m_vosFiber);
|
||||
m_FrameTimeAccumulated -= m_FrameTimeSliceSize;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Run()
|
||||
{
|
||||
HWND hWnd;
|
||||
WNDCLASSEX wc;
|
||||
|
||||
LPVOID fiber = ConvertThreadToFiberEx(this, 0);
|
||||
if (!fiber)
|
||||
return; // ???
|
||||
|
||||
m_vosFiber = new GpFiber_Win32(fiber);
|
||||
|
||||
ZeroMemory(&wc, sizeof(wc));
|
||||
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WinProc;
|
||||
wc.hInstance = g_gpWindowsGlobals.m_hInstance;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = "GPD3D11WindowClass";
|
||||
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
LONG windowStyle = WS_OVERLAPPEDWINDOW;
|
||||
HMENU menus = NULL;
|
||||
|
||||
// TODO: Fix the resolution here
|
||||
RECT wr = { 0, 0, m_windowWidth, m_windowHeight };
|
||||
AdjustWindowRect(&wr, windowStyle, menus != NULL);
|
||||
|
||||
hWnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
|
||||
|
||||
ShowWindow(hWnd, g_gpWindowsGlobals.m_nCmdShow);
|
||||
|
||||
StartD3DForWindow(hWnd, m_SwapChain);
|
||||
|
||||
LARGE_INTEGER lastTimestamp;
|
||||
memset(&lastTimestamp, 0, sizeof(lastTimestamp));
|
||||
|
||||
MSG msg;
|
||||
for (;;)
|
||||
{
|
||||
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
PresentFrameAndSync();
|
||||
}
|
||||
}
|
||||
|
||||
// Exit
|
||||
ConvertFiberToThread();
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Shutdown()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int &width, unsigned int &height)
|
||||
{
|
||||
width = m_windowWidth;
|
||||
height = m_windowHeight;
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties)
|
||||
{
|
||||
return new GpDisplayDriverD3D11(properties);
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties)
|
||||
: m_Properties(properties)
|
||||
, m_FrameTimeAccumulated(0)
|
||||
, m_windowWidth(640)
|
||||
, m_windowHeight(480)
|
||||
, m_vosFiber(nullptr)
|
||||
{
|
||||
memset(&m_SyncTimeBase, 0, sizeof(m_SyncTimeBase));
|
||||
|
||||
QueryPerformanceFrequency(&m_QPFrequency);
|
||||
|
||||
m_FrameTimeSliceSize = m_QPFrequency.QuadPart * static_cast<LONGLONG>(properties.m_FrameTimeLockNumerator) / static_cast<LONGLONG>(properties.m_FrameTimeLockDenominator);
|
||||
}
|
||||
#include "GpDisplayDriverD3D11.h"
|
||||
#include "GpWindows.h"
|
||||
#include "GpFiber_Win32.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <dxgi1_2.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#pragma comment (lib, "d3d11.lib")
|
||||
|
||||
void DebugPrintf(const char *fmt, ...)
|
||||
{
|
||||
char buf[256];
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
vsnprintf_s(buf, 255, fmt, argp);
|
||||
OutputDebugString(buf);
|
||||
va_end(argp);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
{
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
void StartD3DForWindow(HWND hWnd, IDXGISwapChain1*& swapChain)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
|
||||
|
||||
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
|
||||
|
||||
swapChainDesc.BufferCount = 2;
|
||||
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
|
||||
|
||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullscreenDesc;
|
||||
|
||||
ZeroMemory(&swapChainFullscreenDesc, sizeof(swapChainFullscreenDesc));
|
||||
|
||||
swapChainFullscreenDesc.Windowed = TRUE;
|
||||
swapChainFullscreenDesc.RefreshRate.Numerator = 60;
|
||||
swapChainFullscreenDesc.RefreshRate.Denominator = 1;
|
||||
|
||||
UINT flags = 0;
|
||||
const D3D_FEATURE_LEVEL featureLevels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_9_1
|
||||
};
|
||||
|
||||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
|
||||
ID3D11Device *device = NULL;
|
||||
ID3D11DeviceContext *context = NULL;
|
||||
|
||||
D3D_FEATURE_LEVEL selectedFeatureLevel;
|
||||
|
||||
HRESULT result = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevels, sizeof(featureLevels) / sizeof(featureLevels[0]),
|
||||
D3D11_SDK_VERSION, &device, &selectedFeatureLevel, &context);
|
||||
|
||||
IDXGIDevice2 *dxgiDevice = nullptr;
|
||||
result = device->QueryInterface(__uuidof(IDXGIDevice2), reinterpret_cast<void**>(&dxgiDevice));
|
||||
|
||||
IDXGIAdapter *dxgiAdapter = nullptr;
|
||||
result = dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||
|
||||
IDXGIFactory2 *dxgiFactory = nullptr;
|
||||
result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory));
|
||||
|
||||
result = dxgiFactory->CreateSwapChainForHwnd(device, hWnd, &swapChainDesc, nullptr, nullptr, &swapChain);
|
||||
}
|
||||
|
||||
bool GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
{
|
||||
DXGI_PRESENT_PARAMETERS presentParams;
|
||||
|
||||
ZeroMemory(&presentParams, sizeof(presentParams));
|
||||
|
||||
UINT lastPresentCount = 0;
|
||||
|
||||
if (FAILED(m_swapChain->GetLastPresentCount(&lastPresentCount)))
|
||||
return false;
|
||||
|
||||
if (FAILED(m_swapChain->Present1(1, 0, &presentParams)))
|
||||
return false;
|
||||
|
||||
//DebugPrintf("r: %i\n", static_cast<int>(r));
|
||||
|
||||
DXGI_FRAME_STATISTICS stats;
|
||||
if (FAILED(m_swapChain->GetFrameStatistics(&stats)))
|
||||
return false;
|
||||
|
||||
if (stats.SyncQPCTime.QuadPart != 0)
|
||||
{
|
||||
if (m_syncTimeBase.QuadPart == 0)
|
||||
m_syncTimeBase = stats.SyncQPCTime;
|
||||
|
||||
LARGE_INTEGER timestamp;
|
||||
timestamp.QuadPart = stats.SyncQPCTime.QuadPart - m_syncTimeBase.QuadPart;
|
||||
|
||||
bool compacted = false;
|
||||
if (m_presentHistory.Size() > 0)
|
||||
{
|
||||
CompactedPresentHistoryItem &lastItem = m_presentHistory[m_presentHistory.Size() - 1];
|
||||
LONGLONG timeDelta = timestamp.QuadPart - lastItem.m_timestamp.QuadPart;
|
||||
|
||||
if (timeDelta < 0)
|
||||
timeDelta = 0; // This should never happen
|
||||
|
||||
if (timeDelta * static_cast<LONGLONG>(m_properties.m_frameTimeLockDenominator) < m_QPFrequency.QuadPart * static_cast<LONGLONG>(m_properties.m_frameTimeLockNumerator))
|
||||
{
|
||||
lastItem.m_numFrames++;
|
||||
compacted = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!compacted)
|
||||
{
|
||||
if (m_presentHistory.Size() == m_presentHistory.CAPACITY)
|
||||
m_presentHistory.RemoveFromStart();
|
||||
|
||||
CompactedPresentHistoryItem *newItem = m_presentHistory.Append();
|
||||
newItem->m_timestamp = timestamp;
|
||||
newItem->m_numFrames = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_presentHistory.Size() >= 2)
|
||||
{
|
||||
const size_t presentHistorySizeMinusOne = m_presentHistory.Size() - 1;
|
||||
unsigned int numFrames = 0;
|
||||
for (size_t i = 0; i < presentHistorySizeMinusOne; i++)
|
||||
numFrames += m_presentHistory[i].m_numFrames;
|
||||
|
||||
LONGLONG timeFrame = m_presentHistory[presentHistorySizeMinusOne].m_timestamp.QuadPart - m_presentHistory[0].m_timestamp.QuadPart;
|
||||
|
||||
unsigned int cancelledFrames = 0;
|
||||
LONGLONG cancelledTime = 0;
|
||||
|
||||
const int overshootTolerance = 2;
|
||||
|
||||
for (size_t i = 0; i < presentHistorySizeMinusOne; i++)
|
||||
{
|
||||
LONGLONG blockTimeframe = m_presentHistory[i + 1].m_timestamp.QuadPart - m_presentHistory[i].m_timestamp.QuadPart;
|
||||
unsigned int blockNumFrames = m_presentHistory[i].m_numFrames;
|
||||
|
||||
if (blockTimeframe * static_cast<LONGLONG>(numFrames) >= timeFrame * static_cast<LONGLONG>(blockNumFrames) * overshootTolerance)
|
||||
{
|
||||
cancelledTime += blockTimeframe;
|
||||
cancelledFrames += blockNumFrames;
|
||||
}
|
||||
}
|
||||
|
||||
numFrames -= cancelledFrames;
|
||||
timeFrame -= cancelledTime;
|
||||
|
||||
// timeFrame / numFrames = Frame timestep
|
||||
// Unless Frame timestep is within the frame lock range, a.k.a.
|
||||
// timeFrame / numFrames / qpFreq >= minFrameTimeNum / minFrameTimeDenom
|
||||
|
||||
bool isInFrameTimeLock = false;
|
||||
if (timeFrame * static_cast<LONGLONG>(m_properties.m_frameTimeLockMinDenominator) >= static_cast<LONGLONG>(numFrames) * static_cast<LONGLONG>(m_properties.m_frameTimeLockMinNumerator) * m_QPFrequency.QuadPart
|
||||
&& timeFrame * static_cast<LONGLONG>(m_properties.m_frameTimeLockMaxDenominator) <= static_cast<LONGLONG>(numFrames) * static_cast<LONGLONG>(m_properties.m_frameTimeLockMaxNumerator) * m_QPFrequency.QuadPart)
|
||||
{
|
||||
isInFrameTimeLock = true;
|
||||
}
|
||||
|
||||
LONGLONG frameTimeStep = m_frameTimeSliceSize;
|
||||
if (!isInFrameTimeLock)
|
||||
{
|
||||
const int MAX_FRAMES_PER_STEP = 4;
|
||||
|
||||
frameTimeStep = timeFrame / numFrames;
|
||||
if (frameTimeStep > m_frameTimeSliceSize * MAX_FRAMES_PER_STEP)
|
||||
frameTimeStep = m_frameTimeSliceSize * MAX_FRAMES_PER_STEP;
|
||||
}
|
||||
|
||||
m_frameTimeAccumulated += frameTimeStep;
|
||||
while (m_frameTimeAccumulated >= m_frameTimeSliceSize)
|
||||
{
|
||||
m_properties.m_tickFunc(m_properties.m_tickFuncContext, m_vosFiber);
|
||||
m_frameTimeAccumulated -= m_frameTimeSliceSize;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Run()
|
||||
{
|
||||
HWND hWnd;
|
||||
WNDCLASSEX wc;
|
||||
|
||||
LPVOID fiber = ConvertThreadToFiberEx(this, 0);
|
||||
if (!fiber)
|
||||
return; // ???
|
||||
|
||||
m_vosFiber = new GpFiber_Win32(fiber);
|
||||
|
||||
ZeroMemory(&wc, sizeof(wc));
|
||||
|
||||
wc.cbSize = sizeof(WNDCLASSEX);
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WinProc;
|
||||
wc.hInstance = g_gpWindowsGlobals.m_hInstance;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = "GPD3D11WindowClass";
|
||||
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
LONG windowStyle = WS_OVERLAPPEDWINDOW;
|
||||
HMENU menus = NULL;
|
||||
|
||||
// TODO: Fix the resolution here
|
||||
RECT wr = { 0, 0, m_windowWidth, m_windowHeight };
|
||||
AdjustWindowRect(&wr, windowStyle, menus != NULL);
|
||||
|
||||
hWnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
|
||||
|
||||
ShowWindow(hWnd, g_gpWindowsGlobals.m_nCmdShow);
|
||||
|
||||
StartD3DForWindow(hWnd, m_swapChain);
|
||||
|
||||
LARGE_INTEGER lastTimestamp;
|
||||
memset(&lastTimestamp, 0, sizeof(lastTimestamp));
|
||||
|
||||
MSG msg;
|
||||
for (;;)
|
||||
{
|
||||
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
|
||||
DispatchMessage(&msg);
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
PresentFrameAndSync();
|
||||
}
|
||||
}
|
||||
|
||||
// Exit
|
||||
ConvertFiberToThread();
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Shutdown()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *pixelFormat)
|
||||
{
|
||||
if (width)
|
||||
*width = m_windowWidth;
|
||||
if (height)
|
||||
*height = m_windowHeight;
|
||||
if (pixelFormat)
|
||||
*pixelFormat = PortabilityLayer::PixelFormat_8BitStandard;
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties)
|
||||
{
|
||||
return new GpDisplayDriverD3D11(properties);
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties)
|
||||
: m_properties(properties)
|
||||
, m_frameTimeAccumulated(0)
|
||||
, m_windowWidth(640)
|
||||
, m_windowHeight(480)
|
||||
, m_vosFiber(nullptr)
|
||||
{
|
||||
memset(&m_syncTimeBase, 0, sizeof(m_syncTimeBase));
|
||||
|
||||
QueryPerformanceFrequency(&m_QPFrequency);
|
||||
|
||||
m_frameTimeSliceSize = m_QPFrequency.QuadPart * static_cast<LONGLONG>(properties.m_frameTimeLockNumerator) / static_cast<LONGLONG>(properties.m_frameTimeLockDenominator);
|
||||
}
|
||||
|
Reference in New Issue
Block a user