RenderInstancesDX12.cpp 2.8 KB

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