mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-27 00:28:14 +00:00
Merge pull request #6129 from fdfawef324/claude/agc-tessellation-refusal-fields
fix(agc): print the VGT_TF_PARAM and VGT_LS_HS_CONFIG fields of a refused tessellation draw
This commit is contained in:
2 files changed
+45
-1
No files matched your search
@@ -17,6 +17,7 @@
|
||||
#include <span>
|
||||
#include <array>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
namespace AgcDriver::Graphics {
|
||||
namespace {
|
||||
@@ -50,6 +51,25 @@ std::string zeroMessage(std::uint32_t offset, std::uint32_t value, const char* n
|
||||
return std::string(name) + " is unsupported" + detail;
|
||||
}
|
||||
|
||||
std::string tessellationMessage(std::uint32_t config, std::uint32_t parameters, const ShaderRecompiler::TessellationConfiguration& tess) {
|
||||
static constexpr std::array<std::string_view, 3> Types{"TESS_ISOLINE", "TESS_TRIANGLE", "TESS_QUAD"};
|
||||
static constexpr std::array<std::string_view, 4> Partitionings{"PART_INTEGER", "PART_POW2", "PART_FRAC_ODD", "PART_FRAC_EVEN"};
|
||||
static constexpr std::array<std::string_view, 4> Topologies{"OUTPUT_POINT", "OUTPUT_LINE", "OUTPUT_TRIANGLE_CW", "OUTPUT_TRIANGLE_CCW"};
|
||||
std::ostringstream message;
|
||||
const auto field = [&](std::string_view name, std::uint32_t value, std::span<const std::string_view> names) {
|
||||
message << name << '=' << value;
|
||||
if (value < names.size()) message << ' ' << names[value];
|
||||
};
|
||||
message << "VGT_TF_PARAM=0x" << std::hex << parameters << std::dec << " (";
|
||||
field("TYPE", tess.domain, Types);
|
||||
message << ", ";
|
||||
field("PARTITIONING", tess.partitioning, Partitionings);
|
||||
message << ", ";
|
||||
field("TOPOLOGY", tess.outputTopology, Topologies);
|
||||
message << "), VGT_LS_HS_CONFIG=0x" << std::hex << config << std::dec << " (NUM_PATCHES=" << tess.patchesPerGroup << ", HS_NUM_INPUT_CP=" << tess.inputControlPoints << ", HS_NUM_OUTPUT_CP=" << tess.outputControlPoints << "): only triangle and quad domains with integer, fractional-even or fractional-odd partitioning and triangle output are supported by the reference path";
|
||||
return message.str();
|
||||
}
|
||||
|
||||
void zero(const Registers& registers, std::uint32_t offset, std::uint32_t mask, const char* name, RegisterBank bank = RegisterBank::Context) {
|
||||
const auto value = read(registers, offset, bank);
|
||||
if ((value & mask) != 0) throw std::runtime_error(zeroMessage(offset, value, name));
|
||||
@@ -915,7 +935,7 @@ ShaderStages DecodeShaderStages(const QueueState& queue, bool vertexWorkgroup) {
|
||||
validate(tess.inputControlPoints != 0 && tess.inputControlPoints <= 32 && tess.outputControlPoints != 0 && tess.outputControlPoints <= 32, "invalid tessellation control-point counts");
|
||||
validate(tess.patchesPerGroup != 0, "VGT_LS_HS_CONFIG.NUM_PATCHES is zero");
|
||||
if ((parameters & ~0x000600ffu) != 0) Require(false, zeroMessage(0x2db, parameters, "VGT_TF_PARAM donut, factor detection, memory type or reserved state"));
|
||||
validate((tess.domain == 1 || tess.domain == 2) && (tess.partitioning == 0 || tess.partitioning == 2 || tess.partitioning == 3) && (tess.outputTopology == 2 || tess.outputTopology == 3), "only triangle and quad domains with integer, fractional-even or fractional-odd partitioning and triangle output are supported by the reference path");
|
||||
if (!((tess.domain == 1 || tess.domain == 2) && (tess.partitioning == 0 || tess.partitioning == 2 || tess.partitioning == 3) && (tess.outputTopology == 2 || tess.outputTopology == 3))) validate(false, tessellationMessage(config, parameters, tess).c_str());
|
||||
result.minTessellationLevel = readFloat(queue.context, 0x287);
|
||||
result.maxTessellationLevel = readFloat(queue.context, 0x286);
|
||||
Require(result.minTessellationLevel >= 0.0f && result.minTessellationLevel <= 63.0f && result.minTessellationLevel <= result.maxTessellationLevel && result.maxTessellationLevel >= 1.0f, "tessellation level clamps need 0 <= VGT_HOS_MIN_TESS_LEVEL <= 63, VGT_HOS_MAX_TESS_LEVEL >= 1 and the minimum at most the maximum");
|
||||
|
||||
@@ -995,6 +995,29 @@ void ShaderStageTests() {
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "missing register");
|
||||
}
|
||||
|
||||
void UnsupportedTessellationFieldTests() {
|
||||
auto queue = makeState();
|
||||
queue.context[0x2d5] = 0x0200210d;
|
||||
queue.userConfig[0x242] = 9;
|
||||
queue.userConfig[0x25b] = 0x1fe55;
|
||||
queue.context[0x286] = 0x42800000;
|
||||
queue.context[0x287] = 0x3f800000;
|
||||
for (const auto [config, parameters, fields] : {
|
||||
std::tuple{0xc355u, 0x40045u, "VGT_TF_PARAM=0x40045 (TYPE=1 TESS_TRIANGLE, PARTITIONING=1 PART_POW2, TOPOLOGY=2 OUTPUT_TRIANGLE_CW), VGT_LS_HS_CONFIG=0xc355 (NUM_PATCHES=85, HS_NUM_INPUT_CP=3, HS_NUM_OUTPUT_CP=3)"},
|
||||
std::tuple{0x1033fu, 0x40066u, "VGT_TF_PARAM=0x40066 (TYPE=2 TESS_QUAD, PARTITIONING=1 PART_POW2, TOPOLOGY=3 OUTPUT_TRIANGLE_CCW), VGT_LS_HS_CONFIG=0x1033f (NUM_PATCHES=63, HS_NUM_INPUT_CP=3, HS_NUM_OUTPUT_CP=4)"},
|
||||
std::tuple{0xc355u, 0x40048u, "VGT_TF_PARAM=0x40048 (TYPE=0 TESS_ISOLINE, PARTITIONING=2 PART_FRAC_ODD, TOPOLOGY=2 OUTPUT_TRIANGLE_CW)"},
|
||||
std::tuple{0xc355u, 0x40029u, "(TYPE=1 TESS_TRIANGLE, PARTITIONING=2 PART_FRAC_ODD, TOPOLOGY=1 OUTPUT_LINE)"},
|
||||
std::tuple{0xc355u, 0x4000du, "(TYPE=1 TESS_TRIANGLE, PARTITIONING=3 PART_FRAC_EVEN, TOPOLOGY=0 OUTPUT_POINT)"},
|
||||
std::tuple{0xc355u, 0x4004bu, "(TYPE=3, PARTITIONING=2 PART_FRAC_ODD, TOPOLOGY=2 OUTPUT_TRIANGLE_CW)"},
|
||||
std::tuple{0xc355u, 0x400f1u, "(TYPE=1 TESS_TRIANGLE, PARTITIONING=4, TOPOLOGY=7)"}}) {
|
||||
queue.context[0x2d6] = config;
|
||||
queue.context[0x2db] = parameters;
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "VGT_SHADER_STAGES_EN=0x200210d: VGT_TF_PARAM=0x");
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, fields);
|
||||
expectFailure([&] { AgcDriver::Graphics::DecodeState(queue); }, "): only triangle and quad domains with integer, fractional-even or fractional-odd partitioning and triangle output are supported by the reference path");
|
||||
}
|
||||
}
|
||||
|
||||
void NggVertexWorkgroupTests() {
|
||||
auto queue = makeState();
|
||||
queue.context[0x2d5] = 0x12010;
|
||||
@@ -8792,6 +8815,7 @@ int main(int argc, char** argv) {
|
||||
depthCopyFormatTests();
|
||||
quadPixelMaskTests();
|
||||
ShaderStageTests();
|
||||
UnsupportedTessellationFieldTests();
|
||||
NggVertexWorkgroupTests();
|
||||
inactiveVertexPointSizeTests();
|
||||
PolygonPrimitiveTests();
|
||||
|
||||
Reference in new issue
Block a user