d3d8: reconcile clean continuation 015 source

This commit is contained in:
Jonas Volman committed 2026-09-23 22:34:13 -07:00
1 parent 641e146696
commit dbcea3d616
31 files changed
+1547 -799

No files matched your search

+4 -4
View File
@@ -9055,10 +9055,10 @@
{ "file_offset": 1986320, "flags": 32, "name": "_D3D_AllocContiguousMemory@8" },
{ "file_offset": 1986352, "flags": 32, "name": "_D3D_FreeContiguousMemory@4" },
{ "file_offset": 1986384, "flags": 32, "name": "_code_001e4f50" },
{ "file_offset": 1986400, "flags": 32, "name": "_code_001e4f60" },
{ "file_offset": 1986432, "flags": 32, "name": "_code_001e4f80" },
{ "file_offset": 1986480, "flags": 32, "name": "_code_001e4fb0" },
{ "file_offset": 1986528, "flags": 32, "name": "_code_001e4fe0" },
{ "file_offset": 1986400, "flags": 32, "name": "?Push1@D3D@@YGXPAKW4SubChannel@1@KK@Z", "static": true },
{ "file_offset": 1986432, "flags": 32, "name": "?Push3@D3D@@YGXPAKW4SubChannel@1@KKKK@Z", "static": true },
{ "file_offset": 1986480, "flags": 32, "name": "?Push4@D3D@@YGXPAKW4SubChannel@1@KKKKK@Z", "static": true },
{ "file_offset": 1986528, "flags": 32, "name": "?PushCount@D3D@@YGXPAKW4SubChannel@1@KK@Z", "static": true },
{ "file_offset": 1986560, "flags": 32, "name": "?GPUCopyMemory@D3D@@YGXKKK@Z" },
{ "file_offset": 1986896, "flags": 32, "name": "?GPUCopyVideoRectangle@D3D@@YGXKKKKKKPAUtagRECT@@PAUtagPOINT@@@Z" },
{ "file_offset": 1987152, "flags": 32, "name": "?ReserveInstMem@CMiniport@D3D@@AAEKK@Z" },
@@ -0,0 +1,66 @@
# D3D8 continuation 015 intake (2026-09-24)
The supplied `d3d8_continuation_015_full.zip` has SHA-256
`CF8ED5CC52514DDC312E7607643968754C106328977703000508E47FBD8E4F6F`.
Its `VERIFY_HANDOFF.py` checked all 4,508 payload files without a hash failure.
The archive is evidence, not a matching-credit ledger or publication package.
It contains executable, PDB, XBE, compiler and SDK assets that were not imported.
The preserved review copy is outside this repository at
`C:/Users/isabe/Documents/Codex/2026-07-13/i-w/d3d8-015-review/`.
The source remains in the separately GPL-3.0-or-later licensed `libs/d3d8/`
subtree. Canonical `LICENSE.GPL-3.0` and `PROVENANCE.md` are retained. The donor's
`math.cpp` expansion references NVIDIA material described as proprietary and
confidential; it was not imported or credited. The donor's 519 matched
contributions / 54,589 padded bytes are a separate replay claim, not canonical
meaningful-byte credit, and no whole-object completion follows from them.
## Independently admitted source
The checkpoint-015 memory packet restores the PDB-backed `SubChannel` packet
helpers in `push_internal.h`, makes `GPUCopyVideoRectangle` strict exact, and
retains the better nonexact `GPUCopyMemory` draft. The four private helper names
were applied in place in `config/symbols.json` using the original PDB signature,
length and address evidence recorded in the archive's
`evidence/wave15/new_helper_owner_manifest.json`. The older checkpoint-011
`BlockOnTime` body in `pusher.cpp` is also strict exact. Its two user-pointer draw
bodies in `drawprim.cpp` remain nonexact, with zero matching credit.
The remaining clean-source 011–014 edits add eight exact functions:
`CreatePalette` (110 meaningful), `CDevice::UnInit` (404),
`CheckDisplayFormat` (19), `HalDacControlInit` (207), `GetVideoAddress` (12),
`CommonSetAntiAliasingControl` (59), `SetTextureState_ParameterCheck` (5),
and `InitializeSurface` (48). Other reconstructed bodies stay fuzzy at zero
credit. The four new headers contain D3D8-associated declarations, not copied
SDK assets.
The full accepted delta is **14 new strict functions and 1,468 meaningful
D3D8 code bytes**: 354 / 43,039 to 368 / 44,507 of 685 functions / 73,886
meaningful bytes. The first six account for 604 meaningful bytes, the latter
eight for 864. Padded code proofs for the first six are
`GPUCopyVideoRectangle` 256, `Push1`/`PushCount`/`Push3`/`Push4` 160 together,
and `BlockOnTime` 240. Padded and meaningful totals are intentionally separate.
`GPUCopyMemory` is 320 candidate bytes against January's 336 and gets zero
credit. Halo code credit is unchanged. No D3D8 object is whole-object matched.
## Gates and remaining work
The full 833-unit Ninja build and tools pytest suite pass (1,159 passed,
5 skipped, 26 subtests). The Halo stable sweep reports no exact regressions;
the D3D8 verdict was checked separately against pristine checkpoint-010 COFF
objects because `stable_verdicts.py` does not cover D3D8's named code sections.
The independent D3D8 census found 14 gains and no exact losses. Parks are 96
active, zero stale/invalid; object admission has zero contradictions. The
fake-match scan reports only the two inherited low-level assembly sites in
`pixeljar.cpp` and `pusher.cpp`, with no new lead. `git diff --check` passes.
Only eight register-access substitutions were taken from the `d3dbase.cpp`
patch; its added `SetLight` body was held because it calls withheld math
providers. `lazy.cpp` and NVIDIA-referenced `math.cpp` remain untouched. The
isolated clean-source build showed no *new* unresolved math import. Three
undefined math providers in baseline `lazy.obj` are inherited from checkpoint
010, so a whole-driver link is not claimed. The SDK overlay generator,
compiler and build recipe were not imported or modified. Revisit held material
only with independent publication rights or clean-source evidence, a selected-
provider link, and full no-regression sweep. All donor fuzzy candidates and
experiments remain in the preserved review copy; none is counted as exact.
+6
View File
@@ -9,6 +9,12 @@ Inspected paths in that repository, all under `libs/libd3d8/se/`:
`pixeljar.cpp`, `pixeljar.hpp`, `state.cpp`, `resource.cpp`, `vshader.cpp`,
`pshader.cpp`, `enum.cpp`, and `d3dbase.cpp`.
The later D3D8 continuation also uses the same RXDK reference for the
rectangle-copy algorithm in `memory.cpp`. The continuation-015 integration
retains that attribution and keeps all adapted D3D8 source under this GPL
subtree; it does not import the donor's NVIDIA-referenced `math.cpp` changes
or any bundled binary, PDB, compiler, or SDK assets.
Repository source URL:
https://github.com/Team-Resurgent/RXDK-Libs/tree/29e018674a3443f9df5b5cb4478bb9c54d8a2a3a/libs/libd3d8/se
+6 -8
View File
@@ -60,14 +60,13 @@ HRESULT WINAPI D3DDevice_CreateVertexBuffer(
{
return E_OUTOFMEMORY;
}
void *memory = MmAllocateContiguousMemoryEx(length, 0, 0x03ffb000, 0,
PAGE_READWRITE | PAGE_WRITECOMBINE);
void *memory = D3D::AllocateContiguousMemory(length, 0);
if (!memory)
{
LocalFree(buffer);
return E_OUTOFMEMORY;
}
buffer->Data = (DWORD)memory & 0x03ffffff;
buffer->Data = XMETAL_MapToPhysicalOffset(memory);
buffer->Common = D3DCOMMON_D3DCREATED | D3DCOMMON_TYPE_VERTEXBUFFER | 1;
*result = buffer;
return S_OK;
@@ -81,16 +80,15 @@ HRESULT WINAPI D3DDevice_CreatePalette(
{
return E_OUTOFMEMORY;
}
void *memory = MmAllocateContiguousMemoryEx(D3D::g_PaletteSize[size], 0,
0x03ffb000, 0, PAGE_READWRITE | PAGE_WRITECOMBINE);
void *memory = D3D::AllocateContiguousMemory(D3D::g_PaletteSize[size], 0);
if (!memory)
{
LocalFree(palette);
return E_OUTOFMEMORY;
}
DWORD paletteBits = (DWORD)size << D3DPALETTE_COMMON_PALETTESIZE_SHIFT;
palette->Data = (DWORD)memory & 0x03ffffff;
palette->Common = paletteBits | D3DCOMMON_D3DCREATED | D3DCOMMON_TYPE_PALETTE | 1;
palette->Common = ((DWORD)size << D3DPALETTE_COMMON_PALETTESIZE_SHIFT) |
D3DCOMMON_D3DCREATED | D3DCOMMON_TYPE_PALETTE | 1;
palette->Data = XMETAL_MapToPhysicalOffset(memory);
*result = palette;
return S_OK;
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef D3D8_CHECKSUM_INTERNAL_H
#define D3D8_CHECKSUM_INTERNAL_H
#include "device_layout.h"
namespace D3D
{
/* The test callback advances one of three color channels per invocation.
* These original test-only globals are shared across the kernel wait boundary.
* Callers serialize checksum requests; overlapping requests are unsupported. */
extern DWORD g_DoChecksum;
extern DWORD g_Channel;
extern DWORD g_Value[3];
}
extern "C" void __cdecl D3DTest_ChecksumCallback(
DWORD frame);
extern "C" void WINAPI D3DTest_GetScreenChecksum(
DWORD *red,
DWORD *green,
DWORD *blue);
#endif
+8 -8
View File
@@ -932,7 +932,7 @@ void WINAPI D3DDevice_GetRasterStatus(
D3DRASTER_STATUS *status)
{
CDevice *device = g_pDevice;
DWORD line = ReadGpuRegister(device->m_NvBase, NV2A_RASTER_POSITION)
DWORD line = REG_RD32(device->m_NvBase, NV2A_RASTER_POSITION)
& NV2A_RASTER_POSITION_MASK;
if (line != 0 && line < device->m_DisplayHeight)
{
@@ -953,7 +953,7 @@ BOOL WINAPI D3DDevice_IsBusy(
_HWREG *registerBase = device->m_NvBase;
return (((DWORD)device->HwGet() & 0x0fffffff) !=
((DWORD)device->m_pKickOff & 0x0fffffff)) ||
ReadGpuRegister(registerBase, NV2A_GRAPHICS_STATUS) != 0;
REG_RD32(registerBase, NV2A_GRAPHICS_STATUS) != 0;
}
void WINAPI D3DDevice_GetDisplayFieldStatus(
D3DFIELD_STATUS *status)
@@ -1011,14 +1011,14 @@ void WINAPI D3DDevice_SetTileCompressionTagBits(
address /= 16;
while (count)
{
WriteGpuRegister(registerBase, NV2A_TAG_INDEX,
REG_WR32(registerBase, NV2A_TAG_INDEX,
(((NV2A_TAG_PARTITION_SELECT + partition) & NV2A_TAG_SELECT_MASK) << 16)
| ((address++ & NV2A_TAG_ADDRESS_MASK) << 6));
DWORD dwordCount = min(count, 16 - dataAddress);
count -= dwordCount;
for (DWORD i = dataAddress; i < dwordCount; i++)
{
WriteGpuRegister(registerBase, NV2A_TAG_DATA + i * sizeof(DWORD), *data++);
REG_WR32(registerBase, NV2A_TAG_DATA + i * sizeof(DWORD), *data++);
}
dataAddress = 0;
}
@@ -1035,14 +1035,14 @@ void WINAPI D3DDevice_GetTileCompressionTagBits(
address /= 16;
while (count)
{
WriteGpuRegister(registerBase, NV2A_TAG_INDEX,
REG_WR32(registerBase, NV2A_TAG_INDEX,
(((NV2A_TAG_PARTITION_SELECT + partition) & NV2A_TAG_SELECT_MASK) << 16)
| ((address++ & NV2A_TAG_ADDRESS_MASK) << 6));
DWORD dwordCount = min(count, 16 - dataAddress);
count -= dwordCount;
for (DWORD i = dataAddress; i < dwordCount; i++)
{
*data++ = ReadGpuRegister(registerBase, NV2A_TAG_DATA + i * sizeof(DWORD));
*data++ = REG_RD32(registerBase, NV2A_TAG_DATA + i * sizeof(DWORD));
}
dataAddress = 0;
}
@@ -1066,14 +1066,14 @@ DWORD WINAPI D3DDevice_GetTileCompressionTags(
DWORD dataStart = partitionAddressStart % 16;
for (DWORD addressOffset = 0; dwordsToRead; addressOffset++)
{
WriteGpuRegister(registerBase, NV2A_TAG_INDEX,
REG_WR32(registerBase, NV2A_TAG_INDEX,
(((NV2A_TAG_PARTITION_SELECT + partition) & NV2A_TAG_SELECT_MASK) << 16)
| (((partitionAddressStart / 16 + addressOffset) & NV2A_TAG_ADDRESS_MASK) << 6));
DWORD dwordCount = min(dwordsToRead, 16 - dataStart);
dwordsToRead -= dwordCount;
for (DWORD i = dataStart; i < dwordCount; i++)
{
DWORD data = ReadGpuRegister(registerBase,
DWORD data = REG_RD32(registerBase,
NV2A_TAG_DATA + i * sizeof(DWORD));
while (data)
{
+2
View File
@@ -32,6 +32,8 @@ struct DISPLAYMODE
DWORD DisplayMode;
};
typedef char DisplayModeSize[sizeof(DISPLAYMODE) == 12 ? 1 : -1];
BOOL WINAPI CheckDisplayFormat(
D3DFORMAT format);
const DISPLAYMODE *WINAPI GetTableForCurrentAvInfo(
void);
extern const D3DADAPTER_IDENTIFIER8 g_AdapterIdentifier;
+106
View File
@@ -152,3 +152,109 @@ void WINAPI D3DDevice_PrimeVertexCache(
device->EndPush(push);
return;
}
/* These user-pointer paths submit the original attribute-run representation.
* Integer byte cursors permit a signed/wrapping inter-run displacement without
* forming an invalid intermediate C++ pointer. Each copied range must be backed
* by the caller's valid vertex allocation, including DWORD attribute padding. */
void WINAPI D3DDevice_DrawVerticesUP(
D3DPRIMITIVETYPE primitiveType,
UINT vertexCount,
const void *vertexData,
UINT stride)
{
CDevice *device = g_pDevice;
device->SetStateUP();
DWORD *push = device->StartPush();
Push1(push, 0x17fc, primitiveType);
device->EndPush(push + 2);
device->m_StateFlags |= 0x800;
ULONG_PTR source = (ULONG_PTR)vertexData + device->m_InlineStartOffset;
DWORD attributeCount = device->m_InlineAttributeCount;
InlineAttributeData *attributes = device->m_InlineAttributeData;
attributes[attributeCount - 1].UP_Delta = stride + device->m_InlineDelta;
DWORD limit = vertexCount <= 16 ? 16 : 2047 / device->m_InlineVertexDwords;
do
{
DWORD batch = min(limit, vertexCount);
DWORD words = device->m_InlineVertexDwords * batch;
vertexCount -= batch;
push = device->StartPush(words + 3);
PushCount(push, 0x40001818, words);
push++;
do
{
for (DWORD i = 0; i < attributeCount; ++i)
{
DWORD bytes = attributes[i].UP_Count * sizeof(DWORD);
memcpy(push, (const void *)source, bytes);
push += attributes[i].UP_Count;
source += bytes + attributes[i].UP_Delta;
}
} while (--batch != 0);
if (vertexCount)
{
device->EndPush(push);
}
} while (vertexCount != 0);
Push1(push, 0x17fc, 0);
device->EndPush(push + 2);
if (device->m_StateFlags & 0x1000)
{
SetFence(1);
}
device->m_StateFlags &= ~0x1800UL;
return;
}
void WINAPI D3DDevice_DrawIndexedVerticesUP(
D3DPRIMITIVETYPE primitiveType,
UINT vertexCount,
const void *indexData,
const void *vertexData,
UINT stride)
{
const WORD *indices = (const WORD *)indexData;
CDevice *device = g_pDevice;
device->SetStateUP();
DWORD *push = device->StartPush();
Push1(push, 0x17fc, primitiveType);
device->EndPush(push + 2);
device->m_StateFlags |= 0x800;
ULONG_PTR base = (ULONG_PTR)vertexData + device->m_InlineStartOffset;
DWORD attributeCount = device->m_InlineAttributeCount;
const InlineAttributeData *attributes = device->m_InlineAttributeData;
DWORD limit = vertexCount <= 16 ? 16 : 2047 / device->m_InlineVertexDwords;
do
{
DWORD batch = min(limit, vertexCount);
DWORD words = device->m_InlineVertexDwords * batch;
vertexCount -= batch;
push = device->StartPush(words + 3);
PushCount(push, 0x40001818, words);
push++;
do
{
ULONG_PTR source = base + (DWORD)*indices++ * stride;
for (DWORD i = 0; i < attributeCount; ++i)
{
DWORD bytes = attributes[i].UP_Count * sizeof(DWORD);
memcpy(push, (const void *)source, bytes);
push += attributes[i].UP_Count;
source += bytes + attributes[i].UP_Delta;
}
} while (--batch != 0);
if (vertexCount)
{
device->EndPush(push);
}
} while (vertexCount != 0);
Push1(push, 0x17fc, 0);
device->EndPush(push + 2);
if (device->m_StateFlags & 0x1000)
{
SetFence(1);
}
device->m_StateFlags &= ~0x1800UL;
return;
}
+7 -9
View File
@@ -14,6 +14,7 @@
#include "vshader_internal.h"
#include "surface_internal.h"
#include "pixeljar.h"
#include "memory_internal.h"
#pragma code_seg("D3D")
namespace D3D
{
@@ -120,20 +121,20 @@ void CDevice::FreeFrameBuffers(
if (m_pAutoDepthBuffer != NULL)
{
SetTile(1, NULL);
MmFreeContiguousMemory(m_pAutoDepthBuffer);
FreeContiguousMemory(m_pAutoDepthBuffer);
m_pAutoDepthBuffer = NULL;
ZeroMemory(&m_AutoDepthSurface, sizeof(m_AutoDepthSurface));
}
if (m_pFrameBufferBase != NULL)
{
SetTile(0, NULL);
MmFreeContiguousMemory(m_pFrameBufferBase);
FreeContiguousMemory(m_pFrameBufferBase);
m_pFrameBufferBase = NULL;
ZeroMemory(m_FrameBufferSurfaces, sizeof(m_FrameBufferSurfaces));
}
if (m_pAntiAliasBufferBase != NULL)
{
MmFreeContiguousMemory(m_pAntiAliasBufferBase);
FreeContiguousMemory(m_pAntiAliasBufferBase);
m_pAntiAliasBufferBase = NULL;
}
return;
@@ -267,8 +268,7 @@ HRESULT CDevice::InitializeFrameBuffers(
frameCount = doAntiAlias ? 1 : frameCount;
DWORD allocationSize = (frameCount * frameSize + D3DTILE_ALIGNMENT - 1)
& ~(D3DTILE_ALIGNMENT - 1);
BYTE *memory = (BYTE *)MmAllocateContiguousMemoryEx(allocationSize, 0,
0x03ffb000, D3DTILE_ALIGNMENT, PAGE_READWRITE | PAGE_WRITECOMBINE);
BYTE *memory = (BYTE *)D3D::AllocateContiguousMemory(allocationSize, D3DTILE_ALIGNMENT);
if (memory == NULL)
return E_OUTOFMEMORY;
m_pFrameBufferBase = memory;
@@ -296,8 +296,7 @@ HRESULT CDevice::InitializeFrameBuffers(
autoDepthStencilFormat, CalcTilePitch(width, autoDepthStencilFormat),
true, false, false, &format, &size);
allocationSize = (frameSize + D3DTILE_ALIGNMENT - 1) & ~(D3DTILE_ALIGNMENT - 1);
memory = (BYTE *)MmAllocateContiguousMemoryEx(allocationSize, 0,
0x03ffb000, D3DTILE_ALIGNMENT, PAGE_READWRITE | PAGE_WRITECOMBINE);
memory = (BYTE *)D3D::AllocateContiguousMemory(allocationSize, D3DTILE_ALIGNMENT);
if (memory == NULL)
return E_OUTOFMEMORY;
m_pAutoDepthBuffer = memory;
@@ -319,8 +318,7 @@ HRESULT CDevice::InitializeFrameBuffers(
{
frameSize = PixelJar::EncodeFormat(backBufferWidth, backBufferHeight, 1, 1,
postfilterFormat, 0, true, false, false, &format, &size);
memory = (BYTE *)MmAllocateContiguousMemoryEx(backBufferCount * frameSize, 0,
0x03ffb000, D3DTILE_ALIGNMENT, PAGE_READWRITE | PAGE_WRITECOMBINE);
memory = (BYTE *)D3D::AllocateContiguousMemory(backBufferCount * frameSize, D3DTILE_ALIGNMENT);
if (memory == NULL)
return E_OUTOFMEMORY;
m_pAntiAliasBufferBase = memory;
+1 -1
View File
@@ -6,7 +6,7 @@
#pragma code_seg("D3D")
namespace D3D
{
__inline BOOL CheckDisplayFormat(
__inline BOOL WINAPI CheckDisplayFormat(
D3DFORMAT format)
{
return g_TextureFormat[format] & 0x80;
+12 -11
View File
@@ -1,6 +1,7 @@
#ifndef D3D8_HARDWARE_INTERNAL_H
#define D3D8_HARDWARE_INTERNAL_H
#include "device_layout.h"
#include "xmetal_memory_internal.h"
/* January PDB layout. Volatile register accesses describe mapped device
* storage, rather than selecting an otherwise unnecessary instruction. */
struct Nv206eControl
@@ -67,14 +68,14 @@ struct _HWREG
};
/* Address the complete mapped MMIO region, not an out-of-bounds element of
* the one-element marker array in the historical declaration. */
__inline DWORD WINAPI ReadGpuRegister(
_HWREG *base,
static __inline DWORD WINAPI REG_RD32(
void *base,
DWORD offset)
{
return *(volatile DWORD *)((BYTE *)base + offset);
}
__inline void WINAPI WriteGpuRegister(
_HWREG *base,
static __inline void WINAPI REG_WR32(
void *base,
DWORD offset,
DWORD value)
{
@@ -82,14 +83,14 @@ __inline void WINAPI WriteGpuRegister(
return;
}
/* Byte-wide indexed CRTC and palette registers have distinct access widths. */
__inline BYTE WINAPI ReadGpuRegister8(
_HWREG *base,
static __inline BYTE WINAPI REG_RD08(
void *base,
DWORD offset)
{
return *(volatile BYTE *)((BYTE *)base + offset);
}
__inline void WINAPI WriteGpuRegister8(
_HWREG *base,
static __inline void WINAPI REG_WR08(
void *base,
DWORD offset,
BYTE value)
{
@@ -99,20 +100,20 @@ __inline void WINAPI WriteGpuRegister8(
__inline void CMiniport::EnableInterrupts(
void)
{
WriteGpuRegister((_HWREG *)m_RegisterBase, 0x140, m_GenInfo.ChipIntrEn0);
REG_WR32((_HWREG *)m_RegisterBase, 0x140, m_GenInfo.ChipIntrEn0);
return;
}
/* Original inline method, also present as a 16-byte target in dxgcreate. */
__inline void CMiniport::DisableInterrupts(
void)
{
WriteGpuRegister((_HWREG *)m_RegisterBase, 0x140, 0);
REG_WR32((_HWREG *)m_RegisterBase, 0x140, 0);
return;
}
__inline DWORD *CDevice::HwGet(
void)
{
return (DWORD *)(m_pControlDma->Get | 0x80000000UL);
return (DWORD *)XMETAL_MapToContiguousAddress(m_pControlDma->Get);
}
__inline DWORD CDevice::GpuTime(
void)
+2 -1
View File
@@ -26,6 +26,7 @@ enum
LAZY_POINT_SIZE_METHOD = 0x43c
};
extern const D3DVECTOR g_EyeDirection;
extern const DWORD g_MinFilter[2][3];
DWORD WINAPI GetColorMaterial(
void);
void WINAPI LazySetShaderStageProgram(
@@ -77,7 +78,7 @@ __inline void WINAPI StoreFloat(
memcpy(word, &value, sizeof(value));
return;
}
__inline float WINAPI Floatify(
static __inline float WINAPI Floatify(
DWORD word)
{
float value;
+9 -1
View File
@@ -4,6 +4,8 @@
namespace D3D
{
extern const D3DMATRIX g_IdentityMatrix;
extern const float g_Lar[32];
extern const float g_Mar[32];
void WINAPI ScaleVector3(
D3DVECTOR *out,
const D3DVECTOR *v,
@@ -23,12 +25,18 @@ void WINAPI MatrixProduct4x4(
D3DMATRIX *out,
const D3DMATRIX *a,
const D3DMATRIX *b);
float WINAPI JBInvSqrt(
const float value);
float WINAPI nvSqrt(
float value);
float WINAPI nvInv(
float value);
void WINAPI NormalizeVector3(
D3DVECTOR *vector);
BOOL WINAPI Inverse4x4(
D3DMATRIX *out,
const D3DMATRIX *matrix,
BOOL ignoreScale);
BOOL normalize);
long WINAPI FloatToLong(
float value);
__inline DWORD WINAPI Round(
+21 -17
View File
@@ -51,14 +51,11 @@ void WINAPI GPUCopyVideoRectangle(
{
case 1: format = 1; break;
case 2: format = 4; break;
case 4:
case 4: format = 10; break;
default: format = 10; break;
}
PushCount(push, 0x8300, 4);
push[1] = format;
push[2] = (sourcePitch & 0xffff) | (destinationPitch << 16);
push[3] = sourceOffset;
push[4] = destinationOffset;
Push4(push, SUBCH_RECTCOPYSURFACES, 0x300, format,
(sourcePitch & 0xffff) | (destinationPitch << 16), sourceOffset, destinationOffset);
device->EndPush(push + 5);
while (count--)
{
@@ -68,10 +65,7 @@ void WINAPI GPUCopyVideoRectangle(
/* Disjoint 16-bit fields; XOR is the target's combining operation. */
DWORD size = (((DWORD)rectangles->right - (DWORD)rectangles->left) & 0xffff)
^ (((DWORD)rectangles->bottom - (DWORD)rectangles->top) << 16);
PushCount(push, 0x6300, 3);
push[1] = sourcePoint;
push[2] = destinationPoint;
push[3] = size;
Push3(push, SUBCH_RECTCOPY, 0x300, sourcePoint, destinationPoint, size);
device->EndPush(push + 4);
rectangles++;
points++;
@@ -91,7 +85,9 @@ void WINAPI GPUCopyMemory(
{
CDevice *device = g_pDevice;
volatile NvNotification *notifiers = device->m_pMemCopyNotifiers;
unsigned __int64 notified = ReadNotificationTime(&notifiers[0]);
DWORD initial[2];
initial[0] = notifiers[0].timeStamp.nanoseconds[0];
initial[1] = notifiers[0].timeStamp.nanoseconds[1];
if (size)
{
do
@@ -120,13 +116,13 @@ void WINAPI GPUCopyMemory(
DWORD *push = device->StartPush();
if (!remaining)
{
Push1(push, 0x4104, 0);
Push1(push, SUBCH_MEMCOPY, 0x104, 0);
push += 2;
}
PushCount(push, 0x4184, 2);
PushCount(push, SUBCH_MEMCOPY, 0x184, 2);
push[1] = 5;
push[2] = 4;
PushCount(push + 3, 0x430c, 8);
PushCount(push + 3, SUBCH_MEMCOPY, 0x30c, 8);
push[4] = sourceOffset;
push[5] = destinationOffset;
push[6] = width;
@@ -141,13 +137,21 @@ void WINAPI GPUCopyMemory(
size = remaining;
} while (size);
device->KickOff();
while (notified == ReadNotificationTime(&notifiers[0]))
while (initial[0] == notifiers[0].timeStamp.nanoseconds[0] &&
initial[1] == notifiers[0].timeStamp.nanoseconds[1])
{
BusyLoop();
}
notified = ReadNotificationTime(&notifiers[0]);
while (ReadNotificationTime(&notifiers[1]) < notified)
DWORD completedHigh = notifiers[0].timeStamp.nanoseconds[1];
DWORD completedLow = notifiers[0].timeStamp.nanoseconds[0];
for (;;)
{
DWORD otherHigh = notifiers[1].timeStamp.nanoseconds[1];
if (otherHigh > completedHigh ||
(otherHigh == completedHigh && notifiers[1].timeStamp.nanoseconds[0] >= completedLow))
{
break;
}
BusyLoop();
}
}
+17
View File
@@ -1,6 +1,8 @@
#ifndef D3D8_MEMORY_INTERNAL_H
#define D3D8_MEMORY_INTERNAL_H
#include <xtl.h>
#include "kernel_memory.h"
#include "xmetal_memory_internal.h"
void *WINAPI D3D_AllocContiguousMemory(
DWORD size,
DWORD alignment);
@@ -12,6 +14,21 @@ extern "C" HLOCAL WINAPI D3D_FreeNoncontiguousMemory(
void *memory);
namespace D3D
{
/* PDB-private January allocator used by the pixel/resource creation family.
* The top 20 KiB remain reserved for GPU instance memory. */
static __inline void *WINAPI AllocateContiguousMemory(
DWORD size,
DWORD alignment)
{
return MmAllocateContiguousMemoryEx(size, 0, 0x03ffb000,
alignment, PAGE_READWRITE | PAGE_WRITECOMBINE);
}
static __inline void WINAPI FreeContiguousMemory(
void *memory)
{
MmFreeContiguousMemory(memory);
return;
}
void WINAPI GPUCopyMemory(
DWORD sourceOffset,
DWORD destinationOffset,
+114 -114
View File
@@ -28,9 +28,9 @@ int CMiniport::MapRegisters(
* registers: volatility is required for the actual device transaction. */
_HWREG *base = (_HWREG *)0xfd000000UL;
m_RegisterBase = base;
WriteGpuRegister(base, 0x1804, ReadGpuRegister(base, 0x1804) | 4);
WriteGpuRegister(base, 0x600140, 0);
WriteGpuRegister(base, 0x9140, 0);
REG_WR32(base, 0x1804, REG_RD32(base, 0x1804) | 4);
REG_WR32(base, 0x600140, 0);
REG_WR32(base, 0x9140, 0);
return TRUE;
}
@@ -38,8 +38,8 @@ void CMiniport::TmrDelay(
DWORD nanoseconds)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
DWORD start = ReadGpuRegister(base, 0x9400);
while (ReadGpuRegister(base, 0x9400) - start < nanoseconds)
DWORD start = REG_RD32(base, 0x9400);
while (REG_RD32(base, 0x9400) - start < nanoseconds)
{
}
return;
@@ -65,9 +65,9 @@ int CMiniport::GetGeneralInfo(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
m_GenInfo.ChipId = (ReadGpuRegister(base, 0x1800) >> 16) & 0xfffc;
m_GenInfo.MaskRevision = ReadGpuRegister(base, 0x1808) & 0xff;
m_GenInfo.VideoRamSize = ReadGpuRegister(base, 0x10020c);
m_GenInfo.ChipId = (REG_RD32(base, 0x1800) >> 16) & 0xfffc;
m_GenInfo.MaskRevision = REG_RD32(base, 0x1808) & 0xff;
m_GenInfo.VideoRamSize = REG_RD32(base, 0x10020c);
m_GenInfo.CrystalFreq = 16666666;
return TRUE;
}
@@ -191,11 +191,11 @@ int CMiniport::CreateCtxDmaObject(
case ADDR_AGPMEM: flags |= 0x30000; break;
case ADDR_SYSMEM: flags |= 0x20000; break;
}
WriteGpuRegister(base, 0x700008 + (instance << 4), page);
WriteGpuRegister(base, 0x70000c + (instance << 4), page);
REG_WR32(base, 0x700008 + (instance << 4), page);
REG_WR32(base, 0x70000c + (instance << 4), page);
flags |= 0x8000;
WriteGpuRegister(base, (0x70000 + instance) << 4, flags);
WriteGpuRegister(base, 0x700004 + (instance << 4), limit);
REG_WR32(base, (0x70000 + instance) << 4, flags);
REG_WR32(base, 0x700004 + (instance << 4), limit);
object->Init();
object->Engine = 0;
object->Handle = handle;
@@ -211,8 +211,8 @@ int CMiniport::InitEngines(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
WriteGpuRegister(base, 0x1830, 0);
WriteGpuRegister(base, 0x180c, 0xf800);
REG_WR32(base, 0x1830, 0);
REG_WR32(base, 0x180c, 0xf800);
HalMcControlInit();
m_GenInfo.ChipIntrEn0 = 1;
@@ -236,9 +236,9 @@ int CMiniport::InitEngines(
numerator /= 2;
denominator /= 2;
}
WriteGpuRegister(base, 0x9200, (numerator + 1) / 2);
WriteGpuRegister(base, 0x9210, (denominator + 1) / 2);
WriteGpuRegister(base, 0x9420, 0xffffffffUL);
REG_WR32(base, 0x9200, (numerator + 1) / 2);
REG_WR32(base, 0x9210, (denominator + 1) / 2);
REG_WR32(base, 0x9420, 0xffffffffUL);
HalFbControlInit();
HalDacControlInit();
InitGammaRamp(0);
@@ -258,23 +258,23 @@ void CMiniport::TilingUpdateIdle(
DWORD *savedPush)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
while (!(ReadGpuRegister(base, 0x3214) & 0x10) ||
!(ReadGpuRegister(base, 0x2400) & 0x10) ||
(ReadGpuRegister(base, 0x3220) & 0x10))
while (!(REG_RD32(base, 0x3214) & 0x10) ||
!(REG_RD32(base, 0x2400) & 0x10) ||
(REG_RD32(base, 0x3220) & 0x10))
{
ServiceFifoInterrupt();
if (ReadGpuRegister(base, 0x400100))
if (REG_RD32(base, 0x400100))
{
ServiceGrInterrupt();
}
if (ReadGpuRegister(base, 0x100) & 0x1000000)
if (REG_RD32(base, 0x100) & 0x1000000)
{
VBlank();
}
}
*savedPush = ReadGpuRegister(base, 0x3220);
WriteGpuRegister(base, 0x3220, 0);
while (ReadGpuRegister(base, 0x3220) & 0x10)
*savedPush = REG_RD32(base, 0x3220);
REG_WR32(base, 0x3220, 0);
while (REG_RD32(base, 0x3220) & 0x10)
{
}
return;
@@ -292,62 +292,62 @@ void CMiniport::ShutdownEngines(
{
DestroyTile(tile, TRUE);
}
WriteGpuRegister(base, 0x2044, 0);
REG_WR32(base, 0x2044, 0);
// Shutdown has its own drain sequence: unlike TilingUpdateIdle it does not
// retain the DMA push register for resuming later. This separation is also
// present in the pinned mpcore reference, not manual helper expansion.
while (!(ReadGpuRegister(base, 0x3214) & 0x10) ||
!(ReadGpuRegister(base, 0x2400) & 0x10) ||
(ReadGpuRegister(base, 0x3220) & 0x10))
while (!(REG_RD32(base, 0x3214) & 0x10) ||
!(REG_RD32(base, 0x2400) & 0x10) ||
(REG_RD32(base, 0x3220) & 0x10))
{
ServiceFifoInterrupt();
if (ReadGpuRegister(base, 0x400100))
if (REG_RD32(base, 0x400100))
{
ServiceGrInterrupt();
}
if (ReadGpuRegister(base, 0x100) & 0x1000000)
if (REG_RD32(base, 0x100) & 0x1000000)
{
VBlank();
}
}
WriteGpuRegister(base, 0x3220, 0);
while (ReadGpuRegister(base, 0x3220) & 0x10)
REG_WR32(base, 0x3220, 0);
while (REG_RD32(base, 0x3220) & 0x10)
{
}
WriteGpuRegister(base, 0x2500, 0);
WriteGpuRegister(base, 0x3000, 0);
WriteGpuRegister(base, 0x3050, 0);
WriteGpuRegister(base, 0x3200, 0);
WriteGpuRegister(base, 0x3250, 0);
REG_WR32(base, 0x2500, 0);
REG_WR32(base, 0x3000, 0);
REG_WR32(base, 0x3050, 0);
REG_WR32(base, 0x3200, 0);
REG_WR32(base, 0x3250, 0);
HalFifoContextSwitch(1);
WriteGpuRegister(base, 0x3210, 0);
WriteGpuRegister(base, 0x3270, 0);
REG_WR32(base, 0x3210, 0);
REG_WR32(base, 0x3270, 0);
DWORD fifoReassign = ReadGpuRegister(base, 0x2500);
DWORD fifoPush = ReadGpuRegister(base, 0x3200);
DWORD fifoPull = ReadGpuRegister(base, 0x3250);
WriteGpuRegister(base, 0x2500, 0);
WriteGpuRegister(base, 0x3200, 0);
WriteGpuRegister(base, 0x3250, 0);
DWORD fifoReassign = REG_RD32(base, 0x2500);
DWORD fifoPush = REG_RD32(base, 0x3200);
DWORD fifoPull = REG_RD32(base, 0x3250);
REG_WR32(base, 0x2500, 0);
REG_WR32(base, 0x3200, 0);
REG_WR32(base, 0x3250, 0);
for (DWORD channel = 0; channel < 2; ++channel)
{
if (m_HalInfo.FifoInUse)
{
WriteGpuRegister(base, m_HalInfo.FifoContextAddr1 + channel * 64 + 4,
ReadGpuRegister(base, m_HalInfo.FifoContextAddr1 + channel * 64));
WriteGpuRegister(base, m_HalInfo.FifoContextAddr1 + channel * 64 + 16, 0);
REG_WR32(base, m_HalInfo.FifoContextAddr1 + channel * 64 + 4,
REG_RD32(base, m_HalInfo.FifoContextAddr1 + channel * 64));
REG_WR32(base, m_HalInfo.FifoContextAddr1 + channel * 64 + 16, 0);
}
}
WriteGpuRegister(base, 0x3250, fifoPull);
WriteGpuRegister(base, 0x3200, fifoPush);
WriteGpuRegister(base, 0x2500, fifoReassign);
WriteGpuRegister(base, 0x2508, 0);
WriteGpuRegister(base, 0x2140, 0);
REG_WR32(base, 0x3250, fifoPull);
REG_WR32(base, 0x3200, fifoPush);
REG_WR32(base, 0x2500, fifoReassign);
REG_WR32(base, 0x2508, 0);
REG_WR32(base, 0x2140, 0);
HalGrLoadChannelContext(2);
WriteGpuRegister(base, 0x100200, m_HalInfo.FbSave0);
WriteGpuRegister(base, 0x100204, m_HalInfo.FbSave1);
WriteGpuRegister(base, 0x200, m_HalInfo.McSave);
WriteGpuRegister(base, 0x140, m_HalInfo.McSaveIntrEn0);
REG_WR32(base, 0x100200, m_HalInfo.FbSave0);
REG_WR32(base, 0x100204, m_HalInfo.FbSave1);
REG_WR32(base, 0x200, m_HalInfo.McSave);
REG_WR32(base, 0x140, m_HalInfo.McSaveIntrEn0);
HalRegisterShutdownNotification(
&m_ShutdownRegistration, FALSE);
KeDisconnectInterrupt(&m_InterruptObject);
@@ -375,32 +375,32 @@ int CMiniport::CreateTile(
do
{
HalGrIdle();
WriteGpuRegister(base, 0x100244 + tile * 16, offset + size - 1);
WriteGpuRegister(base, 0x100248 + tile * 16, pitch);
WriteGpuRegister(base, 0x400904 + tile * 16, offset + size - 1);
WriteGpuRegister(base, 0x400908 + tile * 16, pitch);
REG_WR32(base, 0x100244 + tile * 16, offset + size - 1);
REG_WR32(base, 0x100248 + tile * 16, pitch);
REG_WR32(base, 0x400904 + tile * 16, offset + size - 1);
REG_WR32(base, 0x400908 + tile * 16, pitch);
if (memoryType & D3DTILE_FLAGS_ZBUFFER)
{
WriteGpuRegister(base, 0x400900 + tile * 16, offset | 3);
WriteGpuRegister(base, 0x100240 + tile * 16, offset | 3);
WriteGpuRegister(base, 0x400750, 0xea0000 | ((tile * 4 + 0x10) & 0x1ffc));
WriteGpuRegister(base, 0x400754, offset | 3);
REG_WR32(base, 0x400900 + tile * 16, offset | 3);
REG_WR32(base, 0x100240 + tile * 16, offset | 3);
REG_WR32(base, 0x400750, 0xea0000 | ((tile * 4 + 0x10) & 0x1ffc));
REG_WR32(base, 0x400754, offset | 3);
}
else
{
WriteGpuRegister(base, 0x400900 + tile * 16, offset | 1);
WriteGpuRegister(base, 0x100240 + tile * 16, offset | 1);
WriteGpuRegister(base, 0x400750, 0xea0000 | ((tile * 4 + 0x10) & 0x1ffc));
WriteGpuRegister(base, 0x400754, offset | 1);
REG_WR32(base, 0x400900 + tile * 16, offset | 1);
REG_WR32(base, 0x100240 + tile * 16, offset | 1);
REG_WR32(base, 0x400750, 0xea0000 | ((tile * 4 + 0x10) & 0x1ffc));
REG_WR32(base, 0x400754, offset | 1);
}
WriteGpuRegister(base, 0x400750, 0xea0000 | ((tile * 4 + 0x30) & 0x1ffc));
WriteGpuRegister(base, 0x400754, offset + size - 1);
WriteGpuRegister(base, 0x400750, 0xea0000 | ((tile * 4 + 0x50) & 0x1ffc));
WriteGpuRegister(base, 0x400754, pitch);
} while (ReadGpuRegister(base, 0x100240 + tile * 16) != ReadGpuRegister(base, 0x400900 + tile * 16) ||
ReadGpuRegister(base, 0x100248 + tile * 16) != ReadGpuRegister(base, 0x400908 + tile * 16) ||
(ReadGpuRegister(base, 0x100244 + tile * 16) & ~0x3fffUL) !=
(ReadGpuRegister(base, 0x400904 + tile * 16) & ~0x3fffUL));
REG_WR32(base, 0x400750, 0xea0000 | ((tile * 4 + 0x30) & 0x1ffc));
REG_WR32(base, 0x400754, offset + size - 1);
REG_WR32(base, 0x400750, 0xea0000 | ((tile * 4 + 0x50) & 0x1ffc));
REG_WR32(base, 0x400754, pitch);
} while (REG_RD32(base, 0x100240 + tile * 16) != REG_RD32(base, 0x400900 + tile * 16) ||
REG_RD32(base, 0x100248 + tile * 16) != REG_RD32(base, 0x400908 + tile * 16) ||
(REG_RD32(base, 0x100244 + tile * 16) & ~0x3fffUL) !=
(REG_RD32(base, 0x400904 + tile * 16) & ~0x3fffUL));
if (memoryType & D3DTILE_FLAGS_ZCOMPRESS)
{
DWORD zData = (zTag / 4) | 0x80000000UL;
@@ -411,24 +411,24 @@ int CMiniport::CreateTile(
do
{
HalGrIdle();
WriteGpuRegister(base, 0x100300 + tile * 4, zData);
WriteGpuRegister(base, 0x400980 + tile * 4, zData);
WriteGpuRegister(base, 0x400750, 0xea0000 | ((tile * 4 + 0x90) & 0x1ffc));
WriteGpuRegister(base, 0x400754, zData);
} while (ReadGpuRegister(base, 0x100300 + tile * 4) !=
ReadGpuRegister(base, 0x400980 + tile * 4));
REG_WR32(base, 0x100300 + tile * 4, zData);
REG_WR32(base, 0x400980 + tile * 4, zData);
REG_WR32(base, 0x400750, 0xea0000 | ((tile * 4 + 0x90) & 0x1ffc));
REG_WR32(base, 0x400754, zData);
} while (REG_RD32(base, 0x100300 + tile * 4) !=
REG_RD32(base, 0x400980 + tile * 4));
if (zOffset != 0)
{
do
{
DWORD zOffsetValue = zOffset | tile | 0x80000000UL;
HalGrIdle();
WriteGpuRegister(base, 0x100324, zOffsetValue);
WriteGpuRegister(base, 0x4009a0, zOffsetValue);
} while (ReadGpuRegister(base, 0x100324) != ReadGpuRegister(base, 0x4009a0));
REG_WR32(base, 0x100324, zOffsetValue);
REG_WR32(base, 0x4009a0, zOffsetValue);
} while (REG_RD32(base, 0x100324) != REG_RD32(base, 0x4009a0));
}
}
WriteGpuRegister(base, 0x3220, dmaPush);
REG_WR32(base, 0x3220, dmaPush);
return TRUE;
}
@@ -442,22 +442,22 @@ int CMiniport::DestroyTile(
do
{
HalGrIdle();
WriteGpuRegister(base, 0x100240 + tile * 16, 0);
WriteGpuRegister(base, 0x400900 + tile * 16, 0);
WriteGpuRegister(base, 0x400750, 0xea0000 | ((tile * 4 + 0x10) & 0x1ffc));
WriteGpuRegister(base, 0x400754, 0);
} while (ReadGpuRegister(base, 0x100240 + tile * 16) !=
ReadGpuRegister(base, 0x400900 + tile * 16));
WriteGpuRegister(base, 0x100300 + tile * 4, 0);
WriteGpuRegister(base, 0x400980 + tile * 4, 0);
WriteGpuRegister(base, 0x400750, 0xea0000 | ((tile * 4 + 0x90) & 0x1ffc));
WriteGpuRegister(base, 0x400754, 0);
REG_WR32(base, 0x100240 + tile * 16, 0);
REG_WR32(base, 0x400900 + tile * 16, 0);
REG_WR32(base, 0x400750, 0xea0000 | ((tile * 4 + 0x10) & 0x1ffc));
REG_WR32(base, 0x400754, 0);
} while (REG_RD32(base, 0x100240 + tile * 16) !=
REG_RD32(base, 0x400900 + tile * 16));
REG_WR32(base, 0x100300 + tile * 4, 0);
REG_WR32(base, 0x400980 + tile * 4, 0);
REG_WR32(base, 0x400750, 0xea0000 | ((tile * 4 + 0x90) & 0x1ffc));
REG_WR32(base, 0x400754, 0);
if (zOffset != 0)
{
WriteGpuRegister(base, 0x100324, 0);
WriteGpuRegister(base, 0x4009a0, 0);
REG_WR32(base, 0x100324, 0);
REG_WR32(base, 0x4009a0, 0);
}
WriteGpuRegister(base, 0x3220, dmaPush);
REG_WR32(base, 0x3220, dmaPush);
return TRUE;
}
}
@@ -468,16 +468,16 @@ int CMiniport::LoadEngines(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
DWORD command = ReadGpuRegister(base, 0x184c);
WriteGpuRegister(base, 0x184c, command & ~0x300UL);
WriteGpuRegister(base, 0x184c, command);
WriteGpuRegister(base, 0x200, 0xffffffffUL);
DWORD command = REG_RD32(base, 0x184c);
REG_WR32(base, 0x184c, command & ~0x300UL);
REG_WR32(base, 0x184c, command);
REG_WR32(base, 0x200, 0xffffffffUL);
EnableInterrupts();
HalDacLoad();
LARGE_INTEGER systemTime;
_TIME_FIELDS fields;
static const BYTE timerMonthDays[12] =
static const BYTE tmrMonthDays[12] =
{
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
@@ -496,21 +496,21 @@ int CMiniport::LoadEngines(
// a corrected calendar conversion. Kernel TIME_FIELDS months are 1..12.
while (--fields.Month)
{
days += timerMonthDays[fields.Month];
days += tmrMonthDays[fields.Month];
}
days += fields.Day;
DWORD highTime = days * 20117 + fields.Hour * 838 +
(fields.Minute * 257698 + fields.Second * 4295) / 1000;
highTime += 146951526;
WriteGpuRegister(base, 0x9400, 0);
WriteGpuRegister(base, 0x9410, highTime);
WriteGpuRegister(base, 0x400720, 0);
REG_WR32(base, 0x9400, 0);
REG_WR32(base, 0x9410, highTime);
REG_WR32(base, 0x400720, 0);
HalGrControlLoad();
WriteGpuRegister(base, 0x400100, 0xffffffffUL);
WriteGpuRegister(base, 0x400140, 0xffffffffUL);
REG_WR32(base, 0x400100, 0xffffffffUL);
REG_WR32(base, 0x400140, 0xffffffffUL);
HalFifoControlLoad();
WriteGpuRegister(base, 0x2100, 0xffffffffUL);
WriteGpuRegister(base, 0x2140, m_HalInfo.FifoIntrEn0);
REG_WR32(base, 0x2100, 0xffffffffUL);
REG_WR32(base, 0x2140, m_HalInfo.FifoIntrEn0);
return TRUE;
}
+529 -523
View File
File diff suppressed because it is too large. Load diff
+68 -68
View File
@@ -21,7 +21,7 @@ void CMiniport::GrDone(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
while (ReadGpuRegister(base, 0x400700))
while (REG_RD32(base, 0x400700))
{
}
return;
@@ -30,9 +30,9 @@ DWORD CMiniport::ServiceVideoInterrupt(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
if (ReadGpuRegister(base, 0x8100) & 1)
if (REG_RD32(base, 0x8100) & 1)
{
WriteGpuRegister(base, 0x8100, 1);
REG_WR32(base, 0x8100, 1);
}
return 0;
}
@@ -61,12 +61,12 @@ void WINAPI CMiniport::Dpc(
DWORD pending;
do
{
DWORD interrupts = ReadGpuRegister(base, 0x100);
DWORD interrupts = REG_RD32(base, 0x100);
pending = 0;
if (interrupts & 0x100000)
{
WriteGpuRegister(base, 0x9100, 1);
pending = ReadGpuRegister(base, 0x9100);
REG_WR32(base, 0x9100, 1);
pending = REG_RD32(base, 0x9100);
}
if (interrupts & 0x01000000)
{
@@ -76,7 +76,7 @@ void WINAPI CMiniport::Dpc(
{
pending |= miniport->ServiceGrInterrupt();
}
if ((interrupts & 0x100) || (ReadGpuRegister(base, 0x2080) & 1))
if ((interrupts & 0x100) || (REG_RD32(base, 0x2080) & 1))
{
pending |= miniport->ServiceFifoInterrupt();
}
@@ -117,7 +117,7 @@ void CMiniport::FixupPushBuffer(
memcpy(start + returnOffset, &jump, sizeof(jump));
if (method == 0x308)
{
WriteGpuRegister((_HWREG *)m_RegisterBase, 0x324c, returnAddress);
REG_WR32((_HWREG *)m_RegisterBase, 0x324c, returnAddress);
m_PusherGetRunSize += returnOffset;
}
return;
@@ -141,9 +141,9 @@ BYTE WINAPI CMiniport::Isr(
{
CMiniport *miniport = (CMiniport *)context;
_HWREG *base = (_HWREG *)miniport->m_RegisterBase;
if (miniport->m_InterruptsEnabled && ReadGpuRegister(base, 0x140))
if (miniport->m_InterruptsEnabled && REG_RD32(base, 0x140))
{
DWORD pending = ReadGpuRegister(base, 0x100);
DWORD pending = REG_RD32(base, 0x100);
if (pending)
{
if (pending & 0x01000000)
@@ -173,7 +173,7 @@ DWORD CMiniport::VBlank(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
BYTE crtcIndex = ReadGpuRegister8(base, 0x6013d4);
BYTE crtcIndex = REG_RD08(base, 0x6013d4);
++m_VBlankCount;
if (m_VBlankFlips[m_VBlankFlipNext].Pending == TRUE &&
(m_PresentationInterval != D3DPRESENT_INTERVAL_TWO || IsOddField()))
@@ -186,7 +186,7 @@ DWORD CMiniport::VBlank(
DacProgramGammaRamp(&m_GammaRamp[bank]);
m_GammaUpdated[bank] = FALSE;
}
WriteGpuRegister(base, 0x40071c, ReadGpuRegister(base, 0x40071c) | 2);
REG_WR32(base, 0x40071c, REG_RD32(base, 0x40071c) | 2);
if (++m_VBlankFlipNext == 5)
{
m_VBlankFlipNext = 0;
@@ -195,14 +195,14 @@ DWORD CMiniport::VBlank(
}
do
{
WriteGpuRegister(base, 0x600100, 1);
} while (ReadGpuRegister(base, 0x100) & 0x01000000);
REG_WR32(base, 0x600100, 1);
} while (REG_RD32(base, 0x100) & 0x01000000);
KeSetEvent(&m_VerticalBlankEvent, 1, FALSE);
if (m_pVerticalBlankCallback)
{
m_pVerticalBlankCallback(m_VBlankCount);
}
WriteGpuRegister8(base, 0x6013d4, crtcIndex);
REG_WR08(base, 0x6013d4, crtcIndex);
return 0;
}
}
@@ -219,7 +219,7 @@ void CMiniport::SoftwareMethod(
case SoftwareFlipImmediate:
{
DacProgramVideoStart(data);
WriteGpuRegister(base, 0x40071c, ReadGpuRegister(base, 0x40071c) | 2);
REG_WR32(base, 0x40071c, REG_RD32(base, 0x40071c) | 2);
DWORD bank = m_VBlankFlipCount & 1;
if (m_GammaUpdated[bank] == TRUE)
{
@@ -250,30 +250,30 @@ void CMiniport::SoftwareMethod(
break;
case SoftwareReadCallback:
case SoftwareWriteCallback:
((D3DCALLBACK)data)(ReadGpuRegister(base, 0x40186c));
((D3DCALLBACK)data)(REG_RD32(base, 0x40186c));
break;
case SoftwareDxt1NoiseEnable:
WriteGpuRegister(base, 0x400750, 0xe00050);
WriteGpuRegister(base, 0x400754, data);
WriteGpuRegister(base, 0x400750, 0xdf0008);
WriteGpuRegister(base, 0x400754, data);
REG_WR32(base, 0x400750, 0xe00050);
REG_WR32(base, 0x400754, data);
REG_WR32(base, 0x400750, 0xdf0008);
REG_WR32(base, 0x400754, data);
break;
case SoftwareWriteRegister:
WriteGpuRegister(base, data, ReadGpuRegister(base, 0x40186c));
REG_WR32(base, data, REG_RD32(base, 0x40186c));
break;
case SoftwareSetSurfacePitchAndOffset:
{
DWORD offset = ReadGpuRegister(base, 0x40186c);
if (offset != ReadGpuRegister(base, 0x400828))
DWORD offset = REG_RD32(base, 0x40186c);
if (offset != REG_RD32(base, 0x400828))
{
DbgPrint("D3D: Adjusting offset\n");
WriteGpuRegister(base, 0x400828, offset);
REG_WR32(base, 0x400828, offset);
++g_Adjusts;
}
if (data != ReadGpuRegister(base, 0x400858))
if (data != REG_RD32(base, 0x400858))
{
DbgPrint("D3D: Adjusting pitch\n");
WriteGpuRegister(base, 0x400858, data);
REG_WR32(base, 0x400858, data);
++g_Adjusts;
}
}
@@ -286,30 +286,30 @@ DWORD CMiniport::ServiceGrInterrupt(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
WriteGpuRegister(base, 0x400720, 0);
DWORD interrupts = ReadGpuRegister(base, 0x400100);
DWORD method = ReadGpuRegister(base, 0x400704);
DWORD notifySource = ReadGpuRegister(base, 0x400108);
REG_WR32(base, 0x400720, 0);
DWORD interrupts = REG_RD32(base, 0x400100);
DWORD method = REG_RD32(base, 0x400704);
DWORD notifySource = REG_RD32(base, 0x400108);
DWORD channel = (method >> 20) & 0x1f;
method &= 0x1ffc;
if (interrupts & 0x1000)
{
WriteGpuRegister(base, 0x400100, 0x1000);
REG_WR32(base, 0x400100, 0x1000);
GrDone();
HalGrLoadChannelContext(channel);
}
if (interrupts & 0x10)
{
WriteGpuRegister(base, 0x400100, 0x10);
REG_WR32(base, 0x400100, 0x10);
}
if (((interrupts & 1) || (interrupts & 0x100000)) && (notifySource & 0x40))
{
WriteGpuRegister(base, 0x400100, (interrupts & 1) ? 1 : 0x100000);
REG_WR32(base, 0x400100, (interrupts & 1) ? 1 : 0x100000);
}
interrupts = ReadGpuRegister(base, 0x400100);
interrupts = REG_RD32(base, 0x400100);
if (interrupts)
{
WriteGpuRegister(base, 0x400100, interrupts);
REG_WR32(base, 0x400100, interrupts);
if (interrupts != 0x1000 && interrupts != 0x01000000)
{
if (interrupts & 0x10)
@@ -318,13 +318,13 @@ DWORD CMiniport::ServiceGrInterrupt(
}
if (notifySource && ((interrupts & 1) || (interrupts & 0x100000)))
{
DWORD objectClass = ReadGpuRegister(base, 0x40014c) & 0xff;
DWORD data = ReadGpuRegister(base, 0x400708);
DWORD objectClass = REG_RD32(base, 0x40014c) & 0xff;
DWORD data = REG_RD32(base, 0x400708);
if (!(notifySource & 0x40))
{
if (method == 0x100)
{
SoftwareMethod(data, ReadGpuRegister(base, 0x401a88));
SoftwareMethod(data, REG_RD32(base, 0x401a88));
}
else
{
@@ -339,30 +339,30 @@ DWORD CMiniport::ServiceGrInterrupt(
}
}
}
WriteGpuRegister(base, 0x400720, 1);
return ReadGpuRegister(base, 0x400100);
REG_WR32(base, 0x400720, 1);
return REG_RD32(base, 0x400100);
}
DWORD CMiniport::ServiceFifoInterrupt(
void)
{
_HWREG *base = (_HWREG *)m_RegisterBase;
DWORD interrupts = ReadGpuRegister(base, 0x2100);
DWORD interrupts = REG_RD32(base, 0x2100);
if (interrupts & 0x100000)
{
WriteGpuRegister(base, 0x2100, 0x100000);
REG_WR32(base, 0x2100, 0x100000);
}
if (interrupts & 0x01000000)
{
WriteGpuRegister(base, 0x2100, 0x01000000);
REG_WR32(base, 0x2100, 0x01000000);
}
interrupts = ReadGpuRegister(base, 0x2100);
interrupts = REG_RD32(base, 0x2100);
if (interrupts & 1)
{
DWORD pull = ReadGpuRegister(base, 0x3250);
WriteGpuRegister(base, 0x2500, 0);
WriteGpuRegister(base, 0x3250, 0);
WriteGpuRegister(base, 0x2100, 1);
DWORD pull = REG_RD32(base, 0x3250);
REG_WR32(base, 0x2500, 0);
REG_WR32(base, 0x3250, 0);
REG_WR32(base, 0x2100, 1);
DWORD retries = 0xffff;
do
{
@@ -370,50 +370,50 @@ DWORD CMiniport::ServiceFifoInterrupt(
{
break;
}
pull = ReadGpuRegister(base, 0x3250);
pull = REG_RD32(base, 0x3250);
} while (--retries);
WriteGpuRegister(base, 0x3258, 0);
WriteGpuRegister(base, 0x3250, 1);
WriteGpuRegister(base, 0x2500, 1);
REG_WR32(base, 0x3258, 0);
REG_WR32(base, 0x3250, 1);
REG_WR32(base, 0x2500, 1);
}
if (interrupts & 0x1000)
{
DbgPrint("SW PUT=%x\n", g_pDevice->m_Pusher.m_pPut);
DbgPrint("HW PUT=%x\n", *(volatile DWORD *)0xfd003240UL);
DbgPrint("HW GET=%x\n", *(volatile DWORD *)0xfd003244UL);
WriteGpuRegister(base, 0x2100, 0x1000);
WriteGpuRegister(base, 0x3228, 0);
if (ReadGpuRegister(base, 0x3240) != ReadGpuRegister(base, 0x3244))
REG_WR32(base, 0x2100, 0x1000);
REG_WR32(base, 0x3228, 0);
if (REG_RD32(base, 0x3240) != REG_RD32(base, 0x3244))
{
WriteGpuRegister(base, 0x3244, ReadGpuRegister(base, 0x3244) + 4);
REG_WR32(base, 0x3244, REG_RD32(base, 0x3244) + 4);
}
}
if (ReadGpuRegister(base, 0x3220) & 0x1000)
if (REG_RD32(base, 0x3220) & 0x1000)
{
while (!(ReadGpuRegister(base, 0x3214) & 0x10) && !ReadGpuRegister(base, 0x2100))
while (!(REG_RD32(base, 0x3214) & 0x10) && !REG_RD32(base, 0x2100))
{
if (ReadGpuRegister(base, 0x400100))
if (REG_RD32(base, 0x400100))
{
ServiceGrInterrupt();
}
if (ReadGpuRegister(base, 0x100) & 0x01000000)
if (REG_RD32(base, 0x100) & 0x01000000)
{
VBlank();
}
}
if (ReadGpuRegister(base, 0x3214) & 0x10)
if (REG_RD32(base, 0x3214) & 0x10)
{
while (ReadGpuRegister(base, 0x2500) & 0x10)
while (REG_RD32(base, 0x2500) & 0x10)
{
}
WriteGpuRegister(base, 0x3220, ReadGpuRegister(base, 0x3220) & ~0x1000UL);
REG_WR32(base, 0x3220, REG_RD32(base, 0x3220) & ~0x1000UL);
}
}
if (!ReadGpuRegister(base, 0x2100))
if (!REG_RD32(base, 0x2100))
{
WriteGpuRegister(base, 0x3250, 1);
WriteGpuRegister(base, 0x2500, 1);
REG_WR32(base, 0x3250, 1);
REG_WR32(base, 0x2500, 1);
}
return ReadGpuRegister(base, 0x2100) | (ReadGpuRegister(base, 0x2080) & 1);
return REG_RD32(base, 0x2100) | (REG_RD32(base, 0x2080) & 1);
}
}
+56
View File
@@ -0,0 +1,56 @@
#ifndef D3D8_PUSH_FLOAT_INTERNAL_H
#define D3D8_PUSH_FLOAT_INTERNAL_H
#include "push_internal.h"
namespace D3D
{
__inline void WINAPI StoreFloatPair(
DWORD *push,
float first,
float second)
{
memcpy(push, &first, sizeof(first));
memcpy(push + 1, &second, sizeof(second));
return;
}
__inline void WINAPI StoreFloat4(
DWORD *push,
float first,
float second,
float third,
float fourth)
{
memcpy(push, &first, sizeof(first));
memcpy(push + 1, &second, sizeof(second));
memcpy(push + 2, &third, sizeof(third));
memcpy(push + 3, &fourth, sizeof(fourth));
return;
}
/* Floating-point GPU methods carry IEEE-754 words. Representation copies keep
* the DWORD-backed command allocation free of float-pointer type punning. */
__inline void WINAPI Push2f(
DWORD *push,
DWORD method,
float first,
float second)
{
PushCount(push, method, 2);
memcpy(push + 1, &first, sizeof(first));
memcpy(push + 2, &second, sizeof(second));
return;
}
__inline void WINAPI Push4fSafe(
DWORD *push,
DWORD method,
float first,
float second,
float third,
float fourth)
{
PushCount(push, method, 4);
StoreFloat4(push + 1, first, second, third, fourth);
return;
}
}
#endif
+71 -12
View File
@@ -5,6 +5,7 @@
* NV2A FIFO packet operations. The method word and data words are GPU
* commands, never native x86 instruction bytes. */
#include "device_layout.h"
#include "xmetal_internal.h"
extern "C" DWORD *WINAPI XMETAL_StartPush(
_XMETAL_PushBuffer *buffer);
extern "C" DWORD *WINAPI XMETAL_StartPushCount(
@@ -40,40 +41,98 @@ __inline DWORD *CDevice::StartPush(
__inline void CDevice::EndPush(
DWORD *put)
{
m_Pusher.m_pPut = put;
XMETAL_EndPush(&m_Pusher, put);
return;
}
__inline void WINAPI PushCount(
static __inline void WINAPI PushCount(
DWORD *push,
DWORD method,
DWORD count)
{
push[0] = method + (count << 18);
XMETAL_PushCount(push, method, count);
return;
}
__inline void WINAPI Push1(
static __inline void WINAPI Push1(
DWORD *push,
DWORD method,
DWORD value)
{
push[0] = method + (1 << 18);
push[1] = value;
XMETAL_Push1(push, method, value);
return;
}
__inline void WINAPI Push2(
static __inline void WINAPI Push2(
DWORD *push,
DWORD method,
DWORD first,
DWORD second)
{
push[0] = method + (2 << 18);
XMETAL_Push2(push, method, first, second);
return;
}
/* January's eight hardware FIFO subchannels, authenticated by the original PDB. */
enum SubChannel
{
SUBCH_3D = 0,
SUBCH_SW = 1,
SUBCH_MEMCOPY = 2,
SUBCH_RECTCOPY = 3,
SUBCH_RECTCOPYSURFACES = 4,
SUBCH_UNUSED0 = 5,
SUBCH_UNUSED1 = 6,
SUBCH_UNUSED2 = 7
};
static __inline void WINAPI PushCount(
DWORD *push,
SubChannel subchannel,
DWORD method,
DWORD count)
{
push[0] = method + ((subchannel + (count << 5)) << 13);
return;
}
static __inline void WINAPI Push1(
DWORD *push,
SubChannel subchannel,
DWORD method,
DWORD value)
{
push[0] = method + ((subchannel + (1 << 5)) << 13);
push[1] = value;
return;
}
static __inline void WINAPI Push3(
DWORD *push,
SubChannel subchannel,
DWORD method,
DWORD first,
DWORD second,
DWORD third)
{
push[0] = method + ((subchannel + (3 << 5)) << 13);
push[1] = first;
push[2] = second;
push[3] = third;
return;
}
static __inline void WINAPI Push4(
DWORD *push,
SubChannel subchannel,
DWORD method,
DWORD first,
DWORD second,
DWORD third,
DWORD fourth)
{
push[0] = method + ((subchannel + (4 << 5)) << 13);
push[1] = first;
push[2] = second;
push[3] = third;
push[4] = fourth;
return;
}
/* NV2A matrix packets have sixteen transposed words, or twelve words of
* an already-computed inverse. Copies preserve the float representation. */
__inline void WINAPI PushMatrixTransposed(
static __inline void WINAPI PushMatrixTransposed(
DWORD *push,
DWORD method,
const D3DMATRIX *matrix)
@@ -81,7 +140,7 @@ __inline void WINAPI PushMatrixTransposed(
DumpMatrixTransposed(push, method + (16 << 18), matrix);
return;
}
__inline void WINAPI PushInverseModelViewMatrix(
static __inline void WINAPI PushInverseModelViewMatrix(
DWORD *push,
DWORD method,
const D3DMATRIX *matrix)
@@ -90,7 +149,7 @@ __inline void WINAPI PushInverseModelViewMatrix(
memcpy(push + 1, matrix, 12 * sizeof(DWORD));
return;
}
__inline DWORD WINAPI SwapRgb(
static __inline DWORD WINAPI SwapRgb(
DWORD color)
{
return (color & 0xff00ff00UL) | ((color & 0xff) << 16) | ((color >> 16) & 0xff);
@@ -122,7 +181,7 @@ enum
NV097_SET_CULL_FACE_V_FRONT = 0x404,
NV097_SET_CULL_FACE_V_BACK = 0x405
};
__inline void WINAPI Push4f(
static __inline void WINAPI Push4f(
DWORD *push,
DWORD method,
float x,
+143 -1
View File
@@ -4,6 +4,7 @@
#include "pusher_state.h"
#include "resource_internal.h"
#include "pixeljar.h"
#include "kernel_dispatcher.h"
#pragma code_seg("D3D")
namespace D3D
{
@@ -67,7 +68,7 @@ DWORD *CDevice::GpuGet(
DWORD *get = HwGet();
if (get < m_pPushBase || get >= m_pPushLimit)
{
get = (DWORD *)((ReadGpuRegister(m_NvBase, 0x324c) & ~1UL) | 0x80000000UL);
get = (DWORD *)((REG_RD32(m_NvBase, 0x324c) & ~1UL) | 0x80000000UL);
}
return get;
}
@@ -242,3 +243,144 @@ extern "C" DWORD *WINAPI XMETAL_StartPushCount(
}
return put;
}
namespace D3D
{
/* The January wait protocol patches a live GPU fence only while its gap is
* at least 32 KiB. If the GPU wins the race, restore harmless commands and
* spin on the fence time. No target code is executed by the build tools. */
void WINAPI BlockOnTime(
DWORD time,
BOOL makeSpace)
{
CDevice *device = g_pDevice;
if (time == 0 || !device->IsTimePending(time))
{
return;
}
if (time == device->m_CpuTime)
{
SetFence(0);
}
DWORD spinTime = time;
Fence *fence = FindFence(time);
DWORD gap = ComputeGap(device, fence);
if (gap >= 32768)
{
FenceEncoding *encoding = fence->pEncoding;
KeClearEvent(&device->m_Miniport.m_BusyBlockEvent);
if (!makeSpace)
{
encoding->m_WaitForIdleCommand = 0x40110;
encoding->m_WaitForIdleArgument = 0;
}
encoding->m_NoOperationCommand = 0x40100;
encoding->m_FenceCommand = 0x310;
FlushWCCache();
DWORD newGap = ComputeGap(device, fence);
if (newGap < 32768)
{
encoding->m_WaitForIdleCommand = 0x40100;
encoding->m_WaitForIdleArgument = 0;
encoding->m_NoOperationCommand = 0x40100;
encoding->m_FenceCommand = 0;
FlushWCCache();
spinTime = fence->Time;
}
else
{
while (KeWaitForSingleObject(&device->m_Miniport.m_BusyBlockEvent,
UserRequest, UserMode, FALSE, NULL) != 0)
{
}
return;
}
}
while (device->IsTimePending(spinTime))
{
}
return;
}
}
namespace D3D
{
/* Addresses used to compare prospective segment limits are integer byte
* offsets, not pointers formed outside the allocated circular push buffer. */
DWORD *CDevice::MakeSpace(
void)
{
DWORD *put = m_Pusher.m_pPut;
if (m_StateFlags & 4)
{
DWORD *base = (DWORD *)m_pPushBufferRecordResource->Data;
m_PushBufferRecordWrapSize += (DWORD)((BYTE *)put - (BYTE *)base);
m_Pusher.m_pPut = (DWORD *)m_pPushBufferRecordResource->Data;
return m_Pusher.m_pPut;
}
ULONG_PTR limit = (ULONG_PTR)put + m_PushSegmentSize;
if (limit + m_PushSegmentSize / 2 >= (ULONG_PTR)m_pPushLimit)
{
if ((ULONG_PTR)put + m_PushSegmentSize / 2 <= (ULONG_PTR)m_pPushLimit)
{
limit = (ULONG_PTR)m_pPushLimit;
}
else
{
m_PusherLastSize = (DWORD)((BYTE *)put - (BYTE *)m_pPushBase);
*m_Pusher.m_pPut = ((DWORD)m_pPushBase & 0x0fffffffUL) | 1;
while (HwGet() == m_pPushBase)
{
}
put = m_pPushBase;
limit = (ULONG_PTR)put + m_PushSegmentSize;
m_Pusher.m_pPut = put;
}
}
DWORD gpuTime = GpuTime();
DWORD *get = GpuGet();
if (get > put && (ULONG_PTR)get <= limit)
{
DWORD index = m_PusherLastSegment;
ULONG_PTR midpoint = (ULONG_PTR)put + m_PushBufferSize / 2;
DWORD fenceTime = m_PusherSegment[index].Time;
ULONG_PTR fence = (ULONG_PTR)m_PusherSegment[index].pEncoding;
BOOL blocked = FALSE;
while (Age(fenceTime) < Age(gpuTime))
{
if (fence < (ULONG_PTR)put) fence += m_PusherLastSize;
if (fence < midpoint)
{
BlockOnTime(fenceTime, TRUE);
blocked = TRUE;
break;
}
index = (index - 1) & 15;
if (index == m_PusherLastSegment) break;
fence = (ULONG_PTR)m_PusherSegment[index].pEncoding;
fenceTime = m_PusherSegment[index].Time;
}
if (!blocked)
{
do
{
BusyLoop();
get = GpuGet();
} while (get > put && (ULONG_PTR)get <= limit);
}
GpuGet();
}
m_Pusher.m_pThreshold = (DWORD *)(limit - 129 * sizeof(DWORD));
if (m_StateFlags & 0x800)
{
m_StateFlags |= 0x1000;
KickOff();
}
else
{
SetFence(1);
KickOff();
}
return m_Pusher.m_pPut;
}
}
+16 -5
View File
@@ -6,6 +6,7 @@
#include "resource_internal.h"
#include "pixeljar.h"
#include "kernel_memory.h"
#include "memory_internal.h"
#pragma code_seg("D3D")
namespace D3D
{
@@ -71,7 +72,7 @@ void WINAPI CleanPrivateData(
BYTE *WINAPI GetDataFromResource(
D3DResource *resource)
{
return (BYTE *)(resource->Data | 0x80000000UL);
return (BYTE *)XMETAL_MapToContiguousAddress(resource->Data);
}
void WINAPI DestroyResource(
D3DResource *resource)
@@ -86,19 +87,19 @@ void WINAPI DestroyResource(
{
if (resource->Common & D3DSURFACE_OWNSMEMORY)
{
MmFreeContiguousMemory((void *)(resource->Data | 0x80000000UL));
FreeContiguousMemory(XMETAL_MapToContiguousAddress(resource->Data));
}
}
else if (type == D3DCOMMON_TYPE_PUSHBUFFER)
{
if (!(resource->Common & D3DPUSHBUFFER_RUN_USING_CPU_COPY))
{
MmFreeContiguousMemory((void *)resource->Data);
FreeContiguousMemory((void *)resource->Data);
}
}
else if (type != D3DCOMMON_TYPE_INDEXBUFFER && type != D3DCOMMON_TYPE_FIXUP)
{
MmFreeContiguousMemory((void *)(resource->Data | 0x80000000UL));
FreeContiguousMemory(XMETAL_MapToContiguousAddress(resource->Data));
}
LocalFree(resource);
return;
@@ -272,7 +273,7 @@ void WINAPI D3DResource_Register(
}
else
{
resource->Data = (DWORD)memory & 0x03ffffffUL;
resource->Data = XMETAL_MapToPhysicalOffset(memory);
}
return;
}
@@ -358,3 +359,13 @@ void WINAPI D3DResource_FreePrivateData(
}
return;
}
namespace D3D
{
/* Original externally linked video-address conversion, not an emission shim. */
void *WINAPI GetVideoAddress(
DWORD address)
{
return XMETAL_MapToVideoAddress(address);
}
}
+2
View File
@@ -7,6 +7,8 @@ BOOL WINAPI IsResourceSetInDevice(
D3DResource *resource);
void WINAPI BlockOnResource(
D3DResource *resource);
void *WINAPI GetVideoAddress(
DWORD address);
BYTE *WINAPI GetDataFromResource(
D3DResource *resource);
void WINAPI InternalAddRef(
+62 -2
View File
@@ -6,6 +6,8 @@
#include "pixeljar.h"
#include "state_internal.h"
#include "math_internal.h"
#include "vshader_internal.h"
#include "push_float_internal.h"
#pragma code_seg("D3D")
namespace D3D
@@ -54,8 +56,8 @@ void __fastcall CommonSetAntiAliasingControl(
DWORD *push = device->StartPush();
push = CommonSetViewport(device, push);
Push1(push, 0x1d7c,
(D3D__RenderState[D3DRS_MULTISAMPLEMASK] << 16) |
(D3D__RenderState[D3DRS_MULTISAMPLEANTIALIAS] & 0xf));
(D3D__RenderState[D3DRS_MULTISAMPLEANTIALIAS] & 0xf) |
(D3D__RenderState[D3DRS_MULTISAMPLEMASK] << 16));
device->EndPush(push + 2);
return;
}
@@ -615,3 +617,61 @@ DWORD *__fastcall CommonSetTextureBumpEnv(
return push;
}
}
namespace D3D
{
/* January PDB S_LDATA32: KELVIN_BORDER, const float, original value +0.53125.
* Kept as a real constant owner, not an address-based identifier. */
const float KELVIN_BORDER = 0.53125f;
DWORD *__fastcall CommonSetViewport(
CDevice *device,
DWORD *push)
{
float clipNear;
float clipFar;
float xViewport = device->m_Viewport.X * device->m_SuperSampleScaleX + KELVIN_BORDER;
float yViewport = device->m_Viewport.Y * device->m_SuperSampleScaleY + KELVIN_BORDER;
if ((D3D__RenderState[D3DRS_MULTISAMPLETYPE] & 0x1000) &&
D3D__RenderState[D3DRS_MULTISAMPLEANTIALIAS] &&
device->m_pRenderTarget == &device->m_FrameBufferSurfaces[0])
{
xViewport -= 0.5f;
yViewport -= 0.5f;
}
if (device->m_pVertexShader->Flags & (VERTEXSHADER_PASSTHROUGH | VERTEXSHADER_PROGRAM))
{
if (!(device->m_StateFlags & 0x200))
{
float fm11 = device->m_Viewport.Width * device->m_SuperSampleScaleX * 0.5f;
float fm22 = device->m_Viewport.Height * device->m_SuperSampleScaleY * -0.5f;
float fm33 = (device->m_Viewport.MaxZ - device->m_Viewport.MinZ) * device->m_ZScale;
float fm43 = device->m_ZScale * device->m_Viewport.MinZ;
Push4fSafe(push, 0xa20, fm11 + xViewport, -fm22 + yViewport, fm43, 0.0f);
Push4fSafe(push + 5, 0xaf0, fm11, fm22, fm33, 0.0f);
push += 10;
}
clipNear = 0.0f;
clipFar = device->m_ZScale;
}
else
{
Push4fSafe(push, 0xa20, xViewport, yViewport, 0.0f, 0.0f);
push += 5;
clipFar = device->m_ZScale * device->m_Viewport.MaxZ;
clipNear = device->m_ZScale * device->m_Viewport.MinZ;
}
Push2f(push, 0x394, clipNear, clipFar);
return push + 3;
}
}
HRESULT WINAPI D3DDevice_SetTextureState_ParameterCheck(
DWORD stage,
D3DTEXTURESTAGESTATETYPE type,
DWORD value)
{
/* January's retail API reports success; validation exists only in checked
* builds. The entire original return sequence is independently compared. */
return S_OK;
}
+7
View File
@@ -3,6 +3,13 @@
#include "device_layout.h"
namespace D3D
{
/* Original device-state flag: pure devices do not retain shadow constants. */
enum DeviceStateFlags
{
STATE_PUREDEVICE = 0x10
};
void WINAPI CheckLightParameters(
const D3DLIGHT8 *light);
extern const DWORD g_DirtyFromRenderState[];
extern const DWORD g_TransformDirtyTable[];
extern const float g_LODBias2x[];
+9 -11
View File
@@ -2,6 +2,7 @@
#include "resource_internal.h"
#include "kernel_memory.h"
#include "surface_internal.h"
#include "memory_internal.h"
#pragma code_seg("D3D")
void WINAPI D3DSurface_GetDesc(
D3DSurface *surface,
@@ -48,7 +49,7 @@ HRESULT WINAPI CreateSurfaceOfTexture(
{
D3DSurface *surface = (D3DSurface *)LocalAlloc(LMEM_ZEROINIT, sizeof(*surface));
if (!surface) return E_OUTOFMEMORY;
surface->Data = (DWORD)data & 0x03ffffff;
surface->Data = XMETAL_MapToPhysicalOffset(data);
surface->Common = 0x01050001;
surface->Format = format;
surface->Size = size;
@@ -66,7 +67,7 @@ HRESULT WINAPI CreateVolumeOfTexture(
{
D3DVolume *volume = (D3DVolume *)LocalAlloc(LMEM_ZEROINIT, sizeof(*volume));
if (!volume) return E_OUTOFMEMORY;
volume->Data = (DWORD)data & 0x03ffffff;
volume->Data = XMETAL_MapToPhysicalOffset(data);
volume->Common = 0x01050001;
volume->Format = format;
volume->Size = 0;
@@ -88,14 +89,13 @@ HRESULT WINAPI CreateStandAloneSurface(
renderTarget, false, false, &encodedFormat, &encodedSize);
D3DSurface *surface = (D3DSurface *)LocalAlloc(LMEM_ZEROINIT, sizeof(*surface));
if (!surface) return E_OUTOFMEMORY;
void *memory = MmAllocateContiguousMemoryEx(allocationSize, 0, 0x03ffb000, 64,
PAGE_READWRITE | PAGE_WRITECOMBINE);
void *memory = D3D::AllocateContiguousMemory(allocationSize, 64);
if (!memory)
{
LocalFree(surface);
return E_OUTOFMEMORY;
}
surface->Data = (DWORD)memory & 0x03ffffff;
surface->Data = XMETAL_MapToPhysicalOffset(memory);
surface->Common = 0x81050001;
surface->Format = encodedFormat;
surface->Size = encodedSize;
@@ -114,10 +114,10 @@ void WINAPI InitializeSurface(
DWORD size,
void *memory)
{
surface->Data = (DWORD)memory & 0x03ffffff;
surface->Size = size;
surface->Data = XMETAL_MapToPhysicalOffset(memory);
surface->Common = D3DCOMMON_D3DCREATED | D3DCOMMON_TYPE_SURFACE | 1;
surface->Format = format;
surface->Size = size;
surface->Parent = NULL;
surface->Lock = 0;
return;
@@ -133,16 +133,14 @@ HRESULT WINAPI CreateSurfaceWithContiguousHeader(
format, 0, true, false, false, &encodedFormat, &encodedSize);
/* The original allocation reserves an aligned 64-byte header prefix.
* The returned surface occupies only the first sizeof(D3DSurface) bytes. */
D3DSurface *surface = (D3DSurface *)MmAllocateContiguousMemoryEx(
allocationSize + SURFACE_CONTIGUOUS_HEADER_BYTES, 0, 0x03ffb000,
D3DSURFACE_ALIGNMENT, PAGE_READWRITE | PAGE_WRITECOMBINE);
D3DSurface *surface = (D3DSurface *)D3D::AllocateContiguousMemory(allocationSize + SURFACE_CONTIGUOUS_HEADER_BYTES, D3DSURFACE_ALIGNMENT);
if (!surface)
{
return E_OUTOFMEMORY;
}
void *pixels = (BYTE *)surface + SURFACE_CONTIGUOUS_HEADER_BYTES;
surface->Common = D3DCOMMON_D3DCREATED | D3DCOMMON_TYPE_SURFACE | D3DSURFACE_OWNSMEMORY | 1;
surface->Data = (DWORD)pixels & 0x03ffffff;
surface->Data = XMETAL_MapToPhysicalOffset(pixels);
surface->Format = encodedFormat;
surface->Size = encodedSize;
surface->Parent = NULL;
+3 -3
View File
@@ -1,5 +1,6 @@
#include "pixeljar.h"
#include "kernel_memory.h"
#include "memory_internal.h"
#pragma code_seg("D3D")
void WINAPI D3DTexture_GetLevelDesc(
D3DTexture *texture,
@@ -82,14 +83,13 @@ HRESULT WINAPI CreateTexture(
if (usage & 0x10000) encodedFormat &= ~D3DFORMAT_BORDERSOURCE_COLOR;
D3DBaseTexture *texture = (D3DBaseTexture *)LocalAlloc(LMEM_ZEROINIT, sizeof(*texture));
if (!texture) return E_OUTOFMEMORY;
void *memory = MmAllocateContiguousMemoryEx(allocationSize, 0, 0x03ffb000,
128, PAGE_READWRITE | PAGE_WRITECOMBINE);
void *memory = D3D::AllocateContiguousMemory(allocationSize, 128);
if (!memory)
{
LocalFree(texture);
return E_OUTOFMEMORY;
}
texture->Data = (DWORD)memory & 0x03ffffff;
texture->Data = XMETAL_MapToPhysicalOffset(memory);
texture->Common = 0x01040001;
texture->Format = encodedFormat;
texture->Size = encodedSize;
+92
View File
@@ -7,6 +7,7 @@
#include "resource_internal.h"
#include "state_internal.h"
#include "math_internal.h"
#include "push_float_internal.h"
#pragma code_seg("D3D")
namespace D3D
{
@@ -728,3 +729,94 @@ void WINAPI D3DDevice_SetVertexShader(
}
return;
}
namespace D3D
{
/* Same January semantic constant as state.cpp, separately owned in this TU. */
const float KELVIN_BORDER = 0.53125f;
void __fastcall CommonSetPassthroughProgram(
CDevice *device)
{
if (device->m_pVertexShader->Flags & VERTEXSHADER_PASSTHROUGH)
{
const DWORD *program;
DWORD size;
if (D3D__RenderState[D3DRS_FOGTABLEMODE] == D3DFOG_NONE)
{
program = g_PassthruProgramSpecularFog;
size = sizeof(g_PassthruProgramSpecularFog) / sizeof(DWORD);
}
else if (device->m_StateFlags & 2)
{
size = sizeof(g_PassthruProgramZFog) / sizeof(DWORD);
program = g_PassthruProgramZFog;
}
else
{
program = g_PassthruProgramWFog;
size = sizeof(g_PassthruProgramWFog) / sizeof(DWORD);
}
DWORD *push = device->StartPush(size + 30);
Push1(push, 0x1ea4, 0);
PushCount(push + 2, 0xb80, 8);
float wScale = D3D__RenderState[D3DRS_ZENABLE] == D3DZB_USEW ?
device->m_ZScale * device->m_InverseWFar : 1.0f;
/* The eight-word constant method is already written above. */
StoreFloat4(push + 3, device->m_SuperSampleScaleX, device->m_SuperSampleScaleY, device->m_ZScale, wScale);
if ((D3D__RenderState[D3DRS_MULTISAMPLETYPE] & 0x1000) &&
D3D__RenderState[D3DRS_MULTISAMPLEANTIALIAS] &&
device->m_pRenderTarget == &device->m_FrameBufferSurfaces[0])
{
StoreFloatPair(push + 7, KELVIN_BORDER - 0.5f, KELVIN_BORDER - 0.5f);
}
else
{
StoreFloatPair(push + 7, KELVIN_BORDER, KELVIN_BORDER);
}
push[9] = 0;
push[10] = 0;
Push1(push + 11, 0x1e9c, 0);
push = ParseProgram(push + 13, program, size);
device->EndPush(push);
}
return;
}
}
namespace D3D
{
extern "C"
void WINAPI D3DDevice_SetVertexShaderConstant(
INT index,
const void *constantData,
DWORD constantCount)
{
CDevice *device = g_pDevice;
index += 96;
int dwords = (int)(constantCount * 4);
if (!(device->m_StateFlags & STATE_PUREDEVICE))
{
memcpy(&device->m_VertexShaderConstants[index][0], constantData,
dwords * sizeof(DWORD));
}
DWORD *push = device->StartPush(dwords + 26);
Push1(push, 0x1ea4, index);
push += 2;
const BYTE *source = (const BYTE *)constantData;
/* Valid constants occupy the caller-backed original register range. Each
* packet is at most eight four-word registers; count and indices are bounded. */
while (dwords > 32)
{
PushCount(push, 0x0b80, 32);
memcpy(push + 1, source, 32 * sizeof(DWORD));
push += 33;
source += 32 * sizeof(DWORD);
dwords -= 32;
}
PushCount(push, 0x0b80, dwords);
memcpy(push + 1, source, dwords * sizeof(DWORD));
push += dwords + 1;
device->EndPush(push);
return;
}
}
+3
View File
@@ -33,6 +33,9 @@ struct Stream
D3DVertexBuffer *pVertexBuffer; /* +0x8 */
};
typedef char Stream_size_check[sizeof(Stream) == 12 ? 1 : -1];
extern const DWORD g_PassthruProgramSpecularFog[48];
extern const DWORD g_PassthruProgramZFog[44];
extern const DWORD g_PassthruProgramWFog[48];
extern VertexShader g_FvfVertexShader;
extern Stream g_Stream[16];
extern const DWORD g_TextureCount[4];
+47
View File
@@ -0,0 +1,47 @@
#ifndef D3D8_XMETAL_INTERNAL_H
#define D3D8_XMETAL_INTERNAL_H
#include "device_layout.h"
/* January's PDB describes these header helpers as module-local procedures.
* This is the actual raw packet layer used by the D3D convenience wrappers.
* Count fields are disjoint from the method; payloads are NV2A commands.
* Internal linkage permits ordinary VC7 private calling-convention optimization.
*/
extern "C"
{
static __inline void WINAPI XMETAL_EndPush(
_XMETAL_PushBuffer *buffer,
DWORD *put)
{
buffer->m_pPut = put;
return;
}
static __inline void WINAPI XMETAL_Push1(
DWORD *push,
DWORD method,
DWORD value)
{
push[0] = method + (1 << 18);
push[1] = value;
return;
}
static __inline void WINAPI XMETAL_Push2(
DWORD *push,
DWORD method,
DWORD first,
DWORD second)
{
push[0] = method + (2 << 18);
push[1] = first;
push[2] = second;
return;
}
static __inline void WINAPI XMETAL_PushCount(
DWORD *push,
DWORD method,
DWORD count)
{
push[0] = method + (count << 18);
return;
}
}
#endif
+39
View File
@@ -0,0 +1,39 @@
#ifndef D3D8_XMETAL_MEMORY_INTERNAL_H
#define D3D8_XMETAL_MEMORY_INTERNAL_H
#include "device_layout.h"
/* Original module-local XMETAL address helpers. In this retail build the
* contiguous-memory diagnostic has no instructions other than its return.
* The physical map is the January 64 MiB map, not a later SDK aperture. */
extern "C"
{
static __inline void WINAPI XMETAL_DebugVerifyContiguous(
void *memory)
{
return;
}
/* Original retail physical-address diagnostic is also an empty check. */
static __inline void WINAPI XMETAL_DebugVerifyPhysical(
DWORD address)
{
return;
}
static __inline void *WINAPI XMETAL_MapToContiguousAddress(
DWORD address)
{
XMETAL_DebugVerifyPhysical(address);
return (void *)(address | 0x80000000UL);
}
static __inline void *WINAPI XMETAL_MapToVideoAddress(
DWORD address)
{
XMETAL_DebugVerifyPhysical(address);
return (void *)(address | 0x80000000UL);
}
static __inline DWORD WINAPI XMETAL_MapToPhysicalOffset(
void *memory)
{
XMETAL_DebugVerifyContiguous(memory);
return (DWORD)memory & 0x03ffffffUL;
}
}
#endif