mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-18 23:00:26 +02:00
d3d8: reconcile clean continuation 015 source
This commit is contained in:
1 parent
641e146696
commit
dbcea3d616
31 files changed
+1547
-799
No files matched your search
+4
-4
@@ -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.
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -6,7 +6,7 @@
|
||||
#pragma code_seg("D3D")
|
||||
namespace D3D
|
||||
{
|
||||
__inline BOOL CheckDisplayFormat(
|
||||
__inline BOOL WINAPI CheckDisplayFormat(
|
||||
D3DFORMAT format)
|
||||
{
|
||||
return g_TextureFormat[format] & 0x80;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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(¬ifiers[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(¬ifiers[0]))
|
||||
while (initial[0] == notifiers[0].timeStamp.nanoseconds[0] &&
|
||||
initial[1] == notifiers[0].timeStamp.nanoseconds[1])
|
||||
{
|
||||
BusyLoop();
|
||||
}
|
||||
notified = ReadNotificationTime(¬ifiers[0]);
|
||||
while (ReadNotificationTime(¬ifiers[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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large.
Load diff
+68
-68
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user