Skip to content

Commit

Permalink
[material] texture packing, compression and gpu upload will now be do…
Browse files Browse the repository at this point in the history
…ne on a different thread
  • Loading branch information
PanosK92 committed Nov 24, 2024
1 parent 9ef9473 commit b16ae0f
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 31 deletions.
2 changes: 1 addition & 1 deletion editor/ImGui/Implementation/ImGui_RHI.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ namespace ImGui::RHI
is_frame_texture = Renderer::GetRenderTarget(Renderer_RenderTarget::frame_output)->GetObjectId() == texture->GetObjectId();

// during engine startup, some textures might be loading in different threads
if (texture->IsGpuReady())
if (texture->GetResourceState() == ResourceState::Ready)
{
cmd_list->SetTexture(Renderer_BindingsSrv::tex, texture);

Expand Down
2 changes: 1 addition & 1 deletion editor/Widgets/FileDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ void FileDialog::ShowMiddle()
// Image
if (RHI_Texture* texture = item.GetTexture())
{
if (texture->IsGpuReady()) // This is possible for when the editor is reading from drive
if (texture->GetResourceState() == ResourceState::Ready) // This is possible for when the editor is reading from drive
{
// Compute thumbnail size
ImVec2 image_size = ImVec2(static_cast<float>(texture->GetWidth()), static_cast<float>(texture->GetHeight()));
Expand Down
2 changes: 1 addition & 1 deletion editor/Widgets/IconLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Icon::Icon(IconType type, const string& file_path)

RHI_Texture* Icon::GetTexture() const
{
if (m_texture && m_texture->IsGpuReady())
if (m_texture && m_texture->GetResourceState() == ResourceState::Ready)
{
return m_texture.get();
}
Expand Down
30 changes: 21 additions & 9 deletions runtime/Core/ThreadPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,31 @@ namespace Spartan
threads.clear();
}

void ThreadPool::AddTask(Task&& task)
future<void> ThreadPool::AddTask(Task&& task)
{
// Lock tasks mutex
// create a packaged task that will give us a future
auto packaged_task = make_shared<std::packaged_task<void()>>(forward<Task>(task));

// get the future before we move the packaged_task into the lambda
future<void> future = packaged_task->get_future();

// lock tasks mutex
unique_lock<mutex> lock(mutex_tasks);

// Save the task
tasks.emplace_back(bind(std::forward<Task>(task)));

// Unlock the mutex

// save the task - wrap the packaged_task in a lambda that will execute it
tasks.emplace_back([packaged_task]()
{
(*packaged_task)();
});

// unlock the mutex
lock.unlock();

// Wake up a thread
// wake up a thread
condition_var.notify_one();

// return the future that can be used to wait for task completion
return future;
}

void ThreadPool::ParallelLoop(function<void(uint32_t work_index_start, uint32_t work_index_end)>&& function, const uint32_t work_total)
Expand Down
8 changes: 4 additions & 4 deletions runtime/Core/ThreadPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#pragma once

//= INCLUDES ===========
#include "Definitions.h"
//= INCLUDES ========
#include <future>
#include <functional>
//======================
//===================

namespace Spartan
{
Expand All @@ -37,7 +37,7 @@ namespace Spartan
static void Shutdown();

// add a task
static void AddTask(Task&& task);
static std::future<void> AddTask(Task&& task);

// spread execution of a given function across all available threads
static void ParallelLoop(std::function<void(uint32_t work_index_start, uint32_t work_index_end)>&& function, const uint32_t work_total);
Expand Down
7 changes: 5 additions & 2 deletions runtime/RHI/RHI_Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ namespace Spartan
if (cmd_list != nullptr)
{
// wait in case this texture loading in another thread
while (!IsGpuReady())
while (m_resource_state != ResourceState::Ready)
{
SP_LOG_INFO("Waiting for texture \"%s\" to finish loading...", m_object_name.c_str());
this_thread::sleep_for(chrono::milliseconds(16));
Expand All @@ -523,10 +523,13 @@ namespace Spartan

void RHI_Texture::PrepareForGpu()
{
SP_ASSERT_MSG(!IsGpuReady(), "The texture is already optimized");
SP_ASSERT_MSG(m_resource_state != ResourceState::Processing, "The texture is already being processed");
SP_ASSERT_MSG(m_resource_state != ResourceState::Ready, "The texture is already optimized");
SP_ASSERT(m_slices.size() > 0);
SP_ASSERT(m_slices[0].mips.size() > 0);

m_resource_state = ResourceState::Processing;

if (!IsCompressedFormat()) // the bistro world loads compressed textures with mips
{
// generate mip chain
Expand Down
2 changes: 1 addition & 1 deletion runtime/RHI/Vulkan/Vulkan_CommandList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1434,7 +1434,7 @@ namespace Spartan
}

// if the texture is null or it's still loading, ignore it
if (!texture || !texture->IsGpuReady())
if (!texture || texture->GetResourceState() != ResourceState::Ready)
return;

// get some texture info
Expand Down
19 changes: 13 additions & 6 deletions runtime/Rendering/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "../RHI/RHI_Texture.h"
#include "../World/World.h"
#include "../Core/ProgressTracker.h"
#include "../Core/ThreadPool.h"
SP_WARNINGS_OFF
#include "../IO/pugixml.hpp"
SP_WARNINGS_ON
Expand Down Expand Up @@ -323,7 +324,10 @@ namespace Spartan

void Material::Optimize(const bool is_gltf)
{
SP_ASSERT_MSG(!IsGpuReady(), "The material is already optimized");
SP_ASSERT_MSG(m_resource_state != ResourceState::Processing, "The material is already being processed");
SP_ASSERT_MSG(m_resource_state != ResourceState::Ready, "The material is already optimized");

m_resource_state = ResourceState::Processing;

RHI_Texture* texture_color = GetTexture(MaterialTextureType::Color);
RHI_Texture* texture_alpha_mask = GetTexture(MaterialTextureType::AlphaMask);
Expand Down Expand Up @@ -431,14 +435,17 @@ namespace Spartan
}

// prepare all textures
for (RHI_Texture* texture : m_textures)
future<void> texture_preparation_task = ThreadPool::AddTask([this]()
{
if (texture && !texture->IsGpuReady())
for (RHI_Texture* texture : m_textures)
{
// todo: this could be given to the thread pool
texture->PrepareForGpu();
if (texture && texture->GetResourceState() == ResourceState::Max)
{
texture->PrepareForGpu();
}
}
}
});
texture_preparation_task.wait();

// determine if the material is optimized
bool is_optimized = GetTexture(MaterialTextureType::Packed) != nullptr;
Expand Down
4 changes: 2 additions & 2 deletions runtime/Rendering/Mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <vector>
#include <mutex>
#include "Material.h"
#include "../Resource/IResource.h"
#include "../Math/BoundingBox.h"
#include "../RHI/RHI_Vertex.h"
#include "../Math/BoundingBox.h"
#include "../Resource/IResource.h"
//================================

namespace Spartan
Expand Down
7 changes: 3 additions & 4 deletions runtime/Resource/IResource.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Spartan

enum class ResourceState
{
Processed,
Processing,
Ready,
Max
};
Expand Down Expand Up @@ -100,9 +100,6 @@ namespace Spartan
uint32_t GetFlags() const { return m_flags; }
void SetFlags(const uint32_t flags) { m_flags = flags; }

// ready to use
bool IsGpuReady() const { return m_resource_state == ResourceState::Ready; }

// io
virtual bool SaveToFile(const std::string& file_path) { return true; }
virtual bool LoadFromFile(const std::string& file_path) { return true; }
Expand All @@ -111,6 +108,8 @@ namespace Spartan
template <typename T>
static constexpr ResourceType TypeToEnum();

ResourceState GetResourceState() const { return m_resource_state; }

protected:
ResourceType m_resource_type = ResourceType::Max;
std::atomic<ResourceState> m_resource_state = ResourceState::Max;
Expand Down

0 comments on commit b16ae0f

Please sign in to comment.