[D3D12] Add epsilon to texture coordinates to resolve tie in nearest-neighbor filtering

This commit is contained in:
Triang3l 2018-10-24 16:35:00 +03:00
parent 119342dbac
commit e68a0c37b9
1 changed files with 18 additions and 0 deletions

View File

@ -8234,12 +8234,24 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
// It's probably applicable to tfetchCube too, we're going to assume it's
// used for them the same way as for stacked textures.
// http://web.archive.org/web/20090511231340/http://msdn.microsoft.com:80/en-us/library/bb313959.aspx
// Adding 1/1024 - quarter of one fixed-point unit of subpixel precision
// (not to touch rounding when the GPU is converting to fixed-point) - to
// resolve the ambiguity when the texture coordinate is directly between two
// pixels, which hurts nearest-neighbor sampling (fixes the XBLA logo being
// blocky in Banjo-Kazooie and the outlines around things and overall
// blockiness in Halo 3).
float offset_x = instr.attributes.offset_x;
if (instr.opcode != FetchOpcode::kGetTextureWeights) {
offset_x += 1.0f / 1024.0f;
}
float offset_y = 0.0f, offset_z = 0.0f;
if (instr.dimension == TextureDimension::k2D ||
instr.dimension == TextureDimension::k3D ||
instr.dimension == TextureDimension::kCube) {
offset_y = instr.attributes.offset_y;
if (instr.opcode != FetchOpcode::kGetTextureWeights) {
offset_y += 1.0f / 1024.0f;
}
// Don't care about the Z offset for cubemaps when getting weights because
// zero Z will be returned anyway (the face index doesn't participate in
// bilinear filtering).
@ -8247,6 +8259,9 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
(instr.dimension == TextureDimension::kCube &&
instr.opcode != FetchOpcode::kGetTextureWeights)) {
offset_z = instr.attributes.offset_z;
if (instr.opcode != FetchOpcode::kGetTextureWeights) {
offset_z += 1.0f / 1024.0f;
}
}
}
@ -8262,6 +8277,9 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
// unlikely to be used on purpose.
// http://web.archive.org/web/20090514012026/http://msdn.microsoft.com:80/en-us/library/bb313957.aspx
uint32_t size_and_is_3d_temp = UINT32_MAX;
// With 1/1024 this will always be true anyway, but let's keep the shorter
// path without the offset in case some day this hack won't be used anymore
// somehow.
bool has_offset = offset_x != 0.0f || offset_y != 0.0f || offset_z != 0.0f;
if (instr.opcode == FetchOpcode::kGetTextureWeights || has_offset ||
instr.attributes.unnormalized_coordinates ||