diff options
| author | 2019-01-05 01:01:38 -0300 | |
|---|---|---|
| committer | 2019-01-30 00:00:15 -0300 | |
| commit | 9f803299de3a9c512939ede48654fab838343a8a (patch) | |
| tree | 4ba30f0ad404bd4120dd5b2e4f21193bf03952fd /src | |
| parent | shader_decode: Implement LDG and basic cbuf tracking (diff) | |
| download | yuzu-9f803299de3a9c512939ede48654fab838343a8a.tar.gz yuzu-9f803299de3a9c512939ede48654fab838343a8a.tar.xz yuzu-9f803299de3a9c512939ede48654fab838343a8a.zip | |
gl_rasterizer: Implement global memory management
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_global_cache.cpp | 70 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_global_cache.h | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 6 |
6 files changed, 140 insertions, 4 deletions
diff --git a/src/video_core/renderer_opengl/gl_global_cache.cpp b/src/video_core/renderer_opengl/gl_global_cache.cpp index 7992b82c4..c7f32feaa 100644 --- a/src/video_core/renderer_opengl/gl_global_cache.cpp +++ b/src/video_core/renderer_opengl/gl_global_cache.cpp | |||
| @@ -4,8 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | #include <glad/glad.h> | 5 | #include <glad/glad.h> |
| 6 | 6 | ||
| 7 | #include "common/assert.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "core/core.h" | ||
| 10 | #include "core/memory.h" | ||
| 7 | #include "video_core/renderer_opengl/gl_global_cache.h" | 11 | #include "video_core/renderer_opengl/gl_global_cache.h" |
| 8 | #include "video_core/renderer_opengl/gl_rasterizer.h" | 12 | #include "video_core/renderer_opengl/gl_rasterizer.h" |
| 13 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | ||
| 9 | #include "video_core/renderer_opengl/utils.h" | 14 | #include "video_core/renderer_opengl/utils.h" |
| 10 | 15 | ||
| 11 | namespace OpenGL { | 16 | namespace OpenGL { |
| @@ -18,7 +23,72 @@ CachedGlobalRegion::CachedGlobalRegion(VAddr addr, u32 size) : addr{addr}, size{ | |||
| 18 | LabelGLObject(GL_BUFFER, buffer.handle, addr, "GlobalMemory"); | 23 | LabelGLObject(GL_BUFFER, buffer.handle, addr, "GlobalMemory"); |
| 19 | } | 24 | } |
| 20 | 25 | ||
| 26 | void CachedGlobalRegion::Reload(u32 size_) { | ||
| 27 | constexpr auto max_size = static_cast<u32>(RasterizerOpenGL::MaxGlobalMemorySize); | ||
| 28 | |||
| 29 | size = size_; | ||
| 30 | if (size > max_size) { | ||
| 31 | size = max_size; | ||
| 32 | LOG_CRITICAL(HW_GPU, "Global region size {} exceeded the expected size {}!", size_, | ||
| 33 | max_size); | ||
| 34 | } | ||
| 35 | |||
| 36 | // TODO(Rodrigo): Get rid of Memory::GetPointer with a staging buffer | ||
| 37 | glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer.handle); | ||
| 38 | glBufferData(GL_SHADER_STORAGE_BUFFER, size, Memory::GetPointer(addr), GL_DYNAMIC_DRAW); | ||
| 39 | } | ||
| 40 | |||
| 41 | GlobalRegion GlobalRegionCacheOpenGL::TryGetReservedGlobalRegion(VAddr addr, u32 size) const { | ||
| 42 | const auto search{reserve.find(addr)}; | ||
| 43 | if (search == reserve.end()) { | ||
| 44 | return {}; | ||
| 45 | } | ||
| 46 | return search->second; | ||
| 47 | } | ||
| 48 | |||
| 49 | GlobalRegion GlobalRegionCacheOpenGL::GetUncachedGlobalRegion(VAddr addr, u32 size) { | ||
| 50 | GlobalRegion region{TryGetReservedGlobalRegion(addr, size)}; | ||
| 51 | if (!region) { | ||
| 52 | // No reserved surface available, create a new one and reserve it | ||
| 53 | region = std::make_shared<CachedGlobalRegion>(addr, size); | ||
| 54 | ReserveGlobalRegion(region); | ||
| 55 | } | ||
| 56 | region->Reload(size); | ||
| 57 | return region; | ||
| 58 | } | ||
| 59 | |||
| 60 | void GlobalRegionCacheOpenGL::ReserveGlobalRegion(const GlobalRegion& region) { | ||
| 61 | reserve[region->GetAddr()] = region; | ||
| 62 | } | ||
| 63 | |||
| 21 | GlobalRegionCacheOpenGL::GlobalRegionCacheOpenGL(RasterizerOpenGL& rasterizer) | 64 | GlobalRegionCacheOpenGL::GlobalRegionCacheOpenGL(RasterizerOpenGL& rasterizer) |
| 22 | : RasterizerCache{rasterizer} {} | 65 | : RasterizerCache{rasterizer} {} |
| 23 | 66 | ||
| 67 | GlobalRegion GlobalRegionCacheOpenGL::GetGlobalRegion( | ||
| 68 | const GLShader::GlobalMemoryEntry& global_region, | ||
| 69 | Tegra::Engines::Maxwell3D::Regs::ShaderStage stage) { | ||
| 70 | |||
| 71 | auto& gpu{Core::System::GetInstance().GPU()}; | ||
| 72 | const auto cbufs = gpu.Maxwell3D().state.shader_stages[static_cast<u64>(stage)]; | ||
| 73 | const auto cbuf_addr = gpu.MemoryManager().GpuToCpuAddress( | ||
| 74 | cbufs.const_buffers[global_region.GetCbufIndex()].address + global_region.GetCbufOffset()); | ||
| 75 | ASSERT(cbuf_addr); | ||
| 76 | |||
| 77 | const auto actual_addr_gpu = Memory::Read64(*cbuf_addr); | ||
| 78 | const auto size = Memory::Read32(*cbuf_addr + 8); | ||
| 79 | const auto actual_addr = gpu.MemoryManager().GpuToCpuAddress(actual_addr_gpu); | ||
| 80 | ASSERT(actual_addr); | ||
| 81 | |||
| 82 | // Look up global region in the cache based on address | ||
| 83 | GlobalRegion region = TryGet(*actual_addr); | ||
| 84 | |||
| 85 | if (!region) { | ||
| 86 | // No global region found - create a new one | ||
| 87 | region = GetUncachedGlobalRegion(*actual_addr, size); | ||
| 88 | Register(region); | ||
| 89 | } | ||
| 90 | |||
| 91 | return region; | ||
| 92 | } | ||
| 93 | |||
| 24 | } // namespace OpenGL | 94 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_global_cache.h b/src/video_core/renderer_opengl/gl_global_cache.h index 406a735bc..37830bb7c 100644 --- a/src/video_core/renderer_opengl/gl_global_cache.h +++ b/src/video_core/renderer_opengl/gl_global_cache.h | |||
| @@ -5,9 +5,13 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <unordered_map> | ||
| 9 | |||
| 8 | #include <glad/glad.h> | 10 | #include <glad/glad.h> |
| 9 | 11 | ||
| 12 | #include "common/assert.h" | ||
| 10 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "video_core/engines/maxwell_3d.h" | ||
| 11 | #include "video_core/rasterizer_cache.h" | 15 | #include "video_core/rasterizer_cache.h" |
| 12 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 16 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 13 | 17 | ||
| @@ -40,6 +44,9 @@ public: | |||
| 40 | return buffer.handle; | 44 | return buffer.handle; |
| 41 | } | 45 | } |
| 42 | 46 | ||
| 47 | /// Reloads the global region from guest memory | ||
| 48 | void Reload(u32 size_); | ||
| 49 | |||
| 43 | // TODO(Rodrigo): When global memory is written (STG), implement flushing | 50 | // TODO(Rodrigo): When global memory is written (STG), implement flushing |
| 44 | void Flush() override { | 51 | void Flush() override { |
| 45 | UNIMPLEMENTED(); | 52 | UNIMPLEMENTED(); |
| @@ -55,6 +62,17 @@ private: | |||
| 55 | class GlobalRegionCacheOpenGL final : public RasterizerCache<GlobalRegion> { | 62 | class GlobalRegionCacheOpenGL final : public RasterizerCache<GlobalRegion> { |
| 56 | public: | 63 | public: |
| 57 | explicit GlobalRegionCacheOpenGL(RasterizerOpenGL& rasterizer); | 64 | explicit GlobalRegionCacheOpenGL(RasterizerOpenGL& rasterizer); |
| 65 | |||
| 66 | /// Gets the current specified shader stage program | ||
| 67 | GlobalRegion GetGlobalRegion(const GLShader::GlobalMemoryEntry& descriptor, | ||
| 68 | Tegra::Engines::Maxwell3D::Regs::ShaderStage stage); | ||
| 69 | |||
| 70 | private: | ||
| 71 | GlobalRegion TryGetReservedGlobalRegion(VAddr addr, u32 size) const; | ||
| 72 | GlobalRegion GetUncachedGlobalRegion(VAddr addr, u32 size); | ||
| 73 | void ReserveGlobalRegion(const GlobalRegion& region); | ||
| 74 | |||
| 75 | std::unordered_map<VAddr, GlobalRegion> reserve; | ||
| 58 | }; | 76 | }; |
| 59 | 77 | ||
| 60 | } // namespace OpenGL | 78 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 71829fee0..ca421ef28 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -300,6 +300,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 300 | // Next available bindpoints to use when uploading the const buffers and textures to the GLSL | 300 | // Next available bindpoints to use when uploading the const buffers and textures to the GLSL |
| 301 | // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. | 301 | // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. |
| 302 | u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; | 302 | u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; |
| 303 | u32 current_gmem_bindpoint = 0; | ||
| 303 | u32 current_texture_bindpoint = 0; | 304 | u32 current_texture_bindpoint = 0; |
| 304 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | 305 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; |
| 305 | 306 | ||
| @@ -358,6 +359,10 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 358 | SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), shader, primitive_mode, | 359 | SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), shader, primitive_mode, |
| 359 | current_constbuffer_bindpoint); | 360 | current_constbuffer_bindpoint); |
| 360 | 361 | ||
| 362 | // Configure global memory regions for this shader stage. | ||
| 363 | current_gmem_bindpoint = SetupGlobalRegions(static_cast<Maxwell::ShaderStage>(stage), | ||
| 364 | shader, primitive_mode, current_gmem_bindpoint); | ||
| 365 | |||
| 361 | // Configure the textures for this shader stage. | 366 | // Configure the textures for this shader stage. |
| 362 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, | 367 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, |
| 363 | primitive_mode, current_texture_bindpoint); | 368 | primitive_mode, current_texture_bindpoint); |
| @@ -993,6 +998,23 @@ u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, Shader& shad | |||
| 993 | return current_bindpoint + static_cast<u32>(entries.size()); | 998 | return current_bindpoint + static_cast<u32>(entries.size()); |
| 994 | } | 999 | } |
| 995 | 1000 | ||
| 1001 | u32 RasterizerOpenGL::SetupGlobalRegions(Maxwell::ShaderStage stage, Shader& shader, | ||
| 1002 | GLenum primitive_mode, u32 current_bindpoint) { | ||
| 1003 | for (const auto& global_region : shader->GetShaderEntries().global_memory_entries) { | ||
| 1004 | const auto& region = | ||
| 1005 | global_cache.GetGlobalRegion(global_region, static_cast<Maxwell::ShaderStage>(stage)); | ||
| 1006 | const GLuint block_index{shader->GetProgramResourceIndex(global_region)}; | ||
| 1007 | ASSERT(block_index != GL_INVALID_INDEX); | ||
| 1008 | |||
| 1009 | glBindBufferBase(GL_SHADER_STORAGE_BUFFER, current_bindpoint, region->GetBufferHandle()); | ||
| 1010 | glShaderStorageBlockBinding(shader->GetProgramHandle(primitive_mode), block_index, | ||
| 1011 | current_bindpoint); | ||
| 1012 | ++current_bindpoint; | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | return current_bindpoint; | ||
| 1016 | } | ||
| 1017 | |||
| 996 | u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, | 1018 | u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, |
| 997 | GLenum primitive_mode, u32 current_unit) { | 1019 | GLenum primitive_mode, u32 current_unit) { |
| 998 | MICROPROFILE_SCOPE(OpenGL_Texture); | 1020 | MICROPROFILE_SCOPE(OpenGL_Texture); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 21c51f874..57ab2f627 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -138,6 +138,16 @@ private: | |||
| 138 | GLenum primitive_mode, u32 current_bindpoint); | 138 | GLenum primitive_mode, u32 current_bindpoint); |
| 139 | 139 | ||
| 140 | /** | 140 | /** |
| 141 | * Configures the current global memory regions to use for the draw command. | ||
| 142 | * @param stage The shader stage to configure buffers for. | ||
| 143 | * @param shader The shader object that contains the specified stage. | ||
| 144 | * @param current_bindpoint The offset at which to start counting new buffer bindpoints. | ||
| 145 | * @returns The next available bindpoint for use in the next shader stage. | ||
| 146 | */ | ||
| 147 | u32 SetupGlobalRegions(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader, | ||
| 148 | GLenum primitive_mode, u32 current_bindpoint); | ||
| 149 | |||
| 150 | /** | ||
| 141 | * Configures the current textures to use for the draw command. | 151 | * Configures the current textures to use for the draw command. |
| 142 | * @param stage The shader stage to configure textures for. | 152 | * @param stage The shader stage to configure textures for. |
| 143 | * @param shader The shader object that contains the specified stage. | 153 | * @param shader The shader object that contains the specified stage. |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index b3aca39af..54ec23f3a 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -108,11 +108,23 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type) | |||
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { | 110 | GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { |
| 111 | const auto search{resource_cache.find(buffer.GetHash())}; | 111 | const auto search{cbuf_resource_cache.find(buffer.GetHash())}; |
| 112 | if (search == resource_cache.end()) { | 112 | if (search == cbuf_resource_cache.end()) { |
| 113 | const GLuint index{ | 113 | const GLuint index{ |
| 114 | glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())}; | 114 | glGetProgramResourceIndex(program.handle, GL_UNIFORM_BLOCK, buffer.GetName().c_str())}; |
| 115 | resource_cache[buffer.GetHash()] = index; | 115 | cbuf_resource_cache[buffer.GetHash()] = index; |
| 116 | return index; | ||
| 117 | } | ||
| 118 | |||
| 119 | return search->second; | ||
| 120 | } | ||
| 121 | |||
| 122 | GLuint CachedShader::GetProgramResourceIndex(const GLShader::GlobalMemoryEntry& global_mem) { | ||
| 123 | const auto search{gmem_resource_cache.find(global_mem.GetHash())}; | ||
| 124 | if (search == gmem_resource_cache.end()) { | ||
| 125 | const GLuint index{glGetProgramResourceIndex(program.handle, GL_SHADER_STORAGE_BLOCK, | ||
| 126 | global_mem.GetName().c_str())}; | ||
| 127 | gmem_resource_cache[global_mem.GetHash()] = index; | ||
| 116 | return index; | 128 | return index; |
| 117 | } | 129 | } |
| 118 | 130 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index e0887dd7b..62b1733b4 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -76,6 +76,9 @@ public: | |||
| 76 | /// Gets the GL program resource location for the specified resource, caching as needed | 76 | /// Gets the GL program resource location for the specified resource, caching as needed |
| 77 | GLuint GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer); | 77 | GLuint GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer); |
| 78 | 78 | ||
| 79 | /// Gets the GL program resource location for the specified resource, caching as needed | ||
| 80 | GLuint GetProgramResourceIndex(const GLShader::GlobalMemoryEntry& global_mem); | ||
| 81 | |||
| 79 | /// Gets the GL uniform location for the specified resource, caching as needed | 82 | /// Gets the GL uniform location for the specified resource, caching as needed |
| 80 | GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); | 83 | GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); |
| 81 | 84 | ||
| @@ -107,7 +110,8 @@ private: | |||
| 107 | OGLProgram triangles_adjacency; | 110 | OGLProgram triangles_adjacency; |
| 108 | } geometry_programs; | 111 | } geometry_programs; |
| 109 | 112 | ||
| 110 | std::map<u32, GLuint> resource_cache; | 113 | std::map<u32, GLuint> cbuf_resource_cache; |
| 114 | std::map<u32, GLuint> gmem_resource_cache; | ||
| 111 | std::map<u32, GLint> uniform_cache; | 115 | std::map<u32, GLint> uniform_cache; |
| 112 | }; | 116 | }; |
| 113 | 117 | ||