Merge branch 'master' into vulkan

This commit is contained in:
Triang3l 2022-06-30 22:15:29 +03:00
commit 6772c88141
1 changed files with 29 additions and 17 deletions

View File

@ -3012,31 +3012,43 @@ void DxbcShaderTranslator::CompletePixelShader() {
// checked, but let's assume this means "always", not "less, equal or // checked, but let's assume this means "always", not "less, equal or
// greater". // greater".
// TODO(Triang3l): Check how alpha test works with NaN on Direct3D 9. // TODO(Triang3l): Check how alpha test works with NaN on Direct3D 9.
a_.OpINE(alpha_test_op_dest, alpha_test_mask_src, dxbc::Src::LU(0b111)); a_.OpINE(alpha_test_op_dest, alpha_test_mask_src,
dxbc::Src::LU(uint32_t(xenos::CompareFunction::kAlways)));
// Don't do the test if the mode is "always". // Don't do the test if the mode is "always".
a_.OpIf(true, alpha_test_op_src); a_.OpIf(true, alpha_test_op_src);
{ {
// Do the test. Can't use subtraction and sign because of float specials. // Do the test.
dxbc::Src alpha_src( dxbc::Src alpha_src(
dxbc::Src::R(system_temps_color_[0], dxbc::Src::kWWWW)); dxbc::Src::R(system_temps_color_[0], dxbc::Src::kWWWW));
dxbc::Src alpha_test_reference_src(LoadSystemConstant( dxbc::Src alpha_test_reference_src(LoadSystemConstant(
SystemConstants::Index::kAlphaTestReference, SystemConstants::Index::kAlphaTestReference,
offsetof(SystemConstants, alpha_test_reference), dxbc::Src::kXXXX)); offsetof(SystemConstants, alpha_test_reference), dxbc::Src::kXXXX));
// Less than. // Handle "not equal" specially (specifically as "not equal" so it's true
a_.OpLT(alpha_test_op_dest, alpha_src, alpha_test_reference_src); // for NaN, not "less or greater" which is false for NaN).
a_.OpOr(alpha_test_op_dest, alpha_test_op_src, a_.OpIEq(alpha_test_op_dest, alpha_test_mask_src,
dxbc::Src::LU(~uint32_t(1 << 0))); dxbc::Src::LU(uint32_t(xenos::CompareFunction::kNotEqual)));
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); a_.OpIf(true, alpha_test_op_src);
// Equals to. { a_.OpNE(alpha_test_mask_dest, alpha_src, alpha_test_reference_src); }
a_.OpEq(alpha_test_op_dest, alpha_src, alpha_test_reference_src); a_.OpElse();
a_.OpOr(alpha_test_op_dest, alpha_test_op_src, {
dxbc::Src::LU(~uint32_t(1 << 1))); // Less than.
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); a_.OpLT(alpha_test_op_dest, alpha_src, alpha_test_reference_src);
// Greater than. a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
a_.OpLT(alpha_test_op_dest, alpha_test_reference_src, alpha_src); dxbc::Src::LU(~uint32_t(1 << 0)));
a_.OpOr(alpha_test_op_dest, alpha_test_op_src, a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
dxbc::Src::LU(~uint32_t(1 << 2))); // Equals to.
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src); a_.OpEq(alpha_test_op_dest, alpha_src, alpha_test_reference_src);
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
dxbc::Src::LU(~uint32_t(1 << 1)));
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
// Greater than.
a_.OpLT(alpha_test_op_dest, alpha_test_reference_src, alpha_src);
a_.OpOr(alpha_test_op_dest, alpha_test_op_src,
dxbc::Src::LU(~uint32_t(1 << 2)));
a_.OpAnd(alpha_test_mask_dest, alpha_test_mask_src, alpha_test_op_src);
}
// Close the "not equal" check.
a_.OpEndIf();
// Discard the pixel if it has failed the test. // Discard the pixel if it has failed the test.
if (edram_rov_used_) { if (edram_rov_used_) {
a_.OpRetC(false, alpha_test_mask_src); a_.OpRetC(false, alpha_test_mask_src);