Export Direct3DCreate9Ex, reporting the feature as unavailable - #384
Conversation
|
Looks like exporting the symbol un-gates the entire d3d9ex.c suite, ouch. |
e418d29 to
b28424a
Compare
athei
left a comment
There was a problem hiding this comment.
Thanks, the diagnosis is convincing and the code itself passes the conventions: no new static, key, wire field, dependency, derive or allow, null_out and the HRESULT constants reused, log_once_warn! on the stub, doc shape right, .def updated, and the baseline hand-edit for all eight variants is confirmed by the Intel conformance legs. Five things before it can land.
-
docs/STATUS.mdline 48 still says "D3D9Ex: noDirect3DCreate9Ex, shared handles or D3D9On12". The description says both STATUS.md and CONFORMANCE.md record the export as absent and that this narrows the decision, but only CONFORMANCE.md is in the diff, so the status document now contradicts the DLL. That is the missing companion edit CONTRIBUTING lists under what sends a PR back. -
Nothing fails before this change and passes after it. CONTRIBUTING asks for that on any observable-behaviour claim, and the precedent for the last export addition is
windows/tests/tests/e2e/d3dperf.rswith itsCOVERAGE.mdrow: resolve byGetProcAddresson the loaded module, no harness, so a missing export is a test failure rather than a link error. The same shape pins this one: the name resolves, the call answersD3DERR_NOTAVAILABLEwith the out slot nulled, and a null out slot answersD3DERR_INVALIDCALL. The audit only checks the COVERAGE row once a file exists, which is why nothing caught it. -
The alternatives leave out the risk this trades for. No Windows d3d9.dll has ever presented "export resolves, call fails": XP has no export and Vista onwards always succeeds, so the failure branch after a successful lookup is the least exercised path in every engine, and every title that probes the name changes code path with this PR. Half-Life 2's
shaderapidx9.dllresolvesDirect3DCreate9Exby name (mat_supports_d3d9ex,mat_disable_d3d9ex,-nod3d9ex), so it moves from the plain create to the Ex attempt plus fallback. It needs a run from this branch before merge. GTA IV never asks for the name and the WoW clients use plainDirect3DCreate9, so those are unaffected. -
The verification section is stale. The
unload::exception_after_free_library_survivesfailure it excuses is #378, fixed by #395, which is already in your rebased base. The nine visual sites paragraph describes the local machine, not the change. The verification should name the gates that ran (make checkis fmt, clippy, audit and doc;make teston both arches; conformance on every CI image) and say which way the new test went. -
Nits. The doc comment says
ppD3Dwhere the parameter isout. In CONFORMANCE.md the new### d3d9ex.cheading has no.c/so the parser reads it as prose, which works, but the file's shape for a cluster with nothing to classify is the bare### d3d9ex.c clustersheader, and the "previously mis-attributed to test_scene" sentence is history rather than rationale.
|
I am taking this over from here: the five points above land as commits on top of yours on |
## Symptoms
Halo 2 (Vista) does not start. Its bundled compatibility checker,
`PCCompat.dll`, reports "Initialization failed. Either insufficient system
resources were found to run the game, or game data is missing or damaged"
and the game exits before creating a device.
## Root cause
`PCCompat.dll` resolves `Direct3DCreate9Ex` by name to decide whether the
installed runtime is the Vista-era one, and treats a null result as a runtime
it will not run on. It never calls what it finds: an export that logged on
entry recorded zero calls across runs that reached gameplay.
The adapter identity is not involved. Reporting a GeForce 8800 GT through
`adapter.spoof=nvidia` fails identically, as does filling `DriverVersion`,
`DeviceIdentifier` and `WHQLLevel`, and as does `debug.capsAll=true`. The
title makes two D3D9 calls before giving up, `GetAdapterIdentifier` and
`GetDeviceCaps`, and both succeed.
## Changes
`Direct3DCreate9Ex` is exported and answers `D3DERR_NOTAVAILABLE`, clearing
the out pointer, which is the documented failure for a runtime without
D3D9Ex. D3D9Ex itself stays unimplemented.
`docs/STATUS.md` and `unix/conformance/CONFORMANCE.md` both record the export
as deliberately absent, so this narrows that decision: the feature remains out
of scope, only the entry point becomes resolvable.
The export un-gates `d3d9ex.c`, whose `START_TEST` used to return at
`win_skip("Failed to get address of Direct3DCreate9Ex")`. The suite now runs
and reports no failures: every test fails to create its Ex device and skips,
and a skip is not a failure. So the baselined site goes away rather than
being replaced, and the eight `d3d9ex.c:5184 count=1` entries are removed with
the cluster prose rewritten to say why the suite is empty.
## Alternatives
Return a plain `IDirect3D9` cast as `IDirect3D9Ex`: its first 17 vtable slots
match, and it is what proved the diagnosis, but it runs off the end of the
vtable as soon as a caller touches one of the five Ex-only methods.
Implement D3D9Ex: past what this title needs, and a scope decision of its own.
A per-title profile entry: profiles carry config keys, and an export is not a
config key.
Leave it absent: the title cannot start for want of a symbol it never calls.
## Verification
`make check` and `make test`: 1033 and 200 host unit tests, 440 end-to-end
tests on both architectures. `unload::exception_after_free_library_survives`
fails identically on an unmodified tree at this commit and is unrelated.
`make conformance-i686`: `d3d9ex` moves from `baseline(failed=1)
current(failed=0) STALE BASELINE` to `ok`, and `device` and `stateblock` are
unchanged. `visual` reports nine new sites on this machine, but a control run
of the same target on an unmodified tree at this commit reports the identical
nine, so they are not from this change.
In the title, the device is created and gameplay renders. At
`RUST_LOG=mtld3d::d3d9=warn` the new warning is never emitted, confirming the
export is resolved and not called.
An end-to-end test resolves the export by name and checks the documented failure of a runtime without D3D9Ex: D3DERR_NOTAVAILABLE with the out slot nulled, D3DERR_INVALIDCALL for a null slot. STATUS.md no longer claims the export is absent, and the d3d9ex conformance cluster prose sits under its clusters header without the attribution history.
Findings addressed on the branch directly; review state no longer applies.
|
Half Life 2 still working. |
Symptoms
Halo 2 (Vista) does not start. Its bundled compatibility checker,
PCCompat.dll, reports "Initialization failed. Either insufficient system resources were found to run the game, or game data is missing or damaged" and the game exits before creating a device.Root cause
PCCompat.dllresolvesDirect3DCreate9Exby name to decide whether the installed runtime is the Vista-era one, and treats a null result as a runtime it will not run on. It never calls what it finds: an export that logged on entry recorded zero calls across runs that reached gameplay.The adapter identity is not involved. Reporting a GeForce 8800 GT through
adapter.spoof=nvidiafails identically, as does fillingDriverVersion,DeviceIdentifierandWHQLLevel, and as doesdebug.capsAll=true. The title makes two D3D9 calls before giving up,GetAdapterIdentifierandGetDeviceCaps, and both succeed.Changes
Direct3DCreate9Exis exported and answersD3DERR_NOTAVAILABLE, clearing the out slot, which is the documented failure for a runtime without D3D9Ex; a null out slot answersD3DERR_INVALIDCALL. D3D9Ex itself stays unimplemented andQueryInterfacefor the Ex interfaces staysE_NOINTERFACE.docs/STATUS.mdrecords the export as resolvable and the feature as absent.unix/conformance/CONFORMANCE.mdexplains why the d3d9ex cluster now has no sites:START_TESTused to return atwin_skip("Failed to get address of Direct3DCreate9Ex"), which counts as a failure under Wine; with the export resolving, every test fails to create its Ex device and skips, so the eightd3d9ex.c:5184baseline entries go away rather than being replaced.A new end-to-end test,
windows/tests/tests/e2e/d3d9ex.rswith itsCOVERAGE.mdrow, resolves the export byGetProcAddresson the loaded module the wayd3dperf.rsdoes, so a missing export is a test failure and not a link error, and pins the two return codes and the nulled slot.Alternatives
Return a plain
IDirect3D9cast asIDirect3D9Ex: its first 17 vtable slots match, and it is what proved the diagnosis, but it runs off the end of the vtable as soon as a caller touches one of the five Ex-only methods.Implement D3D9Ex: past what this title needs, and a scope decision of its own.
A per-title profile entry: profiles carry config keys, and an export is not a config key.
Leave it absent: the title cannot start for want of a symbol it never calls.
The trade this makes: no Windows d3d9.dll has ever presented "export resolves, call fails" (XP has no export, Vista onwards always succeeds), so every title that probes the name now runs the least exercised branch of its loader, the fallback after a failed
Direct3DCreate9Ex. Half-Life 2'sshaderapidx9.dllis such a title (mat_supports_d3d9ex,-nod3d9ex) and is the one run before merge; GTA IV never asks for the name and the WoW clients use plainDirect3DCreate9.Verification
make check(fmt, clippy nursery + pedantic, audit, doc) green.make test ISOLATED=1: 1086 and 258 host unit tests, 475 end-to-end tests per architecture, all passing, four processes per architecture.The new test fails before and passes after: with main's
d3d9.defandlib.rsswapped in by name,make test ISOLATED=1 FILTER=d3d9exreportse2e::d3d9ex::direct3d_create9_ex_resolves_and_reports_not_availableFAILED atGetProcAddress(Direct3DCreate9Ex); with the branch's files it passes on both architectures.Conformance:
d3d9exmoves frombaseline(failed=1) current(failed=0) STALE BASELINEtook,device,visualandstateblockunchanged; CI's conformance legs on every image, the Intel@mac2entries included, confirm the baseline edit.In Halo 2 the device is created and gameplay renders; at
RUST_LOG=mtld3d::d3d9=warnthe new warning is never emitted, confirming the export is resolved and not called. Half-Life 2 run from this build: pending.