18 #define GLFW_INCLUDE_VULKAN
19 #include <GLFW/glfw3.h>
21 #include <ext/vulkan/glslang/Public/ShaderLang.h>
22 #include <ext/vulkan/spirv/GlslangToSpv.h>
23 #include <ext/vulkan/vma/src/VmaUsage.h>
24 #include <ext/vulkan/OGLCompilersDLL/InitializeDll.h>
26 #define THSVS_SIMPLER_VULKAN_SYNCHRONIZATION_IMPLEMENTATION
27 #include <ext/vulkan/svs/thsvs_simpler_vulkan_synchronization.h>
37 #include <unordered_map>
38 #include <unordered_set>
71 using std::unique_ptr;
77 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
78 #define ERR_EXIT(err_msg, err_class) \
80 Console::println(err_msg); \
81 Application::exit(1); \
84 #define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
86 fp##entrypoint = (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
87 if (fp##entrypoint == nullptr) { \
88 ERR_EXIT("vkGetInstanceProcAddr failed to find vk" #entrypoint, "vkGetInstanceProcAddr Failure"); \
92 #define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
94 fp##entrypoint = (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint); \
95 if (fp##entrypoint == nullptr) { \
96 ERR_EXIT("vkGetDeviceProcAddr failed to find vk" #entrypoint, "vkGetDeviceProcAddr Failure"); \
106 using std::to_string;
107 using std::unordered_map;
108 using std::unordered_set;
141 VKRenderer::VKRenderer():
143 queueSpinlock(
"queue_spinlock"),
144 buffersMutex(
"buffers_mutex"),
145 texturesMutex(
"textures_mutex"),
146 deleteMutex(
"delete_mutex"),
147 disposeMutex(
"dispose_mutex"),
148 pipelinesSpinLock(
"pipelines_spinlock"),
149 vmaSpinlock(
"vma_spinlock")
185 inline VkBool32
VKRenderer::checkLayers(uint32_t checkCount,
const char **checkNames,
const vector<VkLayerProperties>& instanceLayers) {
187 for (i = 0; i < checkCount; i++) {
189 for (j = 0; j < instanceLayers.size(); j++) {
190 if (!strcmp(checkNames[i], instanceLayers[j].layerName)) {
196 fprintf(stderr,
"Cannot find layer: %s\n", checkNames[i]);
204 auto& currentContext =
contexts[contextIdx];
205 if (currentContext.setupCommandInUse == VK_NULL_HANDLE) {
206 currentContext.setupCommandInUse = currentContext.setupCommand;
209 const VkCommandBufferBeginInfo cmdBufInfo = {
210 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
212 .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
213 .pInheritanceInfo =
nullptr
217 err = vkBeginCommandBuffer(currentContext.setupCommandInUse, &cmdBufInfo);
226 auto& currentContext =
contexts[contextIdx];
229 if (currentContext.setupCommandInUse != VK_NULL_HANDLE) {
232 err = vkEndCommandBuffer(currentContext.setupCommandInUse);
235 VkFence nullFence = { VK_NULL_HANDLE };
236 VkSubmitInfo submitInfo = {
237 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
239 .waitSemaphoreCount = 0,
240 .pWaitSemaphores =
nullptr,
241 .pWaitDstStageMask =
nullptr,
242 .commandBufferCount = 1,
243 .pCommandBuffers = ¤tContext.setupCommandInUse,
244 .signalSemaphoreCount = 0,
245 .pSignalSemaphores =
nullptr
250 err = vkQueueSubmit(
queue, 1, &submitInfo, currentContext.setupFence);
260 VkResult fenceResult;
262 fenceResult = vkWaitForFences(
device, 1, ¤tContext.setupFence, VK_TRUE, 100000000);
263 }
while (fenceResult == VK_TIMEOUT);
264 vkResetFences(
device, 1, ¤tContext.setupFence);
267 currentContext.setupCommandInUse = VK_NULL_HANDLE;
272 auto& currentContext =
contexts[contextIdx];
275 if (bufferId == -1) bufferId = currentContext.currentCommandBuffer;
278 auto& commandBuffer = currentContext.commandBuffers[bufferId];
279 if (commandBuffer.drawCmdStarted ==
true)
return false;
282 VkResult fenceResult;
284 fenceResult = vkWaitForFences(
device, 1, &commandBuffer.drawFence, VK_TRUE, 100000000);
285 }
while (fenceResult == VK_TIMEOUT);
286 vkResetFences(
device, 1, &commandBuffer.drawFence);
289 const VkCommandBufferBeginInfo cmdBufInfo = {
290 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
292 .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
293 .pInheritanceInfo =
nullptr
298 err = vkBeginCommandBuffer(commandBuffer.drawCommand, &cmdBufInfo);
301 array<ThsvsAccessType, 2> nextAccessTypes { THSVS_ACCESS_COLOR_ATTACHMENT_WRITE, THSVS_ACCESS_NONE };
302 ThsvsImageLayout nextLayout { THSVS_IMAGE_LAYOUT_OPTIMAL };
307 ThsvsImageBarrier svsImageBarrier = {
310 .nextAccessCount =
static_cast<uint32_t
>(nextAccessTypes[1] != THSVS_ACCESS_NONE?2:1),
311 .pNextAccesses = nextAccessTypes.data(),
313 .nextLayout = nextLayout,
314 .discardContents =
true,
315 .srcQueueFamilyIndex = 0,
316 .dstQueueFamilyIndex = 0,
318 .subresourceRange = {
319 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
326 VkImageMemoryBarrier vkImageMemoryBarrier;
327 VkPipelineStageFlags srcStages;
328 VkPipelineStageFlags dstStages;
329 thsvsGetVulkanImageMemoryBarrier(
333 &vkImageMemoryBarrier
340 vkCmdPipelineBarrier(commandBuffer.drawCommand, srcStages, dstStages, 0, 0,
nullptr, 0,
nullptr, 1, &vkImageMemoryBarrier);
348 commandBuffer.drawCmdStarted =
true;
358 auto& currentContext =
contexts[contextIdx];
360 if (bufferId == -1) bufferId = currentContext.currentCommandBuffer;
361 auto& commandBuffer = currentContext.commandBuffers[bufferId];
364 currentContext.pipeline = VK_NULL_HANDLE;
367 if (commandBuffer.drawCmdStarted ==
false)
return VK_NULL_HANDLE;
371 err = vkEndCommandBuffer(commandBuffer.drawCommand);
375 auto endedCommandBuffer = commandBuffer.drawCommand;
378 commandBuffer.drawCmdStarted =
false;
381 if (cycleBuffers ==
true) currentContext.currentCommandBuffer = (currentContext.currentCommandBuffer + 1) %
DRAW_COMMANDBUFFER_MAX;
384 return endedCommandBuffer;
390 VkPipelineStageFlags pipeStageFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
391 VkSubmitInfo submitInfo = {
392 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
394 .waitSemaphoreCount = 0,
395 .pWaitSemaphores =
nullptr,
396 .pWaitDstStageMask = &pipeStageFlags,
397 .commandBufferCount =
static_cast<uint32_t
>(commandBufferCount),
398 .pCommandBuffers = commandBuffers,
399 .signalSemaphoreCount = 0,
400 .pSignalSemaphores =
nullptr
406 err = vkQueueSubmit(
queue, 1, &submitInfo, fence);
419 inline void VKRenderer::setImageLayout(
int contextIdx,
texture_type* textureObject,
const array<ThsvsAccessType,2>& nextAccessTypes, ThsvsImageLayout nextLayout,
bool discardContent, uint32_t baseMipLevel, uint32_t levelCount,
bool submit) {
420 auto& currentContext =
contexts[contextIdx];
429 if (_textureObject->accessTypes[baseArrayLayer] == nextAccessTypes && _textureObject->svsLayout == nextLayout)
return;
431 ThsvsImageBarrier svsImageBarrier = {
432 .prevAccessCount =
static_cast<uint32_t
>(_textureObject->accessTypes[baseArrayLayer][1] != THSVS_ACCESS_NONE?2:1),
433 .pPrevAccesses = _textureObject->
accessTypes[baseArrayLayer].data(),
434 .nextAccessCount =
static_cast<uint32_t
>(nextAccessTypes[1] != THSVS_ACCESS_NONE?2:1),
435 .pNextAccesses = nextAccessTypes.data(),
436 .prevLayout = _textureObject->svsLayout,
437 .nextLayout = nextLayout,
438 .discardContents = discardContent,
439 .srcQueueFamilyIndex = 0,
440 .dstQueueFamilyIndex = 0,
441 .image = _textureObject->image,
442 .subresourceRange = {
443 .aspectMask = _textureObject->aspectMask,
444 .baseMipLevel = baseMipLevel,
445 .levelCount = levelCount,
446 .baseArrayLayer = baseArrayLayer,
450 VkImageMemoryBarrier vkImageMemoryBarrier;
451 VkPipelineStageFlags srcStages;
452 VkPipelineStageFlags dstStages;
453 thsvsGetVulkanImageMemoryBarrier(
457 &vkImageMemoryBarrier
462 vkCmdPipelineBarrier(currentContext.setupCommandInUse, srcStages, dstStages, 0, 0,
nullptr, 0,
nullptr, 1, &vkImageMemoryBarrier);
466 _textureObject->accessTypes[baseArrayLayer] = nextAccessTypes;
467 _textureObject->svsLayout = nextLayout;
468 _textureObject->vkLayout = vkImageMemoryBarrier.newLayout;
474 const array<ThsvsAccessType,2>& prevAccessTypes,
475 const array<ThsvsAccessType,2>& nextAccessTypes,
476 ThsvsImageLayout prevLayout,
477 ThsvsImageLayout nextLayout,
479 uint32_t baseMipLevel,
489 ThsvsImageBarrier svsImageBarrier = {
490 .prevAccessCount =
static_cast<uint32_t
>(prevAccessTypes[1] != THSVS_ACCESS_NONE?2:1),
491 .pPrevAccesses = prevAccessTypes.data(),
492 .nextAccessCount =
static_cast<uint32_t
>(nextAccessTypes[1] != THSVS_ACCESS_NONE?2:1),
493 .pNextAccesses = nextAccessTypes.data(),
494 .prevLayout = prevLayout,
495 .nextLayout = nextLayout,
496 .discardContents = discardContent,
497 .srcQueueFamilyIndex = 0,
498 .dstQueueFamilyIndex = 0,
499 .
image = _textureObject->image,
500 .subresourceRange = {
501 .aspectMask = _textureObject->aspectMask,
502 .baseMipLevel = baseMipLevel,
503 .levelCount = levelCount,
504 .baseArrayLayer = baseArrayLayer,
508 thsvsGetVulkanImageMemoryBarrier(
517 imageLayoutChange.
svsLayout = nextLayout;
519 imageLayoutChange.
valid =
true;
523 auto& currentContext =
contexts[contextIdx];
537 _textureObject->accessTypes[baseArrayLayer] = imageLayoutChange.
accessTypes;
538 _textureObject->svsLayout = imageLayoutChange.
svsLayout;
539 _textureObject->vkLayout = imageLayoutChange.
vkLayout;
543 auto& currentContext =
contexts[contextIdx];
546 array<VkImageMemoryBarrier, 8> vkImageMemoryBarriers = {
547 imageLayoutChanges[0].vkImageMemoryBarrier,
548 imageLayoutChanges[1].vkImageMemoryBarrier,
549 imageLayoutChanges[2].vkImageMemoryBarrier,
550 imageLayoutChanges[3].vkImageMemoryBarrier,
551 imageLayoutChanges[4].vkImageMemoryBarrier,
552 imageLayoutChanges[5].vkImageMemoryBarrier,
553 imageLayoutChanges[6].vkImageMemoryBarrier,
554 imageLayoutChanges[7].vkImageMemoryBarrier
559 vkCmdPipelineBarrier(currentContext.setupCommandInUse, imageLayoutChanges[0].srcStages, imageLayoutChanges[0].dstStages, 0, 0,
nullptr, 0,
nullptr, vkImageMemoryBarriers.size(), vkImageMemoryBarriers.data());
564 for (
auto textureObject: textureObjects) {
566 auto _textureObject = textureObject->cubemapBufferTexture !=
nullptr?textureObject->cubemapBufferTexture:textureObject;
569 auto baseArrayLayer =
static_cast<uint32_t
>(textureObject->cubemapBufferTexture !=
nullptr?textureObject->cubemapTextureIndex -
CUBEMAPTEXTUREINDEX_MIN:0);
572 _textureObject->accessTypes[baseArrayLayer] = imageLayoutChanges[i].accessTypes;
573 _textureObject->svsLayout = imageLayoutChanges[i].svsLayout;
574 _textureObject->vkLayout = imageLayoutChanges[i].vkLayout;
579 inline void VKRenderer::setImageLayout2(
int contextIdx,
texture_type* textureObject,
const array<ThsvsAccessType,2>& accessTypes,
const array<ThsvsAccessType,2>& nextAccessTypes, ThsvsImageLayout layout, ThsvsImageLayout nextLayout,
bool discardContent, uint32_t baseMipLevel, uint32_t levelCount, uint32_t baseArrayLayer, uint32_t layerCount,
bool updateTextureObject) {
580 auto& currentContext =
contexts[contextIdx];
583 ThsvsImageBarrier svsImageBarrier = {
584 .prevAccessCount =
static_cast<uint32_t
>(accessTypes[1] != THSVS_ACCESS_NONE?2:1),
585 .pPrevAccesses = accessTypes.data(),
586 .nextAccessCount =
static_cast<uint32_t
>(nextAccessTypes[1] != THSVS_ACCESS_NONE?2:1),
587 .pNextAccesses = nextAccessTypes.data(),
588 .prevLayout = layout,
589 .nextLayout = nextLayout,
590 .discardContents = discardContent,
591 .srcQueueFamilyIndex = 0,
592 .dstQueueFamilyIndex = 0,
593 .image = textureObject->
image,
594 .subresourceRange = {
596 .baseMipLevel = baseMipLevel,
597 .levelCount = levelCount,
598 .baseArrayLayer = baseArrayLayer,
599 .layerCount = layerCount
602 VkImageMemoryBarrier vkImageMemoryBarrier;
603 VkPipelineStageFlags srcStages;
604 VkPipelineStageFlags dstStages;
605 thsvsGetVulkanImageMemoryBarrier(
609 &vkImageMemoryBarrier
614 vkCmdPipelineBarrier(currentContext.setupCommandInUse, srcStages, dstStages, 0, 0,
nullptr, 0,
nullptr, 1, &vkImageMemoryBarrier);
618 textureObject->
accessTypes[baseArrayLayer] = nextAccessTypes;
620 textureObject->
vkLayout = vkImageMemoryBarrier.newLayout;
623 inline void VKRenderer::setImageLayout3(
int contextIdx, VkImage image, VkImageAspectFlags aspectMask,
const array<ThsvsAccessType,2>& accessTypes,
const array<ThsvsAccessType,2>& nextAccessTypes, ThsvsImageLayout layout, ThsvsImageLayout nextLayout) {
624 auto& currentContext =
contexts[contextIdx];
627 ThsvsImageBarrier svsImageBarrier = {
628 .prevAccessCount =
static_cast<uint32_t
>(accessTypes[1] != THSVS_ACCESS_NONE?2:1),
629 .pPrevAccesses = accessTypes.data(),
630 .nextAccessCount =
static_cast<uint32_t
>(nextAccessTypes[1] != THSVS_ACCESS_NONE?2:1),
631 .pNextAccesses = nextAccessTypes.data(),
632 .prevLayout = layout,
633 .nextLayout = nextLayout,
634 .discardContents =
false,
635 .srcQueueFamilyIndex = 0,
636 .dstQueueFamilyIndex = 0,
638 .subresourceRange = {
639 .aspectMask = aspectMask,
646 VkImageMemoryBarrier vkImageMemoryBarrier;
647 VkPipelineStageFlags srcStages;
648 VkPipelineStageFlags dstStages;
649 thsvsGetVulkanImageMemoryBarrier(
653 &vkImageMemoryBarrier
658 vkCmdPipelineBarrier(currentContext.setupCommandInUse, srcStages, dstStages, 0, 0,
nullptr, 0,
nullptr, 1, &vkImageMemoryBarrier);
662 inline void VKRenderer::prepareTextureImage(
int contextIdx,
struct texture_type* textureObject, VkImageTiling tiling, VkImageUsageFlags usage, VkFlags requiredFlags,
Texture* texture,
const array<ThsvsAccessType,2>& nextAccesses, ThsvsImageLayout imageLayout,
bool disableMipMaps, uint32_t baseLevel, uint32_t levelCount) {
663 auto& currentContext =
contexts[contextIdx];
671 const VkImageCreateInfo imageCreateInfo = {
672 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
675 .imageType = VK_IMAGE_TYPE_2D,
678 .width = textureWidth,
679 .height = textureHeight,
682 .mipLevels = disableMipMaps ==
false && texture->
isUseMipMap() ==
true?
static_cast<uint32_t
>(texture->
getMipLevels()):1,
684 .samples = VK_SAMPLE_COUNT_1_BIT,
687 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
688 .queueFamilyIndexCount = 0,
689 .pQueueFamilyIndices = 0,
690 .initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED
693 VmaAllocationCreateInfo imageAllocCreateInfo = {};
694 imageAllocCreateInfo.usage = VMA_MEMORY_USAGE_UNKNOWN;
695 imageAllocCreateInfo.requiredFlags = requiredFlags;
697 VmaAllocationInfo allocationInfo = {};
698 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &imageAllocCreateInfo, &textureObject->
image, &textureObject->
allocation, &allocationInfo);
701 if ((requiredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
702 const VkImageSubresource imageSubResource = {
703 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
707 VkSubresourceLayout subResourceLayout;
708 vkGetImageSubresourceLayout(
device, textureObject->
image, &imageSubResource, &subResourceLayout);
721 for (
auto y = 0; y < textureHeight; y++) {
722 uint8_t* row = (uint8_t*)((uint8_t*)data + subResourceLayout.offset + subResourceLayout.rowPitch * y);
723 for (
auto x = 0; x < textureWidth; x++) {
724 row[x * 4 + 0] = textureTextureData.
get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 0);
725 row[x * 4 + 1] = textureTextureData.get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 1);
726 row[x * 4 + 2] = textureTextureData.get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 2);
727 row[x * 4 + 3] = bytesPerPixel == 4?textureTextureData.get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 3):0xff;
740 textureObject->
accessTypes = { THSVS_ACCESS_HOST_PREINITIALIZED, THSVS_ACCESS_NONE };
745 THSVS_IMAGE_LAYOUT_OPTIMAL,
754 auto& currentContext =
contexts[contextIdx];
759 auto textureWidth =
static_cast<uint32_t
>(mipMapTexture.
width);
760 auto textureHeight =
static_cast<uint32_t
>(mipMapTexture.
height);
762 const VkImageCreateInfo imageCreateInfo = {
763 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
766 .imageType = VK_IMAGE_TYPE_2D,
769 .width = textureWidth,
770 .height = textureHeight,
775 .samples = VK_SAMPLE_COUNT_1_BIT,
778 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
779 .queueFamilyIndexCount = 0,
780 .pQueueFamilyIndices = 0,
781 .initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED
784 VmaAllocationCreateInfo imageAllocCreateInfo = {};
785 imageAllocCreateInfo.usage = VMA_MEMORY_USAGE_UNKNOWN;
786 imageAllocCreateInfo.requiredFlags = requiredFlags;
788 VmaAllocationInfo allocationInfo = {};
789 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &imageAllocCreateInfo, &textureObject->
image, &textureObject->
allocation, &allocationInfo);
792 if ((requiredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
793 const VkImageSubresource imageSubResource = {
794 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
798 VkSubresourceLayout subResourceLayout;
799 vkGetImageSubresourceLayout(
device, textureObject->
image, &imageSubResource, &subResourceLayout);
811 auto& textureTextureData = mipMapTexture.
textureData;
812 for (
auto y = 0; y < textureHeight; y++) {
813 uint8_t* row = (uint8_t*)((uint8_t*)data + subResourceLayout.offset + subResourceLayout.rowPitch * y);
814 for (
auto x = 0; x < textureWidth; x++) {
815 row[x * 4 + 0] = textureTextureData.
get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 0);
816 row[x * 4 + 1] = textureTextureData.get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 1);
817 row[x * 4 + 2] = textureTextureData.get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 2);
818 row[x * 4 + 3] = bytesPerPixel == 4?textureTextureData.get((y * textureWidth * bytesPerPixel) + (x * bytesPerPixel) + 3):0xff;
831 textureObject->
accessTypes = { THSVS_ACCESS_HOST_PREINITIALIZED, THSVS_ACCESS_NONE };
836 THSVS_IMAGE_LAYOUT_OPTIMAL,
845 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
851 VkSurfaceCapabilitiesKHR surfCapabilities;
853 assert(err == VK_SUCCESS);
855 uint32_t presentModeCount;
857 assert(err == VK_SUCCESS);
858 vector<VkPresentModeKHR> presentModes(presentModeCount);
860 assert(err == VK_SUCCESS);
862 VkExtent2D swapchainExtent;
864 if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) {
871 if (swapchainExtent.width < surfCapabilities.minImageExtent.width) {
872 swapchainExtent.width = surfCapabilities.minImageExtent.width;
873 }
else if (swapchainExtent.width > surfCapabilities.maxImageExtent.width) {
874 swapchainExtent.width = surfCapabilities.maxImageExtent.width;
877 if (swapchainExtent.height < surfCapabilities.minImageExtent.height) {
878 swapchainExtent.height = surfCapabilities.minImageExtent.height;
879 }
else if (swapchainExtent.height > surfCapabilities.maxImageExtent.height) {
880 swapchainExtent.height = surfCapabilities.maxImageExtent.height;
884 swapchainExtent = surfCapabilities.currentExtent;
885 windowWidth = surfCapabilities.currentExtent.width;
892 uint32_t desiredNumOfSwapchainImages = surfCapabilities.minImageCount;
895 if ((surfCapabilities.maxImageCount > 0) && (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) {
897 desiredNumOfSwapchainImages = surfCapabilities.maxImageCount;
901 VkSurfaceTransformFlagsKHR preTransform {};
902 if (surfCapabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
903 preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
905 preTransform = surfCapabilities.currentTransform;
908 const VkSwapchainCreateInfoKHR swapchainCreateInfo = {
909 .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
913 .minImageCount = desiredNumOfSwapchainImages,
917 .width = swapchainExtent.width,
918 .height = swapchainExtent.height
920 .imageArrayLayers = 1,
921 .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
922 .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
923 .queueFamilyIndexCount = 0,
924 .pQueueFamilyIndices = 0,
925 .preTransform = (VkSurfaceTransformFlagBitsKHR)preTransform,
926 .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
929 .oldSwapchain = oldSwapchain,
939 if (oldSwapchain != VK_NULL_HANDLE) {
948 assert(err == VK_SUCCESS);
952 assert(err == VK_SUCCESS);
962 VkImageViewCreateInfo colorAttachmentView = {
963 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
966 .image = swapchainImages[i],
967 .viewType = VK_IMAGE_VIEW_TYPE_2D,
970 .r = VK_COMPONENT_SWIZZLE_R,
971 .g = VK_COMPONENT_SWIZZLE_G,
972 .b = VK_COMPONENT_SWIZZLE_B,
973 .a = VK_COMPONENT_SWIZZLE_A
975 .subresourceRange = {
976 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
985 assert(err == VK_SUCCESS);
992 return StringTools::tokenize(
deviceName,
" \t\n")[0];
1010 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
1014 if (FileSystem::getInstance()->exists(
"shader/vk") ==
false) {
1015 FileSystem::getInstance()->createPath(
"shader/vk");
1018 Console::println(
string() +
"An error occurred: " + exception.what());
1025 glslang::InitProcess();
1026 glslang::InitThread();
1031 uint32_t requiredExtensionCount = 0;
1032 uint32_t instanceExtensionCount = 0;
1033 uint32_t instanceLayerCount = 0;
1034 uint32_t validationLayerCount = 0;
1035 const char** requiredExtensions =
nullptr;
1036 const char** instanceValidationLayers =
nullptr;
1038 uint32_t enabledExtensionCount = 0;
1039 uint32_t enabledLayerCount = 0;
1040 array<const char*, 64> extensionNames {};
1041 array<const char*, 64>enabledLayers {};
1043 const char* instanceValidationLayersAlt1[] = {
1044 "VK_LAYER_KHRONOS_validation"
1046 const char* instanceValidationLayersAlt2[] = {
1047 "VK_LAYER_LUNARG_standard_validation"
1051 auto enableValidationLayers = Application::getApplication()->isDebuggingEnabled();
1052 if (enableValidationLayers ==
true) {
1053 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): \"--debug\" mode enabled: Enabling validation layers");
1055 VkBool32 validationFound = 0;
1056 err = vkEnumerateInstanceLayerProperties(&instanceLayerCount,
nullptr);
1059 instanceValidationLayers = (
const char**)instanceValidationLayersAlt1;
1060 if (instanceLayerCount > 0) {
1061 vector<VkLayerProperties> instanceLayers(instanceLayerCount);
1062 err = vkEnumerateInstanceLayerProperties(&instanceLayerCount, instanceLayers.data());
1067 instanceValidationLayers,
1070 if (validationFound == VK_SUCCESS) {
1071 enabledLayerCount =
ARRAY_SIZE(instanceValidationLayersAlt1);
1072 enabledLayers[0] =
"VK_LAYER_LUNARG_standard_validation";
1073 validationLayerCount = 1;
1076 instanceValidationLayers = (
const char**) instanceValidationLayersAlt2;
1077 enabledLayerCount =
ARRAY_SIZE(instanceValidationLayersAlt2);
1080 instanceValidationLayers,
1083 validationLayerCount =
ARRAY_SIZE(instanceValidationLayersAlt2);
1084 for (i = 0; i < validationLayerCount; i++) {
1085 enabledLayers[i] = instanceValidationLayers[i];
1090 if (!validationFound) {
1091 ERR_EXIT(
"vkEnumerateInstanceLayerProperties failed to find "
1092 "required validation layer.\n\n"
1093 "Please look at the Getting Started guide for additional "
1094 "information.\n",
"vkCreateInstance Failure");
1099 requiredExtensions = glfwGetRequiredInstanceExtensions(&requiredExtensionCount);
1100 if (!requiredExtensions) {
1101 ERR_EXIT(
"glfwGetRequiredInstanceExtensions failed to find the "
1102 "platform surface extensions.\n\nDo you have a compatible "
1103 "Vulkan installable client driver (ICD) installed?\nPlease "
1104 "look at the Getting Started guide for additional "
1105 "information.\n",
"vkCreateInstance Failure"
1109 for (i = 0; i < requiredExtensionCount; i++) {
1110 extensionNames[enabledExtensionCount++] = requiredExtensions[i];
1111 assert(enabledExtensionCount < 64);
1114 err = vkEnumerateInstanceExtensionProperties(
1115 nullptr, &instanceExtensionCount,
nullptr);
1118 if (instanceExtensionCount > 0) {
1119 vector<VkExtensionProperties> instanceExtensions(instanceExtensionCount);
1120 err = vkEnumerateInstanceExtensionProperties(
nullptr, &instanceExtensionCount, instanceExtensions.data());
1122 for (i = 0; i < instanceExtensionCount; i++) {
1123 if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, instanceExtensions[i].extensionName)) {
1124 if (enableValidationLayers ==
true) {
1125 extensionNames[enabledExtensionCount++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
1128 assert(enabledExtensionCount < 64);
1132 const VkApplicationInfo applicationInfo = {
1133 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
1135 .pApplicationName = Application::getApplication()->getTitle().c_str(),
1136 .applicationVersion = 0,
1137 .pEngineName =
"TDME2",
1138 .engineVersion = 200,
1139 .apiVersion = VK_API_VERSION_1_0,
1141 VkInstanceCreateInfo instanceCreateInfo = {
1142 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
1145 .pApplicationInfo = &applicationInfo,
1146 .enabledLayerCount = enabledLayerCount,
1147 .ppEnabledLayerNames = instanceValidationLayers,
1148 .enabledExtensionCount = enabledExtensionCount,
1149 .ppEnabledExtensionNames = extensionNames.data(),
1151 err = vkCreateInstance(&instanceCreateInfo,
nullptr, &
instance);
1152 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
1153 ERR_EXIT(
"Cannot find a compatible Vulkan installable client driver "
1154 "(ICD).\n\nPlease look at the Getting Started guide for "
1155 "additional information.\n",
"vkCreateInstance Failure");
1157 if (err == VK_ERROR_EXTENSION_NOT_PRESENT) {
1158 ERR_EXIT(
"Cannot find a specified extension library"
1159 ".\nMake sure your layers path is set appropriately\n",
1160 "vkCreateInstance Failure");
1163 ERR_EXIT(
"vkCreateInstance failed.\n\nDo you have a compatible Vulkan "
1164 "installable client driver (ICD) installed?\nPlease look at "
1165 "the Getting Started guide for additional information.\n",
1166 "vkCreateInstance Failure");
1170 uint32_t gpuCount = 0;
1171 err = vkEnumeratePhysicalDevices(
instance, &gpuCount,
nullptr);
1172 assert(!err && gpuCount > 0);
1176 vector<VkPhysicalDevice> physicalDevices(gpuCount);
1177 err = vkEnumeratePhysicalDevices(
instance, &gpuCount, physicalDevices.data());
1182 "vkEnumeratePhysicalDevices reported zero accessible devices."
1183 "\n\nDo you have a compatible Vulkan installable client"
1184 " driver (ICD) installed?\nPlease look at the Getting Started"
1185 " guide for additional information.\n",
1186 "vkEnumeratePhysicalDevices Failure"
1191 uint32_t deviceExtensionCount = 0;
1192 VkBool32 swapchainExtFound = 0;
1193 enabledExtensionCount = 0;
1195 err = vkEnumerateDeviceExtensionProperties(
physicalDevice,
nullptr, &deviceExtensionCount,
nullptr);
1198 if (deviceExtensionCount > 0) {
1199 vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
1200 err = vkEnumerateDeviceExtensionProperties(
physicalDevice,
nullptr, &deviceExtensionCount, deviceExtensions.data());
1202 for (i = 0; i < deviceExtensionCount; i++) {
1203 if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME, deviceExtensions[i].extensionName)) {
1204 swapchainExtFound = 1;
1205 extensionNames[enabledExtensionCount++] = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
1207 assert(enabledExtensionCount < 64);
1211 if (!swapchainExtFound) {
1213 "vkEnumerateDeviceExtensionProperties failed to find "
1214 "the " VK_KHR_SWAPCHAIN_EXTENSION_NAME
1215 " extension.\n\nDo you have a compatible "
1216 "Vulkan installable client driver (ICD) installed?\nPlease "
1217 "look at the Getting Started guide for additional "
1218 "information.\n",
"vkCreateInstance Failure"
1247 err = glfwCreateWindowSurface(
instance, Application::glfwWindow,
nullptr, &
surface);
1251 vector<VkBool32> supportsPresent(
queueCount);
1259 uint32_t presentQueueNodeIndex = UINT32_MAX;
1265 if (supportsPresent[i] == VK_TRUE) {
1267 presentQueueNodeIndex = i;
1272 if (presentQueueNodeIndex == UINT32_MAX) {
1276 if (supportsPresent[i] == VK_TRUE) {
1277 presentQueueNodeIndex = i;
1286 "Could not find a graphics and a present queue\n",
1287 "Swapchain Initialization Failure"
1298 "Could not find a common graphics and a present queue\n",
1299 "Swapchain Initialization Failure"
1304 array<float, 1> queuePriorities { 0.0f };
1305 const VkDeviceQueueCreateInfo queueCreateInfo = {
1306 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1310 .queueCount = queuePriorities.size(),
1311 .pQueuePriorities = queuePriorities.data()
1314 VkPhysicalDeviceFeatures features {};
1315 if (
gpuFeatures.shaderClipDistance) features.shaderClipDistance = VK_TRUE;
1316 if (
gpuFeatures.wideLines) features.wideLines = VK_TRUE;
1318 VkDeviceCreateInfo deviceCreateInfo = {
1319 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1322 .queueCreateInfoCount = 1,
1323 .pQueueCreateInfos = &queueCreateInfo,
1324 .enabledLayerCount = 0,
1325 .ppEnabledLayerNames =
nullptr,
1326 .enabledExtensionCount = enabledExtensionCount,
1327 .ppEnabledExtensionNames = extensionNames.data(),
1328 .pEnabledFeatures = &features
1342 uint32_t surfaceFormatCount;
1345 vector<VkSurfaceFormatKHR> surfaceFormats(surfaceFormatCount);
1353 if (surfaceFormatCount == 1 && surfaceFormats[0].format == VK_FORMAT_UNDEFINED) {
1357 for (
auto i = 0; i < surfaceFormatCount; i++) {
1358 if (surfaceFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM) {
1366 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): No format given");
1368 "Could not use VK_FORMAT_R8G8B8A8_UNORM as format\n",
1377 VmaAllocatorCreateInfo allocatorCreateInfo = {};
1379 allocatorCreateInfo.device =
device;
1380 allocatorCreateInfo.instance =
instance;
1381 allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_0;
1384 vmaCreateAllocator(&allocatorCreateInfo, &
vmaAllocator);
1391 array<VkDescriptorPoolSize, 2> desc1TypesCount = {{
1393 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1398 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1403 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
1404 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1409 .poolSizeCount = desc1TypesCount.size(),
1410 .pPoolSizes = desc1TypesCount.data(),
1419 const VkDescriptorPoolSize desc2TypesCount = {
1420 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1424 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
1425 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1431 .pPoolSizes = &desc2TypesCount,
1442 auto& context =
contexts[contextIdx];
1444 context.idx = contextIdx;
1445 context.setupCommandInUse = VK_NULL_HANDLE;
1446 context.currentCommandBuffer = 0;
1447 context.pipelineIdx =
ID_NONE;
1448 context.pipeline = VK_NULL_HANDLE;
1449 context.renderPassStarted =
false;
1453 context.commandBuffers[i].drawCmdStarted =
false;
1454 VkFenceCreateInfo fenceCreateInfoSignaled = {
1455 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1457 .flags = VK_FENCE_CREATE_SIGNALED_BIT
1459 vkCreateFence(
device, &fenceCreateInfoSignaled,
nullptr, &context.commandBuffers[i].drawFence);
1466 const VkCommandPoolCreateInfo commandPoolCreateInfo = {
1467 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1469 .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
1472 err = vkCreateCommandPool(
device, &commandPoolCreateInfo,
nullptr, &context.setupCommandPool);
1476 const VkCommandBufferAllocateInfo commandBufferAllocationInfo = {
1477 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1479 .commandPool = context.setupCommandPool,
1480 .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1481 .commandBufferCount = 1
1483 err = vkAllocateCommandBuffers(
device, &commandBufferAllocationInfo, &context.setupCommand);
1489 const VkCommandPoolCreateInfo commandPoolCreateInfo = {
1490 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1492 .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
1495 err = vkCreateCommandPool(
device, &commandPoolCreateInfo,
nullptr, &context.drawCommandPool);
1499 const VkCommandBufferAllocateInfo commandBufferAllocationInfo = {
1500 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1502 .commandPool = context.drawCommandPool,
1503 .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1504 .commandBufferCount = 1
1507 err = vkAllocateCommandBuffers(
device, &commandBufferAllocationInfo, &context.commandBuffers[i].drawCommand);
1513 VkFenceCreateInfo fenceCreateInfo = {
1514 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1518 vkCreateFence(
device, &fenceCreateInfo,
nullptr, &context.setupFence);
1529 array<float, 16> bogusVertexBuffer = {{
1530 0.0f, 0.0f, 0.0f, 0.0f,
1531 0.0f, 0.0f, 0.0f, 0.0f,
1532 0.0f, 0.0f, 0.0f, 0.0f,
1533 0.0f, 0.0f, 0.0f, 0.0f,
1535 uploadBufferObjectInternal(0,
emptyVertexBuffer, bogusVertexBuffer.size() *
sizeof(
float), (uint8_t*)bogusVertexBuffer.data(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
1544 "cubemap-default-white",
1545 TextureReader::read(
"resources/engine/textures",
"transparent_pixel.png"),
1546 TextureReader::read(
"resources/engine/textures",
"transparent_pixel.png"),
1547 TextureReader::read(
"resources/engine/textures",
"transparent_pixel.png"),
1548 TextureReader::read(
"resources/engine/textures",
"transparent_pixel.png"),
1549 TextureReader::read(
"resources/engine/textures",
"transparent_pixel.png"),
1550 TextureReader::read(
"resources/engine/textures",
"transparent_pixel.png"),
1565 for (
auto i = 0; i < rendererContext.lights.size(); i++) {
1566 rendererContext.lights[i].spotCosCutoff =
static_cast<float>(Math::cos(Math::PI / 180.0f * 180.0f));
1568 rendererContext.textureMatrix.identity();
1587 { THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ, THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE },
1588 THSVS_IMAGE_LAYOUT_OPTIMAL,
1593 array<VkAttachmentDescription, 2> attachments = {{
1597 .samples = VK_SAMPLE_COUNT_1_BIT,
1598 .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1599 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
1600 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1601 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
1602 .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1603 .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
1607 .format = VK_FORMAT_D32_SFLOAT,
1608 .samples = VK_SAMPLE_COUNT_1_BIT,
1609 .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1610 .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
1611 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1612 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
1613 .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1614 .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
1617 const VkAttachmentReference colorReference = {
1619 .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1621 const VkAttachmentReference depthReference = {
1623 .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1625 const VkSubpassDescription subPass = {
1627 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
1628 .inputAttachmentCount = 0,
1629 .pInputAttachments =
nullptr,
1630 .colorAttachmentCount = 1,
1631 .pColorAttachments = &colorReference,
1632 .pResolveAttachments =
nullptr,
1633 .pDepthStencilAttachment = &depthReference,
1634 .preserveAttachmentCount = 0,
1635 .pPreserveAttachments =
nullptr
1637 const VkRenderPassCreateInfo rp_info = {
1638 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
1641 .attachmentCount = 2,
1642 .pAttachments = attachments.data(),
1644 .pSubpasses = &subPass,
1645 .dependencyCount = 0,
1646 .pDependencies =
nullptr
1653 auto& currentContext =
contexts[contextIdx];
1655 if (currentContext.renderPassStarted ==
true)
return;
1656 currentContext.renderPassStarted =
true;
1662 if (frameBuffer ==
nullptr) {
1663 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): framebuffer not found: " + to_string(
boundFrameBufferId));
1665 usedFrameBuffer = frameBuffer->frameBuffer;
1666 vkRenderPass = frameBuffer->renderPass;
1671 const VkRenderPassBeginInfo renderPassBegin = {
1672 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1674 .renderPass = vkRenderPass,
1675 .framebuffer = usedFrameBuffer,
1677 .clearValueCount = 0,
1678 .pClearValues =
nullptr
1680 vkCmdBeginRenderPass(currentContext.commandBuffers[currentContext.currentCommandBuffer].drawCommand, &renderPassBegin, VK_SUBPASS_CONTENTS_INLINE);
1687 auto& currentContext =
contexts[contextIdx];
1688 if (currentContext.renderPassStarted ==
false)
return;
1689 currentContext.renderPassStarted =
false;
1690 vkCmdEndRenderPass(currentContext.commandBuffers[currentContext.currentCommandBuffer].drawCommand);
1694 array<VkImageView, 2> attachments;
1696 attachments[1] = depthBufferTexture->view;
1698 const VkFramebufferCreateInfo frameBufferCreateInfo = {
1699 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1703 .attachmentCount = 2,
1704 .pAttachments = attachments.data(),
1718 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
1724 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(
windowWidth) +
" x " + to_string(
windowHeight));
1750 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
1754 int32_t currentWidth;
1755 int32_t currentHeight;
1756 glfwGetWindowSize(Application::glfwWindow, ¤tWidth, ¤tHeight);
1760 if (needsReshape ==
true)
reshape();
1765 VkSemaphoreCreateInfo semaphoreCreateInfo = {
1766 .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
1784 if (err == VK_ERROR_OUT_OF_DATE_KHR) {
1802 if (err == VK_SUBOPTIMAL_KHR) {
1810 for (
auto i = 0; i <
contexts.size(); i++) {
1819 if (program ==
nullptr || program->contexts[context.idx].texturesDescriptorSetsCacheTextureIds.empty() ==
true)
continue;
1820 auto& programContext = program->contexts[context.idx];
1821 auto& descriptorSets2CacheTextureIds = programContext.texturesDescriptorSetsCacheTextureIds;
1822 auto descriptorSets2CacheTextureIdsIt = descriptorSets2CacheTextureIds.find(textureId);
1823 if (descriptorSets2CacheTextureIdsIt != descriptorSets2CacheTextureIds.end()) {
1824 auto& descriptorSets2Cache = programContext.texturesDescriptorSetsCache;
1825 for (
auto& descriptorSets2CacheHash: descriptorSets2CacheTextureIdsIt->second) {
1826 auto descriptorSets2CacheHashIt = descriptorSets2Cache.find(descriptorSets2CacheHash);
1827 if (descriptorSets2CacheHashIt != descriptorSets2Cache.end()) {
1828 auto desc_sets2_idx = descriptorSets2CacheHashIt->second;
1829 programContext.freeTextureDescriptorSetsIds.push_back(desc_sets2_idx);
1830 descriptorSets2Cache.erase(descriptorSets2CacheHashIt);
1833 descriptorSets2CacheTextureIds.erase(descriptorSets2CacheTextureIdsIt);
1841 auto clearedPipelinesParents = 0;
1842 auto clearedPipelines = 0;
1855 for (
auto pipeline: framebufferPipelines->pipelines) {
1856 if (pipeline != VK_NULL_HANDLE) {
1863 clearedPipelinesParents++;
1869 "VKRenderer::" +
string(__FUNCTION__) +
"(): " +
1870 "cleared pipelines parents: " + to_string(clearedPipelinesParents) +
", " +
1871 "cleared pipelines: " + to_string(clearedPipelines)
1877 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
1885 context.program =
nullptr;
1892 array<ThsvsAccessType, 2> nextAccessTypes { THSVS_ACCESS_PRESENT, THSVS_ACCESS_NONE };
1893 ThsvsImageLayout nextLayout { THSVS_IMAGE_LAYOUT_OPTIMAL };
1897 ThsvsImageBarrier svsImageBarrier = {
1900 .nextAccessCount =
static_cast<uint32_t
>(nextAccessTypes[1] != THSVS_ACCESS_NONE?2:1),
1901 .pNextAccesses = nextAccessTypes.data(),
1903 .nextLayout = nextLayout,
1904 .discardContents =
false,
1905 .srcQueueFamilyIndex = 0,
1906 .dstQueueFamilyIndex = 0,
1908 .subresourceRange = {
1909 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
1912 .baseArrayLayer = 0,
1916 VkImageMemoryBarrier vkImageMemoryBarrier;
1917 VkPipelineStageFlags srcStages;
1918 VkPipelineStageFlags dstStages;
1919 thsvsGetVulkanImageMemoryBarrier(
1923 &vkImageMemoryBarrier
1931 vkCmdPipelineBarrier(
contexts[0].setupCommandInUse, srcStages, dstStages, 0, 0,
nullptr, 0,
nullptr, 1, &vkImageMemoryBarrier);
1940 VkResult presentResult = VK_SUCCESS;
1941 VkPresentInfoKHR presentInfoKHR = {
1942 .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
1944 .waitSemaphoreCount = 0,
1945 .pWaitSemaphores =
nullptr,
1946 .swapchainCount = 1,
1949 .pResults = &presentResult
1955 auto needsReshape =
false;
1956 if (err == VK_ERROR_OUT_OF_DATE_KHR) {
1957 needsReshape =
true;
1959 if (err == VK_SUBOPTIMAL_KHR) {
1962 needsReshape =
true;
1982 if (texture ==
nullptr) {
1983 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): disposing texture: texture not found: " + to_string(textureId));
1989 texture->allocation,
1993 if (texture->cubemapColorBuffer !=
nullptr) {
1995 texture->cubemapColorBuffer->image,
1996 texture->cubemapColorBuffer->allocation,
1997 texture->cubemapColorBuffer->view,
1998 texture->cubemapColorBuffer->sampler
2001 if (texture->cubemapDepthBuffer !=
nullptr) {
2003 texture->cubemapDepthBuffer->image,
2004 texture->cubemapDepthBuffer->allocation,
2005 texture->cubemapDepthBuffer->view,
2006 texture->cubemapDepthBuffer->sampler
2020 if (buffer ==
nullptr) {
2021 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): disposing buffer object: buffer with id " + to_string(bufferObjectId) +
" does not exist");
2024 for (
auto& reusableBufferIt: buffer->buffers) {
2025 auto& reusableBuffer = reusableBufferIt;
2026 if (reusableBuffer.size == 0)
continue;
2029 reusableBuffer.buffer,
2030 reusableBuffer.allocation
2033 buffers[bufferObjectId] =
nullptr;
2040 vkDestroyPipeline(
device, pipeline,
nullptr);
2049 vmaDestroyBuffer(
vmaAllocator, deleteBuffer.buffer, deleteBuffer.allocation);
2055 if (deleteImage.imageView != VK_NULL_HANDLE) vkDestroyImageView(
device, deleteImage.imageView,
nullptr);
2056 if (deleteImage.sampler != VK_NULL_HANDLE) vkDestroySampler(
device, deleteImage.sampler,
nullptr);
2057 if (deleteImage.image != VK_NULL_HANDLE) vmaDestroyImage(
vmaAllocator, deleteImage.image, deleteImage.allocation);
2067 uint32_t bufferSize = 0;
2069 context.boundIndicesBuffer = VK_NULL_HANDLE;
2071 context.boundBufferSizes.fill(bufferSize);
2074 context.uploadedTextureIds.clear();
2137 int32_t
VKRenderer::loadShader(int32_t type,
const string& pathName,
const string& fileName,
const string& definitions,
const string& functions)
2139 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): INIT: " + pathName +
"/" + fileName +
": " + definitions);
2143 auto& shader = *shaderPtr;
2154 auto& currentContext =
contexts[contextIdx];
2157 currentContext.pipelineIdx =
ID_NONE;
2158 currentContext.pipeline = VK_NULL_HANDLE;
2162 rasterizationStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
2163 rasterizationStateCreateInfo.polygonMode = VK_POLYGON_MODE_FILL;
2164 rasterizationStateCreateInfo.cullMode =
contexts[contextIdx].cullingEnabled ==
true?
cullMode:VK_CULL_MODE_NONE;
2165 rasterizationStateCreateInfo.frontFace = (VkFrontFace)(
contexts[contextIdx].frontFace - 1);
2166 rasterizationStateCreateInfo.depthClampEnable = VK_FALSE;
2167 rasterizationStateCreateInfo.rasterizerDiscardEnable = VK_FALSE;
2168 rasterizationStateCreateInfo.depthBiasEnable = VK_FALSE;
2169 rasterizationStateCreateInfo.lineWidth = 1.0f;
2173 blendAttachmentState.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
2176 blendAttachmentState.dstColorBlendFactor =
blendingMode ==
BLENDING_NORMAL?VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:VK_BLEND_FACTOR_ONE;
2177 blendAttachmentState.colorBlendOp = VK_BLEND_OP_ADD;
2179 blendAttachmentState.dstAlphaBlendFactor =
blendingMode ==
BLENDING_NORMAL?VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:VK_BLEND_FACTOR_ONE;
2180 blendAttachmentState.alphaBlendOp = VK_BLEND_OP_ADD;
2184 depthStencilStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
2185 depthStencilStateCreateInfo.depthTestEnable =
depthBufferTesting ==
true?VK_TRUE:VK_FALSE;
2186 depthStencilStateCreateInfo.depthWriteEnable =
depthBufferWriting ==
true?VK_TRUE:VK_FALSE;
2187 depthStencilStateCreateInfo.depthCompareOp = (VkCompareOp)
depthFunction;
2188 depthStencilStateCreateInfo.back.failOp = VK_STENCIL_OP_KEEP;
2189 depthStencilStateCreateInfo.back.passOp = VK_STENCIL_OP_KEEP;
2190 depthStencilStateCreateInfo.back.compareOp = VK_COMPARE_OP_ALWAYS;
2191 depthStencilStateCreateInfo.stencilTestEnable = VK_FALSE;
2192 depthStencilStateCreateInfo.front = depthStencilStateCreateInfo.back;
2193 depthStencilStateCreateInfo.depthBoundsTestEnable = VK_FALSE;
2194 depthStencilStateCreateInfo.minDepthBounds = 0.0f;
2195 depthStencilStateCreateInfo.maxDepthBounds = 1.0f;
2207 (program->
id & 0x7f) +
2208 ((
contexts[contextIdx].cullingEnabled ==
true?
cullMode:VK_CULL_MODE_NONE & 0x3) << 7) +
2209 ((
contexts[contextIdx].frontFaceIndex & 0x3) << 9) +
2218 vector<VkDescriptorSetLayoutBinding> layoutBindings1(program->
layoutBindings);
2219 vector<VkDescriptorSetLayoutBinding> layoutBindings2(program->
layoutBindings);
2222 auto samplerIdx = 0;
2224 for (
auto shader: program->
shaders) {
2225 if (shader->uboBindingIdx != -1) {
2226 layoutBindings1[uboIdx++] = {
2227 .binding =
static_cast<uint32_t
>(shader->uboBindingIdx),
2228 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
2229 .descriptorCount = 1,
2230 .stageFlags =
static_cast<VkShaderStageFlags
>(shader->type),
2231 .pImmutableSamplers =
nullptr
2235 for (
auto uniform: shader->samplerUniformList) {
2236 layoutBindings2[samplerIdx++] = {
2237 .binding =
static_cast<uint32_t
>(uniform->position),
2238 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
2239 .descriptorCount = 1,
2240 .stageFlags =
static_cast<VkShaderStageFlags
>(shader->type),
2241 .pImmutableSamplers =
nullptr
2247 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
2248 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2251 .bindingCount =
static_cast<uint32_t
>(uboIdx),
2252 .pBindings = layoutBindings1.data(),
2258 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
2259 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
2262 .bindingCount =
static_cast<uint32_t
>(samplerIdx),
2263 .pBindings = layoutBindings2.data(),
2271 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
2272 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2275 .setLayoutCount = descriptorSetLayouts.size(),
2276 .pSetLayouts = descriptorSetLayouts.data()
2281 array<VkDescriptorSetLayout, DESC_MAX_UNCACHED> descriptorSetLayouts1;
2284 VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
2285 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2289 .pSetLayouts = descriptorSetLayouts1.data()
2292 err = vkAllocateDescriptorSets(
device, &descriptorSetAllocateInfo, program->
contexts[context.idx].commandBuffers[i].uboDescriptorSets.data());
2299 array<VkDescriptorSetLayout, DESC_MAX_CACHED> descriptorSetLayouts2;
2302 VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
2303 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2307 .pSetLayouts = descriptorSetLayouts2.data()
2310 err = vkAllocateDescriptorSets(
device, &descriptorSetAllocateInfo, program->
contexts[context.idx].descriptorSets2.data());
2317 array<VkDescriptorSetLayout, DESC_MAX_UNCACHED> descriptorSetLayouts2;
2320 VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
2321 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2325 .pSetLayouts = descriptorSetLayouts2.data()
2328 err = vkAllocateDescriptorSets(
device, &descriptorSetAllocateInfo, program->
contexts[context.idx].commandBuffers[i].texturesDescriptorSetsUncached.data());
2334 err = vkCreatePipelineLayout(
device, &pipelineLayoutCreateInfo,
nullptr, &program->
pipelineLayout);
2339 auto& currentContext =
contexts[contextIdx];
2343 if (framebufferPipelines ==
nullptr) {
2349 auto haveDepthBuffer =
true;
2350 auto haveColorBuffer =
true;
2351 auto haveGeometryBuffer =
false;
2354 if (frameBuffer !=
nullptr) {
2355 haveDepthBuffer = frameBuffer->depthTextureId !=
ID_NONE;
2356 haveColorBuffer = frameBuffer->colorTextureId !=
ID_NONE;
2358 usedRenderPass = frameBuffer->renderPass;
2360 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): framebuffer with id: " + to_string(
boundFrameBufferId) +
" not found!");
2368 VkGraphicsPipelineCreateInfo pipeline {};
2371 VkPipelineCacheCreateInfo pipelineCacheCreateInfo {};
2372 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
2374 VkPipelineVertexInputStateCreateInfo vi {};
2375 VkPipelineInputAssemblyStateCreateInfo ia {};
2376 VkPipelineRasterizationStateCreateInfo rs {};
2377 VkPipelineColorBlendStateCreateInfo cb {};
2378 VkPipelineDepthStencilStateCreateInfo ds {};
2379 VkPipelineViewportStateCreateInfo vp {};
2380 VkPipelineMultisampleStateCreateInfo ms {};
2385 array<VkPipelineShaderStageCreateInfo, 2> shaderStages {};
2389 for (
auto shader: program->
shaders) {
2390 shaderStages[
shaderIdx].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
2391 shaderStages[
shaderIdx].stage = shader->type;
2392 shaderStages[
shaderIdx].module = shader->module;
2397 pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
2401 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
2402 ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
2404 array<VkPipelineColorBlendAttachmentState, 8> bas;
2405 if (haveColorBuffer ==
true) {
2408 if (haveGeometryBuffer ==
true) {
2409 for (
auto i = 0; i < 8; i++) {
2414 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
2415 cb.logicOpEnable = VK_FALSE;
2416 cb.attachmentCount = haveColorBuffer ==
true?1:(haveGeometryBuffer ==
true?8:0);
2417 cb.pAttachments = haveColorBuffer ==
true || haveGeometryBuffer ==
true?bas.data():
nullptr;
2419 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
2420 vp.viewportCount = 1;
2422 vp.scissorCount = 1;
2425 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
2426 ms.pSampleMask =
nullptr;
2427 ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2429 array<VkVertexInputBindingDescription, 4> vb {};
2430 array<VkVertexInputAttributeDescription, 4> va {};
2434 vb[0].stride =
sizeof(float) * 2;
2435 vb[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2438 va[0].format = VK_FORMAT_R32G32_SFLOAT;
2443 vb[1].stride =
sizeof(float) * 1;
2444 vb[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2447 va[1].format = VK_FORMAT_R32_SFLOAT;
2452 vb[2].stride =
sizeof(float) * 2;
2453 vb[2].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2456 va[2].format = VK_FORMAT_R32G32_SFLOAT;
2461 vb[3].stride =
sizeof(float) * 4;
2462 vb[3].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2465 va[3].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2469 vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
2471 vi.vertexBindingDescriptionCount = vb.size();
2472 vi.pVertexBindingDescriptions = vb.data();
2473 vi.vertexAttributeDescriptionCount = va.size();
2474 vi.pVertexAttributeDescriptions = va.data();
2476 pipeline.pVertexInputState = &vi;
2477 pipeline.pInputAssemblyState = &ia;
2478 pipeline.pRasterizationState = &rs;
2479 pipeline.pColorBlendState = haveColorBuffer ==
true || haveGeometryBuffer ==
true?&cb:
nullptr;
2480 pipeline.pMultisampleState = &ms;
2481 pipeline.pViewportState = &vp;
2482 pipeline.pDepthStencilState = haveDepthBuffer ==
true?&ds:
nullptr;
2483 pipeline.pStages = shaderStages.data();
2484 pipeline.renderPass = usedRenderPass;
2485 pipeline.pDynamicState =
nullptr;
2487 pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
2488 err = vkCreatePipelineCache(
device, &pipelineCacheCreateInfo,
nullptr, &pipelineCache);
2491 err = vkCreateGraphicsPipelines(
device, pipelineCache, 1, &pipeline,
nullptr, &framebufferPipelines->pipelines[currentContext.pipelineIdx]);
2495 vkDestroyPipelineCache(
device, pipelineCache,
nullptr);
2499 auto& currentContext =
contexts[contextIdx];
2500 if (currentContext.pipelineIdx ==
ID_NONE || currentContext.pipeline == VK_NULL_HANDLE) {
2504 if (pipeline == VK_NULL_HANDLE) {
2510 auto& commandBuffer = currentContext.commandBuffers[currentContext.currentCommandBuffer];
2511 vkCmdBindPipeline(commandBuffer.drawCommand, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
2512 currentContext.pipeline = pipeline;
2517 auto& currentContext =
contexts[contextIdx];
2521 if (framebufferPipelines ==
nullptr) {
2527 auto haveDepthBuffer =
true;
2528 auto haveColorBuffer =
true;
2529 auto haveGeometryBuffer =
false;
2532 if (frameBuffer !=
nullptr) {
2533 haveDepthBuffer = frameBuffer->depthTextureId !=
ID_NONE;
2534 haveColorBuffer = frameBuffer->colorTextureId !=
ID_NONE;
2536 usedRenderPass = frameBuffer->renderPass;
2538 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): framebuffer with id: " + to_string(
boundFrameBufferId) +
" not found!");
2546 VkGraphicsPipelineCreateInfo pipeline {};
2549 VkPipelineCacheCreateInfo pipelineCacheCreateInfo {};
2550 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
2552 VkPipelineVertexInputStateCreateInfo vi {};
2553 VkPipelineInputAssemblyStateCreateInfo ia {};
2554 VkPipelineRasterizationStateCreateInfo rs {};
2555 VkPipelineColorBlendStateCreateInfo cb {};
2556 VkPipelineDepthStencilStateCreateInfo ds {};
2557 VkPipelineViewportStateCreateInfo vp {};
2558 VkPipelineMultisampleStateCreateInfo ms {};
2563 array<VkPipelineShaderStageCreateInfo, 2> shaderStages {};
2567 for (
auto shader: program->
shaders) {
2568 shaderStages[
shaderIdx].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
2569 shaderStages[
shaderIdx].stage = shader->type;
2570 shaderStages[
shaderIdx].module = shader->module;
2575 pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
2579 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
2580 ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
2582 array<VkPipelineColorBlendAttachmentState, 8> bas;
2583 if (haveColorBuffer ==
true) {
2586 if (haveGeometryBuffer ==
true) {
2587 for (
auto i = 0; i < 8; i++) {
2592 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
2593 cb.logicOpEnable = VK_FALSE;
2594 cb.attachmentCount = haveColorBuffer ==
true?1:(haveGeometryBuffer ==
true?8:0);
2595 cb.pAttachments = haveColorBuffer ==
true || haveGeometryBuffer ==
true?bas.data():
nullptr;
2597 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
2598 vp.viewportCount = 1;
2600 vp.scissorCount = 1;
2603 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
2604 ms.pSampleMask =
nullptr;
2605 ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2607 array<VkVertexInputBindingDescription, 10> vb {};
2608 array<VkVertexInputAttributeDescription, 13> va {};
2612 vb[0].stride =
sizeof(float) * 3;
2613 vb[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2616 va[0].format = VK_FORMAT_R32G32B32_SFLOAT;
2621 vb[1].stride =
sizeof(float) * 3;
2622 vb[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2625 va[1].format = VK_FORMAT_R32G32B32_SFLOAT;
2630 vb[2].stride =
sizeof(float) * 2;
2631 vb[2].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2634 va[2].format = VK_FORMAT_R32G32_SFLOAT;
2639 vb[3].stride =
sizeof(float) * 4;
2640 vb[3].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2643 va[3].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2648 vb[4].stride =
sizeof(float) * 3;
2649 vb[4].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2652 va[4].format = VK_FORMAT_R32G32B32_SFLOAT;
2657 vb[5].stride =
sizeof(float) * 3;
2658 vb[5].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2661 va[5].format = VK_FORMAT_R32G32B32_SFLOAT;
2666 vb[6].stride =
sizeof(float) * 4 * 4;
2667 vb[6].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
2670 va[6].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2671 va[6].offset =
sizeof(float) * 4 * 0;
2676 va[7].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2677 va[7].offset =
sizeof(float) * 4 * 1;
2682 va[8].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2683 va[8].offset =
sizeof(float) * 4 * 2;
2688 va[9].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2689 va[9].offset =
sizeof(float) * 4 * 3;
2693 vb[7].stride =
sizeof(float) * 4;
2694 vb[7].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
2696 va[10].location = 10;
2697 va[10].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2702 vb[8].stride =
sizeof(float) * 4;
2703 vb[8].inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;
2705 va[11].location = 11;
2706 va[11].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2711 vb[9].stride =
sizeof(float) * 3;
2712 vb[9].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2714 va[12].location = 12;
2715 va[12].format = VK_FORMAT_R32G32B32_SFLOAT;
2718 vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
2720 vi.vertexBindingDescriptionCount = vb.size();
2721 vi.pVertexBindingDescriptions = vb.data();
2722 vi.vertexAttributeDescriptionCount = va.size();
2723 vi.pVertexAttributeDescriptions = va.data();
2725 pipeline.pVertexInputState = &vi;
2726 pipeline.pInputAssemblyState = &ia;
2727 pipeline.pRasterizationState = &rs;
2728 pipeline.pColorBlendState = haveColorBuffer ==
true || haveGeometryBuffer ==
true?&cb:
nullptr;
2729 pipeline.pMultisampleState = &ms;
2730 pipeline.pViewportState = &vp;
2731 pipeline.pDepthStencilState = haveDepthBuffer ==
true?&ds:
nullptr;
2732 pipeline.pStages = shaderStages.data();
2733 pipeline.renderPass = usedRenderPass;
2734 pipeline.pDynamicState =
nullptr;
2736 pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
2737 err = vkCreatePipelineCache(
device, &pipelineCacheCreateInfo,
nullptr, &pipelineCache);
2740 err = vkCreateGraphicsPipelines(
device, pipelineCache, 1, &pipeline,
nullptr, &framebufferPipelines->pipelines[currentContext.pipelineIdx]);
2744 vkDestroyPipelineCache(
device, pipelineCache,
nullptr);
2748 auto& currentContext =
contexts[contextIdx];
2749 if (currentContext.pipelineIdx ==
ID_NONE || currentContext.pipeline == VK_NULL_HANDLE) {
2753 if (pipeline == VK_NULL_HANDLE) {
2759 auto& commandBuffer = currentContext.commandBuffers[currentContext.currentCommandBuffer];
2760 vkCmdBindPipeline(commandBuffer.drawCommand, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
2761 currentContext.pipeline = pipeline;
2766 auto& currentContext =
contexts[contextIdx];
2770 if (framebufferPipelines ==
nullptr) {
2776 auto haveDepthBuffer =
true;
2777 auto haveColorBuffer =
true;
2778 auto haveGeometryBuffer =
false;
2781 if (frameBuffer !=
nullptr) {
2782 haveDepthBuffer = frameBuffer->depthTextureId !=
ID_NONE;
2783 haveColorBuffer = frameBuffer->colorTextureId !=
ID_NONE;
2785 usedRenderPass = frameBuffer->renderPass;
2793 VkGraphicsPipelineCreateInfo pipeline {};
2796 array<VkPipelineShaderStageCreateInfo, 2> shaderStages {};
2800 for (
auto shader: program->
shaders) {
2801 shaderStages[
shaderIdx].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
2802 shaderStages[
shaderIdx].stage = shader->type;
2803 shaderStages[
shaderIdx].module = shader->module;
2809 VkPipelineCacheCreateInfo pipelineCacheCreateInfo {};
2810 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
2812 VkPipelineVertexInputStateCreateInfo vi {};
2813 VkPipelineInputAssemblyStateCreateInfo ia {};
2814 VkPipelineRasterizationStateCreateInfo rs {};
2815 VkPipelineColorBlendStateCreateInfo cb {};
2816 VkPipelineDepthStencilStateCreateInfo ds {};
2817 VkPipelineViewportStateCreateInfo vp {};
2818 VkPipelineMultisampleStateCreateInfo ms {};
2823 pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
2827 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
2828 ia.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
2830 array<VkPipelineColorBlendAttachmentState, 8> bas;
2831 if (haveColorBuffer ==
true) {
2834 if (haveGeometryBuffer ==
true) {
2835 for (
auto i = 0; i < 8; i++) {
2839 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
2840 cb.logicOpEnable = VK_FALSE;
2841 cb.attachmentCount = haveColorBuffer ==
true?1:(haveGeometryBuffer ==
true?8:0);
2842 cb.pAttachments = haveColorBuffer ==
true || haveGeometryBuffer ==
true?bas.data():
nullptr;
2844 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
2845 vp.viewportCount = 1;
2847 vp.scissorCount = 1;
2850 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
2851 ms.pSampleMask =
nullptr;
2852 ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
2854 array<VkVertexInputBindingDescription, 9> vb {};
2855 array<VkVertexInputAttributeDescription, 9> va {};
2859 vb[0].stride =
sizeof(float) * 3;
2860 vb[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2863 va[0].format = VK_FORMAT_R32G32B32_SFLOAT;
2868 vb[1].stride =
sizeof(uint16_t) * 2;
2869 vb[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2872 va[1].format = VK_FORMAT_R16G16_UINT;
2877 vb[2].stride =
sizeof(float);
2878 vb[2].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2881 va[2].format = VK_FORMAT_R32_SFLOAT;
2886 vb[3].stride =
sizeof(float) * 4;
2887 vb[3].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2890 va[3].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2895 vb[4].stride =
sizeof(float);
2896 vb[4].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2899 va[4].format = VK_FORMAT_R32_SFLOAT;
2904 vb[5].stride =
sizeof(float);
2905 vb[5].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2908 va[5].format = VK_FORMAT_R32_SFLOAT;
2913 vb[6].stride =
sizeof(uint16_t) * 2;
2914 vb[6].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2917 va[6].format = VK_FORMAT_R16G16_UINT;
2922 vb[7].stride =
sizeof(float) * 4;
2923 vb[7].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2925 va[7].location = 10;
2926 va[7].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2931 vb[8].stride =
sizeof(float) * 4;
2932 vb[8].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
2934 va[8].location = 11;
2935 va[8].format = VK_FORMAT_R32G32B32A32_SFLOAT;
2939 vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
2941 vi.vertexBindingDescriptionCount = vb.size();
2942 vi.pVertexBindingDescriptions = vb.data();
2943 vi.vertexAttributeDescriptionCount = va.size();
2944 vi.pVertexAttributeDescriptions = va.data();
2946 pipeline.pVertexInputState = &vi;
2947 pipeline.pInputAssemblyState = &ia;
2948 pipeline.pRasterizationState = &rs;
2949 pipeline.pColorBlendState = haveColorBuffer ==
true || haveGeometryBuffer ==
true?&cb:
nullptr;
2950 pipeline.pMultisampleState = &ms;
2951 pipeline.pViewportState = &vp;
2952 pipeline.pDepthStencilState = haveDepthBuffer ==
true?&ds:
nullptr;
2953 pipeline.pStages = shaderStages.data();
2954 pipeline.renderPass = usedRenderPass;
2955 pipeline.pDynamicState =
nullptr;
2957 pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
2958 err = vkCreatePipelineCache(
device, &pipelineCacheCreateInfo,
nullptr, &pipelineCache);
2961 err = vkCreateGraphicsPipelines(
device, pipelineCache, 1, &pipeline,
nullptr, &framebufferPipelines->pipelines[currentContext.pipelineIdx]);
2965 vkDestroyPipelineCache(
device, pipelineCache,
nullptr);
2969 auto& currentContext =
contexts[contextIdx];
2970 if (currentContext.pipelineIdx ==
ID_NONE || currentContext.pipeline == VK_NULL_HANDLE) {
2974 if (pipeline == VK_NULL_HANDLE) {
2981 auto& commandBuffer = currentContext.commandBuffers[currentContext.currentCommandBuffer];
2982 vkCmdBindPipeline(commandBuffer.drawCommand, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
2983 currentContext.pipeline = pipeline;
2988 auto& currentContext =
contexts[contextIdx];
2992 if (framebufferPipelines ==
nullptr) {
2998 auto haveDepthBuffer =
true;
2999 auto haveColorBuffer =
true;
3000 auto haveGeometryBuffer =
false;
3003 if (frameBuffer !=
nullptr) {
3004 haveDepthBuffer = frameBuffer->depthTextureId !=
ID_NONE;
3005 haveColorBuffer = frameBuffer->colorTextureId !=
ID_NONE;
3007 usedRenderPass = frameBuffer->renderPass;
3015 VkGraphicsPipelineCreateInfo pipeline {};
3016 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
3019 array<VkPipelineShaderStageCreateInfo, 2> shaderStages {};
3023 for (
auto shader: program->
shaders) {
3024 shaderStages[
shaderIdx].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
3025 shaderStages[
shaderIdx].stage = shader->type;
3026 shaderStages[
shaderIdx].module = shader->module;
3032 VkPipelineCacheCreateInfo pipelineCacheCreateInfo {};
3034 VkPipelineVertexInputStateCreateInfo vi {};
3035 VkPipelineInputAssemblyStateCreateInfo ia {};
3036 VkPipelineRasterizationStateCreateInfo rs {};
3037 VkPipelineColorBlendStateCreateInfo cb {};
3038 VkPipelineDepthStencilStateCreateInfo ds {};
3039 VkPipelineViewportStateCreateInfo vp {};
3040 VkPipelineMultisampleStateCreateInfo ms {};
3041 array<VkDynamicState, 1> dse {};
3042 VkPipelineDynamicStateCreateInfo dsc {};
3047 dse[dsc.dynamicStateCount++] = VK_DYNAMIC_STATE_LINE_WIDTH;
3048 dsc.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
3049 dsc.pDynamicStates = dse.data();
3051 pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
3055 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
3056 ia.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
3058 array<VkPipelineColorBlendAttachmentState, 8> bas;
3059 if (haveColorBuffer ==
true) {
3062 if (haveGeometryBuffer ==
true) {
3063 for (
auto i = 0; i < 8; i++) {
3068 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
3069 cb.logicOpEnable = VK_FALSE;
3070 cb.attachmentCount = haveColorBuffer ==
true?1:(haveGeometryBuffer ==
true?8:0);
3071 cb.pAttachments = haveColorBuffer ==
true || haveGeometryBuffer ==
true?bas.data():
nullptr;
3073 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
3074 vp.viewportCount = 1;
3076 vp.scissorCount = 1;
3079 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
3080 ms.pSampleMask =
nullptr;
3081 ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
3083 array<VkVertexInputBindingDescription, 4> vb {};
3084 array<VkVertexInputAttributeDescription, 4> va {};
3088 vb[0].stride =
sizeof(float) * 3;
3089 vb[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
3092 va[0].format = VK_FORMAT_R32G32B32_SFLOAT;
3097 vb[1].stride =
sizeof(float) * 3;
3098 vb[1].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
3101 va[1].format = VK_FORMAT_R32G32B32_SFLOAT;
3106 vb[2].stride =
sizeof(float) * 2;
3107 vb[2].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
3110 va[2].format = VK_FORMAT_R32G32_SFLOAT;
3115 vb[3].stride =
sizeof(float) * 4;
3116 vb[3].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
3119 va[3].format = VK_FORMAT_R32G32B32A32_SFLOAT;
3122 vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
3124 vi.vertexBindingDescriptionCount = vb.size();
3125 vi.pVertexBindingDescriptions = vb.data();
3126 vi.vertexAttributeDescriptionCount = va.size();
3127 vi.pVertexAttributeDescriptions = va.data();
3129 pipeline.pVertexInputState = &vi;
3130 pipeline.pInputAssemblyState = &ia;
3131 pipeline.pRasterizationState = &rs;
3132 pipeline.pColorBlendState = haveColorBuffer ==
true || haveGeometryBuffer ==
true?&cb:
nullptr;
3133 pipeline.pMultisampleState = &ms;
3134 pipeline.pViewportState = &vp;
3135 pipeline.pDepthStencilState = haveDepthBuffer ==
true?&ds:
nullptr;
3136 pipeline.pStages = shaderStages.data();
3137 pipeline.renderPass = usedRenderPass;
3138 pipeline.pDynamicState = &dsc;
3140 pipelineCacheCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
3141 err = vkCreatePipelineCache(
device, &pipelineCacheCreateInfo,
nullptr, &pipelineCache);
3144 err = vkCreateGraphicsPipelines(
device, pipelineCache, 1, &pipeline,
nullptr, &framebufferPipelines->pipelines[currentContext.pipelineIdx]);
3148 vkDestroyPipelineCache(
device, pipelineCache,
nullptr);
3152 auto& currentContext =
contexts[contextIdx];
3153 if (currentContext.pipelineIdx ==
ID_NONE || currentContext.pipeline == VK_NULL_HANDLE) {
3157 if (pipeline == VK_NULL_HANDLE) {
3164 auto& commandBuffer = currentContext.commandBuffers[currentContext.currentCommandBuffer];
3165 vkCmdBindPipeline(commandBuffer.drawCommand, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
3166 currentContext.pipeline = pipeline;
3176 if (framebufferPipelines ==
nullptr) {
3184 vector<VkDescriptorSetLayoutBinding> layoutBindings1(program->
layoutBindings);
3187 vector<VkPipelineShaderStageCreateInfo> shaderStages(program->
shaders.size());
3190 for (
auto shader: program->
shaders) {
3191 shaderStages[
shaderIdx].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
3192 shaderStages[
shaderIdx].stage = shader->type;
3193 shaderStages[
shaderIdx].module = shader->module;
3196 for (
int i = 0; i <= shader->maxBindings; i++) {
3197 layoutBindings1[i] = {
3198 .binding =
static_cast<uint32_t
>(i),
3199 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
3200 .descriptorCount = 1,
3201 .stageFlags =
static_cast<VkShaderStageFlags
>(shader->type),
3202 .pImmutableSamplers =
nullptr
3206 if (shader->uboBindingIdx != -1) {
3207 layoutBindings1[shader->uboBindingIdx] = {
3208 .binding =
static_cast<uint32_t
>(shader->uboBindingIdx),
3209 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
3210 .descriptorCount = 1,
3211 .stageFlags =
static_cast<VkShaderStageFlags
>(shader->type),
3212 .pImmutableSamplers =
nullptr
3217 const VkDescriptorSetLayoutCreateInfo descriptorSetlayoutCreateInfo = {
3218 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
3222 .pBindings = layoutBindings1.data(),
3229 const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {
3230 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3233 .setLayoutCount = 1,
3239 array<VkDescriptorSetLayout, DESC_MAX_UNCACHED> descriptorSetLayouts1;
3242 VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
3243 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3247 .pSetLayouts = descriptorSetLayouts1.data()
3250 err = vkAllocateDescriptorSets(
device, &descriptorSetAllocateInfo, program->
contexts[context.idx].commandBuffers[i].uboDescriptorSets.data());
3256 err = vkCreatePipelineLayout(
device, &pPipelineLayoutCreateInfo,
nullptr, &program->
pipelineLayout);
3260 VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {
3261 .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
3264 .initialDataSize = 0,
3265 .pInitialData =
nullptr
3267 VkPipelineCache pipelineCache = VK_NULL_HANDLE;
3269 err = vkCreatePipelineCache(
device, &pipelineCacheCreateInfo,
nullptr, &pipelineCache);
3273 VkComputePipelineCreateInfo pipeline = {
3274 .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
3277 .stage = shaderStages[0],
3279 .basePipelineHandle =
nullptr,
3280 .basePipelineIndex = 0
3284 err = vkCreateComputePipelines(
device, pipelineCache, 1, &pipeline,
nullptr, &framebufferPipelines->pipelines[
ID_NONE]);
3288 vkDestroyPipelineCache(
device, pipelineCache,
nullptr);
3295 auto& currentContext =
contexts[contextIdx];
3296 if (currentContext.pipelineIdx ==
ID_NONE || currentContext.pipeline == VK_NULL_HANDLE) {
3302 vkCmdBindPipeline(currentContext.commandBuffers[currentContext.currentCommandBuffer].drawCommand, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
3303 currentContext.pipeline = pipeline;
3309 auto& currentContext =
contexts[contextIdx];
3312 if (currentContext.program !=
nullptr && currentContext.program->id == programId)
return;
3318 currentContext.program =
nullptr;
3321 if (programId ==
ID_NONE)
return;
3324 if (programId < ID_NONE || programId >=
programVector.size()) {
3325 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): program does not exist: " + to_string(programId));
3331 currentContext.program = program;
3336 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
3338 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): could not create program, maximum is " + to_string(
PROGRAMS_MAX));
3342 auto& program = *programPtr;
3343 program.type = type;
3346 for (
auto& programContext: program.contexts) {
3347 programContext.descriptorSets2Idx = 0;
3348 programContext.descriptorSets2.fill(VK_NULL_HANDLE);
3349 for (
auto& programContextCommandBuffer: programContext.commandBuffers) {
3350 programContextCommandBuffer.uboDescriptorSetsIdx = 0;
3351 programContextCommandBuffer.texturesDescriptorSetsIdxUncached = 0;
3352 programContextCommandBuffer.uboDescriptorSets.fill(VK_NULL_HANDLE);
3353 programContextCommandBuffer.texturesDescriptorSetsUncached.fill(VK_NULL_HANDLE);
3357 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): program id: " + to_string(program.id));
3363 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
3364 auto shaderIt =
shaders.find(shaderId);
3365 if (shaderIt ==
shaders.end()) {
3366 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): shader does not exist");
3370 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): program does not exist");
3374 program->shaderIds.push_back(shaderId);
3375 program->shaders.push_back(shaderIt->second);
3380 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(programId));
3382 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): program does not exist");
3393 for (
auto shader: program.shaders) {
3395 if (shader->uboSize > 0) {
3398 auto& uniformBuffer = shader->uniformBuffers[context.idx];
3399 uniformBuffer.size = shader->uboSize;
3400 uniformBuffer.uniformBufferData.resize(shader->uboSize);
3401 for (
auto& uniformBufferBuffer: uniformBuffer.buffers) {
3402 VmaAllocationInfo allocationInfo = {};
3405 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
3406 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
3407 uniformBufferBuffer.buffer,
3408 uniformBufferBuffer.allocation,
3411 VkMemoryPropertyFlags memoryFlags;
3412 vmaGetMemoryTypeProperties(
vmaAllocator, allocationInfo.memoryType, &memoryFlags);
3413 auto memoryMapped = (memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
3414 if (memoryMapped ==
true) {
3416 vmaMapMemory(
vmaAllocator, uniformBufferBuffer.allocation, &mmData);
3418 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): Could not create memory mappable uniform buffer");
3427 for (
auto shader: program.shaders) {
3431 VkShaderModuleCreateInfo shaderModuleCreateInfo;
3432 shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
3433 shaderModuleCreateInfo.pNext =
nullptr;
3434 shaderModuleCreateInfo.codeSize = shader->
spirv.size() *
sizeof(uint32_t);
3435 shaderModuleCreateInfo.pCode = shader->spirv.data();
3436 shaderModuleCreateInfo.flags = 0;
3437 err = vkCreateShaderModule(
device, &shaderModuleCreateInfo,
nullptr, &shader->module);
3438 if (err == VK_SUCCESS) {
3442 string(
"VKRenderer::") +
3443 string(__FUNCTION__) +
3445 to_string(shader->id) +
3454 string(
"VKRenderer::") +
3455 string(__FUNCTION__) +
3457 to_string(shader->id) +
3462 Console::println(shader->source);
3468 shaderLast = shader;
3479 string(
"VKRenderer::") +
3480 string(__FUNCTION__) +
3482 to_string(programId) +
3484 string(
": unknown program: ") +
3485 to_string(program.type)
3495 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + name);
3497 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): program does not exist");
3501 for (
const auto& [uniformLocation, uniformName]: program->uniformLocations) {
3502 if (uniformName == name)
return uniformLocation;
3504 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): uniform not found: '" + name +
"'");
3509 auto& currentContext =
contexts[contextIdx];
3513 for (
auto shader: currentContext.program->shaders) {
3515 if (uniformId < 0 || uniformId >= shader->uniformList.size()) {
3518 string(__FUNCTION__) +
3519 "(): program: uniform id out of uniform list bounds: " +
3520 to_string(currentContext.idx) +
": " +
3521 to_string(currentContext.program->id) +
": " +
3522 to_string(uniformId) +
" / " +
3523 to_string(shader->uniformList.size())
3527 to_string(currentContext.idx) +
": " +
3528 to_string(currentContext.program->id) +
": " +
3529 to_string(uniformId) +
" / " +
3530 currentContext.program->uniformLocations[uniformId]
3534 auto shaderUniformPtr = uniformId != -1?shader->uniformList[uniformId]:
nullptr;
3535 if (shaderUniformPtr ==
nullptr) {
3539 auto& shaderUniform = *shaderUniformPtr;
3593 auto& uniformBuffer = shader->uniformBuffers[contextIdx];
3594 auto remainingSize = size;
3597 auto dst =
static_cast<uint8_t*
>(&uniformBuffer.uniformBufferData[shaderUniform.position]);
3598 while (remainingSize >= 8) {
3599 *(uint64_t*)dst = *(uint64_t*)src;
3604 while (remainingSize >= 4) {
3605 *(uint32_t*)dst = *(uint32_t*)src;
3612 shaderUniform.textureUnit = *((int32_t*)data);
3615 shaderUniform.textureUnit = *((int32_t*)data);
3633 array<float, 12> _data = {
3711 auto& currentContext =
contexts[contextIdx];
3712 if (currentContext.cullingEnabled ==
true)
return;
3714 currentContext.cullingEnabled =
true;
3715 currentContext.frontFaceIndex = currentContext.frontFace;
3720 auto& currentContext =
contexts[contextIdx];
3721 if (currentContext.cullingEnabled ==
false)
return;
3723 currentContext.cullingEnabled =
false;
3724 currentContext.frontFaceIndex = 0;
3729 auto& currentContext =
contexts[contextIdx];
3730 if (currentContext.frontFace == frontFace)
return;
3732 currentContext.frontFace = frontFace;
3733 currentContext.frontFaceIndex = currentContext.cullingEnabled ==
true?frontFace:0;
3740 cullMode = (VkCullModeFlagBits)cullFace;
3804 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
3810 auto attachmentIdx = 0;
3811 array<VkClearAttachment, 9> attachments;
3814 for (
auto i = 0; i < 8; i++) {
3815 attachments[attachmentIdx].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3816 attachments[attachmentIdx].colorAttachment = attachmentIdx;
3822 attachments[attachmentIdx].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
3823 attachments[attachmentIdx].colorAttachment = attachmentIdx;
3830 attachments[attachmentIdx].aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3831 attachments[attachmentIdx].colorAttachment = 0;
3832 attachments[attachmentIdx].clearValue.depthStencil = { 1.0f, 0 };
3835 VkClearRect clearRect = {
3837 .baseArrayLayer = 0,
3840 vkCmdClearAttachments(
3848 auto currentBufferIdx =
contexts[0].currentCommandBuffer;
3850 if (commandBuffer != VK_NULL_HANDLE) {
3858 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
3861 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): could not allocate texture, maximum is " + to_string(
TEXTURES_MAX));
3865 auto reuseTextureId = -1;
3872 auto& texture = *texturePtr;
3873 texture.id = reuseTextureId != -1?reuseTextureId:
textureIdx++;
3881 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(width) +
"x" + to_string(height));
3885 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
3889 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
3896 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): could not allocate texture, maximum is " + to_string(
TEXTURES_MAX));
3900 auto reuseTextureId = -1;
3907 auto& texture = *texturePtr;
3908 texture.id = reuseTextureId != -1?reuseTextureId:
textureIdx++;
3909 texture.bindTexture = texturePtr;
3918 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(textureId) +
" / " + to_string(width) +
"x" + to_string(height));
3922 depthBufferTexture.format = VK_FORMAT_D32_SFLOAT;
3923 depthBufferTexture.width = width;
3924 depthBufferTexture.height = height;
3925 depthBufferTexture.cubemapTextureIndex = cubeMapTextureId ==
ID_NONE?0:cubeMapTextureIndex;
3929 depthBufferTexture.cubemapBufferTexture = cubeMapTexture !=
nullptr?cubeMapTexture->cubemapDepthBuffer:
nullptr;
3935 if (cubeMapTexture ==
nullptr) {
3939 depthBufferTexture.image,
3940 depthBufferTexture.allocation,
3941 depthBufferTexture.view,
3942 depthBufferTexture.sampler
3947 const VkImageCreateInfo imageCreateInfo = {
3948 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3951 .imageType = VK_IMAGE_TYPE_2D,
3952 .format = depthBufferTexture.format,
3954 .width = depthBufferTexture.width,
3955 .height = depthBufferTexture.height,
3960 .samples = VK_SAMPLE_COUNT_1_BIT,
3961 .tiling = VK_IMAGE_TILING_OPTIMAL,
3962 .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
3963 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
3964 .queueFamilyIndexCount = 0,
3965 .pQueueFamilyIndices = 0,
3966 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
3969 VmaAllocationCreateInfo allocationCreateInfo = {};
3970 allocationCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
3972 VmaAllocationInfo allocationInfo = {};
3973 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &allocationCreateInfo, &depthBufferTexture.image, &depthBufferTexture.allocation, &allocationInfo);
3978 depthBufferTexture.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
3979 depthBufferTexture.accessTypes = { THSVS_ACCESS_NONE, THSVS_ACCESS_NONE };
3980 depthBufferTexture.svsLayout = THSVS_IMAGE_LAYOUT_OPTIMAL;
3981 depthBufferTexture.vkLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3985 const VkSamplerCreateInfo samplerCreateInfo = {
3986 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
3989 .magFilter = VK_FILTER_NEAREST,
3990 .minFilter = VK_FILTER_NEAREST,
3991 .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
3992 .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
3993 .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
3994 .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
3996 .anisotropyEnable = VK_FALSE,
3998 .compareEnable = VK_FALSE,
3999 .compareOp = VK_COMPARE_OP_NEVER,
4002 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
4003 .unnormalizedCoordinates = VK_FALSE,
4005 err = vkCreateSampler(
device, &samplerCreateInfo,
nullptr, &depthBufferTexture.sampler);
4011 VkImageViewCreateInfo viewCreateInfo = {
4012 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4015 .image = cubeMapTexture !=
nullptr?cubeMapTexture->cubemapDepthBuffer->image:depthBufferTexture.image,
4016 .viewType = VK_IMAGE_VIEW_TYPE_2D,
4017 .format = depthBufferTexture.format,
4018 .components = VkComponentMapping(),
4019 .subresourceRange = {
4020 .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
4023 .baseArrayLayer = cubeMapTexture !=
nullptr?
static_cast<uint32_t
>(cubeMapTextureIndex -
CUBEMAPTEXTUREINDEX_MIN):0,
4027 err = vkCreateImageView(
device, &viewCreateInfo,
nullptr, &depthBufferTexture.view);
4033 &depthBufferTexture,
4034 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4035 THSVS_IMAGE_LAYOUT_OPTIMAL,
4044 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(width) +
"x" + to_string(height));
4048 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
4052 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
4059 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): could not allocate texture, maximum is " + to_string(
TEXTURES_MAX));
4063 auto reuseTextureId = -1;
4070 auto& texture = *texturePtr;
4071 texture.id = reuseTextureId != -1?reuseTextureId:
textureIdx++;
4072 texture.bindTexture = texturePtr;
4081 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(textureId) +
" / " + to_string(width) +
"x" + to_string(height) +
"(" + to_string(cubeMapTextureId) +
" / " + to_string(cubeMapTextureIndex) +
")");
4083 colorBufferTexture.format = format;
4084 colorBufferTexture.width = width;
4085 colorBufferTexture.height = height;
4086 colorBufferTexture.cubemapTextureIndex = cubeMapTextureId ==
ID_NONE?0:cubeMapTextureIndex;
4091 colorBufferTexture.cubemapBufferTexture = cubeMapTexture !=
nullptr?cubeMapTexture->cubemapColorBuffer:
nullptr;
4097 if (cubeMapTexture ==
nullptr) {
4101 colorBufferTexture.image,
4102 colorBufferTexture.allocation,
4103 colorBufferTexture.view,
4104 colorBufferTexture.sampler
4109 const VkImageCreateInfo imageCreateInfo = {
4110 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
4113 .imageType = VK_IMAGE_TYPE_2D,
4114 .format = colorBufferTexture.format,
4116 .width = colorBufferTexture.width,
4117 .height = colorBufferTexture.height,
4122 .samples = VK_SAMPLE_COUNT_1_BIT,
4123 .tiling = VK_IMAGE_TILING_OPTIMAL,
4124 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4125 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
4126 .queueFamilyIndexCount = 0,
4127 .pQueueFamilyIndices = 0,
4128 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
4131 VmaAllocationCreateInfo allocationCreateInfo = {};
4132 allocationCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
4134 VmaAllocationInfo allocationInfo = {};
4135 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &allocationCreateInfo, &colorBufferTexture.image, &colorBufferTexture.allocation, &allocationInfo);
4140 colorBufferTexture.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4141 colorBufferTexture.accessTypes = { THSVS_ACCESS_NONE, THSVS_ACCESS_NONE };
4142 colorBufferTexture.svsLayout = THSVS_IMAGE_LAYOUT_OPTIMAL;
4143 colorBufferTexture.vkLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4147 const VkSamplerCreateInfo samplerCreateInfo = {
4148 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4151 .magFilter = VK_FILTER_LINEAR,
4152 .minFilter = VK_FILTER_LINEAR,
4153 .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
4154 .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4155 .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4156 .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4158 .anisotropyEnable = VK_FALSE,
4160 .compareEnable = VK_FALSE,
4161 .compareOp = VK_COMPARE_OP_NEVER,
4164 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
4165 .unnormalizedCoordinates = VK_FALSE,
4167 err = vkCreateSampler(
device, &samplerCreateInfo,
nullptr, &colorBufferTexture.sampler);
4173 VkImageViewCreateInfo viewCreateInfo = {
4174 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4177 .image = cubeMapTexture !=
nullptr?cubeMapTexture->cubemapColorBuffer->image:colorBufferTexture.image,
4178 .viewType = VK_IMAGE_VIEW_TYPE_2D,
4179 .format = colorBufferTexture.format,
4181 .r = VK_COMPONENT_SWIZZLE_R,
4182 .g = VK_COMPONENT_SWIZZLE_G,
4183 .b = VK_COMPONENT_SWIZZLE_B,
4184 .a = VK_COMPONENT_SWIZZLE_A,
4186 .subresourceRange = {
4187 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4190 .baseArrayLayer = cubeMapTexture !=
nullptr?
static_cast<uint32_t
>(cubeMapTextureIndex -
CUBEMAPTEXTUREINDEX_MIN):0,
4194 err = vkCreateImageView(
device, &viewCreateInfo,
nullptr, &colorBufferTexture.view);
4200 &colorBufferTexture,
4201 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4202 THSVS_IMAGE_LAYOUT_OPTIMAL,
4211 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(width) +
"x" + to_string(height));
4215 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
4219 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
4226 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): could not allocate texture, maximum is " + to_string(
TEXTURES_MAX));
4230 auto reuseTextureId = -1;
4237 auto& texture = *texturePtr;
4238 texture.id = reuseTextureId != -1?reuseTextureId:
textureIdx++;
4239 texture.bindTexture = texturePtr;
4247 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(width) +
"x" + to_string(height));
4251 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
4255 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
4262 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): could not allocate texture, maximum is " + to_string(
TEXTURES_MAX));
4266 auto reuseTextureId = -1;
4273 auto& texture = *texturePtr;
4274 texture.id = reuseTextureId != -1?reuseTextureId:
textureIdx++;
4275 texture.bindTexture = texturePtr;
4285 "VKRenderer::" +
string(__FUNCTION__) +
"(): " +
4286 textureLeft->
getId() +
" / " +
4287 textureRight->
getId() +
" / " +
4288 textureTop->
getId() +
" / " +
4289 textureBottom->
getId() +
" / " +
4290 textureFront->
getId() +
" / " +
4291 textureBack->
getId()
4296 auto& currentContext =
contexts[contextIdx];
4297 auto& boundTexture = currentContext.boundTextures[currentContext.activeTextureUnit];
4301 if (textureObjectPtr ==
nullptr) {
4302 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): texture not found: " + to_string(boundTexture.id));
4305 auto& texture = *textureObjectPtr;
4327 VK_FORMAT_BC7_UNORM_BLOCK:
4328 VK_FORMAT_R8G8B8A8_UNORM;
4329 texture.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4330 texture.accessTypes = { THSVS_ACCESS_HOST_PREINITIALIZED, THSVS_ACCESS_NONE };
4331 texture.vkLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
4334 const VkImageCreateInfo imageCreateInfo = {
4335 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
4337 .flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
4338 .imageType = VK_IMAGE_TYPE_2D,
4339 .format = texture.format,
4341 .width = texture.width,
4342 .height = texture.height,
4347 .samples = VK_SAMPLE_COUNT_1_BIT,
4348 .tiling = VK_IMAGE_TILING_OPTIMAL,
4349 .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4350 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
4351 .queueFamilyIndexCount = 0,
4352 .pQueueFamilyIndices = 0,
4353 .initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED,
4359 VmaAllocationCreateInfo allocationCreateInfo = {};
4360 allocationCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
4362 VmaAllocationInfo allocationInfo = {};
4363 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &allocationCreateInfo, &texture.image, &texture.allocation, &allocationInfo);
4378 { THSVS_ACCESS_TRANSFER_WRITE, THSVS_ACCESS_NONE },
4379 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4380 THSVS_IMAGE_LAYOUT_OPTIMAL,
4381 THSVS_IMAGE_LAYOUT_OPTIMAL,
4389 texture.accessTypes =
4391 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4392 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4393 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4394 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4395 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4396 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE }
4400 const VkSamplerCreateInfo samplerCreateInfo = {
4401 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4404 .magFilter = VK_FILTER_LINEAR,
4405 .minFilter = VK_FILTER_LINEAR,
4406 .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
4407 .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4408 .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4409 .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4411 .anisotropyEnable = VK_FALSE,
4413 .compareEnable = VK_FALSE,
4414 .compareOp = VK_COMPARE_OP_NEVER,
4417 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
4418 .unnormalizedCoordinates = VK_FALSE,
4420 err = vkCreateSampler(
device, &samplerCreateInfo,
nullptr, &texture.sampler);
4424 VkImageViewCreateInfo viewCreateInfo = {
4425 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4428 .image = texture.image,
4429 .viewType = VK_IMAGE_VIEW_TYPE_CUBE,
4430 .format = texture.format,
4432 .r = VK_COMPONENT_SWIZZLE_R,
4433 .g = VK_COMPONENT_SWIZZLE_G,
4434 .b = VK_COMPONENT_SWIZZLE_B,
4435 .a = VK_COMPONENT_SWIZZLE_A,
4437 .subresourceRange = {
4438 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4441 .baseArrayLayer = 0,
4445 err = vkCreateImageView(
device, &viewCreateInfo,
nullptr, &texture.view);
4449 boundTexture.sampler = texture.sampler;
4450 boundTexture.view = texture.view;
4451 boundTexture.layout = texture.vkLayout;
4454 texture.uploaded =
true;
4455 texture.bindTexture = &texture;
4458 currentContext.uploadedTextureIds.insert(texture.id);
4462 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(width) +
"x" + to_string(height));
4465 auto& currentContext =
contexts[contextIdx];
4469 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
4473 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
4480 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): could not allocate texture, maximum is " + to_string(
TEXTURES_MAX));
4484 auto reuseTextureId = -1;
4491 auto& texture = *texturePtr;
4492 texture.id = reuseTextureId != -1?reuseTextureId:
textureIdx++;
4495 texture.width = width;
4496 texture.height = height;
4497 texture.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4498 texture.vkLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4505 texture.cubemapColorBuffer->id = -1;
4508 texture.cubemapColorBuffer->width = width;
4509 texture.cubemapColorBuffer->height = height;
4510 texture.cubemapColorBuffer->aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4511 texture.cubemapColorBuffer->vkLayout = VK_IMAGE_LAYOUT_UNDEFINED;
4512 const VkImageCreateInfo imageCreateInfo = {
4513 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
4515 .flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
4516 .imageType = VK_IMAGE_TYPE_2D,
4517 .format = texture.cubemapColorBuffer->format,
4519 .width = texture.cubemapColorBuffer->width,
4520 .height = texture.cubemapColorBuffer->height,
4525 .samples = VK_SAMPLE_COUNT_1_BIT,
4526 .tiling = VK_IMAGE_TILING_OPTIMAL,
4527 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
4528 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
4529 .queueFamilyIndexCount = 0,
4530 .pQueueFamilyIndices = 0,
4531 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
4537 VmaAllocationCreateInfo allocationCreateInfo = {};
4538 allocationCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
4540 VmaAllocationInfo allocationInfo = {};
4541 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &allocationCreateInfo, &texture.cubemapColorBuffer->image, &texture.cubemapColorBuffer->allocation, &allocationInfo);
4545 const VkSamplerCreateInfo samplerCreateInfo = {
4546 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4549 .magFilter = VK_FILTER_LINEAR,
4550 .minFilter = VK_FILTER_LINEAR,
4551 .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
4552 .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4553 .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4554 .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
4556 .anisotropyEnable = VK_FALSE,
4558 .compareEnable = VK_FALSE,
4559 .compareOp = VK_COMPARE_OP_NEVER,
4562 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
4563 .unnormalizedCoordinates = VK_FALSE,
4565 err = vkCreateSampler(
device, &samplerCreateInfo,
nullptr, &texture.sampler);
4569 VkImageViewCreateInfo viewCreateInfo = {
4570 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
4573 .image = texture.cubemapColorBuffer->image,
4574 .viewType = VK_IMAGE_VIEW_TYPE_CUBE,
4575 .format = texture.cubemapColorBuffer->format,
4577 .r = VK_COMPONENT_SWIZZLE_R,
4578 .g = VK_COMPONENT_SWIZZLE_G,
4579 .b = VK_COMPONENT_SWIZZLE_B,
4580 .a = VK_COMPONENT_SWIZZLE_A,
4582 .subresourceRange = {
4583 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4586 .baseArrayLayer = 0,
4590 err = vkCreateImageView(
device, &viewCreateInfo,
nullptr, &texture.view);
4597 texture.cubemapColorBuffer,
4598 { THSVS_ACCESS_NONE, THSVS_ACCESS_NONE },
4599 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4600 THSVS_IMAGE_LAYOUT_OPTIMAL,
4601 THSVS_IMAGE_LAYOUT_OPTIMAL,
4613 texture.cubemapDepthBuffer->id = -1;
4614 texture.cubemapDepthBuffer->format = VK_FORMAT_D32_SFLOAT;
4615 texture.cubemapDepthBuffer->width = width;
4616 texture.cubemapDepthBuffer->height = height;
4618 texture.cubemapDepthBuffer->aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
4619 const VkImageCreateInfo imageCreateInfo = {
4620 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
4622 .flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
4623 .imageType = VK_IMAGE_TYPE_2D,
4624 .format = texture.cubemapDepthBuffer->format,
4626 .width = texture.cubemapDepthBuffer->width,
4627 .height = texture.cubemapDepthBuffer->height,
4632 .samples = VK_SAMPLE_COUNT_1_BIT,
4633 .tiling = VK_IMAGE_TILING_OPTIMAL,
4634 .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
4635 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
4636 .queueFamilyIndexCount = 0,
4637 .pQueueFamilyIndices = 0,
4638 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
4644 VmaAllocationCreateInfo allocationCreateInfo = {};
4645 allocationCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
4647 VmaAllocationInfo allocation_info = {};
4648 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &allocationCreateInfo, &texture.cubemapDepthBuffer->image, &texture.cubemapDepthBuffer->allocation, &allocation_info);
4654 texture.cubemapDepthBuffer,
4655 { THSVS_ACCESS_NONE, THSVS_ACCESS_NONE },
4656 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4657 THSVS_IMAGE_LAYOUT_OPTIMAL,
4658 THSVS_IMAGE_LAYOUT_OPTIMAL,
4669 texture.vkLayout = texture.cubemapColorBuffer->vkLayout;
4681 auto& currentContext =
contexts[contextIdx];
4682 auto& boundTexture = currentContext.boundTextures[currentContext.activeTextureUnit];
4686 if (textureObjectPtr ==
nullptr) {
4688 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): texture not found: " + to_string(boundTexture.id));
4691 auto& textureType = *textureObjectPtr;
4706 textureType.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4712 VkFormatProperties textureFormatProperties;
4714 vkGetPhysicalDeviceFormatProperties(
physicalDevice, textureFormat, &textureFormatProperties);
4717 vector<delete_image_type> deleteStagingImages;
4728 VK_IMAGE_TILING_OPTIMAL,
4729 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
4730 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
4732 { THSVS_ACCESS_TRANSFER_WRITE, THSVS_ACCESS_NONE },
4733 THSVS_IMAGE_LAYOUT_OPTIMAL,
4742 VkBuffer buffer { VK_NULL_HANDLE };
4743 VmaAllocation allocation { VK_NULL_HANDLE };
4744 VmaAllocationInfo allocationInfo = {};
4745 createBuffer(bc7TextureData.getCapacity(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, buffer, allocation, allocationInfo);
4748 vmaMemCpy(allocation, bc7TextureData.getBuffer(), bc7TextureData.getCapacity());
4750 VkBufferImageCopy bufferImageCopy = {
4752 .bufferRowLength = 0,
4753 .bufferImageHeight = 0,
4754 .imageSubresource = {
4755 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4757 .baseArrayLayer = 0,
4766 .width = textureType.width,
4767 .height = textureType.height,
4775 vkCmdCopyBufferToImage(
4776 currentContext.setupCommandInUse,
4779 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4786 vmaFlushAllocation(
vmaAllocator, allocation, 0, VK_WHOLE_SIZE);
4797 for (
const auto& textureMipMap: textureMipMaps) {
4799 auto& bc7TextureData = textureMipMap.textureData;
4800 VkBuffer buffer { VK_NULL_HANDLE };
4801 VmaAllocation allocation { VK_NULL_HANDLE };
4802 VmaAllocationInfo allocationInfo = {};
4803 createBuffer(bc7TextureData.getCapacity(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, buffer, allocation, allocationInfo);
4806 vmaMemCpy(allocation, bc7TextureData.getBuffer(), bc7TextureData.getCapacity());
4808 VkBufferImageCopy bufferImageCopy = {
4810 .bufferRowLength = 0,
4811 .bufferImageHeight = 0,
4812 .imageSubresource = {
4813 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4814 .mipLevel =
static_cast<uint32_t
>(level),
4815 .baseArrayLayer = 0,
4824 .width = textureMipMap.width,
4825 .height = textureMipMap.height,
4833 vkCmdCopyBufferToImage(
4834 currentContext.setupCommandInUse,
4837 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4844 vmaFlushAllocation(
vmaAllocator, allocation, 0, VK_WHOLE_SIZE);
4857 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
4858 THSVS_IMAGE_LAYOUT_OPTIMAL,
4865 if ((textureFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) {
4871 stagingTexture.
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4877 VK_IMAGE_TILING_LINEAR,
4878 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4879 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
4881 { THSVS_ACCESS_TRANSFER_READ, THSVS_ACCESS_NONE },
4882 THSVS_IMAGE_LAYOUT_OPTIMAL
4888 VK_IMAGE_TILING_OPTIMAL,
4889 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
4890 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
4892 { THSVS_ACCESS_TRANSFER_WRITE, THSVS_ACCESS_NONE },
4893 THSVS_IMAGE_LAYOUT_OPTIMAL,
4899 VkImageCopy imageCopy = {
4901 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4903 .baseArrayLayer = 0,
4912 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4914 .baseArrayLayer = 0,
4923 .width = textureType.width,
4924 .height = textureType.height,
4931 currentContext.setupCommandInUse,
4932 stagingTexture.
image,
4933 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4935 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4941 deleteStagingImages.emplace_back(
4942 stagingTexture.
image,
4952 for (
const auto& textureMipMap: textureMipMaps) {
4955 mipMapStagingTexture.
width = textureMipMap.width;
4956 mipMapStagingTexture.
height = textureMipMap.height;
4958 mipMapStagingTexture.
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
4963 &mipMapStagingTexture,
4964 VK_IMAGE_TILING_LINEAR,
4965 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4966 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
4969 { THSVS_ACCESS_TRANSFER_READ, THSVS_ACCESS_NONE },
4970 THSVS_IMAGE_LAYOUT_OPTIMAL
4974 VkImageCopy imageCopy = {
4976 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4978 .baseArrayLayer = 0,
4987 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
4988 .mipLevel =
static_cast<uint32_t
>(level),
4989 .baseArrayLayer = 0,
4998 .width = mipMapStagingTexture.
width,
4999 .height = mipMapStagingTexture.
height,
5005 currentContext.setupCommandInUse,
5006 mipMapStagingTexture.
image,
5007 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5009 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5015 deleteStagingImages.emplace_back(
5016 mipMapStagingTexture.
image,
5030 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
5031 THSVS_IMAGE_LAYOUT_OPTIMAL,
5040 for (
auto& deleteStagingImage: deleteStagingImages) {
5042 deleteStagingImage.image,
5043 deleteStagingImage.allocation,
5050 if ((textureFormatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) {
5056 VK_IMAGE_TILING_LINEAR,
5057 VK_IMAGE_USAGE_SAMPLED_BIT,
5058 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
5060 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
5061 THSVS_IMAGE_LAYOUT_OPTIMAL
5066 VkSamplerMipmapMode mipmapMode;
5087 const VkSamplerCreateInfo samplerCreateInfo = {
5088 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
5091 .magFilter = minFilter,
5092 .minFilter = magFilter,
5093 .mipmapMode = mipmapMode,
5098 .anisotropyEnable = VK_FALSE,
5100 .compareEnable = VK_FALSE,
5101 .compareOp = VK_COMPARE_OP_NEVER,
5103 .maxLod = texture->
isUseMipMap() ==
true?
static_cast<float>(mipLevels):0.0f,
5104 .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
5105 .unnormalizedCoordinates = VK_FALSE,
5107 VkImageViewCreateInfo viewCreateInfo = {
5108 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
5111 .image = textureType.image,
5112 .viewType = VK_IMAGE_VIEW_TYPE_2D,
5113 .format = textureFormat,
5115 .r = VK_COMPONENT_SWIZZLE_R,
5116 .g = VK_COMPONENT_SWIZZLE_G,
5117 .b = VK_COMPONENT_SWIZZLE_B,
5118 .a = VK_COMPONENT_SWIZZLE_A,
5120 .subresourceRange = {
5121 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
5123 .levelCount =
static_cast<uint32_t
>(mipLevels),
5124 .baseArrayLayer = 0,
5130 err = vkCreateSampler(
device, &samplerCreateInfo,
nullptr, &textureType.sampler);
5134 err = vkCreateImageView(
device, &viewCreateInfo,
nullptr, &textureType.view);
5138 boundTexture.sampler = textureType.sampler;
5139 boundTexture.view = textureType.view;
5140 boundTexture.layout = textureType.vkLayout;
5143 textureType.uploaded =
true;
5144 textureType.bindTexture = textureObjectPtr;
5147 currentContext.uploadedTextureIds.insert(textureType.id);
5155 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + texture->
getId());
5158 auto& currentContext =
contexts[contextIdx];
5159 auto& cubemapTextureTypeRef = *cubemapTextureType;
5165 VkFormatProperties textureFormatProperties;
5167 vkGetPhysicalDeviceFormatProperties(
physicalDevice, textureFormat, &textureFormatProperties);
5174 &cubemapTextureTypeRef,
5175 { THSVS_ACCESS_HOST_PREINITIALIZED, THSVS_ACCESS_NONE },
5176 { THSVS_ACCESS_TRANSFER_WRITE, THSVS_ACCESS_NONE },
5177 THSVS_IMAGE_LAYOUT_OPTIMAL,
5178 THSVS_IMAGE_LAYOUT_OPTIMAL,
5189 VkBuffer buffer { VK_NULL_HANDLE };
5190 VmaAllocation allocation { VK_NULL_HANDLE };
5191 VmaAllocationInfo allocationInfo = {};
5192 createBuffer(bc7TextureData.getCapacity(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, buffer, allocation, allocationInfo);
5195 vmaMemCpy(allocation, bc7TextureData.getBuffer(), bc7TextureData.getCapacity());
5197 VkBufferImageCopy bufferImageCopy = {
5199 .bufferRowLength = 0,
5200 .bufferImageHeight = 0,
5201 .imageSubresource = {
5202 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
5204 .baseArrayLayer = baseArrayLayer,
5213 .width = cubemapTextureTypeRef.width,
5214 .height = cubemapTextureTypeRef.height,
5222 vkCmdCopyBufferToImage(
5223 currentContext.setupCommandInUse,
5225 cubemapTextureTypeRef.image,
5226 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5233 vmaFlushAllocation(
vmaAllocator, allocation, 0, VK_WHOLE_SIZE);
5237 if ((textureFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) {
5243 staging_texture.
aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
5249 VK_IMAGE_TILING_LINEAR,
5250 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5251 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
5253 { THSVS_ACCESS_TRANSFER_READ, THSVS_ACCESS_NONE },
5254 THSVS_IMAGE_LAYOUT_OPTIMAL
5260 &cubemapTextureTypeRef,
5261 { THSVS_ACCESS_HOST_PREINITIALIZED, THSVS_ACCESS_NONE },
5262 { THSVS_ACCESS_TRANSFER_WRITE, THSVS_ACCESS_NONE },
5263 THSVS_IMAGE_LAYOUT_OPTIMAL,
5264 THSVS_IMAGE_LAYOUT_OPTIMAL,
5274 VkImageCopy imageCopy = {
5276 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
5278 .baseArrayLayer = 0,
5287 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
5289 .baseArrayLayer = baseArrayLayer,
5298 .width = cubemapTextureTypeRef.width,
5299 .height = cubemapTextureTypeRef.height,
5307 currentContext.setupCommandInUse,
5308 staging_texture.
image,
5309 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
5310 cubemapTextureTypeRef.image,
5311 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
5321 staging_texture.
image,
5328 if ((textureFormatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) {
5338 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(textureId) +
" / " + to_string(width) +
"x" + to_string(height));
5347 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
5351 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
5357 if (texturePtr ==
nullptr) {
5358 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): texture not found: " + to_string(textureId));
5363 auto& texture = *texturePtr;
5364 if (texture.width == width && texture.height == height)
return;
5379 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(textureId) +
" / " + to_string(width) +
"x" + to_string(height));
5388 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
5392 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
5398 if (texturePtr ==
nullptr) {
5399 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): texture not found: " + to_string(textureId));
5404 auto& texture = *texturePtr;
5405 if (texture.width == width && texture.height == height)
return;
5419 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(textureId) +
" / " + to_string(width) +
"x" + to_string(height));
5428 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
5432 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
5438 if (texturePtr ==
nullptr) {
5439 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): texture not found: " + to_string(textureId));
5444 auto& texture = *texturePtr;
5445 if (texture.width == width && texture.height == height)
return;
5459 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(textureId) +
" / " + to_string(width) +
"x" + to_string(height));
5468 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): width: " + to_string(width) +
" <= 0, using 1");
5472 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): height: " + to_string(height) +
" <= 0, using 1");
5478 if (texturePtr ==
nullptr) {
5479 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): texture not found: " + to_string(textureId));
5484 auto& texture = *texturePtr;
5485 if (texture.width == width && texture.height == height)
return;
5506 auto& currentContext =
contexts[contextIdx];
5507 auto& boundTexture = currentContext.boundTextures[currentContext.activeTextureUnit];
5513 boundTexture.id = textureId;
5514 if (textureObject !=
nullptr) {
5515 boundTexture.sampler = textureObject->sampler;
5516 boundTexture.view = textureObject->view;
5517 boundTexture.layout = textureObject->vkLayout;
5519 boundTexture.sampler = VK_NULL_HANDLE;
5520 boundTexture.view = VK_NULL_HANDLE;
5521 boundTexture.layout = VK_IMAGE_LAYOUT_UNDEFINED;
5537 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(frameBufferId));
5539 if (frameBuffer ==
nullptr) {
5540 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): frame buffer not found: " + to_string(frameBufferId));
5543 auto& frameBufferStruct = *frameBuffer;
5550 if (depthBufferTexture ==
nullptr) {
5551 if (frameBufferStruct.depthTextureId !=
ID_NONE) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): color buffer: depth buffer texture not found: " + to_string(frameBufferStruct.depthTextureId));
5553 if (colorBufferTexture ==
nullptr) {
5554 if (frameBufferStruct.colorTextureId !=
ID_NONE) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): color buffer: color buffer texture not found: " + to_string(frameBufferStruct.colorTextureId));
5558 if (depthBufferTexture !=
nullptr) {
5563 if (colorBufferTexture !=
nullptr) {
5570 if (depthBufferTexture !=
nullptr && colorBufferTexture !=
nullptr &&
5571 (depthBufferTexture->
width != colorBufferTexture->
width ||
5572 depthBufferTexture->
height != colorBufferTexture->
height)) {
5573 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): color buffer: attachments with different dimension found: Not creating!");
5582 if (frameBufferStruct.renderPass != VK_NULL_HANDLE) vkDestroyRenderPass(
device, frameBufferStruct.renderPass,
nullptr);
5584 auto attachmentIdx = 0;
5585 array<VkAttachmentDescription, 2> attachments;
5586 if (colorBufferTexture !=
nullptr) {
5587 attachments[attachmentIdx++] = {
5589 .format = colorBufferTexture->
format,
5590 .samples = VK_SAMPLE_COUNT_1_BIT,
5591 .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5592 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
5593 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5594 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
5595 .initialLayout = colorBufferTexture->
vkLayout == VK_IMAGE_LAYOUT_GENERAL?VK_IMAGE_LAYOUT_GENERAL:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5596 .finalLayout = colorBufferTexture->
vkLayout == VK_IMAGE_LAYOUT_GENERAL?VK_IMAGE_LAYOUT_GENERAL:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5599 if (depthBufferTexture !=
nullptr) {
5600 attachments[attachmentIdx++] = {
5602 .format = depthBufferTexture->
format,
5603 .samples = VK_SAMPLE_COUNT_1_BIT,
5604 .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5605 .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
5606 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5607 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
5608 .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5609 .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5612 const VkAttachmentReference colorReference = {
5614 .layout = colorBufferTexture !=
nullptr?(colorBufferTexture->
vkLayout == VK_IMAGE_LAYOUT_GENERAL?VK_IMAGE_LAYOUT_GENERAL:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL):VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5616 const VkAttachmentReference depthReference = {
5617 .attachment =
static_cast<uint32_t
>(colorBufferTexture !=
nullptr?1:0),
5618 .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5620 const VkSubpassDescription subpassDescription = {
5622 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
5623 .inputAttachmentCount = 0,
5624 .pInputAttachments =
nullptr,
5625 .colorAttachmentCount =
static_cast<uint32_t
>(colorBufferTexture !=
nullptr?1:0),
5626 .pColorAttachments = colorBufferTexture !=
nullptr?&colorReference:
nullptr,
5627 .pResolveAttachments =
nullptr,
5628 .pDepthStencilAttachment = depthBufferTexture !=
nullptr?&depthReference:
nullptr,
5629 .preserveAttachmentCount = 0,
5630 .pPreserveAttachments =
nullptr
5632 const VkRenderPassCreateInfo renderPassCreateInfo = {
5633 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
5636 .attachmentCount =
static_cast<uint32_t
>(attachmentIdx),
5637 .pAttachments = attachments.data(),
5639 .pSubpasses = &subpassDescription,
5640 .dependencyCount = 0,
5641 .pDependencies =
nullptr
5643 err = vkCreateRenderPass(
device, &renderPassCreateInfo,
nullptr, &frameBufferStruct.renderPass);
5649 if (frameBufferStruct.frameBuffer != VK_NULL_HANDLE) vkDestroyFramebuffer(
device, frameBufferStruct.frameBuffer,
nullptr);
5650 auto attachmentIdx = 0;
5651 array<VkImageView, 2> attachments;
5652 if (colorBufferTexture !=
nullptr) attachments[attachmentIdx++] = colorBufferTexture->
view;
5653 if (depthBufferTexture !=
nullptr) attachments[attachmentIdx++] = depthBufferTexture->
view;
5654 const VkFramebufferCreateInfo fb_info = {
5655 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
5658 .renderPass = frameBufferStruct.renderPass,
5659 .attachmentCount =
static_cast<uint32_t
>(attachmentIdx),
5660 .pAttachments = attachments.data(),
5661 .width = colorBufferTexture !=
nullptr?colorBufferTexture->
width:depthBufferTexture->
width,
5662 .height = colorBufferTexture !=
nullptr?colorBufferTexture->
height:depthBufferTexture->
height,
5665 err = vkCreateFramebuffer(
device, &fb_info,
nullptr, &frameBufferStruct.frameBuffer);
5671 auto geometryBufferTexture1 =
getTextureInternal(frameBufferStruct.gbufferGeometryBufferTextureId1);
5672 auto geometryBufferTexture2 =
getTextureInternal(frameBufferStruct.gbufferGeometryBufferTextureId2);
5673 auto geometryBufferTexture3 =
getTextureInternal(frameBufferStruct.gbufferGeometryBufferTextureId3);
5674 auto colorBufferTexture1 =
getTextureInternal(frameBufferStruct.gbufferColorBufferTextureId1);
5675 auto colorBufferTexture2 =
getTextureInternal(frameBufferStruct.gbufferColorBufferTextureId2);
5676 auto colorBufferTexture3 =
getTextureInternal(frameBufferStruct.gbufferColorBufferTextureId3);
5677 auto colorBufferTexture4 =
getTextureInternal(frameBufferStruct.gbufferColorBufferTextureId4);
5678 auto colorBufferTexture5 =
getTextureInternal(frameBufferStruct.gbufferColorBufferTextureId5);
5680 depthBufferTexture->frameBufferBindImageLayoutChange.valid =
false;
5681 depthBufferTexture->frameBufferUnbindImageLayoutChange.valid =
false;
5682 geometryBufferTexture1->frameBufferBindImageLayoutChange.valid =
false;
5683 geometryBufferTexture1->frameBufferUnbindImageLayoutChange.valid =
false;
5684 geometryBufferTexture2->frameBufferBindImageLayoutChange.valid =
false;
5685 geometryBufferTexture2->frameBufferUnbindImageLayoutChange.valid =
false;
5686 geometryBufferTexture3->frameBufferBindImageLayoutChange.valid =
false;
5687 geometryBufferTexture3->frameBufferUnbindImageLayoutChange.valid =
false;
5688 colorBufferTexture1->frameBufferBindImageLayoutChange.valid =
false;
5689 colorBufferTexture1->frameBufferUnbindImageLayoutChange.valid =
false;
5690 colorBufferTexture2->frameBufferBindImageLayoutChange.valid =
false;
5691 colorBufferTexture2->frameBufferUnbindImageLayoutChange.valid =
false;
5692 colorBufferTexture3->frameBufferBindImageLayoutChange.valid =
false;
5693 colorBufferTexture3->frameBufferUnbindImageLayoutChange.valid =
false;
5694 colorBufferTexture4->frameBufferBindImageLayoutChange.valid =
false;
5695 colorBufferTexture4->frameBufferUnbindImageLayoutChange.valid =
false;
5696 colorBufferTexture5->frameBufferBindImageLayoutChange.valid =
false;
5697 colorBufferTexture5->frameBufferUnbindImageLayoutChange.valid =
false;
5700 depthBufferTexture->frameBufferObjectId = frameBufferStruct.id;
5701 geometryBufferTexture1->frameBufferObjectId = frameBufferStruct.id;
5702 geometryBufferTexture2->frameBufferObjectId = frameBufferStruct.id;
5703 geometryBufferTexture3->frameBufferObjectId = frameBufferStruct.id;
5704 colorBufferTexture1->frameBufferObjectId = frameBufferStruct.id;
5705 colorBufferTexture2->frameBufferObjectId = frameBufferStruct.id;
5706 colorBufferTexture3->frameBufferObjectId = frameBufferStruct.id;
5707 colorBufferTexture4->frameBufferObjectId = frameBufferStruct.id;
5708 colorBufferTexture5->frameBufferObjectId = frameBufferStruct.id;
5711 if (depthBufferTexture->width == 0 || depthBufferTexture->height == 0 ||
5712 depthBufferTexture->width != geometryBufferTexture1->width || depthBufferTexture->height != geometryBufferTexture1->height ||
5713 depthBufferTexture->width != geometryBufferTexture2->width || depthBufferTexture->height != geometryBufferTexture2->height ||
5714 depthBufferTexture->width != geometryBufferTexture3->width || depthBufferTexture->height != geometryBufferTexture3->height ||
5715 depthBufferTexture->width != colorBufferTexture1->width || depthBufferTexture->height != colorBufferTexture1->height ||
5716 depthBufferTexture->width != colorBufferTexture2->width || depthBufferTexture->height != colorBufferTexture2->height ||
5717 depthBufferTexture->width != colorBufferTexture3->width || depthBufferTexture->height != colorBufferTexture3->height ||
5718 depthBufferTexture->width != colorBufferTexture4->width || depthBufferTexture->height != colorBufferTexture4->height ||
5719 depthBufferTexture->width != colorBufferTexture5->width || depthBufferTexture->height != colorBufferTexture5->height) {
5720 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): geometry buffer: attachments with different dimension found: Not creating!");
5725 array<texture_type*, 8> colorBufferTextures = {
5726 geometryBufferTexture1,
5727 geometryBufferTexture2,
5728 geometryBufferTexture3,
5729 colorBufferTexture1,
5730 colorBufferTexture2,
5731 colorBufferTexture3,
5732 colorBufferTexture4,
5741 if (frameBufferStruct.renderPass != VK_NULL_HANDLE) vkDestroyRenderPass(
device, frameBufferStruct.renderPass,
nullptr);
5744 auto attachmentIdx = 0;
5745 array<VkAttachmentDescription, 9> attachments;
5746 for (
auto colorBufferTexture: colorBufferTextures) {
5747 attachments[attachmentIdx++] = {
5749 .format = colorBufferTexture->format,
5750 .samples = VK_SAMPLE_COUNT_1_BIT,
5751 .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5752 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
5753 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5754 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
5755 .initialLayout = colorBufferTexture->vkLayout == VK_IMAGE_LAYOUT_GENERAL?VK_IMAGE_LAYOUT_GENERAL:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5756 .finalLayout = colorBufferTexture->vkLayout == VK_IMAGE_LAYOUT_GENERAL?VK_IMAGE_LAYOUT_GENERAL:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
5759 attachments[attachmentIdx++] = {
5761 .format = depthBufferTexture->format,
5762 .samples = VK_SAMPLE_COUNT_1_BIT,
5763 .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5764 .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
5765 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
5766 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE,
5767 .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5768 .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
5770 array<VkAttachmentReference, 8> colorReferences;
5773 for (
auto colorBufferTexture: colorBufferTextures) {
5774 colorReferences[i] = {
5775 .attachment =
static_cast<uint32_t
>(i),
5776 .layout = colorBufferTexture->vkLayout == VK_IMAGE_LAYOUT_GENERAL?VK_IMAGE_LAYOUT_GENERAL:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
5781 const VkAttachmentReference depthReference = {
5783 .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
5785 const VkSubpassDescription subpassDescription = {
5787 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
5788 .inputAttachmentCount = 0,
5789 .pInputAttachments =
nullptr,
5790 .colorAttachmentCount = 8,
5791 .pColorAttachments = colorReferences.data(),
5792 .pResolveAttachments =
nullptr,
5793 .pDepthStencilAttachment = &depthReference,
5794 .preserveAttachmentCount = 0,
5795 .pPreserveAttachments =
nullptr
5797 const VkRenderPassCreateInfo renderPassCreateInfo = {
5798 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
5801 .attachmentCount =
static_cast<uint32_t
>(attachmentIdx),
5802 .pAttachments = attachments.data(),
5804 .pSubpasses = &subpassDescription,
5805 .dependencyCount = 0,
5806 .pDependencies =
nullptr
5808 err = vkCreateRenderPass(
device, &renderPassCreateInfo,
nullptr, &frameBufferStruct.renderPass);
5814 if (frameBufferStruct.frameBuffer != VK_NULL_HANDLE) vkDestroyFramebuffer(
device, frameBufferStruct.frameBuffer,
nullptr);
5815 auto attachmentIdx = 0;
5816 array<VkImageView, 9> attachments;
5817 for (
auto colorBufferTexture: colorBufferTextures) {
5818 attachments[attachmentIdx++] = colorBufferTexture->view;
5820 attachments[attachmentIdx++] = depthBufferTexture->view;
5821 const VkFramebufferCreateInfo frameBufferCreateInfo = {
5822 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
5825 .renderPass = frameBufferStruct.renderPass,
5826 .attachmentCount =
static_cast<uint32_t
>(attachmentIdx),
5827 .pAttachments = attachments.data(),
5828 .width = depthBufferTexture->width,
5829 .height = depthBufferTexture->height,
5832 err = vkCreateFramebuffer(
device, &frameBufferCreateInfo,
nullptr, &frameBufferStruct.frameBuffer);
5840 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(depthBufferTextureId) +
", " + to_string(colorBufferTextureId) +
" / " + to_string(cubeMapTextureId) +
" / " + to_string(cubeMapTextureIndex));
5843 auto reuseIndex = -1;
5853 auto& frameBuffer = *frameBufferPtr;
5854 frameBuffer.id = reuseIndex != -1?reuseIndex:
framebuffers.size();
5856 frameBuffer.depthTextureId = depthBufferTextureId;
5857 frameBuffer.colorTextureId = colorBufferTextureId;
5858 frameBuffer.cubemapTextureId = cubeMapTextureId;
5859 frameBuffer.cubemapTextureIndex = cubeMapTextureIndex;
5860 if (cubeMapTextureId !=
ID_NONE) {
5862 if (cubeMapTexture ==
nullptr) {
5863 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): missing cube map texture with id: " + to_string(cubeMapTextureId));
5865 cubeMapTexture->bindTexture = cubeMapTexture;
5870 if (reuseIndex != -1) {
5878 return frameBuffer.id;
5882 int32_t depthBufferTextureId,
5883 int32_t geometryBufferTextureId1,
5884 int32_t geometryBufferTextureId2,
5885 int32_t geometryBufferTextureId3,
5886 int32_t colorBufferTextureId1,
5887 int32_t colorBufferTextureId2,
5888 int32_t colorBufferTextureId3,
5889 int32_t colorBufferTextureId4,
5890 int32_t colorBufferTextureId5
5894 "VKRenderer::" +
string(__FUNCTION__) +
"(): " +
5895 to_string(depthBufferTextureId) +
", " +
5896 to_string(geometryBufferTextureId1) +
", " +
5897 to_string(geometryBufferTextureId2) +
", " +
5898 to_string(geometryBufferTextureId3) +
", " +
5899 to_string(colorBufferTextureId1) +
", " +
5900 to_string(colorBufferTextureId2) +
", " +
5901 to_string(colorBufferTextureId3) +
", " +
5902 to_string(colorBufferTextureId4) +
", " +
5903 to_string(colorBufferTextureId5)
5908 auto reuseIndex = -1;
5918 auto& frameBuffer = *frameBufferPtr;
5919 frameBuffer.id = reuseIndex != -1?reuseIndex:
framebuffers.size();
5921 frameBuffer.depthTextureId = depthBufferTextureId;
5922 frameBuffer.gbufferGeometryBufferTextureId1 = geometryBufferTextureId1;
5923 frameBuffer.gbufferGeometryBufferTextureId2 = geometryBufferTextureId2;
5924 frameBuffer.gbufferGeometryBufferTextureId3 = geometryBufferTextureId3;
5925 frameBuffer.gbufferColorBufferTextureId1 = colorBufferTextureId1;
5926 frameBuffer.gbufferColorBufferTextureId2 = colorBufferTextureId2;
5927 frameBuffer.gbufferColorBufferTextureId3 = colorBufferTextureId3;
5928 frameBuffer.gbufferColorBufferTextureId4 = colorBufferTextureId4;
5929 frameBuffer.gbufferColorBufferTextureId5 = colorBufferTextureId5;
5932 if (reuseIndex != -1) {
5940 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): new geometry frame buffer: " + to_string(frameBuffer.id));
5941 return frameBuffer.id;
5947 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(
boundFrameBufferId) +
" --> " + to_string(frameBufferId));
5961 if (frameBuffer ==
nullptr) {
5962 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): framebuffer not found: " + to_string(
boundFrameBufferId));
5965 auto depthBufferTextureId = frameBuffer->depthTextureId;
5966 if (depthBufferTextureId !=
ID_NONE) {
5967 auto& depthBufferTexture = *
textures[depthBufferTextureId];
5968 if (depthBufferTexture.frameBufferUnbindImageLayoutChange.valid ==
false) {
5970 depthBufferTexture.frameBufferUnbindImageLayoutChange,
5971 &depthBufferTexture,
5972 { THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ, THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE },
5973 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
5974 THSVS_IMAGE_LAYOUT_OPTIMAL,
5975 THSVS_IMAGE_LAYOUT_OPTIMAL,
5981 applyImageLayoutChange(0, depthBufferTexture.frameBufferUnbindImageLayoutChange, &depthBufferTexture,
false);
5983 auto colorBufferTextureId = frameBuffer->colorTextureId;
5984 if (colorBufferTextureId !=
ID_NONE) {
5985 auto& colorBufferTexture = *
textures[colorBufferTextureId];
5986 if (colorBufferTexture.frameBufferUnbindImageLayoutChange.valid ==
false) {
5988 colorBufferTexture.frameBufferUnbindImageLayoutChange,
5989 &colorBufferTexture,
5990 { THSVS_ACCESS_COLOR_ATTACHMENT_READ, THSVS_ACCESS_COLOR_ATTACHMENT_WRITE},
5991 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
5992 THSVS_IMAGE_LAYOUT_OPTIMAL,
5993 THSVS_IMAGE_LAYOUT_OPTIMAL,
5999 applyImageLayoutChange(0, colorBufferTexture.frameBufferUnbindImageLayoutChange, &colorBufferTexture,
false);
6001 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(frameBufferId) +
": color buffer: unbinding: " + to_string(colorBufferTextureId) +
" / " + to_string(depthBufferTextureId));
6004 auto depthBufferTextureId = frameBuffer->depthTextureId;
6005 auto colorBufferTextureId1 = frameBuffer->gbufferColorBufferTextureId1;
6006 auto colorBufferTextureId2 = frameBuffer->gbufferColorBufferTextureId2;
6007 auto colorBufferTextureId3 = frameBuffer->gbufferColorBufferTextureId3;
6008 auto colorBufferTextureId4 = frameBuffer->gbufferColorBufferTextureId4;
6009 auto colorBufferTextureId5 = frameBuffer->gbufferColorBufferTextureId5;
6010 if (depthBufferTextureId !=
ID_NONE) {
6011 auto& depthBufferTexture = *
textures[depthBufferTextureId];
6012 if (depthBufferTexture.frameBufferUnbindImageLayoutChange.valid ==
false) {
6014 depthBufferTexture.frameBufferUnbindImageLayoutChange,
6015 &depthBufferTexture,
6016 { THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ, THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE },
6017 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
6018 THSVS_IMAGE_LAYOUT_OPTIMAL,
6019 THSVS_IMAGE_LAYOUT_OPTIMAL,
6025 applyImageLayoutChange(0, depthBufferTexture.frameBufferUnbindImageLayoutChange, &depthBufferTexture,
false);
6027 array<texture_type*, 8> colorBufferTextures = {
6028 textures[frameBuffer->gbufferGeometryBufferTextureId1],
6029 textures[frameBuffer->gbufferGeometryBufferTextureId2],
6030 textures[frameBuffer->gbufferGeometryBufferTextureId3],
6031 textures[frameBuffer->gbufferColorBufferTextureId1],
6032 textures[frameBuffer->gbufferColorBufferTextureId2],
6033 textures[frameBuffer->gbufferColorBufferTextureId3],
6034 textures[frameBuffer->gbufferColorBufferTextureId4],
6035 textures[frameBuffer->gbufferColorBufferTextureId5]
6037 array<image_layout_change, 8> colorBufferTexturesImageLayoutChanges;
6039 for (
auto colorBufferTexture: colorBufferTextures) {
6040 if (colorBufferTexture->frameBufferUnbindImageLayoutChange.valid ==
false) {
6042 colorBufferTexture->frameBufferUnbindImageLayoutChange,
6044 { THSVS_ACCESS_COLOR_ATTACHMENT_READ, THSVS_ACCESS_COLOR_ATTACHMENT_WRITE},
6045 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
6046 THSVS_IMAGE_LAYOUT_OPTIMAL,
6047 THSVS_IMAGE_LAYOUT_OPTIMAL,
6053 colorBufferTexturesImageLayoutChanges[i++] = colorBufferTexture->frameBufferUnbindImageLayoutChange;
6056 if (
VERBOSE ==
true) Console::println(
6057 "VKRenderer::" +
string(__FUNCTION__) +
"(): " +
6058 to_string(frameBufferId) +
6059 ": geometry buffer: unbinding: " +
6060 to_string(depthBufferTextureId) +
", " +
6061 to_string(colorBufferTextures[0]->
id) +
", " +
6062 to_string(colorBufferTextures[1]->
id) +
", " +
6063 to_string(colorBufferTextures[2]->
id) +
", " +
6064 to_string(colorBufferTextures[3]->
id) +
", " +
6065 to_string(colorBufferTextures[4]->
id) +
", " +
6066 to_string(colorBufferTextures[5]->
id) +
", " +
6067 to_string(colorBufferTextures[6]->
id) +
", " +
6068 to_string(colorBufferTextures[7]->
id)
6075 if (frameBufferId !=
ID_NONE) {
6077 if (frameBuffer ==
nullptr) {
6078 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): framebuffer not found: " + to_string(frameBufferId));
6087 if (frameBuffer ==
nullptr) {
6088 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): framebuffer not found: " + to_string(
boundFrameBufferId));
6091 auto depthBufferTextureId = frameBuffer->depthTextureId;
6092 auto colorBufferTextureId = frameBuffer->colorTextureId;
6093 if (depthBufferTextureId !=
ID_NONE) {
6094 auto& depthBufferTexture = *
textures[depthBufferTextureId];
6095 if (depthBufferTexture.frameBufferBindImageLayoutChange.valid ==
false) {
6097 depthBufferTexture.frameBufferBindImageLayoutChange,
6098 &depthBufferTexture,
6099 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
6100 { THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ, THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE },
6101 THSVS_IMAGE_LAYOUT_OPTIMAL,
6102 THSVS_IMAGE_LAYOUT_OPTIMAL,
6108 applyImageLayoutChange(0, depthBufferTexture.frameBufferBindImageLayoutChange, &depthBufferTexture,
false);
6110 if (colorBufferTextureId !=
ID_NONE) {
6111 auto& colorBufferTexture = *
textures[colorBufferTextureId];
6112 if (colorBufferTexture.frameBufferBindImageLayoutChange.valid ==
false) {
6114 colorBufferTexture.frameBufferBindImageLayoutChange,
6115 &colorBufferTexture,
6116 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
6117 { THSVS_ACCESS_COLOR_ATTACHMENT_READ, THSVS_ACCESS_COLOR_ATTACHMENT_WRITE},
6118 THSVS_IMAGE_LAYOUT_OPTIMAL,
6119 THSVS_IMAGE_LAYOUT_OPTIMAL,
6125 applyImageLayoutChange(0, colorBufferTexture.frameBufferBindImageLayoutChange, &colorBufferTexture,
false);
6127 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(frameBufferId) +
": binding: " + to_string(colorBufferTextureId) +
" / " + to_string(depthBufferTextureId));
6130 auto depthBufferTextureId = frameBuffer->depthTextureId;
6131 auto colorBufferTextureId1 = frameBuffer->gbufferColorBufferTextureId1;
6132 auto colorBufferTextureId2 = frameBuffer->gbufferColorBufferTextureId2;
6133 auto colorBufferTextureId3 = frameBuffer->gbufferColorBufferTextureId3;
6134 auto colorBufferTextureId4 = frameBuffer->gbufferColorBufferTextureId4;
6135 auto colorBufferTextureId5 = frameBuffer->gbufferColorBufferTextureId5;
6136 if (depthBufferTextureId !=
ID_NONE) {
6137 auto& depthBufferTexture = *
textures[depthBufferTextureId];
6138 if (depthBufferTexture.frameBufferBindImageLayoutChange.valid ==
false) {
6140 depthBufferTexture.frameBufferBindImageLayoutChange,
6141 &depthBufferTexture,
6142 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
6143 { THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ, THSVS_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE },
6144 THSVS_IMAGE_LAYOUT_OPTIMAL,
6145 THSVS_IMAGE_LAYOUT_OPTIMAL,
6151 applyImageLayoutChange(0, depthBufferTexture.frameBufferBindImageLayoutChange, &depthBufferTexture,
false);
6153 array<texture_type*, 8> colorBufferTextures = {
6154 textures[frameBuffer->gbufferGeometryBufferTextureId1],
6155 textures[frameBuffer->gbufferGeometryBufferTextureId2],
6156 textures[frameBuffer->gbufferGeometryBufferTextureId3],
6157 textures[frameBuffer->gbufferColorBufferTextureId1],
6158 textures[frameBuffer->gbufferColorBufferTextureId2],
6159 textures[frameBuffer->gbufferColorBufferTextureId3],
6160 textures[frameBuffer->gbufferColorBufferTextureId4],
6161 textures[frameBuffer->gbufferColorBufferTextureId5]
6163 array<image_layout_change, 8> colorBufferTexturesImageLayoutChanges;
6165 for (
auto colorBufferTexture: colorBufferTextures) {
6166 if (colorBufferTexture->frameBufferBindImageLayoutChange.valid ==
false) {
6168 colorBufferTexture->frameBufferBindImageLayoutChange,
6170 { THSVS_ACCESS_FRAGMENT_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, THSVS_ACCESS_NONE },
6171 { THSVS_ACCESS_COLOR_ATTACHMENT_READ, THSVS_ACCESS_COLOR_ATTACHMENT_WRITE },
6172 THSVS_IMAGE_LAYOUT_OPTIMAL,
6173 THSVS_IMAGE_LAYOUT_OPTIMAL,
6179 colorBufferTexturesImageLayoutChanges[i++] = colorBufferTexture->frameBufferBindImageLayoutChange;
6182 if (
VERBOSE ==
true) Console::println(
6183 "VKRenderer::" +
string(__FUNCTION__) +
"(): " +
6184 to_string(frameBufferId) +
6185 ": geometry buffer: binding: " +
6186 to_string(depthBufferTextureId) +
", " +
6187 to_string(colorBufferTextures[0]->
id) +
", " +
6188 to_string(colorBufferTextures[1]->
id) +
", " +
6189 to_string(colorBufferTextures[2]->
id) +
", " +
6190 to_string(colorBufferTextures[3]->
id) +
", " +
6191 to_string(colorBufferTextures[4]->
id) +
", " +
6192 to_string(colorBufferTextures[5]->
id) +
", " +
6193 to_string(colorBufferTextures[6]->
id) +
", " +
6194 to_string(colorBufferTextures[7]->
id)
6206 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(frameBufferId));
6207 auto frameBuffer = unique_ptr<framebuffer_object_type>(frameBufferId < 1 || frameBufferId >=
framebuffers.size()?
nullptr:
framebuffers[frameBufferId]);
6208 if (frameBuffer ==
nullptr) {
6209 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): framebuffer not found: " + to_string(frameBufferId));
6212 vkDestroyRenderPass(
device, frameBuffer->renderPass,
nullptr);
6213 vkDestroyFramebuffer(
device, frameBuffer->frameBuffer,
nullptr);
6221 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
6222 vector<int32_t> bufferIds;
6225 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): coud not allocate buffer object, maximum is " + to_string(
BUFFERS_MAX));
6229 for (
auto i = 0; i < bufferCount; i++) {
6231 auto& buffer = *bufferPtr;
6232 auto reuseBufferId = -1;
6238 buffer.id = reuseBufferId != -1?reuseBufferId:
bufferIdx++;
6239 buffer.useGPUMemory = useGPUMemory;
6240 buffer.shared = shared;
6241 buffer.frameUsedLast = -1LL;
6242 buffer.frameCleanedLast =
frame;
6244 buffers[buffer.id] = bufferPtr;
6245 bufferIds.push_back(buffer.id);
6254 auto buffer = bufferObject->bindBuffer;
6255 buffer->frameUsedLast =
frame;
6256 size = buffer->size;
6257 return buffer->buffer;
6261 return bufferObjectId > 0 && bufferObjectId <=
BUFFERS_MAX?
buffers[bufferObjectId]:
nullptr;
6264 inline void VKRenderer::createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, VmaAllocation& allocation, VmaAllocationInfo& allocationInfo) {
6268 const VkBufferCreateInfo bufferCreateInfo = {
6269 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
6272 .size =
static_cast<uint32_t
>(size),
6274 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
6275 .queueFamilyIndexCount = 0,
6276 .pQueueFamilyIndices =
nullptr
6279 VmaAllocationCreateInfo allocationCreateInfo = {};
6280 allocationCreateInfo.flags = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT?VMA_ALLOCATION_CREATE_MAPPED_BIT:0;
6281 allocationCreateInfo.usage = VMA_MEMORY_USAGE_UNKNOWN;
6282 allocationCreateInfo.requiredFlags = properties;
6285 err = vmaCreateBuffer(
vmaAllocator, &bufferCreateInfo, &allocationCreateInfo, &buffer, &allocation, &allocationInfo);
6290 if (size == 0)
return;
6293 if (buffer ==
nullptr)
return;
6307 VmaAllocationInfo dstAllocationInfo {};
6308 vmaGetAllocationInfo(
vmaAllocator, allocationDst, &dstAllocationInfo);
6311 auto remainingSize = size;
6312 auto offset = _offset;
6314 auto dst =
static_cast<uint8_t*
>(dstAllocationInfo.pMappedData) + offset;
6315 while (remainingSize >= 8) {
6316 *(uint64_t*)dst = *(uint64_t*)src;
6321 while (remainingSize >= 4) {
6322 *(uint32_t*)dst = *(uint32_t*)src;
6332 if (size == 0)
return;
6343 vector<int> buffersToRemove;
6346 vector<int32_t> buffersToRemove;
6347 for (
const auto& reusableBufferCandidate: buffer->
buffers) {
6348 if (
frame >= reusableBufferCandidate.frameUsedLast + 10) {
6349 if (reusableBufferCandidate.memoryMappable ==
true) vmaUnmapMemory(
vmaAllocator, reusableBufferCandidate.allocation);
6350 vmaDestroyBuffer(
vmaAllocator, reusableBufferCandidate.buffer, reusableBufferCandidate.allocation);
6351 buffersToRemove.push_back(i - buffersToRemove.size());
6355 for (
auto bufferToRemove: buffersToRemove) {
6356 auto it = buffer->
buffers.begin();
6357 for (
auto i = 0; i < bufferToRemove; i++) ++it;
6369 for (
auto& reusableBufferCandidate: buffer->
buffers) {
6381 if (reusableBufferCandidate->
size >= size &&
6383 reusableBuffer = reusableBufferCandidate;
6391 if (reusableBuffer ==
nullptr) {
6392 buffer->
buffers.emplace_back();
6393 reusableBuffer = &buffer->
buffers.back();
6398 if (reusableBuffer->
size == 0) {
6399 VmaAllocationInfo allocationInfo = {};
6400 createBuffer(size, usage, buffer->
useGPUMemory ==
true?VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, reusableBuffer->
buffer, reusableBuffer->
allocation, allocationInfo);
6401 reusableBuffer->
size = size;
6403 VkMemoryPropertyFlags memoryFlags;
6404 vmaGetMemoryTypeProperties(
vmaAllocator, allocationInfo.memoryType, &memoryFlags);
6405 reusableBuffer->
memoryMappable = (memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
6420 VkBuffer stagingBuffer;
6421 VmaAllocation stagingBufferAllocation;
6422 VkDeviceSize stagingBufferAllocationSize;
6423 VmaAllocationInfo stagingBufferAllocationInfo = {};
6424 createBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, stagingBuffer, stagingBufferAllocation, stagingBufferAllocationInfo);
6429 stagingBufferAllocation
6434 vmaMapMemory(
vmaAllocator, stagingBufferAllocation, &mmData);
6437 vmaMemCpy(stagingBufferAllocation, data, size);
6440 VkBufferCopy copyRegion = {
6443 .size =
static_cast<VkDeviceSize
>(size)
6445 vkCmdCopyBuffer(
contexts[contextIdx].setupCommandInUse, stagingBuffer, reusableBuffer->
buffer, 1, ©Region);
6465 uploadBufferObjectInternal(contextIdx, bufferObjectId, size, data->
getBuffer(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
6470 uploadBufferObjectInternal(contextIdx, bufferObjectId, size, data->
getBuffer(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
6475 uploadBufferObjectInternal(contextIdx, bufferObjectId, size, data->
getBuffer(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
6480 uploadBufferObjectInternal(contextIdx, bufferObjectId, size, data->
getBuffer(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT));
6485 uploadBufferObjectInternal(contextIdx, bufferObjectId, size, data->
getBuffer(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT));
6494 if (textureObject ==
nullptr)
return nullptr;
6495 return textureObject->bindTexture;
6505 return framebufferPipelinesCandidate;
6517 framebufferPipelines->pipelines.fill(VK_NULL_HANDLE);
6519 return framebufferPipelines;
6523 auto& currentContext =
contexts[contextIdx];
6527 if (framebufferPipelines ==
nullptr)
return VK_NULL_HANDLE;
6528 return framebufferPipelines->pipelines[pipelineIdx];
6533 auto& currentContext =
contexts[contextIdx];
6534 uint32_t bufferSize = 0;
6540 auto& currentContext =
contexts[contextIdx];
6546 auto& currentContext =
contexts[contextIdx];
6552 auto& currentContext =
contexts[contextIdx];
6558 auto& currentContext =
contexts[contextIdx];
6564 auto& currentContext =
contexts[contextIdx];
6570 auto& currentContext =
contexts[contextIdx];
6576 auto& currentContext =
contexts[contextIdx];
6582 auto& currentContext =
contexts[contextIdx];
6588 auto& currentContext =
contexts[contextIdx];
6594 auto& currentContext =
contexts[contextIdx];
6600 auto& currentContext =
contexts[contextIdx];
6605 auto& currentContext =
contexts[contextIdx];
6610 auto& currentContext =
contexts[contextIdx];
6615 auto& currentContext =
contexts[contextIdx];
6620 auto& currentContext =
contexts[contextIdx];
6630 auto& currentContext =
contexts[contextIdx];
6631 auto& programContext = currentContext.program->contexts[currentContext.idx];
6632 auto& programCommandBuffer = programContext.commandBuffers[currentContext.currentCommandBuffer];
6635 auto uboDescriptorSet = programCommandBuffer.uboDescriptorSets[programCommandBuffer.uboDescriptorSetsIdx];
6636 auto texturesDescriptorSetUncached = programCommandBuffer.texturesDescriptorSetsUncached[programCommandBuffer.texturesDescriptorSetsIdxUncached];
6651 array<uint16_t, 8> textureIds {
6652 static_cast<uint16_t
>(
ID_NONE),
6653 static_cast<uint16_t
>(
ID_NONE),
6654 static_cast<uint16_t
>(
ID_NONE),
6655 static_cast<uint16_t
>(
ID_NONE),
6656 static_cast<uint16_t
>(
ID_NONE),
6657 static_cast<uint16_t
>(
ID_NONE),
6658 static_cast<uint16_t
>(
ID_NONE),
6659 static_cast<uint16_t
>(
ID_NONE)
6665 auto samplerIdx = 0;
6666 for (
auto shader: currentContext.program->shaders) {
6668 for (
auto uniform: shader->samplerUniformList) {
6670 if (uniform->textureUnit == -1) {
6671 textureIds[samplerIdx] =
ID_NONE;
6673 auto& boundTexture = currentContext.boundTextures[uniform->textureUnit];
6674 if (boundTexture.view == VK_NULL_HANDLE) {
6675 textureIds[samplerIdx] =
ID_NONE;
6677 textureIds[samplerIdx] = boundTexture.id;
6685 if (shader->uboBindingIdx == -1) {
6691 auto& uniformBuffer = shader->uniformBuffers[currentContext.idx];
6692 auto& src = uniformBuffer.buffers[uniformBuffer.bufferIdx];
6693 auto uboBuffer = src.buffer;
6694 uniformBuffer.bufferIdx = (uniformBuffer.bufferIdx + 1) % uniformBuffer.buffers.size();
6695 vmaMemCpy(src.allocation, uniformBuffer.uniformBufferData.data(), uniformBuffer.size);
6698 currentContext.descriptorBufferInfos[shader->uboBindingIdx] = {
6699 .buffer = uboBuffer,
6701 .range = shader->uboSize
6705 currentContext.descriptorWriteSets[shader->uboBindingIdx] = {
6706 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
6708 .dstSet = uboDescriptorSet,
6709 .dstBinding =
static_cast<uint32_t
>(shader->uboBindingIdx),
6710 .dstArrayElement = 0,
6711 .descriptorCount = 1,
6712 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
6713 .pImageInfo =
nullptr,
6714 .pBufferInfo = ¤tContext.descriptorBufferInfos[shader->uboBindingIdx],
6715 .pTexelBufferView =
nullptr
6722 samplers = samplerIdx;
6725 tuple<uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t, uint16_t> textureDescriptorSetCacheId = {
6726 textureIds[0], textureIds[1], textureIds[2], textureIds[3],
6727 textureIds[4], textureIds[5], textureIds[6], textureIds[7]
6730 auto& textureDescriptorSetCache = programContext.texturesDescriptorSetsCache;
6731 auto textureDescriptorSetCacheIt = samplers >
TEXTUREDESCRIPTORSET_MAX_TEXTURES?textureDescriptorSetCache.end():textureDescriptorSetCache.find(textureDescriptorSetCacheId);
6732 auto textureDescriptorSetCacheHit = textureDescriptorSetCacheIt != textureDescriptorSetCache.end();
6733 if (textureDescriptorSetCacheHit ==
false) {
6735 auto textureDescriptorSetsIdx = -1;
6736 if (programContext.freeTextureDescriptorSetsIds.empty() ==
false) {
6737 auto freeTextureDescriptorSetsIdsIdx = programContext.freeTextureDescriptorSetsIds.size() - 1;
6738 textureDescriptorSetsIdx = programContext.freeTextureDescriptorSetsIds[freeTextureDescriptorSetsIdsIdx];
6739 programContext.freeTextureDescriptorSetsIds.erase(programContext.freeTextureDescriptorSetsIds.begin() + freeTextureDescriptorSetsIdsIdx);
6741 textureDescriptorSetsIdx = programContext.descriptorSets2Idx++;
6743 texturesDescriptorSetUncached = programContext.descriptorSets2[textureDescriptorSetsIdx];
6744 textureDescriptorSetCache[textureDescriptorSetCacheId] = textureDescriptorSetsIdx;
6745 for (
auto textureId: textureIds) programContext.texturesDescriptorSetsCacheTextureIds[textureId].insert(textureDescriptorSetCacheId);
6747 programCommandBuffer.texturesDescriptorSetsIdxUncached = (programCommandBuffer.texturesDescriptorSetsIdxUncached + 1) % programCommandBuffer.texturesDescriptorSetsUncached.size();
6749 auto samplerIdx = 0;
6750 for (
auto shader: currentContext.program->shaders) {
6752 for (
auto uniform: shader->samplerUniformList) {
6753 if (uniform->textureUnit == -1) {
6754 switch(uniform->type) {
6756 currentContext.descriptorImageInfos[samplerIdx] = {
6763 currentContext.descriptorImageInfos[samplerIdx] = {
6770 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): object command: unknown sampler: " + to_string(uniform->type));
6774 auto& boundTexture = currentContext.boundTextures[uniform->textureUnit];
6775 if (boundTexture.view == VK_NULL_HANDLE) {
6776 switch(uniform->type) {
6778 currentContext.descriptorImageInfos[samplerIdx] = {
6785 currentContext.descriptorImageInfos[samplerIdx] = {
6792 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): object command: unknown sampler: " + to_string(uniform->type));
6796 currentContext.descriptorImageInfos[samplerIdx] = {
6797 .sampler = boundTexture.sampler,
6798 .imageView = boundTexture.view,
6799 .imageLayout = boundTexture.layout
6803 currentContext.descriptorWriteSets[uniform->position] = {
6804 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
6806 .dstSet = texturesDescriptorSetUncached,
6807 .dstBinding =
static_cast<uint32_t
>(uniform->position),
6808 .dstArrayElement = 0,
6809 .descriptorCount = 1,
6810 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
6811 .pImageInfo = ¤tContext.descriptorImageInfos[samplerIdx],
6812 .pBufferInfo = VK_NULL_HANDLE,
6813 .pTexelBufferView = VK_NULL_HANDLE
6819 texturesDescriptorSetUncached = programContext.descriptorSets2[textureDescriptorSetCacheIt->second];
6823 vkUpdateDescriptorSets(
device, textureDescriptorSetCacheHit ==
true?uboIdx:currentContext.program->layoutBindings, currentContext.descriptorWriteSets.data(), 0,
nullptr);
6826 array<VkDescriptorSet, 2> descSets { uboDescriptorSet, texturesDescriptorSetUncached };
6829 auto& drawCommand = currentContext.commandBuffers[currentContext.currentCommandBuffer].drawCommand;
6830 vkCmdBindDescriptorSets(drawCommand, VK_PIPELINE_BIND_POINT_GRAPHICS, currentContext.program->pipelineLayout, 0, descSets.size(), descSets.data(), 0,
nullptr);
6833 if (indicesBuffer != VK_NULL_HANDLE) {
6834 vkCmdBindIndexBuffer(drawCommand, indicesBuffer, 0, VK_INDEX_TYPE_UINT32);
6841 if (indicesBuffer != VK_NULL_HANDLE) {
6842 vkCmdDrawIndexed(drawCommand, triangles * 3, instances, trianglesOffset * 3, 0, 0);
6844 vkCmdDraw(drawCommand, triangles * 3, instances, trianglesOffset * 3, 0);
6848 programCommandBuffer.uboDescriptorSetsIdx = (programCommandBuffer.uboDescriptorSetsIdx + 1) % programCommandBuffer.uboDescriptorSets.size();
6849 currentContext.commandCount++;
6862 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
6875 auto currentBufferIdx = context.currentCommandBuffer;
6877 if (commandBuffer != VK_NULL_HANDLE) {
6886 auto& currentContext =
contexts[contextIdx];
6890 if (currentContext.commandCount >= commandsMax) {
6892 auto currentBufferIdx = currentContext.currentCommandBuffer;
6894 if (commandBuffer != VK_NULL_HANDLE)
submitDrawCommandBuffers(1, &commandBuffer, currentContext.commandBuffers[currentBufferIdx].drawFence);
6895 currentContext.commandCount = 0;
6911 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
6914 auto& currentContext =
contexts[contextIdx];
6915 auto& programContext = currentContext.program->contexts[currentContext.idx];
6916 auto& programCommandBuffer = programContext.commandBuffers[currentContext.currentCommandBuffer];
6919 auto uboDescriptorSet = programCommandBuffer.uboDescriptorSets[programCommandBuffer.uboDescriptorSetsIdx];
6920 auto texturesDescriptorSet = programCommandBuffer.texturesDescriptorSetsUncached[programCommandBuffer.texturesDescriptorSetsIdxUncached];
6934 auto samplerIdx = 0;
6935 for (
auto shader: currentContext.program->shaders) {
6937 for (
auto uniform: shader->samplerUniformList) {
6938 if (uniform->textureUnit == -1) {
6939 switch(uniform->type) {
6941 currentContext.descriptorImageInfos[samplerIdx] = {
6948 currentContext.descriptorImageInfos[samplerIdx] = {
6955 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): object command: unknown sampler: " + to_string(uniform->type));
6959 auto& texture = currentContext.boundTextures[uniform->textureUnit];
6960 if (texture.view == VK_NULL_HANDLE) {
6961 switch(uniform->type) {
6963 currentContext.descriptorImageInfos[samplerIdx] = {
6970 currentContext.descriptorImageInfos[samplerIdx] = {
6977 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): object command: unknown sampler: " + to_string(uniform->type));
6981 currentContext.descriptorImageInfos[samplerIdx] = {
6982 .sampler = texture.sampler,
6983 .imageView = texture.view,
6984 .imageLayout = texture.layout
6988 currentContext.descriptorWriteSets[uniform->position] = {
6989 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
6991 .dstSet = texturesDescriptorSet,
6992 .dstBinding =
static_cast<uint32_t
>(uniform->position),
6993 .dstArrayElement = 0,
6994 .descriptorCount = 1,
6995 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
6996 .pImageInfo = ¤tContext.descriptorImageInfos[samplerIdx],
6997 .pBufferInfo = VK_NULL_HANDLE,
6998 .pTexelBufferView = VK_NULL_HANDLE
7004 if (shader->uboBindingIdx == -1) {
7010 auto& uniformBuffer = shader->uniformBuffers[currentContext.idx];
7011 auto& src = uniformBuffer.buffers[uniformBuffer.bufferIdx];
7012 auto uboBuffer = src.buffer;
7013 uniformBuffer.bufferIdx = (uniformBuffer.bufferIdx + 1) % uniformBuffer.buffers.size();
7014 vmaMemCpy(src.allocation, uniformBuffer.uniformBufferData.data(), uniformBuffer.size);
7017 currentContext.descriptorBufferInfos[shader->uboBindingIdx] = {
7018 .buffer = uboBuffer,
7020 .range = shader->uboSize
7024 currentContext.descriptorWriteSets[shader->uboBindingIdx] = {
7025 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
7027 .dstSet = uboDescriptorSet,
7028 .dstBinding =
static_cast<uint32_t
>(shader->uboBindingIdx),
7029 .dstArrayElement = 0,
7030 .descriptorCount = 1,
7031 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
7032 .pImageInfo =
nullptr,
7033 .pBufferInfo = ¤tContext.descriptorBufferInfos[shader->uboBindingIdx],
7034 .pTexelBufferView =
nullptr
7043 vkUpdateDescriptorSets(
device, currentContext.program->layoutBindings, currentContext.descriptorWriteSets.data(), 0,
nullptr);
7046 auto& drawCommand = currentContext.commandBuffers[currentContext.currentCommandBuffer].drawCommand;
7047 array<VkDescriptorSet, 2> descriptorSets { uboDescriptorSet, texturesDescriptorSet };
7048 vkCmdBindDescriptorSets(drawCommand, VK_PIPELINE_BIND_POINT_GRAPHICS, currentContext.program->pipelineLayout, 0, descriptorSets.size(), descriptorSets.data(), 0,
nullptr);
7049 vkCmdBindVertexBuffers(drawCommand, 0,
POINTS_VERTEX_BUFFER_COUNT, currentContext.boundBuffers.data(), currentContext.boundBufferOffsets.data());
7050 vkCmdDraw(drawCommand, points, 1, pointsOffset, 0);
7053 programCommandBuffer.uboDescriptorSetsIdx = (programCommandBuffer.uboDescriptorSetsIdx + 1) % programCommandBuffer.uboDescriptorSets.size();
7054 programCommandBuffer.texturesDescriptorSetsIdxUncached = (programCommandBuffer.texturesDescriptorSetsIdxUncached + 1) % programCommandBuffer.texturesDescriptorSetsUncached.size();
7055 currentContext.commandCount++;
7072 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
7075 auto& currentContext =
contexts[contextIdx];
7076 auto& programCommandBuffer = currentContext.program->contexts[currentContext.idx].commandBuffers[currentContext.currentCommandBuffer];
7079 auto uboDescriptorSet = programCommandBuffer.uboDescriptorSets[programCommandBuffer.uboDescriptorSetsIdx];
7080 auto textureDescriptorSet = programCommandBuffer.texturesDescriptorSetsUncached[programCommandBuffer.texturesDescriptorSetsIdxUncached];
7094 auto samplerIdx = 0;
7095 for (
auto shader: currentContext.program->shaders) {
7097 for (
auto uniform: shader->samplerUniformList) {
7098 if (uniform->textureUnit == -1) {
7099 switch(uniform->type) {
7101 currentContext.descriptorImageInfos[samplerIdx] = {
7108 currentContext.descriptorImageInfos[samplerIdx] = {
7115 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): object command: unknown sampler: " + to_string(uniform->type));
7119 auto& texture = currentContext.boundTextures[uniform->textureUnit];
7120 if (texture.view == VK_NULL_HANDLE) {
7121 switch(uniform->type) {
7123 currentContext.descriptorImageInfos[samplerIdx] = {
7130 currentContext.descriptorImageInfos[samplerIdx] = {
7137 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): object command: unknown sampler: " + to_string(uniform->type));
7141 currentContext.descriptorImageInfos[samplerIdx] = {
7142 .sampler = texture.sampler,
7143 .imageView = texture.view,
7144 .imageLayout = texture.layout
7148 currentContext.descriptorWriteSets[uniform->position] = {
7149 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
7151 .dstSet = textureDescriptorSet,
7152 .dstBinding =
static_cast<uint32_t
>(uniform->position),
7153 .dstArrayElement = 0,
7154 .descriptorCount = 1,
7155 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
7156 .pImageInfo = ¤tContext.descriptorImageInfos[samplerIdx],
7157 .pBufferInfo = VK_NULL_HANDLE,
7158 .pTexelBufferView = VK_NULL_HANDLE
7164 if (shader->uboBindingIdx == -1) {
7170 auto& uniformBuffer = shader->uniformBuffers[currentContext.idx];
7171 auto& src = uniformBuffer.buffers[uniformBuffer.bufferIdx];
7172 auto uboBuffer = src.buffer;
7173 uniformBuffer.bufferIdx = (uniformBuffer.bufferIdx + 1) % uniformBuffer.buffers.size();
7174 vmaMemCpy(src.allocation, uniformBuffer.uniformBufferData.data(), uniformBuffer.size);
7177 currentContext.descriptorBufferInfos[shader->uboBindingIdx] = {
7178 .buffer = uboBuffer,
7180 .range = shader->uboSize
7184 currentContext.descriptorWriteSets[shader->uboBindingIdx] = {
7185 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
7187 .dstSet = uboDescriptorSet,
7188 .dstBinding =
static_cast<uint32_t
>(shader->uboBindingIdx),
7189 .dstArrayElement = 0,
7190 .descriptorCount = 1,
7191 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
7192 .pImageInfo =
nullptr,
7193 .pBufferInfo = ¤tContext.descriptorBufferInfos[shader->uboBindingIdx],
7194 .pTexelBufferView =
nullptr
7203 vkUpdateDescriptorSets(
device, currentContext.program->layoutBindings, currentContext.descriptorWriteSets.data(), 0,
nullptr);
7206 auto& drawCommand = currentContext.commandBuffers[currentContext.currentCommandBuffer].drawCommand;
7207 array<VkDescriptorSet, 2> descriptorSets { uboDescriptorSet, textureDescriptorSet };
7208 vkCmdBindDescriptorSets(drawCommand, VK_PIPELINE_BIND_POINT_GRAPHICS, currentContext.program->pipelineLayout, 0, descriptorSets.size(), descriptorSets.data(), 0,
nullptr);
7209 vkCmdBindVertexBuffers(drawCommand, 0,
LINES_VERTEX_BUFFER_COUNT, currentContext.boundBuffers.data(), currentContext.boundBufferOffsets.data());
7210 vkCmdSetLineWidth(drawCommand,
lineWidth);
7211 vkCmdDraw(drawCommand, points, 1, pointsOffset, 0);
7214 programCommandBuffer.uboDescriptorSetsIdx = (programCommandBuffer.uboDescriptorSetsIdx + 1) % programCommandBuffer.uboDescriptorSets.size();
7215 programCommandBuffer.texturesDescriptorSetsIdxUncached = (programCommandBuffer.texturesDescriptorSetsIdxUncached + 1) % programCommandBuffer.texturesDescriptorSetsUncached.size();
7216 currentContext.commandCount++;
7228 auto& currentContext =
contexts[contextIdx];
7229 uint32_t bufferSize = 0;
7231 currentContext.boundIndicesBuffer = VK_NULL_HANDLE;
7232 currentContext.boundBuffers.fill(defaultBuffer);
7233 currentContext.boundBufferSizes.fill(bufferSize);
7239 for (
auto bufferObjectId: bufferObjectIds) {
7247 return contexts[contextIdx].activeTextureUnit;
7252 contexts[contextIdx].activeTextureUnit = textureUnit;
7257 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
7260 auto pixelDepth = -1.0f;
7263 VkFormat usedFormat = VK_FORMAT_UNDEFINED;
7264 VkImage usedImage = VK_NULL_HANDLE;
7265 uint32_t usedWidth = 0;
7266 uint32_t usedHeight = -1;
7267 array<ThsvsAccessType, 2> usedAccessTypes;
7268 ThsvsImageLayout usedImageLayout = THSVS_IMAGE_LAYOUT_OPTIMAL;
7270 if (frameBuffer ==
nullptr) {
7272 if (depthBufferTexture ==
nullptr) {
7273 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): depth buffer: depth buffer texture not found: " + to_string(
depthBufferDefault));
7276 usedFormat = depthBufferTexture->format;
7277 usedImage = depthBufferTexture->image;
7278 usedWidth = depthBufferTexture->width;
7279 usedHeight = depthBufferTexture->height;
7280 usedAccessTypes = depthBufferTexture->accessTypes[0];
7281 usedImageLayout = depthBufferTexture->svsLayout;
7284 if (depthBufferTexture ==
nullptr) {
7285 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): depth buffer: depth buffer texture not found: " + to_string(frameBuffer->depthBufferTextureId));
7288 usedFormat = depthBufferTexture->format;
7289 usedImage = depthBufferTexture->image;
7290 usedWidth = depthBufferTexture->width;
7291 usedHeight = depthBufferTexture->height;
7292 usedAccessTypes = depthBufferTexture->accessTypes[0];
7293 usedImageLayout = depthBufferTexture->svsLayout;
7301 VmaAllocationInfo allocationInfo = {};
7302 VkBuffer buffer = VK_NULL_HANDLE;
7303 VmaAllocation allocation = VK_NULL_HANDLE;
7306 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
7307 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
7312 VkMemoryPropertyFlags memoryFlags;
7313 vmaGetMemoryTypeProperties(
vmaAllocator, allocationInfo.memoryType, &memoryFlags);
7314 auto memoryMapped = (memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
7315 if (memoryMapped ==
false) {
7317 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): Could not create memory mappable buffer");
7325 array<ThsvsAccessType, 2> nextAccessTypes = { THSVS_ACCESS_TRANSFER_READ, THSVS_ACCESS_NONE };
7326 setImageLayout3(currentContext.idx, usedImage, VK_IMAGE_ASPECT_DEPTH_BIT, usedAccessTypes, nextAccessTypes, usedImageLayout, THSVS_IMAGE_LAYOUT_OPTIMAL);
7329 VkBufferImageCopy bufferImageCopy = {
7331 .bufferRowLength = 0,
7332 .bufferImageHeight = 0,
7333 .imageSubresource = {
7334 .aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
7336 .baseArrayLayer = 0,
7340 .x =
static_cast<int32_t
>(x),
7341 .y =
static_cast<int32_t
>(usedHeight - 1 - y),
7353 vkCmdCopyImageToBuffer(
7354 currentContext.setupCommandInUse,
7356 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7368 pixelDepth =
static_cast<float*
>(data)[0];
7376 array<ThsvsAccessType, 2> lastAccessTypes = { THSVS_ACCESS_TRANSFER_READ, THSVS_ACCESS_NONE };
7377 setImageLayout3(currentContext.idx, usedImage, VK_IMAGE_ASPECT_DEPTH_BIT, lastAccessTypes, usedAccessTypes, THSVS_IMAGE_LAYOUT_OPTIMAL, usedImageLayout);
7389 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(pixelDepth));
7397 if (
VERBOSE ==
true) Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"()");
7400 VkFormat usedFormat = VK_FORMAT_UNDEFINED;
7401 VkImage usedImage = VK_NULL_HANDLE;
7402 uint32_t usedWidth = 0;
7403 uint32_t usedHeight = -1;
7404 array<ThsvsAccessType, 2> usedAccessTypes;
7405 ThsvsImageLayout usedImageLayout = THSVS_IMAGE_LAYOUT_OPTIMAL;
7407 if (frameBuffer ==
nullptr) {
7410 usedImage = swapchainBuffer.image;
7411 usedWidth = swapchainBuffer.width;
7412 usedHeight = swapchainBuffer.height;
7413 usedAccessTypes = swapchainBuffer.accessTypes;
7414 usedImageLayout = swapchainBuffer.svsLayout;
7417 if (colorBufferTexture ==
nullptr) {
7418 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): color buffer: color buffer texture not found: " + to_string(frameBuffer->colorTextureId));
7421 usedFormat = colorBufferTexture->format;
7422 usedImage = colorBufferTexture->image;
7423 usedWidth = colorBufferTexture->width;
7424 usedHeight = colorBufferTexture->height;
7425 usedAccessTypes = colorBufferTexture->accessTypes[0];
7426 usedImageLayout = colorBufferTexture->svsLayout;
7431 VkImage image = VK_NULL_HANDLE;
7432 VmaAllocation allocation = VK_NULL_HANDLE;
7435 const VkImageCreateInfo imageCreateInfo = {
7436 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
7439 .imageType = VK_IMAGE_TYPE_2D,
7440 .format = usedFormat,
7442 .width =
static_cast<uint32_t
>(width),
7443 .height =
static_cast<uint32_t
>(height),
7448 .samples = VK_SAMPLE_COUNT_1_BIT,
7449 .tiling = VK_IMAGE_TILING_LINEAR,
7450 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
7451 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
7452 .queueFamilyIndexCount = 0,
7453 .pQueueFamilyIndices = 0,
7454 .initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED
7457 VmaAllocationCreateInfo imageAllocCreateInfo = {};
7458 imageAllocCreateInfo.usage = VMA_MEMORY_USAGE_UNKNOWN;
7459 imageAllocCreateInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
7461 VmaAllocationInfo allocationInfo = {};
7464 err = vmaCreateImage(
vmaAllocator, &imageCreateInfo, &imageAllocCreateInfo, &image, &allocation, &allocationInfo);
7467 VkImageCopy imageCopy = {
7469 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
7471 .baseArrayLayer = 0,
7480 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
7482 .baseArrayLayer = 0,
7491 .width =
static_cast<uint32_t
>(width),
7492 .height =
static_cast<uint32_t
>(height),
7499 array<ThsvsAccessType, 2> nextAccessTypes = { THSVS_ACCESS_TRANSFER_READ, THSVS_ACCESS_NONE };
7500 setImageLayout3(currentContext.idx, usedImage, VK_IMAGE_ASPECT_COLOR_BIT, usedAccessTypes, nextAccessTypes, usedImageLayout, THSVS_IMAGE_LAYOUT_OPTIMAL);
7504 array<ThsvsAccessType, 2> accessTypes = { THSVS_ACCESS_HOST_PREINITIALIZED, THSVS_ACCESS_NONE };
7505 array<ThsvsAccessType, 2> nextAccessTypes = { THSVS_ACCESS_TRANSFER_WRITE, THSVS_ACCESS_NONE };
7506 setImageLayout3(currentContext.idx, image, VK_IMAGE_ASPECT_COLOR_BIT, accessTypes, nextAccessTypes, THSVS_IMAGE_LAYOUT_OPTIMAL, THSVS_IMAGE_LAYOUT_OPTIMAL);
7511 currentContext.setupCommandInUse,
7513 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7515 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7521 const VkImageSubresource imageSubResource = {
7522 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
7526 VkSubresourceLayout subResourceLayout;
7527 vkGetImageSubresourceLayout(
device, image, &imageSubResource, &subResourceLayout);
7536 auto pixelBuffer = ByteBuffer::allocate(width * height * 4);
7537 for (
int y = height - 1; y >= 0; y--) {
7538 auto row =
static_cast<uint8_t*
>(
static_cast<uint8_t*
>(data) + subResourceLayout.offset + subResourceLayout.rowPitch * y);
7539 for (
auto x = 0; x < width; x++) {
7540 pixelBuffer->put(
static_cast<uint8_t
>(row[x * 4 + 2]));
7541 pixelBuffer->put(
static_cast<uint8_t
>(row[x * 4 + 1]));
7542 pixelBuffer->put(
static_cast<uint8_t
>(row[x * 4 + 0]));
7543 pixelBuffer->put(
static_cast<uint8_t
>(row[x * 4 + 3]));
7553 array<ThsvsAccessType, 2> lastAccessTypes = { THSVS_ACCESS_TRANSFER_READ, THSVS_ACCESS_NONE };
7554 setImageLayout3(currentContext.idx, usedImage, VK_IMAGE_ASPECT_COLOR_BIT, lastAccessTypes, usedAccessTypes, THSVS_IMAGE_LAYOUT_OPTIMAL, usedImageLayout);
7589 auto& currentContext =
contexts[contextIdx];
7590 auto& programCommandBuffer = currentContext.program->contexts[currentContext.idx].commandBuffers[currentContext.currentCommandBuffer];
7593 auto uboDescriptorSet = programCommandBuffer.uboDescriptorSets[programCommandBuffer.uboDescriptorSetsIdx];
7604 for (
auto shader: currentContext.program->shaders) {
7605 for (
int i = 0; i <= shader->maxBindings; i++) {
7606 currentContext.descriptorBufferInfos[i] = {
7607 .buffer = currentContext.boundBuffers[i],
7609 .range = currentContext.boundBufferSizes[i]
7611 currentContext.descriptorWriteSets[i] = {
7612 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
7614 .dstSet = uboDescriptorSet,
7615 .dstBinding =
static_cast<uint32_t
>(i),
7616 .dstArrayElement = 0,
7617 .descriptorCount = 1,
7618 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
7619 .pImageInfo =
nullptr,
7620 .pBufferInfo = ¤tContext.descriptorBufferInfos[i],
7621 .pTexelBufferView =
nullptr
7626 if (shader->uboBindingIdx == -1) {
7633 auto& uniformBuffer = shader->uniformBuffers[currentContext.idx];
7634 auto& src = uniformBuffer.buffers[uniformBuffer.bufferIdx];
7635 auto uboBuffer = src.buffer;
7636 uniformBuffer.bufferIdx = (uniformBuffer.bufferIdx + 1) % uniformBuffer.buffers.size();
7637 vmaMemCpy(src.allocation, uniformBuffer.uniformBufferData.data(), uniformBuffer.size);
7640 currentContext.descriptorBufferInfos[shader->uboBindingIdx] = {
7641 .buffer = uboBuffer,
7643 .range = shader->uboSize
7647 currentContext.descriptorWriteSets[shader->uboBindingIdx] = {
7648 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
7650 .dstSet = uboDescriptorSet,
7651 .dstBinding =
static_cast<uint32_t
>(shader->uboBindingIdx),
7652 .dstArrayElement = 0,
7653 .descriptorCount = 1,
7654 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
7655 .pImageInfo =
nullptr,
7656 .pBufferInfo = ¤tContext.descriptorBufferInfos[shader->uboBindingIdx],
7657 .pTexelBufferView =
nullptr,
7665 vkUpdateDescriptorSets(
device, currentContext.program->layoutBindings, currentContext.descriptorWriteSets.data(), 0,
nullptr);
7668 auto& drawCommand = currentContext.commandBuffers[currentContext.currentCommandBuffer].drawCommand;
7669 vkCmdBindDescriptorSets(drawCommand, VK_PIPELINE_BIND_POINT_COMPUTE, currentContext.program->pipelineLayout, 0, 1, &uboDescriptorSet, 0,
nullptr);
7670 vkCmdDispatch(drawCommand, numGroupsX, numGroupsY, numGroupsZ);
7673 programCommandBuffer.uboDescriptorSetsIdx = (programCommandBuffer.uboDescriptorSetsIdx + 1) % programCommandBuffer.uboDescriptorSets.size();
7674 currentContext.commandCount++;
7688 VkResult fenceResult;
7691 }
while (fenceResult == VK_TIMEOUT);
7694 for (
auto& context:
contexts) context.computeRenderBarrierBuffers.clear();
7705 auto prevAccesses = THSVS_ACCESS_COMPUTE_SHADER_WRITE;
7706 auto nextAccesses = THSVS_ACCESS_VERTEX_BUFFER;
7708 for (
auto buffer: context.computeRenderBarrierBuffers) {
7709 ThsvsBufferBarrier svsBufferBarrier = {
7710 .prevAccessCount = 1,
7711 .pPrevAccesses = &prevAccesses,
7712 .nextAccessCount = 1,
7713 .pNextAccesses = &nextAccesses,
7714 .srcQueueFamilyIndex = 0,
7715 .dstQueueFamilyIndex = 0,
7718 .size = VK_WHOLE_SIZE
7720 VkBufferMemoryBarrier vkBufferMemoryBarrier;
7721 VkPipelineStageFlags srcStages;
7722 VkPipelineStageFlags dstStages;
7723 thsvsGetVulkanBufferMemoryBarrier(
7727 &vkBufferMemoryBarrier
7730 vkCmdPipelineBarrier(context.setupCommandInUse, srcStages, dstStages, 0, 0,
nullptr, 1, &vkBufferMemoryBarrier, 0,
nullptr);
7733 context.computeRenderBarrierBuffers.clear();
7738 uploadBufferObjectInternal(contextIdx, bufferObjectId, size, data->
getBuffer(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
7742 auto& currentContext =
contexts[contextIdx];
7743 uploadBufferObjectInternal(contextIdx, bufferObjectId, size, data->
getBuffer(), (VkBufferUsageFlagBits)(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT));
7747 auto& currentContext =
contexts[contextIdx];
7752 auto& currentContext =
contexts[contextIdx];
7757 auto& currentContext =
contexts[contextIdx];
7762 auto& currentContext =
contexts[contextIdx];
7767 auto& currentContext =
contexts[contextIdx];
7772 auto& currentContext =
contexts[contextIdx];
7774 currentContext.computeRenderBarrierBuffers.push_back(currentContext.boundBuffers[5]);
7776 auto prevAccesses = THSVS_ACCESS_VERTEX_BUFFER;
7777 auto nextAccesses = THSVS_ACCESS_COMPUTE_SHADER_WRITE;
7778 ThsvsBufferBarrier svsbufferBarrier = {
7779 .prevAccessCount = 1,
7780 .pPrevAccesses = &prevAccesses,
7781 .nextAccessCount = 1,
7782 .pNextAccesses = &nextAccesses,
7783 .srcQueueFamilyIndex = 0,
7784 .dstQueueFamilyIndex = 0,
7785 .buffer = currentContext.boundBuffers[5],
7787 .size = VK_WHOLE_SIZE
7789 VkBufferMemoryBarrier vkBufferMemoryBarrier;
7790 VkPipelineStageFlags srcStages;
7791 VkPipelineStageFlags dstStages;
7792 thsvsGetVulkanBufferMemoryBarrier(
7796 &vkBufferMemoryBarrier
7799 vkCmdPipelineBarrier(currentContext.setupCommandInUse, srcStages, dstStages, 0, 0,
nullptr, 1, &vkBufferMemoryBarrier, 0,
nullptr);
7804 auto& currentContext =
contexts[contextIdx];
7806 currentContext.computeRenderBarrierBuffers.push_back(currentContext.boundBuffers[6]);
7807 auto prevAccesses = THSVS_ACCESS_VERTEX_BUFFER;
7808 auto nextAccesses = THSVS_ACCESS_COMPUTE_SHADER_WRITE;
7809 ThsvsBufferBarrier svsbufferBarrier = {
7810 .prevAccessCount = 1,
7811 .pPrevAccesses = &prevAccesses,
7812 .nextAccessCount = 1,
7813 .pNextAccesses = &nextAccesses,
7814 .srcQueueFamilyIndex = 0,
7815 .dstQueueFamilyIndex = 0,
7816 .buffer = currentContext.boundBuffers[6],
7818 .size = VK_WHOLE_SIZE
7820 VkBufferMemoryBarrier vkBufferMemoryBarrier;
7821 VkPipelineStageFlags srcStages;
7822 VkPipelineStageFlags dstStages;
7823 thsvsGetVulkanBufferMemoryBarrier(
7827 &vkBufferMemoryBarrier
7830 vkCmdPipelineBarrier(currentContext.setupCommandInUse, srcStages, dstStages, 0, 0,
nullptr, 1, &vkBufferMemoryBarrier, 0,
nullptr);
7835 auto& currentContext =
contexts[contextIdx];
7840 Console::println(
"VKRenderer::" +
string(__FUNCTION__) +
"(): " + to_string(this->vSync) +
" --> " + to_string(
vSync));
7841 if (this->vSync ==
vSync)
return;
7843 this->vSync =
vSync;
7847 array<VmaBudget, VK_MAX_MEMORY_HEAPS> budget;
7851 stats.memoryUsageShared = budget[1].allocationBytes;
#define ERR_EXIT(err_msg, err_class)
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint)
#define GET_DEVICE_PROC_ADDR(dev, entrypoint)
#define TEXTUREDESCRIPTORSET_MAX_TEXTURES
Application base class, please make sure to allocate application on heap to have correct application ...
void reshape(int32_t width, int32_t height)
Reshape.
static Engine * getInstance()
Returns engine instance.
static TextureManager * getTextureManager()
static int getThreadCount()
TDME2 engine entity shader parameters.
TextureFilter getMinFilter() const
const vector< MipMapTexture > & getMipMapTextures(bool bc7Encoded)
Get mip map textures.
ByteBuffer getRGBTextureData()
uint8_t getRGBDepthBitsPerPixel() const
const string & getId() const
ByteBuffer getBC7TextureData()
uint16_t getTextureHeight() const
TextureFilter getMagFilter() const
uint16_t getTextureWidth() const
ClampMode getClampMode() const
@ TEXTUREFILTER_LINEAR_MIPMAP_LINEAR
@ TEXTUREFILTER_LINEAR_MIPMAP_NEAREST
@ TEXTUREFILTER_NEAREST_MIPMAP_NEAREST
@ TEXTUREFILTER_NEAREST_MIPMAP_LINEAR
bool isUseCompression() const
int32_t addCubeMapTexture(const string &id, Texture *textureLeft, Texture *textureRight, Texture *textureTop, Texture *textureBottom, Texture *textureFront, Texture *textureBack, int contextIdx=0)
Adds a cube map texture to manager.
TextureManager_TextureManaged * addTexture(const string &id, bool &created)
Adds a texture to manager.
int32_t CUBEMAPTEXTUREINDEX_NEGATIVE_Z
int32_t SHADER_FRAGMENT_SHADER
Renderer_Statistics statistics
int32_t SHADER_COMPUTE_SHADER
int32_t SHADER_VERTEX_SHADER
int32_t CLEAR_COLOR_BUFFER_BIT
int32_t CUBEMAPTEXTUREINDEX_NEGATIVE_X
int32_t CUBEMAPTEXTUREINDEX_POSITIVE_Y
vector< Renderer_Context > rendererContexts
int32_t CUBEMAPTEXTUREINDEX_NEGATIVE_Y
virtual void onBindTexture(int contextIdx, int32_t textureId)=0
On bind texture event.
RendererType rendererType
int32_t DEPTHFUNCTION_ALWAYS
int32_t DEPTHFUNCTION_LESSEQUAL
int32_t DEPTHFUNCTION_GREATEREQUAL
int32_t CUBEMAPTEXTUREINDEX_POSITIVE_Z
int32_t CONTEXTINDEX_DEFAULT
int32_t DEPTHFUNCTION_EQUAL
int32_t FRAMEBUFFER_DEFAULT
int32_t CUBEMAPTEXTUREINDEX_POSITIVE_X
int32_t CLEAR_DEPTH_BUFFER_BIT
GL3/Core -> Vulkan shader program.
static void loadShader(VKRenderer::shader_type &shader, int32_t type, const string &pathName, const string &fileName, const string &definitions=string(), const string &functions=string())
Loads a shader.
static bool linkProgram(VKRenderer::program_type &program)
Links attached shaders to a program.
void setClearColor(float red, float green, float blue, float alpha) override
Set up clear color.
void prepareTextureImage(int contextIdx, struct texture_type *textureObject, VkImageTiling tiling, VkImageUsageFlags usage, VkFlags requiredFlags, Texture *texture, const array< ThsvsAccessType, 2 > &nextAccesses, ThsvsImageLayout imageLayout, bool disableMipMaps=true, uint32_t baseLevel=0, uint32_t levelCount=1)
void enableDepthBufferWriting() override
Enable depth buffer writing.
const string getShaderVersion() override
void unsetPipeline(int contextIdx)
void bindSpriteSheetDimensionBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind sprite sheet dimension buffer object.
VkColorSpaceKHR windowColorSpace
void bindTexture(int contextIdx, int32_t textureId) override
Binds a texture with given id or unbinds when using ID_NONE.
uint32_t currentWindowFramebufferIdx
void clear(int32_t mask) override
Clear render buffer with given mask.
void createSkinningComputingProgram(program_type *program)
static constexpr int POINTS_VERTEX_BUFFER_COUNT
void bindTangentsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind tangents buffer object.
void disposeBufferObjects(vector< int32_t > &bufferObjectIds) override
Disposes a frame buffer object.
void invalidateTextureDescriptorCaches(int textureId)
int32_t getTextureUnit(int contextIdx) override
Get texture unit.
VkSwapchainKHR windowSwapchain
void setProgramUniformFloatMatrix3x3(int contextIdx, int32_t uniformId, const array< float, 9 > &data) override
Set up a float matrix 3x3 uniform value.
VkPhysicalDeviceProperties gpuProperties
void doneGuiMode() override
Set up renderer for 3d rendering.
static constexpr int DESC_MAX_UNCACHED
void setColorMask(bool red, bool green, bool blue, bool alpha) override
Set up GL rendering colormask.
void bindTextureCoordinatesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind texture coordinates buffer object.
void submitDrawCommandBuffers(int commandBufferCount, VkCommandBuffer *commandBuffers, VkFence &fence)
void setImageLayout2(int contextIdx, texture_type *textureObject, const array< ThsvsAccessType, 2 > &accessTypes, const array< ThsvsAccessType, 2 > &nextAccessTypes, ThsvsImageLayout layout, ThsvsImageLayout nextLayout, bool discardContent, uint32_t baseMipLevel, uint32_t levelCount, uint32_t baseArrayLayer, uint32_t layerCount, bool updateTextureObject)
void bindSkinningVertexJointWeightsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning vertex joint weights buffer object.
bool isGLCLAvailable() override
vector< delete_buffer_type > deleteBuffers
static constexpr int PROGRAMS_MAX
void attachShaderToProgram(int32_t programId, int32_t shaderId) override
Attaches a shader to a program.
void setupObjectsRenderingPipeline(int contextIdx, program_type *program)
void dispatchCompute(int contextIdx, int32_t numNodesX, int32_t numNodesY, int32_t numNodesZ) override
Dispatch compute.
void setFrontFace(int contextIdx, int32_t frontFace) override
Set up clock wise or counter clock wise faces as front face.
void setTextureUnit(int contextIdx, int32_t textureUnit) override
Sets up texture unit.
buffer_object_type * emptyVertexBuffer
void drawLinesFromBufferObjects(int contextIdx, int32_t points, int32_t pointsOffset) override
Draw lines from buffer objects.
VkDescriptorPool descriptorPool2
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, VmaAllocation &allocation, VmaAllocationInfo &allocationInfo)
void createLinesRenderingPipeline(int contextIdx, program_type *program)
void disableBlending() override
Disables blending.
PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR
void setProgramAttributeLocation(int32_t programId, int32_t location, const string &name) override
Bind attribute to a input location.
VkBool32 checkLayers(uint32_t checkCount, const char **checkNames, const vector< VkLayerProperties > &instanceLayers)
void setViewPort(int32_t width, int32_t height) override
Set up viewport parameter.
uint64_t framebufferPipelinesId
PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR
bool isSupportingMultithreadedRendering() override
VkCullModeFlagBits cullMode
int32_t getTextureUnits() override
void bindSkinningVerticesResultBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning vertices result buffer object.
void setProgramUniformFloat(int contextIdx, int32_t uniformId, float value) override
Set up a float uniform value.
const string getRenderer() override
const Renderer_Statistics getStatistics() override
void uploadCubeMapSingleTexture(int contextIdx, texture_type *cubemapTextureType, Texture *texture, uint32_t baseArrayLayer)
void initialize() override
Initialize renderer.
void setVSync(bool vSync) override
Enable/Disable v-sync.
vector< int32_t > disposeBuffers
int32_t createGBufferColorTexture(int32_t width, int32_t height) override
Creates a geometry buffer color RGBA texture.
PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR
unordered_map< int32_t, shader_type * > shaders
vector< int32_t > freeTextureIds
uint16_t createPipelineIndex(program_type *program, int contextIdx)
void setProgramUniformFloatVec3(int contextIdx, int32_t uniformId, const array< float, 3 > &data) override
Set up a float vec3 uniform value.
bool isSupportingIntegerProgramAttributes() override
static constexpr int SHADERS_COMPUTE_MAX
void disposeFrameBufferObject(int32_t frameBufferId) override
Disposes a frame buffer object.
const string getVendor() override
void uploadBufferObject(int contextIdx, int32_t bufferObjectId, int32_t size, FloatBuffer *data) override
Uploads buffer data to buffer object.
void uploadBufferObjectInternal(int contextIdx, buffer_object_type *buffer, int32_t size, const uint8_t *data, VkBufferUsageFlagBits usage)
void setProgramUniformInternal(int contextIdx, int32_t uniformId, uint8_t *data, int32_t size)
bool textureCompressionAvailable
void memoryBarrier() override
Memory barrier.
void createBufferTexture(int32_t textureId, int32_t width, int32_t height, int32_t cubeMapTextureId, int32_t cubeMapTextureIndex, VkFormat format)
static constexpr int GUI_VERTEX_BUFFER_COUNT
void setupSkinningComputingPipeline(int contextIdx, program_type *program)
void setProgramUniformInteger(int contextIdx, int32_t uniformId, int32_t value) override
Set up a integer uniform value.
int32_t getProgramUniformLocation(int32_t programId, const string &name) override
Returns location of given uniform variable.
void disableDepthBufferWriting() override
Disable depth buffer writing.
SpinLock pipelinesSpinLock
void createRenderProgram(program_type *program)
void setImageLayout(int contextIdx, texture_type *textureObject, const array< ThsvsAccessType, 2 > &nextAccessTypes, ThsvsImageLayout nextLayout, bool discardContent, uint32_t baseMipLevel=0, uint32_t levelCount=1, bool submit=true)
void bindSkinningVertexJointIdxsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning vertex joint indices buffer object.
void invalidatePipelines()
void applyImageLayoutChange(int contextIdx, const image_layout_change &imageLayoutChange, texture_type *textureObject, bool submit=true)
void bindNormalsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind normals buffer object.
int whiteTextureSampler2dDefaultId
void drawPointsFromBufferObjects(int contextIdx, int32_t points, int32_t pointsOffset) override
Draw points from buffer objects.
void vmaMemCpy(VmaAllocation allocationDst, const uint8_t *src, uint32_t size, uint32_t offset=0)
void disposeTexture(int32_t textureId) override
Dispose a texture.
int32_t createColorBufferTexture(int32_t width, int32_t height, int32_t cubeMapTextureId, int32_t cubeMapTextureIndex) override
Creates a color buffer texture.
void disableCulling(int contextIdx) override
Disable culling.
VkBuffer getBindBufferObjectInternal(int32_t bufferObjectId, uint32_t &size)
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR
static constexpr int SHADERS_MAX
void bindEffectColorMulsBufferObject(int contextIdx, int32_t bufferObjectId, int32_t divisor) override
Bind effect color muls buffer object.
int32_t createCubeMapTexture(int contextIdx, int32_t width, int32_t height) override
Create cube map texture from frame buffers.
static constexpr int COMMANDS_MAX_GRAPHICS
void bindCubeMapTexture(int contextIdx, int32_t textureId) override
Binds a cube map texture with given id or unbinds when using ID_NONE.
bool isPBRAvailable() override
VkSemaphore drawCompleteSemaphore
framebuffer_pipelines_type * framebufferPipelinesCache
void setProgramUniformFloatVec4(int contextIdx, int32_t uniformId, const array< float, 4 > &data) override
Set up a float vec4 uniform value.
void setDepthFunction(int32_t depthFunction) override
Set up depth function.
void uploadCubeMapTexture(int contextIdx, Texture *textureLeft, Texture *textureRight, Texture *textureTop, Texture *textureBottom, Texture *textureFront, Texture *textureBack) override
Uploads cube map texture data to current bound texture.
uint32_t graphicsQueueNodeIndex
void bindFrameBuffer(int32_t frameBufferId) override
Enables a framebuffer to be rendered.
static constexpr bool VERBOSE
void initializeRenderPass()
int32_t loadShader(int32_t type, const string &pathName, const string &fileName, const string &definitions=string(), const string &functions=string()) override
Loads a shader.
void initializeFrameBuffers()
bool isNormalMappingAvailable() override
static constexpr int DRAW_COMMANDBUFFER_MAX
vector< framebuffer_pipelines_type * > framebuffersPipelines
void createDepthStencilStateCreateInfo(VkPipelineDepthStencilStateCreateInfo &depthStencilStateCreateInfo)
void resizeDepthBufferTexture(int32_t textureId, int32_t width, int32_t height) override
Resizes a depth texture.
void resizeGBufferGeometryTexture(int32_t textureId, int32_t width, int32_t height) override
Resizes a geometry buffer geometry texture.
int whiteTextureSamplerCubeDefaultId
uint64_t createPipelineFramebufferId()
void finishFrame() override
Finish frame.
bool isInstancedRenderingAvailable() override
Checks if instanced rendering is available.
void drawTrianglesFromBufferObjects(int contextIdx, int32_t triangles, int32_t trianglesOffset) override
Draw triangles from buffer objects.
PFN_vkQueuePresentKHR fpQueuePresentKHR
vector< context_type > contexts
VmaAllocator vmaAllocator
void setupGUIRenderingPipeline(int contextIdx, program_type *program)
static constexpr int TEXTUREUNITS_MAX
void endRenderPass(int contextIdx)
void startRenderPass(int contextIdx)
void createDepthBufferTexture(int32_t textureId, int32_t width, int32_t height, int32_t cubeMapTextureId, int32_t cubeMapTextureIndex)
bool isSpecularMappingAvailable() override
void setImageLayout3(int contextIdx, VkImage image, VkImageAspectFlags aspectMask, const array< ThsvsAccessType, 2 > &accessTypes, const array< ThsvsAccessType, 2 > &nextAccessTypes, ThsvsImageLayout layout, ThsvsImageLayout nextLayout)
void initGuiMode() override
Set up renderer for GUI rendering.
framebuffer_pipelines_type * createFramebufferPipelines(uint64_t framebufferPipelinesId)
void applyImageLayoutChanges(int contextIdx, const array< image_layout_change, 8 > imageLayoutChanges, array< texture_type *, 8 > textureObjects, bool submit=true)
void finishSetupCommandBuffer(int contextIdx)
void bindSkinningVertexJointsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning vertex joints buffer object.
void setCullFace(int32_t cullFace) override
Sets up which face will be culled.
vector< int32_t > createBufferObjects(int32_t bufferCount, bool useGPUMemory, bool shared) override
Generate buffer objects for vertex data and such.
void enableBlending() override
Enables blending.
void setupPointsRenderingPipeline(int contextIdx, program_type *program)
static constexpr int COMPUTE_STORAGE_BUFFER_COUNT
VkPresentModeKHR lastSwapchainPresentMode
void setupLinesRenderingPipeline(int contextIdx, program_type *program)
void createObjectsRenderingPipeline(int contextIdx, program_type *program)
void uploadIndicesBufferObject(int contextIdx, int32_t bufferObjectId, int32_t size, ShortBuffer *data) override
Uploads buffer data to buffer object.
VkPhysicalDeviceFeatures gpuFeatures
void drawInstancedTrianglesFromBufferObjects(int contextIdx, int32_t triangles, int32_t trianglesOffset, VkBuffer indicesBuffer, int32_t instances)
bool linkProgram(int32_t programId) override
Links attached shaders to a program.
void createGUIRenderingPipeline(int contextIdx, program_type *program)
void setProgramUniformFloatMatrix4x4(int contextIdx, int32_t uniformId, const array< float, 16 > &data) override
Set up a float matrix 4x4 uniform value.
void enableCulling(int contextIdx) override
Enable culling.
static constexpr int CUBEMAPTEXTUREINDEX_MIN
int32_t boundFrameBufferId
vector< delete_image_type > deleteImages
PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fpGetPhysicalDeviceSurfacePresentModesKHR
uint32_t windowSwapchainImageCount
vector< program_type * > programVector
bool beginDrawCommandBuffer(int contextIdx, int bufferId=-1)
void endDrawCommandsAllContexts()
array< buffer_object_type *, BUFFERS_MAX+1 > buffers
void bindOriginsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind origins buffer object.
static constexpr int SHADERSSTAGES_MAX
int32_t createProgram(int type) override
Creates a shader program.
static constexpr int LINES_VERTEX_BUFFER_COUNT
void bindIndicesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind indices buffer object.
VkDescriptorPool descriptorPool1
bool isComputeShaderAvailable() override
static constexpr int DESC_MAX_CACHED
void initializeFrame() override
Pre Frame Initialization.
int32_t createGBufferGeometryTexture(int32_t width, int32_t height) override
Creates a geometry buffer geometry texture.
void uploadSkinningBufferObject(int contextIdx, int32_t bufferObjectId, int32_t size, FloatBuffer *data) override
Upload skinning buffer object.
static constexpr int BUFFERS_MAX
void enableAdditionBlending() override
Enable blending with c = a + b.
framebuffer_pipelines_type * getFramebufferPipelines(uint64_t framebufferPipelinesId)
void bindVerticesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind vertices buffer object.
bool deferredShadingAvailable
texture_type * getBindTextureInternal(int32_t textureId)
void prepareMipMapTextureImage(int contextIdx, struct texture_type *textureObject, VkImageTiling tiling, VkImageUsageFlags usage, VkFlags requiredFlags, Texture *texture, const Texture::MipMapTexture &mipMapTexture, const array< ThsvsAccessType, 2 > &nextAccesses, ThsvsImageLayout imageLayout)
vector< int32_t > freeBufferIds
void createRasterizationStateCreateInfo(int contextIdx, VkPipelineRasterizationStateCreateInfo &rasterizationStateCreateInfo)
void drawInstancedIndexedTrianglesFromBufferObjects(int contextIdx, int32_t triangles, int32_t trianglesOffset, int32_t instances) override
Draw instanced indexed triangles from buffer objects.
void bindVertices2BufferObject(int contextIdx, int32_t bufferObjectId) override
Bind vertices 2 buffer object.
VkPhysicalDevice physicalDevice
BlendingMode blendingMode
PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR
void useProgram(int contextIdx, int32_t programId) override
Use shader program.
void bindColorsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind colors buffer object.
VkPresentModeKHR swapchainPresentMode
void bindPointSizesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind point sizes buffer object.
void bindSkinningVerticesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning vertices buffer object.
void createColorBlendAttachmentState(VkPipelineColorBlendAttachmentState &blendAttachmentState)
void bindBitangentsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind bitangents buffer object.
vector< VkPipeline > disposePipelines
void bindSkinningNormalsResultBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning normals result buffer object.
void setProgramUniformFloatMatrices4x4(int contextIdx, int32_t uniformId, int32_t count, FloatBuffer *data) override
Set up a float matrices 4x4 uniform values.
void resizeGBufferColorTexture(int32_t textureId, int32_t width, int32_t height) override
Resizes a geometry buffer color RGBA texture.
void bindSkinningMatricesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning matrices result buffer object.
void initializeSwapChain()
int32_t createGeometryBufferObject(int32_t depthBufferTextureId, int32_t geometryBufferTextureId1, int32_t geometryBufferTextureId2, int32_t geometryBufferTextureId3, int32_t colorBufferTextureId1, int32_t colorBufferTextureId2, int32_t colorBufferTextureId3, int32_t colorBufferTextureId4, int32_t colorBufferTextureId5) override
Creates a geometry frame buffer object.
vector< window_frambuffer_buffer_type > windowFramebufferBuffers
void updateViewPort() override
Update viewport.
vector< VkFence > contextsDrawFences
void requestSubmitDrawBuffers(int contextIdx)
void createFramebufferObject(int32_t frameBufferId)
VkPipeline getPipelineInternal(int contextIdx, program_type *programm, uint64_t framebuffePipelineId, uint32_t pipelineIdx)
void bindModelMatricesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind model matrices buffer object.
void createPointsRenderingPipeline(int contextIdx, program_type *program)
VkSemaphore imageAcquiredSemaphore
void drawIndexedTrianglesFromBufferObjects(int contextIdx, int32_t triangles, int32_t trianglesOffset) override
Draw indexed triangles from buffer objects.
void disableDepthBufferTest() override
Disable depth buffer test.
void bindSkinningNormalsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind skinning normal buffer object.
void unbindBufferObjects(int contextIdx) override
Unbind buffer objects.
array< texture_type *, TEXTURES_MAX+1 > textures
uint32_t lastWindowFramebufferIdx
static constexpr int TEXTURES_MAX
VkPhysicalDeviceMemoryProperties memoryProperties
texture_type * getTextureInternal(int32_t textureId)
void bindEffectColorAddsBufferObject(int contextIdx, int32_t bufferObjectIdd, int32_t divisor) override
Bind effect color adds buffer object.
int32_t createTexture() override
Creates a texture.
vector< int32_t > disposeTextures
VkQueueFamilyProperties * queueProperties
float readPixelDepth(int32_t x, int32_t y) override
Reads a pixel depth.
void uploadTexture(int contextIdx, Texture *texture) override
Uploads texture data to current bound texture.
void getImageLayoutChange(image_layout_change &imageLayoutChange, texture_type *textureObject, const array< ThsvsAccessType, 2 > &prevAccessTypes, const array< ThsvsAccessType, 2 > &nextAccessTypes, ThsvsImageLayout prevLayout, ThsvsImageLayout nextLayout, bool discardContent, uint32_t baseMipLevel=0, uint32_t levelCount=1)
VkCommandBuffer endDrawCommandBuffer(int contextIdx, int bufferId=-1, bool cycleBuffers=true)
texture_type * whiteTextureSampler2dDefault
bool isUsingShortIndices() override
void setLineWidth(float lineWidth) override
Set line width.
ByteBuffer * readPixels(int32_t x, int32_t y, int32_t width, int32_t height) override
Read pixels.
void enableDepthBufferTest() override
Enable depth buffer test.
void resizeColorBufferTexture(int32_t textureId, int32_t width, int32_t height) override
Resize color buffer texture.
static constexpr int OBJECTS_VERTEX_BUFFER_COUNT
void bindTextureSpriteIndicesBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind texture and sprite indices buffer object.
bool isTextureCompressionAvailable() override
void setProgramUniformFloatVec2(int contextIdx, int32_t uniformId, const array< float, 2 > &data) override
Set up a float vec2 uniform value.
void finishSetupCommandBuffers()
bool isDeferredShadingAvailable() override
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR
buffer_object_type * getBufferObjectInternal(int32_t bufferObjectId)
void prepareSetupCommandBuffer(int contextIdx)
texture_type * whiteTextureSamplerCubeDefault
void bindSolidColorsBufferObject(int contextIdx, int32_t bufferObjectId) override
Bind solid colors buffer object.
PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR
vector< framebuffer_object_type * > framebuffers
bool isUsingProgramAttributeLocation() override
Matrix4x4 class representing matrix4x4 mathematical structure and operations for 3d space.
File system singleton class.
void unlock()
Unlocks this mutex.
void lock()
Locks the mutex, additionally mutex locks will block until other locks have been unlocked.
Implementation for read/write lock.
void unlock()
Unlocks this spin lock.
void lock()
Locks the spin lock, additionally spin lock locks will block until other locks have been unlocked.
uint8_t get(int64_t position) const
const uint8_t * getBuffer() const
Run time type information utility class.
std::exception Exception
Exception base class.
Bean holding light properties.
uint32_t disposedTextures
int64_t memoryUsageShared
reusable_buffer * bindBuffer
vector< reusable_buffer * > frameFreeBuffers
reusable_buffer * currentBuffer
list< reusable_buffer > buffers
VkPipelineStageFlags dstStages
VkPipelineStageFlags srcStages
VkImageMemoryBarrier vkImageMemoryBarrier
array< ThsvsAccessType, 2 > accessTypes
ThsvsImageLayout svsLayout
vector< context > contexts
vector< shader_type * > shaders
VkPipelineLayout pipelineLayout
VkDescriptorSetLayout texturesDescriptorSetLayout
VkDescriptorSetLayout uboDescriptorSetLayout
VkImageAspectFlags aspectMask
array< array< ThsvsAccessType, 2 >, 6 > accessTypes
int32_t frameBufferObjectId
int32_t cubemapTextureIndex
texture_type * cubemapBufferTexture
image_layout_change frameBufferUnbindImageLayoutChange
ThsvsImageLayout svsLayout
image_layout_change frameBufferBindImageLayoutChange