[GPU] Properly handle scaled textures and weights
Fix d3d12 logic wrt scaling weights, add vulkan impelementation for using scaled texture offsets and fix resolution-scaled texture detection
This commit is contained in:
@@ -959,64 +959,19 @@ void DxbcShaderTranslator::ProcessTextureFetchInstruction(
|
||||
// would be useless to get weights that will always be zero.
|
||||
|
||||
// Need unnormalized coordinates.
|
||||
// Resolution scale is NOT applied for GetTextureWeights - weights are
|
||||
// calculated from fractional parts of coordinates which should be in guest
|
||||
// texel space, not host texel space. Games expect weights based on guest
|
||||
// texture dimensions.
|
||||
bool coord_operand_temp_pushed = false;
|
||||
dxbc::Src coord_operand =
|
||||
LoadOperand(instr.operands[0], used_result_nonzero_components,
|
||||
coord_operand_temp_pushed);
|
||||
dxbc::Src coord_src(coord_operand);
|
||||
// If needed, apply the resolution scale to the width / height and the
|
||||
// unnormalized coordinates.
|
||||
uint32_t resolution_scaled_result_components =
|
||||
used_result_nonzero_components & revert_resolution_scale_axes;
|
||||
uint32_t resolution_scaled_coord_components =
|
||||
instr.attributes.unnormalized_coordinates
|
||||
? resolution_scaled_result_components
|
||||
: 0b0000;
|
||||
uint32_t resolution_scaled_size_components =
|
||||
size_needed_components & resolution_scaled_result_components;
|
||||
if (resolution_scaled_coord_components ||
|
||||
resolution_scaled_size_components) {
|
||||
if (resolution_scaled_coord_components &&
|
||||
(coord_src.type_ != dxbc::OperandType::kTemp ||
|
||||
coord_src.index_1d_.index_ != system_temp_result_)) {
|
||||
// Use system_temp_result_ as a temporary for conditionally
|
||||
// resolution-scaled coordinates.
|
||||
a_.OpMov(
|
||||
dxbc::Dest::R(system_temp_result_, used_result_nonzero_components),
|
||||
coord_src);
|
||||
coord_src = dxbc::Src::R(system_temp_result_);
|
||||
}
|
||||
// Using system_temp_result_.w as a temporary for the flag indicating
|
||||
// whether the texture was resolved - not involved in coordinate
|
||||
// calculations.
|
||||
assert_zero(used_result_nonzero_components & 0b1000);
|
||||
a_.OpAnd(dxbc::Dest::R(system_temp_result_, 0b1000),
|
||||
LoadSystemConstant(SystemConstants::Index::kTexturesResolved,
|
||||
offsetof(SystemConstants, textures_resolved),
|
||||
dxbc::Src::kXXXX),
|
||||
dxbc::Src::LU(uint32_t(1) << tfetch_index));
|
||||
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_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),
|
||||
coord_src, resolution_scale_src);
|
||||
}
|
||||
if (resolution_scaled_size_components) {
|
||||
a_.OpMul(dxbc::Dest::R(size_and_is_3d_temp,
|
||||
resolution_scaled_size_components),
|
||||
dxbc::Src::R(size_and_is_3d_temp), resolution_scale_src);
|
||||
}
|
||||
a_.OpEndIf();
|
||||
}
|
||||
uint32_t offsets_needed = offsets_not_zero & used_result_nonzero_components;
|
||||
if (!instr.attributes.unnormalized_coordinates || offsets_needed) {
|
||||
// Using system_temp_result_ as a temporary for coordinate denormalization
|
||||
// and offsetting. May already contain the coordinates loaded if
|
||||
// resolution scaling was applied to the coordinates.
|
||||
// and offsetting.
|
||||
coord_src = dxbc::Src::R(system_temp_result_);
|
||||
dxbc::Dest coord_dest(
|
||||
dxbc::Dest::R(system_temp_result_, used_result_nonzero_components));
|
||||
|
||||
Reference in New Issue
Block a user