summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-03-02 19:31:26 -0300
committerGravatar ReinUsesLisp2020-03-13 18:33:04 -0300
commit8e9f23f393763a6d76605206eeb20f6f8885d9a9 (patch)
tree35b28be3f345cd0223732b4803e13de40764d1dc /src
parentgl_shader_decompiler: Decorate output attributes with XFB layout (diff)
downloadyuzu-8e9f23f393763a6d76605206eeb20f6f8885d9a9.tar.gz
yuzu-8e9f23f393763a6d76605206eeb20f6f8885d9a9.tar.xz
yuzu-8e9f23f393763a6d76605206eeb20f6f8885d9a9.zip
gl_rasterizer: Implement transform feedback bindings
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.h9
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp70
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h14
3 files changed, 83 insertions, 10 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 8752a1cfb..ba9c76593 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -634,6 +634,11 @@ public:
634 u32 address_low; 634 u32 address_low;
635 s32 buffer_size; 635 s32 buffer_size;
636 s32 buffer_offset; 636 s32 buffer_offset;
637
638 GPUVAddr Address() const {
639 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
640 address_low);
641 }
637 }; 642 };
638 static_assert(sizeof(TransformFeedbackBinding) == 32); 643 static_assert(sizeof(TransformFeedbackBinding) == 32);
639 644
@@ -652,6 +657,10 @@ public:
652 return shader_config[index].enable != 0; 657 return shader_config[index].enable != 0;
653 } 658 }
654 659
660 bool IsShaderConfigEnabled(Regs::ShaderProgram type) const {
661 return IsShaderConfigEnabled(static_cast<std::size_t>(type));
662 }
663
655 union { 664 union {
656 struct { 665 struct {
657 INSERT_UNION_PADDING_WORDS(0x45); 666 INSERT_UNION_PADDING_WORDS(0x45);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 8a2db8e36..1af4268a4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -496,7 +496,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
496 SyncCullMode(); 496 SyncCullMode();
497 SyncPrimitiveRestart(); 497 SyncPrimitiveRestart();
498 SyncScissorTest(); 498 SyncScissorTest();
499 SyncTransformFeedback();
500 SyncPointState(); 499 SyncPointState();
501 SyncPolygonOffset(); 500 SyncPolygonOffset();
502 SyncAlphaTest(); 501 SyncAlphaTest();
@@ -569,7 +568,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
569 glTextureBarrier(); 568 glTextureBarrier();
570 } 569 }
571 570
572 ++num_queued_commands; 571 BeginTransformFeedback(primitive_mode);
573 572
574 const GLuint base_instance = static_cast<GLuint>(gpu.regs.vb_base_instance); 573 const GLuint base_instance = static_cast<GLuint>(gpu.regs.vb_base_instance);
575 const GLsizei num_instances = 574 const GLsizei num_instances =
@@ -608,6 +607,10 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
608 num_instances, base_instance); 607 num_instances, base_instance);
609 } 608 }
610 } 609 }
610
611 EndTransformFeedback();
612
613 ++num_queued_commands;
611} 614}
612 615
613void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) { 616void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
@@ -1290,11 +1293,6 @@ void RasterizerOpenGL::SyncScissorTest() {
1290 } 1293 }
1291} 1294}
1292 1295
1293void RasterizerOpenGL::SyncTransformFeedback() {
1294 const auto& regs = system.GPU().Maxwell3D().regs;
1295 UNIMPLEMENTED_IF_MSG(regs.tfb_enabled != 0, "Transform feedbacks are not implemented");
1296}
1297
1298void RasterizerOpenGL::SyncPointState() { 1296void RasterizerOpenGL::SyncPointState() {
1299 auto& gpu = system.GPU().Maxwell3D(); 1297 auto& gpu = system.GPU().Maxwell3D();
1300 auto& flags = gpu.dirty.flags; 1298 auto& flags = gpu.dirty.flags;
@@ -1370,4 +1368,62 @@ void RasterizerOpenGL::SyncFramebufferSRGB() {
1370 oglEnable(GL_FRAMEBUFFER_SRGB, gpu.regs.framebuffer_srgb); 1368 oglEnable(GL_FRAMEBUFFER_SRGB, gpu.regs.framebuffer_srgb);
1371} 1369}
1372 1370
1371void RasterizerOpenGL::BeginTransformFeedback(GLenum primitive_mode) {
1372 const auto& regs = system.GPU().Maxwell3D().regs;
1373 if (regs.tfb_enabled == 0) {
1374 return;
1375 }
1376
1377 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) ||
1378 regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) ||
1379 regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry));
1380
1381 for (std::size_t index = 0; index < Maxwell::NumTransformFeedbackBuffers; ++index) {
1382 const auto& binding = regs.tfb_bindings[index];
1383 if (!binding.buffer_enable) {
1384 if (enabled_transform_feedback_buffers[index]) {
1385 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), 0, 0,
1386 0);
1387 }
1388 enabled_transform_feedback_buffers[index] = false;
1389 continue;
1390 }
1391 enabled_transform_feedback_buffers[index] = true;
1392
1393 auto& tfb_buffer = transform_feedback_buffers[index];
1394 tfb_buffer.Create();
1395
1396 const GLuint handle = tfb_buffer.handle;
1397 const std::size_t size = binding.buffer_size;
1398 glNamedBufferData(handle, static_cast<GLsizeiptr>(size), nullptr, GL_STREAM_COPY);
1399 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, static_cast<GLuint>(index), handle, 0,
1400 static_cast<GLsizeiptr>(size));
1401 }
1402
1403 glBeginTransformFeedback(GL_POINTS);
1404}
1405
1406void RasterizerOpenGL::EndTransformFeedback() {
1407 const auto& regs = system.GPU().Maxwell3D().regs;
1408 if (regs.tfb_enabled == 0) {
1409 return;
1410 }
1411
1412 glEndTransformFeedback();
1413
1414 for (std::size_t index = 0; index < Maxwell::NumTransformFeedbackBuffers; ++index) {
1415 const auto& binding = regs.tfb_bindings[index];
1416 if (!binding.buffer_enable) {
1417 continue;
1418 }
1419 UNIMPLEMENTED_IF(binding.buffer_offset != 0);
1420
1421 const GLuint handle = transform_feedback_buffers[index].handle;
1422 const GPUVAddr gpu_addr = binding.Address();
1423 const std::size_t size = binding.buffer_size;
1424 const auto [dest_buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true);
1425 glCopyNamedBufferSubData(handle, *dest_buffer, 0, offset, static_cast<GLsizeiptr>(size));
1426 }
1427}
1428
1373} // namespace OpenGL 1429} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index e6424f5d2..2d3be2437 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -168,9 +168,6 @@ private:
168 /// Syncs the scissor test state to match the guest state 168 /// Syncs the scissor test state to match the guest state
169 void SyncScissorTest(); 169 void SyncScissorTest();
170 170
171 /// Syncs the transform feedback state to match the guest state
172 void SyncTransformFeedback();
173
174 /// Syncs the point state to match the guest state 171 /// Syncs the point state to match the guest state
175 void SyncPointState(); 172 void SyncPointState();
176 173
@@ -192,6 +189,12 @@ private:
192 /// Syncs the framebuffer sRGB state to match the guest state 189 /// Syncs the framebuffer sRGB state to match the guest state
193 void SyncFramebufferSRGB(); 190 void SyncFramebufferSRGB();
194 191
192 /// Begin a transform feedback
193 void BeginTransformFeedback(GLenum primitive_mode);
194
195 /// End a transform feedback
196 void EndTransformFeedback();
197
195 /// Check for extension that are not strictly required but are needed for correct emulation 198 /// Check for extension that are not strictly required but are needed for correct emulation
196 void CheckExtensions(); 199 void CheckExtensions();
197 200
@@ -229,6 +232,11 @@ private:
229 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER}; 232 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
230 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER}; 233 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
231 234
235 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
236 transform_feedback_buffers;
237 std::bitset<Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
238 enabled_transform_feedback_buffers;
239
232 /// Number of commands queued to the OpenGL driver. Reseted on flush. 240 /// Number of commands queued to the OpenGL driver. Reseted on flush.
233 std::size_t num_queued_commands = 0; 241 std::size_t num_queued_commands = 0;
234 242