GteGL4StructuredBuffer.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
9 #include <LowLevel/GteLogger.h>
11 #include <algorithm>
12 using namespace gte;
13 
15  :
17  mCounterOffset(0)
18 {
19  Initialize();
20 }
21 
22 std::shared_ptr<GEObject> GL4StructuredBuffer::Create(void*, GraphicsObject const* object)
23 {
24  if (object->GetType() == GT_STRUCTURED_BUFFER)
25  {
26  return std::make_shared<GL4StructuredBuffer>(
27  static_cast<StructuredBuffer const*>(object));
28  }
29 
30  LogError("Invalid object type.");
31  return nullptr;
32 }
33 
34 void GL4StructuredBuffer::AttachToUnit(GLint shaderStorageBufferUnit)
35 {
36  auto buffer = GetStructuredBuffer();
37 
38  // Cannot use glBindBufferBase because if structured buffer has a counter
39  // associated with it, then there are extra bytes allocated in the buffer
40  // to store the counter value. The structured buffer data does start
41  // at offset=0, so all that is needed is the actual number of data bytes
42  // in the StructuredBuffer object.
43  glBindBufferRange(GL_SHADER_STORAGE_BUFFER, shaderStorageBufferUnit, mGLHandle, 0, buffer->GetNumBytes());
44 }
45 
47 {
48  if (!targetBuffer)
49  {
50  return false;
51  }
52 
53  auto buffer = GetStructuredBuffer();
54  if (StructuredBuffer::CT_NONE == buffer->GetCounterType())
55  {
56  return false;
57  }
58 
62  return true;
63 }
64 
66 {
67  if (!sourceBuffer)
68  {
69  return false;
70  }
71 
72  auto buffer = GetStructuredBuffer();
73  if (StructuredBuffer::CT_NONE == buffer->GetCounterType())
74  {
75  return false;
76  }
77 
81  return true;
82 }
83 
85 {
86  auto buffer = GetStructuredBuffer();
87  if (StructuredBuffer::CT_NONE == buffer->GetCounterType())
88  {
89  return false;
90  }
91 
92  // Read the count from the location in the buffer past the
93  // structured buffer data.
94  GLint count;
97  glBindBuffer(mType, 0);
98 
99  count = (std::max)(0, count);
100  buffer->SetNumActiveElements(count);
101 
102  return true;
103 }
104 
106 {
107  auto buffer = GetStructuredBuffer();
108  if (StructuredBuffer::CT_NONE == buffer->GetCounterType())
109  {
110  return false;
111  }
112 
113  // Get count from front end structured buffer object.
114  if (!buffer->GetKeepInternalCount())
115  {
116  GLint count = buffer->GetNumActiveElements();
117 
119  glBufferSubData(mType, mCounterOffset, 4, &count);
120  glBindBuffer(mType, 0);
121  }
122 
123  return true;
124 }
125 
127 {
128  auto buffer = GetStructuredBuffer();
129 
130  // Need to read number of active elements first if there is
131  // a counter attached to this structured buffer.
132  if (StructuredBuffer::CT_NONE != buffer->GetCounterType())
133  {
134  if (!GetNumActiveElements())
135  {
136  return false;
137  }
138  }
139 
140  return GL4Buffer::CopyGpuToCpu();
141 }
142 
144 {
145  auto buffer = GetStructuredBuffer();
146 
147  // Regular structured buffer (no counter)?
148  if (StructuredBuffer::CT_NONE == buffer->GetCounterType())
149  {
151  }
152 
153  // Structured buffer has a counter (any type)?
154  // Allocate extra bytes to store the counter value.
155  else
156  {
158 
159  // How many bytes are needed for the structured buffer data.
160  auto numBytes = buffer->GetNumBytes();
161 
162  // Allocate extra bytes to align to 4 byte boundary for the offset.
163  // According to glBufferSubData:
164  // "Clients must align data elements consistent with the requirements
165  // of the client platform, with an additional base-level requirement
166  // that an offset within a buffer to a datum comprising N bytes be a
167  // multiple of N."
168  numBytes = ((numBytes + 3) / 4) * 4;
169  mCounterOffset = numBytes;
170 
171  // Allocate 4 extra bytes for the counter itself.
172  numBytes += 4;
173 
174  // Create a dynamic buffer that allows calls to glBufferSubData to
175  // update the buffer and the associated counter separately but within
176  // the same buffer contents.
177  glBufferData(mType, numBytes, nullptr, GL_DYNAMIC_DRAW);
178 
179  // Initialize the GPU memory from the buffer.
180  auto data = buffer->GetData();
181  if (data)
182  {
183  glBufferSubData(mType, 0, buffer->GetNumBytes(), buffer->GetData());
184  }
185 
186  // Initialize the count value.
187  GLint count = buffer->GetNumElements();
188  glBufferSubData(mType, mCounterOffset, 4, &count);
189 
190  glBindBuffer(mType, 0);
191  }
192 }
void AttachToUnit(GLint shaderStorageBufferUnit)
static std::shared_ptr< GEObject > Create(void *unused, GraphicsObject const *object)
int GLint
Definition: glcorearb.h:85
void APIENTRY glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
Definition: GteOpenGL.cpp:3429
#define GL_SHADER_STORAGE_BUFFER
Definition: glcorearb.h:2468
#define GL_DYNAMIC_DRAW
Definition: glcorearb.h:642
GraphicsObjectType GetType() const
bool CopyCounterValueToBuffer(GL4Buffer *targetBuffer, GLint offset)
void APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data)
Definition: GteOpenGL.cpp:1615
void APIENTRY glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
Definition: GteOpenGL.cpp:1589
virtual void Initialize() override
bool CopyCounterValueFromBuffer(GL4Buffer *sourceBuffer, GLint offset)
#define LogError(message)
Definition: GteLogger.h:92
void APIENTRY glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)
Definition: GteOpenGL.cpp:4596
GLboolean * data
Definition: glcorearb.h:126
GLint GLsizei count
Definition: glcorearb.h:400
GL4StructuredBuffer(StructuredBuffer const *cbuffer)
void APIENTRY glBindBuffer(GLenum target, GLuint buffer)
Definition: GteOpenGL.cpp:1534
GT_STRUCTURED_BUFFER
virtual bool CopyGpuToCpu() override
#define GL_COPY_WRITE_BUFFER
Definition: glcorearb.h:1418
#define GL_COPY_READ_BUFFER
Definition: glcorearb.h:1417
void APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
Definition: GteOpenGL.cpp:1602
GLintptr offset
Definition: glcorearb.h:660
GLuint buffer
Definition: glcorearb.h:655
GLuint object
Definition: glext.h:6426
virtual bool CopyGpuToCpu()
virtual void Initialize()
StructuredBuffer * GetStructuredBuffer() const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00