From 99a71580c4356c51bcb5f18b10be55f1e62a65e5 Mon Sep 17 00:00:00 2001
From: Markus Wick <markus@selfnet.de>
Date: Tue, 4 Sep 2018 20:55:34 +0200
Subject: [PATCH] gl_shader_cache: Use an u32 for the binding point cache.

The std::string generation with its malloc and free requirement
was a noticeable overhead. Also switch to an ordered_map to
avoid the std::hash call. As those maps usually have a size of
two elements, the lookup time shall not matter.
---
 src/video_core/renderer_opengl/gl_rasterizer.cpp |  4 ++--
 .../renderer_opengl/gl_shader_cache.cpp          | 16 ++++++++--------
 src/video_core/renderer_opengl/gl_shader_cache.h | 10 +++++-----
 src/video_core/renderer_opengl/gl_shader_gen.h   |  8 ++++++++
 4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index e260c91400..7ee3f2ae71 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -709,7 +709,7 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_pt
 
         // Now configure the bindpoint of the buffer inside the shader
         glUniformBlockBinding(shader->GetProgramHandle(),
-                              shader->GetProgramResourceIndex(used_buffer.GetName()),
+                              shader->GetProgramResourceIndex(used_buffer),
                               current_bindpoint + bindpoint);
     }
 
@@ -733,7 +733,7 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
 
         // Bind the uniform to the sampler.
 
-        glProgramUniform1i(shader->GetProgramHandle(), shader->GetUniformLocation(entry.GetName()),
+        glProgramUniform1i(shader->GetProgramHandle(), shader->GetUniformLocation(entry),
                            current_bindpoint);
 
         const auto texture = maxwell3d.GetStageTexture(entry.GetStage(), entry.GetOffset());
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index ac9adfd837..7e4b85ac33 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -85,23 +85,23 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type)
     SetShaderUniformBlockBindings(program.handle);
 }
 
-GLuint CachedShader::GetProgramResourceIndex(const std::string& name) {
-    auto search{resource_cache.find(name)};
+GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) {
+    auto search{resource_cache.find(buffer.GetHash())};
     if (search == resource_cache.end()) {
         const GLuint index{
-            glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, name.c_str())};
-        resource_cache[name] = index;
+            glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())};
+        resource_cache[buffer.GetHash()] = index;
         return index;
     }
 
     return search->second;
 }
 
-GLint CachedShader::GetUniformLocation(const std::string& name) {
-    auto search{uniform_cache.find(name)};
+GLint CachedShader::GetUniformLocation(const GLShader::SamplerEntry& sampler) {
+    auto search{uniform_cache.find(sampler.GetHash())};
     if (search == uniform_cache.end()) {
-        const GLint index{glGetUniformLocation(program.handle, name.c_str())};
-        uniform_cache[name] = index;
+        const GLint index{glGetUniformLocation(program.handle, sampler.GetName().c_str())};
+        uniform_cache[sampler.GetHash()] = index;
         return index;
     }
 
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 7599876041..6e6febcbcc 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -4,8 +4,8 @@
 
 #pragma once
 
+#include <map>
 #include <memory>
-#include <unordered_map>
 
 #include "common/common_types.h"
 #include "video_core/rasterizer_cache.h"
@@ -43,10 +43,10 @@ public:
     }
 
     /// Gets the GL program resource location for the specified resource, caching as needed
-    GLuint GetProgramResourceIndex(const std::string& name);
+    GLuint GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer);
 
     /// Gets the GL uniform location for the specified resource, caching as needed
-    GLint GetUniformLocation(const std::string& name);
+    GLint GetUniformLocation(const GLShader::SamplerEntry& sampler);
 
 private:
     VAddr addr;
@@ -55,8 +55,8 @@ private:
     GLShader::ShaderEntries entries;
     OGLProgram program;
 
-    std::unordered_map<std::string, GLuint> resource_cache;
-    std::unordered_map<std::string, GLint> uniform_cache;
+    std::map<u32, GLuint> resource_cache;
+    std::map<u32, GLint> uniform_cache;
 };
 
 class ShaderCacheOpenGL final : public RasterizerCache<Shader> {
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h
index c788099d4e..cbb2090ea2 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.h
+++ b/src/video_core/renderer_opengl/gl_shader_gen.h
@@ -53,6 +53,10 @@ public:
         return BufferBaseNames[static_cast<size_t>(stage)] + std::to_string(index);
     }
 
+    u32 GetHash() const {
+        return (static_cast<u32>(stage) << 16) | index;
+    }
+
 private:
     static constexpr std::array<const char*, Maxwell::MaxShaderStage> BufferBaseNames = {
         "buffer_vs_c", "buffer_tessc_c", "buffer_tesse_c", "buffer_gs_c", "buffer_fs_c",
@@ -89,6 +93,10 @@ public:
                std::to_string(sampler_index) + ']';
     }
 
+    u32 GetHash() const {
+        return (static_cast<u32>(stage) << 16) | static_cast<u32>(sampler_index);
+    }
+
     static std::string GetArrayName(Maxwell::ShaderStage stage) {
         return TextureSamplerNames[static_cast<size_t>(stage)];
     }