mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Get rendering kind-of working again
This commit is contained in:
parent
8abfc69154
commit
2bb75f4683
@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.24)
|
||||
# options
|
||||
option(ENGINE_BUILD_TEST "Compile the test program" ON)
|
||||
|
||||
SET(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo")
|
||||
|
||||
project(engine LANGUAGES CXX
|
||||
VERSION "0.1.0"
|
||||
)
|
||||
|
@ -65,6 +65,8 @@ namespace engine {
|
||||
InputManager* inputManager() { return m_inputManager.get(); }
|
||||
SceneManager* sceneManager() { return m_sceneManager.get(); }
|
||||
|
||||
gfx::DrawBuffer* getDrawBuffer() { return m_drawBuffer; }
|
||||
|
||||
std::string getResourcePath(const std::string relativePath) { return (m_resourcesPath / relativePath).string(); }
|
||||
|
||||
private:
|
||||
@ -77,7 +79,7 @@ namespace engine {
|
||||
|
||||
bool m_enableFrameLimiter = true;
|
||||
|
||||
gfx::CommandBuffer *m_drawCommandBuffer;
|
||||
gfx::DrawBuffer *m_drawBuffer;
|
||||
|
||||
/* resource stuff */
|
||||
|
||||
|
@ -90,6 +90,6 @@ namespace engine::gfx {
|
||||
struct Pipeline;
|
||||
struct Buffer;
|
||||
struct Texture;
|
||||
struct CommandBuffer;
|
||||
struct DrawBuffer;
|
||||
|
||||
}
|
||||
|
@ -19,12 +19,15 @@ namespace engine {
|
||||
|
||||
void getViewportSize(uint32_t *w, uint32_t *h);
|
||||
|
||||
gfx::CommandBuffer* beginRender();
|
||||
void finishRender(gfx::CommandBuffer* commandBuffer);
|
||||
gfx::DrawBuffer* beginRender();
|
||||
void finishRender(gfx::DrawBuffer* drawBuffer);
|
||||
|
||||
void cmdBindPipeline(gfx::CommandBuffer* commandBuffer, const gfx::Pipeline* pipeline);
|
||||
void cmdBindDescriptorSetTexture(gfx::CommandBuffer* commandBuffer, uint32_t set, uint32_t binding, const gfx::Texture* texture);
|
||||
void cmdBindDescriptorSetBuffer(gfx::CommandBuffer* commandBuffer, uint32_t set, uint32_t binding, const gfx::Texture* texture);
|
||||
void cmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline);
|
||||
void cmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer);
|
||||
void cmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer);
|
||||
void cmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
|
||||
//void cmdBindDescriptorSetTexture(gfx::CommandBuffer* commandBuffer, uint32_t set, uint32_t binding, const gfx::Texture* texture);
|
||||
//void cmdBindDescriptorSetBuffer(gfx::CommandBuffer* commandBuffer, uint32_t set, uint32_t binding, const gfx::Texture* texture);
|
||||
|
||||
// creates the equivalent of an OpenGL shader program & vertex attrib configuration
|
||||
gfx::Pipeline* createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize, bool alphaBlending, bool backfaceCulling);
|
||||
|
@ -1,13 +1,8 @@
|
||||
#version 450
|
||||
|
||||
layout( push_constant ) uniform Constants {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
} constants;
|
||||
|
||||
layout(location = 0) in vec3 inPosition;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = constants.view * constants.model * vec4(inPosition, 1.0);
|
||||
gl_Position = vec4(inPosition, 1.0);
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ namespace engine {
|
||||
while (m_window->isRunning()) {
|
||||
|
||||
/* begin rendering */
|
||||
m_drawCommandBuffer = m_gfx->beginRender();
|
||||
m_drawBuffer = m_gfx->beginRender();
|
||||
|
||||
/* logic */
|
||||
m_sceneManager->updateActiveScene(m_window->dt());
|
||||
@ -149,7 +149,7 @@ namespace engine {
|
||||
}
|
||||
|
||||
/* draw */
|
||||
m_gfx->finishRender(m_drawCommandBuffer);
|
||||
m_gfx->finishRender(m_drawBuffer);
|
||||
|
||||
/* poll events */
|
||||
m_window->getInputAndEvents();
|
||||
|
@ -43,22 +43,15 @@ namespace engine {
|
||||
static constexpr uint32_t FRAMES_IN_FLIGHT = 2; // This improved FPS by 5x! (on Intel IGPU)
|
||||
|
||||
static constexpr size_t PUSH_CONSTANT_MAX_SIZE = 128; // bytes
|
||||
static constexpr VkIndexType INDEX_TYPE = VK_INDEX_TYPE_UINT32;
|
||||
|
||||
// structures and enums
|
||||
|
||||
struct DepthBuffer {
|
||||
VkImage image;
|
||||
VmaAllocation allocation;
|
||||
VkImageView view;
|
||||
};
|
||||
|
||||
struct DrawCall {
|
||||
const gfx::Pipeline* pipeline = nullptr; // for performance, keep this the same for consecutive draw calls
|
||||
const gfx::Buffer* vertexBuffer = nullptr;
|
||||
const gfx::Buffer* indexBuffer = nullptr; // if this is nullptr, don't use indexed
|
||||
uint32_t count = 0;
|
||||
uint8_t pushConstantData[PUSH_CONSTANT_MAX_SIZE];
|
||||
const gfx::Texture* texture = nullptr;
|
||||
struct FrameData {
|
||||
VkFence renderFence = VK_NULL_HANDLE;
|
||||
VkSemaphore presentSemaphore = VK_NULL_HANDLE;
|
||||
VkSemaphore renderSemaphore = VK_NULL_HANDLE;
|
||||
VkCommandBuffer drawBuf = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
// handles
|
||||
@ -85,8 +78,8 @@ namespace engine {
|
||||
uint32_t mipLevels;
|
||||
};
|
||||
|
||||
struct gfx::CommandBuffer {
|
||||
uint32_t frameIndex; // needed to identify correct command buffer, fences and semaphores
|
||||
struct gfx::DrawBuffer {
|
||||
FrameData frameData;
|
||||
uint32_t imageIndex; // for swapchain present
|
||||
};
|
||||
|
||||
@ -325,7 +318,7 @@ namespace engine {
|
||||
if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; }
|
||||
throw std::runtime_error("MSAA is not supported");
|
||||
}
|
||||
|
||||
#endif
|
||||
static void copyBuffer(VkDevice device, VkCommandPool commandPool, VkQueue queue, VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
|
||||
{
|
||||
[[maybe_unused]] VkResult res;
|
||||
@ -373,6 +366,8 @@ namespace engine {
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static VkCommandBuffer beginOneTimeCommands(VkDevice device, VkCommandPool commandPool)
|
||||
{
|
||||
[[maybe_unused]] VkResult res;
|
||||
@ -528,6 +523,7 @@ namespace engine {
|
||||
0, nullptr,
|
||||
1, &barrier);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// class definitions
|
||||
@ -547,11 +543,8 @@ namespace engine {
|
||||
|
||||
uint64_t FRAMECOUNT = 0;
|
||||
|
||||
// temp
|
||||
VkFence renderFence = VK_NULL_HANDLE;
|
||||
VkSemaphore presentSemaphore = VK_NULL_HANDLE;
|
||||
VkSemaphore renderSemaphore = VK_NULL_HANDLE;
|
||||
VkCommandBuffer drawBuf = VK_NULL_HANDLE;
|
||||
FrameData frameData[FRAMES_IN_FLIGHT] = {};
|
||||
|
||||
bool swapchainIsOutOfDate = false;
|
||||
|
||||
};
|
||||
@ -579,7 +572,13 @@ namespace engine {
|
||||
throw std::runtime_error("The loaded Vulkan version must be at least 1.3");
|
||||
}
|
||||
|
||||
pimpl->instance = createVulkanInstance(pimpl->window, appName, appVersion);
|
||||
#ifdef NDEBUG
|
||||
bool useValidation = false;
|
||||
#else
|
||||
bool useValidation = true;
|
||||
#endif
|
||||
|
||||
pimpl->instance = createVulkanInstance(pimpl->window, appName, appVersion, useValidation, MessageSeverity::SEV_WARNING);
|
||||
|
||||
if (SDL_Vulkan_CreateSurface(pimpl->window, pimpl->instance.instance, &pimpl->surface) == false) {
|
||||
throw std::runtime_error("Unable to create window surface");
|
||||
@ -603,42 +602,45 @@ namespace engine {
|
||||
|
||||
/* the following is temporary setup */
|
||||
|
||||
VkFenceCreateInfo fenceInfo{
|
||||
for (int i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
||||
VkFenceCreateInfo fenceInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = VK_FENCE_CREATE_SIGNALED_BIT
|
||||
};
|
||||
res = vkCreateFence(pimpl->device.device, &fenceInfo, nullptr, &pimpl->renderFence);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create fence!");
|
||||
};
|
||||
res = vkCreateFence(pimpl->device.device, &fenceInfo, nullptr, &pimpl->frameData[i].renderFence);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create fence!");
|
||||
|
||||
VkSemaphoreCreateInfo smphInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0
|
||||
};
|
||||
res = vkCreateSemaphore(pimpl->device.device, &smphInfo, nullptr, &pimpl->presentSemaphore);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create semaphore!");
|
||||
res = vkCreateSemaphore(pimpl->device.device, &smphInfo, nullptr, &pimpl->renderSemaphore);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create semaphore!");
|
||||
VkSemaphoreCreateInfo smphInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0
|
||||
};
|
||||
res = vkCreateSemaphore(pimpl->device.device, &smphInfo, nullptr, &pimpl->frameData[i].presentSemaphore);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create semaphore!");
|
||||
res = vkCreateSemaphore(pimpl->device.device, &smphInfo, nullptr, &pimpl->frameData[i].renderSemaphore);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create semaphore!");
|
||||
|
||||
// Create the command buffer for rendering:
|
||||
VkCommandBufferAllocateInfo cmdAllocInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.commandPool = pimpl->device.commandPools.draw,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1
|
||||
};
|
||||
VKCHECK(vkAllocateCommandBuffers(pimpl->device.device, &cmdAllocInfo, &pimpl->drawBuf));
|
||||
VkCommandBufferAllocateInfo cmdAllocInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.commandPool = pimpl->device.commandPools.draw,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1
|
||||
};
|
||||
VKCHECK(vkAllocateCommandBuffers(pimpl->device.device, &cmdAllocInfo, &pimpl->frameData[i].drawBuf));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GFXDevice::~GFXDevice()
|
||||
{
|
||||
vkFreeCommandBuffers(pimpl->device.device, pimpl->device.commandPools.draw, 1, &pimpl->drawBuf);
|
||||
vkDestroySemaphore(pimpl->device.device, pimpl->renderSemaphore, nullptr);
|
||||
vkDestroySemaphore(pimpl->device.device, pimpl->presentSemaphore, nullptr);
|
||||
vkDestroyFence(pimpl->device.device, pimpl->renderFence, nullptr);
|
||||
for (int i = 0; i < FRAMES_IN_FLIGHT; i++) {
|
||||
vkFreeCommandBuffers(pimpl->device.device, pimpl->device.commandPools.draw, 1, &pimpl->frameData[i].drawBuf);
|
||||
vkDestroySemaphore(pimpl->device.device, pimpl->frameData[i].renderSemaphore, nullptr);
|
||||
vkDestroySemaphore(pimpl->device.device, pimpl->frameData[i].presentSemaphore, nullptr);
|
||||
vkDestroyFence(pimpl->device.device, pimpl->frameData[i].renderFence, nullptr);
|
||||
}
|
||||
|
||||
destroySwapchain(pimpl->swapchain);
|
||||
destroyAllocator(pimpl->allocator);
|
||||
@ -661,12 +663,14 @@ namespace engine {
|
||||
}
|
||||
}
|
||||
|
||||
gfx::CommandBuffer* GFXDevice::beginRender()
|
||||
gfx::DrawBuffer* GFXDevice::beginRender()
|
||||
{
|
||||
VkResult res;
|
||||
|
||||
uint32_t swapchainImageIndex;
|
||||
|
||||
FrameData frameData = pimpl->frameData[pimpl->FRAMECOUNT % FRAMES_IN_FLIGHT];
|
||||
|
||||
do {
|
||||
if (pimpl->swapchainIsOutOfDate) {
|
||||
// re-create swapchain
|
||||
@ -677,19 +681,19 @@ namespace engine {
|
||||
// THIS FUNCTION BLOCKS UNTIL AN IMAGE IS AVAILABLE (it waits for vsync)
|
||||
res = vkAcquireNextImageKHR(
|
||||
pimpl->device.device, pimpl->swapchain.swapchain, 1000000000LL,
|
||||
pimpl->presentSemaphore, VK_NULL_HANDLE, &swapchainImageIndex);
|
||||
frameData.presentSemaphore, VK_NULL_HANDLE, &swapchainImageIndex);
|
||||
if (res != VK_SUBOPTIMAL_KHR && res != VK_ERROR_OUT_OF_DATE_KHR) VKCHECK(res);
|
||||
if (res == VK_SUCCESS) pimpl->swapchainIsOutOfDate = false;
|
||||
} while (pimpl->swapchainIsOutOfDate);
|
||||
|
||||
/* wait until the previous frame RENDERING has finished */
|
||||
res = vkWaitForFences(pimpl->device.device, 1, &pimpl->renderFence, VK_TRUE, 1000000000LL);
|
||||
res = vkWaitForFences(pimpl->device.device, 1, &frameData.renderFence, VK_TRUE, 1000000000LL);
|
||||
VKCHECK(res);
|
||||
res = vkResetFences(pimpl->device.device, 1, &pimpl->renderFence);
|
||||
res = vkResetFences(pimpl->device.device, 1, &frameData.renderFence);
|
||||
VKCHECK(res);
|
||||
|
||||
/* record command buffer */
|
||||
res = vkResetCommandBuffer(pimpl->drawBuf, 0);
|
||||
res = vkResetCommandBuffer(frameData.drawBuf, 0);
|
||||
VKCHECK(res);
|
||||
|
||||
VkCommandBufferBeginInfo beginInfo{
|
||||
@ -698,7 +702,7 @@ namespace engine {
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
.pInheritanceInfo = nullptr // ignored
|
||||
};
|
||||
res = vkBeginCommandBuffer(pimpl->drawBuf, &beginInfo);
|
||||
res = vkBeginCommandBuffer(frameData.drawBuf, &beginInfo);
|
||||
VKCHECK(res);
|
||||
|
||||
{ // RECORDING
|
||||
@ -719,7 +723,7 @@ namespace engine {
|
||||
passBegin.renderArea.offset = { 0, 0 };
|
||||
passBegin.clearValueCount = 1;
|
||||
passBegin.pClearValues = &clearValue;
|
||||
vkCmdBeginRenderPass(pimpl->drawBuf, &passBegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
vkCmdBeginRenderPass(frameData.drawBuf, &passBegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
VkViewport viewport{};
|
||||
viewport.x = 0.0f;
|
||||
@ -728,33 +732,34 @@ namespace engine {
|
||||
viewport.height = -(float)pimpl->swapchain.extent.height;
|
||||
viewport.minDepth = 0.0f;
|
||||
viewport.maxDepth = 1.0f;
|
||||
vkCmdSetViewport(pimpl->drawBuf, 0, 1, &viewport);
|
||||
vkCmdSetViewport(frameData.drawBuf, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor{};
|
||||
scissor.offset = { 0, 0 };
|
||||
scissor.extent = pimpl->swapchain.extent;
|
||||
vkCmdSetScissor(pimpl->drawBuf, 0, 1, &scissor);
|
||||
vkCmdSetScissor(frameData.drawBuf, 0, 1, &scissor);
|
||||
|
||||
}
|
||||
|
||||
// hand command buffer over to caller
|
||||
gfx::CommandBuffer* commandBuffer = new gfx::CommandBuffer;
|
||||
commandBuffer->imageIndex = swapchainImageIndex;
|
||||
return commandBuffer;
|
||||
gfx::DrawBuffer* drawBuffer = new gfx::DrawBuffer;
|
||||
drawBuffer->frameData = frameData;
|
||||
drawBuffer->imageIndex = swapchainImageIndex;
|
||||
return drawBuffer;
|
||||
|
||||
}
|
||||
|
||||
void GFXDevice::finishRender(gfx::CommandBuffer* commandBuffer)
|
||||
void GFXDevice::finishRender(gfx::DrawBuffer* drawBuffer)
|
||||
{
|
||||
if (commandBuffer == nullptr) {
|
||||
if (drawBuffer == nullptr) {
|
||||
return;
|
||||
}
|
||||
uint32_t swapchainImageIndex = commandBuffer->imageIndex;
|
||||
uint32_t swapchainImageIndex = drawBuffer->imageIndex;
|
||||
VkResult res;
|
||||
|
||||
vkCmdEndRenderPass(pimpl->drawBuf);
|
||||
vkCmdEndRenderPass(drawBuffer->frameData.drawBuf);
|
||||
|
||||
res = vkEndCommandBuffer(pimpl->drawBuf);
|
||||
res = vkEndCommandBuffer(drawBuffer->frameData.drawBuf);
|
||||
VKCHECK(res);
|
||||
|
||||
// SUBMIT
|
||||
@ -765,15 +770,15 @@ namespace engine {
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.pNext = nullptr,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &pimpl->presentSemaphore,
|
||||
.pWaitSemaphores = &drawBuffer->frameData.presentSemaphore,
|
||||
.pWaitDstStageMask = &waitStage,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &pimpl->drawBuf,
|
||||
.pCommandBuffers = &drawBuffer->frameData.drawBuf,
|
||||
.signalSemaphoreCount = 1,
|
||||
.pSignalSemaphores = &pimpl->renderSemaphore,
|
||||
.pSignalSemaphores = &drawBuffer->frameData.renderSemaphore,
|
||||
};
|
||||
res = vkQueueSubmit(pimpl->device.queues.drawQueues[0], 1, &submitInfo, pimpl->renderFence);
|
||||
VKCHECK(res);
|
||||
res = vkQueueSubmit(pimpl->device.queues.drawQueues[0], 1, &submitInfo, drawBuffer->frameData.renderFence);
|
||||
// VKCHECK(res); // expensive operation for some reason
|
||||
|
||||
// PRESENT
|
||||
|
||||
@ -781,7 +786,7 @@ namespace engine {
|
||||
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.waitSemaphoreCount = 1,
|
||||
.pWaitSemaphores = &pimpl->renderSemaphore,
|
||||
.pWaitSemaphores = &drawBuffer->frameData.renderSemaphore,
|
||||
.swapchainCount = 1,
|
||||
.pSwapchains = &pimpl->swapchain.swapchain,
|
||||
.pImageIndices = &swapchainImageIndex,
|
||||
@ -796,7 +801,36 @@ namespace engine {
|
||||
|
||||
pimpl->FRAMECOUNT++;
|
||||
|
||||
delete commandBuffer;
|
||||
delete drawBuffer;
|
||||
}
|
||||
|
||||
void GFXDevice::cmdBindPipeline(gfx::DrawBuffer* drawBuffer, const gfx::Pipeline* pipeline)
|
||||
{
|
||||
assert(drawBuffer != nullptr);
|
||||
vkCmdBindPipeline(drawBuffer->frameData.drawBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle);
|
||||
}
|
||||
|
||||
void GFXDevice::cmdBindVertexBuffer(gfx::DrawBuffer* drawBuffer, uint32_t binding, const gfx::Buffer* buffer)
|
||||
{
|
||||
assert(drawBuffer != nullptr);
|
||||
assert(buffer != nullptr);
|
||||
assert(buffer->type == gfx::BufferType::VERTEX);
|
||||
const VkDeviceSize offset = 0;
|
||||
vkCmdBindVertexBuffers(drawBuffer->frameData.drawBuf, binding, 1, &buffer->buffer, &offset);
|
||||
}
|
||||
|
||||
void GFXDevice::cmdBindIndexBuffer(gfx::DrawBuffer* drawBuffer, const gfx::Buffer* buffer)
|
||||
{
|
||||
assert(drawBuffer != nullptr);
|
||||
assert(buffer != nullptr);
|
||||
assert(buffer->type == gfx::BufferType::INDEX);
|
||||
vkCmdBindIndexBuffer(drawBuffer->frameData.drawBuf, buffer->buffer, 0, INDEX_TYPE);
|
||||
}
|
||||
|
||||
void GFXDevice::cmdDrawIndexed(gfx::DrawBuffer* drawBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)
|
||||
{
|
||||
assert(drawBuffer != nullptr);
|
||||
vkCmdDrawIndexed(drawBuffer->frameData.drawBuf, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
|
||||
}
|
||||
|
||||
gfx::Pipeline* GFXDevice::createPipeline(const char* vertShaderPath, const char* fragShaderPath, const gfx::VertexFormat& vertexFormat, uint64_t uniformBufferSize, bool alphaBlending, bool backfaceCulling)
|
||||
@ -1037,8 +1071,6 @@ namespace engine {
|
||||
|
||||
out->type = type;
|
||||
|
||||
#if 0
|
||||
|
||||
VkBuffer stagingBuffer;
|
||||
VmaAllocation stagingAllocation;
|
||||
|
||||
@ -1084,20 +1116,17 @@ namespace engine {
|
||||
}
|
||||
|
||||
// copy the data from the staging buffer to the gpu buffer
|
||||
copyBuffer(pimpl->device, pimpl->commandPool, pimpl->gfxQueue.handle, stagingBuffer, out->buffer, out->size);
|
||||
copyBuffer(pimpl->device.device, pimpl->device.commandPools.transfer, pimpl->device.queues.transferQueues[0], stagingBuffer, out->buffer, out->size);
|
||||
|
||||
// destroy staging buffer
|
||||
vmaDestroyBuffer(pimpl->allocator, stagingBuffer, stagingAllocation);
|
||||
#endif
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
void GFXDevice::destroyBuffer(const gfx::Buffer* buffer)
|
||||
{
|
||||
#if 0
|
||||
vmaDestroyBuffer(pimpl->allocator, buffer->buffer, buffer->allocation);
|
||||
#endif
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ namespace engine {
|
||||
|
||||
GFXDevice* const gfx = m_scene->app()->gfx();
|
||||
|
||||
gfx::DrawBuffer* drawBuffer = m_scene->app()->getDrawBuffer();
|
||||
/* camera stuff */
|
||||
|
||||
const auto cameraTransform = m_scene->getComponent<TransformComponent>(m_camera.camEntity);
|
||||
@ -56,7 +57,7 @@ namespace engine {
|
||||
|
||||
assert(r->material != nullptr);
|
||||
assert(r->mesh != nullptr);
|
||||
assert(r->material->m_texture != nullptr);
|
||||
//assert(r->material->m_texture != nullptr);
|
||||
|
||||
struct {
|
||||
glm::mat4 proj;
|
||||
@ -76,6 +77,11 @@ namespace engine {
|
||||
pushConsts.model = t->worldMatrix;
|
||||
pushConsts.view = viewMatrix;
|
||||
|
||||
gfx->cmdBindPipeline(drawBuffer, r->material->getShader()->getPipeline());
|
||||
gfx->cmdBindVertexBuffer(drawBuffer, 0, r->mesh->getVB());
|
||||
gfx->cmdBindIndexBuffer(drawBuffer, r->mesh->getIB());
|
||||
gfx->cmdDrawIndexed(drawBuffer, r->mesh->getCount(), 1, 0, 0, 0);
|
||||
|
||||
/*
|
||||
gfx->draw(
|
||||
r->material->getShader()->getPipeline(),
|
||||
|
@ -87,7 +87,7 @@ namespace engine {
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
static VkDebugUtilsMessengerCreateInfoEXT getDebugMessengerCreateInfo()
|
||||
static VkDebugUtilsMessengerCreateInfoEXT getDebugMessengerCreateInfo(MessageSeverity validationLevel)
|
||||
{
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugMessengerInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
@ -102,15 +102,7 @@ namespace engine {
|
||||
.pUserData = nullptr,
|
||||
};
|
||||
|
||||
enum class MessageSeverity {
|
||||
SEV_VERBOSE,
|
||||
SEV_INFO,
|
||||
SEV_WARNING,
|
||||
SEV_ERROR // windows.h defines ERROR annoyingly
|
||||
};
|
||||
|
||||
constexpr MessageSeverity MESSAGE_LEVEL = MessageSeverity::SEV_WARNING;
|
||||
switch (MESSAGE_LEVEL) {
|
||||
switch (validationLevel) {
|
||||
case MessageSeverity::SEV_VERBOSE:
|
||||
debugMessengerInfo.messageSeverity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
||||
[[fallthrough]];
|
||||
@ -130,7 +122,7 @@ namespace engine {
|
||||
return debugMessengerInfo;
|
||||
}
|
||||
|
||||
Instance createVulkanInstance(SDL_Window* window, const char* appName, const char* appVersion)
|
||||
Instance createVulkanInstance(SDL_Window* window, const char* appName, const char* appVersion, bool useValidation, MessageSeverity validationLevel)
|
||||
{
|
||||
Instance instance;
|
||||
|
||||
@ -152,22 +144,31 @@ namespace engine {
|
||||
|
||||
const std::vector<const char*> windowExtensions = getWindowExtensions(window);
|
||||
std::vector<const char*> instanceExtensionsToUse = windowExtensions;
|
||||
instanceExtensionsToUse.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
if (useValidation) instanceExtensionsToUse.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
|
||||
const char* const validationLayer = getValidationLayer();
|
||||
const char* validationLayer = nullptr;
|
||||
if (useValidation) {
|
||||
const char* validationLayer = getValidationLayer();
|
||||
}
|
||||
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugMessengerInfo = getDebugMessengerCreateInfo();
|
||||
VkDebugUtilsMessengerCreateInfoEXT debugMessengerInfo = getDebugMessengerCreateInfo(validationLevel);
|
||||
|
||||
VkInstanceCreateInfo instanceInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
|
||||
.pNext = &debugMessengerInfo,
|
||||
.flags = 0,
|
||||
.pApplicationInfo = &applicationInfo,
|
||||
.enabledLayerCount = 1,
|
||||
.ppEnabledLayerNames = &validationLayer,
|
||||
.enabledExtensionCount = (uint32_t)instanceExtensionsToUse.size(),
|
||||
.ppEnabledExtensionNames = instanceExtensionsToUse.data(),
|
||||
.flags = 0
|
||||
};
|
||||
instanceInfo.pApplicationInfo = &applicationInfo;
|
||||
if (validationLayer) {
|
||||
instanceInfo.enabledLayerCount = 1;
|
||||
instanceInfo.ppEnabledLayerNames = &validationLayer;
|
||||
}
|
||||
else {
|
||||
instanceInfo.enabledLayerCount = 0;
|
||||
instanceInfo.ppEnabledLayerNames = nullptr;
|
||||
}
|
||||
instanceInfo.enabledExtensionCount = (uint32_t)instanceExtensionsToUse.size();
|
||||
instanceInfo.ppEnabledExtensionNames = instanceExtensionsToUse.data();
|
||||
|
||||
VkResult res;
|
||||
res = vkCreateInstance(&instanceInfo, nullptr, &instance.instance);
|
||||
@ -181,11 +182,12 @@ namespace engine {
|
||||
volkLoadInstanceOnly(instance.instance);
|
||||
|
||||
// create the debug messenger
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo = getDebugMessengerCreateInfo();
|
||||
|
||||
res = vkCreateDebugUtilsMessengerEXT(instance.instance, &createInfo, nullptr, &instance.debugMessenger);
|
||||
if (res != VK_SUCCESS) {
|
||||
throw std::runtime_error("vkCreateDebugUtilsMessengerExt failed: " + std::to_string(res));
|
||||
if (useValidation) {
|
||||
VkDebugUtilsMessengerCreateInfoEXT createInfo = getDebugMessengerCreateInfo(validationLevel);
|
||||
res = vkCreateDebugUtilsMessengerEXT(instance.instance, &createInfo, nullptr, &instance.debugMessenger);
|
||||
if (res != VK_SUCCESS) {
|
||||
throw std::runtime_error("vkCreateDebugUtilsMessengerExt failed: " + std::to_string(res));
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
@ -193,7 +195,9 @@ namespace engine {
|
||||
|
||||
void destroyVulkanInstance(Instance instance)
|
||||
{
|
||||
vkDestroyDebugUtilsMessengerEXT(instance.instance, instance.debugMessenger, nullptr);
|
||||
if (instance.debugMessenger != VK_NULL_HANDLE) {
|
||||
vkDestroyDebugUtilsMessengerEXT(instance.instance, instance.debugMessenger, nullptr);
|
||||
}
|
||||
vkDestroyInstance(instance.instance, nullptr);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,14 @@ namespace engine {
|
||||
VkDebugUtilsMessengerEXT debugMessenger = VK_NULL_HANDLE;
|
||||
};
|
||||
|
||||
Instance createVulkanInstance(SDL_Window* window, const char* appName, const char* appVersion);
|
||||
enum class MessageSeverity {
|
||||
SEV_VERBOSE,
|
||||
SEV_INFO,
|
||||
SEV_WARNING,
|
||||
SEV_ERROR // windows.h defines ERROR annoyingly
|
||||
};
|
||||
|
||||
Instance createVulkanInstance(SDL_Window* window, const char* appName, const char* appVersion, bool useValidation, MessageSeverity validationLevel = MessageSeverity::SEV_WARNING);
|
||||
void destroyVulkanInstance(Instance instance);
|
||||
|
||||
}
|
@ -44,6 +44,7 @@ void playGame(bool enableFrameLimiter)
|
||||
|
||||
engine::gfx::GraphicsSettings graphicsSettings{};
|
||||
graphicsSettings.vsync = true;
|
||||
graphicsSettings.waitForPresent = false;
|
||||
graphicsSettings.msaaLevel = engine::gfx::MSAALevel::MSAA_OFF;
|
||||
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphicsSettings);
|
||||
|
||||
@ -60,12 +61,25 @@ void playGame(bool enableFrameLimiter)
|
||||
const std::string fragPath = app.getResourcePath("engine/shaders/test.frag");
|
||||
engine::resources::Shader::VertexParams vertexParams{};
|
||||
vertexParams.hasColor = false;
|
||||
vertexParams.hasNormal = false;
|
||||
vertexParams.hasNormal = true;
|
||||
vertexParams.hasTangent = false;
|
||||
vertexParams.hasUV0 = false;
|
||||
vertexParams.hasUV0 = true;
|
||||
bool alphaBlending = false;
|
||||
bool cullBackFace = false;
|
||||
engine::resources::Shader testShader(app.gfx(), vertPath.c_str(), fragPath.c_str(), vertexParams, alphaBlending, cullBackFace);
|
||||
bool cullBackFace = true;
|
||||
auto testShader = std::make_shared<engine::resources::Shader>(app.gfx(), vertPath.c_str(), fragPath.c_str(), vertexParams, alphaBlending, cullBackFace);
|
||||
|
||||
auto camera = myScene->createEntity("camera");
|
||||
|
||||
auto renderSystem = myScene->getSystem<engine::RenderSystem>();
|
||||
renderSystem->setCameraEntity(camera);
|
||||
myScene->getComponent<engine::TransformComponent>(camera)->position = { 0.0f, 10.0f, 0.0f };
|
||||
|
||||
/* cube */
|
||||
uint32_t cube = myScene->createEntity("cube");
|
||||
myScene->getComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f, -0.5f, -0.5f };
|
||||
auto cubeRenderable = myScene->addComponent<engine::RenderableComponent>(cube);
|
||||
cubeRenderable->material = std::make_shared<engine::resources::Material>(testShader);
|
||||
cubeRenderable->mesh = genCuboidMesh(app.gfx(), 1, 1.0f, 1, 1);
|
||||
|
||||
#if 0
|
||||
|
||||
|
@ -14,7 +14,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
bool enableFrameLimiter = true;
|
||||
if (argc == 2) {
|
||||
if (strcmp(argv[2], "nofpslimit") == 0) enableFrameLimiter = false;
|
||||
if (strcmp(argv[1], "nofpslimit") == 0) enableFrameLimiter = false;
|
||||
}
|
||||
|
||||
engine::setupLog(PROJECT_NAME);
|
||||
|
Loading…
Reference in New Issue
Block a user