We got exr loading

This commit is contained in:
2026-01-22 02:04:11 +01:00
parent a5b26f3bdd
commit 41ed926409
23 changed files with 529 additions and 283 deletions

View File

@@ -45,6 +45,9 @@ private:
glm::vec3 m_BaseScale{1.0f};
float m_GrowSpeed = 1.0f; // rad/sec
float m_GrowMin = 0.05f;
float m_GrowMax = 0.3f;
// self spin
glm::vec3 m_SpinAxis{0,1,0};
float m_SpinSpeed = 2.0f; // rad/sec

View File

@@ -50,9 +50,10 @@ public:
struct EndFrameProps {
const VkClearColorValue clearColor{ {0.f, 0.f, 0.f, 1.f} };
const VkClearColorValue clearColor{{0.f, 0.f, 0.f, 1.f}};
glm::ivec4 drawImageBlitRect{}; // where to blit draw image to
};
void endFrame(VkCommandBuffer cmd, const GPUImage& drawImage, const EndFrameProps& props);
void cleanup();
@@ -67,8 +68,7 @@ public:
vkb::Device getDevice() const { return device; }
std::uint32_t getCurrentFrameIndex() const
{
std::uint32_t getCurrentFrameIndex() const {
return frameNumber % FRAMES_IN_FLIGHT;
}
@@ -91,18 +91,20 @@ public:
ImageID createImage(const vkutil::CreateImageInfo& createInfo, const std::string& debugName = "", void* pixelData = nullptr, ImageID imageId = NULL_IMAGE_ID);
ImageID createDrawImage(VkFormat format, glm::ivec2 size, const std::string& debugName = "", ImageID imageId = NULL_IMAGE_ID);
ImageID loadImageFromFile(const std::filesystem::path& path, VkFormat format = VK_FORMAT_R8G8B8A8_SRGB, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, bool mipMap = false);
ImageID loadImageFromFile(const std::filesystem::path& path, VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT, bool mipMap = false, TextureIntent intent = TextureIntent::ColorSrgb);
ImageID addImageToCache(GPUImage image);
const GPUImage& getImage(ImageID id) const;
void uploadImageData(const GPUImage& image, void* pixelData, std::uint32_t layer = 0) const;
[[nodiscard]] const GPUImage& getImage(ImageID id) const;
// void uploadImageData(const GPUImage& image, void* pixelData, std::uint32_t layer = 0) const;
void uploadImageDataSized(const GPUImage& image, const void* pixelData, std::size_t byteSize, std::uint32_t layer) const;
GPUImage createImageRaw(const vkutil::CreateImageInfo& createInfo, std::optional<VmaAllocationCreateInfo> customAllocationCreateInfo = std::nullopt) const;
GPUImage loadImageFromFileRaw(const std::filesystem::path& path, VkFormat format, VkImageUsageFlags usage, bool mipMap) const;
[[nodiscard]] GPUImage createImageRaw(const vkutil::CreateImageInfo& createInfo, std::optional<VmaAllocationCreateInfo> customAllocationCreateInfo = std::nullopt) const;
GPUImage loadImageFromFileRaw(const std::filesystem::path& path, VkImageUsageFlags usage, bool mipMap, TextureIntent intent) const;
void destroyImage(const GPUImage& image) const;
ImageID getWhiteTextureID() { return whiteImageId; }
[[nodiscard]] ImageID getWhiteTextureID() const { return whiteImageId; }
private:
vkb::Instance instance;
@@ -129,17 +131,16 @@ private:
static uint32_t BytesPerTexel(VkFormat fmt) {
switch (fmt) {
case VK_FORMAT_R8_UNORM: return 1;
case VK_FORMAT_R8G8B8A8_UNORM: return 4;
case VK_FORMAT_B8G8R8A8_SRGB: return 4;
case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
case VK_FORMAT_R32G32B32A32_SFLOAT: return 16;
case VK_FORMAT_R8G8B8A8_SRGB: return 4;
case VK_FORMAT_R8_UNORM: return 1;
case VK_FORMAT_R8G8B8A8_UNORM: return 4;
case VK_FORMAT_B8G8R8A8_SRGB: return 4;
case VK_FORMAT_R16G16B16A16_SFLOAT: return 8;
case VK_FORMAT_R32G32B32A32_SFLOAT: return 16;
case VK_FORMAT_R8G8B8A8_SRGB: return 4;
default:
throw std::runtime_error("BytesPerTexel: unsupported format");
}
}
};

View File

