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.

1312 lines
44 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dbuff.c
  8. *
  9. //@@BEGIN_DDKSPLIT
  10. * Content: Main context callbacks for D3D videomemory buffers
  11. //@@END_DDKSPLIT
  12. *
  13. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  14. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  15. \*****************************************************************************/
  16. #include "glint.h"
  17. #include "dma.h"
  18. #include "tag.h"
  19. //@@BEGIN_DDKSPLIT
  20. #if DX7_VERTEXBUFFERS
  21. #define _32_KBYTES ( 32 * 1024 )
  22. //-----------------------------------------------------------------------------
  23. // in-the-file nonexported forward declarations
  24. //-----------------------------------------------------------------------------
  25. BOOL __EB_RemoveFromBufferQueue(P3_THUNKEDDATA* pThisDisplay,
  26. P3_VERTEXBUFFERINFO* pVictim);
  27. void __EB_Wait(P3_THUNKEDDATA* pThisDisplay, P3_VERTEXBUFFERINFO* pBuffer);
  28. #if DBG
  29. //-----------------------------------------------------------------------------
  30. //
  31. // __EB_DisplayHeapInfo
  32. //
  33. // A debug function. Displays the current buffer queue
  34. //
  35. //-----------------------------------------------------------------------------
  36. void
  37. __EB_DisplayHeapInfo(
  38. int DebugLevel,
  39. P3_THUNKEDDATA* pThisDisplay)
  40. {
  41. DWORD dwSequenceID = 0xFFFFFFFF;
  42. if (DebugLevel <= P3R3DX_DebugLevel)
  43. {
  44. P3_VERTEXBUFFERINFO* pCurrentCommandBuffer =
  45. pThisDisplay->pRootCommandBuffer;
  46. P3_VERTEXBUFFERINFO* pCurrentVertexBuffer =
  47. pThisDisplay->pRootVertexBuffer;
  48. int count = 0;
  49. DISPDBG((DebugLevel,"Command buffer heap"));
  50. dwSequenceID = 0xFFFFFFFF;
  51. if (pCurrentCommandBuffer)
  52. {
  53. do
  54. {
  55. // A debug check to ensure that the sequence ID's go backwards
  56. ASSERTDD((dwSequenceID >= pCurrentCommandBuffer->dwSequenceID),
  57. "ERROR: Sequence ID's broken!");
  58. DISPDBG((DebugLevel,"Buffer %d,SequenceID:0x%x Pointer: 0x%x",
  59. count++,
  60. pCurrentCommandBuffer->dwSequenceID,
  61. pCurrentCommandBuffer));
  62. DISPDBG((DebugLevel," pPrev: 0x%x, pNext: 0x%x",
  63. pCurrentCommandBuffer->pPrev,
  64. pCurrentCommandBuffer->pNext));
  65. DISPDBG((DebugLevel," bInUse: %d",
  66. pCurrentCommandBuffer->bInUse));
  67. dwSequenceID = pCurrentCommandBuffer->dwSequenceID;
  68. pCurrentCommandBuffer = pCurrentCommandBuffer->pNext;
  69. } while (pCurrentCommandBuffer != pThisDisplay->pRootCommandBuffer);
  70. }
  71. DISPDBG((DebugLevel,"Vertex buffer heap"));
  72. dwSequenceID = 0xFFFFFFFF;
  73. if (pCurrentVertexBuffer)
  74. {
  75. do
  76. {
  77. // A debug check to ensure that the sequence ID's go backwards
  78. ASSERTDD((dwSequenceID >= pCurrentVertexBuffer->dwSequenceID),
  79. "ERROR: Sequence ID's broken!");
  80. DISPDBG((DebugLevel,"Buffer %d,SequenceID:0x%x Pointer: 0x%x",
  81. count++,
  82. pCurrentVertexBuffer->dwSequenceID,
  83. pCurrentVertexBuffer));
  84. DISPDBG((DebugLevel," pPrev: 0x%x, pNext: 0x%x",
  85. pCurrentVertexBuffer->pPrev,
  86. pCurrentVertexBuffer->pNext));
  87. DISPDBG((DebugLevel," bInUse: %d",
  88. pCurrentVertexBuffer->bInUse));
  89. dwSequenceID = pCurrentVertexBuffer->dwSequenceID;
  90. pCurrentVertexBuffer = pCurrentVertexBuffer->pNext;
  91. } while (pCurrentVertexBuffer != pThisDisplay->pRootVertexBuffer);
  92. }
  93. }
  94. } // __EB_DisplayHeapInfo
  95. #endif // DBG
  96. //-----------------------------------------------------------------------------
  97. //
  98. // __EB_FreeCachedBuffer
  99. //
  100. // Frees a buffer associated with this directdraw surface. This is called
  101. // in response to a destroyexecutebuffer call
  102. //
  103. //-----------------------------------------------------------------------------
  104. void
  105. __EB_FreeCachedBuffer(
  106. P3_THUNKEDDATA* pThisDisplay,
  107. LPDDRAWI_DDRAWSURFACE_LCL pSurf)
  108. {
  109. P3_VERTEXBUFFERINFO* pVictim =
  110. (P3_VERTEXBUFFERINFO*)pSurf->lpGbl->dwReserved1;
  111. if (pVictim != NULL)
  112. {
  113. DISPDBG((DBGLVL,"Buffer is one of ours - destroying it"));
  114. // Wait for the buffer to be consumed
  115. __EB_Wait(pThisDisplay, pVictim);
  116. // Set the inuse flag off so the buffer will be freed.
  117. pVictim->bInUse = FALSE;
  118. // Remove the buffer from the pending list
  119. // The memory won't be freed if the buffer isn't in the list
  120. if (!__EB_RemoveFromBufferQueue(pThisDisplay, pVictim))
  121. {
  122. // Free the memory
  123. switch (pVictim->BufferType)
  124. {
  125. case COMMAND_BUFFER:
  126. _DX_LIN_FreeLinearMemory(&pThisDisplay->CachedCommandHeapInfo,
  127. PtrToUlong(pVictim));
  128. break;
  129. case VERTEX_BUFFER:
  130. _DX_LIN_FreeLinearMemory(&pThisDisplay->CachedVertexHeapInfo,
  131. PtrToUlong(pVictim));
  132. break;
  133. }
  134. }
  135. // Reset the buffer pointers
  136. pSurf->lpGbl->dwReserved1 = 0;
  137. pSurf->lpGbl->fpVidMem = 0;
  138. }
  139. } // __EB_FreeCachedBuffer
  140. //-----------------------------------------------------------------------------
  141. //
  142. // __EB_GetSequenceID
  143. //
  144. // Each vertex buffer and command buffer is "stamped" with a sequence ID which
  145. // can be queried in order to find out if a given buffer was already consumed
  146. // by the hardware. __EB_GetSequenceID returns us the sequence ID of the last
  147. // processed buffer.
  148. //
  149. //-----------------------------------------------------------------------------
  150. const DWORD
  151. __EB_GetSequenceID(
  152. P3_THUNKEDDATA* pThisDisplay)
  153. {
  154. DWORD dwSequenceID;
  155. dwSequenceID = READ_GLINT_CTRL_REG(HostInID);
  156. DISPDBG((DBGLVL,"HostIn ID: 0x%x", dwSequenceID));
  157. return dwSequenceID;
  158. } // __EB_GetSequenceID
  159. //-----------------------------------------------------------------------------
  160. //
  161. // __EB_GetNewSequenceID
  162. //
  163. // A driver routine to increment the sequence ID and return it. This
  164. // routine handles the case where the buffer is wrapped beyond the maximum
  165. // number that it can hold. In such case all buffers are flushed
  166. //
  167. //-----------------------------------------------------------------------------
  168. const DWORD
  169. __EB_GetNewSequenceID(
  170. P3_THUNKEDDATA* pThisDisplay)
  171. {
  172. DWORD dwWrapMask;
  173. DBG_ENTRY(__EB_GetNewSequenceID);
  174. #if DBG
  175. dwWrapMask = 0x1F;
  176. #else
  177. dwWrapMask = 0xFFFFFFFF;
  178. #endif
  179. if( pThisDisplay->dwCurrentSequenceID >= dwWrapMask )
  180. {
  181. // We have wrapped, so flush all the buffers
  182. // but wait for them to be consumed (bWait == TRUE)
  183. _D3D_EB_FlushAllBuffers(pThisDisplay , TRUE);
  184. // This SYNC is needed for unknown reasons - further investigation
  185. // required. //azn???
  186. SYNC_WITH_GLINT;
  187. // Reset the sequence ID numbering
  188. pThisDisplay->dwCurrentSequenceID = 0;
  189. }
  190. else
  191. {
  192. pThisDisplay->dwCurrentSequenceID++;
  193. }
  194. DISPDBG((DBGLVL, "Returning Sequence ID: 0x%x",
  195. pThisDisplay->dwCurrentSequenceID));
  196. DBG_EXIT(__EB_GetNewSequenceID,pThisDisplay->dwCurrentSequenceID);
  197. return pThisDisplay->dwCurrentSequenceID;
  198. } // __EB_GetNewSequenceID
  199. //-----------------------------------------------------------------------------
  200. //
  201. // __EB_Wait
  202. //
  203. // If the current buffer is in the queue, wait for it to pass through
  204. // the chip.
  205. //
  206. //-----------------------------------------------------------------------------
  207. void
  208. __EB_Wait(
  209. P3_THUNKEDDATA* pThisDisplay,
  210. P3_VERTEXBUFFERINFO* pBuffer)
  211. {
  212. DBG_ENTRY(__EB_Wait);
  213. ASSERTDD(pBuffer, "ERROR: Buffer passed to __EB_Wait is null!");
  214. // Don't wait for the buffer, if it has not been added to the queue
  215. if (pBuffer->pNext != NULL)
  216. {
  217. // Flush to ensure that the hostin ID has been sent to the chip
  218. P3_DMA_DEFS();
  219. P3_DMA_GET_BUFFER();
  220. P3_DMA_FLUSH_BUFFER();
  221. DISPDBG((DBGLVL, "*** In __EB_Wait: Buffer Sequence ID: 0x%x",
  222. pBuffer->dwSequenceID));
  223. while (__EB_GetSequenceID(pThisDisplay) < pBuffer->dwSequenceID)
  224. {
  225. static int blockCount;
  226. // This buffer is in the chain of buffers that are being used
  227. // by the host-in unit. We must wait for it to be consumed
  228. // before freeing it.
  229. blockCount = 100;
  230. while( blockCount-- )
  231. NULL;
  232. }
  233. }
  234. DBG_EXIT(__EB_Wait,0);
  235. } // __EB_Wait
  236. //-----------------------------------------------------------------------------
  237. //
  238. // __EB_RemoveFromBufferQueue
  239. //
  240. // Removes a buffer from the queue. Will also free the associated memory
  241. // if it is no longer in use
  242. //
  243. //-----------------------------------------------------------------------------
  244. BOOL
  245. __EB_RemoveFromBufferQueue(
  246. P3_THUNKEDDATA* pThisDisplay,
  247. P3_VERTEXBUFFERINFO* pVictim)
  248. {
  249. ASSERTDD(pVictim != NULL,
  250. "ERROR: NULL buffer passed to EB_RemoveFromList");
  251. DBG_ENTRY(__EB_RemoveFromBufferQueue);
  252. // Don't remove a buffer that isn't already in the queue
  253. if (pVictim->pNext == NULL)
  254. {
  255. DBG_EXIT(__EB_RemoveFromBufferQueue,FALSE);
  256. return FALSE;
  257. }
  258. DISPDBG((DBGLVL,"Removing buffer for queue, ID: 0x%x",
  259. pVictim->dwSequenceID));
  260. // Remove this entry from the list
  261. pVictim->pPrev->pNext = pVictim->pNext;
  262. pVictim->pNext->pPrev = pVictim->pPrev;
  263. switch (pVictim->BufferType)
  264. {
  265. case COMMAND_BUFFER:
  266. // Replace the root node if necessary
  267. if (pVictim == pThisDisplay->pRootCommandBuffer)
  268. {
  269. if (pVictim->pNext != pThisDisplay->pRootCommandBuffer)
  270. {
  271. pThisDisplay->pRootCommandBuffer = pVictim->pNext;
  272. }
  273. else
  274. {
  275. pThisDisplay->pRootCommandBuffer = NULL;
  276. }
  277. }
  278. break;
  279. case VERTEX_BUFFER:
  280. // Replace the root node if necessary
  281. if (pVictim == pThisDisplay->pRootVertexBuffer)
  282. {
  283. if (pVictim->pNext != pThisDisplay->pRootVertexBuffer)
  284. {
  285. pThisDisplay->pRootVertexBuffer = pVictim->pNext;
  286. }
  287. else
  288. {
  289. pThisDisplay->pRootVertexBuffer = NULL;
  290. }
  291. }
  292. break;
  293. } // switch (pVictim->BufferType)
  294. // Buffer is no longer in the list
  295. pVictim->pPrev = NULL;
  296. pVictim->pNext = NULL;
  297. // Free the memory we found if it isn't reserved as a real buffer.
  298. if (!pVictim->bInUse)
  299. {
  300. DISPDBG((DBGLVL," Buffer is old - freeing the memory"));
  301. switch (pVictim->BufferType)
  302. {
  303. case COMMAND_BUFFER:
  304. _DX_LIN_FreeLinearMemory(&pThisDisplay->CachedCommandHeapInfo,
  305. PtrToUlong(pVictim));
  306. break;
  307. case VERTEX_BUFFER:
  308. _DX_LIN_FreeLinearMemory(&pThisDisplay->CachedVertexHeapInfo,
  309. PtrToUlong(pVictim));
  310. break;
  311. }
  312. DBG_EXIT(__EB_RemoveFromBufferQueue,TRUE);
  313. return TRUE;
  314. }
  315. DBG_EXIT(__EB_RemoveFromBufferQueue,FALSE);
  316. return FALSE;
  317. } // __EB_RemoveFromBufferQueue
  318. //-----------------------------------------------------------------------------
  319. //
  320. // __EB_AddToBufferQueue
  321. //
  322. // Adds a buffer to the queue. Note that buffers are always added
  323. // at the start to maintain a temporal ordering of the buffers.
  324. //
  325. //-----------------------------------------------------------------------------
  326. void
  327. __EB_AddToBufferQueue(
  328. P3_THUNKEDDATA* pThisDisplay,
  329. P3_VERTEXBUFFERINFO* pNewBuffer)
  330. {
  331. DBG_ENTRY(__EB_AddToBufferQueue);
  332. ASSERTDD(pNewBuffer != NULL,
  333. "ERROR: NULL buffer passed to EB_AddToList");
  334. ASSERTDD(pNewBuffer->pNext == NULL,
  335. "ERROR: Buffer already in queue (pNext!NULL)");
  336. ASSERTDD(pNewBuffer->pPrev == NULL,
  337. "ERROR: Buffer already in queue (pPrev!NULL)");
  338. switch(pNewBuffer->BufferType)
  339. {
  340. case COMMAND_BUFFER:
  341. // Add the buffer to the queue
  342. // Check that the queue isn't empty.
  343. // If it is start a new list
  344. if (pThisDisplay->pRootCommandBuffer == NULL)
  345. {
  346. DISPDBG((DBGLVL,"Command Buffer queue is empty."
  347. " Starting a new one"));
  348. // Sew in the buffer
  349. pThisDisplay->pRootCommandBuffer = pNewBuffer;
  350. pNewBuffer->pNext = pNewBuffer;
  351. pNewBuffer->pPrev = pNewBuffer;
  352. }
  353. else
  354. {
  355. DISPDBG((DBGLVL,"Adding command buffer to the list"));
  356. // Always put new buffers at the root.
  357. pNewBuffer->pNext = pThisDisplay->pRootCommandBuffer;
  358. pNewBuffer->pPrev = pThisDisplay->pRootCommandBuffer->pPrev;
  359. pThisDisplay->pRootCommandBuffer->pPrev->pNext = pNewBuffer;
  360. pThisDisplay->pRootCommandBuffer->pPrev = pNewBuffer;
  361. pThisDisplay->pRootCommandBuffer = pNewBuffer;
  362. }
  363. break;
  364. case VERTEX_BUFFER:
  365. // Add the buffer to the queue
  366. // Check that the queue isn't empty. If it is start a new list
  367. if (pThisDisplay->pRootVertexBuffer == NULL)
  368. {
  369. DISPDBG((DBGLVL,"Vertex Buffer queue is empty. Starting a new one"));
  370. // Sew in the buffer
  371. pThisDisplay->pRootVertexBuffer = pNewBuffer;
  372. pNewBuffer->pNext = pNewBuffer;
  373. pNewBuffer->pPrev = pNewBuffer;
  374. }
  375. else
  376. {
  377. DISPDBG((DBGLVL,"Adding vertex buffer to the list"));
  378. // Always put new buffers at the root.
  379. pNewBuffer->pNext = pThisDisplay->pRootVertexBuffer;
  380. pNewBuffer->pPrev = pThisDisplay->pRootVertexBuffer->pPrev;
  381. pThisDisplay->pRootVertexBuffer->pPrev->pNext = pNewBuffer;
  382. pThisDisplay->pRootVertexBuffer->pPrev = pNewBuffer;
  383. pThisDisplay->pRootVertexBuffer = pNewBuffer;
  384. }
  385. break;
  386. } // switch(pNewBuffer->BufferType)
  387. DISPDBG((DBGLVL, "Added buffer to queue, ID: 0x%x", pNewBuffer->dwSequenceID));
  388. DBG_EXIT(__EB_AddToBufferQueue,pNewBuffer->dwSequenceID);
  389. } // __EB_AddToBufferQueue
  390. //-----------------------------------------------------------------------------
  391. //
  392. // __EB_AllocateCachedBuffer
  393. //
  394. // Allocates a cached buffer and stores it in the surface structure.
  395. // First this function will try to allocate out of the linear heap.
  396. // If this fails, it will keep walking the buffer queue until there
  397. // are no more buffers left that are pending and aren't in use.
  398. // If all else fails this driver will return FALSE indicating that
  399. // it couldn't allocate the memory due to lack of space
  400. //
  401. //-----------------------------------------------------------------------------
  402. BOOL
  403. __EB_AllocateCachedBuffer(
  404. P3_THUNKEDDATA* pThisDisplay,
  405. DWORD dwBytes,
  406. LPDDRAWI_DDRAWSURFACE_LCL pSurf)
  407. {
  408. P3_MEMREQUEST mmrq;
  409. DWORD dwResult;
  410. P3_VERTEXBUFFERINFO* pCurrentBuffer;
  411. P3_VERTEXBUFFERINFO** ppRootBuffer;
  412. BOOL bFound;
  413. eBufferType BufferType;
  414. pLinearAllocatorInfo pAllocHeap;
  415. static int blockCount;
  416. DBG_ENTRY(__EB_AllocateCachedBuffer);
  417. #if WNT_DDRAW
  418. pAllocHeap = &pThisDisplay->CachedVertexHeapInfo;
  419. BufferType = VERTEX_BUFFER;
  420. ppRootBuffer = &pThisDisplay->pRootVertexBuffer;
  421. #else
  422. // Decide on which heap this surface should come out of.
  423. if (pSurf->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_COMMANDBUFFER)
  424. {
  425. pAllocHeap = &pThisDisplay->CachedCommandHeapInfo;
  426. BufferType = COMMAND_BUFFER;
  427. ppRootBuffer = &pThisDisplay->pRootCommandBuffer;
  428. DISPDBG((DBGLVL,"Buffer is COMMAND_BUFFER"));
  429. }
  430. else
  431. {
  432. pAllocHeap = &pThisDisplay->CachedVertexHeapInfo;
  433. BufferType = VERTEX_BUFFER;
  434. ppRootBuffer = &pThisDisplay->pRootVertexBuffer;
  435. DISPDBG((DBGLVL,"Buffer is VERTEX_BUFFER"));
  436. }
  437. #endif // WNT_DDRAW
  438. #if DBG
  439. // Dump the memory and the pending buffer heaps.
  440. __EB_DisplayHeapInfo(DBGLVL, pThisDisplay);
  441. #endif //DBG
  442. // Do a quick check to see if the buffer at the back is free.
  443. if ((*ppRootBuffer) != NULL)
  444. {
  445. pCurrentBuffer = (*ppRootBuffer)->pPrev;
  446. // If the buffer is big enough, and it's completed, and
  447. // it isn't in use, then free it.
  448. if ( ((dwBytes + sizeof(P3_VERTEXBUFFERINFO)) <= pCurrentBuffer->dwSize) &&
  449. (!pCurrentBuffer->bInUse) &&
  450. (__EB_GetSequenceID(pThisDisplay) >= pCurrentBuffer->dwSequenceID) )
  451. {
  452. // Mark this buffer as in use, so that it doesn't get freed
  453. pCurrentBuffer->bInUse = TRUE;
  454. // It isn't pending any more, so remove it from the queue
  455. // Note that the memory won't be deallocated because we have explicity
  456. // marked it as in use.
  457. __EB_RemoveFromBufferQueue(pThisDisplay, pCurrentBuffer);
  458. // Pass back a pointer to the memory
  459. pSurf->lpGbl->fpVidMem = (FLATPTR)((BYTE *)pCurrentBuffer) +
  460. sizeof(P3_VERTEXBUFFERINFO);
  461. // Store a pointer to the info block at the start of the memory
  462. pSurf->lpGbl->dwReserved1 = (ULONG_PTR)pCurrentBuffer;
  463. #if W95_DDRAW
  464. // Setup the caps
  465. pSurf->lpGbl->dwGlobalFlags |= DDRAWISURFGBL_SYSMEMEXECUTEBUFFER;
  466. #endif
  467. // If you set these you don't see any locks....
  468. pSurf->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  469. // Remember the new size
  470. pSurf->lpGbl->dwLinearSize = dwBytes;
  471. // Mark the buffer as in use and return it
  472. pCurrentBuffer->dwSequenceID = 0;
  473. pCurrentBuffer->bInUse = TRUE;
  474. pCurrentBuffer->pNext = NULL;
  475. pCurrentBuffer->pPrev = NULL;
  476. pCurrentBuffer->BufferType = BufferType;
  477. pCurrentBuffer->dwSize = dwBytes + sizeof(P3_VERTEXBUFFERINFO);
  478. DISPDBG((DBGLVL,"Found a re-useable buffer "
  479. "- didn't need to reallocate memory"));
  480. DBG_EXIT(__EB_AllocateCachedBuffer,TRUE);
  481. return TRUE;
  482. }
  483. }
  484. // do things the longer way...
  485. // Try to allocate the requested memory
  486. do
  487. {
  488. ZeroMemory(&mmrq, sizeof(P3_MEMREQUEST));
  489. mmrq.dwSize = sizeof(P3_MEMREQUEST);
  490. mmrq.dwAlign = 4;
  491. mmrq.dwBytes = dwBytes + sizeof(P3_VERTEXBUFFERINFO);
  492. mmrq.dwFlags = MEM3DL_FIRST_FIT | MEM3DL_FRONT;
  493. dwResult = _DX_LIN_AllocateLinearMemory(pAllocHeap, &mmrq);
  494. if (dwResult == GLDD_SUCCESS)
  495. {
  496. DISPDBG((DBGLVL,"Allocated a cached buffer"));
  497. // Pass back a pointer to the memory
  498. pSurf->lpGbl->fpVidMem = mmrq.pMem + sizeof(P3_VERTEXBUFFERINFO);
  499. // Store a pointer to the info block at the start of the memory
  500. pSurf->lpGbl->dwReserved1 = mmrq.pMem;
  501. #if W95_DDRAW
  502. // Setup the caps
  503. pSurf->lpGbl->dwGlobalFlags |= DDRAWISURFGBL_SYSMEMEXECUTEBUFFER;
  504. #endif
  505. // If you set these you don't see any locks....
  506. pSurf->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
  507. // Remember the new size
  508. pSurf->lpGbl->dwLinearSize = dwBytes;
  509. // Mark the buffer as in use and return it
  510. pCurrentBuffer = (P3_VERTEXBUFFERINFO*)(ULONG_PTR)mmrq.pMem;
  511. pCurrentBuffer->dwSequenceID = 0;
  512. pCurrentBuffer->bInUse = TRUE;
  513. pCurrentBuffer->pNext = NULL;
  514. pCurrentBuffer->pPrev = NULL;
  515. pCurrentBuffer->BufferType = BufferType;
  516. pCurrentBuffer->dwSize = dwBytes + sizeof(P3_VERTEXBUFFERINFO);
  517. DBG_EXIT(__EB_AllocateCachedBuffer,TRUE);
  518. return TRUE;
  519. }
  520. else
  521. {
  522. DISPDBG((DBGLVL,"Failed to allocate cached buffer"));
  523. // Remember that we haven't found any memory yet.
  524. // and that there isn't any memory to use.
  525. bFound = FALSE;
  526. // There are no buffers currently available.
  527. // Wait for a new one to be free from the
  528. // ones that are available and in the queue
  529. // None at all? No chance of any memory being free
  530. // Return FALSE to indicate this.
  531. if ((*ppRootBuffer) == NULL)
  532. {
  533. DISPDBG((DBGLVL,"No buffers in the list!"));
  534. DBG_EXIT(__EB_AllocateCachedBuffer,FALSE);
  535. return FALSE;
  536. }
  537. // Start at the back of the queue, as these are
  538. // the least recently used buffers
  539. pCurrentBuffer = (*ppRootBuffer)->pPrev;
  540. do
  541. {
  542. P3_DMA_DEFS();
  543. // Ensure that all DMA is completed so that the HostIn
  544. // ID is up to date
  545. P3_DMA_GET_BUFFER();
  546. P3_DMA_FLUSH_BUFFER();
  547. DISPDBG((DBGLVL,"Searching for old buffers..."));
  548. // Check to see if this buffer is available to be freed
  549. // It may not be if it is a buffer that hasn't been swapped out,
  550. // such as a vertex buffer.
  551. DISPDBG((DBGLVL,"This buffer ID: 0x%x",
  552. pCurrentBuffer->dwSequenceID));
  553. if( __EB_GetSequenceID(pThisDisplay) >=
  554. pCurrentBuffer->dwSequenceID )
  555. {
  556. DISPDBG((DBGLVL,"Found a buffer that can be "
  557. "removed from the list"));
  558. // It isn't pending any more, so remove it from the queue
  559. if (__EB_RemoveFromBufferQueue(pThisDisplay, pCurrentBuffer))
  560. {
  561. bFound = TRUE;
  562. break;
  563. }
  564. // If the queue is gone, exit (bFound hasn't been
  565. // setup because we didn't find any memory in the queue)
  566. if ((*ppRootBuffer) == NULL)
  567. {
  568. break;
  569. }
  570. // Reset to the last buffer in the chain. This ensures that
  571. // we always look at the least recent buffer
  572. pCurrentBuffer = (*ppRootBuffer)->pPrev;
  573. }
  574. else
  575. {
  576. // BLOCK!
  577. // The buffer we are looking at hasn't become available yet.
  578. // We should back off here until it does.
  579. blockCount = 100;
  580. while( blockCount-- )
  581. NULL;
  582. DISPDBG((DBGLVL,"Blocked waiting for buffer to be free"));
  583. }
  584. } while (pCurrentBuffer != NULL);
  585. }
  586. // Loop until we haven't found any more space to allocate buffers into
  587. } while (bFound);
  588. DISPDBG((WRNLVL,"!! No available new buffers pending to be freed!!"));
  589. DBG_EXIT(__EB_AllocateCachedBuffer,FALSE);
  590. return FALSE;
  591. } // __EB_AllocateCachedBuffer
  592. //-----------------------------------------------------------------------------
  593. //
  594. // _D3D_EB_FlushAllBuffers
  595. //
  596. // Empties the queue. Note that this will cause any allocated buffer
  597. // memory to be freed along the way. This version doesn't wait for the
  598. // buffer to be consumed. It is used when a context switch has
  599. // occured and we know it is safe to do
  600. //
  601. //-----------------------------------------------------------------------------
  602. void
  603. _D3D_EB_FlushAllBuffers(
  604. P3_THUNKEDDATA* pThisDisplay,
  605. BOOL bWait)
  606. {
  607. P3_VERTEXBUFFERINFO* pCurrentBuffer;
  608. DBG_ENTRY(_D3D_EB_FlushAllBuffers);
  609. // Walk the list of buffers, flushing them from the queue
  610. while (pThisDisplay->pRootVertexBuffer != NULL)
  611. {
  612. pCurrentBuffer = pThisDisplay->pRootVertexBuffer;
  613. if(bWait)
  614. {
  615. // Wait for the buffer to be consumed
  616. __EB_Wait(pThisDisplay, pCurrentBuffer);
  617. }
  618. // Remove the buffer from the queue
  619. __EB_RemoveFromBufferQueue(pThisDisplay, pCurrentBuffer);
  620. }
  621. while (pThisDisplay->pRootCommandBuffer != NULL)
  622. {
  623. pCurrentBuffer = pThisDisplay->pRootCommandBuffer;
  624. if(bWait)
  625. {
  626. // Wait for the buffer to be consumed
  627. __EB_Wait(pThisDisplay, pCurrentBuffer);
  628. }
  629. // Remove the buffer from the queue
  630. __EB_RemoveFromBufferQueue(pThisDisplay, pCurrentBuffer);
  631. }
  632. DBG_EXIT(_D3D_EB_FlushAllBuffers,0);
  633. } // _D3D_EB_FlushAllBuffers
  634. //-----------------------------------------------------------------------------
  635. //
  636. // _D3D_EB_GetAndWaitForBuffers
  637. //
  638. //-----------------------------------------------------------------------------
  639. void
  640. _D3D_EB_GetAndWaitForBuffers(
  641. P3_THUNKEDDATA* pThisDisplay,
  642. LPD3DHAL_DRAWPRIMITIVES2DATA pdp2d ,
  643. P3_VERTEXBUFFERINFO** ppVertexBufferInfo,
  644. P3_VERTEXBUFFERINFO** ppCommandBufferInfo)
  645. {
  646. P3_VERTEXBUFFERINFO* pVertexBufferInfo;
  647. P3_VERTEXBUFFERINFO* pCommandBufferInfo;
  648. pCommandBufferInfo =
  649. (P3_VERTEXBUFFERINFO*)pdp2d->lpDDCommands->lpGbl->dwReserved1;
  650. // Check if vertex buffer resides in user memory or in a DDraw surface
  651. if (pdp2d->dwFlags & D3DHALDP2_USERMEMVERTICES)
  652. {
  653. pVertexBufferInfo = NULL;
  654. }
  655. else
  656. {
  657. // This pointer may be NULL, indicating a buffer passed that isn't
  658. // one of ours. That doesn't mean to say that we can't swap in one
  659. // of our buffers if there is one available.
  660. pVertexBufferInfo =
  661. (P3_VERTEXBUFFERINFO*)pdp2d->lpDDVertex->lpGbl->dwReserved1;
  662. }
  663. // If the vertex buffer is in the queue, wait for it.
  664. if (pVertexBufferInfo && pVertexBufferInfo->pPrev)
  665. {
  666. // Wait for this buffer if we need to
  667. __EB_Wait(pThisDisplay, pVertexBufferInfo);
  668. // Remove this buffer from the queue
  669. if (__EB_RemoveFromBufferQueue(pThisDisplay, pVertexBufferInfo))
  670. {
  671. DISPDBG((ERRLVL,"ERROR: This buffer should not have been freed "
  672. "(is in use!)"));
  673. }
  674. }
  675. // If the command buffer is in the queue, wait for it.
  676. if (pCommandBufferInfo && pCommandBufferInfo->pPrev)
  677. {
  678. // Wait for this buffer if we need to
  679. __EB_Wait(pThisDisplay, pCommandBufferInfo);
  680. // Remove this buffer from the queue
  681. if (__EB_RemoveFromBufferQueue(pThisDisplay, pCommandBufferInfo))
  682. {
  683. DISPDBG((ERRLVL,"ERROR: This buffer should not have been freed"
  684. " (is in use!)"));
  685. }
  686. }
  687. // Return current values of pointers to EB buffers
  688. *ppCommandBufferInfo = pCommandBufferInfo;
  689. *ppVertexBufferInfo = pVertexBufferInfo;
  690. } // _D3D_EB_GetAndWaitForBuffers
  691. //-----------------------------------------------------------------------------
  692. //
  693. // _D3D_EB_UpdateSwapBuffers
  694. //
  695. //-----------------------------------------------------------------------------
  696. void
  697. _D3D_EB_UpdateSwapBuffers(
  698. P3_THUNKEDDATA* pThisDisplay,
  699. LPD3DHAL_DRAWPRIMITIVES2DATA pdp2d ,
  700. P3_VERTEXBUFFERINFO* pVertexBufferInfo,
  701. P3_VERTEXBUFFERINFO* pCommandBufferInfo)
  702. {
  703. // Add the buffers to the pending queue.
  704. // Only do this if the buffers actually belong to us.
  705. // If either of the buffers was sent, update the HOSTIN ID.
  706. // We need to make the new sequence ID and the update of the hostin
  707. // 'atomic', or the wraparound will cause a lockup
  708. if (pVertexBufferInfo)
  709. {
  710. P3_DMA_DEFS();
  711. pVertexBufferInfo->dwSequenceID =
  712. __EB_GetNewSequenceID(pThisDisplay);
  713. __EB_AddToBufferQueue(pThisDisplay, pVertexBufferInfo);
  714. P3_DMA_GET_BUFFER_ENTRIES( 2 );
  715. SEND_P3_DATA(HostInID, pVertexBufferInfo->dwSequenceID);
  716. P3_DMA_COMMIT_BUFFER();
  717. }
  718. if (pCommandBufferInfo)
  719. {
  720. P3_DMA_DEFS();
  721. pCommandBufferInfo->dwSequenceID =
  722. __EB_GetNewSequenceID(pThisDisplay);
  723. __EB_AddToBufferQueue(pThisDisplay, pCommandBufferInfo);
  724. P3_DMA_GET_BUFFER_ENTRIES( 2 );
  725. SEND_P3_DATA(HostInID, pCommandBufferInfo->dwSequenceID);
  726. P3_DMA_COMMIT_BUFFER();
  727. }
  728. if (D3DHALDP2_SWAPVERTEXBUFFER & pdp2d->dwFlags)
  729. {
  730. DWORD dwNewSize = pdp2d->lpDDVertex->lpGbl->dwLinearSize;
  731. DISPDBG((DBGLVL,"D3DHALDP2_SWAPVERTEXBUFFER..."));
  732. if (D3DHALDP2_REQVERTEXBUFSIZE & pdp2d->dwFlags)
  733. {
  734. DISPDBG((DBGLVL,"D3DHALDP2_REQVERTEXBUFSIZE - %d",
  735. pdp2d->dwReqVertexBufSize));
  736. if (dwNewSize < pdp2d->dwReqVertexBufSize)
  737. {
  738. dwNewSize = pdp2d->dwReqVertexBufSize;
  739. }
  740. }
  741. DISPDBG((DBGLVL,"Current vertex buffer size: %d, "
  742. "New size will be: %d",
  743. pdp2d->lpDDVertex->lpGbl->dwLinearSize,
  744. dwNewSize));
  745. // The vertex buffer we just sent off is fixed in place until we
  746. // mark it as not in use, which we will after allocating a new
  747. // buffer. The following call will try to get a new buffer and
  748. // update the surface structure appropriately. Note that it won't
  749. // trash the current surface unless the allocation succeeds.
  750. if (__EB_AllocateCachedBuffer(pThisDisplay,
  751. dwNewSize,
  752. pdp2d->lpDDVertex))
  753. {
  754. DISPDBG((DBGLVL,"Got a new swap vertex buffer"));
  755. #define STAMP_BUFFER 0
  756. #if STAMP_BUFFER
  757. {
  758. DWORD i, *pv;
  759. pv = (DWORD * ) pdp2d->lpDDVertex->lpGbl->fpVidMem;
  760. for( i = 0; i < ( dwNewSize / 4 ); i++ )
  761. {
  762. *pv++ = 0x44000000;
  763. }
  764. }
  765. #endif
  766. // Fix up the discarded buffer if required
  767. if (pVertexBufferInfo)
  768. {
  769. // Mark the current buffer as not in use, meaning it can
  770. // be freed once it has cleared P3. This might occur the
  771. // next time we are here.
  772. pVertexBufferInfo->bInUse = FALSE;
  773. // A gotcha! The buffer we just launched was consumed so
  774. // fast that it was freed from the pending list to make
  775. // room for it's replacement. This is normally OK, but in
  776. // this case the buffer we freed isn't being put back
  777. // anywhere - i.e. no surface now owns it, and the memory
  778. // associated with it wasn't freed because as far as the
  779. // driver is concerned it is still in use until it is
  780. // replaced due to the above succesfull call. The
  781. // 'solution' is to add it back into the queue if it is
  782. // not in it, and make sure that it is marked as not in
  783. // use and at a 0 hostin ID.
  784. if (!pVertexBufferInfo->pPrev)
  785. {
  786. pVertexBufferInfo->dwSequenceID = 0;
  787. __EB_AddToBufferQueue(pThisDisplay,
  788. pVertexBufferInfo);
  789. }
  790. }
  791. }
  792. else
  793. {
  794. // Couldn't swap this buffer, so we have to wait
  795. DISPDBG((DBGLVL,"Not swapping vertex buffer "
  796. "due to lack of space!"));
  797. __EB_Wait(pThisDisplay, pVertexBufferInfo);
  798. }
  799. }
  800. else
  801. {
  802. DISPDBG((DBGLVL,"No vertex buffer swapping..."));
  803. }
  804. if (D3DHALDP2_SWAPCOMMANDBUFFER & pdp2d->dwFlags)
  805. {
  806. DWORD dwNewSize = pdp2d->lpDDCommands->lpGbl->dwLinearSize;
  807. DISPDBG((DBGLVL,"D3DHALDP2_SWAPCOMMANDBUFFER..."));
  808. if (D3DHALDP2_REQCOMMANDBUFSIZE & pdp2d->dwFlags)
  809. {
  810. DISPDBG((DBGLVL,"D3DHALDP2_REQCOMMANDBUFSIZE - %d",
  811. pdp2d->dwReqCommandBufSize));
  812. if (dwNewSize < pdp2d->dwReqCommandBufSize)
  813. {
  814. dwNewSize = pdp2d->dwReqCommandBufSize;
  815. }
  816. }
  817. DISPDBG((DBGLVL,"Current command buffer size: "
  818. "%d, New size will be: %d",
  819. pdp2d->lpDDCommands->lpGbl->dwLinearSize,
  820. dwNewSize));
  821. // The command buffer we just sent off is fixed in place until we
  822. // mark it as not in use, which we will after allocating a new
  823. // buffer. The following call will try to get a new buffer and
  824. // update the surface structure appropriately. Note that it won't
  825. // trash the current surface unless the allocation succeeds
  826. if (__EB_AllocateCachedBuffer(pThisDisplay,
  827. dwNewSize,
  828. pdp2d->lpDDCommands))
  829. {
  830. DISPDBG((DBGLVL,"Got a new swap command buffer"));
  831. // Fix up the previous command buffer if required.
  832. if (pCommandBufferInfo)
  833. {
  834. // Mark the current buffer as not in use, meaning it can
  835. // be freed once it has cleared P3. This might occur the
  836. // next time we are here.
  837. pCommandBufferInfo->bInUse = FALSE;
  838. // A gotcha! The buffer we just launched was consumed so
  839. // fast that it was freed from the pending list to make
  840. // room for it's replacement. This is normally OK, but in
  841. // this case the buffer we freed isn't being put back
  842. // anywhere - i.e. no surface now owns it, and the memory
  843. // associated with it wasn't freed because as far as the
  844. // driver is concerned it is still in use until it is
  845. // replaced due to the above succesfull call. The
  846. // 'solution' is to add it back into the queue if it is
  847. // not in it, and make sure that it is marked as not in
  848. // use and at a 0 hostin ID.
  849. if (!pCommandBufferInfo->pPrev)
  850. {
  851. pCommandBufferInfo->dwSequenceID = 0;
  852. __EB_AddToBufferQueue(pThisDisplay,
  853. pCommandBufferInfo);
  854. }
  855. }
  856. }
  857. else
  858. {
  859. // Couldn't swap this buffer, so we have to wait
  860. DISPDBG((DBGLVL,"Not swapping command buffer "
  861. "due to lack of space!"));
  862. __EB_Wait(pThisDisplay, pCommandBufferInfo);
  863. }
  864. }
  865. else
  866. {
  867. DISPDBG((DBGLVL,"No Command buffer swapping..."));
  868. }
  869. } // _D3D_EB_UpdateSwapBuffers
  870. //-----------------------------Public Routine----------------------------------
  871. //
  872. // D3DCanCreateD3DBuffer
  873. //
  874. // Called by the runtime to ask if a type of vertex/command buffer can
  875. // be created by the driver. We don't do anything here at present
  876. //
  877. //
  878. //-----------------------------------------------------------------------------
  879. DWORD CALLBACK
  880. D3DCanCreateD3DBuffer(
  881. LPDDHAL_CANCREATESURFACEDATA pccsd)
  882. {
  883. P3_THUNKEDDATA* pThisDisplay;
  884. DBG_CB_ENTRY(D3DCanCreateD3DBuffer);
  885. GET_THUNKEDDATA(pThisDisplay, pccsd->lpDD);
  886. VALIDATE_MODE_AND_STATE(pThisDisplay);
  887. DBGDUMP_DDSURFACEDESC(DBGLVL, pccsd->lpDDSurfaceDesc);
  888. pccsd->ddRVal = DD_OK;
  889. DBG_CB_EXIT(D3DCanCreateD3DBuffer,pccsd->ddRVal);
  890. return DDHAL_DRIVER_HANDLED;
  891. } // D3DCanCreateD3DBuffer
  892. //-----------------------------Public Routine----------------------------------
  893. //
  894. // D3DCreateD3DBuffer
  895. //
  896. // Called by the runtime to create a vertex buffer. We try to allocate
  897. // from our cached heap here.
  898. //
  899. //
  900. //-----------------------------------------------------------------------------
  901. DWORD CALLBACK
  902. D3DCreateD3DBuffer(
  903. LPDDHAL_CREATESURFACEDATA pcsd)
  904. {
  905. P3_THUNKEDDATA* pThisDisplay;
  906. LPDDRAWI_DDRAWSURFACE_LCL pSurf;
  907. LPDDRAWI_DDRAWSURFACE_LCL FAR* ppSList;
  908. BOOL bHandled = FALSE;
  909. DWORD i;
  910. DBG_CB_ENTRY(D3DCreateD3DBuffer);
  911. GET_THUNKEDDATA(pThisDisplay, pcsd->lpDD);
  912. VALIDATE_MODE_AND_STATE(pThisDisplay);
  913. STOP_SOFTWARE_CURSOR(pThisDisplay);
  914. DDRAW_OPERATION(pContext, pThisDisplay);
  915. ppSList = pcsd->lplpSList;
  916. for (i = 0; i < pcsd->dwSCnt; i++)
  917. {
  918. pSurf = ppSList[i];
  919. // Allocate the size we want
  920. DISPDBG((DBGLVL,"Surface %d requested is 0x%x big",
  921. i, pSurf->lpGbl->dwLinearSize));
  922. DBGDUMP_DDRAWSURFACE_LCL(DBGLVL, pSurf);
  923. pSurf->lpGbl->dwReserved1 = 0;
  924. // A 32 kB command buffer gives a high probability of being allowed
  925. // to swap the associated vertex buffer
  926. if( pSurf->lpGbl->dwLinearSize < _32_KBYTES )
  927. {
  928. pSurf->lpGbl->dwLinearSize = _32_KBYTES;
  929. }
  930. if (__EB_AllocateCachedBuffer(pThisDisplay,
  931. pSurf->lpGbl->dwLinearSize,
  932. pSurf))
  933. {
  934. DISPDBG((DBGLVL,"Allocated a new cached buffer for use by D3D"));
  935. bHandled = TRUE;
  936. }
  937. else
  938. {
  939. // If we can't find a buffer, the best thing to do is to
  940. // punt to D3D and always copy the data into a DMA buffer
  941. // (because it won't be contiguous). The DP2 call should
  942. // check the reserved field before using the HostIn unit
  943. DISPDBG((ERRLVL,"WARNING: Couldn't find any vertex memory"
  944. " in the heap or in the sent list!"));
  945. pSurf->lpGbl->dwReserved1 = 0;
  946. bHandled = FALSE;
  947. }
  948. }
  949. START_SOFTWARE_CURSOR(pThisDisplay);
  950. pcsd->ddRVal = DD_OK;
  951. if (bHandled)
  952. {
  953. DBG_EXIT(D3DCreateD3DBuffer,DDHAL_DRIVER_HANDLED);
  954. return DDHAL_DRIVER_HANDLED;
  955. }
  956. else
  957. {
  958. DBG_CB_EXIT(D3DCreateD3DBuffer,DDHAL_DRIVER_NOTHANDLED);
  959. return DDHAL_DRIVER_NOTHANDLED;
  960. }
  961. } // D3DCreateD3DBuffer
  962. //-----------------------------Public Routine----------------------------------
  963. //
  964. // D3DDestroyD3DBuffer
  965. //
  966. // Called by the runtime to destroy a vertex buffer. We free the buffer
  967. // from our memory heap and the current queue.
  968. //
  969. //
  970. //-----------------------------------------------------------------------------
  971. DWORD CALLBACK
  972. D3DDestroyD3DBuffer(
  973. LPDDHAL_DESTROYSURFACEDATA pdd)
  974. {
  975. P3_THUNKEDDATA* pThisDisplay;
  976. DBG_CB_ENTRY(D3DDestroyD3DBuffer);
  977. GET_THUNKEDDATA(pThisDisplay, pdd->lpDD);
  978. VALIDATE_MODE_AND_STATE(pThisDisplay);
  979. STOP_SOFTWARE_CURSOR(pThisDisplay);
  980. DDRAW_OPERATION(pContext, pThisDisplay);
  981. // Debug data
  982. DBGDUMP_DDRAWSURFACE_LCL(DBGLVL, pdd->lpDDSurface);
  983. // Free the D3D buffer. If its in use, we will wait for it to be ready.
  984. __EB_FreeCachedBuffer(pThisDisplay, pdd->lpDDSurface);
  985. #ifdef CHECK_BUFFERS_ARENT_LEFT_AFTER_APPLICATION_SHUTDOWN
  986. // Flush all the buffers
  987. // This checks that the queue is OK. If you don't do this
  988. // you may see the linear allocator on the 16 bit side complain
  989. // that there is freeable memory there. This is quite alright.
  990. _D3D_EB_FlushAllBuffers(pThisDisplay , TRUE);
  991. #endif
  992. START_SOFTWARE_CURSOR(pThisDisplay);
  993. // We don't handle the call because DDRAW has allocated out of AGP memory
  994. pdd->ddRVal = DD_OK;
  995. DBG_CB_EXIT(D3DDestroyD3DBuffer,DDHAL_DRIVER_HANDLED);
  996. return DDHAL_DRIVER_HANDLED;
  997. } // D3DDestroyD3DBuffer
  998. //-----------------------------Public Routine----------------------------------
  999. //
  1000. // D3DLockD3DBuffer
  1001. //
  1002. // Called by the runtime to lock a vertex buffer. We make sure
  1003. // it has been consumed by the queue, then we continue.
  1004. //
  1005. //
  1006. //-----------------------------------------------------------------------------
  1007. DWORD CALLBACK
  1008. D3DLockD3DBuffer(
  1009. LPDDHAL_LOCKDATA pld)
  1010. {
  1011. P3_THUNKEDDATA* pThisDisplay;
  1012. P3_VERTEXBUFFERINFO* pCurrentBuffer;
  1013. DBG_CB_ENTRY(D3DLockD3DBuffer);
  1014. GET_THUNKEDDATA(pThisDisplay, pld->lpDD);
  1015. VALIDATE_MODE_AND_STATE(pThisDisplay);
  1016. DBGDUMP_DDRAWSURFACE_LCL(DBGLVL, pld->lpDDSurface);
  1017. STOP_SOFTWARE_CURSOR(pThisDisplay);
  1018. DDRAW_OPERATION(pContext, pThisDisplay);
  1019. if (pld->bHasRect)
  1020. {
  1021. DISPDBG((ERRLVL,"Trying to lock a rect in a D3D buffer (error):"));
  1022. DISPDBG((ERRLVL,"left:%d, top:%d, right:%d, bottom:%d",
  1023. pld->rArea.left, pld->rArea.top,
  1024. pld->rArea.right, pld->rArea.bottom));
  1025. // This is just a debugging aid
  1026. // We will ignore any rects requested and lock the whole buffer
  1027. }
  1028. // If the buffer has a next pointer then it is in the circular list
  1029. // and we need to wait for the chip to finish consuming it.
  1030. pCurrentBuffer = (P3_VERTEXBUFFERINFO*)pld->lpDDSurface->lpGbl->dwReserved1;
  1031. if (pCurrentBuffer)
  1032. {
  1033. // Wait for the buffer to be consumed
  1034. __EB_Wait(pThisDisplay, pCurrentBuffer);
  1035. // Remove it from the queue
  1036. if (__EB_RemoveFromBufferQueue(pThisDisplay, pCurrentBuffer))
  1037. {
  1038. // There was an error removing it from the queue
  1039. DISPDBG((ERRLVL,"ERROR: This buffer should not have been freed"
  1040. "(its in use!)"));
  1041. }
  1042. }
  1043. else
  1044. {
  1045. DISPDBG((WRNLVL,"Buffer was not allocated by the driver"));
  1046. }
  1047. START_SOFTWARE_CURSOR(pThisDisplay);
  1048. // Return the pointer
  1049. pld->lpSurfData = (LPVOID)pld->lpDDSurface->lpGbl->fpVidMem;
  1050. DISPDBG((DBGLVL,"Returning 0x%x for locked buffer address",
  1051. pld->lpDDSurface->lpGbl->fpVidMem));
  1052. pld->ddRVal = DD_OK;
  1053. DBG_CB_EXIT(D3DLockD3DBuffer,DDHAL_DRIVER_HANDLED);
  1054. return DDHAL_DRIVER_HANDLED;
  1055. } // D3DLockD3DBuffer
  1056. //-----------------------------Public Routine----------------------------------
  1057. //
  1058. // D3DUnlockD3DBuffer
  1059. //
  1060. // Called by the runtime to unlock a vertex buffer.
  1061. //
  1062. //-----------------------------------------------------------------------------
  1063. DWORD CALLBACK
  1064. D3DUnlockD3DBuffer(
  1065. LPDDHAL_UNLOCKDATA puld)
  1066. {
  1067. DBG_CB_ENTRY(D3DUnlockD3DBuffer);
  1068. // We don't need to do anything special here.
  1069. puld->ddRVal = DD_OK;
  1070. DBG_CB_EXIT(D3DUnlockD3DBuffer,DDHAL_DRIVER_HANDLED);
  1071. return DDHAL_DRIVER_HANDLED;
  1072. } // D3DUnlockD3DBuffer
  1073. #endif // DX7_VERTEXBUFFERS
  1074. //@@END_DDKSPLIT