diff --git a/aster/CMakeLists.txt b/aster/CMakeLists.txt index 5e30339..9522cf3 100644 --- a/aster/CMakeLists.txt +++ b/aster/CMakeLists.txt @@ -20,7 +20,8 @@ set(HEADER_FILES physical_device.h device.h swapchain.h - "pipeline.h") + "pipeline.h" + queue_allocation.h) set(SOURCE_FILES logger.cpp @@ -37,7 +38,7 @@ set_property(TARGET aster_core PROPERTY CXX_STANDARD 20) target_precompile_headers(aster_core PUBLIC global.h) -target_include_directories(aster_core PUBLIC ${CMAKE_SOURCE_DIR}) +target_include_directories(aster_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(aster_core PUBLIC glm::glm-header-only) target_link_libraries(aster_core PRIVATE glfw) diff --git a/aster/device.cpp b/aster/device.cpp index 1f4e916..9e74b45 100644 --- a/aster/device.cpp +++ b/aster/device.cpp @@ -7,6 +7,7 @@ #include "context.h" #include "physical_device.h" +#include "queue_allocation.h" #include #include diff --git a/aster/device.h b/aster/device.h index b757935..b1082c6 100644 --- a/aster/device.h +++ b/aster/device.h @@ -9,15 +9,10 @@ #include +struct QueueAllocation; struct Context; struct PhysicalDevice; -struct QueueAllocation -{ - u32 m_Family; - u32 m_Count; -}; - struct Features { vk::PhysicalDeviceFeatures m_Vulkan10Features; diff --git a/aster/queue_allocation.h b/aster/queue_allocation.h new file mode 100644 index 0000000..eed18a1 --- /dev/null +++ b/aster/queue_allocation.h @@ -0,0 +1,14 @@ +// ============================================= +// Aster: queue_allocation.h +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#pragma once + +#include "global.h" + +struct QueueAllocation +{ + u32 m_Family; + u32 m_Count; +}; \ No newline at end of file diff --git a/samples/00_util/CMakeLists.txt b/samples/00_util/CMakeLists.txt new file mode 100644 index 0000000..bd190b5 --- /dev/null +++ b/samples/00_util/CMakeLists.txt @@ -0,0 +1,8 @@ +# CMakeList.txt ; CMake project for Triangle + +cmake_minimum_required(VERSION 3.13) + +add_library(util_helper STATIC helpers.h helpers.cpp) + +target_link_libraries(util_helper PRIVATE aster_core) +target_include_directories(util_helper PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/samples/00_util/helpers.cpp b/samples/00_util/helpers.cpp new file mode 100644 index 0000000..9e0e60d --- /dev/null +++ b/samples/00_util/helpers.cpp @@ -0,0 +1,90 @@ +// ============================================= +// Aster: helpers.cpp +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#include "helpers.h" + +#include "device.h" +#include "physical_device.h" + +#include + +constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT = QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | + QueueSupportFlagBits::eCompute | QueueSupportFlagBits::ePresent | + QueueSupportFlagBits::eTransfer; + +bool +IsSuitableDevice(const PhysicalDevice *physicalDevice) +{ + const bool hasAllRequiredQueues = + std::ranges::any_of(physicalDevice->m_QueueFamilies, [](const auto &queueFamilyProp) { + return (queueFamilyProp.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT; + }); + + const bool isNotCpu = physicalDevice->m_DeviceProperties.deviceType != vk::PhysicalDeviceType::eCpu; + + const bool hasPresentMode = !physicalDevice->m_PresentModes.empty(); + + const bool hasSurfaceFormat = !physicalDevice->m_SurfaceFormats.empty(); + + return hasSurfaceFormat && hasPresentMode && isNotCpu && hasAllRequiredQueues; +} + +PhysicalDevice +FindSuitableDevice(const PhysicalDevices &physicalDevices) +{ + for (auto &physicalDevice : physicalDevices) + { + if (IsSuitableDevice(&physicalDevice)) + { + return physicalDevice; + } + } + + ERROR("No suitable GPU available on the system.") + THEN_ABORT(vk::Result::eErrorUnknown); +} + +QueueAllocation +FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice) +{ + for (auto &queueFamilyInfo : physicalDevice->m_QueueFamilies) + { + if ((queueFamilyInfo.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT) + { + return { + .m_Family = queueFamilyInfo.m_Index, + .m_Count = queueFamilyInfo.m_Count, + }; + } + } + ERROR("No suitable queue family on the GPU.") + THEN_ABORT(vk::Result::eErrorUnknown); +} + +eastl::vector +ReadFile(cstr fileName) +{ + FILE *filePtr = fopen(fileName, "rb"); + + if (!filePtr) + { + ERROR("Invalid read of {}", fileName) THEN_ABORT(-1); + } + + eastl::vector outputVec; + eastl::array buffer{}; + usize totalRead = 0; + usize readCount; + do + { + readCount = fread(buffer.data(), sizeof(u32), buffer.size(), filePtr); + const auto nextSize = totalRead + readCount; + outputVec.resize(nextSize); + memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data()); + totalRead = nextSize; + } while (readCount == 1024); + + return outputVec; +} \ No newline at end of file diff --git a/samples/00_util/helpers.h b/samples/00_util/helpers.h new file mode 100644 index 0000000..99c12db --- /dev/null +++ b/samples/00_util/helpers.h @@ -0,0 +1,18 @@ +// ============================================= +// Aster: helpers.h +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#pragma once + +#include "global.h" + +#include "queue_allocation.h" +#include + +struct PhysicalDevice; +class PhysicalDevices; + +PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices); +QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice); +eastl::vector ReadFile(cstr fileName); \ No newline at end of file diff --git a/samples/01_triangle/CMakeLists.txt b/samples/01_triangle/CMakeLists.txt index 30f6efb..168266a 100644 --- a/samples/01_triangle/CMakeLists.txt +++ b/samples/01_triangle/CMakeLists.txt @@ -3,9 +3,8 @@ cmake_minimum_required(VERSION 3.13) add_executable(triangle "triangle.cpp") -add_dependencies(triangle aster_core) - add_shader(triangle shader/triangle.vs.hlsl) -add_shader(triangle shader/white.frag.glsl) +add_shader(triangle shader/triangle.frag.glsl) target_link_libraries(triangle PRIVATE aster_core) +target_link_libraries(triangle PRIVATE util_helper) diff --git a/samples/01_triangle/shader/white.frag.glsl b/samples/01_triangle/shader/triangle.frag.glsl similarity index 100% rename from samples/01_triangle/shader/white.frag.glsl rename to samples/01_triangle/shader/triangle.frag.glsl diff --git a/samples/01_triangle/triangle.cpp b/samples/01_triangle/triangle.cpp index afc632e..f0c0992 100644 --- a/samples/01_triangle/triangle.cpp +++ b/samples/01_triangle/triangle.cpp @@ -3,27 +3,26 @@ // Copyright (c) 2020-2024 Anish Bhobe // ============================================= -#include "aster/constants.h" -#include "aster/context.h" -#include "aster/device.h" -#include "aster/physical_device.h" -#include "aster/window.h" +#include "constants.h" +#include "context.h" +#include "device.h" +#include "physical_device.h" +#include "window.h" -#include "aster/global.h" -#include "aster/pipeline.h" -#include "aster/swapchain.h" +#include "global.h" +#include "pipeline.h" +#include "swapchain.h" + +#include "helpers.h" #include constexpr u32 MAX_FRAMES_IN_FLIGHT = 3; constexpr auto VERTEX_SHADER_FILE = "shader/triangle.vs.hlsl.spv"; -constexpr auto FRAGMENT_SHADER_FILE = "shader/white.frag.glsl.spv"; +constexpr auto FRAGMENT_SHADER_FILE = "shader/triangle.frag.glsl.spv"; -bool IsSuitableDevice(const PhysicalDevice *physicalDevice); -PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices); -QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice); -eastl::vector ReadFile(cstr fileName); vk::ShaderModule CreateShader(const Device *device, cstr shaderFile); +Pipeline CreatePipeline(const Device *device, const Swapchain *swapchain); struct Frame { @@ -39,15 +38,6 @@ struct Frame [[nodiscard]] vk::CommandBuffer AllocateCommandBuffer() const; }; -struct Shader -{ - vk::ShaderModule m_ShaderModule; - vk::ShaderStageFlags m_Stage; -}; - -Pipeline -CreatePipeline(const Device *device, const Swapchain *swapchain, cstr vertexShaderFile, cstr fragmentShaderFile); - int main(int, char **) { @@ -69,7 +59,7 @@ main(int, char **) Swapchain swapchain = {&window, &device, "Primary Chain"}; - Pipeline pipeline = CreatePipeline(&device, &swapchain, VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE); + Pipeline pipeline = CreatePipeline(&device, &swapchain); // Persistent variables vk::Viewport viewport = { @@ -259,68 +249,6 @@ main(int, char **) return 0; } -constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT = QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | - QueueSupportFlagBits::eCompute | QueueSupportFlagBits::ePresent | - QueueSupportFlagBits::eTransfer; - -PhysicalDevice -FindSuitableDevice(const PhysicalDevices &physicalDevices) -{ - for (auto &physicalDevice : physicalDevices) - { - if (IsSuitableDevice(&physicalDevice)) - { - return physicalDevice; - } - } - - ERROR("No suitable GPU available on the system.") - THEN_ABORT(vk::Result::eErrorUnknown); -} - -QueueAllocation -FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice) -{ - for (auto &queueFamilyInfo : physicalDevice->m_QueueFamilies) - { - if ((queueFamilyInfo.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT) - { - return { - .m_Family = queueFamilyInfo.m_Index, - .m_Count = queueFamilyInfo.m_Count, - }; - } - } - ERROR("No suitable queue family on the GPU.") - THEN_ABORT(vk::Result::eErrorUnknown); -} - -eastl::vector -ReadFile(cstr fileName) -{ - FILE *filePtr = fopen(fileName, "rb"); - - if (!filePtr) - { - ERROR("Invalid read of {}", fileName) THEN_ABORT(-1); - } - - eastl::vector outputVec; - eastl::array buffer{}; - usize totalRead = 0; - usize readCount; - do - { - readCount = fread(buffer.data(), sizeof(u32), buffer.size(), filePtr); - const auto nextSize = totalRead + readCount; - outputVec.resize(nextSize); - memcpy(outputVec.data() + totalRead, buffer.data(), readCount * sizeof *buffer.data()); - totalRead = nextSize; - } while (readCount == 1024); - - return outputVec; -} - Frame::Frame(const Device *device, const u32 queueFamilyIndex, const u32 frameCount) { m_Device = device; @@ -363,11 +291,11 @@ Frame::AllocateCommandBuffer() const return commandBuffer; } Pipeline -CreatePipeline(const Device *device, const Swapchain *swapchain, cstr vertexShaderFile, cstr fragmentShaderFile) +CreatePipeline(const Device *device, const Swapchain *swapchain) { // Pipeline Setup - auto vertexShaderModule = CreateShader(device, vertexShaderFile); - auto fragmentShaderModule = CreateShader(device, fragmentShaderFile); + auto vertexShaderModule = CreateShader(device, VERTEX_SHADER_FILE); + auto fragmentShaderModule = CreateShader(device, FRAGMENT_SHADER_FILE); eastl::array shaderStages = {{ { @@ -510,21 +438,4 @@ Frame::~Frame() m_Device->m_Device.destroy(m_Pool, nullptr); DEBUG("Destoryed Frame"); -} - -bool -IsSuitableDevice(const PhysicalDevice *physicalDevice) -{ - const bool hasAllRequiredQueues = - std::ranges::any_of(physicalDevice->m_QueueFamilies, [](const auto &queueFamilyProp) { - return (queueFamilyProp.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT; - }); - - const bool isNotCpu = physicalDevice->m_DeviceProperties.deviceType != vk::PhysicalDeviceType::eCpu; - - const bool hasPresentMode = !physicalDevice->m_PresentModes.empty(); - - const bool hasSurfaceFormat = !physicalDevice->m_SurfaceFormats.empty(); - - return hasSurfaceFormat && hasPresentMode && isNotCpu && hasAllRequiredQueues; } \ No newline at end of file diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 7e2c004..a3e353a 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -3,3 +3,6 @@ cmake_minimum_required(VERSION 3.13) add_subdirectory("01_triangle") +add_subdirectory("00_util") + +