diff options
| author | 2019-12-25 17:02:17 -0300 | |
|---|---|---|
| committer | 2020-02-28 16:39:27 -0300 | |
| commit | 96ac3d518a9882a2a040f319c47a567467c9266d (patch) | |
| tree | d1465f931df28d12891b07e5ab8c1d921a396376 /src | |
| parent | common/math_util: Support float type rectangles (diff) | |
| download | yuzu-96ac3d518a9882a2a040f319c47a567467c9266d.tar.gz yuzu-96ac3d518a9882a2a040f319c47a567467c9266d.tar.xz yuzu-96ac3d518a9882a2a040f319c47a567467c9266d.zip | |
gl_rasterizer: Remove dirty flags
Diffstat (limited to 'src')
18 files changed, 7 insertions, 457 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 4b0c6346f..db65e7bf3 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -69,6 +69,8 @@ add_library(video_core STATIC | |||
| 69 | renderer_opengl/gl_shader_manager.h | 69 | renderer_opengl/gl_shader_manager.h |
| 70 | renderer_opengl/gl_shader_util.cpp | 70 | renderer_opengl/gl_shader_util.cpp |
| 71 | renderer_opengl/gl_shader_util.h | 71 | renderer_opengl/gl_shader_util.h |
| 72 | renderer_opengl/gl_state_tracker.cpp | ||
| 73 | renderer_opengl/gl_state_tracker.h | ||
| 72 | renderer_opengl/gl_state.cpp | 74 | renderer_opengl/gl_state.cpp |
| 73 | renderer_opengl/gl_state.h | 75 | renderer_opengl/gl_state.h |
| 74 | renderer_opengl/gl_stream_buffer.cpp | 76 | renderer_opengl/gl_stream_buffer.cpp |
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 0094fd715..a42d37c81 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp | |||
| @@ -21,9 +21,6 @@ MICROPROFILE_DEFINE(DispatchCalls, "GPU", "Execute command buffer", MP_RGB(128, | |||
| 21 | void DmaPusher::DispatchCalls() { | 21 | void DmaPusher::DispatchCalls() { |
| 22 | MICROPROFILE_SCOPE(DispatchCalls); | 22 | MICROPROFILE_SCOPE(DispatchCalls); |
| 23 | 23 | ||
| 24 | // On entering GPU code, assume all memory may be touched by the ARM core. | ||
| 25 | gpu.Maxwell3D().dirty.OnMemoryWrite(); | ||
| 26 | |||
| 27 | dma_pushbuffer_subindex = 0; | 24 | dma_pushbuffer_subindex = 0; |
| 28 | 25 | ||
| 29 | while (Core::System::GetInstance().IsPoweredOn()) { | 26 | while (Core::System::GetInstance().IsPoweredOn()) { |
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 4b824aa4e..254ad6810 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp | |||
| @@ -38,9 +38,6 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) { | |||
| 38 | case KEPLER_COMPUTE_REG_INDEX(data_upload): { | 38 | case KEPLER_COMPUTE_REG_INDEX(data_upload): { |
| 39 | const bool is_last_call = method_call.IsLastCall(); | 39 | const bool is_last_call = method_call.IsLastCall(); |
| 40 | upload_state.ProcessData(method_call.argument, is_last_call); | 40 | upload_state.ProcessData(method_call.argument, is_last_call); |
| 41 | if (is_last_call) { | ||
| 42 | system.GPU().Maxwell3D().dirty.OnMemoryWrite(); | ||
| 43 | } | ||
| 44 | break; | 41 | break; |
| 45 | } | 42 | } |
| 46 | case KEPLER_COMPUTE_REG_INDEX(launch): | 43 | case KEPLER_COMPUTE_REG_INDEX(launch): |
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index fa4a7c5c1..b504b450e 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp | |||
| @@ -33,9 +33,6 @@ void KeplerMemory::CallMethod(const GPU::MethodCall& method_call) { | |||
| 33 | case KEPLERMEMORY_REG_INDEX(data): { | 33 | case KEPLERMEMORY_REG_INDEX(data): { |
| 34 | const bool is_last_call = method_call.IsLastCall(); | 34 | const bool is_last_call = method_call.IsLastCall(); |
| 35 | upload_state.ProcessData(method_call.argument, is_last_call); | 35 | upload_state.ProcessData(method_call.argument, is_last_call); |
| 36 | if (is_last_call) { | ||
| 37 | system.GPU().Maxwell3D().dirty.OnMemoryWrite(); | ||
| 38 | } | ||
| 39 | break; | 36 | break; |
| 40 | } | 37 | } |
| 41 | } | 38 | } |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index b28de1092..7a6bf764c 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -26,7 +26,6 @@ Maxwell3D::Maxwell3D(Core::System& system, VideoCore::RasterizerInterface& raste | |||
| 26 | MemoryManager& memory_manager) | 26 | MemoryManager& memory_manager) |
| 27 | : system{system}, rasterizer{rasterizer}, memory_manager{memory_manager}, | 27 | : system{system}, rasterizer{rasterizer}, memory_manager{memory_manager}, |
| 28 | macro_interpreter{*this}, upload_state{memory_manager, regs.upload} { | 28 | macro_interpreter{*this}, upload_state{memory_manager, regs.upload} { |
| 29 | InitDirtySettings(); | ||
| 30 | InitializeRegisterDefaults(); | 29 | InitializeRegisterDefaults(); |
| 31 | } | 30 | } |
| 32 | 31 | ||
| @@ -103,164 +102,6 @@ void Maxwell3D::InitializeRegisterDefaults() { | |||
| 103 | mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true; | 102 | mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true; |
| 104 | } | 103 | } |
| 105 | 104 | ||
| 106 | #define DIRTY_REGS_POS(field_name) static_cast<u8>(offsetof(Maxwell3D::DirtyRegs, field_name)) | ||
| 107 | |||
| 108 | void Maxwell3D::InitDirtySettings() { | ||
| 109 | const auto set_block = [this](std::size_t start, std::size_t range, u8 position) { | ||
| 110 | const auto start_itr = dirty_pointers.begin() + start; | ||
| 111 | const auto end_itr = start_itr + range; | ||
| 112 | std::fill(start_itr, end_itr, position); | ||
| 113 | }; | ||
| 114 | dirty.regs.fill(true); | ||
| 115 | |||
| 116 | // Init Render Targets | ||
| 117 | constexpr u32 registers_per_rt = sizeof(regs.rt[0]) / sizeof(u32); | ||
| 118 | constexpr u32 rt_start_reg = MAXWELL3D_REG_INDEX(rt); | ||
| 119 | constexpr u32 rt_end_reg = rt_start_reg + registers_per_rt * 8; | ||
| 120 | u8 rt_dirty_reg = DIRTY_REGS_POS(render_target); | ||
| 121 | for (u32 rt_reg = rt_start_reg; rt_reg < rt_end_reg; rt_reg += registers_per_rt) { | ||
| 122 | set_block(rt_reg, registers_per_rt, rt_dirty_reg); | ||
| 123 | ++rt_dirty_reg; | ||
| 124 | } | ||
| 125 | constexpr u32 depth_buffer_flag = DIRTY_REGS_POS(depth_buffer); | ||
| 126 | dirty_pointers[MAXWELL3D_REG_INDEX(zeta_enable)] = depth_buffer_flag; | ||
| 127 | dirty_pointers[MAXWELL3D_REG_INDEX(zeta_width)] = depth_buffer_flag; | ||
| 128 | dirty_pointers[MAXWELL3D_REG_INDEX(zeta_height)] = depth_buffer_flag; | ||
| 129 | constexpr u32 registers_in_zeta = sizeof(regs.zeta) / sizeof(u32); | ||
| 130 | constexpr u32 zeta_reg = MAXWELL3D_REG_INDEX(zeta); | ||
| 131 | set_block(zeta_reg, registers_in_zeta, depth_buffer_flag); | ||
| 132 | |||
| 133 | // Init Vertex Arrays | ||
| 134 | constexpr u32 vertex_array_start = MAXWELL3D_REG_INDEX(vertex_array); | ||
| 135 | constexpr u32 vertex_array_size = sizeof(regs.vertex_array[0]) / sizeof(u32); | ||
| 136 | constexpr u32 vertex_array_end = vertex_array_start + vertex_array_size * Regs::NumVertexArrays; | ||
| 137 | u8 va_dirty_reg = DIRTY_REGS_POS(vertex_array); | ||
| 138 | u8 vi_dirty_reg = DIRTY_REGS_POS(vertex_instance); | ||
| 139 | for (u32 vertex_reg = vertex_array_start; vertex_reg < vertex_array_end; | ||
| 140 | vertex_reg += vertex_array_size) { | ||
| 141 | set_block(vertex_reg, 3, va_dirty_reg); | ||
| 142 | // The divisor concerns vertex array instances | ||
| 143 | dirty_pointers[static_cast<std::size_t>(vertex_reg) + 3] = vi_dirty_reg; | ||
| 144 | ++va_dirty_reg; | ||
| 145 | ++vi_dirty_reg; | ||
| 146 | } | ||
| 147 | constexpr u32 vertex_limit_start = MAXWELL3D_REG_INDEX(vertex_array_limit); | ||
| 148 | constexpr u32 vertex_limit_size = sizeof(regs.vertex_array_limit[0]) / sizeof(u32); | ||
| 149 | constexpr u32 vertex_limit_end = vertex_limit_start + vertex_limit_size * Regs::NumVertexArrays; | ||
| 150 | va_dirty_reg = DIRTY_REGS_POS(vertex_array); | ||
| 151 | for (u32 vertex_reg = vertex_limit_start; vertex_reg < vertex_limit_end; | ||
| 152 | vertex_reg += vertex_limit_size) { | ||
| 153 | set_block(vertex_reg, vertex_limit_size, va_dirty_reg); | ||
| 154 | va_dirty_reg++; | ||
| 155 | } | ||
| 156 | constexpr u32 vertex_instance_start = MAXWELL3D_REG_INDEX(instanced_arrays); | ||
| 157 | constexpr u32 vertex_instance_size = | ||
| 158 | sizeof(regs.instanced_arrays.is_instanced[0]) / sizeof(u32); | ||
| 159 | constexpr u32 vertex_instance_end = | ||
| 160 | vertex_instance_start + vertex_instance_size * Regs::NumVertexArrays; | ||
| 161 | vi_dirty_reg = DIRTY_REGS_POS(vertex_instance); | ||
| 162 | for (u32 vertex_reg = vertex_instance_start; vertex_reg < vertex_instance_end; | ||
| 163 | vertex_reg += vertex_instance_size) { | ||
| 164 | set_block(vertex_reg, vertex_instance_size, vi_dirty_reg); | ||
| 165 | vi_dirty_reg++; | ||
| 166 | } | ||
| 167 | set_block(MAXWELL3D_REG_INDEX(vertex_attrib_format), regs.vertex_attrib_format.size(), | ||
| 168 | DIRTY_REGS_POS(vertex_attrib_format)); | ||
| 169 | |||
| 170 | // Init Shaders | ||
| 171 | constexpr u32 shader_registers_count = | ||
| 172 | sizeof(regs.shader_config[0]) * Regs::MaxShaderProgram / sizeof(u32); | ||
| 173 | set_block(MAXWELL3D_REG_INDEX(shader_config[0]), shader_registers_count, | ||
| 174 | DIRTY_REGS_POS(shaders)); | ||
| 175 | |||
| 176 | // State | ||
| 177 | |||
| 178 | // Viewport | ||
| 179 | constexpr u8 viewport_dirty_reg = DIRTY_REGS_POS(viewport); | ||
| 180 | constexpr u32 viewport_start = MAXWELL3D_REG_INDEX(viewports); | ||
| 181 | constexpr u32 viewport_size = sizeof(regs.viewports) / sizeof(u32); | ||
| 182 | set_block(viewport_start, viewport_size, viewport_dirty_reg); | ||
| 183 | constexpr u32 view_volume_start = MAXWELL3D_REG_INDEX(view_volume_clip_control); | ||
| 184 | constexpr u32 view_volume_size = sizeof(regs.view_volume_clip_control) / sizeof(u32); | ||
| 185 | set_block(view_volume_start, view_volume_size, viewport_dirty_reg); | ||
| 186 | |||
| 187 | // Viewport transformation | ||
| 188 | constexpr u32 viewport_trans_start = MAXWELL3D_REG_INDEX(viewport_transform); | ||
| 189 | constexpr u32 viewport_trans_size = sizeof(regs.viewport_transform) / sizeof(u32); | ||
| 190 | set_block(viewport_trans_start, viewport_trans_size, DIRTY_REGS_POS(viewport_transform)); | ||
| 191 | |||
| 192 | // Cullmode | ||
| 193 | constexpr u32 cull_mode_start = MAXWELL3D_REG_INDEX(cull); | ||
| 194 | constexpr u32 cull_mode_size = sizeof(regs.cull) / sizeof(u32); | ||
| 195 | set_block(cull_mode_start, cull_mode_size, DIRTY_REGS_POS(cull_mode)); | ||
| 196 | |||
| 197 | // Screen y control | ||
| 198 | dirty_pointers[MAXWELL3D_REG_INDEX(screen_y_control)] = DIRTY_REGS_POS(screen_y_control); | ||
| 199 | |||
| 200 | // Primitive Restart | ||
| 201 | constexpr u32 primitive_restart_start = MAXWELL3D_REG_INDEX(primitive_restart); | ||
| 202 | constexpr u32 primitive_restart_size = sizeof(regs.primitive_restart) / sizeof(u32); | ||
| 203 | set_block(primitive_restart_start, primitive_restart_size, DIRTY_REGS_POS(primitive_restart)); | ||
| 204 | |||
| 205 | // Depth Test | ||
| 206 | constexpr u8 depth_test_dirty_reg = DIRTY_REGS_POS(depth_test); | ||
| 207 | dirty_pointers[MAXWELL3D_REG_INDEX(depth_test_enable)] = depth_test_dirty_reg; | ||
| 208 | dirty_pointers[MAXWELL3D_REG_INDEX(depth_write_enabled)] = depth_test_dirty_reg; | ||
| 209 | dirty_pointers[MAXWELL3D_REG_INDEX(depth_test_func)] = depth_test_dirty_reg; | ||
| 210 | |||
| 211 | // Stencil Test | ||
| 212 | constexpr u32 stencil_test_dirty_reg = DIRTY_REGS_POS(stencil_test); | ||
| 213 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_enable)] = stencil_test_dirty_reg; | ||
| 214 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_front_func_func)] = stencil_test_dirty_reg; | ||
| 215 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_front_func_ref)] = stencil_test_dirty_reg; | ||
| 216 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_front_func_mask)] = stencil_test_dirty_reg; | ||
| 217 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_front_op_fail)] = stencil_test_dirty_reg; | ||
| 218 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_front_op_zfail)] = stencil_test_dirty_reg; | ||
| 219 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_front_op_zpass)] = stencil_test_dirty_reg; | ||
| 220 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_front_mask)] = stencil_test_dirty_reg; | ||
| 221 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_two_side_enable)] = stencil_test_dirty_reg; | ||
| 222 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_back_func_func)] = stencil_test_dirty_reg; | ||
| 223 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_back_func_ref)] = stencil_test_dirty_reg; | ||
| 224 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_back_func_mask)] = stencil_test_dirty_reg; | ||
| 225 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_back_op_fail)] = stencil_test_dirty_reg; | ||
| 226 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_back_op_zfail)] = stencil_test_dirty_reg; | ||
| 227 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_back_op_zpass)] = stencil_test_dirty_reg; | ||
| 228 | dirty_pointers[MAXWELL3D_REG_INDEX(stencil_back_mask)] = stencil_test_dirty_reg; | ||
| 229 | |||
| 230 | // Color Mask | ||
| 231 | constexpr u8 color_mask_dirty_reg = DIRTY_REGS_POS(color_mask); | ||
| 232 | dirty_pointers[MAXWELL3D_REG_INDEX(color_mask_common)] = color_mask_dirty_reg; | ||
| 233 | set_block(MAXWELL3D_REG_INDEX(color_mask), sizeof(regs.color_mask) / sizeof(u32), | ||
| 234 | color_mask_dirty_reg); | ||
| 235 | // Blend State | ||
| 236 | constexpr u8 blend_state_dirty_reg = DIRTY_REGS_POS(blend_state); | ||
| 237 | set_block(MAXWELL3D_REG_INDEX(blend_color), sizeof(regs.blend_color) / sizeof(u32), | ||
| 238 | blend_state_dirty_reg); | ||
| 239 | dirty_pointers[MAXWELL3D_REG_INDEX(independent_blend_enable)] = blend_state_dirty_reg; | ||
| 240 | set_block(MAXWELL3D_REG_INDEX(blend), sizeof(regs.blend) / sizeof(u32), blend_state_dirty_reg); | ||
| 241 | set_block(MAXWELL3D_REG_INDEX(independent_blend), sizeof(regs.independent_blend) / sizeof(u32), | ||
| 242 | blend_state_dirty_reg); | ||
| 243 | |||
| 244 | // Scissor State | ||
| 245 | constexpr u8 scissor_test_dirty_reg = DIRTY_REGS_POS(scissor_test); | ||
| 246 | set_block(MAXWELL3D_REG_INDEX(scissor_test), sizeof(regs.scissor_test) / sizeof(u32), | ||
| 247 | scissor_test_dirty_reg); | ||
| 248 | |||
| 249 | // Polygon Offset | ||
| 250 | constexpr u8 polygon_offset_dirty_reg = DIRTY_REGS_POS(polygon_offset); | ||
| 251 | dirty_pointers[MAXWELL3D_REG_INDEX(polygon_offset_fill_enable)] = polygon_offset_dirty_reg; | ||
| 252 | dirty_pointers[MAXWELL3D_REG_INDEX(polygon_offset_line_enable)] = polygon_offset_dirty_reg; | ||
| 253 | dirty_pointers[MAXWELL3D_REG_INDEX(polygon_offset_point_enable)] = polygon_offset_dirty_reg; | ||
| 254 | dirty_pointers[MAXWELL3D_REG_INDEX(polygon_offset_units)] = polygon_offset_dirty_reg; | ||
| 255 | dirty_pointers[MAXWELL3D_REG_INDEX(polygon_offset_factor)] = polygon_offset_dirty_reg; | ||
| 256 | dirty_pointers[MAXWELL3D_REG_INDEX(polygon_offset_clamp)] = polygon_offset_dirty_reg; | ||
| 257 | |||
| 258 | // Depth bounds | ||
| 259 | constexpr u8 depth_bounds_values_dirty_reg = DIRTY_REGS_POS(depth_bounds_values); | ||
| 260 | dirty_pointers[MAXWELL3D_REG_INDEX(depth_bounds[0])] = depth_bounds_values_dirty_reg; | ||
| 261 | dirty_pointers[MAXWELL3D_REG_INDEX(depth_bounds[1])] = depth_bounds_values_dirty_reg; | ||
| 262 | } | ||
| 263 | |||
| 264 | void Maxwell3D::CallMacroMethod(u32 method, std::size_t num_parameters, const u32* parameters) { | 105 | void Maxwell3D::CallMacroMethod(u32 method, std::size_t num_parameters, const u32* parameters) { |
| 265 | // Reset the current macro. | 106 | // Reset the current macro. |
| 266 | executing_macro = 0; | 107 | executing_macro = 0; |
| @@ -317,23 +158,7 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { | |||
| 317 | ASSERT_MSG(method < Regs::NUM_REGS, | 158 | ASSERT_MSG(method < Regs::NUM_REGS, |
| 318 | "Invalid Maxwell3D register, increase the size of the Regs structure"); | 159 | "Invalid Maxwell3D register, increase the size of the Regs structure"); |
| 319 | 160 | ||
| 320 | if (regs.reg_array[method] != method_call.argument) { | 161 | regs.reg_array[method] = method_call.argument; |
| 321 | regs.reg_array[method] = method_call.argument; | ||
| 322 | const std::size_t dirty_reg = dirty_pointers[method]; | ||
| 323 | if (dirty_reg) { | ||
| 324 | dirty.regs[dirty_reg] = true; | ||
| 325 | if (dirty_reg >= DIRTY_REGS_POS(vertex_array) && | ||
| 326 | dirty_reg < DIRTY_REGS_POS(vertex_array_buffers)) { | ||
| 327 | dirty.vertex_array_buffers = true; | ||
| 328 | } else if (dirty_reg >= DIRTY_REGS_POS(vertex_instance) && | ||
| 329 | dirty_reg < DIRTY_REGS_POS(vertex_instances)) { | ||
| 330 | dirty.vertex_instances = true; | ||
| 331 | } else if (dirty_reg >= DIRTY_REGS_POS(render_target) && | ||
| 332 | dirty_reg < DIRTY_REGS_POS(render_settings)) { | ||
| 333 | dirty.render_settings = true; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | } | ||
| 337 | 162 | ||
| 338 | switch (method) { | 163 | switch (method) { |
| 339 | case MAXWELL3D_REG_INDEX(macros.data): { | 164 | case MAXWELL3D_REG_INDEX(macros.data): { |
| @@ -418,9 +243,6 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { | |||
| 418 | case MAXWELL3D_REG_INDEX(data_upload): { | 243 | case MAXWELL3D_REG_INDEX(data_upload): { |
| 419 | const bool is_last_call = method_call.IsLastCall(); | 244 | const bool is_last_call = method_call.IsLastCall(); |
| 420 | upload_state.ProcessData(method_call.argument, is_last_call); | 245 | upload_state.ProcessData(method_call.argument, is_last_call); |
| 421 | if (is_last_call) { | ||
| 422 | dirty.OnMemoryWrite(); | ||
| 423 | } | ||
| 424 | break; | 246 | break; |
| 425 | } | 247 | } |
| 426 | default: | 248 | default: |
| @@ -727,7 +549,6 @@ void Maxwell3D::FinishCBData() { | |||
| 727 | 549 | ||
| 728 | const u32 id = cb_data_state.id; | 550 | const u32 id = cb_data_state.id; |
| 729 | memory_manager.WriteBlock(address, cb_data_state.buffer[id].data(), size); | 551 | memory_manager.WriteBlock(address, cb_data_state.buffer[id].data(), size); |
| 730 | dirty.OnMemoryWrite(); | ||
| 731 | 552 | ||
| 732 | cb_data_state.id = null_cb_data; | 553 | cb_data_state.id = null_cb_data; |
| 733 | cb_data_state.current = null_cb_data; | 554 | cb_data_state.current = null_cb_data; |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 6ea7cc6a5..3a641c182 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -1238,79 +1238,6 @@ public: | |||
| 1238 | 1238 | ||
| 1239 | State state{}; | 1239 | State state{}; |
| 1240 | 1240 | ||
| 1241 | struct DirtyRegs { | ||
| 1242 | static constexpr std::size_t NUM_REGS = 256; | ||
| 1243 | static_assert(NUM_REGS - 1 <= std::numeric_limits<u8>::max()); | ||
| 1244 | |||
| 1245 | union { | ||
| 1246 | struct { | ||
| 1247 | bool null_dirty; | ||
| 1248 | |||
| 1249 | // Vertex Attributes | ||
| 1250 | bool vertex_attrib_format; | ||
| 1251 | |||
| 1252 | // Vertex Arrays | ||
| 1253 | std::array<bool, 32> vertex_array; | ||
| 1254 | |||
| 1255 | bool vertex_array_buffers; | ||
| 1256 | |||
| 1257 | // Vertex Instances | ||
| 1258 | std::array<bool, 32> vertex_instance; | ||
| 1259 | |||
| 1260 | bool vertex_instances; | ||
| 1261 | |||
| 1262 | // Render Targets | ||
| 1263 | std::array<bool, 8> render_target; | ||
| 1264 | bool depth_buffer; | ||
| 1265 | |||
| 1266 | bool render_settings; | ||
| 1267 | |||
| 1268 | // Shaders | ||
| 1269 | bool shaders; | ||
| 1270 | |||
| 1271 | // Rasterizer State | ||
| 1272 | bool viewport; | ||
| 1273 | bool clip_coefficient; | ||
| 1274 | bool cull_mode; | ||
| 1275 | bool primitive_restart; | ||
| 1276 | bool depth_test; | ||
| 1277 | bool stencil_test; | ||
| 1278 | bool blend_state; | ||
| 1279 | bool scissor_test; | ||
| 1280 | bool transform_feedback; | ||
| 1281 | bool color_mask; | ||
| 1282 | bool polygon_offset; | ||
| 1283 | bool depth_bounds_values; | ||
| 1284 | |||
| 1285 | // Complementary | ||
| 1286 | bool viewport_transform; | ||
| 1287 | bool screen_y_control; | ||
| 1288 | |||
| 1289 | bool memory_general; | ||
| 1290 | }; | ||
| 1291 | std::array<bool, NUM_REGS> regs; | ||
| 1292 | }; | ||
| 1293 | |||
| 1294 | void ResetVertexArrays() { | ||
| 1295 | vertex_array.fill(true); | ||
| 1296 | vertex_array_buffers = true; | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | void ResetRenderTargets() { | ||
| 1300 | depth_buffer = true; | ||
| 1301 | render_target.fill(true); | ||
| 1302 | render_settings = true; | ||
| 1303 | } | ||
| 1304 | |||
| 1305 | void OnMemoryWrite() { | ||
| 1306 | shaders = true; | ||
| 1307 | memory_general = true; | ||
| 1308 | ResetRenderTargets(); | ||
| 1309 | ResetVertexArrays(); | ||
| 1310 | } | ||
| 1311 | |||
| 1312 | } dirty{}; | ||
| 1313 | |||
| 1314 | /// Reads a register value located at the input method address | 1241 | /// Reads a register value located at the input method address |
| 1315 | u32 GetRegisterValue(u32 method) const; | 1242 | u32 GetRegisterValue(u32 method) const; |
| 1316 | 1243 | ||
| @@ -1417,8 +1344,6 @@ private: | |||
| 1417 | /// Retrieves information about a specific TSC entry from the TSC buffer. | 1344 | /// Retrieves information about a specific TSC entry from the TSC buffer. |
| 1418 | Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; | 1345 | Texture::TSCEntry GetTSCEntry(u32 tsc_index) const; |
| 1419 | 1346 | ||
| 1420 | void InitDirtySettings(); | ||
| 1421 | |||
| 1422 | /** | 1347 | /** |
| 1423 | * Call a macro on this engine. | 1348 | * Call a macro on this engine. |
| 1424 | * @param method Method to call | 1349 | * @param method Method to call |
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index ad8453c5f..ae51765a6 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp | |||
| @@ -56,9 +56,6 @@ void MaxwellDMA::HandleCopy() { | |||
| 56 | return; | 56 | return; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | // All copies here update the main memory, so mark all rasterizer states as invalid. | ||
| 60 | system.GPU().Maxwell3D().dirty.OnMemoryWrite(); | ||
| 61 | |||
| 62 | if (regs.exec.is_dst_linear && regs.exec.is_src_linear) { | 59 | if (regs.exec.is_dst_linear && regs.exec.is_src_linear) { |
| 63 | // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D | 60 | // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D |
| 64 | // buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count, | 61 | // buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count, |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e1965fb21..1d203fd08 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -117,11 +117,6 @@ GLuint RasterizerOpenGL::SetupVertexFormat() { | |||
| 117 | auto& gpu = system.GPU().Maxwell3D(); | 117 | auto& gpu = system.GPU().Maxwell3D(); |
| 118 | const auto& regs = gpu.regs; | 118 | const auto& regs = gpu.regs; |
| 119 | 119 | ||
| 120 | if (!gpu.dirty.vertex_attrib_format) { | ||
| 121 | return state.draw.vertex_array; | ||
| 122 | } | ||
| 123 | gpu.dirty.vertex_attrib_format = false; | ||
| 124 | |||
| 125 | MICROPROFILE_SCOPE(OpenGL_VAO); | 120 | MICROPROFILE_SCOPE(OpenGL_VAO); |
| 126 | 121 | ||
| 127 | auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); | 122 | auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); |
| @@ -173,30 +168,18 @@ GLuint RasterizerOpenGL::SetupVertexFormat() { | |||
| 173 | } | 168 | } |
| 174 | } | 169 | } |
| 175 | 170 | ||
| 176 | // Rebinding the VAO invalidates the vertex buffer bindings. | ||
| 177 | gpu.dirty.ResetVertexArrays(); | ||
| 178 | |||
| 179 | state.draw.vertex_array = vao_entry.handle; | 171 | state.draw.vertex_array = vao_entry.handle; |
| 180 | return vao_entry.handle; | 172 | return vao_entry.handle; |
| 181 | } | 173 | } |
| 182 | 174 | ||
| 183 | void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { | 175 | void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { |
| 184 | auto& gpu = system.GPU().Maxwell3D(); | 176 | auto& gpu = system.GPU().Maxwell3D(); |
| 185 | if (!gpu.dirty.vertex_array_buffers) | ||
| 186 | return; | ||
| 187 | gpu.dirty.vertex_array_buffers = false; | ||
| 188 | |||
| 189 | const auto& regs = gpu.regs; | 177 | const auto& regs = gpu.regs; |
| 190 | 178 | ||
| 191 | MICROPROFILE_SCOPE(OpenGL_VB); | 179 | MICROPROFILE_SCOPE(OpenGL_VB); |
| 192 | 180 | ||
| 193 | // Upload all guest vertex arrays sequentially to our buffer | 181 | // Upload all guest vertex arrays sequentially to our buffer |
| 194 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { | 182 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { |
| 195 | if (!gpu.dirty.vertex_array[index]) | ||
| 196 | continue; | ||
| 197 | gpu.dirty.vertex_array[index] = false; | ||
| 198 | gpu.dirty.vertex_instance[index] = false; | ||
| 199 | |||
| 200 | const auto& vertex_array = regs.vertex_array[index]; | 183 | const auto& vertex_array = regs.vertex_array[index]; |
| 201 | if (!vertex_array.IsEnabled()) | 184 | if (!vertex_array.IsEnabled()) |
| 202 | continue; | 185 | continue; |
| @@ -224,19 +207,10 @@ void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) { | |||
| 224 | 207 | ||
| 225 | void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { | 208 | void RasterizerOpenGL::SetupVertexInstances(GLuint vao) { |
| 226 | auto& gpu = system.GPU().Maxwell3D(); | 209 | auto& gpu = system.GPU().Maxwell3D(); |
| 227 | |||
| 228 | if (!gpu.dirty.vertex_instances) | ||
| 229 | return; | ||
| 230 | gpu.dirty.vertex_instances = false; | ||
| 231 | |||
| 232 | const auto& regs = gpu.regs; | 210 | const auto& regs = gpu.regs; |
| 233 | // Upload all guest vertex arrays sequentially to our buffer | ||
| 234 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { | ||
| 235 | if (!gpu.dirty.vertex_instance[index]) | ||
| 236 | continue; | ||
| 237 | |||
| 238 | gpu.dirty.vertex_instance[index] = false; | ||
| 239 | 211 | ||
| 212 | // Upload all guest vertex arrays sequentially to our buffer | ||
| 213 | for (u32 index = 0; index < 16; ++index) { | ||
| 240 | if (regs.instanced_arrays.IsInstancingEnabled(index) && | 214 | if (regs.instanced_arrays.IsInstancingEnabled(index) && |
| 241 | regs.vertex_array[index].divisor != 0) { | 215 | regs.vertex_array[index].divisor != 0) { |
| 242 | // Enable vertex buffer instancing with the specified divisor. | 216 | // Enable vertex buffer instancing with the specified divisor. |
| @@ -334,8 +308,6 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 334 | } | 308 | } |
| 335 | 309 | ||
| 336 | SyncClipEnabled(clip_distances); | 310 | SyncClipEnabled(clip_distances); |
| 337 | |||
| 338 | gpu.dirty.shaders = false; | ||
| 339 | } | 311 | } |
| 340 | 312 | ||
| 341 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | 313 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { |
| @@ -371,10 +343,6 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading, | |||
| 371 | void RasterizerOpenGL::ConfigureFramebuffers() { | 343 | void RasterizerOpenGL::ConfigureFramebuffers() { |
| 372 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); | 344 | MICROPROFILE_SCOPE(OpenGL_Framebuffer); |
| 373 | auto& gpu = system.GPU().Maxwell3D(); | 345 | auto& gpu = system.GPU().Maxwell3D(); |
| 374 | if (!gpu.dirty.render_settings) { | ||
| 375 | return; | ||
| 376 | } | ||
| 377 | gpu.dirty.render_settings = false; | ||
| 378 | 346 | ||
| 379 | texture_cache.GuardRenderTargets(true); | 347 | texture_cache.GuardRenderTargets(true); |
| 380 | 348 | ||
| @@ -453,7 +421,6 @@ void RasterizerOpenGL::Clear() { | |||
| 453 | 421 | ||
| 454 | OpenGLState prev_state{OpenGLState::GetCurState()}; | 422 | OpenGLState prev_state{OpenGLState::GetCurState()}; |
| 455 | SCOPE_EXIT({ | 423 | SCOPE_EXIT({ |
| 456 | prev_state.AllDirty(); | ||
| 457 | prev_state.Apply(); | 424 | prev_state.Apply(); |
| 458 | }); | 425 | }); |
| 459 | 426 | ||
| @@ -528,7 +495,6 @@ void RasterizerOpenGL::Clear() { | |||
| 528 | clear_state.EmulateViewportWithScissor(); | 495 | clear_state.EmulateViewportWithScissor(); |
| 529 | } | 496 | } |
| 530 | 497 | ||
| 531 | clear_state.AllDirty(); | ||
| 532 | clear_state.Apply(); | 498 | clear_state.Apply(); |
| 533 | 499 | ||
| 534 | if (use_color) { | 500 | if (use_color) { |
| @@ -631,12 +597,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) { | |||
| 631 | bind_ubo_pushbuffer.Bind(); | 597 | bind_ubo_pushbuffer.Bind(); |
| 632 | bind_ssbo_pushbuffer.Bind(); | 598 | bind_ssbo_pushbuffer.Bind(); |
| 633 | 599 | ||
| 634 | if (invalidate) { | ||
| 635 | // As all cached buffers are invalidated, we need to recheck their state. | ||
| 636 | gpu.dirty.ResetVertexArrays(); | ||
| 637 | } | ||
| 638 | gpu.dirty.memory_general = false; | ||
| 639 | |||
| 640 | shader_program_manager->ApplyTo(state); | 600 | shader_program_manager->ApplyTo(state); |
| 641 | state.Apply(); | 601 | state.Apply(); |
| 642 | 602 | ||
| @@ -1084,14 +1044,8 @@ void RasterizerOpenGL::SyncDepthTestState() { | |||
| 1084 | 1044 | ||
| 1085 | void RasterizerOpenGL::SyncStencilTestState() { | 1045 | void RasterizerOpenGL::SyncStencilTestState() { |
| 1086 | auto& maxwell3d = system.GPU().Maxwell3D(); | 1046 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 1087 | if (!maxwell3d.dirty.stencil_test) { | ||
| 1088 | return; | ||
| 1089 | } | ||
| 1090 | maxwell3d.dirty.stencil_test = false; | ||
| 1091 | |||
| 1092 | const auto& regs = maxwell3d.regs; | 1047 | const auto& regs = maxwell3d.regs; |
| 1093 | state.stencil.test_enabled = regs.stencil_enable != 0; | 1048 | state.stencil.test_enabled = regs.stencil_enable != 0; |
| 1094 | state.MarkDirtyStencilState(); | ||
| 1095 | 1049 | ||
| 1096 | if (!regs.stencil_enable) { | 1050 | if (!regs.stencil_enable) { |
| 1097 | return; | 1051 | return; |
| @@ -1130,9 +1084,6 @@ void RasterizerOpenGL::SyncRasterizeEnable(OpenGLState& current_state) { | |||
| 1130 | 1084 | ||
| 1131 | void RasterizerOpenGL::SyncColorMask() { | 1085 | void RasterizerOpenGL::SyncColorMask() { |
| 1132 | auto& maxwell3d = system.GPU().Maxwell3D(); | 1086 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 1133 | if (!maxwell3d.dirty.color_mask) { | ||
| 1134 | return; | ||
| 1135 | } | ||
| 1136 | const auto& regs = maxwell3d.regs; | 1087 | const auto& regs = maxwell3d.regs; |
| 1137 | 1088 | ||
| 1138 | const std::size_t count = | 1089 | const std::size_t count = |
| @@ -1145,9 +1096,6 @@ void RasterizerOpenGL::SyncColorMask() { | |||
| 1145 | dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE; | 1096 | dest.blue_enabled = (source.B == 0) ? GL_FALSE : GL_TRUE; |
| 1146 | dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE; | 1097 | dest.alpha_enabled = (source.A == 0) ? GL_FALSE : GL_TRUE; |
| 1147 | } | 1098 | } |
| 1148 | |||
| 1149 | state.MarkDirtyColorMask(); | ||
| 1150 | maxwell3d.dirty.color_mask = false; | ||
| 1151 | } | 1099 | } |
| 1152 | 1100 | ||
| 1153 | void RasterizerOpenGL::SyncMultiSampleState() { | 1101 | void RasterizerOpenGL::SyncMultiSampleState() { |
| @@ -1163,9 +1111,6 @@ void RasterizerOpenGL::SyncFragmentColorClampState() { | |||
| 1163 | 1111 | ||
| 1164 | void RasterizerOpenGL::SyncBlendState() { | 1112 | void RasterizerOpenGL::SyncBlendState() { |
| 1165 | auto& maxwell3d = system.GPU().Maxwell3D(); | 1113 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 1166 | if (!maxwell3d.dirty.blend_state) { | ||
| 1167 | return; | ||
| 1168 | } | ||
| 1169 | const auto& regs = maxwell3d.regs; | 1114 | const auto& regs = maxwell3d.regs; |
| 1170 | 1115 | ||
| 1171 | state.blend_color.red = regs.blend_color.r; | 1116 | state.blend_color.red = regs.blend_color.r; |
| @@ -1189,8 +1134,6 @@ void RasterizerOpenGL::SyncBlendState() { | |||
| 1189 | for (std::size_t i = 1; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { | 1134 | for (std::size_t i = 1; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { |
| 1190 | state.blend[i].enabled = false; | 1135 | state.blend[i].enabled = false; |
| 1191 | } | 1136 | } |
| 1192 | maxwell3d.dirty.blend_state = false; | ||
| 1193 | state.MarkDirtyBlendState(); | ||
| 1194 | return; | 1137 | return; |
| 1195 | } | 1138 | } |
| 1196 | 1139 | ||
| @@ -1207,9 +1150,6 @@ void RasterizerOpenGL::SyncBlendState() { | |||
| 1207 | blend.src_a_func = MaxwellToGL::BlendFunc(src.factor_source_a); | 1150 | blend.src_a_func = MaxwellToGL::BlendFunc(src.factor_source_a); |
| 1208 | blend.dst_a_func = MaxwellToGL::BlendFunc(src.factor_dest_a); | 1151 | blend.dst_a_func = MaxwellToGL::BlendFunc(src.factor_dest_a); |
| 1209 | } | 1152 | } |
| 1210 | |||
| 1211 | state.MarkDirtyBlendState(); | ||
| 1212 | maxwell3d.dirty.blend_state = false; | ||
| 1213 | } | 1153 | } |
| 1214 | 1154 | ||
| 1215 | void RasterizerOpenGL::SyncLogicOpState() { | 1155 | void RasterizerOpenGL::SyncLogicOpState() { |
| @@ -1264,9 +1204,6 @@ void RasterizerOpenGL::SyncPointState() { | |||
| 1264 | 1204 | ||
| 1265 | void RasterizerOpenGL::SyncPolygonOffset() { | 1205 | void RasterizerOpenGL::SyncPolygonOffset() { |
| 1266 | auto& maxwell3d = system.GPU().Maxwell3D(); | 1206 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 1267 | if (!maxwell3d.dirty.polygon_offset) { | ||
| 1268 | return; | ||
| 1269 | } | ||
| 1270 | const auto& regs = maxwell3d.regs; | 1207 | const auto& regs = maxwell3d.regs; |
| 1271 | 1208 | ||
| 1272 | state.polygon_offset.fill_enable = regs.polygon_offset_fill_enable != 0; | 1209 | state.polygon_offset.fill_enable = regs.polygon_offset_fill_enable != 0; |
| @@ -1277,9 +1214,6 @@ void RasterizerOpenGL::SyncPolygonOffset() { | |||
| 1277 | state.polygon_offset.units = regs.polygon_offset_units / 2.0f; | 1214 | state.polygon_offset.units = regs.polygon_offset_units / 2.0f; |
| 1278 | state.polygon_offset.factor = regs.polygon_offset_factor; | 1215 | state.polygon_offset.factor = regs.polygon_offset_factor; |
| 1279 | state.polygon_offset.clamp = regs.polygon_offset_clamp; | 1216 | state.polygon_offset.clamp = regs.polygon_offset_clamp; |
| 1280 | |||
| 1281 | state.MarkDirtyPolygonOffset(); | ||
| 1282 | maxwell3d.dirty.polygon_offset = false; | ||
| 1283 | } | 1217 | } |
| 1284 | 1218 | ||
| 1285 | void RasterizerOpenGL::SyncAlphaTest() { | 1219 | void RasterizerOpenGL::SyncAlphaTest() { |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 489eb143c..bef141f63 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -623,10 +623,6 @@ bool ShaderCacheOpenGL::GenerateUnspecializedShaders( | |||
| 623 | } | 623 | } |
| 624 | 624 | ||
| 625 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | 625 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { |
| 626 | if (!system.GPU().Maxwell3D().dirty.shaders) { | ||
| 627 | return last_shaders[static_cast<std::size_t>(program)]; | ||
| 628 | } | ||
| 629 | |||
| 630 | auto& memory_manager{system.GPU().MemoryManager()}; | 626 | auto& memory_manager{system.GPU().MemoryManager()}; |
| 631 | const GPUVAddr address{GetShaderAddress(system, program)}; | 627 | const GPUVAddr address{GetShaderAddress(system, program)}; |
| 632 | 628 | ||
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 7d3bc1a1f..732cb3a3c 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -189,11 +189,6 @@ void OpenGLState::ApplyRasterizerDiscard() { | |||
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | void OpenGLState::ApplyColorMask() { | 191 | void OpenGLState::ApplyColorMask() { |
| 192 | if (!dirty.color_mask) { | ||
| 193 | return; | ||
| 194 | } | ||
| 195 | dirty.color_mask = false; | ||
| 196 | |||
| 197 | for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { | 192 | for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { |
| 198 | const auto& updated = color_mask[i]; | 193 | const auto& updated = color_mask[i]; |
| 199 | auto& current = cur_state.color_mask[i]; | 194 | auto& current = cur_state.color_mask[i]; |
| @@ -232,11 +227,6 @@ void OpenGLState::ApplyPrimitiveRestart() { | |||
| 232 | } | 227 | } |
| 233 | 228 | ||
| 234 | void OpenGLState::ApplyStencilTest() { | 229 | void OpenGLState::ApplyStencilTest() { |
| 235 | if (!dirty.stencil_state) { | ||
| 236 | return; | ||
| 237 | } | ||
| 238 | dirty.stencil_state = false; | ||
| 239 | |||
| 240 | Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled); | 230 | Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled); |
| 241 | 231 | ||
| 242 | const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) { | 232 | const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) { |
| @@ -351,11 +341,6 @@ void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) { | |||
| 351 | } | 341 | } |
| 352 | 342 | ||
| 353 | void OpenGLState::ApplyBlending() { | 343 | void OpenGLState::ApplyBlending() { |
| 354 | if (!dirty.blend_state) { | ||
| 355 | return; | ||
| 356 | } | ||
| 357 | dirty.blend_state = false; | ||
| 358 | |||
| 359 | if (independant_blend.enabled) { | 344 | if (independant_blend.enabled) { |
| 360 | const bool force = independant_blend.enabled != cur_state.independant_blend.enabled; | 345 | const bool force = independant_blend.enabled != cur_state.independant_blend.enabled; |
| 361 | for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) { | 346 | for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) { |
| @@ -383,11 +368,6 @@ void OpenGLState::ApplyLogicOp() { | |||
| 383 | } | 368 | } |
| 384 | 369 | ||
| 385 | void OpenGLState::ApplyPolygonOffset() { | 370 | void OpenGLState::ApplyPolygonOffset() { |
| 386 | if (!dirty.polygon_offset) { | ||
| 387 | return; | ||
| 388 | } | ||
| 389 | dirty.polygon_offset = false; | ||
| 390 | |||
| 391 | Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable, | 371 | Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable, |
| 392 | polygon_offset.fill_enable); | 372 | polygon_offset.fill_enable); |
| 393 | Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable, | 373 | Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable, |
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index bce662f2c..5dda9e88f 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -212,39 +212,8 @@ public: | |||
| 212 | /// Viewport does not affects glClearBuffer so emulate viewport using scissor test | 212 | /// Viewport does not affects glClearBuffer so emulate viewport using scissor test |
| 213 | void EmulateViewportWithScissor(); | 213 | void EmulateViewportWithScissor(); |
| 214 | 214 | ||
| 215 | void MarkDirtyBlendState() { | ||
| 216 | dirty.blend_state = true; | ||
| 217 | } | ||
| 218 | |||
| 219 | void MarkDirtyStencilState() { | ||
| 220 | dirty.stencil_state = true; | ||
| 221 | } | ||
| 222 | |||
| 223 | void MarkDirtyPolygonOffset() { | ||
| 224 | dirty.polygon_offset = true; | ||
| 225 | } | ||
| 226 | |||
| 227 | void MarkDirtyColorMask() { | ||
| 228 | dirty.color_mask = true; | ||
| 229 | } | ||
| 230 | |||
| 231 | void AllDirty() { | ||
| 232 | dirty.blend_state = true; | ||
| 233 | dirty.stencil_state = true; | ||
| 234 | dirty.polygon_offset = true; | ||
| 235 | dirty.color_mask = true; | ||
| 236 | } | ||
| 237 | |||
| 238 | private: | 215 | private: |
| 239 | static OpenGLState cur_state; | 216 | static OpenGLState cur_state; |
| 240 | |||
| 241 | struct { | ||
| 242 | bool blend_state; | ||
| 243 | bool stencil_state; | ||
| 244 | bool viewport_state; | ||
| 245 | bool polygon_offset; | ||
| 246 | bool color_mask; | ||
| 247 | } dirty{}; | ||
| 248 | }; | 217 | }; |
| 249 | static_assert(std::is_trivially_copyable_v<OpenGLState>); | 218 | static_assert(std::is_trivially_copyable_v<OpenGLState>); |
| 250 | 219 | ||
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp | |||
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/video_core/renderer_opengl/gl_state_tracker.h | |||
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index cf934b0d8..942cc6c0a 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -522,7 +522,6 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view, | |||
| 522 | 522 | ||
| 523 | OpenGLState prev_state{OpenGLState::GetCurState()}; | 523 | OpenGLState prev_state{OpenGLState::GetCurState()}; |
| 524 | SCOPE_EXIT({ | 524 | SCOPE_EXIT({ |
| 525 | prev_state.AllDirty(); | ||
| 526 | prev_state.Apply(); | 525 | prev_state.Apply(); |
| 527 | }); | 526 | }); |
| 528 | 527 | ||
| @@ -530,7 +529,6 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view, | |||
| 530 | state.draw.read_framebuffer = src_framebuffer.handle; | 529 | state.draw.read_framebuffer = src_framebuffer.handle; |
| 531 | state.draw.draw_framebuffer = dst_framebuffer.handle; | 530 | state.draw.draw_framebuffer = dst_framebuffer.handle; |
| 532 | state.framebuffer_srgb.enabled = dst_params.srgb_conversion; | 531 | state.framebuffer_srgb.enabled = dst_params.srgb_conversion; |
| 533 | state.AllDirty(); | ||
| 534 | state.Apply(); | 532 | state.Apply(); |
| 535 | 533 | ||
| 536 | u32 buffers{}; | 534 | u32 buffers{}; |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index a4340b502..f71e23f9e 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -311,11 +311,6 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 311 | return; | 311 | return; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | // Maintain the rasterizer's state as a priority | ||
| 315 | OpenGLState prev_state = OpenGLState::GetCurState(); | ||
| 316 | state.AllDirty(); | ||
| 317 | state.Apply(); | ||
| 318 | |||
| 319 | PrepareRendertarget(framebuffer); | 314 | PrepareRendertarget(framebuffer); |
| 320 | RenderScreenshot(); | 315 | RenderScreenshot(); |
| 321 | 316 | ||
| @@ -368,10 +363,6 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 368 | m_current_frame++; | 363 | m_current_frame++; |
| 369 | rasterizer->TickFrame(); | 364 | rasterizer->TickFrame(); |
| 370 | } | 365 | } |
| 371 | |||
| 372 | // Restore the rasterizer state | ||
| 373 | prev_state.AllDirty(); | ||
| 374 | prev_state.Apply(); | ||
| 375 | } | 366 | } |
| 376 | 367 | ||
| 377 | void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) { | 368 | void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) { |
| @@ -445,7 +436,6 @@ void RendererOpenGL::InitOpenGLObjects() { | |||
| 445 | // Link shaders and get variable locations | 436 | // Link shaders and get variable locations |
| 446 | shader.CreateFromSource(vertex_shader, nullptr, fragment_shader); | 437 | shader.CreateFromSource(vertex_shader, nullptr, fragment_shader); |
| 447 | state.draw.shader_program = shader.handle; | 438 | state.draw.shader_program = shader.handle; |
| 448 | state.AllDirty(); | ||
| 449 | state.Apply(); | 439 | state.Apply(); |
| 450 | 440 | ||
| 451 | // Generate VBO handle for drawing | 441 | // Generate VBO handle for drawing |
| @@ -580,14 +570,12 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, | |||
| 580 | 570 | ||
| 581 | state.textures[0] = screen_info.display_texture; | 571 | state.textures[0] = screen_info.display_texture; |
| 582 | state.framebuffer_srgb.enabled = screen_info.display_srgb; | 572 | state.framebuffer_srgb.enabled = screen_info.display_srgb; |
| 583 | state.AllDirty(); | ||
| 584 | state.Apply(); | 573 | state.Apply(); |
| 585 | glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); | 574 | glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); |
| 586 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | 575 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| 587 | // Restore default state | 576 | // Restore default state |
| 588 | state.framebuffer_srgb.enabled = false; | 577 | state.framebuffer_srgb.enabled = false; |
| 589 | state.textures[0] = 0; | 578 | state.textures[0] = 0; |
| 590 | state.AllDirty(); | ||
| 591 | state.Apply(); | 579 | state.Apply(); |
| 592 | } | 580 | } |
| 593 | 581 | ||
| @@ -658,7 +646,6 @@ void RendererOpenGL::RenderScreenshot() { | |||
| 658 | GLuint old_read_fb = state.draw.read_framebuffer; | 646 | GLuint old_read_fb = state.draw.read_framebuffer; |
| 659 | GLuint old_draw_fb = state.draw.draw_framebuffer; | 647 | GLuint old_draw_fb = state.draw.draw_framebuffer; |
| 660 | state.draw.read_framebuffer = state.draw.draw_framebuffer = screenshot_framebuffer.handle; | 648 | state.draw.read_framebuffer = state.draw.draw_framebuffer = screenshot_framebuffer.handle; |
| 661 | state.AllDirty(); | ||
| 662 | state.Apply(); | 649 | state.Apply(); |
| 663 | 650 | ||
| 664 | Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout}; | 651 | Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout}; |
| @@ -678,7 +665,6 @@ void RendererOpenGL::RenderScreenshot() { | |||
| 678 | screenshot_framebuffer.Release(); | 665 | screenshot_framebuffer.Release(); |
| 679 | state.draw.read_framebuffer = old_read_fb; | 666 | state.draw.read_framebuffer = old_read_fb; |
| 680 | state.draw.draw_framebuffer = old_draw_fb; | 667 | state.draw.draw_framebuffer = old_draw_fb; |
| 681 | state.AllDirty(); | ||
| 682 | state.Apply(); | 668 | state.Apply(); |
| 683 | glDeleteRenderbuffers(1, &renderbuffer); | 669 | glDeleteRenderbuffers(1, &renderbuffer); |
| 684 | 670 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 7ddf7d3ee..8186942da 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -172,11 +172,6 @@ VKPipelineCache::~VKPipelineCache() = default; | |||
| 172 | 172 | ||
| 173 | std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { | 173 | std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { |
| 174 | const auto& gpu = system.GPU().Maxwell3D(); | 174 | const auto& gpu = system.GPU().Maxwell3D(); |
| 175 | auto& dirty = system.GPU().Maxwell3D().dirty.shaders; | ||
| 176 | if (!dirty) { | ||
| 177 | return last_shaders; | ||
| 178 | } | ||
| 179 | dirty = false; | ||
| 180 | 175 | ||
| 181 | std::array<Shader, Maxwell::MaxShaderProgram> shaders; | 176 | std::array<Shader, Maxwell::MaxShaderProgram> shaders; |
| 182 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 177 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 3bf86da87..b1be41a21 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -568,9 +568,7 @@ void RasterizerVulkan::FlushWork() { | |||
| 568 | 568 | ||
| 569 | RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { | 569 | RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { |
| 570 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); | 570 | MICROPROFILE_SCOPE(Vulkan_RenderTargets); |
| 571 | auto& dirty = system.GPU().Maxwell3D().dirty; | 571 | constexpr bool update_rendertargets = true; |
| 572 | const bool update_rendertargets = dirty.render_settings; | ||
| 573 | dirty.render_settings = false; | ||
| 574 | 572 | ||
| 575 | texture_cache.GuardRenderTargets(true); | 573 | texture_cache.GuardRenderTargets(true); |
| 576 | 574 | ||
| @@ -973,10 +971,6 @@ void RasterizerVulkan::SetupImage(const Tegra::Texture::TICEntry& tic, const Ima | |||
| 973 | } | 971 | } |
| 974 | 972 | ||
| 975 | void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { | 973 | void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { |
| 976 | if (!gpu.dirty.viewport_transform && scheduler.TouchViewports()) { | ||
| 977 | return; | ||
| 978 | } | ||
| 979 | gpu.dirty.viewport_transform = false; | ||
| 980 | const auto& regs = gpu.regs; | 974 | const auto& regs = gpu.regs; |
| 981 | const std::array viewports{ | 975 | const std::array viewports{ |
| 982 | GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), | 976 | GetViewportState(device, regs, 0), GetViewportState(device, regs, 1), |
| @@ -993,10 +987,6 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D& gpu) { | |||
| 993 | } | 987 | } |
| 994 | 988 | ||
| 995 | void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { | 989 | void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { |
| 996 | if (!gpu.dirty.scissor_test && scheduler.TouchScissors()) { | ||
| 997 | return; | ||
| 998 | } | ||
| 999 | gpu.dirty.scissor_test = false; | ||
| 1000 | const auto& regs = gpu.regs; | 990 | const auto& regs = gpu.regs; |
| 1001 | const std::array scissors = { | 991 | const std::array scissors = { |
| 1002 | GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), | 992 | GetScissorState(regs, 0), GetScissorState(regs, 1), GetScissorState(regs, 2), |
| @@ -1011,10 +1001,6 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D& gpu) { | |||
| 1011 | } | 1001 | } |
| 1012 | 1002 | ||
| 1013 | void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { | 1003 | void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { |
| 1014 | if (!gpu.dirty.polygon_offset && scheduler.TouchDepthBias()) { | ||
| 1015 | return; | ||
| 1016 | } | ||
| 1017 | gpu.dirty.polygon_offset = false; | ||
| 1018 | const auto& regs = gpu.regs; | 1004 | const auto& regs = gpu.regs; |
| 1019 | scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, | 1005 | scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, |
| 1020 | factor = regs.polygon_offset_factor](auto cmdbuf, auto& dld) { | 1006 | factor = regs.polygon_offset_factor](auto cmdbuf, auto& dld) { |
| @@ -1023,10 +1009,6 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D& gpu) { | |||
| 1023 | } | 1009 | } |
| 1024 | 1010 | ||
| 1025 | void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { | 1011 | void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { |
| 1026 | if (!gpu.dirty.blend_state && scheduler.TouchBlendConstants()) { | ||
| 1027 | return; | ||
| 1028 | } | ||
| 1029 | gpu.dirty.blend_state = false; | ||
| 1030 | const std::array blend_color = {gpu.regs.blend_color.r, gpu.regs.blend_color.g, | 1012 | const std::array blend_color = {gpu.regs.blend_color.r, gpu.regs.blend_color.g, |
| 1031 | gpu.regs.blend_color.b, gpu.regs.blend_color.a}; | 1013 | gpu.regs.blend_color.b, gpu.regs.blend_color.a}; |
| 1032 | scheduler.Record([blend_color](auto cmdbuf, auto& dld) { | 1014 | scheduler.Record([blend_color](auto cmdbuf, auto& dld) { |
| @@ -1035,20 +1017,12 @@ void RasterizerVulkan::UpdateBlendConstants(Tegra::Engines::Maxwell3D& gpu) { | |||
| 1035 | } | 1017 | } |
| 1036 | 1018 | ||
| 1037 | void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu) { | 1019 | void RasterizerVulkan::UpdateDepthBounds(Tegra::Engines::Maxwell3D& gpu) { |
| 1038 | if (!gpu.dirty.depth_bounds_values && scheduler.TouchDepthBounds()) { | ||
| 1039 | return; | ||
| 1040 | } | ||
| 1041 | gpu.dirty.depth_bounds_values = false; | ||
| 1042 | const auto& regs = gpu.regs; | 1020 | const auto& regs = gpu.regs; |
| 1043 | scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( | 1021 | scheduler.Record([min = regs.depth_bounds[0], max = regs.depth_bounds[1]]( |
| 1044 | auto cmdbuf, auto& dld) { cmdbuf.setDepthBounds(min, max, dld); }); | 1022 | auto cmdbuf, auto& dld) { cmdbuf.setDepthBounds(min, max, dld); }); |
| 1045 | } | 1023 | } |
| 1046 | 1024 | ||
| 1047 | void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu) { | 1025 | void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D& gpu) { |
| 1048 | if (!gpu.dirty.stencil_test && scheduler.TouchStencilValues()) { | ||
| 1049 | return; | ||
| 1050 | } | ||
| 1051 | gpu.dirty.stencil_test = false; | ||
| 1052 | const auto& regs = gpu.regs; | 1026 | const auto& regs = gpu.regs; |
| 1053 | if (regs.stencil_two_side_enable) { | 1027 | if (regs.stencil_two_side_enable) { |
| 1054 | // Separate values per face | 1028 | // Separate values per face |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index c70e4aec2..ec6dfa49e 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -143,11 +143,6 @@ public: | |||
| 143 | std::lock_guard lock{mutex}; | 143 | std::lock_guard lock{mutex}; |
| 144 | auto& maxwell3d = system.GPU().Maxwell3D(); | 144 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 145 | 145 | ||
| 146 | if (!maxwell3d.dirty.depth_buffer) { | ||
| 147 | return depth_buffer.view; | ||
| 148 | } | ||
| 149 | maxwell3d.dirty.depth_buffer = false; | ||
| 150 | |||
| 151 | const auto& regs{maxwell3d.regs}; | 146 | const auto& regs{maxwell3d.regs}; |
| 152 | const auto gpu_addr{regs.zeta.Address()}; | 147 | const auto gpu_addr{regs.zeta.Address()}; |
| 153 | if (!gpu_addr || !regs.zeta_enable) { | 148 | if (!gpu_addr || !regs.zeta_enable) { |
| @@ -175,10 +170,6 @@ public: | |||
| 175 | std::lock_guard lock{mutex}; | 170 | std::lock_guard lock{mutex}; |
| 176 | ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); | 171 | ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); |
| 177 | auto& maxwell3d = system.GPU().Maxwell3D(); | 172 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 178 | if (!maxwell3d.dirty.render_target[index]) { | ||
| 179 | return render_targets[index].view; | ||
| 180 | } | ||
| 181 | maxwell3d.dirty.render_target[index] = false; | ||
| 182 | 173 | ||
| 183 | const auto& regs{maxwell3d.regs}; | 174 | const auto& regs{maxwell3d.regs}; |
| 184 | if (index >= regs.rt_control.count || regs.rt[index].Address() == 0 || | 175 | if (index >= regs.rt_control.count || regs.rt[index].Address() == 0 || |
| @@ -319,16 +310,7 @@ protected: | |||
| 319 | // and reading it from a separate buffer. | 310 | // and reading it from a separate buffer. |
| 320 | virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0; | 311 | virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0; |
| 321 | 312 | ||
| 322 | void ManageRenderTargetUnregister(TSurface& surface) { | 313 | void ManageRenderTargetUnregister([[maybe_unused]] TSurface& surface) {} |
| 323 | auto& maxwell3d = system.GPU().Maxwell3D(); | ||
| 324 | const u32 index = surface->GetRenderTarget(); | ||
| 325 | if (index == DEPTH_RT) { | ||
| 326 | maxwell3d.dirty.depth_buffer = true; | ||
| 327 | } else { | ||
| 328 | maxwell3d.dirty.render_target[index] = true; | ||
| 329 | } | ||
| 330 | maxwell3d.dirty.render_settings = true; | ||
| 331 | } | ||
| 332 | 314 | ||
| 333 | void Register(TSurface surface) { | 315 | void Register(TSurface surface) { |
| 334 | const GPUVAddr gpu_addr = surface->GetGpuAddr(); | 316 | const GPUVAddr gpu_addr = surface->GetGpuAddr(); |