diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 100 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 12 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.h | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/utils.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/utils.h | 3 |
10 files changed, 53 insertions, 153 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index acdae849c..9658d379c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -107,7 +107,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind | |||
| 107 | state.draw.shader_program = 0; | 107 | state.draw.shader_program = 0; |
| 108 | state.Apply(); | 108 | state.Apply(); |
| 109 | 109 | ||
| 110 | LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here"); | ||
| 111 | CheckExtensions(); | 110 | CheckExtensions(); |
| 112 | } | 111 | } |
| 113 | 112 | ||
| @@ -121,66 +120,41 @@ void RasterizerOpenGL::CheckExtensions() { | |||
| 121 | } | 120 | } |
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | GLuint RasterizerOpenGL::SetupVertexFormat() { | 123 | void RasterizerOpenGL::SetupVertexFormat() { |
| 125 | auto& gpu = system.GPU().Maxwell3D(); | 124 | auto& gpu = system.GPU().Maxwell3D(); |
| 126 | const auto& regs = gpu.regs; | 125 | const auto& regs = gpu.regs; |
| 127 | 126 | ||
| 128 | MICROPROFILE_SCOPE(OpenGL_VAO); | 127 | MICROPROFILE_SCOPE(OpenGL_VAO); |
| 129 | 128 | ||
| 130 | auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); | 129 | // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. Enables |
| 131 | auto& vao_entry = iter->second; | 130 | // the first 16 vertex attributes always, as we don't know which ones are actually used until |
| 132 | 131 | // shader time. Note, Tegra technically supports 32, but we're capping this to 16 for now to | |
| 133 | if (is_cache_miss) { | 132 | // avoid OpenGL errors. |
| 134 | vao_entry.Create(); | 133 | // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't |
| 135 | const GLuint vao = vao_entry.handle; | 134 | // assume every shader uses them all. |
| 136 | 135 | for (u32 index = 0; index < 16; ++index) { | |
| 137 | // Eventhough we are using DSA to create this vertex array, there is a bug on Intel's blob | 136 | const auto& attrib = regs.vertex_attrib_format[index]; |
| 138 | // that fails to properly create the vertex array if it's not bound even after creating it | 137 | |
| 139 | // with glCreateVertexArrays | 138 | // Ignore invalid attributes. |
| 140 | state.draw.vertex_array = vao; | 139 | if (!attrib.IsValid()) { |
| 141 | state.ApplyVertexArrayState(); | 140 | glDisableVertexAttribArray(index); |
| 142 | 141 | continue; | |
| 143 | // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. | ||
| 144 | // Enables the first 16 vertex attributes always, as we don't know which ones are actually | ||
| 145 | // used until shader time. Note, Tegra technically supports 32, but we're capping this to 16 | ||
| 146 | // for now to avoid OpenGL errors. | ||
| 147 | // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't | ||
| 148 | // assume every shader uses them all. | ||
| 149 | for (u32 index = 0; index < 16; ++index) { | ||
| 150 | const auto& attrib = regs.vertex_attrib_format[index]; | ||
| 151 | |||
| 152 | // Ignore invalid attributes. | ||
| 153 | if (!attrib.IsValid()) | ||
| 154 | continue; | ||
| 155 | |||
| 156 | const auto& buffer = regs.vertex_array[attrib.buffer]; | ||
| 157 | LOG_TRACE(Render_OpenGL, | ||
| 158 | "vertex attrib {}, count={}, size={}, type={}, offset={}, normalize={}", | ||
| 159 | index, attrib.ComponentCount(), attrib.SizeString(), attrib.TypeString(), | ||
| 160 | attrib.offset.Value(), attrib.IsNormalized()); | ||
| 161 | |||
| 162 | ASSERT(buffer.IsEnabled()); | ||
| 163 | |||
| 164 | glEnableVertexArrayAttrib(vao, index); | ||
| 165 | if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt || | ||
| 166 | attrib.type == | ||
| 167 | Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) { | ||
| 168 | glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(), | ||
| 169 | MaxwellToGL::VertexType(attrib), attrib.offset); | ||
| 170 | } else { | ||
| 171 | glVertexArrayAttribFormat( | ||
| 172 | vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 173 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); | ||
| 174 | } | ||
| 175 | glVertexArrayAttribBinding(vao, index, attrib.buffer); | ||
| 176 | } | 142 | } |
| 177 | } | 143 | glEnableVertexAttribArray(index); |
| 178 | 144 | ||
| 179 | state.draw.vertex_array = vao_entry.handle; | 145 | if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt || |
| 180 | return vao_entry.handle; | 146 | attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) { |
| 147 | glVertexAttribIFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 148 | attrib.offset); | ||
| 149 | } else { | ||
| 150 | glVertexAttribFormat(index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib), | ||
| 151 | attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); | ||
| 152 | } | ||
| 153 | glVertexAttribBinding(index, attrib.buffer); | ||
| 154 | } | ||
| 181 | } | 155 | } |
| 182 | 156 | ||
| 183 | void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { | 157 | void RasterizerOpenGL::SetupVertexBuffer() { |
| 184 | auto& gpu = system.GPU().Maxwell3D(); | 158 | auto& gpu = system.GPU().Maxwell3D(); |
| 185 | const auto& regs = gpu.regs; | 159 | const auto& regs = gpu.regs; |
| 186 | 160 | ||
| @@ -189,8 +163,9 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { | |||
| 189 | // Upload all guest vertex arrays sequentially to our buffer | 163 | // Upload all guest vertex arrays sequentially to our buffer |
| 190 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { | 164 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 191 | const auto& vertex_array = regs.vertex_array[index]; | 165 | const auto& vertex_array = regs.vertex_array[index]; |
| 192 | if (!vertex_array.IsEnabled()) | 166 | if (!vertex_array.IsEnabled()) { |
| 193 | continue; | 167 | continue; |
| 168 | } | ||
| 194 | 169 | ||
| 195 | const GPUVAddr start = vertex_array.StartAddress(); | 170 | const GPUVAddr start = vertex_array.StartAddress(); |
| 196 | const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); | 171 | const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); |
| @@ -205,15 +180,15 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { | |||
| 205 | 180 | ||
| 206 | if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { | 181 | if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { |
| 207 | // Enable vertex buffer instancing with the specified divisor. | 182 | // Enable vertex buffer instancing with the specified divisor. |
| 208 | glVertexArrayBindingDivisor(vao, index, vertex_array.divisor); | 183 | glVertexBindingDivisor(index, vertex_array.divisor); |
| 209 | } else { | 184 | } else { |
| 210 | // Disable the vertex buffer instancing. | 185 | // Disable the vertex buffer instancing. |
| 211 | glVertexArrayBindingDivisor(vao, index, 0); | 186 | glVertexBindingDivisor(index, 0); |
| 212 | } | 187 | } |
| 213 | } | 188 | } |
| 214 | } | 189 | } |
| 215 | 190 | ||
| 216 | void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { | 191 | void RasterizerOpenGL::SetupVertexInstances() { |
| 217 | auto& gpu = system.GPU().Maxwell3D(); | 192 | auto& gpu = system.GPU().Maxwell3D(); |
| 218 | const auto& regs = gpu.regs; | 193 | const auto& regs = gpu.regs; |
| 219 | 194 | ||
| @@ -222,10 +197,10 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { | |||
| 222 | if (regs.instanced_arrays.IsInstancingEnabled(index) && | 197 | if (regs.instanced_arrays.IsInstancingEnabled(index) && |
| 223 | regs.vertex_array[index].divisor != 0) { | 198 | regs.vertex_array[index].divisor != 0) { |
| 224 | // Enable vertex buffer instancing with the specified divisor. | 199 | // Enable vertex buffer instancing with the specified divisor. |
| 225 | glVertexArrayBindingDivisor(vao, index, regs.vertex_array[index].divisor); | 200 | glVertexBindingDivisor(index, regs.vertex_array[index].divisor); |
| 226 | } else { | 201 | } else { |
| 227 | // Disable the vertex buffer instancing. | 202 | // Disable the vertex buffer instancing. |
| 228 | glVertexArrayBindingDivisor(vao, index, 0); | 203 | glVertexBindingDivisor(index, 0); |
| 229 | } | 204 | } |
| 230 | } | 205 | } |
| 231 | } | 206 | } |
| @@ -559,13 +534,12 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 559 | buffer_cache.Map(buffer_size); | 534 | buffer_cache.Map(buffer_size); |
| 560 | 535 | ||
| 561 | // Prepare vertex array format. | 536 | // Prepare vertex array format. |
| 562 | const GLuint vao = SetupVertexFormat(); | 537 | SetupVertexFormat(); |
| 563 | vertex_array_pushbuffer.Setup(vao); | 538 | vertex_array_pushbuffer.Setup(); |
| 564 | 539 | ||
| 565 | // Upload vertex and index data. | 540 | // Upload vertex and index data. |
| 566 | SetupVertexBuffer(vao); | 541 | SetupVertexBuffer(); |
| 567 | SetupVertexInstances(vao); | 542 | SetupVertexInstances(); |
| 568 | |||
| 569 | GLintptr index_buffer_offset; | 543 | GLintptr index_buffer_offset; |
| 570 | if (is_indexed) { | 544 | if (is_indexed) { |
| 571 | index_buffer_offset = SetupIndexBuffer(); | 545 | index_buffer_offset = SetupIndexBuffer(); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 8afc3c205..b97f9f518 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -194,11 +194,11 @@ private: | |||
| 194 | 194 | ||
| 195 | std::size_t CalculateIndexBufferSize() const; | 195 | std::size_t CalculateIndexBufferSize() const; |
| 196 | 196 | ||
| 197 | /// Updates and returns a vertex array object representing current vertex format | 197 | /// Updates the current vertex format |
| 198 | GLuint SetupVertexFormat(); | 198 | void SetupVertexFormat(); |
| 199 | 199 | ||
| 200 | void SetupVertexBuffer(GLuint vao); | 200 | void SetupVertexBuffer(); |
| 201 | void SetupVertexInstances(GLuint vao); | 201 | void SetupVertexInstances(); |
| 202 | 202 | ||
| 203 | GLintptr SetupIndexBuffer(); | 203 | GLintptr SetupIndexBuffer(); |
| 204 | 204 | ||
| @@ -217,10 +217,6 @@ private: | |||
| 217 | ScreenInfo& screen_info; | 217 | ScreenInfo& screen_info; |
| 218 | 218 | ||
| 219 | std::unique_ptr<GLShader::ProgramManager> shader_program_manager; | 219 | std::unique_ptr<GLShader::ProgramManager> shader_program_manager; |
| 220 | std::map<std::array<Tegra::Engines::Maxwell3D::Regs::VertexAttribute, | ||
| 221 | Tegra::Engines::Maxwell3D::Regs::NumVertexAttributes>, | ||
| 222 | OGLVertexArray> | ||
| 223 | vertex_array_cache; | ||
| 224 | 220 | ||
| 225 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; | 221 | static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; |
| 226 | OGLBufferCache buffer_cache; | 222 | OGLBufferCache buffer_cache; |
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp index c0aee770f..00355c1da 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.cpp +++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp | |||
| @@ -189,24 +189,6 @@ void OGLSync::Release() { | |||
| 189 | handle = 0; | 189 | handle = 0; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | void OGLVertexArray::Create() { | ||
| 193 | if (handle != 0) | ||
| 194 | return; | ||
| 195 | |||
| 196 | MICROPROFILE_SCOPE(OpenGL_ResourceCreation); | ||
| 197 | glCreateVertexArrays(1, &handle); | ||
| 198 | } | ||
| 199 | |||
| 200 | void OGLVertexArray::Release() { | ||
| 201 | if (handle == 0) | ||
| 202 | return; | ||
| 203 | |||
| 204 | MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); | ||
| 205 | glDeleteVertexArrays(1, &handle); | ||
| 206 | OpenGLState::GetCurState().ResetVertexArray(handle).Apply(); | ||
| 207 | handle = 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | void OGLFramebuffer::Create() { | 192 | void OGLFramebuffer::Create() { |
| 211 | if (handle != 0) | 193 | if (handle != 0) |
| 212 | return; | 194 | return; |
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 995a4e45e..de93f4212 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h | |||
| @@ -241,31 +241,6 @@ public: | |||
| 241 | GLsync handle = 0; | 241 | GLsync handle = 0; |
| 242 | }; | 242 | }; |
| 243 | 243 | ||
| 244 | class OGLVertexArray : private NonCopyable { | ||
| 245 | public: | ||
| 246 | OGLVertexArray() = default; | ||
| 247 | |||
| 248 | OGLVertexArray(OGLVertexArray&& o) noexcept : handle(std::exchange(o.handle, 0)) {} | ||
| 249 | |||
| 250 | ~OGLVertexArray() { | ||
| 251 | Release(); | ||
| 252 | } | ||
| 253 | |||
| 254 | OGLVertexArray& operator=(OGLVertexArray&& o) noexcept { | ||
| 255 | Release(); | ||
| 256 | handle = std::exchange(o.handle, 0); | ||
| 257 | return *this; | ||
| 258 | } | ||
| 259 | |||
| 260 | /// Creates a new internal OpenGL resource and stores the handle | ||
| 261 | void Create(); | ||
| 262 | |||
| 263 | /// Deletes the internal OpenGL resource | ||
| 264 | void Release(); | ||
| 265 | |||
| 266 | GLuint handle = 0; | ||
| 267 | }; | ||
| 268 | |||
| 269 | class OGLFramebuffer : private NonCopyable { | 244 | class OGLFramebuffer : private NonCopyable { |
| 270 | public: | 245 | public: |
| 271 | OGLFramebuffer() = default; | 246 | OGLFramebuffer() = default; |
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 6b5eea342..1c39e7fba 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -98,12 +98,6 @@ void OpenGLState::ApplyFramebufferState() { | |||
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | void OpenGLState::ApplyVertexArrayState() { | ||
| 102 | if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) { | ||
| 103 | glBindVertexArray(draw.vertex_array); | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | void OpenGLState::ApplyShaderProgram() { | 101 | void OpenGLState::ApplyShaderProgram() { |
| 108 | if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { | 102 | if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { |
| 109 | glUseProgram(draw.shader_program); | 103 | glUseProgram(draw.shader_program); |
| @@ -338,7 +332,6 @@ void OpenGLState::ApplyImages() { | |||
| 338 | void OpenGLState::Apply() { | 332 | void OpenGLState::Apply() { |
| 339 | MICROPROFILE_SCOPE(OpenGL_State); | 333 | MICROPROFILE_SCOPE(OpenGL_State); |
| 340 | ApplyFramebufferState(); | 334 | ApplyFramebufferState(); |
| 341 | ApplyVertexArrayState(); | ||
| 342 | ApplyShaderProgram(); | 335 | ApplyShaderProgram(); |
| 343 | ApplyProgramPipeline(); | 336 | ApplyProgramPipeline(); |
| 344 | ApplyClipDistances(); | 337 | ApplyClipDistances(); |
| @@ -411,13 +404,6 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) { | |||
| 411 | return *this; | 404 | return *this; |
| 412 | } | 405 | } |
| 413 | 406 | ||
| 414 | OpenGLState& OpenGLState::ResetVertexArray(GLuint handle) { | ||
| 415 | if (draw.vertex_array == handle) { | ||
| 416 | draw.vertex_array = 0; | ||
| 417 | } | ||
| 418 | return *this; | ||
| 419 | } | ||
| 420 | |||
| 421 | OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) { | 407 | OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) { |
| 422 | if (draw.read_framebuffer == handle) { | 408 | if (draw.read_framebuffer == handle) { |
| 423 | draw.read_framebuffer = 0; | 409 | draw.read_framebuffer = 0; |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 366753714..f7c722b36 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -74,7 +74,6 @@ public: | |||
| 74 | struct { | 74 | struct { |
| 75 | GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING | 75 | GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING |
| 76 | GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING | 76 | GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING |
| 77 | GLuint vertex_array = 0; // GL_VERTEX_ARRAY_BINDING | ||
| 78 | GLuint shader_program = 0; // GL_CURRENT_PROGRAM | 77 | GLuint shader_program = 0; // GL_CURRENT_PROGRAM |
| 79 | GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING | 78 | GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING |
| 80 | } draw; | 79 | } draw; |
| @@ -117,7 +116,6 @@ public: | |||
| 117 | void Apply(); | 116 | void Apply(); |
| 118 | 117 | ||
| 119 | void ApplyFramebufferState(); | 118 | void ApplyFramebufferState(); |
| 120 | void ApplyVertexArrayState(); | ||
| 121 | void ApplyShaderProgram(); | 119 | void ApplyShaderProgram(); |
| 122 | void ApplyProgramPipeline(); | 120 | void ApplyProgramPipeline(); |
| 123 | void ApplyClipDistances(); | 121 | void ApplyClipDistances(); |
| @@ -142,7 +140,6 @@ public: | |||
| 142 | OpenGLState& ResetSampler(GLuint handle); | 140 | OpenGLState& ResetSampler(GLuint handle); |
| 143 | OpenGLState& ResetProgram(GLuint handle); | 141 | OpenGLState& ResetProgram(GLuint handle); |
| 144 | OpenGLState& ResetPipeline(GLuint handle); | 142 | OpenGLState& ResetPipeline(GLuint handle); |
| 145 | OpenGLState& ResetVertexArray(GLuint handle); | ||
| 146 | OpenGLState& ResetFramebuffer(GLuint handle); | 143 | OpenGLState& ResetFramebuffer(GLuint handle); |
| 147 | OpenGLState& ResetRenderbuffer(GLuint handle); | 144 | OpenGLState& ResetRenderbuffer(GLuint handle); |
| 148 | 145 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 9cd67e05e..2fb5938e2 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -441,22 +441,8 @@ void RendererOpenGL::InitOpenGLObjects() { | |||
| 441 | // Generate VBO handle for drawing | 441 | // Generate VBO handle for drawing |
| 442 | vertex_buffer.Create(); | 442 | vertex_buffer.Create(); |
| 443 | 443 | ||
| 444 | // Generate VAO | ||
| 445 | vertex_array.Create(); | ||
| 446 | state.draw.vertex_array = vertex_array.handle; | ||
| 447 | |||
| 448 | // Attach vertex data to VAO | 444 | // Attach vertex data to VAO |
| 449 | glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); | 445 | glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); |
| 450 | glVertexArrayAttribFormat(vertex_array.handle, PositionLocation, 2, GL_FLOAT, GL_FALSE, | ||
| 451 | offsetof(ScreenRectVertex, position)); | ||
| 452 | glVertexArrayAttribFormat(vertex_array.handle, TexCoordLocation, 2, GL_FLOAT, GL_FALSE, | ||
| 453 | offsetof(ScreenRectVertex, tex_coord)); | ||
| 454 | glVertexArrayAttribBinding(vertex_array.handle, PositionLocation, 0); | ||
| 455 | glVertexArrayAttribBinding(vertex_array.handle, TexCoordLocation, 0); | ||
| 456 | glEnableVertexArrayAttrib(vertex_array.handle, PositionLocation); | ||
| 457 | glEnableVertexArrayAttrib(vertex_array.handle, TexCoordLocation); | ||
| 458 | glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0, | ||
| 459 | sizeof(ScreenRectVertex)); | ||
| 460 | 446 | ||
| 461 | // Allocate textures for the screen | 447 | // Allocate textures for the screen |
| 462 | screen_info.texture.resource.Create(GL_TEXTURE_2D); | 448 | screen_info.texture.resource.Create(GL_TEXTURE_2D); |
| @@ -581,6 +567,14 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 581 | glCullFace(GL_BACK); | 567 | glCullFace(GL_BACK); |
| 582 | glFrontFace(GL_CW); | 568 | glFrontFace(GL_CW); |
| 583 | 569 | ||
| 570 | glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE, | ||
| 571 | offsetof(ScreenRectVertex, position)); | ||
| 572 | glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE, | ||
| 573 | offsetof(ScreenRectVertex, tex_coord)); | ||
| 574 | glVertexAttribBinding(PositionLocation, 0); | ||
| 575 | glVertexAttribBinding(TexCoordLocation, 0); | ||
| 576 | glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex)); | ||
| 577 | |||
| 584 | glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); | 578 | glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); |
| 585 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 579 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 586 | // Restore default state | 580 | // Restore default state |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index d45e69cbc..978a4d0eb 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h | |||
| @@ -96,7 +96,6 @@ private: | |||
| 96 | OpenGLState state; | 96 | OpenGLState state; |
| 97 | 97 | ||
| 98 | // OpenGL object IDs | 98 | // OpenGL object IDs |
| 99 | OGLVertexArray vertex_array; | ||
| 100 | OGLBuffer vertex_buffer; | 99 | OGLBuffer vertex_buffer; |
| 101 | OGLProgram shader; | 100 | OGLProgram shader; |
| 102 | OGLFramebuffer screenshot_framebuffer; | 101 | OGLFramebuffer screenshot_framebuffer; |
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp index ac99e6385..f2aaf06db 100644 --- a/src/video_core/renderer_opengl/utils.cpp +++ b/src/video_core/renderer_opengl/utils.cpp | |||
| @@ -24,8 +24,7 @@ VertexArrayPushBuffer::VertexArrayPushBuffer() = default; | |||
| 24 | 24 | ||
| 25 | VertexArrayPushBuffer::~VertexArrayPushBuffer() = default; | 25 | VertexArrayPushBuffer::~VertexArrayPushBuffer() = default; |
| 26 | 26 | ||
| 27 | void VertexArrayPushBuffer::Setup(GLuint vao_) { | 27 | void VertexArrayPushBuffer::Setup() { |
| 28 | vao = vao_; | ||
| 29 | index_buffer = nullptr; | 28 | index_buffer = nullptr; |
| 30 | vertex_buffers.clear(); | 29 | vertex_buffers.clear(); |
| 31 | } | 30 | } |
| @@ -41,13 +40,12 @@ void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint* | |||
| 41 | 40 | ||
| 42 | void VertexArrayPushBuffer::Bind() { | 41 | void VertexArrayPushBuffer::Bind() { |
| 43 | if (index_buffer) { | 42 | if (index_buffer) { |
| 44 | glVertexArrayElementBuffer(vao, *index_buffer); | 43 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *index_buffer); |
| 45 | } | 44 | } |
| 46 | 45 | ||
| 47 | // TODO(Rodrigo): Find a way to ARB_multi_bind this | 46 | // TODO(Rodrigo): Find a way to ARB_multi_bind this |
| 48 | for (const auto& entry : vertex_buffers) { | 47 | for (const auto& entry : vertex_buffers) { |
| 49 | glVertexArrayVertexBuffer(vao, entry.binding_index, *entry.buffer, entry.offset, | 48 | glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride); |
| 50 | entry.stride); | ||
| 51 | } | 49 | } |
| 52 | } | 50 | } |
| 53 | 51 | ||
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h index 3ad7c02d4..e8612a9ec 100644 --- a/src/video_core/renderer_opengl/utils.h +++ b/src/video_core/renderer_opengl/utils.h | |||
| @@ -16,7 +16,7 @@ public: | |||
| 16 | explicit VertexArrayPushBuffer(); | 16 | explicit VertexArrayPushBuffer(); |
| 17 | ~VertexArrayPushBuffer(); | 17 | ~VertexArrayPushBuffer(); |
| 18 | 18 | ||
| 19 | void Setup(GLuint vao_); | 19 | void Setup(); |
| 20 | 20 | ||
| 21 | void SetIndexBuffer(const GLuint* buffer); | 21 | void SetIndexBuffer(const GLuint* buffer); |
| 22 | 22 | ||
| @@ -28,7 +28,6 @@ public: | |||
| 28 | private: | 28 | private: |
| 29 | struct Entry; | 29 | struct Entry; |
| 30 | 30 | ||
| 31 | GLuint vao{}; | ||
| 32 | const GLuint* index_buffer{}; | 31 | const GLuint* index_buffer{}; |
| 33 | std::vector<Entry> vertex_buffers; | 32 | std::vector<Entry> vertex_buffers; |
| 34 | }; | 33 | }; |