Vulkan MSAA
parent
9465083742
commit
7f6136bffd
75
README.md
75
README.md
|
@ -6,12 +6,14 @@ Work in progress galaxy down to atom (mostly centimeter) online voxel game
|
|||
|
||||
- [About The Project](#about-the-project)
|
||||
- [Built With](#built-with)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Run it](#run-it)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [Build](#build)
|
||||
- [Usage](#usage)
|
||||
- [Build](#build)
|
||||
- [Prerequisites](#prerequisites-1)
|
||||
- [Optionally](#optionally)
|
||||
- [Installation](#installation)
|
||||
- [Usage](#usage)
|
||||
- [Additionally](#additionally)
|
||||
- [RoadMap](#roadmap)
|
||||
- [License](#license)
|
||||
- [Contact](#contact)
|
||||
|
@ -35,16 +37,30 @@ Experimental project using OpenGL and Vulkan.
|
|||
|
||||
|
||||
<!-- GETTING STARTED -->
|
||||
## Getting Started
|
||||
|
||||
To get a local copy up and running, follow these simple steps.
|
||||
## Run it
|
||||
|
||||
Get a release compatible with your system window library and processor capabilities, or [build](#build) it
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* 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
|
||||
* CMake 3.11
|
||||
|
@ -53,8 +69,9 @@ To get a local copy up and running, follow these simple steps.
|
|||
#### Optionally
|
||||
|
||||
* Python: utility scripts
|
||||
* Tracy v0.7: profiling
|
||||
* glslc: compile vk shaders
|
||||
* [Tracy](https://github.com/wolfpld/tracy) v0.7: profiling
|
||||
* [glslc](https://github.com/KhronosGroup/glslang): build vk shaders
|
||||
* [Compressonator](https://github.com/GPUOpen-Tools/compressonator): build textures
|
||||
|
||||
### Installation
|
||||
|
||||
|
@ -68,23 +85,47 @@ mkdir build && cd build
|
|||
```
|
||||
3. Build CMake
|
||||
```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
|
||||
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
|
||||
./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 -->
|
||||
|
|
BIN
resource/content/textures/1024-realistic/terrain/Mapl.dds (Stored with Git LFS)
BIN
resource/content/textures/1024-realistic/terrain/Mapl.dds (Stored with Git LFS)
Binary file not shown.
|
@ -13,7 +13,7 @@ Client::Client(config::client::options& options): options(options) { }
|
|||
Client::~Client() { }
|
||||
|
||||
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;
|
||||
|
||||
window.setTargetFPS(options.window.targetFPS);
|
||||
|
|
|
@ -72,11 +72,16 @@ public:
|
|||
};
|
||||
struct requirement: properties {
|
||||
requirement(const properties& props, Layout layout, Usage usage, Aspect aspect,
|
||||
bool optimal = true): properties(props), layout(layout), usage(usage),
|
||||
aspect(aspect), optimal(optimal) { }
|
||||
int samples = 1, bool optimal = true): properties(props), layout(layout),
|
||||
usage(usage), aspect(aspect), samples(samples), optimal(optimal)
|
||||
{
|
||||
assert(samples > 0 && (ceil(log2(n)) == floor(log2(n))) && "Samples must be pow2");
|
||||
}
|
||||
Layout layout;
|
||||
Usage usage;
|
||||
Aspect aspect;
|
||||
//NOTE: matches VkSampleCountFlagBits
|
||||
int samples;
|
||||
bool optimal;
|
||||
|
||||
static requirement Texture(const properties &props) {
|
||||
|
|
|
@ -63,11 +63,11 @@ void framebuffer_size_callback(GLFWwindow *, int width, int 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;
|
||||
windowInfo.pfnResize = framebuffer_size_callback;
|
||||
windowInfo.client = {Window::CreateInfo::Client::Type::GL, GL_MAJOR, GL_MINOR};
|
||||
windowInfo.samples = 1;
|
||||
windowInfo.samples = samples;
|
||||
if (!window.create(windowInfo))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class Renderer final: public render::Renderer {
|
|||
public:
|
||||
virtual ~Renderer();
|
||||
|
||||
static bool Load(Window& window, const renderOptions& options);
|
||||
static bool Load(Window& window, const renderOptions& options, int samples);
|
||||
|
||||
glm::vec3 FogColor;
|
||||
GLfloat FogDepth;
|
||||
|
|
|
@ -5,20 +5,20 @@
|
|||
|
||||
namespace render {
|
||||
|
||||
bool Load(Window& window, bool preferVulkan, const renderOptions& options) {
|
||||
bool Load(Window& window, bool preferVulkan, const renderOptions& options, int samples) {
|
||||
if(!preferVulkan) {
|
||||
LOG_T("Trying OpenGL");
|
||||
if(gl::Renderer::Load(window, options))
|
||||
if(gl::Renderer::Load(window, options, samples))
|
||||
return true;
|
||||
window.destroy();
|
||||
}
|
||||
LOG_T("Trying Vulkan");
|
||||
if(vk::Renderer::Load(window, options))
|
||||
if(vk::Renderer::Load(window, options, samples))
|
||||
return true;
|
||||
window.destroy();
|
||||
if(preferVulkan) {
|
||||
LOG_I("Fallback to OpenGL");
|
||||
if(gl::Renderer::Load(window, options))
|
||||
if(gl::Renderer::Load(window, options, samples))
|
||||
return true;
|
||||
}
|
||||
LOG_E("No available graphics library");
|
||||
|
|
|
@ -4,5 +4,5 @@ class Window;
|
|||
namespace render {
|
||||
struct renderOptions;
|
||||
|
||||
bool Load(Window& window, bool preferVulkan, const renderOptions& options);
|
||||
bool Load(Window& window, bool preferVulkan, const renderOptions& options, int samples);
|
||||
}
|
|
@ -243,6 +243,12 @@ void Allocator::transitionImageLayout(VkImage image, VkFormat format, VkImageLay
|
|||
|
||||
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_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 {
|
||||
FATAL("Unsupported layout transition!");
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@ CommandCenter::CommandCenter(VkDevice device, const PhysicalDeviceInfo &info, co
|
|||
FATAL("Failed to create texture sampler!");
|
||||
}
|
||||
}
|
||||
colorFormat = info.getSurfaceFormat().format;
|
||||
colorSamples = info.samples;
|
||||
LOG_D("Samples: " << colorSamples);
|
||||
depthFormat = info.findDepthFormat();
|
||||
}
|
||||
CommandCenter::~CommandCenter() {
|
||||
|
@ -46,13 +49,25 @@ CommandCenter::~CommandCenter() {
|
|||
void CommandCenter::allocate(const std::vector<VkImageView>& views, const Pipeline& pipe, VkExtent2D extent, const renderOptions& opt) {
|
||||
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},
|
||||
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());
|
||||
|
||||
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{};
|
||||
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
|
@ -198,6 +213,7 @@ void CommandCenter::free() {
|
|||
|
||||
vkDestroyDescriptorPool(device, descriptorPool, nullptr);
|
||||
|
||||
colorbuffer.reset();
|
||||
depthbuffer.reset();
|
||||
|
||||
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();
|
||||
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();
|
||||
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.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;
|
||||
|
|
|
@ -25,6 +25,10 @@ private:
|
|||
VkDevice device;
|
||||
|
||||
std::vector<VkFramebuffer> framebuffers;
|
||||
|
||||
VkFormat colorFormat;
|
||||
VkSampleCountFlagBits colorSamples;
|
||||
std::unique_ptr<Image> colorbuffer;
|
||||
VkFormat depthFormat;
|
||||
std::unique_ptr<Image> depthbuffer;
|
||||
|
||||
|
|
|
@ -24,12 +24,26 @@ struct QueueFamilyIndices {
|
|||
};
|
||||
struct PhysicalDeviceInfo {
|
||||
PhysicalDeviceInfo() {}
|
||||
PhysicalDeviceInfo(GLFWwindow *window, VkPhysicalDevice device, VkSurfaceKHR surface):
|
||||
PhysicalDeviceInfo(GLFWwindow *window, VkPhysicalDevice device, VkSurfaceKHR surface, int targetSamples):
|
||||
window(window), device(device), surface(surface),
|
||||
swapDetails(SwapChainSupportDetails::Query(device, surface)), queueIndices(QueueFamilyIndices::Query(device, surface))
|
||||
{
|
||||
vkGetPhysicalDeviceProperties(device, &properties);
|
||||
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;
|
||||
|
@ -44,6 +58,7 @@ struct PhysicalDeviceInfo {
|
|||
GLFWwindow *window;
|
||||
VkPhysicalDevice device = VK_NULL_HANDLE;
|
||||
VkSurfaceKHR surface;
|
||||
VkSampleCountFlagBits samples;
|
||||
SwapChainSupportDetails swapDetails;
|
||||
QueueFamilyIndices queueIndices;
|
||||
VkPhysicalDeviceProperties properties;
|
||||
|
|
|
@ -13,16 +13,18 @@ constexpr auto BLENDING = true;
|
|||
using namespace render::vk;
|
||||
|
||||
Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const renderOptions &options): device(device) {
|
||||
const auto hasSamples = info.samples > 1;
|
||||
{ // Render pass
|
||||
VkAttachmentDescription colorAttachment{};
|
||||
colorAttachment.format = info.getSurfaceFormat().format;
|
||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
colorAttachment.samples = info.samples;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
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{};
|
||||
colorAttachmentRef.attachment = 0; //TODO: layouts bind
|
||||
|
@ -30,7 +32,7 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
|
||||
VkAttachmentDescription depthAttachment{};
|
||||
depthAttachment.format = info.findDepthFormat();
|
||||
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
depthAttachment.samples = info.samples;
|
||||
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
depthAttachment.storeOp = VK_ATTACHMENT_STORE_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.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)
|
||||
|
||||
VkSubpassDescription subpass{};
|
||||
|
@ -49,6 +65,9 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &colorAttachmentRef;
|
||||
subpass.pDepthStencilAttachment = &depthAttachmentRef;
|
||||
if (hasSamples) {
|
||||
subpass.pResolveAttachments = &colorAttachmentResolveRef;
|
||||
}
|
||||
|
||||
VkSubpassDependency dependency{};
|
||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
|
@ -60,7 +79,10 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
|
||||
VkRenderPassCreateInfo renderPassInfo{};
|
||||
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.pAttachments = attachments.data();
|
||||
renderPassInfo.subpassCount = 1;
|
||||
|
@ -190,11 +212,12 @@ Pipeline::Pipeline(VkDevice device, const PhysicalDeviceInfo &info, const render
|
|||
rasterizer.depthBiasClamp = 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.sampleShadingEnable = VK_FALSE;
|
||||
multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
multisampling.minSampleShading = 1.0f;
|
||||
multisampling.rasterizationSamples = info.samples;
|
||||
//MAYBE: add option
|
||||
multisampling.sampleShadingEnable = hasSamples;
|
||||
multisampling.minSampleShading = .2f;
|
||||
multisampling.pSampleMask = nullptr;
|
||||
multisampling.alphaToCoverageEnable = VK_FALSE;
|
||||
multisampling.alphaToOneEnable = VK_FALSE;
|
||||
|
|
|
@ -155,11 +155,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugValidationCallback(VkDebugUtilsMessageSeveri
|
|||
return VK_FALSE;
|
||||
}
|
||||
|
||||
bool Renderer::Load(Window& window, const renderOptions& opt) {
|
||||
bool Renderer::Load(Window& window, const renderOptions& opt, int samples) {
|
||||
Window::CreateInfo windowInfo;
|
||||
windowInfo.pfnResize = on_resize_callback;
|
||||
windowInfo.client = {Window::CreateInfo::Client::Type::VK, 0, 0};
|
||||
windowInfo.samples = 1;
|
||||
windowInfo.samples = -1;
|
||||
if (!window.create(windowInfo))
|
||||
return false;
|
||||
|
||||
|
@ -289,7 +289,7 @@ bool Renderer::Load(Window& window, const renderOptions& opt) {
|
|||
uint bestScore = 0;
|
||||
for(const auto& device: devices) {
|
||||
uint score = 1;
|
||||
auto infos = PhysicalDeviceInfo(window.getPtr(), device, surface);
|
||||
auto infos = PhysicalDeviceInfo(window.getPtr(), device, surface, samples);
|
||||
|
||||
{
|
||||
uint32_t availableExtensionsCount;
|
||||
|
@ -321,6 +321,7 @@ bool Renderer::Load(Window& window, const renderOptions& opt) {
|
|||
score += 10000;
|
||||
|
||||
score += infos.properties.limits.maxImageDimension2D;
|
||||
score += infos.samples * 50;
|
||||
|
||||
if (infos.features.geometryShader)
|
||||
score += 2000;
|
||||
|
|
|
@ -13,7 +13,7 @@ class Renderer final: public render::Renderer {
|
|||
public:
|
||||
virtual ~Renderer();
|
||||
|
||||
static bool Load(Window& window, const renderOptions& options);
|
||||
static bool Load(Window& window, const renderOptions& options, int samples);
|
||||
|
||||
void loadUI(Window &) override;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ memory::ptr createImage(const Image::requirement& req, VkMemoryPropertyFlags pro
|
|||
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
info.usage = static_cast<VkImageUsageFlags>(req.usage);
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
info.samples = static_cast<VkSampleCountFlagBits>(req.samples);
|
||||
info.flags = 0;
|
||||
if (data) {
|
||||
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.maxLod = props.mipmap ? header.mipmapLevels : 0.0f;
|
||||
|
||||
if (props.mipmap && header.mipmapLevels <= 1) {
|
||||
LOG_D("Sampler requires mipmap but image does not");
|
||||
}
|
||||
|
||||
VkSampler sampler;
|
||||
if (vkCreateSampler(device, &samplerInfo, ALLOC, &sampler) != VK_SUCCESS) {
|
||||
FATAL("Failed to create texture sampler!");
|
||||
|
|
|
@ -23,10 +23,10 @@ public:
|
|||
LOG_E("Config file " << path << " not found. Creating default");
|
||||
return toml::table();
|
||||
}();
|
||||
if (config["server"]["enabled"].value_or(false)) {
|
||||
if (config["server"]["enabled"].value_or(true)) {
|
||||
_server = server::options(config["server"]);
|
||||
}
|
||||
if(config["client"]["enabled"].value_or(false)) {
|
||||
if(config["client"]["enabled"].value_or(true)) {
|
||||
_client = client::options(config["client"]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue