Added automatic shader inclusion.
Continued pipeline creation
This commit is contained in:
parent
ec2955436d
commit
49963f3425
@ -91,7 +91,7 @@ endfunction()
|
||||
|
||||
# A function to automate executables aditions
|
||||
function ( addBinary BINARY_NAME )
|
||||
cmake_parse_arguments ( BINARY "IMGUI" "SOURCE" "SHADERS;SLANG_SHADERS;LIBS;TEXTURES;MODELS" ${ARGN} )
|
||||
cmake_parse_arguments ( BINARY "IMGUI;LICENSE" "SOURCE" "SHADERS;SLANG_SHADERS;LIBS;TEXTURES;MODELS" ${ARGN} )
|
||||
if (DEFINED BINARY_SOURCE)
|
||||
add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp )
|
||||
endif()
|
||||
@ -134,31 +134,43 @@ function ( addBinary BINARY_NAME )
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BINARY_LICENSE)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME})
|
||||
endif()
|
||||
|
||||
|
||||
if(DEFINED BINARY_SHADERS)
|
||||
set(SHADER_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${BINARY_NAME}/shaders)
|
||||
set(ALL_SPV_FILES "")
|
||||
foreach(SHADER_SRC ${BINARY_SHADERS})
|
||||
set(EXPANDED_SHADERS "")
|
||||
|
||||
foreach(SHADER_PATTERN ${BINARY_SHADERS})
|
||||
if(SHADER_PATTERN MATCHES "[*?]")
|
||||
file(GLOB SHADER_FILES CONFIGURE_DEPENDS ${SHADER_PATTERN})
|
||||
list(APPEND EXPANDED_SHADERS ${SHADER_FILES})
|
||||
else()
|
||||
list(APPEND EXPANDED_SHADERS ${SHADER_PATTERN})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(SHADER_SRC ${EXPANDED_SHADERS})
|
||||
if(NOT IS_ABSOLUTE ${SHADER_SRC})
|
||||
set(SHADER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_SRC})
|
||||
endif()
|
||||
get_filename_component(EXT ${SHADER_SRC} EXT)
|
||||
if(EXT STREQUAL ".slang")
|
||||
addSlangShader(${SHADER_SRC} "${BINARY_SLANG_ENTRIES}" ${SHADER_OUTPUT_DIR})
|
||||
list(APPEND ALL_SPV_FILES ${SPV_FILE})
|
||||
else()
|
||||
addGlslShader(${SHADER_SRC} ${SHADER_OUTPUT_DIR})
|
||||
list(APPEND ALL_SPV_FILES ${SPV_FILE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_custom_target(shaders_${BINARY_NAME} DEPENDS ${ALL_SPV_FILES})
|
||||
add_dependencies(${BINARY_NAME} shaders_${BINARY_NAME})
|
||||
endif()
|
||||
|
||||
if(DEFINED BINARY_SLANG_SHADERS)
|
||||
set(SLANG_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${BINARY_NAME}/shaders)
|
||||
if(NOT DEFINED BINARY_SLANG_ENTRIES)
|
||||
message(FATAL_ERROR "addBinary: SLANG_SHADERS nécessite SLANG_ENTRIES")
|
||||
endif()
|
||||
addSlangShader("${BINARY_SLANG_SHADERS}" "${BINARY_SLANG_ENTRIES}" ${SLANG_OUTPUT_DIR})
|
||||
add_custom_target(slang_shaders_${BINARY_NAME} DEPENDS ${SPV_FILE})
|
||||
add_dependencies(${BINARY_NAME} slang_shaders_${BINARY_NAME})
|
||||
endif()
|
||||
|
||||
if (DEFINED BINARY_LIBS)
|
||||
target_link_libraries ( ${BINARY_NAME} ${BINARY_LIBS} )
|
||||
endif()
|
||||
@ -192,17 +204,21 @@ function ( addBinary BINARY_NAME )
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
|
||||
# Scan the shader folder
|
||||
file(GLOB SHADER_SOURCES CONFIGURE_DEPENDS "shaders/*")
|
||||
|
||||
# Adds the main binary
|
||||
|
||||
addBinary (
|
||||
engine
|
||||
SOURCE Engine/main
|
||||
|
||||
SHADERS shaders/gradient.comp
|
||||
SHADERS shaders/gradient_color.comp
|
||||
SHADERS shaders/sky.comp
|
||||
SHADERS ${SHADER_SOURCES}
|
||||
SHADERS
|
||||
LIBS glfw fmt vk-bootstrap vulkan
|
||||
IMGUI
|
||||
LICENSE
|
||||
)
|
||||
|
||||
addBinary (
|
||||
|
||||
30
shaders/colored_triangle.slang
Normal file
30
shaders/colored_triangle.slang
Normal file
@ -0,0 +1,30 @@
|
||||
static float2 positions[3] = float2[](
|
||||
float2(0.0, -0.5),
|
||||
float2(0.5, 0.5),
|
||||
float2(-0.5, 0.5)
|
||||
);
|
||||
|
||||
static float3 colors[3] = float3[] (
|
||||
float3(1.0, 0.0, 0.0),
|
||||
float3(0.0, 1.0, 0.0),
|
||||
float3(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
struct VertexOutput {
|
||||
float3 color;
|
||||
float4 sv_position : SV_Position;
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VertexOutput vertMain(uint vid : SV_VertexID) {
|
||||
VertexOutput output;
|
||||
output.sv_position = float4(positions[vid], 0.0, 1.0);
|
||||
output.color = colors[vid];
|
||||
return output;
|
||||
}
|
||||
|
||||
[shader("fragment")]
|
||||
float4 fragMain(VertexOutput inVert) : SV_Target {
|
||||
float3 color = inVert.color;
|
||||
return float4(color, 1.0);
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
// Normal header
|
||||
|
||||
// Current progress
|
||||
// 3 - Graphics Pipeline - Setting up the render pipeline
|
||||
// 3 - Graphics Pipeline - Doing PipelineBuilder functions
|
||||
|
||||
#include "descriptors.h" // Required for public interface custom allocator
|
||||
#include "Common/Types.h"
|
||||
@ -18,7 +18,6 @@ struct FrameData {
|
||||
VkCommandPool _commandPool;
|
||||
VkCommandBuffer _mainCommandBuffer;
|
||||
VkSemaphore _swapchainSemaphore;
|
||||
VkSemaphore _renderSemaphore;
|
||||
VkFence _renderFence;
|
||||
DeletionQueue _deletionQueue;
|
||||
};
|
||||
@ -68,11 +67,15 @@ class Engine {
|
||||
|
||||
FrameData& getCurrentFrame() { return _frames[_frameNumber % FRAME_OVERLAP]; };
|
||||
|
||||
// Sync
|
||||
std::vector<VkSemaphore> _renderSemaphores; // It's size should be the number of swapchain images
|
||||
|
||||
VkQueue _graphicsQueue;
|
||||
uint32_t _graphicsQueueFamily;
|
||||
|
||||
// Deletion queue
|
||||
DeletionQueue _mainDeletionQueue;
|
||||
DeletionQueue _syncDeletionQueue;
|
||||
VmaAllocator _allocator;
|
||||
|
||||
// Draw resources
|
||||
@ -204,9 +207,15 @@ constexpr bool bUseValidationLayers = true;
|
||||
|
||||
void Engine::init() {
|
||||
#ifdef DEBUG
|
||||
std::ifstream infile("LICENSE");
|
||||
fmt::println("[Engine:Init] Initializing the engine...");
|
||||
fmt::println("[Engine:Info] Current engine version {}", BUILD_ID);
|
||||
fmt::println("[Engine:Info] Compiled on {} at {}", __DATE__ ,__TIME__);
|
||||
if (infile.good()) {
|
||||
std::string sLine;
|
||||
std::getline(infile, sLine);
|
||||
fmt::println("[Engine:Info] Current Licence : {}", sLine);
|
||||
}
|
||||
#endif
|
||||
|
||||
glfwInit();
|
||||
@ -241,12 +250,11 @@ void Engine::cleanup() {
|
||||
// Wait for the GPU to stop working
|
||||
vkDeviceWaitIdle(_device);
|
||||
|
||||
_syncDeletionQueue.flush();
|
||||
|
||||
for (int i = 0; i < FRAME_OVERLAP; i++) {
|
||||
vkDestroyCommandPool(_device, _frames[i]._commandPool, nullptr);
|
||||
// Destroy sync objects
|
||||
vkDestroyFence(_device, _frames[i]._renderFence, nullptr);
|
||||
vkDestroySemaphore(_device, _frames[i]._renderSemaphore, nullptr);
|
||||
vkDestroySemaphore(_device, _frames[i]._swapchainSemaphore, nullptr);
|
||||
// Sync objects
|
||||
|
||||
// Uses the deletion queue to clear ressources
|
||||
_frames[i]._deletionQueue.flush();
|
||||
@ -302,6 +310,8 @@ void Engine::draw() {
|
||||
uint32_t swapchainImageIndex;
|
||||
VkResult aquireResult {vkAcquireNextImageKHR(_device, _swapchain, UINT64_MAX, getCurrentFrame()._swapchainSemaphore, nullptr, &swapchainImageIndex)};
|
||||
|
||||
VkSemaphore renderSemaphore = _renderSemaphores[swapchainImageIndex];
|
||||
|
||||
if (aquireResult == VK_SUBOPTIMAL_KHR || aquireResult == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||
// Recreate swapchain
|
||||
_requestResize = true;
|
||||
@ -388,7 +398,7 @@ void Engine::draw() {
|
||||
VkCommandBufferSubmitInfo cmdinfo = vkinit::commandBufferSubmitInfo(cmd);
|
||||
|
||||
VkSemaphoreSubmitInfo waitInfo = vkinit::semaphoreSubmitInfo(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, getCurrentFrame()._swapchainSemaphore);
|
||||
VkSemaphoreSubmitInfo signalInfo = vkinit::semaphoreSubmitInfo(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, getCurrentFrame()._renderSemaphore);
|
||||
VkSemaphoreSubmitInfo signalInfo = vkinit::semaphoreSubmitInfo(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, renderSemaphore);
|
||||
|
||||
VkSubmitInfo2 submit = vkinit::submitInfo(&cmdinfo, &signalInfo, &waitInfo);
|
||||
|
||||
@ -400,7 +410,7 @@ void Engine::draw() {
|
||||
presentInfo.pSwapchains = &_swapchain;
|
||||
presentInfo.swapchainCount = 1;
|
||||
|
||||
presentInfo.pWaitSemaphores = &getCurrentFrame()._renderSemaphore;
|
||||
presentInfo.pWaitSemaphores = &renderSemaphore;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
|
||||
presentInfo.pImageIndices = &swapchainImageIndex;
|
||||
@ -703,16 +713,33 @@ void Engine::initSyncStructures() {
|
||||
fmt::println("[Engine:Init] Creating sync structures...");
|
||||
#endif
|
||||
|
||||
VkFenceCreateInfo fenceCreateInfo = vkinit::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||
// Render semaphores, depends on swapchain
|
||||
_renderSemaphores.resize(_swapchainImages.size());
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vkinit::semaphoreCreateInfo();
|
||||
|
||||
for (size_t i = 0; i < _renderSemaphores.size(); ++i) {
|
||||
VK_CHECK(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_renderSemaphores[i]));
|
||||
|
||||
_syncDeletionQueue.pushFunction([this, i]() {
|
||||
vkDestroySemaphore(_device, _renderSemaphores[i], nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
// Now, other sync objects, that depends on FRAME_OVERLAP
|
||||
VkFenceCreateInfo fenceCreateInfo = vkinit::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||
|
||||
for (int i = 0; i < FRAME_OVERLAP; i++) {
|
||||
VK_CHECK(vkCreateFence(_device, &fenceCreateInfo, nullptr, &_frames[i]._renderFence));
|
||||
|
||||
VK_CHECK(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_frames[i]._swapchainSemaphore));
|
||||
VK_CHECK(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_frames[i]._renderSemaphore));
|
||||
|
||||
_syncDeletionQueue.pushFunction([this, i]() {
|
||||
vkDestroyFence(_device, _frames[i]._renderFence, nullptr);
|
||||
vkDestroySemaphore(_device, _frames[i]._swapchainSemaphore, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Immediate sync objects
|
||||
VK_CHECK(
|
||||
vkCreateFence(
|
||||
@ -723,7 +750,7 @@ void Engine::initSyncStructures() {
|
||||
);
|
||||
);
|
||||
|
||||
_mainDeletionQueue.pushFunction([this]() {
|
||||
_syncDeletionQueue.pushFunction([this]() {
|
||||
vkDestroyFence(
|
||||
_device,
|
||||
_immFence,
|
||||
@ -1331,8 +1358,12 @@ void Engine::resizeSwapchain() {
|
||||
_windowExtent.width = w;
|
||||
_windowExtent.height = h;
|
||||
|
||||
|
||||
_syncDeletionQueue.flush();
|
||||
createSwapchain(_windowExtent.width, _windowExtent.height);
|
||||
|
||||
initSyncStructures();
|
||||
|
||||
_requestResize = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
@ -45,6 +45,29 @@ class PipelineBuilder {
|
||||
void setInputTopology(
|
||||
VkPrimitiveTopology topology
|
||||
);
|
||||
|
||||
void setPolygonMode(
|
||||
VkPolygonMode mode
|
||||
);
|
||||
|
||||
void setCullMode(
|
||||
VkCullModeFlags cullMode,
|
||||
VkFrontFace frontFace
|
||||
);
|
||||
|
||||
void setMultisamplingNone();
|
||||
|
||||
void disableBlending ();
|
||||
|
||||
void setColorAttachmentFormat(
|
||||
VkFormat format
|
||||
);
|
||||
|
||||
void setDepthFormat(
|
||||
VkFormat format
|
||||
);
|
||||
|
||||
void disableDepthtest();
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -265,5 +288,65 @@ void PipelineBuilder::setShaders(
|
||||
);
|
||||
}
|
||||
|
||||
void PipelineBuilder::setInputTopology(
|
||||
VkPrimitiveTopology topology
|
||||
) {
|
||||
_inputAssembly.topology = topology;
|
||||
// I am not going to use primitive restart rn
|
||||
// so I leave it on false
|
||||
_inputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||
}
|
||||
|
||||
void PipelineBuilder::setPolygonMode(
|
||||
VkPolygonMode mode
|
||||
) {
|
||||
_rasterizer.polygonMode = mode;
|
||||
_rasterizer.lineWidth = 1.0f;
|
||||
}
|
||||
|
||||
void PipelineBuilder::setCullMode(
|
||||
VkCullModeFlags cullMode,
|
||||
VkFrontFace frontFace
|
||||
) {
|
||||
_rasterizer.cullMode = cullMode;
|
||||
_rasterizer.frontFace = frontFace;
|
||||
}
|
||||
|
||||
void PipelineBuilder::setMultisamplingNone() {
|
||||
_multisampling.sampleShadingEnable = VK_FALSE;
|
||||
// Multisampling defaulted to no multisampling (1 sample per pixel)
|
||||
_multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
_multisampling.minSampleShading = 1.0f;
|
||||
_multisampling.pSampleMask = nullptr;
|
||||
// No alpha to coverage either
|
||||
_multisampling.alphaToCoverageEnable = VK_FALSE;
|
||||
_multisampling.alphaToOneEnable = VK_FALSE;
|
||||
}
|
||||
|
||||
void PipelineBuilder::disableBlending() {
|
||||
// Default write mask
|
||||
_colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
// No blending
|
||||
_colorBlendAttachment.blendEnable = VK_FALSE;
|
||||
}
|
||||
|
||||
void PipelineBuilder::setDepthFormat(
|
||||
VkFormat format
|
||||
) {
|
||||
_renderInfo.depthAttachmentFormat = format;
|
||||
}
|
||||
|
||||
void PipelineBuilder::disableDepthtest() {
|
||||
_depthStencil.depthTestEnable = VK_FALSE;
|
||||
_depthStencil.depthWriteEnable = VK_FALSE;
|
||||
_depthStencil.depthCompareOp = VK_COMPARE_OP_NEVER;
|
||||
_depthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||
_depthStencil.stencilTestEnable = VK_FALSE;
|
||||
_depthStencil.front = {};
|
||||
_depthStencil.back = {};
|
||||
_depthStencil.minDepthBounds = 0.0f;
|
||||
_depthStencil.maxDepthBounds = 1.0f;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -5,6 +5,9 @@
|
||||
int main(int argc, char* argv[]) {
|
||||
Engine engine;
|
||||
|
||||
// Exemple of overwriting a class value
|
||||
//engine._windowExtent = { 67, 67 };
|
||||
|
||||
engine.init();
|
||||
|
||||
engine.run();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user