summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-04-27 07:37:15 +0200
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-06-21 02:38:33 +0200
commit1bf4154e7d0589dab6922321bf39cf80f22c07d0 (patch)
treefd7a2fa46e99d3126f66bdd1a8b6aa232a65d800 /src
parentshader: Implement bindless images (diff)
downloadyuzu-1bf4154e7d0589dab6922321bf39cf80f22c07d0.tar
yuzu-1bf4154e7d0589dab6922321bf39cf80f22c07d0.tar.gz
yuzu-1bf4154e7d0589dab6922321bf39cf80f22c07d0.tar.bz2
yuzu-1bf4154e7d0589dab6922321bf39cf80f22c07d0.tar.lz
yuzu-1bf4154e7d0589dab6922321bf39cf80f22c07d0.tar.xz
yuzu-1bf4154e7d0589dab6922321bf39cf80f22c07d0.tar.zst
yuzu-1bf4154e7d0589dab6922321bf39cf80f22c07d0.zip
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp43
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.h24
5 files changed, 52 insertions, 24 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index e859a900c..67789db73 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/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(),
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) {
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 2ae2f1db2..ca04d8618 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -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,
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h
index c1569e737..14d11c7fc 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.h
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h
@@ -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{};
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
index d338ece8e..51d9aae94 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -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;
}
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
index 7c9f0cc75..aa12ffc71 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
@@ -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;