Skip to content

Commit 06bc885

Browse files
Initial implementation of texture views
1 parent 0c837b6 commit 06bc885

File tree

3 files changed

+114
-2
lines changed

3 files changed

+114
-2
lines changed

lvk/LVK.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,15 @@ struct TextureDesc {
800800
const char* debugName = "";
801801
};
802802

803+
struct TextureViewDesc {
804+
TextureType type = TextureType_2D;
805+
uint32_t layer = 0;
806+
uint32_t numLayers = 1;
807+
uint32_t mipLevel = 0;
808+
uint32_t numMipLevels = 1;
809+
ComponentMapping swizzle = {};
810+
};
811+
803812
enum AccelStructType : uint8_t {
804813
AccelStructType_Invalid = 0,
805814
AccelStructType_TLAS = 1,
@@ -995,6 +1004,10 @@ class IContext {
9951004
[[nodiscard]] virtual Holder<TextureHandle> createTexture(const TextureDesc& desc,
9961005
const char* debugName = nullptr,
9971006
Result* outResult = nullptr) = 0;
1007+
[[nodiscard]] virtual Holder<TextureHandle> createTextureView(TextureHandle texture,
1008+
const TextureViewDesc& desc,
1009+
const char* debugName = nullptr,
1010+
Result* outResult = nullptr) = 0;
9981011
[[nodiscard]] virtual Holder<ComputePipelineHandle> createComputePipeline(const ComputePipelineDesc& desc,
9991012
Result* outResult = nullptr) = 0;
10001013
[[nodiscard]] virtual Holder<RenderPipelineHandle> createRenderPipeline(const RenderPipelineDesc& desc, Result* outResult = nullptr) = 0;

lvk/vulkan/VulkanClasses.cpp

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3852,8 +3852,7 @@ lvk::Holder<lvk::TextureHandle> lvk::VulkanContext::createTexture(const TextureD
38523852
vkDevice_, vkImageViewType, vkFormat, aspect, 0, VK_REMAINING_MIP_LEVELS, 0, numLayers, mapping, ycbcrInfo, debugNameImageView);
38533853

38543854
if (image.vkUsageFlags_ & VK_IMAGE_USAGE_STORAGE_BIT) {
3855-
if (desc.swizzle.r != Swizzle_Default || desc.swizzle.g != Swizzle_Default || desc.swizzle.b != Swizzle_Default ||
3856-
desc.swizzle.a != Swizzle_Default) {
3855+
if (!desc.swizzle.identity()) {
38573856
// use identity swizzle for storage images
38583857
image.imageViewStorage_ = image.createImageView(
38593858
vkDevice_, vkImageViewType, vkFormat, aspect, 0, VK_REMAINING_MIP_LEVELS, 0, numLayers, {}, ycbcrInfo, debugNameImageView);
@@ -3889,6 +3888,102 @@ lvk::Holder<lvk::TextureHandle> lvk::VulkanContext::createTexture(const TextureD
38893888
return {this, handle};
38903889
}
38913890

3891+
lvk::Holder<lvk::TextureHandle> lvk::VulkanContext::createTextureView(lvk::TextureHandle texture,
3892+
const TextureViewDesc& desc,
3893+
const char* debugName,
3894+
Result* outResult) {
3895+
LVK_ASSERT(texture.valid());
3896+
3897+
// TODO: Texture views are still work-in-progress. Beware!
3898+
3899+
const VulkanImage* baseImage = texturesPool_.get(texture);
3900+
3901+
VulkanImage newImage = *baseImage;
3902+
3903+
// drop old existing views - the baseImage owns them
3904+
memset(&newImage.imageViewStorage_, 0, sizeof(newImage.imageViewStorage_));
3905+
memset(&newImage.imageViewForFramebuffer_, 0, sizeof(newImage.imageViewForFramebuffer_));
3906+
3907+
newImage.isSwapchainImage_ = true; // TODO: rename this to `isExternallyManaged` etc
3908+
3909+
VkImageAspectFlags aspect = 0;
3910+
if (newImage.isDepthFormat_ || newImage.isStencilFormat_) {
3911+
if (newImage.isDepthFormat_) {
3912+
aspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
3913+
} else if (newImage.isStencilFormat_) {
3914+
aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
3915+
}
3916+
} else {
3917+
aspect = VK_IMAGE_ASPECT_COLOR_BIT;
3918+
}
3919+
3920+
VkImageViewType vkImageViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
3921+
switch (desc.type) {
3922+
case TextureType_2D:
3923+
vkImageViewType = desc.numLayers > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
3924+
break;
3925+
case TextureType_3D:
3926+
vkImageViewType = VK_IMAGE_VIEW_TYPE_3D;
3927+
break;
3928+
case TextureType_Cube:
3929+
vkImageViewType = desc.numLayers > 1 ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE;
3930+
break;
3931+
default:
3932+
LVK_ASSERT_MSG(false, "Code should NOT be reached");
3933+
Result::setResult(outResult, Result::Code::RuntimeError, "Unsupported texture view type");
3934+
return {};
3935+
}
3936+
3937+
const VkComponentMapping mapping = {
3938+
.r = VkComponentSwizzle(desc.swizzle.r),
3939+
.g = VkComponentSwizzle(desc.swizzle.g),
3940+
.b = VkComponentSwizzle(desc.swizzle.b),
3941+
.a = VkComponentSwizzle(desc.swizzle.a),
3942+
};
3943+
3944+
newImage.imageView_ = newImage.createImageView(vkDevice_,
3945+
vkImageViewType,
3946+
newImage.vkImageFormat_,
3947+
aspect,
3948+
desc.mipLevel,
3949+
desc.numMipLevels,
3950+
desc.layer,
3951+
desc.numLayers,
3952+
mapping,
3953+
nullptr,
3954+
debugName);
3955+
3956+
if (!LVK_VERIFY(newImage.imageView_ != VK_NULL_HANDLE)) {
3957+
Result::setResult(outResult, Result::Code::RuntimeError, "Cannot create VkImageView");
3958+
return {};
3959+
}
3960+
3961+
if (newImage.vkUsageFlags_ & VK_IMAGE_USAGE_STORAGE_BIT) {
3962+
if (!desc.swizzle.identity()) {
3963+
// use identity swizzle for storage images
3964+
newImage.imageViewStorage_ = newImage.createImageView(vkDevice_,
3965+
vkImageViewType,
3966+
newImage.vkImageFormat_,
3967+
aspect,
3968+
0,
3969+
VK_REMAINING_MIP_LEVELS,
3970+
0,
3971+
desc.numLayers,
3972+
{},
3973+
nullptr,
3974+
debugName);
3975+
LVK_ASSERT(newImage.imageViewStorage_ != VK_NULL_HANDLE);
3976+
}
3977+
}
3978+
3979+
TextureHandle handle = texturesPool_.create(std::move(newImage));
3980+
3981+
awaitingCreation_ = true;
3982+
3983+
return {this, handle};
3984+
}
3985+
3986+
38923987
lvk::AccelStructHandle lvk::VulkanContext::createBLAS(const AccelStructDesc& desc, Result* outResult) {
38933988
LVK_ASSERT(desc.type == AccelStructType_BLAS);
38943989
LVK_ASSERT(desc.geometryType == AccelStructGeomType_Triangles);

lvk/vulkan/VulkanClasses.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,10 @@ class VulkanContext final : public IContext {
486486
Holder<BufferHandle> createBuffer(const BufferDesc& desc, Result* outResult) override;
487487
Holder<SamplerHandle> createSampler(const SamplerStateDesc& desc, Result* outResult) override;
488488
Holder<TextureHandle> createTexture(const TextureDesc& desc, const char* debugName, Result* outResult) override;
489+
Holder<TextureHandle> createTextureView(TextureHandle texture,
490+
const TextureViewDesc& desc,
491+
const char* debugName,
492+
Result* outResult) override;
489493

490494
Holder<ComputePipelineHandle> createComputePipeline(const ComputePipelineDesc& desc, Result* outResult) override;
491495
Holder<RenderPipelineHandle> createRenderPipeline(const RenderPipelineDesc& desc, Result* outResult) override;

0 commit comments

Comments
 (0)