diff --git a/framework/decode/file_processor.cpp b/framework/decode/file_processor.cpp index e5a0b199f2..92746a87a3 100644 --- a/framework/decode/file_processor.cpp +++ b/framework/decode/file_processor.cpp @@ -317,6 +317,31 @@ bool FileProcessor::ProcessBlocks() HandleBlockReadError(kErrorReadingBlockHeader, "Failed to read meta-data block header"); } } + else if (block_header.type == format::BlockType::kFrameMarkerBlock) + { + format::MarkerType marker_type = format::MarkerType::kUnknownMarker; + uint64_t frame_number = 0; + + success = ReadBytes(&marker_type, sizeof(marker_type)); + + if (success) + { + success = ProcessFrameMarker(block_header, marker_type); + + // Break from loop on frame delimiter. + if (IsFrameDelimiter(block_header.type, marker_type)) + { + // Make sure to increment the frame number on the way out. + ++current_frame_number_; + ++block_index_; + break; + } + } + else + { + HandleBlockReadError(kErrorReadingBlockHeader, "Failed to read frame marker header"); + } + } else if (block_header.type == format::BlockType::kStateMarkerBlock) { format::MarkerType marker_type = format::MarkerType::kUnknownMarker; @@ -1721,6 +1746,14 @@ bool FileProcessor::ProcessMetaData(const format::BlockHeader& block_header, for return success; } +bool FileProcessor::ProcessFrameMarker(const format::BlockHeader& block_header, format::MarkerType marker_type) +{ + // Read the rest of the frame marker data. Currently frame markers are not dispatched to decoders. + uint64_t frame_number = 0; + bool success = ReadBytes(&frame_number, sizeof(frame_number)); + return success; +} + bool FileProcessor::ProcessStateMarker(const format::BlockHeader& block_header, format::MarkerType marker_type) { uint64_t frame_number = 0; @@ -1812,6 +1845,11 @@ bool FileProcessor::ProcessAnnotation(const format::BlockHeader& block_header, f return success; } +bool FileProcessor::IsFrameDelimiter(format::BlockType block_type, format::MarkerType marker_type) const +{ + return ((block_type == format::BlockType::kFrameMarkerBlock) && (marker_type == format::MarkerType::kEndMarker)); +} + bool FileProcessor::IsFrameDelimiter(format::ApiCallId call_id) const { // TODO: IDs of API calls that were treated as frame delimiters by the GFXReconstruct layer should be in the capture diff --git a/framework/decode/file_processor.h b/framework/decode/file_processor.h index 9d55a56451..03d55ad059 100644 --- a/framework/decode/file_processor.h +++ b/framework/decode/file_processor.h @@ -112,10 +112,14 @@ class FileProcessor bool ProcessMetaData(const format::BlockHeader& block_header, format::MetaDataId meta_data_id); + bool IsFrameDelimiter(format::BlockType block_type, format::MarkerType marker_type) const; + bool IsFrameDelimiter(format::ApiCallId call_id) const; void HandleBlockReadError(Error error_code, const char* error_message); + bool ProcessFrameMarker(const format::BlockHeader& block_header, format::MarkerType marker_type); + bool ProcessStateMarker(const format::BlockHeader& block_header, format::MarkerType marker_type); bool ProcessAnnotation(const format::BlockHeader& block_header, format::AnnotationType annotation_type); diff --git a/framework/encode/capture_manager.cpp b/framework/encode/capture_manager.cpp index 7e94271b7e..b71fc1d289 100644 --- a/framework/encode/capture_manager.cpp +++ b/framework/encode/capture_manager.cpp @@ -93,9 +93,8 @@ CaptureManager::CaptureManager(format::ApiFamilyId api_family) : page_guard_memory_mode_(kMemoryModeShadowInternal), trim_enabled_(false), trim_current_range_(0), current_frame_(kFirstFrame), capture_mode_(kModeWrite), previous_hotkey_state_(false), previous_runtime_trigger_state_(CaptureSettings::RuntimeTriggerState::kNotUsed), debug_layer_(false), - debug_device_lost_(false), screenshot_prefix_(""), screenshots_enabled_(false), global_frame_count_(0), - disable_dxr_(false), accel_struct_padding_(0), iunknown_wrapping_(false), force_command_serialization_(false), - queue_zero_only_(false) + debug_device_lost_(false), screenshot_prefix_(""), screenshots_enabled_(false), disable_dxr_(false), + accel_struct_padding_(0), iunknown_wrapping_(false), force_command_serialization_(false), queue_zero_only_(false) {} CaptureManager::~CaptureManager() @@ -683,7 +682,7 @@ bool CaptureManager::ShouldTriggerScreenshot() uint32_t target_frame = screenshot_indices_.back(); // If this is a frame of interest, take a screenshot - if (target_frame == (global_frame_count_ + 1)) + if (target_frame == current_frame_) { triger_screenshot = true; @@ -701,12 +700,27 @@ bool CaptureManager::ShouldTriggerScreenshot() return triger_screenshot; } +void CaptureManager::WriteFrameMarker(format::MarkerType marker_type) +{ + if ((capture_mode_ & kModeWrite) == kModeWrite) + { + format::Marker marker_cmd; + uint64_t header_size = sizeof(format::Marker); + marker_cmd.header.type = format::BlockType::kFrameMarkerBlock; + marker_cmd.header.size = header_size; + marker_cmd.marker_type = marker_type; + marker_cmd.frame_number = current_frame_; + current_frame_; + WriteToFile(&marker_cmd, header_size); + } +} + void CaptureManager::EndFrame() { + ++current_frame_; + if (trim_enabled_) { - ++current_frame_; - if ((capture_mode_ & kModeWrite) == kModeWrite) { // Currently capturing a frame range. @@ -721,8 +735,6 @@ void CaptureManager::EndFrame() } } - global_frame_count_++; - // Flush after presents to help avoid capture files with incomplete final blocks. if (file_stream_.get() != nullptr) { diff --git a/framework/encode/capture_manager.h b/framework/encode/capture_manager.h index 444b79a871..d6fb03be52 100644 --- a/framework/encode/capture_manager.h +++ b/framework/encode/capture_manager.h @@ -112,6 +112,8 @@ class CaptureManager void EndMethodCallCapture(); + void WriteFrameMarker(format::MarkerType marker_type); + void EndFrame(); bool ShouldTriggerScreenshot(); @@ -265,7 +267,6 @@ class CaptureManager util::Keyboard keyboard_; std::string screenshot_prefix_; util::ScreenshotFormat screenshot_format_; - uint32_t global_frame_count_; void WriteToFile(const void* data, size_t size); diff --git a/framework/encode/d3d12_capture_manager.cpp b/framework/encode/d3d12_capture_manager.cpp index 3780f0a78e..beaad05c2a 100644 --- a/framework/encode/d3d12_capture_manager.cpp +++ b/framework/encode/d3d12_capture_manager.cpp @@ -583,7 +583,7 @@ void D3D12CaptureManager::PrePresent(IDXGISwapChain_Wrapper* swapchain_wrapper) gfxrecon::graphics::dx12::TakeScreenshot(frame_buffer_renderer_, swapchain_info->command_queue, swapchain, - global_frame_count_ + 1, + GetCurrentFrame(), screenshot_prefix_, screenshot_format_); } diff --git a/framework/encode/vulkan_capture_manager.h b/framework/encode/vulkan_capture_manager.h index 2a44337610..b6bd977a5d 100644 --- a/framework/encode/vulkan_capture_manager.h +++ b/framework/encode/vulkan_capture_manager.h @@ -923,6 +923,11 @@ class VulkanCaptureManager : public CaptureManager GFXRECON_ASSERT(cmd_buffer_wrapper != nullptr); if (cmd_buffer_wrapper->is_frame_boundary) { + // Because not all vkQueueSubmit calls are frame delimiters, add an end frame marker to the capture + // file for this vkQueueSubmit. + WriteFrameMarker(format::MarkerType::kEndMarker); + + // Do common capture manager end of frame processing. EndFrame(); break; } diff --git a/tools/optimize/block_skipping_file_processor.cpp b/tools/optimize/block_skipping_file_processor.cpp index 833f474eb7..e11cc65601 100644 --- a/tools/optimize/block_skipping_file_processor.cpp +++ b/tools/optimize/block_skipping_file_processor.cpp @@ -136,6 +136,31 @@ bool BlockSkippingFileProcessor::ProcessBlocks() HandleBlockReadError(kErrorReadingBlockHeader, "Failed to read meta-data block header"); } } + else if (block_header.type == format::BlockType::kFrameMarkerBlock) + { + format::MarkerType marker_type = format::MarkerType::kUnknownMarker; + uint64_t frame_number = 0; + + success = ReadBytes(&marker_type, sizeof(marker_type)); + + if (success) + { + success = ProcessFrameMarker(block_header, marker_type); + + // Break from loop on frame delimiter. + if (IsFrameDelimiter(block_header.type, marker_type)) + { + // Make sure to increment the frame number on the way out. + ++current_frame_number_; + ++block_index_; + break; + } + } + else + { + HandleBlockReadError(kErrorReadingBlockHeader, "Failed to read frame marker header"); + } + } else if (block_header.type == format::BlockType::kStateMarkerBlock) { format::MarkerType marker_type = format::MarkerType::kUnknownMarker;