ReactOS 0.4.16-dev-2232-gc2aaa52
dxgallocator.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactX Graphics Legacy Kernel
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: DirectDraw video memory allocator
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8#include <dxg_int.h>
9
13 _In_ LPVMEMHEAP pvmh,
16 _Out_opt_ LPDWORD AllocSize,
18 _Out_opt_ LPDWORD ResolvedPitch)
19{
20 FLATPTR MemPtr;
21 DWORD RequiredBytes;
22 DWORD CurrentPos;
23
24 if (!pvmh)
25 {
26 if (AllocSize)
27 *AllocSize = 0;
28 return (FLATPTR)NULL;
29 }
30
31 /* Retrieve memory boundaries from temporary storage */
32 FLATPTR MemBase = (FLATPTR)pvmh->freeList;
33 FLATPTR MemLimit = (FLATPTR)pvmh->allocList;
34
35 if (!MemBase || !MemLimit || MemLimit <= MemBase)
36 {
37 DbgPrint("No valid video memory range\n");
38 if (AllocSize)
39 *AllocSize = 0;
40 return (FLATPTR)NULL;
41 }
42
43 CurrentPos = pvmh->dwCommitedSize;
44 CurrentPos = ALIGN_UP(CurrentPos, sizeof(ULONG));
45
46 if (pvmh->dwFlags & VMEMHEAP_LINEAR)
47 {
48 /* Handle linear memory allocation */
49 RequiredBytes = Width;
50 }
51 else
52 {
53 /* Handle rectangular memory allocation */
54 Width = pvmh->stride ? pvmh->stride : Width;
55 RequiredBytes = Width * Height;
56 }
57 MemPtr = MemBase + CurrentPos;
58
59 if (MemPtr + RequiredBytes > MemLimit)
60 {
61 DbgPrint("Out of memory\n");
62 if (AllocSize)
63 *AllocSize = 0;
64 return (FLATPTR)NULL;
65 }
66
67 pvmh->dwCommitedSize = CurrentPos + RequiredBytes;
68
69 if (ResolvedPitch)
70 *ResolvedPitch = (LONG)Width;
71 if (AllocSize)
72 *AllocSize = RequiredBytes;
73
74 return MemPtr;
75}
76
77/*
78 * Allocates memory from a DirectDraw video memory heap
79 */
83 _In_ LPVIDMEM DdrawVidMem,
87 _Out_opt_ LPDWORD ResolvedPitch,
88 _Out_ PDWORD AllocSize)
89{
91 DWORD ActualSize = 0;
92
93 if (!DdrawVidMem || !DdrawVidMem->lpHeap)
94 {
95 if (AllocSize)
96 *AllocSize = 0;
97 return (FLATPTR)NULL;
98 }
99
100 if ((DdrawVidMem->dwFlags & VIDMEM_ISNONLOCAL) &&
101 !DdrawVidMem->lpHeap->pvPhysRsrv)
102 {
103 if (AllocSize)
104 *AllocSize = 0;
105 return (FLATPTR)NULL;
106 }
107
108 /* Determine memory region boundaries */
109 FLATPTR MemBegin = DdrawVidMem->fpStart;
110 FLATPTR MemEnd;
111
112 if (DdrawVidMem->dwFlags & VIDMEM_ISLINEAR)
113 {
114 MemEnd = DdrawVidMem->fpEnd;
115 }
116 else if (DdrawVidMem->dwFlags & VIDMEM_ISRECTANGULAR)
117 {
118 MemEnd = MemBegin + (DdrawVidMem->dwWidth * DdrawVidMem->dwHeight);
119 }
120 else
121 {
122 MemEnd = DdrawVidMem->fpEnd;
123 }
124
125 if (!MemBegin)
126 {
127 if (AllocSize)
128 *AllocSize = 0;
129 return (FLATPTR)NULL;
130 }
131
132 /* Fallback to heap size if end address is invalid */
133 if (!MemEnd || MemEnd <= MemBegin)
134 {
135 if (DdrawVidMem->lpHeap && DdrawVidMem->lpHeap->dwTotalSize > 0)
136 {
137 MemEnd = MemBegin + DdrawVidMem->lpHeap->dwTotalSize;
138 }
139 else
140 {
141 if (AllocSize)
142 *AllocSize = 0;
143 return (FLATPTR)NULL;
144 }
145 }
146
147 /*
148 * In DxgKrnl we are given APIs to allocate ranges for DMA.
149 * In Vista this is used for trying to deal with ddraw on a dedicated surface
150 * outside of DWMs... control.
151 *
152 * In legacy DirectX these ranges are passed from the driver as valid areas to do
153 * allocation from, depending on this dxg driver to do the tracking.
154 * We don't care much to replicate ALL of this yet.
155 */
156 FLATPTR SavedBegin = (FLATPTR)DdrawVidMem->lpHeap->freeList;
157 FLATPTR SavedEnd = (FLATPTR)DdrawVidMem->lpHeap->allocList;
158 DdrawVidMem->lpHeap->freeList = (LPVOID)MemBegin;
159 DdrawVidMem->lpHeap->allocList = (LPVOID)MemEnd;
160
161 Result = DdrawMemAlloc(DdrawVidMem->lpHeap, Width, Height, &ActualSize,
162 Alignment, ResolvedPitch);
163
164 if (!Result)
165 {
166 if (AllocSize)
167 *AllocSize = 0;
168 return Result;
169 }
170
171 DdrawVidMem->lpHeap->freeList = (LPVOID)SavedBegin;
172 DdrawVidMem->lpHeap->allocList = (LPVOID)SavedEnd;
173
174 if (AllocSize)
175 *AllocSize = ActualSize;
176
177 return Result;
178}
179
181NTAPI
183 LPVIDMEM DdrawVidMem,
184 DWORD Width,
187 LPDWORD ResolvedPitch)
188{
189 DWORD SizeOut = 0;
190
191 if (!DdrawVidMem || !DdrawVidMem->lpHeap ||
192 (DdrawVidMem->dwFlags & VIDMEM_HEAPDISABLED))
193 {
194 return (FLATPTR)NULL;
195 }
196
197 if (DdrawVidMem->dwFlags & VIDMEM_ISNONLOCAL)
198 {
199 if (!DdrawVidMem->lpHeap->pvPhysRsrv)
200 return (FLATPTR)NULL;
201 DbgPrint("AGP memory not supported\n");
202 return (FLATPTR)NULL;
203 }
204
205 return DxDdHeapDdrawMemAlloc(DdrawVidMem, Width, Height,
206 Alignment, ResolvedPitch, &SizeOut);
207}
#define VIDMEM_HEAPDISABLED
Definition: ddrawi.h:213
#define VIDMEM_ISLINEAR
Definition: ddrawi.h:208
#define VIDMEM_ISNONLOCAL
Definition: ddrawi.h:211
#define VIDMEM_ISRECTANGULAR
Definition: ddrawi.h:209
ULONG_PTR FLATPTR
Definition: ddrawint.h:76
#define NULL
Definition: types.h:112
#define VMEMHEAP_LINEAR
Definition: dmemmgr.h:46
FLATPTR NTAPI DxDdHeapVidMemAllocAligned(LPVIDMEM DdrawVidMem, DWORD Width, DWORD Height, LPSURFACEALIGNMENT Alignment, LPDWORD ResolvedPitch)
Definition: dxgallocator.c:182
FLATPTR WINAPI DdrawMemAlloc(_In_ LPVMEMHEAP pvmh, _In_ DWORD Width, _In_ DWORD Height, _Out_opt_ LPDWORD AllocSize, _In_opt_ LPSURFACEALIGNMENT Alignment, _Out_opt_ LPDWORD ResolvedPitch)
Definition: dxgallocator.c:12
FLATPTR WINAPI DxDdHeapDdrawMemAlloc(_In_ LPVIDMEM DdrawVidMem, _In_ DWORD Width, _In_ DWORD Height, _In_opt_ LPSURFACEALIGNMENT Alignment, _Out_opt_ LPDWORD ResolvedPitch, _Out_ PDWORD AllocSize)
Definition: dxgallocator.c:82
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DbgPrint
Definition: hal.h:12
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define LPVOID
Definition: nt_native.h:45
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
LPVMEMHEAP lpHeap
Definition: ddrawi.h:203
DWORD dwFlags
Definition: ddrawi.h:194
LPVOID pvPhysRsrv
Definition: dmemmgr.h:131
#define NTAPI
Definition: typedefs.h:36
uint32_t * LPDWORD
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
#define WINAPI
Definition: msvc.h:6
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409