diff options
-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: // Having them on the same cache-line would result in false-sharing between them. // TODO: Remove this ifdef whenever clang and GCC support // std::hardware_destructive_interference_size. -#if defined(_MSC_VER) && _MSC_VER >= 1911 +#ifdef __cpp_lib_hardware_interference_size alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_read_index{0}; alignas(std::hardware_destructive_interference_size) std::atomic_size_t m_write_index{0}; #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: explicit HLE_DrawIndirectByteCount(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { + const bool force = maxwell3d.Rasterizer().HasDrawTransformFeedback(); + auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0xFFFFU); - if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) { + if (!force && (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology))) { Fallback(parameters); return; } - auto& params = maxwell3d.draw_manager->GetIndirectParams(); params.is_byte_count = true; params.is_indexed = false; @@ -503,6 +504,8 @@ public: maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(launch_dma)), 0x1011, true); maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(inline_data)), regs.transform_feedback.controls[0].stride, true); + + maxwell3d.Rasterizer().RegisterTransformFeedback(regs.upload.dest.Address()); } }; 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: virtual void BindChannel(Tegra::Control::ChannelState& channel) {} virtual void ReleaseChannel(s32 channel_id) {} + + /// Register the address as a Transform Feedback Object + virtual void RegisterTransformFeedback(GPUVAddr tfb_object_addr) {} + + /// Returns true when the rasterizer has Draw Transform Feedback capabilities + virtual bool HasDrawTransformFeedback() { + return false; + } }; } // 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 *image_handles++ = buffer.View(offset, size, format); } +void BufferCacheRuntime::BindTransformFeedbackObject(GPUVAddr tfb_object_addr) { + OGLTransformFeedback& tfb_object = tfb_objects[tfb_object_addr]; + tfb_object.Create(); + glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb_object.handle); +} + +GLuint BufferCacheRuntime::GetTransformFeedbackObject(GPUVAddr tfb_object_addr) { + ASSERT(tfb_objects.contains(tfb_object_addr)); + return tfb_objects[tfb_object_addr].handle; +} + } // 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 @@ #include <array> #include <span> +#include <unordered_map> #include "common/common_types.h" #include "video_core/buffer_cache/buffer_cache_base.h" @@ -121,6 +122,9 @@ public: void BindImageBuffer(Buffer& buffer, u32 offset, u32 size, VideoCore::Surface::PixelFormat format); + void BindTransformFeedbackObject(GPUVAddr tfb_object_addr); + GLuint GetTransformFeedbackObject(GPUVAddr tfb_object_addr); + u64 GetDeviceMemoryUsage() const; void BindFastUniformBuffer(size_t stage, u32 binding_index, u32 size) { @@ -233,6 +237,7 @@ private: u32 index_buffer_offset = 0; u64 device_access_memory; + std::unordered_map<GPUVAddr, OGLTransformFeedback> tfb_objects; }; 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() { const auto& params = maxwell3d->draw_manager->GetIndirectParams(); buffer_cache.SetDrawIndirect(¶ms); PrepareDraw(params.is_indexed, [this, ¶ms](GLenum primitive_mode) { + if (params.is_byte_count) { + const GPUVAddr tfb_object_base_addr = params.indirect_start_address - 4U; + const GLuint tfb_object = + buffer_cache_runtime.GetTransformFeedbackObject(tfb_object_base_addr); + glDrawTransformFeedback(primitive_mode, tfb_object); + return; + } const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer(); const GLvoid* const gl_offset = reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset)); @@ -1371,6 +1378,10 @@ void RasterizerOpenGL::ReleaseChannel(s32 channel_id) { query_cache.EraseChannel(channel_id); } +void RasterizerOpenGL::RegisterTransformFeedback(GPUVAddr tfb_object_addr) { + buffer_cache_runtime.BindTransformFeedbackObject(tfb_object_addr); +} + AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_) : buffer_cache{buffer_cache_}, texture_cache{texture_cache_} {} 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: void ReleaseChannel(s32 channel_id) override; + void RegisterTransformFeedback(GPUVAddr tfb_object_addr) override; + + bool HasDrawTransformFeedback() override { + return true; + } + private: static constexpr size_t MAX_TEXTURES = 192; 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() { handle = 0; } +void OGLTransformFeedback::Create() { + if (handle != 0) + return; + + MICROPROFILE_SCOPE(OpenGL_ResourceCreation); + glCreateTransformFeedbacks(1, &handle); +} + +void OGLTransformFeedback::Release() { + if (handle == 0) + return; + + MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); + glDeleteTransformFeedbacks(1, &handle); + handle = 0; +} + } // 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: GLuint handle = 0; }; +class OGLTransformFeedback final { +public: + YUZU_NON_COPYABLE(OGLTransformFeedback); + + OGLTransformFeedback() = default; + + OGLTransformFeedback(OGLTransformFeedback&& o) noexcept : handle(std::exchange(o.handle, 0)) {} + + ~OGLTransformFeedback() { + Release(); + } + + OGLTransformFeedback& operator=(OGLTransformFeedback&& o) noexcept { + Release(); + handle = std::exchange(o.handle, 0); + return *this; + } + + /// Creates a new internal OpenGL resource and stores the handle + void Create(); + + /// Deletes the internal OpenGL resource + void Release(); + + GLuint handle = 0; +}; + } // 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 // The wanted format is not supported by hardware, search for alternatives const VkFormat* alternatives = GetFormatAlternatives(wanted_format); if (alternatives == nullptr) { - ASSERT_MSG(false, - "Format={} with usage={} and type={} has no defined alternatives and host " - "hardware does not support it", - wanted_format, wanted_usage, format_type); + LOG_ERROR(Render_Vulkan, + "Format={} with usage={} and type={} has no defined alternatives and host " + "hardware does not support it", + wanted_format, wanted_usage, format_type); return wanted_format; } @@ -774,10 +774,10 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags } // No alternatives found, panic - ASSERT_MSG(false, - "Format={} with usage={} and type={} is not supported by the host hardware and " - "doesn't support any of the alternatives", - wanted_format, wanted_usage, format_type); + LOG_ERROR(Render_Vulkan, + "Format={} with usage={} and type={} is not supported by the host hardware and " + "doesn't support any of the alternatives", + wanted_format, wanted_usage, format_type); return wanted_format; } 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 .objectHandle = reinterpret_cast<u64>(handle), .pObjectName = name, }; - Check(dld->vkSetDebugUtilsObjectNameEXT(device, &name_info)); + if (dld->vkSetDebugUtilsObjectNameEXT) { + Check(dld->vkSetDebugUtilsObjectNameEXT(device, &name_info)); + } } } // 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 { /// Max number of recently loaded items to keep track of static const int max_recent_files_item = 10; - // TODO: Make use of this! - enum { - UI_IDLE, - UI_EMU_BOOTING, - UI_EMU_RUNNING, - UI_EMU_STOPPING, - }; - enum { CREATE_SHORTCUT_MSGBOX_FULLSCREEN_YES, CREATE_SHORTCUT_MSGBOX_SUCCESS, |