1 // Copyright 2020 yuzu Emulator Project
2 // Licensed under GPLv2 or any later version
3 // Refer to the license.txt file included.
4
5 #include <algorithm>
6 #include <cstddef>
7 #include <iterator>
8
9 #include "common/common_types.h"
10 #include "core/core.h"
11 #include "video_core/dirty_flags.h"
12 #include "video_core/engines/maxwell_3d.h"
13 #include "video_core/gpu.h"
14 #include "video_core/renderer_vulkan/vk_state_tracker.h"
15
16 #define OFF(field_name) MAXWELL3D_REG_INDEX(field_name)
17 #define NUM(field_name) (sizeof(Maxwell3D::Regs::field_name) / (sizeof(u32)))
18
19 namespace Vulkan {
20
21 namespace {
22
23 using namespace Dirty;
24 using namespace VideoCommon::Dirty;
25 using Tegra::Engines::Maxwell3D;
26 using Regs = Maxwell3D::Regs;
27 using Tables = Maxwell3D::DirtyState::Tables;
28 using Table = Maxwell3D::DirtyState::Table;
29 using Flags = Maxwell3D::DirtyState::Flags;
30
MakeInvalidationFlags()31 Flags MakeInvalidationFlags() {
32 Flags flags{};
33 flags[Viewports] = true;
34 flags[Scissors] = true;
35 flags[DepthBias] = true;
36 flags[BlendConstants] = true;
37 flags[DepthBounds] = true;
38 flags[StencilProperties] = true;
39 flags[CullMode] = true;
40 flags[DepthBoundsEnable] = true;
41 flags[DepthTestEnable] = true;
42 flags[DepthWriteEnable] = true;
43 flags[DepthCompareOp] = true;
44 flags[FrontFace] = true;
45 flags[StencilOp] = true;
46 flags[StencilTestEnable] = true;
47 return flags;
48 }
49
SetupDirtyViewports(Tables & tables)50 void SetupDirtyViewports(Tables& tables) {
51 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
52 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
53 tables[0][OFF(viewport_transform_enabled)] = Viewports;
54 }
55
SetupDirtyScissors(Tables & tables)56 void SetupDirtyScissors(Tables& tables) {
57 FillBlock(tables[0], OFF(scissor_test), NUM(scissor_test), Scissors);
58 }
59
SetupDirtyDepthBias(Tables & tables)60 void SetupDirtyDepthBias(Tables& tables) {
61 auto& table = tables[0];
62 table[OFF(polygon_offset_units)] = DepthBias;
63 table[OFF(polygon_offset_clamp)] = DepthBias;
64 table[OFF(polygon_offset_factor)] = DepthBias;
65 }
66
SetupDirtyBlendConstants(Tables & tables)67 void SetupDirtyBlendConstants(Tables& tables) {
68 FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendConstants);
69 }
70
SetupDirtyDepthBounds(Tables & tables)71 void SetupDirtyDepthBounds(Tables& tables) {
72 FillBlock(tables[0], OFF(depth_bounds), NUM(depth_bounds), DepthBounds);
73 }
74
SetupDirtyStencilProperties(Tables & tables)75 void SetupDirtyStencilProperties(Tables& tables) {
76 auto& table = tables[0];
77 table[OFF(stencil_two_side_enable)] = StencilProperties;
78 table[OFF(stencil_front_func_ref)] = StencilProperties;
79 table[OFF(stencil_front_mask)] = StencilProperties;
80 table[OFF(stencil_front_func_mask)] = StencilProperties;
81 table[OFF(stencil_back_func_ref)] = StencilProperties;
82 table[OFF(stencil_back_mask)] = StencilProperties;
83 table[OFF(stencil_back_func_mask)] = StencilProperties;
84 }
85
SetupDirtyCullMode(Tables & tables)86 void SetupDirtyCullMode(Tables& tables) {
87 auto& table = tables[0];
88 table[OFF(cull_face)] = CullMode;
89 table[OFF(cull_test_enabled)] = CullMode;
90 }
91
SetupDirtyDepthBoundsEnable(Tables & tables)92 void SetupDirtyDepthBoundsEnable(Tables& tables) {
93 tables[0][OFF(depth_bounds_enable)] = DepthBoundsEnable;
94 }
95
SetupDirtyDepthTestEnable(Tables & tables)96 void SetupDirtyDepthTestEnable(Tables& tables) {
97 tables[0][OFF(depth_test_enable)] = DepthTestEnable;
98 }
99
SetupDirtyDepthWriteEnable(Tables & tables)100 void SetupDirtyDepthWriteEnable(Tables& tables) {
101 tables[0][OFF(depth_write_enabled)] = DepthWriteEnable;
102 }
103
SetupDirtyDepthCompareOp(Tables & tables)104 void SetupDirtyDepthCompareOp(Tables& tables) {
105 tables[0][OFF(depth_test_func)] = DepthCompareOp;
106 }
107
SetupDirtyFrontFace(Tables & tables)108 void SetupDirtyFrontFace(Tables& tables) {
109 auto& table = tables[0];
110 table[OFF(front_face)] = FrontFace;
111 table[OFF(screen_y_control)] = FrontFace;
112 }
113
SetupDirtyStencilOp(Tables & tables)114 void SetupDirtyStencilOp(Tables& tables) {
115 auto& table = tables[0];
116 table[OFF(stencil_front_op_fail)] = StencilOp;
117 table[OFF(stencil_front_op_zfail)] = StencilOp;
118 table[OFF(stencil_front_op_zpass)] = StencilOp;
119 table[OFF(stencil_front_func_func)] = StencilOp;
120 table[OFF(stencil_back_op_fail)] = StencilOp;
121 table[OFF(stencil_back_op_zfail)] = StencilOp;
122 table[OFF(stencil_back_op_zpass)] = StencilOp;
123 table[OFF(stencil_back_func_func)] = StencilOp;
124
125 // Table 0 is used by StencilProperties
126 tables[1][OFF(stencil_two_side_enable)] = StencilOp;
127 }
128
SetupDirtyStencilTestEnable(Tables & tables)129 void SetupDirtyStencilTestEnable(Tables& tables) {
130 tables[0][OFF(stencil_enable)] = StencilTestEnable;
131 }
132
133 } // Anonymous namespace
134
StateTracker(Tegra::GPU & gpu)135 StateTracker::StateTracker(Tegra::GPU& gpu)
136 : flags{gpu.Maxwell3D().dirty.flags}, invalidation_flags{MakeInvalidationFlags()} {
137 auto& tables = gpu.Maxwell3D().dirty.tables;
138 SetupDirtyRenderTargets(tables);
139 SetupDirtyViewports(tables);
140 SetupDirtyScissors(tables);
141 SetupDirtyDepthBias(tables);
142 SetupDirtyBlendConstants(tables);
143 SetupDirtyDepthBounds(tables);
144 SetupDirtyStencilProperties(tables);
145 SetupDirtyCullMode(tables);
146 SetupDirtyDepthBoundsEnable(tables);
147 SetupDirtyDepthTestEnable(tables);
148 SetupDirtyDepthWriteEnable(tables);
149 SetupDirtyDepthCompareOp(tables);
150 SetupDirtyFrontFace(tables);
151 SetupDirtyStencilOp(tables);
152 SetupDirtyStencilTestEnable(tables);
153 }
154
155 } // namespace Vulkan
156