Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ void PublishRegisteredShader(std::shared_ptr<ShaderRegistry>& registry, const st
void ResolvePreparedGraphics(const ShaderSnapshot& front, const std::shared_ptr<const ShaderSnapshot>& fragment, std::uint32_t primitiveType, const ShaderRecompiler::SpirvTarget& target);

ShaderRecompiler::RectListShaders PreparedRectangle(const ShaderSnapshot& snapshot, std::uint64_t vertexId, std::uint64_t fragmentId);
ShaderRecompiler::RectListShaders DrawRectangle(const ShaderSnapshot& front, const std::shared_ptr<const ShaderSnapshot>& fragment, std::uint64_t vertexId, std::uint64_t fragmentId, const ShaderRecompiler::SpirvTarget& target);

std::shared_ptr<const ShaderRecompiler::SourceHandle> SourceHandleFor(const ShaderSnapshot& snapshot, std::size_t codeOffset, const ShaderRecompiler::RecompileRequest& request);
ShaderRecompiler::PreparedShaderInvocation InvocationFor(const ShaderSnapshot& snapshot, std::size_t codeOffset, const ShaderRecompiler::RecompileRequest& request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ DrawVerdict Driver::draw(QueueState& queue, std::span<const std::uint32_t> packe
const auto buildRectList = [&] {
phaseTiming.Phase(DrawRowVectors);
require(programs.size() == 2 && programResults[0] != nullptr && programResults[1] != nullptr, "rect-list requires vertex and fragment programs");
auto rectangle = PreparedRectangle(*programs[0].snapshot, programResults[0]->variantId, programResults[1]->variantId);
auto rectangle = DrawRectangle(*programs[0].snapshot, programs[1].snapshot, programResults[0]->variantId, programResults[1]->variantId, localDevice->Target());
if (rectListBuilt) {
results[rectIndex] = std::move(rectangle.control);
results[rectIndex + 1] = std::move(rectangle.evaluation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,17 @@ ShaderRecompiler::RectListShaders PreparedRectangle(const ShaderSnapshot& snapsh
throw std::runtime_error("AGC driver: prepared rectangle artifacts are missing");
}

ShaderRecompiler::RectListShaders DrawRectangle(const ShaderSnapshot& front, const std::shared_ptr<const ShaderSnapshot>& fragment, std::uint64_t vertexId, std::uint64_t fragmentId, const ShaderRecompiler::SpirvTarget& target) {
const auto prepared = [&] {
std::lock_guard lock(front.prepared->mutex);
return std::ranges::any_of(front.prepared->rectangles, [&](const auto& entry) { return entry.vertexId == vertexId && entry.fragmentId == fragmentId; });
};
if (prepared()) return PreparedRectangle(front, vertexId, fragmentId);
APS5_LOG_ERR("Rect-list draw of shader 0x%llx has no rectangle for fragment shader 0x%llx; preparing it at draw", static_cast<unsigned long long>(front.codeAddress), static_cast<unsigned long long>(fragment->codeAddress));
ResolvePreparedGraphics(front, fragment, 17, target);
return PreparedRectangle(front, vertexId, fragmentId);
}

ShaderRecompiler::PreparedShaderInvocation InvocationFor(const ShaderSnapshot& snapshot, std::size_t codeOffset, const ShaderRecompiler::RecompileRequest& request) {
require(codeOffset < snapshot.code.size(), "prepared shader code offset is outside the snapshot");
const auto code = std::span(snapshot.code).subspan(codeOffset);
Expand Down
12 changes: 12 additions & 0 deletions core/libs/prx/libSceAgcDriver/tests/execution/PreparedGraphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ void Check(AgcDriver::VulkanDevice& device, AgcDriver::Graphics::ShaderPath path
ResolvePreparedGraphics(*front.snapshot, {}, 7, target);
Require(front.snapshot->prepared->fragments.size() == 1, "expired helper link was not removed");
Require(front.snapshot->prepared->rectangleProgress.size() == 1 && !front.snapshot->prepared->rectangleProgress.front().fragment.expired(), "expired rectangle progress was not removed");
auto drawOnly = prepared;
drawOnly.pixel.interpolatorSettings[0] = 0x405u;
const auto drawStages = PrepareGraphicsStages(drawOnly, target);
auto unlinked = std::make_shared<ShaderSnapshot>();
unlinked->type = 1;
unlinked->prepared->entries.push_back(drawStages.back().entry);
const auto drawPixelId = GetPreparedArtifact(*drawStages.back().entry.handle).variantId;
const auto drawVertexId = GetPreparedArtifact(*drawStages.front().entry.handle).variantId;
Require(drawVertexId == GetPreparedArtifact(*stages.front().entry.handle).variantId && drawPixelId != pixelArtifact.variantId && drawPixelId != newPixelId, "draw-only fragment test did not isolate a new fragment variant");
const auto drawRectangle = DrawRectangle(*front.snapshot, unlinked, drawVertexId, drawPixelId, target);
Require(!drawRectangle.control.spirv.empty() && !drawRectangle.evaluation.spirv.empty(), "a rect-list draw did not prepare the rectangle of a fragment variant prepared at draw");
static_cast<void>(PreparedRectangle(*front.snapshot, drawVertexId, drawPixelId));
}
if (!dump.empty()) {
for (std::size_t index = 0; index < stages.size(); ++index) {
Expand Down
Loading