1 // 2 // Copyright 2021 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // CLCommandQueueVk.h: Defines the class interface for CLCommandQueueVk, 7 // implementing CLCommandQueueImpl. 8 9 #ifndef LIBANGLE_RENDERER_VULKAN_CLCOMMANDQUEUEVK_H_ 10 #define LIBANGLE_RENDERER_VULKAN_CLCOMMANDQUEUEVK_H_ 11 12 #include <vector> 13 14 #include "common/PackedCLEnums_autogen.h" 15 #include "libANGLE/renderer/vulkan/CLContextVk.h" 16 #include "libANGLE/renderer/vulkan/CLEventVk.h" 17 #include "libANGLE/renderer/vulkan/CLKernelVk.h" 18 #include "libANGLE/renderer/vulkan/CLMemoryVk.h" 19 #include "libANGLE/renderer/vulkan/DisplayVk.h" 20 #include "libANGLE/renderer/vulkan/ShareGroupVk.h" 21 #include "libANGLE/renderer/vulkan/cl_types.h" 22 #include "libANGLE/renderer/vulkan/clspv_utils.h" 23 #include "libANGLE/renderer/vulkan/vk_command_buffer_utils.h" 24 #include "libANGLE/renderer/vulkan/vk_helpers.h" 25 #include "libANGLE/renderer/vulkan/vk_resource.h" 26 #include "libANGLE/renderer/vulkan/vk_utils.h" 27 #include "libANGLE/renderer/vulkan/vk_wrapper.h" 28 29 #include "libANGLE/renderer/CLCommandQueueImpl.h" 30 31 namespace rx 32 { 33 34 static constexpr size_t kPrintfBufferSize = 1024 * 1024; 35 36 class CLCommandQueueVk : public CLCommandQueueImpl 37 { 38 public: 39 CLCommandQueueVk(const cl::CommandQueue &commandQueue); 40 ~CLCommandQueueVk() override; 41 42 angle::Result init(); 43 44 angle::Result setProperty(cl::CommandQueueProperties properties, cl_bool enable) override; 45 46 angle::Result enqueueReadBuffer(const cl::Buffer &buffer, 47 bool blocking, 48 size_t offset, 49 size_t size, 50 void *ptr, 51 const cl::EventPtrs &waitEvents, 52 CLEventImpl::CreateFunc *eventCreateFunc) override; 53 54 angle::Result enqueueWriteBuffer(const cl::Buffer &buffer, 55 bool blocking, 56 size_t offset, 57 size_t size, 58 const void *ptr, 59 const cl::EventPtrs &waitEvents, 60 CLEventImpl::CreateFunc *eventCreateFunc) override; 61 62 angle::Result enqueueReadBufferRect(const cl::Buffer &buffer, 63 bool blocking, 64 const cl::MemOffsets &bufferOrigin, 65 const cl::MemOffsets &hostOrigin, 66 const cl::Coordinate ®ion, 67 size_t bufferRowPitch, 68 size_t bufferSlicePitch, 69 size_t hostRowPitch, 70 size_t hostSlicePitch, 71 void *ptr, 72 const cl::EventPtrs &waitEvents, 73 CLEventImpl::CreateFunc *eventCreateFunc) override; 74 75 angle::Result enqueueWriteBufferRect(const cl::Buffer &buffer, 76 bool blocking, 77 const cl::MemOffsets &bufferOrigin, 78 const cl::MemOffsets &hostOrigin, 79 const cl::Coordinate ®ion, 80 size_t bufferRowPitch, 81 size_t bufferSlicePitch, 82 size_t hostRowPitch, 83 size_t hostSlicePitch, 84 const void *ptr, 85 const cl::EventPtrs &waitEvents, 86 CLEventImpl::CreateFunc *eventCreateFunc) override; 87 88 angle::Result enqueueCopyBuffer(const cl::Buffer &srcBuffer, 89 const cl::Buffer &dstBuffer, 90 size_t srcOffset, 91 size_t dstOffset, 92 size_t size, 93 const cl::EventPtrs &waitEvents, 94 CLEventImpl::CreateFunc *eventCreateFunc) override; 95 96 angle::Result enqueueCopyBufferRect(const cl::Buffer &srcBuffer, 97 const cl::Buffer &dstBuffer, 98 const cl::MemOffsets &srcOrigin, 99 const cl::MemOffsets &dstOrigin, 100 const cl::Coordinate ®ion, 101 size_t srcRowPitch, 102 size_t srcSlicePitch, 103 size_t dstRowPitch, 104 size_t dstSlicePitch, 105 const cl::EventPtrs &waitEvents, 106 CLEventImpl::CreateFunc *eventCreateFunc) override; 107 108 angle::Result enqueueFillBuffer(const cl::Buffer &buffer, 109 const void *pattern, 110 size_t patternSize, 111 size_t offset, 112 size_t size, 113 const cl::EventPtrs &waitEvents, 114 CLEventImpl::CreateFunc *eventCreateFunc) override; 115 116 angle::Result enqueueMapBuffer(const cl::Buffer &buffer, 117 bool blocking, 118 cl::MapFlags mapFlags, 119 size_t offset, 120 size_t size, 121 const cl::EventPtrs &waitEvents, 122 CLEventImpl::CreateFunc *eventCreateFunc, 123 void *&mapPtr) override; 124 125 angle::Result enqueueReadImage(const cl::Image &image, 126 bool blocking, 127 const cl::MemOffsets &origin, 128 const cl::Coordinate ®ion, 129 size_t rowPitch, 130 size_t slicePitch, 131 void *ptr, 132 const cl::EventPtrs &waitEvents, 133 CLEventImpl::CreateFunc *eventCreateFunc) override; 134 135 angle::Result enqueueWriteImage(const cl::Image &image, 136 bool blocking, 137 const cl::MemOffsets &origin, 138 const cl::Coordinate ®ion, 139 size_t inputRowPitch, 140 size_t inputSlicePitch, 141 const void *ptr, 142 const cl::EventPtrs &waitEvents, 143 CLEventImpl::CreateFunc *eventCreateFunc) override; 144 145 angle::Result enqueueCopyImage(const cl::Image &srcImage, 146 const cl::Image &dstImage, 147 const cl::MemOffsets &srcOrigin, 148 const cl::MemOffsets &dstOrigin, 149 const cl::Coordinate ®ion, 150 const cl::EventPtrs &waitEvents, 151 CLEventImpl::CreateFunc *eventCreateFunc) override; 152 153 angle::Result enqueueFillImage(const cl::Image &image, 154 const void *fillColor, 155 const cl::MemOffsets &origin, 156 const cl::Coordinate ®ion, 157 const cl::EventPtrs &waitEvents, 158 CLEventImpl::CreateFunc *eventCreateFunc) override; 159 160 angle::Result enqueueCopyImageToBuffer(const cl::Image &srcImage, 161 const cl::Buffer &dstBuffer, 162 const cl::MemOffsets &srcOrigin, 163 const cl::Coordinate ®ion, 164 size_t dstOffset, 165 const cl::EventPtrs &waitEvents, 166 CLEventImpl::CreateFunc *eventCreateFunc) override; 167 168 angle::Result enqueueCopyBufferToImage(const cl::Buffer &srcBuffer, 169 const cl::Image &dstImage, 170 size_t srcOffset, 171 const cl::MemOffsets &dstOrigin, 172 const cl::Coordinate ®ion, 173 const cl::EventPtrs &waitEvents, 174 CLEventImpl::CreateFunc *eventCreateFunc) override; 175 176 angle::Result enqueueMapImage(const cl::Image &image, 177 bool blocking, 178 cl::MapFlags mapFlags, 179 const cl::MemOffsets &origin, 180 const cl::Coordinate ®ion, 181 size_t *imageRowPitch, 182 size_t *imageSlicePitch, 183 const cl::EventPtrs &waitEvents, 184 CLEventImpl::CreateFunc *eventCreateFunc, 185 void *&mapPtr) override; 186 187 angle::Result enqueueUnmapMemObject(const cl::Memory &memory, 188 void *mappedPtr, 189 const cl::EventPtrs &waitEvents, 190 CLEventImpl::CreateFunc *eventCreateFunc) override; 191 192 angle::Result enqueueMigrateMemObjects(const cl::MemoryPtrs &memObjects, 193 cl::MemMigrationFlags flags, 194 const cl::EventPtrs &waitEvents, 195 CLEventImpl::CreateFunc *eventCreateFunc) override; 196 197 angle::Result enqueueNDRangeKernel(const cl::Kernel &kernel, 198 const cl::NDRange &ndrange, 199 const cl::EventPtrs &waitEvents, 200 CLEventImpl::CreateFunc *eventCreateFunc) override; 201 202 angle::Result enqueueTask(const cl::Kernel &kernel, 203 const cl::EventPtrs &waitEvents, 204 CLEventImpl::CreateFunc *eventCreateFunc) override; 205 206 angle::Result enqueueNativeKernel(cl::UserFunc userFunc, 207 void *args, 208 size_t cbArgs, 209 const cl::BufferPtrs &buffers, 210 const std::vector<size_t> bufferPtrOffsets, 211 const cl::EventPtrs &waitEvents, 212 CLEventImpl::CreateFunc *eventCreateFunc) override; 213 214 angle::Result enqueueMarkerWithWaitList(const cl::EventPtrs &waitEvents, 215 CLEventImpl::CreateFunc *eventCreateFunc) override; 216 217 angle::Result enqueueMarker(CLEventImpl::CreateFunc &eventCreateFunc) override; 218 219 angle::Result enqueueWaitForEvents(const cl::EventPtrs &events) override; 220 221 angle::Result enqueueBarrierWithWaitList(const cl::EventPtrs &waitEvents, 222 CLEventImpl::CreateFunc *eventCreateFunc) override; 223 224 angle::Result enqueueBarrier() override; 225 226 angle::Result flush() override; 227 228 angle::Result finish() override; 229 getPlatform()230 CLPlatformVk *getPlatform() { return mContext->getPlatform(); } 231 232 cl_mem getOrCreatePrintfBuffer(); 233 234 private: 235 static constexpr size_t kMaxDependencyTrackerSize = 64; 236 static constexpr size_t kMaxHostBufferUpdateListSize = 16; 237 getProtectionType()238 vk::ProtectionType getProtectionType() const { return vk::ProtectionType::Unprotected; } 239 240 // Create-update-bind the kernel's descriptor set, put push-constants in cmd buffer, capture 241 // kernel resources, and handle kernel execution dependencies 242 angle::Result processKernelResources(CLKernelVk &kernelVk, 243 const cl::NDRange &ndrange, 244 const cl::WorkgroupCount &workgroupCount); 245 246 angle::Result submitCommands(); 247 angle::Result finishInternal(); 248 angle::Result syncHostBuffers(); 249 angle::Result flushComputePassCommands(); 250 angle::Result processWaitlist(const cl::EventPtrs &waitEvents); 251 angle::Result createEvent(CLEventImpl::CreateFunc *createFunc, 252 cl::ExecutionStatus initialStatus); 253 254 angle::Result onResourceAccess(const vk::CommandBufferAccess &access); getCommandBuffer(const vk::CommandBufferAccess & access,vk::OutsideRenderPassCommandBuffer ** commandBufferOut)255 angle::Result getCommandBuffer(const vk::CommandBufferAccess &access, 256 vk::OutsideRenderPassCommandBuffer **commandBufferOut) 257 { 258 ANGLE_TRY(onResourceAccess(access)); 259 *commandBufferOut = &mComputePassCommands->getCommandBuffer(); 260 return angle::Result::Continue; 261 } 262 263 angle::Result processPrintfBuffer(); 264 angle::Result copyImageToFromBuffer(CLImageVk &imageVk, 265 vk::BufferHelper &buffer, 266 const cl::MemOffsets &origin, 267 const cl::Coordinate ®ion, 268 size_t bufferOffset, 269 ImageBufferCopyDirection writeToBuffer); 270 271 bool hasUserEventDependency() const; 272 273 angle::Result insertBarrier(); 274 angle::Result addMemoryDependencies(cl::Memory *clMem); 275 276 CLContextVk *mContext; 277 const CLDeviceVk *mDevice; 278 cl::Memory *mPrintfBuffer; 279 280 vk::SecondaryCommandPools mCommandPool; 281 vk::OutsideRenderPassCommandBufferHelper *mComputePassCommands; 282 vk::SecondaryCommandMemoryAllocator mOutsideRenderPassCommandsAllocator; 283 SerialIndex mCurrentQueueSerialIndex; 284 QueueSerial mLastSubmittedQueueSerial; 285 QueueSerial mLastFlushedQueueSerial; 286 std::mutex mCommandQueueMutex; 287 288 // Created event objects associated with this command queue 289 cl::EventPtrs mAssociatedEvents; 290 291 // Dependant event(s) that this queue has to wait on 292 cl::EventPtrs mDependantEvents; 293 294 // Keep track of kernel resources on prior kernel enqueues 295 angle::HashSet<cl::Object *> mDependencyTracker; 296 297 // Resource reference capturing during execution 298 cl::MemoryPtrs mMemoryCaptures; 299 cl::KernelPtrs mKernelCaptures; 300 301 // Check to see if flush/finish can be skipped 302 bool mHasAnyCommandsPendingSubmission; 303 304 // printf handling 305 bool mNeedPrintfHandling; 306 const angle::HashMap<uint32_t, ClspvPrintfInfo> *mPrintfInfos; 307 308 // Host buffer transferring utility 309 struct HostTransferConfig 310 { 311 cl_command_type type{0}; 312 size_t size = 0; 313 size_t offset = 0; 314 void *dstHostPtr = nullptr; 315 const void *srcHostPtr = nullptr; 316 cl::MemOffsets origin; 317 cl::Coordinate region; 318 }; 319 struct HostTransferEntry 320 { 321 HostTransferConfig transferConfig; 322 cl::MemoryPtr transferBufferHandle; 323 }; 324 using HostTransferEntries = std::vector<HostTransferEntry>; 325 HostTransferEntries mHostTransferList; 326 angle::Result addToHostTransferList(CLBufferVk *srcBuffer, HostTransferConfig transferEntry); 327 angle::Result addToHostTransferList(CLImageVk *srcImage, HostTransferConfig transferEntry); 328 }; 329 330 } // namespace rx 331 332 #endif // LIBANGLE_RENDERER_VULKAN_CLCOMMANDQUEUEVK_H_ 333