// Copyright 2018 The Amber Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SRC_BUFFER_H_ #define SRC_BUFFER_H_ #include #include #include #include #include #include "amber/result.h" #include "amber/value.h" #include "src/datum_type.h" #include "src/format.h" namespace amber { /// Types of buffers which can be created. enum class BufferType : int8_t { /// Unknown buffer type kUnknown = -1, /// A color buffer. kColor = 0, /// A depth/stencil buffer. kDepth, /// An index buffer. kIndex, /// A sampled buffer. kSampled, /// A storage buffer. kStorage, /// A uniform buffer. kUniform, /// A push constant buffer. kPushConstant, /// A vertex buffer. kVertex }; /// A buffer stores data. The buffer maybe provided from the input script, or /// maybe created as needed. A buffer must have a unique name. class Buffer { public: /// Create a buffer of unknown type. Buffer(); /// Create a buffer of |type_|. explicit Buffer(BufferType type); ~Buffer(); /// Returns the BufferType of this buffer. BufferType GetBufferType() const { return buffer_type_; } /// Sets the BufferType for this buffer. void SetBufferType(BufferType type) { buffer_type_ = type; } /// Set the location binding value for the buffer. void SetLocation(uint8_t loc) { location_ = loc; } /// Get the location binding value for the buffer. uint8_t GetLocation() const { return location_; } /// Sets the Format of the buffer to |format|. void SetFormat(std::unique_ptr format) { format_ = std::move(format); } /// Returns the Format describing the buffer data. Format* GetFormat() { return format_.get(); } /// Sets the buffer |name|. void SetName(const std::string& name) { name_ = name; } /// Returns the name of the buffer. std::string GetName() const { return name_; } /// Gets the number of elements this buffer is wide. uint32_t GetWidth() const { return width_; } /// Set the number of elements wide for the buffer. void SetWidth(uint32_t width) { width_ = width; } /// Get the number of elements this buffer is high. uint32_t GetHeight() const { return height_; } /// Set the number of elements high for the buffer. void SetHeight(uint32_t height) { height_ = height; } // | ---------- Element ---------- | ElementCount == 1 // | Value | Value | Value | Value | ValueCount == 4 // | | | | | | | | | | | | | | | | | SizeInBytes == 16 // Note, the SizeInBytes maybe be greater then the size of the values. If // the format IsStd140() and there are 3 rows, the SizeInBytes will be // inflated to 4 values per row, instead of 3. /// Sets the number of elements in the buffer. void SetElementCount(uint32_t count) { element_count_ = count; } /// Returns the number of elements in the buffer. uint32_t ElementCount() const { return element_count_; } /// Sets the number of values in the buffer. void SetValueCount(uint32_t count) { if (!format_) { element_count_ = 0; return; } if (format_->GetPackSize() > 0) { element_count_ = count; } else { // This divides by the needed input values, not the values per element. // The assumption being the values coming in are read from the input, // where components are specified. The needed values maybe less then the // values per element. element_count_ = count / format_->InputNeededPerElement(); } } /// Returns the number of values in the buffer. uint32_t ValueCount() const { if (!format_) return 0; // Packed formats are single values. if (format_->GetPackSize() > 0) return element_count_; return element_count_ * format_->ValuesPerElement(); } /// Returns the number of bytes needed for the data in the buffer. uint32_t GetSizeInBytes() const { if (!format_) return 0; return ElementCount() * format_->SizeInBytes(); } /// Returns the number of bytes for one element in the buffer. uint32_t GetTexelStride() { return format_->SizeInBytes(); } /// Returns the number of bytes for one row of elements in the buffer. uint32_t GetRowStride() { return GetTexelStride() * GetWidth(); } /// Sets the data into the buffer. Result SetData(const std::vector& data); /// Returns a pointer to the internal storage of the buffer. std::vector* ValuePtr() { return &bytes_; } /// Returns a pointer to the internal storage of the buffer. const std::vector* ValuePtr() const { return &bytes_; } /// Returns a casted pointer to the internal storage of the buffer. template const T* GetValues() const { return reinterpret_cast(bytes_.data()); } /// Copies the buffer values to an other one Result CopyTo(Buffer* buffer) const; /// Succeeds only if both buffer contents are equal Result IsEqual(Buffer* buffer) const; private: BufferType buffer_type_ = BufferType::kUnknown; std::string name_; uint32_t element_count_ = 0; uint32_t width_ = 0; uint32_t height_ = 0; uint8_t location_ = 0; std::vector bytes_; std::unique_ptr format_; }; } // namespace amber #endif // SRC_BUFFER_H_