summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.h9
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp96
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h8
3 files changed, 60 insertions, 53 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 92bfda053..f59d01738 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -127,6 +127,7 @@ public:
127 BitField<21, 6, Size> size; 127 BitField<21, 6, Size> size;
128 BitField<27, 3, Type> type; 128 BitField<27, 3, Type> type;
129 BitField<31, 1, u32> bgra; 129 BitField<31, 1, u32> bgra;
130 u32 hex;
130 }; 131 };
131 132
132 u32 ComponentCount() const { 133 u32 ComponentCount() const {
@@ -262,6 +263,10 @@ public:
262 bool IsValid() const { 263 bool IsValid() const {
263 return size != Size::Invalid; 264 return size != Size::Invalid;
264 } 265 }
266
267 bool operator<(const VertexAttribute& other) const {
268 return hex < other.hex;
269 }
265 }; 270 };
266 271
267 enum class PrimitiveTopology : u32 { 272 enum class PrimitiveTopology : u32 {
@@ -545,7 +550,7 @@ public:
545 550
546 INSERT_PADDING_WORDS(0x5B); 551 INSERT_PADDING_WORDS(0x5B);
547 552
548 VertexAttribute vertex_attrib_format[NumVertexAttributes]; 553 std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
549 554
550 INSERT_PADDING_WORDS(0xF); 555 INSERT_PADDING_WORDS(0xF);
551 556
@@ -964,7 +969,7 @@ ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5);
964ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); 969ASSERT_REG_POSITION(stencil_back_mask, 0x3D6);
965ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); 970ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7);
966ASSERT_REG_POSITION(zeta, 0x3F8); 971ASSERT_REG_POSITION(zeta, 0x3F8);
967ASSERT_REG_POSITION(vertex_attrib_format[0], 0x458); 972ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
968ASSERT_REG_POSITION(rt_control, 0x487); 973ASSERT_REG_POSITION(rt_control, 0x487);
969ASSERT_REG_POSITION(zeta_width, 0x48a); 974ASSERT_REG_POSITION(zeta_width, 0x48a);
970ASSERT_REG_POSITION(zeta_height, 0x48b); 975ASSERT_REG_POSITION(zeta_height, 0x48b);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index c66a18155..5d493a2b2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -70,28 +70,13 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo
70 // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0 70 // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
71 state.clip_distance[0] = true; 71 state.clip_distance[0] = true;
72 72
73 // Generate VAO and UBO
74 sw_vao.Create();
75 uniform_buffer.Create();
76
77 state.draw.vertex_array = sw_vao.handle;
78 state.draw.uniform_buffer = uniform_buffer.handle;
79 state.Apply();
80
81 // Create render framebuffer 73 // Create render framebuffer
82 framebuffer.Create(); 74 framebuffer.Create();
83 75
84 hw_vao.Create();
85
86 state.draw.vertex_buffer = buffer_cache.GetHandle();
87
88 shader_program_manager = std::make_unique<GLShader::ProgramManager>(); 76 shader_program_manager = std::make_unique<GLShader::ProgramManager>();
89 state.draw.shader_program = 0; 77 state.draw.shader_program = 0;
90 state.draw.vertex_array = hw_vao.handle;
91 state.Apply(); 78 state.Apply();
92 79
93 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_cache.GetHandle());
94
95 glEnable(GL_BLEND); 80 glEnable(GL_BLEND);
96 81
97 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment); 82 glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment);
@@ -106,7 +91,54 @@ void RasterizerOpenGL::SetupVertexArrays() {
106 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); 91 const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
107 const auto& regs = gpu.regs; 92 const auto& regs = gpu.regs;
108 93
109 state.draw.vertex_array = hw_vao.handle; 94 auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
95 auto& VAO = iter->second;
96
97 if (is_cache_miss) {
98 VAO.Create();
99 state.draw.vertex_array = VAO.handle;
100 state.Apply();
101
102 // The index buffer binding is stored within the VAO. Stupid OpenGL, but easy to work
103 // around.
104 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_cache.GetHandle());
105
106 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
107 // Enables the first 16 vertex attributes always, as we don't know which ones are actually
108 // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16
109 // for now to avoid OpenGL errors.
110 // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
111 // assume every shader uses them all.
112 for (unsigned index = 0; index < 16; ++index) {
113 const auto& attrib = regs.vertex_attrib_format[index];
114
115 // Ignore invalid attributes.
116 if (!attrib.IsValid())
117 continue;
118
119 const auto& buffer = regs.vertex_array[attrib.buffer];
120 LOG_TRACE(HW_GPU,
121 "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
122 index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
123 attrib.offset.Value(), attrib.IsNormalized());
124
125 ASSERT(buffer.IsEnabled());
126
127 glEnableVertexAttribArray(index);
128 if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
129 attrib.type ==
130 Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
131 glVertexAttribIFormat(index, attrib.ComponentCount(),
132 MaxwellToGL::VertexType(attrib), attrib.offset);
133 } else {
134 glVertexAttribFormat(index, attrib.ComponentCount(),
135 MaxwellToGL::VertexType(attrib),
136 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
137 }
138 glVertexAttribBinding(index, attrib.buffer);
139 }
140 }
141 state.draw.vertex_array = VAO.handle;
110 state.draw.vertex_buffer = buffer_cache.GetHandle(); 142 state.draw.vertex_buffer = buffer_cache.GetHandle();
111 state.Apply(); 143 state.Apply();
112 144
@@ -142,38 +174,6 @@ void RasterizerOpenGL::SetupVertexArrays() {
142 glVertexBindingDivisor(index, 0); 174 glVertexBindingDivisor(index, 0);
143 } 175 }
144 } 176 }
145
146 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
147 // Enables the first 16 vertex attributes always, as we don't know which ones are actually used
148 // until shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now
149 // to avoid OpenGL errors.
150 // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
151 // assume every shader uses them all.
152 for (unsigned index = 0; index < 16; ++index) {
153 auto& attrib = regs.vertex_attrib_format[index];
154
155 // Ignore invalid attributes.
156 if (!attrib.IsValid())
157 continue;
158
159 auto& buffer = regs.vertex_array[attrib.buffer];
160 LOG_TRACE(HW_GPU, "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}",
161 index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(),
162 attrib.offset.Value(), attrib.IsNormalized());
163
164 ASSERT(buffer.IsEnabled());
165
166 glEnableVertexAttribArray(index);
167 if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
168 attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
169 glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
170 attrib.offset);
171 } else {
172 glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
173 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
174 }
175 glVertexAttribBinding(index, attrib.buffer);
176 }
177} 177}
178 178
179void RasterizerOpenGL::SetupShaders() { 179void RasterizerOpenGL::SetupShaders() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 4c4b084b8..9c30dc0e8 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -6,6 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <map>
9#include <memory> 10#include <memory>
10#include <tuple> 11#include <tuple>
11#include <utility> 12#include <utility>
@@ -168,14 +169,15 @@ private:
168 ScreenInfo& screen_info; 169 ScreenInfo& screen_info;
169 170
170 std::unique_ptr<GLShader::ProgramManager> shader_program_manager; 171 std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
171 OGLVertexArray sw_vao; 172 std::map<std::array<Tegra::Engines::Maxwell3D::Regs::VertexAttribute,
172 OGLVertexArray hw_vao; 173 Tegra::Engines::Maxwell3D::Regs::NumVertexAttributes>,
174 OGLVertexArray>
175 vertex_array_cache;
173 176
174 std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers; 177 std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers;
175 178
176 static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 179 static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
177 OGLBufferCache buffer_cache; 180 OGLBufferCache buffer_cache;
178 OGLBuffer uniform_buffer;
179 OGLFramebuffer framebuffer; 181 OGLFramebuffer framebuffer;
180 GLint uniform_buffer_alignment; 182 GLint uniform_buffer_alignment;
181 183