diff --git a/layer_example/source/layer_device_functions.hpp b/layer_example/source/layer_device_functions.hpp index f3403c7..df321c2 100644 --- a/layer_example/source/layer_device_functions.hpp +++ b/layer_example/source/layer_device_functions.hpp @@ -23,8 +23,6 @@ * ---------------------------------------------------------------------------- */ -#include - #include "framework/utils.hpp" /* See Vulkan API for documentation. */ diff --git a/layer_gpu_timeline/source/CMakeLists.txt b/layer_gpu_timeline/source/CMakeLists.txt index ca4fc25..b8212d1 100644 --- a/layer_gpu_timeline/source/CMakeLists.txt +++ b/layer_gpu_timeline/source/CMakeLists.txt @@ -52,6 +52,7 @@ add_library( layer_device_functions_queue.cpp layer_device_functions_render_pass.cpp layer_device_functions_trace_rays.cpp + layer_device_functions_transfer.cpp timeline_comms.cpp) target_include_directories( diff --git a/layer_gpu_timeline/source/layer_device_functions.hpp b/layer_gpu_timeline/source/layer_device_functions.hpp index 129f1e6..3806398 100644 --- a/layer_gpu_timeline/source/layer_device_functions.hpp +++ b/layer_gpu_timeline/source/layer_device_functions.hpp @@ -331,6 +331,126 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdTraceRaysKHR( uint32_t height, uint32_t depth); + +// Commands for transfers + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdClearColorImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue* pColor, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdClearDepthStencilImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue* pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBuffer( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy* pRegions); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBufferToImage( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBufferToImage2( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBufferToImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImage2( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImageToBuffer( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImageToBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImageToBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); + // Functions for debug /* See Vulkan API for documentation. */ diff --git a/layer_gpu_timeline/source/layer_device_functions_dispatch.cpp b/layer_gpu_timeline/source/layer_device_functions_dispatch.cpp index 0e3774f..7555501 100644 --- a/layer_gpu_timeline/source/layer_device_functions_dispatch.cpp +++ b/layer_gpu_timeline/source/layer_device_functions_dispatch.cpp @@ -44,6 +44,23 @@ static uint64_t registerDispatch( return cb.dispatch(groupX, groupY, groupZ); } +static void emitStartTag( + Device* layer, + VkCommandBuffer commandBuffer, + uint64_t tagID +) { + // Emit the unique workload tag into the command stream + std::string tagLabel = formatString("t%" PRIu64, tagID); + VkDebugUtilsLabelEXT tagInfo { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = tagLabel.c_str(), + .color = { 0.0f, 0.0f, 0.0f, 0.0f } + }; + + layer->driver.vkCmdBeginDebugUtilsLabelEXT(commandBuffer, &tagInfo); +} + /* See Vulkan API for documentation. */ template <> VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatch( @@ -65,18 +82,9 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatch( static_cast(groupCountY), static_cast(groupCountZ)); - // Emit the unique workload tag into the command stream - std::string tagLabel = formatString("t%" PRIu64, tagID); - VkDebugUtilsLabelEXT tagInfo { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = tagLabel.c_str(), - .color = { 0.0f, 0.0f, 0.0f, 0.0f } - }; - // Release the lock to call into the driver lock.unlock(); - layer->driver.vkCmdBeginDebugUtilsLabelEXT(commandBuffer, &tagInfo); + emitStartTag(layer, commandBuffer, tagID); layer->driver.vkCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ); layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); } @@ -105,18 +113,9 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchBase( static_cast(groupCountY), static_cast(groupCountZ)); - // Emit the unique workload tag into the command stream - std::string tagLabel = formatString("t%" PRIu64, tagID); - VkDebugUtilsLabelEXT tagInfo { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = tagLabel.c_str(), - .color = { 0.0f, 0.0f, 0.0f, 0.0f } - }; - // Release the lock to call into the driver lock.unlock(); - layer->driver.vkCmdBeginDebugUtilsLabelEXT(commandBuffer, &tagInfo); + emitStartTag(layer, commandBuffer, tagID); layer->driver.vkCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ); layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); } @@ -145,18 +144,9 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchBaseKHR( static_cast(groupCountY), static_cast(groupCountZ)); - // Emit the unique workload tag into the command stream - std::string tagLabel = formatString("t%" PRIu64, tagID); - VkDebugUtilsLabelEXT tagInfo { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = tagLabel.c_str(), - .color = { 0.0f, 0.0f, 0.0f, 0.0f } - }; - // Release the lock to call into the driver lock.unlock(); - layer->driver.vkCmdBeginDebugUtilsLabelEXT(commandBuffer, &tagInfo); + emitStartTag(layer, commandBuffer, tagID); layer->driver.vkCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX, groupCountY, groupCountZ); layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); } @@ -176,18 +166,9 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdDispatchIndirect( uint64_t tagID = registerDispatch(layer, commandBuffer, -1, -1, -1); - // Emit the unique workload tag into the command stream - std::string tagLabel = formatString("t%" PRIu64, tagID); - VkDebugUtilsLabelEXT tagInfo { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = tagLabel.c_str(), - .color = { 0.0f, 0.0f, 0.0f, 0.0f } - }; - // Release the lock to call into the driver lock.unlock(); - layer->driver.vkCmdBeginDebugUtilsLabelEXT(commandBuffer, &tagInfo); + emitStartTag(layer, commandBuffer, tagID); layer->driver.vkCmdDispatchIndirect(commandBuffer, buffer, offset); layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); } diff --git a/layer_gpu_timeline/source/layer_device_functions_trace_rays.cpp b/layer_gpu_timeline/source/layer_device_functions_trace_rays.cpp index 5373747..2d99a3b 100644 --- a/layer_gpu_timeline/source/layer_device_functions_trace_rays.cpp +++ b/layer_gpu_timeline/source/layer_device_functions_trace_rays.cpp @@ -32,13 +32,33 @@ extern std::mutex g_vulkanLock; -static void registerTraceRays( +static uint64_t registerTraceRays( Device* layer, - VkCommandBuffer commandBuffer + VkCommandBuffer commandBuffer, + int64_t itemsX, + int64_t itemsY, + int64_t itemsZ +) { + auto& tracker = layer->getStateTracker(); + auto& cb = tracker.getCommandBuffer(commandBuffer); + return cb.traceRays(itemsX, itemsY, itemsZ); +} + +static void emitStartTag( + Device* layer, + VkCommandBuffer commandBuffer, + uint64_t tagID ) { - auto& state = layer->getStateTracker(); - auto& stats = state.getCommandBuffer(commandBuffer).getStats(); - stats.incTraceRaysCount(); + // Emit the unique workload tag into the command stream + std::string tagLabel = formatString("t%" PRIu64, tagID); + VkDebugUtilsLabelEXT tagInfo { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = tagLabel.c_str(), + .color = { 0.0f, 0.0f, 0.0f, 0.0f } + }; + + layer->driver.vkCmdBeginDebugUtilsLabelEXT(commandBuffer, &tagInfo); } /* See Vulkan API for documentation. */ @@ -53,11 +73,13 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdTraceRaysIndirect2KHR( std::unique_lock lock { g_vulkanLock }; auto* layer = Device::retrieve(commandBuffer); - registerTraceRays(layer, commandBuffer); + uint64_t tagID = registerTraceRays(layer, commandBuffer, -1, -1, -1); // Release the lock to call into the driver lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); layer->driver.vkCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); } /* See Vulkan API for documentation. */ @@ -76,10 +98,11 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdTraceRaysIndirectKHR( std::unique_lock lock { g_vulkanLock }; auto* layer = Device::retrieve(commandBuffer); - registerTraceRays(layer, commandBuffer); + uint64_t tagID = registerTraceRays(layer, commandBuffer, -1, -1, -1); // Release the lock to call into the driver lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); layer->driver.vkCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable, pHitShaderBindingTable, pCallableShaderBindingTable, indirectDeviceAddress); } @@ -101,9 +124,10 @@ VKAPI_ATTR void VKAPI_CALL layer_vkCmdTraceRaysKHR( std::unique_lock lock { g_vulkanLock }; auto* layer = Device::retrieve(commandBuffer); - registerTraceRays(layer, commandBuffer); + uint64_t tagID = registerTraceRays(layer, commandBuffer, width, height, depth); // Release the lock to call into the driver lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); layer->driver.vkCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable, pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth); } \ No newline at end of file diff --git a/layer_gpu_timeline/source/layer_device_functions_transfer.cpp b/layer_gpu_timeline/source/layer_device_functions_transfer.cpp new file mode 100644 index 0000000..066c23f --- /dev/null +++ b/layer_gpu_timeline/source/layer_device_functions_transfer.cpp @@ -0,0 +1,476 @@ +/* + * SPDX-License-Identifier: MIT + * ---------------------------------------------------------------------------- + * Copyright (c) 2024 Arm Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * ---------------------------------------------------------------------------- + */ + +#include +#include +#include + +#include "device.hpp" +#include "layer_device_functions.hpp" + +extern std::mutex g_vulkanLock; + +static uint64_t registerBufferTransfer( + Device* layer, + VkCommandBuffer commandBuffer, + const std::string& transferType, + int64_t byteCount +) { + auto& tracker = layer->getStateTracker(); + auto& cb = tracker.getCommandBuffer(commandBuffer); + return cb.bufferTransfer(transferType, byteCount); +} + +static uint64_t registerImageTransfer( + Device* layer, + VkCommandBuffer commandBuffer, + const std::string& transferType, + int64_t pixelCount +) { + auto& tracker = layer->getStateTracker(); + auto& cb = tracker.getCommandBuffer(commandBuffer); + return cb.imageTransfer(transferType, pixelCount); +} + +static void emitStartTag( + Device* layer, + VkCommandBuffer commandBuffer, + uint64_t tagID +) { + // Emit the unique workload tag into the command stream + std::string tagLabel = formatString("t%" PRIu64, tagID); + VkDebugUtilsLabelEXT tagInfo { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = tagLabel.c_str(), + .color = { 0.0f, 0.0f, 0.0f, 0.0f } + }; + + layer->driver.vkCmdBeginDebugUtilsLabelEXT(commandBuffer, &tagInfo); +} + +// Commands for transfers + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerBufferTransfer( + layer, + commandBuffer, + "Fill buffer", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdClearColorImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue* pColor, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Clear image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdClearDepthStencilImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue* pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Clear image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBuffer( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy* pRegions +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerBufferTransfer( + layer, + commandBuffer, + "Copy buffer", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerBufferTransfer( + layer, + commandBuffer, + "Copy buffer", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyBuffer2(commandBuffer, pCopyBufferInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerBufferTransfer( + layer, + commandBuffer, + "Copy buffer", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyBuffer2KHR(commandBuffer, pCopyBufferInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBufferToImage( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy* pRegions +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Copy image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBufferToImage2( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Copy image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyBufferToImage2(commandBuffer, pCopyBufferToImageInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyBufferToImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Copy image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyBufferToImage2KHR(commandBuffer, pCopyBufferToImageInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Copy image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImage2( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Copy image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyImage2(commandBuffer, pCopyImageInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerImageTransfer( + layer, + commandBuffer, + "Copy image", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyImage2KHR(commandBuffer, pCopyImageInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImageToBuffer( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerBufferTransfer( + layer, + commandBuffer, + "Copy buffer", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImageToBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerBufferTransfer( + layer, + commandBuffer, + "Copy buffer", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyImageToBuffer2(commandBuffer, pCopyImageToBufferInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} + +/* See Vulkan API for documentation. */ +template <> +VKAPI_ATTR void VKAPI_CALL layer_vkCmdCopyImageToBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo +) { + LAYER_TRACE(__func__); + + // Hold the lock to access layer-wide global store + std::unique_lock lock { g_vulkanLock }; + auto* layer = Device::retrieve(commandBuffer); + + uint64_t tagID = registerBufferTransfer( + layer, + commandBuffer, + "Copy buffer", + -1); + + // Release the lock to call into the driver + lock.unlock(); + emitStartTag(layer, commandBuffer, tagID); + layer->driver.vkCmdCopyImageToBuffer2KHR(commandBuffer, pCopyImageToBufferInfo); + layer->driver.vkCmdEndDebugUtilsLabelEXT(commandBuffer); +} diff --git a/lglpy/service_gpu_timeline.py b/lglpy/service_gpu_timeline.py index 0f619ae..9ead818 100644 --- a/lglpy/service_gpu_timeline.py +++ b/lglpy/service_gpu_timeline.py @@ -77,8 +77,7 @@ def handle_renderpass(self, msg): else: self.frame['workloads'].append(msg) - def handle_dispatch(self, msg): - # Find the last workload + def handle_generic(self, msg): self.frame['workloads'].append(msg) def handle_message(self, message: Message): @@ -93,8 +92,8 @@ def handle_message(self, message: Message): elif payloadType == 'renderpass': self.handle_renderpass(parsedPayload) - elif payloadType == 'dispatch': - self.handle_dispatch(parsedPayload) + elif payloadType in ('dispatch', 'tracerays', 'imagetransfer', 'buffertransfer'): + self.handle_generic(parsedPayload) else: assert False, f'Unknown payload type {payloadType}' diff --git a/source_common/trackers/command_buffer.cpp b/source_common/trackers/command_buffer.cpp index ef47730..b1b5d3c 100644 --- a/source_common/trackers/command_buffer.cpp +++ b/source_common/trackers/command_buffer.cpp @@ -137,7 +137,6 @@ uint64_t CommandBuffer::dispatch( int64_t yGroups, int64_t zGroups ) { - LAYER_LOG("Creating LCSDispatch workload"); uint64_t tagID = Tracker::LCSWorkload::assignTagID(); stats.incDispatchCount(); @@ -153,6 +152,67 @@ uint64_t CommandBuffer::dispatch( return tagID; } +/* See header for documentation. */ +uint64_t CommandBuffer::traceRays( + int64_t xItems, + int64_t yItems, + int64_t zItems +) { + uint64_t tagID = Tracker::LCSWorkload::assignTagID(); + stats.incTraceRaysCount(); + + // Add a workload to the render pass + auto workload = std::make_shared( + tagID, xItems, yItems, zItems); + workloads.push_back(workload); + + // Add a command to the layer-side command stream + auto instr = std::make_pair(LCSOpcode::TRACE_RAYS, workload); + workloadCommandStream.push_back(instr); + + return tagID; +} + +/* See header for documentation. */ +uint64_t CommandBuffer::imageTransfer( + const std::string& transferType, + int64_t pixelCount +) { + uint64_t tagID = Tracker::LCSWorkload::assignTagID(); + stats.incImageTransferCount(); + + // Add a workload to the render pass + auto workload = std::make_shared( + tagID, transferType, pixelCount); + workloads.push_back(workload); + + // Add a command to the layer-side command stream + auto instr = std::make_pair(LCSOpcode::IMAGE_TRANSFER, workload); + workloadCommandStream.push_back(instr); + + return tagID; +} + +/* See header for documentation. */ +uint64_t CommandBuffer::bufferTransfer( + const std::string& transferType, + int64_t byteCount +) { + uint64_t tagID = Tracker::LCSWorkload::assignTagID(); + stats.incBufferTransferCount(); + + // Add a workload to the render pass + auto workload = std::make_shared( + tagID, transferType, byteCount); + workloads.push_back(workload); + + // Add a command to the layer-side command stream + auto instr = std::make_pair(LCSOpcode::BUFFER_TRANSFER, workload); + workloadCommandStream.push_back(instr); + + return tagID; +} + /* See header for documentation. */ void CommandBuffer::executeCommands( CommandBuffer& secondary diff --git a/source_common/trackers/command_buffer.hpp b/source_common/trackers/command_buffer.hpp index c4b4828..ea474c0 100644 --- a/source_common/trackers/command_buffer.hpp +++ b/source_common/trackers/command_buffer.hpp @@ -128,6 +128,44 @@ class CommandBuffer int64_t yGroups, int64_t zGroups); + /** + * @brief Capture a trace rays dispatch. + * + * @param xItems Number of work items in X dimension, or -1 if unknown. + * @param yItems Number of work items in Y dimension, or -1 if unknown. + * @param zItems Number of work items in Z dimension, or -1 if unknown. + * + * @return Returns the tagID assigned to this workload. + */ + uint64_t traceRays( + int64_t xItems, + int64_t yItems, + int64_t zItems); + + /** + * @brief Capture a transfer where the destination is an image. + * + * @param transferType The type of the transfer. + * @param pixelCount The number of pixels written. + * + * @return Returns the tagID assigned to this workload. + */ + uint64_t imageTransfer( + const std::string& transferType, + int64_t pixelCount); + + /** + * @brief Capture a transfer where the destination is a buffer. + * + * @param transferType The type of the transfer. + * @param byteCount The number of pixels written. + * + * @return Returns the tagID assigned to this workload. + */ + uint64_t bufferTransfer( + const std::string& transferType, + int64_t byteCount); + /** * @brief Begin a user debug marker range. */ diff --git a/source_common/trackers/layer_command_stream.cpp b/source_common/trackers/layer_command_stream.cpp index 2b29d07..90c8c72 100644 --- a/source_common/trackers/layer_command_stream.cpp +++ b/source_common/trackers/layer_command_stream.cpp @@ -222,5 +222,115 @@ std::string LCSDispatch::getMetadata( return metadata.dump(); } +/* See header for details. */ +LCSTraceRays::LCSTraceRays( + uint64_t _tagID, + int64_t _xItems, + int64_t _yItems, + int64_t _zItems) : + LCSWorkload(_tagID), + xItems(_xItems), + yItems(_yItems), + zItems(_zItems) +{ + +} + +/* See header for details. */ +std::string LCSTraceRays::getMetadata( + const std::string* debugLabel, + uint64_t tagIDContinuation, + uint64_t submitID +) const { + UNUSED(tagIDContinuation); + UNUSED(submitID); + + json metadata = { + { "type", "tracerays" }, + { "tid", tagID }, + { "xItems", xItems }, + { "yItems", yItems }, + { "zItems", zItems } + }; + + if (debugLabel && debugLabel->size()) + { + metadata["label"] = *debugLabel; + } + + return metadata.dump(); +} + +/* See header for details. */ +LCSImageTransfer::LCSImageTransfer( + uint64_t _tagID, + const std::string& _transferType, + int64_t _pixelCount): + LCSWorkload(_tagID), + transferType(_transferType), + pixelCount(_pixelCount) +{ + +} + +/* See header for details. */ +std::string LCSImageTransfer::getMetadata( + const std::string* debugLabel, + uint64_t tagIDContinuation, + uint64_t submitID +) const { + UNUSED(tagIDContinuation); + UNUSED(submitID); + + json metadata = { + { "type", "imagetransfer" }, + { "tid", tagID }, + { "subtype", transferType }, + { "pixels", pixelCount } + }; + + if (debugLabel && debugLabel->size()) + { + metadata["label"] = *debugLabel; + } + + return metadata.dump(); +} + +/* See header for details. */ +LCSBufferTransfer::LCSBufferTransfer( + uint64_t _tagID, + const std::string& _transferType, + int64_t _byteCount): + LCSWorkload(_tagID), + transferType(_transferType), + byteCount(_byteCount) +{ + +} + +/* See header for details. */ +std::string LCSBufferTransfer::getMetadata( + const std::string* debugLabel, + uint64_t tagIDContinuation, + uint64_t submitID +) const { + UNUSED(tagIDContinuation); + UNUSED(submitID); + + json metadata = { + { "type", "buffertransfer" }, + { "tid", tagID }, + { "subtype", transferType }, + { "bytes", byteCount } + }; + + if (debugLabel && debugLabel->size()) + { + metadata["label"] = *debugLabel; + } + + return metadata.dump(); +} } diff --git a/source_common/trackers/layer_command_stream.hpp b/source_common/trackers/layer_command_stream.hpp index 246558d..29acdd6 100644 --- a/source_common/trackers/layer_command_stream.hpp +++ b/source_common/trackers/layer_command_stream.hpp @@ -204,6 +204,77 @@ class LCSDispatch : public LCSWorkload int64_t zGroups; }; +/** + * @brief Baseclass representing a GPU workload in the command stream. + */ +class LCSTraceRays : public LCSWorkload +{ +public: + LCSTraceRays( + uint64_t tagID, + int64_t xItems, + int64_t yItems, + int64_t zItems); + + virtual ~LCSTraceRays() = default; + + virtual std::string getMetadata( + const std::string* debugLabel=nullptr, + uint64_t tagIDContinuation=0, + uint64_t submitID=0) const; + +private: + int64_t xItems; + int64_t yItems; + int64_t zItems; +}; + +/** + * @brief Baseclass representing a GPU workload in the command stream. + */ +class LCSImageTransfer : public LCSWorkload +{ +public: + LCSImageTransfer( + uint64_t tagID, + const std::string& transferType, + int64_t pixelCount); + + virtual ~LCSImageTransfer() = default; + + virtual std::string getMetadata( + const std::string* debugLabel=nullptr, + uint64_t tagIDContinuation=0, + uint64_t submitID=0) const; + +private: + std::string transferType; + int64_t pixelCount; +}; + +/** + * @brief Baseclass representing a GPU workload in the command stream. + */ +class LCSBufferTransfer : public LCSWorkload +{ +public: + LCSBufferTransfer( + uint64_t tagID, + const std::string& transferType, + int64_t byteCount); + + virtual ~LCSBufferTransfer() = default; + + virtual std::string getMetadata( + const std::string* debugLabel=nullptr, + uint64_t tagIDContinuation=0, + uint64_t submitID=0) const; + +private: + std::string transferType; + int64_t byteCount; +}; + /** * @brief Baseclass representing a GPU workload in the command stream. */ diff --git a/source_common/trackers/queue.cpp b/source_common/trackers/queue.cpp index 756ea07..7b79606 100644 --- a/source_common/trackers/queue.cpp +++ b/source_common/trackers/queue.cpp @@ -86,7 +86,10 @@ void Queue::runSubmitCommandStream( } } } - else if (opCode == LCSOpcode::DISPATCH) + else if ((opCode == LCSOpcode::DISPATCH) || + (opCode == LCSOpcode::TRACE_RAYS) || + (opCode == LCSOpcode::IMAGE_TRANSFER) || + (opCode == LCSOpcode::BUFFER_TRANSFER)) { uint64_t tagID = opData->getTagID(); std::string log = joinString(debugStack, "|");