diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 92 |
1 files changed, 83 insertions, 9 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 0e644564a..d1ae4be6d 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -49,8 +49,9 @@ class ExprDecompiler; enum class Type { Void, Bool, Bool2, Float, Int, Uint, HalfFloat }; struct TextureAoffi {}; +struct TextureDerivates {}; using TextureArgument = std::pair<Type, Node>; -using TextureIR = std::variant<TextureAoffi, TextureArgument>; +using TextureIR = std::variant<TextureAoffi, TextureDerivates, TextureArgument>; constexpr u32 MAX_CONSTBUFFER_ELEMENTS = static_cast<u32>(Maxwell::MaxConstBufferSize) / (4 * sizeof(float)); @@ -1075,7 +1076,7 @@ private: } std::string GenerateTexture(Operation operation, const std::string& function_suffix, - const std::vector<TextureIR>& extras) { + const std::vector<TextureIR>& extras, bool sepparate_dc = false) { constexpr std::array coord_constructors = {"float", "vec2", "vec3", "vec4"}; const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); @@ -1090,7 +1091,8 @@ private: expr += "Offset"; } expr += '(' + GetSampler(meta->sampler) + ", "; - expr += coord_constructors.at(count + (has_array ? 1 : 0) + (has_shadow ? 1 : 0) - 1); + expr += coord_constructors.at(count + (has_array ? 1 : 0) + + (has_shadow && !sepparate_dc ? 1 : 0) - 1); expr += '('; for (std::size_t i = 0; i < count; ++i) { expr += Visit(operation[i]).AsFloat(); @@ -1103,15 +1105,22 @@ private: expr += ", float(" + Visit(meta->array).AsInt() + ')'; } if (has_shadow) { - expr += ", " + Visit(meta->depth_compare).AsFloat(); + if (sepparate_dc) { + expr += "), " + Visit(meta->depth_compare).AsFloat(); + } else { + expr += ", " + Visit(meta->depth_compare).AsFloat() + ')'; + } + } else { + expr += ')'; } - expr += ')'; for (const auto& variant : extras) { if (const auto argument = std::get_if<TextureArgument>(&variant)) { expr += GenerateTextureArgument(*argument); } else if (std::holds_alternative<TextureAoffi>(variant)) { expr += GenerateTextureAoffi(meta->aoffi); + } else if (std::holds_alternative<TextureDerivates>(variant)) { + expr += GenerateTextureDerivates(meta->derivates); } else { UNREACHABLE(); } @@ -1181,6 +1190,36 @@ private: return expr; } + std::string GenerateTextureDerivates(const std::vector<Node>& derivates) { + if (derivates.empty()) { + return {}; + } + constexpr std::array coord_constructors = {"float", "vec2", "vec3"}; + std::string expr = ", "; + const std::size_t components = derivates.size() / 2; + std::string dx = coord_constructors.at(components - 1); + std::string dy = coord_constructors.at(components - 1); + dx += '('; + dy += '('; + + for (std::size_t index = 0; index < components; ++index) { + const auto operand_x{derivates.at(index * 2)}; + const auto operand_y{derivates.at(index * 2 + 1)}; + dx += Visit(operand_x).AsFloat(); + dy += Visit(operand_y).AsFloat(); + + if (index + 1 < components) { + dx += ", "; + dy += ", "; + } + } + dx += ')'; + dy += ')'; + expr += dx + ", " + dy; + + return expr; + } + std::string BuildIntegerCoordinates(Operation operation) { constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("}; const std::size_t coords_count{operation.GetOperandsCount()}; @@ -1450,6 +1489,11 @@ private: return GenerateUnary(operation, "bitCount", type, type); } + template <Type type> + Expression BitMSB(Operation operation) { + return GenerateUnary(operation, "findMSB", type, type); + } + Expression HNegate(Operation operation) { const auto GetNegate = [&](std::size_t index) { return VisitOperand(operation, index).AsBool() + " ? -1 : 1"; @@ -1668,10 +1712,17 @@ private: ASSERT(meta); const auto type = meta->sampler.IsShadow() ? Type::Float : Type::Int; - return {GenerateTexture(operation, "Gather", - {TextureAoffi{}, TextureArgument{type, meta->component}}) + - GetSwizzle(meta->element), - Type::Float}; + if (meta->sampler.IsShadow()) { + return {GenerateTexture(operation, "Gather", {TextureAoffi{}}, true) + + GetSwizzle(meta->element), + Type::Float}; + } else { + return {GenerateTexture(operation, "Gather", + {TextureAoffi{}, TextureArgument{type, meta->component}}, + false) + + GetSwizzle(meta->element), + Type::Float}; + } } Expression TextureQueryDimensions(Operation operation) { @@ -1738,6 +1789,14 @@ private: return {std::move(expr), Type::Float}; } + Expression TextureGradient(Operation operation) { + const auto meta = std::get_if<MetaTexture>(&operation.GetMeta()); + ASSERT(meta); + + std::string expr = GenerateTexture(operation, "Grad", {TextureDerivates{}, TextureAoffi{}}); + return {std::move(expr) + GetSwizzle(meta->element), Type::Float}; + } + Expression ImageLoad(Operation operation) { if (!device.HasImageLoadFormatted()) { LOG_ERROR(Render_OpenGL, @@ -1869,6 +1928,10 @@ private: return {}; } + Expression InvocationId(Operation operation) { + return {"gl_InvocationID", Type::Int}; + } + Expression YNegate(Operation operation) { return {"y_direction", Type::Float}; } @@ -1942,6 +2005,11 @@ private: return {fmt::format("readInvocationARB({}, {})", value, index), Type::Float}; } + Expression MemoryBarrierGL(Operation) { + code.AddLine("memoryBarrier();"); + return {}; + } + struct Func final { Func() = delete; ~Func() = delete; @@ -2003,6 +2071,7 @@ private: &GLSLDecompiler::BitfieldInsert<Type::Int>, &GLSLDecompiler::BitfieldExtract<Type::Int>, &GLSLDecompiler::BitCount<Type::Int>, + &GLSLDecompiler::BitMSB<Type::Int>, &GLSLDecompiler::Add<Type::Uint>, &GLSLDecompiler::Mul<Type::Uint>, @@ -2021,6 +2090,7 @@ private: &GLSLDecompiler::BitfieldInsert<Type::Uint>, &GLSLDecompiler::BitfieldExtract<Type::Uint>, &GLSLDecompiler::BitCount<Type::Uint>, + &GLSLDecompiler::BitMSB<Type::Uint>, &GLSLDecompiler::Add<Type::HalfFloat>, &GLSLDecompiler::Mul<Type::HalfFloat>, @@ -2084,6 +2154,7 @@ private: &GLSLDecompiler::TextureQueryDimensions, &GLSLDecompiler::TextureQueryLod, &GLSLDecompiler::TexelFetch, + &GLSLDecompiler::TextureGradient, &GLSLDecompiler::ImageLoad, &GLSLDecompiler::ImageStore, @@ -2104,6 +2175,7 @@ private: &GLSLDecompiler::EmitVertex, &GLSLDecompiler::EndPrimitive, + &GLSLDecompiler::InvocationId, &GLSLDecompiler::YNegate, &GLSLDecompiler::LocalInvocationId<0>, &GLSLDecompiler::LocalInvocationId<1>, @@ -2119,6 +2191,8 @@ private: &GLSLDecompiler::ThreadId, &GLSLDecompiler::ShuffleIndexed, + + &GLSLDecompiler::MemoryBarrierGL, }; static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount)); |