• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_BUFFER_H_
16 #define SRC_BUFFER_H_
17 
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 #include <utility>
22 #include <vector>
23 
24 #include "amber/result.h"
25 #include "amber/value.h"
26 #include "src/format.h"
27 
28 namespace amber {
29 
30 /// Types of buffers which can be created.
31 enum class BufferType : int8_t {
32   /// Unknown buffer type
33   kUnknown = -1,
34   /// A color buffer.
35   kColor = 0,
36   /// A depth/stencil buffer.
37   kDepth,
38   /// An index buffer.
39   kIndex,
40   /// A sampled buffer.
41   kSampled,
42   /// A storage buffer.
43   kStorage,
44   /// A uniform buffer.
45   kUniform,
46   /// A push constant buffer.
47   kPushConstant,
48   /// A vertex buffer.
49   kVertex
50 };
51 
52 /// A buffer stores data. The buffer maybe provided from the input script, or
53 /// maybe created as needed. A buffer must have a unique name.
54 class Buffer {
55  public:
56   /// Create a buffer of unknown type.
57   Buffer();
58   /// Create a buffer of |type_|.
59   explicit Buffer(BufferType type);
60 
61   ~Buffer();
62 
63   /// Returns the BufferType of this buffer.
GetBufferType()64   BufferType GetBufferType() const { return buffer_type_; }
65   /// Sets the BufferType for this buffer.
SetBufferType(BufferType type)66   void SetBufferType(BufferType type) { buffer_type_ = type; }
67 
68   /// Sets the Format of the buffer to |format|.
SetFormat(Format * format)69   void SetFormat(Format* format) {
70     format_is_default_ = false;
71     format_ = format;
72   }
73   /// Returns the Format describing the buffer data.
GetFormat()74   Format* GetFormat() const { return format_; }
75 
SetFormatIsDefault(bool val)76   void SetFormatIsDefault(bool val) { format_is_default_ = val; }
FormatIsDefault()77   bool FormatIsDefault() const { return format_is_default_; }
78 
79   /// Sets the buffer |name|.
SetName(const std::string & name)80   void SetName(const std::string& name) { name_ = name; }
81   /// Returns the name of the buffer.
GetName()82   std::string GetName() const { return name_; }
83 
84   /// Gets the number of elements this buffer is wide.
GetWidth()85   uint32_t GetWidth() const { return width_; }
86   /// Set the number of elements wide for the buffer.
SetWidth(uint32_t width)87   void SetWidth(uint32_t width) { width_ = width; }
88   /// Get the number of elements this buffer is high.
GetHeight()89   uint32_t GetHeight() const { return height_; }
90   /// Set the number of elements high for the buffer.
SetHeight(uint32_t height)91   void SetHeight(uint32_t height) { height_ = height; }
92 
93   // | ---------- Element ---------- | ElementCount == 1
94   // | Value | Value | Value | Value |   ValueCount == 4
95   // | | | | | | | | | | | | | | | | |  SizeInBytes == 16
96   // Note, the SizeInBytes maybe be greater then the size of the values. If
97   // the format is std140 and there are 3 rows, the SizeInBytes will be
98   // inflated to 4 values per row, instead of 3.
99 
100   /// Sets the number of elements in the buffer.
SetElementCount(uint32_t count)101   void SetElementCount(uint32_t count) { element_count_ = count; }
102   /// Returns the number of elements in the buffer.
ElementCount()103   uint32_t ElementCount() const { return element_count_; }
104 
105   /// Sets the number of values in the buffer.
SetValueCount(uint32_t count)106   void SetValueCount(uint32_t count) {
107     if (!format_) {
108       element_count_ = 0;
109       return;
110     }
111     if (format_->IsPacked()) {
112       element_count_ = count;
113     } else {
114       // This divides by the needed input values, not the values per element.
115       // The assumption being the values coming in are read from the input,
116       // where components are specified. The needed values maybe less then the
117       // values per element.
118       element_count_ = count / format_->InputNeededPerElement();
119     }
120   }
121   /// Returns the number of values in the buffer.
ValueCount()122   uint32_t ValueCount() const {
123     if (!format_)
124       return 0;
125     // Packed formats are single values.
126     if (format_->IsPacked())
127       return element_count_;
128     return element_count_ * format_->InputNeededPerElement();
129   }
130 
131   /// Returns the number of bytes needed for the data in the buffer.
GetSizeInBytes()132   uint32_t GetSizeInBytes() const {
133     if (!format_)
134       return 0;
135     return ElementCount() * format_->SizeInBytes();
136   }
137 
138   /// Returns the number of bytes for one element in the buffer.
GetElementStride()139   uint32_t GetElementStride() { return format_->SizeInBytes(); }
140 
141   /// Returns the number of bytes for one row of elements in the buffer.
GetRowStride()142   uint32_t GetRowStride() { return GetElementStride() * GetWidth(); }
143 
144   /// Sets the data into the buffer.
145   Result SetData(const std::vector<Value>& data);
146 
147   /// Resizes the buffer to hold |element_count| elements. This is separate
148   /// from SetElementCount() because we may not know the format when we set the
149   /// initial count. This requires the format to have been set.
150   void SetSizeInElements(uint32_t element_count);
151 
152   /// Resizes the buffer to hold |size_in_bytes|/format_->SizeInBytes()
153   /// number of elements while resizing the buffer to |size_in_bytes| bytes.
154   /// This requires the format to have been set. This is separate from
155   /// SetSizeInElements() since the given argument here is |size_in_bytes|
156   /// bytes vs |element_count| elements
157   void SetSizeInBytes(uint32_t size_in_bytes);
158 
159   /// Sets the max_size_in_bytes_ to |max_size_in_bytes| bytes
160   void SetMaxSizeInBytes(uint32_t max_size_in_bytes);
161   /// Returns max_size_in_bytes_ if it is not zero. Otherwise it means this
162   /// buffer is an amber buffer which has a fix size and returns
163   /// GetSizeInBytes()
164   uint32_t GetMaxSizeInBytes() const;
165 
166   /// Write |data| into the buffer |offset| bytes from the start. Write
167   /// |size_in_bytes| of data.
168   Result SetDataWithOffset(const std::vector<Value>& data, uint32_t offset);
169 
170   /// At each ubo, ssbo size and ssbo subdata size calls, recalculates
171   /// max_size_in_bytes_ and updates it if underlying buffer got bigger
172   Result RecalculateMaxSizeInBytes(const std::vector<Value>& data,
173                                    uint32_t offset);
174 
175   /// Writes |src| data into buffer at |offset|.
176   Result SetDataFromBuffer(const Buffer* src, uint32_t offset);
177 
178   /// Returns a pointer to the internal storage of the buffer.
ValuePtr()179   std::vector<uint8_t>* ValuePtr() { return &bytes_; }
180   /// Returns a pointer to the internal storage of the buffer.
ValuePtr()181   const std::vector<uint8_t>* ValuePtr() const { return &bytes_; }
182 
183   /// Returns a casted pointer to the internal storage of the buffer.
184   template <typename T>
GetValues()185   const T* GetValues() const {
186     return reinterpret_cast<const T*>(bytes_.data());
187   }
188 
189   /// Copies the buffer values to an other one
190   Result CopyTo(Buffer* buffer) const;
191 
192   /// Succeeds only if both buffer contents are equal
193   Result IsEqual(Buffer* buffer) const;
194 
195   /// Returns a histogram
196   std::vector<uint64_t> GetHistogramForChannel(uint32_t channel,
197                                                uint32_t num_bins) const;
198 
199   /// Checks if buffers are compatible for comparison
200   Result CheckCompability(Buffer* buffer) const;
201 
202   /// Compare the RMSE of this buffer against |buffer|. The RMSE must be
203   /// less than |tolerance|.
204   Result CompareRMSE(Buffer* buffer, float tolerance) const;
205 
206   /// Compare the histogram EMD of this buffer against |buffer|. The EMD must be
207   /// less than |tolerance|.
208   Result CompareHistogramEMD(Buffer* buffer, float tolerance) const;
209 
210  private:
211   uint32_t WriteValueFromComponent(const Value& value,
212                                    FormatMode mode,
213                                    uint32_t num_bits,
214                                    uint8_t* ptr);
215 
216   // Calculates the difference between the value stored in this buffer and
217   // those stored in |buffer| and returns all the values.
218   std::vector<double> CalculateDiffs(const Buffer* buffer) const;
219 
220   BufferType buffer_type_ = BufferType::kUnknown;
221   std::string name_;
222   /// max_size_in_bytes_ is the total size in bytes needed to hold the buffer
223   /// over all ubo, ssbo size and ssbo subdata size calls.
224   uint32_t max_size_in_bytes_ = 0;
225   uint32_t element_count_ = 0;
226   uint32_t width_ = 0;
227   uint32_t height_ = 0;
228   bool format_is_default_ = false;
229   std::vector<uint8_t> bytes_;
230   Format* format_ = nullptr;
231 };
232 
233 }  // namespace amber
234 
235 #endif  // SRC_BUFFER_H_
236