mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
test(agc): an evicted draw entry serves no relocation through its alias
Add EvictedEntriesServeNoRelocation, run by a new ctest agc_driver_draw_cache_relocation_evicted (--evicted) with APS5_DRAW_CACHE_ENTRIES=2. It teaches a relocation alias as MovedDataHitsTheCache does, checks that one moved draw hits, evicts both taught entries with draws of another vertex shader, and requires that the next moved draw with the same contents does not hit. Before the alias named a key, the alias kept the evicted entry and served it.
This commit is contained in:
1 parent
41196116ee
commit
1d2fdfb261
2 files changed
+47
-2
No files matched your search
@@ -2292,6 +2292,13 @@ if(BUILD_TESTING)
|
||||
set_tests_properties(agc_driver_sparse_indirect_indices_unreadable PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
add_test(NAME agc_driver_draw_cache_relocation_evicted COMMAND agc_driver_draw_cache_relocation_tests --evicted)
|
||||
set_tests_properties(agc_driver_draw_cache_relocation_evicted PROPERTIES
|
||||
ENVIRONMENT "ANYPS5_NO_SHADER_CACHE=1;APS5_DRAW_CACHE_ENTRIES=2" SKIP_RETURN_CODE 77 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
|
||||
if(WIN32)
|
||||
set_tests_properties(agc_driver_draw_cache_relocation_evicted PROPERTIES ENVIRONMENT_MODIFICATION
|
||||
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
set_tests_properties(agc_driver_pixel_implicit_derivatives PROPERTIES TIMEOUT 30)
|
||||
set_tests_properties(agc_driver_storage_file_write PROPERTIES TIMEOUT 30 ENVIRONMENT "ANYPS5_NO_SHADER_CACHE=1;APS5_SUSPEND_DRAIN=1")
|
||||
set_tests_properties(agc_driver_draw_pipeline_trace PROPERTIES
|
||||
|
||||
@@ -135,6 +135,37 @@ void MovedDataHitsTheCache(bool libraries) {
|
||||
Require(again.lookups == 10 && again.hits == 5, mode + ": a draw at an address seen before did not reuse the cached draw (" + std::to_string(again.hits) + " hits)");
|
||||
}
|
||||
|
||||
void EvictedEntriesServeNoRelocation(bool libraries) {
|
||||
Registered(VertexHeader, VertexCode.data(), sizeof(VertexCode), 2);
|
||||
Registered(PixelHeader, PixelCode.data(), sizeof(PixelCode), 1);
|
||||
Registered(SecondVertexHeader, SecondVertexCode.data(), sizeof(SecondVertexCode), 2);
|
||||
const auto mode = std::string(libraries ? "with" : "without") + " graphics pipeline libraries";
|
||||
const auto draw = [&](const float* source, const std::uint32_t* vertexCode) {
|
||||
auto commands = DrawFrom({source}, vertexCode);
|
||||
Packet packet{commands.data(), static_cast<std::uint32_t>(commands.size()), 0, {}};
|
||||
Require(sceAgcDriverSubmitDcb(&packet) == 0, "the draw submission failed");
|
||||
AgcDriverWaitIdle_nid_postfix();
|
||||
return AgcDriver::DriverDetail::Driver::Get().DrawCacheCounters();
|
||||
};
|
||||
static std::array<std::array<float, 4>, 6> same{};
|
||||
for (auto& entry : same) entry = {1.0f, 0.0f, 0.0f, 0.0f};
|
||||
alignas(16) static std::array<std::array<float, 4>, 3> others{};
|
||||
for (std::size_t i = 0; i < others.size(); ++i) others[i] = {0.25f + 0.03125f * static_cast<float>(i), 0.0f, 0.0f, 0.0f};
|
||||
AgcDriver::DriverDetail::DrawEntryCounters counters{};
|
||||
for (std::size_t i = 0; i < 4; ++i) counters = draw(same[i].data(), VertexCode.data());
|
||||
Require(counters.lookups == 4 && counters.hits == 0 && counters.inserts == 2, mode + ": the draws that teach the moved pointer and its contents made " + std::to_string(counters.hits) + " hits and " + std::to_string(counters.inserts) + " inserts, expected 0 and 2");
|
||||
const auto relocated = draw(same[4].data(), VertexCode.data());
|
||||
Require(relocated.hits == 1, mode + ": a draw whose data moved after the teaching draws did not reuse the cached draw (" + std::to_string(relocated.hits) + " hits)");
|
||||
auto evicted = relocated;
|
||||
for (const auto& entry : others) {
|
||||
draw(entry.data(), SecondVertexCode.data());
|
||||
evicted = draw(entry.data(), SecondVertexCode.data());
|
||||
}
|
||||
Require(evicted.evictions - relocated.evictions >= 2 && evicted.inserts - relocated.inserts >= 2, mode + ": draws of another vertex shader did not evict the two taught entries from the draw cache (" + std::to_string(evicted.inserts - relocated.inserts) + " inserts, " + std::to_string(evicted.evictions - relocated.evictions) + " evictions; run with APS5_DRAW_CACHE_ENTRIES=2)");
|
||||
const auto after = draw(same[5].data(), VertexCode.data());
|
||||
Require(after.lookups == evicted.lookups + 1 && after.hits == evicted.hits, mode + ": a draw whose data moved reused a draw the cache had evicted, through its relocation alias (" + std::to_string(after.hits - evicted.hits) + " hits)");
|
||||
}
|
||||
|
||||
void SplitRunsNameTheirSharedWords() {
|
||||
alignas(16) static std::array<std::uint32_t, 4> data{1u, 2u, 3u, 4u};
|
||||
auto table = std::make_shared<ShaderRecompiler::SrtGuestWords>();
|
||||
@@ -228,9 +259,10 @@ void MovedForwardedWordReachesStageDataHit(bool libraries) {
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
int main(int argc, char** argv) {
|
||||
try {
|
||||
SplitRunsNameTheirSharedWords();
|
||||
const bool evicted = argc == 2 && std::string(argv[1]) == "--evicted";
|
||||
if (!evicted) SplitRunsNameTheirSharedWords();
|
||||
bool libraries = false;
|
||||
{
|
||||
const auto device = OpenVulkanTestDevice();
|
||||
@@ -238,6 +270,12 @@ int main() {
|
||||
libraries = device->GraphicsPipelineLibraries();
|
||||
}
|
||||
if (!libraries && std::getenv("APS5_NO_GPL") == nullptr) return VulkanTestSkipped;
|
||||
if (evicted) {
|
||||
EvictedEntriesServeNoRelocation(libraries);
|
||||
AgcDriverShutdown_nid_postfix();
|
||||
std::cout << "An evicted draw served no relocation " << (libraries ? "with" : "without") << " graphics pipeline libraries\n";
|
||||
return 0;
|
||||
}
|
||||
MovedDataHitsTheCache(libraries);
|
||||
UnrelocatedAliasesStayOut(libraries);
|
||||
MovedForwardedWordReachesStageDataHit(libraries);
|
||||
|
||||
Reference in new issue
Block a user