Adds tests for the final combiner stage flags.

This commit is contained in:
Erik Abair 2022-03-12 08:18:49 -08:00
parent 89632200f8
commit 5225bf7edd
4 changed files with 102 additions and 11 deletions

View File

@ -185,8 +185,8 @@ void TestHost::SetVertexBufferAttributes(uint32_t enabled_fields) {
// FIXME: Figure out what to do in cases where there are multiple stages with different swizzle flags.
// Is this supported by hardware?
Vertex *vptr = texture_stage_[0].IsLinear() ? vertex_buffer_->linear_vertex_buffer_
: vertex_buffer_->normalized_vertex_buffer_;
Vertex *vptr =
texture_stage_[0].IsLinear() ? vertex_buffer_->linear_vertex_buffer_ : vertex_buffer_->normalized_vertex_buffer_;
auto set = [this, enabled_fields](VertexAttribute attribute, uint32_t attribute_index, uint32_t format, uint32_t size,
const void *data) {
@ -1302,19 +1302,23 @@ void TestHost::SetFinalCombiner0(TestHost::CombinerSource a_source, bool a_alpha
void TestHost::SetFinalCombiner1(TestHost::CombinerSource e_source, bool e_alpha, bool e_invert,
TestHost::CombinerSource f_source, bool f_alpha, bool f_invert,
TestHost::CombinerSource g_source, bool g_alpha, bool g_invert,
bool specular_add_invert_r12, bool specular_add_invert_r5, bool specular_clamp) const {
bool specular_add_invert_r0, bool specular_add_invert_v1, bool specular_clamp) const {
auto channel = [](CombinerSource src, bool alpha, bool invert) { return src + (alpha << 4) + (invert << 5); };
// The V1+R0 sum is not available in CW1.
ASSERT(e_source != SRC_SPEC_R0_SUM && f_source != SRC_SPEC_R0_SUM && g_source != SRC_SPEC_R0_SUM);
uint32_t value = (channel(e_source, e_alpha, e_invert) << 24) + (channel(f_source, f_alpha, f_invert) << 16) +
(channel(g_source, g_alpha, g_invert) << 8);
if (specular_add_invert_r12) {
value += 0x20;
if (specular_add_invert_r0) {
// NV097_SET_COMBINER_SPECULAR_FOG_CW1_SPECULAR_ADD_INVERT_R12 crashes on hardware.
value += (1 << 5);
}
if (specular_add_invert_r5) {
value += (1 << 6);
if (specular_add_invert_v1) {
value += NV097_SET_COMBINER_SPECULAR_FOG_CW1_SPECULAR_ADD_INVERT_R5;
}
if (specular_clamp) {
value += (1 << 7);
value += NV097_SET_COMBINER_SPECULAR_FOG_CW1_SPECULAR_CLAMP;
}
auto p = pb_begin();

View File

@ -78,7 +78,7 @@ class TestHost {
SRC_TEX3, // Texcoord3
SRC_R0, // R0 from the vertex shader
SRC_R1, // R1 from the vertex shader
SRC_SPEC_R0_SUM, // Specular + R1
SRC_SPEC_R0_SUM, // Specular + R0
SRC_EF_PROD, // Combiner param E * F
};
@ -434,7 +434,7 @@ class TestHost {
void SetFinalCombiner1(CombinerSource e_source = SRC_ZERO, bool e_alpha = false, bool e_invert = false,
CombinerSource f_source = SRC_ZERO, bool f_alpha = false, bool f_invert = false,
CombinerSource g_source = SRC_ZERO, bool g_alpha = false, bool g_invert = false,
bool specular_add_invert_r12 = false, bool specular_add_invert_r5 = false,
bool specular_add_invert_r0 = false, bool specular_add_invert_v1 = false,
bool specular_clamp = false) const;
void SetCombinerFactorC0(int combiner, uint32_t value) const;

View File

@ -8,11 +8,13 @@
static constexpr const char* kMuxTestName = "Mux";
static constexpr const char* kIndependenceTestName = "Independence";
static constexpr const char* kFlagsTestName = "Flags";
CombinerTests::CombinerTests(TestHost& host, std::string output_dir)
: TestSuite(host, std::move(output_dir), "Combiner") {
tests_[kMuxTestName] = [this]() { TestMux(); };
tests_[kIndependenceTestName] = [this]() { TestCombinerIndependence(); };
tests_[kFlagsTestName] = [this]() { TestFlags(); };
}
void CombinerTests::Initialize() {
@ -206,4 +208,88 @@ void CombinerTests::TestCombinerIndependence() {
pb_draw_text_screen();
host_.FinishDraw(allow_saving_, output_dir_, kIndependenceTestName);
}
}
void CombinerTests::TestFlags() {
static constexpr uint32_t kBackgroundColor = 0xFF303030;
host_.PrepareDraw(kBackgroundColor);
uint32_t vertex_elements = host_.POSITION | host_.DIFFUSE | host_.SPECULAR;
host_.SetCombinerControl(1);
// Set V1 and R0 to 1.0
host_.SetInputColorCombiner(0, TestHost::OneInput(), TestHost::OneInput(), TestHost::OneInput(),
TestHost::OneInput());
host_.SetOutputColorCombiner(0, TestHost::DST_SPECULAR, TestHost::DST_R0);
// Set the final output to (D=0) + (A=0.5) * (B=V1+R0) + (1 - A=0.5) * (C=0)
// Set alpha (G) to 1.0
host_.SetFinalCombinerFactorC0(0.5f, 0.5f, 0.5f, 0.5f);
host_.SetFinalCombiner0(TestHost::SRC_C0, false, false, TestHost::SRC_SPEC_R0_SUM, false, false);
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, true,
true);
// The expected output is full brightness white.
pb_printat(2, 10, (char*)"Uncapped");
host_.SetVertexBuffer(vertex_buffers_[0]);
host_.DrawArrays(vertex_elements);
// Do the same thing, but clamp the V1+R0 sum
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, true,
true, false, false, true);
pb_printat(2, 22, (char*)"Capped");
host_.SetVertexBuffer(vertex_buffers_[1]);
host_.DrawArrays(vertex_elements);
// Set v1 to 0, r0 to 0.75.
host_.SetCombinerFactorC0(0, 0.75f, 0.75f, 0.75f, 0.75f);
host_.SetInputColorCombiner(0, TestHost::ZeroInput(), TestHost::ZeroInput(), TestHost::ColorInput(TestHost::SRC_C0),
TestHost::OneInput());
host_.SetOutputColorCombiner(0, TestHost::DST_SPECULAR, TestHost::DST_R0);
// Set A to 1.0 so the final output is just B(the V1 + R0 sum).
host_.SetFinalCombiner0(TestHost::SRC_ZERO, false, true, TestHost::SRC_SPEC_R0_SUM, false, false);
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, true,
true);
pb_printat(2, 31, (char*)"Normal R0");
host_.SetVertexBuffer(vertex_buffers_[2]);
host_.DrawArrays(vertex_elements);
// Now invert R0.
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, true,
true, true, false, false);
pb_printat(2, 42, (char*)"1 - R0");
host_.SetVertexBuffer(vertex_buffers_[3]);
host_.DrawArrays(vertex_elements);
// Essentially the same test, but using v1 instead of r0
// Set r0 to 0, v1 to 0.75.
host_.SetInputColorCombiner(0, TestHost::ZeroInput(), TestHost::ZeroInput(), TestHost::ColorInput(TestHost::SRC_C0),
TestHost::OneInput());
host_.SetOutputColorCombiner(0, TestHost::DST_R0, TestHost::DST_SPECULAR);
// Set A to 1.0 so the final output is just B(the V1 + R0 sum).
host_.SetFinalCombiner0(TestHost::SRC_ZERO, false, true, TestHost::SRC_SPEC_R0_SUM, false, false);
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, true,
true);
pb_printat(7, 14, (char*)"V1");
host_.SetVertexBuffer(vertex_buffers_[4]);
host_.DrawArrays(vertex_elements);
// Now invert V1.
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, true,
true, false, true, false);
pb_printat(7, 23, (char*)"1 - V1");
host_.SetVertexBuffer(vertex_buffers_[5]);
host_.DrawArrays(vertex_elements);
pb_printat(0, 0, (char*)"%s\n", kFlagsTestName);
pb_draw_text_screen();
host_.FinishDraw(allow_saving_, output_dir_, kFlagsTestName);
}

View File

@ -20,6 +20,7 @@ class CombinerTests : public TestSuite {
void CreateGeometry();
void TestMux();
void TestCombinerIndependence();
void TestFlags();
private:
std::shared_ptr<VertexBuffer> vertex_buffers_[6];