vsg  1.0.4
VulkanSceneGraph library
Data.h
1 #pragma once
2 
3 /* <editor-fold desc="MIT License">
4 
5 Copyright(c) 2018 Robert Osfield
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8 
9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 
13 </editor-fold> */
14 
15 #include <vsg/core/Allocator.h>
16 #include <vsg/core/Object.h>
17 #include <vsg/core/compare.h>
18 #include <vsg/core/type_name.h>
19 #include <vsg/vk/vulkan.h>
20 
21 #include <cstring>
22 #include <vector>
23 
24 namespace vsg
25 {
26 
29  {
30  uint32_t count = 0;
31 
32  bool operator==(const ModifiedCount& rhs) const { return count == rhs.count; }
33  bool operator!=(const ModifiedCount& rhs) const { return count != rhs.count; }
34 
35  void operator++() { ++count; }
36  };
37 
39  using block64 = uint8_t[8];
40 
42  using block128 = uint8_t[16];
43 
44  enum Origin : uint8_t
45  {
46  TOP_LEFT = 0,
47  BOTTOM_LEFT = 2
48  };
49 
50  enum DataVariance : uint8_t
51  {
52  STATIC_DATA = 0,
53  STATIC_DATA_UNREF_AFTER_TRANSFER = 1,
54  DYNAMIC_DATA = 2,
55  DYNAMIC_DATA_TRANSFER_AFTER_RECORD = 3
56  };
57 
58  template<typename T>
60  {
61  using value_type = T;
62  using iterator_category = std::forward_iterator_tag;
63  using difference_type = std::ptrdiff_t;
64  using pointer = T*;
65  using reference = T&;
66 
67  value_type* ptr;
68  uint32_t stride; // stride in bytes
69 
70  inline void advance()
71  {
72  if constexpr (std::is_const<value_type>::value)
73  ptr = reinterpret_cast<value_type*>(reinterpret_cast<const uint8_t*>(ptr) + stride);
74  else
75  ptr = reinterpret_cast<value_type*>(reinterpret_cast<uint8_t*>(ptr) + stride);
76  }
77 
78  stride_iterator& operator++()
79  {
80  advance();
81  return *this;
82  }
83  stride_iterator operator++(int)
84  {
85  stride_iterator reval(*this);
86  advance();
87  return reval;
88  }
89 
90  bool operator==(stride_iterator rhs) const { return ptr == rhs.ptr; }
91  bool operator!=(stride_iterator rhs) const { return ptr != rhs.ptr; }
92  bool operator<(stride_iterator rhs) const { return ptr < rhs.ptr; }
93  bool operator<=(stride_iterator rhs) const { return ptr <= rhs.ptr; }
94  bool operator>(stride_iterator rhs) const { return ptr > rhs.ptr; }
95  bool operator>=(stride_iterator rhs) const { return ptr >= rhs.ptr; }
96 
97  value_type& operator*() { return *reinterpret_cast<value_type*>(ptr); }
98  value_type* operator->() { return reinterpret_cast<value_type*>(ptr); }
99  };
100 
103  class VSG_DECLSPEC Data : public Object
104  {
105  public:
106  /* Properties used for specifying the format of the data, use of mipmaps, block compressed data and origin.
107  * Default of no mipmapping and {1,1,1} is uncompressed.
108  * A single block (Block64/Block128) is stored as a single value with the Data object. */
109  struct VSG_DECLSPEC Properties
110  {
111  Properties() = default;
112  Properties(const Properties& rhs) = default;
113  explicit Properties(VkFormat in_format) :
114  format(in_format) {}
115 
116  VkFormat format = VK_FORMAT_UNDEFINED;
117  uint32_t stride = 0;
118  uint8_t maxNumMipmaps = 0;
119  uint8_t blockWidth = 1;
120  uint8_t blockHeight = 1;
121  uint8_t blockDepth = 1;
122  uint8_t origin = TOP_LEFT;
123  int8_t imageViewType = -1;
124  DataVariance dataVariance = STATIC_DATA;
125  AllocatorType allocatorType = ALLOCATOR_TYPE_VSG_ALLOCATOR;
126 
127  int compare(const Properties& rhs) const;
128  Properties& operator=(const Properties& rhs);
129  };
130 
131  Data() {}
132 
133  explicit Data(Properties layout) :
134  properties(layout) {}
135 
136  Data(Properties layout, uint32_t min_stride) :
137  properties(layout)
138  {
139  if (properties.stride < min_stride) properties.stride = min_stride;
140  }
141 
143  static void* operator new(std::size_t count);
144  static void operator delete(void* ptr);
145 
146  std::size_t sizeofObject() const noexcept override { return sizeof(Data); }
147  bool is_compatible(const std::type_info& type) const noexcept override { return typeid(Data) == type || Object::is_compatible(type); }
148 
149  int compare(const Object& rhs_object) const override
150  {
151  int result = Object::compare(rhs_object);
152  if (result != 0) return result;
153 
154  auto& rhs = static_cast<decltype(*this)>(rhs_object);
155 
156  if ((result = properties.compare(rhs.properties))) return result;
157 
158  // the shorter data is less
159  if (dataSize() < rhs.dataSize()) return -1;
160  if (dataSize() > rhs.dataSize()) return 1;
161 
162  // if both empty then they must be equal
163  if (dataSize() == 0) return 0;
164 
165  // use memcpy to compare the contents of the data
166  return std::memcmp(dataPointer(), rhs.dataPointer(), dataSize());
167  }
168 
169  void read(Input& input) override;
170  void write(Output& output) const override;
171 
174 
175  bool dynamic() const { return properties.dataVariance >= DYNAMIC_DATA; }
176 
177  virtual std::size_t valueSize() const = 0;
178  virtual std::size_t valueCount() const = 0;
179 
180  virtual bool dataAvailable() const = 0;
181  virtual std::size_t dataSize() const = 0;
182 
183  virtual void* dataPointer() = 0;
184  virtual const void* dataPointer() const = 0;
185 
186  virtual void* dataPointer(size_t index) = 0;
187  virtual const void* dataPointer(size_t index) const = 0;
188 
189  virtual void* dataRelease() = 0;
190 
191  virtual std::uint32_t dimensions() const = 0;
192 
193  virtual std::uint32_t width() const = 0;
194  virtual std::uint32_t height() const = 0;
195  virtual std::uint32_t depth() const = 0;
196 
197  bool contiguous() const { return valueSize() == properties.stride; }
198 
199  uint32_t stride() const { return properties.stride ? properties.stride : static_cast<uint32_t>(valueSize()); }
200 
201  using MipmapOffsets = std::vector<std::size_t>;
202  MipmapOffsets computeMipmapOffsets() const;
203  static std::size_t computeValueCountIncludingMipmaps(std::size_t w, std::size_t h, std::size_t d, uint32_t maxNumMipmaps);
204 
206  void dirty() { ++_modifiedCount; }
207 
210  {
211  if (_modifiedCount != mc)
212  {
213  mc = _modifiedCount;
214  return true;
215  }
216  else
217  return false;
218  }
219 
221  bool differentModifiedCount(const ModifiedCount& mc) const { return _modifiedCount != mc; }
222 
223  protected:
224  virtual ~Data() {}
225 
226  ModifiedCount _modifiedCount;
227 
228 #if 1
229  public:
232 
234  void setLayout(Layout layout)
235  {
236  VkFormat previous_format = properties.format; // temporary hack to keep applications that call setFormat(..) before setProperties(..) working
237  uint32_t previous_stride = properties.stride;
238  properties = layout;
239  if (properties.format == 0 && previous_format != 0) properties.format = previous_format; // temporary hack to keep existing applications working
240  if (properties.stride == 0 && previous_stride != 0) properties.stride = previous_stride; // make sure the layout as a valid stride.
241  }
243  Layout& getLayout() { return properties; }
245  Layout getLayout() const { return properties; }
246 #endif
247  };
248  VSG_type_name(vsg::Data);
249 
250  using DataList = std::vector<ref_ptr<Data>>;
251 
252 } // namespace vsg
Definition: Data.h:104
Properties properties
properties of the data such as format, origin, stride, dataVariance etc.
Definition: Data.h:173
bool differentModifiedCount(const ModifiedCount &mc) const
return true if Data's ModifiedCount is different than the specified ModifiedCount
Definition: Data.h:221
Layout getLayout() const
deprecated: use data->properties
Definition: Data.h:245
void setLayout(Layout layout)
deprecated: use data->properties = properties instead.
Definition: Data.h:234
void dirty()
increment the ModifiedCount to signify the data has been modified
Definition: Data.h:206
Layout & getLayout()
deprecated: use data->properties
Definition: Data.h:243
bool getModifiedCount(ModifiedCount &mc) const
get the Data's ModifiedCount and return true if this changes the specified ModifiedCount
Definition: Data.h:209
int compare(const Object &rhs_object) const override
compare two objects, return -1 if this object is less than rhs, return 0 if it's equal,...
Definition: Data.h:149
Definition: Input.h:43
Definition: Object.h:42
virtual int compare(const Object &rhs) const
compare two objects, return -1 if this object is less than rhs, return 0 if it's equal,...
Definition: Object.h:77
Definition: Output.h:40
Definition: Data.h:110
DataVariance dataVariance
-1 signifies undefined VkImageViewType, if value >=0 then value should be treated as valid VkImageVie...
Definition: Data.h:124
ModifiedCount provides a count value to keep track of modifications to data.
Definition: Data.h:29
Definition: Data.h:60