RenderPrimitive.cpp 4.0 KB

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