Expanded basic program to use a vertex buffer via the new basalt::Buffer
Updated vertex function get_attribute_descriptions to conform to new standard for template-based binding Moved definition of triangle verticies inside of the application function Maps, copies into and unmaps the vertex buffer from the darray<Vertex> Uses a reference to refer to the current frames command buffer to not repeat the ugly indexing render area and viewport extent is updated every frame with the swapchain extent No longer directly recreate the framebuffers, now using the recreate function with the renderpass passed as a paramater
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "vulkan/basalt_command_buffer.h"
|
||||
#include "vulkan/basalt_swapchain.h"
|
||||
#include "vulkan/basalt_buffer.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct Vertex
|
||||
@@ -11,19 +12,19 @@ struct Vertex
|
||||
glm::vec3 colour;
|
||||
|
||||
static VkVertexInputBindingDescription get_binding_description(void);
|
||||
static VkResult get_attribute_descriptions(VkVertexInputAttributeDescription** out_attributes, u32* out_num_attributes);
|
||||
static VkResult get_attribute_descriptions(VkVertexInputAttributeDescription* out_attributes, u32* out_num_attributes);
|
||||
};
|
||||
|
||||
static basalt::darray<Vertex> verts({
|
||||
{{0.0f, -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}}
|
||||
}, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_32);
|
||||
|
||||
void framebuffer_resized(GLFWwindow* window, int width, int height);
|
||||
|
||||
void application()
|
||||
{
|
||||
basalt::darray<Vertex> verts({
|
||||
{{0.0f, -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}}
|
||||
}, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_32);
|
||||
|
||||
VkResult err = VK_SUCCESS;
|
||||
|
||||
basalt::Context ctx("Basic",
|
||||
@@ -87,9 +88,6 @@ void application()
|
||||
})
|
||||
.build();
|
||||
|
||||
VkVertexInputAttributeDescription* vertex_attribs = nullptr;
|
||||
u32 num_vertex_attribs = 0;
|
||||
VK_ASSERT(Vertex::get_attribute_descriptions(&vertex_attribs, &num_vertex_attribs), "Failed to get vertex input attribute description(s)\n\tAt %s:%d\n\tError %s\n\tVertex class %s\n", typeid(Vertex).name());
|
||||
basalt::Pipeline pipeline = basalt::PipelineBuilder(dev, swapchain.swapchain_extent, VK_NULL_HANDLE)
|
||||
.add_dynamic_state(VK_DYNAMIC_STATE_SCISSOR)
|
||||
.add_dynamic_state(VK_DYNAMIC_STATE_VIEWPORT)
|
||||
@@ -106,12 +104,18 @@ void application()
|
||||
})
|
||||
.add_shader("shaders/out/simple.vert.spv", VK_SHADER_STAGE_VERTEX_BIT)
|
||||
.add_shader("shaders/out/simple.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||
.add_vertex_binding(Vertex::get_binding_description(), vertex_attribs, num_vertex_attribs)
|
||||
.add_vertex_binding<Vertex>()
|
||||
.build();
|
||||
basalt::mem::dealloc(vertex_attribs, sizeof(VkVertexInputAttributeDescription) * num_vertex_attribs, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_ANY);
|
||||
|
||||
swapchain.create_framebuffers(pass.render_pass);
|
||||
|
||||
basalt::Buffer vertex_buffer(dev, verts.m_nelements * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
{
|
||||
void* dst = vertex_buffer.map();
|
||||
memcpy(dst, verts.m_pdata, vertex_buffer.size);
|
||||
vertex_buffer.unmap();
|
||||
}
|
||||
|
||||
basalt::CommandPool cmdpool(dev, phy_dev.indicies.graphics);
|
||||
basalt::darray<basalt::CommandBuffer> cmdbufs(swapchain.max_frames_in_flight, MEMORY_TAG_CLASS_DYNARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_32);
|
||||
for (u32 i = 0; i < swapchain.max_frames_in_flight; ++i)
|
||||
@@ -133,32 +137,41 @@ void application()
|
||||
.minDepth = 0.0f,
|
||||
.maxDepth = 1.0f
|
||||
};
|
||||
VkBuffer buffers[] = { vertex_buffer.buffer };
|
||||
VkDeviceSize offsets[] = { 0 };
|
||||
|
||||
while (!window.should_close())
|
||||
{
|
||||
render_area.extent = swapchain.swapchain_extent;
|
||||
viewport.width = render_area.extent.width;
|
||||
viewport.height = render_area.extent.height;
|
||||
|
||||
glfwPollEvents();
|
||||
basalt::CommandBuffer& cmdbuf = cmdbufs[swapchain.current_frame];
|
||||
|
||||
u32 image_index = swapchain.wait_acquire_reset();
|
||||
if (image_index == -1 || !swapchain.framebuffers_created)
|
||||
{
|
||||
swapchain.create_framebuffers(pass.render_pass);
|
||||
swapchain.recreate(pass.render_pass);
|
||||
swapchain.current_frame = (swapchain.current_frame + 1) % swapchain.max_frames_in_flight;
|
||||
continue;
|
||||
}
|
||||
|
||||
cmdbufs[swapchain.current_frame].reset();
|
||||
cmdbufs[swapchain.current_frame].start(pass, swapchain.framebuffers[image_index], render_area);
|
||||
cmdbufs[swapchain.current_frame].bind_pipeline(pipeline, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||
cmdbufs[swapchain.current_frame].set_scissor(render_area);
|
||||
cmdbufs[swapchain.current_frame].set_viewport(viewport);
|
||||
vkCmdDraw(cmdbufs[swapchain.current_frame].vk, 3, 1, 0, 0);
|
||||
cmdbufs[swapchain.current_frame].stop();
|
||||
cmdbuf.reset();
|
||||
cmdbuf.start(pass, swapchain.framebuffers[image_index], render_area);
|
||||
cmdbuf.bind_pipeline(pipeline, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||
vkCmdBindVertexBuffers(cmdbuf.vk, 0, sizeof(buffers) / sizeof(buffers[0]), buffers, offsets);
|
||||
cmdbuf.set_scissor(render_area);
|
||||
cmdbuf.set_viewport(viewport);
|
||||
vkCmdDraw(cmdbuf.vk, vertex_buffer.size / sizeof(Vertex), 1, 0, 0);
|
||||
cmdbuf.stop();
|
||||
|
||||
VkSubmitInfo submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO};
|
||||
VkSemaphore wait_semaphores[] = {swapchain.semaphores_image_available[swapchain.current_frame]};
|
||||
VkSemaphore signal_semaphores[] = {swapchain.semaphores_render_finished[image_index]};
|
||||
VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &cmdbufs[swapchain.current_frame].vk;
|
||||
submit_info.pCommandBuffers = &cmdbuf.vk;
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = wait_semaphores;
|
||||
submit_info.pWaitDstStageMask = wait_stages;
|
||||
@@ -227,20 +240,28 @@ VkVertexInputBindingDescription Vertex::get_binding_description(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
VkResult Vertex::get_attribute_descriptions(VkVertexInputAttributeDescription** out_attributes, u32* out_num_attributes)
|
||||
VkResult Vertex::get_attribute_descriptions(VkVertexInputAttributeDescription* out_attributes, u32* out_num_attributes)
|
||||
{
|
||||
*out_attributes = basalt::mem::allocT<VkVertexInputAttributeDescription>(2, MEMORY_TAG_CLASS_ARRAY | MEMORY_TAG_ZONE_APPLICATION | MEMORY_TAG_ALIGN_ANY);
|
||||
constexpr u32 num_attribs = 2;
|
||||
if (out_attributes == nullptr)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
*out_num_attributes = 2;
|
||||
VkVertexInputAttributeDescription* ptr = *out_attributes;
|
||||
ptr[0].binding = 0;
|
||||
ptr[0].location = 0;
|
||||
ptr[0].format = VK_FORMAT_R32G32_SFLOAT;
|
||||
ptr[0].offset = offsetof(Vertex, pos);
|
||||
ptr[1].binding = 0;
|
||||
ptr[1].location = 1;
|
||||
ptr[1].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
ptr[1].offset = offsetof(Vertex, colour);
|
||||
{
|
||||
*out_num_attributes = num_attribs;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
BASSERT_ERROR(*out_num_attributes == num_attribs,
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;,
|
||||
"Assertion %s failed at %s:%d\n\tAttempted to get attribute descriptions for object type %s but the allocated size %u was not sufficient. Expected %u\n",
|
||||
typeid(Vertex).name(), out_num_attributes, num_attribs
|
||||
);
|
||||
|
||||
out_attributes[0].binding = 0;
|
||||
out_attributes[0].location = 0;
|
||||
out_attributes[0].format = VK_FORMAT_R32G32_SFLOAT;
|
||||
out_attributes[0].offset = offsetof(Vertex, pos);
|
||||
out_attributes[1].binding = 0;
|
||||
out_attributes[1].location = 1;
|
||||
out_attributes[1].format = VK_FORMAT_R32G32B32_SFLOAT;
|
||||
out_attributes[1].offset = offsetof(Vertex, colour);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user