1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Restore legacy double/triple buffered v-sync behavior

On recent drivers, double buffered DirectDraw flips no longer wait for the
vertical sync before returning and instead just insert the flip into the
flip queue for later execution. This effectively results in triple buffered
behavior (in the render-ahead sense) and causes up to an extra frame of
latency even if the flip queue size is set to 1.

To restore the legacy double buffered behavior, each flip waits for the
presented frame to leave the flip queue before returning.

To restore the legacy triple buffered behavior, the flip queue size is
forced to 1. This causes the flip to wait if the previous flip is still
pending.
This commit is contained in:
narzoul 2016-11-29 00:00:49 +01:00
parent 89f1556789
commit d898961a7e
14 changed files with 486 additions and 17 deletions

View File

@ -6,6 +6,7 @@
#include <d3dumddi.h>
#include "Common/CompatVtable.h"
#include "D3dDdi/Log/AdapterFuncsLog.h"
#include "D3dDdi/Visitors/AdapterFuncsVisitor.h"
namespace D3dDdi

View File

@ -11,6 +11,7 @@
#include "Common/Log.h"
#include "D3dDdi/AdapterCallbacks.h"
#include "D3dDdi/AdapterFuncs.h"
#include "D3dDdi/KernelModeThunks.h"
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_OPENADAPTER& data)
{
@ -33,21 +34,6 @@ namespace
HRESULT APIENTRY openAdapter(D3DDDIARG_OPENADAPTER* pOpenData);
void unhookOpenAdapter();
NTSTATUS APIENTRY d3dKmtQueryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* pData)
{
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTQueryAdapterInfo)(pData);
if (SUCCEEDED(result) && KMTQAITYPE_UMDRIVERNAME == pData->Type)
{
auto info = static_cast<D3DKMT_UMDFILENAMEINFO*>(pData->pPrivateDriverData);
if (g_hookedUmdFileName != info->UmdFileName)
{
unhookOpenAdapter();
hookOpenAdapter(info->UmdFileName);
}
}
return result;
}
void hookOpenAdapter(const std::wstring& umdFileName)
{
g_hookedUmdFileName = umdFileName;
@ -99,7 +85,16 @@ namespace D3dDdi
void installHooks()
{
HOOK_FUNCTION(gdi32, D3DKMTQueryAdapterInfo, d3dKmtQueryAdapterInfo);
KernelModeThunks::installHooks();
}
void onUmdFileNameQueried(const std::wstring& umdFileName)
{
if (g_hookedUmdFileName != umdFileName)
{
unhookOpenAdapter();
hookOpenAdapter(umdFileName);
}
}
void uninstallHooks()

View File

@ -1,8 +1,11 @@
#pragma once
#include <string>
namespace D3dDdi
{
UINT getDdiVersion();
void installHooks();
void onUmdFileNameQueried(const std::wstring& umdFileName);
void uninstallHooks();
}

View File

@ -0,0 +1,234 @@
#define CINTERFACE
#include <map>
#include <d3d.h>
#include <d3dumddi.h>
#include <../km/d3dkmthk.h>
#include "Common/Log.h"
#include "Common/Hook.h"
#include "D3dDdi/Hooks.h"
#include "D3dDdi/KernelModeThunks.h"
#include "DDraw/Surfaces/PrimarySurface.h"
namespace
{
struct ContextInfo
{
D3DKMT_HANDLE device;
ContextInfo() : device(0) {}
};
struct DeviceInfo
{
D3DKMT_HANDLE adapter;
D3DDDI_VIDEO_PRESENT_SOURCE_ID vidPnSourceId;
DeviceInfo() : adapter(0), vidPnSourceId(D3DDDI_ID_UNINITIALIZED) {}
};
std::map<D3DKMT_HANDLE, ContextInfo> g_contexts;
std::map<D3DKMT_HANDLE, DeviceInfo> g_devices;
NTSTATUS APIENTRY createDevice(D3DKMT_CREATEDEVICE* pData)
{
Compat::LogEnter("D3DKMTCreateDevice", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTCreateDevice)(pData);
if (SUCCEEDED(result))
{
g_devices[pData->hDevice].adapter = pData->hAdapter;
D3DKMT_SETQUEUEDLIMIT limit = {};
limit.hDevice = pData->hDevice;
limit.Type = D3DKMT_SET_QUEUEDLIMIT_PRESENT;
limit.QueuedPresentLimit = 1;
CALL_ORIG_FUNC(D3DKMTSetQueuedLimit)(&limit);
}
Compat::LogLeave("D3DKMTCreateDevice", pData) << result;
return result;
}
NTSTATUS APIENTRY createContext(D3DKMT_CREATECONTEXT* pData)
{
Compat::LogEnter("D3DKMTCreateContext", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTCreateContext)(pData);
if (SUCCEEDED(result))
{
g_contexts[pData->hContext].device = pData->hDevice;
}
Compat::LogLeave("D3DKMTCreateContext", pData) << result;
return result;
}
NTSTATUS APIENTRY createContextVirtual(D3DKMT_CREATECONTEXTVIRTUAL* pData)
{
Compat::LogEnter("D3DKMTCreateContextVirtual", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTCreateContextVirtual)(pData);
if (SUCCEEDED(result))
{
g_contexts[pData->hContext].device = pData->hDevice;
}
Compat::LogLeave("D3DKMTCreateContextVirtual", pData) << result;
return result;
}
NTSTATUS APIENTRY destroyContext(const D3DKMT_DESTROYCONTEXT* pData)
{
Compat::LogEnter("D3DKMTDestroyContext", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTDestroyContext)(pData);
if (SUCCEEDED(result))
{
g_contexts.erase(pData->hContext);
}
Compat::LogLeave("D3DKMTDestroyContext", pData) << result;
return result;
}
NTSTATUS APIENTRY destroyDevice(const D3DKMT_DESTROYDEVICE* pData)
{
Compat::LogEnter("D3DKMTDestroyDevice", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTDestroyDevice)(pData);
if (SUCCEEDED(result))
{
g_devices.erase(pData->hDevice);
}
Compat::LogLeave("D3DKMTDestroyDevice", pData) << result;
return result;
}
NTSTATUS APIENTRY present(D3DKMT_PRESENT* pData)
{
Compat::LogEnter("D3DKMTPresent", pData);
static UINT presentCount = 0;
++presentCount;
pData->Flags.PresentCountValid = 1;
pData->PresentCount = presentCount;
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTPresent)(pData);
if (SUCCEEDED(result) &&
1 == DDraw::PrimarySurface::getDesc().dwBackBufferCount &&
pData->Flags.Flip && pData->FlipInterval != D3DDDI_FLIPINTERVAL_IMMEDIATE)
{
auto contextIt = g_contexts.find(pData->hContext);
auto deviceIt = (contextIt != g_contexts.end())
? g_devices.find(contextIt->second.device)
: g_devices.find(pData->hDevice);
if (deviceIt != g_devices.end())
{
D3DKMT_WAITFORVERTICALBLANKEVENT vbEvent = {};
vbEvent.hAdapter = deviceIt->second.adapter;
vbEvent.hDevice = deviceIt->first;
vbEvent.VidPnSourceId = deviceIt->second.vidPnSourceId;
D3DKMT_GETDEVICESTATE deviceState = {};
deviceState.hDevice = deviceIt->first;
deviceState.StateType = D3DKMT_DEVICESTATE_PRESENT;
deviceState.PresentState.VidPnSourceId = deviceIt->second.vidPnSourceId;
NTSTATUS stateResult = D3DKMTGetDeviceState(&deviceState);
while (SUCCEEDED(stateResult) &&
presentCount != deviceState.PresentState.PresentStats.PresentCount)
{
if (FAILED(D3DKMTWaitForVerticalBlankEvent(&vbEvent)))
{
Sleep(1);
}
stateResult = D3DKMTGetDeviceState(&deviceState);
}
}
}
Compat::LogLeave("D3DKMTPresent", pData) << result;
return result;
}
NTSTATUS APIENTRY queryAdapterInfo(const D3DKMT_QUERYADAPTERINFO* pData)
{
Compat::LogEnter("D3DKMTQueryAdapterInfo", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTQueryAdapterInfo)(pData);
if (SUCCEEDED(result) && KMTQAITYPE_UMDRIVERNAME == pData->Type)
{
auto info = static_cast<D3DKMT_UMDFILENAMEINFO*>(pData->pPrivateDriverData);
D3dDdi::onUmdFileNameQueried(info->UmdFileName);
}
Compat::LogLeave("D3DKMTQueryAdapterInfo", pData) << result;
return result;
}
NTSTATUS APIENTRY setQueuedLimit(const D3DKMT_SETQUEUEDLIMIT* pData)
{
Compat::LogEnter("D3DKMTSetQueuedLimit", pData);
if (D3DKMT_SET_QUEUEDLIMIT_PRESENT == pData->Type)
{
const UINT origLimit = pData->QueuedPresentLimit;
const_cast<D3DKMT_SETQUEUEDLIMIT*>(pData)->QueuedPresentLimit = 1;
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTSetQueuedLimit)(pData);
const_cast<D3DKMT_SETQUEUEDLIMIT*>(pData)->QueuedPresentLimit = origLimit;
Compat::LogLeave("D3DKMTSetQueuedLimit", pData) << result;
return result;
}
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTSetQueuedLimit)(pData);
Compat::LogLeave("D3DKMTSetQueuedLimit", pData) << result;
return result;
}
void processSetVidPnSourceOwner(const D3DKMT_SETVIDPNSOURCEOWNER* pData)
{
auto& vidPnSourceId = g_devices[pData->hDevice].vidPnSourceId;
for (UINT i = 0; i < pData->VidPnSourceCount; ++i)
{
if (D3DKMT_VIDPNSOURCEOWNER_UNOWNED != pData->pType[i])
{
vidPnSourceId = pData->pVidPnSourceId[i];
return;
}
}
vidPnSourceId = D3DDDI_ID_UNINITIALIZED;
}
NTSTATUS APIENTRY setVidPnSourceOwner(const D3DKMT_SETVIDPNSOURCEOWNER* pData)
{
Compat::LogEnter("D3DKMTSetVidPnSourceOwner", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTSetVidPnSourceOwner)(pData);
if (SUCCEEDED(result))
{
processSetVidPnSourceOwner(pData);
}
Compat::LogLeave("D3DKMTSetVidPnSourceOwner", pData) << result;
return result;
}
NTSTATUS APIENTRY setVidPnSourceOwner1(const D3DKMT_SETVIDPNSOURCEOWNER1* pData)
{
Compat::LogEnter("D3DKMTSetVidPnSourceOwner1", pData);
NTSTATUS result = CALL_ORIG_FUNC(D3DKMTSetVidPnSourceOwner1)(pData);
if (SUCCEEDED(result))
{
processSetVidPnSourceOwner(&pData->Version0);
}
Compat::LogLeave("D3DKMTSetVidPnSourceOwner1", pData) << result;
return result;
}
}
namespace D3dDdi
{
namespace KernelModeThunks
{
void installHooks()
{
HOOK_FUNCTION(gdi32, D3DKMTCreateContext, createContext);
HOOK_FUNCTION(gdi32, D3DKMTCreateContextVirtual, createContextVirtual);
HOOK_FUNCTION(gdi32, D3DKMTCreateDevice, createDevice);
HOOK_FUNCTION(gdi32, D3DKMTDestroyContext, destroyContext);
HOOK_FUNCTION(gdi32, D3DKMTDestroyDevice, destroyDevice);
HOOK_FUNCTION(gdi32, D3DKMTQueryAdapterInfo, queryAdapterInfo);
HOOK_FUNCTION(gdi32, D3DKMTPresent, present);
HOOK_FUNCTION(gdi32, D3DKMTSetQueuedLimit, setQueuedLimit);
HOOK_FUNCTION(gdi32, D3DKMTSetVidPnSourceOwner, setVidPnSourceOwner);
HOOK_FUNCTION(gdi32, D3DKMTSetVidPnSourceOwner1, setVidPnSourceOwner1);
}
}
}

