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