Skip to content

Commit

Permalink
Add view and sampler info to image create info
Browse files Browse the repository at this point in the history
  • Loading branch information
yknishidate committed Sep 23, 2024
1 parent 32564f3 commit cc0357e
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 46 deletions.
90 changes: 53 additions & 37 deletions include/reactive/Graphics/Image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
namespace rv {
class Buffer;

struct ImageViewCreateInfo {
vk::ImageAspectFlags aspect = vk::ImageAspectFlagBits::eColor;
};

struct SamplerCreateInfo {
vk::Filter filter = vk::Filter::eLinear;
vk::SamplerAddressMode addressMode = vk::SamplerAddressMode::eRepeat;
vk::SamplerMipmapMode mipmapMode = vk::SamplerMipmapMode::eLinear;
};

// NOTE:
// Cubemap はファイルから読み込むものと想定して
// アプリ側で作成するのは 2D or 3D のみとする
Expand All @@ -14,10 +24,17 @@ struct ImageCreateInfo {

vk::Extent3D extent = {1, 1, 1};

vk::ImageType imageType = vk::ImageType::e2D;

vk::Format format;

uint32_t mipLevels = 1;

std::optional<ImageViewCreateInfo> viewInfo;

std::optional<SamplerCreateInfo> samplerInfo;

// Debug
std::string debugName{};
};

Expand Down Expand Up @@ -53,8 +70,39 @@ class Image {

~Image();

void createImageView(vk::ImageViewType _viewType = vk::ImageViewType::e2D,
vk::ImageAspectFlags _aspect = vk::ImageAspectFlagBits::eColor) {
auto getImage() const -> vk::Image { return image; }
auto getView() const -> vk::ImageView { return view; }
auto getSampler() const -> vk::Sampler { return sampler; }
auto getInfo() const -> vk::DescriptorImageInfo { return {sampler, view, layout}; }
auto getMipLevels() const -> uint32_t { return mipLevels; }
auto getAspectMask() const -> vk::ImageAspectFlags { return aspect; }
auto getLayout() const -> vk::ImageLayout { return layout; }
auto getExtent() const -> vk::Extent3D { return extent; }
auto getFormat() const -> vk::Format { return format; }
auto getLayerCount() const -> uint32_t { return layerCount; }
auto getViewType() const -> vk::ImageViewType { return viewType; }

// Ensure that data is pre-filled
// ImageLayout is implicitly shifted to ShaderReadOnlyOptimal
void generateMipmaps(const CommandBuffer& commandBuffer);

// TODO: refactor these
static auto loadFromFile(const Context& context,
const std::filesystem::path& filepath,
uint32_t mipLevels = 1,
vk::Filter _filter = vk::Filter::eLinear,
vk::SamplerAddressMode _addressMode = vk::SamplerAddressMode::eRepeat)
-> ImageHandle;

// mipmap is not supported
static auto loadFromFileHDR(const Context& context, const std::filesystem::path& filepath)
-> ImageHandle;

static auto loadFromKTX(const Context& context, const std::filesystem::path& filepath)
-> ImageHandle;

private:
void createImageView(vk::ImageViewType _viewType, vk::ImageAspectFlags _aspect) {
viewType = _viewType;
aspect = _aspect;

Expand All @@ -74,9 +122,9 @@ class Image {
view = context->getDevice().createImageView(viewInfo);
}

void createSampler(vk::Filter _filter = vk::Filter::eLinear,
vk::SamplerAddressMode _addressMode = vk::SamplerAddressMode::eRepeat,
vk::SamplerMipmapMode _mipmapMode = vk::SamplerMipmapMode::eLinear) {
void createSampler(vk::Filter _filter,
vk::SamplerAddressMode _addressMode,
vk::SamplerMipmapMode _mipmapMode) {
vk::SamplerCreateInfo samplerInfo;
samplerInfo.setMagFilter(_filter);
samplerInfo.setMinFilter(_filter);
Expand All @@ -95,38 +143,6 @@ class Image {
sampler = context->getDevice().createSampler(samplerInfo);
}

auto getImage() const -> vk::Image { return image; }
auto getView() const -> vk::ImageView { return view; }
auto getSampler() const -> vk::Sampler { return sampler; }
auto getInfo() const -> vk::DescriptorImageInfo { return {sampler, view, layout}; }
auto getMipLevels() const -> uint32_t { return mipLevels; }
auto getAspectMask() const -> vk::ImageAspectFlags { return aspect; }
auto getLayout() const -> vk::ImageLayout { return layout; }
auto getExtent() const -> vk::Extent3D { return extent; }
auto getFormat() const -> vk::Format { return format; }
auto getLayerCount() const -> uint32_t { return layerCount; }
auto getViewType() const -> vk::ImageViewType { return viewType; }

// Ensure that data is pre-filled
// ImageLayout is implicitly shifted to ShaderReadOnlyOptimal
void generateMipmaps(const CommandBuffer& commandBuffer);

// TODO: refactor these
static auto loadFromFile(const Context& context,
const std::filesystem::path& filepath,
uint32_t mipLevels = 1,
vk::Filter _filter = vk::Filter::eLinear,
vk::SamplerAddressMode _addressMode = vk::SamplerAddressMode::eRepeat)
-> ImageHandle;

// mipmap is not supported
static auto loadFromFileHDR(const Context& context, const std::filesystem::path& filepath)
-> ImageHandle;

static auto loadFromKTX(const Context& context, const std::filesystem::path& filepath)
-> ImageHandle;

private:
const Context* context = nullptr;
std::string debugName;

Expand Down
53 changes: 44 additions & 9 deletions src/Graphics/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ Image::Image(const Context& _context, const ImageCreateInfo& createInfo)
extent{createInfo.extent},
format{createInfo.format},
mipLevels{createInfo.mipLevels} {
vk::ImageType type = extent.depth == 1 ? vk::ImageType::e2D : vk::ImageType::e3D;

// Compute mipmap level
if (mipLevels == std::numeric_limits<uint32_t>::max()) {
mipLevels = calculateMipLevels(extent.width, extent.height);
Expand All @@ -32,7 +30,7 @@ Image::Image(const Context& _context, const ImageCreateInfo& createInfo)
// NOTE: initialLayout must be Undefined or PreInitialized
// NOTE: queueFamily is ignored if sharingMode is not concurrent
vk::ImageCreateInfo imageInfo;
imageInfo.setImageType(type);
imageInfo.setImageType(createInfo.imageType);
imageInfo.setFormat(format);
imageInfo.setExtent(extent);
imageInfo.setMipLevels(mipLevels);
Expand All @@ -52,6 +50,37 @@ Image::Image(const Context& _context, const ImageCreateInfo& createInfo)

context->getDevice().bindImageMemory(image, memory, 0);

// Image view
if (createInfo.viewInfo.has_value()) {
switch (createInfo.imageType) {
case vk::ImageType::e1D: {
viewType = vk::ImageViewType::e1D;
break;
}
case vk::ImageType::e2D: {
viewType = vk::ImageViewType::e2D;
break;
}
case vk::ImageType::e3D: {
viewType = vk::ImageViewType::e3D;
break;
}
default: {
viewType = {};
break;
}
}
createImageView(viewType, createInfo.viewInfo.value().aspect);
}

// Sampler
if (createInfo.samplerInfo.has_value()) {
createSampler(createInfo.samplerInfo.value().filter,
createInfo.samplerInfo.value().addressMode,
createInfo.samplerInfo.value().mipmapMode);
}

// Debug
if (!debugName.empty()) {
context->setDebugName(image, createInfo.debugName.c_str());
}
Expand Down Expand Up @@ -113,10 +142,14 @@ ImageHandle Image::loadFromFile(const Context& context,
.extent = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1},
.format = vk::Format::eR8G8B8A8Unorm,
.mipLevels = mipLevels,
.viewInfo = ImageViewCreateInfo{},
.samplerInfo =
SamplerCreateInfo{
.filter = filter,
.addressMode = addressMode,
},
.debugName = filepathStr,
});
image->createImageView();
image->createSampler(filter, addressMode);

// Copy to image
BufferHandle stagingBuffer = context.createBuffer({
Expand Down Expand Up @@ -160,9 +193,9 @@ ImageHandle Image::loadFromFileHDR(const Context& context, const std::filesystem
.usage = ImageUsage::Sampled,
.extent = {static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1},
.format = vk::Format::eR32G32B32A32Sfloat,
.viewInfo = ImageViewCreateInfo{},
.samplerInfo = SamplerCreateInfo{},
});
image->createImageView();
image->createSampler();

// Copy to image
BufferHandle stagingBuffer = context.createBuffer({
Expand Down Expand Up @@ -221,8 +254,10 @@ auto Image::loadFromKTX(const Context& context, const std::filesystem::path& fil
static_cast<vk::ImageViewType>(texture.viewType), //
texture.width, texture.height, texture.depth, //
texture.levelCount, texture.layerCount);
image->createImageView(static_cast<vk::ImageViewType>(texture.viewType));
image->createSampler();
image->createImageView(static_cast<vk::ImageViewType>(texture.viewType),
vk::ImageAspectFlagBits::eColor);
image->createSampler(vk::Filter::eLinear, vk::SamplerAddressMode::eRepeat,
vk::SamplerMipmapMode ::eNearest);

ktxTexture_Destroy(kTexture);
ktxVulkanDeviceInfo_Destruct(&kvdi);
Expand Down

0 comments on commit cc0357e

Please sign in to comment.