Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion examples/imgui_usage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ if (imgui_SOURCE_DIR)
set_target_properties(imgui PROPERTIES FOLDER "dependencies")
endif()

## STB_IMAGE ###############################################################

FetchContent_Declare(stb_image
GIT_REPOSITORY https://github.com/Thomas-Chqt/stb_image.git
GIT_TAG a09b799a2ba95c14f511493db4ea59811b2fcc97
GIT_SHALLOW 1
GIT_PROGRESS TRUE
FIND_PACKAGE_ARGS
)
FetchContent_MakeAvailable(stb_image)
if (stb_image_SOURCE_DIR)
set_target_properties(stb_image PROPERTIES FOLDER "dependencies")
endif()

##################################################################

add_executable(imgui_usage)
Expand Down Expand Up @@ -86,9 +100,10 @@ target_include_directories(imgui_usage PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
if(CMAKE_GENERATOR STREQUAL "Xcode")
target_compile_definitions(imgui_usage PRIVATE "__XCODE__")
endif()
target_compile_definitions(imgui_usage PRIVATE "RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/resources\"")
target_compile_definitions(imgui_usage PRIVATE "GLFW_INCLUDE_NONE")

target_link_libraries(imgui_usage PRIVATE Graphics imgui)
target_link_libraries(imgui_usage PRIVATE Graphics imgui stb_image)

if(APPLE AND NOT CMAKE_GENERATOR STREQUAL "Xcode")
set(CODESIGN_IDENTITY "-" CACHE STRING "Codesigning identity for imgui_usage")
Expand Down
71 changes: 60 additions & 11 deletions examples/imgui_usage/imgui_usage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@
#include "Graphics/Surface.hpp"
#include "Graphics/Enums.hpp"
#include "Graphics/Swapchain.hpp"
#include "imgui.h"
#include "Graphics/Texture.hpp"

#include <GLFW/glfw3.h>
#include <imgui.h>
#include <backends/imgui_impl_glfw.h>
#include <stb_image/stb_image.h>

#include <memory>
#include <cassert>
#include <cstdint>
#include <cstring>

#if __XCODE__
#include <unistd.h>
Expand Down Expand Up @@ -99,6 +102,41 @@ class Application
m_commandBufferPools.at(i) = m_device->newCommandBufferPool();
}

int width = 0;
int height = 0;
stbi_uc* textureBytes = stbi_load(RESOURCE_DIR"/MyImage01.jpg", &width, &height, nullptr, STBI_rgb_alpha);
assert(textureBytes);

m_texture = m_device->newTexture(gfx::Texture::Descriptor{
.type = gfx::TextureType::texture2d,
.width = static_cast<uint32_t>(width),
.height = static_cast<uint32_t>(height),
.pixelFormat = gfx::PixelFormat::RGBA8Unorm,
.usages = gfx::TextureUsage::copyDestination | gfx::TextureUsage::shaderRead,
.storageMode = gfx::ResourceStorageMode::deviceLocal
});
assert(m_texture);

std::shared_ptr<gfx::Buffer> stagingBuffer = m_device->newBuffer(gfx::Buffer::Descriptor{
.size = static_cast<size_t>(width) * static_cast<size_t>(height) * pixelFormatSize(gfx::PixelFormat::RGBA8Unorm),
.usages = gfx::BufferUsage::copySource,
.storageMode = gfx::ResourceStorageMode::hostVisible
});
assert(stagingBuffer);

auto* bufferData = stagingBuffer->content<stbi_uc>();
std::memcpy(bufferData, textureBytes, stagingBuffer->size());

stbi_image_free(textureBytes);

std::shared_ptr<gfx::CommandBuffer> commandBuffer = m_commandBufferPools.at(m_frameIdx)->get();
commandBuffer->beginBlitPass();
{
commandBuffer->copyBufferToTexture(stagingBuffer, 0, m_texture, 0);
}
commandBuffer->endBlitPass();
m_device->submitCommandBuffers(commandBuffer);

ImGui::CreateContext();

