1
0
forked from Rowland/EG

补完调试信息

This commit is contained in:
Rowland 2025-09-24 14:20:26 +08:00
parent b067e3a304
commit 76ca736824
2 changed files with 204 additions and 5 deletions

View File

@ -79,8 +79,8 @@ class Panda3DWorld(ShowBase):
ShowBase.__init__(self)
# 初始化渲染管线并设置可调整大小的标志
self.render_pipeline.create(self)
_global_render_pipeline = self.render_pipeline
# self.render_pipeline.create(self)
# _global_render_pipeline = self.render_pipeline
# 创建 Qt 能读的 RGBA8 贴图
self.qt_output_tex = Texture("qt_output_tex")
@ -138,7 +138,7 @@ class Panda3DWorld(ShowBase):
#self.cam = self.render_pipeline._showbase.cam
#self.camNode = self.cam.node()
#self.camLens = self.camNode.get_lens()
self.render_pipeline._showbase.camera = self.render_pipeline._showbase.cam
# self.render_pipeline._showbase.camera = self.render_pipeline._showbase.cam
#self.render_pipeline.daytime_mgr.update()

View File

@ -119,6 +119,18 @@ class VRManager(DirectObject):
self.sync_wait_times = []
self.pipeline_history_size = 30
# GPU渲染时间监控OpenVR Frame Timing
self.enable_gpu_timing = True # 是否启用GPU时间监控
self.gpu_scene_render_ms = 0.0 # GPU场景渲染时间
self.gpu_pre_submit_ms = 0.0 # 提交前GPU时间
self.gpu_post_submit_ms = 0.0 # 提交后GPU时间
self.gpu_total_render_ms = 0.0 # GPU总渲染时间
self.gpu_compositor_render_ms = 0.0 # GPU合成器渲染时间
self.gpu_client_frame_interval_ms = 0.0 # 客户端帧间隔
self.gpu_timing_history = [] # GPU时间历史记录
self.gpu_timing_history_size = 30 # GPU时间历史记录大小
self.gpu_timing_failure_count = 0 # GPU时间获取失败次数
# VR系统信息
self.current_eye_resolution = (self.eye_width, self.eye_height)
self.recommended_eye_resolution = (0, 0)
@ -530,6 +542,10 @@ class VRManager(DirectObject):
# 更新系统性能指标
self._update_performance_metrics()
# 更新GPU渲染时间统计
if self.enable_gpu_timing:
self._get_gpu_frame_timing()
# VR更新策略选择
if self.pose_strategy == 'update_task':
# 🚀 新的Running Start策略WaitGetPoses在Submit后调用此处只更新相机
@ -1190,6 +1206,64 @@ class VRManager(DirectObject):
print(f" GPU监控: 不可用 (需要安装 GPUtil 或 pynvml)")
print(f" 安装命令: pip install GPUtil nvidia-ml-py")
# GPU渲染时间OpenVR Frame Timing
if self.enable_gpu_timing:
print(f"⚡ GPU渲染时间:")
pipeline_stats = self._get_pipeline_stats()
gpu_stats = pipeline_stats.get('gpu_timing', {})
gpu_current = pipeline_stats.get('current', {})
# 检查是否有可用的GPU时间数据
has_gpu_data = any(
gpu_current.get(field, 0) > 0
for field in ['gpu_scene_render', 'gpu_total_render', 'gpu_pre_submit', 'gpu_post_submit', 'gpu_compositor_render']
)
if has_gpu_data:
# 显示GPU时间统计最近30帧平均
scene_render = gpu_stats.get('scene_render', {'avg': 0})
total_render = gpu_stats.get('total_render', {'avg': 0})
pre_submit = gpu_stats.get('pre_submit', {'avg': 0})
post_submit = gpu_stats.get('post_submit', {'avg': 0})
compositor = gpu_stats.get('compositor_render', {'avg': 0})
if scene_render['avg'] > 0:
print(f" GPU场景渲染: {scene_render['avg']:.2f}ms (min:{scene_render['min']:.1f}, max:{scene_render['max']:.1f})")
if total_render['avg'] > 0:
print(f" GPU总渲染时间: {total_render['avg']:.2f}ms (min:{total_render['min']:.1f}, max:{total_render['max']:.1f})")
if pre_submit['avg'] > 0:
print(f" GPU提交前时间: {pre_submit['avg']:.2f}ms (min:{pre_submit['min']:.1f}, max:{pre_submit['max']:.1f})")
if post_submit['avg'] > 0:
print(f" GPU提交后时间: {post_submit['avg']:.2f}ms (min:{post_submit['min']:.1f}, max:{post_submit['max']:.1f})")
if compositor['avg'] > 0:
print(f" GPU合成器时间: {compositor['avg']:.2f}ms (min:{compositor['min']:.1f}, max:{compositor['max']:.1f})")
# 显示当前帧GPU时间
print(f"🔍 当前帧GPU时间:")
if gpu_current.get('gpu_scene_render', 0) > 0:
print(f" 场景渲染: {gpu_current['gpu_scene_render']:.2f}ms")
if gpu_current.get('gpu_total_render', 0) > 0:
print(f" 总渲染: {gpu_current['gpu_total_render']:.2f}ms")
if gpu_current.get('gpu_compositor_render', 0) > 0:
print(f" 合成器: {gpu_current['gpu_compositor_render']:.2f}ms")
# GPU时间瓶颈分析
current_total = gpu_current.get('gpu_total_render', 0)
current_scene = gpu_current.get('gpu_scene_render', 0)
if current_total > 12.0: # 假设72fps目标留出一些余量
print(f" ⚠️ GPU总渲染时间过长: {current_total:.1f}ms")
elif current_scene > 8.0:
print(f" ⚠️ GPU场景渲染时间偏高: {current_scene:.1f}ms")
else:
print(f" GPU渲染时间: 暂无数据")
if self.gpu_timing_failure_count > 0:
print(f" 获取失败次数: {self.gpu_timing_failure_count}")
else:
print(f" 等待OpenVR Frame Timing数据...")
else:
print(f"⚡ GPU渲染时间: 已禁用")
# VR特定指标
print(f"🥽 VR指标:")
print(f" 总帧数: {stats['frame_count']}")
@ -1306,6 +1380,17 @@ class VRManager(DirectObject):
if stats['gpu_memory_usage'] > 90:
recommendations.append(" 🔴 显存使用率过高,可能需要降低纹理质量")
# GPU渲染时间建议
if self.enable_gpu_timing:
if self.gpu_total_render_ms > 12.0:
recommendations.append(" ⚠️ GPU总渲染时间过长建议优化场景复杂度")
if self.gpu_scene_render_ms > 8.0:
recommendations.append(" ⚠️ GPU场景渲染时间偏高考虑降低渲染质量")
if self.gpu_compositor_render_ms > 3.0:
recommendations.append(" ⚠️ GPU合成器时间过长检查VR设置或叠加层")
if self.gpu_timing_failure_count > 100:
recommendations.append(" ⚠️ GPU时间统计频繁失败可能需要更新OpenVR")
# 失败率建议
submit_fail_rate = (stats['submit_failures'] / max(stats['frame_count'], 1)) * 100
if submit_fail_rate > 1:
@ -1357,6 +1442,17 @@ class VRManager(DirectObject):
elif current['total_render'] > 0:
summary += f" | 渲染: {current['total_render']:.1f}ms"
# 添加GPU渲染时间信息
if self.enable_gpu_timing:
gpu_total = current.get('gpu_total_render', 0)
gpu_scene = current.get('gpu_scene_render', 0)
if gpu_total > 12.0:
summary += f" | GPU: {gpu_total:.1f}ms⚠"
elif gpu_total > 0:
summary += f" | GPU: {gpu_total:.1f}ms"
elif gpu_scene > 0:
summary += f" | GPU场景: {gpu_scene:.1f}ms"
# 显示目标帧时间对比
vr_info = pipeline_stats['vr_info']
if vr_info['target_frame_time_ms'] > 0:
@ -1979,18 +2075,41 @@ class VRManager(DirectObject):
'max': max(times_list)
}
# 计算GPU时间统计
def get_gpu_field_stats(field_name):
"""从GPU时间历史记录中提取特定字段的统计信息"""
values = []
for gpu_data in self.gpu_timing_history:
if field_name in gpu_data:
values.append(gpu_data[field_name])
return get_stats(values)
return {
'wait_poses': get_stats(self.wait_poses_times),
'render': get_stats(self.render_times),
'submit': get_stats(self.submit_times),
'sync_wait': get_stats(self.sync_wait_times),
'gpu_timing': {
'scene_render': get_gpu_field_stats('scene_render'),
'pre_submit': get_gpu_field_stats('pre_submit'),
'post_submit': get_gpu_field_stats('post_submit'),
'total_render': get_gpu_field_stats('total_render'),
'compositor_render': get_gpu_field_stats('compositor_render'),
'frame_interval': get_gpu_field_stats('frame_interval')
},
'current': {
'wait_poses': self.wait_poses_time,
'left_render': self.left_render_time,
'right_render': self.right_render_time,
'submit': self.submit_time,
'sync_wait': self.vr_sync_wait_time,
'total_render': self.left_render_time + self.right_render_time
'total_render': self.left_render_time + self.right_render_time,
'gpu_scene_render': self.gpu_scene_render_ms,
'gpu_pre_submit': self.gpu_pre_submit_ms,
'gpu_post_submit': self.gpu_post_submit_ms,
'gpu_total_render': self.gpu_total_render_ms,
'gpu_compositor_render': self.gpu_compositor_render_ms,
'gpu_frame_interval': self.gpu_client_frame_interval_ms
},
'vr_info': {
'eye_resolution': self.current_eye_resolution,
@ -2001,7 +2120,9 @@ class VRManager(DirectObject):
'vsync_to_photons_ms': self.vsync_to_photons_ms,
'vsync_window_ms': self.vsync_window_ms,
'async_reprojection': self.async_reprojection_enabled,
'motion_smoothing': self.motion_smoothing_enabled
'motion_smoothing': self.motion_smoothing_enabled,
'gpu_timing_enabled': self.enable_gpu_timing,
'gpu_timing_failures': self.gpu_timing_failure_count
}
}
@ -2130,6 +2251,84 @@ class VRManager(DirectObject):
except Exception as e:
print(f"⚠️ NVIDIA-ML初始化失败: {e}")
def _get_gpu_frame_timing(self, frames_ago=0):
"""获取GPU渲染时间统计
Args:
frames_ago: 获取多少帧之前的数据0表示当前帧
Returns:
dict: GPU时间数据如果获取失败返回None
"""
if not self.enable_gpu_timing or not self.vr_compositor:
return None
try:
# 调用OpenVR的getFrameTiming API
result, timing = self.vr_compositor.getFrameTiming(framesAgo=frames_ago)
if not result:
self.gpu_timing_failure_count += 1
if self.gpu_timing_failure_count % 300 == 1: # 每5秒输出一次错误
print("⚠️ OpenVR getFrameTiming调用失败")
return None
# 提取GPU时间数据单位毫秒
gpu_data = {}
# 检查timing对象是否有GPU时间相关的属性
if hasattr(timing, 'm_flSceneRenderGpuMs'):
gpu_data['scene_render'] = timing.m_flSceneRenderGpuMs
self.gpu_scene_render_ms = timing.m_flSceneRenderGpuMs
if hasattr(timing, 'm_flPreSubmitGpuMs'):
gpu_data['pre_submit'] = timing.m_flPreSubmitGpuMs
self.gpu_pre_submit_ms = timing.m_flPreSubmitGpuMs
if hasattr(timing, 'm_flPostSubmitGpuMs'):
gpu_data['post_submit'] = timing.m_flPostSubmitGpuMs
self.gpu_post_submit_ms = timing.m_flPostSubmitGpuMs
if hasattr(timing, 'm_flTotalRenderGpuMs'):
gpu_data['total_render'] = timing.m_flTotalRenderGpuMs
self.gpu_total_render_ms = timing.m_flTotalRenderGpuMs
if hasattr(timing, 'm_flCompositorRenderGpuMs'):
gpu_data['compositor_render'] = timing.m_flCompositorRenderGpuMs
self.gpu_compositor_render_ms = timing.m_flCompositorRenderGpuMs
if hasattr(timing, 'm_flClientFrameIntervalMs'):
gpu_data['frame_interval'] = timing.m_flClientFrameIntervalMs
self.gpu_client_frame_interval_ms = timing.m_flClientFrameIntervalMs
# 将GPU时间数据添加到历史记录
if gpu_data:
self.gpu_timing_history.append(gpu_data)
if len(self.gpu_timing_history) > self.gpu_timing_history_size:
self.gpu_timing_history.pop(0)
# 调试信息 - 仅在第一次成功时输出
if not hasattr(self, '_gpu_timing_success_logged'):
available_fields = list(gpu_data.keys())
print(f"✅ GPU时间统计已启用 - 可用字段: {available_fields}")
self._gpu_timing_success_logged = True
return gpu_data
except AttributeError as e:
# OpenVR Python绑定可能不包含某些字段
if self.gpu_timing_failure_count == 0:
print(f"⚠️ GPU时间统计部分功能不可用: {e}")
print(" 这可能是由于OpenVR Python绑定版本问题")
self.gpu_timing_failure_count += 1
return None
except Exception as e:
self.gpu_timing_failure_count += 1
if self.gpu_timing_failure_count % 300 == 1: # 每5秒输出一次错误
print(f"⚠️ 获取GPU时间统计失败: {e}")
return None
def _update_performance_metrics(self):
"""更新系统性能指标"""
if not self.performance_monitoring: