Fix RHI constant binding and add sphere test

This commit is contained in:
2026-03-26 01:23:29 +08:00
parent c5605c2a32
commit 39edb0b497
17 changed files with 959 additions and 35 deletions

View File

@@ -1,4 +1,5 @@
#include "XCEngine/RHI/D3D12/D3D12DescriptorSet.h"
#include "XCEngine/RHI/D3D12/D3D12Buffer.h"
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
#include "XCEngine/RHI/D3D12/D3D12Sampler.h"
@@ -6,6 +7,15 @@
namespace XCEngine {
namespace RHI {
namespace {
uint64_t AlignConstantBufferSize(size_t size) {
const uint64_t minSize = size > 0 ? static_cast<uint64_t>(size) : 1ull;
return (minSize + 255ull) & ~255ull;
}
} // namespace
D3D12DescriptorSet::D3D12DescriptorSet()
: m_heap(nullptr)
, m_offset(0)
@@ -39,6 +49,8 @@ void D3D12DescriptorSet::Shutdown() {
m_offset = 0;
m_count = 0;
m_bindingCount = 0;
m_constantBuffer.reset();
m_constantBufferCapacity = 0;
if (m_bindings != nullptr) {
delete[] m_bindings;
m_bindings = nullptr;
@@ -118,6 +130,7 @@ D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorSet::GetGPUHandle(uint32_t index) con
}
void D3D12DescriptorSet::WriteConstant(uint32_t binding, const void* data, size_t size, size_t offset) {
(void)binding;
size_t requiredSize = offset + size;
if (m_constantBufferData.size() < requiredSize) {
m_constantBufferData.resize(requiredSize);
@@ -126,5 +139,58 @@ void D3D12DescriptorSet::WriteConstant(uint32_t binding, const void* data, size_
m_constantBufferDirty = true;
}
bool D3D12DescriptorSet::HasBindingType(DescriptorType type) const {
for (uint32_t i = 0; i < m_bindingCount; ++i) {
if (static_cast<DescriptorType>(m_bindings[i].type) == type) {
return true;
}
}
return false;
}
uint32_t D3D12DescriptorSet::GetFirstBindingOfType(DescriptorType type) const {
for (uint32_t i = 0; i < m_bindingCount; ++i) {
if (static_cast<DescriptorType>(m_bindings[i].type) == type) {
return m_bindings[i].binding;
}
}
return UINT32_MAX;
}
bool D3D12DescriptorSet::UploadConstantBuffer() {
if (!HasBindingType(DescriptorType::CBV) || m_heap == nullptr || m_heap->GetDevice() == nullptr) {
return false;
}
const uint64_t alignedSize = AlignConstantBufferSize(m_constantBufferData.size());
if (!m_constantBuffer || m_constantBufferCapacity < alignedSize) {
auto constantBuffer = std::make_unique<D3D12Buffer>();
if (!constantBuffer->Initialize(
m_heap->GetDevice(),
alignedSize,
D3D12_RESOURCE_STATE_GENERIC_READ,
D3D12_HEAP_TYPE_UPLOAD)) {
return false;
}
constantBuffer->SetBufferType(BufferType::Constant);
constantBuffer->SetStride(static_cast<uint32_t>(alignedSize));
m_constantBuffer = std::move(constantBuffer);
m_constantBufferCapacity = alignedSize;
m_constantBufferDirty = true;
}
if (m_constantBufferDirty && !m_constantBufferData.empty()) {
m_constantBuffer->SetData(m_constantBufferData.data(), m_constantBufferData.size());
m_constantBufferDirty = false;
}
return m_constantBuffer != nullptr;
}
D3D12_GPU_VIRTUAL_ADDRESS D3D12DescriptorSet::GetConstantBufferGPUAddress() const {
return m_constantBuffer ? m_constantBuffer->GetGPUVirtualAddress() : 0;
}
} // namespace RHI
} // namespace XCEngine