| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #pragma once
- #include <AnKi/Gr/GrObject.h>
- #include <AnKi/Util/WeakArray.h>
- namespace anki {
- /// @addtogroup graphics
- /// @{
- /// Buffer init info.
- /// @memberof Buffer
- class BufferInitInfo : public GrBaseInitInfo
- {
- public:
- PtrSize m_size = 0;
- BufferUsageBit m_usage = BufferUsageBit::kNone;
- BufferMapAccessBit m_mapAccess = BufferMapAccessBit::kNone;
- BufferInitInfo(CString name = {})
- : GrBaseInitInfo(name)
- {
- }
- BufferInitInfo(PtrSize size, BufferUsageBit usage, BufferMapAccessBit mapAccess, CString name = {})
- : GrBaseInitInfo(name)
- , m_size(size)
- , m_usage(usage)
- , m_mapAccess(mapAccess)
- {
- }
- Bool isValid() const
- {
- return m_size && !!m_usage;
- }
- };
- /// GPU buffer.
- class Buffer : public GrObject
- {
- ANKI_GR_OBJECT
- public:
- static constexpr GrObjectType kClassType = GrObjectType::kBuffer;
- /// Return the size of the buffer.
- PtrSize getSize() const
- {
- ANKI_ASSERT(m_size > 0);
- return m_size;
- }
- /// Return the BufferUsageBit of the Buffer.
- BufferUsageBit getBufferUsage() const
- {
- ANKI_ASSERT(!!m_usage);
- return m_usage;
- }
- /// Return the BufferMapAccessBit of the Buffer.
- BufferMapAccessBit getMapAccess() const
- {
- return m_access;
- }
- /// Map the buffer.
- /// @param offset The starting offset.
- /// @param range The range to map or kMaxPtrSize to map until the end.
- /// @param access The access to the buffer.
- void* map(PtrSize offset, PtrSize range, BufferMapAccessBit access);
- /// Flush the buffer from the CPU caches. Call it to make the buffer memory available to the GPU.
- /// @param offset The starting offset.
- /// @param range The range to map or kMaxPtrSize to map until the end.
- void flush(PtrSize offset, PtrSize range) const;
- /// Invalidate the buffer from the CPU caches. Call it to ready the buffer to see GPU updates.
- /// @param offset The starting offset.
- /// @param range The range to map or kMaxPtrSize to map until the end.
- void invalidate(PtrSize offset, PtrSize range) const;
- /// Convenience map method.
- /// @param offset The starting offset.
- /// @param elementCount The number of T element sto map.
- /// @param access The access to the buffer.
- /// @return The array that was mapped.
- template<typename T>
- WeakArray<T, PtrSize> map(PtrSize offset, PtrSize elementCount, BufferMapAccessBit access)
- {
- return WeakArray<T, PtrSize>(static_cast<T*>(map(offset, sizeof(T) * elementCount, access)), elementCount);
- }
- /// Unmap the buffer.
- void unmap();
- /// Get the GPU adress of the buffer.
- U64 getGpuAddress() const
- {
- ANKI_ASSERT(m_gpuAddress);
- return m_gpuAddress;
- }
- protected:
- PtrSize m_size = 0;
- BufferUsageBit m_usage = BufferUsageBit::kNone;
- BufferMapAccessBit m_access = BufferMapAccessBit::kNone;
- U64 m_gpuAddress = 0;
- /// Construct.
- Buffer(CString name)
- : GrObject(kClassType, name)
- {
- }
- /// Destroy.
- ~Buffer()
- {
- }
- private:
- /// Allocate and initialize a new instance.
- [[nodiscard]] static Buffer* newInstance(const BufferInitInfo& init);
- };
- /// A part of a buffer.
- class BufferView
- {
- public:
- BufferView() = default;
- BufferView(const BufferView&) = default;
- explicit BufferView(Buffer* buffer)
- : m_buffer(buffer)
- , m_offset(0)
- , m_range(buffer->getSize())
- {
- validate();
- }
- BufferView(Buffer* buffer, PtrSize offset, PtrSize range)
- : m_buffer(buffer)
- , m_offset(offset)
- , m_range(range)
- {
- validate();
- }
- BufferView& operator=(const BufferView&) = default;
- explicit operator Bool() const
- {
- return isValid();
- }
- [[nodiscard]] Buffer& getBuffer() const
- {
- validate();
- return *m_buffer;
- }
- [[nodiscard]] const PtrSize& getOffset() const
- {
- validate();
- return m_offset;
- }
- BufferView& setOffset(PtrSize offset)
- {
- validate();
- m_offset = offset;
- validate();
- return *this;
- }
- BufferView& incrementOffset(PtrSize bytes)
- {
- validate();
- ANKI_ASSERT(m_range >= bytes);
- m_range -= bytes;
- m_offset += bytes;
- if(m_range == 0)
- {
- *this = {};
- }
- else
- {
- validate();
- }
- return *this;
- }
- [[nodiscard]] const PtrSize& getRange() const
- {
- validate();
- return m_range;
- }
- BufferView& setRange(PtrSize range)
- {
- validate();
- if(range != 0)
- {
- m_range = range;
- validate();
- }
- else
- {
- *this = {};
- }
- return *this;
- }
- [[nodiscard]] Bool isValid() const
- {
- return m_buffer != nullptr;
- }
- [[nodiscard]] Bool overlaps(const BufferView& b) const
- {
- validate();
- b.validate();
- Bool overlaps = m_buffer == b.m_buffer;
- if(m_offset <= b.m_offset)
- {
- overlaps = overlaps && (m_offset + m_range > b.m_offset);
- }
- else
- {
- overlaps = overlaps && (b.m_offset + b.m_range > m_offset);
- }
- return overlaps;
- }
- private:
- Buffer* m_buffer = nullptr;
- PtrSize m_offset = kMaxPtrSize;
- PtrSize m_range = 0;
- void validate() const
- {
- ANKI_ASSERT(m_buffer && m_range > 0);
- ANKI_ASSERT(m_range <= m_buffer->getSize() && m_offset < m_buffer->getSize()); // Do that to ensure the next line won't overflow
- ANKI_ASSERT(m_offset + m_range <= m_buffer->getSize());
- }
- };
- /// @}
- } // end namespace anki
|