View File

@ -0,0 +1,11 @@
#pragma once
#include "D3dDdi/Log/KernelModeThunksLog.h"
namespace D3dDdi
{
namespace KernelModeThunks
{
void installHooks();
}
}

View File

@ -0,0 +1,38 @@
#include "Common/Log.h"
#include "D3dDdi/Log/AdapterFuncsLog.h"
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hAllocation)
<< Compat::hex(data.Value);
}
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data)
{
return Compat::LogStruct(os)
<< data.AllocationIndex
<< Compat::hex(data.Value)
<< Compat::hex(data.DriverId)
<< Compat::hex(data.AllocationOffset)
<< Compat::hex(data.PatchOffset)
<< Compat::hex(data.SplitOffset);
}
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEDEVICE& data)
{
return Compat::LogStruct(os)
<< data.hDevice
<< data.Interface
<< data.Version
<< data.pCallbacks
<< data.pCommandBuffer
<< data.CommandBufferSize
<< data.pAllocationList
<< data.AllocationListSize
<< data.pPatchLocationList
<< data.PatchLocationListSize
<< data.pDeviceFuncs
<< Compat::hex(data.Flags.Value)
<< Compat::hex(data.CommandBuffer);
}

View File

@ -0,0 +1,12 @@
#pragma once
#define CINTERFACE
#include <ostream>
#include <d3d.h>
#include <d3dumddi.h>
std::ostream& operator<<(std::ostream& os, const D3DDDI_ALLOCATIONLIST& data);
std::ostream& operator<<(std::ostream& os, const D3DDDI_PATCHLOCATIONLIST& data);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATEDEVICE& data);

