| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
- // SPDX-FileCopyrightText: 2025 Jorrit Rouwe
- // SPDX-License-Identifier: MIT
- #include <Jolt/Jolt.h>
- #ifdef JPH_USE_DX12
- #include <Jolt/Compute/DX12/ComputeBufferDX12.h>
- #include <Jolt/Compute/DX12/ComputeSystemDX12.h>
- JPH_NAMESPACE_BEGIN
- ComputeBufferDX12::ComputeBufferDX12(ComputeSystemDX12 *inComputeSystem, EType inType, uint64 inSize, uint inStride) :
- ComputeBuffer(inType, inSize, inStride),
- mComputeSystem(inComputeSystem)
- {
- }
- bool ComputeBufferDX12::Initialize(const void *inData)
- {
- uint64 buffer_size = mSize * mStride;
- switch (mType)
- {
- case EType::UploadBuffer:
- mBufferCPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_FLAG_NONE, buffer_size);
- mBufferGPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_FLAG_NONE, buffer_size);
- if (mBufferCPU == nullptr || mBufferGPU == nullptr)
- return false;
- break;
- case EType::ConstantBuffer:
- mBufferCPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_FLAG_NONE, buffer_size);
- if (mBufferCPU == nullptr)
- return false;
- break;
- case EType::ReadbackBuffer:
- JPH_ASSERT(inData == nullptr, "Can't upload data to a readback buffer");
- mBufferCPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_READBACK, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_FLAG_NONE, buffer_size);
- if (mBufferCPU == nullptr)
- return false;
- break;
- case EType::Buffer:
- JPH_ASSERT(inData != nullptr);
- mBufferCPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_FLAG_NONE, buffer_size);
- mBufferGPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_FLAG_NONE, buffer_size);
- if (mBufferCPU == nullptr || mBufferGPU == nullptr)
- return false;
- mNeedsSync = true;
- break;
- case EType::RWBuffer:
- if (inData != nullptr)
- {
- mBufferCPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_UPLOAD, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_FLAG_NONE, buffer_size);
- if (mBufferCPU == nullptr)
- return false;
- mNeedsSync = true;
- }
- mBufferGPU = mComputeSystem->CreateD3DResource(D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, buffer_size);
- if (mBufferGPU == nullptr)
- return false;
- break;
- }
- // Copy data to upload buffer
- if (inData != nullptr)
- {
- void *data = nullptr;
- D3D12_RANGE range = { 0, 0 }; // We're not going to read
- mBufferCPU->Map(0, &range, &data);
- memcpy(data, inData, size_t(buffer_size));
- mBufferCPU->Unmap(0, nullptr);
- }
- return true;
- }
- bool ComputeBufferDX12::Barrier(ID3D12GraphicsCommandList *inCommandList, D3D12_RESOURCE_STATES inTo) const
- {
- // Check if state changed
- if (mCurrentState == inTo)
- return false;
- // Only buffers in GPU memory can change state
- if (mType != ComputeBuffer::EType::Buffer && mType != ComputeBuffer::EType::RWBuffer)
- return true;
- D3D12_RESOURCE_BARRIER barrier;
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
- barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barrier.Transition.pResource = GetResourceGPU();
- barrier.Transition.StateBefore = mCurrentState;
- barrier.Transition.StateAfter = inTo;
- barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
- inCommandList->ResourceBarrier(1, &barrier);
- mCurrentState = inTo;
- return true;
- }
- void ComputeBufferDX12::RWBarrier(ID3D12GraphicsCommandList *inCommandList)
- {
- JPH_ASSERT(mCurrentState == D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
- D3D12_RESOURCE_BARRIER barrier;
- barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
- barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
- barrier.Transition.pResource = GetResourceGPU();
- inCommandList->ResourceBarrier(1, &barrier);
- }
- bool ComputeBufferDX12::SyncCPUToGPU(ID3D12GraphicsCommandList *inCommandList) const
- {
- if (!mNeedsSync)
- return false;
- Barrier(inCommandList, D3D12_RESOURCE_STATE_COPY_DEST);
- inCommandList->CopyResource(GetResourceGPU(), GetResourceCPU());
- mNeedsSync = false;
- return true;
- }
- void *ComputeBufferDX12::MapInternal(EMode inMode)
- {
- void *mapped_resource = nullptr;
- switch (inMode)
- {
- case EMode::Read:
- JPH_ASSERT(mType == EType::ReadbackBuffer);
- if (HRFailed(mBufferCPU->Map(0, nullptr, &mapped_resource)))
- return nullptr;
- break;
- case EMode::Write:
- {
- JPH_ASSERT(mType == EType::UploadBuffer || mType == EType::ConstantBuffer);
- D3D12_RANGE range = { 0, 0 }; // We're not going to read
- if (HRFailed(mBufferCPU->Map(0, &range, &mapped_resource)))
- return nullptr;
- mNeedsSync = true;
- }
- break;
- }
- return mapped_resource;
- }
- void ComputeBufferDX12::UnmapInternal()
- {
- mBufferCPU->Unmap(0, nullptr);
- }
- ComputeBufferResult ComputeBufferDX12::CreateReadBackBuffer() const
- {
- return mComputeSystem->CreateComputeBuffer(EType::ReadbackBuffer, mSize, mStride);
- }
- JPH_NAMESPACE_END
- #endif // JPH_USE_DX12
|