Przeglądaj źródła

gl_shader_decompiler: Implement image binding settings

ReinUsesLisp 7 lat temu
rodzic
commit
1bf4154e7d

+ 4 - 0
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -190,6 +190,10 @@ CachedProgram SpecializeShader(const std::string& code, const GLShader::ShaderEn
         source += fmt::format("#define SAMPLER_BINDING_{} {}\n", sampler.GetIndex(),
         source += fmt::format("#define SAMPLER_BINDING_{} {}\n", sampler.GetIndex(),
                               base_bindings.sampler++);
                               base_bindings.sampler++);
     }
     }
+    for (const auto& image : entries.images) {
+        source +=
+            fmt::format("#define IMAGE_BINDING_{} {}\n", image.GetIndex(), base_bindings.image++);
+    }
 
 
     // Transform 1D textures to texture samplers by declaring its preprocessor macros.
     // Transform 1D textures to texture samplers by declaring its preprocessor macros.
     for (std::size_t i = 0; i < texture_buffer_usage.size(); ++i) {
     for (std::size_t i = 0; i < texture_buffer_usage.size(); ++i) {

+ 3 - 0
src/video_core/renderer_opengl/gl_shader_decompiler.cpp

@@ -235,6 +235,9 @@ public:
         for (const auto& sampler : ir.GetSamplers()) {
         for (const auto& sampler : ir.GetSamplers()) {
             entries.samplers.emplace_back(sampler);
             entries.samplers.emplace_back(sampler);
         }
         }
+        for (const auto& image : ir.GetImages()) {
+            entries.images.emplace_back(image);
+        }
         for (const auto& gmem_pair : ir.GetGlobalMemory()) {
         for (const auto& gmem_pair : ir.GetGlobalMemory()) {
             const auto& [base, usage] = gmem_pair;
             const auto& [base, usage] = gmem_pair;
             entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset,
             entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset,

+ 2 - 0
src/video_core/renderer_opengl/gl_shader_decompiler.h

@@ -27,6 +27,7 @@ struct ShaderEntries;
 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
 using Maxwell = Tegra::Engines::Maxwell3D::Regs;
 using ProgramResult = std::pair<std::string, ShaderEntries>;
 using ProgramResult = std::pair<std::string, ShaderEntries>;
 using SamplerEntry = VideoCommon::Shader::Sampler;
 using SamplerEntry = VideoCommon::Shader::Sampler;
+using ImageEntry = VideoCommon::Shader::Image;
 
 
 class ConstBufferEntry : public VideoCommon::Shader::ConstBuffer {
 class ConstBufferEntry : public VideoCommon::Shader::ConstBuffer {
 public:
 public:
@@ -74,6 +75,7 @@ struct ShaderEntries {
     std::vector<ConstBufferEntry> const_buffers;
     std::vector<ConstBufferEntry> const_buffers;
     std::vector<SamplerEntry> samplers;
     std::vector<SamplerEntry> samplers;
     std::vector<SamplerEntry> bindless_samplers;
     std::vector<SamplerEntry> bindless_samplers;
+    std::vector<ImageEntry> images;
     std::vector<GlobalMemoryEntry> global_memory_entries;
     std::vector<GlobalMemoryEntry> global_memory_entries;
     std::array<bool, Maxwell::NumClipDistances> clip_distances{};
     std::array<bool, Maxwell::NumClipDistances> clip_distances{};
     std::size_t shader_length{};
     std::size_t shader_length{};

+ 34 - 9
src/video_core/renderer_opengl/gl_shader_disk_cache.cpp

@@ -34,11 +34,11 @@ enum class PrecompiledEntryKind : u32 {
     Dump,
     Dump,
 };
 };
 
 
-constexpr u32 NativeVersion = 2;
+constexpr u32 NativeVersion = 3;
 
 
 // Making sure sizes doesn't change by accident
 // Making sure sizes doesn't change by accident
-static_assert(sizeof(BaseBindings) == 12);
-static_assert(sizeof(ShaderDiskCacheUsage) == 32);
+static_assert(sizeof(BaseBindings) == 16);
+static_assert(sizeof(ShaderDiskCacheUsage) == 40);
 
 
 namespace {
 namespace {
 
 
@@ -285,8 +285,7 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
     if (!LoadObjectFromPrecompiled(code_size)) {
     if (!LoadObjectFromPrecompiled(code_size)) {
         return {};
         return {};
     }
     }
-
-    std::string code(code_size, '\0');
+    std::vector<u8> code(code_size);
     if (!LoadArrayFromPrecompiled(code.data(), code.size())) {
     if (!LoadArrayFromPrecompiled(code.data(), code.size())) {
         return {};
         return {};
     }
     }
@@ -298,7 +297,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
     if (!LoadObjectFromPrecompiled(const_buffers_count)) {
     if (!LoadObjectFromPrecompiled(const_buffers_count)) {
         return {};
         return {};
     }
     }
-
     for (u32 i = 0; i < const_buffers_count; ++i) {
     for (u32 i = 0; i < const_buffers_count; ++i) {
         u32 max_offset{};
         u32 max_offset{};
         u32 index{};
         u32 index{};
@@ -314,7 +312,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
     if (!LoadObjectFromPrecompiled(samplers_count)) {
     if (!LoadObjectFromPrecompiled(samplers_count)) {
         return {};
         return {};
     }
     }
-
     for (u32 i = 0; i < samplers_count; ++i) {
     for (u32 i = 0; i < samplers_count; ++i) {
         u64 offset{};
         u64 offset{};
         u64 index{};
         u64 index{};
@@ -332,11 +329,28 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
             static_cast<Tegra::Shader::TextureType>(type), is_array, is_shadow, is_bindless);
             static_cast<Tegra::Shader::TextureType>(type), is_array, is_shadow, is_bindless);
     }
     }
 
 
+    u32 images_count{};
+    if (!LoadObjectFromPrecompiled(images_count)) {
+        return {};
+    }
+    for (u32 i = 0; i < images_count; ++i) {
+        u64 offset{};
+        u64 index{};
+        u32 type{};
+        u8 is_bindless{};
+        if (!LoadObjectFromPrecompiled(offset) || !LoadObjectFromPrecompiled(index) ||
+            !LoadObjectFromPrecompiled(type) || !LoadObjectFromPrecompiled(is_bindless)) {
+            return {};
+        }
+        entry.entries.images.emplace_back(
+            static_cast<std::size_t>(offset), static_cast<std::size_t>(index),
+            static_cast<Tegra::Shader::ImageType>(type), is_bindless != 0);
+    }
+
     u32 global_memory_count{};
     u32 global_memory_count{};
     if (!LoadObjectFromPrecompiled(global_memory_count)) {
     if (!LoadObjectFromPrecompiled(global_memory_count)) {
         return {};
         return {};
     }
     }
-
     for (u32 i = 0; i < global_memory_count; ++i) {
     for (u32 i = 0; i < global_memory_count; ++i) {
         u32 cbuf_index{};
         u32 cbuf_index{};
         u32 cbuf_offset{};
         u32 cbuf_offset{};
@@ -360,7 +374,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
     if (!LoadObjectFromPrecompiled(shader_length)) {
     if (!LoadObjectFromPrecompiled(shader_length)) {
         return {};
         return {};
     }
     }
-
     entry.entries.shader_length = static_cast<std::size_t>(shader_length);
     entry.entries.shader_length = static_cast<std::size_t>(shader_length);
 
 
     return entry;
     return entry;
@@ -400,6 +413,18 @@ bool ShaderDiskCacheOpenGL::SaveDecompiledFile(u64 unique_identifier, const std:
         }
         }
     }
     }
 
 
+    if (!SaveObjectToPrecompiled(static_cast<u32>(entries.images.size()))) {
+        return false;
+    }
+    for (const auto& image : entries.images) {
+        if (!SaveObjectToPrecompiled(static_cast<u64>(image.GetOffset())) ||
+            !SaveObjectToPrecompiled(static_cast<u64>(image.GetIndex())) ||
+            !SaveObjectToPrecompiled(static_cast<u32>(image.GetType())) ||
+            !SaveObjectToPrecompiled(static_cast<u8>(image.IsBindless() ? 1 : 0))) {
+            return false;
+        }
+    }
+
     if (!SaveObjectToPrecompiled(static_cast<u32>(entries.global_memory_entries.size()))) {
     if (!SaveObjectToPrecompiled(static_cast<u32>(entries.global_memory_entries.size()))) {
         return false;
         return false;
     }
     }

+ 9 - 15
src/video_core/renderer_opengl/gl_shader_disk_cache.h

@@ -45,9 +45,11 @@ struct BaseBindings {
     u32 cbuf{};
     u32 cbuf{};
     u32 gmem{};
     u32 gmem{};
     u32 sampler{};
     u32 sampler{};
+    u32 image{};
 
 
     bool operator==(const BaseBindings& rhs) const {
     bool operator==(const BaseBindings& rhs) const {
-        return std::tie(cbuf, gmem, sampler) == std::tie(rhs.cbuf, rhs.gmem, rhs.sampler);
+        return std::tie(cbuf, gmem, sampler, image) ==
+               std::tie(rhs.cbuf, rhs.gmem, rhs.sampler, rhs.image);
     }
     }
 
 
     bool operator!=(const BaseBindings& rhs) const {
     bool operator!=(const BaseBindings& rhs) const {
@@ -91,8 +93,11 @@ namespace std {
 
 
 template <>
 template <>
 struct hash<OpenGL::BaseBindings> {
 struct hash<OpenGL::BaseBindings> {
-    std::size_t operator()(const OpenGL::BaseBindings& bindings) const noexcept {
-        return bindings.cbuf | bindings.gmem << 8 | bindings.sampler << 16;
+    std::size_t operator()(const OpenGL::BaseBindings& bindings) const {
+        return static_cast<std::size_t>(bindings.cbuf) ^
+               (static_cast<std::size_t>(bindings.gmem) << 8) ^
+               (static_cast<std::size_t>(bindings.sampler) << 16) ^
+               (static_cast<std::size_t>(bindings.image) << 24);
     }
     }
 };
 };
 
 
@@ -300,19 +305,8 @@ private:
         return LoadArrayFromPrecompiled(&object, 1);
         return LoadArrayFromPrecompiled(&object, 1);
     }
     }
 
 
-    bool LoadObjectFromPrecompiled(bool& object) {
-        u8 value;
-        const bool read_ok = LoadArrayFromPrecompiled(&value, 1);
-        if (!read_ok) {
-            return false;
-        }
-
-        object = value != 0;
-        return true;
-    }
-
-    // Core system
     Core::System& system;
     Core::System& system;
+
     // Stores whole precompiled cache which will be read from or saved to the precompiled chache
     // Stores whole precompiled cache which will be read from or saved to the precompiled chache
     // file
     // file
     FileSys::VectorVfsFile precompiled_cache_virtual_file;
     FileSys::VectorVfsFile precompiled_cache_virtual_file;