Program Listing for File D3D12ScopedBuffer.cpp¶
↰ Return to documentation for file (Source\Azura\RenderSystem\Src\D3D12\D3D12ScopedBuffer.cpp
)
#include "D3D12/D3D12ScopedBuffer.h"
#include "D3D12/d3dx12.h"
#include "D3D12/D3D12Macros.h"
#include "D3D12/D3D12Debug.h"
namespace Azura {
namespace D3D12 {
namespace {
SizeType Align(SizeType uLocation, SizeType uAlign) {
if ((0 == uAlign) || (uAlign & (uAlign - 1)) != 0) {
throw std::runtime_error("non-pow2 alignment");
}
return ((uLocation + (uAlign - 1)) & ~(uAlign - 1));
}
} // namespace
void D3D12ScopedBuffer::Create(const Microsoft::WRL::ComPtr<ID3D12Device>& device,
const D3D12_HEAP_PROPERTIES& heapProperties,
U32 size,
D3D12_RESOURCE_STATES resourceStates,
const Log& log_D3D12RenderSystem) {
m_size = size;
m_currentState = resourceStates;
const auto bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(m_size);
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "Creating Buffer of Size: %d", size);
VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateCommittedResource(
&heapProperties,
D3D12_HEAP_FLAG_NONE,
&bufferDesc,
resourceStates,
nullptr,
IID_PPV_ARGS(&m_buffer)), "Failed to create Buffer");
}
void D3D12ScopedBuffer::Create(const Microsoft::WRL::ComPtr<ID3D12Device>& device,
const D3D12_HEAP_PROPERTIES& heapProperties,
U32 size,
D3D12_RESOURCE_STATES resourceStates,
D3D12_RESOURCE_FLAGS resourceFlags,
const Log& log_D3D12RenderSystem) {
m_size = size;
m_currentState = resourceStates;
const auto bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(m_size, resourceFlags);
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "Creating Buffer of Size: %d", size);
VERIFY_D3D_OP(log_D3D12RenderSystem, device->CreateCommittedResource(
&heapProperties,
D3D12_HEAP_FLAG_NONE,
&bufferDesc,
resourceStates,
nullptr,
IID_PPV_ARGS(&m_buffer)), "Failed to create Buffer");
}
void D3D12ScopedBuffer::Map() {
void* pData;
CD3DX12_RANGE readRange(0, 0);
m_buffer->Map(0, &readRange, &pData);
p_dataCur = p_dataBegin = reinterpret_cast<U8*>(pData); // NOLINT
p_dataEnd = p_dataBegin + m_size; // NOLINT
}
HRESULT D3D12ScopedBuffer::SubAllocateFromBuffer(U32 size, U32 alignment) {
p_dataCur = reinterpret_cast<UINT8*>(Align(reinterpret_cast<SizeType>(p_dataCur), SizeType(alignment))); // NOLINT
return (p_dataCur + size > p_dataEnd) ? E_INVALIDARG : S_OK; // NOLINT
}
U32 D3D12ScopedBuffer::AppendData(const void* pData, U32 byteSize, U32 alignment, const Log& log_D3D12RenderSystem) {
VERIFY_D3D_OP(log_D3D12RenderSystem, SubAllocateFromBuffer(byteSize, alignment),
"Failed to Sub allocate inside buffer");
const auto byteOffset = GetCurrentOffset();
std::memcpy(p_dataCur, pData, byteSize);
p_dataCur += byteSize; // NOLINT
return byteOffset;
}
U32 D3D12ScopedBuffer::AppendTextureData(const void* pData,
U32 byteSize,
U32 alignment,
U32 textureWidth,
U32 textureRowPitch,
const Log& log_D3D12RenderSystem) {
const U32 numRows = byteSize / textureWidth;
const U32 scaledRowPitch = SCALE_SIZE(textureWidth, textureRowPitch);
const U32 requiredSize = scaledRowPitch * numRows;
VERIFY_D3D_OP(log_D3D12RenderSystem, SubAllocateFromBuffer(requiredSize, alignment),
"Failed to Sub allocate inside buffer");
const auto byteOffset = GetCurrentOffset();
const U8* textureData = reinterpret_cast<const U8*>(pData); // NOLINT
for (U32 idx = 0; idx < numRows; ++idx) {
std::memcpy(p_dataCur, textureData, textureWidth);
p_dataCur += scaledRowPitch; // NOLINT
textureData += textureWidth; // NOLINT
}
return byteOffset;
}
ID3D12Resource* D3D12ScopedBuffer::Real() const {
return m_buffer.Get();
}
D3D12_SHADER_RESOURCE_VIEW_DESC D3D12ScopedBuffer::GetSRV() const {
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; // NOLINT
srvDesc.Buffer.FirstElement = 0; // NOLINT
srvDesc.Buffer.NumElements = m_size / m_stride; // NOLINT
srvDesc.Buffer.StructureByteStride = m_stride; // NOLINT
return srvDesc;
}
D3D12_UNORDERED_ACCESS_VIEW_DESC D3D12ScopedBuffer::GetUAV() const {
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.Format = DXGI_FORMAT_UNKNOWN;
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; // NOLINT
uavDesc.Buffer.FirstElement = 0; // NOLINT
uavDesc.Buffer.NumElements = UINT(m_size / m_stride); // NOLINT
uavDesc.Buffer.StructureByteStride = m_stride; // NOLINT
return uavDesc;
}
U32 D3D12ScopedBuffer::GetStride() const {
return m_stride;
}
void D3D12ScopedBuffer::SetStride(U32 value) {
m_stride = value;
}
U32 D3D12ScopedBuffer::GetSize() const {
return m_size;
}
U32 D3D12ScopedBuffer::GetCurrentOffset() const {
return U32(p_dataCur - p_dataBegin);
}
void D3D12ScopedBuffer::Reset() {
p_dataCur = p_dataBegin;
}
void D3D12ScopedBuffer::Transition(ID3D12GraphicsCommandList* commandList,
D3D12_RESOURCE_STATES toState, const Log& log_D3D12RenderSystem) {
UNUSED(log_D3D12RenderSystem); // Release Mode
if (m_currentState == toState)
{
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "Current State is same as Transition State: %s", D3D12ResourceStateToString(toState));
return;
}
LOG_DBG(log_D3D12RenderSystem, LOG_LEVEL, "Transitioning State: %s => %s", D3D12ResourceStateToString(m_currentState), D3D12ResourceStateToString(toState));
const auto resourceBarrier = CD3DX12_RESOURCE_BARRIER::Transition(m_buffer.Get(), m_currentState, toState);
commandList->ResourceBarrier(1, &resourceBarrier);
m_currentState = toState;
}
} // namespace D3D12
} // namespace Azura