use index buffer and create rectangle
This commit is contained in:
93
main.c
93
main.c
@@ -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);
|
||||
|
Reference in New Issue
Block a user