[D3D12] Write pixel, not sample, position to ps_param_gen

This commit is contained in:
Triang3l 2018-10-24 17:06:41 +03:00
parent e68a0c37b9
commit cabffea4d7
2 changed files with 33 additions and 6 deletions

View File

@ -1739,7 +1739,10 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
float ndc_offset_x = (pa_cl_vte_cntl & (1 << 1)) ? 0.0f : -1.0f;
float ndc_offset_y = (pa_cl_vte_cntl & (1 << 3)) ? 0.0f : 1.0f;
float ndc_offset_z = gl_clip_space_def ? 0.5f : 0.0f;
float pixel_half_pixel_offset = 0.0f;
// Like in OpenGL - VPOS giving pixel centers.
// TODO(Triang3l): Check if ps_param_gen should give center positions in
// OpenGL mode on the Xbox 360.
float pixel_half_pixel_offset = 0.5f;
if (FLAGS_d3d12_half_pixel_offset && !(pa_su_vtx_cntl & (1 << 0))) {
// Signs are hopefully correct here, tested in GTA IV on both clearing
// (without a viewport) and drawing things near the edges of the screen.
@ -1757,7 +1760,8 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
} else {
ndc_offset_y -= 1.0f / 2560.0f;
}
pixel_half_pixel_offset = -0.5f;
// Like in Direct3D 9 - VPOS giving the top-left corner.
pixel_half_pixel_offset = 0.0f;
}
dirty |= system_constants_.ndc_scale[0] != ndc_scale_x;
dirty |= system_constants_.ndc_scale[1] != ndc_scale_y;

View File

@ -961,10 +961,9 @@ void DxbcShaderTranslator::StartPixelShader() {
++stat_.dynamic_flow_control_count;
// Write VPOS (without supersampling because SSAA is used to fake MSAA, and
// at integer coordinates rather than half-pixel if needed) to XY.
system_constants_used_ |= (1ull << kSysConst_SSAAInvScale_Index) |
(1ull << kSysConst_PixelHalfPixelOffset_Index);
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MAD) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(13));
system_constants_used_ |= 1ull << kSysConst_SSAAInvScale_Index;
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_MUL) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9));
shader_code_.push_back(
EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1));
shader_code_.push_back(param_gen_value_temp);
@ -978,6 +977,30 @@ void DxbcShaderTranslator::StartPixelShader() {
shader_code_.push_back(cbuffer_index_system_constants_);
shader_code_.push_back(uint32_t(CbufferRegister::kSystemConstants));
shader_code_.push_back(kSysConst_SSAAInvScale_Vec);
++stat_.instruction_count;
++stat_.float_instruction_count;
// Floor VPOS so with AA, the resulting pixel corner/center is written, not
// the sample position (games likely don't expect it to be fractional).
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ROUND_NI) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(5));
shader_code_.push_back(
EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1));
shader_code_.push_back(param_gen_value_temp);
shader_code_.push_back(
EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1));
shader_code_.push_back(param_gen_value_temp);
++stat_.instruction_count;
++stat_.float_instruction_count;
// If in OpenGL half-pixel offset mode, write the center of the pixel.
system_constants_used_ |= 1ull << kSysConst_PixelHalfPixelOffset_Index;
shader_code_.push_back(ENCODE_D3D10_SB_OPCODE_TYPE(D3D10_SB_OPCODE_ADD) |
ENCODE_D3D10_SB_TOKENIZED_INSTRUCTION_LENGTH(9));
shader_code_.push_back(
EncodeVectorMaskedOperand(D3D10_SB_OPERAND_TYPE_TEMP, 0b0011, 1));
shader_code_.push_back(param_gen_value_temp);
shader_code_.push_back(
EncodeVectorSwizzledOperand(D3D10_SB_OPERAND_TYPE_TEMP, kSwizzleXYZW, 1));
shader_code_.push_back(param_gen_value_temp);
shader_code_.push_back(
EncodeVectorReplicatedOperand(D3D10_SB_OPERAND_TYPE_CONSTANT_BUFFER,
kSysConst_PixelHalfPixelOffset_Comp, 3));