Lots of stuff

This commit is contained in:
elasota
2019-11-11 00:11:59 -05:00
parent 49a35bb15b
commit c8472f7295
406 changed files with 58313 additions and 88 deletions

View File

@@ -0,0 +1,8 @@
#pragma once
enum EGpDisplayDriverType
{
EGpDisplayDriverType_D3D11,
EGpDisplayDriverType_Count,
};

130
GpD3D/GpAppEnvironment.cpp Normal file
View File

@@ -0,0 +1,130 @@
#include "GpAppEnvironment.h"
#include "GpFiberStarter.h"
#include "GpAppInterface.h"
#include "GpPLGlueDisplayDriver.h"
#include "GpFiber.h"
#include "HostSuspendCallArgument.h"
#include <assert.h>
GpAppEnvironment::GpAppEnvironment()
: m_applicationState(ApplicationState_NotStarted)
, m_displayDriver(nullptr)
, m_applicationFiber(nullptr)
, m_vosFiber(nullptr)
, m_suspendCallID(PortabilityLayer::HostSuspendCallID_Unknown)
, m_suspendArgs(nullptr)
, m_suspendReturnValue(nullptr)
{
}
GpAppEnvironment::~GpAppEnvironment()
{
assert(m_applicationFiber == nullptr);
}
void GpAppEnvironment::Init()
{
}
void GpAppEnvironment::Tick(GpFiber *vosFiber)
{
GpAppInterface_Get()->PL_IncrementTickCounter(1);
m_vosFiber = vosFiber;
if (m_applicationState == ApplicationState_WaitingForEvents)
m_applicationState = ApplicationState_Running;
for (;;)
{
switch (m_applicationState)
{
case ApplicationState_NotStarted:
InitializeApplicationState();
m_applicationFiber = GpFiberStarter::StartFiber(GpAppEnvironment::StaticAppThreadFunc, this, vosFiber);
m_applicationState = ApplicationState_Running;
break;
case ApplicationState_WaitingForEvents:
return;
case ApplicationState_Running:
m_applicationFiber->YieldTo();
break;
case ApplicationState_SystemCall:
{
PortabilityLayer::HostSuspendCallID callID = m_suspendCallID;
const PortabilityLayer::HostSuspendCallArgument *args = m_suspendArgs;
PortabilityLayer::HostSuspendCallArgument *returnValue = m_suspendReturnValue;
DispatchSystemCall(callID, args, returnValue);
assert(m_applicationState != ApplicationState_SystemCall);
}
break;
case ApplicationState_TimedSuspend:
if (m_delaySuspendTicks <= 1)
m_applicationState = ApplicationState_Running;
else
{
m_delaySuspendTicks--;
return;
}
break;
default:
assert(false);
break;
};
}
}
void GpAppEnvironment::SetDisplayDriver(IGpDisplayDriver *displayDriver)
{
m_displayDriver = displayDriver;
}
void GpAppEnvironment::StaticAppThreadFunc(void *context)
{
static_cast<GpAppEnvironment*>(context)->AppThreadFunc();
}
void GpAppEnvironment::AppThreadFunc()
{
GpAppInterface_Get()->ApplicationMain();
}
void GpAppEnvironment::InitializeApplicationState()
{
GpAppInterface_Get()->PL_HostDisplayDriver_SetInstance(GpPLGlueDisplayDriver::GetInstance());
GpAppInterface_Get()->PL_InstallHostSuspendHook(GpAppEnvironment::StaticSuspendHookFunc, this);
SynchronizeState();
}
void GpAppEnvironment::SynchronizeState()
{
GpPLGlueDisplayDriver::GetInstance()->SetGpDisplayDriver(m_displayDriver);
}
void GpAppEnvironment::StaticSuspendHookFunc(void *context, PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
{
GpAppEnvironment *appEnv = static_cast<GpAppEnvironment*>(context);
appEnv->m_suspendCallID = callID;
appEnv->m_suspendArgs = args;
appEnv->m_suspendReturnValue = returnValue;
appEnv->m_applicationState = ApplicationState_SystemCall;
appEnv->m_vosFiber->YieldTo();
}
void GpAppEnvironment::DispatchSystemCall(PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue)
{
switch (callID)
{
case PortabilityLayer::HostSuspendCallID_Delay:
m_applicationState = ApplicationState_TimedSuspend;
m_delaySuspendTicks = args[0].m_uint;
break;
default:
assert(false);
}
}

55
GpD3D/GpAppEnvironment.h Normal file
View File

@@ -0,0 +1,55 @@
#pragma once
#include "HostSuspendCallID.h"
#include <stdint.h>
namespace PortabilityLayer
{
union HostSuspendCallArgument;
}
class IGpDisplayDriver;
class GpFiber;
class GpAppEnvironment
{
public:
GpAppEnvironment();
~GpAppEnvironment();
void Init();
void Tick(GpFiber *vosFiber);
void SetDisplayDriver(IGpDisplayDriver *displayDriver);
private:
enum ApplicationState
{
ApplicationState_NotStarted,
ApplicationState_WaitingForEvents,
ApplicationState_Running,
ApplicationState_Terminated,
ApplicationState_SystemCall,
ApplicationState_TimedSuspend,
};
static void StaticAppThreadFunc(void *context);
void AppThreadFunc();
void InitializeApplicationState();
void SynchronizeState();
static void StaticSuspendHookFunc(void *context, PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue);
void DispatchSystemCall(PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue);
ApplicationState m_applicationState;
IGpDisplayDriver *m_displayDriver;
GpFiber *m_applicationFiber;
GpFiber *m_vosFiber;
uint32_t m_delaySuspendTicks;
PortabilityLayer::HostSuspendCallID m_suspendCallID;
const PortabilityLayer::HostSuspendCallArgument *m_suspendArgs;
PortabilityLayer::HostSuspendCallArgument *m_suspendReturnValue;
};

25
GpD3D/GpCoreDefs.h Normal file
View File

@@ -0,0 +1,25 @@
#pragma once
#if __cplusplus >= 199711L
#define GP_IS_CPP11 1
#else
#define GP_IS_CPP11 0
#endif
#if GP_IS_CPP11
#define GP_DELETED = delete
#else
#ifndef nullptr
#define nullptr 0
#endif
#ifndef override
#define override
#endif
#ifndef final
#define final
#endif
#define GP_DELETED
#endif

177
GpD3D/GpD3D.vcxproj Normal file
View File

@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}</ProjectGuid>
<RootNamespace>GpD3D</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\PortabilityLayer.props" />
<Import Project="..\Common.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\PortabilityLayer.props" />
<Import Project="..\Common.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\PortabilityLayer.props" />
<Import Project="..\Common.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\PortabilityLayer.props" />
<Import Project="..\Common.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="GpAppEnvironment.cpp" />
<ClCompile Include="GpDisplayDriverFactory.cpp" />
<ClCompile Include="GpDisplayDriverFactoryD3D11.cpp" />
<ClCompile Include="GpEvent_Win32.cpp" />
<ClCompile Include="GpFiber_Win32.cpp" />
<ClCompile Include="GpFileStream_Win32.cpp" />
<ClCompile Include="GpFileSystem_Win32.cpp" />
<ClCompile Include="GpGlobalConfig.cpp" />
<ClCompile Include="GpMain.cpp" />
<ClCompile Include="GpMain_Win32.cpp" />
<ClCompile Include="GpDisplayDriverD3D11.cpp" />
<ClCompile Include="GpMemoryBuffer.cpp" />
<ClCompile Include="GpPLGlueDisplayDriver.cpp" />
<ClCompile Include="GpSystemServices_Win32.cpp" />
<ClCompile Include="GpFiberStarter_Win32.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="EGpDisplayDriverType.h" />
<ClInclude Include="GpAppEnvironment.h" />
<ClInclude Include="GpCoreDefs.h" />
<ClInclude Include="GpDisplayDriverD3D11.h" />
<ClInclude Include="GpDisplayDriverFactory.h" />
<ClInclude Include="GpDisplayDriverFactoryD3D11.h" />
<ClInclude Include="GpDisplayDriverProperties.h" />
<ClInclude Include="GpEvent.h" />
<ClInclude Include="GpFiber.h" />
<ClInclude Include="GpFiber_Win32.h" />
<ClInclude Include="GpFileStream_Win32.h" />
<ClInclude Include="GpFileSystem_Win32.h" />
<ClInclude Include="GpGlobalConfig.h" />
<ClInclude Include="GpMain.h" />
<ClInclude Include="GpMemoryBuffer.h" />
<ClInclude Include="GpPLGlueDisplayDriver.h" />
<ClInclude Include="GpRingBuffer.h" />
<ClInclude Include="GpSystemServices_Win32.h" />
<ClInclude Include="GpFiberStarter.h" />
<ClInclude Include="GpWindows.h" />
<ClInclude Include="IGpDisplayDriver.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GpApp\GpApp.vcxproj">
<Project>{6233c3f2-5781-488e-b190-4fa8836f5a77}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

