65 VK_Sprite(VkDevice device, VkPhysicalDevice physicalDevice, VkQueue graphicsQueue,
66 VkCommandPool commandPool);
81 void loadSprite(
const std::string &pngPath,
const std::string &fragmentShaderPath =
"");
88 void loadSprite(SDL_Surface *
surface,
const std::string &fragmentShaderPath =
"");
97 void createEmptySprite(
int width,
int height,
const std::string &vertexShaderPath =
"",
const std::string &fragmentShaderPath =
"");
113 void drawSprite(
int x,
int y,
float scaleX,
float scaleY);
123 void drawSprite(
int x,
int y,
float scaleX,
float scaleY,
float rotation);
144 void updateTexture(
const void *pixels,
int width,
int height,
int pitch = 0);
151 bool updateTextureCuda(
const cv::cuda::GpuMat &rgba, cv::cuda::Stream &stream);
158 void setShaderParams(
float p1 = 0.0f,
float p2 = 0.0f,
float p3 = 0.0f,
float p4 = 0.0f);
176 void renderSprites(VkCommandBuffer cmdBuffer, VkPipelineLayout pipelineLayout,
177 uint32_t screenWidth, uint32_t screenHeight);
247 const std::string &instanceVertShaderPath,
248 const std::string &instanceFragShaderPath);
266 void setMouseState(
float mx,
float my,
float pressed,
float reserved = 0.0f);
269 void setUniform0(
float x,
float y,
float z,
float w);
271 void setUniform1(
float x,
float y,
float z,
float w);
273 void setUniform2(
float x,
float y,
float z,
float w);
275 void setUniform3(
float x,
float y,
float z,
float w);
278 struct SpriteVertex {
283 struct SpriteDrawCmd {
289 VkDevice device = VK_NULL_HANDLE;
290 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
291 VkQueue graphicsQueue = VK_NULL_HANDLE;
292 VkCommandPool commandPool = VK_NULL_HANDLE;
293 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
294 VkImage spriteImage = VK_NULL_HANDLE;
295 VkDeviceMemory spriteImageMemory = VK_NULL_HANDLE;
296 VkImageView spriteImageView = VK_NULL_HANDLE;
298 int spriteHeight = 0;
299 bool spriteLoaded =
false;
300 bool externalTexture =
false;
301 VkShaderModule fragmentShaderModule = VK_NULL_HANDLE;
302 bool hasCustomShader =
false;
303 glm::vec4 shaderParams = glm::vec4(0.0f);
304 bool effectsEnabled =
true;
305 std::vector<SpriteDrawCmd> drawQueue;
307 VkPipeline customPipeline = VK_NULL_HANDLE;
308 VkPipelineLayout customPipelineLayout = VK_NULL_HANDLE;
309 VkRenderPass renderPass = VK_NULL_HANDLE;
310 VkFormat colorAttachmentFormat = VK_FORMAT_UNDEFINED;
311 VkFormat depthAttachmentFormat = VK_FORMAT_UNDEFINED;
312 std::string vertexShaderPath;
313 std::string fragmentShaderPath;
314 void createCustomPipeline();
316 VkBuffer quadVertexBuffer = VK_NULL_HANDLE;
317 VkDeviceMemory quadVertexBufferMemory = VK_NULL_HANDLE;
318 VkBuffer quadIndexBuffer = VK_NULL_HANDLE;
319 VkDeviceMemory quadIndexBufferMemory = VK_NULL_HANDLE;
320 bool quadBufferCreated =
false;
321 void createQuadBuffer();
323 VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
324 std::vector<VkDescriptorPool> descriptorPools{};
325 VkDescriptorPool descriptorSetPool = VK_NULL_HANDLE;
326 uint32_t nextDescriptorPoolSets = 16;
327 VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
328 VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
329 std::unordered_map<VkImageView, VkDescriptorSet> externalDescriptorSets{};
330 VkFilter textureFilter = VK_FILTER_LINEAR;
331 void createDescriptorPool();
332 void destroyDescriptorPools();
333 void destroyTextureDescriptorPools();
334 VkDescriptorSet createDescriptorSet(VkImageView imageView);
335 void destroySpriteResources();
337 VkBuffer persistentStagingBuffer = VK_NULL_HANDLE;
338 VkDeviceMemory persistentStagingMemory = VK_NULL_HANDLE;
339 void *persistentStagingMapped =
nullptr;
340 VkDeviceSize persistentStagingSize = 0;
341 VkFence uploadFence = VK_NULL_HANDLE;
342 VkCommandBuffer uploadCmdBuffer = VK_NULL_HANDLE;
343 bool stagingResourcesCreated =
false;
344 [[nodiscard]] VkDeviceSize stagingAllocationSize(VkDeviceSize requiredSize)
const;
345 void createStagingResources(VkDeviceSize size);
346 void destroyStagingResources();
347 void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage,
348 VkMemoryPropertyFlags properties, VkBuffer &buffer,
349 VkDeviceMemory &bufferMemory);
350 uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
351 void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height);
352 VkCommandBuffer beginSingleTimeCommands();
353 void endSingleTimeCommands(VkCommandBuffer commandBuffer);
354 void transitionImageLayout(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout);
355 void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
356 VkImageUsageFlags usage, VkMemoryPropertyFlags properties,
357 VkImage &image, VkDeviceMemory &imageMemory);
358 VkImageView createImageView(VkImage image, VkFormat format);
359 void createSampler();
360 SDL_Surface *convertToRGBA(SDL_Surface *surface);
361 void createSpriteTexture(SDL_Surface *surface);
362 void updateSpriteTexture(
const void *pixels, uint32_t width, uint32_t height);
364 void destroyCudaInterop();
365 bool ensureCudaInterop();
366 bool transitionCudaImageForWrite();
367 bool transitionCudaImageForShaderRead();
368 bool updateTextureCudaHost(
const void *pixels, uint32_t width, uint32_t height, uint32_t pitch);
369 void recordCudaReadyBarrier(VkCommandBuffer cmdBuffer);
370 void createCudaExportableImage(uint32_t width, uint32_t height, VkImage &image, VkDeviceMemory &imageMemory);
371 VkDeviceSize cudaExportMemorySize = 0;
372 cudaExternalMemory_t cudaExternalMemory =
nullptr;
373 cudaMipmappedArray_t cudaMipmappedArray =
nullptr;
374 cudaArray_t cudaArray =
nullptr;
375 bool cudaInteropEnabled =
false;
376 bool cudaInteropUnavailableLogged =
false;
377 bool cudaUploadLogged =
false;
378 bool cudaWriteTransitionLogged =
false;
379 bool cudaSampleBarrierLogged =
false;
380 bool cudaImageNeedsShaderBarrier =
false;
381 VkImageLayout cudaImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
383 std::vector<char> readShaderFile(
const std::string &filename);
385 struct SpriteExtendedUBO {
392 bool extendedUBOEnabled =
false;
393 SpriteExtendedUBO extendedUBOData{};
394 VkBuffer extendedUBOBuffer = VK_NULL_HANDLE;
395 VkDeviceMemory extendedUBOMemory = VK_NULL_HANDLE;
396 void *extendedUBOMapped =
nullptr;
397 VkDescriptorSetLayout extendedDescriptorSetLayout = VK_NULL_HANDLE;
398 VkDescriptorPool extendedDescriptorPool = VK_NULL_HANDLE;
399 VkDescriptorSet extendedDescriptorSet = VK_NULL_HANDLE;
400 bool ownExtendedDescriptorSetLayout =
false;
401 void createExtendedUBO();
402 void updateExtendedUBO();
403 void createExtendedDescriptorSetLayout();
404 void createExtendedDescriptorSet();
405 void destroyExtendedUBO();
407 struct SpriteInstanceData {
408 float posX, posY, sizeW, sizeH;
411 VkBuffer instanceBuffer = VK_NULL_HANDLE;
412 VkDeviceMemory instanceBufferMemory = VK_NULL_HANDLE;
413 void *instanceBufferMapped =
nullptr;
414 uint32_t instanceBufferCapacity = 0;
415 bool instancingEnabled =
false;
416 VkPipeline instancedPipeline = VK_NULL_HANDLE;
417 VkPipelineLayout instancedPipelineLayout = VK_NULL_HANDLE;
418 std::string instanceVertPath;
419 std::string instanceFragPath;
420 void createInstancedPipeline(
const std::string &vertPath,
const std::string &fragPath);
421 void ensureInstanceBuffer(uint32_t count);
422 void destroyInstanceResources();