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;
|
||||
|
||||
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" };
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
@ -79,43 +115,12 @@ class VulkanApp {
|
|||
|
||||
vk::UniqueBuffer mVertexBuffer;
|
||||
vk::UniqueDeviceMemory mVertexBufferMemory;
|
||||
vk::UniqueBuffer mIndexBuffer;
|
||||
vk::UniqueDeviceMemory mIndexBufferMemory;
|
||||
|
||||
bool mFramebufferResized = false;
|
||||
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 {
|
||||
std::optional<u32> graphics_family;
|
||||
std::optional<u32> present_family;
|
||||
|
@ -177,6 +182,7 @@ class VulkanApp {
|
|||
createFramebuffers();
|
||||
createCommandPool();
|
||||
createVertexBuffer();
|
||||
createIndexBuffer();
|
||||
createCommandBuffers();
|
||||
createSyncObjects();
|
||||
}
|
||||
|
@ -307,10 +313,11 @@ class VulkanApp {
|
|||
}
|
||||
|
||||
fn createLogicalDevice() -> void {
|
||||
QueueFamilyIndices indices = findQueueFamilies(mPhysicalDevice);
|
||||
QueueFamilyIndices qfIndices = findQueueFamilies(mPhysicalDevice);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -331,8 +338,8 @@ class VulkanApp {
|
|||
.pEnabledFeatures = &deviceFeatures };
|
||||
|
||||
mDevice = mPhysicalDevice.createDeviceUnique(createInfo);
|
||||
mGraphicsQueue = mDevice->getQueue(indices.graphics_family.value(), 0);
|
||||
mPresentQueue = mDevice->getQueue(indices.present_family.value(), 0);
|
||||
mGraphicsQueue = mDevice->getQueue(qfIndices.graphics_family.value(), 0);
|
||||
mPresentQueue = mDevice->getQueue(qfIndices.present_family.value(), 0);
|
||||
}
|
||||
|
||||
fn createSwapChain() -> void {
|
||||
|
@ -348,9 +355,9 @@ class VulkanApp {
|
|||
imageCount > swapChainSupport.capabilities.maxImageCount)
|
||||
imageCount = swapChainSupport.capabilities.maxImageCount;
|
||||
|
||||
QueueFamilyIndices indices = findQueueFamilies(mPhysicalDevice);
|
||||
std::array<u32, 2> queueFamilyIndices = { indices.graphics_family.value(),
|
||||
indices.present_family.value() };
|
||||
QueueFamilyIndices qfIndices = findQueueFamilies(mPhysicalDevice);
|
||||
std::array<u32, 2> queueFamilyIndices = { qfIndices.graphics_family.value(),
|
||||
qfIndices.present_family.value() };
|
||||
|
||||
vk::SwapchainCreateInfoKHR createInfo {
|
||||
.surface = mSurface.get(),
|
||||
|
@ -360,11 +367,12 @@ class VulkanApp {
|
|||
.imageExtent = extent,
|
||||
.imageArrayLayers = 1,
|
||||
.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,
|
||||
.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 =
|
||||
indices.graphics_family != indices.present_family ? queueFamilyIndices.data() : nullptr,
|
||||
qfIndices.graphics_family != qfIndices.present_family ? queueFamilyIndices.data() : nullptr,
|
||||
.preTransform = swapChainSupport.capabilities.currentTransform,
|
||||
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eOpaque,
|
||||
.presentMode = presentMode,
|
||||
|
@ -578,7 +586,7 @@ class VulkanApp {
|
|||
}
|
||||
|
||||
fn createVertexBuffer() -> void {
|
||||
vk::DeviceSize bufferSize = sizeof(mVertices[0]) * mVertices.size();
|
||||
vk::DeviceSize bufferSize = sizeof(vertices[0]) * vertices.size();
|
||||
|
||||
vk::UniqueBuffer stagingBuffer;
|
||||
vk::UniqueDeviceMemory stagingBufferMemory;
|
||||
|
@ -592,7 +600,7 @@ class VulkanApp {
|
|||
);
|
||||
|
||||
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());
|
||||
|
||||
createBuffer(
|
||||
|
@ -609,6 +617,38 @@ class VulkanApp {
|
|||
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(
|
||||
vk::DeviceSize deviceSize,
|
||||
vk::BufferUsageFlags bufferUsageFlags,
|
||||
|
@ -720,7 +760,9 @@ class VulkanApp {
|
|||
|
||||
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();
|
||||
|
||||
|
@ -867,7 +909,7 @@ class VulkanApp {
|
|||
}
|
||||
|
||||
fn isDeviceSuitable(vk::PhysicalDevice device) -> bool {
|
||||
QueueFamilyIndices indices = findQueueFamilies(device);
|
||||
QueueFamilyIndices qfIndices = findQueueFamilies(device);
|
||||
|
||||
bool extensionsSupported = checkDeviceExtensionSupport(device);
|
||||
|
||||
|
@ -878,7 +920,7 @@ class VulkanApp {
|
|||
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 {
|
||||
|
@ -893,24 +935,24 @@ class VulkanApp {
|
|||
}
|
||||
|
||||
fn findQueueFamilies(vk::PhysicalDevice device) -> QueueFamilyIndices {
|
||||
QueueFamilyIndices indices;
|
||||
QueueFamilyIndices qfIndices;
|
||||
|
||||
std::vector<vk::QueueFamilyProperties> queueFamilies = device.getQueueFamilyProperties();
|
||||
|
||||
for (u32 i = 0; i < queueFamilies.size(); i++) {
|
||||
if (queueFamilies[i].queueFlags & vk::QueueFlagBits::eGraphics)
|
||||
indices.graphics_family = i;
|
||||
qfIndices.graphics_family = i;
|
||||
|
||||
vk::Bool32 queuePresentSupport = device.getSurfaceSupportKHR(i, mSurface.get());
|
||||
|
||||
if (queuePresentSupport)
|
||||
indices.present_family = i;
|
||||
qfIndices.present_family = i;
|
||||
|
||||
if (indices.isComplete())
|
||||
if (qfIndices.isComplete())
|
||||
break;
|
||||
}
|
||||
|
||||
return indices;
|
||||
return qfIndices;
|
||||
}
|
||||
|
||||
static fn getRequiredExtensions() -> std::vector<const char*> {
|
||||
|
|
Loading…
Reference in a new issue