diff options
| author | 2021-08-07 02:59:05 +0200 | |
|---|---|---|
| committer | 2021-11-16 22:11:29 +0100 | |
| commit | dfa82915262ca26d0884528b7bdae791554332ca (patch) | |
| tree | b6e3c6a16cbcfc8952fa0afe5347e13628ce6bdd /src | |
| parent | Texture Cache: Correctly fix Blits Rescaling. (diff) | |
| download | yuzu-dfa82915262ca26d0884528b7bdae791554332ca.tar.gz yuzu-dfa82915262ca26d0884528b7bdae791554332ca.tar.xz yuzu-dfa82915262ca26d0884528b7bdae791554332ca.zip | |
RescalingPass: Agregate pixels on texelFetch while on Fragment Shader
Diffstat (limited to 'src')
| -rw-r--r-- | src/shader_recompiler/ir_opt/rescaling_pass.cpp | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/src/shader_recompiler/ir_opt/rescaling_pass.cpp b/src/shader_recompiler/ir_opt/rescaling_pass.cpp index b94273aa5..71c9d9e6f 100644 --- a/src/shader_recompiler/ir_opt/rescaling_pass.cpp +++ b/src/shader_recompiler/ir_opt/rescaling_pass.cpp | |||
| @@ -40,6 +40,22 @@ void PatchFragCoord(IR::Block& block, IR::Inst& inst) { | |||
| 40 | } | 40 | } |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | [[nodiscard]] IR::U32 SubScale(IR::IREmitter& ir, const IR::U1& is_scaled, const IR::U32& value, | ||
| 44 | const IR::Attribute attrib) { | ||
| 45 | if (Settings::values.resolution_info.active) { | ||
| 46 | const IR::F32 opt1{ir.Imm32(Settings::values.resolution_info.up_factor)}; | ||
| 47 | const IR::F32 base{ir.FPMul(ir.ConvertUToF(32, 32, value), opt1)}; | ||
| 48 | const IR::F32 frag_coord{ir.GetAttribute(attrib)}; | ||
| 49 | const IR::F32 opt2{ir.Imm32(Settings::values.resolution_info.down_factor)}; | ||
| 50 | const IR::F32 floor{ir.FPMul(opt1, ir.FPFloor(ir.FPMul(frag_coord, opt2)))}; | ||
| 51 | const IR::U32 deviation{ | ||
| 52 | ir.ConvertFToU(32, ir.FPAdd(base, ir.FPAdd(frag_coord, ir.FPNeg(floor))))}; | ||
| 53 | return IR::U32{ir.Select(is_scaled, deviation, value)}; | ||
| 54 | } else { | ||
| 55 | return value; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 43 | [[nodiscard]] IR::U32 DownScale(IR::IREmitter& ir, const IR::U1& is_scaled, IR::U32 value) { | 59 | [[nodiscard]] IR::U32 DownScale(IR::IREmitter& ir, const IR::U1& is_scaled, IR::U32 value) { |
| 44 | IR::U32 scaled_value{value}; | 60 | IR::U32 scaled_value{value}; |
| 45 | bool changed{}; | 61 | bool changed{}; |
| @@ -113,6 +129,74 @@ void ScaleIntegerCoord(IR::IREmitter& ir, IR::Inst& inst, const IR::U1& is_scale | |||
| 113 | } | 129 | } |
| 114 | } | 130 | } |
| 115 | 131 | ||
| 132 | void SubScaleImageFetch(IR::Block& block, IR::Inst& inst) { | ||
| 133 | IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; | ||
| 134 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||
| 135 | const IR::U1 is_scaled{ir.IsTextureScaled(ir.Imm32(info.descriptor_index))}; | ||
| 136 | const IR::Value coord{inst.Arg(1)}; | ||
| 137 | switch (info.type) { | ||
| 138 | case TextureType::Color2D: { | ||
| 139 | const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)}, | ||
| 140 | IR::Attribute::PositionX)}; | ||
| 141 | const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)}, | ||
| 142 | IR::Attribute::PositionY)}; | ||
| 143 | inst.SetArg(1, ir.CompositeConstruct(x, y)); | ||
| 144 | break; | ||
| 145 | } | ||
| 146 | case TextureType::ColorArray2D: { | ||
| 147 | const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)}, | ||
| 148 | IR::Attribute::PositionX)}; | ||
| 149 | const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)}, | ||
| 150 | IR::Attribute::PositionY)}; | ||
| 151 | const IR::U32 z{ir.CompositeExtract(coord, 2)}; | ||
| 152 | inst.SetArg(1, ir.CompositeConstruct(x, y, z)); | ||
| 153 | break; | ||
| 154 | } | ||
| 155 | case TextureType::Color1D: | ||
| 156 | case TextureType::ColorArray1D: | ||
| 157 | case TextureType::Color3D: | ||
| 158 | case TextureType::ColorCube: | ||
| 159 | case TextureType::ColorArrayCube: | ||
| 160 | case TextureType::Buffer: | ||
| 161 | // Nothing to patch here | ||
| 162 | break; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | void SubScaleImageRead(IR::Block& block, IR::Inst& inst) { | ||
| 167 | IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; | ||
| 168 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | ||
| 169 | const IR::U1 is_scaled{ir.IsImageScaled(ir.Imm32(info.descriptor_index))}; | ||
| 170 | const IR::Value coord{inst.Arg(1)}; | ||
| 171 | switch (info.type) { | ||
| 172 | case TextureType::Color2D: { | ||
| 173 | const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)}, | ||
| 174 | IR::Attribute::PositionX)}; | ||
| 175 | const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)}, | ||
| 176 | IR::Attribute::PositionY)}; | ||
| 177 | inst.SetArg(1, ir.CompositeConstruct(x, y)); | ||
| 178 | break; | ||
| 179 | } | ||
| 180 | case TextureType::ColorArray2D: { | ||
| 181 | const IR::U32 x{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 0)}, | ||
| 182 | IR::Attribute::PositionX)}; | ||
| 183 | const IR::U32 y{SubScale(ir, is_scaled, IR::U32{ir.CompositeExtract(coord, 1)}, | ||
| 184 | IR::Attribute::PositionY)}; | ||
| 185 | const IR::U32 z{ir.CompositeExtract(coord, 2)}; | ||
| 186 | inst.SetArg(1, ir.CompositeConstruct(x, y, z)); | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | case TextureType::Color1D: | ||
| 190 | case TextureType::ColorArray1D: | ||
| 191 | case TextureType::Color3D: | ||
| 192 | case TextureType::ColorCube: | ||
| 193 | case TextureType::ColorArrayCube: | ||
| 194 | case TextureType::Buffer: | ||
| 195 | // Nothing to patch here | ||
| 196 | break; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 116 | void PatchImageFetch(IR::Block& block, IR::Inst& inst) { | 200 | void PatchImageFetch(IR::Block& block, IR::Inst& inst) { |
| 117 | IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; | 201 | IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; |
| 118 | const auto info{inst.Flags<IR::TextureInstInfo>()}; | 202 | const auto info{inst.Flags<IR::TextureInstInfo>()}; |
| @@ -145,13 +229,23 @@ void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { | |||
| 145 | break; | 229 | break; |
| 146 | } | 230 | } |
| 147 | case IR::Opcode::ImageQueryDimensions: | 231 | case IR::Opcode::ImageQueryDimensions: |
| 148 | PatchImageQueryDimensions(block, inst); | 232 | if (program.stage == Stage::Compute) { |
| 233 | PatchImageQueryDimensions(block, inst); | ||
| 234 | } | ||
| 149 | break; | 235 | break; |
| 150 | case IR::Opcode::ImageFetch: | 236 | case IR::Opcode::ImageFetch: |
| 151 | PatchImageFetch(block, inst); | 237 | if (is_fragment_shader) { |
| 238 | SubScaleImageFetch(block, inst); | ||
| 239 | } else if (program.stage == Stage::Compute) { | ||
| 240 | PatchImageFetch(block, inst); | ||
| 241 | } | ||
| 152 | break; | 242 | break; |
| 153 | case IR::Opcode::ImageRead: | 243 | case IR::Opcode::ImageRead: |
| 154 | PatchImageRead(block, inst); | 244 | if (is_fragment_shader) { |
| 245 | SubScaleImageRead(block, inst); | ||
| 246 | } else if (program.stage == Stage::Compute) { | ||
| 247 | PatchImageRead(block, inst); | ||
| 248 | } | ||
| 155 | break; | 249 | break; |
| 156 | default: | 250 | default: |
| 157 | break; | 251 | break; |