[GPU] Mostly generic, not square-only resolution scaling
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user