129
GpD3D/GpD3D.vcxproj.filters Normal file
View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="GpMain_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpMain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpDisplayDriverD3D11.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpDisplayDriverFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpGlobalConfig.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpDisplayDriverFactoryD3D11.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpAppEnvironment.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpEvent_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpFileSystem_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpMemoryBuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpPLGlueDisplayDriver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpFileStream_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpSystemServices_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpFiberStarter_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GpFiber_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="GpWindows.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpDisplayDriverFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IGpDisplayDriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpMain.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EGpDisplayDriverType.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpDisplayDriverProperties.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpDisplayDriverD3D11.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpGlobalConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpAppEnvironment.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpCoreDefs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpDisplayDriverFactoryD3D11.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpRingBuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpEvent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpFileSystem_Win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpMemoryBuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpPLGlueDisplayDriver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpFileStream_Win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpSystemServices_Win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpFiberStarter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpFiber_Win32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GpFiber.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,290 @@
#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);
}

View File

@@ -0,0 +1,50 @@
#pragma once
#include "GpWindows.h"
#include "GpRingBuffer.h"
#include "IGpDisplayDriver.h"
#include "GpCoreDefs.h"
#include "GpDisplayDriverProperties.h"
struct IDXGISwapChain1;
class GpDisplayDriverD3D11 : public IGpDisplayDriver
{
public:
void Run() override;
void Shutdown() override;
void GetDisplayResolution(unsigned int &width, unsigned int &height) override;
static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties);
private:
GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties);
bool PresentFrameAndSync();
IDXGISwapChain1 *m_SwapChain;
struct CompactedPresentHistoryItem
{
LARGE_INTEGER m_Timestamp;
unsigned int m_NumFrames;
};
GpRingBuffer<CompactedPresentHistoryItem, 60> m_PresentHistory;
GpDisplayDriverProperties m_Properties;
LARGE_INTEGER m_SyncTimeBase;
LARGE_INTEGER m_QPFrequency;
UINT m_ExpectedSyncDelta;
bool m_IsResettingSwapChain;
LONGLONG m_FrameTimeAccumulated;
LONGLONG m_FrameTimeSliceSize;
DWORD m_windowWidth;
DWORD m_windowHeight;
GpFiber *m_vosFiber;
};

