67 VK_Sprite(VkDevice device, VkPhysicalDevice physicalDevice, VkQueue graphicsQueue, VkCommandPool commandPool);
82 void loadSprite(
const std::string &pngPath,
const std::string &fragmentShaderPath =
"");
89 void loadSprite(SDL_Surface *
surface,
const std::string &fragmentShaderPath =
"");
98 void createEmptySprite(
int width,
int height,
const std::string &vertexShaderPath =
"",
const std::string &fragmentShaderPath =
"");
106 void createEmptySpriteRgba16(
int width,
int height,
const std::string &vertexShaderPath =
"",
const std::string &fragmentShaderPath =
"");
122 void drawSprite(
int x,
int y,
float scaleX,
float scaleY);
132 void drawSprite(
int x,
int y,
float scaleX,
float scaleY,
float rotation);
153 void updateTexture(
const void *pixels,
int width,
int height,
int pitch = 0);
169 bool updateTextureCuda(
const cv::cuda::GpuMat &rgba, cv::cuda::Stream &stream);
176 void setShaderParams(
float p1 = 0.0f,
float p2 = 0.0f,
float p3 = 0.0f,
float p4 = 0.0f);
194 void renderSprites(VkCommandBuffer cmdBuffer, VkPipelineLayout pipelineLayout, uint32_t screenWidth, uint32_t screenHeight);
251 void enableComputeShader(
const std::string &path, uint32_t localSizeX, uint32_t localSizeY, uint32_t localSizeZ = 1);
257 void dispatchCompute(VkCommandBuffer cmdBuffer, VkImageView inputView, VkImageView outputView, uint32_t width, uint32_t height);
279 void enableInstancing(uint32_t maxInstances,
const std::string &instanceVertShaderPath,
const std::string &instanceFragShaderPath);
297 void setMouseState(
float mx,
float my,
float pressed,
float reserved = 0.0f);
300 void setUniform0(
float x,
float y,
float z,
float w);
302 void setUniform1(
float x,
float y,
float z,
float w);
304 void setUniform2(
float x,
float y,
float z,
float w);
306 void setUniform3(
float x,
float y,
float z,
float w);
319 void setAudioBands(
float low,
float mid,
float high,
float reserved = 0.0f);
394 [[nodiscard]]
bool updateHistoryTextureCuda(
const cv::cuda::GpuMat &rgba, cv::cuda::Stream &stream);
454 struct SpriteVertex {
459 struct SpriteDrawCmd {
465 VkDevice device = VK_NULL_HANDLE;
466 VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
467 VkQueue graphicsQueue = VK_NULL_HANDLE;
468 VkCommandPool commandPool = VK_NULL_HANDLE;
469 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
470 VkImage spriteImage = VK_NULL_HANDLE;
471 VkDeviceMemory spriteImageMemory = VK_NULL_HANDLE;
472 VkImageView spriteImageView = VK_NULL_HANDLE;
473 VkFormat spriteImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
474 uint32_t spriteBytesPerPixel = 4;
476 int spriteHeight = 0;
477 bool spriteLoaded =
false;
478 bool externalTexture =
false;
479 VkShaderModule fragmentShaderModule = VK_NULL_HANDLE;
480 VkShaderModule computeShaderModule = VK_NULL_HANDLE;
481 VkPipeline computePipeline = VK_NULL_HANDLE;
482 VkPipelineLayout computePipelineLayout = VK_NULL_HANDLE;
483 VkImageView computeOutputImageView = VK_NULL_HANDLE;
484 uint32_t computeLocalSizeX = 1;
485 uint32_t computeLocalSizeY = 1;
486 void createComputePipeline();
487 void destroyComputePipeline();
488 bool hasCustomShader =
false;
489 glm::vec4 shaderParams = glm::vec4(0.0f);
490 bool effectsEnabled =
true;
491 std::vector<SpriteDrawCmd> drawQueue;
493 VkPipeline customPipeline = VK_NULL_HANDLE;
494 VkPipelineLayout customPipelineLayout = VK_NULL_HANDLE;
495 VkRenderPass renderPass = VK_NULL_HANDLE;
496 VkFormat colorAttachmentFormat = VK_FORMAT_UNDEFINED;
497 VkFormat depthAttachmentFormat = VK_FORMAT_UNDEFINED;
498 std::string vertexShaderPath;
499 std::string fragmentShaderPath;
500 void createCustomPipeline();
502 VkBuffer quadVertexBuffer = VK_NULL_HANDLE;
503 VkDeviceMemory quadVertexBufferMemory = VK_NULL_HANDLE;
504 VkBuffer quadIndexBuffer = VK_NULL_HANDLE;
505 VkDeviceMemory quadIndexBufferMemory = VK_NULL_HANDLE;
506 bool quadBufferCreated =
false;
507 void createQuadBuffer();
509 VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
510 std::vector<VkDescriptorPool> descriptorPools{};
511 VkDescriptorPool descriptorSetPool = VK_NULL_HANDLE;
512 uint32_t nextDescriptorPoolSets = 16;
513 VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
514 VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
515 std::unordered_map<VkImageView, VkDescriptorSet> externalDescriptorSets{};
516 VkFilter textureFilter = VK_FILTER_LINEAR;
517 void createDescriptorPool();
518 void destroyDescriptorPools();
519 void destroyTextureDescriptorPools();
520 VkDescriptorSet createDescriptorSet(VkImageView imageView);
521 void destroySpriteResources();
523 VkBuffer persistentStagingBuffer = VK_NULL_HANDLE;
524 VkDeviceMemory persistentStagingMemory = VK_NULL_HANDLE;
525 void *persistentStagingMapped =
nullptr;
526 VkDeviceSize persistentStagingSize = 0;
527 VkFence uploadFence = VK_NULL_HANDLE;
528 VkCommandBuffer uploadCmdBuffer = VK_NULL_HANDLE;
529 bool stagingResourcesCreated =
false;
530 [[nodiscard]] VkDeviceSize stagingAllocationSize(VkDeviceSize requiredSize)
const;
531 void createStagingResources(VkDeviceSize size);
532 void destroyStagingResources();
533 void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, VkDeviceMemory &bufferMemory);
534 uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
535 void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height, uint32_t baseArrayLayer = 0, uint32_t layerCount = 1);
536 VkCommandBuffer beginSingleTimeCommands();
537 void endSingleTimeCommands(VkCommandBuffer commandBuffer);
538 void transitionImageLayout(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t baseArrayLayer = 0, uint32_t layerCount = 1);
539 void createImage(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage &image, VkDeviceMemory &imageMemory, uint32_t arrayLayers = 1, VkImageType imageType = VK_IMAGE_TYPE_2D);
540 VkImageView createImageView(VkImage image, VkFormat format, VkImageViewType viewType = VK_IMAGE_VIEW_TYPE_2D, uint32_t layerCount = 1);
541 void createSampler();
542 SDL_Surface *convertToRGBA(SDL_Surface *surface);
543 void createSpriteTexture(SDL_Surface *surface);
544 void createEmptySpriteWithFormat(
int width,
int height, VkFormat format, uint32_t bytesPerPixel,
const std::string &vertexShaderPath,
const std::string &fragmentShaderPath);
545 void updateSpriteTexture(
const void *pixels, uint32_t width, uint32_t height);
547 void destroyCudaInterop();
548 void destroyCudaHistoryInterop();
549 bool ensureCudaInterop();
550 bool ensureCudaHistoryInterop();
551 bool transitionCudaImageForWrite();
552 bool transitionCudaImageForShaderRead();
553 void transitionCudaHistoryLayer(VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags sourceAccess, VkAccessFlags destinationAccess, VkPipelineStageFlags sourceStage, VkPipelineStageFlags destinationStage);
554 bool updateTextureCudaHost(
const void *pixels, uint32_t width, uint32_t height, uint32_t pitch);
555 void recordCudaReadyBarrier(VkCommandBuffer cmdBuffer);
556 void createCudaExportableImage(uint32_t width, uint32_t height, uint32_t arrayLayers, VkImage &image, VkDeviceMemory &imageMemory, VkDeviceSize &exportMemorySize);
557 VkDeviceSize cudaExportMemorySize = 0;
558 cudaExternalMemory_t cudaExternalMemory =
nullptr;
559 cudaMipmappedArray_t cudaMipmappedArray =
nullptr;
560 cudaArray_t cudaArray =
nullptr;
561 bool cudaInteropEnabled =
false;
562 bool cudaInteropUnavailableLogged =
false;
563 bool cudaUploadLogged =
false;
564 bool cudaWriteTransitionLogged =
false;
565 bool cudaSampleBarrierLogged =
false;
566 bool cudaImageNeedsShaderBarrier =
false;
567 VkImageLayout cudaImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
568 VkDeviceSize cudaHistoryExportMemorySize = 0;
569 cudaExternalMemory_t cudaHistoryExternalMemory =
nullptr;
570 cudaMipmappedArray_t cudaHistoryMipmappedArray =
nullptr;
571 cudaArray_t cudaHistoryArray =
nullptr;
572 bool cudaHistoryInteropEnabled =
false;
573 bool cudaHistoryInteropUnavailableLogged =
false;
574 bool cudaHistoryUploadLogged =
false;
576 std::vector<char> readShaderFile(
const std::string &filename);
578 struct SpriteExtendedUBO {
585 glm::vec4 audio_bands;
586 glm::vec4 audio_history;
588 bool extendedUBOEnabled =
false;
589 SpriteExtendedUBO extendedUBOData{};
590 VkBuffer extendedUBOBuffer = VK_NULL_HANDLE;
591 VkDeviceMemory extendedUBOMemory = VK_NULL_HANDLE;
592 void *extendedUBOMapped =
nullptr;
593 VkDescriptorSetLayout extendedDescriptorSetLayout = VK_NULL_HANDLE;
594 VkDescriptorPool extendedDescriptorPool = VK_NULL_HANDLE;
595 VkDescriptorSet extendedDescriptorSet = VK_NULL_HANDLE;
596 bool ownExtendedDescriptorSetLayout =
false;
597 void createExtendedUBO();
598 void updateExtendedUBO();
599 void createExtendedDescriptorSetLayout();
600 void createExtendedDescriptorSet();
601 void destroyExtendedUBO();
603 bool historyTextureEnabled =
false;
604 bool historyTextureShared =
false;
605 VkImage historyImage = VK_NULL_HANDLE;
606 VkDeviceMemory historyImageMemory = VK_NULL_HANDLE;
607 VkImageView historyImageView = VK_NULL_HANDLE;
608 VkFormat historyImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
609 uint32_t historyWidth = 0;
610 uint32_t historyHeight = 0;
611 uint32_t historyLayers = 0;
612 uint32_t historyHead = 0;
613 void destroyHistoryTexture();
614 void enableHistoryTextureWithFormat(uint32_t width, uint32_t height, uint32_t layers, VkFormat format);
615 void uploadHistoryTextureBytes(
const void *pixels,
int width,
int height,
int pitch,
int bytesPerPixel);
617 bool spectrumTextureEnabled =
false;
618 VkImage spectrumImage = VK_NULL_HANDLE;
619 VkDeviceMemory spectrumImageMemory = VK_NULL_HANDLE;
620 VkImageView spectrumImageView = VK_NULL_HANDLE;
621 uint32_t spectrumBins = 0;
622 void destroySpectrumTexture();
624 bool spectrumHistoryTextureEnabled =
false;
625 VkImage spectrumHistoryImage = VK_NULL_HANDLE;
626 VkDeviceMemory spectrumHistoryImageMemory = VK_NULL_HANDLE;
627 VkImageView spectrumHistoryImageView = VK_NULL_HANDLE;
628 uint32_t spectrumHistoryBins = 0;
629 uint32_t spectrumHistoryLayers = 0;
630 uint32_t spectrumHistoryHead = 0;
631 uint32_t spectrumHistoryWriteIndex = 0;
632 void destroySpectrumHistoryTexture();
633 void recreateExtendedDescriptorLayout();
635 struct SpriteInstanceData {
636 float posX, posY, sizeW, sizeH;
639 VkBuffer instanceBuffer = VK_NULL_HANDLE;
640 VkDeviceMemory instanceBufferMemory = VK_NULL_HANDLE;
641 void *instanceBufferMapped =
nullptr;
642 uint32_t instanceBufferCapacity = 0;
643 bool instancingEnabled =
false;
644 VkPipeline instancedPipeline = VK_NULL_HANDLE;
645 VkPipelineLayout instancedPipelineLayout = VK_NULL_HANDLE;
646 std::string instanceVertPath;
647 std::string instanceFragPath;
648 void createInstancedPipeline(
const std::string &vertPath,
const std::string &fragPath);
649 void ensureInstanceBuffer(uint32_t count);
650 void destroyInstanceResources();