vk_shader_decompiler: Implement Assign and LogicalAssign
This commit is contained in:
		
							parent
							
								
									d316d248ab
								
							
						
					
					
						commit
						676172e20d
					
				@ -693,7 +693,49 @@ private:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Id Assign(Operation operation) {
 | 
					    Id Assign(Operation operation) {
 | 
				
			||||||
        UNIMPLEMENTED();
 | 
					        const Node dest = operation[0];
 | 
				
			||||||
 | 
					        const Node src = operation[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Id target{};
 | 
				
			||||||
 | 
					        if (const auto gpr = std::get_if<GprNode>(dest)) {
 | 
				
			||||||
 | 
					            if (gpr->GetIndex() == Register::ZeroIndex) {
 | 
				
			||||||
 | 
					                // Writing to Register::ZeroIndex is a no op
 | 
				
			||||||
 | 
					                return {};
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            target = registers.at(gpr->GetIndex());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else if (const auto abuf = std::get_if<AbufNode>(dest)) {
 | 
				
			||||||
 | 
					            target = [&]() -> Id {
 | 
				
			||||||
 | 
					                switch (const auto attribute = abuf->GetIndex(); attribute) {
 | 
				
			||||||
 | 
					                case Attribute::Index::Position:
 | 
				
			||||||
 | 
					                    return AccessElement(t_out_float, per_vertex, position_index,
 | 
				
			||||||
 | 
					                                         abuf->GetElement());
 | 
				
			||||||
 | 
					                case Attribute::Index::PointSize:
 | 
				
			||||||
 | 
					                    return AccessElement(t_out_float, per_vertex, point_size_index);
 | 
				
			||||||
 | 
					                case Attribute::Index::ClipDistances0123:
 | 
				
			||||||
 | 
					                    return AccessElement(t_out_float, per_vertex, clip_distances_index,
 | 
				
			||||||
 | 
					                                         abuf->GetElement());
 | 
				
			||||||
 | 
					                case Attribute::Index::ClipDistances4567:
 | 
				
			||||||
 | 
					                    return AccessElement(t_out_float, per_vertex, clip_distances_index,
 | 
				
			||||||
 | 
					                                         abuf->GetElement() + 4);
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    if (IsGenericAttribute(attribute)) {
 | 
				
			||||||
 | 
					                        return AccessElement(t_out_float, output_attributes.at(attribute),
 | 
				
			||||||
 | 
					                                             abuf->GetElement());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    UNIMPLEMENTED_MSG("Unhandled output attribute: {}",
 | 
				
			||||||
 | 
					                                      static_cast<u32>(attribute));
 | 
				
			||||||
 | 
					                    return {};
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else if (const auto lmem = std::get_if<LmemNode>(dest)) {
 | 
				
			||||||
 | 
					            Id address = BitcastTo<Type::Uint>(Visit(lmem->GetAddress()));
 | 
				
			||||||
 | 
					            address = Emit(OpUDiv(t_uint, address, Constant(t_uint, 4)));
 | 
				
			||||||
 | 
					            target = Emit(OpAccessChain(t_prv_float, local_memory, {address}));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Emit(OpStore(target, Visit(src)));
 | 
				
			||||||
        return {};
 | 
					        return {};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -723,7 +765,27 @@ private:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Id LogicalAssign(Operation operation) {
 | 
					    Id LogicalAssign(Operation operation) {
 | 
				
			||||||
        UNIMPLEMENTED();
 | 
					        const Node dest = operation[0];
 | 
				
			||||||
 | 
					        const Node src = operation[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Id target{};
 | 
				
			||||||
 | 
					        if (const auto pred = std::get_if<PredicateNode>(dest)) {
 | 
				
			||||||
 | 
					            ASSERT_MSG(!pred->IsNegated(), "Negating logical assignment");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const auto index = pred->GetIndex();
 | 
				
			||||||
 | 
					            switch (index) {
 | 
				
			||||||
 | 
					            case Tegra::Shader::Pred::NeverExecute:
 | 
				
			||||||
 | 
					            case Tegra::Shader::Pred::UnusedIndex:
 | 
				
			||||||
 | 
					                // Writing to these predicates is a no-op
 | 
				
			||||||
 | 
					                return {};
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            target = predicates.at(index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        } else if (const auto flag = std::get_if<InternalFlagNode>(dest)) {
 | 
				
			||||||
 | 
					            target = internal_flags.at(static_cast<u32>(flag->GetFlag()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Emit(OpStore(target, Visit(src)));
 | 
				
			||||||
        return {};
 | 
					        return {};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user