HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_TextureCache.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RV_TextureCache.h (RV Library, C++)
7  *
8  * COMMENTS:
9  */
10 #ifndef RV_TextureCache_h
11 #define RV_TextureCache_h
12 
13 #include "RV_API.h"
14 #include "RV_TextureRef.h"
15 #include "RV_Type.h"
16 #include "RV_TypePtrs.h"
17 
18 #include <PXL/PXL_Raster.h>
19 #include <UT/UT_Array.h>
20 #include <UT/UT_Cache.h>
21 #include <UT/UT_NonCopyable.h>
22 #include <UT/UT_Map.h>
23 #include <UT/UT_MemoryResource.h>
24 #include <UT/UT_Set.h>
25 #include <UT/UT_StringMap.h>
26 #include <UT/UT_StringHolder.h>
27 #include <UT/UT_UniquePtr.h>
28 #include <UT/UT_VectorTypes.h>
29 
30 #include <SYS/SYS_Types.h>
31 
32 #define RV_INVALID_OP_ID -1
33 
34 typedef void (*RV_TextureHDAResolverCB)(const char *optable_optype,
35  const char *pattern,
36  UT_StringArray &files);
37 
38 class RV_Render;
40 class RV_TextureResolver;
41 class RV_Instance;
42 class RV_VKImage;
43 
44 class PXL_Raster;
45 class IMG_Stat;
46 class IMG_FileParms;
47 
48 /// Global cache of vulkan textures sourced from files.
50 {
51 public:
52  /// Initialize the cache (only used by the system during startup)
53  static void init(const UT_StringHolder &device_name);
54  /// Destroy the cache (only used by the system during exit)
55  static void cleanup();
56 
57  /// Clear all images out of the cache.
58  static void clear();
59  /// Mark any textures as dirty if their file source has been modified
60  static void updateTextures();
61 
62  /// The serial version of the cache. Incremented when a texture is added
63  static exint cacheVersion();
64  /// The serial refresh count of the cache. Incremented when the user
65  /// explicity updates the textures
66  static exint cacheRefresh();
67 
68  static exint currentSizeBytes();
69 
70  static exint totalTextureCount();
71 
72  static exint maxSizeBytes();
73 
74  static exint freeSomeMem(exint mem_in_bytes);
75 
76  /// If the texture is missing, one of these generic placeholders is used.
78  {
79  MISSING_BLACK_CLEAR, // 0,0,0,0
80  MISSING_BLACK_SOLID, // 0,0,0,1
81  MISSING_WHITE_SOLID, // 1,1,1,1
82  MISSING_RED_SOLID, // 1,0,0,1
83  MISSING_NORMAL_MAP, // 0.5, 0.5, 1, 0
84  MISSING_FALLBACK, // custom color
85 
86  MAX_PLACEHOLDER
87  };
88 
90  {
95  PRIORITY_CRITICAL
96  };
97 
98  /// Load the map (if needed) and bind the resulting texture to 'sampler_name'
99  /// in 'set'. If it cannot be loaded, bind a placeholder texture instead.
100  /// This method is equivalent to calling loadTextureRef() and then
101  /// bindTextureRef() or bindPlaceholder(). If the map is a reference to a
102  /// mofr with op:, op_id will contain its unique ID.
103  static bool bindTexture(RV_Render *r,
104  RV_TextureRef &map,
105  const RV_TextureParms &map_parms,
106  const UT_StringHolder &map_name,
107  const UT_StringHolder &relative_to_node,
108  RV_ImageDim tex_type,
110  const UT_StringHolder &sampler_name,
111  bool deferred_load,
112  bool &deferred_loaded,
113  int &op_id,
114  TexturePriority priority = PRIORITY_NORMAL,
115  PlaceholderType missing=MISSING_WHITE_SOLID,
116  UT_Vector4F *fallback_color = nullptr);
117 
118  /// Binds an existing texture ref to the set at 'sampler_name'. It should not
119  /// be a placeholder image (use bindPlaceholder instead).
120  static bool bindTextureRef(RV_Render *r,
123  const UT_StringHolder &sampler_name);
124 
125  /// Bind a small placeholder texture (1x1) to 'sampler_name' in 'set'.
126  /// The RGBA texture color is defined by the placeholder_type, or can be a
127  /// custom/ color if the type is FALLBACK. The texture is 8b unorm RGBA.
128  static bool bindPlaceholder(RV_Render *r,
129  RV_ImageDim tex_type,
131  const UT_StringHolder &sampler_name,
132  PlaceholderType placeholder_type,
133  const UT_Vector4F *fallbackcolor=nullptr);
134 
135  /// Load the map info a texture ref without binding it to a shader. If the
136  /// map could not be loaded, map.isPlaceholder() will be true.
137  /// If allow_deferred_load is true, background load the texture. Keep calling
138  /// this in subsequent redraws until defer_load_finished is true.
139  static bool loadTextureRef(RV_Render *r,
140  RV_TextureRef &map,
141  const RV_TextureParms &map_parms,
142  const UT_StringHolder &map_name,
143  const UT_StringHolder &relative_to_node,
144  RV_ImageDim tex_type,
145  bool allow_deferred_load,
146  bool &defer_load_finished,
147  int &op_id,
148  TexturePriority priority = PRIORITY_NORMAL,
149  UT_Vector3i *resolution = nullptr,
150  UT_Vector4F *fallback_color = nullptr);
151 
152  /// Cache an existing 2D Image. The name should be prefixed with exp:
153  /// (explicitly cached).
154  static bool cacheAsTexture(RV_Render *r,
155  RV_TextureRef &map,
156  const PXL_Raster *source_image,
157  const RV_TextureParms &map_parms,
158  const UT_StringHolder &map_name);
159  /// Remove a cached 2D Image
160  static bool removeCachedTexture(RV_TextureRef &map);
161 
162  /// Cache an existing image. The cache takes ownership (use std::move for
163  /// the image). If the image is a UDIM, you can optionally pass the bounds.
164  /// The map name should be prefixed with exp: (explicitly cached).
165  static bool cacheImage(UT_UniquePtr<RV_VKImage> image,
166  RV_TextureRef &map,
167  const UT_StringHolder &map_name,
168  UT_DimRect *udim_bounds = nullptr);
169  /// Remove a cached image from the cache, taking ownership of it.
170  /// If udim_bounds is not null, write the bounds to it.
172  uncacheImage(RV_TextureRef &map,
173  UT_DimRect *udim_bounds = nullptr);
174 
175 
176  /// Check if the texture is out of date. Flag the ref and set `dirty` if so.
177  /// doesn't touch either if it's current.
178  static void checkTextureDirty(RV_TextureRef &map, bool &dirty);
179 
180  /// Check if the texture has an alpha channel
181  static void checkTextureHasAlpha(const RV_TextureRef &ref, bool &has_alpha);
182 
183  /// For resolving a bunch of files to a 2D array, this is the separator
184  /// character between the filenames.
185  static const char * getFileSeparator() { return "\x1f"; }
186 
187  static void setSingleTexMemLimitMB(exint mem_in_mb);
188  static exint singleTexMemLimitMB();
189 
190  static void setCacheSize(exint mem_in_bytes);
191 
192  /// Reduce all textures in the cache by at least this amount.
193  static void setReductionFactor(fpreal reduce);
194 
195  /// For resolving
196  static void installHDACallback(RV_TextureHDAResolverCB resolver_func);
197 
198  /// @internal
200  {
201  public:
202  ImageInfo();
203  ~ImageInfo();
204 
214  int udim_x = 0;
215  int udim_y = 0;
216  int udim_w = 0;
217  int udim_h = 0;
218  int width = 1;
219  int height = 1;
220  int depth = 1;
221  fpreal aspect = 1.0;
222  bool check_alpha = false;
223  bool alpha = false;
224  int channels = 4;
225  int typeinfo = 0;
226  time_t modtime = 0;
227  fpreal optime = 0.0;
228  int op_id = RV_INVALID_OP_ID;
229  int version = 0;
230  bool valid = false;
231  bool loading = false;
232  fpreal downscale = 1.0;
233  };
234 
235 protected:
236  class Image
237  {
238  public:
239  RV_VKImage *image = nullptr;
240  int udim_x = 0;
241  int udim_y = 0;
242  int udim_w = 0;
243  int udim_h = 0;
244  fpreal aspect = 1.0;
245  int op_id = RV_INVALID_OP_ID;
246  };
247 
248  static RV_TextureCache::Image getTexture(exint id);
249 
250  exint resolveTexture(RV_Render *r,
251  const UT_StringHolder &map_name,
252  const UT_StringHolder &relative_to_node,
253  const RV_TextureParms &tex_parms,
254  RV_ImageDim tex_type,
255  bool force_update,
256  bool deferred_load,
257  bool &defer_loaded,
258  int &op_id,
259  bool &missing_texture,
261  TexturePriority priority,
262  const UT_Vector4F &fallback,
264 
265  static RV_VKImage *getPlaceholder(RV_Render *r, RV_ImageDim tex_type,
266  PlaceholderType type =MISSING_WHITE_SOLID,
267  const UT_Vector4F *fallbackcolor =nullptr);
268 
269  RV_TextureCache::Image privGetTexture(exint id);
270 
272  ~RV_TextureCache() override;
273 
275 
276  // UT_Cache interface
277  const char *utGetCacheName() const override
278  { return "Vulkan Texture Cache"; }
279  int64 utGetCurrentSize() const override
280  { return myCurrentSize; }
281  int64 utReduceCacheSizeBy(int64 amount) override
282  { return freeTextures(amount, true, false); }
283  bool utHasMaxSize() const override { return true; }
284  int64 utGetMaxSize() const override;
285  void utSetMaxSize(int64) override { }
286 
287 
288 private:
289 
290  exint freeTextures(exint needed_to_free, bool free_used, bool must_free);
291  exint cachedSizeBytes() const;
292 
293  class GraphicsMemoryClient : public UT_MemoryClient
294  {
295  public:
296  GraphicsMemoryClient(RV_TextureCache &cache) : myCache(cache) {}
297 
298  const char *name() const override
299  { return "Vulkan Texture Cache";}
300 
301  bool freeMemoryRequest(const UT_MemoryResource *resource,
302  RequestSeverity severity,
303  Niceness nice_level,
304  exint size_in_bytes,
305  exint &freed_amount_in_bytes) override;
306  bool memoryUse(const UT_MemoryResource *resource,
307  exint &in_use_bytes,
308  exint &cached_bytes) override;
309 
310  ~GraphicsMemoryClient() override {}
311  UT_NON_COPYABLE(GraphicsMemoryClient)
312 
313  private:
314  RV_TextureCache &myCache;
315  };
316 
317  GraphicsMemoryClient myResource;
318  UT_Array< UT_Map<exint, ImageInfo > > myImages;
319  UT_Map<exint, RV_ImageDim> myTypeMap;
320 
321  struct ResolveEntry
322  {
323  exint id = 0;
324  TexturePriority priority = RV_TextureCache::PRIORITY_NORMAL;
326 
327  ResolveEntry() {}
328  ResolveEntry(exint id,
329  TexturePriority priority,
331  : id{id}, priority{priority}, refs{refs}
332  {}
333 
334  /// Track if the texture is currently in use, these will
335  /// not be freed until the in use returns to zero.
336  /// set and clear MUST be paired.
337  bool isInUse() const
338  { return myInUseCount > 0; }
339  void setInUse()
340  { ++myInUseCount; }
341  void clearInUse()
342  { --myInUseCount; UT_ASSERT(myInUseCount >= 0); }
343  private:
344  int myInUseCount = 0;
345  };
346  UT_StringMap<ResolveEntry> myResolveMap;
347  UT_StringMap<fpreal> myReductionTable;
348 
350  UT_Array<UT_UniquePtr<RV_VKImage>> myPlaceholders;
351  UT_Array<UT_Map<int32, RV_VKImagePtr>> myFallbackTextures;
352  UT_Lock myLock;
353  UT_Set<exint> myDeferImages;
354 
355  exint myCurrentSize = 0;
356  fpreal myReductionFactor = 1.0;
357  UT_StringHolder myDeviceName;
358 };
359 
360 #endif
A collection of Vulkan UBO, SSBO, and Image shader bindings (descriptor set)
int64 utGetCurrentSize() const override
required - return the current cache size, in bytes
Unsorted map container.
Definition: UT_Map.h:114
void
Definition: png.h:1083
int64 exint
Definition: SYS_Types.h:125
Opaque reference to a texture stored in the RV_TextureCache.
Definition: RV_TextureRef.h:21
GLenum GLenum GLsizei void * image
Definition: glad.h:5132
UT_SharedPtr< RV_TextureRef::CacheData > refs
bool utHasMaxSize() const override
optional - override if the cache has a well defined maximum size
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
GLint ref
Definition: glcorearb.h:124
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
constexpr auto set(type rhs) -> int
Definition: core.h:610
T reduce(RangeT range, const T &identity, const FuncT &func, const JoinT &join)
Definition: Reduce.h:42
UT_Array< UT_UniquePtr< PXL_Raster > > rasters
#define RV_INVALID_OP_ID
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
#define RV_API
Definition: RV_API.h:10
long long int64
Definition: SYS_Types.h:116
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:112
GLenum GLenum severity
Definition: glcorearb.h:2539
void utSetMaxSize(int64) override
UT_UniquePtr< IMG_Stat > stat
HUSD_API const char * resolution()
GLuint const GLchar * name
Definition: glcorearb.h:786
GLushort pattern
Definition: glad.h:2583
PlaceholderType
If the texture is missing, one of these generic placeholders is used.
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:50
Common base class for various caches.
Definition: UT_Cache.h:21
static const char * getFileSeparator()
FS_API bool cleanup(UT_StringArray &removed, UT_StringArray &error_files, exint &memory_freed, bool dry_run, const char *override_path=nullptr)
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glcorearb.h:476
GT_API const UT_StringHolder version
UT_UniquePtr< IMG_FileParms > file_parms
Global cache of vulkan textures sourced from files.
fpreal64 fpreal
Definition: SYS_Types.h:283
File options for manipulating image data on load or save. This class allows you to modify the incomin...
Definition: IMG_FileParms.h:39
Contains the details of a specific image file, used by IMG_File. This class contains all the high-lev...
Definition: IMG_Stat.h:38
GLint GLsizei width
Definition: glcorearb.h:103
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
Wrapper for a client of a limit memory resource.
GLboolean r
Definition: glcorearb.h:1222
void(* RV_TextureHDAResolverCB)(const char *optable_optype, const char *pattern, UT_StringArray &files)
RV_ImageDim
Definition: RV_Type.h:120
int64 utReduceCacheSizeBy(int64 amount) override
UT_Array< std::pair< UT_StringHolder, UT_Vector2i > > udim_tiles
UT_UniquePtr< RV_VKImage > image
ImageBuf OIIO_API channels(const ImageBuf &src, int nchannels, cspan< int > channelorder, cspan< float > channelvalues={}, cspan< std::string > newchannelnames={}, bool shuffle_channel_names=false, int nthreads=0)