Fermat
texture.h
1 /*
2  * Fermat
3  *
4  * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the NVIDIA CORPORATION nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #pragma once
30 
31 #include "types.h"
32 #include "buffers.h"
33 #include "texture_reference.h"
34 #include "texture_view.h"
35 
36 #include <cugar/basic/types.h>
37 #include <cugar/linalg/vector.h>
38 #include <vector>
39 #include <memory>
40 #include <string>
41 
44 
47 
52 template <BufferType TYPE>
54 {
55  TextureStorage() : res_x(0), res_y(0) {}
56 
57  template <BufferType UTYPE>
58  TextureStorage(const TextureStorage<UTYPE>& other) : res_x(other.res_x), res_y(other.res_y), c(other.c) {}
59 
60  template <BufferType UTYPE>
61  TextureStorage& operator=(const TextureStorage<UTYPE>& other)
62  {
63  res_x = other.res_x;
64  res_y = other.res_y;
65  c = other.c;
66  return *this;
67  }
68 
69  const float4* ptr() const { return c.ptr(); }
70  float4* ptr() { return c.ptr(); }
71 
72  void resize(const uint32 _res_x, const uint32 _res_y)
73  {
74  res_x = _res_x;
75  res_y = _res_y;
76 
77  c.alloc(res_x * res_y);
78  }
79 
80  size_t size() const { return res_x * res_y; }
81 
82  uint2 res() const { return make_uint2(res_x, res_y); }
83 
84  void clear()
85  {
86  c.clear(0);
87  }
88 
89  TextureView view()
90  {
91  TextureView out;
92  out.res_x = res_x;
93  out.res_y = res_y;
94  out.c = c.ptr();
95  return out;
96  }
97 
98 public:
99  uint32 res_x;
100  uint32 res_y;
101 
102  DomainBuffer<TYPE, float4> c; // color
103 };
104 
109 template <BufferType TYPE>
111 {
113  typedef std::shared_ptr<TextureStorage<TYPE> > TexturePtr;
114 
115  uint32_t res_x;
116  uint32_t res_y;
117  uint32_t n_levels;
118 
121 
122  MipMapStorage() : res_x(0), res_y(0), n_levels(0) {}
123 
124  template <BufferType UTYPE>
125  MipMapStorage(const MipMapStorage<UTYPE>& other) : res_x(0), res_y(0), n_levels(0)
126  {
127  this->operator=(other);
128  }
129 
130  template <BufferType UTYPE>
131  MipMapStorage& operator=(const MipMapStorage<UTYPE>& other)
132  {
133  res_x = other.res_x;
134  res_y = other.res_y;
135  n_levels = other.n_levels;
136 
137  levels.alloc( n_levels );
138  for (uint32 l = 0; l < n_levels; ++l)
139  {
140  levels[l] = TexturePtr(new TextureType);
141  *levels[l] = *other.levels[l];
142  }
143 
144  level_views.alloc(n_levels);
145  for (uint32 l = 0; l < n_levels; ++l)
146  level_views.set(l, levels[l]->view());
147 
148  return *this;
149  }
150 
151  void set(TexturePtr texture)
152  {
153  res_x = texture->res().x;
154  res_y = texture->res().y;
155 
156  // count the number of levels needed
157  n_levels = 0;
158  {
159  uint32 l_res_x = res_x;
160  uint32 l_res_y = res_y;
161  while (l_res_x >= 1 && l_res_y >= 1)
162  {
163  n_levels++;
164  l_res_x /= 2;
165  l_res_y /= 2;
166  }
167  }
168  levels.alloc(n_levels);
169 
170  if (n_levels)
171  {
172  levels[0] = texture;
173 
174  generate_mips();
175  }
176 
177  level_views.alloc(n_levels);
178  for (uint32 l = 0; l < n_levels; ++l)
179  level_views.set(l, levels[l]->view());
180  }
181 
182  void resize(const uint32_t _res_x, const uint32_t _res_y)
183  {
184  res_x = _res_x;
185  res_y = _res_y;
186 
187  // count levels
188  n_levels = 0;
189  {
190  uint32 l_res_x = res_x;
191  uint32 l_res_y = res_y;
192  while (l_res_x >= 1 && l_res_y >= 1)
193  {
194  n_levels++;
195  l_res_x /= 2;
196  l_res_y /= 2;
197  }
198  }
199  levels.alloc(n_levels);
200 
201  // allocate levels
202  n_levels = 0;
203  {
204  uint32 l_res_x = res_x;
205  uint32 l_res_y = res_y;
206  while (l_res_x >= 1 && l_res_y >= 1)
207  {
208  levels[n_levels] = TexturePtr(new TextureType);
209  levels[n_levels]->resize(l_res_x, l_res_y);
210 
211  n_levels++;
212  l_res_x /= 2;
213  l_res_y /= 2;
214  }
215  }
216 
217  level_views.resize(n_levels);
218  for (uint32 l = 0; l < n_levels; ++l)
219  level_views.set(l, levels[l]->view());
220  }
221 
222  void generate_mips()
223  {
224  uint32 level = 1;
225 
226  uint32 l_res_x = res_x/2;
227  uint32 l_res_y = res_y/2;
228  while (l_res_x >= 1 && l_res_y >= 1)
229  {
230  levels[level] = TexturePtr(new TextureType);
231  levels[level]->resize(l_res_x, l_res_y);
232 
233  downsample(levels[level - 1], levels[level]);
234 
235  level++;
236  l_res_x /= 2;
237  l_res_y /= 2;
238  }
239  }
240 
241  static void downsample(TexturePtr src, TexturePtr dst)
242  {
243  TextureView src_view = src->view();
244  TextureView dst_view = dst->view();
245 
246  for (uint32 y = 0; y < dst_view.res_y; ++y)
247  {
248  for (uint32 x = 0; x < dst_view.res_x; ++x)
249  {
250  cugar::Vector4f t(0.0f);
251  for (uint32 j = 0; j < 2; ++j)
252  for (uint32 i = 0; i < 2; ++i)
253  t += cugar::Vector4f( src_view(x * 2 + i, y * 2 + j) );
254 
255  dst_view(x, y) = t / 4.0f;
256  }
257  }
258  }
259 
260  uint32 level_count() const
261  {
262  return uint32(n_levels);
263  }
264 
265  MipMapView view()
266  {
267  MipMapView r;
268  r.n_levels = n_levels;
269  r.res_x = res_x;
270  r.res_y = res_y;
271  r.levels = level_views.ptr();
272  return r;
273  }
274 };
275 
276 FERMAT_API_EXTERN template class FERMAT_API DomainBuffer<HOST_BUFFER, MipMapStorage<HOST_BUFFER>::TexturePtr>;
277 FERMAT_API_EXTERN template class FERMAT_API DomainBuffer<HOST_BUFFER, MipMapStorage<CUDA_BUFFER>::TexturePtr>;
278 FERMAT_API_EXTERN template class FERMAT_API DomainBuffer<HOST_BUFFER, TextureView>;
279 FERMAT_API_EXTERN template class FERMAT_API DomainBuffer<CUDA_BUFFER, TextureView>;
280 
281 FERMAT_API_EXTERN template struct FERMAT_API TextureStorage<HOST_BUFFER>;
282 FERMAT_API_EXTERN template struct FERMAT_API TextureStorage<CUDA_BUFFER>;
283 
284 FERMAT_API_EXTERN template struct FERMAT_API MipMapStorage<HOST_BUFFER>;
285 FERMAT_API_EXTERN template struct FERMAT_API MipMapStorage<CUDA_BUFFER>;
286 
287 
Definition: texture_view.h:57
Definition: texture.h:110
Definition: texture_view.h:73
Definition: texture.h:53