diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/video_core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 90 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 57 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 105 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 19 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 2 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 16 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 10 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.h | 8 |
9 files changed, 206 insertions, 102 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index aa5bc3bbe..1982b76c4 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -22,6 +22,7 @@ add_library(video_core STATIC rasterizer_interface.h renderer_base.cpp renderer_base.h + renderer_opengl/gl_buffer_cache.cpp renderer_opengl/gl_rasterizer.cpp renderer_opengl/gl_rasterizer.h renderer_opengl/gl_rasterizer_cache.cpp diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp new file mode 100644 index 000000000..c85fbd306 --- /dev/null +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp @@ -0,0 +1,90 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/alignment.h" +#include "common/assert.h" +#include "core/core.h" +#include "core/memory.h" +#include "video_core/renderer_opengl/gl_buffer_cache.h" + +namespace OpenGL { + +OGLBufferCache::OGLBufferCache(size_t size) : stream_buffer(GL_ARRAY_BUFFER, size) {} + +GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, size_t size, size_t alignment, + bool cache) { + auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); + const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; + + // Cache management is a big overhead, so only cache entries with a given size. + // TODO: Figure out which size is the best for given games. + cache &= size >= 2048; + + if (cache) { + auto entry = TryGet(*cpu_addr); + if (entry) { + if (entry->size >= size && entry->alignment == alignment) { + return entry->offset; + } + Unregister(entry); + } + } + + AlignBuffer(alignment); + GLintptr uploaded_offset = buffer_offset; + + Memory::ReadBlock(*cpu_addr, buffer_ptr, size); + + buffer_ptr += size; + buffer_offset += size; + + if (cache) { + auto entry = std::make_shared<CachedBufferEntry>(); + entry->offset = uploaded_offset; + entry->size = size; + entry->alignment = alignment; + entry->addr = *cpu_addr; + Register(entry); + } + + return uploaded_offset; +} + +GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, size_t size, size_t alignment) { + AlignBuffer(alignment); + std::memcpy(buffer_ptr, raw_pointer, size); + GLintptr uploaded_offset = buffer_offset; + + buffer_ptr += size; + buffer_offset += size; + return uploaded_offset; +} + +void OGLBufferCache::Map(size_t max_size) { + bool invalidate; + std::tie(buffer_ptr, buffer_offset_base, invalidate) = + stream_buffer.Map(static_cast<GLsizeiptr>(max_size), 4); + buffer_offset = buffer_offset_base; + + if (invalidate) { + InvalidateAll(); + } +} +void OGLBufferCache::Unmap() { + stream_buffer.Unmap(buffer_offset - buffer_offset_base); +} + +GLuint OGLBufferCache::GetHandle() { + return stream_buffer.GetHandle(); +} + +void OGLBufferCache::AlignBuffer(size_t alignment) { + // Align the offset, not the mapped pointer + GLintptr offset_aligned = + static_cast<GLintptr>(Common::AlignUp(static_cast<size_t>(buffer_offset), alignment)); + buffer_ptr += offset_aligned - buffer_offset; + buffer_offset = offset_aligned; +} + +} // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h new file mode 100644 index 000000000..9c7ad27e6 --- /dev/null +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h @@ -0,0 +1,57 @@ +// Copyright 2018 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <memory> +#include <unordered_map> + +#include "common/common_types.h" +#include "video_core/rasterizer_cache.h" +#include "video_core/renderer_opengl/gl_resource_manager.h" +#include "video_core/renderer_opengl/gl_stream_buffer.h" + +namespace OpenGL { + +struct CachedBufferEntry final { + VAddr GetAddr() const { + return addr; + } + + size_t GetSizeInBytes() const { + return size; + } + + VAddr addr; + size_t size; + GLintptr offset; + size_t alignment; +}; + +class OGLBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> { +public: + OGLBufferCache(size_t size); + + GLintptr UploadMemory(Tegra::GPUVAddr gpu_addr, size_t size, size_t alignment = 4, + bool cache = true); + + GLintptr UploadHostMemory(const void* raw_pointer, size_t size, size_t alignment = 4); + + void Map(size_t max_size); + void Unmap(); + + GLuint GetHandle(); + +protected: + void AlignBuffer(size_t alignment); + +private: + OGLStreamBuffer stream_buffer; + + u8* buffer_ptr; + GLintptr buffer_offset; + GLintptr buffer_offset_base; +}; + +} // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e260c9140..c66a18155 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -43,7 +43,7 @@ MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo& info) - : emu_window{window}, screen_info{info}, stream_buffer(GL_ARRAY_BUFFER, STREAM_BUFFER_SIZE) { + : emu_window{window}, screen_info{info}, buffer_cache(STREAM_BUFFER_SIZE) { // Create sampler objects for (size_t i = 0; i < texture_samplers.size(); ++i) { texture_samplers[i].Create(); @@ -83,14 +83,14 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo hw_vao.Create(); - state.draw.vertex_buffer = stream_buffer.GetHandle(); + state.draw.vertex_buffer = buffer_cache.GetHandle(); shader_program_manager = std::make_unique<GLShader::ProgramManager>(); state.draw.shader_program = 0; state.draw.vertex_array = hw_vao.handle; state.Apply(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer.GetHandle()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_cache.GetHandle()); glEnable(GL_BLEND); @@ -101,14 +101,13 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo RasterizerOpenGL::~RasterizerOpenGL() {} -std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, - GLintptr buffer_offset) { +void RasterizerOpenGL::SetupVertexArrays() { MICROPROFILE_SCOPE(OpenGL_VAO); const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); const auto& regs = gpu.regs; state.draw.vertex_array = hw_vao.handle; - state.draw.vertex_buffer = stream_buffer.GetHandle(); + state.draw.vertex_buffer = buffer_cache.GetHandle(); state.Apply(); // Upload all guest vertex arrays sequentially to our buffer @@ -127,12 +126,10 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, ASSERT(end > start); u64 size = end - start + 1; - GLintptr vertex_buffer_offset; - std::tie(array_ptr, buffer_offset, vertex_buffer_offset) = - UploadMemory(array_ptr, buffer_offset, start, size); + GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size); // Bind the vertex array to the buffer at the current offset. - glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, + glBindVertexBuffer(index, buffer_cache.GetHandle(), vertex_buffer_offset, vertex_array.stride); if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { @@ -177,11 +174,9 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, } glVertexAttribBinding(index, attrib.buffer); } - - return {array_ptr, buffer_offset}; } -std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { +void RasterizerOpenGL::SetupShaders() { MICROPROFILE_SCOPE(OpenGL_Shader); auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); @@ -199,21 +194,15 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr continue; } - std::tie(buffer_ptr, buffer_offset) = - AlignBuffer(buffer_ptr, buffer_offset, static_cast<size_t>(uniform_buffer_alignment)); - const size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 GLShader::MaxwellUniformData ubo{}; ubo.SetFromRegs(gpu.state.shader_stages[stage]); - std::memcpy(buffer_ptr, &ubo, sizeof(ubo)); + GLintptr offset = buffer_cache.UploadHostMemory( + &ubo, sizeof(ubo), static_cast<size_t>(uniform_buffer_alignment)); // Bind the buffer - glBindBufferRange(GL_UNIFORM_BUFFER, stage, stream_buffer.GetHandle(), buffer_offset, - sizeof(ubo)); - - buffer_ptr += sizeof(ubo); - buffer_offset += sizeof(ubo); + glBindBufferRange(GL_UNIFORM_BUFFER, stage, buffer_cache.GetHandle(), offset, sizeof(ubo)); Shader shader{shader_cache.GetStageProgram(program)}; @@ -234,9 +223,8 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr } // Configure the const buffers for this shader stage. - std::tie(buffer_ptr, buffer_offset, current_constbuffer_bindpoint) = - SetupConstBuffers(buffer_ptr, buffer_offset, static_cast<Maxwell::ShaderStage>(stage), - shader, current_constbuffer_bindpoint); + current_constbuffer_bindpoint = SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), + shader, current_constbuffer_bindpoint); // Configure the textures for this shader stage. current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, @@ -250,8 +238,6 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr } shader_program_manager->UseTrivialGeometryShader(); - - return {buffer_ptr, buffer_offset}; } size_t RasterizerOpenGL::CalculateVertexArraysSize() const { @@ -439,31 +425,6 @@ void RasterizerOpenGL::Clear() { glClear(clear_mask); } -std::pair<u8*, GLintptr> RasterizerOpenGL::AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, - size_t alignment) { - // Align the offset, not the mapped pointer - GLintptr offset_aligned = - static_cast<GLintptr>(Common::AlignUp(static_cast<size_t>(buffer_offset), alignment)); - return {buffer_ptr + (offset_aligned - buffer_offset), offset_aligned}; -} - -std::tuple<u8*, GLintptr, GLintptr> RasterizerOpenGL::UploadMemory(u8* buffer_ptr, - GLintptr buffer_offset, - Tegra::GPUVAddr gpu_addr, - size_t size, size_t alignment) { - std::tie(buffer_ptr, buffer_offset) = AlignBuffer(buffer_ptr, buffer_offset, alignment); - GLintptr uploaded_offset = buffer_offset; - - auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); - const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; - Memory::ReadBlock(*cpu_addr, buffer_ptr, size); - - buffer_ptr += size; - buffer_offset += size; - - return {buffer_ptr, buffer_offset, uploaded_offset}; -} - void RasterizerOpenGL::DrawArrays() { if (accelerate_draw == AccelDraw::Disabled) return; @@ -489,7 +450,7 @@ void RasterizerOpenGL::DrawArrays() { const bool is_indexed = accelerate_draw == AccelDraw::Indexed; const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; - state.draw.vertex_buffer = stream_buffer.GetHandle(); + state.draw.vertex_buffer = buffer_cache.GetHandle(); state.Apply(); size_t buffer_size = CalculateVertexArraysSize(); @@ -506,25 +467,21 @@ void RasterizerOpenGL::DrawArrays() { // Add space for at least 18 constant buffers buffer_size += Maxwell::MaxConstBuffers * (MaxConstbufferSize + uniform_buffer_alignment); - u8* buffer_ptr; - GLintptr buffer_offset; - std::tie(buffer_ptr, buffer_offset, std::ignore) = - stream_buffer.Map(static_cast<GLsizeiptr>(buffer_size), 4); - u8* buffer_ptr_base = buffer_ptr; + buffer_cache.Map(buffer_size); - std::tie(buffer_ptr, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset); + SetupVertexArrays(); // If indexed mode, copy the index buffer GLintptr index_buffer_offset = 0; if (is_indexed) { MICROPROFILE_SCOPE(OpenGL_Index); - std::tie(buffer_ptr, buffer_offset, index_buffer_offset) = UploadMemory( - buffer_ptr, buffer_offset, regs.index_array.StartAddress(), index_buffer_size); + index_buffer_offset = + buffer_cache.UploadMemory(regs.index_array.StartAddress(), index_buffer_size); } - std::tie(buffer_ptr, buffer_offset) = SetupShaders(buffer_ptr, buffer_offset); + SetupShaders(); - stream_buffer.Unmap(buffer_ptr - buffer_ptr_base); + buffer_cache.Unmap(); shader_program_manager->ApplyTo(state); state.Apply(); @@ -569,6 +526,7 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { MICROPROFILE_SCOPE(OpenGL_CacheManagement); res_cache.InvalidateRegion(addr, size); shader_cache.InvalidateRegion(addr, size); + buffer_cache.InvalidateRegion(addr, size); } void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { @@ -658,11 +616,8 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr } } -std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_ptr, - GLintptr buffer_offset, - Maxwell::ShaderStage stage, - Shader& shader, - u32 current_bindpoint) { +u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, Shader& shader, + u32 current_bindpoint) { MICROPROFILE_SCOPE(OpenGL_UBO); const auto& gpu = Core::System::GetInstance().GPU(); const auto& maxwell3d = gpu.Maxwell3D(); @@ -699,23 +654,21 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_pt size = Common::AlignUp(size, sizeof(GLvec4)); ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big"); - GLintptr const_buffer_offset; - std::tie(buffer_ptr, buffer_offset, const_buffer_offset) = - UploadMemory(buffer_ptr, buffer_offset, buffer.address, size, - static_cast<size_t>(uniform_buffer_alignment)); + GLintptr const_buffer_offset = buffer_cache.UploadMemory( + buffer.address, size, static_cast<size_t>(uniform_buffer_alignment)); glBindBufferRange(GL_UNIFORM_BUFFER, current_bindpoint + bindpoint, - stream_buffer.GetHandle(), const_buffer_offset, size); + buffer_cache.GetHandle(), const_buffer_offset, size); // 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); } state.Apply(); - return {buffer_ptr, buffer_offset, current_bindpoint + static_cast<u32>(entries.size())}; + return current_bindpoint + static_cast<u32>(entries.size()); } u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, u32 current_unit) { @@ -733,7 +686,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_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 30045ebff..4c4b084b8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -18,7 +18,9 @@ #include "common/common_types.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/memory_manager.h" +#include "video_core/rasterizer_cache.h" #include "video_core/rasterizer_interface.h" +#include "video_core/renderer_opengl/gl_buffer_cache.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_shader_cache.h" @@ -109,9 +111,8 @@ private: * @param current_bindpoint The offset at which to start counting new buffer bindpoints. * @returns The next available bindpoint for use in the next shader stage. */ - std::tuple<u8*, GLintptr, u32> SetupConstBuffers( - u8* buffer_ptr, GLintptr buffer_offset, Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, - Shader& shader, u32 current_bindpoint); + u32 SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader, + u32 current_bindpoint); /* * Configures the current textures to use for the draw command. @@ -173,22 +174,16 @@ private: std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers; static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; - OGLStreamBuffer stream_buffer; + OGLBufferCache buffer_cache; OGLBuffer uniform_buffer; OGLFramebuffer framebuffer; GLint uniform_buffer_alignment; size_t CalculateVertexArraysSize() const; - std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); + void SetupVertexArrays(); - std::pair<u8*, GLintptr> SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); - - std::pair<u8*, GLintptr> AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, size_t alignment); - - std::tuple<u8*, GLintptr, GLintptr> UploadMemory(u8* buffer_ptr, GLintptr buffer_offset, - Tegra::GPUVAddr gpu_addr, size_t size, - size_t alignment = 4); + void SetupShaders(); enum class AccelDraw { Disabled, Arrays, Indexed }; AccelDraw accelerate_draw = AccelDraw::Disabled; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 1965ab7d5..f6b2c5a86 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -690,7 +690,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(bool usin const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; // TODO(bunnei): This is hard corded to use just the first render buffer - LOG_WARNING(Render_OpenGL, "hard-coded for render target 0!"); + LOG_TRACE(Render_OpenGL, "hard-coded for render target 0!"); // get color and depth surfaces SurfaceParams color_params{}; diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index ac9adfd83..7e4b85ac3 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 759987604..6e6febcbc 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 c788099d4..cbb2090ea 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)]; } |