summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp147
1 files changed, 49 insertions, 98 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 74cb59bc1..e6b36a0f2 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -19,6 +19,7 @@
#include "video_core/renderer_opengl/gl_device.h"
#include "video_core/renderer_opengl/gl_rasterizer.h"
#include "video_core/renderer_opengl/gl_shader_decompiler.h"
+#include "video_core/shader/node.h"
#include "video_core/shader/shader_ir.h"
namespace OpenGL::GLShader {
@@ -398,8 +399,6 @@ public:
usage.is_read, usage.is_written);
}
entries.clip_distances = ir.GetClipDistances();
- entries.shader_viewport_layer_array =
- IsVertexShader(stage) && (ir.UsesLayer() || ir.UsesViewportIndex());
entries.shader_length = ir.GetLength();
return entries;
}
@@ -725,36 +724,20 @@ private:
const char* image_type = [&] {
switch (image.GetType()) {
case Tegra::Shader::ImageType::Texture1D:
- return "image1D";
+ return "1D";
case Tegra::Shader::ImageType::TextureBuffer:
- return "imageBuffer";
+ return "Buffer";
case Tegra::Shader::ImageType::Texture1DArray:
- return "image1DArray";
+ return "1DArray";
case Tegra::Shader::ImageType::Texture2D:
- return "image2D";
+ return "2D";
case Tegra::Shader::ImageType::Texture2DArray:
- return "image2DArray";
+ return "2DArray";
case Tegra::Shader::ImageType::Texture3D:
- return "image3D";
+ return "3D";
default:
UNREACHABLE();
- return "image1D";
- }
- }();
-
- const auto [type_prefix, format] = [&]() -> std::pair<const char*, const char*> {
- if (!image.IsSizeKnown()) {
- return {"", ""};
- }
- switch (image.GetSize()) {
- case Tegra::Shader::ImageAtomicSize::U32:
- return {"u", "r32ui, "};
- case Tegra::Shader::ImageAtomicSize::S32:
- return {"i", "r32i, "};
- default:
- UNIMPLEMENTED_MSG("Unimplemented atomic size={}",
- static_cast<u32>(image.GetSize()));
- return {"", ""};
+ return "1D";
}
}();
@@ -765,8 +748,12 @@ private:
qualifier += " writeonly";
}
- code.AddLine("layout (binding = IMAGE_BINDING_{}) {} uniform "
- "{} {};",
+ std::string format;
+ if (image.IsAtomic()) {
+ format = "r32ui, ";
+ }
+
+ code.AddLine("layout ({}binding = IMAGE_BINDING_{}) {} uniform uimage{} {};", format,
image.GetIndex(), qualifier, image_type, GetImage(image));
}
if (!images.empty()) {
@@ -1234,28 +1221,13 @@ private:
}
std::string BuildImageValues(Operation operation) {
+ constexpr std::array constructors{"uint", "uvec2", "uvec3", "uvec4"};
const auto meta{std::get<MetaImage>(operation.GetMeta())};
- const auto [constructors, type] = [&]() -> std::pair<std::array<const char*, 4>, Type> {
- constexpr std::array float_constructors{"float", "vec2", "vec3", "vec4"};
- if (!meta.image.IsSizeKnown()) {
- return {float_constructors, Type::Float};
- }
- switch (meta.image.GetSize()) {
- case Tegra::Shader::ImageAtomicSize::U32:
- return {{"uint", "uvec2", "uvec3", "uvec4"}, Type::Uint};
- case Tegra::Shader::ImageAtomicSize::S32:
- return {{"int", "ivec2", "ivec3", "ivec4"}, Type::Uint};
- default:
- UNIMPLEMENTED_MSG("Unimplemented image size={}",
- static_cast<u32>(meta.image.GetSize()));
- return {float_constructors, Type::Float};
- }
- }();
const std::size_t values_count{meta.values.size()};
std::string expr = fmt::format("{}(", constructors.at(values_count - 1));
for (std::size_t i = 0; i < values_count; ++i) {
- expr += Visit(meta.values.at(i)).As(type);
+ expr += Visit(meta.values.at(i)).AsUint();
if (i + 1 < values_count) {
expr += ", ";
}
@@ -1264,29 +1236,6 @@ private:
return expr;
}
- Expression AtomicImage(Operation operation, const char* opname) {
- constexpr std::array constructors{"int(", "ivec2(", "ivec3(", "ivec4("};
- const auto meta{std::get<MetaImage>(operation.GetMeta())};
- ASSERT(meta.values.size() == 1);
- ASSERT(meta.image.IsSizeKnown());
-
- const auto type = [&]() {
- switch (const auto size = meta.image.GetSize()) {
- case Tegra::Shader::ImageAtomicSize::U32:
- return Type::Uint;
- case Tegra::Shader::ImageAtomicSize::S32:
- return Type::Int;
- default:
- UNIMPLEMENTED_MSG("Unimplemented image size={}", static_cast<u32>(size));
- return Type::Uint;
- }
- }();
-
- return {fmt::format("{}({}, {}, {})", opname, GetImage(meta.image),
- BuildIntegerCoordinates(operation), Visit(meta.values[0]).As(type)),
- type};
- }
-
Expression Assign(Operation operation) {
const Node& dest = operation[0];
const Node& src = operation[1];
@@ -1809,6 +1758,19 @@ private:
return {tmp, Type::Float};
}
+ Expression ImageLoad(Operation operation) {
+ if (!device.HasImageLoadFormatted()) {
+ LOG_ERROR(Render_OpenGL,
+ "Device lacks GL_EXT_shader_image_load_formatted, stubbing image load");
+ return {"0", Type::Int};
+ }
+
+ const auto meta{std::get<MetaImage>(operation.GetMeta())};
+ return {fmt::format("imageLoad({}, {}){}", GetImage(meta.image),
+ BuildIntegerCoordinates(operation), GetSwizzle(meta.element)),
+ Type::Uint};
+ }
+
Expression ImageStore(Operation operation) {
const auto meta{std::get<MetaImage>(operation.GetMeta())};
code.AddLine("imageStore({}, {}, {});", GetImage(meta.image),
@@ -1816,31 +1778,14 @@ private:
return {};
}
- Expression AtomicImageAdd(Operation operation) {
- return AtomicImage(operation, "imageAtomicAdd");
- }
-
- Expression AtomicImageMin(Operation operation) {
- return AtomicImage(operation, "imageAtomicMin");
- }
-
- Expression AtomicImageMax(Operation operation) {
- return AtomicImage(operation, "imageAtomicMax");
- }
- Expression AtomicImageAnd(Operation operation) {
- return AtomicImage(operation, "imageAtomicAnd");
- }
-
- Expression AtomicImageOr(Operation operation) {
- return AtomicImage(operation, "imageAtomicOr");
- }
-
- Expression AtomicImageXor(Operation operation) {
- return AtomicImage(operation, "imageAtomicXor");
- }
+ template <const std::string_view& opname>
+ Expression AtomicImage(Operation operation) {
+ const auto meta{std::get<MetaImage>(operation.GetMeta())};
+ ASSERT(meta.values.size() == 1);
- Expression AtomicImageExchange(Operation operation) {
- return AtomicImage(operation, "imageAtomicExchange");
+ return {fmt::format("imageAtomic{}({}, {}, {})", opname, GetImage(meta.image),
+ BuildIntegerCoordinates(operation), Visit(meta.values[0]).AsUint()),
+ Type::Uint};
}
Expression Branch(Operation operation) {
@@ -2035,6 +1980,12 @@ private:
Func() = delete;
~Func() = delete;
+ static constexpr std::string_view Add = "Add";
+ static constexpr std::string_view And = "And";
+ static constexpr std::string_view Or = "Or";
+ static constexpr std::string_view Xor = "Xor";
+ static constexpr std::string_view Exchange = "Exchange";
+
static constexpr std::string_view ShuffleIndexed = "shuffleNV";
static constexpr std::string_view ShuffleUp = "shuffleUpNV";
static constexpr std::string_view ShuffleDown = "shuffleDownNV";
@@ -2172,14 +2123,14 @@ private:
&GLSLDecompiler::TextureQueryLod,
&GLSLDecompiler::TexelFetch,
+ &GLSLDecompiler::ImageLoad,
&GLSLDecompiler::ImageStore,
- &GLSLDecompiler::AtomicImageAdd,
- &GLSLDecompiler::AtomicImageMin,
- &GLSLDecompiler::AtomicImageMax,
- &GLSLDecompiler::AtomicImageAnd,
- &GLSLDecompiler::AtomicImageOr,
- &GLSLDecompiler::AtomicImageXor,
- &GLSLDecompiler::AtomicImageExchange,
+
+ &GLSLDecompiler::AtomicImage<Func::Add>,
+ &GLSLDecompiler::AtomicImage<Func::And>,
+ &GLSLDecompiler::AtomicImage<Func::Or>,
+ &GLSLDecompiler::AtomicImage<Func::Xor>,
+ &GLSLDecompiler::AtomicImage<Func::Exchange>,
&GLSLDecompiler::Branch,
&GLSLDecompiler::BranchIndirect,