diff options
| author | 2019-11-13 00:27:12 -0300 | |
|---|---|---|
| committer | 2019-11-22 21:28:48 -0300 | |
| commit | 0f23359a44d9258efa0c0cd50243cd0efaf80235 (patch) | |
| tree | 811e174383bf2d14e9785c30105bb0ae03649271 /src | |
| parent | gl_shader_cache: Specialize local memory size for compute shaders (diff) | |
| download | yuzu-0f23359a44d9258efa0c0cd50243cd0efaf80235.tar.gz yuzu-0f23359a44d9258efa0c0cd50243cd0efaf80235.tar.xz yuzu-0f23359a44d9258efa0c0cd50243cd0efaf80235.zip | |
gl_rasterizer: Bind graphics images to draw commands
Images were not being bound to draw invocations because these would
require a cache invalidation.
Diffstat (limited to 'src')
4 files changed, 54 insertions, 33 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index d890076f8..9ce20f8f4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -49,8 +49,26 @@ MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(128, 128, 192)); | |||
| 49 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); | 49 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); |
| 50 | MICROPROFILE_DEFINE(OpenGL_PrimitiveAssembly, "OpenGL", "Prim Asmbl", MP_RGB(255, 100, 100)); | 50 | MICROPROFILE_DEFINE(OpenGL_PrimitiveAssembly, "OpenGL", "Prim Asmbl", MP_RGB(255, 100, 100)); |
| 51 | 51 | ||
| 52 | static std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buffer, | 52 | namespace { |
| 53 | const GLShader::ConstBufferEntry& entry) { | 53 | |
| 54 | template <typename Engine, typename Entry> | ||
| 55 | Tegra::Texture::FullTextureInfo GetTextureInfo(const Engine& engine, const Entry& entry, | ||
| 56 | Tegra::Engines::ShaderType shader_type) { | ||
| 57 | if (entry.IsBindless()) { | ||
| 58 | const Tegra::Texture::TextureHandle tex_handle = | ||
| 59 | engine.AccessConstBuffer32(shader_type, entry.GetBuffer(), entry.GetOffset()); | ||
| 60 | return engine.GetTextureInfo(tex_handle); | ||
| 61 | } | ||
| 62 | if constexpr (std::is_same_v<Engine, Tegra::Engines::Maxwell3D>) { | ||
| 63 | const auto stage = static_cast<Maxwell::ShaderStage>(shader_type); | ||
| 64 | return engine.GetStageTexture(stage, entry.GetOffset()); | ||
| 65 | } else { | ||
| 66 | return engine.GetTexture(entry.GetOffset()); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buffer, | ||
| 71 | const GLShader::ConstBufferEntry& entry) { | ||
| 54 | if (!entry.IsIndirect()) { | 72 | if (!entry.IsIndirect()) { |
| 55 | return entry.GetSize(); | 73 | return entry.GetSize(); |
| 56 | } | 74 | } |
| @@ -64,6 +82,8 @@ static std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buf | |||
| 64 | return buffer.size; | 82 | return buffer.size; |
| 65 | } | 83 | } |
| 66 | 84 | ||
| 85 | } // Anonymous namespace | ||
| 86 | |||
| 67 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, | 87 | RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window, |
| 68 | ScreenInfo& info) | 88 | ScreenInfo& info) |
| 69 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, | 89 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, |
| @@ -272,6 +292,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 272 | SetupDrawConstBuffers(stage, shader); | 292 | SetupDrawConstBuffers(stage, shader); |
| 273 | SetupDrawGlobalMemory(stage, shader); | 293 | SetupDrawGlobalMemory(stage, shader); |
| 274 | SetupDrawTextures(stage, shader, base_bindings); | 294 | SetupDrawTextures(stage, shader, base_bindings); |
| 295 | SetupDrawImages(stage, shader, base_bindings); | ||
| 275 | 296 | ||
| 276 | const ProgramVariant variant(base_bindings, primitive_mode); | 297 | const ProgramVariant variant(base_bindings, primitive_mode); |
| 277 | const auto [program_handle, next_bindings] = shader->GetHandle(variant); | 298 | const auto [program_handle, next_bindings] = shader->GetHandle(variant); |
| @@ -921,18 +942,11 @@ void RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stage, const Shade | |||
| 921 | ASSERT_MSG(base_bindings.sampler + entries.size() <= std::size(state.textures), | 942 | ASSERT_MSG(base_bindings.sampler + entries.size() <= std::size(state.textures), |
| 922 | "Exceeded the number of active textures."); | 943 | "Exceeded the number of active textures."); |
| 923 | 944 | ||
| 924 | for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { | 945 | const auto num_entries = static_cast<u32>(entries.size()); |
| 946 | for (u32 bindpoint = 0; bindpoint < num_entries; ++bindpoint) { | ||
| 925 | const auto& entry = entries[bindpoint]; | 947 | const auto& entry = entries[bindpoint]; |
| 926 | const auto texture = [&] { | 948 | const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage); |
| 927 | if (!entry.IsBindless()) { | 949 | const auto texture = GetTextureInfo(maxwell3d, entry, shader_type); |
| 928 | return maxwell3d.GetStageTexture(stage, entry.GetOffset()); | ||
| 929 | } | ||
| 930 | const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage); | ||
| 931 | const Tegra::Texture::TextureHandle tex_handle = | ||
| 932 | maxwell3d.AccessConstBuffer32(shader_type, entry.GetBuffer(), entry.GetOffset()); | ||
| 933 | return maxwell3d.GetTextureInfo(tex_handle); | ||
| 934 | }(); | ||
| 935 | |||
| 936 | SetupTexture(base_bindings.sampler + bindpoint, texture, entry); | 950 | SetupTexture(base_bindings.sampler + bindpoint, texture, entry); |
| 937 | } | 951 | } |
| 938 | } | 952 | } |
| @@ -945,17 +959,10 @@ void RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) { | |||
| 945 | ASSERT_MSG(entries.size() <= std::size(state.textures), | 959 | ASSERT_MSG(entries.size() <= std::size(state.textures), |
| 946 | "Exceeded the number of active textures."); | 960 | "Exceeded the number of active textures."); |
| 947 | 961 | ||
| 948 | for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { | 962 | const auto num_entries = static_cast<u32>(entries.size()); |
| 963 | for (u32 bindpoint = 0; bindpoint < num_entries; ++bindpoint) { | ||
| 949 | const auto& entry = entries[bindpoint]; | 964 | const auto& entry = entries[bindpoint]; |
| 950 | const auto texture = [&] { | 965 | const auto texture = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute); |
| 951 | if (!entry.IsBindless()) { | ||
| 952 | return compute.GetTexture(entry.GetOffset()); | ||
| 953 | } | ||
| 954 | const Tegra::Texture::TextureHandle tex_handle = compute.AccessConstBuffer32( | ||
| 955 | Tegra::Engines::ShaderType::Compute, entry.GetBuffer(), entry.GetOffset()); | ||
| 956 | return compute.GetTextureInfo(tex_handle); | ||
| 957 | }(); | ||
| 958 | |||
| 959 | SetupTexture(bindpoint, texture, entry); | 966 | SetupTexture(bindpoint, texture, entry); |
| 960 | } | 967 | } |
| 961 | } | 968 | } |
| @@ -981,19 +988,28 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu | |||
| 981 | texture.tic.w_source); | 988 | texture.tic.w_source); |
| 982 | } | 989 | } |
| 983 | 990 | ||
| 991 | void RasterizerOpenGL::SetupDrawImages(Maxwell::ShaderStage stage, const Shader& shader, | ||
| 992 | BaseBindings base_bindings) { | ||
| 993 | const auto& maxwell3d = system.GPU().Maxwell3D(); | ||
| 994 | const auto& entries = shader->GetShaderEntries().images; | ||
| 995 | |||
| 996 | const auto num_entries = static_cast<u32>(entries.size()); | ||
| 997 | for (u32 bindpoint = 0; bindpoint < num_entries; ++bindpoint) { | ||
| 998 | const auto& entry = entries[bindpoint]; | ||
| 999 | const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage); | ||
| 1000 | const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic; | ||
| 1001 | SetupImage(base_bindings.image + bindpoint, tic, entry); | ||
| 1002 | } | ||
| 1003 | } | ||
| 1004 | |||
| 984 | void RasterizerOpenGL::SetupComputeImages(const Shader& shader) { | 1005 | void RasterizerOpenGL::SetupComputeImages(const Shader& shader) { |
| 985 | const auto& compute = system.GPU().KeplerCompute(); | 1006 | const auto& compute = system.GPU().KeplerCompute(); |
| 986 | const auto& entries = shader->GetShaderEntries().images; | 1007 | const auto& entries = shader->GetShaderEntries().images; |
| 987 | for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) { | 1008 | |
| 1009 | const auto num_entries = static_cast<u32>(entries.size()); | ||
| 1010 | for (u32 bindpoint = 0; bindpoint < num_entries; ++bindpoint) { | ||
| 988 | const auto& entry = entries[bindpoint]; | 1011 | const auto& entry = entries[bindpoint]; |
| 989 | const auto tic = [&] { | 1012 | const auto tic = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute).tic; |
| 990 | if (!entry.IsBindless()) { | ||
| 991 | return compute.GetTexture(entry.GetOffset()).tic; | ||
| 992 | } | ||
| 993 | const Tegra::Texture::TextureHandle tex_handle = compute.AccessConstBuffer32( | ||
| 994 | Tegra::Engines::ShaderType::Compute, entry.GetBuffer(), entry.GetOffset()); | ||
| 995 | return compute.GetTextureInfo(tex_handle).tic; | ||
| 996 | }(); | ||
| 997 | SetupImage(bindpoint, tic, entry); | 1013 | SetupImage(bindpoint, tic, entry); |
| 998 | } | 1014 | } |
| 999 | } | 1015 | } |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 0e0819d59..267ed7803 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -118,6 +118,10 @@ private: | |||
| 118 | void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture, | 118 | void SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture, |
| 119 | const GLShader::SamplerEntry& entry); | 119 | const GLShader::SamplerEntry& entry); |
| 120 | 120 | ||
| 121 | /// Configures images in a graphics shader. | ||
| 122 | void SetupDrawImages(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader, | ||
| 123 | BaseBindings base_bindings); | ||
| 124 | |||
| 121 | /// Configures images in a compute shader. | 125 | /// Configures images in a compute shader. |
| 122 | void SetupComputeImages(const Shader& shader); | 126 | void SetupComputeImages(const Shader& shader); |
| 123 | 127 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index b23a982d7..e7c92e45d 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -449,6 +449,7 @@ std::tuple<GLuint, BaseBindings> CachedShader::GetHandle(const ProgramVariant& v | |||
| 449 | base_bindings.cbuf += STAGE_RESERVED_UBOS; | 449 | base_bindings.cbuf += STAGE_RESERVED_UBOS; |
| 450 | base_bindings.gmem += static_cast<u32>(entries.global_memory_entries.size()); | 450 | base_bindings.gmem += static_cast<u32>(entries.global_memory_entries.size()); |
| 451 | base_bindings.sampler += static_cast<u32>(entries.samplers.size()); | 451 | base_bindings.sampler += static_cast<u32>(entries.samplers.size()); |
| 452 | base_bindings.image += static_cast<u32>(entries.images.size()); | ||
| 452 | 453 | ||
| 453 | return {program->handle, base_bindings}; | 454 | return {program->handle, base_bindings}; |
| 454 | } | 455 | } |
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 5ebcbbbba..ccf530367 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | |||
| @@ -52,7 +52,7 @@ struct BindlessSamplerKey { | |||
| 52 | Tegra::Engines::SamplerDescriptor sampler{}; | 52 | Tegra::Engines::SamplerDescriptor sampler{}; |
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | constexpr u32 NativeVersion = 9; | 55 | constexpr u32 NativeVersion = 10; |
| 56 | 56 | ||
| 57 | // Making sure sizes doesn't change by accident | 57 | // Making sure sizes doesn't change by accident |
| 58 | static_assert(sizeof(BaseBindings) == 16); | 58 | static_assert(sizeof(BaseBindings) == 16); |