early-access version 1491

main
pineappleEA 2021-03-01 03:52:01 +01:00
parent ae5276503a
commit dff35d290d
3 changed files with 80 additions and 10 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access
=============
This is the source code for early-access 1490.
This is the source code for early-access 1491.
## Legal Notice

View File

@ -79,6 +79,11 @@ const float fswzadd_modifiers_a[] = float[4](-1.0f, 1.0f, -1.0f, 0.0f );
const float fswzadd_modifiers_b[] = float[4](-1.0f, -1.0f, 1.0f, -1.0f );
)";
enum class HelperFunction {
SignedAtomic = 0,
Total,
};
class ShaderWriter final {
public:
void AddExpression(std::string_view text) {
@ -434,6 +439,7 @@ public:
DeclareInternalFlags();
DeclareCustomVariables();
DeclarePhysicalAttributeReader();
DeclareHelpersForward();
const auto& subfunctions = ir.GetSubFunctions();
auto it = subfunctions.rbegin();
@ -471,6 +477,9 @@ public:
--code.scope;
code.AddLine("}}");
code.AddNewLine();
DeclareHelpers();
}
std::string GetResult() {
@ -620,7 +629,7 @@ private:
size = limit;
}
code.AddLine("shared uint smem[{}];", size / 4);
code.AddLine("shared uint {}[{}];", GetSharedMemory(), size / 4);
code.AddNewLine();
}
code.AddLine("layout (local_size_x = {}, local_size_y = {}, local_size_z = {}) in;",
@ -1004,6 +1013,27 @@ private:
}
}
void DeclareHelpersForward() {
code.AddLine("int Helpers_AtomicShared(uint offset, int value, bool is_min);");
code.AddNewLine();
}
void DeclareHelpers() {
if (IsHelperEnabled(HelperFunction::SignedAtomic)) {
code.AddLine(
R"(int Helpers_AtomicShared(uint offset, int value, bool is_min) {{
uint oldValue, newValue;
do {{
oldValue = {}[offset];
newValue = is_min ? uint(min(int(oldValue), value)) : uint(max(int(oldValue), value));
}} while (atomicCompSwap({}[offset], newValue, oldValue) != oldValue);
return int(oldValue);
}})",
GetSharedMemory(), GetSharedMemory());
code.AddNewLine();
}
}
void VisitBlock(const NodeBlock& bb) {
for (const auto& node : bb) {
Visit(node).CheckVoid();
@ -1130,7 +1160,9 @@ private:
}
if (const auto smem = std::get_if<SmemNode>(&*node)) {
return {fmt::format("smem[{} >> 2]", Visit(smem->GetAddress()).AsUint()), Type::Uint};
return {
fmt::format("{}[{} >> 2]", GetSharedMemory(), Visit(smem->GetAddress()).AsUint()),
Type::Uint};
}
if (const auto internal_flag = std::get_if<InternalFlagNode>(&*node)) {
@ -1624,7 +1656,9 @@ private:
Type::Uint};
} else if (const auto smem = std::get_if<SmemNode>(&*dest)) {
ASSERT(stage == ShaderType::Compute);
target = {fmt::format("smem[{} >> 2]", Visit(smem->GetAddress()).AsUint()), Type::Uint};
target = {
fmt::format("{}[{} >> 2]", GetSharedMemory(), Visit(smem->GetAddress()).AsUint()),
Type::Uint};
} else if (const auto gmem = std::get_if<GmemNode>(&*dest)) {
const std::string real = Visit(gmem->GetRealAddress()).AsUint();
const std::string base = Visit(gmem->GetBaseAddress()).AsUint();
@ -2141,7 +2175,14 @@ private:
UNIMPLEMENTED_IF(meta->sampler.is_array);
const std::size_t count = operation.GetOperandsCount();
std::string expr = "texelFetch(";
std::string expr = "texelFetch";
if (!meta->aoffi.empty()) {
expr += "Offset";
}
expr += '(';
expr += GetSampler(meta->sampler);
expr += ", ";
@ -2163,6 +2204,20 @@ private:
expr += ", ";
expr += Visit(meta->lod).AsInt();
}
if (!meta->aoffi.empty()) {
expr += ", ";
expr += constructors.at(meta->aoffi.size() - 1);
expr += '(';
for (size_t i = 0; i < meta->aoffi.size(); ++i) {
if (i > 0) {
expr += ", ";
}
expr += Visit(meta->aoffi[i]).AsInt();
}
expr += ')';
}
expr += ')';
expr += GetSwizzle(meta->element);
@ -2209,8 +2264,11 @@ private:
template <const std::string_view& opname, Type type>
Expression Atomic(Operation operation) {
if ((opname == Func::Min || opname == Func::Max) && type == Type::Int) {
UNIMPLEMENTED_MSG("Unimplemented Min & Max for atomic operations");
return {};
// Use a helper as a workaround due to memory being uint
SetHelperEnabled(HelperFunction::SignedAtomic, true);
return {fmt::format("Helpers_AtomicShared({}, {}, {})", Visit(operation[0]).AsInt(),
Visit(operation[1]).AsInt(), opname == Func::Min),
Type::Int};
}
return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(),
Visit(operation[1]).AsUint()),
@ -2737,6 +2795,10 @@ private:
}
}
constexpr std::string_view GetSharedMemory() const {
return "shared_mem";
}
std::string GetInternalFlag(InternalFlag flag) const {
constexpr std::array InternalFlagNames = {"zero_flag", "sign_flag", "carry_flag",
"overflow_flag"};
@ -2778,6 +2840,14 @@ private:
return std::min<u32>(device.GetMaxVaryings(), Maxwell::NumVaryings);
}
void SetHelperEnabled(HelperFunction hf, bool enabled) {
helper_functions_enabled[static_cast<size_t>(hf)] = enabled;
}
bool IsHelperEnabled(HelperFunction hf) const {
return helper_functions_enabled[static_cast<size_t>(hf)];
}
const Device& device;
const ShaderIR& ir;
const Registry& registry;
@ -2792,6 +2862,8 @@ private:
ShaderWriter code;
std::optional<u32> max_input_vertices;
std::array<bool, static_cast<size_t>(HelperFunction::Total)> helper_functions_enabled{};
};
std::string GetFlowVariable(u32 index) {

View File

@ -339,8 +339,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
const TextureType texture_type{instr.tlds.GetTextureType()};
const bool is_array{instr.tlds.IsArrayTexture()};
UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::AOFFI),
"AOFFI is not implemented");
UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::MZ), "MZ is not implemented");
const Node4 components = GetTldsCode(instr, texture_type, is_array);
@ -822,7 +820,7 @@ Node4 ShaderIR::GetTldsCode(Instruction instr, TextureType texture_type, bool is
for (std::size_t i = 0; i < type_coord_count; ++i) {
const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
coords.push_back(
GetRegister(last && !aoffi_enabled ? last_coord_register : coord_register + i));
GetRegister(last && !aoffi_enabled ? last_coord_register : (coord_register + i)));
}
const Node array = is_array ? GetRegister(array_register) : nullptr;