RenderPrimitive.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #include <TestFramework.h>
  5. #include <Renderer/RenderPrimitive.h>
  6. #include <Renderer/FatalErrorIfFailed.h>
  7. void RenderPrimitive::ReleaseVertexBuffer()
  8. {
  9. if (mVtxBuffer != nullptr)
  10. {
  11. if (mVtxBufferInUploadHeap)
  12. mRenderer->RecycleD3DResourceOnUploadHeap(mVtxBuffer.Get(), mNumVtx * mVtxSize);
  13. else
  14. mRenderer->RecycleD3DObject(mVtxBuffer.Get());
  15. mVtxBuffer = nullptr;
  16. }
  17. mNumVtx = 0;
  18. mNumVtxToDraw = 0;
  19. mVtxSize = 0;
  20. mVtxBufferInUploadHeap = false;
  21. }
  22. void RenderPrimitive::ReleaseIndexBuffer()
  23. {
  24. if (mIdxBuffer != nullptr)
  25. {
  26. if (mIdxBufferInUploadHeap)
  27. mRenderer->RecycleD3DResourceOnUploadHeap(mIdxBuffer.Get(), mNumIdx * sizeof(uint32));
  28. else
  29. mRenderer->RecycleD3DObject(mIdxBuffer.Get());
  30. mIdxBuffer = nullptr;
  31. }
  32. mNumIdx = 0;
  33. mNumIdxToDraw = 0;
  34. mIdxBufferInUploadHeap = false;
  35. }
  36. void RenderPrimitive::Clear()
  37. {
  38. ReleaseVertexBuffer();
  39. ReleaseIndexBuffer();
  40. }
  41. void RenderPrimitive::CreateVertexBuffer(int inNumVtx, int inVtxSize, const void *inData)
  42. {
  43. ReleaseVertexBuffer();
  44. uint64 size = uint64(inNumVtx) * inVtxSize;
  45. if (inData != nullptr)
  46. {
  47. // Data provided, assume the buffer is static so allocate it on the GPU
  48. mVtxBuffer = mRenderer->CreateD3DResourceOnDefaultHeap(inData, size);
  49. mVtxBufferInUploadHeap = false;
  50. }
  51. else
  52. {
  53. // No data provided, create a buffer that will be uploaded to the GPU every time it is used
  54. mVtxBuffer = mRenderer->CreateD3DResourceOnUploadHeap(size);
  55. mVtxBufferInUploadHeap = true;
  56. }
  57. JPH_IF_DEBUG(mVtxBuffer->SetName(L"Vertex Buffer");)
  58. mNumVtx = inNumVtx;
  59. mNumVtxToDraw = inNumVtx;
  60. mVtxSize = inVtxSize;
  61. }
  62. void *RenderPrimitive::LockVertexBuffer()
  63. {
  64. void *mapped_resource;
  65. D3D12_RANGE range = { 0, 0 };
  66. FatalErrorIfFailed(mVtxBuffer->Map(0, &range, &mapped_resource));
  67. return mapped_resource;
  68. }
  69. void RenderPrimitive::UnlockVertexBuffer()
  70. {
  71. mVtxBuffer->Unmap(0, nullptr);
  72. }
  73. void RenderPrimitive::CreateIndexBuffer(int inNumIdx, const uint32 *inData)
  74. {
  75. ReleaseIndexBuffer();
  76. uint64 size = uint64(inNumIdx) * sizeof(uint32);
  77. if (inData != nullptr)
  78. {
  79. // Data provided, assume the buffer is static so allocate it on the GPU
  80. mIdxBuffer = mRenderer->CreateD3DResourceOnDefaultHeap(inData, size);
  81. mIdxBufferInUploadHeap = false;
  82. }
  83. else
  84. {
  85. // No data provided, create a buffer that will be uploaded to the GPU every time it is used
  86. mIdxBuffer = mRenderer->CreateD3DResourceOnUploadHeap(size);
  87. mIdxBufferInUploadHeap = true;
  88. }
  89. JPH_IF_DEBUG(mIdxBuffer->SetName(L"Index Buffer");)
  90. mNumIdx = inNumIdx;
  91. mNumIdxToDraw = inNumIdx;
  92. }
  93. uint32 *RenderPrimitive::LockIndexBuffer()
  94. {
  95. uint32 *mapped_resource;
  96. D3D12_RANGE range = { 0, 0 };
  97. FatalErrorIfFailed(mIdxBuffer->Map(0, &range, (void **)&mapped_resource));
  98. return mapped_resource;
  99. }
  100. void RenderPrimitive::UnlockIndexBuffer()
  101. {
  102. mIdxBuffer->Unmap(0, nullptr);
  103. }
  104. void RenderPrimitive::Draw() const
  105. {
  106. ID3D12GraphicsCommandList *command_list = mRenderer->GetCommandList();
  107. // Set topology
  108. command_list->IASetPrimitiveTopology(mType);
  109. if (mIdxBuffer == nullptr)
  110. {
  111. // Set vertex buffer
  112. D3D12_VERTEX_BUFFER_VIEW vb_view;
  113. vb_view.BufferLocation = mVtxBuffer->GetGPUVirtualAddress();
  114. vb_view.StrideInBytes = mVtxSize;
  115. vb_view.SizeInBytes = mNumVtxToDraw * mVtxSize;
  116. command_list->IASetVertexBuffers(0, 1, &vb_view);
  117. // Draw the non indexed primitive
  118. command_list->DrawInstanced(mNumVtxToDraw, 1, 0, 0);
  119. }
  120. else
  121. {
  122. // Set vertex buffer
  123. D3D12_VERTEX_BUFFER_VIEW vb_view;
  124. vb_view.BufferLocation = mVtxBuffer->GetGPUVirtualAddress();
  125. vb_view.StrideInBytes = mVtxSize;
  126. vb_view.SizeInBytes = mNumVtx * mVtxSize;
  127. command_list->IASetVertexBuffers(0, 1, &vb_view);
  128. // Set index buffer
  129. D3D12_INDEX_BUFFER_VIEW ib_view;
  130. ib_view.BufferLocation = mIdxBuffer->GetGPUVirtualAddress();
  131. ib_view.SizeInBytes = mNumIdxToDraw * sizeof(uint32);
  132. ib_view.Format = DXGI_FORMAT_R32_UINT;
  133. command_list->IASetIndexBuffer(&ib_view);
  134. // Draw indexed primitive
  135. command_list->DrawIndexedInstanced(mNumIdxToDraw, 1, 0, 0, 0);
  136. }
  137. }