Implement shader-interpreter relative MOVA addressing (#471)

* Add shader uniform-read unit test

* Add unit test f24 vector formatter

* Add Address Register Offset shader unit test

* Implement float-uniform out-of-bound return value

In the case that the resulting float-uniform index is greater than the 96 slots that it has, a result of `{1,1,1,1}` is to be returned.

* Implement shader relative addressing

Fails on the negative unit tests at the moment but passes all of the
others.

* Fix `MOVA` source register indexing
This commit is contained in:
Wunk 2024-03-22 09:48:03 -07:00 committed by GitHub
parent 3270cfe602
commit 5284109fd4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 118 additions and 13 deletions

View file

@ -119,9 +119,17 @@ u8 PICAShader::getIndexedSource(u32 source, u32 index) {
return source;
switch (index) {
case 0: [[likely]] return u8(source); // No offset applied
case 1: return u8(source + addrRegister[0]);
case 2: return u8(source + addrRegister[1]);
// No offset applied
case 0: [[likely]] return u8(source);
// Address register
case 1:
case 2: {
const s32 offset = addrRegister[index - 1];
if (offset < -128 || offset > 127) [[unlikely]] {
return u8(source);
}
return u8(source + offset);
}
case 3: return u8(source + loopCounter);
}
@ -130,15 +138,16 @@ u8 PICAShader::getIndexedSource(u32 source, u32 index) {
}
PICAShader::vec4f PICAShader::getSource(u32 source) {
if (source < 0x10)
if (source < 0x10) {
return inputs[source];
else if (source < 0x20)
} else if (source < 0x20) {
return tempRegisters[source - 0x10];
else if (source <= 0x7f)
return floatUniforms[source - 0x20];
else {
Helpers::warn("[PICA] Unimplemented source value: %X\n", source);
return vec4f({f24::zero(), f24::zero(), f24::zero(), f24::zero()});
} else {
const usize floatIndex = (source - 0x20) & 0x7f;
if (floatIndex >= 96) [[unlikely]] {
return vec4f({f24::fromFloat32(1.0f), f24::fromFloat32(1.0f), f24::fromFloat32(1.0f), f24::fromFloat32(1.0f)});
}
return floatUniforms[floatIndex];
}
}
@ -300,10 +309,10 @@ void PICAShader::mov(u32 instruction) {
void PICAShader::mova(u32 instruction) {
const u32 operandDescriptor = operandDescriptors[instruction & 0x7f];
const u32 src = getBits<12, 7>(instruction);
u32 src = getBits<12, 7>(instruction);
const u32 idx = getBits<19, 2>(instruction);
if (idx) Helpers::panic("[PICA] MOVA: idx != 0");
src = getIndexedSource(src, idx);
vec4f srcVector = getSourceSwizzled<1>(src, operandDescriptor);
u32 componentMask = operandDescriptor & 0xf;