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