mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 00:53:02 -05:00
feat(agc): implement primitive-ordered pixel shaders with fragment shader interlock
DecodeState and the draw precheck rejected DB_SHADER_CONTROL bit 16, PRIMITIVE_ORDERED_PIXEL_SHADER (POPS), which runs the ordered section of overlapping pixels' shaders in primitive order. The bit now reaches the recompiler as a pixel stage field, and such a pixel shader declares PixelInterlockOrderedEXT and runs its whole body between OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT; an invocation that a BDA read fault kills ends the interlock first. The POPS collision SGPRs read 0, so a title skips its POPS wait and runs its per-collision loop once. An image_load still reads a sampled binding, which misses an earlier overlapping primitive's image_store in the same draw. The device enables VK_EXT_fragment_shader_interlock when it has fragmentShaderPixelInterlock; without it the recompile throws, as does a nonzero POPS_OVERLAP_NUM_SAMPLES. The field is part of the recompile cache key, the draw key and the serialized request (version 10).
This commit is contained in:
1 parent
3e32797cca
commit
e1d4e699be
21 files changed
+462
-11
No files matched your search
@@ -305,6 +305,7 @@ void writePixelInfo(Writer& writer, const ShaderPixelStageInfo& info) {
|
||||
writer.WriteBool(info.earlyZ);
|
||||
writer.WriteBool(info.executeOnNoop);
|
||||
writer.WriteU8(static_cast<std::uint8_t>(info.conservativeZExport));
|
||||
writer.WriteBool(info.orderedPixelShader);
|
||||
for (const std::uint8_t value : info.targetOutputMode) {
|
||||
writer.WriteU8(value);
|
||||
}
|
||||
@@ -341,6 +342,7 @@ ShaderPixelStageInfo readPixelInfo(Reader& reader, std::uint32_t version) {
|
||||
info.earlyZ = reader.ReadBool();
|
||||
info.executeOnNoop = reader.ReadBool();
|
||||
if (version >= 7u) info.conservativeZExport = readConservativeZExport(reader);
|
||||
if (version >= 11u) info.orderedPixelShader = reader.ReadBool();
|
||||
for (std::uint8_t& value : info.targetOutputMode) {
|
||||
value = reader.ReadU8();
|
||||
}
|
||||
@@ -697,7 +699,7 @@ std::string RequestSerializer::Serialize(const RecompileRequest& request) const
|
||||
std::string buffer;
|
||||
Writer writer(buffer);
|
||||
writer.WriteU32(0x41505335u);
|
||||
writer.WriteU32(10u);
|
||||
writer.WriteU32(11u);
|
||||
writeShaderBinary(writer, request.shader);
|
||||
writeGuestContext(writer, request.context);
|
||||
writeSpirvTarget(writer, request.target);
|
||||
@@ -723,7 +725,7 @@ DeserializedRequest RequestSerializer::Deserialize(std::string_view text) const
|
||||
Reader reader(decoded);
|
||||
if (reader.ReadU32() != 0x41505335u) throw std::runtime_error("invalid recompile request signature");
|
||||
const auto version = reader.ReadU32();
|
||||
if (version < 1u || version > 10u) throw std::runtime_error("unsupported recompile request serialization version");
|
||||
if (version < 1u || version > 11u) throw std::runtime_error("unsupported recompile request serialization version");
|
||||
DeserializedRequest result{};
|
||||
result.request.shader = readShaderBinary(reader, result.shaderCode, result.shaderHeader);
|
||||
result.request.context = readGuestContext(reader, result, version);
|
||||
|
||||
Reference in new issue
Block a user