mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-06 12:13:57 +00:00
Another test toggle for phi tracking
This commit is contained in:
+1
@@ -32,6 +32,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||
USE_OPTIMIZED_VERTEX_BUFFERS("use_optimized_vertex_buffers"),
|
||||
ENABLE_MULTI_RANGE_STORAGE("enable_multi_range_storage"),
|
||||
ENABLE_SPARSE_BUFFER_BINDING("enable_sparse_buffer_binding"),
|
||||
ENABLE_SHADER_PHI_TRACKING("enable_shader_phi_tracking"),
|
||||
ENABLE_GPU_BUFFER_READBACK("enable_gpu_buffer_readback"),
|
||||
SYNC_MEMORY_OPERATIONS("sync_memory_operations"),
|
||||
BUFFER_REORDER_DISABLE("disable_buffer_reorder"),
|
||||
|
||||
+7
@@ -941,6 +941,13 @@ abstract class SettingsItem(
|
||||
descriptionId = R.string.enable_sparse_buffer_binding_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.ENABLE_SHADER_PHI_TRACKING,
|
||||
titleId = R.string.enable_shader_phi_tracking,
|
||||
descriptionId = R.string.enable_shader_phi_tracking_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SYNC_MEMORY_OPERATIONS,
|
||||
|
||||
+1
@@ -340,6 +340,7 @@ class SettingsFragmentPresenter(
|
||||
add(BooleanSetting.USE_OPTIMIZED_VERTEX_BUFFERS.key)
|
||||
add(BooleanSetting.ENABLE_MULTI_RANGE_STORAGE.key)
|
||||
add(BooleanSetting.ENABLE_SPARSE_BUFFER_BINDING.key)
|
||||
add(BooleanSetting.ENABLE_SHADER_PHI_TRACKING.key)
|
||||
|
||||
add(HeaderSetting(R.string.hacks))
|
||||
|
||||
|
||||
@@ -574,6 +574,8 @@
|
||||
<string name="enable_multi_range_storage_description">toggle for test on multi-range.</string>
|
||||
<string name="enable_sparse_buffer_binding">Sparse Buffer Binding</string>
|
||||
<string name="enable_sparse_buffer_binding_description">toggle for test on sparse buffer binding.</string>
|
||||
<string name="enable_shader_phi_tracking">Shader Phi Tracking</string>
|
||||
<string name="enable_shader_phi_tracking_description">toggle for test on shader phi tracking.</string>
|
||||
|
||||
<string name="hacks">Hacks</string>
|
||||
|
||||
|
||||
@@ -608,6 +608,14 @@ struct Values {
|
||||
true,
|
||||
true};
|
||||
|
||||
SwitchableSetting<bool> enable_shader_phi_tracking{linkage,
|
||||
true,
|
||||
"enable_shader_phi_tracking",
|
||||
Category::RendererAdvanced,
|
||||
Specialization::Default,
|
||||
true,
|
||||
true};
|
||||
|
||||
#ifdef __ANDROID__
|
||||
SwitchableSetting<bool> use_optimized_vertex_buffers{linkage,
|
||||
false,
|
||||
|
||||
@@ -271,6 +271,8 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
|
||||
tr("toggle for test on multi-range."));
|
||||
INSERT(Settings, enable_sparse_buffer_binding, tr("Sparse buffer binding"),
|
||||
tr("toggle for test on sparse buffer binding."));
|
||||
INSERT(Settings, enable_shader_phi_tracking, tr("Shader phi tracking"),
|
||||
tr("toggle for test on shader phi tracking."));
|
||||
INSERT(Settings, fix_bloom_effects, tr("Fix bloom effects"), tr("Removes bloom in Burnout."));
|
||||
|
||||
INSERT(Settings, rescale_hack, tr("Enable Legacy Rescale Pass"),
|
||||
|
||||
@@ -359,6 +359,12 @@ std::optional<ConstBufferAddr> TrackPhi(const IR::Inst* phi, Environment& env,
|
||||
}
|
||||
|
||||
std::optional<ConstBufferAddr> Track(const IR::Value& value, Environment& env, const HostTranslateInfo& host_info) {
|
||||
if (!Settings::values.enable_shader_phi_tracking.GetValue()) {
|
||||
return IR::BreadthFirstSearch(
|
||||
value, [&env, &host_info](const IR::Inst* inst) -> std::optional<ConstBufferAddr> {
|
||||
return TryGetConstBuffer(inst, env, host_info);
|
||||
});
|
||||
}
|
||||
bool ambiguous = false;
|
||||
const std::optional<ConstBufferAddr> result{IR::BreadthFirstSearch(
|
||||
value, [&env, &host_info, &ambiguous](const IR::Inst* inst)
|
||||
|
||||
@@ -1937,6 +1937,9 @@ void BufferCache<P>::DownloadBufferMemory(Buffer& buffer, DAddr device_addr, u64
|
||||
|
||||
template <class P>
|
||||
void BufferCache<P>::DeleteBuffer(BufferId buffer_id, bool do_not_mark) {
|
||||
if constexpr (requires { runtime.OnBufferDeleted(slot_buffers[buffer_id]); }) {
|
||||
runtime.OnBufferDeleted(slot_buffers[buffer_id]);
|
||||
}
|
||||
bool dirty_index{false};
|
||||
boost::container::small_vector<u64, NUM_VERTEX_BUFFERS> dirty_vertex_buffers;
|
||||
const auto scalar_replace = [buffer_id](Binding& binding) {
|
||||
|
||||
@@ -207,6 +207,10 @@ public:
|
||||
multi_range_buffers.Invalidate(key);
|
||||
}
|
||||
|
||||
void OnBufferDeleted(const Buffer& buffer) {
|
||||
multi_range_buffers.DropOwner(buffer.Handle());
|
||||
}
|
||||
|
||||
void BindUniformBuffer(const Buffer& buffer, u32 offset, u32 size) {
|
||||
BindBuffer(buffer, offset, size);
|
||||
}
|
||||
|
||||
@@ -246,6 +246,12 @@ MultiRangeRef MultiRangeBufferCache::Get(u64 key, std::span<const MultiRangeSour
|
||||
entry.size = total;
|
||||
if (CanBindSparse(sources)) {
|
||||
entry.sparse_handle = CreateSparse(sources, total);
|
||||
if (entry.sparse_handle != VK_NULL_HANDLE) {
|
||||
entry.owners.reserve(sources.size());
|
||||
for (const MultiRangeSource& source : sources) {
|
||||
entry.owners.push_back(source.handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entry.sparse_handle == VK_NULL_HANDLE) {
|
||||
VkBufferUsageFlags flags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
|
||||
@@ -296,6 +302,28 @@ void MultiRangeBufferCache::MarkGathered(u64 key) {
|
||||
}
|
||||
}
|
||||
|
||||
void MultiRangeBufferCache::DropOwner(VkBuffer owner) {
|
||||
if (owner == VK_NULL_HANDLE) {
|
||||
return;
|
||||
}
|
||||
for (auto it = entries.begin(); it != entries.end();) {
|
||||
Entry& entry = it->second;
|
||||
bool owned = false;
|
||||
for (const VkBuffer handle : entry.owners) {
|
||||
if (handle == owner) {
|
||||
owned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (owned) {
|
||||
DestroySparse(entry.sparse_handle);
|
||||
it = entries.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MultiRangeBufferCache::Invalidate(u64 key) {
|
||||
const auto it = entries.find(key);
|
||||
if (it != entries.end()) {
|
||||
|
||||
@@ -59,6 +59,8 @@ public:
|
||||
|
||||
void Invalidate(u64 key);
|
||||
|
||||
void DropOwner(VkBuffer owner);
|
||||
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
@@ -74,6 +76,7 @@ private:
|
||||
VkDeviceSize size{};
|
||||
u64 geometry{};
|
||||
bool dirty{true};
|
||||
std::vector<VkBuffer> owners;
|
||||
};
|
||||
|
||||
[[nodiscard]] u64 HashSources(std::span<const MultiRangeSource> sources) const;
|
||||
|
||||
@@ -305,48 +305,13 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo &ci, MemoryUsa
|
||||
.priority = 0.f,
|
||||
};
|
||||
|
||||
const VkDevice logical = *device.GetLogical();
|
||||
const auto &dld = device.GetDispatchLoader();
|
||||
|
||||
VkBuffer handle{};
|
||||
vk::Check(dld.vkCreateBuffer(logical, &ci, nullptr, &handle));
|
||||
|
||||
const VkBufferMemoryRequirementsInfo2 reqs_info{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
|
||||
.pNext = nullptr,
|
||||
.buffer = handle,
|
||||
};
|
||||
VkMemoryRequirements2 reqs2{
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
|
||||
.pNext = nullptr,
|
||||
.memoryRequirements = {},
|
||||
};
|
||||
dld.vkGetBufferMemoryRequirements2(logical, &reqs_info, &reqs2);
|
||||
|
||||
VkMemoryRequirements reqs = reqs2.memoryRequirements;
|
||||
reqs.alignment = (std::max)(reqs.alignment, min_alignment);
|
||||
reqs.memoryTypeBits &= alloc_ci.memoryTypeBits;
|
||||
|
||||
VmaAllocation allocation{};
|
||||
VmaAllocationInfo alloc_info{};
|
||||
VkResult res = vmaAllocateMemory(allocator, &reqs, &alloc_ci, &allocation, &alloc_info);
|
||||
if (res != VK_SUCCESS) {
|
||||
auto relaxed = alloc_ci;
|
||||
relaxed.flags &= ~VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT;
|
||||
res = vmaAllocateMemory(allocator, &reqs, &relaxed, &allocation, &alloc_info);
|
||||
}
|
||||
if (res != VK_SUCCESS) {
|
||||
dld.vkDestroyBuffer(logical, handle, nullptr);
|
||||
vk::Check(res);
|
||||
}
|
||||
const VkResult bind_res = vmaBindBufferMemory(allocator, allocation, handle);
|
||||
if (bind_res != VK_SUCCESS) {
|
||||
vmaFreeMemory(allocator, allocation);
|
||||
dld.vkDestroyBuffer(logical, handle, nullptr);
|
||||
vk::Check(bind_res);
|
||||
}
|
||||
|
||||
VmaAllocation allocation{};
|
||||
VkMemoryPropertyFlags property_flags{};
|
||||
|
||||
vk::Check(vmaCreateBufferWithAlignment(allocator, &ci, &alloc_ci, min_alignment, &handle,
|
||||
&allocation, &alloc_info));
|
||||
vmaGetAllocationMemoryProperties(allocator, allocation, &property_flags);
|
||||
|
||||
u8 *data = reinterpret_cast<u8 *>(alloc_info.pMappedData);
|
||||
@@ -356,7 +321,8 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo &ci, MemoryUsa
|
||||
}
|
||||
const bool is_coherent = (property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
|
||||
|
||||
return vk::Buffer(handle, logical, allocator, allocation, mapped_data, is_coherent, dld);
|
||||
return vk::Buffer(handle, *device.GetLogical(), allocator, allocation, mapped_data, is_coherent,
|
||||
device.GetDispatchLoader());
|
||||
}
|
||||
|
||||
MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements &reqs, MemoryUsage usage)
|
||||
|
||||
Reference in New Issue
Block a user