summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/ring_buffer.h2
-rw-r--r--src/video_core/macro/macro_hle.cpp7
-rw-r--r--src/video_core/rasterizer_interface.h8
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h6
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.h27
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp16
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.cpp4
-rw-r--r--src/yuzu/main.h8
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
379void 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
385GLuint 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
238struct BufferCacheParams { 243struct 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(&params); 310 buffer_cache.SetDrawIndirect(&params);
311 PrepareDraw(params.is_indexed, [this, &params](GLenum primitive_mode) { 311 PrepareDraw(params.is_indexed, [this, &params](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
1381void RasterizerOpenGL::RegisterTransformFeedback(GPUVAddr tfb_object_addr) {
1382 buffer_cache_runtime.BindTransformFeedbackObject(tfb_object_addr);
1383}
1384
1374AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_) 1385AccelerateDMA::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
142private: 148private:
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
210void OGLTransformFeedback::Create() {
211 if (handle != 0)
212 return;
213
214 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
215 glCreateTransformFeedbacks(1, &handle);
216}
217
218void 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
326class OGLTransformFeedback final {
327public:
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,