shader: Fix resolution scaling pass
This commit is contained in:
		
				
					committed by
					
						 Fernando Sahmkow
						Fernando Sahmkow
					
				
			
			
				
	
			
			
			
						parent
						
							fb924ea85c
						
					
				
				
					commit
					1672e9ba09
				
			| @@ -221,6 +221,7 @@ add_library(shader_recompiler STATIC | ||||
|     ir_opt/lower_fp16_to_fp32.cpp | ||||
|     ir_opt/lower_int64_to_int32.cpp | ||||
|     ir_opt/passes.h | ||||
|     ir_opt/rescaling_pass.cpp | ||||
|     ir_opt/ssa_rewrite_pass.cpp | ||||
|     ir_opt/texture_pass.cpp | ||||
|     ir_opt/verification_pass.cpp | ||||
|   | ||||
| @@ -430,6 +430,9 @@ void VisitUsages(Info& info, IR::Inst& inst) { | ||||
|     case IR::Opcode::IsHelperInvocation: | ||||
|         info.uses_is_helper_invocation = true; | ||||
|         break; | ||||
|     case IR::Opcode::ResolutionDownFactor: | ||||
|         info.uses_rescaling_uniform = true; | ||||
|         break; | ||||
|     case IR::Opcode::LaneId: | ||||
|         info.uses_subgroup_invocation_id = true; | ||||
|         break; | ||||
|   | ||||
| @@ -19,6 +19,7 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program); | ||||
| void IdentityRemovalPass(IR::Program& program); | ||||
| void LowerFp16ToFp32(IR::Program& program); | ||||
| void LowerInt64ToInt32(IR::Program& program); | ||||
| void RescalingPass(IR::Program& program); | ||||
| void SsaRewritePass(IR::Program& program); | ||||
| void TexturePass(Environment& env, IR::Program& program); | ||||
| void VerificationPass(const IR::Program& program); | ||||
|   | ||||
| @@ -3,7 +3,9 @@ | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #include "common/alignment.h" | ||||
| #include "common/settings.h" | ||||
| #include "shader_recompiler/environment.h" | ||||
| #include "shader_recompiler/frontend/ir/ir_emitter.h" | ||||
| #include "shader_recompiler/frontend/ir/modifiers.h" | ||||
| #include "shader_recompiler/frontend/ir/program.h" | ||||
| #include "shader_recompiler/frontend/ir/value.h" | ||||
| @@ -12,59 +14,49 @@ | ||||
|  | ||||
| namespace Shader::Optimization { | ||||
| namespace { | ||||
|  | ||||
| void PatchFragCoord(IR::Inst& inst) { | ||||
| void PatchFragCoord(IR::Block& block, IR::Inst& inst) { | ||||
|     IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; | ||||
|     const IR::F32 inv_resolution_factor = IR::F32{Settings::values.resolution_info.down_factor}; | ||||
|     const IR::F32 new_get_attribute = ir.GetAttribute(inst.Arg(0).Attribute()); | ||||
|     const IR::F32 mul = ir.FMul(new_get_attribute, inv_resolution_factor); | ||||
|     const IR::U1 should_rescale = IR::U1{true}; | ||||
|     const IR::F32 selection = ir.Select(should_rescale, mul, new_get_attribute); | ||||
|     inst.ReplaceUsesWith(selection); | ||||
|     const IR::F32 down_factor{ir.ResolutionDownFactor()}; | ||||
|     const IR::F32 frag_coord{&inst}; | ||||
|     const IR::F32 downscaled_frag_coord{ir.FPMul(frag_coord, down_factor)}; | ||||
|     inst.ReplaceUsesWith(downscaled_frag_coord); | ||||
| } | ||||
|  | ||||
| void Visit(Info& info, IR::Inst& inst) { | ||||
|     info.requires_rescaling_uniform = false; | ||||
| void Visit(const IR::Program& program, IR::Block& block, IR::Inst& inst) { | ||||
|     const bool is_fragment_shader{program.stage == Stage::Fragment}; | ||||
|     switch (inst.GetOpcode()) { | ||||
|     case IR::Opcode::GetAttribute: { | ||||
|         conast auto attrib = inst.Arg(0).Attribute(); | ||||
|         const bool is_frag = | ||||
|             attrib == IR::Attribute::PositionX || attrib == IR::Attribute::PositionY; | ||||
|         const bool must_path = is_frag && program.stage == Stage::Fragment; | ||||
|         if (must_path) { | ||||
|             PatchFragCoord(inst); | ||||
|             info.requires_rescaling_uniform = true; | ||||
|         const IR::Attribute attr{inst.Arg(0).Attribute()}; | ||||
|         switch (attr) { | ||||
|         case IR::Attribute::PositionX: | ||||
|         case IR::Attribute::PositionY: | ||||
|             if (is_fragment_shader) { | ||||
|                 PatchFragCoord(block, inst); | ||||
|             } | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     case IR::Opcode::ImageQueryDimensions: { | ||||
|         info.requires_rescaling_uniform |= true; | ||||
|     case IR::Opcode::ImageQueryDimensions: | ||||
|         break; | ||||
|     } | ||||
|     case IR::Opcode::ImageFetch: { | ||||
|         info.requires_rescaling_uniform |= true; | ||||
|     case IR::Opcode::ImageFetch: | ||||
|         break; | ||||
|     } | ||||
|     case IR::Opcode::ImageRead: { | ||||
|         info.requires_rescaling_uniform |= true; | ||||
|     case IR::Opcode::ImageRead: | ||||
|         break; | ||||
|     } | ||||
|     case IR::Opcode::ImageWrite: { | ||||
|         info.requires_rescaling_uniform |= true; | ||||
|     case IR::Opcode::ImageWrite: | ||||
|         break; | ||||
|     } | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| } | ||||
| } // Anonymous namespace | ||||
|  | ||||
| } // namespace | ||||
|  | ||||
| void RescalingPass(Environment& env, IR::Program& program) { | ||||
|     Info& info{program.info}; | ||||
| void RescalingPass(IR::Program& program) { | ||||
|     for (IR::Block* const block : program.post_order_blocks) { | ||||
|         for (IR::Inst& inst : block->Instructions()) { | ||||
|             Visit(info, inst); | ||||
|             Visit(program, *block, inst); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -172,7 +172,7 @@ struct Info { | ||||
|     bool uses_global_memory{}; | ||||
|     bool uses_atomic_image_u32{}; | ||||
|     bool uses_shadow_lod{}; | ||||
|     bool requires_rescaling_uniform{}; | ||||
|     bool uses_rescaling_uniform{}; | ||||
|  | ||||
|     IR::Type used_constant_buffer_types{}; | ||||
|     IR::Type used_storage_buffer_types{}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user