summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-07-27 19:40:10 -0300
committerGravatar ReinUsesLisp2020-02-14 17:27:17 -0300
commit2b58652f0897053d4da04deb586490220ab5a774 (patch)
treecb49e0b4da2297e25da1aa196bbb38d6e996d399 /src
parentgl_resource_manager: Add managed query class (diff)
downloadyuzu-2b58652f0897053d4da04deb586490220ab5a774.tar.gz
yuzu-2b58652f0897053d4da04deb586490220ab5a774.tar.xz
yuzu-2b58652f0897053d4da04deb586490220ab5a774.zip
maxwell_3d: Slow implementation of passed samples (query 21)
Implements GL_SAMPLES_PASSED by waiting immediately for queries.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/engines/maxwell_3d.cpp39
-rw-r--r--src/video_core/engines/maxwell_3d.h38
-rw-r--r--src/video_core/rasterizer_interface.h10
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.cpp59
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.h41
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp24
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h5
8 files changed, 201 insertions, 17 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index db9332d00..3208f4993 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -74,6 +74,8 @@ add_library(video_core STATIC
74 renderer_opengl/gl_stream_buffer.h 74 renderer_opengl/gl_stream_buffer.h
75 renderer_opengl/gl_texture_cache.cpp 75 renderer_opengl/gl_texture_cache.cpp
76 renderer_opengl/gl_texture_cache.h 76 renderer_opengl/gl_texture_cache.h
77 renderer_opengl/gl_query_cache.cpp
78 renderer_opengl/gl_query_cache.h
77 renderer_opengl/maxwell_to_gl.h 79 renderer_opengl/maxwell_to_gl.h
78 renderer_opengl/renderer_opengl.cpp 80 renderer_opengl/renderer_opengl.cpp
79 renderer_opengl/renderer_opengl.h 81 renderer_opengl/renderer_opengl.h
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 0b3e8749b..fe91ff6a0 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -400,6 +400,10 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
400 ProcessQueryCondition(); 400 ProcessQueryCondition();
401 break; 401 break;
402 } 402 }
403 case MAXWELL3D_REG_INDEX(counter_reset): {
404 ProcessCounterReset();
405 break;
406 }
403 case MAXWELL3D_REG_INDEX(sync_info): { 407 case MAXWELL3D_REG_INDEX(sync_info): {
404 ProcessSyncPoint(); 408 ProcessSyncPoint();
405 break; 409 break;
@@ -544,23 +548,23 @@ void Maxwell3D::ProcessQueryGet() {
544 "Units other than CROP are unimplemented"); 548 "Units other than CROP are unimplemented");
545 549
546 switch (regs.query.query_get.operation) { 550 switch (regs.query.query_get.operation) {
547 case Regs::QueryOperation::Release: { 551 case Regs::QueryOperation::Release:
548 const u64 result = regs.query.query_sequence; 552 StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0);
549 StampQueryResult(result, regs.query.query_get.short_query == 0);
550 break; 553 break;
551 } 554 case Regs::QueryOperation::Acquire:
552 case Regs::QueryOperation::Acquire: { 555 // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that
553 // Todo(Blinkhawk): Under this operation, the GPU waits for the CPU 556 // matches the current payload.
554 // to write a value that matches the current payload.
555 UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE"); 557 UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE");
556 break; 558 break;
557 }
558 case Regs::QueryOperation::Counter: { 559 case Regs::QueryOperation::Counter: {
559 u64 result{}; 560 u64 result;
560 switch (regs.query.query_get.select) { 561 switch (regs.query.query_get.select) {
561 case Regs::QuerySelect::Zero: 562 case Regs::QuerySelect::Zero:
562 result = 0; 563 result = 0;
563 break; 564 break;
565 case Regs::QuerySelect::SamplesPassed:
566 result = rasterizer.Query(VideoCore::QueryType::SamplesPassed);
567 break;
564 default: 568 default:
565 result = 1; 569 result = 1;
566 UNIMPLEMENTED_MSG("Unimplemented query select type {}", 570 UNIMPLEMENTED_MSG("Unimplemented query select type {}",
@@ -569,15 +573,13 @@ void Maxwell3D::ProcessQueryGet() {
569 StampQueryResult(result, regs.query.query_get.short_query == 0); 573 StampQueryResult(result, regs.query.query_get.short_query == 0);
570 break; 574 break;
571 } 575 }
572 case Regs::QueryOperation::Trap: { 576 case Regs::QueryOperation::Trap:
573 UNIMPLEMENTED_MSG("Unimplemented query operation TRAP"); 577 UNIMPLEMENTED_MSG("Unimplemented query operation TRAP");
574 break; 578 break;
575 } 579 default:
576 default: {
577 UNIMPLEMENTED_MSG("Unknown query operation"); 580 UNIMPLEMENTED_MSG("Unknown query operation");
578 break; 581 break;
579 } 582 }
580 }
581} 583}
582 584
583void Maxwell3D::ProcessQueryCondition() { 585void Maxwell3D::ProcessQueryCondition() {
@@ -619,6 +621,17 @@ void Maxwell3D::ProcessQueryCondition() {
619 } 621 }
620} 622}
621 623
624void Maxwell3D::ProcessCounterReset() {
625 switch (regs.counter_reset) {
626 case Regs::CounterReset::SampleCnt:
627 rasterizer.ResetCounter(VideoCore::QueryType::SamplesPassed);
628 break;
629 default:
630 UNIMPLEMENTED_MSG("counter_reset={}", static_cast<u32>(regs.counter_reset));
631 break;
632 }
633}
634
622void Maxwell3D::ProcessSyncPoint() { 635void Maxwell3D::ProcessSyncPoint() {
623 const u32 sync_point = regs.sync_info.sync_point.Value(); 636 const u32 sync_point = regs.sync_info.sync_point.Value();
624 const u32 increment = regs.sync_info.increment.Value(); 637 const u32 increment = regs.sync_info.increment.Value();
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 0a2af54e5..d21f678ed 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -409,6 +409,27 @@ public:
409 Linear = 1, 409 Linear = 1,
410 }; 410 };
411 411
412 enum class CounterReset : u32 {
413 SampleCnt = 0x01,
414 Unk02 = 0x02,
415 Unk03 = 0x03,
416 Unk04 = 0x04,
417 EmittedPrimitives = 0x10, // Not tested
418 Unk11 = 0x11,
419 Unk12 = 0x12,
420 Unk13 = 0x13,
421 Unk15 = 0x15,
422 Unk16 = 0x16,
423 Unk17 = 0x17,
424 Unk18 = 0x18,
425 Unk1A = 0x1A,
426 Unk1B = 0x1B,
427 Unk1C = 0x1C,
428 Unk1D = 0x1D,
429 Unk1E = 0x1E,
430 GeneratedPrimitives = 0x1F,
431 };
432
412 struct Cull { 433 struct Cull {
413 enum class FrontFace : u32 { 434 enum class FrontFace : u32 {
414 ClockWise = 0x0900, 435 ClockWise = 0x0900,
@@ -857,7 +878,7 @@ public:
857 BitField<7, 1, u32> c7; 878 BitField<7, 1, u32> c7;
858 } clip_distance_enabled; 879 } clip_distance_enabled;
859 880
860 INSERT_UNION_PADDING_WORDS(0x1); 881 u32 samplecnt_enable;
861 882
862 float point_size; 883 float point_size;
863 884
@@ -865,7 +886,11 @@ public:
865 886
866 u32 point_sprite_enable; 887 u32 point_sprite_enable;
867 888
868 INSERT_UNION_PADDING_WORDS(0x5); 889 INSERT_UNION_PADDING_WORDS(0x3);
890
891 CounterReset counter_reset;
892
893 INSERT_UNION_PADDING_WORDS(0x1);
869 894
870 u32 zeta_enable; 895 u32 zeta_enable;
871 896
@@ -1412,12 +1437,15 @@ private:
1412 /// Handles a write to the QUERY_GET register. 1437 /// Handles a write to the QUERY_GET register.
1413 void ProcessQueryGet(); 1438 void ProcessQueryGet();
1414 1439
1415 // Writes the query result accordingly 1440 /// Writes the query result accordingly.
1416 void StampQueryResult(u64 payload, bool long_query); 1441 void StampQueryResult(u64 payload, bool long_query);
1417 1442
1418 // Handles Conditional Rendering 1443 /// Handles conditional rendering.
1419 void ProcessQueryCondition(); 1444 void ProcessQueryCondition();
1420 1445
1446 /// Handles counter resets.
1447 void ProcessCounterReset();
1448
1421 /// Handles writes to syncing register. 1449 /// Handles writes to syncing register.
1422 void ProcessSyncPoint(); 1450 void ProcessSyncPoint();
1423 1451
@@ -1499,8 +1527,10 @@ ASSERT_REG_POSITION(screen_y_control, 0x4EB);
1499ASSERT_REG_POSITION(vb_element_base, 0x50D); 1527ASSERT_REG_POSITION(vb_element_base, 0x50D);
1500ASSERT_REG_POSITION(vb_base_instance, 0x50E); 1528ASSERT_REG_POSITION(vb_base_instance, 0x50E);
1501ASSERT_REG_POSITION(clip_distance_enabled, 0x544); 1529ASSERT_REG_POSITION(clip_distance_enabled, 0x544);
1530ASSERT_REG_POSITION(samplecnt_enable, 0x545);
1502ASSERT_REG_POSITION(point_size, 0x546); 1531ASSERT_REG_POSITION(point_size, 0x546);
1503ASSERT_REG_POSITION(point_sprite_enable, 0x548); 1532ASSERT_REG_POSITION(point_sprite_enable, 0x548);
1533ASSERT_REG_POSITION(counter_reset, 0x54C);
1504ASSERT_REG_POSITION(zeta_enable, 0x54E); 1534ASSERT_REG_POSITION(zeta_enable, 0x54E);
1505ASSERT_REG_POSITION(multisample_control, 0x54F); 1535ASSERT_REG_POSITION(multisample_control, 0x54F);
1506ASSERT_REG_POSITION(condition, 0x554); 1536ASSERT_REG_POSITION(condition, 0x554);
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index c586cd6fe..2fc627539 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -17,6 +17,10 @@ class MemoryManager;
17 17
18namespace VideoCore { 18namespace VideoCore {
19 19
20enum class QueryType {
21 SamplesPassed,
22};
23
20enum class LoadCallbackStage { 24enum class LoadCallbackStage {
21 Prepare, 25 Prepare,
22 Decompile, 26 Decompile,
@@ -41,6 +45,12 @@ public:
41 /// Dispatches a compute shader invocation 45 /// Dispatches a compute shader invocation
42 virtual void DispatchCompute(GPUVAddr code_addr) = 0; 46 virtual void DispatchCompute(GPUVAddr code_addr) = 0;
43 47
48 /// Resets the counter of a query
49 virtual void ResetCounter(QueryType type) = 0;
50
51 /// Returns the value of a GPU query
52 virtual u64 Query(QueryType type) = 0;
53
44 /// Notify rasterizer that all caches should be flushed to Switch memory 54 /// Notify rasterizer that all caches should be flushed to Switch memory
45 virtual void FlushAll() = 0; 55 virtual void FlushAll() = 0;
46 56
diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp
new file mode 100644
index 000000000..1c7dc999a
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_query_cache.cpp
@@ -0,0 +1,59 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <glad/glad.h>
6
7#include "video_core/renderer_opengl/gl_query_cache.h"
8
9namespace OpenGL {
10
11HostCounter::HostCounter(GLenum target) {
12 query.Create(target);
13}
14
15HostCounter::~HostCounter() = default;
16
17void HostCounter::UpdateState(bool enabled) {
18 if (enabled) {
19 Enable();
20 } else {
21 Disable();
22 }
23}
24
25void HostCounter::Reset() {
26 counter = 0;
27 Disable();
28}
29
30u64 HostCounter::Query() {
31 if (!is_beginned) {
32 return counter;
33 }
34 Disable();
35 u64 value;
36 glGetQueryObjectui64v(query.handle, GL_QUERY_RESULT, &value);
37 Enable();
38
39 counter += value;
40 return counter;
41}
42
43void HostCounter::Enable() {
44 if (is_beginned) {
45 return;
46 }
47 is_beginned = true;
48 glBeginQuery(GL_SAMPLES_PASSED, query.handle);
49}
50
51void HostCounter::Disable() {
52 if (!is_beginned) {
53 return;
54 }
55 glEndQuery(GL_SAMPLES_PASSED);
56 is_beginned = false;
57}
58
59} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_query_cache.h b/src/video_core/renderer_opengl/gl_query_cache.h
new file mode 100644
index 000000000..52c6546bf
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_query_cache.h
@@ -0,0 +1,41 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <glad/glad.h>
8
9#include "common/common_types.h"
10#include "video_core/renderer_opengl/gl_resource_manager.h"
11
12namespace OpenGL {
13
14class HostCounter final {
15public:
16 explicit HostCounter(GLenum target);
17 ~HostCounter();
18
19 /// Enables or disables the counter as required.
20 void UpdateState(bool enabled);
21
22 /// Resets the counter disabling it if needed.
23 void Reset();
24
25 /// Returns the current value of the query.
26 /// @note It may harm precision of future queries if the counter is not disabled.
27 u64 Query();
28
29private:
30 /// Enables the counter when disabled.
31 void Enable();
32
33 /// Disables the counter when enabled.
34 void Disable();
35
36 OGLQuery query; ///< OpenGL query.
37 u64 counter{}; ///< Added values of the counter.
38 bool is_beginned{}; ///< True when the OpenGL query is beginned.
39};
40
41} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index b0eb14c8b..8d132732a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -547,6 +547,9 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
547 MICROPROFILE_SCOPE(OpenGL_Drawing); 547 MICROPROFILE_SCOPE(OpenGL_Drawing);
548 auto& gpu = system.GPU().Maxwell3D(); 548 auto& gpu = system.GPU().Maxwell3D();
549 549
550 const auto& regs = gpu.regs;
551 samples_passed.UpdateState(regs.samplecnt_enable);
552
550 SyncRasterizeEnable(state); 553 SyncRasterizeEnable(state);
551 SyncColorMask(); 554 SyncColorMask();
552 SyncFragmentColorClampState(); 555 SyncFragmentColorClampState();
@@ -709,6 +712,27 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
709 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); 712 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
710} 713}
711 714
715void RasterizerOpenGL::ResetCounter(VideoCore::QueryType type) {
716 switch (type) {
717 case VideoCore::QueryType::SamplesPassed:
718 samples_passed.Reset();
719 break;
720 default:
721 UNIMPLEMENTED_MSG("type={}", static_cast<u32>(type));
722 break;
723 }
724}
725
726u64 RasterizerOpenGL::Query(VideoCore::QueryType type) {
727 switch (type) {
728 case VideoCore::QueryType::SamplesPassed:
729 return samples_passed.Query();
730 default:
731 UNIMPLEMENTED_MSG("type={}", static_cast<u32>(type));
732 return 1;
733 }
734}
735
712void RasterizerOpenGL::FlushAll() {} 736void RasterizerOpenGL::FlushAll() {}
713 737
714void RasterizerOpenGL::FlushRegion(CacheAddr addr, u64 size) { 738void RasterizerOpenGL::FlushRegion(CacheAddr addr, u64 size) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 0501f3828..32bcaf8c2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -24,6 +24,7 @@
24#include "video_core/renderer_opengl/gl_buffer_cache.h" 24#include "video_core/renderer_opengl/gl_buffer_cache.h"
25#include "video_core/renderer_opengl/gl_device.h" 25#include "video_core/renderer_opengl/gl_device.h"
26#include "video_core/renderer_opengl/gl_framebuffer_cache.h" 26#include "video_core/renderer_opengl/gl_framebuffer_cache.h"
27#include "video_core/renderer_opengl/gl_query_cache.h"
27#include "video_core/renderer_opengl/gl_resource_manager.h" 28#include "video_core/renderer_opengl/gl_resource_manager.h"
28#include "video_core/renderer_opengl/gl_sampler_cache.h" 29#include "video_core/renderer_opengl/gl_sampler_cache.h"
29#include "video_core/renderer_opengl/gl_shader_cache.h" 30#include "video_core/renderer_opengl/gl_shader_cache.h"
@@ -61,6 +62,8 @@ public:
61 bool DrawMultiBatch(bool is_indexed) override; 62 bool DrawMultiBatch(bool is_indexed) override;
62 void Clear() override; 63 void Clear() override;
63 void DispatchCompute(GPUVAddr code_addr) override; 64 void DispatchCompute(GPUVAddr code_addr) override;
65 void ResetCounter(VideoCore::QueryType type) override;
66 u64 Query(VideoCore::QueryType type) override;
64 void FlushAll() override; 67 void FlushAll() override;
65 void FlushRegion(CacheAddr addr, u64 size) override; 68 void FlushRegion(CacheAddr addr, u64 size) override;
66 void InvalidateRegion(CacheAddr addr, u64 size) override; 69 void InvalidateRegion(CacheAddr addr, u64 size) override;
@@ -221,6 +224,8 @@ private:
221 GLintptr SetupIndexBuffer(); 224 GLintptr SetupIndexBuffer();
222 225
223 void SetupShaders(GLenum primitive_mode); 226 void SetupShaders(GLenum primitive_mode);
227
228 HostCounter samples_passed{GL_SAMPLES_PASSED};
224}; 229};
225 230
226} // namespace OpenGL 231} // namespace OpenGL