Vulkan Schnee 0.0.1
High-performance rendering engine
Loading...
Searching...
No Matches
ComputeDebugUtils.h
Go to the documentation of this file.
1#pragma once
2
4
5#ifdef COMPUTE_DEBUG
6
8#include <plog/Log.h>
9#include <vector>
10#include <vulkan/vulkan_core.h>
11
12namespace EngineCore::ComputeDebug
13{
26 template <typename T>
27 std::vector<T> readbackBuffer(
28 VkDevice device,
29 VkPhysicalDevice physicalDevice,
30 const VulkanBuffer & buffer,
31 size_t count
32 );
33
42 void logObjectCullingResults( uint32_t objectCount, uint32_t survivingCount );
43
52 void logMeshletCullingResults( uint32_t meshletCount, uint32_t visibleCount );
53
62 void logCounter( const char * name, uint32_t value );
63
74 uint32_t readbackCounter(
75 VkDevice device,
76 VkPhysicalDevice physicalDevice,
77 const VulkanBuffer & buffer
78 );
79
80} // namespace EngineCore::ComputeDebug
81
82// Template implementation
83namespace EngineCore::ComputeDebug
84{
85 template <typename T>
86 std::vector<T> readbackBuffer(
87 VkDevice device,
88 VkPhysicalDevice physicalDevice,
89 const VulkanBuffer & buffer,
90 size_t count
91 )
92 {
93 std::vector<T> result( count );
94
95 const VkDeviceSize bufferSize = count * sizeof( T );
96
97 // Create staging buffer for readback
98 VkBufferCreateInfo stagingBufferInfo{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
99 stagingBufferInfo.size = bufferSize;
100 stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
101 stagingBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
102
103 VkBuffer stagingBuffer;
104 if ( vkCreateBuffer( device, &stagingBufferInfo, nullptr, &stagingBuffer ) != VK_SUCCESS )
105 {
106 PLOGE << "Failed to create staging buffer for readback";
107 return result;
108 }
109
110 VkMemoryRequirements memRequirements;
111 vkGetBufferMemoryRequirements( device, stagingBuffer, &memRequirements );
112
113 VkPhysicalDeviceMemoryProperties memProperties;
114 vkGetPhysicalDeviceMemoryProperties( physicalDevice, &memProperties );
115
116 uint32_t memoryTypeIndex = UINT32_MAX;
117 for ( uint32_t i = 0; i < memProperties.memoryTypeCount; i++ )
118 {
119 if ( ( memRequirements.memoryTypeBits & ( 1 << i ) ) &&
120 ( memProperties.memoryTypes[i].propertyFlags &
121 ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) ) ==
122 ( VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) )
123 {
124 memoryTypeIndex = i;
125 break;
126 }
127 }
128
129 if ( memoryTypeIndex == UINT32_MAX )
130 {
131 PLOGE << "Failed to find suitable memory type for readback buffer";
132 vkDestroyBuffer( device, stagingBuffer, nullptr );
133 return result;
134 }
135
136 VkMemoryAllocateInfo allocInfo{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO };
137 allocInfo.allocationSize = memRequirements.size;
138 allocInfo.memoryTypeIndex = memoryTypeIndex;
139
140 VkDeviceMemory stagingMemory;
141 if ( vkAllocateMemory( device, &allocInfo, nullptr, &stagingMemory ) != VK_SUCCESS )
142 {
143 PLOGE << "Failed to allocate staging memory for readback";
144 vkDestroyBuffer( device, stagingBuffer, nullptr );
145 return result;
146 }
147
148 vkBindBufferMemory( device, stagingBuffer, stagingMemory, 0 );
149
150 // Map memory and copy
151 void * mappedData;
152 vkMapMemory( device, stagingMemory, 0, bufferSize, 0, &mappedData );
153
154 // Note: In a real implementation, we'd need to copy from GPU buffer to staging
155 // This requires a command buffer submission. For now, we assume the buffer
156 // is already host-visible or this is called after a proper copy.
157
158 // For host-visible buffers, we can read directly from the buffer's mapped memory
159 // This is a simplified version - full implementation would use vkCmdCopyBuffer
160
161 memcpy( result.data(), mappedData, bufferSize );
162
163 vkUnmapMemory( device, stagingMemory );
164
165 // Cleanup
166 vkDestroyBuffer( device, stagingBuffer, nullptr );
167 vkFreeMemory( device, stagingMemory, nullptr );
168
169 return result;
170 }
171} // namespace EngineCore::ComputeDebug
172
173#endif // COMPUTE_DEBUG
174
175
176
177
178
179
180
181
182
183
184