Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
7.7 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: d3dmem.c
  6. * Content: Direct3D mem allocation
  7. *@@BEGIN_MSINTERNAL
  8. *
  9. * History:
  10. * Date By Reason
  11. * ==== == ======
  12. * 10/12/95 stevela Initial rev with this header.
  13. *@@END_MSINTERNAL
  14. *
  15. ***************************************************************************/
  16. #include "pch.cpp"
  17. #pragma hdrstop
  18. static D3DMALLOCFUNCTION malloc_function = (D3DMALLOCFUNCTION) MemAlloc;
  19. static D3DREALLOCFUNCTION realloc_function = (D3DREALLOCFUNCTION) MemReAlloc;
  20. static D3DFREEFUNCTION free_function = MemFree;
  21. #undef DPF_MODNAME
  22. #define DPF_MODNAME "D3DMalloc"
  23. HRESULT D3DAPI D3DMalloc(LPVOID* p_return, size_t size)
  24. {
  25. void* p;
  26. if (!VALID_OUTPTR(p_return)) {
  27. D3D_ERR("Bad pointer given");
  28. return DDERR_OUTOFMEMORY;
  29. }
  30. if (size > 0) {
  31. p = malloc_function(size);
  32. if (p == NULL)
  33. return (DDERR_OUTOFMEMORY);
  34. } else {
  35. p = NULL;
  36. }
  37. *p_return = p;
  38. return (D3D_OK);
  39. }
  40. #undef DPF_MODNAME
  41. #define DPF_MODNAME "D3DRealloc"
  42. HRESULT D3DAPI D3DRealloc(LPVOID* p_inout, size_t size)
  43. {
  44. void* p = *p_inout;
  45. HRESULT err = D3D_OK;
  46. if (!VALID_OUTPTR(p_inout))
  47. {
  48. D3D_ERR("Bad pointer given");
  49. return DDERR_OUTOFMEMORY;
  50. }
  51. if (size > 0)
  52. {
  53. if (p)
  54. {
  55. p = realloc_function(p, size);
  56. if (p == NULL)
  57. return (DDERR_OUTOFMEMORY);
  58. }
  59. else
  60. return D3DMalloc(p_inout, size);
  61. }
  62. else
  63. if (size == 0)
  64. {
  65. D3DFree(p);
  66. p = NULL;
  67. }
  68. else
  69. return (DDERR_INVALIDPARAMS);
  70. *p_inout = p;
  71. return (err);
  72. }
  73. #undef DPF_MODNAME
  74. #define DPF_MODNAME "D3DFree"
  75. VOID D3DAPI D3DFree(LPVOID p)
  76. {
  77. if (p == NULL) return;
  78. if (!VALID_DWORD_PTR(p)) {
  79. D3D_ERR("invalid pointer");
  80. return;
  81. }
  82. if (p) {
  83. free_function(p);
  84. }
  85. }
  86. #define CACHE_LINE 32
  87. HRESULT MallocAligned(void** p_return, size_t size)
  88. {
  89. char* p;
  90. size_t offset;
  91. HRESULT error;
  92. if (!p_return)
  93. return DDERR_INVALIDPARAMS;
  94. if (size > 0) {
  95. if ((error = D3DMalloc((void**) &p, size + CACHE_LINE)) != DD_OK)
  96. {
  97. *p_return = NULL;
  98. return error;
  99. }
  100. offset = CACHE_LINE - (DWORD)((ULONG_PTR)p & (CACHE_LINE - 1));
  101. p += offset;
  102. ((size_t*)p)[-1] = offset;
  103. } else
  104. p = NULL;
  105. *p_return = p;
  106. return DD_OK;
  107. }
  108. void FreeAligned(void* p)
  109. {
  110. if (p) {
  111. size_t offset = ((size_t*)p)[-1];
  112. p = (void*) ((unsigned char*)p - offset);
  113. D3DFree(p);
  114. }
  115. }
  116. HRESULT ReallocAligned(void** p_inout, size_t size)
  117. {
  118. char* p = (char*)*p_inout;
  119. HRESULT error;
  120. if (!p_inout)
  121. return DDERR_INVALIDPARAMS;
  122. if (size > 0) {
  123. if (p) {
  124. size_t old_offset = ((size_t*)p)[-1];
  125. size_t new_offset;
  126. p -= old_offset;
  127. if ((error = D3DRealloc((void**) &p, size + CACHE_LINE)) != DD_OK)
  128. return error;
  129. new_offset = CACHE_LINE - (DWORD)((ULONG_PTR)p & (CACHE_LINE - 1));
  130. if (old_offset != new_offset)
  131. memmove(p + new_offset, p + old_offset, size);
  132. p += new_offset;
  133. ((size_t*)p)[-1] = new_offset;
  134. } else
  135. return MallocAligned(p_inout, size);
  136. } else if (size == 0) {
  137. FreeAligned(p);
  138. p = NULL;
  139. } else
  140. return DDERR_INVALIDPARAMS;
  141. *p_inout = p;
  142. return DD_OK;
  143. }
  144. //----------------------------------------------------------------------------
  145. // Growing aligned buffer implementation.
  146. //
  147. HRESULT CAlignedBuffer32::Grow(DWORD growSize)
  148. {
  149. if (allocatedBuf)
  150. D3DFree(allocatedBuf);
  151. size = growSize;
  152. if (D3DMalloc(&allocatedBuf, size + 31) != DD_OK)
  153. {
  154. allocatedBuf = 0;
  155. alignedBuf = 0;
  156. size = 0;
  157. return DDERR_OUTOFMEMORY;
  158. }
  159. alignedBuf = (LPVOID)(((ULONG_PTR)allocatedBuf + 31 ) & ~31);
  160. return D3D_OK;
  161. }
  162. #undef DPF_MODNAME
  163. #define DPF_MODNAME "CBufferDDS::Grow"
  164. //----------------------------------------------------------------------
  165. // Growing buffer using DDS implementation.
  166. //
  167. HRESULT CBufferDDS::Grow(LPDIRECT3DDEVICEI lpDevI, DWORD growSize)
  168. {
  169. DWORD dwRefCnt = 1;
  170. if (growSize <= size)
  171. return D3D_OK;
  172. if (allocatedBuf)
  173. {
  174. // Save reference count before deleting
  175. dwRefCnt = allocatedBuf->AddRef() - 1;
  176. // Release till gone!
  177. while (allocatedBuf->Release());
  178. }
  179. size = growSize;
  180. DDSURFACEDESC2 ddsd;
  181. memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
  182. ddsd.dwSize = sizeof(DDSURFACEDESC2);
  183. ddsd.dwFlags = DDSD_WIDTH | DDSD_CAPS;
  184. ddsd.dwWidth = size + 31;
  185. ddsd.ddsCaps.dwCaps = DDSCAPS_EXECUTEBUFFER | DDSCAPS_SYSTEMMEMORY;
  186. LPDIRECTDRAWSURFACE4 lpDDS4;
  187. HRESULT ret = lpDevI->lpDirect3DI->lpDD4->CreateSurface(&ddsd, &lpDDS4, NULL);
  188. if (ret != DD_OK)
  189. {
  190. D3D_ERR("Failed to allocate Vertex Buffer");
  191. size = 0;
  192. return ret;
  193. }
  194. ret = lpDDS4->QueryInterface(IID_IDirectDrawSurface, (LPVOID*)&allocatedBuf);
  195. if (ret != DD_OK)
  196. {
  197. D3D_ERR("failed to QI for DDS1");
  198. allocatedBuf = 0;
  199. size = 0;
  200. return ret;
  201. }
  202. ret = lpDDS4->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL);
  203. if (ret != DD_OK)
  204. {
  205. D3D_ERR("Could not lock system memory Vertex Buffer.");
  206. allocatedBuf = 0;
  207. size = 0;
  208. return ret;
  209. }
  210. lpDDS4->Release();
  211. alignedBuf = ddsd.lpSurface;
  212. // Restore reference count
  213. while (--dwRefCnt)
  214. allocatedBuf->AddRef();
  215. return D3D_OK;
  216. }
  217. //----------------------------------------------------------------------
  218. // Growing aligned vertex buffer implementation.
  219. //
  220. HRESULT CBufferVB::Grow(LPDIRECT3DDEVICEI lpDevI, DWORD growSize)
  221. {
  222. D3DVERTEXBUFFERDESC vbdesc = {sizeof(D3DVERTEXBUFFERDESC), 0, D3DFVF_TLVERTEX, 0};
  223. DWORD dwRefCnt = 1;
  224. // Note the assumption that base is not zero only for DP2 HAL
  225. if (IS_DP2HAL_DEVICE(lpDevI))
  226. {
  227. CDirect3DDeviceIDP2 *dev = static_cast<CDirect3DDeviceIDP2*>(lpDevI);
  228. HRESULT ret;
  229. ret = dev->FlushStates(growSize);
  230. if (ret != D3D_OK)
  231. {
  232. D3D_ERR("Error trying to render batched commands in CBufferVB::Grow");
  233. return ret;
  234. }
  235. base = 0;
  236. }
  237. if (growSize <= size)
  238. return D3D_OK;
  239. if (allocatedBuf)
  240. {
  241. if (IS_DP2HAL_DEVICE(lpDevI))
  242. {
  243. CDirect3DDeviceIDP2 &dev = *static_cast<CDirect3DDeviceIDP2*>(lpDevI);
  244. if (dev.lpDP2CurrBatchVBI == allocatedBuf)
  245. {
  246. dev.lpDP2CurrBatchVBI->Release();
  247. dev.lpDP2CurrBatchVBI = NULL;
  248. }
  249. }
  250. // Save reference count before deleting
  251. dwRefCnt = allocatedBuf->AddRef() - 1;
  252. // Release till gone!
  253. while (allocatedBuf->Release());
  254. }
  255. vbdesc.dwNumVertices = (growSize + 31) / sizeof(D3DTLVERTEX);
  256. size = vbdesc.dwNumVertices * sizeof(D3DTLVERTEX);
  257. if (!IS_DP2HAL_DEVICE(lpDevI) || !IS_HW_DEVICE(lpDevI))
  258. {
  259. vbdesc.dwCaps = D3DVBCAPS_SYSTEMMEMORY;
  260. }
  261. if (lpDevI->lpDirect3DI->CreateVertexBufferI(&vbdesc, &allocatedBuf, D3DDP_DONOTCLIP | D3DVBFLAGS_CREATEMULTIBUFFER) != DD_OK)
  262. {
  263. allocatedBuf = 0;
  264. size = 0;
  265. return DDERR_OUTOFMEMORY;
  266. }
  267. // Restore reference count
  268. while (--dwRefCnt)
  269. allocatedBuf->AddRef();
  270. allocatedBuf->Lock(DDLOCK_WAIT, &alignedBuf, NULL);
  271. return D3D_OK;
  272. }