View File

@@ -0,0 +1,23 @@
#include "GpDisplayDriverFactory.h"
#include "GpDisplayDriverProperties.h"
#include <assert.h>
IGpDisplayDriver *GpDisplayDriverFactory::CreateDisplayDriver(const GpDisplayDriverProperties &properties)
{
assert(properties.m_Type < EGpDisplayDriverType_Count);
if (ms_Registry[properties.m_Type])
return ms_Registry[properties.m_Type](properties);
else
return nullptr;
}
void GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType type, FactoryFunc_t func)
{
assert(type < EGpDisplayDriverType_Count);
ms_Registry[type] = func;
}
GpDisplayDriverFactory::FactoryFunc_t GpDisplayDriverFactory::ms_Registry[EGpDisplayDriverType_Count];

View File

@@ -0,0 +1,18 @@
#pragma once
#include "EGpDisplayDriverType.h"
class IGpDisplayDriver;
struct GpDisplayDriverProperties;
class GpDisplayDriverFactory
{
public:
typedef IGpDisplayDriver *(*FactoryFunc_t)(const GpDisplayDriverProperties &properties);
static IGpDisplayDriver *CreateDisplayDriver(const GpDisplayDriverProperties &properties);
static void RegisterDisplayDriverFactory(EGpDisplayDriverType type, FactoryFunc_t func);
private:
static FactoryFunc_t ms_Registry[EGpDisplayDriverType_Count];
};

View File

@@ -0,0 +1,7 @@
#include "GpDisplayDriverFactoryD3D11.h"
#include "GpDisplayDriverD3D11.h"
IGpDisplayDriver *GpDisplayDriverFactoryD3D11::Create(const GpDisplayDriverProperties &properties)
{
return GpDisplayDriverD3D11::Create(properties);
}

View File

@@ -0,0 +1,10 @@
#pragma once
class IGpDisplayDriver;
struct GpDisplayDriverProperties;
class GpDisplayDriverFactoryD3D11
{
public:
static IGpDisplayDriver *Create(const GpDisplayDriverProperties &properties);
};

View File

