port: GrpDetector verbatim 40250 over a host IDirect3D8 (Direct3DCreate8); GrpDevice::Create verbatim

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-30 15:02:12 +09:00
co-authored by Claude Opus 5.5
parent 65c43a84cd
commit fd4d9a39df
12 changed files with 1127 additions and 173 deletions
+1
View File
@@ -638,3 +638,4 @@
{"date": "2026-09-30", "unit": "EterLib/SkyBox.cpp", "action": "port", "evidence": "verbatim except native-terrain gate on Render/RenderCloud and qualified CSkyObject::Destroy in the destructor; port.login_flow (map teardown), live-client sky screenshot matches previous build"}
{"date": "2026-09-30", "unit": "EterLib/GrpScreen.cpp", "action": "port", "evidence": "verbatim; 2d draws -> UIRender commands, Show without the web-page rects; D3D8 shim gains TestCooperativeLevel/Reset/Present/GetVertexShader + ID3DXMesh; port.app_loop (3D line/bar draws, device not lost), port.login_flow (picking/projection)"}
{"date": "2026-09-30", "unit": "EterLib/GrpDevice.cpp", "action": "port", "evidence": "verbatim except Create (recording device in place of Direct3DCreate8/detector/CreateDevice, EL3D_ConfirmDevice on its caps); RecordingDevice decodes declaration-only vertex shaders to stream-0 FVFs; GrpScreen Show uses the GrpDevice browser globals; port.app_loop (PT/PNT/PNT2 FVFs, max texture 4096), full ctest, live-client screenshot matches"}
{"date": "2026-09-30", "unit": "EterLib/GrpDetector.cpp", "action": "port", "evidence": "verbatim; IDirect3D8 shim completed (adapter count/caps/format checks/CreateDevice) and implemented once as the host adapter behind Direct3DCreate8 (RecordingDevice.cpp), which CPythonGraphic::GetD3D also returns; GrpDevice::Create now verbatim but for the D3DX debug meshes; port.app_loop (800x600x32 HWVP D16 mode, ms_lpd3d, GetString), full ctest, live-client screenshot matches"}
+251
View File
@@ -0,0 +1,251 @@
{
"reference": "EterLib/GrpDetector.cpp",
"reference_sha256": "91699012029ee35c85e22aaad1ad6732b3c5dcf1dfde38dd5f57fca5a1ca543b",
"priority": "P4",
"contracts": [],
"functions": {
"CompareD3DDisplayModeOrder": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:CompareD3DDisplayModeOrder"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterDisplayModeList::GetDisplayModeNum": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterDisplayModeList::GetDisplayModeNum"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterDisplayModeList::GetPixelFormatNum": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterDisplayModeList::GetPixelFormatNum"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterDisplayModeList::GetDisplayModer": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterDisplayModeList::GetDisplayModer"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterDisplayModeList::GetPixelFormatr": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterDisplayModeList::GetPixelFormatr"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterDisplayModeList::Build": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterDisplayModeList::Build"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_SModeInfo::GetString": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_SModeInfo::GetString"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDeviceInfo::GetD3DModeInfoNum": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDeviceInfo::GetD3DModeInfoNum"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDeviceInfo::GetD3DModeInfop": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDeviceInfo::GetD3DModeInfop"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDeviceInfo::FindDepthStencilFormat": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDeviceInfo::FindDepthStencilFormat"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDeviceInfo::Build": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDeviceInfo::Build"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDeviceInfo::Find": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDeviceInfo::Find"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDeviceInfo::GetString": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDeviceInfo::GetString"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterInfo::GetDesktopD3DDisplayModer": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterInfo::GetDesktopD3DDisplayModer"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterInfo::GetDesktopD3DDisplayModep": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterInfo::GetDesktopD3DDisplayModep"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterInfo::GetD3DDeviceInfop": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterInfo::GetD3DDeviceInfop"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterInfo::GetD3DModeInfop": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterInfo::GetD3DModeInfop"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterInfo::Find": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterInfo::Find"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterInfo::Build": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterInfo::Build"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CAdapterInfo::GetString": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CAdapterInfo::GetString"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDisplayModeAutoDetector::D3D_CDisplayModeAutoDetector": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDisplayModeAutoDetector::D3D_CDisplayModeAutoDetector"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDisplayModeAutoDetector::~D3D_CDisplayModeAutoDetector": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDisplayModeAutoDetector::~D3D_CDisplayModeAutoDetector"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDisplayModeAutoDetector::GetD3DAdapterInfop": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDisplayModeAutoDetector::GetD3DAdapterInfop"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDisplayModeAutoDetector::GetD3DModeInfop": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDisplayModeAutoDetector::GetD3DModeInfop"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDisplayModeAutoDetector::Find": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDisplayModeAutoDetector::Find"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDisplayModeAutoDetector::Build": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDisplayModeAutoDetector::Build"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
},
"D3D_CDisplayModeAutoDetector::GetString": {
"status": "PORTED",
"impl": [
"src/platform/EterLib/GrpDetector.cpp:D3D_CDisplayModeAutoDetector::GetString"
],
"test": [
"tests/port/port_app_loop_test.cpp"
]
}
}
}
+1 -1
View File
@@ -221,7 +221,7 @@
"tests/port/port_app_loop_test.cpp",
"tests/port/port_login_flow_test.cpp"
],
"note": "40250: GetDC, Direct3DCreate8, D3D_CDisplayModeAutoDetector Build/Find (EL3D_ConfirmDevice per device), driver black list, CreateDevice with a refresh-rate retry, DXT CheckDeviceFormat, SetWindowPos, D3DXCreateSphere/Cylinder, SIS/3dfx caps. Port: MtCreateRecordingDevice in place of the Direct3D object and detection; the present parameters the detector does not choose are set as 40250; EL3D_ConfirmDevice runs on the one device's caps; no debug meshes; no adapter identifier. Invariant: same state manager, matrix stack, screen matrices, stream shaders, default IB/PDT VB and texture-memory/border caps after Create."
"note": "40250: also makes the debug sphere/cylinder meshes (D3DXCreateSphere/D3DXCreateCylinder). Port: verbatim over the host adapter (Direct3DCreate8 in RecordingDevice.cpp: one HAL adapter, CreateDevice makes the recording device); no D3DX mesh builders, so ms_lpSphereMesh/ms_lpCylinderMesh stay NULL. Invariant: same detection, present parameters, state manager, matrices, stream shaders, default buffers and caps flags."
},
"CGraphicDevice::__InitializePDTVertexBufferList": {
"status": "PORTED",
@@ -17,9 +17,10 @@
"src/platform/EterPythonLib/PythonGraphic.cpp:CPythonGraphic::GetD3D"
],
"test": [
"tests/port/port_app_loop_test.cpp",
"tests/port/port_login_flow_test.cpp"
],
"note": "40250 returns the IDirect3D8 it created; the port has no D3D8 object, so a CDummyDirect3D8 answers the only caller (CPythonSystem::GetDisplaySettings) with adapter modes 800x600/1024x768/1280x1024 X8R8G8B8 @60. Invariant: systemSetting.GetResolutionCount() > 0 and every mode passes the >=800x600 filter."
"note": "40250 returns ms_lpd3d, which CPythonApplication::Create made before GetDisplaySettings. Port: PythonBoot::Start runs GetDisplaySettings before app.Create, so it returns Direct3DCreate8's host adapter (RecordingDevice.cpp), the object CGraphicDevice::Create later keeps in ms_lpd3d; modes 800x600/1024x768/1280x1024 X8R8G8B8 @60. Invariant: systemSetting.GetResolutionCount() > 0 and every mode passes the >=800x600 filter."
},
"CPythonGraphic::GetOrthoDepth": {
"status": "PORTED",
+562 -79
View File
@@ -1,165 +1,648 @@
// Platform skeleton for EterLib/GrpDetector.h (40250 EterLib/GrpDetector.cpp), generated by platform_stub.py.
// Every MT_PLATFORM_STUB() body is unimplemented: replace it with the platform implementation.
// 40250 EterLib/GrpDetector.cpp, verbatim.
#include "EterLib/StdAfx.h"
#include "EterBase/Stl.h"
#include "EterLib/GrpDetector.h"
#include "../PlatformStub.h"
auto D3D_SModeInfo::GetString(std::string *) -> void
struct FIsEqualD3DDisplayMode
{
MT_PLATFORM_STUB();
FIsEqualD3DDisplayMode(D3DDISPLAYMODE* pkD3DDMChk)
{
m_pkD3DDMChk=pkD3DDMChk;
}
BOOL operator() (D3DDISPLAYMODE& rkD3DDMTest)
{
if (rkD3DDMTest.Width!=m_pkD3DDMChk->Width)
return FALSE;
if (rkD3DDMTest.Height!=m_pkD3DDMChk->Height)
return FALSE;
if (rkD3DDMTest.Format!=m_pkD3DDMChk->Format)
return FALSE;
return TRUE;
}
D3DDISPLAYMODE* m_pkD3DDMChk;
};
static int CompareD3DDisplayModeOrder( const VOID* arg1, const VOID* arg2 )
{
D3DDISPLAYMODE* p1 = (D3DDISPLAYMODE*)arg1;
D3DDISPLAYMODE* p2 = (D3DDISPLAYMODE*)arg2;
if( p1->Format > p2->Format ) return -1;
if( p1->Format < p2->Format ) return +1;
if( p1->Width < p2->Width ) return -1;
if( p1->Width > p2->Width ) return +1;
if( p1->Height < p2->Height ) return -1;
if( p1->Height > p2->Height ) return +1;
return 0;
}
auto D3D_CAdapterDisplayModeList::Build(IDirect3D8 &, D3DFORMAT, UINT) -> void
/////////////////////////////////////////////////////////////////////////////////
UINT D3D_CAdapterDisplayModeList::GetDisplayModeNum()
{
MT_PLATFORM_STUB();
return m_uD3DDMNum;
}
auto D3D_CAdapterDisplayModeList::GetDisplayModeNum() -> UINT
UINT D3D_CAdapterDisplayModeList::GetPixelFormatNum()
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<UINT>();
return m_uD3DFmtNum;
}
auto D3D_CAdapterDisplayModeList::GetPixelFormatNum() -> UINT
const D3DDISPLAYMODE& D3D_CAdapterDisplayModeList::GetDisplayModer(UINT iD3DDM)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<UINT>();
assert(iD3DDM<m_uD3DDMNum);
return m_akD3DDM[iD3DDM];
}
auto D3D_CAdapterDisplayModeList::GetDisplayModer(UINT) -> const D3DDISPLAYMODE &
const D3DFORMAT& D3D_CAdapterDisplayModeList::GetPixelFormatr(UINT iD3DFmt)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<const D3DDISPLAYMODE &>();
assert(iD3DFmt<m_uD3DFmtNum);
return m_aeD3DFmt[iD3DFmt];
}
auto D3D_CAdapterDisplayModeList::GetPixelFormatr(UINT) -> const D3DFORMAT &
VOID D3D_CAdapterDisplayModeList::Build(IDirect3D8& rkD3D, D3DFORMAT eD3DFmtDefault, UINT iD3DAdapterInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<const D3DFORMAT &>();
D3DDISPLAYMODE* akD3DDM=m_akD3DDM;
D3DFORMAT* aeD3DFmt=m_aeD3DFmt;
UINT uD3DDMNum=0;
UINT uD3DFmtNum=0;
aeD3DFmt[uD3DFmtNum++]=eD3DFmtDefault;
UINT uAdapterModeNum=rkD3D.GetAdapterModeCount(iD3DAdapterInfo);
for (UINT iD3DAdapterInfoMode=0; iD3DAdapterInfoMode<uAdapterModeNum; iD3DAdapterInfoMode++)
{
D3DDISPLAYMODE kD3DDMCur;
rkD3D.EnumAdapterModes(iD3DAdapterInfo, iD3DAdapterInfoMode, &kD3DDMCur);
// IsFilterOutLowResolutionMode
if( kD3DDMCur.Width < FILTEROUT_LOWRESOLUTION_WIDTH || kD3DDMCur.Height < FILTEROUT_LOWRESOLUTION_HEIGHT )
continue;
// FindDisplayMode
D3DDISPLAYMODE* pkD3DDMEnd=akD3DDM+uD3DDMNum;
D3DDISPLAYMODE* pkD3DDMFind=std::find_if(akD3DDM, pkD3DDMEnd, FIsEqualD3DDisplayMode(&kD3DDMCur));
// IsNewDisplayMode
if (pkD3DDMFind==pkD3DDMEnd && uD3DDMNum<D3DDISPLAYMODE_MAX)
{
D3DDISPLAYMODE& rkD3DDMNew=akD3DDM[uD3DDMNum++];
rkD3DDMNew.Width=kD3DDMCur.Width;
rkD3DDMNew.Height=kD3DDMCur.Height;
rkD3DDMNew.Format=kD3DDMCur.Format;
// FindFormat
D3DFORMAT* peD3DFmtEnd=aeD3DFmt+uD3DFmtNum;
D3DFORMAT* peD3DFmtFind=std::find(aeD3DFmt, peD3DFmtEnd, kD3DDMCur.Format);
// IsNewFormat
if (peD3DFmtFind==peD3DFmtEnd && uD3DFmtNum<D3DFORMAT_MAX)
{
aeD3DFmt[uD3DFmtNum++]=kD3DDMCur.Format;
}
}
}
qsort(akD3DDM, uD3DDMNum, sizeof(D3DDISPLAYMODE), CompareD3DDisplayModeOrder);
m_uD3DFmtNum=uD3DFmtNum;
m_uD3DDMNum=uD3DDMNum;
}
auto D3D_CDeviceInfo::Build(IDirect3D8 &, UINT, UINT, D3D_CAdapterDisplayModeList &, PFNCONFIRMDEVICE) -> BOOL
/////////////////////////////////////////////////////////////////////////////////
VOID D3D_SModeInfo::GetString(std::string* pstEnumList)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
UINT uScrDepthBits=16;
switch (m_eD3DFmtPixel)
{
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
case D3DFMT_R8G8B8:
uScrDepthBits=32;
break;
}
int iVP=0;
switch (m_dwD3DBehavior)
{
case D3DCREATE_HARDWARE_VERTEXPROCESSING:
iVP=1;
break;
case D3DCREATE_MIXED_VERTEXPROCESSING:
iVP=2;
break;
case D3DCREATE_SOFTWARE_VERTEXPROCESSING:
iVP=3;
break;
}
static const char* szVP[4]=
{
"UNKNOWN",
"HWVP",
"MXVP",
"SWVP",
};
char szText[1024+1];
_snprintf(szText, sizeof(szText), "%dx%dx%d %s\r\n", m_uScrWidth, m_uScrHeight, uScrDepthBits, szVP[iVP]);
pstEnumList->append(szText);
}
auto D3D_CDeviceInfo::Find(UINT, UINT, UINT, BOOL, UINT *) -> BOOL
/////////////////////////////////////////////////////////////////////////////////
const CHAR* D3D_CDeviceInfo::msc_aszD3DDevDesc[D3DDEVICETYPE_NUM] = {"HAL", "REF"};
const D3DDEVTYPE D3D_CDeviceInfo::msc_aeD3DDevType[D3DDEVICETYPE_NUM]={D3DDEVTYPE_HAL, D3DDEVTYPE_REF};
UINT D3D_CDeviceInfo::GetD3DModeInfoNum()
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
return m_uD3DModeInfoNum;
}
auto D3D_CDeviceInfo::GetD3DModeInfoNum() -> UINT
D3D_SModeInfo* D3D_CDeviceInfo::GetD3DModeInfop(UINT iD3D_SModeInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<UINT>();
if (iD3D_SModeInfo >= m_uD3DModeInfoNum)
return NULL;
return &m_akD3DModeInfo[iD3D_SModeInfo];
}
auto D3D_CDeviceInfo::GetString(std::string *) -> void
BOOL D3D_CDeviceInfo::FindDepthStencilFormat(IDirect3D8& rkD3D, UINT iD3DAdapterInfo, D3DDEVTYPE DeviceType, D3DFORMAT TargetFormat, D3DFORMAT* pDepthStencilFormat )
{
MT_PLATFORM_STUB();
UINT m_dwMinDepthBits = 16;
UINT m_dwMinStencilBits = 0;
if( m_dwMinDepthBits <= 16 && m_dwMinStencilBits == 0 )
{
if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D16 ) ) )
{
*pDepthStencilFormat = D3DFMT_D16;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 15 && m_dwMinStencilBits <= 1 )
{
if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D15S1 ) ) )
{
if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D15S1 ) ) )
{
*pDepthStencilFormat = D3DFMT_D15S1;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits == 0 )
{
if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
{
if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D24X8 ) ) )
{
*pDepthStencilFormat = D3DFMT_D24X8;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 8 )
{
if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
{
if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D24S8 ) ) )
{
*pDepthStencilFormat = D3DFMT_D24S8;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 24 && m_dwMinStencilBits <= 4 )
{
if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X4S4 ) ) )
{
if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D24X4S4 ) ) )
{
*pDepthStencilFormat = D3DFMT_D24X4S4;
return TRUE;
}
}
}
if( m_dwMinDepthBits <= 32 && m_dwMinStencilBits == 0 )
{
if( SUCCEEDED( rkD3D.CheckDeviceFormat( iD3DAdapterInfo, DeviceType,
TargetFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32 ) ) )
{
if( SUCCEEDED( rkD3D.CheckDepthStencilMatch( iD3DAdapterInfo, DeviceType,
TargetFormat, TargetFormat, D3DFMT_D32 ) ) )
{
*pDepthStencilFormat = D3DFMT_D32;
return TRUE;
}
}
}
return FALSE;
}
auto D3D_CDeviceInfo::FindDepthStencilFormat(IDirect3D8 &, UINT, D3DDEVTYPE, D3DFORMAT, D3DFORMAT *) -> BOOL
BOOL D3D_CDeviceInfo::Build(IDirect3D8& rkD3D, UINT iD3DAdapterInfo, UINT iDevType, D3D_CAdapterDisplayModeList& rkD3DADMList, BOOL (*pfnConfirmDevice)(D3DCAPS8& rkD3DCaps, UINT uBehavior, D3DFORMAT eD3DFmt))
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
assert(pfnConfirmDevice!=NULL && "D3D_CDeviceInfo::Build");
const D3DDEVTYPE c_eD3DDevType=msc_aeD3DDevType[iDevType];
const TCHAR* c_szD3DDevDesc=msc_aszD3DDevDesc[iDevType];
m_eD3DDevType = c_eD3DDevType;
rkD3D.GetDeviceCaps(iD3DAdapterInfo, c_eD3DDevType, &m_kD3DCaps);
m_szDevDesc = c_szD3DDevDesc;
m_uD3DModeInfoNum=0;
m_canDoWindowed = FALSE;
m_isWindowed = FALSE;
m_eD3DMSTFullscreen = D3DMULTISAMPLE_NONE;
m_eD3DMSTWindowed = D3DMULTISAMPLE_NONE;
BOOL aisFormatConfirmed[20];
DWORD adwD3DBehavior[20];
D3DFORMAT aeD3DFmtDepthStencil[20];
BOOL isHALExists = FALSE;
BOOL isHALWindowedCompatible = FALSE;
BOOL isHALDesktopCompatible = FALSE;
BOOL isHALSampleCompatible = FALSE;
// GetFlagInfo
{
UINT uD3DFmtNum=rkD3DADMList.GetPixelFormatNum();
for (DWORD iFmt=0; iFmt<uD3DFmtNum; ++iFmt)
{
D3DFORMAT eD3DFmtPixel=rkD3DADMList.GetPixelFormatr(iFmt);
DWORD dwD3DBehavior=0;
BOOL isFormatConfirmed=FALSE;
aeD3DFmtDepthStencil[iFmt] = D3DFMT_UNKNOWN;
// SkipNoRenderTargetFormat;
if (FAILED(rkD3D.CheckDeviceType(iD3DAdapterInfo, m_eD3DDevType, eD3DFmtPixel, eD3DFmtPixel, FALSE)))
continue;
if (D3DDEVTYPE_HAL==m_eD3DDevType)
{
isHALExists=TRUE;
if (m_kD3DCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED)
{
isHALWindowedCompatible=TRUE;
if (iFmt==0)
isHALDesktopCompatible=TRUE;
}
}
// Confirm the device/format for HW vertex processing
if (m_kD3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
if (m_kD3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE)
{
dwD3DBehavior=D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE;
if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
isFormatConfirmed = TRUE;
}
if (FALSE == isFormatConfirmed)
{
dwD3DBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;
if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
isFormatConfirmed = TRUE;
}
if (FALSE == isFormatConfirmed)
{
dwD3DBehavior = D3DCREATE_MIXED_VERTEXPROCESSING;
if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
isFormatConfirmed = TRUE;
}
}
// Confirm the device/format for SW vertex processing
if (FALSE == isFormatConfirmed)
{
dwD3DBehavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
if (pfnConfirmDevice(m_kD3DCaps, dwD3DBehavior, eD3DFmtPixel))
isFormatConfirmed = TRUE;
}
if (isFormatConfirmed)
{
if (!FindDepthStencilFormat(rkD3D, iD3DAdapterInfo, c_eD3DDevType, eD3DFmtPixel, &aeD3DFmtDepthStencil[iFmt]))
isFormatConfirmed = TRUE;
}
adwD3DBehavior[iFmt]=dwD3DBehavior;
aisFormatConfirmed[iFmt]=isFormatConfirmed;
}
}
// BuildModeInfoList
{
UINT uD3DDMNum=rkD3DADMList.GetDisplayModeNum();
UINT uD3DFmtNum=rkD3DADMList.GetPixelFormatNum();
for (UINT iD3DDM=0; iD3DDM<uD3DDMNum; ++iD3DDM)
{
const D3DDISPLAYMODE& c_rkD3DDM=rkD3DADMList.GetDisplayModer(iD3DDM);
for (DWORD iFmt=0; iFmt<uD3DFmtNum; ++iFmt)
{
if (rkD3DADMList.GetPixelFormatr(iFmt)==c_rkD3DDM.Format)
{
if (aisFormatConfirmed[iFmt] == TRUE )
{
D3D_SModeInfo& rkModeInfo=m_akD3DModeInfo[m_uD3DModeInfoNum++];
rkModeInfo.m_uScrWidth=c_rkD3DDM.Width;
rkModeInfo.m_uScrHeight=c_rkD3DDM.Height;
rkModeInfo.m_eD3DFmtPixel=c_rkD3DDM.Format;
rkModeInfo.m_dwD3DBehavior=adwD3DBehavior[iFmt];
rkModeInfo.m_eD3DFmtDepthStencil=aeD3DFmtDepthStencil[iFmt];
if( m_eD3DDevType == D3DDEVTYPE_HAL )
isHALSampleCompatible = TRUE;
}
}
}
}
}
// Check if the device is compatible with the desktop display mode
// (which was added initially as formats[0])
if (aisFormatConfirmed[0] && (m_kD3DCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) )
{
m_canDoWindowed=TRUE;
m_isWindowed=TRUE;
}
if (m_uD3DModeInfoNum>0)
return TRUE;
return FALSE;
}
auto D3D_CDeviceInfo::GetD3DModeInfor(UINT) -> D3D_SModeInfo &
BOOL D3D_CDeviceInfo::Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3D_SModeInfo &>();
if (isWindowed)
if (!m_isWindowed)
return FALSE;
for (UINT iD3D_SModeInfo=0; iD3D_SModeInfo<m_uD3DModeInfoNum; ++iD3D_SModeInfo)
{
D3D_SModeInfo& rkModeInfo=m_akD3DModeInfo[iD3D_SModeInfo];
if (rkModeInfo.m_uScrWidth==uScrWidth && rkModeInfo.m_uScrHeight==uScrHeight)
{
if (uScrDepthBits==16)
{
switch (rkModeInfo.m_eD3DFmtPixel)
{
case D3DFMT_R5G6B5:
case D3DFMT_X1R5G5B5:
case D3DFMT_A1R5G5B5:
*piD3DModeInfo=iD3D_SModeInfo;
return TRUE;
break;
}
}
else
{
switch (rkModeInfo.m_eD3DFmtPixel)
{
case D3DFMT_X8R8G8B8:
case D3DFMT_A8R8G8B8:
case D3DFMT_R8G8B8:
*piD3DModeInfo=iD3D_SModeInfo;
return TRUE;
break;
}
}
}
}
return FALSE;
}
auto D3D_CDeviceInfo::GetD3DModeInfop(UINT) -> D3D_SModeInfo *
VOID D3D_CDeviceInfo::GetString(std::string* pstEnumList)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3D_SModeInfo *>();
char szText[1024+1];
_snprintf(szText, sizeof(szText), "%s\r\n========================================\r\n", m_szDevDesc);
pstEnumList->append(szText);
for (UINT iD3D_SModeInfo=0; iD3D_SModeInfo<m_uD3DModeInfoNum; ++iD3D_SModeInfo)
{
_snprintf(szText, sizeof(szText), "%d. ", iD3D_SModeInfo);
pstEnumList->append(szText);
D3D_SModeInfo& rkModeInfo=m_akD3DModeInfo[iD3D_SModeInfo];
rkModeInfo.GetString(pstEnumList);
}
pstEnumList->append("\r\n");
}
decltype(D3D_CDeviceInfo::msc_aszD3DDevDesc) D3D_CDeviceInfo::msc_aszD3DDevDesc{};
/////////////////////////////////////////////////////////////////////////////
decltype(D3D_CDeviceInfo::msc_aeD3DDevType) D3D_CDeviceInfo::msc_aeD3DDevType{};
auto D3D_CAdapterInfo::Find(UINT, UINT, UINT, BOOL, UINT *, UINT *) -> BOOL
D3DDISPLAYMODE& D3D_CAdapterInfo::GetDesktopD3DDisplayModer()
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
return m_kD3DDMDesktop;
}
auto D3D_CAdapterInfo::Build(IDirect3D8 &, UINT, PFNCONFIRMDEVICE) -> BOOL
D3DDISPLAYMODE* D3D_CAdapterInfo::GetDesktopD3DDisplayModep()
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
return &m_kD3DDMDesktop;
}
auto D3D_CAdapterInfo::GetString(std::string *) -> void
D3D_CDeviceInfo* D3D_CAdapterInfo::GetD3DDeviceInfop(UINT iD3DDevInfo)
{
MT_PLATFORM_STUB();
if (iD3DDevInfo >= m_uD3DDevInfoNum)
return NULL;
return &m_akD3DDevInfo[iD3DDevInfo];
}
auto D3D_CAdapterInfo::GetDesktopD3DDisplayModer() -> D3DDISPLAYMODE &
D3D_SModeInfo* D3D_CAdapterInfo::GetD3DModeInfop(UINT iD3DDevInfo, UINT iD3D_SModeInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3DDISPLAYMODE &>();
D3D_CDeviceInfo* pkD3DDevInfo=GetD3DDeviceInfop(iD3DDevInfo);
if (pkD3DDevInfo)
{
D3D_SModeInfo* pkD3DModeInfo=pkD3DDevInfo->GetD3DModeInfop(iD3D_SModeInfo);
if (pkD3DModeInfo)
return pkD3DModeInfo;
}
return NULL;
}
auto D3D_CAdapterInfo::GetDesktopD3DDisplayModep() -> D3DDISPLAYMODE *
BOOL D3D_CAdapterInfo::Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3DDISPLAYMODE *>();
for (UINT iDevInfo=0; iDevInfo<m_uD3DDevInfoNum; ++iDevInfo)
{
D3D_CDeviceInfo& rkD3DDevInfo=m_akD3DDevInfo[iDevInfo];
if (rkD3DDevInfo.Find(uScrWidth, uScrHeight, uScrDepthBits, isWindowed, piD3DModeInfo))
{
*piD3DDevInfo=iDevInfo;
return TRUE;
}
}
return FALSE;
}
auto D3D_CAdapterInfo::GetD3DDeviceInfop(UINT) -> D3D_CDeviceInfo *
BOOL D3D_CAdapterInfo::Build(IDirect3D8& rkD3D, UINT iD3DAdapterInfo, PFNCONFIRMDEVICE pfnConfirmDevice)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3D_CDeviceInfo *>();
D3DDISPLAYMODE& rkD3DDMDesktop=m_kD3DDMDesktop;
if (FAILED(rkD3D.GetAdapterDisplayMode(iD3DAdapterInfo, &rkD3DDMDesktop)))
return FALSE;
rkD3D.GetAdapterIdentifier(iD3DAdapterInfo, D3DENUM_NO_WHQL_LEVEL, &m_kD3DAdapterIdentifier);
m_iCurD3DDevInfo=0;
m_uD3DDevInfoNum=0;
D3D_CAdapterDisplayModeList kD3DADMList;
kD3DADMList.Build(rkD3D, m_kD3DDMDesktop.Format, iD3DAdapterInfo);
D3D_CDeviceInfo* akD3DDevInfo=m_akD3DDevInfo;
for (UINT iDevType=0; iDevType<D3DDEVICETYPE_NUM; ++iDevType)
{
D3D_CDeviceInfo& rkD3DDevInfo=akD3DDevInfo[m_uD3DDevInfoNum];
if (rkD3DDevInfo.Build(rkD3D, iD3DAdapterInfo, iDevType, kD3DADMList, pfnConfirmDevice))
++m_uD3DDevInfoNum;
}
if (m_uD3DDevInfoNum>0)
return TRUE;
return FALSE;
}
auto D3D_CAdapterInfo::GetD3DModeInfop(UINT, UINT) -> D3D_SModeInfo *
VOID D3D_CAdapterInfo::GetString(std::string* pstEnumList)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3D_SModeInfo *>();
for (UINT iDevInfo=0; iDevInfo<m_uD3DDevInfoNum; ++iDevInfo)
{
char szText[1024+1];
_snprintf(szText, sizeof(szText), "Device %d\r\n", iDevInfo);
pstEnumList->append(szText);
D3D_CDeviceInfo& rkD3DDevInfo=m_akD3DDevInfo[iDevInfo];
rkD3DDevInfo.GetString(pstEnumList);
}
}
/////////////////////////////////////////////////////////////////////////////
D3D_CDisplayModeAutoDetector::D3D_CDisplayModeAutoDetector()
{
MT_PLATFORM_STUB();
m_uD3DAdapterInfoCount=0;
}
D3D_CDisplayModeAutoDetector::~D3D_CDisplayModeAutoDetector()
{
MT_PLATFORM_STUB();
}
auto D3D_CDisplayModeAutoDetector::Find(UINT, UINT, UINT, BOOL, UINT *, UINT *, UINT *) -> BOOL
D3D_CAdapterInfo* D3D_CDisplayModeAutoDetector::GetD3DAdapterInfop(UINT iD3DAdapterInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
if (iD3DAdapterInfo >= m_uD3DAdapterInfoCount)
return NULL;
return &m_akD3DAdapterInfo[iD3DAdapterInfo];
}
auto D3D_CDisplayModeAutoDetector::Build(IDirect3D8 &, PFNCONFIRMDEVICE) -> BOOL
D3D_SModeInfo* D3D_CDisplayModeAutoDetector::GetD3DModeInfop(UINT iD3DAdapterInfo, UINT iD3DDevInfo, UINT iD3D_SModeInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<BOOL>();
D3D_CAdapterInfo* pkD3DAdapterInfo=GetD3DAdapterInfop(iD3DAdapterInfo);
if (pkD3DAdapterInfo)
{
D3D_CDeviceInfo* pkD3DDevInfo=pkD3DAdapterInfo->GetD3DDeviceInfop(iD3DDevInfo);
if (pkD3DDevInfo)
{
D3D_SModeInfo* pkD3D_SModeInfo=pkD3DDevInfo->GetD3DModeInfop(iD3D_SModeInfo);
if (pkD3D_SModeInfo)
return pkD3D_SModeInfo;
}
}
return NULL;
}
auto D3D_CDisplayModeAutoDetector::GetD3DAdapterInfop(UINT) -> D3D_CAdapterInfo *
BOOL D3D_CDisplayModeAutoDetector::Find(UINT uScrWidth, UINT uScrHeight, UINT uScrDepthBits, BOOL isWindowed, UINT* piD3DModeInfo, UINT* piD3DDevInfo, UINT* piD3DAdapterInfo)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3D_CAdapterInfo *>();
for (UINT iD3DAdapterInfo=0; iD3DAdapterInfo<m_uD3DAdapterInfoCount; ++iD3DAdapterInfo)
{
D3D_CAdapterInfo& rkAdapterInfo=m_akD3DAdapterInfo[iD3DAdapterInfo];
if (rkAdapterInfo.Find(uScrWidth, uScrHeight, uScrDepthBits, isWindowed, piD3DModeInfo, piD3DDevInfo))
{
*piD3DAdapterInfo=iD3DAdapterInfo;
return TRUE;
}
}
return FALSE;
}
auto D3D_CDisplayModeAutoDetector::GetD3DModeInfop(UINT, UINT, UINT) -> D3D_SModeInfo *
BOOL D3D_CDisplayModeAutoDetector::Build(IDirect3D8& rkD3D, PFNCONFIRMDEVICE pfnConfirmDevice)
{
MT_PLATFORM_STUB();
return mt_platform_stub_return<D3D_SModeInfo *>();
m_uD3DAdapterInfoCount=0;
UINT uTotalAdapterCount=rkD3D.GetAdapterCount();
uTotalAdapterCount=min(uTotalAdapterCount, D3DADAPTERINFO_NUM);
for (UINT iD3DAdapterInfo=0; iD3DAdapterInfo<uTotalAdapterCount; ++iD3DAdapterInfo)
{
D3D_CAdapterInfo& rkAdapterInfo=m_akD3DAdapterInfo[m_uD3DAdapterInfoCount];
if (rkAdapterInfo.Build(rkD3D, iD3DAdapterInfo, pfnConfirmDevice))
++m_uD3DAdapterInfoCount;
}
if (m_uD3DAdapterInfoCount>0)
return TRUE;
return FALSE;
}
auto D3D_CDisplayModeAutoDetector::GetString(std::string *) -> void
VOID D3D_CDisplayModeAutoDetector::GetString(std::string* pstEnumList)
{
MT_PLATFORM_STUB();
for (UINT iD3DAdapterInfo=0; iD3DAdapterInfo<m_uD3DAdapterInfoCount; ++iD3DAdapterInfo)
{
char szText[1024+1];
_snprintf(szText, sizeof(szText), "Adapter %d\r\n", iD3DAdapterInfo);
pstEnumList->append(szText);
D3D_CAdapterInfo& rkAdapterInfo=m_akD3DAdapterInfo[iD3DAdapterInfo];
rkAdapterInfo.GetString(pstEnumList);
}
}
+160 -15
View File
@@ -1,12 +1,9 @@
// 40250 EterLib/GrpDevice.cpp, verbatim but for CGraphicDevice::Create, which makes the recording device
// (RecordingDevice.h) in place of the Direct3D object, adapter detection and CreateDevice.
// 40250 EterLib/GrpDevice.cpp, verbatim. Direct3DCreate8 is the host adapter of RecordingDevice.cpp.
#include "EterLib/StdAfx.h"
#include "EterLib/GrpDevice.h"
#include "EterBase/Stl.h"
#include "EterBase/Debug.h"
#include "RecordingDevice.h"
bool GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = false;
bool GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = false;
bool GRAPHICS_CAPS_HALF_SIZE_IMAGE = false;
@@ -359,12 +356,69 @@ int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /
ms_iHeight = iVres;
ms_hWnd = hWnd;
// PORT: in place of GetDC, Direct3DCreate8, the D3D_CDisplayModeAutoDetector adapter/mode search, the
// driver black list, CreateDevice with its refresh-rate retry, the DXT format checks and the full-screen
// SetWindowPos: the recording device (RecordingDevice.h) renders through the host, which owns the window
// and supports DXT and hardware T&L at any refresh rate.
ms_lpd3dDevice = MtCreateRecordingDevice(iHres, iVres);
ms_hDC = GetDC(hWnd);
ms_lpd3d = Direct3DCreate8(D3D_SDK_VERSION);
if (!ms_lpd3d)
return CREATE_NO_DIRECTX;
if (!ms_kD3DDetector.Build(*ms_lpd3d, EL3D_ConfirmDevice))
return CREATE_ENUM;
if (!ms_kD3DDetector.Find(800, 600, 32, TRUE, &ms_iD3DModeInfo, &ms_iD3DDevInfo, &ms_iD3DAdapterInfo))
return CREATE_DETECT;
std::string stDevList;
ms_kD3DDetector.GetString(&stDevList);
//Tracen(stDevList.c_str());
//Tracenf("adapter %d, device %d, mode %d", ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo);
D3D_CAdapterInfo * pkD3DAdapterInfo = ms_kD3DDetector.GetD3DAdapterInfop(ms_iD3DAdapterInfo);
if (!pkD3DAdapterInfo)
{
Tracenf("adapter %d is EMPTY", ms_iD3DAdapterInfo);
return CREATE_DETECT;
}
if (__IsInDriverBlackList(*pkD3DAdapterInfo))
{
iRet |= CREATE_BAD_DRIVER;
__WarningMessage(hWnd, CREATE_BAD_DRIVER);
}
D3D_SModeInfo * pkD3DModeInfo = pkD3DAdapterInfo->GetD3DModeInfop(ms_iD3DDevInfo, ms_iD3DModeInfo);
if (!pkD3DModeInfo)
{
Tracenf("device %d, mode %d is EMPTY", ms_iD3DDevInfo, ms_iD3DModeInfo);
return CREATE_DETECT;
}
D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
if (Windowed &&
strnicmp(rkD3DAdapterId.Driver, "3dfx", 4)==0 &&
22 == pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format)
{
return CREATE_FORMAT;
}
if (pkD3DModeInfo->m_dwD3DBehavior==D3DCREATE_SOFTWARE_VERTEXPROCESSING)
{
iRet |= CREATE_NO_TNL;
// DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
//__WarningMessage(hWnd, CREATE_NO_TNL);
// END_OF_DISABLE_NOTIFY_NOT_SUPPORT_TNL_MESSAGE
}
std::string stModeInfo;
pkD3DModeInfo->GetString(&stModeInfo);
//Tracen(stModeInfo.c_str());
int ErrorCorrection = 0;
RETRY:
ZeroMemory(&ms_d3dPresentParameter, sizeof(ms_d3dPresentParameter));
ms_d3dPresentParameter.Windowed = Windowed;
@@ -374,13 +428,90 @@ int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /
ms_d3dPresentParameter.BackBufferCount = m_uBackBufferCount;
ms_d3dPresentParameter.SwapEffect = D3DSWAPEFFECT_DISCARD;
if (!Windowed)
if (Windowed)
{
ms_d3dPresentParameter.BackBufferFormat = pkD3DAdapterInfo->GetDesktopD3DDisplayModer().Format;
}
else
{
ms_d3dPresentParameter.BackBufferFormat = pkD3DModeInfo->m_eD3DFmtPixel;
ms_d3dPresentParameter.FullScreen_RefreshRateInHz = iReflashRate;
}
ms_d3dPresentParameter.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
ms_d3dPresentParameter.EnableAutoDepthStencil = TRUE;
ms_d3dPresentParameter.AutoDepthStencilFormat = pkD3DModeInfo->m_eD3DFmtDepthStencil;
ms_dwD3DBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;
ms_dwD3DBehavior = pkD3DModeInfo->m_dwD3DBehavior;
if (FAILED(ms_hLastResult = ms_lpd3d->CreateDevice(
ms_iD3DAdapterInfo,
D3DDEVTYPE_HAL,
hWnd,
// 2004. 1. 9 myevan 버텍스 프로세싱 방식 자동 선택 추가
pkD3DModeInfo->m_dwD3DBehavior,
&ms_d3dPresentParameter,
&ms_lpd3dDevice)))
{
switch (ms_hLastResult)
{
case D3DERR_INVALIDCALL:
Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_INVALIDCALL\nThe method call is invalid. For example, a method's parameter may have an invalid value.");
break;
case D3DERR_NOTAVAILABLE:
Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_NOTAVAILABLE\nThis device does not support the queried technique. ");
break;
case D3DERR_OUTOFVIDEOMEMORY:
Tracen("IDirect3DDevice.CreateDevice - ERROR D3DERR_OUTOFVIDEOMEMORY\nDirect3D does not have enough display memory to perform the operation");
break;
default:
Tracenf("IDirect3DDevice.CreateDevice - ERROR %d", ms_hLastResult);
break;
}
if (ErrorCorrection)
return CREATE_DEVICE;
// 2004. 1. 9 myevan 큰의미 없는 코드인듯.. 에러나면 표시하고 종료하자
iReflashRate = 0;
++ErrorCorrection;
iRet = CREATE_REFRESHRATE;
goto RETRY;
}
// Check DXT Support Info
if(ms_lpd3d->CheckDeviceFormat(
ms_iD3DAdapterInfo,
D3DDEVTYPE_HAL,
ms_d3dPresentParameter.BackBufferFormat,
0,
D3DRTYPE_TEXTURE,
D3DFMT_DXT1) == D3DERR_NOTAVAILABLE)
{
ms_bSupportDXT = false;
}
if(ms_lpd3d->CheckDeviceFormat(
ms_iD3DAdapterInfo,
D3DDEVTYPE_HAL,
ms_d3dPresentParameter.BackBufferFormat,
0,
D3DRTYPE_TEXTURE,
D3DFMT_DXT3) == D3DERR_NOTAVAILABLE)
{
ms_bSupportDXT = false;
}
if(ms_lpd3d->CheckDeviceFormat(
ms_iD3DAdapterInfo,
D3DDEVTYPE_HAL,
ms_d3dPresentParameter.BackBufferFormat,
0,
D3DRTYPE_TEXTURE,
D3DFMT_DXT5) == D3DERR_NOTAVAILABLE)
{
ms_bSupportDXT = false;
}
if (FAILED((ms_hLastResult = ms_lpd3dDevice->GetDeviceCaps(&ms_d3dCaps))))
{
@@ -388,9 +519,10 @@ int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /
return CREATE_GET_DEVICE_CAPS2;
}
// PORT: the detector runs EL3D_ConfirmDevice on each device's caps; here on the one device (max texture size).
if (!EL3D_ConfirmDevice(ms_d3dCaps, ms_dwD3DBehavior, ms_d3dPresentParameter.BackBufferFormat))
return CREATE_DETECT;
if (!Windowed)
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, iHres, iVres, SWP_SHOWWINDOW);
//Tracef("vertex shader version : %X\n",(DWORD)ms_d3dCaps.VertexShaderVersion);
ms_lpd3dDevice->GetViewport(&ms_Viewport);
@@ -448,7 +580,20 @@ int CGraphicDevice::Create(HWND hWnd, int iHres, int iVres, bool Windowed, int /
else
GRAPHICS_CAPS_CAN_NOT_TEXTURE_ADDRESS_BORDER=true;
// PORT: the SIS/3dfx driver caps have no adapter identifier to test.
//D3DADAPTER_IDENTIFIER8& rkD3DAdapterId=pkD3DAdapterInfo->GetIdentifier();
if (strnicmp(rkD3DAdapterId.Driver, "SIS", 3) == 0)
{
GRAPHICS_CAPS_CAN_NOT_DRAW_LINE = true;
GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
ms_isLowTextureMemory = true;
}
else if (strnicmp(rkD3DAdapterId.Driver, "3dfx", 4) == 0)
{
GRAPHICS_CAPS_CAN_NOT_DRAW_SHADOW = true;
GRAPHICS_CAPS_HALF_SIZE_IMAGE = true;
ms_isLowTextureMemory = true;
}
return (iRet);
}
+92 -18
View File
@@ -232,6 +232,30 @@ struct DeviceIndexBuffer final : MtCpuIndexBuffer
}
};
// PORT: a D3D8 HAL on a T&L card (D3DDEVCAPS_HWTRANSFORMANDLIGHT), 8 lights, 4 texture stages,
// vertex shader 1.1 and T&L vertex clipping, as the D3D8 runtime reports for current GPUs; with
// these CGraphicBase::IsFastTNL() is true, so auto tiling picks the hardware-transform terrain.
// Caps2 D3DCAPS2_CANRENDERWINDOWED: the frame goes to a window (the adapter's desktop mode).
void host_device_caps(D3DCAPS8* caps)
{
std::memset(caps, 0, sizeof(*caps));
caps->Caps2 = D3DCAPS2_CANRENDERWINDOWED;
caps->DevCaps = D3DDEVCAPS_HWTRANSFORMANDLIGHT;
caps->VertexShaderVersion = D3DVS_VERSION(1, 1);
caps->PrimitiveMiscCaps = D3DPMISCCAPS_CLIPTLVERTS;
caps->VertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS;
caps->MaxActiveLights = 8;
caps->MaxTextureBlendStages = 4;
caps->MaxSimultaneousTextures = 4;
caps->MaxTextureWidth = caps->MaxTextureHeight = 4096;
caps->MaxAnisotropy = 16;
caps->MaxPrimitiveCount = 0xFFFFF;
caps->MaxVertexIndex = 0xFFFFF;
caps->MaxStreams = 8;
caps->MaxStreamStride = 255;
caps->TextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR;
}
class RecordingDevice final : public IDirect3DDevice8
{
public:
@@ -290,26 +314,9 @@ public:
return refs;
}
// PORT: a D3D8 HAL on a T&L card (D3DDEVCAPS_HWTRANSFORMANDLIGHT), 8 lights, 4 texture stages,
// vertex shader 1.1 and T&L vertex clipping, as the D3D8 runtime reports for current GPUs; with
// these CGraphicBase::IsFastTNL() is true, so auto tiling picks the hardware-transform terrain.
HRESULT GetDeviceCaps(D3DCAPS8* caps) override
{
std::memset(caps, 0, sizeof(*caps));
caps->DevCaps = D3DDEVCAPS_HWTRANSFORMANDLIGHT;
caps->VertexShaderVersion = D3DVS_VERSION(1, 1);
caps->PrimitiveMiscCaps = D3DPMISCCAPS_CLIPTLVERTS;
caps->VertexProcessingCaps = D3DVTXPCAPS_TEXGEN | D3DVTXPCAPS_DIRECTIONALLIGHTS | D3DVTXPCAPS_POSITIONALLIGHTS;
caps->MaxActiveLights = 8;
caps->MaxTextureBlendStages = 4;
caps->MaxSimultaneousTextures = 4;
caps->MaxTextureWidth = caps->MaxTextureHeight = 4096;
caps->MaxAnisotropy = 16;
caps->MaxPrimitiveCount = 0xFFFFF;
caps->MaxVertexIndex = 0xFFFFF;
caps->MaxStreams = 8;
caps->MaxStreamStride = 255;
caps->TextureAddressCaps = D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_CLAMP | D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR;
host_device_caps(caps);
return S_OK;
}
HRESULT GetViewport(D3DVIEWPORT8* viewport) override
@@ -1313,6 +1320,73 @@ bool MtCpuMemoryTexture(const std::string& name, UIMemoryTexture* out)
IDirect3DDevice8* MtCreateRecordingDevice(int width, int height) { return new RecordingDevice(width, height); }
namespace {
// PORT: the one adapter behind Direct3DCreate8: a HAL device with host_device_caps, every format usable,
// no reference rasterizer, and the display modes CPythonSystem::GetDisplaySettings lists as resolutions
// on a 1024x768 X8R8G8B8 desktop. CreateDevice makes the recording device at the back-buffer size.
class HostDirect3D8 final : public IDirect3D8
{
public:
ULONG Release() override { return 0; }
UINT GetAdapterCount() override { return 1; }
HRESULT GetAdapterIdentifier(UINT, DWORD, D3DADAPTER_IDENTIFIER8* pIdentifier) override
{
if (!pIdentifier) return E_FAIL;
memset(pIdentifier, 0, sizeof(D3DADAPTER_IDENTIFIER8));
strncpy(pIdentifier->Driver, "dummy", sizeof(pIdentifier->Driver));
strncpy(pIdentifier->Description, "Dummy Direct3D8", sizeof(pIdentifier->Description));
return S_OK;
}
HRESULT GetAdapterDisplayMode(UINT, D3DDISPLAYMODE* pMode) override
{
if (!pMode) return E_FAIL;
pMode->Width = 1024;
pMode->Height = 768;
pMode->RefreshRate = 60;
pMode->Format = D3DFMT_X8R8G8B8;
return S_OK;
}
UINT GetAdapterModeCount(UINT) override
{
return 3;
}
HRESULT EnumAdapterModes(UINT, UINT Mode, D3DDISPLAYMODE* pMode) override
{
if (!pMode) return E_FAIL;
static const D3DDISPLAYMODE s_modes[] = {
{ 800, 600, 60, D3DFMT_X8R8G8B8 },
{ 1024, 768, 60, D3DFMT_X8R8G8B8 },
{ 1280, 1024, 60, D3DFMT_X8R8G8B8 },
};
if (Mode >= 3) return E_FAIL;
*pMode = s_modes[Mode];
return S_OK;
}
HRESULT CheckDeviceType(UINT, D3DDEVTYPE CheckType, D3DFORMAT, D3DFORMAT, BOOL) override
{
return CheckType == D3DDEVTYPE_HAL ? S_OK : D3DERR_NOTAVAILABLE;
}
HRESULT CheckDeviceFormat(UINT, D3DDEVTYPE, D3DFORMAT, DWORD, D3DRESOURCETYPE, D3DFORMAT) override { return S_OK; }
HRESULT CheckDepthStencilMatch(UINT, D3DDEVTYPE, D3DFORMAT, D3DFORMAT, D3DFORMAT) override { return S_OK; }
HRESULT GetDeviceCaps(UINT, D3DDEVTYPE, D3DCAPS8* pCaps) override
{
host_device_caps(pCaps);
return S_OK;
}
HRESULT CreateDevice(UINT, D3DDEVTYPE, HWND, DWORD, D3DPRESENT_PARAMETERS* pp, IDirect3DDevice8** out) override
{
*out = MtCreateRecordingDevice(int(pp->BackBufferWidth), int(pp->BackBufferHeight));
return S_OK;
}
};
}
IDirect3D8* Direct3DCreate8(UINT)
{
static HostDirect3D8 s_d3d;
return &s_d3d;
}
void SetNativeTerrainRenderEnabled(bool enabled)
{
g_native_terrain_override = enabled ? 1 : 0;
+4 -45
View File
@@ -33,58 +33,17 @@ CPythonGraphic::~CPythonGraphic()
Tracef("Python Graphic Clear\n");
}
namespace
{
class CDummyDirect3D8 : public IDirect3D8
{
public:
HRESULT GetAdapterIdentifier(UINT, DWORD, D3DADAPTER_IDENTIFIER8* pIdentifier) override
{
if (!pIdentifier) return E_FAIL;
memset(pIdentifier, 0, sizeof(D3DADAPTER_IDENTIFIER8));
strncpy(pIdentifier->Driver, "dummy", sizeof(pIdentifier->Driver));
strncpy(pIdentifier->Description, "Dummy Direct3D8", sizeof(pIdentifier->Description));
return S_OK;
}
HRESULT GetAdapterDisplayMode(UINT, D3DDISPLAYMODE* pMode) override
{
if (!pMode) return E_FAIL;
pMode->Width = 1024;
pMode->Height = 768;
pMode->RefreshRate = 60;
pMode->Format = D3DFMT_X8R8G8B8;
return S_OK;
}
UINT GetAdapterModeCount(UINT) override
{
return 3;
}
HRESULT EnumAdapterModes(UINT, UINT Mode, D3DDISPLAYMODE* pMode) override
{
if (!pMode) return E_FAIL;
static const D3DDISPLAYMODE s_modes[] = {
{ 800, 600, 60, D3DFMT_X8R8G8B8 },
{ 1024, 768, 60, D3DFMT_X8R8G8B8 },
{ 1280, 1024, 60, D3DFMT_X8R8G8B8 },
};
if (Mode >= 3) return E_FAIL;
*pMode = s_modes[Mode];
return S_OK;
}
};
}
// 40250 PythonGraphic.cpp:8
void CPythonGraphic::Destroy()
{
}
// 40250 PythonGraphic.cpp:12. PORT: no IDirect3D8 exists; a stand-in reports the adapter modes CPythonSystem
// lists as resolutions.
// 40250 PythonGraphic.cpp:12 returns ms_lpd3d. PORT: PythonBoot::Start runs CPythonSystem::GetDisplaySettings
// before app.Create makes the device (40250 runs it after, in CPythonApplication::Create), so this hands out
// the host adapter Direct3DCreate8 returns, the same object CGraphicDevice::Create keeps in ms_lpd3d.
LPDIRECT3D8 CPythonGraphic::GetD3D()
{
static CDummyDirect3D8 s_dummyD3D;
return &s_dummyD3D;
return Direct3DCreate8(D3D_SDK_VERSION);
}
void CPythonGraphic::SetViewport(float x, float y, float width, float height)
+25 -9
View File
@@ -508,6 +508,9 @@ typedef enum _D3DVERTEXBLENDFLAGS {
// d3d8.h device-lost results (MAKE_D3DHRESULT(2152), (2153)).
#define D3DERR_DEVICELOST ((HRESULT)0x88760868L)
#define D3DERR_DEVICENOTRESET ((HRESULT)0x88760869L)
#define D3DERR_NOTAVAILABLE ((HRESULT)0x8876086AL)
#define D3DERR_OUTOFVIDEOMEMORY ((HRESULT)0x8876017CL)
#define D3DERR_INVALIDCALL ((HRESULT)0x8876086CL)
// d3d8types.h vertex shader declaration tokens
typedef enum _D3DVSD_TOKENTYPE
@@ -692,6 +695,8 @@ typedef struct _D3DCAPS8
} D3DCAPS8;
#define D3DDEVCAPS_HWTRANSFORMANDLIGHT 0x00010000L
#define D3DDEVCAPS_PUREDEVICE 0x00100000L
#define D3DCAPS2_CANRENDERWINDOWED 0x00080000L
#define D3DCAPS2_FULLSCREENGAMMA 0x00020000L
typedef struct _D3DGAMMARAMP
@@ -726,15 +731,6 @@ typedef struct _D3DGAMMARAMP
// upcasts 40250 relies on (texture -> base texture) compile; of the resources only the buffers carry
#define D3DENUM_NO_WHQL_LEVEL 0x00000002L
struct IDirect3D8
{
virtual ~IDirect3D8() = default;
virtual ULONG Release() { return 0; }
virtual HRESULT GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8* pIdentifier) = 0;
virtual HRESULT GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) = 0;
virtual UINT GetAdapterModeCount(UINT Adapter) = 0;
virtual HRESULT EnumAdapterModes(UINT Adapter, UINT Mode, D3DDISPLAYMODE* pMode) = 0;
};
typedef enum _D3DRESOURCETYPE
{
D3DRTYPE_SURFACE = 1,
@@ -747,6 +743,26 @@ typedef enum _D3DRESOURCETYPE
D3DRTYPE_FORCE_DWORD = 0x7fffffff
} D3DRESOURCETYPE;
struct IDirect3DDevice8;
struct IDirect3D8
{
virtual ~IDirect3D8() = default;
virtual ULONG Release() = 0;
virtual UINT GetAdapterCount() = 0;
virtual HRESULT GetAdapterIdentifier(UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER8* pIdentifier) = 0;
virtual UINT GetAdapterModeCount(UINT Adapter) = 0;
virtual HRESULT EnumAdapterModes(UINT Adapter, UINT Mode, D3DDISPLAYMODE* pMode) = 0;
virtual HRESULT GetAdapterDisplayMode(UINT Adapter, D3DDISPLAYMODE* pMode) = 0;
virtual HRESULT CheckDeviceType(UINT Adapter, D3DDEVTYPE CheckType, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed) = 0;
virtual HRESULT CheckDeviceFormat(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) = 0;
virtual HRESULT CheckDepthStencilMatch(UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) = 0;
virtual HRESULT GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS8* pCaps) = 0;
virtual HRESULT CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice8** ppReturnedDeviceInterface) = 0;
};
// d3d8.h; platform/EterLib/RecordingDevice.cpp implements the one host adapter.
#define D3D_SDK_VERSION 220
IDirect3D8* Direct3DCreate8(UINT SDKVersion);
typedef struct _D3DLOCKED_RECT
{
INT Pitch;
-2
View File
@@ -103,8 +103,6 @@ uintptr_t _beginthreadex(void* security, unsigned stack_size, unsigned (*start_a
#define MB_TOPMOST 0x00040000L
#define IDOK 1
int MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
// user32 ReleaseDC: the host owns the window and hands out no DC, so there is none to release.
inline int ReleaseDC(HWND, HDC) { return 1; }
// winmm `timeGetTime`: milliseconds since system start, wrapping at 2^32.
DWORD timeGetTime();
+8
View File
@@ -30,6 +30,14 @@ typedef WORD ATOM;
#define SWP_NOSIZE 0x0001
#define SWP_NOMOVE 0x0002
#define SWP_NOZORDER 0x0004
#define SWP_SHOWWINDOW 0x0040
#define HWND_TOP ((HWND)0)
#define HWND_TOPMOST ((HWND)-1)
// GetDC/ReleaseDC: the host draws the window, so there is no GDI device context to hand out.
inline HDC GetDC(HWND) { return NULL; }
inline int ReleaseDC(HWND, HDC) { return 1; }
#define PM_NOREMOVE 0x0000
#define PM_REMOVE 0x0001
+18
View File
@@ -40,6 +40,11 @@ struct GraphicBaseAccess : CGraphicBase
static DWORD PT() { return ms_ptVS; }
static DWORD PNT() { return ms_pntVS; }
static DWORD PNT2() { return ms_pnt2VS; }
static LPDIRECT3D8 D3D() { return ms_lpd3d; }
static D3D_SModeInfo* Mode() { return ms_kD3DDetector.GetD3DModeInfop(ms_iD3DAdapterInfo, ms_iD3DDevInfo, ms_iD3DModeInfo); }
static const D3DPRESENT_PARAMETERS& PP() { return ms_d3dPresentParameter; }
static DWORD Behavior() { return ms_dwD3DBehavior; }
static void DetectorString(std::string* s) { ms_kD3DDetector.GetString(s); }
};
static int g_failures = 0;
@@ -309,6 +314,19 @@ int main(int argc, char** argv)
CHECK(GraphicBaseAccess::PNT() == (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1));
CHECK(GraphicBaseAccess::PNT2() == (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2));
CHECK(GetMaxTextureWidth() == 4096 && GetMaxTextureHeight() == 4096);
// D3D_CDisplayModeAutoDetector over the host adapter: its HAL device, the 800x600x32 mode Create asks
// for, hardware vertex processing and the first depth format FindDepthStencilFormat tries (D16).
CHECK(GraphicBaseAccess::D3D() == Direct3DCreate8(D3D_SDK_VERSION));
{
D3D_SModeInfo* mode = GraphicBaseAccess::Mode();
CHECK(mode && mode->m_uScrWidth == 800 && mode->m_uScrHeight == 600 && mode->m_eD3DFmtPixel == D3DFMT_X8R8G8B8);
CHECK(mode && mode->m_dwD3DBehavior == D3DCREATE_HARDWARE_VERTEXPROCESSING && mode->m_eD3DFmtDepthStencil == D3DFMT_D16);
CHECK(GraphicBaseAccess::Behavior() == D3DCREATE_HARDWARE_VERTEXPROCESSING);
CHECK(GraphicBaseAccess::PP().AutoDepthStencilFormat == D3DFMT_D16 && GraphicBaseAccess::PP().BackBufferFormat == D3DFMT_X8R8G8B8);
std::string modes;
GraphicBaseAccess::DetectorString(&modes);
CHECK(modes.find("800x600x32 HWVP") != std::string::npos);
}
{
CScreen screen;
CHECK(!screen.IsLostDevice() && screen.RestoreDevice());