Refactoring and extracting helpers.
This commit is contained in:
parent
d9b0e82be7
commit
0ca2779014
|
|
@ -20,7 +20,8 @@ set(HEADER_FILES
|
||||||
physical_device.h
|
physical_device.h
|
||||||
device.h
|
device.h
|
||||||
swapchain.h
|
swapchain.h
|
||||||
"pipeline.h")
|
"pipeline.h"
|
||||||
|
queue_allocation.h)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
logger.cpp
|
logger.cpp
|
||||||
|
|
@ -37,7 +38,7 @@ set_property(TARGET aster_core PROPERTY CXX_STANDARD 20)
|
||||||
|
|
||||||
target_precompile_headers(aster_core PUBLIC global.h)
|
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 PUBLIC glm::glm-header-only)
|
||||||
target_link_libraries(aster_core PRIVATE glfw)
|
target_link_libraries(aster_core PRIVATE glfw)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "physical_device.h"
|
#include "physical_device.h"
|
||||||
|
#include "queue_allocation.h"
|
||||||
|
|
||||||
#include <EASTL/array.h>
|
#include <EASTL/array.h>
|
||||||
#include <EASTL/fixed_vector.h>
|
#include <EASTL/fixed_vector.h>
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,10 @@
|
||||||
|
|
||||||
#include <EASTL/vector.h>
|
#include <EASTL/vector.h>
|
||||||
|
|
||||||
|
struct QueueAllocation;
|
||||||
struct Context;
|
struct Context;
|
||||||
struct PhysicalDevice;
|
struct PhysicalDevice;
|
||||||
|
|
||||||
struct QueueAllocation
|
|
||||||
{
|
|
||||||
u32 m_Family;
|
|
||||||
u32 m_Count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Features
|
struct Features
|
||||||
{
|
{
|
||||||
vk::PhysicalDeviceFeatures m_Vulkan10Features;
|
vk::PhysicalDeviceFeatures m_Vulkan10Features;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
@ -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})
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: helpers.cpp
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
#include "physical_device.h"
|
||||||
|
|
||||||
|
#include <EASTL/array.h>
|
||||||
|
|
||||||
|
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<u32>
|
||||||
|
ReadFile(cstr fileName)
|
||||||
|
{
|
||||||
|
FILE *filePtr = fopen(fileName, "rb");
|
||||||
|
|
||||||
|
if (!filePtr)
|
||||||
|
{
|
||||||
|
ERROR("Invalid read of {}", fileName) THEN_ABORT(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
eastl::vector<u32> outputVec;
|
||||||
|
eastl::array<u32, 1024> 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;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: helpers.h
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
|
#include "queue_allocation.h"
|
||||||
|
#include <EASTL/vector.h>
|
||||||
|
|
||||||
|
struct PhysicalDevice;
|
||||||
|
class PhysicalDevices;
|
||||||
|
|
||||||
|
PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices);
|
||||||
|
QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice);
|
||||||
|
eastl::vector<u32> ReadFile(cstr fileName);
|
||||||
|
|
@ -3,9 +3,8 @@
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
add_executable(triangle "triangle.cpp")
|
add_executable(triangle "triangle.cpp")
|
||||||
add_dependencies(triangle aster_core)
|
|
||||||
|
|
||||||
add_shader(triangle shader/triangle.vs.hlsl)
|
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 aster_core)
|
||||||
|
target_link_libraries(triangle PRIVATE util_helper)
|
||||||
|
|
|
||||||
|
|
@ -3,27 +3,26 @@
|
||||||
// Copyright (c) 2020-2024 Anish Bhobe
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|
||||||
#include "aster/constants.h"
|
#include "constants.h"
|
||||||
#include "aster/context.h"
|
#include "context.h"
|
||||||
#include "aster/device.h"
|
#include "device.h"
|
||||||
#include "aster/physical_device.h"
|
#include "physical_device.h"
|
||||||
#include "aster/window.h"
|
#include "window.h"
|
||||||
|
|
||||||
#include "aster/global.h"
|
#include "global.h"
|
||||||
#include "aster/pipeline.h"
|
#include "pipeline.h"
|
||||||
#include "aster/swapchain.h"
|
#include "swapchain.h"
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
#include <EASTL/array.h>
|
#include <EASTL/array.h>
|
||||||
|
|
||||||
constexpr u32 MAX_FRAMES_IN_FLIGHT = 3;
|
constexpr u32 MAX_FRAMES_IN_FLIGHT = 3;
|
||||||
constexpr auto VERTEX_SHADER_FILE = "shader/triangle.vs.hlsl.spv";
|
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<u32> ReadFile(cstr fileName);
|
|
||||||
vk::ShaderModule CreateShader(const Device *device, cstr shaderFile);
|
vk::ShaderModule CreateShader(const Device *device, cstr shaderFile);
|
||||||
|
Pipeline CreatePipeline(const Device *device, const Swapchain *swapchain);
|
||||||
|
|
||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
|
|
@ -39,15 +38,6 @@ struct Frame
|
||||||
[[nodiscard]] vk::CommandBuffer AllocateCommandBuffer() const;
|
[[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
|
int
|
||||||
main(int, char **)
|
main(int, char **)
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +59,7 @@ main(int, char **)
|
||||||
|
|
||||||
Swapchain swapchain = {&window, &device, "Primary Chain"};
|
Swapchain swapchain = {&window, &device, "Primary Chain"};
|
||||||
|
|
||||||
Pipeline pipeline = CreatePipeline(&device, &swapchain, VERTEX_SHADER_FILE, FRAGMENT_SHADER_FILE);
|
Pipeline pipeline = CreatePipeline(&device, &swapchain);
|
||||||
|
|
||||||
// Persistent variables
|
// Persistent variables
|
||||||
vk::Viewport viewport = {
|
vk::Viewport viewport = {
|
||||||
|
|
@ -259,68 +249,6 @@ main(int, char **)
|
||||||
return 0;
|
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<u32>
|
|
||||||
ReadFile(cstr fileName)
|
|
||||||
{
|
|
||||||
FILE *filePtr = fopen(fileName, "rb");
|
|
||||||
|
|
||||||
if (!filePtr)
|
|
||||||
{
|
|
||||||
ERROR("Invalid read of {}", fileName) THEN_ABORT(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
eastl::vector<u32> outputVec;
|
|
||||||
eastl::array<u32, 1024> 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)
|
Frame::Frame(const Device *device, const u32 queueFamilyIndex, const u32 frameCount)
|
||||||
{
|
{
|
||||||
m_Device = device;
|
m_Device = device;
|
||||||
|
|
@ -363,11 +291,11 @@ Frame::AllocateCommandBuffer() const
|
||||||
return commandBuffer;
|
return commandBuffer;
|
||||||
}
|
}
|
||||||
Pipeline
|
Pipeline
|
||||||
CreatePipeline(const Device *device, const Swapchain *swapchain, cstr vertexShaderFile, cstr fragmentShaderFile)
|
CreatePipeline(const Device *device, const Swapchain *swapchain)
|
||||||
{
|
{
|
||||||
// Pipeline Setup
|
// Pipeline Setup
|
||||||
auto vertexShaderModule = CreateShader(device, vertexShaderFile);
|
auto vertexShaderModule = CreateShader(device, VERTEX_SHADER_FILE);
|
||||||
auto fragmentShaderModule = CreateShader(device, fragmentShaderFile);
|
auto fragmentShaderModule = CreateShader(device, FRAGMENT_SHADER_FILE);
|
||||||
|
|
||||||
eastl::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = {{
|
eastl::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = {{
|
||||||
{
|
{
|
||||||
|
|
@ -510,21 +438,4 @@ Frame::~Frame()
|
||||||
m_Device->m_Device.destroy(m_Pool, nullptr);
|
m_Device->m_Device.destroy(m_Pool, nullptr);
|
||||||
|
|
||||||
DEBUG("Destoryed Frame");
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
@ -3,3 +3,6 @@
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
add_subdirectory("01_triangle")
|
add_subdirectory("01_triangle")
|
||||||
|
add_subdirectory("00_util")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue