summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Liam2022-11-16 22:41:40 -0500
committerGravatar Liam2022-11-17 08:31:43 -0500
commit4c42655a2defddcd8faacaaa4e0bf109693b5a9c (patch)
tree5ec83147c52c4542066585c8936c88ef5ab6c51a
parentmaxwell3d: HLE multi-layer clear macro (diff)
downloadyuzu-4c42655a2defddcd8faacaaa4e0bf109693b5a9c.tar.gz
yuzu-4c42655a2defddcd8faacaaa4e0bf109693b5a9c.tar.xz
yuzu-4c42655a2defddcd8faacaaa4e0bf109693b5a9c.zip
maxwell3d: full HLE for multi-layer clears
-rw-r--r--src/video_core/engines/maxwell_3d.cpp6
-rw-r--r--src/video_core/engines/maxwell_3d.h7
-rw-r--r--src/video_core/macro/macro_hle.cpp16
-rw-r--r--src/video_core/rasterizer_interface.h2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h2
8 files changed, 17 insertions, 24 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index d502d181c..5bb1427c1 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -232,7 +232,7 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
232 use_topology_override = true; 232 use_topology_override = true;
233 return; 233 return;
234 case MAXWELL3D_REG_INDEX(clear_surface): 234 case MAXWELL3D_REG_INDEX(clear_surface):
235 return ProcessClearBuffers(); 235 return ProcessClearBuffers(1);
236 case MAXWELL3D_REG_INDEX(report_semaphore.query): 236 case MAXWELL3D_REG_INDEX(report_semaphore.query):
237 return ProcessQueryGet(); 237 return ProcessQueryGet();
238 case MAXWELL3D_REG_INDEX(render_enable.mode): 238 case MAXWELL3D_REG_INDEX(render_enable.mode):
@@ -596,8 +596,8 @@ u32 Maxwell3D::GetRegisterValue(u32 method) const {
596 return regs.reg_array[method]; 596 return regs.reg_array[method];
597} 597}
598 598
599void Maxwell3D::ProcessClearBuffers() { 599void Maxwell3D::ProcessClearBuffers(u32 layer_count) {
600 rasterizer->Clear(); 600 rasterizer->Clear(layer_count);
601} 601}
602 602
603void Maxwell3D::ProcessDraw(u32 instance_count) { 603void Maxwell3D::ProcessDraw(u32 instance_count) {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index f9cdfbc0b..c3099f9a6 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1129,7 +1129,6 @@ public:
1129 Tegra::RenderTargetFormat format; 1129 Tegra::RenderTargetFormat format;
1130 TileMode tile_mode; 1130 TileMode tile_mode;
1131 union { 1131 union {
1132 u32 depth_volume;
1133 BitField<0, 16, u32> depth; 1132 BitField<0, 16, u32> depth;
1134 BitField<16, 1, u32> volume; 1133 BitField<16, 1, u32> volume;
1135 }; 1134 };
@@ -3087,6 +3086,9 @@ public:
3087 3086
3088 std::vector<u8> inline_index_draw_indexes; 3087 std::vector<u8> inline_index_draw_indexes;
3089 3088
3089 /// Handles a write to the CLEAR_BUFFERS register.
3090 void ProcessClearBuffers(u32 layer_count);
3091
3090private: 3092private:
3091 void InitializeRegisterDefaults(); 3093 void InitializeRegisterDefaults();
3092 3094
@@ -3121,9 +3123,6 @@ private:
3121 /// Handles firmware blob 4 3123 /// Handles firmware blob 4
3122 void ProcessFirmwareCall4(); 3124 void ProcessFirmwareCall4();
3123 3125
3124 /// Handles a write to the CLEAR_BUFFERS register.
3125 void ProcessClearBuffers();
3126
3127 /// Handles a write to the QUERY_GET register. 3126 /// Handles a write to the QUERY_GET register.
3128 void ProcessQueryGet(); 3127 void ProcessQueryGet();
3129 3128
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index 6d35387d9..0f3262edb 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -130,19 +130,13 @@ void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
130void HLE_EAD26C3E2109B06B(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) { 130void HLE_EAD26C3E2109B06B(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
131 ASSERT(parameters.size() == 1); 131 ASSERT(parameters.size() == 1);
132 132
133 Engines::Maxwell3D::Regs::ClearSurface clear_params{parameters[0]}; 133 const Engines::Maxwell3D::Regs::ClearSurface clear_params{parameters[0]};
134
135 const u32 rt_index = clear_params.RT; 134 const u32 rt_index = clear_params.RT;
136 const u32 num_layers = maxwell3d.regs.rt[rt_index].depth_volume; 135 const u32 num_layers = maxwell3d.regs.rt[rt_index].depth;
137 136 ASSERT(clear_params.layer == 0);
138 for (u32 i = 0; i < num_layers; i++) {
139 // 0x674 = regs.clear_surface
140 maxwell3d.CallMethod(0x674, clear_params.raw, true);
141 clear_params.layer.Assign(clear_params.layer + 1);
142 137
143 // FIXME: remove this when amdvlk can clear multiple layers without crashing 138 maxwell3d.regs.clear_surface.raw = clear_params.raw;
144 break; 139 maxwell3d.ProcessClearBuffers(num_layers);
145 }
146} 140}
147 141
148constexpr std::array<std::pair<u64, HLEFunction>, 5> hle_funcs{{ 142constexpr std::array<std::pair<u64, HLEFunction>, 5> hle_funcs{{
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 1cbfef090..cfd872a40 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -43,7 +43,7 @@ public:
43 virtual void Draw(bool is_indexed, u32 instance_count) = 0; 43 virtual void Draw(bool is_indexed, u32 instance_count) = 0;
44 44
45 /// Clear the current framebuffer 45 /// Clear the current framebuffer
46 virtual void Clear() = 0; 46 virtual void Clear(u32 layer_count) = 0;
47 47
48 /// Dispatches a compute shader invocation 48 /// Dispatches a compute shader invocation
49 virtual void DispatchCompute() = 0; 49 virtual void DispatchCompute() = 0;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index d05a5f60b..115a5e010 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -136,7 +136,7 @@ void RasterizerOpenGL::LoadDiskResources(u64 title_id, std::stop_token stop_load
136 shader_cache.LoadDiskResources(title_id, stop_loading, callback); 136 shader_cache.LoadDiskResources(title_id, stop_loading, callback);
137} 137}
138 138
139void RasterizerOpenGL::Clear() { 139void RasterizerOpenGL::Clear(u32 layer_count) {
140 MICROPROFILE_SCOPE(OpenGL_Clears); 140 MICROPROFILE_SCOPE(OpenGL_Clears);
141 if (!maxwell3d->ShouldExecute()) { 141 if (!maxwell3d->ShouldExecute()) {
142 return; 142 return;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 793e0d608..449a14f12 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -69,7 +69,7 @@ public:
69 ~RasterizerOpenGL() override; 69 ~RasterizerOpenGL() override;
70 70
71 void Draw(bool is_indexed, u32 instance_count) override; 71 void Draw(bool is_indexed, u32 instance_count) override;
72 void Clear() override; 72 void Clear(u32 layer_count) override;
73 void DispatchCompute() override; 73 void DispatchCompute() override;
74 void ResetCounter(VideoCore::QueryType type) override; 74 void ResetCounter(VideoCore::QueryType type) override;
75 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override; 75 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index f69c0c50f..67b88621a 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -213,7 +213,7 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
213 EndTransformFeedback(); 213 EndTransformFeedback();
214} 214}
215 215
216void RasterizerVulkan::Clear() { 216void RasterizerVulkan::Clear(u32 layer_count) {
217 MICROPROFILE_SCOPE(Vulkan_Clearing); 217 MICROPROFILE_SCOPE(Vulkan_Clearing);
218 218
219 if (!maxwell3d->ShouldExecute()) { 219 if (!maxwell3d->ShouldExecute()) {
@@ -256,7 +256,7 @@ void RasterizerVulkan::Clear() {
256 .rect = regs.clear_control.use_scissor ? GetScissorState(regs, 0, up_scale, down_shift) 256 .rect = regs.clear_control.use_scissor ? GetScissorState(regs, 0, up_scale, down_shift)
257 : default_scissor, 257 : default_scissor,
258 .baseArrayLayer = regs.clear_surface.layer, 258 .baseArrayLayer = regs.clear_surface.layer,
259 .layerCount = 1, 259 .layerCount = layer_count,
260 }; 260 };
261 if (clear_rect.rect.extent.width == 0 || clear_rect.rect.extent.height == 0) { 261 if (clear_rect.rect.extent.width == 0 || clear_rect.rect.extent.height == 0) {
262 return; 262 return;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index b0bc306f5..70f36d58a 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -65,7 +65,7 @@ public:
65 ~RasterizerVulkan() override; 65 ~RasterizerVulkan() override;
66 66
67 void Draw(bool is_indexed, u32 instance_count) override; 67 void Draw(bool is_indexed, u32 instance_count) override;
68 void Clear() override; 68 void Clear(u32 layer_count) override;
69 void DispatchCompute() override; 69 void DispatchCompute() override;
70 void ResetCounter(VideoCore::QueryType type) override; 70 void ResetCounter(VideoCore::QueryType type) override;
71 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override; 71 void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override;