mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-21 16:12:47 -05:00
The shader info collector refused an out-of-range interpolation parameter reference without saying which one. The message now gives the attribute, component and mode it read and the pixel input count it was checked against, so a title's stop at this check names the attribute its pixel shader reads past the inputs the draw declares. Test: interpolation_reference_range builds pixel programs with an attribute past the inputs, a component past w and a reserved mode, and checks the message names each. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Co-authored-by: overlordxrz-source <overlordxrz-source@users.noreply.github.com>
54 lines
2.3 KiB
C++
54 lines
2.3 KiB
C++
#include "IntermediateRepresentation/IrBuilder.hpp"
|
|
#include "Optimization/ShaderInfoCollector.hpp"
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
|
|
using namespace ShaderRecompiler;
|
|
|
|
namespace {
|
|
|
|
std::string Collect(std::uint32_t attribute, std::uint32_t component, std::uint32_t mode, std::uint32_t inputNum) {
|
|
IrProgram program;
|
|
program.Resources().stage = IrShaderStage::Pixel;
|
|
program.Resources().resourceTrackingComplete = true;
|
|
auto& block = program.CreateBlock();
|
|
program.SetEntryBlock(block);
|
|
program.BlockOrder().push_back(&block);
|
|
IrBuilder builder(program);
|
|
builder.SetInsertionPoint(block);
|
|
auto& parameter = builder.Emit(IrOpcode::GetInterpolationParameter, IrType::U32, {&builder.Constant(attribute), &builder.Constant(component), &builder.Constant(mode)});
|
|
static_cast<void>(builder.Emit(IrOpcode::ReferenceU32, IrType::Void, {¶meter}));
|
|
static_cast<void>(builder.Emit(IrOpcode::Return, IrType::Void, {}));
|
|
ShaderPixelInputInfo pixel {};
|
|
pixel.inputNum = inputNum;
|
|
try {
|
|
ShaderInfoCollector().Collect(program, ShaderStageInputInfo {nullptr, &pixel, nullptr});
|
|
} catch (const std::runtime_error& error) {
|
|
return error.what();
|
|
}
|
|
return {};
|
|
}
|
|
|
|
}
|
|
|
|
int main() {
|
|
int failures = 0;
|
|
const auto expect = [&](bool value, const char* name, const std::string& message) {
|
|
if (!value) {
|
|
std::fprintf(stderr, "%s: %s\n", name, message.c_str());
|
|
++failures;
|
|
}
|
|
};
|
|
const auto attribute = Collect(5u, 1u, 0u, 2u);
|
|
expect(attribute.find("interpolation parameter reference is out of range (attribute 5 component 1 mode 0, 2 inputs)") != std::string::npos, "an attribute past the pixel inputs", attribute);
|
|
const auto component = Collect(0u, 4u, 2u, 1u);
|
|
expect(component.find("(attribute 0 component 4 mode 2, 1 inputs)") != std::string::npos, "a component past w", component);
|
|
const auto mode = Collect(1u, 3u, 3u, 3u);
|
|
expect(mode.find("(attribute 1 component 3 mode 3, 3 inputs)") != std::string::npos, "a reserved interpolation mode", mode);
|
|
const auto inRange = Collect(1u, 3u, 2u, 2u);
|
|
expect(inRange.find("interpolation parameter reference") == std::string::npos, "an in-range reference", inRange);
|
|
return failures == 0 ? 0 : 1;
|
|
}
|