Vertex buffers.
This commit is contained in:
parent
7c17d09822
commit
1a8f113323
|
|
@ -13,7 +13,7 @@ if (MSVC)
|
||||||
add_compile_definitions(_HAS_EXCEPTIONS=1)
|
add_compile_definitions(_HAS_EXCEPTIONS=1)
|
||||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||||
else ()
|
else ()
|
||||||
set(CMAKE_CXX_FLAGS "-Wall -fno-rtti -fno-exceptions")
|
set(CMAKE_CXX_FLAGS "-Wall -g -fno-rtti -fno-exceptions")
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
include(add_shader.cmake)
|
include(add_shader.cmake)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
void
|
void
|
||||||
Buffer::Destroy(const Device *device)
|
Buffer::Destroy(const Device *device)
|
||||||
{
|
{
|
||||||
|
|
@ -16,28 +18,91 @@ Buffer::Destroy(const Device *device)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UniformBuffer::Init(const Device *device, usize size, cstr name)
|
Buffer::Allocate(const Device *device, usize size, vk::BufferUsageFlags bufferUsage,
|
||||||
|
VmaAllocationCreateFlags allocationFlags, VmaMemoryUsage memoryUsage, cstr name)
|
||||||
{
|
{
|
||||||
|
assert(size <= SIZE_MASK);
|
||||||
|
|
||||||
vk::BufferCreateInfo bufferCreateInfo = {
|
vk::BufferCreateInfo bufferCreateInfo = {
|
||||||
.size = size,
|
.size = size,
|
||||||
.usage = vk::BufferUsageFlagBits::eUniformBuffer,
|
.usage = bufferUsage,
|
||||||
.sharingMode = vk::SharingMode::eExclusive,
|
.sharingMode = vk::SharingMode::eExclusive,
|
||||||
};
|
};
|
||||||
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
|
const VmaAllocationCreateInfo allocationCreateInfo = {
|
||||||
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
.flags = allocationFlags,
|
||||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
.usage = memoryUsage,
|
||||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VkBuffer buffer;
|
VkBuffer buffer;
|
||||||
VmaAllocation allocation;
|
VmaAllocation allocation;
|
||||||
|
VmaAllocationInfo allocationInfo;
|
||||||
auto result = Cast<vk::Result>(vmaCreateBuffer(device->m_Allocator, Recast<VkBufferCreateInfo *>(&bufferCreateInfo),
|
auto result = Cast<vk::Result>(vmaCreateBuffer(device->m_Allocator, Recast<VkBufferCreateInfo *>(&bufferCreateInfo),
|
||||||
&allocationCreateInfo, &buffer, &allocation, nullptr));
|
&allocationCreateInfo, &buffer, &allocation, &allocationInfo));
|
||||||
ERROR_IF(Failed(result), "Could not allocate buffer. Cause: {}", result) THEN_ABORT(result);
|
ERROR_IF(Failed(result), "Could not allocate buffer. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
|
||||||
m_Buffer = buffer;
|
m_Buffer = buffer;
|
||||||
m_Size = size;
|
m_Size = size & SIZE_MASK;
|
||||||
m_Allocation = allocation;
|
m_Allocation = allocation;
|
||||||
|
m_Mapped = allocationInfo.pMappedData;
|
||||||
|
|
||||||
|
vk::MemoryPropertyFlags memoryPropertyFlags;
|
||||||
|
vmaGetAllocationMemoryProperties(device->m_Allocator, allocation,
|
||||||
|
Recast<VkMemoryPropertyFlags *>(&memoryPropertyFlags));
|
||||||
|
if (memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible)
|
||||||
|
{
|
||||||
|
m_Size |= HOST_ACCESSIBLE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
device->SetName(m_Buffer, name);
|
device->SetName(m_Buffer, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Buffer::Write(const Device *device, usize offset, usize size, void *data)
|
||||||
|
{
|
||||||
|
assert(IsHostVisible());
|
||||||
|
|
||||||
|
if (!IsMapped())
|
||||||
|
{
|
||||||
|
auto result = Cast<vk::Result>(vmaMapMemory(device->m_Allocator, m_Allocation, &m_Mapped));
|
||||||
|
ERROR_IF(Failed(result), "Memory mapping failed. Cause: {}", result);
|
||||||
|
if (!Failed(result))
|
||||||
|
{
|
||||||
|
memcpy(m_Mapped, data, size);
|
||||||
|
|
||||||
|
vmaUnmapMemory(device->m_Allocator, m_Allocation);
|
||||||
|
m_Mapped = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(m_Mapped, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Debug this.
|
||||||
|
// auto result = Cast<vk::Result>(vmaCopyMemoryToAllocation(device->m_Allocator, &data, m_Allocation, 0, size));
|
||||||
|
// ERROR_IF(Failed(result), "Writing to buffer failed. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UniformBuffer::Init(const Device *device, const usize size, const cstr name)
|
||||||
|
{
|
||||||
|
Allocate(device, size, vk::BufferUsageFlagBits::eUniformBuffer,
|
||||||
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||||
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
VertexBuffer::Init(const Device *device, usize size, cstr name)
|
||||||
|
{
|
||||||
|
Allocate(device, size, vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst,
|
||||||
|
VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StagingBuffer::Init(const Device *device, usize size, cstr name)
|
||||||
|
{
|
||||||
|
Allocate(device, size, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
VMA_MEMORY_USAGE_AUTO, name);
|
||||||
}
|
}
|
||||||
|
|
@ -14,12 +14,55 @@ struct Buffer
|
||||||
{
|
{
|
||||||
vk::Buffer m_Buffer = nullptr;
|
vk::Buffer m_Buffer = nullptr;
|
||||||
VmaAllocation m_Allocation = nullptr;
|
VmaAllocation m_Allocation = nullptr;
|
||||||
usize m_Size = 0;
|
void *m_Mapped = nullptr;
|
||||||
|
|
||||||
|
[[nodiscard]] usize GetSize() const;
|
||||||
|
[[nodiscard]] bool IsHostVisible() const;
|
||||||
|
[[nodiscard]] bool IsMapped() const;
|
||||||
|
|
||||||
void Destroy(const Device *device);
|
void Destroy(const Device *device);
|
||||||
|
void Write(const Device *device, usize offset, usize size, void *data);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Allocate(const Device *device, usize size, vk::BufferUsageFlags bufferUsage,
|
||||||
|
VmaAllocationCreateFlags allocationFlags, VmaMemoryUsage memoryUsage, cstr name);
|
||||||
|
|
||||||
|
usize m_Size = 0;
|
||||||
|
|
||||||
|
constexpr static usize HOST_ACCESSIBLE_BIT = 1llu << 63;
|
||||||
|
constexpr static usize SIZE_MASK = ~HOST_ACCESSIBLE_BIT;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UniformBuffer : Buffer
|
struct UniformBuffer : Buffer
|
||||||
{
|
{
|
||||||
void Init(const Device *device, usize size, cstr name = nullptr);
|
void Init(const Device *device, usize size, cstr name = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VertexBuffer : Buffer
|
||||||
|
{
|
||||||
|
void Init(const Device *device, usize size, cstr name = nullptr);
|
||||||
|
void Write(const Device *device, void *data, usize size, usize offset) const = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StagingBuffer : Buffer
|
||||||
|
{
|
||||||
|
void Init(const Device *device, usize size, cstr name = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline usize
|
||||||
|
Buffer::GetSize() const
|
||||||
|
{
|
||||||
|
return m_Size & SIZE_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Buffer::IsHostVisible() const
|
||||||
|
{
|
||||||
|
return m_Size & HOST_ACCESSIBLE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
Buffer::IsMapped() const
|
||||||
|
{
|
||||||
|
return m_Mapped;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,12 @@ struct Device final
|
||||||
~Device();
|
~Device();
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires vk::isVulkanHandleType<T>::value
|
requires vk::isVulkanHandleType<T>::value void SetName(const T &object, cstr name) const;
|
||||||
void SetName(const T &object, cstr name) const;
|
|
||||||
[[nodiscard]] vk::Queue GetQueue(u32 familyIndex, u32 queueIndex) const;
|
[[nodiscard]] vk::Queue GetQueue(u32 familyIndex, u32 queueIndex) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
requires vk::isVulkanHandleType<T>::value
|
requires vk::isVulkanHandleType<T>::value void
|
||||||
void
|
|
||||||
Device::SetName(const T &object, cstr name) const
|
Device::SetName(const T &object, cstr name) const
|
||||||
{
|
{
|
||||||
if (!name)
|
if (!name)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
add_executable(triangle "triangle.cpp")
|
add_executable(triangle "triangle.cpp")
|
||||||
add_shader(triangle shader/triangle.vs.hlsl)
|
add_shader(triangle shader/triangle.vert.glsl)
|
||||||
add_shader(triangle shader/triangle.frag.glsl)
|
add_shader(triangle shader/triangle.frag.glsl)
|
||||||
|
|
||||||
target_link_libraries(triangle PRIVATE aster_core)
|
target_link_libraries(triangle PRIVATE aster_core)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#version 450
|
||||||
|
#pragma shader_stage(vertex)
|
||||||
|
|
||||||
|
layout(location=0) in vec4 position;
|
||||||
|
layout(location=1) in vec4 color;
|
||||||
|
|
||||||
|
layout(location=0) out vec3 outColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
/*
|
||||||
|
vec3 points[] = {
|
||||||
|
vec3(-0.5f, -0.5f, 0.0f),
|
||||||
|
vec3(0.5f, -0.5f, 0.0f),
|
||||||
|
vec3(0.0f, 0.5f, 0.0f)
|
||||||
|
};
|
||||||
|
vec3 colors[] = {
|
||||||
|
vec3( 1.0f, 0.0f, 0.0f ),
|
||||||
|
vec3( 0.0f, 1.0f, 0.0f ),
|
||||||
|
vec3( 0.0f, 0.0f, 1.0f ),
|
||||||
|
};
|
||||||
|
|
||||||
|
gl_Position = vec4(points[gl_VertexIndex], 1.0f);
|
||||||
|
outColor = vec3(colors[gl_VertexIndex]); //*/
|
||||||
|
//*
|
||||||
|
gl_Position = vec4(position.xyz, 1.0f);
|
||||||
|
outColor = vec3(color.rgb); //*/
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// Copyright (c) 2020-2024 Anish Bhobe
|
// Copyright (c) 2020-2024 Anish Bhobe
|
||||||
// =============================================
|
// =============================================
|
||||||
|
|
||||||
|
#include "buffer.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
|
@ -18,12 +19,43 @@
|
||||||
#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.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);
|
vk::ShaderModule CreateShader(const Device *device, cstr shaderFile);
|
||||||
Pipeline CreatePipeline(const Device *device, const Swapchain *swapchain);
|
Pipeline CreatePipeline(const Device *device, const Swapchain *swapchain);
|
||||||
|
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
float m_Position[4];
|
||||||
|
float m_Color[4];
|
||||||
|
|
||||||
|
constexpr static vk::VertexInputBindingDescription
|
||||||
|
GetBinding(const u32 binding)
|
||||||
|
{
|
||||||
|
return {.binding = binding, .stride = sizeof(Vertex), .inputRate = vk::VertexInputRate::eVertex};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static eastl::array<vk::VertexInputAttributeDescription, 2>
|
||||||
|
GetAttributes(const u32 binding)
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
vk::VertexInputAttributeDescription{
|
||||||
|
.location = 0,
|
||||||
|
.binding = binding,
|
||||||
|
.format = vk::Format::eR32G32B32A32Sfloat,
|
||||||
|
.offset = offsetof(Vertex, m_Position),
|
||||||
|
},
|
||||||
|
vk::VertexInputAttributeDescription{
|
||||||
|
.location = 1,
|
||||||
|
.binding = binding,
|
||||||
|
.format = vk::Format::eR32G32B32A32Sfloat,
|
||||||
|
.offset = offsetof(Vertex, m_Color),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Frame
|
struct Frame
|
||||||
{
|
{
|
||||||
const Device *m_Device;
|
const Device *m_Device;
|
||||||
|
|
@ -55,12 +87,76 @@ main(int, char **)
|
||||||
QueueAllocation queueAllocation = FindAppropriateQueueAllocation(&deviceToUse);
|
QueueAllocation queueAllocation = FindAppropriateQueueAllocation(&deviceToUse);
|
||||||
Device device = {&context, &deviceToUse, &enabledDeviceFeatures, {queueAllocation}, "Primary Device"};
|
Device device = {&context, &deviceToUse, &enabledDeviceFeatures, {queueAllocation}, "Primary Device"};
|
||||||
|
|
||||||
vk::Queue commandQueue = device.GetQueue(queueAllocation.m_Family, 1);
|
vk::Queue commandQueue = device.GetQueue(queueAllocation.m_Family, 0);
|
||||||
|
|
||||||
Swapchain swapchain = {&window, &device, "Primary Chain"};
|
Swapchain swapchain = {&window, &device, "Primary Chain"};
|
||||||
|
|
||||||
Pipeline pipeline = CreatePipeline(&device, &swapchain);
|
Pipeline pipeline = CreatePipeline(&device, &swapchain);
|
||||||
|
|
||||||
|
vk::CommandPool copyPool;
|
||||||
|
vk::CommandBuffer copyBuffer;
|
||||||
|
{
|
||||||
|
vk::CommandPoolCreateInfo poolCreateInfo = {
|
||||||
|
.flags = vk::CommandPoolCreateFlagBits::eTransient,
|
||||||
|
.queueFamilyIndex = queueAllocation.m_Family,
|
||||||
|
};
|
||||||
|
auto result = device.m_Device.createCommandPool(&poolCreateInfo, nullptr, ©Pool);
|
||||||
|
ERROR_IF(Failed(result), "Copy command pool creation failed. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
vk::CommandBufferAllocateInfo bufferAllocateInfo = {
|
||||||
|
.commandPool = copyPool,
|
||||||
|
.level = vk::CommandBufferLevel::ePrimary,
|
||||||
|
.commandBufferCount = 1,
|
||||||
|
};
|
||||||
|
result = device.m_Device.allocateCommandBuffers(&bufferAllocateInfo, ©Buffer);
|
||||||
|
ERROR_IF(Failed(result), "Copy command buffer allocation failed. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eastl::array<Vertex, 3> vertices{};
|
||||||
|
eastl::array vertices = {
|
||||||
|
Vertex{.m_Position = {-0.5f, -0.5f, 0.0f, 1.0f}, .m_Color = {1.0f, 0.0f, 0.0f, 1.0f}},
|
||||||
|
Vertex{.m_Position = {0.5f, -0.5f, 0.0f, 1.0f}, .m_Color = {0.0f, 1.0f, 0.0f, 1.0f}},
|
||||||
|
Vertex{.m_Position = {0.0f, 0.5f, 0.0f, 1.0f}, .m_Color = {0.0f, 0.0f, 1.0f, 1.0f}},
|
||||||
|
};
|
||||||
|
VertexBuffer vbo;
|
||||||
|
vbo.Init(&device, vertices.size() * sizeof vertices[0], "VBO");
|
||||||
|
{
|
||||||
|
StagingBuffer staging;
|
||||||
|
staging.Init(&device, vertices.size() * sizeof vertices[0], "Staging");
|
||||||
|
staging.Write(&device, 0, vertices.size() * sizeof vertices[0], vertices.data());
|
||||||
|
|
||||||
|
vk::Fence fence;
|
||||||
|
vk::FenceCreateInfo fenceCreateInfo = {};
|
||||||
|
auto result = device.m_Device.createFence(&fenceCreateInfo, nullptr, &fence);
|
||||||
|
ERROR_IF(Failed(result), "Fence creation failed. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
|
||||||
|
vk::CommandBufferBeginInfo beginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit};
|
||||||
|
result = copyBuffer.begin(&beginInfo);
|
||||||
|
ERROR_IF(Failed(result), "Copy begin failed. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
|
||||||
|
vk::BufferCopy bufferCopy = {.srcOffset = 0, .dstOffset = 0, .size = staging.GetSize()};
|
||||||
|
copyBuffer.copyBuffer(staging.m_Buffer, vbo.m_Buffer, 1, &bufferCopy);
|
||||||
|
|
||||||
|
result = copyBuffer.end();
|
||||||
|
ERROR_IF(Failed(result), "Copy end failed. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
|
||||||
|
vk::SubmitInfo submitInfo = {
|
||||||
|
.commandBufferCount = 1,
|
||||||
|
.pCommandBuffers = ©Buffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
result = commandQueue.submit(1, &submitInfo, fence);
|
||||||
|
ERROR_IF(Failed(result), "Submit failed. Cause: {}", result) THEN_ABORT(result) ELSE_INFO("Submit copy");
|
||||||
|
|
||||||
|
result = device.m_Device.waitForFences(1, &fence, true, MaxValue<u64>);
|
||||||
|
ERROR_IF(Failed(result), "Fence wait failed. Cause: {}", result) THEN_ABORT(result) ELSE_INFO("Fence wait");
|
||||||
|
|
||||||
|
result = device.m_Device.resetCommandPool(copyPool, {});
|
||||||
|
ERROR_IF(Failed(result), "Couldn't reset command pool. Cause: {}", result) THEN_ABORT(result);
|
||||||
|
|
||||||
|
device.m_Device.destroy(fence, nullptr);
|
||||||
|
staging.Destroy(&device);
|
||||||
|
}
|
||||||
|
|
||||||
// Persistent variables
|
// Persistent variables
|
||||||
vk::Viewport viewport = {
|
vk::Viewport viewport = {
|
||||||
.x = 0,
|
.x = 0,
|
||||||
|
|
@ -105,6 +201,7 @@ main(int, char **)
|
||||||
frames.emplace_back(&device, queueAllocation.m_Family, i);
|
frames.emplace_back(&device, queueAllocation.m_Family, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INFO("Starting loop");
|
||||||
u32 frameIndex = 0;
|
u32 frameIndex = 0;
|
||||||
while (window.Poll())
|
while (window.Poll())
|
||||||
{
|
{
|
||||||
|
|
@ -181,6 +278,8 @@ main(int, char **)
|
||||||
cmd.setViewport(0, 1, &viewport);
|
cmd.setViewport(0, 1, &viewport);
|
||||||
cmd.setScissor(0, 1, &scissor);
|
cmd.setScissor(0, 1, &scissor);
|
||||||
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.m_Pipeline);
|
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline.m_Pipeline);
|
||||||
|
usize offsets = 0;
|
||||||
|
cmd.bindVertexBuffers(0, 1, &vbo.m_Buffer, &offsets);
|
||||||
cmd.draw(3, 1, 0, 0);
|
cmd.draw(3, 1, 0, 0);
|
||||||
|
|
||||||
cmd.endRendering();
|
cmd.endRendering();
|
||||||
|
|
@ -239,6 +338,9 @@ main(int, char **)
|
||||||
auto result = device.m_Device.waitIdle();
|
auto result = device.m_Device.waitIdle();
|
||||||
ERROR_IF(Failed(result), "Wait idle failed. Cause: {}", result);
|
ERROR_IF(Failed(result), "Wait idle failed. Cause: {}", result);
|
||||||
|
|
||||||
|
device.m_Device.destroy(copyPool, nullptr);
|
||||||
|
vbo.Destroy(&device);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,6 +385,7 @@ Frame::AllocateCommandBuffer() const
|
||||||
|
|
||||||
return commandBuffer;
|
return commandBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pipeline
|
Pipeline
|
||||||
CreatePipeline(const Device *device, const Swapchain *swapchain)
|
CreatePipeline(const Device *device, const Swapchain *swapchain)
|
||||||
{
|
{
|
||||||
|
|
@ -314,11 +417,14 @@ CreatePipeline(const Device *device, const Swapchain *swapchain)
|
||||||
ERROR_IF(Failed(result), "Could not create a pipeline layout. Cause: {}", result) THEN_ABORT(result);
|
ERROR_IF(Failed(result), "Could not create a pipeline layout. Cause: {}", result) THEN_ABORT(result);
|
||||||
device->SetName(pipelineLayout, "Triangle Layout");
|
device->SetName(pipelineLayout, "Triangle Layout");
|
||||||
|
|
||||||
|
vk::VertexInputBindingDescription inputBindingDescription = Vertex::GetBinding(0);
|
||||||
|
auto inputAttributeDescription = Vertex::GetAttributes(0);
|
||||||
|
|
||||||
vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
|
vk::PipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
|
||||||
.vertexBindingDescriptionCount = 0,
|
.vertexBindingDescriptionCount = 1,
|
||||||
.pVertexBindingDescriptions = nullptr,
|
.pVertexBindingDescriptions = &inputBindingDescription,
|
||||||
.vertexAttributeDescriptionCount = 0,
|
.vertexAttributeDescriptionCount = Cast<u32>(inputAttributeDescription.size()),
|
||||||
.pVertexAttributeDescriptions = nullptr,
|
.pVertexAttributeDescriptions = inputAttributeDescription.data(),
|
||||||
};
|
};
|
||||||
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
|
vk::PipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
|
||||||
.topology = vk::PrimitiveTopology::eTriangleList,
|
.topology = vk::PrimitiveTopology::eTriangleList,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue