Added Pipeline creation into the Device.
This commit is contained in:
parent
2facb3e6c1
commit
7507394af9
|
|
@ -16,6 +16,7 @@
|
||||||
#define VULKAN_HPP_DISABLE_ENHANCED_MODE 1
|
#define VULKAN_HPP_DISABLE_ENHANCED_MODE 1
|
||||||
#define VULKAN_HPP_NO_EXCEPTIONS 1
|
#define VULKAN_HPP_NO_EXCEPTIONS 1
|
||||||
#define VULKAN_HPP_NO_SMART_HANDLE 1
|
#define VULKAN_HPP_NO_SMART_HANDLE 1
|
||||||
|
#define VULKAN_HPP_NO_STRUCT_SETTERS 1
|
||||||
|
|
||||||
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
#define VMA_STATIC_VULKAN_FUNCTIONS 0
|
||||||
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@
|
||||||
#include "aster/core/image_view.h"
|
#include "aster/core/image_view.h"
|
||||||
#include "aster/core/instance.h"
|
#include "aster/core/instance.h"
|
||||||
#include "aster/core/physical_device.h"
|
#include "aster/core/physical_device.h"
|
||||||
|
#include "aster/core/pipeline.h"
|
||||||
#include "aster/core/sampler.h"
|
#include "aster/core/sampler.h"
|
||||||
#include "aster/core/swapchain.h"
|
#include "aster/core/swapchain.h"
|
||||||
#include "aster/core/pipeline.h"
|
|
||||||
|
|
||||||
#include <EASTL/hash_map.h>
|
#include <EASTL/hash_map.h>
|
||||||
#include <EASTL/optional.h>
|
#include <EASTL/optional.h>
|
||||||
|
|
@ -25,7 +25,6 @@
|
||||||
constexpr static u32 MAX_FRAMES_IN_FLIGHT = 3;
|
constexpr static u32 MAX_FRAMES_IN_FLIGHT = 3;
|
||||||
|
|
||||||
struct Window;
|
struct Window;
|
||||||
using CoreDevice = Device;
|
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct eastl::hash<vk::SamplerCreateInfo>
|
struct eastl::hash<vk::SamplerCreateInfo>
|
||||||
|
|
@ -226,7 +225,61 @@ struct SamplerCreateInfo
|
||||||
#pragma region Pipeline
|
#pragma region Pipeline
|
||||||
// ----------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// TODO
|
struct AttributeInfo
|
||||||
|
{
|
||||||
|
u32 m_Location;
|
||||||
|
u32 m_Offset;
|
||||||
|
enum class Format
|
||||||
|
{
|
||||||
|
eFloat32X4,
|
||||||
|
eFloat32X3,
|
||||||
|
eFloat32X2,
|
||||||
|
eFloat32,
|
||||||
|
} m_Format;
|
||||||
|
|
||||||
|
[[nodiscard]] vk::Format
|
||||||
|
GetFormat() const
|
||||||
|
{
|
||||||
|
switch (m_Format)
|
||||||
|
{
|
||||||
|
case Format::eFloat32X4:
|
||||||
|
return vk::Format::eR32G32B32A32Sfloat;
|
||||||
|
case Format::eFloat32X3:
|
||||||
|
return vk::Format::eR32G32B32Sfloat;
|
||||||
|
case Format::eFloat32X2:
|
||||||
|
return vk::Format::eR32G32Sfloat;
|
||||||
|
case Format::eFloat32:
|
||||||
|
return vk::Format::eR32Sfloat;
|
||||||
|
}
|
||||||
|
return vk::Format::eUndefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexInput
|
||||||
|
{
|
||||||
|
eastl::vector<AttributeInfo> m_Attribute;
|
||||||
|
u32 m_Stride;
|
||||||
|
bool m_IsPerInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GraphicsShaderModuleInfo
|
||||||
|
{
|
||||||
|
std::string_view m_ShaderFile;
|
||||||
|
std::string_view m_EntryPoint;
|
||||||
|
enum class Type
|
||||||
|
{
|
||||||
|
eVertex = vk::ShaderStageFlagBits::eVertex,
|
||||||
|
eFragment = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
eTesselationControl = vk::ShaderStageFlagBits::eTessellationControl,
|
||||||
|
eTesselationEvaluation = vk::ShaderStageFlagBits::eTessellationEvaluation,
|
||||||
|
} m_Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GraphicsPipelineCreateInfo
|
||||||
|
{
|
||||||
|
eastl::fixed_vector<VertexInput, 4, false> m_VertexInputs;
|
||||||
|
eastl::fixed_vector<GraphicsShaderModuleInfo, 4, false> m_ShaderModules;
|
||||||
|
};
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
|
|
@ -291,7 +344,7 @@ class GraphicsContext : public Context
|
||||||
public:
|
public:
|
||||||
DEPRECATE_RAW_CALLS void SetViewport(const vk::Viewport &viewport);
|
DEPRECATE_RAW_CALLS void SetViewport(const vk::Viewport &viewport);
|
||||||
void BindVertexBuffer(const Ref<VertexBuffer> &vertexBuffer);
|
void BindVertexBuffer(const Ref<VertexBuffer> &vertexBuffer);
|
||||||
DEPRECATE_RAW_CALLS void BindPipeline(vk::Pipeline pipeline);
|
void BindPipeline(const Pipeline &pipeline);
|
||||||
void Draw(u32 vertexCount);
|
void Draw(u32 vertexCount);
|
||||||
void DrawIndexed(u32 indexCount);
|
void DrawIndexed(u32 indexCount);
|
||||||
|
|
||||||
|
|
@ -311,8 +364,9 @@ struct Frame
|
||||||
vk::Semaphore m_RenderFinishSem;
|
vk::Semaphore m_RenderFinishSem;
|
||||||
u32 m_FrameIdx;
|
u32 m_FrameIdx;
|
||||||
|
|
||||||
|
eastl::vector<vk::CommandBuffer> m_CommandBuffers;
|
||||||
|
|
||||||
// Transient
|
// Transient
|
||||||
u32 m_ImageIdx;
|
|
||||||
vk::Image m_SwapchainImage;
|
vk::Image m_SwapchainImage;
|
||||||
vk::ImageView m_SwapchainImageView;
|
vk::ImageView m_SwapchainImageView;
|
||||||
u32 m_ImageIdx;
|
u32 m_ImageIdx;
|
||||||
|
|
@ -428,132 +482,13 @@ class Device final
|
||||||
// Pipeline
|
// Pipeline
|
||||||
// ----------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
// TODO: Cache shader modules for reuse. Time to move to `slang`
|
||||||
Pipeline CreatePipeline()
|
private:
|
||||||
{
|
vk::ShaderModule CreateShader(std::string_view shaderFile);
|
||||||
// Pipeline Setup
|
|
||||||
auto vertexShaderModule = CreateShader(device, VERTEX_SHADER_FILE);
|
|
||||||
auto fragmentShaderModule = CreateShader(device, FRAGMENT_SHADER_FILE);
|
|
||||||
|
|
||||||
eastl::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = {{
|
public:
|
||||||
{
|
// Pipelines, unlike the other resources, are not ref-counted.
|
||||||
.stage = vk::ShaderStageFlagBits::eVertex,
|
Pipeline CreatePipeline(const GraphicsPipelineCreateInfo &createInfo);
|
||||||
.module = vertexShaderModule,
|
|
||||||
.pName = "main",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.stage = vk::ShaderStageFlagBits::eFragment,
|
|
||||||
.module = fragmentShaderModule,
|
|
||||||
.pName = "main",
|
|
||||||
},
|
|
||||||
}};
|
|
||||||
|
|
||||||
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
|
|
||||||
.setLayoutCount = 0,
|
|
||||||
.pSetLayouts = nullptr,
|
|
||||||
.pushConstantRangeCount = 0,
|
|
||||||
.pPushConstantRanges = nullptr,
|
|
||||||
};
|
|
||||||
vk::PipelineLayout pipelineLayout;
|
|
||||||
vk::Result result = m_Device.m_Device.createPipelineLayout(&pipelineLayoutCreateInfo, nullptr, &pipelineLayout);
|
|
||||||
ERROR_IF(Failed(result), "Could not create a pipeline layout. Cause: {}", result) THEN_ABORT(result);
|
|
||||||
m_Device.SetName(pipelineLayout, "Triangle Layout");
|
|
||||||
|
|
||||||
vk::VertexInputBindingDescription inputBindingDescription = Vertex::GetBinding(0);
|
|
||||||
auto inputAttributeDescription = Vertex::GetAttributes(0);
|
|
||||||
|
|
||||||
vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
|
|
||||||
.vertexBindingDescriptionCount = 1,
|
|
||||||
.pVertexBindingDescriptions = &inputBindingDescription,
|
|
||||||
.vertexAttributeDescriptionCount = Cast<u32>(inputAttributeDescription.size()),
|
|
||||||
.pVertexAttributeDescriptions = inputAttributeDescription.data(),
|
|
||||||
};
|
|
||||||
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
|
|
||||||
.topology = vk::PrimitiveTopology::eTriangleList,
|
|
||||||
.primitiveRestartEnable = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineViewportStateCreateInfo viewportStateCreateInfo = {
|
|
||||||
.viewportCount = 1,
|
|
||||||
.scissorCount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
|
|
||||||
.depthClampEnable = false,
|
|
||||||
.rasterizerDiscardEnable = false,
|
|
||||||
.polygonMode = vk::PolygonMode::eFill,
|
|
||||||
.cullMode = vk::CullModeFlagBits::eNone,
|
|
||||||
.frontFace = vk::FrontFace::eCounterClockwise,
|
|
||||||
.depthBiasEnable = false,
|
|
||||||
.lineWidth = 1.0,
|
|
||||||
};
|
|
||||||
vk::PipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {
|
|
||||||
.rasterizationSamples = vk::SampleCountFlagBits::e1,
|
|
||||||
.sampleShadingEnable = false,
|
|
||||||
};
|
|
||||||
vk::PipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = {
|
|
||||||
.depthTestEnable = false,
|
|
||||||
.depthWriteEnable = false,
|
|
||||||
};
|
|
||||||
vk::PipelineColorBlendAttachmentState colorBlendAttachmentState = {
|
|
||||||
.blendEnable = false,
|
|
||||||
.srcColorBlendFactor = vk::BlendFactor::eSrcColor,
|
|
||||||
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcColor,
|
|
||||||
.colorBlendOp = vk::BlendOp::eAdd,
|
|
||||||
.srcAlphaBlendFactor = vk::BlendFactor::eSrcAlpha,
|
|
||||||
.dstAlphaBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
|
|
||||||
.alphaBlendOp = vk::BlendOp::eAdd,
|
|
||||||
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
|
||||||
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
|
||||||
};
|
|
||||||
vk::PipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
|
|
||||||
.logicOpEnable = false,
|
|
||||||
.attachmentCount = 1,
|
|
||||||
.pAttachments = &colorBlendAttachmentState,
|
|
||||||
};
|
|
||||||
|
|
||||||
eastl::array dynamicStates = {
|
|
||||||
vk::DynamicState::eScissor,
|
|
||||||
vk::DynamicState::eViewport,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
|
|
||||||
.dynamicStateCount = Cast<u32>(dynamicStates.size()),
|
|
||||||
.pDynamicStates = dynamicStates.data(),
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineRenderingCreateInfo renderingCreateInfo = {
|
|
||||||
.viewMask = 0,
|
|
||||||
.colorAttachmentCount = 1,
|
|
||||||
.pColorAttachmentFormats = &swapchain->m_Format,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::GraphicsPipelineCreateInfo pipelineCreateInfo = {
|
|
||||||
.pNext = &renderingCreateInfo,
|
|
||||||
.stageCount = Cast<u32>(shaderStages.size()),
|
|
||||||
.pStages = shaderStages.data(),
|
|
||||||
.pVertexInputState = &vertexInputStateCreateInfo,
|
|
||||||
.pInputAssemblyState = &inputAssemblyStateCreateInfo,
|
|
||||||
.pViewportState = &viewportStateCreateInfo,
|
|
||||||
.pRasterizationState = &rasterizationStateCreateInfo,
|
|
||||||
.pMultisampleState = &multisampleStateCreateInfo,
|
|
||||||
.pDepthStencilState = &depthStencilStateCreateInfo,
|
|
||||||
.pColorBlendState = &colorBlendStateCreateInfo,
|
|
||||||
.pDynamicState = &dynamicStateCreateInfo,
|
|
||||||
.layout = pipelineLayout,
|
|
||||||
};
|
|
||||||
vk::Pipeline pipeline;
|
|
||||||
result = m_Device.m_Device.createGraphicsPipelines(nullptr, 1, &pipelineCreateInfo, nullptr, &pipeline);
|
|
||||||
ERROR_IF(Failed(result), "Could not create a graphics pipeline. Cause: {}", result)
|
|
||||||
THEN_ABORT(result);
|
|
||||||
m_Device.SetName(pipeline, "Triangle Pipeline");
|
|
||||||
|
|
||||||
m_Device.m_Device.destroy(vertexShaderModule, nullptr);
|
|
||||||
m_Device.m_Device.destroy(fragmentShaderModule, nullptr);
|
|
||||||
|
|
||||||
return {&m_Device, pipelineLayout, pipeline, {}};
|
|
||||||
}
|
|
||||||
//*/
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Frames
|
// Frames
|
||||||
|
|
@ -590,7 +525,7 @@ class Device final
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] vk::Queue
|
[[nodiscard]] vk::Queue
|
||||||
GetQueue(u32 familyIndex, u32 queueIndex) const
|
GetQueue(const u32 familyIndex, const u32 queueIndex) const
|
||||||
{
|
{
|
||||||
return m_Device.GetQueue(familyIndex, queueIndex);
|
return m_Device.GetQueue(familyIndex, queueIndex);
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +545,7 @@ class Device final
|
||||||
// Inner
|
// Inner
|
||||||
// ----------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
[[nodiscard]] CoreDevice &
|
[[nodiscard]] ::Device &
|
||||||
GetInner()
|
GetInner()
|
||||||
{
|
{
|
||||||
return m_Device;
|
return m_Device;
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,5 @@ cmake_minimum_required(VERSION 3.13)
|
||||||
target_sources(aster_core
|
target_sources(aster_core
|
||||||
INTERFACE
|
INTERFACE
|
||||||
"logger.h"
|
"logger.h"
|
||||||
"freelist.h")
|
"freelist.h"
|
||||||
|
"files.h")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: files.h
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "aster/core/constants.h"
|
||||||
|
|
||||||
|
#include <EASTL/span.h>
|
||||||
|
#include <EASTL/vector.h>
|
||||||
|
|
||||||
|
eastl::vector<u32> ReadFile(std::string_view fileName);
|
||||||
|
eastl::vector<u8> ReadFileBytes(std::string_view fileName, bool errorOnFail = true);
|
||||||
|
bool WriteFileBytes(std::string_view fileName, eastl::span<u8> data);
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
#include "core/window.h"
|
#include "core/window.h"
|
||||||
#include "systems/resource.h"
|
#include "systems/resource.h"
|
||||||
|
|
||||||
|
#include "aster/util/files.h"
|
||||||
|
|
||||||
static constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT =
|
static constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT =
|
||||||
QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | QueueSupportFlagBits::eCompute |
|
QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | QueueSupportFlagBits::eCompute |
|
||||||
QueueSupportFlagBits::ePresent | QueueSupportFlagBits::eTransfer;
|
QueueSupportFlagBits::ePresent | QueueSupportFlagBits::eTransfer;
|
||||||
|
|
@ -416,6 +418,191 @@ systems::Device::CreateSampler(const SamplerCreateInfo &createInfo)
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pipelines
|
||||||
|
// ----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Pipeline
|
||||||
|
systems::Device::CreatePipeline(const GraphicsPipelineCreateInfo &createInfo)
|
||||||
|
{
|
||||||
|
auto findShader = [&shaderModules = createInfo.m_ShaderModules](
|
||||||
|
GraphicsShaderModuleInfo::Type type) -> std::optional<GraphicsShaderModuleInfo> {
|
||||||
|
if (const auto res =
|
||||||
|
std::ranges::find_if(shaderModules, [type](const auto &v) { return v.m_Type == type; });
|
||||||
|
res != std::ranges::end(shaderModules))
|
||||||
|
{
|
||||||
|
return *res;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto vs = findShader(GraphicsShaderModuleInfo::Type::eVertex);
|
||||||
|
ERROR_IF(!vs, "Vertex Shader not found.");
|
||||||
|
GraphicsShaderModuleInfo vertexShader = *vs;
|
||||||
|
|
||||||
|
auto fs = findShader(GraphicsShaderModuleInfo::Type::eFragment);
|
||||||
|
ERROR_IF(!fs, "Fragment Shader not found.");
|
||||||
|
GraphicsShaderModuleInfo fragmentShader = *fs;
|
||||||
|
|
||||||
|
// Pipeline Setup
|
||||||
|
auto vertexShaderModule = CreateShader(vertexShader.m_ShaderFile);
|
||||||
|
auto fragmentShaderModule = CreateShader(fragmentShader.m_ShaderFile);
|
||||||
|
|
||||||
|
eastl::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = {{
|
||||||
|
{
|
||||||
|
.stage = vk::ShaderStageFlagBits::eVertex,
|
||||||
|
.module = vertexShaderModule,
|
||||||
|
.pName = vertexShader.m_EntryPoint.data(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.stage = vk::ShaderStageFlagBits::eFragment,
|
||||||
|
.module = fragmentShaderModule,
|
||||||
|
.pName = fragmentShader.m_EntryPoint.data(),
|
||||||
|
},
|
||||||
|
}};
|
||||||
|
|
||||||
|
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
|
||||||
|
.setLayoutCount = 0,
|
||||||
|
.pSetLayouts = nullptr,
|
||||||
|
.pushConstantRangeCount = 0,
|
||||||
|
.pPushConstantRanges = nullptr,
|
||||||
|
};
|
||||||
|
vk::PipelineLayout pipelineLayout;
|
||||||
|
vk::Result result = m_Device.m_Device.createPipelineLayout(&pipelineLayoutCreateInfo, nullptr, &pipelineLayout);
|
||||||
|
ERROR_IF(Failed(result), "Could not create a pipeline layout. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
SetName(pipelineLayout, "Triangle Layout");
|
||||||
|
|
||||||
|
eastl::fixed_vector<vk::VertexInputBindingDescription, 4, false> inputBindingDescriptions;
|
||||||
|
eastl::fixed_vector<vk::VertexInputAttributeDescription, 4, false> inputAttributeDescriptions;
|
||||||
|
u32 binding = 0;
|
||||||
|
for (auto vertexInput : createInfo.m_VertexInputs)
|
||||||
|
{
|
||||||
|
inputBindingDescriptions.push_back({
|
||||||
|
.binding = binding,
|
||||||
|
.stride = vertexInput.m_Stride,
|
||||||
|
.inputRate =
|
||||||
|
vertexInput.m_IsPerInstance ? vk::VertexInputRate::eInstance : vk::VertexInputRate::eVertex,
|
||||||
|
});
|
||||||
|
for (auto attrInput : vertexInput.m_Attribute)
|
||||||
|
{
|
||||||
|
inputAttributeDescriptions.push_back({
|
||||||
|
.location = attrInput.m_Location,
|
||||||
|
.binding = binding,
|
||||||
|
.format = attrInput.GetFormat(),
|
||||||
|
.offset = attrInput.m_Offset,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
++binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
|
||||||
|
.vertexBindingDescriptionCount = Cast<u32>(inputBindingDescriptions.size()),
|
||||||
|
.pVertexBindingDescriptions = inputBindingDescriptions.data(),
|
||||||
|
.vertexAttributeDescriptionCount = Cast<u32>(inputAttributeDescriptions.size()),
|
||||||
|
.pVertexAttributeDescriptions = inputAttributeDescriptions.data(),
|
||||||
|
};
|
||||||
|
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
|
||||||
|
.topology = vk::PrimitiveTopology::eTriangleList,
|
||||||
|
.primitiveRestartEnable = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::PipelineViewportStateCreateInfo viewportStateCreateInfo = {
|
||||||
|
.viewportCount = 1,
|
||||||
|
.scissorCount = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::PipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
|
||||||
|
.depthClampEnable = false,
|
||||||
|
.rasterizerDiscardEnable = false,
|
||||||
|
.polygonMode = vk::PolygonMode::eFill,
|
||||||
|
.cullMode = vk::CullModeFlagBits::eNone,
|
||||||
|
.frontFace = vk::FrontFace::eCounterClockwise,
|
||||||
|
.depthBiasEnable = false,
|
||||||
|
.lineWidth = 1.0,
|
||||||
|
};
|
||||||
|
vk::PipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {
|
||||||
|
.rasterizationSamples = vk::SampleCountFlagBits::e1,
|
||||||
|
.sampleShadingEnable = false,
|
||||||
|
};
|
||||||
|
vk::PipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = {
|
||||||
|
.depthTestEnable = false,
|
||||||
|
.depthWriteEnable = false,
|
||||||
|
};
|
||||||
|
vk::PipelineColorBlendAttachmentState colorBlendAttachmentState = {
|
||||||
|
.blendEnable = false,
|
||||||
|
.srcColorBlendFactor = vk::BlendFactor::eSrcColor,
|
||||||
|
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcColor,
|
||||||
|
.colorBlendOp = vk::BlendOp::eAdd,
|
||||||
|
.srcAlphaBlendFactor = vk::BlendFactor::eSrcAlpha,
|
||||||
|
.dstAlphaBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
|
||||||
|
.alphaBlendOp = vk::BlendOp::eAdd,
|
||||||
|
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
||||||
|
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
||||||
|
};
|
||||||
|
vk::PipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
|
||||||
|
.logicOpEnable = false,
|
||||||
|
.attachmentCount = 1,
|
||||||
|
.pAttachments = &colorBlendAttachmentState,
|
||||||
|
};
|
||||||
|
|
||||||
|
eastl::array dynamicStates = {
|
||||||
|
vk::DynamicState::eScissor,
|
||||||
|
vk::DynamicState::eViewport,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
|
||||||
|
.dynamicStateCount = Cast<u32>(dynamicStates.size()),
|
||||||
|
.pDynamicStates = dynamicStates.data(),
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::PipelineRenderingCreateInfo renderingCreateInfo = {
|
||||||
|
.viewMask = 0,
|
||||||
|
.colorAttachmentCount = 1,
|
||||||
|
.pColorAttachmentFormats = &m_Swapchain.m_Format,
|
||||||
|
};
|
||||||
|
|
||||||
|
vk::GraphicsPipelineCreateInfo pipelineCreateInfo = {
|
||||||
|
.pNext = &renderingCreateInfo,
|
||||||
|
.stageCount = Cast<u32>(shaderStages.size()),
|
||||||
|
.pStages = shaderStages.data(),
|
||||||
|
.pVertexInputState = &vertexInputStateCreateInfo,
|
||||||
|
.pInputAssemblyState = &inputAssemblyStateCreateInfo,
|
||||||
|
.pViewportState = &viewportStateCreateInfo,
|
||||||
|
.pRasterizationState = &rasterizationStateCreateInfo,
|
||||||
|
.pMultisampleState = &multisampleStateCreateInfo,
|
||||||
|
.pDepthStencilState = &depthStencilStateCreateInfo,
|
||||||
|
.pColorBlendState = &colorBlendStateCreateInfo,
|
||||||
|
.pDynamicState = &dynamicStateCreateInfo,
|
||||||
|
.layout = pipelineLayout,
|
||||||
|
};
|
||||||
|
vk::Pipeline pipeline;
|
||||||
|
result = m_Device.m_Device.createGraphicsPipelines(nullptr, 1, &pipelineCreateInfo, nullptr, &pipeline);
|
||||||
|
ERROR_IF(Failed(result), "Could not create a graphics pipeline. Cause: {}", result)
|
||||||
|
THEN_ABORT(result);
|
||||||
|
SetName(pipeline, "Triangle Pipeline");
|
||||||
|
|
||||||
|
m_Device.m_Device.destroy(vertexShaderModule, nullptr);
|
||||||
|
m_Device.m_Device.destroy(fragmentShaderModule, nullptr);
|
||||||
|
|
||||||
|
return {&m_Device, pipelineLayout, pipeline, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
vk::ShaderModule
|
||||||
|
systems::Device::CreateShader(std::string_view shaderFile)
|
||||||
|
{
|
||||||
|
eastl::vector<u32> shaderCode = ReadFile(shaderFile);
|
||||||
|
|
||||||
|
const vk::ShaderModuleCreateInfo shaderModuleCreateInfo = {
|
||||||
|
.codeSize = shaderCode.size() * sizeof(u32),
|
||||||
|
.pCode = shaderCode.data(),
|
||||||
|
};
|
||||||
|
vk::ShaderModule shaderModule;
|
||||||
|
|
||||||
|
vk::Result result = m_Device.m_Device.createShaderModule(&shaderModuleCreateInfo, nullptr, &shaderModule);
|
||||||
|
ERROR_IF(Failed(result), "Shader {} could not be created. Cause: {}", shaderFile, result)
|
||||||
|
THEN_ABORT(result);
|
||||||
|
return shaderModule;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
QueueAllocation
|
QueueAllocation
|
||||||
|
|
@ -695,9 +882,9 @@ systems::GraphicsContext::BindVertexBuffer(const Ref<VertexBuffer> &vertexBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
systems::GraphicsContext::BindPipeline(vk::Pipeline pipeline)
|
systems::GraphicsContext::BindPipeline(const Pipeline &pipeline)
|
||||||
{
|
{
|
||||||
m_Cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
|
m_Cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.m_Pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
target_sources(aster_core PRIVATE "logger.cpp" )
|
target_sources(aster_core PRIVATE "logger.cpp" "files.cpp")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
// =============================================
|
||||||
|
// Aster: files.cpp
|
||||||
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
|
// =============================================
|
||||||
|
|
||||||
|
#include "aster/util/files.h"
|
||||||
|
|
||||||
|
eastl::vector<u32>
|
||||||
|
ReadFile(std::string_view fileName)
|
||||||
|
{
|
||||||
|
FILE *filePtr = fopen(fileName.data(), "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 == buffer.size());
|
||||||
|
|
||||||
|
return outputVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
eastl::vector<u8>
|
||||||
|
ReadFileBytes(std::string_view fileName, bool errorOnFail)
|
||||||
|
{
|
||||||
|
FILE *filePtr = fopen(fileName.data(), "rb");
|
||||||
|
|
||||||
|
if (!filePtr)
|
||||||
|
{
|
||||||
|
ERROR_IF(errorOnFail, "Invalid open (r) of {}. Cause: {}", fileName, errno);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
eastl::vector<u8> outputVec;
|
||||||
|
eastl::array<u8, 4096> buffer{};
|
||||||
|
usize totalRead = 0;
|
||||||
|
usize readCount;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
readCount = fread(buffer.data(), sizeof(u8), 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 == buffer.size());
|
||||||
|
|
||||||
|
(void)fclose(filePtr);
|
||||||
|
|
||||||
|
return outputVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
WriteFileBytes(std::string_view fileName, const eastl::span<u8> data)
|
||||||
|
{
|
||||||
|
FILE *filePtr = fopen(fileName.data(), "wb");
|
||||||
|
|
||||||
|
if (!filePtr)
|
||||||
|
{
|
||||||
|
ERROR("Invalid open (w) of {}. Cause: {}", fileName, errno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const usize written = fwrite(data.data(), sizeof(u8), data.size(), filePtr);
|
||||||
|
|
||||||
|
(void)fclose(filePtr);
|
||||||
|
|
||||||
|
return written == data.size();
|
||||||
|
}
|
||||||
|
|
@ -62,76 +62,3 @@ FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice)
|
||||||
ERROR("No suitable queue family on the GPU.")
|
ERROR("No suitable queue family on the GPU.")
|
||||||
THEN_ABORT(vk::Result::eErrorUnknown);
|
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 == buffer.size());
|
|
||||||
|
|
||||||
return outputVec;
|
|
||||||
}
|
|
||||||
|
|
||||||
eastl::vector<u8>
|
|
||||||
ReadFileBytes(cstr fileName, bool errorOnFail)
|
|
||||||
{
|
|
||||||
FILE *filePtr = fopen(fileName, "rb");
|
|
||||||
|
|
||||||
if (!filePtr)
|
|
||||||
{
|
|
||||||
ERROR_IF(errorOnFail, "Invalid open (r) of {}. Cause: {}", fileName, errno);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
eastl::vector<u8> outputVec;
|
|
||||||
eastl::array<u8, 4096> buffer{};
|
|
||||||
usize totalRead = 0;
|
|
||||||
usize readCount;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
readCount = fread(buffer.data(), sizeof(u8), 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 == buffer.size());
|
|
||||||
|
|
||||||
(void)fclose(filePtr);
|
|
||||||
|
|
||||||
return outputVec;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
WriteFileBytes(cstr fileName, eastl::span<u8> data)
|
|
||||||
{
|
|
||||||
FILE *filePtr = fopen(fileName, "wb");
|
|
||||||
|
|
||||||
if (!filePtr)
|
|
||||||
{
|
|
||||||
ERROR("Invalid open (w) of {}. Cause: {}", fileName, errno);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const usize written = fwrite(data.data(), sizeof(u8), data.size(), filePtr);
|
|
||||||
|
|
||||||
(void)fclose(filePtr);
|
|
||||||
|
|
||||||
return written == data.size();
|
|
||||||
}
|
|
||||||
|
|
@ -18,9 +18,6 @@ class PhysicalDevices;
|
||||||
|
|
||||||
PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices);
|
PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices);
|
||||||
QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice);
|
QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice);
|
||||||
eastl::vector<u32> ReadFile(cstr fileName);
|
|
||||||
eastl::vector<u8> ReadFileBytes(cstr fileName, bool errorOnFail = true);
|
|
||||||
bool WriteFileBytes(cstr fileName, eastl::span<u8> data);
|
|
||||||
|
|
||||||
template <usize TSize>
|
template <usize TSize>
|
||||||
using StackString = eastl::fixed_string<char, TSize, false>;
|
using StackString = eastl::fixed_string<char, TSize, false>;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@
|
||||||
#include "aster/core/swapchain.h"
|
#include "aster/core/swapchain.h"
|
||||||
#include "aster/core/window.h"
|
#include "aster/core/window.h"
|
||||||
|
|
||||||
|
#include "aster/core/pipeline.h"
|
||||||
#include "aster/systems/device.h"
|
#include "aster/systems/device.h"
|
||||||
|
#include "aster/util/files.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
#include <EASTL/array.h>
|
#include <EASTL/array.h>
|
||||||
|
|
@ -21,9 +23,6 @@
|
||||||
constexpr auto VERTEX_SHADER_FILE = "shader/triangle.vert.glsl.spv";
|
constexpr auto VERTEX_SHADER_FILE = "shader/triangle.vert.glsl.spv";
|
||||||
constexpr auto FRAGMENT_SHADER_FILE = "shader/triangle.frag.glsl.spv";
|
constexpr auto FRAGMENT_SHADER_FILE = "shader/triangle.frag.glsl.spv";
|
||||||
|
|
||||||
vk::ShaderModule CreateShader(const Device *device, cstr shaderFile);
|
|
||||||
Pipeline CreatePipeline(const Device *device, const Swapchain *swapchain);
|
|
||||||
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
vec3 m_Position;
|
vec3 m_Position;
|
||||||
|
|
@ -69,7 +68,37 @@ main(int, char **)
|
||||||
.m_Vulkan13Features = {.synchronization2 = true, .dynamicRendering = true}},
|
.m_Vulkan13Features = {.synchronization2 = true, .dynamicRendering = true}},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
Pipeline pipeline = CreatePipeline(&device.m_Device, &device.m_Swapchain);
|
Pipeline pipeline = device.CreatePipeline({
|
||||||
|
.m_VertexInputs = {{
|
||||||
|
.m_Attribute =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.m_Stride = sizeof(Vertex),
|
||||||
|
}},
|
||||||
|
.m_ShaderModules =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.m_ShaderFile = VERTEX_SHADER_FILE,
|
||||||
|
.m_EntryPoint = "main",
|
||||||
|
.m_Type = systems::GraphicsShaderModuleInfo::Type::eVertex,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.m_ShaderFile = FRAGMENT_SHADER_FILE,
|
||||||
|
.m_EntryPoint = "main",
|
||||||
|
.m_Type = systems::GraphicsShaderModuleInfo::Type::eFragment,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// eastl::array<Vertex, 3> vertices{};
|
// eastl::array<Vertex, 3> vertices{};
|
||||||
eastl::array vertices = {
|
eastl::array vertices = {
|
||||||
|
|
@ -168,7 +197,7 @@ main(int, char **)
|
||||||
context.BeginRendering(renderingInfo);
|
context.BeginRendering(renderingInfo);
|
||||||
|
|
||||||
context.SetViewport(viewport);
|
context.SetViewport(viewport);
|
||||||
context.BindPipeline(pipeline.m_Pipeline);
|
context.BindPipeline(pipeline);
|
||||||
context.BindVertexBuffer(vbo);
|
context.BindVertexBuffer(vbo);
|
||||||
context.Draw(3);
|
context.Draw(3);
|
||||||
|
|
||||||
|
|
@ -187,146 +216,3 @@ main(int, char **)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline
|
|
||||||
CreatePipeline(const Device *device, const Swapchain *swapchain)
|
|
||||||
{
|
|
||||||
// Pipeline Setup
|
|
||||||
auto vertexShaderModule = CreateShader(device, VERTEX_SHADER_FILE);
|
|
||||||
auto fragmentShaderModule = CreateShader(device, FRAGMENT_SHADER_FILE);
|
|
||||||
|
|
||||||
eastl::array<vk::PipelineShaderStageCreateInfo, 2> shaderStages = {{
|
|
||||||
{
|
|
||||||
.stage = vk::ShaderStageFlagBits::eVertex,
|
|
||||||
.module = vertexShaderModule,
|
|
||||||
.pName = "main",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.stage = vk::ShaderStageFlagBits::eFragment,
|
|
||||||
.module = fragmentShaderModule,
|
|
||||||
.pName = "main",
|
|
||||||
},
|
|
||||||
}};
|
|
||||||
|
|
||||||
vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
|
|
||||||
.setLayoutCount = 0,
|
|
||||||
.pSetLayouts = nullptr,
|
|
||||||
.pushConstantRangeCount = 0,
|
|
||||||
.pPushConstantRanges = nullptr,
|
|
||||||
};
|
|
||||||
vk::PipelineLayout pipelineLayout;
|
|
||||||
vk::Result result = device->m_Device.createPipelineLayout(&pipelineLayoutCreateInfo, nullptr, &pipelineLayout);
|
|
||||||
ERROR_IF(Failed(result), "Could not create a pipeline layout. Cause: {}", result) THEN_ABORT(result);
|
|
||||||
device->SetName(pipelineLayout, "Triangle Layout");
|
|
||||||
|
|
||||||
vk::VertexInputBindingDescription inputBindingDescription = Vertex::GetBinding(0);
|
|
||||||
auto inputAttributeDescription = Vertex::GetAttributes(0);
|
|
||||||
|
|
||||||
vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
|
|
||||||
.vertexBindingDescriptionCount = 1,
|
|
||||||
.pVertexBindingDescriptions = &inputBindingDescription,
|
|
||||||
.vertexAttributeDescriptionCount = Cast<u32>(inputAttributeDescription.size()),
|
|
||||||
.pVertexAttributeDescriptions = inputAttributeDescription.data(),
|
|
||||||
};
|
|
||||||
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
|
|
||||||
.topology = vk::PrimitiveTopology::eTriangleList,
|
|
||||||
.primitiveRestartEnable = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineViewportStateCreateInfo viewportStateCreateInfo = {
|
|
||||||
.viewportCount = 1,
|
|
||||||
.scissorCount = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
|
|
||||||
.depthClampEnable = false,
|
|
||||||
.rasterizerDiscardEnable = false,
|
|
||||||
.polygonMode = vk::PolygonMode::eFill,
|
|
||||||
.cullMode = vk::CullModeFlagBits::eNone,
|
|
||||||
.frontFace = vk::FrontFace::eCounterClockwise,
|
|
||||||
.depthBiasEnable = false,
|
|
||||||
.lineWidth = 1.0,
|
|
||||||
};
|
|
||||||
vk::PipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {
|
|
||||||
.rasterizationSamples = vk::SampleCountFlagBits::e1,
|
|
||||||
.sampleShadingEnable = false,
|
|
||||||
};
|
|
||||||
vk::PipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = {
|
|
||||||
.depthTestEnable = false,
|
|
||||||
.depthWriteEnable = false,
|
|
||||||
};
|
|
||||||
vk::PipelineColorBlendAttachmentState colorBlendAttachmentState = {
|
|
||||||
.blendEnable = false,
|
|
||||||
.srcColorBlendFactor = vk::BlendFactor::eSrcColor,
|
|
||||||
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcColor,
|
|
||||||
.colorBlendOp = vk::BlendOp::eAdd,
|
|
||||||
.srcAlphaBlendFactor = vk::BlendFactor::eSrcAlpha,
|
|
||||||
.dstAlphaBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
|
|
||||||
.alphaBlendOp = vk::BlendOp::eAdd,
|
|
||||||
.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG |
|
|
||||||
vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA,
|
|
||||||
};
|
|
||||||
vk::PipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
|
|
||||||
.logicOpEnable = false,
|
|
||||||
.attachmentCount = 1,
|
|
||||||
.pAttachments = &colorBlendAttachmentState,
|
|
||||||
};
|
|
||||||
|
|
||||||
eastl::array dynamicStates = {
|
|
||||||
vk::DynamicState::eScissor,
|
|
||||||
vk::DynamicState::eViewport,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineDynamicStateCreateInfo dynamicStateCreateInfo = {
|
|
||||||
.dynamicStateCount = Cast<u32>(dynamicStates.size()),
|
|
||||||
.pDynamicStates = dynamicStates.data(),
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::PipelineRenderingCreateInfo renderingCreateInfo = {
|
|
||||||
.viewMask = 0,
|
|
||||||
.colorAttachmentCount = 1,
|
|
||||||
.pColorAttachmentFormats = &swapchain->m_Format,
|
|
||||||
};
|
|
||||||
|
|
||||||
vk::GraphicsPipelineCreateInfo pipelineCreateInfo = {
|
|
||||||
.pNext = &renderingCreateInfo,
|
|
||||||
.stageCount = Cast<u32>(shaderStages.size()),
|
|
||||||
.pStages = shaderStages.data(),
|
|
||||||
.pVertexInputState = &vertexInputStateCreateInfo,
|
|
||||||
.pInputAssemblyState = &inputAssemblyStateCreateInfo,
|
|
||||||
.pViewportState = &viewportStateCreateInfo,
|
|
||||||
.pRasterizationState = &rasterizationStateCreateInfo,
|
|
||||||
.pMultisampleState = &multisampleStateCreateInfo,
|
|
||||||
.pDepthStencilState = &depthStencilStateCreateInfo,
|
|
||||||
.pColorBlendState = &colorBlendStateCreateInfo,
|
|
||||||
.pDynamicState = &dynamicStateCreateInfo,
|
|
||||||
.layout = pipelineLayout,
|
|
||||||
};
|
|
||||||
vk::Pipeline pipeline;
|
|
||||||
result = device->m_Device.createGraphicsPipelines(nullptr, 1, &pipelineCreateInfo, nullptr, &pipeline);
|
|
||||||
ERROR_IF(Failed(result), "Could not create a graphics pipeline. Cause: {}", result)
|
|
||||||
THEN_ABORT(result);
|
|
||||||
device->SetName(pipeline, "Triangle Pipeline");
|
|
||||||
|
|
||||||
device->m_Device.destroy(vertexShaderModule, nullptr);
|
|
||||||
device->m_Device.destroy(fragmentShaderModule, nullptr);
|
|
||||||
|
|
||||||
return {device, pipelineLayout, pipeline, {}};
|
|
||||||
}
|
|
||||||
|
|
||||||
vk::ShaderModule
|
|
||||||
CreateShader(const Device *device, cstr shaderFile)
|
|
||||||
{
|
|
||||||
eastl::vector<u32> shaderCode = ReadFile(shaderFile);
|
|
||||||
|
|
||||||
const vk::ShaderModuleCreateInfo shaderModuleCreateInfo = {
|
|
||||||
.codeSize = shaderCode.size() * sizeof(u32),
|
|
||||||
.pCode = shaderCode.data(),
|
|
||||||
};
|
|
||||||
vk::ShaderModule shaderModule;
|
|
||||||
|
|
||||||
vk::Result result = device->m_Device.createShaderModule(&shaderModuleCreateInfo, nullptr, &shaderModule);
|
|
||||||
ERROR_IF(Failed(result), "Shader {} could not be created. Cause: {}", shaderFile, result)
|
|
||||||
THEN_ABORT(result);
|
|
||||||
return shaderModule;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue