mirror of
https://github.com/encounter/aurora.git
synced 2026-07-09 18:19:33 -07:00
Runtime texture replacement API
This commit is contained in:
@@ -91,7 +91,6 @@ typedef struct {
|
||||
bool startFullscreen;
|
||||
bool allowJoystickBackgroundEvents;
|
||||
bool pauseOnFocusLost;
|
||||
bool allowTextureReplacements;
|
||||
bool allowTextureDumps;
|
||||
bool allowCpuAdapter;
|
||||
int32_t windowPosX;
|
||||
|
||||
@@ -31,8 +31,6 @@ typedef struct {
|
||||
const AuroraStats* aurora_get_stats();
|
||||
|
||||
void aurora_enable_vsync(bool enabled);
|
||||
void aurora_set_texture_replacements_enabled(bool enabled);
|
||||
void aurora_reload_texture_replacements();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#ifndef AURORA_TEXTURE_HPP
|
||||
#define AURORA_TEXTURE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <span>
|
||||
#include <string_view>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace aurora::texture {
|
||||
|
||||
struct TextureSourceKey {
|
||||
uint64_t textureHash = 0;
|
||||
uint64_t tlutHash = 0;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t format = 0;
|
||||
bool hasTlut = false;
|
||||
|
||||
bool operator==(const TextureSourceKey&) const = default;
|
||||
};
|
||||
|
||||
struct TexturePointerKey {
|
||||
const void* data = nullptr;
|
||||
|
||||
bool operator==(const TexturePointerKey&) const = default;
|
||||
};
|
||||
|
||||
using ReplacementKey = std::variant<TexturePointerKey, TextureSourceKey>;
|
||||
|
||||
struct RawTextureReplacement {
|
||||
std::span<const uint8_t> bytes;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t mipCount = 1;
|
||||
uint32_t gxFormat = 0;
|
||||
std::string_view label = {};
|
||||
};
|
||||
|
||||
struct ReplacementOptions {
|
||||
int32_t priority = 0;
|
||||
};
|
||||
|
||||
struct ReplacementRegistration {
|
||||
uint64_t id = 0;
|
||||
ReplacementKey key;
|
||||
};
|
||||
|
||||
struct ReplacementGroup {
|
||||
std::vector<ReplacementRegistration> registrations;
|
||||
};
|
||||
|
||||
ReplacementRegistration register_replacement(ReplacementKey key, RawTextureReplacement replacement,
|
||||
ReplacementOptions options = {});
|
||||
void unregister_replacement(const ReplacementRegistration& registration);
|
||||
void unregister_replacements(std::span<const ReplacementRegistration> registrations);
|
||||
void unregister_replacements(const ReplacementGroup& group);
|
||||
void unregister_replacements(const ReplacementKey& key);
|
||||
void clear_replacements();
|
||||
|
||||
ReplacementGroup load_replacement_directory(const std::filesystem::path& root, ReplacementOptions options = {});
|
||||
void reload_replacement_directory(const std::filesystem::path& root, ReplacementGroup& group,
|
||||
ReplacementOptions options = {});
|
||||
|
||||
} // namespace aurora::texture
|
||||
|
||||
#endif
|
||||
@@ -1089,10 +1089,3 @@ void pop_debug_group() {
|
||||
}
|
||||
|
||||
const AuroraStats* aurora_get_stats() { return &aurora::gfx::g_stats; }
|
||||
|
||||
void aurora_set_texture_replacements_enabled(const bool enabled) {
|
||||
aurora::g_config.allowTextureReplacements = enabled;
|
||||
aurora::gfx::texture_replacement::reload();
|
||||
}
|
||||
|
||||
void aurora_reload_texture_replacements() { aurora::gfx::texture_replacement::reload(); }
|
||||
|
||||
+468
-263
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,6 @@
|
||||
namespace aurora::gfx::texture_replacement {
|
||||
void initialize() noexcept;
|
||||
void shutdown() noexcept;
|
||||
void reload() noexcept;
|
||||
void register_tlut(const GXTlutObj* obj, const void* data, GXTlutFmt format, uint16_t entries) noexcept;
|
||||
void load_tlut(const GXTlutObj* obj, uint32_t idx) noexcept;
|
||||
std::optional<TextureHandle> find_replacement(const GXTexObj_& obj) noexcept;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "command_processor.hpp"
|
||||
|
||||
#include "../gfx/common.hpp"
|
||||
#include "../gfx/texture_replacement.hpp"
|
||||
#include "dolphin/gx/GXAurora.h"
|
||||
#include "gx.hpp"
|
||||
#include "gx_fmt.hpp"
|
||||
|
||||
+16
-4
@@ -15,6 +15,7 @@
|
||||
#include <absl/container/flat_hash_set.h>
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <cfloat>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
@@ -78,6 +79,14 @@ struct TlutObjectCache {
|
||||
|
||||
absl::flat_hash_map<u32, CachedTextureEntry> s_textureObjectCaches;
|
||||
absl::flat_hash_map<u32, TlutObjectCache> s_tlutObjectCaches;
|
||||
std::atomic_bool s_staticTextureCacheClearPending = false;
|
||||
|
||||
void do_clear_static_texture_cache() noexcept {
|
||||
s_textureObjectCaches.clear();
|
||||
for (auto& [_, cache] : s_tlutObjectCaches) {
|
||||
cache.staticTextureUsers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
DynamicPaletteKey make_dynamic_palette_key(const GXTexObj_& obj, const GXState::CopyTextureRef& source) {
|
||||
return {
|
||||
@@ -147,6 +156,9 @@ gfx::TextureHandle get_tlut_texture(const GXTlutObj_& tlut) {
|
||||
|
||||
gfx::TextureHandle resolve_static_texture(const GXTexObj_& obj) {
|
||||
ZoneScoped;
|
||||
if (s_staticTextureCacheClearPending.exchange(false, std::memory_order_acq_rel)) {
|
||||
do_clear_static_texture_cache();
|
||||
}
|
||||
|
||||
if (obj.texObjId != 0) {
|
||||
if (const auto it = s_textureObjectCaches.find(obj.texObjId); it != s_textureObjectCaches.end()) {
|
||||
@@ -179,6 +191,9 @@ gfx::TextureHandle resolve_static_texture(const GXTexObj_& obj) {
|
||||
|
||||
gfx::TextureHandle resolve_static_palette_texture(const GXTexObj_& obj, const GXTlutObj_& tlut) {
|
||||
ZoneScoped;
|
||||
if (s_staticTextureCacheClearPending.exchange(false, std::memory_order_acq_rel)) {
|
||||
do_clear_static_texture_cache();
|
||||
}
|
||||
|
||||
if (obj.texObjId != 0) {
|
||||
if (const auto it = s_textureObjectCaches.find(obj.texObjId); it != s_textureObjectCaches.end()) {
|
||||
@@ -370,10 +385,7 @@ void clear_copy_texture_cache() noexcept {
|
||||
}
|
||||
|
||||
void clear_static_texture_cache() noexcept {
|
||||
s_textureObjectCaches.clear();
|
||||
for (auto& [_, cache] : s_tlutObjectCaches) {
|
||||
cache.staticTextureUsers.clear();
|
||||
}
|
||||
s_staticTextureCacheClearPending.store(true, std::memory_order_release);
|
||||
}
|
||||
|
||||
void evict_copy_texture(const void* dest) noexcept {
|
||||
|
||||
Reference in New Issue
Block a user