View File

@ -76,6 +76,21 @@ std::ostream& operator<<(std::ostream& os, const D3DDDICB_LOCK2& data)
<< data.pData;
}
std::ostream& operator<<(std::ostream& os, const D3DDDICB_PRESENT& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hSrcAllocation)
<< Compat::hex(data.hDstAllocation)
<< data.hContext
<< data.BroadcastContextCount
<< Compat::array(data.BroadcastContext, data.BroadcastContextCount)
<< Compat::hex(data.BroadcastSrcAllocation)
<< Compat::hex(data.BroadcastDstAllocation)
<< data.PrivateDriverDataSize
<< data.pPrivateDriverData
<< static_cast<UINT>(data.bOptimizeForComposition);
}
std::ostream& operator<<(std::ostream& os, const D3DDDICB_UNLOCK& data)
{
return Compat::LogStruct(os)

View File

@ -14,5 +14,6 @@ std::ostream& operator<<(std::ostream& os, const D3DDDICB_DEALLOCATE& data);
std::ostream& operator<<(std::ostream& os, const D3DDDICB_DEALLOCATE2& data);
std::ostream& operator<<(std::ostream& os, const D3DDDICB_LOCK& data);
std::ostream& operator<<(std::ostream& os, const D3DDDICB_LOCK2& data);
std::ostream& operator<<(std::ostream& os, const D3DDDICB_PRESENT& data);
std::ostream& operator<<(std::ostream& os, const D3DDDICB_UNLOCK& data);
std::ostream& operator<<(std::ostream& os, const D3DDDICB_UNLOCK2& data);

View File

@ -0,0 +1,116 @@
#include "Common/Log.h"
#include "D3dDdi/Log/KernelModeThunksLog.h"
std::ostream& operator<<(std::ostream& os, const D3DKMT_CREATECONTEXT& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hDevice)
<< data.NodeOrdinal
<< data.EngineAffinity
<< Compat::hex(data.Flags.Value)
<< data.pPrivateDriverData
<< data.PrivateDriverDataSize
<< data.ClientHint
<< Compat::hex(data.hContext)
<< data.pCommandBuffer
<< data.CommandBufferSize
<< Compat::array(data.pAllocationList, data.AllocationListSize)
<< data.AllocationListSize
<< Compat::array(data.pPatchLocationList, data.PatchLocationListSize)
<< data.PatchLocationListSize
<< Compat::hex(data.CommandBuffer);
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_CREATECONTEXTVIRTUAL& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hDevice)
<< data.NodeOrdinal
<< data.EngineAffinity
<< Compat::hex(data.Flags.Value)
<< data.pPrivateDriverData
<< data.PrivateDriverDataSize
<< data.ClientHint
<< Compat::hex(data.hContext);
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_CREATEDEVICE& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hAdapter)
<< Compat::hex(*reinterpret_cast<const DWORD*>(&data.Flags))
<< Compat::hex(data.hDevice)
<< data.pCommandBuffer
<< data.CommandBufferSize
<< Compat::array(data.pAllocationList, data.AllocationListSize)
<< data.AllocationListSize
<< Compat::array(data.pPatchLocationList, data.PatchLocationListSize)
<< data.PatchLocationListSize;
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_DESTROYCONTEXT& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hContext);
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_DESTROYDEVICE& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hDevice);
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_PRESENT& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hDevice)
<< data.hWindow
<< data.VidPnSourceId
<< Compat::hex(data.hSource)
<< Compat::hex(data.hDestination)
<< Compat::hex(data.Color)
<< data.DstRect
<< data.SrcRect
<< data.SubRectCnt
<< Compat::array(data.pSrcSubRects, data.SubRectCnt)
<< data.PresentCount
<< data.FlipInterval
<< Compat::hex(data.Flags.Value)
<< data.BroadcastContextCount
<< Compat::hex(Compat::array(data.BroadcastContext, data.BroadcastContextCount))
<< data.PresentLimitSemaphore
<< data.PresentHistoryToken
<< data.pPresentRegions
<< Compat::hex(data.hAdapter)
<< data.Duration
<< Compat::hex(Compat::array(data.BroadcastSrcAllocation, data.BroadcastContextCount))
<< Compat::hex(Compat::array(data.BroadcastDstAllocation, data.BroadcastContextCount))
<< data.PrivateDriverDataSize
<< data.pPrivateDriverData
<< static_cast<UINT>(data.bOptimizeForComposition);
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETQUEUEDLIMIT& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hDevice)
<< data.Type
<< data.VidPnSourceId
<< data.QueuedPendingFlipLimit;
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER& data)
{
return Compat::LogStruct(os)
<< Compat::hex(data.hDevice)
<< Compat::array(data.pType, data.VidPnSourceCount)
<< Compat::array(data.pVidPnSourceId, data.VidPnSourceCount)
<< data.VidPnSourceCount;
}
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER1& data)
{
return Compat::LogStruct(os)
<< data.Version0
<< Compat::hex(data.Flags.Value);
}

