Index buffer

This commit is contained in:
Mars 2024-10-10 18:51:20 -04:00
parent 7cc871fb48
commit 1732d56e22
Signed by: pupbrained
GPG key ID: 874E22DF2F9DFCB5

View file

@ -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*> {