Skip to content

Commit

Permalink
igl | vulkan | Implement ResourcesBinder::bindStorageTexture()
Browse files Browse the repository at this point in the history
Differential Revision: D69332333

fbshipit-source-id: 0cfb37690ccef12fd048869194903c21704c0947
  • Loading branch information
corporateshark authored and facebook-github-bot committed Feb 8, 2025
1 parent fe6bda7 commit 16db572
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
2 changes: 1 addition & 1 deletion samples/desktop/Tiny/Tiny_MeshLarge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ void initIGL() {
#endif
#else
const igl::vulkan::VulkanContextConfig cfg = {
.terminateOnValidationError = true,
.terminateOnValidationError = false,
.enhancedShaderDebugging = false,
.enableValidation = kEnableValidationLayers,
.enableDescriptorIndexing = true,
Expand Down
46 changes: 46 additions & 0 deletions src/igl/vulkan/ResourcesBinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,52 @@ void ResourcesBinder::bindTexture(uint32_t index, igl::vulkan::Texture* tex) {
}
}

void ResourcesBinder::bindStorageImage(uint32_t index, igl::vulkan::Texture* tex) {
IGL_PROFILER_FUNCTION();

if (!IGL_DEBUG_VERIFY(index < IGL_TEXTURE_SAMPLERS_MAX)) {
IGL_DEBUG_ABORT("Invalid texture index");
return;
}

const bool isStorage = tex ? (tex->getUsage() & TextureDesc::TextureUsageBits::Storage) > 0
: false;

if (tex) {
if (!IGL_DEBUG_VERIFY(isStorage)) {
IGL_DEBUG_ABORT("Did you forget to specify TextureUsageBits::Storage on your texture?");
}
}

igl::vulkan::VulkanTexture* newTexture = tex ? &tex->getVulkanTexture() : nullptr;

#if IGL_DEBUG
if (newTexture) {
const igl::vulkan::VulkanImage& img = newTexture->image_;
IGL_DEBUG_ASSERT(img.samples_ == VK_SAMPLE_COUNT_1_BIT,
"Multisampled images cannot be sampled in shaders");
// If you trip this assert, then you are likely using an IGL texture
// that was not rendered to by IGL. If that's the case, then make sure
// the underlying image is transitioned to
// VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
IGL_DEBUG_ASSERT(img.imageLayout_ == VK_IMAGE_LAYOUT_GENERAL);
}
#endif // IGL_DEBUG

// multisampled images cannot be directly accessed from shaders
const bool isTextureAvailable =
(newTexture != nullptr) &&
((newTexture->image_.samples_ & VK_SAMPLE_COUNT_1_BIT) == VK_SAMPLE_COUNT_1_BIT);
const bool isStorageImage = isTextureAvailable && newTexture->image_.isStorageImage();

VkImageView imageView = isStorageImage ? newTexture->imageView_.vkImageView_ : VK_NULL_HANDLE;

if (bindingsStorageImages_.images[index] != imageView) {
bindingsStorageImages_.images[index] = imageView;
isDirtyFlags_ |= DirtyFlagBits_StorageImages;
}
}

void ResourcesBinder::updateBindings(VkPipelineLayout layout, const vulkan::PipelineState& state) {
IGL_PROFILER_FUNCTION_COLOR(IGL_PROFILER_COLOR_UPDATE);

Expand Down
10 changes: 9 additions & 1 deletion src/igl/vulkan/ResourcesBinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ struct BindingsTextures {
VkSampler samplers[IGL_TEXTURE_SAMPLERS_MAX] = {};
};

struct BindingsStorageImages {
VkImageView images[IGL_TEXTURE_SAMPLERS_MAX] = {};
};

/** @brief Stores uniform and storage buffer bindings, as well as bindings for textures and sampler
* states for Vulkan. This class maintains vectors for each type of shader resource available in IGL
* and records the association between binding locations (indices) and the Vulkan objects, while
Expand Down Expand Up @@ -62,6 +66,7 @@ class ResourcesBinder final {

/// @brief Binds a texture to index equal to `index`
void bindTexture(uint32_t index, igl::vulkan::Texture* tex);
void bindStorageImage(uint32_t index, igl::vulkan::Texture* tex);

/// @brief Convenience function that updates all bindings in the context for all resource types
/// that have been modified since the last time this function was called
Expand All @@ -85,15 +90,18 @@ class ResourcesBinder final {
enum DirtyFlagBits : uint8_t {
DirtyFlagBits_Textures = 1 << 0,
DirtyFlagBits_Buffers = 1 << 1,
DirtyFlagBits_StorageImages = 1 << 2,
};

private:
VulkanContext& ctx_;
VkCommandBuffer cmdBuffer_ = VK_NULL_HANDLE;
VkPipeline lastPipelineBound_ = VK_NULL_HANDLE;
uint32_t isDirtyFlags_ = DirtyFlagBits_Textures | DirtyFlagBits_Buffers;
uint32_t isDirtyFlags_ =
DirtyFlagBits_Textures | DirtyFlagBits_Buffers | DirtyFlagBits_StorageImages;
BindingsTextures bindingsTextures_;
BindingsBuffers bindingsBuffers_;
BindingsStorageImages bindingsStorageImages_;
VkPipelineBindPoint bindPoint_ = VK_PIPELINE_BIND_POINT_GRAPHICS;
VulkanImmediateCommands::SubmitHandle nextSubmitHandle_ = {};
};
Expand Down

0 comments on commit 16db572

Please sign in to comment.