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.

234 lines
6.0 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. D3D_ERR("Bad pointer given");
  48. return DDERR_OUTOFMEMORY;
  49. }
  50. if (size > 0) {
  51. if (p) {
  52. p = realloc_function(p, size);
  53. if (p == NULL)
  54. return (DDERR_OUTOFMEMORY);
  55. } else
  56. return D3DMalloc(p_inout, size);
  57. } else if (size == 0) {
  58. D3DFree(p);
  59. p = NULL;
  60. } else
  61. return (DDERR_INVALIDPARAMS);
  62. *p_inout = p;
  63. return (err);
  64. }
  65. #undef DPF_MODNAME
  66. #define DPF_MODNAME "D3DFree"
  67. VOID D3DAPI D3DFree(LPVOID p)
  68. {
  69. if (p == NULL) return;
  70. if (!VALID_DWORD_PTR(p)) {
  71. D3D_ERR("invalid pointer");
  72. return;
  73. }
  74. if (p) {
  75. free_function(p);
  76. }
  77. }
  78. #define CACHE_LINE 32
  79. HRESULT MallocAligned(void** p_return, size_t size)
  80. {
  81. char* p;
  82. size_t offset;
  83. HRESULT error;
  84. if (!p_return)
  85. return DDERR_INVALIDPARAMS;
  86. if (size > 0) {
  87. if ((error = D3DMalloc((void**) &p, size + CACHE_LINE)) != DD_OK)
  88. {
  89. *p_return = NULL;
  90. return error;
  91. }
  92. offset = (size_t)(CACHE_LINE - ((ULONG_PTR)p & (CACHE_LINE - 1)));
  93. p += offset;
  94. ((size_t*)p)[-1] = offset;
  95. } else
  96. p = NULL;
  97. *p_return = p;
  98. return DD_OK;
  99. }
  100. void FreeAligned(void* p)
  101. {
  102. if (p) {
  103. size_t offset = ((size_t*)p)[-1];
  104. p = (void*) ((unsigned char*)p - offset);
  105. D3DFree(p);
  106. }
  107. }
  108. HRESULT ReallocAligned(void** p_inout, size_t size)
  109. {
  110. char* p = (char*)*p_inout;
  111. HRESULT error;
  112. if (!p_inout)
  113. return DDERR_INVALIDPARAMS;
  114. if (size > 0) {
  115. if (p) {
  116. size_t old_offset = ((size_t*)p)[-1];
  117. size_t new_offset;
  118. p -= old_offset;
  119. if ((error = D3DRealloc((void**) &p, size + CACHE_LINE)) != DD_OK)
  120. return error;
  121. new_offset = (size_t)(CACHE_LINE - ((ULONG_PTR)p & (CACHE_LINE - 1)));
  122. if (old_offset != new_offset)
  123. memmove(p + new_offset, p + old_offset, size);
  124. p += new_offset;
  125. ((size_t*)p)[-1] = new_offset;
  126. } else
  127. return MallocAligned(p_inout, size);
  128. } else if (size == 0) {
  129. FreeAligned(p);
  130. p = NULL;
  131. } else
  132. return DDERR_INVALIDPARAMS;
  133. *p_inout = p;
  134. return DD_OK;
  135. }
  136. //----------------------------------------------------------------------------
  137. // Growing aligned buffer implementation.
  138. //
  139. HRESULT CAlignedBuffer32::Grow(DWORD growSize)
  140. {
  141. if (allocatedBuf)
  142. D3DFree(allocatedBuf);
  143. size = growSize;
  144. if (D3DMalloc(&allocatedBuf, size + 31) != DD_OK)
  145. {
  146. allocatedBuf = 0;
  147. alignedBuf = 0;
  148. size = 0;
  149. return DDERR_OUTOFMEMORY;
  150. }
  151. alignedBuf = (LPVOID)(((ULONG_PTR)allocatedBuf + 31 ) & ~31);
  152. return D3D_OK;
  153. }
  154. #undef DPF_MODNAME
  155. #define DPF_MODNAME "CBufferDDS::Grow"
  156. //----------------------------------------------------------------------
  157. // Growing buffer using DDS implementation.
  158. //
  159. HRESULT CBufferDDS::Grow(LPDIRECT3DDEVICEI lpDevI, DWORD growSize)
  160. {
  161. DWORD dwRefCnt = 1;
  162. if (growSize <= size)
  163. return D3D_OK;
  164. if (allocatedBuf)
  165. {
  166. // Save reference count before deleting
  167. dwRefCnt = allocatedBuf->AddRef() - 1;
  168. // Release till gone!
  169. while (allocatedBuf->Release());
  170. allocatedBuf = NULL;
  171. }
  172. size = growSize;
  173. DDSURFACEDESC2 ddsd;
  174. memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
  175. ddsd.dwSize = sizeof(DDSURFACEDESC2);
  176. ddsd.dwFlags = DDSD_WIDTH | DDSD_CAPS;
  177. ddsd.dwWidth = size + 31;
  178. ddsd.ddsCaps.dwCaps = DDSCAPS_EXECUTEBUFFER | DDSCAPS_SYSTEMMEMORY;
  179. LPDIRECTDRAWSURFACE7 lpDDS7;
  180. HRESULT ret = lpDevI->lpDirect3DI->lpDD7->CreateSurface(&ddsd, &lpDDS7, NULL);
  181. if (ret != DD_OK)
  182. {
  183. D3D_ERR("Failed to allocate Vertex Buffer");
  184. size = 0;
  185. return ret;
  186. }
  187. ret = lpDDS7->QueryInterface(IID_IDirectDrawSurface, (LPVOID*)&allocatedBuf);
  188. if (ret != DD_OK)
  189. {
  190. D3D_ERR("failed to QI for DDS1");
  191. lpDDS7->Release();
  192. size = 0;
  193. return ret;
  194. }
  195. ret = lpDDS7->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL);
  196. if (ret != DD_OK)
  197. {
  198. D3D_ERR("Could not lock system memory Vertex Buffer.");
  199. lpDDS7->Release();
  200. allocatedBuf->Release();
  201. allocatedBuf = NULL;
  202. size = 0;
  203. return ret;
  204. }
  205. lpDDS7->Release();
  206. alignedBuf = ddsd.lpSurface;
  207. // Restore reference count
  208. while (--dwRefCnt)
  209. allocatedBuf->AddRef();
  210. return D3D_OK;
  211. }