This commit is contained in:
bailwillharr 2022-10-24 15:16:04 +01:00
parent 46895c0d4b
commit df02820c7d
4 changed files with 81 additions and 28 deletions

View File

@ -19,10 +19,9 @@ namespace engine {
GFXDevice& operator=(const GFXDevice&) = delete;
~GFXDevice();
// adds a vertex buffer draw call to the queue
void drawBuffer(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, uint32_t count);
void drawIndexed(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t indexCount);
// adds a draw call to the queue
// vertexBuffer is required. indexBuffer and uniformData can be NULL
void draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* uniformData);
// Call once per frame. Executes all queued draw calls and renders to the screen.
void renderFrame();

View File

@ -6,6 +6,13 @@
#include "log.hpp"
#include <glm/glm.hpp>
#include <glm/ext.hpp>
struct UBO {
glm::mat4 model{};
glm::mat4 view{};
glm::mat4 proj{};
};
static engine::gfx::Pipeline* pipeline;
static engine::gfx::Buffer* vb;
@ -29,11 +36,7 @@ namespace engine {
};
vertFormat.attributeDescriptions.push_back({0, gfx::VertexAttribFormat::VEC2, 0});
vertFormat.attributeDescriptions.push_back({1, gfx::VertexAttribFormat::VEC3, offsetof(Vertex, col)});
struct UBO {
glm::mat4 model{};
glm::mat4 view{};
glm::mat4 proj{};
};
pipeline = m_gfx->createPipeline(resMan.getFilePath("shader.vert.spv").string().c_str(), resMan.getFilePath("shader.frag.spv").string().c_str(), vertFormat, sizeof(UBO));
const std::vector<Vertex> vertices = {
@ -48,9 +51,6 @@ namespace engine {
};
ib = m_gfx->createBuffer(gfx::BufferType::INDEX, sizeof(uint32_t) * indices.size(), indices.data());
UBO initialUbo{};
// ub = m_gfx->createBuffer(gfx::BufferType::UNIFORM, sizeof(UBO), &initialUbo);
}
Application::~Application()
@ -89,8 +89,13 @@ namespace engine {
}
/* draw */
m_gfx->drawIndexed(pipeline, vb, ib, 6);
UBO initialUbo{
.model = glm::mat4{1.0f},
.view = glm::mat4{1.0f},
.proj = glm::mat4{1.0f}
};
initialUbo.model = glm::scale(glm::mat4{ 1.0f }, glm::vec3{ 0.5f, 0.5f, 1.0f });
m_gfx->draw(pipeline, vb, ib, 6, &initialUbo);
m_gfx->renderFrame();

View File