@@ -0,0 +1,26 @@
#pragma once
#include "EGpDisplayDriverType.h"
class IGpDisplayDriver;
class GpFiber;
struct GpDisplayDriverProperties
{
typedef void(*TickFunc_t)(void *context, GpFiber *vosFiber);
EGpDisplayDriverType m_Type;
unsigned int m_FrameTimeLockNumerator;
unsigned int m_FrameTimeLockDenominator;
unsigned int m_FrameTimeLockMinNumerator;
unsigned int m_FrameTimeLockMinDenominator;
unsigned int m_FrameTimeLockMaxNumerator;
unsigned int m_FrameTimeLockMaxDenominator;
// Tick function and context to call when a frame needs to be served.
TickFunc_t m_TickFunc;
void *m_TickFuncContext;
};

21
GpD3D/GpEvent.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include "GpCoreDefs.h"
class GpEvent final
{
public:
void Wait();
void WaitMSec(unsigned int msec);
void Signal();
void Reset();
void Destroy();
static GpEvent *Create(bool autoReset, bool startSignalled);
private:
explicit GpEvent(void *privateData);
~GpEvent();
void *m_PrivateData;
};

49
GpD3D/GpEvent_Win32.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include "GpEvent.h"
#include "GpWindows.h"
#include <assert.h>
GpEvent::~GpEvent()
{
CloseHandle(static_cast<HANDLE>(m_PrivateData));
}
void GpEvent::Wait()
{
WaitForSingleObject(static_cast<HANDLE>(m_PrivateData), INFINITE);
}
void GpEvent::WaitMSec(unsigned int msec)
{
assert(msec < MAXDWORD);
WaitForSingleObject(static_cast<HANDLE>(m_PrivateData), static_cast<DWORD>(msec));
}
void GpEvent::Signal()
{
SetEvent(static_cast<HANDLE>(m_PrivateData));
}
void GpEvent::Reset()
{
ResetEvent(static_cast<HANDLE>(m_PrivateData));
}
void GpEvent::Destroy()
{
delete this;
}
GpEvent *GpEvent::Create(bool autoReset, bool startSignalled)
{
HANDLE handle = CreateEventA(nullptr, autoReset ? FALSE : TRUE, startSignalled ? TRUE : FALSE, nullptr);
if (!handle)
return nullptr;
return new GpEvent(handle);
}
GpEvent::GpEvent(void *privateData)
: m_PrivateData(privateData)
{
}

10
GpD3D/GpFiber.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "CoreDefs.h"
class GpFiber
{
public:
virtual void YieldTo() = 0;
virtual void Destroy() = 0;
};

11
GpD3D/GpFiberStarter.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
class GpFiber;
class GpFiberStarter
{
public:
typedef void(*ThreadFunc_t)(void *context);
static GpFiber *StartFiber(ThreadFunc_t threadFunc, void *context, GpFiber *creatingFiber);
};

View File

@@ -0,0 +1,52 @@
#include "GpFiberStarter.h"
#include "GpFiber_Win32.h"
#include "GpWindows.h"
#include <assert.h>
namespace GpFiberStarter_Win32
{
struct FiberStartState
{
GpFiberStarter::ThreadFunc_t m_threadFunc;
GpFiber *m_creatingFiber;
void *m_context;
};
static VOID WINAPI FiberStartRoutine(LPVOID lpThreadParameter)
{
const FiberStartState *tss = static_cast<const FiberStartState*>(lpThreadParameter);
GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc;
GpFiber *creatingFiber = tss->m_creatingFiber;
void *context = tss->m_context;
creatingFiber->YieldTo();
threadFunc(context);
assert(!"Fiber function exited");
}
}
GpFiber *GpFiberStarter::StartFiber(ThreadFunc_t threadFunc, void *context, GpFiber *creatingFiber)
{
ULONG_PTR lowLimit;
ULONG_PTR highLimit;
GetCurrentThreadStackLimits(&lowLimit, &highLimit);
ULONG_PTR stackSize = highLimit - lowLimit;
GpFiberStarter_Win32::FiberStartState startState;
startState.m_context = context;
startState.m_creatingFiber = creatingFiber;
startState.m_threadFunc = threadFunc;
void *fiber = CreateFiber(static_cast<SIZE_T>(stackSize), GpFiberStarter_Win32::FiberStartRoutine, &startState);
if (!fiber)
return nullptr;
SwitchToFiber(fiber);
return new GpFiber_Win32(fiber);
}

17
GpD3D/GpFiber_Win32.cpp Normal file
View File

@@ -0,0 +1,17 @@
#include "GpFiber_Win32.h"
GpFiber_Win32::GpFiber_Win32(LPVOID fiber)
: m_fiber(fiber)
{
}
void GpFiber_Win32::YieldTo()
{
SwitchToFiber(m_fiber);
}
void GpFiber_Win32::Destroy()
{
DeleteFiber(m_fiber);
delete this;
}

