void RenderViewport::AllocateDefaultRenderPass(rhi::GfxSetting & gfxSetting) { VKRHI_METHOD_TRACE VkFormat colorformat = m_pSwapChain ? m_pSwapChain->GetFormat() : g_FormatTable[gfxSetting.ColorFormat]; RenderpassAttachment colorAttach = RenderpassAttachment::CreateColor(colorformat); colorAttach.GetDescription() .InitialLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) .FinalLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); RenderpassOptions option; option.AddAttachment(colorAttach); Subpass subpass_; subpass_.AddColorAttachment(0); if (gfxSetting.HasDepth) { VkFormat depthFormat = g_FormatTable[gfxSetting.DepthStencilFormat]; GetSupportedDepthFormat(GetPhysicalDevice(), &depthFormat); RenderpassAttachment depthAttach = RenderpassAttachment::CreateDepthStencil(depthFormat); depthAttach.GetDescription().InitialLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) .FinalLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); subpass_.AddDepthStencilAttachment(1); option.AddAttachment(depthAttach); } option.AddSubPass(subpass_); m_RenderPass = std::make_unique<RenderPass>(GetDevice(), option); }
BOOL RegenDir(Database *DB, char *PathString, const char *Device) { DIR *dird; dirent *diren; char TempPath[1024]; char Physical[1024]; char *n; GetPhysicalDevice(Device, Physical); strcpy(TempPath, PathString); TempPath[strlen(TempPath)-1]=0; // Traverse first level of subdirectories dird = opendir(TempPath); if(dird == NULL) return ( FALSE ); while ( TRUE ) { diren = readdir(dird); if (diren) { n = diren->d_name; strcpy(TempPath, PathString); strcat(TempPath, n); if (IsDirectory(TempPath)) { if ( stricmp(n, "INCOMING" ) != 0 && stricmp(n, "PRINTER_FILES") != 0 && strcmp (n, "." ) != 0 && strcmp (n, ".." ) != 0 && stricmp(n, "BIN" ) != 0 #ifdef DARWIN //A Macintosh OS X file. && stricmp(n, ".DS_Store" ) != 0 #endif //DARWIN ) { strcat(TempPath, PATHSEPSTR); RegenDir(DB, TempPath, Device); } } else { RegenToDatabase (DB, TempPath + strlen(Physical), TempPath, Device); } } else break; } closedir(dird); return TRUE; }
BOOL RegenDir(Database *DB, char *PathString, const char *Device) { HANDLE fdHandle; WIN32_FIND_DATA FileData; char TempPath[1024]; char Physical[1024]; GetPhysicalDevice(Device, Physical); strcpy(TempPath, PathString); strcat(TempPath, "*.*"); // Traverse first level of subdirectories fdHandle = FindFirstFile(TempPath, &FileData); if(fdHandle == INVALID_HANDLE_VALUE) return ( FALSE ); while ( TRUE ) { if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if ( stricmp(FileData.cFileName, "INCOMING") != 0 && stricmp(FileData.cFileName, "PRINTER_FILES") != 0 && strcmp(FileData.cFileName, ".") != 0 && strcmp(FileData.cFileName, "..") != 0 && stricmp(FileData.cFileName, "BIN") != 0 ) { strcpy(TempPath, PathString); strcat(TempPath, FileData.cFileName); strcat(TempPath, PATHSEPSTR); RegenDir(DB, TempPath, Device); } } else { strcpy(TempPath, PathString); strcat(TempPath, FileData.cFileName); RegenToDatabase (DB, TempPath + strlen(Physical), TempPath, Device); } if(!FindNextFile(fdHandle, &FileData)) break; } FindClose(fdHandle); return TRUE; }
std::pair<VkFormat, VkColorSpaceKHR> SwapChain::ChooseFormat(rhi::GfxSetting & gfxSetting) { uint32_t formatCount; K3D_VK_VERIFY(fpGetPhysicalDeviceSurfaceFormatsKHR(GetPhysicalDevice(), m_Surface, &formatCount, NULL)); std::vector<VkSurfaceFormatKHR> surfFormats(formatCount); K3D_VK_VERIFY(fpGetPhysicalDeviceSurfaceFormatsKHR(GetPhysicalDevice(), m_Surface, &formatCount, surfFormats.data())); VkFormat colorFormat; VkColorSpaceKHR colorSpace; if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) { colorFormat = g_FormatTable[gfxSetting.ColorFormat]; } else { K3D_ASSERT(formatCount >= 1); colorFormat = surfFormats[0].format; } colorSpace = surfFormats[0].colorSpace; return std::make_pair(colorFormat, colorSpace); }
VkPresentModeKHR SwapChain::ChoosePresentMode() { uint32_t presentModeCount; K3D_VK_VERIFY(fpGetPhysicalDeviceSurfacePresentModesKHR(GetPhysicalDevice(), m_Surface, &presentModeCount, NULL)); std::vector<VkPresentModeKHR> presentModes(presentModeCount); K3D_VK_VERIFY(fpGetPhysicalDeviceSurfacePresentModesKHR(GetPhysicalDevice(), m_Surface, &presentModeCount, presentModes.data())); VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR; for (size_t i = 0; i < presentModeCount; i++) { if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR; break; } if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) && (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) { swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; } } return swapchainPresentMode; }
int SwapChain::ChooseQueueIndex() { uint32 chosenIndex = 0; std::vector<VkBool32> queuePresentSupport(GetDevice()->GetQueueCount()); for (uint32_t i = 0; i < GetDevice()->GetQueueCount(); ++i) { vkGetPhysicalDeviceSurfaceSupportKHR(GetPhysicalDevice(), i, m_Surface, &queuePresentSupport[i]); if (queuePresentSupport[i]) { chosenIndex = i; break; } } return chosenIndex; }
BOOL RegenFile(char *filename) { Database DB; UINT Index; char Device[255], Physical[1024], BaseName[1024]; if (!DB.Open ( DataSource, UserName, Password, DataHost ) ) { fprintf(stderr, "Error Connecting to SQL\n"); return ( FALSE ); } Index = 0; while ( Index < MAGDevices ) { sprintf(Device, "MAG%d", Index); GetPhysicalDevice(Device, Physical); if (memicmp(Physical, filename, strlen(Physical))==0) { strcpy(BaseName, filename + strlen(Physical)); RegenToDatabase(&DB, BaseName, filename, Device); break; } ++Index; } if (Index == MAGDevices) { fprintf(stderr, "File to enter is not on a MAG device\n"); return ( FALSE ); } return ( TRUE ); }
void SwapChain::Initialize(void * WindowHandle, rhi::GfxSetting & gfxSetting) { InitSurface(WindowHandle); VkPresentModeKHR swapchainPresentMode = ChoosePresentMode(); std::pair<VkFormat, VkColorSpaceKHR> chosenFormat = ChooseFormat(gfxSetting); m_SelectedPresentQueueFamilyIndex = ChooseQueueIndex(); m_SwapchainExtent = { gfxSetting.Width, gfxSetting.Height }; VkSurfaceCapabilitiesKHR surfProperties; K3D_VK_VERIFY(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(GetPhysicalDevice(), m_Surface, &surfProperties)); m_SwapchainExtent = surfProperties.currentExtent; /*gfxSetting.Width = m_SwapchainExtent.width; gfxSetting.Height = m_SwapchainExtent.height;*/ uint32 desiredNumBuffers = kMath::Clamp( gfxSetting.BackBufferCount, surfProperties.minImageCount, surfProperties.maxImageCount); m_DesiredBackBufferCount = desiredNumBuffers; InitSwapChain(m_DesiredBackBufferCount, chosenFormat, swapchainPresentMode, surfProperties.currentTransform); K3D_VK_VERIFY(fpGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, nullptr)); m_ColorImages.resize(m_ReserveBackBufferCount); K3D_VK_VERIFY(fpGetSwapchainImagesKHR(GetRawDevice(), m_SwapChain, &m_ReserveBackBufferCount, m_ColorImages.data())); gfxSetting.BackBufferCount = m_ReserveBackBufferCount; VKLOG(Info, "[SwapChain::Initialize] desired imageCount=%d, reserved imageCount = %d.", m_DesiredBackBufferCount, m_ReserveBackBufferCount); }
// TODO: Resizing bool VkContext::Init(Config config) { if (!glfwInit()) { std::cout << "Unable to initialize GLFW" << std::endl; return false; } if (!CreateInstance(config.windowTitle)) { std::cout << "Unable to create Vulkan instance" << std::endl; return false; } else { std::cout << "Created Vulkan instance" << std::endl; } if (!GetPhysicalDevice()) { std::cout << "Unable to get Vulkan physical device" << std::endl; return false; } else { std::cout << "Acquired Vulkan physical device" << std::endl; } if (!CreateWindowSurface(config.windowWidth, config.windowHeight, config.windowTitle)) { std::cout << "Unable to create window surfcace for Vulkan" << std::endl; return false; } else { std::cout << "Created Vulkan window surface" << std::endl; } if (!GetQueueFamilies()) { std::cout << "Unable to get Vulkan queue families" << std::endl; return false; } else { std::cout << "Acquired queue families" << std::endl; } if (!CreateDevice()) { std::cout << "Unable to create Vulkan device" << std::endl; return false; } else { std::cout << "Created Vulkan device" << std::endl; } #ifdef VOXL_DEBUG if (!SetupValidation()) { std::cout << "Unable to setup Vulkan validation" << std::endl; return false; } else { std::cout << "Setup Vulkan validation" << std::endl; } #endif if (!CreateSemaphores()) { std::cout << "Unable to create Vulkan semaphores" << std::endl; return false; } else { std::cout << "Created Vulkan semaphores" << std::endl; } if (!CreateSwapchain(config.windowWidth, config.windowHeight)) { std::cout << "Unable to create Vulkan swapchain" << std::endl; return false; } else { std::cout << "Created Vulkan swapchain" << std::endl; } if (!CreateCommandPool()) { std::cout << "Unable to create command pool" << std::endl; return false; } else { std::cout << "Created Vulkan command pool" << std::endl; } if (!CreateCommandBuffers()) { std::cout << "Unable to create command buffers" << std::endl; return false; } else { std::cout << "Created Vulkan command buffers" << std::endl; } std::cout << "Successfully initialized Vulkan" << std::endl; return true; }
void RenderViewport::AllocateRenderTargets(rhi::GfxSetting & gfxSetting) { if (m_RenderPass) { VkFormat depthFormat = g_FormatTable[gfxSetting.DepthStencilFormat]; GetSupportedDepthFormat(GetPhysicalDevice(), &depthFormat); VkImage depthImage; VkImageCreateInfo image = {}; image.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image.imageType = VK_IMAGE_TYPE_2D; image.format = depthFormat; // Use example's height and width image.extent = { GetWidth(), GetHeight(), 1 }; image.mipLevels = 1; image.arrayLayers = 1; image.samples = VK_SAMPLE_COUNT_1_BIT; image.tiling = VK_IMAGE_TILING_OPTIMAL; image.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; image.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; vkCreateImage(GetRawDevice(), &image, nullptr, &depthImage); VkDeviceMemory depthMem; // Allocate memory for the image (device local) and bind it to our image VkMemoryAllocateInfo memAlloc = {}; memAlloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; VkMemoryRequirements memReqs; vkGetImageMemoryRequirements(GetRawDevice(), depthImage, &memReqs); memAlloc.allocationSize = memReqs.size; GetDevice()->FindMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memAlloc.memoryTypeIndex); vkAllocateMemory(GetRawDevice(), &memAlloc, nullptr, &depthMem); vkBindImageMemory(GetRawDevice(), depthImage, depthMem, 0); auto layoutCmd = static_cast<CommandContext*>(GetDevice()->NewCommandContext(rhi::ECMD_Graphics)); ImageMemoryBarrierParams params(depthImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); layoutCmd->Begin(); params.MipLevelCount(1).AspectMask(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT).LayerCount(1); layoutCmd->PipelineBarrierImageMemory(params); layoutCmd->End(); layoutCmd->Execute(false); VkImageView depthView; VkImageViewCreateInfo depthStencilView = {}; depthStencilView.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; depthStencilView.viewType = VK_IMAGE_VIEW_TYPE_2D; depthStencilView.format = depthFormat; depthStencilView.subresourceRange = {}; depthStencilView.subresourceRange.aspectMask = DetermineAspectMask(depthFormat); depthStencilView.subresourceRange.baseMipLevel = 0; depthStencilView.subresourceRange.levelCount = 1; depthStencilView.subresourceRange.baseArrayLayer = 0; depthStencilView.subresourceRange.layerCount = 1; depthStencilView.image = depthImage; vkCreateImageView(GetRawDevice(), &depthStencilView, nullptr, &depthView); m_RenderTargets.resize(m_NumBufferCount); RenderpassOptions option = m_RenderPass->GetOption(); VkFormat colorFmt = option.GetAttachments()[0].GetFormat(); for (uint32_t i = 0; i < m_NumBufferCount; ++i) { VkImage colorImage = m_pSwapChain->GetBackImage(i); auto colorImageInfo = ImageViewInfo::CreateColorImageView(GetRawDevice(), colorFmt, colorImage); VKLOG(Info, "swapchain imageView created . (0x%0x).", colorImageInfo.first); colorImageInfo.second.components = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; auto colorTex = Texture::CreateFromSwapChain(colorImage, colorImageInfo.first, colorImageInfo.second, GetDevice()); FrameBuffer::Attachment colorAttach(colorImageInfo.first); FrameBuffer::Attachment depthAttach(depthView); FrameBuffer::Option op; op.Width = GetWidth(); op.Height = GetHeight(); op.Attachments.push_back(colorAttach); op.Attachments.push_back(depthAttach); auto framebuffer = SpFramebuffer(new FrameBuffer(GetDevice(), m_RenderPass->GetPass(), op)); m_RenderTargets[i] = std::make_shared<RenderTarget>(GetDevice(), colorTex, framebuffer, m_RenderPass->GetPass()); } } }
BOOL Regen(const char *Device, int IsCacheOrJukeBox, char *SubDir) { int itemp, i, j, CDNumber, JUKEBOXNumber; Database DB; DIR *dird; dirent *diren; char PathString[1024], TempPath[1024], FileString[1024]; char ActualDevice[256]; char *p; if (!DB.Open ( DataSource, UserName, Password, DataHost ) ) { fprintf(stderr, "Error Connecting to SQL\n"); return ( FALSE ); } // convert device specification to a path GetPhysicalDevice(Device, PathString); itemp = strlen(PathString); if(!itemp) return FALSE; // strip the last subdirectory (e.g., CD0_%04d) for regen of complete CACHE or JUKEBOX devices if (IsCacheOrJukeBox) { PathString[itemp-1]=0; p = strrchr(PathString, PATHSEPCHAR); if (p) p[0]=0; OperatorConsole.printf("Regen directory = %s\n", PathString); itemp = strlen(PathString); if(!itemp) return (FALSE); } // add a '/' to end of directory name if not yet present if(PathString[itemp-1] != PATHSEPCHAR) strcat(PathString, PATHSEPSTR); // PathString now contains Image file storage root directory path // Regen all files and subdirectories below that or only the selected subdirectory if (!IsCacheOrJukeBox) { if (SubDir) { strcat(PathString, SubDir); strcat(PathString, PATHSEPSTR); } return RegenDir(&DB, PathString, Device); } // remaining code is for cache or jukebox devices strcpy(TempPath, PathString); TempPath[strlen(TempPath)-1]=0; dird = opendir(TempPath); if(dird == NULL) return ( FALSE ); while ( TRUE ) { diren = readdir(dird); if (!diren) break; // traverse one level for CD or cache directories (CDs to be burned) if (strcmp(diren->d_name, ".") != 0 && strcmp(diren->d_name, "..") != 0 ) { strcpy(FileString, diren->d_name); // Decompose jukebox directory name to find CD number // Directory name must be like aaaCCCC where C=CD number a=non-number if(strnicmp(Device, "JUKEBOX", 7)==0) { CDNumber = 0; for (i=strlen(FileString)-1; i>=0; i--) { if (FileString[i] < '0' || FileString[i] > '9') { CDNumber = atoi(FileString + i + 1); break; } } sprintf(ActualDevice, "%s.%d", Device, CDNumber); } // Decompose cache directory name to find CD number and jukebox number // Directory name must be like aaaJJaCCCC where C=CD# J=jukebox# a=non-number if(strnicmp(Device, "CACHE", 5)==0) { CDNumber = 0; JUKEBOXNumber = 0; for (i=strlen(FileString)-1; i>=0; i--) { if (FileString[i] < '0' || FileString[i] > '9') { CDNumber = atoi(FileString + i + 1); for (j=i-1; j>=0; j--) { if (FileString[j] < '0' || FileString[j] > '9') { JUKEBOXNumber = atoi(FileString + j + 1); break; } } break; } } sprintf(ActualDevice, "%s.%d.%d", Device, JUKEBOXNumber, CDNumber); } strcpy(TempPath, PathString); strcat(TempPath, FileString); strcat(TempPath, PATHSEPSTR); RegenDir(&DB, TempPath, ActualDevice); } } closedir(dird); #ifdef MULTITHREAD while(!queueempty()) sleep(1); #endif return ( TRUE ); }