• 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/amber.h"
25 #include "amber/result.h"
26 #include "amber/value.h"
27 #include "src/format.h"
28 #include "src/image.h"
29 
30 namespace amber {
31 
32 class Sampler;
33 
34 /// Types of buffers which can be created.
35 enum class BufferType : int8_t {
36   /// Unknown buffer type
37   kUnknown = -1,
38   /// A color buffer.
39   kColor = 0,
40   /// A depth/stencil buffer.
41   kDepthStencil,
42   /// An index buffer.
43   kIndex,
44   /// A sampled image.
45   kSampledImage,
46   /// A combined image sampler.
47   kCombinedImageSampler,
48   /// A storage buffer.
49   kStorage,
50   /// A dynamic storage buffer.
51   kStorageDynamic,
52   /// A uniform buffer.
53   kUniform,
54   /// A dynamic uniform buffer.
55   kUniformDynamic,
56   /// A push constant buffer.
57   kPushConstant,
58   /// A vertex buffer.
59   kVertex,
60   /// A storage image.
61   kStorageImage,
62   /// A uniform texel buffer.
63   kUniformTexelBuffer,
64   /// A storage texel buffer.
65   kStorageTexelBuffer,
66   /// A resolve target.
67   kResolve
68 };
69 
70 enum class InputRate : int8_t {
71   kVertex = 0,
72   kInstance,
73 };
74 
75 /// A buffer stores data. The buffer maybe provided from the input script, or
76 /// maybe created as needed. A buffer must have a unique name.
77 class Buffer {
78  public:
79   /// Create a buffer of unknown type.
80   Buffer();
81 
82   ~Buffer();
83 
84   /// Sets the Format of the buffer to |format|.
SetFormat(Format * format)85   void SetFormat(Format* format) {
86     format_is_default_ = false;
87     format_ = format;
88   }
89   /// Returns the Format describing the buffer data.
GetFormat()90   Format* GetFormat() const { return format_; }
91 
92   /// Sets the sampler used with buffer of combined image sampler type.
SetSampler(Sampler * sampler)93   void SetSampler(Sampler* sampler) { sampler_ = sampler; }
94   /// Returns the sampler of combined image sampler buffer.
GetSampler()95   Sampler* GetSampler() const { return sampler_; }
96 
SetFormatIsDefault(bool val)97   void SetFormatIsDefault(bool val) { format_is_default_ = val; }
FormatIsDefault()98   bool FormatIsDefault() const { return format_is_default_; }
99 
100   /// Sets the buffer |name|.
SetName(const std::string & name)101   void SetName(const std::string& name) { name_ = name; }
102   /// Returns the name of the buffer.
GetName()103   std::string GetName() const { return name_; }
104 
105   /// Gets the number of elements this buffer is wide.
GetWidth()106   uint32_t GetWidth() const { return width_; }
107   /// Set the number of elements wide for the buffer.
SetWidth(uint32_t width)108   void SetWidth(uint32_t width) { width_ = width; }
109   /// Get the number of elements this buffer is high.
GetHeight()110   uint32_t GetHeight() const { return height_; }
111   /// Set the number of elements high for the buffer.
SetHeight(uint32_t height)112   void SetHeight(uint32_t height) { height_ = height; }
113   /// Get the number of elements this buffer is deep.
GetDepth()114   uint32_t GetDepth() const { return depth_; }
115   /// Set the number of elements this buffer is deep.
SetDepth(uint32_t depth)116   void SetDepth(uint32_t depth) { depth_ = depth; }
117 
118   /// Get the image dimensionality.
GetImageDimension()119   ImageDimension GetImageDimension() const { return image_dim_; }
120   /// Set the image dimensionality.
SetImageDimension(ImageDimension dim)121   void SetImageDimension(ImageDimension dim) { image_dim_ = dim; }
122 
123   // | ---------- Element ---------- | ElementCount == 1
124   // | Value | Value | Value | Value |   ValueCount == 4
125   // | | | | | | | | | | | | | | | | |  SizeInBytes == 16
126   // Note, the SizeInBytes maybe be greater then the size of the values. If
127   // the format is std140 and there are 3 rows, the SizeInBytes will be
128   // inflated to 4 values per row, instead of 3.
129 
130   /// Sets the number of elements in the buffer.
SetElementCount(uint32_t count)131   void SetElementCount(uint32_t count) { element_count_ = count; }
132   /// Returns the number of elements in the buffer.
ElementCount()133   uint32_t ElementCount() const { return element_count_; }
134 
135   /// Sets the number of values in the buffer.
SetValueCount(uint32_t count)136   void SetValueCount(uint32_t count) {
137     if (!format_) {
138       element_count_ = 0;
139       return;
140     }
141     if (format_->IsPacked()) {
142       element_count_ = count;
143     } else {
144       // This divides by the needed input values, not the values per element.
145       // The assumption being the values coming in are read from the input,
146       // where components are specified. The needed values maybe less then the
147       // values per element.
148       element_count_ = count / format_->InputNeededPerElement();
149     }
150   }
151   /// Returns the number of values in the buffer.
ValueCount()152   uint32_t ValueCount() const {
153     if (!format_)
154       return 0;
155     // Packed formats are single values.
156     if (format_->IsPacked())
157       return element_count_;
158     return element_count_ * format_->InputNeededPerElement();
159   }
160 
161   /// Returns the number of bytes needed for the data in the buffer.
GetSizeInBytes()162   uint32_t GetSizeInBytes() const {
163     if (!format_)
164       return 0;
165     return ElementCount() * format_->SizeInBytes();
166   }
167 
168   /// Returns the number of bytes for one element in the buffer.
GetElementStride()169   uint32_t GetElementStride() { return format_->SizeInBytes(); }
170 
171   /// Returns the number of bytes for one row of elements in the buffer.
GetRowStride()172   uint32_t GetRowStride() { return GetElementStride() * GetWidth(); }
173 
174   /// Sets the data into the buffer.
175   Result SetData(const std::vector<Value>& data);
176 
177   /// Resizes the buffer to hold |element_count| elements. This is separate
178   /// from SetElementCount() because we may not know the format when we set the
179   /// initial count. This requires the format to have been set.
180   void SetSizeInElements(uint32_t element_count);
181 
182   /// Resizes the buffer to hold |size_in_bytes|/format_->SizeInBytes()
183   /// number of elements while resizing the buffer to |size_in_bytes| bytes.
184   /// This requires the format to have been set. This is separate from
185   /// SetSizeInElements() since the given argument here is |size_in_bytes|
186   /// bytes vs |element_count| elements
187   void SetSizeInBytes(uint32_t size_in_bytes);
188 
189   /// Sets the max_size_in_bytes_ to |max_size_in_bytes| bytes
190   void SetMaxSizeInBytes(uint32_t max_size_in_bytes);
191   /// Returns max_size_in_bytes_ if it is not zero. Otherwise it means this
192   /// buffer is an amber buffer which has a fix size and returns
193   /// GetSizeInBytes()
194   uint32_t GetMaxSizeInBytes() const;
195 
196   /// Write |data| into the buffer |offset| bytes from the start. Write
197   /// |size_in_bytes| of data.
198   Result SetDataWithOffset(const std::vector<Value>& data, uint32_t offset);
199 
200   /// At each ubo, ssbo size and ssbo subdata size calls, recalculates
201   /// max_size_in_bytes_ and updates it if underlying buffer got bigger
202   Result RecalculateMaxSizeInBytes(const std::vector<Value>& data,
203                                    uint32_t offset);
204 
205   /// Writes |src| data into buffer at |offset|.
206   Result SetDataFromBuffer(const Buffer* src, uint32_t offset);
207 
208   /// Sets the number of mip levels for a buffer used as a color buffer
209   /// or a texture.
SetMipLevels(uint32_t mip_levels)210   void SetMipLevels(uint32_t mip_levels) { mip_levels_ = mip_levels; }
211 
212   /// Returns the number of mip levels.
GetMipLevels()213   uint32_t GetMipLevels() const { return mip_levels_; }
214 
215   /// Sets the number of samples.
SetSamples(uint32_t samples)216   void SetSamples(uint32_t samples) { samples_ = samples; }
217 
218   /// Returns the number of samples.
GetSamples()219   uint32_t GetSamples() const { return samples_; }
220 
221   /// Returns a pointer to the internal storage of the buffer.
ValuePtr()222   std::vector<uint8_t>* ValuePtr() { return &bytes_; }
223   /// Returns a pointer to the internal storage of the buffer.
ValuePtr()224   const std::vector<uint8_t>* ValuePtr() const { return &bytes_; }
225 
226   /// Returns a casted pointer to the internal storage of the buffer.
227   template <typename T>
GetValues()228   const T* GetValues() const {
229     return reinterpret_cast<const T*>(bytes_.data());
230   }
231 
232   /// Copies the buffer values to an other one
233   Result CopyTo(Buffer* buffer) const;
234 
235   /// Succeeds only if both buffer contents are equal
236   Result IsEqual(Buffer* buffer) const;
237 
238   /// Returns a histogram
239   std::vector<uint64_t> GetHistogramForChannel(uint32_t channel,
240                                                uint32_t num_bins) const;
241 
242   /// Checks if buffers are compatible for comparison
243   Result CheckCompability(Buffer* buffer) const;
244 
245   /// Compare the RMSE of this buffer against |buffer|. The RMSE must be
246   /// less than |tolerance|.
247   Result CompareRMSE(Buffer* buffer, float tolerance) const;
248 
249   /// Compare the histogram EMD of this buffer against |buffer|. The EMD must be
250   /// less than |tolerance|.
251   Result CompareHistogramEMD(Buffer* buffer, float tolerance) const;
252 
253  private:
254   uint32_t WriteValueFromComponent(const Value& value,
255                                    FormatMode mode,
256                                    uint32_t num_bits,
257                                    uint8_t* ptr);
258 
259   // Calculates the difference between the value stored in this buffer and
260   // those stored in |buffer| and returns all the values.
261   std::vector<double> CalculateDiffs(const Buffer* buffer) const;
262 
263   std::string name_;
264   /// max_size_in_bytes_ is the total size in bytes needed to hold the buffer
265   /// over all ubo, ssbo size and ssbo subdata size calls.
266   uint32_t max_size_in_bytes_ = 0;
267   uint32_t element_count_ = 0;
268   uint32_t width_ = 1;
269   uint32_t height_ = 1;
270   uint32_t depth_ = 1;
271   uint32_t mip_levels_ = 1;
272   uint32_t samples_ = 1;
273   bool format_is_default_ = false;
274   std::vector<uint8_t> bytes_;
275   Format* format_ = nullptr;
276   Sampler* sampler_ = nullptr;
277   ImageDimension image_dim_ = ImageDimension::kUnknown;
278 };
279 
280 }  // namespace amber
281 
282 #endif  // SRC_BUFFER_H_
283