View File

@ -0,0 +1,19 @@
#pragma once
#define CINTERFACE
#include <ostream>
#include <d3d.h>
#include <d3dumddi.h>
#include <../km/d3dkmthk.h>
std::ostream& operator<<(std::ostream& os, const D3DKMT_CREATECONTEXT& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_CREATECONTEXTVIRTUAL& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_CREATEDEVICE& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_DESTROYCONTEXT& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_DESTROYDEVICE& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_PRESENT& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETQUEUEDLIMIT& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER& data);
std::ostream& operator<<(std::ostream& os, const D3DKMT_SETVIDPNSOURCEOWNER1& data);

View File

@ -213,7 +213,7 @@ namespace DDraw
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
desc.dwBackBufferCount = 2;
desc.dwBackBufferCount = 1;
CompatPtr<typename Types<DirectDraw>::TCreatedSurface> surface;
HRESULT result = dd->CreateSurface(&dd, &desc, &surface.getRef(), nullptr);

View File

@ -169,9 +169,12 @@
<ClInclude Include="D3dDdi\DeviceCallbacks.h" />
<ClInclude Include="D3dDdi\DeviceFuncs.h" />
<ClInclude Include="D3dDdi\Hooks.h" />
<ClInclude Include="D3dDdi\KernelModeThunks.h" />
<ClInclude Include="D3dDdi\LockResource.h" />
<ClInclude Include="D3dDdi\Log\AdapterFuncsLog.h" />
<ClInclude Include="D3dDdi\Log\DeviceCallbacksLog.h" />
<ClInclude Include="D3dDdi\Log\DeviceFuncsLog.h" />
<ClInclude Include="D3dDdi\Log\KernelModeThunksLog.h" />
<ClInclude Include="D3dDdi\Visitors\AdapterCallbacksVisitor.h" />
<ClInclude Include="D3dDdi\Visitors\AdapterFuncsVisitor.h" />
<ClInclude Include="D3dDdi\Visitors\DeviceCallbacksVisitor.h" />
@ -233,9 +236,12 @@
<ClCompile Include="D3dDdi\DeviceCallbacks.cpp" />
<ClCompile Include="D3dDdi\DeviceFuncs.cpp" />
<ClCompile Include="D3dDdi\Hooks.cpp" />
<ClCompile Include="D3dDdi\KernelModeThunks.cpp" />
<ClCompile Include="D3dDdi\LockResource.cpp" />
<ClCompile Include="D3dDdi\Log\AdapterFuncsLog.cpp" />
<ClCompile Include="D3dDdi\Log\DeviceCallbacksLog.cpp" />
<ClCompile Include="D3dDdi\Log\DeviceFuncsLog.cpp" />
<ClCompile Include="D3dDdi\Log\KernelModeThunksLog.cpp" />
<ClCompile Include="DDraw\ActivateAppHandler.cpp" />
<ClCompile Include="DDraw\DirectDraw.cpp" />
<ClCompile Include="DDraw\DirectDrawPalette.cpp" />

