1
0
Fork 0

Vulkan MSAA

This commit is contained in:
May B. 2020-10-07 12:39:12 +02:00
parent 9465083742
commit 7f6136bffd
17 changed files with 164 additions and 48 deletions

View File

@ -6,12 +6,14 @@ Work in progress galaxy down to atom (mostly centimeter) online voxel game
- [About The Project](#about-the-project) - [About The Project](#about-the-project)
- [Built With](#built-with) - [Built With](#built-with)
- [Getting Started](#getting-started) - [Run it](#run-it)
- [Prerequisites](#prerequisites) - [Prerequisites](#prerequisites)
- [Build](#build) - [Usage](#usage)
- [Build](#build)
- [Prerequisites](#prerequisites-1)
- [Optionally](#optionally) - [Optionally](#optionally)
- [Installation](#installation) - [Installation](#installation)
- [Usage](#usage) - [Additionally](#additionally)
- [RoadMap](#roadmap) - [RoadMap](#roadmap)
- [License](#license) - [License](#license)
- [Contact](#contact) - [Contact](#contact)
@ -35,16 +37,30 @@ Experimental project using OpenGL and Vulkan.
<!-- GETTING STARTED --> <!-- GETTING STARTED -->
## Getting Started ## Run it
To get a local copy up and running, follow these simple steps.
Get a release compatible with your system window library and processor capabilities, or [build](#build) it
### Prerequisites ### Prerequisites
* OpenGL or Vulkan driver * OpenGL or Vulkan driver
#### Build ### Usage
```sh
./univerxel
```
Edit `config.toml`
<!-- MAYBE: config description -->
Profit !
## Build
To get a local copy up and running, follow these simple steps.
### Prerequisites
* C++17 * C++17
* CMake 3.11 * CMake 3.11
@ -53,8 +69,9 @@ To get a local copy up and running, follow these simple steps.
#### Optionally #### Optionally
* Python: utility scripts * Python: utility scripts
* Tracy v0.7: profiling * [Tracy](https://github.com/wolfpld/tracy) v0.7: profiling
* glslc: compile vk shaders * [glslc](https://github.com/KhronosGroup/glslang): build vk shaders
* [Compressonator](https://github.com/GPUOpen-Tools/compressonator): build textures
### Installation ### Installation
@ -68,23 +85,47 @@ mkdir build && cd build
``` ```
3. Build CMake 3. Build CMake
```sh ```sh
cmake .. cmake <options> ..
``` ```
4. Build Make
CMake options: `-DKEY=VAL`
Key | Usage | Default
--- | --- | ---
SIMD_LEVEL | SIMD processor acceleration (sse2, sse4.1, avx2, avx512f) | `avx2`
USE_FMA | Fast math | `1`
CMAKE_BUILD_TYPE | Level of optimization | `Release`
PROFILING | Tracy profiling | `0`
LOG_DEBUG | Debug logs | `0`
LOG_TRACE | Trace logs | `0`
1. Build Make
```sh ```sh
make make -j<process count> <target>
``` ```
Target | Description
--- | ---
univerxel | All in one
univerxel-server | Standalone server
univerxel-client | Light client
docs | Doxygen documentation
<!-- USAGE EXAMPLES -->
## Usage
#### Additionally
5. Recompile Vulkan shaders
```sh ```sh
./univerxel cd resource/shaders-src
./compile.sh # Use glslc
GLSL="glslValidator -V" ./compile.sh # Other glslang compiler
``` ```
Profit ! 6. Rebuild textures
```sh
cd resource/textures-src
./merge <args> # combine grey images to RGBA
Compressonator -fd BC3 -mipsize <size> <in> <out>
```
<!-- ROADMAP --> <!-- ROADMAP -->

Binary file not shown.

View File

@ -13,7 +13,7 @@ Client::Client(config::client::options& options): options(options) { }
Client::~Client() { } Client::~Client() { }
void Client::run(server_handle* const localHandle) { void Client::run(server_handle* const localHandle) {
if (!render::Load(window, options.preferVulkan, options.renderer)) if (!render::Load(window, options.preferVulkan, options.renderer, options.window.samples))
return; return;
window.setTargetFPS(options.window.targetFPS); window.setTargetFPS(options.window.targetFPS);

View File

@ -72,11 +72,16 @@ public:
}; };
struct requirement: properties { struct requirement: properties {
requirement(const properties& props, Layout layout, Usage usage, Aspect aspect, requirement(const properties& props, Layout layout, Usage usage, Aspect aspect,
bool optimal = true): properties(props), layout(layout), usage(usage), int samples = 1, bool optimal = true): properties(props), layout(layout),
aspect(aspect), optimal(optimal) { } usage(usage), aspect(aspect), samples(samples), optimal(optimal)
{
assert(samples > 0 && (ceil(log2(n)) == floor(log2(n))) && "Samples must be pow2");
}
Layout layout; Layout layout;
Usage usage; Usage usage;
Aspect aspect; Aspect aspect;
//NOTE: matches VkSampleCountFlagBits
int samples;
bool optimal; bool optimal;
static requirement Texture(const properties &props) { static requirement Texture(const properties &props) {

View File

@ -63,11 +63,11 @@ void framebuffer_size_callback(GLFWwindow *, int width, int height) {
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
} }
bool Renderer::Load(Window& window, const renderOptions& opt) { bool Renderer::Load(Window& window, const renderOptions& opt, int samples) {
Window::CreateInfo windowInfo; Window::CreateInfo windowInfo;
windowInfo.pfnResize = framebuffer_size_callback; windowInfo.pfnResize = framebuffer_size_callback;
windowInfo.client = {Window::CreateInfo::Client::Type::GL, GL_MAJOR, GL_MINOR}; windowInfo.client = {Window::CreateInfo::Client::Type::GL, GL_MAJOR, GL_MINOR};
windowInfo.samples = 1; windowInfo.samples = samples;
if (!window.create(windowInfo)) if (!window.create(windowInfo))
return false; return false;

View File

@ -15,7 +15,7 @@ class Renderer final: public render::Renderer {
public: public:
virtual ~Renderer(); virtual ~Renderer();
static bool Load(Window& window, const renderOptions& options); static bool Load(Window& window, const renderOptions& options, int samples);
glm::vec3 FogColor; glm::vec3 FogColor;
GLfloat FogDepth; GLfloat FogDepth;

View File

@ -5,20 +5,20 @@
namespace render { namespace render {
bool Load(Window& window, bool preferVulkan, const renderOptions& options) { bool Load(Window& window, bool preferVulkan, const renderOptions& options, int samples) {
if(!preferVulkan) { if(!preferVulkan) {
LOG_T("Trying OpenGL"); LOG_T("Trying OpenGL");
if(gl::Renderer::Load(window, options)) if(gl::Renderer::Load(window, options, samples))
return true; return true;
window.destroy(); window.destroy();
} }
LOG_T("Trying Vulkan"); LOG_T("Trying Vulkan");
if(vk::Renderer::Load(window, options)) if(vk::Renderer::Load(window, options, samples))
return true; return true;
window.destroy(); window.destroy();
if(preferVulkan) { if(preferVulkan) {
LOG_I("Fallback to OpenGL"); LOG_I("Fallback to OpenGL");
if(gl::Renderer::Load(window, options)) if(gl::Renderer::Load(window, options, samples))
return true; return true;
} }
LOG_E("No available graphics library"); LOG_E("No available graphics library");

View File

@ -4,5 +4,5 @@ class Window;
namespace render { namespace render {
struct renderOptions; struct renderOptions;
bool Load(Window& window, bool preferVulkan, const renderOptions& options); bool Load(Window& window, bool preferVulkan, const renderOptions& options, int samples);
} }

View File

@ -243,6 +243,12 @@ void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLay
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
} else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destinationStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
} else { } else {
FATAL("Unsupported layout transition!"); FATAL("Unsupported layout transition!");
} }

View File

@ -34,6 +34,9 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
FATAL("Failed to create texture sampler!"); FATAL("Failed to create texture sampler!");
} }
} }
colorFormat = info.getSurfaceFormat().format;
colorSamples = info.samples;
LOG_D("Samples: " << colorSamples);
depthFormat = info.findDepthFormat(); depthFormat = info.findDepthFormat();
} }
CommandCenter::~CommandCenter() { CommandCenter::~CommandCenter() {
@ -46,13 +49,25 @@ CommandCenter::~CommandCenter() {
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent, const renderOptions& opt) { void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent, const renderOptions& opt) {
assert(freed); assert(freed);
if (colorSamples > 1) {
colorbuffer = Image::Create(Image::requirement({{extent.height, extent.width}, 1, (Image::Format)colorFormat},
Image::Layout::COLOR_ATTACHMENT, Image::Usage::COLOR_ATTACHMENT | Image::Usage::TRANSIENT_ATTACHMENT,
Image::Aspect::COLOR, colorSamples));
}
depthbuffer = Image::Create(Image::requirement({{extent.height, extent.width}, 1, (Image::Format)depthFormat}, depthbuffer = Image::Create(Image::requirement({{extent.height, extent.width}, 1, (Image::Format)depthFormat},
Image::Layout::DEPTH_STENCIL_ATTACHMENT, Image::Usage::DEPTH_STENCIL_ATTACHMENT, Image::Aspect::DEPTH)); Image::Layout::DEPTH_STENCIL_ATTACHMENT, Image::Usage::DEPTH_STENCIL_ATTACHMENT,
Image::Aspect::DEPTH, colorSamples));
framebuffers.resize(views.size()); framebuffers.resize(views.size());
for (size_t i = 0; i < views.size(); i++) { for (size_t i = 0; i < views.size(); i++) {
std::array<VkImageView, 2> attachments = { views[i], depthbuffer->getView() }; std::vector<VkImageView> attachments;
if (colorSamples > 1) {
attachments = {colorbuffer->getView(), depthbuffer->getView(), views[i]};
} else {
attachments = {views[i], depthbuffer->getView()};
}
VkFramebufferCreateInfo framebufferInfo{}; VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
@ -198,6 +213,7 @@ void CommandCenter::free() {
vkDestroyDescriptorPool(device, descriptorPool, nullptr); vkDestroyDescriptorPool(device, descriptorPool, nullptr);
colorbuffer.reset();
depthbuffer.reset(); depthbuffer.reset();
for (size_t i = 0; i < framebuffers.size(); i++) { for (size_t i = 0; i < framebuffers.size(); i++) {
@ -216,6 +232,7 @@ void CommandCenter::updateUBO(uint32_t idx) {
auto currentTime = std::chrono::high_resolution_clock::now(); auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count(); float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
buffer::vk::UniformBufferObject ubo{}; buffer::vk::UniformBufferObject ubo{};
time = 0.1;
ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f)); ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));
ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
ubo.proj = proj; ubo.proj = proj;

View File

@ -25,6 +25,10 @@ private:
VkDevice device; VkDevice device;
std::vector<VkFramebuffer> framebuffers; std::vector<VkFramebuffer> framebuffers;
VkFormat colorFormat;
VkSampleCountFlagBits colorSamples;
std::unique_ptr<Image> colorbuffer;
VkFormat depthFormat; VkFormat depthFormat;
std::unique_ptr<Image> depthbuffer; std::unique_ptr<Image> depthbuffer;

View File

@ -24,12 +24,26 @@ struct QueueFamilyIndices {
}; };
struct PhysicalDeviceInfo { struct PhysicalDeviceInfo {
PhysicalDeviceInfo() {} PhysicalDeviceInfo() {}
PhysicalDeviceInfo(GLFWwindow *window, VkPhysicalDevice device, VkSurfaceKHR surface): PhysicalDeviceInfo(GLFWwindow *window, VkPhysicalDevice device, VkSurfaceKHR surface, int targetSamples):
window(window), device(device), surface(surface), window(window), device(device), surface(surface),
swapDetails(SwapChainSupportDetails::Query(device, surface)), queueIndices(QueueFamilyIndices::Query(device, surface)) swapDetails(SwapChainSupportDetails::Query(device, surface)), queueIndices(QueueFamilyIndices::Query(device, surface))
{ {
vkGetPhysicalDeviceProperties(device, &properties); vkGetPhysicalDeviceProperties(device, &properties);
vkGetPhysicalDeviceFeatures(device, &features); vkGetPhysicalDeviceFeatures(device, &features);
samples = [&] {
if (targetSamples < 0)
targetSamples = 4;
VkSampleCountFlags counts = properties.limits.framebufferColorSampleCounts & properties.limits.framebufferDepthSampleCounts;
//MAYBE: properties.limits.framebufferStencilSampleCounts
for (auto sample: {VK_SAMPLE_COUNT_64_BIT, VK_SAMPLE_COUNT_32_BIT, VK_SAMPLE_COUNT_16_BIT,
VK_SAMPLE_COUNT_8_BIT, VK_SAMPLE_COUNT_4_BIT, VK_SAMPLE_COUNT_2_BIT
}) {
if (targetSamples >= sample && (counts & sample))
return sample;
}
return VK_SAMPLE_COUNT_1_BIT;
}();
} }
VkSurfaceFormatKHR getSurfaceFormat() const; VkSurfaceFormatKHR getSurfaceFormat() const;
@ -44,6 +58,7 @@ struct PhysicalDeviceInfo {
GLFWwindow *window; GLFWwindow *window;
VkPhysicalDevice device = VK_NULL_HANDLE; VkPhysicalDevice device = VK_NULL_HANDLE;
VkSurfaceKHR surface; VkSurfaceKHR surface;
VkSampleCountFlagBits samples;
SwapChainSupportDetails swapDetails; SwapChainSupportDetails swapDetails;
QueueFamilyIndices queueIndices; QueueFamilyIndices queueIndices;
VkPhysicalDeviceProperties properties; VkPhysicalDeviceProperties properties;

View File

@ -13,16 +13,18 @@ constexpr auto BLENDING = true;
using namespace render::vk; using namespace render::vk;
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) { Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) {
const auto hasSamples = info.samples > 1;
{ // Render pass { // Render pass
VkAttachmentDescription colorAttachment{}; VkAttachmentDescription colorAttachment{};
colorAttachment.format = info.getSurfaceFormat().format; colorAttachment.format = info.getSurfaceFormat().format;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT; colorAttachment.samples = info.samples;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; colorAttachment.finalLayout = hasSamples ?
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentReference colorAttachmentRef{}; VkAttachmentReference colorAttachmentRef{};
colorAttachmentRef.attachment = 0; //TODO: layouts bind colorAttachmentRef.attachment = 0; //TODO: layouts bind
@ -30,7 +32,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
VkAttachmentDescription depthAttachment{}; VkAttachmentDescription depthAttachment{};
depthAttachment.format = info.findDepthFormat(); depthAttachment.format = info.findDepthFormat();
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT; depthAttachment.samples = info.samples;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@ -42,6 +44,20 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
depthAttachmentRef.attachment = 1; depthAttachmentRef.attachment = 1;
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentDescription colorAttachmentResolve{};
colorAttachmentResolve.format = colorAttachment.format;
colorAttachmentResolve.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachmentResolve.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachmentResolve.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachmentResolve.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachmentResolve.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachmentResolve.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachmentResolve.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentReference colorAttachmentResolveRef{};
colorAttachmentResolveRef.attachment = 2;
colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
//TODO: subpasses (world, entities, colors, sky, ui) //TODO: subpasses (world, entities, colors, sky, ui)
VkSubpassDescription subpass{}; VkSubpassDescription subpass{};
@ -49,6 +65,9 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
subpass.colorAttachmentCount = 1; subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef; subpass.pColorAttachments = &colorAttachmentRef;
subpass.pDepthStencilAttachment = &depthAttachmentRef; subpass.pDepthStencilAttachment = &depthAttachmentRef;
if (hasSamples) {
subpass.pResolveAttachments = &colorAttachmentResolveRef;
}
VkSubpassDependency dependency{}; VkSubpassDependency dependency{};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
@ -60,7 +79,10 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
VkRenderPassCreateInfo renderPassInfo{}; VkRenderPassCreateInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
std::array<VkAttachmentDescription, 2> attachments = {colorAttachment, depthAttachment}; std::vector<VkAttachmentDescription> attachments = {colorAttachment, depthAttachment};
if (hasSamples) {
attachments.push_back(colorAttachmentResolve);
}
renderPassInfo.attachmentCount = attachments.size(); renderPassInfo.attachmentCount = attachments.size();
renderPassInfo.pAttachments = attachments.data(); renderPassInfo.pAttachments = attachments.data();
renderPassInfo.subpassCount = 1; renderPassInfo.subpassCount = 1;
@ -190,11 +212,12 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
rasterizer.depthBiasClamp = 0.0f; rasterizer.depthBiasClamp = 0.0f;
rasterizer.depthBiasSlopeFactor = 0.0f; rasterizer.depthBiasSlopeFactor = 0.0f;
VkPipelineMultisampleStateCreateInfo multisampling{}; //TODO: multisampling NOTE: requires gpu feature VkPipelineMultisampleStateCreateInfo multisampling{};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling.sampleShadingEnable = VK_FALSE; multisampling.rasterizationSamples = info.samples;
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; //MAYBE: add option
multisampling.minSampleShading = 1.0f; multisampling.sampleShadingEnable = hasSamples;
multisampling.minSampleShading = .2f;
multisampling.pSampleMask = nullptr; multisampling.pSampleMask = nullptr;
multisampling.alphaToCoverageEnable = VK_FALSE; multisampling.alphaToCoverageEnable = VK_FALSE;
multisampling.alphaToOneEnable = VK_FALSE; multisampling.alphaToOneEnable = VK_FALSE;

View File

@ -155,11 +155,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugValidationCallback(VkDebugUtilsMessageSeveri
return VK_FALSE; return VK_FALSE;
} }
bool Renderer::Load(Window& window, const renderOptions& opt) { bool Renderer::Load(Window& window, const renderOptions& opt, int samples) {
Window::CreateInfo windowInfo; Window::CreateInfo windowInfo;
windowInfo.pfnResize = on_resize_callback; windowInfo.pfnResize = on_resize_callback;
windowInfo.client = {Window::CreateInfo::Client::Type::VK, 0, 0}; windowInfo.client = {Window::CreateInfo::Client::Type::VK, 0, 0};
windowInfo.samples = 1; windowInfo.samples = -1;
if (!window.create(windowInfo)) if (!window.create(windowInfo))
return false; return false;
@ -289,7 +289,7 @@ bool Renderer::Load(Window& window, const renderOptions& opt) {
uint bestScore = 0; uint bestScore = 0;
for(const auto& device: devices) { for(const auto& device: devices) {
uint score = 1; uint score = 1;
auto infos = PhysicalDeviceInfo(window.getPtr(), device, surface); auto infos = PhysicalDeviceInfo(window.getPtr(), device, surface, samples);
{ {
uint32_t availableExtensionsCount; uint32_t availableExtensionsCount;
@ -321,6 +321,7 @@ bool Renderer::Load(Window& window, const renderOptions& opt) {
score += 10000; score += 10000;
score += infos.properties.limits.maxImageDimension2D; score += infos.properties.limits.maxImageDimension2D;
score += infos.samples * 50;
if (infos.features.geometryShader) if (infos.features.geometryShader)
score += 2000; score += 2000;

View File

@ -13,7 +13,7 @@ class Renderer final: public render::Renderer {
public: public:
virtual ~Renderer(); virtual ~Renderer();
static bool Load(Window& window, const renderOptions& options); static bool Load(Window& window, const renderOptions& options, int samples);
void loadUI(Window &) override; void loadUI(Window &) override;

View File

@ -30,7 +30,7 @@ memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags pro
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
info.usage = static_cast<VkImageUsageFlags>(req.usage); info.usage = static_cast<VkImageUsageFlags>(req.usage);
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.samples = VK_SAMPLE_COUNT_1_BIT; info.samples = static_cast<VkSampleCountFlagBits>(req.samples);
info.flags = 0; info.flags = 0;
if (data) { if (data) {
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
@ -140,6 +140,10 @@ std::unique_ptr<Texture> Texture::LoadFromFile(const std::string& path, const sa
samplerInfo.minLod = 0.0f; samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = props.mipmap ? header.mipmapLevels : 0.0f; samplerInfo.maxLod = props.mipmap ? header.mipmapLevels : 0.0f;
if (props.mipmap && header.mipmapLevels <= 1) {
LOG_D("Sampler requires mipmap but image does not");
}
VkSampler sampler; VkSampler sampler;
if (vkCreateSampler(device, &samplerInfo, ALLOC, &sampler) != VK_SUCCESS) { if (vkCreateSampler(device, &samplerInfo, ALLOC, &sampler) != VK_SUCCESS) {
FATAL("Failed to create texture sampler!"); FATAL("Failed to create texture sampler!");

View File

@ -23,10 +23,10 @@ public:
LOG_E("Config file " << path << " not found. Creating default"); LOG_E("Config file " << path << " not found. Creating default");
return toml::table(); return toml::table();
}(); }();
if (config["server"]["enabled"].value_or(false)) { if (config["server"]["enabled"].value_or(true)) {
_server = server::options(config["server"]); _server = server::options(config["server"]);
} }
if(config["client"]["enabled"].value_or(false)) { if(config["client"]["enabled"].value_or(true)) {
_client = client::options(config["client"]); _client = client::options(config["client"]);
} }
} }