.. _program_listing_file_Source_Azura_RenderSystem_Src_D3D12_D3D12ScopedBuffer.cpp: Program Listing for File D3D12ScopedBuffer.cpp ============================================== |exhale_lsh| :ref:`Return to documentation for file ` (``Source\Azura\RenderSystem\Src\D3D12\D3D12ScopedBuffer.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: 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& 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& 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(pData); // NOLINT p_dataEnd = p_dataBegin + m_size; // NOLINT } HRESULT D3D12ScopedBuffer::SubAllocateFromBuffer(U32 size, U32 alignment) { p_dataCur = reinterpret_cast(Align(reinterpret_cast(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(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