shader/memory: Implement ST (generic memory)
This commit is contained in:
		| @@ -180,27 +180,6 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     case OpCode::Id::STG: { | ||||
|         const auto [real_address_base, base_address, descriptor] = | ||||
|             TrackAndGetGlobalMemory(bb, instr, true); | ||||
|  | ||||
|         // Encode in temporary registers like this: real_base_address, {registers_to_be_written...} | ||||
|         SetTemporal(bb, 0, real_address_base); | ||||
|  | ||||
|         const u32 count = GetUniformTypeElementsCount(instr.stg.type); | ||||
|         for (u32 i = 0; i < count; ++i) { | ||||
|             SetTemporal(bb, i + 1, GetRegister(instr.gpr0.Value() + i)); | ||||
|         } | ||||
|         for (u32 i = 0; i < count; ++i) { | ||||
|             const Node it_offset = Immediate(i * 4); | ||||
|             const Node real_address = | ||||
|                 Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset); | ||||
|             const Node gmem = StoreNode(GmemNode(real_address, base_address, descriptor)); | ||||
|  | ||||
|             bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporal(i + 1))); | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     case OpCode::Id::ST_A: { | ||||
|         UNIMPLEMENTED_IF_MSG(instr.gpr8.Value() != Register::ZeroIndex, | ||||
|                              "Indirect attribute loads are not supported"); | ||||
| @@ -256,6 +235,41 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     case OpCode::Id::ST: | ||||
|     case OpCode::Id::STG: { | ||||
|         const auto type = [instr, &opcode]() -> Tegra::Shader::UniformType { | ||||
|             switch (opcode->get().GetId()) { | ||||
|             case OpCode::Id::ST: | ||||
|                 UNIMPLEMENTED_IF_MSG(!instr.generic.extended, "Unextended ST is not implemented"); | ||||
|                 return instr.generic.type; | ||||
|             case OpCode::Id::STG: | ||||
|                 return instr.stg.type; | ||||
|             default: | ||||
|                 UNREACHABLE(); | ||||
|                 return {}; | ||||
|             } | ||||
|         }(); | ||||
|  | ||||
|         const auto [real_address_base, base_address, descriptor] = | ||||
|             TrackAndGetGlobalMemory(bb, instr, true); | ||||
|  | ||||
|         // Encode in temporary registers like this: real_base_address, {registers_to_be_written...} | ||||
|         SetTemporal(bb, 0, real_address_base); | ||||
|  | ||||
|         const u32 count = GetUniformTypeElementsCount(type); | ||||
|         for (u32 i = 0; i < count; ++i) { | ||||
|             SetTemporal(bb, i + 1, GetRegister(instr.gpr0.Value() + i)); | ||||
|         } | ||||
|         for (u32 i = 0; i < count; ++i) { | ||||
|             const Node it_offset = Immediate(i * 4); | ||||
|             const Node real_address = | ||||
|                 Operation(OperationCode::UAdd, NO_PRECISE, real_address_base, it_offset); | ||||
|             const Node gmem = StoreNode(GmemNode(real_address, base_address, descriptor)); | ||||
|  | ||||
|             bb.push_back(Operation(OperationCode::Assign, gmem, GetTemporal(i + 1))); | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     case OpCode::Id::AL2P: { | ||||
|         // Ignore al2p.direction since we don't care about it. | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
					ReinUsesLisp