RenderPrimitiveDX12.cpp 4.1 KB

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