Multisampling implementation using the max samples the GPU supports
This commit is contained in:
19
src/agnosiaimgui.cpp
Normal file
19
src/agnosiaimgui.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "agnosiaimgui.h"
|
||||
#include "imgui.h"
|
||||
|
||||
namespace agnosia_imgui {
|
||||
|
||||
struct {
|
||||
} ImGuiSettings;
|
||||
|
||||
void Gui::drawTabs() {
|
||||
if (ImGui::BeginTabBar("MainTabBar", ImGuiTabBarFlags_Reorderable)) {
|
||||
if (ImGui::BeginTabItem("Graphics Pipeline")) {
|
||||
ImGui::Text("Test");
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
}
|
||||
} // namespace agnosia_imgui
|
11
src/agnosiaimgui.h
Normal file
11
src/agnosiaimgui.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include "global.h"
|
||||
#include "imgui.h"
|
||||
#include <map>
|
||||
|
||||
namespace agnosia_imgui {
|
||||
class Gui {
|
||||
public:
|
||||
static void drawTabs();
|
||||
};
|
||||
} // namespace agnosia_imgui
|
@@ -1,4 +1,5 @@
|
||||
#include "devicelibrary.h"
|
||||
#include "global.h"
|
||||
|
||||
namespace device_libs {
|
||||
|
||||
@@ -162,6 +163,36 @@ VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities,
|
||||
return actualExtent;
|
||||
}
|
||||
}
|
||||
|
||||
VkSampleCountFlagBits getMaxUsableSampleCount() {
|
||||
VkPhysicalDeviceProperties physicalDeviceProps;
|
||||
VkSampleCountFlags maxCounts;
|
||||
vkGetPhysicalDeviceProperties(Global::physicalDevice, &physicalDeviceProps);
|
||||
|
||||
VkSampleCountFlags counts =
|
||||
physicalDeviceProps.limits.framebufferColorSampleCounts &
|
||||
physicalDeviceProps.limits.framebufferDepthSampleCounts;
|
||||
if (counts & VK_SAMPLE_COUNT_64_BIT) {
|
||||
return VK_SAMPLE_COUNT_64_BIT;
|
||||
}
|
||||
if (counts & VK_SAMPLE_COUNT_32_BIT) {
|
||||
return VK_SAMPLE_COUNT_32_BIT;
|
||||
}
|
||||
if (counts & VK_SAMPLE_COUNT_16_BIT) {
|
||||
return VK_SAMPLE_COUNT_16_BIT;
|
||||
}
|
||||
if (counts & VK_SAMPLE_COUNT_8_BIT) {
|
||||
return VK_SAMPLE_COUNT_8_BIT;
|
||||
}
|
||||
if (counts & VK_SAMPLE_COUNT_4_BIT) {
|
||||
return VK_SAMPLE_COUNT_4_BIT;
|
||||
}
|
||||
if (counts & VK_SAMPLE_COUNT_2_BIT) {
|
||||
return VK_SAMPLE_COUNT_2_BIT;
|
||||
}
|
||||
|
||||
return VK_SAMPLE_COUNT_1_BIT;
|
||||
}
|
||||
// --------------------------------------- External Functions
|
||||
// ----------------------------------------- //
|
||||
void DeviceControl::pickPhysicalDevice(VkInstance &instance) {
|
||||
@@ -180,6 +211,7 @@ void DeviceControl::pickPhysicalDevice(VkInstance &instance) {
|
||||
// Once we have buttons or such, maybe ask the user or write a config file
|
||||
// for which GPU to use?
|
||||
Global::physicalDevice = device;
|
||||
Global::perPixelSampleCount = getMaxUsableSampleCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -378,6 +410,7 @@ void DeviceControl::destroyImageViews() {
|
||||
vkDestroyImageView(Global::device, imageView, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------- Getters & Setters
|
||||
// ------------------------------------------ //
|
||||
VkFormat *DeviceControl::getImageFormat() { return &swapChainImageFormat; }
|
||||
|
@@ -1,5 +1,9 @@
|
||||
#include "entrypoint.h"
|
||||
#include "global.h"
|
||||
#include "graphics/texture.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_vulkan.h"
|
||||
|
||||
VkInstance vulkaninstance;
|
||||
|
||||
@@ -88,6 +92,7 @@ void initVulkan() {
|
||||
buffers_libs::Buffers::createDescriptorSetLayout();
|
||||
graphics_pipeline::Graphics::createGraphicsPipeline();
|
||||
graphics_pipeline::Graphics::createCommandPool();
|
||||
texture_libs::Texture::createColorResources();
|
||||
texture_libs::Texture::createDepthResources();
|
||||
texture_libs::Texture::createTextureImage();
|
||||
texture_libs::Texture::createTextureImageView();
|
||||
@@ -126,6 +131,10 @@ void cleanup() {
|
||||
render_present::Render::destroyFenceSemaphores();
|
||||
graphics_pipeline::Graphics::destroyCommandPool();
|
||||
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
vkDestroyDevice(Global::device, nullptr);
|
||||
device_libs::DeviceControl::destroySurface(vulkaninstance);
|
||||
vkDestroyInstance(vulkaninstance, nullptr);
|
||||
|
@@ -5,6 +5,7 @@ namespace Global {
|
||||
VkSurfaceKHR surface;
|
||||
VkDevice device;
|
||||
VkPhysicalDevice physicalDevice;
|
||||
VkSampleCountFlagBits perPixelSampleCount;
|
||||
VkSwapchainKHR swapChain;
|
||||
VkCommandPool commandPool;
|
||||
std::vector<VkCommandBuffer> commandBuffers;
|
||||
@@ -16,6 +17,9 @@ std::vector<VkDescriptorSet> descriptorSets;
|
||||
uint32_t currentFrame = 0;
|
||||
VkImageView textureImageView;
|
||||
VkSampler textureSampler;
|
||||
VkImageView colorImageView;
|
||||
VkImage colorImage;
|
||||
VkDeviceMemory colorImageMemory;
|
||||
VkImageView depthImageView;
|
||||
VkImage depthImage;
|
||||
VkDeviceMemory depthImageMemory;
|
||||
|
@@ -28,6 +28,7 @@ namespace Global {
|
||||
// enabled first, so that's one obvious global, as well as the glfw includes!
|
||||
|
||||
extern VkPhysicalDevice physicalDevice;
|
||||
extern VkSampleCountFlagBits perPixelSampleCount;
|
||||
extern VkDevice device;
|
||||
|
||||
extern VkCommandPool commandPool;
|
||||
@@ -46,6 +47,10 @@ extern VkDescriptorSetLayout descriptorSetLayout;
|
||||
extern VkImageView textureImageView;
|
||||
extern VkSampler textureSampler;
|
||||
|
||||
extern VkImage colorImage;
|
||||
extern VkImageView colorImageView;
|
||||
extern VkDeviceMemory colorImageMemory;
|
||||
|
||||
extern VkImage depthImage;
|
||||
extern VkImageView depthImageView;
|
||||
extern VkDeviceMemory depthImageMemory;
|
||||
@@ -53,8 +58,8 @@ extern VkDeviceMemory depthImageMemory;
|
||||
extern VkSwapchainKHR swapChain;
|
||||
extern std::vector<VkImageView> swapChainImageViews;
|
||||
|
||||
const std::string MODEL_PATH = "assets/models/teapot.obj";
|
||||
const std::string TEXTURE_PATH = "assets/textures/checkermap.png";
|
||||
const std::string MODEL_PATH = "assets/models/viking_room.obj";
|
||||
const std::string TEXTURE_PATH = "assets/textures/viking_room.png";
|
||||
const uint32_t WIDTH = 800;
|
||||
const uint32_t HEIGHT = 600;
|
||||
const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||
|
@@ -2,6 +2,7 @@
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_vulkan.h"
|
||||
#include "texture.h"
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace graphics_pipeline {
|
||||
|
||||
@@ -149,8 +150,7 @@ void Graphics::createGraphicsPipeline() {
|
||||
multisampling.sType =
|
||||
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
multisampling.sampleShadingEnable = VK_FALSE;
|
||||
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
multisampling.rasterizationSamples = Global::perPixelSampleCount;
|
||||
// TODO: Document!
|
||||
VkPipelineDepthStencilStateCreateInfo depthStencil{};
|
||||
depthStencil.sType =
|
||||
@@ -295,8 +295,11 @@ void Graphics::recordCommandBuffer(VkCommandBuffer commandBuffer,
|
||||
|
||||
const VkRenderingAttachmentInfo colorAttachmentInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
|
||||
.imageView = Global::swapChainImageViews[imageIndex],
|
||||
.imageView = Global::colorImageView,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT,
|
||||
.resolveImageView = Global::swapChainImageViews[imageIndex],
|
||||
.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.clearValue = {.color = {0.0f, 0.0f, 0.0f, 1.0f}},
|
||||
@@ -306,7 +309,7 @@ void Graphics::recordCommandBuffer(VkCommandBuffer commandBuffer,
|
||||
.imageView = Global::depthImageView,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.clearValue = {.depthStencil = {1.0f, 0}},
|
||||
};
|
||||
|
||||
|
@@ -4,10 +4,9 @@
|
||||
#include "graphicspipeline.h"
|
||||
#include "render.h"
|
||||
#include "texture.h"
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "../agnosiaimgui.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_vulkan.h"
|
||||
@@ -19,6 +18,8 @@ std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||
std::vector<VkFence> inFlightFences;
|
||||
VkDescriptorPool imGuiDescriptorPool;
|
||||
|
||||
static float floatBar = 0.0f;
|
||||
|
||||
void recreateSwapChain() {
|
||||
int width = 0, height = 0;
|
||||
glfwGetFramebufferSize(Global::window, &width, &height);
|
||||
@@ -37,6 +38,7 @@ void recreateSwapChain() {
|
||||
|
||||
device_libs::DeviceControl::createSwapChain(Global::window);
|
||||
device_libs::DeviceControl::createImageViews();
|
||||
texture_libs::Texture::createColorResources();
|
||||
texture_libs::Texture::createDepthResources();
|
||||
}
|
||||
// At a high level, rendering in Vulkan consists of 5 steps:
|
||||
@@ -123,28 +125,23 @@ void Render::drawImGui() {
|
||||
ImGui::NewFrame();
|
||||
// 2. Show a simple window that we create ourselves. We use a Begin/End pair
|
||||
// to create a named window.
|
||||
{
|
||||
static float f = 0.0f;
|
||||
static int counter = 0;
|
||||
|
||||
ImGui::Begin("Agnosia Debug"); // Create a window called "Hello, world!" and
|
||||
// append into it.
|
||||
static int counter = 0;
|
||||
|
||||
ImGui::Text("This is some useful text."); // Display some text (you can use
|
||||
// a format strings too)
|
||||
ImGui::SliderFloat("float", &f, 0.0f,
|
||||
1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||
ImGui::Begin("Agnosia Debug"); // Create a window called "Hello, world!" and
|
||||
// append into it.
|
||||
|
||||
if (ImGui::Button("Button")) // Buttons return true when clicked (most
|
||||
// widgets return true when edited/activated)
|
||||
counter++;
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("counter = %d", counter);
|
||||
ImGui::Text("This is some useful text."); // Display some text (you can use
|
||||
// a format strings too)
|
||||
ImGui::SliderFloat("float", &floatBar, 0.0f,
|
||||
1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||
|
||||
agnosia_imgui::Gui::drawTabs();
|
||||
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
|
||||
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)",
|
||||
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::Render();
|
||||
}
|
||||
#pragma info
|
||||
@@ -202,6 +199,9 @@ void Render::destroyFenceSemaphores() {
|
||||
}
|
||||
}
|
||||
void Render::cleanupSwapChain() {
|
||||
vkDestroyImageView(Global::device, Global::colorImageView, nullptr);
|
||||
vkDestroyImage(Global::device, Global::colorImage, nullptr);
|
||||
vkFreeMemory(Global::device, Global::colorImageMemory, nullptr);
|
||||
vkDestroyImageView(Global::device, Global::depthImageView, nullptr);
|
||||
vkDestroyImage(Global::device, Global::depthImage, nullptr);
|
||||
vkFreeMemory(Global::device, Global::depthImageMemory, nullptr);
|
||||
@@ -273,6 +273,5 @@ void Render::init_imgui(VkInstance instance) {
|
||||
};
|
||||
|
||||
ImGui_ImplVulkan_Init(&initInfo);
|
||||
|
||||
} // namespace render_present
|
||||
}
|
||||
} // namespace render_present
|
||||
|
@@ -10,5 +10,6 @@ public:
|
||||
static void cleanupSwapChain();
|
||||
static void init_imgui(VkInstance instance);
|
||||
static void drawImGui();
|
||||
static float getFloatBar();
|
||||
};
|
||||
} // namespace render_present
|
||||
|
@@ -1,4 +1,3 @@
|
||||
#include <cstdint>
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "texture.h"
|
||||
#include <stb/stb_image.h>
|
||||
@@ -12,7 +11,8 @@ VkPipelineStageFlags destinationStage;
|
||||
|
||||
namespace texture_libs {
|
||||
void createImage(uint32_t width, uint32_t height, uint32_t mipLevels,
|
||||
VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage,
|
||||
VkSampleCountFlagBits sampleNum, VkFormat format,
|
||||
VkImageTiling tiling, VkImageUsageFlags usage,
|
||||
VkMemoryPropertyFlags properties, VkImage &image,
|
||||
VkDeviceMemory &imageMemory) {
|
||||
// This function specifies all the data in an image object, this is called
|
||||
@@ -29,7 +29,7 @@ void createImage(uint32_t width, uint32_t height, uint32_t mipLevels,
|
||||
imageInfo.tiling = tiling;
|
||||
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
imageInfo.usage = usage;
|
||||
imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
imageInfo.samples = sampleNum;
|
||||
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
imageInfo.mipLevels = mipLevels;
|
||||
|
||||
@@ -309,8 +309,8 @@ void Texture::createTextureImage() {
|
||||
|
||||
stbi_image_free(pixels);
|
||||
|
||||
createImage(textureWidth, textureHeight, mipLevels, VK_FORMAT_R8G8B8A8_SRGB,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
createImage(textureWidth, textureHeight, mipLevels, VK_SAMPLE_COUNT_1_BIT,
|
||||
VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, textureImage,
|
||||
@@ -395,11 +395,24 @@ VkFormat Texture::findDepthFormat() {
|
||||
VK_FORMAT_D24_UNORM_S8_UINT},
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
}
|
||||
void Texture::createColorResources() {
|
||||
VkFormat colorFormat = *device_libs::DeviceControl::getImageFormat();
|
||||
VkExtent2D swapChainExtent = device_libs::DeviceControl::getSwapChainExtent();
|
||||
|
||||
createImage(swapChainExtent.width, swapChainExtent.height, 1,
|
||||
Global::perPixelSampleCount, colorFormat, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, Global::colorImage,
|
||||
Global::colorImageMemory);
|
||||
Global::colorImageView = device_libs::DeviceControl::createImageView(
|
||||
Global::colorImage, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1);
|
||||
}
|
||||
void Texture::createDepthResources() {
|
||||
VkFormat depthFormat = findDepthFormat();
|
||||
VkExtent2D swapChainExtent = device_libs::DeviceControl::getSwapChainExtent();
|
||||
createImage(swapChainExtent.width, swapChainExtent.height, 1, depthFormat,
|
||||
VK_IMAGE_TILING_OPTIMAL,
|
||||
createImage(swapChainExtent.width, swapChainExtent.height, 1,
|
||||
Global::perPixelSampleCount, depthFormat, VK_IMAGE_TILING_OPTIMAL,
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, Global::depthImage,
|
||||
Global::depthImageMemory);
|
||||
|
@@ -1,20 +1,21 @@
|
||||
#pragma once
|
||||
#include "../devicelibrary.h"
|
||||
#include "../global.h"
|
||||
#include "buffers.h"
|
||||
#include "../devicelibrary.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace texture_libs {
|
||||
class Texture {
|
||||
public:
|
||||
static void createTextureImage();
|
||||
static void createTextureImageView();
|
||||
static void createTextureSampler();
|
||||
static void destroyTextureImage();
|
||||
static void destroyTextureSampler();
|
||||
static VkFormat findDepthFormat();
|
||||
static void createDepthResources();
|
||||
|
||||
// ------------ Getters & Setters ------------ //
|
||||
static uint32_t getMipLevels();
|
||||
};
|
||||
}
|
||||
class Texture {
|
||||
public:
|
||||
static void createTextureImage();
|
||||
static void createTextureImageView();
|
||||
static void createTextureSampler();
|
||||
static void destroyTextureImage();
|
||||
static void destroyTextureSampler();
|
||||
static VkFormat findDepthFormat();
|
||||
static void createDepthResources();
|
||||
static void createColorResources();
|
||||
// ------------ Getters & Setters ------------ //
|
||||
static uint32_t getMipLevels();
|
||||
};
|
||||
} // namespace texture_libs
|
||||
|
Reference in New Issue
Block a user