mirror of https://github.com/xemu-project/xemu.git
125 lines
4.2 KiB
C++
125 lines
4.2 KiB
C++
#include <boost/test/unit_test.hpp>
|
|
|
|
#include "nv2a_vsh_emulator.h"
|
|
|
|
#define CHECK_REGISTER(bank, index, actual) \
|
|
do { \
|
|
float *expected = bank + index * 4; \
|
|
BOOST_TEST((expected)[0] == (actual)[0]); \
|
|
BOOST_TEST((expected)[1] == (actual)[1]); \
|
|
BOOST_TEST((expected)[2] == (actual)[2]); \
|
|
BOOST_TEST((expected)[3] == (actual)[3]); \
|
|
} while (0)
|
|
|
|
static void clear_step(Nv2aVshStep *out) {
|
|
out->is_final = false;
|
|
memset(out->mac.outputs, 0, sizeof(out->mac.outputs));
|
|
memset(out->mac.inputs, 0, sizeof(out->mac.inputs));
|
|
memset(out->ilu.outputs, 0, sizeof(out->ilu.outputs));
|
|
memset(out->ilu.inputs, 0, sizeof(out->ilu.inputs));
|
|
|
|
out->mac.opcode = NV2AOP_NOP;
|
|
out->mac.inputs[0].type = NV2ART_NONE;
|
|
out->mac.inputs[0].swizzle[0] = NV2ASW_X;
|
|
out->mac.inputs[0].swizzle[1] = NV2ASW_Y;
|
|
out->mac.inputs[0].swizzle[2] = NV2ASW_Z;
|
|
out->mac.inputs[0].swizzle[3] = NV2ASW_W;
|
|
out->mac.inputs[1].type = NV2ART_NONE;
|
|
out->mac.inputs[1].swizzle[0] = NV2ASW_X;
|
|
out->mac.inputs[1].swizzle[1] = NV2ASW_Y;
|
|
out->mac.inputs[1].swizzle[2] = NV2ASW_Z;
|
|
out->mac.inputs[1].swizzle[3] = NV2ASW_W;
|
|
out->mac.inputs[2].type = NV2ART_NONE;
|
|
out->mac.inputs[2].swizzle[0] = NV2ASW_X;
|
|
out->mac.inputs[2].swizzle[1] = NV2ASW_Y;
|
|
out->mac.inputs[2].swizzle[2] = NV2ASW_Z;
|
|
out->mac.inputs[2].swizzle[3] = NV2ASW_W;
|
|
out->mac.outputs[0].type = NV2ART_NONE;
|
|
out->mac.outputs[1].type = NV2ART_NONE;
|
|
|
|
out->ilu.opcode = NV2AOP_NOP;
|
|
out->ilu.inputs[0].type = NV2ART_NONE;
|
|
out->ilu.inputs[0].swizzle[0] = NV2ASW_X;
|
|
out->ilu.inputs[0].swizzle[1] = NV2ASW_Y;
|
|
out->ilu.inputs[0].swizzle[2] = NV2ASW_Z;
|
|
out->ilu.inputs[0].swizzle[3] = NV2ASW_W;
|
|
out->ilu.inputs[1].type = NV2ART_NONE;
|
|
out->ilu.inputs[1].swizzle[0] = NV2ASW_X;
|
|
out->ilu.inputs[1].swizzle[1] = NV2ASW_Y;
|
|
out->ilu.inputs[1].swizzle[2] = NV2ASW_Z;
|
|
out->ilu.inputs[1].swizzle[3] = NV2ASW_W;
|
|
out->ilu.inputs[2].type = NV2ART_NONE;
|
|
out->ilu.inputs[2].swizzle[0] = NV2ASW_X;
|
|
out->ilu.inputs[2].swizzle[1] = NV2ASW_Y;
|
|
out->ilu.inputs[2].swizzle[2] = NV2ASW_Z;
|
|
out->ilu.inputs[2].swizzle[3] = NV2ASW_W;
|
|
out->ilu.outputs[0].type = NV2ART_NONE;
|
|
out->ilu.outputs[1].type = NV2ART_NONE;
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE(basic_operation_suite)
|
|
|
|
BOOST_AUTO_TEST_CASE(step_trivial) {
|
|
Nv2aVshCPUFullExecutionState full_state;
|
|
Nv2aVshExecutionState state =
|
|
nv2a_vsh_emu_initialize_full_execution_state(&full_state);
|
|
uint32_t reg = 11 * 4;
|
|
full_state.input_regs[reg + 0] = 123.0f;
|
|
full_state.input_regs[reg + 1] = -456.0f;
|
|
full_state.input_regs[reg + 2] = 0.789f;
|
|
full_state.input_regs[reg + 3] = 32.64f;
|
|
|
|
// MOV oT2.xyzw, v11
|
|
Nv2aVshStep step;
|
|
clear_step(&step);
|
|
step.mac.opcode = NV2AOP_MOV;
|
|
step.mac.outputs[0].type = NV2ART_OUTPUT;
|
|
step.mac.outputs[0].index = 11;
|
|
step.mac.outputs[0].writemask = NV2AWM_XYZW;
|
|
step.mac.inputs[0].type = NV2ART_INPUT;
|
|
step.mac.inputs[0].index = 11;
|
|
|
|
nv2a_vsh_emu_apply(&state, &step);
|
|
|
|
CHECK_REGISTER(state.output_regs, NV2AOR_TEX2, &full_state.input_regs[reg]);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(program_context_tracked) {
|
|
Nv2aVshCPUFullExecutionState full_state;
|
|
Nv2aVshExecutionState state =
|
|
nv2a_vsh_emu_initialize_full_execution_state(&full_state);
|
|
uint32_t reg = 11 * 4;
|
|
full_state.input_regs[reg + 0] = 123.0f;
|
|
full_state.input_regs[reg + 1] = -456.0f;
|
|
full_state.input_regs[reg + 2] = 0.789f;
|
|
full_state.input_regs[reg + 3] = 32.64f;
|
|
|
|
// MOV c1.xyzw, v11
|
|
Nv2aVshStep steps[1];
|
|
Nv2aVshStep *step = &steps[0];
|
|
clear_step(step);
|
|
step->mac.opcode = NV2AOP_MOV;
|
|
step->mac.outputs[0].type = NV2ART_CONTEXT;
|
|
step->mac.outputs[0].index = 1;
|
|
step->mac.outputs[0].writemask = NV2AWM_XYZW;
|
|
step->mac.inputs[0].type = NV2ART_INPUT;
|
|
step->mac.inputs[0].index = 11;
|
|
step->is_final = true;
|
|
|
|
Nv2aVshProgram program;
|
|
program.steps = steps;
|
|
|
|
bool context_dirty[192] = {false};
|
|
nv2a_vsh_emu_execute_track_context_writes(&state, &program, context_dirty);
|
|
|
|
CHECK_REGISTER(state.context_regs, 1, &full_state.input_regs[reg]);
|
|
BOOST_TEST(!context_dirty[0]);
|
|
BOOST_TEST(context_dirty[1]);
|
|
for (uint32_t i = 2; i < 192; ++i) {
|
|
BOOST_TEST_INFO(i);
|
|
BOOST_TEST(!context_dirty[i]);
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|