Base Code

Instance
Validation Layers
This commit is contained in:
onTheZero
2026-01-04 07:07:45 -05:00
parent 49aeba24cd
commit 5b32d32b0b
6 changed files with 343 additions and 51 deletions

50
.clang-format Normal file
View File

@@ -0,0 +1,50 @@
StatementMacros: ['UPROPERTY', 'UFUNCTION', 'UCLASS', 'USTRUCT', 'UENUM', 'UINTERFACE', 'GENERATED_BODY']
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Left
AlignOperands: DontAlign
AlignTrailingComments: true
AllowShortBlocksOnASingleLine: Empty
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: true
IndentBraces: false
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakInheritanceList: AfterColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: false
ColumnLimit: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: true
Cpp11BracedListStyle: false
EmptyLineBeforeAccessModifier: LogicalBlock
IndentCaseBlocks: false
IndentCaseLabels: true
IndentPPDirectives: BeforeHash
IndentWidth: 4
NamespaceIndentation: All
PointerAlignment: Left
SortIncludes: false
SpaceBeforeCaseColon: false
TabWidth: 4
UseTab: Always

View File

@@ -4,25 +4,213 @@
#include <iostream>
#include <stdexcept>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include "Logger.h"
const uint32_t WIDTH = 800;
const uint32_t HEIGHT = 600;
class HelloTriangleApplication {
const std::vector<const char*> validationLayers = {
"VK_LAYER_KHRONOS_validation"
};
#ifdef NDEBUG
const bool enableValidationLayers = false;
#else
const bool enableValidationLayers = true;
#endif
class HelloTriangleApplication
{
private:
static VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData)
{
std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl;
return VK_FALSE;
}
private:
GLFWwindow* window;
VkInstance instance;
std::vector<const char*> GetRequiredExtensions()
{
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions;
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
if (enableValidationLayers)
{
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
}
return extensions;
}
bool CheckValidationLayerSupport()
{
uint32_t layerCount;
vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
std::vector<VkLayerProperties> availableLayers(layerCount);
vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
for (const char* layerName : validationLayers)
{
bool layerFound = false;
for (const auto& layerProperties : availableLayers)
{
if (strcmp(layerName, layerProperties.layerName) == 0)
{
layerFound = true;
break;
}
}
if (!layerFound)
{
return false;
}
}
return true;
}
// VkResult vkCreateInstance(
// const VkInstanceCreateInfo* pCreateInfo,
// const VkAllocationCallbacks* pAllocator,
// VkInstance* instance)
//{
// if (pCreateInfo == nullptr || instance == nullptr) {
// log("Null pointer passed to required parameter!");
// return VK_ERROR_INITIALIZATION_FAILED;
// }
// return vkCreateInstance(pCreateInfo, pAllocator, instance);
//}
public:
void run() {
initWindow();
initVulkan();
mainLoop();
cleanup();
void Run()
{
InitWindow();
InitVulkan();
MainLoop();
Cleanup();
}
private:
void initWindow() {
void CheckExtensions(const char* requiredExtensions[], uint32_t requiredExtensionsCount)
{
uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> extensions(extensionCount);
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
std::string required;
std::string available;
required += "Required extensions:\n";
bool found = false;
for (uint32_t i = 0; i < requiredExtensionsCount; i++)
{
std::string requiredExtension = requiredExtensions[i];
for (const auto& extension : extensions)
{
found = strcmp(extension.extensionName, requiredExtensions[i]);
if (found)
{
break;
}
}
std::string status = found ? "FOUND" : "NOT FOUND";
required += "\t" + requiredExtension + " : " + status + "\n";
}
available += "available extensions:\n";
for (const auto& extension : extensions)
{
std::string extensionName = extension.extensionName;
available += "\t" + extensionName + "\n";
}
log(INFO, required);
log(INFO, available);
}
void CreateInstance()
{
log(INFO, "Creating Vulkan instance");
if (enableValidationLayers && !CheckValidationLayerSupport())
{
throw std::runtime_error("validation layers requested, but not available!");
}
VkApplicationInfo appInfo{};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Hello Triangle";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "No Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_0;
VkInstanceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
uint32_t glfwExtensionCount = 0;
const char** glfwExtensions;
glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
createInfo.enabledExtensionCount = glfwExtensionCount;
createInfo.ppEnabledExtensionNames = glfwExtensions;
if (enableValidationLayers)
{
createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
createInfo.ppEnabledLayerNames = validationLayers.data();
}
else
{
createInfo.enabledLayerCount = 0;
}
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
{
throw std::runtime_error("failed to create instance!");
}
CheckExtensions(glfwExtensions, glfwExtensionCount);
auto extensions = GetRequiredExtensions();
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
createInfo.ppEnabledExtensionNames = extensions.data();
}
void InitWindow()
{
log(INFO, "Initializing GLFW window...");
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
@@ -30,30 +218,41 @@ private:
window = glfwCreateWindow(WIDTH, HEIGHT, "Vulkan", nullptr, nullptr);
}
void initVulkan() {
void InitVulkan()
{
log(INFO, "Initializing Vulkan...");
CreateInstance();
}
void mainLoop() {
while (!glfwWindowShouldClose(window)) {
void MainLoop()
{
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
}
}
void cleanup() {
void Cleanup()
{
vkDestroyInstance(instance, nullptr);
glfwDestroyWindow(window);
glfwTerminate();
}
};
int main() {
int main()
{
HelloTriangleApplication app;
try {
app.run();
try
{
app.Run();
}
catch (const std::exception& e) {
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}

View File

@@ -102,13 +102,13 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\OpenGL\glm-0.9.9.7\glm\glm;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
@@ -120,19 +120,25 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\OpenGL\glm-0.9.9.7\glm\glm;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\include;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.304.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Users\jorda\Development\Libraries\OpenGL\glfw-3.4.bin.WIN64\glfw-3.4.bin.WIN64\lib-vc2022;C:\Users\jorda\Development\Libraries\Vulkan\1.4.335.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Learning Vulkan.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Logger.h" />
</ItemGroup>
<ItemGroup>
<None Include=".clang-format" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@@ -19,4 +19,12 @@
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Logger.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include=".clang-format" />
</ItemGroup>
</Project>

0
Logger.cpp Normal file
View File

29
Logger.h Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <iostream>
enum LogLevel {
INFO,
WARNING,
ERROR
};
void log(LogLevel level, const std::string& message) {
std::string levelStr;
switch(level) {
case INFO:
levelStr = "[INFO]";
break;
case WARNING:
levelStr = "[WARNING]";
break;
case ERROR:
levelStr = "[ERROR]";
break;
default:
levelStr = "[UNKNOWN]";
break;
}
std::cout << levelStr << " : " << message << std::endl;
}