Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
glShaderBuffer.cpp
Go to the documentation of this file.
1
2
4
10
12
13namespace Divide
14{
15
17 : ShaderBuffer( context, descriptor )
18 {
19 const size_t targetElementSize = Util::GetAlignmentCorrected( _params._elementSize, _alignmentRequirement );
20 if ( targetElementSize > _params._elementSize )
21 {
22 DIVIDE_ASSERT( (_params._elementSize * _params._elementCount) % _alignmentRequirement == 0u,
23 "ERROR: glShaderBuffer - element size and count combo is less than the minimum alignment requirement for current hardware! Pad the element size and or count a bit" );
24 }
25 else
26 {
27 DIVIDE_ASSERT( _params._elementSize == targetElementSize,
28 "ERROR: glShaderBuffer - element size is less than the minimum alignment requirement for current hardware! Pad the element size a bit" );
29 }
30 _alignedBufferSize = _params._elementCount * _params._elementSize;
31 _alignedBufferSize = static_cast<ptrdiff_t>(realign_offset( _alignedBufferSize, _alignmentRequirement ));
32
33 BufferImplParams implParams;
34 implParams._bufferParams = _params;
36 ? gl46core::GL_SHADER_STORAGE_BUFFER
37 : gl46core::GL_UNIFORM_BUFFER;
38
39 implParams._dataSize = _alignedBufferSize * queueLength();
41
42 _bufferImpl = std::make_unique<glBufferImpl>( context, implParams, descriptor._initialData, _name.empty() ? nullptr : _name.c_str() );
43
44 // Just to avoid issues with reading undefined or zero-initialised memory.
45 // This is quite fast so far so worth it for now.
46 if ( descriptor._separateReadWrite && descriptor._initialData.second > 0 )
47 {
48 for ( U32 i = 1u; i < descriptor._ringBufferLength; ++i )
49 {
50 bufferImpl()->writeOrClearBytes( _alignedBufferSize * i, descriptor._initialData.second, descriptor._initialData.first, true );
51 }
52 }
53 }
54
56 {
57 return bufferImpl()->writeOrClearBytes( range._startOffset, range._length, data );
58 }
59
60 void glShaderBuffer::readBytesInternal( BufferRange range, std::pair<bufferPtr, size_t> outData )
61 {
62 range._length = std::min( std::min( range._length, outData.second ), _alignedBufferSize - range._startOffset );
63 bufferImpl()->readBytes( range._startOffset, range._length, outData );
64 }
65
66 bool glShaderBuffer::bindByteRange( const U8 bindIndex, BufferRange range, I32 readIndex )
67 {
69
71
72 DIVIDE_ASSERT( to_size( range._length ) <= _maxSize && "glShaderBuffer::bindByteRange: attempted to bind a larger shader block than is allowed on the current platform" );
73 DIVIDE_ASSERT( range._startOffset == Util::GetAlignmentCorrected( range._startOffset, _alignmentRequirement ) );
74 if ( readIndex == -1 )
75 {
76 readIndex = queueReadIndex();
77 }
78
79 if ( bindIndex == ShaderProgram::k_commandBufferID )
80 {
81 result = GL_API::GetStateTracker().setActiveBuffer( gl46core::GL_DRAW_INDIRECT_BUFFER, bufferImpl()->memoryBlock()._bufferHandle );
82 GL_API::GetStateTracker()._drawIndirectBufferOffset = bufferImpl()->memoryBlock()._offset + (readIndex * _alignedBufferSize);
83 }
84 else if ( range._length > 0 ) [[likely]]
85 {
86 const size_t offset = bufferImpl()->memoryBlock()._offset + range._startOffset + (readIndex * _alignedBufferSize);
87 // If we bind the entire buffer, offset == 0u and range == 0u is a hack to bind the entire thing instead of a subrange
88 const size_t bindRange = Util::GetAlignmentCorrected( (offset == 0u && to_size( range._length ) == bufferImpl()->memoryBlock()._size) ? 0u : range._length, _alignmentRequirement );
89 result = GL_API::GetStateTracker().setActiveBufferIndexRange( bufferImpl()->params()._target,
90 bufferImpl()->memoryBlock()._bufferHandle,
91 bindIndex,
92 offset,
93 bindRange );
94 }
95
97 {
99 }
100
102 }
103
105 {
106 return _bufferImpl.get();
107 }
108
109} // namespace Divide
#define DIVIDE_ASSERT(...)
#define DIVIDE_UNEXPECTED_CALL()
#define PROFILE_SCOPE_AUTO(CATEGORY)
Definition: Profiler.h:87
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
Definition: GFXDevice.h:215
static GLStateTracker & GetStateTracker() noexcept
Definition: GLWrapper.cpp:1749
GFXDevice & context() const noexcept
I32 queueReadIndex() const noexcept
Definition: RingBuffer.h:63
U16 queueLength() const noexcept
Definition: RingBuffer.h:46
FORCE_INLINE BufferUsageType getUsage() const noexcept
Definition: ShaderBuffer.h:72
BufferParams _params
Definition: ShaderBuffer.h:92
bool bindByteRange(U8 bindIndex, BufferRange range, I32 readIndex=-1)
const glBufferImpl_uptr & bufferImpl() const noexcept
BufferLock writeBytesInternal(BufferRange range, const bufferPtr data) override
void readBytesInternal(BufferRange range, std::pair< bufferPtr, size_t > outData) override
glBufferImpl_uptr _bufferImpl
glShaderBuffer(GFXDevice &context, const ShaderBufferDescriptor &descriptor)
LockableBuffer * getBufferImpl() override final
constexpr Optick::Category::Type Graphics
Definition: Profiler.h:60
FORCE_INLINE size_t GetAlignmentCorrected(const size_t value, const size_t alignment) noexcept
Definition: MathHelper.inl:783
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
int32_t I32
uint8_t U8
constexpr size_t realign_offset(const size_t offset, const size_t align) noexcept
constexpr size_t to_size(const T value)
uint32_t U32
void * bufferPtr
BufferParams _bufferParams
Definition: glBufferImpl.h:45
gl46core::GLenum _target
Definition: glBufferImpl.h:46
size_t _elementSize
Buffer primitive size in bytes.
Definition: BufferParams.h:50
BindResult setActiveBuffer(gl46core::GLenum target, gl46core::GLuint bufferHandle)
Single place to change buffer objects for every target available.
BindResult setActiveBufferIndexRange(gl46core::GLenum target, gl46core::GLuint bufferHandle, gl46core::GLuint bindIndex, size_t offsetInBytes, size_t rangeInBytes)
Same as normal setActiveBuffer but handles proper binding of different ranges.
std::pair< bufferPtr, size_t > _initialData
Definition: ShaderBuffer.h:103
bool _separateReadWrite
Use a separate read/write index based on queue length.
Definition: ShaderBuffer.h:106