use index buffer and create rectangle

This commit is contained in:
2024-07-08 23:33:16 +02:00
parent bf21eae3f1
commit c56a3eccfd

93
main.c
View File

@@ -46,11 +46,17 @@ typedef struct Vertex {
Vec3 color;
} Vertex;
#define VERTEX_COUNT 3
#define VERTEX_COUNT 4
const Vertex vertices[VERTEX_COUNT] = {
{{0.0f, -0.5f}, {0.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, 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}}
};
#define INDEX_COUNT 6
const uint16_t indices[INDEX_COUNT] = {
0, 1, 2, 2, 3, 0
};
struct VulkanData {
@@ -82,6 +88,8 @@ struct VulkanData {
bool framebufferResized;
VkBuffer vertexBuffer;
VkDeviceMemory vertexBufferMemory;
VkBuffer indexBuffer;
VkDeviceMemory indexBufferMemory;
};
struct SwapChainSupportDetails {
@@ -352,7 +360,7 @@ static struct SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice dev
}
static struct QueueFamilyIndices findQueueFamilies(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) {
struct QueueFamilyIndices indices = {
struct QueueFamilyIndices familyIndices = {
.graphicsFamily.v = 0,
.graphicsFamily.is_some = 0,
@@ -372,33 +380,33 @@ static struct QueueFamilyIndices findQueueFamilies(VkPhysicalDevice physicalDevi
VkQueueFamilyProperties queueFamily = queueFamilies[i];
if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT
&& !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT)) {
indices.transferFamily.v = i;
indices.transferFamily.is_some = true;
familyIndices.transferFamily.v = i;
familyIndices.transferFamily.is_some = true;
}
if (queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
indices.graphicsFamily.v = i;
indices.graphicsFamily.is_some = true;
familyIndices.graphicsFamily.v = i;
familyIndices.graphicsFamily.is_some = true;
}
VkBool32 presentSupport = 0;
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, &presentSupport);
if (presentSupport) {
indices.presentFamily.v = i;
indices.presentFamily.is_some = true;
familyIndices.presentFamily.v = i;
familyIndices.presentFamily.is_some = true;
}
if (indices.presentFamily.is_some && indices.graphicsFamily.is_some && indices.transferFamily.is_some) {
if (familyIndices.presentFamily.is_some && familyIndices.graphicsFamily.is_some && familyIndices.transferFamily.is_some) {
break;
}
}
return indices;
return familyIndices;
}
static bool isDeviceSuitable(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { // One could pick the device based on a score.
struct QueueFamilyIndices indices = findQueueFamilies(physicalDevice, surface);
struct QueueFamilyIndices familyIndices = findQueueFamilies(physicalDevice, surface);
VkPhysicalDeviceProperties deviceProperties;
vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
@@ -424,7 +432,7 @@ static bool isDeviceSuitable(VkPhysicalDevice physicalDevice, VkSurfaceKHR surfa
deviceProperties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
deviceFeatures.geometryShader &&
swapChainAdequate &&
indices.graphicsFamily.is_some && indices.presentFamily.is_some && indices.transferFamily.is_some;
familyIndices.graphicsFamily.is_some && familyIndices.presentFamily.is_some && familyIndices.transferFamily.is_some;
}
static void pickPhysicalDevice(struct VulkanData* data) {
@@ -453,12 +461,12 @@ static void pickPhysicalDevice(struct VulkanData* data) {
}
static void createLogicalDevice(struct VulkanData* data) {
struct QueueFamilyIndices indices = findQueueFamilies(data->physicalDevice, data->surface);
struct QueueFamilyIndices familyIndices = findQueueFamilies(data->physicalDevice, data->surface);
float queuePriority = 1.0f;
int queueCount = 3;
VkDeviceQueueCreateInfo queueCreateInfos[queueCount];
uint32_t uniqueQueueFamilies[] = {indices.graphicsFamily.v, indices.transferFamily.v, indices.presentFamily.v};
uint32_t uniqueQueueFamilies[] = {familyIndices.graphicsFamily.v, familyIndices.transferFamily.v, familyIndices.presentFamily.v};
for (int i = 0; i < queueCount; i++) {
uint32_t queueFamily = uniqueQueueFamilies[i];
@@ -471,7 +479,7 @@ static void createLogicalDevice(struct VulkanData* data) {
queueCreateInfos[i] = queueCreateInfo;
}
if (indices.graphicsFamily.v == indices.presentFamily.v) {
if (familyIndices.graphicsFamily.v == familyIndices.presentFamily.v) {
queueCount--;
}
@@ -514,15 +522,15 @@ static void createLogicalDevice(struct VulkanData* data) {
printf("ERROR: Failed to create logical device\n");
exit(1);
}
if (!indices.transferFamily.is_some) {
if (!familyIndices.transferFamily.is_some) {
printf("no graphics\n");
}
if (!indices.presentFamily.is_some) {
if (!familyIndices.presentFamily.is_some) {
printf("no present\n");
}
vkGetDeviceQueue(data->device, indices.graphicsFamily.v, 0, &data->graphicsQueue);
vkGetDeviceQueue(data->device, indices.presentFamily.v, 0, &data->presentQueue);
vkGetDeviceQueue(data->device, indices.transferFamily.v, 0, &data->transferQueue);
vkGetDeviceQueue(data->device, familyIndices.graphicsFamily.v, 0, &data->graphicsQueue);
vkGetDeviceQueue(data->device, familyIndices.presentFamily.v, 0, &data->presentQueue);
vkGetDeviceQueue(data->device, familyIndices.transferFamily.v, 0, &data->transferQueue);
}
static VkExtent2D chooseSwapExtent(VkSurfaceCapabilitiesKHR* capabilities, GLFWwindow* window) {
@@ -577,9 +585,9 @@ static void createSwapChain(struct VulkanData* data, GLFWwindow* window) {
imageCount = swapChainSupport.capabilities.maxImageCount;
}
struct QueueFamilyIndices indices = findQueueFamilies(data->physicalDevice, data->surface);
uint32_t queueFamilyIndices[] = {indices.graphicsFamily.v, indices.presentFamily.v};
uint32_t otherFamilyIndices[] = {indices.transferFamily.v, indices.graphicsFamily.v};
struct QueueFamilyIndices familyIndices = findQueueFamilies(data->physicalDevice, data->surface);
uint32_t queueFamilyIndices[] = {familyIndices.graphicsFamily.v, familyIndices.presentFamily.v};
uint32_t otherFamilyIndices[] = {familyIndices.transferFamily.v, familyIndices.graphicsFamily.v};
VkSwapchainCreateInfoKHR createInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
@@ -600,7 +608,7 @@ static void createSwapChain(struct VulkanData* data, GLFWwindow* window) {
.oldSwapchain = VK_NULL_HANDLE,
};
if (indices.graphicsFamily.v != indices.presentFamily.v) {
if (familyIndices.graphicsFamily.v != familyIndices.presentFamily.v) {
createInfo.pQueueFamilyIndices = queueFamilyIndices;
}
@@ -1001,6 +1009,7 @@ static void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageInd
VkBuffer vertexBuffers[] = {data->vertexBuffer};
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
vkCmdBindIndexBuffer(commandBuffer, data->indexBuffer, 0, VK_INDEX_TYPE_UINT16);
VkViewport viewport = {
.x = 0.0f,
@@ -1017,7 +1026,7 @@ static void recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageInd
.extent = data->swapChainExtent,
};
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
vkCmdDraw(commandBuffer, VERTEX_COUNT, 1, 0, 0);
vkCmdDrawIndexed(commandBuffer, INDEX_COUNT, 1, 0, 0, 0);
vkCmdEndRenderPass(commandBuffer);
if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) {
fprintf(stderr, "ERROR: Failed to record command buffer\n");
@@ -1141,8 +1150,8 @@ static uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags proper
}
static void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer* buffer, VkDeviceMemory* bufferMemory, struct VulkanData* data) {
struct QueueFamilyIndices indices = findQueueFamilies(data->physicalDevice, data->surface);
uint32_t otherFamilyIndices[] = {indices.transferFamily.v, indices.graphicsFamily.v};
struct QueueFamilyIndices familyIndices = findQueueFamilies(data->physicalDevice, data->surface);
uint32_t otherFamilyIndices[] = {familyIndices.transferFamily.v, familyIndices.graphicsFamily.v};
VkBufferCreateInfo bufferInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = size,
@@ -1209,6 +1218,26 @@ static void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size
vkFreeCommandBuffers(data->device, data->transferCommandPool, 1, &commandBuffer);
}
static void createIndexBuffer(struct VulkanData* data) {
VkDeviceSize bufferSize = sizeof(indices[0]) * INDEX_COUNT;
VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &stagingBuffer, &stagingBufferMemory, data);
void* indexData;
vkMapMemory(data->device, stagingBufferMemory, 0, bufferSize, 0, &indexData);
memcpy(indexData, indices, bufferSize);
vkUnmapMemory(data->device, stagingBufferMemory);
createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &data->indexBuffer, &data->indexBufferMemory, data);
copyBuffer(stagingBuffer, data->indexBuffer, bufferSize, data);
vkDestroyBuffer(data->device, stagingBuffer, NULL);
vkFreeMemory(data->device, stagingBufferMemory, NULL);
}
static void createVertexBuffer(struct VulkanData* data) {
VkDeviceSize bufferSize = sizeof(vertices[0]) * VERTEX_COUNT;
@@ -1241,6 +1270,7 @@ static struct VulkanData initVulkan(GLFWwindow* window) {
createGraphicsPipeline(&data);
createFramebuffers(&data);
createCommandPool(&data);
createIndexBuffer(&data);
createVertexBuffer(&data);
createCommandBuffers(&data);
createSyncObjects(&data);
@@ -1265,6 +1295,9 @@ static void cleanup(GLFWwindow* window, struct VulkanData* data) {
cleanupSwapChain(data);
vkDestroyBuffer(data->device, data->vertexBuffer, NULL);
vkFreeMemory(data->device, data->vertexBufferMemory, NULL);
vkDestroyBuffer(data->device, data->indexBuffer, NULL);
vkFreeMemory(data->device, data->indexBufferMemory, NULL);
vkDestroyPipeline(data->device, data->graphicsPipeline, NULL);
vkDestroyPipelineLayout(data->device, data->pipelineLayout, NULL);
vkDestroyRenderPass(data->device, data->renderPass, NULL);