Multisampling implementation using the max samples the GPU supports

This commit is contained in:
Lillian Salehi 2024-11-21 23:54:07 -06:00
parent 2631bbbaba
commit aa53a80fce
22 changed files with 156 additions and 50 deletions

8
imgui.ini Normal file
View File

@ -0,0 +1,8 @@
[Window][Debug##Default]
Pos=60,60
Size=400,400
[Window][Agnosia Debug]
Pos=98,111
Size=494,375

19
src/agnosiaimgui.cpp Normal file
View 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
View 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

View File

@ -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; }

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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}},
};

View File

@ -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,8 +125,7 @@ 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
@ -132,19 +133,15 @@ void Render::drawImGui() {
ImGui::Text("This is some useful text."); // Display some text (you can use
// a format strings too)
ImGui::SliderFloat("float", &f, 0.0f,
ImGui::SliderFloat("float", &floatBar, 0.0f,
1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
if (ImGui::Button("Button")) // Buttons return true when clicked (most
// widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
agnosia_imgui::Gui::drawTabs();
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

View File

@ -10,5 +10,6 @@ public:
static void cleanupSwapChain();
static void init_imgui(VkInstance instance);
static void drawImGui();
static float getFloatBar();
};
} // namespace render_present

View File

@ -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);

View File

@ -1,7 +1,8 @@
#pragma once
#include "../devicelibrary.h"
#include "../global.h"
#include "buffers.h"
#include "../devicelibrary.h"
#include <cstdint>
namespace texture_libs {
class Texture {
@ -13,8 +14,8 @@ namespace texture_libs {
static void destroyTextureSampler();
static VkFormat findDepthFormat();
static void createDepthResources();
static void createColorResources();
// ------------ Getters & Setters ------------ //
static uint32_t getMipLevels();
};
}
} // namespace texture_libs