Jackalope / jen (public) (License: GPLv3 or later version) (since 2018-10-24) (hash sha1)
----> ABOUT:

3D rendering and computing framework based on Vulkan API.

Libraries:
- simdcpp submodule (see my simdcpp repo)
- jmath submodule (see my jmath repo)
- mesh (constexpr generation of cubes, spheres, icosahedrons subdivisions)
- atlas (1D lines and 2D rectangles cutting)
- jlib submodule (see my jlib repo)
- jrf submodule (see my jrf repo)
- vkw (Vulkan API C++ wrapper)
Modules:
- compute (run compute shaders on gpu)
- graphics (draw models with clustered forward rendering and onscreen text)
- resource manager (load meshes, models, textures, scene data from
files and create related objects in graphics module)

----> INSTALLING:

To download all the parts of this framework it's enough to launch
git clone with recursive flag:

$ git clone —recursive ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jen

After this look at git tags:

$ git tag

It is recommended to use a tagged version instead of the latest commit,
because the first commit after the tagged one mostly includes incompatible
parts of future changes for the next version.

$ git checkout v0.1.0

----> DEPENDENCIES:

To use JEN as CMake subdirectory and successfully build programs with it
you need to make sure you have all of its dependencies:
- compiler: Clang or GCC, support for C++17. Clang 10+ or GCC 9+ is recommended,
compiling on Windows OS is tricky and requires something like MinGW with MSYS,
there are also some complications to go through to make dependencies work;
- GLFW3 library, supported version is 3.2.1;
- FreeType library, if graphics module will be used;
- Vulkan API headers, and optional validation layers to debug sneaky problems,
you also need Vulkan support in your graphics driver to run compiled programs;
- LibZip can be necessary, if JRF is used to read zip files;
- CMake, for obvious reasons;
- glslangValidator to compile shader for the graphics module.

CMake must be able to find GLFW3, Vulkan and FreeType (for graphics)
with find_package().

----> HOW TO USE IT:

To use JEN, you need to add it as a subdirectory:

add_subdirecroty(${PATH_TO_JEN})

There are several configuration options:
- JEN_MODULE_COMPUTE - turn compute module on for compiling and including;
- JEN_MODULE_GRAPHICS - turn graphics module on ...;
- JEN_MULTITHREADED_DRAW_FRAME - draw_frame function will use thread pool queue
instead of linear executing;
- JEN_MODULE_RESOURCE_MANAGER - resource manager module ON, if graphics is ON;
- JEN_VLK_VALIDATION - enable Vulkan Validation Layers to debug some errors
related to JEN. This will often produce false-positive,
as well as true-positive errors.

Look in CMakeLists.txt at JenExamples repo for details on how to use and
configure JEN automatically:

$ git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/JenExamples

Also I recommend to compile and run examples to make sure it works correctly.

----> SUPPORTED HARDWARE:

JEN has not been tested well, because it requires running it on large amount of
different hardware to do so. It must work with mesa driver and modern
Intel i965 GPUs as well as AMD GPUs.


----> DOCUMENTATION:

You can generate Doxygen documentation, to do so
turn on any of JEN_DOXYGEN_* options and run documentation target in cmake:

$ cmake -G %1 -DJEN_DOXYGEN_HTML=ON -DJEN_DOXYGEN_LATEX=ON
$ cmake —build —target documentation

