Another test toggle for phi tracking

This commit is contained in:
CamilleLaVey
2026-09-06 01:41:41 -04:00
parent a77c18fbbf
commit 6c87c031a2
12 changed files with 71 additions and 40 deletions
@@ -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"),
@@ -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,
@@ -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>
+8
View File
@@ -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)