From 929ecfa15c13dba4d18993482333542a2cd9d35c Mon Sep 17 00:00:00 2001 From: Triang3l Date: Sat, 13 Jul 2019 12:27:15 +0300 Subject: [PATCH] [D3D12] ROV: Fix stencil test result being ignored for depth --- src/xenia/gpu/dxbc_shader_translator_om.cc | 59 ++++++++++++++-------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/xenia/gpu/dxbc_shader_translator_om.cc b/src/xenia/gpu/dxbc_shader_translator_om.cc index 482dabf35..21939afa9 100644 --- a/src/xenia/gpu/dxbc_shader_translator_om.cc +++ b/src/xenia/gpu/dxbc_shader_translator_om.cc @@ -5353,28 +5353,6 @@ void DxbcShaderTranslator:: ++stat_.instruction_count; ++stat_.movc_instruction_count; - // If the depth test has failed, don't change the depth. - // VGPR [0].x = new depth - // VGPR [0].y = depth test failure - // VGPR [0].z = old depth/stencil - // VGPR [0].w = old depth - shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) | - ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9)); - shader_code_.push_back( - EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); - shader_code_.push_back(system_temps_subroutine_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); - shader_code_.push_back(system_temps_subroutine_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 3, 1)); - shader_code_.push_back(system_temps_subroutine_); - shader_code_.push_back( - EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); - shader_code_.push_back(system_temps_subroutine_); - ++stat_.instruction_count; - ++stat_.movc_instruction_count; - // Extract the depth write flag to SGPR [1].x. // VGPR [0].x = new depth // VGPR [0].y = depth test failure @@ -6132,6 +6110,43 @@ void DxbcShaderTranslator:: ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); ++stat_.instruction_count; + // Check if the depth/stencil has failed not to modify the depth if it has. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_IF) | + ENCODE_D3D10_SB_INSTRUCTION_TEST_BOOLEAN( + D3D10_SB_INSTRUCTION_TEST_NONZERO) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(3)); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 1, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.dynamic_flow_control_count; + + // If the depth/stencil test has failed, don't change the depth. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D11_SB_OPCODE_BFI) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(11)); + shader_code_.push_back( + EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(8); + shader_code_.push_back( + EncodeScalarOperand(D3D10_SB_OPERAND_TYPE_IMMEDIATE32, 0)); + shader_code_.push_back(0); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1)); + shader_code_.push_back(system_temps_subroutine_); + shader_code_.push_back( + EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 2, 1)); + shader_code_.push_back(system_temps_subroutine_); + ++stat_.instruction_count; + ++stat_.uint_instruction_count; + + // Close the depth/stencil failure check. + shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ENDIF) | + ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(1)); + ++stat_.instruction_count; + // Check if need to write - if depth/stencil is different - to VGPR [0].z. // VGPR [0].x = new depth/stencil // VGPR [0].y = depth/stencil test failure