diff options
| author | 2023-12-19 17:32:31 -0500 | |
|---|---|---|
| committer | 2023-12-19 17:32:31 -0500 | |
| commit | db8a601cf82cd4797c32931f13a585c64527780d (patch) | |
| tree | ec0f8a7f5355c9ecb01b03580b65d01671ac3359 /src/video_core/renderer_opengl | |
| parent | Merge pull request #12382 from liamwhite/image-limit (diff) | |
| download | yuzu-db8a601cf82cd4797c32931f13a585c64527780d.tar.gz yuzu-db8a601cf82cd4797c32931f13a585c64527780d.tar.xz yuzu-db8a601cf82cd4797c32931f13a585c64527780d.zip | |
OpenGL: Add GL_PRIMITIVES_GENERATED and GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries
Diffstat (limited to 'src/video_core/renderer_opengl')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_query_cache.cpp | 23 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 49 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 |
3 files changed, 54 insertions, 21 deletions
diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp index ec142d48e..fef7360ed 100644 --- a/src/video_core/renderer_opengl/gl_query_cache.cpp +++ b/src/video_core/renderer_opengl/gl_query_cache.cpp | |||
| @@ -18,16 +18,27 @@ namespace OpenGL { | |||
| 18 | 18 | ||
| 19 | namespace { | 19 | namespace { |
| 20 | 20 | ||
| 21 | constexpr std::array<GLenum, VideoCore::NumQueryTypes> QueryTargets = {GL_SAMPLES_PASSED}; | ||
| 22 | |||
| 23 | constexpr GLenum GetTarget(VideoCore::QueryType type) { | 21 | constexpr GLenum GetTarget(VideoCore::QueryType type) { |
| 24 | return QueryTargets[static_cast<std::size_t>(type)]; | 22 | switch (type) { |
| 23 | case VideoCore::QueryType::SamplesPassed: | ||
| 24 | return GL_SAMPLES_PASSED; | ||
| 25 | case VideoCore::QueryType::PrimitivesGenerated: | ||
| 26 | return GL_PRIMITIVES_GENERATED; | ||
| 27 | case VideoCore::QueryType::TfbPrimitivesWritten: | ||
| 28 | return GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; | ||
| 29 | default: | ||
| 30 | break; | ||
| 31 | } | ||
| 32 | UNIMPLEMENTED_MSG("Query type {}", type); | ||
| 33 | return 0; | ||
| 25 | } | 34 | } |
| 26 | 35 | ||
| 27 | } // Anonymous namespace | 36 | } // Anonymous namespace |
| 28 | 37 | ||
| 29 | QueryCache::QueryCache(RasterizerOpenGL& rasterizer_, Core::Memory::Memory& cpu_memory_) | 38 | QueryCache::QueryCache(RasterizerOpenGL& rasterizer_, Core::Memory::Memory& cpu_memory_) |
| 30 | : QueryCacheLegacy(rasterizer_, cpu_memory_), gl_rasterizer{rasterizer_} {} | 39 | : QueryCacheLegacy(rasterizer_, cpu_memory_), gl_rasterizer{rasterizer_} { |
| 40 | EnableCounters(); | ||
| 41 | } | ||
| 31 | 42 | ||
| 32 | QueryCache::~QueryCache() = default; | 43 | QueryCache::~QueryCache() = default; |
| 33 | 44 | ||
| @@ -103,13 +114,13 @@ u64 CachedQuery::Flush([[maybe_unused]] bool async) { | |||
| 103 | auto& stream = cache->Stream(type); | 114 | auto& stream = cache->Stream(type); |
| 104 | const bool slice_counter = WaitPending() && stream.IsEnabled(); | 115 | const bool slice_counter = WaitPending() && stream.IsEnabled(); |
| 105 | if (slice_counter) { | 116 | if (slice_counter) { |
| 106 | stream.Update(false); | 117 | stream.Disable(); |
| 107 | } | 118 | } |
| 108 | 119 | ||
| 109 | auto result = VideoCommon::CachedQueryBase<HostCounter>::Flush(); | 120 | auto result = VideoCommon::CachedQueryBase<HostCounter>::Flush(); |
| 110 | 121 | ||
| 111 | if (slice_counter) { | 122 | if (slice_counter) { |
| 112 | stream.Update(true); | 123 | stream.Enable(); |
| 113 | } | 124 | } |
| 114 | 125 | ||
| 115 | return result; | 126 | return result; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 279e5a4e0..0545e33c5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -51,6 +51,22 @@ constexpr size_t NUM_SUPPORTED_VERTEX_ATTRIBUTES = 16; | |||
| 51 | void oglEnable(GLenum cap, bool state) { | 51 | void oglEnable(GLenum cap, bool state) { |
| 52 | (state ? glEnable : glDisable)(cap); | 52 | (state ? glEnable : glDisable)(cap); |
| 53 | } | 53 | } |
| 54 | |||
| 55 | std::optional<VideoCore::QueryType> MaxwellToVideoCoreQuery(VideoCommon::QueryType type) { | ||
| 56 | switch (type) { | ||
| 57 | case VideoCommon::QueryType::PrimitivesGenerated: | ||
| 58 | case VideoCommon::QueryType::VtgPrimitivesOut: | ||
| 59 | return VideoCore::QueryType::PrimitivesGenerated; | ||
| 60 | case VideoCommon::QueryType::ZPassPixelCount64: | ||
| 61 | return VideoCore::QueryType::SamplesPassed; | ||
| 62 | case VideoCommon::QueryType::StreamingPrimitivesSucceeded: | ||
| 63 | // case VideoCommon::QueryType::StreamingByteCount: | ||
| 64 | // TODO: StreamingByteCount = StreamingPrimitivesSucceeded * num_verts * vert_stride | ||
| 65 | return VideoCore::QueryType::TfbPrimitivesWritten; | ||
| 66 | default: | ||
| 67 | return std::nullopt; | ||
| 68 | } | ||
| 69 | } | ||
| 54 | } // Anonymous namespace | 70 | } // Anonymous namespace |
| 55 | 71 | ||
| 56 | RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, | 72 | RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, |
| @@ -212,7 +228,6 @@ void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) { | |||
| 212 | 228 | ||
| 213 | SCOPE_EXIT({ gpu.TickWork(); }); | 229 | SCOPE_EXIT({ gpu.TickWork(); }); |
| 214 | gpu_memory->FlushCaching(); | 230 | gpu_memory->FlushCaching(); |
| 215 | query_cache.UpdateCounters(); | ||
| 216 | 231 | ||
| 217 | GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; | 232 | GraphicsPipeline* const pipeline{shader_cache.CurrentGraphicsPipeline()}; |
| 218 | if (!pipeline) { | 233 | if (!pipeline) { |
| @@ -330,7 +345,6 @@ void RasterizerOpenGL::DrawTexture() { | |||
| 330 | MICROPROFILE_SCOPE(OpenGL_Drawing); | 345 | MICROPROFILE_SCOPE(OpenGL_Drawing); |
| 331 | 346 | ||
| 332 | SCOPE_EXIT({ gpu.TickWork(); }); | 347 | SCOPE_EXIT({ gpu.TickWork(); }); |
| 333 | query_cache.UpdateCounters(); | ||
| 334 | 348 | ||
| 335 | texture_cache.SynchronizeGraphicsDescriptors(); | 349 | texture_cache.SynchronizeGraphicsDescriptors(); |
| 336 | texture_cache.UpdateRenderTargets(false); | 350 | texture_cache.UpdateRenderTargets(false); |
| @@ -397,21 +411,28 @@ void RasterizerOpenGL::DispatchCompute() { | |||
| 397 | } | 411 | } |
| 398 | 412 | ||
| 399 | void RasterizerOpenGL::ResetCounter(VideoCommon::QueryType type) { | 413 | void RasterizerOpenGL::ResetCounter(VideoCommon::QueryType type) { |
| 400 | if (type == VideoCommon::QueryType::ZPassPixelCount64) { | 414 | const auto query_cache_type = MaxwellToVideoCoreQuery(type); |
| 401 | query_cache.ResetCounter(VideoCore::QueryType::SamplesPassed); | 415 | if (!query_cache_type.has_value()) { |
| 416 | UNIMPLEMENTED_MSG("Reset query type: {}", type); | ||
| 417 | return; | ||
| 402 | } | 418 | } |
| 419 | query_cache.ResetCounter(*query_cache_type); | ||
| 403 | } | 420 | } |
| 404 | 421 | ||
| 405 | void RasterizerOpenGL::Query(GPUVAddr gpu_addr, VideoCommon::QueryType type, | 422 | void RasterizerOpenGL::Query(GPUVAddr gpu_addr, VideoCommon::QueryType type, |
| 406 | VideoCommon::QueryPropertiesFlags flags, u32 payload, u32 subreport) { | 423 | VideoCommon::QueryPropertiesFlags flags, u32 payload, u32 subreport) { |
| 407 | if (type == VideoCommon::QueryType::ZPassPixelCount64) { | 424 | const auto query_cache_type = MaxwellToVideoCoreQuery(type); |
| 408 | if (True(flags & VideoCommon::QueryPropertiesFlags::HasTimeout)) { | 425 | if (!query_cache_type.has_value()) { |
| 409 | query_cache.Query(gpu_addr, VideoCore::QueryType::SamplesPassed, {gpu.GetTicks()}); | 426 | return QueryFallback(gpu_addr, type, flags, payload, subreport); |
| 410 | } else { | ||
| 411 | query_cache.Query(gpu_addr, VideoCore::QueryType::SamplesPassed, std::nullopt); | ||
| 412 | } | ||
| 413 | return; | ||
| 414 | } | 427 | } |
| 428 | const bool has_timeout = True(flags & VideoCommon::QueryPropertiesFlags::HasTimeout); | ||
| 429 | const auto timestamp = has_timeout ? std::optional<u64>{gpu.GetTicks()} : std::nullopt; | ||
| 430 | query_cache.Query(gpu_addr, *query_cache_type, timestamp); | ||
| 431 | } | ||
| 432 | |||
| 433 | void RasterizerOpenGL::QueryFallback(GPUVAddr gpu_addr, VideoCommon::QueryType type, | ||
| 434 | VideoCommon::QueryPropertiesFlags flags, u32 payload, | ||
| 435 | u32 subreport) { | ||
| 415 | if (type != VideoCommon::QueryType::Payload) { | 436 | if (type != VideoCommon::QueryType::Payload) { |
| 416 | payload = 1u; | 437 | payload = 1u; |
| 417 | } | 438 | } |
| @@ -1294,15 +1315,13 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum | |||
| 1294 | program->ConfigureTransformFeedback(); | 1315 | program->ConfigureTransformFeedback(); |
| 1295 | 1316 | ||
| 1296 | UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || | 1317 | UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) || |
| 1297 | regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) || | 1318 | regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation)); |
| 1298 | regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry)); | ||
| 1299 | UNIMPLEMENTED_IF(primitive_mode != GL_POINTS); | ||
| 1300 | 1319 | ||
| 1301 | // We may have to call BeginTransformFeedbackNV here since they seem to call different | 1320 | // We may have to call BeginTransformFeedbackNV here since they seem to call different |
| 1302 | // implementations on Nvidia's driver (the pointer is different) but we are using | 1321 | // implementations on Nvidia's driver (the pointer is different) but we are using |
| 1303 | // ARB_transform_feedback3 features with NV_transform_feedback interactions and the ARB | 1322 | // ARB_transform_feedback3 features with NV_transform_feedback interactions and the ARB |
| 1304 | // extension doesn't define BeginTransformFeedback (without NV) interactions. It just works. | 1323 | // extension doesn't define BeginTransformFeedback (without NV) interactions. It just works. |
| 1305 | glBeginTransformFeedback(GL_POINTS); | 1324 | glBeginTransformFeedback(primitive_mode); |
| 1306 | } | 1325 | } |
| 1307 | 1326 | ||
| 1308 | void RasterizerOpenGL::EndTransformFeedback() { | 1327 | void RasterizerOpenGL::EndTransformFeedback() { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index ceffe1f1e..b79d7a70c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -225,6 +225,9 @@ private: | |||
| 225 | /// End a transform feedback | 225 | /// End a transform feedback |
| 226 | void EndTransformFeedback(); | 226 | void EndTransformFeedback(); |
| 227 | 227 | ||
| 228 | void QueryFallback(GPUVAddr gpu_addr, VideoCommon::QueryType type, | ||
| 229 | VideoCommon::QueryPropertiesFlags flags, u32 payload, u32 subreport); | ||
| 230 | |||
| 228 | Tegra::GPU& gpu; | 231 | Tegra::GPU& gpu; |
| 229 | 232 | ||
| 230 | const Device& device; | 233 | const Device& device; |