summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ameer J2023-12-19 16:25:08 -0500
committerGravatar Ameer J2023-12-19 19:54:57 -0500
commitbbc0ed118df7f64522e198307a6d28607b23d4be (patch)
tree2dfd7ecaec445de037ec0af719d12991b88379fd
parentMerge pull request #12411 from ameerj/gl-nv-tfb-fixups (diff)
downloadyuzu-bbc0ed118df7f64522e198307a6d28607b23d4be.tar.gz
yuzu-bbc0ed118df7f64522e198307a6d28607b23d4be.tar.xz
yuzu-bbc0ed118df7f64522e198307a6d28607b23d4be.zip
gl_rasterizer: Implement DrawTransformFeedback macro
Diffstat (limited to '')
-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
8 files changed, 90 insertions, 2 deletions
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 4832c03c5..291515e73 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -294,6 +294,13 @@ void RasterizerOpenGL::DrawIndirect() {
294 const auto& params = maxwell3d->draw_manager->GetIndirectParams(); 294 const auto& params = maxwell3d->draw_manager->GetIndirectParams();
295 buffer_cache.SetDrawIndirect(&params); 295 buffer_cache.SetDrawIndirect(&params);
296 PrepareDraw(params.is_indexed, [this, &params](GLenum primitive_mode) { 296 PrepareDraw(params.is_indexed, [this, &params](GLenum primitive_mode) {
297 if (params.is_byte_count) {
298 const GPUVAddr tfb_object_base_addr = params.indirect_start_address - 4U;
299 const GLuint tfb_object =
300 buffer_cache_runtime.GetTransformFeedbackObject(tfb_object_base_addr);
301 glDrawTransformFeedback(primitive_mode, tfb_object);
302 return;
303 }
297 const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer(); 304 const auto [buffer, offset] = buffer_cache.GetDrawIndirectBuffer();
298 const GLvoid* const gl_offset = 305 const GLvoid* const gl_offset =
299 reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset)); 306 reinterpret_cast<const GLvoid*>(static_cast<uintptr_t>(offset));
@@ -1350,6 +1357,10 @@ void RasterizerOpenGL::ReleaseChannel(s32 channel_id) {
1350 query_cache.EraseChannel(channel_id); 1357 query_cache.EraseChannel(channel_id);
1351} 1358}
1352 1359
1360void RasterizerOpenGL::RegisterTransformFeedback(GPUVAddr tfb_object_addr) {
1361 buffer_cache_runtime.BindTransformFeedbackObject(tfb_object_addr);
1362}
1363
1353AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_) 1364AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_, TextureCache& texture_cache_)
1354 : buffer_cache{buffer_cache_}, texture_cache{texture_cache_} {} 1365 : buffer_cache{buffer_cache_}, texture_cache{texture_cache_} {}
1355 1366
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index ceffe1f1e..d28388a9d 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