GteConstantBuffer.h
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.1 (2016/08/29)
7 
8 #pragma once
9 
10 #include <LowLevel/GteLogger.h>
11 #include <Graphics/GteBuffer.h>
13 #include <algorithm>
14 
15 namespace gte
16 {
17 
19 {
20 public:
21  // Construction.
22  ConstantBuffer(size_t numBytes, bool allowDynamicUpdate);
23 
24  // Access to constant buffer members using the layout of a shader
25  // program itself is allowed as long as you have attached the constant
26  // buffer to a shader first.
27  // std::shared_ptr<VertexShader> vshader = <some shader>;
28  // std::shared_ptr<ConstantBuffer> cbuffer = <buffer for the shader>;
29  // vshader->Set("MyCBuffer", cbuffer);
30  // Now you can use SetMember/GetMember calls successfully. In these
31  // calls, you are required to specify the correct type T for the member.
32  // No checking is performed for the size of the input; i.e., too large a
33  // 'value' will cause a memory overwrite within the buffer. The code
34  // does test to ensure that no overwrite occurs outside the buffer.
35 
36  inline void SetLayout(std::vector<MemberLayout> const& layout);
37  inline std::vector<MemberLayout> const& GetLayout() const;
38 
39  // Test for existence of a member with the specified name.
40  bool HasMember(std::string const& name) const;
41 
42  // Set or get a non-array member.
43  template <typename T>
44  bool SetMember(std::string const& name, T const& value);
45 
46  template <typename T>
47  bool GetMember(std::string const& name, T& value) const;
48 
49  // Set or get an array member.
50  template <typename T>
51  bool SetMember(std::string const& name, unsigned int index,
52  T const& value);
53 
54  template <typename T>
55  bool GetMember(std::string const& name, unsigned int index,
56  T& value) const;
57 
58 protected:
59  // Direct3D 11 requires the storage to be a multiple of 16 bytes.
60  // Direct3D 12 requires the storage to be a multiple of 256 bytes.
61  // This function rounds to the nearest multiple when allocating
62  // buffer memory.
63  static size_t GetRoundedNumBytes(size_t numBytes);
64 
65  std::vector<MemberLayout> mLayout;
66 
67 public:
68  // For use by the Shader class for storing reflection information.
69  static int const shaderDataLookup = 0;
70 };
71 
72 
73 inline void ConstantBuffer::SetLayout(std::vector<MemberLayout> const& layout)
74 {
75  mLayout = layout;
76 }
77 
78 inline std::vector<MemberLayout> const& ConstantBuffer::GetLayout() const
79 {
80  return mLayout;
81 }
82 
83 template <typename T>
85 {
86  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
87  [&name](MemberLayout const& item){ return name == item.name; });
88 
89  if (iter == mLayout.end())
90  {
91  LogError("Failed to find member name " + name + ".");
92  return false;
93  }
94 
95  if (iter->numElements > 0)
96  {
97  LogError("Member is an array, use SetMember(name,index,value).");
98  return false;
99  }
100 
101  if (iter->offset + sizeof(T) > mNumBytes)
102  {
103  LogError("Writing will access memory outside the buffer.");
104  return false;
105  }
106 
107  T* target = reinterpret_cast<T*>(mData + iter->offset);
108  *target = value;
109  return true;
110 }
111 
112 template <typename T>
114 {
115  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
116  [&name](MemberLayout const& item){ return name == item.name; });
117 
118  if (iter == mLayout.end())
119  {
120  LogError("Failed to find member name " + name + ".");
121  return false;
122  }
123 
124  if (iter->numElements > 0)
125  {
126  LogError("Member is an array, use GetMember(name,index,value).");
127  return false;
128  }
129 
130  if (iter->offset + sizeof(T) > mNumBytes)
131  {
132  LogError("Reading will access memory outside the buffer.");
133  return false;
134  }
135 
136  T* target = reinterpret_cast<T*>(mData + iter->offset);
137  value = *target;
138  return true;
139 }
140 
141 template <typename T>
143  T const& value)
144 {
145  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
146  [&name](MemberLayout const& item){ return name == item.name; });
147 
148  if (iter == mLayout.end())
149  {
150  LogError("Failed to find member name " + name + ".");
151  return false;
152  }
153 
154  if (iter->numElements == 0)
155  {
156  LogError("Member is a singleton, use SetMember(name,value).");
157  return false;
158  }
159 
160  if (index >= iter->numElements)
161  {
162  LogError("Index is out of range for the member array.");
163  return false;
164  }
165 
166  if (iter->offset + (index + 1)*sizeof(T) > mNumBytes)
167  {
168  LogError("Writing will access memory outside the buffer.");
169  return false;
170  }
171 
172  T* target = reinterpret_cast<T*>(mData + iter->offset + index*sizeof(T));
173  *target = value;
174  return true;
175 }
176 
177 template <typename T>
179  T& value) const
180 {
181  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
182  [&name](MemberLayout const& item){ return name == item.name; });
183 
184  if (iter == mLayout.end())
185  {
186  LogError("Failed to find member name " + name + ".");
187  return false;
188  }
189 
190  if (iter->numElements == 0)
191  {
192  LogError("Member is a singleton, use GetMember(name,value).");
193  return false;
194  }
195 
196  if (index >= iter->numElements)
197  {
198  LogError("Index is out of range for the member array.");
199  return false;
200  }
201 
202  if (iter->offset + (index + 1)*sizeof(T) > mNumBytes)
203  {
204  LogError("Reading will access memory outside the buffer.");
205  return false;
206  }
207 
208  T* target = reinterpret_cast<T*>(mData + iter->offset + index*sizeof(T));
209  value = *target;
210  return true;
211 }
212 
213 
214 }
bool SetMember(std::string const &name, T const &value)
GLsizei const GLfloat * value
Definition: glcorearb.h:819
void SetLayout(std::vector< MemberLayout > const &layout)
GLuint const GLchar * name
Definition: glcorearb.h:781
GLenum target
Definition: glcorearb.h:1662
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
#define LogError(message)
Definition: GteLogger.h:92
std::vector< MemberLayout > const & GetLayout() const
bool GetMember(std::string const &name, T &value) const
GLuint index
Definition: glcorearb.h:781
#define GTE_IMPEXP
Definition: GTEngineDEF.h:63
std::vector< MemberLayout > mLayout


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59