15
GpD3D/GpFiber_Win32.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include "GpWindows.h"
#include "GpFiber.h"
class GpFiber_Win32 final : public GpFiber
{
public:
explicit GpFiber_Win32(LPVOID fiber);
void YieldTo() override;
void Destroy() override;
private:
LPVOID m_fiber;
};

View File

@@ -0,0 +1,141 @@
#include "GpFileStream_Win32.h"
GpFileStream_Win32::GpFileStream_Win32(HANDLE handle, bool readable, bool writeable, bool seekable)
: m_handle(handle)
, m_readable(readable)
, m_writeable(writeable)
, m_seekable(seekable)
{
}
size_t GpFileStream_Win32::Read(void *bytesOut, size_t size)
{
if (!m_readable)
return 0;
size_t totalRead = 0;
while (size)
{
const DWORD chunkSizeToRead = (size > MAXDWORD) ? MAXDWORD : size;
DWORD numRead = 0;
BOOL readSucceeded = ReadFile(m_handle, bytesOut, chunkSizeToRead, &numRead, nullptr);
if (!readSucceeded)
return totalRead;
totalRead += static_cast<size_t>(numRead);
size -= static_cast<size_t>(numRead);
bytesOut = static_cast<void*>(static_cast<uint8_t*>(bytesOut) + numRead);
if (numRead != chunkSizeToRead)
return totalRead;
}
return totalRead;
}
size_t GpFileStream_Win32::Write(const void *bytes, size_t size)
{
if (!m_writeable)
return 0;
size_t totalWritten = 0;
while (size)
{
const DWORD chunkSizeToWrite = (size > MAXDWORD) ? MAXDWORD : size;
DWORD numWritten = 0;
BOOL writeSucceeded = WriteFile(m_handle, bytes, chunkSizeToWrite, &numWritten, nullptr);
if (!writeSucceeded)
return totalWritten;
totalWritten += static_cast<size_t>(numWritten);
size -= static_cast<size_t>(numWritten);
bytes = static_cast<const void*>(static_cast<const uint8_t*>(bytes) + numWritten);
if (numWritten != chunkSizeToWrite)
return totalWritten;
}
return totalWritten;
}
bool GpFileStream_Win32::IsSeekable() const
{
return m_seekable;
}
bool GpFileStream_Win32::IsReadOnly() const
{
return !m_writeable;
}
bool GpFileStream_Win32::IsWriteOnly() const
{
return !m_readable;
}
bool GpFileStream_Win32::SeekStart(PortabilityLayer::UFilePos_t loc)
{
LARGE_INTEGER li;
li.QuadPart = static_cast<LONGLONG>(loc);
return SetFilePointerEx(m_handle, li, nullptr, FILE_BEGIN) != 0;
}
bool GpFileStream_Win32::SeekCurrent(PortabilityLayer::FilePos_t loc)
{
LARGE_INTEGER li;
li.QuadPart = static_cast<LONGLONG>(loc);
return SetFilePointerEx(m_handle, li, nullptr, FILE_CURRENT) != 0;
}
bool GpFileStream_Win32::SeekEnd(PortabilityLayer::UFilePos_t loc)
{
LARGE_INTEGER li;
li.QuadPart = static_cast<LONGLONG>(loc);
return SetFilePointerEx(m_handle, li, nullptr, FILE_END) != 0;
}
bool GpFileStream_Win32::Truncate(PortabilityLayer::UFilePos_t loc)
{
if (!m_writeable)
return false;
PortabilityLayer::UFilePos_t oldPos = Tell();
if (!SeekStart(loc))
return false;
if (!SetEndOfFile(m_handle))
return false;
if (!SeekStart(oldPos))
return false;
return true;
}
PortabilityLayer::UFilePos_t GpFileStream_Win32::Size() const
{
LARGE_INTEGER fsize;
if (!GetFileSizeEx(m_handle, &fsize))
return 0;
return static_cast<PortabilityLayer::UFilePos_t>(fsize.QuadPart);
}
PortabilityLayer::UFilePos_t GpFileStream_Win32::Tell() const
{
LARGE_INTEGER zero;
zero.QuadPart = 0;
LARGE_INTEGER fpos;
if (!SetFilePointerEx(m_handle, zero, &fpos, FILE_CURRENT))
return 0;
return static_cast<PortabilityLayer::UFilePos_t>(fpos.QuadPart);
}
void GpFileStream_Win32::Close()
{
CloseHandle(m_handle);
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include "GpCoreDefs.h"
#include "GpWindows.h"
#include "IOStream.h"
class GpFileStream_Win32 final : public PortabilityLayer::IOStream
{
public:
explicit GpFileStream_Win32(HANDLE handle, bool readable, bool writeable, bool seekable);
size_t Read(void *bytesOut, size_t size) override;
size_t Write(const void *bytes, size_t size) override;
bool IsSeekable() const override;
bool IsReadOnly() const override;
bool IsWriteOnly() const override;
bool SeekStart(PortabilityLayer::UFilePos_t loc) override;
bool SeekCurrent(PortabilityLayer::FilePos_t loc) override;
bool SeekEnd(PortabilityLayer::UFilePos_t loc) override;
bool Truncate(PortabilityLayer::UFilePos_t loc) override;
PortabilityLayer::UFilePos_t Size() const override;
PortabilityLayer::UFilePos_t Tell() const override;
void Close() override;
private:
HANDLE m_handle;
bool m_readable;
bool m_writeable;
bool m_seekable;
};

View File

@@ -0,0 +1,96 @@
#include "GpFileSystem_Win32.h"
#include "GpFileStream_Win32.h"
#include "GpWindows.h"
#include "GpMemoryBuffer.h"
#include <string>
#include <Shlwapi.h>
#include <ShlObj.h>
GpFileSystem_Win32::GpFileSystem_Win32()
{
PWSTR docsPath;
if (!FAILED(SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT, nullptr, &docsPath)))
{
try
{
m_prefsDir = docsPath;
}
catch(...)
{
CoTaskMemFree(docsPath);
throw;
}
m_prefsDir.append(L"\\GlidePort");
CreateDirectoryW(m_prefsDir.c_str(), nullptr);
m_prefsDir.append(L"\\");
}
}
bool GpFileSystem_Win32::FileExists(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path)
{
wchar_t winPath[MAX_PATH + 1];
if (!ResolvePath(virtualDirectory, path, winPath))
return false;
return PathFileExistsW(winPath) != 0;
}
PortabilityLayer::IOStream *GpFileSystem_Win32::OpenFile(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create)
{
wchar_t winPath[MAX_PATH + 1];
if (!ResolvePath(virtualDirectory, path, winPath))
return false;
const DWORD desiredAccess = writeAccess ? (GENERIC_WRITE | GENERIC_READ) : GENERIC_READ;
const DWORD creationDisposition = create ? OPEN_ALWAYS : OPEN_EXISTING;
HANDLE h = CreateFileW(winPath, desiredAccess, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
return new GpFileStream_Win32(h, true, writeAccess, true);
}
GpFileSystem_Win32 *GpFileSystem_Win32::GetInstance()
{
return &ms_instance;
}
bool GpFileSystem_Win32::ResolvePath(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, wchar_t *outPath)
{
const wchar_t *baseDir = nullptr;
switch (virtualDirectory)
{
case PortabilityLayer::EVirtualDirectory_ApplicationData:
baseDir = L"D:\\Source Code\\GlidePort\\Packaged\\";
break;
case PortabilityLayer::EVirtualDirectory_Prefs:
baseDir = m_prefsDir.c_str();
break;
default:
return false;
}
if (baseDir == nullptr)
return false;
const size_t baseDirLen = wcslen(baseDir);
const size_t pathLen = strlen(path);
if (baseDirLen >= MAX_PATH || MAX_PATH - baseDirLen < pathLen)
return false;
memcpy(outPath, baseDir, sizeof(wchar_t) * baseDirLen);
for (size_t i = 0; i < pathLen; i++)
outPath[baseDirLen + i] = static_cast<wchar_t>(path[i]);
outPath[baseDirLen + pathLen] = static_cast<wchar_t>(0);
return true;
}
GpFileSystem_Win32 GpFileSystem_Win32::ms_instance;

View File

@@ -0,0 +1,25 @@
#pragma once
#include "HostFileSystem.h"
#include "GpCoreDefs.h"
#include <string>
class GpFileSystem_Win32 final : public PortabilityLayer::HostFileSystem
{
public:
GpFileSystem_Win32();
bool FileExists(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path) override;
PortabilityLayer::IOStream *OpenFile(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) override;
static GpFileSystem_Win32 *GetInstance();
private:
bool ResolvePath(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, wchar_t *outPath);
std::wstring m_prefsDir;
static GpFileSystem_Win32 ms_instance;
};

3
GpD3D/GpGlobalConfig.cpp Normal file
View File

@@ -0,0 +1,3 @@
#include "GpGlobalConfig.h"
GpGlobalConfig g_gpGlobalConfig;

10
GpD3D/GpGlobalConfig.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include "EGpDisplayDriverType.h"
struct GpGlobalConfig
{
EGpDisplayDriverType m_displayDriverType;
};
extern GpGlobalConfig g_gpGlobalConfig;

48
GpD3D/GpMain.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include "GpMain.h"
#include "GpDisplayDriverFactory.h"
#include "GpDisplayDriverProperties.h"
#include "GpGlobalConfig.h"
#include "GpAppEnvironment.h"
#include "IGpDisplayDriver.h"
#include <string.h>
namespace
{
void TickAppEnvironment(void *context, GpFiber *vosFiber)
{
static_cast<GpAppEnvironment*>(context)->Tick(vosFiber);
}
}
int GpMain::Run()
{
GpAppEnvironment *appEnvironment = new GpAppEnvironment();
GpDisplayDriverProperties ddProps;
memset(&ddProps, 0, sizeof(ddProps));
ddProps.m_FrameTimeLockNumerator = 1;
ddProps.m_FrameTimeLockDenominator = 60;
// +/- 1% tolerance for frame time variance
ddProps.m_FrameTimeLockMinNumerator = 99;
ddProps.m_FrameTimeLockMinDenominator = 6000;
ddProps.m_FrameTimeLockMaxNumerator = 101;
ddProps.m_FrameTimeLockMaxDenominator = 6000;
ddProps.m_TickFunc = TickAppEnvironment;
ddProps.m_TickFuncContext = appEnvironment;
ddProps.m_Type = g_gpGlobalConfig.m_displayDriverType;
IGpDisplayDriver *displayDriver = GpDisplayDriverFactory::CreateDisplayDriver(ddProps);
appEnvironment->Init();
appEnvironment->SetDisplayDriver(displayDriver);
// Start the display loop
displayDriver->Run();
return 0;
}

6
GpD3D/GpMain.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
namespace GpMain
{
int Run();
}

33
GpD3D/GpMain_Win32.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include "GpWindows.h"
#include "GpMain.h"
#include "GpDisplayDriverFactory.h"
#include "GpDisplayDriverFactoryD3D11.h"
#include "GpGlobalConfig.h"
#include "GpFileSystem_Win32.h"
#include "GpAppInterface.h"
#include "GpSystemServices_Win32.h"
#include "HostFileSystem.h"
#include <d3d11.h>
#include <stdio.h>
GPWindowsGlobals g_gpWindowsGlobals;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
GpAppInterface_Get()->PL_HostFileSystem_SetInstance(GpFileSystem_Win32::GetInstance());
GpAppInterface_Get()->PL_HostSystemServices_SetInstance(GpSystemServices_Win32::GetInstance());
g_gpWindowsGlobals.m_hInstance = hInstance;
g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance;
g_gpWindowsGlobals.m_cmdLine = lpCmdLine;
g_gpWindowsGlobals.m_nCmdShow = nCmdShow;
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11;
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDisplayDriverFactoryD3D11::Create);
return GpMain::Run();
}

