summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-01-05 01:01:38 -0300
committerGravatar ReinUsesLisp2019-01-30 00:00:15 -0300
commit9f803299de3a9c512939ede48654fab838343a8a (patch)
tree4ba30f0ad404bd4120dd5b2e4f21193bf03952fd /src
parentshader_decode: Implement LDG and basic cbuf tracking (diff)
downloadyuzu-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.cpp70
-rw-r--r--src/video_core/renderer_opengl/gl_global_cache.h18
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp22
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h6
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
11namespace OpenGL { 16namespace 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
26void 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
41GlobalRegion 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
49GlobalRegion 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
60void GlobalRegionCacheOpenGL::ReserveGlobalRegion(const GlobalRegion& region) {
61 reserve[region->GetAddr()] = region;
62}
63
21GlobalRegionCacheOpenGL::GlobalRegionCacheOpenGL(RasterizerOpenGL& rasterizer) 64GlobalRegionCacheOpenGL::GlobalRegionCacheOpenGL(RasterizerOpenGL& rasterizer)
22 : RasterizerCache{rasterizer} {} 65 : RasterizerCache{rasterizer} {}
23 66
67GlobalRegion 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:
55class GlobalRegionCacheOpenGL final : public RasterizerCache<GlobalRegion> { 62class GlobalRegionCacheOpenGL final : public RasterizerCache<GlobalRegion> {
56public: 63public:
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
70private:
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
1001u32 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
996u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, 1018u32 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
110GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { 110GLuint 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
122GLuint 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