[GPU] Mostly generic, not square-only resolution scaling

This commit is contained in:
Triang3l
2021-12-11 21:55:33 +03:00
parent e2da8597e1
commit 38b4741c8f
254 changed files with 86052 additions and 344263 deletions

View File

@@ -693,13 +693,14 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
}
// Get offsets applied to the coordinates before sampling.
// `offsets` is used for float4 literal construction,
// FIXME(Triang3l): Offsets need to be applied at the LOD being fetched, not
// at LOD 0. However, since offsets have granularity of 0.5, not 1, on the
// Xbox 360, they can't be passed directly as AOffImmI to the `sample`
// instruction (plus-minus 0.5 offsets are very common in games). But
// offsetting at mip levels is a rare usage case, mostly offsets are used for
// things like shadow maps and blur, where there are no mips.
float offsets[4] = {};
float offsets[3] = {};
// MSDN doesn't list offsets as getCompTexLOD parameters.
if (instr.opcode != FetchOpcode::kGetTextureComputedLod) {
// Add a small epsilon to the offset (1.5/4 the fixed-point texture
@@ -770,6 +771,8 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
offsets_not_zero |= 1 << i;
}
}
dxbc::Src offsets_src(
dxbc::Src::LF(offsets[0], offsets[1], offsets[2], 0.0f));
// Load the texture size if needed.
// 1D: X - width.
@@ -894,8 +897,11 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
dxbc::Src::R(size_and_is_3d_temp));
}
}
bool revert_resolution_scale = draw_resolution_scale_ > 1 &&
cvars::draw_resolution_scaled_texture_offsets;
uint32_t revert_resolution_scale_axes =
cvars::draw_resolution_scaled_texture_offsets
? uint32_t(draw_resolution_scale_x_ > 1) |
(uint32_t(draw_resolution_scale_y_ > 1) << 1)
: 0;
if (instr.opcode == FetchOpcode::kGetTextureWeights) {
// FIXME(Triang3l): Mip lerp factor needs to be calculated, and the
@@ -920,8 +926,7 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
// If needed, apply the resolution scale to the width / height and the
// unnormalized coordinates.
uint32_t resolution_scaled_result_components =
revert_resolution_scale ? used_result_nonzero_components & 0b0011
: 0b0000;
used_result_nonzero_components & revert_resolution_scale_axes;
uint32_t resolution_scaled_coord_components =
instr.attributes.unnormalized_coordinates
? resolution_scaled_result_components
@@ -952,7 +957,8 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
a_.OpIf(true, dxbc::Src::R(system_temp_result_, dxbc::Src::kWWWW));
// The texture is resolved - scale the coordinates and the size.
dxbc::Src resolution_scale_src(
dxbc::Src::LF(float(draw_resolution_scale_)));
dxbc::Src::LF(float(draw_resolution_scale_x_),
float(draw_resolution_scale_y_), 1.0f, 1.0f));
if (resolution_scaled_coord_components) {
a_.OpMul(dxbc::Dest::R(system_temp_result_,
resolution_scaled_coord_components),
@@ -975,14 +981,14 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
dxbc::Dest::R(system_temp_result_, used_result_nonzero_components));
if (instr.attributes.unnormalized_coordinates) {
if (offsets_needed) {
a_.OpAdd(coord_dest, coord_operand, dxbc::Src::LP(offsets));
a_.OpAdd(coord_dest, coord_operand, offsets_src);
}
} else {
assert_true((size_needed_components & used_result_nonzero_components) ==
used_result_nonzero_components);
if (offsets_needed) {
a_.OpMAd(coord_dest, coord_operand, dxbc::Src::R(size_and_is_3d_temp),
dxbc::Src::LP(offsets));
offsets_src);
} else {
a_.OpMul(coord_dest, coord_operand,
dxbc::Src::R(size_and_is_3d_temp));
@@ -1048,8 +1054,7 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
uint32_t normalized_components_with_offsets =
normalized_components & offsets_not_zero;
uint32_t normalized_components_with_scaled_offsets =
revert_resolution_scale ? normalized_components_with_offsets & 0b0011
: 0;
normalized_components_with_offsets & revert_resolution_scale_axes;
uint32_t normalized_components_with_unscaled_offsets =
normalized_components_with_offsets &
~normalized_components_with_scaled_offsets;
@@ -1073,20 +1078,23 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
offsetof(SystemConstants, textures_resolved),
dxbc::Src::kXXXX),
dxbc::Src::LU(uint32_t(1) << tfetch_index));
a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b1000),
dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW),
dxbc::Src::LF(1.0f / draw_resolution_scale_),
dxbc::Src::LF(1.0f));
a_.OpMAd(dxbc::Dest::R(coord_and_sampler_temp,
a_.OpIf(true, dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW));
a_.OpAdd(
dxbc::Dest::R(coord_and_sampler_temp,
normalized_components_with_scaled_offsets),
coord_operand,
dxbc::Src::LF(offsets[0] / draw_resolution_scale_x_,
offsets[1] / draw_resolution_scale_y_, 0.0f, 0.0f));
a_.OpElse();
a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp,
normalized_components_with_scaled_offsets),
dxbc::Src::LP(offsets),
dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW),
coord_operand);
coord_operand, offsets_src);
a_.OpEndIf();
}
if (normalized_components_with_unscaled_offsets) {
a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp,
normalized_components_with_unscaled_offsets),
coord_operand, dxbc::Src::LP(offsets));
coord_operand, offsets_src);
}
if (normalized_components_without_offsets) {
a_.OpMov(dxbc::Dest::R(coord_and_sampler_temp,
@@ -1129,7 +1137,7 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
normalized_components_with_offsets);
a_.OpDiv(dxbc::Dest::R(coord_and_sampler_temp,
normalized_components_with_offsets),
dxbc::Src::LP(offsets), dxbc::Src::R(size_and_is_3d_temp));
offsets_src, dxbc::Src::R(size_and_is_3d_temp));
if (normalized_components_with_scaled_offsets) {
// Using coord_and_sampler_temp.w as a temporary for the needed
// resolution scale inverse - sampler not loaded yet.
@@ -1139,15 +1147,18 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
offsetof(SystemConstants, textures_resolved),
dxbc::Src::kXXXX),
dxbc::Src::LU(uint32_t(1) << tfetch_index));
a_.OpMovC(dxbc::Dest::R(coord_and_sampler_temp, 0b1000),
dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW),
dxbc::Src::LF(1.0f / draw_resolution_scale_),
dxbc::Src::LF(1.0f));
a_.OpIf(true, dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW));
a_.OpMAd(dxbc::Dest::R(coord_and_sampler_temp,
normalized_components_with_scaled_offsets),
dxbc::Src::R(coord_and_sampler_temp),
dxbc::Src::R(coord_and_sampler_temp, dxbc::Src::kWWWW),
dxbc::Src::LF(1.0f / draw_resolution_scale_x_,
1.0f / draw_resolution_scale_y_, 1.0f, 1.0f),
coord_operand);
a_.OpElse();
a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp,
normalized_components_with_scaled_offsets),
coord_operand, dxbc::Src::R(coord_and_sampler_temp));
a_.OpEndIf();
}
if (normalized_components_with_unscaled_offsets) {
a_.OpAdd(dxbc::Dest::R(coord_and_sampler_temp,