diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/ring_buffer.h | 2 | ||||
| -rw-r--r-- | src/video_core/macro/macro_hle.cpp | 7 | ||||
| -rw-r--r-- | src/video_core/rasterizer_interface.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.h | 27 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/main.h | 8 |
12 files changed, 102 insertions, 20 deletions
diff --git a/src/common/ring_buffer.h b/src/common/ring_buffer.h index 5c961b202..e7e9fdb38 100644 --- a/src/common/ring_buffer.h +++ b/src/common/ring_buffer.h | |||
| @@ -103,7 +103,7 @@ private: | |||
| 103 | // Having them on the same cache-line would result in false-sharing between them. | 103 | // Having them on the same cache-line would result in false-sharing between them. |
| 104 | // TODO: Remove this ifdef whenever clang and GCC support | 104 | // TODO: Remove this ifdef whenever clang and GCC support |
| 105 | // std::hardware_destructive_interference_size. | 105 | // std::hardware_destructive_interference_size. |
| 106 | #if defined(_MSC_VER) && _MSC_VER >= 1911 | 106 | #ifdef __cpp_lib_hardware_interference_size |
| 107 | alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_read_index{0}; | 107 | alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_read_index{0}; |
| 108 | alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_write_index{0}; | 108 | alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_write_index{0}; |
| 109 | #else | 109 | #else |
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index 046c8085e..46e853e04 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp | |||
| @@ -327,12 +327,13 @@ public: | |||
| 327 | explicit HLE_DrawIndirectByteCount(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} | 327 | explicit HLE_DrawIndirectByteCount(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} |
| 328 | 328 | ||
| 329 | void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { | 329 | void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { |
| 330 | const bool force = maxwell3d.Rasterizer().HasDrawTransformFeedback(); | ||
| 331 | |||
| 330 | auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0xFFFFU); | 332 | auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0xFFFFU); |
| 331 | if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) { | 333 | if (!force && (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology))) { |
| 332 | Fallback(parameters); | 334 | Fallback(parameters); |
| 333 | return; | 335 | return; |
| 334 | } | 336 | } |
| 335 | |||
| 336 | auto& params = maxwell3d.draw_manager->GetIndirectParams(); | 337 | auto& params = maxwell3d.draw_manager->GetIndirectParams(); |
| 337 | params.is_byte_count = true; | 338 | params.is_byte_count = true; |
| 338 | params.is_indexed = false; | 339 | params.is_indexed = false; |
| @@ -503,6 +504,8 @@ public: | |||
| 503 | maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(launch_dma)), 0x1011, true); | 504 | maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(launch_dma)), 0x1011, true); |
| 504 | maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(inline_data)), | 505 | maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(inline_data)), |
| 505 | regs.transform_feedback.controls[0].stride, true); | 506 | regs.transform_feedback.controls[0].stride, true); |
| 507 | |||
| 508 | maxwell3d.Rasterizer().RegisterTransformFeedback(regs.upload.dest.Address()); | ||
| 506 | } | 509 | } |
| 507 | }; | 510 | }; |
| 508 | 511 | ||
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index af1469147..49224ca85 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h | |||
| @@ -173,5 +173,13 @@ public: | |||
| 173 | virtual void BindChannel(Tegra::Control::ChannelState& channel) {} | 173 | virtual void BindChannel(Tegra::Control::ChannelState& channel) {} |
| 174 | 174 | ||
| 175 | virtual void ReleaseChannel(s32 channel_id) {} | 175 | virtual void ReleaseChannel(s32 channel_id) {} |
| 176 | |||
| 177 | /// Register the address as a Transform Feedback Object | ||
| 178 | virtual void RegisterTransformFeedback(GPUVAddr tfb_object_addr) {} | ||
| 179 | |||
| 180 | /// Returns true when the rasterizer has Draw Transform Feedback capabilities | ||
| 181 | virtual bool HasDrawTransformFeedback() { | ||
| 182 | return false; | ||
| 183 | } | ||
| 176 | }; | 184 | }; |
| 177 | } // namespace VideoCore | 185 | } // namespace VideoCore |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp index b787b6994..517ac14dd 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -376,4 +376,15 @@ void BufferCacheRuntime::BindImageBuffer(Buffer& buffer, u32 offset, u32 size, P | |||
| 376 | *image_handles++ = buffer.View(offset, size, format); | 376 | *image_handles++ = buffer.View(offset, size, format); |
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | void BufferCacheRuntime::BindTransformFeedbackObject(GPUVAddr tfb_object_addr) { | ||
| 380 | OGLTransformFeedback& tfb_object = tfb_objects[tfb_object_addr]; | ||
| 381 | tfb_object.Create(); | ||
| 382 | glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb_object.handle); | ||
| 383 | } | ||
| 384 | |||
| 385 | GLuint BufferCacheRuntime::GetTransformFeedbackObject(GPUVAddr tfb_object_addr) { | ||
| 386 | ASSERT(tfb_objects.contains(tfb_object_addr)); | ||
| 387 | return tfb_objects[tfb_object_addr].handle; | ||
| 388 | } | ||
| 389 | |||
| 379 | } // namespace OpenGL | 390 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h index 1e8708f59..2c18de166 100644 --- a/src/video_core/renderer_opengl/gl_buffer_cache.h +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <span> | 7 | #include <span> |
| 8 | #include <unordered_map> | ||
| 8 | 9 | ||
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "video_core/buffer_cache/buffer_cache_base.h" | 11 | #include "video_core/buffer_cache/buffer_cache_base.h" |
| @@ -121,6 +122,9 @@ public: | |||
| 121 | void BindImageBuffer(Buffer& buffer, u32 offset, u32 size, | 122 | void BindImageBuffer(Buffer& buffer, u32 offset, u32 size, |
| 122 | VideoCore::Surface::PixelFormat format); | 123 | VideoCore::Surface::PixelFormat format); |
| 123 | 124 | ||
| 125 | void BindTransformFeedbackObject(GPUVAddr tfb_object_addr); | ||
| 126 | GLuint GetTransformFeedbackObject(GPUVAddr tfb_object_addr); | ||
| 127 | |||
| 124 | u64 GetDeviceMemoryUsage() const; | 128 | u64 GetDeviceMemoryUsage() const; |
| 125 | 129 | ||
| 126 | void BindFastUniformBuffer(size_t stage, u32 binding_index, u32 size) { | 130 | void BindFastUniformBuffer(size_t stage, u32 binding_index, u32 size) { |
| @@ -233,6 +237,7 @@ private: | |||
| 233 | u32 index_buffer_offset = 0; | 237 | u32 index_buffer_offset = 0; |
| 234 | 238 | ||
| 235 | u64 device_access_memory; | 239 | u64 device_access_memory; |
| 240 | std::unordered_map<GPUVAddr, OGLTransformFeedback> tfb_objects; | ||
| 236 | }; | 241 | }; |
| 237 | 242 | ||
| 238 | struct BufferCacheParams { | 243 | struct BufferCacheParams { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 339950d2e..7a5fad735 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -309,6 +309,13 @@ void RasterizerOpenGL::DrawIndirect() { | |||
| 309 | const auto& params = maxwell3d->draw_manager->GetIndirectParams(); | 309 | const auto& params = maxwell3d->draw_manager->GetIndirectParams(); |
| 310 | buffer_cache.SetDrawIndirect(¶ms); | 310 | buffer_cache.SetDrawIndirect(¶ms); |
| 311 | PrepareDraw(params.is_indexed, [this, ¶ms](GLenum primitive_mode) { | 311 | PrepareDraw(params.is_indexed, [this, ¶ms](GLenum primitive_mode) { |
| 312 | if (params.is_byte_count) { | ||
| 313 | const GPUVAddr tfb_object_base_addr = params.indirect_start_address - 4U; | ||
| 314 | const GLuint tfb_object = | ||
| 315 | buffer_cache_runtime.GetTransformFeedbackObject(tfb_object_base_addr); | ||
| 316 | glDrawTransformFeedback(primitive_mode, tfb_object); | ||
| 317 | return; | ||
| 318 | } | ||
| 312 | const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer(); | 319 | const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer(); |
| 313 | const GLvoid* const gl_offset = | 320 | const GLvoid* const gl_offset = |
| 314 | reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset)); | 321 | reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset)); |
| @@ -1371,6 +1378,10 @@ void RasterizerOpenGL::ReleaseChannel(s32 channel_id) { | |||
| 1371 | query_cache.EraseChannel(channel_id); | 1378 | query_cache.EraseChannel(channel_id); |
| 1372 | } | 1379 | } |
| 1373 | 1380 | ||
| 1381 | void RasterizerOpenGL::RegisterTransformFeedback(GPUVAddr tfb_object_addr) { | ||
| 1382 | buffer_cache_runtime.BindTransformFeedbackObject(tfb_object_addr); | ||
| 1383 | } | ||
| 1384 | |||
| 1374 | AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_) | 1385 | AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_) |
| 1375 | : buffer_cache{buffer_cache_}, texture_cache{texture_cache_} {} | 1386 | : buffer_cache{buffer_cache_}, texture_cache{texture_cache_} {} |
| 1376 | 1387 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index b79d7a70c..ce3460938 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -139,6 +139,12 @@ public: | |||
| 139 | 139 | ||
| 140 | void ReleaseChannel(s32 channel_id) override; | 140 | void ReleaseChannel(s32 channel_id) override; |
| 141 | 141 | ||
| 142 | void RegisterTransformFeedback(GPUVAddr tfb_object_addr) override; | ||
| 143 | |||
| 144 | bool HasDrawTransformFeedback() override { | ||
| 145 | return true; | ||
| 146 | } | ||
| 147 | |||
| 142 | private: | 148 | private: |
| 143 | static constexpr size_t MAX_TEXTURES = 192; | 149 | static constexpr size_t MAX_TEXTURES = 192; |
| 144 | static constexpr size_t MAX_IMAGES = 48; | 150 | static constexpr size_t MAX_IMAGES = 48; |
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp index eae8fd110..1d2c9b70a 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.cpp +++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp | |||
| @@ -207,4 +207,21 @@ void OGLQuery::Release() { | |||
| 207 | handle = 0; | 207 | handle = 0; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | void OGLTransformFeedback::Create() { | ||
| 211 | if (handle != 0) | ||
| 212 | return; | ||
| 213 | |||
| 214 | MICROPROFILE_SCOPE(OpenGL_ResourceCreation); | ||
| 215 | glCreateTransformFeedbacks(1, &handle); | ||
| 216 | } | ||
| 217 | |||
| 218 | void OGLTransformFeedback::Release() { | ||
| 219 | if (handle == 0) | ||
| 220 | return; | ||
| 221 | |||
| 222 | MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); | ||
| 223 | glDeleteTransformFeedbacks(1, &handle); | ||
| 224 | handle = 0; | ||
| 225 | } | ||
| 226 | |||
| 210 | } // namespace OpenGL | 227 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 77362acd2..6ca8227bd 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h | |||
| @@ -323,4 +323,31 @@ public: | |||
| 323 | GLuint handle = 0; | 323 | GLuint handle = 0; |
| 324 | }; | 324 | }; |
| 325 | 325 | ||
| 326 | class OGLTransformFeedback final { | ||
| 327 | public: | ||
| 328 | YUZU_NON_COPYABLE(OGLTransformFeedback); | ||
| 329 | |||
| 330 | OGLTransformFeedback() = default; | ||
| 331 | |||
| 332 | OGLTransformFeedback(OGLTransformFeedback&& o) noexcept : handle(std::exchange(o.handle, 0)) {} | ||
| 333 | |||
| 334 | ~OGLTransformFeedback() { | ||
| 335 | Release(); | ||
| 336 | } | ||
| 337 | |||
| 338 | OGLTransformFeedback& operator=(OGLTransformFeedback&& o) noexcept { | ||
| 339 | Release(); | ||
| 340 | handle = std::exchange(o.handle, 0); | ||
| 341 | return *this; | ||
| 342 | } | ||
| 343 | |||
| 344 | /// Creates a new internal OpenGL resource and stores the handle | ||
| 345 | void Create(); | ||
| 346 | |||
| 347 | /// Deletes the internal OpenGL resource | ||
| 348 | void Release(); | ||
| 349 | |||
| 350 | GLuint handle = 0; | ||
| 351 | }; | ||
| 352 | |||
| 326 | } // namespace OpenGL | 353 | } // namespace OpenGL |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index a6fbca69e..727bbd98d 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -755,10 +755,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags | |||
| 755 | // The wanted format is not supported by hardware, search for alternatives | 755 | // The wanted format is not supported by hardware, search for alternatives |
| 756 | const VkFormat* alternatives = GetFormatAlternatives(wanted_format); | 756 | const VkFormat* alternatives = GetFormatAlternatives(wanted_format); |
| 757 | if (alternatives == nullptr) { | 757 | if (alternatives == nullptr) { |
| 758 | ASSERT_MSG(false, | 758 | LOG_ERROR(Render_Vulkan, |
| 759 | "Format={} with usage={} and type={} has no defined alternatives and host " | 759 | "Format={} with usage={} and type={} has no defined alternatives and host " |
| 760 | "hardware does not support it", | 760 | "hardware does not support it", |
| 761 | wanted_format, wanted_usage, format_type); | 761 | wanted_format, wanted_usage, format_type); |
| 762 | return wanted_format; | 762 | return wanted_format; |
| 763 | } | 763 | } |
| 764 | 764 | ||
| @@ -774,10 +774,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags | |||
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | // No alternatives found, panic | 776 | // No alternatives found, panic |
| 777 | ASSERT_MSG(false, | 777 | LOG_ERROR(Render_Vulkan, |
| 778 | "Format={} with usage={} and type={} is not supported by the host hardware and " | 778 | "Format={} with usage={} and type={} is not supported by the host hardware and " |
| 779 | "doesn't support any of the alternatives", | 779 | "doesn't support any of the alternatives", |
| 780 | wanted_format, wanted_usage, format_type); | 780 | wanted_format, wanted_usage, format_type); |
| 781 | return wanted_format; | 781 | return wanted_format; |
| 782 | } | 782 | } |
| 783 | 783 | ||
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 2f78b8af0..074aed964 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -246,7 +246,9 @@ void SetObjectName(const DeviceDispatch* dld, VkDevice device, T handle, VkObjec | |||
| 246 | .objectHandle = reinterpret_cast<u64>(handle), | 246 | .objectHandle = reinterpret_cast<u64>(handle), |
| 247 | .pObjectName = name, | 247 | .pObjectName = name, |
| 248 | }; | 248 | }; |
| 249 | Check(dld->vkSetDebugUtilsObjectNameEXT(device, &name_info)); | 249 | if (dld->vkSetDebugUtilsObjectNameEXT) { |
| 250 | Check(dld->vkSetDebugUtilsObjectNameEXT(device, &name_info)); | ||
| 251 | } | ||
| 250 | } | 252 | } |
| 251 | 253 | ||
| 252 | } // Anonymous namespace | 254 | } // Anonymous namespace |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 530e445f9..366e806d5 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -168,14 +168,6 @@ class GMainWindow : public QMainWindow { | |||
| 168 | /// Max number of recently loaded items to keep track of | 168 | /// Max number of recently loaded items to keep track of |
| 169 | static const int max_recent_files_item = 10; | 169 | static const int max_recent_files_item = 10; |
| 170 | 170 | ||
| 171 | // TODO: Make use of this! | ||
| 172 | enum { | ||
| 173 | UI_IDLE, | ||
| 174 | UI_EMU_BOOTING, | ||
| 175 | UI_EMU_RUNNING, | ||
| 176 | UI_EMU_STOPPING, | ||
| 177 | }; | ||
| 178 | |||
| 179 | enum { | 171 | enum { |
| 180 | CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, | 172 | CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, |
| 181 | CREATE_SHORTCUT_MSGBOX_SUCCESS, | 173 | CREATE_SHORTCUT_MSGBOX_SUCCESS, |