ImGuiIO& io = ImGui::GetIO();
Expand All @@ -116,6 +154,7 @@ class Application
}

m_device->imguiInit({gfx::PixelFormat::BGRA8Unorm});

}

void loop()
Expand Down Expand Up @@ -144,16 +183,21 @@ class Application

if (m_lastCommandBuffers.at(m_frameIdx) != nullptr) {
m_device->waitCommandBuffer(*m_lastCommandBuffers.at(m_frameIdx));
m_lastCommandBuffers.at(m_frameIdx).reset();
m_commandBufferPools.at(m_frameIdx)->reset();
}

m_device->imguiNewFrame();
ImGui_ImplGlfw_NewFrame();

ImGui::NewFrame();
{
static bool showDemoWindow = true;
ImGui::ShowDemoWindow(&showDemoWindow);
ImGui::ShowDemoWindow();

ImGui::Begin("texture");
if (m_texture->imTextureId().has_value() == false)
m_texture->initImTextureId();
ImGui::Image(*m_texture->imTextureId(), ImVec2((float)m_texture->width(), (float)m_texture->height()));
ImGui::End();
}
ImGui::Render();

Expand All @@ -177,28 +221,31 @@ class Application

commandBuffer->beginRenderPass(framebuffer);
{
commandBuffer->addSampledTexture(m_texture);
commandBuffer->imGuiRenderDrawData(ImGui::GetDrawData());
}
commandBuffer->endRenderPass();
commandBuffer->presentDrawable(drawable);

m_lastCommandBuffers.at(m_frameIdx) = commandBuffer;
m_device->submitCommandBuffers(commandBuffer);
m_lastCommandBuffers.at(m_frameIdx) = commandBuffer.get();

if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();

m_frameIdx = (m_frameIdx + 1) % maxFrameInFlight;
}
}

void clean()
{
m_texture.reset();

m_device->waitIdle();
for (auto& pool : m_commandBufferPools)
pool->reset();
m_device->imguiShutdown();

ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(m_window);
Expand All @@ -212,9 +259,11 @@ class Application
std::unique_ptr<gfx::Device> m_device;
std::unique_ptr<gfx::Swapchain> m_swapchain;

std::shared_ptr<gfx::Texture> m_texture;

uint8_t m_frameIdx = 0;
std::array<std::unique_ptr<gfx::CommandBufferPool>, maxFrameInFlight> m_commandBufferPools;
std::array<std::shared_ptr<gfx::CommandBuffer>, maxFrameInFlight> m_lastCommandBuffers = {};
std::array<gfx::CommandBuffer*, maxFrameInFlight> m_lastCommandBuffers = {};
};

int main()
Expand Down
Binary file added examples/imgui_usage/resources/MyImage01.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions include/Graphics/CommandBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class CommandBuffer

virtual void presentDrawable(const std::shared_ptr<Drawable>&) = 0;

virtual void addSampledTexture(const std::shared_ptr<Texture>&) = 0; // for imgui

virtual ~CommandBuffer() = default;

protected:
Expand Down
6 changes: 6 additions & 0 deletions include/Graphics/Texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "Graphics/Enums.hpp"

#include <cstdint>
#include <optional>

namespace gfx
{
Expand Down Expand Up @@ -41,6 +42,11 @@ class Texture
virtual TextureUsages usages() const = 0;
virtual ResourceStorageMode storageMode() const = 0;

#if defined (GFX_IMGUI_ENABLED)
virtual void initImTextureId() = 0;
virtual std::optional<uint64_t> imTextureId() const = 0;
#endif

virtual ~Texture() = default;

protected:
Expand Down
2 changes: 2 additions & 0 deletions src/Metal/MetalCommandBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class MetalCommandBuffer : public CommandBuffer

void presentDrawable(const std::shared_ptr<Drawable>&) override;

void addSampledTexture(const std::shared_ptr<Texture>&) override;


inline id<MTLCommandBuffer> mtlCommandBuffer() const { return m_mtlCommandBuffer; }
inline id<MTLCommandEncoder> commandEncoder() const { return m_commandEncoder; }
Expand Down
7 changes: 7 additions & 0 deletions src/Metal/MetalCommandBuffer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "Metal/MetalBuffer.hpp"
#include "Metal/MetalSampler.hpp"
#include "Metal/MetalTexture.hpp"
#include <memory>
#if defined(GFX_IMGUI_ENABLED)
# include "Metal/imgui_impl_metal.h"
#endif
Expand Down Expand Up @@ -267,6 +268,12 @@
[m_mtlCommandBuffer presentDrawable:drawable->mtlDrawable()];
}}

