summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h6
-rw-r--r--src/video_core/engines/maxwell_3d.cpp4
-rw-r--r--src/video_core/engines/maxwell_3d.h5
-rw-r--r--src/video_core/rasterizer_interface.h3
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp22
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h2
-rw-r--r--src/video_core/renderer_vulkan/wrapper.cpp1
-rw-r--r--src/video_core/renderer_vulkan/wrapper.h10
13 files changed, 57 insertions, 16 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 398f16181..56e570994 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -88,10 +88,6 @@ public:
88 map->MarkAsWritten(true); 88 map->MarkAsWritten(true);
89 MarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1); 89 MarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1);
90 } 90 }
91 } else {
92 if (map->IsWritten()) {
93 WriteBarrier();
94 }
95 } 91 }
96 92
97 return {ToHandle(block), static_cast<u64>(block->GetOffset(cpu_addr))}; 93 return {ToHandle(block), static_cast<u64>(block->GetOffset(cpu_addr))};
@@ -253,8 +249,6 @@ protected:
253 249
254 virtual BufferType ToHandle(const OwnerBuffer& storage) = 0; 250 virtual BufferType ToHandle(const OwnerBuffer& storage) = 0;
255 251
256 virtual void WriteBarrier() = 0;
257
258 virtual OwnerBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0; 252 virtual OwnerBuffer CreateBlock(VAddr cpu_addr, std::size_t size) = 0;
259 253
260 virtual void UploadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size, 254 virtual void UploadBlockData(const OwnerBuffer& buffer, std::size_t offset, std::size_t size,
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 39e3b66a2..7db055ea0 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -184,6 +184,10 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
184 } 184 }
185 185
186 switch (method) { 186 switch (method) {
187 case MAXWELL3D_REG_INDEX(wait_for_idle): {
188 rasterizer.WaitForIdle();
189 break;
190 }
187 case MAXWELL3D_REG_INDEX(shadow_ram_control): { 191 case MAXWELL3D_REG_INDEX(shadow_ram_control): {
188 shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(method_call.argument); 192 shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(method_call.argument);
189 break; 193 break;
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 5e522e0d2..864924ff3 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -709,7 +709,9 @@ public:
709 709
710 union { 710 union {
711 struct { 711 struct {
712 INSERT_UNION_PADDING_WORDS(0x45); 712 INSERT_UNION_PADDING_WORDS(0x44);
713
714 u32 wait_for_idle;
713 715
714 struct { 716 struct {
715 u32 upload_address; 717 u32 upload_address;
@@ -1536,6 +1538,7 @@ private:
1536 static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ 1538 static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \
1537 "Field " #field_name " has invalid position") 1539 "Field " #field_name " has invalid position")
1538 1540
1541ASSERT_REG_POSITION(wait_for_idle, 0x44);
1539ASSERT_REG_POSITION(macros, 0x45); 1542ASSERT_REG_POSITION(macros, 0x45);
1540ASSERT_REG_POSITION(shadow_ram_control, 0x49); 1543ASSERT_REG_POSITION(shadow_ram_control, 0x49);
1541ASSERT_REG_POSITION(upload, 0x60); 1544ASSERT_REG_POSITION(upload, 0x60);
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 603f61952..3cbdac8e7 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -80,6 +80,9 @@ public:
80 /// and invalidated 80 /// and invalidated
81 virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; 81 virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0;
82 82
83 /// Notify the host renderer to wait for previous primitive and compute operations.
84 virtual void WaitForIdle() = 0;
85
83 /// Notify the rasterizer to send all written commands to the host GPU. 86 /// Notify the rasterizer to send all written commands to the host GPU.
84 virtual void FlushCommands() = 0; 87 virtual void FlushCommands() = 0;
85 88
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 4efce0de7..d2cab50bd 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -51,10 +51,6 @@ Buffer OGLBufferCache::CreateBlock(VAddr cpu_addr, std::size_t size) {
51 return std::make_shared<CachedBufferBlock>(cpu_addr, size); 51 return std::make_shared<CachedBufferBlock>(cpu_addr, size);
52} 52}
53 53
54void OGLBufferCache::WriteBarrier() {
55 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
56}
57
58GLuint OGLBufferCache::ToHandle(const Buffer& buffer) { 54GLuint OGLBufferCache::ToHandle(const Buffer& buffer) {
59 return buffer->GetHandle(); 55 return buffer->GetHandle();
60} 56}
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index a74817857..a9e86cfc7 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -59,8 +59,6 @@ protected:
59 59
60 GLuint ToHandle(const Buffer& buffer) override; 60 GLuint ToHandle(const Buffer& buffer) override;
61 61
62 void WriteBarrier() override;
63
64 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 62 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
65 const u8* data) override; 63 const u8* data) override;
66 64
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 725b4c32d..8b3b3ce92 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -746,6 +746,17 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
746 InvalidateRegion(addr, size); 746 InvalidateRegion(addr, size);
747} 747}
748 748
749void RasterizerOpenGL::WaitForIdle() {
750 // Place a barrier on everything that is not framebuffer related.
751 // This is related to another flag that is not currently implemented.
752 glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT |
753 GL_UNIFORM_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT |
754 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
755 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT |
756 GL_BUFFER_UPDATE_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
757 GL_SHADER_STORAGE_BARRIER_BIT | GL_QUERY_BUFFER_BARRIER_BIT);
758}
759
749void RasterizerOpenGL::FlushCommands() { 760void RasterizerOpenGL::FlushCommands() {
750 // Only flush when we have commands queued to OpenGL. 761 // Only flush when we have commands queued to OpenGL.
751 if (num_queued_commands == 0) { 762 if (num_queued_commands == 0) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 87249fb6f..b94c65907 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -75,6 +75,7 @@ public:
75 void SignalSyncPoint(u32 value) override; 75 void SignalSyncPoint(u32 value) override;
76 void ReleaseFences() override; 76 void ReleaseFences() override;
77 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 77 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
78 void WaitForIdle() override;
78 void FlushCommands() override; 79 void FlushCommands() override;
79 void TickFrame() override; 80 void TickFrame() override;
80 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, 81 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index a2d0b42b1..a54583e7d 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -52,8 +52,6 @@ public:
52protected: 52protected:
53 VkBuffer ToHandle(const Buffer& buffer) override; 53 VkBuffer ToHandle(const Buffer& buffer) override;
54 54
55 void WriteBarrier() override {}
56
57 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override; 55 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override;
58 56
59 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 57 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 722fde384..8b009fc22 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -299,7 +299,7 @@ RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWind
299 buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), 299 buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool),
300 sampler_cache(device), 300 sampler_cache(device),
301 fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache), 301 fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache),
302 query_cache(system, *this, device, scheduler) { 302 query_cache(system, *this, device, scheduler), wfi_event{device.GetLogical().CreateEvent()} {
303 scheduler.SetQueryCache(query_cache); 303 scheduler.SetQueryCache(query_cache);
304} 304}
305 305
@@ -573,6 +573,26 @@ void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) {
573 InvalidateRegion(addr, size); 573 InvalidateRegion(addr, size);
574} 574}
575 575
576void RasterizerVulkan::WaitForIdle() {
577 // Everything but wait pixel operations. This intentionally includes FRAGMENT_SHADER_BIT because
578 // fragment shaders can still write storage buffers.
579 VkPipelineStageFlags flags =
580 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT | VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
581 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT |
582 VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT |
583 VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
584 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
585 if (device.IsExtTransformFeedbackSupported()) {
586 flags |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT;
587 }
588
589 scheduler.RequestOutsideRenderPassOperationContext();
590 scheduler.Record([event = *wfi_event, flags](vk::CommandBuffer cmdbuf) {
591 cmdbuf.SetEvent(event, flags);
592 cmdbuf.WaitEvents(event, flags, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, {}, {}, {});
593 });
594}
595
576void RasterizerVulkan::FlushCommands() { 596void RasterizerVulkan::FlushCommands() {
577 if (draw_counter > 0) { 597 if (draw_counter > 0) {
578 draw_counter = 0; 598 draw_counter = 0;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 703a094c3..0ed0e48c6 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -126,6 +126,7 @@ public:
126 void SignalSyncPoint(u32 value) override; 126 void SignalSyncPoint(u32 value) override;
127 void ReleaseFences() override; 127 void ReleaseFences() override;
128 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 128 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
129 void WaitForIdle() override;
129 void FlushCommands() override; 130 void FlushCommands() override;
130 void TickFrame() override; 131 void TickFrame() override;
131 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, 132 bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src,
@@ -275,6 +276,7 @@ private:
275 276
276 vk::Buffer default_buffer; 277 vk::Buffer default_buffer;
277 VKMemoryCommit default_buffer_commit; 278 VKMemoryCommit default_buffer_commit;
279 vk::Event wfi_event;
278 280
279 std::array<View, Maxwell::NumRenderTargets> color_attachments; 281 std::array<View, Maxwell::NumRenderTargets> color_attachments;
280 View zeta_attachment; 282 View zeta_attachment;
diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp
index 7f5bc1404..2ce9b0626 100644
--- a/src/video_core/renderer_vulkan/wrapper.cpp
+++ b/src/video_core/renderer_vulkan/wrapper.cpp
@@ -87,6 +87,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
87 X(vkCmdSetStencilReference); 87 X(vkCmdSetStencilReference);
88 X(vkCmdSetStencilWriteMask); 88 X(vkCmdSetStencilWriteMask);
89 X(vkCmdSetViewport); 89 X(vkCmdSetViewport);
90 X(vkCmdWaitEvents);
90 X(vkCreateBuffer); 91 X(vkCreateBuffer);
91 X(vkCreateBufferView); 92 X(vkCreateBufferView);
92 X(vkCreateCommandPool); 93 X(vkCreateCommandPool);
diff --git a/src/video_core/renderer_vulkan/wrapper.h b/src/video_core/renderer_vulkan/wrapper.h
index bda16a2cb..98937a77a 100644
--- a/src/video_core/renderer_vulkan/wrapper.h
+++ b/src/video_core/renderer_vulkan/wrapper.h
@@ -205,6 +205,7 @@ struct DeviceDispatch : public InstanceDispatch {
205 PFN_vkCmdSetStencilReference vkCmdSetStencilReference; 205 PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
206 PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask; 206 PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
207 PFN_vkCmdSetViewport vkCmdSetViewport; 207 PFN_vkCmdSetViewport vkCmdSetViewport;
208 PFN_vkCmdWaitEvents vkCmdWaitEvents;
208 PFN_vkCreateBuffer vkCreateBuffer; 209 PFN_vkCreateBuffer vkCreateBuffer;
209 PFN_vkCreateBufferView vkCreateBufferView; 210 PFN_vkCreateBufferView vkCreateBufferView;
210 PFN_vkCreateCommandPool vkCreateCommandPool; 211 PFN_vkCreateCommandPool vkCreateCommandPool;
@@ -958,6 +959,15 @@ public:
958 dld->vkCmdSetEvent(handle, event, stage_flags); 959 dld->vkCmdSetEvent(handle, event, stage_flags);
959 } 960 }
960 961
962 void WaitEvents(Span<VkEvent> events, VkPipelineStageFlags src_stage_mask,
963 VkPipelineStageFlags dst_stage_mask, Span<VkMemoryBarrier> memory_barriers,
964 Span<VkBufferMemoryBarrier> buffer_barriers,
965 Span<VkImageMemoryBarrier> image_barriers) const noexcept {
966 dld->vkCmdWaitEvents(handle, events.size(), events.data(), src_stage_mask, dst_stage_mask,
967 memory_barriers.size(), memory_barriers.data(), buffer_barriers.size(),
968 buffer_barriers.data(), image_barriers.size(), image_barriers.data());
969 }
970
961 void BindTransformFeedbackBuffersEXT(u32 first, u32 count, const VkBuffer* buffers, 971 void BindTransformFeedbackBuffersEXT(u32 first, u32 count, const VkBuffer* buffers,
962 const VkDeviceSize* offsets, 972 const VkDeviceSize* offsets,
963 const VkDeviceSize* sizes) const noexcept { 973 const VkDeviceSize* sizes) const noexcept {