diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 6 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 5 | ||||
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 22 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.h | 10 |
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 | ||
| 1541 | ASSERT_REG_POSITION(wait_for_idle, 0x44); | ||
| 1539 | ASSERT_REG_POSITION(macros, 0x45); | 1542 | ASSERT_REG_POSITION(macros, 0x45); |
| 1540 | ASSERT_REG_POSITION(shadow_ram_control, 0x49); | 1543 | ASSERT_REG_POSITION(shadow_ram_control, 0x49); |
| 1541 | ASSERT_REG_POSITION(upload, 0x60); | 1544 | ASSERT_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 | ||
| 54 | void OGLBufferCache::WriteBarrier() { | ||
| 55 | glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); | ||
| 56 | } | ||
| 57 | |||
| 58 | GLuint OGLBufferCache::ToHandle(const Buffer& buffer) { | 54 | GLuint 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 | ||
| 749 | void 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 | |||
| 749 | void RasterizerOpenGL::FlushCommands() { | 760 | void 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: | |||
| 52 | protected: | 52 | protected: |
| 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 | ||
| 576 | void 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 | |||
| 576 | void RasterizerVulkan::FlushCommands() { | 596 | void 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 { |