summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-04-27 07:07:18 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-06-21 02:38:33 +0200
commit06c4ce86458310870abec90ada68ac393256b9b6 (patch)
tree43957a5f0e33c044b1206663e91d390ef1336d2a /src/video_core/renderer_opengl/gl_shader_decompiler.cpp
parentgl_rasterizer: Track texture buffer usage (diff)
downloadyuzu-06c4ce86458310870abec90ada68ac393256b9b6.tar
yuzu-06c4ce86458310870abec90ada68ac393256b9b6.tar.gz
yuzu-06c4ce86458310870abec90ada68ac393256b9b6.tar.bz2
yuzu-06c4ce86458310870abec90ada68ac393256b9b6.tar.lz
yuzu-06c4ce86458310870abec90ada68ac393256b9b6.tar.xz
yuzu-06c4ce86458310870abec90ada68ac393256b9b6.tar.zst
yuzu-06c4ce86458310870abec90ada68ac393256b9b6.zip
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index ece386cdc..2ae2f1db2 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -180,6 +180,7 @@ public:
DeclareGlobalMemory();
DeclareSamplers();
DeclarePhysicalAttributeReader();
+ DeclareImages();
code.AddLine("void execute_{}() {{", suffix);
++code.scope;
@@ -531,6 +532,36 @@ private:
code.AddNewLine();
}
+ void DeclareImages() {
+ const auto& images{ir.GetImages()};
+ for (const auto& image : images) {
+ const std::string image_type = [&]() {
+ switch (image.GetType()) {
+ case Tegra::Shader::ImageType::Texture1D:
+ return "image1D";
+ case Tegra::Shader::ImageType::TextureBuffer:
+ return "bufferImage";
+ case Tegra::Shader::ImageType::Texture1DArray:
+ return "image1DArray";
+ case Tegra::Shader::ImageType::Texture2D:
+ return "image2D";
+ case Tegra::Shader::ImageType::Texture2DArray:
+ return "image2DArray";
+ case Tegra::Shader::ImageType::Texture3D:
+ return "image3D";
+ default:
+ UNREACHABLE();
+ return "image1D";
+ }
+ }();
+ code.AddLine("layout (binding = IMAGE_BINDING_" + std::to_string(image.GetIndex()) +
+ ") coherent volatile writeonly uniform " + image_type + ' ' +
+ GetImage(image) + ';');
+ }
+ if (!images.empty())
+ code.AddNewLine();
+ }
+
void VisitBlock(const NodeBlock& bb) {
for (const auto& node : bb) {
if (const std::string expr = Visit(node); !expr.empty()) {
@@ -1478,6 +1509,39 @@ private:
return tmp;
}
+ std::string ImageStore(Operation operation) {
+ constexpr std::array<const char*, 4> constructors{"int(", "ivec2(", "ivec3(", "ivec4("};
+ const auto meta{std::get<MetaImage>(operation.GetMeta())};
+
+ std::string expr = "imageStore(";
+ expr += GetImage(meta.image);
+ expr += ", ";
+
+ const std::size_t coords_count{operation.GetOperandsCount()};
+ expr += constructors.at(coords_count - 1);
+ for (std::size_t i = 0; i < coords_count; ++i) {
+ expr += VisitOperand(operation, i, Type::Int);
+ if (i + 1 < coords_count) {
+ expr += ", ";
+ }
+ }
+ expr += "), ";
+
+ const std::size_t values_count{meta.values.size()};
+ UNIMPLEMENTED_IF(values_count != 4);
+ expr += "vec4(";
+ for (std::size_t i = 0; i < values_count; ++i) {
+ expr += Visit(meta.values.at(i));
+ if (i + 1 < values_count) {
+ expr += ", ";
+ }
+ }
+ expr += "));";
+
+ code.AddLine(expr);
+ return {};
+ }
+
std::string Branch(Operation operation) {
const auto target = std::get_if<ImmediateNode>(&*operation[0]);
UNIMPLEMENTED_IF(!target);
@@ -1718,6 +1782,8 @@ private:
&GLSLDecompiler::TextureQueryLod,
&GLSLDecompiler::TexelFetch,
+ &GLSLDecompiler::ImageStore,
+
&GLSLDecompiler::Branch,
&GLSLDecompiler::PushFlowStack,
&GLSLDecompiler::PopFlowStack,
@@ -1786,6 +1852,10 @@ private:
return GetDeclarationWithSuffix(static_cast<u32>(sampler.GetIndex()), "sampler");
}
+ std::string GetImage(const Image& image) const {
+ return GetDeclarationWithSuffix(static_cast<u32>(image.GetIndex()), "image");
+ }
+
void EmitIfdefIsBuffer(const Sampler& sampler) {
code.AddLine(fmt::format("#ifdef SAMPLER_{}_IS_BUFFER", sampler.GetIndex()));
}