mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-07 13:39:55 +00:00
fix(shader): take a hull's input stride from its patch term when it reads one control point
derive() learned the LS-to-HS stride from the control-point term of hull LDS reads, or from the patch term of reads at a computed control-point index. A hull with one input control point reads it at constant offsets, so neither applies and the stride stays unknown ('the hull shader reads no LDS per control point, so the local stride is unknown'). Every hull read already has a patch term of exactly inputControlPoints * localStride, so take the stride from it for reads without a control-point term too. Resident Evil Village's quad patches have one input control point.
This commit is contained in:
1 parent
c1e4a0ba8b
commit
e25d561b7c
2 files changed
+29
-1
No files matched your search
@@ -63,6 +63,16 @@ alignas(256) constexpr std::array<std::uint32_t, 54> HullCompareBranch{
|
||||
0x16161690, 0x4c1616ff, 0x00008000, 0xe0741000, 0x0202070b, 0xbf810000,
|
||||
};
|
||||
|
||||
alignas(256) constexpr std::array<std::uint32_t, 49> HullSingleInput{
|
||||
0xd7650000, 0x000100c1, 0xd7660000, 0x000200c1, 0xbf8a0000, 0x7da206f9, 0x81060000, 0xd5480014,
|
||||
0x02151101, 0x362402ff, 0x000000ff, 0x160028a0, 0xd5430015, 0x022224ff, 0x00000020, 0xdbfc0000,
|
||||
0x02000015, 0x162c2890, 0xd5430016, 0x045a24ff, 0x00000030, 0xbf8cc07f, 0xe0781000, 0x02020216,
|
||||
0x7da82881, 0xbe94047e, 0xb06a0020, 0x162602f9, 0x0086066a, 0xd8d80008, 0x06000013, 0xd8dc0201,
|
||||
0x07000013, 0xbf8cc07f, 0x7e300306, 0x7e320306, 0x7e340306, 0x7e360306, 0x34142484, 0xbefe0414,
|
||||
0xe0781000, 0x0403180a, 0x4a162481, 0x16161690, 0x4c1616ff, 0x00008000, 0xe0741000, 0x0202070b,
|
||||
0xbf810000,
|
||||
};
|
||||
|
||||
alignas(256) constexpr std::array<std::uint32_t, 51> HullRestoredExecSaved{
|
||||
0xd7650000, 0x000100c1, 0xd7660000, 0x000200c1, 0xbf8a0000, 0x7da206f9, 0x81060000, 0xd5480014,
|
||||
0x02151101, 0x362402ff, 0x000000ff, 0x160028a0, 0xd5430015, 0x040224ff, 0x00000060, 0xdbfc0000,
|
||||
@@ -717,6 +727,23 @@ void RequireRegisteredStages() {
|
||||
AgcDriverShutdown_nid_postfix();
|
||||
}
|
||||
|
||||
ShaderRecompiler::RecompileResult CompileHull(const ShaderRecompiler::SpirvTarget& target, std::span<const std::uint32_t> code, const ShaderRecompiler::TessellationConfiguration& configuration) {
|
||||
static const std::array<std::uint32_t, 16> userData{0x1000u};
|
||||
const std::array<ShaderRecompiler::MemoryRegion, 1> memory{{{reinterpret_cast<std::uintptr_t>(code.data()), std::as_bytes(code)}}};
|
||||
const ShaderRecompiler::RecompileRequest request{
|
||||
{ShaderStage::TessellationControl, reinterpret_cast<std::uintptr_t>(code.data()), code, 0, {}},
|
||||
{64, 0u, userData, std::nullopt, std::nullopt, ShaderRecompiler::ShaderVertexStageInfo{}, memory},
|
||||
target,
|
||||
ShaderRecompiler::BindingLayout{0, 0, 0, AgcDriver::Graphics::PipelinePushSlotBytes},
|
||||
ShaderRecompiler::GraphicsCompileContext{0u, {}, std::nullopt, configuration, {reinterpret_cast<std::uintptr_t>(Indices.data()), static_cast<std::uint32_t>(Indices.size()), 2, 1}},
|
||||
};
|
||||
return ShaderRecompiler::Recompile(request);
|
||||
}
|
||||
|
||||
void RequireSingleControlPointHulls(const ShaderRecompiler::SpirvTarget& target) {
|
||||
Require(!CompileHull(target, HullSingleInput, {1u, 3u, 1u, 2u, 2u}).spirv.empty(), "a hull that reads only the one input control point of its patch was not compiled");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -728,6 +755,7 @@ int main() {
|
||||
std::puts("tessellation: skipped, the device has no tessellation shaders");
|
||||
return VulkanTestSkipped;
|
||||
}
|
||||
RequireSingleControlPointHulls(target);
|
||||
ExpectRefusal(target, ShaderStage::TessellationControl, HullUnguardedFactors, "not written by control point 0 alone");
|
||||
ExpectRefusal(target, ShaderStage::TessellationControl, HullSquaredAddress, "not a whole number of control points");
|
||||
ExpectRefusal(target, ShaderStage::TessellationControl, HullHalfSlotIndex, "not a whole number of control points");
|
||||
|
||||
@@ -659,7 +659,7 @@ private:
|
||||
for (auto& access : accesses) {
|
||||
if (access.kind == TessellationAttribute::LocalOutput) agree(localStride, access.address.relative, access.pc);
|
||||
if (access.kind == TessellationAttribute::ControlInput && access.address.vertex != 0) agree(localStride, access.address.vertex, access.pc);
|
||||
if (access.kind == TessellationAttribute::ControlInput && access.address.dynamic && access.address.relative > 0 && access.address.relative % inputs == 0) agree(localStride, access.address.relative / inputs, access.pc);
|
||||
if (access.kind == TessellationAttribute::ControlInput && (access.address.dynamic || access.address.vertex == 0) && access.address.relative > 0 && access.address.relative % inputs == 0) agree(localStride, access.address.relative / inputs, access.pc);
|
||||
if (access.kind == TessellationAttribute::ControlOutput && access.address.vertex != 0) agree(controlStride, access.address.vertex, access.pc);
|
||||
if (access.kind == TessellationAttribute::EvaluationInput) {
|
||||
const auto end = access.address.constant + 4 * static_cast<std::int64_t>(access.components);
|
||||
|
||||
Reference in new issue
Block a user