RenderInstances.cpp 2.6 KB

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