mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-14 19:27:50 +00:00
Core / VideoCommon: Remove original custom asset loader
This commit is contained in:
parent
5ec5db9240
commit
d7de49ccf6
@ -82,7 +82,6 @@
|
||||
#include "InputCommon/ControllerInterface/ControllerInterface.h"
|
||||
#include "InputCommon/GCAdapter.h"
|
||||
|
||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
||||
#include "VideoCommon/AsyncRequests.h"
|
||||
#include "VideoCommon/Fifo.h"
|
||||
#include "VideoCommon/FrameDumper.h"
|
||||
@ -528,9 +527,6 @@ static void EmuThread(Core::System& system, std::unique_ptr<BootParameters> boot
|
||||
|
||||
FreeLook::LoadInputConfig();
|
||||
|
||||
system.GetCustomAssetLoader().Init();
|
||||
Common::ScopeGuard asset_loader_guard([&system] { system.GetCustomAssetLoader().Shutdown(); });
|
||||
|
||||
system.GetMovie().Init(*boot);
|
||||
Common::ScopeGuard movie_guard([&system] { system.GetMovie().Shutdown(); });
|
||||
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "IOS/USB/Emulated/Infinity.h"
|
||||
#include "IOS/USB/Emulated/Skylanders/Skylander.h"
|
||||
#include "IOS/USB/USBScanner.h"
|
||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
||||
#include "VideoCommon/CommandProcessor.h"
|
||||
#include "VideoCommon/Fifo.h"
|
||||
#include "VideoCommon/GeometryShaderManager.h"
|
||||
@ -96,7 +95,6 @@ struct System::Impl
|
||||
VideoInterface::VideoInterfaceManager m_video_interface;
|
||||
Interpreter m_interpreter;
|
||||
JitInterface m_jit_interface;
|
||||
VideoCommon::CustomAssetLoader m_custom_asset_loader;
|
||||
FifoPlayer m_fifo_player;
|
||||
FifoRecorder m_fifo_recorder;
|
||||
Movie::MovieManager m_movie;
|
||||
@ -335,8 +333,4 @@ VideoInterface::VideoInterfaceManager& System::GetVideoInterface() const
|
||||
return m_impl->m_video_interface;
|
||||
}
|
||||
|
||||
VideoCommon::CustomAssetLoader& System::GetCustomAssetLoader() const
|
||||
{
|
||||
return m_impl->m_custom_asset_loader;
|
||||
}
|
||||
} // namespace Core
|
||||
|
@ -108,7 +108,6 @@ class SystemTimersManager;
|
||||
}
|
||||
namespace VideoCommon
|
||||
{
|
||||
class CustomAssetLoader;
|
||||
}
|
||||
namespace VideoInterface
|
||||
{
|
||||
@ -197,7 +196,6 @@ public:
|
||||
VertexShaderManager& GetVertexShaderManager() const;
|
||||
XFStateManager& GetXFStateManager() const;
|
||||
VideoInterface::VideoInterfaceManager& GetVideoInterface() const;
|
||||
VideoCommon::CustomAssetLoader& GetCustomAssetLoader() const;
|
||||
|
||||
private:
|
||||
System();
|
||||
|
@ -668,7 +668,6 @@
|
||||
<ClInclude Include="VideoCommon\AbstractTexture.h" />
|
||||
<ClInclude Include="VideoCommon\Assets\CustomAsset.h" />
|
||||
<ClInclude Include="VideoCommon\Assets\CustomAssetLibrary.h" />
|
||||
<ClInclude Include="VideoCommon\Assets\CustomAssetLoader.h" />
|
||||
<ClInclude Include="VideoCommon\Assets\CustomTextureData.h" />
|
||||
<ClInclude Include="VideoCommon\Assets\DirectFilesystemAssetLibrary.h" />
|
||||
<ClInclude Include="VideoCommon\Assets\MaterialAsset.h" />
|
||||
@ -1321,7 +1320,6 @@
|
||||
<ClCompile Include="VideoCommon\AbstractTexture.cpp" />
|
||||
<ClCompile Include="VideoCommon\Assets\CustomAsset.cpp" />
|
||||
<ClCompile Include="VideoCommon\Assets\CustomAssetLibrary.cpp" />
|
||||
<ClCompile Include="VideoCommon\Assets\CustomAssetLoader.cpp" />
|
||||
<ClCompile Include="VideoCommon\Assets\CustomTextureData.cpp" />
|
||||
<ClCompile Include="VideoCommon\Assets\DirectFilesystemAssetLibrary.cpp" />
|
||||
<ClCompile Include="VideoCommon\Assets\MaterialAsset.cpp" />
|
||||
|
@ -1,108 +0,0 @@
|
||||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
||||
|
||||
#include "Common/MemoryUtil.h"
|
||||
#include "VideoCommon/Assets/CustomAssetLibrary.h"
|
||||
|
||||
namespace VideoCommon
|
||||
{
|
||||
void CustomAssetLoader::Init()
|
||||
{
|
||||
m_asset_monitor_thread_shutdown.Clear();
|
||||
|
||||
const size_t sys_mem = Common::MemPhysical();
|
||||
const size_t recommended_min_mem = 2 * size_t(1024 * 1024 * 1024);
|
||||
// keep 2GB memory for system stability if system RAM is 4GB+ - use half of memory in other cases
|
||||
m_max_memory_available =
|
||||
(sys_mem / 2 < recommended_min_mem) ? (sys_mem / 2) : (sys_mem - recommended_min_mem);
|
||||
|
||||
m_asset_monitor_thread = std::thread([this]() {
|
||||
Common::SetCurrentThreadName("Asset monitor");
|
||||
while (true)
|
||||
{
|
||||
if (m_asset_monitor_thread_shutdown.IsSet())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(TIME_BETWEEN_ASSET_MONITOR_CHECKS);
|
||||
|
||||
std::lock_guard lk(m_asset_load_lock);
|
||||
for (auto& [asset_id, asset_to_monitor] : m_assets_to_monitor)
|
||||
{
|
||||
if (auto ptr = asset_to_monitor.lock())
|
||||
{
|
||||
const auto write_time = ptr->GetLastWriteTime();
|
||||
if (write_time > ptr->GetLastLoadedTime())
|
||||
{
|
||||
(void)ptr->Load();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
m_asset_load_thread.Reset("Custom Asset Loader", [this](std::weak_ptr<CustomAsset> asset) {
|
||||
if (auto ptr = asset.lock())
|
||||
{
|
||||
if (m_memory_exceeded)
|
||||
return;
|
||||
|
||||
if (ptr->Load())
|
||||
{
|
||||
std::lock_guard lk(m_asset_load_lock);
|
||||
const std::size_t asset_memory_size = ptr->GetByteSizeInMemory();
|
||||
m_total_bytes_loaded += asset_memory_size;
|
||||
m_assets_to_monitor.try_emplace(ptr->GetAssetId(), ptr);
|
||||
if (m_total_bytes_loaded > m_max_memory_available)
|
||||
{
|
||||
ERROR_LOG_FMT(VIDEO,
|
||||
"Asset memory exceeded with asset '{}', future assets won't load until "
|
||||
"memory is available.",
|
||||
ptr->GetAssetId());
|
||||
m_memory_exceeded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CustomAssetLoader::Shutdown()
|
||||
{
|
||||
m_asset_load_thread.StopAndCancel();
|
||||
|
||||
m_asset_monitor_thread_shutdown.Set();
|
||||
m_asset_monitor_thread.join();
|
||||
m_assets_to_monitor.clear();
|
||||
m_total_bytes_loaded = 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<GameTextureAsset>
|
||||
CustomAssetLoader::LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library)
|
||||
{
|
||||
return LoadOrCreateAsset<GameTextureAsset>(asset_id, m_game_textures, std::move(library));
|
||||
}
|
||||
|
||||
std::shared_ptr<PixelShaderAsset>
|
||||
CustomAssetLoader::LoadPixelShader(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library)
|
||||
{
|
||||
return LoadOrCreateAsset<PixelShaderAsset>(asset_id, m_pixel_shaders, std::move(library));
|
||||
}
|
||||
|
||||
std::shared_ptr<MaterialAsset>
|
||||
CustomAssetLoader::LoadMaterial(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library)
|
||||
{
|
||||
return LoadOrCreateAsset<MaterialAsset>(asset_id, m_materials, std::move(library));
|
||||
}
|
||||
|
||||
std::shared_ptr<MeshAsset> CustomAssetLoader::LoadMesh(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library)
|
||||
{
|
||||
return LoadOrCreateAsset<MeshAsset>(asset_id, m_meshes, std::move(library));
|
||||
}
|
||||
} // namespace VideoCommon
|
@ -1,108 +0,0 @@
|
||||
// Copyright 2023 Dolphin Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include "Common/Flag.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/WorkQueueThread.h"
|
||||
#include "VideoCommon/Assets/CustomAsset.h"
|
||||
#include "VideoCommon/Assets/MaterialAsset.h"
|
||||
#include "VideoCommon/Assets/MeshAsset.h"
|
||||
#include "VideoCommon/Assets/ShaderAsset.h"
|
||||
#include "VideoCommon/Assets/TextureAsset.h"
|
||||
|
||||
namespace VideoCommon
|
||||
{
|
||||
// This class is responsible for loading data asynchronously when requested
|
||||
// and watches that data asynchronously reloading it if it changes
|
||||
class CustomAssetLoader
|
||||
{
|
||||
public:
|
||||
CustomAssetLoader() = default;
|
||||
~CustomAssetLoader() = default;
|
||||
CustomAssetLoader(const CustomAssetLoader&) = delete;
|
||||
CustomAssetLoader(CustomAssetLoader&&) = delete;
|
||||
CustomAssetLoader& operator=(const CustomAssetLoader&) = delete;
|
||||
CustomAssetLoader& operator=(CustomAssetLoader&&) = delete;
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
|
||||
// The following Load* functions will load or create an asset associated
|
||||
// with the given asset id
|
||||
// Loads happen asynchronously where the data will be set now or in the future
|
||||
// Callees are expected to query the underlying data with 'GetData()'
|
||||
// from the 'CustomLoadableAsset' class to determine if the data is ready for use
|
||||
std::shared_ptr<GameTextureAsset> LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library);
|
||||
|
||||
std::shared_ptr<PixelShaderAsset> LoadPixelShader(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library);
|
||||
|
||||
std::shared_ptr<MaterialAsset> LoadMaterial(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library);
|
||||
|
||||
std::shared_ptr<MeshAsset> LoadMesh(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::shared_ptr<CustomAssetLibrary> library);
|
||||
|
||||
private:
|
||||
// TODO C++20: use a 'derived_from' concept against 'CustomAsset' when available
|
||||
template <typename AssetType>
|
||||
std::shared_ptr<AssetType>
|
||||
LoadOrCreateAsset(const CustomAssetLibrary::AssetID& asset_id,
|
||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<AssetType>>& asset_map,
|
||||
std::shared_ptr<CustomAssetLibrary> library)
|
||||
{
|
||||
auto [it, inserted] = asset_map.try_emplace(asset_id);
|
||||
if (!inserted)
|
||||
{
|
||||
auto shared = it->second.lock();
|
||||
if (shared)
|
||||
return shared;
|
||||
}
|
||||
std::shared_ptr<AssetType> ptr(new AssetType(std::move(library), asset_id), [&](AssetType* a) {
|
||||
{
|
||||
std::lock_guard lk(m_asset_load_lock);
|
||||
m_total_bytes_loaded -= a->GetByteSizeInMemory();
|
||||
m_assets_to_monitor.erase(a->GetAssetId());
|
||||
if (m_max_memory_available >= m_total_bytes_loaded && m_memory_exceeded)
|
||||
{
|
||||
INFO_LOG_FMT(VIDEO, "Asset memory went below limit, new assets can begin loading.");
|
||||
m_memory_exceeded = false;
|
||||
}
|
||||
}
|
||||
delete a;
|
||||
});
|
||||
it->second = ptr;
|
||||
m_asset_load_thread.Push(it->second);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static constexpr auto TIME_BETWEEN_ASSET_MONITOR_CHECKS = std::chrono::milliseconds{500};
|
||||
|
||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<GameTextureAsset>> m_game_textures;
|
||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<PixelShaderAsset>> m_pixel_shaders;
|
||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<MaterialAsset>> m_materials;
|
||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<MeshAsset>> m_meshes;
|
||||
std::thread m_asset_monitor_thread;
|
||||
Common::Flag m_asset_monitor_thread_shutdown;
|
||||
|
||||
std::size_t m_total_bytes_loaded = 0;
|
||||
std::size_t m_max_memory_available = 0;
|
||||
std::atomic_bool m_memory_exceeded = false;
|
||||
|
||||
std::map<CustomAssetLibrary::AssetID, std::weak_ptr<CustomAsset>> m_assets_to_monitor;
|
||||
|
||||
// Use a recursive mutex to handle the scenario where an asset goes out of scope while
|
||||
// iterating over the assets to monitor which calls the lock above in 'LoadOrCreateAsset'
|
||||
std::recursive_mutex m_asset_load_lock;
|
||||
Common::WorkQueueThread<std::weak_ptr<CustomAsset>> m_asset_load_thread;
|
||||
};
|
||||
} // namespace VideoCommon
|
@ -16,7 +16,6 @@
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "VideoCommon/AbstractGfx.h"
|
||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
||||
#include "VideoCommon/Assets/DirectFilesystemAssetLibrary.h"
|
||||
#include "VideoCommon/ShaderGenCommon.h"
|
||||
#include "VideoCommon/TextureCacheBase.h"
|
||||
@ -98,28 +97,6 @@ CustomPipelineAction::CustomPipelineAction(
|
||||
m_pipeline_passes.resize(m_passes_config.size());
|
||||
}
|
||||
|
||||
void CustomPipelineAction::OnDrawStarted(GraphicsModActionData::DrawStarted* draw_started)
|
||||
void CustomPipelineAction::OnDrawStarted(GraphicsModActionData::DrawStarted*)
|
||||
{
|
||||
if (!draw_started) [[unlikely]]
|
||||
return;
|
||||
|
||||
if (!draw_started->custom_pixel_shader) [[unlikely]]
|
||||
return;
|
||||
|
||||
if (m_pipeline_passes.empty()) [[unlikely]]
|
||||
return;
|
||||
|
||||
auto& loader = Core::System::GetInstance().GetCustomAssetLoader();
|
||||
|
||||
// For now assume a single pass
|
||||
const auto& pass_config = m_passes_config[0];
|
||||
auto& pass = m_pipeline_passes[0];
|
||||
|
||||
pass.UpdatePixelData(loader, m_library, draw_started->texture_units,
|
||||
pass_config.m_pixel_material_asset);
|
||||
CustomPixelShader custom_pixel_shader;
|
||||
custom_pixel_shader.custom_shader = pass.m_last_generated_shader_code.GetBuffer();
|
||||
custom_pixel_shader.material_uniform_block = pass.m_last_generated_material_code.GetBuffer();
|
||||
*draw_started->custom_pixel_shader = custom_pixel_shader;
|
||||
*draw_started->material_uniform_buffer = pass.m_material_data;
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "Common/VariantUtil.h"
|
||||
|
||||
#include "VideoCommon/AbstractGfx.h"
|
||||
#include "VideoCommon/Assets/CustomAssetLoader.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -172,238 +171,8 @@ std::vector<std::string> GlobalConflicts(std::string_view source)
|
||||
|
||||
} // namespace
|
||||
|
||||
void CustomPipeline::UpdatePixelData(
|
||||
VideoCommon::CustomAssetLoader& loader,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library, std::span<const u32> texture_units,
|
||||
const VideoCommon::CustomAssetLibrary::AssetID& material_to_load)
|
||||
void CustomPipeline::UpdatePixelData(std::shared_ptr<VideoCommon::CustomAssetLibrary>,
|
||||
std::span<const u32>,
|
||||
const VideoCommon::CustomAssetLibrary::AssetID&)
|
||||
{
|
||||
if (!m_pixel_material.m_asset || material_to_load != m_pixel_material.m_asset->GetAssetId())
|
||||
{
|
||||
m_pixel_material.m_asset = loader.LoadMaterial(material_to_load, library);
|
||||
}
|
||||
|
||||
const auto material_data = m_pixel_material.m_asset->GetData();
|
||||
if (!material_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t max_material_data_size = 0;
|
||||
if (m_pixel_material.m_asset->GetLastLoadedTime() > m_pixel_material.m_cached_write_time)
|
||||
{
|
||||
m_last_generated_material_code = ShaderCode{};
|
||||
m_pixel_material.m_cached_write_time = m_pixel_material.m_asset->GetLastLoadedTime();
|
||||
std::size_t texture_count = 0;
|
||||
for (const auto& property : material_data->properties)
|
||||
{
|
||||
max_material_data_size += VideoCommon::MaterialProperty::GetMemorySize(property);
|
||||
VideoCommon::MaterialProperty::WriteAsShaderCode(m_last_generated_material_code, property);
|
||||
if (std::holds_alternative<VideoCommon::CustomAssetLibrary::AssetID>(property.m_value))
|
||||
{
|
||||
texture_count++;
|
||||
}
|
||||
}
|
||||
m_material_data.resize(max_material_data_size);
|
||||
m_game_textures.resize(texture_count);
|
||||
}
|
||||
|
||||
if (!m_pixel_shader.m_asset ||
|
||||
m_pixel_shader.m_asset->GetLastLoadedTime() > m_pixel_shader.m_cached_write_time ||
|
||||
material_data->shader_asset != m_pixel_shader.m_asset->GetAssetId())
|
||||
{
|
||||
m_pixel_shader.m_asset = loader.LoadPixelShader(material_data->shader_asset, library);
|
||||
m_pixel_shader.m_cached_write_time = m_pixel_shader.m_asset->GetLastLoadedTime();
|
||||
|
||||
m_last_generated_shader_code = ShaderCode{};
|
||||
}
|
||||
|
||||
const auto shader_data = m_pixel_shader.m_asset->GetData();
|
||||
if (!shader_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (shader_data->m_properties.size() != material_data->properties.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
u8* material_buffer = m_material_data.data();
|
||||
u32 sampler_index = 8;
|
||||
for (std::size_t index = 0; index < material_data->properties.size(); index++)
|
||||
{
|
||||
auto& property = material_data->properties[index];
|
||||
const auto shader_it = shader_data->m_properties.find(property.m_code_name);
|
||||
if (shader_it == shader_data->m_properties.end())
|
||||
{
|
||||
ERROR_LOG_FMT(VIDEO,
|
||||
"Custom pipeline, has material asset '{}' that uses a "
|
||||
"code name of '{}' but that can't be found on shader asset '{}'!",
|
||||
m_pixel_material.m_asset->GetAssetId(), property.m_code_name,
|
||||
m_pixel_shader.m_asset->GetAssetId());
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto* texture_asset_id =
|
||||
std::get_if<VideoCommon::CustomAssetLibrary::AssetID>(&property.m_value))
|
||||
{
|
||||
if (*texture_asset_id != "")
|
||||
{
|
||||
auto asset = loader.LoadGameTexture(*texture_asset_id, library);
|
||||
if (!asset)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& texture_asset = m_game_textures[index];
|
||||
if (!texture_asset ||
|
||||
texture_asset->m_cached_asset.m_asset->GetLastLoadedTime() >
|
||||
texture_asset->m_cached_asset.m_cached_write_time ||
|
||||
*texture_asset_id != texture_asset->m_cached_asset.m_asset->GetAssetId())
|
||||
{
|
||||
if (!texture_asset)
|
||||
{
|
||||
texture_asset = CachedTextureAsset{};
|
||||
}
|
||||
const auto loaded_time = asset->GetLastLoadedTime();
|
||||
texture_asset->m_cached_asset = VideoCommon::CachedAsset<VideoCommon::GameTextureAsset>{
|
||||
std::move(asset), loaded_time};
|
||||
texture_asset->m_texture.reset();
|
||||
|
||||
if (std::holds_alternative<VideoCommon::ShaderProperty::Sampler2D>(
|
||||
shader_it->second.m_default))
|
||||
{
|
||||
texture_asset->m_sampler_code =
|
||||
fmt::format("SAMPLER_BINDING({}) uniform sampler2D samp_{};\n", sampler_index,
|
||||
property.m_code_name);
|
||||
texture_asset->m_define_code = fmt::format("#define HAS_{} 1\n", property.m_code_name);
|
||||
}
|
||||
else if (std::holds_alternative<VideoCommon::ShaderProperty::Sampler2DArray>(
|
||||
shader_it->second.m_default))
|
||||
{
|
||||
texture_asset->m_sampler_code =
|
||||
fmt::format("SAMPLER_BINDING({}) uniform sampler2DArray samp_{};\n", sampler_index,
|
||||
property.m_code_name);
|
||||
texture_asset->m_define_code = fmt::format("#define HAS_{} 1\n", property.m_code_name);
|
||||
}
|
||||
else if (std::holds_alternative<VideoCommon::ShaderProperty::SamplerCube>(
|
||||
shader_it->second.m_default))
|
||||
{
|
||||
texture_asset->m_sampler_code =
|
||||
fmt::format("SAMPLER_BINDING({}) uniform samplerCube samp_{};\n", sampler_index,
|
||||
property.m_code_name);
|
||||
texture_asset->m_define_code = fmt::format("#define HAS_{} 1\n", property.m_code_name);
|
||||
}
|
||||
}
|
||||
|
||||
const auto texture_data = texture_asset->m_cached_asset.m_asset->GetData();
|
||||
if (!texture_data)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (texture_asset->m_texture)
|
||||
{
|
||||
g_gfx->SetTexture(sampler_index, texture_asset->m_texture.get());
|
||||
g_gfx->SetSamplerState(sampler_index, texture_data->m_sampler);
|
||||
}
|
||||
else
|
||||
{
|
||||
AbstractTextureType texture_type = AbstractTextureType::Texture_2DArray;
|
||||
if (std::holds_alternative<VideoCommon::ShaderProperty::SamplerCube>(
|
||||
shader_it->second.m_default))
|
||||
{
|
||||
texture_type = AbstractTextureType::Texture_CubeMap;
|
||||
}
|
||||
else if (std::holds_alternative<VideoCommon::ShaderProperty::Sampler2D>(
|
||||
shader_it->second.m_default))
|
||||
{
|
||||
texture_type = AbstractTextureType::Texture_2D;
|
||||
}
|
||||
|
||||
if (texture_data->m_texture.m_slices.empty() ||
|
||||
texture_data->m_texture.m_slices[0].m_levels.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& first_slice = texture_data->m_texture.m_slices[0];
|
||||
const TextureConfig texture_config(
|
||||
first_slice.m_levels[0].width, first_slice.m_levels[0].height,
|
||||
static_cast<u32>(first_slice.m_levels.size()),
|
||||
static_cast<u32>(texture_data->m_texture.m_slices.size()), 1,
|
||||
first_slice.m_levels[0].format, 0, texture_type);
|
||||
texture_asset->m_texture = g_gfx->CreateTexture(
|
||||
texture_config, fmt::format("Custom shader texture '{}'", property.m_code_name));
|
||||
if (texture_asset->m_texture)
|
||||
{
|
||||
for (std::size_t slice_index = 0; slice_index < texture_data->m_texture.m_slices.size();
|
||||
slice_index++)
|
||||
{
|
||||
auto& slice = texture_data->m_texture.m_slices[slice_index];
|
||||
for (u32 level_index = 0; level_index < static_cast<u32>(slice.m_levels.size());
|
||||
++level_index)
|
||||
{
|
||||
auto& level = slice.m_levels[level_index];
|
||||
texture_asset->m_texture->Load(level_index, level.width, level.height,
|
||||
level.row_length, level.data.data(),
|
||||
level.data.size(), static_cast<u32>(slice_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sampler_index++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
VideoCommon::MaterialProperty::WriteToMemory(material_buffer, property);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_last_generated_shader_code.GetBuffer().empty())
|
||||
{
|
||||
// Calculate shader details
|
||||
std::string color_shader_data =
|
||||
ReplaceAll(shader_data->m_shader_source, "custom_main", CUSTOM_PIXELSHADER_COLOR_FUNC);
|
||||
const auto global_conflicts = GlobalConflicts(color_shader_data);
|
||||
color_shader_data = ReplaceAll(color_shader_data, "\r\n", "\n");
|
||||
color_shader_data = ReplaceAll(color_shader_data, "{", "{{");
|
||||
color_shader_data = ReplaceAll(color_shader_data, "}", "}}");
|
||||
// First replace global conflicts with dummy strings
|
||||
// This avoids the problem where a shorter word
|
||||
// is in a longer word, ex two functions: 'execute' and 'execute_fast'
|
||||
for (std::size_t i = 0; i < global_conflicts.size(); i++)
|
||||
{
|
||||
const std::string& identifier = global_conflicts[i];
|
||||
color_shader_data =
|
||||
ReplaceAll(color_shader_data, identifier, fmt::format("_{0}_DOLPHIN_TEMP_{0}_", i));
|
||||
}
|
||||
// Now replace the temporaries with the actual value
|
||||
for (std::size_t i = 0; i < global_conflicts.size(); i++)
|
||||
{
|
||||
const std::string& identifier = global_conflicts[i];
|
||||
color_shader_data = ReplaceAll(color_shader_data, fmt::format("_{0}_DOLPHIN_TEMP_{0}_", i),
|
||||
fmt::format("{}_{{0}}", identifier));
|
||||
}
|
||||
|
||||
for (const auto& game_texture : m_game_textures)
|
||||
{
|
||||
if (!game_texture)
|
||||
continue;
|
||||
|
||||
m_last_generated_shader_code.Write("{}", game_texture->m_sampler_code);
|
||||
m_last_generated_shader_code.Write("{}", game_texture->m_define_code);
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < texture_units.size(); i++)
|
||||
{
|
||||
const auto& texture_unit = texture_units[i];
|
||||
m_last_generated_shader_code.Write(
|
||||
"#define TEX_COORD{} data.texcoord[data.texmap_to_texcoord_index[{}]].xy\n", i,
|
||||
texture_unit);
|
||||
}
|
||||
m_last_generated_shader_code.Write("{}", color_shader_data);
|
||||
}
|
||||
}
|
||||
|
@ -17,15 +17,9 @@
|
||||
#include "VideoCommon/Assets/TextureAsset.h"
|
||||
#include "VideoCommon/ShaderGenCommon.h"
|
||||
|
||||
namespace VideoCommon
|
||||
{
|
||||
class CustomAssetLoader;
|
||||
}
|
||||
|
||||
struct CustomPipeline
|
||||
{
|
||||
void UpdatePixelData(VideoCommon::CustomAssetLoader& loader,
|
||||
std::shared_ptr<VideoCommon::CustomAssetLibrary> library,
|
||||
void UpdatePixelData(std::shared_ptr<VideoCommon::CustomAssetLibrary> library,
|
||||
std::span<const u32> texture_units,
|
||||
const VideoCommon::CustomAssetLibrary::AssetID& material_to_load);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user