Resource manager is not documented because it still requires large enhancements.
List of commits:
Subject Hash Author Date (UTC)
Added VkFormat properties checks and fallbacks to follow specification rules. 3c38bb0e9916aea31ef796a53a024aa3111e1ec7 Jackalope 2020-05-19 17:42:59
renamed compute::BindingsSet to BindingSet, vkw::BindNo to vkw::Binding, compute::BindingCreateInfo.bindingNo to binding 072430e257166208d6f4a7b759169779f21bf4c8 Jackalope 2020-05-18 17:51:25
better documentation 5233938573e5c557667de4f467209099a3d48faa Jackalope 2020-05-18 17:38:59
README improvements 3efd2a514affc8c6d706799fd56857c1a7c0d0f6 Jackalope 2020-05-18 17:35:48
better hash for white noise 55b1d39969b9a27a602c464ca216a89ec92cee0b Jackalope 2020-05-17 11:20:30
another reference to temporary removed 84231ce8c36619f9c696cb7da2879f504fa2e66c Jackalope 2020-05-17 10:46:26
removed git_sh directory 4fab20bc30f66ff96fdc9a336708cc5049c13ecb Jackalope 2020-05-17 04:13:34
README 9f70b0aba59a4eed15c5dc86423b0f7976734ce2 Jackalope 2020-05-17 04:09:18
removed C99 extension used in the nested structures initialization b5f33b0c562fd8cc872217eefde5fd6f58318ea3 Jackalope 2020-05-17 03:53:57
Make JEN modules as separate CMake targets e51ffd5b6cb8b1ba15e1f5df683feec8e0665240 Jackalope 2020-05-17 03:52:55
Automated shaders compilation with cmake, no more binaries in git efa9657336852c3543221bc56f4121f698f26044 Jackalope 2020-05-16 13:07:12
Compute process bug fix: correctly fences reset and removed reference to temporary c30b7bf737890cc3a23022c5c5470225bb324443 Jackalope 2020-05-16 07:00:15
pass shader specialization by constant refference 9e14c11e60d709d374f71aec393d28377b1525d2 Jackalope 2020-05-15 12:45:06
Added second template argument for white noise to support custom hash function. 9a714ad51903e35d158ff285fc6e1f517e7100c0 TheArtOfGriefing 2020-05-15 12:22:08
Added shadow map commads fence 447a75b3124eae48d64bf3646df90a7db1adcc57 Jackalope 2020-05-13 09:38:49
Fixed bug with timeline semaphores 08be9cf8af7d32c460fc77ca7c5b0a25976a6d79 Jackalope 2020-05-13 08:21:33
added pipeline cache, refactoring of pipeline stages af2d7d18e63fdeaaec3ca7d92a8f02b107358f27 Jackalope 2020-05-13 08:35:26
window unititialized values fix d9f6249e63550b07d932887c37a233182e7740af Jackalope 2020-05-13 04:21:26
added project information to cmake 2db949aaf90729d4226511773815eb19a314dc35 Jackalope 2020-05-12 18:42:50
Improved cmake scripts c38f2da172d553d519f0cee5d9b6b3f904234806 Jackalope 2020-05-12 07:02:26
Commit 3c38bb0e9916aea31ef796a53a024aa3111e1ec7 - Added VkFormat properties checks and fallbacks to follow specification rules.
Author: Jackalope
Author date (UTC): 2020-05-19 17:42
Committer name: Jackalope
Committer date (UTC): 2020-05-19 17:42
Parent(s): 072430e257166208d6f4a7b759169779f21bf4c8
Signer:
Signing key:
Signing status: N
Tree: 3e7bd30560bbfb58ed5dd8e5c1569d7c52d6536e
File Lines added Lines deleted
include/jen/compute.h 9 8
include/jen/resources.h 0 2
libs/jrf 1 1
libs/vkw/CMakeLists.txt 3 5
libs/vkw/include/vkw/command_buffer.h 1 1
libs/vkw/include/vkw/device_physical.h 26 131
libs/vkw/include/vkw/typedefs.h 266 133
libs/vkw/src/command_buffer.cpp 0 103
libs/vkw/src/result.cpp 0 92
libs/vkw/src/vkw.cpp 253 0
src/compute/CMakeLists.txt 1 1
src/compute/cmd_unit.cpp 1 2
src/compute/compute.cpp 36 3
src/device/device.cpp 1 0
src/device/device.h 1 0
src/graphics/draw_stages/attachment.cpp 1 1
src/graphics/draw_stages/pass_depthcube.cpp 4 7
src/graphics/draw_stages/pass_main.cpp 236 310
src/graphics/draw_stages/pass_main.h 50 57
src/graphics/gpu_transfer/data.cpp 25 24
src/graphics/gpu_transfer/gpu_transfer.cpp 12 32
src/graphics/graphics.cpp 3 3
src/graphics/graphics_interface.cpp 42 2
src/graphics/resources.h 4 6
File include/jen/compute.h changed (mode: 100644) (index 14199e1..d956012)
27 27 #endif #endif
28 28 #include <jen/detail/gpu_image.h> #include <jen/detail/gpu_image.h>
29 29 #include <jen/detail/cmd_container.h> #include <jen/detail/cmd_container.h>
30 #include <jrf/image.h>
30 31
31 32 namespace jen::compute { namespace jen::compute {
32 33 /// @brief Flags to specify binding buffer usage /// @brief Flags to specify binding buffer usage
 
... ... namespace jen::compute {
96 97 /// Values must be in range: /// Values must be in range:
97 98 /// [1;2048] for a 3D image; /// [1;2048] for a 3D image;
98 99 /// [1;16384] for a 2D image /// [1;16384] for a 2D image
99 jm::v3u32 extent;
100 jm::v3u32 extent;
100 101 /// Amount of layers in image array, must be in range [1;2048]. /// Amount of layers in image array, must be in range [1;2048].
101 102 /// Used as 4th dimension - array of images. /// Used as 4th dimension - array of images.
102 uint32_t layer_count;
103 uint32_t layer_count;
103 104 /// Number of mipmap levels in the image /// Number of mipmap levels in the image
104 uint32_t mip_level_count;
105 /// Texel format. @see VkFormat
106 VkFormat format;
105 uint32_t mip_level_count;
106 /// Texel format. @see jrf::Image::Format
107 jrf::Image::Format format;
107 108 /// Image type: 1D, 2D, 3D. @see VkImageType /// Image type: 1D, 2D, 3D. @see VkImageType
108 vkw::ImType type;
109 vkw::ImType type;
109 110 /// Integer amount of samples per pixel. Must be power of 2. /// Integer amount of samples per pixel. Must be power of 2.
110 111 /// Usage of more than 1 sample is called "multisampling". /// Usage of more than 1 sample is called "multisampling".
111 vkw::Samples samples;
112 vkw::Samples samples;
112 113 /// Usage of image. @see ImageUseMask /// Usage of image. @see ImageUseMask
113 ImageUseMask usage;
114 ImageUseMask usage;
114 115 }; };
115 116 /// @brief Constant jl::rarray, array of ImageCreateInfos data types. /// @brief Constant jl::rarray, array of ImageCreateInfos data types.
116 117 using ImageCreateInfos = jl::rarray<const ImageCreateInfo>; using ImageCreateInfos = jl::rarray<const ImageCreateInfo>;
File include/jen/resources.h changed (mode: 100644) (index ec9b1c9..29a4e2f)
... ... namespace jen {
32 32 struct GlyphManager; struct GlyphManager;
33 33 /// @brief In case user wants to allocate manually. /// @brief In case user wants to allocate manually.
34 34 constexpr static const uint64_t GPU_DATA_ALLOCATION_SIZE = 88; constexpr static const uint64_t GPU_DATA_ALLOCATION_SIZE = 88;
35 /// @brief Just for fun
36 constexpr static const uint64_t GPU_TEXTURE_ALLOCATION_SIZE = 120;
37 35 /// @brief User provided data to write into resource memory. /// @brief User provided data to write into resource memory.
38 36 struct WriteData { struct WriteData {
39 37 void *p; ///< Pointer to data which user want to write void *p; ///< Pointer to data which user want to write
File libs/jrf changed (mode: 160000) (index 9c704c5..46ccce5)
1 Subproject commit 9c704c515769a03e5b1f82dcb1fd947884f1bd1e
1 Subproject commit 46ccce5359274d660b327c667903b9534dc3bfe0
File libs/vkw/CMakeLists.txt changed (mode: 100644) (index 5ff13cb..41e796d)
17 17
18 18 cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
19 19
20 add_library(VKW STATIC src/result.cpp src/command_buffer.cpp)
21 target_include_directories(VKW PUBLIC
22 include
23 ${Vulkan_INCLUDE_DIRS}
24 ${GLFW_INCLUDE_DIRS}
20 add_library(VKW STATIC src/vkw.cpp)
21 target_include_directories(VKW
22 PUBLIC include ${Vulkan_INCLUDE_DIRS} ${GLFW_INCLUDE_DIRS}
25 23 ) )
26 24 target_link_libraries(VKW JLIB) target_link_libraries(VKW JLIB)
27 25 target_compile_options(VKW PRIVATE ${JEN_COMPILE_OPTIONS}) target_compile_options(VKW PRIVATE ${JEN_COMPILE_OPTIONS})
File libs/vkw/include/vkw/command_buffer.h changed (mode: 100644) (index 2c2ce62..deb8898)
... ... namespace vkw
95 95 StructHeader __header = {StructType::BARRIER_IMAGE_MEM}; StructHeader __header = {StructType::BARRIER_IMAGE_MEM};
96 96 AccessMaskChange access_change; AccessMaskChange access_change;
97 97 ImLayoutChange layout_change; ImLayoutChange layout_change;
98 Change<uint32_t> queueFamily_change;
98 Change<uint32_t> queue_family_change;
99 99 Image image; Image image;
100 100 ImRange range; ImRange range;
101 101 }; };
File libs/vkw/include/vkw/device_physical.h changed (mode: 100644) (index 92bdeee..3122a25)
24 24 namespace vkw { namespace vkw {
25 25 struct DevicePhysical; struct DevicePhysical;
26 26 using DevicesPhysical = Array<DevicePhysical>; using DevicesPhysical = Array<DevicePhysical>;
27
28 /*
29 * When success, devices array must be freed externally
30 * devices.destroy()
27 /**
28 * @param p_dst When success, devices array must be freed externally:
29 * p_dst->destroy()
31 30 */ */
32 [[nodiscard]] inline Result get_devices(Instance in, DevicesPhysical *p_dst);
33
31 [[nodiscard]] Result
32 get_devices(Instance in, DevicesPhysical *p_dst);
34 33 using QueueFamily = uint32_t; using QueueFamily = uint32_t;
35 34 using QueueIndex = uint32_t; using QueueIndex = uint32_t;
36 35 using QueueIndices = Array<const QueueIndex>; using QueueIndices = Array<const QueueIndex>;
37
38 36 namespace QueueFlag { enum Mask { namespace QueueFlag { enum Mask {
39 GRAPHICS = VK_QUEUE_GRAPHICS_BIT,
40 COMPUTE = VK_QUEUE_COMPUTE_BIT,
41 TRANSFER = VK_QUEUE_TRANSFER_BIT,
42 SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT,
43 PROTECTED = VK_QUEUE_PROTECTED_BIT
44 }; }
37 GRAPHICS = VK_QUEUE_GRAPHICS_BIT,
38 COMPUTE = VK_QUEUE_COMPUTE_BIT,
39 TRANSFER = VK_QUEUE_TRANSFER_BIT,
40 SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT,
41 PROTECTED = VK_QUEUE_PROTECTED_BIT
42 }; }
45 43 using QueueMask = uint32_t; using QueueMask = uint32_t;
46
47 44 struct QueueFamilyProperties : StructWrapper<VkQueueFamilyProperties> { struct QueueFamilyProperties : StructWrapper<VkQueueFamilyProperties> {
48 45 QueueMask queueFlags; QueueMask queueFlags;
49 46 QueueIndex queueCount; QueueIndex queueCount;
 
... ... namespace vkw {
54 51 using QueueFamiliesProperties = jl::array<QueueFamilyProperties, using QueueFamiliesProperties = jl::array<QueueFamilyProperties,
55 52 MAX_QUEUE_FAMILIES>; MAX_QUEUE_FAMILIES>;
56 53 } }
57
58 54 struct vkw::DevicePhysical : HandleWrapper<VkPhysicalDevice> struct vkw::DevicePhysical : HandleWrapper<VkPhysicalDevice>
59 55 { {
60 void queue_families_properties(uint32_t *p_count_dst,
61 QueueFamiliesProperties *p_dst) {
62 vkGetPhysicalDeviceQueueFamilyProperties(p_vk, p_count_dst, nullptr);
56 void
57 queue_families_properties(uint32_t *p_count_dst,
58 QueueFamiliesProperties *p_dst) {
59 vkGetPhysicalDeviceQueueFamilyProperties(p_vk, p_count_dst, {});
63 60 jassert_release(*p_count_dst <= MAX_QUEUE_FAMILIES, jassert_release(*p_count_dst <= MAX_QUEUE_FAMILIES,
64 61 "too many device queue families"); "too many device queue families");
65 62 vkGetPhysicalDeviceQueueFamilyProperties(p_vk, p_count_dst, vkGetPhysicalDeviceQueueFamilyProperties(p_vk, p_count_dst,
 
... ... struct vkw::DevicePhysical : HandleWrapper<VkPhysicalDevice>
69 66 is_present_supported(Surface surface, QueueFamily qf, bool32 *p_dst) { is_present_supported(Surface surface, QueueFamily qf, bool32 *p_dst) {
70 67 return vkGetPhysicalDeviceSurfaceSupportKHR(p_vk, qf, surface, p_dst); return vkGetPhysicalDeviceSurfaceSupportKHR(p_vk, qf, surface, p_dst);
71 68 } }
72 [[nodiscard]] Result check_extension_support(Strings extensions)
73 {
74 uint32_t count;
75 vkEnumerateDeviceExtensionProperties(p_vk, {}, &count, {});
76
77 jl::rarray<VkExtensionProperties> dev_exts;
78 if (not dev_exts.init(count))
79 return VK_ERROR_OUT_OF_HOST_MEMORY;
80 vkEnumerateDeviceExtensionProperties(p_vk, {}, &count, dev_exts.begin());
81
82 for (auto &extension : extensions) {
83 for (auto ex : dev_exts)
84 if (strcmp(ex.extensionName, extension) == 0)
85 goto CONTINUE;
86 dev_exts.destroy();
87 fprintf(stderr, "extension %s not present\n", extension);
88 return ERROR_PHYSICAL_DEVICE_NOT_SUITABLE;
89 CONTINUE:;
90 }
91 dev_exts.destroy();
92 return VK_SUCCESS;
93 }
94
95
96 [[nodiscard]] VkFormatProperties properties(VkFormat format) {
97 VkFormatProperties properties;
98 vkGetPhysicalDeviceFormatProperties(*this, format, &properties);
99 return properties;
100 }
101
102 69 [[nodiscard]] Result [[nodiscard]] Result
103 70 surface_capabilities(Surface s, VkSurfaceCapabilitiesKHR *p_dst) { surface_capabilities(Surface s, VkSurfaceCapabilitiesKHR *p_dst) {
104 71 return vkGetPhysicalDeviceSurfaceCapabilitiesKHR(*this, s, p_dst); return vkGetPhysicalDeviceSurfaceCapabilitiesKHR(*this, s, p_dst);
105 72 } }
106
107 [[nodiscard]] Result
108 surface_formats(Surface s, vkw::Array<vkw::SurfaceFormat> *p_dst)
109 {
110 Result res;
111 uint32_t count;
112 res = vkGetPhysicalDeviceSurfaceFormatsKHR(*this, s, &count, nullptr);
113 if (res != VK_SUCCESS)
114 return res;
115 if (count == 0) {
116 p_dst->init();
117 return res;
118 }
119
120 if (not p_dst->init(count))
121 return VK_ERROR_OUT_OF_HOST_MEMORY;
122
123 res = vkGetPhysicalDeviceSurfaceFormatsKHR(*this, s, &count,
124 &p_dst->first().vk());
125 if (res != VK_SUCCESS)
126 p_dst->destroy();
127 return res;
128 }
129
130 [[nodiscard]] Result surface_present_modes(Surface s, PresentModes *p_dst)
131 {
132 Result res;
133 uint32_t count;
134 res = vkGetPhysicalDeviceSurfacePresentModesKHR(*this, s, &count, nullptr);
135 if (res != VK_SUCCESS)
136 return res;
137
138 if (not p_dst->init(count))
139 return VK_ERROR_OUT_OF_HOST_MEMORY;
140
141 res = vkGetPhysicalDeviceSurfacePresentModesKHR(*this, s, &count,
142 reinterpret_cast<VkPresentModeKHR*>(p_dst->begin()));
143 if (res != VK_SUCCESS)
144 p_dst->destroy();
145 return res;
73 [[nodiscard]] VkFormatProperties format_properties(VkFormat f) {
74 VkFormatProperties fp;
75 vkGetPhysicalDeviceFormatProperties(p_vk, f, &fp);
76 return fp;
146 77 } }
147
148
78 [[nodiscard]] Result
79 check_extension_support(Strings extensions);
80 [[nodiscard]] Result
81 surface_formats(Surface s, vkw::Array<vkw::SurfaceFormat> *p_dst);
82 [[nodiscard]] Result
83 surface_present_modes(Surface s, PresentModes *p_dst);
149 84 [[nodiscard]] bool [[nodiscard]] bool
150 depth_format_supported(VkFormat *p_dst, VkFormat preffered)
151 {
152 VkFormat formats[5] = {
153 VK_FORMAT_D32_SFLOAT,
154 VK_FORMAT_D32_SFLOAT_S8_UINT,
155 VK_FORMAT_D24_UNORM_S8_UINT,
156 VK_FORMAT_D16_UNORM,
157 VK_FORMAT_D16_UNORM_S8_UINT
158 };
159
160 if (properties(preffered).optimalTilingFeatures
161 & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
162 return *p_dst = preffered, true;
163
164 for (size_t i = 0; i < 5; ++i)
165 if (properties(formats[i]).optimalTilingFeatures
166 & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
167 return *p_dst = formats[i], true;
168 fprintf(stderr, "cannot find supported tiling format for gpu\n");
169 return false;
170 }
85 select_depth_format(VkFormat preffered, VkFormat *p_dst);
171 86 }; };
172 87
173 [[nodiscard]] inline vkw::Result vkw::
174 get_devices(Instance in, DevicesPhysical *p_dst)
175 {
176 uint32_t count;
177 VkResult result = vkEnumeratePhysicalDevices(in.p_vk, &count, nullptr);
178 if (result != VK_SUCCESS)
179 return result;
180 if (count == 0) {
181 fprintf(stderr, "Failed to find GPUs with Vulkan support!\n");
182 return result;
183 }
184
185 if (not p_dst->init(count))
186 return VK_ERROR_OUT_OF_HOST_MEMORY;
187
188 result = vkEnumeratePhysicalDevices(in.p_vk, &count, &p_dst->first().p_vk);
189 if (result != VK_SUCCESS)
190 p_dst->destroy();
191 return result;
192 }
File libs/vkw/include/vkw/typedefs.h changed (mode: 100644) (index 3b86268..e3a42a1)
... ... namespace vkw
38 38 using Strings = jl::carray<const char*const>; using Strings = jl::carray<const char*const>;
39 39
40 40 template<typename Source, typename Destination = Source> template<typename Source, typename Destination = Source>
41 union Change
41 struct Change
42 42 { {
43 struct {
44 Source src;
45 Destination dst;
46 };
47 struct {
48 Source initial;
49 Destination final;
50 };
51
52 43 constexpr static void check_same() { constexpr static void check_same() {
53 44 static_assert (std::is_same<Source, Destination>::value); static_assert (std::is_same<Source, Destination>::value);
54 45 } }
 
... ... namespace vkw
73 64 check_same(); check_same();
74 65 std::swap(src,dst); std::swap(src,dst);
75 66 } }
67 Source src;
68 Destination dst;
76 69 }; };
77 70
78 71 using DeviceSize = VkDeviceSize; using DeviceSize = VkDeviceSize;
 
... ... namespace vkw
562 555
563 556 using Binding = uint32_t; using Binding = uint32_t;
564 557
565
558 [[nodiscard]]
566 559 constexpr uint32_t format_size(VkFormat f) { constexpr uint32_t format_size(VkFormat f) {
567 560 uint32_t s = 0; uint32_t s = 0;
568 561 switch(f) { switch(f) {
 
... ... namespace vkw
575 568 case VK_FORMAT_R5G5B5A1_UNORM_PACK16: s = 2; break; case VK_FORMAT_R5G5B5A1_UNORM_PACK16: s = 2; break;
576 569 case VK_FORMAT_B5G5R5A1_UNORM_PACK16: s = 2; break; case VK_FORMAT_B5G5R5A1_UNORM_PACK16: s = 2; break;
577 570 case VK_FORMAT_A1R5G5B5_UNORM_PACK16: s = 2; break; case VK_FORMAT_A1R5G5B5_UNORM_PACK16: s = 2; break;
578 case VK_FORMAT_R8_UNORM: s = 1; break;
579 case VK_FORMAT_R8_SNORM: s = 1; break;
580 case VK_FORMAT_R8_USCALED: s = 1; break;
581 case VK_FORMAT_R8_SSCALED: s = 1; break;
582 case VK_FORMAT_R8_UINT: s = 1; break;
583 case VK_FORMAT_R8_SINT: s = 1; break;
584 case VK_FORMAT_R8_SRGB: s = 1; break;
585 case VK_FORMAT_R8G8_UNORM: s = 2; break;
586 case VK_FORMAT_R8G8_SNORM: s = 2; break;
587 case VK_FORMAT_R8G8_USCALED: s = 2; break;
588 case VK_FORMAT_R8G8_SSCALED: s = 2; break;
589 case VK_FORMAT_R8G8_UINT: s = 2; break;
590 case VK_FORMAT_R8G8_SINT: s = 2; break;
591 case VK_FORMAT_R8G8_SRGB: s = 2; break;
592 case VK_FORMAT_R8G8B8_UNORM: s = 3; break;
593 case VK_FORMAT_R8G8B8_SNORM: s = 3; break;
594 case VK_FORMAT_R8G8B8_USCALED: s = 3; break;
595 case VK_FORMAT_R8G8B8_SSCALED: s = 3; break;
596 case VK_FORMAT_R8G8B8_UINT: s = 3; break;
597 case VK_FORMAT_R8G8B8_SINT: s = 3; break;
598 case VK_FORMAT_R8G8B8_SRGB: s = 3; break;
599 case VK_FORMAT_B8G8R8_UNORM: s = 3; break;
600 case VK_FORMAT_B8G8R8_SNORM: s = 3; break;
601 case VK_FORMAT_B8G8R8_USCALED: s = 3; break;
602 case VK_FORMAT_B8G8R8_SSCALED: s = 3; break;
603 case VK_FORMAT_B8G8R8_UINT: s = 3; break;
604 case VK_FORMAT_B8G8R8_SINT: s = 3; break;
605 case VK_FORMAT_B8G8R8_SRGB: s = 3; break;
606 case VK_FORMAT_R8G8B8A8_UNORM: s = 4; break;
607 case VK_FORMAT_R8G8B8A8_SNORM: s = 4; break;
608 case VK_FORMAT_R8G8B8A8_USCALED: s = 4; break;
609 case VK_FORMAT_R8G8B8A8_SSCALED: s = 4; break;
610 case VK_FORMAT_R8G8B8A8_UINT: s = 4; break;
611 case VK_FORMAT_R8G8B8A8_SINT: s = 4; break;
612 case VK_FORMAT_R8G8B8A8_SRGB: s = 4; break;
613 case VK_FORMAT_B8G8R8A8_UNORM: s = 4; break;
614 case VK_FORMAT_B8G8R8A8_SNORM: s = 4; break;
615 case VK_FORMAT_B8G8R8A8_USCALED: s = 4; break;
616 case VK_FORMAT_B8G8R8A8_SSCALED: s = 4; break;
617 case VK_FORMAT_B8G8R8A8_UINT: s = 4; break;
618 case VK_FORMAT_B8G8R8A8_SINT: s = 4; break;
619 case VK_FORMAT_B8G8R8A8_SRGB: s = 4; break;
620 case VK_FORMAT_A8B8G8R8_UNORM_PACK32: s = 4; break;
621 case VK_FORMAT_A8B8G8R8_SNORM_PACK32: s = 4; break;
622 case VK_FORMAT_A8B8G8R8_USCALED_PACK32: s = 4; break;
623 case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: s = 4; break;
624 case VK_FORMAT_A8B8G8R8_UINT_PACK32: s = 4; break;
625 case VK_FORMAT_A8B8G8R8_SINT_PACK32: s = 4; break;
626 case VK_FORMAT_A8B8G8R8_SRGB_PACK32: s = 4; break;
627 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: s = 4; break;
628 case VK_FORMAT_A2R10G10B10_SNORM_PACK32: s = 4; break;
629 case VK_FORMAT_A2R10G10B10_USCALED_PACK32: s = 4; break;
630 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: s = 4; break;
631 case VK_FORMAT_A2R10G10B10_UINT_PACK32: s = 4; break;
632 case VK_FORMAT_A2R10G10B10_SINT_PACK32: s = 4; break;
633 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: s = 4; break;
634 case VK_FORMAT_A2B10G10R10_SNORM_PACK32: s = 4; break;
635 case VK_FORMAT_A2B10G10R10_USCALED_PACK32: s = 4; break;
636 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: s = 4; break;
637 case VK_FORMAT_A2B10G10R10_UINT_PACK32: s = 4; break;
638 case VK_FORMAT_A2B10G10R10_SINT_PACK32: s = 4; break;
639 case VK_FORMAT_R16_UNORM: s = 2; break;
640 case VK_FORMAT_R16_SNORM: s = 2; break;
641 case VK_FORMAT_R16_USCALED: s = 2; break;
642 case VK_FORMAT_R16_SSCALED: s = 2; break;
643 case VK_FORMAT_R16_UINT: s = 2; break;
644 case VK_FORMAT_R16_SINT: s = 2; break;
645 case VK_FORMAT_R16_SFLOAT: s = 2; break;
646 case VK_FORMAT_R16G16_UNORM: s = 4; break;
647 case VK_FORMAT_R16G16_SNORM: s = 4; break;
648 case VK_FORMAT_R16G16_USCALED: s = 4; break;
649 case VK_FORMAT_R16G16_SSCALED: s = 4; break;
650 case VK_FORMAT_R16G16_UINT: s = 4; break;
651 case VK_FORMAT_R16G16_SINT: s = 4; break;
652 case VK_FORMAT_R16G16_SFLOAT: s = 4; break;
653 case VK_FORMAT_R16G16B16_UNORM: s = 6; break;
654 case VK_FORMAT_R16G16B16_SNORM: s = 6; break;
655 case VK_FORMAT_R16G16B16_USCALED: s = 6; break;
656 case VK_FORMAT_R16G16B16_SSCALED: s = 6; break;
657 case VK_FORMAT_R16G16B16_UINT: s = 6; break;
658 case VK_FORMAT_R16G16B16_SINT: s = 6; break;
659 case VK_FORMAT_R16G16B16_SFLOAT: s = 6; break;
660 case VK_FORMAT_R16G16B16A16_UNORM: s = 8; break;
661 case VK_FORMAT_R16G16B16A16_SNORM: s = 8; break;
662 case VK_FORMAT_R16G16B16A16_USCALED: s = 8; break;
663 case VK_FORMAT_R16G16B16A16_SSCALED: s = 8; break;
664 case VK_FORMAT_R16G16B16A16_UINT: s = 8; break;
665 case VK_FORMAT_R16G16B16A16_SINT: s = 8; break;
666 case VK_FORMAT_R16G16B16A16_SFLOAT: s = 8; break;
667 case VK_FORMAT_R32_UINT: s = 4; break;
668 case VK_FORMAT_R32_SINT: s = 4; break;
669 case VK_FORMAT_R32_SFLOAT: s = 4; break;
670 case VK_FORMAT_R32G32_UINT: s = 8; break;
671 case VK_FORMAT_R32G32_SINT: s = 8; break;
672 case VK_FORMAT_R32G32_SFLOAT: s = 8; break;
673 case VK_FORMAT_R32G32B32_UINT: s = 12; break;
674 case VK_FORMAT_R32G32B32_SINT: s = 12; break;
675 case VK_FORMAT_R32G32B32_SFLOAT: s = 12; break;
676 case VK_FORMAT_R32G32B32A32_UINT: s = 16; break;
677 case VK_FORMAT_R32G32B32A32_SINT: s = 16; break;
678 case VK_FORMAT_R32G32B32A32_SFLOAT: s = 16; break;
679 case VK_FORMAT_R64_UINT: s = 8; break;
680 case VK_FORMAT_R64_SINT: s = 8; break;
681 case VK_FORMAT_R64_SFLOAT: s = 8; break;
682 case VK_FORMAT_R64G64_UINT: s = 16; break;
683 case VK_FORMAT_R64G64_SINT: s = 16; break;
684 case VK_FORMAT_R64G64_SFLOAT: s = 16; break;
685 case VK_FORMAT_R64G64B64_UINT: s = 24; break;
686 case VK_FORMAT_R64G64B64_SINT: s = 24; break;
687 case VK_FORMAT_R64G64B64_SFLOAT: s = 24; break;
688 case VK_FORMAT_R64G64B64A64_UINT: s = 32; break;
689 case VK_FORMAT_R64G64B64A64_SINT: s = 32; break;
690 case VK_FORMAT_R64G64B64A64_SFLOAT: s = 32; break;
691 case VK_FORMAT_B10G11R11_UFLOAT_PACK32: s = 4; break;
692 case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: s = 4; break;
693 case VK_FORMAT_D16_UNORM: s = 2; break;
694 case VK_FORMAT_X8_D24_UNORM_PACK32: s = 4; break;
695 case VK_FORMAT_D32_SFLOAT: s = 4; break;
696 case VK_FORMAT_S8_UINT: s = 1; break;
697 case VK_FORMAT_D16_UNORM_S8_UINT: s = 3; break;
698 case VK_FORMAT_D24_UNORM_S8_UINT: s = 4; break;
699 case VK_FORMAT_D32_SFLOAT_S8_UINT: s = 5; break;
571 case VK_FORMAT_R8_UNORM: s = 1; break;
572 case VK_FORMAT_R8_SNORM: s = 1; break;
573 case VK_FORMAT_R8_USCALED: s = 1; break;
574 case VK_FORMAT_R8_SSCALED: s = 1; break;
575 case VK_FORMAT_R8_UINT: s = 1; break;
576 case VK_FORMAT_R8_SINT: s = 1; break;
577 case VK_FORMAT_R8_SRGB: s = 1; break;
578 case VK_FORMAT_R8G8_UNORM: s = 2; break;
579 case VK_FORMAT_R8G8_SNORM: s = 2; break;
580 case VK_FORMAT_R8G8_USCALED: s = 2; break;
581 case VK_FORMAT_R8G8_SSCALED: s = 2; break;
582 case VK_FORMAT_R8G8_UINT: s = 2; break;
583 case VK_FORMAT_R8G8_SINT: s = 2; break;
584 case VK_FORMAT_R8G8_SRGB: s = 2; break;
585 case VK_FORMAT_R8G8B8_UNORM: s = 3; break;
586 case VK_FORMAT_R8G8B8_SNORM: s = 3; break;
587 case VK_FORMAT_R8G8B8_USCALED: s = 3; break;
588 case VK_FORMAT_R8G8B8_SSCALED: s = 3; break;
589 case VK_FORMAT_R8G8B8_UINT: s = 3; break;
590 case VK_FORMAT_R8G8B8_SINT: s = 3; break;
591 case VK_FORMAT_R8G8B8_SRGB: s = 3; break;
592 case VK_FORMAT_B8G8R8_UNORM: s = 3; break;
593 case VK_FORMAT_B8G8R8_SNORM: s = 3; break;
594 case VK_FORMAT_B8G8R8_USCALED: s = 3; break;
595 case VK_FORMAT_B8G8R8_SSCALED: s = 3; break;
596 case VK_FORMAT_B8G8R8_UINT: s = 3; break;
597 case VK_FORMAT_B8G8R8_SINT: s = 3; break;
598 case VK_FORMAT_B8G8R8_SRGB: s = 3; break;
599 case VK_FORMAT_R8G8B8A8_UNORM: s = 4; break;
600 case VK_FORMAT_R8G8B8A8_SNORM: s = 4; break;
601 case VK_FORMAT_R8G8B8A8_USCALED: s = 4; break;
602 case VK_FORMAT_R8G8B8A8_SSCALED: s = 4; break;
603 case VK_FORMAT_R8G8B8A8_UINT: s = 4; break;
604 case VK_FORMAT_R8G8B8A8_SINT: s = 4; break;
605 case VK_FORMAT_R8G8B8A8_SRGB: s = 4; break;
606 case VK_FORMAT_B8G8R8A8_UNORM: s = 4; break;
607 case VK_FORMAT_B8G8R8A8_SNORM: s = 4; break;
608 case VK_FORMAT_B8G8R8A8_USCALED: s = 4; break;
609 case VK_FORMAT_B8G8R8A8_SSCALED: s = 4; break;
610 case VK_FORMAT_B8G8R8A8_UINT: s = 4; break;
611 case VK_FORMAT_B8G8R8A8_SINT: s = 4; break;
612 case VK_FORMAT_B8G8R8A8_SRGB: s = 4; break;
613 case VK_FORMAT_A8B8G8R8_UNORM_PACK32: s = 4; break;
614 case VK_FORMAT_A8B8G8R8_SNORM_PACK32: s = 4; break;
615 case VK_FORMAT_A8B8G8R8_USCALED_PACK32: s = 4; break;
616 case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: s = 4; break;
617 case VK_FORMAT_A8B8G8R8_UINT_PACK32: s = 4; break;
618 case VK_FORMAT_A8B8G8R8_SINT_PACK32: s = 4; break;
619 case VK_FORMAT_A8B8G8R8_SRGB_PACK32: s = 4; break;
620 case VK_FORMAT_A2R10G10B10_UNORM_PACK32: s = 4; break;
621 case VK_FORMAT_A2R10G10B10_SNORM_PACK32: s = 4; break;
622 case VK_FORMAT_A2R10G10B10_USCALED_PACK32: s = 4; break;
623 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: s = 4; break;
624 case VK_FORMAT_A2R10G10B10_UINT_PACK32: s = 4; break;
625 case VK_FORMAT_A2R10G10B10_SINT_PACK32: s = 4; break;
626 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: s = 4; break;
627 case VK_FORMAT_A2B10G10R10_SNORM_PACK32: s = 4; break;
628 case VK_FORMAT_A2B10G10R10_USCALED_PACK32: s = 4; break;
629 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: s = 4; break;
630 case VK_FORMAT_A2B10G10R10_UINT_PACK32: s = 4; break;
631 case VK_FORMAT_A2B10G10R10_SINT_PACK32: s = 4; break;
632 case VK_FORMAT_R16_UNORM: s = 2; break;
633 case VK_FORMAT_R16_SNORM: s = 2; break;
634 case VK_FORMAT_R16_USCALED: s = 2; break;
635 case VK_FORMAT_R16_SSCALED: s = 2; break;
636 case VK_FORMAT_R16_UINT: s = 2; break;
637 case VK_FORMAT_R16_SINT: s = 2; break;
638 case VK_FORMAT_R16_SFLOAT: s = 2; break;
639 case VK_FORMAT_R16G16_UNORM: s = 4; break;
640 case VK_FORMAT_R16G16_SNORM: s = 4; break;
641 case VK_FORMAT_R16G16_USCALED: s = 4; break;
642 case VK_FORMAT_R16G16_SSCALED: s = 4; break;
643 case VK_FORMAT_R16G16_UINT: s = 4; break;
644 case VK_FORMAT_R16G16_SINT: s = 4; break;
645 case VK_FORMAT_R16G16_SFLOAT: s = 4; break;
646 case VK_FORMAT_R16G16B16_UNORM: s = 6; break;
647 case VK_FORMAT_R16G16B16_SNORM: s = 6; break;
648 case VK_FORMAT_R16G16B16_USCALED: s = 6; break;
649 case VK_FORMAT_R16G16B16_SSCALED: s = 6; break;
650 case VK_FORMAT_R16G16B16_UINT: s = 6; break;
651 case VK_FORMAT_R16G16B16_SINT: s = 6; break;
652 case VK_FORMAT_R16G16B16_SFLOAT: s = 6; break;
653 case VK_FORMAT_R16G16B16A16_UNORM: s = 8; break;
654 case VK_FORMAT_R16G16B16A16_SNORM: s = 8; break;
655 case VK_FORMAT_R16G16B16A16_USCALED: s = 8; break;
656 case VK_FORMAT_R16G16B16A16_SSCALED: s = 8; break;
657 case VK_FORMAT_R16G16B16A16_UINT: s = 8; break;
658 case VK_FORMAT_R16G16B16A16_SINT: s = 8; break;
659 case VK_FORMAT_R16G16B16A16_SFLOAT: s = 8; break;
660 case VK_FORMAT_R32_UINT: s = 4; break;
661 case VK_FORMAT_R32_SINT: s = 4; break;
662 case VK_FORMAT_R32_SFLOAT: s = 4; break;
663 case VK_FORMAT_R32G32_UINT: s = 8; break;
664 case VK_FORMAT_R32G32_SINT: s = 8; break;
665 case VK_FORMAT_R32G32_SFLOAT: s = 8; break;
666 case VK_FORMAT_R32G32B32_UINT: s = 12; break;
667 case VK_FORMAT_R32G32B32_SINT: s = 12; break;
668 case VK_FORMAT_R32G32B32_SFLOAT: s = 12; break;
669 case VK_FORMAT_R32G32B32A32_UINT: s = 16; break;
670 case VK_FORMAT_R32G32B32A32_SINT: s = 16; break;
671 case VK_FORMAT_R32G32B32A32_SFLOAT: s = 16; break;
672 case VK_FORMAT_R64_UINT: s = 8; break;
673 case VK_FORMAT_R64_SINT: s = 8; break;
674 case VK_FORMAT_R64_SFLOAT: s = 8; break;
675 case VK_FORMAT_R64G64_UINT: s = 16; break;
676 case VK_FORMAT_R64G64_SINT: s = 16; break;
677 case VK_FORMAT_R64G64_SFLOAT: s = 16; break;
678 case VK_FORMAT_R64G64B64_UINT: s = 24; break;
679 case VK_FORMAT_R64G64B64_SINT: s = 24; break;
680 case VK_FORMAT_R64G64B64_SFLOAT: s = 24; break;
681 case VK_FORMAT_R64G64B64A64_UINT: s = 32; break;
682 case VK_FORMAT_R64G64B64A64_SINT: s = 32; break;
683 case VK_FORMAT_R64G64B64A64_SFLOAT: s = 32; break;
684 case VK_FORMAT_B10G11R11_UFLOAT_PACK32: s = 4; break;
685 case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: s = 4; break;
686 case VK_FORMAT_D16_UNORM: s = 2; break;
687 case VK_FORMAT_X8_D24_UNORM_PACK32: s = 4; break;
688 case VK_FORMAT_D32_SFLOAT: s = 4; break;
689 case VK_FORMAT_S8_UINT: s = 1; break;
690 case VK_FORMAT_D16_UNORM_S8_UINT: s = 3; break;
691 case VK_FORMAT_D24_UNORM_S8_UINT: s = 4; break;
692 case VK_FORMAT_D32_SFLOAT_S8_UINT: s = 5; break;
693 }
694 return s;
695 };
696 [[nodiscard]]
697 constexpr VkFormat
698 format_storage_optimal_fallback(VkFormat f, const VkPhysicalDeviceFeatures &p)
699 {
700 VkFormat s = {};
701 auto storage_ext = [p]() -> bool {
702 return p.shaderStorageImageExtendedFormats;
703 };
704 switch(f) {
705 case VK_FORMAT_R8G8B8A8_UNORM:
706 case VK_FORMAT_R8G8B8A8_SNORM:
707 case VK_FORMAT_R8G8B8A8_UINT:
708 case VK_FORMAT_R8G8B8A8_SINT:
709 case VK_FORMAT_R16G16B16A16_UINT:
710 case VK_FORMAT_R16G16B16A16_SINT:
711 case VK_FORMAT_R16G16B16A16_SFLOAT:
712 case VK_FORMAT_R32_UINT:
713 case VK_FORMAT_R32_SINT:
714 case VK_FORMAT_R32_SFLOAT:
715 case VK_FORMAT_R32G32_UINT:
716 case VK_FORMAT_R32G32_SINT:
717 case VK_FORMAT_R32G32_SFLOAT:
718 case VK_FORMAT_R32G32B32A32_UINT:
719 case VK_FORMAT_R32G32B32A32_SINT:
720 case VK_FORMAT_R32G32B32A32_SFLOAT:
721 return f;
722 case VK_FORMAT_R8_UNORM:
723 case VK_FORMAT_R8_SNORM:
724 case VK_FORMAT_R8_UINT:
725 case VK_FORMAT_R8_SINT:
726 case VK_FORMAT_R8G8_UNORM:
727 case VK_FORMAT_R8G8_SNORM:
728 case VK_FORMAT_R8_USCALED:
729 case VK_FORMAT_R8_SSCALED:
730 case VK_FORMAT_R8G8_UINT:
731 case VK_FORMAT_R8G8_SINT:
732 case VK_FORMAT_R16_UNORM:
733 case VK_FORMAT_R16_SNORM:
734 case VK_FORMAT_R16_UINT:
735 case VK_FORMAT_R16_SINT:
736 case VK_FORMAT_R16_SFLOAT:
737 case VK_FORMAT_R16G16_UNORM:
738 case VK_FORMAT_R16G16_SNORM:
739 case VK_FORMAT_R16G16_UINT:
740 case VK_FORMAT_R16G16_SINT:
741 case VK_FORMAT_R16G16_SFLOAT:
742 case VK_FORMAT_R16G16B16A16_UNORM:
743 case VK_FORMAT_R16G16B16A16_SNORM:
744 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
745 return storage_ext() ? f : VkFormat();
746 case VK_FORMAT_R8G8_SRGB:
747 return storage_ext() ? VK_FORMAT_R8G8_UINT : VkFormat();
748 case VK_FORMAT_R8_SRGB:
749 return storage_ext() ? VK_FORMAT_R8_UINT : VkFormat();
750 case VK_FORMAT_R8G8B8A8_SRGB:
751 return VK_FORMAT_R8G8B8A8_UINT;
752 case VK_FORMAT_B8G8R8A8_UNORM:
753 return VK_FORMAT_R8G8B8A8_UNORM;
754 case VK_FORMAT_B8G8R8A8_SNORM:
755 return VK_FORMAT_R8G8B8A8_SNORM;
756 case VK_FORMAT_B8G8R8A8_UINT:
757 return VK_FORMAT_R8G8B8A8_UINT;
758 case VK_FORMAT_B8G8R8A8_SINT:
759 return VK_FORMAT_R8G8B8A8_SINT;
760 case VK_FORMAT_B8G8R8A8_SRGB:
761 return VK_FORMAT_R8G8B8A8_UINT;
762 default: break;
763 }
764 return s;
765 }
766 [[nodiscard]]
767 constexpr VkFormat format_sampled_optimal_fallback(VkFormat f) {
768 VkFormat s = {};
769 switch(f) {
770 default: break;
771 case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
772 case VK_FORMAT_R5G6B5_UNORM_PACK16:
773 case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
774 case VK_FORMAT_R8_UNORM:
775 case VK_FORMAT_R8_SNORM:
776 case VK_FORMAT_R8_UINT:
777 case VK_FORMAT_R8_SINT:
778 case VK_FORMAT_R8G8_UNORM:
779 case VK_FORMAT_R8G8_SNORM:
780 case VK_FORMAT_R8G8_UINT:
781 case VK_FORMAT_R8G8_SINT:
782 case VK_FORMAT_R8G8B8A8_UNORM:
783 case VK_FORMAT_R8G8B8A8_SNORM:
784 case VK_FORMAT_R8G8B8A8_UINT:
785 case VK_FORMAT_R8G8B8A8_SINT:
786 case VK_FORMAT_R8G8B8A8_SRGB:
787 case VK_FORMAT_B8G8R8A8_UNORM:
788 case VK_FORMAT_B8G8R8A8_SRGB:
789 case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
790 case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
791 case VK_FORMAT_A8B8G8R8_UINT_PACK32:
792 case VK_FORMAT_A8B8G8R8_SINT_PACK32:
793 case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
794 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
795 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
796 case VK_FORMAT_R16_UINT:
797 case VK_FORMAT_R16_SINT:
798 case VK_FORMAT_R16_SFLOAT:
799 case VK_FORMAT_R16G16_UINT:
800 case VK_FORMAT_R16G16_SINT:
801 case VK_FORMAT_R16G16_SFLOAT:
802 case VK_FORMAT_R16G16B16A16_UINT:
803 case VK_FORMAT_R16G16B16A16_SINT:
804 case VK_FORMAT_R16G16B16A16_SFLOAT:
805 case VK_FORMAT_R32_UINT:
806 case VK_FORMAT_R32_SINT:
807 case VK_FORMAT_R32_SFLOAT:
808 case VK_FORMAT_R32G32_UINT:
809 case VK_FORMAT_R32G32_SINT:
810 case VK_FORMAT_R32G32_SFLOAT:
811 case VK_FORMAT_R32G32B32A32_UINT:
812 case VK_FORMAT_R32G32B32A32_SINT:
813 case VK_FORMAT_R32G32B32A32_SFLOAT:
814 case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
815 case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
816 case VK_FORMAT_D16_UNORM:
817 case VK_FORMAT_D32_SFLOAT:
818 return f;
819 case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
820 return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
821 case VK_FORMAT_B5G6R5_UNORM_PACK16:
822 return VK_FORMAT_R5G6B5_UNORM_PACK16;
823 case VK_FORMAT_R8_SRGB:
824 return VK_FORMAT_R8_UINT;
825 case VK_FORMAT_R8G8_SRGB:
826 return VK_FORMAT_R8G8_UINT;
827 case VK_FORMAT_B8G8R8A8_UINT:
828 return VK_FORMAT_B8G8R8A8_SRGB;
829 case VK_FORMAT_B8G8R8A8_SINT:
830 return VK_FORMAT_R8G8B8A8_SINT;
831 case VK_FORMAT_A2R10G10B10_UINT_PACK32:
832 return VK_FORMAT_A2B10G10R10_UINT_PACK32;
700 833 } }
701 834 return s; return s;
702 835 }; };
File libs/vkw/src/command_buffer.cpp deleted (index 4ebaa4c..0000000)
1 /**
2 * Copyright 2020 Damir Valiev
3 *
4 * This file is part of JEN framework.
5 *
6 * JEN framework is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this library. If not, see <https://www.gnu.org/licenses/>
18 */
19 #include <vkw/command_buffer.h>
20
21 void vkw::CmdBuffer::cmd_gen_mipmaps(const MipmapGetInfo &info)
22 {
23 jassert(info.level_count > 1, "no mips to generate");
24
25 // From begin layout to TRANSFER_SRC
26 BarrierImMem barrier_to_src; {
27 barrier_to_src.access_change.src = info.access_change.src;
28 barrier_to_src.access_change.dst = AccessFlag::TRANSFER_READ;
29 barrier_to_src.layout_change.src = info.layout_change.src;
30 barrier_to_src.layout_change.dst = ImLayout::TRANSFER_SRC;
31 barrier_to_src.queueFamily_change.set_both(VK_QUEUE_FAMILY_IGNORED);
32 barrier_to_src.image = info.image;
33 barrier_to_src.range = {info.aspect, info.layer_count, 1};
34 }
35 StageMaskChange stages_to_src; {
36 stages_to_src.src = info.stage_change.src;
37 stages_to_src.dst = StageFlag::TRANSFER;
38 }
39 // From TRANSFER_SRC to TRANSFER_DST
40 BarrierImMem barrier_to_dst = barrier_to_src; {
41 barrier_to_dst.access_change.dst = AccessFlag::TRANSFER_WRITE;
42 barrier_to_dst.layout_change.dst = ImLayout::TRANSFER_DST;
43 barrier_to_dst.range.mip_levels_offset = 1;
44 barrier_to_dst.range.mip_levels_count = info.level_count - 1;
45 }
46 auto stages_to_dst = StageMaskChange::both(StageFlag::TRANSFER);
47
48 // transition main image without mips to TRANSFER_SRC
49 cmd_barriers(stages_to_src, {}, {}, barrier_to_src);
50 // transition mips to TRANSFER_DST
51 cmd_barriers(stages_to_dst, {}, {}, barrier_to_dst);
52
53 stages_to_src.src = stages_to_dst.dst;
54 barrier_to_src.access_change.src = barrier_to_dst.access_change.dst;
55 barrier_to_src.layout_change.src = barrier_to_dst.layout_change.dst;
56
57 BlitInfo blit; {
58 blit.srcSubresource.aspectMask = ImAspect::COLOR;
59 blit.srcSubresource.baseArrayLayer = 0;
60 blit.srcSubresource.layerCount = info.layer_count;
61 blit.srcOffsets[0] = blit.dstOffsets[0] = {};
62 blit.dstOffsets[1] = { int32_t(info.extent.width),
63 int32_t(info.extent.height),
64 int32_t(info.extent.depth) };
65 blit.dstSubresource = blit.srcSubresource;
66 }
67
68 ImLayoutChange blit_layouts; {
69 blit_layouts.src = ImLayout::TRANSFER_SRC;
70 blit_layouts.dst = ImLayout::TRANSFER_DST;
71 }
72
73
74 for (uint32_t i = 1; i < info.level_count; ++i)
75 {
76 blit.srcSubresource.mipLevel = i - 1;
77 blit.dstSubresource.mipLevel = i;
78 auto &src_offset = blit.srcOffsets[1];
79 auto &dst_offset = blit.dstOffsets[1];
80
81 src_offset = dst_offset;
82 if (dst_offset.x > 1)
83 dst_offset.x /= 2;
84 if (dst_offset.y > 1)
85 dst_offset.y /= 2;
86
87 cmd_blit({info.image, info.image}, blit_layouts, blit, info.filter);
88
89 // transition mip from TRANSFER_DST to TRANSFER_SRC
90 barrier_to_src.range.mip_levels_offset = i;
91 cmd_barriers(stages_to_src, {}, {}, barrier_to_src);
92 }
93
94 // From TRANSFER_SRC to final layout
95 BarrierImMem barrier_fin = barrier_to_src; {
96 barrier_fin.access_change.move(info.access_change.dst);
97 barrier_fin.layout_change.move(info.layout_change.dst);
98 barrier_fin.range.mip_levels_offset = 0;
99 barrier_fin.range.mip_levels_count = info.level_count;
100 }
101 auto stages_fin = stages_to_dst.move_built(info.stage_change.dst);
102 cmd_barriers(stages_fin, {}, {}, barrier_fin);
103 }
File libs/vkw/src/result.cpp deleted (index befc6b9..0000000)
1 /**
2 * Copyright 2020 Damir Valiev
3 *
4 * This file is part of JEN framework.
5 *
6 * JEN framework is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this library. If not, see <https://www.gnu.org/licenses/>
18 */
19 #include "../include/vkw/result.h"
20
21 namespace vkw
22 {
23 const char* to_string(VkResult result)
24 {
25 switch (result)
26 {
27 #define STR(r) case VK_ ##r: return #r
28 STR(SUCCESS);
29 STR(NOT_READY);
30 STR(TIMEOUT);
31 STR(EVENT_SET);
32 STR(EVENT_RESET);
33 STR(INCOMPLETE);
34 STR(ERROR_OUT_OF_HOST_MEMORY);
35 STR(ERROR_OUT_OF_DEVICE_MEMORY);
36 STR(ERROR_INITIALIZATION_FAILED);
37 STR(ERROR_DEVICE_LOST);
38 STR(ERROR_MEMORY_MAP_FAILED);
39 STR(ERROR_LAYER_NOT_PRESENT);
40 STR(ERROR_EXTENSION_NOT_PRESENT);
41 STR(ERROR_FEATURE_NOT_PRESENT);
42 STR(ERROR_INCOMPATIBLE_DRIVER);
43 STR(ERROR_TOO_MANY_OBJECTS);
44 STR(ERROR_FORMAT_NOT_SUPPORTED);
45 STR(ERROR_FRAGMENTED_POOL);
46 STR(ERROR_OUT_OF_POOL_MEMORY);
47 STR(ERROR_INVALID_EXTERNAL_HANDLE);
48 STR(ERROR_SURFACE_LOST_KHR);
49 STR(ERROR_NATIVE_WINDOW_IN_USE_KHR);
50 STR(SUBOPTIMAL_KHR);
51 STR(ERROR_OUT_OF_DATE_KHR);
52 STR(ERROR_INCOMPATIBLE_DISPLAY_KHR);
53 STR(ERROR_VALIDATION_FAILED_EXT);
54 STR(ERROR_INVALID_SHADER_NV);
55 STR(ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
56 STR(ERROR_FRAGMENTATION_EXT);
57 STR(ERROR_NOT_PERMITTED_EXT);
58 STR(ERROR_INVALID_DEVICE_ADDRESS_EXT);
59 STR(ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT);
60 STR(RESULT_RANGE_SIZE);
61 STR(RESULT_MAX_ENUM);
62 STR(ERROR_INCOMPATIBLE_VERSION_KHR);
63 STR(ERROR_UNKNOWN);
64 STR(THREAD_IDLE_KHR);
65 STR(THREAD_DONE_KHR);
66 STR(OPERATION_NOT_DEFERRED_KHR);
67 STR(OPERATION_DEFERRED_KHR);
68 STR(PIPELINE_COMPILE_REQUIRED_EXT);
69 #undef STR
70 }
71 return "UNKNOWN ERROR";
72 }
73
74 const char* to_string(Result result)
75 {
76 switch (result)
77 {
78 #define STR(r) case r: return #r
79 STR(ERROR_FILE_OPENING);
80 STR(ERROR_DEVICE_MEMORY_TYPE_NOT_FOUND);
81 STR(ERROR_PHYSICAL_DEVICE_NOT_SUITABLE);
82 STR(ERROR_INVALID_USAGE);
83 STR(ERROR_FONT);
84 STR(ERROR_JRF);
85 STR(ERROR_WRONG_RESOURCE_FORMAT);
86 STR(ERROR_NO_OBJECTS_LEFT);
87 STR(ERROR_WINDOW_INITIALIZATION);
88 #undef STR
89 }
90 return to_string(result.operator VkResult());
91 }
92 }
File libs/vkw/src/vkw.cpp added (mode: 100644) (index 0000000..5d2a43a)
1 /**
2 * Copyright 2020 Damir Valiev
3 *
4 * This file is part of JEN framework.
5 *
6 * JEN framework is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this library. If not, see <https://www.gnu.org/licenses/>
18 */
19 #include <vkw/command_buffer.h>
20
21 const char* vkw::to_string(VkResult result) {
22 switch (result) {
23 #define STR(r) case VK_ ##r: return #r
24 STR(SUCCESS);
25 STR(NOT_READY);
26 STR(TIMEOUT);
27 STR(EVENT_SET);
28 STR(EVENT_RESET);
29 STR(INCOMPLETE);
30 STR(ERROR_OUT_OF_HOST_MEMORY);
31 STR(ERROR_OUT_OF_DEVICE_MEMORY);
32 STR(ERROR_INITIALIZATION_FAILED);
33 STR(ERROR_DEVICE_LOST);
34 STR(ERROR_MEMORY_MAP_FAILED);
35 STR(ERROR_LAYER_NOT_PRESENT);
36 STR(ERROR_EXTENSION_NOT_PRESENT);
37 STR(ERROR_FEATURE_NOT_PRESENT);
38 STR(ERROR_INCOMPATIBLE_DRIVER);
39 STR(ERROR_TOO_MANY_OBJECTS);
40 STR(ERROR_FORMAT_NOT_SUPPORTED);
41 STR(ERROR_FRAGMENTED_POOL);
42 STR(ERROR_OUT_OF_POOL_MEMORY);
43 STR(ERROR_INVALID_EXTERNAL_HANDLE);
44 STR(ERROR_SURFACE_LOST_KHR);
45 STR(ERROR_NATIVE_WINDOW_IN_USE_KHR);
46 STR(SUBOPTIMAL_KHR);
47 STR(ERROR_OUT_OF_DATE_KHR);
48 STR(ERROR_INCOMPATIBLE_DISPLAY_KHR);
49 STR(ERROR_VALIDATION_FAILED_EXT);
50 STR(ERROR_INVALID_SHADER_NV);
51 STR(ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
52 STR(ERROR_FRAGMENTATION_EXT);
53 STR(ERROR_NOT_PERMITTED_EXT);
54 STR(ERROR_INVALID_DEVICE_ADDRESS_EXT);
55 STR(ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT);
56 STR(RESULT_RANGE_SIZE);
57 STR(RESULT_MAX_ENUM);
58 STR(ERROR_INCOMPATIBLE_VERSION_KHR);
59 STR(ERROR_UNKNOWN);
60 STR(THREAD_IDLE_KHR);
61 STR(THREAD_DONE_KHR);
62 STR(OPERATION_NOT_DEFERRED_KHR);
63 STR(OPERATION_DEFERRED_KHR);
64 STR(PIPELINE_COMPILE_REQUIRED_EXT);
65 #undef STR
66 }
67 return "UNKNOWN ERROR";
68 }
69 const char* vkw::to_string(Result result) {
70 switch (result) {
71 #define STR(r) case r: return #r
72 STR(ERROR_FILE_OPENING);
73 STR(ERROR_DEVICE_MEMORY_TYPE_NOT_FOUND);
74 STR(ERROR_PHYSICAL_DEVICE_NOT_SUITABLE);
75 STR(ERROR_INVALID_USAGE);
76 STR(ERROR_FONT);
77 STR(ERROR_JRF);
78 STR(ERROR_WRONG_RESOURCE_FORMAT);
79 STR(ERROR_NO_OBJECTS_LEFT);
80 STR(ERROR_WINDOW_INITIALIZATION);
81 #undef STR
82 }
83 return to_string(result.operator VkResult());
84 }
85 void vkw::CmdBuffer::cmd_gen_mipmaps(const MipmapGetInfo &info) {
86 jassert(info.level_count > 1, "no mips to generate");
87 // From begin layout to TRANSFER_SRC
88 BarrierImMem barrier_to_src = {
89 .access_change = {info.access_change.src, AccessFlag::TRANSFER_READ},
90 .layout_change = {info.layout_change.src, ImLayout::TRANSFER_SRC },
91 .queue_family_change = {VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED},
92 .image = info.image,
93 .range = {info.aspect, info.layer_count, 1},
94 };
95 StageMaskChange stages_to_src = {info.stage_change.src, StageFlag::TRANSFER};
96 // From TRANSFER_SRC to TRANSFER_DST
97 BarrierImMem barrier_to_dst = barrier_to_src; {
98 barrier_to_dst.access_change.dst = AccessFlag::TRANSFER_WRITE;
99 barrier_to_dst.layout_change.dst = ImLayout::TRANSFER_DST;
100 barrier_to_dst.range.mip_levels_offset = 1;
101 barrier_to_dst.range.mip_levels_count = info.level_count - 1;
102 }
103 auto stages_to_dst = StageMaskChange::both(StageFlag::TRANSFER);
104
105 // transition main image without mips to TRANSFER_SRC
106 cmd_barriers(stages_to_src, {}, {}, barrier_to_src);
107 // transition mips to TRANSFER_DST
108 cmd_barriers(stages_to_dst, {}, {}, barrier_to_dst);
109
110 stages_to_src.src = stages_to_dst.dst;
111 barrier_to_src.access_change.src = barrier_to_dst.access_change.dst;
112 barrier_to_src.layout_change.src = barrier_to_dst.layout_change.dst;
113
114 BlitInfo blit = {
115 .srcSubresource = {
116 .aspectMask = ImAspect::COLOR,
117 .baseArrayLayer = 0,
118 .layerCount = info.layer_count,
119 },
120 .srcOffsets[0] = blit.dstOffsets[0] = {},
121 .dstOffsets[1] = {
122 int32_t(info.extent.width),
123 int32_t(info.extent.height),
124 int32_t(info.extent.depth)
125 },
126 .dstSubresource = blit.srcSubresource,
127 };
128 ImLayoutChange blit_layouts ={ImLayout::TRANSFER_SRC, ImLayout::TRANSFER_DST};
129
130 for (uint32_t i = 1; i < info.level_count; ++i)
131 {
132 blit.srcSubresource.mipLevel = i - 1;
133 blit.dstSubresource.mipLevel = i;
134 auto &src_offset = blit.srcOffsets[1];
135 auto &dst_offset = blit.dstOffsets[1];
136
137 src_offset = dst_offset;
138 if (dst_offset.x > 1)
139 dst_offset.x /= 2;
140 if (dst_offset.y > 1)
141 dst_offset.y /= 2;
142
143 cmd_blit({info.image, info.image}, blit_layouts, blit, info.filter);
144
145 // transition mip from TRANSFER_DST to TRANSFER_SRC
146 barrier_to_src.range.mip_levels_offset = i;
147 cmd_barriers(stages_to_src, {}, {}, barrier_to_src);
148 }
149
150 // From TRANSFER_SRC to final layout
151 BarrierImMem barrier_fin = barrier_to_src; {
152 barrier_fin.access_change.move(info.access_change.dst);
153 barrier_fin.layout_change.move(info.layout_change.dst);
154 barrier_fin.range.mip_levels_offset = 0;
155 barrier_fin.range.mip_levels_count = info.level_count;
156 }
157 auto stages_fin = stages_to_dst.move_built(info.stage_change.dst);
158 cmd_barriers(stages_fin, {}, {}, barrier_fin);
159 }
160 [[nodiscard]] vkw::Result vkw::
161 get_devices(Instance in, DevicesPhysical *p_dst)
162 {
163 uint32_t count;
164 VkResult result = vkEnumeratePhysicalDevices(in.p_vk, &count, nullptr);
165 if (result != VK_SUCCESS)
166 return result;
167 if (count == 0) {
168 fprintf(stderr, "Failed to find GPUs with Vulkan support!\n");
169 return result;
170 }
171
172 if (not p_dst->init(count))
173 return VK_ERROR_OUT_OF_HOST_MEMORY;
174
175 result = vkEnumeratePhysicalDevices(in.p_vk, &count, &p_dst->first().p_vk);
176 if (result != VK_SUCCESS)
177 p_dst->destroy();
178 return result;
179 }
180 [[nodiscard]] vkw::Result vkw::DevicePhysical::
181 check_extension_support(Strings extensions) {
182 uint32_t count;
183 vkEnumerateDeviceExtensionProperties(p_vk, {}, &count, {});
184 jl::rarray<VkExtensionProperties> dev_exts;
185 if (not dev_exts.init(count))
186 return VK_ERROR_OUT_OF_HOST_MEMORY;
187 vkEnumerateDeviceExtensionProperties(p_vk, {}, &count, dev_exts.begin());
188 for (auto &extension : extensions) {
189 for (auto ex : dev_exts)
190 if (strcmp(ex.extensionName, extension) == 0)
191 goto CONTINUE;
192 dev_exts.destroy();
193 fprintf(stderr, "Extension %s is not presented in physical device.\n",
194 extension);
195 return ERROR_PHYSICAL_DEVICE_NOT_SUITABLE;
196 CONTINUE:;
197 }
198 dev_exts.destroy();
199 return VK_SUCCESS;
200 }
201 [[nodiscard]] vkw::Result vkw::DevicePhysical::
202 surface_formats(Surface s, vkw::Array<vkw::SurfaceFormat> *p_dst) {
203 Result res;
204 uint32_t count;
205 res = vkGetPhysicalDeviceSurfaceFormatsKHR(*this, s, &count, {});
206 if (res != VK_SUCCESS)
207 return res;
208 if (count == 0) {
209 p_dst->init();
210 return res;
211 }
212 if (not p_dst->init(count))
213 return VK_ERROR_OUT_OF_HOST_MEMORY;
214 res = vkGetPhysicalDeviceSurfaceFormatsKHR(*this, s, &count,
215 &p_dst->first().vk());
216 if (res != VK_SUCCESS)
217 p_dst->destroy();
218 return res;
219 }
220 [[nodiscard]] vkw::Result vkw::DevicePhysical::
221 surface_present_modes(Surface s, PresentModes *p_dst) {
222 Result res;
223 uint32_t count;
224 res = vkGetPhysicalDeviceSurfacePresentModesKHR(*this, s, &count, {});
225 if (res != VK_SUCCESS)
226 return res;
227 if (not p_dst->init(count))
228 return VK_ERROR_OUT_OF_HOST_MEMORY;
229 res = vkGetPhysicalDeviceSurfacePresentModesKHR(*this, s, &count,
230 reinterpret_cast<VkPresentModeKHR*>(p_dst->begin()));
231 if (res != VK_SUCCESS)
232 p_dst->destroy();
233 return res;
234 }
235 [[nodiscard]] bool vkw::DevicePhysical::
236 select_depth_format(VkFormat preffered, VkFormat *p_dst) {
237 VkFormat formats[5] = {
238 VK_FORMAT_D32_SFLOAT,
239 VK_FORMAT_D32_SFLOAT_S8_UINT,
240 VK_FORMAT_D24_UNORM_S8_UINT,
241 VK_FORMAT_D16_UNORM,
242 VK_FORMAT_D16_UNORM_S8_UINT
243 };
244 if (format_properties(preffered).optimalTilingFeatures
245 & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
246 return *p_dst = preffered, true;
247 for (size_t i = 0; i < 5; ++i)
248 if (format_properties(formats[i]).optimalTilingFeatures
249 & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
250 return *p_dst = formats[i], true;
251 fprintf(stderr, "Cannot find supported depth format for physical device.\n");
252 return false;
253 }
File src/compute/CMakeLists.txt changed (mode: 100644) (index b5d4da3..58ff438)
... ... cmake_minimum_required(VERSION 3.5)
19 19 add_library(JEN_COMPUTE STATIC compute.cpp cmd_unit.cpp) add_library(JEN_COMPUTE STATIC compute.cpp cmd_unit.cpp)
20 20 target_link_libraries(JEN_COMPUTE target_link_libraries(JEN_COMPUTE
21 21 PUBLIC ${Vulkan_LIBRARIES} PUBLIC ${Vulkan_LIBRARIES}
22 PRIVATE VKW JLIB ATLAS JMATH
22 PRIVATE VKW JLIB JRF ATLAS JMATH
23 23 ) )
24 24 target_include_directories(JEN_COMPUTE PRIVATE ${JEN_INCLUDE_DIR}) target_include_directories(JEN_COMPUTE PRIVATE ${JEN_INCLUDE_DIR})
25 25 target_compile_definitions(JEN_COMPUTE ${JEN_DEFINES}) target_compile_definitions(JEN_COMPUTE ${JEN_DEFINES})
File src/compute/cmd_unit.cpp changed (mode: 100644) (index e9a5c55..26655d9)
... ... transitionLayout(Image *p, vkw::CmdBuffer *p_cmd,
34 34 barrier.access_change.dst = vkw::AccessMask(); barrier.access_change.dst = vkw::AccessMask();
35 35 barrier.layout_change.src = p->layout; barrier.layout_change.src = p->layout;
36 36 barrier.layout_change.dst = layout; barrier.layout_change.dst = layout;
37 barrier.queueFamily_change.set_both(VK_QUEUE_FAMILY_IGNORED);
37 barrier.queue_family_change.set_both(VK_QUEUE_FAMILY_IGNORED);
38 38 barrier.image = p->image.image; barrier.image = p->image.image;
39 39 barrier.range.mip_levels_offset = 0; barrier.range.mip_levels_offset = 0;
40 40 barrier.range.mip_levels_count = p->mip_level_count; barrier.range.mip_levels_count = p->mip_level_count;
 
... ... transitionLayout(Image *p, vkw::CmdBuffer *p_cmd,
44 44 } }
45 45 p_cmd->cmd_barriers(stages, {}, {}, barrier); p_cmd->cmd_barriers(stages, {}, {}, barrier);
46 46 } }
47
48 47 void check_transfer(const jen::DeviceBufferPart &part, void check_transfer(const jen::DeviceBufferPart &part,
49 48 vkw::DeviceSize offset, vkw::DeviceSize size) { vkw::DeviceSize offset, vkw::DeviceSize size) {
50 49 jassert(offset + size <= part.size(), "region exceeds buffer"); jassert(offset + size <= part.size(), "region exceeds buffer");
File src/compute/compute.cpp changed (mode: 100644) (index d04b330..e1dad2e)
... ... create_bindings(BindingCreateInfos infos, VkFormat *p_formats,
178 178 return VK_SUCCESS; return VK_SUCCESS;
179 179 } }
180 180
181 [[nodiscard]] Result
181 [[nodiscard]] VkFormat static
182 convert_format(Device *p_d, jrf::Image::Format format) {
183 auto is_suitable = [p_d](VkFormat f) {
184 auto p = p_d->physical.format_properties(f);
185 return p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
186 };
187 auto storage_ext = [p_d]() -> bool {
188 return p_d->features.shaderStorageImageExtendedFormats;
189 };
190 switch (format) {
191 case jrf::Image::Format::R_8:
192 return storage_ext() ? VK_FORMAT_R8_UINT : VkFormat{};
193 case jrf::Image::Format::RG_8:
194 return storage_ext() ? VK_FORMAT_R8G8_UINT : VkFormat{};
195 case jrf::Image::Format::RGB_8:
196 if (is_suitable(VK_FORMAT_R8G8B8_UINT)) return VK_FORMAT_R8G8B8_UINT;
197 else return {};
198 case jrf::Image::Format::RGBA_8:
199 return VK_FORMAT_R8G8B8A8_UINT;
200 case jrf::Image::Format::RGB_8_sRGB:
201 return is_suitable(VK_FORMAT_R8G8B8_SRGB)
202 ? VK_FORMAT_R8G8B8_SRGB : is_suitable(VK_FORMAT_R8G8B8_UINT)
203 ? VK_FORMAT_R8G8B8_UINT : VkFormat();
204 case jrf::Image::Format::RGBA_8_sRGB:
205 return is_suitable(VK_FORMAT_R8G8B8A8_SRGB)
206 ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UINT;
207 }
208 return VK_FORMAT_UNDEFINED;
209 }
210 [[nodiscard]] Result static
182 211 init(Device *p_d, Image *p, const ImageCreateInfo &info) { init(Device *p_d, Image *p, const ImageCreateInfo &info) {
212 VkFormat format = convert_format(p_d, info.format);
213 if (format == VK_FORMAT_UNDEFINED)
214 return VK_ERROR_FORMAT_NOT_SUPPORTED;
215
183 216 GpuImageInfo ii; { GpuImageInfo ii; {
184 217 ii.extent = {info.extent.x, info.extent.y, info.extent.z}; ii.extent = {info.extent.x, info.extent.y, info.extent.z};
185 218 ii.layer_count = info.layer_count; ii.layer_count = info.layer_count;
186 219 ii.mip_level_count = info.mip_level_count; ii.mip_level_count = info.mip_level_count;
187 ii.format = info.format;
220 ii.format = format;
188 221 ii.type = info.type; ii.type = info.type;
189 222 ii.samples = info.samples; ii.samples = info.samples;
190 223 ii.usage = info.usage; ii.usage = info.usage;
 
... ... init(Device *p_d, Image *p, const ImageCreateInfo &info) {
209 242 if (res != VK_SUCCESS) if (res != VK_SUCCESS)
210 243 p->image.destroy(p_d); p->image.destroy(p_d);
211 244
212 p->format = info.format;
245 p->format = format;
213 246 p->layout = vkw::ImLayout::UNDEFINED; p->layout = vkw::ImLayout::UNDEFINED;
214 247 p->mip_level_count = info.mip_level_count; p->mip_level_count = info.mip_level_count;
215 248 p->layer_count = info.layer_count; p->layer_count = info.layer_count;
File src/device/device.cpp changed (mode: 100644) (index 88e5256..4772ccd)
... ... DONE:
281 281 } }
282 282
283 283 vkGetPhysicalDeviceMemoryProperties(physical, &memory_properties); vkGetPhysicalDeviceMemoryProperties(physical, &memory_properties);
284 vkGetPhysicalDeviceFeatures(physical, &features);
284 285
285 286 buffer_allocator.p = nullptr; buffer_allocator.p = nullptr;
286 287 memory_allocator.p = nullptr; memory_allocator.p = nullptr;
File src/device/device.h changed (mode: 100644) (index ea0e268..6021dd7)
... ... struct jen::Device
90 90 uint32_t unique_queue_count; uint32_t unique_queue_count;
91 91 QueueIndices queue_indices; QueueIndices queue_indices;
92 92 VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;
93 VkPhysicalDeviceFeatures features;
93 94 vkw::DeviceMemProps memory_properties; vkw::DeviceMemProps memory_properties;
94 95 DeviceBufferAllocator buffer_allocator; DeviceBufferAllocator buffer_allocator;
95 96 DeviceMemoryAllocator memory_allocator; DeviceMemoryAllocator memory_allocator;
File src/graphics/draw_stages/attachment.cpp changed (mode: 100644) (index a1c812b..81061b0)
... ... transitionLayout(Device *p_dd, CmdData *p_cmds, const CreateInfo &info)
38 38 barrier.access_change.src = vkw::AccessMask(); barrier.access_change.src = vkw::AccessMask();
39 39 barrier.access_change.dst = info.access_consumer; barrier.access_change.dst = info.access_consumer;
40 40 barrier.layout_change.src = vkw::ImLayout::UNDEFINED; barrier.layout_change.src = vkw::ImLayout::UNDEFINED;
41 barrier.queueFamily_change.set_both(VK_QUEUE_FAMILY_IGNORED);
41 barrier.queue_family_change.set_both(VK_QUEUE_FAMILY_IGNORED);
42 42 barrier.image = gpu_image.image; barrier.image = gpu_image.image;
43 43 barrier.range.mip_levels_offset = 0; barrier.range.mip_levels_offset = 0;
44 44 barrier.range.mip_levels_count = info.mip_level_count; barrier.range.mip_levels_count = info.mip_level_count;
File src/graphics/draw_stages/pass_depthcube.cpp changed (mode: 100644) (index aefd74e..d29e085)
... ... init(Device *p_dd, CmdData *p_cmds, const GraphicsSettings &options)
69 69 .stage_consumer = vkw::StageFlag::BOTTOM_OF_PIPE, .stage_consumer = vkw::StageFlag::BOTTOM_OF_PIPE,
70 70 }; };
71 71 if (not p_dd->physical if (not p_dd->physical
72 .depth_format_supported(&att_info.format, VK_FORMAT_D32_SFLOAT))
72 .select_depth_format(VK_FORMAT_D32_SFLOAT, &att_info.format))
73 73 return VK_ERROR_FORMAT_NOT_SUPPORTED; return VK_ERROR_FORMAT_NOT_SUPPORTED;
74 74 res = att_depth.init(p_dd, p_cmds, att_info); res = att_depth.init(p_dd, p_cmds, att_info);
75 75 if (res != VK_SUCCESS) if (res != VK_SUCCESS)
 
... ... create_pipeline_layout(vkw::Device d, vkw::DescrLayouts sl,
103 103 [[nodiscard]] jen::Result [[nodiscard]] jen::Result
104 104 create_pipeline(jen::Device *p_d, vkw::RenderPass rpass, create_pipeline(jen::Device *p_d, vkw::RenderPass rpass,
105 105 jen::vk::PipelineShadowOmni *p_data, jen::vk::PipelineShadowOmni *p_data,
106 const jen::GraphicsSettings &options)
107 {
106 const jen::GraphicsSettings &options) {
108 107 using namespace vkw; using namespace vkw;
109 108 jl::array<PipelineShaderStage, 3> shaders = { PipelineShaderStage jl::array<PipelineShaderStage, 3> shaders = { PipelineShaderStage
110 109 { ShaderStage::VERTEX, p_data->shaders[0] }, { ShaderStage::VERTEX, p_data->shaders[0] },
 
... ... destroy(Device *p_d, vkw::DescrPool pool) {
264 263 } }
265 264 [[nodiscard]] jen::Result [[nodiscard]] jen::Result
266 265 create_pipeline_debug(jen::Device *p_d, vkw::RenderPass rp, vkw::Extent2D ext, create_pipeline_debug(jen::Device *p_d, vkw::RenderPass rp, vkw::Extent2D ext,
267 jen::vk::PipelineDebugDepthCube *p_data)
268 {
266 jen::vk::PipelineDebugDepthCube *p_data) {
269 267 using namespace vkw; using namespace vkw;
270 268 jl::array<PipelineShaderStage, 2> shaderStages = { jl::array<PipelineShaderStage, 2> shaderStages = {
271 269 vkw::PipelineShaderStage::vertex(p_data->shaders[0]), vkw::PipelineShaderStage::vertex(p_data->shaders[0]),
 
... ... CS:
356 354 return res; return res;
357 355 } }
358 356 void jen::vk::PipelineDebugDepthCube:: void jen::vk::PipelineDebugDepthCube::
359 destroy(vkw::Device device)
360 {
357 destroy(vkw::Device device) {
361 358 pipeline.destroy(device); pipeline.destroy(device);
362 359 layout.destroy(device); layout.destroy(device);
363 360 shaders.destroy(device); shaders.destroy(device);
File src/graphics/draw_stages/pass_main.cpp changed (mode: 100644) (index 6ce4204..ef2df70)
18 18 */ */
19 19 #include "pass_main.h" #include "pass_main.h"
20 20
21 [[nodiscard]] jen::Result jen::vk::PassMain::Attachments::
22 init(Device *p_dev, CmdData *p_cmds,
23 vkw::Extent2D extent, vkw::Samples sample_count)
24 {
25 Attachment::CreateInfo att_info; {
26 att_info.flags = AttachmentFlags::DEPTH;
27 att_info.extent = extent;
28 att_info.mip_level_count = 1;
29 if (not p_dev->physical
30 .depth_format_supported(&att_info.format, VK_FORMAT_D32_SFLOAT))
31 return VK_ERROR_FORMAT_NOT_SUPPORTED;
32 att_info.samples = sample_count;
33 att_info.usage = vkw::ImUsage::DEPTH_STENCIL_ATTACHMENT;
34 att_info.access_consumer = {};
35 att_info.stage_consumer = vkw::StageFlag::BOTTOM_OF_PIPE;
36 }
37
38 depth.is_initialized = false;
39 Result result = depth.init(p_dev, p_cmds, att_info);
40 if (result != VK_SUCCESS)
41 return result;
42
43 att_info.samples = 1;
44 att_info.flags = AttachmentFlags::COLOR;
45 att_info.format = VK_FORMAT_R16G16B16A16_SFLOAT;
46 att_info.usage = vkw::ImUsage::COLOR_ATTACHMENT
47 | vkw::ImUsage::INPUT_ATTACHMENT;
48
49 hdr.is_initialized = false;
50 result = hdr.init(p_dev, p_cmds, att_info);
51 if (result != VK_SUCCESS)
52 goto CANCEL_DEPTH;
53
54 hdr_multisampled.is_initialized = false;
55 if (sample_count > 1)
56 {
57 att_info.samples = sample_count;
58 att_info.usage = vkw::ImUsage::COLOR_ATTACHMENT | vkw::ImUsage::SAMPLED;
59 result = hdr_multisampled.init(p_dev, p_cmds, att_info);
60 if (result != VK_SUCCESS)
61 goto CANCEL_HDR;
62 }
63
64 return result;
65
21 [[nodiscard]] jen::Result jen::vk::Attachments::
22 init(Device *p_dev, CmdData *p_cmds, vkw::Extent2D ext, vkw::Samples samples) {
23 Attachment::CreateInfo att_info = {
24 .flags = AttachmentFlags::DEPTH,
25 .extent = ext,
26 .mip_level_count = 1,
27 .samples = samples,
28 .usage = vkw::ImUsage::DEPTH_STENCIL_ATTACHMENT,
29 .access_consumer = {},
30 .stage_consumer = vkw::StageFlag::BOTTOM_OF_PIPE,
31 };
32 if (not p_dev->physical
33 .select_depth_format(VK_FORMAT_D32_SFLOAT, &att_info.format))
34 return VK_ERROR_FORMAT_NOT_SUPPORTED;
35 depth.is_initialized = false;
36 Result result = depth.init(p_dev, p_cmds, att_info);
37 if (result != VK_SUCCESS)
38 return result;
39 att_info.samples = 1;
40 att_info.flags = AttachmentFlags::COLOR;
41 att_info.format = VK_FORMAT_R16G16B16A16_SFLOAT;
42 att_info.usage = vkw::ImUsage::COLOR_ATTACHMENT
43 | vkw::ImUsage::INPUT_ATTACHMENT;
44 hdr.is_initialized = false;
45 result = hdr.init(p_dev, p_cmds, att_info);
46 if (result != VK_SUCCESS)
47 goto CANCEL_DEPTH;
48 hdr_multisampled.is_initialized = false;
49 if (samples > 1) {
50 att_info.samples = samples;
51 att_info.usage = vkw::ImUsage::COLOR_ATTACHMENT | vkw::ImUsage::SAMPLED;
52 result = hdr_multisampled.init(p_dev, p_cmds, att_info);
53 if (result != VK_SUCCESS)
54 goto CANCEL_HDR;
55 }
56 return result;
66 57 CANCEL_HDR: CANCEL_HDR:
67 hdr.destroy(p_dev);
58 hdr.destroy(p_dev);
68 59 CANCEL_DEPTH: CANCEL_DEPTH:
69 depth.destroy(p_dev);
70 return result;
60 depth.destroy(p_dev);
61 return result;
71 62 } }
72
73
74 void jen::vk::PassMain::Attachments::
63 void jen::vk::Attachments::
75 64 destroy(Device *p_dev) { destroy(Device *p_dev) {
76 hdr.destroy(p_dev);
77 hdr_multisampled.destroy(p_dev);
78 depth.destroy(p_dev);
65 hdr.destroy(p_dev);
66 hdr_multisampled.destroy(p_dev);
67 depth.destroy(p_dev);
79 68 } }
80
81 namespace jen::vk
82 {
83 [[nodiscard]] static Result
84 create_pass(
85 vkw::Device device,
86 vkw::Samples samples,
87 const PassMain::Attachments &attachments,
88 VkFormat sc_format,
89 vkw::RenderPass *p_pass
90 ){
91 using namespace vkw;
92 using Att = PassMain::Attachments;
93
94 AttachmentReference offscreen_ref; {
95 offscreen_ref.attachment = samples > 1 ? Att::HDR_M : Att::HDR;
96 offscreen_ref.layout = ImLayout::COLOR_ATTACHMENT;
97 }
98 AttachmentReference hdr_ref; {
99 hdr_ref.attachment = Att::Index::HDR;
100 hdr_ref.layout = ImLayout::COLOR_ATTACHMENT;
101 }
102 AttachmentReference hdr_ref2; {
103 hdr_ref2.attachment = Att::Index::HDR;
104 hdr_ref2.layout = ImLayout::SHADER_READ_ONLY;
105 }
106 AttachmentReference present_ref; {
107 present_ref.attachment = Att::Index::PRESENT;
108 present_ref.layout = ImLayout::COLOR_ATTACHMENT;
109 }
110 AttachmentReference depth_ref; {
111 depth_ref.attachment = Att::Index::DEPTH;
112 depth_ref.layout = ImLayout::DEPTH_STENCIL_ATTACHMENT;
113 }
114
115 jl::array<SubpassDescription, 2> subpasses;
116 {
117 auto &resolving = subpasses[0];
118 resolving.flags = SubpassDescription::Mask();
119 resolving.bindPoint = BindPoint::GRAPHICS;
120 resolving.inputAttachments = {};
121 resolving.colorAttachments = { 1, &offscreen_ref };
122 resolving.p_resolveAttachments = samples > 1 ? &hdr_ref : nullptr;
123 resolving.p_depthStencilAttachment = &depth_ref;
124 resolving.preserveAttachments = {};
125
126 auto &composition = subpasses[1];
127 composition.flags = SubpassDescription::Mask();
128 composition.bindPoint = BindPoint::GRAPHICS;
129 composition.inputAttachments = { 1, &hdr_ref2 };
130 composition.colorAttachments = { 1, &present_ref };
131 composition.p_resolveAttachments = nullptr;
132 composition.p_depthStencilAttachment = nullptr;
133 composition.preserveAttachments = {};
134 }
135
136 static_assert (Att::Index::HDR_M == Att::Index::COUNT - 1,
137 "HDR_M must be last, to be easily removable");
138 uint32_t attachments_count = Att::COUNT;
139 if (samples == 1)
140 attachments_count -= 1;
141
142 jl::array<AttachmentDescription, Att::Index::COUNT> atts_descr;
143 {
144 using AL = AttLoad;
145 using AS = AttStore;
146 using IL = ImLayout;
147
148 auto &hdr_at = atts_descr[Att::HDR];
149 {
150 hdr_at.flags = AttachmentMask();
151 hdr_at.format = attachments.hdr.format;
152 hdr_at.samples = 1;
153
154 hdr_at.op = { AL::DONT_CARE, AS::DONT_CARE };
155 hdr_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
156
157 hdr_at.layout_change.set_both(IL::COLOR_ATTACHMENT);
158 }
159
160 auto& depth_at = atts_descr[Att::DEPTH];
161 {
162 depth_at.flags = AttachmentMask();
163 depth_at.format = attachments.depth.format;
164 depth_at.samples = samples;
165
166 depth_at.op = { AL::CLEAR, AS::DONT_CARE };
167 depth_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
168
169 depth_at.layout_change.set_both(IL::DEPTH_STENCIL_ATTACHMENT);
170 }
171
172 if (attachments_count > Att::HDR_M)
173 {
174 auto &hdrm_at = atts_descr[Att::HDR_M];
175 {
176 hdrm_at.flags = AttachmentMask();
177 hdrm_at.format = attachments.hdr_multisampled.format;
178 hdrm_at.samples = samples;
179 hdrm_at.op = { AL::CLEAR, AS::DONT_CARE };
180 hdrm_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
181 hdrm_at.layout_change.set_both(IL::COLOR_ATTACHMENT);
182 }
183 }
184 else hdr_at.op.initial = AttLoad::CLEAR;
185
186 auto &present_at = atts_descr[Att::PRESENT];
187 {
188 present_at.flags = AttachmentMask();
189 present_at.samples = 1;
190 present_at.format = sc_format;
191
192 present_at.op = { AL::DONT_CARE, AS::STORE };
193 present_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
194 present_at.layout_change = { IL::UNDEFINED, IL::PRESENT_SRC_KHR };
195 }
196 }
197
198 jl::array<SubpassDependency, 3> dependency;
199 {
200 auto &off = dependency[0]; //offscreen
201 {
202 off.subpass_change = { VK_SUBPASS_EXTERNAL, 0 };
203
204 off.stageFlags_change.initial = StageFlag::BOTTOM_OF_PIPE;
205 off.stageFlags_change.final = StageFlag::COLOR_ATTACHMENT_OUTPUT;
206
207 off.accessFlags_change.initial = AccessFlag::MEMORY_READ;
208 off.accessFlags_change.final = AccessFlag::COLOR_ATTACHMENT_READ
209 | AccessFlag::COLOR_ATTACHMENT_WRITE;
210
211 off.dependencyFlags = DependencyFlag::FRAMEBUFFER_LOCAL;
212 }
213
214 auto &comp = dependency[1]; //composition
215 {
216 comp.subpass_change = { 0, 1 };
217 comp.stageFlags_change.initial = StageFlag::COLOR_ATTACHMENT_OUTPUT;
218 comp.stageFlags_change.final = StageFlag::COLOR_ATTACHMENT_OUTPUT;
219
220 comp.accessFlags_change.set_both(AccessFlag::COLOR_ATTACHMENT_READ
221 | AccessFlag::COLOR_ATTACHMENT_WRITE);
222
223 comp.dependencyFlags = DependencyFlag::FRAMEBUFFER_LOCAL;
224 }
225
226 auto &pres = dependency[2]; //present
227 {
228 pres.subpass_change = { 1, VK_SUBPASS_EXTERNAL };
229
230 pres.stageFlags_change.initial = StageFlag::COLOR_ATTACHMENT_OUTPUT;
231 pres.stageFlags_change.final = StageFlag::BOTTOM_OF_PIPE;
232
233 pres.accessFlags_change.src = AccessFlag::COLOR_ATTACHMENT_READ
234 | AccessFlag::COLOR_ATTACHMENT_WRITE;
235
236 pres.accessFlags_change.dst = AccessFlag::MEMORY_READ;
237
238 pres.dependencyFlags = DependencyFlag::FRAMEBUFFER_LOCAL;
239 }
240 }
241
242 return p_pass->init(device, {atts_descr.begin(), attachments_count},
243 {subpasses .begin(), subpasses .end()},
244 {dependency.begin(), dependency.end()});
245 }
69 using namespace jen;
70 using namespace jen::vk;
71
72 [[nodiscard]] static Result
73 create_pass(vkw::Device dev, vkw::Samples samples, const Attachments &atts,
74 VkFormat swapchain_format, vkw::RenderPass *p_pass) {
75 using namespace vkw;
76 using Att = Attachments;
77 AttachmentReference offscreen_ref = {
78 .attachment = samples > 1 ? Att::HDR_M : Att::HDR,
79 .layout = ImLayout::COLOR_ATTACHMENT,
80 };
81 AttachmentReference hdr_ref = {
82 .attachment = Att::Index::HDR,
83 .layout = ImLayout::COLOR_ATTACHMENT,
84 };
85 AttachmentReference hdr_ref2 = {
86 .attachment = Att::Index::HDR,
87 .layout = ImLayout::SHADER_READ_ONLY,
88 };
89 AttachmentReference present_ref = {
90 .attachment = Att::Index::PRESENT,
91 .layout = ImLayout::COLOR_ATTACHMENT,
92 };
93 AttachmentReference depth_ref = {
94 .attachment = Att::Index::DEPTH,
95 .layout = ImLayout::DEPTH_STENCIL_ATTACHMENT,
96 };
97 jl::array<SubpassDescription, 2> subpasses; {
98 auto &resolving = subpasses[0];
99 resolving.flags = SubpassDescription::Mask();
100 resolving.bindPoint = BindPoint::GRAPHICS;
101 resolving.inputAttachments = {};
102 resolving.colorAttachments = { 1, &offscreen_ref };
103 resolving.p_resolveAttachments = samples > 1 ? &hdr_ref : nullptr;
104 resolving.p_depthStencilAttachment = &depth_ref;
105 resolving.preserveAttachments = {};
106
107 auto &composition = subpasses[1];
108 composition.flags = SubpassDescription::Mask();
109 composition.bindPoint = BindPoint::GRAPHICS;
110 composition.inputAttachments = { 1, &hdr_ref2 };
111 composition.colorAttachments = { 1, &present_ref };
112 composition.p_resolveAttachments = nullptr;
113 composition.p_depthStencilAttachment = nullptr;
114 composition.preserveAttachments = {};
115 }
116 static_assert(Att::Index::HDR_M == Att::Index::COUNT - 1,
117 "HDR_M must be last, to be easily removable");
118 uint32_t attachments_count = Att::COUNT;
119 if (samples == 1)
120 attachments_count -= 1;
121 jl::array<AttachmentDescription, Att::Index::COUNT> atts_descr; {
122 using AL = AttLoad;
123 using AS = AttStore;
124 using IL = ImLayout;
125 auto &hdr_at = atts_descr[Att::HDR]; {
126 hdr_at.flags = AttachmentMask();
127 hdr_at.format = atts.hdr.format;
128 hdr_at.samples = 1;
129 hdr_at.op = { AL::DONT_CARE, AS::DONT_CARE };
130 hdr_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
131 hdr_at.layout_change.set_both(IL::COLOR_ATTACHMENT);
132 }
133 auto& depth_at = atts_descr[Att::DEPTH]; {
134 depth_at.flags = AttachmentMask();
135 depth_at.format = atts.depth.format;
136 depth_at.samples = samples;
137 depth_at.op = { AL::CLEAR, AS::DONT_CARE };
138 depth_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
139 depth_at.layout_change.set_both(IL::DEPTH_STENCIL_ATTACHMENT);
140 }
141 if (attachments_count > Att::HDR_M) {
142 auto &hdrm_at = atts_descr[Att::HDR_M]; {
143 hdrm_at.flags = AttachmentMask();
144 hdrm_at.format = atts.hdr_multisampled.format;
145 hdrm_at.samples = samples;
146 hdrm_at.op = { AL::CLEAR, AS::DONT_CARE };
147 hdrm_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
148 hdrm_at.layout_change.set_both(IL::COLOR_ATTACHMENT);
149 }
150 }
151 else
152 hdr_at.op.src = AttLoad::CLEAR;
153 auto &present_at = atts_descr[Att::PRESENT]; {
154 present_at.flags = AttachmentMask();
155 present_at.samples = 1;
156 present_at.format = swapchain_format;
157
158 present_at.op = { AL::DONT_CARE, AS::STORE };
159 present_at.op_stencil = { AL::DONT_CARE, AS::DONT_CARE };
160 present_at.layout_change = { IL::UNDEFINED, IL::PRESENT_SRC_KHR };
161 }
162 }
163 jl::array<SubpassDependency, 3> dependency; {
164 auto &off = dependency[0]; { //offscreen
165 off.subpass_change = { VK_SUBPASS_EXTERNAL, 0 };
166 off.stageFlags_change.src = StageFlag::BOTTOM_OF_PIPE;
167 off.stageFlags_change.dst = StageFlag::COLOR_ATTACHMENT_OUTPUT;
168 off.accessFlags_change.src = AccessFlag::MEMORY_READ;
169 off.accessFlags_change.dst = AccessFlag::COLOR_ATTACHMENT_READ
170 | AccessFlag::COLOR_ATTACHMENT_WRITE;
171 off.dependencyFlags = DependencyFlag::FRAMEBUFFER_LOCAL;
172 }
173 auto &comp = dependency[1]; { //composition
174 comp.subpass_change = { 0, 1 };
175 comp.stageFlags_change.src = StageFlag::COLOR_ATTACHMENT_OUTPUT;
176 comp.stageFlags_change.dst = StageFlag::COLOR_ATTACHMENT_OUTPUT;
177 comp.accessFlags_change.set_both(AccessFlag::COLOR_ATTACHMENT_READ
178 | AccessFlag::COLOR_ATTACHMENT_WRITE);
179 comp.dependencyFlags = DependencyFlag::FRAMEBUFFER_LOCAL;
180 }
181 auto &pres = dependency[2]; { //present
182 pres.subpass_change = { 1, VK_SUBPASS_EXTERNAL };
183 pres.stageFlags_change.src = StageFlag::COLOR_ATTACHMENT_OUTPUT;
184 pres.stageFlags_change.dst = StageFlag::BOTTOM_OF_PIPE;
185 pres.accessFlags_change.src = AccessFlag::COLOR_ATTACHMENT_READ
186 | AccessFlag::COLOR_ATTACHMENT_WRITE;
187 pres.accessFlags_change.dst = AccessFlag::MEMORY_READ;
188 pres.dependencyFlags = DependencyFlag::FRAMEBUFFER_LOCAL;
189 }
190 }
191 return p_pass->init(dev,
192 {atts_descr.begin(), attachments_count},
193 {subpasses .begin(), subpasses .end() },
194 {dependency.begin(), dependency.end() });
246 195 } }
247
248 [[nodiscard]] jen::Result jen::vk::PassMain::Framebuffer::
249 init( vkw::Device device,
250 vkw::RenderPass renderPass_,
251 vkw::Image image_,
252 vkw::Extent2D extent_,
253 VkFormat format,
254 const Attachments &attachments_)
255 {
256 image = image_;
257
258 Result result = imageView.init(device, image, vkw::ImViewType::_2D,
259 format, vkw::ImAspect::COLOR);
260 if (result != VK_SUCCESS)
261 return result;
262
263 jl::array<vkw::ImView, Attachments::COUNT> views;
264 views[Attachments::PRESENT ] = imageView;
265 views[Attachments::HDR ] = attachments_.hdr.gpu_image.view;
266 views[Attachments::DEPTH ] = attachments_.depth.gpu_image.view;
267
268 uint32_t count = Attachments::COUNT;
269 if (attachments_.hdr_multisampled.is_initialized)
270 views[Attachments::HDR_M] = attachments_.hdr_multisampled.gpu_image.view;
271 else count -= 1;
272
273 result = framebuffer.init(device, renderPass_, {views.begin(), count},
274 extent_, 1);
275 if (result != VK_SUCCESS)
276 imageView.destroy(device);
277 return result;
196 [[nodiscard]] jen::Result jen::vk::Framebuffer::
197 init(vkw::Device dev, vkw::RenderPass rp, vkw::Image im, vkw::Extent2D ext,
198 VkFormat format, const Attachments &atts) {
199 image = im;
200 Result res;
201 res = imageView.init(dev, im, vkw::ImViewType::_2D,
202 format, vkw::ImAspect::COLOR);
203 if (res != VK_SUCCESS)
204 return res;
205 jl::array<vkw::ImView, Attachments::COUNT> views;
206 views[Attachments::PRESENT ] = imageView;
207 views[Attachments::HDR ] = atts.hdr.gpu_image.view;
208 views[Attachments::DEPTH ] = atts.depth.gpu_image.view;
209 uint32_t count = Attachments::COUNT;
210 if (atts.hdr_multisampled.is_initialized)
211 views[Attachments::HDR_M] = atts.hdr_multisampled.gpu_image.view;
212 else count -= 1;
213 res = framebuffer.init(dev, rp, {views.begin(), count}, ext, 1);
214 if (res != VK_SUCCESS)
215 imageView.destroy(dev);
216 return res;
278 217 } }
279
280 218 void void
281 jen::vk::PassMain::Framebuffer::destroy(vkw::Device device)
282 {
283 if (not framebuffer.is_null()) {
284 framebuffer.destroy(device);
285 framebuffer.set_null();
286 }
287 if (not imageView.is_null()) {
288 imageView.destroy(device);
289 imageView.set_null();
290 }
219 jen::vk::Framebuffer::
220 destroy(vkw::Device device) {
221 if (not framebuffer.is_null()) {
222 framebuffer.destroy(device);
223 framebuffer.set_null();
224 }
225 if (not imageView.is_null()) {
226 imageView.destroy(device);
227 imageView.set_null();
228 }
291 229 } }
292
293 230 [[nodiscard]] jen::Result jen::vk::PassMain:: [[nodiscard]] jen::Result jen::vk::PassMain::
294 init(Device *p_dev, CmdData *p_cmds, const SwapChainData &sc,
295 vkw::Samples sampleCount
296 ){
297 framebuffers.init();
298 sample_count = sampleCount;
299
300 Result result = attachments.init(p_dev, p_cmds, sc.extent, sampleCount);
301 if (result != VK_SUCCESS)
302 return result;
303
304 result = create_pass(p_dev->device, sampleCount, attachments,
305 sc.surfaceInfo.format, &render_pass);
306 if (result != VK_SUCCESS)
307 goto CANCEL_AT;
308
309 if (not framebuffers.init(sc.image_count))
310 {
311 result = VK_ERROR_OUT_OF_HOST_MEMORY;
312 goto CANCEL_RP;
313 }
314
315 for (uint32_t i = 0; i < framebuffers.count(); ++i)
316 {
317 result = framebuffers[i].init(p_dev->device, render_pass, sc.images[i],
318 sc.extent, sc.surfaceInfo.format,
319 attachments);
320 if (result != VK_SUCCESS)
321 {
322 while (i > 0)
323 framebuffers[--i].destroy(p_dev->device);
324 goto CANCEL_RP;
325 }
326 }
327
328 return VK_SUCCESS;
329
330 CANCEL_RP: render_pass.destroy(p_dev->device);
331 framebuffers.destroy();
332 CANCEL_AT: attachments.destroy(p_dev);
333 return result;
231 init(Device *p_d, CmdData *p_cmds, const SwapChainData &sc, vkw::Samples sams) {
232 framebuffers.init();
233 sample_count = sams;
234 Result res;
235 res = attachments.init(p_d, p_cmds, sc.extent, sams);
236 if (res != VK_SUCCESS)
237 return res;
238 res = create_pass(p_d->device, sams, attachments,
239 sc.surfaceInfo.format, &render_pass);
240 if (res != VK_SUCCESS)
241 goto CANCEL_AT;
242 if (not framebuffers.init(sc.image_count)) {
243 res = VK_ERROR_OUT_OF_HOST_MEMORY;
244 goto CANCEL_RP;
245 }
246 for (uint32_t i = 0; i < framebuffers.count(); ++i) {
247 res = framebuffers[i].init(p_d->device, render_pass, sc.images[i],
248 sc.extent, sc.surfaceInfo.format, attachments);
249 if (res != VK_SUCCESS) {
250 while (i > 0)
251 framebuffers[--i].destroy(p_d->device);
252 goto CANCEL_RP;
253 }
254 }
255 return VK_SUCCESS;
256 CANCEL_RP:
257 render_pass.destroy(p_d->device);
258 framebuffers.destroy();
259 CANCEL_AT:
260 attachments.destroy(p_d);
261 return res;
334 262 } }
335
336 263 void jen::vk::PassMain:: void jen::vk::PassMain::
337 destroy(Device *p_dev)
338 {
339 framebuffers.destroy(&Framebuffer::destroy, *p_dev);
340 render_pass.destroy(*p_dev);
341 render_pass.set_null();
342 attachments.destroy(p_dev);
264 destroy(Device *p_dev) {
265 framebuffers.destroy(&Framebuffer::destroy, *p_dev);
266 render_pass.destroy(*p_dev);
267 render_pass.set_null();
268 attachments.destroy(p_dev);
343 269 } }
File src/graphics/draw_stages/pass_main.h changed (mode: 100644) (index 0726909..25e4c1d)
17 17 * along with this library. If not, see <https://www.gnu.org/licenses/> * along with this library. If not, see <https://www.gnu.org/licenses/>
18 18 */ */
19 19 #pragma once #pragma once
20
21 20 #include "attachment.h" #include "attachment.h"
22 21 #include <jlib/array.h> #include <jlib/array.h>
23 22 #include "swap_chain.h" #include "swap_chain.h"
24 23
25 namespace jen::vk
26 {
27 struct PassMain
28 {
29 [[nodiscard]] Result
30 init(Device*, CmdData*, const SwapChainData&, vkw::Samples);
31
32 void destroy(Device*);
33
34 struct Attachments
35 {
36 enum Index { PRESENT, HDR, DEPTH, HDR_M, COUNT };
37
38 Attachment depth;
39 Attachment hdr_multisampled;
40 Attachment hdr;
41
42 constexpr static jl::array<VkClearValue, COUNT> CLEAR_VALUES()
43 {
44 jl::array<VkClearValue, COUNT> cv{};
45 cv[HDR_M].color = { { 0, 0, 0, 1 } };
46 cv[DEPTH].depthStencil.depth = 1.0f;
47 cv[DEPTH].depthStencil.stencil = 0;
48 cv[HDR] = cv[HDR_M];
49 cv[PRESENT] = cv[HDR_M];
50 return cv;
51 }
52
53 [[nodiscard]] Result
54 init(Device*, CmdData*, vkw::Extent2D, vkw::Samples);
55
56 void destroy(Device*);
57 };
58
59 struct Framebuffer
60 {
61 vkw::Image image;
62 vkw::ImView imageView;
63 vkw::Framebuffer framebuffer;
64
65 [[nodiscard]] Result
66 init(vkw::Device device,
67 vkw::RenderPass renderPass,
68 vkw::Image image_,
69 vkw::Extent2D extent_,
70 VkFormat format,
71 const Attachments &attachments);
72
73 void destroy(vkw::Device device);
74 };
75
76 jl::rarray<Framebuffer> framebuffers;
77 Attachments attachments;
78 vkw::RenderPass render_pass;
79 vkw::Samples sample_count;
80 };
24 namespace jen::vk {
25 struct PassMain;
26 struct Attachments;
27 struct Framebuffer;
81 28 } }
29 struct jen::vk::Attachments {
30 enum Index {
31 PRESENT, HDR, DEPTH, HDR_M, COUNT
32 };
33 constexpr static jl::array<VkClearValue, COUNT> CLEAR_VALUES() {
34 jl::array<VkClearValue, COUNT> cv{};
35 cv[HDR_M].color = { { 0, 0, 0, 1 } };
36 cv[DEPTH].depthStencil.depth = 1.0f;
37 cv[DEPTH].depthStencil.stencil = 0;
38 cv[HDR] = cv[HDR_M];
39 cv[PRESENT] = cv[HDR_M];
40 return cv;
41 }
42 [[nodiscard]] Result
43 init(Device*, CmdData*, vkw::Extent2D, vkw::Samples);
44 void
45 destroy(Device*);
46 Attachment depth;
47 Attachment hdr_multisampled;
48 Attachment hdr;
49 };
50 struct jen::vk::Framebuffer
51 {
52 [[nodiscard]] Result
53 init(vkw::Device device,
54 vkw::RenderPass renderPass,
55 vkw::Image image_,
56 vkw::Extent2D extent_,
57 VkFormat format,
58 const Attachments &attachments);
59 void
60 destroy(vkw::Device device);
61 vkw::Image image;
62 vkw::ImView imageView;
63 vkw::Framebuffer framebuffer;
64 };
65 struct jen::vk::PassMain {
66 [[nodiscard]] Result
67 init(Device*, CmdData*, const SwapChainData&, vkw::Samples);
68 void
69 destroy(Device*);
70 jl::rarray<Framebuffer> framebuffers;
71 Attachments attachments;
72 vkw::RenderPass render_pass;
73 vkw::Samples sample_count;
74 };
File src/graphics/gpu_transfer/data.cpp changed (mode: 100644) (index 0441aa3..8731834)
... ... jen::vk::TransferData::write_data(GpuData *p_data) {
177 177 } }
178 178
179 179 [[nodiscard]] jen::Result jen::vk::TransferData:: [[nodiscard]] jen::Result jen::vk::TransferData::
180 write_texture(GpuTexture *p_texture)
181 {
182 auto &source = p_texture->source;
183
180 write_texture(GpuTexture *p_tex) {
181 auto &source = p_tex->source;
182 uint32_t psize = vkw::format_size(p_tex->format);
184 183 uint32_t i; uint32_t i;
185 vkw::DeviceSize texture_size = source.extent.pixel_count() * 4;
184 auto pcount = source.extent.pixel_count();
185 vkw::DeviceSize texture_size = pcount * psize;
186 186 jen::Result res = get_staging(texture_size, &i); jen::Result res = get_staging(texture_size, &i);
187 187 if (res != VK_SUCCESS) if (res != VK_SUCCESS)
188 188 return res; return res;
189
190 189 auto &buffer = staging_allocations[i]; auto &buffer = staging_allocations[i];
191
192 if (source.extent.pixelSize == 4) {
190 auto pdiff = source.extent.pixelSize - psize;
191 if (pdiff == 0) {
192 jassert(source.extent.size() == texture_size, "Cant be happened");
193 193 memcpy(buffer.p_data(), source.p_pixels, texture_size); memcpy(buffer.p_data(), source.p_pixels, texture_size);
194 194 } }
195 else if (source.extent.pixelSize == 3) {
196 uint8_t pixel[4];
197 pixel[3] = 255;
195 else if (pdiff > 0) {
198 196 uint8_t *p_src = reinterpret_cast<uint8_t *>(source.p_pixels); uint8_t *p_src = reinterpret_cast<uint8_t *>(source.p_pixels);
199 197 uint8_t *p_dst = staging_allocations[i].p_data(); uint8_t *p_dst = staging_allocations[i].p_data();
200 for (uint64_t i = 0; i < source.extent.pixel_count(); ++i) {
201 pixel[0] = p_src[i*3+0];
202 pixel[1] = p_src[i*3+1];
203 pixel[2] = p_src[i*3+2];
204 memcpy(p_dst + i * sizeof(uint32_t), &pixel, 4);
198 uint8_t *p_end = p_dst + pcount * psize;
199 do {
200 memcpy(p_dst, p_src, source.extent.pixelSize);
201 p_src += source.extent.pixelSize;
202 p_dst += source.extent.pixelSize;
203 memset(p_dst, 255, pdiff);
204 p_dst += pdiff;
205 205 } }
206 while(p_dst < p_end);
206 207 } }
207 208
208 209 auto cmd_transfer = cmds_transfer.primary[i]; auto cmd_transfer = cmds_transfer.primary[i];
 
... ... write_texture(GpuTexture *p_texture)
215 216 barrier.access_change.dst = vkw::AccessFlag::TRANSFER_WRITE; barrier.access_change.dst = vkw::AccessFlag::TRANSFER_WRITE;
216 217 barrier.layout_change.src = vkw::ImLayout::UNDEFINED; barrier.layout_change.src = vkw::ImLayout::UNDEFINED;
217 218 barrier.layout_change.dst = vkw::ImLayout::TRANSFER_DST; barrier.layout_change.dst = vkw::ImLayout::TRANSFER_DST;
218 barrier.queueFamily_change.set_both(VK_QUEUE_FAMILY_IGNORED);
219 barrier.image = p_texture->gpu_im.image;
219 barrier.queue_family_change.set_both(VK_QUEUE_FAMILY_IGNORED);
220 barrier.image = p_tex->gpu_im.image;
220 221 barrier.range = {vkw::ImAspect::COLOR, barrier.range = {vkw::ImAspect::COLOR,
221 source.extent.depth, p_texture->mip_levels};
222 source.extent.depth, p_tex->mip_levels};
222 223 } }
223 224 vkw::StageMaskChange stageMasks_change; { vkw::StageMaskChange stageMasks_change; {
224 225 stageMasks_change.src = vkw::StageFlag::TOP_OF_PIPE; stageMasks_change.src = vkw::StageFlag::TOP_OF_PIPE;
 
... ... write_texture(GpuTexture *p_texture)
240 241 region.imageExtent = {source.extent.width, source.extent.height, 1}; region.imageExtent = {source.extent.width, source.extent.height, 1};
241 242 } }
242 243
243 cmd_transfer.cmd_cp_buffer_to_image({buffer.buffer, p_texture->gpu_im.image},
244 cmd_transfer.cmd_cp_buffer_to_image({buffer.buffer, p_tex->gpu_im.image},
244 245 region, vkw::ImLayout::TRANSFER_DST); region, vkw::ImLayout::TRANSFER_DST);
245 246
246 if (p_texture->mip_levels <= 1) {
247 if (p_tex->mip_levels <= 1) {
247 248 barrier.access_change.move(vkw::AccessMask()); barrier.access_change.move(vkw::AccessMask());
248 249 barrier.layout_change.move(vkw::ImLayout::SHADER_READ_ONLY); barrier.layout_change.move(vkw::ImLayout::SHADER_READ_ONLY);
249 250 stageMasks_change.move(vkw::StageFlag::TOP_OF_PIPE); stageMasks_change.move(vkw::StageFlag::TOP_OF_PIPE);
 
... ... write_texture(GpuTexture *p_texture)
270 271 return res; return res;
271 272
272 273 vkw::CmdBuffer::MipmapGetInfo mipmap; { vkw::CmdBuffer::MipmapGetInfo mipmap; {
273 mipmap.image = p_texture->gpu_im.image;
274 mipmap.image = p_tex->gpu_im.image;
274 275 mipmap.aspect = vkw::ImAspect::COLOR; mipmap.aspect = vkw::ImAspect::COLOR;
275 276 mipmap.extent = { source.extent.width, source.extent.height, 1 }; mipmap.extent = { source.extent.width, source.extent.height, 1 };
276 277 mipmap.layer_count = source.extent.depth; mipmap.layer_count = source.extent.depth;
277 mipmap.level_count = p_texture->mip_levels;
278 mipmap.level_count = p_tex->mip_levels;
278 279 mipmap.layout_change.src = vkw::ImLayout::TRANSFER_DST; mipmap.layout_change.src = vkw::ImLayout::TRANSFER_DST;
279 280 mipmap.layout_change.dst = vkw::ImLayout::SHADER_READ_ONLY; mipmap.layout_change.dst = vkw::ImLayout::SHADER_READ_ONLY;
280 281 mipmap.access_change.src = {}; mipmap.access_change.src = {};
 
... ... write_texture(GpuTexture *p_texture)
310 311 } }
311 312
312 313 jassert(res == VK_SUCCESS, "unexpected failure here"); jassert(res == VK_SUCCESS, "unexpected failure here");
313 working_items[i].set_texture(p_texture);
314 working_items[i].set_texture(p_tex);
314 315 return VK_SUCCESS; return VK_SUCCESS;
315 316 } }
File src/graphics/gpu_transfer/gpu_transfer.cpp changed (mode: 100644) (index 534edcd..433a662)
... ... DATA: data.destroy();
136 136 return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
137 137 } }
138 138
139
140 [[nodiscard]] VkFormat choose_image_format(jrf::Image::Format format)
141 {
142 /// @todo Check format features vkGetPhysicalDeviceFormatProperties
143 switch (format) {
144 case jrf::Image::Format::B8G8R8_UINT: //return VK_FORMAT_B8G8R8A8_UINT;
145 case jrf::Image::Format::B8G8R8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
146 case jrf::Image::Format::B8G8R8A8_UINT: //return VK_FORMAT_B8G8R8A8_UINT;
147 case jrf::Image::Format::B8G8R8A8_SRGB: return VK_FORMAT_B8G8R8A8_SRGB;
148 case jrf::Image::Format::R8G8B8A8_SRGB: return VK_FORMAT_R8G8B8A8_SRGB;
149 default: return VK_FORMAT_UNDEFINED;
150 }
151 }
152
153 139 [[nodiscard]] vkw::Result jen::vk::GpuTransfer:: [[nodiscard]] vkw::Result jen::vk::GpuTransfer::
154 140 submit(Priority priority, GpuTexture *p_t, vkw::Sampler sampler) submit(Priority priority, GpuTexture *p_t, vkw::Sampler sampler)
155 141 { {
156 142 auto &src = p_t->source; auto &src = p_t->source;
157
158 GpuImageInfo ci; {
159 ci.extent = {src.extent.width, src.extent.height, 1};
160 ci.layer_count = src.extent.depth;
161 ci.mip_level_count = p_t->mip_levels;
162 ci.format = choose_image_format(src.format);
163 if (ci.format == VK_FORMAT_UNDEFINED) {
164 fprintf(stderr,
165 "GpuTransfer::createTexture - unsupported src texture format\n");
166 return VK_ERROR_FORMAT_NOT_SUPPORTED;
167 }
168 ci.samples = 1;
169 ci.usage = vkw::ImUsage::TRANSFER_DST | vkw::ImUsage::TRANSFER_SRC
170 | vkw::ImUsage::SAMPLED;
171 ci.flags = {};
172 ci.type = vkw::ImType::_2D;
173 ci.tiling = vkw::Tiling::OPTIMAL;
174 }
143 GpuImageInfo ci = {
144 .extent = {src.extent.width, src.extent.height, 1},
145 .layer_count = src.extent.depth,
146 .mip_level_count = p_t->mip_levels,
147 .format = p_t->format,
148 .type = vkw::ImType::_2D,
149 .samples = 1,
150 .usage = vkw::ImUsage::TRANSFER_DST | vkw::ImUsage::TRANSFER_SRC
151 | vkw::ImUsage::SAMPLED,
152 .flags = {},
153 .tiling = vkw::Tiling::OPTIMAL,
154 };
175 155 GpuImageViewInfo vi; { GpuImageViewInfo vi; {
176 156 vi.type = vkw::ImViewType::_2D_ARRAY; vi.type = vkw::ImViewType::_2D_ARRAY;
177 157 vi.aspect = vkw::ImAspect::COLOR; vi.aspect = vkw::ImAspect::COLOR;
File src/graphics/graphics.cpp changed (mode: 100644) (index a078be4..d21e54a)
... ... void cmd_transfer_font_atlas(GraphicsData *p_g, vkw::CmdBuffer cmd) {
65 65 barrier.access_change.dst = vkw::AccessFlag::TRANSFER_WRITE; barrier.access_change.dst = vkw::AccessFlag::TRANSFER_WRITE;
66 66 barrier.layout_change.src = vkw::ImLayout::UNDEFINED; barrier.layout_change.src = vkw::ImLayout::UNDEFINED;
67 67 barrier.layout_change.dst = vkw::ImLayout::TRANSFER_DST; barrier.layout_change.dst = vkw::ImLayout::TRANSFER_DST;
68 barrier.queueFamily_change.set_both(VK_QUEUE_FAMILY_IGNORED);
68 barrier.queue_family_change.set_both(VK_QUEUE_FAMILY_IGNORED);
69 69 barrier.image = stages.stages.fonts.atlas.image; barrier.image = stages.stages.fonts.atlas.image;
70 70 barrier.range = vkw::ImAspect::COLOR; barrier.range = vkw::ImAspect::COLOR;
71 71 } }
 
... ... void cmd_primary_shadow_map_models(GraphicsData *p_g, vkw::CmdBuffer cmd)
147 147 | AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE; | AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE;
148 148 bar.layout_change.src = ImLayout::UNDEFINED; bar.layout_change.src = ImLayout::UNDEFINED;
149 149 bar.layout_change.dst = ImLayout::DEPTH_STENCIL_ATTACHMENT; bar.layout_change.dst = ImLayout::DEPTH_STENCIL_ATTACHMENT;
150 bar.queueFamily_change.set_both(VK_QUEUE_FAMILY_IGNORED);
150 bar.queue_family_change.set_both(VK_QUEUE_FAMILY_IGNORED);
151 151 bar.image = pass.att_depth.gpu_image.image; bar.image = pass.att_depth.gpu_image.image;
152 152 bar.range = {vkw::ImAspect::DEPTH, 6}; bar.range = {vkw::ImAspect::DEPTH, 6};
153 153 } }
 
... ... cmd_primary_main(GraphicsData *p_g, vkw::CmdBuffer cmd) {
327 327 if (res != VK_SUCCESS) if (res != VK_SUCCESS)
328 328 return res; return res;
329 329
330 auto clear_values = PassMain::Attachments::CLEAR_VALUES();
330 auto clear_values = Attachments::CLEAR_VALUES();
331 331 VkRect2D renderArrea; VkRect2D renderArrea;
332 332 renderArrea.offset = {}; renderArrea.offset = {};
333 333 renderArrea.extent = p_g->stages.swap_chain.extent; renderArrea.extent = p_g->stages.swap_chain.extent;
File src/graphics/graphics_interface.cpp changed (mode: 100644) (index bdbc9d6..0c4da4b)
... ... void ModuleGraphics::destroy(GpuData *p_data, bool destroy_source) {
141 141 p->destroyer << p_data; p->destroyer << p_data;
142 142 } }
143 143
144 [[nodiscard]] VkFormat static
145 convert_format(jen::Device *p_d, jrf::Image::Format format) {
146 auto is_linear = [p_d](VkFormat f) {
147 auto p = p_d->physical.format_properties(f);
148 return p.optimalTilingFeatures
149 & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
150 };
151 auto is_suitable = [p_d](VkFormat f) {
152 auto p = p_d->physical.format_properties(f);
153 return p.optimalTilingFeatures &
154 (VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
155 | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT);
156 };
157 switch (format) {
158 case jrf::Image::Format::R_8:
159 return is_linear(VK_FORMAT_R8_UINT) ? VK_FORMAT_R8_UINT : VkFormat();
160 case jrf::Image::Format::RG_8:
161 return is_linear(VK_FORMAT_R8G8_UINT) ? VK_FORMAT_R8G8_UINT : VkFormat();
162 case jrf::Image::Format::RGB_8:
163 if (is_suitable(VK_FORMAT_R8G8B8_UINT))
164 return VK_FORMAT_R8G8B8_UINT;
165 [[fallthrough]];
166 case jrf::Image::Format::RGBA_8:
167 return is_linear(VK_FORMAT_R8G8B8A8_UINT)
168 ? VK_FORMAT_R8G8B8A8_UINT : VK_FORMAT_R8G8B8A8_SRGB;
169 case jrf::Image::Format::RGB_8_sRGB:
170 if (is_suitable(VK_FORMAT_R8G8B8_SRGB))
171 return VK_FORMAT_R8G8B8_SRGB;
172 else
173 return VK_FORMAT_R8G8B8A8_SRGB;
174 case jrf::Image::Format::RGBA_8_sRGB:
175 return VK_FORMAT_R8G8B8A8_SRGB;
176 }
177 return VK_FORMAT_UNDEFINED;
178 }
144 179 [[nodiscard]] Result ModuleGraphics:: [[nodiscard]] Result ModuleGraphics::
145 180 create(const jrf::Image &im, GpuTexture **pp_dst, bool free_source){ create(const jrf::Image &im, GpuTexture **pp_dst, bool free_source){
181 auto format = convert_format(p->p_device, im.format);
182 if (format == 0) {
183 fprintf(stderr,
184 "GpuTransfer::createTexture - unsupported src texture format\n");
185 return VK_ERROR_FORMAT_NOT_SUPPORTED;
186 }
146 187 if (not jl::allocate(pp_dst)) if (not jl::allocate(pp_dst))
147 188 return VK_ERROR_OUT_OF_HOST_MEMORY; return VK_ERROR_OUT_OF_HOST_MEMORY;
148 (*pp_dst)->init(im, free_source);
189 (*pp_dst)->init(im, format, free_source);
149 190 auto r = p->gpu_transfer.submit(GpuTransfer::Priority::LOW, auto r = p->gpu_transfer.submit(GpuTransfer::Priority::LOW,
150 191 *pp_dst, p->stages.textureSampler); *pp_dst, p->stages.textureSampler);
151 192 if (r != VK_SUCCESS) if (r != VK_SUCCESS)
152 193 jl::deallocate(pp_dst); jl::deallocate(pp_dst);
153 194 return r; return r;
154 195 } }
155
156 196 void ModuleGraphics:: void ModuleGraphics::
157 197 destroy(GpuTexture* p_gpuTexture, bool destroy_src) { destroy(GpuTexture* p_gpuTexture, bool destroy_src) {
158 198 if (p_gpuTexture == nullptr) if (p_gpuTexture == nullptr)
File src/graphics/resources.h changed (mode: 100644) (index 96c9603..d32a10d)
... ... struct jen::GpuData {
39 39 static_assert(jen::GPU_DATA_ALLOCATION_SIZE == sizeof(jen::GpuData)); static_assert(jen::GPU_DATA_ALLOCATION_SIZE == sizeof(jen::GpuData));
40 40
41 41 struct jen::GpuTexture { struct jen::GpuTexture {
42 void init(const jrf::Image &src, bool destroy_source) {
42 void init(const jrf::Image &src, VkFormat format, bool destroy_source) {
43 this->format = format;
43 44 state = ResourceState::LOADING; state = ResourceState::LOADING;
45 mip_levels = mip_level(src.extent.width, src.extent.height);
44 46 is_source_destroy_allowed = destroy_source; is_source_destroy_allowed = destroy_source;
45 47 source = src; source = src;
46 mip_levels = mip_level(src.extent.width, src.extent.height);
47 48 } }
48 49 void destroy_source_if_allowed() { void destroy_source_if_allowed() {
49 50 if (is_source_destroy_allowed) { if (is_source_destroy_allowed) {
 
... ... struct jen::GpuTexture {
54 55 static uint32_t mip_level(uint32_t width, uint32_t height) { static uint32_t mip_level(uint32_t width, uint32_t height) {
55 56 return uint32_t(std::floor(std::log2(jl::max(width, height)))) + 1; return uint32_t(std::floor(std::log2(jl::max(width, height)))) + 1;
56 57 } }
57
58 58 GpuImage<GpuImageMode::VIEW> gpu_im; GpuImage<GpuImageMode::VIEW> gpu_im;
59 VkFormat format;
59 60 DescriptorTexture descriptor; DescriptorTexture descriptor;
60 61 ResourceState state; ResourceState state;
61 62 uint32_t mip_levels; uint32_t mip_levels;
62 63 bool is_source_destroy_allowed; bool is_source_destroy_allowed;
63 64 jrf::Image source; jrf::Image source;
64 65 }; };
65 static_assert(jen::GPU_TEXTURE_ALLOCATION_SIZE == sizeof(jen::GpuTexture));
66
67
68 66 struct jen::GpuText struct jen::GpuText
69 67 { {
70 68 [[nodiscard]] static GpuText* new_() { return nullptr; } [[nodiscard]] static GpuText* new_() { return nullptr; }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/Jackalope/jen

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jen

Clone this repository using git:
git clone git://git.rocketgit.com/user/Jackalope/jen

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main