192 lines
6.7 KiB
C++
192 lines
6.7 KiB
C++
// =============================================
|
|
// Aster: triangle.cpp
|
|
// Copyright (c) 2020-2025 Anish Bhobe
|
|
// =============================================
|
|
|
|
#include "aster/aster.h"
|
|
|
|
#include "aster/core/buffer.h"
|
|
#include "aster/core/constants.h"
|
|
#include "aster/core/instance.h"
|
|
#include "aster/core/physical_device.h"
|
|
#include "aster/core/pipeline.h"
|
|
#include "aster/core/swapchain.h"
|
|
#include "aster/core/window.h"
|
|
|
|
#include "aster/core/pipeline.h"
|
|
#include "aster/systems/rendering_device.h"
|
|
#include "aster/util/files.h"
|
|
#include "helpers.h"
|
|
|
|
#include <EASTL/array.h>
|
|
|
|
constexpr auto SHADER_MODULE = "triangle.slang";
|
|
|
|
struct Vertex
|
|
{
|
|
vec3 m_Position;
|
|
vec3 m_Color;
|
|
|
|
static eastl::vector<systems::AttributeInfo>
|
|
GetAttributes()
|
|
{
|
|
return {
|
|
{
|
|
.m_Location = 0,
|
|
.m_Offset = offsetof(Vertex, m_Position),
|
|
.m_Format = systems::AttributeInfo::Format::eFloat32X3,
|
|
},
|
|
{
|
|
.m_Location = 1,
|
|
.m_Offset = offsetof(Vertex, m_Color),
|
|
.m_Format = systems::AttributeInfo::Format::eFloat32X3,
|
|
},
|
|
};
|
|
}
|
|
};
|
|
|
|
int
|
|
main(int, char **)
|
|
{
|
|
MIN_LOG_LEVEL(Logger::LogType::eInfo);
|
|
|
|
Window window = {"Triangle (Aster)", {640, 480}};
|
|
systems::RenderingDevice device{{
|
|
.m_Window = window,
|
|
.m_Features = {.m_Vulkan12Features = {.bufferDeviceAddress = true},
|
|
.m_Vulkan13Features = {.synchronization2 = true, .dynamicRendering = true}},
|
|
.m_AppName = "Triangle",
|
|
.m_ShaderSearchPaths = {"shader/"},
|
|
.m_UseBindless = false,
|
|
.m_Name = "Primary",
|
|
}};
|
|
|
|
Pipeline pipeline;
|
|
auto pipelineError = device.CreateGraphicsPipeline(pipeline, {
|
|
.m_VertexInputs = {{
|
|
.m_Attribute = Vertex::GetAttributes(),
|
|
.m_Stride = sizeof(Vertex),
|
|
}},
|
|
.m_Shaders = {{
|
|
.m_ShaderFile = SHADER_MODULE,
|
|
.m_EntryPoints = {"vsmain", "fsmain"},
|
|
}},
|
|
});
|
|
ERROR_IF(pipelineError, "Error creating pipeline. Cause: {}", pipelineError.What());
|
|
|
|
// eastl::array<Vertex, 3> vertices{};
|
|
eastl::array vertices = {
|
|
Vertex{.m_Position = {-0.5f, -0.5f, 0.0f}, .m_Color = {1.0f, 0.0f, 0.0f}},
|
|
Vertex{.m_Position = {0.5f, -0.5f, 0.0f}, .m_Color = {0.0f, 1.0f, 0.0f}},
|
|
Vertex{.m_Position = {0.0f, 0.5f, 0.0f}, .m_Color = {0.0f, 0.0f, 1.0f}},
|
|
};
|
|
auto vbo = device.CreateVertexBuffer(vertices.size() * sizeof vertices[0], "VBO");
|
|
vbo->Write(0, vertices.size() * sizeof vertices[0], vertices.data());
|
|
|
|
// Persistent variables
|
|
|
|
vk::ImageSubresourceRange subresourceRange = {
|
|
.aspectMask = vk::ImageAspectFlagBits::eColor,
|
|
.baseMipLevel = 0,
|
|
.levelCount = 1,
|
|
.baseArrayLayer = 0,
|
|
.layerCount = 1,
|
|
};
|
|
vk::ImageMemoryBarrier2 topOfThePipeBarrier = {
|
|
.srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
|
.srcAccessMask = vk::AccessFlagBits2::eNone,
|
|
.dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
|
.dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
|
.oldLayout = vk::ImageLayout::eUndefined,
|
|
.newLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
|
.srcQueueFamilyIndex = vk::QueueFamilyIgnored,
|
|
.dstQueueFamilyIndex = vk::QueueFamilyIgnored,
|
|
.subresourceRange = subresourceRange,
|
|
};
|
|
vk::DependencyInfo topOfThePipeDependency = {
|
|
.imageMemoryBarrierCount = 1,
|
|
.pImageMemoryBarriers = &topOfThePipeBarrier,
|
|
};
|
|
vk::ImageMemoryBarrier2 renderToPresentBarrier = {
|
|
.srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput,
|
|
.srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite,
|
|
.dstStageMask = vk::PipelineStageFlagBits2::eBottomOfPipe,
|
|
.dstAccessMask = vk::AccessFlagBits2::eNone,
|
|
.oldLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
|
.newLayout = vk::ImageLayout::ePresentSrcKHR,
|
|
.srcQueueFamilyIndex = vk::QueueFamilyIgnored,
|
|
.dstQueueFamilyIndex = vk::QueueFamilyIgnored,
|
|
.subresourceRange = subresourceRange,
|
|
};
|
|
vk::DependencyInfo renderToPresentDependency = {
|
|
.imageMemoryBarrierCount = 1,
|
|
.pImageMemoryBarriers = &renderToPresentBarrier,
|
|
};
|
|
|
|
INFO("Starting loop");
|
|
while (window.Poll())
|
|
{
|
|
systems::Frame ¤tFrame = device.GetNextFrame();
|
|
|
|
Size2D swapchainSize = currentFrame.m_SwapchainSize;
|
|
|
|
vk::Viewport viewport = {
|
|
.x = 0,
|
|
.y = static_cast<f32>(swapchainSize.m_Height),
|
|
.width = static_cast<f32>(swapchainSize.m_Width),
|
|
.height = -static_cast<f32>(swapchainSize.m_Height),
|
|
.minDepth = 0.0,
|
|
.maxDepth = 1.0,
|
|
};
|
|
|
|
vk::Rect2D scissor = {
|
|
.offset = {0, 0},
|
|
.extent = static_cast<vk::Extent2D>(swapchainSize),
|
|
};
|
|
|
|
auto context = currentFrame.CreateGraphicsContext();
|
|
|
|
topOfThePipeBarrier.image = currentFrame.m_SwapchainImage;
|
|
renderToPresentBarrier.image = currentFrame.m_SwapchainImage;
|
|
|
|
context.Begin();
|
|
|
|
context.Dependency(topOfThePipeDependency);
|
|
|
|
// Render
|
|
vk::RenderingAttachmentInfo attachmentInfo = {
|
|
.imageView = currentFrame.m_SwapchainImageView,
|
|
.imageLayout = vk::ImageLayout::eColorAttachmentOptimal,
|
|
.resolveMode = vk::ResolveModeFlagBits::eNone,
|
|
.loadOp = vk::AttachmentLoadOp::eClear,
|
|
.storeOp = vk::AttachmentStoreOp::eStore,
|
|
.clearValue = vk::ClearColorValue{0.0f, 0.0f, 0.0f, 0.0f},
|
|
};
|
|
|
|
vk::RenderingInfo renderingInfo = {
|
|
.renderArea = scissor,
|
|
.layerCount = 1,
|
|
.colorAttachmentCount = 1,
|
|
.pColorAttachments = &attachmentInfo,
|
|
};
|
|
|
|
context.BeginRendering(renderingInfo);
|
|
|
|
context.SetViewport(viewport);
|
|
context.BindPipeline(pipeline);
|
|
context.BindVertexBuffer(vbo);
|
|
context.Draw(3);
|
|
|
|
context.EndRendering();
|
|
|
|
context.Dependency(renderToPresentDependency);
|
|
|
|
context.End();
|
|
|
|
device.Present(currentFrame, context);
|
|
}
|
|
|
|
device.WaitIdle();
|
|
|
|
return 0;
|
|
} |