49
GpD3D/GpMemoryBuffer.cpp Normal file
View File

@@ -0,0 +1,49 @@
#include "GpMemoryBuffer.h"
#include <new>
void *GpMemoryBuffer::Contents()
{
return reinterpret_cast<uint8_t*>(this) + AlignedSize();
}
size_t GpMemoryBuffer::Size()
{
return m_size;
}
void GpMemoryBuffer::Destroy()
{
delete[] reinterpret_cast<uint8_t*>(this);
}
GpMemoryBuffer *GpMemoryBuffer::Create(size_t sz)
{
const size_t allowedSize = SIZE_MAX - AlignedSize();
if (sz > allowedSize)
return nullptr;
const size_t bufferSize = GpMemoryBuffer::AlignedSize() + sz;
uint8_t *buffer = new uint8_t[bufferSize];
new (buffer) GpMemoryBuffer(sz);
return reinterpret_cast<GpMemoryBuffer*>(buffer);
}
GpMemoryBuffer::GpMemoryBuffer(size_t sz)
: m_size(sz)
{
}
GpMemoryBuffer::~GpMemoryBuffer()
{
}
size_t GpMemoryBuffer::AlignedSize()
{
const size_t paddedSize = (sizeof(GpMemoryBuffer) + PL_SYSTEM_MEMORY_ALIGNMENT - 1);
const size_t sz = paddedSize - paddedSize % PL_SYSTEM_MEMORY_ALIGNMENT;
return sz;
}

