removed render triangle test
This commit is contained in:
@@ -1,278 +0,0 @@
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <sophia/render_triangle_test.hpp>
|
||||
#include <sophia/util/logger.hpp>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "buffer.hpp"
|
||||
#include "device.hpp"
|
||||
#include "image.hpp"
|
||||
#include "pipelines/graphics_pipeline.hpp"
|
||||
#include "shader.hpp"
|
||||
#include "swapchain.hpp"
|
||||
|
||||
namespace sophia {
|
||||
|
||||
namespace {
|
||||
|
||||
struct Vertex {
|
||||
glm::vec2 position;
|
||||
glm::vec3 color;
|
||||
};
|
||||
|
||||
struct PushConstants {
|
||||
glm::mat4 transform;
|
||||
glm::vec4 color;
|
||||
glm::vec4 data;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void runRenderTriangleTest(const std::string& vertShaderPath,
|
||||
const std::string& fragShaderPath) {
|
||||
std::unique_ptr<sophia::Window> window =
|
||||
std::make_unique<Window>(750, 1000, "Render Triangle Test");
|
||||
std::unique_ptr<sophia::Device> device =
|
||||
Device::Builder().withWindow(*window).build();
|
||||
|
||||
log::info("Running Render Triangle Test...");
|
||||
|
||||
std::unique_ptr<Swapchain> swapchain =
|
||||
std::make_unique<Swapchain>(*device, window->getExtent());
|
||||
|
||||
auto vertexShader = Shader::Builder()
|
||||
.fromGLSL(vertShaderPath)
|
||||
.setStage(ShaderStage::VERTEX)
|
||||
.build();
|
||||
auto fragmentShader = Shader::Builder()
|
||||
.fromGLSL(fragShaderPath)
|
||||
.setStage(ShaderStage::FRAGMENT)
|
||||
.build();
|
||||
|
||||
vk::PushConstantRange pushConstantRange{};
|
||||
pushConstantRange.stageFlags =
|
||||
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
|
||||
pushConstantRange.offset = 0;
|
||||
pushConstantRange.size = sizeof(PushConstants);
|
||||
|
||||
vk::PipelineLayoutCreateInfo pipelineLayoutInfo{};
|
||||
pipelineLayoutInfo.pushConstantRangeCount = 1;
|
||||
pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;
|
||||
|
||||
vk::UniquePipelineLayout pipelineLayout =
|
||||
device->get()->createPipelineLayoutUnique(pipelineLayoutInfo);
|
||||
|
||||
std::vector<vk::VertexInputBindingDescription> bindingDescriptions{
|
||||
{0, sizeof(Vertex), vk::VertexInputRate::eVertex}};
|
||||
std::vector<vk::VertexInputAttributeDescription> attributeDescriptions{
|
||||
{0, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, position)},
|
||||
{1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color)}};
|
||||
|
||||
std::unique_ptr<sophia::GraphicsPipeline> graphicsPipeline =
|
||||
GraphicsPipeline::Builder(*device)
|
||||
.setVertexShader(*vertexShader)
|
||||
.setFragmentShader(*fragmentShader)
|
||||
.setPipelineLayout(pipelineLayout.get())
|
||||
.setColorAttachmentFormats({swapchain->getImageFormat()})
|
||||
.setVertexInput(bindingDescriptions, attributeDescriptions)
|
||||
.build();
|
||||
|
||||
// Oversized triangle covering the full screen so the fragment shader runs
|
||||
// for every pixel.
|
||||
std::vector<Vertex> vertices{
|
||||
{{-1.0f, -1.0f}, {1.0f, 0.0f, 0.0f}},
|
||||
{{3.0f, -1.0f}, {0.0f, 1.0f, 0.0f}},
|
||||
{{-1.0f, 3.0f}, {0.0f, 0.0f, 1.0f}},
|
||||
};
|
||||
|
||||
Buffer vertexBuffer{*device, sizeof(Vertex),
|
||||
static_cast<u32>(vertices.size()),
|
||||
vk::BufferUsageFlagBits::eVertexBuffer,
|
||||
vk::MemoryPropertyFlagBits::eHostVisible |
|
||||
vk::MemoryPropertyFlagBits::eHostCoherent};
|
||||
vertexBuffer.map();
|
||||
vertexBuffer.writeToBuffer(vertices.data(), sizeof(Vertex) * vertices.size());
|
||||
vertexBuffer.unmap();
|
||||
|
||||
vk::UniqueSemaphore imageAvailableSemaphore =
|
||||
device->get()->createSemaphoreUnique({});
|
||||
|
||||
std::vector<vk::UniqueSemaphore> renderFinishedSemaphores;
|
||||
for (size_t i = 0; i < swapchain->imageCount(); i++) {
|
||||
renderFinishedSemaphores.push_back(
|
||||
device->get()->createSemaphoreUnique({}));
|
||||
}
|
||||
|
||||
auto recreateSwapchain = [&]() {
|
||||
vk::Extent2D extent = window->getExtent();
|
||||
while (extent.width == 0 || extent.height == 0) {
|
||||
extent = window->getExtent();
|
||||
glfwWaitEvents();
|
||||
}
|
||||
|
||||
device->waitIdle();
|
||||
|
||||
std::shared_ptr<Swapchain> oldSwapchain = std::move(swapchain);
|
||||
swapchain = std::make_unique<Swapchain>(*device, extent, oldSwapchain);
|
||||
|
||||
if (!oldSwapchain->compareSwapchainFormats(*swapchain)) {
|
||||
log::fatal("swapchain image format changed on recreation");
|
||||
throw std::runtime_error("swapchain image format changed on recreation");
|
||||
}
|
||||
|
||||
renderFinishedSemaphores.clear();
|
||||
for (size_t i = 0; i < swapchain->imageCount(); i++) {
|
||||
renderFinishedSemaphores.push_back(
|
||||
device->get()->createSemaphoreUnique({}));
|
||||
}
|
||||
|
||||
log::trace("recreated swapchain");
|
||||
};
|
||||
|
||||
vk::UniqueFence inFlightFence =
|
||||
device->get()->createFenceUnique({vk::FenceCreateFlagBits::eSignaled});
|
||||
|
||||
vk::CommandBufferAllocateInfo commandBufferAllocInfo{
|
||||
device->getCommandPool(), vk::CommandBufferLevel::ePrimary, 1};
|
||||
vk::CommandBuffer commandBuffer =
|
||||
device->get()->allocateCommandBuffers(commandBufferAllocInfo)[0];
|
||||
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
|
||||
while (!window->shouldClose()) {
|
||||
glfwPollEvents();
|
||||
|
||||
double elapsedTime =
|
||||
std::chrono::duration<double>(
|
||||
std::chrono::high_resolution_clock::now() - startTime)
|
||||
.count();
|
||||
|
||||
vk::Fence inFlightFenceHandle = inFlightFence.get();
|
||||
(void)device->get()->waitForFences(inFlightFenceHandle, vk::True,
|
||||
std::numeric_limits<u64>::max());
|
||||
|
||||
vk::Semaphore imageAvailableSemaphoreHandle = imageAvailableSemaphore.get();
|
||||
u32 imageIndex = 0;
|
||||
vk::Result acquireResult =
|
||||
swapchain->acquireNextImage(imageAvailableSemaphoreHandle, imageIndex);
|
||||
if (acquireResult == vk::Result::eErrorOutOfDateKHR) {
|
||||
recreateSwapchain();
|
||||
continue;
|
||||
}
|
||||
if (acquireResult != vk::Result::eSuccess &&
|
||||
acquireResult != vk::Result::eSuboptimalKHR) {
|
||||
log::fatal("failed to acquire swapchain image");
|
||||
throw std::runtime_error("failed to acquire swapchain image");
|
||||
}
|
||||
|
||||
device->get()->resetFences(inFlightFenceHandle);
|
||||
|
||||
commandBuffer.reset();
|
||||
commandBuffer.begin(vk::CommandBufferBeginInfo{});
|
||||
|
||||
Image& image = swapchain->getImage(static_cast<int>(imageIndex));
|
||||
image.transitionLayout(commandBuffer,
|
||||
vk::ImageLayout::eColorAttachmentOptimal);
|
||||
|
||||
vk::ClearValue clearValue{};
|
||||
clearValue.color =
|
||||
vk::ClearColorValue{std::array<float, 4>{0.01f, 0.01f, 0.02f, 1.0f}};
|
||||
|
||||
vk::RenderingAttachmentInfo colorAttachment{};
|
||||
colorAttachment.imageView = image.getView();
|
||||
colorAttachment.imageLayout = vk::ImageLayout::eColorAttachmentOptimal;
|
||||
colorAttachment.loadOp = vk::AttachmentLoadOp::eClear;
|
||||
colorAttachment.storeOp = vk::AttachmentStoreOp::eStore;
|
||||
colorAttachment.clearValue = clearValue;
|
||||
|
||||
vk::RenderingInfo renderingInfo{};
|
||||
renderingInfo.renderArea = vk::Rect2D{{0, 0}, swapchain->getExtent()};
|
||||
renderingInfo.layerCount = 1;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachments = &colorAttachment;
|
||||
|
||||
commandBuffer.beginRendering(renderingInfo);
|
||||
|
||||
vk::Extent2D extent = swapchain->getExtent();
|
||||
vk::Viewport viewport{0.0f,
|
||||
0.0f,
|
||||
static_cast<float>(extent.width),
|
||||
static_cast<float>(extent.height),
|
||||
0.0f,
|
||||
1.0f};
|
||||
vk::Rect2D scissor{{0, 0}, extent};
|
||||
commandBuffer.setViewport(0, viewport);
|
||||
commandBuffer.setScissor(0, scissor);
|
||||
|
||||
graphicsPipeline->bind(commandBuffer);
|
||||
|
||||
vk::Buffer vertexBuffers[] = {vertexBuffer.getBuffer()};
|
||||
vk::DeviceSize offsets[] = {0};
|
||||
commandBuffer.bindVertexBuffers(0, vertexBuffers, offsets);
|
||||
|
||||
PushConstants push{};
|
||||
push.transform = glm::mat4(1.0f);
|
||||
push.color = glm::vec4(1.0f);
|
||||
push.data = glm::vec4(static_cast<float>(extent.width),
|
||||
static_cast<float>(extent.height),
|
||||
static_cast<float>(elapsedTime), 0.0f);
|
||||
commandBuffer.pushConstants(
|
||||
pipelineLayout.get(),
|
||||
vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment,
|
||||
0, sizeof(push), &push);
|
||||
|
||||
commandBuffer.draw(static_cast<u32>(vertices.size()), 1, 0, 0);
|
||||
|
||||
commandBuffer.endRendering();
|
||||
|
||||
image.transitionLayout(commandBuffer, vk::ImageLayout::ePresentSrcKHR);
|
||||
|
||||
commandBuffer.end();
|
||||
|
||||
vk::Semaphore renderFinishedSemaphoreHandle =
|
||||
renderFinishedSemaphores.at(imageIndex).get();
|
||||
vk::PipelineStageFlags waitStage =
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput;
|
||||
|
||||
vk::SubmitInfo submitInfo{};
|
||||
submitInfo.waitSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = &imageAvailableSemaphoreHandle;
|
||||
submitInfo.pWaitDstStageMask = &waitStage;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &commandBuffer;
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = &renderFinishedSemaphoreHandle;
|
||||
|
||||
device->getGraphicsQueue().submit(submitInfo, inFlightFenceHandle);
|
||||
|
||||
vk::Result presentResult = swapchain->present(
|
||||
device->getPresentQueue(), imageIndex, renderFinishedSemaphoreHandle);
|
||||
if (presentResult == vk::Result::eErrorOutOfDateKHR ||
|
||||
presentResult == vk::Result::eSuboptimalKHR || window->wasResized()) {
|
||||
window->resetResizedFlag();
|
||||
recreateSwapchain();
|
||||
continue;
|
||||
}
|
||||
if (presentResult != vk::Result::eSuccess) {
|
||||
log::fatal("failed to present swapchain image");
|
||||
throw std::runtime_error("failed to present swapchain image");
|
||||
}
|
||||
}
|
||||
|
||||
device->waitIdle();
|
||||
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
double totalRuntime =
|
||||
std::chrono::duration<double>(endTime - startTime).count();
|
||||
log::info("Application ran for", totalRuntime, "s");
|
||||
}
|
||||
|
||||
} // namespace sophia
|
||||
Reference in New Issue
Block a user