View File

@ -291,6 +291,15 @@
<ClInclude Include="D3dDdi\LockResource.h">
<Filter>Header Files\D3dDdi</Filter>
</ClInclude>
<ClInclude Include="D3dDdi\Log\AdapterFuncsLog.h">
<Filter>Header Files\D3dDdi\Log</Filter>
</ClInclude>
<ClInclude Include="D3dDdi\KernelModeThunks.h">
<Filter>Header Files\D3dDdi</Filter>
</ClInclude>
<ClInclude Include="D3dDdi\Log\KernelModeThunksLog.h">
<Filter>Header Files\D3dDdi\Log</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">
@ -440,6 +449,15 @@
<ClCompile Include="D3dDdi\LockResource.cpp">
<Filter>Source Files\D3dDdi</Filter>
</ClCompile>
<ClCompile Include="D3dDdi\Log\AdapterFuncsLog.cpp">
<Filter>Source Files\D3dDdi\Log</Filter>
</ClCompile>
<ClCompile Include="D3dDdi\KernelModeThunks.cpp">
<Filter>Source Files\D3dDdi</Filter>
</ClCompile>
<ClCompile Include="D3dDdi\Log\KernelModeThunksLog.cpp">
<Filter>Source Files\D3dDdi\Log</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Dll\DDrawCompat.def">