forked from pupbrained/vulkan-test
Index buffer
This commit is contained in:
parent
7cc871fb48
commit
1732d56e22
148
src/main.cpp
148
src/main.cpp
|
@ -21,6 +21,42 @@ constexpr i32 HEIGHT = 600;
|
||||||
|
|
||||||
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2;
|
constexpr i32 MAX_FRAMES_IN_FLIGHT = 2;
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
glm::vec2 pos;
|
||||||
|
glm::vec3 color;
|
||||||
|
|
||||||
|
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
|
||||||
|
vk::VertexInputBindingDescription bindingDescription { .binding = 0,
|
||||||
|
.stride = sizeof(Vertex),
|
||||||
|
.inputRate = vk::VertexInputRate::eVertex };
|
||||||
|
|
||||||
|
return bindingDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 2> {
|
||||||
|
std::array<vk::VertexInputAttributeDescription, 2> attributeDescriptions {};
|
||||||
|
|
||||||
|
attributeDescriptions[0] = {
|
||||||
|
.location = 0, .binding = 0, .format = vk::Format::eR32G32Sfloat, .offset = offsetof(Vertex, pos)
|
||||||
|
};
|
||||||
|
|
||||||
|
attributeDescriptions[1] = {
|
||||||
|
.location = 1, .binding = 0, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, color)
|
||||||
|
};
|
||||||
|
|
||||||
|
return attributeDescriptions;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr std::array<Vertex, 4> vertices = {
|
||||||
|
{ { { -0.5F, -0.5F }, { 1.0F, 0.0F, 0.0F } },
|
||||||
|
{ { 0.5F, -0.5F }, { 0.0F, 1.0F, 0.0F } },
|
||||||
|
{ { 0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F } },
|
||||||
|
{ { -0.5F, 0.5F }, { 1.0F, 1.0F, 1.0F } } }
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr std::array<u16, 6> indices = { 0, 1, 2, 2, 3, 0 };
|
||||||
|
|
||||||
constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" };
|
constexpr std::array<const char*, 1> validationLayers = { "VK_LAYER_KHRONOS_validation" };
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -79,43 +115,12 @@ class VulkanApp {
|
||||||
|
|
||||||
vk::UniqueBuffer mVertexBuffer;
|
vk::UniqueBuffer mVertexBuffer;
|
||||||
vk::UniqueDeviceMemory mVertexBufferMemory;
|
vk::UniqueDeviceMemory mVertexBufferMemory;
|
||||||
|
vk::UniqueBuffer mIndexBuffer;
|
||||||
|
vk::UniqueDeviceMemory mIndexBufferMemory;
|
||||||
|
|
||||||
bool mFramebufferResized = false;
|
bool mFramebufferResized = false;
|
||||||
u32 mCurrentFrame = 0;
|
u32 mCurrentFrame = 0;
|
||||||
|
|
||||||
struct Vertex {
|
|
||||||
glm::vec2 pos;
|
|
||||||
glm::vec3 color;
|
|
||||||
|
|
||||||
static fn getBindingDescription() -> vk::VertexInputBindingDescription {
|
|
||||||
vk::VertexInputBindingDescription bindingDescription { .binding = 0,
|
|
||||||
.stride = sizeof(Vertex),
|
|
||||||
.inputRate = vk::VertexInputRate::eVertex };
|
|
||||||
|
|
||||||
return bindingDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
static fn getAttributeDescriptions() -> std::array<vk::VertexInputAttributeDescription, 2> {
|
|
||||||
std::array<vk::VertexInputAttributeDescription, 2> attributeDescriptions {};
|
|
||||||
|
|
||||||
attributeDescriptions[0] = {
|
|
||||||
.location = 0, .binding = 0, .format = vk::Format::eR32G32Sfloat, .offset = offsetof(Vertex, pos)
|
|
||||||
};
|
|
||||||
|
|
||||||
attributeDescriptions[1] = {
|
|
||||||
.location = 1, .binding = 0, .format = vk::Format::eR32G32B32Sfloat, .offset = offsetof(Vertex, color)
|
|
||||||
};
|
|
||||||
|
|
||||||
return attributeDescriptions;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::vector<Vertex> mVertices = {
|
|
||||||
{ { 0.0F, -0.5F }, { 1.0F, 1.0F, 1.0F } },
|
|
||||||
{ { 0.5F, 0.5F }, { 0.0F, 1.0F, 0.0F } },
|
|
||||||
{ { -0.5F, 0.5F }, { 0.0F, 0.0F, 1.0F } }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct QueueFamilyIndices {
|
struct QueueFamilyIndices {
|
||||||
std::optional<u32> graphics_family;
|
std::optional<u32> graphics_family;
|
||||||
std::optional<u32> present_family;
|
std::optional<u32> present_family;
|
||||||
|
@ -177,6 +182,7 @@ class VulkanApp {
|
||||||
createFramebuffers();
|
createFramebuffers();
|
||||||
createCommandPool();
|
createCommandPool();
|
||||||
createVertexBuffer();
|
createVertexBuffer();
|
||||||
|
createIndexBuffer();
|
||||||
createCommandBuffers();
|
createCommandBuffers();
|
||||||
createSyncObjects();
|
createSyncObjects();
|
||||||
}
|
}
|
||||||
|
@ -307,10 +313,11 @@ class VulkanApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createLogicalDevice() -> void {
|
fn createLogicalDevice() -> void {
|
||||||
QueueFamilyIndices indices = findQueueFamilies(mPhysicalDevice);
|
QueueFamilyIndices qfIndices = findQueueFamilies(mPhysicalDevice);
|
||||||
|
|
||||||
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
|
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
|
||||||
std::set<u32> uniqueQueueFamilies = { indices.graphics_family.value(), indices.present_family.value() };
|
std::set<u32> uniqueQueueFamilies = { qfIndices.graphics_family.value(),
|
||||||
|
qfIndices.present_family.value() };
|
||||||
|
|
||||||
f32 queuePriority = 1.0F;
|
f32 queuePriority = 1.0F;
|
||||||
|
|
||||||
|
@ -331,8 +338,8 @@ class VulkanApp {
|
||||||
.pEnabledFeatures = &deviceFeatures };
|
.pEnabledFeatures = &deviceFeatures };
|
||||||
|
|
||||||
mDevice = mPhysicalDevice.createDeviceUnique(createInfo);
|
mDevice = mPhysicalDevice.createDeviceUnique(createInfo);
|
||||||
mGraphicsQueue = mDevice->getQueue(indices.graphics_family.value(), 0);
|
mGraphicsQueue = mDevice->getQueue(qfIndices.graphics_family.value(), 0);
|
||||||
mPresentQueue = mDevice->getQueue(indices.present_family.value(), 0);
|
mPresentQueue = mDevice->getQueue(qfIndices.present_family.value(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createSwapChain() -> void {
|
fn createSwapChain() -> void {
|
||||||
|
@ -348,9 +355,9 @@ class VulkanApp {
|
||||||
imageCount > swapChainSupport.capabilities.maxImageCount)
|
imageCount > swapChainSupport.capabilities.maxImageCount)
|
||||||
imageCount = swapChainSupport.capabilities.maxImageCount;
|
imageCount = swapChainSupport.capabilities.maxImageCount;
|
||||||
|
|
||||||
QueueFamilyIndices indices = findQueueFamilies(mPhysicalDevice);
|
QueueFamilyIndices qfIndices = findQueueFamilies(mPhysicalDevice);
|
||||||
std::array<u32, 2> queueFamilyIndices = { indices.graphics_family.value(),
|
std::array<u32, 2> queueFamilyIndices = { qfIndices.graphics_family.value(),
|
||||||
indices.present_family.value() };
|
qfIndices.present_family.value() };
|
||||||
|
|
||||||
vk::SwapchainCreateInfoKHR createInfo {
|
vk::SwapchainCreateInfoKHR createInfo {
|
||||||
.surface = mSurface.get(),
|
.surface = mSurface.get(),
|
||||||
|
@ -360,11 +367,12 @@ class VulkanApp {
|
||||||
.imageExtent = extent,
|
.imageExtent = extent,
|
||||||
.imageArrayLayers = 1,
|
.imageArrayLayers = 1,
|
||||||
.imageUsage = vk::ImageUsageFlagBits::eColorAttachment,
|
.imageUsage = vk::ImageUsageFlagBits::eColorAttachment,
|
||||||
.imageSharingMode = indices.graphics_family != indices.present_family ? vk::SharingMode::eConcurrent
|
.imageSharingMode = qfIndices.graphics_family != qfIndices.present_family ? vk::SharingMode::eConcurrent
|
||||||
: vk::SharingMode::eExclusive,
|
: vk::SharingMode::eExclusive,
|
||||||
.queueFamilyIndexCount = static_cast<u32>(indices.graphics_family != indices.present_family ? 2 : 0),
|
.queueFamilyIndexCount =
|
||||||
|
static_cast<u32>(qfIndices.graphics_family != qfIndices.present_family ? 2 : 0),
|
||||||
.pQueueFamilyIndices =
|
.pQueueFamilyIndices =
|
||||||
indices.graphics_family != indices.present_family ? queueFamilyIndices.data() : nullptr,
|
qfIndices.graphics_family != qfIndices.present_family ? queueFamilyIndices.data() : nullptr,
|
||||||
.preTransform = swapChainSupport.capabilities.currentTransform,
|
.preTransform = swapChainSupport.capabilities.currentTransform,
|
||||||
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
||||||
.presentMode = presentMode,
|
.presentMode = presentMode,
|
||||||
|
@ -578,7 +586,7 @@ class VulkanApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createVertexBuffer() -> void {
|
fn createVertexBuffer() -> void {
|
||||||
vk::DeviceSize bufferSize = sizeof(mVertices[0]) * mVertices.size();
|
vk::DeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
|
||||||
|
|
||||||
vk::UniqueBuffer stagingBuffer;
|
vk::UniqueBuffer stagingBuffer;
|
||||||
vk::UniqueDeviceMemory stagingBufferMemory;
|
vk::UniqueDeviceMemory stagingBufferMemory;
|
||||||
|
@ -592,7 +600,7 @@ class VulkanApp {
|
||||||
);
|
);
|
||||||
|
|
||||||
void* data = mDevice->mapMemory(stagingBufferMemory.get(), 0, bufferSize);
|
void* data = mDevice->mapMemory(stagingBufferMemory.get(), 0, bufferSize);
|
||||||
memcpy(data, mVertices.data(), static_cast<usize>(bufferSize));
|
memcpy(data, vertices.data(), static_cast<usize>(bufferSize));
|
||||||
mDevice->unmapMemory(stagingBufferMemory.get());
|
mDevice->unmapMemory(stagingBufferMemory.get());
|
||||||
|
|
||||||
createBuffer(
|
createBuffer(
|
||||||
|
@ -609,6 +617,38 @@ class VulkanApp {
|
||||||
stagingBufferMemory.reset();
|
stagingBufferMemory.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn createIndexBuffer() -> void {
|
||||||
|
vk::DeviceSize bufferSize = sizeof(indices[0]) * indices.size();
|
||||||
|
|
||||||
|
vk::UniqueBuffer stagingBuffer;
|
||||||
|
vk::UniqueDeviceMemory stagingBufferMemory;
|
||||||
|
|
||||||
|
createBuffer(
|
||||||
|
bufferSize,
|
||||||
|
vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
|
vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent,
|
||||||
|
stagingBuffer,
|
||||||
|
stagingBufferMemory
|
||||||
|
);
|
||||||
|
|
||||||
|
void* data = mDevice->mapMemory(stagingBufferMemory.get(), 0, bufferSize);
|
||||||
|
memcpy(data, indices.data(), static_cast<usize>(bufferSize));
|
||||||
|
mDevice->unmapMemory(stagingBufferMemory.get());
|
||||||
|
|
||||||
|
createBuffer(
|
||||||
|
bufferSize,
|
||||||
|
vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst,
|
||||||
|
vk::MemoryPropertyFlagBits::eDeviceLocal,
|
||||||
|
mIndexBuffer,
|
||||||
|
mIndexBufferMemory
|
||||||
|
);
|
||||||
|
|
||||||
|
copyBuffer(stagingBuffer.get(), mIndexBuffer.get(), bufferSize);
|
||||||
|
|
||||||
|
stagingBuffer.reset();
|
||||||
|
stagingBufferMemory.reset();
|
||||||
|
}
|
||||||
|
|
||||||
fn createBuffer(
|
fn createBuffer(
|
||||||
vk::DeviceSize deviceSize,
|
vk::DeviceSize deviceSize,
|
||||||
vk::BufferUsageFlags bufferUsageFlags,
|
vk::BufferUsageFlags bufferUsageFlags,
|
||||||
|
@ -720,7 +760,9 @@ class VulkanApp {
|
||||||
|
|
||||||
commandBuffer.bindVertexBuffers(0, mVertexBuffer.get(), { 0 });
|
commandBuffer.bindVertexBuffers(0, mVertexBuffer.get(), { 0 });
|
||||||
|
|
||||||
commandBuffer.draw(static_cast<u32>(mVertices.size()), 1, 0, 0);
|
commandBuffer.bindIndexBuffer(mIndexBuffer.get(), 0, vk::IndexType::eUint16);
|
||||||
|
|
||||||
|
commandBuffer.drawIndexed(static_cast<u32>(indices.size()), 1, 0, 0, 0);
|
||||||
|
|
||||||
commandBuffer.endRenderPass();
|
commandBuffer.endRenderPass();
|
||||||
|
|
||||||
|
@ -867,7 +909,7 @@ class VulkanApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn isDeviceSuitable(vk::PhysicalDevice device) -> bool {
|
fn isDeviceSuitable(vk::PhysicalDevice device) -> bool {
|
||||||
QueueFamilyIndices indices = findQueueFamilies(device);
|
QueueFamilyIndices qfIndices = findQueueFamilies(device);
|
||||||
|
|
||||||
bool extensionsSupported = checkDeviceExtensionSupport(device);
|
bool extensionsSupported = checkDeviceExtensionSupport(device);
|
||||||
|
|
||||||
|
@ -878,7 +920,7 @@ class VulkanApp {
|
||||||
swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.present_modes.empty();
|
swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.present_modes.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return indices.isComplete() && extensionsSupported && swapChainAdequate;
|
return qfIndices.isComplete() && extensionsSupported && swapChainAdequate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fn checkDeviceExtensionSupport(vk::PhysicalDevice device) -> bool {
|
static fn checkDeviceExtensionSupport(vk::PhysicalDevice device) -> bool {
|
||||||
|
@ -893,24 +935,24 @@ class VulkanApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn findQueueFamilies(vk::PhysicalDevice device) -> QueueFamilyIndices {
|
fn findQueueFamilies(vk::PhysicalDevice device) -> QueueFamilyIndices {
|
||||||
QueueFamilyIndices indices;
|
QueueFamilyIndices qfIndices;
|
||||||
|
|
||||||
std::vector<vk::QueueFamilyProperties> queueFamilies = device.getQueueFamilyProperties();
|
std::vector<vk::QueueFamilyProperties> queueFamilies = device.getQueueFamilyProperties();
|
||||||
|
|
||||||
for (u32 i = 0; i < queueFamilies.size(); i++) {
|
for (u32 i = 0; i < queueFamilies.size(); i++) {
|
||||||
if (queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics)
|
if (queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics)
|
||||||
indices.graphics_family = i;
|
qfIndices.graphics_family = i;
|
||||||
|
|
||||||
vk::Bool32 queuePresentSupport = device.getSurfaceSupportKHR(i, mSurface.get());
|
vk::Bool32 queuePresentSupport = device.getSurfaceSupportKHR(i, mSurface.get());
|
||||||
|
|
||||||
if (queuePresentSupport)
|
if (queuePresentSupport)
|
||||||
indices.present_family = i;
|
qfIndices.present_family = i;
|
||||||
|
|
||||||
if (indices.isComplete())
|
if (qfIndices.isComplete())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return indices;
|
return qfIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fn getRequiredExtensions() -> std::vector<const char*> {
|
static fn getRequiredExtensions() -> std::vector<const char*> {
|
||||||
|
|
Loading…
Reference in a new issue