void MetalCommandBuffer::addSampledTexture(const std::shared_ptr<Texture>& aTexture)
{
auto texture = std::dynamic_pointer_cast<MetalTexture>(aTexture);
m_usedTextures.insert(texture);
}

MetalCommandBuffer& MetalCommandBuffer::operator = (MetalCommandBuffer&& other) noexcept { @autoreleasepool
{
if (this != &other)
Expand Down
5 changes: 5 additions & 0 deletions src/Metal/MetalTexture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class MetalTexture : public Texture
inline TextureUsages usages() const override { return m_usages; };
inline ResourceStorageMode storageMode() const override { return m_storageMode; };

#if defined (GFX_IMGUI_ENABLED)
inline void initImTextureId() override {} // no-op
inline std::optional<uint64_t> imTextureId() const override { return std::bit_cast<uint64_t>((__bridge void*)m_mtlTexture); }
#endif

inline id<MTLTexture> mtltexture() const { return m_mtlTexture; }
inline void setMtlTexture(const id<MTLTexture>& t) { m_mtlTexture = t; }

Expand Down
30 changes: 30 additions & 0 deletions src/Vulkan/VulkanCommandBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "Vulkan/VulkanSampler.hpp"
#include "Vulkan/VulkanTexture.hpp"
#include "Vulkan/VulkanEnums.hpp"
#include <memory>
#if defined(GFX_IMGUI_ENABLED)
# include "Vulkan/imgui_impl_vulkan.h"
#endif
Expand Down Expand Up @@ -539,4 +540,33 @@ void VulkanCommandBuffer::presentDrawable(const std::shared_ptr<Drawable>& aDraw
m_presentedDrawables.insert(drawable);
}

void VulkanCommandBuffer::addSampledTexture(const std::shared_ptr<Texture>& aTexture)
{
auto texture = std::dynamic_pointer_cast<VulkanTexture>(aTexture);
std::vector<vk::ImageMemoryBarrier2> imageMemoryBarriers;

ImageSyncRequest syncReq{};
syncReq.stageMask = vk::PipelineStageFlagBits2::eFragmentShader;
syncReq.accessMask = vk::AccessFlagBits2::eShaderRead;
syncReq.layout = vk::ImageLayout::eShaderReadOnlyOptimal;
syncReq.preserveContent = true;

auto it = m_imageFinalSyncStates.find(texture);
if (it != m_imageFinalSyncStates.end()) {
auto barrier = syncImage(it->second, syncReq); // will update the final sync state
if (barrier.has_value()) {
barrier->setImage(texture->vkImage());
barrier->setSubresourceRange(texture->subresourceRange());
imageMemoryBarriers.push_back(*barrier);
}
} else {
auto [it1, res1] = m_imageSyncRequests.insert(std::make_pair(texture, syncReq));
assert(res1);
(void)res1;
auto [it2, res2] = m_imageFinalSyncStates.insert(std::make_pair(texture, imageStateAfterSync(syncReq)));
assert(res2);
(void)res2;
}
}

}
4 changes: 4 additions & 0 deletions src/Vulkan/VulkanCommandBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
#include "Graphics/Buffer.hpp"
#include "Graphics/ParameterBlock.hpp"

#include "Graphics/Texture.hpp"
#include "Vulkan/VulkanBuffer.hpp"
#include "Vulkan/VulkanGraphicsPipeline.hpp"
#include "Vulkan/VulkanSampler.hpp"
#include "Vulkan/VulkanTexture.hpp"
#include "Vulkan/VulkanDrawable.hpp"
#include "Vulkan/VulkanParameterBlock.hpp"
#include <memory>

namespace gfx
{
Expand Down Expand Up @@ -64,6 +66,8 @@ class VulkanCommandBuffer : public CommandBuffer

void presentDrawable(const std::shared_ptr<Drawable>&) override;

void addSampledTexture(const std::shared_ptr<Texture>&) override; // for imgui


const vk::CommandBuffer& vkCommandBuffer() const { return m_vkCommandBuffer; }

Expand Down
25 changes: 25 additions & 0 deletions src/Vulkan/VulkanTexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@

#include "Vulkan/VulkanTexture.hpp"
#include "Graphics/Enums.hpp"
#include "Graphics/Sampler.hpp"
#include "Graphics/Texture.hpp"
#include "Vulkan/VulkanDevice.hpp"
#include "Vulkan/VulkanEnums.hpp"
#include "Vulkan/VulkanSampler.hpp"

#if defined (GFX_IMGUI_ENABLED)
#include "imgui_impl_vulkan.h"
#endif

namespace gfx
{
Expand Down Expand Up @@ -98,8 +105,26 @@ VulkanTexture::VulkanTexture(const VulkanDevice* device, const Texture::Descript
m_vkImageView = m_device->vkDevice().createImageView(imageViewCreateInfo);
}

#if defined (GFX_IMGUI_ENABLED)
void VulkanTexture::initImTextureId()
{
std::shared_ptr<Sampler> aSampler = m_device->newSampler(Sampler::Descriptor{});
auto vulkanSampler = std::dynamic_pointer_cast<VulkanSampler>(aSampler);
assert(vulkanSampler);

m_imTextureIdSampler = vulkanSampler;
if (m_imTextureId.has_value())
ImGui_ImplVulkan_RemoveTexture(std::bit_cast<VkDescriptorSet>(*m_imTextureId));
m_imTextureId = std::bit_cast<uint64_t>(ImGui_ImplVulkan_AddTexture(m_imTextureIdSampler->vkSampler(), m_vkImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
}
#endif

VulkanTexture::~VulkanTexture()
{
#if defined (GFX_IMGUI_ENABLED)
if (m_imTextureId.has_value())
ImGui_ImplVulkan_RemoveTexture(std::bit_cast<VkDescriptorSet>(*m_imTextureId));
#endif
m_device->vkDevice().destroyImageView(m_vkImageView);
if (m_allocation != VK_NULL_HANDLE)
vmaDestroyImage(m_device->allocator(), m_vkImage, m_allocation);
Expand Down
12 changes: 12 additions & 0 deletions src/Vulkan/VulkanTexture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@

#include "Graphics/Texture.hpp"
#include "Graphics/Enums.hpp"
#include "Graphics/Sampler.hpp"

#include "Vulkan/Sync.hpp"
#include "Vulkan/VulkanSampler.hpp"

namespace gfx
{
Expand All @@ -37,6 +39,11 @@ class VulkanTexture : public Texture
inline TextureUsages usages() const override { return m_usages; };
inline ResourceStorageMode storageMode() const override { return m_storageMode; };

#if defined (GFX_IMGUI_ENABLED)
void initImTextureId() override;
inline std::optional<uint64_t> imTextureId() const override { return m_imTextureId; }
#endif

inline const vk::Image& vkImage() const { return m_vkImage; }

inline const vk::ImageSubresourceRange& subresourceRange() const { return m_subresourceRange; }
Expand All @@ -63,6 +70,11 @@ class VulkanTexture : public Texture

ImageSyncState m_syncState;

#if defined (GFX_IMGUI_ENABLED)
std::optional<uint64_t> m_imTextureId;
#endif
std::shared_ptr<VulkanSampler> m_imTextureIdSampler;

public:
VulkanTexture& operator=(const VulkanTexture&) = delete;
VulkanTexture& operator=(VulkanTexture&&) = delete;
Expand Down