Polyphase Game Engine
Loading...
Searching...
No Matches
Image.h
Go to the documentation of this file.
1#pragma once
2
3#if API_VULKAN
4
6#include "Maths.h"
7
8#include <vulkan/vulkan.h>
9
10class DestroyQueue;
11
12struct ImageDesc
13{
14 uint32_t mWidth = 4;
15 uint32_t mHeight = 4;
16 VkFormat mFormat = VK_FORMAT_R8G8B8A8_UNORM;
17 VkImageUsageFlags mUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
18 uint32_t mMipLevels = 1;
19 uint32_t mLayers = 1;
20};
21
22struct SamplerDesc
23{
24 VkFilter mMagFilter = VK_FILTER_LINEAR;
25 VkFilter mMinFilter = VK_FILTER_LINEAR;
26 VkSamplerAddressMode mAddressMode = VK_SAMPLER_ADDRESS_MODE_REPEAT;
27 VkBorderColor mBorderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
28 float mMaxAnisotropy = 1.0;
29 bool mAnisotropyEnable = false;
30};
31
32class Image
33{
34public:
35 Image(ImageDesc imageDesc, SamplerDesc samplerDesc, const char* debugObjectName);
36
37 // External image? Kind of a hack needed for using swapchain images with RenderPassCache
38 Image(VkImage image, VkImageView imageView, VkSampler sampler, VkFormat format, uint32_t width, uint32_t height);
39
40 VkImage Get() const;
41 VkImageView GetView() const;
42 VkSampler GetSampler() const;
43
44 VkFormat GetFormat() const;
45 uint32_t GetWidth() const;
46 uint32_t GetHeight() const;
47
48 // waitForCompletion: Update()'s upload/transition commands are submitted
49 // fire-and-forget (no fence) by default -- fine for a texture that gets
50 // re-uploaded every frame (any single stale frame is imperceptible), but
51 // wrong for a texture uploaded ONCE and sampled immediately: on a slow
52 // GPU queue (seen on Android/mobile; desktop's queue is fast enough to
53 // mask it) the sample can land before the upload actually finishes,
54 // rendering stale/undefined content forever since nothing re-uploads to
55 // self-correct. Pass true for exactly that one-shot case -- see
56 // CreateTextureResource()'s call (Texture::Create()'s initial upload).
57 void Update(const void* srcData, bool waitForCompletion = false);
58
59 void Transition(VkImageLayout layout, VkCommandBuffer commandBuffer = VK_NULL_HANDLE);
60 void GenerateMips();
61 void Clear(glm::vec4 color);
62
63 uint64_t GetId() const;
64
65private:
66
67 friend class DestroyQueue;
68 ~Image();
69
70 uint64_t mId = 0;
71 VkImage mImage = VK_NULL_HANDLE;
72 VkImageView mImageView = VK_NULL_HANDLE;
73 VkSampler mSampler = VK_NULL_HANDLE;
74 VramAllocation mMemory;
75
76 uint32_t mWidth = 0;
77 uint32_t mHeight = 0;
78 VkFormat mFormat = VK_FORMAT_UNDEFINED;
79 VkImageUsageFlags mUsage = {};
80 uint32_t mMipLevels = 0;
81 uint32_t mLayers = 0;
82
83 VkFilter mMagFilter = VK_FILTER_LINEAR;
84 VkFilter mMinFilter = VK_FILTER_LINEAR;
85 VkSamplerAddressMode mAddressMode = VK_SAMPLER_ADDRESS_MODE_REPEAT;
86 VkBorderColor mBorderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
87 float mMaxAnisotropy = 1.0;
88 bool mAnisotropyEnable = false;
89
90 // UNDEFINED, not PREINITIALIZED: every Image this class creates is
91 // OPTIMAL-tiled + DEVICE_LOCAL and is never host-written, and
92 // PREINITIALIZED is only meaningful for LINEAR-tiled host-written memory.
93 // Must match ciImage.initialLayout in the constructor. The first upload's
94 // transition then takes the UNDEFINED->TRANSFER_DST barrier (srcAccess=0),
95 // which is spec-valid; the old PREINITIALIZED path used
96 // VK_ACCESS_HOST_WRITE_BIT under a stage mask with no HOST stage -- an
97 // ill-formed barrier desktop drivers forgive but mobile GPUs (Adreno/Mali
98 // texture compression metadata) don't, sampling as black on the first
99 // upload of a fresh image. Only a one-shot texture ever exposed it; a
100 // per-frame stream re-uploads and self-heals from frame 2.
101 VkImageLayout mLayout = VK_IMAGE_LAYOUT_UNDEFINED;
102
103 bool mExternal = false;
104};
105
106#endif
bool Update()
Definition Engine.cpp:995