gfxD3D11PrimitiveBuffer.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2015 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "gfx/D3D11/gfxD3D11Device.h"
  23. #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
  24. #include "gfx/D3D11/gfxD3D11PrimitiveBuffer.h"
  25. #include "core/util/safeRelease.h"
  26. void GFXD3D11PrimitiveBuffer::prepare()
  27. {
  28. D3D11->_setPrimitiveBuffer(this);
  29. }
  30. void GFXD3D11PrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
  31. {
  32. AssertFatal(!mLocked, "GFXD3D11PrimitiveBuffer::lock - Can't lock a primitive buffer more than once!");
  33. mLocked = true;
  34. D3D11_MAP flags = D3D11_MAP_WRITE_DISCARD;
  35. switch(mBufferType)
  36. {
  37. case GFXBufferTypeImmutable:
  38. case GFXBufferTypeStatic:
  39. case GFXBufferTypeDynamic:
  40. flags = D3D11_MAP_WRITE_DISCARD;
  41. break;
  42. case GFXBufferTypeVolatile:
  43. // Get our range now...
  44. AssertFatal(indexStart == 0, "Cannot get a subrange on a volatile buffer.");
  45. AssertFatal(indexEnd < GFX_MAX_DYNAMIC_INDICES, "Cannot get more than GFX_MAX_DYNAMIC_INDICES in a volatile buffer. Up the constant!");
  46. // Get the primtive buffer
  47. mVolatileBuffer = D3D11->mDynamicPB;
  48. AssertFatal( mVolatileBuffer, "GFXD3D11PrimitiveBuffer::lock - No dynamic primitive buffer was available!");
  49. // We created the pool when we requested this volatile buffer, so assume it exists...
  50. if(mVolatileBuffer->mIndexCount + indexEnd > GFX_MAX_DYNAMIC_INDICES)
  51. {
  52. flags = D3D11_MAP_WRITE_DISCARD;
  53. mVolatileStart = indexStart = 0;
  54. indexEnd = indexEnd;
  55. }
  56. else
  57. {
  58. flags = D3D11_MAP_WRITE_NO_OVERWRITE;
  59. mVolatileStart = indexStart = mVolatileBuffer->mIndexCount;
  60. indexEnd += mVolatileBuffer->mIndexCount;
  61. }
  62. mVolatileBuffer->mIndexCount = indexEnd + 1;
  63. ib = mVolatileBuffer->ib;
  64. break;
  65. }
  66. mIndexStart = indexStart;
  67. mIndexEnd = indexEnd;
  68. if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
  69. {
  70. U32 sizeToLock = (indexEnd - indexStart) * sizeof(U16);
  71. *indexPtr = new U8[sizeToLock];
  72. mLockedBuffer = *indexPtr;
  73. }
  74. else
  75. {
  76. D3D11_MAPPED_SUBRESOURCE pIndexData;
  77. ZeroMemory(&pIndexData, sizeof(D3D11_MAPPED_SUBRESOURCE));
  78. HRESULT hr = D3D11DEVICECONTEXT->Map(ib, 0, flags, 0, &pIndexData);
  79. if(FAILED(hr))
  80. {
  81. AssertFatal(false, "GFXD3D11PrimitiveBuffer::lock - Could not lock primitive buffer.");
  82. }
  83. *indexPtr = (U8*)pIndexData.pData + (indexStart * sizeof(U16)) ;
  84. }
  85. #ifdef TORQUE_DEBUG
  86. // Allocate a debug buffer large enough for the lock
  87. // plus space for over and under run guard strings.
  88. mLockedSize = (indexEnd - indexStart) * sizeof(U16);
  89. const U32 guardSize = sizeof( _PBGuardString );
  90. mDebugGuardBuffer = new U8[mLockedSize+(guardSize*2)];
  91. // Setup the guard strings.
  92. dMemcpy( mDebugGuardBuffer, _PBGuardString, guardSize );
  93. dMemcpy( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize );
  94. // Store the real lock pointer and return our debug pointer.
  95. mLockedBuffer = *indexPtr;
  96. *indexPtr = (U16*)( mDebugGuardBuffer + guardSize );
  97. #endif // TORQUE_DEBUG
  98. }
  99. void GFXD3D11PrimitiveBuffer::unlock()
  100. {
  101. #ifdef TORQUE_DEBUG
  102. if ( mDebugGuardBuffer )
  103. {
  104. const U32 guardSize = sizeof( _PBGuardString );
  105. // First check the guard areas for overwrites.
  106. AssertFatal( dMemcmp( mDebugGuardBuffer, _PBGuardString, guardSize ) == 0,
  107. "GFXD3D11PrimitiveBuffer::unlock - Caught lock memory underrun!" );
  108. AssertFatal( dMemcmp( mDebugGuardBuffer + mLockedSize + guardSize, _PBGuardString, guardSize ) == 0,
  109. "GFXD3D11PrimitiveBuffer::unlock - Caught lock memory overrun!" );
  110. // Copy the debug content down to the real PB.
  111. dMemcpy( mLockedBuffer, mDebugGuardBuffer + guardSize, mLockedSize );
  112. // Cleanup.
  113. delete [] mDebugGuardBuffer;
  114. mDebugGuardBuffer = NULL;
  115. //mLockedBuffer = NULL;
  116. mLockedSize = 0;
  117. }
  118. #endif // TORQUE_DEBUG
  119. const U32 totalSize = this->mIndexCount * sizeof(U16);
  120. if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
  121. {
  122. //set up the update region of the buffer
  123. D3D11_BOX box;
  124. box.back = 1;
  125. box.front = 0;
  126. box.top = 0;
  127. box.bottom =1;
  128. box.left = mIndexStart *sizeof(U16);
  129. box.right = mIndexEnd * sizeof(U16);
  130. //update the real ib buffer
  131. D3D11DEVICECONTEXT->UpdateSubresource(ib, 0, &box,mLockedBuffer,totalSize, 0);
  132. //clean up the old buffer
  133. delete[] mLockedBuffer;
  134. mLockedBuffer = NULL;
  135. }
  136. else
  137. {
  138. D3D11DEVICECONTEXT->Unmap(ib,0);
  139. }
  140. mLocked = false;
  141. mIsFirstLock = false;
  142. mVolatileBuffer = NULL;
  143. }
  144. GFXD3D11PrimitiveBuffer::~GFXD3D11PrimitiveBuffer()
  145. {
  146. if( mBufferType != GFXBufferTypeVolatile )
  147. {
  148. SAFE_RELEASE(ib);
  149. }
  150. }
  151. void GFXD3D11PrimitiveBuffer::zombify()
  152. {
  153. if (mBufferType == GFXBufferTypeStatic || mBufferType == GFXBufferTypeImmutable)
  154. return;
  155. AssertFatal(!mLocked, "GFXD3D11PrimitiveBuffer::zombify - Cannot zombify a locked buffer!");
  156. if (mBufferType == GFXBufferTypeVolatile)
  157. {
  158. // We must null the volatile buffer else we're holding
  159. // a dead pointer which can be set on the device.
  160. ib = NULL;
  161. return;
  162. }
  163. // Dynamic buffers get released.
  164. SAFE_RELEASE(ib);
  165. }
  166. void GFXD3D11PrimitiveBuffer::resurrect()
  167. {
  168. if ( mBufferType != GFXBufferTypeDynamic )
  169. return;
  170. D3D11_BUFFER_DESC desc;
  171. desc.ByteWidth = sizeof(U16) * mIndexCount;
  172. desc.Usage = D3D11_USAGE_DYNAMIC;
  173. desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
  174. desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
  175. desc.MiscFlags = 0;
  176. desc.StructureByteStride = 0;
  177. HRESULT hr = D3D11DEVICE->CreateBuffer(&desc, NULL, &ib);
  178. if(FAILED(hr))
  179. {
  180. AssertFatal(false, "GFXD3D11PrimitiveBuffer::resurrect - Failed to allocate an index buffer.");
  181. }
  182. }