21
GpD3D/GpMemoryBuffer.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include "HostMemoryBuffer.h"
class GpMemoryBuffer final : public PortabilityLayer::HostMemoryBuffer
{
public:
void *Contents() override;
size_t Size() override;
void Destroy() override;
static GpMemoryBuffer *Create(size_t sz);
private:
explicit GpMemoryBuffer(size_t sz);
~GpMemoryBuffer();
static size_t AlignedSize();
size_t m_size;
};

View File

@@ -0,0 +1,28 @@
#include "GpPLGlueDisplayDriver.h"
#include "IGpDisplayDriver.h"
GpPLGlueDisplayDriver::GpPLGlueDisplayDriver()
: m_displayDriver(nullptr)
{
}
void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int &width, unsigned int &height)
{
m_displayDriver->GetDisplayResolution(width, height);
}
void GpPLGlueDisplayDriver::HideCursor()
{
}
GpPLGlueDisplayDriver *GpPLGlueDisplayDriver::GetInstance()
{
return &ms_instance;
}
void GpPLGlueDisplayDriver::SetGpDisplayDriver(IGpDisplayDriver *displayDriver)
{
m_displayDriver = displayDriver;
}
GpPLGlueDisplayDriver GpPLGlueDisplayDriver::ms_instance;

View File

