progress. But we still have to correctly send the vertex data.

This commit is contained in:
Vicente Ferrari Smith 2026-02-16 21:29:06 +01:00
parent 34789e806b
commit 19f2acc2ec
15 changed files with 294 additions and 202 deletions

82
.idea/editor.xml generated
View File

@ -246,22 +246,100 @@
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" /> <option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/EXPORT_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/REQUIRES_EXPRESSION_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" /> <option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" /> <option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
</component> </component>
</project> </project>

4
.idea/vcs.xml generated
View File

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/glfw-src" vcs="Git" /> <mapping directory="$PROJECT_DIR$/cmake-build-debug-visual-studio/_deps/glfw-src" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cmake-build-debug/_deps/glm-src" vcs="Git" /> <mapping directory="$PROJECT_DIR$/cmake-build-debug-visual-studio/_deps/glm-src" vcs="Git" />
</component> </component>
</project> </project>

View File

@ -5,7 +5,8 @@ set(CMAKE_CXX_STANDARD 23)
include(FetchContent) include(FetchContent)
find_package(Vulkan REQUIRED) variable_watch($ENV{VULKAN_SDK})
find_package(Vulkan REQUIRED COMPONENTS volk)
FetchContent_Declare( FetchContent_Declare(
glfw glfw

View File

@ -4,7 +4,7 @@
#include <cassert> #include <cassert>
#define VOLK_IMPLEMENTATION #define VOLK_IMPLEMENTATION
#include <volk/volk.h> #include <Volk/volk.h>
#define VMA_IMPLEMENTATION #define VMA_IMPLEMENTATION
#include <vma/vk_mem_alloc.h> #include <vma/vk_mem_alloc.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>

View File

@ -56,17 +56,27 @@ int createInstance(GLFWwindow *window) {
uint32_t extensions_count; uint32_t extensions_count;
const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count); const char** extensions = glfwGetRequiredInstanceExtensions(&extensions_count);
std::vector<const char*> instance_exts; std::vector<const char*> instance_exts;
instance_exts.reserve(extensions_count + 1);
// Copy GLFW-required extensions
for (uint32_t i = 0; i < extensions_count; i++) { for (uint32_t i = 0; i < extensions_count; i++) {
instance_exts.push_back(extensions[i]); instance_exts.push_back(extensions[i]);
} }
// Append portability enumeration (MANDATORY on macOS) // Append portability enumeration (MANDATORY on macOS)
instance_exts.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
instance_exts.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); instance_exts.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
instance_exts.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
for (auto& ext : instance_exts) { uint32_t availableCount = 0;
std::print("extension {}\n", ext); vkEnumerateInstanceExtensionProperties(nullptr, &availableCount, nullptr);
std::vector<VkExtensionProperties> available(availableCount);
vkEnumerateInstanceExtensionProperties(nullptr, &availableCount, available.data());
bool has_portability_extension = false;
for (const VkExtensionProperties &property : available) {
if (strcmp(property.extensionName, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME) == 0) {
has_portability_extension = true;
instance_exts.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
}
} }
constexpr VkApplicationInfo app{ constexpr VkApplicationInfo app{
@ -90,10 +100,9 @@ int createInstance(GLFWwindow *window) {
dbg.pfnUserCallback = debugCallback; dbg.pfnUserCallback = debugCallback;
const VkInstanceCreateInfo ici{ VkInstanceCreateInfo ici{
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pNext = &dbg, .pNext = &dbg,
.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR,
.pApplicationInfo = &app, .pApplicationInfo = &app,
.enabledLayerCount = 1, .enabledLayerCount = 1,
.ppEnabledLayerNames = layers, .ppEnabledLayerNames = layers,
@ -101,6 +110,10 @@ int createInstance(GLFWwindow *window) {
.ppEnabledExtensionNames = instance_exts.data(), .ppEnabledExtensionNames = instance_exts.data(),
}; };
if (has_portability_extension) {
ici.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
VkResult res = vkCreateInstance(&ici, nullptr, &instance); VkResult res = vkCreateInstance(&ici, nullptr, &instance);
if (res != VK_SUCCESS) { if (res != VK_SUCCESS) {
printf("vkCreateInstance failed: %d\n", res); printf("vkCreateInstance failed: %d\n", res);
@ -165,16 +178,28 @@ void createDevice() {
std::println("{}", queueFamily); std::println("{}", queueFamily);
const char* devExts[] = { std::vector<const char*> devExts = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME,
VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME, VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME,
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME, VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME,
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME, VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
"VK_KHR_portability_subset"
}; };
uint32_t extensionCount = 0;
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, nullptr);
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, availableExtensions.data());
for (const auto& ext : availableExtensions) {
if (strcmp(ext.extensionName, "VK_KHR_portability_subset") == 0) {
devExts.push_back("VK_KHR_portability_subset");
break;
}
}
float prio = 1.0f; float prio = 1.0f;
VkDeviceQueueCreateInfo qci{ VkDeviceQueueCreateInfo qci{
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
@ -216,8 +241,8 @@ void createDevice() {
.pNext = &dyn, .pNext = &dyn,
.queueCreateInfoCount = 1, .queueCreateInfoCount = 1,
.pQueueCreateInfos = &qci, .pQueueCreateInfos = &qci,
.enabledExtensionCount = 7, .enabledExtensionCount = (uint32_t)devExts.size(),
.ppEnabledExtensionNames = devExts .ppEnabledExtensionNames = devExts.data(),
}; };
vkCreateDevice(physicalDevice, &dci, nullptr, &device); vkCreateDevice(physicalDevice, &dci, nullptr, &device);

View File

@ -9,16 +9,19 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <vma/vk_mem_alloc.h> #include <vma/vk_mem_alloc.h>
inline VkInstance instance; inline VkInstance instance{};
inline VkPhysicalDevice physicalDevice; inline VkPhysicalDevice physicalDevice{};
inline VkDevice device; inline VkDevice device{};
inline VkQueue graphics_queue; inline VkQueue graphics_queue{};
inline uint32_t queueFamily; inline uint32_t queueFamily{};
inline VkSurfaceKHR surface; inline VkSurfaceKHR surface{};
inline VkDebugUtilsMessengerEXT debugMessenger; inline VkDebugUtilsMessengerEXT debugMessenger{};
inline VmaAllocator allocator; inline VmaAllocator allocator{};
inline uint32_t MAX_FRAMES_IN_FLIGHT = 2;
inline constexpr uint32_t MAX_VERTICES_PER_BATCH = 65536;
int createInstance(GLFWwindow* window); int createInstance(GLFWwindow* window);
void createSurface(GLFWwindow* window); void createSurface(GLFWwindow* window);

View File

@ -15,14 +15,6 @@ bool SortKey::operator<(const SortKey& b) const {
Renderer::Renderer(GLFWwindow *window) { Renderer::Renderer(GLFWwindow *window) {
VkCommandPoolCreateInfo cpci{
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = queueFamily
};
vkCreateCommandPool(device, &cpci, nullptr, &commandPool);
create_pipeline_layout(); create_pipeline_layout();
colored_quad_pipeline = create_graphics_pipeline<vertex_p2_st2_col4_a1_u32>( colored_quad_pipeline = create_graphics_pipeline<vertex_p2_st2_col4_a1_u32>(
device, device,
@ -37,20 +29,7 @@ Renderer::Renderer(GLFWwindow *window) {
} }
void Renderer::begin_frame() { void Renderer::begin_frame() {
uint64_t waitValue = 0; commands.clear();
if (frameValue >= MAX_FRAMES_IN_FLIGHT) {
waitValue = frameValue - MAX_FRAMES_IN_FLIGHT + 1;
VkSemaphoreWaitInfo waitInfo{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
.semaphoreCount = 1,
.pSemaphores = &timelineSemaphore,
.pValues = &waitValue
};
vkWaitSemaphores(device, &waitInfo, UINT64_MAX);
}
} }
void Renderer::flush() { void Renderer::flush() {
@ -122,7 +101,7 @@ void Renderer::create_pipeline_layout() {
bindings[0] = VkDescriptorSetLayoutBinding{ bindings[0] = VkDescriptorSetLayoutBinding{
.binding = 0, .binding = 0,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1000, .descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
}; };
@ -130,7 +109,7 @@ void Renderer::create_pipeline_layout() {
.binding = 1, .binding = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT // The vertex shader "pulls" from here .stageFlags = VK_SHADER_STAGE_VERTEX_BIT
}; };
VkDescriptorBindingFlags flags[2] = { VkDescriptorBindingFlags flags[2] = {
@ -146,7 +125,7 @@ void Renderer::create_pipeline_layout() {
VkDescriptorSetLayoutCreateInfo dslci{ VkDescriptorSetLayoutCreateInfo dslci{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &layoutFlags, // Attach the flags .pNext = &layoutFlags,
.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT,
.bindingCount = 2, .bindingCount = 2,
.pBindings = bindings .pBindings = bindings
@ -175,44 +154,55 @@ void Renderer::create_pipeline_layout() {
} }
void Renderer::createFrameResources() { void Renderer::createFrameResources() {
VkSemaphoreTypeCreateInfo typeInfo{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
.initialValue = 0
};
const VkSemaphoreCreateInfo semaphoreci{ const VkSemaphoreCreateInfo seci{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = &typeInfo
}; };
vkCreateSemaphore(device, &semaphoreci, nullptr, &timelineSemaphore); VkFenceCreateInfo fenceInfo{
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
};
const VkSemaphoreCreateInfo seci{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; VkCommandPoolCreateInfo cpci{
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = queueFamily
};
for (auto & frame : frames) { frames.resize(MAX_FRAMES_IN_FLIGHT);
for (uint32_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i) {
Frame &frame = frames[i];
vkCreateSemaphore(device, &seci, nullptr, &frame.imageAvailable); vkCreateSemaphore(device, &seci, nullptr, &frame.imageAvailable);
vkCreateSemaphore(device, &seci, nullptr, &frame.renderFinished);
} vkCreateFence(device, &fenceInfo, nullptr, &frame.in_flight_fence);
vkCreateCommandPool(device, &cpci, nullptr, &frame.commandPool);
const VkCommandBufferAllocateInfo cbai{ const VkCommandBufferAllocateInfo cbai{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = commandPool, .commandPool = frame.commandPool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1 .commandBufferCount = 1
}; };
for (auto &frame : frames) {
vkAllocateCommandBuffers(device, &cbai, &frame.command_buffer); vkAllocateCommandBuffers(device, &cbai, &frame.command_buffer);
} }
VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
bufferInfo.size = 1024 * 1024 * 4;
bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
VmaAllocationCreateInfo allocInfo = {};
allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU; VkBufferCreateInfo bufferInfo = {
allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = 1024 * 1024 * 4,
.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
};
VmaAllocationCreateInfo allocInfo = {
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
};
vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &vertexBuffer, &vertexAllocation, &vertexAllocInfo); vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &vertexBuffer, &vertexAllocation, &vertexAllocInfo);
@ -237,12 +227,40 @@ void Renderer::createFrameResources() {
void Renderer::end_frame() { void Renderer::end_frame() {
Frame &frame = frames[currentFrame];
vkWaitForFences(device, 1, &frame.in_flight_fence, VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &frame.in_flight_fence);
commands = counting_sort_descending(commands, [](const RenderCommand &cmd){ commands = counting_sort_descending(commands, [](const RenderCommand &cmd){
return cmd.key.depth; return cmd.key.depth;
}); });
VkMemoryPropertyFlags memPropFlags;
vmaGetAllocationMemoryProperties(allocator, vertexAllocation, &memPropFlags);
if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
// The Allocation ended up in a mappable memory.
// Calling vmaCopyMemoryToAllocation() does vmaMapMemory(), memcpy(), vmaUnmapMemory(), and vmaFlushAllocation().
VkResult result = vmaCopyMemoryToAllocation(allocator, myData, alloc, 0, myDataSize);
// Check result...
VkBufferMemoryBarrier bufMemBarrier = { VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER };
bufMemBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
bufMemBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT;
bufMemBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufMemBarrier.buffer = buf;
bufMemBarrier.offset = 0;
bufMemBarrier.size = VK_WHOLE_SIZE;
// It's important to insert a buffer memory barrier here to ensure writing to the buffer has finished.
vkCmdPipelineBarrier(c, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
0, 0, nullptr, 1, &bufMemBarrier, 0, nullptr);
}
vertex_p2_st2_col4_a1_u32 *vPtr = (vertex_p2_st2_col4_a1_u32 *) vertexAllocInfo.pMappedData; vertex_p2_st2_col4_a1_u32 *vPtr = (vertex_p2_st2_col4_a1_u32 *) vertexAllocInfo.pMappedData;
vertex_p2_st2_col4_a1_u32 *currentFrameStart = vPtr + (currentFrame * MAX_VERTICES_PER_FRAME); vertex_p2_st2_col4_a1_u32 *currentFrameStart = vPtr + (currentFrame * MAX_VERTICES_PER_BATCH);
uint32_t totalVertices = 0; uint32_t totalVertices = 0;
for (auto& cmd : commands) { for (auto& cmd : commands) {
@ -251,7 +269,7 @@ void Renderer::end_frame() {
switch (cmd.pipeline) { switch (cmd.pipeline) {
case PipelineType::ColoredQuad: { case PipelineType::ColoredQuad: {
const auto &q = cmd.textured_quad; const auto &q = cmd.colored_quad;
// Calculate spatial corners // Calculate spatial corners
float x0 = q.position.x; float x0 = q.position.x;
@ -260,16 +278,21 @@ void Renderer::end_frame() {
float y1 = q.position.y + q.size.y; float y1 = q.position.y + q.size.y;
// Calculate UV corners // Calculate UV corners
float u0 = q.uvMin.x; // float u0 = q.uvMin.x;
float v0 = q.uvMin.y; // float v0 = q.uvMin.y;
float u1 = q.uvMax.x; // float u1 = q.uvMax.x;
float v1 = q.uvMax.y; // float v1 = q.uvMax.y;
// Define the 4 corners of the quad // Define the 4 corners of the quad
vertex_p2_st2_col4_a1_u32 vTL = { {x0, y0}, {u0, v0}, q.color, 1, q.textureID }; vertex_p2_st2_col4_a1_u32 vTL = { {x0, y0}, {0, 0}, q.color, 1, 0 };
vertex_p2_st2_col4_a1_u32 vTR = { {x1, y0}, {u1, v0}, q.color, 1, q.textureID }; vertex_p2_st2_col4_a1_u32 vTR = { {x1, y0}, {0, 0}, q.color, 1, 0 };
vertex_p2_st2_col4_a1_u32 vBL = { {x0, y1}, {u0, v1}, q.color, 1, q.textureID }; vertex_p2_st2_col4_a1_u32 vBL = { {x0, y1}, {0, 0}, q.color, 1, 0 };
vertex_p2_st2_col4_a1_u32 vBR = { {x1, y1}, {u1, v1}, q.color, 1, q.textureID }; vertex_p2_st2_col4_a1_u32 vBR = { {x1, y1}, {0, 0}, q.color, 1, 0 };
// vertex_p2_st2_col4_a1_u32 vTL = { {x0, y0}, {u0, v0}, q.color, 1, q.textureID };
// vertex_p2_st2_col4_a1_u32 vTR = { {x1, y0}, {u1, v0}, q.color, 1, q.textureID };
// vertex_p2_st2_col4_a1_u32 vBL = { {x0, y1}, {u0, v1}, q.color, 1, q.textureID };
// vertex_p2_st2_col4_a1_u32 vBR = { {x1, y1}, {u1, v1}, q.color, 1, q.textureID };
// --- Triangle 1 (TL, TR, BL) --- // --- Triangle 1 (TL, TR, BL) ---
vPtr[0] = vTL; vPtr[0] = vTL;
@ -295,12 +318,12 @@ void Renderer::end_frame() {
device, device,
swapchain, swapchain,
UINT64_MAX, UINT64_MAX,
frames[currentFrame].imageAvailable, frame.imageAvailable,
VK_NULL_HANDLE, VK_NULL_HANDLE,
&imageIndex &imageIndex
); );
VkCommandBuffer command_buffer = frames[currentFrame].command_buffer; VkCommandBuffer command_buffer = frame.command_buffer;
vkResetCommandBuffer(command_buffer, 0); vkResetCommandBuffer(command_buffer, 0);
recordCommandBuffer( recordCommandBuffer(
@ -311,33 +334,20 @@ void Renderer::end_frame() {
imageLayouts[imageIndex] imageLayouts[imageIndex]
); );
commands.clear();
imageLayouts[imageIndex] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; imageLayouts[imageIndex] = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
frameValue++;
VkSemaphoreSubmitInfo waitBinary{ VkSemaphoreSubmitInfo waitBinary{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
.semaphore = frames[currentFrame].imageAvailable, .semaphore = frame.imageAvailable,
.stageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT .stageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT
}; };
VkSemaphoreSubmitInfo signalBinary{ VkSemaphoreSubmitInfo signalBinary{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
.semaphore = frames[currentFrame].renderFinished, .semaphore = renderFinished[imageIndex],
.stageMask = VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT .stageMask = VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT
}; };
VkSemaphoreSubmitInfo signalTimeline{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
.semaphore = timelineSemaphore,
.value = frameValue,
.stageMask = VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT
};
VkSemaphoreSubmitInfo signals[] = { signalBinary, signalTimeline };
VkCommandBufferSubmitInfo cmdInfo{ VkCommandBufferSubmitInfo cmdInfo{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
.commandBuffer = command_buffer, .commandBuffer = command_buffer,
@ -349,16 +359,16 @@ void Renderer::end_frame() {
.pWaitSemaphoreInfos = &waitBinary, .pWaitSemaphoreInfos = &waitBinary,
.commandBufferInfoCount = 1, .commandBufferInfoCount = 1,
.pCommandBufferInfos = &cmdInfo, .pCommandBufferInfos = &cmdInfo,
.signalSemaphoreInfoCount = 2, .signalSemaphoreInfoCount = 1,
.pSignalSemaphoreInfos = signals, .pSignalSemaphoreInfos = &signalBinary,
}; };
vkQueueSubmit2(graphics_queue, 1, &submit, VK_NULL_HANDLE); vkQueueSubmit2(graphics_queue, 1, &submit, frame.in_flight_fence);
VkPresentInfoKHR present{ VkPresentInfoKHR present{
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.waitSemaphoreCount = 1, .waitSemaphoreCount = 1,
.pWaitSemaphores = &frames[currentFrame].renderFinished, .pWaitSemaphores = &renderFinished[imageIndex],
.swapchainCount = 1, .swapchainCount = 1,
.pSwapchains = &swapchain, .pSwapchains = &swapchain,
.pImageIndices = &imageIndex, .pImageIndices = &imageIndex,
@ -425,7 +435,7 @@ void Renderer::recordCommandBuffer(
vkCmdSetScissor(command_buffer, 0, 1, &sc); vkCmdSetScissor(command_buffer, 0, 1, &sc);
PipelineType lastPipeline = PipelineType::None; // Track current state PipelineType lastPipeline = PipelineType::None; // Track current state
uint32_t vertexOffset = currentFrame * MAX_VERTICES_PER_FRAME; uint32_t vertexOffset = currentFrame * MAX_VERTICES_PER_BATCH;
uint32_t currentBatchVertices = 0; uint32_t currentBatchVertices = 0;
for (const auto & cmd : commands) { for (const auto & cmd : commands) {
@ -479,31 +489,31 @@ VkPipeline Renderer::get_pipeline(PipelineType type) const {
} }
} }
void Renderer::bind_material(VkCommandBuffer cmd, uint16_t materialID) { // void Renderer::bind_material(VkCommandBuffer cmd, uint16_t materialID) {
// In a real app, you'd have an array/map: std::vector<VkDescriptorSet> textureSets; // // In a real app, you'd have an array/map: std::vector<VkDescriptorSet> textureSets;
VkDescriptorSet set = textureSets[materialID]; // VkDescriptorSet set = textureSets[materialID];
//
vkCmdBindDescriptorSets( // vkCmdBindDescriptorSets(
cmd, // cmd,
VK_PIPELINE_BIND_POINT_GRAPHICS, // VK_PIPELINE_BIND_POINT_GRAPHICS,
pipelineLayout, // Our shared layout // pipelineLayout, // Our shared layout
0, // Starting at Set 0 // 0, // Starting at Set 0
1, // Binding 1 set // 1, // Binding 1 set
&set, // &set,
0, nullptr // 0, nullptr
); // );
} // }
void Renderer::create_descriptor_pool() { void Renderer::create_descriptor_pool() {
VkDescriptorPoolSize pool_sizes[] = { VkDescriptorPoolSize pool_sizes[] = {
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 10 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 }, { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1 },
}; };
VkDescriptorPoolCreateInfo pool_info{ VkDescriptorPoolCreateInfo pool_info{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT,
.maxSets = 1000, .maxSets = 1,
.poolSizeCount = 2, .poolSizeCount = 2,
.pPoolSizes = pool_sizes .pPoolSizes = pool_sizes
}; };
@ -517,9 +527,7 @@ void Renderer::create_descriptor_pool() {
.pSetLayouts = &descriptor_set_layout .pSetLayouts = &descriptor_set_layout
}; };
if (vkAllocateDescriptorSets(device, &alloc_info, &set) != VK_SUCCESS) { vkAllocateDescriptorSets(device, &alloc_info, &set);
throw std::runtime_error("Failed to allocate bindless descriptor set!");
}
} }
void Renderer::update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler) { void Renderer::update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler) {
@ -618,7 +626,7 @@ Texture Renderer::upload_texture(int w, int h, void* pixels) {
void Renderer::immediate_submit(std::function<void(VkCommandBuffer)>&& func) const { void Renderer::immediate_submit(std::function<void(VkCommandBuffer)>&& func) const {
VkCommandBufferAllocateInfo allocInfo{ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; VkCommandBufferAllocateInfo allocInfo{ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
allocInfo.commandPool = commandPool; // Use a pool created with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT allocInfo.commandPool = frames[currentFrame].commandPool; // Use a pool created with VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = 1; allocInfo.commandBufferCount = 1;
@ -643,7 +651,7 @@ void Renderer::immediate_submit(std::function<void(VkCommandBuffer)>&& func) con
vkQueueSubmit(graphics_queue, 1, &submit, VK_NULL_HANDLE); vkQueueSubmit(graphics_queue, 1, &submit, VK_NULL_HANDLE);
vkQueueWaitIdle(graphics_queue); vkQueueWaitIdle(graphics_queue);
vkFreeCommandBuffers(device, commandPool, 1, &cmd); vkFreeCommandBuffers(device, frames[currentFrame].commandPool, 1, &cmd);
} }
void Renderer::transition_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) const { void Renderer::transition_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) const {
@ -690,9 +698,7 @@ VkImageView Renderer::create_image_view(VkImage image, VkFormat format) const {
viewInfo.subresourceRange.layerCount = 1; viewInfo.subresourceRange.layerCount = 1;
VkImageView view; VkImageView view;
if (vkCreateImageView(device, &viewInfo, nullptr, &view) != VK_SUCCESS) { vkCreateImageView(device, &viewInfo, nullptr, &view);
throw std::runtime_error("failed to create image view!");
}
return view; return view;
} }
@ -717,7 +723,5 @@ void Renderer::create_default_sampler() {
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
if (vkCreateSampler(device, &samplerInfo, nullptr, &defaultSampler) != VK_SUCCESS) { vkCreateSampler(device, &samplerInfo, nullptr, &defaultSampler);
throw std::runtime_error("failed to create texture sampler!");
}
} }

View File

@ -5,6 +5,7 @@
#ifndef V_RENDERER_H #ifndef V_RENDERER_H
#define V_RENDERER_H #define V_RENDERER_H
#include "init.h"
#include <volk/volk.h> #include <volk/volk.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -22,17 +23,6 @@ enum class PROJECTION_TYPE : uint8_t {
COUNT, COUNT,
}; };
struct vertex_p2_col4 {
glm::vec2 pos;
glm::vec4 col;
};
struct vertex_p2_st2_col4 {
glm::vec2 pos;
glm::vec2 st;
glm::vec4 col;
};
struct vertex_p2_st2_col4_a1_u32 { struct vertex_p2_st2_col4_a1_u32 {
glm::vec2 pos; glm::vec2 pos;
glm::vec2 st; glm::vec2 st;
@ -55,21 +45,6 @@ struct vertex_p2_st2_col4_a1_u32 {
} }
}; };
struct vertex_st2 {
glm::vec2 st;
};
struct vertex_p2_scale2_rot1_st2 {
glm::vec2 pos;
glm::vec2 scale;
float rot;
glm::vec2 st;
};
typedef vertex_st2 quad_st2[6];
typedef vertex_p2_scale2_rot1_st2 quad_pos2_scale2_rot1_st2[6];
// commands // commands
enum class PipelineType : uint8_t { enum class PipelineType : uint8_t {
@ -140,7 +115,7 @@ struct RenderCommand {
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
struct Renderer { struct Renderer {
std::vector<RenderCommand> commands; std::vector<RenderCommand> commands{};
void begin_frame(); void begin_frame();
void end_frame(); void end_frame();
@ -163,47 +138,40 @@ struct Renderer {
void transition_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) const; void transition_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout) const;
VkImageView create_image_view(VkImage image, VkFormat format) const; VkImageView create_image_view(VkImage image, VkFormat format) const;
VkDescriptorSetLayout descriptor_set_layout; VkDescriptorSetLayout descriptor_set_layout{};
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout{};
VkPipeline textured_quad_pipeline; VkPipeline textured_quad_pipeline{};
VkPipeline colored_quad_pipeline; VkPipeline colored_quad_pipeline{};
VkPipeline line_pipeline; VkPipeline line_pipeline{};
VkPipeline text_pipeline; VkPipeline text_pipeline{};
VkPipeline chunk_pipeline; VkPipeline chunk_pipeline{};
VkDescriptorSet set; VkDescriptorSet set{};
VkSampler defaultSampler; VkSampler defaultSampler{};
uint32_t nextTextureSlot = 0; uint32_t nextTextureSlot = 0;
VkCommandPool commandPool;
static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2;
static constexpr uint32_t MAX_VERTICES_PER_FRAME = 65536;
struct Frame { struct Frame {
VkCommandPool commandPool{};
VkCommandBuffer command_buffer{}; VkCommandBuffer command_buffer{};
VkSemaphore imageAvailable{}; VkSemaphore imageAvailable{};
VkSemaphore renderFinished{}; VkFence in_flight_fence{};
}; };
Frame frames[MAX_FRAMES_IN_FLIGHT]; std::vector<Frame> frames;
uint32_t currentFrame = 0; uint32_t currentFrame = 0;
VkSemaphore timelineSemaphore{}; VkBuffer vertexBuffer{};
uint64_t frameValue = 0; VmaAllocation vertexAllocation{};
VmaAllocationInfo vertexAllocInfo{};
VkBuffer vertexBuffer; VkDescriptorPool descriptorPool{};
VmaAllocation vertexAllocation; std::vector<VkDescriptorSet> textureSets{};
VmaAllocationInfo vertexAllocInfo;
VkDescriptorPool descriptorPool;
std::vector<VkDescriptorSet> textureSets;
VkPipeline get_pipeline(PipelineType type) const; VkPipeline get_pipeline(PipelineType type) const;
void bind_material(VkCommandBuffer cmd, uint16_t materialID); // void bind_material(VkCommandBuffer cmd, uint16_t materialID);
void create_descriptor_pool(); void create_descriptor_pool();
VkDescriptorSet create_texture_descriptor(VkImageView imageView, VkSampler sampler);
void update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler); void update_bindless_slot(uint32_t slot, VkImageView view, VkSampler sampler);
// Returns the resource info so the Manager can store it // Returns the resource info so the Manager can store it

View File

@ -3,6 +3,7 @@
// //
#include "swapchain.h" #include "swapchain.h"
#include <print>
void createSwapchain(GLFWwindow* window) { void createSwapchain(GLFWwindow* window) {
int fbWidth, fbHeight; int fbWidth, fbHeight;
@ -13,10 +14,24 @@ void createSwapchain(GLFWwindow* window) {
static_cast<uint32_t>(fbHeight) static_cast<uint32_t>(fbHeight)
}; };
VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR,
.pNext = nullptr,
.surface = surface,
};
VkSurfaceCapabilities2KHR surfCapabilities{
.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR,
};
vkGetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, &surfaceInfo, &surfCapabilities);
MAX_FRAMES_IN_FLIGHT = std::min(surfCapabilities.surfaceCapabilities.minImageCount + 1, surfCapabilities.surfaceCapabilities.maxImageCount);
const VkSwapchainCreateInfoKHR sci{ const VkSwapchainCreateInfoKHR sci{
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.surface = surface, .surface = surface,
.minImageCount = 2, .minImageCount = MAX_FRAMES_IN_FLIGHT,
.imageFormat = swapchain_format.format, .imageFormat = swapchain_format.format,
.imageColorSpace = swapchain_format.colorSpace, .imageColorSpace = swapchain_format.colorSpace,
.imageExtent = swapchain_extent, .imageExtent = swapchain_extent,
@ -33,6 +48,7 @@ void createSwapchain(GLFWwindow* window) {
uint32_t imgCount; uint32_t imgCount;
vkGetSwapchainImagesKHR(device, swapchain, &imgCount, nullptr); vkGetSwapchainImagesKHR(device, swapchain, &imgCount, nullptr);
std::print("imgCount: {}", imgCount);
images = std::vector<VkImage>(imgCount); images = std::vector<VkImage>(imgCount);
vkGetSwapchainImagesKHR(device, swapchain, &imgCount, images.data()); vkGetSwapchainImagesKHR(device, swapchain, &imgCount, images.data());
@ -43,6 +59,12 @@ void createSwapchain(GLFWwindow* window) {
imageViews = std::vector<VkImageView>(imgCount); imageViews = std::vector<VkImageView>(imgCount);
const VkSemaphoreCreateInfo seci{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
};
renderFinished.resize(imgCount);
for (uint32_t i = 0; i < imgCount; i++) { for (uint32_t i = 0; i < imgCount; i++) {
VkImageViewCreateInfo ivci{}; VkImageViewCreateInfo ivci{};
ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
@ -60,5 +82,7 @@ void createSwapchain(GLFWwindow* window) {
ivci.subresourceRange.layerCount = 1; ivci.subresourceRange.layerCount = 1;
vkCreateImageView(device, &ivci, nullptr, &imageViews[i]); vkCreateImageView(device, &ivci, nullptr, &imageViews[i]);
vkCreateSemaphore(device, &seci, nullptr, &renderFinished[i]);
} }
} }

View File

@ -14,6 +14,7 @@ inline VkSurfaceFormatKHR swapchain_format{
VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM,
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR VK_COLOR_SPACE_SRGB_NONLINEAR_KHR
}; };
inline std::vector<VkSemaphore> renderFinished;
inline std::vector<VkImage> images; inline std::vector<VkImage> images;
inline std::vector<VkImageView> imageViews; inline std::vector<VkImageView> imageViews;

View File

@ -10,7 +10,7 @@
#include "texture.h" #include "texture.h"
constexpr std::string TEXTURE_SHEETS_PATH = "data/texture_sheets"; inline const std::string TEXTURE_SHEETS_PATH = "data/texture_sheets";
typedef std::string texture_cell_id; typedef std::string texture_cell_id;
typedef std::string texture_sheet_id; typedef std::string texture_sheet_id;

View File

@ -11,5 +11,5 @@ layout(location = 0) out vec4 out_color;
void main() { void main() {
// outColor = texture(texSamplers[nonuniformEXT(tex_id)], uv) * color; // outColor = texture(texSamplers[nonuniformEXT(tex_id)], uv) * color;
out_color = color; out_color = vec4(1);
} }

Binary file not shown.

View File

@ -9,8 +9,6 @@ struct Vertex {
uint textureID; uint textureID;
}; };
layout(set = 0, binding = 0) uniform sampler2D globalTextures[];
layout(std430, set = 0, binding = 1) readonly buffer VertexBuffer { layout(std430, set = 0, binding = 1) readonly buffer VertexBuffer {
Vertex vertices[]; Vertex vertices[];
} vBuf; } vBuf;
@ -21,16 +19,6 @@ layout(location = 2) out flat uint tex_id;
void main() { void main() {
Vertex testVertices[6] = Vertex[](
Vertex(vec2(-0.5, -0.5), vec2(0.0, 0.0), vec4(1.0, 0.0, 0.0, 1.0), 1.0, 0),
Vertex(vec2( 0.5, -0.5), vec2(1.0, 0.0), vec4(0.0, 1.0, 0.0, 1.0), 1.0, 0),
Vertex(vec2(-0.5, 0.5), vec2(0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0), 1.0, 0),
Vertex(vec2( 0.5, 0.5), vec2(1.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), 1.0, 0),
Vertex(vec2(-0.5, 0.5), vec2(0.0, 1.0), vec4(0.0, 0.0, 1.0, 1.0), 1.0, 0),
Vertex(vec2( 0.5, -0.5), vec2(1.0, 1.0), vec4(0.0, 1.0, 0.0, 1.0), 1.0, 0)
);
Vertex v = vBuf.vertices[gl_VertexIndex]; Vertex v = vBuf.vertices[gl_VertexIndex];
uv = v.uv; uv = v.uv;

Binary file not shown.