shader_jit: Fix/optimize conditional evaluation (#234)
* shader_jit: Add conditional unit-tests
Tests all permutations of X, Y, AND, OR with each possible input value.
* video_core: Fix shader-interpreter conditional-code initialization
Rather than reserving the incoming state of the conditional codes, the
shader-interpreter was setting them both to false. In pretty much all
cases, the initial state of a shaderunit can be zero-initialized
statically. Just running the interpreter shouldn't necessarily reset the
conditional codes though. The JIT loads incoming conditional codes
while the shader-interpreter resets them to false. This makes the
interpreter match the behavior of the shader-jit.
* shader_jit_a64: Fix/optimize conditional evaluation
Fix some of the regressions introduced by the previous optimization.
EOR does not support a constant of `0` in its immediate. In these cases
the COND{0,1} registers can be utilized immediately.
* shader_jit_x64: Fix conditional evaluation extended-bit hazard
The unit test seems to have identified a bug in the x64 jit too. The x64
jit was doing 32-bit comparisons despite the condition flags being 8-bit
values and is sensitive to garbage being in the upper 24 bits of the
register. This is fixed by using the proper 8-bit register types rather
than the 32-bit ones(`eax,`ebx` -> `al`, `bl`).
* shader_jit_x64: Zero-extend conditional-code bytes
`mov` was doing a partial update of bits within the register, allowing
garbage to be introduced in the upper bits of the register.
This commit is contained in:
@@ -9,10 +9,7 @@
|
||||
|
||||
namespace Pica {
|
||||
|
||||
ShaderUnit::ShaderUnit(GeometryEmitter* emitter) : emitter_ptr{emitter} {
|
||||
const Common::Vec4<f24> temp_vec{f24::Zero(), f24::Zero(), f24::Zero(), f24::One()};
|
||||
temporary.fill(temp_vec);
|
||||
}
|
||||
ShaderUnit::ShaderUnit(GeometryEmitter* emitter) : emitter_ptr{emitter} {}
|
||||
|
||||
ShaderUnit::~ShaderUnit() = default;
|
||||
|
||||
|
||||
@@ -46,11 +46,11 @@ struct ShaderUnit {
|
||||
}
|
||||
|
||||
public:
|
||||
s32 address_registers[3];
|
||||
bool conditional_code[2];
|
||||
alignas(16) std::array<Common::Vec4<f24>, 16> input;
|
||||
alignas(16) std::array<Common::Vec4<f24>, 16> temporary;
|
||||
alignas(16) std::array<Common::Vec4<f24>, 16> output;
|
||||
s32 address_registers[3] = {};
|
||||
bool conditional_code[2] = {};
|
||||
alignas(16) std::array<Common::Vec4<f24>, 16> input = {};
|
||||
alignas(16) std::array<Common::Vec4<f24>, 16> temporary = {};
|
||||
alignas(16) std::array<Common::Vec4<f24>, 16> output = {};
|
||||
GeometryEmitter* emitter_ptr;
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user