@@ -7,11 +7,10 @@
#include <unordered_map>
#include <vector>
#include <destrum/Graphics/ids.h>
#include <destrum/Graphics/GPUImage.h>
#include <destrum/Graphics/BindlessSetManager.h>
// #include <destrum/Graphics/Vulkan/BindlessSetManager.h>
#include <destrum/Graphics/GPUImage.h>
#include <destrum/Graphics/ids.h>
#include <destrum/Graphics/TextureIntent.h>
class GfxDevice;
@@ -19,19 +18,18 @@ class ImageCache {
friend class ResourcesInspector;
public:
ImageCache(GfxDevice& gfxDevice);
explicit ImageCache(GfxDevice& gfxDevice);
ImageID loadImageFromFile(
const std::filesystem::path& path,
VkFormat format,
VkImageUsageFlags usage,
bool mipMap);
bool mipMap, TextureIntent intent = TextureIntent::ColorSrgb);
ImageID addImage(GPUImage image);
ImageID addImage(ImageID id, GPUImage image);
const GPUImage& getImage(ImageID id) const;
[[nodiscard]] const GPUImage& getImage(ImageID id) const;
ImageID getFreeImageId() const;
[[nodiscard]] ImageID getFreeImageId() const;
void destroyImages();
@@ -55,7 +53,7 @@ private:
struct LoadedImageInfo {
std::filesystem::path path;
VkFormat format;
TextureIntent intent;
VkImageUsageFlags usage;
bool mipMap;
};

View File

@@ -46,12 +46,15 @@ public:
void setSkyboxTexture(ImageID skyboxImageId);
void flushMaterialUpdates(GfxDevice& gfxDevice);
private:
void createDrawImage(GfxDevice& gfxDevice, const glm::ivec2& drawImageSize, bool firstCreate);
MeshCache& meshCache;
MaterialCache& materialCache;
std::vector<MaterialID> pendingMaterialUploads;
std::vector<MeshDrawCommand> meshDrawCommands;
std::vector<std::size_t> sortedMeshDrawCommands;

View File

@@ -0,0 +1,11 @@
#ifndef TEXTUREINTENT_H
#define TEXTUREINTENT_H
#include <cstdint>
enum class TextureIntent : std::uint8_t {
ColorSrgb, // albedo/UI
DataLinear, // normal/roughness/metalness/etc
};
#endif //TEXTUREINTENT_H

View File

@@ -51,6 +51,12 @@ namespace vkutil {
int destH,
VkFilter filter);
void bufferHostWriteToShaderReadBarrier(
VkCommandBuffer cmd,
VkBuffer buffer,
VkDeviceSize offset = 0,
VkDeviceSize size = VK_WHOLE_SIZE);
void addDebugLabel(VkDevice device, VkImage image, const char* label);
void addDebugLabel(VkDevice device, VkImageView imageView, const char* label);
void addDebugLabel(VkDevice device, VkShaderModule shaderModule, const char* label);
@@ -76,6 +82,5 @@ namespace vkutil {
RenderInfo createRenderingInfo(const RenderingInfoParams& params);
VkShaderModule loadShaderModule(const std::filesystem::path& path, VkDevice device);
}
#endif //UTIL_H

View File

@@ -1,36 +1,73 @@
#ifndef IMAGELOADER_H
#define IMAGELOADER_H
#include <filesystem>
#include <filesystem>
#include <cstddef>
#include <vulkan/vulkan.h>
#include "destrum/Graphics/TextureIntent.h"
struct ImageData {
ImageData() = default;
~ImageData();
// move only
ImageData(ImageData&& o) = default;
ImageData& operator=(ImageData&& o) = default;
// move only (CUSTOM!)
ImageData(ImageData&& o) noexcept { *this = std::move(o); }
// no copies
ImageData(const ImageData& o) = delete;
ImageData& operator=(const ImageData& o) = delete;
// data
ImageData& operator=(ImageData&& o) noexcept {
if (this == &o) return *this;
// free current contents first
this->~ImageData();
// steal
pixels = o.pixels;
hdrPixels = o.hdrPixels;
hdr = o.hdr;
width = o.width;
height = o.height;
channels = o.channels;
comp = o.comp;
shouldSTBFree = o.shouldSTBFree;
shouldEXRFree = o.shouldEXRFree;
vkFormat = o.vkFormat;
byteSize = o.byteSize;
// neuter source so its destructor won't free our memory
o.pixels = nullptr;
o.hdrPixels = nullptr;
o.shouldSTBFree = false;
o.shouldEXRFree = false;
o.hdr = false;
o.width = o.height = o.channels = o.comp = 0;
o.vkFormat = VK_FORMAT_UNDEFINED;
o.byteSize = 0;
return *this;
}
ImageData(const ImageData&) = delete;
ImageData& operator=(const ImageData&) = delete;
unsigned char* pixels{nullptr};
float* hdrPixels{nullptr};
bool hdr{false};
int width{0};
int height{0};
int channels{0};
// HDR only
float* hdrPixels{nullptr};
bool hdr{false};
int comp{0};
bool shouldSTBFree{false};
bool shouldEXRFree{false};
VkFormat vkFormat{VK_FORMAT_UNDEFINED};
std::size_t byteSize{0};
};
namespace util {
ImageData loadImage(const std::filesystem::path& p);
ImageData loadImage(const std::filesystem::path& p, TextureIntent intent);
}
#endif //IMAGELOADER_H
#endif // IMAGELOADER_H