early-access version 1491
This commit is contained in:
parent
ae5276503a
commit
dff35d290d
3 changed files with 80 additions and 10 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 1490.
|
This is the source code for early-access 1491.
|
||||||
|
|
||||||
## Legal Notice
|
## 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 );
|
const float fswzadd_modifiers_b[] = float[4](-1.0f, -1.0f, 1.0f, -1.0f );
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
enum class HelperFunction {
|
||||||
|
SignedAtomic = 0,
|
||||||
|
Total,
|
||||||
|
};
|
||||||
|
|
||||||
class ShaderWriter final {
|
class ShaderWriter final {
|
||||||
public:
|
public:
|
||||||
void AddExpression(std::string_view text) {
|
void AddExpression(std::string_view text) {
|
||||||
|
@ -434,6 +439,7 @@ public:
|
||||||
DeclareInternalFlags();
|
DeclareInternalFlags();
|
||||||
DeclareCustomVariables();
|
DeclareCustomVariables();
|
||||||
DeclarePhysicalAttributeReader();
|
DeclarePhysicalAttributeReader();
|
||||||
|
DeclareHelpersForward();
|
||||||
|
|
||||||
const auto& subfunctions = ir.GetSubFunctions();
|
const auto& subfunctions = ir.GetSubFunctions();
|
||||||
auto it = subfunctions.rbegin();
|
auto it = subfunctions.rbegin();
|
||||||
|
@ -471,6 +477,9 @@ public:
|
||||||
|
|
||||||
--code.scope;
|
--code.scope;
|
||||||
code.AddLine("}}");
|
code.AddLine("}}");
|
||||||
|
|
||||||
|
code.AddNewLine();
|
||||||
|
DeclareHelpers();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetResult() {
|
std::string GetResult() {
|
||||||
|
@ -620,7 +629,7 @@ private:
|
||||||
size = limit;
|
size = limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
code.AddLine("shared uint smem[{}];", size / 4);
|
code.AddLine("shared uint {}[{}];", GetSharedMemory(), size / 4);
|
||||||
code.AddNewLine();
|
code.AddNewLine();
|
||||||
}
|
}
|
||||||
code.AddLine("layout (local_size_x = {}, local_size_y = {}, local_size_z = {}) in;",
|
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) {
|
void VisitBlock(const NodeBlock& bb) {
|
||||||
for (const auto& node : bb) {
|
for (const auto& node : bb) {
|
||||||
Visit(node).CheckVoid();
|
Visit(node).CheckVoid();
|
||||||
|
@ -1130,7 +1160,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto smem = std::get_if<SmemNode>(&*node)) {
|
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)) {
|
if (const auto internal_flag = std::get_if<InternalFlagNode>(&*node)) {
|
||||||
|
@ -1624,7 +1656,9 @@ private:
|
||||||
Type::Uint};
|
Type::Uint};
|
||||||
} else if (const auto smem = std::get_if<SmemNode>(&*dest)) {
|
} else if (const auto smem = std::get_if<SmemNode>(&*dest)) {
|
||||||
ASSERT(stage == ShaderType::Compute);
|
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)) {
|
} else if (const auto gmem = std::get_if<GmemNode>(&*dest)) {
|
||||||
const std::string real = Visit(gmem->GetRealAddress()).AsUint();
|
const std::string real = Visit(gmem->GetRealAddress()).AsUint();
|
||||||
const std::string base = Visit(gmem->GetBaseAddress()).AsUint();
|
const std::string base = Visit(gmem->GetBaseAddress()).AsUint();
|
||||||
|
@ -2141,7 +2175,14 @@ private:
|
||||||
UNIMPLEMENTED_IF(meta->sampler.is_array);
|
UNIMPLEMENTED_IF(meta->sampler.is_array);
|
||||||
const std::size_t count = operation.GetOperandsCount();
|
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 += GetSampler(meta->sampler);
|
||||||
expr += ", ";
|
expr += ", ";
|
||||||
|
|
||||||
|
@ -2163,6 +2204,20 @@ private:
|
||||||
expr += ", ";
|
expr += ", ";
|
||||||
expr += Visit(meta->lod).AsInt();
|
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 += ')';
|
||||||
expr += GetSwizzle(meta->element);
|
expr += GetSwizzle(meta->element);
|
||||||
|
|
||||||
|
@ -2209,8 +2264,11 @@ private:
|
||||||
template <const std::string_view& opname, Type type>
|
template <const std::string_view& opname, Type type>
|
||||||
Expression Atomic(Operation operation) {
|
Expression Atomic(Operation operation) {
|
||||||
if ((opname == Func::Min || opname == Func::Max) && type == Type::Int) {
|
if ((opname == Func::Min || opname == Func::Max) && type == Type::Int) {
|
||||||
UNIMPLEMENTED_MSG("Unimplemented Min & Max for atomic operations");
|
// Use a helper as a workaround due to memory being uint
|
||||||
return {};
|
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(),
|
return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(),
|
||||||
Visit(operation[1]).AsUint()),
|
Visit(operation[1]).AsUint()),
|
||||||
|
@ -2737,6 +2795,10 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr std::string_view GetSharedMemory() const {
|
||||||
|
return "shared_mem";
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetInternalFlag(InternalFlag flag) const {
|
std::string GetInternalFlag(InternalFlag flag) const {
|
||||||
constexpr std::array InternalFlagNames = {"zero_flag", "sign_flag", "carry_flag",
|
constexpr std::array InternalFlagNames = {"zero_flag", "sign_flag", "carry_flag",
|
||||||
"overflow_flag"};
|
"overflow_flag"};
|
||||||
|
@ -2778,6 +2840,14 @@ private:
|
||||||
return std::min<u32>(device.GetMaxVaryings(), Maxwell::NumVaryings);
|
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 Device& device;
|
||||||
const ShaderIR& ir;
|
const ShaderIR& ir;
|
||||||
const Registry& registry;
|
const Registry& registry;
|
||||||
|
@ -2792,6 +2862,8 @@ private:
|
||||||
ShaderWriter code;
|
ShaderWriter code;
|
||||||
|
|
||||||
std::optional<u32> max_input_vertices;
|
std::optional<u32> max_input_vertices;
|
||||||
|
|
||||||
|
std::array<bool, static_cast<size_t>(HelperFunction::Total)> helper_functions_enabled{};
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string GetFlowVariable(u32 index) {
|
std::string GetFlowVariable(u32 index) {
|
||||||
|
|
|
@ -339,8 +339,6 @@ u32 ShaderIR::DecodeTexture(NodeBlock& bb, u32 pc) {
|
||||||
const TextureType texture_type{instr.tlds.GetTextureType()};
|
const TextureType texture_type{instr.tlds.GetTextureType()};
|
||||||
const bool is_array{instr.tlds.IsArrayTexture()};
|
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");
|
UNIMPLEMENTED_IF_MSG(instr.tlds.UsesMiscMode(TextureMiscMode::MZ), "MZ is not implemented");
|
||||||
|
|
||||||
const Node4 components = GetTldsCode(instr, texture_type, is_array);
|
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) {
|
for (std::size_t i = 0; i < type_coord_count; ++i) {
|
||||||
const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
|
const bool last = (i == (type_coord_count - 1)) && (type_coord_count > 1);
|
||||||
coords.push_back(
|
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;
|
const Node array = is_array ? GetRegister(array_register) : nullptr;
|
||||||
|
|
Loading…
Reference in a new issue