@@ -0,0 +1,23 @@
#pragma once
#include "HostDisplayDriver.h"
class IGpDisplayDriver;
class GpPLGlueDisplayDriver final : public PortabilityLayer::HostDisplayDriver
{
public:
GpPLGlueDisplayDriver();
void GetDisplayResolution(unsigned int &width, unsigned int &height) override;
void HideCursor() override;
void SetGpDisplayDriver(IGpDisplayDriver *displayDriver);
static GpPLGlueDisplayDriver *GetInstance();
private:
IGpDisplayDriver *m_displayDriver;
static GpPLGlueDisplayDriver ms_instance;
};

63
GpD3D/GpRingBuffer.h Normal file
View File

@@ -0,0 +1,63 @@
#pragma once
#include <stdint.h>
#include <assert.h>
#include "GpCoreDefs.h"
template<class TItem, size_t TCapacity>
class GpRingBuffer
{
public:
GpRingBuffer()
: m_Size(0)
, m_Start(0)
{
}
TItem &operator[](size_t index)
{
assert(index < m_Size);
return m_Items[(m_Start + index) % TCapacity];
}
void RemoveFromStart()
{
assert(m_Size >= 1);
m_Start = (m_Start + 1) % TCapacity;
m_Size--;
}
void RemoveFromEnd()
{
assert(m_Size >= 1);
m_Size--;
}
void Clear()
{
m_Size = 0;
m_Start = 0;
}
size_t Size() const
{
return m_Size;
}
TItem *Append()
{
if (m_Size == TCapacity)
return nullptr;
m_Size++;
return &m_Items[(m_Start + (m_Size - 1)) % TCapacity];
}
static const size_t CAPACITY = TCapacity;
private:
TItem m_Items[TCapacity];
size_t m_Size;
size_t m_Start;
};

View File

@@ -0,0 +1,19 @@
#include "GpSystemServices_Win32.h"
#include <assert.h>
GpSystemServices_Win32::GpSystemServices_Win32()
{
}
uint32_t GpSystemServices_Win32::GetTime() const
{
return 0;
}
GpSystemServices_Win32 *GpSystemServices_Win32::GetInstance()
{
return &ms_instance;
}
GpSystemServices_Win32 GpSystemServices_Win32::ms_instance;

View File

@@ -0,0 +1,19 @@
#pragma once
#include "HostSystemServices.h"
#include "GpCoreDefs.h"
#include "GpWindows.h"
class GpSystemServices_Win32 final : public PortabilityLayer::HostSystemServices
{
public:
GpSystemServices_Win32();
uint32_t GetTime() const override;
static GpSystemServices_Win32 *GetInstance();
private:
static GpSystemServices_Win32 ms_instance;
};

16
GpD3D/GpWindows.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
struct GPWindowsGlobals
{
HINSTANCE m_hInstance;
HINSTANCE m_hPrevInstance;
LPSTR m_cmdLine;
int m_nCmdShow;
};
extern GPWindowsGlobals g_gpWindowsGlobals;

13
GpD3D/IGpDisplayDriver.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
// Display drivers are responsible for timing and calling the game tick function.
class IGpDisplayDriver
{
public:
virtual ~IGpDisplayDriver() {}
virtual void Run() = 0;
virtual void Shutdown() = 0;
virtual void GetDisplayResolution(unsigned int &width, unsigned int &height) = 0;
};

BIN
GpD3D/x64/Debug/vc141.idb Normal file

Binary file not shown.