优化
This commit is contained in:
@@ -123,6 +123,30 @@ Frame_Statistics_Sample Render_Frame::statistics() const {
|
|||||||
Frame_Statistic::backend_apply_ms,
|
Frame_Statistic::backend_apply_ms,
|
||||||
Frame_Statistic::backend_plan_ms,
|
Frame_Statistic::backend_plan_ms,
|
||||||
Frame_Statistic::backend_execute_ms,
|
Frame_Statistic::backend_execute_ms,
|
||||||
|
Frame_Statistic::backend_target_acquire_ms,
|
||||||
|
Frame_Statistic::backend_structure_check_ms,
|
||||||
|
Frame_Statistic::backend_query_ms,
|
||||||
|
Frame_Statistic::backend_runtime_plan_ms,
|
||||||
|
Frame_Statistic::backend_runtime_execute_ms,
|
||||||
|
Frame_Statistic::backend_mvp_update_ms,
|
||||||
|
Frame_Statistic::backend_frame_begin_ms,
|
||||||
|
Frame_Statistic::backend_frame_plan_ms,
|
||||||
|
Frame_Statistic::backend_external_register_ms,
|
||||||
|
Frame_Statistic::backend_frame_attach_ms,
|
||||||
|
Frame_Statistic::backend_frame_execute_ms,
|
||||||
|
Frame_Statistic::backend_frame_finish_ms,
|
||||||
|
Frame_Statistic::backend_drp_validation_ms,
|
||||||
|
Frame_Statistic::backend_drp_state_ms,
|
||||||
|
Frame_Statistic::backend_drp_buffer_create_ms,
|
||||||
|
Frame_Statistic::backend_drp_texture_create_ms,
|
||||||
|
Frame_Statistic::backend_drp_shader_create_ms,
|
||||||
|
Frame_Statistic::backend_drp_shader_compile_ms,
|
||||||
|
Frame_Statistic::backend_drp_shader_module_create_ms,
|
||||||
|
Frame_Statistic::backend_drp_pipeline_create_ms,
|
||||||
|
Frame_Statistic::backend_drp_binding_create_ms,
|
||||||
|
Frame_Statistic::backend_drp_upload_ms,
|
||||||
|
Frame_Statistic::backend_drp_transfer_ms,
|
||||||
|
Frame_Statistic::backend_drp_record_ms,
|
||||||
Frame_Statistic::backend_submit_queue_ms,
|
Frame_Statistic::backend_submit_queue_ms,
|
||||||
Frame_Statistic::backend_submit_ms,
|
Frame_Statistic::backend_submit_ms,
|
||||||
Frame_Statistic::gpu_completion_observation_ms,
|
Frame_Statistic::gpu_completion_observation_ms,
|
||||||
@@ -136,6 +160,30 @@ Frame_Statistics_Sample Render_Frame::statistics() const {
|
|||||||
Frame_Trace_Measurement::backend_apply_ns,
|
Frame_Trace_Measurement::backend_apply_ns,
|
||||||
Frame_Trace_Measurement::backend_plan_ns,
|
Frame_Trace_Measurement::backend_plan_ns,
|
||||||
Frame_Trace_Measurement::backend_execute_ns,
|
Frame_Trace_Measurement::backend_execute_ns,
|
||||||
|
Frame_Trace_Measurement::backend_target_acquire_ns,
|
||||||
|
Frame_Trace_Measurement::backend_structure_check_ns,
|
||||||
|
Frame_Trace_Measurement::backend_query_ns,
|
||||||
|
Frame_Trace_Measurement::backend_runtime_plan_ns,
|
||||||
|
Frame_Trace_Measurement::backend_runtime_execute_ns,
|
||||||
|
Frame_Trace_Measurement::backend_mvp_update_ns,
|
||||||
|
Frame_Trace_Measurement::backend_frame_begin_ns,
|
||||||
|
Frame_Trace_Measurement::backend_frame_plan_ns,
|
||||||
|
Frame_Trace_Measurement::backend_external_register_ns,
|
||||||
|
Frame_Trace_Measurement::backend_frame_attach_ns,
|
||||||
|
Frame_Trace_Measurement::backend_frame_execute_ns,
|
||||||
|
Frame_Trace_Measurement::backend_frame_finish_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_validation_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_state_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_buffer_create_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_texture_create_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_shader_create_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_shader_compile_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_shader_module_create_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_pipeline_create_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_binding_create_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_upload_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_transfer_ns,
|
||||||
|
Frame_Trace_Measurement::backend_drp_record_ns,
|
||||||
Frame_Trace_Measurement::backend_submit_queue_ns,
|
Frame_Trace_Measurement::backend_submit_queue_ns,
|
||||||
Frame_Trace_Measurement::backend_submit_ns,
|
Frame_Trace_Measurement::backend_submit_ns,
|
||||||
Frame_Trace_Measurement::gpu_completion_observation_ns,
|
Frame_Trace_Measurement::gpu_completion_observation_ns,
|
||||||
|
|||||||
@@ -54,6 +54,30 @@ enum struct Frame_Trace_Measurement : std::uint8_t {
|
|||||||
backend_apply_ns,
|
backend_apply_ns,
|
||||||
backend_plan_ns,
|
backend_plan_ns,
|
||||||
backend_execute_ns,
|
backend_execute_ns,
|
||||||
|
backend_target_acquire_ns,
|
||||||
|
backend_structure_check_ns,
|
||||||
|
backend_query_ns,
|
||||||
|
backend_runtime_plan_ns,
|
||||||
|
backend_runtime_execute_ns,
|
||||||
|
backend_mvp_update_ns,
|
||||||
|
backend_frame_begin_ns,
|
||||||
|
backend_frame_plan_ns,
|
||||||
|
backend_external_register_ns,
|
||||||
|
backend_frame_attach_ns,
|
||||||
|
backend_frame_execute_ns,
|
||||||
|
backend_frame_finish_ns,
|
||||||
|
backend_drp_validation_ns,
|
||||||
|
backend_drp_state_ns,
|
||||||
|
backend_drp_buffer_create_ns,
|
||||||
|
backend_drp_texture_create_ns,
|
||||||
|
backend_drp_shader_create_ns,
|
||||||
|
backend_drp_shader_compile_ns,
|
||||||
|
backend_drp_shader_module_create_ns,
|
||||||
|
backend_drp_pipeline_create_ns,
|
||||||
|
backend_drp_binding_create_ns,
|
||||||
|
backend_drp_upload_ns,
|
||||||
|
backend_drp_transfer_ns,
|
||||||
|
backend_drp_record_ns,
|
||||||
backend_submit_queue_ns,
|
backend_submit_queue_ns,
|
||||||
backend_submit_ns,
|
backend_submit_ns,
|
||||||
gpu_completion_observation_ns,
|
gpu_completion_observation_ns,
|
||||||
|
|||||||
@@ -19,6 +19,30 @@ enum struct Frame_Statistic : std::uint8_t {
|
|||||||
backend_apply_ms,
|
backend_apply_ms,
|
||||||
backend_plan_ms,
|
backend_plan_ms,
|
||||||
backend_execute_ms,
|
backend_execute_ms,
|
||||||
|
backend_target_acquire_ms,
|
||||||
|
backend_structure_check_ms,
|
||||||
|
backend_query_ms,
|
||||||
|
backend_runtime_plan_ms,
|
||||||
|
backend_runtime_execute_ms,
|
||||||
|
backend_mvp_update_ms,
|
||||||
|
backend_frame_begin_ms,
|
||||||
|
backend_frame_plan_ms,
|
||||||
|
backend_external_register_ms,
|
||||||
|
backend_frame_attach_ms,
|
||||||
|
backend_frame_execute_ms,
|
||||||
|
backend_frame_finish_ms,
|
||||||
|
backend_drp_validation_ms,
|
||||||
|
backend_drp_state_ms,
|
||||||
|
backend_drp_buffer_create_ms,
|
||||||
|
backend_drp_texture_create_ms,
|
||||||
|
backend_drp_shader_create_ms,
|
||||||
|
backend_drp_shader_compile_ms,
|
||||||
|
backend_drp_shader_module_create_ms,
|
||||||
|
backend_drp_pipeline_create_ms,
|
||||||
|
backend_drp_binding_create_ms,
|
||||||
|
backend_drp_upload_ms,
|
||||||
|
backend_drp_transfer_ms,
|
||||||
|
backend_drp_record_ms,
|
||||||
backend_submit_queue_ms,
|
backend_submit_queue_ms,
|
||||||
backend_submit_ms,
|
backend_submit_ms,
|
||||||
gpu_completion_observation_ms,
|
gpu_completion_observation_ms,
|
||||||
|
|||||||
@@ -354,9 +354,34 @@ nlohmann::json datoviz_observation_json(
|
|||||||
"queue_submit_wait",
|
"queue_submit_wait",
|
||||||
milliseconds(value.queue_submit_wait_ns)
|
milliseconds(value.queue_submit_wait_ns)
|
||||||
},
|
},
|
||||||
|
{"target_acquire", milliseconds(value.target_acquire_ns)},
|
||||||
|
{"structure_check", milliseconds(value.structure_check_ns)},
|
||||||
{"apply", milliseconds(value.apply_ns)},
|
{"apply", milliseconds(value.apply_ns)},
|
||||||
{"emit", milliseconds(value.emit_ns)},
|
{"query", milliseconds(value.query_ns)},
|
||||||
{"execute", milliseconds(value.execute_ns)},
|
{"runtime_plan", milliseconds(value.runtime_plan_ns)},
|
||||||
|
{"runtime_execute", milliseconds(value.runtime_execute_ns)},
|
||||||
|
{"mvp_update", milliseconds(value.mvp_update_ns)},
|
||||||
|
{"frame_begin", milliseconds(value.frame_begin_ns)},
|
||||||
|
{"frame_plan", milliseconds(value.frame_plan_ns)},
|
||||||
|
{"external_register", milliseconds(value.external_register_ns)},
|
||||||
|
{"frame_attach", milliseconds(value.frame_attach_ns)},
|
||||||
|
{"frame_execute", milliseconds(value.frame_execute_ns)},
|
||||||
|
{"frame_finish", milliseconds(value.frame_finish_ns)},
|
||||||
|
{"drp_validation", milliseconds(value.drp_validation_ns)},
|
||||||
|
{"drp_state", milliseconds(value.drp_state_ns)},
|
||||||
|
{"drp_buffer_create", milliseconds(value.drp_buffer_create_ns)},
|
||||||
|
{"drp_texture_create", milliseconds(value.drp_texture_create_ns)},
|
||||||
|
{"drp_shader_create", milliseconds(value.drp_shader_create_ns)},
|
||||||
|
{"drp_shader_compile", milliseconds(value.drp_shader_compile_ns)},
|
||||||
|
{
|
||||||
|
"drp_shader_module_create",
|
||||||
|
milliseconds(value.drp_shader_module_create_ns)
|
||||||
|
},
|
||||||
|
{"drp_pipeline_create", milliseconds(value.drp_pipeline_create_ns)},
|
||||||
|
{"drp_binding_create", milliseconds(value.drp_binding_create_ns)},
|
||||||
|
{"drp_upload", milliseconds(value.drp_upload_ns)},
|
||||||
|
{"drp_transfer", milliseconds(value.drp_transfer_ns)},
|
||||||
|
{"drp_record", milliseconds(value.drp_record_ns)},
|
||||||
{"submit", milliseconds(value.submit_ns)},
|
{"submit", milliseconds(value.submit_ns)},
|
||||||
{
|
{
|
||||||
"gpu_completion_observation",
|
"gpu_completion_observation",
|
||||||
@@ -372,7 +397,8 @@ nlohmann::json datoviz_observation_json(
|
|||||||
{
|
{
|
||||||
"traffic", {
|
"traffic", {
|
||||||
{"uploaded_bytes", value.uploaded_bytes},
|
{"uploaded_bytes", value.uploaded_bytes},
|
||||||
{"readback_bytes", value.readback_bytes}
|
{"readback_bytes", value.readback_bytes},
|
||||||
|
{"pipeline_create_count", value.drp_pipeline_create_count}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -387,6 +387,44 @@ protected:
|
|||||||
statistic_value("backend_execute_ms", "p95");
|
statistic_value("backend_execute_ms", "p95");
|
||||||
state.counters[prefix + "backend_execute_max_ms"] =
|
state.counters[prefix + "backend_execute_max_ms"] =
|
||||||
statistic_value("backend_execute_ms", "maximum");
|
statistic_value("backend_execute_ms", "maximum");
|
||||||
|
constexpr std::array detailed_backend_statistics{
|
||||||
|
"backend_target_acquire_ms",
|
||||||
|
"backend_structure_check_ms",
|
||||||
|
"backend_query_ms",
|
||||||
|
"backend_runtime_plan_ms",
|
||||||
|
"backend_runtime_execute_ms",
|
||||||
|
"backend_mvp_update_ms",
|
||||||
|
"backend_frame_begin_ms",
|
||||||
|
"backend_frame_plan_ms",
|
||||||
|
"backend_external_register_ms",
|
||||||
|
"backend_frame_attach_ms",
|
||||||
|
"backend_frame_execute_ms",
|
||||||
|
"backend_frame_finish_ms"};
|
||||||
|
constexpr std::array detailed_drp_statistics{
|
||||||
|
"backend_drp_validation_ms",
|
||||||
|
"backend_drp_state_ms",
|
||||||
|
"backend_drp_buffer_create_ms",
|
||||||
|
"backend_drp_texture_create_ms",
|
||||||
|
"backend_drp_shader_create_ms",
|
||||||
|
"backend_drp_shader_compile_ms",
|
||||||
|
"backend_drp_shader_module_create_ms",
|
||||||
|
"backend_drp_pipeline_create_ms",
|
||||||
|
"backend_drp_binding_create_ms",
|
||||||
|
"backend_drp_upload_ms",
|
||||||
|
"backend_drp_transfer_ms",
|
||||||
|
"backend_drp_record_ms"};
|
||||||
|
for (const std::string_view name : detailed_backend_statistics) {
|
||||||
|
state.counters[prefix + std::string{name} + "/p95"] =
|
||||||
|
statistic_value(name, "p95");
|
||||||
|
state.counters[prefix + std::string{name} + "/max"] =
|
||||||
|
statistic_value(name, "maximum");
|
||||||
|
}
|
||||||
|
for (const std::string_view name : detailed_drp_statistics) {
|
||||||
|
state.counters[prefix + std::string{name} + "/p95"] =
|
||||||
|
statistic_value(name, "p95");
|
||||||
|
state.counters[prefix + std::string{name} + "/max"] =
|
||||||
|
statistic_value(name, "maximum");
|
||||||
|
}
|
||||||
state.counters[prefix + "backend_submit_queue_ms"] =
|
state.counters[prefix + "backend_submit_queue_ms"] =
|
||||||
statistic_value("backend_submit_queue_ms", "average");
|
statistic_value("backend_submit_queue_ms", "average");
|
||||||
state.counters[prefix + "backend_submit_queue_p95_ms"] =
|
state.counters[prefix + "backend_submit_queue_p95_ms"] =
|
||||||
@@ -546,6 +584,45 @@ public:
|
|||||||
<< std::setw(10) << counter(prefix + "slot_backpressure")
|
<< std::setw(10) << counter(prefix + "slot_backpressure")
|
||||||
<< std::setw(9) << counter(prefix + "scene_rejected")
|
<< std::setw(9) << counter(prefix + "scene_rejected")
|
||||||
<< '\n';
|
<< '\n';
|
||||||
|
constexpr std::array detailed_backend_statistics{
|
||||||
|
std::pair{"acquire", "backend_target_acquire_ms"},
|
||||||
|
std::pair{"structure", "backend_structure_check_ms"},
|
||||||
|
std::pair{"query", "backend_query_ms"},
|
||||||
|
std::pair{"runtime-plan", "backend_runtime_plan_ms"},
|
||||||
|
std::pair{"runtime-exec", "backend_runtime_execute_ms"},
|
||||||
|
std::pair{"mvp", "backend_mvp_update_ms"},
|
||||||
|
std::pair{"frame-begin", "backend_frame_begin_ms"},
|
||||||
|
std::pair{"frame-plan", "backend_frame_plan_ms"},
|
||||||
|
std::pair{"external", "backend_external_register_ms"},
|
||||||
|
std::pair{"attach", "backend_frame_attach_ms"},
|
||||||
|
std::pair{"frame-exec", "backend_frame_execute_ms"},
|
||||||
|
std::pair{"finish", "backend_frame_finish_ms"}};
|
||||||
|
output << " backend-detail " << id;
|
||||||
|
for (const auto& [label, statistic] :
|
||||||
|
detailed_backend_statistics)
|
||||||
|
output << " " << label << "95/max="
|
||||||
|
<< counter(prefix + statistic + "/p95") << "/"
|
||||||
|
<< counter(prefix + statistic + "/max");
|
||||||
|
output << '\n';
|
||||||
|
constexpr std::array detailed_drp_statistics{
|
||||||
|
std::pair{"validate", "backend_drp_validation_ms"},
|
||||||
|
std::pair{"state", "backend_drp_state_ms"},
|
||||||
|
std::pair{"buffer", "backend_drp_buffer_create_ms"},
|
||||||
|
std::pair{"texture", "backend_drp_texture_create_ms"},
|
||||||
|
std::pair{"shader", "backend_drp_shader_create_ms"},
|
||||||
|
std::pair{"shader-compile", "backend_drp_shader_compile_ms"},
|
||||||
|
std::pair{"shader-module", "backend_drp_shader_module_create_ms"},
|
||||||
|
std::pair{"pipeline", "backend_drp_pipeline_create_ms"},
|
||||||
|
std::pair{"binding", "backend_drp_binding_create_ms"},
|
||||||
|
std::pair{"upload", "backend_drp_upload_ms"},
|
||||||
|
std::pair{"transfer", "backend_drp_transfer_ms"},
|
||||||
|
std::pair{"record", "backend_drp_record_ms"}};
|
||||||
|
output << " drp-detail " << id;
|
||||||
|
for (const auto& [label, statistic] : detailed_drp_statistics)
|
||||||
|
output << " " << label << "95/max="
|
||||||
|
<< counter(prefix + statistic + "/p95") << "/"
|
||||||
|
<< counter(prefix + statistic + "/max");
|
||||||
|
output << '\n';
|
||||||
}
|
}
|
||||||
output << "aggregate_fps=" << counter("aggregate_fps")
|
output << "aggregate_fps=" << counter("aggregate_fps")
|
||||||
<< " min_fps=" << counter("minimum_plot_fps")
|
<< " min_fps=" << counter("minimum_plot_fps")
|
||||||
|
|||||||
@@ -31,9 +31,32 @@ struct Datoviz_Frame_Observation {
|
|||||||
bool controller_input_applied{}; /* 本帧是否把已提交输入应用到 Datoviz 控制器。 */
|
bool controller_input_applied{}; /* 本帧是否把已提交输入应用到 Datoviz 控制器。 */
|
||||||
bool prepare_released_after_submission{}; /* 本帧实际提交后是否立即允许下一帧 Prepare。 */
|
bool prepare_released_after_submission{}; /* 本帧实际提交后是否立即允许下一帧 Prepare。 */
|
||||||
std::uint64_t queue_submit_wait_ns{}; /* 获取共享 VkQueue 提交权的墙钟耗时。 */
|
std::uint64_t queue_submit_wait_ns{}; /* 获取共享 VkQueue 提交权的墙钟耗时。 */
|
||||||
std::uint64_t apply_ns{}; /* 应用本帧 Visual 数据耗时。 */
|
std::uint64_t target_acquire_ns{}; /* 查找或创建本帧三槽目标的墙钟耗时。 */
|
||||||
std::uint64_t emit_ns{}; /* 生成 Datoviz 帧计划耗时。 */
|
std::uint64_t structure_check_ns{}; /* 判断命令结构是否变化的墙钟耗时。 */
|
||||||
std::uint64_t execute_ns{}; /* 执行 Datoviz 帧计划耗时。 */
|
std::uint64_t apply_ns{}; /* 应用 Camera、Axes 和 Visual 数据的墙钟耗时。 */
|
||||||
|
std::uint64_t query_ns{}; /* 处理 Datoviz 查询与悬浮读数的墙钟耗时。 */
|
||||||
|
std::uint64_t runtime_plan_ns{}; /* 生成增量 Runtime 资源命令流的墙钟耗时。 */
|
||||||
|
std::uint64_t runtime_execute_ns{}; /* 执行增量 Runtime 资源命令流的墙钟耗时。 */
|
||||||
|
std::uint64_t mvp_update_ns{}; /* 更新可复用命令所引用 MVP 缓冲的墙钟耗时。 */
|
||||||
|
std::uint64_t frame_begin_ns{}; /* 重置并开始目标命令缓冲录制的墙钟耗时。 */
|
||||||
|
std::uint64_t frame_plan_ns{}; /* 生成完整 Datoviz 帧计划的墙钟耗时。 */
|
||||||
|
std::uint64_t external_register_ns{}; /* 注册外部属性缓冲的墙钟耗时。 */
|
||||||
|
std::uint64_t frame_attach_ns{}; /* 把借用目标附加到 DRP2 Runtime 的墙钟耗时。 */
|
||||||
|
std::uint64_t frame_execute_ns{}; /* 执行完整帧命令流的墙钟耗时。 */
|
||||||
|
std::uint64_t frame_finish_ns{}; /* 完成命令录制并建立提交描述的墙钟耗时。 */
|
||||||
|
std::uint64_t drp_validation_ns{}; /* DRP2 语义验证与状态复制耗时。 */
|
||||||
|
std::uint64_t drp_state_ns{}; /* DRP2 状态建立与提交耗时。 */
|
||||||
|
std::uint64_t drp_buffer_create_ns{}; /* Vulkan Buffer 创建命令耗时。 */
|
||||||
|
std::uint64_t drp_texture_create_ns{}; /* Vulkan Texture 创建命令耗时。 */
|
||||||
|
std::uint64_t drp_shader_create_ns{}; /* Vulkan Shader Module 创建命令耗时。 */
|
||||||
|
std::uint64_t drp_shader_compile_ns{}; /* Shader Module 命令中 GLSL 到 SPIR-V 的编译耗时。 */
|
||||||
|
std::uint64_t drp_shader_module_create_ns{}; /* Shader Module 命令中 vkCreateShaderModule 的耗时。 */
|
||||||
|
std::uint64_t drp_pipeline_create_ns{}; /* Vulkan Pipeline 创建命令耗时。 */
|
||||||
|
std::uint64_t drp_binding_create_ns{}; /* Sampler、Layout 与 Bind Group 创建命令耗时。 */
|
||||||
|
std::uint64_t drp_upload_ns{}; /* Buffer 与 Texture 写入命令耗时。 */
|
||||||
|
std::uint64_t drp_transfer_ns{}; /* 显式 Copy 命令耗时。 */
|
||||||
|
std::uint64_t drp_record_ns{}; /* Render/Compute Pass 录制命令耗时。 */
|
||||||
|
std::uint32_t drp_pipeline_create_count{}; /* 本帧实际创建的图形/计算管线数。 */
|
||||||
std::uint64_t submit_ns{}; /* Vulkan 队列提交耗时。 */
|
std::uint64_t submit_ns{}; /* Vulkan 队列提交耗时。 */
|
||||||
std::uint64_t gpu_completion_observation_ns{}; /* 从 watch 到探测到 fence 完成的墙钟耗时。 */
|
std::uint64_t gpu_completion_observation_ns{}; /* 从 watch 到探测到 fence 完成的墙钟耗时。 */
|
||||||
std::uint64_t completion_task_queue_ns{}; /* 探测到 fence 完成后,Scene completion task 的排队耗时。 */
|
std::uint64_t completion_task_queue_ns{}; /* 探测到 fence 完成后,Scene completion task 的排队耗时。 */
|
||||||
|
|||||||
@@ -208,12 +208,67 @@ inline void publish_datoviz_observation(
|
|||||||
if (observation.apply_ns)
|
if (observation.apply_ns)
|
||||||
frame->record(Frame_Trace_Measurement::backend_apply_ns,
|
frame->record(Frame_Trace_Measurement::backend_apply_ns,
|
||||||
observation.apply_ns);
|
observation.apply_ns);
|
||||||
if (observation.emit_ns)
|
const auto plan_ns = observation.runtime_plan_ns +
|
||||||
|
observation.frame_plan_ns;
|
||||||
|
const auto execute_ns = observation.runtime_execute_ns +
|
||||||
|
observation.frame_attach_ns + observation.frame_execute_ns;
|
||||||
|
if (plan_ns)
|
||||||
frame->record(Frame_Trace_Measurement::backend_plan_ns,
|
frame->record(Frame_Trace_Measurement::backend_plan_ns,
|
||||||
observation.emit_ns);
|
plan_ns);
|
||||||
if (observation.execute_ns)
|
if (execute_ns)
|
||||||
frame->record(Frame_Trace_Measurement::backend_execute_ns,
|
frame->record(Frame_Trace_Measurement::backend_execute_ns,
|
||||||
observation.execute_ns);
|
execute_ns);
|
||||||
|
const std::array detailed_timings{
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_target_acquire_ns,
|
||||||
|
observation.target_acquire_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_structure_check_ns,
|
||||||
|
observation.structure_check_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_query_ns,
|
||||||
|
observation.query_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_runtime_plan_ns,
|
||||||
|
observation.runtime_plan_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_runtime_execute_ns,
|
||||||
|
observation.runtime_execute_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_mvp_update_ns,
|
||||||
|
observation.mvp_update_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_frame_begin_ns,
|
||||||
|
observation.frame_begin_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_frame_plan_ns,
|
||||||
|
observation.frame_plan_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_external_register_ns,
|
||||||
|
observation.external_register_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_frame_attach_ns,
|
||||||
|
observation.frame_attach_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_frame_execute_ns,
|
||||||
|
observation.frame_execute_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_frame_finish_ns,
|
||||||
|
observation.frame_finish_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_validation_ns,
|
||||||
|
observation.drp_validation_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_state_ns,
|
||||||
|
observation.drp_state_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_buffer_create_ns,
|
||||||
|
observation.drp_buffer_create_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_texture_create_ns,
|
||||||
|
observation.drp_texture_create_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_shader_create_ns,
|
||||||
|
observation.drp_shader_create_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_shader_compile_ns,
|
||||||
|
observation.drp_shader_compile_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_shader_module_create_ns,
|
||||||
|
observation.drp_shader_module_create_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_pipeline_create_ns,
|
||||||
|
observation.drp_pipeline_create_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_binding_create_ns,
|
||||||
|
observation.drp_binding_create_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_upload_ns,
|
||||||
|
observation.drp_upload_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_transfer_ns,
|
||||||
|
observation.drp_transfer_ns},
|
||||||
|
std::pair{Frame_Trace_Measurement::backend_drp_record_ns,
|
||||||
|
observation.drp_record_ns}};
|
||||||
|
for (const auto& [measurement, value] : detailed_timings)
|
||||||
|
if (value) frame->record(measurement, value);
|
||||||
if (observation.queue_submit_wait_ns)
|
if (observation.queue_submit_wait_ns)
|
||||||
frame->record(Frame_Trace_Measurement::backend_submit_queue_ns,
|
frame->record(Frame_Trace_Measurement::backend_submit_queue_ns,
|
||||||
observation.queue_submit_wait_ns);
|
observation.queue_submit_wait_ns);
|
||||||
|
|||||||
@@ -6,6 +6,60 @@
|
|||||||
|
|
||||||
namespace aethera::render_3d::detail {
|
namespace aethera::render_3d::detail {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void accumulate_execution_timing(
|
||||||
|
const DvzDrp2ExecutionTiming& source,
|
||||||
|
Datoviz_Frame_Observation& target) noexcept {
|
||||||
|
const auto command = [&](DvzDrp2CommandType type) noexcept {
|
||||||
|
return source.command_ns[static_cast<std::uint32_t>(type)];
|
||||||
|
};
|
||||||
|
const auto count = [&](DvzDrp2CommandType type) noexcept {
|
||||||
|
return source.command_count[static_cast<std::uint32_t>(type)];
|
||||||
|
};
|
||||||
|
target.drp_validation_ns += source.validation_ns;
|
||||||
|
target.drp_state_ns += source.state_ensure_ns + source.state_commit_ns;
|
||||||
|
target.drp_buffer_create_ns += command(DVZ_DRP2_COMMAND_CREATE_BUFFER);
|
||||||
|
target.drp_texture_create_ns += command(DVZ_DRP2_COMMAND_CREATE_TEXTURE);
|
||||||
|
target.drp_shader_create_ns += command(DVZ_DRP2_COMMAND_CREATE_SHADER_MODULE);
|
||||||
|
target.drp_shader_compile_ns += source.shader_compile_ns;
|
||||||
|
target.drp_shader_module_create_ns += source.shader_module_create_ns;
|
||||||
|
target.drp_pipeline_create_ns +=
|
||||||
|
command(DVZ_DRP2_COMMAND_CREATE_RENDER_PIPELINE) +
|
||||||
|
command(DVZ_DRP2_COMMAND_CREATE_COMPUTE_PIPELINE);
|
||||||
|
target.drp_pipeline_create_count +=
|
||||||
|
count(DVZ_DRP2_COMMAND_CREATE_RENDER_PIPELINE) +
|
||||||
|
count(DVZ_DRP2_COMMAND_CREATE_COMPUTE_PIPELINE);
|
||||||
|
target.drp_binding_create_ns +=
|
||||||
|
command(DVZ_DRP2_COMMAND_CREATE_SAMPLER) +
|
||||||
|
command(DVZ_DRP2_COMMAND_CREATE_BIND_GROUP_LAYOUT) +
|
||||||
|
command(DVZ_DRP2_COMMAND_CREATE_BIND_GROUP);
|
||||||
|
target.drp_upload_ns += command(DVZ_DRP2_COMMAND_WRITE_BUFFER) +
|
||||||
|
command(DVZ_DRP2_COMMAND_WRITE_TEXTURE);
|
||||||
|
target.drp_transfer_ns +=
|
||||||
|
command(DVZ_DRP2_COMMAND_COPY_BUFFER_TO_BUFFER) +
|
||||||
|
command(DVZ_DRP2_COMMAND_COPY_BUFFER_TO_TEXTURE) +
|
||||||
|
command(DVZ_DRP2_COMMAND_COPY_TEXTURE_TO_BUFFER) +
|
||||||
|
command(DVZ_DRP2_COMMAND_COPY_TEXTURE_TO_TEXTURE);
|
||||||
|
constexpr std::array record_commands{
|
||||||
|
DVZ_DRP2_COMMAND_BEGIN_RENDER_PASS,
|
||||||
|
DVZ_DRP2_COMMAND_BEGIN_COMPUTE_PASS,
|
||||||
|
DVZ_DRP2_COMMAND_SET_VIEWPORT,
|
||||||
|
DVZ_DRP2_COMMAND_SET_SCISSOR,
|
||||||
|
DVZ_DRP2_COMMAND_SET_PIPELINE,
|
||||||
|
DVZ_DRP2_COMMAND_SET_BIND_GROUP,
|
||||||
|
DVZ_DRP2_COMMAND_SET_VERTEX_BUFFER,
|
||||||
|
DVZ_DRP2_COMMAND_SET_INDEX_BUFFER,
|
||||||
|
DVZ_DRP2_COMMAND_DRAW,
|
||||||
|
DVZ_DRP2_COMMAND_DRAW_INDEXED,
|
||||||
|
DVZ_DRP2_COMMAND_DISPATCH_WORKGROUPS,
|
||||||
|
DVZ_DRP2_COMMAND_END_RENDER_PASS,
|
||||||
|
DVZ_DRP2_COMMAND_END_COMPUTE_PASS,
|
||||||
|
DVZ_DRP2_COMMAND_RESOURCE_BARRIER};
|
||||||
|
for (const auto type : record_commands)
|
||||||
|
target.drp_record_ns += command(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Datoviz Scene 根据当前权威资源生成 DRP2 命令流描述,不提交 GPU。 */
|
/* Datoviz Scene 根据当前权威资源生成 DRP2 命令流描述,不提交 GPU。 */
|
||||||
DvzSceneFrameArtifact* Scene_Datoviz_State::emit(
|
DvzSceneFrameArtifact* Scene_Datoviz_State::emit(
|
||||||
const Scene_3D_Parameters& scene, std::uint8_t target_index) {
|
const Scene_3D_Parameters& scene, std::uint8_t target_index) {
|
||||||
@@ -143,12 +197,6 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
* VkQueue。它必须和 Render Domain 的显式 submit 使用同一外部同步域。
|
* VkQueue。它必须和 Render Domain 的显式 submit 使用同一外部同步域。
|
||||||
* 热路径的已录制目标复用在此锁之前返回,仍可在各 Scene 准备线程并行。
|
* 热路径的已录制目标复用在此锁之前返回,仍可在各 Scene 准备线程并行。
|
||||||
*/
|
*/
|
||||||
std::optional<std::uint8_t> target_index;
|
|
||||||
{
|
|
||||||
std::lock_guard resource_lock(target_mutex_);
|
|
||||||
target_index = acquire_target(scene.viewport);
|
|
||||||
}
|
|
||||||
if (!target_index) return std::nullopt;
|
|
||||||
Datoviz_Frame_Observation observation;
|
Datoviz_Frame_Observation observation;
|
||||||
observation.render_sequence = frame_sequence;
|
observation.render_sequence = frame_sequence;
|
||||||
observation.path = Datoviz_Frame_Path::recorded;
|
observation.path = Datoviz_Frame_Path::recorded;
|
||||||
@@ -156,14 +204,26 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
observation.readback_requested = readback;
|
observation.readback_requested = readback;
|
||||||
observation.controller_input_applied = input_changed_;
|
observation.controller_input_applied = input_changed_;
|
||||||
std::uint64_t phase_started = trace_now_ns();
|
std::uint64_t phase_started = trace_now_ns();
|
||||||
|
std::optional<std::uint8_t> target_index;
|
||||||
|
{
|
||||||
|
std::lock_guard resource_lock(target_mutex_);
|
||||||
|
target_index = acquire_target(scene.viewport);
|
||||||
|
}
|
||||||
|
observation.target_acquire_ns = trace_now_ns() - phase_started;
|
||||||
|
if (!target_index) return std::nullopt;
|
||||||
|
phase_started = trace_now_ns();
|
||||||
const bool content_changed = !matches_command_structure(scene, visuals);
|
const bool content_changed = !matches_command_structure(scene, visuals);
|
||||||
|
observation.structure_check_ns = trace_now_ns() - phase_started;
|
||||||
if (content_changed) ++command_revision_;
|
if (content_changed) ++command_revision_;
|
||||||
auto& frame_target = *targets_->values[*target_index];
|
auto& frame_target = *targets_->values[*target_index];
|
||||||
const bool bind_target =
|
const bool bind_target =
|
||||||
!frame_target.can_reuse_commands(command_revision_, readback);
|
!frame_target.can_reuse_commands(command_revision_, readback);
|
||||||
|
phase_started = trace_now_ns();
|
||||||
observation.uploaded_bytes = apply(
|
observation.uploaded_bytes = apply(
|
||||||
scene, visuals, *target_index, bind_target);
|
scene, visuals, *target_index, bind_target);
|
||||||
|
observation.apply_ns = trace_now_ns() - phase_started;
|
||||||
bool query_changed_scene{};
|
bool query_changed_scene{};
|
||||||
|
phase_started = trace_now_ns();
|
||||||
if (item_interaction_ != nullptr) {
|
if (item_interaction_ != nullptr) {
|
||||||
static_cast<void>(dvz_figure_process_queries(
|
static_cast<void>(dvz_figure_process_queries(
|
||||||
figure_, runtime_slots_[*target_index].runtime, nullptr));
|
figure_, runtime_slots_[*target_index].runtime, nullptr));
|
||||||
@@ -198,8 +258,8 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
observation.query_ns = trace_now_ns() - phase_started;
|
||||||
if (query_changed_scene) ++command_revision_;
|
if (query_changed_scene) ++command_revision_;
|
||||||
observation.apply_ns = trace_now_ns() - phase_started;
|
|
||||||
bool runtime_resources_updated{};
|
bool runtime_resources_updated{};
|
||||||
if (frame_target.can_reuse_commands(command_revision_, readback) &&
|
if (frame_target.can_reuse_commands(command_revision_, readback) &&
|
||||||
!target_runtime_resources_current(visuals, *target_index)) {
|
!target_runtime_resources_current(visuals, *target_index)) {
|
||||||
@@ -220,7 +280,7 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
&uploaded_bytes, &command_recording_valid, &report),
|
&uploaded_bytes, &command_recording_valid, &report),
|
||||||
&dvz_drp2_stream_destroy
|
&dvz_drp2_stream_destroy
|
||||||
};
|
};
|
||||||
observation.emit_ns += trace_now_ns() - phase_started;
|
observation.runtime_plan_ns = trace_now_ns() - phase_started;
|
||||||
if (!update_stream) {
|
if (!update_stream) {
|
||||||
std::string message =
|
std::string message =
|
||||||
"failed to prepare Datoviz retained runtime resources";
|
"failed to prepare Datoviz retained runtime resources";
|
||||||
@@ -233,11 +293,13 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
phase_started = trace_now_ns();
|
phase_started = trace_now_ns();
|
||||||
DvzDrp2ValidationResult update_result{};
|
DvzDrp2ValidationResult update_result{};
|
||||||
{
|
{
|
||||||
update_result = dvz_drp2_runtime_execute(
|
DvzDrp2ExecutionTiming timing{};
|
||||||
|
update_result = dvz_drp2_runtime_execute_timed(
|
||||||
runtime_slots_[*target_index].runtime,
|
runtime_slots_[*target_index].runtime,
|
||||||
update_stream.get());
|
update_stream.get(), &timing);
|
||||||
|
accumulate_execution_timing(timing, observation);
|
||||||
}
|
}
|
||||||
observation.execute_ns += trace_now_ns() - phase_started;
|
observation.runtime_execute_ns = trace_now_ns() - phase_started;
|
||||||
if (!update_result.ok)
|
if (!update_result.ok)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"failed to execute Datoviz retained runtime resources");
|
"failed to execute Datoviz retained runtime resources");
|
||||||
@@ -252,6 +314,7 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
* rebuilding the Figure artifact or re-recording commands. Structural Scene
|
* rebuilding the Figure artifact or re-recording commands. Structural Scene
|
||||||
* changes keep using command_revision_ and fall through to full recording. */
|
* changes keep using command_revision_ and fall through to full recording. */
|
||||||
bool mvp_updated{};
|
bool mvp_updated{};
|
||||||
|
phase_started = trace_now_ns();
|
||||||
if (frame_target.can_reuse_commands(command_revision_, readback) &&
|
if (frame_target.can_reuse_commands(command_revision_, readback) &&
|
||||||
!frame_target.can_reuse(
|
!frame_target.can_reuse(
|
||||||
command_revision_, controller_revision_, readback)) {
|
command_revision_, controller_revision_, readback)) {
|
||||||
@@ -265,6 +328,7 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
mvp_updated = true;
|
mvp_updated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
observation.mvp_update_ns = trace_now_ns() - phase_started;
|
||||||
if (frame_target.can_reuse(
|
if (frame_target.can_reuse(
|
||||||
command_revision_, controller_revision_, readback)) {
|
command_revision_, controller_revision_, readback)) {
|
||||||
{
|
{
|
||||||
@@ -284,9 +348,11 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
phase_started = trace_now_ns();
|
||||||
std::lock_guard recording_lock(target_mutex_);
|
std::lock_guard recording_lock(target_mutex_);
|
||||||
frame_target.begin(
|
frame_target.begin(
|
||||||
observe, readback, command_revision_, controller_revision_);
|
observe, readback, command_revision_, controller_revision_);
|
||||||
|
observation.frame_begin_ns = trace_now_ns() - phase_started;
|
||||||
}
|
}
|
||||||
struct Recording_Scope {
|
struct Recording_Scope {
|
||||||
Datoviz_Frame_Target& target; /* 异常退出时回收尚未发布的录制槽。 */
|
Datoviz_Frame_Target& target; /* 异常退出时回收尚未发布的录制槽。 */
|
||||||
@@ -307,7 +373,7 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
try {
|
try {
|
||||||
phase_started = trace_now_ns();
|
phase_started = trace_now_ns();
|
||||||
artifact.reset(emit(scene, *target_index));
|
artifact.reset(emit(scene, *target_index));
|
||||||
observation.emit_ns = trace_now_ns() - phase_started;
|
observation.frame_plan_ns = trace_now_ns() - phase_started;
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
raise_context("preparing Datoviz frame", std::current_exception());
|
raise_context("preparing Datoviz frame", std::current_exception());
|
||||||
@@ -322,21 +388,26 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
}
|
}
|
||||||
const DvzDrp2CommandStream* stream =
|
const DvzDrp2CommandStream* stream =
|
||||||
dvz_scene_frame_artifact_stream(artifact.get());
|
dvz_scene_frame_artifact_stream(artifact.get());
|
||||||
register_external_attributes(stream, *target_index);
|
|
||||||
const DvzStreamFrame target_frame = frame_target.stream_frame();
|
|
||||||
phase_started = trace_now_ns();
|
phase_started = trace_now_ns();
|
||||||
|
register_external_attributes(stream, *target_index);
|
||||||
|
observation.external_register_ns = trace_now_ns() - phase_started;
|
||||||
|
const DvzStreamFrame target_frame = frame_target.stream_frame();
|
||||||
bool attached{};
|
bool attached{};
|
||||||
DvzDrp2ValidationResult result{};
|
DvzDrp2ValidationResult result{};
|
||||||
{
|
phase_started = trace_now_ns();
|
||||||
attached = stream != nullptr &&
|
attached = stream != nullptr &&
|
||||||
dvz_drp2_runtime_attach_frame_target(
|
dvz_drp2_runtime_attach_frame_target(
|
||||||
runtime_slots_[*target_index].runtime,
|
runtime_slots_[*target_index].runtime,
|
||||||
color_target_id, &target_frame);
|
color_target_id, &target_frame);
|
||||||
if (attached)
|
observation.frame_attach_ns = trace_now_ns() - phase_started;
|
||||||
result = dvz_drp2_runtime_execute(
|
if (attached) {
|
||||||
runtime_slots_[*target_index].runtime, stream);
|
phase_started = trace_now_ns();
|
||||||
|
DvzDrp2ExecutionTiming timing{};
|
||||||
|
result = dvz_drp2_runtime_execute_timed(
|
||||||
|
runtime_slots_[*target_index].runtime, stream, &timing);
|
||||||
|
accumulate_execution_timing(timing, observation);
|
||||||
|
observation.frame_execute_ns = trace_now_ns() - phase_started;
|
||||||
}
|
}
|
||||||
observation.execute_ns = trace_now_ns() - phase_started;
|
|
||||||
observation.validation_performed = true;
|
observation.validation_performed = true;
|
||||||
observation.validation_ok = attached && result.ok;
|
observation.validation_ok = attached && result.ok;
|
||||||
observation.validation_code = static_cast<std::uint32_t>(result.code);
|
observation.validation_code = static_cast<std::uint32_t>(result.code);
|
||||||
@@ -364,8 +435,10 @@ std::optional<Datoviz_Pending_Frame> Scene_Datoviz_State::prepare(
|
|||||||
}
|
}
|
||||||
mark_target_runtime_resources_uploaded(*target_index);
|
mark_target_runtime_resources_uploaded(*target_index);
|
||||||
{
|
{
|
||||||
|
phase_started = trace_now_ns();
|
||||||
std::lock_guard recording_lock(target_mutex_);
|
std::lock_guard recording_lock(target_mutex_);
|
||||||
frame_target.finish_recording();
|
frame_target.finish_recording();
|
||||||
|
observation.frame_finish_ns = trace_now_ns() - phase_started;
|
||||||
}
|
}
|
||||||
recording_scope.released = true;
|
recording_scope.released = true;
|
||||||
input_changed_ = false;
|
input_changed_ = false;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ EXTERN_C_ON
|
|||||||
typedef struct DvzDrp2ValidationResult DvzDrp2ValidationResult;
|
typedef struct DvzDrp2ValidationResult DvzDrp2ValidationResult;
|
||||||
typedef struct DvzDrp2RuntimeConfig DvzDrp2RuntimeConfig;
|
typedef struct DvzDrp2RuntimeConfig DvzDrp2RuntimeConfig;
|
||||||
typedef struct DvzDrp2ExternalBufferDesc DvzDrp2ExternalBufferDesc;
|
typedef struct DvzDrp2ExternalBufferDesc DvzDrp2ExternalBufferDesc;
|
||||||
|
typedef struct DvzDrp2ExecutionTiming DvzDrp2ExecutionTiming;
|
||||||
typedef struct DvzDevice DvzDevice;
|
typedef struct DvzDevice DvzDevice;
|
||||||
typedef struct DvzStreamFrame DvzStreamFrame;
|
typedef struct DvzStreamFrame DvzStreamFrame;
|
||||||
typedef struct DvzVma DvzVma;
|
typedef struct DvzVma DvzVma;
|
||||||
@@ -72,6 +73,19 @@ struct DvzDrp2ExternalBufferDesc
|
|||||||
uint32_t usage;
|
uint32_t usage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DVZ_DRP2_COMMAND_TYPE_COUNT ((uint32_t)DVZ_DRP2_COMMAND_QUEUE_SUBMIT_REPLY + 1U)
|
||||||
|
|
||||||
|
struct DvzDrp2ExecutionTiming
|
||||||
|
{
|
||||||
|
uint64_t validation_ns;
|
||||||
|
uint64_t state_ensure_ns;
|
||||||
|
uint64_t shader_compile_ns;
|
||||||
|
uint64_t shader_module_create_ns;
|
||||||
|
uint64_t command_ns[DVZ_DRP2_COMMAND_TYPE_COUNT];
|
||||||
|
uint32_t command_count[DVZ_DRP2_COMMAND_TYPE_COUNT];
|
||||||
|
uint64_t state_commit_ns;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************************************/
|
/*************************************************************************************************/
|
||||||
@@ -202,6 +216,10 @@ dvz_drp2_validate_stream(const DvzDrp2CommandStream* stream);
|
|||||||
DVZ_EXPORT DvzDrp2ValidationResult
|
DVZ_EXPORT DvzDrp2ValidationResult
|
||||||
dvz_drp2_runtime_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream);
|
dvz_drp2_runtime_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream);
|
||||||
|
|
||||||
|
DVZ_EXPORT DvzDrp2ValidationResult dvz_drp2_runtime_execute_timed(
|
||||||
|
DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream,
|
||||||
|
DvzDrp2ExecutionTiming* timing);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach a borrowed stream frame as a runtime render target.
|
* Attach a borrowed stream frame as a runtime render target.
|
||||||
|
|||||||
+4
-2
@@ -315,7 +315,8 @@ bool _vklite_attach_frame_target(
|
|||||||
bool _vklite_retire_frame_target_depth(
|
bool _vklite_retire_frame_target_depth(
|
||||||
Drp2VkliteState* state, Drp2VkliteObject* object);
|
Drp2VkliteState* state, Drp2VkliteObject* object);
|
||||||
DvzDrp2ValidationResult _vklite_execute(
|
DvzDrp2ValidationResult _vklite_execute(
|
||||||
DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream);
|
DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream,
|
||||||
|
DvzDrp2ExecutionTiming* timing);
|
||||||
VkImageView _vklite_object_image_view(const Drp2VkliteObject* object);
|
VkImageView _vklite_object_image_view(const Drp2VkliteObject* object);
|
||||||
void _vklite_state_cleanup(Drp2VkliteState* state);
|
void _vklite_state_cleanup(Drp2VkliteState* state);
|
||||||
bool _vklite_defer_destroy_object(
|
bool _vklite_defer_destroy_object(
|
||||||
@@ -337,7 +338,8 @@ void _vklite_transition_image_access(
|
|||||||
bool _vklite_compile_glsl(
|
bool _vklite_compile_glsl(
|
||||||
const char* stage, const char* code, uint32_t** spv, uint64_t* spv_size);
|
const char* stage, const char* code, uint32_t** spv, uint64_t* spv_size);
|
||||||
DvzDrp2ValidationResult _vklite_create_shader_module(
|
DvzDrp2ValidationResult _vklite_create_shader_module(
|
||||||
Drp2VkliteState* state, const DvzDrp2Command* command, uint32_t command_index);
|
Drp2VkliteState* state, const DvzDrp2Command* command, uint32_t command_index,
|
||||||
|
DvzDrp2ExecutionTiming* timing);
|
||||||
DvzDrp2ValidationResult _vklite_create_sampler(
|
DvzDrp2ValidationResult _vklite_create_sampler(
|
||||||
Drp2VkliteState* state, const DvzDrp2Command* command, uint32_t command_index);
|
Drp2VkliteState* state, const DvzDrp2Command* command, uint32_t command_index);
|
||||||
DvzDrp2ValidationResult _vklite_create_bind_group_layout(
|
DvzDrp2ValidationResult _vklite_create_bind_group_layout(
|
||||||
|
|||||||
+13
-2
@@ -23,6 +23,7 @@
|
|||||||
#include "_assertions.h"
|
#include "_assertions.h"
|
||||||
#include "_runtime.h"
|
#include "_runtime.h"
|
||||||
#include "_stream.h"
|
#include "_stream.h"
|
||||||
|
#include "datoviz/common/functions.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -573,7 +574,9 @@ static DvzDrp2ValidationResult _vklite_destroy_shader_module(
|
|||||||
|
|
||||||
|
|
||||||
DvzDrp2ValidationResult
|
DvzDrp2ValidationResult
|
||||||
_vklite_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream)
|
_vklite_execute(
|
||||||
|
DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream,
|
||||||
|
DvzDrp2ExecutionTiming* timing)
|
||||||
{
|
{
|
||||||
ANN(runtime);
|
ANN(runtime);
|
||||||
ANN(stream);
|
ANN(stream);
|
||||||
@@ -590,6 +593,7 @@ _vklite_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream)
|
|||||||
for (uint32_t i = 0; i < stream->count; i++)
|
for (uint32_t i = 0; i < stream->count; i++)
|
||||||
{
|
{
|
||||||
const DvzDrp2Command* command = &stream->commands[i];
|
const DvzDrp2Command* command = &stream->commands[i];
|
||||||
|
const uint64_t command_started = timing != NULL ? dvz_time_monotonic_ns() : 0;
|
||||||
switch (command->type)
|
switch (command->type)
|
||||||
{
|
{
|
||||||
case DVZ_DRP2_COMMAND_CREATE_BUFFER:
|
case DVZ_DRP2_COMMAND_CREATE_BUFFER:
|
||||||
@@ -607,7 +611,7 @@ _vklite_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream)
|
|||||||
state, command->u.destroy_texture.texture_id, DRP2_OBJECT_TEXTURE, i);
|
state, command->u.destroy_texture.texture_id, DRP2_OBJECT_TEXTURE, i);
|
||||||
break;
|
break;
|
||||||
case DVZ_DRP2_COMMAND_CREATE_SHADER_MODULE:
|
case DVZ_DRP2_COMMAND_CREATE_SHADER_MODULE:
|
||||||
result = _vklite_create_shader_module(state, command, i);
|
result = _vklite_create_shader_module(state, command, i, timing);
|
||||||
break;
|
break;
|
||||||
case DVZ_DRP2_COMMAND_DESTROY_SHADER_MODULE:
|
case DVZ_DRP2_COMMAND_DESTROY_SHADER_MODULE:
|
||||||
result = _vklite_destroy_shader_module(
|
result = _vklite_destroy_shader_module(
|
||||||
@@ -712,6 +716,13 @@ _vklite_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timing != NULL && command->type < DVZ_DRP2_COMMAND_TYPE_COUNT)
|
||||||
|
{
|
||||||
|
timing->command_ns[command->type] +=
|
||||||
|
dvz_time_monotonic_ns() - command_started;
|
||||||
|
timing->command_count[command->type]++;
|
||||||
|
}
|
||||||
|
|
||||||
if (!result.ok)
|
if (!result.ok)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -34,6 +34,7 @@ typedef int shaderc_shader_kind;
|
|||||||
#include "_runtime.h"
|
#include "_runtime.h"
|
||||||
#include "_stream.h"
|
#include "_stream.h"
|
||||||
#include "_vk_utils.h"
|
#include "_vk_utils.h"
|
||||||
|
#include "datoviz/common/functions.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -444,7 +445,8 @@ bool _vklite_compile_glsl(
|
|||||||
* @return DRP2 validation result
|
* @return DRP2 validation result
|
||||||
*/
|
*/
|
||||||
DvzDrp2ValidationResult _vklite_create_shader_module(
|
DvzDrp2ValidationResult _vklite_create_shader_module(
|
||||||
Drp2VkliteState* state, const DvzDrp2Command* command, uint32_t command_index)
|
Drp2VkliteState* state, const DvzDrp2Command* command, uint32_t command_index,
|
||||||
|
DvzDrp2ExecutionTiming* timing)
|
||||||
{
|
{
|
||||||
ANN(state);
|
ANN(state);
|
||||||
ANN(command);
|
ANN(command);
|
||||||
@@ -464,10 +466,13 @@ DvzDrp2ValidationResult _vklite_create_shader_module(
|
|||||||
|
|
||||||
if (is_glsl)
|
if (is_glsl)
|
||||||
{
|
{
|
||||||
|
const uint64_t compile_started = timing != NULL ? dvz_time_monotonic_ns() : 0;
|
||||||
if (!_vklite_compile_glsl(
|
if (!_vklite_compile_glsl(
|
||||||
command->u.create_shader_module.stage, command->u.create_shader_module.code,
|
command->u.create_shader_module.stage, command->u.create_shader_module.code,
|
||||||
&spv_owned, &spv_size))
|
&spv_owned, &spv_size))
|
||||||
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_ARGUMENT, command_index);
|
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_ARGUMENT, command_index);
|
||||||
|
if (timing != NULL)
|
||||||
|
timing->shader_compile_ns += dvz_time_monotonic_ns() - compile_started;
|
||||||
spv = spv_owned;
|
spv = spv_owned;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -499,7 +504,10 @@ DvzDrp2ValidationResult _vklite_create_shader_module(
|
|||||||
}
|
}
|
||||||
object->shader = shader;
|
object->shader = shader;
|
||||||
|
|
||||||
|
const uint64_t module_started = timing != NULL ? dvz_time_monotonic_ns() : 0;
|
||||||
int out = dvz_shader(state->runtime->device, spv_size, spv, shader);
|
int out = dvz_shader(state->runtime->device, spv_size, spv, shader);
|
||||||
|
if (timing != NULL)
|
||||||
|
timing->shader_module_create_ns += dvz_time_monotonic_ns() - module_started;
|
||||||
dvz_free(spv_owned);
|
dvz_free(spv_owned);
|
||||||
if (out != 0)
|
if (out != 0)
|
||||||
return _vklite_fail_destroy_object(
|
return _vklite_fail_destroy_object(
|
||||||
|
|||||||
+20
-1
@@ -28,6 +28,7 @@
|
|||||||
#include "_log.h"
|
#include "_log.h"
|
||||||
#include "_overflow.h"
|
#include "_overflow.h"
|
||||||
#include "_runtime.h"
|
#include "_runtime.h"
|
||||||
|
#include "datoviz/common/functions.h"
|
||||||
#include "_stream.h"
|
#include "_stream.h"
|
||||||
#include "datoviz/vk/gpu_ctx.h"
|
#include "datoviz/vk/gpu_ctx.h"
|
||||||
|
|
||||||
@@ -509,25 +510,40 @@ bool _dvz_drp2_runtime_vklite_download_buffer(
|
|||||||
*/
|
*/
|
||||||
DvzDrp2ValidationResult
|
DvzDrp2ValidationResult
|
||||||
dvz_drp2_runtime_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream)
|
dvz_drp2_runtime_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream)
|
||||||
|
{
|
||||||
|
return dvz_drp2_runtime_execute_timed(runtime, stream, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DvzDrp2ValidationResult dvz_drp2_runtime_execute_timed(
|
||||||
|
DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* stream,
|
||||||
|
DvzDrp2ExecutionTiming* timing)
|
||||||
{
|
{
|
||||||
if (runtime == NULL)
|
if (runtime == NULL)
|
||||||
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_ARGUMENT, 0);
|
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_ARGUMENT, 0);
|
||||||
if (stream == NULL)
|
if (stream == NULL)
|
||||||
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_ARGUMENT, 0);
|
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_ARGUMENT, 0);
|
||||||
|
|
||||||
|
if (timing != NULL)
|
||||||
|
*timing = (DvzDrp2ExecutionTiming){0};
|
||||||
|
uint64_t phase_started = timing != NULL ? dvz_time_monotonic_ns() : 0;
|
||||||
Drp2RuntimeState next_state = {0};
|
Drp2RuntimeState next_state = {0};
|
||||||
DvzDrp2ValidationResult result = _drp2_runtime_validate_stream(runtime, stream, &next_state);
|
DvzDrp2ValidationResult result = _drp2_runtime_validate_stream(runtime, stream, &next_state);
|
||||||
|
if (timing != NULL)
|
||||||
|
timing->validation_ns = dvz_time_monotonic_ns() - phase_started;
|
||||||
if (!result.ok)
|
if (!result.ok)
|
||||||
{
|
{
|
||||||
_drp2_runtime_state_cleanup(&next_state);
|
_drp2_runtime_state_cleanup(&next_state);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phase_started = timing != NULL ? dvz_time_monotonic_ns() : 0;
|
||||||
if (!_drp2_runtime_state_ensure(runtime))
|
if (!_drp2_runtime_state_ensure(runtime))
|
||||||
{
|
{
|
||||||
_drp2_runtime_state_cleanup(&next_state);
|
_drp2_runtime_state_cleanup(&next_state);
|
||||||
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_STATE, 0);
|
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_STATE, 0);
|
||||||
}
|
}
|
||||||
|
if (timing != NULL)
|
||||||
|
timing->state_ensure_ns = dvz_time_monotonic_ns() - phase_started;
|
||||||
|
|
||||||
if (runtime->semantic_only)
|
if (runtime->semantic_only)
|
||||||
{
|
{
|
||||||
@@ -540,17 +556,20 @@ dvz_drp2_runtime_execute(DvzDrp2Runtime* runtime, const DvzDrp2CommandStream* st
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if DVZ_DRP2_HAS_VKLITE
|
#if DVZ_DRP2_HAS_VKLITE
|
||||||
DvzDrp2ValidationResult backend_result = _vklite_execute(runtime, stream);
|
DvzDrp2ValidationResult backend_result = _vklite_execute(runtime, stream, timing);
|
||||||
if (!backend_result.ok)
|
if (!backend_result.ok)
|
||||||
{
|
{
|
||||||
_drp2_runtime_state_cleanup(&next_state);
|
_drp2_runtime_state_cleanup(&next_state);
|
||||||
return backend_result;
|
return backend_result;
|
||||||
}
|
}
|
||||||
|
phase_started = timing != NULL ? dvz_time_monotonic_ns() : 0;
|
||||||
if (!_drp2_runtime_state_commit(runtime, &next_state))
|
if (!_drp2_runtime_state_commit(runtime, &next_state))
|
||||||
{
|
{
|
||||||
_drp2_runtime_state_cleanup(&next_state);
|
_drp2_runtime_state_cleanup(&next_state);
|
||||||
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_STATE, 0);
|
return _drp2_fail(DVZ_DRP2_VALIDATION_INVALID_STATE, 0);
|
||||||
}
|
}
|
||||||
|
if (timing != NULL)
|
||||||
|
timing->state_commit_ns = dvz_time_monotonic_ns() - phase_started;
|
||||||
return backend_result;
|
return backend_result;
|
||||||
#else
|
#else
|
||||||
_drp2_runtime_state_cleanup(&next_state);
|
_drp2_runtime_state_cleanup(&next_state);
|
||||||
|
|||||||
@@ -57,23 +57,6 @@ static const char ENCODE_GLSL[] =
|
|||||||
" outColor = vec4(linearToSrgb(color.rgb), clamp(color.a, 0.0, 1.0));\n"
|
" outColor = vec4(linearToSrgb(color.rgb), clamp(color.a, 0.0, 1.0));\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
static const char ENCODE_WGSL[] =
|
|
||||||
"@group(0) @binding(0) var source_tex: texture_2d<f32>;\n"
|
|
||||||
"@group(0) @binding(1) var samp: sampler;\n"
|
|
||||||
"fn linear_to_srgb(linear_color: vec3f) -> vec3f {\n"
|
|
||||||
" let clipped = clamp(linear_color, vec3f(0.0), vec3f(1.0));\n"
|
|
||||||
" let lo = vec3f(12.92) * clipped;\n"
|
|
||||||
" let hi = vec3f(1.055) * pow(clipped, vec3f(1.0 / 2.4)) - vec3f(0.055);\n"
|
|
||||||
" return select(hi, lo, clipped <= vec3f(0.0031308));\n"
|
|
||||||
"}\n"
|
|
||||||
"@fragment fn main(@builtin(position) pos: vec4f) -> @location(0) vec4f {\n"
|
|
||||||
" let p = vec2i(pos.xy);\n"
|
|
||||||
" let color = textureLoad(source_tex, p, 0);\n"
|
|
||||||
" return vec4f(linear_to_srgb(color.rgb), clamp(color.a, 0.0, 1.0));\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool _render_pass_external_target_needs_encode(const DvzFramePlanEmitConfig* cfg)
|
static bool _render_pass_external_target_needs_encode(const DvzFramePlanEmitConfig* cfg)
|
||||||
{
|
{
|
||||||
if (cfg != NULL && cfg->color_pipeline == DVZ_COLOR_PIPELINE_LEGACY_SRGB_BLEND)
|
if (cfg != NULL && cfg->color_pipeline == DVZ_COLOR_PIPELINE_LEGACY_SRGB_BLEND)
|
||||||
@@ -302,15 +285,16 @@ bool _render_pass_emit_final_encode(
|
|||||||
if (vs_id == 0)
|
if (vs_id == 0)
|
||||||
return false;
|
return false;
|
||||||
if (ok && is_new)
|
if (ok && is_new)
|
||||||
ok = ok && _emit_shader(stream, vs_id, "VERTEX", _fullscreen_vertex_wgsl(),
|
ok = ok && _emit_shader_spirv(
|
||||||
_builtin_shader_glsl(DVZ_SCENE_BUILTIN_SHADER_WBOIT_RESOLVE, false),
|
stream, vs_id, "VERTEX", "fullscreen_vert",
|
||||||
cfg);
|
_builtin_shader_glsl(DVZ_SCENE_BUILTIN_SHADER_WBOIT_RESOLVE, false), cfg);
|
||||||
|
|
||||||
uint64_t fs_id = _obj_id(emitter, fs_key, &is_new);
|
uint64_t fs_id = _obj_id(emitter, fs_key, &is_new);
|
||||||
if (fs_id == 0)
|
if (fs_id == 0)
|
||||||
return false;
|
return false;
|
||||||
if (ok && is_new)
|
if (ok && is_new)
|
||||||
ok = ok && _emit_shader(stream, fs_id, "FRAGMENT", ENCODE_WGSL, ENCODE_GLSL, cfg);
|
ok = ok && _emit_shader_spirv(
|
||||||
|
stream, fs_id, "FRAGMENT", "final_srgb_encode_frag", ENCODE_GLSL, cfg);
|
||||||
|
|
||||||
uint64_t pipe_id = _obj_id(emitter, pipe_key, &is_new);
|
uint64_t pipe_id = _obj_id(emitter, pipe_key, &is_new);
|
||||||
if (pipe_id == 0)
|
if (pipe_id == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user