HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_VKImage.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_VKImage.h ( RV Library, C++)
7  *
8  * COMMENTS:
9  * Class for creating Vulkan Image object
10  * Includes Vulkan Handle and memory allocation bound to it
11  */
12 #ifndef RV_VKImage_h
13 #define RV_VKImage_h
14 
15 #include "RV_API.h"
16 
17 #include <SYS/SYS_Types.h>
18 #include <SYS/SYS_Math.h>
19 #include <UT/UT_Assert.h>
20 #include <UT/UT_Swap.h>
21 #include <UT/UT_UniquePtr.h>
22 #include <limits>
23 
24 #include "RV_VK.h"
25 #include "RV_Instance.h"
26 #include "RV_Render.h"
27 #include "RV_Type.h"
28 
29 class RV_Instance;
30 class RV_Render;
31 class RV_VKCommandBuffer;
32 class RV_VKImage;
33 class RV_VKMemAllocInfo;
34 class RV_VKQueue;
35 class RV_VKMemory;
36 
38 
39 #define RV_MAX_MIP_LEVEL (std::numeric_limits<int>::max())
40 
41 /// Class for Setting up Image Info
42 /// Should be trivially copiable,
43 /// so it can be duplicated or passed around
44 /// Once a VkImage is created, it is immutable
45 /// so changing a parameter means creating
46 /// a new image
48 {
49 public:
50  // set Vulkan Image Creation parameters
51 
52  /// Define if the image is 1D, 2D, or 3D
53  void setImageType(RV_ImageDim img_type);
54  /// The Vulkan image type
55  VkImageType getImageType() const { return myVkCreateInfo.imageType; }
56  /// The RV image type
57  RV_ImageDim getRVImageType() const { return myRVImageType; }
58 
59  // TODO: use similar abstraction to RE_Texture ..
60  // setFormatType (i.e. Depth, vs. Color vs Stencil)
61  // setFormatDataType (int vs signed int vs float vs ...)
62  // setFormatVecSize (1, 2, 3, 4)
63  /// Set the vulkan image format. RV
64  void setFormat(VkFormat format) { myVkCreateInfo.format = format; }
65  VkFormat getFormat() const { return myVkCreateInfo.format; }
66 
67  /// Returns a vulkan subresource object for the full image
68  VkImageSubresourceRange getFullSubRes() const;
69 
70  /// Defines the size of the image (width, height, depth). 1D and 2D images
71  /// ignore some of the sizes.
72  void setSize(int w, int h, int d)
73  {
74  UT_ASSERT(w >= 1);
75  UT_ASSERT(h >= 1);
76  UT_ASSERT(d >= 1);
77 
78  myVkCreateInfo.extent.width = w;
79  myVkCreateInfo.extent.height = h;
80  myVkCreateInfo.extent.depth = d;
81  }
82  int getWidth() const
83  { return myVkCreateInfo.extent.width; }
84  int getHeight() const
85  { return myVkCreateInfo.extent.height; }
86  int getDepth() const
87  { return myVkCreateInfo.extent.depth; }
88 
89  /// Define the number of samples in a multisampled 2D image.
90  void setSamples(int samples)
91  {
92  UT_ASSERT(samples >= 1);
93  mySamples = samples;
94  }
95  int getSamples() const
96  { return mySamples; }
97 
98  /// Define the number of layers in a 1D or 2D array.
99  void setLayerCount(int count )
100  {
101  UT_ASSERT(count >= 1);
102  myVkCreateInfo.arrayLayers = count;
103  }
104  int getLayerCount() const
105  { return myVkCreateInfo.arrayLayers; }
106 
107  /// Set the maximum number of mipmap levels.
109  {
110  UT_ASSERT( count >= 1);
111  myMaxLevels = SYSmax(count, 1);
112  }
113  int getMaxLevelCount() const
114  { return myMaxLevels; }
115 
116  int getLevelCount() const
117  {
118  exint max_dim = SYSmax(SYSmax(getWidth(), getHeight()), getDepth());
119  int max_level = SYSfloorLog2(max_dim) + 1;
120  return SYSmin(max_level, getMaxLevelCount());
121  }
122 
123  /// Set the texture filter for texture scales above 1.
125  { myMagFilterMode = filter; }
126  /// Set the texture filter for texture scales below 1.
128  { myMinFilterMode = filter; }
129  /// Set the mipmapping mode - DISABLED, NEAREST mipmap, or LINEAR blend
131  { myMipMode = mode; }
132 
133  /// Set the wrapping mode when uv is outside [0,1]:REPEAT,CLAMP,BORDER,MIRROR
135  { myWrapU = u; myWrapV = v; myWrapW = w; }
136 
138  { return myWrapU; }
140  { return myWrapV; }
142  { return myWrapW; }
143 
145  { myUsageStorageBit = b; }
146  bool getUsageStorageBit() const
147  { return myUsageStorageBit; }
148 
149  /// Use linear tiling (true) or optimal tiling. Not all types support linear.
150  void setUseLinearTiling(bool use)
151  { myUseLinearTiling = use; }
152  bool getUseLinearTiling() const
153  { return myUseLinearTiling; }
154 
156  { myMemType = type; }
158  { return myMemType; }
159 
160  /// Access the vulkan creation structure for this image.
162  { return &myVkCreateInfo; }
163 
164  /// Finalize Create Info struct before being passed to
165  /// Vulkan API, and perform any final checks.
166  /// To Be called by Vulkan Image allocate function.
167  /// Returns false if any checks fail
168  virtual bool fillCreateInfo();
169 
170  // Constructors
171  RV_VKImageCreateInfo() = default;
172  virtual RV_VKImageCreateInfo* clone() const
173  {
174  return new RV_VKImageCreateInfo(*this);
175  }
176 
177  virtual ~RV_VKImageCreateInfo();
178 
179 protected:
180  RV_VKImageCreateInfo(const RV_VKImageCreateInfo&) = default;
181 
182  bool isValidForLinearTiling() const;
183 
184  /// Extend Image Create Info struct.
185  /// Used by subclasses to create different
186  /// types of images
188  {
189  UT_ASSERT(p);
190  p->pNext = (VkBaseOutStructure*)myVkCreateInfo.pNext;
191  myVkCreateInfo.pNext = p;
192  }
193 
194  /// Setup allocation info for memory
195  virtual RV_MemType getAllocType(RV_Instance* inst);
196 
197  // ~~~~ Data Members ~~~~
198  // Image format
199  uint32_t mySamples = 0;
200  int myMaxLevels = 1;
201 
202  bool myUseLinearTiling = false;
203  RV_MemType myMemType = RV_MEM_AUTO;
204  RV_ImageDim myRVImageType = RV_IMAGE_2D;
205 
206  // Sampler Info
207  fpreal32 myMinLOD = 0.0;
209  bool myIsNormalized = false;
210  bool myIsTexelSampled = false;
211  bool myUsageStorageBit = false;
218  UT_Vector4F myBorderColor = {0.f, 0.f, 0.f, 0.f};
219 
220  // Vk Image Creation Info struct
221  VkImageCreateInfo myVkCreateInfo = {
223  nullptr,
224  0, /* flags */
225  VK_IMAGE_TYPE_2D, /* imageType */
226  VK_FORMAT_UNDEFINED, /* format */
227  {0, 0, 0}, /* extent */
228  1, /* mipLevels */
229  1, /* arrayLayers */
230  VK_SAMPLE_COUNT_1_BIT, /* samples */
231  VK_IMAGE_TILING_OPTIMAL,/* tiling */
232  0, /* usage */
233  VK_SHARING_MODE_EXCLUSIVE, /* sharingMode */
234  0, /* queueFamilyIndexCount */
235  nullptr, /* pQueueFamilyIndices */
236  VK_IMAGE_LAYOUT_UNDEFINED, /* initialLayout */
237  };
238 
239  friend class RV_VKImage;
240 };
241 
242 /// RAII wrapper class for VkImageView
244 {
245 public:
246  /// Access the vulkan resource for the view
247  VkImageView getVkView() { return myVkView; }
248 
249  // CAN have null state
251  : myInst(nullptr), myVkView(VK_NULL_HANDLE)
252  {}
253  RV_VKImageView(RV_Instance* inst, VkImageView vk_view)
254  : myInst(inst), myVkView(vk_view)
255  {}
256 
257  // disable copy semantics
258  RV_VKImageView(const RV_VKImageView&) = delete;
260 
261  // enable move semantics
262  RV_VKImageView(RV_VKImageView&& other) noexcept
263  : myInst(other.myInst), myVkView(other.myVkView)
264  {
265  other.myInst = nullptr;
266  other.myVkView = VK_NULL_HANDLE;
267  }
268  RV_VKImageView& operator=(RV_VKImageView&& other) noexcept = delete;
269 
270  // Destroy Resource Handle on destruction
272  {
273  if (myVkView != VK_NULL_HANDLE)
274  {
275  VkDevice vk_dev = myInst->getDevice();
276  ::vkDestroyImageView(vk_dev, myVkView, nullptr);
277  }
278  }
279 
280 private:
281  RV_Instance* myInst = nullptr;
282  VkImageView myVkView = VK_NULL_HANDLE;
283 };
284 
285 // RAII wrapper for sampler
287 {
288 public:
289  /// Access the vulkan resource for the sampler
290  VkSampler getVkSampler() { return myVkSampler; }
291 
292  // CAN have null state
294  : myInst(nullptr), myVkSampler(VK_NULL_HANDLE)
295  {}
296  RV_VKSampler(RV_Instance* inst, VkSampler vk_sampler)
297  : myInst(inst), myVkSampler(vk_sampler)
298  {}
299 
300  // disable copy semantics
301  RV_VKSampler(const RV_VKSampler&) = delete;
302  RV_VKSampler& operator=(RV_VKSampler& ) = delete;
303 
304  // enable move semantics
305  RV_VKSampler(RV_VKSampler&& other) noexcept
306  : myInst(other.myInst), myVkSampler(other.myVkSampler)
307  {
308  other.myInst = nullptr;
309  other.myVkSampler = VK_NULL_HANDLE;
310  }
311  RV_VKSampler& operator=(RV_VKSampler&& other) noexcept = delete;
312  // Destroy Resource Handle on destruction
314  {
315  if (myVkSampler != VK_NULL_HANDLE)
316  {
317  VkDevice vk_dev = myInst->getDevice();
318  ::vkDestroySampler(vk_dev, myVkSampler, nullptr);
319  }
320  }
321 
322 private:
323  RV_Instance* myInst = nullptr;
324  VkSampler myVkSampler = VK_NULL_HANDLE;
325 };
326 
327 /// Class hodling VkImage handle and bound Memory allocation
328 /// cleans up resources on destruction
330 {
331 public:
332  /// Creates new Image based on create info
333  static RV_VKImage* allocateImage(
334  RV_Instance* inst,
335  RV_VKImageCreateInfo* info,
336  const char* name = nullptr);
337 
338  /// check whether the format info in pInfo can create
339  /// a valid Vulkan image
340  static bool queryIsUsable(
341  RV_Instance* inst,
342  RV_VKImageCreateInfo* info);
343 
344  /// The image properties
345  const RV_VKImageCreateInfo& getInfo() const { return *myCreateInfo; }
346 
347  // Getters for image members
348  VkImage getVkImage() { return myVkImg; }
349  RV_VKMemory& getMemory() { return *myMemory; }
350  RV_VKSampler& getSampler() { return *mySampler; }
351  VkImageLayout getLayout() const { return myLastLayout; }
352 
353  RV_VKImageView& getFullView() { return *myView; }
355  { return myPrimaryView ? *myPrimaryView :*myView;}
356 
357  // Functions to create Image View for image
358  /// Create new VkImageView for whole VkImage range
359  RV_VKImageView createView();
360  /// Create new VkImageView for specific VkImage subresource range
361  RV_VKImageView createView(const VkImageSubresourceRange &subres);
362  /// Create new VkImageView for specific VkImage subresource range, with type
363  RV_VKImageView createView(const VkImageSubresourceRange &subres, VkImageViewType type);
364  /// Create new VkImageView for specific type, trying to use full subresource range
365  RV_VKImageView createView(VkImageViewType type);
366 
367  /// Record a command to transition image into new layout
368  void transitionImage(
369  RV_VKCommandBuffer* cb,
370  VkImageLayout new_layout,
371  VkImageUsageFlags new_usage, // TODO: new struct to encapsulate access, stage, usage
372  // want to be able to specify extra params
373  // (e.g. read vs write access, and specific pipeline shader stage)
374  // without cluttering the function signature
375  bool keep_data = true,
377 
378  /// Record a command to transition the image for sampling in a shader
380  {
381  transitionImage(cb, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
383  }
384 
385  /// Upload data to the image. Must be in a state for upload.
387  bool uploadData(RV_Render* r, const T &data, int level = 0, int index = 0)
388  {
389  // `T` must be a `UT_Span` or convertable into a `UT_Span`
391  return uploadData(
392  r->instance(), r->getCurrentCB(),
393  span.data(), span.size_bytes(),
394  level, index);
395  }
396 
397  bool uploadData(
398  RV_Render* r,
399  const void* data,
400  exint data_size,
401  int level = 0,
402  int index = 0);
403 
404  bool uploadData(
405  RV_Instance* inst,
406  RV_VKCommandBuffer* cb,
407  const void* data,
408  exint data_size,
409  int level = 0,
410  int index = 0);
411 
412  // TODO: add options for level, layer, separate aspects, offsets
413  /// Copy image data from this image to `other`.
414  bool copyData(RV_Render* r, RV_VKImage* other);
415 
416  /// Generate higher mipmap levels from the base level
417  void generateMipmaps(RV_Render* r);
418 
419  /// Download image data into `data`.
420  bool downloadData(
421  RV_Render* r,
422  void* data,
423  exint data_size,
424  int level = 0,
425  int index = 0,
426  bool primary_aspect = true);
427 
428  virtual ~RV_VKImage();
429 
430  /// Debug print out of image properties (not image data).
431  void print() const;
432 
433 protected:
434  RV_VKImage(
435  RV_Instance* inst,
436  const RV_VKImageCreateInfo* img_info,
437  VkImage vk_img,
438  RV_VKMemory* mem,
440  RV_VKImageView* primary_view,
442 
443  static void deleteImage(
444  RV_Instance* inst,
445  VkImage* img,
446  VkDeviceMemory* mem);
447 
448  // basic resource handles
449  RV_Instance* myInst = nullptr;
450  VkImage myVkImg = VK_NULL_HANDLE;
452 
457 
458 public: // wip
459  // Vulkan Resource Usage
461  VkAccessFlags myLastAccess = 0;
462  VkImageUsageFlags myLastUsage = 0;
463  VkPipelineStageFlags myLastStage = 0;
464  uint32_t myLastQueueFam = 0;
465 
466  RV_StageGroup myWaitingBarrierStage = RV_STAGE_NONE;
467 
468  friend class RV_VKImageCreateInfo;
469 };
470 
471 #endif
void setTextureMinFilter(RV_TextureFilter filter)
Set the texture filter for texture scales below 1.
Definition: RV_VKImage.h:127
#define SYSmax(a, b)
Definition: SYS_Math.h:1538
UT_UniquePtr< RV_VKMemory > myMemory
Definition: RV_VKImage.h:455
void setUsageStorageBit(bool b)
Definition: RV_VKImage.h:144
VkSampler getVkSampler()
Access the vulkan resource for the sampler.
Definition: RV_VKImage.h:290
int getLevelCount() const
Definition: RV_VKImage.h:116
#define VK_NULL_HANDLE
Definition: vulkan_core.h:45
int getWidth() const
Definition: RV_VKImage.h:82
int getSamples() const
Definition: RV_VKImage.h:95
constexpr span< ElementType, Extent > make_span(span< ElementType, Extent > s) noexcept
Definition: UT_Span.h:559
RV_VKImageView & operator=(RV_VKImageView &)=delete
const GLdouble * v
Definition: glcorearb.h:837
const VkImageCreateInfo * getVkInfo() const
Access the vulkan creation structure for this image.
Definition: RV_VKImage.h:161
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Definition: span.h:73
int64 exint
Definition: SYS_Types.h:125
GLint level
Definition: glcorearb.h:108
RV_StageGroup
Definition: RV_Type.h:429
void setSamples(int samples)
Define the number of samples in a multisampled 2D image.
Definition: RV_VKImage.h:90
void addNext(VkBaseOutStructure *p)
Definition: RV_VKImage.h:187
void setTextureWrap(RV_TextureWrap u, RV_TextureWrap v, RV_TextureWrap w)
Set the wrapping mode when uv is outside [0,1]:REPEAT,CLAMP,BORDER,MIRROR.
Definition: RV_VKImage.h:134
VkFlags VkPipelineStageFlags
Definition: vulkan_core.h:2401
UT_UniquePtr< RV_VKSampler > mySampler
Definition: RV_VKImage.h:456
#define VK_LOD_CLAMP_NONE
Definition: vulkan_core.h:125
RV_VKSampler(RV_VKSampler &&other) noexcept
Definition: RV_VKImage.h:305
GLuint sampler
Definition: glcorearb.h:1656
VKAPI_ATTR void VKAPI_CALL vkDestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator)
void setLayerCount(int count)
Define the number of layers in a 1D or 2D array.
Definition: RV_VKImage.h:99
float fpreal32
Definition: SYS_Types.h:200
void setMaxLevelCount(int count)
Set the maximum number of mipmap levels.
Definition: RV_VKImage.h:108
RV_TextureMipMode
Definition: RV_Type.h:134
RV_VKSampler & getSampler()
Definition: RV_VKImage.h:350
UT_UniquePtr< RV_VKImageView > myView
Definition: RV_VKImage.h:453
RV_VKCommandBuffer * getCurrentCB()
The currently recording command buffer.
VKAPI_ATTR void VKAPI_CALL vkDestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator)
VkFlags VkImageUsageFlags
Definition: vulkan_core.h:2311
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
void setTextureMipMode(RV_TextureMipMode mode)
Set the mipmapping mode - DISABLED, NEAREST mipmap, or LINEAR blend.
Definition: RV_VKImage.h:130
virtual RV_VKImageCreateInfo * clone() const
Definition: RV_VKImage.h:172
RV_VKMemory & getMemory()
Definition: RV_VKImage.h:349
int getLayerCount() const
Definition: RV_VKImage.h:104
RV_VKSampler(RV_Instance *inst, VkSampler vk_sampler)
Definition: RV_VKImage.h:296
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
VkImageType getImageType() const
The Vulkan image type.
Definition: RV_VKImage.h:55
VkImageLayout getLayout() const
Definition: RV_VKImage.h:351
#define RV_API
Definition: RV_API.h:10
RV_TextureWrap
Definition: RV_Type.h:141
RV_TextureWrap getTextureWrapV()
Definition: RV_VKImage.h:139
void transitionToSampling(RV_VKCommandBuffer *cb)
Record a command to transition the image for sampling in a shader.
Definition: RV_VKImage.h:379
void setMemoryType(RV_MemType type)
Definition: RV_VKImage.h:155
GLuint const GLchar * name
Definition: glcorearb.h:786
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:36
GLint void * img
Definition: glcorearb.h:556
RV_TextureFilter
Definition: RV_Type.h:127
bool uploadData(RV_Render *r, const T &data, int level=0, int index=0)
Upload data to the image. Must be in a state for upload.
Definition: RV_VKImage.h:387
VkImageType
Definition: vulkan_core.h:1699
GLsizei samples
Definition: glcorearb.h:1298
GLenum mode
Definition: glcorearb.h:99
RV_Instance * instance()
The instance associated with this render.
Definition: RV_Render.h:73
int getMaxLevelCount() const
Definition: RV_VKImage.h:113
RV_ImageDim getRVImageType() const
The RV image type.
Definition: RV_VKImage.h:57
RV_TextureWrap getTextureWrapU()
Definition: RV_VKImage.h:137
int getHeight() const
Definition: RV_VKImage.h:84
RV_VKImageView(RV_VKImageView &&other) noexcept
Definition: RV_VKImage.h:262
RV_VKImageView & getFullView()
Definition: RV_VKImage.h:353
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
RV_MemType getMemoryType() const
Definition: RV_VKImage.h:157
VkFlags VkAccessFlags
Definition: vulkan_core.h:2155
int getDepth() const
Definition: RV_VKImage.h:86
UT_UniquePtr< const RV_VKImageCreateInfo > myCreateInfo
Definition: RV_VKImage.h:451
VkImageLayout
Definition: vulkan_core.h:1250
void setSize(int w, int h, int d)
Definition: RV_VKImage.h:72
GLuint index
Definition: glcorearb.h:786
const RV_VKImageCreateInfo & getInfo() const
The image properties.
Definition: RV_VKImage.h:345
constexpr size_type size_bytes() const noexcept
Definition: span.h:186
VkImageView getVkView()
Access the vulkan resource for the view.
Definition: RV_VKImage.h:247
VkFormat getFormat() const
Definition: RV_VKImage.h:65
VkFormat
Definition: vulkan_core.h:1386
RV_TextureWrap getTextureWrapW()
Definition: RV_VKImage.h:141
bool getUsageStorageBit() const
Definition: RV_VKImage.h:146
Definition: core.h:982
void setUseLinearTiling(bool use)
Use linear tiling (true) or optimal tiling. Not all types support linear.
Definition: RV_VKImage.h:150
VkDevice getDevice()
Get the raw vulkan device assocated with this instance.
RV_MemType
Definition: RV_Type.h:102
VkImageViewType
Definition: vulkan_core.h:1757
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
void setFormat(VkFormat format)
Set the vulkan image format. RV.
Definition: RV_VKImage.h:64
VkImage getVkImage()
Definition: RV_VKImage.h:348
GLboolean r
Definition: glcorearb.h:1222
RV_VKSampler & operator=(RV_VKSampler &)=delete
RV_ImageDim
Definition: RV_Type.h:111
#define SYSmin(a, b)
Definition: SYS_Math.h:1539
type
Definition: core.h:1059
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2976
constexpr pointer data() const noexcept
Definition: span.h:189
void setTextureMagFilter(RV_TextureFilter filter)
Set the texture filter for texture scales above 1.
Definition: RV_VKImage.h:124
UT_UniquePtr< RV_VKImage > RV_VKImagePtr
Definition: RV_VKImage.h:35
UT_UniquePtr< RV_VKImageView > myPrimaryView
Definition: RV_VKImage.h:454
GLint GLsizei count
Definition: glcorearb.h:405
Definition: format.h:895
bool getUseLinearTiling() const
Definition: RV_VKImage.h:152
RV_VKImageView(RV_Instance *inst, VkImageView vk_view)
Definition: RV_VKImage.h:253
struct VkBaseOutStructure * pNext
Definition: vulkan_core.h:2817
RV_VKImageView & getPrimaryView()
Definition: RV_VKImage.h:354
RAII wrapper class for VkImageView.
Definition: RV_VKImage.h:243
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297