| 420 | } |
| 421 | |
| 422 | std::string ErrorMessages::FirstUseError(const HazardResult& hazard, const CommandExecutionContext& exec_context, |
| 423 | const CommandBufferAccessContext& recorded_context, uint32_t command_buffer_index) const { |
| 424 | const ResourceUsageInfo prior_usage_info = exec_context.GetResourceUsageInfo(hazard.TagEx()); |
| 425 | const ResourceUsageInfo recorded_usage_info = recorded_context.GetResourceUsageInfo(hazard.RecordedAccess()->TagEx()); |
| 426 | |
| 427 | AdditionalMessageInfo additional_info; |
| 428 | additional_info.properties.Add(kPropertyCommandBufferIndex, command_buffer_index); |
| 429 | |
| 430 | std::ostringstream ss; |
| 431 | ss << vvl::String(recorded_usage_info.command); |
| 432 | if (!recorded_usage_info.debug_region_name.empty()) { |
| 433 | ss << "[" << recorded_usage_info.debug_region_name << "]"; |
| 434 | } |
| 435 | if (exec_context.Handle().type == kVulkanObjectTypeQueue) { |
| 436 | ss << " (from " << validator_.FormatHandle(recorded_context.Handle()); |
| 437 | ss << " submitted on the current "; |
| 438 | ss << validator_.FormatHandle(exec_context.Handle()) << ")"; |
| 439 | } else { // primary command buffer executes secondary one |
| 440 | assert(exec_context.Handle().type == kVulkanObjectTypeCommandBuffer); |
| 441 | ss << " (from the secondary " << validator_.FormatHandle(recorded_context.Handle()) << ")"; |
| 442 | } |
| 443 | additional_info.access_initiator = ss.str(); |
| 444 | |
| 445 | std::ostringstream ss2; |
| 446 | if (prior_usage_info.queue) { |
| 447 | if (prior_usage_info.cb) { |
| 448 | ss2 << "(from " << validator_.FormatHandle(prior_usage_info.cb->Handle()); |
| 449 | ss2 << " submitted on " << validator_.FormatHandle(prior_usage_info.queue->Handle()) << ")"; |
| 450 | } else { // QueuePresent case (not recorded into command buffer) |
| 451 | ss2 << "(submitted on " << validator_.FormatHandle(prior_usage_info.queue->Handle()) << ")"; |
| 452 | } |
| 453 | } else if (prior_usage_info.cb) { |
| 454 | // TODO: distinuish between "native" primary command buffer commands and |
| 455 | // command recorded from the secondary command buffers. |
| 456 | ss2 << "(from the primary " << validator_.FormatHandle(prior_usage_info.cb->Handle()) << ")"; |
| 457 | } |
| 458 | additional_info.brief_description_end_text = ss2.str(); |
| 459 | |
| 460 | if (!recorded_usage_info.debug_region_name.empty()) { |
| 461 | additional_info.properties.Add(kPropertyDebugRegion, recorded_usage_info.debug_region_name); |
| 462 | } |
| 463 | |
| 464 | // Use generic "resource" when resource handle is not specified for some reason (likely just a missing code). |
| 465 | // TODO: specify resources in EndRenderPass (NegativeSyncVal.QSOBarrierHazard). |
| 466 | const std::string resource_description = (recorded_usage_info.resource_handle != NullVulkanTypedHandle) |
| 467 | ? validator_.FormatHandle(recorded_usage_info.resource_handle) |
| 468 | : "resource"; |
| 469 | return Error(hazard, exec_context, recorded_usage_info.command, resource_description, "SubmitTimeError", additional_info); |
| 470 | } |
| 471 | |
| 472 | std::string ErrorMessages::PresentError(const HazardResult& hazard, const QueueBatchContext& batch_context, vvl::Func command, |
| 473 | const std::string& resource_description, uint32_t swapchain_index) const { |
no test coverage detected