early-access version 1491
This commit is contained in:
parent
ae5276503a
commit
dff35d290d
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user