mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
VideoCommon: update resource manager with a material/shader/and texture(+sampler) resource to show the complexities that warrant the resource manager system
This commit is contained in:
@@ -3,6 +3,11 @@
|
||||
|
||||
#include "VideoCommon/Resources/CustomResourceManager.h"
|
||||
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
#include "VideoCommon/AbstractGfx.h"
|
||||
#include "VideoCommon/PipelineUtils.h"
|
||||
#include "VideoCommon/Resources/InvalidTextures.h"
|
||||
#include "VideoCommon/VideoEvents.h"
|
||||
|
||||
namespace VideoCommon
|
||||
@@ -10,22 +15,46 @@ namespace VideoCommon
|
||||
void CustomResourceManager::Initialize()
|
||||
{
|
||||
m_asset_cache.Initialize();
|
||||
m_worker_thread.Reset("resource-worker");
|
||||
m_host_config.bits = ShaderHostConfig::GetCurrent().bits;
|
||||
m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler();
|
||||
|
||||
m_async_shader_compiler->StartWorkerThreads(1); // TODO expose to config
|
||||
|
||||
m_xfb_event =
|
||||
AfterFrameEvent::Register([this](Core::System&) { XFBTriggered(); }, "CustomResourceManager");
|
||||
GetVideoEvents().after_frame_event.Register([this](Core::System&) { XFBTriggered(); });
|
||||
|
||||
m_invalid_array_texture = CreateInvalidArrayTexture();
|
||||
m_invalid_color_texture = CreateInvalidColorTexture();
|
||||
m_invalid_cubemap_texture = CreateInvalidCubemapTexture();
|
||||
m_invalid_transparent_texture = CreateInvalidTransparentTexture();
|
||||
}
|
||||
|
||||
void CustomResourceManager::Shutdown()
|
||||
{
|
||||
if (m_async_shader_compiler)
|
||||
m_async_shader_compiler->StopWorkerThreads();
|
||||
|
||||
m_asset_cache.Shutdown();
|
||||
m_worker_thread.Shutdown();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void CustomResourceManager::Reset()
|
||||
{
|
||||
m_material_resources.clear();
|
||||
m_shader_resources.clear();
|
||||
m_texture_data_resources.clear();
|
||||
m_texture_sampler_resources.clear();
|
||||
|
||||
m_invalid_transparent_texture.reset();
|
||||
m_invalid_color_texture.reset();
|
||||
m_invalid_cubemap_texture.reset();
|
||||
m_invalid_array_texture.reset();
|
||||
|
||||
m_asset_cache.Reset();
|
||||
m_texture_pool.Reset();
|
||||
m_worker_thread.Reset("resource-worker");
|
||||
}
|
||||
|
||||
void CustomResourceManager::MarkAssetDirty(const CustomAssetLibrary::AssetID& asset_id)
|
||||
@@ -38,24 +67,99 @@ void CustomResourceManager::XFBTriggered()
|
||||
m_asset_cache.Update();
|
||||
}
|
||||
|
||||
void CustomResourceManager::SetHostConfig(const ShaderHostConfig& host_config)
|
||||
{
|
||||
for (auto& [id, shader_resources] : m_shader_resources)
|
||||
{
|
||||
for (auto& [key, shader_resource] : shader_resources)
|
||||
{
|
||||
shader_resource->SetHostConfig(host_config);
|
||||
|
||||
// Hack to get access to resource internals
|
||||
Resource* resource = shader_resource.get();
|
||||
|
||||
// Tell shader and references to trigger a reload
|
||||
// on next usage
|
||||
resource->NotifyAssetChanged(false);
|
||||
}
|
||||
}
|
||||
|
||||
m_host_config.bits = host_config.bits;
|
||||
}
|
||||
|
||||
TextureDataResource* CustomResourceManager::GetTextureDataFromAsset(
|
||||
const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library)
|
||||
{
|
||||
const auto [it, added] = m_texture_data_resources.try_emplace(asset_id, nullptr);
|
||||
if (added)
|
||||
auto& resource = m_texture_data_resources[asset_id];
|
||||
if (resource == nullptr)
|
||||
{
|
||||
it->second = std::make_unique<TextureDataResource>(CreateResourceContext(asset_id, library));
|
||||
resource =
|
||||
std::make_unique<TextureDataResource>(CreateResourceContext(asset_id, std::move(library)));
|
||||
}
|
||||
ProcessResource(it->second.get());
|
||||
return it->second.get();
|
||||
ProcessResource(resource.get());
|
||||
return resource.get();
|
||||
}
|
||||
|
||||
MaterialResource* CustomResourceManager::GetMaterialFromAsset(
|
||||
const CustomAssetLibrary::AssetID& asset_id, const GXPipelineUid& pipeline_uid,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library)
|
||||
{
|
||||
auto& resource = m_material_resources[asset_id][PipelineToHash(pipeline_uid)];
|
||||
if (resource == nullptr)
|
||||
{
|
||||
resource = std::make_unique<MaterialResource>(
|
||||
CreateResourceContext(asset_id, std::move(library)), pipeline_uid);
|
||||
}
|
||||
ProcessResource(resource.get());
|
||||
return resource.get();
|
||||
}
|
||||
|
||||
ShaderResource*
|
||||
CustomResourceManager::GetShaderFromAsset(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::size_t shader_key, const GXPipelineUid& pipeline_uid,
|
||||
const std::string& preprocessor_settings,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library)
|
||||
{
|
||||
auto& resource = m_shader_resources[asset_id][shader_key];
|
||||
if (resource == nullptr)
|
||||
{
|
||||
resource = std::make_unique<ShaderResource>(CreateResourceContext(asset_id, std::move(library)),
|
||||
pipeline_uid, preprocessor_settings, m_host_config);
|
||||
}
|
||||
ProcessResource(resource.get());
|
||||
return resource.get();
|
||||
}
|
||||
|
||||
TextureAndSamplerResource* CustomResourceManager::GetTextureAndSamplerFromAsset(
|
||||
const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library)
|
||||
{
|
||||
auto& resource = m_texture_sampler_resources[asset_id];
|
||||
if (resource == nullptr)
|
||||
{
|
||||
resource = std::make_unique<TextureAndSamplerResource>(
|
||||
CreateResourceContext(asset_id, std::move(library)));
|
||||
}
|
||||
ProcessResource(resource.get());
|
||||
return resource.get();
|
||||
}
|
||||
|
||||
Resource::ResourceContext CustomResourceManager::CreateResourceContext(
|
||||
const CustomAssetLibrary::AssetID& asset_id,
|
||||
const std::shared_ptr<VideoCommon::CustomAssetLibrary>& library)
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library)
|
||||
{
|
||||
return Resource::ResourceContext{asset_id, library, &m_asset_cache, this};
|
||||
return Resource::ResourceContext{asset_id,
|
||||
std::move(library),
|
||||
&m_asset_cache,
|
||||
this,
|
||||
&m_texture_pool,
|
||||
&m_worker_thread,
|
||||
m_async_shader_compiler.get(),
|
||||
m_invalid_array_texture.get(),
|
||||
m_invalid_color_texture.get(),
|
||||
m_invalid_cubemap_texture.get(),
|
||||
m_invalid_transparent_texture.get()};
|
||||
}
|
||||
|
||||
void CustomResourceManager::ProcessResource(Resource* resource)
|
||||
@@ -71,18 +175,15 @@ void CustomResourceManager::ProcessResource(Resource* resource)
|
||||
return;
|
||||
}
|
||||
|
||||
// Early out if we're already at our end state
|
||||
if (resource->GetState() == Resource::State::DataAvailable)
|
||||
return;
|
||||
|
||||
ProcessResourceState(resource);
|
||||
}
|
||||
|
||||
void CustomResourceManager::ProcessResourceState(Resource* resource)
|
||||
{
|
||||
Resource::State next_state = resource->GetState();
|
||||
const auto current_state = resource->GetState();
|
||||
Resource::State next_state = current_state;
|
||||
Resource::TaskComplete task_complete = Resource::TaskComplete::No;
|
||||
switch (resource->GetState())
|
||||
switch (current_state)
|
||||
{
|
||||
case Resource::State::ReloadData:
|
||||
resource->ResetData();
|
||||
@@ -102,6 +203,14 @@ void CustomResourceManager::ProcessResourceState(Resource* resource)
|
||||
case Resource::State::ProcessingData:
|
||||
task_complete = resource->ProcessData();
|
||||
next_state = Resource::State::DataAvailable;
|
||||
break;
|
||||
case Resource::State::DataAvailable:
|
||||
// Early out, we're already at our end state
|
||||
return;
|
||||
default:
|
||||
ERROR_LOG_FMT(VIDEO, "Unknown resource state '{}' for resource '{}'",
|
||||
static_cast<int>(current_state), resource->m_resource_context.primary_asset_id);
|
||||
return;
|
||||
};
|
||||
|
||||
if (task_complete == Resource::TaskComplete::Yes)
|
||||
|
||||
Reference in New Issue
Block a user