RenderInstancesDX12.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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/RenderInstancesDX12.h>
  6. #include <Renderer/DX12/RenderPrimitiveDX12.h>
  7. #include <Renderer/DX12/FatalErrorIfFailedDX12.h>
  8. void RenderInstancesDX12::Clear()
  9. {
  10. if (mInstanceBuffer != nullptr)
  11. mRenderer->RecycleD3DResourceOnUploadHeap(mInstanceBuffer.Get(), mInstanceBufferSize);
  12. mInstanceBuffer = nullptr;
  13. mInstanceBufferSize = 0;
  14. mInstanceSize = 0;
  15. }
  16. void RenderInstancesDX12::CreateBuffer(int inNumInstances, int inInstanceSize)
  17. {
  18. if (mInstanceBuffer == nullptr || mInstanceBufferSize < inNumInstances * inInstanceSize)
  19. {
  20. // Delete the old buffer
  21. Clear();
  22. // Calculate size
  23. mInstanceBufferSize = inNumInstances * inInstanceSize;
  24. // Create buffer
  25. mInstanceBuffer = mRenderer->CreateD3DResourceOnUploadHeap(mInstanceBufferSize);
  26. JPH_IF_DEBUG(mInstanceBuffer->SetName(L"Instance Buffer");)
  27. }
  28. // Update parameters
  29. mInstanceSize = inInstanceSize;
  30. }
  31. void *RenderInstancesDX12::Lock()
  32. {
  33. uint32 *mapped_resource;
  34. D3D12_RANGE range = { 0, 0 };
  35. mInstanceBuffer->Map(0, &range, (void **)&mapped_resource);
  36. return mapped_resource;
  37. }
  38. void RenderInstancesDX12::Unlock()
  39. {
  40. mInstanceBuffer->Unmap(0, nullptr);
  41. }
  42. void RenderInstancesDX12::Draw(RenderPrimitive *inPrimitive, int inStartInstance, int inNumInstances) const
  43. {
  44. if (inNumInstances <= 0)
  45. return;
  46. RenderPrimitiveDX12 *primitive = static_cast<RenderPrimitiveDX12 *>(inPrimitive);
  47. ID3D12GraphicsCommandList *command_list = mRenderer->GetCommandList();
  48. // Set topology
  49. command_list->IASetPrimitiveTopology(primitive->mType == PipelineState::ETopology::Triangle? D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST : D3D_PRIMITIVE_TOPOLOGY_LINELIST);
  50. D3D12_VERTEX_BUFFER_VIEW vb_view[2];
  51. // Vertex buffer
  52. vb_view[0].BufferLocation = primitive->mVtxBuffer->GetGPUVirtualAddress();
  53. vb_view[0].StrideInBytes = primitive->mVtxSize;
  54. vb_view[0].SizeInBytes = primitive->mNumVtxToDraw * primitive->mVtxSize;
  55. // Instances buffer
  56. vb_view[1].BufferLocation = mInstanceBuffer->GetGPUVirtualAddress();
  57. vb_view[1].StrideInBytes = mInstanceSize;
  58. vb_view[1].SizeInBytes = mInstanceBufferSize;
  59. command_list->IASetVertexBuffers(0, 2, &vb_view[0]);
  60. if (primitive->mIdxBuffer == nullptr)
  61. {
  62. // Draw instanced primitive
  63. command_list->DrawInstanced(primitive->mNumVtxToDraw, inNumInstances, 0, inStartInstance);
  64. }
  65. else
  66. {
  67. // Set index buffer
  68. D3D12_INDEX_BUFFER_VIEW ib_view;
  69. ib_view.BufferLocation = primitive->mIdxBuffer->GetGPUVirtualAddress();
  70. ib_view.SizeInBytes = primitive->mNumIdxToDraw * sizeof(uint32);
  71. ib_view.Format = DXGI_FORMAT_R32_UINT;
  72. command_list->IASetIndexBuffer(&ib_view);
  73. // Draw instanced primitive
  74. command_list->DrawIndexedInstanced(primitive->mNumIdxToDraw, inNumInstances, 0, 0, inStartInstance);
  75. }
  76. }