gl_shader_decompiler: Implement image binding settings
This commit is contained in:
		| @@ -190,6 +190,10 @@ CachedProgram SpecializeShader(const std::string& code, const GLShader::ShaderEn | ||||
|         source += fmt::format("#define SAMPLER_BINDING_{} {}\n", sampler.GetIndex(), | ||||
|                               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. | ||||
|     for (std::size_t i = 0; i < texture_buffer_usage.size(); ++i) { | ||||
|   | ||||
| @@ -235,6 +235,9 @@ public: | ||||
|         for (const auto& sampler : ir.GetSamplers()) { | ||||
|             entries.samplers.emplace_back(sampler); | ||||
|         } | ||||
|         for (const auto& image : ir.GetImages()) { | ||||
|             entries.images.emplace_back(image); | ||||
|         } | ||||
|         for (const auto& gmem_pair : ir.GetGlobalMemory()) { | ||||
|             const auto& [base, usage] = gmem_pair; | ||||
|             entries.global_memory_entries.emplace_back(base.cbuf_index, base.cbuf_offset, | ||||
|   | ||||
| @@ -27,6 +27,7 @@ struct ShaderEntries; | ||||
| using Maxwell = Tegra::Engines::Maxwell3D::Regs; | ||||
| using ProgramResult = std::pair<std::string, ShaderEntries>; | ||||
| using SamplerEntry = VideoCommon::Shader::Sampler; | ||||
| using ImageEntry = VideoCommon::Shader::Image; | ||||
|  | ||||
| class ConstBufferEntry : public VideoCommon::Shader::ConstBuffer { | ||||
| public: | ||||
| @@ -74,6 +75,7 @@ struct ShaderEntries { | ||||
|     std::vector<ConstBufferEntry> const_buffers; | ||||
|     std::vector<SamplerEntry> samplers; | ||||
|     std::vector<SamplerEntry> bindless_samplers; | ||||
|     std::vector<ImageEntry> images; | ||||
|     std::vector<GlobalMemoryEntry> global_memory_entries; | ||||
|     std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | ||||
|     std::size_t shader_length{}; | ||||
|   | ||||
| @@ -34,11 +34,11 @@ enum class PrecompiledEntryKind : u32 { | ||||
|     Dump, | ||||
| }; | ||||
|  | ||||
| constexpr u32 NativeVersion = 2; | ||||
| constexpr u32 NativeVersion = 3; | ||||
|  | ||||
| // 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 { | ||||
|  | ||||
| @@ -285,8 +285,7 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn | ||||
|     if (!LoadObjectFromPrecompiled(code_size)) { | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     std::string code(code_size, '\0'); | ||||
|     std::vector<u8> code(code_size); | ||||
|     if (!LoadArrayFromPrecompiled(code.data(), code.size())) { | ||||
|         return {}; | ||||
|     } | ||||
| @@ -298,7 +297,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn | ||||
|     if (!LoadObjectFromPrecompiled(const_buffers_count)) { | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     for (u32 i = 0; i < const_buffers_count; ++i) { | ||||
|         u32 max_offset{}; | ||||
|         u32 index{}; | ||||
| @@ -314,7 +312,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn | ||||
|     if (!LoadObjectFromPrecompiled(samplers_count)) { | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     for (u32 i = 0; i < samplers_count; ++i) { | ||||
|         u64 offset{}; | ||||
|         u64 index{}; | ||||
| @@ -332,11 +329,28 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn | ||||
|             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{}; | ||||
|     if (!LoadObjectFromPrecompiled(global_memory_count)) { | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     for (u32 i = 0; i < global_memory_count; ++i) { | ||||
|         u32 cbuf_index{}; | ||||
|         u32 cbuf_offset{}; | ||||
| @@ -360,7 +374,6 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn | ||||
|     if (!LoadObjectFromPrecompiled(shader_length)) { | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     entry.entries.shader_length = static_cast<std::size_t>(shader_length); | ||||
|  | ||||
|     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()))) { | ||||
|         return false; | ||||
|     } | ||||
|   | ||||
| @@ -45,9 +45,11 @@ struct BaseBindings { | ||||
|     u32 cbuf{}; | ||||
|     u32 gmem{}; | ||||
|     u32 sampler{}; | ||||
|     u32 image{}; | ||||
|  | ||||
|     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 { | ||||
| @@ -91,8 +93,11 @@ namespace std { | ||||
|  | ||||
| template <> | ||||
| 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); | ||||
|     } | ||||
|  | ||||
|     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; | ||||
|  | ||||
|     // Stores whole precompiled cache which will be read from or saved to the precompiled chache | ||||
|     // file | ||||
|     FileSys::VectorVfsFile precompiled_cache_virtual_file; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ReinUsesLisp
					ReinUsesLisp