159 lines
4.9 KiB
C++
159 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include "common.hpp"
|
|
#include <optional>
|
|
#include <vector>
|
|
#include <cmath>
|
|
|
|
namespace render {
|
|
|
|
/// Abstract raw image
|
|
class Image {
|
|
public:
|
|
virtual ~Image() { }
|
|
|
|
struct frame {
|
|
uint32_t height;
|
|
uint32_t width;
|
|
};
|
|
// NOTE: matches VkFormat
|
|
enum class Format {
|
|
/// DXT3 RGBA SRGB
|
|
BC2 = 136,
|
|
/// DXT5 RGBA SRGB
|
|
BC3 = 138,
|
|
// MAYBE: R8G8B8A8
|
|
// MAYBE: For HDR BC6H_SFLOAT = 144,
|
|
};
|
|
|
|
// NOTE: matches VkImageLayout
|
|
enum class Layout {
|
|
UNDEFINED = 0,
|
|
GENERAL = 1,
|
|
COLOR_ATTACHMENT = 2,
|
|
DEPTH_STENCIL_ATTACHMENT = 3,
|
|
DEPTH_STENCIL_READ_ONLY = 4,
|
|
SHADER_READ_ONLY = 5,
|
|
TRANSFER_SRC = 6,
|
|
TRANSFER_DST = 7,
|
|
PREINITIALIZED = 8,
|
|
DEPTH_READ_ONLY_STENCIL_ATTACHMENT = 1000117000,
|
|
DEPTH_ATTACHMENT_STENCIL_READ_ONLY = 1000117001,
|
|
DEPTH_ATTACHMENT = 1000241000,
|
|
DEPTH_READ_ONLY = 1000241001,
|
|
STENCIL_ATTACHMENT = 1000241002,
|
|
STENCIL_READ_ONLY = 1000241003
|
|
};
|
|
// NOTE: matches VkImageUsageFlags
|
|
enum class Usage {
|
|
TRANSFER_SRC = 0x00000001,
|
|
TRANSFER_DST = 0x00000002,
|
|
SAMPLED = 0x00000004,
|
|
STORAGE = 0x00000008,
|
|
COLOR_ATTACHMENT = 0x00000010,
|
|
DEPTH_STENCIL_ATTACHMENT = 0x00000020,
|
|
TRANSIENT_ATTACHMENT = 0x00000040,
|
|
INPUT_ATTACHMENT = 0x00000080,
|
|
};
|
|
friend inline Usage operator|(Usage a, Usage b) {
|
|
return static_cast<Usage>(static_cast<int>(a) | static_cast<int>(b));
|
|
}
|
|
//NOTE: matches VkImageAspectFlags
|
|
enum class Aspect {
|
|
COLOR = 0x00000001,
|
|
DEPTH = 0x00000002,
|
|
STENCIL = 0x00000004,
|
|
METADATA = 0x00000008
|
|
};
|
|
|
|
struct properties {
|
|
frame size;
|
|
uint32_t mipmapLevels;
|
|
Format format;
|
|
};
|
|
struct requirement: properties {
|
|
requirement(const properties& props, Layout layout, Usage usage, Aspect aspect,
|
|
int samples = 1, uint32_t layers = 1, bool cube = false, bool optimal = true):
|
|
properties(props), layout(layout), usage(usage), aspect(aspect), samples(samples),
|
|
layers(layers), cube(cube), optimal(optimal)
|
|
{
|
|
assert(samples > 0 && (std::ceil(std::log2(samples)) == std::floor(std::log2(samples))) && "Samples must be pow2");
|
|
assert(!cube || layers == 6);
|
|
}
|
|
Layout layout;
|
|
Usage usage;
|
|
Aspect aspect;
|
|
//NOTE: matches VkSampleCountFlagBits
|
|
int samples;
|
|
uint32_t layers;
|
|
bool cube;
|
|
bool optimal;
|
|
|
|
static requirement Texture(const properties &props, uint32_t arraySize = 1, bool cube = false) {
|
|
return requirement(props, Layout::SHADER_READ_ONLY, Usage::SAMPLED, Aspect::COLOR, 1, arraySize, cube); }
|
|
};
|
|
|
|
static std::optional<properties> Read(const std::string&, std::vector<unsigned char>& data);
|
|
};
|
|
|
|
/// Const image (single texture2D) with sampler
|
|
class Texture: public Image {
|
|
public:
|
|
// NOTE: matches VkSamplerAddressMode
|
|
enum class Wrap {
|
|
REPEAT = 0,
|
|
MIRRORED_REPEAT = 1,
|
|
CLAMP_TO_EDGE = 2,
|
|
CLAMP_TO_BORDER = 3,
|
|
};
|
|
struct sampling {
|
|
bool magLinear = true;
|
|
bool minLinear = true;
|
|
Wrap wrap = Wrap::MIRRORED_REPEAT;
|
|
int anisotropy = 0;
|
|
bool mipmap = true;
|
|
};
|
|
|
|
/// Only supports dds files
|
|
/// DXT3(BC2) DXT5(BC3)
|
|
static _FORCE_INLINE_ std::unique_ptr<Texture> LoadFromFile(const std::string &path, const sampling &props) {
|
|
assert(loadFunc != nullptr && "Uninitialized renderer");
|
|
return loadFunc(path, props);
|
|
}
|
|
|
|
protected:
|
|
static std::unique_ptr<Texture> (*loadFunc)(const std::string&, const sampling&);
|
|
};
|
|
|
|
/// Const 6 dept image (single textureCube) with sampler
|
|
class TextureCube: public Image {
|
|
public:
|
|
/// Only supports dds files
|
|
/// DXT3(BC2) DXT5(BC3)
|
|
static _FORCE_INLINE_ std::unique_ptr<TextureCube> LoadFromFiles(const std::array<std::string, 6> &paths, const Texture::sampling &props) {
|
|
assert(loadFunc != nullptr && "Uninitialized renderer");
|
|
return loadFunc(paths, props);
|
|
}
|
|
|
|
protected:
|
|
static std::unique_ptr<TextureCube> (*loadFunc)(const std::array<std::string, 6>&, const Texture::sampling&);
|
|
};
|
|
|
|
/// Const image array (textureArray) with sampler
|
|
class TextureArray: public Image {
|
|
public:
|
|
/// Only supports dds files
|
|
/// DXT3(BC2) DXT5(BC3)
|
|
static _FORCE_INLINE_ std::unique_ptr<TextureArray> LoadFromFiles(const std::vector<std::string> &paths, const Texture::sampling &props) {
|
|
assert(loadFunc != nullptr && "Uninitialized renderer");
|
|
return loadFunc(paths, props);
|
|
}
|
|
|
|
constexpr uint32_t getSize() const { return size; }
|
|
|
|
protected:
|
|
TextureArray(uint32_t size): size(size) { }
|
|
uint32_t size;
|
|
static std::unique_ptr<TextureArray> (*loadFunc)(const std::vector<std::string>&, const Texture::sampling&);
|
|
};
|
|
} |