@ -94,6 +94,8 @@ namespace engine {
VkPipelineLayout layout = VK_NULL_HANDLE;
VkPipeline handle = VK_NULL_HANDLE;
std::vector<gfx::Buffer*> uniformBuffers{};
VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
std::array<VkDescriptorSet, FRAMES_IN_FLIGHT> descriptorSets{};
};
@ -1070,30 +1072,33 @@ namespace engine {
vkDestroyInstance(pimpl->instance, nullptr);
}
void GFXDevice::drawBuffer(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, uint32_t count)
void GFXDevice::draw(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count, const void* uniformData)
{
assert(vertexBuffer->type == gfx::BufferType::VERTEX);
assert(vertexBuffer != nullptr);
assert(indexBuffer == nullptr || indexBuffer->type == gfx::BufferType::INDEX);
VkResult res;
DrawCall call{
.vertexBuffer = vertexBuffer,
.indexBuffer = nullptr, // don't use indexed drawing
.indexBuffer = indexBuffer, // will be ignored if nullptr
.count = count,
};
pimpl->drawQueues[pipeline].push(call);
if (uniformData != nullptr) {
uint32_t frameIndex = pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT;
void* dest;
res = vmaMapMemory(pimpl->allocator, pipeline->uniformBuffers[frameIndex]->allocation, &dest);
assert(res == VK_SUCCESS);
memcpy(dest, uniformData, pipeline->uniformBuffers[frameIndex]->size);
vmaUnmapMemory(pimpl->allocator, pipeline->uniformBuffers[frameIndex]->allocation);
}
void GFXDevice::drawIndexed(const gfx::Pipeline* pipeline, const gfx::Buffer* vertexBuffer, const gfx::Buffer* indexBuffer, uint32_t count)
{
assert(vertexBuffer->type == gfx::BufferType::VERTEX);
assert(indexBuffer->type == gfx::BufferType::INDEX);
DrawCall call{
.vertexBuffer = vertexBuffer,
.indexBuffer = indexBuffer, // don't use indexed drawing
.count = count,
};
pimpl->drawQueues[pipeline].push(call);
}
@ -1163,9 +1168,11 @@ namespace engine {
for (auto& [pipeline, queue] : pimpl->drawQueues) {
vkCmdBindPipeline(pimpl->commandBuffers[frameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
vkCmdBindDescriptorSets(pimpl->commandBuffers[frameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->layout, 0, 1, &pipeline->descriptorSets[frameIndex], 0, nullptr);
while (queue.empty() == false) {
DrawCall call = queue.front();
vkCmdBindVertexBuffers(pimpl->commandBuffers[frameIndex], 0, 1, &call.vertexBuffer->buffer, offsets);
if (call.indexBuffer == nullptr) {
// do a simple draw call
vkCmdDraw(pimpl->commandBuffers[frameIndex], call.count, 1, 0, 0);
@ -1252,6 +1259,46 @@ namespace engine {
pipeline->uniformBuffers[i] = buf;
}
// create descriptor pool for uniform buffers
VkDescriptorPoolSize poolSize{};
poolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
poolSize.descriptorCount = FRAMES_IN_FLIGHT;
VkDescriptorPoolCreateInfo poolInfo{};
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
poolInfo.poolSizeCount = 1;
poolInfo.pPoolSizes = &poolSize;
poolInfo.maxSets = FRAMES_IN_FLIGHT;
res = vkCreateDescriptorPool(pimpl->device, &poolInfo, nullptr, &pipeline->descriptorPool);
assert(res == VK_SUCCESS);
std::array<VkDescriptorSetLayout, FRAMES_IN_FLIGHT> layouts;
layouts.fill(pimpl->uboLayout);
VkDescriptorSetAllocateInfo dSetAllocInfo{};
dSetAllocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
dSetAllocInfo.descriptorPool = pipeline->descriptorPool;
dSetAllocInfo.descriptorSetCount = FRAMES_IN_FLIGHT;
dSetAllocInfo.pSetLayouts = layouts.data();
res = vkAllocateDescriptorSets(pimpl->device, &dSetAllocInfo, pipeline->descriptorSets.data());
for (int i = 0; i < FRAMES_IN_FLIGHT; i++) {
VkDescriptorBufferInfo bufferInfo{};
bufferInfo.buffer = pipeline->uniformBuffers[i]->buffer;
bufferInfo.offset = 0;
bufferInfo.range = uniformBufferSize;
VkWriteDescriptorSet descriptorWrite{};
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptorWrite.dstSet = pipeline->descriptorSets[i];
descriptorWrite.dstBinding = 0;
descriptorWrite.dstArrayElement = 0;
descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptorWrite.descriptorCount = 1;
descriptorWrite.pBufferInfo = &bufferInfo;
descriptorWrite.pImageInfo = nullptr;
descriptorWrite.pTexelBufferView = nullptr;
vkUpdateDescriptorSets(pimpl->device, 1, &descriptorWrite, 0, nullptr);
}
// get vertex attrib layout:
VkVertexInputBindingDescription bindingDescription{ };
bindingDescription.binding = 0;
@ -1423,6 +1470,8 @@ namespace engine {
vkDestroyPipeline(pimpl->device, pipeline->handle, nullptr);
vkDestroyPipelineLayout(pimpl->device, pipeline->layout, nullptr);
vkDestroyDescriptorPool(pimpl->device, pipeline->descriptorPool, nullptr);
for (int i = 0; i < FRAMES_IN_FLIGHT; i++) {
destroyBuffer(pipeline->uniformBuffers[i]);
}

View File

@ -42,7 +42,7 @@ void Mesh::initMesh()
void Mesh::drawMesh(const gfx::Pipeline* pipeline)
{
gfx->drawIndexed(pipeline, vb, ib, m_indices.size());
gfx->draw(pipeline, vb, ib, m_indices.size(), nullptr);
}
Mesh::Mesh(GFXDevice* gfx, const std::vector<Vertex>& vertices) : Resource("", "mesh"), gfx(gfx)