[D3D12] Round to nearest when converting to fixed-point

This commit is contained in:
Triang3l
2018-10-26 22:04:11 +03:00
parent f4844207ad
commit 1d45a4f67e
5 changed files with 158 additions and 125 deletions

View File

@@ -1657,6 +1657,21 @@ void DxbcShaderTranslator::CompletePixelShader_DepthTo24Bit() {
++stat_.instruction_count;
++stat_.float_instruction_count;
// Round to the nearest integer. This is the correct way of rounding, rounding
// towards zero gives 0xFF instead of 0x100 in clear shaders in, for instance,
// Halo 3.
// https://docs.microsoft.com/en-us/windows/desktop/direct3d10/d3d10-graphics-programming-guide-resources-data-conversion
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5));
shader_code_.push_back(
EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0001, 1));
shader_code_.push_back(system_temp_depth_);
shader_code_.push_back(
EncodeVectorSelectOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0, 1));
shader_code_.push_back(system_temp_depth_);
++stat_.instruction_count;
++stat_.float_instruction_count;
// Convert to fixed-point.
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOU) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5));
@@ -3199,9 +3214,10 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToROV_StoreColor(
++stat_.instruction_count;
++stat_.float_instruction_count;
// Convert to fixed-point.
// Convert to fixed-point, rounding to the nearest integer.
// https://docs.microsoft.com/en-us/windows/desktop/direct3d10/d3d10-graphics-programming-guide-resources-data-conversion
uint32_t fixed_temp = PushSystemTemp();
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOI) |
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NE) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5));
shader_code_.push_back(
EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1));
@@ -3210,6 +3226,16 @@ void DxbcShaderTranslator::CompletePixelShader_WriteToROV_StoreColor(
EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1));
shader_code_.push_back(source_and_scratch_temp);
++stat_.instruction_count;
++stat_.float_instruction_count;
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_FTOI) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5));
shader_code_.push_back(
EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b1111, 1));
shader_code_.push_back(fixed_temp);
shader_code_.push_back(
EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1));
shader_code_.push_back(fixed_temp);
++stat_.instruction_count;
++stat_.conversion_instruction_count;
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MOVC) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9));